]> git.saurik.com Git - wxWidgets.git/commitdiff
Add support for transparent hint windows under GTK
authorAlex Bligh <alex@alex.org.uk>
Sat, 22 Jul 2006 17:30:28 +0000 (17:30 +0000)
committerAlex Bligh <alex@alex.org.uk>
Sat, 22 Jul 2006 17:30:28 +0000 (17:30 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40237 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/aui/framemanager.h
samples/aui/auidemo.cpp
src/aui/framemanager.cpp

index a0a78ef8f0c0ed46168bc64c3370a8899f18741d..904f07415b2d11421b61b6f2badc89c6f5545477 100644 (file)
@@ -44,6 +44,10 @@ enum wxFrameManagerOption
     wxAUI_MGR_TRANSPARENT_DRAG      = 1 << 2,
     wxAUI_MGR_TRANSPARENT_HINT      = 1 << 3,
     wxAUI_MGR_TRANSPARENT_HINT_FADE = 1 << 4,
+    // The venetian blind effect is ONLY used when the wxAUI_MGR_TRANSPARENT_HINT has been used, but
+    // at runtime we determine we cannot use transparency (because, for instance, the OS does not support it).
+    // setting this flag drops back in such circumstances (only) to the behaviour without wxAUI_MGR_TRANSPARENT_HINT
+    wxAUI_MGR_DISABLE_VENETIAN_BLINDS = 1 << 5,
 
     wxAUI_MGR_DEFAULT = wxAUI_MGR_ALLOW_FLOATING |
                         wxAUI_MGR_TRANSPARENT_HINT |
@@ -540,6 +544,7 @@ protected:
     wxFrame* m_hint_wnd;         // transparent hint window, if supported by platform
     wxTimer m_hint_fadetimer;    // transparent fade timer
     wxByte m_hint_fadeamt;       // transparent fade amount
+    wxByte m_hint_fademax;       // maximum value of hint fade
 
 #ifndef SWIG
     DECLARE_EVENT_TABLE()
index 36c4aeb7f0546b2a07e2f0cba41d08d37f0feb50..aa6ad6504519390e97cb5eae0c7a4eafb8a8247e 100644 (file)
@@ -913,12 +913,12 @@ void MyFrame::OnManagerFlag(wxCommandEvent& event)
 {
     unsigned int flag = 0;
 
-#if !defined(__WXMSW__) && !defined(__WXMAC__)
+#if !defined(__WXMSW__) && !defined(__WXMAC__) && !defined(__WXGTK__)
     if (event.GetId() == ID_TransparentDrag ||
         event.GetId() == ID_TransparentHint ||
         event.GetId() == ID_TransparentHintFade)
     {
-        wxMessageBox(wxT("This option is presently only available on wxMSW and wxMac"));
+        wxMessageBox(wxT("This option is presently only available on wxGTK, wxMSW and wxMac"));
         return;
     }
 #endif
index 27e9a80df30f935e3ef8525374cb4d8c2dd753ad..2cad663320ceab648bfbe7df4273d0a0fd3de552 100644 (file)
@@ -64,6 +64,107 @@ DEFINE_EVENT_TYPE(wxEVT_AUI_RENDER)
 
 IMPLEMENT_DYNAMIC_CLASS(wxFrameManagerEvent, wxEvent)
 
+class wxPseudoTransparentFrame : public wxFrame
+{
+public:
+    wxPseudoTransparentFrame(wxWindow* parent = NULL,
+                wxWindowID id = -1,
+                const wxString& title = wxT(""),
+                const wxPoint& pos = wxDefaultPosition,
+                const wxSize& size = wxDefaultSize,
+                long style = wxDEFAULT_FRAME_STYLE,
+                const wxString &name = wxT("frame"))
+                    : wxFrame(parent, id, title, pos, size, style | wxFRAME_SHAPED, name)
+    {
+        SetBackgroundStyle(wxBG_STYLE_CUSTOM);
+        m_Amount=0;
+        m_MaxWidth=0;
+        m_MaxHeight=0;
+#ifdef __WXGTK__
+        m_CanSetShape = false; // have to wait for window create event on GTK
+#else
+        m_CanSetShape = true;
+#endif
+        SetTransparent(0);
+    }
+
+    virtual bool SetTransparent(wxByte alpha)
+    {
+        if (m_CanSetShape)
+        {
+            int w=100; // some defaults
+            int h=100;
+            GetClientSize(&w, &h);
+            if ((alpha != m_Amount) || (m_MaxWidth<w) | (m_MaxHeight<h))
+            {
+                // Make the region at least double the height and width so we don't have
+                // to rebuild if the size changes.
+                m_MaxWidth=w*2;
+                m_MaxHeight=h*2;
+                m_Amount = alpha;
+                m_Region.Clear();
+//                             m_Region.Union(0, 0, 1, m_MaxWidth);
+                if (m_Amount)
+                {
+                    for (int y=0; y<m_MaxHeight; 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)<m_Amount)
+                            m_Region.Union(0, y, m_MaxWidth, 1);
+                    }
+                }
+                SetShape(m_Region);
+                Refresh();
+            }
+        }
+        return true;
+    }
+
+    void OnPaint(wxPaintEvent & event)
+    {
+        wxPaintDC dc(this);
+        
+        dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION));
+        dc.SetPen(*wxTRANSPARENT_PEN);
+        
+        wxRegionIterator upd(GetUpdateRegion()); // get the update rect list
+        
+        while (upd)
+        {
+            wxRect rect(upd.GetRect());
+            dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
+
+            upd++;
+        }
+    }
+
+#ifdef __WXGTK__
+    void OnWindowCreate(wxWindowCreateEvent& WXUNUSED(event)) {m_CanSetShape=true; SetTransparent(0);}
+#endif
+
+private:
+    int m_Amount;
+    int m_MaxWidth;
+    int m_MaxHeight;
+    bool m_CanSetShape;
+
+    wxRegion m_Region;
+
+    DECLARE_DYNAMIC_CLASS(wxPseudoTransparentFrame);
+    DECLARE_EVENT_TABLE();
+};
+
+
+IMPLEMENT_DYNAMIC_CLASS( wxPseudoTransparentFrame, wxFrame )
+
+BEGIN_EVENT_TABLE(wxPseudoTransparentFrame, wxFrame)
+    EVT_PAINT(wxPseudoTransparentFrame::OnPaint)
+#ifdef __WXGTK__
+    EVT_WINDOW_CREATE(wxPseudoTransparentFrame::OnWindowCreate)
+#endif
+END_EVENT_TABLE()
+
 
 // -- static utility functions --
 
@@ -496,7 +597,7 @@ void wxFrameManager::SetManagedWindow(wxWindow* frame)
 #endif
 
     // Make a window to use for a transparent hint
-#if defined(__WXMSW__)
+#if defined(__WXMSW__) || defined(__WXGTK__)
     m_hint_wnd = new wxFrame(m_frame, -1, wxEmptyString, wxDefaultPosition, wxSize(1,1),
                              wxFRAME_TOOL_WINDOW |
                              wxFRAME_FLOAT_ON_PARENT |
@@ -523,11 +624,23 @@ void wxFrameManager::SetManagedWindow(wxWindow* frame)
     p->SetBackgroundColour(*wxBLUE);
 #endif
 
+    m_hint_fademax=50;
+
     if (m_hint_wnd && !m_hint_wnd->CanSetTransparent())
     {
+
         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, -1, wxEmptyString, wxDefaultPosition, wxSize(1,1),
+                                                wxFRAME_TOOL_WINDOW |
+                                                wxFRAME_FLOAT_ON_PARENT |
+                                                wxFRAME_NO_TASKBAR |
+                                                wxNO_BORDER);
+        
+        m_hint_fademax = 128;
     }    
 }
 
@@ -2462,25 +2575,29 @@ bool wxFrameManager::DoDrop(wxDockInfoArray& docks,
 
 void wxFrameManager::OnHintFadeTimer(wxTimerEvent& WXUNUSED(event))
 {
-    if (!m_hint_wnd || m_hint_fadeamt >= 50)
+    if (!m_hint_wnd || m_hint_fadeamt >= m_hint_fademax)
     {
         m_hint_fadetimer.Stop();
         return;
     }
 
-    m_hint_fadeamt += 5;
+    m_hint_fadeamt += 4;
     m_hint_wnd->SetTransparent(m_hint_fadeamt);
 }
 
 void wxFrameManager::ShowHint(const wxRect& rect)
 {
-    if ((m_flags & wxAUI_MGR_TRANSPARENT_HINT) != 0 && m_hint_wnd)
+    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_last_hint == rect)
             return;
         m_last_hint = rect;
 
-        wxByte initial_fade = 50;
+        wxByte initial_fade = m_hint_fademax;
         if (m_flags & wxAUI_MGR_TRANSPARENT_HINT_FADE)
             initial_fade = 0;
 
@@ -2565,6 +2682,7 @@ void wxFrameManager::HideHint()
     // hides a transparent window hint, if there is one
     if (m_hint_wnd)
     {
+        m_hint_wnd->Show(false);
         m_hint_wnd->SetTransparent(0);
         m_hint_fadetimer.Stop();
         m_last_hint = wxRect();