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