27#include <wx/tokenzr.h>
33#include <wx/dcclient.h>
37#include <wx/settings.h>
47#include "../widgets/Grabber.h"
56 return std::find_if(This->begin(), This->end(),
57 [=](
const Place &place){
58 return place.pTree->pBar == bar;
63 -> std::pair<Forest*, Forest::iterator>
65 auto findTree = [=](
Forest &forest){
66 return std::find_if(forest.begin(), forest.end(),
67 [=](
const Tree &tree){ return tree.pBar == bar; });
70 auto iter1 = findTree(mForest);
71 if (iter1 != mForest.end())
72 return { &mForest, iter1 };
74 Forest::iterator result;
75 auto iter = std::find_if(
begin(),
end(),
76 [&](
const Place &place){
78 return (result = findTree(children)) != children.end();
82 return { &iter->pTree->children, result };
84 return {
nullptr, Forest::iterator{} };
89 auto iter = FindPlace(bar);
91 return UnspecifiedPosition;
93 return iter->position;
98 if (toolBarID.
empty())
102 auto it = std::find_if(
103 This->begin(), This->end(),
104 [=](
const Place& place)
105 { return place.pTree->pBar->GetSection() == toolBarID; });
116 while (!pForest->empty())
117 pForest = &pForest->back().children;
118 pForest->push_back(
Tree {} );
119 pForest->back().pBar = bar;
128 pForest = &parent->pTree->children;
135 const auto begin = pForest->begin();
137 const auto end = pForest->end();
140 if (position.
below) {
155 adopt = (iter !=
end);
158 if (adopt && position.
adopt) {
166 const auto barHeight = bar->GetSize().GetY() +
toolbarGap;
167 auto totalHeight = 0;
168 while (iter != pForest->end() &&
170 (totalHeight += (iter->pBar->GetSize().GetY() +
toolbarGap))) {
173 child.pBar = iter->pBar;
174 child.children.swap(iter->children);
175 iter = pForest->erase(iter);
179 iter = pForest->insert(iter,
Tree{});
184 pForest->insert(iter,
Tree {})->pBar = bar;
189 (
ToolBar *bar,
const std::vector<int> &path)
195 for (
auto ii : path) {
196 Forest::size_type uu = std::max(0, ii);
200 pForest->resize(std::max(uu + 1, pForest->size()));
201 pTree = &(*pForest)[uu];
202 pForest = &pTree->children;
214 iter = forest.erase(iter);
216 auto cIter = children.rbegin(), cEnd = children.rend();
217 while (cIter != cEnd) {
218 iter = forest.insert(iter,
Tree{});
219 (*iter).swap(*cIter);
227 auto pForest = results.first;
230 auto iter = results.second;
231 wxASSERT(iter->pBar == bar);
242 if (!preferredNeighbors.first.empty() ||
243 !preferredNeighbors.second.empty())
245 auto leftNeighbor =
FindToolBar(preferredNeighbors.first);
246 auto topNeighbor =
FindToolBar(preferredNeighbors.second);
250 if (leftNeighbor !=
nullptr || topNeighbor !=
nullptr)
251 position =
Position { leftNeighbor, topNeighbor };
273 if (bar->GetRect().y != iter->pTree->pBar->GetRect().y)
283 ToolBar *bar,
bool &visible,
bool defaultVisible)
291 if (pConfiguration && visible) {
299 while (pLegacy->
bars.size() <=
size_t(ord))
300 pLegacy->
bars.push_back(
nullptr);
301 pLegacy->
bars[ord] = bar;
306 if (!strPath.empty()) {
307 wxStringTokenizer toker { strPath,
wxT(
",") };
308 std::vector<int> path;
309 while(toker.HasMoreTokens()) {
310 auto token = toker.GetNextToken();
311 auto ii = wxAtoi(token);
324 for (
size_t ii = 0; ii < forest.size(); ++ii) {
325 if(forest[ii].pBar ==
nullptr)
326 Remove(forest, forest.begin() + ii--);
330 for (
auto &tree : forest)
343 for (
auto pBar : legacy.
bars) {
358 if (pConfiguration) {
361 const auto cIter = pConfiguration->
FindPlace(bar);
362 const auto path = cIter.
GetPath();
364 auto iter = path.begin(),
end = path.end();
365 strPath += wxString::Format(
wxT(
"%d"), *iter++);
367 strPath += wxString::Format(
wxT(
",%d"), *iter++);
403 wxPanelWrapper( parent, dockid, wxDefaultPosition, parent->GetSize() )
405 SetLabel(
XO(
"ToolDock" ) );
406 SetName(
XO(
"ToolDock" ) );
411 SetLayoutDirection(wxLayout_LeftToRight);
446 bar->Reparent(
this );
470 auto bar = place.pTree->pBar;
471 this->
Dock(bar,
false);
474 Expose( bar->GetSection(),
true );
493 (
ToolBar *ct, wxPoint point) = 0;
508 if (pWrappedConfiguration)
509 pWrappedConfiguration->
Clear();
513 GetParent()->GetClientSize( &width, &height );
520 width, std::numeric_limits<int>::max() };
530 std::vector<Item> items(
mBars.size());
531 Item *layout = items.data();
541 const auto ct = place.pTree->pBar;
544 const auto parent = place.position.rightOf;
546 auto &newItem = *next++;
548 newItem.parent = std::find_if(layout, next - 1, [&](Item &item){
549 return parent->GetSection() == item.section;
553 newItem.section = section;
561 auto &sib = newItem.parent->lastSib;
569 wxSize sz = ct->GetSize();
572 temp.SetPosition(ct->GetParent()->ClientToScreen(ct->GetPosition()));
574 visitor.
ModifySize(ct, temp, prevPosition, place.position, sz);
588 auto pItem = newItem.parent;
589 auto pRect = pItem ? &pItem->rect : &
main;
590 while (pRect != &
main)
593 bool bTooWide = tw > pRect->GetWidth();
597 bool bTooHigh = th > pRect->GetHeight();
601 if (!bTooWide && !bTooHigh)
604 auto parentItem = pItem->parent;
611 pRect = &pItem->rect;
616 ToolBar *& sib = pItem ? pItem->lastWrappedChild : lastWrappedRoot;
618 pItem ? this->
mBars[ pItem->section ] :
nullptr,
622 if (pWrappedConfiguration)
623 pWrappedConfiguration->
Insert(ct, newPosition);
626 const auto cpos = pRect->GetPosition();
627 visitor.
Visit(ct, cpos);
636 newItem.rect = wxRect{ x, cpos.y, width - x, th };
644 std::sort(layout, next,
645 [](
const Item &lhs,
const Item &rhs){
646 return lhs.rect.y < rhs.rect.y;
649 for (
auto iter = layout; iter != next; ++iter) {
650 const auto &item = *iter;
651 const auto &rect = item.rect;
653 auto globalRect = rect;
654 globalRect.SetPosition( this->ClientToScreen(rect.GetPosition()) );
659 position { this->
mBars[ item.section ], item.lastWrappedChild },
661 visitor.
ModifySize(
nullptr, globalRect, prevPosition, position, sz);
666 bool bTooWide = tw > rect.GetWidth();
667 bool bTooHigh = th > rect.GetHeight();
668 if (!bTooWide && !bTooHigh) {
670 const auto cpos = rect.GetPosition();
671 visitor.
Visit(
nullptr, cpos);
691 SizeSetter (
ToolDock *d) : dock{ d } {}
699 bar->SetPosition( point );
702 bool ShouldVisitSpaces()
override
707 virtual void FinalRect
712 dock->SetMinSize( rect.GetSize() );
725 auto ct = place.pTree->pBar;
727 ct->MoveAfterInTabOrder( lt );
755 Inserter(Position &p, wxRect &r,
const wxPoint &pt,
ToolBar *t)
756 : result(p), rect(r), point(pt), tb(t)
761 const wxRect &rectIn,
771 if (rectIn.Contains(point))
773 sz = tb->GetDockedSize();
776 if (ct || (sz.x <= rectIn.width && sz.y <= rectIn.height)) {
779 (sz.y < rectIn.height ||
780 point.y < (rectIn.GetTop() + rectIn.GetBottom()) / 2))
785 usedPrev =
true, result = prevPosition, result.
adopt =
false;
802 rect.y -= tb->GetDockedSize().GetHeight() / 2;
808 bool ShouldVisitSpaces()
override
819 result = finalPosition;
820 wxPoint point1 { finalRect.GetLeft(), finalRect.GetBottom() };
821 rect.SetPosition(point1);
830 bool usedPrev {
false };
835 try { this->
VisitLayout(inserter); }
catch (
const Inserter::Stop&) {}
866 else if( !show && shown )
880 wxCommandEvent e( EVT_TOOLBAR_UPDATED, GetId() );
881 GetParent()->GetEventHandler()->AddPendingEvent( e );
919 wxPaintDC dc(
this );
933 wxSize sz = GetClientSize();
938 auto toolbar = place.pTree->pBar;
942 wxRect r = toolbar->GetRect();
957 event.ResumePropagation(wxEVENT_PROPAGATE_MAX);
int main(int argc, char *argv[])
#define EVT_GRABBER(id, fn)
audacity::BasicSettings * gPrefs
static const AttachedProjectObjects::RegisteredFactory manager
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
static void Dark(wxDC *dc, bool selected, bool highlight=false)
An explicitly nonlocalized string, not meant for the user to see.
wxColour & Colour(int iIndex)
virtual bool Write(const wxString &key, bool value)=0
bool DeleteEntry(const wxString &key)
Deletes specified entry if exists.
virtual bool Read(const wxString &key, bool *value) const =0
const char * end(const char *str) noexcept
const char * begin(const char *str) noexcept