X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/26d18378e5a495bbbda91ab0c30a6b9bd52903b3..dddf9e14ede299e2da0a40eae445b8cab0389087:/src/aui/framemanager.cpp diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index 41c6de3fb8..358f149d31 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" @@ -146,7 +147,11 @@ public: } #ifdef __WXGTK__ - void OnWindowCreate(wxWindowCreateEvent& WXUNUSED(event)) {m_CanSetShape=true; SetTransparent(0);} + void OnWindowCreate(wxWindowCreateEvent& WXUNUSED(event)) + { + m_CanSetShape=true; + SetTransparent(0); + } #endif void OnSize(wxSizeEvent& event) @@ -183,7 +188,7 @@ private: }; -IMPLEMENT_DYNAMIC_CLASS( wxPseudoTransparentFrame, wxFrame ) +IMPLEMENT_DYNAMIC_CLASS(wxPseudoTransparentFrame, wxFrame) BEGIN_EVENT_TABLE(wxPseudoTransparentFrame, wxFrame) EVT_PAINT(wxPseudoTransparentFrame::OnPaint) @@ -493,6 +498,12 @@ wxFrameManager::~wxFrameManager() delete m_art; } +// Creates a floating frame for the windows +wxFloatingPane * wxFrameManager::CreateFloatingFrame(wxWindow* parent, const wxPaneInfo& p) +{ + return new wxFloatingPane(parent, this, p); +} + // GetPane() looks up a wxPaneInfo structure based // on the supplied window pointer. Upon failure, GetPane() // returns an empty wxPaneInfo, a condition which can be checked @@ -561,7 +572,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; } @@ -573,7 +584,22 @@ wxDockUIPart* wxFrameManager::HitTest(int x, int y) // options which are global to wxFrameManager void wxFrameManager::SetFlags(unsigned int flags) { + // find out if we have to call UpdateHintWindowConfig() + bool update_hint_wnd = false; + unsigned int hint_mask = wxAUI_MGR_TRANSPARENT_HINT | + wxAUI_MGR_VENETIAN_BLINDS_HINT | + wxAUI_MGR_RECTANGLE_HINT; + if ((flags & hint_mask) != (m_flags & hint_mask)) + update_hint_wnd = true; + + + // set the new flags m_flags = flags; + + if (update_hint_wnd) + { + UpdateHintWindowConfig(); + } } unsigned int wxFrameManager::GetFlags() const @@ -595,16 +621,97 @@ wxFrame* wxFrameManager::GetFrame() const } +void wxFrameManager::UpdateHintWindowConfig() +{ + // find out if the the system can do transparent frames + bool can_do_transparent = false; + + wxWindow* w = m_frame; + while (w) + { + if (w->IsKindOf(CLASSINFO(wxFrame))) + { + wxFrame* f = static_cast(w); + #if wxCHECK_VERSION(2,7,0) + can_do_transparent = f->CanSetTransparent(); + #endif + break; + } + + w = w->GetParent(); + } + + // if there is an existing hint window, delete it + if (m_hint_wnd) + { + m_hint_wnd->Destroy(); + m_hint_wnd = NULL; + } + + m_hint_fademax = 50; + m_hint_wnd = NULL; + + if ((m_flags & wxAUI_MGR_TRANSPARENT_HINT) && can_do_transparent) + { + // Make a window to use for a transparent hint + #if defined(__WXMSW__) || defined(__WXGTK__) + m_hint_wnd = new wxFrame(m_frame, wxID_ANY, wxEmptyString, + wxDefaultPosition, wxSize(1,1), + wxFRAME_TOOL_WINDOW | + wxFRAME_FLOAT_ON_PARENT | + wxFRAME_NO_TASKBAR | + wxNO_BORDER); + + m_hint_wnd->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION)); + #elif defined(__WXMAC__) + // Using a miniframe with float and tool styles keeps the parent + // frame activated and highlighted as such... + m_hint_wnd = new wxMiniFrame(m_frame, wxID_ANY, wxEmptyString, + wxDefaultPosition, wxSize(1,1), + wxFRAME_FLOAT_ON_PARENT + | wxFRAME_TOOL_WINDOW ); + + // Can't set the bg colour of a Frame in wxMac + wxPanel* p = new wxPanel(m_hint_wnd); + + // The default wxSYS_COLOUR_ACTIVECAPTION colour is a light silver + // color that is really hard to see, especially transparent. + // Until a better system color is decided upon we'll just use + // blue. + p->SetBackgroundColour(*wxBLUE); + #endif + + } + else + { + if ((m_flags & wxAUI_MGR_TRANSPARENT_HINT) != 0 || + (m_flags & wxAUI_MGR_VENETIAN_BLINDS_HINT) != 0) + { + // system can't support transparent fade, or the venetian + // blinds effect was explicitly requested + m_hint_wnd = new wxPseudoTransparentFrame(m_frame, + wxID_ANY, + wxEmptyString, + wxDefaultPosition, + wxSize(1,1), + wxFRAME_TOOL_WINDOW | + wxFRAME_FLOAT_ON_PARENT | + wxFRAME_NO_TASKBAR | + wxNO_BORDER); + m_hint_fademax = 128; + } + } +} // SetManagedWindow() is usually called once when the frame // manager class is being initialized. "frame" specifies // the frame which should be managed by the frame mananger -void wxFrameManager::SetManagedWindow(wxWindow* frame) +void wxFrameManager::SetManagedWindow(wxWindow* wnd) { - wxASSERT_MSG(frame, wxT("specified frame must be non-NULL")); + wxASSERT_MSG(wnd, wxT("specified window must be non-NULL")); - m_frame = frame; + m_frame = wnd; m_frame->PushEventHandler(this); #if wxUSE_MDI @@ -612,9 +719,9 @@ void wxFrameManager::SetManagedWindow(wxWindow* frame) // we need to add the MDI client window as the default // center pane - if (frame->IsKindOf(CLASSINFO(wxMDIParentFrame))) + if (m_frame->IsKindOf(CLASSINFO(wxMDIParentFrame))) { - wxMDIParentFrame* mdi_frame = (wxMDIParentFrame*)frame; + wxMDIParentFrame* mdi_frame = (wxMDIParentFrame*)m_frame; wxWindow* client_window = mdi_frame->GetClientWindow(); wxASSERT_MSG(client_window, wxT("Client window is NULL!")); @@ -625,57 +732,7 @@ void wxFrameManager::SetManagedWindow(wxWindow* frame) } #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; - } + UpdateHintWindowConfig(); } @@ -764,7 +821,7 @@ bool wxFrameManager::AddPane(wxWindow* window, const wxPaneInfo& pane_info) pinfo.buttons.size() == 0) { wxPaneButton button; - button.button_id = wxPaneInfo::buttonClose; + button.button_id = wxAUI_BUTTON_CLOSE; pinfo.buttons.Add(button); } @@ -864,7 +921,7 @@ bool wxFrameManager::InsertPane(wxWindow* window, const wxPaneInfo& pane_info, { return AddPane(window, pane_info); } - else + else { if (pane_info.IsFloating()) { @@ -939,6 +996,40 @@ bool wxFrameManager::DetachPane(wxWindow* window) return false; } +// ClosePane() destroys or hides the pane depending on its +// flags +void wxFrameManager::ClosePane(wxPaneInfo& pane_info) +{ + // first, hide the window + if (pane_info.window && pane_info.window->IsShown()) { + pane_info.window->Show(false); + } + + // make sure that we are the parent of this window + if(pane_info.window && pane_info.window->GetParent() != m_frame) { + pane_info.window->Reparent(m_frame); + } + + // if we have a frame, destroy it + if(pane_info.frame) { + pane_info.frame->Destroy(); + pane_info.frame = NULL; + } + + // now we need to either destroy or hide the pane + if(pane_info.IsDestroyOnClose()) + { + wxWindow * window = pane_info.window; + DetachPane(window); + if(window) { + window->Destroy(); + } + } + else + { + pane_info.Hide(); + } +} // EscapeDelimiters() changes ";" into "\;" and "|" into "\|" // in the input string. This is an internal functions which is @@ -2003,9 +2094,7 @@ void wxFrameManager::Update() { // we need to create a frame for this // pane, which has recently been floated - wxFloatingPane* frame = new wxFloatingPane(m_frame, - this, - p); + wxFloatingPane* frame = CreateFloatingFrame(m_frame, p); #if wxCHECK_VERSION(2,7,0) // on MSW and Mac, if the owner desires transparent dragging, and @@ -2340,7 +2429,7 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, 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). @@ -2355,7 +2444,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; @@ -2370,7 +2459,7 @@ 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_last_rect.IsEmpty() || m_last_rect.Inside(pt.x, pt.y )) + if (m_last_rect.IsEmpty() || m_last_rect.Contains(pt.x, pt.y )) { m_skipping = true; } @@ -2383,12 +2472,12 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, { drop.Float(); } - + m_skipping = false; - + return ProcessDockResult(target, drop); } - + drop.Position(pt.x - GetDockPixelOffset(drop) - offset.x); return ProcessDockResult(target, drop); @@ -2397,7 +2486,7 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, { m_skipping = false; } - + if (!m_skipping) { m_last_rect = part->dock->rect; @@ -2411,8 +2500,8 @@ 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) { if ((part->dock->dock_direction == wxAUI_DOCK_TOP) || @@ -2685,27 +2774,24 @@ void wxFrameManager::OnHintFadeTimer(wxTimerEvent& WXUNUSED(event)) void wxFrameManager::ShowHint(const wxRect& rect) { - 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_hint_wnd) { + // if the hint rect is the same as last time, don't do anything if (m_last_hint == rect) return; m_last_hint = rect; m_hint_fadeamt = m_hint_fademax; - if ((m_flags & wxAUI_MGR_TRANSPARENT_HINT_FADE) + + if ((m_flags & wxAUI_MGR_HINT_FADE) && !((m_hint_wnd->IsKindOf(CLASSINFO(wxPseudoTransparentFrame))) && - (m_flags & wxAUI_MGR_DISABLE_VENETIAN_BLINDS_FADE)) + (m_flags & wxAUI_MGR_NO_VENETIAN_BLINDS_FADE)) ) m_hint_fadeamt = 0; m_hint_wnd->SetSize(rect); - if (! m_hint_wnd->IsShown()) + if (!m_hint_wnd->IsShown()) m_hint_wnd->Show(); // if we are dragging a floating pane, set the focus @@ -2717,7 +2803,7 @@ void wxFrameManager::ShowHint(const wxRect& rect) m_hint_wnd->SetTransparent(m_hint_fadeamt); #else if (m_hint_wnd->IsKindOf(CLASSINFO(wxPseudoTransparentFrame))) - ((wxPseudoTransparentFrame *)m_hint_wnd)->SetTransparent(m_hint_fadeamt); + ((wxPseudoTransparentFrame*)m_hint_wnd)->SetTransparent(m_hint_fadeamt); #endif m_hint_wnd->Raise(); @@ -2729,10 +2815,11 @@ void wxFrameManager::ShowHint(const wxRect& rect) m_hint_fadetimer.Start(5); } } - - else // Not using a transparent hint window... + else // Not using a transparent hint window... { - + if (!(m_flags & wxAUI_MGR_RECTANGLE_HINT)) + return; + if (m_last_hint != rect) { // remove the last hint rectangle @@ -2948,6 +3035,8 @@ void wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd, wxDirection dir) pos = wnd->ClientToScreen( pos ); pt.y = pos.y; } +#else + wxUnusedVar(dir); #endif wxPoint client_pt = m_frame->ScreenToClient(pt); @@ -3049,6 +3138,8 @@ void wxFrameManager::OnFloatingPaneMoved(wxWindow* wnd, wxDirection dir) pos = wnd->ClientToScreen( pos ); pt.y = pos.y; } +#else + wxUnusedVar(dir); #endif wxPoint client_pt = m_frame->ScreenToClient(pt); @@ -3112,15 +3203,9 @@ void wxFrameManager::OnFloatingPaneClosed(wxWindow* wnd, wxCloseEvent& evt) evt.Veto(); return; } - else + 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(); + ClosePane(pane); } } @@ -3163,22 +3248,22 @@ void wxFrameManager::OnRender(wxFrameManagerEvent& evt) { 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; } @@ -3329,7 +3414,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, @@ -3846,7 +3931,7 @@ void wxFrameManager::OnPaneButton(wxFrameManagerEvent& evt) wxPaneInfo& pane = *(evt.pane); - if (evt.button == wxPaneInfo::buttonClose) + if (evt.button == wxAUI_BUTTON_CLOSE) { // fire pane close event wxFrameManagerEvent e(wxEVT_AUI_PANECLOSE); @@ -3855,7 +3940,7 @@ void wxFrameManager::OnPaneButton(wxFrameManagerEvent& evt) if (!e.GetVeto()) { - pane.Hide(); + ClosePane(pane); Update(); } }