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 } }