Beispiel #1
0
        private Size measureTooltip(TooltipModel tooltip, Font titleFont)
        {
            string measuredContentText;

            if (!string.IsNullOrEmpty(tooltip.Title) && !string.IsNullOrEmpty(tooltip.Text))
            {
                measuredContentText = "\n" + tooltip.Text;
            }
            else
            {
                measuredContentText = tooltip.Text;
            }

            var formatFlags = TextFormatFlags.GlyphOverhangPadding | TextFormatFlags.WordBreak;

            if (!Runtime.IsMono)
            {
                formatFlags |= TextFormatFlags.NoPadding | TextFormatFlags.TextBoxControl;
            }

            var graphics = _tooltipTextbox.CreateGraphics();

            var baseSize = new Size(400, 300).ByDpi();

            Size titleSize;

            if (string.IsNullOrEmpty(tooltip.Title))
            {
                titleSize = new Size(0, 0);
            }
            else
            {
                titleSize = graphics.MeasureText(
                    tooltip.Title,
                    titleFont,
                    baseSize,
                    formatFlags);
            }

            Size contentSize;

            if (string.IsNullOrEmpty(measuredContentText))
            {
                contentSize = new Size(0, 0);
            }
            else
            {
                Graphics g = Runtime.IsMono ? null : graphics;
                contentSize = g.MeasureText(
                    measuredContentText,
                    _tooltipTextbox.Font,
                    baseSize,
                    formatFlags);
            }

            int contentWidth = Math.Max(titleSize.Width, contentSize.Width);

            // ideographic strings are under-measured
            Size cjkDelta = tooltip.Text.IsCjk()
                                ? new Size(32, 6).ByDpi()
                                : default;

            int clickableWidthDelta = Clickable
                                ? titleSize.Width + (int)(_buttonClose.Width * 1.25f) - TextPadding.Horizontal / 2 - contentWidth
                                : 0;

            var size = new Size(
                contentWidth + TextPadding.Horizontal + 2 + Math.Max(cjkDelta.Width, clickableWidthDelta),
                titleSize.Height + contentSize.Height + TextPadding.Vertical + cjkDelta.Height);

            if (Runtime.IsMono)
            {
                size += MonoLineInterval.MultiplyBy(measuredContentText.Count(_ => _ == '\n'));
            }

            return(size);
        }
Beispiel #2
0
        private Size measureTooltip(TooltipModel tooltip)
        {
            string measuredContentText;

            if (!string.IsNullOrEmpty(tooltip.Title) && !string.IsNullOrEmpty(tooltip.Text))
            {
                measuredContentText = "\n" + tooltip.Text;
            }
            else
            {
                measuredContentText = tooltip.Text;
            }

            const TextFormatFlags formatFlags =
                TextFormatFlags.GlyphOverhangPadding |
                TextFormatFlags.NoPadding |
                TextFormatFlags.TextBoxControl |
                TextFormatFlags.WordBreak;

            var graphics = _tooltipTextbox.CreateGraphics();

            var baseSize = new Size(400, 300).ByDpi();

            Size titleSize;

            if (string.IsNullOrEmpty(tooltip.Title))
            {
                titleSize = new Size(0, 0);
            }
            else
            {
                titleSize = graphics.MeasureText(
                    tooltip.Title,
                    new Font(_tooltipTextbox.Font, FontStyle.Bold),
                    baseSize,
                    formatFlags);
            }

            Size contentSize;

            if (string.IsNullOrEmpty(measuredContentText))
            {
                contentSize = new Size(0, 0);
            }
            else
            {
                contentSize = graphics.MeasureText(
                    measuredContentText,
                    _tooltipTextbox.Font,
                    baseSize,
                    formatFlags);
            }

            int contentWidth = Math.Max(titleSize.Width, contentSize.Width);

            // ideographic strings are under-measured
            Size cjkDelta = tooltip.Text.IsCjk()
                                ? new Size(32, 6).ByDpi()
                                : default;

            int clickableWidthDelta = Clickable
                                ? titleSize.Width + (int)(_buttonClose.Width * 1.25f) - TextPadding.Horizontal / 2 - contentWidth
                                : 0;

            var size = new Size(
                contentWidth + TextPadding.Horizontal + 2 + Math.Max(cjkDelta.Width, clickableWidthDelta),
                titleSize.Height + contentSize.Height + TextPadding.Vertical + cjkDelta.Height);

            return(size);
        }
Beispiel #3
0
        public void ShowTooltip(TooltipModel tooltip)
        {
            _tooltip             = tooltip;
            Clickable            = tooltip.Clickable;
            _buttonClose.Visible = Clickable;

            _tooltipTextbox.ResetText();
            Font titleFont = new Font(_tooltipTextbox.Font, FontStyle.Bold);

            if (!string.IsNullOrEmpty(tooltip.Title))
            {
                _tooltipTextbox.AppendText(tooltip.Title);
                _tooltipTextbox.Select(0, tooltip.Title.Length);
                _tooltipTextbox.SelectionFont = titleFont;
            }


            if (!string.IsNullOrWhiteSpace(tooltip.Text))
            {
                if (_tooltipTextbox.TextLength > 0)
                {
                    _tooltipTextbox.AppendText("\n\n");
                }

                var titleLength = _tooltipTextbox.TextLength;

                _tooltipTextbox.AppendText(tooltip.Text);

                if (tooltip.HighlightRanges != null)
                {
                    foreach (var range in tooltip.HighlightRanges)
                    {
                        _tooltipTextbox.SelectionStart  = titleLength + range.Index;
                        _tooltipTextbox.SelectionLength = range.Length;

                        if (range.IsContext)
                        {
                            _tooltipTextbox.SelectionBackColor = tooltip.HighlightOptions.HighlightContextColor;
                        }
                        else
                        {
                            _tooltipTextbox.SelectionBackColor = tooltip.HighlightOptions.HighlightColor;
                        }
                    }
                }
            }

            _tooltipTextbox.SelectionStart  = 0;
            _tooltipTextbox.SelectionLength = 0;

            var size         = measureTooltip(tooltip, titleFont);
            var screenBounds = tooltip.Control.RectangleToScreen(tooltip.ObjectBounds);

            var       parentForm = _tooltip.Control.ParentForm();
            Rectangle bounds;

            if (tooltip.UnderMouse)
            {
                bounds = new Rectangle(Cursor.Position - size.MultiplyBy(0.5f).Round(), size);
            }
            else
            {
                var cursor = tooltip.Cursor?.Invoke0(tooltip.Control.PointToScreen);
                bounds = allocateTooltip(
                    size,
                    screenBounds,
                    cursor,
                    TooltipMargin,
                    parentForm,
                    tooltip.PositionPreference?.Invoke(screenBounds));
            }

            if (tooltip.Clickable)
            {
                _tooltipTextbox.Cursor = Cursors.IBeam;
            }
            else
            {
                _tooltipTextbox.Cursor = Cursors.Arrow;
            }

            var parentFormPrev = this.ParentForm();

            if (parentForm != parentFormPrev)
            {
                parentFormPrev?.Controls.Remove(this);
                parentForm.Controls.Add(this);
            }

            Size     = bounds.Size;
            Location = parentForm.PointToClient(bounds.Location);
            Visible  = true;
            BringToFront();
        }
Beispiel #4
0
        public void ShowTooltip(TooltipModel tooltip)
        {
            _tooltip             = tooltip;
            Clickable            = tooltip.Clickable;
            _buttonClose.Visible = Clickable;

            var titleFont = new Font(_tooltipTextbox.Font, FontStyle.Bold);

            _tooltipTextbox.ResetText();
            if (!string.IsNullOrEmpty(tooltip.Title))
            {
                _tooltipTextbox.AppendText(tooltip.Title);
                _tooltipTextbox.Select(0, tooltip.Title.Length);
                _tooltipTextbox.SelectionFont = titleFont;
            }


            if (!string.IsNullOrWhiteSpace(tooltip.Text))
            {
                if (_tooltipTextbox.TextLength > 0)
                {
                    _tooltipTextbox.AppendText("\n\n");
                }

                var titleLength = _tooltipTextbox.TextLength;

                _tooltipTextbox.AppendText(tooltip.Text);

                if (tooltip.HighlightRanges != null)
                {
                    foreach (var range in tooltip.HighlightRanges)
                    {
                        _tooltipTextbox.SelectionStart  = titleLength + range.Index;
                        _tooltipTextbox.SelectionLength = range.Length;

                        if (range.IsContext)
                        {
                            _tooltipTextbox.SelectionBackColor = tooltip.HighlightOptions.HighlightContextColor;
                        }
                        else
                        {
                            _tooltipTextbox.SelectionBackColor = tooltip.HighlightOptions.HighlightColor;
                        }
                    }
                }
            }

            _tooltipTextbox.SelectionStart  = 0;
            _tooltipTextbox.SelectionLength = 0;

            var size         = measureTooltip(tooltip);
            var screenBounds = tooltip.Control.RectangleToScreen(tooltip.ObjectBounds);
            var cursor       = tooltip.Cursor?.Invoke0(tooltip.Control.PointToScreen);
            var bounds       = allocateTooltip(size, screenBounds, cursor, TooltipMargin, tooltip.PositionPreference?.Invoke(screenBounds));

            if (_tooltipTextbox.Focused)
            {
                _tooltipFocusTarget.Focus();
            }

            if (tooltip.Clickable)
            {
                _tooltipTextbox.Cursor = Cursors.IBeam;
            }
            else
            {
                _tooltipTextbox.Cursor = Cursors.Arrow;
            }

            Size = bounds.Size;
            Application.DoEvents();
            Location = bounds.Location;
        }
Beispiel #5
0
        private void mouseMove(object sender, MouseEventArgs e)
        {
            var command = _control.GetCommand(e.Location, MouseButtons.None);

            if (!command.HasValue)
            {
                Hide?.Invoke();
                return;
            }

            var property = _control.Properties[command.Value.ButtonIndex];

            if (string.IsNullOrEmpty(property))
            {
                Hide?.Invoke();
                return;
            }

            var bounds = _control.GetPaintingRectangle(command.Value.ButtonIndex, command.Value.ClickedState);

            var model = new TooltipModel
            {
                Id                 = "qf." + property,
                Control            = _control,
                ObjectBounds       = bounds,
                Cursor             = bounds.Center(),
                Text               = property,
                PositionPreference = getPositionPreference
            };

            Show?.Invoke(model);

            Func <ExtremumFinder <TooltipPosition>, ExtremumFinder <TooltipPosition> > getPositionPreference(Rectangle target)
            {
                Func <TooltipPosition, int> verticalDistanceFrom(Rectangle t) =>
                c =>
                {
                    int dy = c.Bounds.CenterY() - t.CenterY();

                    return(PreferTooltipFromTop
                                                        ? Math.Abs((-dy).MultiplyIfNegative(1.5f))
                                                        : Math.Abs(dy.MultiplyIfNegative(1.5f)));
                };

                Func <TooltipPosition, int> horizontalDistanceFrom(Rectangle t) =>
                c =>
                {
                    int dx = c.Bounds.CenterX() - t.CenterX();

                    return(PreferTooltipFromLeft
                                                        ? Math.Abs((-dx).MultiplyIfNegative(1.5f))
                                                        : Math.Abs(dx.MultiplyIfNegative(1.5f)));
                };

                if (PreferHorizontalShift)
                {
                    return(_ => _
                           .ThenAtMin(verticalDistanceFrom(target))
                           .ThenAtMin(c => PreferTooltipFromLeft ? c.Bounds.X : -c.Bounds.X));
                }
                else
                {
                    return(_ => _
                           .ThenAtMin(horizontalDistanceFrom(target))
                           .ThenAtMin(c => PreferTooltipFromTop ? c.Bounds.Y : -c.Bounds.Y));
                }
            }
        }
Beispiel #6
0
        private Size measureTooltip(TooltipModel tooltip)
        {
            string measuredContentText;

            if (!string.IsNullOrEmpty(tooltip.Title) && !string.IsNullOrEmpty(tooltip.Text))
            {
                measuredContentText = "\n" + tooltip.Text;
            }
            else
            {
                measuredContentText = tooltip.Text;
            }

            const TextFormatFlags formatFlags = TextFormatFlags.GlyphOverhangPadding |
                                                TextFormatFlags.NoPadding |
                                                TextFormatFlags.Left |
                                                TextFormatFlags.TextBoxControl |
                                                TextFormatFlags.WordBreak;

            var graphics = _tooltipTextbox.CreateGraphics();

            Size titleSize;

            if (string.IsNullOrEmpty(tooltip.Title))
            {
                titleSize = new Size(0, 0);
            }
            else
            {
                titleSize = graphics.MeasureText(
                    tooltip.Title,
                    new Font(_tooltipTextbox.Font, FontStyle.Bold),
                    _tooltipTextbox.Size,
                    formatFlags);
            }

            Size contentSize;

            if (string.IsNullOrEmpty(measuredContentText))
            {
                contentSize = new Size(0, 0);
            }
            else
            {
                contentSize = graphics.MeasureText(
                    measuredContentText,
                    _tooltipTextbox.Font,
                    _tooltipTextbox.Size,
                    formatFlags);
            }

            int contentWidth = Math.Max(titleSize.Width, contentSize.Width);

            // ideographic strings are under-measured
            int cjkTermH = tooltip.Text.IsCjk() ? 32 : 0;

            if (Clickable)
            {
                cjkTermH = Math.Max(cjkTermH, titleSize.Width - contentWidth + (int)(_buttonClose.Width * 1.25f) - TextPadding);
            }

            int cjkTermV = tooltip.Text.IsCjk() ? 6 : 0;

            var cjkTermSize = new Size(cjkTermH, cjkTermV).ByDpi();

            var size = new Size(
                contentWidth + _tooltipTextbox.Margin.Horizontal + 2 + cjkTermSize.Width,
                titleSize.Height + contentSize.Height + _tooltipTextbox.Margin.Vertical + cjkTermSize.Height);

            return(size);
        }
        private void showFieldTooltip(Point position)
        {
            var cursorPosition = _view.PointToClient(position);
            var hitInfo        = _view.CalcHitInfo(cursorPosition);

            var dataSource = _view.FindRow(hitInfo.RowHandle);

            if (!hitInfo.AlignButtonDirection.HasValue && (dataSource == null || !hitInfo.FieldBounds.HasValue))
            {
                Hide?.Invoke();
                return;
            }

            if (hitInfo.IsSortButton)
            {
                Show?.Invoke(new TooltipModel
                {
                    Id           = $"{_view.Name}.{hitInfo.RowHandle}.{hitInfo.FieldName}.sort",
                    ObjectBounds = hitInfo.ButtonBounds,
                    Control      = _view,
                    Title        = "Sort by " + hitInfo.FieldName,
                    Text         =
                        "Click to sort by this field.\r\n" +
                        "\r\n" +
                        "Shift+Click to ADD this field to sorting. Currently sorted fields will have higher sort priority.\r\n" +
                        "\r\n" +
                        "Ctrl+Click to REMOVE this field from sorting. Other fields sort order will remain unchanged.\r\n" +
                        "\r\n" +
                        "Repeated click on sort button cycles sort order between Ascending, Descending, None.\r\n" +
                        "\r\n" +
                        "Hold Alt key when hovering to prevent showing this button. Helps selecting text in small fields.",
                    Clickable = false
                });
            }
            else
            {
                if (hitInfo.IsSearchButton)
                {
                    throw new NotSupportedException();
                }

                if (hitInfo.CustomButtonIndex >= 0)
                {
                    var tooltip = new TooltipModel
                    {
                        Id           = $"{_view.Name}.{hitInfo.RowHandle}.{hitInfo.FieldName}.",
                        ObjectBounds = hitInfo.ButtonBounds,
                        Control      = _view,
                        Clickable    = false
                    };

                    if (hitInfo.CustomButtonIndex == DeckListLayout.CustomButtonAdd)
                    {
                        tooltip.Id  += "add";
                        tooltip.Text = "Save this deck";
                    }
                    else if (hitInfo.CustomButtonIndex == DeckListLayout.CustomButtonRemove)
                    {
                        tooltip.Id   += "remove";
                        tooltip.Title = "Remove this deck";
                        tooltip.Text  = "Removes this deck from the list.\r\n" +
                                        "NOTE: be careful, you cannot undo this.";
                    }
                    else if (hitInfo.CustomButtonIndex == DeckListLayout.CustomButtonRename)
                    {
                        tooltip.Id  += "rename";
                        tooltip.Text = "Rename this deck";
                    }
                    else if (hitInfo.CustomButtonIndex == DeckListLayout.CustomButtonOpen)
                    {
                        tooltip.Id   += "open";
                        tooltip.Title = "Open this deck";
                        tooltip.Text  = "Relaces currently opened deck with this one";
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }

                    Show?.Invoke(tooltip);
                }
                else if (hitInfo.AlignButtonDirection.HasValue)
                {
                    Show?.Invoke(new TooltipModel
                    {
                        Id           = $"{_view.Name}.{hitInfo.RowHandle}.{hitInfo.FieldName}.align",
                        ObjectBounds = _view.GetAlignButtonBounds(hitInfo),
                        Control      = _view,
                        Title        = "Viewport alignment",
                        Text         = "Aligns viewport by this corner.\r\n" +
                                       "\r\n" +
                                       "If this corner would be truncated\r\n" +
                                       "viewport will shift to fit it into the screen.",
                        Clickable = false
                    });
                }
                else if (hitInfo.FieldName != null)
                {
                    Show?.Invoke(new TooltipModel
                    {
                        Id               = $"{_view.Name}.{hitInfo.RowHandle}.{hitInfo.FieldName}",
                        ObjectBounds     = hitInfo.FieldBounds.Value,
                        Control          = _view,
                        Title            = hitInfo.FieldName,
                        Text             = _view.GetText(hitInfo.RowHandle, hitInfo.FieldName),
                        HighlightRanges  = _view.GetHighlihgtTextRanges(hitInfo.RowHandle, hitInfo.FieldName),
                        HighlightOptions = _view.ProbeCard.HighlightOptions,
                        Clickable        = true
                    });
                }
            }
        }
Beispiel #8
0
        private void showFieldTooltip(Point position)
        {
            var cursorPosition = _view.PointToClient(position);
            var hitInfo        = _view.CalcHitInfo(cursorPosition);

            var dataSource = _view.FindRow(hitInfo.RowHandle);

            if (!hitInfo.AlignButtonDirection.HasValue && (dataSource == null || !hitInfo.FieldBounds.HasValue))
            {
                Hide?.Invoke();
                return;
            }

            if (hitInfo.IsSortButton)
            {
                Show?.Invoke(new TooltipModel
                {
                    Id           = $"{_view.Name}.{hitInfo.RowHandle}.{hitInfo.FieldName}.sort",
                    ObjectBounds = hitInfo.ButtonBounds,
                    Control      = _view,
                    Title        = "Sort by " + hitInfo.FieldName,
                    Text         =
                        "Click to sort by this field.\r\n" +
                        "\r\n" +
                        "Shift+Click to ADD this field to sorting. Currently sorted fields will have higher sort priority.\r\n" +
                        "\r\n" +
                        "Ctrl+Click to REMOVE this field from sorting. Other fields sort order will remain unchanged.\r\n" +
                        "\r\n" +
                        "Repeated click on sort button cycles sort order between Ascending, Descending, None.\r\n" +
                        "\r\n" +
                        "Hold Alt key when hovering to prevent showing this button. Helps selecting text in small fields.",
                    Clickable = false
                });
            }
            else
            {
                if (hitInfo.IsSearchButton)
                {
                    _log.Error("Search button tooltip is not supported in DeckList layout view");
                    return;
                }

                if (hitInfo.CustomButtonIndex >= 0)
                {
                    var tooltip = new TooltipModel
                    {
                        Id           = $"{_view.Name}.{hitInfo.RowHandle}.{hitInfo.FieldName}.",
                        ObjectBounds = hitInfo.ButtonBounds,
                        Control      = _view,
                        Clickable    = false
                    };

                    if (hitInfo.IsAddButton())
                    {
                        tooltip.Id  += "add";
                        tooltip.Text = "Save this deck";
                    }
                    else if (hitInfo.IsRemoveButton())
                    {
                        tooltip.Id   += "remove";
                        tooltip.Title = "Remove this deck";
                        tooltip.Text  = "Removes this deck from the list.\r\n" +
                                        "NOTE: be careful, you cannot undo this.";
                    }
                    else if (hitInfo.IsRenameButton())
                    {
                        tooltip.Id  += "rename";
                        tooltip.Text = "Rename this deck";
                    }
                    else if (hitInfo.IsOpenButton())
                    {
                        tooltip.Id   += "open";
                        tooltip.Title = "Open deck";
                        tooltip.Text  = "Open the deck in it's original form as it was edited and saved.\r\n\r\n" +
                                        "Left-click to open in this tab, currently opened deck will be replaced.\r\n" +
                                        "Middle-click to open in new tab.\r\n\r\n";
                    }
                    else if (hitInfo.IsOpenTransformedButton())
                    {
                        tooltip.Id   += "open_transformed";
                        tooltip.Title = "Open transformed deck";
                        tooltip.Text  = "Transformed deck uses cards from your collection and cards with known price whenever possible.\r\n\r\n" +
                                        "Left-click to open in this tab, currently opened deck will be replaced.\r\n" +
                                        "Middle-click to open in new tab.\r\n\r\n";
                    }
                    else
                    {
                        return;
                    }

                    Show?.Invoke(tooltip);
                }
                else if (hitInfo.AlignButtonDirection.HasValue)
                {
                    Show?.Invoke(new TooltipModel
                    {
                        Id           = $"{_view.Name}.{hitInfo.RowHandle}.{hitInfo.FieldName}.align",
                        ObjectBounds = _view.GetAlignButtonBounds(hitInfo),
                        Control      = _view,
                        Title        = "Viewport alignment",
                        Text         = "Aligns viewport by this corner.\r\n" +
                                       "\r\n" +
                                       "If this corner would be truncated\r\n" +
                                       "viewport will shift to fit it into the screen.",
                        Clickable = false
                    });
                }
                else if (hitInfo.FieldName != null)
                {
                    Show?.Invoke(new TooltipModel
                    {
                        Id               = $"{_view.Name}.{hitInfo.RowHandle}.{hitInfo.FieldName}",
                        ObjectBounds     = hitInfo.FieldBounds.Value,
                        Control          = _view,
                        Title            = hitInfo.FieldName,
                        Text             = _view.GetText(hitInfo.RowHandle, hitInfo.FieldName),
                        HighlightRanges  = _view.GetHighlightTextRanges(hitInfo.RowHandle, hitInfo.FieldName),
                        HighlightOptions = _view.HighlightOptions,
                        Clickable        = true
                    });
                }
            }
        }