refactor layout API

This commit is contained in:
Jeremy Penner 2021-12-23 22:36:20 -06:00
parent a9b54cc890
commit 8aa79a4c2d
4 changed files with 109 additions and 116 deletions

View file

@ -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))))

View file

@ -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}

View file

@ -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 "<always>"}))
@ -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))

View file

@ -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)