private void CreateFromCollection(ButtonSpecCollectionBase specs,
                                          ref int[] nearCounts,
                                          ref int[] farCounts)
        {
            // If there is a collection to examine
            if (specs != null)
            {
                // Create views for all the button specifications
                foreach (ButtonSpec buttonSpec in specs.Enumerate())
                {
                    // Add view for the button spec
                    ButtonSpecView view = AddButtonSpec(buttonSpec);

                    if (view != null)
                    {
                        // Only interested in visible buttons
                        if (buttonSpec.GetVisible(_redirector))
                        {
                            // Get the index of the target view docker
                            int dockerIndex = GetTargetDockerIndex(buttonSpec.GetLocation(_redirector));

                            // The edge determines which count to use
                            if (buttonSpec.GetEdge(_redirector) == RelativeEdgeAlign.Far)
                            {
                                farCounts[dockerIndex]++;
                            }
                            else
                            {
                                nearCounts[dockerIndex]++;
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Gets the view for the previous visible and enabled button spec of the defined edge.
        /// </summary>
        /// <param name="align">Edge of buttons caller is interested in searching.</param>
        /// <param name="current">Current button that is the marker for searching.</param>
        /// <returns>ViewDrawButton reference; otherwise false.</returns>
        public virtual ViewDrawButton GetPreviousVisibleViewButton(PaletteRelativeEdgeAlign align,
                                                                   ViewDrawButton current)
        {
            ButtonSpecView[] specLookups = new ButtonSpecView[_specLookup.Count];
            _specLookup.Values.CopyTo(specLookups, 0);

            bool found = false;

            for (int i = _specLookup.Count - 1; i >= 0; i--)
            {
                ButtonSpecView specView = specLookups[i];

                if (!found)
                {
                    found = (specView.ViewButton == current);
                }
                else
                {
                    // Is the button actually visible/enabled
                    if (specView.ViewCenter.Visible &&
                        specView.ViewButton.Enabled)
                    {
                        if (specView.ButtonSpec.Edge == align)
                        {
                            return(specView.ViewButton);
                        }
                    }
                }
            }

            return(null);
        }
        /// <summary>
        /// Perform final steps now that the button spec has been created.
        /// </summary>
        /// <param name="buttonSpec">ButtonSpec instance.</param>
        /// <param name="buttonView">Associated ButtonSpecView instance.</param>
        /// <param name="viewDockerIndex">Index of view docker button is placed onto.</param>
        protected virtual void ButtonSpecCreated(ButtonSpec buttonSpec,
                                                 ButtonSpecView buttonView,
                                                 int viewDockerIndex)
        {
            // Cast the remapping palette to the correct type
            ButtonSpecRemapByContentView remapPalette = (ButtonSpecRemapByContentView)buttonView.RemapPalette;

            // Update button with the foreground used for colour mapping
            remapPalette.Foreground = GetDockerForeground(viewDockerIndex);
        }
        private void RemoveButtonSpec(ButtonSpec buttonSpec)
        {
            // Unhook from button spec events
            buttonSpec.ButtonSpecPropertyChanged -= OnPropertyChanged;

            // Get the button view from the button spec
            ButtonSpecView buttonView = _specLookup[buttonSpec];

            if (buttonView != null)
            {
                // Remove the view that was created for the button from its header
                if ((buttonView.ViewCenter.Parent != null) &&
                    buttonView.ViewCenter.Parent.Contains(buttonView.ViewCenter))
                {
                    buttonView.ViewCenter.Parent.Remove(buttonView.ViewCenter);
                }

                // Pull down the view for the button
                buttonView.Destruct();
            }
        }
        private ButtonSpecView AddButtonSpec(ButtonSpec buttonSpec)
        {
            // Find the docker index that is the target for the button spec
            int viewDockerIndex = GetTargetDockerIndex(buttonSpec.GetLocation(_redirector));

            // Are we applying metrics
            if ((_viewMetrics != null) &&
                (_viewMetrics.Length > viewDockerIndex) &&
                (_viewMetricPaddings.Length > viewDockerIndex))
            {
                IPaletteMetric       viewPaletteMetric = _viewMetrics[viewDockerIndex];
                PaletteMetricPadding viewMetricPadding = _viewMetricPaddings[viewDockerIndex];

                // Create an instance to manage the individual button spec
                ButtonSpecView buttonView = CreateButtonSpecView(_redirector, viewPaletteMetric, viewMetricPadding, buttonSpec);

                // Add a lookup from the button spec to the button spec view
                _specLookup.Add(buttonSpec, buttonView);

                // Update the button with the same orientation as the view header
                buttonView.ViewButton.Orientation = CalculateOrientation(DockerOrientation(viewDockerIndex),
                                                                         buttonSpec.GetOrientation(_redirector));

                buttonView.ViewCenter.Orientation = DockerOrientation(viewDockerIndex);

                // Insert the button view into the docker
                AddViewToDocker(viewDockerIndex, GetDockStyle(buttonSpec), buttonView.ViewCenter, (_viewMetrics != null));

                // Perform any last construction steps for button spec
                ButtonSpecCreated(buttonSpec, buttonView, viewDockerIndex);

                // Hook in to the button spec change event
                buttonSpec.ButtonSpecPropertyChanged += OnPropertyChanged;

                return(buttonView);
            }

            return(null);
        }
        /// <summary>
        /// Gets the view for the last visible and enabled button spec of the defined edge.
        /// </summary>
        /// <param name="align">Edge of buttons caller is interested in searching.</param>
        /// <returns>ViewDrawButton reference; otherwise false.</returns>
        public virtual ViewDrawButton GetLastVisibleViewButton(PaletteRelativeEdgeAlign align)
        {
            ButtonSpecView[] specLookups = new ButtonSpecView[_specLookup.Count];
            _specLookup.Values.CopyTo(specLookups, 0);

            for (int i = _specLookup.Count - 1; i >= 0; i--)
            {
                ButtonSpecView specView = specLookups[i];

                // Is the button actually visible/enabled
                if (specView.ViewCenter.Visible &&
                    specView.ViewButton.Enabled)
                {
                    if (specView.ButtonSpec.Edge == align)
                    {
                        return(specView.ViewButton);
                    }
                }
            }

            return(null);
        }