Files
galaxy/crates/editor/src/render/element/horizontal_rule.rs
T

103 lines
3.0 KiB
Rust

use warpui::{
elements::{CornerRadius, Radius},
geometry::{
rect::RectF,
vector::{Vector2F, vec2f},
},
};
use crate::{
extract_block,
render::{
element::paint::{CursorData, CursorDisplayType},
model::{BlockItem, RenderState, RichTextStyles, viewport::ViewportItem},
},
};
use super::{RenderContext, RenderableBlock};
/// Renderable representation of a single horizontal rule separator.
pub struct HorizontalRule {
viewport_item: ViewportItem,
}
impl HorizontalRule {
pub fn new(viewport_item: ViewportItem) -> Self {
Self { viewport_item }
}
pub fn draw_rect(
content_position: Vector2F,
selected: bool,
draw_cursor: bool,
size: Vector2F,
styles: &RichTextStyles,
ctx: &mut RenderContext,
) {
let rect_origin = ctx.content_to_screen(content_position);
let y_axis_offset = (size.y() - styles.horizontal_rule_style.rule_height).max(0.) / 2.;
let rule_bounds = RectF::new(
vec2f(rect_origin.x(), rect_origin.y() + y_axis_offset),
vec2f(size.x(), styles.horizontal_rule_style.rule_height),
);
let line_bounds = RectF::new(rect_origin, size);
ctx.paint
.scene
.draw_rect_with_hit_recording(rule_bounds)
.with_background(styles.horizontal_rule_style.color)
.with_corner_radius(CornerRadius::with_all(Radius::Percentage(50.)));
if selected {
ctx.paint
.scene
.draw_rect_with_hit_recording(line_bounds)
.with_background(styles.selection_fill);
}
if draw_cursor {
let end_of_line_position = content_position + vec2f(size.x(), 0.);
ctx.draw_and_save_cursor(
CursorDisplayType::Bar,
end_of_line_position,
vec2f(styles.cursor_width, size.y()),
CursorData::default(),
styles,
);
}
}
}
impl RenderableBlock for HorizontalRule {
fn viewport_item(&self) -> &ViewportItem {
&self.viewport_item
}
fn layout(
&mut self,
_model: &RenderState,
_ctx: &mut warpui::LayoutContext,
_app: &warpui::AppContext,
) {
}
fn paint(&mut self, model: &RenderState, ctx: &mut RenderContext, _app: &warpui::AppContext) {
let content = model.content();
let horizontal_rule = extract_block!(self.viewport_item, content, (block, BlockItem::HorizontalRule(rule)) => block.horizontal_rule(rule));
let selected = model.offset_in_active_selection(horizontal_rule.start_char_offset);
let draw_cursor = model.is_selection_head(horizontal_rule.start_char_offset);
Self::draw_rect(
horizontal_rule.content_origin(),
selected,
draw_cursor,
horizontal_rule.item.line_size()
- vec2f(self.viewport_item.spacing.x_axis_offset().as_f32(), 0.),
model.styles(),
ctx,
);
}
}