From e9d67860de245022374ea225aee5956ecb4dd79b Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Mon, 4 Jul 2011 04:58:56 +1200 Subject: [PATCH] Proper mouseover support. --- OpenRA.Game/Widgets/ButtonWidget.cs | 2 +- OpenRA.Game/Widgets/CheckboxWidget.cs | 2 +- OpenRA.Game/Widgets/ScrollItem.cs | 4 +++- OpenRA.Game/Widgets/ScrollPanelWidget.cs | 20 ++++++++++--------- OpenRA.Game/Widgets/SliderWidget.cs | 3 ++- OpenRA.Game/Widgets/TextFieldWidget.cs | 2 +- OpenRA.Game/Widgets/Widget.cs | 19 ++++++++++++++++-- .../Widgets/ProductionTabsWidget.cs | 12 ++++++----- mods/cnc/chrome/lobby.yaml | 3 +++ mods/cnc/chrome/preferences.yaml | 1 + 10 files changed, 47 insertions(+), 21 deletions(-) diff --git a/OpenRA.Game/Widgets/ButtonWidget.cs b/OpenRA.Game/Widgets/ButtonWidget.cs index d118aab5ed..7a77bd97d3 100644 --- a/OpenRA.Game/Widgets/ButtonWidget.cs +++ b/OpenRA.Game/Widgets/ButtonWidget.cs @@ -117,7 +117,7 @@ namespace OpenRA.Widgets var s = font.Measure(text); var stateOffset = (Depressed) ? new int2(VisualHeight, VisualHeight) : new int2(0, 0); - DrawBackground("button", rb, disabled, Depressed, rb.Contains(Viewport.LastMousePos)); + DrawBackground("button", rb, disabled, Depressed, Widget.MouseOverWidget == this); font.DrawText(text, new int2(rb.X + (UsableWidth - s.X)/ 2, rb.Y + (Bounds.Height - s.Y) / 2) + stateOffset, disabled ? Color.Gray : Color.White); } diff --git a/OpenRA.Game/Widgets/CheckboxWidget.cs b/OpenRA.Game/Widgets/CheckboxWidget.cs index c08e0cb3f4..2c7e4b3e21 100644 --- a/OpenRA.Game/Widgets/CheckboxWidget.cs +++ b/OpenRA.Game/Widgets/CheckboxWidget.cs @@ -49,7 +49,7 @@ namespace OpenRA.Widgets var check = new Rectangle(rect.Location, new Size(Bounds.Height, Bounds.Height)); var state = disabled ? "checkbox-disabled" : Depressed && HasPressedState ? "checkbox-pressed" : - RenderBounds.Contains(Viewport.LastMousePos) ? "checkbox-hover" : + Widget.MouseOverWidget == this ? "checkbox-hover" : "checkbox"; WidgetUtils.DrawPanel(state, check); diff --git a/OpenRA.Game/Widgets/ScrollItem.cs b/OpenRA.Game/Widgets/ScrollItem.cs index e3ea0aea3b..71cf418544 100644 --- a/OpenRA.Game/Widgets/ScrollItem.cs +++ b/OpenRA.Game/Widgets/ScrollItem.cs @@ -21,6 +21,7 @@ namespace OpenRA.Widgets { IsVisible = () => false; VisualHeight = 0; + IgnoreChildMouseOver = true; } protected ScrollItemWidget(ScrollItemWidget other) @@ -28,6 +29,7 @@ namespace OpenRA.Widgets { IsVisible = () => false; VisualHeight = 0; + IgnoreChildMouseOver = true; } public Func IsSelected = () => false; @@ -35,7 +37,7 @@ namespace OpenRA.Widgets public override void Draw() { var state = IsSelected() ? "scrollitem-selected" : - RenderBounds.Contains(Viewport.LastMousePos) ? "scrollitem-hover" : + Widget.MouseOverWidget == this ? "scrollitem-hover" : null; if (state != null) diff --git a/OpenRA.Game/Widgets/ScrollPanelWidget.cs b/OpenRA.Game/Widgets/ScrollPanelWidget.cs index 7aeb31c0ad..46376ac333 100644 --- a/OpenRA.Game/Widgets/ScrollPanelWidget.cs +++ b/OpenRA.Game/Widgets/ScrollPanelWidget.cs @@ -75,20 +75,22 @@ namespace OpenRA.Widgets downButtonRect = new Rectangle(rb.Right - ScrollbarWidth, rb.Bottom - ScrollbarWidth, ScrollbarWidth, ScrollbarWidth); scrollbarRect = new Rectangle(rb.Right - ScrollbarWidth, rb.Y + ScrollbarWidth - 1, ScrollbarWidth, ScrollbarHeight + 2); thumbRect = new Rectangle(rb.Right - ScrollbarWidth, thumbOrigin, ScrollbarWidth, thumbHeight); - + + var upHover = Widget.MouseOverWidget == this && upButtonRect.Contains(Viewport.LastMousePos); + var upDisabled = thumbHeight == 0 || ListOffset >= 0; + + var downHover = Widget.MouseOverWidget == this && downButtonRect.Contains(Viewport.LastMousePos); + var downDisabled = thumbHeight == 0 || ListOffset <= Bounds.Height - ContentHeight; + + var thumbHover = Widget.MouseOverWidget == this && thumbRect.Contains(Viewport.LastMousePos); WidgetUtils.DrawPanel(Background, backgroundRect); WidgetUtils.DrawPanel("scrollpanel-bg", scrollbarRect); - ButtonWidget.DrawBackground("button", upButtonRect, (thumbHeight == 0 || ListOffset >= 0), - UpPressed, upButtonRect.Contains(Viewport.LastMousePos)); - ButtonWidget.DrawBackground("button", downButtonRect, (thumbHeight == 0 || ListOffset <= Bounds.Height - ContentHeight), - DownPressed, downButtonRect.Contains(Viewport.LastMousePos)); + ButtonWidget.DrawBackground("button", upButtonRect, upDisabled, UpPressed, upHover); + ButtonWidget.DrawBackground("button", downButtonRect, downDisabled, DownPressed, downHover); if (thumbHeight > 0) - ButtonWidget.DrawBackground("scrollthumb", thumbRect, false, (Focused && thumbRect.Contains(Viewport.LastMousePos)), - thumbRect.Contains(Viewport.LastMousePos)); + ButtonWidget.DrawBackground("scrollthumb", thumbRect, false, Focused && thumbHover, thumbHover); - var upDisabled = thumbHeight == 0 || ListOffset >= 0; - var downDisabled = thumbHeight == 0 || ListOffset <= Bounds.Height - ContentHeight; var upOffset = !UpPressed || upDisabled ? 4 : 4 + ButtonDepth; var downOffset = !DownPressed || downDisabled ? 4 : 4 + ButtonDepth; diff --git a/OpenRA.Game/Widgets/SliderWidget.cs b/OpenRA.Game/Widgets/SliderWidget.cs index 1288e9b7f1..06763d34fa 100755 --- a/OpenRA.Game/Widgets/SliderWidget.cs +++ b/OpenRA.Game/Widgets/SliderWidget.cs @@ -196,7 +196,8 @@ namespace OpenRA.Widgets WidgetUtils.DrawPanel("slider-track", trackRect); // Thumb - ButtonWidget.DrawBackground("scrollthumb", tr, IsDisabled(), isMoving, tr.Contains(Viewport.LastMousePos)); + var thumbHover = Widget.MouseOverWidget == this && tr.Contains(Viewport.LastMousePos); + ButtonWidget.DrawBackground("scrollthumb", tr, IsDisabled(), isMoving, thumbHover); } } } diff --git a/OpenRA.Game/Widgets/TextFieldWidget.cs b/OpenRA.Game/Widgets/TextFieldWidget.cs index b8748e5136..8d5f156c63 100644 --- a/OpenRA.Game/Widgets/TextFieldWidget.cs +++ b/OpenRA.Game/Widgets/TextFieldWidget.cs @@ -203,7 +203,7 @@ namespace OpenRA.Widgets var disabled = IsDisabled(); var state = disabled ? "textfield-disabled" : Focused ? "textfield-focused" : - RenderBounds.Contains(Viewport.LastMousePos) ? "textfield-hover" : + Widget.MouseOverWidget == this ? "textfield-hover" : "textfield"; WidgetUtils.DrawPanel(state, diff --git a/OpenRA.Game/Widgets/Widget.cs b/OpenRA.Game/Widgets/Widget.cs index ec08e5ae84..b8b801ad84 100644 --- a/OpenRA.Game/Widgets/Widget.cs +++ b/OpenRA.Game/Widgets/Widget.cs @@ -28,6 +28,7 @@ namespace OpenRA.Widgets static Widget rootWidget = new ContainerWidget(); static Stack WindowList = new Stack(); public static Widget SelectedWidget; + public static Widget MouseOverWidget; public static void CloseWindow() { @@ -68,7 +69,10 @@ namespace OpenRA.Widgets public static bool DoHandleInput(MouseInput mi) { - bool handled = false; + if (mi.Event == MouseInputEvent.Move) + MouseOverWidget = null; + + bool handled = false; if (SelectedWidget != null && SelectedWidget.HandleMouseInputOuter(mi)) handled = true; @@ -80,6 +84,7 @@ namespace OpenRA.Widgets Viewport.LastMousePos = mi.Location; Viewport.TicksSinceLastMove = 0; } + return handled; } @@ -110,6 +115,7 @@ namespace OpenRA.Widgets public string Logic = null; public object LogicObject { get; private set; } public bool Visible = true; + public bool IgnoreChildMouseOver; // Calculated internally public Rectangle Bounds; @@ -132,6 +138,7 @@ namespace OpenRA.Widgets Parent = widget.Parent; IsVisible = widget.IsVisible; + IgnoreChildMouseOver = widget.IgnoreChildMouseOver; foreach (var child in widget.Children) AddChild(child.Clone()); @@ -215,6 +222,7 @@ namespace OpenRA.Widgets if (SelectedWidget != null && !SelectedWidget.LoseFocus(mi)) return false; + SelectedWidget = this; return true; } @@ -255,15 +263,22 @@ namespace OpenRA.Widgets public virtual bool HandleMouseInput(MouseInput mi) { return false; } public bool HandleMouseInputOuter(MouseInput mi) { - // Are we able to handle this event? + // Are we able to handle this event? if (!(Focused || (IsVisible() && GetEventBounds().Contains(mi.Location.X, mi.Location.Y)))) return false; + var oldMouseOver = MouseOverWidget; // Send the event to the deepest children first and bubble up if unhandled foreach (var child in Children.OfType().Reverse()) if (child.HandleMouseInputOuter(mi)) return true; + if (IgnoreChildMouseOver) + MouseOverWidget = oldMouseOver; + + if (mi.Event == MouseInputEvent.Move && MouseOverWidget == null) + MouseOverWidget = this; + return HandleMouseInput(mi); } diff --git a/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs b/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs index 8a63971e42..1aed6a7c95 100755 --- a/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs +++ b/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs @@ -107,13 +107,13 @@ namespace OpenRA.Mods.Cnc.Widgets rightButtonRect = new Rectangle(rb.Right - ArrowWidth, rb.Y, ArrowWidth, rb.Height); var leftDisabled = ListOffset >= 0; + var leftHover = Widget.MouseOverWidget == this && leftButtonRect.Contains(Viewport.LastMousePos); var rightDisabled = ListOffset <= Bounds.Width - rightButtonRect.Width - leftButtonRect.Width - ContentWidth; + var rightHover = Widget.MouseOverWidget == this && rightButtonRect.Contains(Viewport.LastMousePos); WidgetUtils.DrawPanel("panel-black", rb); - ButtonWidget.DrawBackground("button", leftButtonRect, leftDisabled, - leftPressed, leftButtonRect.Contains(Viewport.LastMousePos)); - ButtonWidget.DrawBackground("button", rightButtonRect, rightDisabled, - rightPressed, rightButtonRect.Contains(Viewport.LastMousePos)); + ButtonWidget.DrawBackground("button", leftButtonRect, leftDisabled, leftPressed, leftHover); + ButtonWidget.DrawBackground("button", rightButtonRect, rightDisabled, rightPressed, rightHover); WidgetUtils.DrawRGBA(ChromeProvider.GetImage("scrollbar", leftPressed || leftDisabled ? "up_pressed" : "up_arrow"), new float2(leftButtonRect.Left + 2, leftButtonRect.Top + 2)); @@ -126,10 +126,12 @@ namespace OpenRA.Mods.Cnc.Widgets var origin = new int2(leftButtonRect.Right - 1 + (int)ListOffset, leftButtonRect.Y); SpriteFont font = Game.Renderer.Fonts["TinyBold"]; ContentWidth = 0; + foreach (var tab in Groups[queueGroup].Tabs) { var rect = new Rectangle(origin.X + ContentWidth, origin.Y, TabWidth, rb.Height); - ButtonWidget.DrawBackground("button", rect, false, tab.Queue == palette.CurrentQueue, rect.Contains(Viewport.LastMousePos)); + var hover = !leftHover && !rightHover && Widget.MouseOverWidget == this && rect.Contains(Viewport.LastMousePos); + ButtonWidget.DrawBackground("button", rect, false, tab.Queue == palette.CurrentQueue, hover); ContentWidth += TabWidth - 1; int2 textSize = font.Measure(tab.Name); diff --git a/mods/cnc/chrome/lobby.yaml b/mods/cnc/chrome/lobby.yaml index 1d54868e04..01b500c536 100644 --- a/mods/cnc/chrome/lobby.yaml +++ b/mods/cnc/chrome/lobby.yaml @@ -82,6 +82,7 @@ Container@SERVER_LOBBY: Height:25 X:155 Font:Regular + IgnoreChildMouseOver: true Children: ColorBlock@COLORBLOCK: Id:COLORBLOCK @@ -95,6 +96,7 @@ Container@SERVER_LOBBY: Height:25 X:230 Font:Regular + IgnoreChildMouseOver: true Children: Image@FACTIONFLAG: Id:FACTIONFLAG @@ -260,6 +262,7 @@ Container@SERVER_LOBBY: Height:25 X:155 Font:Regular + IgnoreChildMouseOver: true Children: ColorBlock@COLORBLOCK: Id:COLORBLOCK diff --git a/mods/cnc/chrome/preferences.yaml b/mods/cnc/chrome/preferences.yaml index b8815c6da5..39e334b659 100644 --- a/mods/cnc/chrome/preferences.yaml +++ b/mods/cnc/chrome/preferences.yaml @@ -46,6 +46,7 @@ Container@SETTINGS_PANEL: Y:40 Width:80 Height:25 + IgnoreChildMouseOver: true Children: ColorBlock@COLORBLOCK: Id:COLORBLOCK