X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/59cf2e4999e9ae9bcdc2a3093dec4ec27b50df5b..6d7b547184bfdcdf67790755deb0122050b1d728:/src/aui/framemanager.cpp?ds=sidebyside diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index 933aa5a75e..367bd69858 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -36,12 +36,9 @@ #include "wx/dcscreen.h" #include "wx/toolbar.h" #include "wx/mdi.h" + #include "wx/image.h" #endif -//#include "wx/dcbuffer.h" - -#include "wx/image.h" - WX_CHECK_BUILD_OPTIONS("wxAUI") #include "wx/arrimpl.cpp" @@ -55,6 +52,8 @@ WX_DEFINE_OBJARRAY(wxPaneInfoArray) 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 @@ -63,6 +62,109 @@ DEFINE_EVENT_TYPE(wxEVT_AUI_PANEBUTTON) #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; +#ifdef __WXGTK__ + m_CanSetShape = false; // have to wait for window create event on GTK +#else + m_CanSetShape = true; +#endif + SetTransparent(0); + } + + virtual bool SetTransparent(wxByte alpha) + { + if (m_CanSetShape) + { + int w=100; // some defaults + int h=100; + GetClientSize(&w, &h); + if ((alpha != m_Amount) || (m_MaxWidthGetHWND(); - - 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, (BYTE)amount, 2 /*LWA_ALPHA*/); -} - -#endif // CopyDocksAndPanes() - this utility function creates copies of @@ -333,7 +402,9 @@ static void RenumberDockRows(wxDockInfoPtrArray& docks) } - +// 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; @@ -359,6 +430,7 @@ static int PaneSortFunc(wxPaneInfo** p1, wxPaneInfo** p2) 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) @@ -372,7 +444,7 @@ BEGIN_EVENT_TABLE(wxFrameManager, wxEvtHandler) 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(); @@ -381,9 +453,9 @@ wxFrameManager::wxFrameManager(wxFrame* frame, unsigned int flags) m_hint_wnd = NULL; m_flags = flags; - if (frame) + if (managed_wnd) { - SetFrame(frame); + SetManagedWindow(managed_wnd); } } @@ -481,10 +553,25 @@ unsigned int wxFrameManager::GetFlags() const } -// 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")); @@ -508,6 +595,59 @@ void wxFrameManager::SetFrame(wxFrame* frame) 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 + | wxCAPTION ); + + // 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; + } } @@ -519,8 +659,8 @@ void wxFrameManager::UnInit() 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; } @@ -544,7 +684,9 @@ void wxFrameManager::ProcessMgrEvent(wxFrameManagerEvent& event) // 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 @@ -554,6 +696,7 @@ void wxFrameManager::SetArtProvider(wxDockArt* art_provider) m_art = art_provider; } + bool wxFrameManager::AddPane(wxWindow* window, const wxPaneInfo& pane_info) { // check if the pane has a valid window @@ -574,10 +717,15 @@ bool wxFrameManager::AddPane(wxWindow* window, const wxPaneInfo& pane_info) // if the pane's name identifier is blank, create a random string 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) @@ -641,6 +789,20 @@ bool wxFrameManager::AddPane(wxWindow* window, 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) { @@ -674,7 +836,7 @@ bool wxFrameManager::InsertPane(wxWindow* window, const wxPaneInfo& pane_info, { return AddPane(window, pane_info); } - else + else { if (pane_info.IsFloating()) { @@ -697,6 +859,8 @@ bool wxFrameManager::InsertPane(wxWindow* window, const wxPaneInfo& pane_info, } +// 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; @@ -720,6 +884,24 @@ bool wxFrameManager::DetachPane(wxWindow* window) 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; } @@ -746,6 +928,112 @@ static wxString EscapeDelimiters(const wxString& s) 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 @@ -762,32 +1050,7 @@ wxString wxFrameManager::SavePerspective() 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(); @@ -819,7 +1082,6 @@ bool wxFrameManager::LoadPerspective(const wxString& layout, bool update) 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) @@ -845,7 +1107,6 @@ bool wxFrameManager::LoadPerspective(const wxString& layout, bool update) if (pane_part.empty()) break; - if (pane_part.Left(9) == wxT("dock_size")) { wxString val_name = pane_part.BeforeFirst(wxT('=')); @@ -869,68 +1130,12 @@ 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); + // 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.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(";")); + LoadPaneInfo(pane_part, pane); wxPaneInfo& p = GetPane(pane.name); if (!p.IsOk()) @@ -940,10 +1145,8 @@ bool wxFrameManager::LoadPerspective(const wxString& layout, bool update) return false; } - pane.window = p.window; - pane.frame = p.frame; - pane.buttons = p.buttons; - p = pane; + p.SafeSet(pane); + } if (update) @@ -952,7 +1155,6 @@ bool wxFrameManager::LoadPerspective(const wxString& layout, bool update) return true; } - void wxFrameManager::GetPanePositionsAndSizes(wxDockInfo& dock, wxArrayInt& positions, wxArrayInt& sizes) @@ -1139,9 +1341,12 @@ 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); } @@ -1198,7 +1403,7 @@ 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); } @@ -1288,7 +1493,7 @@ 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) { @@ -1767,17 +1972,16 @@ 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); + this, + p); - // on MSW, if the owner desires transparent dragging, and +#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__ if (m_action == actionDragFloatingPane && (m_flags & wxAUI_MGR_TRANSPARENT_DRAG)) - MakeWindowTransparent(frame, 150); + frame->SetTransparent(150); #endif frame->SetPaneWindow(p); @@ -1795,7 +1999,8 @@ void wxFrameManager::Update() 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); } @@ -2018,7 +2223,7 @@ 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, +bool wxFrameManager::ProcessDockResult(wxPaneInfo& target, const wxPaneInfo& new_pos) { bool allowed = false; @@ -2085,8 +2290,8 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, 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)), @@ -2097,8 +2302,8 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, 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)), @@ -2109,8 +2314,8 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, 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)), @@ -2398,142 +2603,137 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, 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); + 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; - MakeWindowTransparent(m_hint_wnd, initial_fade); - m_hint_wnd->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION)); + 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(); + +#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->SetSize(rect); + m_hint_wnd->Raise(); - } - 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 (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_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 + 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); + 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()) @@ -2569,6 +2769,7 @@ void wxFrameManager::DrawHintRect(wxWindow* pane_window, wxDockUIPartArray uiparts; wxPaneInfo hint = GetPane(pane_window); hint.name = wxT("__HINT__"); + hint.Show(); if (!hint.IsOk()) return; @@ -2634,9 +2835,9 @@ void wxFrameManager::OnFloatingPaneMoveStart(wxWindow* wnd) 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); + pane.frame->SetTransparent(150); #endif } @@ -2723,26 +2924,22 @@ void wxFrameManager::OnFloatingPaneMoved(wxWindow* wnd) // 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(); @@ -2759,39 +2956,58 @@ void wxFrameManager::OnFloatingPaneResized(wxWindow* wnd, const wxSize& size) 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 + 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 @@ -2831,6 +3047,20 @@ void wxFrameManager::Render(wxDC* dc) } } + +// 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__ @@ -2945,7 +3175,7 @@ void wxFrameManager::UpdateButtonOnScreen(wxDockUIPart* button_ui_part, else state = wxAUI_BUTTON_STATE_HOVER; } - else + else { if (event.LeftDown()) state = wxAUI_BUTTON_STATE_HOVER; @@ -3231,7 +3461,7 @@ void wxFrameManager::OnLeftUp(wxMouseEvent& event) Repaint(NULL); } } - else if (m_action == actionClickButton) + else if (m_action == actionClickButton) { m_hover_button = NULL; m_frame->ReleaseMouse(); @@ -3247,15 +3477,15 @@ void wxFrameManager::OnLeftUp(wxMouseEvent& event) 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(); @@ -3281,7 +3511,7 @@ void wxFrameManager::OnLeftUp(wxMouseEvent& event) pane.state &= ~wxPaneInfo::actionPane; Update(); } - else + else { event.Skip(); } @@ -3322,7 +3552,7 @@ 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); @@ -3369,13 +3599,13 @@ 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); } - 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")); @@ -3464,21 +3694,33 @@ 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 wxFrameManager::OnPaneButton(wxFrameManagerEvent& evt) { - wxPaneInfo& pane = *(event.pane); + wxASSERT_MSG(evt.pane, wxT("Pane Info passed to wxFrameManager::OnPaneButton must be non-null")); + + wxPaneInfo& pane = *(evt.pane); - if (event.button == wxPaneInfo::buttonClose) + 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())