feat: better encapsulation

This commit is contained in:
2025-06-20 23:50:01 -06:00
parent 9872bf5245
commit b15ae562a4

View File

@@ -1,111 +1,109 @@
mod font; mod font;
use crate::font::Font; // this brings in the struct Font use crate::font::Font;
use gtk4::{cairo::Context, DrawingArea, Label, ListBox, ListBoxRow, MenuButton, Popover};
use adw::{prelude::*, Application, ApplicationWindow, HeaderBar}; use adw::{prelude::*, Application, ApplicationWindow, HeaderBar};
use gtk4::{
cairo::Context, Box as GtkBox, DrawingArea, Label, ListBox, ListBoxRow, MenuButton,
Orientation, Popover,
};
fn main() { fn main() {
let app = Application::builder() let app = Application::builder()
.application_id("com.example.DotMatrix") .application_id("com.example.DotMatrix")
.build(); .build();
app.connect_activate(build_ui); app.connect_activate(|app| {
let ui = AppWindow::new(app);
ui.window.show();
});
app.run(); app.run();
} }
fn build_ui(app: &adw::Application) { struct AppWindow {
let window = ApplicationWindow::builder() window: ApplicationWindow,
.application(app) _drawing_area: DrawingArea, // keep reference if you later need to update/redraw it
.title("Dot Matrix") }
.default_width(1000)
.default_height(800)
.build();
// HeaderBar impl AppWindow {
let header_bar = HeaderBar::new(); fn new(app: &Application) -> Self {
let window = ApplicationWindow::builder()
.application(app)
.title("Dot Matrix")
.default_width(1000)
.default_height(800)
.build();
// MenuButton let header_bar = HeaderBar::new();
let menu_button = MenuButton::new(); let menu_button = MenuButton::new();
menu_button.set_icon_name("open-menu-symbolic"); menu_button.set_icon_name("open-menu-symbolic");
header_bar.pack_start(&menu_button); header_bar.pack_start(&menu_button);
// Popover let popover = Popover::new();
let popover = Popover::new(); popover.set_parent(&menu_button);
popover.set_parent(&menu_button); menu_button.set_popover(Some(&popover));
menu_button.set_popover(Some(&popover));
// ListBox in popover let list_box = ListBox::new();
let list_box = ListBox::new(); list_box.set_selection_mode(gtk4::SelectionMode::None);
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 let drawing_area = DrawingArea::new();
for label in ["Settings", "Help", "About"] { drawing_area.set_vexpand(true);
let row = ListBoxRow::new(); drawing_area.set_hexpand(true);
let lbl = Label::new(Some(label));
row.set_child(Some(&lbl)); // Matrix data generation
list_box.append(&row); let rows = 36u8;
let cols = 72u8;
let mut dot_matrix: Vec<Vec<u8>> =
(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<u8> = 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<Vec<u8>> = (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<u8> = 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<Vec<u8>>) { fn draw_dot_matrix(cr: &Context, width: i32, height: i32, matrix: &Vec<Vec<u8>>) {
// 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.set_source_rgb(0.1, 0.1, 0.1);
cr.rectangle(0.0, 0.0, width as f64, height as f64); cr.rectangle(0.0, 0.0, width as f64, height as f64);
let _ = cr.fill(); let _ = cr.fill();
// Set dot color (yellow)
cr.set_source_rgb(1.0, 1.0, 0.0); cr.set_source_rgb(1.0, 1.0, 0.0);
// Calculate spacing
let pos_x = 25.0; let pos_x = 25.0;
let pos_y = 25.0; let pos_y = 25.0;
let mut offset_row = 0.0; let mut offset_row = 0.0;
let mut current_line_width = 0.0;
for (row_index, row) in matrix.iter().enumerate() { for (row_index, row) in matrix.iter().enumerate() {
if row_index != 0 && row_index % 8 == 0 { if row_index != 0 && row_index % 8 == 0 {
offset_row += 25.0 offset_row += 25.0;
} }
for (col_index, &val) in row.iter().enumerate() { for (col_index, &val) in row.iter().enumerate() {
@@ -113,7 +111,6 @@ fn draw_dot_matrix(cr: &Context, width: i32, height: i32, matrix: &Vec<Vec<u8>>)
let x = (col_index as f64) * pos_x + pos_x; let x = (col_index as f64) * pos_x + pos_x;
let y = (row_index as f64) * pos_y + offset_row; let y = (row_index as f64) * pos_y + offset_row;
cr.rectangle(x, y, 20.0, 20.0); cr.rectangle(x, y, 20.0, 20.0);
let _ = cr.fill(); let _ = cr.fill();
} }
} }