Author Topic: Toggle toolbar by context menu?  (Read 16551 times)

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6077
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Toggle toolbar by context menu?
« on: April 16, 2013, 08:44:56 am »
A draft patch is below:
Code
Index: main.cpp
===================================================================
--- main.cpp (revision 8991)
+++ main.cpp (working copy)
@@ -529,6 +529,8 @@
     EVT_MENU(idShiftTab,   MainFrame::OnShiftTab)
     EVT_MENU(idCtrlAltTab, MainFrame::OnCtrlAltTab)
 
+    EVT_RIGHT_UP(MainFrame::OnMouseRightUp)
+
 END_EVENT_TABLE()
 
 MainFrame::MainFrame(wxWindow* parent)
@@ -4829,3 +4831,16 @@
 
     return sb;
 }
+// Let the user toggle the toolbar and logs from the context menu
+void MainFrame::OnMouseRightUp(wxMouseEvent& event)
+{
+    wxMenuBar* menuBar = Manager::Get()->GetAppFrame()->GetMenuBar();
+    int idx = menuBar->FindMenu(_("&View"));
+    wxMenu* viewMenu;
+    if (idx != wxNOT_FOUND)
+    {
+        viewMenu = menuBar->GetMenu(idx);
+        PopupMenu(viewMenu);
+    }
+    event.Skip();
+}
Index: main.h
===================================================================
--- main.h (revision 8991)
+++ main.h (working copy)
@@ -95,6 +95,8 @@
         void OnApplicationClose(wxCloseEvent& event);
         void OnStartHereLink(wxCommandEvent& event);
 
+        void OnMouseRightUp(wxMouseEvent& event);
+
         // File->New submenu entries handler
         void OnFileNewWhat(wxCommandEvent& event);
 


I just want to toggle the toolbar status more convenient by using right click.

See screen shot below:



Any comments? (Maybe, the whole menu under "View" is too large, we can only show menus under "Toolbars" sub-menu)
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline BlueHazzard

  • Developer
  • Lives here!
  • *****
  • Posts: 3352
Re: Toggle toolbar by context menu?
« Reply #1 on: April 16, 2013, 09:38:24 am »
Maybe, the whole menu under "View" is too large, we can only show menus under "Toolbars" sub-menu

i think this would be a great idea!
thank you!

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13406
    • Travis build status
Re: Toggle toolbar by context menu?
« Reply #2 on: April 16, 2013, 09:45:51 am »
Maybe, the whole menu under "View" is too large, we can only show menus under "Toolbars" sub-menu
Only toolbars' menu, please.

i think this would be a great idea!
I don't think, so. But this is my opinion.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6077
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Toggle toolbar by context menu?
« Reply #3 on: April 16, 2013, 11:35:03 am »
Thanks for the comments, here is the new patch which only show the sub-menu of toolbars.
Code
Index: main.cpp
===================================================================
--- main.cpp (revision 8991)
+++ main.cpp (working copy)
@@ -529,6 +529,8 @@
     EVT_MENU(idShiftTab,   MainFrame::OnShiftTab)
     EVT_MENU(idCtrlAltTab, MainFrame::OnCtrlAltTab)
 
+    EVT_RIGHT_UP(MainFrame::OnMouseRightUp)
+
 END_EVENT_TABLE()
 
 MainFrame::MainFrame(wxWindow* parent)
@@ -4829,3 +4831,20 @@
 
     return sb;
 }
+// Let the user toggle the toolbar from the context menu
+void MainFrame::OnMouseRightUp(wxMouseEvent& event)
+{
+    wxMenuBar* menuBar = Manager::Get()->GetAppFrame()->GetMenuBar();
+    int idx = menuBar->FindMenu(_("&View"));
+    if (idx != wxNOT_FOUND)
+    {
+        wxMenu* viewMenu = menuBar->GetMenu(idx);
+        idx = viewMenu->FindItem(_("Toolbars"));
+        if (idx != wxNOT_FOUND)
+        {
+            wxMenu* toolbarMenu = viewMenu->FindItem(idx)->GetSubMenu();
+            PopupMenu(toolbarMenu);
+        }
+    }
+    event.Skip();
+}
Index: main.h
===================================================================
--- main.h (revision 8991)
+++ main.h (working copy)
@@ -95,6 +95,8 @@
         void OnApplicationClose(wxCloseEvent& event);
         void OnStartHereLink(wxCommandEvent& event);
 
+        void OnMouseRightUp(wxMouseEvent& event);
+
         // File->New submenu entries handler
         void OnFileNewWhat(wxCommandEvent& event);
 

The only issue is when right click on the title bar of the Logs and project manager (see the red rectangle of the image below), it can also show the context menu.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13406
    • Travis build status
Re: Toggle toolbar by context menu?
« Reply #4 on: April 16, 2013, 11:43:41 am »
Why don't you connect the event to the toolbars themselves?
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6077
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Toggle toolbar by context menu?
« Reply #5 on: April 16, 2013, 11:54:05 am »
Why don't you connect the event to the toolbars themselves?
Do you mean popup the menu when click click on the toolbar button? In-fact I don't know how to do it. :)
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13406
    • Travis build status
Re: Toggle toolbar by context menu?
« Reply #6 on: April 16, 2013, 12:29:59 pm »
Not a button, but the whole toolbar.

Have you tried mytoolbar->Connect(...)  ?
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6077
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Toggle toolbar by context menu?
« Reply #7 on: April 16, 2013, 03:28:23 pm »
Not a button, but the whole toolbar.

Have you tried mytoolbar->Connect(...)  ?
Ok, thanks for the suggestion, here is the patch:
Code
Index: main.cpp
===================================================================
--- main.cpp (revision 8991)
+++ main.cpp (working copy)
@@ -529,6 +529,8 @@
     EVT_MENU(idShiftTab,   MainFrame::OnShiftTab)
     EVT_MENU(idCtrlAltTab, MainFrame::OnCtrlAltTab)
 
+    //EVT_RIGHT_UP(MainFrame::OnMouseRightUp)
+
 END_EVENT_TABLE()
 
 MainFrame::MainFrame(wxWindow* parent)
@@ -1057,9 +1059,13 @@
     Manager::Get()->AddonToolBar(m_pToolbar, xrcToolbarName);
 
     m_pToolbar->Realize();
+    m_pToolbar->Connect(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED, wxCommandEventHandler(MainFrame::OnMouseRightUp) );
 
+
     m_pToolbar->SetInitialSize();
+    m_debuggerToolbarHandler->GetToolbar()->Connect(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED, wxCommandEventHandler(MainFrame::OnMouseRightUp) );
 
+
     std::vector<ToolbarInfo> toolbars;
 
     toolbars.push_back(ToolbarInfo(m_pToolbar, wxAuiPaneInfo().Name(wxT("MainToolbar")).Caption(_("Main Toolbar")), 0));
@@ -1076,7 +1082,11 @@
         {
             ToolbarInfo info = DoAddPluginToolbar(plug);
             if (info.toolbar)
+            {
                 toolbars.push_back(info);
+                info.toolbar->Connect(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED, wxCommandEventHandler(MainFrame::OnMouseRightUp) );
+            }
+
         }
     }
 
@@ -4829,3 +4839,20 @@
 
     return sb;
 }
+// Let the user toggle the toolbar and logs from the context menu
+void MainFrame::OnMouseRightUp(wxCommandEvent& event)
+{
+    wxMenuBar* menuBar = Manager::Get()->GetAppFrame()->GetMenuBar();
+    int idx = menuBar->FindMenu(_("&View"));
+    if (idx != wxNOT_FOUND)
+    {
+        wxMenu* viewMenu = menuBar->GetMenu(idx);
+        idx = viewMenu->FindItem(_("Toolbars"));
+        if (idx != wxNOT_FOUND)
+        {
+            wxMenu* toolbarMenu = viewMenu->FindItem(idx)->GetSubMenu();
+            PopupMenu(toolbarMenu);
+        }
+    }
+    event.Skip();
+}
Index: main.h
===================================================================
--- main.h (revision 8991)
+++ main.h (working copy)
@@ -95,6 +95,8 @@
         void OnApplicationClose(wxCloseEvent& event);
         void OnStartHereLink(wxCommandEvent& event);
 
+        void OnMouseRightUp(wxCommandEvent& event);
+
         // File->New submenu entries handler
         void OnFileNewWhat(wxCommandEvent& event);
 


Question: what is the best place to disconnet the event handler?
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9723
Re: Toggle toolbar by context menu?
« Reply #8 on: April 17, 2013, 07:24:38 am »
Question: what is the best place to disconnet the event handler?
Hard to tell. As a rule of thumb if you put the Connect into the constructor, put the Disconnect in the destructor. If you put Connect in a "Init" method, put it in "UnInit" or alike. Whats most important is that you ensure it gets disconnected early enough, so that late calls into the method won't access invalid references. Its an event, so it literally can come at "any time".
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: https://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: https://wiki.codeblocks.org/index.php?title=FAQ

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6077
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Toggle toolbar by context menu?
« Reply #9 on: April 17, 2013, 09:19:33 am »
Thanks, here is the patch
1, handle right click on either toolbar(red rectangle) or the space next to toolbar(green rectangle). See image shot below:

2, disconnect the event handler of toolbar correctly.
Code
Index: main.cpp
===================================================================
--- main.cpp (revision 8991)
+++ main.cpp (working copy)
@@ -529,6 +529,8 @@
     EVT_MENU(idShiftTab,   MainFrame::OnShiftTab)
     EVT_MENU(idCtrlAltTab, MainFrame::OnCtrlAltTab)
 
+    EVT_RIGHT_UP(MainFrame::OnMouseRightUp)
+
 END_EVENT_TABLE()
 
 MainFrame::MainFrame(wxWindow* parent)
@@ -1057,9 +1059,13 @@
     Manager::Get()->AddonToolBar(m_pToolbar, xrcToolbarName);
 
     m_pToolbar->Realize();
+    m_pToolbar->Connect(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED, wxCommandEventHandler(MainFrame::OnToolBarRightClick) );
 
+
     m_pToolbar->SetInitialSize();
+    m_debuggerToolbarHandler->GetToolbar()->Connect(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED, wxCommandEventHandler(MainFrame::OnToolBarRightClick) );
 
+
     std::vector<ToolbarInfo> toolbars;
 
     toolbars.push_back(ToolbarInfo(m_pToolbar, wxAuiPaneInfo().Name(wxT("MainToolbar")).Caption(_("Main Toolbar")), 0));
@@ -1076,7 +1082,11 @@
         {
             ToolbarInfo info = DoAddPluginToolbar(plug);
             if (info.toolbar)
+            {
                 toolbars.push_back(info);
+                info.toolbar->Connect(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED, wxCommandEventHandler(MainFrame::OnToolBarRightClick) );
+            }
+
         }
     }
 
@@ -1710,6 +1720,8 @@
                 }
                 wxAuiPaneInfo paneInfo(toolbarInfo.paneInfo);
                 m_LayoutManager.AddPane(toolbarInfo.toolbar, paneInfo. ToolbarPane().Top().Row(row).Position(position));
+                // add the event handler for mouse right click
+                toolbarInfo.toolbar->Connect(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED, wxCommandEventHandler(MainFrame::OnToolBarRightClick));
 
                 DoUpdateLayout();
             }
@@ -2752,6 +2764,17 @@
         m_pInfoPane = 0L;
     }
 
+    // Disconnect the event handler for toolbar's mouse right click event before the plugin is
+    // unloaded in Manager::Shutdown().
+    PluginToolbarsMap::iterator it;
+    for( it = m_PluginsTools.begin(); it != m_PluginsTools.end(); ++it )
+    {
+        wxToolBar* toolbar = it->second;
+        if (toolbar)//Disconnect the mouse right click event handler before the toolbar is destroyed
+            toolbar->Disconnect(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED, wxCommandEventHandler(MainFrame::OnToolBarRightClick));
+
+    }
+
     Manager::Shutdown(); // Shutdown() is not Free(), Manager is automatically destroyed at exit
 
     Destroy();
@@ -4456,6 +4479,8 @@
     // remove toolbar, if any
     if (m_PluginsTools[plugin])
     {
+        //Disconnect the mouse right click event handler before the toolbar is destroyed
+        m_PluginsTools[plugin]->Disconnect(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED, wxCommandEventHandler(MainFrame::OnToolBarRightClick));
         m_LayoutManager.DetachPane(m_PluginsTools[plugin]);
         m_PluginsTools[plugin]->Destroy();
         m_PluginsTools.erase(plugin);
@@ -4829,3 +4854,33 @@
 
     return sb;
 }
+// Let the user toggle the toolbar and logs from the context menu
+void MainFrame::OnMouseRightUp(wxMouseEvent& event)
+{
+    PopupToggleToolbarMenu();
+    event.Skip();
+}
+
+void MainFrame::OnToolBarRightClick(wxCommandEvent& event)
+{
+    PopupToggleToolbarMenu();
+    event.Skip();
+}
+
+void MainFrame::PopupToggleToolbarMenu()
+{
+    wxMenuBar* menuBar = Manager::Get()->GetAppFrame()->GetMenuBar();
+    int idx = menuBar->FindMenu(_("&View"));
+    if (idx != wxNOT_FOUND)
+    {
+        wxMenu* viewMenu = menuBar->GetMenu(idx);
+        idx = viewMenu->FindItem(_("Toolbars"));
+        if (idx != wxNOT_FOUND)
+        {
+            wxMenu* toolbarMenu = viewMenu->FindItem(idx)->GetSubMenu();
+            PopupMenu(toolbarMenu);
+        }
+    }
+}
+
+
Index: main.h
===================================================================
--- main.h (revision 8991)
+++ main.h (working copy)
@@ -95,6 +95,14 @@
         void OnApplicationClose(wxCloseEvent& event);
         void OnStartHereLink(wxCommandEvent& event);
 
+        // the two functions below are used to show context menu to toggle toolbar view status
+        // OnMouseRightUp is handler for right click on MainFrame client space not covered by
+        // any other panels, OnToolBarRightClick is used to response the mouse right click command
+        // on the toolbar.
+        void OnMouseRightUp(wxMouseEvent& event);
+        void OnToolBarRightClick(wxCommandEvent& event);
+        void PopupToggleToolbarMenu();
+
         // File->New submenu entries handler
         void OnFileNewWhat(wxCommandEvent& event);
 
@@ -348,14 +356,14 @@
         LogManager*     m_pLogMan;
         InfoPane*       m_pInfoPane;
 
-        wxToolBar* m_pToolbar;
-        PluginToolbarsMap m_PluginsTools;
+        wxToolBar* m_pToolbar;   // main toolbar
+        PluginToolbarsMap m_PluginsTools; // plugin -> toolbar map
 
         PluginIDsMap m_PluginIDsMap;
         wxMenu* m_ToolsMenu;
         wxMenu* m_PluginsMenu;
         wxMenu* m_HelpPluginsMenu;
-        bool    m_ScanningForPlugins;
+        bool    m_ScanningForPlugins; // this variable is used to delay the UI construction
 
         bool m_SmallToolBar;
         bool m_StartupDone;

If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6077
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Toggle toolbar by context menu?
« Reply #10 on: May 01, 2013, 07:09:16 am »
I committed in rev9022.

The only issue is when right click on the title bar of the Logs and project manager (see the red rectangle of the image below), it can also show the context menu.
This issue can't be solved(unless we create a new derived class from wxAuiManager), because
Code
wxAuiDockUIPart* wxAuiManager::HitTest(int x, int y)
is not public exposed, I mean I can't check which UIPart is under the mouse click.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.