diff --git a/samples/Myra.Samples.AllWidgets/AllWidgetsGame.cs b/samples/Myra.Samples.AllWidgets/AllWidgetsGame.cs index e715170e..11b96a31 100644 --- a/samples/Myra.Samples.AllWidgets/AllWidgetsGame.cs +++ b/samples/Myra.Samples.AllWidgets/AllWidgetsGame.cs @@ -110,7 +110,7 @@ protected override void LoadContent() #endif #if ANDROID - Desktop.WidgetGotKeyboardFocus += (s, a) => + _desktop.WidgetGotKeyboardFocus += (s, a) => { var asTextBox = a.Data as TextBox; if (asTextBox == null) diff --git a/samples/Myra.Samples.NonModalWindows/UI/MainPanel.cs b/samples/Myra.Samples.NonModalWindows/UI/MainPanel.cs index 4627365d..f752a0ba 100644 --- a/samples/Myra.Samples.NonModalWindows/UI/MainPanel.cs +++ b/samples/Myra.Samples.NonModalWindows/UI/MainPanel.cs @@ -13,9 +13,9 @@ public MainPanel() { BuildUI(); - _button1.PressedChanged += _button1_PressedChanged; - _button2.PressedChanged += _button2_PressedChanged; - _button3.PressedChanged += _button3_PressedChanged; + _button1.ToggledChanged += _button1_ToggledChanged; + _button2.ToggledChanged += _button2_ToggledChanged; + _button3.ToggledChanged += _button3_ToggledChanged; _window1.Closed += (s, a) => { @@ -40,9 +40,9 @@ public void ShowWindows() _button3.IsPressed = true; } - private void _button1_PressedChanged(object sender, System.EventArgs e) + private void _button1_ToggledChanged(object sender, System.EventArgs e) { - if (_button1.IsPressed) + if (_button1.IsToggled) { _window1.Show(Desktop, new Point(100, 100)); } @@ -52,9 +52,9 @@ private void _button1_PressedChanged(object sender, System.EventArgs e) } } - private void _button2_PressedChanged(object sender, System.EventArgs e) + private void _button2_ToggledChanged(object sender, System.EventArgs e) { - if (_button2.IsPressed) + if (_button2.IsToggled) { _window2.Show(Desktop, new Point(400, 100)); } @@ -64,9 +64,9 @@ private void _button2_PressedChanged(object sender, System.EventArgs e) } } - private void _button3_PressedChanged(object sender, System.EventArgs e) + private void _button3_ToggledChanged(object sender, System.EventArgs e) { - if (_button3.IsPressed) + if (_button3.IsToggled) { _window3.Show(Desktop, new Point(200, 400)); } diff --git a/src/Myra/Graphics2D/UI/ButtonBase.cs b/src/Myra/Graphics2D/UI/ButtonBase.cs index 44471dff..27871f2f 100644 --- a/src/Myra/Graphics2D/UI/ButtonBase.cs +++ b/src/Myra/Graphics2D/UI/ButtonBase.cs @@ -14,7 +14,7 @@ namespace Myra.Graphics2D.UI { public class ButtonBase : SingleItemContainer where T : Widget { - private bool _isPressed = false; + private bool _isToggled = false; [Category("Appearance")] [DefaultValue(HorizontalAlignment.Center)] @@ -41,26 +41,32 @@ public virtual VerticalAlignment ContentVerticalAlignment [Browsable(false)] [XmlIgnore] - public bool IsPressed + public bool IsToggled { get { - return _isPressed; + return _isToggled; } set { - if (value == _isPressed) + if (value == _isToggled) { return; } - _isPressed = value; + _isToggled = value; - OnPressedChanged(); + OnToggledChanged(); } } + /// + /// Indicates whether the current touch gesture started in this widget. + /// Similar to but stays also if the gesture leaves the widget's bounds. + /// + public bool IsPressed { get; set; } + internal bool ReleaseOnTouchLeft; public override Desktop Desktop @@ -92,14 +98,13 @@ protected internal override void OnActiveChanged() { base.OnActiveChanged(); - if (!Active && IsPressed && !Toggleable) + if (!Active && IsToggled && !Toggleable) { - IsPressed = false; + IsToggled = false; } } - public event EventHandler Click; - public event EventHandler PressedChanged; + public event EventHandler ToggledChanged; public ButtonBase() { @@ -113,68 +118,46 @@ public void DoClick() OnTouchUp(); } - public virtual void OnPressedChanged() + public virtual void OnToggledChanged() { - PressedChanged.Invoke(this); + ToggledChanged.Invoke(this); } - public override void OnTouchLeft() + public override void OnTouchLeft(HookableEventArgs args) { - base.OnTouchLeft(); + base.OnTouchLeft(args); if (ReleaseOnTouchLeft && !Toggleable) { - IsPressed = false; + IsToggled = false; } } - public override void OnTouchUp() + public override void OnClick() { - base.OnTouchUp(); - - if (!Enabled) - { - return; - } + base.OnClick(); - var invokeClick = false; - if (!Toggleable) - { - invokeClick = IsPressed; - IsPressed = false; - } - - if (invokeClick) - { - Click.Invoke(this); - } + if (Toggleable && CanChangeToggleable(!IsToggled)) + { + IsToggled = !IsToggled; + } } - public override void OnTouchDown() - { - base.OnTouchDown(); + public override void OnTouchDown() + { + base.OnTouchDown(); - if (!Enabled) - { - return; - } + IsPressed = true; + } - if (!Toggleable) - { - IsPressed = true; - } - else - { - var value = !IsPressed; - if (CanChangeToggleable(value)) - { - IsPressed = value; - Click.Invoke(this); - } - } - } + public override void OnTouchUp() + { + base.OnTouchUp(); + + IsPressed = false; + } - protected virtual bool CanChangeToggleable(bool value) + protected virtual bool CanChangeToggleable(bool value) { return true; } @@ -192,7 +175,7 @@ public override void OnKeyDown(Keys k) } else { - IsPressed = !IsPressed; + IsToggled = !IsToggled; } } } @@ -203,7 +186,7 @@ public override IBrush GetCurrentBackground() if (Enabled) { - if (IsPressed && PressedBackground != null) + if (IsToggled && PressedBackground != null) { result = PressedBackground; } @@ -232,7 +215,7 @@ public void ApplyButtonStyle(ButtonStyle style) private void DesktopTouchUp(object sender, EventArgs args) { - IsPressed = false; + IsToggled = false; } protected override void InternalSetStyle(Stylesheet stylesheet, string name) diff --git a/src/Myra/Graphics2D/UI/ComboBox.cs b/src/Myra/Graphics2D/UI/ComboBox.cs index ffb59885..7e3ace85 100644 --- a/src/Myra/Graphics2D/UI/ComboBox.cs +++ b/src/Myra/Graphics2D/UI/ComboBox.cs @@ -39,7 +39,7 @@ public int? DropdownMaximumHeight [XmlIgnore] public bool IsExpanded { - get { return InternalChild.IsPressed; } + get { return InternalChild.IsToggled; } } public override Desktop Desktop @@ -94,7 +94,7 @@ public ComboBox(string styleName = Stylesheet.DefaultStyleName) HorizontalAlignment = HorizontalAlignment.Stretch }; - InternalChild.PressedChanged += InternalChild_PressedChanged; + InternalChild.ToggledChanged += InternalChild_ToggledChanged; _listBox._parentComboBox = this; _listBox.Items.CollectionChanged += Items_CollectionChanged; @@ -117,17 +117,17 @@ internal void HideDropdown() private void DesktopOnContextMenuClosed(object sender, GenericEventArgs genericEventArgs) { - InternalChild.IsPressed = false; + InternalChild.IsToggled = false; } - private void InternalChild_PressedChanged(object sender, EventArgs e) + private void InternalChild_ToggledChanged(object sender, EventArgs e) { if (_listBox.Items.Count == 0) { return; } - if (InternalChild.IsPressed) + if (InternalChild.IsToggled) { if (_listBox.SelectedIndex == null && Items.Count > 0) { @@ -187,7 +187,7 @@ internal void UpdateSelectedItem() { InternalChild.Text = item.Text; InternalChild.TextColor = item.Color ?? _listBox.ListBoxStyle.ListItemStyle.LabelStyle.TextColor; - ((ImageTextButton)item.Widget).IsPressed = true; + ((ImageTextButton)item.Widget).IsToggled = true; } else { diff --git a/src/Myra/Graphics2D/UI/Container.cs b/src/Myra/Graphics2D/UI/Container.cs index d1675917..c4b108b6 100644 --- a/src/Myra/Graphics2D/UI/Container.cs +++ b/src/Myra/Graphics2D/UI/Container.cs @@ -138,25 +138,25 @@ public override void OnMouseMoved() ChildrenCopy.ProcessMouseMovement(); } - public override void OnTouchEntered() + public override void OnTouchEntered(HookableEventArgs args) { - base.OnTouchEntered(); + base.OnTouchEntered(args); - ChildrenCopy.ProcessTouchMovement(); + ChildrenCopy.ProcessTouchMovement(args); } - public override void OnTouchLeft() + public override void OnTouchLeft(HookableEventArgs args) { - base.OnTouchLeft(); + base.OnTouchLeft(args); - ChildrenCopy.ProcessTouchMovement(); + ChildrenCopy.ProcessTouchMovement(args); } - public override void OnTouchMoved() + public override void OnTouchMoved(HookableEventArgs args) { - base.OnTouchMoved(); + base.OnTouchMoved(args); - ChildrenCopy.ProcessTouchMovement(); + ChildrenCopy.ProcessTouchMovement(args); } public override void OnTouchDown() diff --git a/src/Myra/Graphics2D/UI/DebugOptionsWindow.cs b/src/Myra/Graphics2D/UI/DebugOptionsWindow.cs index 55f1104d..292f3442 100644 --- a/src/Myra/Graphics2D/UI/DebugOptionsWindow.cs +++ b/src/Myra/Graphics2D/UI/DebugOptionsWindow.cs @@ -13,34 +13,34 @@ public DebugOptionsWindow() BuildUI(); - _checkBoxWidgetFrames.IsPressed = MyraEnvironment.DrawWidgetsFrames; - _checkBoxWidgetFrames.PressedChanged += (s, a) => + _checkBoxWidgetFrames.IsToggled = MyraEnvironment.DrawWidgetsFrames; + _checkBoxWidgetFrames.ToggledChanged += (s, a) => { - MyraEnvironment.DrawWidgetsFrames = _checkBoxWidgetFrames.IsPressed; + MyraEnvironment.DrawWidgetsFrames = _checkBoxWidgetFrames.IsToggled; }; - _checkBoxKeyboardFocusedWidgetFrame.IsPressed = MyraEnvironment.DrawKeyboardFocusedWidgetFrame; - _checkBoxKeyboardFocusedWidgetFrame.PressedChanged += (s, a) => + _checkBoxKeyboardFocusedWidgetFrame.IsToggled = MyraEnvironment.DrawKeyboardFocusedWidgetFrame; + _checkBoxKeyboardFocusedWidgetFrame.ToggledChanged += (s, a) => { - MyraEnvironment.DrawKeyboardFocusedWidgetFrame = _checkBoxKeyboardFocusedWidgetFrame.IsPressed; + MyraEnvironment.DrawKeyboardFocusedWidgetFrame = _checkBoxKeyboardFocusedWidgetFrame.IsToggled; }; - _checkBoxMouseWheelFocusedWidgetFrame.IsPressed = MyraEnvironment.DrawMouseWheelFocusedWidgetFrame; - _checkBoxMouseWheelFocusedWidgetFrame.PressedChanged += (s, a) => + _checkBoxMouseWheelFocusedWidgetFrame.IsToggled = MyraEnvironment.DrawMouseWheelFocusedWidgetFrame; + _checkBoxMouseWheelFocusedWidgetFrame.ToggledChanged += (s, a) => { - MyraEnvironment.DrawMouseWheelFocusedWidgetFrame = _checkBoxMouseWheelFocusedWidgetFrame.IsPressed; + MyraEnvironment.DrawMouseWheelFocusedWidgetFrame = _checkBoxMouseWheelFocusedWidgetFrame.IsToggled; }; - _checkBoxGlyphFrames.IsPressed = MyraEnvironment.DrawTextGlyphsFrames; - _checkBoxGlyphFrames.PressedChanged += (s, a) => + _checkBoxGlyphFrames.IsToggled = MyraEnvironment.DrawTextGlyphsFrames; + _checkBoxGlyphFrames.ToggledChanged += (s, a) => { - MyraEnvironment.DrawTextGlyphsFrames = _checkBoxGlyphFrames.IsPressed; + MyraEnvironment.DrawTextGlyphsFrames = _checkBoxGlyphFrames.IsToggled; }; - _checkBoxDisableClipping.IsPressed = MyraEnvironment.DisableClipping; - _checkBoxDisableClipping.PressedChanged += (s, a) => + _checkBoxDisableClipping.IsToggled = MyraEnvironment.DisableClipping; + _checkBoxDisableClipping.ToggledChanged += (s, a) => { - MyraEnvironment.DisableClipping = _checkBoxDisableClipping.IsPressed; + MyraEnvironment.DisableClipping = _checkBoxDisableClipping.IsToggled; }; } @@ -58,9 +58,9 @@ public void AddOption(string text, Action onEnabled, Action onDisabled) Visible = true }; - optionsCheckBox.PressedChanged += (s, a) => + optionsCheckBox.ToggledChanged += (s, a) => { - if (optionsCheckBox.IsPressed) + if (optionsCheckBox.IsToggled) { onEnabled(); } diff --git a/src/Myra/Graphics2D/UI/Desktop.cs b/src/Myra/Graphics2D/UI/Desktop.cs index 5fb33bbd..52d330fd 100644 --- a/src/Myra/Graphics2D/UI/Desktop.cs +++ b/src/Myra/Graphics2D/UI/Desktop.cs @@ -150,9 +150,10 @@ private set } _touchPosition = value; - TouchMoved.Invoke(); - - ChildrenCopy.ProcessTouchMovement(); + HookableEventArgs args = new HookableEventArgs(); + TouchMoved?.Invoke(this, args); + ChildrenCopy.ProcessTouchMovement(args); + args.InvokeHookIfNotHandled(); } } @@ -387,7 +388,7 @@ private bool IsMenuBarActive public event EventHandler MouseMoved; - public event EventHandler TouchMoved; + public event EventHandler TouchMoved; public event EventHandler TouchDown; public event EventHandler TouchUp; public event EventHandler TouchDoubleClick; @@ -1121,7 +1122,7 @@ public void UpdateInput() { UpdateTouch(); } - catch (Exception) + catch (Exception e) { } #endif diff --git a/src/Myra/Graphics2D/UI/Enums.cs b/src/Myra/Graphics2D/UI/Enums.cs index 25e08d0c..a82479d8 100644 --- a/src/Myra/Graphics2D/UI/Enums.cs +++ b/src/Myra/Graphics2D/UI/Enums.cs @@ -71,4 +71,14 @@ public enum ImageResizeMode /// KeepAspectRatio } + + /// + /// Defines in which way the user is scrolling. + /// + public enum ScrollingType + { + Scrollbar, + MouseWheel, + Touch + } } \ No newline at end of file diff --git a/src/Myra/Graphics2D/UI/ImageButton.cs b/src/Myra/Graphics2D/UI/ImageButton.cs index aa7256ec..e7423a57 100644 --- a/src/Myra/Graphics2D/UI/ImageButton.cs +++ b/src/Myra/Graphics2D/UI/ImageButton.cs @@ -76,11 +76,11 @@ public void ApplyImageButtonStyle(ImageButtonStyle style) } } - public override void OnPressedChanged() + public override void OnToggledChanged() { - base.OnPressedChanged(); + base.OnToggledChanged(); - InternalChild.IsPressed = IsPressed; + InternalChild.IsPressed = IsToggled; } } } \ No newline at end of file diff --git a/src/Myra/Graphics2D/UI/ImageTextButton.cs b/src/Myra/Graphics2D/UI/ImageTextButton.cs index 8c535618..0fc7cec9 100644 --- a/src/Myra/Graphics2D/UI/ImageTextButton.cs +++ b/src/Myra/Graphics2D/UI/ImageTextButton.cs @@ -229,12 +229,12 @@ public void ApplyImageTextButtonStyle(ImageTextButtonStyle style) ImageTextSpacing = style.ImageTextSpacing; } - public override void OnPressedChanged() + public override void OnToggledChanged() { - base.OnPressedChanged(); + base.OnToggledChanged(); - _image.IsPressed = IsPressed; - _textBlock.IsPressed = IsPressed; + _image.IsPressed = IsToggled; + _textBlock.IsPressed = IsToggled; } protected override void InternalSetStyle(Stylesheet stylesheet, string name) diff --git a/src/Myra/Graphics2D/UI/ListBox.cs b/src/Myra/Graphics2D/UI/ListBox.cs index 4e66eabd..b94b5c65 100644 --- a/src/Myra/Graphics2D/UI/ListBox.cs +++ b/src/Myra/Graphics2D/UI/ListBox.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.ComponentModel; using System.Xml.Serialization; using Myra.Graphics2D.UI.Styles; @@ -86,7 +86,7 @@ protected override void InsertItem(ListItem item, int index) ImageTextSpacing = item.ImageTextSpacing }; - ((ImageTextButton)widget).PressedChanged += ButtonOnPressed; + ((ImageTextButton)widget).ToggledChanged += ButtonOnToggleChanged; } else { @@ -121,10 +121,10 @@ protected override void Reset() } } - private void ButtonOnPressed(object sender, EventArgs eventArgs) + private void ButtonOnToggleChanged(object sender, EventArgs eventArgs) { var item = (ImageTextButton)sender; - if (!item.IsPressed) + if (!item.IsToggled) { return; } @@ -194,17 +194,17 @@ public override void OnKeyDown(Keys k) } } - public override void OnTouchDown() - { - base.OnTouchDown(); + public override void OnClick() + { + base.OnClick(); - if (!InternalChild._verticalScrollingOn || !InternalChild._verticalScrollbarFrame.Contains(Desktop.TouchPosition)) - { - ComboHideDropdown(); - } - } + if (!InternalChild._verticalScrollingOn || !InternalChild._verticalScrollbarFrame.Contains(Desktop.TouchPosition)) + { + ComboHideDropdown(); + } + } - private void UpdateScrolling() + private void UpdateScrolling() { if (SelectedItem == null) { diff --git a/src/Myra/Graphics2D/UI/ListButton.cs b/src/Myra/Graphics2D/UI/ListButton.cs index 29070290..dc0cd45d 100644 --- a/src/Myra/Graphics2D/UI/ListButton.cs +++ b/src/Myra/Graphics2D/UI/ListButton.cs @@ -18,7 +18,7 @@ protected override bool CanChangeToggleable(bool value) { // At least one list button should be pressed return _selector.SelectionMode == SelectionMode.Multiple || - !IsPressed; + !IsToggled; } } } diff --git a/src/Myra/Graphics2D/UI/ListItem.cs b/src/Myra/Graphics2D/UI/ListItem.cs index 5f326dc7..a394b57f 100644 --- a/src/Myra/Graphics2D/UI/ListItem.cs +++ b/src/Myra/Graphics2D/UI/ListItem.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.ComponentModel; using System.Xml.Serialization; @@ -40,7 +40,7 @@ public Widget Widget var asButton = _widget as ImageTextButton; if (asButton != null) { - asButton.PressedChanged += (s, a) => FireSelectedChanged(); + asButton.ToggledChanged += (s, a) => FireSelectedChanged(); } } } @@ -57,7 +57,7 @@ public bool IsSelected return false; } - return asButton.IsPressed; + return asButton.IsToggled; } set @@ -68,7 +68,7 @@ public bool IsSelected return; } - asButton.IsPressed = value; + asButton.IsToggled = value; } } @@ -95,11 +95,7 @@ public ListItem(string text) : this(text, null) public void FireSelectedChanged() { - var ev = SelectedChanged; - if (ev != null) - { - ev(this, EventArgs.Empty); - } - } + SelectedChanged?.Invoke(this, EventArgs.Empty); + } } } diff --git a/src/Myra/Graphics2D/UI/Menu.cs b/src/Myra/Graphics2D/UI/Menu.cs index 07d1d477..81ebdcac 100644 --- a/src/Myra/Graphics2D/UI/Menu.cs +++ b/src/Myra/Graphics2D/UI/Menu.cs @@ -349,7 +349,7 @@ protected Menu(string styleName) InternalChild.HoverIndexChanged += OnHoverIndexChanged; InternalChild.SelectedIndexChanged += OnSelectedIndexChanged; - InternalChild.TouchUp += InternalChild_TouchUp; + InternalChild.Click += InternalChild_Click; OpenMenuItem = null; @@ -646,7 +646,7 @@ private void OnSelectedIndexChanged(object sender, EventArgs e) } } - private void InternalChild_TouchUp(object sender, EventArgs e) + private void InternalChild_Click(object sender, EventArgs e) { var menuItem = SelectedMenuItem; if (menuItem != null && !menuItem.CanOpen) @@ -666,7 +666,7 @@ private MenuItem GetMenuItem(int? index) return Items[index.Value] as MenuItem; } - private void Click(int? index) + private void SelectMenuItem(int? index) { var menuItem = GetMenuItem(index); if (menuItem == null) @@ -694,7 +694,7 @@ public override void OnKeyDown(Keys k) var menuItem = Items[selectedIndex.Value] as MenuItem; if (menuItem != null && !menuItem.CanOpen) { - Click(menuItem.Index); + SelectMenuItem(menuItem.Index); return; } } @@ -714,7 +714,7 @@ public override void OnKeyDown(Keys k) if (menuItem.UnderscoreChar == c) { - Click(menuItem.Index); + SelectMenuItem(menuItem.Index); return; } } diff --git a/src/Myra/Graphics2D/UI/MenuItem.cs b/src/Myra/Graphics2D/UI/MenuItem.cs index 59f01c4b..5f6b5544 100644 --- a/src/Myra/Graphics2D/UI/MenuItem.cs +++ b/src/Myra/Graphics2D/UI/MenuItem.cs @@ -336,13 +336,8 @@ internal MenuItem FindMenuItemById(string id) public void FireSelected() { - var ev = Selected; - - if (ev != null) - { - ev(this, EventArgs.Empty); - } - } + Selected?.Invoke(this, EventArgs.Empty); + } protected internal override void OnIdChanged() { @@ -353,11 +348,7 @@ protected internal override void OnIdChanged() protected void FireChanged() { - var ev = Changed; - if (ev != null) - { - ev(this, EventArgs.Empty); - } - } + Changed?.Invoke(this, EventArgs.Empty); + } } } \ No newline at end of file diff --git a/src/Myra/Graphics2D/UI/Properties/PropertyGrid.cs b/src/Myra/Graphics2D/UI/Properties/PropertyGrid.cs index 4a539d72..4b5e4195 100644 --- a/src/Myra/Graphics2D/UI/Properties/PropertyGrid.cs +++ b/src/Myra/Graphics2D/UI/Properties/PropertyGrid.cs @@ -95,9 +95,9 @@ public SubGrid(PropertyGrid parent, object value, string header, string category InternalChild.Widgets.Add(_mark); - _mark.PressedChanged += (sender, args) => + _mark.ToggledChanged += (sender, args) => { - if (_mark.IsPressed) + if (_mark.IsToggled) { _propertyGrid.Visible = true; parent._expandedCategories.Add(category); @@ -117,7 +117,7 @@ public SubGrid(PropertyGrid parent, object value, string header, string category if (expanded) { - _mark.IsPressed = true; + _mark.IsToggled = true; } var label = new Label(null) @@ -144,7 +144,7 @@ public override void OnTouchDoubleClick() return; } - _mark.IsPressed = !_mark.IsPressed; + _mark.IsToggled = !_mark.IsToggled; } public override void InternalRender(RenderContext context) @@ -359,14 +359,14 @@ private CheckBox CreateBooleanEditor(Record record, bool hasSetter) var isChecked = (bool)value; var cb = new CheckBox { - IsPressed = isChecked + IsToggled = isChecked }; if (hasSetter) { cb.Click += (sender, args) => { - SetValue(record, _object, cb.IsPressed); + SetValue(record, _object, cb.IsToggled); FireChanged(propertyType.Name); }; } @@ -1164,7 +1164,7 @@ private void Rebuild() if (_expandedCategories.Contains(category.Key)) { - subGrid.Mark.IsPressed = true; + subGrid.Mark.IsToggled = true; } var rp = new Proportion(ProportionType.Auto); diff --git a/src/Myra/Graphics2D/UI/RadioButton.cs b/src/Myra/Graphics2D/UI/RadioButton.cs index b5edd1b6..ff3fb588 100644 --- a/src/Myra/Graphics2D/UI/RadioButton.cs +++ b/src/Myra/Graphics2D/UI/RadioButton.cs @@ -28,11 +28,11 @@ public RadioButton(string styleName = Stylesheet.DefaultStyleName): base(styleNa Toggleable = true; } - public override void OnPressedChanged() + public override void OnToggledChanged() { - base.OnPressedChanged(); + base.OnToggledChanged(); - if (IsPressed) + if (IsToggled) { foreach (var child in Parent.ChildrenCopy) { @@ -43,14 +43,14 @@ public override void OnPressedChanged() continue; } - asRadio.IsPressed = false; + asRadio.IsToggled = false; } } } protected override bool CanChangeToggleable(bool value) { - return !IsPressed; + return !IsToggled; } protected override void InternalSetStyle(Stylesheet stylesheet, string name) diff --git a/src/Myra/Graphics2D/UI/ScrollViewer.cs b/src/Myra/Graphics2D/UI/ScrollViewer.cs index 643dad8e..9534a6df 100644 --- a/src/Myra/Graphics2D/UI/ScrollViewer.cs +++ b/src/Myra/Graphics2D/UI/ScrollViewer.cs @@ -15,12 +15,13 @@ namespace Myra.Graphics2D.UI { public class ScrollViewer : SingleItemContainer, IContent { - private Orientation _scrollbarOrientation; + private DragDirection _dragDirection; + private ScrollingType _scrollingType; internal bool _horizontalScrollingOn, _verticalScrollingOn; private bool _showHorizontalScrollBar, _showVerticalScrollBar; internal Rectangle _horizontalScrollbarFrame, _horizontalScrollbarThumb; internal Rectangle _verticalScrollbarFrame, _verticalScrollbarThumb; - private int? _startBoundsPos; + private Point? _startBoundsPos; private int _thumbMaximumX, _thumbMaximumY; [Browsable(false)] @@ -320,14 +321,14 @@ public ScrollViewer(string styleName = Stylesheet.DefaultStyleName) SetStyle(styleName); } - private void MoveThumb(int delta) + private void MoveThumb(Point delta) { var scrollPosition = ScrollPosition; var maximum = ScrollMaximum; - if (_scrollbarOrientation == Orientation.Horizontal) + if (_dragDirection == DragDirection.Horizontal) { - var newPos = delta + scrollPosition.X; + var newPos = delta.X + scrollPosition.X; if (newPos < 0) { newPos = 0; @@ -340,9 +341,9 @@ private void MoveThumb(int delta) scrollPosition.X = newPos; } - else + if (_dragDirection == DragDirection.Vertical) { - var newPos = delta + scrollPosition.Y; + var newPos = delta.Y + scrollPosition.Y; if (newPos < 0) { @@ -390,23 +391,50 @@ public override void OnTouchDown() var touchPosition = Desktop.TouchPosition; - var r = _verticalScrollbarThumb; - var thumbPosition = ThumbPosition; - r.Y += thumbPosition.Y; - if (ShowVerticalScrollBar && _verticalScrollingOn && r.Contains(touchPosition)) - { - _startBoundsPos = touchPosition.Y; - _scrollbarOrientation = Orientation.Vertical; - } - r = _horizontalScrollbarThumb; - r.X += thumbPosition.X; - if (ShowHorizontalScrollBar && _horizontalScrollingOn && r.Contains(touchPosition)) - { - _startBoundsPos = touchPosition.X; - _scrollbarOrientation = Orientation.Horizontal; - } - } + Rectangle verticalScrollBarRect = _verticalScrollbarThumb; + var thumbPosition = ThumbPosition; + verticalScrollBarRect.Y += thumbPosition.Y; + if (ShowVerticalScrollBar && _verticalScrollingOn && verticalScrollBarRect.Contains(touchPosition)) + { + _startBoundsPos = touchPosition; + _dragDirection = DragDirection.Vertical; + _scrollingType = ScrollingType.Scrollbar; + return; + } + + Rectangle horizontalScrollBarRect = _horizontalScrollbarThumb; + horizontalScrollBarRect.X += thumbPosition.X; + if (ShowHorizontalScrollBar && _horizontalScrollingOn && horizontalScrollBarRect.Contains(touchPosition)) + { + _startBoundsPos = touchPosition; + _dragDirection = DragDirection.Horizontal; + _scrollingType = ScrollingType.Scrollbar; + return; + } + + Rectangle viewerRect = ActualBounds; + viewerRect.X += thumbPosition.X; + if ((_verticalScrollingOn || _horizontalScrollingOn) && viewerRect.Contains(touchPosition)) + { + _startBoundsPos = touchPosition; + if (_verticalScrollingOn && _horizontalScrollingOn) + { + _dragDirection = DragDirection.Both; + } + else if (_verticalScrollingOn) + { + _dragDirection = DragDirection.Vertical; + } + else if (_horizontalScrollingOn) + { + _dragDirection = DragDirection.Horizontal; + } + _scrollingType = ScrollingType.Touch; + + return; + } + } public override void OnMouseWheel(float delta) { @@ -420,13 +448,17 @@ public override void OnMouseWheel(float delta) var step = 10 * ScrollMaximum.Y / _thumbMaximumY; if (delta < 0) { - _scrollbarOrientation = Orientation.Vertical; - MoveThumb(step); + _dragDirection = DragDirection.Vertical; + _scrollingType = ScrollingType.MouseWheel; + + MoveThumb(new Point(0, step)); } else if (delta > 0) { - _scrollbarOrientation = Orientation.Vertical; - MoveThumb(-step); + _dragDirection = DragDirection.Vertical; + _scrollingType = ScrollingType.MouseWheel; + + MoveThumb(new Point(0, -step)); } } @@ -634,28 +666,34 @@ public void ResetScroll() ScrollPosition = Point.Zero; } - private void DesktopTouchMoved(object sender, EventArgs args) + private void DesktopTouchMoved(object sender, HookableEventArgs args) { if (!_startBoundsPos.HasValue) return; var touchPosition = Desktop.TouchPosition; - int delta; - if (_scrollbarOrientation == Orientation.Horizontal) + Point delta = new Point(); + if (_dragDirection == DragDirection.Horizontal) { - delta = (touchPosition.X - _startBoundsPos.Value) * ScrollMaximum.X / _thumbMaximumX; - _startBoundsPos = touchPosition.X; + delta.X = (touchPosition.X - _startBoundsPos.Value.X) * ScrollMaximum.X / _thumbMaximumX; + _startBoundsPos = new Point(touchPosition.X, _startBoundsPos.Value.Y); } - else + if (_dragDirection == DragDirection.Vertical) { - delta = (touchPosition.Y - _startBoundsPos.Value) * ScrollMaximum.Y / _thumbMaximumY; - _startBoundsPos = touchPosition.Y; + delta.Y = (touchPosition.Y - _startBoundsPos.Value.Y) * ScrollMaximum.Y / _thumbMaximumY; + _startBoundsPos = new Point(_startBoundsPos.Value.X, touchPosition.Y); } - - MoveThumb(delta); - } + if (_scrollingType == ScrollingType.Touch) + { + args.AddHook(()=>MoveThumb(Point.Zero-delta)); + } + else + { + args.AddHook(()=>MoveThumb(delta)); + } + } private void DesktopTouchUp(object sender, EventArgs args) { diff --git a/src/Myra/Graphics2D/UI/Slider.cs b/src/Myra/Graphics2D/UI/Slider.cs index 86265460..f1833d2c 100644 --- a/src/Myra/Graphics2D/UI/Slider.cs +++ b/src/Myra/Graphics2D/UI/Slider.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.ComponentModel; using Myra.Graphics2D.UI.Styles; using Myra.Utility; @@ -120,14 +120,16 @@ internal set if (Desktop != null) { Desktop.TouchMoved -= DesktopTouchMoved; - } + Desktop.TouchUp -= DesktopTouchUp; + } base.Desktop = value; if (Desktop != null) { Desktop.TouchMoved += DesktopTouchMoved; - } + Desktop.TouchUp += DesktopTouchUp; + } } } @@ -196,7 +198,7 @@ public override void OnTouchDown() InternalChild.IsPressed = true; } - private void UpdateHint() + private void UpdateHint() { var hint = GetHint(); if (hint < 0) @@ -236,14 +238,19 @@ private void UpdateHint() } } - private void DesktopTouchMoved(object sender, EventArgs args) + private void DesktopTouchMoved(object sender, HookableEventArgs args) { if (!InternalChild.IsPressed) { return; } - + args.SetHandledFlag(); UpdateHint(); } - } + + private void DesktopTouchUp(object sender, EventArgs args) + { + InternalChild.IsPressed = false; + } + } } \ No newline at end of file diff --git a/src/Myra/Graphics2D/UI/SplitPane.cs b/src/Myra/Graphics2D/UI/SplitPane.cs index e3dc7cff..f3f0247f 100644 --- a/src/Myra/Graphics2D/UI/SplitPane.cs +++ b/src/Myra/Graphics2D/UI/SplitPane.cs @@ -6,6 +6,7 @@ using Myra.Graphics2D.UI.Styles; using System.Xml.Serialization; using Myra.Attributes; +using Myra.Utility; #if !STRIDE using Microsoft.Xna.Framework; @@ -80,9 +81,9 @@ public float GetProportion(int widgetIndex) return result; } - public override void OnTouchMoved() + public override void OnTouchMoved(HookableEventArgs args) { - base.OnTouchMoved(); + base.OnTouchMoved(args); if (_mouseCoord == null) { @@ -135,6 +136,7 @@ public override void OnTouchMoved() firstProportion.Value = fp; secondProportion.Value = fp2; FireProportionsChanged(); + args.SetHandledFlag(); } } @@ -147,23 +149,19 @@ private void FireProportionsChanged() } } - private void HandleOnPressedChanged(object sender, EventArgs args) - { - var handle = (ImageButton)sender; + private void HandleOnTouchDown(object sender, EventArgs args) + { + _handleDown = (ImageButton)sender; + _mouseCoord = Orientation == Orientation.Horizontal + ? Desktop.TouchPosition.X - _handleDown.Bounds.X + : Desktop.TouchPosition.Y - _handleDown.Bounds.Y; + } - if (!handle.IsPressed) - { - _handleDown = null; - _mouseCoord = null; - } - else - { - _handleDown = (ImageButton)sender; - _mouseCoord = Orientation == Orientation.Horizontal - ? Desktop.TouchPosition.X - _handleDown.Bounds.X - : Desktop.TouchPosition.Y - _handleDown.Bounds.Y; - } - } + private void HandleOnTouchUp(object sender, EventArgs args) + { + _handleDown = null; + _mouseCoord = null; + } private void WidgetsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) { @@ -248,7 +246,8 @@ public void Reset() handle.ApplyButtonStyle(HandleStyle); - handle.PressedChanged += HandleOnPressedChanged; + handle.TouchDown += HandleOnTouchDown; + handle.TouchUp += HandleOnTouchUp; proportion = new Proportion(ProportionType.Auto); diff --git a/src/Myra/Graphics2D/UI/TabItem.cs b/src/Myra/Graphics2D/UI/TabItem.cs index 9cfaa5d0..b456cc13 100644 --- a/src/Myra/Graphics2D/UI/TabItem.cs +++ b/src/Myra/Graphics2D/UI/TabItem.cs @@ -99,7 +99,7 @@ public bool IsSelected { get { - return Button.IsPressed; + return Button.IsToggled; } set @@ -109,7 +109,7 @@ public bool IsSelected return; } - Button.IsPressed = value; + Button.IsToggled = value; FireSelected(); } } diff --git a/src/Myra/Graphics2D/UI/TextBox.cs b/src/Myra/Graphics2D/UI/TextBox.cs index 89575fa4..2ed60a3f 100644 --- a/src/Myra/Graphics2D/UI/TextBox.cs +++ b/src/Myra/Graphics2D/UI/TextBox.cs @@ -1116,7 +1116,7 @@ public override void OnChar(char c) } } - private void SetCursorByTouch() + private void SetCursorByTouch(HookableEventArgs args = null) { var bounds = ActualBounds; var mousePos = Desktop.TouchPosition; @@ -1131,6 +1131,7 @@ private void SetCursorByTouch() if (glyphIndex != null) { UserSetCursorPosition(line.TextStartIndex + glyphIndex.Value); + args?.SetHandledFlag(); if (_isTouchDown || Desktop.IsShiftDown) { UpdateSelection(); @@ -1146,26 +1147,27 @@ public override void OnTouchDown() { base.OnTouchDown(); - if (!Enabled) - { - return; - } + if (Enabled && Length != 0) + { + _isTouchDown = true; + } + } - if (Length == 0) - { - return; - } + public override void OnTouchUp() + { + base.OnTouchUp(); - SetCursorByTouch(); - - _isTouchDown = true; - } + if (_isTouchDown) + { + SetCursorByTouch(); + } + } - public override void OnTouchMoved() + public override void OnTouchMoved(HookableEventArgs args) { - base.OnTouchMoved(); + base.OnTouchMoved(args); - SetCursorByTouch(); + SetCursorByTouch(args); } public override void OnTouchDoubleClick() @@ -1476,7 +1478,7 @@ public float GetWidth(int index) private void DesktopTouchUp(object sender, EventArgs args) { - _isTouchDown = false; + _isTouchDown = false; } } } \ No newline at end of file diff --git a/src/Myra/Graphics2D/UI/TextButton.cs b/src/Myra/Graphics2D/UI/TextButton.cs index ff7d1fd9..c78ce3e3 100644 --- a/src/Myra/Graphics2D/UI/TextButton.cs +++ b/src/Myra/Graphics2D/UI/TextButton.cs @@ -79,12 +79,17 @@ public void ApplyTextButtonStyle(ButtonStyle style) } } - public override void OnPressedChanged() - { - base.OnPressedChanged(); + public override void OnTouchDown() + { + base.OnTouchDown(); + InternalChild.IsPressed = true; + } - InternalChild.IsPressed = IsPressed; - } + public override void OnTouchUp() + { + base.OnTouchUp(); + InternalChild.IsPressed = false; + } protected override void InternalSetStyle(Stylesheet stylesheet, string name) { diff --git a/src/Myra/Graphics2D/UI/Tree.cs b/src/Myra/Graphics2D/UI/Tree.cs index cb8bf9f3..58637c71 100644 --- a/src/Myra/Graphics2D/UI/Tree.cs +++ b/src/Myra/Graphics2D/UI/Tree.cs @@ -92,13 +92,13 @@ private void UpdateHasRoot() { Mark.Visible = true; Label.Visible = true; - ChildNodesGrid.Visible = Mark.IsPressed; + ChildNodesGrid.Visible = Mark.IsToggled; } else { Mark.Visible = false; Label.Visible = false; - Mark.IsPressed = true; + Mark.IsToggled = true; ChildNodesGrid.Visible = true; } } @@ -179,9 +179,9 @@ public override void OnKeyDown(Keys k) } } - public override void OnTouchDown() + public override void OnClick() { - base.OnTouchDown(); + base.OnClick(); SetHoverRow(Desktop.TouchPosition); diff --git a/src/Myra/Graphics2D/UI/TreeNode.cs b/src/Myra/Graphics2D/UI/TreeNode.cs index 1379f36c..e35c420f 100644 --- a/src/Myra/Graphics2D/UI/TreeNode.cs +++ b/src/Myra/Graphics2D/UI/TreeNode.cs @@ -22,9 +22,9 @@ public class TreeNode : SingleItemContainer public bool IsExpanded { - get { return _mark.IsPressed; } + get { return _mark.IsToggled; } - set { _mark.IsPressed = value; } + set { _mark.IsToggled = value; } } public Label Label @@ -109,9 +109,9 @@ public TreeNode(Tree topTree, string styleName = Stylesheet.DefaultStyleName) VerticalAlignment = VerticalAlignment.Center }; - _mark.PressedChanged += (s, a) => + _mark.ToggledChanged += (s, a) => { - _childNodesGrid.Visible = _mark.IsPressed; + _childNodesGrid.Visible = _mark.IsToggled; }; InternalChild.Widgets.Add(_mark); diff --git a/src/Myra/Graphics2D/UI/Widget.cs b/src/Myra/Graphics2D/UI/Widget.cs index 4b04be7e..8a01498f 100644 --- a/src/Myra/Graphics2D/UI/Widget.cs +++ b/src/Myra/Graphics2D/UI/Widget.cs @@ -717,7 +717,16 @@ public IBrush FocusedBorder [XmlIgnore] public bool IsMouseInside { get; private set; } - [Browsable(false)] + /// + /// Indicates whether the touch gesture stayed inside this widget so far. + /// Is set to if the touch gesture starts inside this widget. + /// Is set to as soon as the touch gesture ends or the current position leaves the widget. + /// + [Browsable(false)] + [XmlIgnore] + public bool TouchStayedInside { get; private set; } + + [Browsable(false)] [XmlIgnore] public bool IsTouchInside { get; private set; } @@ -894,11 +903,12 @@ protected virtual bool UseHoverRenderable public event EventHandler MouseEntered; public event EventHandler MouseMoved; - public event EventHandler TouchLeft; - public event EventHandler TouchEntered; - public event EventHandler TouchMoved; + public event EventHandler TouchLeft; + public event EventHandler TouchEntered; + public event EventHandler TouchMoved; public event EventHandler TouchDown; public event EventHandler TouchUp; + public event EventHandler Click; public event EventHandler TouchDoubleClick; public event EventHandler KeyboardFocusChanged; @@ -1443,38 +1453,30 @@ public virtual void OnMouseWheel(float delta) MouseWheelChanged.Invoke(this, delta); } - public virtual void OnTouchLeft() + public virtual void OnTouchLeft(HookableEventArgs args) { + TouchStayedInside = false; IsTouchInside = false; - TouchLeft.Invoke(this); + TouchLeft?.Invoke(this, args); } - public virtual void OnTouchEntered() + public virtual void OnTouchEntered(HookableEventArgs args) { IsTouchInside = true; - TouchEntered.Invoke(this); + TouchEntered?.Invoke(this, args); } - public virtual void OnTouchMoved() + public virtual void OnTouchMoved(HookableEventArgs args) { IsTouchInside = true; - TouchMoved.Invoke(this); + TouchMoved?.Invoke(this, args); } public virtual void OnTouchDown() { + TouchStayedInside = true; IsTouchInside = true; - if (Enabled && AcceptsKeyboardFocus) - { - Desktop.FocusedKeyboardWidget = this; - } - - if (Enabled && AcceptsMouseWheelFocus) - { - Desktop.FocusedMouseWheelWidget = this; - } - var x = Bounds.X; var y = Bounds.Y; @@ -1499,11 +1501,31 @@ public virtual void OnTouchDown() public virtual void OnTouchUp() { + if (TouchStayedInside) + { + OnClick(); + } + _startPos = null; + TouchStayedInside = false; IsTouchInside = false; TouchUp.Invoke(this); } + public virtual void OnClick() + { + if (Enabled && AcceptsKeyboardFocus) + { + Desktop.FocusedKeyboardWidget = this; + } + + if (Enabled && AcceptsMouseWheelFocus) + { + Desktop.FocusedMouseWheelWidget = this; + } + Click.Invoke(this); + } + protected void FireKeyDown(Keys k) { KeyDown.Invoke(this, k); @@ -1612,7 +1634,7 @@ private void SubscribeOnTouchMoved(bool subscribe) } } - private void DesktopOnTouchMoved(object sender, EventArgs args) + private void DesktopOnTouchMoved(object sender, HookableEventArgs args) { if (_startPos == null || !IsDraggable) { diff --git a/src/Myra/Utility/HookableEventArgs.cs b/src/Myra/Utility/HookableEventArgs.cs new file mode 100644 index 00000000..8cbdd868 --- /dev/null +++ b/src/Myra/Utility/HookableEventArgs.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Myra.Utility +{ + public class HookableEventArgs : EventArgs + { + public bool WasHandled { get; private set; } + + private Action _hook; + + public void SetHandledFlag() + { + WasHandled = true; + } + + public void AddHook(Action hook) + { + _hook = hook; + } + + public bool InvokeHookIfNotHandled() + { + if (_hook == null || WasHandled) + { + return false; + } + + _hook.Invoke(); + return true; + } + } +} diff --git a/src/Myra/Utility/InputHelpers.cs b/src/Myra/Utility/InputHelpers.cs index 72cc789a..48f103b0 100644 --- a/src/Myra/Utility/InputHelpers.cs +++ b/src/Myra/Utility/InputHelpers.cs @@ -155,7 +155,7 @@ public static void ProcessMouseMovement(this List widgets) } } - public static void ProcessTouchMovement(this List widgets) + public static void ProcessTouchMovement(this List widgets, HookableEventArgs args) { // First run: call on OnTouchLeft on all widgets if it is required for (var i = widgets.Count - 1; i >= 0; --i) @@ -163,11 +163,11 @@ public static void ProcessTouchMovement(this List widgets) var w = widgets[i]; if (!w.ContainsTouch && w.IsTouchInside) { - w.OnTouchLeft(); + w.OnTouchLeft(args); } } - // Second run: OnTouchEnter/OnTouchMoved + // Second run: OnTouchEnter/OnTouchMoved for (var i = widgets.Count - 1; i >= 0; --i) { var w = widgets[i]; @@ -179,12 +179,12 @@ public static void ProcessTouchMovement(this List widgets) if (isTouchOver && !wasTouchOver) { - w.OnTouchEntered(); + w.OnTouchEntered(args); } if (isTouchOver && wasTouchOver) { - w.OnTouchMoved(); + w.OnTouchMoved(args); } if (w.Desktop != null && !w.FallsThrough(w.Desktop.TouchPosition))