mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-24 10:16:59 -06:00
Merge pull request #1667 from MarekSpodBiedry/issue-1655
Make the start screen scrollable on short windows (#1655)
This commit is contained in:
@@ -852,85 +852,97 @@ pub fn start_screen(app: &mut DesignApp, ui: &mut egui::Ui) {
|
||||
egui::Align::Min
|
||||
})),
|
||||
|ui| {
|
||||
ui.label(crate::rtl::widget(
|
||||
ui,
|
||||
egui::RichText::new(crate::i18n::tr(&app.ui.language, "Welcome to DesignCraft")).font(semibold(28.0)).color(t.text_strong),
|
||||
));
|
||||
ui.label(crate::rtl::widget(
|
||||
ui,
|
||||
egui::RichText::new(crate::i18n::tr(&app.ui.language, "Page layout for print and screen — fast, open and scriptable."))
|
||||
.size(15.0)
|
||||
.color(t.text_dim),
|
||||
));
|
||||
ui.add_space(24.0);
|
||||
ui.horizontal(|ui| {
|
||||
if ui
|
||||
.add(
|
||||
egui::Button::new(crate::rtl::widget(
|
||||
ui,
|
||||
egui::RichText::new(crate::i18n::tr(&app.ui.language, " New file ")).size(14.0).color(Color32::WHITE),
|
||||
))
|
||||
.fill(t.accent_strong)
|
||||
.corner_radius(16.0)
|
||||
.min_size(vec2(0.0, 32.0)),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
let _ = app.run("app.newDocumentDialog", json!({}));
|
||||
}
|
||||
if ui
|
||||
.add(
|
||||
egui::Button::new(crate::rtl::widget(ui, egui::RichText::new(crate::i18n::tr(&app.ui.language, " Open ")).size(14.0)))
|
||||
egui::ScrollArea::vertical().auto_shrink([false, false]).show(ui, |ui| {
|
||||
ui.label(crate::rtl::widget(
|
||||
ui,
|
||||
egui::RichText::new(crate::i18n::tr(&app.ui.language, "Welcome to DesignCraft")).font(semibold(28.0)).color(t.text_strong),
|
||||
));
|
||||
ui.label(crate::rtl::widget(
|
||||
ui,
|
||||
egui::RichText::new(crate::i18n::tr(&app.ui.language, "Page layout for print and screen — fast, open and scriptable."))
|
||||
.size(15.0)
|
||||
.color(t.text_dim),
|
||||
));
|
||||
ui.add_space(24.0);
|
||||
ui.horizontal(|ui| {
|
||||
if ui
|
||||
.add(
|
||||
egui::Button::new(crate::rtl::widget(
|
||||
ui,
|
||||
egui::RichText::new(crate::i18n::tr(&app.ui.language, " New file ")).size(14.0).color(Color32::WHITE),
|
||||
))
|
||||
.fill(t.accent_strong)
|
||||
.corner_radius(16.0)
|
||||
.min_size(vec2(0.0, 32.0)),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
let _ = app.run("app.openDialog", json!({}));
|
||||
}
|
||||
if ui
|
||||
.add(
|
||||
egui::Button::new(crate::rtl::widget(
|
||||
ui,
|
||||
egui::RichText::new(crate::i18n::tr(&app.ui.language, " Open sample magazine ")).size(14.0),
|
||||
))
|
||||
.corner_radius(16.0)
|
||||
.min_size(vec2(0.0, 32.0)),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
let _ = app.run("file.newSample", json!({}));
|
||||
}
|
||||
});
|
||||
ui.add_space(20.0);
|
||||
community_card(app, ui);
|
||||
recent_files(app, ui);
|
||||
ui.add_space(24.0);
|
||||
ui.label(crate::rtl::widget(
|
||||
ui,
|
||||
egui::RichText::new(crate::i18n::tr(&app.ui.language, "Start a new document")).font(semibold(15.0)).color(t.text_strong),
|
||||
));
|
||||
ui.add_space(8.0);
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
for p in designcraft_doc::build::PRESETS.iter().filter(|p| p.intent == designcraft_doc::Intent::Print) {
|
||||
let (cr, resp) = ui.allocate_exact_size(vec2(120.0, 150.0), Sense::click());
|
||||
let hov = resp.hovered();
|
||||
ui.painter().rect_filled(cr, 6.0, if hov { t.hover } else { t.panel });
|
||||
let k = (80.0 / p.width.max(p.height)) as f32;
|
||||
let pr = egui::Rect::from_center_size(cr.center() - vec2(0.0, 14.0), vec2(p.width as f32 * k, p.height as f32 * k));
|
||||
ui.painter().rect_filled(pr, 0.0, Color32::from_gray(245));
|
||||
ui.painter().text(egui::pos2(cr.center().x, cr.max.y - 26.0), egui::Align2::CENTER_CENTER, p.name, semibold(12.0), t.text_strong);
|
||||
ui.painter().text(
|
||||
egui::pos2(cr.center().x, cr.max.y - 11.0),
|
||||
egui::Align2::CENTER_CENTER,
|
||||
format!("{} × {}", designcraft_geom::format_measure(p.width, p.units), designcraft_geom::format_measure(p.height, p.units)),
|
||||
egui::FontId::proportional(10.0),
|
||||
t.text_dim,
|
||||
);
|
||||
if resp.clicked() {
|
||||
let _ = app.run("file.new", json!({"preset": p.name}));
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
let _ = app.run("app.newDocumentDialog", json!({}));
|
||||
}
|
||||
}
|
||||
if ui
|
||||
.add(
|
||||
egui::Button::new(crate::rtl::widget(ui, egui::RichText::new(crate::i18n::tr(&app.ui.language, " Open ")).size(14.0)))
|
||||
.corner_radius(16.0)
|
||||
.min_size(vec2(0.0, 32.0)),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
let _ = app.run("app.openDialog", json!({}));
|
||||
}
|
||||
if ui
|
||||
.add(
|
||||
egui::Button::new(crate::rtl::widget(
|
||||
ui,
|
||||
egui::RichText::new(crate::i18n::tr(&app.ui.language, " Open sample magazine ")).size(14.0),
|
||||
))
|
||||
.corner_radius(16.0)
|
||||
.min_size(vec2(0.0, 32.0)),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
let _ = app.run("file.newSample", json!({}));
|
||||
}
|
||||
});
|
||||
ui.add_space(20.0);
|
||||
community_card(app, ui);
|
||||
recent_files(app, ui);
|
||||
ui.add_space(24.0);
|
||||
ui.label(crate::rtl::widget(
|
||||
ui,
|
||||
egui::RichText::new(crate::i18n::tr(&app.ui.language, "Start a new document")).font(semibold(15.0)).color(t.text_strong),
|
||||
));
|
||||
ui.add_space(8.0);
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
for p in designcraft_doc::build::PRESETS.iter().filter(|p| p.intent == designcraft_doc::Intent::Print) {
|
||||
let (cr, resp) = ui.allocate_exact_size(vec2(120.0, 150.0), Sense::click());
|
||||
let hov = resp.hovered();
|
||||
ui.painter().rect_filled(cr, 6.0, if hov { t.hover } else { t.panel });
|
||||
let k = (80.0 / p.width.max(p.height)) as f32;
|
||||
let pr = egui::Rect::from_center_size(cr.center() - vec2(0.0, 14.0), vec2(p.width as f32 * k, p.height as f32 * k));
|
||||
ui.painter().rect_filled(pr, 0.0, Color32::from_gray(245));
|
||||
ui.painter().text(
|
||||
egui::pos2(cr.center().x, cr.max.y - 26.0),
|
||||
egui::Align2::CENTER_CENTER,
|
||||
p.name,
|
||||
semibold(12.0),
|
||||
t.text_strong,
|
||||
);
|
||||
ui.painter().text(
|
||||
egui::pos2(cr.center().x, cr.max.y - 11.0),
|
||||
egui::Align2::CENTER_CENTER,
|
||||
format!(
|
||||
"{} × {}",
|
||||
designcraft_geom::format_measure(p.width, p.units),
|
||||
designcraft_geom::format_measure(p.height, p.units)
|
||||
),
|
||||
egui::FontId::proportional(10.0),
|
||||
t.text_dim,
|
||||
);
|
||||
if resp.clicked() {
|
||||
let _ = app.run("file.new", json!({"preset": p.name}));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
@@ -5642,4 +5642,45 @@ mod tests {
|
||||
assert!(texts.iter().any(|t| t == "Recent files"), "{texts:?}");
|
||||
assert!(texts.iter().any(|t| t == "gone"), "the card names it without `.designcraft`: {texts:?}");
|
||||
}
|
||||
|
||||
/// On a short window (1366 x 768 laptops) the start screen is taller than the window; the part
|
||||
/// below the fold has to be reachable by scrolling instead of being cut off.
|
||||
#[test]
|
||||
fn start_screen_scrolls_when_the_window_is_too_short() {
|
||||
let mut app = crate::DesignApp::new(designcraft_engine::Session::new(), crate::Services::default());
|
||||
let ctx = egui::Context::default();
|
||||
crate::theme::install_fonts(&ctx, "");
|
||||
let size = egui::vec2(1366.0, 300.0);
|
||||
let mut tile_y = |events: Vec<egui::Event>| {
|
||||
let input = egui::RawInput { screen_rect: Some(egui::Rect::from_min_size(egui::Pos2::ZERO, size)), events, ..Default::default() };
|
||||
let mut out = ctx.run_ui(input, |ui| {
|
||||
app.logic(&ui.ctx().clone());
|
||||
app.ui(ui);
|
||||
});
|
||||
out.textures_delta.clear();
|
||||
out.shapes.iter().find_map(|s| match &s.shape {
|
||||
// The preset tiles paint their names even when scrolled out of view (labels skip that).
|
||||
egui::Shape::Text(t) if t.galley.text() == "Tabloid" => Some(t.pos.y),
|
||||
_ => None,
|
||||
})
|
||||
};
|
||||
let at = egui::pos2(600.0, 150.0);
|
||||
let mut before = None;
|
||||
for _ in 0..3 {
|
||||
before = tile_y(vec![egui::Event::PointerMoved(at)]);
|
||||
}
|
||||
let before = before.expect("the Tabloid tile is laid out");
|
||||
let wheel = egui::Event::MouseWheel {
|
||||
unit: egui::MouseWheelUnit::Point,
|
||||
delta: egui::vec2(0.0, -400.0),
|
||||
phase: egui::TouchPhase::Move,
|
||||
modifiers: egui::Modifiers::NONE,
|
||||
};
|
||||
let mut after = tile_y(vec![egui::Event::PointerMoved(at), wheel]);
|
||||
for _ in 0..30 {
|
||||
after = tile_y(Vec::new());
|
||||
}
|
||||
let after = after.expect("the Tabloid tile is laid out");
|
||||
assert!(after < before - 50.0, "the start screen should scroll: {before} -> {after}");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user