From 42b0d8b96d2b4246ccfbe985639ee40f94225b5b Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Mon, 22 Jan 2007 15:04:49 +0000 Subject: [PATCH] implemented wxPopupWindow for wxDFB; added wxNonOwnedWindow as base class for wxTopLevelWindow and wxPopupWindow git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@44289 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- Makefile.in | 23 ++ build/bakefiles/files.bkl | 4 + build/msw/wx_core.dsp | 4 + include/wx/dfb/nonownedwnd.h | 118 +++++++++ include/wx/dfb/popupwin.h | 45 ++++ include/wx/dfb/toplevel.h | 63 ----- include/wx/dfb/window.h | 8 +- include/wx/nonownedwnd.h | 24 ++ include/wx/popupwin.h | 6 +- include/wx/toplevel.h | 4 +- src/dfb/nonownedwnd.cpp | 452 +++++++++++++++++++++++++++++++++++ src/dfb/toplevel.cpp | 406 +------------------------------ 12 files changed, 683 insertions(+), 474 deletions(-) create mode 100644 include/wx/dfb/nonownedwnd.h create mode 100644 include/wx/dfb/popupwin.h create mode 100644 include/wx/nonownedwnd.h create mode 100644 src/dfb/nonownedwnd.cpp diff --git a/Makefile.in b/Makefile.in index fd120e7e82..dc02d63f45 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1755,7 +1755,9 @@ COND_TOOLKIT_DFB_LOWLEVEL_HDR = \ wx/dfb/dfbptr.h \ wx/dfb/evtloop.h \ wx/dfb/font.h \ + wx/dfb/nonownedwnd.h \ wx/dfb/pen.h \ + wx/dfb/popupwin.h \ wx/dfb/private.h \ wx/dfb/region.h \ wx/dfb/toplevel.h \ @@ -2977,6 +2979,7 @@ COND_USE_GUI_1_ALL_GUI_HEADERS = \ wx/menuitem.h \ wx/metafile.h \ wx/minifram.h \ + wx/nonownedwnd.h \ wx/notebook.h \ wx/ownerdrw.h \ wx/paper.h \ @@ -3750,6 +3753,7 @@ COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS = \ monodll_font.o \ monodll_fontenum.o \ monodll_fontmgr.o \ + monodll_nonownedwnd.o \ monodll_overlay.o \ monodll_pen.o \ monodll_region.o \ @@ -4583,6 +4587,7 @@ COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS_1 = \ monodll_font.o \ monodll_fontenum.o \ monodll_fontmgr.o \ + monodll_nonownedwnd.o \ monodll_overlay.o \ monodll_pen.o \ monodll_region.o \ @@ -5533,6 +5538,7 @@ COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS_2 = \ monolib_font.o \ monolib_fontenum.o \ monolib_fontmgr.o \ + monolib_nonownedwnd.o \ monolib_overlay.o \ monolib_pen.o \ monolib_region.o \ @@ -6367,6 +6373,7 @@ COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS_3 = \ monolib_font.o \ monolib_fontenum.o \ monolib_fontmgr.o \ + monolib_nonownedwnd.o \ monolib_overlay.o \ monolib_pen.o \ monolib_region.o \ @@ -7546,6 +7553,7 @@ COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS_4 = \ coredll_font.o \ coredll_fontenum.o \ coredll_fontmgr.o \ + coredll_nonownedwnd.o \ coredll_overlay.o \ coredll_pen.o \ coredll_region.o \ @@ -8380,6 +8388,7 @@ COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS_5 = \ coredll_font.o \ coredll_fontenum.o \ coredll_fontmgr.o \ + coredll_nonownedwnd.o \ coredll_overlay.o \ coredll_pen.o \ coredll_region.o \ @@ -9003,6 +9012,7 @@ COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS_6 = \ corelib_font.o \ corelib_fontenum.o \ corelib_fontmgr.o \ + corelib_nonownedwnd.o \ corelib_overlay.o \ corelib_pen.o \ corelib_region.o \ @@ -9837,6 +9847,7 @@ COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS_7 = \ corelib_font.o \ corelib_fontenum.o \ corelib_fontmgr.o \ + corelib_nonownedwnd.o \ corelib_overlay.o \ corelib_pen.o \ corelib_region.o \ @@ -14869,6 +14880,9 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP) @COND_TOOLKIT_DFB_USE_GUI_1@monodll_fontmgr.o: $(srcdir)/src/dfb/fontmgr.cpp $(MONODLL_ODEP) @COND_TOOLKIT_DFB_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/dfb/fontmgr.cpp +@COND_TOOLKIT_DFB_USE_GUI_1@monodll_nonownedwnd.o: $(srcdir)/src/dfb/nonownedwnd.cpp $(MONODLL_ODEP) +@COND_TOOLKIT_DFB_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/dfb/nonownedwnd.cpp + @COND_TOOLKIT_DFB_USE_GUI_1@monodll_overlay.o: $(srcdir)/src/dfb/overlay.cpp $(MONODLL_ODEP) @COND_TOOLKIT_DFB_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/dfb/overlay.cpp @@ -18991,6 +19005,9 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_DFB_USE_GUI_1@monolib_fontmgr.o: $(srcdir)/src/dfb/fontmgr.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_DFB_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/dfb/fontmgr.cpp +@COND_TOOLKIT_DFB_USE_GUI_1@monolib_nonownedwnd.o: $(srcdir)/src/dfb/nonownedwnd.cpp $(MONOLIB_ODEP) +@COND_TOOLKIT_DFB_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/dfb/nonownedwnd.cpp + @COND_TOOLKIT_DFB_USE_GUI_1@monolib_overlay.o: $(srcdir)/src/dfb/overlay.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_DFB_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/dfb/overlay.cpp @@ -23494,6 +23511,9 @@ coredll_win32.o: $(srcdir)/src/univ/themes/win32.cpp $(COREDLL_ODEP) @COND_TOOLKIT_DFB_USE_GUI_1@coredll_fontmgr.o: $(srcdir)/src/dfb/fontmgr.cpp $(COREDLL_ODEP) @COND_TOOLKIT_DFB_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/dfb/fontmgr.cpp +@COND_TOOLKIT_DFB_USE_GUI_1@coredll_nonownedwnd.o: $(srcdir)/src/dfb/nonownedwnd.cpp $(COREDLL_ODEP) +@COND_TOOLKIT_DFB_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/dfb/nonownedwnd.cpp + @COND_TOOLKIT_DFB_USE_GUI_1@coredll_overlay.o: $(srcdir)/src/dfb/overlay.cpp $(COREDLL_ODEP) @COND_TOOLKIT_DFB_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/dfb/overlay.cpp @@ -26452,6 +26472,9 @@ corelib_win32.o: $(srcdir)/src/univ/themes/win32.cpp $(CORELIB_ODEP) @COND_TOOLKIT_DFB_USE_GUI_1@corelib_fontmgr.o: $(srcdir)/src/dfb/fontmgr.cpp $(CORELIB_ODEP) @COND_TOOLKIT_DFB_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/dfb/fontmgr.cpp +@COND_TOOLKIT_DFB_USE_GUI_1@corelib_nonownedwnd.o: $(srcdir)/src/dfb/nonownedwnd.cpp $(CORELIB_ODEP) +@COND_TOOLKIT_DFB_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/dfb/nonownedwnd.cpp + @COND_TOOLKIT_DFB_USE_GUI_1@corelib_overlay.o: $(srcdir)/src/dfb/overlay.cpp $(CORELIB_ODEP) @COND_TOOLKIT_DFB_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/dfb/overlay.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 39fb135e8b..2c4dda0a95 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -841,6 +841,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/menuitem.h wx/metafile.h wx/minifram.h + wx/nonownedwnd.h wx/notebook.h wx/ownerdrw.h wx/paper.h @@ -1839,6 +1840,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/dfb/font.cpp src/dfb/fontenum.cpp src/dfb/fontmgr.cpp + src/dfb/nonownedwnd.cpp src/dfb/overlay.cpp src/dfb/pen.cpp src/dfb/region.cpp @@ -1867,7 +1869,9 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/dfb/dfbptr.h wx/dfb/evtloop.h wx/dfb/font.h + wx/dfb/nonownedwnd.h wx/dfb/pen.h + wx/dfb/popupwin.h wx/dfb/private.h wx/dfb/region.h wx/dfb/toplevel.h diff --git a/build/msw/wx_core.dsp b/build/msw/wx_core.dsp index 4363358168..6d18b3219e 100644 --- a/build/msw/wx_core.dsp +++ b/build/msw/wx_core.dsp @@ -9105,6 +9105,10 @@ SOURCE=..\..\include\wx\msgdlg.h # End Source File # Begin Source File +SOURCE=..\..\include\wx\nonownedwnd.h +# End Source File +# Begin Source File + SOURCE=..\..\include\wx\notebook.h # End Source File # Begin Source File diff --git a/include/wx/dfb/nonownedwnd.h b/include/wx/dfb/nonownedwnd.h new file mode 100644 index 0000000000..6c4e731d5c --- /dev/null +++ b/include/wx/dfb/nonownedwnd.h @@ -0,0 +1,118 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/dfb/nonownedwnd.h +// Purpose: declares wxNonTopLevelWindow class +// Author: Vaclav Slavik +// Modified by: +// Created: 2006-12-24 +// RCS-ID: $Id$ +// Copyright: (c) 2006 TT-Solutions +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_DFB_NONOWNEDWND_H_ +#define _WX_DFB_NONOWNEDWND_H_ + +#include "wx/window.h" +#include "wx/dfb/dfbptr.h" + +wxDFB_DECLARE_INTERFACE(IDirectFBWindow); +class wxDfbQueuedPaintRequests; +struct wxDFBWindowEvent; + +//----------------------------------------------------------------------------- +// wxNonOwnedWindow +//----------------------------------------------------------------------------- + +// This class represents "non-owned" window. A window is owned by another +// window if it has a parent and is positioned within the parent. For example, +// wxFrame is non-owned, because even though it can have a parent, it's +// location is independent of it. This class is for internal use only, it's +// the base class for wxTopLevelWindow and wxPopupWindow. +class WXDLLIMPEXP_CORE wxNonOwnedWindow : public wxWindow +{ +public: + // construction + wxNonOwnedWindow() { Init(); } + wxNonOwnedWindow(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxPanelNameStr) + { + Init(); + + Create(parent, id, pos, size, style, name); + } + + bool Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxPanelNameStr); + + virtual ~wxNonOwnedWindow(); + + // implement base class pure virtuals + virtual bool Show(bool show = true); + + virtual void Update(); + + // implementation from now on + // -------------------------- + + void OnInternalIdle(); + + wxIDirectFBWindowPtr GetDirectFBWindow() const { return m_dfbwin; } + + // Returns true if some invalidated area of the TLW is currently being + // painted + bool IsPainting() const { return m_isPainting; } + +protected: + // common part of all ctors + void Init(); + + virtual wxIDirectFBSurfacePtr ObtainDfbSurface() const; + + // overriden wxWindow methods + virtual void DoGetPosition(int *x, int *y) const; + virtual void DoGetSize(int *width, int *height) const; + virtual void DoMoveWindow(int x, int y, int width, int height); + + virtual void DoRefreshRect(const wxRect& rect); + + // sets DirectFB keyboard focus to this toplevel window (note that DFB + // focus is different from wx: only shown TLWs can have it and not any + // wxWindows as in wx + void SetDfbFocus(); + +private: + // do queued painting in idle time + void HandleQueuedPaintRequests(); + + // DirectFB events handling + static void HandleDFBWindowEvent(const wxDFBWindowEvent& event_); + +protected: + // did we sent wxSizeEvent at least once? + bool m_sizeSet:1; + + // window's opacity (0: transparent, 255: opaque) + wxByte m_opacity; + + // interface to the underlying DirectFB window + wxIDirectFBWindowPtr m_dfbwin; + +private: + // invalidated areas of the TLW that need repainting + wxDfbQueuedPaintRequests *m_toPaint; + // are we currently painting some area of this TLW? + bool m_isPainting; + + friend class wxEventLoop; // for HandleDFBWindowEvent + friend class wxWindowDFB; // for SetDfbFocus +}; + +#endif // _WX_DFB_NONOWNEDWND_H_ diff --git a/include/wx/dfb/popupwin.h b/include/wx/dfb/popupwin.h new file mode 100644 index 0000000000..58d61f8094 --- /dev/null +++ b/include/wx/dfb/popupwin.h @@ -0,0 +1,45 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/dfb/popupwin.h +// Purpose: wxPopupWindow class for wxDFB +// Author: Vaclav Slavik +// Created: 2006-12-24 +// RCS-ID: $Id$ +// Copyright: (c) 2006 TT-Solutions +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_DFB_POPUPWIN_H_ +#define _WX_DFB_POPUPWIN_H_ + +// ---------------------------------------------------------------------------- +// wxPopupWindow +// ---------------------------------------------------------------------------- + +class WXDLLIMPEXP_CORE wxPopupWindow : public wxPopupWindowBase +{ +public: + wxPopupWindow() {} + + wxPopupWindow(wxWindow *parent, int flags = wxBORDER_NONE) + { Create(parent, flags); } + + bool Create(wxWindow *parent, int flags = wxBORDER_NONE) + { + if ( !wxPopupWindowBase::Create(parent) ) + return false; + + return wxNonOwnedWindow::Create + ( + parent, + -1, + // DFB windows must have valid pos & size: + wxPoint(0, 0), wxSize(1, 1), + (flags & wxBORDER_MASK) | wxPOPUP_WINDOW + ); + } + + DECLARE_DYNAMIC_CLASS(wxPopupWindow) +}; + +#endif // _WX_DFB_POPUPWIN_H_ + diff --git a/include/wx/dfb/toplevel.h b/include/wx/dfb/toplevel.h index 4d71aa7aac..fce0970d7e 100644 --- a/include/wx/dfb/toplevel.h +++ b/include/wx/dfb/toplevel.h @@ -11,13 +11,6 @@ #ifndef _WX_DFB_TOPLEVEL_H_ #define _WX_DFB_TOPLEVEL_H_ -#include "wx/dfb/dfbptr.h" - -wxDFB_DECLARE_INTERFACE(IDirectFBWindow); - -class wxDfbQueuedPaintRequests; -struct wxDFBWindowEvent; - //----------------------------------------------------------------------------- // wxTopLevelWindowDFB //----------------------------------------------------------------------------- @@ -48,8 +41,6 @@ public: long style = wxDEFAULT_FRAME_STYLE, const wxString& name = wxFrameNameStr); - virtual ~wxTopLevelWindowDFB(); - // implement base class pure virtuals virtual void Maximize(bool maximize = true); virtual bool IsMaximized() const; @@ -60,52 +51,16 @@ public: virtual bool ShowFullScreen(bool show, long style = wxFULLSCREEN_ALL); virtual bool IsFullScreen() const { return m_fsIsShowing; } - virtual bool Show(bool show = true); - virtual bool CanSetTransparent() { return true; } virtual bool SetTransparent(wxByte alpha); virtual void SetTitle(const wxString &title) { m_title = title; } virtual wxString GetTitle() const { return m_title; } - virtual void Update(); - - // implementation from now on - // -------------------------- - - void OnInternalIdle(); - - wxIDirectFBWindowPtr GetDirectFBWindow() const { return m_dfbwin; } - - // Returns true if some invalidated area of the TLW is currently being - // painted - bool IsPainting() const { return m_isPainting; } - protected: // common part of all ctors void Init(); - virtual wxIDirectFBSurfacePtr ObtainDfbSurface() const; - - // overriden wxWindow methods - virtual void DoGetPosition(int *x, int *y) const; - virtual void DoGetSize(int *width, int *height) const; - virtual void DoMoveWindow(int x, int y, int width, int height); - - virtual void DoRefreshRect(const wxRect& rect); - - // sets DirectFB keyboard focus to this toplevel window (note that DFB - // focus is different from wx: only shown TLWs can have it and not any - // wxWindows as in wx - void SetDfbFocus(); - -private: - // do queued painting in idle time - void HandleQueuedPaintRequests(); - - // DirectFB events handling - static void HandleDFBWindowEvent(const wxDFBWindowEvent& event_); - protected: wxString m_title; @@ -117,24 +72,6 @@ protected: // is the frame currently maximized? bool m_isMaximized:1; wxRect m_savedFrame; - - // did we sent wxSizeEvent at least once? - bool m_sizeSet:1; - - // window's opacity (0: transparent, 255: opaque) - wxByte m_opacity; - - // interface to the underlying DirectFB window - wxIDirectFBWindowPtr m_dfbwin; - -private: - // invalidated areas of the TLW that need repainting - wxDfbQueuedPaintRequests *m_toPaint; - // are we currently painting some area of this TLW? - bool m_isPainting; - - friend class wxEventLoop; // for HandleDFBWindowEvent - friend class wxWindowDFB; // for SetDfbFocus }; #endif // _WX_DFB_TOPLEVEL_H_ diff --git a/include/wx/dfb/window.h b/include/wx/dfb/window.h index e6c2796cf2..9042d7af80 100644 --- a/include/wx/dfb/window.h +++ b/include/wx/dfb/window.h @@ -21,7 +21,7 @@ wxDFB_DECLARE_INTERFACE(IDirectFBSurface); struct wxDFBWindowEvent; class WXDLLIMPEXP_CORE wxFont; -class WXDLLIMPEXP_CORE wxTopLevelWindowDFB; +class WXDLLIMPEXP_CORE wxNonOwnedWindow; class wxOverlayImpl; class wxDfbOverlaysList; @@ -108,7 +108,7 @@ public: wxIDirectFBSurfacePtr GetDfbSurface(); // returns toplevel window the window belongs to - wxTopLevelWindowDFB *GetTLW() const { return m_tlw; } + wxNonOwnedWindow *GetTLW() const { return m_tlw; } void OnInternalIdle(); @@ -174,7 +174,7 @@ private: protected: // toplevel window (i.e. DirectFB window) this window belongs to - wxTopLevelWindowDFB *m_tlw; + wxNonOwnedWindow *m_tlw; private: // subsurface of TLW's surface covered by this window @@ -190,7 +190,7 @@ private: // overlays for this window (or NULL if it doesn't have any) wxDfbOverlaysList *m_overlays; - friend class wxTopLevelWindowDFB; // for HandleXXXEvent + friend class wxNonOwnedWindow; // for HandleXXXEvent friend class wxOverlayImpl; // for Add/RemoveOverlay friend class wxWindowDC; // for PaintOverlays diff --git a/include/wx/nonownedwnd.h b/include/wx/nonownedwnd.h new file mode 100644 index 0000000000..8e4cd1daa8 --- /dev/null +++ b/include/wx/nonownedwnd.h @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/nonownedwnd.h +// Purpose: declares wxNonTopLevelWindow class +// Author: Vaclav Slavik +// Modified by: +// Created: 2006-12-24 +// RCS-ID: $Id$ +// Copyright: (c) 2006 TT-Solutions +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_NONOWNEDWND_H_ +#define _WX_NONOWNEDWND_H_ + +#if defined(__WXDFB__) + #include "wx/dfb/nonownedwnd.h" +#else + // other ports can derive both wxTLW and wxPopupWindow directly + // from wxWindow: + #include "wx/window.h" + typedef wxWindow wxNonOwnedWindow; +#endif + +#endif // _WX_NONOWNEDWND_H_ diff --git a/include/wx/popupwin.h b/include/wx/popupwin.h index c8adb53e31..e9d5ef6485 100644 --- a/include/wx/popupwin.h +++ b/include/wx/popupwin.h @@ -16,14 +16,14 @@ #if wxUSE_POPUPWIN -#include "wx/window.h" +#include "wx/nonownedwnd.h" // ---------------------------------------------------------------------------- // wxPopupWindow: a special kind of top level window used for popup menus, // combobox popups and such. // ---------------------------------------------------------------------------- -class WXDLLEXPORT wxPopupWindowBase : public wxWindow +class WXDLLEXPORT wxPopupWindowBase : public wxNonOwnedWindow { public: wxPopupWindowBase() { } @@ -64,6 +64,8 @@ public: #include "wx/x11/popupwin.h" #elif defined(__WXMOTIF__) #include "wx/motif/popupwin.h" +#elif defined(__WXDFB__) + #include "wx/dfb/popupwin.h" #elif defined(__WXMGL__) #include "wx/mgl/popupwin.h" #else diff --git a/include/wx/toplevel.h b/include/wx/toplevel.h index 5b4c1cd0b3..98c2bd6b49 100644 --- a/include/wx/toplevel.h +++ b/include/wx/toplevel.h @@ -18,7 +18,7 @@ // headers // ---------------------------------------------------------------------------- -#include "wx/window.h" +#include "wx/nonownedwnd.h" #include "wx/iconbndl.h" // the default names for various classes @@ -115,7 +115,7 @@ enum // wxTopLevelWindow: a top level (as opposed to child) window // ---------------------------------------------------------------------------- -class WXDLLEXPORT wxTopLevelWindowBase : public wxWindow +class WXDLLEXPORT wxTopLevelWindowBase : public wxNonOwnedWindow { public: // construction diff --git a/src/dfb/nonownedwnd.cpp b/src/dfb/nonownedwnd.cpp new file mode 100644 index 0000000000..4fe1ac999d --- /dev/null +++ b/src/dfb/nonownedwnd.cpp @@ -0,0 +1,452 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: src/dfb/nonownedwnd.cpp +// Purpose: implementation of wxNonOwnedWindowow +// Author: Vaclav Slavik +// Created: 2006-12-24 +// RCS-ID: $Id$ +// Copyright: (c) 2006 REA Elektronik GmbH +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#include "wx/toplevel.h" + +#ifndef WX_PRECOMP + #include "wx/app.h" +#endif // WX_PRECOMP + +#include "wx/hashmap.h" +#include "wx/evtloop.h" +#include "wx/dfb/private.h" + +#define TRACE_EVENTS _T("events") +#define TRACE_PAINT _T("paint") + +// ============================================================================ +// globals +// ============================================================================ + +// mapping of DirectFB windows to wxTLWs: +WX_DECLARE_HASH_MAP(DFBWindowID, wxNonOwnedWindow*, + wxIntegerHash, wxIntegerEqual, + wxDfbWindowsMap); +static wxDfbWindowsMap gs_dfbWindowsMap; + +// ============================================================================ +// helpers +// ============================================================================ + +// Queue of paint requests +class wxDfbQueuedPaintRequests +{ +public: + ~wxDfbQueuedPaintRequests() { Clear(); } + + // Adds paint request to the queue + void Add(const wxRect& rect) + { + // We use a simple implementation here for now: all refresh requests + // are merged together into single rectangle that is superset of + // all the requested rectangles. This wastes some blitting and painting + // time, but OTOH, EVT_PAINT handler is called only once per window. + m_invalidated.Union(rect); + } + + // Is the queue empty? + bool IsEmpty() const { return m_invalidated.IsEmpty(); } + + // Empties the queue + void Clear() { m_invalidated = wxRect(); } + + // Gets the next request in the queue, returns true if there was one, + // false if the queue was empty + bool GetNext(wxRect& rect) + { + if ( m_invalidated.IsEmpty() ) + return false; + + rect = m_invalidated; + Clear(); // there's only one item in the queue + return true; + } + +private: + // currently invalidated region + wxRect m_invalidated; +}; + +// ============================================================================ +// wxNonOwnedWindow +// ============================================================================ + +// ---------------------------------------------------------------------------- +// creation & destruction +// ---------------------------------------------------------------------------- + +void wxNonOwnedWindow::Init() +{ + m_isShown = false; + m_sizeSet = false; + m_opacity = 255; + m_toPaint = new wxDfbQueuedPaintRequests; + m_isPainting = false; +} + +bool wxNonOwnedWindow::Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString &name) +{ + wxCHECK_MSG( pos.x >= 0 && pos.y >= 0, false, _T("invalid position") ); + wxCHECK_MSG( size.x > 0 && size.y > 0, false, _T("invalid size") ); + + m_tlw = this; + + // create DirectFB window: + wxIDirectFBDisplayLayerPtr layer(wxIDirectFB::Get()->GetDisplayLayer()); + wxCHECK_MSG( layer, false, _T("no display layer") ); + + DFBWindowDescription desc; + desc.flags = (DFBWindowDescriptionFlags) + (DWDESC_CAPS | + DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY); + desc.caps = DWCAPS_DOUBLEBUFFER; + desc.posx = pos.x; + desc.posy = pos.y; + desc.width = size.x; + desc.height = size.y; + m_dfbwin = layer->CreateWindow(&desc); + if ( !m_dfbwin ) + return false; + + // add the new TLW to DFBWindowID->wxTLW map: + DFBWindowID winid; + if ( !m_dfbwin->GetID(&winid) ) + return false; + gs_dfbWindowsMap[winid] = this; + + // TLWs are created initially hidden: + if ( !m_dfbwin->SetOpacity(wxALPHA_TRANSPARENT) ) + return false; + + if ( !wxWindow::Create(NULL, id, pos, size, style, name) ) + return false; + + SetParent(parent); + if ( parent ) + parent->AddChild(this); + + if ( style & (wxSTAY_ON_TOP | wxPOPUP_WINDOW) ) + { + m_dfbwin->SetStackingClass(DWSC_UPPER); + } + + // direct events in this window to the global event buffer: + m_dfbwin->AttachEventBuffer(wxEventLoop::GetDirectFBEventBuffer()); + + return true; +} + +wxNonOwnedWindow::~wxNonOwnedWindow() +{ + m_isBeingDeleted = true; + + // destroy all children before we destroy the underlying DirectFB window, + // so that if any of them does something with the TLW, it will still work: + DestroyChildren(); + + // it's safe to delete the underlying DirectFB window now: + wxDELETE(m_toPaint); + + if ( !m_dfbwin ) + return; + + // remove the TLW from DFBWindowID->wxTLW map: + DFBWindowID winid; + if ( m_dfbwin->GetID(&winid) ) + gs_dfbWindowsMap.erase(winid); + + m_dfbwin->Destroy(); + m_dfbwin.Reset(); +} + +// ---------------------------------------------------------------------------- +// window size & position +// ---------------------------------------------------------------------------- + +void wxNonOwnedWindow::DoGetPosition(int *x, int *y) const +{ + m_dfbwin->GetPosition(x, y); +} + +void wxNonOwnedWindow::DoGetSize(int *width, int *height) const +{ + m_dfbwin->GetSize(width, height); +} + +void wxNonOwnedWindow::DoMoveWindow(int x, int y, int width, int height) +{ + wxPoint curpos = GetPosition(); + if ( curpos.x != x || curpos.y != y ) + { + m_dfbwin->MoveTo(x, y); + } + + wxSize cursize = GetSize(); + if ( cursize.x != width || cursize.y != height ) + { + // changing window's size changes its surface: + InvalidateDfbSurface(); + + m_dfbwin->Resize(width, height); + + // we must repaint the window after it changed size: + if ( IsShown() ) + DoRefreshWindow(); + } +} + +// ---------------------------------------------------------------------------- +// showing and hiding +// ---------------------------------------------------------------------------- + +bool wxNonOwnedWindow::Show(bool show) +{ + // NB: this calls wxWindow::Show() and so ensures DoRefreshWindow() is + // called on the window -- we'll need that below + if ( !wxWindow::Show(show) ) + return false; + + // If this is the first time Show was called, send size event, + // so that the frame can adjust itself (think auto layout or single child) + if ( !m_sizeSet ) + { + m_sizeSet = true; + wxSizeEvent event(GetSize(), GetId()); + event.SetEventObject(this); + GetEventHandler()->ProcessEvent(event); + } + + // make sure the window is fully painted, with all pending updates, before + // DFB WM shows it, otherwise it would attempt to show either empty (= + // black) window surface (if shown for the first time) or it would show + // window with outdated content; note that the window was already refreshed + // in the wxWindow::Show() call above: + if ( show ) + Update(); + + // hide/show the window by setting its opacity to 0/full: + m_dfbwin->SetOpacity(show ? m_opacity : 0); + + if ( show ) + { + wxWindow *focused = wxWindow::FindFocus(); + if ( focused && focused->GetTLW() == this ) + { + SetDfbFocus(); + } + else if ( AcceptsFocus() ) + { + // FIXME: we should probably always call SetDfbFocus instead + // and call SetFocus() from wxActivateEvent/DWET_GOTFOCUS + // handler + SetFocus(); + } + } + + return true; +} + +// ---------------------------------------------------------------------------- +// surfaces and painting +// ---------------------------------------------------------------------------- + +wxIDirectFBSurfacePtr wxNonOwnedWindow::ObtainDfbSurface() const +{ + return m_dfbwin->GetSurface(); +} + +void wxNonOwnedWindow::HandleQueuedPaintRequests() +{ + if ( m_toPaint->IsEmpty() ) + return; // nothing to do + + if ( IsFrozen() || !IsShown() ) + { + // nothing to do if the window is frozen or hidden; clear the queue + // and return (note that it's OK to clear the queue even if the window + // is frozen, because Thaw() calls Refresh()): + m_toPaint->Clear(); + return; + } + + // process queued paint requests: + wxRect winRect(wxPoint(0, 0), GetSize()); + wxRect paintedRect; + + // important note: all DCs created from now until m_isPainting is reset to + // false will not update the front buffer as this flag indicates that we'll + // blit the entire back buffer to front soon + m_isPainting = true; + +#ifdef __WXDEBUG__ + int requestsCount = 0; +#endif + + wxRect request; + while ( m_toPaint->GetNext(request) ) + { +#ifdef __WXDEBUG__ + requestsCount++; +#endif + wxRect clipped(request); + clipped.Intersect(winRect); + if ( clipped.IsEmpty() ) + continue; // nothing to refresh + + wxLogTrace(TRACE_PAINT, + _T("%p ('%s'): processing paint request [%i,%i,%i,%i]"), + this, GetName().c_str(), + clipped.x, clipped.y, clipped.GetRight(), clipped.GetBottom()); + + PaintWindow(clipped); + + // remember rectangle covering all repainted areas: + if ( paintedRect.IsEmpty() ) + paintedRect = clipped; + else + paintedRect.Union(clipped); + } + + m_isPainting = false; + + m_toPaint->Clear(); + + if ( paintedRect.IsEmpty() ) + return; // no painting occurred, no need to flip + + // Flip the surface to make the changes visible. Note that the rectangle we + // flip is *superset* of the union of repainted rectangles (created as + // "rectangles union" by wxRect::Union) and so some parts of the back + // buffer that we didn't touch in this HandleQueuedPaintRequests call will + // be copied to the front buffer as well. This is safe/correct thing to do + // *only* because wx always use wxIDirectFBSurface::FlipToFront() and so + // the back and front buffers contain the same data. + // + // Note that we do _not_ split m_toPaint into disjoint rectangles and + // do FlipToFront() for each of them, because that could result in visible + // updating of the screen; instead, we prefer to flip everything at once. + + DFBRegion r = {paintedRect.GetLeft(), paintedRect.GetTop(), + paintedRect.GetRight(), paintedRect.GetBottom()}; + DFBRegion *rptr = (winRect == paintedRect) ? NULL : &r; + + GetDfbSurface()->FlipToFront(rptr); + + wxLogTrace(TRACE_PAINT, + _T("%p ('%s'): processed %i paint requests, flipped surface: [%i,%i,%i,%i]"), + this, GetName().c_str(), + requestsCount, + paintedRect.x, paintedRect.y, + paintedRect.GetRight(), paintedRect.GetBottom()); +} + +void wxNonOwnedWindow::DoRefreshRect(const wxRect& rect) +{ + // don't overlap outside of the window (NB: 'rect' is in window coords): + wxRect r(rect); + r.Intersect(wxRect(GetSize())); + if ( r.IsEmpty() ) + return; + + wxLogTrace(TRACE_PAINT, + _T("%p ('%s'): [TLW] refresh rect [%i,%i,%i,%i]"), + this, GetName().c_str(), + rect.x, rect.y, rect.GetRight(), rect.GetBottom()); + + // defer painting until idle time or until Update() is called: + m_toPaint->Add(rect); +} + +void wxNonOwnedWindow::Update() +{ + HandleQueuedPaintRequests(); +} + +// --------------------------------------------------------------------------- +// events handling +// --------------------------------------------------------------------------- + +void wxNonOwnedWindow::SetDfbFocus() +{ + wxCHECK_RET( IsShown(), _T("cannot set focus to hidden window") ); + wxASSERT_MSG( FindFocus() && FindFocus()->GetTLW() == this, + _T("setting DirectFB focus to unexpected window") ); + + GetDirectFBWindow()->RequestFocus(); +} + +/* static */ +void wxNonOwnedWindow::HandleDFBWindowEvent(const wxDFBWindowEvent& event_) +{ + const DFBWindowEvent& event = event_; + + if ( gs_dfbWindowsMap.find(event.window_id) == gs_dfbWindowsMap.end() ) + { + wxLogTrace(TRACE_EVENTS, + _T("received event for unknown DirectFB window, ignoring")); + return; + } + + wxNonOwnedWindow *tlw = gs_dfbWindowsMap[event.window_id]; + wxWindow *recipient = NULL; + void (wxWindow::*handlerFunc)(const wxDFBWindowEvent&) = NULL; + + switch ( event.type ) + { + case DWET_KEYDOWN: + case DWET_KEYUP: + { + recipient = wxWindow::FindFocus(); + handlerFunc = &wxWindowDFB::HandleKeyEvent; + break; + } + + case DWET_NONE: + case DWET_ALL: + { + wxFAIL_MSG( _T("invalid event type") ); + break; + } + + default: + // we're not interested in them here + break; + } + + if ( !recipient ) + { + wxLogTrace(TRACE_EVENTS, _T("ignoring event: no recipient window")); + return; + } + + wxCHECK_RET( recipient && recipient->GetTLW() == tlw, + _T("event recipient not in TLW which received the event") ); + + // process the event: + (recipient->*handlerFunc)(event_); +} + +// --------------------------------------------------------------------------- +// idle events processing +// --------------------------------------------------------------------------- + +void wxNonOwnedWindow::OnInternalIdle() +{ + wxWindow::OnInternalIdle(); + HandleQueuedPaintRequests(); +} diff --git a/src/dfb/toplevel.cpp b/src/dfb/toplevel.cpp index bb1620b49a..cf667df95d 100644 --- a/src/dfb/toplevel.cpp +++ b/src/dfb/toplevel.cpp @@ -17,66 +17,8 @@ #include "wx/app.h" #endif // WX_PRECOMP -#include "wx/hashmap.h" -#include "wx/evtloop.h" #include "wx/dfb/private.h" -#define TRACE_EVENTS _T("events") -#define TRACE_PAINT _T("paint") - -// ============================================================================ -// globals -// ============================================================================ - -// mapping of DirectFB windows to wxTLWs: -WX_DECLARE_HASH_MAP(DFBWindowID, wxTopLevelWindowDFB*, - wxIntegerHash, wxIntegerEqual, - wxDfbWindowsMap); -static wxDfbWindowsMap gs_dfbWindowsMap; - -// ============================================================================ -// helpers -// ============================================================================ - -// Queue of paint requests -class wxDfbQueuedPaintRequests -{ -public: - ~wxDfbQueuedPaintRequests() { Clear(); } - - // Adds paint request to the queue - void Add(const wxRect& rect) - { - // We use a simple implementation here for now: all refresh requests - // are merged together into single rectangle that is superset of - // all the requested rectangles. This wastes some blitting and painting - // time, but OTOH, EVT_PAINT handler is called only once per window. - m_invalidated.Union(rect); - } - - // Is the queue empty? - bool IsEmpty() const { return m_invalidated.IsEmpty(); } - - // Empties the queue - void Clear() { m_invalidated = wxRect(); } - - // Gets the next request in the queue, returns true if there was one, - // false if the queue was empty - bool GetNext(wxRect& rect) - { - if ( m_invalidated.IsEmpty() ) - return false; - - rect = m_invalidated; - Clear(); // there's only one item in the queue - return true; - } - -private: - // currently invalidated region - wxRect m_invalidated; -}; - // ============================================================================ // wxTopLevelWindowDFB // ============================================================================ @@ -87,13 +29,8 @@ private: void wxTopLevelWindowDFB::Init() { - m_isShown = false; m_isMaximized = false; m_fsIsShowing = false; - m_sizeSet = false; - m_opacity = 255; - m_toPaint = new wxDfbQueuedPaintRequests; - m_isPainting = false; } bool wxTopLevelWindowDFB::Create(wxWindow *parent, @@ -104,8 +41,6 @@ bool wxTopLevelWindowDFB::Create(wxWindow *parent, long style, const wxString &name) { - m_tlw = this; - // always create a frame of some reasonable, even if arbitrary, size (at // least for MSW compatibility) wxSize size(sizeOrig); @@ -124,113 +59,15 @@ bool wxTopLevelWindowDFB::Create(wxWindow *parent, if ( pos.y == wxDefaultCoord ) pos.y = 0; - // create DirectFB window: - wxIDirectFBDisplayLayerPtr layer(wxIDirectFB::Get()->GetDisplayLayer()); - wxCHECK_MSG( layer, false, _T("no display layer") ); - - DFBWindowDescription desc; - desc.flags = (DFBWindowDescriptionFlags) - (DWDESC_CAPS | - DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY); - desc.caps = DWCAPS_DOUBLEBUFFER; - desc.posx = pos.x; - desc.posy = pos.y; - desc.width = size.x; - desc.height = size.y; - m_dfbwin = layer->CreateWindow(&desc); - if ( !m_dfbwin ) - return false; - - // add the new TLW to DFBWindowID->wxTLW map: - DFBWindowID winid; - if ( !m_dfbwin->GetID(&winid) ) + if ( !wxNonOwnedWindow::Create(parent, id, pos, size, style, name) ) return false; - gs_dfbWindowsMap[winid] = this; - - // TLWs are created initially hidden: - if ( !m_dfbwin->SetOpacity(wxALPHA_TRANSPARENT) ) - return false; - - if ( !wxWindow::Create(NULL, id, pos, size, style, name) ) - return false; - - SetParent(parent); - if ( parent ) - parent->AddChild(this); wxTopLevelWindows.Append(this); m_title = title; - if ( style & (wxSTAY_ON_TOP | wxPOPUP_WINDOW) ) - { - m_dfbwin->SetStackingClass(DWSC_UPPER); - } - - // direct events in this window to the global event buffer: - m_dfbwin->AttachEventBuffer(wxEventLoop::GetDirectFBEventBuffer()); - return true; } -wxTopLevelWindowDFB::~wxTopLevelWindowDFB() -{ - m_isBeingDeleted = true; - - // destroy all children before we destroy the underlying DirectFB window, - // so that if any of them does something with the TLW, it will still work: - DestroyChildren(); - - // it's safe to delete the underlying DirectFB window now: - wxDELETE(m_toPaint); - - if ( !m_dfbwin ) - return; - - // remove the TLW from DFBWindowID->wxTLW map: - DFBWindowID winid; - if ( m_dfbwin->GetID(&winid) ) - gs_dfbWindowsMap.erase(winid); - - m_dfbwin->Destroy(); - m_dfbwin.Reset(); -} - -// ---------------------------------------------------------------------------- -// window size & position -// ---------------------------------------------------------------------------- - -void wxTopLevelWindowDFB::DoGetPosition(int *x, int *y) const -{ - m_dfbwin->GetPosition(x, y); -} - -void wxTopLevelWindowDFB::DoGetSize(int *width, int *height) const -{ - m_dfbwin->GetSize(width, height); -} - -void wxTopLevelWindowDFB::DoMoveWindow(int x, int y, int width, int height) -{ - wxPoint curpos = GetPosition(); - if ( curpos.x != x || curpos.y != y ) - { - m_dfbwin->MoveTo(x, y); - } - - wxSize cursize = GetSize(); - if ( cursize.x != width || cursize.y != height ) - { - // changing window's size changes its surface: - InvalidateDfbSurface(); - - m_dfbwin->Resize(width, height); - - // we must repaint the window after it changed size: - if ( IsShown() ) - DoRefreshWindow(); - } -} - // ---------------------------------------------------------------------------- // showing and hiding // ---------------------------------------------------------------------------- @@ -238,7 +75,8 @@ void wxTopLevelWindowDFB::DoMoveWindow(int x, int y, int width, int height) #warning "FIXME: the rest of this file is almost same as for MGL, merge it" bool wxTopLevelWindowDFB::ShowFullScreen(bool show, long style) { - if (show == m_fsIsShowing) return false; // return what? + if ( show == m_fsIsShowing ) + return true; m_fsIsShowing = show; @@ -268,53 +106,6 @@ bool wxTopLevelWindowDFB::ShowFullScreen(bool show, long style) return true; } -bool wxTopLevelWindowDFB::Show(bool show) -{ - // NB: this calls wxWindow::Show() and so ensures DoRefreshWindow() is - // called on the window -- we'll need that below - if ( !wxTopLevelWindowBase::Show(show) ) - return false; - - // If this is the first time Show was called, send size event, - // so that the frame can adjust itself (think auto layout or single child) - if ( !m_sizeSet ) - { - m_sizeSet = true; - wxSizeEvent event(GetSize(), GetId()); - event.SetEventObject(this); - GetEventHandler()->ProcessEvent(event); - } - - // make sure the window is fully painted, with all pending updates, before - // DFB WM shows it, otherwise it would attempt to show either empty (= - // black) window surface (if shown for the first time) or it would show - // window with outdated content; note that the window was already refreshed - // in the wxTopLevelWindowBase::Show() call above: - if ( show ) - Update(); - - // hide/show the window by setting its opacity to 0/full: - m_dfbwin->SetOpacity(show ? m_opacity : 0); - - if ( show ) - { - wxWindow *focused = wxWindow::FindFocus(); - if ( focused && focused->GetTLW() == this ) - { - SetDfbFocus(); - } - else if ( AcceptsFocus() ) - { - // FIXME: we should probably always call SetDfbFocus instead - // and call SetFocus() from wxActivateEvent/DWET_GOTFOCUS - // handler - SetFocus(); - } - } - - return true; -} - bool wxTopLevelWindowDFB::SetTransparent(wxByte alpha) { if ( IsShown() ) @@ -375,194 +166,3 @@ bool wxTopLevelWindowDFB::IsIconized() const { return false; } - - -// ---------------------------------------------------------------------------- -// surfaces and painting -// ---------------------------------------------------------------------------- - -wxIDirectFBSurfacePtr wxTopLevelWindowDFB::ObtainDfbSurface() const -{ - return m_dfbwin->GetSurface(); -} - -void wxTopLevelWindowDFB::HandleQueuedPaintRequests() -{ - if ( m_toPaint->IsEmpty() ) - return; // nothing to do - - if ( IsFrozen() || !IsShown() ) - { - // nothing to do if the window is frozen or hidden; clear the queue - // and return (note that it's OK to clear the queue even if the window - // is frozen, because Thaw() calls Refresh()): - m_toPaint->Clear(); - return; - } - - // process queued paint requests: - wxRect winRect(wxPoint(0, 0), GetSize()); - wxRect paintedRect; - - // important note: all DCs created from now until m_isPainting is reset to - // false will not update the front buffer as this flag indicates that we'll - // blit the entire back buffer to front soon - m_isPainting = true; - -#ifdef __WXDEBUG__ - int requestsCount = 0; -#endif - - wxRect request; - while ( m_toPaint->GetNext(request) ) - { -#ifdef __WXDEBUG__ - requestsCount++; -#endif - wxRect clipped(request); - clipped.Intersect(winRect); - if ( clipped.IsEmpty() ) - continue; // nothing to refresh - - wxLogTrace(TRACE_PAINT, - _T("%p ('%s'): processing paint request [%i,%i,%i,%i]"), - this, GetName().c_str(), - clipped.x, clipped.y, clipped.GetRight(), clipped.GetBottom()); - - PaintWindow(clipped); - - // remember rectangle covering all repainted areas: - if ( paintedRect.IsEmpty() ) - paintedRect = clipped; - else - paintedRect.Union(clipped); - } - - m_isPainting = false; - - m_toPaint->Clear(); - - if ( paintedRect.IsEmpty() ) - return; // no painting occurred, no need to flip - - // Flip the surface to make the changes visible. Note that the rectangle we - // flip is *superset* of the union of repainted rectangles (created as - // "rectangles union" by wxRect::Union) and so some parts of the back - // buffer that we didn't touch in this HandleQueuedPaintRequests call will - // be copied to the front buffer as well. This is safe/correct thing to do - // *only* because wx always use wxIDirectFBSurface::FlipToFront() and so - // the back and front buffers contain the same data. - // - // Note that we do _not_ split m_toPaint into disjoint rectangles and - // do FlipToFront() for each of them, because that could result in visible - // updating of the screen; instead, we prefer to flip everything at once. - - DFBRegion r = {paintedRect.GetLeft(), paintedRect.GetTop(), - paintedRect.GetRight(), paintedRect.GetBottom()}; - DFBRegion *rptr = (winRect == paintedRect) ? NULL : &r; - - GetDfbSurface()->FlipToFront(rptr); - - wxLogTrace(TRACE_PAINT, - _T("%p ('%s'): processed %i paint requests, flipped surface: [%i,%i,%i,%i]"), - this, GetName().c_str(), - requestsCount, - paintedRect.x, paintedRect.y, - paintedRect.GetRight(), paintedRect.GetBottom()); -} - -void wxTopLevelWindowDFB::DoRefreshRect(const wxRect& rect) -{ - // don't overlap outside of the window (NB: 'rect' is in window coords): - wxRect r(rect); - r.Intersect(wxRect(GetSize())); - if ( r.IsEmpty() ) - return; - - wxLogTrace(TRACE_PAINT, - _T("%p ('%s'): [TLW] refresh rect [%i,%i,%i,%i]"), - this, GetName().c_str(), - rect.x, rect.y, rect.GetRight(), rect.GetBottom()); - - // defer painting until idle time or until Update() is called: - m_toPaint->Add(rect); -} - -void wxTopLevelWindowDFB::Update() -{ - HandleQueuedPaintRequests(); -} - -// --------------------------------------------------------------------------- -// events handling -// --------------------------------------------------------------------------- - -void wxTopLevelWindowDFB::SetDfbFocus() -{ - wxCHECK_RET( IsShown(), _T("cannot set focus to hidden window") ); - wxASSERT_MSG( FindFocus() && FindFocus()->GetTLW() == this, - _T("setting DirectFB focus to unexpected window") ); - - GetDirectFBWindow()->RequestFocus(); -} - -/* static */ -void wxTopLevelWindowDFB::HandleDFBWindowEvent(const wxDFBWindowEvent& event_) -{ - const DFBWindowEvent& event = event_; - - if ( gs_dfbWindowsMap.find(event.window_id) == gs_dfbWindowsMap.end() ) - { - wxLogTrace(TRACE_EVENTS, - _T("received event for unknown DirectFB window, ignoring")); - return; - } - - wxTopLevelWindowDFB *tlw = gs_dfbWindowsMap[event.window_id]; - wxWindow *recipient = NULL; - void (wxWindow::*handlerFunc)(const wxDFBWindowEvent&) = NULL; - - switch ( event.type ) - { - case DWET_KEYDOWN: - case DWET_KEYUP: - { - recipient = wxWindow::FindFocus(); - handlerFunc = &wxWindowDFB::HandleKeyEvent; - break; - } - - case DWET_NONE: - case DWET_ALL: - { - wxFAIL_MSG( _T("invalid event type") ); - break; - } - - default: - // we're not interested in them here - break; - } - - if ( !recipient ) - { - wxLogTrace(TRACE_EVENTS, _T("ignoring event: no recipient window")); - return; - } - - wxCHECK_RET( recipient && recipient->GetTLW() == tlw, - _T("event recipient not in TLW which received the event") ); - - // process the event: - (recipient->*handlerFunc)(event_); -} - -// --------------------------------------------------------------------------- -// idle events processing -// --------------------------------------------------------------------------- - -void wxTopLevelWindowDFB::OnInternalIdle() -{ - wxTopLevelWindowBase::OnInternalIdle(); - HandleQueuedPaintRequests(); -} -- 2.45.2