Permalink
Browse files

Merge pull request #15 from samaaron/hacking

Clean up applet semantics
  • Loading branch information...
2 parents e1a45b4 + 3f6a3e5 commit 935a65c9adaa05a1fda2eb827ce70de517a508b9 @rosado committed Feb 21, 2012
Showing with 142 additions and 92 deletions.
  1. +1 −0 .gitignore
  2. +4 −3 src/processing/core.clj
  3. +137 −89 src/processing/core/applet.clj
View
@@ -4,3 +4,4 @@ classes/
pom-generated.xml
pom.xml
native
+.cake
View
@@ -1265,9 +1265,10 @@
(PApplet/sin (float angle)))
(defn size
- "Defines the dimension of the display window in units of pixels."
- ([width height] (.size *applet* (int width) (int height)))
- ([width height ^String renderer] (.size *applet* (int width) (int height) renderer)))
+ "Not supported. Use :size key in applet or defapplet"
+ [& args]
+ (println "Deprecated - size should be specified as a :size key to applet or defapplet")
+ nil)
;; $$sketchFile
;; $$sketchPath
@@ -14,106 +14,154 @@
mname)]
[(keyword fixed-name) fun]))
-(defmacro defapplet
- "Define an applet. Takes an app-name and a map of options."
- [app-name & opts]
- (let [options (assoc (apply hash-map opts) :name (str app-name))
- fns (dissoc options :name :title :size :key-pressed :key-released :mouse-pressed :mouse-released)
- fns (into {} (map (fn [[k v]] [k (if (symbol? v) `(var ~v) v)]) fns))
- fns (merge {:draw (fn [] nil)} fns)
- key-pressed-fn (or (:key-pressed options)
- (fn [] nil))
- key-released-fn (or (:key-released options)
- (fn [] nil))
- mouse-pressed-fn (or (:mouse-pressed options)
- (fn [] nil))
- mouse-released-fn (or (:mouse-released options)
- (fn [] nil))
- methods (into {} (map fix-mname fns))]
- `(def ~app-name
- (let [frame# (atom nil)
- state# (atom nil)
- prx# (proxy [processing.core.PApplet
- clojure.lang.IMeta] []
- (meta [] (assoc ~options :frame frame#))
- (keyPressed
- ([] (binding [*applet* ~'this
- *state* state#]
- (~key-pressed-fn)))
- ([e#]
- (proxy-super keyPressed e#)))
- (keyReleased
- ([] (binding [*applet* ~'this
- *state* state#]
- (~key-released-fn)))
- ([e#]
- (proxy-super keyReleased e#)))
- (mousePressed
- ([] (binding [*applet* ~'this
- *state* state#]
- (~mouse-pressed-fn)))
- ([e#]
- (proxy-super mousePressed e#)))
- (mouseReleased
- ([] (binding [*applet* ~'this
- *state* state#]
- (~mouse-released-fn)))
- ([e#]
- (proxy-super mouseReleased e#))))
-
- bound-meths# (reduce (fn [methods# [method-name# f#]]
- (assoc methods# (name method-name#)
- (fn [this# & args#]
- (binding [*applet* this#
- *state* state#]
- (apply f# args#)))))
- {}
- ~methods)]
- (update-proxy prx# bound-meths#)
- prx#))))
-(defn stop [applet]
+(defn applet-stop
+ "Stop an applet"
+ [applet]
+ (.stop applet))
+
+(defn applet-start
+ "Start an applet"
+ [applet]
+ (.start applet))
+
+(defn applet-exit
+ "Exit the applet (may kill JVM process)"
+ [applet]
+ (.exit applet))
+
+(defn applet-close
+ "Stop the applet and close the window."
+ [applet]
(let [closing-fn (fn []
(let [frame @(:frame (meta applet))]
- (.destroy applet)
+ (.stop applet)
+ ;;.destroy appears to kill the process too
(doto frame
(.hide)
(.dispose))))]
- (javax.swing.SwingUtilities/invokeAndWait closing-fn)))
-
-(defn run
- "Launches the applet. If given the flag :interactive, it won't exit
- on clicking the close button - it will only dispose the window."
- [applet & interactive?]
- (.init applet)
- (let [m (.meta applet)
- [width height & _] (or (:size m) [200 200])
- close-op (if (first interactive?)
- JFrame/DISPOSE_ON_CLOSE
- JFrame/EXIT_ON_CLOSE)]
- (reset! (:frame m)
- (doto (JFrame. (or (:title m) (:name m)))
- (.addWindowListener (reify WindowListener
- (windowActivated [this e])
- (windowClosing [this e]
- (future (stop applet)))
- (windowDeactivated [this e])
- (windowDeiconified [this e])
- (windowIconified [this e])
- (windowOpened [this e])
- (windowClosed [this e])))
- (.setDefaultCloseOperation close-op)
- (.setSize width height)
- (.add applet)
- (.pack)
- (.show)))))
+ (javax.swing.SwingUtilities/invokeAndWait closing-fn)) )
+
+(defn- applet-run
+ "Launches the applet."
+ ([applet] (applet-run applet nil))
+ ([applet mode]
+ (.init applet)
+ (let [m (.meta applet)
+ [width height & _] (or (:size m) [200 200])
+ close-op (if (= :exit-on-close mode)
+ JFrame/EXIT_ON_CLOSE
+ JFrame/DISPOSE_ON_CLOSE)]
+ (reset! (:frame m)
+ (doto (JFrame. (or (:title m) (:name m)))
+ (.addWindowListener (reify WindowListener
+ (windowActivated [this e])
+ (windowClosing [this e]
+ (future (applet-close applet)))
+ (windowDeactivated [this e])
+ (windowDeiconified [this e])
+ (windowIconified [this e])
+ (windowOpened [this e])
+ (windowClosed [this e])))
+ (.setDefaultCloseOperation close-op)
+ (.setSize width height)
+ (.add applet)
+ (.pack)
+ (.show))))))
+
+(defn- applet-set-size
+ ([width height] (.size *applet* (int width) (int height)))
+ ([width height ^String renderer] (.size *applet* (int width) (int height) renderer)))
+(defn applet
+ [& opts]
+ (let [options (merge {:size [500 300]} (apply hash-map opts))
+ fns (dissoc options :name :title :size :key-pressed
+ :key-released :mouse-pressed :mouse-released
+ :mouse-moved :mouse-dragged :setup)
+ fns (into {} (map (fn [[k v]] [k (if (symbol? v) `(var ~v) v)]) fns))
+ fns (merge {:draw (fn [] nil)} fns)
+ key-pressed-fn (or (:key-pressed options) (fn [] nil))
+ key-released-fn (or (:key-released options) (fn [] nil))
+ mouse-pressed-fn (or (:mouse-pressed options) (fn [] nil))
+ mouse-released-fn (or (:mouse-released options) (fn [] nil))
+ mouse-moved-fn (or (:mouse-moved options) (fn [] nil))
+ mouse-dragged-fn (or (:mouse-dragged options) (fn [] nil))
+ setup-fn (fn []
+ (apply applet-set-size (:size options))
+ (when (:setup options)
+ ((:setup options))))
+ methods (into {} (map fix-mname fns))
+ frame (atom nil)
+ state (atom nil)
+ prx (proxy [processing.core.PApplet
+ clojure.lang.IMeta] []
+ (meta [] (assoc options :frame frame))
+ (keyPressed
+ ([] (binding [*applet* this
+ *state* state]
+ (key-pressed-fn)))
+ ([e]
+ (proxy-super keyPressed e)))
+ (keyReleased
+ ([] (binding [*applet* this
+ *state* state]
+ (key-released-fn)))
+ ([e]
+ (proxy-super keyReleased e)))
+ (mousePressed
+ ([] (binding [*applet* this
+ *state* state]
+ (mouse-pressed-fn)))
+ ([e]
+ (proxy-super mousePressed e)))
+ (mouseReleased
+ ([] (binding [*applet* this
+ *state* state]
+ (mouse-released-fn)))
+ ([e]
+ (proxy-super mouseReleased e)))
+ (mouseMoved
+ ([] (binding [*applet* this
+ *state* state]
+ (mouse-moved-fn)))
+ ([e]
+ (proxy-super mouseMoved e)))
+
+ (mouseDragged
+ ([] (binding [*applet* this
+ *state* state]
+ (mouse-dragged-fn)))
+ ([e]
+ (proxy-super mouseDragged e)))
+
+ (setup
+ ([] (binding [*applet* this
+ *state* state]
+ (setup-fn)))))
+
+ bound-meths (reduce (fn [methods [method-name f]]
+ (assoc methods (name method-name)
+ (fn [this & args]
+ (binding [*applet* this
+ *state* state]
+ (apply f args)))))
+ {}
+ methods)]
+ (update-proxy prx bound-meths)
+ (applet-run prx)
+ prx))
+
+(defmacro defapplet
+ "Define an applet. Takes an app-name and a map of options."
+ [app-name & opts]
+ `(def ~app-name (applet ~@opts)))
(comment ;; Usage:
(defapplet growing-triangle
:draw (fn [] (line 10 10 (frame-count) 100)))
- (run growing-triangle)
- (stop growing-triangle))
+ (applet-stop growing-triangle)
+ (applet-close growing-triangle))

0 comments on commit 935a65c

Please sign in to comment.