123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Media;
- using InABox.Core;
- using Button = System.Windows.Controls.Button;
- using Color = System.Windows.Media.Color;
- using ComboBox = System.Windows.Controls.ComboBox;
- using HorizontalAlignment = System.Windows.HorizontalAlignment;
- using Label = System.Windows.Controls.Label;
- using SystemColors = System.Windows.SystemColors;
- using TextBox = System.Windows.Controls.TextBox;
- using UserControl = System.Windows.Controls.UserControl;
- namespace InABox.WPF
- {
- public class QAGrid : UserControl
- {
- public delegate void QAFormChangedEvent(object sender, Dictionary<Guid, object> values);
- private readonly Dictionary<QAQuestion, Border> borders = new();
- private readonly Grid MasterGrid;
- public QAGrid()
- {
- BorderBrush = new SolidColorBrush(Colors.Gray);
- BorderThickness = new Thickness(0.75);
- MasterGrid = new Grid();
- MasterGrid.Background = new SolidColorBrush(Colors.WhiteSmoke);
- MasterGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.25F, GridUnitType.Star) });
- MasterGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.25F, GridUnitType.Star) });
- MasterGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1.0F, GridUnitType.Auto) });
- MasterGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1.0F, GridUnitType.Star) });
- MasterGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1.0F, GridUnitType.Auto) });
- Content = MasterGrid;
- }
- public bool Preview { get; set; }
- public QAFormChangedEvent OnChanged { get; set; }
- private object GetValue(Dictionary<Guid, object> values, Guid guid)
- {
- if (values.ContainsKey(guid))
- return values[guid];
- return "";
- }
- private Border CreateHeader(string title)
- {
- var label = new Label
- {
- Content = title,
- FontSize = 16.0F,
- HorizontalAlignment = HorizontalAlignment.Center,
- VerticalAlignment = VerticalAlignment.Center
- };
- var border = new Border
- {
- CornerRadius = new CornerRadius(10.0F, 10.0F, 0.0F, 0.0F),
- BorderThickness = new Thickness(1.0F),
- BorderBrush = SystemColors.WindowFrameBrush,
- Background = SystemColors.WindowBrush,
- Margin = new Thickness(5.0F, 5.0F, 5.0F, 2.0F),
- Padding = new Thickness(5.0F)
- };
- border.SetValue(Grid.ColumnProperty, MasterGrid.ColumnDefinitions.Count - 1);
- border.SetValue(Grid.RowProperty, 0);
- border.Child = label;
- MasterGrid.Children.Add(border);
- return border;
- }
- private Thickness GetMargin(Grid grid)
- {
- if (grid.RowDefinitions.Count == 0)
- return new Thickness(2.0F, 0.0F, 2.0F, 0.0F);
- return new Thickness(4.0F, 3.0F, 4.0F, 3.0F);
- }
- public static Color InterpolateColors(Color color1, Color color2, float percentage)
- {
- double a1 = color1.A / 255.0, r1 = color1.R / 255.0, g1 = color1.G / 255.0, b1 = color1.B / 255.0;
- double a2 = color2.A / 255.0, r2 = color2.R / 255.0, g2 = color2.G / 255.0, b2 = color2.B / 255.0;
- var a3 = Convert.ToByte((a1 + (a2 - a1) * percentage) * 255);
- var r3 = Convert.ToByte((r1 + (r2 - r1) * percentage) * 255);
- var g3 = Convert.ToByte((g1 + (g2 - g1) * percentage) * 255);
- var b3 = Convert.ToByte((b1 + (b2 - b1) * percentage) * 255);
- return Color.FromArgb(a3, r3, g3, b3);
- }
- private Color GetBorder(QAQuestion question, Dictionary<Guid, object> answers)
- {
- var parameters = question.ParseParameters();
- var bAnswerRequired = question.Answer != QAAnswer.Comment &&
- (!parameters.ContainsKey("Default") || string.IsNullOrWhiteSpace(parameters["Default"]));
- if (bAnswerRequired && (!answers.ContainsKey(question.ID) || answers[question.ID] == null))
- return Colors.Red;
- return Colors.Transparent;
- }
- public void CollapseMargins()
- {
- MasterGrid.ColumnDefinitions.First().Width = new GridLength(0.0F);
- MasterGrid.ColumnDefinitions.Last().Width = new GridLength(0.0F);
- }
- private void Changed(Dictionary<Guid, object> values)
- {
- OnChanged?.Invoke(this, values);
- foreach (var question in borders.Keys)
- {
- var color = GetBorder(question, values);
- borders[question].BorderBrush = new SolidColorBrush(color);
- borders[question].Background = new SolidColorBrush(InterpolateColors(color, Colors.Transparent, 0.8F));
- }
- }
- private Border CreateBorder(Grid grid, QAQuestion check, Dictionary<Guid, object> values)
- {
- var border = new Border();
- border.SetValue(Grid.ColumnProperty, 0);
- border.SetValue(Grid.RowProperty, grid.RowDefinitions.Count);
- border.Padding = new Thickness(2.0F);
- var color = GetBorder(check, values);
- border.BorderBrush = new SolidColorBrush(color);
- border.Background = new SolidColorBrush(InterpolateColors(color, Colors.Transparent, 0.8F));
- border.BorderThickness = new Thickness(1.5F);
- border.Margin = new Thickness(0F, 2F, 0F, 2F);
- border.CornerRadius = new CornerRadius(5.0F);
- grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1.0F, GridUnitType.Auto) });
- grid.Children.Add(border);
- return border;
- }
- private Border CreateCommentPanel(Grid grid, QAQuestion check, Dictionary<Guid, object> values, int number)
- {
- var border = CreateBorder(grid, check, values);
- var row = new Grid();
- row.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1.0F, GridUnitType.Star) });
- row.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1.0F, GridUnitType.Star) });
- var label = new TextBlock
- {
- Text = check.Question,
- FontSize = 14.0F,
- TextAlignment = TextAlignment.Center,
- TextWrapping = TextWrapping.Wrap,
- VerticalAlignment = VerticalAlignment.Center,
- Margin = GetMargin(grid),
- Padding = new Thickness(10)
- };
- label.SetValue(Grid.RowProperty, 0);
- label.SetValue(Grid.ColumnProperty, 0);
- row.Children.Add(label);
- border.Child = row;
- return border;
- }
- private Border CreateChoicePanel(Grid grid, QAQuestion check, Dictionary<Guid, object> values, int number)
- {
- var border = CreateBorder(grid, check, values);
- var row = new Grid();
- row.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1.0F, GridUnitType.Auto) });
- row.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1.0F, GridUnitType.Star) });
- var label = new TextBlock
- {
- Text = string.Format("{0}. {1}", number, check.Question),
- FontSize = 14.0F,
- Margin = GetMargin(grid),
- VerticalAlignment = VerticalAlignment.Center,
- TextAlignment = TextAlignment.Left,
- TextWrapping = TextWrapping.Wrap
- };
- label.SetValue(Grid.RowProperty, 0);
- label.SetValue(Grid.ColumnProperty, 0);
- row.Children.Add(label);
- if (!string.IsNullOrEmpty(check.Parameters))
- {
- var parameters = check.ParseParameters();
- var buttons = parameters["Options"].Split(',');
- var colors = parameters["Colors"].Split(',');
- var value = GetValue(values, check.ID).ToString();
- if (string.IsNullOrWhiteSpace(value))
- value = parameters["Default"];
- for (var i = 0; i < buttons.Length; i++)
- if (!string.IsNullOrWhiteSpace(buttons[i]))
- {
- var brush = new SolidColorBrush(Colors.WhiteSmoke);
- try
- {
- brush = new BrushConverter().ConvertFromString(colors[i]) as SolidColorBrush;
- }
- catch (Exception e)
- {
- Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
- }
- row.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(80.0F) });
- var button = new Button
- {
- Content = buttons[i],
- FontSize = 14.0F,
- Margin = GetMargin(grid),
- Height = 40,
- Background = buttons[i].Equals(value) ? brush : new SolidColorBrush(Colors.WhiteSmoke),
- Tag = brush
- };
- button.Click += (o, e) =>
- {
- values[check.ID] = button.Content.ToString();
- foreach (var other in row.Children)
- if (other is Button)
- {
- if (other == button)
- ((Button)other).Background = (SolidColorBrush)button.Tag;
- else
- ((Button)other).Background = new SolidColorBrush(Colors.WhiteSmoke);
- }
- Changed(values);
- };
- button.SetValue(Grid.RowProperty, 0);
- button.SetValue(Grid.ColumnProperty, i + 1);
- row.Children.Add(button);
- }
- }
- border.Child = row;
- return border;
- }
- private Border CreateNumberPanel(Grid grid, QAQuestion check, Dictionary<Guid, object> values, int number)
- {
- var border = CreateBorder(grid, check, values);
- var row = new Grid();
- row.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1.0F, GridUnitType.Star) });
- row.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1.0F, GridUnitType.Star) });
- var label = new TextBlock
- {
- Text = string.Format("{0}. {1}", number, check.Question),
- FontSize = 14.0F,
- Margin = GetMargin(grid),
- VerticalAlignment = VerticalAlignment.Center,
- TextAlignment = TextAlignment.Left,
- TextWrapping = TextWrapping.Wrap
- };
- label.SetValue(Grid.RowProperty, 0);
- label.SetValue(Grid.ColumnProperty, 0);
- row.Children.Add(label);
- row.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(160.0F) });
- var editor = new TextBox
- {
- Margin = GetMargin(grid),
- TextAlignment = TextAlignment.Center,
- VerticalContentAlignment = VerticalAlignment.Center,
- Height = 40,
- FontSize = 14.0F
- };
- editor.SetValue(Grid.RowProperty, 0);
- editor.SetValue(Grid.ColumnProperty, 1);
- row.Children.Add(editor);
- var def = "";
- if (!string.IsNullOrEmpty(check.Parameters))
- {
- var parameters = check.ParseParameters();
- def = parameters["Default"];
- }
- var value = GetValue(values, check.ID).ToString();
- editor.Text = string.IsNullOrWhiteSpace(value) ? def : value;
- editor.TextChanged += (o, e) =>
- {
- values[check.ID] = editor.Text;
- Changed(values);
- };
- border.Child = row;
- return border;
- }
- private Border CreateTextPanel(Grid grid, QAQuestion check, Dictionary<Guid, object> values, int number)
- {
- var border = CreateBorder(grid, check, values);
- var row = new Grid();
- row.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1.0F, GridUnitType.Star) });
- row.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1.0F, GridUnitType.Star) });
- var label = new TextBlock
- {
- Text = string.Format("{0}. {1}", number, check.Question),
- FontSize = 14.0F,
- Margin = GetMargin(grid),
- VerticalAlignment = VerticalAlignment.Center,
- TextAlignment = TextAlignment.Left,
- TextWrapping = TextWrapping.Wrap
- };
- label.SetValue(Grid.RowProperty, 0);
- label.SetValue(Grid.ColumnProperty, 0);
- row.Children.Add(label);
- row.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(320.0F, GridUnitType.Pixel) });
- var editor = new TextBox
- {
- Margin = GetMargin(grid),
- TextAlignment = TextAlignment.Center,
- VerticalContentAlignment = VerticalAlignment.Center,
- Height = 40,
- FontSize = 14.0F
- };
- editor.SetValue(Grid.RowProperty, 0);
- editor.SetValue(Grid.ColumnProperty, 1);
- row.Children.Add(editor);
- var def = "";
- if (!string.IsNullOrEmpty(check.Parameters))
- {
- var parameters = check.ParseParameters();
- def = parameters["Default"];
- }
- var value = GetValue(values, check.ID).ToString();
- editor.Text = string.IsNullOrWhiteSpace(value) ? def : value;
- editor.TextChanged += (o, e) =>
- {
- values[check.ID] = editor.Text;
- Changed(values);
- };
- border.Child = row;
- return border;
- }
- private Border CreateComboPanel(Grid grid, QAQuestion check, Dictionary<Guid, object> values, int number)
- {
- var border = CreateBorder(grid, check, values);
- var row = new Grid();
- row.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1.0F, GridUnitType.Star) });
- row.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1.0F, GridUnitType.Star) });
- var label = new TextBlock
- {
- Text = string.Format("{0}. {1}", number, check.Question),
- FontSize = 14.0F,
- Margin = GetMargin(grid),
- VerticalAlignment = VerticalAlignment.Center,
- TextAlignment = TextAlignment.Left,
- TextWrapping = TextWrapping.Wrap
- };
- label.SetValue(Grid.RowProperty, 0);
- label.SetValue(Grid.ColumnProperty, 0);
- row.Children.Add(label);
- row.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(320.0F, GridUnitType.Pixel) });
- var editor = new ComboBox
- {
- Margin = GetMargin(grid),
- HorizontalContentAlignment = HorizontalAlignment.Left,
- VerticalContentAlignment = VerticalAlignment.Center,
- Height = 40
- };
- editor.SetValue(Grid.RowProperty, 0);
- editor.SetValue(Grid.ColumnProperty, 1);
- row.Children.Add(editor);
- if (!string.IsNullOrEmpty(check.Parameters))
- {
- var parameters = check.ParseParameters();
- var options = parameters["Options"].Split(',');
- var def = parameters["Default"];
- for (var i = 0; i < options.Length; i++)
- editor.Items.Add(options[i]);
- var value = GetValue(values, check.ID).ToString();
- editor.SelectedIndex = editor.Items.IndexOf(string.IsNullOrWhiteSpace(value) ? def : value);
- }
- editor.SelectionChanged += (o, e) =>
- {
- values[check.ID] = editor.SelectedIndex >= 0 ? editor.Items[editor.SelectedIndex].ToString() : "";
- Changed(values);
- };
- border.Child = row;
- return border;
- }
- public void Clear()
- {
- borders.Clear();
- MasterGrid.Children.Clear();
- MasterGrid.ColumnDefinitions.Clear();
- MasterGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.25F, GridUnitType.Star) });
- MasterGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.25F, GridUnitType.Star) });
- }
- public void LoadChecks(string title, IEnumerable<QAQuestion> checks, Dictionary<Guid, object> values)
- {
- var sections = new List<string>();
- foreach (var check in checks)
- {
- var section = string.IsNullOrWhiteSpace(check.Section) ? title : check.Section;
- if (!sections.Contains(section))
- sections.Add(section);
- }
- if (!sections.Any())
- sections.Add(title);
- foreach (var section in sections)
- {
- var header = CreateHeader(section);
- var border = new Border
- {
- CornerRadius = new CornerRadius(0.0F, 0.0F, 0.0F, 0.0F),
- BorderThickness = new Thickness(1.0F),
- BorderBrush = SystemColors.WindowFrameBrush,
- Background = SystemColors.WindowBrush,
- Margin = new Thickness(5.0F, 0.0F, 5.0F, 5.0F),
- Padding = new Thickness(10.0F, 10.0F, 5.0F, 10.0F)
- };
- border.SetValue(Grid.RowProperty, 1);
- border.SetValue(Grid.ColumnProperty, MasterGrid.ColumnDefinitions.Count - 1);
- if (MasterGrid.ColumnDefinitions.Count > 2)
- {
- header.Margin = new Thickness(0.0F, 5.0F, 5.0F, 2.0F);
- border.Margin = new Thickness(0.0F, 0.0F, 5.0F, 5.0F);
- CollapseMargins();
- }
- MasterGrid.ColumnDefinitions.Insert(MasterGrid.ColumnDefinitions.Count - 1,
- new ColumnDefinition { Width = new GridLength(1F, GridUnitType.Star) });
- MasterGrid.Children.Add(border);
- var scroll = new ScrollViewer
- {
- VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
- HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled,
- Padding = new Thickness(0.0F, 0.0F, 5.0F, 0.0F)
- };
- border.Child = scroll;
- var grid = new Grid();
- var i = 1;
- if (!checks.Any())
- {
- var check = new QAQuestion
- {
- Answer = QAAnswer.Comment,
- Question = "There are no checks defined for this form",
- Parameters = ""
- };
- borders[check] = CreateCommentPanel(grid, check, values, i);
- }
- else
- {
- foreach (var check in checks)
- {
- Border element = null;
- if (check.Answer == QAAnswer.Comment)
- element = CreateCommentPanel(grid, check, values, i);
- else if (check.Answer == QAAnswer.Choice)
- element = CreateChoicePanel(grid, check, values, i++);
- else if (check.Answer == QAAnswer.Number)
- element = CreateNumberPanel(grid, check, values, i++);
- else if (check.Answer == QAAnswer.Text)
- element = CreateTextPanel(grid, check, values, i++);
- else if (check.Answer == QAAnswer.Combo)
- element = CreateComboPanel(grid, check, values, i++);
- if (element != null)
- borders[check] = element;
- }
- }
- scroll.Content = grid;
- }
- }
- }
- }
|