Skip to content

Commit aa5e608

Browse files
committed
Scroll to column: we can go to all matching columns
1 parent 98d2e87 commit aa5e608

File tree

2 files changed

+69
-20
lines changed

2 files changed

+69
-20
lines changed

src/array_table.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ pub enum ScrollToRowMode {
8282
}
8383

8484

85-
8685
impl ScrollToRowMode {
8786
pub fn as_str(&self) -> &'static str {
8887
match self {
@@ -114,13 +113,16 @@ pub struct ArrayTable {
114113
seed2: usize, // seed for Id
115114
pub matching_rows: Vec<usize>,
116115
pub matching_row_selected: usize,
116+
pub matching_columns: Vec<usize>,
117+
pub matching_column_selected: usize,
117118
pub scroll_to_column: String,
118119
pub scroll_to_row: String,
119120
pub scroll_to_row_mode: ScrollToRowMode,
120121

121122
// Handle interaction
122123
pub next_frame_reset_scroll: bool,
123124
pub changed_scroll_to_column_value: bool,
125+
pub changed_matching_column_selected: bool,
124126
pub changed_matching_row_selected: bool,
125127
pub changed_scroll_to_row_value: Option<Instant>,
126128

@@ -151,16 +153,23 @@ impl super::View<ArrayResponse> for ArrayTable {
151153
let mut scroll_to_x = None;
152154
if self.changed_scroll_to_column_value {
153155
self.changed_scroll_to_column_value = false;
154-
let mut index = self.column_selected.iter().position(|c| {
155-
c.name.to_lowercase().eq(&concat_string!("/", &self.scroll_to_column.to_lowercase()))
156-
});
157-
if index.is_none() {
158-
index = self.column_selected.iter().position(|c| {
159-
c.name.to_lowercase().contains(&self.scroll_to_column.to_lowercase())
160-
});
156+
self.changed_matching_column_selected = true;
157+
self.matching_columns.clear();
158+
self.matching_column_selected = 0;
159+
if !self.scroll_to_column.is_empty() {
160+
for (index, column) in self.column_selected.iter().enumerate() {
161+
if column.name.to_lowercase().eq(&concat_string!("/", &self.scroll_to_column.to_lowercase()))
162+
|| column.name.to_lowercase().contains(&self.scroll_to_column.to_lowercase()) {
163+
self.matching_columns.push(index);
164+
}
165+
}
161166
}
162-
if let Some(index) = index {
163-
if let Some(offset) = self.columns_offset.get(index) {
167+
}
168+
169+
if self.changed_matching_column_selected {
170+
self.changed_matching_column_selected = false;
171+
if !self.matching_columns.is_empty() {
172+
if let Some(offset) = self.columns_offset.get(self.matching_columns[self.matching_column_selected]) {
164173
scroll_to_x = Some(*offset);
165174
}
166175
}
@@ -243,6 +252,8 @@ impl ArrayTable {
243252
windows: vec![],
244253
matching_rows: vec![],
245254
matching_row_selected: 0,
255+
matching_columns: vec![],
256+
matching_column_selected: 0,
246257
scroll_to_column: "".to_string(),
247258
changed_scroll_to_column_value: false,
248259
last_parsed_max_depth,
@@ -251,6 +262,7 @@ impl ArrayTable {
251262
scroll_to_row: "".to_string(),
252263
changed_scroll_to_row_value: None,
253264
changed_matching_row_selected: false,
265+
changed_matching_column_selected: false,
254266
editing_index: RefCell::new(None),
255267
editing_value: RefCell::new(String::new()),
256268
is_sub_table: false,
@@ -343,7 +355,6 @@ impl ArrayTable {
343355
}
344356

345357
pub fn row_height(style: &Arc<Style>, spacing: &Spacing) -> f32 {
346-
347358
egui::TextStyle::Body
348359
.resolve(style)
349360
.size
@@ -452,7 +463,7 @@ impl ArrayTable {
452463
if Self::is_filterable(column) {
453464
let values = ui.memory_mut(|mem| {
454465
let cache = mem.caches.cache::<ColumnFilterCache>();
455-
466+
456467
cache.get((column, &self.nodes, &self.parent_pointer))
457468
});
458469
if !values.is_empty() {

src/main.rs

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ impl MyApp {
237237
}
238238
}
239239

240-
fn goto_next_occurrence(table: &mut ArrayTable) -> bool {
240+
fn goto_next_matching_row_occurrence(table: &mut ArrayTable) -> bool {
241241
if table.matching_rows.len() == 0 {
242242
return false;
243243
}
@@ -249,6 +249,19 @@ impl MyApp {
249249
table.changed_matching_row_selected = true;
250250
true
251251
}
252+
253+
fn goto_next_matching_column_occurrence(table: &mut ArrayTable) -> bool {
254+
if table.matching_columns.len() == 0 {
255+
return false;
256+
}
257+
if table.matching_column_selected == table.matching_columns.len() - 1 {
258+
table.matching_column_selected = 0;
259+
} else {
260+
table.matching_column_selected += 1;
261+
}
262+
table.changed_matching_column_selected = true;
263+
true
264+
}
252265
}
253266

254267
fn set_open(open: &mut BTreeSet<String>, key: &'static str, is_open: bool) {
@@ -308,14 +321,34 @@ impl eframe::App for MyApp {
308321
}
309322
if let Some(ref mut table) = self.table {
310323
ui.separator();
311-
let slider_response = ui.add(
324+
let change_depth_slider_response = ui.add(
312325
egui::Slider::new(&mut self.depth, self.min_depth..=self.max_depth).text("Depth"),
313326
);
314327
ui.add(Separator::default().vertical());
315328
let scroll_to_column_response = ui.allocate_ui(Vec2::new(180.0, ui.spacing().interact_size.y), |ui| {
316-
ui.add(Label::new("Scroll to column: ").wrap(false));
317-
let text_edit = TextEdit::singleline(&mut table.scroll_to_column).hint_text("named");
318-
ui.add(text_edit)
329+
ui.horizontal(|ui| {
330+
ui.add(Label::new("Scroll to column: ").wrap(false));
331+
let text_edit = TextEdit::singleline(&mut table.scroll_to_column).hint_text("named");
332+
let response = ui.add(text_edit);
333+
if !table.matching_columns.is_empty() {
334+
let response_prev = icon::button(ui, CHEVRON_UP, Some("Previous occurrence"), None);
335+
let response_next = icon::button(ui, CHEVRON_DOWN, Some("Next occurrence"), None);
336+
ui.label(RichText::new(format!("{}/{}", table.matching_column_selected + 1, table.matching_columns.len())));
337+
338+
if response_prev.clicked() {
339+
if table.matching_column_selected == 0 {
340+
table.matching_column_selected = table.matching_columns.len() - 1;
341+
} else {
342+
table.matching_column_selected -= 1;
343+
}
344+
table.changed_matching_column_selected = true;
345+
}
346+
if response_next.clicked() {
347+
Self::goto_next_matching_column_occurrence(table);
348+
}
349+
}
350+
response
351+
}).inner
319352
}).inner;
320353

321354
ui.add(Separator::default().vertical());
@@ -347,7 +380,7 @@ impl eframe::App for MyApp {
347380
table.changed_matching_row_selected = true;
348381
}
349382
if response_next.clicked() {
350-
Self::goto_next_occurrence(table);
383+
Self::goto_next_matching_row_occurrence(table);
351384
}
352385
}
353386
(scroll_to_row_mode_response, scroll_to_row_response)
@@ -358,21 +391,26 @@ impl eframe::App for MyApp {
358391
// interaction handling
359392
if scroll_to_column_response.changed() {
360393
table.changed_scroll_to_column_value = true;
394+
} else if scroll_to_column_response.lost_focus() && ctx.input(|i| i.key_pressed(Key::Enter)) {
395+
if Self::goto_next_matching_column_occurrence(table) {
396+
scroll_to_column_response.request_focus();
397+
}
361398
}
362399
if scroll_to_row_response.changed() {
363400
table.changed_scroll_to_row_value = Some(Instant::now());
364401
if table.scroll_to_row.is_empty() {
365402
table.reset_search();
366403
}
367404
} else if scroll_to_row_response.lost_focus() && ctx.input(|i| i.key_pressed(Key::Enter)) {
368-
if Self::goto_next_occurrence(table) {
405+
if Self::goto_next_matching_row_occurrence(table) {
369406
scroll_to_row_response.request_focus();
370407
}
371408
}
372409
if scroll_to_row_mode_response.inner.is_some() && scroll_to_row_mode_response.inner.unwrap() {
373410
table.reset_search();
374411
}
375-
if slider_response.changed() {
412+
if change_depth_slider_response.changed() {
413+
table.changed_scroll_to_column_value = true;
376414
if let Some(new_max_depth) = table.update_max_depth(self.depth) {
377415
self.max_depth = new_max_depth as u8;
378416
}

0 commit comments

Comments
 (0)