Example #1
0
        /// <summary>
        /// Creates a new GUI Element List Menu
        /// </summary>
        /// <param name="capi">The Client API.</param>
        /// <param name="values">The values of the list.</param>
        /// <param name="names">The names for each of the values.</param>
        /// <param name="selectedIndex">The default selected index.</param>
        /// <param name="onSelectionChanged">The event fired when the selection is changed.</param>
        /// <param name="bounds">The bounds of the GUI element.</param>
        public GuiElementListMenu(ICoreClientAPI capi, string[] values, string[] names, int selectedIndex, SelectionChangedDelegate onSelectionChanged, ElementBounds bounds, CairoFont font, bool multiSelect) : base(capi, "", font, bounds)
        {
            if (values.Length != names.Length)
            {
                throw new ArgumentException("Values and Names arrays must be of the same length!");
            }

            hoverTexture     = new LoadedTexture(capi);
            dropDownTexture  = new LoadedTexture(capi);
            scrollbarTexture = new LoadedTexture(capi);

            this.Values             = values;
            this.Names              = names;
            this.SelectedIndex      = selectedIndex;
            this.multiSelect        = multiSelect;
            this.onSelectionChanged = onSelectionChanged;
            HoveredIndex            = selectedIndex;

            ElementBounds scrollbarBounds = ElementBounds.Fixed(0, 0, 0, 0).WithEmptyParent();

            scrollbar = new GuiElementCompactScrollbar(api, OnNewScrollbarValue, scrollbarBounds);



            richtTextElem = new GuiElementRichtext[values.Length];
            for (int i = 0; i < values.Length; i++)
            {
                ElementBounds textBounds = ElementBounds.Fixed(0, 0, 700, 100).WithEmptyParent();
                richtTextElem[i] = new GuiElementRichtext(capi, new RichTextComponentBase[0], textBounds);
            }
        }
Example #2
0
        /// <summary>
        /// Creates a new title bar.
        /// </summary>
        /// <param name="capi">The Client API.</param>
        /// <param name="text">The text on the title bar.</param>
        /// <param name="composer">The GuiComposer for the title bar.</param>
        /// <param name="OnClose">The event fired when the title bar is closed.</param>
        /// <param name="font">The font of the title bar.</param>
        /// <param name="bounds">The bounds of the title bar.</param>
        public GuiElementDialogTitleBar(ICoreClientAPI capi, string text, GuiComposer composer, Action OnClose = null, CairoFont font = null, ElementBounds bounds = null) : base(capi, text, font, bounds)
        {
            closeIconHoverTexture = new LoadedTexture(capi);
            menuIconHoverTexture  = new LoadedTexture(capi);

            if (bounds == null)
            {
                this.Bounds = ElementStdBounds.TitleBar();
            }
            if (font == null)
            {
                this.Font = CairoFont.WhiteSmallText();
            }
            this.OnClose = OnClose;

            ElementBounds dropDownBounds = ElementBounds.Fixed(0, 0, 100, 25);

            this.Bounds.WithChild(dropDownBounds);

            listMenu = new GuiElementListMenu(capi, new string[] { "auto", "manual" }, new string[] { Lang.Get("Fixed"), Lang.Get("Movable") }, 0, onSelectionChanged, dropDownBounds, CairoFont.WhiteSmallText(), false)
            {
                HoveredIndex = 0
            };

            baseComposer = composer;
        }
        public ItemstackComponentBase(ICoreClientAPI capi) : base(capi)
        {
            this.capi = capi;

            dummyInv = new DummyInventory(capi);
            dummyInv.OnAcquireTransitionSpeed = (transType, stack, mul) =>
            {
                return(0);
            };
            renderedTooltipSlot = new DummySlot(null, dummyInv);

            stackInfoBounds =
                ElementBounds
                .FixedSize(EnumDialogArea.None, GuiElementItemstackInfo.BoxWidth, 0)
                .WithFixedPadding(10)
                .WithFixedPosition(20, 40)
            ;

            parentBounds = ElementBounds.Fixed(0, 0, 1, 1);
            parentBounds.WithParent(ElementBounds.Empty);
            stackInfoBounds.WithParent(parentBounds);

            stackInfo = new GuiElementItemstackInfo(capi, stackInfoBounds, OnRequireInfoText);
            stackInfo.SetSourceSlot(renderedTooltipSlot);
            stackInfo.ComposeElements(null, null);
            stackInfo.RecompCheckIgnoredStackAttributes = GlobalConstants.IgnoredStackAttributes;
        }
Example #4
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="capi">The client API</param>
        /// <param name="values">The values of the strings.</param>
        /// <param name="names">The names of the strings.</param>
        /// <param name="selectedIndex">The default selected index.</param>
        /// <param name="onSelectionChanged">The event that occurs when the selection is changed.</param>
        /// <param name="bounds">The bounds of the drop down.</param>
        public GuiElementDropDown(ICoreClientAPI capi, string[] values, string[] names, int selectedIndex, SelectionChangedDelegate onSelectionChanged, ElementBounds bounds, CairoFont font, bool multiSelect) : base(capi, "", font, bounds)
        {
            highlightTexture        = new LoadedTexture(capi);
            currentValueTexture     = new LoadedTexture(capi);
            arrowDownButtonReleased = new LoadedTexture(capi);
            arrowDownButtonPressed  = new LoadedTexture(capi);

            listMenu = new GuiElementListMenu(capi, values, names, selectedIndex, didSelect, bounds, font, multiSelect)
            {
                HoveredIndex = selectedIndex
            };

            ElementBounds textBounds = ElementBounds.Fixed(0, 0, 900, 100).WithEmptyParent();

            richTextElem = new GuiElementRichtext(capi, new RichTextComponentBase[0], textBounds);

            this.onSelectionChanged = onSelectionChanged;
            this.multiSelect        = multiSelect;
        }
        public override void ComposeElements(Context ctx, ImageSurface surface)
        {
            Bounds.CalcWorldBounds();

            if (drawBackground)
            {
                ctx.SetSourceRGBA(1, 1, 1, 0.6);
                ElementRoundRectangle(ctx, Bounds);
                ctx.Fill();
                EmbossRoundRectangleElement(ctx, Bounds, true);
            }

            double absSlotSize = scaled(unscaledSlotSize);

            ElementBounds textBounds = ElementBounds
                                       .Fixed(0, unscaledSlotSize - GuiStyle.SmallFontSize - 2, unscaledSlotSize - 5, unscaledSlotSize - 5)
                                       .WithEmptyParent();

            CairoFont font = CairoFont.WhiteSmallText();

            font.FontWeight = FontWeight.Bold;
            textComposer    = new GuiElementStaticText(api, "", EnumTextOrientation.Right, textBounds, font);
        }
Example #6
0
        void Recompose()
        {
            if (curSlot?.Itemstack == null)
            {
                return;
            }

            readyToRender = false;

            string title = curSlot.GetStackName();
            string desc  = OnRequireInfoText(curSlot);

            desc.TrimEnd();


            titleElement.SetNewText(title, titleFont);
            descriptionElement.SetNewText(desc, Font);

            RecalcBounds(title, desc);


            Bounds.CalcWorldBounds();

            ElementBounds textBounds = Bounds.CopyOnlySize();

            textBounds.CalcWorldBounds();

            TyronThreadPool.QueueTask(() =>
            {
                /*int i = 0;
                 * while (i < 5 && titleElement.HalfComposed) System.Threading.Thread.Sleep(5);*/

                ImageSurface surface = new ImageSurface(Format.Argb32, Bounds.OuterWidthInt, Bounds.OuterHeightInt);
                Context ctx          = genContext(surface);

                ctx.SetSourceRGBA(0, 0, 0, 0);
                ctx.Paint();

                ctx.SetSourceRGBA(backTint[0], backTint[1], backTint[2], backTint[3]);
                RoundRectangle(ctx, textBounds.bgDrawX, textBounds.bgDrawY, textBounds.OuterWidthInt, textBounds.OuterHeightInt, GuiStyle.DialogBGRadius);
                ctx.FillPreserve();

                ctx.SetSourceRGBA(GuiStyle.DialogLightBgColor[0] * 1.4, GuiStyle.DialogStrongBgColor[1] * 1.4, GuiStyle.DialogStrongBgColor[2] * 1.4, 1);
                ctx.LineWidth = 3 * 1.75;
                ctx.StrokePreserve();
                surface.Blur(8.2);

                ctx.SetSourceRGBA(backTint[0] / 2, backTint[1] / 2, backTint[2] / 2, backTint[3]);
                ctx.Stroke();


                int w = (int)(scaled(ItemStackSize) + scaled(40));
                int h = (int)(scaled(ItemStackSize) + scaled(40));

                ImageSurface shSurface = new ImageSurface(Format.Argb32, w, h);
                Context shCtx          = genContext(shSurface);

                shCtx.SetSourceRGBA(GuiStyle.DialogSlotBackColor);
                RoundRectangle(shCtx, 0, 0, w, h, 0);
                shCtx.FillPreserve();

                shCtx.SetSourceRGBA(GuiStyle.DialogSlotFrontColor);
                shCtx.LineWidth = 5;
                shCtx.Stroke();
                shSurface.Blur(7);
                shSurface.Blur(7);
                shSurface.Blur(7);
                EmbossRoundRectangleElement(shCtx, 0, 0, w, h, true);


                ctx.SetSourceSurface(shSurface, (int)(textBounds.drawX), (int)(textBounds.drawY + scaled(MarginTop)));
                ctx.Rectangle(textBounds.drawX, textBounds.drawY + scaled(MarginTop), w, h);
                ctx.Fill();

                shCtx.Dispose();
                shSurface.Dispose();


                api.Event.EnqueueMainThreadTask(() =>
                {
                    //titleElement.genTexture();
                    //descriptionElement.genTexture();

                    titleElement.Compose(false);
                    descriptionElement.Compose(false);

                    generateTexture(surface, ref texture);

                    ctx.Dispose();
                    surface.Dispose();

                    double offset = (int)(30 + ItemStackSize / 2);
                    scissorBounds = ElementBounds.Fixed(4 + offset - ItemStackSize, 2 + offset + MarginTop - ItemStackSize, ItemStackSize + 38, ItemStackSize + 38).WithParent(Bounds);
                    scissorBounds.CalcWorldBounds();

                    readyToRender = true;
                }, "genstackinfotexture");
            });
        }
        void ComposeInteractiveElements()
        {
            slotBounds           = new ElementBounds[availableSlots.Count];
            scissorBounds        = new ElementBounds[availableSlots.Count];
            slotQuantityTextures = new LoadedTexture[availableSlots.Count];
            for (int k = 0; k < slotQuantityTextures.Length; k++)
            {
                slotQuantityTextures[k] = new LoadedTexture(this.api);
            }

            this.rows = (int)Math.Ceiling(1f * availableSlots.Count / cols);

            Bounds.CalcWorldBounds();

            double unscaledSlotWidth  = GuiElementPassiveItemSlot.unscaledSlotSize;
            double unscaledSlotHeight = GuiElementPassiveItemSlot.unscaledSlotSize;

            // Slot sizes
            double absSlotPadding = scaled(unscaledSlotPadding);
            double absSlotWidth   = scaled(GuiElementPassiveItemSlot.unscaledSlotSize);
            double absSlotHeight  = scaled(GuiElementPassiveItemSlot.unscaledSlotSize);

            ElementBounds textBounds = ElementBounds
                                       .Fixed(0, GuiElementPassiveItemSlot.unscaledSlotSize - GuiStyle.SmallishFontSize - 2, GuiElementPassiveItemSlot.unscaledSlotSize - 5, GuiElementPassiveItemSlot.unscaledSlotSize - 5)
                                       .WithEmptyParent();

            CairoFont font = CairoFont.WhiteSmallText().WithFontSize((float)GuiStyle.SmallishFontSize);

            font.FontWeight  = FontWeight.Bold;
            font.Color       = new double[] { 1, 1, 1, 1 };
            font.StrokeColor = new double[] { 0, 0, 0, 1 };
            font.StrokeWidth = RuntimeEnv.GUIScale;

            textComposer = new GuiElementStaticText(api, "", EnumTextOrientation.Right, textBounds, font);


            // 1. draw generic slot
            ImageSurface slotSurface = new ImageSurface(Format.Argb32, (int)absSlotWidth, (int)absSlotWidth);
            Context      slotCtx     = genContext(slotSurface);

            slotCtx.SetSourceRGBA(GuiStyle.DialogSlotBackColor);
            RoundRectangle(slotCtx, 0, 0, absSlotWidth, absSlotHeight, GuiStyle.ElementBGRadius);
            slotCtx.Fill();

            slotCtx.SetSourceRGBA(GuiStyle.DialogSlotFrontColor);
            RoundRectangle(slotCtx, 0, 0, absSlotWidth, absSlotHeight, GuiStyle.ElementBGRadius);
            slotCtx.LineWidth = scaled(4.5);
            slotCtx.Stroke();
            slotSurface.Blur(scaled(4), true);
            slotSurface.Blur(scaled(4), true);

            RoundRectangle(slotCtx, 0, 0, absSlotWidth, absSlotHeight, 1);
            slotCtx.LineWidth = scaled(4.5);
            slotCtx.SetSourceRGBA(0, 0, 0, 0.8);
            slotCtx.Stroke();



            generateTexture(slotSurface, ref slotTexture, true);

            slotCtx.Dispose();
            slotSurface.Dispose();

            // 2. draw slots with backgrounds
            foreach (var val in availableSlots)
            {
                ItemSlot slot = val.Value;
                string   key  = slot.BackgroundIcon + "-" + slot.HexBackgroundColor;

                if ((slot.BackgroundIcon == null && slot.HexBackgroundColor == null) || slotTextureIdsByBgIconAndColor.ContainsKey(key))
                {
                    continue;
                }


                slotSurface = new ImageSurface(Format.Argb32, (int)absSlotWidth, (int)absSlotWidth);
                slotCtx     = genContext(slotSurface);

                if (slot.HexBackgroundColor != null)
                {
                    double[] bgcolor = ColorUtil.Hex2Doubles(slot.HexBackgroundColor);

                    slotCtx.SetSourceRGBA(bgcolor);
                    RoundRectangle(slotCtx, 0, 0, absSlotWidth, absSlotHeight, GuiStyle.ElementBGRadius);
                    slotCtx.Fill();

                    slotCtx.SetSourceRGBA(bgcolor[0] * 0.25, bgcolor[1] * 0.25, bgcolor[2] * 0.25, 1);
                    RoundRectangle(slotCtx, 0, 0, absSlotWidth, absSlotHeight, GuiStyle.ElementBGRadius);
                    slotCtx.LineWidth = scaled(4.5);
                    slotCtx.Stroke();
                    slotSurface.Blur(scaled(4), true);
                    slotSurface.Blur(scaled(4), true);

                    slotCtx.SetSourceRGBA(0, 0, 0, 0.8);
                    RoundRectangle(slotCtx, 0, 0, absSlotWidth, absSlotHeight, 1);
                    slotCtx.LineWidth = scaled(4.5);
                    slotCtx.Stroke();
                }
                else
                {
                    slotCtx.SetSourceRGBA(GuiStyle.DialogSlotBackColor);
                    RoundRectangle(slotCtx, 0, 0, absSlotWidth, absSlotHeight, GuiStyle.ElementBGRadius);
                    slotCtx.Fill();

                    slotCtx.SetSourceRGBA(GuiStyle.DialogSlotFrontColor);
                    RoundRectangle(slotCtx, 0, 0, absSlotWidth, absSlotHeight, GuiStyle.ElementBGRadius);
                    slotCtx.LineWidth = scaled(4.5);
                    slotCtx.Stroke();
                    slotSurface.Blur(scaled(4), true);
                    slotSurface.Blur(scaled(4), true);

                    RoundRectangle(slotCtx, 0, 0, absSlotWidth, absSlotHeight, 1);
                    slotCtx.LineWidth = scaled(4.5);
                    slotCtx.SetSourceRGBA(0, 0, 0, 0.8);
                    slotCtx.Stroke();
                }


                if (slot.BackgroundIcon != null)
                {
                    DrawIconHandler?.Invoke(
                        slotCtx, slot.BackgroundIcon, 2 * (int)absSlotPadding, 2 * (int)absSlotPadding,
                        (int)(absSlotWidth - 4 * absSlotPadding), (int)(absSlotHeight - 4 * absSlotPadding),
                        new double[] { 0, 0, 0, 0.2 }
                        );
                }

                int texId = 0;
                generateTexture(slotSurface, ref texId, true);

                slotCtx.Dispose();
                slotSurface.Dispose();

                slotTextureIdsByBgIconAndColor[key] = texId;
            }

            // 3. Crossed out overlay
            int csize = (int)absSlotWidth - 4;

            slotSurface = new ImageSurface(Format.Argb32, (int)csize, (int)csize);
            slotCtx     = genContext(slotSurface);

            slotCtx.SetSourceRGBA(0, 0, 0, 0.8);
            api.Gui.Icons.DrawCross(slotCtx, 4, 4, 7, csize - 18, true);
            slotCtx.SetSourceRGBA(1, 0.2, 0.2, 0.8);
            slotCtx.LineWidth = 2;
            slotCtx.Stroke();
            generateTexture(slotSurface, ref crossedOutTexture);
            slotCtx.Dispose();
            slotSurface.Dispose();


            // 4. Slot highlight overlay
            slotSurface = new ImageSurface(Format.Argb32, (int)absSlotWidth + 4, (int)absSlotWidth + 4);
            slotCtx     = genContext(slotSurface);

            slotCtx.SetSourceRGBA(GuiStyle.ActiveSlotColor);
            RoundRectangle(slotCtx, 0, 0, absSlotWidth + 4, absSlotHeight + 4, GuiStyle.ElementBGRadius);
            slotCtx.LineWidth = scaled(9);
            slotCtx.StrokePreserve();
            slotSurface.Blur(scaled(6), true);
            slotCtx.StrokePreserve();
            slotSurface.Blur(scaled(6), true);

            slotCtx.LineWidth = scaled(3);
            slotCtx.Stroke();

            slotCtx.LineWidth = scaled(1);
            slotCtx.SetSourceRGBA(GuiStyle.ActiveSlotColor);
            slotCtx.Stroke();

            generateTexture(slotSurface, ref highlightSlotTexture);



            slotCtx.Dispose();
            slotSurface.Dispose();

            int slotIndex = 0;

            foreach (var val in availableSlots)
            {
                int col = slotIndex % cols;
                int row = slotIndex / cols;

                double x = col * (unscaledSlotWidth + unscaledSlotPadding);
                double y = row * (unscaledSlotHeight + unscaledSlotPadding);

                ItemSlot slot = inventory[val.Key];

                slotBounds[slotIndex] = ElementBounds.Fixed(x, y, unscaledSlotWidth, unscaledSlotHeight).WithParent(Bounds);
                slotBounds[slotIndex].CalcWorldBounds();

                scissorBounds[slotIndex] = ElementBounds.Fixed(x + 2, y + 2, unscaledSlotWidth - 4, unscaledSlotHeight - 4).WithParent(Bounds);
                scissorBounds[slotIndex].CalcWorldBounds();

                ComposeSlotOverlays(slot, val.Key, slotIndex);

                slotIndex++;
            }
        }
Example #8
0
        private void ComposeElement(GuiComposer composer, JsonDialogSettings settings, DialogElement elem, int elemKey, double x, double y)
        {
            double factor = settings.SizeMultiplier;

            double labelWidth = 0;

            if (elem.Label != null)
            {
                CairoFont font = CairoFont.WhiteSmallText();
                font.UnscaledFontsize *= factor;
                TextExtents extents = font.GetTextExtents(elem.Label);
                labelWidth = extents.Width / factor / RuntimeEnv.GUIScale + 1;
                FontExtents fext = font.GetFontExtents();

                ElementBounds labelBounds = ElementBounds.Fixed(x, y + Math.Max(0, (elem.Height * factor - fext.Height / RuntimeEnv.GUIScale) / 2), labelWidth, elem.Height).WithScale(factor);

                composer.AddStaticText(elem.Label, font, labelBounds);
                labelWidth += 8;

                if (elem.Tooltip != null)
                {
                    CairoFont tfont = CairoFont.WhiteSmallText();
                    tfont.UnscaledFontsize *= factor;
                    composer.AddHoverText(elem.Tooltip, tfont, 350, labelBounds.FlatCopy(), "tooltip-" + elem.Code);
                    composer.GetHoverText("tooltip-" + elem.Code).SetAutoWidth(true);
                }
            }


            ElementBounds bounds = ElementBounds.Fixed(x + labelWidth, y, elem.Width - labelWidth, elem.Height).WithScale(factor);

            string currentValue = settings.OnGet?.Invoke(elem.Code);

            switch (elem.Type)
            {
            case EnumDialogElementType.Slider:
            {
                string key = "slider-" + elemKey;
                composer.AddSlider((newval) => { settings.OnSet?.Invoke(elem.Code, newval + ""); return(true); }, bounds, key);



                int curVal = 0;
                int.TryParse(currentValue, out curVal);

                composer.GetSlider(key).SetValues(curVal, elem.MinValue, elem.MaxValue, elem.Step);
                composer.GetSlider(key).Scale = factor;
                //composer.GetSlider(key).TriggerOnlyOnMouseUp(true);
                break;
            }

            case EnumDialogElementType.Switch:
            {
                string key = "switch-" + elemKey;
                composer.AddSwitch((newval) => { settings.OnSet?.Invoke(elem.Code, newval ? "1" : "0"); }, bounds, key, 30 * factor, 5 * factor);
                composer.GetSwitch(key).SetValue(currentValue == "1");
            }
            break;

            case EnumDialogElementType.Input:
            {
                string    key  = "input-" + elemKey;
                CairoFont font = CairoFont.WhiteSmallText();
                font.UnscaledFontsize *= factor;

                composer.AddTextInput(bounds, (newval) => { settings.OnSet?.Invoke(elem.Code, newval); }, font, key);
                composer.GetTextInput(key).SetValue(currentValue);
                break;
            }

            case EnumDialogElementType.NumberInput:
            {
                string    key  = "numberinput-" + elemKey;
                CairoFont font = CairoFont.WhiteSmallText();
                font.UnscaledFontsize *= factor;

                composer.AddNumberInput(bounds, (newval) => { settings.OnSet?.Invoke(elem.Code, newval); }, font, key);
                composer.GetNumberInput(key).SetValue(currentValue);
                break;
            }


            case EnumDialogElementType.Button:
                if (elem.Icon != null)
                {
                    composer.AddIconButton(elem.Icon, (val) => { settings.OnSet?.Invoke(elem.Code, null); }, bounds);
                }
                else
                {
                    CairoFont font = CairoFont.ButtonText();
                    font.WithFontSize(elem.FontSize);

                    composer.AddButton(elem.Text, () => { settings.OnSet?.Invoke(elem.Code, null); return(true); }, bounds.WithFixedPadding(8, 0), font);
                }

                if (elem.Tooltip != null && elem.Label == null)
                {
                    CairoFont tfont = CairoFont.WhiteSmallText();
                    tfont.UnscaledFontsize *= factor;
                    composer.AddHoverText(elem.Tooltip, tfont, 350, bounds.FlatCopy(), "tooltip-" + elem.Code);
                    composer.GetHoverText("tooltip-" + elem.Code).SetAutoWidth(true);
                }
                break;

            case EnumDialogElementType.Text:
                composer.AddStaticText(elem.Text, CairoFont.WhiteMediumText().WithFontSize(elem.FontSize), bounds);
                break;

            case EnumDialogElementType.Select:
            case EnumDialogElementType.DynamicSelect:
            {
                string[] values = elem.Values;
                string[] names  = elem.Names;

                if (elem.Type == EnumDialogElementType.DynamicSelect)
                {
                    string[] compos = currentValue.Split(new string[] { "\n" }, StringSplitOptions.None);
                    values       = compos[0].Split(new string[] { "||" }, StringSplitOptions.None);
                    names        = compos[1].Split(new string[] { "||" }, StringSplitOptions.None);
                    currentValue = compos[2];
                }

                int selectedIndex = Array.FindIndex(values, w => w.Equals(currentValue));

                if (elem.Mode == EnumDialogElementMode.DropDown)
                {
                    string key = "dropdown-" + elemKey;

                    composer.AddDropDown(values, names, selectedIndex, (newval, on) => { settings.OnSet?.Invoke(elem.Code, newval); }, bounds, key);

                    composer.GetDropDown(key).Scale = factor;

                    composer.GetDropDown(key).Font.UnscaledFontsize *= factor;
                }
                else
                {
                    if (elem.Icons != null && elem.Icons.Length > 0)
                    {
                        ElementBounds[] manybounds = new ElementBounds[elem.Icons.Length];
                        double          elemHeight = (elem.Height - 4 * elem.Icons.Length) / elem.Icons.Length;

                        for (int i = 0; i < manybounds.Length; i++)
                        {
                            manybounds[i] = bounds.FlatCopy().WithFixedHeight(elemHeight - 4).WithFixedOffset(0, i * (4 + elemHeight)).WithScale(factor);
                        }

                        string    key  = "togglebuttons-" + elemKey;
                        CairoFont font = CairoFont.WhiteSmallText();
                        font.UnscaledFontsize *= factor;

                        composer.AddIconToggleButtons(elem.Icons, font, (newval) => { settings.OnSet?.Invoke(elem.Code, elem.Values[newval]); }, manybounds, key);

                        if (currentValue != null && currentValue.Length > 0)
                        {
                            composer.ToggleButtonsSetValue(key, selectedIndex);
                        }


                        if (elem.Tooltips != null)
                        {
                            for (int i = 0; i < elem.Tooltips.Length; i++)
                            {
                                CairoFont tfont = CairoFont.WhiteSmallText();
                                tfont.UnscaledFontsize *= factor;

                                composer.AddHoverText(elem.Tooltips[i], tfont, 350, manybounds[i].FlatCopy());
                            }
                        }
                    }
                }
            }
            break;
            }


            elementNumber++;
        }
Example #9
0
        /// <summary>
        /// Composes the list of elements dynamically.
        /// </summary>
        public void ComposeDynamicElements()
        {
            Bounds.CalcWorldBounds();

            if (multiSelect)
            {
                if (switches != null)
                {
                    foreach (var val in switches)
                    {
                        val.Dispose();
                    }
                }

                switches = new GuiElementSwitch[Names.Length];
            }

            for (int i = 0; i < richtTextElem.Length; i++)
            {
                richtTextElem[i].Dispose();
            }

            richtTextElem = new GuiElementRichtext[Values.Length];
            for (int i = 0; i < Values.Length; i++)
            {
                ElementBounds textBounds = ElementBounds.Fixed(0, 0, 700, 100).WithEmptyParent();
                richtTextElem[i] = new GuiElementRichtext(api, new RichTextComponentBase[0], textBounds);
            }


            double scaleMul   = Scale * RuntimeEnv.GUIScale;
            double lineHeight = unscaledLineHeight * scaleMul;

            // Expandable box with list of names
            expandedBoxWidth  = Bounds.InnerWidth;
            expandedBoxHeight = Values.Length * lineHeight;

            double scrollbarWidth = 10;

            for (int i = 0; i < Values.Length; i++)
            {
                GuiElementRichtext elem = richtTextElem[i];
                elem.SetNewTextWithoutRecompose(Names[i], Font);
                elem.BeforeCalcBounds();

                expandedBoxWidth = Math.Max(expandedBoxWidth, elem.MaxLineWidth + scaled(scrollbarWidth + 5));
            }
            expandedBoxWidth++;

            //expandedBoxWidth += 5 * scaleMul;


            ImageSurface surface = new ImageSurface(Format.Argb32, (int)expandedBoxWidth, (int)expandedBoxHeight);
            Context      ctx     = genContext(surface);

            visibleBounds             = Bounds.FlatCopy();
            visibleBounds.fixedHeight = Math.Min(MaxHeight, expandedBoxHeight / RuntimeEnv.GUIScale);
            visibleBounds.fixedWidth  = expandedBoxWidth / RuntimeEnv.GUIScale;
            visibleBounds.fixedY     += Bounds.InnerHeight / RuntimeEnv.GUIScale;
            visibleBounds.CalcWorldBounds();

            Font.SetupContext(ctx);

            ctx.SetSourceRGBA(GuiStyle.DialogStrongBgColor);
            RoundRectangle(ctx, 0, 0, expandedBoxWidth, expandedBoxHeight, 1);
            ctx.FillPreserve();
            ctx.SetSourceRGBA(0, 0, 0, 0.5);
            ctx.LineWidth = 2;
            ctx.Stroke();

            double unscaledHeight = Font.GetFontExtents().Height / RuntimeEnv.GUIScale;
            double unscaledOffY   = (unscaledLineHeight - unscaledHeight) / 2;
            double unscaledOffx   = multiSelect ? unscaledHeight + 10 : 0;

            double scaledHeight = unscaledHeight * scaleMul;

            ctx.SetSourceRGBA(GuiStyle.DialogDefaultTextColor);

            ElementBounds switchParentBounds = Bounds.FlatCopy();

            switchParentBounds.IsDrawingSurface = true;
            switchParentBounds.CalcWorldBounds();



            for (int i = 0; i < Values.Length; i++)
            {
                int    num = i;
                double y   = ((int)unscaledOffY + i * unscaledLineHeight) * scaleMul;
                double x   = unscaledOffx + 5 * scaleMul;

                double offy = (scaledHeight - Font.GetTextExtents(Names[i]).Height) / 2;

                if (multiSelect)
                {
                    double        pad          = 2;
                    ElementBounds switchBounds = new ElementBounds()
                    {
                        ParentBounds  = switchParentBounds,
                        fixedX        = 4 * Scale,
                        fixedY        = (y + offy) / RuntimeEnv.GUIScale,
                        fixedWidth    = (unscaledHeight) * Scale,
                        fixedHeight   = (unscaledHeight) * Scale,
                        fixedPaddingX = 0,
                        fixedPaddingY = 0
                    };

                    switches[i] = new GuiElementSwitch(api, (on) => toggled(on, num), switchBounds, switchBounds.fixedHeight, pad);
                    switches[i].ComposeElements(ctx, surface);

                    ctx.SetSourceRGBA(GuiStyle.DialogDefaultTextColor);
                }

                GuiElementRichtext elem = richtTextElem[i];

                elem.Bounds.fixedX = x;
                elem.Bounds.fixedY = (y + offy) / RuntimeEnv.GUIScale;
                elem.BeforeCalcBounds();
                elem.Bounds.CalcWorldBounds();
                elem.ComposeFor(elem.Bounds, ctx, surface);
            }

            generateTexture(surface, ref dropDownTexture);

            ctx.Dispose();
            surface.Dispose();


            // Scrollbar static stuff
            scrollbar.Bounds.WithFixedSize(scrollbarWidth, visibleBounds.fixedHeight - 3).WithFixedPosition(expandedBoxWidth / RuntimeEnv.GUIScale - 10, 0).WithFixedPadding(0, 2);
            scrollbar.Bounds.WithEmptyParent();
            scrollbar.Bounds.CalcWorldBounds();

            surface = new ImageSurface(Format.Argb32, (int)expandedBoxWidth, (int)scrollbar.Bounds.OuterHeight);
            ctx     = genContext(surface);

            scrollbar.ComposeElements(ctx, surface);
            scrollbar.SetHeights((int)visibleBounds.InnerHeight / RuntimeEnv.GUIScale, (int)expandedBoxHeight / RuntimeEnv.GUIScale);

            generateTexture(surface, ref scrollbarTexture);

            ctx.Dispose();
            surface.Dispose();


            // Hover bar
            surface = new ImageSurface(Format.Argb32, (int)expandedBoxWidth, (int)(unscaledLineHeight * scaleMul));
            ctx     = genContext(surface);

            double[] col = GuiStyle.DialogHighlightColor;
            col[3] = 0.5;
            ctx.SetSourceRGBA(col);
            RoundRectangle(ctx, 0, 0, expandedBoxWidth, unscaledLineHeight * scaleMul, 0);
            ctx.Fill();
            generateTexture(surface, ref hoverTexture);

            ctx.Dispose();
            surface.Dispose();
        }
Example #10
0
        public override void RenderInteractiveElements(float deltaTime, double renderX, double renderY)
        {
            LineRectangled bounds = BoundsPerLine[0];

            GridRecipeAndUnnamedIngredients recipeunin = GridRecipesAndUnIn[curItemIndex];

            if ((secondsVisible -= deltaTime) <= 0)
            {
                secondsVisible = 1;
                curItemIndex   = (curItemIndex + 1) % GridRecipesAndUnIn.Length;
                secondCounter++;
            }

            LoadedTexture extraTextTexture;

            if (extraTexts.TryGetValue(curItemIndex, out extraTextTexture))
            {
                capi.Render.Render2DTexturePremultipliedAlpha(extraTextTexture.TextureId, (float)(renderX + bounds.X), (float)(renderY + bounds.Y + 3 * (size + 3)), extraTextTexture.Width, extraTextTexture.Height);
            }

            int    mx = api.Input.MouseX;
            int    my = api.Input.MouseY;
            double rx = 0, ry = 0;



            for (int x = 0; x < 3; x++)
            {
                for (int y = 0; y < 3; y++)
                {
                    int index = recipeunin.Recipe.GetGridIndex(y, x, recipeunin.Recipe.resolvedIngredients, recipeunin.Recipe.Width);

                    CraftingRecipeIngredient ingred = recipeunin.Recipe.GetElementInGrid(y, x, recipeunin.Recipe.resolvedIngredients, recipeunin.Recipe.Width);


                    if (ingred == null)
                    {
                        continue;
                    }

                    rx = renderX + bounds.X + x * (size + GuiElement.scaled(3));
                    ry = renderY + bounds.Y + y * (size + GuiElement.scaled(3));

                    ItemStack[] unnamedWildcardStacklist = null;
                    if (recipeunin.unnamedIngredients?.TryGetValue(index, out unnamedWildcardStacklist) == true)
                    {
                        dummyslot.Itemstack           = unnamedWildcardStacklist[secondCounter % unnamedWildcardStacklist.Length];
                        dummyslot.Itemstack.StackSize = ingred.Quantity;
                    }
                    else
                    {
                        dummyslot.Itemstack = ingred.ResolvedItemstack.Clone();
                    }

                    var           scale         = RuntimeEnv.GUIScale;
                    ElementBounds scissorBounds = ElementBounds.Fixed(rx / scale, ry / scale, size / scale, size / scale).WithEmptyParent();
                    scissorBounds.CalcWorldBounds();
                    api.Render.PushScissor(scissorBounds, true);

                    // 1.16.0: Fugly (but backwards compatible) hack: We temporarily store the ingredient code in an unused field of ItemSlot so that OnHandbookRecipeRender() has access to that number. Proper solution would be to alter the method signature to pass on this value.
                    dummyslot.BackgroundIcon = index + "";
                    dummyslot.Itemstack.Collectible.OnHandbookRecipeRender(capi, recipeunin.Recipe, dummyslot, rx + size * 0.5f, ry + size * 0.5f, size);
                    dummyslot.BackgroundIcon = null;


                    api.Render.PopScissor();

                    // Super weird coordinates, no idea why
                    double dx = mx - rx + 1;
                    double dy = my - ry + 2;

                    if (dx >= 0 && dx < size && dy >= 0 && dy < size)
                    {
                        RenderItemstackTooltip(dummyslot, rx + dx, ry + dy, deltaTime);
                    }
                }
            }
        }