From 01fcb4ba8c92ce5e9e64041c1eedf6a4c9e449f0 Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Mon, 14 Apr 2014 11:06:31 +0400 Subject: [PATCH] fix Hover tracking --- src/dlangui/graphics/resources.d | 2 +- src/dlangui/platforms/common/platform.d | 49 +++++++++++++++++-------- src/dlangui/widgets/widget.d | 6 ++- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/dlangui/graphics/resources.d b/src/dlangui/graphics/resources.d index ddd13b75..5c65002f 100644 --- a/src/dlangui/graphics/resources.d +++ b/src/dlangui/graphics/resources.d @@ -350,7 +350,7 @@ class StateDrawable : Drawable { string s = cast(string)std.file.read(filename); // Check for well-formedness - check(s); + //check(s); // Make a DOM tree auto doc = new Document(s); diff --git a/src/dlangui/platforms/common/platform.d b/src/dlangui/platforms/common/platform.d index a6faccc4..1c65a1a5 100644 --- a/src/dlangui/platforms/common/platform.d +++ b/src/dlangui/platforms/common/platform.d @@ -122,9 +122,9 @@ class Window { Log.d("Setting active widget"); _mouseCaptureWidget = root; _mouseCaptureButtons = event.flags & (MouseFlag.LButton|MouseFlag.RButton|MouseFlag.MButton); - } else if (event.action == MouseAction.Move && _mouseTrackingWidget is null) { + } else if (event.action == MouseAction.Move) { Log.d("Setting tracking widget"); - _mouseTrackingWidget = root; + addTracking(root); } return true; } @@ -132,7 +132,34 @@ class Window { } /// widget which tracks Move events - protected Widget _mouseTrackingWidget; + //protected Widget _mouseTrackingWidget; + protected Widget[] _mouseTrackingWidgets; + private void addTracking(Widget w) { + foreach(widget; _mouseTrackingWidgets) + if (widget is w) + return; + _mouseTrackingWidgets ~= w; + } + private bool checkRemoveTracking(MouseEvent event) { + import std.algorithm; + bool res = false; + for(int i = _mouseTrackingWidgets.length - 1; i >=0; i--) { + Widget w = _mouseTrackingWidgets[i]; + if (!_mainWidget.isChild(w)) { + _mouseTrackingWidgets.remove(i); + continue; + } + if (!w.isPointInside(event.x, event.y)) { + // send Leave message + MouseEvent leaveEvent = new MouseEvent(event); + leaveEvent.changeAction(MouseAction.Leave); + res = w.onMouseEvent(leaveEvent) || res; + _mouseTrackingWidgets.remove(i); + } + } + return res; + } + /// widget which tracks all events after processed ButtonDown protected Widget _mouseCaptureWidget; protected ushort _mouseCaptureButtons; @@ -157,8 +184,8 @@ class Window { // check if _mouseCaptureWidget and _mouseTrackingWidget still exist in child of root widget if (_mouseCaptureWidget !is null && !_mainWidget.isChild(_mouseCaptureWidget)) _mouseCaptureWidget = null; - if (_mouseTrackingWidget !is null && !_mainWidget.isChild(_mouseTrackingWidget)) - _mouseTrackingWidget = null; + + //Log.d("dispatchMouseEvent ", event.action, " (", event.x, ",", event.y, ")"); bool res = false; ushort currentButtons = event.flags & (MouseFlag.LButton|MouseFlag.RButton|MouseFlag.MButton); @@ -212,16 +239,8 @@ class Window { return res; } bool processed = false; - if (event.action == MouseAction.Move && _mouseTrackingWidget !is null) { - if (!_mouseTrackingWidget.isPointInside(event.x, event.y)) { - // send Leave message - MouseEvent leaveEvent = new MouseEvent(event); - leaveEvent.changeAction(MouseAction.Leave); - _mouseTrackingWidget.onMouseEvent(leaveEvent); - // stop tracking - _mouseTrackingWidget = null; - processed = true; - } + if (event.action == MouseAction.Move) { + processed = checkRemoveTracking(event); } if (!res) { res = dispatchMouseEvent(_mainWidget, event); diff --git a/src/dlangui/widgets/widget.d b/src/dlangui/widgets/widget.d index d5e49f33..7177d13e 100644 --- a/src/dlangui/widgets/widget.d +++ b/src/dlangui/widgets/widget.d @@ -306,6 +306,7 @@ class Widget { /// process mouse event; return true if event is processed by widget. bool onMouseEvent(MouseEvent event) { + //Log.d("onMouseEvent ", id, " ", event.action, " (", event.x, ",", event.y, ")"); // support onClick if (_onClickListener !is null) { if (event.action == MouseAction.ButtonDown && event.button == MouseButton.Left) { @@ -329,7 +330,10 @@ class Widget { } if (trackHover) { if (event.action == MouseAction.FocusOut || event.action == MouseAction.Cancel) { - resetState(State.Hovered); + if ((state & State.Hovered)) { + Log.d("Hover off ", id); + resetState(State.Hovered); + } return true; } if (event.action == MouseAction.Move) {