GCC Code Coverage Report


Directory: src/gate/
File: src/gate/ui/cxx_gateui.cpp
Date: 2025-12-12 23:40:09
Exec Total Coverage
Lines: 146 280 52.1%
Functions: 41 73 56.2%
Branches: 28 156 17.9%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/ui/gateui.hpp"
30 #include "gate/exceptions.hpp"
31
32 namespace gate
33 {
34 namespace ui
35 {
36
37 uint32_t const Input::Key_Alt = GATE_UI_KEY_ALT;
38 uint32_t const Input::Key_Ctrl = GATE_UI_KEY_CTRL;
39 uint32_t const Input::Key_Shift = GATE_UI_KEY_SHIFT;
40
41 uint32_t const Input::Mouse_Left = GATE_UI_MOUSE_LEFT;
42 uint32_t const Input::Mouse_Right = GATE_UI_MOUSE_RIGHT;
43 uint32_t const Input::Mouse_Middle = GATE_UI_MOUSE_MIDDLE;
44
45 ///////////////////////////
46 // //
47 // Host implementation //
48 // //
49 ///////////////////////////
50
51 uint32_t const Host::Color_Background = GATE_UI_COLOR_BACKGROUND;
52 uint32_t const Host::Color_Workspace = GATE_UI_COLOR_WORKSPACE;
53 uint32_t const Host::Color_Window = GATE_UI_COLOR_WINDOW;
54 uint32_t const Host::Color_WindowText = GATE_UI_COLOR_WINDOWTEXT;
55 uint32_t const Host::Color_WindowTextDisabled = GATE_UI_COLOR_WINDOWTEXTDISABLED;
56 uint32_t const Host::Color_Control = GATE_UI_COLOR_CONTROL;
57 uint32_t const Host::Color_ControlText = GATE_UI_COLOR_CONTROLTEXT;
58 uint32_t const Host::Color_ControlTextDisabled = GATE_UI_COLOR_CONTROLTEXTDISABLED;
59 uint32_t const Host::Color_ControlBorderLight = GATE_UI_COLOR_CONTROLBORDERLIGHT;
60 uint32_t const Host::Color_ControlBorderHiLight = GATE_UI_COLOR_CONTROLBORDERHILIGHT;
61 uint32_t const Host::Color_ControlBorderShadow = GATE_UI_COLOR_CONTROLBORDERSHADOW;
62 uint32_t const Host::Color_ControlBorderDarkShadow = GATE_UI_COLOR_CONTROLBORDERDARKSHADOW;
63 uint32_t const Host::Color_MenuBackground = GATE_UI_COLOR_MENUBACKGROUND;
64 uint32_t const Host::Color_MenuText = GATE_UI_COLOR_MENUTEXT;
65 uint32_t const Host::Color_SelectedMenuBackground = GATE_UI_COLOR_SELECTEDMENUBACKGROUND;
66 uint32_t const Host::Color_SelectedMenuText = GATE_UI_COLOR_SELECTEDMENUTEXT;
67
68 uint32_t const Host::FontType_Standard = GATE_UI_FONT_TYPE_STANDARD;
69 uint32_t const Host::FontType_SansSerif = GATE_UI_FONT_TYPE_SANSSERIF;
70 uint32_t const Host::FontType_Serif = GATE_UI_FONT_TYPE_SERIF;
71 uint32_t const Host::FontType_Monospace = GATE_UI_FONT_TYPE_MONOSPACE;
72
73 Host::Host()
74 : ptr(NULL)
75 {
76 }
77
78 1 void Host::init(uintptr_t appHandle)
79 {
80 1 gate_result_t result = gate_ui_host_init(&this->impl, appHandle, this);
81
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATEXX_CHECK_ERROR(result);
82 1 this->ptr = &this->impl;
83 1 }
84
85
86 1 Host::Host(uintptr_t appHandle)
87 1 : ptr(NULL)
88 {
89
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 this->init(appHandle);
90 1 }
91
92 2 Host::~Host() noexcept
93 {
94
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 if (this->ptr)
95 {
96 2 gate_ui_host_uninit(this->ptr);
97 }
98 2 }
99
100 Host& Host::getHost(Control& ctrl)
101 {
102 gate_ui_ctrl_t* ptr_ctrl = ctrl.c_impl();
103 if (!ptr_ctrl)
104 {
105 GATEXX_RAISE_ERROR(results::NullPointer);
106 }
107 gate_ui_host_t* ptr_host = gate_ui_ctrl_get_host(ptr_ctrl);
108 if (!ptr_host)
109 {
110 GATEXX_RAISE_ERROR(results::NullPointer);
111 }
112 return Host::getHost(*ptr_host);
113 }
114
115 Host& Host::getHost(gate_ui_host_t& hostImpl)
116 {
117 void* obj_ptr = gate_ui_host_get_userparam(&hostImpl);
118 if (!obj_ptr)
119 {
120 GATEXX_RAISE_ERROR(results::NullPointer);
121 }
122 return *static_cast<Host*>(obj_ptr);
123 }
124
125
126 1 void Host::run()
127 {
128 1 gate_ui_host_run(this->c_impl());
129 1 }
130
131 1 void Host::quit()
132 {
133 1 gate_ui_host_quit(this->c_impl());
134 1 }
135
136 uint32_t Host::getLineHeight()
137 {
138 return gate_ui_host_default_line_height(this->c_impl());
139 }
140 uint32_t Host::getControlHeight(uint32_t lines)
141 {
142 return gate_ui_host_default_control_height(this->c_impl(), lines);
143 }
144
145 int32_t Host::getUnitLength(real32_t units)
146 {
147 real32_t controlHeight = static_cast<real32_t>(this->getControlHeight());
148 return static_cast<int32_t>(controlHeight * units + (units < 0.0f ? -0.5f : 0.5f));
149 }
150
151
152 Color Host::getDefaultColor(uint32_t colortype)
153 {
154 Color ret;
155 result_t res = gate_ui_host_default_color(this->c_impl(), colortype, &ret.value);
156 GATEXX_CHECK_ERROR(res);
157 return ret;
158 }
159
160 2 Font Host::getDefaultFont(uint32_t fonttype)
161 {
162 2 result_t res = GATE_RESULT_OK;
163 2 Font fnt;
164 2 gate_ui_font_t* ptrfnt = &fnt;
165 2 res = gate_ui_host_default_font(this->c_impl(), fonttype, ptrfnt);
166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATEXX_CHECK_ERROR(res);
167 2 return fnt;
168 }
169 int32_t Host::getPixelsOfPoints(real32_t points)
170 {
171 return gate_ui_host_get_pixels_in_points(this->c_impl(), points);
172 }
173 real32_t Host::getPointsOfPixels(int32_t pixels)
174 {
175 return gate_ui_host_get_points_in_pixels(this->c_impl(), pixels);
176 }
177
178
179 static bool_t gate_ui_host_get_fonts_cb(char const* font_name, void* userparam)
180 {
181 ArrayList<String>* ptr = static_cast<ArrayList<String>*>(userparam);
182 ptr->add(String(font_name));
183 return true;
184 }
185
186 Array<String> Host::getFonts()
187 {
188 ArrayList<String> ret;
189 gate_ui_host_enum_fonts(this->c_impl(), &gate_ui_host_get_fonts_cb, &ret);
190 return ret.toArray();
191 }
192
193
194 String Host::getClipboardText()
195 {
196 gate_string_t text;
197 result_t res = gate_ui_host_clipboard_get_text(this->c_impl(), &text);
198 GATEXX_CHECK_EXCEPTION(res);
199 return String::createFrom(text);
200 }
201 bool Host::getClipboardText(String& text)
202 {
203 gate_string_t str;
204 result_t res = gate_ui_host_clipboard_get_text(this->c_impl(), &str);
205 if (GATE_SUCCEEDED(res))
206 {
207 text = String::createFrom(str);
208 return true;
209 }
210 text = String();
211 return false;
212 }
213
214
215 void Host::setClipboardText(String const& text)
216 {
217 result_t res = gate_ui_host_clipboard_set_text(this->c_impl(), text.c_impl());
218 GATEXX_CHECK_EXCEPTION(res);
219 }
220
221 Position Host::getDefaultWorkarea()
222 {
223 Position ret;
224 result_t result = gate_ui_host_default_workarea(this->c_impl(), &ret);
225 GATEXX_CHECK_ERROR(result);
226 return ret;
227 }
228 Position Host::getTotalWorkarea()
229 {
230 Position ret;
231 result_t result = gate_ui_host_total_workarea(this->c_impl(), &ret);
232 GATEXX_CHECK_ERROR(result);
233 return ret;
234 }
235
236 1 gate_ui_host_t* Host::operator*()
237 {
238 1 return this->ptr;
239 }
240 gate_ui_host_t const* Host::operator*() const
241 {
242 return this->ptr;
243 }
244 8 gate_ui_host_t* Host::c_impl()
245 {
246 8 return this->ptr;
247 }
248 gate_ui_host_t const* Host::c_impl() const
249 {
250 return this->ptr;
251 }
252
253
254
255
256 //////////////////////////////
257 // //
258 // Control implementation //
259 // //
260 //////////////////////////////
261
262 uint32_t const Control::Flag_Enabled = GATE_UI_FLAG_ENABLED;
263 uint32_t const Control::Flag_Visible = GATE_UI_FLAG_VISIBLE;
264 uint32_t const Control::Flag_Resizable = GATE_UI_FLAG_RESIZABLE;
265
266 enumint_t const Control::Action_Activate = GATE_UI_ACTION_ACTIVATE;
267 enumint_t const Control::Action_ContextMenu = GATE_UI_ACTION_CONTEXTMENU;
268
269 88 Control::~Control() noexcept
270 {
271 44 this->destroy();
272 44 }
273
274 16 gate_ui_ctrl_t* Control::operator*() const
275 {
276 16 return this->ctrl;
277 }
278
279
280 28 void Control::destroy() noexcept
281 {
282
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 10 times.
28 if (this->ctrl != NULL)
283 {
284 18 gate_ui_ctrl_destroy(this->ctrl);
285 18 this->ctrl = NULL;
286 }
287 28 }
288
289 203 bool Control::isCreated() const noexcept
290 {
291
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 184 times.
203 if (this->ctrl == NULL)
292 {
293 19 return false;
294 }
295 else
296 {
297 184 return gate_ui_ctrl_is_created(this->ctrl);
298 }
299 }
300 3 bool Control::isEnabled() const
301 {
302 3 return gate_ui_ctrl_is_enabled(this->ctrl);
303 }
304 3 bool Control::isFocused() const
305 {
306 3 return gate_ui_ctrl_is_focused(this->ctrl);
307 }
308 3 bool Control::isVisible() const
309 {
310 3 return gate_ui_ctrl_is_visible(this->ctrl);
311 }
312 3 Position Control::getPosition() const
313 {
314 3 Position pos;
315
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 result_t result = gate_ui_ctrl_get_position(this->ctrl, &pos);
316
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
3 GATEXX_CHECK_ERROR(result);
317 3 return pos;
318 }
319 3 Size Control::getSize() const
320 {
321 3 Size sz;
322
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 result_t result = gate_ui_ctrl_get_size(this->ctrl, &sz);
323
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
3 GATEXX_CHECK_ERROR(result);
324 3 return sz;
325 }
326 uint32_t Control::getTextLength() const
327 {
328 uint32_t ret = 0;
329 result_t result = gate_ui_ctrl_get_text_length(this->ctrl, &ret);
330 GATEXX_CHECK_ERROR(result);
331 return ret;
332 }
333
334 3 String Control::getText() const
335 {
336 gate_string_t str;
337
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 result_t result = gate_ui_ctrl_get_text(this->ctrl, &str);
338
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
3 GATEXX_CHECK_ERROR(result);
339 6 return String::createFrom(str);
340 }
341 2 int32_t Control::getState() const
342 {
343 2 int32_t ret = 0;
344
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 result_t result = gate_ui_ctrl_get_state(this->ctrl, &ret);
345
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2 GATEXX_CHECK_ERROR(result);
346 2 return ret;
347 }
348
349 3 void Control::setEnabled(bool enabled)
350 {
351 3 result_t result = gate_ui_ctrl_set_enabled(this->ctrl, enabled);
352
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATEXX_CHECK_ERROR(result);
353 3 }
354 4 void Control::setVisible(bool visible)
355 {
356 4 result_t result = gate_ui_ctrl_set_visible(this->ctrl, visible);
357
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 GATEXX_CHECK_ERROR(result);
358 4 }
359 3 void Control::setPosition(Point const* position, Size const* size)
360 {
361 3 result_t result = gate_ui_ctrl_set_position(this->ctrl, position, size);
362
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATEXX_CHECK_EXCEPTION(result);
363 3 }
364 3 void Control::setPosition(Position const& pos)
365 {
366 3 Point pnt(pos.pos);
367 3 Size sz(pos.size);
368
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 this->setPosition(&pnt, &sz);
369 3 }
370 void Control::setFocus()
371 {
372 result_t result = gate_ui_ctrl_set_focus(this->ctrl);
373 GATEXX_CHECK_EXCEPTION(result);
374 }
375
376
377
378 3 void Control::setText(String const& text)
379 {
380 3 result_t result = gate_ui_ctrl_set_text(this->ctrl, text.c_impl());
381
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATEXX_CHECK_EXCEPTION(result);
382 3 }
383 2 void Control::setState(int32_t state)
384 {
385 2 result_t result = gate_ui_ctrl_set_state(this->ctrl, state);
386
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATEXX_CHECK_EXCEPTION(result);
387 2 }
388
389 22 Control::Control(gate_ui_ctrl_t* ctrlimpl)
390 22 : ctrl_impl(ctrlimpl), ctrl(NULL)
391 {
392
393 22 }
394 11 gate_ui_ctrl_t* Control::c_impl() const
395 {
396 11 return this->ctrl_impl;
397 }
398
399 26 void Control::attachNativeControl(gate_ui_ctrl_t* ctl)
400 {
401 26 this->ctrl = ctl;
402 26 }
403
404 18 void Control::failIfCreated(char const* sourceFunction)
405 {
406
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
18 if (this->isCreated())
407 {
408 raiseError(results::InvalidState,
409 (sourceFunction == NULL) ? "Control::failIfCreated" : sourceFunction);
410 }
411 18 }
412 163 void Control::failIfNotCreated(char const* sourceFunction)
413 {
414
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 163 times.
163 if (!this->isCreated())
415 {
416 raiseError(results::InvalidState,
417 (sourceFunction == NULL) ? "Control::failIfNotCreated" : sourceFunction);
418 }
419 163 }
420
421
422
423
424 ///////////////////////////////////////
425 // //
426 // ControlContainer implementation //
427 // //
428 ///////////////////////////////////////
429
430 7 ControlContainer::ControlContainer(gate_ui_ctrl_t* ctrlimpl)
431 7 : Control(ctrlimpl)
432 {
433
434 7 }
435 14 ControlContainer::~ControlContainer() noexcept
436 {
437 14 }
438
439 Array<Control*> ControlContainer::getChildren() const
440 {
441 Array<Control*> ret;
442 //TODO
443 return ret;
444 }
445
446 void ControlContainer::setLayout(Layout const* layout)
447 {
448 }
449
450
451
452 /////////////////////////////
453 // Layout implementation //
454 /////////////////////////////
455
456 enumint_t const Layout::Type_Auto = GATE_UI_LAYOUT_TYPE_AUTO;
457 enumint_t const Layout::Type_Pixel = GATE_UI_LAYOUT_TYPE_PIXEL;
458 enumint_t const Layout::Type_Percent = GATE_UI_LAYOUT_TYPE_PERCENT;
459 enumint_t const Layout::Type_UnitScale = GATE_UI_LAYOUT_TYPE_UNITSCALE;
460
461 3 Layout::Layout()
462 {
463 3 result_t result = gate_ui_layout_create(this);
464
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATEXX_CHECK_ERROR(result);
465 3 }
466 6 Layout::~Layout()
467 {
468 3 gate_ui_layout_destroy(this);
469 3 }
470
471 3 void Layout::clear()
472 {
473 3 gate_ui_layout_clear(this);
474 3 }
475
476 6 uint32_t Layout::addColumn(enumint_t type, real32_t value)
477 {
478 6 gate_uint32_t colindex = gate_ui_layout_get_columns(this);
479 6 result_t result = gate_ui_layout_add_column(this, type, value);
480
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 GATEXX_CHECK_ERROR(result);
481 6 return colindex;
482 }
483 6 uint32_t Layout::addRow(enumint_t type, real32_t value)
484 {
485 6 gate_uint32_t rowindex = gate_ui_layout_get_rows(this);
486 6 result_t result = gate_ui_layout_add_row(this, type, value);
487
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 GATEXX_CHECK_ERROR(result);
488 6 return rowindex;
489 }
490
491 1 void Layout::setBorder(uint32_t borderWidth)
492 {
493 1 this->border = borderWidth;
494 1 }
495 1 void Layout::setColumnSpace(uint32_t colSpace)
496 {
497 1 this->colspace = colSpace;
498 1 }
499 1 void Layout::setRowSpace(uint32_t rowSpace)
500 {
501 1 this->rowspace = rowSpace;
502 1 }
503
504
505 10 void Layout::setControl(Control const& ctrl, uint32_t row, uint32_t col, uint32_t rowspan, uint32_t colspan)
506 {
507 10 result_t result = gate_ui_layout_set_control(this, ctrl.c_impl(), row, col, rowspan, colspan);
508
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 GATEXX_CHECK_ERROR(result);
509 10 }
510
511 void Layout::apply(uint32_t unitLength, Position const& pose)
512 {
513 result_t result = gate_ui_layout_apply(this, unitLength, &pose);
514 GATEXX_CHECK_EXCEPTION(result);
515 }
516
517
518 IControlManager::~IControlManager() noexcept
519 {
520 }
521
522 HostControlManager::HostControlManager()
523 {
524
525 }
526
527 HostControlManager::~HostControlManager() noexcept
528 {
529
530 }
531
532 void HostControlManager::createHost(uintptr_t hostHandle)
533 {
534 if (this->uihost.empty())
535 {
536 this->uihost.create();
537 this->uihost->init(hostHandle);
538 }
539 }
540 void HostControlManager::cleanupControls()
541 {
542 for (Enumerator<ControlRef const> iter = this->inactiveControls.enumerate(); iter.valid(); iter.next())
543 {
544 Control& ctrl = *iter->get();
545 if (ctrl.isCreated())
546 {
547 ctrl.destroy();
548 }
549 }
550 this->inactiveControls.clear();
551 }
552
553 void HostControlManager::destroyHost()
554 {
555 this->inactiveControls.addItems(this->activeControls.begin(), this->activeControls.end());
556 this->activeControls.clear();
557 this->cleanupControls();
558
559 this->uihost.reset();
560 }
561
562
563 Host& HostControlManager::getHost()
564 {
565 if (!this->uihost)
566 {
567 GATEXX_RAISE_EXCEPTION(results::NullPointer, "UI host not initialized", 0);
568 }
569 return *this->uihost;
570 }
571
572 void HostControlManager::add(ControlRef ctrl)
573 {
574 this->activeControls.add(ctrl);
575 }
576
577 void HostControlManager::remove(Control& ctrl)
578 {
579 ControlList::iterator it = this->activeControls.begin();
580 ControlList::iterator itend = this->activeControls.end();
581
582 for (; it != itend; ++it)
583 {
584 if (it->get() == &ctrl)
585 {
586 ControlRef selectedCtrl = *it;
587 if (selectedCtrl)
588 {
589 if (selectedCtrl->isCreated())
590 {
591 selectedCtrl->destroy();
592 }
593 this->inactiveControls.add(selectedCtrl);
594 this->activeControls.remove(it);
595 }
596 }
597 }
598 if (this->activeControls.empty() && this->uihost)
599 {
600 this->uihost->quit();
601 }
602 }
603
604 } // end of namespace ui
605 } // end of namespace gate
606