155 lines
5.9 KiB
Rust
155 lines
5.9 KiB
Rust
use galaxyui::elements::{
|
|
Align, Border, ConstrainedBox, Container, CornerRadius, Flex, Highlight, ParentElement, Radius,
|
|
Shrinkable, Text,
|
|
};
|
|
use warpui::fonts::{Properties, Weight};
|
|
use warpui::ui_components::components::{Coords, UiComponent, UiComponentStyles};
|
|
use warpui::ui_components::text::Span;
|
|
use warpui::Element;
|
|
|
|
use crate::appearance::Appearance;
|
|
use crate::launch_configs::launch_config::LaunchConfig;
|
|
use crate::search::result_renderer::ItemHighlightState;
|
|
use crate::themes::theme::Fill;
|
|
|
|
impl LaunchConfig {
|
|
/// Renders a [`LaunchConfig`] using a [`StylesProvider`]. Any character indices of the launch
|
|
/// config title contained within `highlighted_indices` are highlighted in bold.
|
|
pub(super) fn render(
|
|
&self,
|
|
appearance: &Appearance,
|
|
item_highlight_state: ItemHighlightState,
|
|
highlight_indices: Vec<usize>,
|
|
) -> Box<dyn Element> {
|
|
let bg_color = background_fill(item_highlight_state, appearance);
|
|
|
|
let text_color = appearance.theme().main_text_color(bg_color).into_solid();
|
|
|
|
let highlight = Highlight::new()
|
|
.with_properties(Properties::default().weight(Weight::Bold))
|
|
.with_foreground_color(text_color);
|
|
|
|
let label = self
|
|
.render_launch_config_name(appearance, item_highlight_state)
|
|
.with_single_highlight(highlight, highlight_indices)
|
|
.finish();
|
|
|
|
let mut configuration = Flex::row();
|
|
configuration.add_child(Shrinkable::new(1., Align::new(label).left().finish()).finish());
|
|
|
|
configuration.add_child(
|
|
Container::new(self.render_config_description(appearance))
|
|
.with_margin_right(14.)
|
|
.finish(),
|
|
);
|
|
|
|
ConstrainedBox::new(configuration.finish())
|
|
.with_height(40.)
|
|
.finish()
|
|
}
|
|
|
|
fn default_pill_styles(appearance: &Appearance) -> UiComponentStyles {
|
|
UiComponentStyles {
|
|
font_family_id: Some(appearance.ui_font_family()),
|
|
font_size: Some(appearance.monospace_font_size()),
|
|
font_color: Some(
|
|
appearance
|
|
.theme()
|
|
.hint_text_color(appearance.theme().background())
|
|
.into_solid(),
|
|
),
|
|
border_radius: Some(CornerRadius::with_all(Radius::Pixels(4.))),
|
|
background: Some(appearance.theme().background().into()),
|
|
height: Some(24.),
|
|
padding: Some(Coords::default().left(6.).right(6.)),
|
|
margin: Some(Coords::default().left(3.)),
|
|
..Default::default()
|
|
}
|
|
}
|
|
|
|
fn render_string_with_pill_styling(
|
|
str: impl Into<String>,
|
|
appearance: &Appearance,
|
|
) -> Box<dyn Element> {
|
|
let style = Self::default_pill_styles(appearance);
|
|
let mut container =
|
|
Container::new(Align::new(Span::new(str.into(), style).build().finish()).finish());
|
|
let mut border = Border::all(style.border_width.unwrap_or_default());
|
|
if let Some(border_color) = style.border_color {
|
|
border = border.with_border_fill(border_color);
|
|
}
|
|
container = container.with_border(border);
|
|
if let Some(padding) = style.padding {
|
|
container = container
|
|
.with_padding_top(padding.top)
|
|
.with_padding_right(padding.right)
|
|
.with_padding_bottom(padding.bottom)
|
|
.with_padding_left(padding.left);
|
|
}
|
|
if let Some(radius) = style.border_radius {
|
|
container = container.with_corner_radius(radius);
|
|
}
|
|
if let Some(background_color) = style.background {
|
|
container = container.with_background(background_color);
|
|
}
|
|
let mut sized_container = ConstrainedBox::new(container.finish());
|
|
if let Some(width) = style.width {
|
|
sized_container = sized_container.with_width(width);
|
|
}
|
|
if let Some(height) = style.height {
|
|
sized_container = sized_container.with_height(height);
|
|
}
|
|
let mut container = Container::new(Align::new(sized_container.finish()).finish());
|
|
if let Some(margin) = style.margin {
|
|
container = container
|
|
.with_margin_top(margin.top)
|
|
.with_margin_right(margin.right)
|
|
.with_margin_bottom(margin.bottom)
|
|
.with_margin_left(margin.left);
|
|
}
|
|
container.finish()
|
|
}
|
|
|
|
fn render_config_description(&self, appearance: &Appearance) -> Box<dyn Element> {
|
|
let num_windows = self.windows.len();
|
|
let num_tabs: usize = self.windows.iter().map(|window| window.tabs.len()).sum();
|
|
let mut windows_str = num_windows.to_string();
|
|
match num_windows {
|
|
1 => windows_str.push_str(" window "),
|
|
_ => windows_str.push_str(" windows"),
|
|
}
|
|
let mut tabs_str = num_tabs.to_string();
|
|
match num_tabs {
|
|
1 => tabs_str.push_str(" tab "),
|
|
_ => tabs_str.push_str(" tabs"),
|
|
}
|
|
Flex::row()
|
|
.with_children(vec![
|
|
Self::render_string_with_pill_styling(windows_str, appearance),
|
|
Self::render_string_with_pill_styling(tabs_str, appearance),
|
|
])
|
|
.finish()
|
|
}
|
|
|
|
fn render_launch_config_name(
|
|
&self,
|
|
appearance: &Appearance,
|
|
item_highlight_state: ItemHighlightState,
|
|
) -> Text {
|
|
let text = Text::new_inline(
|
|
self.name.clone(),
|
|
appearance.ui_font_family(),
|
|
appearance.monospace_font_size(),
|
|
);
|
|
|
|
let bg_color = background_fill(item_highlight_state, appearance);
|
|
text.with_color(appearance.theme().sub_text_color(bg_color).into_solid())
|
|
}
|
|
}
|
|
|
|
fn background_fill(item_highlight_state: ItemHighlightState, appearance: &Appearance) -> Fill {
|
|
item_highlight_state
|
|
.container_background_fill(appearance)
|
|
.unwrap_or_else(|| appearance.theme().surface_2())
|
|
}
|