CabinGame/Luxe/blocks/ui/slider.wren

112 lines
No EOL
3.6 KiB
Text

import "luxe: ui/control" for Control
import "luxe: world" for UI, World, UIEvent
import "luxe: draw" for PathStyle
import "luxe: assets" for Assets
import "luxe: render" for Image
import "luxe: math" for Math
import "globals" for Globals
import "math/rect" for AABB
import "math/math" for M
import "blocks/debug" for DrawDebug
import "math/util" for Util
class UiSlider{
static horizontal{"horiz"}
static vertical{"vert"}
static create(ent){
var slider = Control.create(ent)
var style = PathStyle.new()
style.color = [1,1,1,1]
style.thickness = 1
Control.set_allow_input(slider, true)
var state = {"value": 0.2,
"style": style,
"pressed": false,
"centerLine": true,
"handle": Assets.image("assets/wip/SliderHandle"),
"direction": UiSlider.horizontal
}
Control.set_state_data(slider, state)
Control.set_render(slider) {|control, state, x, y, w, h|
var depth = UI.draw_depth_of(control, 0)
UI.draw_rect(control, x+0.5, y+0.5, depth, w-1, h-1, 0, state["style"])
if(state["centerLine"]) {
UI.draw_line(control, x + h/2, y + h/2, x + w - h/2, y + h/2, depth, state["style"])
}
var image = state["handle"]
var img_size = [Image.get_width(image), Image.get_height(image)]
var slider_x
var slider_y
if(state["direction"] == UiSlider.horizontal){
slider_x = (M.lerp(x+h/2, x+w-h/2, state["value"]) - img_size.x/2).round
slider_y = y+h/2-img_size.y/2
} else if(state["direction"] == UiSlider.vertical){
slider_x = x+w/2-img_size.x/2
slider_y = (M.lerp(y+w/2, y+h-w/2, state["value"]) - img_size.y/2).round
}
UI.draw_image(control, slider_x, slider_y, depth, img_size.x, img_size.y,
0, [1,1,1,1], [0, 0, 1, 1], image, true)
}
Control.set_process(slider){|control, state, event, x,y,w,h|
if(event.control != control) return
if(!Util.valid_event(event)) return
if(event.type == UIEvent.press){
state["pressed"] = true
UI.capture(control)
} else if(event.type == UIEvent.release){
state["pressed"] = false
UI.uncapture(control)
}
if((event.type == UIEvent.move || event.type == UIEvent.press) && state["pressed"]){
var min
var max
var value
if(state["direction"] == UiSlider.horizontal){
var abs_x = Control.get_pos_x_abs(control)
min = abs_x+h/2
max = abs_x+w-h/2
value = event.x
} else if(state["direction"] == UiSlider.vertical){
var abs_y = Control.get_pos_y_abs(control)
min = abs_y+w/2
max = abs_y+h-w/2
value = event.y
}
var rel_pos = M.inv_lerp(min, max, value)
rel_pos = M.clamp(rel_pos, 0, 1)
UI.events_emit(control, UIEvent.change, rel_pos)
}
}
//default events impl, overridable!
Control.set_events(slider){|event|
if(event.type == UIEvent.change){
set_value(slider, event.change)
}
}
return slider
}
static set_value(slider, value){
var data = Control.get_state_data(slider)
data["value"] = value
}
static set_line(slider, line){
var data = Control.get_state_data(slider)
data["centerLine"] = line
}
static set_direction(slider, direction){
var data = Control.get_state_data(slider)
data["direction"] = direction
}
static set_handle(slider, handle){
var data = Control.get_state_data(slider)
data["handle"] = handle
}
}