From d205e331cef972a09b2f811529cc97ae3f7bce77 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Thu, 23 Nov 2023 19:03:11 +0100 Subject: [PATCH] Added native wxOverlay implementation under wxQt --- Makefile.in | 24 +++++- build/bakefiles/files.bkl | 1 + build/cmake/files.cmake | 1 + build/files | 1 + include/wx/private/overlay.h | 2 + src/qt/overlay.cpp | 145 +++++++++++++++++++++++++++++++++++ 6 files changed, 170 insertions(+), 4 deletions(-) create mode 100644 src/qt/overlay.cpp diff --git a/Makefile.in b/Makefile.in index 532042fe8f..b3ec7f4260 100644 --- a/Makefile.in +++ b/Makefile.in @@ -5534,7 +5534,8 @@ COND_TOOLKIT_QT___GUI_SRC_OBJECTS = \ monodll_qt_treectrl.o \ monodll_paletteg.o \ monodll_qt_datectrl.o \ - monodll_qt_timectrl.o + monodll_qt_timectrl.o \ + monodll_qt_overlay.o @COND_TOOLKIT_QT@__GUI_SRC_OBJECTS = $(COND_TOOLKIT_QT___GUI_SRC_OBJECTS) @COND_PLATFORM_UNIX_1@__QT_PLATFORM_SRC_OBJECTS = \ @COND_PLATFORM_UNIX_1@ monodll_unix_dialup.o monodll_unix_joystick.o \ @@ -7297,7 +7298,8 @@ COND_TOOLKIT_QT___GUI_SRC_OBJECTS_1 = \ monolib_qt_treectrl.o \ monolib_paletteg.o \ monolib_qt_datectrl.o \ - monolib_qt_timectrl.o + monolib_qt_timectrl.o \ + monolib_qt_overlay.o @COND_TOOLKIT_QT@__GUI_SRC_OBJECTS_1 = $(COND_TOOLKIT_QT___GUI_SRC_OBJECTS_1) @COND_PLATFORM_UNIX_1@__QT_PLATFORM_SRC_OBJECTS_1 = \ @COND_PLATFORM_UNIX_1@ monolib_unix_dialup.o monolib_unix_joystick.o \ @@ -9212,7 +9214,8 @@ COND_TOOLKIT_QT___GUI_SRC_OBJECTS_2 = \ coredll_qt_treectrl.o \ coredll_paletteg.o \ coredll_qt_datectrl.o \ - coredll_qt_timectrl.o + coredll_qt_timectrl.o \ + coredll_qt_overlay.o @COND_TOOLKIT_QT@__GUI_SRC_OBJECTS_2 = $(COND_TOOLKIT_QT___GUI_SRC_OBJECTS_2) @COND_PLATFORM_UNIX_1@__QT_PLATFORM_SRC_OBJECTS_2 = \ @COND_PLATFORM_UNIX_1@ coredll_unix_dialup.o coredll_unix_joystick.o \ @@ -10703,7 +10706,8 @@ COND_TOOLKIT_QT___GUI_SRC_OBJECTS_3 = \ corelib_qt_treectrl.o \ corelib_paletteg.o \ corelib_qt_datectrl.o \ - corelib_qt_timectrl.o + corelib_qt_timectrl.o \ + corelib_qt_overlay.o @COND_TOOLKIT_QT@__GUI_SRC_OBJECTS_3 = $(COND_TOOLKIT_QT___GUI_SRC_OBJECTS_3) @COND_PLATFORM_UNIX_1@__QT_PLATFORM_SRC_OBJECTS_3 = \ @COND_PLATFORM_UNIX_1@ corelib_unix_dialup.o corelib_unix_joystick.o \ @@ -15802,6 +15806,9 @@ monodll_qt_datectrl.o: $(srcdir)/src/qt/datectrl.cpp $(MONODLL_ODEP) monodll_qt_timectrl.o: $(srcdir)/src/qt/timectrl.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/qt/timectrl.cpp +monodll_qt_overlay.o: $(srcdir)/src/qt/overlay.cpp $(MONODLL_ODEP) + $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/qt/overlay.cpp + monodll_mdig.o: $(srcdir)/src/generic/mdig.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/generic/mdig.cpp @@ -20545,6 +20552,9 @@ monolib_qt_datectrl.o: $(srcdir)/src/qt/datectrl.cpp $(MONOLIB_ODEP) monolib_qt_timectrl.o: $(srcdir)/src/qt/timectrl.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/qt/timectrl.cpp +monolib_qt_overlay.o: $(srcdir)/src/qt/overlay.cpp $(MONOLIB_ODEP) + $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/qt/overlay.cpp + monolib_mdig.o: $(srcdir)/src/generic/mdig.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/generic/mdig.cpp @@ -25966,6 +25976,9 @@ coredll_qt_datectrl.o: $(srcdir)/src/qt/datectrl.cpp $(COREDLL_ODEP) coredll_qt_timectrl.o: $(srcdir)/src/qt/timectrl.cpp $(COREDLL_ODEP) $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/qt/timectrl.cpp +coredll_qt_overlay.o: $(srcdir)/src/qt/overlay.cpp $(COREDLL_ODEP) + $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/qt/overlay.cpp + coredll_mdig.o: $(srcdir)/src/generic/mdig.cpp $(COREDLL_ODEP) $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/generic/mdig.cpp @@ -29683,6 +29696,9 @@ corelib_qt_datectrl.o: $(srcdir)/src/qt/datectrl.cpp $(CORELIB_ODEP) corelib_qt_timectrl.o: $(srcdir)/src/qt/timectrl.cpp $(CORELIB_ODEP) $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/qt/timectrl.cpp +corelib_qt_overlay.o: $(srcdir)/src/qt/overlay.cpp $(CORELIB_ODEP) + $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/qt/overlay.cpp + corelib_mdig.o: $(srcdir)/src/generic/mdig.cpp $(CORELIB_ODEP) $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/generic/mdig.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 584d4539f9..ec7c3637fc 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -477,6 +477,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/generic/paletteg.cpp src/qt/datectrl.cpp src/qt/timectrl.cpp + src/qt/overlay.cpp diff --git a/build/cmake/files.cmake b/build/cmake/files.cmake index b66b6cb20a..d04334668e 100644 --- a/build/cmake/files.cmake +++ b/build/cmake/files.cmake @@ -390,6 +390,7 @@ set(QT_SRC src/generic/paletteg.cpp src/qt/datectrl.cpp src/qt/timectrl.cpp + src/qt/overlay.cpp ) set(MEDIA_QT_SRC diff --git a/build/files b/build/files index 278120c6f0..a25c420544 100644 --- a/build/files +++ b/build/files @@ -379,6 +379,7 @@ QT_SRC= src/qt/msgdlg.cpp src/qt/nonownedwnd.cpp src/qt/notebook.cpp + src/qt/overlay.cpp src/qt/pen.cpp src/qt/popupwin.cpp src/qt/printdlg.cpp diff --git a/include/wx/private/overlay.h b/include/wx/private/overlay.h index fc95d53722..fed674b014 100644 --- a/include/wx/private/overlay.h +++ b/include/wx/private/overlay.h @@ -21,6 +21,8 @@ #elif defined(__WXGTK3__) #define wxHAS_NATIVE_OVERLAY 1 #define wxHAS_GENERIC_OVERLAY 1 +#elif defined(__WXQT__) + #define wxHAS_NATIVE_OVERLAY 1 #else #define wxHAS_GENERIC_OVERLAY 1 #endif diff --git a/src/qt/overlay.cpp b/src/qt/overlay.cpp new file mode 100644 index 0000000000..1807bd02b1 --- /dev/null +++ b/src/qt/overlay.cpp @@ -0,0 +1,145 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: src/qt/overlay.cpp +// Author: Ali Kettab +// Created: 2023-11-01 +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#include "wx/wxprec.h" + +#ifdef __WXQT__ + +#include "wx/private/overlay.h" +#include "wx/dc.h" +#include "wx/window.h" + +#include +#include +#include +#include +#include + +// Inspired by QRubberBand implementation + +class wxOverlayWindow : public QWidget +{ +public: + explicit wxOverlayWindow(QWidget* parent) + : QWidget(parent, parent ? Qt::Widget : Qt::ToolTip) + { + if ( !parent ) + setAttribute(Qt::WA_TranslucentBackground); + setAttribute(Qt::WA_TransparentForMouseEvents); + setAttribute(Qt::WA_NoSystemBackground); + setAttribute(Qt::WA_WState_ExplicitShowHide); + setVisible(false); + } + + void SetPicture(QPicture& pict) + { + m_pict.swap(pict); + update(); + } + +private: + + QPicture m_pict; + + virtual void paintEvent(QPaintEvent* WXUNUSED(event)) override + { + QPainter painter(this); + m_pict.play(&painter); + } +}; + +class wxOverlayImpl: public wxOverlay::Impl +{ +public: + wxOverlayImpl() = default; + ~wxOverlayImpl(); + + virtual bool IsOk() override; + virtual void Init(wxDC*, int, int, int, int) override; + virtual void BeginDrawing(wxDC* dc) override; + virtual void EndDrawing(wxDC* dc) override; + virtual void Clear(wxDC* dc) override; + virtual void Reset() override; + + wxWindow* m_target = nullptr; + wxOverlayWindow* m_overlay = nullptr; +}; + +wxOverlay::Impl* wxOverlay::Create() +{ + return new wxOverlayImpl; +} + + +wxOverlayImpl::~wxOverlayImpl() +{ + if ( m_target && !m_target->IsBeingDeleted() ) + { + if ( m_overlay ) + wxDELETE(m_overlay); + } +} + +bool wxOverlayImpl::IsOk() +{ + return m_overlay != nullptr; +} + +void wxOverlayImpl::Init(wxDC* dc, int , int , int , int ) +{ + wxASSERT_MSG( !IsOk() , "You cannot Init an overlay twice" ); + + wxCHECK_RET( dc, "Invalid dc for wxOverlay" ); + + m_target = dc->GetWindow(); + + m_overlay = new wxOverlayWindow(m_target ? m_target->GetHandle() : nullptr); +} + +void wxOverlayImpl::BeginDrawing(wxDC* WXUNUSED(dc)) +{ + wxCHECK_RET( IsOk(), "wxOverlay not initialized" ); + + QRect qtRect = m_target ? m_target->GetHandle()->rect() + : qGuiApp->primaryScreen()->geometry(); + + m_overlay->setGeometry( qtRect ); + m_overlay->show(); + m_overlay->raise(); +} + +void wxOverlayImpl::EndDrawing(wxDC* dc) +{ + wxCHECK_RET( dc, "Invalid dc for wxOverlay" ); + + auto painter = static_cast(dc->GetHandle()); + auto picture = dynamic_cast(painter->device()); + + if ( picture && !picture->isNull() ) + { + // take over the picture and draw it on the overlay window + m_overlay->SetPicture(*picture); + } +} + +void wxOverlayImpl::Clear(wxDC* WXUNUSED(dc)) +{ + // Already cleared by wxQt +} + +void wxOverlayImpl::Reset() +{ + if ( m_overlay ) + { + if ( m_target ) + m_overlay->hide(); + else + wxDELETE(m_overlay); + } +} + +#endif // __WXQT__