HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
default_selection_delegate.hpp
1// Copyright Take Vos 2021.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "selection_delegate.hpp"
8#include "../observable.hpp"
9#include "../label.hpp"
10#include <type_traits>
11#include <memory>
12#include <vector>
13
14namespace hi::inline v1 {
15
16template<typename T>
18public:
19 using value_type = T;
20
23 observable<value_type> off_value;
24
25 default_selection_delegate(auto &&options, auto &&value, auto &&off_value) noexcept :
26 options(hi_forward(options)), value(hi_forward(value)), off_value(hi_forward(off_value))
27 {
28 // clang-format off
29 _options_cbt = this->options.subscribe([&](auto...){ this->_notifier(); });
30 _value_cbt = this->value.subscribe([&](auto...){ this->_notifier(); });
31 _off_value_cbt = this->off_value.subscribe([&](auto...){ this->_notifier(); });
32 // clang-format on
33 }
34
35 default_selection_delegate(auto &&option_list, auto &&value) noexcept :
36 default_selection_delegate(hi_forward(option_list), hi_forward(value), value_type{})
37 {
38 }
39
40 void set_selected(selection_widget &sender, ptrdiff_t index) noexcept override
41 {
42 if (index == -1 || index >= std::ssize(*options)) {
43 value = *off_value;
44 } else {
45 value = (*options)[index].first;
46 }
47 }
48
49 std::pair<std::vector<label>, ptrdiff_t> options_and_selected(selection_widget const& sender) const noexcept override
50 {
51 auto labels = std::vector<label>{};
52 labels.reserve(options->size());
53
54 auto index = 0_z;
55 auto selected_index = -1_z;
56 for (auto &&option : *options) {
57 if (*value == option.first) {
58 selected_index = index;
59 }
60 labels.push_back(option.second);
61 ++index;
62 }
63
64 return {std::move(labels), selected_index};
65 }
66
67private:
68 typename decltype(options)::token_type _options_cbt;
69 typename decltype(value)::token_type _value_cbt;
70 typename decltype(off_value)::token_type _off_value_cbt;
71};
72
73template<typename OptionList, typename Value, typename... Args>
74default_selection_delegate(OptionList &&, Value &&, Args &&...)
75 -> default_selection_delegate<observable_argument_t<std::remove_cvref_t<Value>>>;
76
77template<typename OptionList, typename Value, typename... Args>
79make_unique_default_selection_delegate(OptionList &&option_list, Value &&value, Args &&...args) noexcept
80{
81 using value_type = observable_argument_t<std::remove_cvref_t<Value>>;
82 return std::make_unique<default_selection_delegate<value_type>>(
83 std::forward<OptionList>(option_list), std::forward<Value>(value), std::forward<Args>(args)...);
84}
85
86} // namespace hi::inline v1
#define hi_forward(x)
Forward a value, based on the decltype of the value.
Definition required.hpp:29
An observable value.
Definition observable.hpp:356
Definition default_selection_delegate.hpp:17
std::pair< std::vector< label >, ptrdiff_t > options_and_selected(selection_widget const &sender) const noexcept override
Retrieve the label of an option.
Definition default_selection_delegate.hpp:49
Definition selection_delegate.hpp:15
A graphical control element that allows the user to choose only one of a predefined set of mutually e...
Definition selection_widget.hpp:37
T move(T... args)
T reserve(T... args)