diff --git a/src/gui/interact/ui-coord.hpp b/src/gui/interact/ui-coord.hpp index 3a07915d1..ec8a335bc 100644 --- a/src/gui/interact/ui-coord.hpp +++ b/src/gui/interact/ui-coord.hpp @@ -57,7 +57,9 @@ #include "lib/util.hpp" //#include +#include #include +#include #include //#include @@ -134,7 +136,7 @@ namespace interact { // convenience shortcuts to start mutation on a copy... - Builder path (string pathDefinition) const; + Builder path (Literal pathDefinition) const; Builder append (Literal elmID) const; Builder prepend (Literal elmID) const; @@ -257,6 +259,13 @@ namespace interact { /** @note Builder allowed to manipulate stored data */ friend class Builder; + size_t + findStartIdx() const + { + REQUIRE (not empty()); + return indexOf (*begin()); + } + Literal accesComponent (UIPathElm idx) const { @@ -267,15 +276,68 @@ namespace interact { void setComponent (size_t idx, Literal newContent) { - Literal* storage = maybeExpandTo (idx); + Literal* storage = expandPosition (idx); setContent (storage, newContent); } - size_t - findStartIdx() const + + /** replace / overwrite existing content starting at given index. + * @param idx where to start adding content; storage will be expanded to accommodate + * @param newContent either a single element, or several elements delimited by `'/'` + * @note - a path sequence will be split at `'/'` and the components _interned_ + * - any excess elements will be cleared + * @warning need to invoke PathArray::normalise() afterwards + */ + void + setTailSequence (size_t idx, Literal newContent) { - REQUIRE (not empty()); - return indexOf (*begin()); + std::vector elms; + if (not isnil (newContent)) + { + if (not std::strchr (newContent, '/')) + { + // single element: just place it as-is + // and remove any further content behind + elms.emplace_back (newContent); + } + else + { // it is actually a sequence of elements, + // which need to be split first, and then + // interned into the global symbol table + string sequence{newContent}; + size_t pos = 0; + size_t last = 0; + while (string::npos != (last = sequence.find ('/', pos))) + { + elms.emplace_back (Symbol{sequence.substr(pos, last - pos)}); + pos = last + 1; + } + sequence = sequence.substr(pos); + if (not isnil (sequence)) + elms.emplace_back (Symbol{sequence}); + } } + + setTailSequence (idx, elms); + } + + /** replace the existing path information with the given elements + * @note - storage will possibly be expanded to accommodate + * - the individual path elements will be _interned_ as Symbol + * - any excess elements will be cleared + * - the pathElms can be _empty_ in which case just + * any content starting from `idx` will be cleared + * @warning need to invoke PathArray::normalise() afterwards + */ + void + setTailSequence (size_t idx, std::vector& pathElms) + { + size_t cnt = pathElms.size(); + expandPosition (idx + cnt); + for (size_t i=0 ; i < cnt; ++i) + setContent (expandPosition(idx + i), pathElms[i]); + size_t end = size(); + for (size_t i = idx+cnt; i size()) - { // copy to expanded storage - auto target = new const char* [cnt+1]; - auto pos = std::copy (storage_, storage_+1+size(), target); - for ( ; pos < target+1+cnt; ++pos) - *pos = nullptr; + { // need more storage if (storage_) - delete[] storage_; - storage_ = reinterpret_cast (target); + { // copy content to new expanded storage + auto target = new const char* [cnt+1]; + auto pos = std::copy (storage_, storage_+1+size(), target); + for ( ; pos < target+1+cnt; ++pos) + *pos = nullptr; + delete[] storage_; + storage_ = reinterpret_cast (target); + } + else // allocate and init empty + storage_ = new Literal [cnt+1]; + size (storage_) = cnt; return; } @@ -453,7 +458,7 @@ namespace lib { * @return pointer to the storage, either existing or reallocated */ Literal* - maybeExpandTo (size_t idx) + expandPosition (size_t idx) { if (chunk_size <= idx and size() <= idx) tail_.resizeTo(idx+1 - chunk_size); diff --git a/tests/gui/interact/ui-coord-test.cpp b/tests/gui/interact/ui-coord-test.cpp index eb794c132..6b440ea56 100644 --- a/tests/gui/interact/ui-coord-test.cpp +++ b/tests/gui/interact/ui-coord-test.cpp @@ -275,23 +275,23 @@ namespace test { CHECK ("α/β/γ/δ/ε/λ/ον" == uic.getPath()); uic = uic.prepend("perspective"); - CHECK ("UI:UI:?[perspective]-panel.*. /α/β/γ/δ/ε/λ/ον" == string(uic)); + CHECK ("UI:?[perspective]-panel.*. /α/β/γ/δ/ε/λ/ον" == string(uic)); CHECK ("?[perspective]-panel.*. " == uic.getComp()); CHECK ("α/β/γ/δ/ε/λ/ον" == uic.getPath()); uic = uic.prepend("win"); - CHECK ("UI:UI:win[perspective]-panel.*. /α/β/γ/δ/ε/λ/ον" == string(uic)); + CHECK ("UI:win[perspective]-panel.*. /α/β/γ/δ/ε/λ/ον" == string(uic)); CHECK ("win[perspective]-panel.*. " == uic.getComp()); CHECK ("α/β/γ/δ/ε/λ/ον" == uic.getPath()); uic = uic.persp(""); - CHECK ("UI:UI:win[*]-panel.*. /α/β/γ/δ/ε/λ/ον" == string(uic)); + CHECK ("UI:win[*]-panel.*. /α/β/γ/δ/ε/λ/ον" == string(uic)); CHECK ("win[*]-panel.*. " == uic.getComp()); CHECK ("α/β/γ/δ/ε/λ/ον" == uic.getPath()); CHECK (12 == uic.size()); uic = uic.path(" "); - CHECK ("UI:UI:win[*]-panel.*. / " == string(uic)); + CHECK ("UI:win[*]-panel.*. / " == string(uic)); CHECK ("win[*]-panel.*. " == uic.getComp()); CHECK (" " == uic.getPath()); CHECK (6 == uic.size()); @@ -299,39 +299,39 @@ namespace test { VERIFY_ERROR (INDEX_BOUNDS, uic[UIC_PART+1]); uic = uic.path(nullptr); - CHECK ("UI:UI:win[*]-panel.*. " == string(uic)); + CHECK ("UI:win[*]-panel.*. " == string(uic)); CHECK ("win[*]-panel.*. " == uic.getComp()); CHECK ("" == uic.getPath()); CHECK (5 == uic.size()); VERIFY_ERROR (INDEX_BOUNDS, uic[UIC_PART]); uic = uic.append(nullptr); - CHECK ("UI:UI:win[*]-panel.*. " == string(uic)); + CHECK ("UI:win[*]-panel.*. " == string(uic)); CHECK ("win[*]-panel.*. " == uic.getComp()); CHECK ("" == uic.getPath()); CHECK (5 == uic.size()); uic = uic.append("*"); - CHECK ("UI:UI:win[*]-panel.*. " == string(uic)); + CHECK ("UI:win[*]-panel.*. " == string(uic)); CHECK ("win[*]-panel.*. " == uic.getComp()); CHECK ("" == uic.getPath()); CHECK (5 == uic.size()); uic = uic.append("**"); - CHECK ("UI:UI:win[*]-panel.*. /**" == string(uic)); + CHECK ("UI:win[*]-panel.*. /**" == string(uic)); CHECK ("win[*]-panel.*. " == uic.getComp()); CHECK ("**" == uic.getPath()); CHECK ("**" == uic[UIC_PART]); CHECK (6 == uic.size()); uic = uic.tab(""); - CHECK ("UI:UI:win[*]-panel.*.*/**" == string(uic)); + CHECK ("UI:win[*]-panel.*.*/**" == string(uic)); CHECK ("win[*]-panel.*.*" == uic.getComp()); CHECK ("**" == uic.getPath()); CHECK (6 == uic.size()); uic = uic.path(""); - CHECK ("UI:UI:win[*]-panel" == string(uic)); + CHECK ("UI:win[*]-panel" == string(uic)); CHECK ("win[*]-panel" == uic.getComp()); CHECK ("" == uic.getPath()); CHECK (3 == uic.size()); diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 708013a61..341d36b66 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -3914,13 +3914,13 @@ - - + + - - + + @@ -3976,8 +3976,8 @@ - - + +