diff options
12 files changed, 207 insertions, 131 deletions
diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c0fbc46 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,5 @@ +root = true + +[*] +charset = utf-8 +indent_style = tab diff --git a/GuiTest/src/main/java/io/github/cottonmc/test/client/TestClientGui.java b/GuiTest/src/main/java/io/github/cottonmc/test/client/TestClientGui.java index bf4ef07..9bbd1fc 100644 --- a/GuiTest/src/main/java/io/github/cottonmc/test/client/TestClientGui.java +++ b/GuiTest/src/main/java/io/github/cottonmc/test/client/TestClientGui.java @@ -33,9 +33,8 @@ public class TestClientGui extends LightweightGuiDescription { label.setText(new LiteralText(s)); }; WListPanel<String, WLabel> list = new WListPanel<String, WLabel>(data, WLabel.class, ()->new WLabel(""), configurator); - root.add(list, 0, 2, 7, 8); + root.add(list, 0, 2, 7, 5); root.validate(this); } - } @@ -12,4 +12,6 @@ See the [Cotton wiki](https://cottonmc.github.io/Wiki/getting_started/SetupDevel And for code examples: * [Client-Only Guis](https://github.com/CottonMC/LibGui/wiki/Client-Sided-Guis) -* [Inventory Guis](https://github.com/CottonMC/LibGui/wiki/Getting-Started-with-GUIs)
\ No newline at end of file +* [Inventory Guis](https://github.com/CottonMC/LibGui/wiki/Getting-Started-with-GUIs) + +For an idea of what's coming down the road for all my projects, you can check my roadmap at https://trello.com/b/0TVU8d63/falkreons-roadmap diff --git a/gradle.properties b/gradle.properties index 45585f4..4d01f74 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ org.gradle.jvmargs=-Xmx1G loader_version=0.4.8+build.158 # Mod Properties - mod_version = 1.3.1-SNAPSHOT + mod_version = 1.3.2-beta.1 maven_group = io.github.cottonmc archives_base_name = LibGui diff --git a/src/main/java/io/github/cottonmc/cotton/gui/CottonScreenController.java b/src/main/java/io/github/cottonmc/cotton/gui/CottonScreenController.java index 4710d5b..0e95295 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/CottonScreenController.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/CottonScreenController.java @@ -306,7 +306,7 @@ public class CottonScreenController extends CraftingContainer<Inventory> impleme } } - if (rootPanel!=null) rootPanel.onClick(x, y, button); + //if (rootPanel!=null) rootPanel.onClick(x, y, button); } public void doCharType(char ch) { diff --git a/src/main/java/io/github/cottonmc/cotton/gui/client/ClientCottonScreen.java b/src/main/java/io/github/cottonmc/cotton/gui/client/ClientCottonScreen.java index 16c0484..16921cf 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/client/ClientCottonScreen.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/client/ClientCottonScreen.java @@ -57,7 +57,7 @@ public class ClientCottonScreen extends Screen { @Override public void render(int mouseX, int mouseY, float partialTicks) { - renderBackground(); + renderBackground(mouseX, mouseY); super.render(mouseX, mouseY, partialTicks); @@ -69,14 +69,13 @@ public class ClientCottonScreen extends Screen { } } - @Override - public void renderBackground() { + public void renderBackground(int mouseX, int mouseY) { super.renderBackground(); if (description!=null) { WPanel root = description.getRootPanel(); if (root!=null) { - root.paintBackground(left, top); + root.paintBackground(left, top, mouseX-left, mouseY-top); } } @@ -93,6 +92,7 @@ public class ClientCottonScreen extends Screen { @Override public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) { + if (description.getRootPanel()==null) return super.mouseClicked(mouseX, mouseY, mouseButton); WWidget focus = description.getFocus(); if (focus!=null) { @@ -107,28 +107,36 @@ public class ClientCottonScreen extends Screen { } } - if (description.getRootPanel()==null) return super.mouseClicked(mouseX, mouseY, mouseButton); - boolean result = super.mouseClicked(mouseX, mouseY, mouseButton); int containerX = (int)mouseX-left; int containerY = (int)mouseY-top; if (containerX<0 || containerY<0 || containerX>=width || containerY>=height) return result; - lastResponder = description.getRootPanel().onMouseDown(containerX, containerY, mouseButton); - + if (lastResponder==null) { + lastResponder = description.getRootPanel().hit(containerX, containerY); + if (lastResponder!=null) lastResponder.onMouseDown(containerX-lastResponder.getAbsoluteX(), containerY-lastResponder.getAbsoluteY(), mouseButton); + } else { + //This is a drag instead + } return result; + } @Override public boolean mouseReleased(double mouseX, double mouseY, int mouseButton) { if (description.getRootPanel()==null) return super.mouseReleased(mouseX, mouseY, mouseButton); - boolean result = super.mouseReleased(mouseX, mouseY, mouseButton); int containerX = (int)mouseX-left; int containerY = (int)mouseY-top; - if (containerX<0 || containerY<0 || containerX>=width || containerY>=height) return result; - WWidget responder = description.getRootPanel().onMouseUp(containerX, containerY, mouseButton); - if (responder!=null && responder==lastResponder) description.getRootPanel().onClick(containerX, containerY, mouseButton); + if (lastResponder!=null) { + lastResponder.onMouseUp(containerX-lastResponder.getAbsoluteX(), containerY-lastResponder.getAbsoluteY(), mouseButton); + if (containerX>=0 && containerY>=0 && containerX<width && containerY<height) { + lastResponder.onClick(containerX-lastResponder.getAbsoluteX(), containerY-lastResponder.getAbsoluteY(), mouseButton); + } + } else { + description.getRootPanel().onMouseUp(containerX, containerY, mouseButton); + } + lastResponder = null; return result; } @@ -136,12 +144,18 @@ public class ClientCottonScreen extends Screen { @Override public boolean mouseDragged(double mouseX, double mouseY, int mouseButton, double unknown_1, double unknown_2) { if (description.getRootPanel()==null) return super.mouseDragged(mouseX, mouseY, mouseButton, unknown_1, unknown_2); - boolean result = super.mouseDragged(mouseX, mouseY, mouseButton, unknown_1, unknown_2); + int containerX = (int)mouseX-left; int containerY = (int)mouseY-top; - if (containerX<0 || containerY<0 || containerX>=width || containerY>=height) return result; - description.getRootPanel().onMouseDrag(containerX, containerY, mouseButton); + + if (lastResponder!=null) { + lastResponder.onMouseDrag(containerX-lastResponder.getAbsoluteX(), containerY-lastResponder.getAbsoluteY(), mouseButton); + return result; + } else { + if (containerX<0 || containerY<0 || containerX>=width || containerY>=height) return result; + description.getRootPanel().onMouseDrag(containerX, containerY, mouseButton); + } return result; } diff --git a/src/main/java/io/github/cottonmc/cotton/gui/client/CottonScreen.java b/src/main/java/io/github/cottonmc/cotton/gui/client/CottonScreen.java index 6935894..bb9f665 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/client/CottonScreen.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/client/CottonScreen.java @@ -100,7 +100,11 @@ public class CottonScreen<T extends CottonScreenController> extends AbstractCont int containerX = (int)mouseX-left; int containerY = (int)mouseY-top; if (containerX<0 || containerY<0 || containerX>=width || containerY>=height) return result; - lastResponder = container.doMouseDown(containerX, containerY, mouseButton); + if (lastResponder==null) { + lastResponder = container.doMouseDown(containerX, containerY, mouseButton); + } else { + //This is a drag instead + } return result; } @@ -109,10 +113,16 @@ public class CottonScreen<T extends CottonScreenController> extends AbstractCont boolean result = super.mouseReleased(mouseX, mouseY, mouseButton); int containerX = (int)mouseX-left; int containerY = (int)mouseY-top; - if (containerX<0 || containerY<0 || containerX>=width || containerY>=height) return result; - WWidget responder = container.doMouseUp(containerX, containerY, mouseButton); - if (responder!=null && responder==lastResponder) container.doClick(containerX, containerY, mouseButton); + if (lastResponder!=null) { + lastResponder.onMouseUp(containerX-lastResponder.getAbsoluteX(), containerY-lastResponder.getAbsoluteY(), mouseButton); + if (containerX>=0 && containerY>=0 && containerX<width && containerY<height) { + lastResponder.onClick(containerX-lastResponder.getAbsoluteX(), containerY-lastResponder.getAbsoluteY(), mouseButton); + } + } else { + container.doMouseUp(containerX, containerY, mouseButton); + } + lastResponder = null; return result; } @@ -123,8 +133,14 @@ public class CottonScreen<T extends CottonScreenController> extends AbstractCont int containerX = (int)mouseX-left; int containerY = (int)mouseY-top; - if (containerX<0 || containerY<0 || containerX>=width || containerY>=height) return result; - container.doMouseDrag(containerX, containerY, mouseButton); + + if (lastResponder!=null) { + lastResponder.onMouseDrag(containerX-lastResponder.getAbsoluteX(), containerY-lastResponder.getAbsoluteY(), mouseButton); + return result; + } else { + if (containerX<0 || containerY<0 || containerX>=width || containerY>=height) return result; + container.doMouseDrag(containerX, containerY, mouseButton); + } return result; } @@ -171,7 +187,7 @@ public class CottonScreen<T extends CottonScreenController> extends AbstractCont WPanel root = this.container.getRootPanel(); if (root==null) return; - root.paintBackground(left, top); + root.paintBackground(left, top, mouseX-left, mouseY-top); //TODO: Change this to a label that lives in the rootPanel instead? if (container instanceof Nameable) { diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WButton.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WButton.java index 0f5159c..32558a9 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WButton.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WButton.java @@ -31,7 +31,7 @@ public class WButton extends WWidget { @Override public void paintForeground(int x, int y, int mouseX, int mouseY) { - System.out.println("Mouse: { "+mouseX+", "+mouseY+" }"); + //System.out.println("Mouse: { "+mouseX+", "+mouseY+" }"); boolean hovered = (mouseX>=x && mouseY>=y && mouseX<x+getWidth() && mouseY<y+getHeight()); int state = 1; //1=regular. 2=hovered. 0=disabled. @@ -75,7 +75,7 @@ public class WButton extends WWidget { public void onClick(int x, int y, int button) { super.onClick(x, y, button); - if (enabled) { + if (enabled && isWithinBounds(x, y)) { MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F)); if (onClick!=null) onClick.run(); diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WListPanel.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WListPanel.java index de3c7ed..abb403e 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WListPanel.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WListPanel.java @@ -40,7 +40,7 @@ public class WListPanel<D, W extends WWidget> extends WPanel { } @Override - public void paintBackground(int x, int y) { + public void paintBackground(int x, int y, int mouseX, int mouseY) { if (getBackgroundPainter()!=null) { getBackgroundPainter().paintBackground(x, y, this); } else { @@ -58,75 +58,83 @@ public class WListPanel<D, W extends WWidget> extends WPanel { } @Override - public void layout() { - //super.layout(); - - System.out.println("Validating"); - - //Recompute cellHeight if needed - if (!fixedHeight) { - if (unconfigured.isEmpty()) { - if (configured.isEmpty()) { - W exemplar = supplier.get(); - unconfigured.add(exemplar); - if (!exemplar.canResize()) cellHeight = exemplar.getHeight(); - } else { - W exemplar = configured.values().iterator().next(); - if (!exemplar.canResize()) cellHeight = exemplar.getHeight(); - } + public void layout() { + + this.children.clear(); + this.children.add(scrollBar); + scrollBar.setLocation(this.width-scrollBar.getWidth(), 0); + scrollBar.setSize(8, this.height); + //scrollBar.window = 6; + scrollBar.setMaxValue(data.size()); + + //super.layout(); + + //System.out.println("Validating"); + + //Recompute cellHeight if needed + if (!fixedHeight) { + if (unconfigured.isEmpty()) { + if (configured.isEmpty()) { + W exemplar = supplier.get(); + unconfigured.add(exemplar); + if (!exemplar.canResize()) cellHeight = exemplar.getHeight(); } else { - W exemplar = unconfigured.get(0); + W exemplar = configured.values().iterator().next(); if (!exemplar.canResize()) cellHeight = exemplar.getHeight(); } + } else { + W exemplar = unconfigured.get(0); + if (!exemplar.canResize()) cellHeight = exemplar.getHeight(); } - if (cellHeight<4) cellHeight=4; - - int layoutHeight = this.getHeight()-(margin*2); - int cellsHigh = layoutHeight / cellHeight; - - - System.out.println("Adding children..."); - - this.children.clear(); - this.children.add(scrollBar); - scrollBar.setLocation(this.width-scrollBar.getWidth(), 0); - scrollBar.setSize(8, this.height); - - //Fix up the scrollbar handle and track metrics - scrollBar.window = cellsHigh; - scrollBar.setMaxValue(data.size()); - int scrollOffset = scrollBar.value; - System.out.println(scrollOffset); - - int presentCells = Math.min(data.size()-scrollOffset, cellsHigh); - - if (presentCells>0) { - for(int i=0; i<presentCells; i++) { - int index = i+scrollOffset; - D d = data.get(index); - W w = configured.get(d); - if (w==null) { - if (unconfigured.isEmpty()) { - w = supplier.get(); - } else { - w = unconfigured.remove(0); - } - configurator.accept(d, w); - configured.put(d, w); - } - - //At this point, w is nonnull and configured by d - if (w.canResize()) { - w.setSize(this.width-(margin*2), cellHeight); + } + if (cellHeight<4) cellHeight=4; + + int layoutHeight = this.getHeight()-(margin*2); + int cellsHigh = layoutHeight / cellHeight; + + + //System.out.println("Adding children..."); + + //this.children.clear(); + //this.children.add(scrollBar); + //scrollBar.setLocation(this.width-scrollBar.getWidth(), 0); + //scrollBar.setSize(8, this.height); + + //Fix up the scrollbar handle and track metrics + scrollBar.window = cellsHigh; + //scrollBar.setMaxValue(data.size()); + int scrollOffset = scrollBar.value; + //System.out.println(scrollOffset); + + int presentCells = Math.min(data.size()-scrollOffset, cellsHigh); + + if (presentCells>0) { + for(int i=0; i<presentCells; i++) { + int index = i+scrollOffset; + D d = data.get(index); + W w = configured.get(d); + if (w==null) { + if (unconfigured.isEmpty()) { + w = supplier.get(); + } else { + w = unconfigured.remove(0); } - w.x = margin; - w.y = margin + (cellHeight * i); - this.children.add(w); + configurator.accept(d, w); + configured.put(d, w); + } + + //At this point, w is nonnull and configured by d + if (w.canResize()) { + w.setSize(this.width-(margin*2) - scrollBar.getWidth(), cellHeight); } + w.x = margin; + w.y = margin + (cellHeight * i); + this.children.add(w); } - - System.out.println("Children: "+children.size()); } + + //System.out.println("Children: "+children.size()); + } public WListPanel<D, W> setListItemHeight(int height) { cellHeight = height; diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java index 055e188..cda638d 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java @@ -103,7 +103,7 @@ public abstract class WPanel extends WWidget { } super.onMouseDrag(x, y, button); } - + /* @Override public void onClick(int x, int y, int button) { if (children.isEmpty()) return; @@ -117,6 +117,24 @@ public abstract class WPanel extends WWidget { return; //Only send the message to the first valid recipient } } + }*/ + + /** + * Finds the most specific child node at this location. + */ + @Override + public WWidget hit(int x, int y) { + if (children.isEmpty()) return this; + for(int i=children.size()-1; i>=0; i--) { //Backwards so topmost widgets get priority + WWidget child = children.get(i); + if ( x>=child.getX() && + y>=child.getY() && + x<child.getX()+child.getWidth() && + y<child.getY()+child.getHeight()) { + return child.hit(x, y); + } + } + return this; } @Override @@ -127,11 +145,11 @@ public abstract class WPanel extends WWidget { @Environment(EnvType.CLIENT) @Override - public void paintBackground(int x, int y) { + public void paintBackground(int x, int y, int mouseX, int mouseY) { if (backgroundPainter!=null) backgroundPainter.paintBackground(x, y, this); for(WWidget child : children) { - child.paintBackground(x + child.getX(), y + child.getY()); + child.paintBackground(x + child.getX(), y + child.getY(), mouseX-child.getX(), mouseY-child.getY()); } } diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WScrollBar.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WScrollBar.java index f84342c..524b0d2 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WScrollBar.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WScrollBar.java @@ -10,6 +10,7 @@ public class WScrollBar extends WWidget { protected int anchor = -1; protected int anchorValue = -1; + protected boolean sliding = false; public WScrollBar() { } @@ -31,39 +32,34 @@ public class WScrollBar extends WWidget { } } - @Override - public void paintForeground(int x, int y, int mouseX, int mouseY) { - super.paintForeground(x, y, mouseX, mouseY); - - //Sneakily update bar position - if (anchor!=-1) { - onMouseDown(mouseX+x, mouseY+y, 0); - } - } - /** * Gets the on-axis size of the scrollbar handle in gui pixels */ public int getHandleSize() { float percentage = (window>=maxValue) ? 1f : window / (float)maxValue; int bar = (axis==Axis.HORIZONTAL) ? width-2 : height-2; - return (int)(percentage*bar); + int result = (int)(percentage*bar); + if (result<6) result = 6; + return result; } /** * Gets the number of pixels the scrollbar handle is able to move along its track from one end to the other. */ public int getMovableDistance() { - int logicalDistance = maxValue-window; - if (logicalDistance<0) logicalDistance = 0; - float percentage = logicalDistance / (float)maxValue; - - //System.out.println("MovableDistance! maxValue: "+maxValue+", window: "+window+", logicalDistance: "+logicalDistance+", percentage: "+percentage); - return (int) ( (axis==Axis.HORIZONTAL) ? (width-2)*percentage : (height-2)*percentage); + int bar = (axis==Axis.HORIZONTAL) ? width-2 : height-2; + return bar-getHandleSize(); + } + + public int pixelsToValues(int pixels) { + int bar = (axis==Axis.HORIZONTAL) ? width-2 : height-2; + //int bar = getMovableDistance(); + float percent = pixels / (float)bar; + return (int)(percent*(maxValue-window)); } public int getHandlePosition() { - float percent = value / (float)Math.max(maxValue, 1); + float percent = value / (float)Math.max(maxValue-window, 1); return (int)(percent * getMovableDistance()); } @@ -75,6 +71,23 @@ public class WScrollBar extends WWidget { return maxValue - window; } + protected void adjustSlider(int x, int y) { + + int delta = 0; + if (axis==Axis.HORIZONTAL) { + delta = x-anchor; + } else { + delta = y-anchor; + } + + int valueDelta = pixelsToValues(delta); + int valueNew = anchorValue + valueDelta; + + if (valueNew>getMaxScrollValue()) valueNew = getMaxScrollValue(); + if (valueNew<0) valueNew = 0; + this.value = valueNew; + } + @Override public WWidget onMouseDown(int x, int y, int button) { //TODO: Clicking before or after the handle should jump instead of scrolling @@ -86,28 +99,13 @@ public class WScrollBar extends WWidget { anchor = y; anchorValue = value; } + sliding = true; return this; } @Override public void onMouseDrag(int x, int y, int button) { - int delta = 0; - if (axis==Axis.HORIZONTAL) { - delta = x-anchor; - } else { - delta = y-anchor; - } - - float percentMoved = (delta / (float)getMovableDistance()); - int valueDelta = (int)(percentMoved * maxValue); - int valueNew = anchorValue + valueDelta; - if (valueNew>getMaxScrollValue()) valueNew = getMaxScrollValue(); - if (valueNew<0) valueNew = 0; - this.value = valueNew; - - //System.out.println("Anchor: "+anchor+", Delta: "+delta+", PercentMoved: "+percentMoved+", ValueDelta: "+valueDelta); - - super.onMouseDrag(x, y, button); + adjustSlider(x, y); } @Override @@ -115,7 +113,7 @@ public class WScrollBar extends WWidget { //TODO: Clicking before or after the handle should jump instead of scrolling anchor = -1; anchorValue = -1; - + sliding = false; return this; } diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WWidget.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WWidget.java index 9d0c80a..1314f88 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WWidget.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WWidget.java @@ -177,6 +177,11 @@ public class WWidget { } @Environment(EnvType.CLIENT) + public void paintBackground(int x, int y, int mouseX, int mouseY) { + this.paintBackground(x, y); + } + + @Environment(EnvType.CLIENT) public void paintBackground(int x, int y) { } @@ -187,6 +192,10 @@ public class WWidget { } } + public boolean isWithinBounds(int x, int y) { + return x>=0 && y>=0 && x<this.width && y<this.height; + } + /** * Internal method to conditionally render tooltip data. This requires an overriden {@link #addInformation(List) * addInformation} method to insert data into the tooltip - without this, the method returns early, because no work @@ -220,5 +229,12 @@ public class WWidget { * @param information List containing all previous tooltip data. */ public void addInformation(List<String> information) { -} + } + + /** + * Find the most specific child node at this location. For non-panel widgets, returns this widget. + */ + public WWidget hit(int x, int y) { + return this; + } } |