refactor(editor): route settings image profile buttons through shared feedback
This commit is contained in:
parent
4159dde2e3
commit
2dcdcc93e6
|
|
@ -9,4 +9,8 @@ pub enum AgentSettingsButton {
|
|||
McpClientConfigCopy,
|
||||
ImageSearchTest,
|
||||
ImageGenAdd,
|
||||
ImageProfileHeader(usize),
|
||||
ImageProfileRemove(usize),
|
||||
ImageProfileProvider(usize),
|
||||
ImageProfileTest(usize),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -639,10 +639,15 @@ fn paint_profile_row(
|
|||
} else {
|
||||
cx.backend.stroke_round_rect(row, 6.0, theme.border, 1.0);
|
||||
}
|
||||
if settings.hover_image_gen_profile_header == Some(index) {
|
||||
cx.backend
|
||||
.fill_round_rect(profile_header_rect(row), 6.0, theme.button_hover);
|
||||
}
|
||||
crate::widgets::button::paint_ghost_button_feedback(
|
||||
cx.backend,
|
||||
theme,
|
||||
profile_header_rect(row),
|
||||
settings.hover_image_gen_profile_header == Some(index),
|
||||
ui.button_pressed(ButtonPressTarget::AgentSettings(
|
||||
AgentSettingsButton::ImageProfileHeader(index),
|
||||
)),
|
||||
);
|
||||
let dot = profile_active_rect(row);
|
||||
if active {
|
||||
cx.backend.fill_oval(dot, theme.primary);
|
||||
|
|
@ -708,10 +713,15 @@ fn paint_profile_row(
|
|||
);
|
||||
|
||||
let remove_hover = profile_remove_hover_rect(row);
|
||||
if settings.hover_image_gen_profile_remove == Some(index) {
|
||||
cx.backend
|
||||
.fill_round_rect(remove_hover, 6.0, theme.button_hover);
|
||||
}
|
||||
crate::widgets::button::paint_ghost_button_feedback(
|
||||
cx.backend,
|
||||
theme,
|
||||
remove_hover,
|
||||
settings.hover_image_gen_profile_remove == Some(index),
|
||||
ui.button_pressed(ButtonPressTarget::AgentSettings(
|
||||
AgentSettingsButton::ImageProfileRemove(index),
|
||||
)),
|
||||
);
|
||||
draw_icon(
|
||||
cx.backend,
|
||||
Icon::Trash,
|
||||
|
|
@ -746,6 +756,9 @@ fn paint_profile_row(
|
|||
profile,
|
||||
profile_test_btn_rect(row),
|
||||
settings.hover_image_gen_profile_test == Some(index),
|
||||
ui.button_pressed(ButtonPressTarget::AgentSettings(
|
||||
AgentSettingsButton::ImageProfileTest(index),
|
||||
)),
|
||||
);
|
||||
let provider_rect = profile_provider_rect(row);
|
||||
paint_provider_field(
|
||||
|
|
@ -755,6 +768,9 @@ fn paint_profile_row(
|
|||
provider_rect,
|
||||
row.origin.x + 12.0,
|
||||
settings.hover_image_gen_profile_provider == Some(index),
|
||||
ui.button_pressed(ButtonPressTarget::AgentSettings(
|
||||
AgentSettingsButton::ImageProfileProvider(index),
|
||||
)),
|
||||
);
|
||||
if settings.image_gen_provider_menu_open == Some(index) {
|
||||
let hovered = settings
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use crate::theme::Theme;
|
|||
use crate::widgets::agent_settings_caret::{paint_settings_input_view, settings_input_text};
|
||||
use crate::widgets::icons::{draw_icon, Icon};
|
||||
use crate::widgets::PaintCx;
|
||||
use crate::{Color, Point2D, Rect, TextLayout};
|
||||
use crate::{Point2D, Rect, TextLayout};
|
||||
use op_editor_core::agent_settings::{
|
||||
AgentSettings, ImageGenField, ImageGenProfile, ImageGenProvider, ImageSearchField,
|
||||
ImageTestStatus, SettingsFocus,
|
||||
|
|
@ -222,15 +222,13 @@ pub(super) fn paint_profile_test_button(
|
|||
profile: &ImageGenProfile,
|
||||
btn: Rect,
|
||||
hovered: bool,
|
||||
pressed: bool,
|
||||
) {
|
||||
let enabled =
|
||||
!profile.api_key.trim().is_empty() && profile.test_status != ImageTestStatus::Testing;
|
||||
paint_profile_test_status(cx, theme, profile, btn);
|
||||
cx.backend.fill_round_rect(btn, 6.0, theme.muted);
|
||||
if hovered {
|
||||
cx.backend
|
||||
.fill_round_rect(btn, 6.0, profile_button_hover_color(theme));
|
||||
}
|
||||
crate::widgets::button::paint_ghost_button_feedback(cx.backend, theme, btn, hovered, pressed);
|
||||
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);
|
||||
|
|
@ -255,15 +253,6 @@ pub(super) fn paint_profile_test_button(
|
|||
);
|
||||
}
|
||||
|
||||
fn profile_button_hover_color(theme: &Theme) -> Color {
|
||||
Color {
|
||||
r: theme.foreground.r,
|
||||
g: theme.foreground.g,
|
||||
b: theme.foreground.b,
|
||||
a: 0.12,
|
||||
}
|
||||
}
|
||||
|
||||
fn paint_profile_test_status(
|
||||
cx: &mut PaintCx<'_>,
|
||||
theme: &Theme,
|
||||
|
|
@ -312,6 +301,7 @@ pub(super) fn paint_provider_field(
|
|||
input: Rect,
|
||||
label_x: f32,
|
||||
hovered: bool,
|
||||
pressed: bool,
|
||||
) {
|
||||
let label_lay = TextLayout::single_run(
|
||||
"Provider",
|
||||
|
|
@ -323,9 +313,7 @@ pub(super) fn paint_provider_field(
|
|||
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);
|
||||
if hovered {
|
||||
cx.backend.fill_round_rect(input, 6.0, theme.button_hover);
|
||||
}
|
||||
crate::widgets::button::paint_ghost_button_feedback(cx.backend, theme, input, hovered, pressed);
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use crate::{Color, Point2D, Rect, RenderBackend, TextLayout};
|
|||
use op_editor_core::agent_settings::{
|
||||
AgentSettingsTab, ImageGenField, ImageGenProvider, ImageTestStatus, SettingsFocus,
|
||||
};
|
||||
use op_editor_core::EditorState;
|
||||
use op_editor_core::{AgentSettingsButton, ButtonPressTarget, EditorState};
|
||||
|
||||
#[derive(Default)]
|
||||
struct CaptureBackend {
|
||||
|
|
@ -406,14 +406,80 @@ fn images_tab_profile_controls_hover_paints_visible_washes() {
|
|||
}
|
||||
assert!(
|
||||
backend.round_fills.iter().any(|(fill, color)| {
|
||||
rect_eq(*fill, test_button)
|
||||
&& !color_eq(*color, panel.theme.muted)
|
||||
&& color.a > panel.theme.button_hover.a + 0.01
|
||||
rect_eq(*fill, test_button) && color_eq(*color, panel.theme.button_hover)
|
||||
}),
|
||||
"hovered profile test button should paint a stronger visible hover wash"
|
||||
"hovered profile test button should paint the shared hover token"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pressed_image_gen_profile_controls_use_shared_button_feedback() {
|
||||
for button in [
|
||||
AgentSettingsButton::ImageProfileHeader(0),
|
||||
AgentSettingsButton::ImageProfileRemove(0),
|
||||
AgentSettingsButton::ImageProfileProvider(0),
|
||||
AgentSettingsButton::ImageProfileTest(0),
|
||||
] {
|
||||
let mut state = EditorState::default();
|
||||
state.editor_ui.agent_settings.tab = AgentSettingsTab::Images;
|
||||
state.editor_ui.agent_settings.add_image_gen_profile();
|
||||
state.editor_ui.agent_settings.focus = Some(SettingsFocus::ImageGenProfile {
|
||||
index: 0,
|
||||
field: ImageGenField::Name,
|
||||
});
|
||||
state.editor_ui.pressed_button = Some(ButtonPressTarget::AgentSettings(button));
|
||||
let panel = AgentSettingsPanel::for_editor(&state);
|
||||
let rect = panel.rect(1200.0, 800.0);
|
||||
let content_x = rect.origin.x + 200.0 + 24.0;
|
||||
let content_y = rect.origin.y + 24.0;
|
||||
let content_w = rect.size.x - 200.0 - 48.0;
|
||||
let row = Rect {
|
||||
origin: Point2D::new(content_x + 8.0, content_y + 36.0 + 24.0 + 28.0 + 36.0 + 8.0),
|
||||
size: Point2D::new(content_w - 16.0, 32.0 + 8.0 + 5.0 * 36.0),
|
||||
};
|
||||
let target = match button {
|
||||
AgentSettingsButton::ImageProfileHeader(_) => Rect {
|
||||
origin: row.origin,
|
||||
size: Point2D::new(row.size.x, 32.0),
|
||||
},
|
||||
AgentSettingsButton::ImageProfileRemove(_) => Rect {
|
||||
origin: Point2D::new(row.origin.x + row.size.x - 30.0, row.origin.y + 2.0),
|
||||
size: Point2D::new(28.0, 28.0),
|
||||
},
|
||||
AgentSettingsButton::ImageProfileProvider(_) => Rect {
|
||||
origin: Point2D::new(row.origin.x + 110.0, row.origin.y + 40.0 + 36.0),
|
||||
size: Point2D::new(row.size.x - 110.0 - 12.0, 24.0),
|
||||
},
|
||||
AgentSettingsButton::ImageProfileTest(_) => Rect {
|
||||
origin: Point2D::new(
|
||||
row.origin.x + row.size.x - 12.0 - 56.0,
|
||||
row.origin.y + 40.0 + 72.0,
|
||||
),
|
||||
size: Point2D::new(56.0, 24.0),
|
||||
},
|
||||
_ => unreachable!("case list only includes image profile buttons"),
|
||||
};
|
||||
let expected = panel
|
||||
.theme
|
||||
.button_hover
|
||||
.with_alpha(panel.theme.button_hover.a * 1.8);
|
||||
let mut backend = CaptureBackend::default();
|
||||
let mut cx = PaintCx {
|
||||
backend: &mut backend,
|
||||
};
|
||||
|
||||
panel.paint(&mut cx, rect);
|
||||
|
||||
assert!(
|
||||
backend
|
||||
.round_fills
|
||||
.iter()
|
||||
.any(|(fill, color)| rect_eq(*fill, target) && color_eq(*color, expected)),
|
||||
"pressed {button:?} should paint the shared pressed feedback token"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn disabled_image_gen_profile_test_hover_uses_visible_wash() {
|
||||
let mut state = EditorState::default();
|
||||
|
|
@ -449,11 +515,9 @@ fn disabled_image_gen_profile_test_hover_uses_visible_wash() {
|
|||
|
||||
assert!(
|
||||
backend.round_fills.iter().any(|(fill, color)| {
|
||||
rect_eq(*fill, test_button)
|
||||
&& !color_eq(*color, panel.theme.muted)
|
||||
&& color.a > panel.theme.button_hover.a + 0.01
|
||||
rect_eq(*fill, test_button) && color_eq(*color, panel.theme.button_hover)
|
||||
}),
|
||||
"disabled profile test button hover should paint a visible wash"
|
||||
"disabled profile test button hover should paint the shared hover token"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,6 +106,10 @@ pub fn agent_settings_button(
|
|||
W::CopyMcpClientConfig => Some(O::McpClientConfigCopy),
|
||||
W::TestImageSearch => Some(O::ImageSearchTest),
|
||||
W::AddGenConfig => Some(O::ImageGenAdd),
|
||||
W::ToggleGenConfigEditor(index) => Some(O::ImageProfileHeader(index)),
|
||||
W::RemoveGenConfig(index) => Some(O::ImageProfileRemove(index)),
|
||||
W::ToggleGenProviderMenu(index) => Some(O::ImageProfileProvider(index)),
|
||||
W::TestGenConfig(index) => Some(O::ImageProfileTest(index)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use super::WidgetHostNative;
|
|||
use op_editor_core::agent_settings::{
|
||||
AgentSettingsTab, ImageGenField, ImageGenProvider, ImageTestStatus, SettingsFocus,
|
||||
};
|
||||
use op_editor_core::{AgentSettingsButton, ButtonPressTarget};
|
||||
use op_editor_ui::widgets::agent_settings_panel::AgentSettingsPanel;
|
||||
|
||||
#[test]
|
||||
|
|
@ -43,6 +44,15 @@ fn image_generation_profile_test_tracks_testing_status_like_ts() {
|
|||
.agent_settings
|
||||
.image_gen_profiles[0];
|
||||
assert_eq!(profile.test_status, ImageTestStatus::Testing);
|
||||
assert_eq!(
|
||||
host.editor_state().editor_ui.pressed_button,
|
||||
Some(ButtonPressTarget::AgentSettings(
|
||||
AgentSettingsButton::ImageProfileTest(0)
|
||||
))
|
||||
);
|
||||
|
||||
assert!(host.apply_release_with_viewport(1200.0, 800.0));
|
||||
assert_eq!(host.editor_state().editor_ui.pressed_button, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -617,6 +617,15 @@ fn image_generation_profile_buttons_add_activate_and_remove() {
|
|||
1200.0,
|
||||
800.0
|
||||
));
|
||||
assert_eq!(
|
||||
host.editor_state().editor_ui.pressed_button,
|
||||
Some(ButtonPressTarget::AgentSettings(
|
||||
AgentSettingsButton::ImageProfileRemove(1)
|
||||
))
|
||||
);
|
||||
assert!(host.apply_release_with_viewport(1200.0, 800.0));
|
||||
assert_eq!(host.editor_state().editor_ui.pressed_button, None);
|
||||
|
||||
let settings = &host.editor_state().editor_ui.agent_settings;
|
||||
assert_eq!(settings.image_gen_profiles.len(), 1);
|
||||
assert_eq!(
|
||||
|
|
@ -738,6 +747,14 @@ fn image_generation_provider_click_opens_menu_without_changing_profile() {
|
|||
.image_gen_provider_menu_open,
|
||||
Some(0)
|
||||
);
|
||||
assert_eq!(
|
||||
host.editor_state().editor_ui.pressed_button,
|
||||
Some(ButtonPressTarget::AgentSettings(
|
||||
AgentSettingsButton::ImageProfileProvider(0)
|
||||
))
|
||||
);
|
||||
assert!(host.apply_release_with_viewport(1200.0, 800.0));
|
||||
assert_eq!(host.editor_state().editor_ui.pressed_button, None);
|
||||
|
||||
assert!(host.dispatch_agent_settings_press(
|
||||
content_x + 110.0 + 20.0,
|
||||
|
|
@ -784,6 +801,12 @@ fn image_generation_profile_header_click_toggles_editor_closed() {
|
|||
let row_y = gen_top + 36.0 + 8.0;
|
||||
|
||||
assert!(host.dispatch_agent_settings_press(content_x + 72.0, row_y + 16.0, 1200.0, 800.0));
|
||||
assert_eq!(
|
||||
host.editor_state().editor_ui.pressed_button,
|
||||
Some(ButtonPressTarget::AgentSettings(
|
||||
AgentSettingsButton::ImageProfileHeader(0)
|
||||
))
|
||||
);
|
||||
|
||||
assert_eq!(host.editor_state().editor_ui.agent_settings.focus, None);
|
||||
assert!(host
|
||||
|
|
@ -792,6 +815,8 @@ fn image_generation_profile_header_click_toggles_editor_closed() {
|
|||
.settings_input
|
||||
.text()
|
||||
.is_empty());
|
||||
assert!(host.apply_release_with_viewport(1200.0, 800.0));
|
||||
assert_eq!(host.editor_state().editor_ui.pressed_button, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -256,6 +256,15 @@ fn image_generation_profile_test_tracks_testing_status_like_ts() {
|
|||
.agent_settings
|
||||
.image_gen_profiles[0];
|
||||
assert_eq!(profile.test_status, ImageTestStatus::Testing);
|
||||
assert_eq!(
|
||||
host.editor_state.editor_ui.pressed_button,
|
||||
Some(ButtonPressTarget::AgentSettings(
|
||||
AgentSettingsButton::ImageProfileTest(0)
|
||||
))
|
||||
);
|
||||
|
||||
assert!(host.apply_release_with_viewport(1200.0, 800.0));
|
||||
assert_eq!(host.editor_state.editor_ui.pressed_button, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -304,6 +313,14 @@ fn image_generation_provider_select_commits_and_closes_menu() {
|
|||
field: ImageGenField::Name,
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
host.editor_state.editor_ui.pressed_button,
|
||||
Some(ButtonPressTarget::AgentSettings(
|
||||
AgentSettingsButton::ImageProfileProvider(0)
|
||||
))
|
||||
);
|
||||
assert!(host.apply_release_with_viewport(1200.0, 800.0));
|
||||
assert_eq!(host.editor_state.editor_ui.pressed_button, None);
|
||||
|
||||
assert!(host.dispatch_agent_settings_press(
|
||||
content_x + 110.0 + 20.0,
|
||||
|
|
@ -351,9 +368,17 @@ fn image_generation_profile_header_click_toggles_editor_closed() {
|
|||
let row_y = gen_top + 36.0 + 8.0;
|
||||
|
||||
assert!(host.dispatch_agent_settings_press(content_x + 72.0, row_y + 16.0, 1200.0, 800.0));
|
||||
assert_eq!(
|
||||
host.editor_state.editor_ui.pressed_button,
|
||||
Some(ButtonPressTarget::AgentSettings(
|
||||
AgentSettingsButton::ImageProfileHeader(0)
|
||||
))
|
||||
);
|
||||
|
||||
assert_eq!(host.editor_state.editor_ui.agent_settings.focus, None);
|
||||
assert!(host.editor_state.editor_ui.settings_input.text().is_empty());
|
||||
assert!(host.apply_release_with_viewport(1200.0, 800.0));
|
||||
assert_eq!(host.editor_state.editor_ui.pressed_button, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Reference in a new issue