Skip to content

Commit f0a3fe3

Browse files
authored
Merge pull request #45 from boydm/boyd
Add a :direction option to the Dropdown component so it can drop either up or down
2 parents 92c4b72 + 894f07e commit f0a3fe3

File tree

3 files changed

+55
-17
lines changed

3 files changed

+55
-17
lines changed

changelist.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
an inconsistency where sometimes the incoming point would be in local coordinate
1212
space and sometimes it would be global. If you want to capture that sort of input, either
1313
cover the space with a clear rect, or capture the input.
14+
* Add the `:direction` option to the `Dropdown` component so can can go either up or down.
1415

1516
### 0.7.0
1617
* First public release

lib/scenic/component/input/dropdown.ex

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,22 @@ defmodule Scenic.Component.Input.Dropdown do
1515

1616
@default_width 160
1717
@default_height 30
18+
@default_direction :down
1819

1920
@default_font :roboto
2021
@default_font_size 20
2122

2223
@drop_click_window_ms 400
2324

24-
@carat {{0, 0}, {12, 0}, {6, 6}}
25+
@caret {{0, 0}, {12, 0}, {6, 6}}
2526
@text_id :__dropbox_text__
26-
@carat_id :__carat__
27+
@caret_id :__caret__
2728
@dropbox_id :__dropbox__
2829
@button_id :__dropbox_btn__
2930

30-
@rad :math.pi() / 2
31+
@rotate_neutral :math.pi() / 2
32+
@rotate_down 0
33+
@rotate_up :math.pi()
3134

3235
# --------------------------------------------------------
3336
def info(data) do
@@ -83,6 +86,23 @@ defmodule Scenic.Component.Input.Dropdown do
8386
item_count = Enum.count(items)
8487
drop_height = item_count * height
8588

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+
86106
graph =
87107
Graph.build(font: font, font_size: font_size)
88108
|> rect({width, height}, fill: theme.background, stroke: {2, theme.border})
@@ -92,12 +112,12 @@ defmodule Scenic.Component.Input.Dropdown do
92112
text_align: :left,
93113
id: @text_id
94114
)
95-
|> triangle(@carat,
115+
|> triangle(@caret,
96116
fill: theme.text,
97117
translate: {width - 18, height * 0.5},
98118
pin: {6, 0},
99-
rotate: @rad,
100-
id: @carat_id
119+
rotate: @rotate_neutral,
120+
id: @caret_id
101121
)
102122

103123
# an invisible rect for hit-test purposes
@@ -132,7 +152,7 @@ defmodule Scenic.Component.Input.Dropdown do
132152

133153
g
134154
end,
135-
translate: {0, height + 1},
155+
translate: translate_menu,
136156
id: @dropbox_id,
137157
hidden: true
138158
)
@@ -145,7 +165,8 @@ defmodule Scenic.Component.Input.Dropdown do
145165
down: false,
146166
hover_id: nil,
147167
items: items,
148-
drop_time: 0
168+
drop_time: 0,
169+
rotate_caret: rotate_caret
149170
}
150171

151172
push_graph(graph)
@@ -170,15 +191,15 @@ defmodule Scenic.Component.Input.Dropdown do
170191
def handle_input(
171192
{:cursor_button, {:left, :press, _, _}},
172193
%{id: @button_id} = context,
173-
%{down: false, graph: graph} = state
194+
%{down: false, graph: graph, rotate_caret: rotate_caret} = state
174195
) do
175196
# capture input
176197
ViewPort.capture_input(context, [:cursor_button, :cursor_pos])
177198

178199
# drop the menu
179200
graph =
180201
graph
181-
|> Graph.modify(@carat_id, &update_opts(&1, rotate: 0))
202+
|> Graph.modify(@caret_id, &update_opts(&1, rotate: rotate_caret))
182203
|> Graph.modify(@dropbox_id, &update_opts(&1, hidden: false))
183204
|> push_graph()
184205

@@ -228,7 +249,12 @@ defmodule Scenic.Component.Input.Dropdown do
228249
def handle_input(
229250
{:cursor_button, {:left, :press, _, _}},
230251
%{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
232258
) do
233259
# release the input capture
234260
ViewPort.release_input(context, [:cursor_button, :cursor_pos])
@@ -238,7 +264,7 @@ defmodule Scenic.Component.Input.Dropdown do
238264
# restore standard highliting
239265
|> update_highlighting(items, selected_id, nil, theme)
240266
# raise the dropdown
241-
|> Graph.modify(@carat_id, &update_opts(&1, rotate: @rad))
267+
|> Graph.modify(@caret_id, &update_opts(&1, rotate: @rotate_neutral))
242268
|> Graph.modify(@dropbox_id, &update_opts(&1, hidden: true))
243269
# push to the viewport
244270
|> push_graph()
@@ -268,7 +294,7 @@ defmodule Scenic.Component.Input.Dropdown do
268294
graph =
269295
graph
270296
|> 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))
272298
|> Graph.modify(@dropbox_id, &update_opts(&1, hidden: true))
273299
|> push_graph()
274300

@@ -284,7 +310,12 @@ defmodule Scenic.Component.Input.Dropdown do
284310
def handle_input(
285311
{:cursor_button, {:left, :release, _, _}},
286312
%{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
288319
) do
289320
# release the input capture
290321
ViewPort.release_input(context, [:cursor_button, :cursor_pos])
@@ -294,7 +325,7 @@ defmodule Scenic.Component.Input.Dropdown do
294325
# restore standard highliting
295326
|> update_highlighting(items, selected_id, nil, theme)
296327
# raise the dropdown
297-
|> Graph.modify(@carat_id, &update_opts(&1, rotate: @rad))
328+
|> Graph.modify(@caret_id, &update_opts(&1, rotate: @rotate_neutral))
298329
|> Graph.modify(@dropbox_id, &update_opts(&1, hidden: true))
299330
# push to the viewport
300331
|> push_graph()
@@ -307,7 +338,12 @@ defmodule Scenic.Component.Input.Dropdown do
307338
def handle_input(
308339
{:cursor_button, {:left, :release, _, _}},
309340
%{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
311347
) do
312348
# release the input capture
313349
ViewPort.release_input(context, [:cursor_button, :cursor_pos])
@@ -325,7 +361,7 @@ defmodule Scenic.Component.Input.Dropdown do
325361
# restore standard highliting
326362
|> update_highlighting(items, item_id, nil, theme)
327363
# raise the dropdown
328-
|> Graph.modify(@carat_id, &update_opts(&1, rotate: @rad))
364+
|> Graph.modify(@caret_id, &update_opts(&1, rotate: @rotate_neutral))
329365
|> Graph.modify(@dropbox_id, &update_opts(&1, hidden: true))
330366
# push to the viewport
331367
|> push_graph()

lib/scenic/components.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ defmodule Scenic.Components do
293293
Buttons honor the following list of additional styles.
294294
* `:width` - pass in a number to set the width of the button.
295295
* `:height` - pass in a number to set the height of the button.
296+
* `:direction` - what direction should the menu drop. Can be either `:down` or `:up`. The default is `:down`.
296297
297298
## Theme
298299

0 commit comments

Comments
 (0)