diff --git a/src/gui/interact/ui-coord.hpp b/src/gui/interact/ui-coord.hpp index 8a6dd575c..dc8e9972e 100644 --- a/src/gui/interact/ui-coord.hpp +++ b/src/gui/interact/ui-coord.hpp @@ -249,7 +249,8 @@ namespace interact { void setComponent (UIPathElm idx, Literal newContent) { - UNIMPLEMENTED ("forcibly change data, maybe extend storage"); + Literal* storage = maybeExpandTo (idx); + setContent (storage, newContent); } @@ -295,7 +296,7 @@ namespace interact { /* == Builder functions == */ - Builder&& + Builder window (Literal windowID) { uic_.setComponent (UIC_WINDOW, windowID); @@ -303,15 +304,15 @@ namespace interact { } /** augment UI coordinates to mandate a specific perspective to be active within the window */ - Builder&& + Builder persp (Literal perspectiveID) { - uic_.setComponent (UIC_PART, perspectiveID); + uic_.setComponent (UIC_PERSP, perspectiveID); return std::move (*this); } /** augment UI coordinates to indicate a specific view to be used */ - Builder&& + Builder view (Literal viewID) { uic_.setComponent (UIC_VIEW, viewID); @@ -319,7 +320,7 @@ namespace interact { } /** augment UI coordinates to indicate a specific tab within the view" */ - Builder&& + Builder tab (Literal tabID) { uic_.setComponent (UIC_TAB, tabID); @@ -327,7 +328,7 @@ namespace interact { } /** augment UI coordinates to indicate a tab specified by index number */ - Builder&& + Builder tab (uint tabIdx) { uic_.setComponent (UIC_TAB, Symbol{"#"+util::toString (tabIdx)}); @@ -336,21 +337,21 @@ namespace interact { /** augment UI coordinates to define a complete local path */ - Builder&& + Builder path (string pathDefinition) { UNIMPLEMENTED ("set path"); } /** augment UI coordinates by appending a further component at the end */ - Builder&& + Builder append (Literal elmID) { UNIMPLEMENTED ("mutate: append"); } /** augment partially defined UI coordinates by extending them towards the root */ - Builder&& + Builder prepend (Literal elmID) { UNIMPLEMENTED ("mutate: preprend"); diff --git a/src/lib/path-array.hpp b/src/lib/path-array.hpp index 2e2d3ecb5..8a0071fa7 100644 --- a/src/lib/path-array.hpp +++ b/src/lib/path-array.hpp @@ -101,7 +101,7 @@ namespace lib { PStorage newCopy() const { - size_t siz = size (unConst(this)->storage_); + size_t siz = 1 + size (unConst(this)->storage_); const char** alloc = new const char*[siz]; std::copy (storage_, storage_+siz, alloc); return reinterpret_cast (alloc); @@ -198,9 +198,20 @@ namespace lib { } void - trimTo (size_t cnt) + resizeTo (size_t cnt) { - REQUIRE (cnt <= size()); + if (cnt > 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; + if (storage_) + delete[] storage_; + storage_ = reinterpret_cast (target); + size (storage_) = cnt; + return; + } if (not storage_) return; if (cnt == 0) { @@ -437,6 +448,22 @@ namespace lib { return const_cast (elm); } + /** + * @internal ensure storage for the indicated position exists + * @return pointer to the storage, either existing or reallocated + */ + Literal* + maybeExpandTo (size_t idx) + { + if (chunk_size <= idx and size() <= idx) + tail_.resizeTo(idx+1 - chunk_size); + if (idx < chunk_size) + return elms_.begin() + idx; + + ENSURE (idx-chunk_size < tail_.size()); + return const_cast (&tail_[idx-chunk_size]); + } + /** @internal force new content into the given entry */ void setContent (Literal* pos, const char* val) @@ -487,9 +514,9 @@ namespace lib { setContent (getPosition(idx), nullptr); if (idx >= chunk_size-1) - tail_.trimTo (idx+1 - chunk_size); + tail_.resizeTo (idx+1 - chunk_size); else - tail_.trimTo (0); + tail_.resizeTo (0); } }; diff --git a/tests/gui/interact/ui-coord-test.cpp b/tests/gui/interact/ui-coord-test.cpp index ae73197a0..0ebebb4ed 100644 --- a/tests/gui/interact/ui-coord-test.cpp +++ b/tests/gui/interact/ui-coord-test.cpp @@ -143,7 +143,7 @@ namespace test { verify_builder() { UICoord uic1 = UICoord::window("window"); - UICoord uic2 = uic2.view("view"); + UICoord uic2 = uic1.view("view"); CHECK ("UI:window" == string(uic1)); CHECK ("UI:window[*]-*.view" == string(uic2)); CHECK (1 == uic1.size()); diff --git a/tests/library/path-array-test.cpp b/tests/library/path-array-test.cpp index b4b88e97a..db129ef28 100644 --- a/tests/library/path-array-test.cpp +++ b/tests/library/path-array-test.cpp @@ -481,6 +481,16 @@ namespace test { CHECK (ParrT("" ,"Δ","Θ","Ξ","" ,"Ψ","Φ","" ) == ParrT("" ,"Δ","Θ","Ξ",nullptr,"Ψ","Φ")); CHECK (ParrT("" ,"Δ","Θ","Ξ","*","Ψ","Φ","" ) == ParrT("" ,"Δ","Θ","Ξ",nullptr,"Ψ","Φ")); CHECK (ParrT("" ,"Δ","Θ","Ξ","*","Ψ","Φ","" ) == ParrT("" ,"Δ","Θ","Ξ","", "Ψ","Φ")); + + ParrT src{"Γ","Δ","Θ","Ξ","Σ","Ψ","Φ","Ω"}; + ParrT copy{src}; + CHECK (not isnil(copy)); + CHECK (src == copy); + + ParrT target {std::move (copy)}; + CHECK (src == target); + CHECK (copy != target); + CHECK (copy != src); } };