|
1 | 1 | package gregtech.common.mui.widget; |
2 | 2 |
|
| 3 | +import gregtech.api.metatileentity.multiblock.ui.MultiblockUIBuilder; |
3 | 4 | import gregtech.api.mui.IconAcessor; |
4 | 5 |
|
5 | 6 | import net.minecraft.client.gui.FontRenderer; |
|
18 | 19 | import com.cleanroommc.modularui.screen.ModularScreen; |
19 | 20 | import com.cleanroommc.modularui.screen.RichTooltip; |
20 | 21 | import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; |
| 22 | +import com.cleanroommc.modularui.theme.WidgetTheme; |
| 23 | +import com.cleanroommc.modularui.utils.Alignment; |
21 | 24 | import com.cleanroommc.modularui.utils.HoveredWidgetList; |
22 | 25 | import com.cleanroommc.modularui.widget.Widget; |
23 | 26 | import com.cleanroommc.modularui.widget.scroll.ScrollArea; |
24 | 27 | import com.cleanroommc.modularui.widget.scroll.ScrollData; |
25 | 28 | import com.cleanroommc.modularui.widget.sizer.Area; |
| 29 | +import com.cleanroommc.modularui.widget.sizer.Box; |
26 | 30 | import org.jetbrains.annotations.NotNull; |
27 | 31 | import org.jetbrains.annotations.Nullable; |
28 | 32 |
|
29 | | -import java.util.function.Consumer; |
30 | | - |
31 | 33 | public class ScrollableTextWidget extends Widget<ScrollableTextWidget> |
32 | 34 | implements IRichTextBuilder<ScrollableTextWidget>, Interactable, IViewport, |
33 | 35 | JeiIngredientProvider { |
34 | 36 |
|
35 | 37 | private final RichText text = new RichText(); |
36 | | - private Consumer<RichText> builder; |
| 38 | + private MultiblockUIBuilder builder; |
37 | 39 | private boolean dirty = false; |
38 | 40 | private boolean autoUpdate = false; |
| 41 | + private boolean initScroll; |
39 | 42 | private Object lastIngredient; |
40 | 43 |
|
41 | 44 | private final ScrollArea scroll = new ScrollArea(); |
@@ -161,26 +164,60 @@ public void preDraw(ModularGuiContext context, boolean transformed) { |
161 | 164 | if (!transformed) { |
162 | 165 | Stencil.applyAtZero(this.scroll, context); |
163 | 166 | } else { |
164 | | - drawText(context); |
| 167 | + drawText(context, false); |
165 | 168 | } |
166 | 169 | } |
167 | 170 |
|
168 | | - private void drawText(ModularGuiContext context) { |
| 171 | + public void postRebuild() { |
| 172 | + if (initScroll || !isValid()) return; |
| 173 | + initScroll = true; |
| 174 | + |
| 175 | + // i really hate how this is done but it works |
| 176 | + // this is responsible for scrolling to the right value on ui ope |
| 177 | + // eg half-way for center, and at the bottom for bottom alignments |
| 178 | + drawText(getContext(), true); |
| 179 | + int size = this.scroll.getScrollY().getScrollSize(); |
| 180 | + if (size <= getArea().h()) return; |
| 181 | + size -= getArea().h(); |
| 182 | + |
| 183 | + Alignment alignment = this.text.getAlignment(); |
| 184 | + int scroll = (int) (size * alignment.y); |
| 185 | + this.scroll.getScrollY().scrollTo(this.scroll, scroll); |
| 186 | + } |
| 187 | + |
| 188 | + private void drawText(ModularGuiContext context, boolean simulate) { |
169 | 189 | if (this.autoUpdate || this.dirty) { |
170 | 190 | if (this.builder != null) { |
171 | 191 | this.text.clearText(); |
172 | | - this.builder.accept(this.text); |
| 192 | + this.builder.build(this.text); |
173 | 193 | } |
174 | 194 | this.dirty = false; |
175 | 195 | } |
176 | | - this.text.setupRenderer(this.renderer, getArea().getPadding().left, getArea().getPadding().top - getScrollY(), |
177 | | - getArea().paddedWidth(), getArea().paddedHeight(), |
178 | | - getWidgetTheme(context.getTheme()).getTextColor(), |
179 | | - getWidgetTheme(context.getTheme()).getTextShadow()); |
180 | | - this.text.compileAndDraw(this.renderer, context, false); |
| 196 | + |
| 197 | + Alignment alignment = this.text.getAlignment(); |
| 198 | + Area area = getArea(); |
| 199 | + Box padding = area.getPadding(); |
| 200 | + WidgetTheme widgetTheme = getWidgetTheme(context.getTheme()); |
| 201 | + |
| 202 | + this.text.compileAndDraw(this.renderer, context, true); |
| 203 | + |
181 | 204 | // this isn't perfect, but i hope it's good enough |
182 | | - int diff = (int) Math.ceil((this.renderer.getLastHeight() - getArea().h()) / 2); |
183 | | - this.scroll.getScrollY().setScrollSize(getArea().h() + Math.max(0, diff)); |
| 205 | + int diff = (int) Math.ceil((this.renderer.getLastHeight() - area.h()) / 2); |
| 206 | + this.scroll.getScrollY().setScrollSize(area.h() + Math.max(0, diff)); |
| 207 | + |
| 208 | + if (!simulate) { |
| 209 | + // this is responsible for centering the text if there's not enough to scroll |
| 210 | + int x = padding.left; |
| 211 | + int y = (int) (area.h() * alignment.y); |
| 212 | + if (alignment.y == 0.5f) y -= (int) (this.renderer.getLastHeight() / 2); |
| 213 | + y = Math.min(Math.max(padding.top, y), area.h() - padding.bottom); |
| 214 | + if (alignment.y > 0.5f) y -= area.h(); // why? |
| 215 | + this.text.setupRenderer(this.renderer, x, y - getScrollY(), |
| 216 | + area.paddedWidth(), area.paddedHeight(), |
| 217 | + widgetTheme.getTextColor(), widgetTheme.getTextShadow()); |
| 218 | + |
| 219 | + this.text.compileAndDraw(this.renderer, context, false); |
| 220 | + } |
184 | 221 | } |
185 | 222 |
|
186 | 223 | @Override |
@@ -215,11 +252,11 @@ public ScrollableTextWidget autoUpdate(boolean autoUpdate) { |
215 | 252 | /** |
216 | 253 | * A builder which is called every time before drawing when {@link #dirty} is true. |
217 | 254 | * |
218 | | - * @param builder text builder |
219 | | - * @return this |
| 255 | + * @param uiBuilder@return this |
220 | 256 | */ |
221 | | - public ScrollableTextWidget textBuilder(Consumer<RichText> builder) { |
222 | | - this.builder = builder; |
| 257 | + public ScrollableTextWidget textBuilder(MultiblockUIBuilder uiBuilder) { |
| 258 | + this.builder = uiBuilder; |
| 259 | + this.builder.postRebuild(this::postRebuild); |
223 | 260 | markDirty(); |
224 | 261 | return this; |
225 | 262 | } |
|
0 commit comments