curls/server/static/dashboard/js/main/combo.js

130 lines
2.9 KiB
JavaScript

/*
This is a button widget
It can be used to cycle through a list of items
It uses NeedContext to show the menu
It's similar to a select widget
*/
class Combo {
constructor(args) {
this.args = args
this.prepare()
}
prepare() {
DOM.evs(this.args.element, [`click`, `contextmenu`], (e) => {
this.show_menu(e)
e.preventDefault()
})
DOM.ev(this.args.element, `auxclick`, (e) => {
if (e.button === 1) {
this.reset()
}
})
DOM.ev(this.args.element, `wheel`, (e) => {
let direction = Utils.wheel_direction(e)
this.cycle(direction)
e.preventDefault()
})
let lines = [
this.args.title,
`Click to pick option`,
`Wheel to cycle option`,
`Middle Click to reset`,
]
this.args.element.title = lines.join(`\n`)
if (this.args.extra_title) {
this.args.element.title += `\n${this.args.extra_title}`
}
this.block = new Block()
this.update_text()
}
get_item() {
return this.args.items.find(x => x.value === this.args.get())
}
update_text() {
let item = this.get_item(this.args)
this.args.element.textContent = item.name
}
show_menu(e) {
let items = []
let current = this.args.get()
for (let item of this.args.items) {
if (item.value === Utils.separator) {
items.push({ separator: true })
}
else {
items.push({
text: item.name,
action: () => {
this.action(item.value)
},
selected: item.value === current,
info: item.info,
icon: item.icon,
})
}
}
Utils.context({ items: items, e: e, input: this.args.input })
}
action(value) {
this.args.action(value)
this.update_text()
}
reset() {
this.action(this.args.default)
}
get_values() {
return this.args.items
.filter(x => x.value !== Utils.separator)
.filter(x => !x.skip)
.map(x => x.value)
}
cycle(direction) {
if (this.block.add_charge()) {
return
}
let value = this.args.get()
let values = this.get_values(this.args)
let index = values.indexOf(value)
if (direction === `up`) {
index -= 1
}
else if (direction === `down`) {
index += 1
}
if (index < 0) {
index = values.length - 1
}
else if (index >= values.length) {
index = 0
}
let new_value = values[index]
this.action(new_value)
}
set_value(value) {
this.action(value)
}
}