Skip to content

Commit 54939f3

Browse files
committed
Refactor mod options type system
1 parent 050eed3 commit 54939f3

10 files changed

Lines changed: 98 additions & 102 deletions

File tree

src/gui/options/option-elements/all.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { GuiOption } from '../../../mod-options'
1+
import { GuiOption, OptionVisibleTypes } from '../../../mod-options'
22

33
declare global {
44
namespace modmanager.gui.Options {}
@@ -12,14 +12,14 @@ import './info'
1212
import './input-field'
1313
import './object-slider'
1414

15-
export interface ModOptionsOptionElement {
16-
guiOption: GuiOption
15+
export interface ModOptionsOptionElement<T extends OptionVisibleTypes> {
16+
guiOption: GuiOption<T>
1717

1818
getNameGuiInfo(this: this): { has: boolean }
1919
}
2020

21-
export interface ModOptionsOptionConstructor<T extends ModOptionsOptionElement> {
22-
new (optionRow: modmanager.gui.OptionsOptionRow, width: number, rowGroup: sc.RowButtonGroup): T
21+
export interface ModOptionsOptionConstructor<E extends ModOptionsOptionElement<T>, T extends OptionVisibleTypes> {
22+
new (optionRow: modmanager.gui.OptionsOptionRow<T>, width: number, rowGroup: sc.RowButtonGroup): E
2323
}
2424

2525
export function optGet(guiOption: GuiOption): unknown {

src/gui/options/option-elements/button-group.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,25 @@ import { ModOptionsOptionConstructor, ModOptionsOptionElement, optGet, optSet }
22

33
declare global {
44
namespace modmanager.gui.Options {
5-
interface BUTTON_GROUP extends sc.OPTION_GUIS_DEFS.BUTTON_GROUP, ModOptionsOptionElement {}
5+
interface BUTTON_GROUP extends sc.OPTION_GUIS_DEFS.BUTTON_GROUP, ModOptionsOptionElement<'BUTTON_GROUP'> {}
66
interface BUTTON_GROUP_CONSTRUCTOR
77
extends ImpactClass<BUTTON_GROUP>,
8-
ModOptionsOptionConstructor<BUTTON_GROUP> {}
8+
ModOptionsOptionConstructor<BUTTON_GROUP, 'BUTTON_GROUP'> {}
99
var BUTTON_GROUP: BUTTON_GROUP_CONSTRUCTOR
1010
}
1111
}
1212

1313
modmanager.gui.Options ??= {} as any
1414
modmanager.gui.Options.BUTTON_GROUP = sc.OPTION_GUIS[sc.OPTION_TYPES.BUTTON_GROUP].extend({
1515
init(optionRow, width, rowGroup) {
16-
const option = (optionRow as modmanager.gui.OptionsOptionRow).guiOption
17-
this.guiOption = option
18-
if (option.type != 'BUTTON_GROUP') throw new Error('what')
16+
this.guiOption = optionRow.guiOption
1917

20-
const index = optGet(option) as number
18+
const index = optGet(this.guiOption) as number
2119

2220
const backup_ig_lang_get = ig.lang.get
2321
// @ts-expect-error
2422
ig.lang.get = (): string[] => {
25-
return option.buttonNames ?? []
23+
return this.guiOption.buttonNames ?? []
2624
}
2725
const backup_sc_options_get = sc.options.get
2826
sc.options.get = () => index

src/gui/options/option-elements/button.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import { ModOptionsOptionConstructor, ModOptionsOptionElement } from './all'
22

33
declare global {
44
namespace modmanager.gui.Options {
5-
interface BUTTON extends ig.GuiElementBase, ModOptionsOptionElement {
5+
interface BUTTON extends ig.GuiElementBase, ModOptionsOptionElement<'BUTTON'> {
66
button: sc.ButtonGui
77
}
8-
interface BUTTON_CONSTRUCTOR extends ImpactClass<BUTTON>, ModOptionsOptionConstructor<BUTTON> {}
8+
interface BUTTON_CONSTRUCTOR extends ImpactClass<BUTTON>, ModOptionsOptionConstructor<BUTTON, 'BUTTON'> {}
99
var BUTTON: BUTTON_CONSTRUCTOR
1010
}
1111
}
@@ -14,21 +14,19 @@ modmanager.gui.Options.BUTTON = ig.GuiElementBase.extend({
1414
init(optionRow, _width, rowGroup) {
1515
this.parent()
1616

17-
const option = (optionRow as modmanager.gui.OptionsOptionRow).guiOption
18-
this.guiOption = option
19-
if (option.type != 'BUTTON') throw new Error('how')
17+
this.guiOption = optionRow.guiOption
2018

21-
this.button = new sc.ButtonGui(option.name)
22-
if (option.onPress) {
19+
this.button = new sc.ButtonGui(this.guiOption.name)
20+
if (this.guiOption.onPress) {
2321
this.button.onButtonPress = () => {
24-
option.onPress.call(option)
22+
this.guiOption.onPress.call(this.guiOption)
2523
}
2624
}
2725

2826
this.button.setAlign(ig.GUI_ALIGN.X_LEFT, ig.GUI_ALIGN.Y_CENTER)
2927

3028
const backup = this.button.focusGained.bind(this.button)
31-
this.button.data = option.description
29+
this.button.data = this.guiOption.description
3230
this.button.focusGained = function (this: sc.ButtonGui) {
3331
backup()
3432
sc.menu.setInfoText(this.data as string)

src/gui/options/option-elements/checkbox.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ import { ModOptionsOptionConstructor, ModOptionsOptionElement, optGet, optSet }
22

33
declare global {
44
namespace modmanager.gui.Options {
5-
interface CHECKBOX extends sc.OPTION_GUIS_DEFS.CHECKBOX, ModOptionsOptionElement {
5+
interface CHECKBOX extends sc.OPTION_GUIS_DEFS.CHECKBOX, ModOptionsOptionElement<'CHECKBOX'> {
66
currentNumber: sc.TextGui
77
}
8-
interface CHECKBOX_CONSTRUCTOR extends ImpactClass<CHECKBOX>, ModOptionsOptionConstructor<CHECKBOX> {}
8+
interface CHECKBOX_CONSTRUCTOR
9+
extends ImpactClass<CHECKBOX>,
10+
ModOptionsOptionConstructor<CHECKBOX, 'CHECKBOX'> {}
911
var CHECKBOX: CHECKBOX_CONSTRUCTOR
1012
}
1113
}
@@ -14,7 +16,7 @@ modmanager.gui.Options.CHECKBOX = sc.OPTION_GUIS[sc.OPTION_TYPES.CHECKBOX].exten
1416
init(optionRow, width, rowGroup) {
1517
this.parent(optionRow, width, rowGroup)
1618

17-
this.guiOption = (optionRow as modmanager.gui.OptionsOptionRow).guiOption
19+
this.guiOption = optionRow.guiOption
1820

1921
this.button.setPressed(optGet(this.guiOption) as boolean)
2022
},

src/gui/options/option-elements/controls.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,25 @@ import { ModOptionsOptionConstructor, ModOptionsOptionElement } from './all'
22

33
declare global {
44
namespace modmanager.gui.Options {
5-
interface CONTROLS extends sc.OPTION_GUIS_DEFS.CONTROLS, ModOptionsOptionElement {
5+
interface CONTROLS extends sc.OPTION_GUIS_DEFS.CONTROLS, ModOptionsOptionElement<'CONTROLS'> {
66
currentNumber: sc.TextGui
77
}
8-
interface CONTROLS_CONSTRUCTOR extends ImpactClass<CONTROLS>, ModOptionsOptionConstructor<CONTROLS> {}
8+
interface CONTROLS_CONSTRUCTOR
9+
extends ImpactClass<CONTROLS>,
10+
ModOptionsOptionConstructor<CONTROLS, 'CONTROLS'> {}
911
var CONTROLS: CONTROLS_CONSTRUCTOR
1012
}
1113
}
1214
modmanager.gui.Options.CONTROLS = sc.OPTION_GUIS[sc.OPTION_TYPES.CONTROLS].extend({
1315
init(optionRow, width, rowGroup) {
16+
this.guiOption = optionRow.guiOption
17+
1418
const backup_ig_lang_get = ig.lang.get
1519
// @ts-expect-error
1620
ig.lang.get = (path: string, ...args) => {
1721
if (path == 'sc.gui.options.controls.none') return backup_ig_lang_get.call(ig.lang, path, ...args)
18-
if (path == 'sc.gui.options.controls.description') return optionRow.guiOption.description
19-
if (path.startsWith('sc.gui.options.controls.keys.')) return optionRow.guiOption.name
22+
if (path == 'sc.gui.options.controls.description') return this.guiOption.description
23+
if (path.startsWith('sc.gui.options.controls.keys.')) return this.guiOption.name
2024
throw new Error('what')
2125
}
2226

src/gui/options/option-elements/info.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import { ModOptionsOptionConstructor, ModOptionsOptionElement } from './all'
22

33
declare global {
44
namespace modmanager.gui.Options {
5-
interface INFO extends ig.GuiElementBase, ModOptionsOptionElement {
5+
interface INFO extends ig.GuiElementBase, ModOptionsOptionElement<'INFO'> {
66
text: sc.TextGui
77
box: sc.CenterBoxGui
88
}
9-
interface INFO_CONSTRUCTOR extends ImpactClass<INFO>, ModOptionsOptionConstructor<INFO> {}
9+
interface INFO_CONSTRUCTOR extends ImpactClass<INFO>, ModOptionsOptionConstructor<INFO, 'INFO'> {}
1010
var INFO: INFO_CONSTRUCTOR
1111
}
1212
}
@@ -15,7 +15,7 @@ modmanager.gui.Options.INFO = ig.GuiElementBase.extend({
1515
init(optionRow, width, _rowGroup) {
1616
this.parent()
1717

18-
this.guiOption = (optionRow as modmanager.gui.OptionsOptionRow).guiOption
18+
this.guiOption = optionRow.guiOption
1919

2020
this.text = new sc.TextGui(this.guiOption.name, { maxWidth: width - 36, font: sc.fontsystem.smallFont })
2121
const height = this.text.hook.size.y

src/gui/options/option-elements/input-field.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,19 +75,25 @@ modmanager.gui.InputFieldWrapper = ig.GuiElementBase.extend({
7575

7676
declare global {
7777
namespace modmanager.gui.Options {
78-
interface INPUT_FIELD extends modmanager.gui.InputFieldWrapper, ModOptionsOptionElement {}
79-
interface INPUT_FIELD_CONSTRUCTOR extends ImpactClass<INPUT_FIELD>, ModOptionsOptionConstructor<INPUT_FIELD> {}
78+
interface INPUT_FIELD extends modmanager.gui.InputFieldWrapper, ModOptionsOptionElement<'INPUT_FIELD'> {}
79+
interface INPUT_FIELD_CONSTRUCTOR
80+
extends ImpactClass<INPUT_FIELD>,
81+
ModOptionsOptionConstructor<INPUT_FIELD, 'INPUT_FIELD'> {}
8082
var INPUT_FIELD: INPUT_FIELD_CONSTRUCTOR
8183
}
8284
}
8385

8486
modmanager.gui.Options.INPUT_FIELD = modmanager.gui.InputFieldWrapper.extend({
8587
init(optionRow, width, rowGroup) {
86-
const option = (optionRow as modmanager.gui.OptionsOptionRow).guiOption
87-
this.guiOption = option
88-
if (option.type != 'INPUT_FIELD') throw new Error('how')
88+
this.guiOption = optionRow.guiOption
8989

90-
this.parent(optGet(option) as string, text => optSet(option, text), width, option.isValid, option.description)
90+
this.parent(
91+
optGet(this.guiOption) as string,
92+
text => optSet(this.guiOption, text),
93+
width,
94+
this.guiOption.isValid,
95+
this.guiOption.description
96+
)
9197

9298
rowGroup.addFocusGui(this.inputField, 0, optionRow.row)
9399
},

src/gui/options/option-elements/object-slider.ts

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import { ModOptionsOptionConstructor, ModOptionsOptionElement, optGet, optSet }
22

33
declare global {
44
namespace modmanager.gui.Options {
5-
interface OBJECT_SLIDER extends sc.OPTION_GUIS_DEFS.OBJECT_SLIDER, ModOptionsOptionElement {
5+
interface OBJECT_SLIDER extends sc.OPTION_GUIS_DEFS.OBJECT_SLIDER, ModOptionsOptionElement<'OBJECT_SLIDER'> {
66
currentNumber: sc.TextGui
77
}
88
interface OBJECT_SLIDER_CONSTRUCTOR
99
extends ImpactClass<OBJECT_SLIDER>,
10-
ModOptionsOptionConstructor<OBJECT_SLIDER> {}
10+
ModOptionsOptionConstructor<OBJECT_SLIDER, 'OBJECT_SLIDER'> {}
1111
var OBJECT_SLIDER: OBJECT_SLIDER_CONSTRUCTOR
1212
}
1313
}
@@ -18,33 +18,33 @@ modmanager.gui.Options.OBJECT_SLIDER = ig.GuiElementBase.extend({
1818
this.parent()
1919

2020
this.base = optionRow
21+
this.guiOption = optionRow.guiOption
2122

22-
const option = (optionRow as modmanager.gui.OptionsOptionRow).guiOption
23-
this.guiOption = option
24-
if (option.type != 'OBJECT_SLIDER') throw new Error('what')
23+
const snap = this.guiOption.snap ?? true
2524

26-
const snap = option.snap ?? true
27-
28-
const data = option.data
25+
const data = this.guiOption.data
2926
this.entries = Object.values(data!)
3027
width -= 4
31-
this.showPercentage = option.showPercentage
28+
this.showPercentage = this.guiOption.showPercentage
3229

33-
this.slider = new sc.OptionFocusSlider(this.onChange.bind(this), snap, option.fill, rowGroup)
30+
this.slider = new sc.OptionFocusSlider(this.onChange.bind(this), snap, this.guiOption.fill, rowGroup)
3431

35-
this.slider.setPreferredThumbSize(Math.max(30, option.thumbWidth ?? Math.floor(252 / this.entries.length)), 21)
32+
this.slider.setPreferredThumbSize(
33+
Math.max(30, this.guiOption.thumbWidth ?? Math.floor(252 / this.entries.length)),
34+
21
35+
)
3636

3737
this.slider.setPos(0, 0)
3838
this.slider.setMinMaxValue(0, this.entries.length - 1)
3939
this.slider.setSize(width - 4, 21, 9)
40-
this.slider.data = option.description
40+
this.slider.data = this.guiOption.description
4141
this.addChildGui(this.slider)
4242
this.currentNumber = new sc.TextGui('')
4343
this.currentNumber.setAlign(ig.GUI_ALIGN.X_CENTER, ig.GUI_ALIGN.Y_CENTER)
4444
this.slider.thumb.addChildGui(this.currentNumber)
4545
rowGroup.addFocusGui(this.slider, 0, this.base.row)
4646

47-
const value = optGet(option) as number
47+
const value = optGet(this.guiOption) as number
4848
let index = this.entries.findIndex(v => v == value)
4949
if (index == -1) index = 0
5050
this.slider.setValue(index)
@@ -54,8 +54,6 @@ modmanager.gui.Options.OBJECT_SLIDER = ig.GuiElementBase.extend({
5454
return { has: true }
5555
},
5656
updateNumberDisplay() {
57-
if (this.guiOption.type != 'OBJECT_SLIDER') throw new Error('what')
58-
5957
const func = this.guiOption.customNumberDisplay
6058
if (func) {
6159
let ret = func.call(this.guiOption, this._lastVal)

src/gui/options/option-row.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
import type { GuiOption } from '../../mod-options'
1+
import type { GuiOption, OptionVisibleTypes } from '../../mod-options'
22
import { ModOptionsOptionElement } from './option-elements/all'
33
import './option-elements/all'
44

55
declare global {
66
namespace modmanager.gui {
7-
interface OptionsOptionRow extends sc.OptionRow {
8-
guiOption: GuiOption
7+
interface OptionsOptionRow<T extends OptionVisibleTypes = OptionVisibleTypes> extends sc.OptionRow {
8+
guiOption: GuiOption<T>
99
}
1010
interface OptionsOptionRowConstructor extends ImpactClass<OptionsOptionRow> {
11-
new (
12-
option: GuiOption,
11+
new <T extends OptionVisibleTypes>(
12+
option: GuiOption<T>,
1313
row: number,
1414
rowGroup: sc.RowButtonGroup,
1515
width: number,
1616
height?: number
17-
): OptionsOptionRow
17+
): OptionsOptionRow<T>
1818
}
1919
var OptionsOptionRow: OptionsOptionRowConstructor
2020
}
@@ -32,8 +32,8 @@ modmanager.gui.OptionsOptionRow = sc.OptionRow.extend({
3232
this.optionDes = option.description
3333
this.row = row
3434

35-
const clazz = modmanager.gui.Options[option.type as Exclude<typeof option.type, 'ARRAY_SLIDER' | 'JSON_DATA'>]
36-
let { has: hasNameGui } = (clazz.prototype as ModOptionsOptionElement).getNameGuiInfo()
35+
const clazz = modmanager.gui.Options[option.type as OptionVisibleTypes]
36+
let { has: hasNameGui } = (clazz.prototype as ModOptionsOptionElement<any>).getNameGuiInfo()
3737
hasNameGui &&= !!option.name
3838

3939
const nameGuiPadding: boolean = !option.noNamePadding
@@ -62,7 +62,7 @@ modmanager.gui.OptionsOptionRow = sc.OptionRow.extend({
6262
}
6363

6464
if (clazz) {
65-
const typeGui: ig.GuiElementBase = new clazz(this, optionWidth, rowGroup)
65+
const typeGui: ig.GuiElementBase = new clazz(this as any, optionWidth, rowGroup)
6666
this.typeGui = typeGui as any
6767
typeGui.setSize(optionWidth, Math.max(26, typeGui.hook.size.y))
6868
typeGui.setAlign(ig.GUI_ALIGN.X_LEFT, ig.GUI_ALIGN.Y_BOTTOM)

0 commit comments

Comments
 (0)