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