#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"
#include "wx/dcclient.h"
#include "wx/dcscreen.h"
#include "wx/toolbar.h"
- #include "wx/mdi.h"
#include "wx/image.h"
+ #include "wx/statusbr.h"
#endif
WX_CHECK_BUILD_OPTIONS("wxAUI")
wxAuiPaneInfo wxAuiNullPaneInfo;
wxAuiDockInfo wxAuiNullDockInfo;
-DEFINE_EVENT_TYPE(wxEVT_AUI_PANE_BUTTON)
-DEFINE_EVENT_TYPE(wxEVT_AUI_PANE_CLOSE)
-DEFINE_EVENT_TYPE(wxEVT_AUI_PANE_MAXIMIZE)
-DEFINE_EVENT_TYPE(wxEVT_AUI_PANE_RESTORE)
-DEFINE_EVENT_TYPE(wxEVT_AUI_RENDER)
-DEFINE_EVENT_TYPE(wxEVT_AUI_FIND_MANAGER)
+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
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)
};
}
+
+
+// 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 --
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()
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;
// 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;
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();
// first, give the owner frame a chance to override
if (m_frame)
{
- if (m_frame->ProcessEvent(event))
+ if (m_frame->GetEventHandler()->ProcessEvent(event))
return;
}
{
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();
-
- // 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)
{
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();
// value that the pane will receive
int pane_proportion = pane.dock_proportion;
- wxBoxSizer* horz_pane_sizer = new wxBoxSizer(wxHORIZONTAL);
- wxBoxSizer* vert_pane_sizer = new wxBoxSizer(wxVERTICAL);
+ wxAuiProportionalBoxSizer* horz_pane_sizer = new wxAuiProportionalBoxSizer(wxHORIZONTAL);
+ wxAuiProportionalBoxSizer* vert_pane_sizer = new wxAuiProportionalBoxSizer(wxVERTICAL);
if (pane.HasGripper())
{
if (pane.HasCaption())
{
// create the caption sizer
- wxBoxSizer* caption_sizer = new wxBoxSizer(wxHORIZONTAL);
+ wxAuiProportionalBoxSizer* caption_sizer = new wxAuiProportionalBoxSizer(wxHORIZONTAL);
sizer_item = caption_sizer->Add(1, caption_size, 1, wxEXPAND);
}
// 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;
wxAuiDockUIPartArray& uiparts,
bool spacer_only)
{
- wxBoxSizer* container = new wxBoxSizer(wxVERTICAL);
+ wxAuiProportionalBoxSizer* container = new wxAuiProportionalBoxSizer(wxVERTICAL);
int pane_border_size = m_art->GetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE);
int caption_size = m_art->GetMetric(wxAUI_DOCKART_CAPTION_SIZE);
// create a container which will hold this layer's
// docks (top, bottom, left, right)
- cont = new wxBoxSizer(wxVERTICAL);
+ cont = new wxAuiProportionalBoxSizer(wxVERTICAL);
// find any top docks in this layer
// fill out the middle layer (which consists
// of left docks, content area and right docks)
- middle = new wxBoxSizer(wxHORIZONTAL);
+ middle = new wxAuiProportionalBoxSizer(wxHORIZONTAL);
// find any left docks in this layer
FindDocks(docks, wxAUI_DOCK_LEFT, layer, -1, arr);
{
// no sizer available, because there are no docks,
// therefore we will create a simple background area
- cont = new wxBoxSizer(wxVERTICAL);
+ cont = new wxAuiProportionalBoxSizer(wxVERTICAL);
wxSizerItem* sizer_item = cont->Add(1,1, 1, wxEXPAND);
wxAuiDockUIPart part;
part.type = wxAuiDockUIPart::typeBackground;
// 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 ))
{
}
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;
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;
}
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);
+ Connect(m_hint_fadetimer.GetId(), wxEVT_TIMER,
+ wxTimerEventHandler(wxAuiManager::OnHintFadeTimer));
}
}
else // Not using a transparent hint window...
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;
}
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);
}
wxAuiPaneInfo& pane = GetPane(wnd);
wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
+ if(!pane.frame)
+ return;
+
wxPoint pt = ::wxGetMousePosition();
#if 0
wxAuiPaneInfo& pane = GetPane(wnd);
wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
+ if(!pane.frame)
+ return;
+
wxPoint pt = ::wxGetMousePosition();
#if 0
// 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);
+ int new_size, old_size = m_action_part->dock->size;
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:
- 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:
- 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:
- m_action_part->dock->size = rect.y + rect.height -
+ new_size = rect.y + rect.height -
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;
}
}
}
+ // 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
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);
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;
+ }
}
}
}