Skip to content

Commit

Permalink
feat: ✨ Make Arrays collapsible; make collapsible sections optional
Browse files Browse the repository at this point in the history
  • Loading branch information
zmerp committed Sep 11, 2023
1 parent a417a84 commit a3ce7c1
Show file tree
Hide file tree
Showing 11 changed files with 234 additions and 149 deletions.
106 changes: 53 additions & 53 deletions Cargo.lock

Large diffs are not rendered by default.

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

[target.'cfg(not(target_os = "android"))'.dependencies]
Expand Down
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/alvr-org/settings-schema-rs", rev = "b565cf6" }
settings-schema = { git = "https://github.com/alvr-org/settings-schema-rs", rev = "676185f" }
statrs = "0.16"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
Expand Down
6 changes: 2 additions & 4 deletions alvr/dashboard/src/dashboard/components/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,11 @@ impl SettingsTab {
let schema = Settings::schema(alvr_session::session_settings_default());

// Top level node must be a section
let schema_entries = if let SchemaNode::Section(entries) = schema {
entries
} else {
let SchemaNode::Section { entries, .. } = schema else {
unreachable!();
};

let top_level_entries = schema_entries
let top_level_entries = entries
.into_iter()
.map(|entry| {
let id = entry.name;
Expand Down
38 changes: 28 additions & 10 deletions alvr/dashboard/src/dashboard/components/settings_controls/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use eframe::egui::Ui;
use serde_json as json;

pub struct Control {
nesting_info: NestingInfo,
controls: Vec<SettingControl>,
}

Expand All @@ -15,13 +16,17 @@ impl Control {
.enumerate()
.map(|(idx, schema)| {
let mut nesting_info = nesting_info.clone();
nesting_info.path.push("content".into());
nesting_info.path.push(idx.into());

SettingControl::new(nesting_info, schema)
})
.collect();

Self { controls }
Self {
nesting_info,
controls,
}
}

pub fn ui(
Expand All @@ -32,19 +37,32 @@ impl Control {
) -> Option<PathValuePair> {
super::grid_flow_inline(ui, allow_inline);

let session_array_mut = session_fragment.as_array_mut().unwrap();

let count = self.controls.len();
let json::Value::Bool(collapsed_state_mut) = &mut session_fragment["gui_collapsed"] else {
unreachable!()
};

let mut request = None;
for (idx, control) in self.controls.iter_mut().enumerate() {
let allow_inline = idx == 0;
request = control
.ui(ui, &mut session_array_mut[idx], allow_inline)
.or(request);

if idx != count - 1 {
if (*collapsed_state_mut && ui.small_button("Expand").clicked())
|| (!*collapsed_state_mut && ui.small_button("Collapse").clicked())
{
*collapsed_state_mut = !*collapsed_state_mut;
request = super::set_single_value(
&self.nesting_info,
"gui_collapsed".into(),
json::Value::Bool(*collapsed_state_mut),
);
}

if !*collapsed_state_mut {
let session_array_mut = session_fragment["content"].as_array_mut().unwrap();

for (idx, control) in self.controls.iter_mut().enumerate() {
ui.end_row();

request = control
.ui(ui, &mut session_array_mut[idx], false)
.or(request);
}
}

Expand Down
11 changes: 8 additions & 3 deletions alvr/dashboard/src/dashboard/components/settings_controls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,14 @@ pub enum SettingControl {
impl SettingControl {
pub fn new(nesting_info: NestingInfo, schema: SchemaNode) -> Self {
match schema {
SchemaNode::Section(entries) => {
Self::Section(section::Control::new(nesting_info, entries))
}
SchemaNode::Section {
entries,
gui_collapsible,
} => Self::Section(section::Control::new(
nesting_info,
entries,
gui_collapsible,
)),
SchemaNode::Choice {
default,
variants,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ struct Entry {
pub struct Control {
nesting_info: NestingInfo,
entries: Vec<Entry>,
gui_collapsible: bool,
}

impl Control {
pub fn new(
mut nesting_info: NestingInfo,
schema_entries: Vec<SchemaEntry<SchemaNode>>,
gui_collapsible: bool,
) -> Self {
nesting_info.indentation_level += 1;

Expand Down Expand Up @@ -59,6 +61,7 @@ impl Control {
Self {
nesting_info,
entries,
gui_collapsible,
}
}

Expand All @@ -68,35 +71,42 @@ impl Control {
session_fragment: &mut json::Value,
allow_inline: bool,
) -> Option<PathValuePair> {
super::grid_flow_inline(ui, allow_inline);
let entries_count = self.entries.len();

let session_fragments_mut = session_fragment.as_object_mut().unwrap();
let mut request = None;

let json::Value::Bool(state_mut) = &mut session_fragments_mut["gui_collapsed"] else {
unreachable!()
};
let collapsed = if self.gui_collapsible {
super::grid_flow_inline(ui, allow_inline);

let entries_count = self.entries.len();
let json::Value::Bool(state_mut) = &mut session_fragment["gui_collapsed"] else {
unreachable!()
};

fn get_request(nesting_info: &NestingInfo, collapsed: bool) -> Option<PathValuePair> {
super::set_single_value(
nesting_info,
"gui_collapsed".into(),
json::Value::Bool(collapsed),
)
}
if (*state_mut && ui.small_button("Expand").clicked())
|| (!*state_mut && ui.small_button("Collapse").clicked())
{
*state_mut = !*state_mut;
request = super::set_single_value(
&self.nesting_info,
"gui_collapsed".into(),
json::Value::Bool(*state_mut),
);
}

let mut response = None;
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 !*state_mut {
ui.end_row();
*state_mut
} else {
if allow_inline {
ui.end_row();
}

false
};

if !collapsed {
for (i, entry) in self.entries.iter_mut().enumerate() {
ui.horizontal(|ui| {
ui.add_space(INDENTATION_STEP * self.nesting_info.indentation_level as f32);
Expand Down Expand Up @@ -131,17 +141,17 @@ impl Control {
);
}
});
response = entry
request = entry
.control
.ui(ui, &mut session_fragments_mut[&entry.id.id], true)
.or(response);
.ui(ui, &mut session_fragment[&entry.id.id], true)
.or(request);

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

response
request
}
}
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/alvr-org/settings-schema-rs", rev = "b565cf6" }
settings-schema = { git = "https://github.com/alvr-org/settings-schema-rs", rev = "676185f" }

[build-dependencies]
regex = "1"
8 changes: 7 additions & 1 deletion alvr/session/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,13 @@ static OPENVR_PROPS_DEFAULT: alvr_common::once_cell::sync::Lazy<OpenvrPropertyDe
"Uint64" => "0",
"Float" => "0.0",
"String" => "String::new()",
"Vector3" => "[0.0, 0.0, 0.0]",
"Vector3" => {
r"ArrayDefault {
gui_collapsed: false,
content: [0.0, 0.0, 0.0],
}"
}

_ => "()",
};

Expand Down
65 changes: 48 additions & 17 deletions alvr/session/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,10 @@ fn extrapolate_session_settings_from_session_settings(
schema: &SchemaNode,
) -> json::Value {
match schema {
SchemaNode::Section(entries) => json::Value::Object({
SchemaNode::Section {
entries,
gui_collapsible,
} => json::Value::Object({
let mut entries: json::Map<String, json::Value> = entries
.iter()
.map(|named_entry| {
Expand All @@ -260,17 +263,19 @@ fn extrapolate_session_settings_from_session_settings(
})
.collect();

let collapsed_state = new_session_settings
.get("gui_collapsed")
.and_then(|val| val.as_bool())
.unwrap_or_else(|| {
old_session_settings
.get("gui_collapsed")
.unwrap()
.as_bool()
.unwrap()
});
entries.insert("gui_collapsed".into(), json::Value::Bool(collapsed_state));
if *gui_collapsible {
let collapsed_state = new_session_settings
.get("gui_collapsed")
.and_then(|val| val.as_bool())
.unwrap_or_else(|| {
old_session_settings
.get("gui_collapsed")
.unwrap()
.as_bool()
.unwrap()
});
entries.insert("gui_collapsed".into(), json::Value::Bool(collapsed_state));
}

entries
}),
Expand Down Expand Up @@ -392,20 +397,36 @@ fn extrapolate_session_settings_from_session_settings(
}

SchemaNode::Array(array_schema) => {
let gui_collapsed = new_session_settings
.get("gui_collapsed")
.cloned()
.filter(|new_key| new_key.is_string())
.unwrap_or_else(|| old_session_settings["gui_collapsed"].clone());

let array_vec = (0..array_schema.len())
.map(|idx| {
new_session_settings
.get(idx)
.cloned()
.unwrap_or_else(|| old_session_settings[idx].clone())
})
.collect();
json::Value::Array(array_vec)
.collect::<Vec<_>>();

json::json!({
"gui_collapsed": gui_collapsed,
"content": array_vec
})
}

SchemaNode::Vector {
default_element, ..
} => {
let gui_collapsed = new_session_settings
.get("gui_collapsed")
.cloned()
.filter(|new_key| new_key.is_string())
.unwrap_or_else(|| old_session_settings["gui_collapsed"].clone());

let element_json = new_session_settings
.get("element")
.map(|new_element_json| {
Expand All @@ -427,12 +448,19 @@ fn extrapolate_session_settings_from_session_settings(
.unwrap_or_else(|| old_session_settings["content"].clone());

json::json!({
"gui_collapsed": gui_collapsed,
"element": element_json,
"content": content_json
})
}

SchemaNode::Dictionary { default_value, .. } => {
let gui_collapsed = new_session_settings
.get("gui_collapsed")
.cloned()
.filter(|new_key| new_key.is_string())
.unwrap_or_else(|| old_session_settings["gui_collapsed"].clone());

let key_json = new_session_settings
.get("key")
.cloned()
Expand All @@ -457,6 +485,7 @@ fn extrapolate_session_settings_from_session_settings(
.unwrap_or_else(|| old_session_settings["content"].clone());

json::json!({
"gui_collapsed": gui_collapsed,
"key": key_json,
"value": value_json,
"content": content_json
Expand All @@ -472,7 +501,7 @@ fn json_session_settings_to_settings(
schema: &SchemaNode,
) -> json::Value {
match schema {
SchemaNode::Section(entries) => json::Value::Object(
SchemaNode::Section { entries, .. } => json::Value::Object(
entries
.iter()
.map(|named_entry| {
Expand Down Expand Up @@ -531,7 +560,10 @@ fn json_session_settings_to_settings(
.iter()
.enumerate()
.map(|(idx, element_schema)| {
json_session_settings_to_settings(&session_settings[idx], element_schema)
json_session_settings_to_settings(
&session_settings["content"][idx],
element_schema,
)
})
.collect(),
),
Expand Down Expand Up @@ -600,7 +632,6 @@ mod tests {
fn test_session_extrapolation_diff() {
let input_json_string = r#"{
"session_settings": {
"gui_collapsed": false,
"fjdshfks": false,
"video": {
"preferred_fps": 60.0
Expand Down
Loading

0 comments on commit a3ce7c1

Please sign in to comment.