Complete port to yew
This is the biggest commit of all time. Yew requires so much cloning smh As a side note, if you drag to select the plate a lot, it uses a lot of CPU resources.
This commit is contained in:
		
							parent
							
								
									240c37a94d
								
							
						
					
					
						commit
						ba3eca603b
					
				| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					    <head>
 | 
				
			||||||
 | 
					        <meta charset="utf-8" />
 | 
				
			||||||
 | 
					        <link data-trunk rel="css" href="assets/css/global.css">
 | 
				
			||||||
 | 
					        <link data-trunk rel="css" href="assets/css/plate.css">
 | 
				
			||||||
 | 
					        <link data-trunk rel="css" href="assets/css/plate_container.css">
 | 
				
			||||||
 | 
					        <title>Yew App</title>
 | 
				
			||||||
 | 
					    </head>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
| 
						 | 
					@ -1,22 +1,17 @@
 | 
				
			||||||
#![allow(non_snake_case)]
 | 
					#![allow(non_snake_case)]
 | 
				
			||||||
use dioxus::prelude::*;
 | 
					use yew::prelude::*;
 | 
				
			||||||
use super::plates::plate_container::PlateContainer;
 | 
					use super::plates::plate_container::PlateContainer;
 | 
				
			||||||
use super::tree::Tree;
 | 
					use super::tree::Tree;
 | 
				
			||||||
use super::transfer_menu::TransferMenu;
 | 
					use super::transfer_menu::TransferMenu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static STYLE: &'static str = include_str!("global.css");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn MainWindow(cx: Scope) -> Element {
 | 
					#[function_component]
 | 
				
			||||||
    cx.render(rsx! {
 | 
					pub fn MainWindow() -> Html {
 | 
				
			||||||
        style { STYLE },
 | 
					    html!{
 | 
				
			||||||
        div {
 | 
					        <div class="main_container">
 | 
				
			||||||
            class: "main_container",
 | 
					            <Tree />
 | 
				
			||||||
            Tree {},
 | 
					            <TransferMenu />
 | 
				
			||||||
            TransferMenu {},
 | 
					            <PlateContainer source_dims={(24,16)} destination_dims={(24,16)}/>
 | 
				
			||||||
            PlateContainer {
 | 
					        </div>
 | 
				
			||||||
                source_dims: (24,16),
 | 
					 | 
				
			||||||
                destination_dims: (24,16)
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,35 @@
 | 
				
			||||||
#![allow(non_snake_case)]
 | 
					#![allow(non_snake_case)]
 | 
				
			||||||
use dioxus::prelude::*;
 | 
					use yew::prelude::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[inline_props]
 | 
					#[derive(Properties, PartialEq)]
 | 
				
			||||||
pub fn DestinationPlate(cx: Scope, width: u8, height: u8) -> Element {
 | 
					pub struct DestinationPlateProps {
 | 
				
			||||||
 | 
					    pub width: u8,
 | 
				
			||||||
 | 
					    pub height: u8,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[function_component]
 | 
				
			||||||
 | 
					pub fn DestinationPlate(props: &DestinationPlateProps) -> Html {
 | 
				
			||||||
 | 
					    let rows = (1..=props.height).map(|i| {
 | 
				
			||||||
 | 
					        let row = (1..=props.width).map(|j| {
 | 
				
			||||||
 | 
					            html! {
 | 
				
			||||||
 | 
					                <DestPlateCell i={i} j={j} />
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }).collect::<Html>();
 | 
				
			||||||
 | 
					        html! {
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                { row }
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }).collect::<Html>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    html! {
 | 
				
			||||||
 | 
					        <div class="dest_plate">
 | 
				
			||||||
 | 
					            <table>
 | 
				
			||||||
 | 
					                { rows }
 | 
				
			||||||
 | 
					            </table>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
    cx.render(rsx! {
 | 
					    cx.render(rsx! {
 | 
				
			||||||
        div {
 | 
					        div {
 | 
				
			||||||
            class: "dest_plate",
 | 
					            class: "dest_plate",
 | 
				
			||||||
| 
						 | 
					@ -18,15 +45,29 @@ pub fn DestinationPlate(cx: Scope, width: u8, height: u8) -> Element {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[inline_props]
 | 
					#[derive(Properties, PartialEq)]
 | 
				
			||||||
fn DestPlateCell(cx: Scope<PlateCellProps>, i: u8, j: u8, color: Option<String>) -> Element {
 | 
					pub struct DestPlateCellProps {
 | 
				
			||||||
    let color_string = match color {
 | 
					    pub i: u8,
 | 
				
			||||||
 | 
					    pub j: u8,
 | 
				
			||||||
 | 
					    pub color: Option<String>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[function_component]
 | 
				
			||||||
 | 
					fn DestPlateCell(props: &DestPlateCellProps) -> Html {
 | 
				
			||||||
 | 
					    let color_string = match &props.color {
 | 
				
			||||||
        Some(c) => c.clone(),
 | 
					        Some(c) => c.clone(),
 | 
				
			||||||
        None => "None".to_string(),
 | 
					        None => "None".to_string(),
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    html! {
 | 
				
			||||||
 | 
					        <td class="plate_cell">
 | 
				
			||||||
 | 
					            <div class="plate_cell_inner" />
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
    cx.render(rsx! {
 | 
					    cx.render(rsx! {
 | 
				
			||||||
        td {
 | 
					        td {
 | 
				
			||||||
            class: "plate_cell",
 | 
					            class: "plate_cell",
 | 
				
			||||||
| 
						 | 
					@ -37,4 +78,5 @@ fn DestPlateCell(cx: Scope<PlateCellProps>, i: u8, j: u8, color: Option<String>)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,20 +1,20 @@
 | 
				
			||||||
#![allow(non_snake_case)]
 | 
					#![allow(non_snake_case)]
 | 
				
			||||||
use dioxus::prelude::*;
 | 
					use yew::prelude::*;
 | 
				
			||||||
use super::source_plate::SourcePlate;
 | 
					 use super::source_plate::SourcePlate;
 | 
				
			||||||
use super::destination_plate::DestinationPlate;
 | 
					use super::destination_plate::DestinationPlate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static STYLE: &'static str = include_str!("plate_container.css");
 | 
					#[derive(Properties, PartialEq)]
 | 
				
			||||||
 | 
					pub struct PlateContainerProps {
 | 
				
			||||||
#[inline_props]
 | 
					    pub source_dims: (u8,u8),
 | 
				
			||||||
pub fn PlateContainer(cx: Scope, source_dims: (u8,u8), destination_dims: (u8,u8)) -> Element {
 | 
					    pub destination_dims: (u8,u8)
 | 
				
			||||||
    cx.render(rsx! {
 | 
					}
 | 
				
			||||||
        style { STYLE }
 | 
					
 | 
				
			||||||
        div {
 | 
					#[function_component]
 | 
				
			||||||
            class: "plate_container",
 | 
					pub fn PlateContainer(props: &PlateContainerProps) -> Html {
 | 
				
			||||||
            SourcePlate {width: source_dims.0,
 | 
					    html! {
 | 
				
			||||||
                         height: source_dims.1},
 | 
					        <div class="plate_container">
 | 
				
			||||||
            DestinationPlate {width: destination_dims.0,
 | 
					            <SourcePlate width={props.source_dims.0} height={props.source_dims.1} />
 | 
				
			||||||
                              height: destination_dims.1}
 | 
					            <DestinationPlate width={props.destination_dims.0} height={props.destination_dims.1} />
 | 
				
			||||||
        }
 | 
					        </div>
 | 
				
			||||||
    })
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,62 +1,120 @@
 | 
				
			||||||
#![allow(non_snake_case)]
 | 
					#![allow(non_snake_case)]
 | 
				
			||||||
use dioxus::prelude::*;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static STYLE: &'static str = include_str!("plate.css");
 | 
					use yew::prelude::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(PartialEq, Props)]
 | 
					#[derive(PartialEq, Properties)]
 | 
				
			||||||
pub struct SourcePlateProps {
 | 
					pub struct SourcePlateProps {
 | 
				
			||||||
    width: u8,
 | 
					    pub width: u8,
 | 
				
			||||||
    height: u8,
 | 
					    pub height: u8,
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
struct SelectionState {
 | 
					 | 
				
			||||||
    m_start: Option<(u8, u8)>,
 | 
					 | 
				
			||||||
    m_end: Option<(u8, u8)>,
 | 
					 | 
				
			||||||
    m_stat: bool,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn SourcePlate(cx: Scope<SourcePlateProps>) -> Element {
 | 
					#[function_component]
 | 
				
			||||||
    use_shared_state_provider(cx, || SelectionState {
 | 
					pub fn SourcePlate(props: &SourcePlateProps) -> Html {
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					    let selection_state = use_state_eq(|| SelectionState{
 | 
				
			||||||
        m_start: None,
 | 
					        m_start: None,
 | 
				
			||||||
        m_end: None,
 | 
					        m_end: None,
 | 
				
			||||||
        m_stat: false,
 | 
					        m_stat: false
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cx.render(rsx! {
 | 
					    let m_start_handle: UseStateHandle<Option<(u8,u8)>> = use_state_eq(|| None);
 | 
				
			||||||
        div{
 | 
					    let m_end_handle: UseStateHandle<Option<(u8,u8)>> = use_state_eq(|| None);
 | 
				
			||||||
            class: "source_plate",
 | 
					    let m_stat_handle: UseStateHandle<bool> = use_state_eq(|| false);
 | 
				
			||||||
            style { STYLE }
 | 
					    let m_stat_handle2 = m_stat_handle.clone();
 | 
				
			||||||
            table {
 | 
					    let m_start = m_start_handle.clone();
 | 
				
			||||||
                draggable: "false",
 | 
					    let m_end = m_end_handle.clone();
 | 
				
			||||||
                for i in 1..=cx.props.height {
 | 
					
 | 
				
			||||||
                    tr {
 | 
					    let mouse_callback = Callback::from(move |(i,j,t)| {
 | 
				
			||||||
                        draggable: "false",
 | 
					        match t {
 | 
				
			||||||
                        for j in 1..=cx.props.width {
 | 
					            MouseEventType::MOUSEDOWN => {
 | 
				
			||||||
                            SourcePlateCell {i: i, j: j}
 | 
					                m_start_handle.set(Some((i,j)));
 | 
				
			||||||
                        }
 | 
					                m_end_handle.set(None);
 | 
				
			||||||
                    }
 | 
					                m_stat_handle.set(true);
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            MouseEventType::MOUSEENTER => {
 | 
				
			||||||
 | 
					                if *m_stat_handle {
 | 
				
			||||||
 | 
					                    m_end_handle.set(Some((i,j)))
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
    })
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    let mouseup_callback = Callback::from(move |_: MouseEvent| {
 | 
				
			||||||
 | 
					        m_stat_handle2.set(false);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    let mouseleave_callback = Callback::clone(&mouseup_callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let rows = (1..=props.height).map(|i| {
 | 
				
			||||||
 | 
					        let row = (1..=props.width).map(|j| {
 | 
				
			||||||
 | 
					            html! {
 | 
				
			||||||
 | 
					                <SourcePlateCell i={i} j={j}
 | 
				
			||||||
 | 
					                selected={in_rect(*m_start.clone(), *m_end.clone(), (i,j))}
 | 
				
			||||||
 | 
					                mouse={mouse_callback.clone()}/>
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }).collect::<Html>();
 | 
				
			||||||
 | 
					        html! {
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                { row }
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }).collect::<Html>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    html! {
 | 
				
			||||||
 | 
					        <div class="source_plate">
 | 
				
			||||||
 | 
					            <table
 | 
				
			||||||
 | 
					            onmouseup={move |e| {
 | 
				
			||||||
 | 
					                mouseup_callback.emit(e);
 | 
				
			||||||
 | 
					            }}
 | 
				
			||||||
 | 
					            onmouseleave={move |e| {
 | 
				
			||||||
 | 
					                mouseleave_callback.emit(e);
 | 
				
			||||||
 | 
					            }}>
 | 
				
			||||||
 | 
					                { rows }
 | 
				
			||||||
 | 
					            </table>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[inline_props]
 | 
					#[derive(PartialEq, Properties)]
 | 
				
			||||||
fn SourcePlateCell(cx: Scope<PlateCellProps>, i: u8, j: u8, color: Option<String>) -> Element {
 | 
					pub struct SourcePlateCellProps {
 | 
				
			||||||
    let selection_state = use_shared_state::<SelectionState>(cx).unwrap();
 | 
					    i: u8,
 | 
				
			||||||
    let selected = in_rect(
 | 
					    j: u8,
 | 
				
			||||||
        selection_state.read().m_start,
 | 
					    selected: bool,
 | 
				
			||||||
        selection_state.read().m_end,
 | 
					    mouse: Callback<(u8,u8, MouseEventType)>,
 | 
				
			||||||
        (*i, *j),
 | 
					    color: Option<String>
 | 
				
			||||||
    );
 | 
					}
 | 
				
			||||||
    let selected_class = match selected {
 | 
					#[derive(Debug)]
 | 
				
			||||||
        true => "current_select",
 | 
					pub enum MouseEventType {
 | 
				
			||||||
        false => "",
 | 
					    MOUSEDOWN,
 | 
				
			||||||
 | 
					    MOUSEENTER
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[function_component]
 | 
				
			||||||
 | 
					fn SourcePlateCell(props: &SourcePlateCellProps) -> Html {
 | 
				
			||||||
 | 
					    let selected_class = match props.selected {
 | 
				
			||||||
 | 
					        true => Some("current_select"),
 | 
				
			||||||
 | 
					        false => None,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    let color_string = match color {
 | 
					    let color_string = match &props.color {
 | 
				
			||||||
        Some(c) => c.clone(),
 | 
					        Some(c) => c.clone(),
 | 
				
			||||||
        None => "None".to_string(),
 | 
					        None => "None".to_string(),
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					    let mouse = Callback::clone(&props.mouse);
 | 
				
			||||||
 | 
					    let mouse2 = Callback::clone(&props.mouse);
 | 
				
			||||||
 | 
					    let (i,j) = (props.i.clone(), props.j.clone());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    html! {
 | 
				
			||||||
 | 
					        <td class={classes!("plate_cell", selected_class)}
 | 
				
			||||||
 | 
					            onmousedown={move |_| {
 | 
				
			||||||
 | 
					                mouse.emit((i,j, MouseEventType::MOUSEDOWN))
 | 
				
			||||||
 | 
					            }}
 | 
				
			||||||
 | 
					            onmouseenter={move |_| {
 | 
				
			||||||
 | 
					                mouse2.emit((i,j, MouseEventType::MOUSEENTER))
 | 
				
			||||||
 | 
					            }}>
 | 
				
			||||||
 | 
					            <div class="plate_cell_inner" />
 | 
				
			||||||
 | 
					        </td>
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
    cx.render(rsx! {
 | 
					    cx.render(rsx! {
 | 
				
			||||||
        td {
 | 
					        td {
 | 
				
			||||||
            class: "plate_cell {selected_class}",
 | 
					            class: "plate_cell {selected_class}",
 | 
				
			||||||
| 
						 | 
					@ -83,6 +141,7 @@ fn SourcePlateCell(cx: Scope<PlateCellProps>, i: u8, j: u8, color: Option<String
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn in_rect(corner1: Option<(u8, u8)>, corner2: Option<(u8, u8)>, pt: (u8, u8)) -> bool {
 | 
					fn in_rect(corner1: Option<(u8, u8)>, corner2: Option<(u8, u8)>, pt: (u8, u8)) -> bool {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,157 @@
 | 
				
			||||||
 | 
					#![allow(non_snake_case)]
 | 
				
			||||||
 | 
					use yew::prelude::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(PartialEq, Properties)]
 | 
				
			||||||
 | 
					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(props: &SourcePlateProps) -> Html {
 | 
				
			||||||
 | 
					    use_shared_state_provider(cx, || SelectionState {
 | 
				
			||||||
 | 
					        m_start: None,
 | 
				
			||||||
 | 
					        m_end: None,
 | 
				
			||||||
 | 
					        m_stat: false,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cx.render(rsx! {
 | 
				
			||||||
 | 
					        div{
 | 
				
			||||||
 | 
					            class: "source_plate",
 | 
				
			||||||
 | 
					            style { STYLE }
 | 
				
			||||||
 | 
					            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}
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(PartialEq, Properties)]
 | 
				
			||||||
 | 
					pub struct SourcePlateCellProps {
 | 
				
			||||||
 | 
					    i: u8,
 | 
				
			||||||
 | 
					    j: u8,
 | 
				
			||||||
 | 
					    color: Option<String>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn SourcePlateCell(props: &SourcePlateCe) -> Element {
 | 
				
			||||||
 | 
					    let selection_state = use_shared_state::<SelectionState>(cx).unwrap();
 | 
				
			||||||
 | 
					    let selected = in_rect(
 | 
				
			||||||
 | 
					        selection_state.read().m_start,
 | 
				
			||||||
 | 
					        selection_state.read().m_end,
 | 
				
			||||||
 | 
					        (*i, *j),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    let selected_class = match selected {
 | 
				
			||||||
 | 
					        true => "current_select",
 | 
				
			||||||
 | 
					        false => "",
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    let color_string = match color {
 | 
				
			||||||
 | 
					        Some(c) => c.clone(),
 | 
				
			||||||
 | 
					        None => "None".to_string(),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cx.render(rsx! {
 | 
				
			||||||
 | 
					        td {
 | 
				
			||||||
 | 
					            class: "plate_cell {selected_class}",
 | 
				
			||||||
 | 
					            draggable: "false",
 | 
				
			||||||
 | 
					            style: "background: {color_string}",
 | 
				
			||||||
 | 
					            onmousedown: move |_| {
 | 
				
			||||||
 | 
					                selection_state.write().m_start = Some((*i,*j));
 | 
				
			||||||
 | 
					                selection_state.write().m_end = None;
 | 
				
			||||||
 | 
					                selection_state.write().m_stat = true;
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            onmouseenter: move |me: MouseEvent| {
 | 
				
			||||||
 | 
					                if me.data.held_buttons().is_empty() {
 | 
				
			||||||
 | 
					                    selection_state.write().m_stat = false;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if selection_state.read().m_stat {
 | 
				
			||||||
 | 
					                    selection_state.write().m_end = Some((*i,*j))
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            onmouseup: move |_| {
 | 
				
			||||||
 | 
					                selection_state.write().m_stat = false
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            div {
 | 
				
			||||||
 | 
					                class: "plate_cell_inner"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn in_rect(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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(test)]
 | 
				
			||||||
 | 
					mod tests {
 | 
				
			||||||
 | 
					    use super::in_rect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // in_rect tests
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_in_rect1() {
 | 
				
			||||||
 | 
					        // Test in center of rect
 | 
				
			||||||
 | 
					        let c1 = (1, 1);
 | 
				
			||||||
 | 
					        let c2 = (10, 10);
 | 
				
			||||||
 | 
					        let pt = (5, 5);
 | 
				
			||||||
 | 
					        assert!(in_rect(Some(c1), Some(c2), pt));
 | 
				
			||||||
 | 
					        // Order of the corners should not matter:
 | 
				
			||||||
 | 
					        assert!(in_rect(Some(c2), Some(c1), pt));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_in_rect2() {
 | 
				
			||||||
 | 
					        // Test on top/bottom edges of rect
 | 
				
			||||||
 | 
					        let c1 = (1, 1);
 | 
				
			||||||
 | 
					        let c2 = (10, 10);
 | 
				
			||||||
 | 
					        let pt1 = (1, 5);
 | 
				
			||||||
 | 
					        let pt2 = (10, 5);
 | 
				
			||||||
 | 
					        assert!(in_rect(Some(c1), Some(c2), pt1));
 | 
				
			||||||
 | 
					        assert!(in_rect(Some(c1), Some(c2), pt2));
 | 
				
			||||||
 | 
					        // Order of the corners should not matter:
 | 
				
			||||||
 | 
					        assert!(in_rect(Some(c2), Some(c1), pt1));
 | 
				
			||||||
 | 
					        assert!(in_rect(Some(c2), Some(c1), pt2));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_in_rect3() {
 | 
				
			||||||
 | 
					        // Test on left/right edges of rect
 | 
				
			||||||
 | 
					        let c1 = (1, 1);
 | 
				
			||||||
 | 
					        let c2 = (10, 10);
 | 
				
			||||||
 | 
					        let pt1 = (5, 1);
 | 
				
			||||||
 | 
					        let pt2 = (5, 10);
 | 
				
			||||||
 | 
					        assert!(in_rect(Some(c1), Some(c2), pt1));
 | 
				
			||||||
 | 
					        assert!(in_rect(Some(c1), Some(c2), pt2));
 | 
				
			||||||
 | 
					        // Order of the corners should not matter:
 | 
				
			||||||
 | 
					        assert!(in_rect(Some(c2), Some(c1), pt1));
 | 
				
			||||||
 | 
					        assert!(in_rect(Some(c2), Some(c1), pt2));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_in_rect4() {
 | 
				
			||||||
 | 
					        // Test cases that should fail
 | 
				
			||||||
 | 
					        let c1 = (1, 1);
 | 
				
			||||||
 | 
					        let c2 = (10, 10);
 | 
				
			||||||
 | 
					        let pt1 = (0, 0);
 | 
				
			||||||
 | 
					        let pt2 = (15, 15);
 | 
				
			||||||
 | 
					        assert_eq!(false, in_rect(Some(c1), Some(c2), pt1));
 | 
				
			||||||
 | 
					        assert_eq!(false, in_rect(Some(c1), Some(c2), pt2));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,33 +1,20 @@
 | 
				
			||||||
#![allow(non_snake_case)]
 | 
					#![allow(non_snake_case)]
 | 
				
			||||||
use dioxus::prelude::*;
 | 
					use yew::prelude::*;
 | 
				
			||||||
use regex::Regex;
 | 
					use regex::Regex;
 | 
				
			||||||
use lazy_static::lazy_static;
 | 
					use lazy_static::lazy_static;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[inline_props]
 | 
					#[function_component]
 | 
				
			||||||
pub fn TransferMenu(cx: Scope) -> Element {
 | 
					pub fn TransferMenu() -> Html {
 | 
				
			||||||
    cx.render(rsx! {
 | 
					    html! {
 | 
				
			||||||
        div {
 | 
					        <div class="transfer_menu">
 | 
				
			||||||
            class: "transfer_menu",
 | 
					            <form>
 | 
				
			||||||
            form{
 | 
					                <label for="src_region">{"Source Region:"}</label>
 | 
				
			||||||
                label {
 | 
					                <input type="text" name="src_region" />
 | 
				
			||||||
                    r#for: "src_region",
 | 
					                <label for="dest_region">{"Destination Region:"}</label>
 | 
				
			||||||
                    "Source Region:"
 | 
					                <input type="text" name="dest_region" />
 | 
				
			||||||
                },
 | 
					            </form>
 | 
				
			||||||
                input {
 | 
					        </div>
 | 
				
			||||||
                    r#type: "text",
 | 
					 | 
				
			||||||
                    name: "src_region",
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                label {
 | 
					 | 
				
			||||||
                    r#for: "dest_region",
 | 
					 | 
				
			||||||
                    "Destination Region:"
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                input {
 | 
					 | 
				
			||||||
                    r#type: "text",
 | 
					 | 
				
			||||||
                    name: "dest_region",
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(PartialEq, Eq, Debug)]
 | 
					#[derive(PartialEq, Eq, Debug)]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,10 @@
 | 
				
			||||||
#![allow(non_snake_case)]
 | 
					#![allow(non_snake_case)]
 | 
				
			||||||
use dioxus::prelude::*;
 | 
					use yew::prelude::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[inline_props]
 | 
					#[function_component]
 | 
				
			||||||
pub fn Tree(cx: Scope) -> Element {
 | 
					pub fn Tree() -> Html {
 | 
				
			||||||
    cx.render(rsx! {
 | 
					    html! {
 | 
				
			||||||
        div {
 | 
					        <div class="tree">
 | 
				
			||||||
            class: "tree",
 | 
					        </div>
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										13
									
								
								src/lib.rs
								
								
								
								
							
							
						
						
									
										13
									
								
								src/lib.rs
								
								
								
								
							| 
						 | 
					@ -2,18 +2,17 @@
 | 
				
			||||||
mod components;
 | 
					mod components;
 | 
				
			||||||
mod data;
 | 
					mod data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use yew::prelude::*;
 | 
				
			||||||
use components::main_window::MainWindow;
 | 
					use components::main_window::MainWindow;
 | 
				
			||||||
use dioxus::prelude::*;
 | 
					 | 
				
			||||||
use fermi::*;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(debug_assertions)]
 | 
					#[cfg(debug_assertions)]
 | 
				
			||||||
use data::*;
 | 
					use data::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn App(cx: Scope) -> Element {
 | 
					#[function_component]
 | 
				
			||||||
    use_init_atom_root(cx);
 | 
					pub fn App() -> Html {
 | 
				
			||||||
    cx.render(rsx! {
 | 
					    html! {
 | 
				
			||||||
        MainWindow {}
 | 
					        <MainWindow />
 | 
				
			||||||
    })
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(debug_assertions)]
 | 
					#[cfg(debug_assertions)]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,9 +3,10 @@ use plate_tool::plate_test;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use plate_tool::App;
 | 
					use plate_tool::App;
 | 
				
			||||||
use wasm_logger;
 | 
					use wasm_logger;
 | 
				
			||||||
 | 
					use yew::prelude::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn main() {
 | 
					fn main() {
 | 
				
			||||||
    wasm_logger::init(wasm_logger::Config::default());
 | 
					    wasm_logger::init(wasm_logger::Config::default());
 | 
				
			||||||
    dioxus_web::launch(App);
 | 
					    yew::Renderer::<App>::new().render();
 | 
				
			||||||
    //plate_test();
 | 
					    //plate_test();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue