This commit is contained in:
Emilia Allison 2023-05-11 17:49:03 -04:00
commit 14df69db59
Signed by: emilia
GPG Key ID: 7A3F8997BFE894E0
9 changed files with 1869 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/target
/dist

1671
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

12
Cargo.toml Normal file
View File

@ -0,0 +1,12 @@
[package]
name = "plate-tool"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
dioxus = "0.3.2"
dioxus-web = "0.3.1"
log = "0.4"
wasm-logger = "0.2"

46
Dioxus.toml Normal file
View File

@ -0,0 +1,46 @@
[application]
# dioxus project name
name = "Plate Tool"
# default platfrom
# you can also use `dioxus serve/build --platform XXX` to use other platform
# value: web | desktop
default_platform = "web"
# Web `build` & `serve` dist path
out_dir = "dist"
# resource (static) file folder
asset_dir = "public"
[web.app]
# HTML title tag content
title = "Plate Tool"
[web.watcher]
watch_path = ["src"]
index_on_404 = true
# include `assets` in web platform
[web.resource]
# CSS style file
style = []
# Javascript code file
script = []
[web.resource.dev]
# Javascript code file
# serve: [dev-server] only
script = []
[application.tools]
# use binaryen.wasm-opt for output Wasm file
# binaryen just will trigger in `web` platform
binaryen = { wasm_opt = true }

1
src/components/mod.rs Normal file
View File

@ -0,0 +1 @@
pub mod source_plate;

16
src/components/plate.css Normal file
View File

@ -0,0 +1,16 @@
table, tr, td {
box-sizing: border-box;
user-select: none;
}
td.plate_cell {
width: 30px;
height: 30px;
background: blue;
}
td.plate_cell:hover {
background: purple;
}
td.current_select {
border: 3px solid red;
}

View File

@ -0,0 +1,97 @@
#![allow(non_snake_case)]
use dioxus::prelude::*;
static STYLE: &'static str = include_str!("plate.css");
#[derive(PartialEq, Props)]
pub struct SourcePlateProps {
width: u8,
height: u8,
}
struct SelectionState {
m_start: Option<(u8,u8)>,
m_end: Option<(u8,u8)>,
m_stat: bool
}
pub fn SourcePlate(cx: Scope<SourcePlateProps>) -> Element {
use_shared_state_provider(cx, || SelectionState {
m_start: None,
m_end: None,
m_stat: false
});
cx.render(rsx!{
style {
vec![STYLE].into_iter().map(|s| rsx!{s}) // This is stupid
}
PlateSelectionIndicator {}
table {
draggable: "false",
for i in 1..=cx.props.height {
tr {
draggable: "false",
for j in 1..=cx.props.width {
SourcePlateCell {i: i, j: j}
}
}
},
}
})
}
#[inline_props]
fn SourcePlateCell(cx: Scope<PlateCellProps>, i: u8, j: u8,) -> Element {
let selection_state = use_shared_state::<SelectionState>(cx).unwrap();
let selected = in_square(selection_state.read().m_start,
selection_state.read().m_end, (*i,*j));
let selected_class = match selected {
true => "current_select",
false => ""
};
cx.render(rsx!{
td {
class: "plate_cell {selected_class}",
draggable: "false",
onmousedown: move |_| {
selection_state.write().m_start = Some((*i,*j));
selection_state.write().m_end = None;
selection_state.write().m_stat = true;
},
onmouseover: move |_| {
if selection_state.read().m_stat {
selection_state.write().m_end = Some((*i,*j))
}
},
onmouseup: move |_| {
selection_state.write().m_stat = false
},
}
})
}
fn in_square(corner1: Option<(u8,u8)>, corner2: Option<(u8,u8)>, pt: (u8,u8)) -> bool {
if let (Some(c1), Some(c2)) = (corner1, corner2) {
return pt.0 <= u8::max(c1.0,c2.0) &&
pt.0 >= u8::min(c1.0,c2.0) &&
pt.1 <= u8::max(c1.1,c2.1) &&
pt.1 >= u8::min(c1.1,c2.1)
} else { return false }
}
fn PlateSelectionIndicator(cx: Scope) -> Element {
let selection_state = use_shared_state::<SelectionState>(cx).unwrap();
let start_str = match selection_state.read().m_start {
Some(start) => format!("{},{}", start.0, start.1),
None => "None".to_string()
};
let end_str = match selection_state.read().m_end{
Some(end) => format!("{},{}", end.0, end.1),
None => "None".to_string()
};
cx.render(rsx!{
p { start_str ", and " end_str }
})
}

17
src/lib.rs Normal file
View File

@ -0,0 +1,17 @@
#![allow(non_snake_case)]
mod components;
use dioxus::prelude::*;
use components::source_plate::SourcePlate;
pub fn App(cx: Scope) -> Element {
cx.render(rsx! {
div {
"Shrimp"
SourcePlate {
width: 24,
height: 18,
}
}
})
}

7
src/main.rs Normal file
View File

@ -0,0 +1,7 @@
use plate_tool::App;
use wasm_logger;
fn main() {
wasm_logger::init(wasm_logger::Config::default());
dioxus_web::launch(App);
}