Kirix Support Forums

Live resizing

Please post any wxAUI patches or modifications you've created here. Thanks!

Live resizing

Postby astigsen on Thu Jan 26, 2006 1:23 pm

Here is a patch that enables live resizing (eg. sizer follows mouse rather than drawing a hint).

I would like to avoid the reacquisition of the part pointer in wxFrameManager::OnMotion(), but I was not able to find a smarter way. Maybe somebody with a deeper knowledge of the code could take a look at it?

Code: Select all
--- wxaui-0.9.1/manager.h   2006-01-10 18:37:04.000000000 +0100
+++ manager.h   2006-01-26 19:09:24.828125000 +0100
@@ -30,6 +30,7 @@
     wxAUI_MGR_TRANSPARENT_DRAG      = 1 << 2,
     wxAUI_MGR_TRANSPARENT_HINT      = 1 << 3,
     wxAUI_MGR_TRANSPARENT_HINT_FADE = 1 << 4,
+    wxAUI_MGR_LIVE_RESIZE           = 1 << 5,

     wxAUI_MGR_DEFAULT = wxAUI_MGR_ALLOW_FLOATING |
                         wxAUI_MGR_TRANSPARENT_HINT |


Code: Select all
--- wxaui-0.9.1/manager.cpp   2006-01-10 18:37:06.000000000 +0100
+++ manager.cpp   2006-01-26 18:41:18.421875000 +0100
@@ -3555,189 +3555,14 @@
     {
         m_frame->ReleaseMouse();

-        // get rid of the hint rectangle
-        wxScreenDC dc;
-        DrawResizeHint(dc, m_action_hintrect);
+        if (!(m_flags & wxAUI_MGR_LIVE_RESIZE))
+        {
+            // get rid of the hint rectangle
+            wxScreenDC dc;
+            DrawResizeHint(dc, m_action_hintrect);
+        }
+        ResizeDock(wxPoint(event.m_x, event.m_y));
-
-        // resize the dock or the pane
-        if (m_action_part && m_action_part->type==wxDockUIPart::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 == wxDockUIPart::typePaneSizer)
-        {
-            wxDockInfo& dock = *m_action_part->dock;
-            wxPaneInfo& pane = *m_action_part->pane;
-
-            int total_proportion = 0;
-            int dock_pixels = 0;
-            int new_pixsize = 0;
-
-            int caption_size = m_art->GetMetric(wxAUI_ART_CAPTION_SIZE);
-            int pane_border_size = m_art->GetMetric(wxAUI_ART_PANE_BORDER_SIZE);
-            int sash_size = m_art->GetMetric(wxAUI_ART_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
-            wxDockUIPart* 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)
-            {
-                wxPaneInfo& 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)
-            {
-                wxPaneInfo& 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);
-        }
     }
      else if (m_action == actionClickButton)
     {
@@ -3790,6 +3615,190 @@
     m_last_mouse_move = wxPoint(); // see comment in OnMotion()
}

+void wxFrameManager::ResizeDock(const wxPoint& pos)
+{
+    // resize the dock or the pane
+    if (m_action_part && m_action_part->type==wxDockUIPart::typeDockSizer)
+    {
+        wxLogDebug(wxT("  part %d"), m_action_part->dock->dock_direction);
+        wxRect& rect = m_action_part->dock->rect;
+
+        wxPoint new_pos(pos.x - m_action_offset.x,
+                        pos.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 == wxDockUIPart::typePaneSizer)
+    {
+        wxDockInfo& dock = *m_action_part->dock;
+        wxPaneInfo& pane = *m_action_part->pane;
+
+        int total_proportion = 0;
+        int dock_pixels = 0;
+        int new_pixsize = 0;
+
+        int caption_size = m_art->GetMetric(wxAUI_ART_CAPTION_SIZE);
+        int pane_border_size = m_art->GetMetric(wxAUI_ART_PANE_BORDER_SIZE);
+        int sash_size = m_art->GetMetric(wxAUI_ART_SASH_SIZE);
+
+        wxPoint new_pos(pos.x - m_action_offset.x,
+                        pos.y - m_action_offset.y);
+
+        // determine the pane rectangle by getting the pane part
+        wxDockUIPart* 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)
+        {
+            wxPaneInfo& 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)
+        {
+            wxPaneInfo& 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);
+    }
+}
+

void wxFrameManager::OnMotion(wxMouseEvent& event)
{
@@ -3807,22 +3816,33 @@
     
     if (m_action == actionResize)
     {
-        wxPoint pos = m_action_part->rect.GetPosition();
-        if (m_action_part->orientation == wxHORIZONTAL)
-            pos.y = wxMax(0, event.m_y - m_action_offset.y);
-             else
-            pos.x = wxMax(0, event.m_x - m_action_offset.x);
-
-        wxRect rect(m_frame->ClientToScreen(pos),
-                    m_action_part->rect.GetSize());
-
-        wxScreenDC dc;
-        if (!m_action_hintrect.IsEmpty())
-            DrawResizeHint(dc, m_action_hintrect);
-        DrawResizeHint(dc, rect);
-        m_action_hintrect = rect;
+        if (m_flags & wxAUI_MGR_LIVE_RESIZE)
+        {
+            ResizeDock(wxPoint(event.m_x, event.m_y));
+
+            // The part pointer does not seem to survive the relayout
+            // so we have to reacquire it here for it to be valid
+            // at the next motion event
+            m_action_part = HitTest(event.GetX(), event.GetY());
+        }
+        else {
+            wxPoint pos = m_action_part->rect.GetPosition();
+            if (m_action_part->orientation == wxHORIZONTAL)
+                pos.y = wxMax(0, event.m_y - m_action_offset.y);
+                 else
+                pos.x = wxMax(0, event.m_x - m_action_offset.x);
+
+            wxRect rect(m_frame->ClientToScreen(pos),
+                        m_action_part->rect.GetSize());
+
+            wxScreenDC dc;
+            if (!m_action_hintrect.IsEmpty())
+                DrawResizeHint(dc, m_action_hintrect);
+            DrawResizeHint(dc, rect);
+            m_action_hintrect = rect;
+        }
     }
-     else if (m_action == actionClickCaption)
+    else if (m_action == actionClickCaption)
     {
         int drag_x_threshold = wxSystemSettings::GetMetric(wxSYS_DRAG_X);
         int drag_y_threshold = wxSystemSettings::GetMetric(wxSYS_DRAG_Y);
astigsen
Registered User
 
Posts: 8
Joined: Thu Jan 26, 2006 9:06 am

Resizing what?

Postby abligh on Thu Jan 26, 2006 2:52 pm

Hi,

[deleted some idiocy of my own - I see you mean resizing docked panes and dragging sashes, as opposed to resizing floating panes or the main window]

Is the unified diff available on http:// or ftp:// somewhere? All the line feeds and whitespace are broken if I screen-scrape it from this system - else I'd just have tried it :-)

Alex
abligh
Registered User
 
Posts: 59
Joined: Sun Jan 01, 2006 2:31 pm

Return to wxAUI Patches & Modifications