///////////////////////////////////////////////////////////////////////////////
-// 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
///////////////////////////////////////////////////////////////////////////////
#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"
wxPaneInfo wxNullPaneInfo;
wxDockInfo wxNullDockInfo;
DEFINE_EVENT_TYPE(wxEVT_AUI_PANEBUTTON)
+DEFINE_EVENT_TYPE(wxEVT_AUI_PANECLOSE)
+DEFINE_EVENT_TYPE(wxEVT_AUI_RENDER)
#ifdef __WXMAC__
// a few defines to avoid nameclashes
#include "wx/mac/private.h"
#endif
+IMPLEMENT_DYNAMIC_CLASS(wxFrameManagerEvent, 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; y<m_MaxHeight; y++)
+ {
+ // Reverse the order of the bottom 4 bits
+ int j=((y&8)?1:0)|((y&4)?2:0)|((y&2)?4:0)|((y&1)?8:0);
+ if ((j*16+8)<m_Amount)
+ m_Region.Union(0, y, m_MaxWidth, 1);
+ }
+ }
+ SetShape(m_Region);
+ Refresh();
+ }
+ return true;
+ }
+
+ void OnPaint(wxPaintEvent& WXUNUSED(event))
+ {
+ wxPaintDC dc(this);
+
+ if (m_Region.IsEmpty())
+ return;
+
+#ifdef __WXMAC__
+ dc.SetBrush(wxColour(128, 192, 255));
+#else
+ dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION));
+#endif
+ dc.SetPen(*wxTRANSPARENT_PEN);
+
+ wxRegionIterator upd(GetUpdateRegion()); // get the update rect list
+
+ while (upd)
+ {
+ wxRect rect(upd.GetRect());
+ dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
+
+ upd++;
+ }
+ }
+
+#ifdef __WXGTK__
+ void OnWindowCreate(wxWindowCreateEvent& WXUNUSED(event)) {m_CanSetShape=true; SetTransparent(0);}
+#endif
+
+ void OnSize(wxSizeEvent& event)
+ {
+ // We sometimes get surplus size events
+ if ((event.GetSize().GetWidth() == m_lastWidth) &&
+ (event.GetSize().GetHeight() == m_lastHeight))
+ {
+ event.Skip();
+ return;
+ }
+ m_lastWidth = event.GetSize().GetWidth();
+ m_lastHeight = event.GetSize().GetHeight();
+
+ SetTransparent(m_Amount);
+ m_Region.Intersect(0, 0, event.GetSize().GetWidth(),
+ event.GetSize().GetHeight());
+ SetShape(m_Region);
+ Refresh();
+ event.Skip();
+ }
+
+private:
+ wxByte m_Amount;
+ int m_MaxWidth;
+ int m_MaxHeight;
+ bool m_CanSetShape;
+ int m_lastWidth,m_lastHeight;
+
+ wxRegion m_Region;
+
+ DECLARE_DYNAMIC_CLASS(wxPseudoTransparentFrame)
+ DECLARE_EVENT_TABLE()
+};
+
+
+IMPLEMENT_DYNAMIC_CLASS( wxPseudoTransparentFrame, wxFrame )
+
+BEGIN_EVENT_TABLE(wxPseudoTransparentFrame, wxFrame)
+ EVT_PAINT(wxPseudoTransparentFrame::OnPaint)
+ EVT_SIZE(wxPseudoTransparentFrame::OnSize)
+#ifdef __WXGTK__
+ EVT_WINDOW_CREATE(wxPseudoTransparentFrame::OnWindowCreate)
+#endif
+END_EVENT_TABLE()
+
// -- static utility functions --
{
wxBitmap stipple = wxPaneCreateStippleBitmap();
wxBrush brush(stipple);
- dc.SetBrush(brush);
+ dc.SetBrush(brush);
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetLogicalFunction(wxXOR);
dc.DrawRectangle(rect);
}
-#ifdef __WXMSW__
-
-// on supported windows systems (Win2000 and greater), this function
-// will make a frame window transparent by a certain amount
-static void MakeWindowTransparent(wxWindow* wnd, int amount)
-{
- // this API call is not in all SDKs, only the newer ones, so
- // we will runtime bind this
- typedef DWORD (WINAPI *PSETLAYEREDWINDOWATTR)(HWND, DWORD, BYTE, DWORD);
- static PSETLAYEREDWINDOWATTR pSetLayeredWindowAttributes = NULL;
- static HMODULE h = NULL;
- HWND hwnd = (HWND)wnd->GetHWND();
-
- 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
{
wxPaneInfo& 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;
}
}
}
-// 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,
int dock_direction,
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)
{
}
// RemovePaneFromDocks() removes a pane window from all docks
-// with a possible exception specified by parameter "except"
+// with a possible exception specified by parameter "ex_cept"
static void RemovePaneFromDocks(wxDockInfoArray& docks,
wxPaneInfo& pane,
- wxDockInfo* except = NULL)
+ wxDockInfo* 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)
+ if (&d == ex_cept)
continue;
wxPaneInfo* pi = FindPaneInDock(d, pane.window);
if (pi)
}
-
+// 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(wxPaneInfoArray& panes, wxWindow* active_pane)
{
int i, pane_count;
BEGIN_EVENT_TABLE(wxFrameManager, wxEvtHandler)
EVT_AUI_PANEBUTTON(wxFrameManager::OnPaneButton)
+ EVT_AUI_RENDER(wxFrameManager::OnRender)
EVT_PAINT(wxFrameManager::OnPaint)
EVT_ERASE_BACKGROUND(wxFrameManager::OnEraseBackground)
EVT_SIZE(wxFrameManager::OnSize)
END_EVENT_TABLE()
-wxFrameManager::wxFrameManager(wxFrame* frame, unsigned int flags)
+wxFrameManager::wxFrameManager(wxWindow* managed_wnd, unsigned int flags)
{
m_action = actionNone;
m_last_mouse_move = wxPoint();
m_art = new wxDefaultDockArt;
m_hint_wnd = NULL;
m_flags = flags;
+ m_skipping = false;
- if (frame)
+ if (managed_wnd)
{
- SetFrame(frame);
+ SetManagedWindow(managed_wnd);
}
}
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
+
+ // 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)
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)
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;
}
}
-// SetFrame() is usually called once when the frame
+// don't use these anymore as they are deprecated
+// use Set/GetManagedFrame() instead
+void wxFrameManager::SetFrame(wxFrame* frame)
+{
+ SetManagedWindow((wxWindow*)frame);
+}
+
+wxFrame* wxFrameManager::GetFrame() const
+{
+ return (wxFrame*)m_frame;
+}
+
+
+
+
+// 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 wxFrameManager::SetManagedWindow(wxWindow* frame)
{
wxASSERT_MSG(frame, wxT("specified frame must be non-NULL"));
if (frame->IsKindOf(CLASSINFO(wxMDIParentFrame)))
{
wxMDIParentFrame* mdi_frame = (wxMDIParentFrame*)frame;
- wxMDIClientWindow* client_window = mdi_frame->GetClientWindow();
+ wxWindow* client_window = mdi_frame->GetClientWindow();
wxASSERT_MSG(client_window, wxT("Client window is NULL!"));
CenterPane().PaneBorder(false));
}
#endif
+
+ // 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
+
+ m_hint_fademax=50;
+
+ if (m_hint_wnd
+ // CanSetTransparent is only present in the 2.7.0 ABI. To allow this file to be easily used
+ // in a backported environment, conditionally compile this in.
+#if wxCHECK_VERSION(2,7,0)
+ && !m_hint_wnd->CanSetTransparent()
+#endif
+ )
+ {
+
+ m_hint_wnd->Close();
+ m_hint_wnd->Destroy();
+ m_hint_wnd = NULL;
+
+ // If we can convert it to a PseudoTransparent window, do so
+ 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;
+ }
}
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* wxFrameManager::GetManagedWindow() const
{
return m_frame;
}
// SetArtProvider() instructs wxFrameManager to use the
// specified art provider for all drawing calls. This allows
-// plugable look-and-feel features
+// plugable look-and-feel features. The pointer that is
+// passed to this method subsequently belongs to wxFrameManager,
+// and is deleted in the frame manager destructor
void wxFrameManager::SetArtProvider(wxDockArt* 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)
{
// check if the pane has a valid window
// 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;
button.button_id = wxPaneInfo::buttonClose;
pinfo.buttons.Add(button);
}
-
+
if (pinfo.best_size == wxDefaultSize &&
pinfo.window)
{
// 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
// correct?
pinfo.best_size.y++;
}
-
+
if (pinfo.min_size != wxDefaultSize)
{
if (pinfo.best_size.x < pinfo.min_size.x)
return AddPane(window, pinfo);
}
+bool wxFrameManager::AddPane(wxWindow* window,
+ const wxPaneInfo& pane_info,
+ const wxPoint& drop_pos)
+{
+ if (!AddPane(window, pane_info))
+ return false;
+
+ wxPaneInfo& pane = GetPane(window);
+
+ DoDrop(m_docks, m_panes, pane, drop_pos, wxPoint(0,0));
+
+ return true;
+}
+
bool wxFrameManager::InsertPane(wxWindow* window, const wxPaneInfo& pane_info,
int insert_level)
{
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);
{
return AddPane(window, pane_info);
}
- else
+ else
{
if (pane_info.IsFloating())
{
return true;
}
-
+
+// DetachPane() removes a pane from the frame manager. This
+// method will not destroy the window that is removed.
bool wxFrameManager::DetachPane(wxWindow* window)
{
int i, count;
for (i = 0, count = m_panes.GetCount(); i < count; ++i)
{
- wxPaneInfo& p = m_panes.Item(i);
+ wxPaneInfo& p = m_panes.Item(i);
if (p.window == window)
{
if (p.frame)
// 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
p.window->Reparent(m_frame);
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)
+ {
+ wxDockUIPart& part = m_uiparts.Item(pi);
+ if (part.pane == &p)
+ {
+ m_uiparts.RemoveAt(pi);
+ part_count--;
+ pi--;
+ continue;
+ }
+ }
+
m_panes.RemoveAt(i);
return true;
}
static wxString EscapeDelimiters(const wxString& s)
{
wxString result;
- result.Alloc(s.Length());
+ result.Alloc(s.length());
const wxChar* ch = s.c_str();
while (*ch)
{
return result;
}
+wxString wxFrameManager::SavePaneInfo(wxPaneInfo& 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 wxFrameManager::LoadPaneInfo(wxString pane_part, wxPaneInfo &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
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("|");
+ 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);
-
+
result += wxString::Format(wxT("dock_size(%d,%d,%d)=%d|"),
dock.dock_direction, dock.dock_layer,
dock.dock_row, dock.size);
}
-
+
return result;
}
{
wxString input = layout;
wxString part;
-
+
// check layout string version
part = input.BeforeFirst(wxT('|'));
input = input.AfterFirst(wxT('|'));
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)
// 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;
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(')'));
piece.BeforeFirst(wxT(',')).ToLong(&layer);
piece.AfterFirst(wxT(',')).ToLong(&row);
value.ToLong(&size);
-
+
wxDockInfo dock;
dock.dock_direction = dir;
dock.dock_layer = layer;
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(";"));
+
+ LoadPaneInfo(pane_part, pane);
- 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);
if (!p.IsOk())
{
// 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,
wxArrayInt& positions,
wxArrayInt& sizes)
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
wxPaneInfo& 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())
size += gripper_size;
if (pane.HasCaption())
- size += caption_size;
+ size += caption_size;
size += pane.best_size.y;
}
-
+
sizes.Add(size);
}
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;
wxPaneInfo& pane,
wxDockUIPartArray& uiparts,
bool spacer_only)
-{
+{
wxDockUIPart part;
wxSizerItem* sizer_item;
{
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;
{
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);
}
// 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())
{
pane_proportion = 0;
}
}
-
+
if (min_size != wxDefaultSize)
{
vert_pane_sizer->SetItemMinSize(
part.sizer_item = sizer_item;
uiparts.Add(part);
}
- else
+ else
{
sizer_item = cont->Add(horz_pane_sizer, pane_proportion, wxEXPAND);
}
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);
part.sizer_item = sizer_item;
uiparts.Add(part);
}
- else
+ else
{
for (pane_i = 0; pane_i < pane_count; ++pane_i)
{
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
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);
}
{
wxDockInfo& 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);
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)
}
}
}
-
+
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)
{
wxArrayInt pane_positions, pane_sizes;
GetPanePositionsAndSizes(dock, pane_positions, pane_sizes);
-
+
int offset = 0;
for (j = 0; j < dock_pane_count; ++j)
{
}
}
}
-
+
// 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();
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
{
// 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);
-
+
+ if (p.frame->IsShown())
+ p.frame->Show(false);
+
// reparent to m_frame and destroy the pane
p.window->Reparent(m_frame);
p.frame->SetSizer(NULL);
// 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
+ this,
+ 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
{
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
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,
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);
void wxFrameManager::DoFrameLayout()
{
m_frame->Layout();
-
+
int i, part_count;
for (i = 0, part_count = m_uiparts.GetCount(); i < part_count; ++i)
{
// 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
{
// 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;
if (part.type == wxDockUIPart::typeDock)
part.dock->rect = part.rect;
}
-
+
delete sizer;
-
+
for (i = 0, dock_count = docks.GetCount(); i < dock_count; ++i)
{
wxDockInfo& dock = docks.Item(i);
// 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,
+bool wxFrameManager::ProcessDockResult(wxPaneInfo& target,
const wxPaneInfo& new_pos)
{
bool allowed = false;
// 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
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).
return ProcessDockResult(target, drop);
}
-
wxDockUIPart* part = HitTest(pt.x, pt.y);
{
if (!part || !part->dock)
return false;
-
-
+
// calculate the offset from where the dock begins
// to the point where the user dropped the pane
int dock_drop_offset = 0;
// 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).
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);
-
+
if (!part)
return false;
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:
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
}
if (insert_dock_row)
- {
+ {
DoInsertDockRow(panes, insert_dir, insert_layer, insert_row);
drop.Dock().Direction(insert_dir).
Layer(insert_layer).
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)
void wxFrameManager::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)
{
- #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_flags & wxAUI_MGR_TRANSPARENT_HINT) != 0
+ && m_hint_wnd
+ // Finally, don't use a venetian blind effect if it's been specifically disabled
+ && !((m_hint_wnd->IsKindOf(CLASSINFO(wxPseudoTransparentFrame))) &&
+ (m_flags & wxAUI_MGR_DISABLE_VENETIAN_BLINDS))
+ )
{
if (m_last_hint == rect)
return;
m_last_hint = rect;
-
- 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);
-
- MakeWindowTransparent(m_hint_wnd, initial_fade);
- m_hint_wnd->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION));
+
+ m_hint_fadeamt = m_hint_fademax;
+ if ((m_flags & wxAUI_MGR_TRANSPARENT_HINT_FADE)
+ && !((m_hint_wnd->IsKindOf(CLASSINFO(wxPseudoTransparentFrame))) &&
+ (m_flags & wxAUI_MGR_DISABLE_VENETIAN_BLINDS_FADE))
+ )
+ m_hint_fadeamt = 0;
+
+ 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);
- // 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);
+ if (m_last_hint != rect)
+ {
+ // remove the last hint rectangle
+ m_last_hint = rect;
+ m_frame->Refresh();
+ m_frame->Update();
+ }
- if (pane.IsFloating() &&
- pane.frame->IsShown())
+ wxScreenDC screendc;
+ wxRegion clip(1, 1, 10000, 10000);
+
+ // 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
+ wxPaneInfo& pane = m_panes.Item(i);
- clip.Subtract(rect);
+ 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);
+ }
}
- }
- 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);
+
+ 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);
+ 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__
+{
+ // 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())
{
wxDockUIPartArray uiparts;
wxPaneInfo hint = GetPane(pane_window);
hint.name = wxT("__HINT__");
+ hint.Show();
if (!hint.IsOk())
return;
break;
}
}
-
+
delete sizer;
if (rect.IsEmpty())
// try to find the pane
wxPaneInfo& 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 wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd, wxDirection dir)
{
// try to find the pane
wxPaneInfo& 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;
+ }
+#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();
wxPaneInfoArray panes;
wxDockUIPartArray uiparts;
wxPaneInfo hint = pane;
-
+
CopyDocksAndPanes(docks, panes, m_docks, m_panes);
// find out where the new pane would be
return;
if (hint.IsFloating())
return;
-
+
pane = hint;
m_action = actionDragToolbarPane;
m_action_window = pane.window;
-
+
Update();
}
-
+
return;
}
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 wxFrameManager::OnFloatingPaneMoved(wxWindow* wnd, wxDirection dir)
{
// try to find the pane
wxPaneInfo& 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;
+ }
+#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
}
-
+
Update();
-
+
HideHint();
}
// try to find the pane
wxPaneInfo& pane = GetPane(wnd);
wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
-
+
pane.floating_size = size;
}
-void wxFrameManager::OnFloatingPaneClosed(wxWindow* wnd)
+
+void wxFrameManager::OnFloatingPaneClosed(wxWindow* wnd, wxCloseEvent& evt)
{
// try to find the pane
wxPaneInfo& 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
+ wxFrameManagerEvent e(wxEVT_AUI_PANECLOSE);
+ e.SetPane(&pane);
+ e.SetCanVeto(evt.CanVeto());
+ ProcessMgrEvent(e);
+
+ if (e.GetVeto())
+ {
+ evt.Veto();
+ return;
+ }
+ else
+ {
+ // reparent the pane window back to us and
+ // prepare the frame window for destruction
+ if (pane.window->IsShown())
+ pane.window->Show(false);
+ pane.window->Reparent(m_frame);
+ pane.frame = NULL;
+ pane.Hide();
+ }
}
+
+
void wxFrameManager::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 wxFrameManager::OnRender(wxFrameManagerEvent& evt)
{
+ wxDC* dc = evt.GetDC();
+
#ifdef __WXMAC__
dc->Clear() ;
#endif
// 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);
+ m_art->DrawSash(*dc, m_frame, part.orientation, part.rect);
break;
case wxDockUIPart::typeBackground:
- m_art->DrawBackground(*dc, part.orientation, part.rect);
+ 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);
+ 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;
+ m_art->DrawGripper(*dc, m_frame, part.rect, *part.pane);
+ break;
case wxDockUIPart::typePaneBorder:
- m_art->DrawBorder(*dc, part.rect, *part.pane);
+ m_art->DrawBorder(*dc, m_frame, part.rect, *part.pane);
break;
case wxDockUIPart::typePaneButton:
- m_art->DrawPaneButton(*dc, part.button->button_id,
+ m_art->DrawPaneButton(*dc, m_frame, part.button->button_id,
wxAUI_BUTTON_STATE_NORMAL, part.rect, *part.pane);
break;
}
}
}
+
+// Render() fire a render event, which is normally handled by
+// wxFrameManager::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 wxFrameManager::Render(wxDC* dc)
+{
+ wxFrameManagerEvent e(wxEVT_AUI_RENDER);
+ e.SetDC(dc);
+ ProcessMgrEvent(e);
+}
+
void wxFrameManager::Repaint(wxDC* dc)
{
#ifdef __WXMAC__
#endif
}
-void wxFrameManager::OnSize(wxSizeEvent& WXUNUSED(event))
+void wxFrameManager::OnSize(wxSizeEvent& event)
{
if (m_frame)
{
DoFrameLayout();
Repaint();
}
+ event.Skip();
}
cursor = wxCursor(wxCURSOR_SIZING);
}
}
-
+
event.SetCursor(cursor);
}
wxDockUIPart* hit_test = HitTest(event.GetX(), event.GetY());
int state = wxAUI_BUTTON_STATE_NORMAL;
-
+
if (hit_test == button_ui_part)
{
if (event.LeftDown())
else
state = wxAUI_BUTTON_STATE_HOVER;
}
- else
+ else
{
if (event.LeftDown())
state = wxAUI_BUTTON_STATE_HOVER;
if (pt.x != 0 || pt.y != 0)
cdc.SetDeviceOrigin(pt.x, pt.y);
- m_art->DrawPaneButton(cdc,
+ m_art->DrawPaneButton(cdc, m_frame,
button_ui_part->button->button_id,
state,
button_ui_part->rect,
wxPaneInfo& p = *dock.panes.Item(i);
if (p.window == pane.window)
pane_position = i;
-
+
// while we're at it, subtract the pane sash
// width from the dock width, because this would
// skew our proportion calculations
if (i > 0)
dock_pixels -= sash_size;
-
+
// also, the whole size (including decorations) of
// all fixed panes must also be subtracted, because they
// are not part of the proportion calculation
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
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)
{
// 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,
if (pane.min_size.IsFullySpecified())
{
min_size = 0;
-
+
if (pane.HasBorder())
min_size += (pane_border_size*2);
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
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);
e.SetPane(m_action_part->pane);
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);
wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
-
+
// save the new positions
wxDockInfoPtrArray docks;
FindDocks(m_docks, pane.dock_direction,
if (docks.GetCount() == 1)
{
wxDockInfo& 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;
Update();
}
- else
+ else
{
event.Skip();
}
// 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();
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;
if (!pane_info->IsToolbar())
{
if ((m_flags & wxAUI_MGR_ALLOW_FLOATING) &&
- pane_info->IsFloatable())
+ pane_info->IsFloatable())
{
m_action = actionDragFloatingPane;
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
}
}
}
- 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);
}
- else if (m_action == actionDragToolbarPane)
+ else if (m_action == actionDragToolbarPane)
{
wxPaneInfo& pane = GetPane(m_action_window);
wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
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())
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
m_action = actionDragFloatingPane;
m_action_window = pane.frame;
}
- }
- else
+ }
+ else
{
wxDockUIPart* part = HitTest(event.GetX(), event.GetY());
if (part && part->type == wxDockUIPart::typePaneButton)
void wxFrameManager::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)
{
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 wxFrameManager::OnPaneButton(wxFrameManagerEvent& evt)
{
- wxPaneInfo& pane = *(event.pane);
-
- if (event.button == wxPaneInfo::buttonClose)
+ wxASSERT_MSG(evt.pane, wxT("Pane Info passed to wxFrameManager::OnPaneButton must be non-null"));
+
+ wxPaneInfo& pane = *(evt.pane);
+
+ if (evt.button == wxPaneInfo::buttonClose)
{
- pane.Hide();
- Update();
+ // fire pane close event
+ wxFrameManagerEvent e(wxEVT_AUI_PANECLOSE);
+ e.SetPane(evt.pane);
+ ProcessMgrEvent(e);
+
+ if (!e.GetVeto())
+ {
+ pane.Hide();
+ Update();
+ }
}
- else if (event.button == wxPaneInfo::buttonPin)
+ else if (evt.button == wxPaneInfo::buttonPin)
{
if ((m_flags & wxAUI_MGR_ALLOW_FLOATING) &&
pane.IsFloatable())