summaryrefslogtreecommitdiffstats
path: root/tdegtk/tdegtk-tabwidgetdata.h
blob: e7284bff92eb3de5cd06bdbafeb817f75af6fa7f (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
#ifndef tdegtk_tabwidgetdata_h
#define tdegtk_widgetdata_h
/*
* this file was largely taken from the oxygen gtk engine
* Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
*
* 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 "tdegtk-signals.h"

#include <gtk/gtk.h>
#include <vector>
#include <map>

    //! detects and stores tab widget hovered tab
    class TabWidgetData
    {

        public:

        //! constructor
        TabWidgetData( void ):
            _target(0L),
            _hoveredTab(-1),
            _dragInProgress( false ),
            _dirty( false )
        {}

        //! destructor
        virtual ~TabWidgetData( void )
        { disconnect( _target ); }

        //! setup connections
        void connect( GtkWidget* );

        //! disconnect
        void disconnect( GtkWidget* );

        //!@name modifiers
        //@{

        //! update tab rectangle
        /* this is used to decide when a tab is hovered or not */
        void updateTabRect( GtkWidget*, int, const GdkRectangle& );

        //! update hovered tab
        void updateHoveredTab( GtkWidget* = 0L );

        //! true when drag is in progress
        void setDragInProgress( bool value )
        { _dragInProgress = value; }

        //! toggle dirty state
        void toggleDirty( void )
        { setDirty( !isDirty() ); }

        //! mark as dirty
        void setDirty( bool );

        //@}

        //@name accessors
        //@{

        //! true if hovered
        int hoveredTab( void ) const
        { return _hoveredTab; }

        //! true when drag is in progress
        bool dragInProgress( void ) const
        { return _dragInProgress; }

        //! true if is dirty
        bool isDirty( void ) const
        { return _dirty; }

        //! returns true if provided point is in one tab of the widget
        bool isInTab( int x, int y ) const;

        //@]

        protected:

        //! set current tab
        void setHoveredTab( GtkWidget*, int );

        //! child registration
        //@{

        void updateRegisteredChildren( GtkWidget* = 0L );
        void registerChild( GtkWidget* );
        void unregisterChild( GtkWidget* );

        //@}

        //!@name static callbacks
        //@{
        static gboolean motionNotifyEvent( GtkWidget*, GdkEventMotion*, gpointer );
        static gboolean leaveNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer );
        static void pageAddedEvent( GtkNotebook*, GtkWidget*, guint, gpointer );
        static gboolean childDestroyNotifyEvent( GtkWidget*, gpointer );
        static gboolean childCrossingNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer );
        static void childAddedEvent( GtkContainer*, GtkWidget*, gpointer );
        //@}

        private:

        //! default tabRect size
        GdkRectangle defaultRect( void ) const
        {
            GdkRectangle out = {0, 0, -1, -1};
            return out;
        }

        //! target widget
        GtkWidget* _target;

        //!@name callbacks IDs
        //@{
        Signal _motionId;
        Signal _leaveId;
        Signal _pageAddedId;
        //@}

        //! index of currently hovered tab
        int _hoveredTab;

        //! true when there is a drag in progress
        bool _dragInProgress;

        //! true when tabbar is dirty
        /*! a repaint is triggered of the full tabbar when set to true.
        This forces the tabbar base to be redrawn event if the selected tab
        has not been primarily damaged */
        bool _dirty;

        //! store rectangles matching tabs
        typedef std::vector<GdkRectangle> RectangleList;
        RectangleList _tabRects;

        //! child data
        /*!
        one must keep track of the tab widgets children enter/leave event
        to properly update tab hover because some tabs have embedded children.
        This is notably the case for gimp, nautilus (in tabbed mode), etc.
        */
        class ChildData
        {
            public:

            //! constructor
            ChildData( void )
            {}

            //! destructor
            virtual ~ChildData( void )
            {}

            //! disconnect all signals
            void disconnect( void );

            Signal _destroyId;
            Signal _addId;
            Signal _enterId;
            Signal _leaveId;
        };

        //! map registered children and corresponding data
        typedef std::map<GtkWidget*, ChildData> ChildDataMap;
        ChildDataMap _childrenData;

    };

#endif