Skip to content

Commit 37c83a4

Browse files
Added fix for issue 409 with minimal test
1 parent e173b69 commit 37c83a4

4 files changed

Lines changed: 170 additions & 9 deletions

File tree

.vscode/launch.json

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,38 @@
145145
"args": [],
146146
"cwd": "${workspaceFolder}"
147147
},
148+
{
149+
"type": "lldb",
150+
"request": "launch",
151+
"name": "Debug example 'dropdown_pos'",
152+
"cargo": {
153+
"args": [
154+
"build",
155+
"--example=dropdown_pos",
156+
],
157+
"filter": {
158+
"name": "dropdown_pos",
159+
"kind": "example"
160+
}
161+
},
162+
"args": [],
163+
"cwd": "${workspaceFolder}"
164+
},
165+
{
166+
"name": "(Windows) Launch example 'dropdown_pos'",
167+
"type": "cppvsdbg",
168+
"request": "launch",
169+
"program": "${workspaceRoot}/target/debug/examples/dropdown_pos.exe",
170+
"args": [
171+
"--example",
172+
"dropdown_pos"
173+
],
174+
"stopAtEntry": false,
175+
"cwd": "${workspaceRoot}",
176+
"environment": [],
177+
"preLaunchTask": "build_dropdown_pos",
178+
"console": "integratedTerminal",
179+
},
148180
{
149181
"type": "lldb",
150182
"request": "launch",

.vscode/tasks.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// .vscode/tasks.json
2+
{
3+
"version": "2.0.0",
4+
"tasks": [
5+
{
6+
"label": "build_dropdown_pos",
7+
"type": "cargo",
8+
"command": "build",
9+
"args": [
10+
"--example",
11+
"dropdown_pos"
12+
],
13+
"problemMatcher": [
14+
"$rustc"
15+
],
16+
"group": {
17+
"kind": "build",
18+
"isDefault": true
19+
}
20+
}
21+
]
22+
}

examples/dropdown_pos.rs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
use iced::{
2+
Alignment, Element,
3+
Length::{Fill, FillPortion, Shrink},
4+
widget::{button, column, container, row, scrollable, text},
5+
};
6+
use iced_aw::{DropDown, drop_down};
7+
use std::str::FromStr;
8+
9+
fn main() -> iced::Result {
10+
iced::application(App::default, App::update, App::view).run()
11+
}
12+
13+
#[derive(Default, Debug, Clone)]
14+
enum DropDownItem {
15+
#[default]
16+
A,
17+
B,
18+
C,
19+
}
20+
21+
impl ToString for DropDownItem {
22+
fn to_string(&self) -> String {
23+
match self {
24+
DropDownItem::A => String::from_str("A").unwrap(),
25+
DropDownItem::B => String::from_str("B").unwrap(),
26+
DropDownItem::C => String::from_str("C").unwrap(),
27+
}
28+
}
29+
}
30+
31+
impl DropDownItem {
32+
const ALL: &'static [Self] = &[DropDownItem::A, DropDownItem::B, DropDownItem::C];
33+
}
34+
35+
#[derive(Default)]
36+
struct App {
37+
is_open: bool,
38+
selected: DropDownItem,
39+
}
40+
41+
#[derive(Debug, Clone)]
42+
enum Message {
43+
DropdownOpen,
44+
DropdownSelect(DropDownItem),
45+
}
46+
47+
impl App {
48+
fn view(&self) -> Element<'_, Message> {
49+
row![
50+
container(column![
51+
container(
52+
column![text("Placeholder").size(18), text("text").size(12)]
53+
.spacing(2)
54+
.width(Fill)
55+
.align_x(Alignment::Center)
56+
)
57+
.padding(4),
58+
column![
59+
row![
60+
text("Placeholder"),
61+
button("scaffold").padding(1).height(Shrink)
62+
],
63+
scrollable(text("Lorem")).height(Fill)
64+
]
65+
])
66+
.width(FillPortion(1)),
67+
column![
68+
row![
69+
text("Dropdowns"),
70+
prepare_dropdown(self.selected.clone(), self.is_open)
71+
]
72+
.spacing(4)
73+
.padding(5),
74+
scrollable("Lorem").height(Fill)
75+
]
76+
.width(FillPortion(2))
77+
]
78+
.into()
79+
}
80+
81+
fn update(&mut self, message: Message) {
82+
match message {
83+
Message::DropdownOpen => self.is_open = !self.is_open,
84+
Message::DropdownSelect(drop_down_item) => self.selected = drop_down_item,
85+
}
86+
}
87+
}
88+
89+
fn prepare_dropdown<'a>(selected: DropDownItem, expanded: bool) -> DropDown<'a, Message> {
90+
let underlay = button(
91+
row![
92+
text(selected.to_string()).width(90),
93+
if expanded { text("V") } else { text("<") }
94+
]
95+
.align_y(Alignment::Center),
96+
)
97+
.on_press(Message::DropdownOpen);
98+
let overlay = container(column(DropDownItem::ALL.iter().map(|r| {
99+
button(text(r.to_string()).size(18).wrapping(text::Wrapping::None))
100+
.width(Fill)
101+
.on_press(Message::DropdownSelect(r.clone()))
102+
.into()
103+
})));
104+
DropDown::new(underlay, overlay, expanded)
105+
.alignment(drop_down::Alignment::Bottom)
106+
.on_dismiss(Message::DropdownOpen)
107+
}

src/widget/drop_down.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ where
321321
Alignment::Start | Alignment::End => limits.max_height(max_height_symmetric),
322322
};
323323

324-
let mut node = self
324+
let node = self
325325
.element
326326
.as_widget_mut()
327327
.layout(self.state, renderer, &limits);
@@ -364,23 +364,23 @@ where
364364
- node.bounds().height / 2.0,
365365
),
366366
};
367+
//commenting these out for now as we have no way of knowing the actual screen size here.. maybe in a later iced update?
368+
/*if new_position.x + node.bounds().width > max.width {
369+
new_position.x -= max.width - node.bounds().width;
370+
}*/
367371

368-
if new_position.x + node.bounds().width > max.width {
369-
new_position.x = max.width - node.bounds().width;
370-
}
371372
if new_position.x < 0.0 {
372373
new_position.x = 0.0;
373374
}
374375

375-
if new_position.y + node.bounds().height > max.height {
376-
new_position.y = max.height - node.bounds().height;
377-
}
376+
/*if new_position.y + node.bounds().height > max.height {
377+
new_position.y -= max.height - node.bounds().height;
378+
}*/
378379
if new_position.y < 0.0 {
379380
new_position.y = 0.0;
380381
}
381382

382-
node.move_to_mut(new_position);
383-
node
383+
node.move_to(new_position)
384384
}
385385

386386
fn draw(

0 commit comments

Comments
 (0)