Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Distributor #60

Merged
merged 2 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion TODO
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
* Continue rebasing from 03e447d44e29bc81498f912e227c75a35a420d8d
* Continue rebasing from b50089aa71c0625f5273c468ac169b71f8bba664
* Add a focus listener interface.
* Make focus apply synchronously.
* Graphics and input objects for DirectX.
Expand Down
53 changes: 53 additions & 0 deletions include/guisan/basiccontainer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ namespace gcn
class GCN_CORE_DECLSPEC BasicContainer : public Widget, public DeathListener
{
public:
/**
* Constructor.
*/
BasicContainer();

/**
* Destructor
*/
Expand Down Expand Up @@ -120,9 +125,36 @@ namespace gcn
virtual void death(const Event& event);

protected:
/**
* Moves a widget to the top. Normally one wants to use
* Widget::moveToTop instead.
*
* THIS METHOD IS NOT SAFE TO CALL INSIDE A WIDGETS LOGIC FUNCTION
* INSIDE ANY LISTER FUNCTIONS!
*
* @param widget The widget to move to the top.
* @since 1.1.0
*/
void _moveToTopWithNoChecks(Widget* widget);

/**
* Moves a widget to the bottom. Normally one wants to use
* Widget::moveToBottom instead.
*
* THIS METHOD IS NOT SAFE TO CALL INSIDE A WIDGETS LOGIC FUNCTION
* INSIDE ANY LISTER FUNCTIONS!
*
* @param The widget to move to the bottom.
* @since 1.1.0
*/
void _moveToBottomWithNoChecks(Widget* widget);

/**
* Adds a widget to the basic container.
*
* THIS METHOD IS NOT SAFE TO CALL INSIDE A WIDGETS LOGIC FUNCTION
* INSIDE ANY LISTER FUNCTIONS!
*
* @param widget The widget to add.
* @see remove, clear
*/
Expand All @@ -131,6 +163,9 @@ namespace gcn
/**
* Removes a widget from the basic container.
*
* THIS METHOD IS NOT SAFE TO CALL INSIDE A WIDGETS LOGIC FUNCTION
* INSIDE ANY LISTER FUNCTIONS!
*
* @param widget The widget to remove.
* @see add, clear
*/
Expand All @@ -139,6 +174,9 @@ namespace gcn
/**
* Clears the basic container from all widgets.
*
* THIS METHOD IS NOT SAFE TO CALL INSIDE A WIDGETS LOGIC FUNCTION
* INSIDE ANY LISTER FUNCTIONS!
*
* @see remove, clear
*/
virtual void clear();
Expand Down Expand Up @@ -175,6 +213,21 @@ namespace gcn
* Holds all widgets of the basic container.
*/
WidgetList mWidgets;

/**
* Holds a widget that should be moved to the top.
*/
Widget* mWidgetToBeMovedToTheTop;

/**
* Holds a widget that should be moved to the bottom.
*/
Widget* mWidgetToBeMovedToTheBottom;

/**
* True if logic is currently being processed, false otherwise.
*/
bool mLogicIsProcessing;
};
}

Expand Down
26 changes: 25 additions & 1 deletion include/guisan/inputevent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,15 @@ namespace gcn
/**
* Constructor.
*
* @param source The source widget of the event.
* @param source The widget the event concerns.
* @param distributor The distributor of the event.
* @param isShiftPressed True if shift is pressed, false otherwise.
* @param isControlPressed True if control is pressed, false otherwise.
* @param isAltPressed True if alt is pressed, false otherwise.
* @param isMetaPressed True if meta is pressed, false otherwise.
*/
InputEvent(Widget* source,
Widget* distributor,
bool isShiftPressed,
bool isControlPressed,
bool isAltPressed,
Expand Down Expand Up @@ -140,6 +142,14 @@ namespace gcn
*/
bool isConsumed() const;

/**
* Gets the distributor of the event.
* The function is used to tell which widget actually distributed the
* event. As input events bubbles up, the source of the event
* may not be the same as the distributor of the event.
*/
Widget* getDistributor() const;

protected:
/**
* True if shift is pressed, false otherwise.
Expand All @@ -166,6 +176,20 @@ namespace gcn
* false otherwise.
*/
bool mIsConsumed;

/**
* Holds the distributor of the event.
*/
Widget* mDistributor;

/**
* Gui is a friend of this class in order to be able to manipulate
* the protected member variables of this class and at the same time
* keep the MouseEvent class as const as possible. Gui needs to
* update the distributer of this class whenever the distributer
* changes as events bubble up.
*/
friend class Gui;
};
}

Expand Down
4 changes: 3 additions & 1 deletion include/guisan/keyevent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ namespace gcn
/**
* Constructor.
*
* @param source The source widget of the event.
* @param source The widget the event concerns.
* @param distributor The distributor of the event.
* @param isShiftPressed True if shift is pressed, false otherwise.
* @param isControlPressed True if control is pressed, false otherwise.
* @param isAltPressed True if alt is pressed, false otherwise.
Expand All @@ -94,6 +95,7 @@ namespace gcn
* @param key The key of the event.
*/
KeyEvent(Widget* source,
Widget* distributor,
bool isShiftPressed,
bool isControlPressed,
bool isAltPressed,
Expand Down
4 changes: 3 additions & 1 deletion include/guisan/mouseevent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ namespace gcn
/**
* Constructor.
*
* @param source The source widget of the mouse event.
* @param source The widget the event concerns.
* @param distributor The distributor of the mouse event.
* @param isShiftPressed True if shift is pressed, false otherwise.
* @param isControlPressed True if control is pressed, false otherwise.
* @param isAltPressed True if alt is pressed, false otherwise.
Expand All @@ -91,6 +92,7 @@ namespace gcn
* It's set to zero if another button is used.
*/
MouseEvent(Widget* source,
Widget* distributor,
bool isShiftPressed,
bool isControlPressed,
bool isAltPressed,
Expand Down
60 changes: 47 additions & 13 deletions src/basiccontainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,38 +69,44 @@

namespace gcn
{
BasicContainer::BasicContainer() :
mWidgetToBeMovedToTheTop(NULL),
mWidgetToBeMovedToTheBottom(NULL),
mLogicIsProcessing(false)
{}

BasicContainer::~BasicContainer()
{
clear();
}

void BasicContainer::moveToTop(Widget* widget)
{
WidgetListIterator iter;
for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
WidgetListIterator iter = std::find(mWidgets.begin(), mWidgets.end(), widget);

if (iter == mWidgets.end())
{
if (*iter == widget)
{
mWidgets.erase(iter);
mWidgets.push_back(widget);
return;
}
throw GCN_EXCEPTION("There is no such widget in this container.");
}

throw GCN_EXCEPTION("There is no such widget in this container.");
if (mLogicIsProcessing)
mWidgetToBeMovedToTheTop = widget;
else
_moveToTopWithNoChecks(widget);
}

void BasicContainer::moveToBottom(Widget* widget)
{
WidgetListIterator iter;
iter = find(mWidgets.begin(), mWidgets.end(), widget);
WidgetListIterator iter = find(mWidgets.begin(), mWidgets.end(), widget);

if (iter == mWidgets.end())
{
throw GCN_EXCEPTION("There is no such widget in this container.");
}
mWidgets.erase(iter);
mWidgets.push_front(widget);
if (mLogicIsProcessing)
mWidgetToBeMovedToTheBottom = widget;
else
_moveToBottomWithNoChecks(widget);
}

void BasicContainer::death(const Event& event)
Expand Down Expand Up @@ -219,7 +225,23 @@ namespace gcn

void BasicContainer::logic()
{
mLogicIsProcessing = true;
mWidgetToBeMovedToTheTop = NULL;
mWidgetToBeMovedToTheBottom = NULL;
logicChildren();
mLogicIsProcessing = false;

if (mWidgetToBeMovedToTheTop != NULL)
{
_moveToTopWithNoChecks(mWidgetToBeMovedToTheTop);
mWidgetToBeMovedToTheTop = NULL;
}

if (mWidgetToBeMovedToTheBottom != NULL)
{
_moveToTopWithNoChecks(mWidgetToBeMovedToTheBottom);
mWidgetToBeMovedToTheBottom = NULL;
}
}

void BasicContainer::_setFocusHandler(FocusHandler* focusHandler)
Expand Down Expand Up @@ -399,4 +421,16 @@ namespace gcn

return NULL;
}

void BasicContainer::_moveToTopWithNoChecks(Widget* widget)
{
mWidgets.remove(widget);
mWidgets.push_back(widget);
}

void BasicContainer::_moveToBottomWithNoChecks(Widget* widget)
{
mWidgets.remove(widget);
mWidgets.push_front(widget);
}
}
13 changes: 10 additions & 3 deletions src/gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ namespace gcn
mAltPressed = keyInput.isAltPressed();

KeyEvent keyEventToGlobalKeyListeners(NULL,
NULL,
mShiftPressed,
mControlPressed,
mAltPressed,
Expand All @@ -297,7 +298,9 @@ namespace gcn
// Send key inputs to the focused widgets
if (mFocusHandler->getFocused() != NULL)
{
KeyEvent keyEvent(getKeyEventSource(),
Widget* source = getKeyEventSource();
KeyEvent keyEvent(source,
source,
mShiftPressed,
mControlPressed,
mAltPressed,
Expand Down Expand Up @@ -704,6 +707,7 @@ namespace gcn
}

MouseEvent mouseEvent(source,
source,
mShiftPressed,
mControlPressed,
mAltPressed,
Expand Down Expand Up @@ -732,7 +736,7 @@ namespace gcn

mouseEvent.mX = x - widgetX;
mouseEvent.mY = y - widgetY;
mouseEvent.mDistributor = widget;
std::list<MouseListener*> mouseListeners = widget->_getMouseListeners();

// Send the event to all mouse listeners of the widget.
Expand Down Expand Up @@ -788,6 +792,7 @@ namespace gcn
// If a non modal focused widget has been reach
// and we have modal focus cancel the distribution.
if (mFocusHandler->getModalFocused() != NULL
&& widget != NULL
&& !widget->isModalFocused())
{
break;
Expand All @@ -796,6 +801,7 @@ namespace gcn
// If a non modal mouse input focused widget has been reach
// and we have modal mouse input focus cancel the distribution.
if (mFocusHandler->getModalMouseInputFocused() != NULL
&& widget != NULL
&& !widget->isModalMouseInputFocused())
{
break;
Expand Down Expand Up @@ -833,8 +839,9 @@ namespace gcn

if (widget->isEnabled())
{
keyEvent.mDistributor = widget;
std::list<KeyListener*> keyListeners = widget->_getKeyListeners();

// Send the event to all key listeners of the source widget.
for (std::list<KeyListener*>::iterator it = keyListeners.begin();
it != keyListeners.end();
Expand Down
24 changes: 15 additions & 9 deletions src/inputevent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,19 @@
namespace gcn
{
InputEvent::InputEvent(Widget* source,
Widget* distributor,
bool isShiftPressed,
bool isControlPressed,
bool isAltPressed,
bool isMetaPressed)
:Event(source),
mShiftPressed(isShiftPressed),
mControlPressed(isControlPressed),
mAltPressed(isAltPressed),
mMetaPressed(isMetaPressed),
mIsConsumed(false)
bool isMetaPressed) :
Event(source),
mShiftPressed(isShiftPressed),
mControlPressed(isControlPressed),
mAltPressed(isAltPressed),
mMetaPressed(isMetaPressed),
mIsConsumed(false),
mDistributor(distributor)
{

}

bool InputEvent::isShiftPressed() const
Expand Down Expand Up @@ -106,4 +107,9 @@ namespace gcn
{
return mIsConsumed;
}
}

Widget* InputEvent::getDistributor() const
{
return mDistributor;
}
} // namespace gcn
Loading