forked from Sneeds-Feed-and-Seed/sneedacity
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCellularPanel.h
175 lines (129 loc) · 5.37 KB
/
CellularPanel.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/**********************************************************************
Sneedacity: A Digital Audio Editor
CellularPanel.h
Paul Licameli
**********************************************************************/
#ifndef __SNEEDACITY_CELLULAR_PANEL__
#define __SNEEDACITY_CELLULAR_PANEL__
#include "widgets/OverlayPanel.h" // to inherit
class ViewInfo;
class SneedacityProject;
class TrackPanelCell;
struct TrackPanelDrawingContext;
class TrackPanelGroup;
class TrackPanelNode;
struct TrackPanelMouseEvent;
struct TrackPanelMouseState;
class TranslatableString;
class UIHandle;
using UIHandlePtr = std::shared_ptr<UIHandle>;
// This class manages a panel divided into a number of sub-rectangles called
// cells, that each implement hit tests returning click-drag-release handler
// objects, and other services.
// It has no dependency on the Track class.
class SNEEDACITY_DLL_API CellularPanel : public OverlayPanel {
public:
CellularPanel(wxWindow * parent, wxWindowID id,
const wxPoint & pos,
const wxSize & size,
ViewInfo *viewInfo,
// default as for wxPanel:
long style = wxTAB_TRAVERSAL | wxNO_BORDER);
~CellularPanel() override;
// Overridables:
virtual SneedacityProject *GetProject() const = 0;
// Get the root object defining a recursive subdivision of the panel's
// area into cells
virtual std::shared_ptr<TrackPanelNode> Root() = 0;
virtual TrackPanelCell *GetFocusedCell() = 0;
virtual void SetFocusedCell() = 0;
virtual void ProcessUIHandleResult
(TrackPanelCell *pClickedCell, TrackPanelCell *pLatestCell,
unsigned refreshResult) = 0;
virtual void UpdateStatusMessage( const TranslatableString & ) = 0;
public:
// Structure and functions for generalized visitation of the subdivision
struct Visitor {
virtual ~Visitor();
virtual void VisitCell( const wxRect &rect, TrackPanelCell &cell );
virtual void BeginGroup( const wxRect &rect, TrackPanelGroup &group );
virtual void EndGroup( const wxRect &rect, TrackPanelGroup &group );
};
// Most general visit
void Visit( Visitor &visitor );
// Easier visit when you care only about cells
using SimpleCellVisitor =
std::function< void( const wxRect &rect, TrackPanelCell &cell ) >;
void VisitCells( const SimpleCellVisitor &visitor );
// Easier visits when you want to visit each node once only
using SimpleNodeVisitor =
std::function< void( const wxRect &rect, TrackPanelNode &node ) >;
void VisitPreorder( const SimpleNodeVisitor &visitor );
void VisitPostorder( const SimpleNodeVisitor &visitor );
// Find cell by coordinate
struct FoundCell {
std::shared_ptr< TrackPanelCell > pCell;
wxRect rect;
};
FoundCell FindCell(int mouseX, int mouseY);
// Search the tree of subdivisions of the panel area for the given cell.
// If more than one sub-area is associated with the same cell object, it
// is not specified which rectangle is returned.
wxRect FindRect(const TrackPanelCell &cell);
// Search the tree of subdivisions of the panel area for a node (group or
// cell) satisfying the predicate. If more than one sub-area is associated
// with some node satisfying the predicate, it is not specified which
// rectangle is returned.
wxRect FindRect(const std::function< bool( TrackPanelNode& ) > &pred);
UIHandlePtr Target();
std::shared_ptr<TrackPanelCell> LastCell() const;
bool IsMouseCaptured();
wxCoord MostRecentXCoord() const;
void HandleCursorForPresentMouseState(bool doHit = true);
// Visit the Draw functions of all cells that intersect the panel area,
// and of handles associated with such cells,
// and of all groups of cells,
// repeatedly with a pass count from 0 to nPasses - 1
void Draw( TrackPanelDrawingContext &context, unsigned nPasses );
protected:
bool HasEscape();
bool CancelDragging( bool escaping );
void DoContextMenu( TrackPanelCell *pCell = nullptr );
void ClearTargets();
private:
void Visit(
const wxRect &rect, const std::shared_ptr<TrackPanelNode> &node,
Visitor &visitor );
bool HasRotation();
bool ChangeTarget(bool forward, bool cycle);
void OnMouseEvent(wxMouseEvent & event);
void OnCaptureLost(wxMouseCaptureLostEvent & event);
void OnCaptureKey(wxCommandEvent & event);
void OnKeyDown(wxKeyEvent & event);
void OnChar(wxKeyEvent & event);
void OnKeyUp(wxKeyEvent & event);
void OnSetFocus(wxFocusEvent & event);
void OnKillFocus(wxFocusEvent & event);
void OnContextMenu(wxContextMenuEvent & event);
void HandleInterruptedDrag();
void Uncapture( bool escaping, wxMouseState *pState = nullptr );
bool HandleEscapeKey(bool down);
void UpdateMouseState(const wxMouseState &state);
void HandleModifierKey();
void HandleClick( const TrackPanelMouseEvent &tpmEvent );
void HandleWheelRotation( TrackPanelMouseEvent &tpmEvent );
void HandleMotion( wxMouseState &state, bool doHit = true );
void HandleMotion
( const TrackPanelMouseState &tpmState, bool doHit = true );
void Leave();
protected:
ViewInfo *mViewInfo;
// To do: make a drawing method and make this private
wxMouseState mLastMouseState;
private:
struct State;
std::unique_ptr<State> mState;
struct Filter;
DECLARE_EVENT_TABLE()
};
#endif