view src/net/kryshen/indyvon/demo.clj @ 80:880ae8e03408

Measure time intervals between repaints. Experiments.
author Mikhail Kryshen <mikhail@kryshen.net>
date Wed, 01 Sep 2010 22:25:55 +0400
parents 1ca7872b889b
children 5d2153e8a28d
line source
1 ;;
2 ;; Copyright 2010 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 (:gen-class)
22 (:use
23 (net.kryshen.indyvon core layers component))
24 (:import
25 (net.kryshen.indyvon.core Size)
26 (java.awt Color)
27 (javax.swing JFrame)))
29 (defn draw-button!
30 "Draws button immediately (but uses callback for button action
31 unlike IMGUI)."
32 [id content callback & args]
33 (with-handlers id
34 (let [shadow-offset 2
35 padding 4
36 border-width 1
37 offset (if (picked? id) (/ shadow-offset 2) 0)
38 ^Color color (:alt-back-color *theme*)
39 color (if (hovered? id) (.brighter color) color)
40 width (- *width* shadow-offset)
41 height (- *height* shadow-offset)]
42 (with-color Color/BLACK
43 (.fillRect *graphics* shadow-offset shadow-offset width height))
44 (with-color color
45 (.fillRect *graphics* offset offset width height))
46 (draw! (border content border-width padding)
47 offset offset width height))
48 ;; Event handlers
49 (:mouse-entered _ (repaint))
50 (:mouse-exited _ (repaint))
51 (:mouse-pressed _ (repaint))
52 (:mouse-released _ (repaint))
53 (:mouse-clicked _ (apply callback args))))
55 (defn combine-colors [^Color color1 ^Color color2 c]
56 (case c
57 0.0 color1
58 1.0 color2
59 (let [rgb1 (.getRGBComponents color1 nil)
60 rgb2 (.getRGBComponents color2 nil)
61 rgb (float-array (map #(+ (* (- 1 c) %1) (* c %2)) rgb1 rgb2))]
62 (Color. (aget rgb 0) (aget rgb 1) (aget rgb 2) (aget rgb 3)))))
64 (defn animate
65 "Changes atom value according to specified range, speed, and current
66 frame interval. Invokes repaint if change happens."
67 [atom from to speed]
68 (let [prev @atom
69 state (cond
70 (zero? speed) :stop
71 (= prev from) (if (pos? speed) :start :stop)
72 (= prev to) (if (neg? speed) :start :stop)
73 :default :continue)]
74 ;;(println prev from to speed state *interval*)
75 (if (= state :stop)
76 prev
77 (let [interval (if (= state :start) 1 *interval*)
78 step (* speed interval 1E-9)
79 val (swap! atom #(-> % (+ step) (max from) (min to)))]
80 (repaint)
81 val))))
83 (defn button
84 "Create animated button layer."
85 [content callback & args]
86 (let [padding 4
87 border-width 1
88 shadow-offset 2
89 face (border content padding border-width)
90 highlight (atom 0)
91 animation-speed (atom 0)]
92 (interval-layer
93 (reify
94 Layer
95 (render! [button]
96 (with-handlers button
97 (let [hovered (hovered? button)
98 offset (if (picked? button) (/ shadow-offset 2) 0)
99 color (combine-colors
100 (:alt-back-color *theme*) Color/WHITE
101 (animate highlight 0.0 1.0 @animation-speed))
102 width (- *width* shadow-offset)
103 height (- *height* shadow-offset)]
104 (with-color Color/BLACK
105 (.fillRect *graphics*
106 shadow-offset shadow-offset
107 width height))
108 (with-color color
109 (.fillRect *graphics* offset offset width height))
110 (draw! (border content border-width padding)
111 offset offset width height))
112 ;; Event handlers
113 (:mouse-entered _
114 (reset! animation-speed 4)
115 (repaint))
116 (:mouse-exited _
117 (reset! animation-speed -2)
118 (repaint))
119 (:mouse-pressed _ (repaint))
120 (:mouse-released _ (repaint))
121 (:mouse-clicked _ (apply callback args))))
122 (layer-size [button]
123 (let [face-size (layer-size face)]
124 (Size. (+ (:width face-size) shadow-offset)
125 (+ (:height face-size) shadow-offset))))))))
127 (def button1 (button (label "Animated button 1")
128 println "Animated button 1 clicked"))
130 (def button2 (button (label "Animated button 2")
131 println "Animated button 2 clicked"))
133 (def layer1
134 (reify
135 Layer
136 (render! [layer]
137 (with-handlers layer
138 (with-color (if (hovered? layer) Color/ORANGE Color/RED)
139 (.fillRect *graphics* 0 0 *width* *height*))
140 (:mouse-entered e
141 (repaint)
142 (println e))
143 (:mouse-exited e
144 (repaint)
145 (println e))
146 (:mouse-moved e
147 (println e))))
148 (layer-size [layer]
149 (Size. 30 20))))
151 (def layer1b (border layer1 2 3))
153 (def layer2
154 (reify
155 Layer
156 (render! [layer]
157 (doto *graphics*
158 (.setColor Color/YELLOW)
159 (.fillRect 0 0 *width* *height*))
160 (with-rotate 0.5 0 0
161 (draw! layer1b 30 25))
162 (draw! layer1 55 5))
163 (layer-size [layer]
164 (Size. 70 65))))
166 (def layer2m (miniature layer2 30 30))
168 (def layer3 (border (label "Sample\ntext" :right :center)))
170 (def layer
171 (reify
172 Layer
173 (render! [layer]
174 ;;(repaint)
175 ;;(println (format "%.3f" (/ *interval* 1E9)))
176 (doto *graphics*
177 ;; Random color to see when repaint happens.
178 (.setColor (rand-nth [Color/BLACK Color/BLUE Color/RED]))
179 (.drawLine 0 0 *width* *height*)
180 (.drawLine *width* 0 0 *height*))
181 (draw! layer2 15 20)
182 (draw! layer2m 120 50)
183 (draw! layer3 100 100 80 50)
184 (draw! button1 50 160)
185 (with-rotate (/ Math/PI 6) 250 200
186 (draw! button1 200 160))
187 (draw! button2 50 250)
188 (with-bounds 100 200 140 30
189 (draw-button! :button
190 (label "Immediate button" :center :center)
191 #(println "Button clicked!"))))
192 (layer-size [layer]
193 (Size. 400 300))))
195 ;; Main viewport
196 (def vp (viewport layer))
198 ;; Miniature (rendered asynchronously)
199 (def vp-miniature (border (viewport-miniature vp 100 75)))
201 ;; Main scene
202 (def scene
203 (fps-layer
204 (decorate-layer vp [_]
205 (draw! vp)
206 (draw! vp-miniature (- *width* 105) 5))))
208 (defn show-frame [layer]
209 (doto (make-jframe "Test" layer)
210 (.setDefaultCloseOperation JFrame/DISPOSE_ON_CLOSE)
211 (.setVisible true)))
213 (defn -main []
214 (println "Try to drag the viewport.")
215 (show-frame scene))