Audacity  3.0.3
ZoomHandle.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3 Audacity: A Digital Audio Editor
4 
5 ZoomHandle.cpp
6 
7 Paul Licameli split from TrackPanel.cpp
8 
9 **********************************************************************/
10 
11 
12 #include "ZoomHandle.h"
13 
14 #include <algorithm>
15 
16 #include <wx/dc.h>
17 #include <wx/event.h>
18 #include <wx/gdicmn.h>
19 
20 #include "../../HitTestResult.h"
21 #include "../../RefreshCode.h"
22 #include "../../TrackArtist.h"
23 #include "../../TrackPanelDrawingContext.h"
24 #include "../../TrackPanelMouseEvent.h"
25 #include "../../ViewInfo.h"
26 #include "../../../images/Cursors.h"
27 
38 
40 {}
41 
43  (const wxMouseState &state, const AudacityProject *WXUNUSED(pProject))
44 {
45  static auto zoomInCursor =
46  ::MakeCursor(wxCURSOR_MAGNIFIER, ZoomInCursorXpm, 19, 15);
47  static auto zoomOutCursor =
48  ::MakeCursor(wxCURSOR_MAGNIFIER, ZoomOutCursorXpm, 19, 15);
49  TranslatableString message;
50  // TODO: Why not mention middle click to zoom normal on Windows too?
51 #if defined( __WXMAC__ )
52  message = XO("Click to Zoom In, Shift-Click to Zoom Out");
53 #elif defined( __WXMSW__ )
54  message = XO("Drag to Zoom Into Region, Right-Click to Zoom Out");
55 #elif defined( __WXGTK__ )
56  message = XO("Left=Zoom In, Right=Zoom Out, Middle=Normal");
57 #endif
58  return {
59  message,
60  (state.ShiftDown() ? &*zoomOutCursor : &*zoomInCursor)
61  };
62 }
63 
65 (std::weak_ptr<ZoomHandle> &holder)
66 {
67  auto result = std::make_shared<ZoomHandle>();
68  result = AssignUIHandlePtr(holder, result);
69  return result;
70 }
71 
73 (std::weak_ptr<ZoomHandle> &holder,
74  const wxMouseState &state)
75 {
76  if (state.ButtonIsDown(wxMOUSE_BTN_RIGHT))
77  return HitAnywhere(holder);
78  else
79  return {};
80 }
81 
83 {
84 }
85 
88 {
89  const wxMouseEvent &event = evt.event;
90  if (event.ButtonDown() || event.LeftDClick()) {
92  mZoomStart = event.m_x;
93  mZoomEnd = event.m_x;
94  mRect = evt.rect;
95  }
97 }
98 
101 {
102  const wxMouseEvent &event = evt.event;
103  const int left = mRect.GetLeft();
104  const int right = mRect.GetRight();
105 
106  mZoomEnd = event.m_x;
107 
108  if (event.m_x < left) {
109  mZoomEnd = left;
110  }
111  else if (event.m_x > right) {
112  mZoomEnd = right;
113  }
114 
115  // Refresh tracks ALWAYS. Even if IsDragZooming() becomes false, make the
116  // dashed lines disappear. -- PRL
117  return RefreshCode::RefreshAll; // (IsDragZooming() ? RefreshAllTracks : RefreshNone),
118 }
119 
121 (const TrackPanelMouseState &st, AudacityProject *pProject)
122 {
123  return HitPreview(st.state, pProject);
124 }
125 
127 (const TrackPanelMouseEvent &evt, AudacityProject *pProject,
128  wxWindow *)
129 {
130  const wxMouseEvent &event = evt.event;
131  auto &viewInfo = ViewInfo::Get( *pProject );
132  if (mZoomEnd < mZoomStart)
134 
135  const int trackLeftEdge = mRect.x;
136  if (IsDragZooming())
137  {
140  double left = viewInfo.PositionToTime(mZoomStart, trackLeftEdge);
141  double right = viewInfo.PositionToTime(mZoomEnd, trackLeftEdge);
142 
143  double multiplier =
144  (viewInfo.PositionToTime(mRect.width) - viewInfo.PositionToTime(0)) /
145  (right - left);
146  if (event.ShiftDown())
147  multiplier = 1.0 / multiplier;
148 
149  viewInfo.ZoomBy(multiplier);
150 
151  viewInfo.h = left;
152  }
153  else
154  {
158  const double center_h =
159  viewInfo.PositionToTime(event.m_x, trackLeftEdge);
160 
161  const double multiplier =
162  (event.RightUp() || event.RightDClick() || event.ShiftDown())
163  ? 0.5 : 2.0;
164  viewInfo.ZoomBy(multiplier);
165 
166  if (event.MiddleUp() || event.MiddleDClick())
167  viewInfo.SetZoom(ZoomInfo::GetDefaultZoom()); // AS: Reset zoom.
168 
169  const double new_center_h =
170  viewInfo.PositionToTime(event.m_x, trackLeftEdge);
171 
172  viewInfo.h += (center_h - new_center_h);
173  }
174 
175  mZoomEnd = mZoomStart = 0;
176 
177  using namespace RefreshCode;
178  return RefreshAll | FixScrollbars;
179 }
180 
182 {
183  // Cancel is implemented! And there is no initial state to restore,
184  // so just return a code.
186 }
187 
189  TrackPanelDrawingContext &context,
190  const wxRect &rect, unsigned iPass )
191 {
192  if ( iPass == TrackArtist::PassZooming &&
193  // PRL: Draw dashed lines only if we would zoom in
194  // for button up.
195  IsDragZooming() ) {
196  auto &dc = context.dc;
197  dc.SetBrush(*wxTRANSPARENT_BRUSH);
198  dc.SetPen(*wxBLACK_DASHED_PEN);
199  // Make the top and bottom of the dashed rectangle disappear out of
200  // bounds, so that you only see vertical dashed lines.
201  dc.DrawRectangle( {
203  rect.y - 1,
204  1 + abs(mZoomEnd - mZoomStart),
205  rect.height + 2
206  } );
207  }
208 }
209 
212  const wxRect &rect, const wxRect &panelRect, unsigned iPass )
213 {
214  if ( iPass == TrackArtist::PassZooming )
215  return MaximizeHeight( rect, panelRect );
216  else
217  return rect;
218 }
219 
221 {
222  const int DragThreshold = 3;// Anything over 3 pixels is a drag, else a click.
223  return (abs(mZoomEnd - mZoomStart) > DragThreshold);
224 }
ZoomHandle::IsDragZooming
bool IsDragZooming() const
Definition: ZoomHandle.cpp:220
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
RefreshCode::FixScrollbars
@ FixScrollbars
Definition: RefreshCode.h:27
ViewInfo::Get
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:156
ZoomHandle::Draw
void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass) override
Definition: ZoomHandle.cpp:188
TrackPanelMouseEvent::rect
const wxRect & rect
Definition: TrackPanelMouseEvent.h:59
RefreshCode::RefreshAll
@ RefreshAll
Definition: RefreshCode.h:26
RefreshCode::RefreshNone
@ RefreshNone
Definition: RefreshCode.h:21
ZoomHandle::~ZoomHandle
virtual ~ZoomHandle()
Definition: ZoomHandle.cpp:82
ZoomInfo::GetDefaultZoom
static double GetDefaultZoom()
Definition: ZoomInfo.h:121
ZoomHandle::mZoomEnd
int mZoomEnd
Definition: ZoomHandle.h:66
TrackPanelDrawingContext
Definition: TrackPanelDrawingContext.h:22
MakeCursor
std::unique_ptr< wxCursor > MakeCursor(int WXUNUSED(CursorId), const char *const pXpm[36], int HotX, int HotY)
Definition: TrackPanel.cpp:176
ZoomHandle::Click
Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
Definition: ZoomHandle.cpp:87
XO
#define XO(s)
Definition: Internat.h:31
TrackPanelDrawingContext::dc
wxDC & dc
Definition: TrackPanelDrawingContext.h:23
ZoomHandle.h
ZoomHandle::Drag
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
Definition: ZoomHandle.cpp:100
ZoomHandle::Preview
HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *pProject) override
Definition: ZoomHandle.cpp:121
ZoomHandle::HitAnywhere
static UIHandlePtr HitAnywhere(std::weak_ptr< ZoomHandle > &holder)
Definition: ZoomHandle.cpp:65
ZoomHandle::Cancel
Result Cancel(AudacityProject *pProject) override
Definition: ZoomHandle.cpp:181
ZoomHandle::HitPreview
static HitTestPreview HitPreview(const wxMouseState &state, const AudacityProject *pProject)
Definition: ZoomHandle.cpp:43
DragThreshold
const int DragThreshold
Definition: TrackPanel.h:58
ZoomHandle::Release
Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
Definition: ZoomHandle.cpp:127
ZoomHandle::mZoomStart
int mZoomStart
Definition: ZoomHandle.h:66
UIHandle::Result
unsigned Result
Definition: UIHandle.h:37
ZoomHandle::HitTest
static UIHandlePtr HitTest(std::weak_ptr< ZoomHandle > &holder, const wxMouseState &state)
Definition: ZoomHandle.cpp:73
UIHandlePtr
std::shared_ptr< UIHandle > UIHandlePtr
Definition: CellularPanel.h:28
HitTestPreview
Definition: HitTestResult.h:20
TrackPanelDrawable::MaximizeHeight
static wxRect MaximizeHeight(const wxRect &rect, const wxRect &panelRect)
Definition: TrackPanelDrawable.h:52
anonymous_namespace{NoteTrack.cpp}::swap
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:735
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
ZoomHandle::DrawingArea
wxRect DrawingArea(TrackPanelDrawingContext &, const wxRect &rect, const wxRect &panelRect, unsigned iPass) override
Definition: ZoomHandle.cpp:210
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:113
ZoomHandle::mRect
wxRect mRect
Definition: ZoomHandle.h:67
TrackPanelMouseEvent
Definition: TrackPanelMouseEvent.h:46
TrackPanelMouseState
Definition: TrackPanelMouseEvent.h:28
TrackArtist::PassZooming
@ PassZooming
Definition: TrackArtist.h:79
AssignUIHandlePtr
std::shared_ptr< Subclass > AssignUIHandlePtr(std::weak_ptr< Subclass > &holder, const std::shared_ptr< Subclass > &pNew)
Definition: UIHandle.h:145
RefreshCode
Namespace containing an enum 'what to do on a refresh?'.
Definition: RefreshCode.h:16
TrackPanelMouseEvent::event
wxMouseEvent & event
Definition: TrackPanelMouseEvent.h:58
TrackPanelMouseState::state
wxMouseState & state
Definition: TrackPanelMouseEvent.h:38
ZoomHandle::ZoomHandle
ZoomHandle()
Definition: ZoomHandle.cpp:39