Remove list of recipients from ui::Message

master
David Capello 2018-12-12 13:25:12 -03:00
parent ab9883e260
commit 105d389fdc
16 changed files with 153 additions and 198 deletions

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2016-2017 David Capello
//
// This program is distributed under the terms of
@ -495,7 +496,7 @@ private:
label->Click.connect(
[this, url]{
Message* msg = new LoadFileMessage(url);
msg->addRecipient(this);
msg->setRecipient(this);
Manager::getDefault()->enqueueMessage(msg);
});
}

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -357,7 +358,8 @@ bool DocView::onProcessMessage(Message* msg)
{
switch (msg->type()) {
case kFocusEnterMessage:
m_editor->requestFocus();
if (msg->recipient() != m_editor)
m_editor->requestFocus();
break;
}
return Box::onProcessMessage(msg);

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
@ -284,7 +285,7 @@ bool Tabs::onProcessMessage(Message* msg)
case kMouseEnterMessage:
calculateHot();
return true;
break;
case kMouseMoveMessage:
calculateHot();

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -230,7 +231,7 @@ bool ToolBar::onProcessMessage(Message* msg)
mouseMsg->buttons(),
mouseMsg->modifiers(),
mouseMsg->position());
mouseMsg2->addRecipient(strip);
mouseMsg2->setRecipient(strip);
manager()->enqueueMessage(mouseMsg2);
}
}
@ -662,7 +663,7 @@ bool ToolBar::ToolStrip::onProcessMessage(Message* msg)
mouseMsg->buttons(),
mouseMsg->modifiers(),
mouseMsg->position());
mouseMsg2->addRecipient(bar);
mouseMsg2->setRecipient(bar);
manager()->enqueueMessage(mouseMsg2);
}
}

View File

@ -372,7 +372,8 @@ bool ComboBox::onProcessMessage(Message* msg)
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
Widget* pick = manager()->pick(mouseMsg->position());
return (pick && pick->hasAncestor(this) ? true: false);
if (pick && pick->hasAncestor(this))
return true;
}
}
break;

View File

@ -355,21 +355,23 @@ void Manager::generateMessagesFromOSEvents()
case os::Event::CloseDisplay: {
Message* msg = new Message(kCloseDisplayMessage);
msg->broadcastToChildren(this);
msg->setRecipient(this);
msg->setPropagateToChildren(true);
enqueueMessage(msg);
break;
}
case os::Event::ResizeDisplay: {
Message* msg = new Message(kResizeDisplayMessage);
msg->broadcastToChildren(this);
msg->setRecipient(this);
msg->setPropagateToChildren(true);
enqueueMessage(msg);
break;
}
case os::Event::DropFiles: {
Message* msg = new DropFilesMessage(sheEvent.files());
msg->addRecipient(this);
msg->setRecipient(this);
enqueueMessage(msg);
break;
}
@ -598,7 +600,7 @@ void Manager::handleTouchMagnify(const gfx::Point& mousePos,
mousePos,
magnification);
msg->addRecipient(widget);
msg->setRecipient(widget);
enqueueMessage(msg);
}
@ -731,67 +733,40 @@ void Manager::setFocus(Widget* widget)
&& !(widget->hasFlags(HIDDEN))
&& !(widget->hasFlags(DECORATIVE))
&& someParentIsFocusStop(widget)))) {
WidgetsList widget_parents;
Widget* common_parent = NULL;
if (widget)
widget->getParents(false, widget_parents);
Widget* commonAncestor = findLowestCommonAncestor(focus_widget, widget);
// Fetch the focus
if (focus_widget) {
WidgetsList focus_parents;
focus_widget->getParents(true, focus_parents);
Message* msg = new Message(kFocusLeaveMessage);
for (Widget* parent1 : focus_parents) {
if (widget) {
for (Widget* parent2 : widget_parents) {
if (parent1 == parent2) {
common_parent = parent1;
break;
}
}
if (common_parent)
break;
}
if (parent1->hasFocus()) {
parent1->disableFlags(HAS_FOCUS);
msg->addRecipient(parent1);
}
}
auto msg = new Message(kFocusLeaveMessage);
msg->setRecipient(focus_widget);
msg->setPropagateToParent(true);
msg->setCommonAncestor(commonAncestor);
enqueueMessage(msg);
// Remove HAS_FOCUS from all hierarchy
auto a = focus_widget;
while (a && a != commonAncestor) {
a->disableFlags(HAS_FOCUS);
a = a->parent();
}
}
// Put the focus
focus_widget = widget;
if (widget) {
WidgetsList::iterator it;
if (common_parent) {
it = std::find(widget_parents.begin(),
widget_parents.end(),
common_parent);
ASSERT(it != widget_parents.end());
++it;
}
else
it = widget_parents.begin();
Message* msg = new Message(kFocusEnterMessage);
for (; it != widget_parents.end(); ++it) {
Widget* w = *it;
if (w->hasFlags(FOCUS_STOP)) {
w->enableFlags(HAS_FOCUS);
msg->addRecipient(w);
}
}
auto msg = new Message(kFocusEnterMessage);
msg->setRecipient(widget);
msg->setPropagateToParent(true);
msg->setCommonAncestor(commonAncestor);
enqueueMessage(msg);
// Add HAS_FOCUS to all hierarchy
auto a = focus_widget;
while (a && a != commonAncestor) {
if (a->hasFlags(FOCUS_STOP))
a->enableFlags(HAS_FOCUS);
a = a->parent();
}
}
}
}
@ -812,71 +787,49 @@ void Manager::setMouse(Widget* widget)
#endif
if ((mouse_widget != widget) && (!capture_widget)) {
WidgetsList widget_parents;
Widget* common_parent = NULL;
if (widget)
widget->getParents(false, widget_parents);
Widget* commonAncestor = findLowestCommonAncestor(mouse_widget, widget);
// Fetch the mouse
if (mouse_widget) {
WidgetsList mouse_parents;
mouse_widget->getParents(true, mouse_parents);
Message* msg = new Message(kMouseLeaveMessage);
for (Widget* parent1 : mouse_parents) {
if (widget) {
for (Widget* parent2 : widget_parents) {
if (parent1 == parent2) {
common_parent = parent1;
break;
}
}
if (common_parent)
break;
}
if (parent1->hasMouse()) {
parent1->disableFlags(HAS_MOUSE);
msg->addRecipient(parent1);
}
}
auto msg = new Message(kMouseLeaveMessage);
msg->setRecipient(mouse_widget);
msg->setCommonAncestor(commonAncestor);
msg->setPropagateToParent(true);
msg->setCommonAncestor(commonAncestor);
enqueueMessage(msg);
// Remove HAS_MOUSE from all the hierarchy
auto a = mouse_widget;
while (a && a != commonAncestor) {
a->disableFlags(HAS_MOUSE);
a = a->parent();
}
}
// Put the mouse
mouse_widget = widget;
if (widget) {
WidgetsList::iterator it;
if (common_parent) {
it = std::find(widget_parents.begin(),
widget_parents.end(),
common_parent);
ASSERT(it != widget_parents.end());
++it;
}
else
it = widget_parents.begin();
Message* msg = newMouseMessage(
auto msg = newMouseMessage(
kMouseEnterMessage, NULL,
get_mouse_position(),
PointerType::Unknown,
_internal_get_mouse_buttons(),
kKeyUninitializedModifier);
for (; it != widget_parents.end(); ++it) {
(*it)->enableFlags(HAS_MOUSE);
msg->addRecipient(*it);
}
msg->setRecipient(widget);
msg->setPropagateToParent(true);
msg->setCommonAncestor(commonAncestor);
enqueueMessage(msg);
generateSetCursorMessage(get_mouse_position(),
kKeyUninitializedModifier,
PointerType::Unknown);
// Add HAS_MOUSE to all the hierarchy
auto a = mouse_widget;
while (a && a != commonAncestor) {
a->enableFlags(HAS_MOUSE);
a = a->parent();
}
}
}
}
@ -1419,12 +1372,9 @@ int Manager::pumpQueue()
}
if (!done) {
// Then send the message to its recipients
for (Widget* widget : msg->recipients()) {
// Then send the message to its recipient
if (Widget* widget = msg->recipient())
done = sendMessageToWidget(msg, widget);
if (done)
break;
}
}
// Remove the message from the used_msg_queue
@ -1621,6 +1571,46 @@ void Manager::collectGarbage()
Internal routines
**********************************************************************/
// static
Widget* Manager::findLowestCommonAncestor(Widget* a, Widget* b)
{
if (!a || !b)
return nullptr;
a = a->parent();
b = b->parent();
Widget* u = a;
Widget* v = b;
int aDepth = 0;
int bDepth = 0;
while (u) {
++aDepth;
u = u->parent();
}
while (v) {
++bDepth;
v = v->parent();
}
while (aDepth > bDepth) {
--aDepth;
a = a->parent();
}
while (bDepth > aDepth) {
--bDepth;
b = b->parent();
}
while (a && b) {
if (a == b)
break;
a = a->parent();
b = b->parent();
}
return a;
}
// static
void Manager::removeWidgetFromRecipients(Widget* widget, Message* msg)
{
@ -1685,7 +1675,7 @@ Message* Manager::newMouseMessage(
wheelDelta, preciseWheel);
if (widget)
msg->addRecipient(widget);
msg->setRecipient(widget);
return msg;
}
@ -1695,15 +1685,15 @@ void Manager::broadcastKeyMsg(Message* msg)
{
// Send the message to the widget with capture
if (capture_widget) {
msg->addRecipient(capture_widget);
msg->setRecipient(capture_widget);
}
// Send the msg to the focused widget
else if (focus_widget) {
msg->addRecipient(focus_widget);
msg->setRecipient(focus_widget);
}
// Finally, send the message to the manager, it'll know what to do
else {
msg->addRecipient(this);
msg->setRecipient(this);
}
}

View File

@ -150,6 +150,7 @@ namespace ui {
int pumpQueue();
bool sendMessageToWidget(Message* msg, Widget* widget);
static Widget* findLowestCommonAncestor(Widget* a, Widget* b);
static void removeWidgetFromRecipients(Widget* widget, Message* msg);
static bool someParentIsFocusStop(Widget* widget);
static Widget* findMagneticWidget(Widget* widget);

View File

@ -1,4 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This file is released under the terms of the MIT license.
@ -1059,7 +1060,7 @@ void MenuItem::openSubmenu(bool select_first)
}
msg = new OpenMenuItemMessage(select_first);
msg->addRecipient(this);
msg->setRecipient(this);
Manager::getDefault()->enqueueMessage(msg);
// Get the 'base'
@ -1102,7 +1103,7 @@ void MenuItem::closeSubmenu(bool last_of_close_chain)
// Second: now we can close the 'menuitem'
msg = new CloseMenuItemMessage(last_of_close_chain);
msg->addRecipient(this);
msg->setRecipient(this);
Manager::getDefault()->enqueueMessage(msg);
// If this is the last message of the chain, here we have the
@ -1181,7 +1182,7 @@ void Menu::closeAll()
void MenuBox::closePopup()
{
Message* msg = new Message(kClosePopupMessage);
msg->addRecipient(this);
msg->setRecipient(this);
Manager::getDefault()->enqueueMessage(msg);
}
@ -1223,7 +1224,7 @@ void MenuItem::executeClick()
{
// Send the message
Message* msg = new Message(kExecuteMenuItemMessage);
msg->addRecipient(this);
msg->setRecipient(this);
Manager::getDefault()->enqueueMessage(msg);
}

View File

@ -23,6 +23,8 @@ namespace ui {
Message::Message(MessageType type, KeyModifiers modifiers)
: m_type(type)
, m_flags(0)
, m_recipient(nullptr)
, m_commonAncestor(nullptr)
{
if (modifiers == kKeyUninitializedModifier && os::instance())
m_modifiers = os::instance()->keyModifiers();
@ -34,31 +36,17 @@ Message::~Message()
{
}
void Message::addRecipient(Widget* widget)
void Message::setRecipient(Widget* widget)
{
ASSERT(m_recipient == nullptr);
ASSERT_VALID_WIDGET(widget);
m_recipients.push_back(widget);
m_recipient = widget;
}
void Message::removeRecipient(Widget* widget)
{
for (WidgetsList::iterator
it = m_recipients.begin(),
end = m_recipients.end(); it != end; ++it) {
if (*it == widget)
*it = NULL;
}
}
void Message::broadcastToChildren(Widget* widget)
{
ASSERT_VALID_WIDGET(widget);
for (auto child : widget->children())
broadcastToChildren(child);
addRecipient(widget);
if (m_recipient == widget)
m_recipient = nullptr;
}
KeyMessage::KeyMessage(MessageType type,

View File

@ -40,8 +40,7 @@ namespace ui {
virtual ~Message();
MessageType type() const { return m_type; }
const WidgetsList& recipients() const { return m_recipients; }
bool hasRecipients() const { return !m_recipients.empty(); }
Widget* recipient() const { return m_recipient; }
bool fromFilter() const { return hasFlag(FromFilter); }
void setFromFilter(const bool state) { setFlag(FromFilter, state); }
KeyModifiers modifiers() const { return m_modifiers; }
@ -56,16 +55,17 @@ namespace ui {
bool onlyCmdPressed() const { return m_modifiers == kKeyCmdModifier; }
bool onlyWinPressed() const { return m_modifiers == kKeyWinModifier; }
void addRecipient(Widget* widget);
void setRecipient(Widget* widget);
void removeRecipient(Widget* widget);
void broadcastToChildren(Widget* widget);
bool propagateToChildren() const { return hasFlag(PropagateToChildren); }
bool propagateToParent() const { return hasFlag(PropagateToParent); }
void setPropagateToChildren(const bool state) { setFlag(PropagateToChildren, state); }
void setPropagateToParent(const bool state) { setFlag(PropagateToParent, state); }
Widget* commonAncestor() { return m_commonAncestor; }
void setCommonAncestor(Widget* widget) { m_commonAncestor = widget; }
private:
bool hasFlag(const Flags flag) const {
return (m_flags & flag) == flag;
@ -76,8 +76,9 @@ namespace ui {
}
MessageType m_type; // Type of message
WidgetsList m_recipients; // List of recipients of the message
int m_flags; // Special flags for this message
Widget* m_recipient; // Recipient of this message
Widget* m_commonAncestor; // Common ancestor between the Leave <-> Enter messages
KeyModifiers m_modifiers; // Key modifiers pressed when message was created
};

View File

@ -1,4 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This file is released under the terms of the MIT license.
@ -355,7 +356,7 @@ void execute_from_ui_thread(std::function<void()>&& f)
ASSERT(man);
FunctionMessage* msg = new FunctionMessage(std::move(f));
msg->addRecipient(man);
msg->setRecipient(man);
man->enqueueMessage(msg);
}

View File

@ -1,4 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2017 David Capello
//
// This file is released under the terms of the MIT license.
@ -91,7 +92,7 @@ void Timer::pollTimers()
ASSERT(timer->m_owner != nullptr);
Message* msg = new TimerMessage(count, timer);
msg->addRecipient(timer->m_owner);
msg->setRecipient(timer->m_owner);
Manager::getDefault()->enqueueMessage(msg);
}
}

View File

@ -1,4 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This file is released under the terms of the MIT license.
@ -65,7 +66,7 @@ bool TooltipManager::onProcessMessage(Message* msg)
switch (msg->type()) {
case kMouseEnterMessage: {
for (Widget* widget : msg->recipients()) {
if (Widget* widget = msg->recipient()) {
Tips::iterator it = m_tips.find(widget);
if (it != m_tips.end()) {
m_target.widget = it->first;
@ -79,7 +80,7 @@ bool TooltipManager::onProcessMessage(Message* msg)
m_timer->start();
}
}
return false;
break;
}
case kKeyDownMessage:

View File

@ -409,20 +409,6 @@ Manager* Widget::manager() const
return Manager::getDefault();
}
void Widget::getParents(bool ascendant, WidgetsList& parents)
{
assert_ui_thread();
for (Widget* widget=this; widget; widget=widget->m_parent) {
// append parents in tail
if (ascendant)
parents.push_back(widget);
// append parents in head
else
parents.insert(parents.begin(), widget);
}
}
Widget* Widget::nextSibling()
{
assert_ui_thread();
@ -983,7 +969,7 @@ void Widget::flushRedraw()
for (c=0; c<nrects; ++c, ++it, --count) {
// Create the draw message
msg = new PaintMessage(count, *it);
msg->addRecipient(widget);
msg->setRecipient(widget);
// Enqueue the draw message
manager->enqueueMessage(msg);
@ -1282,10 +1268,8 @@ void Widget::releaseFocus()
manager()->freeFocus();
}
/**
* Captures the mouse to send all the future mouse messsages to the
* specified widget (included the kMouseMoveMessage and kSetCursorMessage).
*/
// Captures the mouse to send all the future mouse messsages to the
// specified widget (included the kMouseMoveMessage and kSetCursorMessage).
void Widget::captureMouse()
{
if (!manager()->getCapture()) {
@ -1293,9 +1277,7 @@ void Widget::captureMouse()
}
}
/**
* Releases the capture of the mouse events.
*/
// Releases the capture of the mouse events.
void Widget::releaseMouse()
{
if (manager()->getCapture() == this) {
@ -1316,7 +1298,7 @@ bool Widget::offerCapture(ui::MouseMessage* mouseMsg, int widget_type)
mouseMsg->buttons(),
mouseMsg->modifiers(),
mouseMsg->position());
mouseMsg2->addRecipient(pick);
mouseMsg2->setRecipient(pick);
manager()->enqueueMessage(mouseMsg2);
return true;
}
@ -1324,26 +1306,11 @@ bool Widget::offerCapture(ui::MouseMessage* mouseMsg, int widget_type)
return false;
}
bool Widget::hasFocus() const
{
return hasFlags(HAS_FOCUS);
}
bool Widget::hasMouse() const
{
return hasFlags(HAS_MOUSE);
}
bool Widget::hasMouseOver() const
{
return (this == pick(get_mouse_position()));
}
bool Widget::hasCapture() const
{
return hasFlags(HAS_CAPTURE);
}
void Widget::setMnemonic(int mnemonic)
{
m_mnemonic = mnemonic;
@ -1433,7 +1400,7 @@ bool Widget::onProcessMessage(Message* msg)
case kMouseMoveMessage:
case kMouseWheelMessage:
// Propagate the message to the parent.
if (parent() != NULL)
if (parent())
return parent()->sendMessage(msg);
else
break;
@ -1446,6 +1413,7 @@ bool Widget::onProcessMessage(Message* msg)
set_mouse_cursor(kArrowCursor);
return true;
}
break;
}
@ -1457,8 +1425,10 @@ bool Widget::onProcessMessage(Message* msg)
}
// Propagate the message to the parent.
if (msg->propagateToParent() && parent())
if (msg->propagateToParent() && parent() &&
msg->commonAncestor() != parent()) {
return parent()->sendMessage(msg);
}
return false;
}

View File

@ -165,11 +165,6 @@ namespace ui {
Widget* parent() const { return m_parent; }
Manager* manager() const;
// Returns a list of parents, if "ascendant" is true the list is
// build from child to parents, else the list is from parent to
// children.
void getParents(bool ascendant, WidgetsList& parents);
// Returns a list of children.
const WidgetsList& children() const { return m_children; }
@ -341,10 +336,10 @@ namespace ui {
void captureMouse();
void releaseMouse();
bool hasFocus() const;
bool hasMouse() const;
bool hasFocus() const { return hasFlags(HAS_FOCUS); }
bool hasMouse() const { return hasFlags(HAS_MOUSE); }
bool hasCapture() const { return hasFlags(HAS_CAPTURE); }
bool hasMouseOver() const;
bool hasCapture() const;
// Offer the capture to widgets of the given type. Returns true if
// the capture was passed to other widget.

View File

@ -609,7 +609,7 @@ void Window::moveWindow(const gfx::Rect& rect, bool use_blit)
// Send a kWinMoveMessage message to the window
Message* msg = new Message(kWinMoveMessage);
msg->addRecipient(this);
msg->setRecipient(this);
manager->enqueueMessage(msg);
// Get the region & the drawable region of the window