]> git.saurik.com Git - wxWidgets.git/blobdiff - src/aui/framemanager.cpp
compilation fix for wxUSE_UNICODE_MSLU && !WXWIN_COMPATIBILITY_2_6 (bug 1587408)
[wxWidgets.git] / src / aui / framemanager.cpp
index 4d42a2610bf422d4ad1db733ace751f0147ce456..358f149d315283ea43e098eafd00a57343494a7a 100644 (file)
@@ -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<wxFrame*>(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
@@ -2337,7 +2426,12 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks,
     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)),
+                                      GetMaxLayer(docks, wxAUI_DOCK_RIGHT)) + 1;
+
         drop.Dock().Bottom().
+             Layer(new_layer).
              Row(0).
              Position(pt.x - GetDockPixelOffset(drop) - offset.x);
         return ProcessDockResult(target, drop);
@@ -2350,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;
@@ -2365,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;
             }
@@ -2378,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);
@@ -2392,7 +2486,7 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks,
         {
             m_skipping = false;
         }
-        
+
         if (!m_skipping)
         {
             m_last_rect = part->dock->rect;
@@ -2406,15 +2500,26 @@ 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)
         {
-            int row = drop.dock_row;
-            DoInsertDockRow(panes, part->dock->dock_direction,
-                            part->dock->dock_layer,
-                            part->dock->dock_row);
-            drop.dock_row = row;
+            if ((part->dock->dock_direction == wxAUI_DOCK_TOP) ||
+                (part->dock->dock_direction == wxAUI_DOCK_LEFT))
+            {
+                int row = drop.dock_row;
+                DoInsertDockRow(panes, part->dock->dock_direction,
+                                part->dock->dock_layer,
+                                part->dock->dock_row);
+                drop.dock_row = row;
+            }
+            else
+            {
+                DoInsertDockRow(panes, part->dock->dock_direction,
+                                part->dock->dock_layer,
+                                part->dock->dock_row+1);
+                drop.dock_row = part->dock->dock_row+1;
+            }
         }
 
         if ((
@@ -2422,10 +2527,22 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks,
             ((pt.x > part->dock->rect.x + part->dock->rect.width - 2 ) && part->dock->IsVertical())
             ) && part->dock->panes.GetCount() > 1)
         {
-            DoInsertDockRow(panes, part->dock->dock_direction,
-                            part->dock->dock_layer,
-                            part->dock->dock_row+1);
-            drop.dock_row = part->dock->dock_row+1;
+            if ((part->dock->dock_direction == wxAUI_DOCK_TOP) ||
+                (part->dock->dock_direction == wxAUI_DOCK_LEFT))
+            {
+                DoInsertDockRow(panes, part->dock->dock_direction,
+                                part->dock->dock_layer,
+                                part->dock->dock_row+1);
+                drop.dock_row = part->dock->dock_row+1;
+            }
+            else
+            {
+                int row = drop.dock_row;
+                DoInsertDockRow(panes, part->dock->dock_direction,
+                                part->dock->dock_layer,
+                                part->dock->dock_row);
+                drop.dock_row = row;
+            }
         }
 
         return ProcessDockResult(target, drop);
@@ -2657,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
@@ -2689,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();
 
@@ -2701,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
@@ -2920,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);
@@ -3021,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);
@@ -3084,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);
     }
 }
 
@@ -3135,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;
         }
@@ -3301,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,
@@ -3818,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);
@@ -3827,7 +3940,7 @@ void wxFrameManager::OnPaneButton(wxFrameManagerEvent& evt)
 
         if (!e.GetVeto())
         {
-            pane.Hide();
+            ClosePane(pane);
             Update();
         }
     }