]> git.saurik.com Git - wxWidgets.git/blobdiff - src/aui/framemanager.cpp
wxUSE_PANGO is always 1 for wxGTK2 so there is no need to use #if wxUSE_PANGO in...
[wxWidgets.git] / src / aui / framemanager.cpp
index 33312ec65bc05172c6cbf3f5e33098851a84942f..3079df6dba5fd6170299a7d7461b144e68ae3078 100644 (file)
     #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,39 +85,6 @@ static void DrawResizeHint(wxDC& dc, const wxRect& rect)
     dc.DrawRectangle(rect);
 }
 
-#ifdef __WXMSW__
-
-// on supported windows systems (Win2000 and greater), this function
-// will make a frame window transparent by a certain amount
-static void MakeWindowTransparent(wxWindow* wnd, int amount)
-{
-    // 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);
-    static PSETLAYEREDWINDOWATTR pSetLayeredWindowAttributes = NULL;
-    static HMODULE h = NULL;
-    HWND hwnd = (HWND)wnd->GetHWND();
-
-    if (!h)
-        h = LoadLibrary(_T("user32"));
-
-    if (!pSetLayeredWindowAttributes)
-    {
-        pSetLayeredWindowAttributes =
-         (PSETLAYEREDWINDOWATTR)GetProcAddress(h,"SetLayeredWindowAttributes");
-    }
-
-    if (pSetLayeredWindowAttributes == NULL)
-        return;
-
-    LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);
-    if (0 == (exstyle & 0x80000) /*WS_EX_LAYERED*/)
-        SetWindowLong(hwnd, GWL_EXSTYLE, exstyle | 0x80000 /*WS_EX_LAYERED*/);
-
-    pSetLayeredWindowAttributes(hwnd, 0, (BYTE)amount, 2 /*LWA_ALPHA*/);
-}
-
-#endif
 
 
 // CopyDocksAndPanes() - this utility function creates copies of
@@ -333,7 +301,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 +329,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 +343,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 +352,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 +452,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"));
 
@@ -508,6 +494,40 @@ void wxFrameManager::SetFrame(wxFrame* frame)
                 CenterPane().PaneBorder(false));
     }
 #endif
+
+    // Make a window to use for a translucent hint
+#if defined(__WXMSW__)
+    m_hint_wnd = new wxFrame(m_frame, -1, 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, -1, wxEmptyString, wxDefaultPosition, wxSize(1,1),
+                                 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
+
+    if (m_hint_wnd && !m_hint_wnd->CanSetTranslucency())
+    {
+        m_hint_wnd->Close();
+        m_hint_wnd = NULL;
+    }    
 }
 
 
@@ -519,8 +539,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 +564,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 +576,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 +600,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());
     }
 
@@ -642,6 +669,20 @@ bool wxFrameManager::AddPane(wxWindow* window,
     return AddPane(window, pinfo);
 }
 
+bool wxFrameManager::AddPane(wxWindow* window,
+                             const wxPaneInfo& pane_info,
+                             const wxPoint& drop_pos)
+{
+    if (!AddPane(window, pane_info))
+        return false;
+    
+    wxPaneInfo& pane = GetPane(window);
+    
+    DoDrop(m_docks, m_panes, pane, drop_pos, wxPoint(0,0));
+    
+    return true;
+}
+
 bool wxFrameManager::InsertPane(wxWindow* window, const wxPaneInfo& pane_info,
                                 int insert_level)
 {
@@ -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;
@@ -721,6 +764,24 @@ bool wxFrameManager::DetachPane(wxWindow* window)
                 p.frame->Destroy();
                 p.frame = NULL;
             }
+            
+            // make sure there are no references to this pane in our uiparts,
+            // just in case the caller doesn't call Update() immediately after
+            // the DetachPane() call.  This prevets obscure crashes which would
+            // happen at window repaint if the caller forgets to call Update()
+            int pi, part_count;
+            for (pi = 0, part_count = (int)m_uiparts.GetCount(); pi < part_count; ++pi)
+            {
+                wxDockUIPart& part = m_uiparts.Item(pi);
+                if (part.pane == &p)
+                {
+                    m_uiparts.RemoveAt(pi);
+                    part_count--;
+                    pi--;
+                    continue;
+                }
+            }
+            
             m_panes.RemoveAt(i);
             return true;
         }
@@ -1140,9 +1201,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 +1263,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 +1353,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 +1832,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->SetTranslucency(150);
 
                 frame->SetPaneWindow(p);
                 p.frame = frame;
@@ -1796,7 +1857,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 +2081,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 +2148,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 +2160,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 +2172,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 +2461,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();
@@ -2407,28 +2468,12 @@ void wxFrameManager::OnHintFadeTimer(wxTimerEvent& WXUNUSED(event))
     }
 
     m_hint_fadeamt += 5;
-    MakeWindowTransparent(m_hint_wnd, m_hint_fadeamt);
-#endif
+    m_hint_wnd->SetTranslucency(m_hint_fadeamt);
 }
 
 void wxFrameManager::ShowHint(const wxRect& rect)
 {
-#ifdef __WXMSW__
-
-    // First, determine if the operating system can handle transparency.
-    // Transparency is available on Win2000 and above
-
-    static int os_type = -1;
-    static int ver_major = -1;
-
-    if (os_type == -1)
-        os_type = ::wxGetOsVersion(&ver_major);
-
-    // 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 && m_hint_wnd)
     {
         if (m_last_hint == rect)
             return;
@@ -2438,33 +2483,18 @@ void wxFrameManager::ShowHint(const wxRect& rect)
         if (m_flags & wxAUI_MGR_TRANSPARENT_HINT_FADE)
             initial_fade = 0;
 
-        if (m_hint_wnd == NULL)
-        {
-            wxPoint pt = rect.GetPosition();
-            wxSize size = rect.GetSize();
-            m_hint_wnd = new wxFrame(m_frame, -1, wxEmptyString, pt, size,
-                                     wxFRAME_TOOL_WINDOW |
-                                     wxFRAME_FLOAT_ON_PARENT |
-                                     wxFRAME_NO_TASKBAR |
-                                     wxNO_BORDER);
-
-            MakeWindowTransparent(m_hint_wnd, initial_fade);
-            m_hint_wnd->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION));
+        if (! m_hint_wnd->IsShown())
             m_hint_wnd->Show();
 
-            // if we are dragging a floating pane, set the focus
-            // back to that floating pane (otherwise it becomes unfocused)
-            if (m_action == actionDragFloatingPane && m_action_window)
-                m_action_window->SetFocus();
+        // if we are dragging a floating pane, set the focus
+        // back to that floating pane (otherwise it becomes unfocused)
+        if (m_action == actionDragFloatingPane && m_action_window)
+            m_action_window->SetFocus();
 
-        }
-         else
-        {
-            wxPoint pt = rect.GetPosition();
-            wxSize size = rect.GetSize();
-            MakeWindowTransparent(m_hint_wnd, initial_fade);
-            m_hint_wnd->SetSize(pt.x, pt.y, rect.width, rect.height);
-        }
+        m_hint_wnd->SetTranslucency(initial_fade);
+        m_hint_wnd->SetSize(rect);
+        m_hint_wnd->Raise();
+        
 
         if (m_flags & wxAUI_MGR_TRANSPARENT_HINT_FADE)
         {
@@ -2473,68 +2503,67 @@ void wxFrameManager::ShowHint(const wxRect& rect)
             m_hint_fadetimer.SetOwner(this, 101);
             m_hint_fadetimer.Start(5);
         }
-
-        return;
     }
-#endif
 
-    if (m_last_hint != rect)
+    else  // Not using a translucent hint window...
     {
-        // remove the last hint rectangle
-        m_last_hint = rect;
-        m_frame->Refresh();
-        m_frame->Update();
-    }
-
-    wxScreenDC screendc;
-    wxRegion clip(1, 1, 10000, 10000);
+        
+        if (m_last_hint != rect)
+        {
+            // remove the last hint rectangle
+            m_last_hint = rect;
+            m_frame->Refresh();
+            m_frame->Update();
+        }
 
-    // clip all floating windows, so we don't draw over them
-    int i, pane_count;
-    for (i = 0, pane_count = m_panes.GetCount(); i < pane_count; ++i)
-    {
-        wxPaneInfo& pane = m_panes.Item(i);
+        wxScreenDC screendc;
+        wxRegion clip(1, 1, 10000, 10000);
 
-        if (pane.IsFloating() &&
-            pane.frame->IsShown())
+        // clip all floating windows, so we don't draw over them
+        int i, pane_count;
+        for (i = 0, pane_count = m_panes.GetCount(); i < pane_count; ++i)
         {
-            wxRect rect = pane.frame->GetRect();
-            #ifdef __WXGTK__
-            // wxGTK returns the client size, not the whole frame size
-            rect.width += 15;
-            rect.height += 35;
-            rect.Inflate(5);
-            #endif
+            wxPaneInfo& pane = m_panes.Item(i);
 
-            clip.Subtract(rect);
+            if (pane.IsFloating() &&
+                pane.frame->IsShown())
+            {
+                wxRect rect = pane.frame->GetRect();
+#ifdef __WXGTK__
+                // wxGTK returns the client size, not the whole frame size
+                rect.width += 15;
+                rect.height += 35;
+                rect.Inflate(5);
+#endif
+
+                clip.Subtract(rect);
+            }
         }
-    }
 
-    screendc.SetClippingRegion(clip);
+        screendc.SetClippingRegion(clip);
 
-    wxBitmap stipple = wxPaneCreateStippleBitmap();
-    wxBrush brush(stipple);
-    screendc.SetBrush(brush);
-    screendc.SetPen(*wxTRANSPARENT_PEN);
+        wxBitmap stipple = wxPaneCreateStippleBitmap();
+        wxBrush brush(stipple);
+        screendc.SetBrush(brush);
+        screendc.SetPen(*wxTRANSPARENT_PEN);
 
-    screendc.DrawRectangle(rect.x, rect.y, 5, rect.height);
-    screendc.DrawRectangle(rect.x+5, rect.y, rect.width-10, 5);
-    screendc.DrawRectangle(rect.x+rect.width-5, rect.y, 5, rect.height);
-    screendc.DrawRectangle(rect.x+5, rect.y+rect.height-5, rect.width-10, 5);
+        screendc.DrawRectangle(rect.x, rect.y, 5, rect.height);
+        screendc.DrawRectangle(rect.x+5, rect.y, rect.width-10, 5);
+        screendc.DrawRectangle(rect.x+rect.width-5, rect.y, 5, rect.height);
+        screendc.DrawRectangle(rect.x+5, rect.y+rect.height-5, rect.width-10, 5);
+    }
 }
 
 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);
+        m_hint_wnd->SetTranslucency(0);
         m_hint_fadetimer.Stop();
         m_last_hint = wxRect();
         return;
     }
-#endif
 
     // hides a painted hint by redrawing the frame window
     if (!m_last_hint.IsEmpty())
@@ -2570,6 +2599,7 @@ void wxFrameManager::DrawHintRect(wxWindow* pane_window,
     wxDockUIPartArray uiparts;
     wxPaneInfo hint = GetPane(pane_window);
     hint.name = wxT("__HINT__");
+    hint.Show();
 
     if (!hint.IsOk())
         return;
@@ -2635,10 +2665,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
+        pane.frame->SetTranslucency(150);
 }
 
 void wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd)
@@ -2724,26 +2752,20 @@ void wxFrameManager::OnFloatingPaneMoved(wxWindow* wnd)
 
     // if a key modifier is pressed while dragging the frame,
     // don't dock the window
-    if (wxGetKeyState(WXK_CONTROL) || wxGetKeyState(WXK_ALT))
+    if (!wxGetKeyState(WXK_CONTROL) && !wxGetKeyState(WXK_ALT))
     {
-        HideHint();
-        return;
+        // do the drop calculation
+        DoDrop(m_docks, m_panes, pane, client_pt, action_offset);
     }
-
-
-    // do the drop calculation
-    DoDrop(m_docks, m_panes, pane, client_pt, action_offset);
-
+    
     // if the pane is still floating, update it's floating
     // position (that we store)
     if (pane.IsFloating())
     {
         pane.floating_pos = pane.frame->GetPosition();
 
-        #ifdef __WXMSW__
         if (m_flags & wxAUI_MGR_TRANSPARENT_DRAG)
-            MakeWindowTransparent(pane.frame, 255);
-        #endif
+            pane.frame->SetTranslucency(255);
     }
 
     Update();
@@ -2760,39 +2782,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
@@ -2832,6 +2873,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__
@@ -2946,7 +3001,7 @@ void wxFrameManager::UpdateButtonOnScreen(wxDockUIPart* button_ui_part,
              else
             state = wxAUI_BUTTON_STATE_HOVER;
     }
-     else
+    else
     {
         if (event.LeftDown())
             state = wxAUI_BUTTON_STATE_HOVER;
@@ -3232,7 +3287,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();
@@ -3248,15 +3303,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();
 
@@ -3282,7 +3337,7 @@ void wxFrameManager::OnLeftUp(wxMouseEvent& event)
         pane.state &= ~wxPaneInfo::actionPane;
         Update();
     }
-     else
+    else
     {
         event.Skip();
     }
@@ -3323,7 +3378,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);
@@ -3370,13 +3425,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"));
@@ -3470,16 +3525,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"));
+
+    wxPaneInfo& pane = *(evt.pane);
 
-    if (event.button == wxPaneInfo::buttonClose)
+    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())