Skip to content

Commit

Permalink
feat(dragdrop): Implement basic UI
Browse files Browse the repository at this point in the history
  • Loading branch information
dr1rrb committed Oct 16, 2020
1 parent 589897e commit fabb408
Show file tree
Hide file tree
Showing 5 changed files with 292 additions and 81 deletions.
73 changes: 73 additions & 0 deletions src/Uno.UI/UI/Xaml/DragRoot.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#nullable enable

using System;
using System.Linq;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;

namespace Windows.UI.Xaml
{
internal class DragRoot : Canvas
{
private readonly DragDropManager _manager;

public DragRoot(DragDropManager manager)
{
_manager = manager;

VerticalAlignment = VerticalAlignment.Stretch;
HorizontalAlignment = HorizontalAlignment.Stretch;
Background = new SolidColorBrush(Colors.Transparent);

//PointerEntered += OnPointerEntered;
//PointerExited += OnPointerExited;
//PointerMoved += OnPointerMoved;
//PointerReleased += OnPointerReleased;
//PointerCanceled += OnPointerCanceled;
}

public int PendingDragCount => Children.Count;

public void Show(DragView view)
{
view.IsHitTestVisible = false;
Children.Add(view);
}

public void Hide(DragView view)
{
Children.Remove(view);
}

private static void OnPointerEntered(object snd, PointerRoutedEventArgs e)
{
((DragRoot)snd)._manager.ProcessPointerEnteredWindow(e);
e.Handled = true;
}

private static void OnPointerExited(object snd, PointerRoutedEventArgs e)
{
((DragRoot)snd)._manager.ProcessPointerExitedWindow(e);
e.Handled = true;
}

private static void OnPointerMoved(object snd, PointerRoutedEventArgs e)
{
((DragRoot)snd)._manager.ProcessPointerMovedOverWindow(e);
e.Handled = true;
}

private static void OnPointerReleased(object snd, PointerRoutedEventArgs e)
{
((DragRoot)snd)._manager.ProcessPointerReleased(e);
e.Handled = true;
}

private static void OnPointerCanceled(object snd, PointerRoutedEventArgs e)
{
((DragRoot)snd)._manager.ProcessPointerCanceled(e);
e.Handled = true;
}
}
}
69 changes: 0 additions & 69 deletions src/Uno.UI/UI/Xaml/DragUIRoot.cs

This file was deleted.

171 changes: 164 additions & 7 deletions src/Uno.UI/UI/Xaml/DragView.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,192 @@
#nullable enable
#nullable enable

using System;
using System.Collections.Generic;
using System.Linq;
using Windows.ApplicationModel.DataTransfer;
using Windows.ApplicationModel.DataTransfer.DragDrop.Core;
using Windows.Foundation;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;

namespace Windows.UI.Xaml
{
internal class DragView : Control
{
private readonly Stack<DragUIOverride> _overrides = new Stack<DragUIOverride>();
#region Glyph
public static readonly DependencyProperty GlyphProperty = DependencyProperty.Register(
"Glyph", typeof(string), typeof(DragView), new PropertyMetadata(default(string)));

public string Glyph
{
get { return (string)GetValue(GlyphProperty); }
set { SetValue(GlyphProperty, value); }
}
#endregion

#region GlyphVisibility
public static readonly DependencyProperty GlyphVisibilityProperty = DependencyProperty.Register(
"GlyphVisibility", typeof(Visibility), typeof(DragView), new PropertyMetadata(default(Visibility)));

public Visibility GlyphVisibility
{
get => (Visibility)GetValue(GlyphVisibilityProperty);
private set => SetValue(GlyphVisibilityProperty, value);
}
#endregion

#region Caption
public static readonly DependencyProperty CaptionProperty = DependencyProperty.Register(
"Caption", typeof(string), typeof(DragView), new PropertyMetadata(default(string)));

public string Caption
{
get => (string)GetValue(CaptionProperty);
set => SetValue(CaptionProperty, value);
}
#endregion

#region CaptionVisibility
public static readonly DependencyProperty CaptionVisibilityProperty = DependencyProperty.Register(
"CaptionVisibility", typeof(Visibility), typeof(DragView), new PropertyMetadata(default(Visibility)));

public Visibility CaptionVisibility
{
get => (Visibility)GetValue(CaptionVisibilityProperty);
private set => SetValue(CaptionVisibilityProperty, value);
}
#endregion

#region Content
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(
"Content", typeof(ImageSource), typeof(DragView), new PropertyMetadata(default(ImageSource)));

public ImageSource? Content
{
get => (ImageSource?)GetValue(ContentProperty);
private set => SetValue(ContentProperty, value);
}
#endregion

#region ContentVisibility
public static readonly DependencyProperty ContentVisibilityProperty = DependencyProperty.Register(
"ContentVisibility", typeof(Visibility), typeof(DragView), new PropertyMetadata(default(Visibility)));

public Visibility ContentVisibility
{
get => (Visibility)GetValue(ContentVisibilityProperty);
private set => SetValue(ContentVisibilityProperty, value);
}
#endregion

#region TooltipVisibility
public static readonly DependencyProperty TooltipVisibilityProperty = DependencyProperty.Register(
"TooltipVisibility", typeof(Visibility), typeof(DragView), new PropertyMetadata(default(Visibility)));

public Visibility TooltipVisibility
{
get => (Visibility)GetValue(TooltipVisibilityProperty);
set => SetValue(TooltipVisibilityProperty, value);
}
#endregion

private readonly DragUI? _ui;
private readonly TranslateTransform _transform;

private Point _location;

public DragView(DragUI? ui)
{

_ui = ui;
DefaultStyleKey = typeof(DragView);
RenderTransform = _transform = new TranslateTransform();

Content = ui?.Content;
}

public void SetLocation(Point location)
{
// TODO: Make sure to not move the element out of the bounds of the window
_location = location;

_transform.X = location.X - (ActualWidth / 2);
_transform.Y = location.Y - 40; // The caption is above the pointer
}

public void Stack(DragUIOverride @override)
public void Update(DataPackageOperation acceptedOperation, CoreDragUIOverride viewOverride)
{
// UWP does not allow new lines (trim to the first line, even if blank) and trims the text.
var caption = viewOverride
.Caption
?.Split(new[] {'\r', '\n'}, StringSplitOptions.None)
.FirstOrDefault()
?.Trim();

if (string.IsNullOrEmpty(caption))
{
caption = ToCaption(acceptedOperation);
}

Glyph = ToGlyph(acceptedOperation);
GlyphVisibility = ToVisibility(viewOverride.IsGlyphVisible);
Caption = caption!;
CaptionVisibility = ToVisibility(viewOverride.IsCaptionVisible);
Content = viewOverride.Content as ImageSource ?? _ui?.Content;
ContentVisibility = ToVisibility(viewOverride.IsContentVisible);
TooltipVisibility = ToVisibility(viewOverride.IsGlyphVisible || viewOverride.IsCaptionVisible);
Visibility = Visibility.Visible;
}

public void Hide()
{
Visibility = Visibility.Collapsed;
}

private static Visibility ToVisibility(bool isVisible)
=> isVisible ? Visibility.Visible : Visibility.Collapsed;

private static string ToGlyph(DataPackageOperation result)
{
_overrides.Push(@override);
// If multiple flags set (which should not!), the UWP precedence is Link > Copy > Move
// TODO: Real glyph
if (result.HasFlag(DataPackageOperation.Link))
{
return "🔗";
}
else if (result.HasFlag(DataPackageOperation.Copy))
{
return "";
}
else if (result.HasFlag(DataPackageOperation.Move))
{
return "🡕";
}
else // None
{
return "🚫";
}
}

public void Pop()
private static string ToCaption(DataPackageOperation result)
{
_overrides.Pop();
// If multiple flags set (which should not!), the UWP precedence is Link > Copy > Move
// TODO: Localize
if (result.HasFlag(DataPackageOperation.Link))
{
return "Link";
}
else if (result.HasFlag(DataPackageOperation.Copy))
{
return "Copy";
}
else if (result.HasFlag(DataPackageOperation.Move))
{
return "Move";
}
else // None
{
return string.Empty;
}
}
}
}
45 changes: 45 additions & 0 deletions src/Uno.UI/UI/Xaml/DragView.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:win="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:u="using:Uno.UI.Controls"
xmlns:ios="http://uno.ui/ios"
xmlns:android="http://uno.ui/android"
xmlns:wasm="http://uno.ui/wasm"
xmlns:netstdref="http://uno.ui/netstdref"
xmlns:skia="http://uno.ui/skia"
xmlns:macos="http://uno.ui/macos"
xmlns:uBehaviors="using:Uno.UI.Behaviors"
mc:Ignorable="d ios android wasm netstdref macos skia">

<!-- Default style for Windows.UI.Xaml.Controls.ScrollViewer -->
<Style TargetType="DragView">
<Setter Property="IsTabStop" Value="False" />
<Setter Property="IsHitTestVisible" Value="False" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Padding" Value="0" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DragView">
<Grid>
<Image Visibility="{TemplateBinding CaptionVisiblity}" Source="{TemplateBinding Content}" Opacity=".8" />
<StackPanel
Orientation="Horizontal"
BorderThickness="1"
BorderBrush="{StaticResource SystemControlForegroundChromeHighBrush}"
Background="{StaticResource SystemControlBackgroundChromeMediumLowBrush}"
Padding="2,5"
Visibility="{TemplateBinding TooltipVisibility}">
<TextBlock Visibility="{TemplateBinding GlyphVisiblity}" Text="{TemplateBinding Glyph}" Margin="3,0" />
<TextBlock Visibility="{TemplateBinding CaptionVisiblity}" Text="{TemplateBinding Caption}" Margin="3,0" />
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Loading

0 comments on commit fabb408

Please sign in to comment.