diff options
| author | Alexander M Pickering <alex@cogarr.net> | 2025-01-09 18:11:46 -0600 |
|---|---|---|
| committer | Alexander M Pickering <alex@cogarr.net> | 2025-01-09 18:11:46 -0600 |
| commit | decb72f936060a65bff18e9cbf33642ea3a71cd0 (patch) | |
| tree | 3b07bb1bfc1e4f0e39ec4ff8e0c243cd4fab0d61 /src/ui | |
| parent | 726876d42270f8974fd495be91127ea7585472ff (diff) | |
| download | ggj25-decb72f936060a65bff18e9cbf33642ea3a71cd0.tar.gz ggj25-decb72f936060a65bff18e9cbf33642ea3a71cd0.tar.bz2 ggj25-decb72f936060a65bff18e9cbf33642ea3a71cd0.zip | |
Work
Diffstat (limited to 'src/ui')
| -rw-r--r-- | src/ui/button.moon | 131 | ||||
| -rw-r--r-- | src/ui/joystick.moon | 98 | ||||
| -rw-r--r-- | src/ui/textbox.moon | 119 |
3 files changed, 348 insertions, 0 deletions
diff --git a/src/ui/button.moon b/src/ui/button.moon new file mode 100644 index 0000000..789ecae --- /dev/null +++ b/src/ui/button.moon @@ -0,0 +1,131 @@ + +s = require("ui.sprites") +util = require("util") +color = require("color") +states = {"up","down"} +rows = {"upper","mid","lower"} +cols = {"left","mid","right"} +class Button + --am.sprite() only works once the window is created + @initalized = false + @initalize: => + for _, state, _, row, _, col in util.cartesian(states, rows, cols) + name = table.concat({state,row,col},"_") + assert(s["button_" .. name], "Failed to find sprite:" .. name) + @[name] = am.sprite(s["button_" .. name],"left","top") + @initalized = true + new: (x,y,w,h,text)=> + if not @@initalized + @@initalize! + @em = 16 -- width of a character + text = text or "" + assert(w > 15, "Button must have at least width 15") + @node = am.group! + position = am.translate(x,y+h)\tag("position") + @up_sprites = am.group! + position\append(@up_sprites) + @down_sprites = am.group! + @node\append(position) + @up_sprites\append(@@up_upper_left) + @up_sprites\append( + am.translate(@@up_upper_left.width,0)\append( + am.scale(w - @@up_upper_left.width - @@up_upper_right.width,1)\append( + @@up_upper_mid + ))) + @up_sprites\append( + am.translate(w - @@up_upper_right.width, 0)\append( + @@up_upper_right + )) + mid_height = h - @@up_upper_left.height - @@up_lower_left.height + @up_sprites\append( + am.translate(0,-@@up_upper_left.height)\append( + am.scale(1,mid_height)\append( + @@up_mid_left + ))) + @up_sprites\append( + am.translate(@@up_upper_left.width, -@@up_upper_left.height)\append( + am.scale(w - @@up_mid_left.width - @@up_mid_right.width, h - @@up_upper_mid.height - @@up_lower_mid.height)\append( + @@up_mid_mid + ))) + @up_sprites\append( + am.translate(w - @@up_mid_right.width,-@@up_upper_right.height)\append( + am.scale(1,h - @@up_upper_right.height - @@up_lower_right.height)\append( + @@up_mid_right + ))) + @up_sprites\append( + am.translate(0,-(h - @@up_lower_left.height))\append( + @@up_lower_left + )) + @up_sprites\append( + am.translate(@@up_lower_left.width,-(h - @@up_lower_mid.height))\append( + am.scale(w - @@up_lower_left.width - @@up_lower_right.width,1)\append( + @@up_lower_mid + ))) + @up_sprites\append( + am.translate(w - @@up_lower_right.width, -(h - @@up_lower_right.height))\append( + @@up_lower_right + )) + @up_sprites\append( + am.translate(@@up_upper_left.width, -@@up_upper_right.height)\append( + am.text(text, "left","top", color.am_color.foreground) + )) + @down_sprites\append(@@down_upper_left) + @down_sprites\append( + am.translate(@@down_upper_left.width,0)\append( + am.scale(w - @@down_upper_left.width - @@down_upper_right.width,1)\append( + @@down_upper_mid + ))) + @down_sprites\append( + am.translate(w - @@down_upper_right.width, 0)\append( + @@down_upper_right + )) + mid_height = h - @@down_upper_left.height - @@down_lower_left.height + @down_sprites\append( + am.translate(0,-@@down_upper_left.height)\append( + am.scale(1,mid_height)\append( + @@down_mid_left + ))) + @down_sprites\append( + am.translate(@@down_upper_left.width, -@@down_upper_left.height)\append( + am.scale(w - @@down_mid_left.width - @@down_mid_right.width, h - @@down_upper_mid.height - @@down_lower_mid.height)\append( + @@down_mid_mid + ))) + @down_sprites\append( + am.translate(w - @@down_mid_right.width,-@@down_upper_right.height)\append( + am.scale(1,h - @@down_upper_right.height - @@down_lower_right.height)\append( + @@down_mid_right + ))) + @down_sprites\append( + am.translate(0,-(h - @@down_lower_left.height))\append( + @@down_lower_left + )) + @down_sprites\append( + am.translate(@@down_lower_left.width,-(h - @@down_lower_mid.height))\append( + am.scale(w - @@down_lower_left.width - @@down_lower_right.width,1)\append( + @@down_lower_mid + ))) + @down_sprites\append( + am.translate(w - @@down_lower_right.width, -(h - @@down_lower_right.height))\append( + @@down_lower_right + )) + @text = am.text(text, "left","top", color.am_color.foreground) + position\append( + am.translate(@@down_upper_left.width, -@@down_upper_right.height)\append( + @text + )) + @depressed = false + down: () => + @depressed = true + @.node("position")\replace(@up_sprites, @down_sprites) + up: () => + @depressed = false + @.node("position")\replace(@down_sprites, @up_sprites) + fire: (e) => + if e.event == "touches_began" or e.event == "mouse_down" + @down! + if @on + @on(e) + if e.event == "touches_ended" or e.event == "mouse_up" + @up! + +Button diff --git a/src/ui/joystick.moon b/src/ui/joystick.moon new file mode 100644 index 0000000..168e18b --- /dev/null +++ b/src/ui/joystick.moon @@ -0,0 +1,98 @@ + +color = require("color") +window = require("window") + +circle_cache = setmetatable({},{__mode: "v"}) +hollow_circle = (x,y,radius, thickness, color) -> + key = string.format("%d\0%d\0%d\0%d",x,y,radius, thickness) + if circle_cache[key] + return circle_cache[key] + arr = {} + segments = 60 + step = (2*math.pi) / segments + for i = 0,2*math.pi, step + arr[#arr+1] = vec2(i+step, 1) + arr[#arr+1] = vec2(i, 1) + arr[#arr+1] = vec2(i+step,0) + arr[#arr+1] = vec2(i+step,0) + arr[#arr+1] = vec2(i,1) + arr[#arr+1] = vec2(i,0) + circle = am.use_program(am.program([[ + precision highp float; + attribute vec2 index; + uniform float thickness; + uniform float radius; + uniform mat4 MV; + uniform mat4 P; + void main() { + float distance = thickness * index[1]; + vec2 vert = vec2(cos(index[0]) * (radius - distance), sin(index[0]) * (radius - distance)); + gl_Position = P * MV * vec4(vert, 0.0, 1.0); + } + ]],[[ + precision mediump float; + uniform vec4 color; + void main() { + gl_FragColor = color; + } + ]]))\append(am.bind({ + MV: mat4( + 1, 0, 0, 0 + 0, 1, 0, 0 + 0, 0, 1, 0 + x, y, 0, 1 + ) + thickness: thickness + radius: radius + index: am.vec2_array(arr) + color: color + })\append(am.draw("triangles"))) + circle_cache[key] = circle + circle + +class Joystick + --am.sprite() only works once the window is created + @initalized = false + @initalize: => + @hollow_circle = am.group! + step = 0.5 + thickness = 0.02 + lastpoint = vec2(1,0) + print("color.am_color.background is:", color.am_color.background) + for k,v in pairs(color.am_color) + print(k,":",v) + highlight_start = (5/8) * math.pi + highlight_end = (7/8) * math.pi + shadow_start = (3/2) * math.pi + shadow_end = 2 * math.pi + for i = 0,2*math.pi,step + nextpoint = vec2(math.cos(i), math.sin(i)) + @hollow_circle\append(am.line(lastpoint + vec2(1,1), nextpoint + vec2(1,1), thickness, color.am_color.outline)) + --@hollow_circle\append(am.line(lastpoint, nextpoint, thickness, color.am_color.background)) + lastpoint = nextpoint + @hollow_circle\append(am.line(lastpoint, vec2(1,0), thickness * 2, color.am_color.outline)) + @hollow_circle\append(am.line(lastpoint,vec2(1,0), thickness, color.am_color.background)) + @initalized = true + new: (x,y,r)=> + if not @@initalized + @@initalize! + @node = am.group! + position = am.translate(x,y)\tag("position") + @node\append(position) + --position\append(am.circle(vec2(x,y), r, color.am_color.background)) + @stick_pos = am.translate(0,0)\tag("stick") + position\append( + @stick_pos\append( + am.circle(vec2(0,0), r/9, color.am_color.outline)\append( + am.circle(vec2(0,0), r/10, color.am_color.background)\append( + am.circle(vec2(-r/60,r/60),r/15, color.am_color.foreground)\append( + am.circle(vec2(5,-5),r/13, color.am_color.background) + ))))) + --position\append(am.scale(r,r)\append(@@hollow_circle)) + --position\append(am.circle(vec2(x,y),r)\append(am.blend("subtract")\append(am.circle(vec2(x,y),r-10)))) + position\append(hollow_circle(x,y,r,8,color.am_color.outline)) + position\append(hollow_circle(x,y,r-math.sqrt(2),5,color.am_color.background)) + fire: (tbl) => + print("Fired",tbl) + +Joystick diff --git a/src/ui/textbox.moon b/src/ui/textbox.moon new file mode 100644 index 0000000..3c6151d --- /dev/null +++ b/src/ui/textbox.moon @@ -0,0 +1,119 @@ + +color = require("color") +Button = require("ui.button") + +valid_chars = "abcdefghijklmnopqrstuvwxyz" +shifted_nums = "!@#$%^&*()" +class Textbox extends Button + new: (x,y,w,h,value,placeholder) => + super(x,y,w,h,value) + if value == "" + @text.text = placeholder + @text.color = color.am_color.shadow + @cursor = am.group( + am.translate(@em,0)\append( + am.rect(0,0,@em/4,-@em,color.am_color.foreground) + )) + @cursor.hidden = true + @text\append(@cursor) + @cursor_pos = #@text.text + @update_cursor_pos! + @valid_chars = {} + @max_chars = math.huge + for i = 1, #valid_chars + char = valid_chars\sub(i,i) + @valid_chars[char] = char + @valid_chars[char\upper] = char\upper + for i = 0,9 + @valid_chars[tostring(i)] = tostring(i) + @valid_chars["kp_" .. tostring(i)] = tostring(i) + @valid_chars.kp_divide = "/" + @valid_chars.kp_multiply = "*" + @valid_chars.kp_minus = "-" + @valid_chars.kp_plus = "+" + @valid_chars.kp_period = "." + @valid_chars.space = " " + @valid_chars.minus = "-" + @valid_chars.MINUS = "_" + @valid_chars.equals = "=" + @valid_chars.EQUALS = "+" + @valid_chars.leftbracket = "[" + @valid_chars.LEFTBRACKET = "{" + @valid_chars.rightbracket = "]" + @valid_chars.RIGHTBRACKET = "}" + @valid_chars.semicolon = ";" + @valid_chars.SEMICOLON = ":" + @valid_chars.quote = "'" + @valid_chars.QUOTE = '"' + @valid_chars.backquote = "`" + @valid_chars.BACKQUOTE = "~" + @valid_chars.comma = "," + @valid_chars.COMMA = "<" + @valid_chars.period = "." + @valid_chars.PERIOD = ">" + @valid_chars.slash = "/" + @valid_chars.SLASH = "?" + @cursor + down: () => + super! + @cursor.hidden = false + @text.color = color.am_color.foreground + up: () => + super! + @cursor.hidden = true + @text.color = color.am_color.shadow + update_cursor_pos: () => + @.cursor("translate").x = @cursor_pos * 9 + fire: (e) => + print("cursor pos is", @cursor_pos) + if e.event == "mouse_down" + @down! + if @on + @on(e) + add_key = e.event == "keys_pressed" and @depressed + if add_key + t = @text.text + for key in *e.data + print("analyzing key:",key) + if key == "delete" or key == "backspace" + @cursor_pos -=1 + if @cursor_pos < 0 + @cursor_pos = 0 + t = t\sub(1,@cursor_pos) .. t\sub(@cursor_pos+2) + elseif key == "home" + @cursor_pos = 0 + elseif key == "end" + @cursor_pos = #t + elseif key == "right" + @cursor_pos += 1 + if @cursor_pos > #t + @cursor_pos = #t + elseif key == "left" + @cursor_pos -= 1 + if @cursor_pos < 0 + @cursor_pos = 0 + elseif tonumber(key) and tonumber(key) >= 0 and tonumber(key) <= 9 + kn = tonumber(key) + nd = key + if e.shift + nd = shifted_nums\sub(kn,kn) + @cursor_pos += 1 + t = t\sub(1,@cursor_pos) .. nd .. t\sub(@cursor_pos) + elseif key == "kp_enter" or key == "enter" + if @on + @on(e) + elseif key == "escape" + @up! + else + if e.shift and key\sub(1,3) ~= "kp_" + key = key\upper! + if @valid_chars[key] + @cursor_pos += 1 + t = t\sub(0,@cursor_pos) .. @valid_chars[key] .. t\sub(@cursor_pos) + if #t > @max_chars + t = t\sub(1,@max_chars) + @text.text = t + @update_cursor_pos! + add_key + +Textbox |
