From 4bc1ce6856ee258680c68dadad37e8cb9a1d2d51 Mon Sep 17 00:00:00 2001 From: oakes Date: Tue, 21 Jan 2014 19:11:12 -0500 Subject: [PATCH] Add docstrings to ui and utils --- src/play_clj/ui.clj | 191 ++++++++++++++++++++++++++++++++++++----- src/play_clj/utils.clj | 46 +++++++++- 2 files changed, 216 insertions(+), 21 deletions(-) diff --git a/src/play_clj/ui.clj b/src/play_clj/ui.clj index b4e5399..9f805c8 100644 --- a/src/play_clj/ui.clj +++ b/src/play_clj/ui.clj @@ -14,27 +14,40 @@ [com.esotericsoftware.tablelayout Cell])) (defmacro drawable - [type & options] + "Internal use only" + [k & options] `(~(symbol (str u/main-package ".scenes.scene2d.ui." - (u/key->pascal type) "Drawable.")) + (u/key->pascal k) "Drawable.")) ~@options)) (defmacro style - [type & options] + "Returns a style object based on the keyword `k` + + (style :check-box)" + [k & options] `(~(symbol (str u/main-package ".scenes.scene2d.ui." - (u/key->pascal type) "$" - (u/key->pascal type) "Style.")) + (u/key->pascal k) "$" + (u/key->pascal k) "Style.")) ~@options)) (defmacro skin + "Returns a [Skin](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/Skin.html) +based on the file at `path` + + (skin \"uiskin.json\")" [path & options] `(u/calls! ^Skin (Skin. (.internal ^Files (Gdx/files) ~path)) ~@options)) (defmacro align - [key] - `(u/static-field-lower :scenes :scene2d :utils :Align ~key)) + "Returns a static field from [Align](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/utils/Align.html) + + (align :center)" + [k] + `(u/static-field-lower :scenes :scene2d :utils :Align ~k)) (defn cell! + "Calls a single method on a [Cell](https://github.com/libgdx/libgdx/blob/master/gdx/src/com/esotericsoftware/tablelayout/Cell.java) +(this could probably be made into a macro...)" [^Cell cell & args] (let [method (first args) [[a1 a2 a3 a4] rest-args] (split-with #(not (keyword? %)) (rest args))] @@ -81,7 +94,22 @@ (apply cell! cell rest-args)) cell)) -(defmulti add-to-group! #(-> % first :object type) :default WidgetGroup) +(defmulti add-to-group! + "Internal use only" + #(-> % first :object type) :default WidgetGroup) + +(defn ^:private create-tree-node + "Internal use only" + [child] + {:object (Tree$Node. ^Actor (:object child))}) + +(defn ^:private add-tree-nodes + "Internal use only" + [parent children] + (when-let [node (add-to-group! [parent (first children)])] + (doseq [child (rest children)] + (add-to-group! [node child])) + node)) (defmethod add-to-group! WidgetGroup [[parent child]] @@ -99,17 +127,6 @@ :row (.row ^Table (:object parent)) (u/throw-key-not-found child)))) -(defn ^:private create-tree-node - [child] - {:object (Tree$Node. ^Actor (:object child))}) - -(defn ^:private add-tree-nodes - [parent children] - (when-let [node (add-to-group! [parent (first children)])] - (doseq [child (rest children)] - (add-to-group! [node child])) - node)) - (defmethod add-to-group! Tree [[parent child]] (cond @@ -131,60 +148,86 @@ (add-tree-nodes parent child))) (defn add! + "Adds the entities in `children` to the `group` entity of type [WidgetGroup](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/WidgetGroup.html)" [group & children] (doseq [child children] (add-to-group! [group child])) group) (defn ^:private create-group + "Internal use only" [^WidgetGroup group children] (apply add! (u/create-entity group) children)) -; widgets +; check-box (defn check-box* + "The function version of `check-box`" [^String text arg] (u/create-entity (CheckBox. text arg))) (defmacro check-box + "Returns an entity based on [CheckBox](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/CheckBox.html) + + (check-box \"I'm a check box\" (style :check-box off on font color)) + (check-box \"I'm a check box\" (skin \"uiskin.json\"))" [text arg & options] `(let [entity# (check-box* ~text ~arg)] (u/calls! ^CheckBox (u/get-obj entity# :object) ~@options) entity#)) (defmacro check-box! + "Calls a single method on a `check-box`" [entity k & options] `(u/call! ^Checkbox (u/get-obj ~entity :object) ~k ~@options)) +; dialog + (defn dialog* + "The function version of `dialog`" [text arg] (u/create-entity (Dialog. text arg))) (defmacro dialog + "Returns an entity based on [Dialog](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/Dialog.html) + + (dialog \"I'm a dialog\" (style :window font font-color background)) + (dialog \"I'm a dialog\" (skin \"uiskin.json\"))" [text arg & options] `(let [entity# (dialog* ~text ~arg)] (u/calls! ^Dialog (u/get-obj entity# :object) ~@options) entity#)) (defmacro dialog! + "Calls a single method on a `dialog`" [entity k & options] `(u/call! ^Dialog (u/get-obj ~entity :object) ~k ~@options)) +; horizontal + (defn horizontal* + "The function version of `horizontal`" [children] (create-group (HorizontalGroup.) children)) (defmacro horizontal + "Returns an entity based on [HorizontalGroup](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/HorizontalGroup.html) + + (horizontal [entity-1 entity-2])" [children & options] `(let [entity# (horizontal* ~children)] (u/calls! ^HorizontalGroup (u/get-obj entity# :object) ~@options) entity#)) (defmacro horizontal! + "Calls a single method on a `horizontal`" [entity k & options] `(u/call! ^HorizontalGroup (u/get-obj ~entity :object) ~k ~@options)) +; image + (defn image* + "The function version of `image`" [arg] (u/create-entity (cond @@ -196,44 +239,68 @@ (Image. arg)))) (defmacro image + "Returns an entity based on [Image](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/Image.html) + + (image \"image.png\")" [arg & options] `(let [entity# (image* ~arg)] (u/calls! ^Image (u/get-obj entity# :object) ~@options) entity#)) (defmacro image! + "Calls a single method on a `image`" [entity k & options] `(u/call! ^Image (u/get-obj ~entity :object) ~k ~@options)) +; image-button + (defn image-button* + "The function version of `image-button`" [arg] (u/create-entity (ImageButton. arg))) (defmacro image-button + "Returns an entity based on [ImageButton](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/ImageButton.html) + + (image-button (style :image-button up dn check img-up img-dn img-check)) + (image-button (skin \"uiskin.json\"))" [arg & options] `(let [entity# (image-button* ~arg)] (u/calls! ^ImageButton (u/get-obj entity# :object) ~@options) entity#)) (defmacro image-button! + "Calls a single method on a `image-button`" [entity k & options] `(u/call! ^ImageButton (u/get-obj ~entity :object) ~k ~@options)) +; image-text-button + (defn image-text-button* + "The function version of `image-text-button`" [^String text arg] (u/create-entity (ImageTextButton. text arg))) (defmacro image-text-button + "Returns an entity based on [ImageTextButton](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/ImageTextButton.html) + + (image-text-button \"I'm an image text button\" + (style :image-text-button up down checked font)) + (image-text-button \"I'm an image text button\" (skin \"uiskin.json\"))" [text arg & options] `(let [entity# (image-text-button* ~text ~arg)] (u/calls! ^ImageTextButton (u/get-obj entity# :object) ~@options) entity#)) (defmacro image-text-button! + "Calls a single method on a `image-text-button`" [entity k & options] `(u/call! ^ImageTextButton (u/get-obj ~entity :object) ~k ~@options)) +; label + (defn label* + "The function version of `label`" [^String text arg] (u/create-entity (if (isa? (type arg) Color) @@ -241,44 +308,70 @@ (Label. text arg)))) (defmacro label + "Returns an entity based on [Label](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/Label.html) + + (label \"I'm a label\" (color :white)) + (label \"I'm a label\" (style :label (g2d/bitmap-font) (color :white))) + (label \"I'm a label\" (skin \"uiskin.json\"))" [text arg & options] `(let [entity# (label* ~text ~arg)] (u/calls! ^Label (u/get-obj entity# :object) ~@options) entity#)) (defmacro label! + "Calls a single method on a `label`" [entity k & options] `(u/call! ^Label (u/get-obj ~entity :object) ~k ~@options)) +; scroll-pane + (defn scroll-pane* + "The function version of `scroll-pane`" [child arg] (u/create-entity (ScrollPane. (u/get-obj child :object) arg))) (defmacro scroll-pane + "Returns an entity based on [ScrollPane](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/ScrollPane.html) + + (scroll-pane table-entity (style :scroll-pane back h h-knob v v-knob)) + (scroll-pane table-entity (skin \"uiskin.json\"))" [child arg & options] `(let [entity# (scroll-pane* ~child ~arg)] (u/calls! ^ScrollPane (u/get-obj entity# :object) ~@options) entity#)) (defmacro scroll-pane! + "Calls a single method on a `scroll-pane`" [entity k & options] `(u/call! ^ScrollPane (u/get-obj ~entity :object) ~k ~@options)) +; select-box + (defn select-box* + "The function version of `select-box`" [items arg] (u/create-entity (SelectBox. (into-array items) arg))) (defmacro select-box + "Returns an entity based on [SelectBox](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/SelectBox.html) + + (select-box [\"Item 1\" \"Item 2\" \"Item 3\"] + (style :select-box font color back scroll-style list-style)) + (select-box [\"Item 1\" \"Item 2\" \"Item 3\"] (skin \"uiskin.json\"))" [items arg & options] `(let [entity# (select-box* ~items ~arg)] (u/calls! ^SelectBox (u/get-obj entity# :object) ~@options) entity#)) (defmacro select-box! + "Calls a single method on a `select-box`" [entity k & options] `(u/call! ^SelectBox (u/get-obj ~entity :object) ~k ~@options)) +; slider + (defn slider* + "The function version of `slider`" [{:keys [min max step vertical?] :or {min 0 max 10 step 1 vertical? false}} arg] @@ -286,109 +379,167 @@ (Slider. (float min) (float max) (float step) vertical? arg))) (defmacro slider + "Returns an entity based on [Slider](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/Slider.html) + + (slider {:min 0 :max 10 :step 1 :vertical? false} (style :slider back knob)) + (slider {:min 0 :max 10 :step 1 :vertical? false} (skin \"uiskin.json\"))" [attrs arg & options] `(let [entity# (slider* ~attrs ~arg)] (u/calls! ^Slider (u/get-obj entity# :object) ~@options) entity#)) (defmacro slider! + "Calls a single method on a `slider`" [entity k & options] `(u/call! ^Slider (u/get-obj ~entity :object) ~k ~@options)) +; stack + (defn stack* + "The function version of `stack`" [children] (create-group (Stack.) children)) (defmacro stack + "Returns an entity based on [Stack](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/Stack.html) + + (stack [entity-1 entity-2])" [children & options] `(let [entity# (stack* ~children)] (u/calls! ^Stack (u/get-obj entity# :object) ~@options) entity#)) (defmacro stack! + "Calls a single method on a `stack`" [entity k & options] `(u/call! ^Stack (u/get-obj ~entity :object) ~k ~@options)) +; table + (defn table* + "The function version of `table`" [children] (create-group (Table.) children)) (defmacro table + "Returns an entity based on [Table](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/Table.html) + + (table [entity-1 entity-2])" [children & options] `(let [entity# (table* ~children)] (u/calls! ^Table (u/get-obj entity# :object) ~@options) entity#)) (defmacro table! + "Calls a single method on a `table`" [entity k & options] `(u/call! ^Table (u/get-obj ~entity :object) ~k ~@options)) +; text-button + (defn text-button* + "The function version of `text-button`" [^String text arg] (u/create-entity (TextButton. text arg))) (defmacro text-button + "Returns an entity based on [TextButton](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/TextButton.html) + + (text-button \"I'm a text button\" (style :text-button up dn checked font)) + (text-button \"I'm a text button\" (skin \"uiskin.json\"))" [text arg & options] `(let [entity# (text-button* ~text ~arg)] (u/calls! ^TextButton (u/get-obj entity# :object) ~@options) entity#)) (defmacro text-button! + "Calls a single method on a `text-button`" [entity k & options] `(u/call! ^TextButton (u/get-obj ~entity :object) ~k ~@options)) +; text-field + (defn text-field* + "The function version of `text-field`" [^String text arg] (u/create-entity (TextField. text arg))) (defmacro text-field + "Returns an entity based on [TextField](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/TextField.html) + + (text-field \"I'm a text field\" (style :text-field font col cur sel back)) + (text-field \"I'm a text field\" (skin \"uiskin.json\"))" [text arg & options] `(let [entity# (text-field* ~text ~arg)] (u/calls! ^TextField (u/get-obj entity# :object) ~@options) entity#)) (defmacro text-field! + "Calls a single method on a `text-field`" [entity k & options] `(u/call! ^TextField (u/get-obj ~entity :object) ~k ~@options)) +; tree + (defn tree* + "The function version of `tree`" [children arg] (create-group (Tree. arg) children)) (defmacro tree + "Returns an entity based on [Tree](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/Tree.html) + + (tree [entity-1 entity-2] (style :tree plus minus selection)) + (tree [entity-1 entity-2] (skin \"uiskin.json\"))" [children arg & options] `(let [entity# (tree* ~children ~arg)] (u/calls! ^Tree (u/get-obj entity# :object) ~@options) entity#)) (defmacro tree! + "Calls a single method on a `tree`" [entity k & options] `(u/call! ^Tree (u/get-obj ~entity :object) ~k ~@options)) +; vertical + (defn vertical* + "The function version of `vertical`" [children] (create-group (VerticalGroup.) children)) (defmacro vertical + "Returns an entity based on [VerticalGroup](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/VerticalGroup.html) + + (vertical [entity-1 entity-2])" [children & options] `(let [entity# (vertical* ~children)] (u/calls! ^VerticalGroup (u/get-obj entity# :object) ~@options) entity#)) (defmacro vertical! + "Calls a single method on a `vertical`" [entity k & options] `(u/call! ^VerticalGroup (u/get-obj ~entity :object) ~k ~@options)) +; window + (defn window* + "The function version of `window`" [children ^String title arg] (create-group (Window. title arg) children)) (defmacro window + "Returns an entity based on [Window](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/Window.html) + + (window [entity-1 entity-2] \"I'm a window\" (style :window title font col)) + (window [entity-1 entity-2] \"I'm a window\" (skin \"uiskin.json\"))" [children title arg & options] `(let [entity# (window* ~children ~title ~arg)] (u/calls! ^Window (u/get-obj entity# :object) ~@options) entity#)) (defmacro window! + "Calls a single method on a `window`" [entity k & options] `(u/call! ^Window (u/get-obj ~entity :object) ~k ~@options)) diff --git a/src/play_clj/utils.clj b/src/play_clj/utils.clj index d827826..5523886 100644 --- a/src/play_clj/utils.clj +++ b/src/play_clj/utils.clj @@ -7,10 +7,12 @@ ; misc (defn throw-key-not-found + "Internal use only" [k] (throw (Exception. (str "The keyword " k " is not found.")))) (defn get-obj + "Internal use only" [obj k] (if (map? obj) (or (get obj k) @@ -22,26 +24,31 @@ (def ^:const main-package "com.badlogic.gdx") (defn ^:private split-key + "Internal use only" [k] (-> k name (s/split #"-"))) (defn ^:private join-keys + "Internal use only" [k-list] (->> k-list (map name) (s/join ".") (str main-package "."))) (defn key->upper + "Returns a string based on keyword `k` with upper case and underscores" [k] (->> (split-key k) (map s/upper-case) (s/join "_"))) (defn key->pascal + "Returns a string based on keyword `k` with pascal case and no delimiters" [k] (->> (split-key k) (map s/capitalize) (s/join ""))) (defn key->camel + "Returns a string based on keyword `k` with camel case and no delimiters" [k] (let [parts (split-key k)] (->> (rest parts) @@ -50,36 +57,48 @@ (s/join "")))) (defn key->method + "Returns a symbol based on keyword `k` formatted as a method call" [k] (symbol (str "." (key->camel k)))) ; static methods/fields (defn static-symbol + "Returns a fully-qualified static method or field based on `args` whose last +item is formatted with `transform-fn`" [args transform-fn] (->> (transform-fn (last args)) (str (join-keys (butlast args)) "/") symbol)) (defmacro static-field-lower + "Returns a fully-qualified static method or field whose last item is formatted +in camel case" [& args] `~(static-symbol args key->camel)) (defmacro static-field-upper + "Returns a fully-qualified static method or field whose last item is formatted +in upper case" [& args] `~(static-symbol args key->upper)) (defmacro scaling + "Internal use only" [k] `(static-field-lower :utils :Scaling ~k)) ; java interop (defmacro call! + "Calls method `k` of `obj` with `args` + + (call! \"I'm a string\" :index-of \"s\")" [obj k & args] `(~(key->method k) ~obj ~@args)) (defn create-method-calls + "Internal use only" [calls args] (let [method-name (first args) [my-args rest-args] (split-with #(not (keyword? %)) (rest args))] @@ -89,16 +108,29 @@ calls))) (defmacro calls! + "Calls methods on `obj` + + (calls! (java.util.ArrayList.) :add \"I'm a string\" :add \"So am I\")" [obj & args] `(doto ~obj ~@(create-method-calls [] args))) (defn create-field-setters + "Internal use only" [obj {:keys [] :as args}] (map (fn [[k v]] `(set! (. ~obj ~(symbol (key->camel k))) ~v)) args)) (defmacro fields! + "Sets fields on `obj` (it is important that `obj` is a symbol, because when +the macro expands it will use it several times, and you probably don't want a +new object to be created each time a field is set) + + (fields! obj + :active true + :angle 2 + :awake true + :fixed-rotation false)" [obj & args] `(do ~@(create-field-setters obj args) ~obj)) @@ -106,18 +138,24 @@ ; data structures (defn gdx-array* + "The function version of `gdx-array`" [clj-arr] (Array. true (into-array clj-arr) 1 (count clj-arr))) (defmacro gdx-array + "Returns an [Array](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/Array.html) + + (gdx-array [1 2 3 4])" [clj-arr & options] `(calls! ^Array (gdx-array* ~clj-arr) ~@options)) (defmacro gdx-array! + "Calls a single method on `gdx-array`" [object k & options] `(call! ^Array ~object ~k ~@options)) (defn gdx-array-map* + "The function version of `gdx-array-map`" [clj-map] (let [gdx-map (ArrayMap.)] (doseq [[k v] clj-map] @@ -125,16 +163,22 @@ gdx-map)) (defmacro gdx-array-map + "Returns an [ArrayMap](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/ArrayMap.html) + + (gdx-array-map {:key-1 1 :key-2 2})" [clj-map & options] `(calls! ^ArrayMap (gdx-array-map* ~clj-map) ~@options)) (defmacro gdx-array-map! + "Calls a single method on `gdx-array-map`" [object k & options] `(call! ^ArrayMap ~object ~k ~@options)) ; entities -(defmulti create-entity class) +(defmulti create-entity + "Internal use only" + class) (defmethod create-entity TextureRegion [obj]