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