Exemple #1
0
        private static void UpdateHelpStack()
        {
            needStackUpdate = false;

            foreach (Form f in EditorHelper.GetZSortedAppWindows())
            {
                if (!f.Visible)
                {
                    continue;
                }
                if (!new Rectangle(f.Location, f.Size).Contains(Cursor.Position))
                {
                    continue;
                }

                Point localPos = f.PointToClient(Cursor.Position);
                hoveredControl = f.GetChildAtPointDeep(localPos, GetChildAtPointSkip.Invisible | GetChildAtPointSkip.Transparent);
                break;
            }

            Control  c;
            HelpInfo help;

            // Get rid of disposed Controls
            c = hoveredHelpProvider as Control;
            if (c == null || c.IsDisposed)
            {
                hoveredHelpProvider = null;
                hoveredHelpCaptured = false;
            }

            // An IHelpProvider has captured the mouse: Ask what to do with it.
            if (hoveredHelpCaptured)
            {
                help = hoveredHelpProvider.ProvideHoverHelp(c.PointToClient(Cursor.Position), ref hoveredHelpCaptured);

                // Update provider's help info
                stack.UpdateFromProvider(hoveredHelpProvider, help);

                // If still in charge: Return early.
                if (hoveredHelpCaptured)
                {
                    return;
                }
            }

            // No IHelpProvider in charge: Find one that provides help
            help = null;
            IHelpProvider lastHelpProvider = hoveredHelpProvider;

            foreach (IHelpProvider hp in hoveredControl.GetControlAncestors <IHelpProvider>())
            {
                c    = hp as Control;
                help = hp.ProvideHoverHelp(c.PointToClient(Cursor.Position), ref hoveredHelpCaptured);
                hoveredHelpProvider = hp;
                if (help != null || hoveredHelpCaptured)
                {
                    break;
                }
            }

            // Update help system based on the result.
            if (lastHelpProvider != hoveredHelpProvider)
            {
                stack.UpdateFromProvider(lastHelpProvider, hoveredHelpProvider, help);
            }
            else if (hoveredHelpProvider != null)
            {
                stack.UpdateFromProvider(hoveredHelpProvider, help);
            }
        }
        HelpInfo IHelpProvider.ProvideHoverHelp(Point localPos, ref bool captured)
        {
            // A dropdown is opened. Provide dropdown help.
            IPopupControlHost dropdownEdit = this.FocusEditor as IPopupControlHost;

            if (dropdownEdit != null && dropdownEdit.IsDropDownOpened)
            {
                EnumPropertyEditor           enumEdit           = dropdownEdit as EnumPropertyEditor;
                FlaggedEnumPropertyEditor    enumFlagEdit       = dropdownEdit as FlaggedEnumPropertyEditor;
                ObjectSelectorPropertyEditor objectSelectorEdit = dropdownEdit as ObjectSelectorPropertyEditor;

                // Its able to provide help. Redirect.
                if (dropdownEdit is IHelpProvider)
                {
                    captured = true;
                    Point dropdownEditorPos = this.GetEditorLocation(dropdownEdit as PropertyEditor, true);
                    return((dropdownEdit as IHelpProvider).ProvideHoverHelp(new Point(localPos.X - dropdownEditorPos.X, localPos.Y - dropdownEditorPos.Y), ref captured));
                }
                // Special case: Its a known basic dropdown.
                else if (enumEdit != null)
                {
                    captured = true;
                    if (enumEdit.DropDownHoveredName != null)
                    {
                        return(HelpInfo.FromMember(enumEdit.EditedType.GetField(enumEdit.DropDownHoveredName, ReflectionHelper.BindAll)));
                    }
                    else
                    {
                        FieldInfo field = enumEdit.EditedType.GetField(enumEdit.DisplayedValue.ToString(), ReflectionHelper.BindAll);
                        if (field != null)
                        {
                            return(HelpInfo.FromMember(field));
                        }
                    }
                }
                else if (enumFlagEdit != null)
                {
                    captured = true;
                    if (enumFlagEdit.DropDownHoveredItem != null)
                    {
                        return(HelpInfo.FromMember(enumFlagEdit.EditedType.GetField(enumFlagEdit.DropDownHoveredItem.Caption, ReflectionHelper.BindAll)));
                    }
                    else
                    {
                        FieldInfo field = enumFlagEdit.EditedType.GetField(enumFlagEdit.DisplayedValue.ToString(), ReflectionHelper.BindAll);
                        if (field != null)
                        {
                            return(HelpInfo.FromMember(field));
                        }
                    }
                }
                else if (objectSelectorEdit != null)
                {
                    captured = true;
                    if (objectSelectorEdit.DropDownHoveredObject != null)
                    {
                        return(HelpInfo.FromObject(objectSelectorEdit.DropDownHoveredObject.Value));
                    }
                    else
                    {
                        return(HelpInfo.FromObject(objectSelectorEdit.DisplayedValue));
                    }
                }

                // No help available.
                return(null);
            }
            captured = false;

            // Pick an editor and see if it has access to an actual IHelpProvider
            PropertyEditor pickedEditor = this.PickEditorAt(localPos.X, localPos.Y, true);
            PropertyEditor helpEditor   = pickedEditor;

            while (helpEditor != null)
            {
                Point helpEditorPos = this.GetEditorLocation(helpEditor, true);
                if (helpEditor is IHelpProvider)
                {
                    IHelpProvider localProvider = helpEditor as IHelpProvider;
                    HelpInfo      localHelp     = localProvider.ProvideHoverHelp(new Point(localPos.X - helpEditorPos.X, localPos.Y - helpEditorPos.Y), ref captured);
                    if (localHelp != null)
                    {
                        return(localHelp);
                    }
                }
                helpEditor = helpEditor.ParentEditor;
            }

            // If not, default to member or type information
            if (pickedEditor != null)
            {
                if (!string.IsNullOrEmpty(pickedEditor.PropertyDesc))
                {
                    return(HelpInfo.FromText(pickedEditor.PropertyName, pickedEditor.PropertyDesc));
                }
                else if (pickedEditor.EditedMember != null)
                {
                    return(HelpInfo.FromMember(pickedEditor.EditedMember));
                }
                else if (pickedEditor.EditedType != null)
                {
                    return(HelpInfo.FromMember(pickedEditor.EditedType));
                }
            }

            return(null);
        }
Exemple #3
0
        private static void UpdateHelpStack()
        {
            needStackUpdate = false;

            // Retrieving all windows in a z-sorted way is a "time consuming" (~ 0.05ms) and API-heavy
            // query, and we don't need to be that accurate. Don't do it every time. Once a second is enough.
            bool updateGlobalWindows =
                globalWindows == null ||
                (DateTime.Now - lastGlobalWindowUpdate).TotalMilliseconds > 1000 ||
                globalWindows.Any(f => f.IsDisposed);

            if (updateGlobalWindows)
            {
                lastGlobalWindowUpdate = DateTime.Now;
                globalWindows          = EditorHelper.GetZSortedAppWindows();
            }

            // Iterate through our list of windows to find the one we're hovering
            foreach (Form form in globalWindows)
            {
                if (!form.Visible)
                {
                    continue;
                }
                if (!new Rectangle(form.Location, form.Size).Contains(Cursor.Position))
                {
                    continue;
                }

                Point localPos = form.PointToClient(Cursor.Position);
                hoveredControl = form.GetChildAtPointDeep(localPos, GetChildAtPointSkip.Invisible | GetChildAtPointSkip.Transparent);
                break;
            }

            Control  c;
            HelpInfo help;

            // Get rid of disposed Controls
            c = hoveredHelpProvider as Control;
            if (c == null || c.IsDisposed)
            {
                hoveredHelpProvider = null;
                hoveredHelpCaptured = false;
            }

            // An IHelpProvider has captured the mouse: Ask what to do with it.
            if (hoveredHelpCaptured)
            {
                help = hoveredHelpProvider.ProvideHoverHelp(c.PointToClient(Cursor.Position), ref hoveredHelpCaptured);

                // Update provider's help info
                stack.UpdateFromProvider(hoveredHelpProvider, help);

                // If still in charge: Return early.
                if (hoveredHelpCaptured)
                {
                    return;
                }
            }

            // No IHelpProvider in charge: Find one that provides help
            help = null;
            IHelpProvider lastHelpProvider = hoveredHelpProvider;

            foreach (IHelpProvider hp in hoveredControl.GetControlAncestors <IHelpProvider>())
            {
                c    = hp as Control;
                help = hp.ProvideHoverHelp(c.PointToClient(Cursor.Position), ref hoveredHelpCaptured);
                hoveredHelpProvider = hp;
                if (help != null || hoveredHelpCaptured)
                {
                    break;
                }
            }

            // Update help system based on the result.
            if (lastHelpProvider != hoveredHelpProvider)
            {
                stack.UpdateFromProvider(lastHelpProvider, hoveredHelpProvider, help);
            }
            else if (hoveredHelpProvider != null)
            {
                stack.UpdateFromProvider(hoveredHelpProvider, help);
            }
        }