GUIFramework 1.1.0
Framework for desktop GUI applications in C++.
Loading...
Searching...
No Matches
GUIFramework.cpp
Go to the documentation of this file.
1#include "GUIFramework.h"
2
8
12
15
18
23
27
34
37
41
51#include "Components/RichEdit.h"
58#include "Composites/GroupBox.h"
59
66
69
73
78
82
85
88
92
95
102
104
105#include <TlHelp32.h>
106
107#pragma warning(disable: 6335)
108
109using namespace std;
110
111template<>
112struct hash<set<uint32_t>>
113{
114 size_t operator () (const set<uint32_t>& data);
115};
116
117template<>
118struct less<FILETIME>
119{
120 bool operator()(const FILETIME& left, const FILETIME& right) const
121 {
122 return CompareFileTime(&left, &right) == -1;
123 }
124};
125
126static set<uint32_t> makeHotkey(uint32_t key, const vector<gui_framework::hotkeys::additionalKeys>& additionalKeys);
127
128namespace gui_framework
129{
130 unique_ptr<GUIFramework> GUIFramework::instance = nullptr;
131
133 key(static_cast<uint32_t>(-1))
134 {
135
136 }
137
138 GUIFramework::hotkeyData::hotkeyData(uint32_t key, const function<void()>& hotkeyEvent, const vector<hotkeys::additionalKeys>& additionalKeys) :
139 key(key),
140 hotkeyEvent(hotkeyEvent),
141 additionalKeys(additionalKeys)
142 {
143
144 }
145
146 GUIFramework::hotkeyData::hotkeyData(uint32_t key, const string& functionName, const string& moduleName, const vector<hotkeys::additionalKeys>& additionalKeys) :
147 key(key),
148 functionName(functionName),
149 moduleName(moduleName),
150 additionalKeys(additionalKeys)
151 {
152
153 }
154
155 void GUIFramework::initCreators()
156 {
157 creators.reserve(25);
158
160
162
164
166
168
170
172
174
176
178
179#pragma region ProgressBars
181
183#pragma endregion
184
185#pragma region ComboBoxes
187
189
191#pragma endregion
192
193#pragma region ListBoxes
195
197#pragma endregion
198
199#pragma region ListViews
201
203
205
207
209
211#pragma endregion
212
213#pragma region Trackbars
215
217#pragma endregion
218 }
219
220 void GUIFramework::initDeserializers()
221 {
222 deserializers.reserve(25);
223
225
227
229
231
233
235
237
239
241
243
244#pragma region ProgressBars
246
248#pragma endregion
249
250#pragma region ComboBoxes
252
254
256#pragma endregion
257
258#pragma region ListBoxes
260
262#pragma endregion
263
264#pragma region ListViews
266
268
270
272
274
276#pragma endregion
277
278#pragma region Trackbars
280
282#pragma endregion
283 }
284
285 void GUIFramework::addComponent(BaseComponent* component)
286 {
287 unique_lock<recursive_mutex> lock(componentsMutex);
288
289 components.push_back(component);
290 }
291
292 void GUIFramework::removeComponent(BaseComponent* component)
293 {
294 unique_lock<recursive_mutex> lock(componentsMutex);
295
296 erase(components, component);
297 }
298
299 uint32_t GUIFramework::generateId(wstring_view windowName)
300 {
301 unique_lock<mutex> lock(idMutex);
302
303 uint32_t id;
304
305 if (availableIds.size())
306 {
307 id = availableIds.front();
308
309 availableIds.pop();
310 }
311 else
312 {
313 id = nextId++;
314 }
315
316 generatedIds.insert(make_pair(windowName, id));
317
318 return id;
319 }
320
321 uint32_t GUIFramework::generateTrayId()
322 {
323 return nextTrayId++;
324 }
325
326 void GUIFramework::removeIds(const wstring& windowName)
327 {
328 unique_lock<mutex> lock(idMutex);
329
330 if (!generatedIds.contains(windowName))
331 {
332 return;
333 }
334
335 auto it = generatedIds.equal_range(windowName);
336
337 for_each(it.first, it.second, [this](const pair<wstring, uint32_t>& data) { availableIds.push(generatedIds.extract(data.first).mapped()); });
338 }
339
340 void GUIFramework::removeId(const wstring& windowName, uint32_t id)
341 {
342 unique_lock<mutex> lock(idMutex);
343
344 if (!generatedIds.contains(windowName))
345 {
346 return;
347 }
348
349 auto it = generatedIds.equal_range(windowName);
350
351 for (; it.first != it.second; ++it.first)
352 {
353 if (it.first->second == id)
354 {
355 availableIds.push(generatedIds.extract(it.first).mapped());
356
357 break;
358 }
359 }
360 }
361
362 vector<uint32_t> GUIFramework::getIds(const wstring& windowName)
363 {
364 unique_lock<mutex> lock(idMutex);
365
366 auto resultIterator = generatedIds.equal_range(windowName);
367 vector<uint32_t> result;
368
369 if (resultIterator.first != generatedIds.end())
370 {
371 result.reserve(distance(resultIterator.first, resultIterator.second));
372
373 for_each(resultIterator.first, resultIterator.second, [&result](const pair<wstring, uint32_t>& data) { result.push_back(data.second); });
374 }
375
376 return result;
377 }
378
379 void GUIFramework::processHotkeys() const
380 {
381 static set<const set<uint32_t>*> possibleHotkeys;
382 static constexpr int keyDownBit = 1 << 16;
383
384 possibleHotkeys.clear();
385
386 ranges::for_each(allHotkeys, [](const set<uint32_t>& keys) { possibleHotkeys.insert(&keys); });
387
388 for (const auto& i : allHotkeys)
389 {
390 for (const auto& j : i)
391 {
392 if (!(GetAsyncKeyState(j) & keyDownBit))
393 {
394 possibleHotkeys.erase(&i);
395
396 break;
397 }
398 }
399 }
400
401 if (possibleHotkeys.size())
402 {
403 const set<uint32_t>& hotkey = **possibleHotkeys.begin();
404
405 hotkeys.at(hash<set<uint32_t>>()(hotkey))();
406 }
407 }
408
409 void GUIFramework::initUIThreadId()
410 {
411 HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, NULL);
412 DWORD currentProcessId = GetCurrentProcessId();
413 map<FILETIME, DWORD> threadsCreationTime;
414 THREADENTRY32 threadEntry = {};
415
416 threadEntry.dwSize = sizeof(threadEntry);
417
418 if (Thread32First(handle, &threadEntry))
419 {
420 do
421 {
422 if (threadEntry.th32OwnerProcessID == currentProcessId)
423 {
424 if (HANDLE threadHandle = OpenThread(THREAD_QUERY_INFORMATION, false, threadEntry.th32ThreadID))
425 {
426 FILETIME creationTime;
427 FILETIME exiteTime;
428 FILETIME kernelTime;
429 FILETIME userTime;
430
431 if (GetThreadTimes(threadHandle, &creationTime, &exiteTime, &kernelTime, &userTime))
432 {
433 threadsCreationTime.emplace(move(creationTime), threadEntry.th32ThreadID);
434 }
435 }
436 }
437 } while (Thread32Next(handle, &threadEntry));
438 }
439
440 CloseHandle(handle);
441
442 if (threadsCreationTime.empty())
443 {
444 throw exceptions::CantGetUIThreadId(__FILE__, __FUNCTION__, __LINE__);
445 }
446
447 uiThreadId = threadsCreationTime.begin()->second;
448 }
449
450 void GUIFramework::loadModule(const string& modulePath, const string& moduleName)
451 {
452 try
453 {
454 if (modulePath.empty())
455 {
456 if (!filesystem::exists(moduleName))
457 {
458 throw exceptions::FileDoesNotExist(moduleName, __FILE__, __FUNCTION__, __LINE__);
459 }
460 }
461 else
462 {
463 if (!filesystem::exists(modulePath))
464 {
465 throw exceptions::FileDoesNotExist(modulePath, __FILE__, __FUNCTION__, __LINE__);
466 }
467 }
468 }
469 catch (const exceptions::FileDoesNotExist& e)
470 {
471 unique_lock<mutex> lock(loadModulesMutex);
472
473 cantLoadedModules.push_back(e.what());
474
475 return;
476 }
477
478 HMODULE module = LoadLibraryA
479 (
480 modulePath.empty() ?
481 moduleName.data() :
482 modulePath.data()
483 );
484
485 unique_lock<mutex> lock(loadModulesMutex);
486
487 if (!module)
488 {
489 try
490 {
491 if (modulePath.empty())
492 {
493 throw exceptions::CantLoadModuleException(moduleName, __FILE__, __FUNCTION__, __LINE__);
494 }
495 else
496 {
497 throw exceptions::CantLoadModuleException(modulePath, __FILE__, __FUNCTION__, __LINE__);
498 }
499 }
500 catch (const exceptions::CantLoadModuleException& e)
501 {
502 cantLoadedModules.push_back(e.what());
503 }
504 }
505 else
506 {
507 modules[moduleName] = module;
508
509 modulesPaths[moduleName] = modulePath.empty() ? moduleName : modulePath;
510 }
511 }
512
513 void GUIFramework::loadModulesFromSettings(const json::utility::jsonObject& settingsObject)
514 {
515 const vector<json::utility::jsonObject>& jsonModules = settingsObject.getArray(json_settings::modulesSetting);
516
517 modules.reserve(jsonModules.size());
518
519 for (const json::utility::jsonObject& jsonModule : jsonModules)
520 {
521 const json::utility::jsonObject& moduleObject = std::get<json::utility::jsonObject>(jsonModule.data.front().second);
522 const string& moduleName = moduleObject.getString(json_settings::moduleNameSetting);
523 const string& modulePath = std::get<string>(ranges::find_if
524 (
525 moduleObject.data,
526 [](const pair<string, json::utility::jsonObject::variantType>& value) { return value.first == json_settings::pathToModuleSettings; }
527 )->second);
528
529 {
530 unique_lock<mutex> lock(loadModulesMutex);
531
532 modules.emplace(moduleName, nullptr);
533
534 modulesPaths.emplace(moduleName, "");
535 }
536
537 asyncModulesHandles.push_back
538 (
539 this->addTask
540 (
541 bind(static_cast<void(GUIFramework::*)(const string&, const string&)>(&GUIFramework::loadModule), this, modulePath, moduleName)
542 )
543 );
544 }
545 }
546
547 GUIFramework::GUIFramework() :
548 nextId(1),
549 nextTrayId(custom_window_messages::startTrayId)
550 {
551 if (!filesystem::exists(json_settings::settingsJSONFile))
552 {
553 throw runtime_error(format(R"(File "{}" does not exist)"sv, json_settings::settingsJSONFile));
554 }
555
556 jsonSettings = ifstream(json_settings::settingsJSONFile.data());
557
558 this->initUIThreadId();
559
560 try
561 {
562 int64_t threadsCount = jsonSettings.getInt(json_settings::threadsCountSetting);
563
564 if (threadsCount != -1)
565 {
566 if (threadsCount)
567 {
568 threadPool = make_unique<threading::ThreadPool>(static_cast<uint32_t>(threadsCount));
569 }
570 else
571 {
572 threadPool = make_unique<threading::ThreadPool>();
573 }
574 }
575 }
576 catch (const json::exceptions::CantFindValueException&)
577 {
578
579 }
580
581 InitCommonControlsEx(&comm);
582
583 modules.emplace("MSFT"s, LoadLibraryW(libraries::msftEditLibrary.data()));
584 modules.emplace("", GetModuleHandleW(nullptr));
585
586 const json::utility::jsonObject& settingsObject = jsonSettings.getObject(json_settings::settingsObject);
587
588 try
589 {
591 {
592 this->initCreators();
593 }
594 }
595 catch (const json::exceptions::CantFindValueException&)
596 {
597
598 }
599
600 try
601 {
603 {
604 this->initDeserializers();
605 }
606 }
607 catch (const json::exceptions::CantFindValueException&)
608 {
609
610 }
611
612 try
613 {
614 this->loadModulesFromSettings(settingsObject);
615 }
616 catch (const json::exceptions::CantFindValueException&)
617 {
618
619 }
620 }
621
622 GUIFramework::~GUIFramework()
623 {
624 for (auto& [name, module] : modules)
625 {
626 FreeLibrary(module);
627 }
628 }
629
630 GUIFramework& GUIFramework::GUIFramework::get()
631 {
632 static mutex getInstanceMutex;
633
634 if (!instance)
635 {
636 unique_lock<mutex> lock(getInstanceMutex);
637
638 instance.reset(new GUIFramework());
639 }
640
641 return *instance;
642 }
643
644 void GUIFramework::runOnUIThread(const function<void()>& function)
645 {
646 GUIFramework& instance = GUIFramework::get();
647 unique_lock<recursive_mutex> runOnUIThreadLock(instance.runOnUIThreadMutex);
648
649 instance.runOnUIFunctions.push(function);
650 }
651
652 void GUIFramework::runOnUIThread(function<void()>&& function)
653 {
654 GUIFramework& instance = GUIFramework::get();
655 unique_lock<recursive_mutex> runOnUIThreadLock(instance.runOnUIThreadMutex);
656
657 instance.runOnUIFunctions.push(move(function));
658 }
659
661 {
662 int argc = 0;
663 wchar_t** argv = nullptr;
664 wstring_view commandLine = GetCommandLineW();
665 STARTUPINFO startInfo = {};
666 PROCESS_INFORMATION processInfo = {};
667
668 startInfo.cb = sizeof(startInfo);
669
670 argv = CommandLineToArgvW(commandLine.data(), &argc);
671
672 if (!CreateProcessW
673 (
674 argv[0],
675 const_cast<wchar_t*>(commandLine.data()),
676 nullptr,
677 nullptr,
678 false,
679 NULL,
680 nullptr,
681 nullptr,
682 &startInfo,
683 &processInfo
684 ))
685 {
686 throw gui_framework::exceptions::GetLastErrorException(GetLastError(), __FILE__, __FUNCTION__, __LINE__);
687 }
688
689 exit(exitCode);
690 }
691
693 {
694 return GUIFramework::get().uiThreadId;
695 }
696
698 {
699 string version = "1.1.0";
700
701 return version;
702 }
703
704 unique_ptr<threading::Future> GUIFramework::addTask(const function<void()>& task, const function<void()>& callback)
705 {
706 if (!threadPool)
707 {
708 throw runtime_error("Can't find threadsCount setting in gui_framework.json");
709 }
710
711 return threadPool->addTask(task, callback);
712 }
713
714 unique_ptr<threading::Future> GUIFramework::addTask(const function<void()>& task, function<void()>&& callback)
715 {
716 if (!threadPool)
717 {
718 throw runtime_error("Can't find threadsCount setting in gui_framework.json");
719 }
720
721 return threadPool->addTask(task, move(callback));
722 }
723
724 unique_ptr<threading::Future> GUIFramework::addTask(function<void()>&& task, const function<void()>& callback)
725 {
726 if (!threadPool)
727 {
728 throw runtime_error("Can't find threadsCount setting in gui_framework.json");
729 }
730
731 return threadPool->addTask(move(task), callback);
732 }
733
734 unique_ptr<threading::Future> GUIFramework::addTask(function<void()>&& task, function<void()>&& callback)
735 {
736 if (!threadPool)
737 {
738 throw runtime_error("Can't find threadsCount setting in gui_framework.json");
739 }
740
741 return threadPool->addTask(move(task), move(callback));
742 }
743
744 size_t GUIFramework::registerHotkey(hotkeys::keys key, const function<void()>& onClick, const vector<hotkeys::additionalKeys>& additionalKeys)
745 {
746 set<uint32_t> hotkey = makeHotkey(key, additionalKeys);
747 size_t id = hash<set<uint32_t>>()(hotkey);
748
749 unique_lock<mutex> lock(hotkeyIdMutex);
750
751 hotkeys[id] = onClick;
752
753 allHotkeys.push_back(move(hotkey));
754
755 serializableHotkeysData[id] = hotkeyData(key, onClick, additionalKeys);
756
757 return id;
758 }
759
760 size_t GUIFramework::registerHotkey(hotkeys::keys key, const string& functionName, const string& moduleName, const vector<hotkeys::additionalKeys>& additionalKeys)
761 {
762 onClickSignature tem = nullptr;
763
764 {
765 unique_lock<mutex> lock(loadModulesMutex);
766
767 const HMODULE& module = this->getModules().at(moduleName);
768
769 tem = reinterpret_cast<onClickSignature>(GetProcAddress(module, functionName.data()));
770
771 if (!tem)
772 {
773 throw exceptions::CantFindFunctionFromModuleException(functionName, moduleName, __FILE__, __FUNCTION__, __LINE__);
774 }
775 }
776
777 size_t id = this->registerHotkey(key, tem, additionalKeys);
778
779 {
780 unique_lock<mutex> lock(hotkeyIdMutex);
781
782 serializableHotkeysData[id].functionName = functionName;
783 serializableHotkeysData[id].moduleName = moduleName;
784 }
785
786 return id;
787 }
788
789 bool GUIFramework::unregisterHotkey(size_t hotkeyId)
790 {
791 unique_lock<mutex> lock(hotkeyIdMutex);
792
793 auto it = hotkeys.find(hotkeyId);
794
795 if (it != hotkeys.end())
796 {
797 set<uint32_t> hotkey = makeHotkey(serializableHotkeysData[hotkeyId].key, serializableHotkeysData[hotkeyId].additionalKeys);
798
799 hotkeys.erase(it);
800
801 erase(allHotkeys, hotkey);
802
803 serializableHotkeysData.erase(hotkeyId);
804
805 return true;
806 }
807
808 return false;
809 }
810
811 bool GUIFramework::unregisterHotkey(uint32_t key, const std::vector<hotkeys::additionalKeys>& additionalKeys)
812 {
813 unique_lock<mutex> lock(hotkeyIdMutex);
814
815 set<uint32_t> hotkey = makeHotkey(key, additionalKeys);
816 size_t hotkeyId = hash<set<uint32_t>>()(hotkey);
817 auto it = hotkeys.find(hotkeyId);
818
819 if (it != hotkeys.end())
820 {
821 hotkeys.erase(it);
822
823 erase(allHotkeys, hotkey);
824
825 serializableHotkeysData.erase(hotkeyId);
826
827 return true;
828 }
829
830 return false;
831 }
832
833 vector<GUIFramework::hotkeyData> GUIFramework::getRegisteredHotkeys()
834 {
835 vector<hotkeyData> result;
836
837 result.reserve(serializableHotkeysData.size());
838
839 unique_lock<mutex> lock(hotkeyIdMutex);
840
841 for (const auto& [key, value] : serializableHotkeysData)
842 {
843 result.emplace_back(value);
844 }
845
846 return result;
847 }
848
849 void GUIFramework::loadModule(const string& moduleName, const filesystem::path& pathToModule)
850 {
851 if (!filesystem::exists(pathToModule))
852 {
853 throw exceptions::FileDoesNotExist(moduleName, __FILE__, __FUNCTION__, __LINE__);
854 }
855
856 HMODULE module = LoadLibraryA(pathToModule.string().data());
857
858 if (!module)
859 {
860 throw exceptions::CantLoadModuleException(moduleName, __FILE__, __FUNCTION__, __LINE__);
861 }
862
863 modules.emplace(moduleName, module);
864 }
865
866 void GUIFramework::unloadModule(const string& moduleName)
867 {
868 auto it = modules.find(moduleName);
869
870 if (it == modules.end())
871 {
872 return;
873 }
874
875 FreeLibrary(it->second);
876
877 modules.erase(it);
878 }
879
881 {
882 return ranges::find(components, component) != components.end();
883 }
884
885 vector<json::utility::jsonObject> GUIFramework::serializeHotkeys()
886 {
887 using json::utility::jsonObject;
888
889 unique_lock<mutex> lock(hotkeyIdMutex);
890 vector<jsonObject> result;
891
892 for (const auto& [key, value] : serializableHotkeysData)
893 {
894 if (value.functionName.size())
895 {
896 jsonObject object;
897
898 object.data.push_back({ "key"s, static_cast<uint64_t>(value.key) });
899 object.data.push_back({ "functionName"s, value.functionName });
900 object.data.push_back({ "moduleName"s, value.moduleName });
901 object.data.push_back({ "pathToModule"s, modulesPaths.at(value.moduleName) });
902
903 if (value.additionalKeys.size())
904 {
905 vector<jsonObject> additionalKeys;
906
907 additionalKeys.reserve(value.additionalKeys.size());
908
909 ranges::for_each(value.additionalKeys, [&additionalKeys](const hotkeys::additionalKeys& key) { json::utility::appendArray(static_cast<int64_t>(key), additionalKeys); });
910
911 object.data.push_back({ "additionalKeys"s, move(additionalKeys) });
912 }
913
914 json::utility::appendArray(move(object), result);
915 }
916 }
917
918 return result;
919 }
920
921 void GUIFramework::deserializeHotkeys(const json::utility::jsonObject& description)
922 {
923 using json::utility::jsonObject;
924
925 const auto& jsonHotkeys = description.getArray("hotkeys");
926
927 for (const auto& i : jsonHotkeys)
928 {
929 const jsonObject& hotkey = std::get<jsonObject>(i.data.front().second);
930
931 hotkeys::keys key = static_cast<hotkeys::keys>(hotkey.getUnsignedInt("key"));
932 const string& functionName = hotkey.getString("functionName");
933 const string& moduleName = hotkey.getString("moduleName");
934 vector<uint64_t> tem = json::utility::JSONArrayWrapper(hotkey.getArray("additionalKeys")).getAsUInt64_tArray();
935 vector<hotkeys::additionalKeys> additionalKeys;
936
937 ranges::for_each(tem, [&additionalKeys](uint64_t additionalKey) { additionalKeys.push_back(static_cast<hotkeys::additionalKeys>(additionalKey)); });
938
939 this->registerHotkey(key, functionName, moduleName, additionalKeys);
940 }
941 }
942
944 {
945 // TODO: load check
946
947 return true;
948 }
949
950 void GUIFramework::changeLocalization(const string& language) const
951 {
952 localization::TextLocalization::get().changeLanguage(language);
953 localization::WTextLocalization::get().changeLanguage(language);
954
955 for (const auto& component : components)
956 {
957 if (interfaces::ITextLocalized* localizable = dynamic_cast<interfaces::ITextLocalized*>(component); localizable && localizable->getAutoUpdate())
958 {
959 localizable->updateLocalizationEvent();
960 }
961 }
962 }
963
964 const unordered_map<size_t, smartPointerType<utility::BaseComponentCreator>>& GUIFramework::getCreators() const
965 {
966 return creators;
967 }
968
969 const unordered_map<size_t, smartPointerType<interfaces::IDeserializer>>& GUIFramework::getDeserializers() const
970 {
971 return deserializers;
972 }
973
974 const json::JSONParser& GUIFramework::getJSONSettings() const
975 {
976 return jsonSettings;
977 }
978
979 const unordered_map<string, HMODULE, localization::utility::StringViewHash, localization::utility::StringViewEqual>& GUIFramework::getModules() const
980 {
981 return modules;
982 }
983
984 const unordered_map<string, string>& GUIFramework::getModulesPaths() const
985 {
986 return modulesPaths;
987 }
988
990 {
991 unique_lock<mutex> lock(loadModulesMutex);
992
993 return cantLoadedModules;
994 }
995
996 HMODULE GUIFramework::operator [](const string& moduleName) const
997 {
998 return modules.at(moduleName);
999 }
1000}
1001
1002size_t hash<set<uint32_t>>::operator () (const set<uint32_t>& data)
1003{
1004 if (data.empty())
1005 {
1006 return 0;
1007 }
1008
1009 size_t result = 1;
1010
1011 for (const auto& i : data)
1012 {
1013 result = 31 * result + i;
1014 }
1015
1016 return result;
1017}
1018
1019set<uint32_t> makeHotkey(uint32_t key, const vector<gui_framework::hotkeys::additionalKeys>& additionalKeys)
1020{
1021 set<uint32_t> hotkey;
1022
1023 for_each(additionalKeys.begin(), additionalKeys.end(), [&hotkey](gui_framework::hotkeys::additionalKeys additionalKey) { hotkey.insert(static_cast<uint32_t>(additionalKey)); });
1024
1025 hotkey.insert(key);
1026
1027 return hotkey;
1028}
Base class for all windows, controls, etc.
const std::unordered_map< std::string, std::string > & getModulesPaths() const
Get all loaded modules paths.
std::vector< std::string > getCantLoadedModules()
List of all exceptions in load modules process.
void changeLocalization(const std::string &language) const
Change localization for all components.
void unloadModule(const std::string &moduleName)
Unload module.
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::vector< json::utility::jsonObject > serializeHotkeys()
Serialize hotkeys.
void deserializeHotkeys(const json::utility::jsonObject &description)
Deserialize hotkeys.
const std::unordered_map< std::string, HMODULE, localization::utility::StringViewHash, localization::utility::StringViewEqual > & getModules() const
Get all loaded modules.
void addCreator(Args &&... args)
Add derived from BaseComponentCreator creator.
std::vector< hotkeyData > getRegisteredHotkeys()
Thread safe get hotkeys.
static void runOnUIThread(const std::function< void()> &function)
Run function in UI thread. Functions processed only when window in main UI thread has focus.
bool isExist(BaseComponent *component)
Check if component created. If component destroyed after you call findComponent, you may have not val...
const std::unordered_map< size_t, smartPointerType< utility::BaseComponentCreator > > & getCreators() const
Get all current registered creators.
HMODULE operator[](const std::string &moduleName) const
Get handle to specific module.
const json::JSONParser & getJSONSettings() const
Get settings from gui_framework.json.
const std::unordered_map< size_t, smartPointerType< interfaces::IDeserializer > > & getDeserializers() const
Get all current registered deserializers.
static DWORD getUIThreadId()
Getter for UI thread id.
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 std::string getGUIFrameworkVersion()
Get current GUIFramework version.
static GUIFramework & get()
Singleton instance access.
static void restartApplication(int exitCode=0)
Restart application with given exit code.
bool unregisterHotkey(size_t hotkeyId)
Thread safe unregister hotkey.
void addDeserializer(Args &&... args)
Add derived from IDeserializer deserializer.
bool isModulesLoaded() const
Check if modules are loaded. You can call getCantLoadedModules() to check if loaded modules have fail...
Throws by asset finding methods.
Exception that receive error code from GetLastError function.
Provides changing localization in component by calling GUIFramework::changeLocalization.
constexpr uint32_t startTrayId
Used by GUIFramework and BaseMainWindow internally.
const std::string usingDeserializersSetting
constexpr std::string_view settingsJSONFile
constexpr std::wstring_view msftEditLibrary
void(*)() onClickSignature
Default on click signature.
bool operator()(const FILETIME &left, const FILETIME &right) const