feat: transformation buttons

This commit is contained in:
2025-04-01 21:00:31 +02:00
parent c15db2847d
commit bd8b0fecf1
2 changed files with 63 additions and 22 deletions

View File

@@ -23,21 +23,37 @@ impl Pattern {
}
#[must_use]
pub fn apply_transformation(&self, transformation: Transformation) -> Self {
let mut holds = self.clone();
if transformation.shift_right > 0 {
holds = holds.shift_right(transformation.shift_right);
pub fn shift_left(&self, shift: u64) -> Option<Self> {
// Out of bounds check
if let Some(min_col) = self.pattern.iter().map(|(hold_position, _)| hold_position.col).min() {
if shift > min_col {
return None;
}
}
if transformation.mirror {
holds = holds.mirror();
}
holds
let pattern: BTreeMap<HoldPosition, HoldRole> = self
.pattern
.iter()
.map(|(hold_position, hold_role)| {
let mut hold_position = hold_position.clone();
hold_position.col -= shift;
(hold_position, *hold_role)
})
.collect();
Some(Self { pattern })
}
#[must_use]
pub fn shift_right(&self, shift: u64) -> Self {
let mut pattern = self.clone();
pattern.pattern = pattern
pub fn shift_right(&self, wall_dimensions: WallDimensions, shift: u64) -> Option<Self> {
// Out of bounds check
if let Some(max_col) = self.pattern.iter().map(|(hold_position, _)| hold_position.col).max() {
if max_col + shift >= wall_dimensions.cols {
return None;
}
}
let pattern: BTreeMap<HoldPosition, HoldRole> = self
.pattern
.iter()
.map(|(hold_position, hold_role)| {
@@ -46,7 +62,8 @@ impl Pattern {
(hold_position, *hold_role)
})
.collect();
pattern
Some(Self { pattern })
}
#[must_use]

View File

@@ -187,7 +187,6 @@ fn View() -> impl IntoView {
<Separator />
<div class="flex flex-row justify-around">
<Transformations />
<NextProblemButton />
</div>
</Section>
@@ -196,7 +195,8 @@ fn View() -> impl IntoView {
<Section title="Current problem">
{move || ctx.problem.get().map(|problem| view! { <ProblemInfo problem /> })}
<Separator /> <AttemptRadioGroup /> <Separator /> <History />
<Separator /> <Transformations /> <Separator /><AttemptRadioGroup />
<Separator /> <History />
</Section>
</div>
@@ -214,25 +214,49 @@ fn Transformations() -> impl IntoView {
let ctx = use_context::<Context>().unwrap();
let on_left = Callback::new(move |()| {
tracing::debug!("left");
let left = Signal::derive(move || {
let mut problem = ctx.problem.get()?;
let new_pattern = problem.pattern.shift_left(1)?;
problem.pattern = new_pattern;
Some(problem)
});
let on_mirror = Callback::new(move |()| {
let right = Signal::derive(move || {
let mut problem = ctx.problem.get()?;
let wall_dimensions = ctx.wall.read().wall_dimensions;
let new_pattern = problem.pattern.shift_right(wall_dimensions, 1)?;
problem.pattern = new_pattern;
Some(problem)
});
let on_click_left = Callback::new(move |()| {
tracing::debug!("left");
if let Some(problem) = left.get() {
ctx.cb_set_problem.run(problem);
}
});
let on_click_mirror = Callback::new(move |()| {
tracing::debug!("mirror");
if let Some(mut problem) = ctx.problem.get() {
problem.pattern = problem.pattern.mirror();
ctx.cb_set_problem.run(problem);
}
});
let on_right = Callback::new(move |()| {
let on_click_right = Callback::new(move |()| {
tracing::debug!("right");
if let Some(problem) = right.get() {
ctx.cb_set_problem.run(problem);
}
});
let left_disabled = Signal::derive(move || left.read().is_none());
let right_disabled = Signal::derive(move || right.read().is_none());
view! {
<div class="flex flex-row gap-2 justify-center">
<Button icon=Icon::ChevronLeft disabled=true on_click=on_left />
<Button icon=Icon::CodeBracketSquare on_click=on_mirror />
<Button icon=Icon::ChevronRight on_click=on_right />
<Button icon=Icon::ChevronLeft disabled=left_disabled on_click=on_click_left />
<Button icon=Icon::CodeBracketSquare on_click=on_click_mirror />
<Button icon=Icon::ChevronRight disabled=right_disabled on_click=on_click_right />
</div>
}
}
@@ -261,7 +285,7 @@ fn NextProblemButton() -> impl IntoView {
let ctx = use_context::<Context>().unwrap();
let on_click = Callback::new(move |_| ctx.cb_next_problem.run(()));
view! { <Button icon=Icon::ArrowPath text="Next problem" on_click color=Gradient::PurpleBlue /> }
view! { <Button icon=Icon::ArrowPath text="Randomize" on_click color=Gradient::PurpleBlue /> }
}
#[component]