summaryrefslogtreecommitdiffstats
path: root/tdegtk/tdegtk-utils.h
blob: 66be2c978d2d21e62505ab17218375197de46d4a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
#ifndef tdegtk_utils_h
#define tdegtk_utils_h
/*
* this file was largely taken from the oxygen gtk engine
* Copyright (c) 2010 Hugo Pereira Da Costa <[email protected]>
* Copyright (c) 2010 Ruslan Kabatsayev <[email protected]>
*
* GdkPixbuf modification code from Walmis
* <http://gnome-look.org/content/show.php?content=77783&forumpage=3>
*
* This  library is free  software; you can  redistribute it and/or
* modify it  under  the terms  of the  GNU Lesser  General  Public
* License  as published  by the Free  Software  Foundation; either
* version 2 of the License, or( at your option ) any later version.
*
* This library is distributed  in the hope that it will be useful,
* but  WITHOUT ANY WARRANTY; without even  the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License  along  with  this library;  if not,  write to  the Free
* Software Foundation, Inc., 51  Franklin St, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/

// #include "oxygenrgba.h"

#include <gdk/gdk.h>
#include <gtk/gtk.h>

#include <cmath>
#include <string>

#if 0
    //! GdkRectangle streamer
    inline std::ostream& operator << (std::ostream& out, const GdkRectangle& rect )
    {
        out << "( " << rect.x << "," << rect.y << "," << rect.width << "," << rect.height << ")";
        return out;
    }

    //! GtkBorder streamer
    inline std::ostream& operator << (std::ostream& out, const GtkBorder& border )
    {
        out << "( " << border.left << "," << border.right << "," << border.top << "," << border.bottom << ")";
        return out;
    }

    //! streamer for GtkWidgetPath
    std::ostream& operator << ( std::ostream& out, const GtkWidgetPath* path );

    //! GtkContainer streamer
    inline std::ostream& operator << (std::ostream& out, GtkContainer* container)
    {
        GList* children=gtk_container_get_children(container);
        for(GList* child=g_list_first(children); child; child=g_list_next(child))
        {
            out << G_OBJECT_TYPE_NAME(child->data) << " ";
        }
        g_list_free(children);
        return out;
    }
#endif

    namespace Gtk
    {

        //! mouse button enumeration
        enum MouseButton
        {
            NoButton = 0,
            LeftButton = 1,
            RightButton = 2,
            MidButton = 3
        };

        //@!name gdk utilities
        //@{

#if 0
        //! returns OxygenRgba color from GdkColor
        /*! TODO: remove as obsolete */
        inline ColorUtils::Rgba gdk_get_color( const GdkColor& color )
        {
            return ColorUtils::Rgba(
                double(color.red)/0xffff,
                double(color.green)/0xffff,
                double(color.blue)/0xffff );
        }

        //! returns OxygenRgba color from GdkColor
        inline ColorUtils::Rgba gdk_get_color( const GdkRGBA& color )
        { return ColorUtils::Rgba( color.red, color.green, color.blue, color.alpha ); }
#endif

        //! map widget origin to top level
        /*!
        x and y correspond to (0,0) maped to toplevel window;
        w and h correspond to toplevel window frame size
        */
        bool gdk_window_map_to_toplevel( GdkWindow*, gint*, gint*, gint*, gint*, bool frame = false );

        //! map widget origin to top level
        /*!
        x and y correspond to (0,0) maped to toplevel window;
        w and h correspond to toplevel window frame size
        */
        bool gtk_widget_map_to_toplevel( GtkWidget*, gint*, gint*, gint*, gint*, bool frame = false );

        //! map widget onto another (parent) widget
        /*! second argument can be any parent in widget's ancestry tree */
        bool gtk_widget_map_to_parent( GtkWidget*, GtkWidget*, gint*, gint*, gint*, gint* );

        //! map window/widget origin to top level
        inline bool gdk_map_to_toplevel( GdkWindow* window, GtkWidget* widget, gint* x, gint* y, gint* w, gint* h, bool frame = false )
        {
            if( window && GDK_IS_WINDOW( window ) ) return gdk_window_map_to_toplevel( window, x, y, w, h, frame );
            else return gtk_widget_map_to_toplevel( widget, x, y, w, h, frame );
        }

        //! map window origin to top level
        inline bool gdk_map_to_toplevel( GdkWindow* window, gint* x, gint* y, gint* w, gint* h, bool frame = false )
        { return gdk_window_map_to_toplevel( window, x, y, w, h, frame ); }

        //! translate origin of child window into parent
        /*! returns true on success */
        bool gdk_window_translate_origin( GdkWindow*, GdkWindow*, gint*, gint* );

        //! get top level windows dimension
        void gdk_toplevel_get_size( GdkWindow*, gint*, gint* );

        //! get top level windows dimension
        void gdk_toplevel_get_frame_size( GdkWindow*, gint*, gint* );

        //! get position relatve to toplevel
        void gdk_window_get_toplevel_origin( GdkWindow*, gint*, gint* );

        //! add alpha channel to pixbuf
        GdkPixbuf* gdk_pixbuf_set_alpha( const GdkPixbuf*, double );

        //! changes the gamma value of an image
        bool gdk_pixbuf_to_gamma( GdkPixbuf* pixbuf, double value );

        //! resize pixbuf
        GdkPixbuf* gdk_pixbuf_resize( GdkPixbuf* src, int width, int height );

        //! returns initialized GdkRectangle
        inline GdkRectangle gdk_rectangle( int x = 0, int y = 0, int w = -1, int h = -1 )
        {
            GdkRectangle out = {x, y, w, h};
            return out;
        }

        //! returns true if rectangle is valid
        inline bool gdk_rectangle_is_valid( const GdkRectangle* rect )
        { return rect && rect->width > 0 && rect->height > 0; }

        //! performs union of two rectangle, properly accounting for their validity
        inline void gdk_rectangle_union( const GdkRectangle* first, const GdkRectangle* second, GdkRectangle* out )
        {
            if( !out ) return;
            const bool firstIsValid( Gtk::gdk_rectangle_is_valid( first ) );
            const bool secondIsValid( Gtk::gdk_rectangle_is_valid( second ) );
            if( firstIsValid && secondIsValid )  ::gdk_rectangle_union( first, second, out );
            else if( secondIsValid ) *out = *second;
            else *out = *first;
        }

        //! returns true if given rectangle contains point
        inline bool gdk_rectangle_contains( const GdkRectangle* rect, int x, int y )
        {
            return
                rect &&
                ( rect->x <= x && (rect->x + rect->width) > x ) &&
                ( rect->y <= y && (rect->y + rect->height) > y );
        }

        //@}

        //! get arrow orientation from angle
        inline GtkArrowType gtk_arrow_get_type( const double& angle )
        {
            static const double delta( 0.001 );
            if( std::abs( angle ) < delta ) return GTK_ARROW_UP;
            else if( std::abs( angle - M_PI/2 ) < delta ) return GTK_ARROW_RIGHT;
            else if( std::abs( angle - M_PI ) < delta ) return GTK_ARROW_DOWN;
            else return GTK_ARROW_LEFT;
        }

        //! returns true if widget's layout is reversed
        inline bool gtk_widget_layout_is_reversed( GtkWidget* widget )
        { return widget ? gtk_widget_get_direction( widget ) == GTK_TEXT_DIR_RTL : false; }

        //! returns true if widget's layout is reversed
        inline bool gtk_theming_engine_layout_is_reversed( GtkThemingEngine* engine )
        { return engine ? gtk_theming_engine_get_direction( engine ) == GTK_TEXT_DIR_RTL : false; }

        //! set all buttons in the container to state NORMAL
        void gtk_container_adjust_buttons_state( GtkContainer*, gpointer=0L );

        //! returns widget allocation
        inline GtkAllocation gtk_widget_get_allocation( GtkWidget* widget )
        {
            GtkAllocation allocation = { 0, 0, -1, -1 };
            ::gtk_widget_get_allocation( widget, &allocation );
            return allocation;
        }

        //! returns true if given path has given type
        bool gtk_widget_path_has_type( const GtkWidgetPath*, GType );

        //! returns true if widget is a groupbox (a la Qt)
        inline bool gtk_widget_is_groupbox( GtkWidget* widget )
        {
            return
                GTK_IS_FRAME( widget ) &&
                gtk_frame_get_label_widget( GTK_FRAME( widget ) ) &&
                gtk_frame_get_shadow_type( GTK_FRAME( widget ) ) == GTK_SHADOW_OUT;
        }

        //! returns true if widget (or one of its parent) has a custom background
        bool gtk_widget_has_custom_background( GtkWidget*, GtkStateType = GTK_STATE_NORMAL );

        //! returns true if is an Gnome applet
        bool gtk_widget_is_applet( GtkWidget* );

        //! print some widget information
        void gtk_widget_print_tree( GtkWidget* );

        //! returns true if widget supports rgba
        bool gtk_widget_has_rgba( GtkWidget* );

        //! returns true if default screen is composited
        bool gdk_default_screen_is_composited( void );

        //! returns true if window supports rgba
        bool gdk_window_has_rgba( GdkWindow* );

        //! true if visual supports rgba
        bool gdk_visual_has_rgba( GdkVisual* );

        //! returns true if window is a base window
        bool gdk_window_is_base( GdkWindow* );

        //! returns true if window is a base window that do not need painting
        bool gdk_window_nobackground( GdkWindow* );

        //! true if object match a given type
        bool g_object_is_a( const GObject*, const std::string& );

        //! trigger area update using GdkRectangle
        inline void gtk_widget_queue_draw( GtkWidget* widget, const GdkRectangle* rect = 0L )
        {
            if( !gdk_rectangle_is_valid( rect ) ) ::gtk_widget_queue_draw( widget );
            else ::gtk_widget_queue_draw_area( widget, rect->x, rect->y, rect->width, rect->height );
        }

        //!@name check parent type
        //@{

        //! returns widget path as a string
        std::string gtk_widget_path( GtkWidget* );

        //! return parent of given type if any
        GtkWidget* gtk_widget_find_parent( GtkWidget*, GType );

        //! return parent of given type
        inline GtkWidget* gtk_widget_find_parent( GtkWidget* widget, const std::string& typeName )
        {
            const GType tmp( g_type_from_name( typeName.c_str() ) );
            return tmp ? gtk_widget_find_parent( widget, tmp ): 0L;
        }

        //! return parent "group box" if any.
        GtkWidget* gtk_parent_groupbox( GtkWidget* widget );

        //! return parent button if any.
        inline GtkWidget* gtk_parent_button( GtkWidget* widget )
        { return gtk_widget_find_parent( widget, GTK_TYPE_BUTTON ); }

        //! return parent menu if any
        inline GtkWidget* gtk_parent_menubar( GtkWidget* widget )
        { return gtk_widget_find_parent( widget, GTK_TYPE_MENU_BAR ); }

        //! return parent menu if any
        inline GtkWidget* gtk_parent_menu( GtkWidget* widget )
        { return gtk_widget_find_parent( widget, GTK_TYPE_MENU ); }

        //! return parent treeview if any.
        inline GtkWidget* gtk_parent_tree_view( GtkWidget* widget )
        { return gtk_widget_find_parent( widget, GTK_TYPE_TREE_VIEW ); }

        //! return parent combobox if any.
        inline GtkWidget* gtk_parent_combobox( GtkWidget* widget )
        { return gtk_widget_find_parent( widget, GTK_TYPE_COMBO_BOX ); }

        //! return parent combobox if any.
        inline GtkWidget* gtk_parent_combobox_entry( GtkWidget* widget )
        {
            GtkWidget* parent( gtk_parent_combobox( widget ) );
            return ( parent && gtk_combo_box_get_has_entry( GTK_COMBO_BOX( parent ) ) ) ? parent:0L;
        }

        //! return parent scrolled window if any.
        inline GtkWidget* gtk_parent_scrolled_window( GtkWidget* widget )
        { return gtk_widget_find_parent( widget, GTK_TYPE_SCROLLED_WINDOW ); }

        //! return parent statusbar if any.
        inline GtkWidget* gtk_parent_statusbar( GtkWidget* widget )
        { return gtk_widget_find_parent( widget, GTK_TYPE_STATUSBAR ); }

        //! return parent combobox if any.
        inline GtkWidget* gtk_parent_notebook( GtkWidget* widget )
        { return gtk_widget_find_parent( widget, GTK_TYPE_NOTEBOOK ); }

        //! returns true if potentialParent is (maybe indirect) parent of widget
        bool gtk_widget_is_parent( GtkWidget*, GtkWidget* potentialParent );

        //! returns true if one of the parent widgets has a sunken shadow
        bool gtk_parent_is_shadow_in( GtkWidget* );

        //@}

        //! true if a widget (orientable) is horizontal
        inline bool gtk_widget_is_horizontal( GtkWidget* widget )
        {
            if( !GTK_IS_ORIENTABLE( widget ) ) return true;
            return gtk_orientable_get_orientation( GTK_ORIENTABLE( widget ) ) == GTK_ORIENTATION_HORIZONTAL;
        }


        //! true if a widget (orientable) is vertical
        inline bool gtk_widget_is_vertical( GtkWidget* widget )
        {
            if( !GTK_IS_ORIENTABLE( widget ) ) return false;
            return gtk_orientable_get_orientation( GTK_ORIENTABLE( widget ) ) == GTK_ORIENTATION_VERTICAL;
        }

        //! true if scrolled window must be forced to have a sunken frame
        bool gtk_scrolled_window_force_sunken( GtkWidget* );

        //!@name button utilities
        //@{

        //! true for 'flat' buttons (e.g. toolbuttons)
        bool gtk_button_is_flat( GtkWidget* );

        //! true for treeview headers and affiliated
        bool gtk_button_is_header( GtkWidget* );

        //! true for buttons in path bars
        bool gtk_button_is_in_path_bar( GtkWidget* widget );

        //! true if widget is last in path bar
        bool gtk_path_bar_button_is_last( GtkWidget* widget );

        //! returns an image on button-container
        GtkWidget* gtk_button_find_image( GtkWidget* );

        //! returns an image on button-container
        GtkWidget* gtk_button_find_label( GtkWidget* );

        //@}

        //!@name combobox utilities
        //@{

        //! returns true if combobox has frame
        bool gtk_combobox_has_frame( GtkWidget* );

        //! true if widget is the treeview of a combobox
        bool gtk_combobox_is_tree_view( GtkWidget* );

        //! true if widget is the treeview of a combobox
        bool gtk_combobox_is_scrolled_window( GtkWidget* );

        //! true if widget is the treeview of a combobox
        bool gtk_combobox_is_viewport( GtkWidget* );

        //! true if widget is the treeview of a combobox
        bool gtk_combobox_is_frame( GtkWidget* );

        //! true if combobox must appear as list
        bool gtk_combobox_appears_as_list( GtkWidget* );

        //@}

        //!@name notebook utilities
        //@{

        //! returns true if position is in hovered tab
        //* this should move to OxygenTabWidgetData
        bool gtk_notebook_tab_contains( GtkWidget*, int tab, int x, int y );

        //! returns tab matching position or -1 if none
        int gtk_notebook_find_tab( GtkWidget*, int x, int y );

        //! returns index of first visible tab
        int gtk_notebook_find_first_tab( GtkWidget* );

        //! returns true if widget is one of the notebook's tab labels
        bool gtk_notebook_is_tab_label( GtkNotebook*, GtkWidget* );

        //! returns tabbar rect in notebook
        void gtk_notebook_get_tabbar_rect( GtkNotebook*, GdkRectangle* );

        //! returns true if notebook has visible scrollbar arrows
        /*! arrows are dimmed visible if at least one of the child tab_labels is unmapped */
        bool gtk_notebook_has_visible_arrows( GtkNotebook* );

        // make all the buttons on the tabs normal
        bool gtk_notebook_update_close_buttons( GtkNotebook*);

        //! returns true if widget is a notebook close button
        bool gtk_notebook_is_close_button( GtkWidget* );

        //@}

        //! calculates viewport offsets (between view window and bin window
        void gtk_viewport_get_position( GtkViewport*, gint*, gint* );

        //! returns a widget which has response_id as response id for dialog
        GtkWidget* gtk_dialog_find_button( GtkDialog*, gint );

    }

#endif