-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathradio_group.h
134 lines (115 loc) · 3.32 KB
/
radio_group.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/**
* Part of WinLamb - Win32 API Lambda Library
* https://github.com/rodrigocfd/winlamb
* Copyright 2017-present Rodrigo Cesar de Freitas Dias
* This library is released under the MIT License
*/
#pragma once
#include <memory>
#include <vector>
#include "radio.h"
namespace wl {
// Automates a group of native radio buttons.
class radio_group final {
private:
size_t _sz = 0;
std::unique_ptr<radio[]> _items; // vector requires movable object, so we use an ordinary array
public:
radio_group() = default;
radio_group(radio_group&&) = default;
radio_group& operator=(radio_group&&) = default; // movable only
radio_group& assign(HWND hParent, std::initializer_list<int> ctrlIds) {
if (this->_items) {
throw std::logic_error("Trying to assign a radio group twice.");
}
this->_sz = ctrlIds.size();
this->_items = std::make_unique<radio[]>(ctrlIds.size());
size_t i = 0;
for (int ctrlId : ctrlIds) {
this->_items[i++].assign(hParent, ctrlId);
}
this->_items[0].set_check(true) // first is checked by default
.style.first_in_group(true); // and receives WS_GROUP
return *this;
}
radio_group& assign(const wnd* parent, std::initializer_list<int> ctrlIds) {
return this->assign(parent->hwnd(), ctrlIds);
}
size_t size() const noexcept {
return this->_sz;
}
std::vector<int> get_all_ids() const {
std::vector<int> ids;
ids.reserve(this->_sz);
for (size_t i = 0; i < this->_sz; ++i) {
ids.emplace_back(this->_items[i].ctrl_id());
}
return ids;
}
const radio& get_by_pos(size_t index) const {
return this->_items[index];
}
radio& get_by_pos(size_t index) {
return this->_items[index];
}
const radio& get_by_id(int ctrlId) const {
for (size_t i = 0; i < this->_sz; ++i) {
if (this->_items[i].ctrl_id() == ctrlId) {
return this->_items[i];
}
}
throw std::out_of_range("Radio ID doesn't exist.");
}
radio& get_by_id(int ctrlId) {
for (size_t i = 0; i < this->_sz; ++i) {
if (this->_items[i].ctrl_id() == ctrlId) {
return this->_items[i];
}
}
throw std::out_of_range("Radio ID doesn't exist.");
}
radio_group& set_enabled(bool enabled) noexcept {
for (size_t i = 0; i < this->_sz; ++i) {
this->_items[i].set_enabled(enabled);
}
return *this;
}
radio_group& set_checked_by_pos(size_t index) {
for (size_t i = 0; i < this->_sz; ++i) {
if (i != index) {
this->_items[i].set_check(false);
}
}
this->_items[index].set_check_and_trigger(true);
return *this;
}
radio_group& set_checked_by_id(int ctrlId) {
size_t target = -1;
for (size_t i = 0; i < this->_sz; ++i) {
if (this->_items[i].ctrl_id() == ctrlId) {
target = i;
} else {
this->_items[i].set_check(false);
}
}
this->_items[target].set_check_and_trigger(true);
return *this;
}
size_t get_checked_pos() const {
for (size_t i = 0; i < this->_sz; ++i) {
if (this->_items[i].is_checked()) {
return i;
}
}
throw std::logic_error("Radio group has no assigned value.");
}
int get_checked_id() const {
for (size_t i = 0; i < this->_sz; ++i) {
if (this->_items[i].is_checked()) {
return this->_items[i].ctrl_id();
}
}
throw std::logic_error("Radio group has no assigned value.");
}
};
}//namespace wl