GUIFramework 1.1.0
Framework for desktop GUI applications in C++.
Loading...
Searching...
No Matches
GUIFramework.h
Go to the documentation of this file.
1#pragma once
2
3#include <future>
4#include <shared_mutex>
5#include <mutex>
6#include <algorithm>
7
10#include "Utility/Keys.h"
11#include "StringViewUtils.h"
12
13#pragma comment (lib, "Comctl32.lib")
14#pragma comment (lib, "UxTheme.lib")
15
16#pragma comment (lib, "JSON.lib")
17#pragma comment (lib, "ThreadPool.lib")
18#pragma comment (lib, "Localization.lib")
19
20namespace gui_framework
21{
24 {
25 public:
27 {
28 uint32_t key;
29 std::function<void()> hotkeyEvent;
30 std::string functionName;
31 std::string moduleName;
32 std::vector<hotkeys::additionalKeys> additionalKeys;
33
34 hotkeyData();
35
36 hotkeyData(uint32_t key, const std::function<void()>& hotkeyEvent, const std::vector<hotkeys::additionalKeys>& additionalKeys);
37
38 hotkeyData(uint32_t key, const std::string& functionName, const std::string& moduleName, const std::vector<hotkeys::additionalKeys>& additionalKeys);
39
40 hotkeyData(const hotkeyData&) = default;
41
42 hotkeyData(hotkeyData&&) noexcept = default;
43
44 hotkeyData& operator = (const hotkeyData&) = default;
45
46 hotkeyData& operator = (hotkeyData&&) noexcept = default;
47
48 ~hotkeyData() = default;
49 };
50
51 private:
52 static std::unique_ptr<GUIFramework> instance;
53
54 private:
55 json::JSONParser jsonSettings;
56 std::unique_ptr<threading::ThreadPool> threadPool;
57 INITCOMMONCONTROLSEX comm;
58 std::unordered_map<std::string, HMODULE, localization::utility::StringViewHash, localization::utility::StringViewEqual> modules;
59 std::unordered_map<std::string, std::string> modulesPaths;
60 std::unordered_map<size_t, smartPointerType<utility::BaseComponentCreator>> creators;
61 std::unordered_map<size_t, smartPointerType<interfaces::IDeserializer>> deserializers;
62 DWORD uiThreadId;
63#pragma region Ids
64 std::unordered_multimap<std::wstring, uint32_t> generatedIds;
65 std::queue<uint32_t> availableIds;
66 std::mutex idMutex;
67 uint32_t nextId;
68 std::atomic<uint32_t> nextTrayId;
69#pragma endregion
70#pragma region Hotkeys
71 std::unordered_map<size_t, std::function<void()>> hotkeys;
72 std::vector<std::set<uint32_t>> allHotkeys;
73 std::unordered_map<size_t, hotkeyData> serializableHotkeysData;
74 std::mutex hotkeyIdMutex;
75#pragma endregion
76#pragma region ComponentsFinding
77 std::vector<BaseComponent*> components;
78 std::recursive_mutex componentsMutex;
79#pragma endregion
80#pragma region Modules
81 std::vector<std::unique_ptr<threading::Future>> asyncModulesHandles;
82 std::mutex loadModulesMutex;
83 std::vector<std::string> cantLoadedModules;
84#pragma endregion
85#pragma region RunOnUIThread
86 std::recursive_mutex runOnUIThreadMutex;
87 std::queue<std::function<void()>> runOnUIFunctions;
88#pragma endregion
89
90 private:
91 void initCreators();
92
93 void initDeserializers();
94
95 void addComponent(BaseComponent* component);
96
97 void removeComponent(BaseComponent* component);
98
99 private:
100 uint32_t generateId(std::wstring_view windowName);
101
102 uint32_t generateTrayId();
103
104 void removeIds(const std::wstring& windowName);
105
106 void removeId(const std::wstring& windowName, uint32_t id);
107
108 std::vector<uint32_t> getIds(const std::wstring& windowName);
109
110 void processHotkeys() const;
111
112 void initUIThreadId();
113
114 void loadModule(const std::string& modulePath, const std::string& moduleName);
115
116 void loadModulesFromSettings(const json::utility::jsonObject& settingsObject);
117
118 private:
119 GUIFramework();
120
122
123 public:
128 static GUIFramework& get();
129
132 static void runOnUIThread(const std::function<void()>& function);
133
136 static void runOnUIThread(std::function<void()>&& function);
137
141 static void restartApplication(int exitCode = 0);
142
145 static DWORD getUIThreadId();
146
151 static std::string getGUIFrameworkVersion();
152
153 public:
158 std::unique_ptr<threading::Future> addTask(const std::function<void()>& task, const std::function<void()>& callback = nullptr);
159
164 std::unique_ptr<threading::Future> addTask(const std::function<void()>& task, std::function<void()>&& callback);
165
170 std::unique_ptr<threading::Future> addTask(std::function<void()>&& task, const std::function<void()>& callback = nullptr);
171
176 std::unique_ptr<threading::Future> addTask(std::function<void()>&& task, std::function<void()>&& callback);
177
183 size_t registerHotkey(hotkeys::keys key, const std::function<void()>& onClick, const std::vector<hotkeys::additionalKeys>& additionalKeys = {});
184
193 size_t registerHotkey(hotkeys::keys key, const std::string& functionName, const std::string& moduleName, const std::vector<hotkeys::additionalKeys>& additionalKeys = {});
194
198 bool unregisterHotkey(size_t hotkeyId);
199
204 bool unregisterHotkey(uint32_t key, const std::vector<hotkeys::additionalKeys>& additionalKeys = {});
205
208 std::vector<hotkeyData> getRegisteredHotkeys();
209
215 void loadModule(const std::string& moduleName, const std::filesystem::path& pathToModule);
216
219 void unloadModule(const std::string& moduleName);
220
224 bool isExist(BaseComponent* component);
225
228 std::vector<json::utility::jsonObject> serializeHotkeys();
229
232 void deserializeHotkeys(const json::utility::jsonObject& description);
233
236 bool isModulesLoaded() const;
237
240 void changeLocalization(const std::string& language) const;
241
244 const std::unordered_map<size_t, smartPointerType<utility::BaseComponentCreator>>& getCreators() const;
245
248 const std::unordered_map<size_t, smartPointerType<interfaces::IDeserializer>>& getDeserializers() const;
249
252 const json::JSONParser& getJSONSettings() const;
253
256 const std::unordered_map<std::string, HMODULE, localization::utility::StringViewHash, localization::utility::StringViewEqual>& getModules() const;
257
260 const std::unordered_map<std::string, std::string>& getModulesPaths() const;
261
264 std::vector<std::string> getCantLoadedModules();
265
272 HMODULE operator [](const std::string& moduleName) const;
273
277 template<typename T = BaseComponent>
278 T* findComponent(HWND handle);
279
283 template<typename T = BaseComponent>
284 T* findComponent(const std::wstring& componentName);
285
287 template<std::derived_from<BaseComponent> T, std::derived_from<utility::BaseComponentCreator> CreatorT, typename... Args>
288 void addCreator(Args&&... args);
289
291 template<std::derived_from<BaseComponent> T, std::derived_from<interfaces::IDeserializer> DeserializerT, typename... Args>
292 void addDeserializer(Args&&... args);
293#pragma region FriendClasses
294 friend class BaseComponent;
295 friend class WindowHolder;
296 friend class BaseDialogBox;
297 friend class BaseMainWindow;
298 friend struct std::default_delete<GUIFramework>;
299#pragma endregion
300 };
301
302 template<typename T>
303 T* GUIFramework::findComponent(HWND handle)
304 {
305 std::unique_lock<std::recursive_mutex> lock(componentsMutex);
306
307 auto it = std::ranges::find_if(components, [&handle](BaseComponent* component) { return component->getHandle() == handle; });
308
309 return it == components.end() ? nullptr : dynamic_cast<T*>(*it);
310 }
311
312 template<typename T>
313 T* GUIFramework::findComponent(const std::wstring& componentName)
314 {
315 std::unique_lock<std::recursive_mutex> lock(componentsMutex);
316
317 auto it = std::ranges::find_if(components, [&componentName](BaseComponent* component) { return component->getWindowName() == componentName; });
318
319 return it == components.end() ? nullptr : dynamic_cast<T*>(*it);
320 }
321
322 template<std::derived_from<BaseComponent> T, std::derived_from<utility::BaseComponentCreator> CreatorT, typename... Args>
323 void GUIFramework::addCreator(Args&&... args)
324 {
325 creators[typeid(T).hash_code()] = smartPointerType<CreatorT>(new CreatorT(std::forward<Args>(args)...));
326 }
327
328 template<std::derived_from<BaseComponent> T, std::derived_from<interfaces::IDeserializer> DeserializerT, typename... Args>
329 void GUIFramework::addDeserializer(Args&&... args)
330 {
331 deserializers[typeid(T).hash_code()] = smartPointerType<DeserializerT>(new DeserializerT(std::forward<Args>(args)...));
332 }
333}
#define GUI_FRAMEWORK_API
std::unique_ptr< T > smartPointerType
Compatible smart pointer type.
Base class for all windows, controls, etc.
std::wstring_view getWindowName() const
Base class for all dialog boxes.
Setup for main application window.
Singleton with GUIFramework settings and some functionality.
void loadModule(const std::string &moduleName, const std::filesystem::path &pathToModule)
Load module with some sort of data.
std::unique_ptr< threading::Future > addTask(const std::function< void()> &task, std::function< void()> &&callback)
Add task to thread pool. Thread safe method.
std::unique_ptr< threading::Future > addTask(std::function< void()> &&task, const std::function< void()> &callback=nullptr)
Add task to thread pool. Thread safe method.
size_t registerHotkey(hotkeys::keys key, const std::function< void()> &onClick, const std::vector< hotkeys::additionalKeys > &additionalKeys={})
Only works in thread, that call runMainLoop from WindowHolder. Thread safe register hotkey.
std::unique_ptr< threading::Future > addTask(std::function< void()> &&task, std::function< void()> &&callback)
Add task to thread pool. Thread safe method.
static void runOnUIThread(const std::function< void()> &function)
Run function in UI thread. Functions processed only when window in main UI thread has focus.
std::unique_ptr< threading::Future > addTask(const std::function< void()> &task, const std::function< void()> &callback=nullptr)
Add task to thread pool. Thread safe method.
static void runOnUIThread(std::function< void()> &&function)
Run function in UI thread. Functions processed only when window in main UI thread has focus.
size_t registerHotkey(hotkeys::keys key, const std::string &functionName, const std::string &moduleName, const std::vector< hotkeys::additionalKeys > &additionalKeys={})
Only works in thread, that call runMainLoop from WindowHolder. Thread safe register hotkey.
static GUIFramework & get()
Singleton instance access.
Provides runMainLoop for top level window.
hotkeyData(uint32_t key, const std::string &functionName, const std::string &moduleName, const std::vector< hotkeys::additionalKeys > &additionalKeys)
hotkeyData(const hotkeyData &)=default
std::vector< hotkeys::additionalKeys > additionalKeys
hotkeyData(uint32_t key, const std::function< void()> &hotkeyEvent, const std::vector< hotkeys::additionalKeys > &additionalKeys)
hotkeyData(hotkeyData &&) noexcept=default