xref: /glogg/src/viewtools.cpp (revision c633ced33b4f2c2cf77c0c80a15fa73a7f13ad9f)
1 /*
2  * Copyright (C) 2015 Nicolas Bonnefon and other contributors
3  *
4  * This file is part of glogg.
5  *
6  * glogg is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * glogg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with glogg.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "viewtools.h"
21 
22 #include "log.h"
23 
24 /* ElasticHook */
25 
26 void ElasticHook::move( int value )
27 {
28     static constexpr int MAX_POSITION = 2000;
29 
30     if ( timer_id_ == 0 )
31         timer_id_ = startTimer( TIMER_PERIOD_MS );
32 
33     int resistance = 0;
34     if ( !held_ && ( position_ * value > 0 ) ) // value and resistance have the same sign
35         resistance = position_ / 10;
36 
37     position_ = std::min( position_ + ( value - resistance ), MAX_POSITION );
38 
39     if ( !held_ && ( std::chrono::duration_cast<std::chrono::milliseconds>
40             ( std::chrono::steady_clock::now() - last_update_ ).count() > TIMER_PERIOD_MS ) )
41         decreasePosition();
42 
43     if ( ( ! hooked_ ) && position_ >= hook_threshold_ ) {
44         position_ -= hook_threshold_;
45         hooked_ = true;
46         emit hooked( true );
47     }
48     else if ( hooked_ && position_ <= - hook_threshold_ ) {
49         position_ += hook_threshold_;
50         hooked_ = false;
51         emit hooked( false );
52     }
53 
54     if ( position_ < 0 && !isHooked() )
55         position_ = 0;
56 
57     last_update_ = std::chrono::steady_clock::now();
58 
59     LOG( logDEBUG ) << "ElasticHook::move: new value " << position_;
60 
61     emit lengthChanged();
62 }
63 
64 void ElasticHook::timerEvent( QTimerEvent* event )
65 {
66     if ( !held_ && ( std::chrono::duration_cast<std::chrono::milliseconds>
67             ( std::chrono::steady_clock::now() - last_update_ ).count() > TIMER_PERIOD_MS ) ) {
68         decreasePosition();
69         last_update_ = std::chrono::steady_clock::now();
70     }
71 }
72 
73 void ElasticHook::decreasePosition()
74 {
75     static constexpr int PROP_RATIO = 10;
76 
77     // position_ -= DECREASE_RATE + ( ( position_/SQUARE_RATIO ) * ( position_/SQUARE_RATIO ) );
78     if ( std::abs( position_ ) < DECREASE_RATE ) {
79         position_ = 0;
80         killTimer( timer_id_ );
81         timer_id_ = 0;
82     }
83     else if ( position_ > 0 )
84         position_ -= DECREASE_RATE + ( position_/PROP_RATIO );
85     else if ( position_ < 0 )
86         position_ += DECREASE_RATE - ( position_/PROP_RATIO );
87 
88     LOG( logDEBUG ) << "ElasticHook::timerEvent: new value " << position_;
89 
90     emit lengthChanged();
91 }
92