Break ui code to separate namespace and refactor

This commit is contained in:
oakes
2014-01-11 14:14:13 -05:00
parent b2efae2d99
commit bf98ffbb9b
8 changed files with 230 additions and 205 deletions

View File

@@ -1,12 +1,12 @@
(ns play-clj.core
(:require [clojure.set :as set]
[play-clj.utils :as utils])
[play-clj.ui :as ui]
[play-clj.utils :as u])
(:import [com.badlogic.gdx Application Audio Files Game Gdx Graphics Input
InputMultiplexer InputProcessor Net Screen]
[com.badlogic.gdx.graphics Camera Color GL20 OrthographicCamera
PerspectiveCamera Texture]
[com.badlogic.gdx.graphics.g2d Animation BitmapFont SpriteBatch
TextureRegion]
[com.badlogic.gdx.graphics.g2d Animation SpriteBatch TextureRegion]
[com.badlogic.gdx.input GestureDetector
GestureDetector$GestureListener]
[com.badlogic.gdx.maps MapLayer MapLayers]
@@ -17,29 +17,12 @@
IsometricStaggeredTiledMapRenderer
IsometricTiledMapRenderer
OrthogonalTiledMapRenderer]
[com.badlogic.gdx.scenes.scene2d Actor Stage]
[com.badlogic.gdx.scenes.scene2d.ui ButtonGroup CheckBox Dialog
ImageButton ImageTextButton Label Skin Slider TextButton TextField]
[com.badlogic.gdx.scenes.scene2d.utils ActorGestureListener
ChangeListener ClickListener DragListener FocusListener
NinePatchDrawable SpriteDrawable TextureRegionDrawable TiledDrawable]))
(defmulti create-entity class)
(defmethod create-entity TextureRegion
[obj]
{:type :image :object obj})
(defmethod create-entity Actor
[obj]
{:type :actor :object obj})
[com.badlogic.gdx.scenes.scene2d Actor Stage]))
(load "core_2d")
(load "core_deprecated")
(load "core_global")
(load "core_interop")
(load "core_render")
(load "core_ui")
(defn defscreen*
[{:keys [on-show on-render on-hide on-pause on-resize on-resume]
@@ -56,11 +39,7 @@
(compare-and-set! entities entities-list)))))
listeners [(input-processor options execute-fn!)
(gesture-detector options execute-fn!)]
ui-listeners [(ui-gesture-listener options execute-fn!)
(ui-change-listener options execute-fn!)
(ui-click-listener options execute-fn!)
(ui-drag-listener options execute-fn!)
(ui-focus-listener options execute-fn!)]
ui-listeners (ui/listeners options execute-fn!)
create-renderer-fn! #(swap! screen assoc :renderer (renderer %))
update-fn! #(swap! screen merge %)]
{:screen screen
@@ -121,3 +100,15 @@
(defn update!
[{:keys [update-fn!]} & {:keys [] :as args}]
(update-fn! args))
(defn listen!
[{:keys [renderer ui-listeners] :as screen} entities]
(assert (isa? (type renderer) Stage))
(add-input! renderer)
(stage! screen :clear)
(doseq [{:keys [object]} entities]
(when (isa? (type object) Actor)
(stage! screen :add-actor object)
(doseq [listener ui-listeners]
(.addListener ^Actor object listener))))
entities)

View File

@@ -26,7 +26,7 @@
nil))
(.draw object batch 1))
(defn draw-image!
(defn draw-texture!
[^SpriteBatch batch {:keys [^TextureRegion object x y width height]}]
(assert (and object x y width height))
(.draw batch object (float x) (float y) (float width) (float height)))
@@ -34,12 +34,12 @@
(defn draw-entity!
[^SpriteBatch batch entity]
(if (not (map? entity))
(draw-entity! batch (create-entity entity))
(draw-entity! batch (u/create-entity entity))
(case (:type entity)
:actor
(draw-actor! batch entity)
:image
(draw-image! batch entity)
:texture
(draw-texture! batch entity)
nil)))
(defn draw! [{:keys [renderer] :as screen} entities]
@@ -53,7 +53,7 @@
; textures
(defn image*
(defn texture*
[img]
(cond
(string? img)
@@ -63,19 +63,25 @@
:else
img))
(defmacro image
(defmacro texture
[img & options]
`(create-entity (utils/calls! ^TextureRegion (image* ~img) ~@options)))
`(u/create-entity (u/calls! ^TextureRegion (texture* ~img) ~@options)))
(defmacro animation
[duration images & args]
[duration textures & args]
`(Animation. ~duration
(utils/gdx-into-array (map :object ~images))
(utils/gdx-static-field :graphics :g2d :Animation
~(or (first args) :normal))))
(u/gdx-into-array (map :object ~textures))
(u/gdx-static-field :graphics :g2d :Animation
~(or (first args) :normal))))
(defn animation-image
([screen ^Animation animation]
(create-entity (.getKeyFrame animation (:total-time screen) true)))
([screen ^Animation animation is-looping?]
(create-entity (.getKeyFrame animation (:total-time screen) is-looping?))))
(defn animation-texture
([{:keys [total-time]} ^Animation animation]
(u/create-entity (.getKeyFrame animation total-time true)))
([{:keys [total-time]} ^Animation animation is-looping?]
(u/create-entity (.getKeyFrame animation total-time is-looping?))))
; interop
(defmacro texture!
[entity k & options]
`(u/call! ^TextureRegion (:object ~entity) ~k ~@options))

View File

@@ -10,3 +10,7 @@
(defmethod renderer :stage [_]
(Stage.))
(defmacro label
[& args]
`(ui/label ~@args))

View File

@@ -13,37 +13,62 @@
(defmacro color
[& args]
`~(if (keyword? (first args))
`(Color. ^Color (utils/gdx-static-field :graphics :Color ~(first args)))
`(Color. ^Color (u/gdx-static-field :graphics :Color ~(first args)))
`(Color. ~@args)))
(defmacro bitmap-font
[& options]
`(BitmapFont. ~@options))
; interop
(defmacro app!
[k & options]
`(u/call! ^Application (Gdx/app) ~k ~@options))
(defmacro audio!
[k & options]
`(u/call! ^Audio (Gdx/audio) ~k ~@options))
(defmacro files!
[k & options]
`(u/call! ^Files (Gdx/files) ~k ~@options))
(defmacro gl!
[k & options]
`(u/call! ^GL20 (Gdx/gl20) ~k ~@options))
(defmacro graphics!
[k & options]
`(u/call! ^Graphics (Gdx/graphics) ~k ~@options))
(defmacro input!
[k & options]
`(u/call! ^Input (Gdx/input) ~k ~@options))
(defmacro net!
[k & options]
`(u/call! ^Net (Gdx/net) ~k ~@options))
; input/output
(defn game
[key]
(case key
:width (.getWidth ^Graphics (Gdx/graphics))
:height (.getHeight ^Graphics (Gdx/graphics))
:fps (.getFramesPerSecond ^Graphics (Gdx/graphics))
:is-fullscreen? (.isFullscreen ^Graphics (Gdx/graphics))
:is-touched? (.isTouched ^Input (Gdx/input))
:x (.getX ^Input (Gdx/input))
:y (.getY ^Input (Gdx/input))
:width (graphics! :get-width)
:height (graphics! :get-height)
:fps (graphics! :get-frames-per-second)
:is-fullscreen? (graphics! :is-fullscreen)
:is-touched? (input! :is-touched)
:x (input! :get-x)
:y (input! :get-y)
nil))
(defmacro key-code
[key]
`~(symbol
(str utils/gdx-package ".Input$Keys/" (utils/key->static-field key))))
`~(symbol (str u/gdx-package ".Input$Keys/" (u/key->static-field key))))
(defmacro is-pressed?
[key]
`(.isKeyPressed ^Input (Gdx/input) (key-code ~key)))
`(input! :is-key-pressed (key-code ~key)))
(defn- input-processor
(defn ^:private input-processor
[{:keys [on-key-down on-key-typed on-key-up on-mouse-moved
on-scrolled on-touch-down on-touch-dragged on-touch-up]}
execute-fn!]
@@ -73,7 +98,7 @@
(execute-fn! on-touch-up :screen-x sx :screen-y sy :pointer p :button b)
false)))
(defn- gesture-listener
(defn ^:private gesture-listener
[{:keys [on-fling on-long-press on-pan on-pan-stop on-pinch on-tap on-zoom]}
execute-fn!]
(reify GestureDetector$GestureListener
@@ -103,10 +128,10 @@
(execute-fn! on-zoom :initial-distance id :distance d)
false)))
(defn- gesture-detector
(defn ^:private gesture-detector
[options execute-fn!]
(proxy [GestureDetector] [(gesture-listener options execute-fn!)]))
(defn- add-input!
(defn ^:private add-input!
[^InputProcessor p]
(.addProcessor ^InputMultiplexer (.getInputProcessor (Gdx/input)) p))
(.addProcessor ^InputMultiplexer (input! :get-input-processor) p))

View File

@@ -1,102 +0,0 @@
(in-ns 'play-clj.core)
; 2d
(defmacro image!
[entity k & options]
`(utils/call! ^TextureRegion (:object ~entity) ~k ~@options))
; render
(defmacro orthogonal-tiled-map!
[screen k & options]
`(utils/call! ^OrthogonalTiledMapRenderer (:renderer ~screen) ~k ~@options))
(defmacro isometric-tiled-map!
[screen k & options]
`(utils/call! ^IsometricTiledMapRenderer (:renderer ~screen) ~k ~@options))
(defmacro isometric-staggered-tiled-map!
[screen k & options]
`(utils/call! ^IsometricStaggeredTiledMapRenderer (:renderer ~screen)
~k ~@options))
(defmacro hexagonal-tiled-map!
[screen k & options]
`(utils/call! ^HexagonalTiledMapRenderer (:renderer ~screen) ~k ~@options))
(defmacro stage!
[screen k & options]
`(utils/call! ^Stage (:renderer ~screen) ~k ~@options))
(defmacro orthographic-camera!
[screen k & options]
`(utils/call! ^OrthographicCamera (:camera ~screen) ~k ~@options))
(defmacro perspective-camera!
[screen k & options]
`(utils/call! ^PerspectiveCamera (:camera ~screen) ~k ~@options))
; global
(defmacro app!
[k & options]
`(utils/call! ^Application (Gdx/app) ~k ~@options))
(defmacro audio!
[k & options]
`(utils/call! ^Audio (Gdx/audio) ~k ~@options))
(defmacro files!
[k & options]
`(utils/call! ^Files (Gdx/files) ~k ~@options))
(defmacro gl!
[k & options]
`(utils/call! ^GL20 (Gdx/gl20) ~k ~@options))
(defmacro graphics!
[k & options]
`(utils/call! ^Graphics (Gdx/graphics) ~k ~@options))
(defmacro input!
[k & options]
`(utils/call! ^Input (Gdx/input) ~k ~@options))
(defmacro net!
[k & options]
`(utils/call! ^Net (Gdx/net) ~k ~@options))
; ui
(defmacro check-box!
[entity k & options]
`(utils/call! ^Checkbox (:object ~entity) ~k ~@options))
(defmacro image-button!
[entity k & options]
`(utils/call! ^ImageButton (:object ~entity) ~k ~@options))
(defmacro image-text-button!
[entity k & options]
`(utils/call! ^ImageTextButton (:object ~entity) ~k ~@options))
(defmacro label!
[entity k & options]
`(utils/call! ^Label (:object ~entity) ~k ~@options))
(defmacro slider!
[entity k & options]
`(utils/call! ^Slider (:object ~entity) ~k ~@options))
(defmacro text-button!
[entity k & options]
`(utils/call! ^TextButton (:object ~entity) ~k ~@options))
(defmacro text-field!
[entity k & options]
`(utils/call! ^TextField (:object ~entity) ~k ~@options))
(defmacro dialog!
[entity k & options]
`(utils/call! ^Dialog (:object ~entity) ~k ~@options))

View File

@@ -91,3 +91,34 @@
(when x (set! (. (. camera position) x) x))
(when y (set! (. (. camera position) y) y))
(.update camera))
; interop
(defmacro orthogonal-tiled-map!
[screen k & options]
`(u/call! ^OrthogonalTiledMapRenderer (:renderer ~screen) ~k ~@options))
(defmacro isometric-tiled-map!
[screen k & options]
`(u/call! ^IsometricTiledMapRenderer (:renderer ~screen) ~k ~@options))
(defmacro isometric-staggered-tiled-map!
[screen k & options]
`(u/call! ^IsometricStaggeredTiledMapRenderer (:renderer ~screen)
~k ~@options))
(defmacro hexagonal-tiled-map!
[screen k & options]
`(u/call! ^HexagonalTiledMapRenderer (:renderer ~screen) ~k ~@options))
(defmacro stage!
[screen k & options]
`(u/call! ^Stage (:renderer ~screen) ~k ~@options))
(defmacro orthographic-camera!
[screen k & options]
`(u/call! ^OrthographicCamera (:camera ~screen) ~k ~@options))
(defmacro perspective-camera!
[screen k & options]
`(u/call! ^PerspectiveCamera (:camera ~screen) ~k ~@options))

View File

@@ -1,21 +1,36 @@
(in-ns 'play-clj.core)
(defmacro style
[type & options]
`(~(symbol (str utils/gdx-package ".scenes.scene2d.ui."
(utils/key->class type) "$"
(utils/key->class type) "Style."))
~@options))
(ns play-clj.ui
(:require [play-clj.utils :as u])
(:import [com.badlogic.gdx Files Gdx]
[com.badlogic.gdx.graphics Color Texture]
[com.badlogic.gdx.graphics.g2d BitmapFont TextureRegion]
[com.badlogic.gdx.scenes.scene2d Actor Stage]
[com.badlogic.gdx.scenes.scene2d.ui ButtonGroup CheckBox Dialog Image
ImageButton ImageTextButton Label Skin Slider TextButton TextField]
[com.badlogic.gdx.scenes.scene2d.utils ActorGestureListener
ChangeListener ClickListener DragListener FocusListener
NinePatchDrawable SpriteDrawable TextureRegionDrawable
TiledDrawable]))
(defmacro drawable
[type & options]
`(~(symbol (str utils/gdx-package ".scenes.scene2d.utils."
(utils/key->class type) "Drawable."))
`(~(symbol (str u/gdx-package ".scenes.scene2d.u."
(u/key->class type) "Drawable."))
~@options))
(defmacro bitmap-font
[& options]
`(BitmapFont. ~@options))
(defmacro style
[type & options]
`(~(symbol (str u/gdx-package ".scenes.scene2d.ui."
(u/key->class type) "$"
(u/key->class type) "Style."))
~@options))
(defmacro skin
[path & options]
`(utils/calls! ^Skin (Skin. (files! :internal ~path)) ~@options))
`(u/calls! ^Skin (Skin. (.internal ^Files (Gdx/files) ~path)) ~@options))
; widgets
@@ -25,7 +40,21 @@
(defmacro check-box
[text arg & options]
`(create-entity (utils/calls! ^CheckBox (check-box* ~text ~arg) ~@options)))
`(u/create-entity (u/calls! ^CheckBox (check-box* ~text ~arg) ~@options)))
(defn image*
[arg]
(cond
(map? arg)
(Image. ^TextureRegion (:object arg))
(string? arg)
(Image. (Texture. arg))
:else
(Image. arg)))
(defmacro image
[arg & options]
`(u/create-entity (u/calls! ^Image (image* ~arg) ~@options)))
(defn image-button*
[arg]
@@ -33,7 +62,7 @@
(defmacro image-button
[arg & options]
`(create-entity (utils/calls! ^ImageButton (image-button* ~arg) ~@options)))
`(u/create-entity (u/calls! ^ImageButton (image-button* ~arg) ~@options)))
(defn image-text-button*
[^String text arg]
@@ -41,8 +70,8 @@
(defmacro image-text-button
[text arg & options]
`(create-entity
(utils/calls! ^ImageTextButton (image-text-button* ~text ~arg) ~@options)))
`(u/create-entity (u/calls! ^ImageTextButton (image-text-button* ~text ~arg)
~@options)))
(defn label*
[^String text arg]
@@ -52,7 +81,7 @@
(defmacro label
[text arg & options]
`(create-entity (utils/calls! ^Label (label* ~text ~arg) ~@options)))
`(u/create-entity (u/calls! ^Label (label* ~text ~arg) ~@options)))
(defn slider*
[min max step is-vert? arg]
@@ -60,8 +89,8 @@
(defmacro slider
[min max step is-vert? arg & options]
`(create-entity
(utils/calls! ^Slider (slider* ~min ~max ~step ~is-vert? ~arg) ~@options)))
`(u/create-entity (u/calls! ^Slider (slider* ~min ~max ~step ~is-vert? ~arg)
~@options)))
(defn text-button*
[^String text arg]
@@ -69,8 +98,7 @@
(defmacro text-button
[text arg & options]
`(create-entity
(utils/calls! ^TextButton (text-button* ~text ~arg) ~@options)))
`(u/create-entity (u/calls! ^TextButton (text-button* ~text ~arg) ~@options)))
(defn text-field*
[^String text arg]
@@ -78,7 +106,7 @@
(defmacro text-field
[text arg & options]
`(create-entity (utils/calls! ^TextField (text-field* ~text ~arg) ~@options)))
`(u/create-entity (u/calls! ^TextField (text-field* ~text ~arg) ~@options)))
(defn dialog*
[text arg]
@@ -86,23 +114,11 @@
(defmacro dialog
[text arg & options]
`(create-entity (utils/calls! ^Dialog (dialog* ~text ~arg) ~@options)))
`(u/create-entity (u/calls! ^Dialog (dialog* ~text ~arg) ~@options)))
; listeners
(defn ui-listen!
[{:keys [renderer ui-listeners] :as screen} entities]
(assert (isa? (type renderer) Stage))
(add-input! renderer)
(stage! screen :clear)
(doseq [{:keys [object]} entities]
(when (isa? (type object) Actor)
(stage! screen :add-actor object)
(doseq [listener ui-listeners]
(.addListener ^Actor object listener))))
entities)
(defn- ui-gesture-listener
(defn ^:private gesture-listener
[{:keys [on-ui-fling on-ui-long-press on-ui-pan on-ui-pinch
on-ui-tap on-ui-touch-down on-ui-touch-up on-ui-zoom]}
execute-fn!]
@@ -128,13 +144,13 @@
(zoom [e id d]
(execute-fn! on-ui-zoom :event e :initial-distance id :distance d))))
(defn- ui-change-listener
(defn ^:private change-listener
[{:keys [on-ui-changed]} execute-fn!]
(proxy [ChangeListener] []
(changed [e a]
(execute-fn! on-ui-changed :event e :actor a))))
(defn- ui-click-listener
(defn ^:private click-listener
[{:keys [on-ui-clicked on-ui-enter on-ui-exit
on-ui-touch-down on-ui-touch-dragged on-ui-touch-up]}
execute-fn!]
@@ -153,7 +169,7 @@
(touchUp [e x y p b]
(execute-fn! on-ui-touch-up :event e :x x :y y :pointer p :button b))))
(defn- ui-drag-listener
(defn ^:private drag-listener
[{:keys [on-ui-drag on-ui-drag-start on-ui-drag-stop
on-ui-touch-down on-ui-touch-dragged on-ui-touch-up]}
execute-fn!]
@@ -172,7 +188,7 @@
(dragStop [e x y p]
(execute-fn! on-ui-drag-stop :event e :x x :y y :pointer p))))
(defn- ui-focus-listener
(defn ^:private focus-listener
[{:keys [on-ui-keyboard-focus-changed on-ui-scroll-focus-changed]}
execute-fn!]
(proxy [FocusListener] []
@@ -180,3 +196,45 @@
(execute-fn! on-ui-keyboard-focus-changed :event e :actor a :focused? f))
(scrollFocusChanged [e a f]
(execute-fn! on-ui-scroll-focus-changed :event e :actor a :focused? f))))
(defn listeners
[options execute-fn!]
[(gesture-listener options execute-fn!)
(change-listener options execute-fn!)
(click-listener options execute-fn!)
(drag-listener options execute-fn!)
(focus-listener options execute-fn!)])
; interop
(defmacro check-box!
[entity k & options]
`(u/call! ^Checkbox (:object ~entity) ~k ~@options))
(defmacro image-button!
[entity k & options]
`(u/call! ^ImageButton (:object ~entity) ~k ~@options))
(defmacro image-text-button!
[entity k & options]
`(u/call! ^ImageTextButton (:object ~entity) ~k ~@options))
(defmacro label!
[entity k & options]
`(u/call! ^Label (:object ~entity) ~k ~@options))
(defmacro slider!
[entity k & options]
`(u/call! ^Slider (:object ~entity) ~k ~@options))
(defmacro text-button!
[entity k & options]
`(u/call! ^TextButton (:object ~entity) ~k ~@options))
(defmacro text-field!
[entity k & options]
`(u/call! ^TextField (:object ~entity) ~k ~@options))
(defmacro dialog!
[entity k & options]
`(u/call! ^Dialog (:object ~entity) ~k ~@options))

View File

@@ -1,14 +1,16 @@
(ns play-clj.utils
(:require [clojure.string :as s])
(:import [com.badlogic.gdx.utils Array]))
(:import [com.badlogic.gdx.graphics.g2d TextureRegion]
[com.badlogic.gdx.utils Array]
[com.badlogic.gdx.scenes.scene2d Actor]))
(def ^:const gdx-package "com.badlogic.gdx")
(defn- split-key
(defn ^:private split-key
[key]
(-> key name (s/split #"-")))
(defn- join-keys
(defn ^:private join-keys
[keys]
(->> keys (map name) (s/join ".") (str gdx-package ".")))
@@ -61,3 +63,13 @@
(defmacro calls!
[obj & {:keys [] :as args}]
`(doto ~obj ~@(map calls!* args)))
(defmulti create-entity class)
(defmethod create-entity TextureRegion
[obj]
{:type :texture :object obj})
(defmethod create-entity Actor
[obj]
{:type :actor :object obj})