@@ -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,23 @@ 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 =
94
+ case direction do
95
+ :down -> { 0 , height + 1 }
96
+ :up -> { 0 , height * - item_count - 1 }
97
+ end
98
+
99
+ # get the direction to rotate the caret
100
+ rotate_caret =
101
+ case direction do
102
+ :down -> @ rotate_down
103
+ :up -> - @ rotate_up
104
+ end
105
+
86
106
graph =
87
107
Graph . build ( font: font , font_size: font_size )
88
108
|> rect ( { width , height } , fill: theme . background , stroke: { 2 , theme . border } )
@@ -92,12 +112,12 @@ defmodule Scenic.Component.Input.Dropdown do
92
112
text_align: :left ,
93
113
id: @ text_id
94
114
)
95
- |> triangle ( @ carat ,
115
+ |> triangle ( @ caret ,
96
116
fill: theme . text ,
97
117
translate: { width - 18 , height * 0.5 } ,
98
118
pin: { 6 , 0 } ,
99
- rotate: @ rad ,
100
- id: @ carat_id
119
+ rotate: @ rotate_neutral ,
120
+ id: @ caret_id
101
121
)
102
122
103
123
# an invisible rect for hit-test purposes
@@ -132,7 +152,7 @@ defmodule Scenic.Component.Input.Dropdown do
132
152
133
153
g
134
154
end ,
135
- translate: { 0 , height + 1 } ,
155
+ translate: translate_menu ,
136
156
id: @ dropbox_id ,
137
157
hidden: true
138
158
)
@@ -145,7 +165,8 @@ defmodule Scenic.Component.Input.Dropdown do
145
165
down: false ,
146
166
hover_id: nil ,
147
167
items: items ,
148
- drop_time: 0
168
+ drop_time: 0 ,
169
+ rotate_caret: rotate_caret
149
170
}
150
171
151
172
push_graph ( graph )
@@ -170,15 +191,15 @@ defmodule Scenic.Component.Input.Dropdown do
170
191
def handle_input (
171
192
{ :cursor_button , { :left , :press , _ , _ } } ,
172
193
% { id: @ button_id } = context ,
173
- % { down: false , graph: graph } = state
194
+ % { down: false , graph: graph , rotate_caret: rotate_caret } = state
174
195
) do
175
196
# capture input
176
197
ViewPort . capture_input ( context , [ :cursor_button , :cursor_pos ] )
177
198
178
199
# drop the menu
179
200
graph =
180
201
graph
181
- |> Graph . modify ( @ carat_id , & update_opts ( & 1 , rotate: 0 ) )
202
+ |> Graph . modify ( @ caret_id , & update_opts ( & 1 , rotate: rotate_caret ) )
182
203
|> Graph . modify ( @ dropbox_id , & update_opts ( & 1 , hidden: false ) )
183
204
|> push_graph ( )
184
205
@@ -228,7 +249,12 @@ defmodule Scenic.Component.Input.Dropdown do
228
249
def handle_input (
229
250
{ :cursor_button , { :left , :press , _ , _ } } ,
230
251
% { id: nil } = context ,
231
- % { down: true , items: items , theme: theme , selected_id: selected_id } = state
252
+ % {
253
+ down: true ,
254
+ items: items ,
255
+ theme: theme ,
256
+ selected_id: selected_id
257
+ } = state
232
258
) do
233
259
# release the input capture
234
260
ViewPort . release_input ( context , [ :cursor_button , :cursor_pos ] )
@@ -238,7 +264,7 @@ defmodule Scenic.Component.Input.Dropdown do
238
264
# restore standard highliting
239
265
|> update_highlighting ( items , selected_id , nil , theme )
240
266
# raise the dropdown
241
- |> Graph . modify ( @ carat_id , & update_opts ( & 1 , rotate: @ rad ) )
267
+ |> Graph . modify ( @ caret_id , & update_opts ( & 1 , rotate: @ rotate_neutral ) )
242
268
|> Graph . modify ( @ dropbox_id , & update_opts ( & 1 , hidden: true ) )
243
269
# push to the viewport
244
270
|> push_graph ( )
@@ -268,7 +294,7 @@ defmodule Scenic.Component.Input.Dropdown do
268
294
graph =
269
295
graph
270
296
|> update_highlighting ( items , selected_id , nil , theme )
271
- |> Graph . modify ( @ carat_id , & update_opts ( & 1 , rotate: @ rad ) )
297
+ |> Graph . modify ( @ caret_id , & update_opts ( & 1 , rotate: @ rotate_neutral ) )
272
298
|> Graph . modify ( @ dropbox_id , & update_opts ( & 1 , hidden: true ) )
273
299
|> push_graph ( )
274
300
@@ -284,7 +310,12 @@ defmodule Scenic.Component.Input.Dropdown do
284
310
def handle_input (
285
311
{ :cursor_button , { :left , :release , _ , _ } } ,
286
312
% { id: nil } = context ,
287
- % { down: true , items: items , theme: theme , selected_id: selected_id } = state
313
+ % {
314
+ down: true ,
315
+ items: items ,
316
+ theme: theme ,
317
+ selected_id: selected_id
318
+ } = state
288
319
) do
289
320
# release the input capture
290
321
ViewPort . release_input ( context , [ :cursor_button , :cursor_pos ] )
@@ -294,7 +325,7 @@ defmodule Scenic.Component.Input.Dropdown do
294
325
# restore standard highliting
295
326
|> update_highlighting ( items , selected_id , nil , theme )
296
327
# raise the dropdown
297
- |> Graph . modify ( @ carat_id , & update_opts ( & 1 , rotate: @ rad ) )
328
+ |> Graph . modify ( @ caret_id , & update_opts ( & 1 , rotate: @ rotate_neutral ) )
298
329
|> Graph . modify ( @ dropbox_id , & update_opts ( & 1 , hidden: true ) )
299
330
# push to the viewport
300
331
|> push_graph ( )
@@ -307,7 +338,12 @@ defmodule Scenic.Component.Input.Dropdown do
307
338
def handle_input (
308
339
{ :cursor_button , { :left , :release , _ , _ } } ,
309
340
% { id: item_id } = context ,
310
- % { down: true , id: id , items: items , theme: theme } = state
341
+ % {
342
+ down: true ,
343
+ id: id ,
344
+ items: items ,
345
+ theme: theme
346
+ } = state
311
347
) do
312
348
# release the input capture
313
349
ViewPort . release_input ( context , [ :cursor_button , :cursor_pos ] )
@@ -325,7 +361,7 @@ defmodule Scenic.Component.Input.Dropdown do
325
361
# restore standard highliting
326
362
|> update_highlighting ( items , item_id , nil , theme )
327
363
# raise the dropdown
328
- |> Graph . modify ( @ carat_id , & update_opts ( & 1 , rotate: @ rad ) )
364
+ |> Graph . modify ( @ caret_id , & update_opts ( & 1 , rotate: @ rotate_neutral ) )
329
365
|> Graph . modify ( @ dropbox_id , & update_opts ( & 1 , hidden: true ) )
330
366
# push to the viewport
331
367
|> push_graph ( )
0 commit comments