Audacity 3.2.0
UIHandle.h
Go to the documentation of this file.
1/**********************************************************************
2
3Audacity: A Digital Audio Editor
4
5UIHandle.h
6
7Paul Licameli
8
9**********************************************************************/
10
11#ifndef __AUDACITY_UI_HANDLE__
12#define __AUDACITY_UI_HANDLE__
13
14#include <utility>
15#include <memory>
16#include <typeinfo>
17#include "TrackPanelDrawable.h" // to inherit
18
19class wxDC;
20class wxRect;
21class wxRegion;
22class wxWindow;
23
24class AudacityProject;
25struct HitTestPreview;
26class TrackPanelCell;
29
31// A TrackPanelCell reports a handle object of some subclass, in response to a
32// hit test at a mouse position; then this handle processes certain events,
33// and maintains necessary state through click-drag-release event sequences.
34class AUDACITY_DLL_API UIHandle /* not final */ : public TrackPanelDrawable
35{
36public:
37 // See RefreshCode.h for bit flags:
38 using Result = unsigned;
39
40 // Future: may generalize away from current Track class
42
43 virtual ~UIHandle() = 0;
44
45 // Before clicking, the handle is notified that it has been "hit"
46 // This might put the handle into its first rotated state
47 // (or last, if forward is false) or mark itself as needing a highlight.
48 // Default does nothing.
49 virtual void Enter(bool forward, AudacityProject *pProject);
50
51 // Tell whether the handle has more than one TAB key rotation state.
52 // Default is always false.
53 virtual bool HasRotation() const;
54
55 // If not previously in the last rotation state (or first if !forward),
56 // change rotation state and return true; else return false
57 // Default does nothing and returns false
58 virtual bool Rotate(bool forward);
59
60 // Tell whether the handle has its own escape action. In case it is already
61 // clicked, it will not cancel on Escape key if true.
62 // Default is always false.
63 virtual bool HasEscape(AudacityProject *pProject) const;
64
65 // The handle may change state and mark itself for highlight change.
66 // Default does nothing and returns false
67 virtual bool Escape(AudacityProject *pProject);
68
70
72 virtual bool HandlesRightClick();
73
74 // Assume hit test (implemented in other classes) was positive.
75 // May return Cancelled, overriding the hit test decision and stopping drag.
76 // Otherwise the framework will later call Release or Cancel after
77 // some number of Drag calls.
78 virtual Result Click
79 (const TrackPanelMouseEvent &event, AudacityProject *pProject) = 0;
80
81 // Assume previously Clicked and not yet Released or Cancelled.
82 // pCell may be other than for Click; may be NULL, and rect empty.
83 // Return value may include the Cancelled return flag,
84 // in which case the handle will not be invoked again.
85 virtual Result Drag
86 (const TrackPanelMouseEvent &event, AudacityProject *pProject) = 0;
87
88 // Can be called when the handle has been hit but not yet clicked,
89 // or called after Drag().
90 // Specifies cursor and status bar message.
92 (const TrackPanelMouseState &state, AudacityProject *pProject) = 0;
93
94 // Assume previously Clicked and not yet Released or Cancelled.
95 // event.pCell may be other than for Click; may be NULL, and rect empty.
96 // Can use pParent as parent to pop up a context menu,
97 // connecting and disconnecting event handlers for the menu items.
98 // Cancelled in return flags has no effect.
100 (const TrackPanelMouseEvent &event, AudacityProject *pProject,
101 wxWindow *pParent) = 0;
102
103 // Assume previously Clicked and not yet Released or Cancelled.
104 // Cancelled in return flags has no effect.
105 virtual Result Cancel(AudacityProject *pProject) = 0;
106
107 // Whether to force Release (not Cancel!) of the drag when a
108 // keystroke command is about to be dispatched. Default is always false.
109 // When default is false, any remembered pointers to tracks should be
110 // weak_ptrs.
111 virtual bool StopsOnKeystroke();
112
113 // Notification after a command is dispatched; generally, it will need to
114 // be overridden only in case StopsOnKeystroke() returns false. Default
115 // does nothing.
116 // PRL: all former uses of this are now accomplished with weak_ptr instead
117 // to avoid dangling pointers to tracks. But maybe there will be a future
118 // use?
119 virtual void OnProjectChange(AudacityProject *pProject);
120
121public:
122 Result GetChangeHighlight() const { return mChangeHighlight; }
123 void SetChangeHighlight(Result val) { mChangeHighlight = val; }
124
125 // If AssignUIHandlePtr is used, then this function is also called before any
126 // overwrite.
127 // Make overloads of this for other subclasses, to cause refresh
128 // of the cell during mouse motion within it.
130 (const UIHandle &/*oldState*/, const UIHandle &/*newState*/)
131 {
132 return 0;
133 }
134
135protected:
136 // Derived classes can set this nonzero in a constructor, which is enough
137 // to cause repaint of the cell whenever the pointer hits the target,
138 // or leaves it without clicking, or releases or escapes from a drag.
139 Result mChangeHighlight { 0 };
140
141};
142
143using UIHandlePtr = std::shared_ptr<UIHandle>;
144
145// A frequent convenience for defining a hit test.
146// Construct a NEW handle as if hit the first time; then either keep it, or
147// use it to overwrite the state of a previously constructed handle that has not
148// yet been released.
149template<typename Subclass>
150std::shared_ptr<Subclass> AssignUIHandlePtr
151( std::weak_ptr<Subclass> &holder, const std::shared_ptr<Subclass> &pNew )
152{
153 // Either assign to a null weak_ptr, or else rewrite what the weak_ptr
154 // points at. Thus a handle already pointed at changes its state but not its
155 // identity. This may matter for the framework that holds the strong
156 // pointers.
157 auto ptr = holder.lock();
158 if (!ptr) {
159 holder = pNew;
160 return pNew;
161 }
162 else {
163 //type slicing check
164 wxASSERT(typeid(*ptr) == typeid(*pNew));
165
166 auto code = Subclass::NeedChangeHighlight( *ptr, *pNew );
167 *ptr = std::move(*pNew);
168 ptr->SetChangeHighlight( code );
169 return ptr;
170 }
171}
172
173#endif
std::shared_ptr< UIHandle > UIHandlePtr
Definition: CellularPanel.h:28
std::shared_ptr< Subclass > AssignUIHandlePtr(std::weak_ptr< Subclass > &holder, const std::shared_ptr< Subclass > &pNew)
Definition: UIHandle.h:151
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
Drawing interface common to cells, groups of cells, and temporary handles in CellularPanel.
Short-lived drawing and event-handling object associated with a TrackPanelCell.
Definition: UIHandle.h:35
virtual Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject)=0
virtual Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent)=0
unsigned Result
Definition: UIHandle.h:38
void SetChangeHighlight(Result val)
Definition: UIHandle.h:123
Result GetChangeHighlight() const
Definition: UIHandle.h:122
static UIHandle::Result NeedChangeHighlight(const UIHandle &, const UIHandle &)
Definition: UIHandle.h:130
virtual HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *pProject)=0
virtual Result Cancel(AudacityProject *pProject)=0
virtual Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject)=0
void Rotate(ArraysOf< float > &arrays, size_t historyLen)