/// <summary>
        /// Edits the specified object's value using the editor style indicated by GetEditStyle.
        /// </summary>
        /// <param name="context">An ITypeDescriptorContext that can be used to gain additional context information.</param>
        /// <param name="provider">An IServiceProvider that this editor can use to obtain services.</param>
        /// <param name="value">The object to edit.</param>
        /// <returns></returns>
        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            if ((context != null) && (context.Instance != null) && (provider != null))
            {
                // Convert to the correct class.
                CommandBaseCollection commands = value as CommandBaseCollection;

                // Create the dialog used to edit the commands
                CommandCollectionDialog dialog = new CommandCollectionDialog(commands);

                // Give user the chance to modify the nodes
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    // Reflect changes back into original copy and generate appropriate
                    // component changes to designer to reflect these changes
                    SynchronizeCollections(commands, dialog.Commands, context);

                    // Notify container that value has been changed
                    context.OnComponentChanged();
                }
            }

            // Return the original value
            return(value);
        }
        /// <summary>
        /// Initializes a new instance of the NodeCollectionDialog class.
        /// </summary>
        /// <param name="original">Original Nodes to be edited.</param>
        public CommandCollectionDialog(CommandBaseCollection original)
        {
            // Required for Windows Form Designer support
            InitializeComponent();

            // Create a new per command
            foreach (CommandBase command in original)
            {
                // Create a new tree node to hold the command
                Node newNode = new Node();

                // Create a copy to attach to the node
                CommandBase copy = (CommandBase)command.Clone();

                if (copy.GetType() == typeof(SeparatorCommand))
                {
                    newNode.Text = "(Separator)";
                }
                else if (copy.GetType() == typeof(ButtonCommand))
                {
                    ButtonCommand button = copy as ButtonCommand;

                    // Special case the absense of text
                    if (button.Text.Length == 0)
                    {
                        newNode.Text = "<Empty>";
                    }
                    else
                    {
                        newNode.Text = button.Text;
                    }

                    // We want to know when the text for the node changes
                    button.TextChanged += new EventHandler(OnTextChanged);
                }

                // Attached a copy of the command to the node
                newNode.Tag = copy;

                // Append to end of the list
                treeControl1.Nodes.Add(newNode);
            }

            // Set correct initial state of the buttons
            UpdateButtonState();
        }
Exemple #3
0
        private void InternalConstruct()
        {
            // Create internal state objects
            _details = new CommandDetails(this);
            _engine  = new SingleLayoutEngine();
            _states  = new CommandStateCollection();
            _padding = new Padding();

            // Define state
            _initCount       = 0;
            _layoutRequired  = false;
            _mouseDownButton = MouseButtons.None;
            _mouseCapture    = false;
            _currentCmdState = null;
            _tooltipCmdState = null;

            // Hook into padding changed events
            _padding.PaddingChanged += new EventHandler(OnPaddingChanged);

            // Create exposed/internal collections of commands
            _externals = new CommandBaseCollection();
            _internals = new CommandBaseCollection();

            // Hook into command collection modifications
            _externals.Clearing += new CollectionClear(OnCommandsClearing);
            _externals.Cleared  += new CollectionClear(OnCommandsCleared);
            _externals.Inserted += new CollectionChange(OnCommandInserted);
            _externals.Removed  += new CollectionChange(OnCommandRemoved);
            _internals.Clearing += new CollectionClear(OnCommandsClearing);
            _internals.Cleared  += new CollectionClear(OnCommandsCleared);
            _internals.Inserted += new CollectionChange(OnCommandInserted);
            _internals.Removed  += new CollectionChange(OnCommandRemoved);

            // Need a timer so that when the mouse hovers we can show tooltips
            _hoverTimer       = new Timer();
            _hoverTimer.Tick += new EventHandler(OnMouseHoverTick);

            // Need a timer so that we can send updates to top level commands
            _updateTimer       = new Timer();
            _updateTimer.Tick += new EventHandler(OnUpdateTick);
        }
        private void SynchronizeCollections(CommandBaseCollection orig,
                                            CommandBaseCollection copy,
                                            ITypeDescriptorContext context)
        {
            // Make a note of all original commands that are still in copy
            Hashtable both = new Hashtable();

            // First pass, scan looking for commands that are in original and copy
            foreach (CommandBase copyCommand in copy)
            {
                // Does this node have an back pointer to its original?
                if (copyCommand.Original != null)
                {
                    // Then make a note that it is in both collections
                    both.Add(copyCommand.Original, copyCommand.Original);

                    // Update the original from the copy
                    copyCommand.Original.UpdateInstance(copyCommand);
                }
            }

            int origCount = orig.Count;

            // Second pass, remove commands in the original but not in the copy
            for (int i = 0; i < origCount; i++)
            {
                // Get access to the indexed command from original
                CommandBase origCommand = orig[i];

                // If not in the found collection...
                if (!both.ContainsKey(origCommand))
                {
                    // ...then it has been removed from the copy, so delete it
                    orig.Remove(origCommand);

                    // Must remove from context container so it is removed from designer tray
                    context.Container.Remove(origCommand as IComponent);

                    // Reduce the count and index to reflect change in collection contents
                    --i;
                    --origCount;
                }
            }

            int copyCount = copy.Count;

            // Third pass, add new nodes from copy but not in original
            for (int i = 0; i < copyCount; i++)
            {
                // Get access to the indexed command from copy
                CommandBase copyCommand = copy[i];

                // If this command is a new one then it will not have an 'original' property
                if (copyCommand.Original == null)
                {
                    // It references itself in the new collection
                    copyCommand.Original = copyCommand;

                    // Add this node into the original at indexed position
                    orig.Insert(i, copyCommand);

                    // Must add into context container so it is added to the designer tray
                    context.Container.Add(copyCommand as IComponent);
                }
            }

            // Fourth pass, set correct ordering to match copy
            for (int i = 0; i < copyCount; i++)
            {
                // Grab indexed item from the copy
                CommandBase copyCommand = copy[i];

                // Get the command to look for in original
                CommandBase origCommand = copyCommand.Original;

                // Find its indexed position in original collection
                int origIndex = orig.IndexOf(origCommand);

                // If this is not its required position
                if (origIndex != i)
                {
                    // Remove it from collection
                    orig.Remove(origCommand);

                    // Insert back in correct place
                    orig.Insert(i, origCommand);
                }
            }
        }