1 #ifndef oxygenscrolledwindowdata_h
2 #define oxygenscrolledwindowdata_h
3 /*
4 * this file is part of the oxygen gtk engine
5 * Copyright (c) 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
6 * Copyright (c) 2010 Ruslan Kabatsayev <b7.10110111@gmail.com>
7 *
8 * This  library is free  software; you can  redistribute it and/or
9 * modify it  under  the terms  of the  GNU Lesser  General  Public
10 * License  as published  by the Free  Software  Foundation; either
11 * version 2 of the License, or(at your option ) any later version.
12 *
13 * This library is distributed  in the hope that it will be useful,
14 * but  WITHOUT ANY WARRANTY; without even  the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License  along  with  this library;  if not,  write to  the Free
20 * Software Foundation, Inc., 51  Franklin St, Fifth Floor, Boston,
21 * MA 02110-1301, USA.
22 */
23 
24 #include "oxygensignal.h"
25 
26 #include <gtk/gtk.h>
27 #include <algorithm>
28 #include <map>
29 
30 namespace Oxygen
31 {
32 
33     //! handle hover in scrolledwindows
34     class ScrolledWindowData
35     {
36 
37         public:
38 
39         //! constructor
ScrolledWindowData(void)40         ScrolledWindowData( void ):
41             _target(0)
42         {}
43 
44         //! destructor
~ScrolledWindowData(void)45         virtual ~ScrolledWindowData( void )
46         { disconnect( _target ); }
47 
48         //! setup connections
49         void connect( GtkWidget* );
50 
51         //! disconnect
52         void disconnect( GtkWidget* );
53 
54         //! true if any child is hovered
hovered(void)55         bool hovered( void ) const
56         { return std::find_if( _childrenData.begin(), _childrenData.end(), HoveredFTor() ) != _childrenData.end(); }
57 
58         //! true if any child has focus
focused(void)59         bool focused( void ) const
60         { return std::find_if( _childrenData.begin(), _childrenData.end(), FocusedFTor() ) != _childrenData.end(); }
61 
62         //! register child
63         /*! needed to track enter/leave events in treeview headers */
64         void registerChild( GtkWidget* );
65 
66         protected:
67 
68         //! set mouse over state
69         virtual void setHovered( GtkWidget* widget, bool value );
70 
71         //! set focus state
72         virtual void setFocused( GtkWidget* widget, bool value );
73 
74         //! unregister child
75         void unregisterChild( GtkWidget* );
76 
77         //!@ callbacks
78         //@{
79         static gboolean childDestroyNotifyEvent( GtkWidget*, gpointer );
80         static gboolean enterNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer );
81         static gboolean leaveNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer );
82         static gboolean focusInNotifyEvent( GtkWidget*, GdkEvent*, gpointer );
83         static gboolean focusOutNotifyEvent( GtkWidget*, GdkEvent*, gpointer );
84         static void childAddedEvent( GtkContainer* parent, GtkWidget*, gpointer );
85         //@}
86 
87         private:
88 
89         //! target widget
90         GtkWidget* _target;
91 
92         //! child data
93         class ChildData
94         {
95             public:
96 
97             //! constructor
ChildData(void)98             ChildData( void ):
99                 _hovered( false ),
100                 _focused( false )
101             {}
102 
103             //! destructor
~ChildData(void)104             virtual ~ChildData( void )
105             {}
106 
107             //! disconnect all signals
108             void disconnect( GtkWidget* );
109 
110             //! true if widget is hovered
111             bool _hovered;
112             bool _focused;
113 
114             Signal _destroyId;
115             Signal _enterId;
116             Signal _leaveId;
117             Signal _focusInId;
118             Signal _focusOutId;
119 
120         };
121 
122         //! need to detect hovered child
123         class HoveredFTor
124         {
125             public:
126 
operator()127             bool operator () ( const std::pair<GtkWidget*, ChildData>& dataPair )
128             { return dataPair.second._hovered; }
129 
130         };
131 
132         //! need to detect hovered child
133         class FocusedFTor
134         {
135             public:
136 
operator()137             bool operator () ( const std::pair<GtkWidget*, ChildData>& dataPair )
138             { return dataPair.second._focused; }
139 
140         };
141 
142         //! map registered children and corresponding data
143         typedef std::map<GtkWidget*, ChildData> ChildDataMap;
144         ChildDataMap _childrenData;
145 
146     };
147 
148 }
149 
150 #endif
151