Exemplo n.º 1
0
        private static void AddColorHexagon(int i, Palette palette, Canvas container, PaletteSelector owner, List <PaletteColorInfo> infos, Func <Color, Color> colourBlindnessFunction)
        {
            AnimatableTransform transform = new AnimatableTransform(new Matrix(1, 0, 0, 1, 0, 0));

            PaletteColorInfo info = new PaletteColorInfo()
            {
                Index = i, OriginalIndex = i, Transform = transform
            };

            infos.Insert(i, info);

            double centerX = (1.5 + 2.5 * i) * HexagonRadius + 6.93;
            double centerY = HexagonRadius * Math.Cos(Math.PI / 6) * (i % 2 == 0 ? 1 : 2);

            PathGeometry leftHexagon   = GetHexagonPath(new Point(centerX - 0.5 * HexagonRadius, centerY), HexagonRadius);
            PathGeometry centerHexagon = GetHexagonPath(new Point(centerX, centerY), HexagonRadius);
            PathGeometry rightHexagon  = GetHexagonPath(new Point(centerX + 0.5 * HexagonRadius, centerY), HexagonRadius);


            Color color        = palette.Colors[i % palette.Colors.Count];
            Color lighterColor = ColorPicker.GetLighterColor(color);
            Color darkerColor  = ColorPicker.GetDarkerColor(color);


            Avalonia.Controls.Shapes.Path leftPath = new Avalonia.Controls.Shapes.Path()
            {
                Data = leftHexagon, Fill = new ColorVisualBrush(colourBlindnessFunction(lighterColor)), Cursor = new Avalonia.Input.Cursor(Avalonia.Input.StandardCursorType.Hand)
            };
            Avalonia.Controls.Shapes.Path rightPath = new Avalonia.Controls.Shapes.Path()
            {
                Data = rightHexagon, Fill = new ColorVisualBrush(colourBlindnessFunction(darkerColor)), Cursor = new Avalonia.Input.Cursor(Avalonia.Input.StandardCursorType.Hand)
            };
            Avalonia.Controls.Shapes.Path centerPath = new Avalonia.Controls.Shapes.Path()
            {
                Data = centerHexagon, Fill = new ColorVisualBrush(colourBlindnessFunction(color)), Cursor = new Avalonia.Input.Cursor(Avalonia.Input.StandardCursorType.Hand)
            };

            if (!ColorPicker.TransitionsDisabled)
            {
                leftPath.Transitions = new Transitions
                {
                    new ThicknessTransition()
                    {
                        Property = Avalonia.Controls.Shapes.Path.MarginProperty, Duration = new TimeSpan(0, 0, 0, 0, 100)
                    }
                };

                rightPath.Transitions = new Transitions
                {
                    new ThicknessTransition()
                    {
                        Property = Avalonia.Controls.Shapes.Path.MarginProperty, Duration = new TimeSpan(0, 0, 0, 0, 100)
                    }
                };
            }

            leftPath.Classes.Add("HexagonLeftPalette");
            rightPath.Classes.Add("HexagonRightPalette");
            centerPath.Classes.Add("HexagonCenter");

            rightPath.PointerEnter += (s, e) =>
            {
                rightPath.ZIndex  = 10;
                centerPath.ZIndex = 10;
            };

            rightPath.PointerLeave += async(s, e) =>
            {
                await Task.Delay(100);

                rightPath.ZIndex  = 0;
                centerPath.ZIndex = 0;
            };

            leftPath.PointerPressed += (s, e) =>
            {
                owner.ColorSelected?.Invoke(owner, new ColorSelectedEventArgs(lighterColor));
            };

            rightPath.PointerPressed += (s, e) =>
            {
                owner.ColorSelected?.Invoke(owner, new ColorSelectedEventArgs(darkerColor));
            };

            centerPath.PointerPressed += (s, e) =>
            {
                owner.ColorSelected?.Invoke(owner, new ColorSelectedEventArgs(color));
            };

            Point p1, p2, p3, p4;

            if (i % 2 == 0)
            {
                p1 = new Point(centerX + HexagonRadius * Math.Cos(Math.PI * 2 / 3) - HexagonRadius * 0.5, centerY + HexagonRadius * Math.Sin(Math.PI * 2 / 3));
                p2 = new Point(centerX + HexagonRadius * Math.Cos(Math.PI * 1 / 3) + HexagonRadius * 0.5, centerY + HexagonRadius * Math.Sin(Math.PI * 1 / 3));
                p3 = p2 + new Point(-Math.Cos(Math.PI / 3), Math.Sin(Math.PI / 3)) * HexagonRadius * 0.6;
                p4 = p1 + new Point(Math.Cos(Math.PI / 3), Math.Sin(Math.PI / 3)) * HexagonRadius * 0.6;
            }
            else
            {
                p1 = new Point(centerX + HexagonRadius * Math.Cos(Math.PI * 4 / 3) - HexagonRadius * 0.5, centerY + HexagonRadius * Math.Sin(Math.PI * 4 / 3));
                p2 = new Point(centerX + HexagonRadius * Math.Cos(Math.PI * 5 / 3) + HexagonRadius * 0.5, centerY + HexagonRadius * Math.Sin(Math.PI * 5 / 3));
                p3 = p2 + new Point(-Math.Cos(Math.PI / 3), -Math.Sin(Math.PI / 3)) * HexagonRadius * 0.6;
                p4 = p1 + new Point(Math.Cos(Math.PI / 3), -Math.Sin(Math.PI / 3)) * HexagonRadius * 0.6;
            }


            AnimatablePath4Points deleteBG = new AnimatablePath4Points(p1, p2, p2, p1);

            AnimatableColorBrush bgFill = new AnimatableColorBrush(Color.FromRgb(180, 180, 180), col => deleteBG.Path.Fill = new SolidColorBrush(col));

            deleteBG.Path.Cursor = new Avalonia.Input.Cursor(Avalonia.Input.StandardCursorType.Hand);

            PathGeometry deleteGeometry = new PathGeometry();
            PathFigure   seg1           = new PathFigure()
            {
                StartPoint = new Point(centerX - HexagonRadius * 0.15, centerY - HexagonRadius * 0.15), IsClosed = false
            };

            seg1.Segments.Add(new LineSegment()
            {
                Point = seg1.StartPoint + new Point(HexagonRadius * 0.3, HexagonRadius * 0.3)
            });
            PathFigure seg2 = new PathFigure()
            {
                StartPoint = new Point(centerX + HexagonRadius * 0.15, centerY - HexagonRadius * 0.15), IsClosed = false
            };

            seg2.Segments.Add(new LineSegment()
            {
                Point = seg2.StartPoint + new Point(-HexagonRadius * 0.3, HexagonRadius * 0.3)
            });
            deleteGeometry.Figures.Add(seg1);
            deleteGeometry.Figures.Add(seg2);

            RelativePoint renderTransformOrigin = new RelativePoint(centerX, centerY, RelativeUnit.Absolute);


            leftPath.RenderTransform            = transform.MatrixTransform;
            leftPath.RenderTransformOrigin      = renderTransformOrigin;
            rightPath.RenderTransform           = transform.MatrixTransform;
            rightPath.RenderTransformOrigin     = renderTransformOrigin;
            centerPath.RenderTransform          = transform.MatrixTransform;
            centerPath.RenderTransformOrigin    = renderTransformOrigin;
            deleteBG.Path.RenderTransform       = transform.MatrixTransform;
            deleteBG.Path.RenderTransformOrigin = renderTransformOrigin;
            AnimatableTransform fgTransform = new AnimatableTransform(new Matrix(1, 0, 0, 1, 0, (info.Index % 2 == 0 ? 1 : -1) * HexagonRadius * Math.Sin(Math.PI / 3) * 0.7));

            TransformGroup fgTransforms = new TransformGroup();

            fgTransforms.Children.Add(transform.MatrixTransform);
            fgTransforms.Children.Add(fgTransform.MatrixTransform);

            Avalonia.Controls.Shapes.Path deleteFG = new Avalonia.Controls.Shapes.Path()
            {
                Data = deleteGeometry, StrokeThickness = HexagonRadius * 0.1, IsHitTestVisible = false, RenderTransform = fgTransforms, RenderTransformOrigin = renderTransformOrigin
            };

            info.DeleteBGPath      = deleteBG;
            info.DeleteFBTransform = fgTransform;

            AnimatableColorBrush fgStroke = new AnimatableColorBrush(Color.FromRgb(255, 255, 255), col => deleteFG.Stroke = new SolidColorBrush(col));

            deleteBG.Path.PointerEnter += (s, e) =>
            {
                bgFill.Update(Color.FromRgb(240, 240, 240), false);
                fgStroke.Update(Color.FromRgb(128, 128, 128), false);
            };

            deleteBG.Path.PointerLeave += (s, e) =>
            {
                bgFill.Update(Color.FromRgb(180, 180, 180), false);
                fgStroke.Update(Colors.White, false);
            };

            container.Children.Add(deleteBG.Path);
            container.Children.Add(deleteFG);

            bool deleteVisible = false;

            centerPath.PointerEnter += async(s, e) =>
            {
                if (!deleteVisible)
                {
                    double _centerX = (1.5 + 2.5 * info.OriginalIndex) * HexagonRadius + 6.93;
                    double _centerY = HexagonRadius * Math.Cos(Math.PI / 6) * (info.OriginalIndex % 2 == 0 ? 1 : 2);

                    Point _p1, _p2, _p3, _p4;

                    if (info.Index % 2 == 0)
                    {
                        _p1 = new Point(_centerX + HexagonRadius * Math.Cos(Math.PI * 2 / 3) - HexagonRadius * 0.5, _centerY + HexagonRadius * Math.Sin(Math.PI * 2 / 3));
                        _p2 = new Point(_centerX + HexagonRadius * Math.Cos(Math.PI * 1 / 3) + HexagonRadius * 0.5, _centerY + HexagonRadius * Math.Sin(Math.PI * 1 / 3));
                        _p3 = _p2 + new Point(-Math.Cos(Math.PI / 3), Math.Sin(Math.PI / 3)) * HexagonRadius * 0.6;
                        _p4 = _p1 + new Point(Math.Cos(Math.PI / 3), Math.Sin(Math.PI / 3)) * HexagonRadius * 0.6;
                    }
                    else
                    {
                        _p1 = new Point(_centerX + HexagonRadius * Math.Cos(Math.PI * 4 / 3) - HexagonRadius * 0.5, _centerY + HexagonRadius * Math.Sin(Math.PI * 4 / 3));
                        _p2 = new Point(_centerX + HexagonRadius * Math.Cos(Math.PI * 5 / 3) + HexagonRadius * 0.5, _centerY + HexagonRadius * Math.Sin(Math.PI * 5 / 3));
                        _p3 = _p2 + new Point(-Math.Cos(Math.PI / 3), -Math.Sin(Math.PI / 3)) * HexagonRadius * 0.6;
                        _p4 = _p1 + new Point(Math.Cos(Math.PI / 3), -Math.Sin(Math.PI / 3)) * HexagonRadius * 0.6;
                    }

                    deleteVisible      = true;
                    deleteBG.Points    = new PointCollection4(_p1, _p2, _p3, _p4);
                    fgTransform.Matrix = new Matrix(1, 0, 0, 1, 0, (info.Index % 2 == 0 ? 1 : -1) * HexagonRadius * Math.Sin(Math.PI / 3) * 1.3);
                    await Task.Delay(100);

                    deleteBG.Path.ZIndex = 11;
                    deleteFG.ZIndex      = 11;
                    await Task.Delay(1000);

                    deleteBG.Path.ZIndex = 0;
                    deleteFG.ZIndex      = 0;
                    fgTransform.Matrix   = new Matrix(1, 0, 0, 1, 0, (info.Index % 2 == 0 ? 1 : -1) * HexagonRadius * Math.Sin(Math.PI / 3) * 0.7);
                    deleteBG.Points      = new PointCollection4(_p1, _p2, _p2, _p1);
                    deleteVisible        = false;
                }
            };

            container.Children.Add(leftPath);
            container.Children.Add(rightPath);
            container.Children.Add(centerPath);


            deleteBG.Path.PointerPressed += async(s, e) =>
            {
                transform.Matrix = new Matrix(0, 0, 0, 0, transform.Matrix.M31, transform.Matrix.M32);

                for (int j = info.Index + 1; j < infos.Count; j++)
                {
                    infos[j].Transform.Matrix = new Matrix(1, 0, 0, 1, infos[j].Transform.Matrix.M31 - HexagonRadius * 2.5, infos[j].Transform.Matrix.M32 + HexagonRadius * Math.Sin(Math.PI / 3) * (j % 2 == 0 ? 1 : -1));
                    infos[j].Index--;

                    if (infos[j].DeleteBGPath != null)
                    {
                        double _centerX = (1.5 + 2.5 * infos[j].OriginalIndex) * HexagonRadius + 6.93;
                        double _centerY = HexagonRadius * Math.Cos(Math.PI / 6) * (infos[j].OriginalIndex % 2 == 0 ? 1 : 2);

                        Point _p1, _p2;

                        if (infos[j].Index % 2 == 0)
                        {
                            _p1 = new Point(_centerX + HexagonRadius * Math.Cos(Math.PI * 2 / 3) - HexagonRadius * 0.5, _centerY + HexagonRadius * Math.Sin(Math.PI * 2 / 3));
                            _p2 = new Point(_centerX + HexagonRadius * Math.Cos(Math.PI * 1 / 3) + HexagonRadius * 0.5, _centerY + HexagonRadius * Math.Sin(Math.PI * 1 / 3));
                        }
                        else
                        {
                            _p1 = new Point(_centerX + HexagonRadius * Math.Cos(Math.PI * 4 / 3) - HexagonRadius * 0.5, _centerY + HexagonRadius * Math.Sin(Math.PI * 4 / 3));
                            _p2 = new Point(_centerX + HexagonRadius * Math.Cos(Math.PI * 5 / 3) + HexagonRadius * 0.5, _centerY + HexagonRadius * Math.Sin(Math.PI * 5 / 3));
                        }

                        infos[j].DeleteBGPath.Points      = new PointCollection4(_p1, _p2, _p2, _p1);
                        infos[j].DeleteFBTransform.Matrix = new Matrix(1, 0, 0, 1, 0, -infos[j].DeleteFBTransform.Matrix.M32);
                    }
                }

                await Task.Delay(100);

                container.Width -= HexagonRadius * 2.5;

                infos.RemoveAt(info.Index);
                palette.Colors.RemoveAt(info.Index);

                container.Children.Remove(leftPath);
                container.Children.Remove(rightPath);
                container.Children.Remove(centerPath);
                container.Children.Remove(deleteBG.Path);
                container.Children.Remove(deleteFG);
            };
        }
Exemplo n.º 2
0
        private Canvas BuildPaletteCanvas(Palette palette)
        {
            int n = palette.Colors.Count + 1;

            Canvas tbr = new Canvas()
            {
                Height = HexagonRadius * Math.Cos(Math.PI / 6) * 3, Width = HexagonRadius * (3 + 2.5 * (n - 1)) + 13.86, Margin = new Thickness(0, 0, 0, 5)
            };

            if (!ColorPicker.TransitionsDisabled)
            {
                tbr.Transitions = new Transitions
                {
                    new DoubleTransition()
                    {
                        Property = Canvas.WidthProperty, Duration = new TimeSpan(0, 0, 0, 0, 100)
                    }
                };
            }

            List <PaletteColorInfo> infos = new List <PaletteColorInfo>();

            for (int i = 0; i < n - 1; i++)
            {
                AddColorHexagon(i, palette, tbr, this, infos, this.ColourBlindnessFunction);
            }


            {
                int    i       = n - 1;
                double centerX = (1.5 + 2.5 * i) * HexagonRadius + 6.93;
                double centerY = HexagonRadius * Math.Cos(Math.PI / 6) * (i % 2 == 0 ? 1 : 2);

                PathGeometry leftHexagon   = GetHexagonPath(new Point(centerX - 0.5 * HexagonRadius, centerY), HexagonRadius);
                PathGeometry centerHexagon = GetHexagonPath(new Point(centerX, centerY), HexagonRadius);
                PathGeometry rightHexagon  = GetHexagonPath(new Point(centerX + 0.5 * HexagonRadius, centerY), HexagonRadius);

                Avalonia.Controls.Shapes.Path leftPath = new Avalonia.Controls.Shapes.Path()
                {
                    Data = leftHexagon, ZIndex = 2
                };
                Avalonia.Controls.Shapes.Path rightPath = new Avalonia.Controls.Shapes.Path()
                {
                    Data = rightHexagon, ZIndex = 2
                };
                Avalonia.Controls.Shapes.Path centerPath = new Avalonia.Controls.Shapes.Path()
                {
                    Data = centerHexagon, Cursor = new Avalonia.Input.Cursor(Avalonia.Input.StandardCursorType.Hand), ZIndex = 2
                };

                AnimatableColorBrush leftFill   = new AnimatableColorBrush(Color.FromRgb(240, 240, 240), col => leftPath.Fill = new SolidColorBrush(col));
                AnimatableColorBrush rightFill  = new AnimatableColorBrush(Color.FromRgb(240, 240, 240), col => rightPath.Fill = new SolidColorBrush(col));
                AnimatableColorBrush centerFill = new AnimatableColorBrush(Color.FromRgb(200, 200, 200), col => centerPath.Fill = new SolidColorBrush(col));

                tbr.Children.Add(leftPath);
                tbr.Children.Add(rightPath);
                tbr.Children.Add(centerPath);

                PathGeometry plusGeometry       = new PathGeometry();
                PathFigure   verticalPlusFigure = new PathFigure()
                {
                    StartPoint = new Point(centerX, centerY - HexagonRadius * 0.5), IsClosed = false
                };
                verticalPlusFigure.Segments.Add(new LineSegment()
                {
                    Point = new Point(centerX, centerY + HexagonRadius * 0.5)
                });
                PathFigure horizontalPlusFigure = new PathFigure()
                {
                    StartPoint = new Point(centerX - HexagonRadius * 0.5, centerY), IsClosed = false
                };
                horizontalPlusFigure.Segments.Add(new LineSegment()
                {
                    Point = new Point(centerX + HexagonRadius * 0.5, centerY)
                });
                plusGeometry.Figures.Add(verticalPlusFigure);
                plusGeometry.Figures.Add(horizontalPlusFigure);

                Avalonia.Controls.Shapes.Path plusPath = new Avalonia.Controls.Shapes.Path()
                {
                    Data = plusGeometry, StrokeThickness = HexagonRadius * 0.2, IsHitTestVisible = false, ZIndex = 2
                };
                AnimatableColorBrush plusStroke = new AnimatableColorBrush(Colors.White, col => plusPath.Stroke = new SolidColorBrush(col));

                tbr.Children.Add(plusPath);

                AnimatableTransform transform = new AnimatableTransform(new Matrix(1, 0, 0, 1, 0, 0));

                leftPath.RenderTransform   = transform.MatrixTransform;
                rightPath.RenderTransform  = transform.MatrixTransform;
                centerPath.RenderTransform = transform.MatrixTransform;
                plusPath.RenderTransform   = transform.MatrixTransform;

                bool disabled = false;

                centerPath.PointerEnter += (s, e) =>
                {
                    if (!disabled)
                    {
                        leftFill.Update(Color.FromRgb(180, 180, 180), false);
                        rightFill.Update(Color.FromRgb(180, 180, 180), false);
                        centerFill.Update(Color.FromRgb(240, 240, 240), false);
                        plusStroke.Update(Color.FromRgb(180, 180, 180), false);
                    }
                };
                centerPath.PointerLeave += (s, e) =>
                {
                    if (!disabled)
                    {
                        leftFill.Update(Color.FromRgb(240, 240, 240), false);
                        rightFill.Update(Color.FromRgb(240, 240, 240), false);
                        centerFill.Update(Color.FromRgb(200, 200, 200), false);
                        plusStroke.Update(Colors.White, false);
                    }
                };

                centerPath.PointerPressed += async(s, e) =>
                {
                    disabled = true;

                    Color col = this.Owner.Color;

                    leftFill.Update(ColorPicker.GetLighterColor(col), false);
                    rightFill.Update(ColorPicker.GetDarkerColor(col), false);
                    centerFill.Update(col, false);
                    plusStroke.Update(Color.FromArgb(0, 255, 255, 255), false);

                    await Task.Delay(100);

                    leftPath.ZIndex   = -1;
                    centerPath.ZIndex = -1;
                    rightPath.ZIndex  = -1;
                    plusPath.ZIndex   = -1;

                    palette.Colors.Add(col);
                    AddColorHexagon(palette.Colors.Count - 1, palette, tbr, this, infos, this.ColourBlindnessFunction);

                    leftFill.Update(Color.FromRgb(240, 240, 240), false);
                    rightFill.Update(Color.FromRgb(240, 240, 240), false);
                    centerFill.Update(Color.FromRgb(200, 200, 200), false);
                    plusStroke.Update(Colors.White, false);

                    tbr.Width += HexagonRadius * 2.5;
                    double deltaX = HexagonRadius * 2.5;
                    double deltaY = HexagonRadius * Math.Sin(Math.PI / 3) * (palette.Colors.Count % 2 == 0 ? -1 : 1);
                    transform.Matrix = new Matrix(1, 0, 0, 1, transform.Matrix.M31 + deltaX, transform.Matrix.M32 + deltaY);

                    await Task.Delay(100);

                    leftPath.ZIndex   = 2;
                    centerPath.ZIndex = 2;
                    rightPath.ZIndex  = 2;
                    plusPath.ZIndex   = 2;

                    disabled = false;
                };

                infos.Add(new PaletteColorInfo()
                {
                    Index = -1, Transform = transform
                });
            }


            return(tbr);
        }