@@ -15,19 +15,22 @@ defmodule Scenic.Component.Input.Dropdown do
15
15
16
16
@ default_width 160
17
17
@ default_height 30
18
+ @ default_direction :down
18
19
19
20
@ default_font :roboto
20
21
@ default_font_size 20
21
22
22
23
@ drop_click_window_ms 400
23
24
24
- @ carat { { 0 , 0 } , { 12 , 0 } , { 6 , 6 } }
25
+ @ caret { { 0 , 0 } , { 12 , 0 } , { 6 , 6 } }
25
26
@ text_id :__dropbox_text__
26
- @ carat_id :__carat__
27
+ @ caret_id :__caret__
27
28
@ dropbox_id :__dropbox__
28
29
@ button_id :__dropbox_btn__
29
30
30
- @ rad :math . pi ( ) / 2
31
+ @ rotate_neutral :math . pi ( ) / 2
32
+ @ rotate_down 0
33
+ @ rotate_up :math . pi ( )
31
34
32
35
# --------------------------------------------------------
33
36
def info ( data ) do
@@ -83,6 +86,21 @@ defmodule Scenic.Component.Input.Dropdown do
83
86
item_count = Enum . count ( items )
84
87
drop_height = item_count * height
85
88
89
+ # get the drop direction
90
+ direction = styles [ :direction ] || @ default_direction
91
+
92
+ # calculate the where to put the drop box. Depends on the direction
93
+ translate_menu = case direction do
94
+ :down -> { 0 , height + 1 }
95
+ :up -> { 0 , height * - item_count - 1 }
96
+ end
97
+
98
+ # get the direction to rotate the caret
99
+ rotate_caret = case direction do
100
+ :down -> @ rotate_down
101
+ :up -> - @ rotate_up
102
+ end
103
+
86
104
graph =
87
105
Graph . build ( font: font , font_size: font_size )
88
106
|> rect ( { width , height } , fill: theme . background , stroke: { 2 , theme . border } )
@@ -92,12 +110,12 @@ defmodule Scenic.Component.Input.Dropdown do
92
110
text_align: :left ,
93
111
id: @ text_id
94
112
)
95
- |> triangle ( @ carat ,
113
+ |> triangle ( @ caret ,
96
114
fill: theme . text ,
97
115
translate: { width - 18 , height * 0.5 } ,
98
116
pin: { 6 , 0 } ,
99
- rotate: @ rad ,
100
- id: @ carat_id
117
+ rotate: @ rotate_neutral ,
118
+ id: @ caret_id
101
119
)
102
120
103
121
# an invisible rect for hit-test purposes
@@ -132,7 +150,7 @@ defmodule Scenic.Component.Input.Dropdown do
132
150
133
151
g
134
152
end ,
135
- translate: { 0 , height + 1 } ,
153
+ translate: translate_menu ,
136
154
id: @ dropbox_id ,
137
155
hidden: true
138
156
)
@@ -145,7 +163,8 @@ defmodule Scenic.Component.Input.Dropdown do
145
163
down: false ,
146
164
hover_id: nil ,
147
165
items: items ,
148
- drop_time: 0
166
+ drop_time: 0 ,
167
+ rotate_caret: rotate_caret
149
168
}
150
169
151
170
push_graph ( graph )
@@ -170,15 +189,15 @@ defmodule Scenic.Component.Input.Dropdown do
170
189
def handle_input (
171
190
{ :cursor_button , { :left , :press , _ , _ } } ,
172
191
% { id: @ button_id } = context ,
173
- % { down: false , graph: graph } = state
192
+ % { down: false , graph: graph , rotate_caret: rotate_caret } = state
174
193
) do
175
194
# capture input
176
195
ViewPort . capture_input ( context , [ :cursor_button , :cursor_pos ] )
177
196
178
197
# drop the menu
179
198
graph =
180
199
graph
181
- |> Graph . modify ( @ carat_id , & update_opts ( & 1 , rotate: 0 ) )
200
+ |> Graph . modify ( @ caret_id , & update_opts ( & 1 , rotate: rotate_caret ) )
182
201
|> Graph . modify ( @ dropbox_id , & update_opts ( & 1 , hidden: false ) )
183
202
|> push_graph ( )
184
203
@@ -228,7 +247,12 @@ defmodule Scenic.Component.Input.Dropdown do
228
247
def handle_input (
229
248
{ :cursor_button , { :left , :press , _ , _ } } ,
230
249
% { id: nil } = context ,
231
- % { down: true , items: items , theme: theme , selected_id: selected_id } = state
250
+ % {
251
+ down: true ,
252
+ items: items ,
253
+ theme: theme ,
254
+ selected_id: selected_id
255
+ } = state
232
256
) do
233
257
# release the input capture
234
258
ViewPort . release_input ( context , [ :cursor_button , :cursor_pos ] )
@@ -238,7 +262,7 @@ defmodule Scenic.Component.Input.Dropdown do
238
262
# restore standard highliting
239
263
|> update_highlighting ( items , selected_id , nil , theme )
240
264
# raise the dropdown
241
- |> Graph . modify ( @ carat_id , & update_opts ( & 1 , rotate: @ rad ) )
265
+ |> Graph . modify ( @ caret_id , & update_opts ( & 1 , rotate: @ rotate_neutral ) )
242
266
|> Graph . modify ( @ dropbox_id , & update_opts ( & 1 , hidden: true ) )
243
267
# push to the viewport
244
268
|> push_graph ( )
@@ -268,7 +292,7 @@ defmodule Scenic.Component.Input.Dropdown do
268
292
graph =
269
293
graph
270
294
|> update_highlighting ( items , selected_id , nil , theme )
271
- |> Graph . modify ( @ carat_id , & update_opts ( & 1 , rotate: @ rad ) )
295
+ |> Graph . modify ( @ caret_id , & update_opts ( & 1 , rotate: @ rotate_neutral ) )
272
296
|> Graph . modify ( @ dropbox_id , & update_opts ( & 1 , hidden: true ) )
273
297
|> push_graph ( )
274
298
@@ -284,7 +308,12 @@ defmodule Scenic.Component.Input.Dropdown do
284
308
def handle_input (
285
309
{ :cursor_button , { :left , :release , _ , _ } } ,
286
310
% { id: nil } = context ,
287
- % { down: true , items: items , theme: theme , selected_id: selected_id } = state
311
+ % {
312
+ down: true ,
313
+ items: items ,
314
+ theme: theme ,
315
+ selected_id: selected_id
316
+ } = state
288
317
) do
289
318
# release the input capture
290
319
ViewPort . release_input ( context , [ :cursor_button , :cursor_pos ] )
@@ -294,7 +323,7 @@ defmodule Scenic.Component.Input.Dropdown do
294
323
# restore standard highliting
295
324
|> update_highlighting ( items , selected_id , nil , theme )
296
325
# raise the dropdown
297
- |> Graph . modify ( @ carat_id , & update_opts ( & 1 , rotate: @ rad ) )
326
+ |> Graph . modify ( @ caret_id , & update_opts ( & 1 , rotate: @ rotate_neutral ) )
298
327
|> Graph . modify ( @ dropbox_id , & update_opts ( & 1 , hidden: true ) )
299
328
# push to the viewport
300
329
|> push_graph ( )
@@ -307,7 +336,12 @@ defmodule Scenic.Component.Input.Dropdown do
307
336
def handle_input (
308
337
{ :cursor_button , { :left , :release , _ , _ } } ,
309
338
% { id: item_id } = context ,
310
- % { down: true , id: id , items: items , theme: theme } = state
339
+ % {
340
+ down: true ,
341
+ id: id ,
342
+ items: items ,
343
+ theme: theme
344
+ } = state
311
345
) do
312
346
# release the input capture
313
347
ViewPort . release_input ( context , [ :cursor_button , :cursor_pos ] )
@@ -325,7 +359,7 @@ defmodule Scenic.Component.Input.Dropdown do
325
359
# restore standard highliting
326
360
|> update_highlighting ( items , item_id , nil , theme )
327
361
# raise the dropdown
328
- |> Graph . modify ( @ carat_id , & update_opts ( & 1 , rotate: @ rad ) )
362
+ |> Graph . modify ( @ caret_id , & update_opts ( & 1 , rotate: @ rotate_neutral ) )
329
363
|> Graph . modify ( @ dropbox_id , & update_opts ( & 1 , hidden: true ) )
330
364
# push to the viewport
331
365
|> push_graph ( )
0 commit comments