(fn attach-imstate [view] (set view.imstate {:x (love.mouse.getX) :y (love.mouse.getY)}) (local cls view.__index) (fn view.on_mouse_pressed [self button x y clicks] (tset self.imstate button :pressed) (set self.imstate.x x) (set self.imstate.y y) (cls.on_mouse_pressed self button x y clicks)) (fn view.on_mouse_moved [self x y dx dy] (set self.imstate.x x) (set self.imstate.y y) (cls.on_mouse_moved self x y dx dy)) (fn view.on_mouse_released [self button x y] (tset self.imstate button :released) (set self.imstate.x x) (set self.imstate.y y) (cls.on_mouse_released self button x y)) (fn view.draw [self] (cls.draw self) (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 make-tag [tag] (match (type tag) :string tag :table (table.concat tag "::") _ (tostring tag))) (fn mouse-inside [view x y w h] (and (>= view.imstate.x x) (<= view.imstate.x (+ x w)) (>= view.imstate.y y) (<= view.imstate.y (+ y h)))) (fn activate [view tag x y w h] (when (and (= view.imstate.left :pressed) (mouse-inside view x y w h)) (set view.imstate.active (make-tag tag)) true)) (fn active? [view tag] (= view.imstate.active (make-tag tag))) (fn button [view tag x y w h] (activate view tag x y w h) (and (active? view tag) (= view.imstate.left :released) (mouse-inside view x y w h))) {: attach-imstate : mouse-inside : activate : active? : button}