Skip to content

Commit

Permalink
Add a mechanism to control individual variant availability for enum e…
Browse files Browse the repository at this point in the history
…dit UI and use it for `MapProvider`
  • Loading branch information
abey79 committed Nov 5, 2024
1 parent 562e9d3 commit 74c0322
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 11 deletions.
97 changes: 88 additions & 9 deletions crates/viewer/re_component_ui/src/datatype_uis/enum_combobox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,70 @@ use re_viewer_context::{MaybeMutRef, ViewerContext};

use crate::response_utils::response_with_changes_of_inner;

/// Is a particular variant of an enum available for selection? If not, why?
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum VariantAvailable {
/// The variant is available
Yes,

/// The variant is not available.
No {
/// The reason why the variant is not available, markdown formated.
reason_markdown: String,
},
}

/// Trait for a type that can provide information about whether a particular variant of an enum is
/// available for selection.
pub trait VariantAvailableProvider<EnumT: re_types_core::reflection::Enum> {
fn is_variant_enabled(ctx: &ViewerContext<'_>, variant: EnumT) -> VariantAvailable;
}

/// A variant available provider that makes all variants available.
struct AllEnumVariantAvailable<EnumT: re_types_core::reflection::Enum> {
_phantom: std::marker::PhantomData<EnumT>,
}

impl<EnumT: re_types_core::reflection::Enum> VariantAvailableProvider<EnumT>
for AllEnumVariantAvailable<EnumT>
{
fn is_variant_enabled(_ctx: &ViewerContext<'_>, _variant: EnumT) -> VariantAvailable {
VariantAvailable::Yes
}
}

/// Edit or view an enum value using a combobox. All variants are available.
pub fn edit_view_enum<EnumT: re_types_core::reflection::Enum + re_types_core::Component>(
_ctx: &ViewerContext<'_>,
ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
current_value: &mut MaybeMutRef<'_, EnumT>,
) -> egui::Response {
edit_view_enum_with_variant_available::<EnumT, AllEnumVariantAvailable<EnumT>>(
ctx,
ui,
current_value,
)
}

/// Edit or view an enum value using a combobox. The availability of each variant is determined by
/// the provided `VariantAvailableProvider` type.
pub fn edit_view_enum_with_variant_available<
EnumT: re_types_core::reflection::Enum + re_types_core::Component,
VariantAvailT: VariantAvailableProvider<EnumT>,
>(
ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
current_value: &mut MaybeMutRef<'_, EnumT>,
) -> egui::Response {
let id_salt = EnumT::name().full_name();
edit_view_enum_impl(ui, id_salt, current_value)
edit_view_enum_impl::<_, VariantAvailT>(ctx, ui, id_salt, current_value)
}

fn edit_view_enum_impl<EnumT: re_types_core::reflection::Enum>(
fn edit_view_enum_impl<
EnumT: re_types_core::reflection::Enum,
VariantAvailT: VariantAvailableProvider<EnumT>,
>(
ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
id_salt: &str,
current_value: &mut MaybeMutRef<'_, EnumT>,
Expand All @@ -32,9 +86,19 @@ fn edit_view_enum_impl<EnumT: re_types_core::reflection::Enum>(
return ui.label("<no variants>");
};

let mut response = variant_ui(ui, current_value, first);
let mut response = crate::datatype_uis::enum_combobox::variant_ui(
ui,
current_value,
first,
VariantAvailT::is_variant_enabled(ctx, first),
);
for variant in iter {
response |= variant_ui(ui, current_value, variant);
response |= variant_ui(
ui,
current_value,
variant,
VariantAvailT::is_variant_enabled(ctx, variant),
);
}
response
});
Expand All @@ -53,9 +117,24 @@ fn variant_ui<EnumT: re_types_core::reflection::Enum>(
ui: &mut egui::Ui,
current_value: &mut EnumT,
variant: EnumT,
variant_available: VariantAvailable,
) -> egui::Response {
ui.selectable_value(current_value, variant, variant.to_string())
.on_hover_ui(|ui| {
ui.markdown_ui(variant.docstring_md());
})
match variant_available {
VariantAvailable::Yes => ui
.selectable_value(current_value, variant, variant.to_string())
.on_hover_ui(|ui| {
ui.markdown_ui(variant.docstring_md());
}),
VariantAvailable::No {
reason_markdown: reason,
} => {
ui.add_enabled_ui(false, |ui| {
ui.selectable_value(current_value, variant, variant.to_string())
.on_disabled_hover_ui(|ui| {
ui.markdown_ui(&format!("{}\n\n{}", variant.docstring_md(), reason));
})
})
.inner
}
}
}
5 changes: 4 additions & 1 deletion crates/viewer/re_component_ui/src/datatype_uis/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ mod vec;
mod view_id;

pub use bool_toggle::edit_bool;
pub use enum_combobox::edit_view_enum;
pub use enum_combobox::{
edit_view_enum, edit_view_enum_with_variant_available, VariantAvailable,
VariantAvailableProvider,
};
pub use float_drag::{
edit_f32_min_to_max_float, edit_f32_zero_to_max, edit_f32_zero_to_one,
edit_f64_float_raw_with_speed_impl,
Expand Down
9 changes: 8 additions & 1 deletion crates/viewer/re_component_ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod entity_path;
mod fallback_ui;
mod image_format;
mod line_strip;
mod map_provider;
mod marker_shape;
mod pinhole;
mod radius;
Expand All @@ -27,6 +28,7 @@ use datatype_uis::{
edit_view_enum, edit_view_range1d, view_view_id,
};

use crate::datatype_uis::edit_view_enum_with_variant_available;
use re_types::{
blueprint::components::{
BackgroundKind, Corner2D, LockRangeDuringZoom, MapProvider, ViewFit, Visible, ZoomLevel,
Expand Down Expand Up @@ -94,7 +96,12 @@ pub fn create_component_ui_registry() -> re_viewer_context::ComponentUiRegistry
registry.add_singleline_edit_or_view::<Corner2D>(edit_view_enum);
registry.add_singleline_edit_or_view::<FillMode>(edit_view_enum);
registry.add_singleline_edit_or_view::<MagnificationFilter>(edit_view_enum);
registry.add_singleline_edit_or_view::<MapProvider>(edit_view_enum);
registry.add_singleline_edit_or_view::<MapProvider>(
edit_view_enum_with_variant_available::<
MapProvider,
crate::map_provider::MapProviderVariantAvailable,
>,
);
registry.add_singleline_edit_or_view::<TransformRelation>(edit_view_enum);
registry.add_singleline_edit_or_view::<ViewFit>(edit_view_enum);

Expand Down
30 changes: 30 additions & 0 deletions crates/viewer/re_component_ui/src/map_provider.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use re_types::blueprint::components::MapProvider;
use re_viewer_context::ViewerContext;

use crate::datatype_uis::{VariantAvailable, VariantAvailableProvider};

pub struct MapProviderVariantAvailable;

impl VariantAvailableProvider<MapProvider> for MapProviderVariantAvailable {
fn is_variant_enabled(ctx: &ViewerContext<'_>, variant: MapProvider) -> VariantAvailable {
let map_box_available = if ctx
.app_options
.mapbox_access_token()
.is_some_and(|token| !token.is_empty())
{
VariantAvailable::Yes
} else {
VariantAvailable::No {
reason_markdown: "Mapbox access token is not set. ".to_owned(),
}
};

match variant {
MapProvider::OpenStreetMap => VariantAvailable::Yes,

MapProvider::MapboxStreets | MapProvider::MapboxDark | MapProvider::MapboxSatellite => {
map_box_available
}
}
}
}

0 comments on commit 74c0322

Please sign in to comment.