Impl additional info text box, drop logic
Can place tokens, and not place tokens where there already is a token. Additional info text box added to the side of the board. More information to the UI regarding placed tokens.
This commit is contained in:
parent
4c8e330c05
commit
3b4d8b3483
5 changed files with 307 additions and 140 deletions
|
@ -9,4 +9,4 @@ edition = "2021"
|
||||||
yew = "0.19"
|
yew = "0.19"
|
||||||
log = "0.4.6"
|
log = "0.4.6"
|
||||||
wasm-logger = "0.2.0"
|
wasm-logger = "0.2.0"
|
||||||
web-sys = { version = "0.3.56", features = ["HtmlDivElement"] }
|
web-sys = { version = "0.3.56", features = ["HtmlDivElement", "HtmlButtonElement"] }
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<style>
|
<style>
|
||||||
div.wrapper {
|
div.wrapper {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(7, 50px);
|
grid-template-columns: repeat(7, 50px) 400px;
|
||||||
gap: 2px;
|
gap: 2px;
|
||||||
grid-auto-rows: 50px;
|
grid-auto-rows: 50px;
|
||||||
border: 0px;
|
border: 0px;
|
||||||
|
@ -15,9 +15,13 @@
|
||||||
grid-row: 9;
|
grid-row: 9;
|
||||||
grid-column: 1 / 8;
|
grid-column: 1 / 8;
|
||||||
}
|
}
|
||||||
div.info_text {
|
div.info_text_side_wrapper {
|
||||||
|
grid-row: 1 / 9;
|
||||||
|
grid-column: 8;
|
||||||
|
}
|
||||||
|
div.info_text0 {
|
||||||
background-color: #DDD;
|
background-color: #DDD;
|
||||||
width: fill;
|
width: 100%;
|
||||||
height: 400px;
|
height: 400px;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
@ -25,6 +29,16 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column-reverse;
|
flex-direction: column-reverse;
|
||||||
}
|
}
|
||||||
|
div.info_text1 {
|
||||||
|
background-color: #DDD;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
word-wrap: break-word;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
}
|
||||||
button.slot {
|
button.slot {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//const ROWS: u8 = 8;
|
pub const ROWS: u8 = 8;
|
||||||
pub const COLS: u8 = 7;
|
pub const COLS: u8 = 7;
|
||||||
|
|
||||||
pub const INFO_TEXT_MAX_ITEMS: u32 = 100;
|
pub const INFO_TEXT_MAX_ITEMS: u32 = 100;
|
||||||
pub const INFO_TEXT_HEIGHT: i32 = 400;
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
use std::fmt::Display;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
@ -15,17 +16,37 @@ impl Default for BoardState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for BoardState {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match *self {
|
||||||
|
BoardState::Empty => f.write_str("open"),
|
||||||
|
BoardState::Cyan => f.write_str("cyan"),
|
||||||
|
BoardState::Magenta => f.write_str("magenta"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum Turn {
|
pub enum Turn {
|
||||||
CyanPlayer,
|
CyanPlayer,
|
||||||
MagentaPlayer,
|
MagentaPlayer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Turn {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match *self {
|
||||||
|
Turn::CyanPlayer => f.write_str("CyanPlayer"),
|
||||||
|
Turn::MagentaPlayer => f.write_str("MagentaPlayer"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct SharedState {
|
pub struct SharedState {
|
||||||
pub board: [Rc<Cell<BoardState>>; 56],
|
pub board: [Rc<Cell<BoardState>>; 56],
|
||||||
pub turn: Cell<Turn>,
|
pub turn: Rc<Cell<Turn>>,
|
||||||
pub info_text_ref: NodeRef,
|
pub info_text_ref: [NodeRef; 2],
|
||||||
|
pub slot_refs: [NodeRef; 56],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SharedState {
|
impl Default for SharedState {
|
||||||
|
@ -90,8 +111,68 @@ impl Default for SharedState {
|
||||||
Rc::new(Cell::new(BoardState::default())),
|
Rc::new(Cell::new(BoardState::default())),
|
||||||
Rc::new(Cell::new(BoardState::default())),
|
Rc::new(Cell::new(BoardState::default())),
|
||||||
],
|
],
|
||||||
turn: Cell::new(Turn::CyanPlayer),
|
turn: Rc::new(Cell::new(Turn::CyanPlayer)),
|
||||||
info_text_ref: NodeRef::default(),
|
// NodeRef array needs to have unique values
|
||||||
|
info_text_ref: [NodeRef::default(), NodeRef::default()],
|
||||||
|
// slot_refs array needs to have unique values
|
||||||
|
slot_refs: [
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
NodeRef::default(),
|
||||||
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::constants::{COLS, INFO_TEXT_HEIGHT, INFO_TEXT_MAX_ITEMS};
|
use crate::constants::{COLS, INFO_TEXT_MAX_ITEMS, ROWS};
|
||||||
use crate::state::{BoardState, SharedState, Turn};
|
use crate::state::{BoardState, SharedState, Turn};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -26,17 +26,14 @@ impl Component for Slot {
|
||||||
|
|
||||||
fn view(&self, ctx: &Context<Self>) -> Html {
|
fn view(&self, ctx: &Context<Self>) -> Html {
|
||||||
let idx = ctx.props().idx;
|
let idx = ctx.props().idx;
|
||||||
let state = match ctx.props().state.as_ref().get() {
|
let state = ctx.props().state.as_ref().get();
|
||||||
BoardState::Empty => "open",
|
|
||||||
BoardState::Cyan => "cyan",
|
|
||||||
BoardState::Magenta => "magenta",
|
|
||||||
};
|
|
||||||
let idx_copy = idx;
|
let idx_copy = idx;
|
||||||
let onclick = ctx.link().callback(move |_| SlotMessage::Press(idx_copy));
|
let onclick = ctx.link().callback(move |_| SlotMessage::Press(idx_copy));
|
||||||
let col = idx % COLS;
|
let col = idx % COLS;
|
||||||
let row = idx / COLS;
|
let row = idx / COLS;
|
||||||
html! {
|
html! {
|
||||||
<button class={format!("slot {} r{} c{}", state, row, col)} id={format!("{}", idx)} onclick={onclick}>
|
<button class={format!("slot {} r{} c{}", state, row, col)} id={format!("{}", idx)} onclick={onclick}>
|
||||||
|
{idx}
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,64 +70,67 @@ impl Component for Wrapper {
|
||||||
.expect("state to be set");
|
.expect("state to be set");
|
||||||
html! {
|
html! {
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<Slot idx=0 state={shared.board[0].clone()} />
|
<Slot idx=0 state={shared.board[0].clone()} ref={shared.slot_refs[0].clone()} />
|
||||||
<Slot idx=1 state={shared.board[1].clone()} />
|
<Slot idx=1 state={shared.board[1].clone()} ref={shared.slot_refs[1].clone()} />
|
||||||
<Slot idx=2 state={shared.board[2].clone()} />
|
<Slot idx=2 state={shared.board[2].clone()} ref={shared.slot_refs[2].clone()} />
|
||||||
<Slot idx=3 state={shared.board[3].clone()} />
|
<Slot idx=3 state={shared.board[3].clone()} ref={shared.slot_refs[3].clone()} />
|
||||||
<Slot idx=4 state={shared.board[4].clone()} />
|
<Slot idx=4 state={shared.board[4].clone()} ref={shared.slot_refs[4].clone()} />
|
||||||
<Slot idx=5 state={shared.board[5].clone()} />
|
<Slot idx=5 state={shared.board[5].clone()} ref={shared.slot_refs[5].clone()} />
|
||||||
<Slot idx=6 state={shared.board[6].clone()} />
|
<Slot idx=6 state={shared.board[6].clone()} ref={shared.slot_refs[6].clone()} />
|
||||||
<Slot idx=7 state={shared.board[7].clone()} />
|
<Slot idx=7 state={shared.board[7].clone()} ref={shared.slot_refs[7].clone()} />
|
||||||
<Slot idx=8 state={shared.board[8].clone()} />
|
<Slot idx=8 state={shared.board[8].clone()} ref={shared.slot_refs[8].clone()} />
|
||||||
<Slot idx=9 state={shared.board[9].clone()} />
|
<Slot idx=9 state={shared.board[9].clone()} ref={shared.slot_refs[9].clone()} />
|
||||||
<Slot idx=10 state={shared.board[10].clone()} />
|
<Slot idx=10 state={shared.board[10].clone()} ref={shared.slot_refs[10].clone()} />
|
||||||
<Slot idx=11 state={shared.board[11].clone()} />
|
<Slot idx=11 state={shared.board[11].clone()} ref={shared.slot_refs[11].clone()} />
|
||||||
<Slot idx=12 state={shared.board[12].clone()} />
|
<Slot idx=12 state={shared.board[12].clone()} ref={shared.slot_refs[12].clone()} />
|
||||||
<Slot idx=13 state={shared.board[13].clone()} />
|
<Slot idx=13 state={shared.board[13].clone()} ref={shared.slot_refs[13].clone()} />
|
||||||
<Slot idx=14 state={shared.board[14].clone()} />
|
<Slot idx=14 state={shared.board[14].clone()} ref={shared.slot_refs[14].clone()} />
|
||||||
<Slot idx=15 state={shared.board[15].clone()} />
|
<Slot idx=15 state={shared.board[15].clone()} ref={shared.slot_refs[15].clone()} />
|
||||||
<Slot idx=16 state={shared.board[16].clone()} />
|
<Slot idx=16 state={shared.board[16].clone()} ref={shared.slot_refs[16].clone()} />
|
||||||
<Slot idx=17 state={shared.board[17].clone()} />
|
<Slot idx=17 state={shared.board[17].clone()} ref={shared.slot_refs[17].clone()} />
|
||||||
<Slot idx=18 state={shared.board[18].clone()} />
|
<Slot idx=18 state={shared.board[18].clone()} ref={shared.slot_refs[18].clone()} />
|
||||||
<Slot idx=19 state={shared.board[19].clone()} />
|
<Slot idx=19 state={shared.board[19].clone()} ref={shared.slot_refs[19].clone()} />
|
||||||
<Slot idx=20 state={shared.board[20].clone()} />
|
<Slot idx=20 state={shared.board[20].clone()} ref={shared.slot_refs[20].clone()} />
|
||||||
<Slot idx=21 state={shared.board[21].clone()} />
|
<Slot idx=21 state={shared.board[21].clone()} ref={shared.slot_refs[21].clone()} />
|
||||||
<Slot idx=22 state={shared.board[22].clone()} />
|
<Slot idx=22 state={shared.board[22].clone()} ref={shared.slot_refs[22].clone()} />
|
||||||
<Slot idx=23 state={shared.board[23].clone()} />
|
<Slot idx=23 state={shared.board[23].clone()} ref={shared.slot_refs[23].clone()} />
|
||||||
<Slot idx=24 state={shared.board[24].clone()} />
|
<Slot idx=24 state={shared.board[24].clone()} ref={shared.slot_refs[24].clone()} />
|
||||||
<Slot idx=25 state={shared.board[25].clone()} />
|
<Slot idx=25 state={shared.board[25].clone()} ref={shared.slot_refs[25].clone()} />
|
||||||
<Slot idx=26 state={shared.board[26].clone()} />
|
<Slot idx=26 state={shared.board[26].clone()} ref={shared.slot_refs[26].clone()} />
|
||||||
<Slot idx=27 state={shared.board[27].clone()} />
|
<Slot idx=27 state={shared.board[27].clone()} ref={shared.slot_refs[27].clone()} />
|
||||||
<Slot idx=28 state={shared.board[28].clone()} />
|
<Slot idx=28 state={shared.board[28].clone()} ref={shared.slot_refs[28].clone()} />
|
||||||
<Slot idx=29 state={shared.board[29].clone()} />
|
<Slot idx=29 state={shared.board[29].clone()} ref={shared.slot_refs[29].clone()} />
|
||||||
<Slot idx=30 state={shared.board[30].clone()} />
|
<Slot idx=30 state={shared.board[30].clone()} ref={shared.slot_refs[30].clone()} />
|
||||||
<Slot idx=31 state={shared.board[31].clone()} />
|
<Slot idx=31 state={shared.board[31].clone()} ref={shared.slot_refs[31].clone()} />
|
||||||
<Slot idx=32 state={shared.board[32].clone()} />
|
<Slot idx=32 state={shared.board[32].clone()} ref={shared.slot_refs[32].clone()} />
|
||||||
<Slot idx=33 state={shared.board[33].clone()} />
|
<Slot idx=33 state={shared.board[33].clone()} ref={shared.slot_refs[33].clone()} />
|
||||||
<Slot idx=34 state={shared.board[34].clone()} />
|
<Slot idx=34 state={shared.board[34].clone()} ref={shared.slot_refs[34].clone()} />
|
||||||
<Slot idx=35 state={shared.board[35].clone()} />
|
<Slot idx=35 state={shared.board[35].clone()} ref={shared.slot_refs[35].clone()} />
|
||||||
<Slot idx=36 state={shared.board[36].clone()} />
|
<Slot idx=36 state={shared.board[36].clone()} ref={shared.slot_refs[36].clone()} />
|
||||||
<Slot idx=37 state={shared.board[37].clone()} />
|
<Slot idx=37 state={shared.board[37].clone()} ref={shared.slot_refs[37].clone()} />
|
||||||
<Slot idx=38 state={shared.board[38].clone()} />
|
<Slot idx=38 state={shared.board[38].clone()} ref={shared.slot_refs[38].clone()} />
|
||||||
<Slot idx=39 state={shared.board[39].clone()} />
|
<Slot idx=39 state={shared.board[39].clone()} ref={shared.slot_refs[39].clone()} />
|
||||||
<Slot idx=40 state={shared.board[40].clone()} />
|
<Slot idx=40 state={shared.board[40].clone()} ref={shared.slot_refs[40].clone()} />
|
||||||
<Slot idx=41 state={shared.board[41].clone()} />
|
<Slot idx=41 state={shared.board[41].clone()} ref={shared.slot_refs[41].clone()} />
|
||||||
<Slot idx=42 state={shared.board[42].clone()} />
|
<Slot idx=42 state={shared.board[42].clone()} ref={shared.slot_refs[42].clone()} />
|
||||||
<Slot idx=43 state={shared.board[43].clone()} />
|
<Slot idx=43 state={shared.board[43].clone()} ref={shared.slot_refs[43].clone()} />
|
||||||
<Slot idx=44 state={shared.board[44].clone()} />
|
<Slot idx=44 state={shared.board[44].clone()} ref={shared.slot_refs[44].clone()} />
|
||||||
<Slot idx=45 state={shared.board[45].clone()} />
|
<Slot idx=45 state={shared.board[45].clone()} ref={shared.slot_refs[45].clone()} />
|
||||||
<Slot idx=46 state={shared.board[46].clone()} />
|
<Slot idx=46 state={shared.board[46].clone()} ref={shared.slot_refs[46].clone()} />
|
||||||
<Slot idx=47 state={shared.board[47].clone()} />
|
<Slot idx=47 state={shared.board[47].clone()} ref={shared.slot_refs[47].clone()} />
|
||||||
<Slot idx=48 state={shared.board[48].clone()} />
|
<Slot idx=48 state={shared.board[48].clone()} ref={shared.slot_refs[48].clone()} />
|
||||||
<Slot idx=49 state={shared.board[49].clone()} />
|
<Slot idx=49 state={shared.board[49].clone()} ref={shared.slot_refs[49].clone()} />
|
||||||
<Slot idx=50 state={shared.board[50].clone()} />
|
<Slot idx=50 state={shared.board[50].clone()} ref={shared.slot_refs[50].clone()} />
|
||||||
<Slot idx=51 state={shared.board[51].clone()} />
|
<Slot idx=51 state={shared.board[51].clone()} ref={shared.slot_refs[51].clone()} />
|
||||||
<Slot idx=52 state={shared.board[52].clone()} />
|
<Slot idx=52 state={shared.board[52].clone()} ref={shared.slot_refs[52].clone()} />
|
||||||
<Slot idx=53 state={shared.board[53].clone()} />
|
<Slot idx=53 state={shared.board[53].clone()} ref={shared.slot_refs[53].clone()} />
|
||||||
<Slot idx=54 state={shared.board[54].clone()} />
|
<Slot idx=54 state={shared.board[54].clone()} ref={shared.slot_refs[54].clone()} />
|
||||||
<Slot idx=55 state={shared.board[55].clone()} />
|
<Slot idx=55 state={shared.board[55].clone()} ref={shared.slot_refs[55].clone()} />
|
||||||
<div class="info_text_wrapper">
|
<div class="info_text_wrapper">
|
||||||
<InfoText />
|
<InfoText id=0 />
|
||||||
|
</div>
|
||||||
|
<div class="info_text_side_wrapper">
|
||||||
|
<InfoText id=1 />
|
||||||
</div>
|
</div>
|
||||||
</div> // wrapper
|
</div> // wrapper
|
||||||
}
|
}
|
||||||
|
@ -141,75 +141,144 @@ impl Component for Wrapper {
|
||||||
.link()
|
.link()
|
||||||
.context::<SharedState>(Callback::noop())
|
.context::<SharedState>(Callback::noop())
|
||||||
.expect("state to be set");
|
.expect("state to be set");
|
||||||
|
let window = web_sys::window().expect("no window exists");
|
||||||
|
let document = window.document().expect("window should have a document");
|
||||||
|
|
||||||
let split_str: Vec<&str> = msg.split_whitespace().collect();
|
let split_str: Vec<&str> = msg.split_whitespace().collect();
|
||||||
if split_str.len() == 2 {
|
if split_str.len() == 2 && split_str[0] == "pressed" {
|
||||||
if split_str[0] == "pressed" {
|
if let Ok(idx) = split_str[1].parse::<u8>() {
|
||||||
if let Ok(idx) = split_str[1].parse::<u8>() {
|
let mut bottom_idx = idx;
|
||||||
let output_str: String = format!("Got {idx} pressed.");
|
let mut placed = false;
|
||||||
shared.board[idx as usize].replace(match shared.board[idx as usize].get() {
|
let current_player = shared.turn.get();
|
||||||
BoardState::Empty => BoardState::Cyan,
|
|
||||||
BoardState::Cyan => BoardState::Magenta,
|
// check if clicked on empty slot
|
||||||
BoardState::Magenta => BoardState::Empty,
|
if shared.board[idx as usize].get() == BoardState::Empty {
|
||||||
|
// get bottom-most empty slot
|
||||||
|
while bottom_idx + COLS < ROWS * COLS
|
||||||
|
&& shared.board[(bottom_idx + COLS) as usize].get() == BoardState::Empty
|
||||||
|
{
|
||||||
|
bottom_idx += COLS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply current player's color to bottom-most empty slot
|
||||||
|
shared.board[bottom_idx as usize].replace(match shared.turn.get() {
|
||||||
|
Turn::CyanPlayer => BoardState::Cyan,
|
||||||
|
Turn::MagentaPlayer => BoardState::Magenta,
|
||||||
|
});
|
||||||
|
let current_board_state = shared.board[bottom_idx as usize].get();
|
||||||
|
|
||||||
|
// swap turn
|
||||||
|
shared.turn.replace(match shared.turn.get() {
|
||||||
|
Turn::CyanPlayer => Turn::MagentaPlayer,
|
||||||
|
Turn::MagentaPlayer => Turn::CyanPlayer,
|
||||||
});
|
});
|
||||||
|
|
||||||
// DEBUG
|
// get handle to slot
|
||||||
log::info!("{} is {:?}", idx, shared.board[idx as usize].get());
|
if let Some(slot) =
|
||||||
|
shared.slot_refs[bottom_idx as usize].cast::<web_sys::HtmlButtonElement>()
|
||||||
// DEBUG
|
|
||||||
//log::info!("{}", &output_str);
|
|
||||||
|
|
||||||
if let Some(info_text) = shared.info_text_ref.cast::<web_sys::HtmlDivElement>()
|
|
||||||
{
|
{
|
||||||
// create the new text to be appended in the output
|
// set slot info
|
||||||
let window = web_sys::window().expect("no window exists");
|
slot.set_class_name(&format!(
|
||||||
let document = window.document().expect("window should have a document");
|
"slot {} r{} c{}",
|
||||||
let p = document
|
current_board_state,
|
||||||
.create_element("p")
|
bottom_idx / COLS,
|
||||||
.expect("document should be able to create <p>");
|
bottom_idx % COLS
|
||||||
p.set_text_content(Some(&output_str));
|
));
|
||||||
|
|
||||||
// check if scrolled to top
|
|
||||||
|
|
||||||
// DEBUG
|
|
||||||
//log::info!(
|
|
||||||
// "pre: scroll top is {}, scroll height is {}",
|
|
||||||
// info_text.scroll_top(),
|
|
||||||
// info_text.scroll_height()
|
|
||||||
//);
|
|
||||||
let at_top: bool =
|
|
||||||
info_text.scroll_top() <= INFO_TEXT_HEIGHT - info_text.scroll_height();
|
|
||||||
|
|
||||||
// append text to output
|
|
||||||
info_text
|
|
||||||
.append_with_node_1(&p)
|
|
||||||
.expect("should be able to append to info_text");
|
|
||||||
while info_text.child_element_count() > INFO_TEXT_MAX_ITEMS {
|
|
||||||
info_text
|
|
||||||
.remove_child(&info_text.first_child().unwrap())
|
|
||||||
.expect("should be able to limit items in info_text");
|
|
||||||
}
|
|
||||||
|
|
||||||
// scroll to top only if at top
|
|
||||||
|
|
||||||
// DEBUG
|
|
||||||
//log::info!("at_top is {}", if at_top { "true" } else { "false" });
|
|
||||||
|
|
||||||
if at_top {
|
|
||||||
info_text.set_scroll_top(INFO_TEXT_HEIGHT - info_text.scroll_height());
|
|
||||||
}
|
|
||||||
|
|
||||||
// DEBUG
|
|
||||||
//log::info!(
|
|
||||||
// "post: scroll top is {}, scroll height is {}",
|
|
||||||
// info_text.scroll_top(),
|
|
||||||
// info_text.scroll_height()
|
|
||||||
//);
|
|
||||||
} else {
|
|
||||||
log::warn!("Failed to get \"info_text\"");
|
|
||||||
}
|
}
|
||||||
} // let Ok(idx) = split_str[1].parse::<u8>()
|
|
||||||
} // split_str[0] == "pressed"
|
placed = true;
|
||||||
} // split_str.len() == 2
|
}
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
//log::info!("{} is {:?}", idx, shared.board[idx as usize].get());
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
//log::info!("{}", &output_str);
|
||||||
|
|
||||||
|
// info text below the grid
|
||||||
|
if let Some(info_text) = shared.info_text_ref[0].cast::<web_sys::HtmlDivElement>() {
|
||||||
|
let height = info_text.client_height();
|
||||||
|
|
||||||
|
// create the new text to be appended in the output
|
||||||
|
let p = document
|
||||||
|
.create_element("p")
|
||||||
|
.expect("document should be able to create <p>");
|
||||||
|
let output_str = match placed {
|
||||||
|
true => format!("{} placed into slot {}", current_player, bottom_idx),
|
||||||
|
false => "Invalid place to insert".into(),
|
||||||
|
};
|
||||||
|
p.set_text_content(Some(&output_str));
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
//log::info!(
|
||||||
|
// "pre: scroll top is {}, scroll height is {}",
|
||||||
|
// info_text.scroll_top(),
|
||||||
|
// info_text.scroll_height()
|
||||||
|
//);
|
||||||
|
|
||||||
|
// check if scrolled to top
|
||||||
|
let at_top: bool = info_text.scroll_top() <= height - info_text.scroll_height();
|
||||||
|
|
||||||
|
// append text to output
|
||||||
|
info_text
|
||||||
|
.append_with_node_1(&p)
|
||||||
|
.expect("should be able to append to info_text");
|
||||||
|
while info_text.child_element_count() > INFO_TEXT_MAX_ITEMS {
|
||||||
|
info_text
|
||||||
|
.remove_child(&info_text.first_child().unwrap())
|
||||||
|
.expect("should be able to limit items in info_text");
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
//log::info!("at_top is {}", if at_top { "true" } else { "false" });
|
||||||
|
|
||||||
|
// scroll to top only if at top
|
||||||
|
if at_top {
|
||||||
|
info_text.set_scroll_top(height - info_text.scroll_height());
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
//log::info!(
|
||||||
|
// "post: scroll top is {}, scroll height is {}",
|
||||||
|
// info_text.scroll_top(),
|
||||||
|
// info_text.scroll_height()
|
||||||
|
//);
|
||||||
|
} else {
|
||||||
|
log::warn!("Failed to get bottom \"info_text\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
// info text right of the grid
|
||||||
|
if let Some(info_text) = shared.info_text_ref[1].cast::<web_sys::HtmlDivElement>() {
|
||||||
|
let height = info_text.client_height();
|
||||||
|
|
||||||
|
// create the new text to be appended in the output
|
||||||
|
let p = document
|
||||||
|
.create_element("p")
|
||||||
|
.expect("document should be able to create <p>");
|
||||||
|
p.set_text_content(Some(&format!("It is {}'s turn", shared.turn.get())));
|
||||||
|
|
||||||
|
// check if scrolled to top
|
||||||
|
let at_top: bool = info_text.scroll_top() <= height - info_text.scroll_height();
|
||||||
|
|
||||||
|
// append text to output
|
||||||
|
info_text
|
||||||
|
.append_with_node_1(&p)
|
||||||
|
.expect("should be able to append to info_text");
|
||||||
|
while info_text.child_element_count() > INFO_TEXT_MAX_ITEMS {
|
||||||
|
info_text
|
||||||
|
.remove_child(&info_text.first_child().unwrap())
|
||||||
|
.expect("should be able to limit items in info_text");
|
||||||
|
}
|
||||||
|
|
||||||
|
// scroll to top only if at top
|
||||||
|
if at_top {
|
||||||
|
info_text.set_scroll_top(height - info_text.scroll_height());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log::warn!("Failed to get side \"info_text\"");
|
||||||
|
}
|
||||||
|
} // let Ok(idx) = split_str[1].parse::<u8>()
|
||||||
|
} // split_str.len() == 2 && split_str[0] == "pressed"
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -218,9 +287,14 @@ impl Component for Wrapper {
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct InfoText {}
|
pub struct InfoText {}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Properties)]
|
||||||
|
pub struct InfoTextProperties {
|
||||||
|
id: usize,
|
||||||
|
}
|
||||||
|
|
||||||
impl Component for InfoText {
|
impl Component for InfoText {
|
||||||
type Message = ();
|
type Message = ();
|
||||||
type Properties = ();
|
type Properties = InfoTextProperties;
|
||||||
|
|
||||||
fn create(_ctx: &Context<Self>) -> Self {
|
fn create(_ctx: &Context<Self>) -> Self {
|
||||||
Self {}
|
Self {}
|
||||||
|
@ -232,8 +306,7 @@ impl Component for InfoText {
|
||||||
.context::<SharedState>(Callback::noop())
|
.context::<SharedState>(Callback::noop())
|
||||||
.expect("state to be set");
|
.expect("state to be set");
|
||||||
html! {
|
html! {
|
||||||
<div ref={shared.info_text_ref} class="info_text">
|
<div ref={shared.info_text_ref[ctx.props().id].clone()} class={format!("info_text{}", ctx.props().id)}>
|
||||||
{"Hello"}
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue