view src/net/kryshen/indyvon/demo.clj @ 101:9874107e3e96

Clojure 1.3 compatibility, mouse wheel support, scalable viewport, additional layer implementations.
author Mikhail Kryshen <mikhail@kryshen.net>
date Wed, 18 May 2011 20:50:49 +0400
parents 5d2153e8a28d
children fd8fb8a3ff5a
line source
1 ;;
2 ;; Copyright 2010, 2011 Mikhail Kryshen <mikhail@kryshen.net>
3 ;;
4 ;; This file is part of Indyvon.
5 ;;
6 ;; Indyvon is free software: you can redistribute it and/or modify it
7 ;; under the terms of the GNU Lesser General Public License version 3
8 ;; only, as published by the Free Software Foundation.
9 ;;
10 ;; Indyvon is distributed in the hope that it will be useful, but
11 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 ;; Lesser General Public License for more details.
14 ;;
15 ;; You should have received a copy of the GNU Lesser General Public
16 ;; License along with Indyvon. If not, see
17 ;; <http://www.gnu.org/licenses/>.
18 ;;
20 (ns net.kryshen.indyvon.demo
21 "Indyvon demo and experiments."
22 (:gen-class)
23 (:use
24 (net.kryshen.indyvon core layers component))
25 (:import
26 (net.kryshen.indyvon.core Size)
27 (java.awt Color)
28 (javax.swing JFrame)))
30 (defn draw-button!
31 "Draws button immediately (but uses callback for button action
32 unlike IMGUI)."
33 [id content callback & args]
34 (with-handlers id
35 (let [shadow-offset 2
36 padding 4
37 border-width 1
38 offset (if (picked? id) (/ shadow-offset 2) 0)
39 ^Color color (:alt-back-color *theme*)
40 color (if (hovered? id) (.brighter color) color)
41 width (- *width* shadow-offset)
42 height (- *height* shadow-offset)]
43 (with-color Color/BLACK
44 (.fillRect *graphics* shadow-offset shadow-offset width height))
45 (with-color color
46 (.fillRect *graphics* offset offset width height))
47 (draw! (border content border-width padding)
48 offset offset width height))
49 ;; Event handlers
50 (:mouse-entered _ (repaint))
51 (:mouse-exited _ (repaint))
52 (:mouse-pressed _ (repaint))
53 (:mouse-released _ (repaint))
54 (:mouse-clicked _ (apply callback args))))
56 (defn combine-colors [^Color color1 ^Color color2 c]
57 "Returns color between color1 and color2. When c (0 <= c <= 1.0) is
58 closer to 0 the returned сolor is closer to color1."
59 (case c
60 0.0 color1
61 1.0 color2
62 (let [rgb1 (.getRGBComponents color1 nil)
63 rgb2 (.getRGBComponents color2 nil)
64 rgb (float-array (map #(+ (* (- 1 c) %1) (* c %2)) rgb1 rgb2))]
65 (Color. (aget rgb 0) (aget rgb 1) (aget rgb 2) (aget rgb 3)))))
67 (defn animate
68 "Changes atom value according to specified range, speed, and current
69 frame interval. Invokes repaint if change happens."
70 [atom from to speed]
71 (let [prev @atom
72 state (cond
73 (zero? speed) :stop
74 (= prev from) (if (pos? speed) :start :stop)
75 (= prev to) (if (neg? speed) :start :stop)
76 :default :continue)]
77 (if (= state :stop)
78 prev
79 (let [interval (if (= state :start) 1 *interval*)
80 step (* speed interval 1E-9)
81 val (swap! atom #(-> % (+ step) (max from) (min to)))]
82 (repaint)
83 val))))
85 (defn animated-button
86 "Create animated button layer."
87 [content callback & args]
88 (let [padding 4
89 border-width 1
90 shadow-offset 2
91 face (border content padding border-width)
92 highlight (atom 0)
93 animation-speed (atom 0)]
94 (interval-layer
95 (reify
96 Layer
97 (render! [button]
98 (with-handlers button
99 (let [hovered (hovered? button)
100 offset (if (picked? button) (/ shadow-offset 2) 0)
101 color (combine-colors
102 (:alt-back-color *theme*) Color/WHITE
103 (animate highlight 0.0 1.0 @animation-speed))
104 width (- *width* shadow-offset)
105 height (- *height* shadow-offset)]
106 (with-color Color/BLACK
107 (.fillRect *graphics*
108 shadow-offset shadow-offset
109 width height))
110 (with-color color
111 (.fillRect *graphics* offset offset width height))
112 (draw! (border content border-width padding)
113 offset offset width height))
114 ;; Event handlers
115 (:mouse-entered _
116 (reset! animation-speed 4)
117 (repaint))
118 (:mouse-exited _
119 (reset! animation-speed -2)
120 (repaint))
121 (:mouse-pressed _ (repaint))
122 (:mouse-released _ (repaint))
123 (:mouse-clicked _ (apply callback args))))
124 (layer-size [button]
125 (let [face-size (layer-size face)]
126 (Size. (+ (:width face-size) shadow-offset)
127 (+ (:height face-size) shadow-offset))))))))
129 (def button1 (animated-button (label "Animated button 1")
130 println "Animated button 1 clicked"))
132 (def button2 (animated-button (label "Animated button 2")
133 println "Animated button 2 clicked"))
135 (def test-layer1
136 (reify
137 Layer
138 (render! [layer]
139 (with-handlers layer
140 (with-color (if (hovered? layer) Color/ORANGE Color/RED)
141 (.fillRect *graphics* 0 0 *width* *height*))
142 (:mouse-entered e
143 (repaint)
144 (println e))
145 (:mouse-exited e
146 (repaint)
147 (println e))
148 (:mouse-moved e
149 (println e))))
150 (layer-size [layer]
151 (Size. 30 20))))
153 (def test-layer1b (border test-layer1 2 3))
155 (def test-layer2
156 (reify
157 Layer
158 (render! [layer]
159 (doto *graphics*
160 (.setColor Color/YELLOW)
161 (.fillRect 0 0 *width* *height*))
162 (with-rotate 0.5 0 0
163 (draw! test-layer1b 30 25))
164 (draw! test-layer1 55 5))
165 (layer-size [layer]
166 (Size. 70 65))))
168 (def test-layer2m (miniature test-layer2 30 30))
170 (def test-layer3 (border (label "Sample\ntext" :right :bottom)))
172 (def root
173 (reify
174 Layer
175 (render! [layer]
176 ;;(repaint)
177 (doto *graphics*
178 (.drawLine 0 0 *width* *height*)
179 (.drawLine *width* 0 0 *height*)
180 ;; Random color to see when repaint happens.
181 (.setColor (rand-nth [Color/BLACK Color/BLUE Color/RED]))
182 (.fillOval 5 5 20 20))
183 (draw! test-layer2 30 20)
184 (draw! test-layer2m 120 50)
185 (draw! test-layer3 100 100 80 50)
186 (draw! button1 50 160)
187 (with-rotate (/ Math/PI 6) 250 200
188 (draw! button1 200 160))
189 (draw! button2 50 250)
190 (with-bounds 100 200 140 30
191 (draw-button! :button
192 (label "Immediate button" :center :center)
193 #(println "Button clicked!"))))
194 (layer-size [layer]
195 (Size. 400 300))))
197 ;; Main viewport
198 (def vp (viewport root))
200 ;; Miniature (rendered asynchronously)
201 (def vp-miniature (border (viewport-miniature vp 100 75)))
203 ;; Main scene
204 (def scene
205 (fps-layer
206 (decorate-layer vp [_]
207 (draw! vp)
208 (draw! vp-miniature (- *width* 105) 5))))
210 (defn show-frame [layer]
211 (doto (make-jframe "Test" layer)
212 (.setDefaultCloseOperation JFrame/DISPOSE_ON_CLOSE)
213 (.setVisible true)))
215 (defn -main []
216 (println "Try to drag the viewport.")
217 (show-frame scene))
219 (comment
220 (show-frame (viewport-miniature vp 200 150)))