olcPixelGameEngine v2.28
The official distribution of olcPixelGameEngine, a tool used in javidx9's YouTube videos and projects
Loading...
Searching...
No Matches
olcPGEX_QuickGUI.h
Go to the documentation of this file.
1/*
2 OneLoneCoder - QuickGUI v1.03
3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 A semi-immediate mode GUI for very simple GUI stuff.
5 Includes:
6 Label - Displays a single-line string
7 TextBox - Click to enter/edit single-line text
8 Button - A clickable labelled rectangle
9 CheckBox - A clickable labelled rectangle that retains state
10 ImageButton - A Button with an image instead of text
11 ImageCheckBox- A CheckBox with an image instead of text
12 Slider - An omnidirectional draggable handle between two values
13 ListBox - A list of strings, that can be scrolled and an item selected
14
15 License (OLC-3)
16 ~~~~~~~~~~~~~~~
17
18 Copyright 2018 - 2024 OneLoneCoder.com
19
20 Redistribution and use in source and binary forms, with or without
21 modification, are permitted provided that the following conditions
22 are met:
23
24 1. Redistributions or derivations of source code must retain the above
25 copyright notice, this list of conditions and the following disclaimer.
26
27 2. Redistributions or derivative works in binary form must reproduce
28 the above copyright notice. This list of conditions and the following
29 disclaimer must be reproduced in the documentation and/or other
30 materials provided with the distribution.
31
32 3. Neither the name of the copyright holder nor the names of its
33 contributors may be used to endorse or promote products derived
34 from this software without specific prior written permission.
35
36 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
37 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
38 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
39 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
40 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
46 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
48 Links
49 ~~~~~
50 YouTube: https://www.youtube.com/javidx9
51 Discord: https://discord.gg/WhwHUMV
52 Twitter: https://www.twitter.com/javidx9
53 Twitch: https://www.twitch.tv/javidx9
54 GitHub: https://www.github.com/onelonecoder
55 Homepage: https://www.onelonecoder.com
56
57 Author
58 ~~~~~~
59 David Barr, aka javidx9, ©OneLoneCoder 2019, 2020, 2021, 2022, 2023, 2024
60
61 Changes
62 ~~~~~~~
63 v1.01 +Moved Slider::fGrabRad into "theme"
64 +Manager::CopyThemeFrom() - copies theme attributes from a different manager
65 +ListBox - Displays a vector of strings
66 v1.02 +ImageButton
67 +ImageCheckBox
68 +ListBox::bSelectionChanged flag, true when list selected item changes
69 =Fix - Text box mouse behaviours, mouse release is now meaningless
70 +CheckBox Fix for decal display
71 v1.03 =Fix ImageCheckBox
72
73*/
74
75#ifndef OLC_PGEX_QUICKGUI_H
76#define OLC_PGEX_QUICKGUI_H
77
78#include "olcPixelGameEngine.h"
79
80
82{
83 class Manager;
84
85 // Virtual base class for all controls
87 {
88 public:
90 virtual ~BaseControl();
91
92 public:
93 // Switches the control on/off
94 void Enable(const bool bEnable);
95 // Sets whether or not the control is interactive/displayed
96 bool bVisible = true;
97
98 // True on single frame control begins being manipulated
99 bool bPressed = false;
100 // True on all frames control is under user manipulation
101 bool bHeld = false;
102 // True on single frame control ceases being manipulated
103 bool bReleased = false;
104
105 public:
106 // Updates the controls behvaiour
107 virtual void Update(olc::PixelGameEngine* pge) = 0;
108 // Draws the control using "sprite" based CPU operations
109 virtual void Draw(olc::PixelGameEngine* pge) = 0;
110 // Draws the control using "decal" based GPU operations
111 virtual void DrawDecal(olc::PixelGameEngine* pge) = 0;
112
113 protected:
114 // Controls are related to a manager, where the theme resides
115 // and control groups can be implemented
117
118 // All controls exists in one of four states
119 // Disabled - Greyed out and not interactive
120 // Normal - interactive and operational
121 // Hover - currently under the users mouse focus
122 // Click - user is interacting with the control
124
125 // To add a "swish" to things, controls can fade between states
126 float m_fTransition = 0.0;
127 };
128
129
130 // A QuickGUI::Manager acts as a convenient grouping of controls
132 {
133 public:
134 // Construct Manager, bCleanUpForMe will automatically DELETE any controls
135 // given to this manager via AddControl() if true
136 Manager(const bool bCleanUpForMe = true);
137 virtual ~Manager();
138
139 public:
140 // Add a gui element derived form BaseControl to this manager
141 void AddControl(BaseControl* control);
142 // Updates all controls this manager operates
144 // Draws as "sprite" all controls this manager operates
146 // Draws as "decal" all controls this manager operates
148
149 public: // This managers "Theme" can be set here
150 // Various element colours
157 // Speed to transiton from Normal -> Hover
158 float fHoverSpeedOn = 10.0f;
159 // Speed to transiton from Hover -> Normal
160 float fHoverSpeedOff = 4.0f;
161 // Size of grab handle
162 float fGrabRad = 8.0f;
163 // Copy all theme attributes into a different manager object
164 void CopyThemeFrom(const Manager& manager);
165
166 private:
167 // Should this manager call delete on the controls it opeerates?
168 bool m_bEraseControlsOnDestroy = true;
169 // Container of controls
170 std::vector<BaseControl*> m_vControls;
171 };
172
173
174 // Creates a Label Control - it's just text!
175 class Label : public BaseControl
176 {
177 public:
178 Label(olc::QuickGUI::Manager& manager, // Associate with a Manager
179 const std::string& text, // Text to display
180 const olc::vf2d& pos, // Location of label top-left
181 const olc::vf2d& size); // Size of label
182
183 public:
184 // Position of button
186 // Size of button
188 // Text displayed on button
189 std::string sText;
190 // Show a border?
191 bool bHasBorder = false;
192 // Show a background?
193 bool bHasBackground = false;
194 // Where should the text be positioned?
197
198 public: // BaseControl overrides
199 void Update(olc::PixelGameEngine* pge) override;
200 void Draw(olc::PixelGameEngine* pge) override;
201 void DrawDecal(olc::PixelGameEngine* pge) override;
202 };
203
204 class TextBox : public Label
205 {
206 public:
207 TextBox(olc::QuickGUI::Manager& manager, // Associate with a Manager
208 const std::string& text, // Text to display
209 const olc::vf2d& pos, // Location of text box top-left
210 const olc::vf2d& size); // Size of text box
211
212 public: // BaseControl overrides
213 void Update(olc::PixelGameEngine* pge) override;
214 void Draw(olc::PixelGameEngine* pge) override;
215 void DrawDecal(olc::PixelGameEngine* pge) override;
216
217 protected:
218 bool m_bTextEdit = false;
219
220 };
221
222 // Creates a Button Control - a clickable, labelled rectangle
223 class Button : public BaseControl
224 {
225 public:
226 Button(olc::QuickGUI::Manager& manager, // Associate with a Manager
227 const std::string& text, // Text to display
228 const olc::vf2d& pos, // Location of button top-left
229 const olc::vf2d& size); // Size of button
230
231 public:
232 // Position of button
234 // Size of button
236 // Text displayed on button
237 std::string sText;
238
239 public: // BaseControl overrides
240 void Update(olc::PixelGameEngine* pge) override;
241 void Draw(olc::PixelGameEngine* pge) override;
242 void DrawDecal(olc::PixelGameEngine* pge) override;
243 };
244
245 // Creates a Button Control - a clickable, labelled rectangle
246 class CheckBox : public Button
247 {
248 public:
249 CheckBox(olc::QuickGUI::Manager& manager, // Associate with a Manager
250 const std::string& text, // Text to display
251 const bool check, // Is checked or not?
252 const olc::vf2d& pos, // Location of button top-left
253 const olc::vf2d& size); // Size of button
254
255 public:
256 bool bChecked = false;
257
258 public: // BaseControl overrides
259 void Update(olc::PixelGameEngine* pge) override;
260 void Draw(olc::PixelGameEngine* pge) override;
261 void DrawDecal(olc::PixelGameEngine* pge) override;
262 };
263
264 class ImageButton : public Button
265 {
266 public:
267 ImageButton(olc::QuickGUI::Manager& manager, // Associate with a Manager
268 const olc::Renderable &icon, // Text to display
269 const olc::vf2d& pos, // Location of button top-left
270 const olc::vf2d& size); // Size of button
271
272 public:
274
275 public:
276 void Draw(olc::PixelGameEngine* pge) override;
277 void DrawDecal(olc::PixelGameEngine* pge) override;
278 };
279
281 {
282 public:
283 ImageCheckBox(olc::QuickGUI::Manager& manager, // Associate with a Manager
284 const olc::Renderable& icon, // Text to display
285 const bool check, // Is checked or not?
286 const olc::vf2d& pos, // Location of button top-left
287 const olc::vf2d& size); // Size of button
288
289 public:
290 bool bChecked = false;
291
292 public:
293 void Update(olc::PixelGameEngine* pge) override;
294 void Draw(olc::PixelGameEngine* pge) override;
295 void DrawDecal(olc::PixelGameEngine* pge) override;
296 };
297
298
299 // Creates a Slider Control - a grabbable handle that slides between two locations
300 class Slider : public BaseControl
301 {
302 public:
303 Slider(olc::QuickGUI::Manager& manager, // Associate with a Manager
304 const olc::vf2d& posmin, // Screen location of "minimum"
305 const olc::vf2d& posmax, // Screen location of "maximum"
306 const float valmin, // Value of minimum
307 const float valmax, // Value of maximum
308 const float value); // Starting value
309
310 public:
311 // Minium value
312 float fMin = -100.0f;
313 // Maximum value
314 float fMax = +100.0f;
315 // Current value
316 float fValue = 0.0f;
317
318 // Location of minimum/start
320 // Location of maximum/end
322
323 public: // BaseControl overrides
324 void Update(olc::PixelGameEngine* pge) override;
325 void Draw(olc::PixelGameEngine* pge) override;
326 void DrawDecal(olc::PixelGameEngine* pge) override;
327 };
328
329
330 class ListBox : public BaseControl
331 {
332 public:
333 ListBox(olc::QuickGUI::Manager& manager, // Associate with a Manager
334 std::vector<std::string>& vList,
335 const olc::vf2d& pos, // Location of list top-left
336 const olc::vf2d& size); // Size of list
337
338 // Position of list
340 // Size of list
342 // Show a border?
343 bool bHasBorder = true;
344 // Show a background?
345 bool bHasBackground = true;
346
347 public:
348 Slider *m_pSlider = nullptr;
350 size_t m_nVisibleItems = 0;
351 std::vector<std::string>& m_vList;
352
353 public:
354 // Item currently selected
355 size_t nSelectedItem = 0;
357 // Has selection changed?
358 bool bSelectionChanged = false;
359
360 public: // BaseControl overrides
361 void Update(olc::PixelGameEngine* pge) override;
362 void Draw(olc::PixelGameEngine* pge) override;
363 void DrawDecal(olc::PixelGameEngine* pge) override;
364 };
365
366
367 class ModalDialog : public olc::PGEX
368 {
369 public:
371
372 public:
373 void ShowFileOpen(const std::string& sPath);
374
375 protected:
376 virtual bool OnBeforeUserUpdate(float& fElapsedTime) override;
377
378 private:
379 bool m_bShowDialog = false;
380
381 Manager m_manFileSelect;
382 ListBox* m_listVolumes = nullptr;
383 ListBox* m_listDirectory = nullptr;
384 ListBox* m_listFiles = nullptr;
385
386 std::vector<std::string> m_vVolumes;
387 std::vector<std::string> m_vDirectory;
388 std::vector<std::string> m_vFiles;
389 std::filesystem::path m_path;
390 };
391}
392
393
394#ifdef OLC_PGEX_QUICKGUI
395#undef OLC_PGEX_QUICKGUI
396namespace olc::QuickGUI
397{
398
399#pragma region BaseControl
400 BaseControl::BaseControl(olc::QuickGUI::Manager& manager) : m_manager(manager)
401 {
402 m_manager.AddControl(this);
403 }
404
406 {
407
408 }
409
410 void BaseControl::Enable(const bool bEnable)
411 {
413 }
414#pragma endregion
415
416#pragma region Manager
417 Manager::Manager(const bool bCleanUpForMe)
418 {
419 m_bEraseControlsOnDestroy = bCleanUpForMe;
420 }
421
423 {
424 if (m_bEraseControlsOnDestroy)
425 for (auto& p : m_vControls)
426 delete p;
427
428 m_vControls.clear();
429 }
430
431 void Manager::AddControl(BaseControl* control)
432 {
433 m_vControls.push_back(control);
434 }
435
437 {
438 for (auto& p : m_vControls) p->Update(pge);
439 }
440
442 {
443 for (auto& p : m_vControls) p->Draw(pge);
444 }
445
447 {
448 for (auto& p : m_vControls) p->DrawDecal(pge);
449 }
450
451 void Manager::CopyThemeFrom(const Manager& manager)
452 {
453 this->colBorder = manager.colBorder;
454 this->colClick = manager.colClick;
455 this->colDisable = manager.colDisable;
456 this->colHover = manager.colHover;
457 this->colNormal = manager.colNormal;
458 this->colText = manager.colText;
459 this->fGrabRad = manager.fGrabRad;
460 this->fHoverSpeedOff = manager.fHoverSpeedOff;
461 this->fHoverSpeedOn = manager.fHoverSpeedOn;
462 }
463#pragma endregion
464
465#pragma region Label
466 Label::Label(olc::QuickGUI::Manager& manager, const std::string& text, const olc::vf2d& pos, const olc::vf2d& size)
467 : BaseControl(manager)
468 {
469 vPos = pos; vSize = size; sText = text;
470 }
471
473 {
474
475 }
476
478 {
479 if (!bVisible)
480 return;
481
482 if (bHasBackground)
483 {
484 pge->FillRect(vPos + olc::vf2d(1, 1), vSize - olc::vf2d(2, 2), m_manager.colNormal);
485 }
486
487 if(bHasBorder)
489
490 olc::vf2d vText = pge->GetTextSizeProp(sText);
491 switch (nAlign)
492 {
493 case Alignment::Left:
494 pge->DrawStringProp(olc::vf2d( vPos.x + 2.0f, vPos.y + (vSize.y - vText.y) * 0.5f ), sText, m_manager.colText);
495 break;
497 pge->DrawStringProp(vPos + (vSize - vText) * 0.5f, sText, m_manager.colText);
498 break;
499 case Alignment::Right:
500 pge->DrawStringProp(olc::vf2d{ vPos.x + vSize.x - vText.x - 2.0f, vPos.y + (vSize.y - vText.y) * 0.5f }, sText, m_manager.colText);
501 break;
502 }
503 }
504
506 {
507 if (!bVisible)
508 return;
509
510 if (bHasBackground)
511 {
513 }
514
515 if (bHasBorder)
516 {
520 }
521
522 olc::vf2d vText = pge->GetTextSizeProp(sText);
523 switch (nAlign)
524 {
525 case Alignment::Left:
526 pge->DrawStringPropDecal({ vPos.x + 2.0f, vPos.y + (vSize.y - vText.y) * 0.5f }, sText, m_manager.colText);
527 break;
529 pge->DrawStringPropDecal(vPos + (vSize - vText) * 0.5f, sText, m_manager.colText);
530 break;
531 case Alignment::Right:
532 pge->DrawStringPropDecal({ vPos.x + vSize.x - vText.x - 2.0f, vPos.y + (vSize.y - vText.y) * 0.5f }, sText, m_manager.colText);
533 break;
534 }
535 }
536#pragma endregion
537
538
539#pragma region TextBox
540 TextBox::TextBox(olc::QuickGUI::Manager& manager, const std::string& text, const olc::vf2d& pos, const olc::vf2d& size)
541 : Label(manager, text, pos, size)
542 {
543 nAlign = Alignment::Left;
544 bHasBorder = true;
545 bHasBackground = false;
546 }
547
549 {
551 return;
552
553 bPressed = false;
554 bReleased = false;
555
556 olc::vf2d vMouse = pge->GetMousePos();
557
558 if (vMouse.x >= vPos.x && vMouse.x < vPos.x + vSize.x &&
559 vMouse.y >= vPos.y && vMouse.y < vPos.y + vSize.y)
560 {
561 // Released inside box does nothing to me, but i may have
562 // to finish off the neighbours... oo err
563 bPressed = pge->GetMouse(olc::Mouse::LEFT).bPressed;
564 bReleased = pge->GetMouse(olc::Mouse::LEFT).bReleased;
565
566 if (bPressed && pge->IsTextEntryEnabled() && !m_bTextEdit)
567 {
568 pge->TextEntryEnable(false);
569 }
570
571
572 if (bPressed && !pge->IsTextEntryEnabled() && !m_bTextEdit)
573 {
574 pge->TextEntryEnable(true, sText);
575 m_bTextEdit = true;
576 }
577
578 bHeld = pge->GetMouse(olc::Mouse::LEFT).bHeld;
579
580
581 }
582 else
583 {
584 // Released outside box
585 bPressed = pge->GetMouse(olc::Mouse::LEFT).bPressed;
586 bReleased = pge->GetMouse(olc::Mouse::LEFT).bReleased;
587 bHeld = pge->GetMouse(olc::Mouse::LEFT).bHeld;
588
589 if (bPressed && m_bTextEdit)
590 {
591 sText = pge->TextEntryGetString();
592 pge->TextEntryEnable(false);
593 m_bTextEdit = false;
594 }
595 }
596
597 if (m_bTextEdit && pge->IsTextEntryEnabled())
598 sText = pge->TextEntryGetString();
599 }
600
602 {
603 if (!bVisible)
604 return;
605
606 if (bHasBackground)
607 {
608 pge->FillRect(vPos + olc::vf2d(1, 1), vSize - olc::vf2d(2, 2), m_manager.colNormal);
609 }
610
611 if (bHasBorder)
613
614 if (m_bTextEdit && pge->IsTextEntryEnabled())
615 {
616 // Draw Cursor
617 int32_t i = pge->TextEntryGetCursor();
618 olc::vf2d vCursorPos = pge->GetTextSizeProp(sText.substr(0, i));
619 pge->FillRect(olc::vf2d(vPos.x + 2.0f + vCursorPos.x, (vPos.y + (vSize.y - 10.0f) * 0.5f)), { 2, 10 }, m_manager.colText);
620 }
621
622 // Draw Text
623 olc::vf2d vText = pge->GetTextSizeProp(sText);
624 pge->DrawStringProp(olc::vf2d(vPos.x + 2.0f, vPos.y + (vSize.y - vText.y) * 0.5f), sText, m_manager.colText);
625
626 }
627
629 {
630 if (!bVisible)
631 return;
632
633 if (bHasBackground)
634 {
636 }
637
638 if (bHasBorder)
639 {
643 }
644
645 if (m_bTextEdit && pge->IsTextEntryEnabled())
646 {
647 // Draw Cursor
648 int32_t i = pge->TextEntryGetCursor();
649 olc::vf2d vCursorPos = pge->GetTextSizeProp(sText.substr(0, i));
650 pge->FillRectDecal(olc::vf2d(vPos.x + 2.0f + vCursorPos.x, (vPos.y + (vSize.y - 10.0f) * 0.5f)), { 2, 10 }, m_manager.colText);
651 }
652
653 // Draw Text
654 olc::vf2d vText = pge->GetTextSizeProp(sText);
655 pge->DrawStringPropDecal(olc::vf2d(vPos.x + 2.0f, vPos.y + (vSize.y - vText.y) * 0.5f), sText, m_manager.colText);
656 }
657#pragma endregion
658
659#pragma region Button
660 Button::Button(olc::QuickGUI::Manager& manager, const std::string& text, const olc::vf2d& pos, const olc::vf2d& size)
661 : BaseControl(manager)
662 {
663 vPos = pos; vSize = size; sText = text;
664 }
665
667 {
669 return;
670
671 bPressed = false;
672 bReleased = false;
673 float fElapsedTime = pge->GetElapsedTime();
674
675 olc::vf2d vMouse = pge->GetMousePos();
676 if (m_state != State::Click)
677 {
678 if (vMouse.x >= vPos.x && vMouse.x < vPos.x + vSize.x &&
679 vMouse.y >= vPos.y && vMouse.y < vPos.y + vSize.y)
680 {
681 m_fTransition += fElapsedTime * m_manager.fHoverSpeedOn;
683
684 bPressed = pge->GetMouse(olc::Mouse::LEFT).bPressed;
685 if (bPressed)
686 {
688 }
689
690 bHeld = pge->GetMouse(olc::Mouse::LEFT).bHeld;
691 }
692 else
693 {
694 m_fTransition -= fElapsedTime * m_manager.fHoverSpeedOff;
696 }
697 }
698 else
699 {
700 bHeld = pge->GetMouse(olc::Mouse::LEFT).bHeld;
701 bReleased = pge->GetMouse(olc::Mouse::LEFT).bReleased;
703 }
704
705 m_fTransition = std::clamp(m_fTransition, 0.0f, 1.0f);
706 }
707
709 {
710 if (!bVisible)
711 return;
712
713 switch (m_state)
714 {
715 case State::Disabled:
717 break;
718 case State::Normal:
719 case State::Hover:
721 break;
722 case State::Click:
724 break;
725 }
726
728 olc::vf2d vText = pge->GetTextSizeProp(sText);
729 pge->DrawStringProp(vPos + (vSize - vText) * 0.5f, sText, m_manager.colText);
730 }
731
733 {
734 if (!bVisible)
735 return;
736
737 switch (m_state)
738 {
739 case State::Disabled:
741 break;
742 case State::Normal:
743 case State::Hover:
745 break;
746 case State::Click:
748 break;
749 }
753
754 olc::vf2d vText = pge->GetTextSizeProp(sText);
755 pge->DrawStringPropDecal(vPos + (vSize - vText) * 0.5f, sText, m_manager.colText);
756 }
757#pragma endregion
758
759
760#pragma region ImageButton
761 ImageButton::ImageButton(olc::QuickGUI::Manager& manager, const olc::Renderable& icon, const olc::vf2d& pos, const olc::vf2d& size)
762 : Button(manager, "", pos, size), pIcon(icon)
763 {
764
765 }
766
768 {
769 Button::Draw(pge);
770 pge->DrawSprite(vPos + olc::vi2d(4, 4), pIcon.Sprite());
771 }
772
774 {
776 pge->DrawDecal(vPos + olc::vi2d(4, 4), pIcon.Decal());
777 }
778#pragma endregion
779
780
781#pragma region ImageCheckBox
782 ImageCheckBox::ImageCheckBox(olc::QuickGUI::Manager& manager, const olc::Renderable& gfx, const bool check, const olc::vf2d& pos, const olc::vf2d& size)
783 : ImageButton(manager, gfx, pos, size)
784 {
785 bChecked = check;
786 }
787
789 {
791 return;
792
794 if (bPressed) bChecked = !bChecked;
795 }
796
798 {
800
801 if (bChecked)
802 pge->DrawRect(vPos + olc::vf2d(2, 2), vSize - olc::vi2d(5, 5), m_manager.colBorder);
803 }
804
806 {
807 if (!bVisible)
808 return;
809
811
812 if (bChecked)
813 {
815 pge->DrawDecal(vPos + olc::vi2d(4, 4), pIcon.Decal());
816 }
817
821
822 olc::vf2d vText = pge->GetTextSizeProp(sText);
823 pge->DrawStringPropDecal(vPos + (vSize - vText) * 0.5f, sText, m_manager.colText);
824 }
825#pragma endregion
826
827
828#pragma region CheckBox
829 CheckBox::CheckBox(olc::QuickGUI::Manager& manager, const std::string& text, const bool check, const olc::vf2d& pos, const olc::vf2d& size)
830 : Button(manager, text, pos, size)
831 {
832 bChecked = check;
833 }
834
836 {
838 return;
839
840 Button::Update(pge);
841 if (bPressed)
843 }
844
846 {
847 if (!bVisible)
848 return;
849
850 Button::Draw(pge);
851
852 if (bChecked)
853 pge->DrawRect(vPos + olc::vf2d(2, 2), vSize - olc::vi2d(5, 5), m_manager.colBorder);
854 }
855
857 {
858 if (!bVisible)
859 return;
860
862
863 if (bChecked)
864 {
868 }
869
870 olc::vf2d vText = pge->GetTextSizeProp(sText);
871 pge->DrawStringPropDecal(vPos + (vSize - vText) * 0.5f, sText, m_manager.colText);
872 }
873#pragma endregion
874
875#pragma region Slider
876 Slider::Slider(olc::QuickGUI::Manager& manager, const olc::vf2d& posmin, const olc::vf2d& posmax, const float valmin, const float valmax, const float value)
877 : BaseControl(manager)
878 {
879 vPosMin = posmin; vPosMax = posmax; fMin = valmin; fMax = valmax; fValue = value;
880 }
881
883 {
885 return;
886
887 float fElapsedTime = pge->GetElapsedTime();
888
889 olc::vf2d vMouse = pge->GetMousePos();
890 bHeld = false;
891 if (m_state == State::Click)
892 {
894 float u = d.dot(vMouse - vPosMin) / d.mag2();
895 fValue = u * (fMax - fMin) + fMin;
896 bHeld = true;
897 }
898 else
899 {
900 olc::vf2d vSliderPos = vPosMin + (vPosMax - vPosMin) * ((fValue - fMin) / (fMax - fMin));
901 if ((vMouse - vSliderPos).mag2() <= int32_t(m_manager.fGrabRad) * int32_t(m_manager.fGrabRad))
902 {
903 m_fTransition += fElapsedTime * m_manager.fHoverSpeedOn;
905 if (pge->GetMouse(olc::Mouse::LEFT).bPressed)
906 {
908 bPressed = true;
909 }
910 }
911 else
913 }
914
915 if (pge->GetMouse(olc::Mouse::LEFT).bReleased)
916 {
918 bReleased = true;
919 }
920
921 if (m_state == State::Normal)
922 {
923 m_fTransition -= fElapsedTime * m_manager.fHoverSpeedOff;
925 bHeld = false;
926 }
927
928 fValue = std::clamp(fValue, fMin, fMax);
929 m_fTransition = std::clamp(m_fTransition, 0.0f, 1.0f);
930 }
931
933 {
934 if (!bVisible)
935 return;
936
938 olc::vf2d vSliderPos = vPosMin + (vPosMax - vPosMin) * ((fValue - fMin) / (fMax - fMin));
939
940 switch (m_state)
941 {
942 case State::Disabled:
943 pge->FillCircle(vSliderPos, int32_t(m_manager.fGrabRad), m_manager.colDisable);
944 break;
945 case State::Normal:
946 case State::Hover:
948 break;
949 case State::Click:
950 pge->FillCircle(vSliderPos, int32_t(m_manager.fGrabRad), m_manager.colClick);
951 break;
952 }
953
954
955 pge->DrawCircle(vSliderPos, int32_t(m_manager.fGrabRad), m_manager.colBorder);
956 }
957
959 {
960 if (!bVisible)
961 return;
962
964 olc::vf2d vSliderPos = vPosMin + (vPosMax - vPosMin) * ((fValue - fMin) / (fMax - fMin));
965
966 switch (m_state)
967 {
968 case State::Disabled:
970 break;
971 case State::Normal:
972 case State::Hover:
974 break;
975 case State::Click:
977 break;
978 }
979
983 }
984
985
986#pragma endregion
987
988#pragma region ListBox
989 ListBox::ListBox(olc::QuickGUI::Manager& manager, std::vector<std::string>& vList, const olc::vf2d& pos, const olc::vf2d& size)
990 : BaseControl(manager), m_vList(vList)
991 {
992 m_group.CopyThemeFrom(m_manager);
993 vPos = pos;
994 vSize = size;
995 m_pSlider = new Slider(m_group, { pos.x + size.x - m_manager.fGrabRad - 1, pos.y + m_manager.fGrabRad + 1 },
996 { pos.x + size.x - m_manager.fGrabRad - 1, pos.y + size.y - m_manager.fGrabRad - 1 }, 0, float(m_vList.size()), 0);
997 }
998
1000 {
1001 if (m_state == State::Disabled || !bVisible)
1002 return;
1003
1004
1006 olc::vf2d vMouse = pge->GetMousePos() - vPos + olc::vi2d(2,0);
1007 if (pge->GetMouse(olc::Mouse::LEFT).bPressed)
1008 {
1009 if (vMouse.x >= 0 && vMouse.x < vSize.x - (m_group.fGrabRad * 2) && vMouse.y >= 0 && vMouse.y < vSize.y)
1010 {
1011
1012 nSelectedItem = size_t(m_pSlider->fValue + vMouse.y / 10);
1013 }
1014 }
1015
1016 nSelectedItem = std::clamp(nSelectedItem, size_t(0), m_vList.size()-1);
1017
1019
1020
1021 m_pSlider->fMax = float(m_vList.size());
1022 m_group.Update(pge);
1023 }
1024
1026 {
1027 if (!bVisible)
1028 return;
1029
1030 if (bHasBackground)
1031 {
1032 pge->FillRect(vPos + olc::vf2d(1, 1), vSize - olc::vf2d(2, 2), m_manager.colNormal);
1033 }
1034
1035 if (bHasBorder)
1037
1038
1039 size_t idx0 = size_t(m_pSlider->fValue);
1040 size_t idx1 = std::min(idx0 + size_t((vSize.y - 4) / 10), m_vList.size());
1041
1042 olc::vf2d vTextPos = vPos + olc::vf2d(2,2);
1043 for (size_t idx = idx0; idx < idx1; idx++)
1044 {
1045 if (idx == nSelectedItem)
1046 pge->FillRect(vTextPos - olc::vi2d(1,1), {int32_t(vSize.x - m_group.fGrabRad * 2), 10}, m_group.colHover);
1047 pge->DrawStringProp(vTextPos, m_vList[idx]);
1048 vTextPos.y += 10;
1049 }
1050
1051 m_group.Draw(pge);
1052 }
1053
1055 {
1056 if (!bVisible)
1057 return;
1058
1059 if (bHasBackground)
1061
1062 size_t idx0 = size_t(m_pSlider->fValue);
1063 size_t idx1 = std::min(idx0 + size_t((vSize.y - 4) / 10), m_vList.size());
1064
1065 olc::vf2d vTextPos = vPos + olc::vf2d(2, 2);
1066 for (size_t idx = idx0; idx < idx1; idx++)
1067 {
1068 if (idx == nSelectedItem)
1069 pge->FillRectDecal(vTextPos - olc::vi2d(1, 1), { vSize.x - m_group.fGrabRad * 2.0f, 10.0f }, m_group.colHover);
1070 pge->DrawStringPropDecal(vTextPos, m_vList[idx]);
1071 vTextPos.y += 10;
1072 }
1073
1074 if (bHasBorder)
1075 {
1079 }
1080
1081 m_group.DrawDecal(pge);
1082 }
1083#pragma endregion
1084
1085
1086
1087#pragma region Modal
1088 ModalDialog::ModalDialog() : olc::PGEX(true)
1089 {
1090
1091 // Create File Open Dialog
1092 olc::vi2d vScreenSize = pge->GetScreenSize();
1093
1094 m_listDirectory = new ListBox(m_manFileSelect, m_vDirectory, olc::vf2d(20, 20), olc::vf2d(300, 500));
1095 m_listFiles = new ListBox(m_manFileSelect, m_vFiles, olc::vf2d(330, 20), olc::vf2d(300, 500));
1096
1097 m_path = "/";
1098 for (auto const& dir_entry : std::filesystem::directory_iterator{ m_path })
1099 {
1100 if(dir_entry.is_directory())
1101 m_vDirectory.push_back(dir_entry.path().filename().string());
1102 else
1103 m_vFiles.push_back(dir_entry.path().filename().string());
1104 }
1105 }
1106
1107 void ModalDialog::ShowFileOpen(const std::string& sPath)
1108 {
1109 m_bShowDialog = true;
1110 }
1111
1112 bool ModalDialog::OnBeforeUserUpdate(float& fElapsedTime)
1113 {
1114 if(!m_bShowDialog) return false;
1115
1116 m_manFileSelect.Update(this->pge);
1117
1119 {
1120 m_path = m_path.parent_path().string() + "/";
1121 //m_listDirectory->bSelectionChanged = true;
1122 //m_listDirectory->nSelectedItem = 0;
1123 }
1124
1125 if (m_listDirectory->bSelectionChanged)
1126 {
1127 std::string sDirectory = m_vDirectory[m_listDirectory->nSelectedItem];
1128 /*if (sDirectory == "..")
1129 m_path = m_path.parent_path().string() + "/";
1130 else
1131 m_path += sDirectory+ "/";*/
1132
1133
1134 m_path += sDirectory + "/";
1135 // Reconstruct Lists
1136 m_vDirectory.clear();
1137
1138 m_vFiles.clear();
1139
1140
1141 for (auto const& dir_entry : std::filesystem::directory_iterator{ m_path })
1142 {
1143 if (dir_entry.is_directory() || dir_entry.is_other())
1144 m_vDirectory.push_back(dir_entry.path().filename().string());
1145 else
1146 m_vFiles.push_back(dir_entry.path().filename().string());
1147 }
1148
1149 //m_vDirectory.push_back("..");
1150
1151 //m_listFiles->nSelectedItem = 0;
1152 //m_listDirectory->nSelectedItem = 0;
1153
1154 }
1155
1156 pge->DrawStringDecal({ 0,0 }, m_path.string());
1157
1158
1159
1160
1161 m_manFileSelect.DrawDecal(this->pge);
1162
1163
1164
1166 {
1167 m_bShowDialog = false;
1168 return false;
1169 }
1170
1171 return true;
1172 }
1173#pragma endregion
1174
1175}
1176#endif // OLC_PGEX_QUICKGUI
1177#endif // OLC_PGEX_QUICKGUI_H
Definition olcPixelGameEngine.h:1615
static PixelGameEngine * pge
Definition olcPixelGameEngine.h:1627
Definition olcPixelGameEngine.h:1225
void FillRectDecal(const olc::vf2d &pos, const olc::vf2d &size, const olc::Pixel col=olc::WHITE)
void DrawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, Pixel p=olc::WHITE, uint32_t pattern=0xFFFFFFFF)
void DrawStringProp(int32_t x, int32_t y, const std::string &sText, Pixel col=olc::WHITE, uint32_t scale=1)
void DrawRect(int32_t x, int32_t y, int32_t w, int32_t h, Pixel p=olc::WHITE)
HWButton GetKey(Key k) const
void SetDecalMode(const olc::DecalMode &mode)
void DrawCircle(int32_t x, int32_t y, int32_t radius, Pixel p=olc::WHITE, uint8_t mask=0xFF)
int32_t TextEntryGetCursor() const
void FillCircle(int32_t x, int32_t y, int32_t radius, Pixel p=olc::WHITE)
void TextEntryEnable(const bool bEnable, const std::string &sText="")
const olc::vi2d & GetScreenSize() const
void DrawDecal(const olc::vf2d &pos, olc::Decal *decal, const olc::vf2d &scale={ 1.0f, 1.0f }, const olc::Pixel &tint=olc::WHITE)
void DrawSprite(int32_t x, int32_t y, Sprite *sprite, uint32_t scale=1, uint8_t flip=olc::Sprite::NONE)
void DrawStringDecal(const olc::vf2d &pos, const std::string &sText, const Pixel col=olc::WHITE, const olc::vf2d &scale={ 1.0f, 1.0f })
void FillRect(int32_t x, int32_t y, int32_t w, int32_t h, Pixel p=olc::WHITE)
void DrawStringPropDecal(const olc::vf2d &pos, const std::string &sText, const Pixel col=olc::WHITE, const olc::vf2d &scale={ 1.0f, 1.0f })
const olc::vi2d & GetMousePos() const
void DrawLineDecal(const olc::vf2d &pos1, const olc::vf2d &pos2, Pixel p=olc::WHITE)
olc::vi2d GetTextSizeProp(const std::string &s)
std::string TextEntryGetString() const
bool IsTextEntryEnabled() const
HWButton GetMouse(uint32_t b) const
float GetElapsedTime() const
Definition olcPGEX_QuickGUI.h:87
float m_fTransition
Definition olcPGEX_QuickGUI.h:126
virtual void DrawDecal(olc::PixelGameEngine *pge)=0
olc::QuickGUI::Manager & m_manager
Definition olcPGEX_QuickGUI.h:116
State
Definition olcPGEX_QuickGUI.h:123
bool bHeld
Definition olcPGEX_QuickGUI.h:101
bool bVisible
Definition olcPGEX_QuickGUI.h:96
bool bReleased
Definition olcPGEX_QuickGUI.h:103
BaseControl(olc::QuickGUI::Manager &manager)
virtual void Draw(olc::PixelGameEngine *pge)=0
enum olc::QuickGUI::BaseControl::State m_state
virtual void Update(olc::PixelGameEngine *pge)=0
bool bPressed
Definition olcPGEX_QuickGUI.h:99
void Enable(const bool bEnable)
Definition olcPGEX_QuickGUI.h:224
Button(olc::QuickGUI::Manager &manager, const std::string &text, const olc::vf2d &pos, const olc::vf2d &size)
void Draw(olc::PixelGameEngine *pge) override
void DrawDecal(olc::PixelGameEngine *pge) override
std::string sText
Definition olcPGEX_QuickGUI.h:237
olc::vf2d vPos
Definition olcPGEX_QuickGUI.h:233
olc::vf2d vSize
Definition olcPGEX_QuickGUI.h:235
void Update(olc::PixelGameEngine *pge) override
Definition olcPGEX_QuickGUI.h:247
void Update(olc::PixelGameEngine *pge) override
bool bChecked
Definition olcPGEX_QuickGUI.h:256
CheckBox(olc::QuickGUI::Manager &manager, const std::string &text, const bool check, const olc::vf2d &pos, const olc::vf2d &size)
void Draw(olc::PixelGameEngine *pge) override
void DrawDecal(olc::PixelGameEngine *pge) override
Definition olcPGEX_QuickGUI.h:265
void DrawDecal(olc::PixelGameEngine *pge) override
ImageButton(olc::QuickGUI::Manager &manager, const olc::Renderable &icon, const olc::vf2d &pos, const olc::vf2d &size)
void Draw(olc::PixelGameEngine *pge) override
const olc::Renderable & pIcon
Definition olcPGEX_QuickGUI.h:273
Definition olcPGEX_QuickGUI.h:281
void Draw(olc::PixelGameEngine *pge) override
void Update(olc::PixelGameEngine *pge) override
ImageCheckBox(olc::QuickGUI::Manager &manager, const olc::Renderable &icon, const bool check, const olc::vf2d &pos, const olc::vf2d &size)
void DrawDecal(olc::PixelGameEngine *pge) override
bool bChecked
Definition olcPGEX_QuickGUI.h:290
Definition olcPGEX_QuickGUI.h:176
olc::vf2d vSize
Definition olcPGEX_QuickGUI.h:187
enum olc::QuickGUI::Label::Alignment nAlign
olc::vf2d vPos
Definition olcPGEX_QuickGUI.h:185
std::string sText
Definition olcPGEX_QuickGUI.h:189
Alignment
Definition olcPGEX_QuickGUI.h:196
void Draw(olc::PixelGameEngine *pge) override
bool bHasBorder
Definition olcPGEX_QuickGUI.h:191
void DrawDecal(olc::PixelGameEngine *pge) override
Label(olc::QuickGUI::Manager &manager, const std::string &text, const olc::vf2d &pos, const olc::vf2d &size)
bool bHasBackground
Definition olcPGEX_QuickGUI.h:193
void Update(olc::PixelGameEngine *pge) override
Definition olcPGEX_QuickGUI.h:331
ListBox(olc::QuickGUI::Manager &manager, std::vector< std::string > &vList, const olc::vf2d &pos, const olc::vf2d &size)
Manager m_group
Definition olcPGEX_QuickGUI.h:349
void DrawDecal(olc::PixelGameEngine *pge) override
std::vector< std::string > & m_vList
Definition olcPGEX_QuickGUI.h:351
olc::vf2d vSize
Definition olcPGEX_QuickGUI.h:341
olc::vf2d vPos
Definition olcPGEX_QuickGUI.h:339
void Update(olc::PixelGameEngine *pge) override
bool bHasBorder
Definition olcPGEX_QuickGUI.h:343
size_t nPreviouslySelectedItem
Definition olcPGEX_QuickGUI.h:356
Slider * m_pSlider
Definition olcPGEX_QuickGUI.h:348
size_t nSelectedItem
Definition olcPGEX_QuickGUI.h:355
bool bSelectionChanged
Definition olcPGEX_QuickGUI.h:358
bool bHasBackground
Definition olcPGEX_QuickGUI.h:345
void Draw(olc::PixelGameEngine *pge) override
size_t m_nVisibleItems
Definition olcPGEX_QuickGUI.h:350
Definition olcPGEX_QuickGUI.h:132
float fHoverSpeedOn
Definition olcPGEX_QuickGUI.h:158
void CopyThemeFrom(const Manager &manager)
float fGrabRad
Definition olcPGEX_QuickGUI.h:162
olc::Pixel colBorder
Definition olcPGEX_QuickGUI.h:155
olc::Pixel colText
Definition olcPGEX_QuickGUI.h:156
void DrawDecal(olc::PixelGameEngine *pge)
olc::Pixel colClick
Definition olcPGEX_QuickGUI.h:153
Manager(const bool bCleanUpForMe=true)
void Update(olc::PixelGameEngine *pge)
void AddControl(BaseControl *control)
olc::Pixel colDisable
Definition olcPGEX_QuickGUI.h:154
void Draw(olc::PixelGameEngine *pge)
olc::Pixel colNormal
Definition olcPGEX_QuickGUI.h:151
float fHoverSpeedOff
Definition olcPGEX_QuickGUI.h:160
olc::Pixel colHover
Definition olcPGEX_QuickGUI.h:152
Definition olcPGEX_QuickGUI.h:368
void ShowFileOpen(const std::string &sPath)
virtual bool OnBeforeUserUpdate(float &fElapsedTime) override
Definition olcPGEX_QuickGUI.h:301
void Draw(olc::PixelGameEngine *pge) override
void Update(olc::PixelGameEngine *pge) override
olc::vf2d vPosMin
Definition olcPGEX_QuickGUI.h:319
float fMin
Definition olcPGEX_QuickGUI.h:312
float fValue
Definition olcPGEX_QuickGUI.h:316
void DrawDecal(olc::PixelGameEngine *pge) override
float fMax
Definition olcPGEX_QuickGUI.h:314
Slider(olc::QuickGUI::Manager &manager, const olc::vf2d &posmin, const olc::vf2d &posmax, const float valmin, const float valmax, const float value)
olc::vf2d vPosMax
Definition olcPGEX_QuickGUI.h:321
Definition olcPGEX_QuickGUI.h:205
void DrawDecal(olc::PixelGameEngine *pge) override
void Draw(olc::PixelGameEngine *pge) override
bool m_bTextEdit
Definition olcPGEX_QuickGUI.h:218
void Update(olc::PixelGameEngine *pge) override
TextBox(olc::QuickGUI::Manager &manager, const std::string &text, const olc::vf2d &pos, const olc::vf2d &size)
Definition olcPixelGameEngine.h:1125
olc::Sprite * Sprite() const
olc::Decal * Decal() const
Definition olcPGEX_QuickGUI.h:82
Definition olcPixelGameEngine.h:593
v_2d< float > vf2d
Definition olcPixelGameEngine.h:894
Pixel PixelLerp(const olc::Pixel &p1, const olc::Pixel &p2, float t)
static const Pixel CYAN(0, 255, 255)
static const Pixel DARK_GREY(128, 128, 128)
v_2d< int32_t > vi2d
Definition olcPixelGameEngine.h:892
@ BACK
Definition olcPixelGameEngine.h:979
@ ESCAPE
Definition olcPixelGameEngine.h:979
static const Pixel BLUE(0, 0, 255)
static const Pixel DARK_BLUE(0, 0, 128)
static const Pixel WHITE(255, 255, 255)
bool bPressed
Definition olcPixelGameEngine.h:999
bool bReleased
Definition olcPixelGameEngine.h:1000
bool bHeld
Definition olcPixelGameEngine.h:1001
Definition olcPixelGameEngine.h:924
T x
Definition olcPixelGameEngine.h:604
T y
Definition olcPixelGameEngine.h:606
constexpr auto dot(const v_2d &rhs) const
Definition olcPixelGameEngine.h:678
constexpr T mag2() const
Definition olcPixelGameEngine.h:635