1
//////////////////////////////////////////////////////////////////////////////
2
// oxygentoolbardata.cpp
3
// stores event filters and maps widgets to timelines for animations
6
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
8
// Permission is hereby granted, free of charge, to any person obtaining a copy
9
// of this software and associated documentation files (the "Software"), to
10
// deal in the Software without restriction, including without limitation the
11
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12
// sell copies of the Software, and to permit persons to whom the Software is
13
// furnished to do so, subject to the following conditions:
15
// The above copyright notice and this permission notice shall be included in
16
// all copies or substantial portions of the Software.
18
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25
//////////////////////////////////////////////////////////////////////////////
27
#include "oxygentoolbardata.h"
28
#include "oxygentoolbardata.moc"
30
#include <QtGui/QToolButton>
35
//________________________________________________________________________
36
ToolBarData::ToolBarData( QObject* parent, QWidget* target, int duration ):
37
AnimationData( parent, target ),
44
target->installEventFilter( this );
46
_animation = new Animation( duration, this );
47
animation().data()->setDirection( Animation::Forward );
48
animation().data()->setStartValue( 0.0 );
49
animation().data()->setEndValue( 1.0 );
50
animation().data()->setTargetObject( this );
51
animation().data()->setPropertyName( "opacity" );
54
_progressAnimation = new Animation( duration, this );
55
progressAnimation().data()->setDirection( Animation::Forward );
56
progressAnimation().data()->setStartValue( 0 );
57
progressAnimation().data()->setEndValue( 1 );
58
progressAnimation().data()->setTargetObject( this );
59
progressAnimation().data()->setPropertyName( "progress" );
60
progressAnimation().data()->setEasingCurve( QEasingCurve::Linear );
62
// add all children widgets to event handler
63
foreach( QObject* child, target->children() )
64
{ if( qobject_cast<QToolButton*>( child ) ) childAddedEvent( child ); }
68
//______________________________________________
69
bool ToolBarData::eventFilter( QObject* object, QEvent* event )
73
const QObject *targetData = target().data();
74
if( object == targetData )
77
switch( event->type() )
84
object->event( event );
90
case QEvent::ChildAdded:
93
// add children even in disabled case, to make sure they
94
// are properly registered when engine is enabled
95
QChildEvent* childEvent( static_cast<QChildEvent*>( event ) );
96
childAddedEvent( childEvent->child() );
104
} else if( object->parent() == targetData ) {
106
if( !enabled() ) return false;
108
switch( event->type() )
111
case QEvent::HoverEnter:
112
childEnterEvent( object );
115
case QEvent::HoverLeave:
116
if( currentObject() && !_timer.isActive() ) _timer.start( 100, this );
130
//____________________________________________________________
131
void ToolBarData::updateAnimatedRect( void )
134
// check rect validity
135
if( currentRect().isNull() || previousRect().isNull() )
137
_animatedRect = QRect();
141
// compute rect located 'between' previous and current
142
_animatedRect.setLeft( previousRect().left() + progress()*(currentRect().left() - previousRect().left()) );
143
_animatedRect.setRight( previousRect().right() + progress()*(currentRect().right() - previousRect().right()) );
144
_animatedRect.setTop( previousRect().top() + progress()*(currentRect().top() - previousRect().top()) );
145
_animatedRect.setBottom( previousRect().bottom() + progress()*(currentRect().bottom() - previousRect().bottom()) );
153
//________________________________________________________________________
154
void ToolBarData::enterEvent( const QObject* )
157
if( _timer.isActive() ) _timer.stop();
158
if( animation().data()->isRunning() ) animation().data()->stop();
159
if( progressAnimation().data()->isRunning() ) progressAnimation().data()->stop();
168
//________________________________________________________________________
169
void ToolBarData::leaveEvent( const QObject* )
172
if( progressAnimation().data()->isRunning() ) progressAnimation().data()->stop();
173
if( animation().data()->isRunning() ) animation().data()->stop();
177
if( currentObject() )
180
clearCurrentObject();
181
animation().data()->setDirection( Animation::Backward );
182
animation().data()->start();
190
//________________________________________________________________________
191
void ToolBarData::childEnterEvent( const QObject* object )
194
if( object == currentObject() ) return;
196
const QToolButton* local = qobject_cast<const QToolButton*>( object );
198
// check if current position match another action
199
if( local && local->isEnabled() )
202
if( _timer.isActive() ) _timer.stop();
205
QRect activeRect( local->rect().translated( local->mapToParent( QPoint(0,0) ) ) );
207
// update previous rect if the current action is valid
208
if( currentObject() )
211
if( !progressAnimation().data()->isRunning() )
214
setPreviousRect( currentRect() );
216
} else if( progress() < 1 && currentRect().isValid() && previousRect().isValid() ) {
218
// re-calculate previous rect so that animatedRect
219
// is unchanged after currentRect is updated
220
// this prevents from having jumps in the animation
221
qreal ratio = progress()/(1.0-progress());
222
_previousRect.adjust(
223
ratio*( currentRect().left() - activeRect.left() ),
224
ratio*( currentRect().top() - activeRect.top() ),
225
ratio*( currentRect().right() - activeRect.right() ),
226
ratio*( currentRect().bottom() - activeRect.bottom() ) );
230
// update current action
231
setCurrentObject( local );
232
setCurrentRect( activeRect );
233
if( animation().data()->isRunning() ) animation().data()->stop();
234
if( !progressAnimation().data()->isRunning() ) progressAnimation().data()->start();
238
setCurrentObject( local );
239
setCurrentRect( activeRect );
244
if( animation().data()->isRunning() ) animation().data()->stop();
245
if( !progressAnimation().data()->isRunning() ) progressAnimation().data()->start();
249
setPreviousRect( activeRect );
251
if( progressAnimation().data()->isRunning() ) progressAnimation().data()->stop();
252
animation().data()->setDirection( Animation::Forward );
253
if( !animation().data()->isRunning() ) animation().data()->start();
258
} else if( currentObject() ) {
260
if( !_timer.isActive() ) _timer.start( 100, this );
268
//___________________________________________________________________
269
void ToolBarData::childAddedEvent( QObject* object )
271
QWidget* widget( qobject_cast<QWidget*>( object ) );
272
if( !widget ) return;
275
connect( animation().data(), SIGNAL( valueChanged( const QVariant& ) ), widget, SLOT( update() ), Qt::UniqueConnection );
276
connect( progressAnimation().data(), SIGNAL( valueChanged( const QVariant& ) ), widget, SLOT( update() ), Qt::UniqueConnection );
279
widget->removeEventFilter( this );
280
widget->installEventFilter( this );
283
//___________________________________________________________
284
void ToolBarData::timerEvent( QTimerEvent *event )
287
if( event->timerId() != _timer.timerId() ) return AnimationData::timerEvent( event );
289
leaveEvent( target().data() );