aboutsummaryrefslogtreecommitdiff
path: root/features/settings
diff options
context:
space:
mode:
authorSoopyboo32 <49228220+Soopyboo32@users.noreply.github.com>2021-10-31 09:49:42 +0800
committerSoopyboo32 <49228220+Soopyboo32@users.noreply.github.com>2021-10-31 09:49:42 +0800
commit48653ec89538f1650106a5e77463412cad4684c2 (patch)
tree09687cd579462e04d539fd4615369fa6dae13902 /features/settings
downloadSoopyV2-48653ec89538f1650106a5e77463412cad4684c2.tar.gz
SoopyV2-48653ec89538f1650106a5e77463412cad4684c2.tar.bz2
SoopyV2-48653ec89538f1650106a5e77463412cad4684c2.zip
first commit
Diffstat (limited to 'features/settings')
-rw-r--r--features/settings/index.js249
-rw-r--r--features/settings/metadata.json8
-rw-r--r--features/settings/settingThings/button.js18
-rw-r--r--features/settings/settingThings/location.js332
-rw-r--r--features/settings/settingThings/settingBase.js106
-rw-r--r--features/settings/settingThings/textSetting.js33
-rw-r--r--features/settings/settingThings/toggle.js58
-rw-r--r--features/settings/settingsCommunicator.js29
8 files changed, 833 insertions, 0 deletions
diff --git a/features/settings/index.js b/features/settings/index.js
new file mode 100644
index 0000000..6d41754
--- /dev/null
+++ b/features/settings/index.js
@@ -0,0 +1,249 @@
+/// <reference types="../../../CTAutocomplete" />
+/// <reference lib="es2015" />
+import Feature from "../../featureClass/class";
+import * as GuiManager from "../../../guimanager/index.js"
+import SoopyGuiElement from "../../../guimanager/GuiElement/SoopyGuiElement";
+import SoopyTextElement from "../../../guimanager/GuiElement/SoopyTextElement";
+import SoopyBoxElement from "../../../guimanager/GuiElement/SoopyBoxElement";
+import TextWithArrow from "../../../guimanager/GuiElement/TextWithArrow";
+import ButtonWithArrow from "../../../guimanager/GuiElement/ButtonWithArrow";
+import BoxWithToggleAndDescription from "../../../guimanager/GuiElement/BoxWithToggleAndDescription";
+import ButtonWithArrowAndDescription from "../../../guimanager/GuiElement/ButtonWithArrowAndDescription";
+import SoopyMouseClickEvent from "../../../guimanager/EventListener/SoopyMouseClickEvent";
+import SoopyContentChangeEvent from "../../../guimanager/EventListener/SoopyContentChangeEvent";
+import SoopyOpenGuiEvent from "../../../guimanager/EventListener/SoopyOpenGuiEvent";
+import settingsCommunicator from "./settingsCommunicator";
+import GuiPage from "../soopyGui/GuiPage"
+
+
+class SettingsRenderer extends Feature {
+ constructor() {
+ super()
+
+ this.gui = undefined
+
+ this.pages = []
+ this.currentPage = 0
+ this.backButton = undefined
+ this.settingsCategoryArea = undefined
+ this.settingsTitle = undefined
+ this.settingsArea = undefined
+ this.modifyingFeature = false
+ this.featureLoadedTextBox = undefined
+
+ this.SettingPage = undefined
+ }
+
+ onEnable(){
+
+ this.SettingPage = new SettingPage()
+ this.SettingPage.FeatureManager = this.FeatureManager
+
+ return;
+ }
+
+ onDisable(){
+ this.SettingPage = undefined
+ return;
+ this.gui.delete()
+
+ this.pages = []
+ this.currentPage = 0
+ this.backButton = undefined
+ this.settingsArea = undefined
+ this.settingsTitle = undefined
+ this.settingsCategoryArea = undefined
+ this.modifyingFeature = false
+ this.featureLoadedTextBox = undefined
+ }
+
+ clickedOpenSettings(){
+
+
+ this.goToPage(1)
+ }
+
+ clickedBackButton(){
+ this.goToPage(this.currentPage-1)
+ }
+
+ goToPage(pageNum, animate=true){
+ pageNum = Math.max(0, Math.min(pageNum, this.pages.length-1))
+
+ if(pageNum == this.currentPage){
+ return
+ }
+
+ this.currentPage = pageNum
+
+ this.pages.forEach((p, i)=>{
+ p.forEach(e=>{
+ e.location.location.x.set(i-pageNum, animate?1000:0)
+ })
+ })
+
+ this.backButton.location.location.y.set(pageNum === 0?-0.2:0, animate?1000:0)
+ }
+}
+
+class SettingPage extends GuiPage {
+ constructor(){
+ super(10)
+
+ this.name = "Settings"
+
+ this.pages = [this.newPage(), this.newPage()]
+
+ this.settingsCategoryArea = undefined
+ this.settingsTitle = undefined
+ this.settingsArea = undefined
+ this.modifyingFeature = false
+ this.featureLoadedTextBox = undefined
+
+ this.SettingPage = undefined
+
+ this.pages[0].addEvent(new GuiManager.SoopyRenderEvent().setHandler(()=>{this.updateLocs()}))
+
+ //###############################################################################################
+ // Settings Category Page
+ //###############################################################################################
+
+
+
+ let settingsCategoryTitle = new SoopyTextElement().setText("§0Settings").setMaxTextScale(3).setLocation(0.1, 0.05, 0.8, 0.1)
+ this.pages[0].addChild(settingsCategoryTitle)
+
+ this.settingsCategoryArea = new SoopyGuiElement().setLocation(0.1, 0.2, 0.8, 0.8).setScrollable(true)
+ this.pages[0].addChild(this.settingsCategoryArea)
+
+
+ //###############################################################################################
+ // Settings Page
+ //###############################################################################################
+
+ this.settingsTitle = new SoopyTextElement().setMaxTextScale(3).setLocation(0.1, 0.05, 0.8, 0.1)
+ this.pages[1].addChild(this.settingsTitle)
+
+ this.settingsArea = new SoopyGuiElement().setLocation(0.1, 0.2, 0.8, 0.8).setScrollable(true)
+ this.pages[1].addChild(this.settingsArea)
+
+
+ this.finaliseLoading()
+ }
+
+ onOpen(){
+ this.updateSettingCategories()
+ this.settingsCategoryArea.location.scroll.x.set(0, 0)
+ this.settingsCategoryArea.location.scroll.y.set(0, 0)
+ }
+
+ updateSettingCategories(){
+ this.settingsCategoryArea.children = []
+
+ let i = 0
+
+ Object.keys(this.FeatureManager.featureMetas).sort((a, b)=>{return a.sortA-b.sortA}).forEach((f)=>{
+ let meta = this.FeatureManager.featureMetas[f]
+
+ let isHidden = meta.isHidden
+ if(typeof isHidden === "string"){
+ isHidden = require("../" + f + "/" + isHidden).default()
+ }
+ if(isHidden) return
+
+ let category = new ButtonWithArrowAndDescription().setText("&0" + meta.name).setDesc("&0" +meta.description).setLocation(0, 0.225*i, 1, 0.2)
+ category.addEvent(new SoopyMouseClickEvent().setHandler(()=>{this.clickedOpenCategory(f)}))
+
+ this.settingsCategoryArea.addChild(category)
+
+ i++
+ })
+ // this.FeatureManager.features = {}; enabled features
+ }
+
+ updateSettings(category){
+ let meta = this.FeatureManager.featureMetas[category]
+
+ this.settingsArea.children = []
+
+ this.settingsTitle.setText("&0" + this.FeatureManager.featureMetas[category].name)
+
+ let height = 0
+
+ if(meta.isTogglable){
+ let toggle = new BoxWithToggleAndDescription().setLocation(0, height, 1, 0.2).setText("&0Main toggle").setDesc("&0This is the main toggle for the whole category")
+ this.settingsArea.addChild(toggle)
+
+ toggle.toggle.setValue(this.FeatureManager.isFeatureLoaded(category), 0)
+
+ toggle.toggle.addEvent(new SoopyContentChangeEvent().setHandler((newVal, oldVal, resetFun)=>{
+ //dont allow editing if currenately loading/unloading it
+ if(this.modifyingFeature){
+ resetFun()
+ return
+ }
+
+ //toggle the feature
+ this.modifyingFeature = true
+ new Thread(()=>{
+ this.FeatureManager.featureSettingsData[category].enabled = newVal
+ this.FeatureManager.featureSettingsDataLastUpdated = true
+
+ if(!newVal && this.FeatureManager.isFeatureLoaded(category)){
+ this.FeatureManager.unloadFeature(category)
+ }
+ if(newVal && !this.FeatureManager.isFeatureLoaded(category)){
+ this.FeatureManager.loadFeature(category)
+ }
+
+ Thread.sleep(100)
+
+ this.modifyingFeature = false
+
+ this.updateSettings(category)
+ }).start()
+ }))
+ height += toggle.location.size.y.get()+0.045
+ }
+
+ if(!this.FeatureManager.isFeatureLoaded(category)){
+
+ //only show if feature issnt loaded
+
+ let textBox = new SoopyBoxElement().setLocation(0, height, 1, 0.2)
+ .addChild(new SoopyTextElement().setText("&0Feature not loaded").setLocation(0, 0, 1, 0.5))
+ .addChild(new SoopyTextElement().setText("&0Load feature to access settings").setLocation(0, 0.5, 1, 0.5))
+ this.settingsArea.addChild(textBox)
+ return;
+ }
+
+ settingsCommunicator.getModuleSettings(category).forEach(setting=>{
+ setting.location.location.y.set(height, 0)
+ this.settingsArea.addChild(setting)
+
+ height += 0.045+setting.location.size.y.get()
+ })
+ }
+
+ updateLocs(){
+ let totalHeight = 0
+
+ this.settingsArea.children.forEach(e=>{
+ e.location.location.y.set(totalHeight, 0)
+
+ totalHeight += e.location.size.y.get()+Math.min(0.045,e.location.size.y.get())
+ })
+ }
+
+ clickedOpenCategory(category){
+ this.updateSettings(category)
+ this.goToPage(2)
+
+ this.settingsArea.location.scroll.x.set(0, 0)
+ this.settingsArea.location.scroll.y.set(0, 0)
+ }
+}
+
+module.exports = {
+ class: new SettingsRenderer()
+} \ No newline at end of file
diff --git a/features/settings/metadata.json b/features/settings/metadata.json
new file mode 100644
index 0000000..8f2ace4
--- /dev/null
+++ b/features/settings/metadata.json
@@ -0,0 +1,8 @@
+{
+ "name": "Settings",
+ "description": "Adds a settings gui with toggles for all the modules, also renders each individual module's settings",
+ "isHidden": true,
+ "isTogglable": false,
+ "defaultEnabled": true,
+ "sortA": 0
+} \ No newline at end of file
diff --git a/features/settings/settingThings/button.js b/features/settings/settingThings/button.js
new file mode 100644
index 0000000..77ba4b8
--- /dev/null
+++ b/features/settings/settingThings/button.js
@@ -0,0 +1,18 @@
+import SoopyMouseClickEvent from "../../../../guimanager/EventListener/SoopyMouseClickEvent";
+import ButtonWithArrow from "../../../../guimanager/GuiElement/ButtonWithArrow";
+import SettingBase from "./settingBase";
+
+class ButtonSetting extends SettingBase {
+ constructor(name, description, settingId, module, buttonText, buttonFunction, defaultValue=null){
+ super(name, description, defaultValue, settingId, module)
+
+ this.buttonObject = new ButtonWithArrow().setLocation(0, 0.3, 0.8, 0.4).setText("§0"+buttonText)
+ this.settingObject.addChild(this.buttonObject)
+
+ this.buttonObject.addEvent(new SoopyMouseClickEvent().setHandler(()=>{
+ buttonFunction.call(this)
+ }))
+ }
+}
+
+export default ButtonSetting \ No newline at end of file
diff --git a/features/settings/settingThings/location.js b/features/settings/settingThings/location.js
new file mode 100644
index 0000000..69d1a43
--- /dev/null
+++ b/features/settings/settingThings/location.js
@@ -0,0 +1,332 @@
+import { SoopyGui } from "../../../../guimanager"
+import SoopyBoxElement from "../../../../guimanager/GuiElement/SoopyBoxElement"
+import SoopyTextElement from "../../../../guimanager/GuiElement/SoopyTextElement"
+import ButtonSetting from "./button"
+import BoxWithText from "../../../../guimanager/GuiElement/BoxWithText"
+import ButtonWithArrow from "../../../../guimanager/GuiElement/ButtonWithArrow"
+import SoopyMouseClickEvent from "../../../../guimanager/EventListener/SoopyMouseClickEvent"
+import NumberTextBox from "../../../../guimanager/GuiElement/NumberTextBox"
+import SoopyContentChangeEvent from "../../../../guimanager/EventListener/SoopyContentChangeEvent"
+
+let allLocations = []
+
+class LocationSetting extends ButtonSetting {
+ constructor(name, description, settingId, module, defaultLocation){
+ super(name, description, settingId, module, "Edit Position", this.editPosition, defaultLocation)
+
+ this.x = this.getValue()[0]
+ this.y = this.getValue()[1]
+ this.scale = this.getValue()[2]
+ this.shadowType = this.getValue()[3] //0-none, 1-vanilla, 2-border
+
+ this.editTempTextV = undefined
+
+ this.dragging = false
+ this.dragOffset = [0, 0]
+ this.resisizing = false
+ this.resizePoint = 0
+ this.resizeInitialPos=[0, 0, 0, 0, 0, 0]
+
+ this.parent = undefined
+
+ this.soopyGui = new SoopyGui()
+ this.soopyGui._renderBackground = ()=>{} //remove background darkening
+
+ this.elmSettings = new SoopyBoxElement().setLocation(0, 0, 0.25, 0.25)
+
+ let scaleText = new SoopyTextElement().setText("&0Scale: ").setLocation(3, 0.025, 1, 0.15)
+ scaleText.location.location.setRelative(false, true)
+ scaleText.centeredX = false
+ this.elmSettings.addChild(scaleText)
+
+ this.scaleInput = new NumberTextBox().setText(this.scale.toFixed(2)).setLocation(Renderer.getStringWidth("Scale: ")+3, 0.025, -(Renderer.getStringWidth("Scale: ")+6), 0.15)
+ this.scaleInput.location.location.setRelative(false, true)
+ this.scaleInput.location.size.setRelative(false, true)
+ this.elmSettings.addChild(this.scaleInput)
+ this.scaleInput.text.addEvent(new SoopyContentChangeEvent().setHandler((newVal, oldVal, resetFun)=>{
+ try{
+ newVal = parseFloat(newVal)
+ if(!isNaN(newVal)){
+ this.scale = newVal
+ this._updateValue()
+ }
+ }catch(e){}
+ }))
+ this.lastScaleRender = this.scale.toFixed(2)
+
+ let xText = new SoopyTextElement().setText("&0X: ").setLocation(3, 0.225, 1, 0.15)
+ xText.location.location.setRelative(false, true)
+ xText.centeredX = false
+ this.elmSettings.addChild(xText)
+ this.xInput = new NumberTextBox().setText(this.x.toFixed(0)).setLocation(Renderer.getStringWidth("X: ")+3, 0.225, -(Renderer.getStringWidth("X: ")+6), 0.15)
+ this.xInput.location.location.setRelative(false, true)
+ this.xInput.location.size.setRelative(false, true)
+ this.elmSettings.addChild(this.xInput)
+ this.xInput.text.addEvent(new SoopyContentChangeEvent().setHandler((newVal, oldVal, resetFun)=>{
+ try{
+ newVal = parseFloat(newVal)
+ if(!isNaN(newVal)){
+ this.x = newVal
+ this._updateValue()
+ }
+ }catch(e){}
+ }))
+ this.lastXRender = this.x.toFixed(0)
+
+ let yText = new SoopyTextElement().setText("&0Y: ").setLocation(3, 0.425, 1, 0.15)
+ yText.location.location.setRelative(false, true)
+ yText.centeredX = false
+ this.elmSettings.addChild(yText)
+ this.yInput = new NumberTextBox().setText(this.y.toFixed(0)).setLocation(Renderer.getStringWidth("Y: ")+3, 0.425, -(Renderer.getStringWidth("Y: ")+6), 0.15)
+ this.yInput.location.location.setRelative(false, true)
+ this.yInput.location.size.setRelative(false, true)
+ this.elmSettings.addChild(this.yInput)
+ this.yInput.text.addEvent(new SoopyContentChangeEvent().setHandler((newVal, oldVal, resetFun)=>{
+ try{
+ newVal = parseFloat(newVal)
+ if(!isNaN(newVal)){
+ this.y = newVal
+ this._updateValue()
+ }
+ }catch(e){}
+ }))
+ this.lastYRender = this.y.toFixed(0)
+
+ this.soopyGui.element.addChild(this.elmSettings)
+
+ let button = new ButtonWithArrow().setText("&0Reset").setLocation(0.125, 0.625, 0.75, 0.15)
+ button.addEvent(new SoopyMouseClickEvent().setHandler(()=>{
+ this.x = defaultLocation[0]
+ this.y = defaultLocation[1]
+ this.scale = defaultLocation[2]
+ this.shadowType = defaultLocation[3]
+ }))
+ this.elmSettings.addChild(button)
+
+ let button2 = new ButtonWithArrow().setText("&0Back").setLocation(0.125, 0.825, 0.75, 0.15)
+ button2.addEvent(new SoopyMouseClickEvent().setHandler(()=>{
+ this.soopyGui.close()
+ this.guiObject.main.ctGui.open()
+ }))
+ this.elmSettings.addChild(button2)
+
+ this.editGui = this.soopyGui.ctGui
+
+ this.editGui.registerDraw((mouseX, mouseY, partialTicks)=>{
+ this.renderGui(mouseX, mouseY)
+ this.soopyGui._render(mouseX, mouseY, partialTicks)
+ })
+ this.editGui.registerClicked((mouseX, mouseY, button)=>{
+ this.clicked(mouseX, mouseY)
+ this.soopyGui._onClick(mouseX, mouseY, button)
+ })
+ this.editGui.registerMouseReleased((mouseX, mouseY)=>{
+ this.released(mouseX, mouseY)
+ })
+
+ allLocations.push(this)
+ }
+
+ requires(toggleSetting){
+ this.requiresO = toggleSetting
+
+ toggleSetting.toggleObject.addEvent(new SoopyContentChangeEvent().setHandler((newVal, oldVal, resetFun)=>{
+ if(newVal){
+ this.guiObject.location.size.y.set(0.2, 500)
+ }else{
+ this.guiObject.location.size.y.set(0, 500)
+ }
+ }))
+ let newVal = this.requiresO.getValue()
+ if(!newVal){
+ this.guiObject.location.size.y.set(0, 0)
+ }
+
+ return this
+ }
+
+ _updateValue(){
+ this.setValue([this.x, this.y, this.scale, this.shadowType])
+ }
+
+ editTempText(text){
+ this.editTempTextV = text
+ return this;
+ }
+
+ setParent(parent){
+ this.parent = parent
+ }
+
+ editPosition(){
+ this.guiObject.main.ctGui.close()
+
+ this.soopyGui.open()
+ }
+
+ clicked(mouseX, mouseY){
+ let width = this.getWidth()
+ let height = 9*this.parent.getText()[0].length
+
+ let locations = [[this.x, this.y], [this.x+width*this.scale, this.y], [this.x, this.y+height*this.scale], [this.x+width*this.scale, this.y+height*this.scale]]
+
+ locations.forEach((loc, i)=>{
+ if(mouseX >= loc[0]-1*Math.max(1, this.scale) && mouseX <= loc[0]+1*Math.max(1, this.scale)
+ && mouseY >= loc[1]-1*Math.max(1, this.scale) && mouseY <= loc[1]+1*Math.max(1, this.scale)){
+ this.resisizing= true
+ this.resizePoint = i
+ this.resizeInitialPos = [mouseX, mouseY, this.x, this.y, width*this.scale, height*this.scale]
+ }
+ })
+ if(this.resisizing) return;
+
+ if(mouseX > this.x && mouseX < this.x+width*this.scale
+ && mouseY>this.y && mouseY<this.y+height*this.scale){
+ this.dragging = true;
+ this.dragOffset = [this.x-mouseX, this.y-mouseY]
+ }
+ }
+ released(mouseX, mouseY){
+ this.updateLocation(mouseX, mouseY)
+ this.dragging = false
+ this.resisizing = false
+
+ this._updateValue()
+ }
+
+ getWidth(){
+ return Math.max(...(this.parent.getText()[0].map(a=>Renderer.getStringWidth(ChatLib.removeFormatting(a)))))
+ }
+
+ updateLocation(mouseX, mouseY, drawCollidingBox){
+ let width = this.getWidth()
+ let height = 9*this.parent.getText()[0].length
+
+ if(this.dragging){
+ this.x = mouseX+this.dragOffset[0]
+ this.y = mouseY+this.dragOffset[1]
+
+ let snapPoints = []
+ allLocations.forEach(loc=>{
+ if(loc === this) return;
+ snapPoints.push([loc.x, loc.y])
+ snapPoints.push([loc.x+loc.getWidth()*loc.scale, loc.y])
+ snapPoints.push([loc.x+loc.getWidth()*loc.scale, loc.y+height*loc.scale])
+ snapPoints.push([loc.x, loc.y+height*loc.scale])
+ })
+
+ snapPoints.forEach(point=>{
+ //top left
+ if(Math.abs(this.x-point[0]) < 5 && Math.abs(this.y-point[1]) < 5){
+ this.x = point[0]
+ this.y = point[1]
+ }
+
+ //top right
+ if(Math.abs(this.x+width*this.scale-point[0]) < 5 && Math.abs(this.y-point[1]) < 5){
+ this.x = point[0]-width*this.scale
+ this.y = point[1]
+ }
+
+ //bottom left
+ if(Math.abs(this.x-point[0]) < 5 && Math.abs(this.y+height*this.scale-point[1]) < 5){
+ this.x = point[0]
+ this.y = point[1]-height*this.scale
+ }
+
+ //bottom right
+ if(Math.abs(this.x+width*this.scale-point[0]) < 5 && Math.abs(this.y+height*this.scale-point[1]) < 5){
+ this.x = point[0]-width*this.scale
+ this.y = point[1]-height*this.scale
+ }
+ })
+ }
+ if(this.resisizing){
+ if(this.resizePoint === 3){
+ this.scale=(mouseX-this.x)/width
+ this.scale = Math.max(0.25, this.scale)
+ }
+ if(this.resizePoint === 1){
+
+ let [oMouseX, oMouseY, oX, oY, ow, oh] = this.resizeInitialPos
+
+ this.scale=(mouseX-this.x)/width
+ this.scale = Math.max(0.25, this.scale)
+ this.y=oY+oh-height*this.scale
+ }
+ if(this.resizePoint===0){
+ let [oMouseX, oMouseY, oX, oY, ow, oh] = this.resizeInitialPos
+
+ this.scale=(oX+ow-mouseX)/width
+ this.scale = Math.max(0.25, this.scale)
+ this.x=oX+ow-width*this.scale
+ this.y=oY+oh-height*this.scale
+ }
+ if(this.resizePoint === 2){
+ let [oMouseX, oMouseY, oX, oY, ow, oh] = this.resizeInitialPos
+
+ this.scale=(oX+ow-mouseX)/width
+ this.scale = Math.max(0.25, this.scale)
+ this.x=oX+ow-width*this.scale
+ }
+ }
+ }
+
+ renderGui(mouseX, mouseY){
+
+ if(this.parent){
+ this.parent.editTempTextV = this.editTempTextV
+ this.parent.editTempTimeV = Date.now()
+
+ this.parent.tempDisableTime = Date.now()
+ this.parent.renderRaw()
+ }
+
+ let width = this.getWidth()
+ let height = 9*this.parent.getText()[0].length
+
+ this.updateLocation(mouseX, mouseY, true)
+
+ this.renderBox(true)
+
+ if(this.x+width*this.scale/2 > Renderer.screen.getWidth()/2){
+ this.elmSettings.location.location.x.set(Math.min(Math.max(this.x/Renderer.screen.getWidth()-0.25-0.03, 0.02), 0.73))
+ }else{
+ this.elmSettings.location.location.x.set(Math.min(Math.max((this.x+width*this.scale)/Renderer.screen.getWidth()+0.03, 0.02), 0.73))
+ }
+ this.elmSettings.location.location.y.set(Math.min(Math.max((this.y+height*this.scale/2)/Renderer.screen.getHeight() - this.elmSettings.location.size.y.get()/2, 0.02), 0.73))
+
+
+ if(this.lastScaleRender !== this.scale.toFixed(2) && !this.scaleInput.text.selected){
+ this.lastScaleRender = this.scale.toFixed(2)
+ this.scaleInput.setText(this.scale.toFixed(2))
+ }
+ if(this.lastXRender !== this.x.toFixed(0) && !this.xInput.text.selected){
+ this.lastXRender = this.x.toFixed(0)
+ this.xInput.setText(this.x.toFixed(0))
+ }
+ if(this.lastYRender !== this.y.toFixed(0) && !this.yInput.text.selected){
+ this.lastYRender = this.y.toFixed(0)
+ this.yInput.setText(this.y.toFixed(0))
+ }
+ }
+
+ renderBox(drawHandles){
+ let width = this.getWidth()
+ let height = 9*this.parent.getText()[0].length
+
+ Renderer.drawRect(Renderer.color(255, 255, 255), this.x, this.y, width*this.scale, 1)
+ Renderer.drawRect(Renderer.color(255, 255, 255), this.x, this.y, 1, height*this.scale)
+ Renderer.drawRect(Renderer.color(255, 255, 255), this.x, this.y+height*this.scale, width*this.scale, 1)
+ Renderer.drawRect(Renderer.color(255, 255, 255), this.x+width*this.scale, this.y, 1, height*this.scale)
+
+ if(drawHandles){
+ Renderer.drawRect(Renderer.color(255, 255, 255), this.x-1*Math.max(1, this.scale)+width*this.scale, this.y-1*Math.max(1, this.scale), 2*Math.max(1, this.scale)+1, 2*Math.max(1, this.scale)+1)
+ Renderer.drawRect(Renderer.color(255, 255, 255), this.x-1*Math.max(1, this.scale), this.y-1*Math.max(1, this.scale)+height*this.scale, 2*Math.max(1, this.scale)+1, 2*Math.max(1, this.scale)+1)
+ Renderer.drawRect(Renderer.color(255, 255, 255), this.x-1*Math.max(1, this.scale)+width*this.scale, this.y-1*Math.max(1, this.scale)+height*this.scale, 2*Math.max(1, this.scale)+1, 2*Math.max(1, this.scale)+1)
+ Renderer.drawRect(Renderer.color(255, 255, 255), this.x-1*Math.max(1, this.scale), this.y-1*Math.max(1, this.scale), 2*Math.max(1, this.scale)+1, 2*Math.max(1, this.scale)+1)
+ }
+ }
+}
+
+export default LocationSetting \ No newline at end of file
diff --git a/features/settings/settingThings/settingBase.js b/features/settings/settingThings/settingBase.js
new file mode 100644
index 0000000..fbee5bf
--- /dev/null
+++ b/features/settings/settingThings/settingBase.js
@@ -0,0 +1,106 @@
+import SoopyContentChangeEvent from "../../../../guimanager/EventListener/SoopyContentChangeEvent";
+import BoxWithTextAndDescription from "../../../../guimanager/GuiElement/BoxWithTextAndDescription"
+import SoopyGuiElement from "../../../../guimanager/GuiElement/SoopyGuiElement";
+import settingsCommunicator from "../settingsCommunicator";
+
+class SettingBase {
+ constructor(name, description, defaultVal, settingId, module){
+ this.name = name;
+ this.description = description;
+ this.defaultVal = defaultVal;
+ this.settingId = settingId
+ this.module = module
+ this.moduleId = module.getId()
+
+ this.val = defaultVal;
+
+ this.guiObject = new BoxWithTextAndDescription().setDesc("§0"+this.description).setText("§0"+this.name).setLocation(0, 0, 1, 0.175)
+
+ this.settingObject = new SoopyGuiElement().setLocation(0.8, 0, 0.2, 1)
+
+ this.guiObject.addChild(this.settingObject)
+
+ settingsCommunicator.addSetting(this.moduleId, settingId, this.getGuiObject())
+
+ if(!module.FeatureManager.featureSettingsData[this.moduleId]){
+ module.FeatureManager.featureSettingsData[this.moduleId] = {}
+ }
+ if(!module.FeatureManager.featureSettingsData[this.moduleId].subSettings)module.FeatureManager.featureSettingsData[this.moduleId].subSettings = {}
+ if(!module.FeatureManager.featureSettingsData[this.moduleId].subSettings[settingId]){
+ module.FeatureManager.featureSettingsData[this.moduleId].subSettings[settingId] = {
+ value: this.getDefaultValue(),
+ temp_val: this.getDefaultValue()
+ }
+
+ module.FeatureManager.featureSettingsDataLastUpdated = true
+ }
+ let temp_val_temp =module.FeatureManager.featureSettingsData[this.moduleId].subSettings[settingId].temp_val
+ this.setValue(module.FeatureManager.featureSettingsData[this.moduleId].subSettings[settingId].value)
+ this.temp_val = temp_val_temp
+
+ this.requiresO = undefined
+ }
+
+ getValue(){
+ return this.val;
+ }
+
+ setValue(val){
+ this.val = val;
+
+ if(!this.requiresO || this.requiresO.getValue()){
+ this.temp_val = val
+ }
+
+ if(this.module.FeatureManager.featureSettingsData[this.moduleId].subSettings[this.settingId].value !== val){
+ this.module.FeatureManager.featureSettingsData[this.moduleId].subSettings[this.settingId].value = val
+
+ this.module.FeatureManager.featureSettingsDataLastUpdated = true
+ }
+ if(this.module.FeatureManager.featureSettingsData[this.moduleId].subSettings[this.settingId].temp_val !== this.temp_val){
+ this.module.FeatureManager.featureSettingsData[this.moduleId].subSettings[this.settingId].temp_val = this.temp_val
+
+ this.module.FeatureManager.featureSettingsDataLastUpdated = true
+ }
+ }
+
+ getName(){
+ return this.name;
+ }
+
+ getDescription(){
+ return this.description;
+ }
+
+ getDefaultValue(){
+ return this.defaultVal;
+ }
+
+ getGuiObject(){
+ return this.guiObject;
+ }
+
+ requires(toggleSetting){
+ this.requiresO = toggleSetting
+
+ toggleSetting.toggleObject.addEvent(new SoopyContentChangeEvent().setHandler((newVal, oldVal, resetFun)=>{
+ if(newVal){
+ this.guiObject.location.size.y.set(0.2, 500)
+ }else{
+ this.guiObject.location.size.y.set(0, 500)
+ }
+ }))
+ let newVal = this.requiresO.getValue()
+ if(!newVal){
+ this.guiObject.location.size.y.set(0, 0)
+ }
+
+ return this
+ }
+
+ delete(){
+ settingsCommunicator.removeSetting(this.module, this.settingId)
+ }
+}
+
+export default SettingBase \ No newline at end of file
diff --git a/features/settings/settingThings/textSetting.js b/features/settings/settingThings/textSetting.js
new file mode 100644
index 0000000..4960461
--- /dev/null
+++ b/features/settings/settingThings/textSetting.js
@@ -0,0 +1,33 @@
+
+import SoopyContentChangeEvent from "../../../../guimanager/EventListener/SoopyContentChangeEvent";
+import TextBox from "../../../../guimanager/GuiElement/TextBox";
+import PasswordInput from "../../../../guimanager/GuiElement/PasswordInput"
+import SettingBase from "./settingBase";
+
+class TextSetting extends SettingBase {
+ constructor(name, description, defaultVal, settingId, module, placeholder, isSecret){
+ super(name, description, defaultVal, settingId, module)
+
+ this.textObject = (isSecret?new PasswordInput():new TextBox()).setLocation(0, 0.2, 0.9, 0.6).setText(this.getValue()).setPlaceholder(placeholder)
+ this.settingObject.addChild(this.textObject)
+
+ this.settingObject.setLocation(0.6, 0, 0.4, 1)
+ this.guiObject.text.setLocation(0, 0, 0.6, 0.6)
+ this.guiObject.description.setLocation(0, 0.6, 0.55, 0.4)
+
+ this.textObject.addEvent(new SoopyContentChangeEvent().setHandler((newVal, oldVal, resetFun)=>{
+ this.setValue(newVal)
+ }))
+
+ }
+
+ setValue(newVal){
+ super.setValue(newVal)
+
+ this.textObject.setText(newVal)
+
+ return this
+ }
+}
+
+export default TextSetting \ No newline at end of file
diff --git a/features/settings/settingThings/toggle.js b/features/settings/settingThings/toggle.js
new file mode 100644
index 0000000..d839b8f
--- /dev/null
+++ b/features/settings/settingThings/toggle.js
@@ -0,0 +1,58 @@
+import Enum from "../../../../guimanager/Enum";
+import SoopyContentChangeEvent from "../../../../guimanager/EventListener/SoopyContentChangeEvent";
+import Toggle from "../../../../guimanager/GuiElement/Toggle";
+import SettingBase from "./settingBase";
+
+class ToggleSetting extends SettingBase {
+ constructor(name, description, defaultVal, settingId, module){
+ super(name, description, defaultVal, settingId, module)
+
+ this.toggleObject = new Toggle().setLocation(0, 0.3, 0.8, 0.4).setValue(this.getValue())
+ this.settingObject.addChild(this.toggleObject)
+
+ this.toggleObject.addEvent(new SoopyContentChangeEvent().setHandler((newVal, oldVal, resetFun)=>{
+ this.setValue(newVal)
+ }))
+
+ }
+
+ setValue(newVal){
+ super.setValue(newVal)
+
+ this.toggleObject.setValue(newVal)
+
+ return this
+ }
+
+ requires(toggleSetting){
+ this.requiresO = toggleSetting
+
+ toggleSetting.toggleObject.addEvent(new SoopyContentChangeEvent().setHandler((newVal, oldVal, resetFun)=>{
+ if(newVal){
+ this.setValue(this.temp_val)
+
+ this.toggleObject.triggerEvent(Enum.EVENT.CONTENT_CHANGE, [this.temp_val, false, ()=>{}])
+
+ this.guiObject.location.size.y.set(0.2, 500)
+ }else{
+ this.temp_val = this.getValue()
+ this.setValue(false)
+
+ this.toggleObject.triggerEvent(Enum.EVENT.CONTENT_CHANGE, [false, this.temp_val, ()=>{}])
+
+ this.guiObject.location.size.y.set(0, 500)
+ }
+ }))
+ let newVal = this.requiresO.getValue()
+ if(!newVal){
+ let temp_val = this.temp_val
+ this.setValue(false)
+ this.temp_val = temp_val
+ this.guiObject.location.size.y.set(0, 0)
+ }
+
+ return this
+ }
+}
+
+export default ToggleSetting \ No newline at end of file
diff --git a/features/settings/settingsCommunicator.js b/features/settings/settingsCommunicator.js
new file mode 100644
index 0000000..b54b1c1
--- /dev/null
+++ b/features/settings/settingsCommunicator.js
@@ -0,0 +1,29 @@
+//So features can add settings by adding to this class, then the gui will load data from this class
+//this makes it so i can add settings before the settings gui is loaded
+//and so that settings gui can still be dynamicly reloaded and not break things
+
+class SettingsCommunicator {
+ constructor(){
+ this.settings = {}
+ }
+
+ addSetting(module, settingID, settingObject){
+ if(!this.settings[module]) this.settings[module] = {}
+
+ this.settings[module][settingID] = settingObject
+ }
+ removeSetting(module, settingID){
+ if(!this.settings[module]) return;
+ delete this.settings[module][settingID]
+ }
+ getSetting(module, settingID){
+ return this.settings[module][settingID]
+ }
+ getModuleSettings(module){
+ return Object.values(this.settings[module] || [])
+ }
+}
+
+const settingsCommunicator = new SettingsCommunicator()
+
+export default settingsCommunicator \ No newline at end of file