10b05c6eaSNicolas Bonnefon /* 20b05c6eaSNicolas Bonnefon * Copyright (C) 2015 Nicolas Bonnefon and other contributors 30b05c6eaSNicolas Bonnefon * 40b05c6eaSNicolas Bonnefon * This file is part of glogg. 50b05c6eaSNicolas Bonnefon * 60b05c6eaSNicolas Bonnefon * glogg is free software: you can redistribute it and/or modify 70b05c6eaSNicolas Bonnefon * it under the terms of the GNU General Public License as published by 80b05c6eaSNicolas Bonnefon * the Free Software Foundation, either version 3 of the License, or 90b05c6eaSNicolas Bonnefon * (at your option) any later version. 100b05c6eaSNicolas Bonnefon * 110b05c6eaSNicolas Bonnefon * glogg is distributed in the hope that it will be useful, 120b05c6eaSNicolas Bonnefon * but WITHOUT ANY WARRANTY; without even the implied warranty of 130b05c6eaSNicolas Bonnefon * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 140b05c6eaSNicolas Bonnefon * GNU General Public License for more details. 150b05c6eaSNicolas Bonnefon * 160b05c6eaSNicolas Bonnefon * You should have received a copy of the GNU General Public License 170b05c6eaSNicolas Bonnefon * along with glogg. If not, see <http://www.gnu.org/licenses/>. 180b05c6eaSNicolas Bonnefon */ 190b05c6eaSNicolas Bonnefon 200b05c6eaSNicolas Bonnefon #include "viewtools.h" 210b05c6eaSNicolas Bonnefon 220b05c6eaSNicolas Bonnefon #include "log.h" 230b05c6eaSNicolas Bonnefon 240b05c6eaSNicolas Bonnefon /* ElasticHook */ 250b05c6eaSNicolas Bonnefon 260b05c6eaSNicolas Bonnefon void ElasticHook::move( int value ) 270b05c6eaSNicolas Bonnefon { 280b05c6eaSNicolas Bonnefon if ( timer_id_ == 0 ) 290b05c6eaSNicolas Bonnefon timer_id_ = startTimer( TIMER_PERIOD_MS ); 300b05c6eaSNicolas Bonnefon 31a9448ba0SNicolas Bonnefon int resistance = 0; 32*ac6602a5SNicolas Bonnefon if ( position_ * value > 0 ) // value and resistance have the same sign 33a9448ba0SNicolas Bonnefon resistance = position_ / 12; 34a9448ba0SNicolas Bonnefon 35*ac6602a5SNicolas Bonnefon position_ += value - resistance; 360b05c6eaSNicolas Bonnefon 37a9448ba0SNicolas Bonnefon if ( std::chrono::duration_cast<std::chrono::milliseconds> 38a9448ba0SNicolas Bonnefon ( std::chrono::steady_clock::now() - last_update_ ).count() > TIMER_PERIOD_MS ) 39a9448ba0SNicolas Bonnefon decreasePosition(); 40a9448ba0SNicolas Bonnefon 41*ac6602a5SNicolas Bonnefon if ( ( ! hooked_ ) && position_ >= hook_threshold_ ) { 42*ac6602a5SNicolas Bonnefon position_ -= hook_threshold_; 43*ac6602a5SNicolas Bonnefon hooked_ = true; 44*ac6602a5SNicolas Bonnefon emit hooked( true ); 45*ac6602a5SNicolas Bonnefon } 46*ac6602a5SNicolas Bonnefon else if ( hooked_ && position_ <= - hook_threshold_ ) { 47*ac6602a5SNicolas Bonnefon position_ += hook_threshold_; 48*ac6602a5SNicolas Bonnefon hooked_ = false; 49*ac6602a5SNicolas Bonnefon emit hooked( false ); 50*ac6602a5SNicolas Bonnefon } 51*ac6602a5SNicolas Bonnefon 52*ac6602a5SNicolas Bonnefon if ( position_ < 0 && !isHooked() ) 53*ac6602a5SNicolas Bonnefon position_ = 0; 54*ac6602a5SNicolas Bonnefon 55a9448ba0SNicolas Bonnefon last_update_ = std::chrono::steady_clock::now(); 56a9448ba0SNicolas Bonnefon 570b05c6eaSNicolas Bonnefon LOG( logDEBUG ) << "ElasticHook::move: new value " << position_; 580b05c6eaSNicolas Bonnefon 590b05c6eaSNicolas Bonnefon emit lengthChanged(); 600b05c6eaSNicolas Bonnefon } 610b05c6eaSNicolas Bonnefon 620b05c6eaSNicolas Bonnefon void ElasticHook::timerEvent( QTimerEvent* event ) 630b05c6eaSNicolas Bonnefon { 64a9448ba0SNicolas Bonnefon if ( std::chrono::duration_cast<std::chrono::milliseconds> 65a9448ba0SNicolas Bonnefon ( std::chrono::steady_clock::now() - last_update_ ).count() > TIMER_PERIOD_MS ) { 66a9448ba0SNicolas Bonnefon decreasePosition(); 67a9448ba0SNicolas Bonnefon last_update_ = std::chrono::steady_clock::now(); 68a9448ba0SNicolas Bonnefon } 69a9448ba0SNicolas Bonnefon } 700b05c6eaSNicolas Bonnefon 71a9448ba0SNicolas Bonnefon void ElasticHook::decreasePosition() 72a9448ba0SNicolas Bonnefon { 73a9448ba0SNicolas Bonnefon static constexpr int PROP_RATIO = 10; 74a9448ba0SNicolas Bonnefon 75a9448ba0SNicolas Bonnefon // position_ -= DECREASE_RATE + ( ( position_/SQUARE_RATIO ) * ( position_/SQUARE_RATIO ) ); 76*ac6602a5SNicolas Bonnefon if ( std::abs( position_ ) < DECREASE_RATE ) { 770b05c6eaSNicolas Bonnefon position_ = 0; 780b05c6eaSNicolas Bonnefon killTimer( timer_id_ ); 790b05c6eaSNicolas Bonnefon timer_id_ = 0; 800b05c6eaSNicolas Bonnefon } 81*ac6602a5SNicolas Bonnefon else if ( position_ > 0 ) 82*ac6602a5SNicolas Bonnefon position_ -= DECREASE_RATE + ( position_/PROP_RATIO ); 83*ac6602a5SNicolas Bonnefon else if ( position_ < 0 ) 84*ac6602a5SNicolas Bonnefon position_ += DECREASE_RATE - ( position_/PROP_RATIO ); 85*ac6602a5SNicolas Bonnefon 860b05c6eaSNicolas Bonnefon LOG( logDEBUG ) << "ElasticHook::timerEvent: new value " << position_; 870b05c6eaSNicolas Bonnefon 880b05c6eaSNicolas Bonnefon emit lengthChanged(); 890b05c6eaSNicolas Bonnefon } 90