fix(settings): open image provider menu
This commit is contained in:
parent
0b72d14b8a
commit
3d1c0b6ae1
|
|
@ -437,6 +437,7 @@ pub struct AgentSettings {
|
|||
pub openverse_client_secret: String,
|
||||
pub image_gen_profiles: Vec<ImageGenProfile>,
|
||||
pub active_image_gen_profile_id: Option<String>,
|
||||
pub image_gen_provider_menu_open: Option<usize>,
|
||||
pub next_image_gen_profile_id: u64,
|
||||
/// Whether the desktop host should check GitHub releases on
|
||||
/// startup. Manual "Check for Updates" stays available.
|
||||
|
|
@ -477,6 +478,7 @@ impl Default for AgentSettings {
|
|||
openverse_client_secret: String::new(),
|
||||
image_gen_profiles: Vec::new(),
|
||||
active_image_gen_profile_id: None,
|
||||
image_gen_provider_menu_open: None,
|
||||
next_image_gen_profile_id: 1,
|
||||
auto_update_enabled: true,
|
||||
focus: None,
|
||||
|
|
@ -737,6 +739,7 @@ impl AgentSettings {
|
|||
if self.image_gen_profiles.len() == before {
|
||||
return false;
|
||||
}
|
||||
self.image_gen_provider_menu_open = None;
|
||||
if self.active_image_gen_profile_id.as_deref() == Some(id) {
|
||||
self.active_image_gen_profile_id =
|
||||
self.image_gen_profiles.first().map(|p| p.id.clone());
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ fn default_settings_are_quiescent() {
|
|||
assert!(s.acp_agent_draft.is_none());
|
||||
assert!(s.image_gen_profiles.is_empty());
|
||||
assert!(s.active_image_gen_profile_id.is_none());
|
||||
assert!(s.image_gen_provider_menu_open.is_none());
|
||||
assert!(!s.images_advanced_open);
|
||||
assert!(s.openverse_client_id.is_empty());
|
||||
assert!(s.openverse_client_secret.is_empty());
|
||||
|
|
|
|||
|
|
@ -1,18 +1,17 @@
|
|||
//! Images tab of the settings modal.
|
||||
|
||||
use crate::theme::Theme;
|
||||
use crate::widgets::agent_settings_caret::{
|
||||
caret_x_for_text, paint_caret, settings_caret_for_focus,
|
||||
};
|
||||
use crate::widgets::agent_settings_i18n::t as t_settings;
|
||||
use crate::widgets::agent_settings_images_parts::{
|
||||
ellipsize, paint_search_input_row, rect_contains,
|
||||
ellipsize, paint_profile_field, paint_profile_test_button, paint_provider_field,
|
||||
paint_provider_menu, paint_search_input_row, rect_contains,
|
||||
};
|
||||
use crate::widgets::icons::{draw_icon, Icon};
|
||||
use crate::widgets::PaintCx;
|
||||
use crate::{Color, Point2D, Rect, TextLayout};
|
||||
use op_editor_core::agent_settings::{
|
||||
AgentSettings, ImageGenField, ImageGenProfile, ImageSearchField, SettingsFocus,
|
||||
AgentSettings, ImageGenField, ImageGenProfile, ImageGenProvider, ImageSearchField,
|
||||
SettingsFocus,
|
||||
};
|
||||
use op_editor_core::editor_ui_state::EditorUiState;
|
||||
|
||||
|
|
@ -38,6 +37,7 @@ const PROFILE_FORM_TOP: f32 = 40.0;
|
|||
const PROFILE_FIELD_H: f32 = 24.0;
|
||||
const PROFILE_TEST_BTN_W: f32 = 56.0;
|
||||
const PROFILE_TEST_GAP: f32 = 8.0;
|
||||
const PROVIDER_OPTION_H: f32 = 24.0;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ImagesHit {
|
||||
|
|
@ -49,8 +49,15 @@ pub enum ImagesHit {
|
|||
SetActiveGenConfig(usize),
|
||||
RemoveGenConfig(usize),
|
||||
TestGenConfig(usize),
|
||||
CycleGenProvider(usize),
|
||||
FocusGenConfig { index: usize, field: ImageGenField },
|
||||
ToggleGenProviderMenu(usize),
|
||||
SelectGenProvider {
|
||||
index: usize,
|
||||
provider: ImageGenProvider,
|
||||
},
|
||||
FocusGenConfig {
|
||||
index: usize,
|
||||
field: ImageGenField,
|
||||
},
|
||||
None,
|
||||
}
|
||||
|
||||
|
|
@ -235,6 +242,17 @@ fn profile_provider_rect(row: Rect) -> Rect {
|
|||
profile_field_rect(row, 1)
|
||||
}
|
||||
|
||||
fn profile_provider_option_rect(row: Rect, option_index: usize) -> Rect {
|
||||
let provider = profile_provider_rect(row);
|
||||
Rect {
|
||||
origin: Point2D::new(
|
||||
provider.origin.x,
|
||||
provider.origin.y + provider.size.y + option_index as f32 * PROVIDER_OPTION_H,
|
||||
),
|
||||
size: Point2D::new(provider.size.x, PROVIDER_OPTION_H),
|
||||
}
|
||||
}
|
||||
|
||||
fn profile_field_index(field: ImageGenField) -> usize {
|
||||
match field {
|
||||
ImageGenField::Name => 0,
|
||||
|
|
@ -266,6 +284,16 @@ pub fn hit_test(content: Rect, settings: &AgentSettings, scrolled: Point2D) -> I
|
|||
}
|
||||
for (index, profile) in settings.image_gen_profiles.iter().enumerate() {
|
||||
let row = profile_row_rect(content, settings, index);
|
||||
if settings.image_gen_provider_menu_open == Some(index) {
|
||||
for (option_index, provider) in ImageGenProvider::ALL.iter().enumerate() {
|
||||
if rect_contains(profile_provider_option_rect(row, option_index), scrolled) {
|
||||
return ImagesHit::SelectGenProvider {
|
||||
index,
|
||||
provider: *provider,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
if rect_contains(profile_active_rect(row), scrolled) {
|
||||
return ImagesHit::SetActiveGenConfig(index);
|
||||
}
|
||||
|
|
@ -283,7 +311,7 @@ pub fn hit_test(content: Rect, settings: &AgentSettings, scrolled: Point2D) -> I
|
|||
return ImagesHit::None;
|
||||
}
|
||||
if rect_contains(profile_provider_rect(row), scrolled) {
|
||||
return ImagesHit::CycleGenProvider(index);
|
||||
return ImagesHit::ToggleGenProviderMenu(index);
|
||||
}
|
||||
for field in image_gen_fields() {
|
||||
if rect_contains(profile_input_rect(row, field), scrolled) {
|
||||
|
|
@ -628,168 +656,28 @@ fn paint_profile_row(
|
|||
|
||||
if editing {
|
||||
for field in image_gen_fields() {
|
||||
paint_profile_field(cx, theme, settings, ui, profile, index, field, row, now_ms);
|
||||
paint_profile_field(
|
||||
cx,
|
||||
theme,
|
||||
settings,
|
||||
ui,
|
||||
profile,
|
||||
index,
|
||||
field,
|
||||
profile_input_rect(row, field),
|
||||
row.origin.x + 12.0,
|
||||
now_ms,
|
||||
);
|
||||
}
|
||||
paint_profile_test_button(cx, theme, ui, profile, row);
|
||||
paint_provider_field(cx, theme, profile, row);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn paint_profile_field(
|
||||
cx: &mut PaintCx<'_>,
|
||||
theme: &Theme,
|
||||
settings: &AgentSettings,
|
||||
ui: &EditorUiState,
|
||||
profile: &ImageGenProfile,
|
||||
index: usize,
|
||||
field: ImageGenField,
|
||||
row: Rect,
|
||||
now_ms: u64,
|
||||
) {
|
||||
let focus = SettingsFocus::ImageGenProfile { index, field };
|
||||
let focused = settings.focus == Some(focus);
|
||||
let value = if focused {
|
||||
ui.settings_input_draft.as_str()
|
||||
} else {
|
||||
match field {
|
||||
ImageGenField::Name => profile.name.as_str(),
|
||||
ImageGenField::ApiKey if !profile.api_key.is_empty() => "********",
|
||||
ImageGenField::ApiKey => "",
|
||||
ImageGenField::Model => profile.model.as_str(),
|
||||
ImageGenField::BaseUrl => profile.base_url.as_deref().unwrap_or(""),
|
||||
paint_profile_test_button(cx, theme, ui, profile, profile_test_btn_rect(row));
|
||||
let provider_rect = profile_provider_rect(row);
|
||||
paint_provider_field(cx, theme, profile, provider_rect, row.origin.x + 12.0);
|
||||
if settings.image_gen_provider_menu_open == Some(index) {
|
||||
paint_provider_menu(cx, theme, provider_rect, profile.provider);
|
||||
}
|
||||
};
|
||||
let label = match field {
|
||||
ImageGenField::Name => "Name",
|
||||
ImageGenField::ApiKey => "API Key",
|
||||
ImageGenField::Model => "Model",
|
||||
ImageGenField::BaseUrl => "Base URL",
|
||||
};
|
||||
let input = profile_input_rect(row, field);
|
||||
let label_lay = TextLayout::single_run(
|
||||
label,
|
||||
"system-ui",
|
||||
11.0,
|
||||
to_jian(theme.muted_foreground),
|
||||
Point2D::new(0.0, 0.0),
|
||||
);
|
||||
cx.backend.draw_text(
|
||||
&label_lay,
|
||||
Point2D::new(row.origin.x + 12.0, input.origin.y + 16.0),
|
||||
);
|
||||
cx.backend.fill_round_rect(
|
||||
input,
|
||||
6.0,
|
||||
if focused {
|
||||
theme.background
|
||||
} else {
|
||||
theme.card
|
||||
},
|
||||
);
|
||||
cx.backend.stroke_round_rect(
|
||||
input,
|
||||
6.0,
|
||||
if focused { theme.primary } else { theme.border },
|
||||
1.0,
|
||||
);
|
||||
let clipped = ellipsize(cx, value, input.size.x - 12.0, 11.0);
|
||||
let text_x = input.origin.x + 6.0;
|
||||
let value_lay = TextLayout::single_run(
|
||||
&clipped,
|
||||
"system-ui",
|
||||
11.0,
|
||||
to_jian(theme.foreground),
|
||||
Point2D::new(0.0, 0.0),
|
||||
);
|
||||
cx.backend
|
||||
.draw_text(&value_lay, Point2D::new(text_x, input.origin.y + 16.0));
|
||||
if focused {
|
||||
let caret = settings_caret_for_focus(ui, focus);
|
||||
let caret_x = caret_x_for_text(
|
||||
cx,
|
||||
value,
|
||||
caret,
|
||||
text_x,
|
||||
input.origin.x + input.size.x - 8.0,
|
||||
11.0,
|
||||
);
|
||||
let caret_y = input.origin.y + 4.5;
|
||||
let anchor = ui.settings_input_caret_anchor_ms;
|
||||
paint_caret(cx, theme, now_ms, anchor, caret_x, caret_y);
|
||||
}
|
||||
}
|
||||
|
||||
fn paint_profile_test_button(
|
||||
cx: &mut PaintCx<'_>,
|
||||
theme: &Theme,
|
||||
ui: &EditorUiState,
|
||||
profile: &ImageGenProfile,
|
||||
row: Rect,
|
||||
) {
|
||||
let btn = profile_test_btn_rect(row);
|
||||
let enabled = !profile.api_key.trim().is_empty();
|
||||
cx.backend.fill_round_rect(btn, 6.0, theme.muted);
|
||||
cx.backend.stroke_round_rect(btn, 6.0, theme.border, 1.0);
|
||||
let label = t_settings(ui, "settings.images.test");
|
||||
let label_w = cx.backend.measure_text(label, 11.0);
|
||||
let layout = TextLayout::single_run(
|
||||
label,
|
||||
"system-ui",
|
||||
11.0,
|
||||
to_jian(if enabled {
|
||||
theme.foreground
|
||||
} else {
|
||||
theme.muted_foreground
|
||||
}),
|
||||
Point2D::new(0.0, 0.0),
|
||||
);
|
||||
cx.backend.draw_text(
|
||||
&layout,
|
||||
Point2D::new(
|
||||
btn.origin.x + (btn.size.x - label_w) / 2.0,
|
||||
btn.origin.y + btn.size.y / 2.0 + 4.0,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
fn paint_provider_field(cx: &mut PaintCx<'_>, theme: &Theme, profile: &ImageGenProfile, row: Rect) {
|
||||
let input = profile_provider_rect(row);
|
||||
let label_lay = TextLayout::single_run(
|
||||
"Provider",
|
||||
"system-ui",
|
||||
11.0,
|
||||
to_jian(theme.muted_foreground),
|
||||
Point2D::new(0.0, 0.0),
|
||||
);
|
||||
cx.backend.draw_text(
|
||||
&label_lay,
|
||||
Point2D::new(row.origin.x + 12.0, input.origin.y + 16.0),
|
||||
);
|
||||
cx.backend.fill_round_rect(input, 6.0, theme.card);
|
||||
cx.backend.stroke_round_rect(input, 6.0, theme.border, 1.0);
|
||||
let value = ellipsize(cx, profile.provider.label(), input.size.x - 28.0, 11.0);
|
||||
let value_lay = TextLayout::single_run(
|
||||
&value,
|
||||
"system-ui",
|
||||
11.0,
|
||||
to_jian(theme.foreground),
|
||||
Point2D::new(0.0, 0.0),
|
||||
);
|
||||
cx.backend.draw_text(
|
||||
&value_lay,
|
||||
Point2D::new(input.origin.x + 6.0, input.origin.y + 16.0),
|
||||
);
|
||||
draw_icon(
|
||||
cx.backend,
|
||||
Icon::ChevronDown,
|
||||
Point2D::new(input.origin.x + input.size.x - 18.0, input.origin.y + 5.0),
|
||||
14.0,
|
||||
theme.muted_foreground,
|
||||
1.5,
|
||||
);
|
||||
}
|
||||
|
||||
fn image_gen_fields() -> [ImageGenField; 4] {
|
||||
use ImageGenField::*;
|
||||
[Name, ApiKey, Model, BaseUrl]
|
||||
|
|
|
|||
|
|
@ -4,13 +4,18 @@ use crate::theme::Theme;
|
|||
use crate::widgets::agent_settings_caret::{
|
||||
caret_x_for_text, paint_caret, settings_caret_for_focus,
|
||||
};
|
||||
use crate::widgets::icons::{draw_icon, Icon};
|
||||
use crate::widgets::PaintCx;
|
||||
use crate::{Color, Point2D, Rect, TextLayout};
|
||||
use op_editor_core::agent_settings::{AgentSettings, ImageSearchField, SettingsFocus};
|
||||
use op_editor_core::agent_settings::{
|
||||
AgentSettings, ImageGenField, ImageGenProfile, ImageGenProvider, ImageSearchField,
|
||||
SettingsFocus,
|
||||
};
|
||||
use op_editor_core::editor_ui_state::EditorUiState;
|
||||
|
||||
const ROW_H: f32 = 36.0;
|
||||
const LABEL_W: f32 = 110.0;
|
||||
const PROVIDER_OPTION_H: f32 = 24.0;
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(super) fn paint_search_input_row(
|
||||
|
|
@ -98,6 +103,205 @@ pub(super) fn paint_search_input_row(
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(super) fn paint_profile_field(
|
||||
cx: &mut PaintCx<'_>,
|
||||
theme: &Theme,
|
||||
settings: &AgentSettings,
|
||||
ui: &EditorUiState,
|
||||
profile: &ImageGenProfile,
|
||||
index: usize,
|
||||
field: ImageGenField,
|
||||
input: Rect,
|
||||
label_x: f32,
|
||||
now_ms: u64,
|
||||
) {
|
||||
let focus = SettingsFocus::ImageGenProfile { index, field };
|
||||
let focused = settings.focus == Some(focus);
|
||||
let value = if focused {
|
||||
ui.settings_input_draft.as_str()
|
||||
} else {
|
||||
match field {
|
||||
ImageGenField::Name => profile.name.as_str(),
|
||||
ImageGenField::ApiKey if !profile.api_key.is_empty() => "********",
|
||||
ImageGenField::ApiKey => "",
|
||||
ImageGenField::Model => profile.model.as_str(),
|
||||
ImageGenField::BaseUrl => profile.base_url.as_deref().unwrap_or(""),
|
||||
}
|
||||
};
|
||||
let label = match field {
|
||||
ImageGenField::Name => "Name",
|
||||
ImageGenField::ApiKey => "API Key",
|
||||
ImageGenField::Model => "Model",
|
||||
ImageGenField::BaseUrl => "Base URL",
|
||||
};
|
||||
let label_lay = TextLayout::single_run(
|
||||
label,
|
||||
"system-ui",
|
||||
11.0,
|
||||
to_jian(theme.muted_foreground),
|
||||
Point2D::new(0.0, 0.0),
|
||||
);
|
||||
cx.backend
|
||||
.draw_text(&label_lay, Point2D::new(label_x, input.origin.y + 16.0));
|
||||
cx.backend.fill_round_rect(
|
||||
input,
|
||||
6.0,
|
||||
if focused {
|
||||
theme.background
|
||||
} else {
|
||||
theme.card
|
||||
},
|
||||
);
|
||||
cx.backend.stroke_round_rect(
|
||||
input,
|
||||
6.0,
|
||||
if focused { theme.primary } else { theme.border },
|
||||
1.0,
|
||||
);
|
||||
let clipped = ellipsize(cx, value, input.size.x - 12.0, 11.0);
|
||||
let text_x = input.origin.x + 6.0;
|
||||
let value_lay = TextLayout::single_run(
|
||||
&clipped,
|
||||
"system-ui",
|
||||
11.0,
|
||||
to_jian(theme.foreground),
|
||||
Point2D::new(0.0, 0.0),
|
||||
);
|
||||
cx.backend
|
||||
.draw_text(&value_lay, Point2D::new(text_x, input.origin.y + 16.0));
|
||||
if focused {
|
||||
let caret = settings_caret_for_focus(ui, focus);
|
||||
let caret_x = caret_x_for_text(
|
||||
cx,
|
||||
value,
|
||||
caret,
|
||||
text_x,
|
||||
input.origin.x + input.size.x - 8.0,
|
||||
11.0,
|
||||
);
|
||||
let caret_y = input.origin.y + 4.5;
|
||||
let anchor = ui.settings_input_caret_anchor_ms;
|
||||
paint_caret(cx, theme, now_ms, anchor, caret_x, caret_y);
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn paint_profile_test_button(
|
||||
cx: &mut PaintCx<'_>,
|
||||
theme: &Theme,
|
||||
ui: &EditorUiState,
|
||||
profile: &ImageGenProfile,
|
||||
btn: Rect,
|
||||
) {
|
||||
let enabled = !profile.api_key.trim().is_empty();
|
||||
cx.backend.fill_round_rect(btn, 6.0, theme.muted);
|
||||
cx.backend.stroke_round_rect(btn, 6.0, theme.border, 1.0);
|
||||
let label = crate::widgets::agent_settings_i18n::t(ui, "settings.images.test");
|
||||
let label_w = cx.backend.measure_text(label, 11.0);
|
||||
let layout = TextLayout::single_run(
|
||||
label,
|
||||
"system-ui",
|
||||
11.0,
|
||||
to_jian(if enabled {
|
||||
theme.foreground
|
||||
} else {
|
||||
theme.muted_foreground
|
||||
}),
|
||||
Point2D::new(0.0, 0.0),
|
||||
);
|
||||
cx.backend.draw_text(
|
||||
&layout,
|
||||
Point2D::new(
|
||||
btn.origin.x + (btn.size.x - label_w) / 2.0,
|
||||
btn.origin.y + btn.size.y / 2.0 + 4.0,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
pub(super) fn paint_provider_field(
|
||||
cx: &mut PaintCx<'_>,
|
||||
theme: &Theme,
|
||||
profile: &ImageGenProfile,
|
||||
input: Rect,
|
||||
label_x: f32,
|
||||
) {
|
||||
let label_lay = TextLayout::single_run(
|
||||
"Provider",
|
||||
"system-ui",
|
||||
11.0,
|
||||
to_jian(theme.muted_foreground),
|
||||
Point2D::new(0.0, 0.0),
|
||||
);
|
||||
cx.backend
|
||||
.draw_text(&label_lay, Point2D::new(label_x, input.origin.y + 16.0));
|
||||
cx.backend.fill_round_rect(input, 6.0, theme.card);
|
||||
cx.backend.stroke_round_rect(input, 6.0, theme.border, 1.0);
|
||||
let value = ellipsize(cx, profile.provider.label(), input.size.x - 28.0, 11.0);
|
||||
let value_lay = TextLayout::single_run(
|
||||
&value,
|
||||
"system-ui",
|
||||
11.0,
|
||||
to_jian(theme.foreground),
|
||||
Point2D::new(0.0, 0.0),
|
||||
);
|
||||
cx.backend.draw_text(
|
||||
&value_lay,
|
||||
Point2D::new(input.origin.x + 6.0, input.origin.y + 16.0),
|
||||
);
|
||||
draw_icon(
|
||||
cx.backend,
|
||||
Icon::ChevronDown,
|
||||
Point2D::new(input.origin.x + input.size.x - 18.0, input.origin.y + 5.0),
|
||||
14.0,
|
||||
theme.muted_foreground,
|
||||
1.5,
|
||||
);
|
||||
}
|
||||
|
||||
pub(super) fn paint_provider_menu(
|
||||
cx: &mut PaintCx<'_>,
|
||||
theme: &Theme,
|
||||
input: Rect,
|
||||
selected: ImageGenProvider,
|
||||
) {
|
||||
let menu = Rect {
|
||||
origin: Point2D::new(input.origin.x, input.origin.y + input.size.y),
|
||||
size: Point2D::new(
|
||||
input.size.x,
|
||||
PROVIDER_OPTION_H * ImageGenProvider::ALL.len() as f32,
|
||||
),
|
||||
};
|
||||
cx.backend.fill_round_rect(menu, 6.0, theme.card);
|
||||
cx.backend.stroke_round_rect(menu, 6.0, theme.border, 1.0);
|
||||
for (index, provider) in ImageGenProvider::ALL.iter().enumerate() {
|
||||
let option_y = menu.origin.y + index as f32 * PROVIDER_OPTION_H;
|
||||
if *provider == selected {
|
||||
cx.backend.fill_round_rect(
|
||||
Rect {
|
||||
origin: Point2D::new(menu.origin.x + 2.0, option_y + 2.0),
|
||||
size: Point2D::new(menu.size.x - 4.0, PROVIDER_OPTION_H - 4.0),
|
||||
},
|
||||
4.0,
|
||||
theme.muted,
|
||||
);
|
||||
}
|
||||
let label = TextLayout::single_run(
|
||||
provider.label(),
|
||||
"system-ui",
|
||||
11.0,
|
||||
to_jian(theme.foreground),
|
||||
Point2D::new(0.0, 0.0),
|
||||
);
|
||||
cx.backend.draw_text(
|
||||
&label,
|
||||
Point2D::new(
|
||||
menu.origin.x + 8.0,
|
||||
option_y + PROVIDER_OPTION_H / 2.0 + 4.0,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn ellipsize(cx: &mut PaintCx<'_>, value: &str, max_w: f32, size: f32) -> String {
|
||||
if cx.backend.measure_text(value, size) <= max_w {
|
||||
return value.to_string();
|
||||
|
|
|
|||
|
|
@ -88,7 +88,11 @@ pub enum AgentSettingsHit {
|
|||
SetActiveGenConfig(usize),
|
||||
RemoveGenConfig(usize),
|
||||
TestGenConfig(usize),
|
||||
CycleGenProvider(usize),
|
||||
ToggleGenProviderMenu(usize),
|
||||
SelectGenProvider {
|
||||
index: usize,
|
||||
provider: op_editor_core::agent_settings::ImageGenProvider,
|
||||
},
|
||||
FocusGenConfig {
|
||||
index: usize,
|
||||
field: ImageGenField,
|
||||
|
|
@ -257,8 +261,11 @@ impl<'a> AgentSettingsPanel<'a> {
|
|||
ImagesHit::TestGenConfig(index) => {
|
||||
return AgentSettingsHit::TestGenConfig(index);
|
||||
}
|
||||
ImagesHit::CycleGenProvider(index) => {
|
||||
return AgentSettingsHit::CycleGenProvider(index);
|
||||
ImagesHit::ToggleGenProviderMenu(index) => {
|
||||
return AgentSettingsHit::ToggleGenProviderMenu(index);
|
||||
}
|
||||
ImagesHit::SelectGenProvider { index, provider } => {
|
||||
return AgentSettingsHit::SelectGenProvider { index, provider };
|
||||
}
|
||||
ImagesHit::FocusGenConfig { index, field } => {
|
||||
return AgentSettingsHit::FocusGenConfig { index, field };
|
||||
|
|
|
|||
|
|
@ -891,6 +891,6 @@ fn images_tab_expanded_profile_provider_row_is_clickable() {
|
|||
rect,
|
||||
crate::Point2D::new(content_x + 110.0 + 20.0, provider_y + 12.0)
|
||||
),
|
||||
AgentSettingsHit::CycleGenProvider(0)
|
||||
AgentSettingsHit::ToggleGenProviderMenu(0)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -612,7 +612,7 @@ fn image_generation_profile_focus_accepts_text_and_commits() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn image_generation_provider_click_cycles_provider_and_clears_model() {
|
||||
fn image_generation_provider_click_opens_menu_without_changing_profile() {
|
||||
let mut host = WidgetHostNative::new();
|
||||
host.editor_state_mut().editor_ui.agent_settings.tab = AgentSettingsTab::Images;
|
||||
host.editor_state_mut()
|
||||
|
|
@ -649,9 +649,28 @@ fn image_generation_provider_click_cycles_provider_and_clears_model() {
|
|||
.editor_ui
|
||||
.agent_settings
|
||||
.image_gen_profiles[0];
|
||||
assert_eq!(profile.provider, ImageGenProvider::OpenAi);
|
||||
assert_eq!(profile.model, "dall-e-3");
|
||||
assert!(host.editor_state().editor_ui.agent_settings.focus.is_none());
|
||||
assert_eq!(
|
||||
host.editor_state()
|
||||
.editor_ui
|
||||
.agent_settings
|
||||
.image_gen_provider_menu_open,
|
||||
Some(0)
|
||||
);
|
||||
|
||||
assert!(host.dispatch_agent_settings_press(
|
||||
content_x + 110.0 + 20.0,
|
||||
provider_y + 60.0,
|
||||
1200.0,
|
||||
800.0
|
||||
));
|
||||
let settings = &host.editor_state().editor_ui.agent_settings;
|
||||
let profile = &settings.image_gen_profiles[0];
|
||||
assert_eq!(profile.provider, ImageGenProvider::Gemini);
|
||||
assert!(profile.model.is_empty());
|
||||
assert!(host.editor_state().editor_ui.agent_settings.focus.is_none());
|
||||
assert!(settings.image_gen_provider_menu_open.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -197,21 +197,29 @@ impl WidgetHostNative {
|
|||
);
|
||||
}
|
||||
}
|
||||
AgentSettingsHit::CycleGenProvider(index) => {
|
||||
AgentSettingsHit::ToggleGenProviderMenu(index) => {
|
||||
self.commit_settings_focus_if_any();
|
||||
if let Some(profile) = self
|
||||
.editor_state
|
||||
.editor_ui
|
||||
.agent_settings
|
||||
.image_gen_profiles
|
||||
.get_mut(index)
|
||||
{
|
||||
profile.provider = profile.provider.next();
|
||||
profile.model.clear();
|
||||
let settings = &mut self.editor_state.editor_ui.agent_settings;
|
||||
settings.image_gen_provider_menu_open =
|
||||
(settings.image_gen_provider_menu_open != Some(index)).then_some(index);
|
||||
}
|
||||
AgentSettingsHit::SelectGenProvider { index, provider } => {
|
||||
self.commit_settings_focus_if_any();
|
||||
let settings = &mut self.editor_state.editor_ui.agent_settings;
|
||||
if let Some(profile) = settings.image_gen_profiles.get_mut(index) {
|
||||
if profile.provider != provider {
|
||||
profile.provider = provider;
|
||||
profile.model.clear();
|
||||
}
|
||||
}
|
||||
settings.image_gen_provider_menu_open = None;
|
||||
}
|
||||
AgentSettingsHit::FocusGenConfig { index, field } => {
|
||||
self.commit_settings_focus_if_any();
|
||||
self.editor_state
|
||||
.editor_ui
|
||||
.agent_settings
|
||||
.image_gen_provider_menu_open = None;
|
||||
self.focus_image_gen_profile(index, field);
|
||||
}
|
||||
AgentSettingsHit::ToggleAutoUpdate => {
|
||||
|
|
|
|||
|
|
@ -181,21 +181,29 @@ impl WidgetHost {
|
|||
self.editor_state.editor_ui.settings_input_caret_anchor_ms = self.now_ms;
|
||||
}
|
||||
}
|
||||
AgentSettingsHit::CycleGenProvider(index) => {
|
||||
AgentSettingsHit::ToggleGenProviderMenu(index) => {
|
||||
self.commit_settings_focus();
|
||||
if let Some(profile) = self
|
||||
.editor_state
|
||||
.editor_ui
|
||||
.agent_settings
|
||||
.image_gen_profiles
|
||||
.get_mut(index)
|
||||
{
|
||||
profile.provider = profile.provider.next();
|
||||
profile.model.clear();
|
||||
let settings = &mut self.editor_state.editor_ui.agent_settings;
|
||||
settings.image_gen_provider_menu_open =
|
||||
(settings.image_gen_provider_menu_open != Some(index)).then_some(index);
|
||||
}
|
||||
AgentSettingsHit::SelectGenProvider { index, provider } => {
|
||||
self.commit_settings_focus();
|
||||
let settings = &mut self.editor_state.editor_ui.agent_settings;
|
||||
if let Some(profile) = settings.image_gen_profiles.get_mut(index) {
|
||||
if profile.provider != provider {
|
||||
profile.provider = provider;
|
||||
profile.model.clear();
|
||||
}
|
||||
}
|
||||
settings.image_gen_provider_menu_open = None;
|
||||
}
|
||||
AgentSettingsHit::FocusGenConfig { index, field } => {
|
||||
self.commit_settings_focus();
|
||||
self.editor_state
|
||||
.editor_ui
|
||||
.agent_settings
|
||||
.image_gen_provider_menu_open = None;
|
||||
self.focus_image_gen_profile(index, field);
|
||||
}
|
||||
AgentSettingsHit::ToggleAutoUpdate => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue