Skip to content

Commit 899b034

Browse files
committed
feat(record): support selecting item by clicking empty area to right
1 parent 37369bc commit 899b034

File tree

3 files changed

+122
-3
lines changed

3 files changed

+122
-3
lines changed

scm-record/src/render.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,32 @@ impl<'a, ComponentId: Clone + Debug + Eq + Hash> Viewport<'a, ComponentId> {
409409
widget.render(rect, self.buf);
410410
}
411411

412+
pub fn fill_rest_of_line(&mut self, x: isize, y: isize) {
413+
let line_width = self.rect.width.unwrap_isize() - x;
414+
let line_width: usize = match line_width.try_into() {
415+
Ok(0) | Err(_) => return,
416+
Ok(line_width) => line_width,
417+
};
418+
419+
let line_rect = Rect {
420+
x,
421+
y,
422+
width: line_width,
423+
height: 1,
424+
};
425+
self.current_trace_mut().merge_rect(line_rect);
426+
let draw_rect = self.rect.intersect(line_rect);
427+
if !draw_rect.is_empty() {
428+
let buf_rect = self.translate_rect(draw_rect);
429+
self.buf.set_span(
430+
buf_rect.x,
431+
buf_rect.y,
432+
&Span::raw(" ".repeat(line_width)),
433+
buf_rect.width,
434+
);
435+
}
436+
}
437+
412438
/// Convert the virtual `Rect` being displayed on the viewport, potentially
413439
/// including an area off-screen, into a real terminal `tui::layout::Rect`
414440
/// indicating the actual positions of the characters to be printed

scm-record/src/ui.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,9 +1028,18 @@ impl<'a> Recorder<'a> {
10281028
let y = row.unwrap_isize() + self.scroll_offset_y;
10291029
drawn_rects
10301030
.iter()
1031-
.filter(|(_id, rect)| rect.contains_point(x, y))
1032-
.min_by(|(_, lhs), (_, rhs)| lhs.size().area().cmp(&rhs.size().area()))
1033-
.map(|(id, _rect)| id.clone())
1031+
.filter(|(id, rect)| {
1032+
rect.contains_point(x, y)
1033+
&& match id {
1034+
ComponentId::App => false,
1035+
ComponentId::SelectableItem(_)
1036+
| ComponentId::TristateBox(_)
1037+
| ComponentId::QuitDialog
1038+
| ComponentId::QuitDialogButton(_) => true,
1039+
}
1040+
})
1041+
.min_by_key(|(id, rect)| (rect.size().area(), (rect.y, rect.x), *id))
1042+
.map(|(id, _rect)| *id)
10341043
.unwrap_or(ComponentId::App)
10351044
}
10361045

@@ -1463,6 +1472,7 @@ impl Component for FileView<'_> {
14631472
section_views,
14641473
is_header_selected,
14651474
} = self;
1475+
viewport.fill_rest_of_line(x, y);
14661476

14671477
let tristate_box_rect = viewport.draw_component(x, y, tristate_box);
14681478
viewport.draw_span(
@@ -1542,6 +1552,7 @@ impl Component for SectionView<'_> {
15421552
section,
15431553
line_start_num,
15441554
} = self;
1555+
viewport.fill_rest_of_line(x, y);
15451556

15461557
let SectionKey {
15471558
file_idx,
@@ -1811,6 +1822,7 @@ impl Component for SectionLineView<'_> {
18111822

18121823
fn draw(&self, viewport: &mut Viewport<Self::Id>, x: isize, y: isize) {
18131824
let Self { line_key: _, inner } = self;
1825+
viewport.fill_rest_of_line(x, y);
18141826
match inner {
18151827
SectionLineViewInner::Unchanged { line, line_num } => {
18161828
let style = Style::default().add_modifier(Modifier::DIM);

scm-record/tests/test_scm_record.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,3 +896,84 @@ fn test_mouse_click_checkbox() -> eyre::Result<()> {
896896

897897
Ok(())
898898
}
899+
900+
#[test]
901+
fn test_mouse_click_wide_line() -> eyre::Result<()> {
902+
let state = RecordState {
903+
files: vec![File {
904+
path: Cow::Borrowed(Path::new("foo")),
905+
file_mode: None,
906+
sections: vec![
907+
Section::FileMode {
908+
is_toggled: false,
909+
before: FileMode::absent(),
910+
after: FileMode(0o100644),
911+
},
912+
Section::Changed {
913+
lines: vec![SectionChangedLine {
914+
is_toggled: false,
915+
change_type: ChangeType::Removed,
916+
line: Cow::Borrowed("foo\n"),
917+
}],
918+
},
919+
],
920+
}],
921+
};
922+
923+
let initial = TestingScreenshot::default();
924+
let click_line = TestingScreenshot::default();
925+
let click_line_section = TestingScreenshot::default();
926+
let click_file_mode_section = TestingScreenshot::default();
927+
let click_file = TestingScreenshot::default();
928+
let event_source = EventSource::testing(
929+
80,
930+
4,
931+
[
932+
initial.event(),
933+
Event::Click { row: 3, column: 50 },
934+
click_line.event(),
935+
Event::Click { row: 2, column: 50 },
936+
click_line_section.event(),
937+
Event::Click { row: 1, column: 50 },
938+
click_file_mode_section.event(),
939+
Event::Click { row: 0, column: 50 },
940+
click_file.event(),
941+
Event::QuitAccept,
942+
],
943+
);
944+
let recorder = Recorder::new(state, event_source);
945+
recorder.run()?;
946+
947+
insta::assert_display_snapshot!(initial, @r###"
948+
"( ) foo "
949+
" [ ] File mode changed from 0 to 100644 "
950+
" [ ] Section 2/2 "
951+
" [ ] - foo "
952+
"###);
953+
insta::assert_display_snapshot!(click_line, @r###"
954+
"[ ] foo "
955+
" [ ] File mode changed from 0 to 100644 "
956+
" [ ] Section 2/2 "
957+
" ( ) - foo "
958+
"###);
959+
insta::assert_display_snapshot!(click_line_section, @r###"
960+
"[ ] foo "
961+
" [ ] File mode changed from 0 to 100644 "
962+
" ( ) Section 2/2 "
963+
" [ ] - foo "
964+
"###);
965+
insta::assert_display_snapshot!(click_file_mode_section, @r###"
966+
"[ ] foo "
967+
" ( ) File mode changed from 0 to 100644 "
968+
" [ ] Section 2/2 "
969+
" [ ] - foo "
970+
"###);
971+
insta::assert_display_snapshot!(click_file, @r###"
972+
"( ) foo "
973+
" [ ] File mode changed from 0 to 100644 "
974+
" [ ] Section 2/2 "
975+
" [ ] - foo "
976+
"###);
977+
978+
Ok(())
979+
}

0 commit comments

Comments
 (0)