diff --git a/docs/changes.txt b/docs/changes.txt index edb6fb9980..b62e275ffd 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -121,6 +121,8 @@ All (GUI): - Fixed wxHTML's line breaks handling in
 blocks broken in 2.8.8 (#10120).
 - wxHTML: don't include extra whitespace in table cells.
 - Implemented wxWindow::DragAcceptFiles() on all platforms.
+- Added wxAUI_MGR_LIVE_RESIZE flag to wxAuiManager and made it the default on
+  wxMac with CoreGraphics where sash drawing isn't implemented.
 
 All (Unix):
 
diff --git a/docs/latex/wx/auimanager.tex b/docs/latex/wx/auimanager.tex
index 4328db3810..d050a240d6 100644
--- a/docs/latex/wx/auimanager.tex
+++ b/docs/latex/wx/auimanager.tex
@@ -109,6 +109,7 @@ enum wxAuiManagerOption
     wxAUI_MGR_RECTANGLE_HINT           = 1 << 5,
     wxAUI_MGR_HINT_FADE                = 1 << 6,
     wxAUI_MGR_NO_VENETIAN_BLINDS_FADE  = 1 << 7,
+    wxAUI_MGR_LIVE_RESIZE              = 1 << 8,
 
     wxAUI_MGR_DEFAULT = wxAUI_MGR_ALLOW_FLOATING |
                         wxAUI_MGR_TRANSPARENT_HINT |
diff --git a/include/wx/aui/framemanager.h b/include/wx/aui/framemanager.h
index 9c45516d8f..ea86538710 100644
--- a/include/wx/aui/framemanager.h
+++ b/include/wx/aui/framemanager.h
@@ -47,6 +47,7 @@ enum wxAuiManagerOption
     wxAUI_MGR_RECTANGLE_HINT           = 1 << 5,
     wxAUI_MGR_HINT_FADE                = 1 << 6,
     wxAUI_MGR_NO_VENETIAN_BLINDS_FADE  = 1 << 7,
+    wxAUI_MGR_LIVE_RESIZE              = 1 << 8,
 
     wxAUI_MGR_DEFAULT = wxAUI_MGR_ALLOW_FLOATING |
                         wxAUI_MGR_TRANSPARENT_HINT |
@@ -166,7 +167,7 @@ public:
     }
 
     ~wxAuiPaneInfo() {}
-    
+
 #ifndef SWIG
     wxAuiPaneInfo(const wxAuiPaneInfo& c)
     {
@@ -350,12 +351,12 @@ public:
 #ifdef SWIG
     %typemap(out) wxAuiPaneInfo& ;
 #endif
-    
+
 public:
 
     // NOTE: You can add and subtract flags from this list,
     // but do not change the values of the flags, because
-    // they are stored in a binary integer format in the 
+    // they are stored in a binary integer format in the
     // perspective string.  If you really need to change the
     // values around, you'll have to ensure backwards-compatibility
     // in the perspective loading code.
@@ -384,11 +385,11 @@ public:
         buttonMaximize        = 1 << 22,
         buttonMinimize        = 1 << 23,
         buttonPin             = 1 << 24,
-        
+
         buttonCustom1         = 1 << 26,
         buttonCustom2         = 1 << 27,
         buttonCustom3         = 1 << 28,
-        
+
         savedHiddenState      = 1 << 30, // used internally
         actionPane            = 1 << 31  // used internally
     };
@@ -451,7 +452,7 @@ public:
 
     bool AddPane(wxWindow* window,
                  const wxAuiPaneInfo& pane_info);
-                 
+
     bool AddPane(wxWindow* window,
                  const wxAuiPaneInfo& pane_info,
                  const wxPoint& drop_pos);
@@ -465,7 +466,7 @@ public:
                  int insert_level = wxAUI_INSERT_PANE);
 
     bool DetachPane(wxWindow* window);
-    
+
     void Update();
 
     wxString SavePaneInfo(wxAuiPaneInfo& pane);
@@ -475,7 +476,7 @@ public:
 
     void SetDockSizeConstraint(double width_pct, double height_pct);
     void GetDockSizeConstraint(double* width_pct, double* height_pct) const;
-    
+
     void ClosePane(wxAuiPaneInfo& pane_info);
     void MaximizePane(wxAuiPaneInfo& pane_info);
     void RestorePane(wxAuiPaneInfo& pane_info);
@@ -493,12 +494,12 @@ public:
                  wxWindow* pane_window,
                  const wxPoint& pt,
                  const wxPoint& offset);
-                      
+
     void DrawHintRect(
                  wxWindow* pane_window,
                  const wxPoint& pt,
                  const wxPoint& offset);
-                      
+
     virtual void ShowHint(const wxRect& rect);
     virtual void HideHint();
 
@@ -506,14 +507,14 @@ public:
 
     // deprecated -- please use SetManagedWindow() and
     // and GetManagedWindow() instead
-    
+
     wxDEPRECATED( void SetFrame(wxFrame* frame) );
     wxDEPRECATED( wxFrame* GetFrame() const );
-    
+
 protected:
 
     void UpdateHintWindowConfig();
-    
+
     void DoFrameLayout();
 
     void LayoutAddPane(wxSizer* container,
@@ -559,6 +560,10 @@ protected:
                               wxArrayInt& positions,
                               wxArrayInt& sizes);
 
+#if wxABI_VERSION >= 20810
+    /// Ends a resize action, or for live update, resizes the sash
+    bool DoEndResizeAction(wxMouseEvent& event);
+#endif
 
 public:
 
@@ -623,7 +628,7 @@ protected:
     wxTimer m_hint_fadetimer;    // transparent fade timer
     wxByte m_hint_fadeamt;       // transparent fade amount
     wxByte m_hint_fademax;       // maximum value of hint fade
-    
+
     void* m_reserved;
 
 #ifndef SWIG
@@ -665,17 +670,17 @@ public:
     void SetPane(wxAuiPaneInfo* p) { pane = p; }
     void SetButton(int b) { button = b; }
     void SetDC(wxDC* pdc) { dc = pdc; }
- 
+
     wxAuiManager* GetManager() const { return manager; }
     wxAuiPaneInfo* GetPane() const { return pane; }
     int GetButton() const { return button; }
     wxDC* GetDC() const { return dc; }
-    
+
     void Veto(bool veto = true) { veto_flag = veto; }
     bool GetVeto() const { return veto_flag; }
     void SetCanVeto(bool can_veto) { canveto_flag = can_veto; }
     bool CanVeto() const { return  canveto_flag && veto_flag; }
-    
+
 public:
     wxAuiManager* manager;
     wxAuiPaneInfo* pane;
diff --git a/samples/aui/auidemo.cpp b/samples/aui/auidemo.cpp
index 40e0e0a936..c1bf0f9c4f 100644
--- a/samples/aui/auidemo.cpp
+++ b/samples/aui/auidemo.cpp
@@ -84,6 +84,7 @@ class MyFrame : public wxFrame
         ID_NoGradient,
         ID_VerticalGradient,
         ID_HorizontalGradient,
+        ID_LiveUpdate,
         ID_Settings,
         ID_CustomizeToolbar,
         ID_DropDownToolbarItem,
@@ -101,9 +102,9 @@ class MyFrame : public wxFrame
         ID_NotebookArtSimple,
         ID_NotebookAlignTop,
         ID_NotebookAlignBottom,
-        
+
         ID_SampleItem,
-        
+
         ID_FirstPerspective = ID_CreatePerspective+1000
     };
 
@@ -588,6 +589,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_MENU(ID_HintFade, MyFrame::OnManagerFlag)
     EVT_MENU(ID_NoVenetianFade, MyFrame::OnManagerFlag)
     EVT_MENU(ID_TransparentDrag, MyFrame::OnManagerFlag)
+    EVT_MENU(ID_LiveUpdate, MyFrame::OnManagerFlag)
     EVT_MENU(ID_AllowActivePane, MyFrame::OnManagerFlag)
     EVT_MENU(ID_NotebookTabFixedWidth, MyFrame::OnNotebookFlag)
     EVT_MENU(ID_NotebookNoCloseButton, MyFrame::OnNotebookFlag)
@@ -634,6 +636,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_UPDATE_UI(ID_HintFade, MyFrame::OnUpdateUI)
     EVT_UPDATE_UI(ID_NoVenetianFade, MyFrame::OnUpdateUI)
     EVT_UPDATE_UI(ID_TransparentDrag, MyFrame::OnUpdateUI)
+    EVT_UPDATE_UI(ID_LiveUpdate, MyFrame::OnUpdateUI)
     EVT_UPDATE_UI(ID_NoGradient, MyFrame::OnUpdateUI)
     EVT_UPDATE_UI(ID_VerticalGradient, MyFrame::OnUpdateUI)
     EVT_UPDATE_UI(ID_HorizontalGradient, MyFrame::OnUpdateUI)
@@ -696,6 +699,7 @@ MyFrame::MyFrame(wxWindow* parent,
     options_menu->AppendCheckItem(ID_NoVenetianFade, _("Disable Venetian Blinds Hint Fade-in"));
     options_menu->AppendCheckItem(ID_TransparentDrag, _("Transparent Drag"));
     options_menu->AppendCheckItem(ID_AllowActivePane, _("Allow Active Pane"));
+    options_menu->AppendCheckItem(ID_LiveUpdate, _("Live Resize Update"));
     options_menu->AppendSeparator();
     options_menu->AppendRadioItem(ID_NoGradient, _("No Caption Gradient"));
     options_menu->AppendRadioItem(ID_VerticalGradient, _("Vertical Caption Gradient"));
@@ -753,7 +757,7 @@ MyFrame::MyFrame(wxWindow* parent,
 
 
     // prepare a few custom overflow elements for the toolbars' overflow buttons
-    
+
     wxAuiToolBarItemArray prepend_items;
     wxAuiToolBarItemArray append_items;
     wxAuiToolBarItem item;
@@ -816,7 +820,7 @@ MyFrame::MyFrame(wxWindow* parent,
 
 
     wxAuiToolBar* tb4 = new wxAuiToolBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
-                                         wxAUI_TB_DEFAULT_STYLE | 
+                                         wxAUI_TB_DEFAULT_STYLE |
                                          wxAUI_TB_OVERFLOW |
                                          wxAUI_TB_TEXT |
                                          wxAUI_TB_HORZ_TEXT);
@@ -1075,6 +1079,7 @@ void MyFrame::OnManagerFlag(wxCommandEvent& event)
         case ID_TransparentHint: flag = wxAUI_MGR_TRANSPARENT_HINT; break;
         case ID_VenetianBlindsHint: flag = wxAUI_MGR_VENETIAN_BLINDS_HINT; break;
         case ID_RectangleHint: flag = wxAUI_MGR_RECTANGLE_HINT; break;
+        case ID_LiveUpdate: flag = wxAUI_MGR_LIVE_RESIZE; break;
     }
 
     if (flag)
@@ -1188,6 +1193,9 @@ void MyFrame::OnUpdateUI(wxUpdateUIEvent& event)
         case ID_TransparentHint:
             event.Check((flags & wxAUI_MGR_TRANSPARENT_HINT) != 0);
             break;
+        case ID_LiveUpdate:
+            event.Check((flags & wxAUI_MGR_LIVE_RESIZE) != 0);
+            break;
         case ID_VenetianBlindsHint:
             event.Check((flags & wxAUI_MGR_VENETIAN_BLINDS_HINT) != 0);
             break;
@@ -1394,35 +1402,35 @@ void MyFrame::OnDropDownToolbarItem(wxAuiToolBarEvent& evt)
     if (evt.IsDropDownClicked())
     {
         wxAuiToolBar* tb = static_cast(evt.GetEventObject());
-        
+
         tb->SetToolSticky(evt.GetId(), true);
-        
+
         // create the popup menu
         wxMenu menuPopup;
-        
+
         wxBitmap bmp = wxArtProvider::GetBitmap(wxART_QUESTION, wxART_OTHER, wxSize(16,16));
-        
+
         wxMenuItem* m1 =  new wxMenuItem(&menuPopup, 101, _("Drop Down Item 1"));
         m1->SetBitmap(bmp);
         menuPopup.Append(m1);
-        
+
         wxMenuItem* m2 =  new wxMenuItem(&menuPopup, 101, _("Drop Down Item 2"));
         m2->SetBitmap(bmp);
         menuPopup.Append(m2);
-        
+
         wxMenuItem* m3 =  new wxMenuItem(&menuPopup, 101, _("Drop Down Item 3"));
         m3->SetBitmap(bmp);
         menuPopup.Append(m3);
-        
+
         wxMenuItem* m4 =  new wxMenuItem(&menuPopup, 101, _("Drop Down Item 4"));
         m4->SetBitmap(bmp);
         menuPopup.Append(m4);
-        
+
         // line up our menu with the button
         wxRect rect = tb->GetToolRect(evt.GetId());
         wxPoint pt = tb->ClientToScreen(rect.GetBottomLeft());
         pt = ScreenToClient(pt);
-        
+
 
         PopupMenu(&menuPopup, pt);
 
diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp
index 7bcd189c19..1dbf11ae78 100644
--- a/src/aui/framemanager.cpp
+++ b/src/aui/framemanager.cpp
@@ -720,6 +720,17 @@ unsigned int wxAuiManager::GetFlags() const
     return m_flags;
 }
 
+// Convenience function
+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__) && wxMAC_USE_CORE_GRAPHICS
+    return true;
+#else
+    return (manager.GetFlags() & wxAUI_MGR_LIVE_RESIZE) == wxAUI_MGR_LIVE_RESIZE;
+#endif
+}
 
 // don't use these anymore as they are deprecated
 // use Set/GetManagedFrame() instead
@@ -3911,8 +3922,11 @@ void wxAuiManager::UpdateButtonOnScreen(wxAuiDockUIPart* button_ui_part,
     }
 }
 
+static int gs_CurrentDragItem = -1;
+
 void wxAuiManager::OnLeftDown(wxMouseEvent& event)
 {
+    gs_CurrentDragItem = -1;
     wxAuiDockUIPart* part = HitTest(event.GetX(), event.GetY());
     if (part)
     {
@@ -4006,6 +4020,191 @@ void wxAuiManager::OnLeftDown(wxMouseEvent& event)
 #endif
 }
 
+/// Ends a resize action, or for live update, resizes the sash
+bool wxAuiManager::DoEndResizeAction(wxMouseEvent& event)
+{
+    // resize the dock or the pane
+    if (m_action_part && m_action_part->type==wxAuiDockUIPart::typeDockSizer)
+    {
+        wxRect& rect = m_action_part->dock->rect;
+
+        wxPoint new_pos(event.m_x - m_action_offset.x,
+            event.m_y - m_action_offset.y);
+
+        switch (m_action_part->dock->dock_direction)
+        {
+        case wxAUI_DOCK_LEFT:
+            m_action_part->dock->size = new_pos.x - rect.x;
+            break;
+        case wxAUI_DOCK_TOP:
+            m_action_part->dock->size = new_pos.y - rect.y;
+            break;
+        case wxAUI_DOCK_RIGHT:
+            m_action_part->dock->size = rect.x + rect.width -
+                new_pos.x - m_action_part->rect.GetWidth();
+            break;
+        case wxAUI_DOCK_BOTTOM:
+            m_action_part->dock->size = rect.y + rect.height -
+                new_pos.y - m_action_part->rect.GetHeight();
+            break;
+        }
+
+        Update();
+        Repaint(NULL);
+    }
+    else if (m_action_part &&
+        m_action_part->type == wxAuiDockUIPart::typePaneSizer)
+    {
+        wxAuiDockInfo& dock = *m_action_part->dock;
+        wxAuiPaneInfo& pane = *m_action_part->pane;
+
+        int total_proportion = 0;
+        int dock_pixels = 0;
+        int new_pixsize = 0;
+
+        int caption_size = m_art->GetMetric(wxAUI_DOCKART_CAPTION_SIZE);
+        int pane_border_size = m_art->GetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE);
+        int sash_size = m_art->GetMetric(wxAUI_DOCKART_SASH_SIZE);
+
+        wxPoint new_pos(event.m_x - m_action_offset.x,
+            event.m_y - m_action_offset.y);
+
+        // determine the pane rectangle by getting the pane part
+        wxAuiDockUIPart* pane_part = GetPanePart(pane.window);
+        wxASSERT_MSG(pane_part,
+            wxT("Pane border part not found -- shouldn't happen"));
+
+        // determine the new pixel size that the user wants;
+        // this will help us recalculate the pane's proportion
+        if (dock.IsHorizontal())
+            new_pixsize = new_pos.x - pane_part->rect.x;
+        else
+            new_pixsize = new_pos.y - pane_part->rect.y;
+
+        // determine the size of the dock, based on orientation
+        if (dock.IsHorizontal())
+            dock_pixels = dock.rect.GetWidth();
+        else
+            dock_pixels = dock.rect.GetHeight();
+
+        // determine the total proportion of all resizable panes,
+        // and the total size of the dock minus the size of all
+        // the fixed panes
+        int i, dock_pane_count = dock.panes.GetCount();
+        int pane_position = -1;
+        for (i = 0; i < dock_pane_count; ++i)
+        {
+            wxAuiPaneInfo& p = *dock.panes.Item(i);
+            if (p.window == pane.window)
+                pane_position = i;
+
+            // while we're at it, subtract the pane sash
+            // width from the dock width, because this would
+            // skew our proportion calculations
+            if (i > 0)
+                dock_pixels -= sash_size;
+
+            // also, the whole size (including decorations) of
+            // all fixed panes must also be subtracted, because they
+            // are not part of the proportion calculation
+            if (p.IsFixed())
+            {
+                if (dock.IsHorizontal())
+                    dock_pixels -= p.best_size.x;
+                else
+                    dock_pixels -= p.best_size.y;
+            }
+            else
+            {
+                total_proportion += p.dock_proportion;
+            }
+        }
+
+        // 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
+        // to the right of the action pane
+        int borrow_pane = -1;
+        for (i = pane_position+1; i < dock_pane_count; ++i)
+        {
+            wxAuiPaneInfo& p = *dock.panes.Item(i);
+            if (!p.IsFixed())
+            {
+                borrow_pane = i;
+                break;
+            }
+        }
+
+
+        // demand that the pane being resized is found in this dock
+        // (this assert really never should be raised)
+        wxASSERT_MSG(pane_position != -1, wxT("Pane not found in dock"));
+
+        // prevent division by zero
+        if (dock_pixels == 0 || total_proportion == 0 || borrow_pane == -1)
+        {
+            m_action = actionNone;
+            return false;
+        }
+
+        // calculate the new proportion of the pane
+        int new_proportion = (new_pixsize*total_proportion)/dock_pixels;
+
+        // default minimum size
+        int min_size = 0;
+
+        // check against the pane's minimum size, if specified. please note
+        // that this is not enough to ensure that the minimum size will
+        // not be violated, because the whole frame might later be shrunk,
+        // causing the size of the pane to violate it's minimum size
+        if (pane.min_size.IsFullySpecified())
+        {
+            min_size = 0;
+
+            if (pane.HasBorder())
+                min_size += (pane_border_size*2);
+
+            // calculate minimum size with decorations (border,caption)
+            if (pane_part->orientation == wxVERTICAL)
+            {
+                min_size += pane.min_size.y;
+                if (pane.HasCaption())
+                    min_size += caption_size;
+            }
+            else
+            {
+                min_size += pane.min_size.x;
+            }
+        }
+
+
+        // for some reason, an arithmatic error somewhere is causing
+        // the proportion calculations to always be off by 1 pixel;
+        // for now we will add the 1 pixel on, but we really should
+        // determine what's causing this.
+        min_size++;
+
+        int min_proportion = (min_size*total_proportion)/dock_pixels;
+
+        if (new_proportion < min_proportion)
+            new_proportion = min_proportion;
+
+
+
+        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;
+        pane.dock_proportion = new_proportion;
+
+        // repaint
+        Update();
+        Repaint(NULL);
+    }
+
+    return true;
+}
 
 void wxAuiManager::OnLeftUp(wxMouseEvent& event)
 {
@@ -4015,196 +4214,25 @@ void wxAuiManager::OnLeftUp(wxMouseEvent& event)
 
         // get rid of the hint rectangle
 
-        // On Mac we use a wxClientDC since when compiling and running on Leopard,
+        // On non-CG Mac we use a wxClientDC since when compiling and running on Leopard,
         // we can get the dreaded _SetDstBlits32BGRA crash (but not in the AUI sample).
-        // This only helps in non-CG mode - there is zero resize feeedback in CG mode
-        // at present.
+        // In CG mode we always use live resize since DrawResizeHint doesn't work.
+        if (!wxAuiManager_HasLiveResize(*this))
+        {
+            // get rid of the hint rectangle
 #if defined(__WXMAC__) && !wxMAC_USE_CORE_GRAPHICS
-        wxClientDC dc(m_frame);
+            wxClientDC dc(m_frame);
 #else
-        wxScreenDC dc;
+            wxScreenDC dc;
 #endif
-        DrawResizeHint(dc, m_action_hintrect);
-
-        // resize the dock or the pane
-        if (m_action_part && m_action_part->type==wxAuiDockUIPart::typeDockSizer)
-        {
-            wxRect& rect = m_action_part->dock->rect;
-
-            wxPoint new_pos(event.m_x - m_action_offset.x,
-                            event.m_y - m_action_offset.y);
-
-            switch (m_action_part->dock->dock_direction)
-            {
-                case wxAUI_DOCK_LEFT:
-                    m_action_part->dock->size = new_pos.x - rect.x;
-                    break;
-                case wxAUI_DOCK_TOP:
-                    m_action_part->dock->size = new_pos.y - rect.y;
-                    break;
-                case wxAUI_DOCK_RIGHT:
-                    m_action_part->dock->size = rect.x + rect.width -
-                                  new_pos.x - m_action_part->rect.GetWidth();
-                    break;
-                case wxAUI_DOCK_BOTTOM:
-                    m_action_part->dock->size = rect.y + rect.height -
-                                  new_pos.y - m_action_part->rect.GetHeight();
-                    break;
-            }
-
-            Update();
-            Repaint(NULL);
+            DrawResizeHint(dc, m_action_hintrect);
         }
-         else if (m_action_part &&
-                  m_action_part->type == wxAuiDockUIPart::typePaneSizer)
-        {
-            wxAuiDockInfo& dock = *m_action_part->dock;
-            wxAuiPaneInfo& pane = *m_action_part->pane;
+        if (gs_CurrentDragItem != -1 && wxAuiManager_HasLiveResize(*this))
+            m_action_part = & (m_uiparts.Item(gs_CurrentDragItem));
 
-            int total_proportion = 0;
-            int dock_pixels = 0;
-            int new_pixsize = 0;
+        DoEndResizeAction(event);
 
-            int caption_size = m_art->GetMetric(wxAUI_DOCKART_CAPTION_SIZE);
-            int pane_border_size = m_art->GetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE);
-            int sash_size = m_art->GetMetric(wxAUI_DOCKART_SASH_SIZE);
-
-            wxPoint new_pos(event.m_x - m_action_offset.x,
-                            event.m_y - m_action_offset.y);
-
-            // determine the pane rectangle by getting the pane part
-            wxAuiDockUIPart* pane_part = GetPanePart(pane.window);
-            wxASSERT_MSG(pane_part,
-                       wxT("Pane border part not found -- shouldn't happen"));
-
-            // determine the new pixel size that the user wants;
-            // this will help us recalculate the pane's proportion
-            if (dock.IsHorizontal())
-                new_pixsize = new_pos.x - pane_part->rect.x;
-                 else
-                new_pixsize = new_pos.y - pane_part->rect.y;
-
-            // determine the size of the dock, based on orientation
-            if (dock.IsHorizontal())
-                dock_pixels = dock.rect.GetWidth();
-                 else
-                dock_pixels = dock.rect.GetHeight();
-
-            // determine the total proportion of all resizable panes,
-            // and the total size of the dock minus the size of all
-            // the fixed panes
-            int i, dock_pane_count = dock.panes.GetCount();
-            int pane_position = -1;
-            for (i = 0; i < dock_pane_count; ++i)
-            {
-                wxAuiPaneInfo& p = *dock.panes.Item(i);
-                if (p.window == pane.window)
-                    pane_position = i;
-
-                // while we're at it, subtract the pane sash
-                // width from the dock width, because this would
-                // skew our proportion calculations
-                if (i > 0)
-                    dock_pixels -= sash_size;
-
-                // also, the whole size (including decorations) of
-                // all fixed panes must also be subtracted, because they
-                // are not part of the proportion calculation
-                if (p.IsFixed())
-                {
-                    if (dock.IsHorizontal())
-                        dock_pixels -= p.best_size.x;
-                         else
-                        dock_pixels -= p.best_size.y;
-                }
-                 else
-                {
-                    total_proportion += p.dock_proportion;
-                }
-            }
-
-            // 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
-            // to the right of the action pane
-            int borrow_pane = -1;
-            for (i = pane_position+1; i < dock_pane_count; ++i)
-            {
-                wxAuiPaneInfo& p = *dock.panes.Item(i);
-                if (!p.IsFixed())
-                {
-                    borrow_pane = i;
-                    break;
-                }
-            }
-
-
-            // demand that the pane being resized is found in this dock
-            // (this assert really never should be raised)
-            wxASSERT_MSG(pane_position != -1, wxT("Pane not found in dock"));
-
-            // prevent division by zero
-            if (dock_pixels == 0 || total_proportion == 0 || borrow_pane == -1)
-            {
-                m_action = actionNone;
-                return;
-            }
-
-            // calculate the new proportion of the pane
-            int new_proportion = (new_pixsize*total_proportion)/dock_pixels;
-
-            // default minimum size
-            int min_size = 0;
-
-            // check against the pane's minimum size, if specified. please note
-            // that this is not enough to ensure that the minimum size will
-            // not be violated, because the whole frame might later be shrunk,
-            // causing the size of the pane to violate it's minimum size
-            if (pane.min_size.IsFullySpecified())
-            {
-                min_size = 0;
-
-                if (pane.HasBorder())
-                    min_size += (pane_border_size*2);
-
-                // calculate minimum size with decorations (border,caption)
-                if (pane_part->orientation == wxVERTICAL)
-                {
-                    min_size += pane.min_size.y;
-                    if (pane.HasCaption())
-                        min_size += caption_size;
-                }
-                 else
-                {
-                    min_size += pane.min_size.x;
-                }
-            }
-
-
-            // for some reason, an arithmatic error somewhere is causing
-            // the proportion calculations to always be off by 1 pixel;
-            // for now we will add the 1 pixel on, but we really should
-            // determine what's causing this.
-            min_size++;
-
-            int min_proportion = (min_size*total_proportion)/dock_pixels;
-
-            if (new_proportion < min_proportion)
-                new_proportion = min_proportion;
-
-
-
-            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;
-            pane.dock_proportion = new_proportion;
-
-            // repaint
-            Update();
-            Repaint(NULL);
-        }
+        gs_CurrentDragItem = -1;
     }
     else if (m_action == actionClickButton)
     {
@@ -4287,6 +4315,13 @@ void wxAuiManager::OnMotion(wxMouseEvent& event)
 
     if (m_action == actionResize)
     {
+        // It's necessary to reset m_action_part since it destroyed
+        // by the Update within DoEndResizeAction.
+        if (gs_CurrentDragItem != -1)
+            m_action_part = & (m_uiparts.Item(gs_CurrentDragItem));
+        else
+            gs_CurrentDragItem = m_uiparts.Index(* m_action_part);
+
         if (m_action_part)
         {
             wxPoint pos = m_action_part->rect.GetPosition();
@@ -4295,24 +4330,30 @@ void wxAuiManager::OnMotion(wxMouseEvent& event)
                  else
                 pos.x = wxMax(0, event.m_x - m_action_offset.x);
 
-          // On Mac we use a wxClientDC since when compiling and running on Leopard,
-          // we can get the dreaded _SetDstBlits32BGRA crash (but not in the AUI sample).
-          // This only helps in non-CG mode - there is zero resize feeedback in CG mode
-          // at present.
-#if defined(__WXMAC__) && !wxMAC_USE_CORE_GRAPHICS
-            wxRect rect(pos,
-                    m_action_part->rect.GetSize());
+            if (wxAuiManager_HasLiveResize(*this))
+            {
 
-            wxClientDC dc(m_frame);
+                m_frame->ReleaseMouse();
+                DoEndResizeAction(event);
+                m_frame->CaptureMouse();
+            }
+            else
+            {
+#if defined(__WXMAC__) && !wxMAC_USE_CORE_GRAPHICS
+                wxRect rect(pos,
+                            m_action_part->rect.GetSize());
+
+                wxClientDC dc(m_frame);
 #else
-            wxRect rect(m_frame->ClientToScreen(pos),
-                    m_action_part->rect.GetSize());
-            wxScreenDC dc;
+                wxRect rect(m_frame->ClientToScreen(pos),
+                            m_action_part->rect.GetSize());
+                wxScreenDC dc;
 #endif
-            if (!m_action_hintrect.IsEmpty())
-                DrawResizeHint(dc, m_action_hintrect);
-            DrawResizeHint(dc, rect);
-            m_action_hintrect = rect;
+                if (!m_action_hintrect.IsEmpty())
+                    DrawResizeHint(dc, m_action_hintrect);
+                DrawResizeHint(dc, rect);
+                m_action_hintrect = rect;
+            }
         }
     }
     else if (m_action == actionClickCaption)
diff --git a/version-script.in b/version-script.in
index b76a7c2570..c55b4e30f6 100644
--- a/version-script.in
+++ b/version-script.in
@@ -26,6 +26,7 @@
 # public symbols added in 2.8.10 (please keep in alphabetical order):
 @WX_VERSION_TAG@.10 {
         *wxArtProvider*PushBack*;
+        *wxAui*DoEndResizeAction*;
         *wxCArrayString*Release*;
         *wxDCBase*GetFontPointSizeAdjustment*;
         *wxWindowBase*DragAcceptFiles*;