1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/gtk/window.h
3 // Purpose:
4 // Author:      Robert Roebling
5 // Copyright:   (c) 1998 Robert Roebling
6 // Licence:     wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
8 
9 #ifndef _WX_GTK_WINDOW_H_
10 #define _WX_GTK_WINDOW_H_
11 
12 #include "wx/dynarray.h"
13 
14 #ifdef __WXGTK3__
15     typedef struct _cairo cairo_t;
16     typedef struct _GtkStyleProvider GtkStyleProvider;
17     typedef struct _GtkCssProvider GtkCssProvider;
18     #define WXUNUSED_IN_GTK2(x) x
19     #define WXUNUSED_IN_GTK3(x)
20 #else
21     #define WXUNUSED_IN_GTK2(x)
22     #define WXUNUSED_IN_GTK3(x) x
23 #endif
24 
25 typedef struct _GdkEventKey GdkEventKey;
26 typedef struct _GtkIMContext GtkIMContext;
27 
28 WX_DEFINE_EXPORTED_ARRAY_PTR(GdkWindow *, wxArrayGdkWindows);
29 
30 extern "C"
31 {
32 
33 typedef void (*wxGTKCallback)();
34 
35 }
36 
37 //-----------------------------------------------------------------------------
38 // wxWindowGTK
39 //-----------------------------------------------------------------------------
40 
41 class WXDLLIMPEXP_CORE wxWindowGTK : public wxWindowBase
42 {
43 public:
44     // creating the window
45     // -------------------
46     wxWindowGTK();
47     wxWindowGTK(wxWindow *parent,
48                 wxWindowID id,
49                 const wxPoint& pos = wxDefaultPosition,
50                 const wxSize& size = wxDefaultSize,
51                 long style = 0,
52                 const wxString& name = wxASCII_STR(wxPanelNameStr));
53     bool Create(wxWindow *parent,
54                 wxWindowID id,
55                 const wxPoint& pos = wxDefaultPosition,
56                 const wxSize& size = wxDefaultSize,
57                 long style = 0,
58                 const wxString& name = wxASCII_STR(wxPanelNameStr));
59     virtual ~wxWindowGTK();
60 
61     // implement base class (pure) virtual methods
62     // -------------------------------------------
63 
64     virtual void Raise() wxOVERRIDE;
65     virtual void Lower() wxOVERRIDE;
66 
67     virtual bool Show( bool show = true ) wxOVERRIDE;
68     virtual bool IsShown() const wxOVERRIDE;
69 
70     virtual bool IsRetained() const wxOVERRIDE;
71 
72     virtual void SetFocus() wxOVERRIDE;
73 
74     // hint from wx to native GTK+ tab traversal code
75     virtual void SetCanFocus(bool canFocus) wxOVERRIDE;
76 
77     virtual bool Reparent( wxWindowBase *newParent ) wxOVERRIDE;
78 
79     virtual void WarpPointer(int x, int y) wxOVERRIDE;
80 #ifdef __WXGTK3__
81     virtual bool EnableTouchEvents(int eventsMask) wxOVERRIDE;
82 #endif // __WXGTK3__
83 
84     virtual void Refresh( bool eraseBackground = true,
85                           const wxRect *rect = (const wxRect *) NULL ) wxOVERRIDE;
86     virtual void Update() wxOVERRIDE;
87     virtual void ClearBackground() wxOVERRIDE;
88 
89     virtual bool SetBackgroundColour( const wxColour &colour ) wxOVERRIDE;
90     virtual bool SetForegroundColour( const wxColour &colour ) wxOVERRIDE;
91     virtual bool SetCursor( const wxCursor &cursor ) wxOVERRIDE;
92     virtual bool SetFont( const wxFont &font ) wxOVERRIDE;
93 
94     virtual bool SetBackgroundStyle(wxBackgroundStyle style) wxOVERRIDE ;
95     virtual bool IsTransparentBackgroundSupported(wxString* reason = NULL) const wxOVERRIDE;
96 
97     virtual int GetCharHeight() const wxOVERRIDE;
98     virtual int GetCharWidth() const wxOVERRIDE;
99     virtual double GetContentScaleFactor() const wxOVERRIDE;
100     virtual double GetDPIScaleFactor() const wxOVERRIDE;
101 
102     virtual void SetScrollbar( int orient, int pos, int thumbVisible,
103                                int range, bool refresh = true ) wxOVERRIDE;
104     virtual void SetScrollPos( int orient, int pos, bool refresh = true ) wxOVERRIDE;
105     virtual int GetScrollPos( int orient ) const wxOVERRIDE;
106     virtual int GetScrollThumb( int orient ) const wxOVERRIDE;
107     virtual int GetScrollRange( int orient ) const wxOVERRIDE;
108     virtual void ScrollWindow( int dx, int dy,
109                                const wxRect* rect = NULL ) wxOVERRIDE;
110     virtual bool ScrollLines(int lines) wxOVERRIDE;
111     virtual bool ScrollPages(int pages) wxOVERRIDE;
112 
113 #if wxUSE_DRAG_AND_DROP
114     virtual void SetDropTarget( wxDropTarget *dropTarget ) wxOVERRIDE;
115 #endif // wxUSE_DRAG_AND_DROP
116 
117     virtual void AddChild( wxWindowBase *child ) wxOVERRIDE;
118     virtual void RemoveChild( wxWindowBase *child ) wxOVERRIDE;
119 
120     virtual void SetLayoutDirection(wxLayoutDirection dir) wxOVERRIDE;
121     virtual wxLayoutDirection GetLayoutDirection() const wxOVERRIDE;
122     virtual wxCoord AdjustForLayoutDirection(wxCoord x,
123                                              wxCoord width,
124                                              wxCoord widthTotal) const wxOVERRIDE;
125 
126     virtual bool DoIsExposed( int x, int y ) const wxOVERRIDE;
127     virtual bool DoIsExposed( int x, int y, int w, int h ) const wxOVERRIDE;
128 
129     virtual void SetDoubleBuffered(bool on) wxOVERRIDE;
130     virtual bool IsDoubleBuffered() const wxOVERRIDE;
131 
132     // SetLabel(), which does nothing in wxWindow
SetLabel(const wxString & label)133     virtual void SetLabel(const wxString& label) wxOVERRIDE { m_gtkLabel = label; }
GetLabel()134     virtual wxString GetLabel() const wxOVERRIDE            { return m_gtkLabel; }
135 
136     // implementation
137     // --------------
138 
GetHandle()139     virtual WXWidget GetHandle() const wxOVERRIDE { return m_widget; }
140 
141     // many important things are done here, this function must be called
142     // regularly
143     virtual void OnInternalIdle() wxOVERRIDE;
144 
145     // For compatibility across platforms (not in event table)
OnIdle(wxIdleEvent & WXUNUSED (event))146     void OnIdle(wxIdleEvent& WXUNUSED(event)) {}
147 
148     // Used by all window classes in the widget creation process.
149     bool PreCreation( wxWindowGTK *parent, const wxPoint &pos, const wxSize &size );
150     void PostCreation();
151 
152     // Internal addition of child windows
153     void DoAddChild(wxWindowGTK *child);
154 
155     // This method sends wxPaintEvents to the window.
156     // It is also responsible for background erase events.
157 #ifdef __WXGTK3__
158     void GTKSendPaintEvents(cairo_t* cr);
159 #else
160     void GTKSendPaintEvents(const GdkRegion* region);
161 #endif
162 
163     // The methods below are required because many native widgets
164     // are composed of several subwidgets and setting a style for
165     // the widget means setting it for all subwidgets as well.
166     // also, it is not clear which native widget is the top
167     // widget where (most of) the input goes. even tooltips have
168     // to be applied to all subwidgets.
169     virtual GtkWidget* GetConnectWidget();
170     void ConnectWidget( GtkWidget *widget );
171 
172     // Called from several event handlers, if it returns true or false, the
173     // same value should be immediately returned by the handler without doing
174     // anything else. If it returns -1, the handler should continue as usual
175     int GTKCallbackCommonPrologue(struct _GdkEventAny *event) const;
176 
177     // Simplified form of GTKCallbackCommonPrologue() which can be used from
178     // GTK callbacks without return value to check if the event should be
179     // ignored: if this returns true, the event shouldn't be handled
180     bool GTKShouldIgnoreEvent() const;
181 
182 
183     // override this if some events should never be consumed by wxWidgets but
184     // but have to be left for the native control
185     //
186     // base version just calls HandleWindowEvent()
187     virtual bool GTKProcessEvent(wxEvent& event) const;
188 
189     // Map GTK widget direction of the given widget to/from wxLayoutDirection
190     static wxLayoutDirection GTKGetLayout(GtkWidget *widget);
191     static void GTKSetLayout(GtkWidget *widget, wxLayoutDirection dir);
192 
193     // This is called when capture is taken from the window. It will
194     // fire off capture lost events.
195     void GTKReleaseMouseAndNotify();
196     static void GTKHandleCaptureLost();
197 
198     GdkWindow* GTKGetDrawingWindow() const;
199 
200     bool GTKHandleFocusIn();
201     virtual bool GTKHandleFocusOut();
202     void GTKHandleFocusOutNoDeferring();
203     void GTKHandleDeferredFocusOut();
204 
205     // Called when m_widget becomes realized. Derived classes must call the
206     // base class method if they override it.
207     virtual void GTKHandleRealized();
208     void GTKHandleUnrealize();
209 
210     // Apply the widget style to the given window. Should normally only be
211     // called from the overridden DoApplyWidgetStyle() implementation in
212     // another window and exists solely to provide access to protected
213     // DoApplyWidgetStyle() when it's really needed.
GTKDoApplyWidgetStyle(wxWindowGTK * win,GtkRcStyle * style)214     static void GTKDoApplyWidgetStyle(wxWindowGTK* win, GtkRcStyle *style)
215     {
216         win->DoApplyWidgetStyle(style);
217     }
218 
219 protected:
220     // for controls composed of multiple GTK widgets, return true to eliminate
221     // spurious focus events if the focus changes between GTK+ children within
222     // the same wxWindow
GTKNeedsToFilterSameWindowFocus()223     virtual bool GTKNeedsToFilterSameWindowFocus() const { return false; }
224 
225     // Override GTKWidgetNeedsMnemonic and return true if your
226     // needs to set its mnemonic widget, such as for a
227     // GtkLabel for wxStaticText, then do the actual
228     // setting of the widget inside GTKWidgetDoSetMnemonic
229     virtual bool GTKWidgetNeedsMnemonic() const;
230     virtual void GTKWidgetDoSetMnemonic(GtkWidget* w);
231 
232     // Get the GdkWindows making part of this window: usually there will be
233     // only one of them in which case it should be returned directly by this
234     // function. If there is more than one GdkWindow (can be the case for
235     // composite widgets), return NULL and fill in the provided array
236     //
237     // This is not pure virtual for backwards compatibility but almost
238     // certainly must be overridden in any wxControl-derived class!
239     virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
240 
241     // Check if the given window makes part of this widget
242     bool GTKIsOwnWindow(GdkWindow *window) const;
243 
244 public:
245     // Returns the default context which usually is anti-aliased
246     PangoContext   *GTKGetPangoDefaultContext();
247 
248 #if wxUSE_TOOLTIPS
249     // applies tooltip to the widget (tip must be UTF-8 encoded)
250     virtual void GTKApplyToolTip(const char* tip);
251 #endif // wxUSE_TOOLTIPS
252 
253     // Called when a window should delay showing itself
254     // until idle time used in Reparent().
GTKShowOnIdle()255     void GTKShowOnIdle() { m_showOnIdle = true; }
256 
257     // This is called from the various OnInternalIdle methods
258     bool GTKShowFromOnIdle();
259 
260     // is this window transparent for the mouse events (as wxStaticBox is)?
GTKIsTransparentForMouse()261     virtual bool GTKIsTransparentForMouse() const { return false; }
262 
263     // Common scroll event handling code for wxWindow and wxScrollBar
264     wxEventType GTKGetScrollEventType(GtkRange* range);
265 
266     // position and size of the window
267     int                  m_x, m_y;
268     int                  m_width, m_height;
269     int m_clientWidth, m_clientHeight;
270     // Whether the client size variables above are known to be correct
271     // (because they have been validated by a size-allocate) and should
272     // be used to report client size
273     bool m_useCachedClientSize;
274     // Whether the GtkAllocation and GdkWindow positions are known to be correct
275     bool m_isGtkPositionValid;
276 
277     // see the docs in src/gtk/window.cpp
278     GtkWidget           *m_widget;          // mostly the widget seen by the rest of GTK
279     GtkWidget           *m_wxwindow;        // mostly the client area as per wxWidgets
280 
281     // label for use with GetLabelSetLabel
282     wxString             m_gtkLabel;
283 
284     // return true if the window is of a standard (i.e. not wxWidgets') class
IsOfStandardClass()285     bool IsOfStandardClass() const { return m_wxwindow == NULL; }
286 
287     // this widget will be queried for GTK's focus events
288     GtkWidget           *m_focusWidget;
289 
290     void GTKDisableFocusOutEvent();
291     void GTKEnableFocusOutEvent();
292 
293 
294     // Input method support
295 
296     // The IM context used for generic, i.e. non-native, windows.
297     //
298     // It might be a good idea to avoid allocating it unless key events from
299     // this window are really needed but currently we do it unconditionally.
300     //
301     // For native widgets (i.e. those for which IsOfStandardClass() returns
302     // true) it is NULL.
303     GtkIMContext* m_imContext;
304 
305     // Pointer to the event being currently processed by the IME or NULL if not
306     // inside key handling.
307     GdkEventKey* m_imKeyEvent;
308 
309     // This method generalizes gtk_im_context_filter_keypress(): for the
310     // generic windows it does just that but it's overridden by the classes
311     // wrapping native widgets that use IM themselves and so provide specific
312     // methods for accessing it such gtk_entry_im_context_filter_keypress().
313     virtual int GTKIMFilterKeypress(GdkEventKey* event) const;
314 
315     // This method must be called from the derived classes "insert-text" signal
316     // handlers to check if the text is not being inserted by the IM and, if
317     // this is the case, generate appropriate wxEVT_CHAR events for it.
318     //
319     // Returns true if we did generate and process events corresponding to this
320     // text or false if we didn't handle it.
321     bool GTKOnInsertText(const char* text);
322 
323     // This is just a helper of GTKOnInsertText() which is also used by GTK+
324     // "commit" signal handler.
325     bool GTKDoInsertTextFromIM(const char* text);
326 
327 
328     // indices for the arrays below
329     enum ScrollDir { ScrollDir_Horz, ScrollDir_Vert, ScrollDir_Max };
330 
331     // horizontal/vertical scroll bar
332     GtkRange* m_scrollBar[ScrollDir_Max];
333 
334     // horizontal/vertical scroll position
335     double m_scrollPos[ScrollDir_Max];
336 
337     // return the scroll direction index corresponding to the given orientation
338     // (which is wxVERTICAL or wxHORIZONTAL)
ScrollDirFromOrient(int orient)339     static ScrollDir ScrollDirFromOrient(int orient)
340     {
341         return orient == wxVERTICAL ? ScrollDir_Vert : ScrollDir_Horz;
342     }
343 
344     // return the orientation for the given scrolling direction
OrientFromScrollDir(ScrollDir dir)345     static int OrientFromScrollDir(ScrollDir dir)
346     {
347         return dir == ScrollDir_Horz ? wxHORIZONTAL : wxVERTICAL;
348     }
349 
350     // find the direction of the given scrollbar (must be one of ours)
351     ScrollDir ScrollDirFromRange(GtkRange *range) const;
352 
353     void GTKUpdateCursor(
354         bool isBusyOrGlobalCursor = false,
355         bool isRealize = false,
356         const wxCursor* overrideCursor = NULL);
357 
358     // extra (wxGTK-specific) flags
359     bool                 m_noExpose:1;          // wxGLCanvas has its own redrawing
360     bool                 m_nativeSizeEvent:1;   // wxGLCanvas sends wxSizeEvent upon "alloc_size"
361     bool                 m_isScrolling:1;       // dragging scrollbar thumb?
362     bool                 m_clipPaintRegion:1;   // true after ScrollWindow()
363     bool                 m_dirtyTabOrder:1;     // tab order changed, GTK focus
364                                                 // chain needs update
365     bool                 m_mouseButtonDown:1;
366     bool                 m_showOnIdle:1;        // postpone showing the window until idle
367     bool m_needCursorReset:1;
368 
369     wxRegion             m_nativeUpdateRegion;  // not transformed for RTL
370 
371 protected:
372     // implement the base class pure virtuals
373     virtual void DoGetTextExtent(const wxString& string,
374                                  int *x, int *y,
375                                  int *descent = NULL,
376                                  int *externalLeading = NULL,
377                                  const wxFont *font = NULL) const wxOVERRIDE;
378     virtual void DoClientToScreen( int *x, int *y ) const wxOVERRIDE;
379     virtual void DoScreenToClient( int *x, int *y ) const wxOVERRIDE;
380     virtual void DoGetPosition( int *x, int *y ) const wxOVERRIDE;
381     virtual void DoGetSize( int *width, int *height ) const wxOVERRIDE;
382     virtual void DoGetClientSize( int *width, int *height ) const wxOVERRIDE;
383     virtual void DoSetSize(int x, int y,
384                            int width, int height,
385                            int sizeFlags = wxSIZE_AUTO) wxOVERRIDE;
386     virtual void DoSetClientSize(int width, int height) wxOVERRIDE;
387     virtual wxSize DoGetBorderSize() const wxOVERRIDE;
388     virtual void DoMoveWindow(int x, int y, int width, int height) wxOVERRIDE;
389     virtual void DoEnable(bool enable) wxOVERRIDE;
390 
391 #if wxUSE_MENUS_NATIVE
392     virtual bool DoPopupMenu( wxMenu *menu, int x, int y ) wxOVERRIDE;
393 #endif // wxUSE_MENUS_NATIVE
394 
395     virtual void DoCaptureMouse() wxOVERRIDE;
396     virtual void DoReleaseMouse() wxOVERRIDE;
397 
398     virtual void DoFreeze() wxOVERRIDE;
399     virtual void DoThaw() wxOVERRIDE;
400 
401     void GTKConnectFreezeWidget(GtkWidget* widget);
402     void GTKFreezeWidget(GtkWidget *w);
403     void GTKThawWidget(GtkWidget *w);
404     void GTKDisconnect(void* instance);
405 
406 #if wxUSE_TOOLTIPS
407     virtual void DoSetToolTip( wxToolTip *tip ) wxOVERRIDE;
408 #endif // wxUSE_TOOLTIPS
409 
410     // Create a GtkScrolledWindow containing the given widget (usually
411     // m_wxwindow but not necessarily) and assigns it to m_widget. Also shows
412     // the widget passed to it.
413     //
414     // Can be only called if we have either wxHSCROLL or wxVSCROLL in our
415     // style.
416     void GTKCreateScrolledWindowWith(GtkWidget* view);
417 
418     virtual void DoMoveInTabOrder(wxWindow *win, WindowOrder move) wxOVERRIDE;
419     virtual bool DoNavigateIn(int flags) wxOVERRIDE;
420 
421 
422     // Copies m_children tab order to GTK focus chain:
423     void RealizeTabOrder();
424 
425 #ifdef __WXGTK3__
426     // Use the given CSS string for styling the widget. The provider must be
427     // allocated, and remains owned, by the caller.
428     void GTKApplyCssStyle(GtkCssProvider* provider, const char* style);
429     void GTKApplyCssStyle(const char* style);
430 #else // GTK+ < 3
431     // Called by ApplyWidgetStyle (which is called by SetFont() and
432     // SetXXXColour etc to apply style changed to native widgets) to create
433     // modified GTK style with non-standard attributes.
434     GtkRcStyle* GTKCreateWidgetStyle();
435 #endif
436 
437     void GTKApplyWidgetStyle(bool forceStyle = false);
438 
439     // Helper function to ease native widgets wrapping, called by
440     // GTKApplyWidgetStyle() and supposed to be overridden, not called.
441     //
442     // And if you actually need to call it, e.g. to propagate style change to a
443     // composite control, use public static GTKDoApplyWidgetStyle().
444     virtual void DoApplyWidgetStyle(GtkRcStyle *style);
445 
446     void GTKApplyStyle(GtkWidget* widget, GtkRcStyle* style);
447 
448     // sets the border of a given GtkScrolledWindow from a wx style
449     static void GTKScrolledWindowSetBorder(GtkWidget* w, int style);
450 
451     // Connect the given function to the specified signal on m_widget.
452     //
453     // This is just a wrapper for g_signal_connect() and returns the handler id
454     // just as it does.
455     unsigned long GTKConnectWidget(const char *signal, wxGTKCallback callback);
456 
457     void ConstrainSize();
458 
459 #ifdef __WXGTK3__
460     static GdkWindow* GTKFindWindow(GtkWidget* widget);
461     static void GTKFindWindow(GtkWidget* widget, wxArrayGdkWindows& windows);
462 
463     bool m_needSizeEvent;
464 #endif
465 
466 private:
467     void Init();
468 
469     // return true if this window must have a non-NULL parent, false if it can
470     // be created without parent (normally only top level windows but in wxGTK
471     // there is also the exception of wxMenuBar)
GTKNeedsParent()472     virtual bool GTKNeedsParent() const { return !IsTopLevel(); }
473 
474     enum ScrollUnit { ScrollUnit_Line, ScrollUnit_Page, ScrollUnit_Max };
475 
476     // common part of ScrollLines() and ScrollPages() and could be used, in the
477     // future, for horizontal scrolling as well
478     //
479     // return true if we scrolled, false otherwise (on error or simply if we
480     // are already at the end)
481     bool DoScrollByUnits(ScrollDir dir, ScrollUnit unit, int units);
482     virtual void AddChildGTK(wxWindowGTK* child);
483 
484 #ifdef __WXGTK3__
485     // paint context is stashed here so wxPaintDC can use it
486     cairo_t* m_paintContext;
487     // style provider for "background-image"
488     GtkStyleProvider* m_styleProvider;
489 
490 public:
GTKPaintContext()491     cairo_t* GTKPaintContext() const
492     {
493         return m_paintContext;
494     }
495     void GTKSizeRevalidate();
496 #endif
497 
498     wxDECLARE_DYNAMIC_CLASS(wxWindowGTK);
499     wxDECLARE_NO_COPY_CLASS(wxWindowGTK);
500 };
501 
502 #endif // _WX_GTK_WINDOW_H_
503