27#include <wx/tokenzr.h>
33#include <wx/dcclient.h>
39#include <wx/settings.h>
49#include "../widgets/Grabber.h"
58 return std::find_if(This->begin(), This->end(),
59 [=](
const Place &place){
60 return place.pTree->pBar == bar;
65 -> std::pair<Forest*, Forest::iterator>
67 auto findTree = [=](
Forest &forest){
68 return std::find_if(forest.begin(), forest.end(),
69 [=](
const Tree &tree){ return tree.pBar == bar; });
72 auto iter1 = findTree(mForest);
73 if (iter1 != mForest.end())
74 return { &mForest, iter1 };
76 Forest::iterator result;
77 auto iter = std::find_if(
begin(),
end(),
78 [&](
const Place &place){
80 return (result = findTree(children)) != children.end();
84 return { &iter->pTree->children, result };
86 return {
nullptr, Forest::iterator{} };
91 auto iter = FindPlace(bar);
93 return UnspecifiedPosition;
95 return iter->position;
104 while (!pForest->empty())
105 pForest = &pForest->back().children;
106 pForest->push_back(
Tree {} );
107 pForest->back().pBar = bar;
116 pForest = &parent->pTree->children;
123 const auto begin = pForest->begin();
125 const auto end = pForest->end();
128 if (position.
below) {
143 adopt = (iter !=
end);
146 if (adopt && position.
adopt) {
154 const auto barHeight = bar->GetSize().GetY() +
toolbarGap;
155 auto totalHeight = 0;
156 while (iter != pForest->end() &&
158 (totalHeight += (iter->pBar->GetSize().GetY() +
toolbarGap))) {
161 child.pBar = iter->pBar;
162 child.children.swap(iter->children);
163 iter = pForest->erase(iter);
167 iter = pForest->insert(iter,
Tree{});
172 pForest->insert(iter,
Tree {})->pBar = bar;
177 (
ToolBar *bar,
const std::vector<int> &path)
183 for (
auto ii : path) {
184 Forest::size_type uu = std::max(0, ii);
188 pForest->resize(std::max(uu + 1, pForest->size()));
189 pTree = &(*pForest)[uu];
190 pForest = &pTree->children;
202 iter = forest.erase(iter);
204 auto cIter = children.rbegin(), cEnd = children.rend();
205 while (cIter != cEnd) {
206 iter = forest.insert(iter,
Tree{});
207 (*iter).swap(*cIter);
215 auto pForest = results.first;
218 auto iter = results.second;
219 wxASSERT(iter->pBar == bar);
247 if (bar->GetRect().y != iter->pTree->pBar->GetRect().y)
257 ToolBar *bar,
bool &visible,
bool defaultVisible)
263 gPrefs->Read( wxT(
"Show"), &visible, defaultVisible);
265 if (pConfiguration && visible) {
267 gPrefs->Read( wxT(
"Order"), &ord, -1 );
275 while (pLegacy->
bars.size() <=
size_t(ord))
276 pLegacy->
bars.push_back(
nullptr);
277 pLegacy->
bars[ord] = bar;
281 gPrefs->Read( wxT(
"Path"), &strPath );
282 if (!strPath.empty()) {
283 wxStringTokenizer toker { strPath, wxT(
",") };
284 std::vector<int> path;
285 while(toker.HasMoreTokens()) {
286 auto token = toker.GetNextToken();
287 auto ii = wxAtoi(token);
300 for (
size_t ii = 0; ii < forest.size(); ++ii) {
301 if(forest[ii].pBar ==
nullptr)
302 Remove(forest, forest.begin() + ii--);
306 for (
auto &tree : forest)
319 for (
auto pBar : legacy.
bars) {
334 if (pConfiguration) {
337 const auto cIter = pConfiguration->
FindPlace(bar);
338 const auto path = cIter.
GetPath();
340 auto iter = path.begin(),
end = path.end();
341 strPath += wxString::Format(wxT(
"%d"), *iter++);
343 strPath += wxString::Format(wxT(
",%d"), *iter++);
345 gPrefs->Write(wxT(
"Path"), strPath);
379 wxPanelWrapper( parent, dockid, wxDefaultPosition, parent->GetSize() )
381 SetLabel(
XO(
"ToolDock" ) );
382 SetName(
XO(
"ToolDock" ) );
386 memset(mBars, 0,
sizeof(mBars));
388 SetLayoutDirection(wxLayout_LeftToRight);
409 mBars[ bar->GetId() ] =
nullptr;
423 bar->Reparent(
this );
424 mBars[ bar->GetId() ] = bar;
447 auto bar = place.pTree->pBar;
448 this->
Dock(bar,
false);
451 Expose( bar->GetId(),
true );
470 (
ToolBar *ct, wxPoint point) = 0;
485 if (pWrappedConfiguration)
486 pWrappedConfiguration->
Clear();
490 GetParent()->GetClientSize( &width, &height );
497 width, std::numeric_limits<int>::max() };
515 const auto ct = place.pTree->pBar;
518 const auto parent = place.position.rightOf;
519 const auto type = ct->
GetType();
520 auto &newItem = layout[ type ];
521 newItem.parentBarID = parent ? parent->GetType() :
NoBarID;
524 newItem.myBarID = type;
526 const auto parentItem = parent ? &layout[ parent->GetType() ] :
nullptr;
533 auto &sib = parentItem->lastSib;
541 wxSize sz = ct->GetSize();
544 temp.SetPosition(ct->GetParent()->ClientToScreen(ct->GetPosition()));
546 visitor.
ModifySize(ct, temp, prevPosition, place.position, sz);
560 auto pItem = parentItem;
561 auto pRect = pItem ? &pItem->rect : &
main;
562 while (pRect != &
main)
565 bool bTooWide = tw > pRect->GetWidth();
569 bool bTooHigh = th > pRect->GetHeight();
573 if (!bTooWide && !bTooHigh)
576 if (pItem->parentBarID ==
NoBarID) {
581 pItem = &layout[ pItem->parentBarID ];
582 pRect = &pItem->rect;
587 ToolBar *& sib = pItem ? pItem->lastWrappedChild : lastWrappedRoot;
589 pItem ? this->
mBars[ pItem->myBarID ] :
nullptr,
593 if (pWrappedConfiguration)
594 pWrappedConfiguration->
Insert(ct, newPosition);
597 const auto cpos = pRect->GetPosition();
598 visitor.
Visit(ct, cpos);
607 newItem.rect = wxRect{ x, cpos.y, width - x, th };
615 [](
const Item &item){
616 return item.myBarID ==
NoBarID || item.rect.IsEmpty();
620 std::sort(layout,
end,
621 [](
const Item &lhs,
const Item &rhs){
622 return lhs.rect.y < rhs.rect.y;
625 for (
auto iter = layout; iter !=
end; ++iter) {
626 const auto &item = *iter;
627 const auto &rect = item.rect;
629 auto globalRect = rect;
630 globalRect.SetPosition( this->ClientToScreen(rect.GetPosition()) );
635 position { this->
mBars[ item.myBarID ], item.lastWrappedChild },
637 visitor.
ModifySize(
nullptr, globalRect, prevPosition, position, sz);
642 bool bTooWide = tw > rect.GetWidth();
643 bool bTooHigh = th > rect.GetHeight();
644 if (!bTooWide && !bTooHigh) {
646 const auto cpos = rect.GetPosition();
647 visitor.
Visit(
nullptr, cpos);
667 SizeSetter (
ToolDock *d) : dock{ d } {}
675 bar->SetPosition( point );
678 bool ShouldVisitSpaces()
override
683 virtual void FinalRect
688 dock->SetMinSize( rect.GetSize() );
701 auto ct = place.pTree->pBar;
703 ct->MoveAfterInTabOrder( lt );
731 Inserter(Position &p, wxRect &r,
const wxPoint &pt,
ToolBar *t)
732 : result(p), rect(r), point(pt), tb(t)
737 const wxRect &rectIn,
747 if (rectIn.Contains(point))
749 sz = tb->GetDockedSize();
752 if (ct || (sz.x <= rectIn.width && sz.y <= rectIn.height)) {
755 (sz.y < rectIn.height ||
756 point.y < (rectIn.GetTop() + rectIn.GetBottom()) / 2))
761 usedPrev =
true, result = prevPosition, result.
adopt =
false;
778 rect.y -= tb->GetDockedSize().GetHeight() / 2;
784 bool ShouldVisitSpaces()
override
795 result = finalPosition;
796 wxPoint point1 { finalRect.GetLeft(), finalRect.GetBottom() };
797 rect.SetPosition(point1);
806 bool usedPrev {
false };
811 try { this->
VisitLayout(inserter); }
catch (
const Inserter::Stop&) {}
842 else if( !show && shown )
856 wxCommandEvent e( EVT_TOOLBAR_UPDATED, GetId() );
857 GetParent()->GetEventHandler()->AddPendingEvent( e );
895 wxPaintDC dc(
this );
909 wxSize sz = GetClientSize();
917 auto toolbar = place.pTree->pBar;
921 wxRect r = toolbar->GetRect();
947 event.ResumePropagation(wxEVENT_PROPAGATE_MAX);
IMPLEMENT_WX_THEME_SUPPORT int main(int argc, char *argv[])
#define EVT_GRABBER(id, fn)
auto Visit(Visitor &&vis, Variant &&var)
Mimic some of std::visit, for the case of one visitor only.
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)
virtual bool DeleteEntry(const wxString &key, bool bDeleteGroupIfEmpty=true) wxOVERRIDE
wxColour & Colour(int iIndex)
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.