settings_ui: Refactor item renderers to render entire field (#39959)
Closes #ISSUE Release Notes: - N/A *or* Added/Fixed/Improved ...
This commit is contained in:
@@ -8,7 +8,7 @@ use feature_flags::FeatureFlag;
|
||||
use fuzzy::StringMatchCandidate;
|
||||
use gpui::{
|
||||
Action, App, Div, Entity, FocusHandle, Focusable, FontWeight, Global, ReadGlobal as _,
|
||||
ScrollHandle, Subscription, Task, TitlebarOptions, UniformListScrollHandle, Window,
|
||||
ScrollHandle, Stateful, Subscription, Task, TitlebarOptions, UniformListScrollHandle, Window,
|
||||
WindowBounds, WindowHandle, WindowOptions, actions, div, point, prelude::*, px, size,
|
||||
uniform_list,
|
||||
};
|
||||
@@ -83,12 +83,20 @@ actions!(
|
||||
#[action(namespace = settings_editor)]
|
||||
struct FocusFile(pub u32);
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct SettingField<T: 'static> {
|
||||
pick: fn(&SettingsContent) -> &Option<T>,
|
||||
pick_mut: fn(&mut SettingsContent) -> &mut Option<T>,
|
||||
}
|
||||
|
||||
impl<T: 'static> Clone for SettingField<T> {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
// manual impl because derive puts a Copy bound on T, which is inaccurate in our case
|
||||
impl<T: 'static> Copy for SettingField<T> {}
|
||||
|
||||
/// Helper for unimplemented settings, used in combination with `SettingField::unimplemented`
|
||||
/// to keep the setting around in the UI with valid pick and pick_mut implementations, but don't actually try to render it.
|
||||
/// TODO(settings_ui): In non-dev builds (`#[cfg(not(debug_assertions))]`) make this render as edit-in-json
|
||||
@@ -99,7 +107,7 @@ impl<T: 'static> SettingField<T> {
|
||||
#[allow(unused)]
|
||||
fn unimplemented(self) -> SettingField<UnimplementedSettingField> {
|
||||
SettingField {
|
||||
pick: |_| &None,
|
||||
pick: |_| &Some(UnimplementedSettingField),
|
||||
pick_mut: |_| unreachable!(),
|
||||
}
|
||||
}
|
||||
@@ -127,10 +135,6 @@ impl<T> AnySettingField for SettingField<T> {
|
||||
}
|
||||
|
||||
fn file_set_in(&self, file: SettingsUiFile, cx: &App) -> (settings::SettingsFile, bool) {
|
||||
if AnySettingField::type_id(self) == TypeId::of::<UnimplementedSettingField>() {
|
||||
return (file.to_settings(), true);
|
||||
}
|
||||
|
||||
let (file, value) = cx
|
||||
.global::<SettingsStore>()
|
||||
.get_value_from_file(file.to_settings(), self.pick);
|
||||
@@ -146,12 +150,13 @@ struct SettingFieldRenderer {
|
||||
TypeId,
|
||||
Box<
|
||||
dyn Fn(
|
||||
&dyn AnySettingField,
|
||||
&SettingsWindow,
|
||||
&SettingItem,
|
||||
SettingsUiFile,
|
||||
Option<&SettingsFieldMetadata>,
|
||||
&mut Window,
|
||||
&mut App,
|
||||
) -> AnyElement,
|
||||
&mut Context<SettingsWindow>,
|
||||
) -> Stateful<Div>,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
@@ -161,10 +166,10 @@ struct SettingFieldRenderer {
|
||||
impl Global for SettingFieldRenderer {}
|
||||
|
||||
impl SettingFieldRenderer {
|
||||
fn add_renderer<T: 'static>(
|
||||
fn add_basic_renderer<T: 'static>(
|
||||
&mut self,
|
||||
renderer: impl Fn(
|
||||
&SettingField<T>,
|
||||
render_control: impl Fn(
|
||||
SettingField<T>,
|
||||
SettingsUiFile,
|
||||
Option<&SettingsFieldMetadata>,
|
||||
&mut Window,
|
||||
@@ -172,51 +177,67 @@ impl SettingFieldRenderer {
|
||||
) -> AnyElement
|
||||
+ 'static,
|
||||
) -> &mut Self {
|
||||
let key = TypeId::of::<T>();
|
||||
let renderer = Box::new(
|
||||
move |any_setting_field: &dyn AnySettingField,
|
||||
self.add_renderer(
|
||||
move |settings_window: &SettingsWindow,
|
||||
item: &SettingItem,
|
||||
field: SettingField<T>,
|
||||
settings_file: SettingsUiFile,
|
||||
metadata: Option<&SettingsFieldMetadata>,
|
||||
window: &mut Window,
|
||||
cx: &mut App| {
|
||||
let field = any_setting_field
|
||||
cx: &mut Context<SettingsWindow>| {
|
||||
render_settings_item(
|
||||
settings_window,
|
||||
item,
|
||||
settings_file.clone(),
|
||||
render_control(field, settings_file, metadata, window, cx),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn add_renderer<T: 'static>(
|
||||
&mut self,
|
||||
renderer: impl Fn(
|
||||
&SettingsWindow,
|
||||
&SettingItem,
|
||||
SettingField<T>,
|
||||
SettingsUiFile,
|
||||
Option<&SettingsFieldMetadata>,
|
||||
&mut Window,
|
||||
&mut Context<SettingsWindow>,
|
||||
) -> Stateful<Div>
|
||||
+ 'static,
|
||||
) -> &mut Self {
|
||||
let key = TypeId::of::<T>();
|
||||
let renderer = Box::new(
|
||||
move |settings_window: &SettingsWindow,
|
||||
item: &SettingItem,
|
||||
settings_file: SettingsUiFile,
|
||||
metadata: Option<&SettingsFieldMetadata>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<SettingsWindow>| {
|
||||
let field = *item
|
||||
.field
|
||||
.as_ref()
|
||||
.as_any()
|
||||
.downcast_ref::<SettingField<T>>()
|
||||
.unwrap();
|
||||
renderer(field, settings_file, metadata, window, cx)
|
||||
renderer(
|
||||
settings_window,
|
||||
item,
|
||||
field,
|
||||
settings_file,
|
||||
metadata,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
},
|
||||
);
|
||||
self.renderers.borrow_mut().insert(key, renderer);
|
||||
self
|
||||
}
|
||||
|
||||
fn render(
|
||||
&self,
|
||||
any_setting_field: &dyn AnySettingField,
|
||||
settings_file: SettingsUiFile,
|
||||
metadata: Option<&SettingsFieldMetadata>,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> AnyElement {
|
||||
let key = any_setting_field.type_id();
|
||||
if let Some(renderer) = self.renderers.borrow().get(&key) {
|
||||
renderer(any_setting_field, settings_file, metadata, window, cx)
|
||||
} else {
|
||||
Button::new("no-renderer", "NO RENDERER")
|
||||
.style(ButtonStyle::Outlined)
|
||||
.size(ButtonSize::Medium)
|
||||
.icon(Some(IconName::XCircle))
|
||||
.icon_position(IconPosition::Start)
|
||||
.icon_color(Color::Error)
|
||||
.tab_index(0_isize)
|
||||
.tooltip(Tooltip::text(any_setting_field.type_name()))
|
||||
.into_any_element()
|
||||
// panic!(
|
||||
// "No renderer found for type: {}",
|
||||
// any_setting_field.type_name()
|
||||
// )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct NonFocusableHandle {
|
||||
@@ -278,7 +299,7 @@ pub fn init(cx: &mut App) {
|
||||
|
||||
fn init_renderers(cx: &mut App) {
|
||||
cx.default_global::<SettingFieldRenderer>()
|
||||
.add_renderer::<UnimplementedSettingField>(|_, _, _, _, _| {
|
||||
.add_basic_renderer::<UnimplementedSettingField>(|_, _, _, _, _| {
|
||||
Button::new("open-in-settings-file", "Edit in settings.json")
|
||||
.style(ButtonStyle::Outlined)
|
||||
.size(ButtonSize::Medium)
|
||||
@@ -288,197 +309,70 @@ fn init_renderers(cx: &mut App) {
|
||||
})
|
||||
.into_any_element()
|
||||
})
|
||||
.add_renderer::<bool>(|settings_field, file, _, _, cx| {
|
||||
render_toggle_button(*settings_field, file, cx).into_any_element()
|
||||
})
|
||||
.add_renderer::<String>(|settings_field, file, metadata, _, cx| {
|
||||
render_text_field(settings_field.clone(), file, metadata, cx)
|
||||
})
|
||||
.add_renderer::<SaturatingBool>(|settings_field, file, _, _, cx| {
|
||||
render_toggle_button(*settings_field, file, cx)
|
||||
})
|
||||
.add_renderer::<CursorShape>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<RestoreOnStartupBehavior>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<BottomDockLayout>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<OnLastWindowClosed>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<CloseWindowWhenNoItems>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::FontFamilyName>(|settings_field, file, _, window, cx| {
|
||||
// todo(settings_ui): We need to pass in a validator for this to ensure that users that type in invalid font names
|
||||
render_font_picker(settings_field.clone(), file, window, cx)
|
||||
})
|
||||
.add_basic_renderer::<bool>(render_toggle_button)
|
||||
.add_basic_renderer::<String>(render_text_field)
|
||||
.add_basic_renderer::<SaturatingBool>(render_toggle_button)
|
||||
.add_basic_renderer::<CursorShape>(render_dropdown)
|
||||
.add_basic_renderer::<RestoreOnStartupBehavior>(render_dropdown)
|
||||
.add_basic_renderer::<BottomDockLayout>(render_dropdown)
|
||||
.add_basic_renderer::<OnLastWindowClosed>(render_dropdown)
|
||||
.add_basic_renderer::<CloseWindowWhenNoItems>(render_dropdown)
|
||||
.add_basic_renderer::<settings::FontFamilyName>(render_font_picker)
|
||||
// todo(settings_ui): This needs custom ui
|
||||
// .add_renderer::<settings::BufferLineHeight>(|settings_field, file, _, window, cx| {
|
||||
// // todo(settings_ui): Do we want to expose the custom variant of buffer line height?
|
||||
// // right now there's a manual impl of strum::VariantArray
|
||||
// render_dropdown(*settings_field, file, window, cx)
|
||||
// })
|
||||
.add_renderer::<settings::BaseKeymapContent>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::MultiCursorModifier>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::HideMouseMode>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::CurrentLineHighlight>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::ShowWhitespaceSetting>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::SoftWrap>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::ScrollBeyondLastLine>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::SnippetSortOrder>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::ClosePosition>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::DockSide>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::TerminalDockPosition>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::DockPosition>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::GitGutterSetting>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::GitHunkStyleSetting>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::DiagnosticSeverityContent>(
|
||||
|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
},
|
||||
)
|
||||
.add_renderer::<settings::SeedQuerySetting>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::DoubleClickInMultibuffer>(
|
||||
|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
},
|
||||
)
|
||||
.add_renderer::<settings::GoToDefinitionFallback>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::ActivateOnClose>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::ShowDiagnostics>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::ShowCloseButton>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::ProjectPanelEntrySpacing>(
|
||||
|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
},
|
||||
)
|
||||
.add_renderer::<settings::RewrapBehavior>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::FormatOnSave>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::IndentGuideColoring>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::IndentGuideBackgroundColoring>(
|
||||
|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
},
|
||||
)
|
||||
.add_renderer::<settings::FileFinderWidthContent>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::ShowDiagnostics>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::WordsCompletionMode>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::LspInsertMode>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::AlternateScroll>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::TerminalBlink>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::CursorShapeContent>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<f32>(|settings_field, file, _, window, cx| {
|
||||
render_number_field(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<u32>(|settings_field, file, _, window, cx| {
|
||||
render_number_field(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<u64>(|settings_field, file, _, window, cx| {
|
||||
render_number_field(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<usize>(|settings_field, file, _, window, cx| {
|
||||
render_number_field(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<NonZero<usize>>(|settings_field, file, _, window, cx| {
|
||||
render_number_field(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<NonZeroU32>(|settings_field, file, _, window, cx| {
|
||||
render_number_field(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<CodeFade>(|settings_field, file, _, window, cx| {
|
||||
render_number_field(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<FontWeight>(|settings_field, file, _, window, cx| {
|
||||
render_number_field(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::MinimumContrast>(|settings_field, file, _, window, cx| {
|
||||
render_number_field(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::ShowScrollbar>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::ScrollbarDiagnostics>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::ShowMinimap>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::DisplayIn>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::MinimapThumb>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::MinimapThumbBorder>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
})
|
||||
.add_renderer::<settings::SteppingGranularity>(|settings_field, file, _, window, cx| {
|
||||
render_dropdown(*settings_field, file, window, cx)
|
||||
});
|
||||
|
||||
// todo(settings_ui): Figure out how we want to handle discriminant unions
|
||||
.add_basic_renderer::<settings::BaseKeymapContent>(render_dropdown)
|
||||
.add_basic_renderer::<settings::MultiCursorModifier>(render_dropdown)
|
||||
.add_basic_renderer::<settings::HideMouseMode>(render_dropdown)
|
||||
.add_basic_renderer::<settings::CurrentLineHighlight>(render_dropdown)
|
||||
.add_basic_renderer::<settings::ShowWhitespaceSetting>(render_dropdown)
|
||||
.add_basic_renderer::<settings::SoftWrap>(render_dropdown)
|
||||
.add_basic_renderer::<settings::ScrollBeyondLastLine>(render_dropdown)
|
||||
.add_basic_renderer::<settings::SnippetSortOrder>(render_dropdown)
|
||||
.add_basic_renderer::<settings::ClosePosition>(render_dropdown)
|
||||
.add_basic_renderer::<settings::DockSide>(render_dropdown)
|
||||
.add_basic_renderer::<settings::TerminalDockPosition>(render_dropdown)
|
||||
.add_basic_renderer::<settings::DockPosition>(render_dropdown)
|
||||
.add_basic_renderer::<settings::GitGutterSetting>(render_dropdown)
|
||||
.add_basic_renderer::<settings::GitHunkStyleSetting>(render_dropdown)
|
||||
.add_basic_renderer::<settings::DiagnosticSeverityContent>(render_dropdown)
|
||||
.add_basic_renderer::<settings::SeedQuerySetting>(render_dropdown)
|
||||
.add_basic_renderer::<settings::DoubleClickInMultibuffer>(render_dropdown)
|
||||
.add_basic_renderer::<settings::GoToDefinitionFallback>(render_dropdown)
|
||||
.add_basic_renderer::<settings::ActivateOnClose>(render_dropdown)
|
||||
.add_basic_renderer::<settings::ShowDiagnostics>(render_dropdown)
|
||||
.add_basic_renderer::<settings::ShowCloseButton>(render_dropdown)
|
||||
.add_basic_renderer::<settings::ProjectPanelEntrySpacing>(render_dropdown)
|
||||
.add_basic_renderer::<settings::RewrapBehavior>(render_dropdown)
|
||||
.add_basic_renderer::<settings::FormatOnSave>(render_dropdown)
|
||||
.add_basic_renderer::<settings::IndentGuideColoring>(render_dropdown)
|
||||
.add_basic_renderer::<settings::IndentGuideBackgroundColoring>(render_dropdown)
|
||||
.add_basic_renderer::<settings::FileFinderWidthContent>(render_dropdown)
|
||||
.add_basic_renderer::<settings::ShowDiagnostics>(render_dropdown)
|
||||
.add_basic_renderer::<settings::WordsCompletionMode>(render_dropdown)
|
||||
.add_basic_renderer::<settings::LspInsertMode>(render_dropdown)
|
||||
.add_basic_renderer::<settings::AlternateScroll>(render_dropdown)
|
||||
.add_basic_renderer::<settings::TerminalBlink>(render_dropdown)
|
||||
.add_basic_renderer::<settings::CursorShapeContent>(render_dropdown)
|
||||
.add_basic_renderer::<f32>(render_number_field)
|
||||
.add_basic_renderer::<u32>(render_number_field)
|
||||
.add_basic_renderer::<u64>(render_number_field)
|
||||
.add_basic_renderer::<usize>(render_number_field)
|
||||
.add_basic_renderer::<NonZero<usize>>(render_number_field)
|
||||
.add_basic_renderer::<NonZeroU32>(render_number_field)
|
||||
.add_basic_renderer::<CodeFade>(render_number_field)
|
||||
.add_basic_renderer::<FontWeight>(render_number_field)
|
||||
.add_basic_renderer::<settings::MinimumContrast>(render_number_field)
|
||||
.add_basic_renderer::<settings::ShowScrollbar>(render_dropdown)
|
||||
.add_basic_renderer::<settings::ScrollbarDiagnostics>(render_dropdown)
|
||||
.add_basic_renderer::<settings::ShowMinimap>(render_dropdown)
|
||||
.add_basic_renderer::<settings::DisplayIn>(render_dropdown)
|
||||
.add_basic_renderer::<settings::MinimapThumb>(render_dropdown)
|
||||
.add_basic_renderer::<settings::MinimapThumbBorder>(render_dropdown)
|
||||
.add_basic_renderer::<settings::SteppingGranularity>(render_dropdown);
|
||||
// .add_renderer::<ThemeSelection>(|settings_field, file, _, window, cx| {
|
||||
// render_dropdown(*settings_field, file, window, cx)
|
||||
// });
|
||||
@@ -636,14 +530,48 @@ impl SettingsPageItem {
|
||||
.into_any_element(),
|
||||
SettingsPageItem::SettingItem(setting_item) => {
|
||||
let renderer = cx.default_global::<SettingFieldRenderer>().clone();
|
||||
let (found_in_file, found) = setting_item.field.file_set_in(file.clone(), cx);
|
||||
let file_set_in = SettingsUiFile::from_settings(found_in_file);
|
||||
let (_, found) = setting_item.field.file_set_in(file.clone(), cx);
|
||||
|
||||
h_flex()
|
||||
.id(setting_item.title)
|
||||
.min_w_0()
|
||||
.gap_2()
|
||||
.justify_between()
|
||||
let renderers = renderer.renderers.borrow();
|
||||
let field_renderer =
|
||||
renderers.get(&AnySettingField::type_id(setting_item.field.as_ref()));
|
||||
let field_renderer_or_warning =
|
||||
field_renderer.ok_or("NO RENDERER").and_then(|renderer| {
|
||||
if cfg!(debug_assertions) && !found {
|
||||
Err("NO DEFAULT")
|
||||
} else {
|
||||
Ok(renderer)
|
||||
}
|
||||
});
|
||||
|
||||
let field = match field_renderer_or_warning {
|
||||
Ok(field_renderer) => field_renderer(
|
||||
settings_window,
|
||||
setting_item,
|
||||
file,
|
||||
setting_item.metadata.as_deref(),
|
||||
window,
|
||||
cx,
|
||||
),
|
||||
Err(warning) => render_settings_item(
|
||||
settings_window,
|
||||
setting_item,
|
||||
file,
|
||||
Button::new("error-warning", warning)
|
||||
.style(ButtonStyle::Outlined)
|
||||
.size(ButtonSize::Medium)
|
||||
.icon(Some(IconName::Debug))
|
||||
.icon_position(IconPosition::Start)
|
||||
.icon_color(Color::Error)
|
||||
.tab_index(0_isize)
|
||||
.tooltip(Tooltip::text(setting_item.field.type_name()))
|
||||
.into_any_element(),
|
||||
window,
|
||||
cx,
|
||||
),
|
||||
};
|
||||
|
||||
field
|
||||
.pt_4()
|
||||
.map(|this| {
|
||||
if is_last {
|
||||
@@ -654,58 +582,6 @@ impl SettingsPageItem {
|
||||
.border_color(cx.theme().colors().border_variant)
|
||||
}
|
||||
})
|
||||
.child(
|
||||
v_flex()
|
||||
.w_full()
|
||||
.max_w_1_2()
|
||||
.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.gap_1()
|
||||
.child(Label::new(SharedString::new_static(setting_item.title)))
|
||||
.when_some(
|
||||
file_set_in.filter(|file_set_in| file_set_in != &file),
|
||||
|this, file_set_in| {
|
||||
this.child(
|
||||
Label::new(format!(
|
||||
"— set in {}",
|
||||
settings_window
|
||||
.display_name(&file_set_in)
|
||||
.expect("File name should exist")
|
||||
))
|
||||
.color(Color::Muted)
|
||||
.size(LabelSize::Small),
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
.child(
|
||||
Label::new(SharedString::new_static(setting_item.description))
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted),
|
||||
),
|
||||
)
|
||||
.child(if cfg!(debug_assertions) && !found {
|
||||
Button::new("no-default-field", "NO DEFAULT")
|
||||
.size(ButtonSize::Medium)
|
||||
.icon(IconName::XCircle)
|
||||
.icon_position(IconPosition::Start)
|
||||
.icon_color(Color::Error)
|
||||
.icon_size(IconSize::Small)
|
||||
.style(ButtonStyle::Outlined)
|
||||
.tooltip(Tooltip::text(
|
||||
"This warning is only displayed in dev builds.",
|
||||
))
|
||||
.into_any_element()
|
||||
} else {
|
||||
renderer.render(
|
||||
setting_item.field.as_ref(),
|
||||
file,
|
||||
setting_item.metadata.as_deref(),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.into_any_element()
|
||||
}
|
||||
SettingsPageItem::SubPageLink(sub_page_link) => h_flex()
|
||||
@@ -747,6 +623,55 @@ impl SettingsPageItem {
|
||||
}
|
||||
}
|
||||
|
||||
fn render_settings_item(
|
||||
settings_window: &SettingsWindow,
|
||||
setting_item: &SettingItem,
|
||||
file: SettingsUiFile,
|
||||
control: AnyElement,
|
||||
_window: &mut Window,
|
||||
cx: &mut Context<'_, SettingsWindow>,
|
||||
) -> Stateful<Div> {
|
||||
let (found_in_file, _) = setting_item.field.file_set_in(file.clone(), cx);
|
||||
let file_set_in = SettingsUiFile::from_settings(found_in_file);
|
||||
|
||||
h_flex()
|
||||
.id(setting_item.title)
|
||||
.min_w_0()
|
||||
.gap_2()
|
||||
.justify_between()
|
||||
.child(
|
||||
v_flex()
|
||||
.w_1_2()
|
||||
.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.gap_1()
|
||||
.child(Label::new(SharedString::new_static(setting_item.title)))
|
||||
.when_some(
|
||||
file_set_in.filter(|file_set_in| file_set_in != &file),
|
||||
|this, file_set_in| {
|
||||
this.child(
|
||||
Label::new(format!(
|
||||
"— set in {}",
|
||||
settings_window
|
||||
.display_name(&file_set_in)
|
||||
.expect("File name should exist")
|
||||
))
|
||||
.color(Color::Muted)
|
||||
.size(LabelSize::Small),
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
.child(
|
||||
Label::new(SharedString::new_static(setting_item.description))
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted),
|
||||
),
|
||||
)
|
||||
.child(control)
|
||||
}
|
||||
|
||||
struct SettingItem {
|
||||
title: &'static str,
|
||||
description: &'static str,
|
||||
@@ -2157,6 +2082,7 @@ fn render_text_field<T: From<String> + Into<String> + AsRef<str> + Clone>(
|
||||
field: SettingField<T>,
|
||||
file: SettingsUiFile,
|
||||
metadata: Option<&SettingsFieldMetadata>,
|
||||
_window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> AnyElement {
|
||||
let (_, initial_text) =
|
||||
@@ -2186,6 +2112,8 @@ fn render_text_field<T: From<String> + Into<String> + AsRef<str> + Clone>(
|
||||
fn render_toggle_button<B: Into<bool> + From<bool> + Copy>(
|
||||
field: SettingField<B>,
|
||||
file: SettingsUiFile,
|
||||
_metadata: Option<&SettingsFieldMetadata>,
|
||||
_window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> AnyElement {
|
||||
let (_, value) = SettingsStore::global(cx).get_value_from_file(file.to_settings(), field.pick);
|
||||
@@ -2215,6 +2143,7 @@ fn render_toggle_button<B: Into<bool> + From<bool> + Copy>(
|
||||
fn render_font_picker(
|
||||
field: SettingField<settings::FontFamilyName>,
|
||||
file: SettingsUiFile,
|
||||
_metadata: Option<&SettingsFieldMetadata>,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> AnyElement {
|
||||
@@ -2262,6 +2191,7 @@ fn render_font_picker(
|
||||
fn render_number_field<T: NumberFieldType + Send + Sync>(
|
||||
field: SettingField<T>,
|
||||
file: SettingsUiFile,
|
||||
_metadata: Option<&SettingsFieldMetadata>,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> AnyElement {
|
||||
@@ -2283,6 +2213,7 @@ fn render_number_field<T: NumberFieldType + Send + Sync>(
|
||||
fn render_dropdown<T>(
|
||||
field: SettingField<T>,
|
||||
file: SettingsUiFile,
|
||||
_metadata: Option<&SettingsFieldMetadata>,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> AnyElement
|
||||
|
||||
Reference in New Issue
Block a user