]> git.saurik.com Git - wxWidgets.git/blobdiff - src/aui/framemanager.cpp
added wxSizerItem::AssignXXX() methods replacing the old SetXXX() but freeing the...
[wxWidgets.git] / src / aui / framemanager.cpp
index 846fa1aba148a3232aa758c9ab7fe46fc5b74a5e..e758807ecc5a993551f4217c05fee6a2b03dab10 100644 (file)
@@ -52,12 +52,12 @@ WX_DEFINE_OBJARRAY(wxAuiPaneInfoArray)
 
 wxAuiPaneInfo wxAuiNullPaneInfo;
 wxAuiDockInfo wxAuiNullDockInfo;
-DEFINE_EVENT_TYPE(wxEVT_AUI_PANEBUTTON)
-DEFINE_EVENT_TYPE(wxEVT_AUI_PANECLOSE)
-DEFINE_EVENT_TYPE(wxEVT_AUI_PANEMAXIMIZE)
-DEFINE_EVENT_TYPE(wxEVT_AUI_PANERESTORE)
+DEFINE_EVENT_TYPE(wxEVT_AUI_PANE_BUTTON)
+DEFINE_EVENT_TYPE(wxEVT_AUI_PANE_CLOSE)
+DEFINE_EVENT_TYPE(wxEVT_AUI_PANE_MAXIMIZE)
+DEFINE_EVENT_TYPE(wxEVT_AUI_PANE_RESTORE)
 DEFINE_EVENT_TYPE(wxEVT_AUI_RENDER)
-DEFINE_EVENT_TYPE(wxEVT_AUI_FINDMANAGER)
+DEFINE_EVENT_TYPE(wxEVT_AUI_FIND_MANAGER)
 
 #ifdef __WXMAC__
     // a few defines to avoid nameclashes
@@ -69,11 +69,6 @@ DEFINE_EVENT_TYPE(wxEVT_AUI_FINDMANAGER)
 IMPLEMENT_DYNAMIC_CLASS(wxAuiManagerEvent, wxEvent)
 IMPLEMENT_CLASS(wxAuiManager, wxEvtHandler)
 
-// private manager flags (not yet on the public API)
-enum wxAuiPrivateManagerOption
-{
-    wxAUI_MGR_NO_DOCK_SIZE_LIMIT = 1 << 28
-};
 
 
 const int auiToolBarLayer = 10;
@@ -477,7 +472,7 @@ static int PaneSortFunc(wxAuiPaneInfo** p1, wxAuiPaneInfo** p2)
 
 
 BEGIN_EVENT_TABLE(wxAuiManager, wxEvtHandler)
-    EVT_AUI_PANEBUTTON(wxAuiManager::OnPaneButton)
+    EVT_AUI_PANE_BUTTON(wxAuiManager::OnPaneButton)
     EVT_AUI_RENDER(wxAuiManager::OnRender)
     EVT_PAINT(wxAuiManager::OnPaint)
     EVT_ERASE_BACKGROUND(wxAuiManager::OnEraseBackground)
@@ -488,7 +483,7 @@ BEGIN_EVENT_TABLE(wxAuiManager, wxEvtHandler)
     EVT_MOTION(wxAuiManager::OnMotion)
     EVT_LEAVE_WINDOW(wxAuiManager::OnLeaveWindow)
     EVT_CHILD_FOCUS(wxAuiManager::OnChildFocus)
-    EVT_AUI_FINDMANAGER(wxAuiManager::OnFindManager)
+    EVT_AUI_FIND_MANAGER(wxAuiManager::OnFindManager)
     EVT_TIMER(101, wxAuiManager::OnHintFadeTimer)
 END_EVENT_TABLE()
 
@@ -504,6 +499,9 @@ wxAuiManager::wxAuiManager(wxWindow* managed_wnd, unsigned int flags)
     m_skipping = false;
     m_has_maximized = false;
     m_frame = NULL;
+    m_dock_constraint_x = 0.3;
+    m_dock_constraint_y = 0.3;
+    m_reserved = NULL;
     
     if (managed_wnd)
     {
@@ -516,10 +514,11 @@ wxAuiManager::~wxAuiManager()
     delete m_art;
 }
 
-// Creates a floating frame for the windows
-wxAuiFloatingFrame * wxAuiManager::CreateFloatingFrame(wxWindow* parent, const wxAuiPaneInfo& p)
+// creates a floating frame for the windows
+wxAuiFloatingFrame* wxAuiManager::CreateFloatingFrame(wxWindow* parent,
+                                                      const wxAuiPaneInfo& pane_info)
 {
-    return new wxAuiFloatingFrame(parent, this, p);
+    return new wxAuiFloatingFrame(parent, this, pane_info);
 }
 
 // GetPane() looks up a wxAuiPaneInfo structure based
@@ -646,7 +645,7 @@ wxFrame* wxAuiManager::GetFrame() const
 // need to be managed by the manager itself.
 wxAuiManager* wxAuiManager::GetManager(wxWindow* window)
 {
-    wxAuiManagerEvent evt(wxEVT_AUI_FINDMANAGER);
+    wxAuiManagerEvent evt(wxEVT_AUI_FIND_MANAGER);
     evt.SetManager(NULL);
     evt.ResumePropagation(wxEVENT_PROPAGATE_MAX);
     if (!window->ProcessEvent(evt))
@@ -824,10 +823,19 @@ bool wxAuiManager::AddPane(wxWindow* window, const wxAuiPaneInfo& pane_info)
     if (!window)
         return false;
 
-    // check if the pane already exists
+    // check if the window is already managed by us
     if (GetPane(pane_info.window).IsOk())
         return false;
 
+    // check if the pane name already exists, this could reveal a
+    // bug in the library user's application
+    bool already_exists = false;
+    if (!pane_info.name.empty() && GetPane(pane_info.name).IsOk())
+    {
+        wxFAIL_MSG(wxT("A pane with that name already exists in the manager!"));
+        already_exists = true;
+    }
+
     // if the new pane is docked then we should undo maximize
     if (pane_info.IsDocked())
         RestoreMaximizedPane();
@@ -839,8 +847,9 @@ bool wxAuiManager::AddPane(wxWindow* window, const wxAuiPaneInfo& pane_info)
     // set the pane window
     pinfo.window = window;
 
+
     // if the pane's name identifier is blank, create a random string
-    if (pinfo.name.empty())
+    if (pinfo.name.empty() || already_exists)
     {
         pinfo.name.Printf(wxT("%08lx%08x%08x%08lx"),
              ((unsigned long)pinfo.window) & 0xffffffff,
@@ -911,8 +920,8 @@ bool wxAuiManager::AddPane(wxWindow* window, const wxAuiPaneInfo& pane_info)
 }
 
 bool wxAuiManager::AddPane(wxWindow* window,
-                             int direction,
-                             const wxString& caption)
+                           int direction,
+                           const wxString& caption)
 {
     wxAuiPaneInfo pinfo;
     pinfo.Caption(caption);
@@ -928,8 +937,8 @@ bool wxAuiManager::AddPane(wxWindow* window,
 }
 
 bool wxAuiManager::AddPane(wxWindow* window,
-                             const wxAuiPaneInfo& pane_info,
-                             const wxPoint& drop_pos)
+                           const wxAuiPaneInfo& pane_info,
+                           const wxPoint& drop_pos)
 {
     if (!AddPane(window, pane_info))
         return false;
@@ -1113,7 +1122,13 @@ void wxAuiManager::MaximizePane(wxAuiPaneInfo& pane_info)
         if (!p.IsToolbar())
         {
             p.Restore();
-            p.SaveHidden();
+            
+            // save hidden state
+            p.SetFlag(wxAuiPaneInfo::savedHiddenState,
+                      p.HasFlag(wxAuiPaneInfo::optionHidden));
+
+            // hide the pane, because only the newly
+            // maximized pane should show
             p.Hide();
         }
     }
@@ -1140,7 +1155,8 @@ void wxAuiManager::RestorePane(wxAuiPaneInfo& pane_info)
         wxAuiPaneInfo& p = m_panes.Item(i);
         if (!p.IsToolbar())
         {
-            p.RestoreHidden();
+            p.SetFlag(wxAuiPaneInfo::optionHidden,
+                      p.HasFlag(wxAuiPaneInfo::savedHiddenState));
         }
     }
 
@@ -1305,7 +1321,7 @@ wxString wxAuiManager::SavePerspective()
 {
     wxString result;
     result.Alloc(500);
-    result = wxT("layout1|");
+    result = wxT("layout2|");
 
     int pane_i, pane_count = m_panes.GetCount();
     for (pane_i = 0; pane_i < pane_count; ++pane_i)
@@ -1336,11 +1352,13 @@ bool wxAuiManager::LoadPerspective(const wxString& layout, bool update)
     wxString part;
 
     // check layout string version
+    //    'layout1' = wxAUI 0.9.0 - wxAUI 0.9.2
+    //    'layout2' = wxAUI 0.9.2 (wxWidgets 2.8)
     part = input.BeforeFirst(wxT('|'));
     input = input.AfterFirst(wxT('|'));
     part.Trim(true);
     part.Trim(false);
-    if (part != wxT("layout1"))
+    if (part != wxT("layout2"))
         return false;
 
     // mark all panes currently managed as docked and hidden
@@ -1508,10 +1526,10 @@ void wxAuiManager::GetPanePositionsAndSizes(wxAuiDockInfo& dock,
 
 
 void wxAuiManager::LayoutAddPane(wxSizer* cont,
-                                   wxAuiDockInfo& dock,
-                                   wxAuiPaneInfo& pane,
-                                   wxAuiDockUIPartArray& uiparts,
-                                   bool spacer_only)
+                                 wxAuiDockInfo& dock,
+                                 wxAuiPaneInfo& pane,
+                                 wxAuiDockUIPartArray& uiparts,
+                                 bool spacer_only)
 {
     wxAuiDockUIPart part;
     wxSizerItem* sizer_item;
@@ -1629,7 +1647,7 @@ void wxAuiManager::LayoutAddPane(wxSizer* cont,
 
 
     // determine if the pane should have a minimum size; if the pane is
-    // non-resizable (fixed) then we must set a minimum size. Alternitavely,
+    // non-resizable (fixed) then we must set a minimum size. Alternatively,
     // if the pane.min_size is set, we must use that value as well
 
     wxSize min_size = pane.min_size;
@@ -1834,9 +1852,9 @@ void wxAuiManager::LayoutAddDock(wxSizer* cont,
 }
 
 wxSizer* wxAuiManager::LayoutAll(wxAuiPaneInfoArray& panes,
-                                   wxAuiDockInfoArray& docks,
-                                   wxAuiDockUIPartArray& uiparts,
-                                   bool spacer_only)
+                                 wxAuiDockInfoArray& docks,
+                                 wxAuiDockUIPartArray& uiparts,
+                                 bool spacer_only)
 {
     wxBoxSizer* container = new wxBoxSizer(wxVERTICAL);
 
@@ -1961,17 +1979,22 @@ wxSizer* wxAuiManager::LayoutAll(wxAuiPaneInfoArray& panes,
                 }
             }
 
-            if (!(m_flags & wxAUI_MGR_NO_DOCK_SIZE_LIMIT))
-            {
-                // new dock's size may not be more than 1/3 of the frame size
-                if (dock.IsHorizontal())
-                    size = wxMin(size, cli_size.y/3);
-                     else
-                    size = wxMin(size, cli_size.x/3);
-            }
+
+            // new dock's size may not be more than the dock constraint
+            // parameter specifies.  See SetDockSizeConstraint()
             
+            int max_dock_x_size = (int)(m_dock_constraint_x * ((double)cli_size.x));
+            int max_dock_y_size = (int)(m_dock_constraint_y * ((double)cli_size.y));
+            
+            if (dock.IsHorizontal())
+                size = wxMin(size, max_dock_y_size);
+                 else
+                size = wxMin(size, max_dock_x_size);
+
+            // absolute minimum size for a dock is 10 pixels
             if (size < 10)
                 size = 10;
+                
             dock.size = size;
         }
 
@@ -2204,6 +2227,27 @@ wxSizer* wxAuiManager::LayoutAll(wxAuiPaneInfoArray& panes,
 }
 
 
+// SetDockSizeConstraint() allows the dock constraints to be set.  For example,
+// specifying values of 0.5, 0.5 will mean that upon dock creation, a dock may
+// not be larger than half of the window's size
+
+void wxAuiManager::SetDockSizeConstraint(double width_pct, double height_pct)
+{
+    m_dock_constraint_x = wxMax(0.0, wxMin(1.0, width_pct));
+    m_dock_constraint_y = wxMax(0.0, wxMin(1.0, height_pct));
+}
+
+void wxAuiManager::GetDockSizeConstraint(double* width_pct, double* height_pct) const
+{
+    if (width_pct)
+        *width_pct = m_dock_constraint_x;
+    
+    if (height_pct)
+        *height_pct = m_dock_constraint_y;
+}
+
+
+
 // Update() updates the layout.  Whenever changes are made to
 // one or more panes, this function should be called.  It is the
 // external entry point for running the layout engine.
@@ -2300,10 +2344,15 @@ void wxAuiManager::Update()
                 // and size reflect the information in wxAuiPaneInfo
                 if (p.frame->GetPosition() != p.floating_pos)
                 {
+                    p.frame->SetSize(p.floating_pos.x, p.floating_pos.y,
+                                     p.floating_size.x, p.floating_size.y,
+                                     wxSIZE_USE_EXISTING);
+                /*
                     p.frame->SetSize(p.floating_pos.x, p.floating_pos.y,
                                      wxDefaultCoord, wxDefaultCoord,
                                      wxSIZE_USE_EXISTING);
                     //p.frame->Move(p.floating_pos.x, p.floating_pos.y);
+                */
                 }
 
                 if (p.frame->IsShown() != p.IsShown())
@@ -2528,7 +2577,7 @@ int wxAuiManager::GetDockPixelOffset(wxAuiPaneInfo& test)
 // the target info.  If the operation was allowed, the function returns true.
 
 bool wxAuiManager::ProcessDockResult(wxAuiPaneInfo& target,
-                              const wxAuiPaneInfo& new_pos)
+                                     const wxAuiPaneInfo& new_pos)
 {
     bool allowed = false;
     switch (new_pos.dock_direction)
@@ -3201,6 +3250,12 @@ wxRect wxAuiManager::CalculateHintRect(wxWindow* pane_window,
     // actually show the hint rectangle on the screen
     m_frame->ClientToScreen(&rect.x, &rect.y);
 
+    if ( m_frame->GetLayoutDirection() == wxLayout_RightToLeft )
+    {
+        // Mirror rectangle in RTL mode
+        rect.x -= rect.GetWidth();
+    }
+
     return rect;
 }
 
@@ -3434,7 +3489,7 @@ void wxAuiManager::OnFloatingPaneClosed(wxWindow* wnd, wxCloseEvent& evt)
 
 
     // fire pane close event
-    wxAuiManagerEvent e(wxEVT_AUI_PANECLOSE);
+    wxAuiManagerEvent e(wxEVT_AUI_PANE_CLOSE);
     e.SetPane(&pane);
     e.SetCanVeto(evt.CanVeto());
     ProcessMgrEvent(e);
@@ -3742,6 +3797,26 @@ void wxAuiManager::OnLeftDown(wxMouseEvent& event)
          else if (part->type == wxAuiDockUIPart::typeCaption ||
                   part->type == wxAuiDockUIPart::typeGripper)
         {
+            // if we are managing a wxAuiFloatingFrame window, then
+            // we are an embedded wxAuiManager inside the wxAuiFloatingFrame.
+            // We want to initiate a toolbar drag in our owner manager
+            wxWindow* managed_wnd = GetManagedWindow();
+            
+            if (part->pane && 
+                part->pane->window &&
+                managed_wnd &&
+                managed_wnd->IsKindOf(CLASSINFO(wxAuiFloatingFrame)))
+            {
+                wxAuiFloatingFrame* floating_frame = (wxAuiFloatingFrame*)managed_wnd;
+                wxAuiManager* owner_mgr = floating_frame->GetOwnerManager();
+                owner_mgr->StartPaneDrag(part->pane->window,
+                                             wxPoint(event.m_x - part->rect.x,
+                                                     event.m_y - part->rect.y));
+                return;
+            }
+            
+        
+        
             if (part->dock && part->dock->dock_direction == wxAUI_DOCK_CENTER)
                 return;
 
@@ -3977,7 +4052,7 @@ void wxAuiManager::OnLeftUp(wxMouseEvent& event)
         if (m_action_part == HitTest(event.GetX(), event.GetY()))
         {
             // fire button-click event
-            wxAuiManagerEvent e(wxEVT_AUI_PANEBUTTON);
+            wxAuiManagerEvent e(wxEVT_AUI_PANE_BUTTON);
             e.SetManager(this);
             e.SetPane(m_action_part->pane);
             e.SetButton(m_action_part->button->button_id);
@@ -4227,7 +4302,7 @@ void wxAuiManager::OnPaneButton(wxAuiManagerEvent& evt)
     if (evt.button == wxAUI_BUTTON_CLOSE)
     {
         // fire pane close event
-        wxAuiManagerEvent e(wxEVT_AUI_PANECLOSE);
+        wxAuiManagerEvent e(wxEVT_AUI_PANE_CLOSE);
         e.SetManager(this);
         e.SetPane(evt.pane);
         ProcessMgrEvent(e);
@@ -4241,7 +4316,7 @@ void wxAuiManager::OnPaneButton(wxAuiManagerEvent& evt)
     else if (evt.button == wxAUI_BUTTON_MAXIMIZE_RESTORE && !pane.IsMaximized())
     {
         // fire pane close event
-        wxAuiManagerEvent e(wxEVT_AUI_PANEMAXIMIZE);
+        wxAuiManagerEvent e(wxEVT_AUI_PANE_MAXIMIZE);
         e.SetManager(this);
         e.SetPane(evt.pane);
         ProcessMgrEvent(e);
@@ -4255,7 +4330,7 @@ void wxAuiManager::OnPaneButton(wxAuiManagerEvent& evt)
     else if (evt.button == wxAUI_BUTTON_MAXIMIZE_RESTORE && pane.IsMaximized())
     {
         // fire pane close event
-        wxAuiManagerEvent e(wxEVT_AUI_PANERESTORE);
+        wxAuiManagerEvent e(wxEVT_AUI_PANE_RESTORE);
         e.SetManager(this);
         e.SetPane(evt.pane);
         ProcessMgrEvent(e);