mirror of
https://github.com/cookiengineer/audacity
synced 2025-11-14 17:14:07 +01:00
TrackPanel no longer implements the zoom tool...
... Also changed the behavior of drawing of dashed lines: make them disappear when they approach close enough that right-up will zoom out, not in.
This commit is contained in:
committed by
Paul Licameli
parent
cba51e1bf8
commit
85c03bb3b3
@@ -9,6 +9,7 @@ Paul Licameli split from TrackPanel.cpp
|
||||
**********************************************************************/
|
||||
|
||||
#include "../../Track.h"
|
||||
#include "../../TrackPanelMouseEvent.h"
|
||||
#include "TrackControls.h"
|
||||
#include "TrackVRulerControls.h"
|
||||
|
||||
@@ -16,8 +17,10 @@ Paul Licameli split from TrackPanel.cpp
|
||||
#include "../../Project.h"
|
||||
#include "../../toolbars/ToolsToolBar.h"
|
||||
|
||||
#include "ZoomHandle.h"
|
||||
|
||||
HitTestResult Track::HitTest
|
||||
(const TrackPanelMouseEvent &,
|
||||
(const TrackPanelMouseEvent &event,
|
||||
const AudacityProject *pProject)
|
||||
{
|
||||
const ToolsToolBar * pTtb = pProject->GetToolsToolBar();
|
||||
@@ -25,10 +28,12 @@ HitTestResult Track::HitTest
|
||||
const bool isMultiTool = pTtb->IsDown(multiTool);
|
||||
if (!isMultiTool) {
|
||||
switch (pTtb->GetCurrentTool()) {
|
||||
case zoomTool:
|
||||
return ZoomHandle::HitAnywhere(event.event, pProject);
|
||||
|
||||
case selectTool:
|
||||
case envelopeTool:
|
||||
case drawTool:
|
||||
case zoomTool:
|
||||
case slideTool:
|
||||
default:
|
||||
// cases not yet implemented
|
||||
@@ -40,9 +45,8 @@ HitTestResult Track::HitTest
|
||||
// Replicate some of the logic of TrackPanel::DetermineToolToUse
|
||||
HitTestResult result;
|
||||
|
||||
if (isMultiTool) {
|
||||
// To do: special hit tests
|
||||
}
|
||||
if (isMultiTool)
|
||||
result = ZoomHandle::HitTest(event.event, pProject);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
212
src/tracks/ui/ZoomHandle.cpp
Normal file
212
src/tracks/ui/ZoomHandle.cpp
Normal file
@@ -0,0 +1,212 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
ZoomHandle.cpp
|
||||
|
||||
Paul Licameli split from TrackPanel.cpp
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "../../Audacity.h"
|
||||
#include "ZoomHandle.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "../../MemoryX.h"
|
||||
|
||||
#include <wx/dc.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/gdicmn.h>
|
||||
|
||||
#include "../../HitTestResult.h"
|
||||
#include "../../Project.h"
|
||||
#include "../../RefreshCode.h"
|
||||
#include "../../TrackPanelMouseEvent.h"
|
||||
#include "../../toolbars/ToolsToolBar.h"
|
||||
#include "../../ViewInfo.h"
|
||||
#include "../../../images/Cursors.h"
|
||||
|
||||
/// This class takes care of our different zoom
|
||||
/// possibilities. It is possible for a user to just
|
||||
/// "zoom in" or "zoom out," but it is also possible
|
||||
/// for a user to drag and select an area that he
|
||||
/// or she wants to be zoomed in on. We use mZoomStart
|
||||
/// and mZoomEnd to track the beginning and end of such
|
||||
/// a zoom area. Note that the ViewInfo
|
||||
/// actually keeps track of our zoom constant,
|
||||
/// so we achieve zooming by altering the zoom constant
|
||||
/// and forcing a refresh.
|
||||
|
||||
ZoomHandle::ZoomHandle()
|
||||
{
|
||||
}
|
||||
|
||||
ZoomHandle &ZoomHandle::Instance()
|
||||
{
|
||||
static ZoomHandle instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
HitTestPreview ZoomHandle::HitPreview
|
||||
(const wxMouseEvent &event, const AudacityProject *pProject)
|
||||
{
|
||||
static auto zoomInCursor =
|
||||
::MakeCursor(wxCURSOR_MAGNIFIER, ZoomInCursorXpm, 19, 15);
|
||||
static auto zoomOutCursor =
|
||||
::MakeCursor(wxCURSOR_MAGNIFIER, ZoomOutCursorXpm, 19, 15);
|
||||
const ToolsToolBar *const ttb = pProject->GetToolsToolBar();
|
||||
return {
|
||||
ttb->GetMessageForTool(zoomTool),
|
||||
(event.ShiftDown() ? &*zoomOutCursor : &*zoomInCursor)
|
||||
};
|
||||
}
|
||||
|
||||
HitTestResult ZoomHandle::HitAnywhere
|
||||
(const wxMouseEvent &event, const AudacityProject *pProject)
|
||||
{
|
||||
return { HitPreview(event, pProject), &Instance() };
|
||||
}
|
||||
|
||||
HitTestResult ZoomHandle::HitTest
|
||||
(const wxMouseEvent &event, const AudacityProject *pProject)
|
||||
{
|
||||
if (event.ButtonIsDown(wxMOUSE_BTN_RIGHT) || event.RightUp())
|
||||
return HitAnywhere(event, pProject);
|
||||
else
|
||||
return {};
|
||||
}
|
||||
|
||||
ZoomHandle::~ZoomHandle()
|
||||
{
|
||||
}
|
||||
|
||||
UIHandle::Result ZoomHandle::Click
|
||||
(const TrackPanelMouseEvent &evt, AudacityProject *)
|
||||
{
|
||||
const wxMouseEvent &event = evt.event;
|
||||
if (event.ButtonDown() || event.LeftDClick()) {
|
||||
/// Zoom button down, record the position.
|
||||
mZoomStart = event.m_x;
|
||||
mZoomEnd = event.m_x;
|
||||
mRect = evt.rect;
|
||||
}
|
||||
return RefreshCode::RefreshNone;
|
||||
}
|
||||
|
||||
UIHandle::Result ZoomHandle::Drag
|
||||
(const TrackPanelMouseEvent &evt, AudacityProject *)
|
||||
{
|
||||
const wxMouseEvent &event = evt.event;
|
||||
const int left = mRect.GetLeft();
|
||||
const int right = mRect.GetRight();
|
||||
|
||||
mZoomEnd = event.m_x;
|
||||
|
||||
if (event.m_x < left) {
|
||||
mZoomEnd = left;
|
||||
}
|
||||
else if (event.m_x > right) {
|
||||
mZoomEnd = right;
|
||||
}
|
||||
|
||||
// Refresh tracks ALWAYS. Even if IsDragZooming() becomes false, make the
|
||||
// dashed lines disappear. -- PRL
|
||||
return RefreshCode::RefreshAll; // (IsDragZooming() ? RefreshAllTracks : RefreshNone),
|
||||
}
|
||||
|
||||
HitTestPreview ZoomHandle::Preview
|
||||
(const TrackPanelMouseEvent &evt, const AudacityProject *pProject)
|
||||
{
|
||||
return HitPreview(evt.event, pProject);
|
||||
}
|
||||
|
||||
UIHandle::Result ZoomHandle::Release
|
||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject,
|
||||
wxWindow *)
|
||||
{
|
||||
const wxMouseEvent &event = evt.event;
|
||||
ViewInfo &viewInfo = pProject->GetViewInfo();
|
||||
if (mZoomEnd < mZoomStart)
|
||||
std::swap(mZoomStart, mZoomEnd);
|
||||
|
||||
const int trackLeftEdge = mRect.x;
|
||||
if (IsDragZooming())
|
||||
{
|
||||
/// This actually sets the Zoom value when you're done doing
|
||||
/// a drag zoom.
|
||||
double left = viewInfo.PositionToTime(mZoomStart, trackLeftEdge);
|
||||
double right = viewInfo.PositionToTime(mZoomEnd, trackLeftEdge);
|
||||
|
||||
double multiplier =
|
||||
(viewInfo.PositionToTime(mRect.width) - viewInfo.PositionToTime(0)) /
|
||||
(right - left);
|
||||
if (event.ShiftDown())
|
||||
multiplier = 1.0 / multiplier;
|
||||
|
||||
viewInfo.ZoomBy(multiplier);
|
||||
|
||||
viewInfo.h = left;
|
||||
}
|
||||
else
|
||||
{
|
||||
/// This handles normal Zoom In/Out, if you just clicked;
|
||||
/// IOW, if you were NOT dragging to zoom an area.
|
||||
/// \todo MAGIC NUMBER: We've got several in this method.
|
||||
const double center_h =
|
||||
viewInfo.PositionToTime(event.m_x, trackLeftEdge);
|
||||
|
||||
const double multiplier =
|
||||
(event.RightUp() || event.RightDClick() || event.ShiftDown())
|
||||
? 0.5 : 2.0;
|
||||
viewInfo.ZoomBy(multiplier);
|
||||
|
||||
if (event.MiddleUp() || event.MiddleDClick())
|
||||
viewInfo.SetZoom(ZoomInfo::GetDefaultZoom()); // AS: Reset zoom.
|
||||
|
||||
const double new_center_h =
|
||||
viewInfo.PositionToTime(event.m_x, trackLeftEdge);
|
||||
|
||||
viewInfo.h += (center_h - new_center_h);
|
||||
}
|
||||
|
||||
mZoomEnd = mZoomStart = 0;
|
||||
|
||||
using namespace RefreshCode;
|
||||
return RefreshAll | FixScrollbars;
|
||||
}
|
||||
|
||||
UIHandle::Result ZoomHandle::Cancel(AudacityProject*)
|
||||
{
|
||||
// Cancel is implemented! And there is no initial state to restore,
|
||||
// so just return a code.
|
||||
return RefreshCode::RefreshAll;
|
||||
}
|
||||
|
||||
void ZoomHandle::DrawExtras
|
||||
(DrawingPass pass, wxDC * dc, const wxRegion &, const wxRect &panelRect)
|
||||
{
|
||||
if (pass == Cells) {
|
||||
// PRL: Draw dashed lines only if we would zoom in
|
||||
// for button up.
|
||||
if (!IsDragZooming())
|
||||
return;
|
||||
|
||||
wxRect rect;
|
||||
|
||||
dc->SetBrush(*wxTRANSPARENT_BRUSH);
|
||||
dc->SetPen(*wxBLACK_DASHED_PEN);
|
||||
|
||||
rect.x = std::min(mZoomStart, mZoomEnd);
|
||||
rect.width = 1 + abs(mZoomEnd - mZoomStart);
|
||||
rect.y = -1;
|
||||
rect.height = panelRect.height + 2;
|
||||
|
||||
dc->DrawRectangle(rect);
|
||||
}
|
||||
}
|
||||
|
||||
bool ZoomHandle::IsDragZooming() const
|
||||
{
|
||||
const int DragThreshold = 3;// Anything over 3 pixels is a drag, else a click.
|
||||
return (abs(mZoomEnd - mZoomStart) > DragThreshold);
|
||||
}
|
||||
66
src/tracks/ui/ZoomHandle.h
Normal file
66
src/tracks/ui/ZoomHandle.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
ZoomHandle.h
|
||||
|
||||
Paul Licameli split from TrackPanel.cpp
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef __AUDACITY_ZOOM_HANDLE__
|
||||
#define __AUDACITY_ZOOM_HANDLE__
|
||||
|
||||
#include "../../UIHandle.h"
|
||||
|
||||
class wxMouseEvent;
|
||||
#include <wx/gdicmn.h>
|
||||
|
||||
struct HitTestResult;
|
||||
|
||||
class ZoomHandle final : public UIHandle
|
||||
{
|
||||
ZoomHandle();
|
||||
ZoomHandle(const ZoomHandle&) = delete;
|
||||
ZoomHandle &operator=(const ZoomHandle&) = delete;
|
||||
static ZoomHandle& Instance();
|
||||
static HitTestPreview HitPreview
|
||||
(const wxMouseEvent &event, const AudacityProject *pProject);
|
||||
|
||||
public:
|
||||
static HitTestResult HitAnywhere
|
||||
(const wxMouseEvent &event, const AudacityProject *pProject);
|
||||
static HitTestResult HitTest
|
||||
(const wxMouseEvent &event, const AudacityProject *pProject);
|
||||
|
||||
virtual ~ZoomHandle();
|
||||
|
||||
Result Click
|
||||
(const TrackPanelMouseEvent &event, AudacityProject *pProject) override;
|
||||
|
||||
Result Drag
|
||||
(const TrackPanelMouseEvent &event, AudacityProject *pProject) override;
|
||||
|
||||
HitTestPreview Preview
|
||||
(const TrackPanelMouseEvent &event, const AudacityProject *pProject)
|
||||
override;
|
||||
|
||||
Result Release
|
||||
(const TrackPanelMouseEvent &event, AudacityProject *pProject,
|
||||
wxWindow *pParent) override;
|
||||
|
||||
Result Cancel(AudacityProject *pProject) override;
|
||||
|
||||
void DrawExtras
|
||||
(DrawingPass pass,
|
||||
wxDC * dc, const wxRegion &updateRegion, const wxRect &panelRect)
|
||||
override;
|
||||
|
||||
private:
|
||||
bool IsDragZooming() const;
|
||||
|
||||
int mZoomStart{}, mZoomEnd{};
|
||||
wxRect mRect{};
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user