OSDN Git Service

Popup menu on the list control is implemented (also in the Ruby dialog)
authortoshinagata1964 <toshinagata1964@a2be9bc6-48de-4e38-9406-05402d4bc13c>
Fri, 2 Aug 2013 06:33:08 +0000 (06:33 +0000)
committertoshinagata1964 <toshinagata1964@a2be9bc6-48de-4e38-9406-05402d4bc13c>
Fri, 2 Aug 2013 06:33:08 +0000 (06:33 +0000)
git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/molby/trunk@379 a2be9bc6-48de-4e38-9406-05402d4bc13c

MolLib/Ruby_bind/ruby_dialog.c
MolLib/Ruby_bind/ruby_dialog.h
wxSources/MyListCtrl.cpp
wxSources/MyListCtrl.h
wxSources/RubyDialogFrame.cpp
wxSources/RubyDialogFrame.h
xcode-build/Molby.xcodeproj/project.pbxproj

index 0f4350f..4a5b445 100644 (file)
@@ -40,7 +40,7 @@ static VALUE
        /*  Data source for Table (= MyListCtrl)  */
        sOnCountSymbol, sOnGetValueSymbol, sOnSetValueSymbol, sOnSelectionChangedSymbol,
        sOnSetColorSymbol, sIsItemEditableSymbol, sIsDragAndDropEnabledSymbol, sOnDragSelectionToRowSymbol,
-       sSelectionSymbol, sColumnsSymbol, sRefreshSymbol;
+       sSelectionSymbol, sColumnsSymbol, sRefreshSymbol, sHasPopUpMenu, sOnPopUpMenuSelected;
 
 VALUE rb_cDialog = Qfalse;
 VALUE rb_cDialogItem = Qfalse;
@@ -1710,12 +1710,9 @@ RubyDialog_SetTableItemText(RubyValue self, RDItem *ip, int row, int column, con
        int status;
        void *vp[7] = { (void *)self, (void *)ip, (void *)sOnSetValueSymbol, (void *)row, (void *)column, (void *)str, NULL };
        VALUE val = rb_protect(s_RubyDialog_doTableAction, (VALUE)vp, &status);
-       if (status != 0) {
-               Molby_showError(status);
-               return -1;
-       } else if (val == Qnil)
+       if (status != 0 || val == Qnil) {
                return -1;
-       else
+       else
                return (int)vp[6];
 }
 
@@ -1735,10 +1732,7 @@ RubyDialog_IsTableItemEditable(RubyValue self, RDItem *ip, int row, int column)
        int status;
        void *vp[4] = { (void *)self, (void *)ip, (void *)sIsItemEditableSymbol, NULL };
        VALUE val = rb_protect(s_RubyDialog_doTableAction, (VALUE)vp, &status);
-       if (status != 0) {
-               Molby_showError(status);
-               return 0;
-       } else if (val == Qnil)
+       if (status != 0 || val == Qnil)
                return 0;
        else return (int)vp[3]; 
 }
@@ -1749,10 +1743,7 @@ RubyDialog_IsTableDragAndDropEnabled(RubyValue self, RDItem *ip)
        int status;
        void *vp[4] = { (void *)self, (void *)ip, (void *)sIsDragAndDropEnabledSymbol, NULL };
        VALUE val = rb_protect(s_RubyDialog_doTableAction, (VALUE)vp, &status);
-       if (status != 0) {
-               Molby_showError(status);
-               return 0;
-       } else if (val == Qnil)
+       if (status != 0 || val == Qnil)
                return 0;
        else return (int)vp[3]; 
 }
@@ -1773,14 +1764,32 @@ RubyDialog_SetTableItemColor(RubyValue self, RDItem *ip, int row, int column, fl
        int status;
        void *vp[8] = { (void *)self, (void *)ip, (void *)sOnSetColorSymbol, (void *)row, (void *)column, (void *)fg, (void *)bg, NULL };
        VALUE val = rb_protect(s_RubyDialog_doTableAction, (VALUE)vp, &status);
-       if (status != 0) {
-               Molby_showError(status);
-               return 0;
-       } else if (val == Qnil)
+       if (status != 0 || val == Qnil)
                return 0;
        else return (int)vp[7];
 }
 
+int
+RubyDialog_HasPopUpMenu(RubyValue self, RDItem *ip, int row, int column, char ***menu_titles)
+{
+       int status;
+       void *vp[7] = { (void *)self, (void *)ip, (void *)sHasPopUpMenu, (void *)row, (void *)column, (void *)menu_titles, NULL };
+       VALUE val = rb_protect(s_RubyDialog_doTableAction, (VALUE)vp, &status);
+       if (status != 0 || val == Qnil)
+               return 0;
+       else return (int)vp[6];
+}
+
+void
+RubyDialog_OnPopUpMenuSelected(RubyValue self, RDItem *ip, int row, int column, int selected_index)
+{
+       int status;
+       void *vp[7] = { (void *)self, (void *)ip, (void *)sOnPopUpMenuSelected, (void *)row, (void *)column, (void *)selected_index, NULL };
+       rb_protect(s_RubyDialog_doTableAction, (VALUE)vp, &status);
+       if (status != 0)
+               Molby_showError(status);
+}
+       
 #pragma mark ====== Utility function ======
 
 int
@@ -2035,7 +2044,7 @@ RubyDialogInitClass(void)
                        &sMediumSymbol, &sBoldSymbol, &sLightSymbol,
                        &sOnCountSymbol, &sOnGetValueSymbol, &sOnSetValueSymbol, &sOnSelectionChangedSymbol,
                        &sOnSetColorSymbol, &sIsItemEditableSymbol, &sIsDragAndDropEnabledSymbol, &sOnDragSelectionToRowSymbol,
-                       &sSelectionSymbol, &sColumnsSymbol, &sRefreshSymbol
+                       &sSelectionSymbol, &sColumnsSymbol, &sRefreshSymbol, &sHasPopUpMenu, &sOnPopUpMenuSelected
                };
                static const char *sTable2[] = {
                        "text", "textfield", "radio", "button",
@@ -2055,7 +2064,7 @@ RubyDialogInitClass(void)
                        "medium", "bold", "light",
                        "on_count", "on_get_value", "on_set_value", "on_selection_changed",
                        "on_set_color", "is_item_editable", "is_drag_and_drop_enabled", "on_drag_selection_to_row",
-                       "selection", "columns", "refresh"
+                       "selection", "columns", "refresh", "has_popup_menu", "on_popup_menu_selected"
                };
                int i;
                for (i = 0; i < sizeof(sTable1) / sizeof(sTable1[0]); i++)
index d9cb6ad..3acd0ca 100644 (file)
@@ -53,6 +53,7 @@ extern int RubyDialog_validateItemContent(RubyValue self, RDItem *ip, const char
 extern void RubyDialog_doItemAction(RubyValue self, RDItem *ip);
 extern void RubyDialog_doTimerAction(RubyValue self);
 extern int RubyDialog_getFlexFlags(RubyValue self, RDItem *ip);
+
 extern int RubyDialog_GetTableItemCount(RubyValue self, RDItem *ip);
 extern void RubyDialog_GetTableItemText(RubyValue self, RDItem *ip, int row, int column, char *buf, int blen);
 extern int RubyDialog_SetTableItemText(RubyValue self, RDItem *ip, int row, int column, const char *str);
@@ -61,6 +62,9 @@ extern int RubyDialog_IsTableItemEditable(RubyValue self, RDItem *ip, int row, i
 extern int RubyDialog_IsTableDragAndDropEnabled(RubyValue self, RDItem *ip);
 extern void RubyDialog_OnTableSelectionChanged(RubyValue self, RDItem *ip);
 extern int RubyDialog_SetTableItemColor(RubyValue self, RDItem *ip, int row, int column, float *fg, float *bg);
+extern int RubyDialog_HasPopUpMenu(RubyValue self, RDItem *ip, int row, int column, char ***menu_titles);
+extern void RubyDialog_OnPopUpMenuSelected(RubyValue self, RDItem *ip, int row, int column, int selected_index);
+       
 extern void RubyDialogInitClass(void);
 
 /*  Stub routines  */
index 1c8785e..d899f40 100644 (file)
  */
 
 #include "MyListCtrl.h"
+#include "MyMBConv.h"
 
 #include "wx/dcclient.h"
 #include "wx/scrolwin.h"
 #include "wx/glcanvas.h"
+#include "wx/menu.h"
 
 const wxEventType MyListCtrlEvent = wxNewEventType();
 
@@ -532,6 +534,13 @@ MyListCtrl::InsertColumn(long col, const wxString &heading, int format, int widt
 }
 
 void
+MyListCtrl::OnPopUpMenuSelected(wxCommandEvent &event)
+{
+       if (dataSource != NULL)
+               dataSource->OnPopUpMenuSelected(this, lastPopUpRow, lastPopUpColumn, event.GetId());
+}
+
+void
 MyListCtrl::OnLeftDClick(wxMouseEvent &event)
 {
        int row, col;
@@ -552,11 +561,31 @@ MyListCtrl::OnLeftDClick(wxMouseEvent &event)
 void
 MyListCtrl::OnMouseDown(wxMouseEvent &event)
 {
+       int row, col, i, n;
+       char **items;
+
        if (editText != NULL && editText->IsShown()) {
                //  During the text edit, mouse down outside the textctrl will terminate the editing
                EndEditText();
        }
 
+       wxPoint pos = event.GetPosition();
+       if (FindItemAtPosition(pos, &row, &col) && dataSource != NULL && (n = dataSource->HasPopUpMenu(this, row, col, &items)) > 0) {
+               wxMenu mnu;
+               for (i = 0; i < n; i++) {
+                       wxString itemStr(items[i], WX_DEFAULT_CONV);
+                       mnu.Append(i, itemStr);
+                       free(items[i]);
+                       items[i] = NULL;
+               }
+               free(items);
+               lastPopUpColumn = col;
+               lastPopUpRow = row;
+               mnu.Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MyListCtrl::OnPopUpMenuSelected), NULL, this);
+               PopupMenu(&mnu);
+               return;
+       }
+       
        //  Intercept mouse down event and post selection change notification
        //  (a workaround of wxMSW problem where EVT_LIST_ITEM_SELECTED is not sent in some occasions)
        PostSelectionChangeNotification();
index c52a126..14bee90 100644 (file)
@@ -44,7 +44,12 @@ public:
        virtual bool IsItemEditable(MyListCtrl *ctrl, long row, long column) { return false; }
        virtual bool IsDragAndDropEnabled(MyListCtrl *ctrl) { return false; }
        virtual void OnSelectionChanged(MyListCtrl *ctrl) {}
-       
+
+       //  If a popup menu is attached to the cell, then returns a positive integer, and *menu_titles should
+       //  contain a malloc()'ed array of char* pointers (that are also malloc()'ed or strdup()'ed)
+       virtual int HasPopUpMenu(MyListCtrl *ctrl, long row, long column, char ***menu_titles) { return 0; }
+       virtual void OnPopUpMenuSelected(MyListCtrl *ctrl, long row, long column, int selected_index) {}
+
        //  Return 1 if foreground color should be modified, 2 if background color should be modified, 3 if both
        virtual int SetItemColor(MyListCtrl *ctrl, long row, long col, float *fg, float *bg) { return 0; }
 };
@@ -104,13 +109,15 @@ public:
        
        void OnChar(wxKeyEvent &event);
        void OnMouseDown(wxMouseEvent &event);
+       void OnPopUpMenuSelected(wxCommandEvent &event);
        void OnLeftDClick(wxMouseEvent &event);
        
        void PostSelectionChangeNotification();
        
        bool selectionChangeNotificationSent;
        bool selectionChangeNotificationEnabled;
-       
+       int lastPopUpColumn, lastPopUpRow;
+
 private:
        DECLARE_DYNAMIC_CLASS(MyListCtrl)
        DECLARE_EVENT_TABLE()
index d6feda9..2446633 100644 (file)
@@ -442,6 +442,18 @@ RubyDialogFrame::SetItemColor(MyListCtrl *ctrl, long row, long col, float *fg, f
        return RubyDialog_SetTableItemColor((RubyValue)dval, (RDItem *)ctrl, row, col, fg, bg);
 }
 
+int
+RubyDialogFrame::HasPopUpMenu(MyListCtrl *ctrl, long row, long column, char ***menu_titles)
+{
+       return RubyDialog_HasPopUpMenu((RubyValue)dval, (RDItem *)ctrl, row, column, menu_titles);
+}
+
+void
+RubyDialogFrame::OnPopUpMenuSelected(MyListCtrl *ctrl, long row, long column, int selected_index)
+{
+       RubyDialog_OnPopUpMenuSelected((RubyValue)dval, (RDItem *)ctrl, row, column, selected_index);
+}
+
 #pragma mark ====== Plain C interface ======
 
 RubyDialog *
index fdb8c42..5487f24 100644 (file)
@@ -75,7 +75,9 @@ public:
        virtual bool IsDragAndDropEnabled(MyListCtrl *ctrl);
        virtual void OnSelectionChanged(MyListCtrl *ctrl);
        virtual int SetItemColor(MyListCtrl *ctrl, long row, long col, float *fg, float *bg);
-       
+       virtual int HasPopUpMenu(MyListCtrl *ctrl, long row, long column, char ***menu_titles);
+       virtual void OnPopUpMenuSelected(MyListCtrl *ctrl, long row, long column, int selected_index);
+               
 private:
        DECLARE_EVENT_TABLE()
 };
index 0aa0622..ab40d7f 100755 (executable)
                        children = (
                                E4A4667410C15B4300E40A9D /* listctrl.cpp */,
                                9E12580E119EC42E00E95DC3 /* docview.cpp */,
-                               E4513F530EED72C0009DF1F7 /* MyListCtrl.h */,
                                E40DDC6C1435C03E000F0E81 /* MyMBConv.h */,
+                               E4513F530EED72C0009DF1F7 /* MyListCtrl.h */,
                                E4513F540EED72C0009DF1F7 /* MyListCtrl.cpp */,
                                E4C8CBDD10B83060006C4692 /* MyDocManager.h */,
                                E4C8CBDE10B83060006C4692 /* MyDocManager.cpp */,