Kirix Support Forums

Interim Fix for Toolbar Orientation Switching

Please post any wxAUI patches or modifications you've created here. Thanks!

Interim Fix for Toolbar Orientation Switching

Postby NinjaNL on Tue Jan 22, 2008 4:38 am

As some of you may know (and Ben in any case must be getting sick of me asking about it) a new class wxAuiToolBar is coming (and has been mentioned for over a year now) which will take care of automatic orientation switching.

automatic orientation switching - when a toolbar is docked at the Top or Bottom dock, the toolbar will have horizontal orientation, when it is docked at the Left or Right it will have vertical orientation.

In the interim, I have managed to implement a sort of orientation switching in my development. It relies on another wxWidgets library, the wxFL library, or more accurately, the wxDynamicToolbar component. The drawback with this implementation is that currently you have to specify a size for the toolbar when you create it. This will obviously need a bit of playing around to get your toolbars looking OK, but it isn't meant to be a replacement for whatever the AUI developers are doing, just an interim fix.

To implement automatic orientation switching, replace all wxAui managed wxToolbars with wxDynamicToolbars, and apply the following changes to the wxAui library:

wxWidgets\include\aui\framemanager.h

after the line (<> 582)
void OnFindManager(wxAuiManagerEvent& evt);

add
void OnToolbarDrop(wxAuiManagerEvent& evt);

after the line (<> 810)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_AUI, wxEVT_AUI_FIND_MANAGER, 0)

add
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_AUI, wxEVT_AUI_TOOLBAR_DROP, 0)

after the line (<> 829)
#define EVT_AUI_FIND_MANAGER(func) \
wx__DECLARE_EVT0(wxEVT_AUI_FIND_MANAGER, wxAuiManagerEventHandler(func))

add
#define EVT_AUI_TOOLBAR_DROP(func) \
wx__DECLARE_EVT0(wxEVT_AUI_TOOLBAR_DROP, wxAuiManagerEventHandler(func))

after the line (<> 841)
%constant wxEventType wxEVT_AUI_FIND_MANAGER;

add
%constant wxEventType wxEVT_AUI_TOOLBAR_DROP;

after the line (<> 850)
EVT_AUI_FIND_MANAGER = wx.PyEventBinder( wxEVT_AUI_FIND_MANAGER )

add
EVT_AUI_TOOLBAR_DROP = wx.PyEventBinder( wxEVT_AUI_TOOLBAR_DROP )


in wxWidgets\src\aui\framemanager.cpp

firstly add the dynamictoolbar headers

#include "wx/fl/dyntbar.h" // auto-layout toolbar
#include "wx/fl/dyntbarhnd.h" // control-bar dimension handler for it

then after the line (<> 63)
DEFINE_EVENT_TYPE(wxEVT_AUI_FIND_MANAGER)

add
DEFINE_EVENT_TYPE(wxEVT_AUI_TOOLBAR_DROP)

then after the line (<> 572)
EVT_TIMER(101, wxAuiManager::OnHintFadeTimer)

add
EVT_AUI_TOOLBAR_DROP(wxAuiManager::OnToolbarDrop)

at line (<> 3569)
change
Code: Select all
   // if a key modifier is pressed while dragging the frame,
    // don't dock the window
    if (!wxGetKeyState(WXK_CONTROL) && !wxGetKeyState(WXK_ALT))
    {
        // do the drop calculation
        DoDrop(m_docks, m_panes, pane, client_pt, action_offset);
   }


to

Code: Select all
   // if a key modifier is pressed while dragging the frame,
    // don't dock the window
    if (!wxGetKeyState(WXK_CONTROL) && !wxGetKeyState(WXK_ALT))
    {
        // do the drop calculation
        DoDrop(m_docks, m_panes, pane, client_pt, action_offset);

      if (pane.IsToolbar())
      {
         // fire dropped toolbar event event
         wxAuiManagerEvent e(wxEVT_AUI_TOOLBAR_DROP);
         e.SetManager(this);
         e.SetPane(&pane);
         ProcessMgrEvent(e);
      }
    }


at about line 4232 (in the actionDragToolbarPane section of the void wxAuiManager::OnLeftUp(wxMouseEvent& event)
function)
after

Code: Select all
        if (docks.GetCount() == 1)
        {
            wxAuiDockInfo& dock = *docks.Item(0);

            wxArrayInt pane_positions, pane_sizes;
            GetPanePositionsAndSizes(dock, pane_positions, pane_sizes);

            int i, dock_pane_count = dock.panes.GetCount();
            for (i = 0; i < dock_pane_count; ++i)
                dock.panes.Item(i)->dock_pos = pane_positions[i];
        }

add

Code: Select all
        // fire dropped toolbar event event
        wxAuiManagerEvent e(wxEVT_AUI_TOOLBAR_DROP);
        e.SetManager(this);
        e.SetPane(&pane);
        ProcessMgrEvent(e);
        pane.state &= ~wxAuiPaneInfo::actionPane;


and finally at the end of the file add
Code: Select all
void wxAuiManager::OnToolbarDrop(wxAuiManagerEvent& evt)
{
   if(evt.GetPane()->window->IsKindOf(CLASSINFO(wxDynamicToolBar)))
   {
      wxDynamicToolBar* toolBar = wxDynamicCast(evt.GetPane()->window, wxDynamicToolBar);

      wxAuiPaneInfo* pane = evt.GetPane();
      int direction = pane->dock_direction;
      long style = toolBar->GetWindowStyle();
      toolBar->Show(false);
      wxSize old_size = pane->best_size;
      
      style &= ~(wxTB_HORIZONTAL | wxTB_VERTICAL);
      
      switch( direction )
      {
         case wxAUI_DOCK_LEFT:
         case wxAUI_DOCK_RIGHT:
         {
            style |= wxTB_VERTICAL;
            if (old_size.x > old_size.y)
               pane->BestSize(old_size.y, old_size.x);
            else
               pane->BestSize(old_size.x, old_size.y);

            if(pane->HasGripper())
               pane->GripperTop(true);
            
            break;
         }
         case wxAUI_DOCK_TOP:
         case wxAUI_DOCK_BOTTOM:
         {
            style |= wxTB_HORIZONTAL;
            if (old_size.x > old_size.y)
               pane->BestSize(old_size.x, old_size.y);
            else
               pane->BestSize(old_size.y, old_size.x);

            if(pane->HasGripperTop())
               pane->GripperTop(false);
            
            break;
         }
      }

      toolBar->SetWindowStyle(style);
      toolBar->Layout();
      toolBar->Show(true);
      Update();
   }
}


before the final

#endif // wxUSE_AUI


This isn't meant to be a replacement for whatever the wxAUI developers will be bringing, but it does seem to work for myself, and hopefully it should work for y'all too.

I repeat that this will be unnecessary once the wxAUI developers release their wxAuiToolbar which I understand should do automatic orientation switching, but it suffices in the meantime.

Don't forget that you will also need to add the wxFL library to your project.

I would have generated a patch, but my version of the files has already been heavily patched with several fixes I have proposed here as well as the doc/view patch (and others) which has been posted.

Hopefully I have been clear enough in my explanation, and I hope it comes in useful for someone.
NinjaNL
Registered User
 
Posts: 40
Joined: Thu Jun 14, 2007 6:53 am

Return to wxAUI Patches & Modifications