Merge branch 'win-transparency'
Improve shaped sample and its documentation. See #22230.
This commit is contained in:
@@ -36,6 +36,9 @@
|
||||
#include "wx/dcclient.h"
|
||||
#include "wx/graphics.h"
|
||||
#include "wx/image.h"
|
||||
#include "wx/scopedptr.h"
|
||||
#include "wx/sizer.h"
|
||||
#include "wx/slider.h"
|
||||
|
||||
#ifndef wxHAS_IMAGES_IN_RESOURCES
|
||||
#include "../sample.xpm"
|
||||
@@ -50,6 +53,7 @@ enum
|
||||
{
|
||||
Show_Shaped = 100,
|
||||
Show_Transparent,
|
||||
Show_TransparentBg,
|
||||
|
||||
// must be consecutive and in the same order as wxShowEffect enum elements
|
||||
Show_Effect_First,
|
||||
@@ -134,12 +138,14 @@ private:
|
||||
class SeeThroughFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
void Create();
|
||||
void Create(wxWindow* parent);
|
||||
|
||||
private:
|
||||
// event handlers (these functions should _not_ be virtual)
|
||||
void OnPaint(wxPaintEvent& evt);
|
||||
|
||||
void OnAlpha(wxCommandEvent& event);
|
||||
|
||||
// any class wishing to process wxWidgets events must use this macro
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
};
|
||||
@@ -238,6 +244,7 @@ bool MyApp::OnInit()
|
||||
wxBEGIN_EVENT_TABLE(MainFrame, wxFrame)
|
||||
EVT_MENU(Show_Shaped, MainFrame::OnShowShaped)
|
||||
EVT_MENU(Show_Transparent, MainFrame::OnShowTransparent)
|
||||
EVT_MENU(Show_TransparentBg, MainFrame::OnShowTransparent)
|
||||
EVT_MENU_RANGE(Show_Effect_First, Show_Effect_Last, MainFrame::OnShowEffect)
|
||||
EVT_MENU(wxID_EXIT, MainFrame::OnExit)
|
||||
wxEND_EVENT_TABLE()
|
||||
@@ -252,6 +259,8 @@ MainFrame::MainFrame()
|
||||
wxMenu * const menuFrames = new wxMenu;
|
||||
menuFrames->Append(Show_Shaped, "Show &shaped window\tCtrl-S");
|
||||
menuFrames->Append(Show_Transparent, "Show &transparent window\tCtrl-T");
|
||||
menuFrames->Append(Show_TransparentBg,
|
||||
"Show with &transparent background\tShift-Ctrl-T");
|
||||
menuFrames->AppendSeparator();
|
||||
menuFrames->Append(Show_Effect_Roll, "Show &rolled effect\tCtrl-R");
|
||||
menuFrames->Append(Show_Effect_Slide, "Show s&lide effect\tCtrl-L");
|
||||
@@ -272,19 +281,27 @@ void MainFrame::OnShowShaped(wxCommandEvent& WXUNUSED(event))
|
||||
shapedFrame->Show(true);
|
||||
}
|
||||
|
||||
void MainFrame::OnShowTransparent(wxCommandEvent& WXUNUSED(event))
|
||||
void MainFrame::OnShowTransparent(wxCommandEvent& event)
|
||||
{
|
||||
wxString reason;
|
||||
if (IsTransparentBackgroundSupported(&reason))
|
||||
SeeThroughFrame *seeThroughFrame = new SeeThroughFrame;
|
||||
|
||||
if ( event.GetId() == Show_TransparentBg )
|
||||
{
|
||||
SeeThroughFrame *seeThroughFrame = new SeeThroughFrame;
|
||||
seeThroughFrame->Create();
|
||||
seeThroughFrame->Show(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogError("%s, can't create transparent window.", reason);
|
||||
wxString reason;
|
||||
if (IsTransparentBackgroundSupported(&reason))
|
||||
{
|
||||
seeThroughFrame->SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogError("Can't use transparent background: %s", reason);
|
||||
delete seeThroughFrame;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
seeThroughFrame->Create(this);
|
||||
seeThroughFrame->Show(true);
|
||||
}
|
||||
|
||||
void MainFrame::OnShowEffect(wxCommandEvent& event)
|
||||
@@ -474,44 +491,77 @@ wxBEGIN_EVENT_TABLE(SeeThroughFrame, wxFrame)
|
||||
EVT_PAINT(SeeThroughFrame::OnPaint)
|
||||
wxEND_EVENT_TABLE()
|
||||
|
||||
void SeeThroughFrame::Create()
|
||||
void
|
||||
SeeThroughFrame::Create(wxWindow* parent)
|
||||
{
|
||||
SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
|
||||
wxFrame::Create(NULL, wxID_ANY, "Transparency test",
|
||||
wxPoint(100, 30), wxSize(300, 300),
|
||||
wxFrame::Create(parent, wxID_ANY, "Transparency test",
|
||||
wxDefaultPosition, wxWindow::FromDIP(wxSize(300, 300), parent),
|
||||
wxDEFAULT_FRAME_STYLE |
|
||||
wxFULL_REPAINT_ON_RESIZE |
|
||||
wxSTAY_ON_TOP);
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
|
||||
const int initialAlpha = wxALPHA_OPAQUE / 2;
|
||||
|
||||
// Create control for choosing alpha and put it in the middle of the window.
|
||||
wxPanel* panel = new wxPanel(this);
|
||||
wxSlider* slider = new wxSlider
|
||||
(
|
||||
panel,
|
||||
wxID_ANY,
|
||||
initialAlpha,
|
||||
wxALPHA_TRANSPARENT,
|
||||
wxALPHA_OPAQUE,
|
||||
wxDefaultPosition,
|
||||
FromDIP(wxSize(256, -1)),
|
||||
wxSL_HORIZONTAL | wxSL_LABELS
|
||||
);
|
||||
slider->Bind(wxEVT_SLIDER, &SeeThroughFrame::OnAlpha, this);
|
||||
|
||||
const wxSizerFlags center = wxSizerFlags().Center().Border();
|
||||
|
||||
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
|
||||
sizer->Add(new wxStaticText(panel, wxID_ANY, "Window opacity:"), center);
|
||||
sizer->Add(slider, center);
|
||||
panel->SetSizer(sizer);
|
||||
|
||||
wxSizer* sizerTop = new wxBoxSizer(wxVERTICAL);
|
||||
sizerTop->AddStretchSpacer();
|
||||
sizerTop->Add(panel, center);
|
||||
sizerTop->AddStretchSpacer();
|
||||
SetSizer(sizerTop);
|
||||
|
||||
// Note that this must be called before the frame is shown.
|
||||
SetTransparent(initialAlpha);
|
||||
}
|
||||
|
||||
// Paints a grid of varying hue and alpha
|
||||
void SeeThroughFrame::OnPaint(wxPaintEvent& WXUNUSED(evt))
|
||||
{
|
||||
wxPaintDC dc(this);
|
||||
dc.SetPen(wxNullPen);
|
||||
wxScopedPtr<wxGraphicsContext> gc(wxGraphicsContext::Create(dc));
|
||||
|
||||
int xcount = 8;
|
||||
int ycount = 8;
|
||||
// Draw 3 bands: one opaque, one semi-transparent and one transparent.
|
||||
const wxSize size = GetClientSize();
|
||||
const double h = size.y / 3.0;
|
||||
|
||||
double xstep = 1.0 / xcount;
|
||||
double ystep = 1.0 / ycount;
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.AddRectangle(0, 0, size.x, h);
|
||||
gc->SetBrush(wxBrush(wxColour(0, 0, 255, wxALPHA_OPAQUE)));
|
||||
gc->FillPath(path);
|
||||
|
||||
int width = GetClientSize().GetWidth();
|
||||
int height = GetClientSize().GetHeight();
|
||||
gc->SetBrush(wxBrush(wxColour(0, 0, 255, wxALPHA_OPAQUE / 2)));
|
||||
gc->Translate(0, h);
|
||||
gc->FillPath(path);
|
||||
|
||||
for ( double x = 0; x < 1; x += xstep )
|
||||
{
|
||||
for ( double 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);
|
||||
}
|
||||
}
|
||||
// This blue won't actually be seen and instead the white background will
|
||||
// be visible, because this brush is fully transparent.
|
||||
gc->SetBrush(wxBrush(wxColour(0, 0, 255, wxALPHA_TRANSPARENT)));
|
||||
gc->Translate(0, h);
|
||||
gc->FillPath(path);
|
||||
}
|
||||
|
||||
void SeeThroughFrame::OnAlpha(wxCommandEvent& event)
|
||||
{
|
||||
SetTransparent(event.GetInt());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user