using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using TradeIdeas.TIProData; using TradeIdeas.TIProGUI; // TODO: Read the initialValue. If possible use that to set the initial state of the window. namespace TIProDevExtension.ValueEditor { public partial class GradientEditor : Form { /// /// The value that the user selected / created. /// /// If the user hits cancel, this will be the same as the value we started from. /// /// If the user hits OK, and there is some problem, we return the exception. That /// works because the ValueSelector control knows how to display an exception. /// public object Result { get; private set; } public GradientEditor(object initialValue = null) { Result = initialValue; InitializeComponent(); _gradientColorChooser.GradientInfo = new GradientInfo(); // DPI issues? This different from what we've seen in other forms. // When we get here (symbolTextBox.Right == inputValueSelector.Right), // as it should be. But it doesn't look right. symbolTextBox.Width = inputValueSelector.Right - symbolTextBox.Left - 1; // Strange. In other forms it seems like this is called automatically in // InitializeComponent(). symbolTextBox_TextChanged(null, null); UpdateSampleColumns(); _gradientColorChooser.OnChange += delegate { UpdateSampleColumns(); }; } static readonly string PLACEHOLDER_NAME = "value"; static readonly DataNode.PlaceHolder PLACEHOLDER = new DataNode.PlaceHolder(PLACEHOLDER_NAME); private void UpdateSampleColumns() { samplesDataNodeTable.Columns.Clear(); DataNode.Factory valueFactory = ConstantDataNode.GetFactory(PLACEHOLDER); DataNode.Factory colorFactory = GradientInfoDataNode.GetFactory(_gradientColorChooser.GradientInfo, valueFactory); DataNodeViewer viewer = new DataNodeNumberViewer(valueFactory, 2, foreColor: colorFactory); DataNodeColumn column = new DataNodeColumn(viewer); column.HeaderText = "Foreground"; samplesDataNodeTable.Columns.Add(column); viewer = new DataNodeNumberViewer(valueFactory, 2, backColor: colorFactory); column = new DataNodeColumn(viewer); column.HeaderText = "Background"; samplesDataNodeTable.Columns.Add(column); // For some reason clearing all of the columns also clears all of the rows. UpdateSampleRows(); } // It's tempting to add a comma to the list. That would be inconsistent with the rest // of our code which tries to read and write numbers in the current locale. private static readonly char[] SPLIT = new char[] { ' ' }; private void UpdateSampleRows() { if ((null == samplesDataNodeTable) || (null == sampleNumbersTextBox)) // We are still building the form. return; samplesDataNodeTable.Rows.Clear(); foreach (string possible in sampleNumbersTextBox.Text.Split(SPLIT)) { double value; if (double.TryParse(possible, out value)) { DataGridViewRow row = new DataGridViewRow(); row.Tag = new Dictionary { { PLACEHOLDER_NAME, value } }; samplesDataNodeTable.Rows.Add(row); } } } private GradientColorChooser _gradientColorChooser = new GradientColorChooser(); private void symbolTextBox_TextChanged(object sender, EventArgs e) { Dictionary < string, object> sampleData = new Dictionary(); string symbol = symbolTextBox.Text.Trim(); if (symbol != "") sampleData[DataNode.PlaceHolder.SYMBOL.Key] = symbolTextBox.Text; inputValueSelector.SampleData = sampleData; } private void editColorsButton_Click(object sender, EventArgs e) { using (TopListColorChooser dialog = new TopListColorChooser(ConnectionMaster.First)) { dialog.GradientColorChooser = _gradientColorChooser; dialog.LimitToColumn(new ColumnInfo()); dialog.ShowDialog(); } } private class ColorPair { public string Name; public GradientInfo Colors; } private List GetColors(TopListForm form) { List result = new List(); GradientInfo main; Dictionary columns; form.GetColors(out main, out columns); if (null != main) result.Add(new ColorPair { Name = "main", Colors = main }); if (null != columns) foreach (var kvp in columns) result.Add(new ColorPair { Name = kvp.Key, Colors = kvp.Value }); return result; } private void SetColors(GradientInfo gradientInfo) { _gradientColorChooser.GradientInfo = gradientInfo; } private void selectFromTopListButton_Click(object sender, EventArgs e) { ContextMenuStrip menu = new ContextMenuStrip(); foreach (Form form in Application.OpenForms.Cast
().Where(x => !x.IsDisposed).ToList()) { TopListForm asTopList = form as TopListForm; if (null != asTopList) { string name = asTopList.Text ?? "Unnamed Top List"; List colors = GetColors(asTopList); if (colors.Count == 1) menu.Items.Add(name, null, delegate { SetColors(colors[0].Colors); }); else if (colors.Count > 0) { ToolStripMenuItem submenu = (ToolStripMenuItem)menu.Items.Add(name); foreach (ColorPair colorPair in colors) submenu.DropDown.Items.Add(colorPair.Name, null, delegate { SetColors(colorPair.Colors); }); } } } if (menu.Items.Count == 0) { ToolStripItem item = menu.Items.Add("No Windows Found"); item.Enabled = false; } Point ptLowerLeft = new Point(0, selectFromTopListButton.Height); ptLowerLeft = selectFromTopListButton.PointToScreen(ptLowerLeft); menu.Show(ptLowerLeft); } private void sampleNumbersTextBox_TextChanged(object sender, EventArgs e) { UpdateSampleRows(); } private void samplesDataNodeTable_SelectionChanged(object sender, EventArgs e) { if (samplesDataNodeTable.SelectedCells.Count > 0) samplesDataNodeTable.ClearSelection(); } private void okButton_Click(object sender, EventArgs e) { try { Result = GradientInfoDataNode.GetFactory(_gradientColorChooser.GradientInfo, (DataNode.Factory)inputValueSelector.Value); } catch (Exception ex) { // Presumably the user slected an input value that was not a DataNode.Factory. // We try to steer the user away from inappropriate answers. But I'm not sure we can // ever completely avoid bad types here. Result = ex; } DialogResult = DialogResult.OK; } } }