diff --git a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNPCGlobalMainMenu.java b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNPCGlobalMainMenu.java index 2e73bc3bf..cba9b69b6 100644 --- a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNPCGlobalMainMenu.java +++ b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNPCGlobalMainMenu.java @@ -6,12 +6,12 @@ import noppes.npcs.NoppesStringUtils; import noppes.npcs.client.NoppesUtil; import noppes.npcs.client.gui.global.GuiNpcManagePlayerData; import noppes.npcs.client.gui.global.GuiNpcNaturalSpawns; -import noppes.npcs.client.gui.util.GuiNPCInterface2; -import noppes.npcs.client.gui.util.GuiNpcButton; -import noppes.npcs.client.gui.util.GuiScrollableComponent; +import noppes.npcs.client.gui.util.*; import noppes.npcs.constants.EnumGuiType; import noppes.npcs.entity.EntityNPCInterface; +import java.util.Arrays; + public class GuiNPCGlobalMainMenu extends GuiNPCInterface2{ public GuiNPCGlobalMainMenu(EntityNPCInterface npc){ super(npc,5); @@ -36,15 +36,27 @@ public class GuiNPCGlobalMainMenu extends GuiNPCInterface2{ if(Loader.isModLoaded("npcdbc")) this.addButton(new GuiNpcButton(200, guiLeft + 210, y += 22, "global.customforms")); - GuiScrollableComponent scrollableComponent = new GuiScrollableComponent(null, guiLeft + 210, y+=22, 200, 150, 90); - this.addScrollableGui(0, scrollableComponent); + GuiScrollWindow scrollWindow = new GuiScrollWindow(this, guiLeft + 210, y+=22, 200, 150, 200); + this.addScrollableGui(0, scrollWindow); int k = 10; - scrollableComponent.addButton(new GuiNpcButton(30, 0, k, 80, 20, "Something")); - scrollableComponent.addButton(new GuiNpcButton(31, 0, k += 24, 80, 20, "Something")); - scrollableComponent.addButton(new GuiNpcButton(32, 0, k += 24, 80, 20, "Something")); - scrollableComponent.addButton(new GuiNpcButton(33, 0, k += 24, 80, 20, "Something")); - scrollableComponent.addButton(new GuiNpcButton(34, 0, k += 24, 80, 20, "Something")); - scrollableComponent.addButton(new GuiNpcButton(35, 0, k += 24, 80, 20, "Something")); + scrollWindow.addButton(new GuiNpcButton(30, 0, k, 80, 20, "Something")); + scrollWindow.addButton(new GuiNpcButton(31, 0, k += 24, 80, 20, "Something")); + scrollWindow.addButton(new GuiNpcButton(32, 0, k += 24, 80, 20, "Something")); + scrollWindow.addButton(new GuiNpcButton(33, 0, k += 24, 80, 20, "Something")); + scrollWindow.addButton(new GuiNpcButton(34, 0, k += 24, 80, 20, "Something")); + scrollWindow.addButton(new GuiNpcButton(35, 0, k += 24, 80, 20, "Something")); + scrollWindow.addButton(new GuiNpcButton(35, 0, k += 24, 80, 20, "Something")); + + scrollWindow.addTextField(new GuiNpcTextField(40, scrollWindow, fontRendererObj, 0, k += 24, 90, 20, "")); + + GuiCustomScroll scroll = new GuiCustomScroll(scrollWindow,0); + scroll.setList(Arrays.asList("Something", "Something2","Somethin4g","Somet5hing","Someth6ing","Somet7hing","Somet8hing","Som9ething")); + scroll.setSize(143, 50); + scroll.guiLeft = 0; + scroll.guiTop = k+=22; + + scrollWindow.addScroll(scroll); + System.out.println(k); } @@ -89,6 +101,7 @@ public class GuiNPCGlobalMainMenu extends GuiNPCInterface2{ if (id == 200) { NoppesUtil.requestOpenGUI(EnumGuiType.ManageCustomForms); } + System.out.println("HIT BUTTON"); } @Override public void save() { diff --git a/src/main/java/noppes/npcs/client/gui/util/GuiNPCInterface.java b/src/main/java/noppes/npcs/client/gui/util/GuiNPCInterface.java index 158950ad5..c82555b3c 100644 --- a/src/main/java/noppes/npcs/client/gui/util/GuiNPCInterface.java +++ b/src/main/java/noppes/npcs/client/gui/util/GuiNPCInterface.java @@ -36,7 +36,7 @@ public abstract class GuiNPCInterface extends GuiScreen protected HashMap scrolls = new HashMap(); protected HashMap sliders = new HashMap(); protected HashMap extra = new HashMap(); - protected HashMap scrollableGuiInserts = new HashMap<>(); + protected HashMap scrollWindows = new HashMap<>(); public String title; private ResourceLocation background = null; @@ -87,7 +87,7 @@ public abstract class GuiNPCInterface extends GuiScreen topbuttons.clear(); scrolls.clear(); sliders.clear(); - scrollableGuiInserts.clear(); + scrollWindows.clear(); Keyboard.enableRepeatEvents(true); } @Override @@ -109,10 +109,10 @@ public abstract class GuiNPCInterface extends GuiScreen extra.put(gui.id, gui); } - public void addScrollableGui(int id, GuiScrollableComponent gui){ + public void addScrollableGui(int id, GuiScrollWindow gui){ gui.setWorldAndResolution(mc, width, height); gui.initGui(); - scrollableGuiInserts.put(id, gui); + scrollWindows.put(id, gui); } public void mouseClicked(int i, int j, int k) @@ -124,7 +124,7 @@ public abstract class GuiNPCInterface extends GuiScreen if(tf.enabled) tf.mouseClicked(i, j, k); - for(GuiScrollableComponent guiScrollableComponent : scrollableGuiInserts.values()) { + for(GuiScrollWindow guiScrollableComponent : scrollWindows.values()) { if(guiScrollableComponent.isMouseOver(i, j)) guiScrollableComponent.mouseClicked(i, j, k); } @@ -158,6 +158,10 @@ public abstract class GuiNPCInterface extends GuiScreen for(GuiNpcTextField tf : textfields.values()) tf.textboxKeyTyped(c, i); + for(GuiScrollWindow guiScrollableComponent : scrollWindows.values()) { + guiScrollableComponent.keyTyped(c, i); + } + if (closeOnEsc && (i == 1 || !GuiNpcTextField.isFieldActive() && isInventoryKey(i))){ close(); } @@ -205,11 +209,10 @@ public abstract class GuiNPCInterface extends GuiScreen return labels.get(i); } - public GuiScrollableComponent getScrollableGui(int i) { - return scrollableGuiInserts.get(i); + public GuiScrollWindow getScrollableGui(int i) { + return scrollWindows.get(i); } - public void addSlider(GuiNpcSlider slider){ sliders.put(slider.id,slider); buttonList.add(slider); @@ -266,7 +269,7 @@ public abstract class GuiNPCInterface extends GuiScreen button.drawHover(i, j, subGui); } } - for(GuiScrollableComponent guiScrollableComponent : scrollableGuiInserts.values()){ + for(GuiScrollWindow guiScrollableComponent : scrollWindows.values()){ guiScrollableComponent.drawScreen(i, j, f, guiScrollableComponent.isMouseOver(i,j)?mouseScroll:0); } diff --git a/src/main/java/noppes/npcs/client/gui/util/GuiScrollWindow.java b/src/main/java/noppes/npcs/client/gui/util/GuiScrollWindow.java new file mode 100644 index 000000000..a1185c272 --- /dev/null +++ b/src/main/java/noppes/npcs/client/gui/util/GuiScrollWindow.java @@ -0,0 +1,351 @@ +package noppes.npcs.client.gui.util; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.GuiYesNoCallback; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.util.ResourceLocation; +import noppes.npcs.entity.EntityNPCInterface; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; +import java.util.ArrayList; +import java.util.HashMap; + +public class GuiScrollWindow extends GuiScreen implements ITextfieldListener, ICustomScrollListener, GuiYesNoCallback +{ + public static final ResourceLocation resource = new ResourceLocation("customnpcs","textures/gui/misc.png"); + + protected GuiNPCInterface parent; + public boolean drawDefaultBackground = true; + public EntityNPCInterface npc; + protected HashMap buttons = new HashMap(); + protected HashMap textfields = new HashMap(); + protected HashMap labels = new HashMap(); + protected HashMap scrolls = new HashMap(); + protected HashMap sliders = new HashMap(); + + protected ScaledResolution scaledResolution; + + // Window Size + public int clipWidth; + public int clipHeight; + + // Location + public int xPos = 0; + public int yPos = 0; + + public int maxScrollY = 0; + public float scrollY = 0; + public float nextScrollY = 0; + public int mouseScroll; + boolean isScrolling; + + /** + * Scrollable GUI component :P? + * @param posX the X Position of the gui element on the screen + * @param posY the Y Position of the GUI element on the screen + * @param clipWidth width of the element + * @param clipHeight height of the element + * @param maxScroll extra Y area displayed through the scrollbar. + */ + public GuiScrollWindow(GuiNPCInterface parent, int posX, int posY, int clipWidth, int clipHeight, int maxScroll){ + this.parent = parent; + this.xPos = posX; + this.yPos = posY; + this.clipWidth = clipWidth; + this.clipHeight = clipHeight; + this.maxScrollY = maxScroll; + } + + + @Override + public void initGui(){ + super.initGui(); + + scaledResolution = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + + float scrollPerc = 0; + if((yPos+clipHeight) != 0){ + scrollPerc = (nextScrollY) / (clipHeight); + } + + nextScrollY = scrollPerc * (clipHeight); + + GuiNpcTextField.unfocus(); + buttonList.clear(); + labels.clear(); + textfields.clear(); + buttons.clear(); + scrolls.clear(); + sliders.clear(); + Keyboard.enableRepeatEvents(true); + } + @Override + public void updateScreen(){ + for(GuiNpcTextField tf : textfields.values()){ + if(tf.enabled) + tf.updateCursorCounter(); + } + super.updateScreen(); + } + + public void mouseClicked(int i, int j, int k) + { + + i = i - xPos; + j = (int) (j-yPos+scrollY); + + for(GuiNpcTextField tf : new ArrayList(textfields.values())) + if(tf.enabled) + tf.mouseClicked(i, j, k); + + if (k == 0){ + for(GuiCustomScroll scroll : new ArrayList(scrolls.values())){ + scroll.mouseClicked(i, j, k); + } + } + mouseEvent(i,j,k); + super.mouseClicked(i, j, k); + } + + public void mouseEvent(int i, int j, int k){}; + + @Override + protected void actionPerformed(GuiButton guibutton) { + parent.buttonEvent(guibutton); + } + public void buttonEvent(GuiButton guibutton){ + parent.buttonEvent(guibutton); + }; + + @Override + public void keyTyped(char c, int i){ + for(GuiNpcTextField tf : textfields.values()) + tf.textboxKeyTyped(c, i); + } + + + public void addButton(GuiNpcButton button){ + buttons.put(button.id,button); + buttonList.add(button); + } + public GuiNpcButton getButton(int i) { + return buttons.get(i); + } + public void addTextField(GuiNpcTextField tf){ + textfields.put(tf.id,tf); + } + public GuiNpcTextField getTextField(int i){ + return textfields.get(i); + } + public void addLabel(GuiNpcLabel label) { + labels.put(label.id, label); + } + public GuiNpcLabel getLabel(int i){ + return labels.get(i); + } + + public void addSlider(GuiNpcSlider slider){ + sliders.put(slider.id,slider); + buttonList.add(slider); + } + public GuiNpcSlider getSlider(int i) { + return sliders.get(i); + } + public void addScroll(GuiCustomScroll scroll) { + scroll.setWorldAndResolution(mc, 350, 250); + scrolls.put(scroll.id, scroll); + } + public GuiCustomScroll getScroll(int id){ + return scrolls.get(id); + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks){ + scrollY = (float) lerp(scrollY, nextScrollY, partialTicks); + boolean drawBackground = this.drawDefaultBackground; + + GL11.glPushMatrix(); + + // Enable clipping + GL11.glEnable(GL11.GL_SCISSOR_TEST); + setClip(xPos, yPos, clipWidth, clipHeight); + + this.drawDefaultBackground = false; + if(drawBackground) + this.drawGradientRect(0, 0, this.width, this.height, 0x66000000, 0x88000000); + + + if(maxScrollY > 0) + setClip(xPos, yPos, clipWidth-13, clipHeight); + + GL11.glTranslatef(xPos, yPos-scrollY, 0); + + + this.drawComponents(mouseX -xPos, (int) (mouseY +scrollY-yPos), partialTicks); + + + this.drawDefaultBackground = drawBackground; + + //Disable clipping (VERY IMPORTANT) + GL11.glDisable(GL11.GL_SCISSOR_TEST); + GL11.glTranslatef(-xPos, -yPos+scrollY, 0); + + if(maxScrollY > 0){ + drawScrollBar(); + } + + GL11.glPopMatrix(); + } + + public void drawScreen(int mouseX, int mouseY, float partialTicks, int mouseScroll){ + adjustScroll(mouseX, mouseY, mouseScroll); + this.mouseScroll = mouseScroll; + this.drawScreen(mouseX, mouseY, partialTicks); + } + + public void drawComponents(int i, int j, float f){ + if(drawDefaultBackground) + drawDefaultBackground(); + + boolean subGui = parent.hasSubGui(); + for(GuiNpcLabel label : labels.values()) + label.drawLabel(this,fontRendererObj); + for(GuiNpcTextField tf : textfields.values()){ + tf.drawTextBox(i, j); + } + for(GuiCustomScroll scroll : scrolls.values()){ + scroll.updateSubGUI(subGui); + scroll.drawScreen(i, j, f, !subGui && scroll.isMouseOver(i, j)?mouseScroll:0); + } + super.drawScreen(i, j, f); + for(GuiCustomScroll scroll : scrolls.values()) + if(scroll.hoverableText){ + scroll.drawHover(i, j); + } + for(GuiNpcButton button : buttons.values()){ + button.updateSubGUI(subGui); + if(!button.hoverableText.isEmpty()){ + button.drawHover(i, j, subGui); + } + } + } + + public void elementClicked() { + parent.elementClicked(); + } + @Override + public boolean doesGuiPauseGame(){ + return false; + } + + public void doubleClicked() {} + + public boolean isInventoryKey(int i){ + return i == mc.gameSettings.keyBindInventory.getKeyCode(); //inventory key + } + + @Override + public void drawDefaultBackground() { + super.drawDefaultBackground(); + } + + protected void setClip(int x, int y, int width, int height){ + if(scaledResolution == null) + return; + int scaleFactor = scaledResolution.getScaleFactor(); + + + // Correct the positions for Screen Space in OpenGL + x*=scaleFactor; + y*=scaleFactor; + width*=scaleFactor; + height*=scaleFactor; + + // Adjust position to Top-Left origin (OpenGL window/screen space uses bottom-left origin) + y=mc.displayHeight-y; + + // Set clip + GL11.glScissor(x, y-height, width, height); + } + + public boolean isMouseOver(int mouseX, int mouseY){ + return mouseX >= xPos && mouseX <= clipWidth+xPos && mouseY >= yPos && mouseY <= clipHeight+yPos; + } + + public void adjustScroll(int mouseX, int mouseY, int mouseScroll) { + mouseX -= xPos; + mouseY -= yPos; + if(Mouse.isButtonDown(0)){ + if(mouseX >= clipWidth-9 && mouseX < clipWidth-4 && mouseY >= 4 && mouseY < clipHeight){ + isScrolling = true; + } + } + else + isScrolling = false; + + if(isScrolling){ + // This Scroll Y is wrong + float proportion = (mouseY - 4) / (float) (clipHeight - 8); + nextScrollY = (int) (proportion * maxScrollY); + if(nextScrollY < 0){ + nextScrollY = 0; + } + if(nextScrollY > maxScrollY){ + nextScrollY = maxScrollY; + } + } + + for(GuiCustomScroll guiCustomScroll : scrolls.values()) { + if (guiCustomScroll.isMouseOver(mouseX, (int) (mouseY + scrollY))) { + return; + } + } + + if(mouseScroll != 0){ + nextScrollY -= (float) mouseScroll/15; + if(nextScrollY > maxScrollY) + nextScrollY = maxScrollY; + if(nextScrollY < 0) + nextScrollY = 0; + } + } + + private void drawScrollBar() + { + mc.renderEngine.bindTexture(resource); + GL11.glColor4f(1, 1, 1, 1); + + int maxSize = (int) ((clipHeight) * ( (double) (clipHeight)/ (clipHeight + maxScrollY))); + int x = xPos + clipWidth - 9; + int y = (int) (yPos + 4 + (scrollY/maxScrollY * (clipHeight-maxSize-8))); + + for(int k = y; k < y+maxSize && k-clipHeight+maxSize < clipHeight + yPos;k++){ + drawTexturedModalRect(x, k, 176, 9, 5, 1); + } + } + + private double lerp(double a, double b, double lambda){ + return a + lambda * (b - a); + } + + + @Override + public void customScrollClicked(int i, int j, int k, GuiCustomScroll guiCustomScroll) { + if(parent instanceof ICustomScrollListener) + ((ICustomScrollListener) parent).customScrollClicked(i, j, k, guiCustomScroll); + } + + @Override + public void customScrollDoubleClicked(String selection, GuiCustomScroll scroll) { + if(parent instanceof ICustomScrollListener) + ((ICustomScrollListener) parent).customScrollDoubleClicked(selection, scroll); + } + + @Override + public void unFocused(GuiNpcTextField textfield) { + if(parent instanceof ITextfieldListener) + ((ITextfieldListener) parent).unFocused(textfield); + } +} diff --git a/src/main/java/noppes/npcs/client/gui/util/GuiScrollableComponent.java b/src/main/java/noppes/npcs/client/gui/util/GuiScrollableComponent.java deleted file mode 100644 index 7283d2c17..000000000 --- a/src/main/java/noppes/npcs/client/gui/util/GuiScrollableComponent.java +++ /dev/null @@ -1,199 +0,0 @@ -package noppes.npcs.client.gui.util; - -import net.minecraft.client.gui.GuiButton; -import net.minecraft.client.gui.ScaledResolution; -import net.minecraft.util.ChatComponentText; -import net.minecraft.util.ResourceLocation; -import noppes.npcs.client.gui.custom.GuiCustom; -import noppes.npcs.entity.EntityNPCInterface; -import noppes.npcs.scripted.CustomNPCsException; -import org.lwjgl.input.Mouse; -import org.lwjgl.opengl.GL11; - -import java.util.Arrays; - -public class GuiScrollableComponent extends GuiNPCInterface{ - - public static final ResourceLocation resource = new ResourceLocation("customnpcs","textures/gui/misc.png"); - protected ScaledResolution scaledResolution; - public int clipWidth; - public int clipHeight; - boolean isScrolling; - - protected int xPos = 0; - protected int yPos = 0; - - protected int maxScrollY = 0; - protected float scrollY = 0; - protected float nextScrollY = 0; - - private double lerp(double a, double b, double lambda){ - return a + lambda * (b - a); - } - - /** - * Scrollable GUI component :P? - * @param npc npc - * @param posX the X Position of the gui element on the screen - * @param posY the Y Position of the GUI element on the screen - * @param clipWidth width of the element - * @param clipHeight height of the element - * @param maxScroll extra Y area displayed through the scrollbar. - */ - public GuiScrollableComponent(EntityNPCInterface npc, int posX, int posY, int clipWidth, int clipHeight, int maxScroll){ - super(npc); - this.xPos = posX; - this.yPos = posY; - this.clipWidth = clipWidth; - this.clipHeight = clipHeight; - this.maxScrollY = maxScroll; - } - - @Override - public void save() { - - } - - @Override - public void initGui(){ - super.initGui(); - scaledResolution = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); - - float scrollPerc = 0; - if((guiTop+clipHeight) != 0){ - scrollPerc = (nextScrollY) / (clipHeight); - } - - nextScrollY = scrollPerc * (clipHeight); - } - - @Override - public void drawScreen(int mouseX, int mouseY, float partialTicks){ - scrollY = (float) lerp(scrollY, nextScrollY, partialTicks); - boolean drawBackground = this.drawDefaultBackground; - - GL11.glPushMatrix(); - - //Enable clipping - GL11.glEnable(GL11.GL_SCISSOR_TEST); - setClip(xPos, yPos, clipWidth, clipHeight); - - this.drawDefaultBackground = false; - if(drawBackground) - this.drawDefaultBackground(); - - - if(maxScrollY > 0) - setClip(xPos, yPos, clipWidth-13, clipHeight); - - GL11.glTranslatef(xPos, yPos-scrollY, 0); - super.drawScreen(mouseX-xPos, (int) (mouseY+scrollY-yPos), partialTicks); - - this.drawDefaultBackground = drawBackground; - - //Disable clipping (VERY IMPORTANT) - GL11.glDisable(GL11.GL_SCISSOR_TEST); - GL11.glTranslatef(-xPos, -yPos+scrollY, 0); - - if(maxScrollY > 0){ - drawScrollBar(); - } - - GL11.glPopMatrix(); - } - - public void drawScreen(int mouseX, int mouseY, float partialTicks, int mouseScroll){ - adjustScroll(mouseX, mouseY, mouseScroll); - - GuiNPCInterface.recordScroll = false; - this.drawScreen(mouseX, mouseY, partialTicks); - GuiNPCInterface.recordScroll = true; - } - - private void drawScrollBar() - { - mc.renderEngine.bindTexture(resource); - GL11.glColor4f(1, 1, 1, 1); - - int maxSize = (int) ((clipHeight) * ( (double) (clipHeight)/ (clipHeight + maxScrollY))); - int x = xPos + clipWidth - 9; - int y = (int) (yPos + 4 + (scrollY/maxScrollY * (clipHeight-maxSize-8))); - - for(int k = y; k < y+maxSize && k-clipHeight+maxSize < clipHeight + yPos;k++){ - drawTexturedModalRect(x, k, 176, 9, 5, 1); - } - } - - public void adjustScroll(int mouseX, int mouseY, int mouseScroll) { - mouseX -= xPos; - mouseY -= yPos; - if(Mouse.isButtonDown(0)){ - if(mouseX >= clipWidth-9 && mouseX < clipWidth-4 && mouseY >= 4 && mouseY < clipHeight){ - isScrolling = true; - } - } - else - isScrolling = false; - - if(isScrolling){ - // This Scroll Y is wrong - float proportion = (mouseY - 4) / (float) (clipHeight - 8); - nextScrollY = (int) (proportion * maxScrollY); - if(nextScrollY < 0){ - nextScrollY = 0; - } - if(nextScrollY > maxScrollY){ - nextScrollY = maxScrollY; - } - } - - if(mouseScroll != 0){ - nextScrollY -= (float) mouseScroll/15; - if(nextScrollY > maxScrollY) - nextScrollY = maxScrollY; - if(nextScrollY < 0) - nextScrollY = 0; - } - } - - @Override - public void addScrollableGui(int id, GuiScrollableComponent d){ - throw new CustomNPCsException("You can't put scrollable GUIs into a scrollable GUI"); - } - - @Override - public void buttonEvent(GuiButton button){} - - @Override - public void mouseClicked(int mouseX, int mouseY, int mouseButton){ - super.mouseClicked(mouseX-xPos, (int) (mouseY-yPos+scrollY), mouseButton); - } - - @Override - public void handleMouseInput(){ - super.handleMouseInput(); - } - - public boolean isMouseOver(int mouseX, int mouseY){ - return mouseX >= xPos && mouseX <= clipWidth+xPos && mouseY >= yPos && mouseY <= clipHeight+yPos; - } - - protected void setClip(int x, int y, int width, int height){ - if(scaledResolution == null) - return; - int scaleFactor = scaledResolution.getScaleFactor(); - - - //Correct the positions for Screen Space in OpenGL - x*=scaleFactor; - y*=scaleFactor; - width*=scaleFactor; - height*=scaleFactor; - - //Adjust position to Top-Left origin (OpenGL window/screen space uses bottom-left origin) - y=mc.displayHeight-y; - - //Set clip - GL11.glScissor(x, y-height, width, height); - } -}