File indexing completed on 2024-05-12 17:05:51
0001 /* 0002 this file is part of the oxygen gtk engine 0003 SPDX-FileCopyrightText: 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "oxygentreeviewstatedata.h" 0009 #include "../config.h" 0010 0011 #include <iostream> 0012 0013 namespace Oxygen 0014 { 0015 0016 //_____________________________________________ 0017 void TreeViewStateData::connect( GtkWidget* widget ) 0018 { 0019 0020 #if OXYGEN_DEBUG 0021 std::cerr << "Oxygen::TreeViewStateData::connect - " << widget << " (" << G_OBJECT_TYPE_NAME( widget ) << ")" << std::endl; 0022 #endif 0023 0024 _target = widget; 0025 0026 // connect timeLines 0027 _current._timeLine.connect( (GSourceFunc)delayedUpdate, this ); 0028 _previous._timeLine.connect( (GSourceFunc)delayedUpdate, this ); 0029 0030 // set directions 0031 _current._timeLine.setDirection( TimeLine::Forward ); 0032 _previous._timeLine.setDirection( TimeLine::Backward ); 0033 0034 } 0035 0036 //_____________________________________________ 0037 void TreeViewStateData::disconnect( GtkWidget* widget ) 0038 { 0039 #if OXYGEN_DEBUG 0040 std::cerr << "Oxygen::TreeViewStateData::disconnect - " << widget << " (" << G_OBJECT_TYPE_NAME( widget ) << ")" << std::endl; 0041 #endif 0042 0043 _current._timeLine.disconnect(); 0044 _current._info.clear(); 0045 0046 _previous._timeLine.disconnect(); 0047 _previous._info.clear(); 0048 0049 _target = 0L; 0050 0051 } 0052 0053 //_____________________________________________ 0054 bool TreeViewStateData::updateState( const Gtk::CellInfo& info, bool state ) 0055 { 0056 if( state && info != _current._info ) 0057 { 0058 0059 // stop current animation if running 0060 if( _current._timeLine.isRunning() ) _current._timeLine.stop(); 0061 0062 // stop previous animation if running 0063 if( _current._info.isValid() ) 0064 { 0065 if( _previous._timeLine.isRunning() ) _previous._timeLine.stop(); 0066 0067 // update dirty rect, to make sure de-allocated cellInfo gets repainted 0068 if( _previous._info.isValid() && GTK_IS_TREE_VIEW( _target ) ) 0069 { _dirtyRect = _previous._info.backgroundRect( GTK_TREE_VIEW( _target ) ); } 0070 0071 // move current tab info to previous 0072 _previous._info = _current._info; 0073 _previous._timeLine.start(); 0074 } 0075 0076 // assign new info to current and start animation 0077 _current._info = info; 0078 if( _current._info.isValid() ) _current._timeLine.start(); 0079 0080 return true; 0081 0082 } else if( (!state) && info == _current._info ) { 0083 0084 // stop current animation if running 0085 if( _current._timeLine.isRunning() ) _current._timeLine.stop(); 0086 0087 // stop previous animation if running 0088 if( _previous._timeLine.isRunning() ) _previous._timeLine.stop(); 0089 0090 // update dirty rect, to make sure de-allocated cellInfo gets repainted 0091 if( _previous._info.isValid() && GTK_IS_TREE_VIEW( _target ) ) 0092 { _dirtyRect = _previous._info.backgroundRect( GTK_TREE_VIEW( _target ) ); } 0093 0094 // move current tab info to previous 0095 _previous._info = _current._info; 0096 if( _previous._info.isValid() ) _previous._timeLine.start(); 0097 0098 // assign invalid info to current 0099 _current._info.clear(); 0100 0101 return true; 0102 0103 } else return false; 0104 0105 } 0106 0107 //_____________________________________________ 0108 GdkRectangle TreeViewStateData::dirtyRect( void ) 0109 { 0110 0111 GdkRectangle rect( Gtk::gdk_rectangle() ); 0112 if( GTK_IS_TREE_VIEW( _target ) ) 0113 { 0114 GtkTreeView* treeView( GTK_TREE_VIEW( _target ) ); 0115 0116 const GdkRectangle previousRect( _previous._info.backgroundRect( treeView ) ); 0117 const GdkRectangle currentRect( _current._info.backgroundRect( treeView ) ); 0118 if( Gtk::gdk_rectangle_is_valid( &previousRect ) && Gtk::gdk_rectangle_is_valid( ¤tRect ) ) 0119 { 0120 0121 gdk_rectangle_union( &previousRect, ¤tRect, &rect ); 0122 0123 } else if( Gtk::gdk_rectangle_is_valid( &previousRect ) ) { 0124 0125 rect = previousRect; 0126 0127 } else if( Gtk::gdk_rectangle_is_valid( ¤tRect ) ) { 0128 0129 rect = currentRect; 0130 0131 } 0132 0133 // also union with dirty rect 0134 if( Gtk::gdk_rectangle_is_valid( &_dirtyRect ) ) 0135 { 0136 if( Gtk::gdk_rectangle_is_valid( &rect ) ) gdk_rectangle_union( &_dirtyRect, &rect, &rect ); 0137 else rect = _dirtyRect; 0138 0139 _dirtyRect = Gtk::gdk_rectangle(); 0140 0141 } 0142 0143 // finally convert to widget coordinated 0144 gtk_tree_view_convert_bin_window_to_widget_coords( 0145 treeView, rect.x, rect.y, 0146 &rect.x, &rect.y ); 0147 0148 0149 } 0150 0151 return rect; 0152 0153 } 0154 0155 //_____________________________________________ 0156 gboolean TreeViewStateData::delayedUpdate( gpointer pointer ) 0157 { 0158 0159 TreeViewStateData& data( *static_cast<TreeViewStateData*>( pointer ) ); 0160 0161 if( data._target ) 0162 { 0163 const GdkRectangle rect( data.dirtyRect() ); 0164 Gtk::gtk_widget_queue_draw( data._target, &rect ); 0165 } 0166 0167 return FALSE; 0168 0169 } 0170 0171 }