using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Tango.FSE.MachineConfiguration.Views
{
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Tango.Core.Helpers;
using Tango.SharedUI.Shapes;
namespace Tango.SharedUI.Controls
{
/// <summary>
/// Interaction logic for HiveControl.xaml
/// </summary>
public partial class HiveControl : UserControl
{
public event EventHandler<HexagonControl> HexagonSelected;
public event EventHandler HiveGenerated;
public ObservableCollection<HexagonControl> Hexagons
{
get { return (ObservableCollection<HexagonControl>)GetValue(HexagonsProperty); }
set { SetValue(HexagonsProperty, value); }
}
public static readonly DependencyProperty HexagonsProperty =
DependencyProperty.Register("Hexagons", typeof(ObservableCollection<HexagonControl>), typeof(HiveControl), new PropertyMetadata(null));
public ObservableCollection<HexagonControl> SelectedHexagons
{
get { return (ObservableCollection<HexagonControl>)GetValue(SelectedHexagonsProperty); }
set { SetValue(SelectedHexagonsProperty, value); }
}
public static readonly DependencyProperty SelectedHexagonsProperty =
DependencyProperty.Register("SelectedHexagons", typeof(ObservableCollection<HexagonControl>), typeof(HiveControl), new PropertyMetadata(null));
public int MaxSelections
{
get { return (int)GetValue(MaxSelectionsProperty); }
set { SetValue(MaxSelectionsProperty, value); }
}
public static readonly DependencyProperty MaxSelectionsProperty =
DependencyProperty.Register("MaxSelections", typeof(int), typeof(HiveControl), new PropertyMetadata(3));
public bool DisplayGridPosition
{
get { return (bool)GetValue(DisplayGridPositionProperty); }
set { SetValue(DisplayGridPositionProperty, value); }
}
public static readonly DependencyProperty DisplayGridPositionProperty =
DependencyProperty.Register("DisplayGridPosition", typeof(bool), typeof(HiveControl), new PropertyMetadata(false));
public HexagonControl CenterHexagon
{
get { return (HexagonControl)GetValue(CenterHexagonProperty); }
set { SetValue(CenterHexagonProperty, value); }
}
public static readonly DependencyProperty CenterHexagonProperty =
DependencyProperty.Register("CenterHexagon", typeof(HexagonControl), typeof(HiveControl), new PropertyMetadata(null));
public int HiveWidth
{
get { return (int)GetValue(HiveWidthProperty); }
set { SetValue(HiveWidthProperty, value); }
}
public static readonly DependencyProperty HiveWidthProperty =
DependencyProperty.Register("HiveWidth", typeof(int), typeof(HiveControl), new PropertyMetadata(5));
public int HiveHeight
{
get { return (int)GetValue(HiveHeightProperty); }
set { SetValue(HiveHeightProperty, value); }
}
public static readonly DependencyProperty HiveHeightProperty =
DependencyProperty.Register("HiveHeight", typeof(int), typeof(HiveControl), new PropertyMetadata(5));
public HiveControl()
{
Hexagons = new ObservableCollection<HexagonControl>();
SelectedHexagons = new ObservableCollection<HexagonControl>();
InitializeComponent();
HiveHeight = 5;
HiveWidth = 5;
this.Loaded += HiveControl_Loaded;
}
private void HiveControl_Loaded(object sender, RoutedEventArgs e)
{
GenerateHive();
HiveGenerated?.Invoke(this,new EventArgs());
}
private void GenerateHive()
{
Hexagons.Clear();
SelectedHexagons.Clear();
canvas.Children.Clear();
double width = ActualWidth;
double height = ActualHeight;
double hexHeight = height / (double)HiveHeight;
int gap = (int)((Math.Round(HiveHeight / 2d, MidpointRounding.AwayFromZero)) / 2d);
for (int column = 0; column < HiveWidth / 2; column++)
{
for (int row = gap; row < HiveHeight - (gap % 2 != 0 ? gap : gap + 1); row++)
{
AddHexagon(hexHeight, row, column);
}
gap--;
}
int centerColumn = (int)Math.Round(HiveHeight / 2d, MidpointRounding.ToEven);
for (int row = 0; row < HiveHeight; row++)
{
AddHexagon(hexHeight, row, centerColumn);
}
gap = 0;
for (int column = centerColumn + 1; column < HiveWidth; column++)
{
for (int row = gap; row < HiveHeight - (gap % 2 != 0 ? gap : gap + 1); row++)
{
AddHexagon(hexHeight, row, column);
}
gap++;
}
Width = Hexagons.Max(x => x.Points.Max(y => y.X));
CenterHexagon = GetHexagon((int)Math.Round(HiveWidth / 2d, MidpointRounding.ToEven), (int)Math.Round(HiveHeight / 2d, MidpointRounding.ToEven));
}
private void AddHexagon(double hexHeight, int row, int col)
{
Point[] points = HexToPoints(hexHeight, row, col);
HexagonControl hexagon = new HexagonControl(points, row, col);
hexagon.HorizontalAlignment = HorizontalAlignment.Center;
hexagon.VerticalAlignment = VerticalAlignment.Center;
hexagon.Stroke = Brushes.Black;
hexagon.StrokeThickness = 1;
hexagon.Fill = new SolidColorBrush(ColorHelper.GetRandomGrayscaleColor());
canvas.Children.Add(hexagon);
Hexagons.Add(hexagon);
hexagon.Bind(HexagonControl.DisplayGridPositionProperty, this, DisplayGridPositionProperty, BindingMode.OneWay);
hexagon.MouseEnter += Hexagon_MouseEnter;
hexagon.MouseUp += Hexagon_MouseUp;
}
private void Hexagon_MouseUp(object sender, MouseButtonEventArgs e)
{
HexagonControl hexagon = sender as HexagonControl;
ToggleHexagonSelection(hexagon);
}
public void SelectHexagon(HexagonControl hexagon)
{
SelectedHexagons.Clear();
SelectedHexagons.Add(hexagon);
Hexagons.ToList().ForEach(x => x.IsSelected = false);
hexagon.IsSelected = true;
HexagonSelected?.Invoke(this, hexagon);
}
private void ToggleHexagonSelection(HexagonControl hexagon)
{
bool selected = !hexagon.IsSelected;
if (MaxSelections > Hexagons.Where(x => x.IsSelected).Count())
{
hexagon.IsSelected = selected;
}
else
{
if (selected)
{
SelectedHexagons.First().IsSelected = false;
SelectedHexagons.Remove(SelectedHexagons.First());
hexagon.IsSelected = true;
}
else
{
hexagon.IsSelected = false;
}
}
if (selected)
{
SelectedHexagons.Add(hexagon);
HexagonSelected?.Invoke(this, hexagon);
}
else
{
SelectedHexagons.Remove(hexagon);
}
}
private void Hexagon_MouseEnter(object sender, MouseEventArgs e)
{
Canvas.SetZIndex(sender as FrameworkElement, canvas.Children.OfType<HexagonControl>().Where(x => !x.IsSelected).Max(x => Canvas.GetZIndex(x)) + 1);
foreach (var item in canvas.Children.OfType<HexagonControl>().Where(x => x.IsSelected))
{
Canvas.SetZIndex(item, canvas.Children.OfType<HexagonControl>().Max(x => Canvas.GetZIndex(x)) + 1);
}
}
private Point[] HexToPoints(double height, float row, float col)
{
// Start with the leftmost corner of the upper left hexagon.
double width = HexWidth(height);
double y = height / 2;
double x = 0;
// Move down the required number of rows.
y += row * height;
// If the column is odd, move down half a hex more.
if (col % 2 == 1) y += height / 2;
// Move over for the column number.
x += col * (width * 0.75f);
// Generate the points.
return new Point[]
{
new Point(x, y),
new Point(x + width * 0.25f, y - height / 2),
new Point(x + width * 0.75f, y - height / 2),
new Point(x + width, y),
new Point(x + width * 0.75f, y + height / 2),
new Point(x + width * 0.25f, y + height / 2),
};
}
private double HexWidth(double height)
{
return (double)(4 * (height / 2 / Math.Sqrt(3)));
}
public HexagonControl GetHexagon(int row, int column)
{
return Hexagons.Where(x => x.Row == row && x.Column == column).FirstOrDefault();
}
}
}