added wxBG_STYLE_TRANSPARENT and implemented it for wxMac; documented various transparency-related functions

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@49341 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2007-10-22 21:15:04 +00:00
parent 5a2b31a0d7
commit 4488a1d332
7 changed files with 250 additions and 28 deletions

View File

@ -181,6 +181,7 @@ All (GUI):
- Added support for drop down toolbar buttons (Tim Kosse).
- Added support for labels for toolbar controls (Vince Harron).
- Added wxMessageDialog::SetMessage() and SetExtendedMessage().
- Added wxBG_STYLE_TRANSPARENT background style (Julian Scheid)
- Added XRCSIZERITEM() macro for obtaining sizers from XRC (Brian Vanderburg II)
- New and improved wxFileCtrl (Diaa Sami and Marcin Wojdyr)
- Added wxEventBlocker class (Francesco Montorsi).

View File

@ -226,6 +226,16 @@ called by the user code.
Sets the cached best size value.
\membersection{wxWindow::CanSetTransparent}\label{wxwindowcansettransparent}
\func{bool}{CanSetTransparent}{\void}
Returns \true if the system supports transparent windows and calling
\helpref{SetTransparent}{wxwindowsettransparent} may succeed. If this function
returns \false, transparent windows are definitely not supported by the current
system.
\membersection{wxWindow::CaptureMouse}\label{wxwindowcapturemouse}
\func{virtual void}{CaptureMouse}{\void}
@ -775,19 +785,32 @@ Returns the background colour of the window.
\constfunc{virtual wxBackgroundStyle}{GetBackgroundStyle}{\void}
Returns the background style of the window. The background style indicates
whether background colour should be determined by the system (wxBG\_STYLE\_SYSTEM),
be set to a specific colour (wxBG\_STYLE\_COLOUR), or should be left to the
application to implement (wxBG\_STYLE\_CUSTOM).
On GTK+, use of wxBG\_STYLE\_CUSTOM allows the flicker-free drawing of a custom
background, such as a tiled bitmap. Currently the style has no effect on other platforms.
Returns the background style of the window. The background style can be one of:
\begin{twocollist}\itemsep=0pt
\twocolitem{wxBG\_STYLE\_SYSTEM}{Use the default background, as determined by
the system or the current theme.}
\twocolitem{wxBG\_STYLE\_COLOUR}{Use a solid colour for the background, this
style is set automatically if you call
\helpref{SetBackgroundColour}{wxwindowsetbackgroundcolour} so you only need to
set it explicitly if you had changed the background style to something else
before.}
\twocolitem{wxBG\_STYLE\_CUSTOM}{Don't draw the background at all, it's
supposed that it is drawn by the user-defined erase background event handler.
This style should be used to avoid flicker when the background is entirely
custom-drawn.}
\twocolitem{wxBG\_STYLE\_TRANSPARET}{The background is (partially) transparent,
this style is automatically set if you call
\helpref{SetTransparent}{wxwindowsettransparent} which is used to set the
transparency level.}
\end{twocollist}
\wxheading{See also}
\helpref{wxWindow::SetBackgroundColour}{wxwindowsetbackgroundcolour},\rtfsp
\helpref{wxWindow::GetForegroundColour}{wxwindowgetforegroundcolour},\rtfsp
\helpref{wxWindow::SetBackgroundStyle}{wxwindowsetbackgroundstyle}
\helpref{wxWindow::SetBackgroundStyle}{wxwindowsetbackgroundstyle},\rtfsp
\helpref{wxWindow::SetTransparent}{wxwindowsettransparent}
\membersection{wxWindow::GetEffectiveMinSize}\label{wxwindowgeteffectiveminsize}
@ -2793,19 +2816,15 @@ applications on the system.
\func{virtual void}{SetBackgroundStyle}{\param{wxBackgroundStyle}{ style}}
Sets the background style of the window. The background style indicates
whether background colour should be determined by the system (wxBG\_STYLE\_SYSTEM),
be set to a specific colour (wxBG\_STYLE\_COLOUR), or should be left to the
application to implement (wxBG\_STYLE\_CUSTOM).
On GTK+, use of wxBG\_STYLE\_CUSTOM allows the flicker-free drawing of a custom
background, such as a tiled bitmap. Currently the style has no effect on other platforms.
Sets the background style of the window. see
\helpref{GetBackgroundStyle()}{wxwindowgetbackgroundstyle} for the description
of the possible style values.
\wxheading{See also}
\helpref{wxWindow::SetBackgroundColour}{wxwindowsetbackgroundcolour},\rtfsp
\helpref{wxWindow::GetForegroundColour}{wxwindowgetforegroundcolour},\rtfsp
\helpref{wxWindow::GetBackgroundStyle}{wxwindowgetbackgroundstyle}
\helpref{wxWindow::SetTransparent}{wxwindowsettransparent}
@ -3545,6 +3564,20 @@ See also: \helpref{GetToolTip}{wxwindowgettooltip},
\helpref{wxToolTip}{wxtooltip}
\membersection{wxWindow::SetTransparent}\label{wxwindowsettransparent}
\func{bool}{SetTransparent}{\param{wxByte }{alpha}}
Set the transparency of the window. If the system supports transparent windows,
returns \true, otherwise returns \false and the window remains fully opaque.
See also \helpref{CanSetTransparent}{wxwindowcansettransparent}.
The parameter \arg{alpha} is in the range $0..255$ where $0$ corresponds to a
fully transparent window and $255$ to the fully opaque one. The constants
\texttt{wxIMAGE\_ALPHA\_TRANSPARENT} and \texttt{wxIMAGE\_ALPHA\_OPAQUE} can be
used.
\membersection{wxWindow::SetValidator}\label{wxwindowsetvalidator}
\func{virtual void}{SetValidator}{\param{const wxValidator\&}{ validator}}

View File

@ -1751,7 +1751,8 @@ enum wxBackgroundStyle
{
wxBG_STYLE_SYSTEM,
wxBG_STYLE_COLOUR,
wxBG_STYLE_CUSTOM
wxBG_STYLE_CUSTOM,
wxBG_STYLE_TRANSPARENT
};
/*

View File

@ -70,6 +70,7 @@ public:
virtual bool SetTransparent(wxByte alpha);
virtual bool CanSetTransparent();
virtual bool SetBackgroundStyle(wxBackgroundStyle style);
// implementation from now on
// --------------------------

View File

@ -58,12 +58,13 @@ public:
};
// Define a new frame type: this is going to be our main frame
// Define a new frame type: this is going to the frame showing the
// effect of wxFRAME_SHAPED
class ShapedFrame : public wxFrame
{
public:
// ctor(s)
ShapedFrame();
ShapedFrame(wxFrame *parent);
void SetWindowShape();
// event handlers (these functions should _not_ be virtual)
@ -84,6 +85,35 @@ private:
DECLARE_EVENT_TABLE()
};
// Define a new frame type: this is going to the frame showing the
// effect of wxWindow::SetTransparent and of
// wxWindow::SetBackgroundStyle(wxBG_STYLE_TRANSPARENT)
class SeeThroughFrame : public wxFrame
{
public:
// ctor(s)
SeeThroughFrame();
// event handlers (these functions should _not_ be virtual)
void OnDoubleClick(wxMouseEvent& evt);
void OnPaint(wxPaintEvent& evt);
void OnSize(wxSizeEvent& evt);
private:
enum State
{
STATE_SEETHROUGH,
STATE_TRANSPARENT,
STATE_OPAQUE,
STATE_MAX
};
State m_currentState;
// any class wishing to process wxWidgets events must use this macro
DECLARE_EVENT_TABLE()
};
// ----------------------------------------------------------------------------
// event tables and other macros for wxWidgets
@ -130,10 +160,14 @@ bool MyApp::OnInit()
wxInitAllImageHandlers();
// Create the main application window
ShapedFrame *frame = new ShapedFrame();
frame->Show(true);
SetTopWindow(frame);
// Create the transparent window
SeeThroughFrame *seeThroughFrame = new SeeThroughFrame();
seeThroughFrame->Show(true);
SetTopWindow(seeThroughFrame);
// Create the shaped window
ShapedFrame *shapedFrame = new ShapedFrame(seeThroughFrame);
shapedFrame->Show(true);
// success: wxApp::OnRun() will be called which will enter the main message
// loop and the application will run. If we returned false here, the
@ -142,12 +176,12 @@ bool MyApp::OnInit()
}
// ----------------------------------------------------------------------------
// main frame
// shaped frame
// ----------------------------------------------------------------------------
// frame constructor
ShapedFrame::ShapedFrame()
: wxFrame((wxFrame *)NULL, wxID_ANY, wxEmptyString,
ShapedFrame::ShapedFrame(wxFrame *parent)
: wxFrame(parent, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxSize(100, 100), //wxDefaultSize,
0
| wxFRAME_SHAPED
@ -235,3 +269,93 @@ void ShapedFrame::OnWindowCreate(wxWindowCreateEvent& WXUNUSED(evt))
SetWindowShape();
}
// ----------------------------------------------------------------------------
// see-through frame
// ----------------------------------------------------------------------------
// frame constructor
SeeThroughFrame::SeeThroughFrame()
: wxFrame(NULL, wxID_ANY, "Transparency test: double click here",
wxPoint(100, 30), wxSize(300, 300),
wxDEFAULT_FRAME_STYLE | wxSTAY_ON_TOP),
m_currentState(STATE_SEETHROUGH)
{
SetBackgroundColour(wxColour(255, 255, 255, 255));
SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
}
// Redraws the whole window on resize
void SeeThroughFrame::OnSize(wxSizeEvent& WXUNUSED(evt))
{
Refresh();
}
// Paints a grid of varying hue and alpha
void SeeThroughFrame::OnPaint(wxPaintEvent& WXUNUSED(evt))
{
wxPaintDC dc(this);
dc.SetPen(wxNullPen);
int xcount = 8;
int ycount = 8;
float xstep = 1. / xcount;
float ystep = 1. / ycount;
int width = GetClientSize().GetWidth();
int height = GetClientSize().GetHeight();
for ( float x = 0.; x < 1.; x += xstep )
{
for ( float y = 0.; y < 1.; y += ystep )
{
wxImage::RGBValue v = wxImage::HSVtoRGB(wxImage::HSVValue(x, 1., 1.));
dc.SetBrush(wxBrush(wxColour(v.red, v.green, v.blue,
(int)(255*(1. - y)))));
int x1 = (int)(x * width);
int y1 = (int)(y * height);
int x2 = (int)((x + xstep) * width);
int y2 = (int)((y + ystep) * height);
dc.DrawRectangle(x1, y1, x2 - x1, y2 - y1);
}
}
}
// Switches between colour and transparent background on doubleclick
void SeeThroughFrame::OnDoubleClick(wxMouseEvent& WXUNUSED(evt))
{
m_currentState = (State)((m_currentState + 1) % STATE_MAX);
switch ( m_currentState )
{
case STATE_OPAQUE:
SetBackgroundStyle(wxBG_STYLE_COLOUR);
SetTransparent(255);
SetTitle("Opaque");
break;
case STATE_SEETHROUGH:
SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
SetTransparent(255);
SetTitle("See through");
break;
case STATE_TRANSPARENT:
SetBackgroundStyle(wxBG_STYLE_COLOUR);
SetTransparent(128);
SetTitle("Semi-transparent");
break;
case STATE_MAX:
wxFAIL_MSG( "unreachable" );
}
Refresh();
}
BEGIN_EVENT_TABLE(SeeThroughFrame, wxFrame)
EVT_LEFT_DCLICK(SeeThroughFrame::OnDoubleClick)
EVT_PAINT(SeeThroughFrame::OnPaint)
EVT_SIZE(SeeThroughFrame::OnSize)
END_EVENT_TABLE()

View File

@ -102,6 +102,7 @@ static const EventTypeSpec eventList[] =
{ kEventClassWindow , kEventWindowBoundsChanging } ,
{ kEventClassWindow , kEventWindowBoundsChanged } ,
{ kEventClassWindow , kEventWindowClose } ,
{ kEventClassWindow , kEventWindowGetRegion } ,
// we have to catch these events on the toplevel window level,
// as controls don't get the raw mouse events anymore
@ -804,6 +805,36 @@ static pascal OSStatus wxMacTopLevelWindowEventHandler( EventHandlerCallRef hand
}
break ;
case kEventWindowGetRegion :
{
if ( toplevelWindow->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT )
{
WindowRegionCode windowRegionCode ;
// Fetch the region code that is being queried
GetEventParameter( event,
kEventParamWindowRegionCode,
typeWindowRegionCode, NULL,
sizeof windowRegionCode, NULL,
&windowRegionCode ) ;
// If it is the opaque region code then set the
// region to empty and return noErr to stop event
// propagation
if ( windowRegionCode == kWindowOpaqueRgn ) {
RgnHandle region;
GetEventParameter( event,
kEventParamRgnHandle,
typeQDRgnHandle, NULL,
sizeof region, NULL,
&region) ;
SetEmptyRgn(region) ;
result = noErr ;
}
}
}
break ;
default :
break ;
}
@ -1482,6 +1513,24 @@ void wxTopLevelWindowMac::SetExtraStyle(long exStyle)
#endif
}
bool wxTopLevelWindowMac::SetBackgroundStyle(wxBackgroundStyle style)
{
if ( !wxTopLevelWindowBase::SetBackgroundStyle(style) )
return false ;
WindowRef windowRef = HIViewGetWindow( (HIViewRef)GetHandle() );
if ( GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT )
{
OSStatus err = HIWindowChangeFeatures( windowRef, 0, kWindowIsOpaque );
verify_noerr( err );
err = ReshapeCustomWindow( windowRef );
verify_noerr( err );
}
return true ;
}
// TODO: switch to structure bounds -
// we are still using coordinates of the content view
//

View File

@ -278,6 +278,15 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl
}
}
CGContextSetAlpha( cgContext , alpha ) ;
if ( thisWindow->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT )
{
HIRect bounds;
HIViewGetBounds( controlRef, &bounds );
CGContextClearRect( cgContext, bounds );
}
#endif
if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) )
result = noErr ;
@ -2363,7 +2372,8 @@ void wxWindowMac::OnEraseBackground(wxEraseEvent& event)
return ;
#if TARGET_API_MAC_OSX
if ( !m_macBackgroundBrush.Ok() || m_macBackgroundBrush.GetStyle() == wxTRANSPARENT )
if ( !m_macBackgroundBrush.Ok() || m_macBackgroundBrush.GetStyle() == wxTRANSPARENT
|| GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT )
{
event.Skip() ;
}
@ -3343,7 +3353,8 @@ void wxWindowMac::OnMouseEvent( wxMouseEvent &event )
void wxWindowMac::OnPaint( wxPaintEvent & event )
{
if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL )
if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL
&& GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT )
CallNextEventHandler(
(EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() ,
(EventRef) wxTheApp->MacGetCurrentEvent() ) ;
@ -3387,6 +3398,8 @@ bool wxWindowMac::Reparent(wxWindowBase *newParentBase)
bool wxWindowMac::SetTransparent(wxByte alpha)
{
#if wxMAC_USE_CORE_GRAPHICS
SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
if ( alpha != m_macAlpha )
{
m_macAlpha = alpha ;