use super::*;
pub(super) struct EditorChrome {
pub(super) surface: Color,
pub(super) border: Color,
pub(super) chrome_background: Color,
pub(super) gutter_background: Color,
pub(super) minimap_background: Color,
pub(super) scrollbar_track: Color,
pub(super) scrollbar_thumb: Color,
pub(super) separator: Color,
pub(super) ink: Color,
pub(super) dim_ink: Color,
pub(super) accent: Color,
pub(super) active_line: Color,
pub(super) indent_guide: Color,
pub(super) whitespace_mark: Color,
pub(super) selection: Color,
pub(super) search_hit: Color,
pub(super) search_current: Color,
pub(super) occurrence: Color,
pub(super) popup_background: Color,
pub(super) popup_border: Color,
pub(super) popup_selected: Color,
}
impl EditorChrome {
pub(super) fn resolve(editor: &CodeEditor) -> Self {
let style = editor.base.style();
let theme = crate::style::resolved_theme_style_shared("code_editor");
let pick = |explicit: Option<Color>, themed: Option<Color>, literal: Color| -> Color {
explicit.or(themed).unwrap_or(literal)
};
let themed_bg = theme.as_ref().and_then(|t| t.background_color);
let themed_ink = theme.as_ref().and_then(|t| t.text_color);
let themed_border = theme.as_ref().and_then(|t| t.border_color);
let (accent, themed_surface) = crate::style::theme_manager()
.current_theme()
.map(|active| {
(
active.colors.primary,
(active.colors.surface_container != active.colors.background)
.then_some(active.colors.surface_container),
)
})
.unwrap_or((editor.palette.bracket_color, None));
let caller_surface = if style.theme_derived { None } else { style.background_color };
let surface =
caller_surface.or(themed_surface).or(themed_bg).unwrap_or(editor.palette.background);
let ink = pick(style.text_color, themed_ink, editor.palette.color_for(TokenKind::Plain));
let border = pick(style.border_color, themed_border, editor.palette.border_color);
let warning = crate::style::semantic_color(crate::style::SemanticColor::Warning)
.unwrap_or(editor.palette.search_color);
let error = crate::style::semantic_color(crate::style::SemanticColor::Error)
.unwrap_or(editor.palette.border_color);
let chrome_background = surface.blend(&ink, 0.06);
Self {
surface,
border: if border == surface { error } else { border },
chrome_background,
gutter_background: surface.blend(&ink, 0.03),
minimap_background: surface.blend(&ink, 0.04),
scrollbar_track: surface.blend(&ink, 0.05),
scrollbar_thumb: surface.blend(&ink, 0.22),
separator: surface.blend(&ink, 0.12),
ink,
dim_ink: ink.legible_on(chrome_background, 4.5).blend(&chrome_background, 0.30),
accent,
active_line: surface.blend(&ink, 0.04),
indent_guide: surface.blend(&ink, 0.1),
whitespace_mark: surface.blend(&ink, 0.25),
selection: accent.blend(&surface, 0.7),
search_hit: warning.blend(&surface, 0.55),
search_current: warning.blend(&surface, 0.15),
occurrence: accent.blend(&surface, 0.82),
popup_background: surface.blend(&ink, 0.02),
popup_border: if border == surface { error } else { border },
popup_selected: accent.blend(&surface, 0.82),
}
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct TabSlot {
pub(crate) buffer: usize,
pub(crate) rect: Rect,
pub(crate) close: Rect,
}
pub(crate) const TAB_LEFT_PAD: i32 = 10;
pub(crate) const TAB_MARKER_SLOT: i32 = 12;
pub(crate) const TAB_CLOSE_SLOT: i32 = 24;
pub(crate) const TAB_MAX_WIDTH: i32 = 240;
pub(crate) const TAB_MIN_WIDTH: i32 = 84;
pub(super) struct RowGeometry<'a> {
pub(super) layout: Option<&'a RowLayout>,
pub(super) grid: &'a LineGrid<'a>,
pub(super) cell: f32,
pub(super) first_column: usize,
pub(super) indent: f32,
}
impl<'a> RowGeometry<'a> {
pub(super) fn x_of(&self, index: usize) -> f32 {
if let Some(x) = self.layout.and_then(|layout| layout.x_of_char(index)) {
return x;
}
let column = self.grid.column_of_char(index).saturating_sub(self.first_column);
self.indent + column as f32 * self.cell
}
pub(super) fn byte_of_char(&self, index: usize) -> usize {
self.grid.byte_of_char(index)
}
pub(super) fn char_of_byte(&self, byte: usize) -> usize {
self.grid.char_of_byte(byte)
}
}