rewrite imgui, tile editor
This commit is contained in:
parent
d070e8adb0
commit
f81dd88a52
69
editor/gfxedit2.fnl
Normal file
69
editor/gfxedit2.fnl
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
(local View (require :core.view))
|
||||||
|
(local tiles (require :game.tiles))
|
||||||
|
(local tiledraw (require :editor.tiledraw))
|
||||||
|
(local util (require :lib.util))
|
||||||
|
(local files (require :game.files))
|
||||||
|
(local {: attach-imstate : button : vert} (util.require :editor.imgui))
|
||||||
|
|
||||||
|
(local GraphicsEditView (View:extend))
|
||||||
|
|
||||||
|
(local sprite-scale 4)
|
||||||
|
(set GraphicsEditView.sprite-scale sprite-scale)
|
||||||
|
|
||||||
|
(fn GraphicsEditView.new [self]
|
||||||
|
(GraphicsEditView.super.new self)
|
||||||
|
(self:set-style (self:initial-style))
|
||||||
|
(set self.scrollheight math.huge)
|
||||||
|
(set self.scrollable true)
|
||||||
|
(attach-imstate self))
|
||||||
|
(fn GraphicsEditView.get_scrollable_size [self] self.scrollheight)
|
||||||
|
(fn GraphicsEditView.initial-style [self] :tiles)
|
||||||
|
(fn GraphicsEditView.tilesize [self]
|
||||||
|
(let [style (tiles.style self.style)]
|
||||||
|
(values (or style.editw style.tilew) (or style.edith style.tileh))))
|
||||||
|
(fn GraphicsEditView.set-style [self key]
|
||||||
|
(set self.style key)
|
||||||
|
(set self.tilecache (files.cache key))
|
||||||
|
(set self.itile 1))
|
||||||
|
(fn GraphicsEditView.reload [self] (files.reload))
|
||||||
|
(fn GraphicsEditView.save [self] (files.save))
|
||||||
|
|
||||||
|
(fn GraphicsEditView.select-rel [self ditile]
|
||||||
|
(when self.itile
|
||||||
|
(local itile (+ self.itile ditile))
|
||||||
|
(when (>= itile 1) (set self.itile itile))))
|
||||||
|
|
||||||
|
(fn GraphicsEditView.draw-sprite [self x y itile ?key]
|
||||||
|
(let [sprite (self.tilecache:sprite itile ?key)]
|
||||||
|
(when sprite
|
||||||
|
(love.graphics.setColor 1 1 1)
|
||||||
|
(love.graphics.draw sprite x y 0 self.sprite-scale self.sprite-scale)
|
||||||
|
(values (* (sprite:getWidth) self.sprite-scale) (* (sprite:getHeight) self.sprite-scale)))))
|
||||||
|
|
||||||
|
(fn tile-selector [{: view : x : y : w : scale &as form} chosen-itile ?key]
|
||||||
|
(var tilex x)
|
||||||
|
(var tiley y)
|
||||||
|
(var selected-itile nil)
|
||||||
|
(var (pixw pixh) (view:tilesize))
|
||||||
|
(when (= files.game.platform :ii) (set pixw (* (/ pixw 8) 7)))
|
||||||
|
(local tilew (* scale pixw))
|
||||||
|
(local tileh (* scale pixh))
|
||||||
|
(for [itile 1 (length view.tilecache.tiles)]
|
||||||
|
(view:draw-sprite tilex tiley itile ?key)
|
||||||
|
(when (= itile chosen-itile)
|
||||||
|
(love.graphics.rectangle :line (- tilex 2) (- tiley 2) (+ tilew 4) (+ tileh 4)))
|
||||||
|
(when (button {: view :tag [:tile itile] :x tilex :y tiley :w tilew :h tileh})
|
||||||
|
(set selected-itile itile))
|
||||||
|
(set tilex (+ tilex tilew 4))
|
||||||
|
(when (>= (+ tilex tilew) (+ x w))
|
||||||
|
(set tilex x)
|
||||||
|
(set tiley (+ tiley tileh 4))))
|
||||||
|
(set form.h (+ tiley tileh (- y)))
|
||||||
|
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)
|
||||||
|
selected-itile (do (set self.itile selected-itile)
|
||||||
|
(set self.tilekey ?key))))
|
||||||
|
|
||||||
|
GraphicsEditView
|
338
editor/imgui.fnl
Normal file
338
editor/imgui.fnl
Normal file
|
@ -0,0 +1,338 @@
|
||||||
|
(local core (require :core))
|
||||||
|
(local config (require :core.config))
|
||||||
|
(local command (require :core.command))
|
||||||
|
(local keymap (require :core.keymap))
|
||||||
|
(local style (require :core.style))
|
||||||
|
(local lume (require :lib.lume))
|
||||||
|
|
||||||
|
(fn attach-imstate [view]
|
||||||
|
(set view.imstate {})
|
||||||
|
(fn view.on_mouse_pressed [self button x y clicks]
|
||||||
|
(tset self.imstate button :pressed)
|
||||||
|
(self.__index.on_mouse_pressed self button x y clicks))
|
||||||
|
(fn view.on_mouse_released [self button x y]
|
||||||
|
(tset self.imstate button :released)
|
||||||
|
(self.__index.on_mouse_released self button x y))
|
||||||
|
(fn view.on_key_pressed [self key]
|
||||||
|
(when (= self.imstate.keys nil)
|
||||||
|
(set self.imstate.keys []))
|
||||||
|
(table.insert self.imstate.keys key))
|
||||||
|
(fn view.on_text_input [self text]
|
||||||
|
(set self.imstate.text (.. (or self.imstate.text "") text))
|
||||||
|
(self.__index.on_text_input self text))
|
||||||
|
(fn view.form [self ?overrides]
|
||||||
|
(lume.merge {:x (+ self.position.x style.padding.x (- self.scroll.x))
|
||||||
|
:y (+ self.position.y style.padding.y (- self.scroll.y))
|
||||||
|
:view self}
|
||||||
|
(or ?overrides {})))
|
||||||
|
(fn view.end-scroll [self {: y : h}]
|
||||||
|
(set self.scrollheight (- (+ y (or h 0) style.padding.y) (+ self.position.y style.padding.y (- self.scroll.y)))))
|
||||||
|
(fn view.draw [self]
|
||||||
|
(set self.cursor nil)
|
||||||
|
(self.__index.draw self)
|
||||||
|
(when self.imstate.postponed
|
||||||
|
(each [_ action (ipairs self.imstate.postponed)]
|
||||||
|
(action))
|
||||||
|
(set self.imstate.postponed nil))
|
||||||
|
(when (= self.cursor nil) (set self.cursor :arrow))
|
||||||
|
(set self.imstate.keys nil)
|
||||||
|
(set self.imstate.text nil)
|
||||||
|
(when (= self.imstate.left :released)
|
||||||
|
(set self.imstate.active nil))
|
||||||
|
(each [_ button (pairs [:left :middle :right])]
|
||||||
|
(tset self.imstate button
|
||||||
|
(match (. self.imstate button)
|
||||||
|
:pressed :down
|
||||||
|
:down :down
|
||||||
|
:released nil)))))
|
||||||
|
|
||||||
|
(fn register-keys [keys]
|
||||||
|
(local commands {})
|
||||||
|
(local keymaps {})
|
||||||
|
(each [_ key (ipairs keys)]
|
||||||
|
(local command-name (.. "imstate:" key))
|
||||||
|
(tset commands command-name #(core.active_view:on_key_pressed key))
|
||||||
|
(tset keymaps key command-name))
|
||||||
|
(command.add #(not= (-?> core.active_view.imstate (. :focus)) nil) commands)
|
||||||
|
(keymap.add keymaps))
|
||||||
|
|
||||||
|
(register-keys [:backspace :delete :left :right :shift+left :shift+right :home :end :shift+home :shift+end
|
||||||
|
:ctrl+left :ctrl+right :ctrl+shift+left :ctrl+shift+right :ctrl+c :ctrl+v])
|
||||||
|
|
||||||
|
(fn cmd-predicate [p]
|
||||||
|
(var p-fn p)
|
||||||
|
(when (= (type p-fn) :string) (set p-fn (require p-fn)))
|
||||||
|
(when (= (type p-fn) :table)
|
||||||
|
(local cls p-fn)
|
||||||
|
(set p-fn (fn [] (core.active_view:is cls))))
|
||||||
|
(fn [] (when (= (-?> core.active_view.imstate (. :focus)) nil)
|
||||||
|
(p-fn))))
|
||||||
|
|
||||||
|
(fn postpone [view f]
|
||||||
|
(when (= view.imstate.postponed nil)
|
||||||
|
(set view.imstate.postponed []))
|
||||||
|
(table.insert view.imstate.postponed f))
|
||||||
|
|
||||||
|
(fn make-tag [tag]
|
||||||
|
(match (type tag)
|
||||||
|
:string tag
|
||||||
|
:table (table.concat tag "::")
|
||||||
|
_ (tostring tag)))
|
||||||
|
|
||||||
|
(fn mouse-inside [x y w h]
|
||||||
|
(local (mx my) (values (love.mouse.getX) (love.mouse.getY)))
|
||||||
|
(and (>= mx x) (<= mx (+ x w)) (>= my y) (<= my (+ y h))))
|
||||||
|
|
||||||
|
(fn consume-pressed [view button]
|
||||||
|
(when (= (. view.imstate button) :pressed)
|
||||||
|
(tset view.imstate button :down)
|
||||||
|
true))
|
||||||
|
|
||||||
|
(fn activate [{: view : tag : x : y : w : h}]
|
||||||
|
(when (and (mouse-inside x y w h) (consume-pressed view :left))
|
||||||
|
(set view.imstate.active (make-tag tag))
|
||||||
|
true))
|
||||||
|
|
||||||
|
(fn set-cursor [view cursor]
|
||||||
|
(when (= view.cursor nil) (set view.cursor cursor)))
|
||||||
|
|
||||||
|
(fn active? [view tag] (= view.imstate.active (make-tag tag)))
|
||||||
|
(fn button [{: view : tag : x : y : w : h &as form}]
|
||||||
|
(when (mouse-inside x y w h) (set-cursor view :hand))
|
||||||
|
(activate form)
|
||||||
|
(and (active? view tag) (= view.imstate.left :released) (mouse-inside x y w h)))
|
||||||
|
|
||||||
|
(fn form-defaults [form k v ...]
|
||||||
|
(when (= (. form k) nil)
|
||||||
|
(let [v (if (= (type v) :function) (v form) v)]
|
||||||
|
(tset form k v)))
|
||||||
|
(if (>= (select :# ...) 2) (form-defaults form ...)
|
||||||
|
(do (when form.tag (set form.tag (make-tag form.tag))) ; fix up tag
|
||||||
|
form)))
|
||||||
|
|
||||||
|
(fn with-style [form ...]
|
||||||
|
(form-defaults form :font style.font :color style.text :xpad style.padding.x :ypad style.padding.y ...))
|
||||||
|
|
||||||
|
(fn textbutton [form label]
|
||||||
|
(let [{: x : y : w : h : xpad : ypad : font : color : bg}
|
||||||
|
(with-style form
|
||||||
|
:bg style.selection
|
||||||
|
:tag label
|
||||||
|
:w #(+ ($1.font:get_width label) $1.xpad)
|
||||||
|
:h #(+ ($1.font:get_height) $1.ypad))]
|
||||||
|
(renderer.draw_rect x y w h bg)
|
||||||
|
(renderer.draw_text font label (+ x (/ xpad 2)) (+ y (/ ypad 2)) color)
|
||||||
|
(button form)))
|
||||||
|
|
||||||
|
(fn checkbox [form name isset]
|
||||||
|
(let [{: x : y : w : h : font : color : x-label}
|
||||||
|
(with-style form
|
||||||
|
:tag name
|
||||||
|
:h (* 12 SCALE)
|
||||||
|
:x-label #(+ $1.x $1.h $1.xpad)
|
||||||
|
:w #(+ $1.x-label ($1.font:get_width name)))]
|
||||||
|
(love.graphics.rectangle (if isset :fill :line) x y h h)
|
||||||
|
(renderer.draw_text font name x-label y color)
|
||||||
|
(love.graphics.setColor 1 1 1 1)
|
||||||
|
(button form))) ; whose idea was this?? should return (not isset) >:/
|
||||||
|
|
||||||
|
(fn focused? [view tag] (= (make-tag tag) (-?> view.imstate.focus (. :tag))))
|
||||||
|
(fn focus [{: view : tag : x : y : w : h &as form} opts]
|
||||||
|
(if (activate form)
|
||||||
|
(set view.imstate.focus
|
||||||
|
(doto (lume.clone (or opts {}))
|
||||||
|
(tset :tag (make-tag tag))))
|
||||||
|
|
||||||
|
(and (= view.imstate.left :released) (focused? view tag) (not (mouse-inside x y w h)))
|
||||||
|
(set view.imstate.focus nil))
|
||||||
|
(focused? view tag))
|
||||||
|
|
||||||
|
(local blink_period 0.8)
|
||||||
|
(fn x-from-i [s i xLeft font]
|
||||||
|
(if (or (<= i 1) (= s "")) xLeft
|
||||||
|
(x-from-i (s:sub 2) (- i 1) (+ xLeft (font:get_width (s:sub 1 1))) font)))
|
||||||
|
(fn i-from-x [s x xLeft font ?i]
|
||||||
|
(local i (or ?i 1))
|
||||||
|
(local w (font:get_width (s:sub 1 1)))
|
||||||
|
(local xMid (+ xLeft (/ w 2)))
|
||||||
|
(if (or (<= x xMid) (= s "")) i
|
||||||
|
(i-from-x (s:sub 2) x (+ xLeft w) font (+ i 1))))
|
||||||
|
|
||||||
|
(fn next-match [text i di pred]
|
||||||
|
(local imax (+ (length text) 1))
|
||||||
|
(local inext (+ i di))
|
||||||
|
(if (<= inext 1) 1
|
||||||
|
(> inext imax) imax
|
||||||
|
(pred (text:sub inext inext)) (if (< di 0) i inext)
|
||||||
|
(next-match text inext di pred)))
|
||||||
|
(fn is-nonword-char [char] (config.non_word_chars:find char nil true))
|
||||||
|
(fn next-word [text i di]
|
||||||
|
(let [iwordboundary (next-match text i di #(is-nonword-char $1))]
|
||||||
|
(next-match text iwordboundary di #(not (is-nonword-char $1)))))
|
||||||
|
|
||||||
|
(fn textnav [key i text]
|
||||||
|
(local imax (+ (length text) 1))
|
||||||
|
(match key
|
||||||
|
:left (math.max 1 (- i 1))
|
||||||
|
:right (math.min imax (+ i 1))
|
||||||
|
:ctrl+left (next-word text i -1)
|
||||||
|
:ctrl+right (next-word text i 1)
|
||||||
|
:home 1
|
||||||
|
:end imax))
|
||||||
|
|
||||||
|
(fn selection-span [view]
|
||||||
|
(let [f view.imstate.focus
|
||||||
|
iStart (math.min f.i f.iAnchor)
|
||||||
|
iLim (math.max f.i f.iAnchor)]
|
||||||
|
(values iStart iLim)))
|
||||||
|
(fn selection-text [view text]
|
||||||
|
(local (iStart iLim) (selection-span view))
|
||||||
|
(text:sub iStart (- iLim 1)))
|
||||||
|
|
||||||
|
(fn replace-selection [view s replacement ?iStart ?iLim]
|
||||||
|
(local (iStart iLim) (if ?iLim (values ?iStart ?iLim) (selection-span view)))
|
||||||
|
(local text
|
||||||
|
(.. (s:sub 1 (- iStart 1))
|
||||||
|
replacement
|
||||||
|
(s:sub iLim)))
|
||||||
|
(local iNew (+ iStart (length replacement)))
|
||||||
|
(set view.imstate.focus.i iNew)
|
||||||
|
(set view.imstate.focus.iAnchor iNew)
|
||||||
|
text)
|
||||||
|
|
||||||
|
(fn textbox [form text]
|
||||||
|
(local {: font : color : w : h : x : y : xpad : ypad : color : view : tag}
|
||||||
|
(with-style form :h #(+ ($1.font:get_height) $1.xpad)))
|
||||||
|
(var textNew (or text ""))
|
||||||
|
(local (hText xText yText) (values (font:get_height) (+ x (/ xpad 2)) (+ y (/ ypad 2))))
|
||||||
|
(local initial-press (= view.imstate.left :pressed))
|
||||||
|
|
||||||
|
; handle key events
|
||||||
|
(when (focus form {:i 1 :iAnchor 1 :blink (love.timer.getTime)})
|
||||||
|
(local f view.imstate.focus)
|
||||||
|
(when (> f.i (+ (length textNew) 1)) (set f.i (+ (length textNew) 1)))
|
||||||
|
(when (> f.iAnchor (+ (length textNew) 1)) (set f.iAnchor (+ (length textNew) 1)))
|
||||||
|
(when view.imstate.text
|
||||||
|
(set textNew (replace-selection view textNew view.imstate.text)))
|
||||||
|
(each [_ key (ipairs (or view.imstate.keys []))]
|
||||||
|
(set view.imstate.focus.blink (love.timer.getTime))
|
||||||
|
(if (= key :ctrl+c) (system.set_clipboard (selection-text view textNew))
|
||||||
|
(= key :ctrl+v) (set textNew (replace-selection view textNew (system.get_clipboard)))
|
||||||
|
(key:find "shift%+") (set f.i (or (textnav (key:gsub "shift%+" "") f.i textNew) f.i))
|
||||||
|
(let [iNav (textnav key f.i textNew)]
|
||||||
|
(when iNav
|
||||||
|
(set f.i iNav)
|
||||||
|
(set f.iAnchor iNav))
|
||||||
|
(when (or (= key :delete) (= key :backspace))
|
||||||
|
(local (iStartDel iLimDel)
|
||||||
|
(if (not= f.i f.iAnchor) (selection-span view)
|
||||||
|
(= key :delete) (values f.i (+ f.i 1))
|
||||||
|
(= key :backspace) (values (math.max 1 (- f.i 1)) f.i)))
|
||||||
|
(set textNew (replace-selection view textNew "" iStartDel iLimDel)))))))
|
||||||
|
|
||||||
|
; handle mouse events
|
||||||
|
(when (mouse-inside x y w h) (set-cursor view :ibeam))
|
||||||
|
(when (and (focused? view tag) (active? view tag) (mouse-inside x y w h))
|
||||||
|
(local mouse-i (i-from-x textNew (love.mouse.getX) x style.font))
|
||||||
|
(when initial-press
|
||||||
|
(set view.imstate.focus.iAnchor mouse-i))
|
||||||
|
(set view.imstate.focus.i mouse-i))
|
||||||
|
|
||||||
|
; draw box
|
||||||
|
(love.graphics.setLineWidth 1)
|
||||||
|
(love.graphics.rectangle :line x y w h)
|
||||||
|
(if (focused? view tag)
|
||||||
|
; draw text with selection + caret
|
||||||
|
(let [(iStart iLim) (selection-span view)
|
||||||
|
xSelect (renderer.draw_text font (textNew:sub 1 (- iStart 1)) xText yText color)
|
||||||
|
sSelect (textNew:sub iStart (- iLim 1))
|
||||||
|
wSelect (font:get_width sSelect)
|
||||||
|
xTail (+ xSelect wSelect)]
|
||||||
|
(when (> wSelect 0)
|
||||||
|
(renderer.draw_rect xSelect yText wSelect hText style.selection)
|
||||||
|
(renderer.draw_text font sSelect xSelect yText color))
|
||||||
|
(renderer.draw_text font (textNew:sub iLim) xTail yText color)
|
||||||
|
(when (or (active? view tag)
|
||||||
|
(< (% (- (love.timer.getTime) view.imstate.focus.blink) (* blink_period 2)) blink_period))
|
||||||
|
(renderer.draw_rect (x-from-i textNew view.imstate.focus.i xText font) yText style.caret_width hText style.caret)))
|
||||||
|
; just draw the text
|
||||||
|
(renderer.draw_text font textNew xText yText color))
|
||||||
|
(love.graphics.setColor 1 1 1)
|
||||||
|
textNew)
|
||||||
|
|
||||||
|
(fn textfield [form label text]
|
||||||
|
(let [{: x : y : w : wlabel : wtext : font : color}
|
||||||
|
(with-style form :wlabel #(+ ($1.font:get_width label) $1.xpad)
|
||||||
|
:wtext (* 150 SCALE)
|
||||||
|
:w #(+ $1.wlabel $1.wtext)
|
||||||
|
:tag label)
|
||||||
|
form-textbox (lume.merge form {:w wtext :x (+ x wlabel)})
|
||||||
|
_ (renderer.draw_text font label x y color)
|
||||||
|
text (textbox form-textbox text)]
|
||||||
|
(set form.h form-textbox.h)
|
||||||
|
text))
|
||||||
|
|
||||||
|
(fn option-text [option]
|
||||||
|
(match (type option)
|
||||||
|
:string option
|
||||||
|
:table (or option.label (tostring option))
|
||||||
|
_ (tostring option)))
|
||||||
|
|
||||||
|
(fn dropdown [form selection options]
|
||||||
|
(let [{: x : y : w :h row-h : font : color : bg : xpad : ypad : view : tag}
|
||||||
|
(with-style form :h #(+ ($1.font:get_height) $1.ypad)
|
||||||
|
:bg style.selection)]
|
||||||
|
(var new-selection nil)
|
||||||
|
|
||||||
|
(renderer.draw_rect x y w row-h bg)
|
||||||
|
(renderer.draw_text style.font (option-text selection) (+ x xpad) (+ y (/ ypad 2)) color)
|
||||||
|
(renderer.draw_text style.icon_font "-" (+ x w (- xpad)) (+ y (/ ypad 2)) color)
|
||||||
|
|
||||||
|
(when (focused? view tag)
|
||||||
|
(var row-y (+ y row-h))
|
||||||
|
(each [i option (ipairs options)]
|
||||||
|
(when (button (lume.merge form {:tag [(make-tag tag) i] :y row-y}))
|
||||||
|
(set new-selection option))
|
||||||
|
(set row-y (+ row-y row-h)))
|
||||||
|
(postpone view (fn []
|
||||||
|
(var row-y (+ y row-h))
|
||||||
|
(each [i option (ipairs options)]
|
||||||
|
(renderer.draw_rect x row-y w row-h bg)
|
||||||
|
(renderer.draw_text font (option-text option) (+ x xpad) (+ row-y (/ ypad 2)) color)
|
||||||
|
(set row-y (+ row-y row-h))))))
|
||||||
|
(focus form)
|
||||||
|
(or new-selection 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 overrides)
|
||||||
|
form)
|
||||||
|
|
||||||
|
(fn vert [form viewfn overrides ...]
|
||||||
|
(let [result [(viewfn (prepare-form form overrides) ...)]]
|
||||||
|
(set form.y (+ form.y (or form.h 0) (or form.ypad 0)))
|
||||||
|
(table.unpack result)))
|
||||||
|
|
||||||
|
(fn horiz [form viewfn overrides ...]
|
||||||
|
(let [result [(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 [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 (+ x w))
|
||||||
|
(set form.x x)
|
||||||
|
(set form.y (+ form.y form.h (or form.ypad 0))))
|
||||||
|
(table.unpack result))))
|
||||||
|
|
||||||
|
{: attach-imstate : cmd-predicate : postpone : mouse-inside : activate : active?
|
||||||
|
: button : checkbox : textbox : textfield : textbutton : dropdown
|
||||||
|
: vert : horiz : horiz-wrapper
|
||||||
|
: with-style : prepare-form : form-defaults}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
(local GraphicsEditView (require :editor.gfxedit))
|
(local GraphicsEditView (require :editor.gfxedit2))
|
||||||
(local style (require :core.style))
|
(local style (require :core.style))
|
||||||
(local tiles (require :game.tiles))
|
(local tiles (require :game.tiles))
|
||||||
(local files (require :game.files))
|
(local files (require :game.files))
|
||||||
(local util (require :lib.util))
|
(local util (require :lib.util))
|
||||||
(local {: mouse-inside : activate : active? : checkbox : textfield : button : dropdown} (util.require :editor.imstate))
|
(local lume (require :lib.lume))
|
||||||
|
(local {: mouse-inside : activate : active? : checkbox : textfield : button : dropdown : with-style : form-defaults : vert : horiz-wrapper} (util.require :editor.imgui))
|
||||||
|
|
||||||
(local TileView (GraphicsEditView:extend))
|
(local TileView (GraphicsEditView:extend))
|
||||||
|
|
||||||
|
@ -47,92 +48,105 @@
|
||||||
(renderer.draw_rect x y pixel-size pixel-size colorbg)
|
(renderer.draw_rect x y pixel-size pixel-size colorbg)
|
||||||
(when ?colorfg (renderer.draw_rect (+ x 3) (+ y 3) (- pixel-size 6) (- pixel-size 6) ?colorfg)))
|
(when ?colorfg (renderer.draw_rect (+ x 3) (+ y 3) (- pixel-size 6) (- pixel-size 6) ?colorfg)))
|
||||||
|
|
||||||
(fn TileView.draw-tile-editor [self tile x y]
|
(fn tile-editor [{:view self : x : y &as form} tile]
|
||||||
(when (not (active? self :tile)) (self:draw-off))
|
(local {: tag} (with-style form :tag :tile))
|
||||||
|
(when (not (active? self tag)) (self:draw-off))
|
||||||
(local (w h) (self:tilesize))
|
(local (w h) (self:tilesize))
|
||||||
(local editor-w (* (+ pixel-size 1) w))
|
(set form.w (* (+ pixel-size 1) w))
|
||||||
(local editor-h (* (+ pixel-size 1) h))
|
(set form.h (* (+ pixel-size 1) h))
|
||||||
(activate self :tile x y editor-w editor-h)
|
(activate form)
|
||||||
(for [bitx 0 (- w 1)] (for [bity 0 (- h 1)]
|
(for [bitx 0 (- w 1)] (for [bity 0 (- h 1)]
|
||||||
(local (ibyte ibit mask) (self:map-bitxy bitx bity w h))
|
(local (ibyte ibit mask) (self:map-bitxy bitx bity w h))
|
||||||
(local b (get-bits tile ibyte ibit mask))
|
(local b (get-bits tile ibyte ibit mask))
|
||||||
(local (px py) (values (+ x (* bitx (+ pixel-size 1))) (+ y (* bity (+ pixel-size 1)))))
|
(local (px py) (values (+ x (* bitx (+ pixel-size 1))) (+ y (* bity (+ pixel-size 1)))))
|
||||||
(local (colorbg colorfg) (self:pixel-color b ibyte ibit))
|
(local (colorbg colorfg) (self:pixel-color b ibyte ibit))
|
||||||
(self:draw-pixel px py colorbg colorfg)
|
(self:draw-pixel px py colorbg colorfg)
|
||||||
(when (and (active? self :tile) (mouse-inside px py pixel-size pixel-size))
|
(when (and (active? self tag) (mouse-inside px py pixel-size pixel-size))
|
||||||
(self:draw-on b)
|
(self:draw-on b)
|
||||||
(local bits (self:draw-bits))
|
(local bits (self:draw-bits))
|
||||||
(when (not= bits b)
|
(when (not= bits b)
|
||||||
(self:update-tile (set-tile-bits tile ibyte ibit mask bits))))))
|
(self:update-tile (set-tile-bits tile ibyte ibit mask bits))))))
|
||||||
(love.graphics.setColor 1 1 1 1)
|
(love.graphics.setColor 1 1 1 1))
|
||||||
(values editor-w editor-h))
|
|
||||||
|
|
||||||
(fn TileView.draw-tile-flag [self flagname x y]
|
(fn TileView.draw-tile-editor [self form tile] (vert form tile-editor {} tile))
|
||||||
(local flags (-?> self.tilecache.tiles (. self.itile) (. :flags)))
|
|
||||||
(local flagset (if flags (. flags flagname) false))
|
|
||||||
(let [(checked yNew) (checkbox self flagname flagset x y)]
|
|
||||||
(when checked (tset flags flagname (if flagset nil true)))
|
|
||||||
yNew))
|
|
||||||
|
|
||||||
(fn TileView.draw-tile-flags [self x y]
|
(fn tile-flag [form tile flagname]
|
||||||
(local tile (-?> self.tilecache.tiles (. self.itile)))
|
(local flagset (?. tile :flags flagname))
|
||||||
(var y y)
|
(when (checkbox form flagname flagset)
|
||||||
|
(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)}]
|
||||||
(when tile
|
(when tile
|
||||||
(set (tile.word y) (textfield self "Default word" tile.word x (+ y style.padding.y) (* 100 SCALE) (* 200 SCALE)))
|
(set tile.word (vert form textfield fieldform "Default word" tile.word))
|
||||||
(set (tile.label y) (textfield self "Label" tile.label x (+ y style.padding.y) (* 100 SCALE) (* 200 SCALE))))
|
(set tile.label (vert form textfield fieldform "Label" tile.label)))
|
||||||
(each [iflag flagname (ipairs (tiles.flags))]
|
(each [iflag flagname (ipairs (tiles.flags))]
|
||||||
(set y (self:draw-tile-flag flagname x (+ y style.padding.y))))
|
(vert form tile-flag {} tile flagname))))
|
||||||
y)
|
|
||||||
|
|
||||||
(fn TileView.draw-tile-preview [self x y]
|
(fn tile-preview [{:view self : x : y &as form} itile tilekey]
|
||||||
(each [_ [tx ty] (ipairs (self:preview-locations))]
|
(each [_ [tx ty] (ipairs (self:preview-locations))]
|
||||||
(self:draw-sprite (+ x (* tx self.sprite-scale)) (+ y (* ty self.sprite-scale)) self.itile self.tilekey)))
|
(let [dx (* tx self.sprite-scale) dy (* ty self.sprite-scale)
|
||||||
|
(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-palette [self x y w]
|
(fn tile-palette [{:view self : x : y : w &as form} pal selected-color]
|
||||||
(local pal (self:palette))
|
(let [wrap (horiz-wrapper (with-style form))]
|
||||||
(if pal
|
(var selected-color selected-color)
|
||||||
(do (var cx x)
|
|
||||||
(var cy y)
|
|
||||||
(each [icolor color (ipairs pal)]
|
(each [icolor color (ipairs pal)]
|
||||||
(when (>= cx w)
|
(renderer.draw_rect form.x form.y pixel-size pixel-size color)
|
||||||
(set cx x)
|
(when (= icolor selected-color)
|
||||||
(set cy (+ cy pixel-size style.padding.y)))
|
|
||||||
(when (button self [:pal icolor] cx cy pixel-size pixel-size)
|
|
||||||
(set self.icolor icolor))
|
|
||||||
(renderer.draw_rect cx cy pixel-size pixel-size color)
|
|
||||||
(when (= icolor self.icolor)
|
|
||||||
(love.graphics.setColor 1 1 1 1)
|
(love.graphics.setColor 1 1 1 1)
|
||||||
(love.graphics.rectangle :line (- cx 2) (- cy 2) (+ pixel-size 4) (+ pixel-size 4)))
|
(love.graphics.rectangle :line (- form.x 2) (- form.y 2) (+ pixel-size 4) (+ pixel-size 4)))
|
||||||
(set cx (+ cx pixel-size style.padding.x)))
|
(when (wrap button {:tag [:pal icolor] :w pixel-size :h pixel-size})
|
||||||
(+ pixel-size style.padding.y))
|
(set selected-color icolor)))
|
||||||
0))
|
(set form.w w) ;; todo: some kind of "group" combinator that does this for us
|
||||||
|
(set form.h (+ (- form.y y) pixel-size))
|
||||||
|
(set form.x x)
|
||||||
|
(set form.y y)
|
||||||
|
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))))
|
||||||
|
|
||||||
(fn TileView.update-tile [self newtile]
|
(fn TileView.update-tile [self newtile]
|
||||||
(self.tilecache:update-tile self.itile newtile self.tilekey))
|
(self.tilecache:update-tile self.itile newtile self.tilekey))
|
||||||
|
|
||||||
(fn TileView.draw-style-selector [self x y]
|
(fn style-selector [form current-style]
|
||||||
(renderer.draw_text style.font "Style" x (+ y (/ style.padding.y 2)) style.text)
|
(let [{:view self : x : y : font : color : ypad} (with-style form)
|
||||||
(let [(selection yNext) (dropdown self :layer-selector self.style (tiles.tile-styles) (+ x (* 50 SCALE)) y (* 100 SCALE)) ]
|
form-drop (lume.merge form {:x (+ x (* 50 SCALE)) :w (* 100 SCALE) :tag :layer-selector})
|
||||||
(when (not= self.style selection)
|
selection (dropdown form-drop current-style (tiles.tile-styles))]
|
||||||
(self:set-style selection))
|
(renderer.draw_text font "Style" x (+ y (/ ypad 2)) color)
|
||||||
(- yNext y)))
|
(set form.w (- (+ form-drop.x form-drop.w) x))
|
||||||
|
(set form.h form-drop.h)
|
||||||
|
(when (not= current-style selection) selection)))
|
||||||
|
|
||||||
|
(fn TileView.draw-style-selector [self form]
|
||||||
|
(match (vert form style-selector {} self.style)
|
||||||
|
new-style (self:set-style new-style)))
|
||||||
|
|
||||||
(fn TileView.draw [self]
|
(fn TileView.draw [self]
|
||||||
(self:draw_background style.background)
|
(self:draw_background style.background)
|
||||||
(self:draw_scrollbar)
|
(self:draw_scrollbar)
|
||||||
(local (x y) (values (+ self.position.x style.padding.x (- self.scroll.x))
|
(let [form (self:form)
|
||||||
(+ self.position.y style.padding.y (- self.scroll.y))))
|
form-side (self:form)]
|
||||||
(local (editor-w editor-h) (self:draw-tile-editor (self:tile) x y))
|
(self:draw-tile-editor form (self:tile))
|
||||||
(local preview-y (self:draw-tile-flags (+ x editor-w pixel-size) y))
|
|
||||||
(self:draw-tile-preview (+ x editor-w pixel-size) (+ preview-y style.padding.y))
|
; layout sidebar
|
||||||
(var selector-y (+ y editor-h pixel-size))
|
(set form-side.x (+ form.x form.w form.xpad))
|
||||||
(set selector-y (+ selector-y (self:draw-tile-palette x selector-y (- self.size.x 20))))
|
(self:draw-tile-flags form-side)
|
||||||
|
(self:draw-tile-preview form-side)
|
||||||
|
|
||||||
|
; continue laying out under tile editor
|
||||||
|
(self:draw-tile-palette (lume.extend form {:w (- self.size.x 20)}))
|
||||||
(when (> (length (tiles.tile-styles)) 1)
|
(when (> (length (tiles.tile-styles)) 1)
|
||||||
(set selector-y (+ selector-y (self:draw-style-selector x selector-y) style.padding.y)))
|
(self:draw-style-selector form))
|
||||||
(each [_ key (ipairs (self:tilekeys))]
|
(each [_ key (ipairs (self:tilekeys))]
|
||||||
(local selector-h (self:draw-tile-selector x selector-y (- self.size.x 20) key))
|
(self:draw-tile-selector (lume.extend form {:w (- self.size.x 20)}) key))
|
||||||
(set selector-y (+ selector-y selector-h pixel-size)))
|
(self:end-scroll form)))
|
||||||
(set self.scrollheight (- selector-y y)))
|
|
||||||
|
|
||||||
(fn TileView.initial-style [self] :tiles)
|
(fn TileView.initial-style [self] :tiles)
|
||||||
(fn TileView.get_name [self] "Tile Editor")
|
(fn TileView.get_name [self] "Tile Editor")
|
||||||
|
|
Loading…
Reference in a new issue