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