Merge branch 'main' into fix/windows-ctrl-slash
This commit is contained in:
4 files changed
+148
-2
No files matched your search
@@ -136,6 +136,7 @@ impl ThemeAdvancedEditor {
|
|||||||
let ansi_pickers = (0..ANSI_COUNT)
|
let ansi_pickers = (0..ANSI_COUNT)
|
||||||
.map(|index| {
|
.map(|index| {
|
||||||
new_color_picker(
|
new_color_picker(
|
||||||
|
ThemeAdvancedField::Ansi(index),
|
||||||
Some(definition.terminal.palette.get(index).unwrap_or([0, 0, 0])),
|
Some(definition.terminal.palette.get(index).unwrap_or([0, 0, 0])),
|
||||||
ansi_inputs[index].clone(),
|
ansi_inputs[index].clone(),
|
||||||
window,
|
window,
|
||||||
@@ -145,6 +146,7 @@ impl ThemeAdvancedEditor {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let selection_background_picker = new_color_picker(
|
let selection_background_picker = new_color_picker(
|
||||||
|
ThemeAdvancedField::SelectionBackground,
|
||||||
definition.terminal.selection_background,
|
definition.terminal.selection_background,
|
||||||
selection_background_input.clone(),
|
selection_background_input.clone(),
|
||||||
window,
|
window,
|
||||||
@@ -152,6 +154,7 @@ impl ThemeAdvancedEditor {
|
|||||||
&mut picker_subscriptions,
|
&mut picker_subscriptions,
|
||||||
);
|
);
|
||||||
let selection_foreground_picker = new_color_picker(
|
let selection_foreground_picker = new_color_picker(
|
||||||
|
ThemeAdvancedField::SelectionForeground,
|
||||||
definition.terminal.selection_foreground,
|
definition.terminal.selection_foreground,
|
||||||
selection_foreground_input.clone(),
|
selection_foreground_input.clone(),
|
||||||
window,
|
window,
|
||||||
@@ -159,6 +162,7 @@ impl ThemeAdvancedEditor {
|
|||||||
&mut picker_subscriptions,
|
&mut picker_subscriptions,
|
||||||
);
|
);
|
||||||
let cursor_text_picker = new_color_picker(
|
let cursor_text_picker = new_color_picker(
|
||||||
|
ThemeAdvancedField::CursorText,
|
||||||
definition.terminal.cursor_text,
|
definition.terminal.cursor_text,
|
||||||
cursor_text_input.clone(),
|
cursor_text_input.clone(),
|
||||||
window,
|
window,
|
||||||
@@ -211,6 +215,17 @@ impl ThemeAdvancedEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(super) fn picker(&self, field: ThemeAdvancedField) -> Option<&Entity<ColorPickerState>> {
|
||||||
|
match field {
|
||||||
|
ThemeAdvancedField::Ansi(index) => self.ansi_pickers.get(index),
|
||||||
|
ThemeAdvancedField::SelectionBackground => Some(&self.selection_background_picker),
|
||||||
|
ThemeAdvancedField::SelectionForeground => Some(&self.selection_foreground_picker),
|
||||||
|
ThemeAdvancedField::CursorText => Some(&self.cursor_text_picker),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Replace all control values after a template/reset/import operation.
|
/// Replace all control values after a template/reset/import operation.
|
||||||
/// Invalid input errors belong to the old draft and therefore disappear.
|
/// Invalid input errors belong to the old draft and therefore disappear.
|
||||||
pub(super) fn sync_from_definition(
|
pub(super) fn sync_from_definition(
|
||||||
@@ -557,6 +572,7 @@ impl ThemeAdvancedEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn new_color_picker(
|
fn new_color_picker(
|
||||||
|
field: ThemeAdvancedField,
|
||||||
color: Option<Rgb8>,
|
color: Option<Rgb8>,
|
||||||
input: Entity<InputState>,
|
input: Entity<InputState>,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
@@ -590,6 +606,7 @@ fn new_color_picker(
|
|||||||
input.update(cx, |state, cx| {
|
input.update(cx, |state, cx| {
|
||||||
state.set_value(format_hex_rgb(rgb), window, cx);
|
state.set_value(format_hex_rgb(rgb), window, cx);
|
||||||
});
|
});
|
||||||
|
this.on_theme_advanced_input(field, window, cx);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
subscriptions.push(subscription);
|
subscriptions.push(subscription);
|
||||||
|
|||||||
@@ -938,7 +938,7 @@ impl SettingsPane {
|
|||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_theme_advanced_input(
|
pub(super) fn on_theme_advanced_input(
|
||||||
&mut self,
|
&mut self,
|
||||||
field: ThemeAdvancedField,
|
field: ThemeAdvancedField,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
@@ -964,6 +964,14 @@ impl SettingsPane {
|
|||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(super) fn theme_advanced_picker(
|
||||||
|
&self,
|
||||||
|
field: ThemeAdvancedField,
|
||||||
|
) -> Option<Entity<gpui_component::color_picker::ColorPickerState>> {
|
||||||
|
self.theme_editor.as_ref()?.advanced_editor.as_ref()?.picker(field).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
fn request_close_theme_editor(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
fn request_close_theme_editor(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
if self.theme_editor.as_ref().is_some_and(|editor| editor.save_busy) {
|
if self.theme_editor.as_ref().is_some_and(|editor| editor.save_busy) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ impl SettingsPane {
|
|||||||
let foreground = theme_color(draft.terminal.foreground, 1.0);
|
let foreground = theme_color(draft.terminal.foreground, 1.0);
|
||||||
let accent = theme_color(resolved_ui.accent, 1.0);
|
let accent = theme_color(resolved_ui.accent, 1.0);
|
||||||
let cursor = theme_color(draft.terminal.cursor.unwrap_or(draft.terminal.foreground), 1.0);
|
let cursor = theme_color(draft.terminal.cursor.unwrap_or(draft.terminal.foreground), 1.0);
|
||||||
|
let cursor_text =
|
||||||
|
theme_color(draft.terminal.cursor_text.unwrap_or(draft.terminal.background), 1.0);
|
||||||
let selection_background = theme_color(
|
let selection_background = theme_color(
|
||||||
draft
|
draft
|
||||||
.terminal
|
.terminal
|
||||||
@@ -233,7 +235,18 @@ impl SettingsPane {
|
|||||||
.gap(px(7.0))
|
.gap(px(7.0))
|
||||||
.items_center()
|
.items_center()
|
||||||
.child(div().text_color(accent).child("❯"))
|
.child(div().text_color(accent).child("❯"))
|
||||||
.child(div().w(px(8.0)).h(px(font_size * line_height)).bg(cursor)),
|
.child(
|
||||||
|
div()
|
||||||
|
.debug_selector(|| "theme-editor-preview-cursor".to_owned())
|
||||||
|
.w(px(font_size * 0.78))
|
||||||
|
.h(px(font_size * line_height))
|
||||||
|
.flex()
|
||||||
|
.items_center()
|
||||||
|
.justify_center()
|
||||||
|
.bg(cursor)
|
||||||
|
.text_color(cursor_text)
|
||||||
|
.child("A"),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.into_any_element(),
|
.into_any_element(),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -483,6 +483,28 @@ fn editor_template(pane: &Entity<SettingsPane>, cx: &mut VisualTestContext) -> T
|
|||||||
pane.read_with(cx, |pane, _| pane.theme_editor.as_ref().expect("theme editor state").template)
|
pane.read_with(cx, |pane, _| pane.theme_editor.as_ref().expect("theme editor state").template)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn emit_advanced_picker_color(
|
||||||
|
pane: &Entity<SettingsPane>,
|
||||||
|
field: super::theme_advanced::ThemeAdvancedField,
|
||||||
|
color: [u8; 3],
|
||||||
|
cx: &mut VisualTestContext,
|
||||||
|
) {
|
||||||
|
let picker = pane
|
||||||
|
.read_with(cx, |pane, _| pane.theme_advanced_picker(field).expect("advanced color picker"));
|
||||||
|
picker.update(cx, |_, cx| {
|
||||||
|
let [r, g, b] = color;
|
||||||
|
let hsla: gpui::Hsla = gpui::Rgba {
|
||||||
|
r: f32::from(r) / 255.0,
|
||||||
|
g: f32::from(g) / 255.0,
|
||||||
|
b: f32::from(b) / 255.0,
|
||||||
|
a: 1.0,
|
||||||
|
}
|
||||||
|
.into();
|
||||||
|
cx.emit(gpui_component::color_picker::ColorPickerEvent::Change(Some(hsla)));
|
||||||
|
});
|
||||||
|
draw(cx);
|
||||||
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn theme_editor_opens_from_the_picker_with_common_fields_and_collapsed_advanced(
|
fn theme_editor_opens_from_the_picker_with_common_fields_and_collapsed_advanced(
|
||||||
cx: &mut TestAppContext,
|
cx: &mut TestAppContext,
|
||||||
@@ -728,6 +750,92 @@ fn theme_editor_save_and_apply_persists_copy_and_reloads_its_foreground(cx: &mut
|
|||||||
assert_eq!(palette_foreground(&mut window), applied.color("terminal", "foreground").unwrap());
|
assert_eq!(palette_foreground(&mut window), applied.color("terminal", "foreground").unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
fn advanced_selection_and_cursor_text_picker_colors_preview_persist_apply_and_reopen(
|
||||||
|
cx: &mut TestAppContext,
|
||||||
|
) {
|
||||||
|
use super::theme_advanced::ThemeAdvancedField;
|
||||||
|
|
||||||
|
let _fixture_guard = lock_theme_studio();
|
||||||
|
let _settings_guard = SettingsBytesGuard::capture();
|
||||||
|
std::fs::write(nebula_settings::settings_path(), TEST_SETTINGS)
|
||||||
|
.expect("write isolated advanced color settings");
|
||||||
|
let mut theme_cleanup = CustomThemeCleanup::default();
|
||||||
|
let (pane, mut window) = open_settings(cx);
|
||||||
|
let before_library_ids = custom_theme_ids();
|
||||||
|
let saved_name = format!("Advanced colors native test {}", std::process::id());
|
||||||
|
let selection_background = [0x1b, 0x2c, 0x3d];
|
||||||
|
let selection_foreground = [0xe1, 0xd2, 0xc3];
|
||||||
|
let cursor_text = [0x12, 0xeb, 0x77];
|
||||||
|
|
||||||
|
open_theme_editor(&mut window);
|
||||||
|
edit_input("theme-editor-name", &saved_name, &mut window);
|
||||||
|
click("theme-editor-advanced-toggle", &mut window);
|
||||||
|
assert!(window.debug_bounds("theme-editor-preview-cursor").is_some());
|
||||||
|
|
||||||
|
emit_advanced_picker_color(
|
||||||
|
&pane,
|
||||||
|
ThemeAdvancedField::SelectionBackground,
|
||||||
|
selection_background,
|
||||||
|
&mut window,
|
||||||
|
);
|
||||||
|
emit_advanced_picker_color(
|
||||||
|
&pane,
|
||||||
|
ThemeAdvancedField::SelectionForeground,
|
||||||
|
selection_foreground,
|
||||||
|
&mut window,
|
||||||
|
);
|
||||||
|
emit_advanced_picker_color(&pane, ThemeAdvancedField::CursorText, cursor_text, &mut window);
|
||||||
|
|
||||||
|
let draft = editor_draft(&pane, &mut window);
|
||||||
|
assert_eq!(draft.terminal.selection_background, Some(selection_background));
|
||||||
|
assert_eq!(draft.terminal.selection_foreground, Some(selection_foreground));
|
||||||
|
assert_eq!(draft.terminal.cursor_text, Some(cursor_text));
|
||||||
|
|
||||||
|
click("theme-editor-save-apply", &mut window);
|
||||||
|
assert!(window.debug_bounds("theme-editor-dialog").is_none());
|
||||||
|
|
||||||
|
let after_documents = custom_theme_documents();
|
||||||
|
for document in &after_documents {
|
||||||
|
if document.id().is_some_and(|id| !before_library_ids.iter().any(|before| before == id))
|
||||||
|
&& document.name().starts_with(&saved_name)
|
||||||
|
{
|
||||||
|
theme_cleanup.track(document);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let applied_id = RuntimeSettings::load().custom_theme.expect("advanced color theme is active");
|
||||||
|
let applied = after_documents
|
||||||
|
.iter()
|
||||||
|
.find(|document| document.id() == Some(applied_id.as_str()))
|
||||||
|
.expect("advanced color theme remains in the library");
|
||||||
|
let applied_definition = applied.definition().expect("saved advanced color definition");
|
||||||
|
assert_eq!(applied_definition.terminal.selection_background, Some(selection_background));
|
||||||
|
assert_eq!(applied_definition.terminal.selection_foreground, Some(selection_foreground));
|
||||||
|
assert_eq!(applied_definition.terminal.cursor_text, Some(cursor_text));
|
||||||
|
|
||||||
|
window.read(|cx| {
|
||||||
|
let palette = &cx.global::<crate::gpui_shell::config::Settings>().palette;
|
||||||
|
let bytes = |color: gpui::Rgba| {
|
||||||
|
[
|
||||||
|
(color.r * 255.0).round() as u8,
|
||||||
|
(color.g * 255.0).round() as u8,
|
||||||
|
(color.b * 255.0).round() as u8,
|
||||||
|
]
|
||||||
|
};
|
||||||
|
assert_eq!(bytes(palette.selection), selection_background);
|
||||||
|
assert_eq!(palette.selection_foreground.map(bytes), Some(selection_foreground));
|
||||||
|
assert_eq!(palette.cursor_text.map(bytes), Some(cursor_text));
|
||||||
|
});
|
||||||
|
|
||||||
|
click("open-theme-picker", &mut window);
|
||||||
|
assert!(window.debug_bounds("appearance-picker-dialog").is_some());
|
||||||
|
click("customize-theme", &mut window);
|
||||||
|
let reopened = editor_draft(&pane, &mut window);
|
||||||
|
assert_eq!(reopened.terminal.selection_background, Some(selection_background));
|
||||||
|
assert_eq!(reopened.terminal.selection_foreground, Some(selection_foreground));
|
||||||
|
assert_eq!(reopened.terminal.cursor_text, Some(cursor_text));
|
||||||
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn invalid_color_stays_dirty_and_save_rejects_after_a_later_valid_edit(cx: &mut TestAppContext) {
|
fn invalid_color_stays_dirty_and_save_rejects_after_a_later_valid_edit(cx: &mut TestAppContext) {
|
||||||
let _fixture_guard = lock_theme_studio();
|
let _fixture_guard = lock_theme_studio();
|
||||||
|
|||||||
Reference in new issue
Block a user