From 1cb7120ac9e002a03dfcf0066e3a69c6554688e4 Mon Sep 17 00:00:00 2001 From: Sean D'Epagnier Date: Fri, 26 Aug 2016 03:56:44 -0400 Subject: [PATCH] support masked or partially transparent windows in wxqt --- Makefile.in | 20 +++++++++++ build/bakefiles/files.bkl | 1 + include/wx/nonownedwnd.h | 2 ++ include/wx/qt/nonownedwnd.h | 30 ++++++++++++++++ src/qt/nonownedwnd.cpp | 68 +++++++++++++++++++++++++++++++++++++ src/qt/region.cpp | 34 +++++++++++++++++-- 6 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 include/wx/qt/nonownedwnd.h create mode 100644 src/qt/nonownedwnd.cpp diff --git a/Makefile.in b/Makefile.in index 25d3327804..22693e6da1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -5036,6 +5036,7 @@ COND_TOOLKIT_QT___LOWLEVEL_SRC_OBJECTS = \ monodll_qt_msgdlg.o \ monodll_qt_notebook.o \ monodll_qt_palette.o \ + monodll_qt_nonownedwnd.o \ monodll_qt_pen.o \ monodll_qt_popupwin.o \ monodll_qt_printdlg.o \ @@ -5744,6 +5745,7 @@ COND_TOOLKIT_QT___LOWLEVEL_SRC_OBJECTS_1 = \ monodll_qt_msgdlg.o \ monodll_qt_notebook.o \ monodll_qt_palette.o \ + monodll_qt_nonownedwnd.o \ monodll_qt_pen.o \ monodll_qt_popupwin.o \ monodll_qt_printdlg.o \ @@ -7060,6 +7062,7 @@ COND_TOOLKIT_QT___LOWLEVEL_SRC_OBJECTS_2 = \ monolib_qt_msgdlg.o \ monolib_qt_notebook.o \ monolib_qt_palette.o \ + monolib_qt_nonownedwnd.o \ monolib_qt_pen.o \ monolib_qt_popupwin.o \ monolib_qt_printdlg.o \ @@ -7768,6 +7771,7 @@ COND_TOOLKIT_QT___LOWLEVEL_SRC_OBJECTS_3 = \ monolib_qt_msgdlg.o \ monolib_qt_notebook.o \ monolib_qt_palette.o \ + monolib_qt_nonownedwnd.o \ monolib_qt_pen.o \ monolib_qt_popupwin.o \ monolib_qt_printdlg.o \ @@ -9228,6 +9232,7 @@ COND_TOOLKIT_QT___LOWLEVEL_SRC_OBJECTS_4 = \ coredll_qt_msgdlg.o \ coredll_qt_notebook.o \ coredll_qt_palette.o \ + coredll_qt_nonownedwnd.o \ coredll_qt_pen.o \ coredll_qt_popupwin.o \ coredll_qt_printdlg.o \ @@ -9936,6 +9941,7 @@ COND_TOOLKIT_QT___LOWLEVEL_SRC_OBJECTS_5 = \ coredll_qt_msgdlg.o \ coredll_qt_notebook.o \ coredll_qt_palette.o \ + coredll_qt_nonownedwnd.o \ coredll_qt_pen.o \ coredll_qt_popupwin.o \ coredll_qt_printdlg.o \ @@ -10704,6 +10710,7 @@ COND_TOOLKIT_QT___LOWLEVEL_SRC_OBJECTS_6 = \ corelib_qt_msgdlg.o \ corelib_qt_notebook.o \ corelib_qt_palette.o \ + corelib_qt_nonownedwnd.o \ corelib_qt_pen.o \ corelib_qt_popupwin.o \ corelib_qt_printdlg.o \ @@ -11412,6 +11419,7 @@ COND_TOOLKIT_QT___LOWLEVEL_SRC_OBJECTS_7 = \ corelib_qt_msgdlg.o \ corelib_qt_notebook.o \ corelib_qt_palette.o \ + corelib_qt_nonownedwnd.o \ corelib_qt_pen.o \ corelib_qt_popupwin.o \ corelib_qt_printdlg.o \ @@ -18730,6 +18738,9 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP) @COND_TOOLKIT_QT_USE_GUI_1@monodll_qt_palette.o: $(srcdir)/src/qt/palette.cpp $(MONODLL_ODEP) @COND_TOOLKIT_QT_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/qt/palette.cpp +@COND_TOOLKIT_QT_USE_GUI_1@monodll_qt_nonownedwnd.o: $(srcdir)/src/qt/nonownedwnd.cpp $(MONODLL_ODEP) +@COND_TOOLKIT_QT_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/qt/nonownedwnd.cpp + @COND_TOOLKIT_QT_USE_GUI_1@monodll_qt_pen.o: $(srcdir)/src/qt/pen.cpp $(MONODLL_ODEP) @COND_TOOLKIT_QT_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/qt/pen.cpp @@ -23587,6 +23598,9 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_QT_USE_GUI_1@monolib_qt_palette.o: $(srcdir)/src/qt/palette.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_QT_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/qt/palette.cpp +@COND_TOOLKIT_QT_USE_GUI_1@monolib_qt_nonownedwnd.o: $(srcdir)/src/qt/nonownedwnd.cpp $(MONOLIB_ODEP) +@COND_TOOLKIT_QT_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/qt/nonownedwnd.cpp + @COND_TOOLKIT_QT_USE_GUI_1@monolib_qt_pen.o: $(srcdir)/src/qt/pen.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_QT_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/qt/pen.cpp @@ -28510,6 +28524,9 @@ coredll_win32.o: $(srcdir)/src/univ/themes/win32.cpp $(COREDLL_ODEP) @COND_TOOLKIT_QT_USE_GUI_1@coredll_qt_palette.o: $(srcdir)/src/qt/palette.cpp $(COREDLL_ODEP) @COND_TOOLKIT_QT_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/qt/palette.cpp +@COND_TOOLKIT_QT_USE_GUI_1@coredll_qt_nonownedwnd.o: $(srcdir)/src/qt/nonownedwnd.cpp $(COREDLL_ODEP) +@COND_TOOLKIT_QT_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/qt/nonownedwnd.cpp + @COND_TOOLKIT_QT_USE_GUI_1@coredll_qt_pen.o: $(srcdir)/src/qt/pen.cpp $(COREDLL_ODEP) @COND_TOOLKIT_QT_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/qt/pen.cpp @@ -31909,6 +31926,9 @@ corelib_win32.o: $(srcdir)/src/univ/themes/win32.cpp $(CORELIB_ODEP) @COND_TOOLKIT_QT_USE_GUI_1@corelib_qt_palette.o: $(srcdir)/src/qt/palette.cpp $(CORELIB_ODEP) @COND_TOOLKIT_QT_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/qt/palette.cpp +@COND_TOOLKIT_QT_USE_GUI_1@corelib_qt_nonownedwnd.o: $(srcdir)/src/qt/nonownedwnd.cpp $(CORELIB_ODEP) +@COND_TOOLKIT_QT_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/qt/nonownedwnd.cpp + @COND_TOOLKIT_QT_USE_GUI_1@corelib_qt_pen.o: $(srcdir)/src/qt/pen.cpp $(CORELIB_ODEP) @COND_TOOLKIT_QT_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/qt/pen.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index d163adb16f..59d4d9d6d8 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -380,6 +380,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/qt/msgdlg.cpp src/qt/notebook.cpp src/qt/palette.cpp + src/qt/nonownedwnd.cpp src/qt/pen.cpp src/qt/popupwin.cpp src/qt/printdlg.cpp diff --git a/include/wx/nonownedwnd.h b/include/wx/nonownedwnd.h index 9beb00da9b..d8bfca3684 100644 --- a/include/wx/nonownedwnd.h +++ b/include/wx/nonownedwnd.h @@ -102,6 +102,8 @@ protected: #include "wx/osx/nonownedwnd.h" #elif defined(__WXMSW__) #include "wx/msw/nonownedwnd.h" +#elif defined(__WXQT__) + #include "wx/qt/nonownedwnd.h" #else // No special class needed in other ports, they can derive both wxTLW and // wxPopupWindow directly from wxWindow and don't implement SetShape(). diff --git a/include/wx/qt/nonownedwnd.h b/include/wx/qt/nonownedwnd.h new file mode 100644 index 0000000000..87df501491 --- /dev/null +++ b/include/wx/qt/nonownedwnd.h @@ -0,0 +1,30 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/qt/nonownedwnd.h +// Author: Sean D'Epagnier +// Copyright: (c) 2016 wxWidgets dev team +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_QT_NONOWNEDWND_H_ +#define _WX_QT_NONOWNEDWND_H_ + +// ---------------------------------------------------------------------------- +// wxNonOwnedWindow contains code common to wx{Popup,TopLevel}Window in wxQT. +// ---------------------------------------------------------------------------- + +class WXDLLIMPEXP_CORE wxNonOwnedWindow : public wxNonOwnedWindowBase +{ +public: + wxNonOwnedWindow(); + +protected: + virtual bool DoClearShape() wxOVERRIDE; + virtual bool DoSetRegionShape(const wxRegion& region) wxOVERRIDE; +#if wxUSE_GRAPHICS_CONTEXT + virtual bool DoSetPathShape(const wxGraphicsPath& path) wxOVERRIDE; +#endif // wxUSE_GRAPHICS_CONTEXT + + wxDECLARE_NO_COPY_CLASS(wxNonOwnedWindow); +}; + +#endif // _WX_QT_NONOWNEDWND_H_ diff --git a/src/qt/nonownedwnd.cpp b/src/qt/nonownedwnd.cpp new file mode 100644 index 0000000000..061ddec816 --- /dev/null +++ b/src/qt/nonownedwnd.cpp @@ -0,0 +1,68 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/qt/nonownedwnd.h +// Author: Sean D'Epagnier +// Copyright: (c) 2016 wxWidgets dev team +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// for compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#ifndef WX_PRECOMP + #include "wx/dcclient.h" + #include "wx/region.h" + #include "wx/region.h" +#endif // WX_PRECOMP + +#include "wx/nonownedwnd.h" +#include "wx/qt/private/converter.h" + +#include +#include +#include + +// ============================================================================ +// wxNonOwnedWindow implementation +// ============================================================================ + +wxNonOwnedWindow::wxNonOwnedWindow() +{ +} + +bool wxNonOwnedWindow::DoClearShape() +{ + GetHandle()->setMask(QBitmap()); + return true; +} + +bool wxNonOwnedWindow::DoSetRegionShape(const wxRegion& region) +{ + QPixmap pixmap(GetHandle()->size()); + QPainter painter(&pixmap); + painter.fillRect(pixmap.rect(), Qt::white); + painter.setClipRegion(region.GetHandle()); + painter.fillRect(pixmap.rect(), Qt::black); + GetHandle()->setMask(pixmap.createMaskFromColor(Qt::white)); + return true; +} + +#if wxUSE_GRAPHICS_CONTEXT +bool wxNonOwnedWindow::DoSetPathShape(const wxGraphicsPath& path) +{ + wxMISSING_IMPLEMENTATION( __FUNCTION__ ); + return true; +} +#endif + diff --git a/src/qt/region.cpp b/src/qt/region.cpp index 6cf474023a..b37b856f14 100644 --- a/src/qt/region.cpp +++ b/src/qt/region.cpp @@ -15,6 +15,7 @@ #include #include +#include class wxRegionRefData: public wxGDIRefData { @@ -34,7 +35,7 @@ class wxRegionRefData: public wxGDIRefData wxRegionRefData( QPolygon p, Qt::FillRule fr ) : m_qtRegion( p, fr ) { } - + wxRegionRefData( const wxRegionRefData& data ) : wxGDIRefData() { @@ -93,9 +94,36 @@ wxRegion::wxRegion(const wxBitmap& bmp) m_refData = new wxRegionRefData( QRect( 0, 0, bmp.GetWidth(), bmp.GetHeight() ) ); } -wxRegion::wxRegion(const wxBitmap& WXUNUSED(bmp), const wxColour& WXUNUSED(transp), int WXUNUSED(tolerance)) +wxRegion::wxRegion(const wxBitmap& bmp, const wxColour& transp, int tolerance) { - wxMISSING_IMPLEMENTATION( __FUNCTION__ ); + if(!bmp.GetHandle()) { + m_refData = new wxRegionRefData(); + return; + } + + if(tolerance == 0) { + m_refData = new wxRegionRefData(bmp.GetHandle()->createMaskFromColor(transp.GetQColor())); + return; + } + + unsigned char raw[bmp.GetWidth()*bmp.GetHeight()]; + memset(raw, 0, bmp.GetWidth()*bmp.GetHeight()); + + QImage img(bmp.GetHandle()->toImage()); + int r = transp.Red(), g = transp.Green(), b = transp.Blue(); + for(int y=0; y tolerance || + abs(c.green() - g) > tolerance || + abs(c.blue() - b) > tolerance) { + int ind = y*img.width()+x; + raw[ind>>3] |= 1<<(ind&7); + } + } + } + + m_refData = new wxRegionRefData(QBitmap::fromData(bmp.GetHandle()->size(), raw)); } bool wxRegion::IsEmpty() const