/// <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(); }
void ComposeCurrentValue() { double width = Bounds.InnerWidth; valueWidth = (int)((Bounds.InnerWidth - scaled(20)) * Scale); valueHeight = (int)(scaled(30) * Scale); // Current value ImageSurface surface = new ImageSurface(Format.Argb32, valueWidth, valueHeight); Context ctx = genContext(surface); Font.SetupContext(ctx); ctx.SetSourceRGBA(GuiStyle.DialogDefaultTextColor); string text = ""; double height = Font.GetFontExtents().Height; if (listMenu.SelectedIndices.Length > 1) { for (int i = 0; i < listMenu.SelectedIndices.Length; i++) { int index = listMenu.SelectedIndices[i]; string addText = ""; if (text.Length > 0) { addText += ", "; } addText += listMenu.Names[index]; int cntleft = listMenu.SelectedIndices.Length - i; int cnt = listMenu.SelectedIndices.Length; string moreText = text.Length > 0 ? (" " + (cntleft == 1 ? Lang.Get(SingularMoreNameCode, cntleft) : Lang.Get(PluralMoreNameCode, cntleft))) : (cnt == 1 ? Lang.Get(SingularNameCode, cnt) : Lang.Get(PluralNameCode, cnt)) ; if (Font.GetTextExtents(text + addText + Lang.Get(PluralMoreNameCode, cntleft)).Width < width) { text += addText; } else { text = text + moreText; break; } } } else { if (listMenu.SelectedIndices.Length == 1) { text = listMenu.Names[listMenu.SelectedIndex]; } } richTextElem.SetNewTextWithoutRecompose(text, Font); richTextElem.BeforeCalcBounds(); richTextElem.Bounds.fixedX = 5; richTextElem.Bounds.fixedY = (valueHeight - height) / 2 / RuntimeEnv.GUIScale; richTextElem.BeforeCalcBounds(); richTextElem.Bounds.CalcWorldBounds(); richTextElem.ComposeFor(richTextElem.Bounds, ctx, surface); generateTexture(surface, ref currentValueTexture); ctx.Dispose(); surface.Dispose(); }
public void AsyncRecompose() { if (curSlot?.Itemstack == null) { return; } Dirty = true; string title = curSlot.GetStackName(); string desc = OnRequireInfoText(curSlot); desc.TrimEnd(); titleElement.Bounds.fixedWidth = maxWidth - scaled(GuiElementPassiveItemSlot.unscaledItemSize) * 3 - 10; descriptionElement.Bounds.fixedWidth = maxWidth - 40 - scaled(GuiElementPassiveItemSlot.unscaledItemSize) * 3 - 10; descriptionElement.Bounds.CalcWorldBounds(); titleElement.Bounds.CalcWorldBounds(); titleElement.SetNewTextWithoutRecompose(title, titleFont, null, true); descriptionElement.SetNewTextWithoutRecompose(desc, Font, null, true); RecalcBounds(); Bounds.CalcWorldBounds(); ElementBounds textBounds = Bounds.CopyOnlySize(); textBounds.CalcWorldBounds(); TyronThreadPool.QueueTask(() => { 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.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(); Dirty = false; }, "genstackinfotexture"); }); }