Skip to content

Commit

Permalink
Add support to close a recording (#2972)
Browse files Browse the repository at this point in the history
### What

This PR adds support to close a recording. Currently, this is available
through the Rerun menu and the command palette. A close button will be
added to the recording list UI in a subsequent PR.

My choices:
- No warning, etc. This is a rather "lossy" feature.
- No shortcut for the "Close recording" command (the natural one would
be cmd-W, but that usually close an actual window).
- When a recording is closed, the next one is selected when sorted by
(app ID, recording time). If the closed recording was the last, then the
previous one is selected.

<img width="1422" alt="image"
src="https://github.com/rerun-io/rerun/assets/49431240/81f189e5-890a-45fd-b6ef-4c963d8fc20c">


### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)
* [x] I have tested [demo.rerun.io](https://demo.rerun.io/pr/2972) (if
applicable)

- [PR Build Summary](https://build.rerun.io/pr/2972)
- [Docs
preview](https://rerun.io/preview/pr%3Aantoine%2Fclose-recording/docs)
- [Examples
preview](https://rerun.io/preview/pr%3Aantoine%2Fclose-recording/examples)
  • Loading branch information
abey79 authored Aug 14, 2023
1 parent e5a0047 commit 04f974f
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 0 deletions.
6 changes: 6 additions & 0 deletions crates/re_data_store/src/store_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,4 +374,10 @@ impl StoreDb {

entity_db.purge(&cutoff_times, &drop_row_ids);
}

/// Key used for sorting recordings in the UI.
pub fn sort_key(&self) -> impl Ord + '_ {
self.store_info()
.map(|info| (info.application_id.0.as_str(), info.started))
}
}
7 changes: 7 additions & 0 deletions crates/re_ui/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub enum UICommand {
Save,
#[cfg(not(target_arch = "wasm32"))]
SaveSelection,
CloseCurrentRecording,
#[cfg(not(target_arch = "wasm32"))]
Quit,

Expand Down Expand Up @@ -86,6 +87,11 @@ impl UICommand {
#[cfg(not(target_arch = "wasm32"))]
UICommand::Open => ("Open…", "Open a Rerun Data File (.rrd)"),

UICommand::CloseCurrentRecording => (
"Close current Recording",
"Close the current Recording (unsaved data will be lost)",
),

#[cfg(not(target_arch = "wasm32"))]
UICommand::Quit => ("Quit", "Close the Rerun Viewer"),

Expand Down Expand Up @@ -186,6 +192,7 @@ impl UICommand {
UICommand::SaveSelection => Some(cmd_alt(Key::S)),
#[cfg(not(target_arch = "wasm32"))]
UICommand::Open => Some(cmd(Key::O)),
UICommand::CloseCurrentRecording => None,

#[cfg(all(not(target_arch = "wasm32"), target_os = "windows"))]
UICommand::Quit => Some(KeyboardShortcut::new(Modifiers::ALT, Key::F4)),
Expand Down
12 changes: 12 additions & 0 deletions crates/re_viewer/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@ impl App {
SystemCommand::SetRecordingId(recording_id) => {
store_hub.set_recording_id(recording_id);
}
SystemCommand::CloseRecordingId(recording_id) => {
store_hub.remove_recording_id(&recording_id);
}
#[cfg(not(target_arch = "wasm32"))]
SystemCommand::LoadRrd(path) => {
let with_notification = true;
Expand Down Expand Up @@ -343,6 +346,15 @@ impl App {
.send_system(SystemCommand::LoadRrd(rrd_file));
}
}
UICommand::CloseCurrentRecording => {
let cur_rec = store_context
.and_then(|ctx| ctx.recording)
.map(|rec| rec.store_id());
if let Some(cur_rec) = cur_rec {
self.command_sender
.send_system(SystemCommand::CloseRecordingId(cur_rec.clone()));
}
}
#[cfg(not(target_arch = "wasm32"))]
UICommand::Quit => {
_frame.close();
Expand Down
35 changes: 35 additions & 0 deletions crates/re_viewer/src/store_hub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,17 @@ impl StoreHub {
self.selected_rec_id = Some(recording_id);
}

pub fn remove_recording_id(&mut self, recording_id: &StoreId) {
if let Some(new_selection) = self.store_dbs.find_closest_recording(recording_id) {
self.set_recording_id(new_selection.clone());
} else {
self.application_id = None;
self.selected_rec_id = None;
}

self.store_dbs.remove(recording_id);
}

/// Change the selected [`ApplicationId`]
pub fn set_app_id(&mut self, app_id: ApplicationId) {
// If we don't know of a blueprint for this `ApplicationId` yet,
Expand Down Expand Up @@ -326,6 +337,30 @@ impl StoreBundle {
self.store_dbs.remove(id);
}

/// Returns the closest "neighbor" recording to the given id.
///
/// The closest neighbor is the next recording when sorted by (app ID, time), if any, or the
/// previous one otherwise. This is used to update the selected recording when the current one
/// is deleted.
pub fn find_closest_recording(&self, id: &StoreId) -> Option<&StoreId> {
let mut recs = self.recordings().collect_vec();
recs.sort_by_key(|store_db| store_db.sort_key());

let cur_pos = recs.iter().position(|rec| rec.store_id() == id);

if let Some(cur_pos) = cur_pos {
if recs.len() > cur_pos + 1 {
Some(recs[cur_pos + 1].store_id())
} else if cur_pos > 0 {
Some(recs[cur_pos - 1].store_id())
} else {
None
}
} else {
None
}
}

// --

pub fn contains_recording(&self, id: &StoreId) -> bool {
Expand Down
2 changes: 2 additions & 0 deletions crates/re_viewer/src/ui/rerun_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ impl App {

self.save_buttons_ui(ui, _store_context);

UICommand::CloseCurrentRecording.menu_button_ui(ui, &self.command_sender);

ui.add_space(spacing);

// On the web the browser controls the zoom
Expand Down
3 changes: 3 additions & 0 deletions crates/re_viewer_context/src/command_sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ pub enum SystemCommand {
/// Change the active recording-id in the `StoreHub`
SetRecordingId(StoreId),

/// Close a recording
CloseRecordingId(StoreId),

/// Update the blueprint with additional data
///
/// The [`StoreId`] should generally be the currently selected blueprint
Expand Down

0 comments on commit 04f974f

Please sign in to comment.