X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b836b6ea08c2cc7a22f1d44d88f0ce92ecc8a5a3..0b850f25d2924ee0e5ea08f93fffaa63f62f9104:/src/aui/framemanager.cpp diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index 0f32eda42c..27e3bf9416 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,8 @@ DEFINE_EVENT_TYPE(wxEVT_AUI_PANEBUTTON) #include "wx/mac/private.h" #endif +IMPLEMENT_DYNAMIC_CLASS(wxFrameManagerEvent, wxEvent) + // -- static utility functions -- @@ -84,12 +85,12 @@ static void DrawResizeHint(wxDC& dc, const wxRect& rect) dc.DrawRectangle(rect); } -#ifdef __WXMSW__ -// on supported windows systems (Win2000 and greater), this function +// on supported windows systems (Win2000 and greater, Mac), this function // will make a frame window transparent by a certain amount static void MakeWindowTransparent(wxWindow* wnd, int amount) { +#if defined(__WXMSW__) // 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); @@ -103,7 +104,13 @@ static void MakeWindowTransparent(wxWindow* wnd, int amount) if (!pSetLayeredWindowAttributes) { pSetLayeredWindowAttributes = - (PSETLAYEREDWINDOWATTR)GetProcAddress(h,"SetLayeredWindowAttributes"); + (PSETLAYEREDWINDOWATTR)GetProcAddress(h, +#ifdef __WXWINCE__ + wxT("SetLayeredWindowAttributes") +#else + "SetLayeredWindowAttributes" +#endif + ); } if (pSetLayeredWindowAttributes == NULL) @@ -114,9 +121,18 @@ static void MakeWindowTransparent(wxWindow* wnd, int amount) SetWindowLong(hwnd, GWL_EXSTYLE, exstyle | 0x80000 /*WS_EX_LAYERED*/); pSetLayeredWindowAttributes(hwnd, 0, (BYTE)amount, 2 /*LWA_ALPHA*/); -} +#elif defined(__WXMAC__) + + WindowRef handle = GetControlOwner((OpaqueControlRef*)wnd->GetHandle()); + SetWindowAlpha(handle, float(amount)/ 255.0); + +#else + wxUnusedVar(wnd); + wxUnusedVar(amount); #endif +} + // CopyDocksAndPanes() - this utility function creates copies of @@ -333,7 +349,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 +377,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 +391,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 +400,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 +500,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")); @@ -519,8 +553,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 +578,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 +590,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 @@ -577,7 +614,11 @@ bool wxFrameManager::AddPane(wxWindow* window, const wxPaneInfo& pane_info) pinfo.name.Printf(wxT("%08lx%08x%08x%08lx"), ((unsigned long)pinfo.window) & 0xffffffff, (unsigned int)time(NULL), +#ifdef __WXWINCE__ + (unsigned int)GetTickCount(), +#else (unsigned int)clock(), +#endif (unsigned long)m_panes.GetCount()); } @@ -675,7 +716,7 @@ bool wxFrameManager::InsertPane(wxWindow* window, const wxPaneInfo& pane_info, { return AddPane(window, pane_info); } - else + else { if (pane_info.IsFloating()) { @@ -698,6 +739,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; @@ -1140,9 +1183,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); } @@ -1199,7 +1245,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); } @@ -1289,7 +1335,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) { @@ -1768,18 +1814,15 @@ 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 + // 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); -#endif frame->SetPaneWindow(p); p.frame = frame; @@ -1796,7 +1839,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); } @@ -2019,7 +2063,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; @@ -2086,8 +2130,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)), @@ -2098,8 +2142,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)), @@ -2110,8 +2154,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)), @@ -2399,7 +2443,6 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks, void wxFrameManager::OnHintFadeTimer(wxTimerEvent& WXUNUSED(event)) { -#ifdef __WXMSW__ if (!m_hint_wnd || m_hint_fadeamt >= 50) { m_hint_fadetimer.Stop(); @@ -2408,13 +2451,11 @@ void wxFrameManager::OnHintFadeTimer(wxTimerEvent& WXUNUSED(event)) m_hint_fadeamt += 5; MakeWindowTransparent(m_hint_wnd, m_hint_fadeamt); -#endif } void wxFrameManager::ShowHint(const wxRect& rect) { -#ifdef __WXMSW__ - +#if defined(__WXMSW__) || defined(__WXMAC__) // First, determine if the operating system can handle transparency. // Transparency is available on Win2000 and above @@ -2427,8 +2468,11 @@ void wxFrameManager::ShowHint(const wxRect& rect) // 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 +#ifdef __WXMSW__ + && os_type == wxWINDOWS_NT && ver_major >= 5 +#endif + ) { if (m_last_hint == rect) return; @@ -2442,6 +2486,7 @@ void wxFrameManager::ShowHint(const wxRect& rect) { wxPoint pt = rect.GetPosition(); wxSize size = rect.GetSize(); +#if defined(__WXMSW__) m_hint_wnd = new wxFrame(m_frame, -1, wxEmptyString, pt, size, wxFRAME_TOOL_WINDOW | wxFRAME_FLOAT_ON_PARENT | @@ -2450,6 +2495,23 @@ void wxFrameManager::ShowHint(const wxRect& rect) MakeWindowTransparent(m_hint_wnd, initial_fade); 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, -1, wxEmptyString, pt, size, + 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_wnd->Show(); // if we are dragging a floating pane, set the focus @@ -2458,10 +2520,11 @@ void wxFrameManager::ShowHint(const wxRect& rect) m_action_window->SetFocus(); } - else + else { MakeWindowTransparent(m_hint_wnd, initial_fade); m_hint_wnd->SetSize(rect); + m_hint_wnd->Raise(); } if (m_flags & wxAUI_MGR_TRANSPARENT_HINT_FADE) @@ -2475,7 +2538,7 @@ void wxFrameManager::ShowHint(const wxRect& rect) return; } #endif - + if (m_last_hint != rect) { // remove the last hint rectangle @@ -2523,8 +2586,7 @@ void wxFrameManager::ShowHint(const wxRect& rect) 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); @@ -2532,7 +2594,6 @@ void wxFrameManager::HideHint() m_last_hint = wxRect(); return; } -#endif // hides a painted hint by redrawing the frame window if (!m_last_hint.IsEmpty()) @@ -2568,6 +2629,7 @@ void wxFrameManager::DrawHintRect(wxWindow* pane_window, wxDockUIPartArray uiparts; wxPaneInfo hint = GetPane(pane_window); hint.name = wxT("__HINT__"); + hint.Show(); if (!hint.IsOk()) return; @@ -2633,10 +2695,8 @@ void wxFrameManager::OnFloatingPaneMoveStart(wxWindow* wnd) wxPaneInfo& pane = GetPane(wnd); wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found")); -#ifdef __WXMSW__ if (m_flags & wxAUI_MGR_TRANSPARENT_DRAG) MakeWindowTransparent(pane.frame, 150); -#endif } void wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd) @@ -2738,10 +2798,8 @@ void wxFrameManager::OnFloatingPaneMoved(wxWindow* wnd) { pane.floating_pos = pane.frame->GetPosition(); - #ifdef __WXMSW__ if (m_flags & wxAUI_MGR_TRANSPARENT_DRAG) MakeWindowTransparent(pane.frame, 255); - #endif } Update(); @@ -2758,39 +2816,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 @@ -2830,6 +2907,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__ @@ -2944,7 +3035,7 @@ void wxFrameManager::UpdateButtonOnScreen(wxDockUIPart* button_ui_part, else state = wxAUI_BUTTON_STATE_HOVER; } - else + else { if (event.LeftDown()) state = wxAUI_BUTTON_STATE_HOVER; @@ -3230,7 +3321,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(); @@ -3246,15 +3337,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(); @@ -3280,7 +3371,7 @@ void wxFrameManager::OnLeftUp(wxMouseEvent& event) pane.state &= ~wxPaneInfo::actionPane; Update(); } - else + else { event.Skip(); } @@ -3321,7 +3412,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); @@ -3368,13 +3459,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")); @@ -3468,16 +3559,26 @@ void wxFrameManager::OnChildFocus(wxChildFocusEvent& event) // 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")); - if (event.button == wxPaneInfo::buttonClose) + 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())