5 * Created by Toshi Nagata on 08/12/05.
6 * Copyright 2008 Toshi Nagata. All rights reserved.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation version 2 of the License.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
18 #include "wx/gdicmn.h"
19 #include "wx/stattext.h"
20 #include "wx/textctrl.h"
21 #include "wx/button.h"
22 #include "wx/tglbtn.h"
23 #include "wx/filedlg.h"
24 #include "wx/dirdlg.h"
25 #include "wx/dcclient.h"
26 #include "wx/choice.h"
27 #include "wx/checkbox.h"
28 #include "wx/radiobut.h"
29 #include "wx/statline.h"
30 #include "wx/settings.h"
32 #include "RubyDialogFrame.h"
35 #include "MyDocument.h"
37 BEGIN_EVENT_TABLE(RubyDialogFrame, wxDialog)
38 EVT_TIMER(-1, RubyDialogFrame::OnTimerEvent)
39 EVT_BUTTON(wxID_OK, RubyDialogFrame::OnDefaultButtonPressed)
40 EVT_BUTTON(wxID_CANCEL, RubyDialogFrame::OnDefaultButtonPressed)
41 EVT_SIZE(RubyDialogFrame::OnSize)
44 RubyDialogFrame::RubyDialogFrame(wxWindow* parent, wxWindowID wid, const wxString& title, const wxPoint& pos, const wxSize& size, long style):
45 wxDialog(parent, wid, title, pos, size, style)
51 autoResizeEnabled = true;
55 // Create a vertical box sizer that contains a panel containing all controls and a sizer containing
57 contentSizer = new wxBoxSizer(wxVERTICAL);
59 buttonSizer = NULL; // Will be created later
60 myTimer = NULL; // Will be created when necessary
61 boxSizer = new wxBoxSizer(wxVERTICAL);
62 boxSizer->Add(contentSizer, 1, wxALL | wxEXPAND, 14);
63 this->SetSizer(boxSizer);
65 this->CentreOnScreen();
68 RubyDialogFrame::~RubyDialogFrame()
78 RubyDialogFrame::DiscardMessageData()
81 for (i = 0; i < countMessageData; i++) {
82 if (messageData[i * 5] != NULL) {
83 wxEventType eventType = (wxEventType)messageData[i * 5 + 2];
84 wxEvtHandler *handler = NULL;
85 if (eventType == MyDocumentEvent)
86 handler = MyDocumentFromMolecule((Molecule *)messageData[i * 5]);
87 if (handler != NULL) {
88 handler->Disconnect((int)messageData[i * 5 + 1], eventType, wxCommandEventHandler(RubyDialogFrame::HandleDocumentEvent), NULL, this);
98 RubyDialogFrame::AddDialogItem(RDItem *item)
100 if (nditems % 8 == 0) {
102 ditems = (RDItem **)malloc(sizeof(RDItem *) * 8);
104 ditems = (RDItem **)realloc(ditems, sizeof(RDItem *) * (nditems + 8));
106 ditems[nditems++] = item;
107 if (item != NULL && ((wxWindow *)item)->IsKindOf(CLASSINFO(wxPanel))) {
108 wxSize size = ((wxPanel *)item)->GetSize();
109 if (contentPanel == NULL)
110 contentSizer->Add((wxPanel *)item, 1, wxEXPAND);
112 contentSizer->Replace(contentPanel, (wxPanel *)item);
113 contentSizer->SetItemMinSize((wxPanel *)item, size.GetWidth(), size.GetHeight());
114 contentPanel = (wxPanel *)item;
122 RubyDialogFrame::DialogItemAtIndex(int index)
124 if (index >= 0 && index < nditems)
125 return ditems[index];
130 RubyDialogFrame::SearchDialogItem(RDItem *item)
133 for (i = 0; i < nditems; i++) {
134 if (item == ditems[i])
141 RubyDialogFrame::SetRubyObject(RubyValue val)
145 /* Stop message mechanism (because this object is already disconnected from the Ruby world) */
146 DiscardMessageData();
150 /* Create standard buttons. If oktitle/canceltitle == NULL, then the button is created but set hidden.
151 If the title is "", then the default titles are used. */
153 RubyDialogFrame::CreateStandardButtons(const char *oktitle, const char *canceltitle)
155 wxSizer *sizer = CreateButtonSizer(wxOK | wxCANCEL);
156 if (oktitle != NULL || canceltitle != NULL) {
158 return; /* Cannot create */
159 if (buttonSizer == NULL) {
160 boxSizer->Add(sizer, 0, wxBOTTOM | wxLEFT | wxRIGHT | wxEXPAND, 14);
163 boxSizer->Replace(buttonSizer, sizer);
167 /* Buttons are created but sizer is left unregistered */
168 if (buttonSizer != NULL)
169 boxSizer->Remove(buttonSizer);
174 if (ditems[0] != NULL)
175 ((wxWindow *)ditems[0])->Destroy();
176 if (ditems[1] != NULL)
177 ((wxWindow *)ditems[1])->Destroy();
178 ditems[0] = (RDItem *)wxWindow::FindWindowById(wxID_OK, this);
179 ditems[1] = (RDItem *)wxWindow::FindWindowById(wxID_CANCEL, this);
180 if (oktitle == NULL) {
181 ((wxWindow *)ditems[0])->Show(false);
182 ((wxWindow *)ditems[0])->Enable(false);
184 if (oktitle[0] != 0) {
185 wxString label1(oktitle, WX_DEFAULT_CONV);
186 ((wxButton *)ditems[0])->SetLabel(label1);
188 ((wxWindow *)ditems[0])->Connect(-1, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, this);
190 if (canceltitle == NULL) {
191 ((wxWindow *)ditems[1])->Show(false);
192 ((wxWindow *)ditems[1])->Enable(false);
194 if (canceltitle[0] != 0) {
195 wxString label2(canceltitle, WX_DEFAULT_CONV);
196 ((wxButton *)ditems[1])->SetLabel(label2);
198 ((wxWindow *)ditems[1])->Connect(-1, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, this);
203 RubyDialogFrame::StartIntervalTimer(int millisec)
205 if (myTimer == NULL) {
206 myTimer = new wxTimer(this);
208 return myTimer->Start(millisec);
212 RubyDialogFrame::StopIntervalTimer(void)
219 RubyDialogFrame::OnDialogItemAction(wxCommandEvent &event)
221 RubyDialog_doItemAction((RubyValue)dval, (RDItem *)(event.GetEventObject()));
225 RubyDialogFrame::OnDefaultButtonPressed(wxCommandEvent &event)
227 /* Ignore the wxID_OK and wxID_CANCEL requests if the default buttons are hidden */
228 wxWindow *item = wxWindow::FindWindowById(event.GetId(), this);
229 if (!item->IsShown())
235 RubyDialogFrame::OnTimerEvent(wxTimerEvent &event)
237 RubyDialog_doTimerAction((RubyValue)dval);
241 sResizeSubWindows(RubyValue dval, wxWindow *win, int dx, int dy)
243 wxWindowList & children = win->GetChildren();
244 wxWindowList::Node *node;
245 for (node = children.GetFirst(); node; node = node->GetNext()) {
246 int i, d, f, d1, d2, d3, ddx, ddy;
247 wxWindow *current = (wxWindow *)node->GetData();
248 wxRect frame = current->GetRect();
249 int flex = RubyDialog_getFlexFlags(dval, (RDItem *)current);
252 for (i = 0, f = flex; i < 2; i++, f /= 2) {
257 switch (f & 21) { /* left, right, width (or top, bottom, height) */
258 case 21: /* all flex */
262 case 5: /* left & right */
267 case 17: /* left & width */
272 case 20: /* right & width */
300 if (ddx != 0 || ddy != 0)
301 sResizeSubWindows(dval, current, ddx, ddy);
302 current->SetSize(frame);
307 RubyDialogFrame::OnSize(wxSizeEvent &event)
309 wxSize size = GetClientSize();
310 if (mySize.width != 0 && mySize.height != 0 && /*(mySize.width != size.x || mySize.height != size.y) &&*/ autoResizeEnabled) {
311 /* Resize the subviews */
312 sResizeSubWindows((RubyValue)dval, this, size.x - mySize.width, size.y - mySize.height);
314 mySize.width = size.x;
315 mySize.height = size.y;
320 RubyDialogFrame::ListenToObject(void *obj, const char *objtype, const char *msg, RubyValue oval, RubyValue pval)
323 wxEventType eventType;
324 wxEvtHandler *handler;
325 if (strcmp(objtype, "Molecule") == 0) {
326 eventType = MyDocumentEvent;
327 handler = MyDocumentFromMolecule((Molecule *)obj);
329 return -1; /* obj is not an event handler */
332 else if (strcmp(msg, "documentModified") == 0)
333 eventId = MyDocumentEvent_documentModified;
334 else if (strcmp(msg, "documentWillClose") == 0)
335 eventId = MyDocumentEvent_documentWillClose;
336 else return -2; /* this event type is not supported */
339 if (pval == NULL || pval == RubyNil) {
340 /* Remove the registration */
341 for (i = 0; i < countMessageData; i++) {
342 if (messageData[i * 5] == obj &&
343 messageData[i * 5 + 1] == (void *)eventId &&
344 messageData[i * 5 + 2] == (void *)eventType) {
345 handler->Disconnect(eventId, eventType, wxCommandEventHandler(RubyDialogFrame::HandleDocumentEvent), NULL, this);
346 if (eventType == MyDocumentEvent)
347 MoleculeRelease((Molecule *)obj);
351 if (i == countMessageData)
352 return -3; /* No such message */
353 messageData[i * 5] = NULL;
356 /* Check the duplicate */
357 j = countMessageData; /* The position to store info if it is new */
358 for (i = 0; i < countMessageData; i++) {
359 if (messageData[i * 5] == obj &&
360 messageData[i * 5 + 1] == (void *)eventId &&
361 messageData[i * 5 + 2] == (void *)eventType) {
362 /* Just replace the arguments */
363 messageData[i * 5 + 3] = (void *)oval;
364 messageData[i * 5 + 4] = (void *)pval;
367 if (messageData[i * 5] == NULL)
370 if (i == countMessageData) {
371 /* Register the data and establish a new connection */
372 if (j == countMessageData) {
373 /* Create a new entry */
374 InsertArray(&messageData, &countMessageData, sizeof(void *) * 5, i, 1, NULL);
376 messageData[j * 5] = obj;
377 messageData[j * 5 + 1] = (void *)eventId;
378 messageData[j * 5 + 2] = (void *)eventType;
379 messageData[j * 5 + 3] = (void *)oval;
380 messageData[j * 5 + 4] = (void *)pval;
381 handler->Connect(eventId, eventType, wxCommandEventHandler(RubyDialogFrame::HandleDocumentEvent), NULL, this);
382 if (eventType == MyDocumentEvent)
383 MoleculeRetain((Molecule *)obj);
391 RubyDialogFrame::HandleDocumentEvent(wxCommandEvent &event)
394 int eventId = event.GetId();
395 int eventType = event.GetEventType();
396 wxObject *eventObject = event.GetEventObject();
399 if (eventType == MyDocumentEvent) {
400 if (wxDynamicCast(eventObject, MyDocument) != NULL) {
401 obj = ((MyDocument *)eventObject)->GetMolecule();
405 /* Look up the message table */
406 for (i = 0; i < countMessageData; i++) {
407 if (messageData[i * 5] == obj &&
408 messageData[i * 5 + 1] == (void *)eventId &&
409 messageData[i * 5 + 2] == (void *)eventType) {
411 RubyValue oval = (RubyValue)messageData[i * 5 + 3];
412 RubyValue pval = (RubyValue)messageData[i * 5 + 4];
413 Ruby_funcall2_protect_extern(pval, g_RubyID_call, 1, &oval, &status);
419 #pragma mark ====== MyListCtrlDataSource methods ======
422 RubyDialogFrame::GetItemCount(MyListCtrl *ctrl)
424 return RubyDialog_GetTableItemCount((RubyValue)dval, (RDItem *)ctrl);
428 RubyDialogFrame::GetItemText(MyListCtrl *ctrl, long row, long column) const
431 RubyDialog_GetTableItemText((RubyValue)dval, (RDItem *)ctrl, row, column, buf, sizeof buf);
432 wxString str(buf, WX_DEFAULT_CONV);
437 RubyDialogFrame::SetItemText(MyListCtrl *ctrl, long row, long column, const wxString &value)
439 return RubyDialog_SetTableItemText((RubyValue)dval, (RDItem *)ctrl, row, column, value.mb_str(WX_DEFAULT_CONV));
443 RubyDialogFrame::DragSelectionToRow(MyListCtrl *ctrl, long row)
445 RubyDialog_DragTableSelectionToRow((RubyValue)dval, (RDItem *)ctrl, row);
449 RubyDialogFrame::IsItemEditable(MyListCtrl *ctrl, long row, long column)
451 return RubyDialog_IsTableItemEditable((RubyValue)dval, (RDItem *)ctrl, row, column);
455 RubyDialogFrame::IsDragAndDropEnabled(MyListCtrl *ctrl)
457 return RubyDialog_IsTableDragAndDropEnabled((RubyValue)dval, (RDItem *)ctrl);
461 RubyDialogFrame::OnSelectionChanged(MyListCtrl *ctrl)
463 RubyDialog_OnTableSelectionChanged((RubyValue)dval, (RDItem *)ctrl);
467 RubyDialogFrame::SetItemColor(MyListCtrl *ctrl, long row, long col, float *fg, float *bg)
469 return RubyDialog_SetTableItemColor((RubyValue)dval, (RDItem *)ctrl, row, col, fg, bg);
473 RubyDialogFrame::HasPopUpMenu(MyListCtrl *ctrl, long row, long column, char ***menu_titles)
475 return RubyDialog_HasPopUpMenu((RubyValue)dval, (RDItem *)ctrl, row, column, menu_titles);
479 RubyDialogFrame::OnPopUpMenuSelected(MyListCtrl *ctrl, long row, long column, int selected_index)
481 RubyDialog_OnPopUpMenuSelected((RubyValue)dval, (RDItem *)ctrl, row, column, selected_index);
484 #pragma mark ====== Plain C interface ======
487 RubyDialogCallback_new(int style)
489 /* RubyDialogFrame should not have a close box */
490 RubyDialogFrame *dref;
491 int fstyle = wxCAPTION | wxSYSTEM_MENU;
492 if (style & rd_Resizable)
493 fstyle |= wxRESIZE_BOX | wxRESIZE_BORDER;
494 dref = new RubyDialogFrame(GetMainFrame(), -1, _T("Ruby Dialog"), wxDefaultPosition, wxDefaultSize, fstyle);
495 return (RubyDialog *)dref;
499 RubyDialogCallback_release(RubyDialog *dref)
501 ((RubyDialogFrame *)dref)->Destroy();
505 RubyDialogCallback_setRubyObject(RubyDialog *dref, RubyValue val)
507 ((RubyDialogFrame *)dref)->SetRubyObject(val);
511 RubyDialogCallback_setWindowTitle(RubyDialog *dref, const char *title)
513 wxString str(title, WX_DEFAULT_CONV);
514 ((RubyDialogFrame *)dref)->SetLabel(str);
518 RubyDialogCallback_runModal(RubyDialog *dref)
520 int retval = ((RubyDialogFrame *)dref)->ShowModal();
521 if (retval == wxID_OK)
523 else return 1; /* Cancel */
527 RubyDialogCallback_endModal(RubyDialog *dref, int status)
529 ((RubyDialogFrame *)dref)->StopIntervalTimer();
530 if (((RubyDialogFrame *)dref)->IsModal())
531 ((RubyDialogFrame *)dref)->EndModal(status == 0 ? wxID_OK : wxID_CANCEL);
532 else ((RubyDialogFrame *)dref)->Close();
536 RubyDialogCallback_close(RubyDialog *dref)
538 ((RubyDialogFrame *)dref)->StopIntervalTimer();
539 ((RubyDialogFrame *)dref)->Close();
543 RubyDialogCallback_show(RubyDialog *dref)
545 if (((RubyDialogFrame *)dref)->myTimer != NULL)
546 ((RubyDialogFrame *)dref)->StartIntervalTimer(-1);
547 ((RubyDialogFrame *)dref)->Show(true);
548 ((RubyDialogFrame *)dref)->Raise();
552 RubyDialogCallback_hide(RubyDialog *dref)
554 ((RubyDialogFrame *)dref)->StopIntervalTimer();
555 ((RubyDialogFrame *)dref)->Show(false);
559 RubyDialogCallback_startIntervalTimer(RubyDialog *dref, float interval)
561 return ((RubyDialogFrame *)dref)->StartIntervalTimer(interval * 1000);
565 RubyDialogCallback_stopIntervalTimer(RubyDialog *dref)
567 ((RubyDialogFrame *)dref)->StopIntervalTimer();
571 RDRectFromwxRect(const wxRect &frame)
574 rframe.origin.x = frame.x;
575 rframe.origin.y = frame.y;
576 rframe.size.width = frame.width;
577 rframe.size.height = frame.height;
582 wxRectFromRDRect(RDRect rframe)
584 wxRect frame(rframe.origin.x, rframe.origin.y, rframe.size.width, rframe.size.height);
589 RubyDialogCallback_windowMinSize(RubyDialog *dref)
591 wxSize minSize = ((RubyDialogFrame *)dref)->GetMinSize();
593 rminSize.width = minSize.GetWidth();
594 rminSize.height = minSize.GetHeight();
599 RubyDialogCallback_setWindowMinSize(RubyDialog *dref, RDSize size)
602 minSize.x = size.width;
603 minSize.y = size.height;
604 ((RubyDialogFrame *)dref)->SetMinSize(minSize);
608 RubyDialogCallback_windowSize(RubyDialog *dref)
610 wxSize minSize = ((RubyDialogFrame *)dref)->GetSize();
612 rminSize.width = minSize.GetWidth();
613 rminSize.height = minSize.GetHeight();
617 RubyDialogCallback_setWindowSize(RubyDialog *dref, RDSize size)
619 wxSize wsize(size.width, size.height);
620 ((RubyDialogFrame *)dref)->SetSize(wsize);
621 ((RubyDialogFrame *)dref)->CentreOnScreen();
625 RubyDialogCallback_setAutoResizeEnabled(RubyDialog *dref, int flag)
627 ((RubyDialogFrame *)dref)->SetAutoResizeEnabled(flag);
631 RubyDialogCallback_isAutoResizeEnabled(RubyDialog *dref)
633 return ((RubyDialogFrame *)dref)->IsAutoResizeEnabled();
637 RubyDialogCallback_Listen(RubyDialog *dref, void *obj, const char *objtype, const char *msg, RubyValue oval, RubyValue pval)
639 return ((RubyDialogFrame *)dref)->ListenToObject(obj, objtype, msg, oval, pval);
643 RubyDialogCallback_createStandardButtons(RubyDialog *dref, const char *oktitle, const char *canceltitle)
645 ((RubyDialogFrame *)dref)->CreateStandardButtons(oktitle, canceltitle);
649 OffsetForItemRect(const char *type)
651 wxRect offset(0, 0, 0, 0);
652 if (strcmp(type, "textfield") == 0) {
653 #if defined(__WXMAC__)
657 else if (strcmp(type, "button") == 0) {
658 #if defined(__WXMAC__)
665 } else if (strcmp(type, "checkbox") == 0) {
672 RubyDialogCallback_createItem(RubyDialog *dref, const char *type, const char *title, RDRect frame)
674 wxWindow *control = NULL;
676 RubyDialogFrame *parent = ((RubyDialogFrame *)dref);
677 wxString tstr((title ? title : ""), WX_DEFAULT_CONV);
678 bool no_action = false;
680 rect = wxRectFromRDRect(frame);
681 offset = OffsetForItemRect(type);
682 if (rect.width == 0 && rect.height == 0) {
683 rect.SetPosition(wxDefaultPosition);
684 rect.SetSize(wxDefaultSize);
686 rect.SetX(rect.x + offset.x);
687 rect.SetY(rect.y + offset.y);
688 rect.SetWidth(rect.width + offset.width);
689 rect.SetHeight(rect.height + offset.height);
692 if (strcmp(type, "text") == 0) {
694 long style = wxST_NO_AUTORESIZE;
695 if (rect.width == wxDefaultSize.x && rect.height == wxDefaultSize.y)
696 style = 0; /* Allow autoresize */
697 wxStaticText *st = new wxStaticText(parent, -1, tstr, rect.GetPosition(), rect.GetSize(), style);
700 } else if (strcmp(type, "textfield") == 0) {
702 wxTextCtrl *tc = new wxTextCtrl(parent, -1, tstr, rect.GetPosition(), rect.GetSize());
704 tc->Connect(-1, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, parent);
705 } else if (strcmp(type, "textview") == 0) {
707 wxTextCtrl *tc = new wxTextCtrl(parent, -1, tstr, rect.GetPosition(), rect.GetSize(), wxTE_MULTILINE | wxTE_RICH);
709 tc->Connect(-1, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, parent);
710 } else if (strcmp(type, "view") == 0) {
712 wxPanel *pn = new wxPanel(parent, -1, rect.GetPosition(), rect.GetSize());
714 } else if (strcmp(type, "line") == 0) {
716 int direction = (rect.width > rect.height ? wxLI_HORIZONTAL : wxLI_VERTICAL);
717 wxStaticLine *ln = new wxStaticLine(parent, -1, rect.GetPosition(), rect.GetSize(), direction);
719 /* printf("is_vertical = %d\n", (int)ln->IsVertical()); */
720 } else if (strcmp(type, "button") == 0) {
722 wxButton *bn = new wxButton(parent, -1, tstr, rect.GetPosition(), rect.GetSize());
724 bn->Connect(-1, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, parent);
725 } else if (strcmp(type, "togglebutton") == 0) {
727 wxToggleButton *bn = new wxToggleButton(parent, -1, tstr, rect.GetPosition(), rect.GetSize());
729 bn->Connect(-1, wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, parent);
730 } else if (strcmp(type, "popup") == 0) {
731 /* Popup button (wxChoice) */
732 wxString du[1] = { _T(" ") };
733 wxChoice *ch = new wxChoice(parent, -1, rect.GetPosition(), rect.GetSize(), 1, du);
735 ch->Connect(-1, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, parent);
736 } else if (strcmp(type, "checkbox") == 0) {
737 /* Checkbox (wxCheckBox) */
738 wxCheckBox *cb = new wxCheckBox(parent, -1, tstr, rect.GetPosition(), rect.GetSize());
740 cb->Connect(-1, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, parent);
741 } else if (strcmp(type, "radio") == 0) {
742 /* Radio button (not grouped) */
743 wxRadioButton *rb = new wxRadioButton(parent, -2, tstr, rect.GetPosition(), rect.GetSize(), wxRB_SINGLE);
745 rb->Connect(-1, wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, parent);
746 } else if (strcmp(type, "table") == 0) {
747 /* Table view = MyListCtrl */
748 MyListCtrl *tb = new MyListCtrl();
749 tb->Create(parent, -1, rect.GetPosition(), rect.GetSize());
751 tb->SetDataSource(parent);
754 if (title[0] != 0 || strcmp(type, "textfield") == 0) {
755 /* Resize the frame rect as necessary */
756 RDSize minSize = RubyDialogCallback_sizeOfString((RDItem *)control, title);
757 wxSize size = control->GetSize();
758 if (size.GetHeight() < minSize.height)
759 size.SetHeight(minSize.height);
760 if (size.GetWidth() < minSize.width)
761 size.SetWidth(minSize.width);
762 size.SetWidth(size.GetWidth() + offset.width);
763 size.SetHeight(size.GetHeight() + offset.height);
764 control->SetSize(size);
767 if (wxDynamicCast(control, wxTextCtrl) != NULL) {
768 /* Set default font */
770 attr.SetFont(wxSystemSettings::GetFont(wxSYS_SYSTEM_FONT));
771 ((wxTextCtrl *)control)->SetDefaultStyle(attr);
774 ((RubyDialogFrame *)dref)->AddDialogItem((RDItem *)control);
776 return (RDItem *)control;
780 RubyDialogCallback_dialogItemAtIndex(RubyDialog *dref, int idx)
783 return (RDItem *)dref;
784 else return ((RubyDialogFrame *)dref)->DialogItemAtIndex(idx);
788 RubyDialogCallback_indexOfItem(RubyDialog *dref, RDItem *item)
790 return ((RubyDialogFrame *)dref)->SearchDialogItem(item);
794 RubyDialogCallback_moveItemUnderView(RDItem *item, RDItem *superView, RDPoint origin)
796 if (item == NULL || superView == NULL || item == superView)
798 if (((wxWindow *)item)->Reparent((wxWindow *)superView)) {
799 ((wxWindow *)item)->Move(origin.x, origin.y);
804 RubyDialogCallback_superview(RDItem *item)
806 return (RDItem *)(((wxWindow *)item)->GetParent());
810 RubyDialogCallback_frameOfItem(RDItem *item)
812 wxRect rect = ((wxWindow *)item)->GetRect();
813 if (gRubyDialogIsFlipped) {
814 wxWindow *parent = ((wxWindow *)item)->GetParent();
815 if (parent != NULL) {
816 wxRect superRect = parent->GetRect();
817 rect.SetY(superRect.GetHeight() - rect.GetHeight() - rect.GetY());
820 return RDRectFromwxRect(rect);
824 RubyDialogCallback_setFrameOfItem(RDItem *item, RDRect rect)
826 wxRect wrect = wxRectFromRDRect(rect);
827 if (gRubyDialogIsFlipped) {
828 wxWindow *parent = ((wxWindow *)item)->GetParent();
829 if (parent != NULL) {
830 wxRect srect = parent->GetRect();
831 wrect.SetY(srect.GetHeight() - wrect.GetHeight() - wrect.GetY());
834 ((wxWindow *)item)->SetSize(wrect);
838 RubyDialogCallback_setStringToItem(RDItem *item, const char *s)
840 wxString str(s, WX_DEFAULT_CONV);
841 if (wxDynamicCast((wxWindow *)item, wxTextCtrl) != NULL) {
842 ((wxTextCtrl *)item)->SetValue(str);
847 RubyDialogCallback_getStringFromItem(RDItem *item, char *buf, int bufsize)
850 if (wxDynamicCast((wxWindow *)item, wxTextCtrl) != NULL) {
851 str = ((wxTextCtrl *)item)->GetValue();
856 strncpy(buf, str.mb_str(WX_DEFAULT_CONV), bufsize - 1);
857 buf[bufsize - 1] = 0;
861 RubyDialogCallback_getStringPtrFromItem(RDItem *item)
864 if (wxDynamicCast((wxWindow *)item, wxTextCtrl) != NULL) {
865 str = ((wxTextCtrl *)item)->GetValue();
869 return strdup(str.mb_str(WX_DEFAULT_CONV));
873 RubyDialogCallback_titleOfItem(RDItem *item)
876 if (wxDynamicCast((wxWindow *)item, wxTextCtrl) != NULL) {
877 str = ((wxTextCtrl *)item)->GetValue();
879 str = ((wxWindow *)item)->GetLabel();
881 return strdup(str.mb_str(WX_DEFAULT_CONV));
885 RubyDialogCallback_setTitleToItem(RDItem *item, const char *s)
887 wxString str(s, WX_DEFAULT_CONV);
888 if (wxDynamicCast((wxWindow *)item, wxTextCtrl) != NULL) {
889 ((wxTextCtrl *)item)->SetValue(str);
891 ((wxWindow *)item)->SetLabel(str);
896 RubyDialogCallback_setEnabledForItem(RDItem *item, int flag)
898 ((wxWindow *)item)->Enable(flag);
902 RubyDialogCallback_isItemEnabled(RDItem *item)
904 /* if (wxDynamicCast((wxWindow *)item, wxTextCtrl) != NULL)
905 return ((wxTextCtrl *)item)->IsEditable();
907 return ((wxWindow *)item)->IsEnabled();
911 RubyDialogCallback_setEditableForItem(RDItem *item, int flag)
913 if (wxDynamicCast((wxWindow *)item, wxTextCtrl) != NULL)
914 return ((wxTextCtrl *)item)->SetEditable(flag);
918 RubyDialogCallback_isItemEditable(RDItem *item)
920 if (wxDynamicCast((wxWindow *)item, wxTextCtrl) != NULL)
921 return ((wxTextCtrl *)item)->IsEditable();
926 RubyDialogCallback_setStateForItem(RDItem *item, int state)
928 if (wxDynamicCast((wxWindow *)item, wxRadioButton) != NULL) {
929 ((wxRadioButton *)item)->SetValue(state);
930 } else if (wxDynamicCast((wxWindow *)item, wxCheckBox) != NULL) {
931 ((wxCheckBox *)item)->SetValue(state);
932 } else if (wxDynamicCast((wxWindow *)item, wxToggleButton) != NULL) {
933 ((wxToggleButton *)item)->SetValue(state);
938 RubyDialogCallback_getStateForItem(RDItem *item)
940 if (wxDynamicCast((wxWindow *)item, wxRadioButton) != NULL) {
941 return ((wxRadioButton *)item)->GetValue();
942 } else if (wxDynamicCast((wxWindow *)item, wxCheckBox) != NULL) {
943 return ((wxCheckBox *)item)->GetValue();
944 } else if (wxDynamicCast((wxWindow *)item, wxToggleButton) != NULL) {
945 return ((wxToggleButton *)item)->GetValue();
950 RubyDialogCallback_setHiddenForItem(RDItem *item, int flag)
952 ((wxWindow *)item)->Show(flag == 0);
956 RubyDialogCallback_isItemHidden(RDItem *item)
958 return !(((wxWindow *)item)->IsShown());
962 RubyDialogCallback_setFontForItem(RDItem *item, int size, int family, int style, int weight)
967 if ((ctrl = wxDynamicCast((wxWindow *)item, wxTextCtrl)) != NULL) {
968 wxTextAttr attr = ctrl->GetDefaultStyle();
969 font = attr.GetFont();
970 } else if ((stxt = wxDynamicCast((wxWindow *)item, wxStaticText)) != NULL) {
971 font = stxt->GetFont();
974 size = font.GetPointSize();
976 family = font.GetFamily();
978 family = (family == 2 ? wxFONTFAMILY_ROMAN :
979 (family == 3 ? wxFONTFAMILY_SWISS :
980 (family == 4 ? wxFONTFAMILY_MODERN :
981 wxFONTFAMILY_DEFAULT)));
984 style = font.GetStyle();
986 style = (style == 2 ? wxFONTSTYLE_SLANT :
987 (style == 3 ? wxFONTSTYLE_ITALIC :
988 wxFONTSTYLE_NORMAL));
991 weight = font.GetWeight();
993 weight = (weight == 2 ? wxFONTWEIGHT_BOLD :
994 (weight == 3 ? wxFONTWEIGHT_LIGHT :
995 wxFONTWEIGHT_NORMAL));
999 newAttr.SetFont(wxFont(size, family, style, weight));
1000 ctrl->SetDefaultStyle(newAttr);
1001 } else if (stxt != NULL) {
1002 stxt->SetFont(wxFont(size, family, style, weight));
1003 wxString label = stxt->GetLabel();
1004 stxt->SetLabel(_(""));
1005 stxt->SetLabel(label); /* Update the control size */
1010 RubyDialogCallback_getFontForItem(RDItem *item, int *size, int *family, int *style, int *weight)
1014 if ((ctrl = wxDynamicCast((wxWindow *)item, wxTextCtrl)) != NULL) {
1015 wxTextAttr attr = ctrl->GetDefaultStyle();
1016 wxFont font = attr.GetFont();
1018 *size = font.GetPointSize();
1019 if (family != NULL) {
1020 n = font.GetFamily();
1021 *family = (n == wxFONTFAMILY_DEFAULT ? 1 :
1022 (n == wxFONTFAMILY_ROMAN ? 2 :
1023 (n == wxFONTFAMILY_SWISS ? 3 :
1024 (n == wxFONTFAMILY_MODERN ? 4 :
1027 if (style != NULL) {
1028 n = font.GetStyle();
1029 *style = (n == wxFONTSTYLE_NORMAL ? 1 :
1030 (n == wxFONTSTYLE_SLANT ? 2 :
1031 (n == wxFONTSTYLE_ITALIC ? 3 :
1034 if (weight != NULL) {
1035 n = font.GetWeight();
1036 *weight = (n == wxFONTWEIGHT_NORMAL ? 1 :
1037 (n == wxFONTWEIGHT_BOLD ? 2 :
1038 (n == wxFONTWEIGHT_LIGHT ? 3 :
1046 RubyDialogCallback_appendString(RDItem *item, const char *str)
1049 if ((ctrl = wxDynamicCast((wxWindow *)item, wxTextCtrl)) != NULL) {
1050 ctrl->AppendText(wxString(str, WX_DEFAULT_CONV));
1056 RubyDialogCallback_setNeedsDisplay(RDItem *item, int flag)
1059 ((wxWindow *)item)->Refresh();
1063 RubyDialogCallback_countSubItems(RDItem *item)
1065 if (wxDynamicCast((wxWindow *)item, wxChoice) != NULL) {
1066 return ((wxChoice *)item)->GetCount();
1071 RubyDialogCallback_appendSubItem(RDItem *item, const char *s)
1073 wxString str(s, WX_DEFAULT_CONV);
1074 if (wxDynamicCast((wxWindow *)item, wxChoice) != NULL) {
1075 return ((wxChoice *)item)->Append(str);
1080 RubyDialogCallback_insertSubItem(RDItem *item, const char *s, int pos)
1082 wxString str(s, WX_DEFAULT_CONV);
1083 if (wxDynamicCast((wxWindow *)item, wxChoice) != NULL && pos >= 0 && pos < ((wxChoice *)item)->GetCount()) {
1084 return ((wxChoice *)item)->Insert(str, pos);
1089 RubyDialogCallback_deleteSubItem(RDItem *item, int pos)
1091 if (wxDynamicCast((wxWindow *)item, wxChoice) != NULL && pos >= 0 && pos < ((wxChoice *)item)->GetCount()) {
1092 ((wxChoice *)item)->Delete(pos);
1098 RubyDialogCallback_titleOfSubItem(RDItem *item, int pos)
1100 if (wxDynamicCast((wxWindow *)item, wxChoice) != NULL && pos >= 0 && pos < ((wxChoice *)item)->GetCount()) {
1101 wxString str = ((wxChoice *)item)->GetString(pos);
1102 return strdup(str.mb_str(WX_DEFAULT_CONV));
1107 RubyDialogCallback_setSelectedSubItem(RDItem *item, int pos)
1109 if (wxDynamicCast((wxWindow *)item, wxChoice) != NULL && pos >= 0 && pos < ((wxChoice *)item)->GetCount()) {
1110 ((wxChoice *)item)->SetSelection(pos);
1115 RubyDialogCallback_selectedSubItem(RDItem *item)
1117 if (wxDynamicCast((wxWindow *)item, wxChoice) != NULL) {
1118 return ((wxChoice *)item)->GetSelection();
1123 RubyDialogCallback_sizeOfString(RDItem *item, const char *s)
1126 wxCoord w, h, descent, leading;
1127 wxPaintDC dc((wxWindow *)item);
1129 const char *s1, *s2, *sfin;
1130 size.width = size.height = 0;
1131 s1 = (s == NULL || s[0] == 0 ? " " : s);
1135 s2 = strchr(s1, '\n');
1138 wxString str(s1, WX_DEFAULT_CONV, s2 - s1);
1139 dc.GetTextExtent(str, &w, &h, &descent, &leading);
1142 size.height += h + descent + leading;
1151 RubyDialogCallback_resizeToBest(RDItem *item)
1155 size = ((wxWindow *)item)->GetBestSize();
1156 ((wxWindow *)item)->SetSize(size);
1157 rsize.width = size.GetWidth();
1158 rsize.height = size.GetHeight();
1163 RubyDialogCallback_deleteTableColumn(RDItem *item, int col)
1165 if (wxDynamicCast((wxWindow *)item, MyListCtrl) != NULL) {
1166 return ((MyListCtrl *)item)->DeleteColumn(col);
1167 } else return false;
1171 RubyDialogCallback_insertTableColumn(RDItem *item, int col, const char *heading, int format, int width)
1173 if (wxDynamicCast((wxWindow *)item, MyListCtrl) != NULL) {
1174 wxString hstr((heading ? heading : ""), WX_DEFAULT_CONV);
1175 return ((MyListCtrl *)item)->InsertColumn(col, hstr, format, width);
1176 } else return false;
1180 RubyDialogCallback_countTableColumn(RDItem *item)
1182 if (wxDynamicCast((wxWindow *)item, MyListCtrl) != NULL) {
1183 return ((MyListCtrl *)item)->GetColumnCount();
1188 RubyDialogCallback_isTableRowSelected(RDItem *item, int row)
1190 if (wxDynamicCast((wxWindow *)item, MyListCtrl) != NULL) {
1191 return ((MyListCtrl *)item)->GetItemState(row, wxLIST_STATE_SELECTED) != 0;
1192 } else return false;
1196 RubyDialogCallback_setTableRowSelected(RDItem *item, int row, int flag)
1198 if (wxDynamicCast((wxWindow *)item, MyListCtrl) != NULL) {
1199 long state = (flag ? wxLIST_STATE_SELECTED : 0);
1200 return ((MyListCtrl *)item)->SetItemState(row, state, wxLIST_STATE_SELECTED);
1201 } else return false;
1205 RubyDialogCallback_refreshTable(RDItem *item)
1207 if (wxDynamicCast((wxWindow *)item, MyListCtrl) != NULL) {
1208 ((MyListCtrl *)item)->RefreshTable();
1213 RubyDialogCallback_savePanel(const char *title, const char *dirname, const char *wildcard, char *buf, int bufsize)
1216 wxString pstr((dirname ? dirname : ""), WX_DEFAULT_CONV);
1217 wxString tstr((title ? title : "Choose a file"), WX_DEFAULT_CONV);
1218 wxString fstr(buf, WX_DEFAULT_CONV);
1219 wxString wstr((wildcard ? wildcard : "All files (*.*)|*.*"), WX_DEFAULT_CONV);
1220 wxWindow *old_focus = wxWindow::FindFocus();
1221 wxFileDialog *dialog = new wxFileDialog(NULL, tstr, pstr, fstr, wstr, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
1222 if (dialog->ShowModal() == wxID_OK) {
1223 strncpy(buf, dialog->GetPath().mb_str(wxConvFile), bufsize - 1);
1224 buf[bufsize - 1] = 0;
1231 if (old_focus != NULL)
1232 old_focus->SetFocus();
1237 RubyDialogCallback_openPanel(const char *title, const char *dirname, const char *wildcard, char ***array, int for_directories, int multiple_selection)
1240 wxString pstr((dirname ? dirname : ""), WX_DEFAULT_CONV);
1241 wxString wstr((wildcard ? wildcard : "All files (*.*)|*.*"), WX_DEFAULT_CONV);
1242 int style = wxFD_OPEN | (multiple_selection ? wxFD_MULTIPLE : 0);
1243 wxWindow *old_focus = wxWindow::FindFocus();
1244 if (for_directories) {
1245 wxString tstr((title ? title : "Choose a directory"), WX_DEFAULT_CONV);
1246 wxDirDialog *dialog = new wxDirDialog(NULL, tstr, pstr);
1247 if (dialog->ShowModal() == wxID_OK) {
1248 *array = (char **)malloc(sizeof(char *));
1249 (*array)[0] = strdup(dialog->GetPath().mb_str(wxConvFile));
1254 wxString tstr((title ? title : "Choose a file"), WX_DEFAULT_CONV);
1255 wxFileDialog *dialog = new wxFileDialog(NULL, tstr, pstr, _T(""), wstr, style);
1256 if (dialog->ShowModal() == wxID_OK) {
1257 if (multiple_selection) {
1259 wxArrayString paths;
1260 dialog->GetPaths(paths);
1261 n = paths.GetCount();
1262 *array = (char **)malloc(sizeof(char *) * n);
1263 for (i = 0; i < n; i++) {
1264 (*array)[i] = strdup(paths[i].mb_str(wxConvFile));
1268 *array = (char **)malloc(sizeof(char *));
1269 (*array)[0] = strdup(dialog->GetPath().mb_str(wxConvFile));
1275 if (old_focus != NULL)
1276 old_focus->SetFocus();