X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e092fb2e67fcf13d74a079f04cff6d5db98c4e8b..ce22ac4592fccaedd8324e7a8f08b510748827e4:/src/aui/framemanager.cpp diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index 55933e04f0..3dc1ac038b 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -30,6 +30,7 @@ #include "wx/aui/floatpane.h" #ifndef WX_PRECOMP + #include "wx/panel.h" #include "wx/settings.h" #include "wx/app.h" #include "wx/dcclient.h" @@ -53,6 +54,7 @@ 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 @@ -61,6 +63,137 @@ DEFINE_EVENT_TYPE(wxEVT_AUI_PANECLOSE) #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; yGetHWND(); - - if (!h) - h = LoadLibrary(_T("user32")); - - if (!pSetLayeredWindowAttributes) - { - pSetLayeredWindowAttributes = - (PSETLAYEREDWINDOWATTR)GetProcAddress(h, -#ifdef __WXWINCE__ - wxT("SetLayeredWindowAttributes") -#else - "SetLayeredWindowAttributes" -#endif - ); - } - - 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 @@ -304,16 +398,16 @@ static wxPaneInfo* FindPaneInDock(const wxDockInfo& dock, wxWindow* window) } // 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) @@ -365,6 +459,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) @@ -378,7 +473,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(); @@ -386,10 +481,11 @@ wxFrameManager::wxFrameManager(wxFrame* frame, unsigned int flags) m_art = new wxDefaultDockArt; m_hint_wnd = NULL; m_flags = flags; + m_skipping = false; - if (frame) + if (managed_wnd) { - SetFrame(frame); + SetManagedWindow(managed_wnd); } } @@ -466,7 +562,7 @@ wxDockUIPart* wxFrameManager::HitTest(int x, int y) 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; } @@ -487,10 +583,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")); @@ -514,6 +625,58 @@ 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 ); + + // 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; + } } @@ -525,8 +688,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; } @@ -655,6 +818,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) { @@ -728,7 +905,9 @@ bool wxFrameManager::DetachPane(wxWindow* window) // reduce flicker p.window->SetSize(1,1); - p.frame->Show(false); + + if (p.frame->IsShown()) + p.frame->Show(false); // reparent to m_frame and destroy the pane p.window->Reparent(m_frame); @@ -736,6 +915,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; } @@ -762,6 +959,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 @@ -778,32 +1081,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(); @@ -835,7 +1113,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) @@ -861,7 +1138,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('=')); @@ -885,68 +1161,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); - - 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")); - } - } + // 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(";")); - // 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()) @@ -956,10 +1176,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) @@ -968,7 +1186,6 @@ bool wxFrameManager::LoadPerspective(const wxString& layout, bool update) return true; } - void wxFrameManager::GetPanePositionsAndSizes(wxDockInfo& dock, wxArrayInt& positions, wxArrayInt& sizes) @@ -1158,6 +1375,9 @@ void wxFrameManager::LayoutAddPane(wxSizer* cont, 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); } @@ -1756,7 +1976,9 @@ void wxFrameManager::Update() // 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); @@ -1786,22 +2008,20 @@ void wxFrameManager::Update() 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); p.frame = frame; - if (p.IsShown()) - { + if (p.IsShown() && !frame->IsShown()) frame->Show(); - } } else { @@ -1810,16 +2030,19 @@ 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); } - 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 @@ -2033,7 +2256,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; @@ -2091,11 +2314,7 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, 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); @@ -2103,11 +2322,7 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, 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); @@ -2115,11 +2330,7 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, 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); @@ -2127,9 +2338,10 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, 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). @@ -2137,7 +2349,6 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, return ProcessDockResult(target, drop); } - wxDockUIPart* part = HitTest(pt.x, pt.y); @@ -2145,8 +2356,7 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, { 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; @@ -2161,16 +2371,39 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, // should float if being dragged over center pane windows if (!part->dock->fixed || part->dock->dock_direction == wxAUI_DOCK_CENTER) { - if ((m_flags & wxAUI_MGR_ALLOW_FLOATING) && + if (m_last_rect.IsEmpty() || m_last_rect.Contains(pt.x, pt.y )) + { + m_skipping = true; + } + else + { + if ((m_flags & wxAUI_MGR_ALLOW_FLOATING) && (drop.IsFloatable() || (part->dock->dock_direction != wxAUI_DOCK_CENTER && part->dock->dock_direction != wxAUI_DOCK_NONE))) - { - drop.Float(); + { + drop.Float(); + } + + m_skipping = false; + + return ProcessDockResult(target, drop); } + + drop.Position(pt.x - GetDockPixelOffset(drop) - offset.x); return ProcessDockResult(target, drop); } + else + { + m_skipping = false; + } + + if (!m_skipping) + { + m_last_rect = part->dock->rect; + m_last_rect.Inflate( 15, 15 ); + } drop.Dock(). Direction(part->dock->dock_direction). @@ -2179,15 +2412,26 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, Position(dock_drop_offset); if (( - ((pt.y < part->dock->rect.y + 2) && part->dock->IsHorizontal()) || - ((pt.x < part->dock->rect.x + 2) && part->dock->IsVertical()) + ((pt.y < part->dock->rect.y + 1) && part->dock->IsHorizontal()) || + ((pt.x < part->dock->rect.x + 1) && part->dock->IsVertical()) ) && part->dock->panes.GetCount() > 1) { - int row = drop.dock_row; - DoInsertDockRow(panes, part->dock->dock_direction, - part->dock->dock_layer, - part->dock->dock_row); - drop.dock_row = row; + if ((part->dock->dock_direction == wxAUI_DOCK_TOP) || + (part->dock->dock_direction == wxAUI_DOCK_LEFT)) + { + int row = drop.dock_row; + DoInsertDockRow(panes, part->dock->dock_direction, + part->dock->dock_layer, + part->dock->dock_row); + drop.dock_row = row; + } + else + { + DoInsertDockRow(panes, part->dock->dock_direction, + part->dock->dock_layer, + part->dock->dock_row+1); + drop.dock_row = part->dock->dock_row+1; + } } if (( @@ -2195,10 +2439,22 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, ((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); @@ -2413,140 +2669,139 @@ 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; + 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; - 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_wnd->SetSize(rect); - 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(); - } - else - { - MakeWindowTransparent(m_hint_wnd, initial_fade); - m_hint_wnd->SetSize(rect); - } +#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_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); - screendc.DrawRectangle(rect.x, rect.y, 5, rect.height); - screendc.DrawRectangle(rect.x+5, rect.y, rect.width-10, 5); - screendc.DrawRectangle(rect.x+rect.width-5, rect.y, 5, rect.height); - screendc.DrawRectangle(rect.x+5, rect.y+rect.height-5, rect.width-10, 5); + wxBitmap stipple = wxPaneCreateStippleBitmap(); + wxBrush brush(stipple); + screendc.SetBrush(brush); + screendc.SetPen(*wxTRANSPARENT_PEN); + + screendc.DrawRectangle(rect.x, rect.y, 5, rect.height); + screendc.DrawRectangle(rect.x+5, rect.y, rect.width-10, 5); + screendc.DrawRectangle(rect.x+rect.width-5, rect.y, 5, rect.height); + screendc.DrawRectangle(rect.x+5, rect.y+rect.height-5, rect.width-10, 5); + } } void wxFrameManager::HideHint() { - // hides a transparent window hint (currently wxMSW only) -#ifdef __WXMSW__ + // 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()) @@ -2582,6 +2837,7 @@ void wxFrameManager::DrawHintRect(wxWindow* pane_window, wxDockUIPartArray uiparts; wxPaneInfo hint = GetPane(pane_window); hint.name = wxT("__HINT__"); + hint.Show(); if (!hint.IsOk()) return; @@ -2647,19 +2903,54 @@ 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 } -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 @@ -2719,13 +3010,48 @@ void wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd) 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 @@ -2736,26 +3062,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(); @@ -2785,7 +3107,7 @@ void wxFrameManager::OnFloatingPaneClosed(wxWindow* wnd, wxCloseEvent& evt) e.SetPane(&pane); e.SetCanVeto(evt.CanVeto()); ProcessMgrEvent(e); - + if (e.GetVeto()) { evt.Veto(); @@ -2795,7 +3117,8 @@ void wxFrameManager::OnFloatingPaneClosed(wxWindow* wnd, wxCloseEvent& evt) { // reparent the pane window back to us and // prepare the frame window for destruction - pane.window->Show(false); + if (pane.window->IsShown()) + pane.window->Show(false); pane.window->Reparent(m_frame); pane.frame = NULL; pane.Hide(); @@ -2816,12 +3139,14 @@ void wxFrameManager::OnFloatingPaneActivated(wxWindow* wnd) } } -// 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 @@ -2839,28 +3164,42 @@ void wxFrameManager::Render(wxDC* dc) { 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); + 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__ @@ -2913,13 +3252,14 @@ void wxFrameManager::OnEraseBackground(wxEraseEvent& event) #endif } -void wxFrameManager::OnSize(wxSizeEvent& WXUNUSED(event)) +void wxFrameManager::OnSize(wxSizeEvent& event) { if (m_frame) { DoFrameLayout(); Repaint(); } + event.Skip(); } @@ -2990,7 +3330,7 @@ void wxFrameManager::UpdateButtonOnScreen(wxDockUIPart* button_ui_part, 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, @@ -3494,6 +3834,8 @@ void wxFrameManager::OnChildFocus(wxChildFocusEvent& event) m_frame->Refresh(); } } + + event.Skip(); } @@ -3502,7 +3844,7 @@ void wxFrameManager::OnChildFocus(wxChildFocusEvent& event) void wxFrameManager::OnPaneButton(wxFrameManagerEvent& evt) { wxASSERT_MSG(evt.pane, wxT("Pane Info passed to wxFrameManager::OnPaneButton must be non-null")); - + wxPaneInfo& pane = *(evt.pane); if (evt.button == wxPaneInfo::buttonClose) @@ -3511,7 +3853,7 @@ void wxFrameManager::OnPaneButton(wxFrameManagerEvent& evt) wxFrameManagerEvent e(wxEVT_AUI_PANECLOSE); e.SetPane(evt.pane); ProcessMgrEvent(e); - + if (!e.GetVeto()) { pane.Hide();