KiCad PCB EDA Suite
zoom_controller.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
5 * Copyright (C) 2013-2015 CERN
6 * Copyright (C) 2012-2019 KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * @author Tomasz Wlostowski <[email protected]>
9 * @author Maciej Suminski <[email protected]>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, you may find one here:
23 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
24 * or you may search the http://www.gnu.org website for the version 2 license,
25 * or you may write to the Free Software Foundation, Inc.,
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
27 */
28
30
31#include <trace_helpers.h>
32
33#include <wx/log.h>
34
35#include <algorithm>
36
37using namespace KIGFX;
38
39
45{
46public:
48 {
49 return ACCELERATING_ZOOM_CONTROLLER::CLOCK::now();
50 }
51};
52
53
54ACCELERATING_ZOOM_CONTROLLER::ACCELERATING_ZOOM_CONTROLLER(
55 double aScale, const TIMEOUT& aAccTimeout, TIMESTAMP_PROVIDER* aTimestampProv ) :
56 m_accTimeout( aAccTimeout ),
57 m_scale( aScale )
58{
59 if( aTimestampProv )
60 {
61 m_timestampProv = aTimestampProv;
62 }
63 else
64 {
65 m_ownTimestampProv = std::make_unique<SIMPLE_TIMESTAMPER>();
67 }
68
70}
71
72
74{
75 // The minimal step value when changing the current zoom level
76 const double minStep = 1.05;
77
78 const auto timestamp = m_timestampProv->GetTimestamp();
79 auto timeDiff = std::chrono::duration_cast<TIMEOUT>( timestamp - m_prevTimestamp );
80
81 m_prevTimestamp = timestamp;
82
83 wxLogTrace( traceZoomScroll,
84 wxString::Format( "Rot %d, time diff: %ldms", aRotation, (long)timeDiff.count() ) );
85
86 double zoomScale;
87
88 // Set scaling speed depending on scroll wheel event interval
89 if( timeDiff < m_accTimeout
90 && ( (aRotation > 0) == m_prevRotationPositive ) )
91 {
92 zoomScale = ( 2.05 * m_scale / 5.0 ) - timeDiff / m_accTimeout;
93
94 // be sure zoomScale value is significant
95 zoomScale = std::max( zoomScale, minStep );
96
97 if( aRotation < 0 )
98 zoomScale = 1.0 / zoomScale;
99 }
100 else
101 {
102 zoomScale = ( aRotation > 0 ) ? minStep : 1 / minStep;
103 }
104 m_prevRotationPositive = aRotation > 0;
105
106 wxLogTrace( traceZoomScroll, wxString::Format( " Zoom factor: %f", zoomScale ) );
107
108 return zoomScale;
109}
110
111
112CONSTANT_ZOOM_CONTROLLER::CONSTANT_ZOOM_CONTROLLER( double aScale ) : m_scale( aScale )
113{
114}
115
116
118{
119 wxLogTrace( traceZoomScroll, wxString::Format( "Rot %d", aRotation ) );
120
121 aRotation = ( aRotation > 0 ) ? std::min( aRotation, 100 ) : std::max( aRotation, -100 );
122
123 double dscale = aRotation * m_scale;
124
125 double zoom_scale = ( aRotation > 0 ) ? ( 1 + dscale ) : 1 / ( 1 - dscale );
126
127 wxLogTrace( traceZoomScroll, wxString::Format( " Zoom factor: %f", zoom_scale ) );
128
129 return zoom_scale;
130}
131
132// need these until C++17
134
std::chrono::time_point< CLOCK > TIME_PT
The default timeout, after which a another scroll will not be accelerated.
static constexpr TIMEOUT DEFAULT_TIMEOUT
The default minimum step factor for accelerating controller.
std::chrono::milliseconds TIMEOUT
The clock used for the timestamp (guaranteed to be monotonic).
TIME_PT m_prevTimestamp
The timeout value.
bool m_prevRotationPositive
Previous rotation was positive.
double m_scale
A multiplier for the minimum zoom step size.
TIMESTAMP_PROVIDER * m_timestampProv
< The timestamp provider to use (might be provided externally).
double GetScaleForRotation(int aRotation) override
Get the scale factor produced by a given mousewheel rotation.
std::unique_ptr< TIMESTAMP_PROVIDER > m_ownTimestampProv
The timestamp of the previous event.
double GetScaleForRotation(int aRotation) override
A suitable (magic) scale factor for GTK3 systems.
static constexpr double MSW_SCALE
A suitable (magic) scale factor for Windows systems.
double m_scale
< The scale factor set by the constructor.
static constexpr double MAC_SCALE
static constexpr double GTK3_SCALE
A suitable (magic) scale factor for Mac systems.
A very simple timestamper that uses the KIGFX::ACCELERATING_ZOOM_CONTROLLER::CLOCK to provide a times...
ACCELERATING_ZOOM_CONTROLLER::TIME_PT GetTimestamp() override
const wxChar *const traceZoomScroll
Flag to enable debug output of zoom-scrolling calculations in KIGFX::ZOOM_CONTROLLER and derivatives.
The Cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:266
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
wxLogTrace helper definitions.