mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-31 06:06:48 -06:00
Merge the fixed #104 branch (which carries #31 and #38) and restructure the Brazilian Portuguese language onto its per-language layout: - The PORTUGUESE table moves, unchanged, to crates/ui-egui/src/i18n/pt.rs as pt::translate, like zh/ko/ru. Language::PtBr gets code() "pt" (parse also accepts pt-BR/pt_BR via the tag reduction); it is still saved as "pt". - No per-language command: the View combo and the control channel switch with app.language.set {"language": "pt"} (app.language.portuguese is dropped); error text, engine.commands params and the snapshot example list every code. - pt.rs covers the keys added since (Page Layout|Orientation, the display theme combo, and the Sheet Options View/Print checkboxes, Exibir / Imprimir); the coverage test checks pt like zh/ko/ru. - people.toml keeps both new contributor entries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
124 lines
4.3 KiB
Rust
124 lines
4.3 KiB
Rust
//! Renders the whole GridCraft window offscreen (wgpu, no window) to a PNG.
|
|
//!
|
|
//! `cargo run --release -p gridcraft-ui-egui --example snapshot -- [--sample sales] [--in file.xlsx]
|
|
//! [--size 1440x900] [--scale 2] [--cmd 'id={json}']... [--tab Insert] [--dark] [--language en|zh|ja|ko|ru|pt]
|
|
//! [--dialog 'name={json}'] out.png`
|
|
|
|
use gridcraft_engine::Session;
|
|
use gridcraft_ui_egui::SheetApp;
|
|
use serde_json::json;
|
|
|
|
fn main() {
|
|
let args: Vec<String> = std::env::args().skip(1).collect();
|
|
let mut sample = None;
|
|
let mut input = None;
|
|
let mut size = (1440.0f32, 900.0f32);
|
|
let mut scale = 2.0f32;
|
|
let mut cmds: Vec<String> = vec![];
|
|
let mut tab = None;
|
|
let mut dark = false;
|
|
let mut pane: Option<String> = None;
|
|
let mut chart: Option<u32> = None;
|
|
let mut dialog: Option<String> = None;
|
|
let mut language: Option<String> = None;
|
|
let mut out = "snapshot.png".to_string();
|
|
let mut i = 0;
|
|
while i < args.len() {
|
|
match args[i].as_str() {
|
|
"--sample" => {
|
|
i += 1;
|
|
sample = args.get(i).cloned();
|
|
}
|
|
"--in" => {
|
|
i += 1;
|
|
input = args.get(i).cloned();
|
|
}
|
|
"--size" => {
|
|
i += 1;
|
|
if let Some((w, h)) = args.get(i).and_then(|s| s.split_once('x')) {
|
|
size = (w.parse().unwrap_or(1440.0), h.parse().unwrap_or(900.0));
|
|
}
|
|
}
|
|
"--scale" => {
|
|
i += 1;
|
|
scale = args.get(i).and_then(|s| s.parse().ok()).unwrap_or(2.0);
|
|
}
|
|
"--cmd" => {
|
|
i += 1;
|
|
if let Some(c) = args.get(i) {
|
|
cmds.push(c.clone());
|
|
}
|
|
}
|
|
"--tab" => {
|
|
i += 1;
|
|
tab = args.get(i).cloned();
|
|
}
|
|
"--dark" => dark = true,
|
|
"--pane" => {
|
|
i += 1;
|
|
pane = args.get(i).cloned();
|
|
}
|
|
"--chart" => {
|
|
i += 1;
|
|
chart = args.get(i).and_then(|s| s.parse().ok());
|
|
}
|
|
"--dialog" => {
|
|
i += 1;
|
|
dialog = args.get(i).cloned();
|
|
}
|
|
"--language" => {
|
|
i += 1;
|
|
language = args.get(i).cloned();
|
|
}
|
|
other => out = other.to_string(),
|
|
}
|
|
i += 1;
|
|
}
|
|
let mut session = Session::new();
|
|
if let Some(p) = &input {
|
|
session.execute("file.open", json!({"path": p})).expect("open");
|
|
} else if let Some(s) = &sample {
|
|
session.execute("file.new", json!({"sample": s})).expect("sample");
|
|
} else {
|
|
session.new_workbook();
|
|
}
|
|
for c in &cmds {
|
|
let (id, p) = c.split_once('=').map(|(a, b)| (a.to_string(), serde_json::from_str(b).unwrap_or(json!({})))).unwrap_or((c.clone(), json!({})));
|
|
if let Err(e) = session.execute(&id, p) {
|
|
eprintln!("{id}: {e}");
|
|
}
|
|
}
|
|
let mut harness =
|
|
egui_kittest::Harness::builder().with_size(egui::vec2(size.0, size.1)).with_pixels_per_point(scale).with_max_steps(12).wgpu().build_ui_state(
|
|
move |ui, app: &mut SheetApp| {
|
|
let ctx = ui.ctx().clone();
|
|
app.logic(&ctx);
|
|
app.ui(ui);
|
|
},
|
|
{
|
|
let mut app = SheetApp::new(session, Default::default());
|
|
app.ui.dark = dark;
|
|
if let Some(code) = &language
|
|
&& let Some(l) = gridcraft_ui_egui::i18n::Language::parse(code)
|
|
{
|
|
app.ui.language = l;
|
|
}
|
|
if let Some(t) = tab {
|
|
app.ui.ribbon_tab = t;
|
|
}
|
|
app.grid.pane = pane;
|
|
app.selected_chart = chart;
|
|
if let Some(d) = &dialog {
|
|
let (name, p) =
|
|
d.split_once('=').map(|(a, b)| (a, serde_json::from_str(b).unwrap_or(json!({})))).unwrap_or((d.as_str(), json!({})));
|
|
app.open_dialog(name, p);
|
|
}
|
|
app
|
|
},
|
|
);
|
|
harness.run_steps(8);
|
|
let img = harness.render().expect("render");
|
|
img.save(&out).expect("save png");
|
|
eprintln!("wrote {out} ({}x{})", img.width(), img.height());
|
|
}
|