#![windows_subsystem = "windows"] use bitsy_parser::game::Game; use gio::prelude::*; use gtk::prelude::*; use gtk::Orientation; use std::env::args; const SPACING: i32 = 16; fn error_popup(message: &str) { let popup = gtk::Window::new(gtk::WindowType::Toplevel); popup.set_title("error"); popup.set_border_width(SPACING as u32); popup.set_position(gtk::WindowPosition::Center); popup.set_default_size(256, 64); let vertical = gtk::Box::new(Orientation::Vertical, SPACING); popup.add(&vertical); let message = gtk::Label::new(Some(message)); vertical.add(&message); let button_ok = gtk::Button::with_label("OK"); vertical.add(&button_ok); popup.show_all(); button_ok.connect_clicked(move |_| unsafe { popup.destroy(); }); } fn add_text_box(container: >k::Box, label: &str) -> gtk::TextBuffer { let vertical = gtk::Box::new(Orientation::Vertical, SPACING); vertical.set_property_expand(true); let label = gtk::Label::new(Some(label)); vertical.add(&label); let h: Option<>k::Adjustment> = None; let v: Option<>k::Adjustment> = None; let scrolled_window = gtk::ScrolledWindow::new(h, v); scrolled_window.set_property_expand(true); let text_view = gtk::TextView::new(); text_view.set_property_monospace(true); scrolled_window.add(&text_view); vertical.add(&scrolled_window); container.add(&vertical); text_view.get_buffer().unwrap() } fn parse_or_error(game_data: String, label: &str) -> Result { let main = Game::from(game_data); if main.is_ok() { Ok(main.unwrap()) } else { error_popup(&format!( "Couldn't parse {} game data: {:?}", label, main.unwrap_err())); Err(()) } } fn buffer_to_string(buffer: >k::TextBuffer) -> String { let (start, end) = &buffer.get_bounds(); buffer.get_text(start, end, false).unwrap().to_string() } fn build_ui(application: >k::Application) { let window = gtk::ApplicationWindow::new(application); window.set_title("mixsy"); window.set_border_width(SPACING as u32); window.set_position(gtk::WindowPosition::Center); window.set_default_size(396, 512); let vertical = gtk::Box::new(Orientation::Vertical, SPACING); let buffer_main = add_text_box(&vertical, "main game data"); let buffer_additional = add_text_box(&vertical, "additional game data"); let button = gtk::Button::with_label("mix!"); vertical.add(&button); let separator = gtk::Separator::new(Orientation::Vertical); vertical.add(&separator); let buffer_output = add_text_box(&vertical, "output"); button.connect_clicked(move |_| { let main = buffer_to_string(&buffer_main); let additional = buffer_to_string(&buffer_additional); let main = parse_or_error(main, "main"); let additional = parse_or_error(additional, "additional"); if main.is_ok() && additional.is_ok() { let mut main = main.unwrap(); let additional = additional.unwrap(); main.merge(additional); buffer_output.set_text(&main.to_string()); } }); window.add(&vertical); window.show_all(); } fn main() { let application = gtk::Application::new( Some("dev.tinybird.max.mixsy"), Default::default() ).expect("Initialization failed..."); application.connect_activate(|app| { build_ui(app); }); application.run(&args().collect::>()); }