Files
playmat/src/grid.rs
2019-06-05 16:35:45 +02:00

138 lines
3.6 KiB
Rust

use crate::*;
pub struct Grid {
inner: gtk::Grid,
}
#[derive(Debug,Copy,Clone)]
pub struct CellPosition(i32, i32);
impl Grid {
/// Initialize a grid, populating its cells
/// Only square grid for now
pub(crate) fn init(inner: gtk::Grid, size: i32, app_state: AppState) -> Self {
for i in 0..(size * size) {
let x = i % size;
let y = i / size;
let cell = grid::Cell::new(
CellPosition(x,y)
);
cell.inner.connect_clicked(app_state.clone());
cell.inner.connect_drag_drop(app_state.clone());
inner.attach(cell.as_ref(), x, y, 1, 1);
}
Grid { inner }
}
}
struct CellWidget {
eventbox: gtk::EventBox,
position: gtk::Label,
header : gtk::Label,
content: gtk::Label,
}
impl CellWidget {
fn new(pos: CellPosition, header_text: &str) -> Self {
let cell_src = include_str!("../res/cell.glade");
let builder = gtk::Builder::new_from_string(&cell_src);
// Set up reactivity on buttons
let eventbox: gtk::EventBox =
builder
.get_object("cell")
.unwrap();
eventbox.set_events(gdk::EventMask::BUTTON_PRESS_MASK);
let header: gtk::Label =
builder
.get_object("header")
.unwrap();
header.set_text(header_text);
let position: gtk::Label =
builder
.get_object("position")
.unwrap();
position.set_text(&format!("{}x{}", pos.0, pos.1));
let cell = CellWidget {
eventbox,
position,
header,
content: builder.get_object("content").unwrap(),
};
cell
}
pub fn connect_clicked(&self, state: AppState) {
let header = self.header.clone();
let content = self.content.clone();
self.eventbox
.connect_button_press_event(move |_,_| {
let mut state = state.borrow_mut();
if let Some(data) = state.pending.take() {
println!("{:?}", data);
content.set_text(&data.name);
};
header.set_text("Is Clicked.");
gtk::Inhibit(true)
});
}
pub fn connect_drag_drop(&self, _state: AppState) {
// Drag-and-drop capacity
let targets = vec![];
self.eventbox.drag_dest_set(
gtk::DestDefaults::ALL,
&targets,
gdk::DragAction::COPY,
);
self.eventbox.drag_source_set(
gdk::ModifierType::MODIFIER_MASK,
&targets,
gdk::DragAction::COPY,
);
//let app_state = state.clone();
self.eventbox.connect_drag_begin(|_,_| {
println!("Lift...");
// Copy the current instance data
// inside app_state.pending
});
self.eventbox.connect_drag_end(|_,_| {
println!("Drop !");
// Same as clicked, grab data
});
// TODO: Add failed signal to remove data
}
}
impl AsRef<gtk::EventBox> for CellWidget {
#[inline]
fn as_ref(&self) -> &gtk::EventBox {
&self.eventbox
}
}
struct Cell {
inner: CellWidget,
position: CellPosition,
}
impl Cell {
fn new(position: CellPosition) -> Self {
Cell {
inner: CellWidget::new(position, ""),
position
}
}
}
impl AsRef<gtk::EventBox> for Cell {
#[inline]
fn as_ref(&self) -> &gtk::EventBox {
self.inner.as_ref()
}
}