]> git.saurik.com Git - wxWidgets.git/blobdiff - src/aui/framemanager.cpp
fixing wrong version commit
[wxWidgets.git] / src / aui / framemanager.cpp
index 8a84dea7fdb09ceca5365264a1fcbfc92f9c6b92..a63b4375b0ac282f2cb7b894796f357d9a098e17 100644 (file)
@@ -40,6 +40,7 @@
     #include "wx/dcscreen.h"
     #include "wx/toolbar.h"
     #include "wx/image.h"
     #include "wx/dcscreen.h"
     #include "wx/toolbar.h"
     #include "wx/image.h"
+    #include "wx/statusbr.h"
 #endif
 
 WX_CHECK_BUILD_OPTIONS("wxAUI")
 #endif
 
 WX_CHECK_BUILD_OPTIONS("wxAUI")
@@ -276,6 +277,16 @@ public:
         return true;
     }
 
         return true;
     }
 
+protected:
+    virtual void DoSetSizeHints( int minW, int minH,
+                                 int maxW, int maxH,
+                                 int incW, int incH)
+    {
+        // the real wxFrame method doesn't work for us because we're not really
+        // a top level window so skip it
+        wxWindow::DoSetSizeHints(minW, minH, maxW, maxH, incW, incH);
+    }
+
 private:
     DECLARE_DYNAMIC_CLASS(wxPseudoTransparentFrame)
 };
 private:
     DECLARE_DYNAMIC_CLASS(wxPseudoTransparentFrame)
 };
@@ -558,6 +569,7 @@ static int PaneSortFunc(wxAuiPaneInfo** p1, wxAuiPaneInfo** p2)
 }
 
 
 }
 
 
+
 // -- wxAuiManager class implementation --
 
 
 // -- wxAuiManager class implementation --
 
 
@@ -575,7 +587,6 @@ BEGIN_EVENT_TABLE(wxAuiManager, wxEvtHandler)
     EVT_MOUSE_CAPTURE_LOST(wxAuiManager::OnCaptureLost)
     EVT_CHILD_FOCUS(wxAuiManager::OnChildFocus)
     EVT_AUI_FIND_MANAGER(wxAuiManager::OnFindManager)
     EVT_MOUSE_CAPTURE_LOST(wxAuiManager::OnCaptureLost)
     EVT_CHILD_FOCUS(wxAuiManager::OnChildFocus)
     EVT_AUI_FIND_MANAGER(wxAuiManager::OnFindManager)
-    EVT_TIMER(101, wxAuiManager::OnHintFadeTimer)
 END_EVENT_TABLE()
 
 
 END_EVENT_TABLE()
 
 
@@ -743,6 +754,7 @@ bool wxAuiManager_HasLiveResize(wxAuiManager& manager)
     // With Core Graphics on Mac, it's not possible to show sash feedback,
     // so we'll always use live update instead.
 #if defined(__WXMAC__)
     // With Core Graphics on Mac, it's not possible to show sash feedback,
     // so we'll always use live update instead.
 #if defined(__WXMAC__)
+    wxUnusedVar(manager);
     return true;
 #else
     return (manager.GetFlags() & wxAUI_MGR_LIVE_RESIZE) == wxAUI_MGR_LIVE_RESIZE;
     return true;
 #else
     return (manager.GetFlags() & wxAUI_MGR_LIVE_RESIZE) == wxAUI_MGR_LIVE_RESIZE;
@@ -1048,21 +1060,15 @@ bool wxAuiManager::AddPane(wxWindow* window, const wxAuiPaneInfo& pane_info)
     {
         pinfo.best_size = pinfo.window->GetClientSize();
 
     {
         pinfo.best_size = pinfo.window->GetClientSize();
 
+#if wxUSE_TOOLBAR
         if (pinfo.window->IsKindOf(CLASSINFO(wxToolBar)))
         {
             // GetClientSize() doesn't get the best size for
             // a toolbar under some newer versions of wxWidgets,
             // so use GetBestSize()
             pinfo.best_size = pinfo.window->GetBestSize();
         if (pinfo.window->IsKindOf(CLASSINFO(wxToolBar)))
         {
             // GetClientSize() doesn't get the best size for
             // a toolbar under some newer versions of wxWidgets,
             // so use GetBestSize()
             pinfo.best_size = pinfo.window->GetBestSize();
-
-            // for some reason, wxToolBar::GetBestSize() is returning
-            // a size that is a pixel shy of the correct amount.
-            // I believe this to be the correct action, until
-            // wxToolBar::GetBestSize() is fixed.  Is this assumption
-            // correct?
-            // commented out by JACS 2007-9-08 after having added a pixel in wxMSW's wxToolBar::DoGetBestSize()
-            // pinfo.best_size.y++;
         }
         }
+#endif // wxUSE_TOOLBAR
 
         if (pinfo.min_size != wxDefaultSize)
         {
 
         if (pinfo.min_size != wxDefaultSize)
         {
@@ -1281,7 +1287,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);
     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();
 
         {
             p.Restore();
 
@@ -2895,7 +2901,8 @@ bool wxAuiManager::DoDrop(wxAuiDockInfoArray& docks,
         // toolbars may only be moved in and to fixed-pane docks,
         // otherwise we will try to float the pane.  Also, the pane
         // should float if being dragged over center pane windows
         // toolbars may only be moved in and to fixed-pane docks,
         // otherwise we will try to float the pane.  Also, the pane
         // should float if being dragged over center pane windows
-        if (!part->dock->fixed || part->dock->dock_direction == wxAUI_DOCK_CENTER)
+        if (!part->dock->fixed || part->dock->dock_direction == wxAUI_DOCK_CENTER ||
+            pt.x >= cli_size.x || pt.x <= 0 || pt.y >= cli_size.y || pt.y <= 0)
         {
             if (m_last_rect.IsEmpty() || m_last_rect.Contains(pt.x, pt.y ))
             {
         {
             if (m_last_rect.IsEmpty() || m_last_rect.Contains(pt.x, pt.y ))
             {
@@ -2903,13 +2910,9 @@ bool wxAuiManager::DoDrop(wxAuiDockInfoArray& docks,
             }
             else
             {
             }
             else
             {
-                if ((m_flags & wxAUI_MGR_ALLOW_FLOATING) &&
-                   (drop.IsFloatable() ||
-                    (part->dock->dock_direction != wxAUI_DOCK_CENTER &&
-                     part->dock->dock_direction != wxAUI_DOCK_NONE)))
+                if ((m_flags & wxAUI_MGR_ALLOW_FLOATING) && drop.IsFloatable())
                 {
                 {
-                    if (drop.IsFloatable())
-                        drop.Float();
+                    drop.Float();
                 }
 
                 m_skipping = false;
                 }
 
                 m_skipping = false;
@@ -3190,6 +3193,8 @@ void wxAuiManager::OnHintFadeTimer(wxTimerEvent& WXUNUSED(event))
     if (!m_hint_wnd || m_hint_fadeamt >= m_hint_fademax)
     {
         m_hint_fadetimer.Stop();
     if (!m_hint_wnd || m_hint_fadeamt >= m_hint_fademax)
     {
         m_hint_fadetimer.Stop();
+        Disconnect(m_hint_fadetimer.GetId(), wxEVT_TIMER,
+                   wxTimerEventHandler(wxAuiManager::OnHintFadeTimer));
         return;
     }
 
         return;
     }
 
@@ -3231,8 +3236,10 @@ void wxAuiManager::ShowHint(const wxRect& rect)
         if (m_hint_fadeamt != m_hint_fademax) //  Only fade if we need to
         {
             // start fade in timer
         if (m_hint_fadeamt != m_hint_fademax) //  Only fade if we need to
         {
             // start fade in timer
-            m_hint_fadetimer.SetOwner(this, 101);
+            m_hint_fadetimer.SetOwner(this);
             m_hint_fadetimer.Start(5);
             m_hint_fadetimer.Start(5);
+            Connect(m_hint_fadetimer.GetId(), wxEVT_TIMER,
+                    wxTimerEventHandler(wxAuiManager::OnHintFadeTimer));
         }
     }
     else  // Not using a transparent hint window...
         }
     }
     else  // Not using a transparent hint window...
@@ -3300,6 +3307,10 @@ void wxAuiManager::HideHint()
             m_hint_wnd->Show(false);
         m_hint_wnd->SetTransparent(0);
         m_hint_fadetimer.Stop();
             m_hint_wnd->Show(false);
         m_hint_wnd->SetTransparent(0);
         m_hint_fadetimer.Stop();
+        // In case this is called while a hint fade is going, we need to
+        // disconnect the event handler.
+        Disconnect(m_hint_fadetimer.GetId(), wxEVT_TIMER,
+                   wxTimerEventHandler(wxAuiManager::OnHintFadeTimer));
         m_last_hint = wxRect();
         return;
     }
         m_last_hint = wxRect();
         return;
     }
@@ -3466,6 +3477,9 @@ void wxAuiManager::OnFloatingPaneMoveStart(wxWindow* wnd)
     wxAuiPaneInfo& pane = GetPane(wnd);
     wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
 
     wxAuiPaneInfo& pane = GetPane(wnd);
     wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
 
+    if(!pane.frame)
+        return;
+
     if (m_flags & wxAUI_MGR_TRANSPARENT_DRAG)
         pane.frame->SetTransparent(150);
 }
     if (m_flags & wxAUI_MGR_TRANSPARENT_DRAG)
         pane.frame->SetTransparent(150);
 }
@@ -3476,6 +3490,9 @@ void wxAuiManager::OnFloatingPaneMoving(wxWindow* wnd, wxDirection dir)
     wxAuiPaneInfo& pane = GetPane(wnd);
     wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
 
     wxAuiPaneInfo& pane = GetPane(wnd);
     wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
 
+    if(!pane.frame)
+        return;
+
     wxPoint pt = ::wxGetMousePosition();
 
 #if 0
     wxPoint pt = ::wxGetMousePosition();
 
 #if 0
@@ -3576,6 +3593,9 @@ void wxAuiManager::OnFloatingPaneMoved(wxWindow* wnd, wxDirection dir)
     wxAuiPaneInfo& pane = GetPane(wnd);
     wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
 
     wxAuiPaneInfo& pane = GetPane(wnd);
     wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
 
+    if(!pane.frame)
+        return;
+
     wxPoint pt = ::wxGetMousePosition();
 
 #if 0
     wxPoint pt = ::wxGetMousePosition();
 
 #if 0
@@ -4046,26 +4066,84 @@ bool wxAuiManager::DoEndResizeAction(wxMouseEvent& event)
     // resize the dock or the pane
     if (m_action_part && m_action_part->type==wxAuiDockUIPart::typeDockSizer)
     {
     // resize the dock or the pane
     if (m_action_part && m_action_part->type==wxAuiDockUIPart::typeDockSizer)
     {
+        // first, we must calculate the maximum size the dock may be
+        int sash_size = m_art->GetMetric(wxAUI_DOCKART_SASH_SIZE);
+
+        int used_width = 0, used_height = 0;
+
+        wxSize client_size = m_frame->GetClientSize();
+
+        size_t dock_i, dock_count = m_docks.GetCount();
+        for (dock_i = 0; dock_i < dock_count; ++dock_i)
+        {
+            wxAuiDockInfo& dock = m_docks.Item(dock_i);
+            if (dock.dock_direction == wxAUI_DOCK_TOP ||
+                dock.dock_direction == wxAUI_DOCK_BOTTOM)
+            {
+                used_height += dock.size;
+            }
+            if (dock.dock_direction == wxAUI_DOCK_LEFT ||
+                dock.dock_direction == wxAUI_DOCK_RIGHT)
+            {
+                used_width += dock.size;
+            }
+            if (dock.resizable)
+                used_width += sash_size;
+        }
+
+
+        int available_width = client_size.GetWidth() - used_width;
+        int available_height = client_size.GetHeight() - used_height;
+
+
+#if wxUSE_STATUSBAR
+        // if there's a status control, the available
+        // height decreases accordingly
+        if (m_frame && m_frame->IsKindOf(CLASSINFO(wxFrame)))
+        {
+            wxFrame* frame = static_cast<wxFrame*>(m_frame);
+            wxStatusBar* status = frame->GetStatusBar();
+            if (status)
+            {
+                wxSize status_client_size = status->GetClientSize();
+                available_height -= status_client_size.GetHeight();
+            }
+        }
+#endif
+
         wxRect& rect = m_action_part->dock->rect;
 
         wxPoint new_pos(event.m_x - m_action_offset.x,
             event.m_y - m_action_offset.y);
         wxRect& rect = m_action_part->dock->rect;
 
         wxPoint new_pos(event.m_x - m_action_offset.x,
             event.m_y - m_action_offset.y);
+        int new_size, old_size = m_action_part->dock->size;
 
         switch (m_action_part->dock->dock_direction)
         {
         case wxAUI_DOCK_LEFT:
 
         switch (m_action_part->dock->dock_direction)
         {
         case wxAUI_DOCK_LEFT:
-            m_action_part->dock->size = new_pos.x - rect.x;
+            new_size = new_pos.x - rect.x;
+            if (new_size-old_size > available_width)
+                new_size = old_size+available_width;
+            m_action_part->dock->size = new_size;
             break;
         case wxAUI_DOCK_TOP:
             break;
         case wxAUI_DOCK_TOP:
-            m_action_part->dock->size = new_pos.y - rect.y;
+            new_size = new_pos.y - rect.y;
+            if (new_size-old_size > available_height)
+                new_size = old_size+available_height;
+            m_action_part->dock->size = new_size;
             break;
         case wxAUI_DOCK_RIGHT:
             break;
         case wxAUI_DOCK_RIGHT:
-            m_action_part->dock->size = rect.x + rect.width -
-                new_pos.x - m_action_part->rect.GetWidth();
+            new_size = rect.x + rect.width - new_pos.x -
+                       m_action_part->rect.GetWidth();
+            if (new_size-old_size > available_width)
+                new_size = old_size+available_width;
+            m_action_part->dock->size = new_size;
             break;
         case wxAUI_DOCK_BOTTOM:
             break;
         case wxAUI_DOCK_BOTTOM:
-            m_action_part->dock->size = rect.y + rect.height -
+            new_size = rect.y + rect.height -
                 new_pos.y - m_action_part->rect.GetHeight();
                 new_pos.y - m_action_part->rect.GetHeight();
+            if (new_size-old_size > available_height)
+                new_size = old_size+available_height;
+            m_action_part->dock->size = new_size;
             break;
         }
 
             break;
         }
 
@@ -4140,6 +4218,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
         // 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
@@ -4214,10 +4297,26 @@ bool wxAuiManager::DoEndResizeAction(wxMouseEvent& event)
         int prop_diff = new_proportion - pane.dock_proportion;
 
         // borrow the space from our neighbor pane to the
         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;
 
         pane.dock_proportion = new_proportion;
 
+
         // repaint
         Update();
         Repaint(NULL);
         // repaint
         Update();
         Repaint(NULL);
@@ -4355,9 +4454,19 @@ void wxAuiManager::OnMotion(wxMouseEvent& event)
                 wxScreenDC dc;
 
                 if (!m_action_hintrect.IsEmpty())
                 wxScreenDC dc;
 
                 if (!m_action_hintrect.IsEmpty())
+                {
+                    // remove old resize hint
                     DrawResizeHint(dc, m_action_hintrect);
                     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;
+                }
             }
         }
     }
             }
         }
     }