130 lines
3.8 KiB
Rust
130 lines
3.8 KiB
Rust
mod font;
|
|
|
|
use crate::font::Font; // this brings in the struct Font
|
|
use gtk::cairo::Context;
|
|
use gtk::prelude::*;
|
|
use gtk::{
|
|
Application, ApplicationWindow, DrawingArea, HeaderBar, Label, ListBox, ListBoxRow, MenuButton,
|
|
Popover,
|
|
};
|
|
|
|
fn main() {
|
|
let app = Application::builder()
|
|
.application_id("com.example.DotMatrix")
|
|
.build();
|
|
|
|
app.connect_activate(build_ui);
|
|
app.run();
|
|
}
|
|
|
|
fn build_ui(app: >k::Application) {
|
|
let window = ApplicationWindow::builder()
|
|
.application(app)
|
|
.title("Dot Matrix")
|
|
.default_width(1000)
|
|
.default_height(800)
|
|
.build();
|
|
|
|
// HeaderBar
|
|
let header_bar = HeaderBar::new();
|
|
window.set_titlebar(Some(&header_bar));
|
|
|
|
// MenuButton
|
|
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));
|
|
|
|
// ListBox in popover
|
|
let list_box = ListBox::new();
|
|
list_box.set_selection_mode(gtk::SelectionMode::None); // No selection on menu items
|
|
|
|
// Add menu items (ListBoxRows with Labels)
|
|
let item1_row = ListBoxRow::new();
|
|
let item1_label = Label::new(Some("Settings"));
|
|
item1_row.set_child(Some(&item1_label));
|
|
list_box.append(&item1_row);
|
|
|
|
let item2_row = ListBoxRow::new();
|
|
let item2_label = Label::new(Some("Help"));
|
|
item2_row.set_child(Some(&item2_label));
|
|
list_box.append(&item2_row);
|
|
|
|
let item3_row = ListBoxRow::new();
|
|
let item3_label = Label::new(Some("About"));
|
|
item3_row.set_child(Some(&item3_label));
|
|
list_box.append(&item3_row);
|
|
|
|
popover.set_child(Some(&list_box)); // Set the ListBox as the child of the Popover
|
|
|
|
let drawing_area = DrawingArea::new();
|
|
|
|
let rows = 100 as u8;
|
|
let cols = 100 as u8;
|
|
|
|
// Generate the matrix using iterators
|
|
let mut dot_matrix: Vec<Vec<u8>> = (0..rows).map(|_| (0..cols).map(|_| 0).collect()).collect();
|
|
let insert_matrix: Vec<Vec<u8>> = (0..7).map(|_| (0..5).map(|_| 1).collect()).collect();
|
|
let font_5x7: Font = Font::new("5x7");
|
|
let char_bitmap = font_5x7.get_char_bitmap(1).unwrap();
|
|
|
|
insert_matrix_at(&mut dot_matrix, &insert_matrix, 0, 0);
|
|
insert_matrix_at(&mut dot_matrix, &insert_matrix, 0, 6);
|
|
insert_matrix_at(&mut dot_matrix, &char_bitmap, 0, 12);
|
|
|
|
drawing_area.set_draw_func(move |_area, cr, width, height| {
|
|
draw_dot_matrix(cr, width, height, &dot_matrix);
|
|
});
|
|
|
|
window.set_child(Some(&drawing_area));
|
|
window.show();
|
|
}
|
|
|
|
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.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 spacing_x = 25.0;
|
|
let spacing_y = 25.0;
|
|
let radius = 10.0;
|
|
|
|
for (row_index, row) in matrix.iter().enumerate() {
|
|
for (col_index, &val) in row.iter().enumerate() {
|
|
if val == 1 {
|
|
let x = (col_index as f64 + 0.5) * spacing_x;
|
|
let y = (row_index as f64 + 0.5) * spacing_y;
|
|
cr.arc(x, y, radius, 0.0, std::f64::consts::PI * 2.0);
|
|
let _ = cr.fill();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn insert_matrix_at(
|
|
target: &mut Vec<Vec<u8>>,
|
|
insert: &Vec<Vec<u8>>,
|
|
row_offset: usize,
|
|
col_offset: usize,
|
|
) {
|
|
for (i, insert_row) in insert.iter().enumerate() {
|
|
for (j, &val) in insert_row.iter().enumerate() {
|
|
if row_offset + i < target.len() && col_offset + j < target[0].len() {
|
|
target[row_offset + i][col_offset + j] = val;
|
|
}
|
|
}
|
|
}
|
|
}
|