Skip to content

Commit

Permalink
fix: Seek bar double tooltips bug (#379)
Browse files Browse the repository at this point in the history
* fix seekbar double tooltips bug and better match the tooltip style to the Slider tooltip

* fix posible preview tooltip translation drift
  • Loading branch information
huynhsontung authored May 17, 2024
1 parent a93c937 commit feaffc0
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 46 deletions.
3 changes: 3 additions & 0 deletions Screenbox/Controls/SeekBar.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,13 @@
Foreground="{x:Bind Foreground, Mode=OneWay}"
IsEnabled="{x:Bind ViewModel.IsSeekable, Mode=OneWay, FallbackValue=False}"
IsKeyDownEnabled="{x:Bind ViewModel.ShouldHandleKeyDown, Mode=OneWay}"
IsThumbToolTipEnabled="{x:Bind ViewModel.ShouldShowPreview, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}"
LargeChange="10000"
Loaded="SeekBarSlider_OnLoaded"
Maximum="{x:Bind ViewModel.Length, Mode=OneWay, FallbackValue=0}"
Minimum="0"
PointerCanceled="SeekBarSlider_OnPointerExited"
PointerEntered="SeekBarSlider_OnPointerEntered"
PointerExited="SeekBarSlider_OnPointerExited"
SizeChanged="SeekBarSlider_OnSizeChanged"
SmallChange="5000"
Expand Down
72 changes: 26 additions & 46 deletions Screenbox/Controls/SeekBar.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ public bool ProgressOnly

internal SeekBarViewModel ViewModel => (SeekBarViewModel)DataContext;
private readonly DispatcherQueueTimer _previewToolTipTimer;
private bool _overridePreviewToolTipDelay;
private Thumb? _seekBarThumb;

private readonly ToolTip _previewToolTip;
Expand All @@ -47,7 +46,7 @@ public SeekBar()
RegisterSeekBarPointerHandlers();
DispatcherQueue dispatcherQueue = DispatcherQueue.GetForCurrentThread();
_previewToolTipTimer = dispatcherQueue.CreateTimer();
_previewToolTip = new ToolTip { Padding = new Thickness(8, 3, 8, 5), FontSize = 14 };
_previewToolTip = new ToolTip { Padding = new Thickness(8, 3, 8, 5), FontSize = 15, VerticalOffset = 13 };

ViewModel.PropertyChanged += ViewModelOnPropertyChanged;
}
Expand All @@ -71,41 +70,38 @@ private void RegisterSeekBarPointerHandlers()
private void PointerReleasedEventHandler(object sender, PointerRoutedEventArgs e)
{
ViewModel.OnSeekBarPointerEvent(false);
if (!ViewModel.ShouldShowPreview)
{
_previewToolTipTimer.Debounce(() =>
{
ViewModel.ShouldShowPreview = true;
}, TimeSpan.FromMilliseconds(500));
}
}

private void PointerPressedEventHandler(object sender, PointerRoutedEventArgs e)
{
ViewModel.OnSeekBarPointerEvent(true);
ViewModel.ShouldShowPreview = false;
}

private void PointerMovedEventHandler(object s, PointerRoutedEventArgs e)
{
if (!ViewModel.ShouldShowPreview) return;
PointerPoint pointerPoint = e.GetCurrentPoint(SeekBarSlider);
UpdatePreviewTime(pointerPoint);
if (_previewToolTip.IsOpen || _overridePreviewToolTipDelay)
{
_overridePreviewToolTipDelay = false;
_previewToolTipTimer.Stop();
ShowPreviewToolTip(pointerPoint);
}
else
double halfWidth = SeekBarSlider.ActualWidth / 2;
_previewToolTip.Translation = new Vector3((float)(-halfWidth + pointerPoint.Position.X), 0, 0);
if (!ViewModel.ShouldShowPreview || !_previewToolTip.IsOpen) return;
_previewToolTipTimer.Stop();
_previewToolTip.IsOpen = true;
}

private void SeekBarSlider_OnPointerEntered(object sender, PointerRoutedEventArgs e)
{
if (ToolTipService.GetToolTip(SeekBarSlider) is not ToolTip)
{
_previewToolTipTimer.Debounce(() => ShowPreviewToolTip(pointerPoint), TimeSpan.FromMilliseconds(50));
ToolTipService.SetToolTip(SeekBarSlider, _previewToolTip);
}

ViewModel.ShouldShowPreview = true;
_previewToolTipTimer.Debounce(() => _previewToolTip.IsOpen = true, TimeSpan.FromMilliseconds(100));
}

private void SeekBarSlider_OnPointerExited(object sender, PointerRoutedEventArgs e)
{
ViewModel.ShouldShowPreview = true;
ViewModel.ShouldShowPreview = false;
_previewToolTipTimer.Stop();
_previewToolTip.IsOpen = false;
ToolTipService.SetToolTip(SeekBarSlider, null);
Expand All @@ -121,21 +117,20 @@ private void SeekBarSlider_OnLoaded(object sender, RoutedEventArgs e)
_seekBarThumb = SeekBarSlider.FindDescendant<Thumb>();
if (_seekBarThumb != null)
{
_seekBarThumb.PointerEntered += SeekBarThumb_PointerEntered;
_seekBarThumb.PointerExited += SeekBarThumb_PointerExited;
_seekBarThumb.PointerCanceled += SeekBarSlider_OnPointerExited;
// When Thumb is pressed, it hijacks pointer events until it's released
_seekBarThumb.PointerReleased += SeekBarThumb_PointerReleased;
}
}

private void SeekBarThumb_PointerExited(object sender, PointerRoutedEventArgs e)
{
ViewModel.ShouldShowPreview = true;
_overridePreviewToolTipDelay = true;
}

private void SeekBarThumb_PointerEntered(object sender, PointerRoutedEventArgs e)
private void SeekBarThumb_PointerReleased(object sender, PointerRoutedEventArgs e)
{
ViewModel.ShouldShowPreview = false;
var position = e.GetCurrentPoint(SeekBarSlider).Position;
bool inBound = position.X >= 0 && position.X <= SeekBarSlider.ActualWidth &&
position.Y >= 0 && position.Y <= SeekBarSlider.ActualHeight;
if (!inBound)
{
SeekBarSlider_OnPointerExited(sender, e);
}
}

private void ResetPreviewToolTip()
Expand All @@ -144,21 +139,6 @@ private void ResetPreviewToolTip()
_previewToolTip.IsOpen = false;
}

private void ShowPreviewToolTip(PointerPoint pointerPoint)
{
double halfWidth = SeekBarSlider.ActualWidth / 2;
if (ToolTipService.GetToolTip(SeekBarSlider) is not ToolTip)
{
ToolTipService.SetToolTip(SeekBarSlider, _previewToolTip);
}
else
{
_previewToolTip.IsOpen = true;
}

_previewToolTip.Translation = new Vector3((float)(-halfWidth + pointerPoint.Position.X), 0, 0);
}

private void UpdatePreviewTime(PointerPoint pointerPoint)
{
double pointerOffset = pointerPoint.Position.X;
Expand Down

0 comments on commit feaffc0

Please sign in to comment.