forked from microsoft/PowerToys
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsettings_objects.h
222 lines (193 loc) · 9.56 KB
/
settings_objects.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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#pragma once
#include "json.h"
namespace PowerToysSettings
{
class HotkeyObject;
class Settings
{
public:
Settings(
const HINSTANCE hinstance, // Module handle of the PowerToy DLL 'IMAGE_DOS_HEADER __ImageBase'
std::wstring_view powertoy_name);
// Add additional general information to the PowerToy settings.
void set_description(UINT resource_id);
void set_description(std::wstring_view description);
void set_icon_key(std::wstring_view icon_key);
void set_overview_link(std::wstring_view overview_link);
void set_video_link(std::wstring_view video_link);
// Add properties to the PowerToy settings.
void add_bool_toggle(std::wstring_view name, UINT description_resource_id, bool value);
void add_bool_toggle(std::wstring_view name, std::wstring_view description, bool value);
void add_int_spinner(std::wstring_view name, UINT description_resource_id, int value, int min, int max, int step);
void add_int_spinner(std::wstring_view name, std::wstring_view description, int value, int min, int max, int step);
void add_string(std::wstring_view name, UINT description_resource_id, std::wstring_view value);
void add_string(std::wstring_view name, std::wstring_view description, std::wstring_view value);
void add_multiline_string(std::wstring_view name, UINT description_resource_id, std::wstring_view value);
void add_multiline_string(std::wstring_view name, std::wstring_view description, std::wstring_view value);
void add_color_picker(std::wstring_view name, UINT description_resource_id, std::wstring_view value);
void add_color_picker(std::wstring_view name, std::wstring_view description, std::wstring_view value);
void add_hotkey(std::wstring_view name, UINT description_resource_id, const HotkeyObject& hotkey);
void add_hotkey(std::wstring_view name, std::wstring_view description, const HotkeyObject& hotkey);
void add_choice_group(std::wstring_view name, UINT description_resource_id, std::wstring_view value, const std::vector<std::pair<std::wstring, UINT>>& keys_and_text_ids);
void add_choice_group(std::wstring_view name, std::wstring_view description, std::wstring_view value, const std::vector<std::pair<std::wstring, std::wstring>>& keys_and_texts);
void add_dropdown(std::wstring_view name, UINT description_resource_id, std::wstring_view value, const std::vector<std::pair<std::wstring, UINT>>& keys_and_text_ids);
void add_dropdown(std::wstring_view name, std::wstring_view description, std::wstring_view value, const std::vector<std::pair<std::wstring, std::wstring>>& keys_and_texts);
void add_custom_action(std::wstring_view name, UINT description_resource_id, UINT button_text_resource_id, UINT ext_description_resource_id);
void add_custom_action(std::wstring_view name, UINT description_resource_id, UINT button_text_resource_id, std::wstring_view value);
void add_custom_action(std::wstring_view name, std::wstring_view description, std::wstring_view button_text, std::wstring_view value);
void add_header_szLarge(std::wstring_view name, std::wstring_view description, std::wstring_view value);
// Serialize the internal json to a string.
std::wstring serialize();
// Serialize the internal json to the input buffer.
bool serialize_to_buffer(wchar_t* buffer, int* buffer_size);
private:
json::JsonObject m_json;
int m_curr_priority = 0; // For keeping order when adding elements.
HINSTANCE m_instance;
std::wstring get_resource(UINT resource_id);
};
class PowerToyValues
{
public:
PowerToyValues(std::wstring_view powertoy_name);
static PowerToyValues from_json_string(std::wstring_view json);
static PowerToyValues load_from_settings_file(std::wstring_view powertoy_name);
template<typename T>
inline void add_property(std::wstring_view name, T value)
{
json::JsonObject prop_value;
prop_value.SetNamedValue(L"value", json::value(value));
m_json.GetNamedObject(L"properties").SetNamedValue(name, prop_value);
}
std::optional<bool> get_bool_value(std::wstring_view property_name);
std::optional<int> get_int_value(std::wstring_view property_name);
std::optional<std::wstring> get_string_value(std::wstring_view property_name);
std::optional<json::JsonObject> get_json(std::wstring_view property_name);
std::wstring serialize();
void save_to_settings_file();
private:
const std::wstring m_version = L"1.0";
void set_version();
json::JsonObject m_json;
std::wstring _name;
PowerToyValues() {}
};
class CustomActionObject
{
public:
static CustomActionObject from_json_string(std::wstring_view json)
{
return CustomActionObject(json::JsonValue::Parse(json).GetObjectW());
}
std::wstring get_name() { return m_json.GetNamedString(L"action_name").c_str(); }
std::wstring get_value() { return m_json.GetNamedString(L"value").c_str(); }
protected:
CustomActionObject(json::JsonObject action_json) :
m_json(std::move(action_json)){};
json::JsonObject m_json;
};
class HotkeyObject
{
public:
static HotkeyObject from_json(json::JsonObject json)
{
return HotkeyObject(std::move(json));
}
static HotkeyObject from_json_string(std::wstring_view json)
{
return HotkeyObject(json::JsonValue::Parse(json).GetObjectW());
}
static HotkeyObject from_settings(bool win_pressed, bool ctrl_pressed, bool alt_pressed, bool shift_pressed, UINT vk_code)
{
json::JsonObject json;
json.SetNamedValue(L"win", json::value(win_pressed));
json.SetNamedValue(L"ctrl", json::value(ctrl_pressed));
json.SetNamedValue(L"alt", json::value(alt_pressed));
json.SetNamedValue(L"shift", json::value(shift_pressed));
json.SetNamedValue(L"code", json::value(vk_code));
json.SetNamedValue(L"key", json::value(key_from_code(vk_code)));
return std::move(json);
}
const json::JsonObject& get_json() const { return m_json; }
std::wstring get_key() const { return m_json.GetNamedString(L"key").c_str(); }
UINT get_code() const { return static_cast<UINT>(m_json.GetNamedNumber(L"code")); }
bool win_pressed() const { return m_json.GetNamedBoolean(L"win"); }
bool ctrl_pressed() const { return m_json.GetNamedBoolean(L"ctrl"); }
bool alt_pressed() const { return m_json.GetNamedBoolean(L"alt"); }
bool shift_pressed() const { return m_json.GetNamedBoolean(L"shift"); }
UINT get_modifiers_repeat() const
{
return (win_pressed() ? MOD_WIN : 0) |
(ctrl_pressed() ? MOD_CONTROL : 0) |
(alt_pressed() ? MOD_ALT : 0) |
(shift_pressed() ? MOD_SHIFT : 0);
}
UINT get_modifiers() const
{
return get_modifiers_repeat() | MOD_NOREPEAT;
}
protected:
static std::wstring key_from_code(UINT key_code)
{
auto layout = GetKeyboardLayout(0);
auto scan_code = MapVirtualKeyExW(key_code, MAPVK_VK_TO_VSC_EX, layout);
// Determinate if vk is an extended key. Unfortunately MAPVK_VK_TO_VSC_EX
// does not return correct values.
static std::vector<UINT> extended_keys = {
VK_APPS,
VK_CANCEL,
VK_SNAPSHOT,
VK_DIVIDE,
VK_NUMLOCK,
VK_LWIN,
VK_RWIN,
VK_RMENU,
VK_RCONTROL,
VK_RSHIFT,
VK_RETURN,
VK_INSERT,
VK_DELETE,
VK_PRIOR,
VK_NEXT,
VK_HOME,
VK_END,
VK_UP,
VK_DOWN,
VK_LEFT,
VK_RIGHT,
};
if (find(begin(extended_keys), end(extended_keys), key_code) != end(extended_keys))
{
scan_code |= 0x100;
}
std::array<BYTE, 256> key_states{}; // Zero-initialize
std::array<wchar_t, 256> output;
auto output_bytes = ToUnicodeEx(key_code, scan_code, key_states.data(), output.data(), (int)output.size() - 1, 0, layout);
if (output_bytes <= 0)
{
// If ToUnicodeEx fails (e.g. for F1-F12 keys) use GetKeyNameTextW
output_bytes = GetKeyNameTextW(scan_code << 16, output.data(), static_cast<int>(output.size()));
}
if (output_bytes > 0)
{
output[output_bytes] = 0;
if (output_bytes == 1 && output[0] >= 'a' && output[0] <= 'z')
{
// Make Latin letters keys capital, as it looks better
output[0] = toupper(output[0]);
}
return output.data();
}
return L"(Key " + std::to_wstring(key_code) + L")";
}
HotkeyObject(json::JsonObject hotkey_json) :
m_json(std::move(hotkey_json))
{
if (get_key() == L"~" && get_modifiers_repeat() == MOD_WIN)
{
m_json.SetNamedValue(L"key", json::value(key_from_code(get_code())));
}
};
json::JsonObject m_json;
};
}