// Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; using System.Reactive; using System.Reactive.Linq; using Avalonia.Data; using Avalonia.Interactivity; using Avalonia.Input; using Avalonia.Layout; namespace Avalonia.Controls.Primitives { public class ScrollEventArgs : EventArgs { public ScrollEventArgs(ScrollEventType eventType, double newValue) { ScrollEventType = eventType; NewValue = newValue; } public double NewValue { get; private set; } public ScrollEventType ScrollEventType { get; private set; } } /// /// A scrollbar control. /// public class ScrollBar : RangeBase { /// /// Defines the property. /// public static readonly StyledProperty ViewportSizeProperty = AvaloniaProperty.Register(nameof(ViewportSize), defaultValue: double.NaN); /// /// Defines the property. /// public static readonly StyledProperty VisibilityProperty = AvaloniaProperty.Register(nameof(Visibility)); /// /// Defines the property. /// public static readonly StyledProperty OrientationProperty = AvaloniaProperty.Register(nameof(Orientation), Orientation.Vertical); private Button _lineUpButton; private Button _lineDownButton; private Button _pageUpButton; private Button _pageDownButton; /// /// Initializes static members of the class. /// static ScrollBar() { Thumb.DragDeltaEvent.AddClassHandler((x, e) => x.OnThumbDragDelta(e), RoutingStrategies.Bubble); Thumb.DragCompletedEvent.AddClassHandler((x, e) => x.OnThumbDragComplete(e), RoutingStrategies.Bubble); } /// /// Initializes a new instance of the class. /// public ScrollBar() { var isVisible = Observable.Merge( this.GetObservable(MinimumProperty).Select(_ => Unit.Default), this.GetObservable(MaximumProperty).Select(_ => Unit.Default), this.GetObservable(ViewportSizeProperty).Select(_ => Unit.Default), this.GetObservable(VisibilityProperty).Select(_ => Unit.Default)) .Select(_ => CalculateIsVisible()); this.Bind(IsVisibleProperty, isVisible, BindingPriority.Style); UpdatePseudoClasses(Orientation); } /// /// Gets or sets the amount of the scrollable content that is currently visible. /// public double ViewportSize { get { return GetValue(ViewportSizeProperty); } set { SetValue(ViewportSizeProperty, value); } } /// /// Gets or sets a value that indicates whether the scrollbar should hide itself when it /// is not needed. /// public ScrollBarVisibility Visibility { get { return GetValue(VisibilityProperty); } set { SetValue(VisibilityProperty, value); } } /// /// Gets or sets the orientation of the scrollbar. /// public Orientation Orientation { get { return GetValue(OrientationProperty); } set { SetValue(OrientationProperty, value); } } public event EventHandler Scroll; /// /// Calculates whether the scrollbar should be visible. /// /// The scrollbar's visibility. private bool CalculateIsVisible() { switch (Visibility) { case ScrollBarVisibility.Visible: return true; case ScrollBarVisibility.Disabled: case ScrollBarVisibility.Hidden: return false; case ScrollBarVisibility.Auto: return double.IsNaN(ViewportSize) || Maximum > 0; default: throw new InvalidOperationException("Invalid value for ScrollBar.Visibility."); } } protected override void OnKeyDown(KeyEventArgs e) { if (e.Key == Key.PageUp) { LargeDecrement(); e.Handled = true; } else if (e.Key == Key.PageDown) { LargeIncrement(); e.Handled = true; } } protected override void OnPropertyChanged( AvaloniaProperty property, Optional oldValue, BindingValue newValue, BindingPriority priority) { base.OnPropertyChanged(property, oldValue, newValue, priority); if (property == OrientationProperty) { UpdatePseudoClasses(newValue.GetValueOrDefault()); } } protected override void OnTemplateApplied(TemplateAppliedEventArgs e) { base.OnTemplateApplied(e); if (_lineUpButton != null) { _lineUpButton.Click -= LineUpClick; } if (_lineDownButton != null) { _lineDownButton.Click -= LineDownClick; } if (_pageUpButton != null) { _pageUpButton.Click -= PageUpClick; } if (_pageDownButton != null) { _pageDownButton.Click -= PageDownClick; } _lineUpButton = e.NameScope.Find