diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2019-05-23 16:44:30 +0300 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2019-05-23 16:44:30 +0300 |
| commit | 26cee052a5b20d7a5bdb597776c55dcd3da2da62 (patch) | |
| tree | fd4a4bfceeb4509515913557fc66ad28704abdf9 /Software/Visual_Studio/PPC/Tango.PPC.Common/Controls | |
| parent | 2521b3c058fe18f1ebd48a85577349b49c1c2108 (diff) | |
| download | Tango-26cee052a5b20d7a5bdb597776c55dcd3da2da62.tar.gz Tango-26cee052a5b20d7a5bdb597776c55dcd3da2da62.zip | |
Implemented new Twine color catalog !
Diffstat (limited to 'Software/Visual_Studio/PPC/Tango.PPC.Common/Controls')
3 files changed, 414 insertions, 60 deletions
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Controls/TwineCatalogControl.xaml b/Software/Visual_Studio/PPC/Tango.PPC.Common/Controls/TwineCatalogControl.xaml index 93af8965a..65db9818c 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Controls/TwineCatalogControl.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Controls/TwineCatalogControl.xaml @@ -14,20 +14,21 @@ <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="1*"/> - <ColumnDefinition Width="0"/> + <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> - <ListBox Style="{StaticResource BlankListBox}" ItemsSource="{Binding Groups}" VirtualizingPanel.VirtualizationMode="Recycling" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.ScrollUnit="Pixel" x:Name="list" x:FieldModifier="public" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Hidden"> - <ListBox.ItemsPanel> - <ItemsPanelTemplate> - <VirtualizingStackPanel /> - </ItemsPanelTemplate> - </ListBox.ItemsPanel> - <ListBox.ItemTemplate> + <touch:LightTouchScrollViewer x:Name="scrollViewer" ScrollBarVisibility="Collapsed"> + <!--<Border Background="White">--> + <local:TwineCatalogRenderer x:Name="renderer" Groups="{Binding Groups}" SelectedItem="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=SelectedItem,Mode=TwoWay}"></local:TwineCatalogRenderer> + <!--</Border>--> + </touch:LightTouchScrollViewer> + + <!--<touch:TouchListBox ItemsSource="{Binding Groups}" x:Name="list" x:FieldModifier="public" DisableRipple="True" ScrollBarVisibility="Collapsed" SelectionMode="None"> + <touch:TouchListBox.ItemTemplate> <DataTemplate> <StackPanel Margin="0 0 10 0"> <TextBlock HorizontalAlignment="Center" Text="{Binding Name,IsAsync=True}" FontSize="{StaticResource TangoTitleFontSize}"></TextBlock> - <touch:TouchStaticListBox ItemsSource="{Binding Items}" SelectedItem="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=SelectedItem,Mode=TwoWay}" Margin="0 20 0 40"> + <touch:TouchStaticListBox ItemsSource="{Binding Items,IsAsync=True}" SelectedItem="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=SelectedItem,Mode=TwoWay}" Margin="0 20 0 40"> <touch:TouchStaticListBox.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Orientation="Horizontal" /> @@ -41,11 +42,13 @@ <ScaleTransform ScaleX="1" ScaleY="1" /> </Setter.Value> </Setter> - <!--<Setter Property="Effect"> + --> + <!--<Setter Property="Effect"> <Setter.Value> <DropShadowEffect Color="{StaticResource TangoDarkForegroundColor}" ShadowDepth="0" BlurRadius="20" Opacity="0" /> </Setter.Value> </Setter>--> + <!-- <Style.Triggers> <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},Path=IsSelected}" Value="True"> <DataTrigger.EnterActions> @@ -53,7 +56,9 @@ <Storyboard> <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" To="1.5" Duration="00:00:00" /> <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" To="1.5" Duration="00:00:00" /> - <!--<DoubleAnimation Storyboard.TargetProperty="Effect.Opacity" To="1" Duration="00:00:0.2" />--> + --> + <!--<DoubleAnimation Storyboard.TargetProperty="Effect.Opacity" To="1" Duration="00:00:0.2" />--> + <!-- </Storyboard> </BeginStoryboard> </DataTrigger.EnterActions> @@ -62,7 +67,9 @@ <Storyboard> <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" To="1" Duration="00:00:00" /> <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" To="1" Duration="00:00:00" /> - <!--<DoubleAnimation Storyboard.TargetProperty="Effect.Opacity" To="0" Duration="00:00:0.2" />--> + --> + <!--<DoubleAnimation Storyboard.TargetProperty="Effect.Opacity" To="0" Duration="00:00:0.2" />--> + <!-- </Storyboard> </BeginStoryboard> </DataTrigger.ExitActions> @@ -74,15 +81,17 @@ <DataTemplate> <StackPanel Margin="10" Width="70"> <Ellipse Width="60" Height="60" Fill="{Binding Brush}" /> - <controls:FastTextBlock Margin="0 5 0 0" HorizontalAlignment="Center" Text="{Binding Name,IsAsync=True}"></controls:FastTextBlock> + --> + <!--<controls:FastTextBlock Margin="0 5 0 0" HorizontalAlignment="Center" Text="{Binding Name,IsAsync=True}"></controls:FastTextBlock>--> + <!-- </StackPanel> </DataTemplate> </touch:TouchStaticListBox.ItemTemplate> </touch:TouchStaticListBox> </StackPanel> </DataTemplate> - </ListBox.ItemTemplate> - </ListBox> + </touch:TouchListBox.ItemTemplate> + </touch:TouchListBox>--> <Grid Grid.Column="1"> <!--<Rectangle Stroke="{StaticResource TangoDividerBrush}" HorizontalAlignment="Left" />--> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Controls/TwineCatalogControl.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Controls/TwineCatalogControl.xaml.cs index e23c629c5..af5888f3f 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Controls/TwineCatalogControl.xaml.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Controls/TwineCatalogControl.xaml.cs @@ -47,20 +47,22 @@ namespace Tango.PPC.Common.Controls { InitializeComponent(); - list.ApplyTemplate(); - list.Loaded += TwineCatalogControl_Loaded; + //list.ApplyTemplate(); + //list.Loaded += TwineCatalogControl_Loaded; DataContextChanged += (x, y) => { _catalog = DataContext as Catalog; - //if (list.ScrollViewer != null && _catalog != null) - //{ - // list.ScrollViewer.ScrollToTop(); - // _preventChange = true; - // slider.Value = _catalog.Groups.Count; - // _preventChange = false; - //} + if (scrollViewer != null && _catalog != null) + { + scrollViewer.ScrollToTop(); + _preventChange = true; + slider.Value = _catalog.Groups.Count; + _preventChange = false; + } }; + + scrollViewer.Scrolling += ScrollViewer_Scrolling; } /// <summary> @@ -70,22 +72,22 @@ namespace Tango.PPC.Common.Controls /// <param name="e">The <see cref="Touch.Controls.DoubleValueChangedEventArgs"/> instance containing the event data.</param> private void ScrollViewer_Scrolling(object sender, Touch.Controls.DoubleValueChangedEventArgs e) { - //if (!_preventChange) - //{ - // if (e.Value > _lastScrollPosition + 60 || e.Value < _lastScrollPosition - 60) - // { - // var group = list.ScrollViewer.GetMostVisibleElementDataContext<CatalogGroup>(); + if (!_preventChange) + { + if (e.Value > _lastScrollPosition + 60 || e.Value < _lastScrollPosition - 60) + { + var group = renderer.GetVisibleGroup(); - // if (group != null) - // { - // _preventChange = true; - // slider.Value = slider.Maximum - _catalog.Groups.IndexOf(group); - // _preventChange = false; - // } + if (group != null) + { + _preventChange = true; + slider.Value = slider.Maximum - _catalog.Groups.IndexOf(group); + _preventChange = false; + } - // _lastScrollPosition = e.Value; - // } - //} + _lastScrollPosition = e.Value; + } + } } /// <summary> @@ -113,22 +115,23 @@ namespace Tango.PPC.Common.Controls /// <param name="e">The <see cref="RoutedPropertyChangedEventArgs{System.Double}"/> instance containing the event data.</param> private void TouchSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { - //if (_catalog == null || _catalog.Groups.Count == 0) return; + if (_catalog == null || _catalog.Groups.Count == 0) return; - //if (!_preventChange) - //{ - // if (_catalog != null) - // { - // _preventChange = true; - // list.ScrollToItem(_catalog.Groups.ElementAt(_catalog.Groups.Count - 1 - (int)e.NewValue)); - // _preventChange = false; - // } - //} + if (!_preventChange) + { + if (_catalog != null) + { + _preventChange = true; + var group = _catalog.Groups.ElementAt(_catalog.Groups.Count - 1 - (int)e.NewValue); + scrollViewer.ScrollToPosition(renderer.GetGroupPosition(group)); + _preventChange = false; + } + } - //if (_catalog != null && _catalog.Groups.Count > _catalog.Groups.Count - 1 - (int)e.NewValue && _catalog.Groups.Count - 1 - (int)e.NewValue > -1) - //{ - // slider.Foreground = new SolidColorBrush(_catalog.Groups.ElementAt(_catalog.Groups.Count - 1 - (int)e.NewValue).Color); - //} + if (_catalog != null && _catalog.Groups.Count > _catalog.Groups.Count - 1 - (int)e.NewValue && _catalog.Groups.Count - 1 - (int)e.NewValue > -1) + { + slider.Foreground = new SolidColorBrush(_catalog.Groups.ElementAt(_catalog.Groups.Count - 1 - (int)e.NewValue).Color); + } } /// <summary> @@ -136,14 +139,14 @@ namespace Tango.PPC.Common.Controls /// </summary> private void OnSelectedItemChanged() { - if (!_preventChange) - { - _preventChange = true; - var item = SelectedItem; - SelectedItem = null; - SelectedItem = item; - _preventChange = false; - } + //if (!_preventChange) + //{ + // _preventChange = true; + // var item = SelectedItem; + // SelectedItem = null; + // SelectedItem = item; + // _preventChange = false; + //} } /// <summary> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Controls/TwineCatalogRenderer.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Controls/TwineCatalogRenderer.cs new file mode 100644 index 000000000..7a8ddbb46 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Controls/TwineCatalogRenderer.cs @@ -0,0 +1,342 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; +using Tango.BL.Catalogs; +using Tango.Touch.Controls; + +namespace Tango.PPC.Common.Controls +{ + public class TwineCatalogRenderer : FrameworkElement + { + private class ItemContainer + { + public DrawingVisual Visual { get; set; } + public CatalogItem Item { get; set; } + public double PositionY { get; set; } + } + + private class GroupContainer + { + public DrawingVisual Visual { get; set; } + public CatalogGroup Group { get; set; } + public double PositionY { get; set; } + + public List<ItemContainer> Items { get; set; } + + public GroupContainer() + { + Items = new List<ItemContainer>(); + } + } + + private readonly VisualCollection _children; + private List<ItemContainer> _catalogItems; + private List<GroupContainer> _groupItems; + private double ellipseWidth = 60; + private double ellipseHeight = 60; + private double textHeight = 30; + private double ellipseMargin = 20; + private double textMargin = 5; + private double groupMargin = 60; + private bool selectedFromClick; + private LightTouchScrollViewer _scrollViewer; + + public List<CatalogGroup> Groups + { + get { return (List<CatalogGroup>)GetValue(GroupsProperty); } + set { SetValue(GroupsProperty, value); } + } + public static readonly DependencyProperty GroupsProperty = + DependencyProperty.Register("Groups", typeof(List<CatalogGroup>), typeof(TwineCatalogRenderer), new PropertyMetadata(null, (d, e) => { (d as TwineCatalogRenderer).OnCatalogChanged(); })); + + public CatalogItem SelectedItem + { + get { return (CatalogItem)GetValue(SelectedItemProperty); } + set { SetValue(SelectedItemProperty, value); } + } + public static readonly DependencyProperty SelectedItemProperty = + DependencyProperty.Register("SelectedItem", typeof(CatalogItem), typeof(TwineCatalogRenderer), new PropertyMetadata(null, (d, e) => (d as TwineCatalogRenderer).OnSelectedItemChanged(e.OldValue, e.NewValue))); + + public Brush Foreground + { + get { return (Brush)this.GetValue(ForegroundProperty); } + set { this.SetValue(ForegroundProperty, value); } + } + public static readonly DependencyProperty ForegroundProperty = + TextBlock.ForegroundProperty.AddOwner(typeof(TwineCatalogRenderer)); + + public Brush Background + { + get { return (Brush)GetValue(BackgroundProperty); } + set { SetValue(BackgroundProperty, value); } + } + public static readonly DependencyProperty BackgroundProperty = + DependencyProperty.Register("Background", typeof(Brush), typeof(TwineCatalogRenderer), new PropertyMetadata(null)); + + + public TwineCatalogRenderer() + { + Background = new SolidColorBrush(Colors.White); + + _children = new VisualCollection(this); + _catalogItems = new List<ItemContainer>(); + _groupItems = new List<GroupContainer>(); + + this.PreviewMouseUp += TwineCatalogRenderer_MouseLeftButtonUp; + this.Loaded += TwineCatalogRenderer_Loaded; + } + + private void TwineCatalogRenderer_Loaded(object sender, RoutedEventArgs e) + { + _scrollViewer = this.FindAncestor<LightTouchScrollViewer>(); + } + + public CatalogGroup GetVisibleGroup() + { + double currentPosition = _scrollViewer.GetScrollPosition(); + + var viewportRect = _scrollViewer.GetViewPortRect(); + + foreach (var group in _groupItems.Where(x => x.Items.Count > 0).Reverse().ToList()) + { + var groupRect = GetGroupRect(group); + + if (groupRect.IntersectsWith(viewportRect)) + { + return group.Group; + } + } + + return null; + } + + public double GetGroupPosition(CatalogGroup group) + { + return _groupItems.Single(x => x.Group == group).PositionY; + } + + private Rect GetGroupRect(GroupContainer group) + { + var height = group.Items.Last().PositionY - group.PositionY; + return new Rect(0, group.PositionY + (height / 4), ActualWidth, height); + } + + private void TwineCatalogRenderer_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) + { + + if (!_scrollViewer.IsAfterScrolling) + { + // Retreive the coordinates of the mouse button event. + Point pt = e.GetPosition((UIElement)this); + + // Initiate the hit test by setting up a hit test result callback method. + VisualTreeHelper.HitTest(this, null, HitTestCallback, new PointHitTestParameters(pt)); + } + } + + // If a child visual object is hit, toggle its opacity to visually indicate a hit. + public HitTestResultBehavior HitTestCallback(HitTestResult result) + { + if (result.VisualHit.GetType() == typeof(System.Windows.Media.DrawingVisual)) + { + var visual = result.VisualHit as DrawingVisual; + + if (visual != null) + { + var container = _catalogItems.SingleOrDefault(x => x.Visual == visual); + + if (container != null && container.Item is CatalogItem) + { + selectedFromClick = true; + SelectedItem = container.Item; + selectedFromClick = false; + } + } + } + + // Stop the hit test enumeration of objects in the visual tree. + return HitTestResultBehavior.Stop; + } + + private void OnSelectedItemChanged(object oldValue, object newValue) + { + var newItem = _catalogItems.SingleOrDefault(x => x.Item == newValue); + var oldItem = _catalogItems.SingleOrDefault(x => x.Item == oldValue); + + if (newItem != null) + { + (newItem.Visual.Transform as ScaleTransform).ScaleX = 1.3; + (newItem.Visual.Transform as ScaleTransform).ScaleY = 1.3; + + if (!selectedFromClick) + { + _scrollViewer.ScrollToPosition(newItem.PositionY - _scrollViewer.ActualHeight / 2); + } + } + + if (oldItem != null) + { + (oldItem.Visual.Transform as ScaleTransform).ScaleX = 1; + (oldItem.Visual.Transform as ScaleTransform).ScaleY = 1; + } + } + + private ItemContainer AddCatalogItem(DrawingVisual visual, CatalogItem item, double y) + { + _children.Add(visual); + + var container = new ItemContainer() + { + Visual = visual, + Item = item, + PositionY = y, + }; + + _catalogItems.Add(container); + + return container; + } + + private GroupContainer AddGroupItem(DrawingVisual visual, CatalogGroup group, double y) + { + _children.Add(visual); + + var container = new GroupContainer() + { + Visual = visual, + Group = group, + PositionY = y, + }; + + _groupItems.Add(container); + + return container; + } + + private void OnCatalogChanged() + { + _children.Clear(); + _catalogItems.Clear(); + _groupItems.Clear(); + + double position_y = 0; + double position_x = 0; + + if (Groups != null) + { + foreach (var group in Groups) + { + position_x = 0; + + var groupContainer = AddGroupItem(CreateGroup(group.Name, position_y), group, position_y); + + position_y += ellipseMargin; + + foreach (var item in group.Items) + { + double x = position_x + ellipseMargin; + + if (x + ellipseWidth > ActualWidth) + { + position_x = 0; + position_y += (ellipseHeight + ellipseMargin + textMargin + textHeight); + } + + var itemContainer = AddCatalogItem(CreateItem(item, position_x + ellipseMargin, position_y + ellipseMargin), item, position_y + ellipseMargin); + groupContainer.Items.Add(itemContainer); + + position_x += ellipseWidth + ellipseMargin; + } + + position_y += (ellipseHeight + ellipseMargin + textMargin + textHeight + groupMargin); + } + + Height = position_y; + } + + //InvalidateVisual(); + } + + private DrawingVisual CreateItem(CatalogItem item, double x, double y) + { + DrawingVisual drawingVisual = new DrawingVisual(); + DrawingContext drawingContext = drawingVisual.RenderOpen(); + + drawingContext.DrawEllipse(item.Brush, null, new Point(x + ellipseWidth / 2, y + ellipseHeight / 2), ellipseWidth / 2, ellipseHeight / 2); + + var formattedText = new FormattedText(item.Name, + CultureInfo.GetCultureInfo("en-us"), + FlowDirection.LeftToRight, + new Typeface("Flexo"), + 16, + Foreground); + + formattedText.MaxTextWidth = ellipseWidth + ellipseMargin; + + drawingContext.DrawText(formattedText, new Point((x + (ellipseWidth / 2)) - (formattedText.Width / 2), y + ellipseHeight + textMargin)); + + var center = new Point(x + ellipseWidth / 2, (y + ellipseHeight / 2) + textHeight + textMargin); + + drawingVisual.Transform = new ScaleTransform(1, 1, center.X, center.Y); + + drawingContext.Close(); + + return drawingVisual; + } + + private void Clear() + { + DrawingVisual drawingVisual = new DrawingVisual(); + DrawingContext drawingContext = drawingVisual.RenderOpen(); + + drawingContext.DrawRectangle(Background, null, new Rect(0, 0, ActualWidth, ActualHeight)); + + drawingContext.Close(); + + _children.Add(drawingVisual); + } + + private DrawingVisual CreateGroup(String name, double y) + { + DrawingVisual drawingVisual = new DrawingVisual(); + DrawingContext drawingContext = drawingVisual.RenderOpen(); + + var formattedText = new FormattedText(name, + CultureInfo.GetCultureInfo("en-us"), + FlowDirection.LeftToRight, + new Typeface("Flexo"), + 25, + Foreground); + + //formattedText.SetFontWeight(FontWeights.SemiBold); + + drawingContext.DrawText(formattedText, new Point((ActualWidth / 2) - (formattedText.Width / 2), y)); + + drawingContext.Close(); + + return drawingVisual; + } + + // Provide a required override for the VisualChildrenCount property. + protected override int VisualChildrenCount => _children != null ? _children.Count : 0; + + // Provide a required override for the GetVisualChild method. + protected override Visual GetVisualChild(int index) + { + if (index < 0 || index >= _children.Count) + { + throw new ArgumentOutOfRangeException(); + } + + return _children[index]; + } + } +} |
