diff --git a/include/avnd/concepts/dynamic_items.hpp b/include/avnd/concepts/dynamic_items.hpp new file mode 100644 index 00000000..8f4708be --- /dev/null +++ b/include/avnd/concepts/dynamic_items.hpp @@ -0,0 +1,20 @@ +#pragma once + +/* SPDX-License-Identifier: GPL-3.0-or-later */ + +#include + +#include +#include +#include + +namespace avnd +{ +// enum-ish parameter carrying an update_items callback for runtime item lists. +template +concept dynamic_items_parameter = enum_ish_parameter && requires(T t) { + { + t.update_items + } -> std::convertible_to)>>; +}; +} diff --git a/include/avnd/concepts/folder_items.hpp b/include/avnd/concepts/folder_items.hpp new file mode 100644 index 00000000..51fdf83e --- /dev/null +++ b/include/avnd/concepts/folder_items.hpp @@ -0,0 +1,19 @@ +#pragma once + +/* SPDX-License-Identifier: GPL-3.0-or-later */ + +#include + +#include + +namespace avnd +{ +// A combobox whose items are the files of a sibling folder port, populated by +// the host at edit time. The port exposes folder_port() (the sibling port's +// name) and extensions() (accepted suffixes). +template +concept folder_items_parameter = enum_ish_parameter && requires { + { T::folder_port() } -> std::convertible_to; + { T::extensions() } -> std::convertible_to; +}; +} diff --git a/include/halp/dynamic_combobox.hpp b/include/halp/dynamic_combobox.hpp new file mode 100644 index 00000000..a412b0e1 --- /dev/null +++ b/include/halp/dynamic_combobox.hpp @@ -0,0 +1,46 @@ +#pragma once + +/* SPDX-License-Identifier: GPL-3.0-or-later */ + +#include +#include + +#include +#include +#include +#include +#include + +namespace halp +{ +// Combobox whose items are set at runtime via update_items. Bindings without +// support leave update_items empty and use the static range() fallback. +template +struct dynamic_combobox +{ + enum widget + { + combobox + }; + + struct range + { + std::array values{"-"}; + int init{0}; + }; + + static clang_buggy_consteval auto name() { return std::string_view{lit.value}; } + + int value{0}; + + std::function)> update_items; + + operator int&() noexcept { return value; } + operator const int&() const noexcept { return value; } + auto& operator=(int t) noexcept + { + value = t; + return *this; + } +}; +} diff --git a/include/halp/folder_combobox.hpp b/include/halp/folder_combobox.hpp new file mode 100644 index 00000000..0dfd7827 --- /dev/null +++ b/include/halp/folder_combobox.hpp @@ -0,0 +1,52 @@ +#pragma once + +/* SPDX-License-Identifier: GPL-3.0-or-later */ + +#include +#include + +#include +#include +#include + +namespace halp +{ +// Combobox whose items are the files of a sibling folder port, listed by the +// host at edit time (and refreshed when the folder changes) — no execution +// needed. The VALUE is the selected file name (a string), so an object can use +// it directly as a file name. `folder_port` names the sibling path/folder +// port; `extensions` is a space-separated list of accepted suffixes (empty = +// all files); `init` is the initially selected file name — it stays selected +// even while the file does not exist yet, so chains of processes that write +// then read conventionally-named files keep working with default values. +template < + static_string lit, static_string folder = "Folder", static_string exts = "", + static_string init_value = "-"> +struct folder_combobox +{ + enum widget + { + combobox + }; + + struct range + { + std::array values{init_value.value}; + std::string_view init{init_value.value}; + }; + + static clang_buggy_consteval auto name() { return std::string_view{lit.value}; } + static clang_buggy_consteval auto folder_port() { return std::string_view{folder.value}; } + static clang_buggy_consteval auto extensions() { return std::string_view{exts.value}; } + + std::string value{}; + + operator std::string&() noexcept { return value; } + operator const std::string&() const noexcept { return value; } + auto& operator=(std::string t) noexcept + { + value = std::move(t); + return *this; + } +}; +}