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