From 7f062de6e627ef1ebbf3741aaca74743d67defef Mon Sep 17 00:00:00 2001 From: Ronja Date: Sun, 4 Oct 2020 18:35:12 +0200 Subject: [PATCH] ppl page --- Luxe/assets/names.lx | 4 ++ Luxe/assets/wip/8Cross.image.lx | 3 + Luxe/assets/wip/8Cross.png | 3 + Luxe/assets/wip/8Head.image.lx | 3 + Luxe/assets/wip/8Head.png | 3 + Luxe/blocks/adventures.wren | 5 ++ Luxe/blocks/human/human.wren | 2 +- Luxe/blocks/tooltip.wren | 11 +++- Luxe/blocks/ui/adventure.wren | 103 ++++++++++++++++++++++++++++-- Luxe/blocks/ui/box.wren | 28 ++++++++ Luxe/blocks/ui/compass.wren | 2 +- Luxe/blocks/ui/image_button.wren | 1 + Luxe/blocks/ui/info.wren | 4 +- Luxe/blocks/ui/ui.wren | 12 ++-- Luxe/game.wren | 2 +- Luxe/math/event.wren | 22 +++++++ Luxe/math/observable.wren | 20 +++++- Luxe/math/util.wren | 16 +++++ Luxe/outline/settings.settings.lx | 6 +- 19 files changed, 230 insertions(+), 20 deletions(-) create mode 100644 Luxe/assets/wip/8Cross.image.lx create mode 100644 Luxe/assets/wip/8Cross.png create mode 100644 Luxe/assets/wip/8Head.image.lx create mode 100644 Luxe/assets/wip/8Head.png create mode 100644 Luxe/blocks/ui/box.wren diff --git a/Luxe/assets/names.lx b/Luxe/assets/names.lx index a22d269..db5da8e 100644 --- a/Luxe/assets/names.lx +++ b/Luxe/assets/names.lx @@ -16,4 +16,8 @@ "Mercedes" "Karl" "Lara" + "Bug" + "Sandra" + "Claus" + "Niels" ] \ No newline at end of file diff --git a/Luxe/assets/wip/8Cross.image.lx b/Luxe/assets/wip/8Cross.image.lx new file mode 100644 index 0000000..1106c0b --- /dev/null +++ b/Luxe/assets/wip/8Cross.image.lx @@ -0,0 +1,3 @@ +image = { + source = "assets/wip/8Cross.png" +} \ No newline at end of file diff --git a/Luxe/assets/wip/8Cross.png b/Luxe/assets/wip/8Cross.png new file mode 100644 index 0000000..d777e44 --- /dev/null +++ b/Luxe/assets/wip/8Cross.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be5d8f0d2466495ac5c27c393de3f74ddc1b5192530fc3de190b79233f61ba4d +size 128 diff --git a/Luxe/assets/wip/8Head.image.lx b/Luxe/assets/wip/8Head.image.lx new file mode 100644 index 0000000..27e2127 --- /dev/null +++ b/Luxe/assets/wip/8Head.image.lx @@ -0,0 +1,3 @@ +image = { + source = "assets/wip/8Head.png" +} \ No newline at end of file diff --git a/Luxe/assets/wip/8Head.png b/Luxe/assets/wip/8Head.png new file mode 100644 index 0000000..95d68c0 --- /dev/null +++ b/Luxe/assets/wip/8Head.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0fd33debd0b68b65b3ab8d7fe79f327f09b26b668f82ea90445dac3b672c052 +size 111 diff --git a/Luxe/blocks/adventures.wren b/Luxe/blocks/adventures.wren index 738f08e..789910b 100644 --- a/Luxe/blocks/adventures.wren +++ b/Luxe/blocks/adventures.wren @@ -27,6 +27,11 @@ class Adventures{ discard(){ _planning.value = null } + + set_max_distance(dist){ + _max_distance = dist + planning.emit() + } } class Adventure{ diff --git a/Luxe/blocks/human/human.wren b/Luxe/blocks/human/human.wren index 3c4aa9f..679499e 100644 --- a/Luxe/blocks/human/human.wren +++ b/Luxe/blocks/human/human.wren @@ -111,7 +111,7 @@ class HumanSystem is ModifierSystem { if(Input.mouse_state_pressed(MouseButton.left)){ var game = Globals["Game"] if(_hoverEnt){ //remove if statement to allow clicking away (probably needs extra code to allow ui clicking) - game.Focus.value = _hoverEnt + game.focus.value = _hoverEnt } } } //tick diff --git a/Luxe/blocks/tooltip.wren b/Luxe/blocks/tooltip.wren index 1c85ddf..69380d0 100644 --- a/Luxe/blocks/tooltip.wren +++ b/Luxe/blocks/tooltip.wren @@ -1,6 +1,7 @@ import "luxe: world" for Entity, Text, Transform import "luxe: assets" for Assets import "luxe: render" for Material +import "luxe: math" for Math import "globals" for Globals import "math/vector" for Vector @@ -29,6 +30,8 @@ class Tooltip{ Transform.set_snap(shadow, 1, 1, 0) _shadows.add(shadow) } + _width = 0 + _height = 0 Globals["Tooltip"] = this } @@ -36,6 +39,8 @@ class Tooltip{ tick(){ var pos = Vector.new(Globals["UiMouse"]) if(pos){ + pos.x = Math.clamp(pos.x, 1, Globals["Renderer"].width - _width - 1) + pos.y = Math.clamp(pos.y, 1, Globals["Renderer"].height - _height - 1) if(_x){ pos.x = _x } @@ -76,6 +81,10 @@ class Tooltip{ _source = source _x = null _y = null + + var extents = Text.get_extents(_text) + _width = extents.x + _height = extents.y } clear(){ @@ -84,7 +93,7 @@ class Tooltip{ clear(source){ if(_source != source) return - set("", null) + set("") _active = false } } \ No newline at end of file diff --git a/Luxe/blocks/ui/adventure.wren b/Luxe/blocks/ui/adventure.wren index 6aa8eab..450dbf0 100644 --- a/Luxe/blocks/ui/adventure.wren +++ b/Luxe/blocks/ui/adventure.wren @@ -3,8 +3,11 @@ import "luxe: world" for Entity, Transform, UI, UIRenderMode, UIEvent import "luxe: world" for UILayout, UILayoutBehave, UILayoutContain import "luxe: ui/control" for Control import "luxe: ui/label" for UILabel +import "luxe: ui/image" for UIImage import "luxe: assets" for Assets import "luxe: render" for Material, TextAlign +import "luxe: color" for Color +import "luxe: game" for Frame import "globals" for Globals import "blocks/ui/image_button" for ImageButton @@ -12,8 +15,12 @@ import "math/observable" for Observable import "blocks/ui/simple_text" for UISimpleText import "blocks/ui/ui" for Ui import "blocks/ui/slider" for UiSlider +import "blocks/ui/box" for UiBox import "blocks/ui/compass" for UiCompass +import "blocks/ui/info" for UiInfo //this is a cyclic dependency waiting to happen import "math/math" for M +import "math/util" for Util +import "blocks/human/human" for Human class UiAdventure{ root{_root} @@ -59,15 +66,15 @@ class UiAdventure{ //toolbar icons _ui.list_button(list, [1, 0], "Info") {_ui.ui_mode = Ui.Info} + _ui.list_button(list, [3, 0], "Direction") {_page.value = UiAdventure.direction} + _ui.list_button(list, [2, 0], "People") {_page.value = UiAdventure.people} + _ui.list_button(list, [4, 0], "Stuff") {_page.value = UiAdventure.resources} + _ui.list_button(list, [5, 0], "Depart") {_page.value = UiAdventure.depart} _ui.list_button(list, [0, 0], "Abort") { _ui.ui_mode = Ui.Info _game.adventures.discard() _page.value = UiAdventure.direction } - _ui.list_button(list, [3, 0], "Direction") {_page.value = UiAdventure.direction} - _ui.list_button(list, [2, 0], "People") {_page.value = UiAdventure.people} - _ui.list_button(list, [4, 0], "Stuff") {_page.value = UiAdventure.resources} - _ui.list_button(list, [5, 0], "Depart") {_page.value = UiAdventure.depart} } direction(){ @@ -179,6 +186,94 @@ class UiAdventure{ _page.on_change(true){|val| Control.set_visible(page, val == UiAdventure.people) } + + _game.focus.on_change(true) {|val| + if(!val) return + if(_ui.ui_mode == Ui.Planning && _page.value == UiAdventure.people){ + var adventure = _game.adventures.planning + if(adventure.value && !adventure.value.adventurers.contains(val)) { + adventure.value.adventurers.insert(0, val) + adventure.emit() + } + } + } + + var list = UiBox.create(_ent) + Control.child_add(page, list) + Control.set_clip(list, true) + UILayout.set_contain(_ent, list, UILayoutContain.column | UILayoutContain.start) //| + UILayout.set_behave(_ent, list, UILayoutBehave.fill) + UILayout.set_margin(_ent, list, 40, 0, 0, 0) + + var tiny_head = Assets.image("assets/wip/8Head") + var x_image = Assets.image("assets/wip/8Cross") + + _adventurerListItems = [] + _game.adventures.planning.on_change(true) {|adventure| + //cleanup + _adventurerListItems.each{|item| + Control.destroy(item) + } + _adventurerListItems.clear() + + if(!adventure) return + + //rebuild + adventure.adventurers.each{ |adventurer| + var item = UiBox.create(_ent) + Control.child_add(list, item) + UILayout.set_behave(_ent, item, UILayoutBehave.left | UILayoutBehave.right)//| + 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 + } + } + + var head = UIImage.create(_ent) + Control.child_add(item, head) + Control.set_size(head, 8, 8) + UIImage.set_image(head, tiny_head) + UIImage.set_color(head, Human.get_color(adventurer)) + UILayout.set_margin(_ent, head, 2, 0, 0, 0) + + var name = UILabel.create(_ent) + Control.child_add(item, name) + UILabel.set_align_vertical(name, TextAlign.bottom) + UILabel.set_font(name, _ui.font) + UILabel.set_text_size(name, 8) + UILabel.set_text(name, Human.get_name(adventurer)) + UILayout.set_behave(_ent, name, UILayoutBehave.hfill | UILayoutBehave.left)//| + UILayout.set_margin(_ent, name, 2, 1, 0, 1) + + var remove = ImageButton.create(_ent) + 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) + Util.remove(adventure.adventurers, adventurer) + _game.adventures.planning.emit() + } + } + } + + _adventurerListItems.add(item) + } + UILayout.commit(_ent) + UI.commit(_ent) + } } resources(){ diff --git a/Luxe/blocks/ui/box.wren b/Luxe/blocks/ui/box.wren new file mode 100644 index 0000000..fc03258 --- /dev/null +++ b/Luxe/blocks/ui/box.wren @@ -0,0 +1,28 @@ +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 + +class UiBox{ + + static create(ent){ + var box = Control.create(ent) + var style = PathStyle.new() + style.color = [1,1,1,1] + style.thickness = 1 + Control.set_state_data(box, {"style": style}) + Control.set_render(box) {|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"]) + } + return box + } + +} \ No newline at end of file diff --git a/Luxe/blocks/ui/compass.wren b/Luxe/blocks/ui/compass.wren index cf13392..edde663 100644 --- a/Luxe/blocks/ui/compass.wren +++ b/Luxe/blocks/ui/compass.wren @@ -20,7 +20,7 @@ class UiCompass{ 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 radians between 0 and tau + 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] diff --git a/Luxe/blocks/ui/image_button.wren b/Luxe/blocks/ui/image_button.wren index 481b78f..373ce50 100644 --- a/Luxe/blocks/ui/image_button.wren +++ b/Luxe/blocks/ui/image_button.wren @@ -49,6 +49,7 @@ class ImageButton{ Globals["Tooltip"].clear(button) } } + UI.event_cancel(ent, event.id) } } diff --git a/Luxe/blocks/ui/info.wren b/Luxe/blocks/ui/info.wren index a27174c..1e53689 100644 --- a/Luxe/blocks/ui/info.wren +++ b/Luxe/blocks/ui/info.wren @@ -25,6 +25,8 @@ class UiInfo{ static diary{"diary"} static resources{"resources"} + page{_page} + construct new(ent, ui){ _ent = ent _ui = ui @@ -32,7 +34,7 @@ class UiInfo{ _page = Observable.new(UiInfo.human) _focus = Observable.new() - Globals["Game"].Focus.on_change(true) {|val| + Globals["Game"].focus.on_change(true) {|val| if(ui.ui_mode == Ui.Info){ _focus.value = val if(_page.value == UiInfo.resources){ diff --git a/Luxe/blocks/ui/ui.wren b/Luxe/blocks/ui/ui.wren index 158c33d..caae32b 100644 --- a/Luxe/blocks/ui/ui.wren +++ b/Luxe/blocks/ui/ui.wren @@ -24,6 +24,9 @@ class Ui{ ui_mode{_ui_mode.value} ui_mode=(v){_ui_mode.value = v} + planning{_planning} + info{_info} + construct new(app){ var game = Globals["Game"] var ui_rect = Globals["UiRect"] @@ -34,9 +37,6 @@ class Ui{ UI.create(_ent, ui_rect.x, ui_rect.y, ui_rect.width, ui_rect.height, 0, app.ui_camera) UI.set_render_mode(_ent, UIRenderMode.world) - var solid_mat = Material.create("luxe: material_basis/ui_solid") - var text_mat = Material.create("luxe: material_basis/ui_font") - //var text_mat = Material.create("shaders/pixel_text_ui") UI.set_material_basis(_ent, "luxe: material_basis/ui_solid", "shaders/pixel_text_ui") UILayout.create(_ent) @@ -44,15 +44,11 @@ class Ui{ _info = UiInfo.new(_ent, this) _planning = UiAdventure.new(_ent, this) - _ui_mode.on_change(true) {|val| + _ui_mode.on_change(true) {|val| Control.set_visible(_planning.root, val == Ui.Planning) Control.set_visible(_info.root, val == Ui.Info) UI.commit(_ent) } - - game.Focus.on_change() {|val| - ui_mode = Ui.Info - } UI.commit(_ent) UILayout.commit(_ent) diff --git a/Luxe/game.wren b/Luxe/game.wren index f616051..fdb3549 100644 --- a/Luxe/game.wren +++ b/Luxe/game.wren @@ -101,7 +101,7 @@ class Game is Ready { Human.set_name(human, name) } - Focus{_focus} + focus{_focus} adventures{_adventures} resources{_resources} diff --git a/Luxe/math/event.wren b/Luxe/math/event.wren index 2db3274..77284b5 100644 --- a/Luxe/math/event.wren +++ b/Luxe/math/event.wren @@ -72,4 +72,26 @@ class ListenerToken{ discard(){ event.unlisten(index) } +} + +class MultiListenerToken{ + events{_events} + indices{_indices} + + construct new(tokens){ + _events = [] + _indices = [] + tokens.each{|token| add(token)} + } + + add(token){ + _events.add(token.event) + _indices.add(token.index) + } + + discard(){ + Util.for_all([events, indices]) {|event, index| + event.unlisten(index) + } + } } \ No newline at end of file diff --git a/Luxe/math/observable.wren b/Luxe/math/observable.wren index 4725df3..5c5e2f6 100644 --- a/Luxe/math/observable.wren +++ b/Luxe/math/observable.wren @@ -1,4 +1,5 @@ -import "math/event" for Event +import "math/event" for Event, MultiListenerToken +import "math/util" for Util class Observable{ value{_value} @@ -47,4 +48,21 @@ class Observable{ _event.once(fn) } } + + static any_change(observables, fn){ + var change_method = Fn.new{|whatever| + Util.call_arg_list(fn, observables.map{|observable| observable.value.toList}) + } + var tokens = observables.map{|observable| + return observable.on_change(change_method) + } + return MultiListenerToken.new(tokens) + } + + static any_change(observables, initial, fn){ + if(initial){ + Util.call_arg_list(fn, observables.map{|observable|observable.value}.toList) + } + any_change(observables, fn) + } } \ No newline at end of file diff --git a/Luxe/math/util.wren b/Luxe/math/util.wren index e0dcbb2..71a0bc0 100644 --- a/Luxe/math/util.wren +++ b/Luxe/math/util.wren @@ -21,6 +21,22 @@ class Util{ } } + static index_of(sequence, element){ + var index = -1 + var any = sequence.any{|elem| + index = index + 1 + return elem == element + } + return any ? index : -1 + } + + static remove(list, element){ + var index = index_of(list, element) + if(index < 0) return false + list.removeAt(index) + return true + } + static for_all(sequences, fn){ var count = sequences.count var counter = (0...count) diff --git a/Luxe/outline/settings.settings.lx b/Luxe/outline/settings.settings.lx index b18a5d2..8dc16cf 100644 --- a/Luxe/outline/settings.settings.lx +++ b/Luxe/outline/settings.settings.lx @@ -13,6 +13,8 @@ engine = { stencil = 0 depth = 0 } +} - //ui.debug_vis = true -} \ No newline at end of file +//debug stuff +//engine.ui.debug_vis = true +engine.render.opengl.debug_level = 3 \ No newline at end of file