From 23d2b2d4074067b3b7f85ed31ef5dff558f8511d Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Mon, 19 Apr 2021 15:55:32 +0200 Subject: [PATCH] type tooltip rendering --- editor/src/editor/mvc/ed_update.rs | 6 +- editor/src/editor/mvc/ed_view.rs | 78 ++++++++++++++++++++------ editor/src/editor/render_ast.rs | 9 ++- editor/src/editor/style.rs | 2 +- editor/src/graphics/primitives/text.rs | 4 +- editor/src/ui/theme.rs | 2 +- editor/src/ui/tooltip.rs | 60 +++++++++++++++----- 7 files changed, 121 insertions(+), 40 deletions(-) diff --git a/editor/src/editor/mvc/ed_update.rs b/editor/src/editor/mvc/ed_update.rs index 905995d659..ec32085af4 100644 --- a/editor/src/editor/mvc/ed_update.rs +++ b/editor/src/editor/mvc/ed_update.rs @@ -168,7 +168,7 @@ impl<'a> EdModel<'a> { self.selected_expr_opt = Some(SelectedExpression { ast_node_id, mark_node_id: parent_id, - type_str: "Todo".to_owned(), + type_str: "Str".to_owned(), // TODO get this String from type inference }); self.dirty = true; @@ -189,7 +189,7 @@ impl<'a> EdModel<'a> { self.selected_expr_opt = Some(SelectedExpression { ast_node_id, mark_node_id, - type_str: "Todo".to_owned(), + type_str: "Str".to_owned(), // TODO get this String from type inference }); self.dirty = true; @@ -259,7 +259,7 @@ impl<'a> EdModel<'a> { None }; - // have to split the previous if up to prevent borrowing issues + // have to split the previous `if` up to prevent borrowing issues if let Some(expr_mark_node_id) = expr_mark_node_id_opt { let caret_pos = self.get_caret(); diff --git a/editor/src/editor/mvc/ed_view.rs b/editor/src/editor/mvc/ed_view.rs index ebd06fe776..41ba6e6d72 100644 --- a/editor/src/editor/mvc/ed_view.rs +++ b/editor/src/editor/mvc/ed_view.rs @@ -1,6 +1,7 @@ use super::ed_model::EdModel; use crate::editor::config::Config; use crate::editor::ed_error::EdResult; +use crate::editor::mvc::ed_model::SelectedExpression; use crate::editor::render_ast::build_code_graphics; use crate::editor::render_debug::build_debug_graphics; use crate::graphics::primitives::rect::Rect; @@ -8,6 +9,7 @@ use crate::ui::text::caret_w_select::make_caret_rect; use crate::ui::text::caret_w_select::make_selection_rect; use crate::ui::text::caret_w_select::CaretWSelect; use crate::ui::text::selection::Selection; +use crate::ui::tooltip::ToolTip; use crate::ui::ui_error::MissingGlyphDims; use cgmath::Vector2; use snafu::OptionExt; @@ -19,6 +21,32 @@ pub struct RenderedWgpu { pub rects: Vec, } +impl RenderedWgpu { + pub fn new() -> Self { + Self { + text_sections: Vec::new(), + rects: Vec::new(), + } + } + + pub fn add_text(&mut self, new_text_section: glyph_brush::OwnedSection) { + self.text_sections.push(new_text_section); + } + + pub fn add_rect(&mut self, new_rect: Rect) { + self.rects.push(new_rect); + } + + pub fn add_rects(&mut self, new_rects: Vec) { + self.rects.extend(new_rects); + } + + pub fn extend(&mut self, rendered_wgpu: RenderedWgpu) { + self.text_sections.extend(rendered_wgpu.text_sections); + self.rects.extend(rendered_wgpu.rects); + } +} + // create text and rectangles based on EdModel's markup_root pub fn model_to_wgpu<'a>( ed_model: &'a mut EdModel, @@ -28,9 +56,9 @@ pub fn model_to_wgpu<'a>( ) -> EdResult { let glyph_dim_rect = ed_model.glyph_dim_rect_opt.context(MissingGlyphDims {})?; - let mut all_text_sections = Vec::new(); + let mut all_rendered = RenderedWgpu::new(); - let (code_section, mut rects) = build_code_graphics( + let rendered_code_graphics = build_code_graphics( ed_model.markup_node_pool.get(ed_model.markup_root_id), size, txt_coords, @@ -39,7 +67,7 @@ pub fn model_to_wgpu<'a>( &ed_model.markup_node_pool, )?; - all_text_sections.push(code_section); + all_rendered.extend(rendered_code_graphics); let caret_w_sel_vec = ed_model .caret_w_select_vec @@ -47,28 +75,31 @@ pub fn model_to_wgpu<'a>( .map(|(caret_w_sel, _)| *caret_w_sel) .collect(); - let mut sel_rects = - build_selection_graphics(caret_w_sel_vec, txt_coords, config, glyph_dim_rect)?; + let rendered_selection = build_selection_graphics( + caret_w_sel_vec, + &ed_model.selected_expr_opt, + txt_coords, + config, + glyph_dim_rect, + )?; - rects.append(&mut sel_rects); + all_rendered.extend(rendered_selection); if ed_model.show_debug_view { - all_text_sections.push(build_debug_graphics(size, txt_coords, config, ed_model)?); + all_rendered.add_text(build_debug_graphics(size, txt_coords, config, ed_model)?); } - Ok(RenderedWgpu { - text_sections: all_text_sections, - rects, - }) + Ok(all_rendered) } pub fn build_selection_graphics( caret_w_select_vec: Vec, + selected_expr_opt: &Option, txt_coords: Vector2, config: &Config, glyph_dim_rect: Rect, -) -> EdResult> { - let mut rects = Vec::new(); +) -> EdResult { + let mut all_rendered = RenderedWgpu::new(); let char_width = glyph_dim_rect.width; let char_height = glyph_dim_rect.height; @@ -90,16 +121,31 @@ pub fn build_selection_graphics( let width = ((end_pos.column as f32) * char_width) - ((start_pos.column as f32) * char_width); - rects.push(make_selection_rect( + all_rendered.add_rect(make_selection_rect( sel_rect_x, sel_rect_y, width, &glyph_dim_rect, &config.ed_theme.ui_theme, )); + + // redner tooltip showing type + if let Some(selected_expr) = selected_expr_opt { + let tooltip = ToolTip { + position_x: sel_rect_x, + position_y: sel_rect_y - glyph_dim_rect.height, + text: selected_expr.type_str.clone(), + }; + + let (tip_rect, tip_text) = + tooltip.render_tooltip(&glyph_dim_rect, &config.ed_theme.ui_theme); + + all_rendered.add_rect(tip_rect); + all_rendered.add_text(tip_text); + } } - rects.push(make_caret_rect( + all_rendered.add_rect(make_caret_rect( top_left_x, top_left_y, &glyph_dim_rect, @@ -107,5 +153,5 @@ pub fn build_selection_graphics( )); } - Ok(rects) + Ok(all_rendered) } diff --git a/editor/src/editor/render_ast.rs b/editor/src/editor/render_ast.rs index b6300dadf6..dad35cb176 100644 --- a/editor/src/editor/render_ast.rs +++ b/editor/src/editor/render_ast.rs @@ -1,4 +1,5 @@ use super::markup::nodes::{MarkupNode, BLANK_PLACEHOLDER}; +use crate::editor::mvc::ed_view::RenderedWgpu; use crate::editor::slow_pool::SlowPool; use crate::editor::{ed_error::EdResult, theme::EdTheme, util::map_get}; use crate::graphics::primitives::rect::Rect; @@ -15,9 +16,10 @@ pub fn build_code_graphics<'a>( config: &Config, glyph_dim_rect: Rect, markup_node_pool: &'a SlowPool, -) -> EdResult<(glyph_brush::OwnedSection, Vec)> { +) -> EdResult { let area_bounds = (size.width as f32, size.height as f32); let layout = wgpu_glyph::Layout::default().h_align(wgpu_glyph::HorizontalAlign::Left); + let mut rendered_wgpu = RenderedWgpu::new(); let (glyph_text_vec, rects) = markup_to_wgpu( markup_node, @@ -33,7 +35,10 @@ pub fn build_code_graphics<'a>( let section = gr_text::section_from_glyph_text(glyph_text_vec, txt_coords.into(), area_bounds, layout); - Ok((section, rects)) + rendered_wgpu.add_rects(rects); + rendered_wgpu.add_text(section); + + Ok(rendered_wgpu) } struct CodeStyle<'a> { diff --git a/editor/src/editor/style.rs b/editor/src/editor/style.rs index 8395a7a95e..095b9d60aa 100644 --- a/editor/src/editor/style.rs +++ b/editor/src/editor/style.rs @@ -1 +1 @@ -pub const CODE_TXT_XY: (f32, f32) = (30.0, 30.0); +pub const CODE_TXT_XY: (f32, f32) = (40.0, 60.0); diff --git a/editor/src/graphics/primitives/text.rs b/editor/src/graphics/primitives/text.rs index c0b2451426..f2012059e3 100644 --- a/editor/src/graphics/primitives/text.rs +++ b/editor/src/graphics/primitives/text.rs @@ -84,8 +84,8 @@ fn section_from_text<'a>( ) } -pub fn owned_section_from_text<'a>( - text: &'a Text, +pub fn owned_section_from_text( + text: &Text, layout: wgpu_glyph::Layout, ) -> OwnedSection { OwnedSection { diff --git a/editor/src/ui/theme.rs b/editor/src/ui/theme.rs index ce7a3c45bd..640c8daa6a 100644 --- a/editor/src/ui/theme.rs +++ b/editor/src/ui/theme.rs @@ -26,7 +26,7 @@ impl Default for UITheme { text: gr_colors::WHITE, caret: gr_colors::WHITE, select_highlight: from_hsba(240, 55, 100, 0.3), - tooltip_bg: from_hsb(240, 32, 30), + tooltip_bg: from_hsb(240, 60, 50), tooltip_text: gr_colors::WHITE, default_font_size: 30.0, } diff --git a/editor/src/ui/tooltip.rs b/editor/src/ui/tooltip.rs index ad500d3200..2f26d51c36 100644 --- a/editor/src/ui/tooltip.rs +++ b/editor/src/ui/tooltip.rs @@ -4,25 +4,46 @@ use crate::graphics::primitives::text::layout_from_text; use crate::graphics::primitives::text::Text; use crate::ui::theme::UITheme; -struct ToolTip { - position_x: f32, - position_y: f32, - text: String, +pub struct ToolTip { + pub position_x: f32, + pub position_y: f32, + pub text: String, } impl ToolTip { - fn make_tooltip_rect(&self, width: f32, height: f32, ui_theme: &UITheme) -> Rect { + fn make_tooltip_rect( + &self, + width: f32, + height: f32, + height_padding: f32, + y_margin: f32, + ui_theme: &UITheme, + ) -> Rect { Rect { - top_left_coords: (self.position_x, self.position_y).into(), - height, + top_left_coords: ( + self.position_x, + self.position_y - (height_padding + y_margin), + ) + .into(), + height: height + height_padding, width, color: ui_theme.tooltip_bg, } } - fn make_tooltip_text<'a>(&'a self, ui_theme: &UITheme) -> Text<'a> { + fn make_tooltip_text<'a>( + &'a self, + x_offset: f32, + y_offset: f32, + y_margin: f32, + ui_theme: &UITheme, + ) -> Text<'a> { Text { - position: (self.position_x, self.position_y).into(), //TODO adjust position + position: ( + self.position_x + x_offset, + self.position_y - (y_offset + y_margin), + ) + .into(), color: ui_theme.tooltip_text, text: &self.text, size: ui_theme.default_font_size, @@ -34,18 +55,27 @@ impl ToolTip { &self, glyph_dim_rect: &Rect, ui_theme: &UITheme, - ) -> (glyph_brush::OwnedSection, Rect) { - let text = self.make_tooltip_text(ui_theme); + ) -> (Rect, glyph_brush::OwnedSection) { + let width_padding = glyph_dim_rect.height / 1.3; + let height_padding = width_padding / 1.3; + + let text_x_offset = width_padding / 2.0; + let text_y_offset = height_padding / 2.0; + + let y_margin = glyph_dim_rect.height / 4.0; + + let text = self.make_tooltip_text(text_x_offset, text_y_offset, y_margin, ui_theme); let text_layout = layout_from_text(&text); let text_section = gr_text::owned_section_from_text(&text, text_layout); - let padding = 0.5 * glyph_dim_rect.height; let rect = self.make_tooltip_rect( - glyph_dim_rect.width * (text.text.len() as f32) + padding, - glyph_dim_rect.height + padding, + glyph_dim_rect.width * (text.text.len() as f32) + width_padding, + glyph_dim_rect.height, + height_padding, + y_margin, ui_theme, ); - (text_section, rect) + (rect, text_section) } }