6#include "fifechan/focushandler.hpp"
16#include "fifechan/platform.hpp"
19#include "fifechan/events/event.hpp"
20#include "fifechan/exception.hpp"
21#include "fifechan/listeners/focuslistener.hpp"
22#include "fifechan/widget.hpp"
26 FocusHandler::FocusHandler() :
27 mFocusedWidget(nullptr),
28 mDraggedWidget(nullptr),
29 mLastWidgetWithMouse(nullptr),
30 mLastWidgetWithModalFocus(nullptr),
31 mLastWidgetWithModalMouseInputFocus(nullptr),
32 mLastWidgetPressed(nullptr)
42 auto itFoundWidget = std::ranges::find(
mWidgets, widget);
44 if (itFoundWidget ==
mWidgets.end()) {
50 if (oldFocused != widget) {
53 if (oldFocused !=
nullptr) {
54 Event const focusEvent(oldFocused);
58 Event const focusEvent(*itFoundWidget);
70 if (focusOwner ==
nullptr && mouseOwner ==
nullptr) {
77 if (mouseOwner !=
nullptr && !mouseOwner->
isDescendantOf(existingCapture)) {
78 existingCapture->releaseMouse();
100 Widget* prevFocus =
nullptr;
105 if (prevFocus !=
nullptr) {
109 std::cerr <<
"[FocusHandler] Warning: focus request failed in noexcept context\n";
128 Event const focusEvent(focused);
142 if (old !=
nullptr) {
146 if (widget !=
nullptr) {
177 int focusedWidget = -1;
179 for (i = 0; std::cmp_less(i,
mWidgets.size()); ++i) {
185 int const focused = focusedWidget;
189 int num_widgets =
static_cast<int>(
mWidgets.size());
191 for (; num_widgets > 0; --num_widgets) {
194 if (std::cmp_greater_equal(focusedWidget,
mWidgets.size())) {
198 if (focusedWidget == focused) {
202 if (
mWidgets.at(focusedWidget)->isFocusable()) {
206 if (num_widgets == 1) {
212 if (focusedWidget >= 0) {
232 int focusedWidget = -1;
233 for (i = 0; std::cmp_less(i,
mWidgets.size()); ++i) {
238 int const focused = focusedWidget;
242 i =
static_cast<int>(
mWidgets.size());
253 if (focusedWidget < 0) {
254 focusedWidget =
mWidgets.size() - 1;
257 if (focusedWidget == focused) {
261 if (
mWidgets.at(focusedWidget)->isFocusable()) {
266 if (focusedWidget >= 0) {
294 auto iter = std::ranges::find(
mWidgets, widget);
295 if (iter != std::ranges::end(
mWidgets)) {
331 Event const focusEvent(focused);
350 int focusedWidget = -1;
351 for (i = 0; std::cmp_less(i,
mWidgets.size()); ++i) {
356 int const focused = focusedWidget;
358 i =
static_cast<int>(
mWidgets.size());
370 if (std::cmp_greater_equal(focusedWidget,
mWidgets.size())) {
374 if (focusedWidget == focused) {
378 if (
mWidgets.at(focusedWidget)->isFocusable() &&
mWidgets.at(focusedWidget)->isTabInEnabled() &&
380 mWidgets.at(focusedWidget)->isModalFocused()) {
385 if (focusedWidget >= 0) {
411 int focusedWidget = -1;
412 for (i = 0; std::cmp_less(i,
mWidgets.size()); ++i) {
417 int const focused = focusedWidget;
419 i =
static_cast<int>(
mWidgets.size());
431 if (focusedWidget <= 0) {
432 focusedWidget =
mWidgets.size() - 1;
435 if (focusedWidget == focused) {
439 if (
mWidgets.at(focusedWidget)->isFocusable() &&
mWidgets.at(focusedWidget)->isTabInEnabled() &&
445 if (focusedWidget >= 0) {
464 for (
auto& focusListener : focusListeners) {
465 focusListener->focusLost(focusEvent);
476 for (
auto& focusListener : focusListeners) {
477 focusListener->focusGained(focusEvent);
Base class for all GUI event objects.
Widget * getSource() const
Gets the source widget of the event.
std::vector< ModalState > mModalStack
Holds the modal stack for nested modal dialogs.
Widget * mFocusedWidget
Holds the focused widget.
virtual bool hasModalFocus() const
Checks if any modal state is active.
virtual Widget * getLastWidgetWithMouse()
Gets the last widget with the mouse.
WidgetVector mWidgets
Holds the widgets currently being handled by the focus handler.
Widget * mDraggedWidget
Holds the dragged widget.
virtual Widget * getFocusOwner() const
Gets the active input root widget for focus routing.
virtual void focusPrevious()
Focuses the previous widget added to a container.
virtual void widgetHidden(Widget *widget)
Informs the focus handler that a widget was hidden.
virtual void setLastWidgetWithMouse(Widget *lastWidgetWithMouse)
Sets the last widget with the mouse.
virtual void popModal() noexcept
Pops the current modal state from the stack.
virtual void focusNone()
Focuses nothing.
virtual Widget * getDraggedWidget()
Gets the widget being dragged.
Widget * mLastWidgetWithModalMouseInputFocus
Holds the last widget with modal mouse input focus.
virtual void setFocusedWidget(Widget *widget)
Sets the focused widget directly.
Widget * mLastWidgetPressed
Holds the last widget pressed.
virtual void add(Widget *widget)
Adds a widget to by handles by the focus handler.
virtual void setLastWidgetWithModalFocus(Widget *lastWidgetWithModalFocus)
Sets the last widget with modal focus.
virtual void pushModal(Widget *focusOwner, Widget *mouseOwner=nullptr)
Pushes a new modal state onto the stack.
virtual void setLastWidgetPressed(Widget *lastWidgetPressed)
Sets the last widget pressed.
virtual Widget * getLastWidgetWithModalMouseInputFocus()
Gets the last widget with modal mouse input focus.
virtual Widget * getLastWidgetWithModalFocus()
Gets the last widget with modal focus.
virtual void remove(Widget *widget)
Removes a widget from the focus handler.
virtual bool isFocused(Widget const *widget) const
Checks if a widget is focused.
virtual void distributeFocusGainedEvent(Event const &focusEvent)
Distributes a focus gained event.
virtual void tabPrevious()
Focuses the previous widget which allows tabbing in unless current focused Widget disallows tabbing o...
Widget * mLastWidgetWithModalFocus
Holds the last widget with modal focus.
virtual Widget * getMouseCaptureOwner() const
Gets the widget with modal mouse input focus.
virtual void clearModal()
Clears all modal states from the stack.
virtual void tabNext()
Focuses the next widget which allows tabbing in unless the current focused Widget disallows tabbing o...
virtual void distributeFocusLostEvent(Event const &focusEvent)
Distributes a focus lost event.
virtual void focusNext()
Focuses the next widget added to a container.
virtual void releaseFocus(Widget *widget)
Releases focus for the specified widget if it is currently focused.
virtual void setDraggedWidget(Widget *draggedWidget)
Sets the widget being dragged.
virtual void requestFocus(Widget *widget)
Requests focus for a widget.
virtual Widget * getLastWidgetPressed()
Gets the last widget pressed.
Widget * mLastWidgetWithMouse
Holds the last widget with the mouse.
virtual void setLastWidgetWithModalMouseInputFocus(Widget *lastWidgetWithModalMouseInputFocus)
Sets the last widget with modal mouse input focus.
virtual Widget * getFocused() const
Gets the widget with focus.
Used replacement tokens by configure_file():
void throwException(std::string const &message, std::source_location location=std::source_location::current())
Throw an Exception capturing the current source location.
Represents a single modal state level with focus and mouse owners.
Widget * focusOwner
Widget with modal focus at this level.
Widget * mouseOwner
Widget with modal mouse input at this level.