X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/50acee04cdaf2fec9f3fa4cd0035ff2d9ed7d53a..7ac21a67618fd116d17d39a936380b3689972ee3:/src/aui/framemanager.cpp diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index 609be6a75b..e1b0ee6797 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -1,10 +1,10 @@ /////////////////////////////////////////////////////////////////////////////// -// Name: framemanager.cpp +// Name: src/aui/framemanager.cpp // Purpose: wxaui: wx advanced user interface - docking window manager // Author: Benjamin I. Williams // Modified by: // Created: 2005-05-17 -// RCS-ID: +// RCS-ID: $Id$ // Copyright: (C) Copyright 2005-2006, Kirix Corporation, All Rights Reserved // Licence: wxWindows Library Licence, Version 3.1 /////////////////////////////////////////////////////////////////////////////// @@ -30,26 +30,33 @@ #include "wx/aui/floatpane.h" #ifndef WX_PRECOMP -// #include "wx/log.h" + #include "wx/panel.h" + #include "wx/settings.h" + #include "wx/app.h" + #include "wx/dcclient.h" + #include "wx/dcscreen.h" + #include "wx/toolbar.h" + #include "wx/mdi.h" + #include "wx/image.h" #endif -//#include "wx/dcbuffer.h" - -#include "wx/app.h" -#include "wx/image.h" WX_CHECK_BUILD_OPTIONS("wxAUI") #include "wx/arrimpl.cpp" WX_DECLARE_OBJARRAY(wxRect, wxAuiRectArray); WX_DEFINE_OBJARRAY(wxAuiRectArray) -WX_DEFINE_OBJARRAY(wxDockUIPartArray) -WX_DEFINE_OBJARRAY(wxDockInfoArray) -WX_DEFINE_OBJARRAY(wxPaneButtonArray) -WX_DEFINE_OBJARRAY(wxPaneInfoArray) +WX_DEFINE_OBJARRAY(wxAuiDockUIPartArray) +WX_DEFINE_OBJARRAY(wxAuiDockInfoArray) +WX_DEFINE_OBJARRAY(wxAuiPaneButtonArray) +WX_DEFINE_OBJARRAY(wxAuiPaneInfoArray) -wxPaneInfo wxNullPaneInfo; -wxDockInfo wxNullDockInfo; +wxAuiPaneInfo wxAuiNullPaneInfo; +wxAuiDockInfo wxAuiNullDockInfo; DEFINE_EVENT_TYPE(wxEVT_AUI_PANEBUTTON) +DEFINE_EVENT_TYPE(wxEVT_AUI_PANECLOSE) +DEFINE_EVENT_TYPE(wxEVT_AUI_PANEMAXIMIZE) +DEFINE_EVENT_TYPE(wxEVT_AUI_PANERESTORE) +DEFINE_EVENT_TYPE(wxEVT_AUI_RENDER) #ifdef __WXMAC__ // a few defines to avoid nameclashes @@ -58,6 +65,141 @@ DEFINE_EVENT_TYPE(wxEVT_AUI_PANEBUTTON) #include "wx/mac/private.h" #endif +IMPLEMENT_DYNAMIC_CLASS(wxAuiManagerEvent, wxEvent) + +class wxPseudoTransparentFrame : public wxFrame +{ +public: + wxPseudoTransparentFrame(wxWindow* parent = NULL, + wxWindowID id = wxID_ANY, + const wxString& title = wxEmptyString, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxDEFAULT_FRAME_STYLE, + const wxString &name = wxT("frame")) + : wxFrame(parent, id, title, pos, size, style | wxFRAME_SHAPED, name) + { + SetBackgroundStyle(wxBG_STYLE_CUSTOM); + m_Amount=0; + m_MaxWidth=0; + m_MaxHeight=0; + m_lastWidth=0; + m_lastHeight=0; +#ifdef __WXGTK__ + m_CanSetShape = false; // have to wait for window create event on GTK +#else + m_CanSetShape = true; +#endif + m_Region = wxRegion(0, 0, 0, 0); + SetTransparent(0); + } + + virtual bool SetTransparent(wxByte alpha) + { + if (m_CanSetShape) + { + int w=100; // some defaults + int h=100; + GetClientSize(&w, &h); + + m_MaxWidth = w; + m_MaxHeight = h; + m_Amount = alpha; + m_Region.Clear(); +// m_Region.Union(0, 0, 1, m_MaxWidth); + if (m_Amount) + { + for (int y=0; yGetHWND(); - - if (!h) - h = LoadLibrary(_T("user32")); - - if (!pSetLayeredWindowAttributes) - { - pSetLayeredWindowAttributes = - (PSETLAYEREDWINDOWATTR)GetProcAddress(h,"SetLayeredWindowAttributes"); - } - - if (pSetLayeredWindowAttributes == NULL) - return; - - LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); - if (0 == (exstyle & 0x80000) /*WS_EX_LAYERED*/) - SetWindowLong(hwnd, GWL_EXSTYLE, exstyle | 0x80000 /*WS_EX_LAYERED*/); - - pSetLayeredWindowAttributes(hwnd, 0, amount, 2 /*LWA_ALPHA*/); -} - -#endif // CopyDocksAndPanes() - this utility function creates copies of -// the dock and pane info. wxDockInfo's usually contain pointers -// to wxPaneInfo classes, thus this function is necessary to reliably +// the dock and pane info. wxAuiDockInfo's usually contain pointers +// to wxAuiPaneInfo classes, thus this function is necessary to reliably // reconstruct that relationship in the new dock info and pane info arrays -static void CopyDocksAndPanes(wxDockInfoArray& dest_docks, - wxPaneInfoArray& dest_panes, - const wxDockInfoArray& src_docks, - const wxPaneInfoArray& src_panes) +static void CopyDocksAndPanes(wxAuiDockInfoArray& dest_docks, + wxAuiPaneInfoArray& dest_panes, + const wxAuiDockInfoArray& src_docks, + const wxAuiPaneInfoArray& src_panes) { dest_docks = src_docks; dest_panes = src_panes; int i, j, k, dock_count, pc1, pc2; for (i = 0, dock_count = dest_docks.GetCount(); i < dock_count; ++i) { - wxDockInfo& dock = dest_docks.Item(i); + wxAuiDockInfo& dock = dest_docks.Item(i); for (j = 0, pc1 = dock.panes.GetCount(); j < pc1; ++j) for (k = 0, pc2 = src_panes.GetCount(); k < pc2; ++k) if (dock.panes.Item(j) == &src_panes.Item(k)) @@ -139,12 +248,12 @@ static void CopyDocksAndPanes(wxDockInfoArray& dest_docks, // GetMaxLayer() is an internal function which returns // the highest layer inside the specified dock -static int GetMaxLayer(const wxDockInfoArray& docks, int dock_direction) +static int GetMaxLayer(const wxAuiDockInfoArray& docks, int dock_direction) { int i, dock_count, max_layer = 0; for (i = 0, dock_count = docks.GetCount(); i < dock_count; ++i) { - wxDockInfo& dock = docks.Item(i); + wxAuiDockInfo& dock = docks.Item(i); if (dock.dock_direction == dock_direction && dock.dock_layer > max_layer && !dock.fixed) max_layer = dock.dock_layer; @@ -155,14 +264,14 @@ static int GetMaxLayer(const wxDockInfoArray& docks, int dock_direction) // GetMaxRow() is an internal function which returns // the highest layer inside the specified dock -static int GetMaxRow(const wxPaneInfoArray& panes, int direction, int layer) +static int GetMaxRow(const wxAuiPaneInfoArray& panes, int direction, int layer) { int i, pane_count, max_row = 0; for (i = 0, pane_count = panes.GetCount(); i < pane_count; ++i) { - wxPaneInfo& pane = panes.Item(i); + wxAuiPaneInfo& pane = panes.Item(i); if (pane.dock_direction == direction && - pane.dock_layer == layer && + pane.dock_layer == layer && pane.dock_row > max_row) max_row = pane.dock_row; } @@ -173,14 +282,14 @@ static int GetMaxRow(const wxPaneInfoArray& panes, int direction, int layer) // DoInsertDockLayer() is an internal function that inserts a new dock // layer by incrementing all existing dock layer values by one -static void DoInsertDockLayer(wxPaneInfoArray& panes, +static void DoInsertDockLayer(wxAuiPaneInfoArray& panes, int dock_direction, int dock_layer) { int i, pane_count; for (i = 0, pane_count = panes.GetCount(); i < pane_count; ++i) { - wxPaneInfo& pane = panes.Item(i); + wxAuiPaneInfo& pane = panes.Item(i); if (!pane.IsFloating() && pane.dock_direction == dock_direction && pane.dock_layer >= dock_layer) @@ -190,7 +299,7 @@ static void DoInsertDockLayer(wxPaneInfoArray& panes, // DoInsertDockLayer() is an internal function that inserts a new dock // row by incrementing all existing dock row values by one -static void DoInsertDockRow(wxPaneInfoArray& panes, +static void DoInsertDockRow(wxAuiPaneInfoArray& panes, int dock_direction, int dock_layer, int dock_row) @@ -198,7 +307,7 @@ static void DoInsertDockRow(wxPaneInfoArray& panes, int i, pane_count; for (i = 0, pane_count = panes.GetCount(); i < pane_count; ++i) { - wxPaneInfo& pane = panes.Item(i); + wxAuiPaneInfo& pane = panes.Item(i); if (!pane.IsFloating() && pane.dock_direction == dock_direction && pane.dock_layer == dock_layer && @@ -207,9 +316,9 @@ static void DoInsertDockRow(wxPaneInfoArray& panes, } } -// DoInsertDockLayer() is an internal function that inserts a space for +// DoInsertDockLayer() is an internal function that inserts a space for // another dock pane by incrementing all existing dock row values by one -static void DoInsertPane(wxPaneInfoArray& panes, +static void DoInsertPane(wxAuiPaneInfoArray& panes, int dock_direction, int dock_layer, int dock_row, @@ -218,7 +327,7 @@ static void DoInsertPane(wxPaneInfoArray& panes, int i, pane_count; for (i = 0, pane_count = panes.GetCount(); i < pane_count; ++i) { - wxPaneInfo& pane = panes.Item(i); + wxAuiPaneInfo& pane = panes.Item(i); if (!pane.IsFloating() && pane.dock_direction == dock_direction && pane.dock_layer == dock_layer && @@ -231,11 +340,11 @@ static void DoInsertPane(wxPaneInfoArray& panes, // FindDocks() is an internal function that returns a list of docks which meet // the specified conditions in the parameters and returns a sorted array // (sorted by layer and then row) -static void FindDocks(wxDockInfoArray& docks, +static void FindDocks(wxAuiDockInfoArray& docks, int dock_direction, int dock_layer, int dock_row, - wxDockInfoPtrArray& arr) + wxAuiDockInfoPtrArray& arr) { int begin_layer = dock_layer; int end_layer = dock_layer; @@ -250,14 +359,14 @@ static void FindDocks(wxDockInfoArray& docks, max_row = wxMax(max_row, docks.Item(i).dock_row); max_layer = wxMax(max_layer, docks.Item(i).dock_layer); } - + // if no dock layer was specified, search all dock layers if (dock_layer == -1) { begin_layer = 0; end_layer = max_layer; } - + // if no dock row was specified, search all dock row if (dock_row == -1) { @@ -271,7 +380,7 @@ static void FindDocks(wxDockInfoArray& docks, for (row = begin_row; row <= end_row; ++row) for (i = 0; i < dock_count; ++i) { - wxDockInfo& d = docks.Item(i); + wxAuiDockInfo& d = docks.Item(i); if (dock_direction == -1 || dock_direction == d.dock_direction) { if (d.dock_layer == layer && d.dock_row == row) @@ -281,13 +390,13 @@ static void FindDocks(wxDockInfoArray& docks, } // FindPaneInDock() looks up a specified window pointer inside a dock. -// If found, the corresponding wxPaneInfo pointer is returned, otherwise NULL. -static wxPaneInfo* FindPaneInDock(const wxDockInfo& dock, wxWindow* window) +// If found, the corresponding wxAuiPaneInfo pointer is returned, otherwise NULL. +static wxAuiPaneInfo* FindPaneInDock(const wxAuiDockInfo& dock, wxWindow* window) { int i, count = dock.panes.GetCount(); for (i = 0; i < count; ++i) { - wxPaneInfo* p = dock.panes.Item(i); + wxAuiPaneInfo* p = dock.panes.Item(i); if (p->window == window) return p; } @@ -295,18 +404,18 @@ static wxPaneInfo* FindPaneInDock(const wxDockInfo& dock, wxWindow* window) } // RemovePaneFromDocks() removes a pane window from all docks -// with a possible exception specified by parameter "except" -static void RemovePaneFromDocks(wxDockInfoArray& docks, - wxPaneInfo& pane, - wxDockInfo* except = NULL) +// with a possible exception specified by parameter "ex_cept" +static void RemovePaneFromDocks(wxAuiDockInfoArray& docks, + wxAuiPaneInfo& pane, + wxAuiDockInfo* ex_cept = NULL ) { int i, dock_count; for (i = 0, dock_count = docks.GetCount(); i < dock_count; ++i) { - wxDockInfo& d = docks.Item(i); - if (&d == except) + wxAuiDockInfo& d = docks.Item(i); + if (&d == ex_cept) continue; - wxPaneInfo* pi = FindPaneInDock(d, pane.window); + wxAuiPaneInfo* pi = FindPaneInDock(d, pane.window); if (pi) d.panes.Remove(pi); } @@ -315,12 +424,12 @@ static void RemovePaneFromDocks(wxDockInfoArray& docks, // RenumberDockRows() takes a dock and assigns sequential numbers // to existing rows. Basically it takes out the gaps; so if a // dock has rows with numbers 0,2,5, they will become 0,1,2 -static void RenumberDockRows(wxDockInfoPtrArray& docks) +static void RenumberDockRows(wxAuiDockInfoPtrArray& docks) { int i, dock_count, j, pane_count; for (i = 0, dock_count = docks.GetCount(); i < dock_count; ++i) { - wxDockInfo& dock = *docks.Item(i); + wxAuiDockInfo& dock = *docks.Item(i); dock.dock_row = i; for (j = 0, pane_count = dock.panes.GetCount(); j < pane_count; ++j) dock.panes.Item(j)->dock_row = i; @@ -328,102 +437,114 @@ static void RenumberDockRows(wxDockInfoPtrArray& docks) } - -static void SetActivePane(wxPaneInfoArray& panes, wxWindow* active_pane) +// SetActivePane() sets the active pane, as well as cycles through +// every other pane and makes sure that all others' active flags +// are turned off +static void SetActivePane(wxAuiPaneInfoArray& panes, wxWindow* active_pane) { int i, pane_count; for (i = 0, pane_count = panes.GetCount(); i < pane_count; ++i) { - wxPaneInfo& pane = panes.Item(i); - pane.state &= ~wxPaneInfo::optionActive; + wxAuiPaneInfo& pane = panes.Item(i); + pane.state &= ~wxAuiPaneInfo::optionActive; if (pane.window == active_pane) - pane.state |= wxPaneInfo::optionActive; + pane.state |= wxAuiPaneInfo::optionActive; } } // this function is used to sort panes by dock position -static int PaneSortFunc(wxPaneInfo** p1, wxPaneInfo** p2) +static int PaneSortFunc(wxAuiPaneInfo** p1, wxAuiPaneInfo** p2) { return ((*p1)->dock_pos < (*p2)->dock_pos) ? -1 : 1; } -// -- wxFrameManager class implementation -- +// -- wxAuiManager class implementation -- -BEGIN_EVENT_TABLE(wxFrameManager, wxEvtHandler) - EVT_AUI_PANEBUTTON(wxFrameManager::OnPaneButton) - EVT_PAINT(wxFrameManager::OnPaint) - EVT_ERASE_BACKGROUND(wxFrameManager::OnEraseBackground) - EVT_SIZE(wxFrameManager::OnSize) - EVT_SET_CURSOR(wxFrameManager::OnSetCursor) - EVT_LEFT_DOWN(wxFrameManager::OnLeftDown) - EVT_LEFT_UP(wxFrameManager::OnLeftUp) - EVT_MOTION(wxFrameManager::OnMotion) - EVT_LEAVE_WINDOW(wxFrameManager::OnLeaveWindow) - EVT_CHILD_FOCUS(wxFrameManager::OnChildFocus) - EVT_TIMER(101, wxFrameManager::OnHintFadeTimer) +BEGIN_EVENT_TABLE(wxAuiManager, wxEvtHandler) + EVT_AUI_PANEBUTTON(wxAuiManager::OnPaneButton) + EVT_AUI_RENDER(wxAuiManager::OnRender) + EVT_PAINT(wxAuiManager::OnPaint) + EVT_ERASE_BACKGROUND(wxAuiManager::OnEraseBackground) + EVT_SIZE(wxAuiManager::OnSize) + EVT_SET_CURSOR(wxAuiManager::OnSetCursor) + EVT_LEFT_DOWN(wxAuiManager::OnLeftDown) + EVT_LEFT_UP(wxAuiManager::OnLeftUp) + EVT_MOTION(wxAuiManager::OnMotion) + EVT_LEAVE_WINDOW(wxAuiManager::OnLeaveWindow) + EVT_CHILD_FOCUS(wxAuiManager::OnChildFocus) + EVT_TIMER(101, wxAuiManager::OnHintFadeTimer) END_EVENT_TABLE() -wxFrameManager::wxFrameManager(wxFrame* frame, unsigned int flags) +wxAuiManager::wxAuiManager(wxWindow* managed_wnd, unsigned int flags) { m_action = actionNone; m_last_mouse_move = wxPoint(); m_hover_button = NULL; - m_art = new wxDefaultDockArt; + m_art = new wxAuiDefaultDockArt; m_hint_wnd = NULL; m_flags = flags; - - if (frame) + m_skipping = false; + m_has_maximized = false; + m_frame = NULL; + + if (managed_wnd) { - SetFrame(frame); + SetManagedWindow(managed_wnd); } } -wxFrameManager::~wxFrameManager() +wxAuiManager::~wxAuiManager() { delete m_art; } -// GetPane() looks up a wxPaneInfo structure based +// Creates a floating frame for the windows +wxAuiFloatingFrame * wxAuiManager::CreateFloatingFrame(wxWindow* parent, const wxAuiPaneInfo& p) +{ + return new wxAuiFloatingFrame(parent, this, p); +} + +// GetPane() looks up a wxAuiPaneInfo structure based // on the supplied window pointer. Upon failure, GetPane() -// returns an empty wxPaneInfo, a condition which can be checked -// by calling wxPaneInfo::IsOk(). +// returns an empty wxAuiPaneInfo, a condition which can be checked +// by calling wxAuiPaneInfo::IsOk(). // // The pane info's structure may then be modified. Once a pane's -// info is modified, wxFrameManager::Update() must be called to +// info is modified, wxAuiManager::Update() must be called to // realize the changes in the UI. -wxPaneInfo& wxFrameManager::GetPane(wxWindow* window) +wxAuiPaneInfo& wxAuiManager::GetPane(wxWindow* window) { int i, pane_count; for (i = 0, pane_count = m_panes.GetCount(); i < pane_count; ++i) { - wxPaneInfo& p = m_panes.Item(i); + wxAuiPaneInfo& p = m_panes.Item(i); if (p.window == window) return p; } - return wxNullPaneInfo; + return wxAuiNullPaneInfo; } // this version of GetPane() looks up a pane based on a // 'pane name', see above comment for more info -wxPaneInfo& wxFrameManager::GetPane(const wxString& name) +wxAuiPaneInfo& wxAuiManager::GetPane(const wxString& name) { int i, pane_count; for (i = 0, pane_count = m_panes.GetCount(); i < pane_count; ++i) { - wxPaneInfo& p = m_panes.Item(i); + wxAuiPaneInfo& p = m_panes.Item(i); if (p.name == name) return p; } - return wxNullPaneInfo; + return wxAuiNullPaneInfo; } // GetAllPanes() returns a reference to all the pane info structures -wxPaneInfoArray& wxFrameManager::GetAllPanes() +wxAuiPaneInfoArray& wxAuiManager::GetAllPanes() { return m_panes; } @@ -431,59 +552,170 @@ wxPaneInfoArray& wxFrameManager::GetAllPanes() // HitTest() is an internal function which determines // which UI item the specified coordinates are over // (x,y) specify a position in client coordinates -wxDockUIPart* wxFrameManager::HitTest(int x, int y) +wxAuiDockUIPart* wxAuiManager::HitTest(int x, int y) { - wxDockUIPart* result = NULL; + wxAuiDockUIPart* result = NULL; int i, part_count; for (i = 0, part_count = m_uiparts.GetCount(); i < part_count; ++i) { - wxDockUIPart* item = &m_uiparts.Item(i); - - // we are not interested in typeDock, because this space + wxAuiDockUIPart* item = &m_uiparts.Item(i); + + // we are not interested in typeDock, because this space // isn't used to draw anything, just for measurements; // besides, the entire dock area is covered with other // rectangles, which we are interested in. - if (item->type == wxDockUIPart::typeDock) + if (item->type == wxAuiDockUIPart::typeDock) continue; - + // if we already have a hit on a more specific item, we are not // interested in a pane hit. If, however, we don't already have // a hit, returning a pane hit is necessary for some operations - if ((item->type == wxDockUIPart::typePane || - item->type == wxDockUIPart::typePaneBorder) && result) + if ((item->type == wxAuiDockUIPart::typePane || + item->type == wxAuiDockUIPart::typePaneBorder) && result) continue; - + // if the point is inside the rectangle, we have a hit - if (item->rect.Inside(x,y)) + if (item->rect.Contains(x,y)) result = item; } - + return result; } // SetFlags() and GetFlags() allow the owner to set various -// options which are global to wxFrameManager -void wxFrameManager::SetFlags(unsigned int flags) +// options which are global to wxAuiManager +void wxAuiManager::SetFlags(unsigned int flags) { + // find out if we have to call UpdateHintWindowConfig() + bool update_hint_wnd = false; + unsigned int hint_mask = wxAUI_MGR_TRANSPARENT_HINT | + wxAUI_MGR_VENETIAN_BLINDS_HINT | + wxAUI_MGR_RECTANGLE_HINT; + if ((flags & hint_mask) != (m_flags & hint_mask)) + update_hint_wnd = true; + + + // set the new flags m_flags = flags; + + if (update_hint_wnd) + { + UpdateHintWindowConfig(); + } } -unsigned int wxFrameManager::GetFlags() const +unsigned int wxAuiManager::GetFlags() const { return m_flags; } -// SetFrame() is usually called once when the frame +// don't use these anymore as they are deprecated +// use Set/GetManagedFrame() instead +void wxAuiManager::SetFrame(wxFrame* frame) +{ + SetManagedWindow((wxWindow*)frame); +} + +wxFrame* wxAuiManager::GetFrame() const +{ + return (wxFrame*)m_frame; +} + + +void wxAuiManager::UpdateHintWindowConfig() +{ + // find out if the the system can do transparent frames + bool can_do_transparent = false; + + wxWindow* w = m_frame; + while (w) + { + if (w->IsKindOf(CLASSINFO(wxFrame))) + { + wxFrame* f = static_cast(w); + #if wxCHECK_VERSION(2,7,0) + can_do_transparent = f->CanSetTransparent(); + #endif + break; + } + + w = w->GetParent(); + } + + // if there is an existing hint window, delete it + if (m_hint_wnd) + { + m_hint_wnd->Destroy(); + m_hint_wnd = NULL; + } + + m_hint_fademax = 50; + m_hint_wnd = NULL; + + if ((m_flags & wxAUI_MGR_TRANSPARENT_HINT) && can_do_transparent) + { + // Make a window to use for a transparent hint + #if defined(__WXMSW__) || defined(__WXGTK__) + m_hint_wnd = new wxFrame(m_frame, wxID_ANY, wxEmptyString, + wxDefaultPosition, wxSize(1,1), + wxFRAME_TOOL_WINDOW | + wxFRAME_FLOAT_ON_PARENT | + wxFRAME_NO_TASKBAR | + wxNO_BORDER); + + m_hint_wnd->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION)); + #elif defined(__WXMAC__) + // Using a miniframe with float and tool styles keeps the parent + // frame activated and highlighted as such... + m_hint_wnd = new wxMiniFrame(m_frame, wxID_ANY, wxEmptyString, + wxDefaultPosition, wxSize(1,1), + wxFRAME_FLOAT_ON_PARENT + | wxFRAME_TOOL_WINDOW ); + + // Can't set the bg colour of a Frame in wxMac + wxPanel* p = new wxPanel(m_hint_wnd); + + // The default wxSYS_COLOUR_ACTIVECAPTION colour is a light silver + // color that is really hard to see, especially transparent. + // Until a better system color is decided upon we'll just use + // blue. + p->SetBackgroundColour(*wxBLUE); + #endif + + } + else + { + if ((m_flags & wxAUI_MGR_TRANSPARENT_HINT) != 0 || + (m_flags & wxAUI_MGR_VENETIAN_BLINDS_HINT) != 0) + { + // system can't support transparent fade, or the venetian + // blinds effect was explicitly requested + m_hint_wnd = new wxPseudoTransparentFrame(m_frame, + wxID_ANY, + wxEmptyString, + wxDefaultPosition, + wxSize(1,1), + wxFRAME_TOOL_WINDOW | + wxFRAME_FLOAT_ON_PARENT | + wxFRAME_NO_TASKBAR | + wxNO_BORDER); + m_hint_fademax = 128; + } + } +} + + +// SetManagedWindow() is usually called once when the frame // manager class is being initialized. "frame" specifies // the frame which should be managed by the frame mananger -void wxFrameManager::SetFrame(wxFrame* frame) +void wxAuiManager::SetManagedWindow(wxWindow* wnd) { - wxASSERT_MSG(frame, wxT("specified frame must be non-NULL")); + wxASSERT_MSG(wnd, wxT("specified window must be non-NULL")); - m_frame = frame; + m_frame = wnd; m_frame->PushEventHandler(this); #if wxUSE_MDI @@ -491,41 +723,46 @@ void wxFrameManager::SetFrame(wxFrame* frame) // we need to add the MDI client window as the default // center pane - if (frame->IsKindOf(CLASSINFO(wxMDIParentFrame))) + if (m_frame->IsKindOf(CLASSINFO(wxMDIParentFrame))) { - wxMDIParentFrame* mdi_frame = (wxMDIParentFrame*)frame; - wxMDIClientWindow* client_window = mdi_frame->GetClientWindow(); + wxMDIParentFrame* mdi_frame = (wxMDIParentFrame*)m_frame; + wxWindow* client_window = mdi_frame->GetClientWindow(); wxASSERT_MSG(client_window, wxT("Client window is NULL!")); AddPane(client_window, - wxPaneInfo().Name(wxT("mdiclient")). + wxAuiPaneInfo().Name(wxT("mdiclient")). CenterPane().PaneBorder(false)); } #endif + + UpdateHintWindowConfig(); } // UnInit() must be called, usually in the destructor // of the frame class. If it is not called, usually this // will result in a crash upon program exit -void wxFrameManager::UnInit() +void wxAuiManager::UnInit() { - m_frame->RemoveEventHandler(this); + if (m_frame) + { + m_frame->RemoveEventHandler(this); + } } -// GetFrame() returns the frame pointer being managed by wxFrameManager -wxFrame* wxFrameManager::GetFrame() const +// GetManagedWindow() returns the window pointer being managed +wxWindow* wxAuiManager::GetManagedWindow() const { return m_frame; } -wxDockArt* wxFrameManager::GetArtProvider() const +wxAuiDockArt* wxAuiManager::GetArtProvider() const { return m_art; } -void wxFrameManager::ProcessMgrEvent(wxFrameManagerEvent& event) +void wxAuiManager::ProcessMgrEvent(wxAuiManagerEvent& event) { // first, give the owner frame a chance to override if (m_frame) @@ -537,19 +774,22 @@ void wxFrameManager::ProcessMgrEvent(wxFrameManagerEvent& event) ProcessEvent(event); } -// SetArtProvider() instructs wxFrameManager to use the +// SetArtProvider() instructs wxAuiManager to use the // specified art provider for all drawing calls. This allows -// plugable look-and-feel features -void wxFrameManager::SetArtProvider(wxDockArt* art_provider) +// plugable look-and-feel features. The pointer that is +// passed to this method subsequently belongs to wxAuiManager, +// and is deleted in the frame manager destructor +void wxAuiManager::SetArtProvider(wxAuiDockArt* art_provider) { // delete the last art provider, if any delete m_art; - + // assign the new art provider m_art = art_provider; } -bool wxFrameManager::AddPane(wxWindow* window, const wxPaneInfo& pane_info) + +bool wxAuiManager::AddPane(wxWindow* window, const wxAuiPaneInfo& pane_info) { // check if the pane has a valid window if (!window) @@ -559,34 +799,49 @@ bool wxFrameManager::AddPane(wxWindow* window, const wxPaneInfo& pane_info) if (GetPane(pane_info.window).IsOk()) return false; + // if the new pane is docked then we should undo maximize + if(pane_info.IsDocked()) + RestoreMaximizedPane(); + m_panes.Add(pane_info); - wxPaneInfo& pinfo = m_panes.Last(); + wxAuiPaneInfo& pinfo = m_panes.Last(); // set the pane window pinfo.window = window; - + // if the pane's name identifier is blank, create a random string - if (pinfo.name.IsEmpty()) + if (pinfo.name.empty()) { - pinfo.name.Printf(wxT("%08x%08x%08x%08x"), + pinfo.name.Printf(wxT("%08lx%08x%08x%08lx"), ((unsigned long)pinfo.window) & 0xffffffff, (unsigned int)time(NULL), - (unsigned int)clock(), m_panes.GetCount()); +#ifdef __WXWINCE__ + (unsigned int)GetTickCount(), +#else + (unsigned int)clock(), +#endif + (unsigned long)m_panes.GetCount()); } - + // set initial proportion (if not already set) if (pinfo.dock_proportion == 0) pinfo.dock_proportion = 100000; - if (pinfo.HasCloseButton() && - pinfo.buttons.size() == 0) + if (pinfo.HasMaximizeButton()) { - wxPaneButton button; - button.button_id = wxPaneInfo::buttonClose; + wxAuiPaneButton button; + button.button_id = wxAUI_BUTTON_MAXIMIZE_RESTORE; pinfo.buttons.Add(button); } - + + if (pinfo.HasCloseButton()) + { + wxAuiPaneButton button; + button.button_id = wxAUI_BUTTON_CLOSE; + pinfo.buttons.Add(button); + } + if (pinfo.best_size == wxDefaultSize && pinfo.window) { @@ -598,7 +853,7 @@ bool wxFrameManager::AddPane(wxWindow* window, const wxPaneInfo& pane_info) // 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 @@ -606,7 +861,7 @@ bool wxFrameManager::AddPane(wxWindow* window, const wxPaneInfo& pane_info) // correct? pinfo.best_size.y++; } - + if (pinfo.min_size != wxDefaultSize) { if (pinfo.best_size.x < pinfo.min_size.x) @@ -619,11 +874,11 @@ bool wxFrameManager::AddPane(wxWindow* window, const wxPaneInfo& pane_info) return true; } -bool wxFrameManager::AddPane(wxWindow* window, +bool wxAuiManager::AddPane(wxWindow* window, int direction, const wxString& caption) { - wxPaneInfo pinfo; + wxAuiPaneInfo pinfo; pinfo.Caption(caption); switch (direction) { @@ -636,7 +891,21 @@ bool wxFrameManager::AddPane(wxWindow* window, return AddPane(window, pinfo); } -bool wxFrameManager::InsertPane(wxWindow* window, const wxPaneInfo& pane_info, +bool wxAuiManager::AddPane(wxWindow* window, + const wxAuiPaneInfo& pane_info, + const wxPoint& drop_pos) +{ + if (!AddPane(window, pane_info)) + return false; + + wxAuiPaneInfo& pane = GetPane(window); + + DoDrop(m_docks, m_panes, pane, drop_pos, wxPoint(0,0)); + + return true; +} + +bool wxAuiManager::InsertPane(wxWindow* window, const wxAuiPaneInfo& pane_info, int insert_level) { // shift the panes around, depending on the insert level @@ -661,10 +930,10 @@ bool wxFrameManager::InsertPane(wxWindow* window, const wxPaneInfo& pane_info, pane_info.dock_layer); break; } - + // if the window already exists, we are basically just moving/inserting the // existing window. If it doesn't exist, we need to add it and insert it - wxPaneInfo& existing_pane = GetPane(window); + wxAuiPaneInfo& existing_pane = GetPane(window); if (!existing_pane.IsOk()) { return AddPane(window, pane_info); @@ -681,6 +950,9 @@ bool wxFrameManager::InsertPane(wxWindow* window, const wxPaneInfo& pane_info, } else { + // if the new pane is docked then we should undo maximize + RestoreMaximizedPane(); + existing_pane.Direction(pane_info.dock_direction); existing_pane.Layer(pane_info.dock_layer); existing_pane.Row(pane_info.dock_row); @@ -691,13 +963,15 @@ bool wxFrameManager::InsertPane(wxWindow* window, const wxPaneInfo& pane_info, return true; } - -bool wxFrameManager::DetachPane(wxWindow* window) + +// DetachPane() removes a pane from the frame manager. This +// method will not destroy the window that is removed. +bool wxAuiManager::DetachPane(wxWindow* window) { int i, count; for (i = 0, count = m_panes.GetCount(); i < count; ++i) { - wxPaneInfo& p = m_panes.Item(i); + wxAuiPaneInfo& p = m_panes.Item(i); if (p.window == window) { if (p.frame) @@ -707,14 +981,37 @@ bool wxFrameManager::DetachPane(wxWindow* window) // reduce flicker p.window->SetSize(1,1); - p.frame->Show(false); + + if (p.frame->IsShown()) + p.frame->Show(false); // reparent to m_frame and destroy the pane + if(m_action_window == p.frame) { + m_action_window = NULL; + } p.window->Reparent(m_frame); p.frame->SetSizer(NULL); p.frame->Destroy(); p.frame = NULL; } + + // make sure there are no references to this pane in our uiparts, + // just in case the caller doesn't call Update() immediately after + // the DetachPane() call. This prevets obscure crashes which would + // happen at window repaint if the caller forgets to call Update() + int pi, part_count; + for (pi = 0, part_count = (int)m_uiparts.GetCount(); pi < part_count; ++pi) + { + wxAuiDockUIPart& part = m_uiparts.Item(pi); + if (part.pane == &p) + { + m_uiparts.RemoveAt(pi); + part_count--; + pi--; + continue; + } + } + m_panes.RemoveAt(i); return true; } @@ -722,6 +1019,109 @@ bool wxFrameManager::DetachPane(wxWindow* window) return false; } +// ClosePane() destroys or hides the pane depending on its +// flags +void wxAuiManager::ClosePane(wxAuiPaneInfo& pane_info) +{ + // if we were maximized, restore + if(pane_info.IsMaximized()) { + RestorePane(pane_info); + } + + // first, hide the window + if (pane_info.window && pane_info.window->IsShown()) { + pane_info.window->Show(false); + } + + // make sure that we are the parent of this window + if(pane_info.window && pane_info.window->GetParent() != m_frame) { + pane_info.window->Reparent(m_frame); + } + + // if we have a frame, destroy it + if(pane_info.frame) { + pane_info.frame->Destroy(); + pane_info.frame = NULL; + } + + // now we need to either destroy or hide the pane + if(pane_info.IsDestroyOnClose()) + { + wxWindow * window = pane_info.window; + DetachPane(window); + if(window) { + window->Destroy(); + } + } + else + { + pane_info.Hide(); + } +} + +void wxAuiManager::MaximizePane(wxAuiPaneInfo& pane_info) +{ + int i, pane_count; + + // un-maximize and hide all other panes + for (i = 0, pane_count = m_panes.GetCount(); i < pane_count; ++i) + { + wxAuiPaneInfo& p = m_panes.Item(i); + if(!p.IsToolbar()) { + p.Restore(); + p.SaveHidden(); + p.Hide(); + } + } + + // mark ourselves maximized + pane_info.Maximize(); + pane_info.Show(); + m_has_maximized = true; + + // last, show the window + if (pane_info.window && !pane_info.window->IsShown()) { + pane_info.window->Show(true); + } +} + +void wxAuiManager::RestorePane(wxAuiPaneInfo& pane_info) +{ + int i, pane_count; + + // restore all the panes + for (i = 0, pane_count = m_panes.GetCount(); i < pane_count; ++i) + { + wxAuiPaneInfo& p = m_panes.Item(i); + if(!p.IsToolbar()) { + p.RestoreHidden(); + } + } + + // mark ourselves non-maximized + pane_info.Restore(); + m_has_maximized = false; + + // last, show the window + if (pane_info.window && !pane_info.window->IsShown()) { + pane_info.window->Show(true); + } +} + +void wxAuiManager::RestoreMaximizedPane() +{ + int i, pane_count; + + // restore all the panes + for (i = 0, pane_count = m_panes.GetCount(); i < pane_count; ++i) + { + wxAuiPaneInfo& p = m_panes.Item(i); + if(p.IsMaximized()) { + RestorePane(p); + break; + } + } +} // EscapeDelimiters() changes ";" into "\;" and "|" into "\|" // in the input string. This is an internal functions which is @@ -729,7 +1129,7 @@ bool wxFrameManager::DetachPane(wxWindow* window) static wxString EscapeDelimiters(const wxString& s) { wxString result; - result.Alloc(s.Length()); + result.Alloc(s.length()); const wxChar* ch = s.c_str(); while (*ch) { @@ -741,13 +1141,119 @@ static wxString EscapeDelimiters(const wxString& s) return result; } +wxString wxAuiManager::SavePaneInfo(wxAuiPaneInfo& pane) +{ + wxString result = wxT("name="); + result += EscapeDelimiters(pane.name); + result += wxT(";"); + + result += wxT("caption="); + result += EscapeDelimiters(pane.caption); + result += wxT(";"); + + result += wxString::Format(wxT("state=%u;"), pane.state); + result += wxString::Format(wxT("dir=%d;"), pane.dock_direction); + result += wxString::Format(wxT("layer=%d;"), pane.dock_layer); + result += wxString::Format(wxT("row=%d;"), pane.dock_row); + result += wxString::Format(wxT("pos=%d;"), pane.dock_pos); + result += wxString::Format(wxT("prop=%d;"), pane.dock_proportion); + result += wxString::Format(wxT("bestw=%d;"), pane.best_size.x); + result += wxString::Format(wxT("besth=%d;"), pane.best_size.y); + result += wxString::Format(wxT("minw=%d;"), pane.min_size.x); + result += wxString::Format(wxT("minh=%d;"), pane.min_size.y); + result += wxString::Format(wxT("maxw=%d;"), pane.max_size.x); + result += wxString::Format(wxT("maxh=%d;"), pane.max_size.y); + result += wxString::Format(wxT("floatx=%d;"), pane.floating_pos.x); + result += wxString::Format(wxT("floaty=%d;"), pane.floating_pos.y); + result += wxString::Format(wxT("floatw=%d;"), pane.floating_size.x); + result += wxString::Format(wxT("floath=%d"), pane.floating_size.y); + + return result; +} + +// Load a "pane" with the pane infor settings in pane_part +void wxAuiManager::LoadPaneInfo(wxString pane_part, wxAuiPaneInfo &pane) +{ + // replace escaped characters so we can + // split up the string easily + pane_part.Replace(wxT("\\|"), wxT("\a")); + pane_part.Replace(wxT("\\;"), wxT("\b")); + + while(1) + { + wxString val_part = pane_part.BeforeFirst(wxT(';')); + pane_part = pane_part.AfterFirst(wxT(';')); + wxString val_name = val_part.BeforeFirst(wxT('=')); + wxString value = val_part.AfterFirst(wxT('=')); + val_name.MakeLower(); + val_name.Trim(true); + val_name.Trim(false); + value.Trim(true); + value.Trim(false); + + if (val_name.empty()) + break; + + if (val_name == wxT("name")) + pane.name = value; + else if (val_name == wxT("caption")) + pane.caption = value; + else if (val_name == wxT("state")) + pane.state = (unsigned int)wxAtoi(value.c_str()); + else if (val_name == wxT("dir")) + pane.dock_direction = wxAtoi(value.c_str()); + else if (val_name == wxT("layer")) + pane.dock_layer = wxAtoi(value.c_str()); + else if (val_name == wxT("row")) + pane.dock_row = wxAtoi(value.c_str()); + else if (val_name == wxT("pos")) + pane.dock_pos = wxAtoi(value.c_str()); + else if (val_name == wxT("prop")) + pane.dock_proportion = wxAtoi(value.c_str()); + else if (val_name == wxT("bestw")) + pane.best_size.x = wxAtoi(value.c_str()); + else if (val_name == wxT("besth")) + pane.best_size.y = wxAtoi(value.c_str()); + else if (val_name == wxT("minw")) + pane.min_size.x = wxAtoi(value.c_str()); + else if (val_name == wxT("minh")) + pane.min_size.y = wxAtoi(value.c_str()); + else if (val_name == wxT("maxw")) + pane.max_size.x = wxAtoi(value.c_str()); + else if (val_name == wxT("maxh")) + pane.max_size.y = wxAtoi(value.c_str()); + else if (val_name == wxT("floatx")) + pane.floating_pos.x = wxAtoi(value.c_str()); + else if (val_name == wxT("floaty")) + pane.floating_pos.y = wxAtoi(value.c_str()); + else if (val_name == wxT("floatw")) + pane.floating_size.x = wxAtoi(value.c_str()); + else if (val_name == wxT("floath")) + pane.floating_size.y = wxAtoi(value.c_str()); + else { + wxFAIL_MSG(wxT("Bad Perspective String")); + } + } + + // replace escaped characters so we can + // split up the string easily + pane.name.Replace(wxT("\a"), wxT("|")); + pane.name.Replace(wxT("\b"), wxT(";")); + pane.caption.Replace(wxT("\a"), wxT("|")); + pane.caption.Replace(wxT("\b"), wxT(";")); + pane_part.Replace(wxT("\a"), wxT("|")); + pane_part.Replace(wxT("\b"), wxT(";")); + + return; +} + // SavePerspective() saves all pane information as a single string. // This string may later be fed into LoadPerspective() to restore // all pane settings. This save and load mechanism allows an // exact pane configuration to be saved and restored at a later time -wxString wxFrameManager::SavePerspective() +wxString wxAuiManager::SavePerspective() { wxString result; result.Alloc(500); @@ -756,56 +1262,31 @@ wxString wxFrameManager::SavePerspective() int pane_i, pane_count = m_panes.GetCount(); for (pane_i = 0; pane_i < pane_count; ++pane_i) { - wxPaneInfo& pane = m_panes.Item(pane_i); - - result += wxT("name="); - result += EscapeDelimiters(pane.name); - result += wxT(";"); - - result += wxT("caption="); - result += EscapeDelimiters(pane.caption); - result += wxT(";"); - - result += wxString::Format(wxT("state=%u;"), pane.state); - result += wxString::Format(wxT("dir=%d;"), pane.dock_direction); - result += wxString::Format(wxT("layer=%d;"), pane.dock_layer); - result += wxString::Format(wxT("row=%d;"), pane.dock_row); - result += wxString::Format(wxT("pos=%d;"), pane.dock_pos); - result += wxString::Format(wxT("prop=%d;"), pane.dock_proportion); - result += wxString::Format(wxT("bestw=%d;"), pane.best_size.x); - result += wxString::Format(wxT("besth=%d;"), pane.best_size.y); - result += wxString::Format(wxT("minw=%d;"), pane.min_size.x); - result += wxString::Format(wxT("minh=%d;"), pane.min_size.y); - result += wxString::Format(wxT("maxw=%d;"), pane.max_size.x); - result += wxString::Format(wxT("maxh=%d;"), pane.max_size.y); - result += wxString::Format(wxT("floatx=%d;"), pane.floating_pos.x); - result += wxString::Format(wxT("floaty=%d;"), pane.floating_pos.y); - result += wxString::Format(wxT("floatw=%d;"), pane.floating_size.x); - result += wxString::Format(wxT("floath=%d"), pane.floating_size.y); - result += wxT("|"); + wxAuiPaneInfo& pane = m_panes.Item(pane_i); + result += SavePaneInfo(pane)+wxT("|"); } - + int dock_i, dock_count = m_docks.GetCount(); for (dock_i = 0; dock_i < dock_count; ++dock_i) { - wxDockInfo& dock = m_docks.Item(dock_i); - + wxAuiDockInfo& dock = m_docks.Item(dock_i); + result += wxString::Format(wxT("dock_size(%d,%d,%d)=%d|"), dock.dock_direction, dock.dock_layer, dock.dock_row, dock.size); } - + return result; } // LoadPerspective() loads a layout which was saved with SavePerspective() // If the "update" flag parameter is true, the GUI will immediately be updated -bool wxFrameManager::LoadPerspective(const wxString& layout, bool update) +bool wxAuiManager::LoadPerspective(const wxString& layout, bool update) { wxString input = layout; wxString part; - + // check layout string version part = input.BeforeFirst(wxT('|')); input = input.AfterFirst(wxT('|')); @@ -813,8 +1294,7 @@ bool wxFrameManager::LoadPerspective(const wxString& layout, bool update) part.Trim(false); if (part != wxT("layout1")) return false; - - + // mark all panes currently managed as docked and hidden int pane_i, pane_count = m_panes.GetCount(); for (pane_i = 0; pane_i < pane_count; ++pane_i) @@ -822,30 +1302,29 @@ bool wxFrameManager::LoadPerspective(const wxString& layout, bool update) // clear out the dock array; this will be reconstructed m_docks.Clear(); - + // replace escaped characters so we can // split up the string easily input.Replace(wxT("\\|"), wxT("\a")); input.Replace(wxT("\\;"), wxT("\b")); - + while (1) { - wxPaneInfo pane; + wxAuiPaneInfo pane; wxString pane_part = input.BeforeFirst(wxT('|')); input = input.AfterFirst(wxT('|')); pane_part.Trim(true); // if the string is empty, we're done parsing - if (pane_part.IsEmpty()) + if (pane_part.empty()) break; - if (pane_part.Left(9) == wxT("dock_size")) { wxString val_name = pane_part.BeforeFirst(wxT('=')); wxString value = pane_part.AfterFirst(wxT('=')); - + long dir, layer, row, size; wxString piece = val_name.AfterFirst(wxT('(')); piece = piece.BeforeLast(wxT(')')); @@ -854,8 +1333,8 @@ bool wxFrameManager::LoadPerspective(const wxString& layout, bool update) piece.BeforeFirst(wxT(',')).ToLong(&layer); piece.AfterFirst(wxT(',')).ToLong(&row); value.ToLong(&size); - - wxDockInfo dock; + + wxAuiDockInfo dock; dock.dock_direction = dir; dock.dock_layer = layer; dock.dock_row = row; @@ -864,91 +1343,32 @@ bool wxFrameManager::LoadPerspective(const wxString& layout, bool update) continue; } - while (1) - { - wxString val_part = pane_part.BeforeFirst(wxT(';')); - pane_part = pane_part.AfterFirst(wxT(';')); - wxString val_name = val_part.BeforeFirst(wxT('=')); - wxString value = val_part.AfterFirst(wxT('=')); - val_name.MakeLower(); - val_name.Trim(true); - val_name.Trim(false); - value.Trim(true); - value.Trim(false); - - if (val_name.IsEmpty()) - break; + // Undo our escaping as LoadPaneInfo needs to take an unescaped + // name so it can be called by external callers + pane_part.Replace(wxT("\a"), wxT("|")); + pane_part.Replace(wxT("\b"), wxT(";")); - if (val_name == wxT("name")) - pane.name = value; - else if (val_name == wxT("caption")) - pane.caption = value; - else if (val_name == wxT("state")) - pane.state = (unsigned int)wxAtoi(value.c_str()); - else if (val_name == wxT("dir")) - pane.dock_direction = wxAtoi(value.c_str()); - else if (val_name == wxT("layer")) - pane.dock_layer = wxAtoi(value.c_str()); - else if (val_name == wxT("row")) - pane.dock_row = wxAtoi(value.c_str()); - else if (val_name == wxT("pos")) - pane.dock_pos = wxAtoi(value.c_str()); - else if (val_name == wxT("prop")) - pane.dock_proportion = wxAtoi(value.c_str()); - else if (val_name == wxT("bestw")) - pane.best_size.x = wxAtoi(value.c_str()); - else if (val_name == wxT("besth")) - pane.best_size.y = wxAtoi(value.c_str()); - else if (val_name == wxT("minw")) - pane.min_size.x = wxAtoi(value.c_str()); - else if (val_name == wxT("minh")) - pane.min_size.y = wxAtoi(value.c_str()); - else if (val_name == wxT("maxw")) - pane.max_size.x = wxAtoi(value.c_str()); - else if (val_name == wxT("maxh")) - pane.max_size.y = wxAtoi(value.c_str()); - else if (val_name == wxT("floatx")) - pane.floating_pos.x = wxAtoi(value.c_str()); - else if (val_name == wxT("floaty")) - pane.floating_pos.y = wxAtoi(value.c_str()); - else if (val_name == wxT("floatw")) - pane.floating_size.x = wxAtoi(value.c_str()); - else if (val_name == wxT("floath")) - pane.floating_size.y = wxAtoi(value.c_str()); - else { - wxFAIL_MSG(wxT("Bad Perspective String")); - } - } - - // replace escaped characters so we can - // split up the string easily - pane.name.Replace(wxT("\a"), wxT("|")); - pane.name.Replace(wxT("\b"), wxT(";")); - pane.caption.Replace(wxT("\a"), wxT("|")); - pane.caption.Replace(wxT("\b"), wxT(";")); - - wxPaneInfo& p = GetPane(pane.name); + LoadPaneInfo(pane_part, pane); + + wxAuiPaneInfo& p = GetPane(pane.name); if (!p.IsOk()) { // the pane window couldn't be found // in the existing layout return false; } - - pane.window = p.window; - pane.frame = p.frame; - pane.buttons = p.buttons; - p = pane; + + p.SafeSet(pane); + } - + if (update) Update(); return true; } - -void wxFrameManager::GetPanePositionsAndSizes(wxDockInfo& dock, +void wxAuiManager::GetPanePositionsAndSizes(wxAuiDockInfo& dock, wxArrayInt& positions, wxArrayInt& sizes) { @@ -965,27 +1385,27 @@ void wxFrameManager::GetPanePositionsAndSizes(wxDockInfo& dock, // find the pane marked as our action pane for (pane_i = 0; pane_i < pane_count; ++pane_i) { - wxPaneInfo& pane = *(dock.panes.Item(pane_i)); + wxAuiPaneInfo& pane = *(dock.panes.Item(pane_i)); - if (pane.state & wxPaneInfo::actionPane) + if (pane.state & wxAuiPaneInfo::actionPane) { wxASSERT_MSG(action_pane==-1, wxT("Too many fixed action panes")); action_pane = pane_i; } } - + // set up each panes default position, and // determine the size (width or height, depending // on the dock's orientation) of each pane for (pane_i = 0; pane_i < pane_count; ++pane_i) { - wxPaneInfo& pane = *(dock.panes.Item(pane_i)); + wxAuiPaneInfo& pane = *(dock.panes.Item(pane_i)); positions.Add(pane.dock_pos); int size = 0; - + if (pane.HasBorder()) size += (pane_border_size*2); - + if (dock.IsHorizontal()) { if (pane.HasGripper() && !pane.HasGripperTop()) @@ -998,10 +1418,10 @@ void wxFrameManager::GetPanePositionsAndSizes(wxDockInfo& dock, size += gripper_size; if (pane.HasCaption()) - size += caption_size; + size += caption_size; size += pane.best_size.y; } - + sizes.Add(size); } @@ -1022,7 +1442,7 @@ void wxFrameManager::GetPanePositionsAndSizes(wxDockInfo& dock, offset += sizes[pane_i]; } - + // if the dock mode is fixed, make sure none of the panes // overlap; we will bump panes that overlap offset = 0; @@ -1039,13 +1459,13 @@ void wxFrameManager::GetPanePositionsAndSizes(wxDockInfo& dock, } -void wxFrameManager::LayoutAddPane(wxSizer* cont, - wxDockInfo& dock, - wxPaneInfo& pane, - wxDockUIPartArray& uiparts, +void wxAuiManager::LayoutAddPane(wxSizer* cont, + wxAuiDockInfo& dock, + wxAuiPaneInfo& pane, + wxAuiDockUIPartArray& uiparts, bool spacer_only) -{ - wxDockUIPart part; +{ + wxAuiDockUIPart part; wxSizerItem* sizer_item; int caption_size = m_art->GetMetric(wxAUI_ART_CAPTION_SIZE); @@ -1072,10 +1492,10 @@ void wxFrameManager::LayoutAddPane(wxSizer* cont, { if (pane.HasGripperTop()) sizer_item = vert_pane_sizer ->Add(1, gripper_size, 0, wxEXPAND); - else + else sizer_item = horz_pane_sizer ->Add(gripper_size, 1, 0, wxEXPAND); - part.type = wxDockUIPart::typeGripper; + part.type = wxAuiDockUIPart::typeGripper; part.dock = &dock; part.pane = &pane; part.button = NULL; @@ -1092,7 +1512,7 @@ void wxFrameManager::LayoutAddPane(wxSizer* cont, sizer_item = caption_sizer->Add(1, caption_size, 1, wxEXPAND); - part.type = wxDockUIPart::typeCaption; + part.type = wxAuiDockUIPart::typeCaption; part.dock = &dock; part.pane = &pane; part.button = NULL; @@ -1107,13 +1527,13 @@ void wxFrameManager::LayoutAddPane(wxSizer* cont, for (i = 0, button_count = pane.buttons.GetCount(); i < button_count; ++i) { - wxPaneButton& button = pane.buttons.Item(i); + wxAuiPaneButton& button = pane.buttons.Item(i); sizer_item = caption_sizer->Add(pane_button_size, caption_size, 0, wxEXPAND); - part.type = wxDockUIPart::typePaneButton; + part.type = wxAuiDockUIPart::typePaneButton; part.dock = &dock; part.pane = &pane; part.button = &button; @@ -1134,13 +1554,16 @@ void wxFrameManager::LayoutAddPane(wxSizer* cont, { sizer_item = vert_pane_sizer->Add(1, 1, 1, wxEXPAND); } - else + else { sizer_item = vert_pane_sizer->Add(pane.window, 1, wxEXPAND); + // Don't do this because it breaks the pane size in floating windows + // BIW: Right now commenting this out is causing problems with + // an mdi client window as the center pane. vert_pane_sizer->SetItemMinSize(pane.window, 1, 1); } - part.type = wxDockUIPart::typePane; + part.type = wxAuiDockUIPart::typePane; part.dock = &dock; part.pane = &pane; part.button = NULL; @@ -1153,7 +1576,7 @@ void wxFrameManager::LayoutAddPane(wxSizer* cont, // determine if the pane should have a minimum size; if the pane is // non-resizable (fixed) then we must set a minimum size. Alternitavely, // if the pane.min_size is set, we must use that value as well - + wxSize min_size = pane.min_size; if (pane.IsFixed()) { @@ -1163,7 +1586,7 @@ void wxFrameManager::LayoutAddPane(wxSizer* cont, pane_proportion = 0; } } - + if (min_size != wxDefaultSize) { vert_pane_sizer->SetItemMinSize( @@ -1184,7 +1607,7 @@ void wxFrameManager::LayoutAddPane(wxSizer* cont, sizer_item = cont->Add(horz_pane_sizer, pane_proportion, wxEXPAND | wxALL, pane_border_size); - part.type = wxDockUIPart::typePaneBorder; + part.type = wxAuiDockUIPart::typePaneBorder; part.dock = &dock; part.pane = &pane; part.button = NULL; @@ -1193,30 +1616,30 @@ void wxFrameManager::LayoutAddPane(wxSizer* cont, part.sizer_item = sizer_item; uiparts.Add(part); } - else + else { sizer_item = cont->Add(horz_pane_sizer, pane_proportion, wxEXPAND); } } -void wxFrameManager::LayoutAddDock(wxSizer* cont, - wxDockInfo& dock, - wxDockUIPartArray& uiparts, +void wxAuiManager::LayoutAddDock(wxSizer* cont, + wxAuiDockInfo& dock, + wxAuiDockUIPartArray& uiparts, bool spacer_only) { wxSizerItem* sizer_item; - wxDockUIPart part; + wxAuiDockUIPart part; int sash_size = m_art->GetMetric(wxAUI_ART_SASH_SIZE); int orientation = dock.IsHorizontal() ? wxHORIZONTAL : wxVERTICAL; // resizable bottom and right docks have a sash before them - if (!dock.fixed && (dock.dock_direction == wxAUI_DOCK_BOTTOM || + if (!m_has_maximized && !dock.fixed && (dock.dock_direction == wxAUI_DOCK_BOTTOM || dock.dock_direction == wxAUI_DOCK_RIGHT)) { sizer_item = cont->Add(sash_size, sash_size, 0, wxEXPAND); - part.type = wxDockUIPart::typeDockSizer; + part.type = wxAuiDockUIPart::typeDockSizer; part.orientation = orientation; part.dock = &dock; part.pane = NULL; @@ -1230,12 +1653,13 @@ void wxFrameManager::LayoutAddDock(wxSizer* cont, wxSizer* dock_sizer = new wxBoxSizer(orientation); // add each pane to the dock + bool has_maximized_pane = false; int pane_i, pane_count = dock.panes.GetCount(); if (dock.fixed) { wxArrayInt pane_positions, pane_sizes; - + // figure out the real pane positions we will // use, without modifying the each pane's pane_pos member GetPanePositionsAndSizes(dock, pane_positions, pane_sizes); @@ -1243,8 +1667,11 @@ void wxFrameManager::LayoutAddDock(wxSizer* cont, int offset = 0; for (pane_i = 0; pane_i < pane_count; ++pane_i) { - wxPaneInfo& pane = *(dock.panes.Item(pane_i)); + wxAuiPaneInfo& pane = *(dock.panes.Item(pane_i)); int pane_pos = pane_positions.Item(pane_i); + if(pane.IsMaximized()) { + has_maximized_pane = true; + } int amount = pane_pos - offset; if (amount > 0) @@ -1254,7 +1681,7 @@ void wxFrameManager::LayoutAddDock(wxSizer* cont, else sizer_item = dock_sizer->Add(amount, 1, 0, wxEXPAND); - part.type = wxDockUIPart::typeBackground; + part.type = wxAuiDockUIPart::typeBackground; part.dock = &dock; part.pane = NULL; part.button = NULL; @@ -1274,7 +1701,7 @@ void wxFrameManager::LayoutAddDock(wxSizer* cont, // at the end add a very small stretchable background area sizer_item = dock_sizer->Add(1,1, 1, wxEXPAND); - part.type = wxDockUIPart::typeBackground; + part.type = wxAuiDockUIPart::typeBackground; part.dock = &dock; part.pane = NULL; part.button = NULL; @@ -1283,19 +1710,22 @@ void wxFrameManager::LayoutAddDock(wxSizer* cont, part.sizer_item = sizer_item; uiparts.Add(part); } - else + else { for (pane_i = 0; pane_i < pane_count; ++pane_i) { - wxPaneInfo& pane = *(dock.panes.Item(pane_i)); + wxAuiPaneInfo& pane = *(dock.panes.Item(pane_i)); + if(pane.IsMaximized()) { + has_maximized_pane = true; + } // if this is not the first pane being added, // we need to add a pane sizer - if (pane_i > 0) + if (!m_has_maximized && pane_i > 0) { sizer_item = dock_sizer->Add(sash_size, sash_size, 0, wxEXPAND); - part.type = wxDockUIPart::typePaneSizer; + part.type = wxAuiDockUIPart::typePaneSizer; part.dock = &dock; part.pane = dock.panes.Item(pane_i-1); part.button = NULL; @@ -1309,12 +1739,12 @@ void wxFrameManager::LayoutAddDock(wxSizer* cont, } } - if (dock.dock_direction == wxAUI_DOCK_CENTER) + if (dock.dock_direction == wxAUI_DOCK_CENTER || has_maximized_pane) sizer_item = cont->Add(dock_sizer, 1, wxEXPAND); else sizer_item = cont->Add(dock_sizer, 0, wxEXPAND); - part.type = wxDockUIPart::typeDock; + part.type = wxAuiDockUIPart::typeDock; part.dock = &dock; part.pane = NULL; part.button = NULL; @@ -1329,12 +1759,12 @@ void wxFrameManager::LayoutAddDock(wxSizer* cont, cont->SetItemMinSize(dock_sizer, dock.size, 0); // top and left docks have a sash after them - if (!dock.fixed && (dock.dock_direction == wxAUI_DOCK_TOP || + if (!m_has_maximized && !dock.fixed && (dock.dock_direction == wxAUI_DOCK_TOP || dock.dock_direction == wxAUI_DOCK_LEFT)) { sizer_item = cont->Add(sash_size, sash_size, 0, wxEXPAND); - part.type = wxDockUIPart::typeDockSizer; + part.type = wxAuiDockUIPart::typeDockSizer; part.dock = &dock; part.pane = NULL; part.button = NULL; @@ -1345,9 +1775,9 @@ void wxFrameManager::LayoutAddDock(wxSizer* cont, } } -wxSizer* wxFrameManager::LayoutAll(wxPaneInfoArray& panes, - wxDockInfoArray& docks, - wxDockUIPartArray& uiparts, +wxSizer* wxAuiManager::LayoutAll(wxAuiPaneInfoArray& panes, + wxAuiDockInfoArray& docks, + wxAuiDockUIPartArray& uiparts, bool spacer_only) { wxBoxSizer* container = new wxBoxSizer(wxVERTICAL); @@ -1356,22 +1786,23 @@ wxSizer* wxFrameManager::LayoutAll(wxPaneInfoArray& panes, int caption_size = m_art->GetMetric(wxAUI_ART_CAPTION_SIZE); wxSize cli_size = m_frame->GetClientSize(); int i, dock_count, pane_count; - + // empty all docks out for (i = 0, dock_count = docks.GetCount(); i < dock_count; ++i) docks.Item(i).panes.Empty(); - + + // iterate through all known panes, filing each // of them into the appropriate dock. If the // pane does not exist in the dock, add it for (i = 0, pane_count = panes.GetCount(); i < pane_count; ++i) { - wxPaneInfo& p = panes.Item(i); + wxAuiPaneInfo& p = panes.Item(i); // find any docks in this layer - wxDockInfo* dock; - wxDockInfoPtrArray arr; + wxAuiDockInfo* dock; + wxAuiDockInfoPtrArray arr; FindDocks(docks, p.dock_direction, p.dock_layer, p.dock_row, arr); if (arr.GetCount() > 0) @@ -1381,7 +1812,7 @@ wxSizer* wxFrameManager::LayoutAll(wxPaneInfoArray& panes, else { // dock was not found, so we need to create a new one - wxDockInfo d; + wxAuiDockInfo d; d.dock_direction = p.dock_direction; d.dock_layer = p.dock_layer; d.dock_row = p.dock_row; @@ -1396,7 +1827,7 @@ wxSizer* wxFrameManager::LayoutAll(wxPaneInfoArray& panes, RemovePaneFromDocks(docks, p, dock); // pane needs to be added to the dock, - // if it doesn't already exist + // if it doesn't already exist if (!FindPaneInDock(*dock, p.window)) dock->panes.Add(&p); } @@ -1418,9 +1849,9 @@ wxSizer* wxFrameManager::LayoutAll(wxPaneInfoArray& panes, // configure the docks further for (i = 0, dock_count = docks.GetCount(); i < dock_count; ++i) { - wxDockInfo& dock = docks.Item(i); + wxAuiDockInfo& dock = docks.Item(i); int j, dock_pane_count = dock.panes.GetCount(); - + // sort the dock pane array by the pane's // dock position (dock_pos), in ascending order dock.panes.Sort(PaneSortFunc); @@ -1432,19 +1863,19 @@ wxSizer* wxFrameManager::LayoutAll(wxPaneInfoArray& panes, for (j = 0; j < dock_pane_count; ++j) { - wxPaneInfo& pane = *dock.panes.Item(j); + wxAuiPaneInfo& pane = *dock.panes.Item(j); wxSize pane_size = pane.best_size; if (pane_size == wxDefaultSize) pane_size = pane.min_size; if (pane_size == wxDefaultSize) pane_size = pane.window->GetSize(); - + if (dock.IsHorizontal()) size = wxMax(pane_size.y, size); else size = wxMax(pane_size.x, size); } - + // add space for the border (two times), but only // if at least one pane inside the dock has a pane border for (j = 0; j < dock_pane_count; ++j) @@ -1488,7 +1919,7 @@ wxSizer* wxFrameManager::LayoutAll(wxPaneInfoArray& panes, int dock_min_size = 0; for (j = 0; j < dock_pane_count; ++j) { - wxPaneInfo& pane = *dock.panes.Item(j); + wxAuiPaneInfo& pane = *dock.panes.Item(j); if (pane.min_size != wxDefaultSize) { if (pane.HasBorder()) @@ -1507,15 +1938,15 @@ wxSizer* wxFrameManager::LayoutAll(wxPaneInfoArray& panes, } } } - + if (plus_border) dock_min_size += (pane_border_size*2); if (plus_caption && dock.IsHorizontal()) dock_min_size += (caption_size); - + dock.min_size = dock_min_size; - - + + // if the pane's current size is less than it's // minimum, increase the dock's size to it's minimum if (dock.size < dock.min_size) @@ -1529,12 +1960,12 @@ wxSizer* wxFrameManager::LayoutAll(wxPaneInfoArray& panes, dock.toolbar = true; for (j = 0; j < dock_pane_count; ++j) { - wxPaneInfo& pane = *dock.panes.Item(j); + wxAuiPaneInfo& pane = *dock.panes.Item(j); if (!pane.IsFixed()) dock.fixed = false; if (!pane.IsToolbar()) dock.toolbar = false; - if (pane.state & wxPaneInfo::actionPane) + if (pane.state & wxAuiPaneInfo::actionPane) action_pane_marked = true; } @@ -1546,7 +1977,7 @@ wxSizer* wxFrameManager::LayoutAll(wxPaneInfoArray& panes, { for (j = 0; j < dock_pane_count; ++j) { - wxPaneInfo& pane = *dock.panes.Item(j); + wxAuiPaneInfo& pane = *dock.panes.Item(j); pane.dock_pos = j; } } @@ -1559,11 +1990,11 @@ wxSizer* wxFrameManager::LayoutAll(wxPaneInfoArray& panes, { wxArrayInt pane_positions, pane_sizes; GetPanePositionsAndSizes(dock, pane_positions, pane_sizes); - + int offset = 0; for (j = 0; j < dock_pane_count; ++j) { - wxPaneInfo& pane = *(dock.panes.Item(j)); + wxAuiPaneInfo& pane = *(dock.panes.Item(j)); pane.dock_pos = pane_positions[j]; int amount = pane.dock_pos - offset; @@ -1576,12 +2007,12 @@ wxSizer* wxFrameManager::LayoutAll(wxPaneInfoArray& panes, } } } - + // discover the maximum dock layer int max_layer = 0; for (i = 0; i < dock_count; ++i) max_layer = wxMax(max_layer, docks.Item(i).dock_layer); - + // clear out uiparts uiparts.Empty(); @@ -1595,7 +2026,7 @@ wxSizer* wxFrameManager::LayoutAll(wxPaneInfoArray& panes, for (layer = 0; layer <= max_layer; ++layer) { - wxDockInfoPtrArray arr; + wxAuiDockInfoPtrArray arr; // find any docks in this layer FindDocks(docks, -1, layer, -1, arr); @@ -1620,10 +2051,10 @@ wxSizer* wxFrameManager::LayoutAll(wxPaneInfoArray& panes, LayoutAddDock(cont, *arr.Item(row), uiparts, spacer_only); } - + // fill out the middle layer (which consists // of left docks, content area and right docks) - + middle = new wxBoxSizer(wxHORIZONTAL); // find any left docks in this layer @@ -1646,12 +2077,12 @@ wxSizer* wxFrameManager::LayoutAll(wxPaneInfoArray& panes, for (row = 0,row_count = arr.GetCount(); rowAdd(1,1, 1, wxEXPAND); - wxDockUIPart part; - part.type = wxDockUIPart::typeBackground; + wxAuiDockUIPart part; + part.type = wxAuiDockUIPart::typeBackground; part.pane = NULL; part.dock = NULL; part.button = NULL; @@ -1695,8 +2126,8 @@ wxSizer* wxFrameManager::LayoutAll(wxPaneInfoArray& panes, // therefore we will create a simple background area cont = new wxBoxSizer(wxVERTICAL); wxSizerItem* sizer_item = cont->Add(1,1, 1, wxEXPAND); - wxDockUIPart part; - part.type = wxDockUIPart::typeBackground; + wxAuiDockUIPart part; + part.type = wxAuiDockUIPart::typeBackground; part.pane = NULL; part.dock = NULL; part.button = NULL; @@ -1714,7 +2145,7 @@ wxSizer* wxFrameManager::LayoutAll(wxPaneInfoArray& panes, // one or more panes, this function should be called. It is the // external entry point for running the layout engine. -void wxFrameManager::Update() +void wxAuiManager::Update() { wxSizer* sizer; int i, pane_count = m_panes.GetCount(); @@ -1726,18 +2157,41 @@ void wxFrameManager::Update() // redocked or are becoming non-floating for (i = 0; i < pane_count; ++i) { - wxPaneInfo& p = m_panes.Item(i); + wxAuiPaneInfo& p = m_panes.Item(i); if (!p.IsFloating() && p.frame) { // because the pane is no longer in a floating, we need to // reparent it to m_frame and destroy the floating frame - + // reduce flicker p.window->SetSize(1,1); - p.frame->Show(false); - + + + // the following block is a workaround for bug #1531361 + // (see wxWidgets sourceforge page). On wxGTK (only), when + // a frame is shown/hidden, a move event unfortunately + // also gets fired. Because we may be dragging around + // a pane, we need to cancel that action here to prevent + // a spurious crash. + if (m_action_window == p.frame) + { + if (wxWindow::GetCapture() == m_frame) + m_frame->ReleaseMouse(); + m_action = actionNone; + m_action_window = NULL; + } + + // hide the frame + if (p.frame->IsShown()) + p.frame->Show(false); + // reparent to m_frame and destroy the pane + if(m_action_window == p.frame) + { + m_action_window = NULL; + } + p.window->Reparent(m_frame); p.frame->SetSizer(NULL); p.frame->Destroy(); @@ -1753,7 +2207,7 @@ void wxFrameManager::Update() // and float panes as necessary for (i = 0; i < pane_count; ++i) { - wxPaneInfo& p = m_panes.Item(i); + wxAuiPaneInfo& p = m_panes.Item(i); if (p.IsFloating()) { @@ -1761,52 +2215,50 @@ void wxFrameManager::Update() { // we need to create a frame for this // pane, which has recently been floated - wxFloatingPane* frame = new wxFloatingPane(m_frame, - this, -1, - p.floating_pos, - p.floating_size); - - // on MSW, if the owner desires transparent dragging, and + wxAuiFloatingFrame* frame = CreateFloatingFrame(m_frame, p); + +#if wxCHECK_VERSION(2,7,0) + // on MSW and Mac, if the owner desires transparent dragging, and // the dragging is happening right now, then the floating - // window should have this style by default - #ifdef __WXMSW__ + // window should have this style by default if (m_action == actionDragFloatingPane && (m_flags & wxAUI_MGR_TRANSPARENT_DRAG)) - MakeWindowTransparent(frame, 150); - #endif - + frame->SetTransparent(150); +#endif + frame->SetPaneWindow(p); p.frame = frame; - if (p.IsShown()) - { + if (p.IsShown() && !frame->IsShown()) frame->Show(); - } } else { // frame already exists, make sure it's position - // and size reflect the information in wxPaneInfo + // and size reflect the information in wxAuiPaneInfo if (p.frame->GetPosition() != p.floating_pos) { p.frame->SetSize(p.floating_pos.x, p.floating_pos.y, - -1, -1, wxSIZE_USE_EXISTING); + wxDefaultCoord, wxDefaultCoord, + wxSIZE_USE_EXISTING); //p.frame->Move(p.floating_pos.x, p.floating_pos.y); } - p.frame->Show(p.IsShown()); + if (p.frame->IsShown() != p.IsShown()) + p.frame->Show(p.IsShown()); } } else { - p.window->Show(p.IsShown()); + if (p.window->IsShown() != p.IsShown()) + p.window->Show(p.IsShown()); } // if "active panes" are no longer allowed, clear // any optionActive values from the pane states if ((m_flags & wxAUI_MGR_ALLOW_ACTIVE_PANE) == 0) { - p.state &= ~wxPaneInfo::optionActive; + p.state &= ~wxAuiPaneInfo::optionActive; } } @@ -1817,7 +2269,7 @@ void wxFrameManager::Update() for (i = 0; i < pane_count; ++i) { wxRect r; - wxPaneInfo& p = m_panes.Item(i); + wxAuiPaneInfo& p = m_panes.Item(i); if (p.window && p.IsShown() && p.IsDocked()) r = p.rect; @@ -1841,7 +2293,7 @@ void wxFrameManager::Update() // changed, the corresponding panes must also be updated for (i = 0; i < pane_count; ++i) { - wxPaneInfo& p = m_panes.Item(i); + wxAuiPaneInfo& p = m_panes.Item(i); if (p.window && p.window->IsShown() && p.IsDocked()) { if (p.rect != old_pane_rects[i]) @@ -1854,9 +2306,9 @@ void wxFrameManager::Update() Repaint(); - + // set frame's minimum size - + /* // N.B. More work needs to be done on frame minimum sizes; // this is some intresting code that imposes the minimum size, @@ -1868,9 +2320,9 @@ void wxFrameManager::Update() wxSize minframe_size(min_size.x+frame_size.x-client_size.x, min_size.y+frame_size.y-client_size.y ); - + m_frame->SetMinSize(minframe_size); - + if (frame_size.x < minframe_size.x || frame_size.y < minframe_size.y) sizer->Fit(m_frame); @@ -1883,21 +2335,21 @@ void wxFrameManager::Update() // and updates their internal rectangles. This should always be called // instead of calling m_frame->Layout() directly -void wxFrameManager::DoFrameLayout() +void wxAuiManager::DoFrameLayout() { m_frame->Layout(); - + int i, part_count; for (i = 0, part_count = m_uiparts.GetCount(); i < part_count; ++i) { - wxDockUIPart& part = m_uiparts.Item(i); + wxAuiDockUIPart& part = m_uiparts.Item(i); // get the rectangle of the UI part // originally, this code looked like this: // part.rect = wxRect(part.sizer_item->GetPosition(), // part.sizer_item->GetSize()); // this worked quite well, with one exception: the mdi - // client window had a "deferred" size variable + // client window had a "deferred" size variable // that returned the wrong size. It looks like // a bug in wx, because the former size of the window // was being returned. So, we will retrieve the part's @@ -1923,9 +2375,9 @@ void wxFrameManager::DoFrameLayout() part.rect.width += border; - if (part.type == wxDockUIPart::typeDock) + if (part.type == wxAuiDockUIPart::typeDock) part.dock->rect = part.rect; - if (part.type == wxDockUIPart::typePane) + if (part.type == wxAuiDockUIPart::typePane) part.pane->rect = part.rect; } } @@ -1935,20 +2387,20 @@ void wxFrameManager::DoFrameLayout() // rectangle of the pane in question, including decorations like // caption and border (if any). -wxDockUIPart* wxFrameManager::GetPanePart(wxWindow* wnd) +wxAuiDockUIPart* wxAuiManager::GetPanePart(wxWindow* wnd) { int i, part_count; for (i = 0, part_count = m_uiparts.GetCount(); i < part_count; ++i) { - wxDockUIPart& part = m_uiparts.Item(i); - if (part.type == wxDockUIPart::typePaneBorder && + wxAuiDockUIPart& part = m_uiparts.Item(i); + if (part.type == wxAuiDockUIPart::typePaneBorder && part.pane && part.pane->window == wnd) return ∂ } for (i = 0, part_count = m_uiparts.GetCount(); i < part_count; ++i) { - wxDockUIPart& part = m_uiparts.Item(i); - if (part.type == wxDockUIPart::typePane && + wxAuiDockUIPart& part = m_uiparts.Item(i); + if (part.type == wxAuiDockUIPart::typePane && part.pane && part.pane->window == wnd) return ∂ } @@ -1963,15 +2415,15 @@ wxDockUIPart* wxFrameManager::GetPanePart(wxWindow* wnd) // vertical docks). This value is necessary for calculating // fixel-pane/toolbar offsets when they are dragged. -int wxFrameManager::GetDockPixelOffset(wxPaneInfo& test) +int wxAuiManager::GetDockPixelOffset(wxAuiPaneInfo& test) { // the only way to accurately calculate the dock's // offset is to actually run a theoretical layout - + int i, part_count, dock_count; - wxDockInfoArray docks; - wxPaneInfoArray panes; - wxDockUIPartArray uiparts; + wxAuiDockInfoArray docks; + wxAuiPaneInfoArray panes; + wxAuiDockUIPartArray uiparts; CopyDocksAndPanes(docks, panes, m_docks, m_panes); panes.Add(test); @@ -1982,18 +2434,18 @@ int wxFrameManager::GetDockPixelOffset(wxPaneInfo& test) for (i = 0, part_count = uiparts.GetCount(); i < part_count; ++i) { - wxDockUIPart& part = uiparts.Item(i); + wxAuiDockUIPart& part = uiparts.Item(i); part.rect = wxRect(part.sizer_item->GetPosition(), part.sizer_item->GetSize()); - if (part.type == wxDockUIPart::typeDock) + if (part.type == wxAuiDockUIPart::typeDock) part.dock->rect = part.rect; } - + delete sizer; - + for (i = 0, dock_count = docks.GetCount(); i < dock_count; ++i) { - wxDockInfo& dock = docks.Item(i); + wxAuiDockInfo& dock = docks.Item(i); if (test.dock_direction == dock.dock_direction && test.dock_layer==dock.dock_layer && test.dock_row==dock.dock_row) { @@ -2013,8 +2465,8 @@ int wxFrameManager::GetDockPixelOffset(wxPaneInfo& test) // if a dock operation is allowed, the new dock position is copied into // the target info. If the operation was allowed, the function returns true. -static bool ProcessDockResult(wxPaneInfo& target, - const wxPaneInfo& new_pos) +bool wxAuiManager::ProcessDockResult(wxAuiPaneInfo& target, + const wxAuiPaneInfo& new_pos) { bool allowed = false; switch (new_pos.dock_direction) @@ -2037,7 +2489,7 @@ static bool ProcessDockResult(wxPaneInfo& target, // dropped, it performs the drop operation using the specified dock and pane // arrays. By specifying copied dock and pane arrays when calling, a "what-if" // scenario can be performed, giving precise coordinates for drop hints. -// If, however, wxFrameManager:m_docks and wxFrameManager::m_panes are specified +// If, however, wxAuiManager:m_docks and wxAuiManager::m_panes are specified // as parameters, the changes will be made to the main state arrays const int auiInsertRowPixels = 10; @@ -2045,20 +2497,20 @@ const int auiNewRowPixels = 40; const int auiLayerInsertPixels = 40; const int auiLayerInsertOffset = 5; -bool wxFrameManager::DoDrop(wxDockInfoArray& docks, - wxPaneInfoArray& panes, - wxPaneInfo& target, +bool wxAuiManager::DoDrop(wxAuiDockInfoArray& docks, + wxAuiPaneInfoArray& panes, + wxAuiPaneInfo& target, const wxPoint& pt, const wxPoint& offset) { wxSize cli_size = m_frame->GetClientSize(); - wxPaneInfo drop = target; + wxAuiPaneInfo drop = target; // The result should always be shown drop.Show(); - + // Check to see if the pane has been dragged outside of the window // (or near to the outside of the window), if so, dock it along the edge @@ -2067,49 +2519,38 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, int layer_insert_offset = auiLayerInsertOffset; if (target.IsToolbar()) layer_insert_offset = 0; - + if (pt.x < layer_insert_offset && pt.x > layer_insert_offset-auiLayerInsertPixels) { - int new_layer = wxMax(wxMax(GetMaxLayer(docks, wxAUI_DOCK_LEFT), - GetMaxLayer(docks, wxAUI_DOCK_BOTTOM)), - GetMaxLayer(docks, wxAUI_DOCK_TOP)) + 1; drop.Dock().Left(). - Layer(new_layer). Row(0). Position(pt.y - GetDockPixelOffset(drop) - offset.y); return ProcessDockResult(target, drop); } - else if (pt.y < layer_insert_offset && - pt.y > layer_insert_offset-auiLayerInsertPixels) + else if (pt.y < layer_insert_offset && + pt.y > layer_insert_offset-auiLayerInsertPixels) { - int new_layer = wxMax(wxMax(GetMaxLayer(docks, wxAUI_DOCK_TOP), - GetMaxLayer(docks, wxAUI_DOCK_LEFT)), - GetMaxLayer(docks, wxAUI_DOCK_RIGHT)) + 1; drop.Dock().Top(). - Layer(new_layer). Row(0). Position(pt.x - GetDockPixelOffset(drop) - offset.x); return ProcessDockResult(target, drop); } - else if (pt.x >= cli_size.x - layer_insert_offset && - pt.x < cli_size.x - layer_insert_offset + auiLayerInsertPixels) + else if (pt.x >= cli_size.x - layer_insert_offset && + pt.x < cli_size.x - layer_insert_offset + auiLayerInsertPixels) { - int new_layer = wxMax(wxMax(GetMaxLayer(docks, wxAUI_DOCK_RIGHT), - GetMaxLayer(docks, wxAUI_DOCK_TOP)), - GetMaxLayer(docks, wxAUI_DOCK_BOTTOM)) + 1; drop.Dock().Right(). - Layer(new_layer). Row(0). Position(pt.y - GetDockPixelOffset(drop) - offset.y); return ProcessDockResult(target, drop); } - else if (pt.y >= cli_size.y - layer_insert_offset && - pt.y < cli_size.y - layer_insert_offset + auiLayerInsertPixels) + else if (pt.y >= cli_size.y - layer_insert_offset && + pt.y < cli_size.y - layer_insert_offset + auiLayerInsertPixels) { - int new_layer = wxMax(wxMax(GetMaxLayer(docks, wxAUI_DOCK_BOTTOM), - GetMaxLayer(docks, wxAUI_DOCK_LEFT)), - GetMaxLayer(docks, wxAUI_DOCK_RIGHT)) + 1; + int new_layer = wxMax( wxMax( GetMaxLayer(docks, wxAUI_DOCK_BOTTOM), + GetMaxLayer(docks, wxAUI_DOCK_LEFT)), + GetMaxLayer(docks, wxAUI_DOCK_RIGHT)) + 1; + drop.Dock().Bottom(). Layer(new_layer). Row(0). @@ -2117,15 +2558,13 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, return ProcessDockResult(target, drop); } - - wxDockUIPart* part = HitTest(pt.x, pt.y); + wxAuiDockUIPart* part = HitTest(pt.x, pt.y); if (drop.IsToolbar()) { if (!part || !part->dock) return false; - // calculate the offset from where the dock begins // to the point where the user dropped the pane @@ -2141,17 +2580,40 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, // should float if being dragged over center pane windows if (!part->dock->fixed || part->dock->dock_direction == wxAUI_DOCK_CENTER) { - if ((m_flags & wxAUI_MGR_ALLOW_FLOATING) && + if (m_last_rect.IsEmpty() || m_last_rect.Contains(pt.x, pt.y )) + { + m_skipping = true; + } + else + { + if ((m_flags & wxAUI_MGR_ALLOW_FLOATING) && (drop.IsFloatable() || (part->dock->dock_direction != wxAUI_DOCK_CENTER && part->dock->dock_direction != wxAUI_DOCK_NONE))) - { - drop.Float(); + { + drop.Float(); + } + + m_skipping = false; + + return ProcessDockResult(target, drop); } - + + drop.Position(pt.x - GetDockPixelOffset(drop) - offset.x); + return ProcessDockResult(target, drop); } - + else + { + m_skipping = false; + } + + if (!m_skipping) + { + m_last_rect = part->dock->rect; + m_last_rect.Inflate( 15, 15 ); + } + drop.Dock(). Direction(part->dock->dock_direction). Layer(part->dock->dock_layer). @@ -2159,26 +2621,49 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, Position(dock_drop_offset); if (( - ((pt.y < part->dock->rect.y + 2) && part->dock->IsHorizontal()) || - ((pt.x < part->dock->rect.x + 2) && part->dock->IsVertical()) + ((pt.y < part->dock->rect.y + 1) && part->dock->IsHorizontal()) || + ((pt.x < part->dock->rect.x + 1) && part->dock->IsVertical()) ) && part->dock->panes.GetCount() > 1) { - int row = drop.dock_row; - DoInsertDockRow(panes, part->dock->dock_direction, - part->dock->dock_layer, - part->dock->dock_row); - drop.dock_row = row; + if ((part->dock->dock_direction == wxAUI_DOCK_TOP) || + (part->dock->dock_direction == wxAUI_DOCK_LEFT)) + { + int row = drop.dock_row; + DoInsertDockRow(panes, part->dock->dock_direction, + part->dock->dock_layer, + part->dock->dock_row); + drop.dock_row = row; + } + else + { + DoInsertDockRow(panes, part->dock->dock_direction, + part->dock->dock_layer, + part->dock->dock_row+1); + drop.dock_row = part->dock->dock_row+1; + } } - + if (( ((pt.y > part->dock->rect.y + part->dock->rect.height - 2 ) && part->dock->IsHorizontal()) || ((pt.x > part->dock->rect.x + part->dock->rect.width - 2 ) && part->dock->IsVertical()) ) && part->dock->panes.GetCount() > 1) { - DoInsertDockRow(panes, part->dock->dock_direction, - part->dock->dock_layer, - part->dock->dock_row+1); - drop.dock_row = part->dock->dock_row+1; + if ((part->dock->dock_direction == wxAUI_DOCK_TOP) || + (part->dock->dock_direction == wxAUI_DOCK_LEFT)) + { + DoInsertDockRow(panes, part->dock->dock_direction, + part->dock->dock_layer, + part->dock->dock_row+1); + drop.dock_row = part->dock->dock_row+1; + } + else + { + int row = drop.dock_row; + DoInsertDockRow(panes, part->dock->dock_direction, + part->dock->dock_layer, + part->dock->dock_row); + drop.dock_row = row; + } } return ProcessDockResult(target, drop); @@ -2186,20 +2671,20 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, - + if (!part) return false; - if (part->type == wxDockUIPart::typePaneBorder || - part->type == wxDockUIPart::typeCaption || - part->type == wxDockUIPart::typeGripper || - part->type == wxDockUIPart::typePaneButton || - part->type == wxDockUIPart::typePane || - part->type == wxDockUIPart::typePaneSizer || - part->type == wxDockUIPart::typeDockSizer || - part->type == wxDockUIPart::typeBackground) + if (part->type == wxAuiDockUIPart::typePaneBorder || + part->type == wxAuiDockUIPart::typeCaption || + part->type == wxAuiDockUIPart::typeGripper || + part->type == wxAuiDockUIPart::typePaneButton || + part->type == wxAuiDockUIPart::typePane || + part->type == wxAuiDockUIPart::typePaneSizer || + part->type == wxAuiDockUIPart::typeDockSizer || + part->type == wxAuiDockUIPart::typeBackground) { - if (part->type == wxDockUIPart::typeDockSizer) + if (part->type == wxAuiDockUIPart::typeDockSizer) { if (part->dock->panes.GetCount() != 1) return false; @@ -2257,12 +2742,12 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, part = GetPanePart(part->pane->window); if (!part) return false; - + bool insert_dock_row = false; int insert_row = part->pane->dock_row; int insert_dir = part->pane->dock_direction; int insert_layer = part->pane->dock_layer; - + switch (part->pane->dock_direction) { case wxAUI_DOCK_TOP: @@ -2298,7 +2783,7 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, if (new_row_pixels_y > (part->rect.height*20)/100) new_row_pixels_y = (part->rect.height*20)/100; - + // determine if the mouse pointer is in a location that // will cause a new row to be inserted. The hot spot positions // are along the borders of the center pane @@ -2328,7 +2813,7 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, } if (insert_dock_row) - { + { DoInsertDockRow(panes, insert_dir, insert_layer, insert_row); drop.Dock().Direction(insert_dir). Layer(insert_layer). @@ -2336,25 +2821,25 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, Position(0); return ProcessDockResult(target, drop); } - + // determine the mouse offset and the pane size, both in the // direction of the dock itself, and perpendicular to the dock - + int offset, size; - + if (part->orientation == wxVERTICAL) { offset = pt.y - part->rect.y; - size = part->rect.GetHeight(); + size = part->rect.GetHeight(); } else { offset = pt.x - part->rect.x; size = part->rect.GetWidth(); } - + int drop_position = part->pane->dock_pos; - + // if we are in the top/left part of the pane, // insert the pane before the pane being hovered over if (offset <= size/2) @@ -2391,145 +2876,140 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, } -void wxFrameManager::OnHintFadeTimer(wxTimerEvent& WXUNUSED(event)) +void wxAuiManager::OnHintFadeTimer(wxTimerEvent& WXUNUSED(event)) { -#ifdef __WXMSW__ - if (!m_hint_wnd || m_hint_fadeamt >= 50) + if (!m_hint_wnd || m_hint_fadeamt >= m_hint_fademax) { m_hint_fadetimer.Stop(); return; } - - m_hint_fadeamt += 5; - MakeWindowTransparent(m_hint_wnd, m_hint_fadeamt); + + m_hint_fadeamt += 4; +#if wxCHECK_VERSION(2,7,0) + m_hint_wnd->SetTransparent(m_hint_fadeamt); +#else + if (m_hint_wnd->IsKindOf(CLASSINFO(wxPseudoTransparentFrame))) + ((wxPseudoTransparentFrame *)m_hint_wnd)->SetTransparent(m_hint_fadeamt); #endif } -void wxFrameManager::ShowHint(const wxRect& rect) +void wxAuiManager::ShowHint(const wxRect& rect) { - #ifdef __WXMSW__ - - // First, determine if the operating system can handle transparency. - // Transparency is available on Win2000 and above - - static int os_type = -1; - static int ver_major = -1; - - if (os_type == -1) - os_type = ::wxGetOsVersion(&ver_major); - - // If the transparent flag is set, and the OS supports it, - // go ahead and use a transparent hint - - if ((m_flags & wxAUI_MGR_TRANSPARENT_HINT) != 0 && - os_type == wxWINDOWS_NT && ver_major >= 5) + if (m_hint_wnd) { + // if the hint rect is the same as last time, don't do anything if (m_last_hint == rect) return; m_last_hint = rect; + + m_hint_fadeamt = m_hint_fademax; - int initial_fade = 50; - if (m_flags & wxAUI_MGR_TRANSPARENT_HINT_FADE) - initial_fade = 0; - - if (m_hint_wnd == NULL) - { - wxPoint pt = rect.GetPosition(); - wxSize size = rect.GetSize(); - m_hint_wnd = new wxFrame(m_frame, -1, wxEmptyString, pt, size, - wxFRAME_TOOL_WINDOW | - wxFRAME_FLOAT_ON_PARENT | - wxFRAME_NO_TASKBAR | - wxNO_BORDER); + if ((m_flags & wxAUI_MGR_HINT_FADE) + && !((m_hint_wnd->IsKindOf(CLASSINFO(wxPseudoTransparentFrame))) && + (m_flags & wxAUI_MGR_NO_VENETIAN_BLINDS_FADE)) + ) + m_hint_fadeamt = 0; - MakeWindowTransparent(m_hint_wnd, initial_fade); - m_hint_wnd->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION)); + m_hint_wnd->SetSize(rect); + + if (!m_hint_wnd->IsShown()) m_hint_wnd->Show(); - // if we are dragging a floating pane, set the focus - // back to that floating pane (otherwise it becomes unfocused) - if (m_action == actionDragFloatingPane && m_action_window) - m_action_window->SetFocus(); + // if we are dragging a floating pane, set the focus + // back to that floating pane (otherwise it becomes unfocused) + if (m_action == actionDragFloatingPane && m_action_window) + m_action_window->SetFocus(); - } - else - { - wxPoint pt = rect.GetPosition(); - wxSize size = rect.GetSize(); - MakeWindowTransparent(m_hint_wnd, initial_fade); - m_hint_wnd->SetSize(pt.x, pt.y, rect.width, rect.height); - } - - if (m_flags & wxAUI_MGR_TRANSPARENT_HINT_FADE) +#if wxCHECK_VERSION(2,7,0) + m_hint_wnd->SetTransparent(m_hint_fadeamt); +#else + if (m_hint_wnd->IsKindOf(CLASSINFO(wxPseudoTransparentFrame))) + ((wxPseudoTransparentFrame*)m_hint_wnd)->SetTransparent(m_hint_fadeamt); +#endif + m_hint_wnd->Raise(); + + + if (m_hint_fadeamt != m_hint_fademax) // Only fade if we need to { // start fade in timer - m_hint_fadeamt = 0; m_hint_fadetimer.SetOwner(this, 101); m_hint_fadetimer.Start(5); } - - return; } - #endif - - if (m_last_hint != rect) + else // Not using a transparent hint window... { - // remove the last hint rectangle - m_last_hint = rect; - m_frame->Refresh(); - m_frame->Update(); - } - - wxScreenDC screendc; - wxRegion clip(1, 1, 10000, 10000); + if (!(m_flags & wxAUI_MGR_RECTANGLE_HINT)) + return; + + if (m_last_hint != rect) + { + // remove the last hint rectangle + m_last_hint = rect; + m_frame->Refresh(); + m_frame->Update(); + } - // clip all floating windows, so we don't draw over them - int i, pane_count; - for (i = 0, pane_count = m_panes.GetCount(); i < pane_count; ++i) - { - wxPaneInfo& pane = m_panes.Item(i); + wxScreenDC screendc; + wxRegion clip(1, 1, 10000, 10000); - if (pane.IsFloating() && - pane.frame->IsShown()) + // clip all floating windows, so we don't draw over them + int i, pane_count; + for (i = 0, pane_count = m_panes.GetCount(); i < pane_count; ++i) { - wxRect rect = pane.frame->GetRect(); - #ifdef __WXGTK__ - // wxGTK returns the client size, not the whole frame size - rect.width += 15; - rect.height += 35; - rect.Inflate(5); - #endif + wxAuiPaneInfo& pane = m_panes.Item(i); + + if (pane.IsFloating() && + pane.frame->IsShown()) + { + wxRect rect = pane.frame->GetRect(); +#ifdef __WXGTK__ + // wxGTK returns the client size, not the whole frame size + rect.width += 15; + rect.height += 35; + rect.Inflate(5); +#endif - clip.Subtract(rect); + clip.Subtract(rect); + } } - } - screendc.SetClippingRegion(clip); + // As we can only hide the hint by redrawing the managed window, we + // need to clip the region to the managed window too or we get + // nasty redrawn problems. + clip.Intersect(m_frame->GetRect()); - wxBitmap stipple = wxPaneCreateStippleBitmap(); - wxBrush brush(stipple); - screendc.SetBrush(brush); - screendc.SetPen(*wxTRANSPARENT_PEN); + screendc.SetClippingRegion(clip); - screendc.DrawRectangle(rect.x, rect.y, 5, rect.height); - screendc.DrawRectangle(rect.x+5, rect.y, rect.width-10, 5); - screendc.DrawRectangle(rect.x+rect.width-5, rect.y, 5, rect.height); - screendc.DrawRectangle(rect.x+5, rect.y+rect.height-5, rect.width-10, 5); + wxBitmap stipple = wxPaneCreateStippleBitmap(); + wxBrush brush(stipple); + screendc.SetBrush(brush); + screendc.SetPen(*wxTRANSPARENT_PEN); + + screendc.DrawRectangle(rect.x, rect.y, 5, rect.height); + screendc.DrawRectangle(rect.x+5, rect.y, rect.width-10, 5); + screendc.DrawRectangle(rect.x+rect.width-5, rect.y, 5, rect.height); + screendc.DrawRectangle(rect.x+5, rect.y+rect.height-5, rect.width-10, 5); + } } -void wxFrameManager::HideHint() -{ - // hides a transparent window hint (currently wxMSW only) - #ifdef __WXMSW__ +void wxAuiManager::HideHint() +{ + // hides a transparent window hint, if there is one if (m_hint_wnd) { - MakeWindowTransparent(m_hint_wnd, 0); + if (m_hint_wnd->IsShown()) + m_hint_wnd->Show(false); +#if wxCHECK_VERSION(2,7,0) + m_hint_wnd->SetTransparent(0); +#else + if (m_hint_wnd->IsKindOf(CLASSINFO(wxPseudoTransparentFrame))) + ((wxPseudoTransparentFrame *)m_hint_wnd)->SetTransparent(0); +#endif m_hint_fadetimer.Stop(); m_last_hint = wxRect(); return; } - #endif - + // hides a painted hint by redrawing the frame window if (!m_last_hint.IsEmpty()) { @@ -2547,7 +3027,7 @@ void wxFrameManager::HideHint() // DrawHintRect() then calls ShowHint() to indicate this drop rectangle. // "pane_window" is the window pointer of the pane being dragged, pt is // the mouse position, in client coordinates -void wxFrameManager::DrawHintRect(wxWindow* pane_window, +void wxAuiManager::DrawHintRect(wxWindow* pane_window, const wxPoint& pt, const wxPoint& offset) { @@ -2559,11 +3039,12 @@ void wxFrameManager::DrawHintRect(wxWindow* pane_window, // so that we don't modify the real thing on screen int i, pane_count, part_count; - wxDockInfoArray docks; - wxPaneInfoArray panes; - wxDockUIPartArray uiparts; - wxPaneInfo hint = GetPane(pane_window); + wxAuiDockInfoArray docks; + wxAuiPaneInfoArray panes; + wxAuiDockUIPartArray uiparts; + wxAuiPaneInfo hint = GetPane(pane_window); hint.name = wxT("__HINT__"); + hint.Show(); if (!hint.IsOk()) return; @@ -2599,9 +3080,9 @@ void wxFrameManager::DrawHintRect(wxWindow* pane_window, for (i = 0, part_count = uiparts.GetCount(); i < part_count; ++i) { - wxDockUIPart& part = uiparts.Item(i); + wxAuiDockUIPart& part = uiparts.Item(i); - if (part.type == wxDockUIPart::typePaneBorder && + if (part.type == wxAuiDockUIPart::typePaneBorder && part.pane && part.pane->name == wxT("__HINT__")) { rect = wxRect(part.sizer_item->GetPosition(), @@ -2609,7 +3090,7 @@ void wxFrameManager::DrawHintRect(wxWindow* pane_window, break; } } - + delete sizer; if (rect.IsEmpty()) @@ -2623,27 +3104,64 @@ void wxFrameManager::DrawHintRect(wxWindow* pane_window, ShowHint(rect); } -void wxFrameManager::OnFloatingPaneMoveStart(wxWindow* wnd) +void wxAuiManager::OnFloatingPaneMoveStart(wxWindow* wnd) { // try to find the pane - wxPaneInfo& pane = GetPane(wnd); + wxAuiPaneInfo& pane = GetPane(wnd); wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found")); - - #ifdef __WXMSW__ + +#if wxCHECK_VERSION(2,7,0) if (m_flags & wxAUI_MGR_TRANSPARENT_DRAG) - MakeWindowTransparent(pane.frame, 150); - #endif + pane.frame->SetTransparent(150); +#endif } -void wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd) +void wxAuiManager::OnFloatingPaneMoving(wxWindow* wnd, wxDirection dir) { // try to find the pane - wxPaneInfo& pane = GetPane(wnd); + wxAuiPaneInfo& pane = GetPane(wnd); wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found")); - + wxPoint pt = ::wxGetMousePosition(); + +#if 0 + // Adapt pt to direction + if (dir == wxNORTH) + { + // move to pane's upper border + wxPoint pos( 0,0 ); + pos = wnd->ClientToScreen( pos ); + pt.y = pos.y; + // and some more pixels for the title bar + pt.y -= 5; + } else + if (dir == wxWEST) + { + // move to pane's left border + wxPoint pos( 0,0 ); + pos = wnd->ClientToScreen( pos ); + pt.x = pos.x; + } else + if (dir == wxEAST) + { + // move to pane's right border + wxPoint pos( wnd->GetSize().x, 0 ); + pos = wnd->ClientToScreen( pos ); + pt.x = pos.x; + } else + if (dir == wxSOUTH) + { + // move to pane's bottom border + wxPoint pos( 0, wnd->GetSize().y ); + pos = wnd->ClientToScreen( pos ); + pt.y = pos.y; + } +#else + wxUnusedVar(dir); +#endif + wxPoint client_pt = m_frame->ScreenToClient(pt); - + // calculate the offset from the upper left-hand corner // of the frame to the mouse pointer wxPoint frame_pos = pane.frame->GetPosition(); @@ -2654,11 +3172,11 @@ void wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd) { if (m_action == actionDragFloatingPane) { - wxDockInfoArray docks; - wxPaneInfoArray panes; - wxDockUIPartArray uiparts; - wxPaneInfo hint = pane; - + wxAuiDockInfoArray docks; + wxAuiPaneInfoArray panes; + wxAuiDockUIPartArray uiparts; + wxAuiPaneInfo hint = pane; + CopyDocksAndPanes(docks, panes, m_docks, m_panes); // find out where the new pane would be @@ -2666,14 +3184,14 @@ void wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd) return; if (hint.IsFloating()) return; - + pane = hint; m_action = actionDragToolbarPane; m_action_window = pane.window; - + Update(); } - + return; } @@ -2689,104 +3207,153 @@ void wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd) DrawHintRect(wnd, client_pt, action_offset); - #ifdef __WXGTK__ +#ifdef __WXGTK__ // this cleans up some screen artifacts that are caused on GTK because // we aren't getting the exact size of the window (see comment // in DrawHintRect) //Refresh(); - #endif - - +#endif + + // reduces flicker m_frame->Update(); } -void wxFrameManager::OnFloatingPaneMoved(wxWindow* wnd) +void wxAuiManager::OnFloatingPaneMoved(wxWindow* wnd, wxDirection dir) { // try to find the pane - wxPaneInfo& pane = GetPane(wnd); + wxAuiPaneInfo& pane = GetPane(wnd); wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found")); - + wxPoint pt = ::wxGetMousePosition(); + +#if 0 + // Adapt pt to direction + if (dir == wxNORTH) + { + // move to pane's upper border + wxPoint pos( 0,0 ); + pos = wnd->ClientToScreen( pos ); + pt.y = pos.y; + // and some more pixels for the title bar + pt.y -= 10; + } else + if (dir == wxWEST) + { + // move to pane's left border + wxPoint pos( 0,0 ); + pos = wnd->ClientToScreen( pos ); + pt.x = pos.x; + } else + if (dir == wxEAST) + { + // move to pane's right border + wxPoint pos( wnd->GetSize().x, 0 ); + pos = wnd->ClientToScreen( pos ); + pt.x = pos.x; + } else + if (dir == wxSOUTH) + { + // move to pane's bottom border + wxPoint pos( 0, wnd->GetSize().y ); + pos = wnd->ClientToScreen( pos ); + pt.y = pos.y; + } +#else + wxUnusedVar(dir); +#endif + wxPoint client_pt = m_frame->ScreenToClient(pt); - + // calculate the offset from the upper left-hand corner // of the frame to the mouse pointer wxPoint frame_pos = pane.frame->GetPosition(); wxPoint action_offset(pt.x-frame_pos.x, pt.y-frame_pos.y); - + // if a key modifier is pressed while dragging the frame, // don't dock the window - if (wxGetKeyState(WXK_CONTROL) || wxGetKeyState(WXK_ALT)) + if (!wxGetKeyState(WXK_CONTROL) && !wxGetKeyState(WXK_ALT)) { - HideHint(); - return; + // do the drop calculation + DoDrop(m_docks, m_panes, pane, client_pt, action_offset); } - - // do the drop calculation - DoDrop(m_docks, m_panes, pane, client_pt, action_offset); - // if the pane is still floating, update it's floating // position (that we store) if (pane.IsFloating()) { pane.floating_pos = pane.frame->GetPosition(); - - #ifdef __WXMSW__ + +#if wxCHECK_VERSION(2,7,0) if (m_flags & wxAUI_MGR_TRANSPARENT_DRAG) - MakeWindowTransparent(pane.frame, 255); - #endif + pane.frame->SetTransparent(255); +#endif + } else if(m_has_maximized) { + RestoreMaximizedPane(); } - + Update(); - + HideHint(); } -void wxFrameManager::OnFloatingPaneResized(wxWindow* wnd, const wxSize& size) +void wxAuiManager::OnFloatingPaneResized(wxWindow* wnd, const wxSize& size) { // try to find the pane - wxPaneInfo& pane = GetPane(wnd); + wxAuiPaneInfo& pane = GetPane(wnd); wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found")); - + pane.floating_size = size; } -void wxFrameManager::OnFloatingPaneClosed(wxWindow* wnd) + +void wxAuiManager::OnFloatingPaneClosed(wxWindow* wnd, wxCloseEvent& evt) { // try to find the pane - wxPaneInfo& pane = GetPane(wnd); + wxAuiPaneInfo& pane = GetPane(wnd); wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found")); - // reparent the pane window back to us and - // prepare the frame window for destruction - pane.window->Show(false); - pane.window->Reparent(m_frame); - pane.frame = NULL; - pane.Hide(); + + // fire pane close event + wxAuiManagerEvent e(wxEVT_AUI_PANECLOSE); + e.SetPane(&pane); + e.SetCanVeto(evt.CanVeto()); + ProcessMgrEvent(e); + + if (e.GetVeto()) + { + evt.Veto(); + return; + } + else + { + ClosePane(pane); + } } -void wxFrameManager::OnFloatingPaneActivated(wxWindow* wnd) + + +void wxAuiManager::OnFloatingPaneActivated(wxWindow* wnd) { if (GetFlags() & wxAUI_MGR_ALLOW_ACTIVE_PANE) { // try to find the pane - wxPaneInfo& pane = GetPane(wnd); - wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found")); + wxASSERT_MSG(GetPane(wnd).IsOk(), wxT("Pane window not found")); SetActivePane(m_panes, wnd); Repaint(); } } -// Render() draws all of the pane captions, sashes, +// OnRender() draws all of the pane captions, sashes, // backgrounds, captions, grippers, pane borders and buttons. // It renders the entire user interface. -void wxFrameManager::Render(wxDC* dc) +void wxAuiManager::OnRender(wxAuiManagerEvent& evt) { + wxDC* dc = evt.GetDC(); + #ifdef __WXMAC__ dc->Clear() ; #endif @@ -2794,39 +3361,53 @@ void wxFrameManager::Render(wxDC* dc) for (i = 0, part_count = m_uiparts.GetCount(); i < part_count; ++i) { - wxDockUIPart& part = m_uiparts.Item(i); + wxAuiDockUIPart& part = m_uiparts.Item(i); // don't draw hidden pane items if (part.sizer_item && !part.sizer_item->IsShown()) continue; - + switch (part.type) { - case wxDockUIPart::typeDockSizer: - case wxDockUIPart::typePaneSizer: - m_art->DrawSash(*dc, part.orientation, part.rect); + case wxAuiDockUIPart::typeDockSizer: + case wxAuiDockUIPart::typePaneSizer: + m_art->DrawSash(*dc, m_frame, part.orientation, part.rect); break; - case wxDockUIPart::typeBackground: - m_art->DrawBackground(*dc, part.orientation, part.rect); + case wxAuiDockUIPart::typeBackground: + m_art->DrawBackground(*dc, m_frame, part.orientation, part.rect); break; - case wxDockUIPart::typeCaption: - m_art->DrawCaption(*dc, part.pane->caption, part.rect, *part.pane); + case wxAuiDockUIPart::typeCaption: + m_art->DrawCaption(*dc, m_frame, part.pane->caption, part.rect, *part.pane); break; - case wxDockUIPart::typeGripper: - m_art->DrawGripper(*dc, part.rect, *part.pane); - break; - case wxDockUIPart::typePaneBorder: - m_art->DrawBorder(*dc, part.rect, *part.pane); + case wxAuiDockUIPart::typeGripper: + m_art->DrawGripper(*dc, m_frame, part.rect, *part.pane); break; - case wxDockUIPart::typePaneButton: - m_art->DrawPaneButton(*dc, part.button->button_id, + case wxAuiDockUIPart::typePaneBorder: + m_art->DrawBorder(*dc, m_frame, part.rect, *part.pane); + break; + case wxAuiDockUIPart::typePaneButton: + m_art->DrawPaneButton(*dc, m_frame, part.button->button_id, wxAUI_BUTTON_STATE_NORMAL, part.rect, *part.pane); break; } } } -void wxFrameManager::Repaint(wxDC* dc) + +// Render() fire a render event, which is normally handled by +// wxAuiManager::OnRender(). This allows the render function to +// be overridden via the render event. This can be useful for paintin +// custom graphics in the main window. Default behavior can be +// invoked in the overridden function by calling OnRender() + +void wxAuiManager::Render(wxDC* dc) +{ + wxAuiManagerEvent e(wxEVT_AUI_RENDER); + e.SetDC(dc); + ProcessMgrEvent(e); +} + +void wxAuiManager::Repaint(wxDC* dc) { #ifdef __WXMAC__ if ( dc == NULL ) @@ -2863,13 +3444,13 @@ void wxFrameManager::Repaint(wxDC* dc) delete client_dc; } -void wxFrameManager::OnPaint(wxPaintEvent& WXUNUSED(event)) +void wxAuiManager::OnPaint(wxPaintEvent& WXUNUSED(event)) { wxPaintDC dc(m_frame); Repaint(&dc); } -void wxFrameManager::OnEraseBackground(wxEraseEvent& event) +void wxAuiManager::OnEraseBackground(wxEraseEvent& event) { #ifdef __WXMAC__ event.Skip() ; @@ -2878,30 +3459,31 @@ void wxFrameManager::OnEraseBackground(wxEraseEvent& event) #endif } -void wxFrameManager::OnSize(wxSizeEvent& WXUNUSED(event)) +void wxAuiManager::OnSize(wxSizeEvent& event) { if (m_frame) { DoFrameLayout(); Repaint(); } + event.Skip(); } -void wxFrameManager::OnSetCursor(wxSetCursorEvent& event) +void wxAuiManager::OnSetCursor(wxSetCursorEvent& event) { // determine cursor - wxDockUIPart* part = HitTest(event.GetX(), event.GetY()); + wxAuiDockUIPart* part = HitTest(event.GetX(), event.GetY()); wxCursor cursor = wxNullCursor; if (part) { - if (part->type == wxDockUIPart::typeDockSizer || - part->type == wxDockUIPart::typePaneSizer) + if (part->type == wxAuiDockUIPart::typeDockSizer || + part->type == wxAuiDockUIPart::typePaneSizer) { // a dock may not be resized if it has a single // pane which is not resizable - if (part->type == wxDockUIPart::typeDockSizer && part->dock && + if (part->type == wxAuiDockUIPart::typeDockSizer && part->dock && part->dock->panes.GetCount() == 1 && part->dock->panes.Item(0)->IsFixed()) return; @@ -2915,24 +3497,24 @@ void wxFrameManager::OnSetCursor(wxSetCursorEvent& event) else cursor = wxCursor(wxCURSOR_SIZENS); } - else if (part->type == wxDockUIPart::typeGripper) + else if (part->type == wxAuiDockUIPart::typeGripper) { cursor = wxCursor(wxCURSOR_SIZING); } } - + event.SetCursor(cursor); } -void wxFrameManager::UpdateButtonOnScreen(wxDockUIPart* button_ui_part, +void wxAuiManager::UpdateButtonOnScreen(wxAuiDockUIPart* button_ui_part, const wxMouseEvent& event) { - wxDockUIPart* hit_test = HitTest(event.GetX(), event.GetY()); + wxAuiDockUIPart* hit_test = HitTest(event.GetX(), event.GetY()); int state = wxAUI_BUTTON_STATE_NORMAL; - + if (hit_test == button_ui_part) { if (event.LeftDown()) @@ -2955,27 +3537,30 @@ void wxFrameManager::UpdateButtonOnScreen(wxDockUIPart* button_ui_part, if (pt.x != 0 || pt.y != 0) cdc.SetDeviceOrigin(pt.x, pt.y); - m_art->DrawPaneButton(cdc, - button_ui_part->button->button_id, - state, - button_ui_part->rect, - *hit_test->pane); + if (hit_test->pane) + { + m_art->DrawPaneButton(cdc, m_frame, + button_ui_part->button->button_id, + state, + button_ui_part->rect, + *hit_test->pane); + } } -void wxFrameManager::OnLeftDown(wxMouseEvent& event) +void wxAuiManager::OnLeftDown(wxMouseEvent& event) { - wxDockUIPart* part = HitTest(event.GetX(), event.GetY()); + wxAuiDockUIPart* part = HitTest(event.GetX(), event.GetY()); if (part) { - if (part->dock && part->dock->dock_direction == wxAUI_DOCK_CENTER) - return; - - if (part->type == wxDockUIPart::typeDockSizer || - part->type == wxDockUIPart::typePaneSizer) + if (part->type == wxAuiDockUIPart::typeDockSizer || + part->type == wxAuiDockUIPart::typePaneSizer) { + if (part->dock && part->dock->dock_direction == wxAUI_DOCK_CENTER) + return; + // a dock may not be resized if it has a single // pane which is not resizable - if (part->type == wxDockUIPart::typeDockSizer && part->dock && + if (part->type == wxAuiDockUIPart::typeDockSizer && part->dock && part->dock->panes.GetCount() == 1 && part->dock->panes.Item(0)->IsFixed()) return; @@ -2992,7 +3577,7 @@ void wxFrameManager::OnLeftDown(wxMouseEvent& event) event.m_y - part->rect.y); m_frame->CaptureMouse(); } - else if (part->type == wxDockUIPart::typePaneButton) + else if (part->type == wxAuiDockUIPart::typePaneButton) { m_action = actionClickButton; m_action_part = part; @@ -3001,9 +3586,12 @@ void wxFrameManager::OnLeftDown(wxMouseEvent& event) UpdateButtonOnScreen(part, event); } - else if (part->type == wxDockUIPart::typeCaption || - part->type == wxDockUIPart::typeGripper) + else if (part->type == wxAuiDockUIPart::typeCaption || + part->type == wxAuiDockUIPart::typeGripper) { + if (part->dock && part->dock->dock_direction == wxAUI_DOCK_CENTER) + return; + if (GetFlags() & wxAUI_MGR_ALLOW_ACTIVE_PANE) { // set the caption as active @@ -3036,7 +3624,7 @@ void wxFrameManager::OnLeftDown(wxMouseEvent& event) } -void wxFrameManager::OnLeftUp(wxMouseEvent& event) +void wxAuiManager::OnLeftUp(wxMouseEvent& event) { if (m_action == actionResize) { @@ -3047,7 +3635,7 @@ void wxFrameManager::OnLeftUp(wxMouseEvent& event) DrawResizeHint(dc, m_action_hintrect); // resize the dock or the pane - if (m_action_part && m_action_part->type==wxDockUIPart::typeDockSizer) + if (m_action_part && m_action_part->type==wxAuiDockUIPart::typeDockSizer) { wxRect& rect = m_action_part->dock->rect; @@ -3076,10 +3664,10 @@ void wxFrameManager::OnLeftUp(wxMouseEvent& event) Repaint(NULL); } else if (m_action_part && - m_action_part->type == wxDockUIPart::typePaneSizer) + m_action_part->type == wxAuiDockUIPart::typePaneSizer) { - wxDockInfo& dock = *m_action_part->dock; - wxPaneInfo& pane = *m_action_part->pane; + wxAuiDockInfo& dock = *m_action_part->dock; + wxAuiPaneInfo& pane = *m_action_part->pane; int total_proportion = 0; int dock_pixels = 0; @@ -3093,7 +3681,7 @@ void wxFrameManager::OnLeftUp(wxMouseEvent& event) event.m_y - m_action_offset.y); // determine the pane rectangle by getting the pane part - wxDockUIPart* pane_part = GetPanePart(pane.window); + wxAuiDockUIPart* pane_part = GetPanePart(pane.window); wxASSERT_MSG(pane_part, wxT("Pane border part not found -- shouldn't happen")); @@ -3117,16 +3705,16 @@ void wxFrameManager::OnLeftUp(wxMouseEvent& event) int pane_position = -1; for (i = 0; i < dock_pane_count; ++i) { - wxPaneInfo& p = *dock.panes.Item(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 @@ -3142,7 +3730,7 @@ void wxFrameManager::OnLeftUp(wxMouseEvent& event) 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 @@ -3150,19 +3738,19 @@ void wxFrameManager::OnLeftUp(wxMouseEvent& event) int borrow_pane = -1; for (i = pane_position+1; i < dock_pane_count; ++i) { - wxPaneInfo& p = *dock.panes.Item(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) { @@ -3172,10 +3760,10 @@ void wxFrameManager::OnLeftUp(wxMouseEvent& event) // 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, @@ -3183,7 +3771,7 @@ void wxFrameManager::OnLeftUp(wxMouseEvent& event) if (pane.min_size.IsFullySpecified()) { min_size = 0; - + if (pane.HasBorder()) min_size += (pane_border_size*2); @@ -3199,8 +3787,8 @@ void wxFrameManager::OnLeftUp(wxMouseEvent& event) 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 @@ -3208,75 +3796,75 @@ void wxFrameManager::OnLeftUp(wxMouseEvent& event) 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) + else if (m_action == actionClickButton) { m_hover_button = NULL; - m_frame->ReleaseMouse(); + m_frame->ReleaseMouse(); UpdateButtonOnScreen(m_action_part, event); // make sure we're still over the item that was originally clicked if (m_action_part == HitTest(event.GetX(), event.GetY())) - { + { // fire button-click event - wxFrameManagerEvent e(wxEVT_AUI_PANEBUTTON); + wxAuiManagerEvent e(wxEVT_AUI_PANEBUTTON); e.SetPane(m_action_part->pane); e.SetButton(m_action_part->button->button_id); ProcessMgrEvent(e); } } - else if (m_action == actionClickCaption) + else if (m_action == actionClickCaption) { m_frame->ReleaseMouse(); } - else if (m_action == actionDragFloatingPane) + else if (m_action == actionDragFloatingPane) { m_frame->ReleaseMouse(); } - else if (m_action == actionDragToolbarPane) + else if (m_action == actionDragToolbarPane) { m_frame->ReleaseMouse(); - wxPaneInfo& pane = GetPane(m_action_window); + wxAuiPaneInfo& pane = GetPane(m_action_window); wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found")); - + // save the new positions - wxDockInfoPtrArray docks; + wxAuiDockInfoPtrArray docks; FindDocks(m_docks, pane.dock_direction, pane.dock_layer, pane.dock_row, docks); if (docks.GetCount() == 1) { - wxDockInfo& dock = *docks.Item(0); - + wxAuiDockInfo& dock = *docks.Item(0); + wxArrayInt pane_positions, pane_sizes; GetPanePositionsAndSizes(dock, pane_positions, pane_sizes); - + int i, dock_pane_count = dock.panes.GetCount(); for (i = 0; i < dock_pane_count; ++i) dock.panes.Item(i)->dock_pos = pane_positions[i]; } - - pane.state &= ~wxPaneInfo::actionPane; + + pane.state &= ~wxAuiPaneInfo::actionPane; Update(); } - else + else { event.Skip(); } @@ -3286,20 +3874,20 @@ void wxFrameManager::OnLeftUp(wxMouseEvent& event) } -void wxFrameManager::OnMotion(wxMouseEvent& event) +void wxAuiManager::OnMotion(wxMouseEvent& event) { // sometimes when Update() is called from inside this method, // a spurious mouse move event is generated; this check will make // sure that only real mouse moves will get anywhere in this method; // this appears to be a bug somewhere, and I don't know where the // mouse move event is being generated. only verified on MSW - + wxPoint mouse_pos = event.GetPosition(); if (m_last_mouse_move == mouse_pos) return; m_last_mouse_move = mouse_pos; - + if (m_action == actionResize) { wxPoint pos = m_action_part->rect.GetPosition(); @@ -3317,23 +3905,23 @@ void wxFrameManager::OnMotion(wxMouseEvent& event) 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); - + // caption has been clicked. we need to check if the mouse // is now being dragged. if it is, we need to change the // mouse action to 'drag' if (abs(event.m_x - m_action_start.x) > drag_x_threshold || - abs(event.m_y - m_action_start.y) > drag_y_threshold) + abs(event.m_y - m_action_start.y) > drag_y_threshold) { - wxPaneInfo* pane_info = m_action_part->pane; + wxAuiPaneInfo* pane_info = m_action_part->pane; if (!pane_info->IsToolbar()) { if ((m_flags & wxAUI_MGR_ALLOW_FLOATING) && - pane_info->IsFloatable()) + pane_info->IsFloatable()) { m_action = actionDragFloatingPane; @@ -3341,12 +3929,16 @@ void wxFrameManager::OnMotion(wxMouseEvent& event) wxPoint pt = m_frame->ClientToScreen(event.GetPosition()); pane_info->floating_pos = wxPoint(pt.x - m_action_offset.x, pt.y - m_action_offset.y); + // float the window + if(pane_info->IsMaximized()) { + RestorePane(*pane_info); + } pane_info->Float(); Update(); m_action_window = pane_info->frame; - + // action offset is used here to make it feel "natural" to the user // to drag a docked pane and suddenly have it become a floating frame. // Sometimes, however, the offset where the user clicked on the docked @@ -3364,22 +3956,24 @@ void wxFrameManager::OnMotion(wxMouseEvent& event) } } } - else if (m_action == actionDragFloatingPane) + else if (m_action == actionDragFloatingPane) { - wxPoint pt = m_frame->ClientToScreen(event.GetPosition()); - m_action_window->Move(pt.x - m_action_offset.x, - pt.y - m_action_offset.y); + if(m_action_window) { + wxPoint pt = m_frame->ClientToScreen(event.GetPosition()); + m_action_window->Move(pt.x - m_action_offset.x, + pt.y - m_action_offset.y); + } } - else if (m_action == actionDragToolbarPane) + else if (m_action == actionDragToolbarPane) { - wxPaneInfo& pane = GetPane(m_action_window); + wxAuiPaneInfo& pane = GetPane(m_action_window); wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found")); - pane.state |= wxPaneInfo::actionPane; + pane.state |= wxAuiPaneInfo::actionPane; wxPoint pt = event.GetPosition(); DoDrop(m_docks, m_panes, pane, pt, m_action_offset); - + // if DoDrop() decided to float the pane, set up // the floating pane's initial position if (pane.IsFloating()) @@ -3388,38 +3982,42 @@ void wxFrameManager::OnMotion(wxMouseEvent& event) pane.floating_pos = wxPoint(pt.x - m_action_offset.x, pt.y - m_action_offset.y); } - + // this will do the actiual move operation; // in the case that the pane has been floated, // this call will create the floating pane // and do the reparenting Update(); - + // if the pane has been floated, change the mouse // action actionDragFloatingPane so that subsequent // EVT_MOTION() events will move the floating pane if (pane.IsFloating()) { - pane.state &= ~wxPaneInfo::actionPane; + pane.state &= ~wxAuiPaneInfo::actionPane; m_action = actionDragFloatingPane; m_action_window = pane.frame; } - } - else + } + else { - wxDockUIPart* part = HitTest(event.GetX(), event.GetY()); - if (part && part->type == wxDockUIPart::typePaneButton) + wxAuiDockUIPart* part = HitTest(event.GetX(), event.GetY()); + if (part && part->type == wxAuiDockUIPart::typePaneButton) { if (part != m_hover_button) { // make the old button normal if (m_hover_button) + { UpdateButtonOnScreen(m_hover_button, event); - + Repaint(); + } + // mouse is over a button, so repaint the // button in hover mode UpdateButtonOnScreen(part, event); m_hover_button = part; + } } else @@ -3437,7 +4035,7 @@ void wxFrameManager::OnMotion(wxMouseEvent& event) } } -void wxFrameManager::OnLeaveWindow(wxMouseEvent& WXUNUSED(event)) +void wxAuiManager::OnLeaveWindow(wxMouseEvent& WXUNUSED(event)) { if (m_hover_button) { @@ -3446,10 +4044,10 @@ void wxFrameManager::OnLeaveWindow(wxMouseEvent& WXUNUSED(event)) } } -void wxFrameManager::OnChildFocus(wxChildFocusEvent& event) +void wxAuiManager::OnChildFocus(wxChildFocusEvent& event) { - // when a child pane has it's focus set, we should change the - // pane's active state to reflect this. (this is only true if + // when a child pane has it's focus set, we should change the + // pane's active state to reflect this. (this is only true if // active panes are allowed by the owner) if (GetFlags() & wxAUI_MGR_ALLOW_ACTIVE_PANE) { @@ -3459,21 +4057,59 @@ void wxFrameManager::OnChildFocus(wxChildFocusEvent& event) m_frame->Refresh(); } } + + event.Skip(); } // OnPaneButton() is an event handler that is called // when a pane button has been pressed. -void wxFrameManager::OnPaneButton(wxFrameManagerEvent& event) +void wxAuiManager::OnPaneButton(wxAuiManagerEvent& evt) { - wxPaneInfo& pane = *(event.pane); - - if (event.button == wxPaneInfo::buttonClose) + wxASSERT_MSG(evt.pane, wxT("Pane Info passed to wxAuiManager::OnPaneButton must be non-null")); + + wxAuiPaneInfo& pane = *(evt.pane); + + if (evt.button == wxAUI_BUTTON_CLOSE) { - pane.Hide(); - Update(); + // fire pane close event + wxAuiManagerEvent e(wxEVT_AUI_PANECLOSE); + e.SetPane(evt.pane); + ProcessMgrEvent(e); + + if (!e.GetVeto()) + { + ClosePane(pane); + Update(); + } + } + else if (evt.button == wxAUI_BUTTON_MAXIMIZE_RESTORE && !pane.IsMaximized()) + { + // fire pane close event + wxAuiManagerEvent e(wxEVT_AUI_PANEMAXIMIZE); + e.SetPane(evt.pane); + ProcessMgrEvent(e); + + if (!e.GetVeto()) + { + MaximizePane(pane); + Update(); + } + } + else if (evt.button == wxAUI_BUTTON_MAXIMIZE_RESTORE && pane.IsMaximized()) + { + // fire pane close event + wxAuiManagerEvent e(wxEVT_AUI_PANERESTORE); + e.SetPane(evt.pane); + ProcessMgrEvent(e); + + if (!e.GetVeto()) + { + RestorePane(pane); + Update(); + } } - else if (event.button == wxPaneInfo::buttonPin) + else if (evt.button == wxAUI_BUTTON_PIN) { if ((m_flags & wxAUI_MGR_ALLOW_FLOATING) && pane.IsFloatable())