From b15ae562a405fc0295589df07dea3a61cfda43aa Mon Sep 17 00:00:00 2001 From: Nathan Carlson Date: Fri, 20 Jun 2025 23:50:01 -0600 Subject: [PATCH] feat: better encapsulation --- dot-matrix/src/main.rs | 147 ++++++++++++++++++++--------------------- 1 file changed, 72 insertions(+), 75 deletions(-) diff --git a/dot-matrix/src/main.rs b/dot-matrix/src/main.rs index 28db48a..fc80fdf 100644 --- a/dot-matrix/src/main.rs +++ b/dot-matrix/src/main.rs @@ -1,111 +1,109 @@ mod font; -use crate::font::Font; // this brings in the struct Font -use gtk4::{cairo::Context, DrawingArea, Label, ListBox, ListBoxRow, MenuButton, Popover}; - +use crate::font::Font; use adw::{prelude::*, Application, ApplicationWindow, HeaderBar}; +use gtk4::{ + cairo::Context, Box as GtkBox, DrawingArea, Label, ListBox, ListBoxRow, MenuButton, + Orientation, Popover, +}; fn main() { let app = Application::builder() .application_id("com.example.DotMatrix") .build(); - app.connect_activate(build_ui); + app.connect_activate(|app| { + let ui = AppWindow::new(app); + ui.window.show(); + }); app.run(); } -fn build_ui(app: &adw::Application) { - let window = ApplicationWindow::builder() - .application(app) - .title("Dot Matrix") - .default_width(1000) - .default_height(800) - .build(); +struct AppWindow { + window: ApplicationWindow, + _drawing_area: DrawingArea, // keep reference if you later need to update/redraw it +} - // HeaderBar - let header_bar = HeaderBar::new(); +impl AppWindow { + fn new(app: &Application) -> Self { + let window = ApplicationWindow::builder() + .application(app) + .title("Dot Matrix") + .default_width(1000) + .default_height(800) + .build(); - // MenuButton - let menu_button = MenuButton::new(); - menu_button.set_icon_name("open-menu-symbolic"); - header_bar.pack_start(&menu_button); + let header_bar = HeaderBar::new(); + let menu_button = MenuButton::new(); + menu_button.set_icon_name("open-menu-symbolic"); + header_bar.pack_start(&menu_button); - // Popover - let popover = Popover::new(); - popover.set_parent(&menu_button); - menu_button.set_popover(Some(&popover)); + let popover = Popover::new(); + popover.set_parent(&menu_button); + menu_button.set_popover(Some(&popover)); - // ListBox in popover - let list_box = ListBox::new(); - list_box.set_selection_mode(gtk4::SelectionMode::None); + let list_box = ListBox::new(); + list_box.set_selection_mode(gtk4::SelectionMode::None); + for label in ["Settings", "Help", "About"] { + let row = ListBoxRow::new(); + let lbl = Label::new(Some(label)); + row.set_child(Some(&lbl)); + list_box.append(&row); + } + popover.set_child(Some(&list_box)); - // Add menu items - for label in ["Settings", "Help", "About"] { - let row = ListBoxRow::new(); - let lbl = Label::new(Some(label)); - row.set_child(Some(&lbl)); - list_box.append(&row); + let drawing_area = DrawingArea::new(); + drawing_area.set_vexpand(true); + drawing_area.set_hexpand(true); + + // Matrix data generation + let rows = 36u8; + let cols = 72u8; + let mut dot_matrix: Vec> = + (0..rows).map(|_| (0..cols).map(|_| 0).collect()).collect(); + + let font_5x7: Font = Font::new("5x7"); + let thing = String::from("abcdefghijklmnop"); + let ascii_values: Vec = thing.chars().map(|c| c as u8).collect(); + + let mut col_offset = 0; + for ch in ascii_values { + let char_matrix = &font_5x7.get_char_bitmap(ch as u64).unwrap(); + insert_matrix_at(&mut dot_matrix, char_matrix, 0, col_offset); + col_offset += char_matrix.first().unwrap().len() + 1; + } + + drawing_area.set_draw_func(move |_area, cr, width, height| { + draw_dot_matrix(cr, width, height, &dot_matrix); + }); + + let layout = GtkBox::new(Orientation::Vertical, 0); + layout.append(&header_bar); + layout.append(&drawing_area); + window.set_content(Some(&layout)); + + AppWindow { + window, + _drawing_area: drawing_area, + } } - - popover.set_child(Some(&list_box)); - - // Drawing area setup - let drawing_area = DrawingArea::new(); - drawing_area.set_vexpand(true); - drawing_area.set_hexpand(true); - - let rows = 36u8; - let cols = 72u8; - - let mut dot_matrix: Vec> = (0..rows).map(|_| (0..cols).map(|_| 0).collect()).collect(); - let font_5x7: Font = Font::new("5x7"); - - let thing = String::from("abcdefghijklmnop"); - let ascii_values: Vec = thing.chars().map(|c| c as u8).collect(); - - let mut col_offset = 0; - for ch in ascii_values { - let char_matrix = &font_5x7.get_char_bitmap(ch as u64).unwrap(); - insert_matrix_at(&mut dot_matrix, char_matrix, 0, col_offset); - col_offset += char_matrix.first().unwrap().len() + 1; - } - - drawing_area.set_draw_func(move |_area, cr, width, height| { - draw_dot_matrix(cr, width, height, &dot_matrix); - }); - - // 🔁 NEW: ToolbarView container - let layout = gtk4::Box::new(gtk4::Orientation::Vertical, 0); - layout.append(&header_bar); - layout.append(&drawing_area); - window.set_content(Some(&layout)); - - window.show(); } fn draw_dot_matrix(cr: &Context, width: i32, height: i32, matrix: &Vec>) { - // let rows = matrix.len(); - // let _cols = if rows > 0 { matrix[0].len() } else { 0 }; - - // Background: dark gray cr.set_source_rgb(0.1, 0.1, 0.1); cr.rectangle(0.0, 0.0, width as f64, height as f64); let _ = cr.fill(); - // Set dot color (yellow) cr.set_source_rgb(1.0, 1.0, 0.0); - // Calculate spacing let pos_x = 25.0; let pos_y = 25.0; - let mut offset_row = 0.0; - let mut current_line_width = 0.0; for (row_index, row) in matrix.iter().enumerate() { if row_index != 0 && row_index % 8 == 0 { - offset_row += 25.0 + offset_row += 25.0; } for (col_index, &val) in row.iter().enumerate() { @@ -113,7 +111,6 @@ fn draw_dot_matrix(cr: &Context, width: i32, height: i32, matrix: &Vec>) let x = (col_index as f64) * pos_x + pos_x; let y = (row_index as f64) * pos_y + offset_row; cr.rectangle(x, y, 20.0, 20.0); - let _ = cr.fill(); } }