1 /*
2 * this file is part of the oxygen gtk engine
3 * Copyright (c) 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
4 *
5 * This  library is free  software; you can  redistribute it and/or
6 * modify it  under  the terms  of the  GNU Lesser  General  Public
7 * License  as published  by the Free  Software  Foundation; either
8 * version 2 of the License, or(at your option ) any later version.
9 *
10 * This library is distributed  in the hope that it will be useful,
11 * but  WITHOUT ANY WARRANTY; without even  the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License  along  with  this library;  if not,  write to  the Free
17 * Software Foundation, Inc., 51  Franklin St, Fifth Floor, Boston,
18 * MA 02110-1301, USA.
19 */
20 
21 #include "oxygentabwidgetstatedata.h"
22 #include "../oxygengtkutils.h"
23 #include "../config.h"
24 
25 #include <iostream>
26 
27 namespace Oxygen
28 {
29 
30     //_____________________________________________
31     const int TabWidgetStateData::IndexInvalid = -1;
32 
33     //_____________________________________________
connect(GtkWidget * widget)34     void TabWidgetStateData::connect( GtkWidget* widget )
35     {
36 
37         #if OXYGEN_DEBUG
38         std::cerr << "Oxygen::TabWidgetStateData::connect - " << widget << " (" << G_OBJECT_TYPE_NAME( widget ) << ")" << std::endl;
39         #endif
40 
41         _target = widget;
42 
43         // connect timeLines
44         _current._timeLine.connect( (GSourceFunc)delayedUpdate, this );
45         _previous._timeLine.connect( (GSourceFunc)delayedUpdate, this );
46 
47         // set directions
48         _current._timeLine.setDirection( TimeLine::Forward );
49         _previous._timeLine.setDirection( TimeLine::Backward );
50 
51     }
52 
53     //_____________________________________________
disconnect(GtkWidget * widget)54     void TabWidgetStateData::disconnect( GtkWidget* widget )
55     {
56         #if OXYGEN_DEBUG
57         std::cerr << "Oxygen::TabWidgetStateData::disconnect - " << widget << " (" << G_OBJECT_TYPE_NAME( widget ) << ")" << std::endl;
58         #endif
59 
60         _current._timeLine.disconnect();
61         _current._index = IndexInvalid;
62 
63         _previous._timeLine.disconnect();
64         _previous._index = IndexInvalid;
65 
66         _target = 0L;
67 
68     }
69 
70     //_____________________________________________
updateState(int index,bool state)71     bool TabWidgetStateData::updateState( int index, bool state )
72     {
73         if( state && index != _current._index )
74         {
75 
76             // stop current animation if running
77             if( _current._timeLine.isRunning() ) _current._timeLine.stop();
78 
79             // stop previous animation if running
80             if( _current._index != IndexInvalid )
81             {
82                 if( _previous._timeLine.isRunning() ) _previous._timeLine.stop();
83 
84                 // move current tab index to previous
85                 _previous._index = _current._index;
86                 _previous._timeLine.start();
87             }
88 
89             // assign new index to current and start animation
90             _current._index = index;
91             if( _current._index != IndexInvalid ) _current._timeLine.start();
92 
93             return true;
94 
95         } else if( (!state) && index == _current._index ) {
96 
97             // stop current animation if running
98             if( _current._timeLine.isRunning() ) _current._timeLine.stop();
99 
100             // stop previous animation if running
101             if( _previous._timeLine.isRunning() ) _previous._timeLine.stop();
102 
103             // move current tab index to previous
104             _previous._index = _current._index;
105             if( _previous._index != IndexInvalid ) _previous._timeLine.start();
106 
107             // assign invalid index to current
108             _current._index = IndexInvalid;
109 
110             return true;
111 
112         } else return false;
113 
114     }
115 
116     //_____________________________________________
dirtyRect(void) const117     GdkRectangle TabWidgetStateData::dirtyRect( void ) const
118     {
119 
120         // FIXME: it might be enough to union the rects of the current and previous tab
121         if( GTK_IS_NOTEBOOK( _target ) )
122         {
123 
124             GdkRectangle rect( Gtk::gdk_rectangle() );
125             Gtk::gtk_notebook_get_tabbar_rect( GTK_NOTEBOOK( _target ), &rect );
126 
127             #if OXYGEN_DEBUG
128             std::cerr << "Oxygen::TabWidgetData::dirtyRect - " << rect << std::endl;
129             #endif
130 
131             return rect;
132 
133         } else {
134 
135             return Gtk::gtk_widget_get_allocation( _target );
136 
137         }
138 
139     }
140 
141     //_____________________________________________
delayedUpdate(gpointer pointer)142     gboolean TabWidgetStateData::delayedUpdate( gpointer pointer )
143     {
144 
145         TabWidgetStateData& data( *static_cast<TabWidgetStateData*>( pointer ) );
146 
147         if( !data._target ) return FALSE;
148 
149         const GdkRectangle rect( data.dirtyRect() );
150         Gtk::gtk_widget_queue_draw( data._target, &rect );
151         return FALSE;
152 
153     }
154 
155 }
156