File indexing completed on 2024-05-12 17:05:50
0001 #ifndef oxygentabwidgetdata_h 0002 #define oxygentabwidgetdata_h 0003 /* 0004 * this file is part of the oxygen gtk engine 0005 * SPDX-FileCopyrightText: 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr> 0006 * 0007 * SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 0010 #include "oxygensignal.h" 0011 0012 #include <gtk/gtk.h> 0013 #include <vector> 0014 #include <map> 0015 0016 namespace Oxygen 0017 { 0018 0019 //! detects and stores tab widget hovered tab 0020 class TabWidgetData 0021 { 0022 0023 public: 0024 0025 //! constructor 0026 TabWidgetData( void ): 0027 _target(0L), 0028 _hoveredTab(-1), 0029 _dragInProgress( false ), 0030 _dirty( false ) 0031 {} 0032 0033 //! destructor 0034 virtual ~TabWidgetData( void ) 0035 { disconnect( _target ); } 0036 0037 //! setup connections 0038 void connect( GtkWidget* ); 0039 0040 //! disconnect 0041 void disconnect( GtkWidget* ); 0042 0043 //!@name modifiers 0044 //@{ 0045 0046 //! update tab rectangle 0047 /* this is used to decide when a tab is hovered or not */ 0048 void updateTabRect( GtkWidget*, int, const GdkRectangle& ); 0049 0050 //! update hovered tab 0051 void updateHoveredTab( GtkWidget* = 0L ); 0052 0053 //! true when drag is in progress 0054 void setDragInProgress( bool value ) 0055 { _dragInProgress = value; } 0056 0057 //! toggle dirty state 0058 void toggleDirty( void ) 0059 { setDirty( !isDirty() ); } 0060 0061 //! mark as dirty 0062 void setDirty( bool ); 0063 0064 //@} 0065 0066 //@name accessors 0067 //@{ 0068 0069 //! true if hovered 0070 int hoveredTab( void ) const 0071 { return _hoveredTab; } 0072 0073 //! true when drag is in progress 0074 bool dragInProgress( void ) const 0075 { return _dragInProgress; } 0076 0077 //! true if is dirty 0078 bool isDirty( void ) const 0079 { return _dirty; } 0080 0081 //! returns true if provided point is in one tab of the widget 0082 bool isInTab( int x, int y ) const; 0083 0084 //@] 0085 0086 protected: 0087 0088 //! set current tab 0089 void setHoveredTab( GtkWidget*, int ); 0090 0091 //! child registration 0092 //@{ 0093 0094 void updateRegisteredChildren( GtkWidget* = 0L ); 0095 void registerChild( GtkWidget* ); 0096 void unregisterChild( GtkWidget* ); 0097 0098 //@} 0099 0100 //!@name static callbacks 0101 //@{ 0102 static gboolean motionNotifyEvent( GtkWidget*, GdkEventMotion*, gpointer ); 0103 static gboolean leaveNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer ); 0104 static void pageAddedEvent( GtkNotebook*, GtkWidget*, guint, gpointer ); 0105 static gboolean childDestroyNotifyEvent( GtkWidget*, gpointer ); 0106 static gboolean childCrossingNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer ); 0107 static void childAddedEvent( GtkContainer*, GtkWidget*, gpointer ); 0108 //@} 0109 0110 private: 0111 0112 //! default tabRect size 0113 GdkRectangle defaultRect( void ) const 0114 { 0115 GdkRectangle out = {0, 0, -1, -1}; 0116 return out; 0117 } 0118 0119 //! target widget 0120 GtkWidget* _target; 0121 0122 //!@name callbacks IDs 0123 //@{ 0124 Signal _motionId; 0125 Signal _leaveId; 0126 Signal _pageAddedId; 0127 //@} 0128 0129 //! index of currently hovered tab 0130 int _hoveredTab; 0131 0132 //! true when there is a drag in progress 0133 bool _dragInProgress; 0134 0135 //! true when tabbar is dirty 0136 /*! a repaint is triggered of the full tabbar when set to true. 0137 This forces the tabbar base to be redrawn event if the selected tab 0138 has not been primarily damaged */ 0139 bool _dirty; 0140 0141 //! store rectangles matching tabs 0142 typedef std::vector<GdkRectangle> RectangleList; 0143 RectangleList _tabRects; 0144 0145 //! child data 0146 /*! 0147 one must keep track of the tab widgets children enter/leave event 0148 to properly update tab hover because some tabs have embedded children. 0149 This is notably the case for gimp, nautilus (in tabbed mode), etc. 0150 */ 0151 class ChildData 0152 { 0153 public: 0154 0155 //! constructor 0156 ChildData( void ) 0157 {} 0158 0159 //! destructor 0160 virtual ~ChildData( void ) 0161 {} 0162 0163 //! disconnect all signals 0164 void disconnect( void ); 0165 0166 Signal _destroyId; 0167 Signal _addId; 0168 Signal _enterId; 0169 Signal _leaveId; 0170 }; 0171 0172 //! map registered children and corresponding data 0173 typedef std::map<GtkWidget*, ChildData> ChildDataMap; 0174 ChildDataMap _childrenData; 0175 0176 }; 0177 0178 } 0179 0180 #endif