From 15a3b6ac2c96378893fb5e33b64a1f3f0584ee8b Mon Sep 17 00:00:00 2001 From: David Capello Date: Sat, 26 Apr 2014 11:09:59 -0300 Subject: [PATCH] Fix double-click issues - Fix double-click behavior when double-clicks are generated from Manager::generateMouseMessages(). - Add Widget::setDoubleClickeable/isDoubleClickeable() member functions for widgets that accept double-clicks. --- src/allegro/README.md | 2 ++ src/allegro/src/win/wwnd.c | 2 +- src/app/ui/file_list.cpp | 1 + src/app/ui/timeline.cpp | 1 + src/ui/base.h | 1 + src/ui/entry.cpp | 3 ++- src/ui/listbox.cpp | 1 + src/ui/manager.cpp | 34 +++++++++++++++++----------------- src/ui/widget.cpp | 13 +++++++++++++ src/ui/widget.h | 4 ++++ 10 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/allegro/README.md b/src/allegro/README.md index f38a43aaa..6d11f4cbb 100644 --- a/src/allegro/README.md +++ b/src/allegro/README.md @@ -10,3 +10,5 @@ Changes: * Added resize support for Windows, X11, and Mac OS X ports. * Removed code and functions that are not used (Allegro GUI, audio, MIDI, joystick, etc.). +* The HWND class has CS_DBLCLKS enabled (so UI code can detect + double-clicks from Windows messages). diff --git a/src/allegro/src/win/wwnd.c b/src/allegro/src/win/wwnd.c index 37bd9e82e..cb0c07853 100644 --- a/src/allegro/src/win/wwnd.c +++ b/src/allegro/src/win/wwnd.c @@ -427,7 +427,7 @@ static HWND create_directx_window(void) if (first) { /* setup the window class */ - wnd_class.style = CS_HREDRAW | CS_VREDRAW; + wnd_class.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; wnd_class.lpfnWndProc = directx_wnd_proc; wnd_class.cbClsExtra = 0; wnd_class.cbWndExtra = 0; diff --git a/src/app/ui/file_list.cpp b/src/app/ui/file_list.cpp index a37118d82..2aee4357d 100644 --- a/src/app/ui/file_list.cpp +++ b/src/app/ui/file_list.cpp @@ -45,6 +45,7 @@ FileList::FileList() { setFocusStop(true); setDoubleBuffered(true); + setDoubleClickeable(true); m_currentFolder = FileSystemModule::instance()->getRootFileItem(); m_req_valid = false; diff --git a/src/app/ui/timeline.cpp b/src/app/ui/timeline.cpp index e016cf708..beebb766e 100644 --- a/src/app/ui/timeline.cpp +++ b/src/app/ui/timeline.cpp @@ -161,6 +161,7 @@ Timeline::Timeline() m_context->addObserver(this); setDoubleBuffered(true); + setDoubleClickeable(true); } Timeline::~Timeline() diff --git a/src/ui/base.h b/src/ui/base.h index bf3ddc9d2..7f1d779bb 100644 --- a/src/ui/base.h +++ b/src/ui/base.h @@ -58,6 +58,7 @@ namespace ui { #define JI_INITIALIZED 0x0400 // The widget was already initialized by a theme. #define JI_DIRTY 0x0800 // The widget (or one child) is dirty (update_region != empty). #define JI_HASTEXT 0x1000 // The widget has text (at least setText() was called one time). +#define JI_DOUBLECLICKABLE 0x2000 // The widget accepts double-clicks class GuiSystem { public: diff --git a/src/ui/entry.cpp b/src/ui/entry.cpp index 018b9a2c8..16b79ee45 100644 --- a/src/ui/entry.cpp +++ b/src/ui/entry.cpp @@ -61,7 +61,8 @@ Entry::Entry(size_t maxsize, const char *format, ...) /* widget->align = JI_LEFT | JI_MIDDLE; */ setText(buf); - this->setFocusStop(true); + setFocusStop(true); + setDoubleClickeable(true); initTheme(); } diff --git a/src/ui/listbox.cpp b/src/ui/listbox.cpp index 00ecbcbaa..54d7a1478 100644 --- a/src/ui/listbox.cpp +++ b/src/ui/listbox.cpp @@ -28,6 +28,7 @@ ListBox::ListBox() : Widget(kListBoxWidget) { setFocusStop(true); + setDoubleClickeable(true); initTheme(); } diff --git a/src/ui/manager.cpp b/src/ui/manager.cpp index 13d6bbf51..61b59e688 100644 --- a/src/ui/manager.cpp +++ b/src/ui/manager.cpp @@ -300,10 +300,11 @@ void Manager::generateMouseMessages() ((jmouse_b(1) & 2) == 0 && (jmouse_b(0) & 2) == 2) || ((jmouse_b(1) & 4) == 0 && (jmouse_b(0) & 4) == 4); MessageType msgType = (pressed ? kMouseDownMessage: kMouseUpMessage); + MouseButtons mouseButtons = (pressed ? currentMouseButtons(0): currentMouseButtons(1)); // The message will include which button was pressed or released. // (This doesn't represent all buttons that are currently pushed.) - MouseButtons mouseButtons = (MouseButtons) + MouseButtons mouseButtonsDelta = (MouseButtons) (currentMouseButtons(0) ^ currentMouseButtons(1)); ////////////////////////////////////////////////////////////////////// @@ -341,28 +342,22 @@ void Manager::generateMouseMessages() if (current_ticks - double_click_ticks > DOUBLE_CLICK_TIMEOUT_MSECS) { double_click_level = DOUBLE_CLICK_NONE; } - else if (double_click_buttons == mouseButtons) { - if (double_click_level == DOUBLE_CLICK_DOWN) { - double_click_level = DOUBLE_CLICK_UP; - double_click_ticks = current_ticks; - } - } - // Press other button, back to NONE - else { - double_click_level = DOUBLE_CLICK_NONE; + else if (double_click_level == DOUBLE_CLICK_DOWN) { + double_click_level = DOUBLE_CLICK_UP; + double_click_ticks = current_ticks; } } } switch (msgType) { case kMouseDownMessage: - handleMouseDown(mousePos, mouseButtons); + handleMouseDown(mousePos, mouseButtonsDelta); break; case kMouseUpMessage: - handleMouseUp(mousePos, mouseButtons); + handleMouseUp(mousePos, mouseButtonsDelta); break; case kDoubleClickMessage: - handleMouseDoubleClick(mousePos, mouseButtons); + handleMouseDoubleClick(mousePos, mouseButtonsDelta); break; } } @@ -518,7 +513,7 @@ void Manager::generateMessagesFromSheEvents() continue; MouseButtons clickedButton = mouse_buttons_from_she_to_ui(sheEvent); - handleMouseUp(sheEvent.position(), clickedButton); + handleMouseDoubleClick(sheEvent.position(), clickedButton); break; } @@ -583,9 +578,14 @@ void Manager::handleMouseUp(const gfx::Point& mousePos, MouseButtons mouseButton void Manager::handleMouseDoubleClick(const gfx::Point& mousePos, MouseButtons mouseButtons) { - enqueueMessage(newMouseMessage(kDoubleClickMessage, - (capture_widget ? capture_widget: mouse_widget), - mousePos, mouseButtons)); + Widget* dst = (capture_widget ? capture_widget: mouse_widget); + if (dst && dst->isDoubleClickeable()) { + enqueueMessage(newMouseMessage(kDoubleClickMessage, + dst, mousePos, mouseButtons)); + } + else { + handleMouseDown(mousePos, mouseButtons); + } } void Manager::handleMouseWheel(const gfx::Point& mousePos, MouseButtons mouseButtons, int delta) diff --git a/src/ui/widget.cpp b/src/ui/widget.cpp index f69ecf8f2..66c450dd6 100644 --- a/src/ui/widget.cpp +++ b/src/ui/widget.cpp @@ -277,6 +277,14 @@ void Widget::setFocusMagnet(bool state) this->flags &= ~JI_FOCUSMAGNET; } +void Widget::setDoubleClickeable(bool state) +{ + if (state) + this->flags |= JI_DOUBLECLICKABLE; + else + this->flags &= ~JI_DOUBLECLICKABLE; +} + bool Widget::isVisible() const { const Widget* widget = this; @@ -330,6 +338,11 @@ bool Widget::isFocusMagnet() const return (this->flags & JI_FOCUSMAGNET) ? true: false; } +bool Widget::isDoubleClickeable() const +{ + return (this->flags & JI_DOUBLECLICKABLE) ? true: false; +} + // =============================================================== // PARENTS & CHILDREN // =============================================================== diff --git a/src/ui/widget.h b/src/ui/widget.h index e1e0bf654..9d5e1a341 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -139,6 +139,10 @@ namespace ui { void setFocusMagnet(bool state); bool isFocusMagnet() const; + // True if this widget wants double-clicks. + void setDoubleClickeable(bool state); + bool isDoubleClickeable() const; + // =============================================================== // LOOK & FEEL // ===============================================================