aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/kr
diff options
context:
space:
mode:
authorsyeyoung <cyong06@naver.com>2021-07-21 00:08:48 +0900
committersyeyoung <cyong06@naver.com>2021-07-21 00:34:14 +0900
commita6009e4aef3a8f8b641733d62034bf629afd7053 (patch)
treee23467327f1e9ddc2ffcdc4604e6d5fbb1ccecf2 /src/main/java/kr
parentaa804403a1dcc8f9b36672e0e56e591e810147b3 (diff)
downloadSkyblock-Dungeons-Guide-a6009e4aef3a8f8b641733d62034bf629afd7053.tar.gz
Skyblock-Dungeons-Guide-a6009e4aef3a8f8b641733d62034bf629afd7053.tar.bz2
Skyblock-Dungeons-Guide-a6009e4aef3a8f8b641733d62034bf629afd7053.zip
Add Scroll Bar and Scrollable Panel
Diffstat (limited to 'src/main/java/kr')
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/gui/MPanel.java9
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/gui/elements/MList.java69
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/gui/elements/MScrollBar.java145
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/gui/elements/MScrollablePanel.java181
4 files changed, 403 insertions, 1 deletions
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/gui/MPanel.java b/src/main/java/kr/syeyoung/dungeonsguide/gui/MPanel.java
index aa949d16..319a7af8 100644
--- a/src/main/java/kr/syeyoung/dungeonsguide/gui/MPanel.java
+++ b/src/main/java/kr/syeyoung/dungeonsguide/gui/MPanel.java
@@ -104,6 +104,11 @@ public class MPanel {
}
protected Point lastParentPoint;
+
+ @Getter
+ @Setter
+ private boolean ignoreBoundOnClip;
+
public void render0(ScaledResolution resolution, Point parentPoint, Rectangle parentClip, int absMousex, int absMousey, int relMousex0, int relMousey0, float partialTicks) { // 0,0 - a a
lastParentPoint = parentPoint;
@@ -116,7 +121,9 @@ public class MPanel {
Rectangle absBound = getBounds().getBounds();
absBound.setLocation(absBound.x + parentPoint.x, absBound.y + parentPoint.y);
- Rectangle clip = determineClip(parentClip, absBound);
+ Rectangle clip;
+ if (ignoreBoundOnClip) clip = parentClip;
+ else clip = determineClip(parentClip, absBound);
lastAbsClip = clip;
if (clip.getSize().height * clip.getSize().width == 0) return;
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/gui/elements/MList.java b/src/main/java/kr/syeyoung/dungeonsguide/gui/elements/MList.java
new file mode 100644
index 00000000..de3e4b40
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/gui/elements/MList.java
@@ -0,0 +1,69 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.gui.elements;
+
+import kr.syeyoung.dungeonsguide.gui.MPanel;
+import lombok.Getter;
+import net.minecraft.client.gui.Gui;
+
+import java.awt.*;
+
+public class MList extends MPanel {
+ @Getter
+ private int gap = 5;
+
+ public void setGap(int gap) {
+ this.gap = gap;
+ realignChildren();
+ }
+
+ private final int gapLineColor = 0xFFFFFFFF;
+
+ protected void realignChildren() {
+ int y = 0;
+ for (MPanel childComponent : getChildComponents()) {
+ Dimension preferedSize = childComponent.getPreferredSize();
+ childComponent.setBounds(new Rectangle(0, y, bounds.width, Math.max(10, preferedSize.height)));
+ y += preferedSize.height;
+ y += gap;
+ }
+ setSize(new Dimension(getSize().width, Math.max(0, y-gap)));
+ }
+
+ @Override
+ public void render(int absMousex, int absMousey, int relMousex0, int relMousey0, float partialTicks, Rectangle scissor) {
+ for (int i = 1; i < getChildComponents().size(); i++) {
+ MPanel panel = getChildComponents().get(i);
+ Rectangle bound = panel.getBounds();
+ Gui.drawRect(0,bound.y - (gap/2), getBounds().width, bound.y - (gap/2)+1, gapLineColor);
+ }
+ }
+
+ @Override
+ public void add(MPanel child) {
+ super.add(child);
+ realignChildren();
+ }
+
+ @Override
+ public void remove(MPanel panel) {
+ super.remove(panel);
+ realignChildren();
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/gui/elements/MScrollBar.java b/src/main/java/kr/syeyoung/dungeonsguide/gui/elements/MScrollBar.java
new file mode 100644
index 00000000..ecd94b07
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/gui/elements/MScrollBar.java
@@ -0,0 +1,145 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.gui.elements;
+
+import kr.syeyoung.dungeonsguide.config.types.AColor;
+import kr.syeyoung.dungeonsguide.gui.MPanel;
+import kr.syeyoung.dungeonsguide.utils.RenderUtils;
+import lombok.Getter;
+import lombok.Setter;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.util.MathHelper;
+
+import java.awt.*;
+
+public class MScrollBar extends MPanel {
+ private final Axis axis;
+ @Setter
+ @Getter
+ private int thumbSize, max, min;
+ @Setter
+ @Getter
+ private int current;
+
+ public void addToCurrent(int dv) {
+ int current2 = current + dv;
+
+ current = MathHelper.clamp_int(current2, min, max - thumbSize);
+ if (max - min < thumbSize) current = min;
+
+ if (onUpdate != null) onUpdate.run();
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ return new Dimension(axis == Axis.X ? -1 : 20, axis == Axis.Y ? -1 : 20);
+ }
+
+ @Getter
+ @Setter
+ private int background = RenderUtils.blendAlpha(0xFF141414, 0.04f),
+ thumb = RenderUtils.blendAlpha(0xFF141414, 0.08f),
+ thumbHover = RenderUtils.blendAlpha(0xFF141414, 0.09f),
+ thumbClick = RenderUtils.blendAlpha(0xFF141414, 0.14f);
+
+ private Runnable onUpdate;
+
+ public MScrollBar(int min, int max, int thumbSize, int current, Axis axis, Runnable onUpdate) {
+ this.min = min; this.min = max; this.thumbSize = thumbSize; this.current = current; this.axis = axis;
+ this.current = MathHelper.clamp_int(current, min, max - thumbSize);
+ if (max - min < thumbSize) this.current = min;
+ this.onUpdate = onUpdate;
+ }
+
+ @Override
+ public void render(int absMousex, int absMousey, int relMousex0, int relMousey0, float partialTicks, Rectangle scissor) {
+ // RENDER SUPER NICE SCROLL BAR
+ Gui.drawRect(0,0,getBounds().width, getBounds().height, background);
+ double startPerc, endPerc;
+ if (max - min == 0) {
+ startPerc =0; endPerc = 1;
+ } else {
+ startPerc = (current - min)/((double)max - min);
+ endPerc = (current+thumbSize - min)/((double)max - min);
+ }
+
+ int color = thumbHover;
+ if (getBounds().contains(relMousex0, relMousey0)) color = thumbHover;
+ if (grabbed) color = thumbClick;
+
+ if (axis == Axis.X) {
+ int startX = (int) (startPerc * getBounds().width);
+ int endX = (int) (endPerc * getBounds().width);
+ endX = Math.max(endX, startX + 20);
+
+ Gui.drawRect(startX,0,endX,getBounds().height, color);
+ } else if (axis == Axis.Y) {
+ int startY = (int) (startPerc * getBounds().height);
+ int endY = (int) (endPerc * getBounds().height);
+ endY = Math.max(endY, startY + 20);
+
+ Gui.drawRect(0,startY,getBounds().width,endY, color);
+ }
+ }
+
+ private int lastX;
+ private int lastY;
+ private int actualValue;
+ private boolean grabbed;
+ @Override
+ public void mouseClicked(int absMouseX, int absMouseY, int relMouseX, int relMouseY, int mouseButton) {
+ if (!lastAbsClip.contains(absMouseX, absMouseY)) return;
+ if (getTooltipsOpen() > 0) return;
+ grabbed = true;
+ actualValue = current;
+ lastX = absMouseX;
+ lastY = absMouseY;
+ }
+
+ @Override
+ public void mouseClickMove(int absMouseX, int absMouseY, int relMouseX, int relMouseY, int clickedMouseButton, long timeSinceLastClick) {
+ if (!grabbed) return;
+ int dx = absMouseX - lastX, dy = absMouseY - lastY;
+
+ lastX = absMouseX;
+ lastY = absMouseY;
+
+ int prevVal = current;
+
+ if (axis == Axis.Y) {
+ actualValue += dy * (max - min) / getBounds().height;
+ } else if (axis == Axis.X) {
+ actualValue += dx * (max - min) / getBounds().width;
+ }
+
+ current = MathHelper.clamp_int(actualValue, min, max - thumbSize);
+ if (max - min < thumbSize) current = min;
+
+ if (onUpdate != null && prevVal != current) onUpdate.run();
+ }
+
+ @Override
+ public void mouseReleased(int absMouseX, int absMouseY, int relMouseX, int relMouseY, int state) {
+ grabbed= false;
+ }
+
+ public static enum Axis {
+ X, Y
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/gui/elements/MScrollablePanel.java b/src/main/java/kr/syeyoung/dungeonsguide/gui/elements/MScrollablePanel.java
new file mode 100644
index 00000000..ffdab32b
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/gui/elements/MScrollablePanel.java
@@ -0,0 +1,181 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.gui.elements;
+
+import kr.syeyoung.dungeonsguide.gui.MPanel;
+import kr.syeyoung.dungeonsguide.utils.RenderUtils;
+import lombok.Getter;
+import lombok.Setter;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.util.MathHelper;
+import org.w3c.dom.css.Rect;
+
+import java.awt.*;
+
+public class MScrollablePanel extends MPanel {
+ @Getter
+ private boolean hideScrollBarWhenNotNecessary = false;
+
+ public void setHideScrollBarWhenNotNecessary(boolean hideScrollBarWhenNotNecessary) {
+ this.hideScrollBarWhenNotNecessary = hideScrollBarWhenNotNecessary;
+ setBounds(getBounds());
+ }
+
+ private final int axis; // 1: Y 2: X 3: both.
+
+
+ private Dimension totalContentArea = new Dimension();
+
+ private MPanel viewPort;
+ @Getter
+ private MPanel contentArea;
+ @Getter
+ private MScrollBar scrollBarX, scrollBarY;
+
+ private Rectangle contentAreaDim;
+
+ public MScrollablePanel(int axis) {
+ this.axis = axis;
+ viewPort = new MPanel();
+ scrollBarX = new MScrollBar(0, 1, 1, 0, MScrollBar.Axis.X, this::onScrollBarUpdate);
+ scrollBarY = new MScrollBar(0, 1, 1, 0, MScrollBar.Axis.Y, this::onScrollBarUpdate);
+
+ if ((axis & 1) > 0)
+ super.add(scrollBarY);
+ if ((axis & 2) > 0)
+ super.add(scrollBarX);
+ super.add(viewPort);
+
+
+ contentArea = new MPanel() {
+ @Override
+ public void add(MPanel child) {
+ super.add(child);
+ evalulateContentArea();
+ }
+
+ @Override
+ public void remove(MPanel panel) {
+ super.remove(panel);
+ evalulateContentArea();
+ }
+
+ @Override
+ public void setBounds(Rectangle bounds) {
+ if (bounds == null) return;
+ this.bounds.x = bounds.x;
+ this.bounds.y = bounds.y;
+ this.bounds.width = bounds.width;
+ this.bounds.height = bounds.height;
+
+ onBoundsUpdate();
+ }
+
+ @Override
+ public void resize(int parentWidth, int parentHeight) {
+ for (MPanel childComponent : childComponents) {
+ childComponent.resize0(parentWidth, parentHeight);
+ }
+ evalulateContentArea();
+ }
+ };
+ viewPort.add(contentArea);
+ contentArea.setIgnoreBoundOnClip(true);
+ evalulateContentArea();
+ }
+
+ @Override
+ public void render(int absMousex, int absMousey, int relMousex0, int relMousey0, float partialTicks, Rectangle scissor) {
+ super.render(absMousex, absMousey, relMousex0, relMousey0, partialTicks, scissor);
+
+ boolean hideX = false, hideY = false;
+ if (bounds.width > contentAreaDim.width && hideScrollBarWhenNotNecessary) hideX = true;
+ if (bounds.height > contentAreaDim.height && hideScrollBarWhenNotNecessary) hideY = true;
+ if (axis == 3 && !(hideX && hideY)) {
+ Gui.drawRect(scrollBarX.getBounds().width, scrollBarY.getBounds().height, getBounds().width, getBounds().height, RenderUtils.blendAlpha(0x141414, 0.03f));
+ }
+ }
+
+ private void evalulateContentArea() {
+ if (contentArea.getChildComponents().size() == 0) {
+ contentAreaDim= new Rectangle(0,0,0,0);
+ return;
+ }
+ int minX = Integer.MAX_VALUE, minY = Integer.MAX_VALUE, maxX = Integer.MIN_VALUE, maxY = Integer.MIN_VALUE;
+ for (MPanel childComponent : contentArea.getChildComponents()) {
+ Rectangle bounds = childComponent.getBounds();
+ if (bounds.x < minX) minX = bounds.x;
+ if (bounds.x + bounds.width > maxX) maxX = bounds.x + bounds.width;
+ if (bounds.y < minY) minY = bounds.y;
+ if (bounds.y + bounds.height > maxY) maxY = bounds.y + bounds.height;
+ }
+ contentAreaDim = new Rectangle(minX, minY, maxX - minX, maxY - minY);
+ scrollBarX.setMin(contentAreaDim.x);
+ scrollBarX.setMax(contentAreaDim.x + contentAreaDim.width);
+ scrollBarY.setMin(contentAreaDim.y);
+ scrollBarY.setMax(contentAreaDim.y + contentAreaDim.height);
+ }
+
+ @Override
+ public void setBounds(Rectangle bounds) {
+ super.setBounds(bounds);
+ boolean hideX = false, hideY = false;
+ if (bounds.width > contentAreaDim.width && hideScrollBarWhenNotNecessary) hideX = true;
+ if (bounds.height > contentAreaDim.height && hideScrollBarWhenNotNecessary) hideY = true;
+
+ if (axis == 3 && !(hideX || hideY)) {
+ Dimension preferedX = scrollBarX.getPreferredSize();
+ Dimension preferedY = scrollBarY.getPreferredSize();
+ scrollBarY.setBounds(new Rectangle(bounds.width - preferedY.width, 0, preferedY.width, bounds.height - preferedX.height));
+ scrollBarX.setBounds(new Rectangle(0, bounds.height - preferedX.height, bounds.width - preferedY.width, preferedX.height));
+ } else if (axis == 2 || (axis == 3 && hideY)) {
+ Dimension preferedX = scrollBarX.getPreferredSize();
+ scrollBarY.setBounds(new Rectangle(0,0,0,0));
+ scrollBarX.setBounds(new Rectangle(0, bounds.height - preferedX.height, bounds.width, preferedX.height));
+ } else if (axis == 1 || (axis == 3 && hideX)) {
+ Dimension preferedY = scrollBarY.getPreferredSize();
+ scrollBarX.setBounds(new Rectangle(0,0,0,0));
+ scrollBarY.setBounds(new Rectangle(bounds.width - preferedY.width, 0, preferedY.width, bounds.height));
+ }
+
+ viewPort.setBounds(new Rectangle(0,0,bounds.width-scrollBarY.getBounds().width, bounds.height - scrollBarX.getBounds().height));
+
+ scrollBarX.setThumbSize(viewPort.getBounds().width);
+ scrollBarY.setThumbSize(viewPort.getBounds().height);
+ }
+
+
+ private void onScrollBarUpdate() {
+ contentArea.setPosition(new Point(-scrollBarX.getCurrent(), -scrollBarY.getCurrent()));
+ }
+
+
+ @Override
+ public void add(MPanel child) { contentArea.add(child); }
+
+ @Override
+ public void remove(MPanel panel) { contentArea.remove(panel); }
+
+ @Override
+ public void mouseScrolled(int absMouseX, int absMouseY, int relMouseX0, int relMouseY0, int scrollAmount) {
+ if (lastAbsClip.contains(absMouseX, absMouseY) && (axis == 1 || axis == 3)) {
+ scrollBarY.addToCurrent(MathHelper.clamp_int(scrollAmount, -1, 1) * -30);
+ }
+ }
+}