using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Xml; using System.Windows.Forms; using TradeIdeas.XML; namespace TradeIdeas.TIProGUI { public struct AlertColors { public Color BullishFg; public Color BullishBg; public Color BearishFg; public Color BearishBg; public Color NeutralFg; public Color NeutralBg; private AlertColors(int dummy) { BullishFg = Color.Black; BullishBg = Color.Lime; BearishFg = Color.Black; BearishBg = Color.FromArgb(255, 128, 128); NeutralFg = Color.Black; NeutralBg = Color.FromArgb(128, 128, 255); } static public AlertColors Default { get { AlertColors result = new AlertColors(0); return result; } } public void Save(XmlNode node) { node.SetProperty("BULLISH_FG", BullishFg); node.SetProperty("BULLISH_BG", BullishBg); node.SetProperty("BEARISH_FG", BearishFg); node.SetProperty("BEARISH_BG", BearishBg); node.SetProperty("NEUTRAL_FG", NeutralFg); node.SetProperty("NEUTRAL_BG", NeutralBg); } public void Save(XmlNode parent, string name) { Save(parent.NewNode(name)); } private static void GetColor(XmlNode node, string name, ref Color color) { color = node.Property(name, color); } public static AlertColors Load(XmlNode node) { AlertColors result = Default; GetColor(node, "BULLISH_FG", ref result.BullishFg); GetColor(node, "BULLISH_BG", ref result.BullishBg); GetColor(node, "BEARISH_FG", ref result.BearishFg); GetColor(node, "BEARISH_BG", ref result.BearishBg); GetColor(node, "NEUTRAL_FG", ref result.NeutralFg); GetColor(node, "NEUTRAL_BG", ref result.NeutralBg); return result; } public override bool Equals(object obj) { if (obj is AlertColors) return Equals((AlertColors)obj); else return false; } public bool Equals(AlertColors other) { // Note: Color.Equals() looks at more than the argb values. Black and (0, 0, 0) // are considered different because black has a name. return (BullishFg.ToArgb() == other.BullishFg.ToArgb()) && (BullishBg.ToArgb() == other.BullishBg.ToArgb()) && (BearishFg.ToArgb() == other.BearishFg.ToArgb()) && (BearishBg.ToArgb() == other.BearishBg.ToArgb()) && (NeutralFg.ToArgb() == other.NeutralFg.ToArgb()) && (NeutralBg.ToArgb() == other.NeutralBg.ToArgb()); } public override int GetHashCode() { // Assume colors might be swapped a lot, so xor without the shift would not have been // a good hash code. return BullishFg.ToArgb() ^ (BullishBg.ToArgb() << 1) ^ (BearishFg.ToArgb() << 2) ^ (BearishBg.ToArgb() << 3) ^ (NeutralFg.ToArgb() << 4) ^ (NeutralBg.ToArgb() << 5); } } public partial class AlertColorPicker : Form, ISaveLayout { private const int SPACER = 2; //vertical and horizontal. white spacer between each color setting block private FontManager _fontManager; private const float DEFAULT_FONT_SIZE = 8.25F; static private AlertColorPicker _instance; private String bullishListViewText; private String bearishListViewText; private String neutralListViewText; private int padding; private int bullishStringWidth; private int bearishStringWidth; private int neutralStringWidth; private int fontHeight; private List _phrases; // Support image for menu items public static readonly WindowIconCache WindowIconCache = new WindowIconCache("ALERT_COLOR"); static public AlertColorPicker Find() { if (null == _instance) _instance = new AlertColorPicker(); return _instance; } private AlertColorPicker() { _recentColors.Add(AlertColors.Default); this.StartPosition = FormStartPosition.CenterParent; InitializeComponent(); MinimizeBox = false; WindowIconCache.SetIcon(this); _phrases = GuiEnvironment.XmlConfig.Node("ALERT_COLOR_PICKER").Node("PHRASES"); _fontManager = new FontManager(this, DEFAULT_FONT_SIZE); _fontManager.selectTheFont(); Font = GuiEnvironment.FontSettings; Graphics g = recentSettingsListView.CreateGraphics(); //initialization... padding = (int)(g.MeasureString("x x", Font).Width - g.MeasureString("xx", Font).Width); bullishListViewText = _phrases.Node("BULLISH_SHORT").PropertyForCulture("TEXT", "***"); bullishStringWidth = (int)(g.MeasureString(bullishListViewText, Font).Width + padding); bearishListViewText = _phrases.Node("BEARISH_SHORT").PropertyForCulture("TEXT", "***"); bearishStringWidth = (int)(g.MeasureString(bearishListViewText, Font).Width + padding); neutralListViewText = _phrases.Node("NEUTRAL_SHORT").PropertyForCulture("TEXT", "***"); neutralStringWidth = (int)(g.MeasureString(neutralListViewText, Font).Width + padding); fontHeight = Font.Height; g.Dispose(); } private void setListBoxItemParameters(DrawListViewItemEventArgs e) { padding = (int)(e.Graphics.MeasureString("x x", Font).Width - e.Graphics.MeasureString("xx", e.Item.Font).Width); bullishListViewText = " " + _phrases.Node("BULLISH_SHORT").PropertyForCulture("TEXT", "***") + " "; bullishStringWidth = (int)(e.Graphics.MeasureString(bullishListViewText, e.Item.Font).Width + padding); bearishListViewText = " " + _phrases.Node("BEARISH_SHORT").PropertyForCulture("TEXT", "***") + " "; bearishStringWidth = (int)(e.Graphics.MeasureString(bearishListViewText, e.Item.Font).Width + padding); neutralListViewText = " " + _phrases.Node("NEUTRAL_SHORT").PropertyForCulture("TEXT", "***") + " "; neutralStringWidth = (int)(e.Graphics.MeasureString(neutralListViewText, e.Item.Font).Width + padding); recentSettingsListView.Columns[0].Width = bullishStringWidth + SPACER; recentSettingsListView.Columns[1].Width = bearishStringWidth + SPACER; recentSettingsListView.Columns[2].Width = neutralStringWidth + SPACER; fontHeight = e.Item.Font.Height; } private void setUpColumnsForListBox() { recentSettingsListView.Clear(); recentSettingsListView.Columns.Add(bullishListViewText, bullishStringWidth); recentSettingsListView.Columns.Add(bearishListViewText, bearishStringWidth); recentSettingsListView.Columns.Add(neutralListViewText, neutralStringWidth); } private void CultureChanged() { Text = _phrases.Node("TITLE").PropertyForCulture("TEXT", "***"); bullishSampleLabel.Text = _phrases.Node("BULLISH_ALERT_SAMPLE").PropertyForCulture("TEXT", "***"); bearishSampleLabel.Text = _phrases.Node("BEARISH_ALERT_SAMPLE").PropertyForCulture("TEXT", "***"); neutralSampleLabel.Text = _phrases.Node("NEUTRAL_ALERT_SAMPLE").PropertyForCulture("TEXT", "***"); recentSettingsLabel.Text = _phrases.Node("RECENT_SETTINGS").PropertyForCulture("TEXT", "***"); List commonPhrases = GuiEnvironment.XmlConfig.Node("COMMON_PHRASES"); okButton.Text = commonPhrases.Node("OK").PropertyForCulture("TEXT", "***"); cancelButton.Text = commonPhrases.Node("CANCEL").PropertyForCulture("TEXT", "***"); } private List _recentColors = new List(); public AlertColors AlertColors { get { AlertColors result; result.BullishFg = bullishFgButton.BackColor; result.BullishBg = bullishBgButton.BackColor; result.BearishFg = bearishFgButton.BackColor; result.BearishBg = bearishBgButton.BackColor; result.NeutralFg = neutralFgButton.BackColor; result.NeutralBg = neutralBgButton.BackColor; return result; } set { AddToRecent(value); SetAll(value); } } WindowIconCache ISaveLayout.WindowIconCache { get { return WindowIconCache; } } public bool Pinned { get; set; } private void SetAll(AlertColors newColors) { bullishFgButton.BackColor = newColors.BullishFg; bullishSampleLabel.ForeColor = newColors.BullishFg; bullishBgButton.BackColor = newColors.BullishBg; bullishSampleLabel.BackColor = newColors.BullishBg; bearishFgButton.BackColor = newColors.BearishFg; bearishSampleLabel.ForeColor = newColors.BearishFg; bearishBgButton.BackColor = newColors.BearishBg; bearishSampleLabel.BackColor = newColors.BearishBg; neutralFgButton.BackColor = newColors.NeutralFg; neutralSampleLabel.ForeColor = newColors.NeutralFg; neutralBgButton.BackColor = newColors.NeutralBg; neutralSampleLabel.BackColor = newColors.NeutralBg; } private void AddToRecent(AlertColors newColors) { // If it's already in the list, move it to the top. _recentColors.Remove(newColors); _recentColors.Insert(0, newColors); // Don't let the list get too long. while (_recentColors.Count > 15) _recentColors.RemoveAt(_recentColors.Count - 1); // Update the GUI recentSettingsListView.Items.Clear(); setUpColumnsForListBox(); foreach (AlertColors colors in _recentColors) { //Add items in the list view string[] arr = new string[3]; ListViewItem itm; arr[0] = bullishListViewText; arr[1] = bearishListViewText; arr[2] = neutralListViewText; itm = new ListViewItem(arr); itm.UseItemStyleForSubItems = false; recentSettingsListView.Items.Add(itm); } } private void AlertColorPicker_FormClosed(object sender, FormClosedEventArgs e) { // Save this value regardless of whether the user hit OK or cancel. AddToRecent(AlertColors); } private void SetColor(Button button, Label label, bool foreground) { colorDialog1.Color = button.BackColor; if (colorDialog1.ShowDialog() == DialogResult.OK) { button.BackColor = colorDialog1.Color; if (foreground) label.ForeColor = colorDialog1.Color; else label.BackColor = colorDialog1.Color; } } private void bullishFgButton_Click(object sender, EventArgs e) { SetColor(bullishFgButton, bullishSampleLabel, true); } private void bullishBgButton_Click(object sender, EventArgs e) { SetColor(bullishBgButton, bullishSampleLabel, false); } private void bearishFgButton_Click(object sender, EventArgs e) { SetColor(bearishFgButton, bearishSampleLabel, true); } private void bearishBgButton_Click(object sender, EventArgs e) { SetColor(bearishBgButton, bearishSampleLabel, false); } private void neutralFgButton_Click(object sender, EventArgs e) { SetColor(neutralFgButton, neutralSampleLabel, true); } private void neutralBgButton_Click(object sender, EventArgs e) { SetColor(neutralBgButton, neutralSampleLabel, false); } private void recentSettingsListBox_SelectedIndexChanged(object sender, EventArgs e) { int index; int count = recentSettingsListView.SelectedIndices.Count; if (count == 0) index = 0; else index = recentSettingsListView.SelectedIndices[0]; if(index >= 0) { SetAll(_recentColors[index]); } } private void AlertColorPicker_VisibleChanged(object sender, EventArgs e) { if (!Visible) { // Save the size of this window...should user resize.. Height = Size.Height; Width = Size.Width; } if (Visible) { // This window is reused, so we can't customize the culture specific stuff in the // constructor. But this is a modal dialog box, so we don't have to worry about // changes while this window is currently displayed. CultureChanged(); _fontManager.selectTheFont(); } } private void recentSettingsListBox_DrawItem(object sender, DrawListViewItemEventArgs e) { if (e.ItemIndex < 0) // This actually happens! e.DrawBackground(); else { setListBoxItemParameters(e); AlertColors colors = _recentColors[e.ItemIndex]; string toDisplay = bullishListViewText; Rectangle r = e.Item.SubItems[0].Bounds; SolidBrush bullBg = new SolidBrush(colors.BullishBg); e.Graphics.FillRectangle(bullBg, r.X, r.Y, bullishStringWidth, fontHeight + SPACER); bullBg.Dispose(); SolidBrush bullFg = new SolidBrush(colors.BullishFg); e.Graphics.DrawString(toDisplay, e.Item.Font, bullFg, r.X, r.Y + 1); bullFg.Dispose(); r = e.Item.SubItems[1].Bounds; toDisplay = bearishListViewText; SolidBrush bearBg = new SolidBrush(colors.BearishBg); e.Graphics.FillRectangle(bearBg, r.X, r.Y, bearishStringWidth, fontHeight + SPACER); bearBg.Dispose(); SolidBrush bearFg = new SolidBrush(colors.BearishFg); e.Graphics.DrawString(toDisplay, e.Item.Font, bearFg, r.X, r.Y + 1); bearFg.Dispose(); r = e.Item.SubItems[2].Bounds; toDisplay = neutralListViewText; SolidBrush neutralBg = new SolidBrush(colors.NeutralBg); e.Graphics.FillRectangle(neutralBg, r.X, r.Y, neutralStringWidth, fontHeight + SPACER); neutralBg.Dispose(); SolidBrush neutralFg = new SolidBrush(colors.NeutralFg); e.Graphics.DrawString(toDisplay, e.Item.Font, neutralFg, r.X, r.Y + 1); bearFg.Dispose(); } } public void SaveLayout(XmlNode parent) { } } }