#region Copyright & License Information /* * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, * see COPYING. */ #endregion using System; using System.Drawing; using OpenRA.FileFormats; namespace OpenRA.Widgets { public class ButtonWidget : Widget { public Func GetKey = _ => Hotkey.Invalid; public Hotkey Key { get { return GetKey(this); } set { GetKey = _ => value; } } [Translate] public string Text = ""; public string Background = "button"; public bool Depressed = false; public int VisualHeight = ChromeMetrics.Get("ButtonDepth"); public string Font = ChromeMetrics.Get("ButtonFont"); public Color TextColor = ChromeMetrics.Get("ButtonTextColor"); public Color TextColorDisabled = ChromeMetrics.Get("ButtonTextColorDisabled"); public bool Contrast = ChromeMetrics.Get("ButtonTextContrast"); public Color ContrastColor = ChromeMetrics.Get("ButtonTextContrastColor"); public bool Disabled = false; public bool Highlighted = false; public Func GetText; public Func GetColor; public Func GetColorDisabled; public Func GetContrastColor; public Func IsDisabled; public Func IsHighlighted; public Action OnMouseDown = _ => {}; public Action OnMouseUp = _ => {}; Lazy tooltipContainer; public readonly string TooltipContainer; public readonly string TooltipTemplate = "BUTTON_TOOLTIP"; public string TooltipText; // Equivalent to OnMouseUp, but without an input arg public Action OnClick = () => {}; public Action OnDoubleClick = () => {}; public Action OnKeyPress = _ => {}; readonly Ruleset modRules; [ObjectCreator.UseCtor] public ButtonWidget(Ruleset modRules) { this.modRules = modRules; GetText = () => { return Text; }; GetColor = () => TextColor; GetColorDisabled = () => TextColorDisabled; GetContrastColor = () => ContrastColor; OnMouseUp = _ => OnClick(); OnKeyPress = _ => OnClick(); IsDisabled = () => Disabled; IsHighlighted = () => Highlighted; tooltipContainer = Exts.Lazy(() => Ui.Root.Get(TooltipContainer)); } protected ButtonWidget(ButtonWidget other) : base(other) { this.modRules = other.modRules; Text = other.Text; Font = other.Font; TextColor = other.TextColor; TextColorDisabled = other.TextColorDisabled; Contrast = other.Contrast; ContrastColor = other.ContrastColor; Depressed = other.Depressed; Background = other.Background; VisualHeight = other.VisualHeight; GetText = other.GetText; GetColor = other.GetColor; GetColorDisabled = other.GetColorDisabled; GetContrastColor = other.GetContrastColor; OnMouseDown = other.OnMouseDown; Disabled = other.Disabled; IsDisabled = other.IsDisabled; Highlighted = other.Highlighted; IsHighlighted = other.IsHighlighted; OnMouseUp = mi => OnClick(); OnKeyPress = _ => OnClick(); TooltipTemplate = other.TooltipTemplate; TooltipText = other.TooltipText; TooltipContainer = other.TooltipContainer; tooltipContainer = Exts.Lazy(() => Ui.Root.Get(TooltipContainer)); } public override bool YieldMouseFocus(MouseInput mi) { Depressed = false; return base.YieldMouseFocus(mi); } public override bool HandleKeyPress(KeyInput e) { if (Hotkey.FromKeyInput(e) != Key || e.Event != KeyInputEvent.Down) return false; if (!IsDisabled()) { OnKeyPress(e); Sound.PlayNotification(modRules, null, "Sounds", "ClickSound", null); } else Sound.PlayNotification(modRules, null, "Sounds", "ClickDisabledSound", null); return true; } public override bool HandleMouseInput(MouseInput mi) { if (mi.Button != MouseButton.Left) return false; if (mi.Event == MouseInputEvent.Down && !TakeMouseFocus(mi)) return false; var disabled = IsDisabled(); if (HasMouseFocus && mi.Event == MouseInputEvent.Up && mi.MultiTapCount == 2) { if (!disabled) { OnDoubleClick(); return YieldMouseFocus(mi); } } // Only fire the onMouseUp event if we successfully lost focus, and were pressed else if (HasMouseFocus && mi.Event == MouseInputEvent.Up) { if (Depressed && !disabled) OnMouseUp(mi); return YieldMouseFocus(mi); } if (mi.Event == MouseInputEvent.Down) { // OnMouseDown returns false if the button shouldn't be pressed if (!disabled) { OnMouseDown(mi); Depressed = true; Sound.PlayNotification(modRules, null, "Sounds", "ClickSound", null); } else { YieldMouseFocus(mi); Sound.PlayNotification(modRules, null, "Sounds", "ClickDisabledSound", null); } } else if (mi.Event == MouseInputEvent.Move && HasMouseFocus) Depressed = RenderBounds.Contains(mi.Location); return Depressed; } public override void MouseEntered() { if (TooltipContainer == null) return; tooltipContainer.Value.SetTooltip(TooltipTemplate, new WidgetArgs() {{ "button", this }}); } public override void MouseExited() { if (TooltipContainer == null) return; tooltipContainer.Value.RemoveTooltip(); } public override int2 ChildOrigin { get { return RenderOrigin + ((Depressed) ? new int2(VisualHeight, VisualHeight) : new int2(0, 0)); } } public override void Draw() { var rb = RenderBounds; var disabled = IsDisabled(); var highlighted = IsHighlighted(); var font = Game.Renderer.Fonts[Font]; var text = GetText(); var color = GetColor(); var colordisabled = GetColorDisabled(); var contrast = GetContrastColor(); var s = font.Measure(text); var stateOffset = (Depressed) ? new int2(VisualHeight, VisualHeight) : new int2(0, 0); var position = new int2(rb.X + (UsableWidth - s.X) / 2, rb.Y + (Bounds.Height - s.Y) / 2); DrawBackground(rb, disabled, Depressed, Ui.MouseOverWidget == this, highlighted); if (Contrast) font.DrawTextWithContrast(text, position + stateOffset, disabled ? colordisabled : color, contrast, 2); else font.DrawText(text, position + stateOffset, disabled ? colordisabled : color); } public override Widget Clone() { return new ButtonWidget(this); } public virtual int UsableWidth { get { return Bounds.Width; } } public virtual void DrawBackground(Rectangle rect, bool disabled, bool pressed, bool hover, bool highlighted) { DrawBackground(Background, rect, disabled, pressed, hover, highlighted); } public static void DrawBackground(string baseName, Rectangle rect, bool disabled, bool pressed, bool hover, bool highlighted) { var variant = highlighted ? "-highlighted" : ""; var state = disabled ? "-disabled" : pressed ? "-pressed" : hover ? "-hover" : ""; WidgetUtils.DrawPanel(baseName + variant + state, rect); } } }