Skip to content

Commit d7eeede

Browse files
committed
feat: add navigation buttons
1 parent 0efd129 commit d7eeede

File tree

2 files changed

+140
-41
lines changed

2 files changed

+140
-41
lines changed

src/app.rs

Lines changed: 123 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::{
66

77
#[cfg(not(target_arch = "wasm32"))]
88
use anyhow::{bail, Context};
9-
use egui::{Align, Modifiers};
9+
use egui::{Align, KeyboardShortcut, Modifiers};
1010
use egui_extras::{Column, TableBuilder};
1111
use log::info;
1212

@@ -24,6 +24,10 @@ pub struct LogViewerApp {
2424
last_filename: Arc<Mutex<Option<PathBuf>>>,
2525
show_last_filename: bool,
2626
track_item_align: Option<Align>,
27+
shortcut_prev: KeyboardShortcut,
28+
shortcut_next: KeyboardShortcut,
29+
shortcut_first: KeyboardShortcut,
30+
shortcut_last: KeyboardShortcut,
2731

2832
#[serde(skip)]
2933
should_scroll: bool,
@@ -40,6 +44,10 @@ impl Default for LogViewerApp {
4044
loading_status: Default::default(),
4145
last_filename: Default::default(),
4246
track_item_align: Default::default(),
47+
shortcut_prev: KeyboardShortcut::new(Modifiers::NONE, egui::Key::ArrowUp),
48+
shortcut_next: KeyboardShortcut::new(Modifiers::NONE, egui::Key::ArrowDown),
49+
shortcut_first: KeyboardShortcut::new(Modifiers::NONE, egui::Key::Home),
50+
shortcut_last: KeyboardShortcut::new(Modifiers::NONE, egui::Key::End),
4351
should_scroll: Default::default(),
4452
show_last_filename: true,
4553
}
@@ -254,29 +262,9 @@ impl LogViewerApp {
254262
fn ui_loading(&mut self, ui: &mut egui::Ui) {
255263
match &self.loading_status {
256264
LoadingStatus::NotInProgress => {
257-
ui.horizontal(|ui| {
258-
if ui.button("📂 Open log file...").clicked() {
259-
let ctx = ui.ctx().clone();
260-
self.loading_status = self.initiate_loading(ctx);
261-
}
262-
#[cfg(not(target_arch = "wasm32"))]
263-
{
264-
if ui.button("Reload").clicked() {
265-
self.loading_status = self.reload_file();
266-
}
267-
if ui.button("Load Most Recent File").clicked() {
268-
self.loading_status = self.load_most_recent_file();
269-
}
270-
}
271-
if ui.button("Clear Data").clicked() {
272-
self.data = None;
273-
}
274-
if self.show_last_filename {
275-
if let Some(filename) = self.last_filename.lock().unwrap().as_ref() {
276-
ui.label(format!("Filename: {}", filename.display()));
277-
}
278-
}
279-
});
265+
self.data_load_ui(ui);
266+
ui.separator();
267+
self.navigation_and_filtering_ui(ui);
280268
}
281269
LoadingStatus::InProgress(promise) => {
282270
if promise.ready().is_some() {
@@ -365,6 +353,34 @@ impl LogViewerApp {
365353
});
366354
}
367355

356+
fn move_selected_prev(&mut self) {
357+
if let Some(data) = self.data.as_mut() {
358+
data.move_selected_to_prev();
359+
self.should_scroll = true;
360+
}
361+
}
362+
363+
fn move_selected_next(&mut self) {
364+
if let Some(data) = self.data.as_mut() {
365+
data.move_selected_to_next();
366+
self.should_scroll = true;
367+
}
368+
}
369+
370+
fn move_selected_first(&mut self) {
371+
if let Some(data) = self.data.as_mut() {
372+
data.move_selected_to_first();
373+
self.should_scroll = true;
374+
}
375+
}
376+
377+
fn move_selected_last(&mut self) {
378+
if let Some(data) = self.data.as_mut() {
379+
data.move_selected_to_last();
380+
self.should_scroll = true;
381+
}
382+
}
383+
368384
fn ui_help(&mut self, ui: &mut egui::Ui) {
369385
ui.collapsing("Help", |ui| {
370386
ui.horizontal(|ui| {
@@ -413,20 +429,93 @@ impl LogViewerApp {
413429
}
414430

415431
fn check_shortcuts(&mut self, ui: &mut egui::Ui) {
416-
if let Some(data) = self.data.as_mut() {
417-
let up_shortcut = egui::KeyboardShortcut::new(Modifiers::NONE, egui::Key::ArrowUp);
418-
let down_shortcut = egui::KeyboardShortcut::new(Modifiers::NONE, egui::Key::ArrowDown);
432+
if ui.input_mut(|i| i.consume_shortcut(&self.shortcut_prev)) {
433+
self.move_selected_prev();
434+
}
435+
436+
if ui.input_mut(|i| i.consume_shortcut(&self.shortcut_next)) {
437+
self.move_selected_next();
438+
}
419439

420-
if ui.input_mut(|i| i.consume_shortcut(&up_shortcut)) {
421-
data.move_selected_to_prev();
422-
self.should_scroll = true;
440+
if ui.input_mut(|i| i.consume_shortcut(&self.shortcut_first)) {
441+
self.move_selected_first();
442+
}
443+
444+
if ui.input_mut(|i| i.consume_shortcut(&self.shortcut_last)) {
445+
self.move_selected_last();
446+
}
447+
}
448+
449+
fn navigation_and_filtering_ui(&mut self, ui: &mut egui::Ui) {
450+
ui.horizontal(|ui| {
451+
ui.label("Nav:");
452+
if ui
453+
.button("⏪")
454+
.on_hover_text(format!(
455+
"First ({})",
456+
ui.ctx().format_shortcut(&self.shortcut_first)
457+
))
458+
.clicked()
459+
{
460+
self.move_selected_first();
461+
}
462+
if ui
463+
.button("⬆")
464+
.on_hover_text(format!(
465+
"Previous ({})",
466+
ui.ctx().format_shortcut(&self.shortcut_prev)
467+
))
468+
.clicked()
469+
{
470+
self.move_selected_prev();
471+
}
472+
if ui
473+
.button("⬇")
474+
.on_hover_text(format!(
475+
"Next ({})",
476+
ui.ctx().format_shortcut(&self.shortcut_next)
477+
))
478+
.clicked()
479+
{
480+
self.move_selected_next();
481+
}
482+
if ui
483+
.button("⏩")
484+
.on_hover_text(format!(
485+
"Last ({})",
486+
ui.ctx().format_shortcut(&self.shortcut_last)
487+
))
488+
.clicked()
489+
{
490+
self.move_selected_last();
491+
}
492+
});
493+
}
494+
fn data_load_ui(&mut self, ui: &mut egui::Ui) {
495+
ui.horizontal(|ui| {
496+
if ui.button("📂 Open log file...").clicked() {
497+
let ctx = ui.ctx().clone();
498+
self.loading_status = self.initiate_loading(ctx);
499+
}
500+
#[cfg(not(target_arch = "wasm32"))]
501+
{
502+
if ui.button("Reload").clicked() {
503+
self.loading_status = self.reload_file();
504+
}
505+
if ui.button("Load Most Recent File").clicked() {
506+
self.loading_status = self.load_most_recent_file();
507+
}
508+
}
509+
if ui.button("Clear Data").clicked() {
510+
self.data = None;
423511
}
424512

425-
if ui.input_mut(|i| i.consume_shortcut(&down_shortcut)) {
426-
data.move_selected_to_next();
427-
self.should_scroll = true;
513+
if self.show_last_filename {
514+
if let Some(filename) = self.last_filename.lock().unwrap().as_ref() {
515+
ui.label(format!("Filename: {}", filename.display()));
516+
}
428517
}
429-
}
518+
});
430519
}
431520
}
432521

src/app/data.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,8 @@ impl Data {
135135
} else {
136136
// Do nothing already on last row
137137
}
138-
} else if !self.rows.is_empty() {
139-
// Set to first row
140-
self.selected_row = Some(0)
141138
} else {
142-
// No rows to select
139+
self.move_selected_to_last();
143140
}
144141
}
145142

@@ -150,9 +147,22 @@ impl Data {
150147
} else {
151148
// Do nothing already on first row
152149
}
153-
} else if !self.rows.is_empty() {
154-
// Set to last row
155-
self.selected_row = Some(self.rows.len() - 1)
150+
} else {
151+
self.move_selected_to_first()
152+
}
153+
}
154+
155+
pub fn move_selected_to_first(&mut self) {
156+
if !self.rows.is_empty() {
157+
self.selected_row = Some(0)
158+
} else {
159+
// No rows to select
160+
}
161+
}
162+
163+
pub fn move_selected_to_last(&mut self) {
164+
if !self.rows.is_empty() {
165+
self.selected_row = Some(self.rows.len() - 1);
156166
} else {
157167
// No rows to select
158168
}

0 commit comments

Comments
 (0)