]> git.saurik.com Git - wxWidgets.git/commitdiff
Added wxTopLevelWindow::SetTranslucency and CanSetTranslucency, with
authorRobin Dunn <robin@alldunn.com>
Sun, 16 Jul 2006 03:28:23 +0000 (03:28 +0000)
committerRobin Dunn <robin@alldunn.com>
Sun, 16 Jul 2006 03:28:23 +0000 (03:28 +0000)
implementations (so far) for wxMSW and wxMac.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40112 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
docs/latex/wx/tlw.tex
include/wx/aui/framemanager.h
include/wx/mac/carbon/toplevel.h
include/wx/msw/missing.h
include/wx/msw/toplevel.h
include/wx/toplevel.h
src/aui/framemanager.cpp
src/mac/carbon/toplevel.cpp
src/msw/toplevel.cpp
wxPython/src/_toplvl.i

index a06114daedff292e059f612bac036a16b4384ff9..462bec058a4514228a4ce67a6926669dc245fb02 100644 (file)
@@ -159,6 +159,8 @@ All (GUI):
 - Fixed problem with zoom setting in print preview.
 - Moved wxRichTextCtrl from the advanced library to its own.
 - wxNB_HITTEST_* flags renamed to wxBK_HITTEST_* to serve all book controls.
+- Added wxTopLevelWindow::SetTranslucency and CanSetTranslucency, with
+  implementations (so far) for wxMSW and wxMac.
 
 wxMSW:
 
index 770b9e34cd12473b5906d654243b04c436e0fc03..ee1ba586baeba1ea5fbd2021b93f6a1688b013d9 100644 (file)
@@ -29,6 +29,16 @@ applicable for the two classes above.
 
 \latexignore{\rtfignore{\wxheading{Members}}}
 
+\membersection{wxTopLevelWindow::CanSetTranslucency}\label{wxtoplevelwindowcansettranslucency}
+
+\func{virtual bool}{CanSetTranslucency}{\void}
+
+Returns \true if the platform supports making the window translucent.
+
+\wxheading{See also}
+
+\helpref{wxTopLevelWindow::SetTranslucency}{wxtoplevelwindowsettranslucency}
+
 
 \membersection{wxTopLevelWindow::GetIcon}\label{wxtoplevelwindowgeticon}
 
@@ -271,6 +281,22 @@ Sets the window title.
 \helpref{wxTopLevelWindow::GetTitle}{wxtoplevelwindowgettitle}
 
 
+\membersection{wxTopLevelWindow::SetTranslucency}\label{wxtoplevelwindowsettranslucency}
+
+\func{virtual bool}{SetTranslucency}{\param{int }{ alpha}}
+
+If the platform supports it will set the window to be translucent
+
+\wxheading{Parameters}
+
+\docparam{alpha}{Determines how opaque or transparent the window will
+  be.  A value of 0 sets the window to be fully transparent, and a
+  value of 255 sets the window to be fully opaque.}
+
+Returns \true if the translucency was successfully changed.
+
+
+
 \membersection{wxTopLevelWindow::ShouldPreventAppExit}\label{wxtoplevelwindowshouldpreventappexit}
 
 \constfunc{virtual bool}{ShouldPreventAppExit}{\void}
index 7c4390a5eb751740dbf6ec2355fb17df4d8bc4a2..250afd6d91485483628472cc78013cc26a9e9c55 100644 (file)
@@ -340,7 +340,7 @@ public:
     wxString caption;     // caption displayed on the window
 
     wxWindow* window;     // window that is in this pane
-    wxWindow* frame;      // floating frame window that holds the pane
+    wxFrame* frame;       // floating frame window that holds the pane
     unsigned int state;   // a combination of wxPaneState values
 
     int dock_direction;   // dock direction (top, bottom, left, right, center)
@@ -527,9 +527,9 @@ protected:
     wxRect m_last_hint;          // last hint rectangle
     wxPoint m_last_mouse_move;   // last mouse move position (see OnMotion)
 
-    wxWindow* m_hint_wnd;        // transparent hint window (for now, only msw)
-    wxTimer m_hint_fadetimer;    // transparent fade timer (for now, only msw)
-    int m_hint_fadeamt;          // transparent fade amount (for now, only msw)
+    wxFrame* m_hint_wnd;         // transparent hint window, if supported by platform
+    wxTimer m_hint_fadetimer;    // transparent fade timer
+    int m_hint_fadeamt;          // transparent fade amount
 
 #ifndef SWIG
     DECLARE_EVENT_TABLE()
index 9383af61c6582103d13b96c61c6021af2c0f9061..cdffba933f7ed979e2c122d33152769ef3fde5ef 100644 (file)
@@ -69,6 +69,10 @@ public:
     virtual bool ShowFullScreen(bool show, long style = wxFULLSCREEN_ALL) ;
     virtual bool IsFullScreen() const ;
 
+    virtual bool SetTranslucency(int alpha);
+    virtual bool CanSetTranslucency();
+
+
     // implementation from now on
     // --------------------------
 
index dae3338a0fb2b869e80025e969d16d23f745850f..a62f97b6c2e79c6d40ace84a288272380575e9b4 100644 (file)
 #define TPM_RECURSE 1
 #endif
 
+
+#ifndef WS_EX_LAYERED
+#define WS_EX_LAYERED 0x80000
+#endif
+
+#ifndef LWA_ALPHA
+#define LWA_ALPHA 2
+#endif
+
 // ----------------------------------------------------------------------------
 // ListView common control
 // Needed by listctrl.cpp
index 3647a33b9b62a938f1267201014e7aa9d2ee8434..f8d064c24bb37814cb2bfcf137c768fdee497404 100644 (file)
@@ -70,6 +70,11 @@ public:
     // button from the title bar
     bool EnableCloseButton(bool enable = true);
 
+    // Set window transparency if the platform supports it
+    virtual bool SetTranslucency(int alpha);
+    virtual bool CanSetTranslucency();
+
+    
     // implementation from now on
     // --------------------------
 
index 69c5a76ac1a7379faaf822732aa33171ec299d44..50409bb5ce9e971dfbf33e41be664e7c824ac799 100644 (file)
@@ -196,7 +196,11 @@ public:
     void CentreOnScreen(int dir = wxBOTH) { DoCentre(dir | wxCENTRE_ON_SCREEN); }
     void CenterOnScreen(int dir = wxBOTH) { CentreOnScreen(dir); }
 
+    // Set window transparency if the platform supports it
+    virtual bool SetTranslucency(int WXUNUSED(alpha)) { return false; }
+    virtual bool CanSetTranslucency() { return false; }
 
+    
     // implementation only from now on
     // -------------------------------
 
index 27e3bf941619124aeed9df3f5662bae8e1ce865b..286df116e54e64dfe6e9f74eb9c2d7f30f6e51ef 100644 (file)
@@ -86,54 +86,6 @@ static void DrawResizeHint(wxDC& dc, const wxRect& rect)
 }
 
 
-// on supported windows systems (Win2000 and greater, Mac), this function
-// will make a frame window transparent by a certain amount
-static void MakeWindowTransparent(wxWindow* wnd, int amount)
-{
-#if defined(__WXMSW__)
-    // 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,
-#ifdef __WXWINCE__
-                                                 wxT("SetLayeredWindowAttributes")
-#else
-                                                 "SetLayeredWindowAttributes"
-#endif
-                                               );
-    }
-
-    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*/);
-
-#elif defined(__WXMAC__)
-
-    WindowRef handle = GetControlOwner((OpaqueControlRef*)wnd->GetHandle());
-    SetWindowAlpha(handle, float(amount)/ 255.0);
-
-#else
-    wxUnusedVar(wnd);
-    wxUnusedVar(amount);
-#endif
-}
-
-
 
 // CopyDocksAndPanes() - this utility function creates copies of
 // the dock and pane info.  wxDockInfo's usually contain pointers
@@ -542,6 +494,40 @@ void wxFrameManager::SetManagedWindow(wxWindow* 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;
+    }    
 }
 
 
@@ -1822,7 +1808,7 @@ void wxFrameManager::Update()
                 // window should have this style by default
                 if (m_action == actionDragFloatingPane &&
                     (m_flags & wxAUI_MGR_TRANSPARENT_DRAG))
-                        MakeWindowTransparent(frame, 150);
+                        frame->SetTranslucency(150);
 
                 frame->SetPaneWindow(p);
                 p.frame = frame;
@@ -2450,29 +2436,12 @@ void wxFrameManager::OnHintFadeTimer(wxTimerEvent& WXUNUSED(event))
     }
 
     m_hint_fadeamt += 5;
-    MakeWindowTransparent(m_hint_wnd, m_hint_fadeamt);
+    m_hint_wnd->SetTranslucency(m_hint_fadeamt);
 }
 
 void wxFrameManager::ShowHint(const wxRect& rect)
 {
-#if defined(__WXMSW__) || defined(__WXMAC__)
-    // 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
-#ifdef __WXMSW__
-        && os_type == wxWINDOWS_NT && ver_major >= 5
-#endif
-        )
+    if ((m_flags & wxAUI_MGR_TRANSPARENT_HINT) != 0 && m_hint_wnd)
     {
         if (m_last_hint == rect)
             return;
@@ -2482,50 +2451,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();
-#if defined(__WXMSW__)
-            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));
-#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, pt, size,
-                                         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->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
-        {
-            MakeWindowTransparent(m_hint_wnd, initial_fade);
-            m_hint_wnd->SetSize(rect);
-            m_hint_wnd->Raise();
-        }
+        m_hint_wnd->SetTranslucency(initial_fade);
+        m_hint_wnd->SetSize(rect);
+        m_hint_wnd->Raise();
+        
 
         if (m_flags & wxAUI_MGR_TRANSPARENT_HINT_FADE)
         {
@@ -2534,54 +2471,55 @@ void wxFrameManager::ShowHint(const wxRect& rect)
             m_hint_fadetimer.SetOwner(this, 101);
             m_hint_fadetimer.Start(5);
         }
-
-        return;
     }
-#endif
-    
-    if (m_last_hint != rect)
-    {
-        // remove the last hint rectangle
-        m_last_hint = rect;
-        m_frame->Refresh();
-        m_frame->Update();
-    }
-
-    wxScreenDC screendc;
-    wxRegion clip(1, 1, 10000, 10000);
 
-    // 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)
+    else  // Not using a translucent hint window...
     {
-        wxPaneInfo& pane = m_panes.Item(i);
+        
+        if (m_last_hint != rect)
+        {
+            // remove the last hint rectangle
+            m_last_hint = rect;
+            m_frame->Refresh();
+            m_frame->Update();
+        }
+
+        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()
@@ -2589,7 +2527,7 @@ void wxFrameManager::HideHint()
     // 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;
@@ -2696,7 +2634,7 @@ void wxFrameManager::OnFloatingPaneMoveStart(wxWindow* wnd)
     wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
 
     if (m_flags & wxAUI_MGR_TRANSPARENT_DRAG)
-        MakeWindowTransparent(pane.frame, 150);
+        pane.frame->SetTranslucency(150);
 }
 
 void wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd)
@@ -2782,16 +2720,12 @@ 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())
@@ -2799,7 +2733,7 @@ void wxFrameManager::OnFloatingPaneMoved(wxWindow* wnd)
         pane.floating_pos = pane.frame->GetPosition();
 
         if (m_flags & wxAUI_MGR_TRANSPARENT_DRAG)
-            MakeWindowTransparent(pane.frame, 255);
+            pane.frame->SetTranslucency(255);
     }
 
     Update();
index 7c57eeed8674219a20f34283ca8df94ba120c0b6..5d77fdc67328b4e3b71ed302c222b9f6e560b017 100644 (file)
@@ -1431,6 +1431,21 @@ bool wxTopLevelWindowMac::IsFullScreen() const
     return m_macFullScreenData != NULL ;
 }
 
+
+bool wxTopLevelWindowMac::SetTranslucency(int alpha)
+{
+    WindowRef handle = GetControlOwner((OpaqueControlRef*)GetHandle());
+    OSStatus result = SetWindowAlpha(handle, float(alpha)/255.0);
+    return result == noErr;
+}
+
+
+bool wxTopLevelWindowMac::CanSetTranslucency()
+{
+    return true;
+}
+
+
 void wxTopLevelWindowMac::SetExtraStyle(long exStyle)
 {
     if ( GetExtraStyle() == exStyle )
index 07897473234d2cba671a00166885fbdb7187571d..e0a489a759df48741bb343f53225adf22fde8228 100644 (file)
@@ -1043,6 +1043,55 @@ void wxTopLevelWindowMSW::RequestUserAttention(int flags)
     }
 }
 
+// ---------------------------------------------------------------------------
+
+bool wxTopLevelWindowMSW::SetTranslucency(int alpha)
+{
+    typedef DWORD (WINAPI *PSETLAYEREDWINDOWATTR)(HWND, DWORD, BYTE, DWORD);
+    static PSETLAYEREDWINDOWATTR pSetLayeredWindowAttributes = NULL;
+
+    if (alpha < 0) alpha = 0;
+    if (alpha > 255) alpha = 255;
+    
+    if ( pSetLayeredWindowAttributes == NULL )
+    {
+        wxDynamicLibrary dllUser32(_T("user32.dll"));
+        pSetLayeredWindowAttributes = (PSETLAYEREDWINDOWATTR)
+            dllUser32.GetSymbol(wxT("SetLayeredWindowAttributes"));
+    }
+    if ( pSetLayeredWindowAttributes == NULL )
+        return false;
+
+    LONG exstyle = GetWindowLong(GetHwnd(), GWL_EXSTYLE);
+
+    // if setting alpha to fully opaque then turn off the layered style
+    if (alpha == 255)
+    {
+        SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyle & ~WS_EX_LAYERED);
+        Refresh();
+        return true;
+    }
+
+    // Otherwise, set the layered style if needed and set the alpha value
+    if ((exstyle & WS_EX_LAYERED) == 0 )
+        SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyle | WS_EX_LAYERED);
+
+    return pSetLayeredWindowAttributes(GetHwnd(), 0, (BYTE)alpha, LWA_ALPHA) != 0;   
+}
+
+bool wxTopLevelWindowMSW::CanSetTranslucency()
+{
+    // The API is available on win2k and above
+    
+    static int os_type = -1;
+    static int ver_major = -1;
+
+    if (os_type == -1)
+        os_type = ::wxGetOsVersion(&ver_major);
+
+    return (os_type == wxWINDOWS_NT && ver_major >= 5);
+}
+
 // ----------------------------------------------------------------------------
 // wxTopLevelWindow event handling
 // ----------------------------------------------------------------------------
index e9e6c60fd153789bedd2cbd5d92e4d7401d8b292..c9aa280142cf51a934a720e5b3b2949b509636bb 100644 (file)
@@ -162,6 +162,18 @@ public:
         void , CenterOnScreen(int dir = wxBOTH),
         "Center the window on screen", "");
     %pythoncode { CentreOnScreen = CenterOnScreen }
+
+#ifdef __WXMSW__
+    bool EnableCloseButton(bool enable = true);
+#else
+    %extend {
+        bool EnableCloseButton(bool enable = true) { return false; }
+    }
+#endif
+
+    virtual bool SetTranslucency(int alpha); 
+    virtual bool CanSetTranslucency();
+
 };