diff --git a/Luxe/assets/names.lx b/Luxe/assets/names.lx index 22e3779..35e41d4 100644 --- a/Luxe/assets/names.lx +++ b/Luxe/assets/names.lx @@ -3,6 +3,8 @@ //make groups based on origin culture / meaning //probably better to do when I have a procgen text engine + "Abyole" + "Afua" "Amelia" "Bertine" "Bob" @@ -14,10 +16,14 @@ "Duck" "Elliott" "Freya" + "Gidado" "Ida" "Innes" + "Irene" + "Isisa" "Jess" "Jules" + "Kabanga" "Karl" "Karo" "Lara" @@ -29,6 +35,7 @@ "Mara" "Mercedes" "Merryl" + "Mii’a" "Niels" "Nina" "Rami" @@ -38,10 +45,12 @@ "Ronja" "Sandra" "Simon" + "Sironka" "Steve" "Sven" "Sy" "Ty" "Wocky" + "X!abbu" "Zoe" ] \ No newline at end of file diff --git a/Luxe/blocks/ui/adventure.wren b/Luxe/blocks/ui/adventure.wren index 78227da..7979d8c 100644 --- a/Luxe/blocks/ui/adventure.wren +++ b/Luxe/blocks/ui/adventure.wren @@ -11,7 +11,8 @@ import "luxe: game" for Frame import "luxe: containers" for Lists import "globals" for Globals -import "blocks/ui/image_button" for ImageButton +import "blocks/ui/clickable" for Clickable +import "blocks/ui/image_util" for UiImageUtil import "math/observable" for Observable import "blocks/ui/simple_text" for UISimpleText import "blocks/ui/ui" for Ui @@ -121,7 +122,7 @@ class UiAdventure{ Control.set_events(compass){|event| if(event.type == UIEvent.change){ var angle = event.change - var angleIndex = M.repeat(-(steps * angle / 360).round, steps) + var angleIndex = M.mod(-(steps * angle / 360).round, steps) var adventure = _game.adventures.planning adventure.value.direction = angleIndex adventure.emit() @@ -226,16 +227,12 @@ class UiAdventure{ UILayout.set_margin(_ent, item, 0, 0, 0, 0) UILayout.set_contain(_ent, item, UILayoutContain.row | UILayoutContain.start)//| Control.set_size(item, -1, 12) - Control.set_allow_input(item, true) Control.set_id(item, "Person %(i) : %(Human.get_name(adventurer))") - Control.set_events(item) {|event| - if(UI.event_cancelled(_ent, event.id)) return - if(!Util.valid_event(event)) return - if(event.type == UIEvent.press){ - _ui.ui_mode = Ui.Info - _ui.info.page.value = UiInfo.human - _game.focus.value = adventurer - } + Clickable.make_clickable(item) + Clickable.set_on_click(item) { + _ui.ui_mode = Ui.Info + _ui.info.page.value = UiInfo.human + _game.focus.value = adventurer } UiScrollBox.add(list, item) @@ -255,20 +252,19 @@ class UiAdventure{ UILayout.set_behave(_ent, name, UILayoutBehave.hfill | UILayoutBehave.left)//| UILayout.set_margin(_ent, name, 2, 1, 0, 1) - var remove = ImageButton.create(_ent) + var remove = UIImage.create(_ent) + Clickable.make_clickable(remove) Control.child_add(item, remove) Control.set_size(remove, 8, 8) UIImage.set_image(remove, x_image) UIImage.set_color(remove, Color.hex(0xec172a)) UILayout.set_margin(_ent, remove, 0, 0, 2, 0) - ImageButton.set_tooltip(remove, "remove") - ImageButton.set_state_change(remove) { |data, button| - if(data["press"]){ - Frame.end{ - Globals["Tooltip"].clear(button) - Lists.remove(adventure.adventurers, adventurer) - _game.adventures.planning.emit() - } + Clickable.set_tooltip(remove, "remove") + Clickable.set_on_click(remove) { + Frame.end{ + Globals["Tooltip"].clear(remove) + Lists.remove(adventure.adventurers, adventurer) + _game.adventures.planning.emit() } } @@ -315,14 +311,11 @@ class UiAdventure{ UILayout.set_margin(_ent, item, 0, 0, 0, 0) UILayout.set_contain(_ent, item, UILayoutContain.row | UILayoutContain.start)//| Control.set_size(item, -1, 12) - Control.set_allow_input(item, true) - Control.set_events(item) {|event| - if(UI.event_cancelled(_ent, event.id)) return - if(event.type == UIEvent.press){ - _ui.ui_mode = Ui.Info - _ui.info.page.value = UiInfo.human - _game.focus.value = adventurer - } + Clickable.make_clickable(item) + Clickable.set_on_click(item) { + _ui.ui_mode = Ui.Info + _ui.info.page.value = UiInfo.human + _game.focus.value = adventurer } UiScrollBox.add(list, item) @@ -342,20 +335,19 @@ class UiAdventure{ UILayout.set_behave(_ent, name, UILayoutBehave.hfill | UILayoutBehave.left)//| UILayout.set_margin(_ent, name, 2, 1, 0, 1) - var remove = ImageButton.create(_ent) + var remove = UIImage.create(_ent) + Clickable.make_clickable(remove) Control.child_add(item, remove) Control.set_size(remove, 8, 8) UIImage.set_image(remove, x_image) UIImage.set_color(remove, Color.hex(0xec172a)) UILayout.set_margin(_ent, remove, 0, 0, 2, 0) - ImageButton.set_tooltip(remove, "remove") - ImageButton.set_state_change(remove) { |data, button| - if(data["press"]){ - Frame.end{ - Globals["Tooltip"].clear(button) - Lists.remove(adventure.adventurers, adventurer) - _game.adventures.planning.emit() - } + Clickable.set_tooltip(remove, "remove") + Clickable.set_on_click(remove) { + Frame.end{ + Globals["Tooltip"].clear(remove) + Lists.remove(adventure.adventurers, adventurer) + _game.adventures.planning.emit() } } diff --git a/Luxe/blocks/ui/clickable.wren b/Luxe/blocks/ui/clickable.wren new file mode 100644 index 0000000..74e605c --- /dev/null +++ b/Luxe/blocks/ui/clickable.wren @@ -0,0 +1,123 @@ +import "luxe: ui/image" for UIImage +import "luxe: world" for UIEvent, UI +import "luxe: ui/control" for Control +import "luxe: settings" for Settings +import "luxe: io" for IO +import "luxe: math" for Math + +import "globals" for Globals +import "math/util" for Util + +class Clickable{ + static make_clickable(button){ + var ent = Control.get_entity(button) + var data = Control.get_state_data(button) + if(data == null) data = {} + var newData = { + "hover": false, + "press": false, + "state_change": null, + "tooltip": null, + "allow_cancelled": false, + "click_time": Settings.get("game.ui.button.click_time", 10), + "click_area": Settings.get("game.ui.button.click_area", 2), + "on_click": null, + "press_time": -1, + "press_location": [0, 0], + } + newData.each{|val| + if(data.containsKey(val.key)) System.print("[warning] overriding key %(val.key)") + data[val.key] = val.value + } + Control.set_state_data(button, data) + Control.set_allow_input(button, true) + + Control.set_events(button) {|event| + var data = Control.get_state_data(button) + if(!Util.valid_event(event, data["allow_cancelled"])) return + var changed = false + if(event.type == UIEvent.enter){ + changed = true + data["hover"] = true + } else if(event.type == UIEvent.exit) { + changed = true + data["hover"] = false + data["press"] = false + } else if(event.type == UIEvent.press) { + changed = true + data["press"] = true + if(data["click_time"] < 0){ + if(data["on_click"])data["on_click"].call() //you are valid, you are loved, you have been clicked + } else { + data["press_time"] = IO.timestamp() + data["press_location"] = [event.x, event.y] + } + } else if(event.type == UIEvent.release) { + changed = true + data["press"] = false + + var press_time = data["press_time"] + var click_time = data["click_time"] + if(click_time >= 0 && press_time >= 0 && + press_time + click_time >= IO.timestamp()){ + if(data["on_click"])data["on_click"].call() + } + } else if(event.type == UIEvent.move) { + var press_location = data["press_location"] + //if mouse moved too much + if(Math.length(press_location.x - event.x, press_location.y - event.y) > data["click_area"]) { + //abort click + data["press_time"] = -1 + } + } + + if(changed){ + //System.print(UIEvent.name(string_type) + " " + data["tooltip"]) + var func = data["state_change"] + if(func){ + func.call(data, button) + } + var tooltip = data["tooltip"] + if(tooltip){ + if(data["hover"]) { + Globals["Tooltip"].set(tooltip, button) + //this only works when the UI is at the very bottom + //which it is so whatever :) + Globals["Tooltip"].fix_y(Globals["UiRect"].height-Control.get_pos_y_abs(button)) + } else { + Globals["Tooltip"].clear(button) + } + } + UI.event_cancel(ent, event.id) + } + + } + + return button + } + + static set_tooltip(control, tooltip){ + var data = Control.get_state_data(control) + data["tooltip"] = tooltip + } + + static set_allow_cancelled(control, allow){ + var data = Control.get_state_data(control) + data["allow_cancelled"] = allow + } + + static set_state_change(control, fn){ + var data = Control.get_state_data(control) + data["state_change"] = fn + } + + static set_on_click(control, fn){ + var data = Control.get_state_data(control) + data["on_click"] = fn + } + + static get_data(control){ + return Control.get_state_data(control) + } +} + diff --git a/Luxe/blocks/ui/image_button.wren b/Luxe/blocks/ui/image_button.wren deleted file mode 100644 index c78f13a..0000000 --- a/Luxe/blocks/ui/image_button.wren +++ /dev/null @@ -1,80 +0,0 @@ -import "luxe: ui/image" for UIImage -import "luxe: world" for UIEvent, UI -import "luxe: ui/control" for Control - -import "globals" for Globals -import "math/util" for Util - -class ImageButton{ - static create(ent){ - var button = UIImage.create(ent) - var data = { - "hover": false, - "press": false, - "state_change": null, - "tooltip": null - } - Control.set_state_data(button, data) - - Control.set_events(button) {|event| - if(!Util.valid_event(event)) return - if(UI.event_cancelled(ent, event.id)) return - var data = null - if(event.type == UIEvent.enter){ - data = Control.get_state_data(button) - data["hover"] = true - } else if(event.type == UIEvent.exit) { - data = Control.get_state_data(button) - data["hover"] = false - data["press"] = false - } else if(event.type == UIEvent.press) { - data = Control.get_state_data(button) - data["press"] = true - } else if(event.type == UIEvent.release) { - data = Control.get_state_data(button) - data["press"] = false - } - - if(data){ - //System.print(UIEvent.name(string_type) + " " + data["tooltip"]) - var func = data["state_change"] - if(func){ - func.call(data, button) - } - var tooltip = data["tooltip"] - if(tooltip){ - if(data["hover"]) { - Globals["Tooltip"].set(tooltip, button) - //this only works when the UI is at the very bottom - //which it is so whatever :) - Globals["Tooltip"].fix_y(Globals["UiRect"].height-Control.get_pos_y_abs(button)) - } else { - Globals["Tooltip"].clear(button) - } - } - UI.event_cancel(ent, event.id) - } - } - - return button - } - - static set_tooltip(control, tooltip){ - var data = Control.get_state_data(control) - data["tooltip"] = tooltip - } - - static set_state_change(control, fn){ - var data = Control.get_state_data(control) - data["state_change"] = fn - } - - static get_data(control){ - //System.print(Control.get_state_data(control)) - } - - static set_tile_uv(control, tiles, index){ - UIImage.set_uv(control, index.x/tiles.x, index.y/tiles.y, (index.x+1)/tiles.x, (index.y+1)/tiles.y) - } -} - diff --git a/Luxe/blocks/ui/image_util.wren b/Luxe/blocks/ui/image_util.wren new file mode 100644 index 0000000..041786c --- /dev/null +++ b/Luxe/blocks/ui/image_util.wren @@ -0,0 +1,7 @@ +import "luxe: ui/image" for UIImage + +class UiImageUtil{ + static set_tile_uv(control, tiles, index){ + UIImage.set_uv(control, index.x/tiles.x, index.y/tiles.y, (index.x+1)/tiles.x, (index.y+1)/tiles.y) + } +} \ No newline at end of file diff --git a/Luxe/blocks/ui/info.wren b/Luxe/blocks/ui/info.wren index 1e53689..6e6c384 100644 --- a/Luxe/blocks/ui/info.wren +++ b/Luxe/blocks/ui/info.wren @@ -11,7 +11,8 @@ import "luxe: ui/text" for UIText import "luxe: render" for Material import "globals" for Globals -import "blocks/ui/image_button" for ImageButton +import "blocks/ui/clickable" for Clickable +import "blocks/ui/image_util" for UiImageUtil import "math/observable" for Observable import "math/stringUtil" for StringUtil import "blocks/ui/simple_text" for UISimpleText diff --git a/Luxe/blocks/ui/scroll_box.wren b/Luxe/blocks/ui/scroll_box.wren index 4ddad1c..c562029 100644 --- a/Luxe/blocks/ui/scroll_box.wren +++ b/Luxe/blocks/ui/scroll_box.wren @@ -53,7 +53,7 @@ class UiScrollBox{ UILayout.set_contain(ent, childContainer, UILayoutContain.column | UILayoutContain.start) //| Control.set_allow_input(childContainer, true) Control.set_events(childContainer){ |event| - if(!Util.valid_event(event)) return + if(!Util.valid_event(event, true)) return if(event.type == UIEvent.press) { Control.set_state_data(childContainer, true) UI.capture(childContainer) diff --git a/Luxe/blocks/ui/ui.wren b/Luxe/blocks/ui/ui.wren index 09441c6..3a1d323 100644 --- a/Luxe/blocks/ui/ui.wren +++ b/Luxe/blocks/ui/ui.wren @@ -11,7 +11,8 @@ import "luxe: ui/text" for UIText import "luxe: render" for Material import "globals" for Globals -import "blocks/ui/image_button" for ImageButton +import "blocks/ui/clickable" for Clickable +import "blocks/ui/image_util" for UiImageUtil import "math/observable" for Observable import "blocks/ui/simple_text" for UISimpleText @@ -56,7 +57,8 @@ class Ui{ } list_button(parent){ - var button = ImageButton.create(_ent) + var button = UIImage.create(_ent) + Clickable.make_clickable(button) Control.set_size(button, 16, 16) Control.child_add(parent, button) var adventureButtons = Assets.image("assets/wip/AdventureButtons") @@ -68,22 +70,20 @@ class Ui{ var tiles = [10, 1] var button = list_button(parent) - ImageButton.set_tile_uv(button, tiles, tile) + UiImageUtil.set_tile_uv(button, tiles, tile) return button } list_button(parent, tile, tooltip){ var button = list_button(parent, tile) - ImageButton.set_tooltip(button, tooltip) + Clickable.set_tooltip(button, tooltip) return button } list_button(parent, tile, tooltip, pressFn){ var button = list_button(parent, tile, tooltip) - ImageButton.set_state_change(button) { |data| - if(data["press"]){ - pressFn.call() - } + Clickable.set_on_click(button) { + pressFn.call() } return button } diff --git a/Luxe/math/math.wren b/Luxe/math/math.wren index 1f6f290..c8624f0 100644 --- a/Luxe/math/math.wren +++ b/Luxe/math/math.wren @@ -52,11 +52,14 @@ class M{ return result } - static repeat(number, min, max){ - return min + repeat(number, max - min) + //not remainder!! + //this is the cool modulo + //the one that can deal with negative numbers not badly + static mod(number, min, max){ + return min + mod(number, max - min) } - static repeat(number, max){ + static mod(number, max){ return max.sign * ((number % max + max) % max) } diff --git a/Luxe/math/rect.wren b/Luxe/math/rect.wren index b495313..5463159 100644 --- a/Luxe/math/rect.wren +++ b/Luxe/math/rect.wren @@ -1,4 +1,5 @@ import "math/vector" for Vector +//import M at end of file class AABB{ x{_x} diff --git a/Luxe/math/util.wren b/Luxe/math/util.wren index eb74a50..8548f61 100644 --- a/Luxe/math/util.wren +++ b/Luxe/math/util.wren @@ -69,9 +69,13 @@ class Util{ } static valid_event(event){ + return valid_event(event, false) + } + + static valid_event(event, allow_cancelled){ //cancelled events are not valid :V var entity = Control.get_entity(event.control) - if(UI.event_cancelled(entity, event.id)) return false + if(!allow_cancelled && UI.event_cancelled(entity, event.id)) return false //events without a position are always valid if(![UIEvent.press, UIEvent.release, UIEvent.move].contains(event.type)) return true diff --git a/Luxe/outline/settings.settings.lx b/Luxe/outline/settings.settings.lx index 8dc16cf..ac44b4e 100644 --- a/Luxe/outline/settings.settings.lx +++ b/Luxe/outline/settings.settings.lx @@ -13,8 +13,15 @@ engine = { stencil = 0 depth = 0 } + + + //debug stuff + //ui.debug_vis = true + render.opengl.debug_level = 3 } -//debug stuff -//engine.ui.debug_vis = true -engine.render.opengl.debug_level = 3 \ No newline at end of file +game = { + ui = { + button.click_time = 2 + } +} \ No newline at end of file diff --git a/Luxe/project.modules.lx b/Luxe/project.modules.lx index 567dfa2..c9ffc35 100644 --- a/Luxe/project.modules.lx +++ b/Luxe/project.modules.lx @@ -1,3 +1,3 @@ modules = { - luxe = "2020.3.0" + luxe = "2020.3.1" } //modules