X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/cedd7b22f4efca68479ec4bb79a9ce5f80164a3b..3e1924dd5f5744c3e2a8973de9b3e4f372b7fd85:/src/aui/framemanager.cpp diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index 0de88d5734..b4ee254fd6 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -67,6 +67,12 @@ DEFINE_EVENT_TYPE(wxEVT_AUI_FIND_MANAGER) #include "wx/mac/private.h" #endif +#ifdef __WXMSW__ + #include "wx/msw/wrapwin.h" + #include "wx/msw/private.h" + #include "wx/msw/dc.h" +#endif + IMPLEMENT_DYNAMIC_CLASS(wxAuiManagerEvent, wxEvent) IMPLEMENT_CLASS(wxAuiManager, wxEvtHandler) @@ -74,6 +80,8 @@ IMPLEMENT_CLASS(wxAuiManager, wxEvtHandler) const int auiToolBarLayer = 10; +#ifndef __WXGTK20__ + class wxPseudoTransparentFrame : public wxFrame { @@ -209,6 +217,72 @@ BEGIN_EVENT_TABLE(wxPseudoTransparentFrame, wxFrame) END_EVENT_TABLE() +#else + // __WXGTK20__ + +#include + +static void +gtk_pseudo_window_realized_callback( GtkWidget *m_widget, void *WXUNUSED(win) ) +{ + wxSize disp = wxGetDisplaySize(); + int amount = 128; + wxRegion region; + for (int y=0; ywindow, region.GetRegion(), 0, 0); +} + + +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")) + { + if (!CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) + return; + + m_title = title; + + m_widget = gtk_window_new( GTK_WINDOW_POPUP ); + + g_signal_connect( m_widget, "realize", + G_CALLBACK (gtk_pseudo_window_realized_callback), this ); + + GdkColor col; + col.red = 128 * 256; + col.green = 192 * 256; + col.blue = 255 * 256; + gtk_widget_modify_bg( m_widget, GTK_STATE_NORMAL, &col ); + } + + bool SetTransparent(wxByte WXUNUSED(alpha)) + { + return true; + } + +private: + DECLARE_DYNAMIC_CLASS(wxPseudoTransparentFrame) +}; + +IMPLEMENT_DYNAMIC_CLASS(wxPseudoTransparentFrame, wxFrame) + +#endif + // __WXGTK20__ + + + // -- static utility functions -- static wxBitmap wxPaneCreateStippleBitmap() @@ -223,10 +297,15 @@ static void DrawResizeHint(wxDC& dc, const wxRect& rect) wxBitmap stipple = wxPaneCreateStippleBitmap(); wxBrush brush(stipple); dc.SetBrush(brush); +#ifdef __WXMSW__ + wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl(); + PatBlt(GetHdcOf(*impl), rect.GetX(), rect.GetY(), rect.GetWidth(), rect.GetHeight(), PATINVERT); +#else dc.SetPen(*wxTRANSPARENT_PEN); dc.SetLogicalFunction(wxXOR); dc.DrawRectangle(rect); +#endif } @@ -430,20 +509,26 @@ static void RemovePaneFromDocks(wxAuiDockInfoArray& docks, } } +/* +// This function works fine, and may be used in the future + // RenumberDockRows() takes a dock and assigns sequential numbers // to existing rows. Basically it takes out the gaps; so if a // dock has rows with numbers 0,2,5, they will become 0,1,2 static void RenumberDockRows(wxAuiDockInfoPtrArray& docks) { - int i, dock_count, j, pane_count; + int i, dock_count; for (i = 0, dock_count = docks.GetCount(); i < dock_count; ++i) { wxAuiDockInfo& dock = *docks.Item(i); dock.dock_row = i; + + int j, pane_count; for (j = 0, pane_count = dock.panes.GetCount(); j < pane_count; ++j) dock.panes.Item(j)->dock_row = i; } } +*/ // SetActivePane() sets the active pane, as well as cycles through @@ -512,12 +597,29 @@ wxAuiManager::wxAuiManager(wxWindow* managed_wnd, unsigned int flags) wxAuiManager::~wxAuiManager() { + // NOTE: It's possible that the windows have already been destroyed by the + // time this dtor is called, so this loop can result in memory access via + // invalid pointers, resulting in a crash. So it will be disabled while + // waiting for a better solution. +#if 0 for ( size_t i = 0; i < m_panes.size(); i++ ) { wxAuiPaneInfo& pinfo = m_panes[i]; if (pinfo.window && !pinfo.window->GetParent()) delete pinfo.window; } +#endif + + // We need to remove any reference to this wxAuiManager in any of the + // wxAuiFloatingFrames associated with this manager in case they haven't + // been deleted just yet. + // We need an array copy since Unregister removes the items. + wxAuiFloatingFramePtrArray array_copy = m_floating_frames; + int i, count = array_copy.GetCount(); + for (i = 0; i < count; ++i) + { + UnregisterFloatingFrame(array_copy.Item(i)); + } delete m_art; } @@ -526,7 +628,47 @@ wxAuiManager::~wxAuiManager() wxAuiFloatingFrame* wxAuiManager::CreateFloatingFrame(wxWindow* parent, const wxAuiPaneInfo& pane_info) { - return new wxAuiFloatingFrame(parent, this, pane_info); + wxAuiFloatingFrame* frame = new wxAuiFloatingFrame(parent, this, pane_info); + RegisterFloatingFrame(frame); + return frame; +} + +bool wxAuiManager::CanDockPanel(const wxAuiPaneInfo & WXUNUSED(p)) +{ + // if a key modifier is pressed while dragging the frame, + // don't dock the window + return !(wxGetKeyState(WXK_CONTROL) || wxGetKeyState(WXK_ALT)); +} + +// registers a floating frame with this manager (see header) +void wxAuiManager::RegisterFloatingFrame(wxAuiFloatingFrame* frame) +{ + frame->SetOwnerManager(this); + int i, count = m_floating_frames.GetCount(); + for (i = 0; i < count; ++i) + { + wxAuiFloatingFrame* f = m_floating_frames.Item(i); + if (f == frame) + // this frame is already registered + return; + } + m_floating_frames.Add(frame); +} + +// unregisters a floating frame from this manager (see header) +void wxAuiManager::UnregisterFloatingFrame(wxAuiFloatingFrame* frame) +{ + frame->SetOwnerManager(NULL); + int i, count = m_floating_frames.GetCount(); + for (i = 0; i < count; ++i) + { + wxAuiFloatingFrame* f = m_floating_frames.Item(i); + if (f == frame) + { + m_floating_frames.Remove(f); + return; + } + } } // GetPane() looks up a wxAuiPaneInfo structure based @@ -675,6 +817,7 @@ void wxAuiManager::UpdateHintWindowConfig() { wxFrame* f = static_cast(w); can_do_transparent = f->CanSetTransparent(); + break; } @@ -923,7 +1066,8 @@ bool wxAuiManager::AddPane(wxWindow* window, const wxAuiPaneInfo& pane_info) // I believe this to be the correct action, until // wxToolBar::GetBestSize() is fixed. Is this assumption // correct? - pinfo.best_size.y++; + // commented out by JACS 2007-9-08 after having added a pixel in wxMSW's wxToolBar::DoGetBestSize() + // pinfo.best_size.y++; } if (pinfo.min_size != wxDefaultSize) @@ -1085,8 +1229,7 @@ bool wxAuiManager::DetachPane(wxWindow* window) return false; } -// ClosePane() destroys or hides the pane depending on its -// flags +// ClosePane() destroys or hides the pane depending on its flags void wxAuiManager::ClosePane(wxAuiPaneInfo& pane_info) { // if we were maximized, restore @@ -1439,12 +1582,11 @@ bool wxAuiManager::LoadPerspective(const wxString& layout, bool update) if (!p.IsOk()) { // the pane window couldn't be found - // in the existing layout - return false; + // in the existing layout -- skip it + continue; } p.SafeSet(pane); - } if (update) @@ -2082,6 +2224,8 @@ wxSizer* wxAuiManager::LayoutAll(wxAuiPaneInfoArray& panes, dock.fixed = false; if (!pane.IsToolbar()) dock.toolbar = false; + if (pane.HasFlag(wxAuiPaneInfo::optionDockFixed)) + dock.fixed = true; if (pane.state & wxAuiPaneInfo::actionPane) action_pane_marked = true; } @@ -2161,7 +2305,6 @@ wxSizer* wxAuiManager::LayoutAll(wxAuiPaneInfoArray& panes, // find any top docks in this layer FindDocks(docks, wxAUI_DOCK_TOP, layer, -1, arr); - RenumberDockRows(arr); if (!arr.IsEmpty()) { for (row = 0, row_count = arr.GetCount(); row < row_count; ++row) @@ -2176,7 +2319,6 @@ wxSizer* wxAuiManager::LayoutAll(wxAuiPaneInfoArray& panes, // find any left docks in this layer FindDocks(docks, wxAUI_DOCK_LEFT, layer, -1, arr); - RenumberDockRows(arr); if (!arr.IsEmpty()) { for (row = 0, row_count = arr.GetCount(); row < row_count; ++row) @@ -2215,20 +2357,19 @@ wxSizer* wxAuiManager::LayoutAll(wxAuiPaneInfoArray& panes, // find any right docks in this layer FindDocks(docks, wxAUI_DOCK_RIGHT, layer, -1, arr); - RenumberDockRows(arr); if (!arr.IsEmpty()) { for (row = arr.GetCount()-1; row >= 0; --row) LayoutAddDock(middle, *arr.Item(row), uiparts, spacer_only); } - cont->Add(middle, 1, wxEXPAND); + if (middle->GetChildren().GetCount() > 0) + cont->Add(middle, 1, wxEXPAND); // find any bottom docks in this layer FindDocks(docks, wxAUI_DOCK_BOTTOM, layer, -1, arr); - RenumberDockRows(arr); if (!arr.IsEmpty()) { for (row = arr.GetCount()-1; row >= 0; --row) @@ -2285,6 +2426,8 @@ void wxAuiManager::GetDockSizeConstraint(double* width_pct, double* height_pct) void wxAuiManager::Update() { + m_hover_button = NULL; + wxSizer* sizer; int i, pane_count = m_panes.GetCount(); @@ -2373,7 +2516,7 @@ void wxAuiManager::Update() { // frame already exists, make sure it's position // and size reflect the information in wxAuiPaneInfo - if (p.frame->GetPosition() != p.floating_pos) + if ((p.frame->GetPosition() != p.floating_pos) || (p.frame->GetSize() != p.floating_size)) { p.frame->SetSize(p.floating_pos.x, p.floating_pos.y, p.floating_size.x, p.floating_size.y, @@ -3391,7 +3534,7 @@ void wxAuiManager::OnFloatingPaneMoving(wxWindow* wnd, wxDirection dir) // if a key modifier is pressed while dragging the frame, // don't dock the window - if (wxGetKeyState(WXK_CONTROL) || wxGetKeyState(WXK_ALT)) + if (!CanDockPanel(pane)) { HideHint(); return; @@ -3466,7 +3609,7 @@ void wxAuiManager::OnFloatingPaneMoved(wxWindow* wnd, wxDirection dir) // if a key modifier is pressed while dragging the frame, // don't dock the window - if (!wxGetKeyState(WXK_CONTROL) && !wxGetKeyState(WXK_ALT)) + if (CanDockPanel(pane)) { // do the drop calculation DoDrop(m_docks, m_panes, pane, client_pt, action_offset); @@ -3521,7 +3664,15 @@ void wxAuiManager::OnFloatingPaneClosed(wxWindow* wnd, wxCloseEvent& evt) } else { - ClosePane(pane); + // close the pane, but check that it + // still exists in our pane array first + // (the event handler above might have removed it) + + wxAuiPaneInfo& check = GetPane(wnd); + if (check.IsOk()) + { + ClosePane(pane); + } } } @@ -3529,11 +3680,8 @@ void wxAuiManager::OnFloatingPaneClosed(wxWindow* wnd, wxCloseEvent& evt) void wxAuiManager::OnFloatingPaneActivated(wxWindow* wnd) { - if (GetFlags() & wxAUI_MGR_ALLOW_ACTIVE_PANE) + if ((GetFlags() & wxAUI_MGR_ALLOW_ACTIVE_PANE) && GetPane(wnd).IsOk()) { - // try to find the pane - wxASSERT_MSG(GetPane(wnd).IsOk(), wxT("Pane window not found")); - SetActivePane(m_panes, wnd); Repaint(); } @@ -3560,8 +3708,8 @@ void wxAuiManager::OnRender(wxAuiManagerEvent& evt) { wxAuiDockUIPart& part = m_uiparts.Item(i); - // don't draw hidden pane items - if (part.sizer_item && !part.sizer_item->IsShown()) + // don't draw hidden pane items or items that aren't windows + if (part.sizer_item && ((!part.sizer_item->IsWindow() && !part.sizer_item->IsSpacer() && !part.sizer_item->IsSizer()) || !part.sizer_item->IsShown())) continue; switch (part.type) @@ -3787,8 +3935,9 @@ void wxAuiManager::OnLeftDown(wxMouseEvent& event) if (part->type == wxAuiDockUIPart::typeDockSizer || part->type == wxAuiDockUIPart::typePaneSizer) { - if (part->dock && part->dock->dock_direction == wxAUI_DOCK_CENTER) - return; + // Removing this restriction so that a centre pane can be resized + //if (part->dock && part->dock->dock_direction == wxAUI_DOCK_CENTER) + // return; // a dock may not be resized if it has a single // pane which is not resizable @@ -3841,9 +3990,6 @@ void wxAuiManager::OnLeftDown(wxMouseEvent& event) - if (part->dock && part->dock->dock_direction == wxAUI_DOCK_CENTER) - return; - if (GetFlags() & wxAUI_MGR_ALLOW_ACTIVE_PANE) { // set the caption as active @@ -3851,6 +3997,9 @@ void wxAuiManager::OnLeftDown(wxMouseEvent& event) Repaint(); } + if (part->dock && part->dock->dock_direction == wxAUI_DOCK_CENTER) + return; + m_action = actionClickCaption; m_action_part = part; m_action_start = wxPoint(event.m_x, event.m_y); @@ -4304,7 +4453,8 @@ void wxAuiManager::OnChildFocus(wxChildFocusEvent& event) // active panes are allowed by the owner) if (GetFlags() & wxAUI_MGR_ALLOW_ACTIVE_PANE) { - if (GetPane(event.GetWindow()).IsOk()) + wxAuiPaneInfo& pane = GetPane(event.GetWindow()); + if (pane.IsOk() && (pane.state & wxAuiPaneInfo::optionActive) == 0) { SetActivePane(m_panes, event.GetWindow()); m_frame->Refresh(); @@ -4333,7 +4483,16 @@ void wxAuiManager::OnPaneButton(wxAuiManagerEvent& evt) if (!e.GetVeto()) { - ClosePane(pane); + // close the pane, but check that it + // still exists in our pane array first + // (the event handler above might have removed it) + + wxAuiPaneInfo& check = GetPane(pane.window); + if (check.IsOk()) + { + ClosePane(pane); + } + Update(); } }