Audacity  2.2.2
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 #include "../../Audacity.h"
12 #include "ZoomHandle.h"
13 
14 #include <algorithm>
15 #include "../../MemoryX.h"
16 
17 #include <wx/dc.h>
18 #include <wx/event.h>
19 #include <wx/gdicmn.h>
20 
21 #include "../../HitTestResult.h"
22 #include "../../Project.h"
23 #include "../../RefreshCode.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  wxString message;
50  // TODO: Why not mention middle click to zoom normal on Windows too?
51 #if defined( __WXMAC__ )
52  message = _("Click to Zoom In, Shift-Click to Zoom Out");
53 #elif defined( __WXMSW__ )
54  message = _("Drag to Zoom Into Region, Right-Click to Zoom Out");
55 #elif defined( __WXGTK__ )
56  message = _("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, const 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  ViewInfo &viewInfo = pProject->GetViewInfo();
132  if (mZoomEnd < mZoomStart)
133  std::swap(mZoomStart, mZoomEnd);
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 (DrawingPass pass, wxDC * dc, const wxRegion &, const wxRect &panelRect)
190 {
191  if (pass == Cells) {
192  // PRL: Draw dashed lines only if we would zoom in
193  // for button up.
194  if (!IsDragZooming())
195  return;
196 
197  wxRect rect;
198 
199  dc->SetBrush(*wxTRANSPARENT_BRUSH);
200  dc->SetPen(*wxBLACK_DASHED_PEN);
201 
202  rect.x = std::min(mZoomStart, mZoomEnd);
203  rect.width = 1 + abs(mZoomEnd - mZoomStart);
204  rect.y = -1;
205  rect.height = panelRect.height + 2;
206 
207  dc->DrawRectangle(rect);
208  }
209 }
210 
212 {
213  const int DragThreshold = 3;// Anything over 3 pixels is a drag, else a click.
214  return (abs(mZoomEnd - mZoomStart) > DragThreshold);
215 }
void SetZoom(double pixelsPerSecond)
Definition: ViewInfo.cpp:94
virtual ~ZoomHandle()
Definition: ZoomHandle.cpp:82
static UIHandlePtr HitAnywhere(std::weak_ptr< ZoomHandle > &holder)
Definition: ZoomHandle.cpp:65
ViewInfo is used mainly to hold the zooming, selection and scroll information. It also has some statu...
Definition: ViewInfo.h:141
const int DragThreshold
Definition: TrackPanel.h:242
static UIHandlePtr HitTest(std::weak_ptr< ZoomHandle > &holder, const wxMouseState &state)
Definition: ZoomHandle.cpp:73
Result Cancel(AudacityProject *pProject) override
Definition: ZoomHandle.cpp:181
HitTestPreview Preview(const TrackPanelMouseState &state, const AudacityProject *pProject) override
Definition: ZoomHandle.cpp:121
double PositionToTime(wxInt64 position, wxInt64 origin=0, bool ignoreFisheye=false) const
Definition: ViewInfo.cpp:49
double h
Definition: ViewInfo.h:47
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:176
unsigned Result
Definition: UIHandle.h:37
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
Definition: ZoomHandle.cpp:100
Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
Definition: ZoomHandle.cpp:87
int min(int a, int b)
void DrawExtras(DrawingPass pass, wxDC *dc, const wxRegion &updateRegion, const wxRect &panelRect) override
Definition: ZoomHandle.cpp:189
std::shared_ptr< UIHandle > UIHandlePtr
Definition: TrackPanel.h:59
bool IsDragZooming() const
Definition: ZoomHandle.cpp:211
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
int mZoomStart
Definition: ZoomHandle.h:62
int mZoomEnd
Definition: ZoomHandle.h:62
static double GetDefaultZoom()
Definition: ViewInfo.h:85
Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
Definition: ZoomHandle.cpp:127
std::unique_ptr< wxCursor > MakeCursor(int WXUNUSED(CursorId), const char *const pXpm[36], int HotX, int HotY)
Definition: TrackPanel.cpp:274
void ZoomBy(double multiplier)
Definition: ViewInfo.cpp:112
const ViewInfo & GetViewInfo() const
Definition: Project.h:207
std::shared_ptr< Subclass > AssignUIHandlePtr(std::weak_ptr< Subclass > &holder, const std::shared_ptr< Subclass > &pNew)
Definition: UIHandle.h:162
static HitTestPreview HitPreview(const wxMouseState &state, const AudacityProject *pProject)
Definition: ZoomHandle.cpp:43
DrawingPass
Definition: UIHandle.h:43