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);