use crate::graph::{
CachePolicy, DrawPrimitiveNode, IsolationReasons, LayerNode, PrimitiveEntry, PrimitiveNode,
PrimitivePhase, ProjectiveTransform, RenderGraph, RenderNode, TextPrimitiveNode,
};
use crate::raster_cache::LayerRasterCacheHashes;
use cranpose_ui_graphics::{
Brush, Color, CornerRadii, DrawPrimitive, GraphicsLayer, Point, Rect, Size,
};
#[derive(Clone, PartialEq, Eq)]
pub struct DevOverlayKey {
pub text: String,
pub viewport_width_bits: u32,
pub viewport_height_bits: u32,
}
impl DevOverlayKey {
pub fn new(text: &str, viewport: Size) -> Self {
Self {
text: text.to_string(),
viewport_width_bits: viewport.width.to_bits(),
viewport_height_bits: viewport.height.to_bits(),
}
}
}
pub fn build_dev_overlay_graph(
text: &str,
viewport: Size,
node_id: cranpose_core::NodeId,
) -> RenderGraph {
let padding = 8.0;
let font_size = 14.0;
let char_width = 7.0;
let text_width = text.len() as f32 * char_width;
let text_height = font_size * 1.4;
let x = (viewport.width - text_width - padding * 2.0).max(padding);
let y = padding;
let mut overlay_layer = LayerNode {
node_id: Some(node_id),
local_bounds: Rect {
x: 0.0,
y: 0.0,
width: text_width + padding,
height: text_height + padding / 2.0,
},
transform_to_parent: ProjectiveTransform::translation(x, y),
content_offset: Point::default(),
motion_context_animated: false,
translated_content_context: false,
translated_content_offset: Point::default(),
graphics_layer: GraphicsLayer::default(),
clip_to_bounds: false,
shadow_clip: None,
hit_test: None,
has_hit_targets: false,
isolation: IsolationReasons::default(),
cache_policy: CachePolicy::None,
cache_hashes: LayerRasterCacheHashes::default(),
cache_hashes_valid: false,
children: vec![
RenderNode::Primitive(PrimitiveEntry {
phase: PrimitivePhase::BeforeChildren,
node: PrimitiveNode::Draw(DrawPrimitiveNode {
primitive: DrawPrimitive::RoundRect {
rect: Rect {
x: 0.0,
y: 0.0,
width: text_width + padding,
height: text_height + padding / 2.0,
},
brush: Brush::Solid(Color(0.0, 0.0, 0.0, 0.7)),
radii: CornerRadii::uniform(4.0),
},
clip: None,
}),
}),
RenderNode::Primitive(PrimitiveEntry {
phase: PrimitivePhase::AfterChildren,
node: PrimitiveNode::Text(Box::new(TextPrimitiveNode {
node_id,
rect: Rect {
x: padding / 2.0,
y: padding / 4.0,
width: text_width,
height: text_height,
},
text: cranpose_ui::text::AnnotatedString::from(text),
text_style: cranpose_ui::TextStyle::default(),
font_size,
layout_options: cranpose_ui::TextLayoutOptions::default(),
clip: None,
})),
}),
],
};
overlay_layer.recompute_raster_cache_hashes();
let mut graph = RenderGraph::new(LayerNode {
node_id: None,
local_bounds: Rect::from_size(viewport),
transform_to_parent: ProjectiveTransform::identity(),
content_offset: Point::default(),
motion_context_animated: false,
translated_content_context: false,
translated_content_offset: Point::default(),
graphics_layer: GraphicsLayer::default(),
clip_to_bounds: false,
shadow_clip: None,
hit_test: None,
has_hit_targets: false,
isolation: IsolationReasons::default(),
cache_policy: CachePolicy::None,
cache_hashes: LayerRasterCacheHashes::default(),
cache_hashes_valid: false,
children: vec![RenderNode::Layer(Box::new(overlay_layer))],
});
graph.root.recompute_raster_cache_hashes();
graph
}