You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							256 lines
						
					
					
						
							8.5 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							256 lines
						
					
					
						
							8.5 KiB
						
					
					
				| 
 | |
| -- text popup in the middle of the screen that dissapates | |
| function gui_alert(message, color, decay_time) | |
|     win.scene:append( | |
|         am.scale(3) ^ am.text(message, color or COLORS.WHITE) | |
|         :action(coroutine.create(function(self) | |
|             am.wait(am.tween(self, decay_time or 1, { color = vec4(0) }, am.ease_in_out)) | |
|             win.scene:remove(self) | |
|         end)) | |
|     ) | |
| end | |
| 
 | |
| local function gui_make_backing_rect( | |
|     position, | |
|     content_width, | |
|     content_height, | |
|     padding | |
| ) | |
|     local half_width = content_width/2 | |
|     local half_height = content_height/2 | |
| 
 | |
|     local x1 = position[1] - half_width - padding | |
|     local y1 = position[2] - half_height - padding | |
|     local x2 = position[1] + half_width + padding | |
|     local y2 = position[2] + half_height + padding | |
| 
 | |
|     return x1, y1, x2, y2 | |
| end | |
| 
 | |
| -- args { | |
| --  position vec2 | |
| --  onclick function | |
| --  padding number | |
| -- | |
| --  min_width number | |
| --  min_height number | |
| -- | |
| --  label string | |
| --  font { | |
| --    color vec4 | |
| --    halign "center" | "left" | "right" | |
| --    valign "center" | "top" | "bottom" | |
| --  } | |
| -- } | |
| function gui_make_button(args) | |
|     local args = args or {} | |
| 
 | |
|     local position = args.position or vec2(0) | |
|     local onclick = args.onclick | |
|     local padding = args.padding or 6 | |
| 
 | |
|     local min_width = args.min_width or 0 | |
|     local min_height = args.min_height or 0 | |
| 
 | |
|     local label = args.label or "" | |
|     local font = args.font or { | |
|         color = vec4(1), | |
|         halign = "center", | |
|         valign = "center" | |
|     } | |
| 
 | |
|     local scene = am.group() | |
| 
 | |
|     local text = am.text(args.label or "", font.color, font.halign, font.valign) | |
|     scene:append(am.translate(args.position) ^ text) | |
| 
 | |
|     local content_width = math.max(min_width, text.width) | |
|     local content_height = math.max(min_height, text.height) | |
| 
 | |
|     local x1, y1, x2, y2 = gui_make_backing_rect(position, content_width, content_height, padding) | |
| 
 | |
|     local back_rect = am.rect(x1 - padding/2, y1, x2, y2 + padding/2, vec4(0, 0, 0, 1)) | |
|     local front_rect = am.rect(x1, y1, x2, y2, vec4(0.4)) | |
|     scene:prepend(front_rect) | |
|     scene:prepend(back_rect) | |
| 
 | |
|     scene:action(function(self) | |
|         if point_in_rect(win:mouse_position(), back_rect) then | |
|             if win:mouse_pressed"left" then | |
|                 front_rect.color = vec4(0.4) | |
| 
 | |
|                 if onclick then | |
|                     onclick() | |
|                 end | |
|             else | |
|                 front_rect.color = vec4(0, 0, 0, 1) | |
|             end | |
|         else | |
|             front_rect.color = vec4(0.4) | |
|         end | |
|     end) | |
| 
 | |
|     return scene | |
| end | |
| 
 | |
| -- args { | |
| --  position vec2 | |
| --  dimensions vec2 | |
| --  max number | |
| --  padding number | |
| --  validate function(string) -> bool | |
| --  onchange function(new_value) -> void | |
| -- } | |
| function gui_make_textfield( | |
|     args | |
| ) | |
|     local args = args or {} | |
|     local position = args.position or vec2(0) | |
|     local dimensions = args.dimensions or vec2(100, 40) | |
|     local validate = args.validate or function(string) return true end | |
|     local width, height = dimensions.x, dimensions.y | |
|     local max = args.max or 10 | |
|     local padding = args.padding or 6 | |
|     local half_width = width/2 | |
|     local half_height = height/2 | |
| 
 | |
|     local x1 = position[1] - half_width - padding | |
|     local y1 = position[2] - half_height - padding | |
|     local x2 = position[1] + half_width + padding | |
|     local y2 = position[2] + half_height + padding | |
| 
 | |
|     local back_rect = am.rect(x1 - padding/2, y1, x2, y2 + padding/2, vec4(0, 0, 0, 1)) | |
|     local front_rect = am.rect(x1, y1, x2, y2, vec4(0.4)) | |
| 
 | |
|     local function blink_cursor(cursor) | |
|         while true do | |
|             am.wait(am.delay(0.4)) | |
|             cursor.color = vec4(0) | |
|             am.wait(am.delay(0.4)) | |
|             cursor.color = vec4(0, 0, 0, 1) | |
|         end | |
|     end | |
| 
 | |
|     local group = am.group{ | |
|         back_rect, | |
|         front_rect, | |
|         am.translate(position + vec2(-width/2 + padding, 0)) ^ am.group( | |
|             am.scale(2) ^ am.text("", vec4(0, 0, 0, 1), "left"), | |
|             (am.translate(0, -8) ^ am.line(vec2(0, 0), vec2(16, 0), 2, vec4(0, 0, 0, 1)):action(coroutine.create(blink_cursor))):tag"cursor" | |
|         ) | |
|     } | |
| 
 | |
|     group"text".text = ""; | |
| 
 | |
|     group:action(function(self) | |
|         local keys = win:keys_pressed() | |
|         if #keys == 0 then return end | |
| 
 | |
|         local chars = {} | |
|         local shift = win:key_down("lshift") or win:key_down("rshift") | |
|         for i,k in pairs(keys) do | |
|             if k:len() == 1 then -- @HACK alphabetical or digit characters | |
|                 if string.match(k, "%a") then | |
|                     if shift then | |
|                         table.insert(chars, k:upper()) | |
|                     else | |
|                         table.insert(chars, k) | |
|                     end | |
|                 elseif string.match(k, "%d") then | |
|                     if shift then | |
|                         if k == "1" then table.insert(chars, "!") | |
|                         elseif k == "2" then table.insert(chars, "@") | |
|                         elseif k == "3" then table.insert(chars, "#") | |
|                         elseif k == "4" then table.insert(chars, "$") | |
|                         elseif k == "5" then table.insert(chars, "%") | |
|                         elseif k == "6" then table.insert(chars, "^") | |
|                         elseif k == "7" then table.insert(chars, "&") | |
|                         elseif k == "8" then table.insert(chars, "*") | |
|                         elseif k == "9" then table.insert(chars, "(") | |
|                         elseif k == "0" then table.insert(chars, ")") | |
|                         end | |
|                     else | |
|                         table.insert(chars, k) | |
|                     end | |
|                 end | |
|             -- begin non-alphabetical/digit | |
|             elseif k == "minus" then | |
|                 if shift then table.insert(chars, "_") | |
|                 else          table.insert(chars, "-") end | |
|             elseif k == "equals" then | |
|                 if shift then table.insert(chars, "=") | |
|                 else          table.insert(chars, "+") end | |
|             elseif k == "leftbracket" then | |
|                 if shift then table.insert(chars, "{") | |
|                 else          table.insert(chars, "[") end | |
|             elseif k == "rightbracket" then | |
|                 if shift then table.insert(chars, "}") | |
|                 else          table.insert(chars, "]") end | |
|             elseif k == "backslash" then | |
|                 if shift then table.insert(chars, "|") | |
|                 else          table.insert(chars, "\\") end | |
|             elseif k == "semicolon" then | |
|                 if shift then table.insert(chars, ":") | |
|                 else          table.insert(chars, ";") end | |
|             elseif k == "quote" then | |
|                 if shift then table.insert(chars, "\"") | |
|                 else          table.insert(chars, "'") end | |
|             elseif k == "backquote" then | |
|                 if shift then table.insert(chars, "~") | |
|                 else          table.insert(chars, "`") end | |
|             elseif k == "comma" then | |
|                 if shift then table.insert(chars, "<") | |
|                 else          table.insert(chars, ",") end | |
|             elseif k == "period" then | |
|                 if shift then table.insert(chars, ">") | |
|                 else          table.insert(chars, ".") end | |
|             elseif k == "slash" then | |
|                 if shift then table.insert(chars, "?") | |
|                 else          table.insert(chars, "/") end | |
| 
 | |
|             -- control characters | |
|             elseif k == "backspace" then | |
|                 -- @NOTE this doesn't preserve the order of chars in the array so if | |
|                 -- someone presses a the key "a" then the backspace key in the same frame, in that order | |
|                 -- the backspace occurs first | |
|                 if self"text".text:len() ~= 0 then | |
|                     self"text".text = self"text".text:sub(1, self"text".text:len() - 1) | |
|                     self"cursor".position2d = self"cursor".position2d - vec2(9 * 2, 0) | |
|                     self"cursor".hidden = false | |
|                 end | |
|             elseif k == "tab" then | |
|                 -- @TODO | |
| 
 | |
|             elseif k == "space" then | |
|                 table.insert(chars, " ") | |
| 
 | |
|             elseif k == "capslock" then | |
|                 -- @TODO | |
|             end | |
|         end | |
| 
 | |
|         for _,c in pairs(chars) do | |
|             if validate(self"text".text .. c) then | |
|                 local len = self"text".text:len() | |
|                 if len <= max then | |
|                     self"text".text = self"text".text .. c | |
|                     self"cursor".position2d = self"cursor".position2d + vec2(9 * 2, 0) | |
|                     if len == max then | |
|                         self"cursor".hidden = true | |
|                     end | |
|                 end | |
|             end | |
|         end | |
|     end) | |
| 
 | |
|     function get_value() | |
|         return group"text".text | |
|     end | |
| 
 | |
|     return group, get_value | |
| end | |
| 
 | |
| function gui_open_modal() | |
| 
 | |
| end | |
| 
 |