1 #ifndef oxygentabwidgetdata_h 2 #define oxygentabwidgetdata_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 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or(at your option ) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free 19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, 20 * MA 02110-1301, USA. 21 */ 22 23 #include "oxygensignal.h" 24 25 #include <gtk/gtk.h> 26 #include <vector> 27 #include <map> 28 29 namespace Oxygen 30 { 31 32 //! detects and stores tab widget hovered tab 33 class TabWidgetData 34 { 35 36 public: 37 38 //! constructor TabWidgetData(void)39 TabWidgetData( void ): 40 _target(0L), 41 _hoveredTab(-1), 42 _dragInProgress( false ), 43 _dirty( false ) 44 {} 45 46 //! destructor ~TabWidgetData(void)47 virtual ~TabWidgetData( void ) 48 { disconnect( _target ); } 49 50 //! setup connections 51 void connect( GtkWidget* ); 52 53 //! disconnect 54 void disconnect( GtkWidget* ); 55 56 //!@name modifiers 57 //@{ 58 59 //! update tab rectangle 60 /* this is used to decide when a tab is hovered or not */ 61 void updateTabRect( GtkWidget*, int, const GdkRectangle& ); 62 63 //! update hovered tab 64 void updateHoveredTab( GtkWidget* = 0L ); 65 66 //! true when drag is in progress setDragInProgress(bool value)67 void setDragInProgress( bool value ) 68 { _dragInProgress = value; } 69 70 //! toggle dirty state toggleDirty(void)71 void toggleDirty( void ) 72 { setDirty( !isDirty() ); } 73 74 //! mark as dirty 75 void setDirty( bool ); 76 77 //@} 78 79 //@name accessors 80 //@{ 81 82 //! true if hovered hoveredTab(void)83 int hoveredTab( void ) const 84 { return _hoveredTab; } 85 86 //! true when drag is in progress dragInProgress(void)87 bool dragInProgress( void ) const 88 { return _dragInProgress; } 89 90 //! true if is dirty isDirty(void)91 bool isDirty( void ) const 92 { return _dirty; } 93 94 //! returns true if provided point is in one tab of the widget 95 bool isInTab( int x, int y ) const; 96 97 //@] 98 99 protected: 100 101 //! set current tab 102 void setHoveredTab( GtkWidget*, int ); 103 104 //! child registration 105 //@{ 106 107 void updateRegisteredChildren( GtkWidget* = 0L ); 108 void registerChild( GtkWidget* ); 109 void unregisterChild( GtkWidget* ); 110 111 //@} 112 113 //!@name static callbacks 114 //@{ 115 static gboolean motionNotifyEvent( GtkWidget*, GdkEventMotion*, gpointer ); 116 static gboolean leaveNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer ); 117 static void pageAddedEvent( GtkNotebook*, GtkWidget*, guint, gpointer ); 118 static gboolean childDestroyNotifyEvent( GtkWidget*, gpointer ); 119 static gboolean childCrossingNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer ); 120 static void childAddedEvent( GtkContainer*, GtkWidget*, gpointer ); 121 //@} 122 123 private: 124 125 //! default tabRect size defaultRect(void)126 GdkRectangle defaultRect( void ) const 127 { 128 GdkRectangle out = {0, 0, -1, -1}; 129 return out; 130 } 131 132 //! target widget 133 GtkWidget* _target; 134 135 //!@name callbacks IDs 136 //@{ 137 Signal _motionId; 138 Signal _leaveId; 139 Signal _pageAddedId; 140 //@} 141 142 //! index of currently hovered tab 143 int _hoveredTab; 144 145 //! true when there is a drag in progress 146 bool _dragInProgress; 147 148 //! true when tabbar is dirty 149 /*! a repaint is triggered of the full tabbar when set to true. 150 This forces the tabbar base to be redrawn event if the selected tab 151 has not been primarily damaged */ 152 bool _dirty; 153 154 //! store rectangles matching tabs 155 typedef std::vector<GdkRectangle> RectangleList; 156 RectangleList _tabRects; 157 158 //! child data 159 /*! 160 one must keep track of the tab widgets children enter/leave event 161 to properly update tab hover because some tabs have embedded children. 162 This is notably the case for gimp, nautilus (in tabbed mode), etc. 163 */ 164 class ChildData 165 { 166 public: 167 168 //! constructor ChildData(void)169 ChildData( void ) 170 {} 171 172 //! destructor ~ChildData(void)173 virtual ~ChildData( void ) 174 {} 175 176 //! disconnect all signals 177 void disconnect( void ); 178 179 Signal _destroyId; 180 Signal _addId; 181 Signal _enterId; 182 Signal _leaveId; 183 }; 184 185 //! map registered children and corresponding data 186 typedef std::map<GtkWidget*, ChildData> ChildDataMap; 187 ChildDataMap _childrenData; 188 189 }; 190 191 } 192 193 #endif 194