feat: transformation buttons
This commit is contained in:
@@ -23,21 +23,37 @@ impl Pattern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn apply_transformation(&self, transformation: Transformation) -> Self {
|
pub fn shift_left(&self, shift: u64) -> Option<Self> {
|
||||||
let mut holds = self.clone();
|
// Out of bounds check
|
||||||
if transformation.shift_right > 0 {
|
if let Some(min_col) = self.pattern.iter().map(|(hold_position, _)| hold_position.col).min() {
|
||||||
holds = holds.shift_right(transformation.shift_right);
|
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]
|
#[must_use]
|
||||||
pub fn shift_right(&self, shift: u64) -> Self {
|
pub fn shift_right(&self, wall_dimensions: WallDimensions, shift: u64) -> Option<Self> {
|
||||||
let mut pattern = self.clone();
|
// Out of bounds check
|
||||||
pattern.pattern = pattern
|
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
|
.pattern
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(hold_position, hold_role)| {
|
.map(|(hold_position, hold_role)| {
|
||||||
@@ -46,7 +62,8 @@ impl Pattern {
|
|||||||
(hold_position, *hold_role)
|
(hold_position, *hold_role)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
pattern
|
|
||||||
|
Some(Self { pattern })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
|||||||
@@ -187,7 +187,6 @@ fn View() -> impl IntoView {
|
|||||||
<Separator />
|
<Separator />
|
||||||
|
|
||||||
<div class="flex flex-row justify-around">
|
<div class="flex flex-row justify-around">
|
||||||
<Transformations />
|
|
||||||
<NextProblemButton />
|
<NextProblemButton />
|
||||||
</div>
|
</div>
|
||||||
</Section>
|
</Section>
|
||||||
@@ -196,7 +195,8 @@ fn View() -> impl IntoView {
|
|||||||
|
|
||||||
<Section title="Current problem">
|
<Section title="Current problem">
|
||||||
{move || ctx.problem.get().map(|problem| view! { <ProblemInfo problem /> })}
|
{move || ctx.problem.get().map(|problem| view! { <ProblemInfo problem /> })}
|
||||||
<Separator /> <AttemptRadioGroup /> <Separator /> <History />
|
<Separator /> <Transformations /> <Separator /><AttemptRadioGroup />
|
||||||
|
<Separator /> <History />
|
||||||
</Section>
|
</Section>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -214,25 +214,49 @@ fn Transformations() -> impl IntoView {
|
|||||||
|
|
||||||
let ctx = use_context::<Context>().unwrap();
|
let ctx = use_context::<Context>().unwrap();
|
||||||
|
|
||||||
let on_left = Callback::new(move |()| {
|
let left = Signal::derive(move || {
|
||||||
tracing::debug!("left");
|
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");
|
tracing::debug!("mirror");
|
||||||
if let Some(mut problem) = ctx.problem.get() {
|
if let Some(mut problem) = ctx.problem.get() {
|
||||||
problem.pattern = problem.pattern.mirror();
|
problem.pattern = problem.pattern.mirror();
|
||||||
ctx.cb_set_problem.run(problem);
|
ctx.cb_set_problem.run(problem);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let on_right = Callback::new(move |()| {
|
let on_click_right = Callback::new(move |()| {
|
||||||
tracing::debug!("right");
|
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! {
|
view! {
|
||||||
<div class="flex flex-row gap-2 justify-center">
|
<div class="flex flex-row gap-2 justify-center">
|
||||||
<Button icon=Icon::ChevronLeft disabled=true on_click=on_left />
|
<Button icon=Icon::ChevronLeft disabled=left_disabled on_click=on_click_left />
|
||||||
<Button icon=Icon::CodeBracketSquare on_click=on_mirror />
|
<Button icon=Icon::CodeBracketSquare on_click=on_click_mirror />
|
||||||
<Button icon=Icon::ChevronRight on_click=on_right />
|
<Button icon=Icon::ChevronRight disabled=right_disabled on_click=on_click_right />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -261,7 +285,7 @@ fn NextProblemButton() -> impl IntoView {
|
|||||||
let ctx = use_context::<Context>().unwrap();
|
let ctx = use_context::<Context>().unwrap();
|
||||||
|
|
||||||
let on_click = Callback::new(move |_| ctx.cb_next_problem.run(()));
|
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]
|
#[component]
|
||||||
|
|||||||
Reference in New Issue
Block a user