File indexing completed on 2024-05-12 05:34:35

0001 #ifndef oxygenscrolledwindowdata_h
0002 #define oxygenscrolledwindowdata_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 * SPDX-FileCopyrightText: 2010 Ruslan Kabatsayev <b7.10110111@gmail.com>
0007 *
0008 * SPDX-License-Identifier: LGPL-2.0-or-later
0009 */
0010 
0011 #include "oxygensignal.h"
0012 
0013 #include <gtk/gtk.h>
0014 #include <algorithm>
0015 #include <map>
0016 
0017 namespace Oxygen
0018 {
0019 
0020     //! handle hover in scrolledwindows
0021     class ScrolledWindowData
0022     {
0023 
0024         public:
0025 
0026         //! constructor
0027         ScrolledWindowData( void ):
0028             _target(0)
0029         {}
0030 
0031         //! destructor
0032         virtual ~ScrolledWindowData( void )
0033         { disconnect( _target ); }
0034 
0035         //! setup connections
0036         void connect( GtkWidget* );
0037 
0038         //! disconnect
0039         void disconnect( GtkWidget* );
0040 
0041         //! true if any child is hovered
0042         bool hovered( void ) const
0043         { return std::find_if( _childrenData.begin(), _childrenData.end(), HoveredFTor() ) != _childrenData.end(); }
0044 
0045         //! true if any child has focus
0046         bool focused( void ) const
0047         { return std::find_if( _childrenData.begin(), _childrenData.end(), FocusedFTor() ) != _childrenData.end(); }
0048 
0049         //! register child
0050         /*! needed to track enter/leave events in treeview headers */
0051         void registerChild( GtkWidget* );
0052 
0053         protected:
0054 
0055         //! set mouse over state
0056         virtual void setHovered( GtkWidget* widget, bool value );
0057 
0058         //! set focus state
0059         virtual void setFocused( GtkWidget* widget, bool value );
0060 
0061         //! unregister child
0062         void unregisterChild( GtkWidget* );
0063 
0064         //!@ callbacks
0065         //@{
0066         static gboolean childDestroyNotifyEvent( GtkWidget*, gpointer );
0067         static gboolean enterNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer );
0068         static gboolean leaveNotifyEvent( GtkWidget*, GdkEventCrossing*, gpointer );
0069         static gboolean focusInNotifyEvent( GtkWidget*, GdkEvent*, gpointer );
0070         static gboolean focusOutNotifyEvent( GtkWidget*, GdkEvent*, gpointer );
0071         static void childAddedEvent( GtkContainer* parent, GtkWidget*, gpointer );
0072         //@}
0073 
0074         private:
0075 
0076         //! target widget
0077         GtkWidget* _target;
0078 
0079         //! child data
0080         class ChildData
0081         {
0082             public:
0083 
0084             //! constructor
0085             ChildData( void ):
0086                 _hovered( false ),
0087                 _focused( false )
0088             {}
0089 
0090             //! destructor
0091             virtual ~ChildData( void )
0092             {}
0093 
0094             //! disconnect all signals
0095             void disconnect( GtkWidget* );
0096 
0097             //! true if widget is hovered
0098             bool _hovered;
0099             bool _focused;
0100 
0101             Signal _destroyId;
0102             Signal _enterId;
0103             Signal _leaveId;
0104             Signal _focusInId;
0105             Signal _focusOutId;
0106 
0107         };
0108 
0109         //! need to detect hovered child
0110         class HoveredFTor
0111         {
0112             public:
0113 
0114             bool operator () ( const std::pair<GtkWidget*, ChildData>& dataPair )
0115             { return dataPair.second._hovered; }
0116 
0117         };
0118 
0119         //! need to detect hovered child
0120         class FocusedFTor
0121         {
0122             public:
0123 
0124             bool operator () ( const std::pair<GtkWidget*, ChildData>& dataPair )
0125             { return dataPair.second._focused; }
0126 
0127         };
0128 
0129         //! map registered children and corresponding data
0130         typedef std::map<GtkWidget*, ChildData> ChildDataMap;
0131         ChildDataMap _childrenData;
0132 
0133     };
0134 
0135 }
0136 
0137 #endif