]> git.saurik.com Git - wxWidgets.git/commitdiff
Add support for auto-orientable toolbars to AUI.
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 23 Jul 2010 23:33:10 +0000 (23:33 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 23 Jul 2010 23:33:10 +0000 (23:33 +0000)
Allow wxAUI to change the toolbar orientation depending on where is it docked.
It is also now possible to specify wxAUI_TB_VERTICAL or HORIZONTAL to force
the toolbar to be always oriented in the given sense and to prevent it from
being docked at the sides incompatible with it.

Closes #11712.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65061 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
include/wx/aui/auibar.h
include/wx/aui/framemanager.h
samples/aui/auidemo.cpp
src/aui/auibar.cpp
src/aui/framemanager.cpp

index 7537912008e46174664f6ea2977b195b2685667c..e99dd4bdc941c11e7c917c84d5a58685713c04b4 100644 (file)
@@ -408,6 +408,11 @@ MSW:
 - Fix Cygwin 1.7 build (David Gangola).
 - Allow using wxDC::DrawText() with multiline texts.
 
+All (GUI):
+
+- wxAUI: support auto-orientable toolbars (wsu).
+
+
 2.9.1:
 ------
 
index b8f6ff453bc39b6a4c9536f92aafe15bec0ad717..b02d405e4e8134ae8486cf3f37d841d647b2730b 100644 (file)
@@ -21,6 +21,7 @@
 #include "wx/pen.h"
 
 //class WXDLLIMPEXP_FWD_CORE wxSizerItem;
+class wxAuiPaneInfo;
 
 enum wxAuiToolBarStyle
 {
@@ -29,9 +30,17 @@ enum wxAuiToolBarStyle
     wxAUI_TB_NO_AUTORESIZE = 1 << 2,
     wxAUI_TB_GRIPPER       = 1 << 3,
     wxAUI_TB_OVERFLOW      = 1 << 4,
+    // using this style forces the toolbar to be vertical and
+    // be only dockable to the left or right sides of the window
+    // whereas by default it can be horizontal or vertical and
+    // be docked anywhere
     wxAUI_TB_VERTICAL      = 1 << 5,
     wxAUI_TB_HORZ_LAYOUT   = 1 << 6,
+    // analogous to wxAUI_TB_VERTICAL, but forces the toolbar
+    // to be horizontal
+    wxAUI_TB_HORIZONTAL    = 1 << 7,
     wxAUI_TB_HORZ_TEXT     = (wxAUI_TB_HORZ_LAYOUT | wxAUI_TB_TEXT),
+    wxAUI_ORIENTATION_MASK = (wxAUI_TB_VERTICAL | wxAUI_TB_HORIZONTAL),
     wxAUI_TB_DEFAULT_STYLE = 0
 };
 
@@ -564,6 +573,10 @@ public:
     void SetCustomOverflowItems(const wxAuiToolBarItemArray& prepend,
                                 const wxAuiToolBarItemArray& append);
 
+    // get size of hint rectangle for a particular dock location
+    wxSize GetHintSize(int dock_direction) const;
+    bool IsPaneValid(const wxAuiPaneInfo& pane) const;
+
 protected:
 
     virtual void OnCustomRender(wxDC& WXUNUSED(dc),
@@ -636,6 +649,14 @@ protected:
     bool m_overflow_visible;
     long m_style;
 
+    bool RealizeHelper(wxClientDC& dc, bool horizontal);
+    static bool IsPaneValid(long style, const wxAuiPaneInfo& pane);
+    bool IsPaneValid(long style) const;
+    void SetArtFlags() const;
+    wxOrientation m_orientation;
+    wxSize m_horzHintSize;
+    wxSize m_vertHintSize;
+
     DECLARE_EVENT_TABLE()
     DECLARE_CLASS(wxAuiToolBar)
 };
index 037989d4de0ca5d794331d5772b3b288044ae127..94ff9568f011568b8dab56960e1314397a0176ec 100644 (file)
@@ -222,6 +222,8 @@ public:
         source.window = window;
         source.frame = frame;
         source.buttons = buttons;
+        wxCHECK_RET(source.IsValid(),
+                    "window settings and pane settings are incompatible");
         // now assign
         *this = source;
     }
@@ -253,7 +255,15 @@ public:
 #ifdef SWIG
     %typemap(out) wxAuiPaneInfo& { $result = $self; Py_INCREF($result); }
 #endif
-    wxAuiPaneInfo& Window(wxWindow* w) { window = w; return *this; }
+    wxAuiPaneInfo& Window(wxWindow* w)
+    {
+        wxAuiPaneInfo test(*this);
+        test.window = w;
+        wxCHECK_MSG(test.IsValid(), *this,
+                    "window settings and pane settings are incompatible");
+        *this = test;
+        return *this;
+    }
     wxAuiPaneInfo& Name(const wxString& n) { name = n; return *this; }
     wxAuiPaneInfo& Caption(const wxString& c) { caption = c; return *this; }
     wxAuiPaneInfo& Left() { dock_direction = wxAUI_DOCK_LEFT; return *this; }
@@ -308,10 +318,14 @@ public:
 
     wxAuiPaneInfo& DefaultPane()
     {
-        state |= optionTopDockable | optionBottomDockable |
+        wxAuiPaneInfo test(*this);
+        test.state |= optionTopDockable | optionBottomDockable |
                  optionLeftDockable | optionRightDockable |
                  optionFloatable | optionMovable | optionResizable |
                  optionCaption | optionPaneBorder | buttonClose;
+        wxCHECK_MSG(test.IsValid(), *this,
+                    "window settings and pane settings are incompatible");
+        *this = test;
         return *this;
     }
 
@@ -334,10 +348,14 @@ public:
 
     wxAuiPaneInfo& SetFlag(int flag, bool option_state)
     {
+        wxAuiPaneInfo test(*this);
         if (option_state)
-            state |= flag;
+            test.state |= flag;
         else
-            state &= ~flag;
+            test.state &= ~flag;
+        wxCHECK_MSG(test.IsValid(), *this,
+                    "window settings and pane settings are incompatible");
+        *this = test;
         return *this;
     }
 
@@ -416,6 +434,8 @@ public:
     wxAuiPaneButtonArray buttons; // buttons on the pane
 
     wxRect rect;              // current rectangle (populated by wxAUI)
+
+    bool IsValid() const;
 };
 
 
index 78fa5692d31db779317aa6b7a98849d180c027f2..faea051a5c5428d7c4cfa89790b0ab2078fbda70 100644 (file)
@@ -85,6 +85,7 @@ class MyFrame : public wxFrame
         ID_VerticalGradient,
         ID_HorizontalGradient,
         ID_LiveUpdate,
+        ID_AllowToolbarResizing,
         ID_Settings,
         ID_CustomizeToolbar,
         ID_DropDownToolbarItem,
@@ -158,6 +159,7 @@ private:
     void OnTabAlignment(wxCommandEvent &evt);
 
     void OnGradient(wxCommandEvent& evt);
+    void OnToolbarResizing(wxCommandEvent& evt);
     void OnManagerFlag(wxCommandEvent& evt);
     void OnNotebookFlag(wxCommandEvent& evt);
     void OnUpdateUI(wxUpdateUIEvent& evt);
@@ -612,6 +614,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_MENU(ID_NoGradient, MyFrame::OnGradient)
     EVT_MENU(ID_VerticalGradient, MyFrame::OnGradient)
     EVT_MENU(ID_HorizontalGradient, MyFrame::OnGradient)
+    EVT_MENU(ID_AllowToolbarResizing, MyFrame::OnToolbarResizing)
     EVT_MENU(ID_Settings, MyFrame::OnSettings)
     EVT_MENU(ID_CustomizeToolbar, MyFrame::OnCustomizeToolbar)
     EVT_MENU(ID_GridContent, MyFrame::OnChangeContentPane)
@@ -644,6 +647,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_UPDATE_UI(ID_NoGradient, MyFrame::OnUpdateUI)
     EVT_UPDATE_UI(ID_VerticalGradient, MyFrame::OnUpdateUI)
     EVT_UPDATE_UI(ID_HorizontalGradient, MyFrame::OnUpdateUI)
+    EVT_UPDATE_UI(ID_AllowToolbarResizing, MyFrame::OnUpdateUI)
     EVT_MENU_RANGE(MyFrame::ID_FirstPerspective, MyFrame::ID_FirstPerspective+1000,
                    MyFrame::OnRestorePerspective)
     EVT_AUITOOLBAR_TOOL_DROPDOWN(ID_DropDownToolbarItem, MyFrame::OnDropDownToolbarItem)
@@ -710,6 +714,8 @@ MyFrame::MyFrame(wxWindow* parent,
     options_menu->AppendRadioItem(ID_VerticalGradient, _("Vertical Caption Gradient"));
     options_menu->AppendRadioItem(ID_HorizontalGradient, _("Horizontal Caption Gradient"));
     options_menu->AppendSeparator();
+    options_menu->AppendCheckItem(ID_AllowToolbarResizing, _("Allow Toolbar Resizing"));
+    options_menu->AppendSeparator();
     options_menu->Append(ID_Settings, _("Settings Pane"));
 
     wxMenu* notebook_menu = new wxMenu;
@@ -789,7 +795,7 @@ MyFrame::MyFrame(wxWindow* parent,
 
 
     wxAuiToolBar* tb2 = new wxAuiToolBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
-                                         wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_OVERFLOW);
+                                         wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_OVERFLOW | wxAUI_TB_HORIZONTAL);
     tb2->SetToolBitmapSize(wxSize(16,16));
 
     wxBitmap tb2_bmp1 = wxArtProvider::GetBitmap(wxART_QUESTION, wxART_OTHER, wxSize(16,16));
@@ -947,29 +953,24 @@ MyFrame::MyFrame(wxWindow* parent,
     // add the toolbars to the manager
     m_mgr.AddPane(tb1, wxAuiPaneInfo().
                   Name(wxT("tb1")).Caption(wxT("Big Toolbar")).
-                  ToolbarPane().Top().
-                  LeftDockable(false).RightDockable(false));
+                  ToolbarPane().Top());
 
     m_mgr.AddPane(tb2, wxAuiPaneInfo().
-                  Name(wxT("tb2")).Caption(wxT("Toolbar 2")).
-                  ToolbarPane().Top().Row(1).
-                  LeftDockable(false).RightDockable(false));
+                  Name(wxT("tb2")).Caption(wxT("Toolbar 2 (Horizontal)")).
+                  ToolbarPane().Top().Row(1));
 
     m_mgr.AddPane(tb3, wxAuiPaneInfo().
                   Name(wxT("tb3")).Caption(wxT("Toolbar 3")).
-                  ToolbarPane().Top().Row(1).Position(1).
-                  LeftDockable(false).RightDockable(false));
+                  ToolbarPane().Top().Row(1).Position(1));
 
     m_mgr.AddPane(tb4, wxAuiPaneInfo().
                   Name(wxT("tb4")).Caption(wxT("Sample Bookmark Toolbar")).
-                  ToolbarPane().Top().Row(2).
-                  LeftDockable(false).RightDockable(false));
+                  ToolbarPane().Top().Row(2));
 
     m_mgr.AddPane(tb5, wxAuiPaneInfo().
                   Name(wxT("tb5")).Caption(wxT("Sample Vertical Toolbar")).
                   ToolbarPane().Left().
-                  GripperTop().
-                  TopDockable(false).BottomDockable(false));
+                  GripperTop());
 
     m_mgr.AddPane(new wxButton(this, wxID_ANY, _("Test Button")),
                   wxAuiPaneInfo().Name(wxT("tb6")).
@@ -1055,6 +1056,22 @@ void MyFrame::OnGradient(wxCommandEvent& event)
     m_mgr.Update();
 }
 
+void MyFrame::OnToolbarResizing(wxCommandEvent& WXUNUSED(evt))
+{
+    wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes();
+    const size_t count = all_panes.GetCount();
+    for (size_t i = 0; i < count; ++i)
+    {
+        wxAuiToolBar* toolbar = wxDynamicCast(all_panes[i].window, wxAuiToolBar);
+        if (toolbar)
+        {
+            all_panes[i].Resizable(!all_panes[i].IsResizable());
+        }
+    }
+
+    m_mgr.Update();
+}
+
 void MyFrame::OnManagerFlag(wxCommandEvent& event)
 {
     unsigned int flag = 0;
@@ -1198,6 +1215,21 @@ void MyFrame::OnUpdateUI(wxUpdateUIEvent& event)
         case ID_HorizontalGradient:
             event.Check(m_mgr.GetArtProvider()->GetMetric(wxAUI_DOCKART_GRADIENT_TYPE) == wxAUI_GRADIENT_HORIZONTAL);
             break;
+        case ID_AllowToolbarResizing:
+        {
+            wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes();
+            const size_t count = all_panes.GetCount();
+            for (size_t i = 0; i < count; ++i)
+            {
+                wxAuiToolBar* toolbar = wxDynamicCast(all_panes[i].window, wxAuiToolBar);
+                if (toolbar)
+                {
+                    event.Check(all_panes[i].IsResizable());
+                    break;
+                }
+            }
+            break;
+        }
         case ID_AllowFloating:
             event.Check((flags & wxAUI_MGR_ALLOW_FLOATING) != 0);
             break;
index 773ccf41df7f88f05b042e1e7d8f0f536fb249a7..e33ce817a091db98f4ed597a8fd7d3e8771135be 100644 (file)
@@ -792,6 +792,22 @@ int wxAuiDefaultToolBarArt::ShowDropDown(wxWindow* wnd,
 
 
 
+static wxOrientation GetOrientation(long& style)
+{
+    switch (style & wxAUI_ORIENTATION_MASK)
+    {
+        case wxAUI_TB_HORIZONTAL:
+            return wxHORIZONTAL;
+        case wxAUI_TB_VERTICAL:
+            return wxVERTICAL;
+        default:
+            wxFAIL_MSG("toolbar cannot be locked in both horizontal and vertical orientations (maybe no lock was intended?)");
+            // fall through
+        case 0:
+            return wxBOTH;
+    }
+}
+
 BEGIN_EVENT_TABLE(wxAuiToolBar, wxControl)
     EVT_SIZE(wxAuiToolBar::OnSize)
     EVT_IDLE(wxAuiToolBar::OnIdle)
@@ -837,13 +853,18 @@ wxAuiToolBar::wxAuiToolBar(wxWindow* parent,
     m_gripper_sizer_item = NULL;
     m_overflow_sizer_item = NULL;
     m_dragging = false;
+    m_orientation = GetOrientation(style);
+    if (m_orientation == wxBOTH)
+    {
+        m_orientation = wxHORIZONTAL;
+    }
     m_style = style | wxBORDER_NONE;
     m_gripper_visible = (m_style & wxAUI_TB_GRIPPER) ? true : false;
     m_overflow_visible = (m_style & wxAUI_TB_OVERFLOW) ? true : false;
     m_overflow_state = 0;
     SetMargins(5, 5, 2, 2);
     SetFont(*wxNORMAL_FONT);
-    m_art->SetFlags((unsigned int)m_style);
+    SetArtFlags();
     SetExtraStyle(wxWS_EX_PROCESS_IDLE);
     if (style & wxAUI_TB_HORZ_LAYOUT)
         SetToolTextOrientation(wxAUI_TBTOOL_TEXT_RIGHT);
@@ -859,13 +880,17 @@ wxAuiToolBar::~wxAuiToolBar()
 
 void wxAuiToolBar::SetWindowStyleFlag(long style)
 {
+    GetOrientation(style);      // assert if style is invalid
+    wxCHECK_RET(IsPaneValid(style),
+                "window settings and pane settings are incompatible");
+
     wxControl::SetWindowStyleFlag(style);
 
     m_style = style;
 
     if (m_art)
     {
-        m_art->SetFlags((unsigned int)m_style);
+        SetArtFlags();
     }
 
     if (m_style & wxAUI_TB_GRIPPER)
@@ -898,7 +923,7 @@ void wxAuiToolBar::SetArtProvider(wxAuiToolBarArt* art)
 
     if (m_art)
     {
-        m_art->SetFlags((unsigned int)m_style);
+        SetArtFlags();
         m_art->SetTextOrientation(m_tool_text_orientation);
     }
 }
@@ -1342,8 +1367,16 @@ int wxAuiToolBar::GetToolPacking() const
 }
 
 
-void wxAuiToolBar::SetOrientation(int WXUNUSED(orientation))
+void wxAuiToolBar::SetOrientation(int orientation)
 {
+    wxCHECK_RET(orientation == wxHORIZONTAL ||
+                orientation == wxVERTICAL,
+                "invalid orientation value");
+    if (orientation != m_orientation)
+    {
+        m_orientation = wxOrientation(orientation);
+        SetArtFlags();
+    }
 }
 
 void wxAuiToolBar::SetMargins(int left, int right, int top, int bottom)
@@ -1651,6 +1684,65 @@ void wxAuiToolBar::SetCustomOverflowItems(const wxAuiToolBarItemArray& prepend,
     m_custom_overflow_append = append;
 }
 
+// get size of hint rectangle for a particular dock location
+wxSize wxAuiToolBar::GetHintSize(int dock_direction) const
+{
+    switch (dock_direction)
+    {
+        case wxAUI_DOCK_TOP:
+        case wxAUI_DOCK_BOTTOM:
+            return m_horzHintSize;
+        case wxAUI_DOCK_RIGHT:
+        case wxAUI_DOCK_LEFT:
+            return m_vertHintSize;
+        default:
+            wxCHECK_MSG(false, wxDefaultSize, "invalid dock location value");
+    }
+}
+
+bool wxAuiToolBar::IsPaneValid(const wxAuiPaneInfo& pane) const
+{
+    return IsPaneValid(m_style, pane);
+}
+
+bool wxAuiToolBar::IsPaneValid(long style, const wxAuiPaneInfo& pane)
+{
+    if (style & wxAUI_TB_HORIZONTAL)
+    {
+        if (pane.IsLeftDockable() || pane.IsRightDockable())
+        {
+            return false;
+        }
+    }
+    else if (style & wxAUI_TB_VERTICAL)
+    {
+        if (pane.IsTopDockable() || pane.IsBottomDockable())
+        {
+            return false;
+        }
+    }
+    return true;
+}
+
+bool wxAuiToolBar::IsPaneValid(long style) const
+{
+    wxAuiManager* manager = wxAuiManager::GetManager(const_cast<wxAuiToolBar*>(this));
+    if (manager)
+    {
+        return IsPaneValid(style, manager->GetPane(const_cast<wxAuiToolBar*>(this)));
+    }
+    return true;
+}
+
+void wxAuiToolBar::SetArtFlags() const
+{
+    unsigned int artflags = m_style & ~wxAUI_ORIENTATION_MASK;
+    if (m_orientation == wxVERTICAL)
+    {
+        artflags |= wxAUI_TB_VERTICAL;
+    }
+    m_art->SetFlags(artflags);
+}
 
 size_t wxAuiToolBar::GetToolCount() const
 {
@@ -1688,7 +1780,7 @@ bool wxAuiToolBar::GetToolFitsByIndex(int tool_idx) const
 
     wxRect rect = m_items[tool_idx].sizer_item->GetRect();
 
-    if (m_style & wxAUI_TB_VERTICAL)
+    if (m_orientation == wxVERTICAL)
     {
         // take the dropdown size into account
         if (m_overflow_visible)
@@ -1745,11 +1837,40 @@ bool wxAuiToolBar::Realize()
     if (!dc.IsOk())
         return false;
 
-    bool horizontal = true;
-    if (m_style & wxAUI_TB_VERTICAL)
-        horizontal = false;
+    // calculate hint sizes for both horizontal and vertical
+    // in the order that leaves toolbar in correct final state
+    bool retval = false;
+    if (m_orientation == wxHORIZONTAL)
+    {
+        if (RealizeHelper(dc, false))
+        {
+            m_vertHintSize = GetSize();
+            if (RealizeHelper(dc, true))
+            {
+                m_horzHintSize = GetSize();
+                retval = true;
+            }
+        }
+    }
+    else
+    {
+        if (RealizeHelper(dc, true))
+        {
+            m_horzHintSize = GetSize();
+            if (RealizeHelper(dc, false))
+            {
+                m_vertHintSize = GetSize();
+                retval = true;
+            }
+        }
+    }
 
+    Refresh(false);
+    return retval;
+}
 
+bool wxAuiToolBar::RealizeHelper(wxClientDC& dc, bool horizontal)
+{
     // create the new sizer to add toolbar elements to
     wxBoxSizer* sizer = new wxBoxSizer(horizontal ? wxHORIZONTAL : wxVERTICAL);
 
@@ -1986,7 +2107,6 @@ bool wxAuiToolBar::Realize()
         m_sizer->SetDimension(0, 0, cur_size.x, cur_size.y);
     }
 
-    Refresh(false);
     return true;
 }
 
@@ -2001,7 +2121,7 @@ wxRect wxAuiToolBar::GetOverflowRect() const
     wxRect overflow_rect = m_overflow_sizer_item->GetRect();
     int overflow_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE);
 
-    if (m_style & wxAUI_TB_VERTICAL)
+    if (m_orientation == wxVERTICAL)
     {
         overflow_rect.y = cli_rect.height - overflow_size;
         overflow_rect.x = 0;
@@ -2119,11 +2239,6 @@ void wxAuiToolBar::OnSize(wxSizeEvent& WXUNUSED(evt))
     int x, y;
     GetClientSize(&x, &y);
 
-    if (x > y)
-        SetOrientation(wxHORIZONTAL);
-    else
-        SetOrientation(wxVERTICAL);
-
     if (((x >= y) && m_absolute_min_size.x > x) ||
         ((y > x) && m_absolute_min_size.y > y))
     {
@@ -2158,6 +2273,11 @@ void wxAuiToolBar::OnSize(wxSizeEvent& WXUNUSED(evt))
 
     Refresh(false);
     Update();
+
+    // idle events aren't sent while user is resizing frame (why?),
+    // but resizing toolbar here causes havoc,
+    // so force idle handler to run after size handling complete
+    QueueEvent(new wxIdleEvent);
 }
 
 
@@ -2180,6 +2300,76 @@ void wxAuiToolBar::DoSetSize(int x,
 
 void wxAuiToolBar::OnIdle(wxIdleEvent& evt)
 {
+    // if orientation doesn't match dock, fix it
+    wxAuiManager* manager = wxAuiManager::GetManager(this);
+    if (manager)
+    {
+        wxAuiPaneInfo& pane = manager->GetPane(this);
+        // pane state member is public, so it might have been changed
+        // without going through wxPaneInfo::SetFlag() check
+        bool ok = pane.IsOk();
+        wxCHECK2_MSG(!ok || IsPaneValid(m_style, pane), ok = false,
+                    "window settings and pane settings are incompatible");
+        if (ok)
+        {
+            wxOrientation newOrientation = m_orientation;
+            if (pane.IsDocked())
+            {
+                switch (pane.dock_direction)
+                {
+                    case wxAUI_DOCK_TOP:
+                    case wxAUI_DOCK_BOTTOM:
+                        newOrientation = wxHORIZONTAL;
+                        break;
+                    case wxAUI_DOCK_LEFT:
+                    case wxAUI_DOCK_RIGHT:
+                        newOrientation = wxVERTICAL;
+                        break;
+                    default:
+                        wxFAIL_MSG("invalid dock location value");
+                }
+            }
+            else if (pane.IsResizable() &&
+                    GetOrientation(m_style) == wxBOTH)
+            {
+                // changing orientation in OnSize causes havoc
+                int x, y;
+                GetClientSize(&x, &y);
+
+                if (x > y)
+                {
+                    newOrientation = wxHORIZONTAL;
+                }
+                else
+                {
+                    newOrientation = wxVERTICAL;
+                }
+            }
+            if (newOrientation != m_orientation)
+            {
+                SetOrientation(newOrientation);
+                Realize();
+                if (newOrientation == wxHORIZONTAL)
+                {
+                    pane.best_size = GetHintSize(wxAUI_DOCK_TOP);
+                }
+                else
+                {
+                    pane.best_size = GetHintSize(wxAUI_DOCK_LEFT);
+                }
+                if (pane.IsDocked())
+                {
+                    pane.floating_size = wxDefaultSize;
+                }
+                else
+                {
+                    SetSize(GetParent()->GetClientSize());
+                }
+                manager->Update();
+            }
+        }
+    }
+
     DoIdleUpdate();
     evt.Skip();
 }
@@ -2190,9 +2380,7 @@ void wxAuiToolBar::OnPaint(wxPaintEvent& WXUNUSED(evt))
     wxRect cli_rect(wxPoint(0,0), GetClientSize());
 
 
-    bool horizontal = true;
-    if (m_style & wxAUI_TB_VERTICAL)
-        horizontal = false;
+    bool horizontal = m_orientation == wxHORIZONTAL;
 
 
     m_art->DrawBackground(dc, this, cli_rect);
index 7e66858fc2b4bd1bba87549c4b9adf0bd581e1cf..f9b29c1f75abff27668295cdfcac0c8607196c7e 100644 (file)
@@ -569,6 +569,14 @@ static int PaneSortFunc(wxAuiPaneInfo** p1, wxAuiPaneInfo** p2)
 }
 
 
+bool wxAuiPaneInfo::IsValid() const
+{
+    // Should this RTTI and function call be rewritten as
+    // sending a new event type to allow other window types
+    // to check the pane settings?
+    wxAuiToolBar* toolbar = wxDynamicCast(window, wxAuiToolBar);
+    return !toolbar || toolbar->IsPaneValid(*this);
+}
 
 // -- wxAuiManager class implementation --
 
@@ -992,7 +1000,40 @@ bool wxAuiManager::AddPane(wxWindow* window, const wxAuiPaneInfo& pane_info)
     if (pane_info.IsDocked())
         RestoreMaximizedPane();
 
-    m_panes.Add(pane_info);
+    // special case:  wxAuiToolBar style interacts with docking flags
+    wxAuiPaneInfo test(pane_info);
+    wxAuiToolBar* toolbar = wxDynamicCast(window, wxAuiToolBar);
+    if (toolbar)
+    {
+        // if pane has default docking flags
+        const unsigned int dockMask = wxAuiPaneInfo::optionLeftDockable |
+                                        wxAuiPaneInfo::optionRightDockable |
+                                        wxAuiPaneInfo::optionTopDockable |
+                                        wxAuiPaneInfo::optionBottomDockable;
+        const unsigned int defaultDock = wxAuiPaneInfo().
+                                            DefaultPane().state & dockMask;
+        if ((test.state & dockMask) == defaultDock)
+        {
+            // set docking flags based on toolbar style
+            if (toolbar->GetWindowStyleFlag() & wxAUI_TB_VERTICAL)
+            {
+                test.TopDockable(false).BottomDockable(false);
+            }
+            else if (toolbar->GetWindowStyleFlag() & wxAUI_TB_HORIZONTAL)
+            {
+                test.LeftDockable(false).RightDockable(false);
+            }
+        }
+        else
+        {
+            // see whether non-default docking flags are valid
+            test.window = window;
+            wxCHECK_MSG(test.IsValid(), false,
+                        "toolbar style and pane docking flags are incompatible");
+        }
+    }
+
+    m_panes.Add(test);
 
     wxAuiPaneInfo& pinfo = m_panes.Last();
 
@@ -2783,7 +2824,22 @@ bool wxAuiManager::ProcessDockResult(wxAuiPaneInfo& target,
     }
 
     if (allowed)
+    {
         target = new_pos;
+        // Should this RTTI and function call be rewritten as
+        // sending a new event type to allow other window types
+        // to vary size based on dock location?
+        wxAuiToolBar* toolbar = wxDynamicCast(target.window, wxAuiToolBar);
+        if (toolbar)
+        {
+            wxSize hintSize = toolbar->GetHintSize(target.dock_direction);
+            if (target.best_size != hintSize)
+            {
+                target.best_size = hintSize;
+                target.floating_size = wxDefaultSize;
+            }
+        }
+    }
 
     return allowed;
 }