Added wxTopLevelWindow::SetTranslucency and CanSetTranslucency, with

implementations (so far) for wxMSW and wxMac.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40112 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2006-07-16 03:28:23 +00:00
parent 0b850f25d2
commit 50f3c41d61
11 changed files with 226 additions and 166 deletions

View File

@@ -159,6 +159,8 @@ All (GUI):
- Fixed problem with zoom setting in print preview. - Fixed problem with zoom setting in print preview.
- Moved wxRichTextCtrl from the advanced library to its own. - Moved wxRichTextCtrl from the advanced library to its own.
- wxNB_HITTEST_* flags renamed to wxBK_HITTEST_* to serve all book controls. - 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: wxMSW:

View File

@@ -29,6 +29,16 @@ applicable for the two classes above.
\latexignore{\rtfignore{\wxheading{Members}}} \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} \membersection{wxTopLevelWindow::GetIcon}\label{wxtoplevelwindowgeticon}
@@ -271,6 +281,22 @@ Sets the window title.
\helpref{wxTopLevelWindow::GetTitle}{wxtoplevelwindowgettitle} \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} \membersection{wxTopLevelWindow::ShouldPreventAppExit}\label{wxtoplevelwindowshouldpreventappexit}
\constfunc{virtual bool}{ShouldPreventAppExit}{\void} \constfunc{virtual bool}{ShouldPreventAppExit}{\void}

View File

@@ -340,7 +340,7 @@ public:
wxString caption; // caption displayed on the window wxString caption; // caption displayed on the window
wxWindow* window; // window that is in this pane 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 unsigned int state; // a combination of wxPaneState values
int dock_direction; // dock direction (top, bottom, left, right, center) int dock_direction; // dock direction (top, bottom, left, right, center)
@@ -527,9 +527,9 @@ protected:
wxRect m_last_hint; // last hint rectangle wxRect m_last_hint; // last hint rectangle
wxPoint m_last_mouse_move; // last mouse move position (see OnMotion) wxPoint m_last_mouse_move; // last mouse move position (see OnMotion)
wxWindow* m_hint_wnd; // transparent hint window (for now, only msw) wxFrame* m_hint_wnd; // transparent hint window, if supported by platform
wxTimer m_hint_fadetimer; // transparent fade timer (for now, only msw) wxTimer m_hint_fadetimer; // transparent fade timer
int m_hint_fadeamt; // transparent fade amount (for now, only msw) int m_hint_fadeamt; // transparent fade amount
#ifndef SWIG #ifndef SWIG
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()

View File

@@ -69,6 +69,10 @@ public:
virtual bool ShowFullScreen(bool show, long style = wxFULLSCREEN_ALL) ; virtual bool ShowFullScreen(bool show, long style = wxFULLSCREEN_ALL) ;
virtual bool IsFullScreen() const ; virtual bool IsFullScreen() const ;
virtual bool SetTranslucency(int alpha);
virtual bool CanSetTranslucency();
// implementation from now on // implementation from now on
// -------------------------- // --------------------------

View File

@@ -121,6 +121,15 @@
#define TPM_RECURSE 1 #define TPM_RECURSE 1
#endif #endif
#ifndef WS_EX_LAYERED
#define WS_EX_LAYERED 0x80000
#endif
#ifndef LWA_ALPHA
#define LWA_ALPHA 2
#endif
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ListView common control // ListView common control
// Needed by listctrl.cpp // Needed by listctrl.cpp

View File

@@ -70,6 +70,11 @@ public:
// button from the title bar // button from the title bar
bool EnableCloseButton(bool enable = true); 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 // implementation from now on
// -------------------------- // --------------------------

View File

@@ -196,6 +196,10 @@ public:
void CentreOnScreen(int dir = wxBOTH) { DoCentre(dir | wxCENTRE_ON_SCREEN); } void CentreOnScreen(int dir = wxBOTH) { DoCentre(dir | wxCENTRE_ON_SCREEN); }
void CenterOnScreen(int dir = wxBOTH) { CentreOnScreen(dir); } 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 // implementation only from now on
// ------------------------------- // -------------------------------

View 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 // CopyDocksAndPanes() - this utility function creates copies of
// the dock and pane info. wxDockInfo's usually contain pointers // the dock and pane info. wxDockInfo's usually contain pointers
@@ -542,6 +494,40 @@ void wxFrameManager::SetManagedWindow(wxWindow* frame)
CenterPane().PaneBorder(false)); CenterPane().PaneBorder(false));
} }
#endif #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 // window should have this style by default
if (m_action == actionDragFloatingPane && if (m_action == actionDragFloatingPane &&
(m_flags & wxAUI_MGR_TRANSPARENT_DRAG)) (m_flags & wxAUI_MGR_TRANSPARENT_DRAG))
MakeWindowTransparent(frame, 150); frame->SetTranslucency(150);
frame->SetPaneWindow(p); frame->SetPaneWindow(p);
p.frame = frame; p.frame = frame;
@@ -2450,29 +2436,12 @@ void wxFrameManager::OnHintFadeTimer(wxTimerEvent& WXUNUSED(event))
} }
m_hint_fadeamt += 5; m_hint_fadeamt += 5;
MakeWindowTransparent(m_hint_wnd, m_hint_fadeamt); m_hint_wnd->SetTranslucency(m_hint_fadeamt);
} }
void wxFrameManager::ShowHint(const wxRect& rect) void wxFrameManager::ShowHint(const wxRect& rect)
{ {
#if defined(__WXMSW__) || defined(__WXMAC__) if ((m_flags & wxAUI_MGR_TRANSPARENT_HINT) != 0 && m_hint_wnd)
// 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_last_hint == rect) if (m_last_hint == rect)
return; return;
@@ -2482,36 +2451,7 @@ void wxFrameManager::ShowHint(const wxRect& rect)
if (m_flags & wxAUI_MGR_TRANSPARENT_HINT_FADE) if (m_flags & wxAUI_MGR_TRANSPARENT_HINT_FADE)
initial_fade = 0; initial_fade = 0;
if (m_hint_wnd == NULL) if (! m_hint_wnd->IsShown())
{
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
m_hint_wnd->Show(); m_hint_wnd->Show();
// if we are dragging a floating pane, set the focus // if we are dragging a floating pane, set the focus
@@ -2519,13 +2459,10 @@ void wxFrameManager::ShowHint(const wxRect& rect)
if (m_action == actionDragFloatingPane && m_action_window) if (m_action == actionDragFloatingPane && m_action_window)
m_action_window->SetFocus(); m_action_window->SetFocus();
} m_hint_wnd->SetTranslucency(initial_fade);
else
{
MakeWindowTransparent(m_hint_wnd, initial_fade);
m_hint_wnd->SetSize(rect); m_hint_wnd->SetSize(rect);
m_hint_wnd->Raise(); m_hint_wnd->Raise();
}
if (m_flags & wxAUI_MGR_TRANSPARENT_HINT_FADE) if (m_flags & wxAUI_MGR_TRANSPARENT_HINT_FADE)
{ {
@@ -2534,10 +2471,10 @@ void wxFrameManager::ShowHint(const wxRect& rect)
m_hint_fadetimer.SetOwner(this, 101); m_hint_fadetimer.SetOwner(this, 101);
m_hint_fadetimer.Start(5); m_hint_fadetimer.Start(5);
} }
return;
} }
#endif
else // Not using a translucent hint window...
{
if (m_last_hint != rect) if (m_last_hint != rect)
{ {
@@ -2583,13 +2520,14 @@ void wxFrameManager::ShowHint(const wxRect& rect)
screendc.DrawRectangle(rect.x+rect.width-5, rect.y, 5, rect.height); 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+5, rect.y+rect.height-5, rect.width-10, 5);
} }
}
void wxFrameManager::HideHint() void wxFrameManager::HideHint()
{ {
// hides a transparent window hint, if there is one // hides a transparent window hint, if there is one
if (m_hint_wnd) if (m_hint_wnd)
{ {
MakeWindowTransparent(m_hint_wnd, 0); m_hint_wnd->SetTranslucency(0);
m_hint_fadetimer.Stop(); m_hint_fadetimer.Stop();
m_last_hint = wxRect(); m_last_hint = wxRect();
return; return;
@@ -2696,7 +2634,7 @@ void wxFrameManager::OnFloatingPaneMoveStart(wxWindow* wnd)
wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found")); wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found"));
if (m_flags & wxAUI_MGR_TRANSPARENT_DRAG) if (m_flags & wxAUI_MGR_TRANSPARENT_DRAG)
MakeWindowTransparent(pane.frame, 150); pane.frame->SetTranslucency(150);
} }
void wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd) void wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd)
@@ -2782,15 +2720,11 @@ void wxFrameManager::OnFloatingPaneMoved(wxWindow* wnd)
// if a key modifier is pressed while dragging the frame, // if a key modifier is pressed while dragging the frame,
// don't dock the window // 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 // do the drop calculation
DoDrop(m_docks, m_panes, pane, client_pt, action_offset); DoDrop(m_docks, m_panes, pane, client_pt, action_offset);
}
// if the pane is still floating, update it's floating // if the pane is still floating, update it's floating
// position (that we store) // position (that we store)
@@ -2799,7 +2733,7 @@ void wxFrameManager::OnFloatingPaneMoved(wxWindow* wnd)
pane.floating_pos = pane.frame->GetPosition(); pane.floating_pos = pane.frame->GetPosition();
if (m_flags & wxAUI_MGR_TRANSPARENT_DRAG) if (m_flags & wxAUI_MGR_TRANSPARENT_DRAG)
MakeWindowTransparent(pane.frame, 255); pane.frame->SetTranslucency(255);
} }
Update(); Update();

View File

@@ -1431,6 +1431,21 @@ bool wxTopLevelWindowMac::IsFullScreen() const
return m_macFullScreenData != NULL ; 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) void wxTopLevelWindowMac::SetExtraStyle(long exStyle)
{ {
if ( GetExtraStyle() == exStyle ) if ( GetExtraStyle() == exStyle )

View 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 // wxTopLevelWindow event handling
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -162,6 +162,18 @@ public:
void , CenterOnScreen(int dir = wxBOTH), void , CenterOnScreen(int dir = wxBOTH),
"Center the window on screen", ""); "Center the window on screen", "");
%pythoncode { CentreOnScreen = CenterOnScreen } %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();
}; };