use mossfets_game_of_life::game::Coord; use relm4::factory::Position; use relm4::factory::positions::GridPosition; use relm4::prelude::{FactoryComponent, DynamicIndex}; use relm4::{gtk, RelmWidgetExt}; use adw::prelude::{AccessibleExtManual, WidgetExt}; use gtk::prelude::ButtonExt; use crate::app::AppMsg; /// A cell being rendered to the grid. The coordinates are in grid space. #[derive(Debug)] pub struct Cell { coordinate: (isize, isize), pub value: bool, } impl Cell { pub fn get_coordinate(&self) -> &(isize, isize) { &(self.coordinate) } pub fn new(coordinate: (isize, isize), value: bool) -> Self { Self { coordinate, value } } } #[derive(Debug)] pub enum CellMsg {} #[derive(Debug)] pub enum CellOutput { ChangeAtGridSpacePoint(Coord), } #[relm4::factory(pub)] impl FactoryComponent for Cell { type Init = (Coord, bool); type Input = CellMsg; type Output = CellOutput; type CommandOutput = (); type Widgets = FactoryWidgets; type ParentInput = AppMsg; //type Factory = FactoryVec; //type Root = gtk::AspectFrame; type ParentWidget = gtk::Grid; // A grid cell view! { root = gtk::AspectFrame { set_ratio: 10.0, #[wrap(Some)] #[name = "button"] set_child = >k::Button { connect_clicked[sender, coord = self.coordinate] => move |_| { sender.output(CellOutput::ChangeAtGridSpacePoint(coord)); }, set_hexpand: true, set_vexpand: true, set_class_active: ("cell", true), #[watch] update_property: &[gtk::accessible::Property::Description( &format!( "Cell {} {} {}", self.coordinate.0, self.coordinate.1, if self.value { "live" } else { "dead" } ) )], // Set the CSS "live" class to whether the cell is live, and update appropriately #[watch] set_class_active: ("live", self.value), }, } } fn init_model(init: Self::Init, _index: &DynamicIndex, _sender: relm4::FactorySender) -> Self { let (coordinate, value) = init; Self { coordinate, value } } fn output_to_parent_input(output: Self::Output) -> Option { Some(match output { CellOutput::ChangeAtGridSpacePoint(coordinate) => AppMsg::ChangeAtGridSpacePoint(coordinate), }) } /*fn view ( &self, _key: &>::Key, widgets: &Self::Widgets, ) { // The "live" CSS class makes the cell appear white. widgets.button.child().unwrap().set_class_active("live", self.value) }*/ } impl Position for Cell { fn position(&self, _index: usize) -> GridPosition { GridPosition { column: self.coordinate.0 as i32, row: self.coordinate.1 as i32, width: 1, height: 1, } } }