+private:
+ virtual bool DoSetShape(GdkWindow* window)
+ {
+ gdk_window_shape_combine_mask(window, NULL, 0, 0);
+
+ return true;
+ }
+};
+
+// Version using simple wxRegion.
+class wxNonOwnedWindowShapeImplRegion : public wxNonOwnedWindowShapeImpl
+{
+public:
+ wxNonOwnedWindowShapeImplRegion(wxWindow* win, const wxRegion& region) :
+ wxNonOwnedWindowShapeImpl(win),
+ m_region(region)
+ {
+ }
+
+ virtual bool CanBeDeleted() const { return true; }
+
+private:
+ virtual bool DoSetShape(GdkWindow* window)
+ {
+ gdk_window_shape_combine_region(window, m_region.GetRegion(), 0, 0);
+
+ return true;
+ }
+
+ wxRegion m_region;
+};
+
+#if wxUSE_GRAPHICS_CONTEXT
+
+// Version using more complex wxGraphicsPath.
+class wxNonOwnedWindowShapeImplPath : public wxNonOwnedWindowShapeImpl
+{
+public:
+ wxNonOwnedWindowShapeImplPath(wxWindow* win, const wxGraphicsPath& path) :
+ wxNonOwnedWindowShapeImpl(win),
+ m_path(path),
+ m_mask(CreateShapeBitmap(path), *wxBLACK)
+ {
+
+ m_win->Connect
+ (
+ wxEVT_PAINT,
+ wxPaintEventHandler(wxNonOwnedWindowShapeImplPath::OnPaint),
+ NULL,
+ this
+ );
+ }
+
+ virtual ~wxNonOwnedWindowShapeImplPath()
+ {
+ m_win->Disconnect
+ (
+ wxEVT_PAINT,
+ wxPaintEventHandler(wxNonOwnedWindowShapeImplPath::OnPaint),
+ NULL,
+ this
+ );
+ }
+
+ // Currently we always return false from here, if drawing the border
+ // becomes optional, we could return true if we don't need to draw it.
+ virtual bool CanBeDeleted() const { return false; }
+
+private:
+ wxBitmap CreateShapeBitmap(const wxGraphicsPath& path)
+ {
+ // Draw the path on a bitmap to get the mask we need.
+ //
+ // Notice that using monochrome bitmap here doesn't work because of an
+ // apparent wxGraphicsContext bug in wxGTK, so use a bitmap of screen
+ // depth even if this is wasteful.
+ wxBitmap bmp(m_win->GetSize());
+
+ wxMemoryDC dc(bmp);
+
+ dc.SetBackground(*wxBLACK);
+ dc.Clear();
+
+ wxScopedPtr<wxGraphicsContext> context(wxGraphicsContext::Create(dc));
+ context->SetBrush(*wxWHITE);
+ context->FillPath(path);
+
+ return bmp;
+ }
+
+ virtual bool DoSetShape(GdkWindow *window)
+ {
+ GdkBitmap* bitmap = m_mask.GetBitmap();
+ if ( !bitmap )
+ return false;
+
+ gdk_window_shape_combine_mask(window, bitmap, 0, 0);
+
+ return true;
+ }
+
+ // Draw a shaped window border.
+ void OnPaint(wxPaintEvent& event)
+ {
+ event.Skip();
+
+ wxPaintDC dc(m_win);
+ wxScopedPtr<wxGraphicsContext> context(wxGraphicsContext::Create(dc));
+ context->SetPen(wxPen(*wxLIGHT_GREY, 2));
+ context->StrokePath(m_path);
+ }
+
+ wxGraphicsPath m_path;
+ wxMask m_mask;
+};
+
+#endif // wxUSE_GRAPHICS_CONTEXT