GUIFramework 1.1.0
Framework for desktop GUI applications in C++.
Loading...
Searching...
No Matches
BaseTabControl.cpp
Go to the documentation of this file.
1#include "BaseTabControl.h"
2
4#include "GUIFramework.h"
5
9
10#pragma warning(disable: 26454)
11
12using namespace std;
13
14namespace gui_framework
15{
17
18 tabData::tabData(const wstring& text, const filesystem::path& pathToImage, const function<void()>& callback) :
19 text(text),
20 pathToImage(pathToImage),
21 callback(callback)
22 {
23
24 }
25
26 tabData::tabData(const wstring& text, const filesystem::path& pathToImage, const string& functionName, const string& moduleName) :
27 text(text),
28 pathToImage(pathToImage),
29 functionName(functionName),
30 moduleName(moduleName)
31 {
32 onClickSignature tem = reinterpret_cast<onClickSignature>(GetProcAddress(GUIFramework::get().getModules().at(moduleName), functionName.data()));
33
34 if (!tem)
35 {
36 throw exceptions::CantFindFunctionFromModuleException(functionName, moduleName, __FILE__, __FUNCTION__, __LINE__);
37 }
38
39 callback = tem;
40 }
41
42 LRESULT BaseTabControl::windowMessagesHandle(HWND handle, UINT message, WPARAM wparam, LPARAM lparam, bool& isUsed)
43 {
44 if (message == WM_NOTIFY)
45 {
46 NMHDR* notification = reinterpret_cast<NMHDR*>(lparam);
47
48 if (notification->code == TCN_SELCHANGE)
49 {
50 isUsed = true;
51
52 LRESULT currentTab = this->getSelectedTab();
53
54 if (currentTab != -1)
55 {
56 callbacks[currentTab]();
57 }
58
59 return 0;
60 }
61 }
62
63 isUsed = false;
64
65 return -1;
66 }
67
68 BaseTabControl::BaseTabControl(const wstring& tabControlName, const utility::ComponentSettings& settings, uint16_t imagesWidth, uint16_t imagesHeight, BaseComposite* parent) :
70 (
71 standard_classes::tabControl,
72 tabControlName,
73 settings,
74 styles::DefaultStyles(),
75 parent
76 ),
77 images(imagesWidth, imagesHeight)
78 {
79 SendMessageW(handle, TCM_SETIMAGELIST, NULL, reinterpret_cast<LPARAM>(images.getImageList()));
80 }
81
82 LRESULT BaseTabControl::appendText(const wstring& text, const function<void()>& onClick)
83 {
84 return this->insertText(this->size(), text, onClick);
85 }
86
87 LRESULT BaseTabControl::appendText(const wstring& text, const string& functionName, const string& moduleName)
88 {
89 return this->insertText(this->size(), text, functionName, moduleName);
90 }
91
92 LRESULT BaseTabControl::insertText(size_t index, const wstring& text, const function<void()>& onClick)
93 {
94 TCITEMW item = {};
95
96 item.mask = TCIF_TEXT;
97 item.pszText = const_cast<wchar_t*>(text.data());
98 item.cchTextMax = static_cast<int>(text.size());
99
100 LRESULT result = SendMessageW(handle, TCM_INSERTITEM, index, reinterpret_cast<LPARAM>(&item));
101
102 if (result != -1)
103 {
104 auto it = callbacks.insert(callbacks.begin() + index, onClick);
105
106 tabs.emplace(tabs.begin() + index, text, filesystem::path(), *it);
107 }
108
109 return result;
110 }
111
112 LRESULT BaseTabControl::insertText(size_t index, const wstring& text, const string& functionName, const string& moduleName)
113 {
114 TCITEMW item = {};
115
116 item.mask = TCIF_TEXT;
117 item.pszText = const_cast<wchar_t*>(text.data());
118 item.cchTextMax = static_cast<int>(text.size());
119
120 LRESULT result = SendMessageW(handle, TCM_INSERTITEM, index, reinterpret_cast<LPARAM>(&item));
121
122 if (result != -1)
123 {
124 onClickSignature tem = reinterpret_cast<onClickSignature>(GetProcAddress(GUIFramework::get().getModules().at(moduleName), functionName.data()));
125
126 if (!tem)
127 {
128 throw exceptions::CantFindFunctionFromModuleException(functionName, moduleName, __FILE__, __FUNCTION__, __LINE__);
129 }
130
131 callbacks.insert(callbacks.begin() + index, tem);
132
133 tabs.emplace(tabs.begin() + index, text, filesystem::path(), functionName, moduleName);
134 }
135
136 return result;
137 }
138
139 LRESULT BaseTabControl::appendImage(const filesystem::path& pathToImage, const function<void()>& onClick)
140 {
141 return this->insertImage(this->size(), pathToImage, onClick);
142 }
143
144 LRESULT BaseTabControl::appendImage(const filesystem::path& pathToImage, const string& functionName, const string& moduleName)
145 {
146 return this->insertImage(this->size(), pathToImage, functionName, moduleName);
147 }
148
149 LRESULT BaseTabControl::insertImage(size_t index, const filesystem::path& pathToImage, const function<void()>& onClick)
150 {
151 if (!filesystem::exists(pathToImage))
152 {
153 throw exceptions::FileDoesNotExist(pathToImage, __FILE__, __FUNCTION__, __LINE__);
154 }
155
156 TCITEMW item = {};
157
158 if (!images.contains(pathToImage))
159 {
160 images.addImage(pathToImage);
161 }
162
163 item.mask = TCIF_IMAGE;
164 item.iImage = images[pathToImage];
165
166 LRESULT result = SendMessageW(handle, TCM_INSERTITEM, index, reinterpret_cast<LPARAM>(&item));
167
168 if (result != -1)
169 {
170 auto it = callbacks.insert(callbacks.begin() + index, onClick);
171
172 tabs.emplace(tabs.begin() + index, wstring(), pathToImage, *it);
173 }
174
175 return result;
176 }
177
178 LRESULT BaseTabControl::insertImage(size_t index, const filesystem::path& pathToImage, const string& functionName, const string& moduleName)
179 {
180 if (!filesystem::exists(pathToImage))
181 {
182 throw exceptions::FileDoesNotExist(pathToImage, __FILE__, __FUNCTION__, __LINE__);
183 }
184
185 TCITEMW item = {};
186
187 if (!images.contains(pathToImage))
188 {
189 images.addImage(pathToImage);
190 }
191
192 item.mask = TCIF_IMAGE;
193 item.iImage = images[pathToImage];
194
195 LRESULT result = SendMessageW(handle, TCM_INSERTITEM, index, reinterpret_cast<LPARAM>(&item));
196
197 if (result != -1)
198 {
199 onClickSignature tem = reinterpret_cast<onClickSignature>(GetProcAddress(GUIFramework::get().getModules().at(moduleName), functionName.data()));
200
201 if (!tem)
202 {
203 throw exceptions::CantFindFunctionFromModuleException(functionName, moduleName, __FILE__, __FUNCTION__, __LINE__);
204 }
205
206 callbacks.insert(callbacks.begin() + index, tem);
207
208 tabs.emplace(tabs.begin() + index, wstring(), pathToImage, functionName, moduleName);
209 }
210
211 return result;
212 }
213
214 LRESULT BaseTabControl::appendTextAndImage(const wstring& text, const filesystem::path& pathToImage, const function<void()>& onClick)
215 {
216 return this->insertTextAndImage(this->size(), text, pathToImage, onClick);
217 }
218
219 LRESULT BaseTabControl::appendTextAndImage(const wstring& text, const filesystem::path& pathToImage, const string& functionName, const string& moduleName)
220 {
221 return this->insertTextAndImage(this->size(), text, pathToImage, functionName, moduleName);
222 }
223
224 LRESULT BaseTabControl::insertTextAndImage(size_t index, const wstring& text, const filesystem::path& pathToImage, const function<void()>& onClick)
225 {
226 if (!filesystem::exists(pathToImage))
227 {
228 throw exceptions::FileDoesNotExist(pathToImage, __FILE__, __FUNCTION__, __LINE__);
229 }
230
231 TCITEMW item = {};
232
233 if (!images.contains(pathToImage))
234 {
235 images.addImage(pathToImage);
236 }
237
238 item.mask = TCIF_TEXT | TCIF_IMAGE;
239 item.pszText = const_cast<wchar_t*>(text.data());
240 item.cchTextMax = static_cast<int>(text.size());
241 item.iImage = images[pathToImage];
242
243 LRESULT result = SendMessageW(handle, TCM_INSERTITEM, index, reinterpret_cast<LPARAM>(&item));
244
245 if (result != -1)
246 {
247 auto it = callbacks.insert(callbacks.begin() + index, onClick);
248
249 tabs.emplace(tabs.begin() + index, text, pathToImage, *it);
250 }
251
252 return result;
253 }
254
255 LRESULT BaseTabControl::insertTextAndImage(size_t index, const wstring& text, const filesystem::path& pathToImage, const string& functionName, const string& moduleName)
256 {
257 if (!filesystem::exists(pathToImage))
258 {
259 throw exceptions::FileDoesNotExist(pathToImage, __FILE__, __FUNCTION__, __LINE__);
260 }
261
262 TCITEMW item = {};
263
264 if (!images.contains(pathToImage))
265 {
266 images.addImage(pathToImage);
267 }
268
269 item.mask = TCIF_TEXT | TCIF_IMAGE;
270 item.pszText = const_cast<wchar_t*>(text.data());
271 item.cchTextMax = static_cast<int>(text.size());
272 item.iImage = images[pathToImage];
273
274 LRESULT result = SendMessageW(handle, TCM_INSERTITEM, index, reinterpret_cast<LPARAM>(&item));
275
276 if (result != -1)
277 {
278 onClickSignature tem = reinterpret_cast<onClickSignature>(GetProcAddress(GUIFramework::get().getModules().at(moduleName), functionName.data()));
279
280 if (!tem)
281 {
282 throw exceptions::CantFindFunctionFromModuleException(functionName, moduleName, __FILE__, __FUNCTION__, __LINE__);
283 }
284
285 callbacks.insert(callbacks.begin() + index, tem);
286
287 tabs.emplace(tabs.begin() + index, text, pathToImage, functionName, moduleName);
288 }
289
290 return result;
291 }
292
293 bool BaseTabControl::removeTab(size_t index)
294 {
295 bool result = SendMessageW(handle, TCM_DELETEITEM, static_cast<WPARAM>(index), NULL);
296
297 if (result)
298 {
299 callbacks.erase(callbacks.begin() + index);
300
301 tabs.erase(tabs.begin() + index);
302 }
303
304 return result;
305 }
306
308 {
309 bool result = SendMessageW(handle, TCM_DELETEALLITEMS, NULL, NULL);
310
311 if (result)
312 {
313 callbacks.clear();
314
315 tabs.clear();
316 }
317
318 return result;
319 }
320
321 size_t BaseTabControl::size() const
322 {
323 return SendMessageW(handle, TCM_GETITEMCOUNT, NULL, NULL);
324 }
325
326 bool BaseTabControl::setItem(size_t index, const function<void()>& callback, const wstring& text, const filesystem::path& pathToImage)
327 {
328 if (!pathToImage.empty() && !filesystem::exists(pathToImage))
329 {
330 throw exceptions::FileDoesNotExist(pathToImage, __FILE__, __FUNCTION__, __LINE__);
331 }
332
333 TCITEMW item = {};
334
335 if (text.size())
336 {
337 item.mask |= TCIF_TEXT;
338
339 item.pszText = const_cast<wchar_t*>(text.data());
340 item.cchTextMax = static_cast<int>(text.size());
341 }
342
343 if (!pathToImage.empty())
344 {
345 if (!images.contains(pathToImage))
346 {
347 images.addImage(pathToImage);
348 }
349
350 item.mask |= TCIF_IMAGE;
351
352 item.iImage = images[pathToImage];
353 }
354
355 bool result = SendMessageW(handle, TCM_SETITEM, index, reinterpret_cast<LPARAM>(&item));
356
357 if (result)
358 {
359 callbacks[index] = callback;
360
361 tabs[index] = tabData(text, pathToImage, callback);
362 }
363
364 return result;
365 }
366
367 bool BaseTabControl::setItem(size_t index, const string& functionName, const string& moduleName, const wstring& text, const filesystem::path& pathToImage)
368 {
369 GUIFramework& instance = GUIFramework::get();
370 const HMODULE& module = instance.getModules().at(moduleName);
371
372 onClickSignature tem = reinterpret_cast<onClickSignature>(GetProcAddress(module, functionName.data()));
373
374 if (!tem)
375 {
376 throw exceptions::CantFindFunctionFromModuleException(functionName, moduleName, __FILE__, __FUNCTION__, __LINE__);
377 }
378
379 if (!pathToImage.empty() && !filesystem::exists(pathToImage))
380 {
381 throw exceptions::FileDoesNotExist(pathToImage, __FILE__, __FUNCTION__, __LINE__);
382 }
383
384 TCITEMW item = {};
385
386 if (text.size())
387 {
388 item.mask |= TCIF_TEXT;
389
390 item.pszText = const_cast<wchar_t*>(text.data());
391 item.cchTextMax = static_cast<int>(text.size());
392 }
393
394 if (!pathToImage.empty())
395 {
396 if (!images.contains(pathToImage))
397 {
398 images.addImage(pathToImage);
399 }
400
401 item.mask |= TCIF_IMAGE;
402
403 item.iImage = images[pathToImage];
404 }
405
406 bool result = SendMessageW(handle, TCM_SETITEM, index, reinterpret_cast<LPARAM>(&item));
407
408 if (result)
409 {
410 callbacks[index] = tem;
411
412 tabs[index] = tabData(text, pathToImage, functionName, moduleName);
413 }
414
415 return result;
416 }
417
418 LRESULT BaseTabControl::setSelection(size_t index)
419 {
420 return SendMessageW(handle, TCM_SETCURSEL, static_cast<WPARAM>(index), NULL);
421 }
422
424 {
425 return tabs.at(index);
426 }
427
429 {
430 return SendMessageW(handle, TCM_GETCURSEL, NULL, NULL);
431 }
432
434 {
435 return images.getImagesWidth();
436 }
437
439 {
440 return images.getImagesHeight();
441 }
442
443 void BaseTabControl::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue)
444 {
445 __utility::throwNotImplementedException(__FUNCTION__, "BaseTabControl"sv);
446 }
447
448 void BaseTabControl::setTextColor(uint8_t red, uint8_t green, uint8_t blue)
449 {
450 __utility::throwNotImplementedException(__FUNCTION__, "BaseTabControl"sv);
451 }
452
453 json::JSONBuilder BaseTabControl::getStructure() const
454 {
455 using json::utility::jsonObject;
456
457 json::JSONBuilder builder = BaseComponent::getStructure();
458 jsonObject& current = get<jsonObject>(builder[utility::to_string(windowName, ISerializable::getCodepage())]);
459 vector<jsonObject> jsonTabs;
460
461 current.data.push_back({ "imagesWidth"s, static_cast<uint64_t>(images.getImagesWidth()) });
462
463 current.data.push_back({ "imagesHeight"s, static_cast<uint64_t>(images.getImagesHeight()) });
464
465 auto serializeText = [this](jsonObject& object, const tabData& data)
466 {
467 if (data.text.empty())
468 {
469 return;
470 }
471
472 object.data.push_back({ "tabText"s, utility::to_string(data.text, ISerializable::getCodepage()) });
473 };
474 auto serializePathToImage = [](jsonObject& object, const tabData& data)
475 {
476 if (data.pathToImage.empty())
477 {
478 return;
479 }
480
481 object.data.push_back({ "tabImagePath"s, data.pathToImage.string() });
482 };
483 auto serializeCallback = [](jsonObject& object, const tabData& data)
484 {
485 object.data.push_back({ "functionName"s, data.functionName });
486 object.data.push_back({ "moduleName"s, data.moduleName });
487 object.data.push_back({ "pathToModule"s, GUIFramework::get().getModulesPaths().at(data.moduleName) });
488 };
489
490 for (const auto& i : tabs)
491 {
492 jsonObject object;
493
494 if (i.functionName.size())
495 {
496 serializeText(object, i);
497
498 serializePathToImage(object, i);
499
500 serializeCallback(object, i);
501
502 json::utility::appendArray(move(object), jsonTabs);
503 }
504 else
505 {
506 serializeText(object, i);
507
508 serializePathToImage(object, i);
509
510 json::utility::appendArray(move(object), jsonTabs);
511 }
512 }
513
514 current.data.push_back({ "tabs"s, move(jsonTabs) });
515
516 return builder;
517 }
518}
Base class for all windows, controls, etc.
virtual json::JSONBuilder getStructure() const override
const std::wstring windowName
Base class for all windows that has children windows.
virtual LRESULT insertText(size_t index, const std::wstring &text, const std::function< void()> &onClick) final
virtual json::JSONBuilder getStructure() const override
virtual uint16_t getImagesWidth() const final
virtual bool setItem(size_t index, const std::function< void()> &callback, const std::wstring &text=L"", const std::filesystem::path &pathToImage=L"") final
virtual LRESULT getSelectedTab() const final
virtual const tabData & getItem(size_t index) const final
virtual bool removeTab(size_t index) final
virtual LRESULT setSelection(size_t index) final
virtual LRESULT appendImage(const std::filesystem::path &pathToImage, const std::function< void()> &onClick) final
virtual LRESULT insertTextAndImage(size_t index, const std::wstring &text, const std::filesystem::path &pathToImage, const std::function< void()> &onClick) final
virtual LRESULT insertImage(size_t index, const std::filesystem::path &pathToImage, const std::function< void()> &onClick) final
std::vector< std::function< void()> > callbacks
virtual LRESULT appendText(const std::wstring &text, const std::function< void()> &onClick) final
virtual size_t size() const final
virtual LRESULT appendTextAndImage(const std::wstring &text, const std::filesystem::path &pathToImage, const std::function< void()> &onClick) final
utility::ImagesHolder images
virtual void setTextColor(uint8_t red, uint8_t green, uint8_t blue) final override
Not implemented.
virtual void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) final override
Not implemented.
std::vector< tabData > tabs
virtual uint16_t getImagesHeight() const final
const std::unordered_map< std::string, std::string > & getModulesPaths() const
Get all loaded modules paths.
static GUIFramework & get()
Singleton instance access.
Throws by asset finding methods.
virtual uint16_t getImagesWidth() const final
virtual HIMAGELIST getImageList() const final
virtual uint16_t getImagesHeight() const final
virtual bool contains(const std::filesystem::path &pathToImage) const final
uint16_t addImage(const std::filesystem::path &pathToImage) override
void throwNotImplementedException(string_view methodName, string_view className)
Definition Utility.cpp:186
string to_string(wstring_view stringToConvert, uint32_t codepage)
Definition Utility.cpp:41
void(*)() onClickSignature
Default on click signature.
BaseTabControl::tabData tabData