fixed issue #13 - at least for win32 platform

This commit is contained in:
Vadim Lopatin 2014-12-10 11:15:54 +03:00
parent 4ee330fb7c
commit 0e3d0db945
3 changed files with 81 additions and 29 deletions

View File

@ -28,6 +28,10 @@ import dlangui.graphics.drawbuf;
private import dlangui.graphics.gldrawbuf;
private import std.algorithm;
// specify debug=DebugMouseEvents for logging mouse handling
// specify debug=DebugRedraw for logging drawing and layouts handling
// specify debug=DebugKeys for logging of key events
/// window creation flags
enum WindowFlag : uint {
/// window can be resized
@ -202,12 +206,14 @@ class Window {
long measureStart = currentTimeMillis;
measure();
long measureEnd = currentTimeMillis;
if (measureEnd - measureStart > PERFORMANCE_LOGGING_THRESHOLD_MS)
Log.d("measure took ", measureEnd - measureStart, " ms");
if (measureEnd - measureStart > PERFORMANCE_LOGGING_THRESHOLD_MS) {
debug(DebugRedraw) Log.d("measure took ", measureEnd - measureStart, " ms");
}
layout();
long layoutEnd = currentTimeMillis;
if (layoutEnd - measureEnd > PERFORMANCE_LOGGING_THRESHOLD_MS)
Log.d("layout took ", layoutEnd - measureEnd, " ms");
if (layoutEnd - measureEnd > PERFORMANCE_LOGGING_THRESHOLD_MS) {
debug(DebugRedraw) Log.d("layout took ", layoutEnd - measureEnd, " ms");
}
//checkUpdateNeeded(needDraw, needLayout, animationActive);
}
long drawStart = currentTimeMillis;
@ -217,8 +223,10 @@ class Window {
foreach(p; _popups)
p.onDraw(buf);
long drawEnd = currentTimeMillis;
if (drawEnd - drawStart > PERFORMANCE_LOGGING_THRESHOLD_MS)
Log.d("draw took ", drawEnd - drawStart, " ms");
debug(DebugRedraw) {
if (drawEnd - drawStart > PERFORMANCE_LOGGING_THRESHOLD_MS)
Log.d("draw took ", drawEnd - drawStart, " ms");
}
if (animationActive)
scheduleAnimation();
}
@ -254,7 +262,7 @@ class Window {
if (newFocus is null || isChild(newFocus)) {
if (newFocus !is null) {
// when calling, setState(focused), window.focusedWidget is still previously focused widget
Log.d("new focus: ", newFocus.id);
debug(DebugFocus) Log.d("new focus: ", newFocus.id);
newFocus.setState(State.Focused);
}
_focusedWidget = newFocus;
@ -283,7 +291,7 @@ class Window {
if (event.action == KeyAction.KeyDown || event.action == KeyAction.KeyUp) {
_keyboardModifiers = event.flags;
if (event.keyCode == KeyCode.ALT || event.keyCode == KeyCode.LALT || event.keyCode == KeyCode.RALT) {
Log.d("ALT key: keyboardModifiers = ", _keyboardModifiers);
debug(DebugKeys) Log.d("ALT key: keyboardModifiers = ", _keyboardModifiers);
if (_mainWidget) {
_mainWidget.invalidate();
res = true;
@ -329,9 +337,9 @@ class Window {
}
// if not processed by children, offer event to root
if (sendAndCheckOverride(root, event)) {
debug(mouse) Log.d("MouseEvent is processed");
debug(DebugMouseEvents) Log.d("MouseEvent is processed");
if (event.action == MouseAction.ButtonDown && _mouseCaptureWidget is null && !event.doNotTrackButtonDown) {
debug(mouse) Log.d("Setting active widget");
debug(DebugMouseEvents) Log.d("Setting active widget");
setCaptureWidget(root, event);
} else if (event.action == MouseAction.Move) {
addTracking(root);
@ -393,11 +401,17 @@ class Window {
/// does current capture widget want to receive move events even if pointer left it
protected bool _mouseCaptureFocusedOutTrackMovements;
protected void clearMouseCapture() {
_mouseCaptureWidget = null;
_mouseCaptureFocusedOut = false;
_mouseCaptureFocusedOutTrackMovements = false;
_mouseCaptureButtons = 0;
}
protected bool dispatchCancel(MouseEvent event) {
event.changeAction(MouseAction.Cancel);
bool res = _mouseCaptureWidget.onMouseEvent(event);
_mouseCaptureWidget = null;
_mouseCaptureFocusedOut = false;
clearMouseCapture();
return res;
}
@ -411,6 +425,11 @@ class Window {
return res;
}
/// returns true if mouse is currently captured
bool isMouseCaptured() {
return (_mouseCaptureWidget !is null && isChild(_mouseCaptureWidget));
}
/// dispatch mouse event to window content widgets
bool dispatchMouseEvent(MouseEvent event) {
// ignore events if there is no root
@ -418,19 +437,23 @@ class Window {
return false;
// check if _mouseCaptureWidget and _mouseTrackingWidget still exist in child of root widget
if (_mouseCaptureWidget !is null && !isChild(_mouseCaptureWidget))
_mouseCaptureWidget = null;
if (_mouseCaptureWidget !is null && !isChild(_mouseCaptureWidget)) {
clearMouseCapture();
}
//Log.d("dispatchMouseEvent ", event.action, " (", event.x, ",", event.y, ")");
debug(DebugMouseEvents) Log.d("dispatchMouseEvent ", event.action, " (", event.x, ",", event.y, ")");
bool res = false;
ushort currentButtons = event.flags & (MouseFlag.LButton|MouseFlag.RButton|MouseFlag.MButton);
if (_mouseCaptureWidget !is null) {
// try to forward message directly to active widget
if (event.action == MouseAction.Move) {
debug(DebugMouseEvents) Log.d("dispatchMouseEvent: Move; buttons state=", currentButtons);
if (!_mouseCaptureWidget.isPointInside(event.x, event.y)) {
if (currentButtons != _mouseCaptureButtons)
if (currentButtons != _mouseCaptureButtons) {
debug(DebugMouseEvents) Log.d("dispatchMouseEvent: Move; buttons state changed from ", _mouseCaptureButtons, " to ", currentButtons, " - cancelling capture");
return dispatchCancel(event);
}
// point is no more inside of captured widget
if (!_mouseCaptureFocusedOut) {
// sending FocusOut message
@ -462,15 +485,25 @@ class Window {
_mouseCaptureFocusedOut = true;
_mouseCaptureButtons = event.flags & (MouseFlag.LButton|MouseFlag.RButton|MouseFlag.MButton);
return sendAndCheckOverride(_mouseCaptureWidget, event);
} else {
debug(DebugMouseEvents) Log.d("dispatchMouseEvent: mouseCaptureFocusedOut + Leave - cancelling capture");
return dispatchCancel(event);
}
return true;
} else if (event.action == MouseAction.ButtonDown || event.action == MouseAction.ButtonUp) {
if (!_mouseCaptureWidget.isPointInside(event.x, event.y)) {
if (currentButtons != _mouseCaptureButtons) {
debug(DebugMouseEvents) Log.d("dispatchMouseEvent: ButtonUp/ButtonDown; buttons state changed from ", _mouseCaptureButtons, " to ", currentButtons, " - cancelling capture");
return dispatchCancel(event);
}
}
}
// other messages
res = sendAndCheckOverride(_mouseCaptureWidget, event);
if (!currentButtons) {
// usable capturing - no more buttons pressed
debug(mouse) Log.d("unsetting active widget");
_mouseCaptureWidget = null;
debug(DebugMouseEvents) Log.d("unsetting active widget");
clearMouseCapture();
}
return res;
}

View File

@ -23,6 +23,10 @@ version (USE_OPENGL) {
import dlangui.graphics.glsupport;
}
// specify debug=DebugMouseEvents for logging mouse handling
// specify debug=DebugRedraw for logging drawing and layouts handling
// specify debug=DebugKeys for logging of key events
pragma(lib, "gdi32.lib");
pragma(lib, "user32.lib");
@ -461,7 +465,7 @@ class Win32Window : Window {
private bool _mouseTracking;
private bool onMouse(uint message, uint flags, short x, short y) {
//Log.d("Win32 Mouse Message ", message, " flags=", flags, " x=", x, " y=", y);
debug(DebugMouseEvents) Log.d("Win32 Mouse Message ", message, " flags=", flags, " x=", x, " y=", y);
MouseButton button = MouseButton.None;
MouseAction action = MouseAction.ButtonDown;
ButtonDetails * pbuttonDetails = null;
@ -501,7 +505,7 @@ class Win32Window : Window {
pbuttonDetails = &_mbutton;
break;
case WM_MOUSELEAVE:
Log.d("WM_MOUSELEAVE");
debug(DebugMouseEvents) Log.d("WM_MOUSELEAVE");
action = MouseAction.Leave;
break;
case WM_MOUSEWHEEL:
@ -525,15 +529,17 @@ class Win32Window : Window {
} else if (action == MouseAction.ButtonUp) {
pbuttonDetails.up(x, y, cast(ushort)flags);
}
if (((message == WM_MOUSELEAVE) || (x < 0 || y < 0 || x > _dx || y > _dy)) && _mouseTracking) {
action = MouseAction.Leave;
Log.d("WM_MOUSELEAVE - releasing capture");
_mouseTracking = false;
ReleaseCapture();
if (((message == WM_MOUSELEAVE) || (x < 0 || y < 0 || x >= _dx || y >= _dy)) && _mouseTracking) {
if (!isMouseCaptured() || (!_lbutton.isDown && !_rbutton.isDown && !_mbutton.isDown)) {
action = MouseAction.Leave;
debug(DebugMouseEvents) Log.d("Win32Window.onMouse releasing capture");
_mouseTracking = false;
ReleaseCapture();
}
}
if (message != WM_MOUSELEAVE && !_mouseTracking) {
if (x >=0 && y >= 0 && x < _dx && y < _dy) {
Log.d("Setting capture");
debug(DebugMouseEvents) Log.d("Win32Window.onMouse Setting capture");
_mouseTracking = true;
SetCapture(_hwnd);
}
@ -544,7 +550,7 @@ class Win32Window : Window {
event.mbutton = _mbutton;
bool res = dispatchMouseEvent(event);
if (res) {
Log.d("Calling update() after mouse event");
//Log.v("Calling update() after mouse event");
update();
}
return res;
@ -587,7 +593,7 @@ class Win32Window : Window {
res = dispatchKeyEvent(event);
}
if (res) {
Log.d("Calling update() after key event");
debug(DebugRedraw) Log.d("Calling update() after key event");
update();
}
return res;

View File

@ -475,10 +475,16 @@ class ScrollBar : AbstractSlider, OnClickHandler {
return true;
}
if (event.action == MouseAction.FocusOut && _dragging) {
Log.d("ScrollBar slider dragging - FocusOut");
return true;
}
if (event.action == MouseAction.FocusIn && _dragging) {
Log.d("ScrollBar slider dragging - FocusIn");
return true;
}
if (event.action == MouseAction.Move && _dragging) {
int delta = _orientation == Orientation.Vertical ? event.y - _dragStart.y : event.x - _dragStart.x;
Log.d("ScrollBar slider dragging - Move delta=", delta);
Rect rc = _dragStartRect;
int offset;
int space;
@ -529,11 +535,18 @@ class ScrollBar : AbstractSlider, OnClickHandler {
}
return true;
}
if ((event.action == MouseAction.Leave || event.action == MouseAction.Cancel) && trackHover) {
if (event.action == MouseAction.Leave && trackHover) {
Log.d("Leave ", id);
resetState(State.Hovered);
return true;
}
if (event.action == MouseAction.Cancel && trackHover) {
Log.d("Cancel ? trackHover", id);
resetState(State.Hovered);
resetState(State.Pressed);
_dragging = false;
return true;
}
if (event.action == MouseAction.Cancel) {
Log.d("SliderButton.onMouseEvent event.action == MouseAction.Cancel");
resetState(State.Pressed);