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.
This commit is contained in:
David Capello 2014-04-26 11:09:59 -03:00
parent 5d824512c2
commit 15a3b6ac2c
10 changed files with 43 additions and 19 deletions

View File

@ -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).

View File

@ -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;

View File

@ -45,6 +45,7 @@ FileList::FileList()
{
setFocusStop(true);
setDoubleBuffered(true);
setDoubleClickeable(true);
m_currentFolder = FileSystemModule::instance()->getRootFileItem();
m_req_valid = false;

View File

@ -161,6 +161,7 @@ Timeline::Timeline()
m_context->addObserver(this);
setDoubleBuffered(true);
setDoubleClickeable(true);
}
Timeline::~Timeline()

View File

@ -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:

View File

@ -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();
}

View File

@ -28,6 +28,7 @@ ListBox::ListBox()
: Widget(kListBoxWidget)
{
setFocusStop(true);
setDoubleClickeable(true);
initTheme();
}

View File

@ -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)

View File

@ -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
// ===============================================================

View File

@ -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
// ===============================================================