forked from tenacityteam/tenacity-legacy
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathToolDock.h
351 lines (280 loc) · 8.89 KB
/
ToolDock.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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
/**********************************************************************
Audacity: A Digital Audio Editor
ToolDock.h
Dominic Mazzoni
Shane T. Mueller
Leland Lucius
**********************************************************************/
#ifndef __AUDACITY_TOOLDOCK__
#define __AUDACITY_TOOLDOCK__
#include <vector>
#include <wx/defs.h>
#include "ToolBar.h"
#include "MemoryX.h"
class wxCommandEvent;
class wxEraseEvent;
class wxSizeEvent;
class wxPaintEvent;
class wxPoint;
class wxRect;
class wxWindow;
class GrabberEvent;
////////////////////////////////////////////////////////////
/// class ToolDock
////////////////////////////////////////////////////////////
//
// ToolDock IDs
//
enum
{
NoDockID = 0,
TopDockID,
BotDockID,
DockCount = 2
};
// A description of a layout of toolbars, as a forest of trees that root
// at the left edge of the tool dock and grow rightward
class ToolBarConfiguration
{
struct Tree;
using Forest = std::vector<Tree>;
public:
void Swap(ToolBarConfiguration &that)
{
mForest.swap(that.mForest);
}
void Clear()
{
mForest.clear();
}
// Describe one toolbar's position in terms of its parent and preceding
// sibling
// When specifying a place at which to insert, "adopt" means insertion of
// an internal node displacing other nodes deeper as its children
struct Position {
ToolBar *rightOf {};
ToolBar *below {};
bool adopt {true};
bool valid {true};
// Default constructor
Position() {}
explicit Position(
ToolBar *r,
ToolBar *b = nullptr,
bool shouldAdopt = true
)
: rightOf{ r }, below{ b }, adopt{ shouldAdopt }
{}
// Constructor for the invalid value
explicit Position(bool /* dummy */) : valid{ false } {}
friend inline bool operator ==
(const Position &lhs, const Position &rhs)
{ return lhs.valid == rhs.valid &&
(!lhs.valid ||
(lhs.rightOf == rhs.rightOf
&& lhs.below == rhs.below
&& lhs.adopt == rhs.adopt
));
}
friend inline bool operator !=
(const Position &lhs, const Position &rhs)
{ return !(lhs == rhs); }
};
static const Position UnspecifiedPosition;
// Point to a node in the forest and describe its position
struct Place {
Tree *pTree {};
Position position;
};
// This iterator visits the nodes of the forest in pre-order, and at each
// stop, reports its Place
class Iterator
: public ValueIterator<Place>
{
public:
const Place &operator * () const { return mPlace; }
const Place *operator -> () const { return &**this; }
Iterator &operator ++ ()
{
// This is a feature: advance position even at the end
mPlace.position =
Position{ mPlace.pTree ? mPlace.pTree->pBar : nullptr };
if (!mIters.empty())
{
auto triple = &mIters.back();
auto &children = triple->current->children;
if (children.empty()) {
while (++triple->current == triple->end) {
mIters.pop_back();
if (mIters.empty())
break;
triple = &mIters.back();
}
}
else {
auto b = children.begin();
mIters.push_back( Triple { b, b, children.end() } );
}
}
if (mIters.empty()) {
mPlace.pTree = nullptr;
// Leave mPlace.position as above
}
else {
const auto &triple = mIters.back();
mPlace.pTree = &*triple.current;
if (mIters.size() == 1)
mPlace.position.rightOf = nullptr;
else
mPlace.position.rightOf = (mIters.rbegin() + 1)->current->pBar;
if (triple.begin == triple.current)
mPlace.position.below = nullptr;
else
mPlace.position.below = (triple.current - 1)->pBar;
}
return *this;
}
// This may be called on the end iterator, and then returns empty
std::vector<int> GetPath() const
{
std::vector<int> path;
path.reserve(mIters.size());
for (const auto &triple : mIters)
path.push_back(triple.current - triple.begin);
return path;
}
friend inline bool operator ==
(const Iterator &lhs, const Iterator &rhs)
{
const auto &li = lhs.mIters;
const auto &ri = rhs.mIters;
return li.size() == ri.size() &&
std::equal(li.begin(), li.end(), ri.begin());
}
friend inline bool operator !=
(const Iterator &lhs, const Iterator &rhs)
{
return !(lhs == rhs);
}
private:
friend ToolBarConfiguration;
Iterator () {}
explicit Iterator(ToolBarConfiguration &conf)
{
auto &forest = conf.mForest;
if (!forest.empty()) {
auto b = forest.begin();
mIters.push_back( Triple { b, b, forest.end() } );
mPlace.pTree = &*b;
}
}
Place mPlace;
using FIter = Forest::iterator;
struct Triple
{
Triple (FIter b, FIter c, FIter e)
: begin{b}, current{c}, end{e} {}
FIter begin, current, end;
friend inline bool operator ==
(const Triple &lhs, const Triple &rhs)
{
// Really need only to compare current
return
// lhs.begin == rhs.begin &&
lhs.current == rhs.current
// && lhs.end == rhs.end
;
}
};
std::vector<Triple> mIters;
};
Iterator begin() { return Iterator { *this }; }
Iterator end() const { return Iterator {}; }
Position Find(const ToolBar *bar) const;
bool Contains(const ToolBar *bar) const
{
return Find(bar) != UnspecifiedPosition;
}
// Default position inserts at the end
void Insert(ToolBar *bar,
Position position = UnspecifiedPosition);
void InsertAtPath(ToolBar *bar, const std::vector<int> &path);
void Remove(const ToolBar *bar);
// Future: might allow a state that the configuration remembers
// a hidden bar, but for now, it's equivalent to Contains():
bool Shows(const ToolBar *bar) const { return Contains(bar); }
void Show(ToolBar *bar);
void Hide(ToolBar *bar);
bool IsRightmost(const ToolBar *bar) const;
struct Legacy {
std::vector<ToolBar*> bars;
};
static bool Read
(ToolBarConfiguration *pConfiguration,
Legacy *pLegacy,
ToolBar *bar, bool &visible, bool defaultVisible);
void PostRead(Legacy &legacy);
static void Write
(const ToolBarConfiguration *pConfiguration, const ToolBar *bar);
private:
void Remove(Forest &forest, Forest::iterator iter);
void RemoveNulls(Forest &forest);
struct Tree
{
ToolBar *pBar {};
Forest children;
void swap(Tree &that)
{
std::swap(pBar, that.pBar);
children.swap(that.children);
}
};
Iterator FindPlace(const ToolBar *bar) const;
std::pair<Forest*, Forest::iterator> FindPeers(const ToolBar *bar);
Forest mForest;
};
class ToolDock final : public wxPanelWrapper
{
public:
ToolDock( wxEvtHandler *manager, wxWindow *parent, int dockid );
~ToolDock();
bool AcceptsFocus() const override { return false; };
void LoadConfig();
void LayoutToolBars();
void Expose( int type, bool show );
int GetOrder( ToolBar *bar );
void Dock( ToolBar *bar, bool deflate,
ToolBarConfiguration::Position ndx
= ToolBarConfiguration::UnspecifiedPosition);
void Undock( ToolBar *bar );
ToolBarConfiguration::Position
PositionBar( ToolBar *t, const wxPoint & pos, wxRect & rect );
ToolBarConfiguration &GetConfiguration()
{ return mConfiguration; }
// backup gets old contents of the configuration; the configuration is
// set to the wrapped configuration.
void WrapConfiguration(ToolBarConfiguration &backup);
// Reverse what was done by WrapConfiguration.
void RestoreConfiguration(ToolBarConfiguration &backup);
void Updated();
protected:
void OnErase( wxEraseEvent & event );
void OnSize( wxSizeEvent & event );
void OnPaint( wxPaintEvent & event );
void OnGrabber( GrabberEvent & event );
void OnMouseEvents(wxMouseEvent &event);
private:
class LayoutVisitor;
void VisitLayout(LayoutVisitor &visitor,
ToolBarConfiguration *pWrappedConfiguration = nullptr);
wxEvtHandler *mManager;
// Stores adjacency relations that we want to realize in the dock layout
ToolBarConfiguration mConfiguration;
// Configuration as modified by the constraint of the main window width
ToolBarConfiguration mWrappedConfiguration;
ToolBar *mBars[ ToolBarCount ];
public:
DECLARE_CLASS( ToolDock )
DECLARE_EVENT_TABLE()
};
#endif