aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
blob: 0a023a85ca41e22fa55bf87411630fd4aa0f06c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use eframe::egui;
use std::sync::Arc;
use tokio::sync::Mutex;

mod api;
mod config;
mod core;
mod models;
mod session;
mod ui;

use session::SessionManager;
use ui::app::BeepZoneApp;

fn main() -> eframe::Result<()> {
    // Initialize logging
    env_logger::Builder::from_default_env()
        .filter_level(log::LevelFilter::Info)
        .init();

    log::info!("Starting BeepZone Inventory Management System");

    // Configure egui options
    let options = eframe::NativeOptions {
        viewport: egui::ViewportBuilder::default()
            .with_inner_size([1280.0, 800.0])
            .with_min_inner_size([800.0, 600.0])
            .with_icon(load_icon()),
        persist_window: true,
        ..Default::default()
    };

    // Initialize session manager
    let session_manager = Arc::new(Mutex::new(SessionManager::new()));

    // Run the application
    eframe::run_native(
        "BeepZone Inventory System",
        options,
        Box::new(move |cc| {
            // Configure fonts and style
            configure_fonts(&cc.egui_ctx);
            configure_style(&cc.egui_ctx);

            Ok(Box::new(BeepZoneApp::new(cc, session_manager)))
        }),
    )
}

fn load_icon() -> egui::IconData {
    // Load the app icon from assets
    let icon_bytes = include_bytes!("assets/app-icon/AppIcon.png");

    // Parse PNG file
    match image::load_from_memory(icon_bytes) {
        Ok(img) => {
            let rgba = img.to_rgba8();
            let (width, height) = rgba.dimensions();

            egui::IconData {
                rgba: rgba.into_raw(),
                width: width as u32,
                height: height as u32,
            }
        }
        Err(e) => {
            log::warn!("Failed to load app icon: {}. Using fallback.", e);
            // Fallback to a simple default icon
            egui::IconData {
                rgba: vec![255; 32 * 32 * 4],
                width: 32,
                height: 32,
            }
        }
    }
}

// Include generated font byte bindings from build.rs (downloaded into OUT_DIR)
// (Removed build.rs embedded fonts; using egui-phosphor instead)

fn configure_fonts(ctx: &egui::Context) {
    let mut fonts = egui::FontDefinitions::default();

    // Use Phosphor icon font via crate as a portable fallback
    egui_phosphor::add_to_fonts(&mut fonts, egui_phosphor::variants::Variant::Regular);

    ctx.set_fonts(fonts);
}

fn configure_style(ctx: &egui::Context) {
    // Configure style for consistent appearance across light/dark themes
    ctx.all_styles_mut(|style| {
        // Configure spacing - these settings apply to both themes
        style.spacing.item_spacing = egui::vec2(8.0, 8.0);
        style.spacing.button_padding = egui::vec2(12.0, 6.0);
        style.spacing.window_margin = egui::Margin::from(12.0);

        // Configure interaction
        style.interaction.tooltip_delay = 0.5;

        // Configure visuals for a modern look - applied to both themes
        style.visuals.window_corner_radius = egui::CornerRadius::from(8.0);
        style.visuals.button_frame = true;
        style.visuals.collapsing_header_frame = true;
    });
}