diff options
Diffstat (limited to 'src/features/settings')
-rw-r--r-- | src/features/settings/helpDataLoader.js | 50 | ||||
-rw-r--r-- | src/features/settings/index.js | 332 | ||||
-rw-r--r-- | src/features/settings/locationSettingHolder.js | 27 | ||||
-rw-r--r-- | src/features/settings/metadata.json | 8 | ||||
-rw-r--r-- | src/features/settings/settingThings/FakeRequireToggle.js | 27 | ||||
-rw-r--r-- | src/features/settings/settingThings/button.js | 18 | ||||
-rw-r--r-- | src/features/settings/settingThings/dropdownSetting.js | 41 | ||||
-rw-r--r-- | src/features/settings/settingThings/imageLocation.js | 321 | ||||
-rw-r--r-- | src/features/settings/settingThings/location.js | 340 | ||||
-rw-r--r-- | src/features/settings/settingThings/settingBase.js | 162 | ||||
-rw-r--r-- | src/features/settings/settingThings/textSetting.js | 41 | ||||
-rw-r--r-- | src/features/settings/settingThings/toggle.js | 62 | ||||
-rw-r--r-- | src/features/settings/settingsCommunicator.js | 35 |
13 files changed, 1464 insertions, 0 deletions
diff --git a/src/features/settings/helpDataLoader.js b/src/features/settings/helpDataLoader.js new file mode 100644 index 0000000..21ca241 --- /dev/null +++ b/src/features/settings/helpDataLoader.js @@ -0,0 +1,50 @@ +import { fetch } from "../../utils/networkUtils"; + +class HelpDataLoader { + constructor() { + this.availableHelpData = {} + this.dataCach = {} + + fetch("http://soopy.dev/api/soopyv2/settingshelpoptions.json").json().then(data => { + Object.keys(data).forEach(category => { + this.availableHelpData[category] = new Set(data[category]) + }); + }) + } + + hasData(category, id) { + return this.availableHelpData[category] && this.availableHelpData[category].has(id) + } + + getData(category, id, callback) { + if (!this.hasData(category, id)) { + callback("") + return + } + + if (this.dataCach[category] && this.dataCach[category][id]) { + callback(this.dataCach[category][id]) + return + } + + fetch("http://soopy.dev/api/soopyv2/settingshelp/" + category + "/" + id).text().then(data => { + if (!this.dataCach[category]) { + this.dataCach[category] = {} + } + + this.dataCach[category][id] = data + + callback(data) + }) + } +} + +if (!global.helpDataLoader) { + global.helpDataLoader = new HelpDataLoader(); + + register("gameUnload", () => { + global.helpDataLoader = undefined + }) +} + +export default global.helpDataLoader;
\ No newline at end of file diff --git a/src/features/settings/index.js b/src/features/settings/index.js new file mode 100644 index 0000000..38ccb9d --- /dev/null +++ b/src/features/settings/index.js @@ -0,0 +1,332 @@ +/// <reference types="../../../../CTAutocomplete" /> +/// <reference lib="es2015" /> +import Feature from "../../featureClass/class"; +import SoopyGuiElement from "../../../guimanager/GuiElement/SoopyGuiElement"; +import SoopyTextElement from "../../../guimanager/GuiElement/SoopyTextElement"; +import SoopyBoxElement from "../../../guimanager/GuiElement/SoopyBoxElement"; +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 settingsCommunicator from "./settingsCommunicator"; +import GuiPage from "../soopyGui/GuiPage" +import { SoopyGui, SoopyRenderEvent } from "../../../guimanager"; +import TextBox from "../../../guimanager/GuiElement/TextBox"; +import locationSettingHolder from "./locationSettingHolder"; + + +class SettingsRenderer extends Feature { + constructor() { + super() + } + + onEnable() { + this.SettingPage = new SettingPage() + this.EditLocationsPage = new EditLocationsPage() + this.SettingPage.FeatureManager = this.FeatureManager + + this.registerStep(true, 1, () => { + if (!this.EditLocationsPage) return + + if (this.EditLocationsPage.needsExitPage) { + this.EditLocationsPage.goToPage(0, 500) + this.EditLocationsPage.needsExitPage = false + } + }) + + this.registerCommand("soopytogglesetting", (category, setting) => { + settingsCommunicator.settings?.[category]?.[setting]?.setValue(!settingsCommunicator.settings?.[category]?.[setting]?.getValue()) + }) + + } + + onDisable() { + this.EditLocationsPage = undefined + this.SettingPage = undefined + } +} + +class EditLocationsPage extends GuiPage { + + constructor() { + super(9) + + this.name = "Edit GUI Locations" + + this.needsExitPage = false + + this.soopyGui = new SoopyGui() + this.soopyGui._renderBackground = () => { } //remove background darkening + + + + this.soopyGui.ctGui.registerDraw((mouseX, mouseY, partialTicks) => { + this.renderGui(mouseX, mouseY) + this.soopyGui._render(mouseX, mouseY, partialTicks) + }) + this.soopyGui.ctGui.registerClicked((mouseX, mouseY, button) => { + this.clicked(mouseX, mouseY) + this.soopyGui._onClick(mouseX, mouseY, button) + }) + this.soopyGui.ctGui.registerMouseReleased((mouseX, mouseY) => { + this.released(mouseX, mouseY) + }) + + this.finaliseLoading() + } + + renderGui(mouseX, mouseY) { + for (let setting of locationSettingHolder.getData()) { + if (setting.parent) { + if (setting.parent.isEnabled()) { + setting.renderGui(mouseX, mouseY) + } + } else { + setting.renderGui(mouseX, mouseY) + } + } + } + + clicked(mouseX, mouseY) { + for (let setting of locationSettingHolder.getData()) { + if (setting.clicked(mouseX, mouseY)) return //dont allow the user to drag 2 locations at once + } + } + + released(mouseX, mouseY) { + for (let setting of locationSettingHolder.getData()) { + setting.released(mouseX, mouseY) + } + } + + onOpen() { + this.needsExitPage = true + + this.soopyGui.open() + } +} + +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 SoopyRenderEvent().setHandler(() => { this.updateLocs() })) + + //############################################################################################### + // Settings Category Page + //############################################################################################### + + + let settingsCategoryTitle = new SoopyTextElement().setText("§0Settings").setMaxTextScale(3).setLocation(0.1, 0.05, 0.5, 0.1) + this.pages[0].addChild(settingsCategoryTitle) + + this.settingsCategorySearch = new TextBox().setPlaceholder("Search...").setLocation(0.6, 0.05 + 0.0125, 0.3, 0.075) + this.pages[0].addChild(this.settingsCategorySearch) + + this.settingsCategorySearch.text.addEvent(new SoopyContentChangeEvent().setHandler(() => { + this.updateSettingCategories() + })) + + 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) + this.settingsCategoryArea._scrollAmount = 0 + + this.settingsCategorySearch.setText("") + this.updateSettingCategories() + } + + onOpenPage(p) { + if (p === 1) this.updateSettingCategories() + + this.closeSidebarPage() + } + + updateSettingCategories() { + + let search = this.settingsCategorySearch.text.text + + this.settingsCategoryArea.children = [] + + let height = 0 + + Object.keys(this.FeatureManager.featureMetas).sort((a, b) => { return a.sortA - b.sortA }).forEach((f) => { + + let meta = this.FeatureManager.featureMetas[f] + + let showing = search.length === 0 + + if (!showing) { + showing = meta.name.toLowerCase().includes(search.toLowerCase()) || meta.description.toLowerCase().includes(search.toLowerCase()) + } + + if (!showing) { + settingsCommunicator.getModuleSettings(f).forEach(setting => { + + if (setting && (setting.name.toLowerCase().includes(search.toLowerCase()) || setting.description.toLowerCase().includes(search.toLowerCase()))) { + showing = true + } + }) + } + + if (!showing) return + + let isHidden = meta.isHidden + if (typeof isHidden === "string") { + isHidden = require("../" + f + "/" + isHidden).hidden(this.FeatureManager) + } + if (isHidden) return + + let category = new ButtonWithArrowAndDescription().setText("&0" + meta.name).setDesc("&0" + meta.description).setLocation(0, height, 1, 0.15) + category.addEvent(new SoopyMouseClickEvent().setHandler(() => { this.clickedOpenCategory(f) })) + + this.settingsCategoryArea.addChild(category) + + height += 0.175 + + + if (search.length > 0) { + settingsCommunicator.getModuleSettings(f).forEach(setting => { + + if (setting && (setting.name.toLowerCase().includes(search.toLowerCase()) || setting.description.toLowerCase().includes(search.toLowerCase()))) { + + setting.getGuiObject().location.location.y.set(height, 0) + this.settingsCategoryArea.addChild(setting.getGuiObject()) + + height += 0.025 + setting.getGuiObject().location.size.y.get() + + setting.update() + } + }) + } + }) + + + // 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.15).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 + 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) + } + + + this.modifyingFeature = false + + this.updateSettings(category) + })) + 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.15) + .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.getGuiObject().location.location.y.set(height, 0) + this.settingsArea.addChild(setting.getGuiObject()) + + height += 0.045 + setting.getGuiObject().location.size.y.get() + + setting.update() + }) + } + + 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()) + }) + + totalHeight = 0 + + this.settingsCategoryArea.children.forEach(e => { + e.location.location.y.set(totalHeight, 0) + + totalHeight += e.location.size.y.get() + Math.min(0.025, 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) + this.settingsArea._scrollAmount = 0 + } +} + +module.exports = { + class: new SettingsRenderer() +}
\ No newline at end of file diff --git a/src/features/settings/locationSettingHolder.js b/src/features/settings/locationSettingHolder.js new file mode 100644 index 0000000..af6f507 --- /dev/null +++ b/src/features/settings/locationSettingHolder.js @@ -0,0 +1,27 @@ +class LocationSettingHolder { + constructor() { + this.data = new Set(); + } + + addLocationSetting(setting) { + this.data.add(setting) + } + + removeLocationSetting(setting) { + this.data.delete(setting) + } + + getData() { + return [...this.data] + } +} + +if (!global.LocationSettingHolder) { + global.LocationSettingHolder = new LocationSettingHolder(); + + register("gameUnload", () => { + global.LocationSettingHolder = undefined + }) +} + +export default global.LocationSettingHolder;
\ No newline at end of file diff --git a/src/features/settings/metadata.json b/src/features/settings/metadata.json new file mode 100644 index 0000000..8f2ace4 --- /dev/null +++ b/src/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/src/features/settings/settingThings/FakeRequireToggle.js b/src/features/settings/settingThings/FakeRequireToggle.js new file mode 100644 index 0000000..41932f3 --- /dev/null +++ b/src/features/settings/settingThings/FakeRequireToggle.js @@ -0,0 +1,27 @@ + +class FakeRequireToggle{ + constructor(val){ + this.val = val + + this.thisToggleEvents = [] + + this.toggleObject = { + addEvent: (event)=>{ + this.thisToggleEvents.push(event) + } + } + } + + set(newVal){ + if(this.val === newVal) return + this.val = newVal + + this.thisToggleEvents.forEach(e=>e._trigger(this, [this.val])) + } + + getValue(){ + return this.val + } +} + +export default FakeRequireToggle
\ No newline at end of file diff --git a/src/features/settings/settingThings/button.js b/src/features/settings/settingThings/button.js new file mode 100644 index 0000000..77ba4b8 --- /dev/null +++ b/src/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/src/features/settings/settingThings/dropdownSetting.js b/src/features/settings/settingThings/dropdownSetting.js new file mode 100644 index 0000000..0cf7b27 --- /dev/null +++ b/src/features/settings/settingThings/dropdownSetting.js @@ -0,0 +1,41 @@ + +import SoopyContentChangeEvent from "../../../../guimanager/EventListener/SoopyContentChangeEvent"; +import SettingBase from "./settingBase"; +import Dropdown from "../../../../guimanager/GuiElement/Dropdown"; + +class DropdownSetting extends SettingBase { + constructor(name, description, defaultVal, settingId, module, optionsData){ + super(name, description, defaultVal, settingId, module) + + this.dropdownObject = new Dropdown().setLocation(0, 0.2, 0.9, 0.6).setOptions(optionsData).setSelectedOption(this.getValue()) + this.settingObject.addChild(this.dropdownObject) + + 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.dropdownObject.addEvent(new SoopyContentChangeEvent().setHandler((newVal, oldVal, resetFun)=>{ + this.setValue(newVal) + })) + + } + update(){ + if(this.hasHelp()){ + this.guiObject.addChild(this.helpButton) + + this.guiObject.text.setLocation(0.075, 0, 0.6-0.075, 0.6) + }else{ + this.guiObject.text.setLocation(0, 0, 0.6, 0.6) + } + } + + setValue(newVal){ + super.setValue(newVal) + + this.dropdownObject.setSelectedOption(newVal) + + return this + } +} + +export default DropdownSetting
\ No newline at end of file diff --git a/src/features/settings/settingThings/imageLocation.js b/src/features/settings/settingThings/imageLocation.js new file mode 100644 index 0000000..c459c82 --- /dev/null +++ b/src/features/settings/settingThings/imageLocation.js @@ -0,0 +1,321 @@ +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" +import locationSettingHolder from "../locationSettingHolder" + +class ImageLocationSetting extends ButtonSetting { + constructor(name, description, settingId, module, defaultLocation, image, imageWBase, imageHBase) { + 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.image = image + this.imageWBase = imageWBase + this.imageHBase = imageHBase + + this.dragging = false + this.dragOffset = [0, 0] + this.resisizing = false + this.resizePoint = 0 + this.resizeInitialPos = [0, 0, 0, 0, 0, 0] + + 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) + }) + + locationSettingHolder.addLocationSetting(this) + } + + requires(toggleSetting) { + this.requiresO = toggleSetting + + toggleSetting.toggleObject.addEvent(new SoopyContentChangeEvent().setHandler((newVal, oldVal, resetFun) => { + if (newVal) { + this.guiObject.location.size.y.set(0.15, 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]) + } + + editPosition() { + this.guiObject.main.ctGui.close() + + this.soopyGui.open() + } + + clicked(mouseX, mouseY) { + let width = this.getWidth() + let height = this.getHeight() + + 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] + return true + } + return false + } + released(mouseX, mouseY) { + this.updateLocation(mouseX, mouseY) + this.dragging = false + this.resisizing = false + + this._updateValue() + } + + getWidth() { + return this.imageWBase + } + + getHeight() { + return this.imageHBase + } + + updateLocation(mouseX, mouseY, drawCollidingBox) { + let width = this.getWidth() + let height = this.getHeight() + + if (this.dragging) { + this.x = mouseX + this.dragOffset[0] + this.y = mouseY + this.dragOffset[1] + + let snapPoints = [] + locationSettingHolder.getData().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) { + + let width = this.getWidth() + let height = this.getHeight() + + this.image.draw(this.x, this.y, width * this.scale, height * this.scale) + + 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 = this.getHeight() + + 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 ImageLocationSetting
\ No newline at end of file diff --git a/src/features/settings/settingThings/location.js b/src/features/settings/settingThings/location.js new file mode 100644 index 0000000..4e18446 --- /dev/null +++ b/src/features/settings/settingThings/location.js @@ -0,0 +1,340 @@ +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" +import locationSettingHolder from "../locationSettingHolder" + +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] ?? 10 + this.y = this.getValue()[1] ?? 10 + this.scale = this.getValue()[2] || 1 + 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.onChange = undefined + + 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) + }) + + locationSettingHolder.addLocationSetting(this) + } + + requires(toggleSetting) { + this.requiresO = toggleSetting + + toggleSetting.toggleObject.addEvent(new SoopyContentChangeEvent().setHandler((newVal, oldVal, resetFun) => { + if (newVal) { + this.guiObject.location.size.y.set(0.15, 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() { + locationSettingHolder.removeLocationSetting(this) + } + + _updateValue() { + this.setValue([this.x, this.y, this.scale, this.shadowType]) + if (this.onChange) this.onChange() + } + + 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 = this.parent.getHeight(true) + + 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] + return true + } + return false + } + released(mouseX, mouseY) { + this.updateLocation(mouseX, mouseY) + this.dragging = false + this.resisizing = false + + this._updateValue() + } + + getWidth() { + return this.parent.getWidth(true) + } + + updateLocation(mouseX, mouseY, drawCollidingBox) { + let width = this.getWidth() + let height = this.parent.getHeight(true) + + if (this.dragging) { + this.x = mouseX + this.dragOffset[0] + this.y = mouseY + this.dragOffset[1] + + let snapPoints = [] + locationSettingHolder.getData().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 = this.parent.getHeight(true) + + 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 = this.parent.getHeight(true) + + 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/src/features/settings/settingThings/settingBase.js b/src/features/settings/settingThings/settingBase.js new file mode 100644 index 0000000..5320f40 --- /dev/null +++ b/src/features/settings/settingThings/settingBase.js @@ -0,0 +1,162 @@ +import SoopyContentChangeEvent from "../../../../guimanager/EventListener/SoopyContentChangeEvent"; +import SoopyMouseClickEvent from "../../../../guimanager/EventListener/SoopyMouseClickEvent"; +import BoxWithText from "../../../../guimanager/GuiElement/BoxWithText"; +import BoxWithTextAndDescription from "../../../../guimanager/GuiElement/BoxWithTextAndDescription" +import SoopyGuiElement from "../../../../guimanager/GuiElement/SoopyGuiElement"; +import renderLibs from "../../../../guimanager/renderLibs"; +import helpDataLoader from "../helpDataLoader"; +import settingsCommunicator from "../settingsCommunicator"; +import SoopyMarkdownElement from "../../../../guimanager/GuiElement/SoopyMarkdownElement"; + +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.contributorVal = undefined + + this.val = defaultVal; + + this.guiObject = new BoxWithTextAndDescription().setDesc("§0" + this.description.replace(/\n/g, "\n§0")).setText("§0" + this.name).setLocation(0, 0, 1, 0.15) + + this.settingObject = new SoopyGuiElement().setLocation(0.8, 0, 0.15, 1) + + this.guiObject.addChild(this.settingObject) + + this.helpButton = new BoxWithText().setText("§0?").setLocation(3, 3, 0.05, 0.5) + this.helpButton.location.location.setRelative(false, false) + + this.helpButton.addEvent(new SoopyMouseClickEvent().setHandler(() => { + module.FeatureManager.features.soopyGui.class.openSidebarPage(new SoopyGuiElement().setLocation(0.05, 0.05, 0.9, 0.9).setScrollable(true).addChild(new SoopyMarkdownElement().setLocation(0, 0, 1, 1).setText("Loading..."))) + + this.getHelp(helpText => { + module.FeatureManager.features.soopyGui.class.openSidebarPage(new SoopyGuiElement().setLocation(0.05, 0.05, 0.9, 0.9).setScrollable(true).addChild(new SoopyMarkdownElement().setLocation(0, 0, 1, 1).setText(helpText))) + }) + })) + + this.helpButton.setLore(["Click for more information about this setting"]) + + settingsCommunicator.addSetting(this.moduleId, settingId, this) + + 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 + + this.onchangethings = [] + + this.initTime = Date.now() + } + + update() { + if (this.hasHelp()) { + this.guiObject.addChild(this.helpButton) + + this.guiObject.text.setLocation(0.075, 0, 0.8 - 0.075, 0.6) + } else { + this.guiObject.text.setLocation(0, 0, 0.8, 0.6) + } + } + + hasHelp() { + return helpDataLoader.hasData(this.moduleId, this.settingId) + } + + getHelp(callback) { + helpDataLoader.getData(this.moduleId, this.settingId, callback) + } + + getValue() { + return this.val; + } + + setValue(val) { + if (this.val === val) return + 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 + } + + if (this.onchangethings && Date.now() - this.initTime > 1000) this.onchangethings.forEach(([fun, context]) => { fun.call(context) }) + } + + 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.15, 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 + } + + contributor(name, things = []) { + this.contributorVal = { name, things } + //TODO: this entire function + return this + } + + delete() { + settingsCommunicator.removeSetting(this.module, this.settingId) + } + + onchange(context, fun) { + this.onchangethings.push([fun, context]) + return this + } +} + +export default SettingBase
\ No newline at end of file diff --git a/src/features/settings/settingThings/textSetting.js b/src/features/settings/settingThings/textSetting.js new file mode 100644 index 0000000..edc0989 --- /dev/null +++ b/src/features/settings/settingThings/textSetting.js @@ -0,0 +1,41 @@ + +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.text.addEvent(new SoopyContentChangeEvent().setHandler((newVal, oldVal, resetFun) => { + this.setValue(newVal) + })) + + } + update() { + if (this.hasHelp()) { + this.guiObject.addChild(this.helpButton) + + this.guiObject.text.setLocation(0.075, 0, 0.6 - 0.075, 0.6) + } else { + this.guiObject.text.setLocation(0, 0, 0.6, 0.6) + } + } + setValue(newVal) { + super.setValue(newVal) + + this.textObject.setText(newVal) + + return this + } +} + +export default TextSetting
\ No newline at end of file diff --git a/src/features/settings/settingThings/toggle.js b/src/features/settings/settingThings/toggle.js new file mode 100644 index 0000000..24310d2 --- /dev/null +++ b/src/features/settings/settingThings/toggle.js @@ -0,0 +1,62 @@ +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.onChange = undefined + + 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) + + if (this.onChange) this.onChange() + + 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.15, 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/src/features/settings/settingsCommunicator.js b/src/features/settings/settingsCommunicator.js new file mode 100644 index 0000000..053a7c1 --- /dev/null +++ b/src/features/settings/settingsCommunicator.js @@ -0,0 +1,35 @@ +//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] || []) + } +} + +if(!global.soopyv2SettingsCommunicator){ + global.soopyv2SettingsCommunicator = new SettingsCommunicator() + + register("gameUnload", ()=>{ + global.soopyv2SettingsCommunicator = undefined + }) +} + +export default global.soopyv2SettingsCommunicator
\ No newline at end of file |