From 8aa79a4c2d5d62cd00080267ec4cf8cd842a50c9 Mon Sep 17 00:00:00 2001 From: Jeremy Penner Date: Thu, 23 Dec 2021 22:36:20 -0600 Subject: [PATCH] refactor layout API --- editor/gfxedit2.fnl | 13 +++--- editor/imgui.fnl | 71 +++++++++++++----------------- editor/mapedit.fnl | 93 ++++++++++++++++++++-------------------- editor/tileedit/init.fnl | 48 +++++++++++---------- 4 files changed, 109 insertions(+), 116 deletions(-) diff --git a/editor/gfxedit2.fnl b/editor/gfxedit2.fnl index 6ec5ed7..185e8d8 100644 --- a/editor/gfxedit2.fnl +++ b/editor/gfxedit2.fnl @@ -3,7 +3,7 @@ (local tiledraw (require :editor.tiledraw)) (local util (require :lib.util)) (local files (require :game.files)) -(local {: attach-imstate : button : vert : horiz-wrapper : begin-group} (util.require :editor.imgui)) +(local {: attach-imstate : button : reform : horiz-wrapper : group-wrapper} (util.require :editor.imgui)) (local GraphicsEditView (View:extend)) @@ -42,7 +42,7 @@ (fn tile-selector [{: view &as form} selected-itile ?key] (var selected-itile selected-itile) - (let [g (begin-group) + (let [g (group-wrapper form) wrap (horiz-wrapper form)] (for [itile 1 (length view.tilecache.tiles)] (let [{: x : y} form @@ -50,13 +50,14 @@ (when (and w h) (when (= itile selected-itile) (love.graphics.rectangle :line (- x 2) (- y 2) (+ w 4) (+ h 4))) - (when (wrap form #(g button $...) {:tag [:tile itile] : w : h}) - (set selected-itile itile))))) - (g form) + (when (g button (reform form {:tag [:tile itile] : w : h})) + (set selected-itile itile)) + (wrap form)))) + (g) selected-itile)) (fn GraphicsEditView.draw-tile-selector [self form ?key] - (match (vert form tile-selector {:scale self.sprite-scale :w form.w} (when (= self.tilekey ?key) self.itile) ?key) + (match (tile-selector (reform form {:scale self.sprite-scale :w form.w}) (when (= self.tilekey ?key) self.itile) ?key) selected-itile (do (set self.itile selected-itile) (set self.tilekey ?key)))) diff --git a/editor/imgui.fnl b/editor/imgui.fnl index 6e4db70..37bbfed 100644 --- a/editor/imgui.fnl +++ b/editor/imgui.fnl @@ -318,34 +318,18 @@ selection)) (local form-preserved-keys (collect [_ key (ipairs [:view :x :y :font :color :xpad :ypad])] key true)) -(fn prepare-form [form overrides] - (each [key (pairs form)] - (when (= (. form-preserved-keys key) nil) - (tset form key nil))) - (lume.extend form (or overrides {})) - form) +(fn reform [form overrides] + (if (and overrides overrides.into (not= overrides.into form)) + (reform (lume.extend (lume.clear overrides.into) form) overrides) + (do (each [key (pairs form)] + (when (= (. form-preserved-keys key) nil) + (tset form key nil))) + (lume.extend form (or overrides {}))))) -(fn vert [form viewfn overrides ...] - (let [result (if viewfn [(viewfn (prepare-form form overrides) ...)] [])] - (set form.y (+ form.y (or form.h 0) (or form.ypad 0))) - (table.unpack result))) +(fn under [form overrides] (reform form (lume.merge (or overrides {}) {:y (+ form.y (or form.h 0) (or form.ypad 0))}))) +(fn right-of [form overrides] (reform form (lume.merge (or overrides {}) {:x (+ form.x (or form.w 0) (or form.xpad 0))}))) -(fn horiz [form viewfn overrides ...] - (let [result (if viewfn [(viewfn (prepare-form form overrides) ...)] [])] - (set form.x (+ form.x (or form.w 0) (or form.xpad 0))) - (table.unpack result))) - -(fn horiz-wrapper [{: x : w &as form}] - (set form.w nil) - (fn [form viewfn overrides ...] - (let [result [(viewfn (prepare-form form overrides) ...)]] - (set form.x (+ form.x (or form.w 0) (or form.xpad 0))) - (when (> (+ form.x (or form.w 0)) (+ x w)) - (set form.x x) - (set form.y (+ form.y form.h (or form.ypad 0)))) - (table.unpack result)))) - -(fn begin-group [] +(fn group-wrapper [orig-form] (let [group {} update-dimension (fn [form coord-key size-key] @@ -360,23 +344,28 @@ (tset group size-key (- (math.max (+ coord-form size-form) (+ coord-group size-group)) coord-form))) ; extend the size if the new item is outside the bounds to the right / down - (tset group size-key (- (math.max (+ coord-form size-form) (+ coord-group size-group)) coord-group)))))] + (tset group size-key (- (math.max (+ coord-form size-form) (+ coord-group size-group)) coord-group))) + form)) + update-dimensions (fn [form] (update-dimension form :x :w) (update-dimension form :y :h))] - (fn [viewfn-or-form ?form ...] - (if (= (type viewfn-or-form) :function) - (let [result [(viewfn-or-form ?form ...)]] - (update-dimension ?form :x :w) - (update-dimension ?form :y :h) - (table.unpack result)) - (do (set viewfn-or-form.x group.x) - (set viewfn-or-form.y group.y) - (set viewfn-or-form.w group.w) - (set viewfn-or-form.h group.h) - (lume.clear group) - viewfn-or-form))))) + (fn [?viewfn-or-form ?form ...] + (match [(type ?viewfn-or-form) ?viewfn-or-form] + [:function viewfn] (let [result [(viewfn ?form ...)]] + (update-dimensions ?form) + (table.unpack result)) + [:table form] (update-dimensions form) + [:nil] (do (lume.extend orig-form group) + (lume.clear group) + orig-form))))) + +(fn horiz-wrapper [{:x orig-x :w orig-w}] + (fn [{: x : y : w : h : xpad : ypad &as form} overrides] + (if (> (+ x (or w 0) xpad (or w 0)) (+ orig-x orig-w)) + (reform form (lume.merge (or overrides {}) {:x orig-x :y (+ y (or h 0) (or ypad 0))})) + (right-of form overrides)))) {: attach-imstate : cmd-predicate : postpone : mouse-inside : activate : active? : button : checkbox : textbox : textfield : textbutton : dropdown : labelled-dropdown - : vert : horiz : horiz-wrapper : begin-group - : with-style : prepare-form : form-defaults} + : reform : under : right-of : horiz-wrapper : group-wrapper + : with-style : form-defaults} diff --git a/editor/mapedit.fnl b/editor/mapedit.fnl index 960c1be..ec4d9e6 100644 --- a/editor/mapedit.fnl +++ b/editor/mapedit.fnl @@ -3,7 +3,8 @@ (local util (require :lib.util)) (local lume (require :lib.lume)) (local files (require :game.files)) -(local {: mouse-inside : activate : active? : checkbox : textfield : textbutton : textbox : dropdown : labelled-dropdown : vert : horiz : begin-group} (util.require :editor.imgui)) +(local {: show} (util.require :inspector.debug)) +(local {: mouse-inside : activate : active? : checkbox : textfield : textbutton : textbox : dropdown : labelled-dropdown : under : right-of : reform : group-wrapper} (util.require :editor.imgui)) (local {: tilestrip-to-sprite} (util.require :editor.tiledraw)) (local {: encode-yx : encode-itile : decode-itile : dimensions} (util.require :game.tiles)) (local actions (require :editor.actions)) @@ -84,10 +85,10 @@ (set files.game.levels [])) files.game.levels) -(fn MapEditView.draw-map-selector [self {: x : y &as form}] +(fn MapEditView.draw-map-selector [self form] (let [level-count (length (self:levels)) options (icollect [i (util.countiter (+ level-count 1))] (if (<= i level-count) i :New)) - ilevel (vert form labelled-dropdown {:tag :map-selector :wdropdown (* 100 SCALE)} "Map" self.ilevel options)] + ilevel (labelled-dropdown (reform form {:tag :map-selector :wdropdown (* 100 SCALE)}) "Map" self.ilevel options)] (when (not= ilevel self.ilevel) (set self.ilevel (if (= ilevel :New) (+ level-count 1) ilevel)) (self:load-level)))) @@ -99,7 +100,7 @@ (fn MapEditView.draw-layer-selector [self {: x : y &as form}] (let [mkopt (fn [ilayer] {: ilayer :label (.. ilayer " (" (self:layer-type ilayer) ")")}) options (icollect [ilayer (ipairs (platform :layers))] (mkopt ilayer)) - selection (vert form labelled-dropdown {:wdropdown (* 100 SCALE) :tag :layer-selector} "Layer" (mkopt self.ilayer) options)] + selection (labelled-dropdown (reform form {:wdropdown (* 100 SCALE) :tag :layer-selector}) "Layer" (mkopt self.ilayer) options)] (when (not= self.ilayer selection.ilayer) (self:set-ilayer selection.ilayer)))) @@ -164,22 +165,23 @@ (when (and (active? self :map) (mouse-inside x y w h)) (let [iobject (self:iobject-from-xy mx my)] (match self.imstate.left - :pressed (set self.iobject-linking iobject) + :down (when (= self.iobject-linking nil) (set self.iobject-linking iobject)) :released - (if (and (not= iobject nil) (= self.iobject-linking iobject)) - (set self.iobject iobject) + (do (if (and (not= iobject nil) (= self.iobject-linking iobject)) + (set self.iobject iobject) - (not= self.iobject-linking nil) - (tset (self:linking-obj) :link iobject) + (not= self.iobject-linking nil) + (tset (self:linking-obj) :link iobject) - (not= self.playerpos nil) - (do (tset self.level self.playerpos {:x mx :y my}) - (set self.playerpos nil)) + (not= self.playerpos nil) + (do (tset self.level self.playerpos {:x mx :y my}) + (set self.playerpos nil)) - (= iobject nil) - (let [tile (self.tilecache:tile (self:itile-from-xy mx my))] - (table.insert self.level.objects {:x mx :y my :func (or tile.word "")}) - (set self.iobject (length self.level.objects)))))))) + (= iobject nil) + (let [tile (self.tilecache:tile (self:itile-from-xy mx my))] + (table.insert self.level.objects {:x mx :y my :func (or tile.word "")}) + (set self.iobject (length self.level.objects)))) + (set self.iobject-linking nil)))))) (fn MapEditView.handle-mouseedits-tile [self mx my x y w h] (when (and (active? self :map) (mouse-inside x y w h) (not= (self:itile-from-xy mx my) self.itile)) @@ -214,8 +216,7 @@ (when (mouse-inside tilex intiley tilew intileh) (when (not= iobject nil) (set iobject-over iobject)) (self:draw-tile-xy-label mx my tilex intiley tileh ystagger)))) - (when (= self.itile nil) (self:draw-link-lines form iobject-over)) - (vert form)) + (when (= self.itile nil) (self:draw-link-lines form iobject-over))) (fn condition-label [flag] (if flag {:label flag : flag} {:label ""})) @@ -230,13 +231,13 @@ (var istep-to-delete nil) (when (not object.steps) (set object.steps [])) (each [istep step (ipairs object.steps)] - (when (textbutton (lume.merge form {:x (+ form.x (* 280 SCALE))}) "X") + (when (textbutton (reform form {:x (+ form.x (* 280 SCALE))}) "X") (set istep-to-delete istep)) - (set step.condition (. (dropdown (lume.merge form {:x (+ form.x (* 100 SCALE)) :w (* 100 SCALE) :tag [:code-condition istep]}) (condition-label step.condition) (condition-options)) :flag)) - (set step.action (vert form dropdown {:w (* 100 SCALE) :tag [:code-action istep]} (or step.action (. actions.actionlist 1)) actions.actionlist)) - (vert form actions.edit {:w (* 300 SCALE)} istep)) + (set step.condition (. (dropdown (reform form {:x (+ form.x (* 100 SCALE)) :w (* 100 SCALE) :tag [:code-condition istep]}) (condition-label step.condition) (condition-options)) :flag)) + (set step.action (dropdown (under form {:w (* 100 SCALE) :tag [:code-action istep]}) (or step.action (. actions.actionlist 1)) actions.actionlist)) + (actions.edit (under form {:w (* 300 SCALE)}) istep)) (when istep-to-delete (table.remove object.steps istep-to-delete)) - (when (vert form textbutton {} "+ New Step") + (when (textbutton (under form) "+ New Step") (table.insert object.steps {}))) (fn advanced? [object] @@ -247,33 +248,33 @@ (fn MapEditView.draw-object-advanced-editor [self form object] (let [fieldform {:wlabel (* 100 SCALE) :wtext (* 200 SCALE)}] - (set object.func (vert form textfield fieldform "Word" object.func)) - (set object.name (vert form textfield fieldform "Name" object.name)) - (set object.linkword (vert form textfield fieldform "Link word" object.linkword)) + (set object.func (textfield (reform form fieldform) "Word" object.func)) + (set object.name (textfield (under form fieldform) "Name" object.name)) + (set object.linkword (textfield (under form fieldform) "Link word" object.linkword)) (if object.link - (when (vert form textbutton {} "Unlink") + (when (textbutton (under form) "Unlink") (set object.link nil)) - (set object.linkentity (vert form textfield fieldform "Link entity" object.linkentity))))) + (set object.linkentity (textfield (under form fieldform) "Link entity" object.linkentity))))) (fn MapEditView.draw-object-editor [self form] (let [object (self:object) - footer (begin-group)] + footer (group-wrapper form)] (if (advanced? object) (self:draw-object-advanced-editor form object) (self:draw-object-code-editor form object)) - (set self.new-flag-name (horiz form #(footer textbox $...) {:tag :new-flag-name :w (* 200 SCALE)} self.new-flag-name)) - (when (horiz form #(footer textbutton $...) {} "+ New Flag") + (set self.new-flag-name (footer textbox (under form {:tag :new-flag-name :w (* 200 SCALE)}) self.new-flag-name)) + + (when (footer textbutton (right-of form) "+ New Flag") (when (= files.game.flags nil) (set files.game.flags [])) (table.insert files.game.flags self.new-flag-name) (set self.new-flag-name "")) - (vert (footer form)) - (when (horiz form #(footer textbutton $...) {} "Delete") + (when (footer textbutton (under (footer)) "Delete") (move-object self.level.objects (+ self.iobject 1) self.iobject) (set self.iobject nil)) - (when (horiz form #(footer textbutton $...) {} (if (advanced? object) "Simple" "Advanced")) + (when (footer textbutton (right-of form) (if (advanced? object) "Simple" "Advanced")) (set object.advanced (not (advanced? object)))) - (vert (footer form)))) + (footer))) (fn MapEditView.load-level [self] (set self.stripcache {}) @@ -291,28 +292,28 @@ (self:draw_scrollbar) (let [form (self:form) form-editor (self:form) - header (begin-group) - _ (self:draw-map-selector form header) - _ (when (platform :layers) (self:draw-layer-selector form header)) - _ (self:draw-map-editor form) + header (group-wrapper form) + _ (header #(self:draw-map-selector $...) form) + _ (when (platform :layers) (header #(self:draw-layer-selector $...) (right-of form))) + _ (self:draw-map-editor (under (header))) editor-on-side (> self.size.x (+ form.w (* 300 SCALE))) fieldform {:wlabel (* 100 SCALE) :wtext (* 200 SCALE)}] (when editor-on-side (set form-editor.x (+ form.x form.w style.padding.x)) (set form-editor.w (- form-editor.w form.w style.padding.x))) - (self:draw-tile-selector (lume.extend form {:w (if editor-on-side form.w (- self.size.x (* style.padding.x 2)))})) - (set self.level.tickword (vert form textfield fieldform "Tick word" self.level.tickword)) - (set self.level.moveword (vert form textfield fieldform "Move word" self.level.moveword)) - (set self.level.loadword (vert form textfield fieldform "Load word" self.level.loadword)) - (when (vert form checkbox {} "Edit objects" (= self.itile nil)) + (self:draw-tile-selector (under form {:w (if editor-on-side form.w (- self.size.x (* style.padding.x 2)))})) + (set self.level.tickword (textfield (under form fieldform) "Tick word" self.level.tickword)) + (set self.level.moveword (textfield (under form fieldform) "Move word" self.level.moveword)) + (set self.level.loadword (textfield (under form fieldform) "Load word" self.level.loadword)) + (when (checkbox (under form) "Edit objects" (= self.itile nil)) (set self.itile nil) (set self.playerpos nil)) (each [_ player (ipairs (or files.game.players [:player]))] - (when (vert form checkbox {} (.. "Position " player) (and (= self.itile nil) (= self.playerpos player))) + (when (checkbox (under form) (.. "Position " player) (and (= self.itile nil) (= self.playerpos player))) (set self.itile nil) (set self.playerpos player))) (each [_ levelflag (ipairs (or files.game.levelflags []))] - (when (vert form checkbox {} levelflag (. self.level levelflag)) + (when (checkbox (under form) levelflag (. self.level levelflag)) (tset self.level levelflag (not (. self.level levelflag))))) (when (not editor-on-side) (set form-editor.y (+ form.y form.h style.padding.y))) (when self.iobject (self:draw-object-editor form-editor)) diff --git a/editor/tileedit/init.fnl b/editor/tileedit/init.fnl index 655ea85..a7c4470 100644 --- a/editor/tileedit/init.fnl +++ b/editor/tileedit/init.fnl @@ -4,8 +4,9 @@ (local files (require :game.files)) (local util (require :lib.util)) (local lume (require :lib.lume)) -(local {: mouse-inside : activate : active? : checkbox : textfield : button : dropdown : with-style : form-defaults - : vert : horiz-wrapper : begin-group} (util.require :editor.imgui)) +(local {: show} (util.require :inspector.debug)) +(local {: mouse-inside : activate : active? : checkbox : textfield : button : dropdown : with-style + : under : right-of : reform : horiz-wrapper : group-wrapper} (util.require :editor.imgui)) (local TileView (GraphicsEditView:extend)) @@ -69,7 +70,7 @@ (self:update-tile (set-tile-bits tile ibyte ibit mask bits)))))) (love.graphics.setColor 1 1 1 1)) -(fn TileView.draw-tile-editor [self form tile] (vert form tile-editor {} tile)) +(fn TileView.draw-tile-editor [self form tile] (tile-editor form tile)) (fn tile-flag [form tile flagname] (local flagset (?. tile :flags flagname)) @@ -77,13 +78,13 @@ (tset tile :flags flagname (if flagset nil true)))) (fn TileView.draw-tile-flags [self form] - (let [tile (-?> self.tilecache.tiles (. self.itile)) - fieldform {:wlabel (* 100 SCALE) :wtext (* 200 SCALE)}] + (let [tile (-?> self.tilecache.tiles (. self.itile)) + fieldform {:wlabel (* 100 SCALE) :wtext (* 200 SCALE)}] (when tile - (set tile.word (vert form textfield fieldform "Default word" tile.word)) - (set tile.label (vert form textfield fieldform "Label" tile.label))) + (set tile.word (textfield (reform form fieldform) "Default word" tile.word)) + (set tile.label (textfield (under form fieldform) "Label" tile.label))) (each [iflag flagname (ipairs (tiles.flags))] - (vert form tile-flag {} tile flagname)))) + (tile-flag (under form) tile flagname)))) (fn tile-preview [{:view self : x : y &as form} itile tilekey] (each [_ [tx ty] (ipairs (self:preview-locations))] @@ -91,25 +92,26 @@ (w h) (self:draw-sprite (+ x dx) (+ y dy) itile tilekey)] (when (and w (or (= form.w nil) (< form.w (+ w dx)))) (set form.w (+ w dx))) (when (and h (or (= form.h nil) (< form.h (+ h dy)))) (set form.h (+ h dy)))))) -(fn TileView.draw-tile-preview [self form] (vert form tile-preview {} self.itile self.tilekey)) +(fn TileView.draw-tile-preview [self form] (tile-preview form self.itile self.tilekey)) (fn tile-palette [{:view self : x : y : w &as form} pal selected-color] - (let [g (begin-group) - wrap (horiz-wrapper (with-style form))] + (let [g (group-wrapper (with-style form)) + wrap (horiz-wrapper form)] (var selected-color selected-color) (each [icolor color (ipairs pal)] (renderer.draw_rect form.x form.y pixel-size pixel-size color) (when (= icolor selected-color) (love.graphics.setColor 1 1 1 1) (love.graphics.rectangle :line (- form.x 2) (- form.y 2) (+ pixel-size 4) (+ pixel-size 4))) - (when (wrap form #(g button $...) {:tag [:pal icolor] :w pixel-size :h pixel-size}) - (set selected-color icolor))) - (g form) + (when (g button (reform form {:tag [:pal icolor] :w pixel-size :h pixel-size})) + (set selected-color icolor)) + (wrap form)) + (g) selected-color)) (fn TileView.draw-tile-palette [self form] (match (self:palette) - pal (set self.icolor (vert form tile-palette {:w form.w} pal self.icolor)))) + pal (set self.icolor (tile-palette form pal self.icolor)))) (fn TileView.update-tile [self newtile] (self.tilecache:update-tile self.itile newtile self.tilekey)) @@ -124,27 +126,27 @@ (when (not= current-style selection) selection))) (fn TileView.draw-style-selector [self form] - (match (vert form style-selector {} self.style) + (match (style-selector form self.style) new-style (self:set-style new-style))) (fn TileView.draw [self] (self:draw_background style.background) (self:draw_scrollbar) (let [form (self:form) - form-side (self:form)] + form-side (self:form) + full-width {:w form.w}] (self:draw-tile-editor form (self:tile)) ; layout sidebar - (set form-side.x (+ form.x form.w form.xpad)) - (self:draw-tile-flags form-side) - (self:draw-tile-preview form-side) + (self:draw-tile-flags (right-of form {:into form-side})) + (self:draw-tile-preview (under form-side)) ; continue laying out under tile editor - (self:draw-tile-palette (lume.extend form {:w (- self.size.x 20)})) + (self:draw-tile-palette (under form full-width)) (when (> (length (tiles.tile-styles)) 1) - (self:draw-style-selector form)) + (self:draw-style-selector (under form))) (each [_ key (ipairs (self:tilekeys))] - (self:draw-tile-selector (lume.extend form {:w (- self.size.x 20)}) key)) + (self:draw-tile-selector (under form full-width) key)) (self:end-scroll form))) (fn TileView.initial-style [self] :tiles)