budget-app/src/main.rs
2026-10-25 13:38:59 +03:00

91 lines
3 KiB
Rust

//! budget — the Old Mutual "the budget & you" monthly budget planner as a
//! plain full-window Makepad app, ported from the sheets app and the
//! user's `Old_Mutual_Finance_Budget_Tool.xls`.
//!
//! The grid is the stock `DataGrid` widget; the formula engine, dependency
//! graph, formats, undo and CSV above it come from this crate, and the
//! workbook starts out carrying the planner from the Excel tool — sections,
//! items, and the subtotals/totals as live formulas.
pub use makepad_widgets;
use budget::{app, forms, nav_button, theme, view};
use makepad_widgets::*;
app_main!(
App,
font_assets: ["budget/resources/jetbrains_mono_variable.ttf"]
);
script_mod! {
use mod.prelude.widgets.*
use mod.widgets.*
startup() do #(App::script_component(vm)){
ui: Root{
main_window := Window{
window.inner_size: vec2(420, 800)
window.title: "Old Mutual Budget"
// The stock window clears to `theme.color_bg_app` as captured
// when the widgets module was evaluated — before this app
// retinted it — so state the sheet's own ground explicitly.
pass +: { clear_color: mod.sheets.bg }
body +: {
padding: 0.
margin: 0.
spacing: 0.
budget := BudgetApp{}
}
}
}
}
}
#[derive(Script, ScriptHook)]
pub struct App {
#[live]
ui: WidgetRef,
}
impl MatchEvent for App {
fn handle_startup(&mut self, cx: &mut Cx) {
if let Some(mut budget) = self
.ui
.widget(cx, ids!(budget))
.borrow_mut::<app::BudgetApp>()
{
budget.arm_storage(cx);
}
}
fn handle_actions(&mut self, _cx: &mut Cx, _actions: &Actions) {}
}
impl AppMain for App {
fn script_mod(vm: &mut ScriptVm) -> ScriptValue {
log!("boot: modules");
makepad_widgets::script_mod(vm);
for e in vm.take_errors() { log!("boot err after widgets: {}", e); }
log!("boot: widgets ok");
// Retint the stock widgets, then publish the palette as `mod.sheets`
// for this app's own splash.
makepad_wm_theme::apply(vm);
theme::install(vm);
nav_button::script_mod(vm);
for e in vm.take_errors() { log!("boot err after nav_button: {}", e); }
log!("boot: nav_button ok");
view::script_mod(vm);
for e in vm.take_errors() { log!("boot err after view: {}", e); }
log!("boot: view ok");
forms::script_mod(vm);
for e in vm.take_errors() { log!("boot err after forms: {}", e); }
log!("boot: forms ok");
app::script_mod(vm);
for e in vm.take_errors() { log!("boot err after app: {}", e); }
log!("boot: app ok");
self::script_mod(vm)
}
fn handle_event(&mut self, cx: &mut Cx, event: &Event) {
self.match_event(cx, event);
self.ui.handle_event(cx, event, &mut Scope::empty());
}
}