Example #1
0
        // Generate a list of valid groups for a button: disallowing already-used groups
        // and also ancestors of earlier buttons and descendants of later buttons.
        // "context" is the button to generate the list for.
        // Pass null for the Add Group button.
        private List <GroupingType> GetRemainingGroupTypes(Button context)
        {
            List <GroupingType> remainingGroupTypes = new List <GroupingType>(potentialGroups);

            foreach (GroupingType customField in customFields)
            {
                remainingGroupTypes.Add(customField);
            }

            // Remove group types which are not relevant to any of the things being searched for.
            foreach (GroupingType gt in remainingGroupTypes.ToArray())
            {
                if (!WantGroupingType(gt))
                {
                    remainingGroupTypes.Remove(gt);
                }
            }

            int posRelativeToContext = -1;  // -1 for before; 0 for context itself; +1 for after

            foreach (Button button in groups)
            {
                if (button == context)
                {
                    posRelativeToContext = 0;
                }
                else if (posRelativeToContext == 0)
                {
                    posRelativeToContext = 1;
                }

                GroupingType groupType = button.Tag as GroupingType;
                if (groupType == null)
                {
                    continue;
                }

                // Remove the button type itself.
                remainingGroupTypes.Remove(groupType);
                // Also if we are still to the left of context, also remove ancestor types of this button;
                // conversely, if we are to the right of context, remove descendant types of this button.
                // Also having Folder on another button precludes all other choices.
                foreach (GroupingType gt in remainingGroupTypes.ToArray())
                {
                    if (posRelativeToContext == -1 && groupType.IsDescendantOf(gt) ||
                        posRelativeToContext == 1 && gt.IsDescendantOf(groupType) ||
                        posRelativeToContext != 0 && groupType is FolderGroupingType)
                    {
                        remainingGroupTypes.Remove(gt);
                    }
                }
            }

            return(remainingGroupTypes);
        }
Example #2
0
 public override bool IsDescendantOf(GroupingType gt)
 {
     return(gt == parent || (parent != null && parent.IsDescendantOf(gt)));
 }
Example #3
0
        void button_MouseMove(object sender, MouseEventArgs e)
        {
            if (draggedButton == null)
            {
                return;
            }

            Point OnScreen = draggedButton.PointToScreen(e.Location);

            if (!dragging && Math.Abs(clickPoint.X - OnScreen.X) < 5)
            {
                return;
            }

            dragging = true;

            draggedButton.BringToFront();

            // Now we need to figure out where to move it,
            // both on the screen and in the internal array of buttons.
            // We need to take into account which buttons we have dragged it past,
            // and which buttons it's allowed to pass given the grouping hierarchy.
            // Note that if buttons are already out of order (legacy configuration),
            // we don't force them back in order, but they can't get any worse.

            GroupingType draggedGroupType   = draggedButton.Tag as GroupingType;
            int          draggedButtonLeft  = draggedButton.Left;
            int          draggedButtonRight = draggedButton.Left + draggedButton.Width;
            int          draggedButtonIndex = groups.IndexOf(draggedButton);

            int offset       = 0;
            int leftBarrier  = -1;
            int swapWith     = -1;
            int rightBarrier = -1;

            Button[] groupsArray = groups.ToArray();
            foreach (Button candidateButton in groupsArray)
            {
                GroupingType candidateGroupType    = candidateButton.Tag as GroupingType;
                int          candidateButtonMiddle = offset + (candidateButton.Width / 2);
                int          candidateButtonIndex  = groups.IndexOf(candidateButton);

                if (draggedGroupType != null && candidateGroupType != null)
                {
                    if (candidateButtonIndex < draggedButtonIndex)
                    {
                        if (draggedGroupType.IsDescendantOf(candidateGroupType))
                        {
                            leftBarrier = candidateButtonIndex;
                        }
                    }
                    else if (candidateButtonIndex > draggedButtonIndex)
                    {
                        if (candidateGroupType.IsDescendantOf(draggedGroupType))
                        {
                            rightBarrier = candidateButtonIndex;
                        }
                    }
                }


                if (swapWith == -1 &&
                    candidateButtonMiddle > draggedButtonLeft &&
                    candidateButtonMiddle < draggedButtonRight)
                {
                    swapWith = candidateButtonIndex;
                }

                offset += candidateButton.Width + innerGutter;
            }

            Point InControl         = PointToClient(OnScreen);
            int   potentialLocation = InControl.X - dragOffset;

            bool movedLeft    = (swapWith >= 0 && swapWith < draggedButtonIndex);
            bool movedRight   = (swapWith >= 0 && swapWith > draggedButtonIndex);
            bool movedNeither = !movedLeft && !movedRight;

            if (movedRight || movedNeither)
            {
                int maxRight = 0;
                if (rightBarrier >= 0)
                {
                    if (swapWith >= 0 && swapWith >= rightBarrier)
                    {
                        swapWith = rightBarrier - 1;
                    }
                    maxRight = groupsArray[rightBarrier].Left - draggedButton.Width - innerGutter;
                }
                else if (groupsArray.Length >= 2)
                {
                    maxRight = groupsArray[groupsArray.Length - 2].Right + innerGutter;
                }

                if (potentialLocation > maxRight)
                {
                    potentialLocation = maxRight;
                }
            }
            if (movedLeft || movedNeither)
            {
                int maxLeft = 0;
                if (leftBarrier >= 0)
                {
                    if (swapWith >= 0 && swapWith <= leftBarrier)
                    {
                        swapWith = leftBarrier + 1;
                    }
                    maxLeft = groupsArray[leftBarrier].Right + innerGutter;
                }

                if (potentialLocation < maxLeft)
                {
                    potentialLocation = maxLeft;
                }
            }

            draggedButton.Left = potentialLocation;
            if (swapWith >= 0 && swapWith != draggedButtonIndex)
            {
                groups.Remove(draggedButton);
                groups.Insert(swapWith, draggedButton);
                Setup();
            }
        }