fix(ai): edit image generation profiles
This commit is contained in:
parent
54aff64327
commit
9498e8d37d
|
|
@ -100,6 +100,14 @@ pub enum BuiltinAgentField {
|
|||
BaseUrl,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ImageGenField {
|
||||
Name,
|
||||
ApiKey,
|
||||
Model,
|
||||
BaseUrl,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum SettingsFocus {
|
||||
McpPort,
|
||||
|
|
@ -107,6 +115,10 @@ pub enum SettingsFocus {
|
|||
index: usize,
|
||||
field: BuiltinAgentField,
|
||||
},
|
||||
ImageGenProfile {
|
||||
index: usize,
|
||||
field: ImageGenField,
|
||||
},
|
||||
}
|
||||
|
||||
/// Built-in provider backend configured directly in OpenPencil.
|
||||
|
|
|
|||
|
|
@ -70,7 +70,8 @@ mod tests_pages;
|
|||
|
||||
pub use agent_settings::{
|
||||
AgentSettings, AgentSettingsDrag, AgentSettingsTab, BuiltinAgentConfig, BuiltinAgentField,
|
||||
BuiltinAgentKind, ImageGenProfile, ImageGenProvider, McpCli, McpServer, SettingsFocus,
|
||||
BuiltinAgentKind, ImageGenField, ImageGenProfile, ImageGenProvider, McpCli, McpServer,
|
||||
SettingsFocus,
|
||||
};
|
||||
pub use align::AlignAction;
|
||||
pub use chat::{
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ use crate::widgets::agent_settings_i18n::t as t_settings;
|
|||
use crate::widgets::icons::{draw_icon, Icon};
|
||||
use crate::widgets::PaintCx;
|
||||
use crate::{Color, Point2D, Rect, TextLayout};
|
||||
use op_editor_core::agent_settings::{AgentSettings, ImageGenProfile};
|
||||
use op_editor_core::agent_settings::{
|
||||
AgentSettings, ImageGenField, ImageGenProfile, SettingsFocus,
|
||||
};
|
||||
use op_editor_core::editor_ui_state::EditorUiState;
|
||||
|
||||
const TITLE_H: f32 = 36.0;
|
||||
|
|
@ -25,6 +27,8 @@ const PROFILE_ROW_H: f32 = 32.0;
|
|||
const PROFILE_ROW_GAP: f32 = 6.0;
|
||||
const ACTIVE_DOT: f32 = 14.0;
|
||||
const DELETE_W: f32 = 24.0;
|
||||
const PROFILE_FORM_TOP: f32 = 40.0;
|
||||
const PROFILE_FIELD_H: f32 = 24.0;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ImagesHit {
|
||||
|
|
@ -33,6 +37,7 @@ pub enum ImagesHit {
|
|||
AddGenConfig,
|
||||
SetActiveGenConfig(usize),
|
||||
RemoveGenConfig(usize),
|
||||
FocusGenConfig { index: usize, field: ImageGenField },
|
||||
None,
|
||||
}
|
||||
|
||||
|
|
@ -60,11 +65,24 @@ fn profile_list_h(settings: &AgentSettings) -> f32 {
|
|||
if settings.image_gen_profiles.is_empty() {
|
||||
80.0
|
||||
} else {
|
||||
settings.image_gen_profiles.len() as f32 * PROFILE_ROW_H
|
||||
settings
|
||||
.image_gen_profiles
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, _)| profile_row_h(settings, index))
|
||||
.sum::<f32>()
|
||||
+ settings.image_gen_profiles.len().saturating_sub(1) as f32 * PROFILE_ROW_GAP
|
||||
}
|
||||
}
|
||||
|
||||
fn profile_row_h(settings: &AgentSettings, index: usize) -> f32 {
|
||||
if is_editing_profile(settings, index) {
|
||||
PROFILE_ROW_H + 8.0 + 4.0 * ROW_H
|
||||
} else {
|
||||
PROFILE_ROW_H
|
||||
}
|
||||
}
|
||||
|
||||
fn advanced_toggle_rect(content: Rect) -> Rect {
|
||||
Rect {
|
||||
origin: Point2D::new(content.origin.x, content.origin.y + TITLE_H),
|
||||
|
|
@ -103,12 +121,17 @@ fn add_btn_rect(content: Rect, settings: &AgentSettings) -> Rect {
|
|||
|
||||
fn profile_row_rect(content: Rect, settings: &AgentSettings, index: usize) -> Rect {
|
||||
let top = image_gen_section_top(content, settings) + SECTION_TITLE_H;
|
||||
let y = settings
|
||||
.image_gen_profiles
|
||||
.iter()
|
||||
.enumerate()
|
||||
.take(index)
|
||||
.fold(top, |acc, (i, _)| {
|
||||
acc + profile_row_h(settings, i) + PROFILE_ROW_GAP
|
||||
});
|
||||
Rect {
|
||||
origin: Point2D::new(
|
||||
content.origin.x,
|
||||
top + index as f32 * (PROFILE_ROW_H + PROFILE_ROW_GAP),
|
||||
),
|
||||
size: Point2D::new(content.size.x, PROFILE_ROW_H),
|
||||
origin: Point2D::new(content.origin.x, y),
|
||||
size: Point2D::new(content.size.x, profile_row_h(settings, index)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -132,6 +155,16 @@ fn profile_remove_rect(row: Rect) -> Rect {
|
|||
}
|
||||
}
|
||||
|
||||
fn profile_field_rect(row: Rect, field_index: usize) -> Rect {
|
||||
Rect {
|
||||
origin: Point2D::new(
|
||||
row.origin.x + LABEL_W,
|
||||
row.origin.y + PROFILE_FORM_TOP + field_index as f32 * ROW_H,
|
||||
),
|
||||
size: Point2D::new(row.size.x - LABEL_W - 12.0, PROFILE_FIELD_H),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hit_test(content: Rect, settings: &AgentSettings, scrolled: Point2D) -> ImagesHit {
|
||||
if rect_contains(advanced_toggle_rect(content), scrolled) {
|
||||
return ImagesHit::ToggleAdvanced;
|
||||
|
|
@ -150,6 +183,19 @@ pub fn hit_test(content: Rect, settings: &AgentSettings, scrolled: Point2D) -> I
|
|||
if rect_contains(profile_remove_rect(row), scrolled) {
|
||||
return ImagesHit::RemoveGenConfig(index);
|
||||
}
|
||||
if is_editing_profile(settings, index) {
|
||||
for (field_index, field) in image_gen_fields().into_iter().enumerate() {
|
||||
if rect_contains(profile_field_rect(row, field_index), scrolled) {
|
||||
return ImagesHit::FocusGenConfig { index, field };
|
||||
}
|
||||
}
|
||||
}
|
||||
if rect_contains(row, scrolled) {
|
||||
return ImagesHit::FocusGenConfig {
|
||||
index,
|
||||
field: ImageGenField::Name,
|
||||
};
|
||||
}
|
||||
}
|
||||
ImagesHit::None
|
||||
}
|
||||
|
|
@ -365,7 +411,7 @@ pub(super) fn paint_images_tab(
|
|||
} else {
|
||||
for (index, profile) in settings.image_gen_profiles.iter().enumerate() {
|
||||
let row = profile_row_rect(content, settings, index);
|
||||
paint_profile_row(cx, theme, settings, profile, row);
|
||||
paint_profile_row(cx, theme, settings, ui, profile, index, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -374,13 +420,21 @@ fn paint_profile_row(
|
|||
cx: &mut PaintCx<'_>,
|
||||
theme: &Theme,
|
||||
settings: &AgentSettings,
|
||||
ui: &EditorUiState,
|
||||
profile: &ImageGenProfile,
|
||||
index: usize,
|
||||
row: Rect,
|
||||
) {
|
||||
let active = settings.active_image_gen_profile_id.as_deref() == Some(profile.id.as_str());
|
||||
if active {
|
||||
let editing = is_editing_profile(settings, index);
|
||||
if active || editing {
|
||||
cx.backend.fill_round_rect(row, 6.0, theme.muted);
|
||||
cx.backend.stroke_round_rect(row, 6.0, theme.primary, 1.0);
|
||||
cx.backend.stroke_round_rect(
|
||||
row,
|
||||
6.0,
|
||||
if active { theme.primary } else { theme.border },
|
||||
1.0,
|
||||
);
|
||||
} else {
|
||||
cx.backend.stroke_round_rect(row, 6.0, theme.border, 1.0);
|
||||
}
|
||||
|
|
@ -445,6 +499,93 @@ fn paint_profile_row(
|
|||
theme.muted_foreground,
|
||||
1.5,
|
||||
);
|
||||
|
||||
if editing {
|
||||
for (field_index, field) in image_gen_fields().into_iter().enumerate() {
|
||||
paint_profile_field(
|
||||
cx,
|
||||
theme,
|
||||
settings,
|
||||
ui,
|
||||
profile,
|
||||
index,
|
||||
field,
|
||||
field_index,
|
||||
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,
|
||||
field_index: usize,
|
||||
row: Rect,
|
||||
) {
|
||||
let focused = settings.focus == Some(SettingsFocus::ImageGenProfile { index, field });
|
||||
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 input = profile_field_rect(row, field_index);
|
||||
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 value = ellipsize(cx, value, input.size.x - 12.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),
|
||||
);
|
||||
}
|
||||
|
||||
fn paint_input_row(
|
||||
|
|
@ -495,6 +636,22 @@ fn ellipsize(cx: &mut PaintCx<'_>, value: &str, max_w: f32, size: f32) -> String
|
|||
format!("{out}...")
|
||||
}
|
||||
|
||||
fn image_gen_fields() -> [ImageGenField; 4] {
|
||||
[
|
||||
ImageGenField::Name,
|
||||
ImageGenField::ApiKey,
|
||||
ImageGenField::Model,
|
||||
ImageGenField::BaseUrl,
|
||||
]
|
||||
}
|
||||
|
||||
fn is_editing_profile(settings: &AgentSettings, index: usize) -> bool {
|
||||
matches!(
|
||||
settings.focus,
|
||||
Some(SettingsFocus::ImageGenProfile { index: i, .. }) if i == index
|
||||
)
|
||||
}
|
||||
|
||||
fn rect_contains(r: Rect, p: Point2D) -> bool {
|
||||
p.x >= r.origin.x
|
||||
&& p.y >= r.origin.y
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use crate::widgets::icons::{draw_icon, Icon};
|
|||
use crate::widgets::{PaintCx, Widget, WidgetId};
|
||||
use crate::{Color, Point2D, Rect, TextLayout};
|
||||
use op_editor_core::agent_settings::{
|
||||
AgentProvider, AgentSettings, AgentSettingsTab, BuiltinAgentField, McpCli,
|
||||
AgentProvider, AgentSettings, AgentSettingsTab, BuiltinAgentField, ImageGenField, McpCli,
|
||||
};
|
||||
use op_editor_core::editor_ui_state::EditorUiState;
|
||||
use op_editor_core::EditorState;
|
||||
|
|
@ -58,6 +58,10 @@ pub enum AgentSettingsHit {
|
|||
AddGenConfig,
|
||||
SetActiveGenConfig(usize),
|
||||
RemoveGenConfig(usize),
|
||||
FocusGenConfig {
|
||||
index: usize,
|
||||
field: ImageGenField,
|
||||
},
|
||||
ToggleAutoUpdate,
|
||||
FocusMcpPort,
|
||||
Outside,
|
||||
|
|
@ -170,6 +174,9 @@ impl<'a> AgentSettingsPanel<'a> {
|
|||
ImagesHit::RemoveGenConfig(index) => {
|
||||
return AgentSettingsHit::RemoveGenConfig(index);
|
||||
}
|
||||
ImagesHit::FocusGenConfig { index, field } => {
|
||||
return AgentSettingsHit::FocusGenConfig { index, field };
|
||||
}
|
||||
ImagesHit::None => {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
use crate::widgets::agent_settings_panel::{AgentSettingsHit, AgentSettingsPanel};
|
||||
use op_editor_core::agent_settings::{AgentSettingsTab, BuiltinAgentField, SettingsFocus};
|
||||
use op_editor_core::agent_settings::{
|
||||
AgentSettingsTab, BuiltinAgentField, ImageGenField, SettingsFocus,
|
||||
};
|
||||
use op_editor_core::EditorState;
|
||||
|
||||
#[test]
|
||||
|
|
@ -222,3 +224,37 @@ fn images_tab_content_height_includes_profile_rows() {
|
|||
"configured image generation profiles should replace the TS empty state with rows"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn images_tab_expanded_profile_fields_are_focusable() {
|
||||
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,
|
||||
});
|
||||
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 gen_top = content_y + 36.0 + 24.0 + 28.0;
|
||||
let row_y = gen_top + 36.0;
|
||||
let api_field_y = row_y + 32.0 + 8.0 + 36.0;
|
||||
|
||||
assert_eq!(
|
||||
panel.hit_test(
|
||||
rect,
|
||||
crate::Point2D::new(content_x + 110.0 + 20.0, api_field_y + 12.0)
|
||||
),
|
||||
AgentSettingsHit::FocusGenConfig {
|
||||
index: 0,
|
||||
field: ImageGenField::ApiKey,
|
||||
}
|
||||
);
|
||||
assert!(
|
||||
panel.content_total_height() > 180.0,
|
||||
"focused image profile should expand to show editable fields"
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
use super::WidgetHostNative;
|
||||
use op_editor_core::agent_settings::{AgentSettingsTab, BuiltinAgentField, SettingsFocus};
|
||||
use op_editor_core::agent_settings::{
|
||||
AgentSettingsTab, BuiltinAgentField, ImageGenField, SettingsFocus,
|
||||
};
|
||||
use op_editor_ui::widgets::agent_settings_panel::AgentSettingsPanel;
|
||||
|
||||
#[test]
|
||||
|
|
@ -248,3 +250,35 @@ fn image_generation_profile_buttons_add_activate_and_remove() {
|
|||
Some(first.as_str())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn image_generation_profile_focus_accepts_text_and_commits() {
|
||||
let mut host = WidgetHostNative::new();
|
||||
host.editor_state_mut().editor_ui.agent_settings.tab = AgentSettingsTab::Images;
|
||||
host.editor_state_mut()
|
||||
.editor_ui
|
||||
.agent_settings
|
||||
.add_image_gen_profile();
|
||||
host.editor_state_mut().editor_ui.agent_settings.focus = Some(SettingsFocus::ImageGenProfile {
|
||||
index: 0,
|
||||
field: ImageGenField::Name,
|
||||
});
|
||||
host.editor_state_mut()
|
||||
.editor_ui
|
||||
.settings_input_draft
|
||||
.clear();
|
||||
|
||||
for c in "Hero Images".chars() {
|
||||
assert!(host.apply_text(c));
|
||||
}
|
||||
assert!(host.apply_send());
|
||||
|
||||
let settings = &host.editor_state().editor_ui.agent_settings;
|
||||
assert_eq!(settings.image_gen_profiles[0].name, "Hero Images");
|
||||
assert!(settings.focus.is_none());
|
||||
assert!(host
|
||||
.editor_state()
|
||||
.editor_ui
|
||||
.settings_input_draft
|
||||
.is_empty());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ impl WidgetHostNative {
|
|||
op_editor_core::agent_settings::SettingsFocus::BuiltinAgent { .. } => {
|
||||
!c.is_control() && draft.len() < 512
|
||||
}
|
||||
op_editor_core::agent_settings::SettingsFocus::ImageGenProfile { .. } => {
|
||||
!c.is_control() && draft.len() < 512
|
||||
}
|
||||
};
|
||||
if accepts {
|
||||
draft.push(c);
|
||||
|
|
|
|||
|
|
@ -135,6 +135,35 @@ impl WidgetHostNative {
|
|||
.remove_image_gen_profile(&id);
|
||||
}
|
||||
}
|
||||
AgentSettingsHit::FocusGenConfig { index, field } => {
|
||||
self.commit_settings_focus_if_any();
|
||||
if let Some(profile) = self
|
||||
.editor_state
|
||||
.editor_ui
|
||||
.agent_settings
|
||||
.image_gen_profiles
|
||||
.get(index)
|
||||
{
|
||||
self.editor_state.editor_ui.settings_input_draft = match field {
|
||||
op_editor_core::agent_settings::ImageGenField::Name => profile.name.clone(),
|
||||
op_editor_core::agent_settings::ImageGenField::ApiKey => {
|
||||
profile.api_key.clone()
|
||||
}
|
||||
op_editor_core::agent_settings::ImageGenField::Model => {
|
||||
profile.model.clone()
|
||||
}
|
||||
op_editor_core::agent_settings::ImageGenField::BaseUrl => {
|
||||
profile.base_url.clone().unwrap_or_default()
|
||||
}
|
||||
};
|
||||
self.editor_state.editor_ui.agent_settings.focus = Some(
|
||||
op_editor_core::agent_settings::SettingsFocus::ImageGenProfile {
|
||||
index,
|
||||
field,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
AgentSettingsHit::ToggleAutoUpdate => {
|
||||
let v = &mut self
|
||||
.editor_state
|
||||
|
|
@ -282,10 +311,34 @@ impl WidgetHostNative {
|
|||
| AgentSettingsHit::Inside => {}
|
||||
AgentSettingsHit::AddGenConfig => {
|
||||
self.commit_settings_focus_if_any();
|
||||
self.editor_state
|
||||
let id = self
|
||||
.editor_state
|
||||
.editor_ui
|
||||
.agent_settings
|
||||
.add_image_gen_profile();
|
||||
let index = self
|
||||
.editor_state
|
||||
.editor_ui
|
||||
.agent_settings
|
||||
.image_gen_profiles
|
||||
.iter()
|
||||
.position(|profile| profile.id == id)
|
||||
.unwrap_or(0);
|
||||
if let Some(profile) = self
|
||||
.editor_state
|
||||
.editor_ui
|
||||
.agent_settings
|
||||
.image_gen_profiles
|
||||
.get(index)
|
||||
{
|
||||
self.editor_state.editor_ui.settings_input_draft = profile.name.clone();
|
||||
self.editor_state.editor_ui.agent_settings.focus = Some(
|
||||
op_editor_core::agent_settings::SettingsFocus::ImageGenProfile {
|
||||
index,
|
||||
field: op_editor_core::agent_settings::ImageGenField::Name,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.mark_dirty();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use super::WidgetHostNative;
|
|||
impl WidgetHostNative {
|
||||
/// Commit any focused settings-modal input.
|
||||
pub(in crate::widget_host) fn commit_settings_focus_if_any(&mut self) {
|
||||
use op_editor_core::agent_settings::{BuiltinAgentField, SettingsFocus};
|
||||
use op_editor_core::agent_settings::{BuiltinAgentField, ImageGenField, SettingsFocus};
|
||||
let Some(focus) = self.editor_state.editor_ui.agent_settings.focus.take() else {
|
||||
return;
|
||||
};
|
||||
|
|
@ -47,6 +47,34 @@ impl WidgetHostNative {
|
|||
self.editor_state.rebuild_chat_models();
|
||||
}
|
||||
}
|
||||
SettingsFocus::ImageGenProfile { index, field } => {
|
||||
if let Some(profile) = self
|
||||
.editor_state
|
||||
.editor_ui
|
||||
.agent_settings
|
||||
.image_gen_profiles
|
||||
.get_mut(index)
|
||||
{
|
||||
match field {
|
||||
ImageGenField::Name => {
|
||||
profile.name = draft.trim().to_string();
|
||||
}
|
||||
ImageGenField::ApiKey => {
|
||||
profile.api_key = draft.trim().to_string();
|
||||
}
|
||||
ImageGenField::Model => {
|
||||
profile.model = draft.trim().to_string();
|
||||
}
|
||||
ImageGenField::BaseUrl => {
|
||||
profile.base_url = if draft.trim().is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(draft.trim().to_string())
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.mark_dirty();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -404,6 +404,7 @@ impl WidgetHost {
|
|||
self.editor_state.editor_ui.agent_settings.mcp_server.port = port.max(1024);
|
||||
}
|
||||
}
|
||||
SettingsFocus::BuiltinAgent { .. } | SettingsFocus::ImageGenProfile { .. } => {}
|
||||
}
|
||||
self.mark_dirty();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,5 @@
|
|||
//! Web `apply_press` + `apply_click` + `apply_right_press` —
|
||||
//! extracted from `widget_host.rs` so the spine stays under the
|
||||
//! 800-line cap. Mirrors the native `widget_host/press.rs` +
|
||||
//! `click.rs` split.
|
||||
//!
|
||||
//! `EditorState` is the host's source of truth. Every widget
|
||||
//! the canvas hit-test runs against the layout-resolved `LayoutScene`,
|
||||
//! refreshed at the top of each input handler); the shell-core hit
|
||||
//! results (`NodeId` / hit enums) are translated into op-editor-core
|
||||
//! widget hit-test results before feeding `EditorState`
|
||||
//! mutators.
|
||||
|
||||
//! Web press handlers split from `widget_host.rs`; mirrors the
|
||||
//! native press/click split and keeps `EditorState` as source of truth.
|
||||
use op_editor_ui::widgets::{
|
||||
AIChatHit, AIChatPlaceholder, LayerPanel, LayerPanelHit, LocalePicker, PropertyPanel, Toolbar,
|
||||
TopBar, TopBarHit, STATUS_BAR_HEIGHT, STATUS_BAR_WIDTH, TOP_BAR_HEIGHT,
|
||||
|
|
@ -22,10 +12,7 @@ use super::{
|
|||
};
|
||||
|
||||
impl WidgetHost {
|
||||
/// `true` when `(x, y)` is over the StatusBar's search icon — the
|
||||
/// left section of the bottom-right pill. Mirrors the native
|
||||
/// host; `38 px` is a generous target that stops short of the
|
||||
/// minus button.
|
||||
/// `true` when `(x, y)` is over the StatusBar search icon.
|
||||
pub(in crate::widget_host) fn status_bar_search_hit(
|
||||
&self,
|
||||
x: f32,
|
||||
|
|
@ -47,8 +34,7 @@ impl WidgetHost {
|
|||
&& y <= origin_y + STATUS_BAR_HEIGHT
|
||||
}
|
||||
|
||||
/// Zoom + pan so the active page's content is framed within the
|
||||
/// canvas region (the StatusBar search action).
|
||||
/// Zoom + pan so the active page's content is framed within the canvas.
|
||||
pub(in crate::widget_host) fn zoom_to_fit(&mut self, viewport_w: f32, viewport_h: f32) {
|
||||
self.refresh_layout_scene();
|
||||
let Some(content) = self.layout_scene.content_bounds() else {
|
||||
|
|
@ -803,6 +789,9 @@ impl WidgetHost {
|
|||
| AgentSettingsHit::AddAcpAgent
|
||||
| AgentSettingsHit::TestImageSearch
|
||||
| AgentSettingsHit::AddGenConfig
|
||||
| AgentSettingsHit::SetActiveGenConfig(_)
|
||||
| AgentSettingsHit::RemoveGenConfig(_)
|
||||
| AgentSettingsHit::FocusGenConfig { .. }
|
||||
| AgentSettingsHit::Inside => {}
|
||||
}
|
||||
self.mark_dirty();
|
||||
|
|
|
|||
Loading…
Reference in a new issue