]> git.saurik.com Git - wxWidgets.git/blobdiff - src/aui/framemanager.cpp
added length to wx(Scoped)CharBuffer to improve handling of embedded NULs
[wxWidgets.git] / src / aui / framemanager.cpp
index 4616efe633c9c7dac8a945e679fb5b421f2dcedd..ca6ea2b3c9bb9a619c75103e18290f4274270de2 100644 (file)
@@ -30,6 +30,7 @@
 #include "wx/aui/floatpane.h"
 #include "wx/aui/tabmdi.h"
 #include "wx/aui/auibar.h"
+#include "wx/mdi.h"
 
 #ifndef WX_PRECOMP
     #include "wx/panel.h"
@@ -38,7 +39,6 @@
     #include "wx/dcclient.h"
     #include "wx/dcscreen.h"
     #include "wx/toolbar.h"
-    #include "wx/mdi.h"
     #include "wx/image.h"
 #endif
 
@@ -54,12 +54,12 @@ WX_DEFINE_OBJARRAY(wxAuiPaneInfoArray)
 
 wxAuiPaneInfo wxAuiNullPaneInfo;
 wxAuiDockInfo wxAuiNullDockInfo;
-wxDEFINE_EVENT( wxEVT_AUI_PANE_BUTTON, wxAuiManagerEvent )
-wxDEFINE_EVENT( wxEVT_AUI_PANE_CLOSE, wxAuiManagerEvent )
-wxDEFINE_EVENT( wxEVT_AUI_PANE_MAXIMIZE, wxAuiManagerEvent )
-wxDEFINE_EVENT( wxEVT_AUI_PANE_RESTORE, wxAuiManagerEvent )
-wxDEFINE_EVENT( wxEVT_AUI_RENDER, wxAuiManagerEvent )
-wxDEFINE_EVENT( wxEVT_AUI_FIND_MANAGER, wxAuiManagerEvent )
+wxDEFINE_EVENT( wxEVT_AUI_PANE_BUTTON, wxAuiManagerEvent );
+wxDEFINE_EVENT( wxEVT_AUI_PANE_CLOSE, wxAuiManagerEvent );
+wxDEFINE_EVENT( wxEVT_AUI_PANE_MAXIMIZE, wxAuiManagerEvent );
+wxDEFINE_EVENT( wxEVT_AUI_PANE_RESTORE, wxAuiManagerEvent );
+wxDEFINE_EVENT( wxEVT_AUI_RENDER, wxAuiManagerEvent );
+wxDEFINE_EVENT( wxEVT_AUI_FIND_MANAGER, wxAuiManagerEvent );
 
 #ifdef __WXMAC__
     // a few defines to avoid nameclashes
@@ -558,6 +558,136 @@ static int PaneSortFunc(wxAuiPaneInfo** p1, wxAuiPaneInfo** p2)
 }
 
 
+
+
+// this utility class implements a proportional sizer
+// as it existed in wxWidgets 2.8 and before.
+
+class wxAuiProportionalBoxSizer : public wxBoxSizer
+{
+public:
+    wxAuiProportionalBoxSizer(int orientation) : wxBoxSizer(orientation) { }
+    
+    void RecalcSizes()
+    {
+        if (m_children.GetCount() == 0)
+            return;
+
+        int fixed_height = 0;
+        int fixed_width = 0;
+        int stretchable = 0;
+        wxSizerItemList::compatibility_iterator node;
+        
+        // find fixed width and height, as well
+        // as the total stretchable proportions
+        node = m_children.GetFirst();
+        while (node)
+        {
+            wxSizerItem *item = node->GetData();
+            
+            if (item->IsShown())
+            {
+                stretchable += item->GetProportion();
+                
+                wxSize size(item->GetMinSizeWithBorder());
+                if (item->GetProportion() == 0)
+                {
+                    if (m_orient == wxVERTICAL)
+                    {
+                        fixed_height += size.y;
+                        fixed_width = wxMax(fixed_width, size.x);
+                    }
+                     else
+                    {
+                        fixed_width += size.x;
+                        fixed_height = wxMax(fixed_height, size.y);
+                    }
+                }
+            }
+            
+            node = node->GetNext();
+        }
+
+
+        // delta specifies the total amount to be allocated to stretch spaces
+        int delta = 0;
+        if (stretchable)
+        {
+            if (m_orient == wxHORIZONTAL)
+                delta = m_size.x - fixed_width;
+                 else
+                delta = m_size.y - fixed_height;
+        }
+
+        // go through each item and assign sizes
+        wxPoint pt(m_position);
+        node = m_children.GetFirst();
+        while (node)
+        {
+            wxSizerItem* item = node->GetData();
+
+            if (item->IsShown())
+            {
+                wxSize size(item->GetMinSizeWithBorder());
+
+                if (m_orient == wxVERTICAL)
+                {
+                    wxCoord height = size.y;
+                    if (item->GetProportion())
+                    {
+                        height = (delta * item->GetProportion()) / stretchable;
+                        delta -= height;
+                        stretchable -= item->GetProportion();
+                    }
+
+                    wxPoint child_pos(pt);
+                    wxSize child_size(size.x, height);
+
+                    if (item->GetFlag() & (wxEXPAND | wxSHAPED))
+                        child_size.x = m_size.x;
+                    else if (item->GetFlag() & wxALIGN_RIGHT)
+                        child_pos.x += m_size.x - size.x;
+                    else if (item->GetFlag() & (wxCENTER | wxALIGN_CENTER_HORIZONTAL))
+                        child_pos.x += (m_size.x - size.x) / 2;
+
+                    item->SetDimension(child_pos, child_size);
+
+                    pt.y += height;
+                }
+                 else
+                {
+                    wxCoord width = size.x;
+                    if (item->GetProportion())
+                    {
+                        width = (delta * item->GetProportion()) / stretchable;
+                        delta -= width;
+                        stretchable -= item->GetProportion();
+                    }
+
+                    wxPoint child_pos(pt);
+                    wxSize child_size(width, size.y);
+
+                    if (item->GetFlag() & (wxEXPAND | wxSHAPED))
+                        child_size.y = m_size.y;
+                    else if (item->GetFlag() & wxALIGN_BOTTOM)
+                        child_pos.y += m_size.y - size.y;
+                    else if (item->GetFlag() & (wxCENTER | wxALIGN_CENTER_VERTICAL))
+                        child_pos.y += (m_size.y - size.y) / 2;
+
+                    item->SetDimension(child_pos, child_size);
+                    
+                    pt.x += width;
+                }
+            }
+
+            node = node->GetNext();
+        }
+    }
+};
+
+
+
+
 // -- wxAuiManager class implementation --
 
 
@@ -582,6 +712,7 @@ END_EVENT_TABLE()
 wxAuiManager::wxAuiManager(wxWindow* managed_wnd, unsigned int flags)
 {
     m_action = actionNone;
+    m_action_window = NULL;
     m_last_mouse_move = wxPoint();
     m_hover_button = NULL;
     m_art = new wxAuiDefaultDockArt;
@@ -771,7 +902,7 @@ wxAuiManager* wxAuiManager::GetManager(wxWindow* window)
     wxAuiManagerEvent evt(wxEVT_AUI_FIND_MANAGER);
     evt.SetManager(NULL);
     evt.ResumePropagation(wxEVENT_PROPAGATE_MAX);
-    if (!window->ProcessEvent(evt))
+    if (!window->GetEventHandler()->ProcessEvent(evt))
         return NULL;
 
     return evt.GetManager();
@@ -932,7 +1063,7 @@ void wxAuiManager::ProcessMgrEvent(wxAuiManagerEvent& event)
     // first, give the owner frame a chance to override
     if (m_frame)
     {
-        if (m_frame->ProcessEvent(event))
+        if (m_frame->GetEventHandler()->ProcessEvent(event))
             return;
     }
 
@@ -1280,7 +1411,7 @@ void wxAuiManager::MaximizePane(wxAuiPaneInfo& pane_info)
     for (i = 0, pane_count = m_panes.GetCount(); i < pane_count; ++i)
     {
         wxAuiPaneInfo& p = m_panes.Item(i);
-        if (!p.IsToolbar())
+        if (!p.IsToolbar() && !p.IsFloating())
         {
             p.Restore();
 
@@ -1883,7 +2014,7 @@ void wxAuiManager::LayoutAddDock(wxSizer* cont,
     }
 
     // create the sizer for the dock
-    wxSizer* dock_sizer = new wxBoxSizer(orientation);
+    wxSizer* dock_sizer = new wxAuiProportionalBoxSizer(orientation);
 
     // add each pane to the dock
     bool has_maximized_pane = false;
@@ -4139,6 +4270,11 @@ bool wxAuiManager::DoEndResizeAction(wxMouseEvent& event)
             }
         }
 
+        // new size can never be more than the number of dock pixels
+        if (new_pixsize > dock_pixels)
+            new_pixsize = dock_pixels;
+
+
         // find a pane in our dock to 'steal' space from or to 'give'
         // space to -- this is essentially what is done when a pane is
         // resized; the pane should usually be the first non-fixed pane
@@ -4165,7 +4301,7 @@ bool wxAuiManager::DoEndResizeAction(wxMouseEvent& event)
             m_action = actionNone;
             return false;
         }
-
+        
         // calculate the new proportion of the pane
         int new_proportion = (new_pixsize*total_proportion)/dock_pixels;
 
@@ -4213,10 +4349,26 @@ bool wxAuiManager::DoEndResizeAction(wxMouseEvent& event)
         int prop_diff = new_proportion - pane.dock_proportion;
 
         // borrow the space from our neighbor pane to the
-        // right or bottom (depending on orientation)
-        dock.panes.Item(borrow_pane)->dock_proportion -= prop_diff;
+        // right or bottom (depending on orientation);
+        // also make sure we don't make the neighbor too small
+        int prop_borrow = dock.panes.Item(borrow_pane)->dock_proportion;
+
+        if (prop_borrow - prop_diff < 0)
+        {
+            // borrowing from other pane would make it too small,
+            // so cancel the resize operation
+            prop_borrow = min_proportion;
+        }
+         else
+        {
+            prop_borrow -= prop_diff;
+        }
+
+        
+        dock.panes.Item(borrow_pane)->dock_proportion = prop_borrow;
         pane.dock_proportion = new_proportion;
 
+
         // repaint
         Update();
         Repaint(NULL);
@@ -4354,9 +4506,19 @@ void wxAuiManager::OnMotion(wxMouseEvent& event)
                 wxScreenDC dc;
 
                 if (!m_action_hintrect.IsEmpty())
+                {
+                    // remove old resize hint
                     DrawResizeHint(dc, m_action_hintrect);
-                DrawResizeHint(dc, rect);
-                m_action_hintrect = rect;
+                    m_action_hintrect = wxRect();
+                }
+                
+                // draw new resize hint, if it's inside the managed frame
+                wxRect frame_screen_rect = m_frame->GetScreenRect();
+                if (frame_screen_rect.Contains(rect))
+                {
+                    DrawResizeHint(dc, rect);
+                    m_action_hintrect = rect;
+                }
             }
         }
     }