Start refactoring code

This commit is contained in:
Julian Mutter 2023-10-09 20:13:30 +02:00
parent 3cc632f8e1
commit 8f7df7cdaa

View File

@ -1,3 +1,5 @@
// mod window;
use cairo::Context; use cairo::Context;
use clap::Parser; use clap::Parser;
use gio::ApplicationFlags; use gio::ApplicationFlags;
@ -23,7 +25,7 @@ fn main() {
println!("Parse args"); println!("Parse args");
let app = Application::builder() let app = Application::builder()
.application_id(APP_ID) .application_id(APP_ID)
.flags(gio::ApplicationFlags::FLAGS_NONE) // .flags(gio::ApplicationFlags::FLAGS_NONE)
.build(); .build();
app.connect_activate(move |app| { app.connect_activate(move |app| {
@ -33,6 +35,21 @@ fn main() {
app.run_with_args(&[] as &[&str]); app.run_with_args(&[] as &[&str]);
} }
struct Ui {
bottom_bar: gtk4::Box,
header_bar: gtk4::HeaderBar,
}
fn toggle_fullscreen(ui: &Ui) {
if ui.header_bar.is_visible() {
ui.header_bar.hide();
ui.bottom_bar.hide();
} else {
ui.header_bar.show();
ui.bottom_bar.show();
}
}
fn build_ui(app: &Application, cli: &Cli) { fn build_ui(app: &Application, cli: &Cli) {
println!("building ui"); println!("building ui");
let open_file_button = gtk4::Button::from_icon_name("document-open"); let open_file_button = gtk4::Button::from_icon_name("document-open");
@ -41,34 +58,38 @@ fn build_ui(app: &Application, cli: &Cli) {
.orientation(gtk4::Orientation::Vertical) .orientation(gtk4::Orientation::Vertical)
.build(); .build();
let bottom_bar = gtk4::Box::builder().hexpand_set(true).build(); let ui = Ui {
let header_bar = gtk4::HeaderBar::builder().build(); bottom_bar: gtk4::Box::builder().hexpand_set(true).build(),
header_bar: gtk4::HeaderBar::builder().build(),
};
let ui = Rc::new(RefCell::new(ui));
header_bar.pack_start(&open_file_button); ui.borrow().header_bar.pack_start(&open_file_button);
app_wrapper.append(&bottom_bar); app_wrapper.append(&ui.borrow().bottom_bar);
let window = ApplicationWindow::builder() let window = ApplicationWindow::builder()
.application(app) .application(app)
.title("Music Reader") .title("Music Reader")
.child(&app_wrapper) .child(&app_wrapper)
.maximized(true)
.build(); .build();
window.set_titlebar(Some(&header_bar)); window.set_titlebar(Some(&ui.borrow().header_bar));
let toggle_fullscreen = clone!(@weak header_bar, @weak bottom_bar => move || { // let toggle_fullscreen = clone!(@weak header_bar, @weak bottom_bar => move || {
if header_bar.is_visible() { // if header_bar.is_visible() {
header_bar.hide(); // header_bar.hide();
bottom_bar.hide(); // bottom_bar.hide();
} else { // } else {
header_bar.show(); // header_bar.show();
bottom_bar.show(); // bottom_bar.show();
} // }
}); // });
let load_doc = move |file: &PathBuf| { let load_doc = move |file: &PathBuf| {
println!("Loading file..."); println!("Loading file...");
let drawing_area = DrawingArea::builder() let drawing_area = DrawingArea::builder()
.width_request(100) // .width_request(100)
.height_request(100) // .height_request(100)
.hexpand(true) .hexpand(true)
.vexpand(true) .vexpand(true)
.build(); .build();
@ -81,30 +102,25 @@ fn build_ui(app: &Application, cli: &Cli) {
app_wrapper.prepend(&drawing_area); app_wrapper.prepend(&drawing_area);
let page_indicator = Label::builder().label("Counting").build(); let page_indicator = Label::builder().label("Counting").build();
let old_indicator = bottom_bar.last_child(); let old_indicator = ui.borrow().bottom_bar.last_child();
if old_indicator.is_some() { if old_indicator.is_some() {
bottom_bar.remove(&old_indicator.unwrap()); ui.borrow().bottom_bar.remove(&old_indicator.unwrap());
} }
bottom_bar.append(&page_indicator); ui.borrow().bottom_bar.append(&page_indicator);
let doc = PopplerDocument::new_from_file(file, "").unwrap(); let doc = PopplerDocument::new_from_file(file, "").unwrap();
let num_pages = doc.get_n_pages(); let num_pages = doc.get_n_pages();
let num_pages_ref = Rc::new(RefCell::new(num_pages)); let current_page_number = Rc::new(RefCell::new(1));
let current_page = Rc::new(RefCell::new(1));
let current_page_copy_another = current_page.clone();
let current_page_view = current_page.clone();
let surface = cairo::ImageSurface::create(cairo::Format::Rgb24, 0, 0).unwrap(); let surface = cairo::ImageSurface::create(cairo::Format::Rgb24, 0, 0).unwrap();
let ctx = Context::new(&surface).unwrap(); let ctx = Context::new(&surface).unwrap();
let update_page_status = clone!(@strong num_pages_ref, @weak page_indicator, @strong drawing_area => move || { let update_page_status = glib::clone!(@strong num_pages, @strong current_page_number, @strong page_indicator, @weak drawing_area => @default-panic, move || {
let page_status: String = format!("{} of {}", *current_page_copy_another.borrow_mut(), num_pages); let page_status: String = format!("{} of {}", current_page_number.borrow(), num_pages);
let page_status_s: &str = &page_status[..]; let page_status_s: &str = &page_status[..];
page_indicator.set_label(page_status_s); page_indicator.set_label(page_status_s);
drawing_area.queue_draw(); drawing_area.queue_draw();
}); });
update_page_status(); update_page_status();
@ -112,14 +128,14 @@ fn build_ui(app: &Application, cli: &Cli) {
let click = gtk4::GestureClick::new(); let click = gtk4::GestureClick::new();
click.set_button(0); click.set_button(0);
click.connect_pressed( click.connect_pressed(
glib::clone!(@weak drawing_area, @strong toggle_fullscreen, @strong num_pages, @strong update_page_status => move |_count, _, x, y| { glib::clone!(@weak ui, @weak drawing_area, @strong current_page_number, @strong num_pages, @strong update_page_status => @default-panic, move |_count, _, x, y| {
let center = drawing_area.width() / 2; let center = drawing_area.width() / 2;
if y < (drawing_area.height() / 5) as f64 { if y < (drawing_area.height() / 5) as f64 {
toggle_fullscreen(); toggle_fullscreen(&ui.borrow());
} else if x > center as f64 && *current_page.borrow_mut() < num_pages { } else if x > center as f64 && *current_page_number.borrow() < num_pages{
*current_page.borrow_mut() += 1; *current_page_number.borrow_mut() += 1;
} else if x < center as f64 && *current_page.borrow_mut() > 1 { } else if x < center as f64 && *current_page_number.borrow() > 1 {
*current_page.borrow_mut() -= 1; *current_page_number.borrow_mut() -= 1;
} }
update_page_status(); update_page_status();
@ -128,43 +144,45 @@ fn build_ui(app: &Application, cli: &Cli) {
drawing_area.add_controller(&click); drawing_area.add_controller(&click);
drawing_area.set_draw_func(move |area, context, _a, _b| { drawing_area.set_draw_func(
let current_page_number = &current_page_view.borrow_mut(); glib::clone!(@strong current_page_number => @default-panic, move |area, context, _a, _b| {
context.set_source_rgba(1.0, 1.0, 1.0, 1.0); println!("Draw!");
context.paint().unwrap(); context.set_source_rgba(1.0, 1.0, 1.0, 1.0);
context.fill().expect("uh oh"); context.paint().unwrap();
context.paint().unwrap(); context.fill().expect("uh oh");
context.paint().unwrap();
let page = doc.get_page(**current_page_number - 1).unwrap(); let page = doc.get_page(*current_page_number.borrow_mut()- 1).unwrap();
let (w, h) = page.get_size(); let (w, h) = page.get_size();
let width_diff = area.width() as f64 / w; let width_diff = area.width() as f64 / w;
let height_diff = area.height() as f64 / h; let height_diff = area.height() as f64 / h;
context.save().unwrap(); context.save().unwrap();
if width_diff > height_diff { if width_diff > height_diff {
context.translate( context.translate(
(area.width() as f64 - w * height_diff) / 2.0, (area.width() as f64 - w * height_diff) / 2.0,
(area.height() as f64 - h * height_diff) / 2.0, (area.height() as f64 - h * height_diff) / 2.0,
); );
context.scale(height_diff, height_diff); context.scale(height_diff, height_diff);
} else { } else {
context.translate( context.translate(
(area.width() as f64 - w * width_diff) / 2.0, (area.width() as f64 - w * width_diff) / 2.0,
(area.height() as f64 - h * width_diff) / 2.0, (area.height() as f64 - h * width_diff) / 2.0,
); );
context.scale(width_diff, width_diff); context.scale(width_diff, width_diff);
} }
page.render(&context); page.render(&context);
let r = ctx.paint(); let r = ctx.paint();
match r { match r {
Err(v) => println!("Error painting PDF: {v:?}"), Err(v) => println!("Error painting PDF: {v:?}"),
Ok(_v) => {} Ok(_v) => {}
} }
ctx.show_page().unwrap(); ctx.show_page().unwrap();
}); }),
);
}; };
match cli.file.as_ref() { match cli.file.as_ref() {
@ -172,23 +190,25 @@ fn build_ui(app: &Application, cli: &Cli) {
None => {} None => {}
} }
open_file_button.connect_clicked(clone!(@weak window, @strong load_doc => move |_button| { open_file_button.connect_clicked(
let filechooser = gtk4::FileChooserDialog::builder() glib::clone!(@weak window, @strong load_doc => @default-panic, move |_button| {
.title("Choose a PDF...") let filechooser = gtk4::FileChooserDialog::builder()
.action(gtk4::FileChooserAction::Open) .title("Choose a PDF...")
.modal(true) .action(gtk4::FileChooserAction::Open)
.build(); .modal(true)
filechooser.add_button("_Cancel", gtk4::ResponseType::Cancel); .build();
filechooser.add_button("_Open", gtk4::ResponseType::Accept); filechooser.add_button("_Cancel", gtk4::ResponseType::Cancel);
filechooser.set_transient_for(Some(&window)); filechooser.add_button("_Open", gtk4::ResponseType::Accept);
filechooser.connect_response(clone!(@strong load_doc => move |d, response| { filechooser.set_transient_for(Some(&window));
if response == gtk4::ResponseType::Accept { filechooser.connect_response(glib::clone!(@strong load_doc => @default-panic, move |d, response| {
let path = d.file().unwrap().path().unwrap(); if response == gtk4::ResponseType::Accept {
load_doc(&path); let path = d.file().unwrap().path().unwrap();
} load_doc(&path);
d.destroy(); }
})); d.destroy();
filechooser.show() }));
})); filechooser.show()
}),
);
window.present(); window.present();
} }