]> git.saurik.com Git - wxWidgets.git/blobdiff - src/aui/framemanager.cpp
ignore WinCE projects and build directories
[wxWidgets.git] / src / aui / framemanager.cpp
index 9585b5b24260ccfc43736fa503c954a2b5608809..b4ee254fd6551c10c6ebcc59eef1150be0e63957 100644 (file)
@@ -67,6 +67,12 @@ DEFINE_EVENT_TYPE(wxEVT_AUI_FIND_MANAGER)
     #include "wx/mac/private.h"
 #endif
 
     #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)
 
 IMPLEMENT_DYNAMIC_CLASS(wxAuiManagerEvent, wxEvent)
 IMPLEMENT_CLASS(wxAuiManager, wxEvtHandler)
 
@@ -74,6 +80,8 @@ IMPLEMENT_CLASS(wxAuiManager, wxEvtHandler)
 
 const int auiToolBarLayer = 10;
 
 
 const int auiToolBarLayer = 10;
 
+#ifndef __WXGTK20__
+
 
 class wxPseudoTransparentFrame : public wxFrame
 {
 
 class wxPseudoTransparentFrame : public wxFrame
 {
@@ -209,6 +217,72 @@ BEGIN_EVENT_TABLE(wxPseudoTransparentFrame, wxFrame)
 END_EVENT_TABLE()
 
 
 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()
 // -- 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);
     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);
     dc.SetPen(*wxTRANSPARENT_PEN);
 
     dc.SetLogicalFunction(wxXOR);
     dc.DrawRectangle(rect);
+#endif
 }
 
 
 }
 
 
@@ -430,6 +509,9 @@ 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
 // 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
@@ -440,15 +522,13 @@ static void RenumberDockRows(wxAuiDockInfoPtrArray& docks)
     {
         wxAuiDockInfo& dock = *docks.Item(i);
         dock.dock_row = i;
     {
         wxAuiDockInfo& dock = *docks.Item(i);
         dock.dock_row = i;
-        
-        // (BIW) I believe these lines are wrong because they are modifying
-        // the original pane structures, which should be avoided as much
-        // as possible.
-        
-        //for (j = 0, pane_count = dock.panes.GetCount(); j < pane_count; ++j)
-        //    dock.panes.Item(j)->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
 
 
 // SetActivePane() sets the active pane, as well as cycles through
@@ -517,12 +597,29 @@ wxAuiManager::wxAuiManager(wxWindow* managed_wnd, unsigned int flags)
 
 wxAuiManager::~wxAuiManager()
 {
 
 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;
     }
     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;
 }
 
     delete m_art;
 }
@@ -531,7 +628,9 @@ wxAuiManager::~wxAuiManager()
 wxAuiFloatingFrame* wxAuiManager::CreateFloatingFrame(wxWindow* parent,
                                                       const wxAuiPaneInfo& pane_info)
 {
 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))
 }
 
 bool wxAuiManager::CanDockPanel(const wxAuiPaneInfo & WXUNUSED(p))
@@ -541,6 +640,37 @@ bool wxAuiManager::CanDockPanel(const wxAuiPaneInfo & WXUNUSED(p))
     return !(wxGetKeyState(WXK_CONTROL) || wxGetKeyState(WXK_ALT));
 }
 
     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
 // 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
@@ -687,6 +817,7 @@ void wxAuiManager::UpdateHintWindowConfig()
         {
             wxFrame* f = static_cast<wxFrame*>(w);
             can_do_transparent = f->CanSetTransparent();
         {
             wxFrame* f = static_cast<wxFrame*>(w);
             can_do_transparent = f->CanSetTransparent();
+            
             break;
         }
 
             break;
         }
 
@@ -2174,7 +2305,6 @@ wxSizer* wxAuiManager::LayoutAll(wxAuiPaneInfoArray& panes,
 
         // find any top docks in this layer
         FindDocks(docks, wxAUI_DOCK_TOP, layer, -1, arr);
 
         // 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)
         if (!arr.IsEmpty())
         {
             for (row = 0, row_count = arr.GetCount(); row < row_count; ++row)
@@ -2189,7 +2319,6 @@ wxSizer* wxAuiManager::LayoutAll(wxAuiPaneInfoArray& panes,
 
         // find any left docks in this layer
         FindDocks(docks, wxAUI_DOCK_LEFT, layer, -1, arr);
 
         // 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)
         if (!arr.IsEmpty())
         {
             for (row = 0, row_count = arr.GetCount(); row < row_count; ++row)
@@ -2228,20 +2357,19 @@ wxSizer* wxAuiManager::LayoutAll(wxAuiPaneInfoArray& panes,
 
         // find any right docks in this layer
         FindDocks(docks, wxAUI_DOCK_RIGHT, layer, -1, arr);
 
         // 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);
         }
 
         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);
 
 
 
         // 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)
         if (!arr.IsEmpty())
         {
             for (row = arr.GetCount()-1; row >= 0; --row)
@@ -4364,7 +4492,7 @@ void wxAuiManager::OnPaneButton(wxAuiManagerEvent& evt)
             {
                 ClosePane(pane);
             }
             {
                 ClosePane(pane);
             }
-            
+
             Update();
         }
     }
             Update();
         }
     }