Skip to content

Commit

Permalink
feat(dashboard): ✨ Make sections collapsible
Browse files Browse the repository at this point in the history
The session can save the collapsed state of each section
  • Loading branch information
zmerp committed Sep 3, 2023
1 parent 43f2c18 commit 4e3aa3b
Show file tree
Hide file tree
Showing 14 changed files with 303 additions and 200 deletions.
179 changes: 88 additions & 91 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions alvr/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ once_cell = "1"
parking_lot = "0.12"
semver = { version = "1", features = ["serde"] }
serde = { version = "1", features = ["derive"] }
settings-schema = { git = "https://github.com/zarik5/settings-schema-rs" }
settings-schema = { git = "https://github.com/alvr-org/settings-schema-rs", rev = "b565cf6" }
# settings-schema = { path = "../../../../settings-schema-rs/settings-schema" }

[target.'cfg(not(target_os = "android"))'.dependencies]
rfd = {version = "0.11", optional = true }
rfd = { version = "0.11", optional = true }
2 changes: 1 addition & 1 deletion alvr/dashboard/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ env_logger = "0.10"
ico = "0.3"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
settings-schema = { git = "https://github.com/zarik5/settings-schema-rs" }
settings-schema = { git = "https://github.com/alvr-org/settings-schema-rs", rev = "b565cf6" }
statrs = "0.16"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ impl Control {
) -> Option<PathValuePair> {
super::grid_flow_inline(ui, allow_inline);

// todo: can this be written better?
let enabled_mut = if let json::Value::Bool(enabled) = session_fragment {
enabled
} else {
let json::Value::Bool(enabled_mut) = session_fragment else {
unreachable!()
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,7 @@ impl Control {

let session_variants_mut = session_fragment.as_object_mut().unwrap();

// todo: can this be written better?
let variant_mut = if let json::Value::String(variant) = &mut session_variants_mut["variant"]
{
variant
} else {
let json::Value::String(variant_mut) = &mut session_variants_mut["variant"] else {
unreachable!()
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ fn grid_flow_inline(ui: &mut Ui, allow_inline: bool) {
}
}

fn grid_flow_block(ui: &mut Ui, allow_inline: bool) {
if allow_inline {
ui.end_row();
}
}

pub fn get_display_name(id: &str, strings: &HashMap<String, String>) -> String {
strings.get("display_name").cloned().unwrap_or_else(|| {
let mut chars = id.chars();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,7 @@ impl Control {

let session_switch_mut = session_fragment.as_object_mut().unwrap();

// todo: can this be written better?
let set_mut = if let json::Value::Bool(set) = &mut session_switch_mut["set"] {
set
} else {
let json::Value::Bool(set_mut) = &mut session_switch_mut["set"] else {
unreachable!()
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,35 @@
use std::collections::{HashMap, HashSet};

use super::schema::{HigherOrderChoiceSchema, PresetModifierOperation};
use crate::dashboard::components::{NestingInfo, SettingControl};
use crate::dashboard::components::{self, NestingInfo, SettingControl};
use alvr_gui_common::theme::{
log_colors::{INFO_LIGHT, WARNING_LIGHT},
OK_GREEN,
};
use alvr_packets::{PathSegment, PathValuePair};
use eframe::egui::Ui;
use eframe::egui::{self, popup, Ui};
use serde_json as json;
use settings_schema::{SchemaEntry, SchemaNode};

const POPUP_ID: &str = "setpopup";

pub struct Control {
name: String,
help: Option<String>,
steamvr_restart_flag: bool,
real_time_flag: bool,
modifiers: HashMap<String, Vec<PathValuePair>>,
control: SettingControl,
preset_json: json::Value,
}

impl Control {
pub fn new(schema: HigherOrderChoiceSchema) -> Self {
let name = schema.name.clone();
let name = components::get_display_name(&schema.name, &schema.strings);
let help = schema.strings.get("help").cloned();
// let notice = entry.strings.get("notice").cloned();
let steamvr_restart_flag = schema.flags.contains("steamvr-restart");
let real_time_flag = schema.flags.contains("real-time");

let modifiers = schema
.options
Expand All @@ -38,33 +51,25 @@ impl Control {
})
.collect();

let control_schema = SchemaNode::Section(
[SchemaEntry {
name: schema.name.clone(),
strings: schema.strings,
flags: schema.flags,
content: SchemaNode::Choice {
default: schema.options[schema.default_option_index]
.display_name
.clone(),
variants: schema
.options
let control_schema = SchemaNode::Choice {
default: schema.options[schema.default_option_index]
.display_name
.clone(),
variants: schema
.options
.into_iter()
.map(|option| SchemaEntry {
name: option.display_name.clone(),
strings: [("display_name".into(), option.display_name)]
.into_iter()
.map(|option| SchemaEntry {
name: option.display_name.clone(),
strings: [("display_name".into(), option.display_name)]
.into_iter()
.collect(),
flags: HashSet::new(),
content: None,
})
.collect(),
gui: Some(schema.gui),
},
}]
.into_iter()
.collect(),
);
flags: HashSet::new(),
content: None,
})
.collect(),
gui: Some(schema.gui),
};

let control = SettingControl::new(
NestingInfo {
path: vec![],
Expand All @@ -74,13 +79,14 @@ impl Control {
);

let preset_json = json::json!({
schema.name: {
"variant": ""
}
"variant": ""
});

Self {
name,
help,
steamvr_restart_flag,
real_time_flag,
modifiers,
control,
preset_json,
Expand Down Expand Up @@ -126,11 +132,48 @@ impl Control {
}

// Note: if no modifier matched, the control will unselect all options
self.preset_json[&self.name]["variant"] = json::Value::String(selected_option);
self.preset_json["variant"] = json::Value::String(selected_option);
}

pub fn ui(&mut self, ui: &mut Ui) -> Vec<PathValuePair> {
if let Some(desc) = self.control.ui(ui, &mut self.preset_json, false) {
let mut response = None;

ui.horizontal(|ui| {
ui.label(&self.name);

if let Some(string) = &self.help {
if ui.colored_label(INFO_LIGHT, "❓").hovered() {
popup::show_tooltip_text(ui.ctx(), egui::Id::new(POPUP_ID), string);
}
}
if self.steamvr_restart_flag && ui.colored_label(WARNING_LIGHT, "⚠").hovered() {
popup::show_tooltip_text(
ui.ctx(),
egui::Id::new(POPUP_ID),
format!(
"Changing this setting will make SteamVR restart!\n{}",
"Please save your in-game progress first"
),
);
}

// The emoji is blue but it will be green in the UI
if self.real_time_flag && ui.colored_label(OK_GREEN, "🔵").hovered() {
popup::show_tooltip_text(
ui.ctx(),
egui::Id::new(POPUP_ID),
"This setting can be changed in real-time during streaming!",
);
}
});
response = self
.control
.ui(ui, &mut self.preset_json, true)
.or(response);

// ui.end_row();

if let Some(desc) = response {
// todo: handle children requests
self.modifiers[desc.value.as_str().unwrap()].clone()
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,53 +68,77 @@ impl Control {
session_fragment: &mut json::Value,
allow_inline: bool,
) -> Option<PathValuePair> {
super::grid_flow_block(ui, allow_inline);
super::grid_flow_inline(ui, allow_inline);

let session_fragments_mut = session_fragment.as_object_mut().unwrap();

let json::Value::Bool(state_mut) = &mut session_fragments_mut["gui_collapsed"] else {
unreachable!()
};

let entries_count = self.entries.len();

fn get_request(nesting_info: &NestingInfo, collapsed: bool) -> Option<PathValuePair> {
super::set_single_value(
nesting_info,
"gui_collapsed".into(),
json::Value::Bool(collapsed),
)
}

let mut response = None;
for (i, entry) in self.entries.iter_mut().enumerate() {
ui.horizontal(|ui| {
ui.add_space(INDENTATION_STEP * self.nesting_info.indentation_level as f32);
let label_res = ui.label(&entry.id.display);
if cfg!(debug_assertions) {
label_res.on_hover_text(&*entry.id);
}
if (*state_mut && ui.small_button("Expand").clicked())
|| (!*state_mut && ui.small_button("Collapse").clicked())
{
*state_mut = !*state_mut;
response = get_request(&self.nesting_info, *state_mut);
}

if !*state_mut {
ui.end_row();

if let Some(string) = &entry.help {
if ui.colored_label(INFO_LIGHT, "❓").hovered() {
popup::show_tooltip_text(ui.ctx(), egui::Id::new(POPUP_ID), string);
for (i, entry) in self.entries.iter_mut().enumerate() {
ui.horizontal(|ui| {
ui.add_space(INDENTATION_STEP * self.nesting_info.indentation_level as f32);
let label_res = ui.label(&entry.id.display);
if cfg!(debug_assertions) {
label_res.on_hover_text(&*entry.id);
}

if let Some(string) = &entry.help {
if ui.colored_label(INFO_LIGHT, "❓").hovered() {
popup::show_tooltip_text(ui.ctx(), egui::Id::new(POPUP_ID), string);
}
}
if entry.steamvr_restart_flag && ui.colored_label(WARNING_LIGHT, "⚠").hovered()
{
popup::show_tooltip_text(
ui.ctx(),
egui::Id::new(POPUP_ID),
format!(
"Changing this setting will make SteamVR restart!\n{}",
"Please save your in-game progress first"
),
);
}
}
if entry.steamvr_restart_flag && ui.colored_label(WARNING_LIGHT, "⚠").hovered() {
popup::show_tooltip_text(
ui.ctx(),
egui::Id::new(POPUP_ID),
format!(
"Changing this setting will make SteamVR restart!\n{}",
"Please save your in-game progress first"
),
);
}

// The emoji is blue but it will be green in the UI
if entry.real_time_flag && ui.colored_label(OK_GREEN, "🔵").hovered() {
popup::show_tooltip_text(
ui.ctx(),
egui::Id::new(POPUP_ID),
"This setting can be changed in real-time during streaming!",
);
// The emoji is blue but it will be green in the UI
if entry.real_time_flag && ui.colored_label(OK_GREEN, "🔵").hovered() {
popup::show_tooltip_text(
ui.ctx(),
egui::Id::new(POPUP_ID),
"This setting can be changed in real-time during streaming!",
);
}
});
response = entry
.control
.ui(ui, &mut session_fragments_mut[&entry.id.id], true)
.or(response);

if i != entries_count - 1 {
ui.end_row();
}
});
response = entry
.control
.ui(ui, &mut session_fragments_mut[&entry.id.id], true)
.or(response);

if i != entries_count - 1 {
ui.end_row();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,7 @@ impl Control {

let session_switch_mut = session_fragment.as_object_mut().unwrap();

// todo: can this be written better?
let enabled_mut = if let json::Value::Bool(enabled) = &mut session_switch_mut["enabled"] {
enabled
} else {
let json::Value::Bool(enabled_mut) = &mut session_switch_mut["enabled"] else {
unreachable!()
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,7 @@ impl Control {
) -> Option<PathValuePair> {
super::grid_flow_inline(ui, allow_inline);

// todo: can this be written better?
let text_mut = if let json::Value::String(text) = session_fragment {
text
} else {
let json::Value::String(text_mut) = session_fragment else {
unreachable!()
};

Expand Down
2 changes: 1 addition & 1 deletion alvr/session/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ alvr_common.workspace = true
bytemuck = { version = "1", features = ["derive"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
settings-schema = { git = "https://github.com/zarik5/settings-schema-rs" }
settings-schema = { git = "https://github.com/alvr-org/settings-schema-rs", rev = "b565cf6" }

[build-dependencies]
regex = "1"
Loading

0 comments on commit 4e3aa3b

Please sign in to comment.