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 <tomasz.wlostowski@cern.ch>
9  * @author Maciej Suminski <maciej.suminski@cern.ch>
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 
29 #include <view/zoom_controller.h>
30 
31 #include <trace_helpers.h>
32 
33 #include <wx/log.h>
34 
35 #include <algorithm>
36 
37 using namespace KIGFX;
38 
39 
45 {
46 public:
48  {
49  return ACCELERATING_ZOOM_CONTROLLER::CLOCK::now();
50  }
51 };
52 
53 
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_lastTimestamp );
80 
81  m_lastTimestamp = 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  {
91  zoomScale = ( 2.05 * m_scale / 5.0 ) - timeDiff / m_accTimeout;
92 
93  // be sure zoomScale value is significant
94  zoomScale = std::max( zoomScale, minStep );
95 
96  if( aRotation < 0 )
97  zoomScale = 1.0 / zoomScale;
98  }
99  else
100  {
101  zoomScale = ( aRotation > 0 ) ? minStep : 1 / minStep;
102  }
103 
104  wxLogTrace( traceZoomScroll, wxString::Format( " Zoom factor: %f", zoomScale ) );
105 
106  return zoomScale;
107 }
108 
109 
110 CONSTANT_ZOOM_CONTROLLER::CONSTANT_ZOOM_CONTROLLER( double aScale ) : m_scale( aScale )
111 {
112 }
113 
114 
116 {
117  wxLogTrace( traceZoomScroll, wxString::Format( "Rot %d", aRotation ) );
118 
119  aRotation = ( aRotation > 0 ) ? std::min( aRotation, 100 ) : std::max( aRotation, -100 );
120 
121  double dscale = aRotation * m_scale;
122 
123  double zoom_scale = ( aRotation > 0 ) ? ( 1 + dscale ) : 1 / ( 1 - dscale );
124 
125  wxLogTrace( traceZoomScroll, wxString::Format( " Zoom factor: %f", zoom_scale ) );
126 
127  return zoom_scale;
128 }
129 
130 // need these until C++17
132 
133 constexpr double CONSTANT_ZOOM_CONTROLLER::MAC_SCALE;
134 constexpr double CONSTANT_ZOOM_CONTROLLER::GTK3_SCALE;
double GetScaleForRotation(int aRotation) override
Gets the scale factor produced by a given mousewheel rotation.
const wxChar *const traceZoomScroll
Flag to enable debug output of zoom-scrolling calculations in KIGFX::ZOOM_CONTROLLER and derivatives.
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:175
std::chrono::time_point< CLOCK > TIME_PT
The type of the time stamps.
TIME_PT m_lastTimestamp
The timestamp of the last event.
static constexpr TIMEOUT DEFAULT_TIMEOUT
The default timeout, after which a another scroll will not be accelerated.
double m_scale
A multiplier for the minimum zoom step size.
TIMESTAMP_PROVIDER * m_timestampProv
The timestamp provider to use (might be provided externally)
ACCELERATING_ZOOM_CONTROLLER(double aScale=DEFAULT_ACCELERATION_SCALE, const TIMEOUT &aAccTimeout=DEFAULT_TIMEOUT, TIMESTAMP_PROVIDER *aTimestampProv=nullptr)
static constexpr double GTK3_SCALE
A suitable (magic) scale factor for GTK3 systems.
std::chrono::milliseconds TIMEOUT
The type of the acceleration timeout.
double m_scale
The scale factor set by the constructor.
static constexpr double MAC_SCALE
A suitable (magic) scale factor for Mac systems.
wxLogTrace helper definitions.
double GetScaleForRotation(int aRotation) override
Gets the scale factor produced by a given mousewheel rotation.
TIMEOUT m_accTimeout
The timeout value.
A very simple timestamper that uses the KIGFX::ACCELERATING_ZOOM_CONTROLLER::CLOCK to provide a times...
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
std::unique_ptr< TIMESTAMP_PROVIDER > m_ownTimestampProv
Any provider owned by this class (the default one, if used)
ACCELERATING_ZOOM_CONTROLLER::TIME_PT GetTimestamp() override