5#include "fifechan/widget.hpp"
13#include "fifechan/actionevent.hpp"
14#include "fifechan/actionlistener.hpp"
15#include "fifechan/deathlistener.hpp"
16#include "fifechan/defaultfont.hpp"
17#include "fifechan/event.hpp"
18#include "fifechan/exception.hpp"
19#include "fifechan/focushandler.hpp"
20#include "fifechan/graphics.hpp"
21#include "fifechan/keylistener.hpp"
22#include "fifechan/mouselistener.hpp"
23#include "fifechan/rectangle.hpp"
24#include "fifechan/size.hpp"
25#include "fifechan/visibilityeventhandler.hpp"
26#include "fifechan/widgetlistener.hpp"
51 std::list<Widget*>::const_iterator childrenIter;
52 for (childrenIter =
mChildren.begin(); childrenIter !=
mChildren.end(); ++childrenIter) {
53 (*childrenIter)->_setParent(
nullptr);
56 std::list<DeathListener*>::const_iterator deathIter;
58 Event
const event(
this);
59 (*deathIter)->death(event);
63 Event
const event(
this);
79 }
catch (fcn::Exception
const & e) {
80 std::cerr <<
"Exception caught in Widget destructor: " << e.
what() <<
'\n';
81 }
catch (std::exception
const & e) {
82 std::cerr <<
"Exception caught in Widget destructor: " << e.what() <<
'\n';
84 std::cerr <<
"Unknown exception caught in Widget destructor" <<
'\n';
96 highlightColor = outlineColor + 0x303030;
97 highlightColor.
a = alpha;
98 shadowColor = outlineColor - 0x303030;
99 shadowColor.
a = alpha;
103 graphics->
drawLine(i, i, width - i, i);
104 graphics->
drawLine(i, i + 1, i, height - i - 1);
106 graphics->
drawLine(width - i, i + 1, width - i, height - i);
107 graphics->
drawLine(i, height - i, width - i - 1, height - i);
114 Color highlightColor;
120 highlightColor = borderColor + 0x303030;
121 highlightColor.
a = alpha;
122 shadowColor = borderColor - 0x303030;
123 shadowColor.
a = alpha;
127 graphics->
drawLine(i, i, width - i, i);
128 graphics->
drawLine(i, i + 1, i, height - i - 1);
130 graphics->
drawLine(width - i, i + 1, width - i, height - i);
131 graphics->
drawLine(i, height - i, width - i - 1, height - i);
145 graphics->
drawLine(i, i, width - i, i);
146 graphics->
drawLine(i, i + 1, i, height - i - 1);
147 graphics->
drawLine(width - i, i + 1, width - i, height - i);
148 graphics->
drawLine(i, height - i, width - i - 1, height - i);
165 newDimension.
width = width;
178 newDimension.
height = height;
241 for (; currChild != endChildren; ++currChild) {
242 (*currChild)->distributeAncestorMovedEvent(
this);
249 unsigned int childs = 0;
252 for (; currChild != endChildren; ++currChild) {
260 unsigned int childs = 0;
263 for (; currChild != endChildren; ++currChild) {
321 int const minWidth =
mMinSize.getWidth();
322 int const minHeight =
mMinSize.getHeight();
323 int const maxWidth =
mMaxSize.getWidth();
324 int const maxHeight =
mMaxSize.getHeight();
328 mDimension.width = std::max(std::min(currWidth, maxWidth), minWidth);
329 mDimension.height = std::max(std::min(currHeight, maxHeight), minHeight);
355 while ((widget->
getParent() !=
nullptr) && top) {
523 throwException(
"No focus handler is set (did you add the widget to the GUI?)");
560 for (; currChild != endChildren; ++currChild) {
561 (*currChild)->distributeAncestorShownEvent(
this);
570 for (; currChild != endChildren; ++currChild) {
571 (*currChild)->distributeAncestorHiddenEvent(
this);
671 if (focusHandler !=
nullptr) {
672 focusHandler->
add(
this);
681 std::list<Widget*>::const_iterator iter;
684 (*iter)->_setFocusHandler(focusHandler);
813 std::list<Widget*>::iterator iter;
815 if ((*iter)->mCurrentFont ==
nullptr) {
816 (*iter)->fontChanged();
858 newDimension.
width = width;
859 newDimension.
height = height;
877 throwException(
"No focus handler is set (did you add the widget to the GUI?)");
886 throwException(
"No focus handler is set (did you add the widget to the GUI?)");
889 return mFocusHandler->getModalMouseInputFocused() ==
nullptr;
895 throwException(
"No focus handler is set (did you add the widget to the GUI?)");
904 throwException(
"No focus handler is set (did you add the widget to the GUI?)");
931 throwException(
"No focus handler is set (did you add the widget to the GUI?)");
944 throwException(
"No focus handler is set (did you add the widget to the GUI?)");
965 std::list<Widget*>::reverse_iterator iter;
1006 std::list<Widget*>::const_iterator iter;
1028 std::list<WidgetListener*>::const_iterator iter;
1030 Event const event(
this);
1031 (*iter)->widgetResized(event);
1037 std::list<WidgetListener*>::const_iterator iter;
1039 Event const event(
this);
1040 (*iter)->widgetMoved(event);
1046 std::list<WidgetListener*>::const_iterator iter;
1048 Event const event(
this);
1049 (*iter)->widgetHidden(event);
1057 Event const event(ancestor);
1059 for (; currWidgetListener != endWidgetListeners; ++currWidgetListener) {
1060 (*currWidgetListener)->ancestorMoved(event);
1064 auto const endChildren(
mChildren.end());
1066 for (; currChild != endChildren; ++currChild) {
1067 (*currChild)->distributeAncestorMovedEvent(ancestor);
1078 Event const event(ancestor);
1080 for (; currWidgetListener != endWidgetListeners; ++currWidgetListener) {
1081 (*currWidgetListener)->ancestorHidden(event);
1085 auto const endChildren(
mChildren.end());
1087 for (; currChild != endChildren; ++currChild) {
1088 (*currChild)->distributeAncestorHiddenEvent(ancestor);
1099 Event const event(ancestor);
1101 for (; currWidgetListener != endWidgetListeners; ++currWidgetListener) {
1102 (*currWidgetListener)->ancestorShown(event);
1106 auto const endChildren(
mChildren.end());
1108 for (; currChild != endChildren; ++currChild) {
1109 (*currChild)->distributeAncestorShownEvent(ancestor);
1115 std::list<ActionListener*>::const_iterator iter;
1118 (*iter)->action(actionEvent);
1124 std::list<WidgetListener*>::const_iterator iter;
1126 Event const event(
this);
1127 (*iter)->widgetShown(event);
1134 mParent->showWidgetPart(
this, rectangle);
1147 while (parent !=
nullptr) {
1157 std::list<Widget*> result;
1159 std::list<Widget*>::const_iterator iter;
1161 Widget* widget = (*iter);
1163 result.push_back(widget);
1174 std::list<Widget*>::const_iterator iter;
1176 Widget* widget = (*iter);
1186 std::list<Widget*>::const_iterator iter;
1188 Widget* widget = (*iter);
1190 if (widget->
getId() ==
id) {
1196 if (child !=
nullptr) {
1208 area.
x += widget->
getX();
1209 area.
y += widget->
getY();
1230 std::list<Widget*>::const_iterator iter;
1232 Widget* widget = (*iter);
1250 auto it = std::ranges::find(
mChildren, widget);
1252 if (it == std::ranges::end(
mChildren)) {
1253 throwException(
"There is no such widget in this container.");
1292 std::list<Widget*>::iterator iter;
1293 iter = std::ranges::find(
mChildren, widget);
1296 throwException(
"There is no such widget in this widget.");
1305 std::list<Widget*>::iterator iter;
1306 iter = std::ranges::find(
mChildren, widget);
1309 throwException(
"There is no such widget in this widget.");
1322 auto focused = std::ranges::find_if(
mChildren, [](
auto* w) {
1323 return w->isFocused();
1326 auto next = (focused == std::ranges::end(
mChildren)) ? std::ranges::begin(
mChildren) : std::next(focused);
1328 auto it = std::ranges::find_if(next, std::ranges::end(
mChildren), [](
auto* w) {
1329 return w->isFocusable();
1332 if (it == std::ranges::end(
mChildren)) {
1333 it = std::ranges::find_if(std::ranges::begin(
mChildren), next, [](
auto* w) {
1334 return w->isFocusable();
1339 (*it)->requestFocus();
1349 auto rev = std::ranges::reverse_view(
mChildren);
1351 auto focused = std::ranges::find_if(rev, [](
auto* w) {
1352 return w->isFocused();
1355 auto next = (focused == std::ranges::end(rev)) ? std::ranges::begin(rev) : std::next(focused);
1357 auto rit = std::ranges::find_if(next, std::ranges::end(rev), [](
auto* w) {
1358 return w->isFocusable();
1361 if (rit == std::ranges::end(rev)) {
1362 rit = std::ranges::find_if(std::ranges::begin(rev), next, [](
auto* w) {
1363 return w->isFocusable();
1368 (*rit)->requestFocus();
1396 if (widget->isVisible() && childrenArea.
isIntersecting(widget->getDimension())) {
1397 widget->_draw(graphics);
1409 std::list<Widget*>::const_iterator iter;
Represents an action trigger (e.g., button click).
Interface for listening to action events from widgets.
uint8_t a
Alpha color component (0-255).
Interface for listening to widget destruction events.
A basic font implementation capable only of drawing rectangles (placeholder).
Base class for all GUI event objects.
char const * what() const noexcept override
Returns a pointer to a null-terminated string with a description of the exception.
Manages focus navigation and assignment among widgets within a Gui instance.
virtual void add(Widget *widget)
Adds a widget to by handles by the focus handler.
Interface for listening to focus gain/loss events.
Abstract interface for font rendering.
Abstract interface providing primitive drawing functions (lines, rectangles, etc.).
virtual void popClipArea()
Removes the top most clip area from the stack.
virtual bool pushClipArea(Rectangle area)
Pushes a clip area onto the stack.
virtual void drawLine(int x1, int y1, int x2, int y2)=0
Draws a line.
virtual void setColor(Color const &color)=0
Sets the color to use when drawing.
Interface for listening to keyboard events.
Interface for listening to mouse events.
Represents a rectangular area (X, Y, Width, Height).
bool isContaining(int x, int y) const
Checks the rectangle contains a point.
int width
Holds the width of the rectangle.
int y
Holds the x coordinate of the rectangle.
int x
Holds the x coordinate of the rectangle.
int height
Holds the height of the rectangle.
bool isIntersecting(Rectangle const &rectangle) const
Checks if another rectangle intersects with the rectangle.
Represents dimensions defined by width and height.
Handles changes in widget visibility states.
void widgetHidden(Event const &e) override
Informs gui that a widget was hidden.
void widgetShown(Event const &e) override
Informs gui that a widget was shown.