#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)
const int auiToolBarLayer = 10;
+#ifndef __WXGTK20__
+
class wxPseudoTransparentFrame : public wxFrame
{
END_EVENT_TABLE()
+#else
+ // __WXGTK20__
+
+#include <gtk/gtk.h>
+
+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; y<disp.y; y++)
+ {
+ // Reverse the order of the bottom 4 bits
+ int j=((y&8)?1:0)|((y&4)?2:0)|((y&2)?4:0)|((y&1)?8:0);
+ if ((j*16+8)<amount)
+ region.Union(0, y, disp.x, 1);
+ }
+ gdk_window_shape_combine_region(m_widget->window, 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()
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
}
}
}
+/*
+// 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
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;
}
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))
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
// on the supplied window pointer. Upon failure, GetPane()
// returns an empty wxAuiPaneInfo, a condition which can be checked
{
wxFrame* f = static_cast<wxFrame*>(w);
can_do_transparent = f->CanSetTransparent();
+
break;
}
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
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)
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;
}
// 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)
// 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)
// 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)
}
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);
+ }
}
}
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();
}
}