103 lines
3.0 KiB
Rust
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,
|
|
);
|
|
}
|
|
}
|