Example #1
0
        public FontFile.FontSize GetFontSize(float pixelsPreUnit)
        {
            var actualSize = MathUtils.Round(pixelsPreUnit * size);

            if (lastFontSize == null || lastFontSize.size != actualSize)
            {
                lastFontSize = fontFile.GetFontForSize(actualSize);
            }
            return(lastFontSize);
        }
Example #2
0
 private float GetCharacterPosition(int id, FontFile.FontSize fontSize, float max)
 {
     if (id == 0)
     {
         return(0);
     }
     if (id == text.Length)
     {
         return(max);
     }
     SDL_ttf.TTF_SizeUNICODE(fontSize.handle, text.Substring(0, id), out var w, out _);
     return(gui.PixelsToUnits(w));
 }
Example #3
0
        private unsafe int FindCaretIndex(string text, float position, FontFile.FontSize fontSize, float maxWidth)
        {
            if (string.IsNullOrEmpty(text) || position <= 0f)
            {
                return(0);
            }
            var cachedText = gui.textCache.GetCached((fontSize, text, uint.MaxValue));
            var maxW       = gui.PixelsToUnits(cachedText.texRect.w);
            var scale      = 1f;

            if (maxW > maxWidth)
            {
                scale = maxWidth / maxW;
                maxW  = maxWidth;
            }
            int min = 0, max = text.Length;
            var minW = 0f;

            if (position >= maxW)
            {
                return(max);
            }

            var handle = fontSize.handle;

            fixed(char *arr = text)
            {
                while (max > min + 1)
                {
                    var ratio = (maxW - position) / (maxW - minW);
                    var mid   = MathUtils.Clamp(MathUtils.Round(min * ratio + max * (1f - ratio)), min + 1, max - 1);
                    var prev  = arr[mid];
                    arr[mid] = '\0';
                    TTF_SizeUNICODE(handle, arr, out var w, out _);
                    arr[mid] = prev;
                    var midW = gui.PixelsToUnits(w) * scale;
                    if (midW > position)
                    {
                        max  = mid;
                        maxW = midW;
                    }
                    else
                    {
                        min  = mid;
                        minW = midW;
                    }
                }
            }

            return(maxW - position > position - minW ? min : max);
        }
Example #4
0
 private void GetTextParameters(string textToBuild, Rect textRect, FontFile.FontSize fontSize, RectAlignment alignment, out TextCache cachedText, out float scale, out float textWidth, out Rect realTextRect)
 {
     realTextRect = textRect;
     scale        = 1f;
     textWidth    = 0f;
     if (!string.IsNullOrEmpty(textToBuild))
     {
         cachedText = gui.textCache.GetCached((fontSize, textToBuild, uint.MaxValue));
         textWidth  = gui.PixelsToUnits(cachedText.texRect.w);
         if (textWidth > realTextRect.Width)
         {
             scale = realTextRect.Width / textWidth;
         }
         else
         {
             realTextRect = ImGui.AlignRect(textRect, alignment, textWidth, textRect.Height);
         }
     }
     else
     {
         realTextRect = ImGui.AlignRect(textRect, alignment, 0f, textRect.Height);
         cachedText   = null;
     }
 }
Example #5
0
        public bool BuildTextInput(string text, out string newText, string placeholder, FontFile.FontSize fontSize, bool delayed, Icon icon, Padding padding, RectAlignment alignment, SchemeColor color)
        {
            newText = text;
            Rect textRect, realTextRect;

            using (gui.EnterGroup(padding, RectAllocator.LeftRow))
            {
                var lineSize = gui.PixelsToUnits(fontSize.lineSize);
                if (icon != Icon.None)
                {
                    gui.BuildIcon(icon, lineSize, color + 3);
                }
                textRect = gui.RemainingRow(0.3f).AllocateRect(0, lineSize, RectAlignment.MiddleFullRow);
            }
            var boundingRect = gui.lastRect;
            var focused      = rect == boundingRect;

            if (focused && this.text == null)
            {
                this.text = text ?? "";
                SetCaret(0, this.text.Length);
            }

            switch (gui.action)
            {
            case ImGuiAction.MouseDown:
                if (gui.actionParameter != SDL.SDL_BUTTON_LEFT)
                {
                    break;
                }
                if (gui.ConsumeMouseDown(boundingRect))
                {
                    SetFocus(boundingRect, text ?? "");
                    GetTextParameters(this.text, textRect, fontSize, alignment, out _, out _, out _, out realTextRect);
                    SetCaret(FindCaretIndex(text, gui.mousePosition.X - realTextRect.X, fontSize, textRect.Width));
                }
                break;

            case ImGuiAction.MouseMove:
                if (focused && gui.actionParameter == SDL.SDL_BUTTON_LEFT)
                {
                    GetTextParameters(this.text, textRect, fontSize, alignment, out _, out _, out _, out realTextRect);
                    SetCaret(caret, FindCaretIndex(this.text, gui.mousePosition.X - realTextRect.X, fontSize, textRect.Width));
                }
                gui.ConsumeMouseOver(boundingRect, RenderingUtils.cursorCaret, false);
                break;

            case ImGuiAction.Build:
                var    textColor = color + 2;
                string textToBuild;
                if (focused)
                {
                    textToBuild = this.text;
                }
                else if (string.IsNullOrEmpty(text))
                {
                    textToBuild = placeholder;
                    textColor   = color + 3;
                }
                else
                {
                    textToBuild = text;
                }

                GetTextParameters(textToBuild, textRect, fontSize, alignment, out var cachedText, out var scale, out var textWidth, out realTextRect);
                if (cachedText != null)
                {
                    gui.DrawRenderable(realTextRect, cachedText, textColor);
                }

                if (focused)
                {
                    if (selectionAnchor != caret)
                    {
                        var left  = GetCharacterPosition(Math.Min(selectionAnchor, caret), fontSize, textWidth) * scale;
                        var right = GetCharacterPosition(Math.Max(selectionAnchor, caret), fontSize, textWidth) * scale;
                        gui.DrawRectangle(new Rect(left + realTextRect.X, realTextRect.Y, right - left, realTextRect.Height), SchemeColor.TextSelection);
                    }
                    else
                    {
                        if (nextCaretTimer <= Ui.time)
                        {
                            nextCaretTimer = Ui.time + 500;
                            caretVisible   = !caretVisible;
                        }
                        gui.SetNextRebuild(nextCaretTimer);
                        if (caretVisible)
                        {
                            var caretPosition = GetCharacterPosition(caret, fontSize, textWidth) * scale;
                            gui.DrawRectangle(new Rect(caretPosition + realTextRect.X - 0.05f, realTextRect.Y, 0.1f, realTextRect.Height), color + 2);
                        }
                    }
                }
                gui.DrawRectangle(boundingRect, color);
                break;
            }

            if (boundingRect == prevRect)
            {
                var changed = text != prevText;
                if (changed)
                {
                    newText = prevText;
                }
                prevRect = default;
                prevText = null;
                return(changed);
            }

            if (focused && !delayed && this.text != text)
            {
                newText = this.text;
                return(true);
            }

            return(false);
        }