Add preference section navigation
This commit is contained in:
@@ -312,13 +312,23 @@ fn update_runtime_config(runtime_config: &RwLock<Config>, config: &Config) {
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub(super) fn open_preferences(&mut self) {
|
||||
pub(super) fn open_preferences(&mut self) -> Task<Message> {
|
||||
if let Some(id) = self.preferences_window {
|
||||
return window::gain_focus(id);
|
||||
}
|
||||
if self.database.is_none() || self.pending_project_path.is_some() || self.choosing_folder {
|
||||
return;
|
||||
return Task::none();
|
||||
}
|
||||
self.preference_draft = PreferenceDraft::from_saved(&self.config);
|
||||
self.preference_error = None;
|
||||
self.preferences_open = true;
|
||||
let (id, open) = window::open(window::Settings {
|
||||
size: Size::new(920.0, 700.0),
|
||||
min_size: Some(Size::new(720.0, 480.0)),
|
||||
icon: Some(app_icon()),
|
||||
..Default::default()
|
||||
});
|
||||
self.preferences_window = Some(id);
|
||||
open.map(Message::PreferencesOpened)
|
||||
}
|
||||
|
||||
pub(super) fn save_preferences(&mut self) {
|
||||
@@ -413,7 +423,6 @@ impl App {
|
||||
self._endpoint = Some(endpoint);
|
||||
}
|
||||
self.preference_draft = PreferenceDraft::from_saved(&self.config);
|
||||
self.preferences_open = false;
|
||||
self.preference_error = None;
|
||||
self.error = None;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ use model_manager::{download_status_bar, format_bytes, format_duration};
|
||||
|
||||
use super::{
|
||||
ActiveDownload, App, DetailTab, MAX_SIDEBAR_WIDTH, MIN_SIDEBAR_WIDTH, Message, MetricsPoint,
|
||||
ModelDownload, ModelOperation, chat_scroll_id, composer_id, models_path, preferences_scroll_id,
|
||||
ModelDownload, ModelOperation, PreferenceSection, chat_scroll_id, composer_id, models_path,
|
||||
preferences_scroll_id,
|
||||
};
|
||||
use crate::database::{ProjectWithSessions, Session, SessionState};
|
||||
use crate::model::{
|
||||
@@ -53,7 +54,9 @@ const TRAFFIC_LIGHT_WIDTH: f32 = 78.0;
|
||||
|
||||
impl App {
|
||||
pub(crate) fn view(&self, id: window::Id) -> Element<'_, Message> {
|
||||
let content = if self.model_manager_window == Some(id) {
|
||||
let content = if self.preferences_window == Some(id) {
|
||||
self.preferences_panel()
|
||||
} else if self.model_manager_window == Some(id) {
|
||||
self.model_manager()
|
||||
} else if self.help_window == Some(id) {
|
||||
self.help_view()
|
||||
@@ -98,8 +101,7 @@ impl App {
|
||||
/// Whether a dialog covers the window. Focus moves through the whole widget
|
||||
/// tree, so the layers below have to stay out of the dialog's field order.
|
||||
pub(super) fn modal_open(&self) -> bool {
|
||||
self.preferences_open
|
||||
|| self.pending_project_path.is_some()
|
||||
self.pending_project_path.is_some()
|
||||
|| self.pending_session_delete.is_some()
|
||||
|| self.session_rename.is_some()
|
||||
|| self.menu_session().is_some()
|
||||
@@ -161,8 +163,6 @@ impl App {
|
||||
#[cfg(target_os = "macos")]
|
||||
if let Some((prompt, _)) = &self.pending_tool_approval {
|
||||
layers.push(self.tool_approval_panel(prompt));
|
||||
} else if self.preferences_open {
|
||||
layers.push(self.preferences_panel());
|
||||
} else if let Some(path) = &self.pending_project_path {
|
||||
layers.push(self.project_dialog(path));
|
||||
} else if let Some((_, title)) = &self.session_rename {
|
||||
@@ -177,9 +177,7 @@ impl App {
|
||||
layers.push(panel);
|
||||
}
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
if self.preferences_open {
|
||||
layers.push(self.preferences_panel());
|
||||
} else if let Some(path) = &self.pending_project_path {
|
||||
if let Some(path) = &self.pending_project_path {
|
||||
layers.push(self.project_dialog(path));
|
||||
} else if let Some((_, title)) = &self.session_rename {
|
||||
layers.push(self.rename_dialog(title));
|
||||
@@ -780,10 +778,12 @@ fn hint<'a>(title: impl Into<Element<'a, Message>>, description: &'a str) -> Too
|
||||
}
|
||||
|
||||
fn preference_group<'a>(
|
||||
section: PreferenceSection,
|
||||
title: &'a str,
|
||||
content: impl Into<Element<'a, Message>>,
|
||||
) -> Element<'a, Message> {
|
||||
container(column![text(title).size(11).color(muted_text()), content.into(),].spacing(10))
|
||||
.id(iced::widget::Id::new(section.anchor()))
|
||||
.width(Length::Fill)
|
||||
.padding(14)
|
||||
.style(preference_group_style)
|
||||
|
||||
@@ -81,6 +81,7 @@ impl App {
|
||||
}
|
||||
|
||||
let model_group = preference_group(
|
||||
PreferenceSection::Model,
|
||||
"MODEL & LIFECYCLE",
|
||||
column![
|
||||
hint(
|
||||
@@ -129,6 +130,7 @@ impl App {
|
||||
.spacing(10),
|
||||
);
|
||||
let endpoint_group = preference_group(
|
||||
PreferenceSection::Endpoint,
|
||||
"LOCAL ENDPOINT",
|
||||
column![
|
||||
hint(
|
||||
@@ -155,6 +157,7 @@ impl App {
|
||||
.spacing(10),
|
||||
);
|
||||
let generation_group = preference_group(
|
||||
PreferenceSection::Generation,
|
||||
"GENERATION",
|
||||
column![
|
||||
preference_input_row(
|
||||
@@ -239,6 +242,7 @@ impl App {
|
||||
.spacing(10),
|
||||
);
|
||||
let execution_group = preference_group(
|
||||
PreferenceSection::Execution,
|
||||
"EXECUTION",
|
||||
column![
|
||||
preference_input_row(
|
||||
@@ -295,6 +299,7 @@ impl App {
|
||||
.spacing(10),
|
||||
);
|
||||
let acceleration_group = preference_group(
|
||||
PreferenceSection::Acceleration,
|
||||
"ACCELERATION & MEMORY",
|
||||
column![
|
||||
text("SPECULATIVE DECODING").size(11).color(muted_text()),
|
||||
@@ -424,6 +429,7 @@ impl App {
|
||||
.spacing(10),
|
||||
);
|
||||
let steering_group = preference_group(
|
||||
PreferenceSection::Steering,
|
||||
"STEERING & DIAGNOSTICS",
|
||||
column![
|
||||
text("DIRECTIONAL STEERING").size(11).color(muted_text()),
|
||||
@@ -493,6 +499,7 @@ impl App {
|
||||
.spacing(10),
|
||||
);
|
||||
let kv_cache_group = preference_group(
|
||||
PreferenceSection::KvCache,
|
||||
"KV CACHE",
|
||||
column![
|
||||
preference_input_row(
|
||||
@@ -556,45 +563,60 @@ impl App {
|
||||
if let Some(error) = &self.preference_error {
|
||||
fields = fields.push(text(error).style(iced::widget::text::danger));
|
||||
}
|
||||
let header = row![
|
||||
icon(ICON_SETTINGS, 22),
|
||||
text("Preferences").size(24),
|
||||
Space::new().width(Length::Fill),
|
||||
text("⌘,").size(12),
|
||||
]
|
||||
.spacing(10)
|
||||
.align_y(Alignment::Center);
|
||||
let navigation = PreferenceSection::ALL.iter().fold(
|
||||
column![
|
||||
row![icon(ICON_SETTINGS, 20), text("Preferences").size(20)]
|
||||
.spacing(9)
|
||||
.align_y(Alignment::Center),
|
||||
text("Jump to section").size(12).color(muted_text()),
|
||||
rule::horizontal(1),
|
||||
]
|
||||
.spacing(8),
|
||||
|navigation, section| {
|
||||
navigation.push(
|
||||
button(text(section.label()).size(13))
|
||||
.on_press(Message::ScrollPreferences(*section))
|
||||
.width(Length::Fill)
|
||||
.padding([8, 10])
|
||||
.style(button::text),
|
||||
)
|
||||
},
|
||||
);
|
||||
let footer = row![
|
||||
action_button("Reset DS4 defaults").on_press(Message::ResetPreferences),
|
||||
Space::new().width(Length::Fill),
|
||||
action_button("Cancel").on_press(Message::DismissPanel),
|
||||
action_button("Cancel").on_press(Message::ClosePreferences),
|
||||
action_button("Save").on_press(Message::SavePreferences),
|
||||
]
|
||||
.spacing(8);
|
||||
|
||||
let panel = container(
|
||||
column![
|
||||
header,
|
||||
scrollable(container(fields).padding(iced::Padding::ZERO.right(18)))
|
||||
.id(preferences_scroll_id())
|
||||
.height(Length::Fill),
|
||||
footer
|
||||
]
|
||||
.spacing(16),
|
||||
)
|
||||
.padding(24)
|
||||
.width(700)
|
||||
container(row![
|
||||
container(navigation)
|
||||
.width(210)
|
||||
.height(Length::Fill)
|
||||
.padding(20)
|
||||
.style(sidebar_style),
|
||||
container(
|
||||
column![
|
||||
row![
|
||||
text("Settings").size(24),
|
||||
Space::new().width(Length::Fill),
|
||||
text("⌘,").size(12).color(muted_text()),
|
||||
]
|
||||
.align_y(Alignment::Center),
|
||||
scrollable(container(fields).padding(iced::Padding::ZERO.right(18)))
|
||||
.id(preferences_scroll_id())
|
||||
.height(Length::Fill),
|
||||
footer,
|
||||
]
|
||||
.spacing(16),
|
||||
)
|
||||
.padding(24)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill),
|
||||
])
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.max_height(660)
|
||||
.style(overview_style);
|
||||
opaque(
|
||||
container(panel)
|
||||
.padding(24)
|
||||
.center_x(Length::Fill)
|
||||
.center_y(Length::Fill)
|
||||
.style(|_| {
|
||||
container::Style::default().background(Color::from_rgba8(0, 0, 0, 0.68))
|
||||
}),
|
||||
)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user