// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once #include #include #include #include #include namespace gui { template class StringPolicy { public: using Range = std::vector; using Type = ValType; StringPolicy(Range range, Boundaries boundaries) : range{range}, boundaries{boundaries} {} ValType get() const { return pos < range.size() ? range[pos] : ValType{}; } UTF8 str() const { return pos < range.size() ? range[pos] : UTF8{}; } void set(ValType val) { for (auto i = 0U; i < range.size(); i++) { if (range[i] == val) { pos = i; break; } } } bool next() { bool ret{true}; if (pos >= upRange()) { if (boundaries == Boundaries::Continuous) { pos = 0; } else { pos = upRange(); ret = false; } } else { pos++; } return ret; } bool previous() { bool ret{true}; if (pos <= 0) { if (boundaries == Boundaries::Continuous) { pos = upRange(); } else { pos = 0; ret = false; } } else { pos--; } return ret; } void updateRange(Range newRange) { if (range != newRange) { range = newRange; pos = 0; } } [[nodiscard]] bool isAtMin() const { return pos == 0; } [[nodiscard]] bool isAtMax() const { return pos == upRange(); } private: std::uint32_t upRange() const { return range.size() - 1; } Range range; std::uint32_t pos{}; const Boundaries boundaries{}; }; template class DefaultNumericFormatter { public: std::string operator()(const ValType val) const { return std::to_string(val); } }; template class FixedSizeFormatter { public: std::string operator()(const ValType val) const { std::stringstream outStream; outStream << std::setw(Width) << std::setfill('0') << val; return outStream.str(); } }; template > class NumericPolicy { struct RangeImpl { ValType min; ValType max; ValType step; bool operator!=(const RangeImpl &oth) const { return min != oth.min || max != oth.max || step != oth.step; } }; public: using Range = RangeImpl; using Type = ValType; NumericPolicy(Range range, Boundaries boundaries) : range{range}, boundaries{boundaries} {} ValType get() const { return currentValue; } UTF8 str() const { return Formatter{}(currentValue); } void set(ValType val) { currentValue = val; } bool next() { bool ret{true}; if (currentValue >= range.max) { if (boundaries == Boundaries::Continuous) { currentValue = range.min; } else { currentValue = range.max; ret = false; } } else { currentValue += range.step; } return ret; } bool previous() { bool ret{true}; if (currentValue <= range.min) { if (boundaries == Boundaries::Continuous) { currentValue = range.max; } else { currentValue = range.min; ret = false; } } else { currentValue -= range.step; } return ret; } void updateRange(Range newRange) { if (range != newRange) { range = newRange; currentValue = 0; } } [[nodiscard]] bool isAtMin() const { return currentValue == range.min; } [[nodiscard]] bool isAtMax() const { return currentValue == range.max; } private: Range range; ValType currentValue{}; const Boundaries boundaries{}; }; template class ModelDelegatePolicy { public: using Range = std::vector; using Type = ValType; ModelDelegatePolicy(Range range, Boundaries boundaries) : range{range}, boundaries{boundaries} {} Type get() const { return pos < range.size() ? range[pos] : Type{}; } UTF8 str() const { return pos < range.size() ? RepresentationType{range[pos]} : RepresentationType{}; } void set(ValType val) { for (auto i = 0U; i < range.size(); i++) { if (range[i] == val) { pos = i; break; } } } bool next() { bool ret{true}; if (pos >= upRange()) { if (boundaries == Boundaries::Continuous) { pos = 0; } else { pos = upRange(); ret = false; } } else { pos++; } return ret; } bool previous() { bool ret{true}; if (pos <= 0) { if (boundaries == Boundaries::Continuous) { pos = upRange(); } else { pos = 0; ret = false; } } else { pos--; } return ret; } void updateRange(Range newRange) { if (range != newRange) { range = newRange; pos = 0; } } [[nodiscard]] bool isAtMin() const { return pos == 0; } [[nodiscard]] bool isAtMax() const { return pos == upRange(); } private: std::uint32_t upRange() const { return range.size() - 1; } Range range; std::uint32_t pos{}; const Boundaries boundaries{}; }; } // namespace gui