Skip to content

Commit

Permalink
feat: remove station
Browse files Browse the repository at this point in the history
  • Loading branch information
CalliEve committed Sep 5, 2024
1 parent 5443936 commit 9adcb1b
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 16 deletions.
29 changes: 20 additions & 9 deletions src/components/atoms/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ pub fn Button(
/// If the button is an overlay button.
#[prop(optional)]
overlay: bool,
/// If the button has been selected.
#[prop(optional)]
#[prop(into)]
active: Signal<bool>,
) -> impl IntoView {
let color = if danger {
"red"
Expand All @@ -38,7 +42,7 @@ pub fn Button(
let base_active = base + 200;
let dark = base + 200;
let dark_hover = dark + 100;
let dark_active = dark + 200;
let dark_active = if dark >= 800 { 950 } else { dark + 200 };

let mut class = "inline-block px-4 \
py-1.5 text-center uppercase \
Expand All @@ -60,32 +64,39 @@ pub fn Button(
hover:border-{color}-{base_hover} \
active:text-{color}-{base_active} \
active:border-{color}-{base_active} \
focus:text-{color}-{base_active} \
focus:border-{color}-{base_active} \
dark:text-{color}-{dark} \
dark:border-{color}-{dark} \
dark:hover:text-{color}-{dark_hover} \
dark:hover:border-{color}-{dark_hover} \
dark:active:text-{color}-{dark_active} \
dark:active:border-{color}-{dark_active}"
dark:active:border-{color}-{dark_active} \
dark:focus:text-{color}-{dark_active} \
dark:focus:border-{color}-{dark_active}"
);
} else {
class += &format!(
" text-white bg-{color}-{base} \
hover:bg-{color}-{base_hover} \
active:bg-{color}-{base_active} \
focus:bg-{color}-{base_active} \
dark:bg-{color}-{dark} \
dark:hover:bg-{color}-{dark_hover} \
dark:active:bg-{color}-{dark_active}"
dark:active:bg-{color}-{dark_active} \
dark:focus:bg-{color}-{dark_active}"
);
}

class = class.replace("1000", "950");

view! {
<button
type="button"
class=class
on:click=on_click>
{text}
</button>
<button
type="button"
class=class
focus=active
on:click=on_click>
{text}
</button>
}
}
18 changes: 18 additions & 0 deletions src/components/molecules/canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use wasm_bindgen::{

use crate::{
components::{
state::RemoveType,
CanvasState,
MapState,
},
Expand Down Expand Up @@ -155,6 +156,23 @@ fn on_mouse_down(map_state: &mut MapState, ev: &UiEvent) {
return;
}

// Handle a click while having a remove operation selected
if let Some(remove_type) = map_state.get_selected_remove() {
if let Some(station) = map.station_at_node(mouse_pos) {
match remove_type {
RemoveType::Station => {
map.remove_station(station);
},
RemoveType::Line => {
// Not currently supported
},
}
map_state.set_map(map);
}
map_state.clear_selected_remove();
return;
}

if let Some(mut selected_station) = map
.station_at_node(mouse_pos)
.and_then(|s| map.get_station(s))
Expand Down
36 changes: 32 additions & 4 deletions src/components/organisms/sidebar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::{
ButtonProps,
NumberInput,
},
state::RemoveType,
MapState,
},
models::{
Expand Down Expand Up @@ -38,6 +39,18 @@ pub fn Sidebar() -> impl IntoView {
state.set_selected_line(line)
})
};
let remove_station = move |_| {
map_state.update(|state| {
state.set_selected_remove(RemoveType::Station);
});
};
let remove_station_selected = move || {
map_state
.get()
.get_selected_remove()
== Some(RemoveType::Station)
};

let update_square_size = move |mut n: f64| {
if n < 1.0 {
n = 1.0;
Expand All @@ -60,13 +73,28 @@ pub fn Sidebar() -> impl IntoView {
on_input=update_square_size/>
<ButtonGroup
children={vec![
ButtonProps::builder().text("Add Station").on_click(Box::new(add_station)).build(),
ButtonProps::builder().text("Remove Station").on_click(Box::new(|_| {})).danger(true).build(),
ButtonProps::builder()
.text("Add Station")
.on_click(Box::new(add_station))
.build(),
ButtonProps::builder()
.text("Remove Station")
.on_click(Box::new(remove_station))
.active(Signal::derive(remove_station_selected))
.danger(true)
.build(),
]}/>
<ButtonGroup
children={vec![
ButtonProps::builder().text("Add Line").on_click(Box::new(add_line)).build(),
ButtonProps::builder().text("Remove Line").on_click(Box::new(|_| {})).danger(true).build(),
ButtonProps::builder()
.text("Add Line")
.on_click(Box::new(add_line))
.build(),
ButtonProps::builder()
.text("Remove Line")
.on_click(Box::new(|_| {}))
.danger(true)
.build(),
]}/>
</div>
}
Expand Down
25 changes: 25 additions & 0 deletions src/components/state/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ use crate::{
},
};

/// The type of remove operation that is currently selected.
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum RemoveType {
Station,
Line,
}

/// Holds all the state of the current map and canvas.
#[derive(Clone, Debug)]
pub struct MapState {
Expand All @@ -24,6 +31,8 @@ pub struct MapState {
selected_station: Option<SelectedStation>,
/// The currently selected [`Line`].
selected_line: Option<SelectedLine>,
/// The type of remove operation that is currently selected.
selected_remove: Option<RemoveType>,
/// The state of the canvas.
canvas: CanvasState,
}
Expand All @@ -36,6 +45,7 @@ impl MapState {
map,
selected_station: None,
selected_line: None,
selected_remove: None,
canvas: CanvasState::default(),
}
}
Expand Down Expand Up @@ -71,6 +81,21 @@ impl MapState {
self.selected_station = None;
}

/// A getter method for the selected remove operation.
pub fn get_selected_remove(&self) -> Option<RemoveType> {
self.selected_remove
}

/// A setter method for the selected remove operation.
pub fn set_selected_remove(&mut self, operation: RemoveType) {
self.selected_remove = Some(operation);
}

/// Set the selected remove operation to None.
pub fn clear_selected_remove(&mut self) {
self.selected_remove = None;
}

/// A mutable getter method for the selected line.
pub fn get_mut_selected_line(&mut self) -> Option<&mut SelectedLine> {
self.selected_line
Expand Down
5 changes: 4 additions & 1 deletion src/components/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ mod canvas;
mod map;

pub use canvas::CanvasState;
pub use map::MapState;
pub use map::{
MapState,
RemoveType,
};

use crate::models::Map;

Expand Down
2 changes: 1 addition & 1 deletion src/models/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ impl Edge {
let color_offset = if color_count == 1 {
0.0
} else {
((i as f64) * width + 0.1) - ((color_count as f64 * width + 0.1) / 2.0)
((i as f64) * width) - ((color_count as f64 * width) / 2.0) + (width / 2.0)
};

draw_edge(
Expand Down
44 changes: 44 additions & 0 deletions src/models/line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,50 @@ impl Line {
}
}

/// Remove a station from the line.
pub fn remove_station(&mut self, map: &mut Map, station: StationID) {
if let Some(index) = self
.stations
.iter()
.position(|s| s == &station)
{
self.stations
.remove(index);
}

let mut start = None;
let mut end = None;
let edges = self
.edges
.clone();
for edge_id in edges {
let edge = map
.get_edge(edge_id)
.expect("removing invalid edge id from line");

if edge.get_to() == station {
start = Some(edge.get_from());

self.edges
.retain(|e| *e != edge_id);
map.removed_edge(edge_id, self.get_id());
} else if edge.get_from() == station {
end = Some(edge.get_to());

self.edges
.retain(|e| *e != edge_id);
map.removed_edge(edge_id, self.get_id());
}
}

if start.is_some() && end.is_some() {
self.add_edge(
map.get_edge_id_between(start.unwrap(), end.unwrap()),
map,
);
}
}

/// Add an edge that is being used by this line.
pub fn add_edge(&mut self, edge_id: EdgeID, map: &mut Map) {
let edge = map
Expand Down
16 changes: 16 additions & 0 deletions src/models/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,22 @@ impl Map {
.insert(station.get_id(), station);
}

/// Remove a station from the map.
pub fn remove_station(&mut self, id: StationID) {
let lines: Vec<_> = self
.lines
.values()
.cloned()
.collect();
for mut line in lines.into_iter() {
line.remove_station(self, id);
self.add_line(line);
}

self.stations
.remove(&id);
}

/// Add a line to the map.
pub fn add_line(&mut self, line: Line) {
for edge_id in line.get_edges() {
Expand Down
2 changes: 1 addition & 1 deletion tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = {
.flatMap((s) =>
["400", "500", "600", "700", "800", "900", "950"].map((n) => `${s}-${n}`)
)
.flatMap((s) => ["", "hover:", "active:"].map((m) => `${m}${s}`))
.flatMap((s) => ["", "hover:", "active:", "focus:"].map((m) => `${m}${s}`))
.flatMap((s) => ["", "dark:"].map((m) => `${m}${s}`)),
theme: {
extend: {
Expand Down

0 comments on commit 9adcb1b

Please sign in to comment.