/* * Copyright (C) 2015 Nicolas Bonnefon and other contributors * * This file is part of glogg. * * glogg is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * glogg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with glogg. If not, see . */ #include "viewtools.h" #include "log.h" /* ElasticHook */ void ElasticHook::move( int value ) { static constexpr int MAX_POSITION = 2000; if ( timer_id_ == 0 ) timer_id_ = startTimer( TIMER_PERIOD_MS ); int resistance = 0; if ( !held_ && ( position_ * value > 0 ) ) // value and resistance have the same sign resistance = position_ / 10; position_ = std::min( position_ + ( value - resistance ), MAX_POSITION ); if ( !held_ && ( std::chrono::duration_cast ( std::chrono::steady_clock::now() - last_update_ ).count() > TIMER_PERIOD_MS ) ) decreasePosition(); if ( ( ! hooked_ ) && position_ >= hook_threshold_ ) { position_ -= hook_threshold_; hooked_ = true; emit hooked( true ); } else if ( hooked_ && position_ <= - hook_threshold_ ) { position_ += hook_threshold_; hooked_ = false; emit hooked( false ); } if ( position_ < 0 && !isHooked() ) position_ = 0; last_update_ = std::chrono::steady_clock::now(); LOG( logDEBUG ) << "ElasticHook::move: new value " << position_; emit lengthChanged(); } void ElasticHook::timerEvent( QTimerEvent* event ) { if ( !held_ && ( std::chrono::duration_cast ( std::chrono::steady_clock::now() - last_update_ ).count() > TIMER_PERIOD_MS ) ) { decreasePosition(); last_update_ = std::chrono::steady_clock::now(); } } void ElasticHook::decreasePosition() { static constexpr int PROP_RATIO = 10; // position_ -= DECREASE_RATE + ( ( position_/SQUARE_RATIO ) * ( position_/SQUARE_RATIO ) ); if ( std::abs( position_ ) < DECREASE_RATE ) { position_ = 0; killTimer( timer_id_ ); timer_id_ = 0; } else if ( position_ > 0 ) position_ -= DECREASE_RATE + ( position_/PROP_RATIO ); else if ( position_ < 0 ) position_ += DECREASE_RATE - ( position_/PROP_RATIO ); LOG( logDEBUG ) << "ElasticHook::timerEvent: new value " << position_; emit lengthChanged(); }