combine vertical/horizontal variant to remove duplicate code
This commit is contained in:
parent
a346bcf8a3
commit
7dec7054fb
7 changed files with 477 additions and 725 deletions
|
@ -53,356 +53,300 @@ impl<'a> DatePickerPopup<'a> {
|
||||||
let weeks = month_data(popup_state.year, popup_state.month);
|
let weeks = month_data(popup_state.year, popup_state.month);
|
||||||
let mut close = false;
|
let mut close = false;
|
||||||
let height = 20.0;
|
let height = 20.0;
|
||||||
GridBuilder::new(ui, Padding::new(2.0, 0.0)).vertical(|builder| {
|
GridBuilder::new(ui, Padding::new(2.0, 0.0))
|
||||||
builder
|
.sizes(
|
||||||
.rows(
|
Size::Absolute(height),
|
||||||
Size::Absolute(height),
|
match (self.combo_boxes, self.arrows) {
|
||||||
match (self.combo_boxes, self.arrows) {
|
(true, true) => 2,
|
||||||
(true, true) => 2,
|
(true, false) | (false, true) => 1,
|
||||||
(true, false) | (false, true) => 1,
|
(false, false) => 0,
|
||||||
(false, false) => 0,
|
},
|
||||||
},
|
)
|
||||||
)
|
.sizes(
|
||||||
.rows(
|
Size::Absolute(2.0 + (height + 2.0) * weeks.len() as f32),
|
||||||
Size::Absolute(2.0 + (height + 2.0) * weeks.len() as f32),
|
if self.calendar { 1 } else { 0 },
|
||||||
if self.calendar { 1 } else { 0 },
|
)
|
||||||
)
|
.size(Size::Absolute(height))
|
||||||
.row(Size::Absolute(height))
|
.vertical(|mut grid| {
|
||||||
.build(|mut grid| {
|
if self.combo_boxes {
|
||||||
if self.combo_boxes {
|
grid.grid_noclip(|builder| {
|
||||||
grid.horizontal_noclip(|builder| {
|
builder.sizes(Size::Remainder, 3).horizontal(|mut grid| {
|
||||||
builder.columns(Size::Remainder, 3).build(|mut grid| {
|
grid.cell_noclip(|ui| {
|
||||||
grid.cell_noclip(|ui| {
|
ComboBox::from_id_source("date_picker_year")
|
||||||
ComboBox::from_id_source("date_picker_year")
|
.selected_text(format!("{}", popup_state.year))
|
||||||
.selected_text(format!("{}", popup_state.year))
|
.show_ui(ui, |ui| {
|
||||||
.show_ui(ui, |ui| {
|
for year in today.year() - 5..today.year() + 10 {
|
||||||
for year in today.year() - 5..today.year() + 10 {
|
|
||||||
if ui
|
|
||||||
.selectable_value(
|
|
||||||
&mut popup_state.year,
|
|
||||||
year,
|
|
||||||
format!("{}", year),
|
|
||||||
)
|
|
||||||
.changed()
|
|
||||||
{
|
|
||||||
ui.memory()
|
|
||||||
.data
|
|
||||||
.insert_persisted(id, popup_state.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
grid.cell_noclip(|ui| {
|
|
||||||
ComboBox::from_id_source("date_picker_month")
|
|
||||||
.selected_text(format!("{}", popup_state.month))
|
|
||||||
.show_ui(ui, |ui| {
|
|
||||||
for month in 1..=12 {
|
|
||||||
if ui
|
|
||||||
.selectable_value(
|
|
||||||
&mut popup_state.month,
|
|
||||||
month,
|
|
||||||
format!("{}", month),
|
|
||||||
)
|
|
||||||
.changed()
|
|
||||||
{
|
|
||||||
ui.memory()
|
|
||||||
.data
|
|
||||||
.insert_persisted(id, popup_state.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
grid.cell_noclip(|ui| {
|
|
||||||
ComboBox::from_id_source("date_picker_day")
|
|
||||||
.selected_text(format!("{}", popup_state.day))
|
|
||||||
.show_ui(ui, |ui| {
|
|
||||||
for day in 1..=popup_state.last_day_of_month() {
|
|
||||||
if ui
|
|
||||||
.selectable_value(
|
|
||||||
&mut popup_state.day,
|
|
||||||
day,
|
|
||||||
format!("{}", day),
|
|
||||||
)
|
|
||||||
.changed()
|
|
||||||
{
|
|
||||||
ui.memory()
|
|
||||||
.data
|
|
||||||
.insert_persisted(id, popup_state.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.arrows {
|
|
||||||
grid.horizontal(|builder| {
|
|
||||||
builder.columns(Size::Remainder, 6).build(|mut grid| {
|
|
||||||
grid.cell(|ui| {
|
|
||||||
ui.with_layout(
|
|
||||||
Layout::top_down_justified(Align::Center),
|
|
||||||
|ui| {
|
|
||||||
if ui
|
if ui
|
||||||
.button("<<<")
|
.selectable_value(
|
||||||
.on_hover_text("substract one year")
|
&mut popup_state.year,
|
||||||
.clicked()
|
year,
|
||||||
|
format!("{}", year),
|
||||||
|
)
|
||||||
|
.changed()
|
||||||
{
|
{
|
||||||
popup_state.year -= 1;
|
|
||||||
popup_state.day = popup_state
|
|
||||||
.day
|
|
||||||
.min(popup_state.last_day_of_month());
|
|
||||||
ui.memory()
|
ui.memory()
|
||||||
.data
|
.data
|
||||||
.insert_persisted(id, popup_state.clone());
|
.insert_persisted(id, popup_state.clone());
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
);
|
});
|
||||||
});
|
});
|
||||||
grid.cell(|ui| {
|
grid.cell_noclip(|ui| {
|
||||||
ui.with_layout(
|
ComboBox::from_id_source("date_picker_month")
|
||||||
Layout::top_down_justified(Align::Center),
|
.selected_text(format!("{}", popup_state.month))
|
||||||
|ui| {
|
.show_ui(ui, |ui| {
|
||||||
|
for month in 1..=12 {
|
||||||
if ui
|
if ui
|
||||||
.button("<<")
|
.selectable_value(
|
||||||
.on_hover_text("substract one month")
|
&mut popup_state.month,
|
||||||
.clicked()
|
month,
|
||||||
|
format!("{}", month),
|
||||||
|
)
|
||||||
|
.changed()
|
||||||
{
|
{
|
||||||
popup_state.month -= 1;
|
|
||||||
if popup_state.month == 0 {
|
|
||||||
popup_state.month = 12;
|
|
||||||
popup_state.year -= 1;
|
|
||||||
}
|
|
||||||
popup_state.day = popup_state
|
|
||||||
.day
|
|
||||||
.min(popup_state.last_day_of_month());
|
|
||||||
ui.memory()
|
ui.memory()
|
||||||
.data
|
.data
|
||||||
.insert_persisted(id, popup_state.clone());
|
.insert_persisted(id, popup_state.clone());
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
);
|
});
|
||||||
});
|
});
|
||||||
grid.cell(|ui| {
|
grid.cell_noclip(|ui| {
|
||||||
ui.with_layout(
|
ComboBox::from_id_source("date_picker_day")
|
||||||
Layout::top_down_justified(Align::Center),
|
.selected_text(format!("{}", popup_state.day))
|
||||||
|ui| {
|
.show_ui(ui, |ui| {
|
||||||
|
for day in 1..=popup_state.last_day_of_month() {
|
||||||
if ui
|
if ui
|
||||||
.button("<")
|
.selectable_value(
|
||||||
.on_hover_text("substract one day")
|
&mut popup_state.day,
|
||||||
.clicked()
|
day,
|
||||||
|
format!("{}", day),
|
||||||
|
)
|
||||||
|
.changed()
|
||||||
{
|
{
|
||||||
popup_state.day -= 1;
|
|
||||||
if popup_state.day == 0 {
|
|
||||||
popup_state.month -= 1;
|
|
||||||
if popup_state.month == 0 {
|
|
||||||
popup_state.year -= 1;
|
|
||||||
popup_state.month = 12;
|
|
||||||
}
|
|
||||||
popup_state.day =
|
|
||||||
popup_state.last_day_of_month();
|
|
||||||
}
|
|
||||||
ui.memory()
|
ui.memory()
|
||||||
.data
|
.data
|
||||||
.insert_persisted(id, popup_state.clone());
|
.insert_persisted(id, popup_state.clone());
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
);
|
});
|
||||||
});
|
});
|
||||||
grid.cell(|ui| {
|
})
|
||||||
ui.with_layout(
|
});
|
||||||
Layout::top_down_justified(Align::Center),
|
}
|
||||||
|ui| {
|
|
||||||
if ui.button(">").on_hover_text("add one day").clicked()
|
|
||||||
{
|
|
||||||
popup_state.day += 1;
|
|
||||||
if popup_state.day > popup_state.last_day_of_month()
|
|
||||||
{
|
|
||||||
popup_state.day = 1;
|
|
||||||
popup_state.month += 1;
|
|
||||||
if popup_state.month > 12 {
|
|
||||||
popup_state.month = 1;
|
|
||||||
popup_state.year += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ui.memory()
|
|
||||||
.data
|
|
||||||
.insert_persisted(id, popup_state.clone());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
grid.cell(|ui| {
|
|
||||||
ui.with_layout(
|
|
||||||
Layout::top_down_justified(Align::Center),
|
|
||||||
|ui| {
|
|
||||||
if ui
|
|
||||||
.button(">>")
|
|
||||||
.on_hover_text("add one month")
|
|
||||||
.clicked()
|
|
||||||
{
|
|
||||||
popup_state.month += 1;
|
|
||||||
if popup_state.month > 12 {
|
|
||||||
popup_state.month = 1;
|
|
||||||
popup_state.year += 1;
|
|
||||||
}
|
|
||||||
popup_state.day = popup_state
|
|
||||||
.day
|
|
||||||
.min(popup_state.last_day_of_month());
|
|
||||||
ui.memory()
|
|
||||||
.data
|
|
||||||
.insert_persisted(id, popup_state.clone());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
grid.cell(|ui| {
|
|
||||||
ui.with_layout(
|
|
||||||
Layout::top_down_justified(Align::Center),
|
|
||||||
|ui| {
|
|
||||||
if ui
|
|
||||||
.button(">>>")
|
|
||||||
.on_hover_text("add one year")
|
|
||||||
.clicked()
|
|
||||||
{
|
|
||||||
popup_state.year += 1;
|
|
||||||
popup_state.day = popup_state
|
|
||||||
.day
|
|
||||||
.min(popup_state.last_day_of_month());
|
|
||||||
ui.memory()
|
|
||||||
.data
|
|
||||||
.insert_persisted(id, popup_state.clone());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.calendar {
|
if self.arrows {
|
||||||
grid.cell(|ui| {
|
grid.grid(|builder| {
|
||||||
TableBuilder::new(ui, Padding::new(2.0, 0.0))
|
builder.sizes(Size::Remainder, 6).horizontal(|mut grid| {
|
||||||
.scroll(false)
|
|
||||||
.columns(Size::Remainder, if self.calendar_week { 8 } else { 7 })
|
|
||||||
.header(height, |mut header| {
|
|
||||||
if self.calendar_week {
|
|
||||||
header.col(|ui| {
|
|
||||||
ui.with_layout(
|
|
||||||
Layout::centered_and_justified(Direction::TopDown),
|
|
||||||
|ui| {
|
|
||||||
ui.add(Label::new("Week"));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Locale
|
|
||||||
for name in ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"] {
|
|
||||||
header.col(|ui| {
|
|
||||||
ui.with_layout(
|
|
||||||
Layout::centered_and_justified(Direction::TopDown),
|
|
||||||
|ui| {
|
|
||||||
ui.add(Label::new(name));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.body(|mut body| {
|
|
||||||
for week in weeks {
|
|
||||||
body.row(height, |mut row| {
|
|
||||||
if self.calendar_week {
|
|
||||||
row.col(|ui| {
|
|
||||||
ui.add(Label::new(format!("{}", week.number)));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
for day in week.days {
|
|
||||||
row.col(|ui| {
|
|
||||||
ui.with_layout(
|
|
||||||
Layout::top_down_justified(Align::Center),
|
|
||||||
|ui| {
|
|
||||||
//TODO: Colors from egui style
|
|
||||||
let fill_color = if popup_state.year
|
|
||||||
== day.year()
|
|
||||||
&& popup_state.month == day.month()
|
|
||||||
&& popup_state.day == day.day()
|
|
||||||
{
|
|
||||||
Color32::DARK_BLUE
|
|
||||||
} else if day.weekday() == Weekday::Sat
|
|
||||||
|| day.weekday() == Weekday::Sun
|
|
||||||
{
|
|
||||||
Color32::DARK_RED
|
|
||||||
} else {
|
|
||||||
Color32::BLACK
|
|
||||||
};
|
|
||||||
let text_color = if day == today {
|
|
||||||
Color32::RED
|
|
||||||
} else if day.month()
|
|
||||||
== popup_state.month
|
|
||||||
{
|
|
||||||
Color32::WHITE
|
|
||||||
} else {
|
|
||||||
Color32::from_gray(80)
|
|
||||||
};
|
|
||||||
|
|
||||||
let button = Button::new(
|
|
||||||
RichText::new(format!(
|
|
||||||
"{}",
|
|
||||||
day.day()
|
|
||||||
))
|
|
||||||
.color(text_color),
|
|
||||||
)
|
|
||||||
.fill(fill_color);
|
|
||||||
|
|
||||||
if ui.add(button).clicked() {
|
|
||||||
popup_state.year = day.year();
|
|
||||||
popup_state.month = day.month();
|
|
||||||
popup_state.day = day.day();
|
|
||||||
ui.memory().data.insert_persisted(
|
|
||||||
id,
|
|
||||||
popup_state.clone(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
grid.horizontal(|builder| {
|
|
||||||
builder.columns(Size::Remainder, 3).build(|mut grid| {
|
|
||||||
grid.empty();
|
|
||||||
grid.cell(|ui| {
|
grid.cell(|ui| {
|
||||||
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
||||||
if ui.button("Abbrechen").clicked() {
|
if ui
|
||||||
close = true;
|
.button("<<<")
|
||||||
|
.on_hover_text("substract one year")
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
popup_state.year -= 1;
|
||||||
|
popup_state.day =
|
||||||
|
popup_state.day.min(popup_state.last_day_of_month());
|
||||||
|
ui.memory().data.insert_persisted(id, popup_state.clone());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
grid.cell(|ui| {
|
grid.cell(|ui| {
|
||||||
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
||||||
if ui.button("Speichern").clicked() {
|
if ui
|
||||||
*self.selection = Date::from_utc(
|
.button("<<")
|
||||||
NaiveDate::from_ymd(
|
.on_hover_text("substract one month")
|
||||||
popup_state.year,
|
.clicked()
|
||||||
popup_state.month,
|
{
|
||||||
popup_state.day,
|
popup_state.month -= 1;
|
||||||
),
|
if popup_state.month == 0 {
|
||||||
Utc,
|
popup_state.month = 12;
|
||||||
);
|
popup_state.year -= 1;
|
||||||
close = true;
|
}
|
||||||
|
popup_state.day =
|
||||||
|
popup_state.day.min(popup_state.last_day_of_month());
|
||||||
|
ui.memory().data.insert_persisted(id, popup_state.clone());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
grid.cell(|ui| {
|
||||||
|
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
||||||
|
if ui.button("<").on_hover_text("substract one day").clicked() {
|
||||||
|
popup_state.day -= 1;
|
||||||
|
if popup_state.day == 0 {
|
||||||
|
popup_state.month -= 1;
|
||||||
|
if popup_state.month == 0 {
|
||||||
|
popup_state.year -= 1;
|
||||||
|
popup_state.month = 12;
|
||||||
|
}
|
||||||
|
popup_state.day = popup_state.last_day_of_month();
|
||||||
|
}
|
||||||
|
ui.memory().data.insert_persisted(id, popup_state.clone());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
grid.cell(|ui| {
|
||||||
|
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
||||||
|
if ui.button(">").on_hover_text("add one day").clicked() {
|
||||||
|
popup_state.day += 1;
|
||||||
|
if popup_state.day > popup_state.last_day_of_month() {
|
||||||
|
popup_state.day = 1;
|
||||||
|
popup_state.month += 1;
|
||||||
|
if popup_state.month > 12 {
|
||||||
|
popup_state.month = 1;
|
||||||
|
popup_state.year += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui.memory().data.insert_persisted(id, popup_state.clone());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
grid.cell(|ui| {
|
||||||
|
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
||||||
|
if ui.button(">>").on_hover_text("add one month").clicked() {
|
||||||
|
popup_state.month += 1;
|
||||||
|
if popup_state.month > 12 {
|
||||||
|
popup_state.month = 1;
|
||||||
|
popup_state.year += 1;
|
||||||
|
}
|
||||||
|
popup_state.day =
|
||||||
|
popup_state.day.min(popup_state.last_day_of_month());
|
||||||
|
ui.memory().data.insert_persisted(id, popup_state.clone());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
grid.cell(|ui| {
|
||||||
|
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
||||||
|
if ui.button(">>>").on_hover_text("add one year").clicked() {
|
||||||
|
popup_state.year += 1;
|
||||||
|
popup_state.day =
|
||||||
|
popup_state.day.min(popup_state.last_day_of_month());
|
||||||
|
ui.memory().data.insert_persisted(id, popup_state.clone());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.calendar {
|
||||||
|
grid.cell(|ui| {
|
||||||
|
TableBuilder::new(ui, Padding::new(2.0, 0.0))
|
||||||
|
.scroll(false)
|
||||||
|
.columns(Size::Remainder, if self.calendar_week { 8 } else { 7 })
|
||||||
|
.header(height, |mut header| {
|
||||||
|
if self.calendar_week {
|
||||||
|
header.col(|ui| {
|
||||||
|
ui.with_layout(
|
||||||
|
Layout::centered_and_justified(Direction::TopDown),
|
||||||
|
|ui| {
|
||||||
|
ui.add(Label::new("Week"));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Locale
|
||||||
|
for name in ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"] {
|
||||||
|
header.col(|ui| {
|
||||||
|
ui.with_layout(
|
||||||
|
Layout::centered_and_justified(Direction::TopDown),
|
||||||
|
|ui| {
|
||||||
|
ui.add(Label::new(name));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.body(|mut body| {
|
||||||
|
for week in weeks {
|
||||||
|
body.row(height, |mut row| {
|
||||||
|
if self.calendar_week {
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.add(Label::new(format!("{}", week.number)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for day in week.days {
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.with_layout(
|
||||||
|
Layout::top_down_justified(Align::Center),
|
||||||
|
|ui| {
|
||||||
|
//TODO: Colors from egui style
|
||||||
|
let fill_color = if popup_state.year
|
||||||
|
== day.year()
|
||||||
|
&& popup_state.month == day.month()
|
||||||
|
&& popup_state.day == day.day()
|
||||||
|
{
|
||||||
|
Color32::DARK_BLUE
|
||||||
|
} else if day.weekday() == Weekday::Sat
|
||||||
|
|| day.weekday() == Weekday::Sun
|
||||||
|
{
|
||||||
|
Color32::DARK_RED
|
||||||
|
} else {
|
||||||
|
Color32::BLACK
|
||||||
|
};
|
||||||
|
let text_color = if day == today {
|
||||||
|
Color32::RED
|
||||||
|
} else if day.month() == popup_state.month {
|
||||||
|
Color32::WHITE
|
||||||
|
} else {
|
||||||
|
Color32::from_gray(80)
|
||||||
|
};
|
||||||
|
|
||||||
|
let button = Button::new(
|
||||||
|
RichText::new(format!("{}", day.day()))
|
||||||
|
.color(text_color),
|
||||||
|
)
|
||||||
|
.fill(fill_color);
|
||||||
|
|
||||||
|
if ui.add(button).clicked() {
|
||||||
|
popup_state.year = day.year();
|
||||||
|
popup_state.month = day.month();
|
||||||
|
popup_state.day = day.day();
|
||||||
|
ui.memory().data.insert_persisted(
|
||||||
|
id,
|
||||||
|
popup_state.clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
grid.grid(|builder| {
|
||||||
|
builder.sizes(Size::Remainder, 3).horizontal(|mut grid| {
|
||||||
|
grid.empty();
|
||||||
|
grid.cell(|ui| {
|
||||||
|
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
||||||
|
if ui.button("Abbrechen").clicked() {
|
||||||
|
close = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
grid.cell(|ui| {
|
||||||
|
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
||||||
|
if ui.button("Speichern").clicked() {
|
||||||
|
*self.selection = Date::from_utc(
|
||||||
|
NaiveDate::from_ymd(
|
||||||
|
popup_state.year,
|
||||||
|
popup_state.month,
|
||||||
|
popup_state.day,
|
||||||
|
),
|
||||||
|
Utc,
|
||||||
|
);
|
||||||
|
close = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
if close {
|
if close {
|
||||||
popup_state.setup = false;
|
popup_state.setup = false;
|
||||||
|
|
|
@ -25,80 +25,75 @@ impl super::Demo for GridDemo {
|
||||||
|
|
||||||
impl super::View for GridDemo {
|
impl super::View for GridDemo {
|
||||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||||
GridBuilder::new(ui, Padding::new(0.0, 5.0)).vertical(|builder| {
|
GridBuilder::new(ui, Padding::new(0.0, 5.0))
|
||||||
builder
|
.size(Size::Absolute(50.0))
|
||||||
.row(Size::Absolute(50.0))
|
.size(Size::Remainder)
|
||||||
.row(Size::Remainder)
|
.size(Size::RelativeMinimum {
|
||||||
.row(Size::RelativeMinimum {
|
relative: 0.5,
|
||||||
relative: 0.5,
|
minimum: 60.0,
|
||||||
minimum: 60.0,
|
})
|
||||||
})
|
.vertical(|mut grid| {
|
||||||
.build(|mut grid| {
|
grid.cell(|ui| {
|
||||||
grid.cell(|ui| {
|
ui.painter()
|
||||||
ui.painter().rect_filled(
|
.rect_filled(ui.available_rect_before_wrap(), 0.0, Color32::BLUE);
|
||||||
ui.available_rect_before_wrap(),
|
});
|
||||||
0.0,
|
grid.grid(|builder| {
|
||||||
Color32::BLUE,
|
builder.sizes(Size::Remainder, 2).horizontal(|mut grid| {
|
||||||
);
|
grid.cell(|ui| {
|
||||||
});
|
ui.painter().rect_filled(
|
||||||
grid.horizontal(|builder| {
|
ui.available_rect_before_wrap(),
|
||||||
builder.columns(Size::Remainder, 2).build(|mut grid| {
|
0.0,
|
||||||
grid.cell(|ui| {
|
Color32::RED,
|
||||||
ui.painter().rect_filled(
|
);
|
||||||
ui.available_rect_before_wrap(),
|
|
||||||
0.0,
|
|
||||||
Color32::RED,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
grid.vertical(|builder| {
|
|
||||||
builder.rows(Size::Remainder, 3).build(|mut grid| {
|
|
||||||
grid.empty();
|
|
||||||
grid.cell(|ui| {
|
|
||||||
ui.painter().rect_filled(
|
|
||||||
ui.available_rect_before_wrap(),
|
|
||||||
0.0,
|
|
||||||
Color32::YELLOW,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
grid.grid(|builder| {
|
||||||
grid.horizontal(|builder| {
|
builder.sizes(Size::Remainder, 3).vertical(|mut grid| {
|
||||||
builder
|
|
||||||
.column(Size::Remainder)
|
|
||||||
.column(Size::Absolute(50.0))
|
|
||||||
.column(Size::Remainder)
|
|
||||||
.column(Size::Absolute(70.0))
|
|
||||||
.build(|mut grid| {
|
|
||||||
grid.empty();
|
|
||||||
grid.vertical(|builder| {
|
|
||||||
builder
|
|
||||||
.row(Size::Remainder)
|
|
||||||
.row(Size::Absolute(50.0))
|
|
||||||
.row(Size::Remainder)
|
|
||||||
.build(|mut grid| {
|
|
||||||
grid.empty();
|
|
||||||
grid.cell(|ui| {
|
|
||||||
ui.painter().rect_filled(
|
|
||||||
ui.available_rect_before_wrap(),
|
|
||||||
0.0,
|
|
||||||
Color32::GOLD,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
grid.empty();
|
grid.empty();
|
||||||
grid.cell(|ui| {
|
grid.cell(|ui| {
|
||||||
ui.painter().rect_filled(
|
ui.painter().rect_filled(
|
||||||
ui.available_rect_before_wrap(),
|
ui.available_rect_before_wrap(),
|
||||||
0.0,
|
0.0,
|
||||||
Color32::GREEN,
|
Color32::YELLOW,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
grid.grid(|builder| {
|
||||||
|
builder
|
||||||
|
.size(Size::Remainder)
|
||||||
|
.size(Size::Absolute(50.0))
|
||||||
|
.size(Size::Remainder)
|
||||||
|
.size(Size::Absolute(70.0))
|
||||||
|
.horizontal(|mut grid| {
|
||||||
|
grid.empty();
|
||||||
|
grid.grid(|builder| {
|
||||||
|
builder
|
||||||
|
.size(Size::Remainder)
|
||||||
|
.size(Size::Absolute(50.0))
|
||||||
|
.size(Size::Remainder)
|
||||||
|
.vertical(|mut grid| {
|
||||||
|
grid.empty();
|
||||||
|
grid.cell(|ui| {
|
||||||
|
ui.painter().rect_filled(
|
||||||
|
ui.available_rect_before_wrap(),
|
||||||
|
0.0,
|
||||||
|
Color32::GOLD,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
grid.empty();
|
||||||
|
grid.cell(|ui| {
|
||||||
|
ui.painter().rect_filled(
|
||||||
|
ui.available_rect_before_wrap(),
|
||||||
|
0.0,
|
||||||
|
Color32::GREEN,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,158 @@
|
||||||
mod horizontal;
|
use crate::{
|
||||||
mod vertical;
|
layout::{CellSize, Layout, LineDirection},
|
||||||
|
sizing::Sizing,
|
||||||
use crate::Padding;
|
Padding, Size,
|
||||||
|
};
|
||||||
use egui::Ui;
|
use egui::Ui;
|
||||||
pub use horizontal::*;
|
|
||||||
pub use vertical::*;
|
enum GridDirection {
|
||||||
|
Horizontal,
|
||||||
|
Vertical,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct GridBuilder<'a> {
|
pub struct GridBuilder<'a> {
|
||||||
ui: &'a mut Ui,
|
ui: &'a mut Ui,
|
||||||
|
sizing: Sizing,
|
||||||
padding: Padding,
|
padding: Padding,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> GridBuilder<'a> {
|
impl<'a> GridBuilder<'a> {
|
||||||
|
/// Create new grid builder
|
||||||
|
/// After adding size hints with [Self::column]/[Self::columns] the grid can be build with [Self::horizontal]/[Self::vertical]
|
||||||
pub fn new(ui: &'a mut Ui, padding: Padding) -> Self {
|
pub fn new(ui: &'a mut Ui, padding: Padding) -> Self {
|
||||||
Self { ui, padding }
|
let sizing = Sizing::new();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
ui,
|
||||||
|
sizing,
|
||||||
|
padding,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn horizontal(self, horizontal_grid_builder: impl FnOnce(HorizontalGridBuilder)) {
|
/// Add size hint for column/row
|
||||||
horizontal_grid_builder(HorizontalGridBuilder::new(self.ui, self.padding));
|
pub fn size(mut self, size: Size) -> Self {
|
||||||
|
self.sizing.add_size(size);
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vertical(self, vertical_grid_builder: impl FnOnce(VerticalGridBuilder)) {
|
/// Add size hint for columns/rows [count] times
|
||||||
vertical_grid_builder(VerticalGridBuilder::new(self.ui, self.padding));
|
pub fn sizes(mut self, size: Size, count: usize) -> Self {
|
||||||
|
for _ in 0..count {
|
||||||
|
self.sizing.add_size(size.clone());
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build horizontal grid
|
||||||
|
pub fn horizontal<F>(self, grid: F)
|
||||||
|
where
|
||||||
|
F: for<'b> FnOnce(Grid<'a, 'b>),
|
||||||
|
{
|
||||||
|
let widths = self.sizing.into_lengths(
|
||||||
|
self.ui.available_rect_before_wrap().width() - 2.0 * self.padding.outer,
|
||||||
|
self.padding.inner,
|
||||||
|
);
|
||||||
|
let mut layout = Layout::new(self.ui, self.padding.clone(), LineDirection::TopToBottom);
|
||||||
|
grid(Grid {
|
||||||
|
layout: &mut layout,
|
||||||
|
direction: GridDirection::Horizontal,
|
||||||
|
padding: self.padding.clone(),
|
||||||
|
widths,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build vertical grid
|
||||||
|
pub fn vertical<F>(self, grid: F)
|
||||||
|
where
|
||||||
|
F: for<'b> FnOnce(Grid<'a, 'b>),
|
||||||
|
{
|
||||||
|
let widths = self.sizing.into_lengths(
|
||||||
|
self.ui.available_rect_before_wrap().height() - 2.0 * self.padding.outer,
|
||||||
|
self.padding.inner,
|
||||||
|
);
|
||||||
|
let mut layout = Layout::new(self.ui, self.padding.clone(), LineDirection::LeftToRight);
|
||||||
|
grid(Grid {
|
||||||
|
layout: &mut layout,
|
||||||
|
direction: GridDirection::Vertical,
|
||||||
|
padding: self.padding.clone(),
|
||||||
|
widths,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Grid<'a, 'b> {
|
||||||
|
layout: &'b mut Layout<'a>,
|
||||||
|
direction: GridDirection,
|
||||||
|
padding: Padding,
|
||||||
|
widths: Vec<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'b> Grid<'a, 'b> {
|
||||||
|
fn size(&mut self) -> (CellSize, CellSize) {
|
||||||
|
match self.direction {
|
||||||
|
GridDirection::Horizontal => (
|
||||||
|
CellSize::Absolute(self.widths.remove(0)),
|
||||||
|
CellSize::Remainder,
|
||||||
|
),
|
||||||
|
GridDirection::Vertical => (
|
||||||
|
CellSize::Remainder,
|
||||||
|
CellSize::Absolute(self.widths.remove(0)),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add empty cell
|
||||||
|
pub fn empty(&mut self) {
|
||||||
|
assert!(
|
||||||
|
!self.widths.is_empty(),
|
||||||
|
"Tried using more grid cells then available."
|
||||||
|
);
|
||||||
|
|
||||||
|
let (width, height) = self.size();
|
||||||
|
self.layout.empty(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _cell(&mut self, clip: bool, add_contents: impl FnOnce(&mut Ui)) {
|
||||||
|
assert!(
|
||||||
|
!self.widths.is_empty(),
|
||||||
|
"Tried using more grid cells then available."
|
||||||
|
);
|
||||||
|
|
||||||
|
let (width, height) = self.size();
|
||||||
|
self.layout.add(width, height, clip, add_contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add cell, content is clipped
|
||||||
|
pub fn cell(&mut self, add_contents: impl FnOnce(&mut Ui)) {
|
||||||
|
self._cell(true, add_contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add cell, content is not clipped
|
||||||
|
pub fn cell_noclip(&mut self, add_contents: impl FnOnce(&mut Ui)) {
|
||||||
|
self._cell(false, add_contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _grid(&mut self, clip: bool, grid_builder: impl FnOnce(GridBuilder)) {
|
||||||
|
let padding = self.padding.clone();
|
||||||
|
self._cell(clip, |ui| {
|
||||||
|
grid_builder(GridBuilder::new(ui, padding));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/// Add grid as cell, content is clipped
|
||||||
|
pub fn grid(&mut self, grid_builder: impl FnOnce(GridBuilder)) {
|
||||||
|
self._grid(true, grid_builder)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add grid as cell, content is not clipped
|
||||||
|
pub fn grid_noclip(&mut self, grid_builder: impl FnOnce(GridBuilder)) {
|
||||||
|
self._grid(false, grid_builder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'b> Drop for Grid<'a, 'b> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
while !self.widths.is_empty() {
|
||||||
|
self.empty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,157 +0,0 @@
|
||||||
use crate::{
|
|
||||||
layout::{CellSize, LineDirection},
|
|
||||||
sizing::Sizing,
|
|
||||||
Layout, Padding, Size,
|
|
||||||
};
|
|
||||||
use egui::Ui;
|
|
||||||
|
|
||||||
use super::VerticalGridBuilder;
|
|
||||||
|
|
||||||
pub struct HorizontalGridBuilder<'a> {
|
|
||||||
ui: &'a mut Ui,
|
|
||||||
padding: Padding,
|
|
||||||
sizing: Sizing,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> HorizontalGridBuilder<'a> {
|
|
||||||
/// Create new grid builder for horizontal grid
|
|
||||||
/// After adding size hints with [Self::column]/[Self::columns] the grid can be build with [Self::build]
|
|
||||||
pub(crate) fn new(ui: &'a mut Ui, padding: Padding) -> Self {
|
|
||||||
let layouter = Sizing::new(
|
|
||||||
ui.available_rect_before_wrap().width() - 2.0 * padding.outer,
|
|
||||||
padding.inner,
|
|
||||||
);
|
|
||||||
|
|
||||||
Self {
|
|
||||||
ui,
|
|
||||||
padding,
|
|
||||||
sizing: layouter,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add size hint for column
|
|
||||||
pub fn column(mut self, size: Size) -> Self {
|
|
||||||
self.sizing.add_size(size);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add size hint for columns [count] times
|
|
||||||
pub fn columns(mut self, size: Size, count: usize) -> Self {
|
|
||||||
for _ in 0..count {
|
|
||||||
self.sizing.add_size(size.clone());
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Build grid
|
|
||||||
pub fn build<F>(self, horizontal_grid: F)
|
|
||||||
where
|
|
||||||
F: for<'b> FnOnce(HorizontalGrid<'a, 'b>),
|
|
||||||
{
|
|
||||||
let widths = self.sizing.into_lengths();
|
|
||||||
let mut layout = Layout::new(self.ui, self.padding.clone(), LineDirection::TopToBottom);
|
|
||||||
let grid = HorizontalGrid {
|
|
||||||
layout: &mut layout,
|
|
||||||
padding: self.padding.clone(),
|
|
||||||
widths,
|
|
||||||
};
|
|
||||||
horizontal_grid(grid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct HorizontalGrid<'a, 'b> {
|
|
||||||
layout: &'b mut Layout<'a>,
|
|
||||||
padding: Padding,
|
|
||||||
widths: Vec<f32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'b> HorizontalGrid<'a, 'b> {
|
|
||||||
/// Add empty cell
|
|
||||||
pub fn empty(&mut self) {
|
|
||||||
assert!(
|
|
||||||
!self.widths.is_empty(),
|
|
||||||
"Tried using more grid cells then available."
|
|
||||||
);
|
|
||||||
|
|
||||||
self.layout.empty(
|
|
||||||
CellSize::Absolute(self.widths.remove(0)),
|
|
||||||
CellSize::Remainder,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn _cell(&mut self, clip: bool, add_contents: impl FnOnce(&mut Ui)) {
|
|
||||||
assert!(
|
|
||||||
!self.widths.is_empty(),
|
|
||||||
"Tried using more grid cells then available."
|
|
||||||
);
|
|
||||||
|
|
||||||
self.layout.add(
|
|
||||||
CellSize::Absolute(self.widths.remove(0)),
|
|
||||||
CellSize::Remainder,
|
|
||||||
clip,
|
|
||||||
add_contents,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add cell, content is clipped
|
|
||||||
pub fn cell(&mut self, add_contents: impl FnOnce(&mut Ui)) {
|
|
||||||
self._cell(true, add_contents);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add cell, content is not clipped
|
|
||||||
pub fn cell_noclip(&mut self, add_contents: impl FnOnce(&mut Ui)) {
|
|
||||||
self._cell(false, add_contents);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn _horizontal(
|
|
||||||
&mut self,
|
|
||||||
clip: bool,
|
|
||||||
horizontal_grid_builder: impl FnOnce(HorizontalGridBuilder),
|
|
||||||
) {
|
|
||||||
let padding = self.padding.clone();
|
|
||||||
self._cell(clip, |ui| {
|
|
||||||
horizontal_grid_builder(HorizontalGridBuilder::new(ui, padding));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/// Add horizontal grid as cell, content is clipped
|
|
||||||
pub fn horizontal(&mut self, horizontal_grid_builder: impl FnOnce(HorizontalGridBuilder)) {
|
|
||||||
self._horizontal(true, horizontal_grid_builder)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add horizontal grid as cell, content is not clipped
|
|
||||||
pub fn horizontal_noclip(
|
|
||||||
&mut self,
|
|
||||||
horizontal_grid_builder: impl FnOnce(HorizontalGridBuilder),
|
|
||||||
) {
|
|
||||||
self._horizontal(false, horizontal_grid_builder)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn _vertical(
|
|
||||||
&mut self,
|
|
||||||
clip: bool,
|
|
||||||
vertical_grid_builder: impl FnOnce(VerticalGridBuilder),
|
|
||||||
) {
|
|
||||||
let padding = self.padding.clone();
|
|
||||||
self._cell(clip, |ui| {
|
|
||||||
vertical_grid_builder(VerticalGridBuilder::new(ui, padding));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add vertical grid as cell, content is clipped
|
|
||||||
pub fn vertical(&mut self, vertical_grid_builder: impl FnOnce(VerticalGridBuilder)) {
|
|
||||||
self._vertical(true, vertical_grid_builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add vertical grid as cell, content is not clipped
|
|
||||||
pub fn vertical_noclip(&mut self, vertical_grid_builder: impl FnOnce(VerticalGridBuilder)) {
|
|
||||||
self._vertical(false, vertical_grid_builder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'b> Drop for HorizontalGrid<'a, 'b> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
while !self.widths.is_empty() {
|
|
||||||
self.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,158 +0,0 @@
|
||||||
use crate::{layout::CellSize, sizing::Sizing, Layout, Padding, Size};
|
|
||||||
use egui::Ui;
|
|
||||||
|
|
||||||
use super::HorizontalGridBuilder;
|
|
||||||
|
|
||||||
pub struct VerticalGridBuilder<'a> {
|
|
||||||
ui: &'a mut Ui,
|
|
||||||
padding: Padding,
|
|
||||||
sizing: Sizing,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> VerticalGridBuilder<'a> {
|
|
||||||
/// Create new grid builder for vertical grid
|
|
||||||
/// After adding size hints with [Self::row]/[Self::rows] the grid can be build with [Self::build]
|
|
||||||
pub(crate) fn new(ui: &'a mut Ui, padding: Padding) -> Self {
|
|
||||||
let layouter = Sizing::new(
|
|
||||||
ui.available_rect_before_wrap().height() - 2.0 * padding.outer,
|
|
||||||
padding.inner,
|
|
||||||
);
|
|
||||||
|
|
||||||
Self {
|
|
||||||
ui,
|
|
||||||
padding,
|
|
||||||
sizing: layouter,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add size hint for row
|
|
||||||
pub fn row(mut self, size: Size) -> Self {
|
|
||||||
self.sizing.add_size(size);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add size hint for rows [count] times
|
|
||||||
pub fn rows(mut self, size: Size, count: usize) -> Self {
|
|
||||||
for _ in 0..count {
|
|
||||||
self.sizing.add_size(size.clone());
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Build grid
|
|
||||||
pub fn build<F>(self, vertical_grid: F)
|
|
||||||
where
|
|
||||||
F: for<'b> FnOnce(VerticalGrid<'a, 'b>),
|
|
||||||
{
|
|
||||||
let heights = self.sizing.into_lengths();
|
|
||||||
let mut layout = Layout::new(
|
|
||||||
self.ui,
|
|
||||||
self.padding.clone(),
|
|
||||||
crate::layout::LineDirection::LeftToRight,
|
|
||||||
);
|
|
||||||
let grid = VerticalGrid {
|
|
||||||
layout: &mut layout,
|
|
||||||
padding: self.padding.clone(),
|
|
||||||
heights,
|
|
||||||
};
|
|
||||||
vertical_grid(grid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct VerticalGrid<'a, 'b> {
|
|
||||||
layout: &'b mut Layout<'a>,
|
|
||||||
padding: Padding,
|
|
||||||
heights: Vec<f32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'b> VerticalGrid<'a, 'b> {
|
|
||||||
/// Add empty cell
|
|
||||||
pub fn empty(&mut self) {
|
|
||||||
assert!(
|
|
||||||
!self.heights.is_empty(),
|
|
||||||
"Tried using more grid cells then available."
|
|
||||||
);
|
|
||||||
|
|
||||||
self.layout.empty(
|
|
||||||
CellSize::Remainder,
|
|
||||||
CellSize::Absolute(self.heights.remove(0)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn _cell(&mut self, clip: bool, add_contents: impl FnOnce(&mut Ui)) {
|
|
||||||
assert!(
|
|
||||||
!self.heights.is_empty(),
|
|
||||||
"Tried using more grid cells then available."
|
|
||||||
);
|
|
||||||
|
|
||||||
self.layout.add(
|
|
||||||
CellSize::Remainder,
|
|
||||||
CellSize::Absolute(self.heights.remove(0)),
|
|
||||||
clip,
|
|
||||||
add_contents,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add cell, content is clipped
|
|
||||||
pub fn cell(&mut self, add_contents: impl FnOnce(&mut Ui)) {
|
|
||||||
self._cell(true, add_contents);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add cell, content is not clipped
|
|
||||||
pub fn cell_noclip(&mut self, add_contents: impl FnOnce(&mut Ui)) {
|
|
||||||
self._cell(false, add_contents);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn _horizontal(
|
|
||||||
&mut self,
|
|
||||||
clip: bool,
|
|
||||||
horizontal_grid_builder: impl FnOnce(HorizontalGridBuilder),
|
|
||||||
) {
|
|
||||||
let padding = self.padding.clone();
|
|
||||||
self._cell(clip, |ui| {
|
|
||||||
horizontal_grid_builder(HorizontalGridBuilder::new(ui, padding));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add horizontal grid as cell, content is clipped
|
|
||||||
pub fn horizontal(&mut self, horizontal_grid_builder: impl FnOnce(HorizontalGridBuilder)) {
|
|
||||||
self._horizontal(true, horizontal_grid_builder)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add horizontal grid as cell, content is not clipped
|
|
||||||
pub fn horizontal_noclip(
|
|
||||||
&mut self,
|
|
||||||
horizontal_grid_builder: impl FnOnce(HorizontalGridBuilder),
|
|
||||||
) {
|
|
||||||
self._horizontal(false, horizontal_grid_builder)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn _vertical(
|
|
||||||
&mut self,
|
|
||||||
clip: bool,
|
|
||||||
vertical_grid_builder: impl FnOnce(VerticalGridBuilder),
|
|
||||||
) {
|
|
||||||
let padding = self.padding.clone();
|
|
||||||
self._cell(clip, |ui| {
|
|
||||||
vertical_grid_builder(VerticalGridBuilder::new(ui, padding));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add vertical grid as cell, content is clipped
|
|
||||||
pub fn vertical(&mut self, vertical_grid_builder: impl FnOnce(VerticalGridBuilder)) {
|
|
||||||
self._vertical(true, vertical_grid_builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add vertical grid as cell, content is not clipped
|
|
||||||
pub fn vertical_noclip(&mut self, vertical_grid_builder: impl FnOnce(VerticalGridBuilder)) {
|
|
||||||
self._vertical(false, vertical_grid_builder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'b> Drop for VerticalGrid<'a, 'b> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
while !self.heights.is_empty() {
|
|
||||||
self.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -19,27 +19,20 @@ pub enum Size {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Sizing {
|
pub struct Sizing {
|
||||||
length: f32,
|
|
||||||
inner_padding: f32,
|
|
||||||
sizes: Vec<Size>,
|
sizes: Vec<Size>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sizing {
|
impl Sizing {
|
||||||
pub fn new(length: f32, inner_padding: f32) -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self { sizes: vec![] }
|
||||||
length,
|
|
||||||
inner_padding,
|
|
||||||
sizes: vec![],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_size(&mut self, size: Size) {
|
pub fn add_size(&mut self, size: Size) {
|
||||||
self.sizes.push(size);
|
self.sizes.push(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_lengths(self) -> Vec<f32> {
|
pub fn into_lengths(self, length: f32, inner_padding: f32) -> Vec<f32> {
|
||||||
let mut remainders = 0;
|
let mut remainders = 0;
|
||||||
let length = self.length;
|
|
||||||
let sum_non_remainder = self
|
let sum_non_remainder = self
|
||||||
.sizes
|
.sizes
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -61,7 +54,7 @@ impl Sizing {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.sum::<f32>()
|
.sum::<f32>()
|
||||||
+ self.inner_padding * (self.sizes.len() + 1) as f32;
|
+ inner_padding * (self.sizes.len() + 1) as f32;
|
||||||
|
|
||||||
let avg_remainder_length = if remainders == 0 {
|
let avg_remainder_length = if remainders == 0 {
|
||||||
0.0
|
0.0
|
||||||
|
|
|
@ -20,10 +20,7 @@ pub struct TableBuilder<'a> {
|
||||||
|
|
||||||
impl<'a> TableBuilder<'a> {
|
impl<'a> TableBuilder<'a> {
|
||||||
pub fn new(ui: &'a mut Ui, padding: Padding) -> Self {
|
pub fn new(ui: &'a mut Ui, padding: Padding) -> Self {
|
||||||
let sizing = Sizing::new(
|
let sizing = Sizing::new();
|
||||||
ui.available_rect_before_wrap().width() - 2.0 * padding.outer,
|
|
||||||
padding.inner,
|
|
||||||
);
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
ui,
|
ui,
|
||||||
|
@ -62,7 +59,10 @@ impl<'a> TableBuilder<'a> {
|
||||||
|
|
||||||
/// Create a header row which always stays visible and at the top
|
/// Create a header row which always stays visible and at the top
|
||||||
pub fn header(self, height: f32, header: impl FnOnce(TableRow<'_, '_>)) -> Table<'a> {
|
pub fn header(self, height: f32, header: impl FnOnce(TableRow<'_, '_>)) -> Table<'a> {
|
||||||
let widths = self.sizing.into_lengths();
|
let widths = self.sizing.into_lengths(
|
||||||
|
self.ui.available_rect_before_wrap().width() - 2.0 * self.padding.outer,
|
||||||
|
self.padding.inner,
|
||||||
|
);
|
||||||
let ui = self.ui;
|
let ui = self.ui;
|
||||||
{
|
{
|
||||||
let mut layout = Layout::new(ui, self.padding.clone(), LineDirection::TopToBottom);
|
let mut layout = Layout::new(ui, self.padding.clone(), LineDirection::TopToBottom);
|
||||||
|
@ -92,7 +92,10 @@ impl<'a> TableBuilder<'a> {
|
||||||
where
|
where
|
||||||
F: for<'b> FnOnce(TableBody<'b>),
|
F: for<'b> FnOnce(TableBody<'b>),
|
||||||
{
|
{
|
||||||
let widths = self.sizing.into_lengths();
|
let widths = self.sizing.into_lengths(
|
||||||
|
self.ui.available_rect_before_wrap().width() - 2.0 * self.padding.outer,
|
||||||
|
self.padding.inner,
|
||||||
|
);
|
||||||
|
|
||||||
Table {
|
Table {
|
||||||
ui: self.ui,
|
ui: self.ui,
|
||||||
|
|
Loading…
Reference in a new issue