Skip to content

Commit 37369bc

Browse files
committed
feat(record): support toggling checkboxes by clicking
1 parent 8a99f79 commit 37369bc

File tree

2 files changed

+86
-14
lines changed

2 files changed

+86
-14
lines changed

scm-record/src/ui.rs

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ impl<'a> Recorder<'a> {
569569
file_key,
570570
tristate_box: TristateBox {
571571
use_unicode: self.use_unicode,
572-
id: ComponentId::TristateBox,
572+
id: ComponentId::TristateBox(SelectionKey::File(file_key)),
573573
tristate: file_tristate,
574574
is_focused,
575575
},
@@ -600,7 +600,9 @@ impl<'a> Recorder<'a> {
600600
section_key,
601601
tristate_box: TristateBox {
602602
use_unicode: self.use_unicode,
603-
id: ComponentId::TristateBox,
603+
id: ComponentId::TristateBox(SelectionKey::Section(
604+
section_key,
605+
)),
604606
tristate: section_tristate,
605607
is_focused: match self.selection_key {
606608
SelectionKey::None
@@ -1036,9 +1038,12 @@ impl<'a> Recorder<'a> {
10361038
match component_id {
10371039
ComponentId::App | ComponentId::QuitDialog => StateUpdate::None,
10381040
ComponentId::SelectableItem(selection_key) => StateUpdate::SelectItem(selection_key),
1039-
ComponentId::TristateBox => {
1040-
// TODO: implement toggling the checkbox
1041-
StateUpdate::None
1041+
ComponentId::TristateBox(selection_key) => {
1042+
if self.selection_key == selection_key {
1043+
StateUpdate::ToggleItem(selection_key)
1044+
} else {
1045+
StateUpdate::SelectItem(selection_key)
1046+
}
10421047
}
10431048
ComponentId::QuitDialogButton(QuitDialogButtonId::GoBack) => {
10441049
StateUpdate::SetQuitDialog(None)
@@ -1291,7 +1296,7 @@ impl<'a> Recorder<'a> {
12911296
enum ComponentId {
12921297
App,
12931298
SelectableItem(SelectionKey),
1294-
TristateBox,
1299+
TristateBox(SelectionKey),
12951300
QuitDialog,
12961301
QuitDialogButton(QuitDialogButtonId),
12971302
}
@@ -1673,18 +1678,19 @@ impl Component for SectionView<'_> {
16731678
}
16741679
Some(SectionSelection::SectionHeader) | None => false,
16751680
};
1681+
let line_key = LineKey {
1682+
file_idx,
1683+
section_idx,
1684+
line_idx,
1685+
};
16761686
let tristate_box = TristateBox {
16771687
use_unicode: *use_unicode,
1678-
id: ComponentId::TristateBox,
1688+
id: ComponentId::TristateBox(SelectionKey::Line(line_key)),
16791689
tristate: Tristate::from(*is_toggled),
16801690
is_focused,
16811691
};
16821692
let line_view = SectionLineView {
1683-
line_key: LineKey {
1684-
file_idx,
1685-
section_idx,
1686-
line_idx,
1687-
},
1693+
line_key,
16881694
inner: SectionLineViewInner::Changed {
16891695
tristate_box,
16901696
change_type: *change_type,
@@ -1708,9 +1714,14 @@ impl Component for SectionView<'_> {
17081714
Some(SectionSelection::SectionHeader) => true,
17091715
Some(SectionSelection::ChangedLine(_)) | None => false,
17101716
};
1717+
let section_key = SectionKey {
1718+
file_idx,
1719+
section_idx,
1720+
};
1721+
let selection_key = SelectionKey::Section(section_key);
17111722
let tristate_box = TristateBox {
17121723
use_unicode: *use_unicode,
1713-
id: ComponentId::TristateBox,
1724+
id: ComponentId::TristateBox(selection_key),
17141725
tristate: Tristate::from(*is_toggled),
17151726
is_focused,
17161727
};
@@ -1732,9 +1743,13 @@ impl Component for SectionView<'_> {
17321743
Some(SectionSelection::SectionHeader) => true,
17331744
Some(SectionSelection::ChangedLine(_)) | None => false,
17341745
};
1746+
let section_key = SectionKey {
1747+
file_idx,
1748+
section_idx,
1749+
};
17351750
let tristate_box = TristateBox {
17361751
use_unicode: *use_unicode,
1737-
id: ComponentId::TristateBox,
1752+
id: ComponentId::TristateBox(SelectionKey::Section(section_key)),
17381753
tristate: Tristate::from(*is_toggled),
17391754
is_focused,
17401755
};

scm-record/tests/test_scm_record.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,3 +839,60 @@ fn test_mouse_support() -> eyre::Result<()> {
839839

840840
Ok(())
841841
}
842+
#[test]
843+
fn test_mouse_click_checkbox() -> eyre::Result<()> {
844+
let state = RecordState {
845+
files: vec![
846+
File {
847+
path: Cow::Borrowed(Path::new("foo")),
848+
file_mode: None,
849+
sections: vec![],
850+
},
851+
File {
852+
path: Cow::Borrowed(Path::new("bar")),
853+
file_mode: None,
854+
sections: vec![Section::FileMode {
855+
is_toggled: false,
856+
before: FileMode::absent(),
857+
after: FileMode(0o100644),
858+
}],
859+
},
860+
],
861+
};
862+
863+
let initial = TestingScreenshot::default();
864+
let click_unselected_checkbox = TestingScreenshot::default();
865+
let click_selected_checkbox = TestingScreenshot::default();
866+
let event_source = EventSource::testing(
867+
80,
868+
3,
869+
[
870+
initial.event(),
871+
Event::Click { row: 1, column: 1 },
872+
click_unselected_checkbox.event(),
873+
Event::Click { row: 1, column: 1 },
874+
click_selected_checkbox.event(),
875+
Event::QuitAccept,
876+
],
877+
);
878+
let recorder = Recorder::new(state, event_source);
879+
recorder.run()?;
880+
881+
insta::assert_display_snapshot!(initial, @r###"
882+
"( ) foo "
883+
"[ ] bar "
884+
" [ ] File mode changed from 0 to 100644 "
885+
"###);
886+
insta::assert_display_snapshot!(click_unselected_checkbox, @r###"
887+
"[ ] foo "
888+
"( ) bar "
889+
" [ ] File mode changed from 0 to 100644 "
890+
"###);
891+
insta::assert_display_snapshot!(click_selected_checkbox, @r###"
892+
"[ ] foo "
893+
"(×) bar "
894+
" [×] File mode changed from 0 to 100644 "
895+
"###);
896+
897+
Ok(())
898+
}

0 commit comments

Comments
 (0)