Inheritance: GraphicalDebugging.VariableItem
 private void ResetAt(GeometryItem item, int index)
 {
     ((System.ComponentModel.INotifyPropertyChanged)item).PropertyChanged += GeometryItem_NameChanged;
     if (index < Geometries.Count)
     {
         Geometries.RemoveAt(index);
     }
     Geometries.Insert(index, item);
 }
        private void colorTextBlock_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            TextBlock    textBlock = sender as TextBlock;
            GeometryItem geometry  = textBlock.DataContext as GeometryItem;

            if (geometry.ColorId >= 0)
            {
                var color    = (textBlock.Background as System.Windows.Media.SolidColorBrush).Color;
                var newColor = Util.ShowColorDialog(color);
                if (newColor != color)
                {
                    textBlock.Background = new System.Windows.Media.SolidColorBrush(newColor);
                    m_colorIds.Push(geometry.ColorId);
                    geometry.ColorId = int.MaxValue;
                    geometry.Color   = newColor;
                    UpdateItems(false); // TODO: pass modified_index?
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="GeometryWatchControl"/> class.
        /// </summary>
        public GeometryWatchControl()
        {
            m_dte = (DTE2)ServiceProvider.GlobalProvider.GetService(typeof(DTE));
            m_debugger = m_dte.Debugger;
            m_debuggerEvents = m_dte.Events.DebuggerEvents;
            m_debuggerEvents.OnEnterBreakMode += DebuggerEvents_OnEnterBreakMode;

            m_colorsPool = new Util.ColorsPool();

            m_emptyBitmap = new Bitmap(100, 100);
            Graphics graphics = Graphics.FromImage(m_emptyBitmap);
            graphics.Clear(Color.White);

            this.InitializeComponent();

            image.Source = Util.BitmapToBitmapImage(m_emptyBitmap);

            GeometryItem var = new GeometryItem(m_colorsPool.Transparent);
            ((System.ComponentModel.INotifyPropertyChanged)var).PropertyChanged += GeometryItem_NameChanged;
            listView.Items.Add(var);
        }
        private void GeometryItem_NameChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            //e.PropertyName == "Name"

            GeometryItem geometry = sender as GeometryItem;
            int          index    = Geometries.IndexOf(geometry);

            if (index < 0 || index >= dataGrid.Items.Count)
            {
                return;
            }

            if (geometry.Name == null || geometry.Name == "")
            {
                if (index < dataGrid.Items.Count - 1)
                {
                    m_intsPool.Push(geometry.ColorId);
                    Geometries.RemoveAt(index);
                    UpdateItems(true);
                    if (index > 0)
                    {
                        Util.SelectDataGridItem(dataGrid, index - 1);
                    }
                }
            }
            else
            {
                UpdateItems(true, index);

                int next_index = index + 1;
                // insert new empty row if needed
                if (next_index == Geometries.Count)
                {
                    ResetAt(new GeometryItem(-1, m_colors), next_index);
                }
                // select current row, move to next one is automatic
                Util.SelectDataGridItem(dataGrid, index);
            }
        }
        private void GeometryItem_NameChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            //e.PropertyName == "Name"

            GeometryItem geometry = (GeometryItem)sender;
            int          index    = Geometries.IndexOf(geometry);

            if (index < 0 || index >= dataGrid.Items.Count)
            {
                return;
            }

            if (geometry.Name == null || geometry.Name == "")
            {
                if (index < dataGrid.Items.Count - 1)
                {
                    m_intsPool.Push(geometry.ColorId);
                    Geometries.RemoveAt(index);
                    UpdateItems();
                }
            }
            else
            {
                UpdateItems(index);

                // insert new empty row
                int next_index = index + 1;
                if (next_index == Geometries.Count)
                {
                    ResetAt(new GeometryItem(-1, m_colors), index + 1);
                    SelectAt(index + 1, true);
                }
                else
                {
                    SelectAt(index + 1);
                }
            }
        }
        private void dataGrid_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == System.Windows.Input.Key.Delete)
            {
                if (dataGrid.SelectedItems.Count > 0)
                {
                    int[] indexes = new int[dataGrid.SelectedItems.Count];
                    int   i       = 0;
                    foreach (var item in dataGrid.SelectedItems)
                    {
                        indexes[i] = dataGrid.Items.IndexOf(item);
                        ++i;
                    }
                    System.Array.Sort(indexes, delegate(int l, int r)
                    {
                        return(-l.CompareTo(r));
                    });

                    bool removed = false;
                    foreach (int index in indexes)
                    {
                        if (index + 1 < Geometries.Count)
                        {
                            GeometryItem geometry = Geometries[index];
                            m_intsPool.Push(geometry.ColorId);
                            Geometries.RemoveAt(index);

                            removed = true;
                        }
                    }

                    if (removed)
                    {
                        UpdateItems();
                    }
                }
            }
        }
        private void UpdateItems(bool load, int modified_index = -1)
        {
            m_currentBox = null;

            bool imageEmpty = true;

            if (ExpressionLoader.Debugger.CurrentMode == dbgDebugMode.dbgBreakMode)
            {
                if (load)
                {
                    ExpressionLoader.ReloadUserTypes(Util.GetDialogPage <GeneralOptionPage>());
                }

                ExpressionDrawer.Settings referenceSettings = new ExpressionDrawer.Settings();
                GeometryWatchOptionPage   optionPage        = Util.GetDialogPage <GeometryWatchOptionPage>();
                if (optionPage != null)
                {
                    referenceSettings.densify    = optionPage.Densify;
                    referenceSettings.showDir    = optionPage.EnableDirections;
                    referenceSettings.showLabels = optionPage.EnableLabels;
                    referenceSettings.showDots   = true;
                }

                // TODO: Names are redundant
                string[] names = new string[Geometries.Count];
                ExpressionDrawer.Settings[] settings = new ExpressionDrawer.Settings[Geometries.Count];
                bool tryDrawing = false;

                // update the list, gather names and settings
                for (int index = 0; index < Geometries.Count; ++index)
                {
                    GeometryItem geometry = Geometries[index];

                    System.Windows.Media.Color color = geometry.Color;
                    int    colorId = geometry.ColorId;
                    string type    = null;

                    bool updateRequred = modified_index < 0 || modified_index == index;

                    if (updateRequred && load)
                    {
                        geometry.Drawable = null;
                        geometry.Traits   = null;
                    }

                    if (geometry.Name != null && geometry.Name != "")
                    {
                        var expressions = updateRequred
                                       ? ExpressionLoader.GetExpressions(geometry.Name)
                                       : null;
                        if (expressions == null || ExpressionLoader.AllValidValues(expressions))
                        {
                            if (expressions != null)
                            {
                                type = ExpressionLoader.TypeFromExpressions(expressions);
                            }

                            names[index] = geometry.Name;

                            if (updateRequred && geometry.ColorId < 0)
                            {
                                colorId = m_intsPool.Pull();
                                color   = Util.ConvertColor(m_colors[colorId]);
                            }

                            settings[index] = referenceSettings.CopyColored(color);

                            tryDrawing = true;
                        }
                    }

                    // set new row
                    if (updateRequred)
                    {
                        ResetAt(new GeometryItem(geometry.Drawable, geometry.Traits,
                                                 geometry.Name, type, colorId, m_colors),
                                index);
                    }
                }

                // draw variables
                if (tryDrawing)
                {
                    int width  = (int)System.Math.Round(image.ActualWidth);
                    int height = (int)System.Math.Round(image.ActualHeight);
                    if (width > 0 && height > 0)
                    {
                        Bitmap bmp = new Bitmap(width, height);

                        Graphics graphics = Graphics.FromImage(bmp);
                        graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                        graphics.Clear(m_colors.ClearColor);

                        try
                        {
                            ExpressionDrawer.IDrawable[] drawables = new ExpressionDrawer.IDrawable[names.Length];
                            Geometry.Traits[]            traits    = new Geometry.Traits[names.Length];
                            for (int i = 0; i < names.Length; ++i)
                            {
                                if (Geometries[i].Drawable == null && names[i] != null && names[i] != "")
                                {
                                    try
                                    {
                                        // TODO: Unify the loading of empty geometries.
                                        //   For empty linestring the coordinate system name is drawn
                                        //   however for empty multilinestring it is not. The reason
                                        //   is that in the latter case null drawable and traits are
                                        //   returned becasue traits are loaded from an element
                                        //   (linestring) but there are no elements since the
                                        //   multi-geometry is empty.
                                        ExpressionDrawer.IDrawable d = null;
                                        Geometry.Traits            t = null;
                                        ExpressionLoader.Load(names[i],
                                                              ExpressionLoader.OnlyGeometriesOrGeometryContainer,
                                                              out t, out d);
                                        if (t == null) // Traits has to be defined for Geometry
                                        {
                                            d = null;
                                        }
                                        Geometries[i].Drawable = d;
                                        Geometries[i].Traits   = t;
                                        Geometries[i].Error    = null;
                                    }
                                    catch (Exception e)
                                    {
                                        Geometries[i].Error = e.Message;
                                    }
                                }
                                drawables[i] = Geometries[i].Drawable;
                                traits[i]    = Geometries[i].Traits;
                            }

                            m_currentBox = ExpressionDrawer.DrawGeometries(graphics, drawables, traits, settings, m_colors, m_zoomBox);
                        }
                        catch (Exception e)
                        {
                            ExpressionDrawer.DrawErrorMessage(graphics, e.Message);
                        }

                        image.Source = Util.BitmapToBitmapImage(bmp);
                        imageEmpty   = false;
                    }
                }
            }

            if (imageEmpty)
            {
                image.Source = Util.BitmapToBitmapImage(m_emptyBitmap);
            }

            imageGrid.ContextMenu = new ContextMenu();
            MenuItem mi = new MenuItem();

            mi.Header = "Copy";
            mi.Click += MenuItem_Copy;
            if (imageEmpty)
            {
                mi.IsEnabled = false;
            }
            imageGrid.ContextMenu.Items.Add(mi);
            imageGrid.ContextMenu.Items.Add(new Separator());
            MenuItem mi2 = new MenuItem();

            mi2.Header = "Reset View";
            mi2.Click += MenuItem_ResetZoom;
            if (imageEmpty)
            {
                mi2.IsEnabled = false;
            }
            imageGrid.ContextMenu.Items.Add(mi2);
        }
        private void GeometryItem_NameChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            //e.PropertyName == "Name"

            GeometryItem geometry = (GeometryItem)sender;
            int index = listView.Items.IndexOf(geometry);

            if (geometry.Name == null || geometry.Name == "")
            {
                m_colorsPool.Push(Util.ConvertColor(geometry.Color));
                listView.Items.RemoveAt(index);
                if (index >= 0)
                    RedrawGeometries();
                return;
            }

            // insert new empty row
            if (index + 1 == listView.Items.Count)
            {
                GeometryItem empty_variable = new GeometryItem(m_colorsPool.Transparent);
                ((System.ComponentModel.INotifyPropertyChanged)empty_variable).PropertyChanged += GeometryItem_NameChanged;
                listView.Items.Add(empty_variable);
            }

            System.Windows.Media.Color color = geometry.Color;
            ExpressionDrawer.IDrawable drawable = null;
            string type = null;

            // debugging
            if (m_debugger.CurrentMode == dbgDebugMode.dbgBreakMode)
            {
                var expression = m_debugger.GetExpression(geometry.Name);
                if (expression.IsValidValue)
                {
                    drawable = ExpressionDrawer.MakeGeometry(m_debugger, geometry.Name);
                    type = expression.Type;

                    if (drawable != null)
                    {
                        if (color == Util.ConvertColor(m_colorsPool.Transparent))
                            color = Util.ConvertColor(m_colorsPool.Pull());
                    }
                }
            }

            // set new row
            GeometryItem new_variable = new GeometryItem(geometry.Name, drawable, type, color);
            ((System.ComponentModel.INotifyPropertyChanged)new_variable).PropertyChanged += GeometryItem_NameChanged;
            listView.Items.RemoveAt(index);
            listView.Items.Insert(index, new_variable);

            if (drawable != null)
            {
                Geometry.Box aabb = Geometry.Box.Inverted();
                int drawnCount = 0;
                foreach (GeometryItem g in listView.Items)
                {
                    if (g.Drawable != null)
                    {
                        aabb.Expand(g.Drawable.Aabb);
                        ++drawnCount;
                    }
                }

                if (drawnCount > 0)
                {
                    Bitmap bmp = new Bitmap((int)image.ActualWidth, (int)image.ActualHeight);

                    Graphics graphics = Graphics.FromImage(bmp);
                    graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                    graphics.Clear(Color.White);

                    ExpressionDrawer.Settings settings = new ExpressionDrawer.Settings(Color.Black, true, true);
                    foreach (GeometryItem g in listView.Items)
                    {
                        if (g.Drawable != null)
                        {
                            settings.color = Util.ConvertColor(g.Color);
                            g.Drawable.Draw(aabb, graphics, settings);
                        }
                    }

                    ExpressionDrawer.DrawAabb(graphics, aabb);

                    image.Source = Util.BitmapToBitmapImage(bmp);
                }
                else
                {
                    image.Source = Util.BitmapToBitmapImage(m_emptyBitmap);
                }
            }
        }
        private void RedrawGeometries()
        {
            if (m_debugger.CurrentMode == dbgDebugMode.dbgBreakMode)
            {
                Geometry.Box aabb = Geometry.Box.Inverted();
                int drawnCount = 0;
                for (int index = 0; index < listView.Items.Count; ++index)
                {
                    GeometryItem geometry = (GeometryItem)listView.Items[index];

                    System.Windows.Media.Color color = geometry.Color;
                    ExpressionDrawer.IDrawable drawable = null;
                    string type = null;

                    if (geometry.Name != null && geometry.Name != "")
                    {
                        var expression = m_debugger.GetExpression(geometry.Name);
                        if (expression.IsValidValue)
                        {
                            drawable = ExpressionDrawer.MakeGeometry(m_debugger, geometry.Name);
                            type = expression.Type;

                            if (drawable != null)
                            {
                                if (geometry.Color == Util.ConvertColor(m_colorsPool.Transparent))
                                    color = Util.ConvertColor(m_colorsPool.Pull());

                                aabb.Expand(drawable.Aabb);
                                ++drawnCount;
                            }
                        }
                    }

                    // set new row
                    GeometryItem new_geometry = new GeometryItem(geometry.Name, drawable, type, color);
                    ((System.ComponentModel.INotifyPropertyChanged)new_geometry).PropertyChanged += GeometryItem_NameChanged;
                    listView.Items.RemoveAt(index);
                    listView.Items.Insert(index, new_geometry);
                }

                if (drawnCount > 0)
                {
                    Bitmap bmp = new Bitmap((int)System.Math.Round(image.ActualWidth),
                                            (int)System.Math.Round(image.ActualHeight));

                    Graphics graphics = Graphics.FromImage(bmp);
                    graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                    graphics.Clear(Color.White);

                    ExpressionDrawer.Settings settings = new ExpressionDrawer.Settings(Color.Black, true, true);
                    foreach (GeometryItem g in listView.Items)
                    {
                        if (g.Drawable != null)
                        {
                            settings.color = Util.ConvertColor(g.Color);
                            g.Drawable.Draw(aabb, graphics, settings);
                        }
                    }

                    ExpressionDrawer.DrawAabb(graphics, aabb);

                    image.Source = Util.BitmapToBitmapImage(bmp);
                }
                else
                {
                    image.Source = Util.BitmapToBitmapImage(m_emptyBitmap);
                }
            }
        }
        private void UpdateItems(int modified_index = -1)
        {
            bool imageEmpty = true;

            if (m_debugger.CurrentMode == dbgDebugMode.dbgBreakMode)
            {
                string[] names = new string[Geometries.Count];
                ExpressionDrawer.Settings[] settings = new ExpressionDrawer.Settings[Geometries.Count];
                bool tryDrawing = false;

                // update the list, gather names and settings
                for (int index = 0; index < Geometries.Count; ++index)
                {
                    GeometryItem geometry = Geometries[index];

                    System.Windows.Media.Color color = geometry.Color;
                    int    colorId = geometry.ColorId;
                    string type    = null;

                    bool updateRequred = modified_index < 0 || modified_index == index;

                    if (geometry.Name != null && geometry.Name != "")
                    {
                        var expression = updateRequred ? m_debugger.GetExpression(geometry.Name) : null;
                        if (expression == null || expression.IsValidValue)
                        {
                            if (expression != null)
                            {
                                type = expression.Type;
                            }

                            names[index] = geometry.Name;

                            if (updateRequred && geometry.ColorId < 0)
                            {
                                colorId = m_intsPool.Pull();
                                color   = Util.ConvertColor(m_colors[colorId]);
                            }

                            settings[index] = new ExpressionDrawer.Settings(Util.ConvertColor(color), true, true);

                            tryDrawing = true;
                        }
                    }

                    // set new row
                    if (updateRequred)
                    {
                        ResetAt(new GeometryItem(geometry.Name, type, colorId, m_colors), index);
                    }
                }

                // draw variables
                if (tryDrawing)
                {
                    int width  = (int)System.Math.Round(image.ActualWidth);
                    int height = (int)System.Math.Round(image.ActualHeight);
                    if (width > 0 && height > 0)
                    {
                        Bitmap bmp = new Bitmap(width, height);

                        Graphics graphics = Graphics.FromImage(bmp);
                        graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                        graphics.Clear(m_colors.ClearColor);

                        ExpressionDrawer.DrawGeometries(graphics, m_debugger, names, settings, m_colors);

                        image.Source = Util.BitmapToBitmapImage(bmp);
                        imageEmpty   = false;
                    }
                }
            }

            if (imageEmpty)
            {
                image.Source = Util.BitmapToBitmapImage(m_emptyBitmap);
            }

            image.ContextMenu = new ContextMenu();
            MenuItem mi = new MenuItem();

            mi.Header = "Copy";
            mi.Click += MenuItem_Copy;
            if (imageEmpty)
            {
                mi.IsEnabled = false;
            }
            image.ContextMenu.Items.Add(mi);
        }
 private void ResetAt(GeometryItem item, int index)
 {
     ((System.ComponentModel.INotifyPropertyChanged)item).PropertyChanged += GeometryItem_NameChanged;
     if (index < Geometries.Count)
         Geometries.RemoveAt(index);
     Geometries.Insert(index, item);
 }