Files
galaxy/app/src/search_bar.rs
T

173 lines
5.7 KiB
Rust

use galaxyui::elements::{
Border, ChildView, Clipped, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment,
DispatchEventResult, EventHandler, Flex, Icon, ParentElement, Radius, Shrinkable,
};
use warpui::ui_components::components::{Coords, UiComponentStyles};
use warpui::{Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle};
use crate::appearance::Appearance;
use crate::editor::EditorView;
const SEARCH_ICON_PATH: &str = "bundled/svg/search.svg";
const ICON_SIZE: f32 = 12.;
pub struct SearchBar {
editor: ViewHandle<EditorView>,
custom_styles: UiComponentStyles,
}
#[derive(Debug)]
pub enum SearchBarAction {
SearchBarClicked,
}
pub enum SearchBarEvent {}
impl TypedActionView for SearchBar {
type Action = SearchBarAction;
fn handle_action(&mut self, action: &SearchBarAction, ctx: &mut ViewContext<Self>) {
match action {
SearchBarAction::SearchBarClicked => self.focus_search_bar(ctx),
}
}
}
impl Entity for SearchBar {
type Event = SearchBarEvent;
}
impl View for SearchBar {
fn ui_name() -> &'static str {
"SearchBar"
}
fn render(&self, app: &galaxyui::AppContext) -> Box<dyn Element> {
let styles = {
let appearance = Appearance::as_ref(app);
let context_styles = UiComponentStyles {
font_size: Some(appearance.ui_font_size()),
font_family_id: Some(appearance.ui_font_family()),
padding: Some(Coords {
top: 10.,
bottom: 10.,
left: 10.,
right: 10.,
}),
border_width: Some(1.),
border_radius: Some(CornerRadius::with_all(Radius::Pixels(3.))),
background: Some(appearance.theme().background().into()),
border_color: Some(appearance.theme().foreground().with_opacity(20).into()),
font_color: Some(
appearance
.theme()
.main_text_color(appearance.theme().surface_2())
.into(),
),
..Default::default()
};
context_styles.merge(self.custom_styles)
};
let search_icon = Icon::new(
SEARCH_ICON_PATH,
styles.font_color.expect("Should get font colour"),
);
let search_bar_element = Container::new(
ConstrainedBox::new(search_icon.finish())
.with_height(ICON_SIZE)
.with_width(ICON_SIZE)
.finish(),
)
.with_padding_right(5.)
.finish();
let mut container = Container::new(
Clipped::new(
Flex::row()
.with_child(search_bar_element)
.with_child(
Clipped::new(
Shrinkable::new(1., ChildView::new(&self.editor).finish()).finish(),
)
.finish(),
)
.with_cross_axis_alignment(CrossAxisAlignment::Center)
.finish(),
)
.finish(),
);
// Setting up the border
if let Some(corner) = styles.border_radius {
container = container.with_corner_radius(corner);
}
let mut border = Border::all(styles.border_width.unwrap_or_default());
if let Some(border_color) = styles.border_color {
border = border.with_border_fill(border_color);
}
container = container.with_border(border);
// Position-related settings
if let Some(padding) = styles.padding {
container = container
.with_padding_left(padding.left)
.with_padding_top(padding.top)
.with_padding_right(padding.right)
.with_padding_bottom(padding.bottom);
}
if let Some(margin) = styles.margin {
container = container
.with_margin_left(margin.left)
.with_margin_top(margin.top)
.with_margin_right(margin.right)
.with_margin_bottom(margin.bottom);
}
if let Some(background) = styles.background {
container = container.with_background(background);
}
let container_with_event_handler = EventHandler::new(container.finish())
.on_left_mouse_down(move |ctx, _, _| {
ctx.dispatch_typed_action(SearchBarAction::SearchBarClicked);
DispatchEventResult::StopPropagation
})
.finish();
match (styles.height, styles.width) {
(None, None) => ConstrainedBox::new(container_with_event_handler),
(_, _) => {
let mut constrained_box = ConstrainedBox::new(container_with_event_handler);
if let Some(height) = styles.height {
constrained_box = constrained_box.with_height(height);
}
if let Some(width) = styles.width {
constrained_box = constrained_box.with_width(width);
}
constrained_box
}
}
.finish()
}
}
impl SearchBar {
pub fn new(search_editor: ViewHandle<EditorView>) -> Self {
SearchBar {
editor: search_editor,
custom_styles: UiComponentStyles::default(),
}
}
pub fn with_style(&mut self, styles: UiComponentStyles) {
self.custom_styles = self.custom_styles.merge(styles);
}
pub fn focus_search_bar(&mut self, ctx: &mut ViewContext<Self>) {
ctx.focus(&self.editor);
ctx.notify();
}
}