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  const TIMEOUT& aAccTimeout, TIMESTAMP_PROVIDER* aTimestampProv )
56  : m_accTimeout( aAccTimeout )
57 {
58  if( aTimestampProv )
59  {
60  m_timestampProv = aTimestampProv;
61  }
62  else
63  {
64  m_ownTimestampProv = std::make_unique<SIMPLE_TIMESTAMPER>();
66  }
67 
69 }
70 
71 
73 {
74  // The minimal step value when changing the current zoom level
75  const double zoomLevelScale = 1.2;
76 
77  const auto timestamp = m_timestampProv->GetTimestamp();
78  auto timeDiff = std::chrono::duration_cast<TIMEOUT>( timestamp - m_lastTimestamp );
79 
80  m_lastTimestamp = timestamp;
81 
82  wxLogTrace( traceZoomScroll,
83  wxString::Format( "Rot %d, time diff: %ldms", aRotation, (long)timeDiff.count() ) );
84 
85  double zoomScale;
86 
87  // Set scaling speed depending on scroll wheel event interval
88  if( timeDiff < m_accTimeout )
89  {
90  zoomScale = 2.05 - timeDiff / m_accTimeout;
91 
92  // be sure zoomScale value is significant
93  zoomScale = std::max( zoomScale, zoomLevelScale );
94 
95  if( aRotation < 0 )
96  zoomScale = 1.0 / zoomScale;
97  }
98  else
99  {
100  zoomScale = ( aRotation > 0 ) ? zoomLevelScale : 1 / zoomLevelScale;
101  }
102 
103  wxLogTrace( traceZoomScroll, wxString::Format( " Zoom factor: %f", zoomScale ) );
104 
105  return zoomScale;
106 }
107 
108 
109 CONSTANT_ZOOM_CONTROLLER::CONSTANT_ZOOM_CONTROLLER( double aScale ) : m_scale( aScale )
110 {
111 }
112 
113 
115 {
116  wxLogTrace( traceZoomScroll, wxString::Format( "Rot %d", aRotation ) );
117 
118  aRotation = ( aRotation > 0 ) ? std::min( aRotation, 100 ) : std::max( aRotation, -100 );
119 
120  double dscale = aRotation * m_scale;
121 
122  double zoom_scale = ( aRotation > 0 ) ? ( 1 + dscale ) : 1 / ( 1 - dscale );
123 
124  wxLogTrace( traceZoomScroll, wxString::Format( " Zoom factor: %f", zoom_scale ) );
125 
126  return zoom_scale;
127 }
128 
129 // need these until C++17
131 
132 constexpr double CONSTANT_ZOOM_CONTROLLER::MAC_SCALE;
133 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: class_module.h:58
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.
TIMESTAMP_PROVIDER * m_timestampProv
The timestamp provider to use (might be provided externally)
ACCELERATING_ZOOM_CONTROLLER(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
#define max(a, b)
Definition: auxiliary.h:86
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
#define min(a, b)
Definition: auxiliary.h:85