-
Notifications
You must be signed in to change notification settings - Fork 0
/
box.clj
143 lines (125 loc) · 5.31 KB
/
box.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
(ns strigui.box
(:require [clojure2d.core :as c2d]
[clojure.set :as s]
[strigui.events :as e]
[strigui.window :as wnd]
[strigui.widget :as wdg]))
(set! *warn-on-reflection* true)
;;(set! *unchecked-math* :warn-on-boxed)
(defprotocol Box
"collection of functions around redrawing boxes, managing the border etc. ..."
(draw-hover [this canvas] "draws the hover effect")
(draw-clicked [this canvas] "draws the clicked effect"))
(def ^:private default-font-size 15)
(def boxes-clicked (atom #{}))
(def boxes-focused (atom #{}))
(defn box-coord
"Computes the full box coordinates.
Returns the vector [x y border-width border-heigth]"
[canvas text {:keys [^long x ^long y ^long min-width]}]
(let [text-box (c2d/with-canvas-> canvas
(c2d/text-bounding-box text))
text-width (nth text-box 2)
text-heigth (nth text-box 3)
btn-w (* text-width 1.8)
border-width (if (and (number? min-width) (< btn-w min-width)) min-width btn-w)
border-heigth (* text-heigth 1.8)]
[x y border-width border-heigth]))
(defn box-draw-text
"Draws the text of the box"
[canvas text {:keys [^long x ^long y color ^long min-width align font-style font-size]}]
(let [style (if (empty? font-style) :bold (first font-style))
size (if (number? font-size) font-size default-font-size)
[_ _ border-width border-heigth] (box-coord canvas text {:x x :y y :min-width min-width})
[_ text-y text-width _] (c2d/with-canvas-> canvas
(c2d/set-font-attributes size style)
(c2d/text-bounding-box text))
background-color (if (> (count color) 0) (first color) :grey)
foreground-color (if (> (count color) 1) (nth color 1) :black)
x-offset (if (and (number? min-width) (= min-width border-width))
(/ (- border-width text-width) 2.0)
(* border-width 0.12))]
(c2d/with-canvas-> canvas
(c2d/set-color background-color)
(c2d/rect x y border-width border-heigth)
(c2d/set-font-attributes size style)
(c2d/set-color foreground-color)
(c2d/text text (+ x x-offset) (- y (* text-y 1.5))))))
(defn box-draw
"canvas - clojure2d canvas
text - text displayed inside the input
x - x coordinate of top left corner
y - y coordinate of top left corner
color - vector consisting of [background-color font-color]
min-width - the minimum width"
([args] (apply box-draw args))
([canvas text args]
(let [{:keys [^long x ^long y color ^long min-width]} args
[_ _ border-width border-heigth] (box-coord canvas text {:x x :y y :min-width min-width})
background-color (if (> (count color) 0) (first color) :grey)]
(c2d/with-canvas-> canvas
(c2d/set-color background-color)
(c2d/rect x y border-width border-heigth))
(box-draw-text canvas text args)
[x y border-width border-heigth])))
(defn box-border
([canvas color strength x y w h]
(box-border canvas color strength x y w h true))
([canvas color strength x y w h no-fill]
(when (> strength 0)
(c2d/with-canvas-> canvas
(c2d/set-color color)
(c2d/rect (- x strength) (- y strength) (+ w (* 2 strength)) (+ h (* 2 strength)) no-fill))
(box-border canvas color (- strength 1) x y w h no-fill))))
(defn box-draw-border
([^strigui.box.Box box canvas] (box-draw-border box canvas :black 1))
([^strigui.box.Box box canvas color] (box-draw-border box canvas color 1))
([^strigui.box.Box box canvas color strength] (box-draw-border box canvas color strength false))
([^strigui.box.Box box canvas color strength fill]
(let [[x y w h] (wdg/coord box)]
(box-border canvas color strength x y w h (not fill)))))
(defn box-draw-hover
[^strigui.box.Box box canvas]
(box-draw-border box canvas :black 2)
box)
(defn box-redraw
[^strigui.box.Box box canvas]
(let [coord (wdg/coord box)]
(when (not-empty coord)
(box-draw-border box canvas :white 2)
(box-draw-border box canvas :black 1)
(wdg/draw box canvas)
box)))
(defn box-remove-drawn
[^strigui.box.Box box canvas]
(box-draw-border box canvas :white 1 true))
(defn swap-focused!
[box]
(let [focus @boxes-focused
new (if (contains? focus box)
(s/difference focus #{box})
(s/union focus #{box}))]
(reset! boxes-focused new)))
(defn focused?
[box]
(contains? @boxes-focused box))
(defmethod wdg/widget-global-event :mouse-released
[_ canvas & args]
(map #(draw-hover %1 canvas) @boxes-clicked)
(reset! boxes-clicked #{}))
(defmethod wdg/widget-global-event :mouse-pressed-on-empty-space
[_ canvas & args]
(println "mouse pressed on empty space")
(reset! boxes-focused #{}))
(defmethod wdg/widget-global-event :key-pressed
[_ canvas & args]
(let [char (first args)
code (nth args 1)
new-focused-inputs (doall (map #(e/key-pressed %1 char code) @boxes-focused))]
(when (not-empty new-focused-inputs)
(println (str "key pressed: " char))
(doall (map #(wdg/unregister canvas %1) @boxes-focused))
(println new-focused-inputs)
(doall (map #(wdg/register canvas %1) new-focused-inputs))
(doall (map #(box-draw-text canvas (wdg/value %1) (wdg/args %1)) new-focused-inputs))
(reset! boxes-focused (set new-focused-inputs)))))