File indexing completed on 2024-04-28 05:32:11
0001 #ifndef oxygengtkcellinfo_h 0002 #define oxygengtkcellinfo_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 "oxygenflags.h" 0011 0012 #include <vector> 0013 #include <iostream> 0014 #include <gdk/gdk.h> 0015 #include <gtk/gtk.h> 0016 0017 namespace Oxygen 0018 { 0019 namespace Gtk 0020 { 0021 0022 //! stores information for a given treeview cell 0023 /*! 0024 note: treeview itself is not stored as a member of the object, to avoid carying dangling pointers 0025 around. As a consequence it must be passed as argument of all methods that would need it. This 0026 implicitely requires that the same treeview is used in constructor and accessors, although it would 0027 not crash if not the case 0028 */ 0029 class CellInfo 0030 { 0031 0032 public: 0033 0034 //! empty constructor 0035 explicit CellInfo( void ): 0036 _path( 0L ), 0037 _column( -1 ) 0038 {} 0039 0040 //! copy constructor 0041 CellInfo( const CellInfo& other ): 0042 _path( other._path ? gtk_tree_path_copy( other._path ):0L ), 0043 _column( other._column ) 0044 {} 0045 0046 //! construct from tree view and position 0047 /*! unfortunately the path retrieval does not always work because x and y must be positive */ 0048 explicit CellInfo( GtkTreeView* treeView, int x, int y ): 0049 _path(0L), 0050 _column(-1) 0051 { 0052 GtkTreeViewColumn *column( 0L ); 0053 gtk_tree_view_get_path_at_pos( treeView, x, y, &_path, &column, 0L, 0L ); 0054 _column = indexOfColumn( treeView, column ); 0055 } 0056 0057 //! construct from tree view and rectangle 0058 explicit CellInfo( GtkTreeView* treeView, int x, int y, int w, int h ); 0059 0060 //! destructor 0061 virtual ~CellInfo( void ) 0062 { if( _path ) gtk_tree_path_free( _path ); } 0063 0064 //! assignment operator 0065 CellInfo& operator = (const CellInfo& other ) 0066 { 0067 if( _path ) gtk_tree_path_free( _path ); 0068 _path = other._path ? gtk_tree_path_copy( other._path ):0L; 0069 _column = other._column; 0070 return *this; 0071 } 0072 0073 //! equal to operator 0074 bool operator == (const CellInfo& other ) const 0075 { return sameColumn( other ) && samePath( other ); } 0076 0077 //! equal to operator 0078 bool operator != (const CellInfo& other ) const 0079 { return !( sameColumn( other ) && samePath( other )); } 0080 0081 //! clear 0082 void clear( void ) 0083 { 0084 if( _path ) gtk_tree_path_free( _path ); 0085 _path = 0L; 0086 _column = -1; 0087 } 0088 0089 //!@name accessors 0090 //@{ 0091 0092 //! true if valid 0093 bool isValid( void ) const 0094 { return _path && _column >= 0; } 0095 0096 //! returns true if column is the last one 0097 bool isLastVisibleColumn( GtkTreeView* ) const; 0098 0099 //! returns true if column is the first one 0100 bool isFirstVisibleColumn( GtkTreeView* ) const; 0101 0102 //! returns true if column is the one that contains expander 0103 bool isExpanderColumn( GtkTreeView* treeView ) const 0104 { return _column >= 0 && _column == indexOfColumn( treeView, gtk_tree_view_get_expander_column( treeView ) ); } 0105 0106 //! returs true if column is let of expander column 0107 bool isLeftOfExpanderColumn( GtkTreeView* ) const; 0108 0109 //! returns true if path has parent 0110 bool hasParent( GtkTreeView* ) const; 0111 0112 //! parent cell 0113 CellInfo parent( void ) const; 0114 0115 //! returns true if path has children 0116 bool hasChildren( GtkTreeView* ) const; 0117 0118 //! returns true if path is last at its given level 0119 bool isLast( GtkTreeView* ) const; 0120 0121 //! return path depth 0122 unsigned int depth( void ) const 0123 { return _path ? (unsigned int) gtk_tree_path_get_depth( _path ):0; } 0124 0125 //! true if column match 0126 bool sameColumn( const CellInfo& other ) const 0127 { return _column == other._column; } 0128 0129 //! true if path match 0130 bool samePath( const CellInfo& other ) const 0131 { 0132 if( _path ) return other._path && !gtk_tree_path_compare( _path, other._path ); 0133 else return !other._path; 0134 } 0135 0136 //! background rect 0137 GdkRectangle backgroundRect( GtkTreeView* ) const; 0138 0139 //@} 0140 0141 private: 0142 0143 //! path 0144 GtkTreePath* _path; 0145 0146 //! column index 0147 gint _column; 0148 0149 //! streamer 0150 friend std::ostream& operator << (std::ostream& out, const CellInfo& info ) 0151 { 0152 0153 if( info.isValid() ) 0154 { 0155 gchar* path( gtk_tree_path_to_string( info._path ) ); 0156 out << path; 0157 g_free( path ); 0158 } else out << "invalid"; 0159 return out; 0160 } 0161 0162 static gint indexOfColumn( GtkTreeView*, GtkTreeViewColumn* ); 0163 0164 }; 0165 0166 //! cell info flags 0167 /*! stores relevant information from cell info needed for painting */ 0168 class CellInfoFlags 0169 { 0170 0171 public: 0172 0173 //! constructor 0174 explicit CellInfoFlags( void ): 0175 _depth(0), 0176 _expanderSize(0), 0177 _levelIndent(0) 0178 {} 0179 0180 //! flags 0181 enum CellFlag 0182 { 0183 HasParent = 1<<0, 0184 HasChildren = 1<<1, 0185 IsLast = 1<<2, 0186 Reversed = 1<<3 0187 }; 0188 0189 OX_DECLARE_FLAGS( CellFlags, CellFlag ); 0190 0191 //! constructor from CellInfo 0192 explicit CellInfoFlags( GtkTreeView* treeView, const CellInfo& cellInfo ); 0193 0194 //! flags 0195 CellFlags _flags; 0196 0197 //! depth 0198 unsigned int _depth; 0199 int _expanderSize; 0200 int _levelIndent; 0201 0202 //! keep track of whether this cell, or parents are last in hierarchy 0203 std::vector<bool> _isLast; 0204 }; 0205 0206 } 0207 0208 OX_DECLARE_OPERATORS_FOR_FLAGS( Gtk::CellInfoFlags::CellFlags ); 0209 0210 } 0211 #endif