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: asset" for Asset 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 "luxe: io" for IO class UiCompass{ static font{Asset.font("assets/fonts/BabyBlocks")} static size{8} static create(ent){ var compass = Control.create(ent) var style = PathStyle.new() style.color = [1,1,1,1] style.thickness = 2 Control.set_allow_input(compass, true) Control.set_state_data(compass, {"angle": 0, "style": style, "pressed": false}) //angle is in degree tragically Control.set_render(compass) {|control, state, x, y, w, h| var depth = UI.draw_depth_of(control, 0) var center = [x + w/2, y + h/2] var image = Assets.image("assets/wip/Needle") var ratio = Image.get_width(image) / Image.get_height(image) var needleSize = [(Math.min(w, h) - 8) * ratio, (Math.min(w, h) - 8)] var angle = state["angle"] UI.draw_ring(control, center.x, center.y, depth, w/2, h/2, 0, 360, 8, state["style"]) UI.draw_image(control, center.x - needleSize.x/2, center.y-needleSize.y/2, depth, needleSize.x, needleSize.y, angle, [1,1,1,1], [0, 0, 1, 1], image, true) } Control.set_process(compass){|control, state, event, x,y,w,h| if(event.control != control) return if(event.type == UIEvent.press){ var relative_pos = AABB.new(x, y, w, h).relative_pos([event.x, event.y]) var inside = M.length(relative_pos.map{|comp| comp - 0.5}) < 0.5 if(inside) { state["pressed"] = true UI.capture(control) } } if(event.type == UIEvent.release){ state["pressed"] = false UI.uncapture(control) } if((event.type == UIEvent.move || event.type == UIEvent.press) && state["pressed"]){ var center = [x + w/2, y + h/2] var diff = [event.x - center.x, event.y - center.y] var angle = Math.atan2(-diff.y, diff.x) - Num.tau / 4 //flip y because ui coordinates are different; shift by 1/4 circle constant to make up 0° UI.events_emit(control, UIEvent.change, Math.degrees(angle)) } } return compass } static set_angle(con, angle){ var data = Control.get_state_data(con) data["angle"] = angle % 360 } static set_color(control, color){ var data = Control.get_state_data(control) data["style"].color = color } }