mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-11 05:34:11 +03:00
type tooltip rendering
This commit is contained in:
parent
633e10f9e9
commit
23d2b2d407
@ -168,7 +168,7 @@ impl<'a> EdModel<'a> {
|
|||||||
self.selected_expr_opt = Some(SelectedExpression {
|
self.selected_expr_opt = Some(SelectedExpression {
|
||||||
ast_node_id,
|
ast_node_id,
|
||||||
mark_node_id: parent_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;
|
self.dirty = true;
|
||||||
@ -189,7 +189,7 @@ impl<'a> EdModel<'a> {
|
|||||||
self.selected_expr_opt = Some(SelectedExpression {
|
self.selected_expr_opt = Some(SelectedExpression {
|
||||||
ast_node_id,
|
ast_node_id,
|
||||||
mark_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;
|
self.dirty = true;
|
||||||
@ -259,7 +259,7 @@ impl<'a> EdModel<'a> {
|
|||||||
None
|
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 {
|
if let Some(expr_mark_node_id) = expr_mark_node_id_opt {
|
||||||
let caret_pos = self.get_caret();
|
let caret_pos = self.get_caret();
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use super::ed_model::EdModel;
|
use super::ed_model::EdModel;
|
||||||
use crate::editor::config::Config;
|
use crate::editor::config::Config;
|
||||||
use crate::editor::ed_error::EdResult;
|
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_ast::build_code_graphics;
|
||||||
use crate::editor::render_debug::build_debug_graphics;
|
use crate::editor::render_debug::build_debug_graphics;
|
||||||
use crate::graphics::primitives::rect::Rect;
|
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::make_selection_rect;
|
||||||
use crate::ui::text::caret_w_select::CaretWSelect;
|
use crate::ui::text::caret_w_select::CaretWSelect;
|
||||||
use crate::ui::text::selection::Selection;
|
use crate::ui::text::selection::Selection;
|
||||||
|
use crate::ui::tooltip::ToolTip;
|
||||||
use crate::ui::ui_error::MissingGlyphDims;
|
use crate::ui::ui_error::MissingGlyphDims;
|
||||||
use cgmath::Vector2;
|
use cgmath::Vector2;
|
||||||
use snafu::OptionExt;
|
use snafu::OptionExt;
|
||||||
@ -19,6 +21,32 @@ pub struct RenderedWgpu {
|
|||||||
pub rects: Vec<Rect>,
|
pub rects: Vec<Rect>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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<Rect>) {
|
||||||
|
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
|
// create text and rectangles based on EdModel's markup_root
|
||||||
pub fn model_to_wgpu<'a>(
|
pub fn model_to_wgpu<'a>(
|
||||||
ed_model: &'a mut EdModel,
|
ed_model: &'a mut EdModel,
|
||||||
@ -28,9 +56,9 @@ pub fn model_to_wgpu<'a>(
|
|||||||
) -> EdResult<RenderedWgpu> {
|
) -> EdResult<RenderedWgpu> {
|
||||||
let glyph_dim_rect = ed_model.glyph_dim_rect_opt.context(MissingGlyphDims {})?;
|
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),
|
ed_model.markup_node_pool.get(ed_model.markup_root_id),
|
||||||
size,
|
size,
|
||||||
txt_coords,
|
txt_coords,
|
||||||
@ -39,7 +67,7 @@ pub fn model_to_wgpu<'a>(
|
|||||||
&ed_model.markup_node_pool,
|
&ed_model.markup_node_pool,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
all_text_sections.push(code_section);
|
all_rendered.extend(rendered_code_graphics);
|
||||||
|
|
||||||
let caret_w_sel_vec = ed_model
|
let caret_w_sel_vec = ed_model
|
||||||
.caret_w_select_vec
|
.caret_w_select_vec
|
||||||
@ -47,28 +75,31 @@ pub fn model_to_wgpu<'a>(
|
|||||||
.map(|(caret_w_sel, _)| *caret_w_sel)
|
.map(|(caret_w_sel, _)| *caret_w_sel)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut sel_rects =
|
let rendered_selection = build_selection_graphics(
|
||||||
build_selection_graphics(caret_w_sel_vec, txt_coords, config, glyph_dim_rect)?;
|
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 {
|
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 {
|
Ok(all_rendered)
|
||||||
text_sections: all_text_sections,
|
|
||||||
rects,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_selection_graphics(
|
pub fn build_selection_graphics(
|
||||||
caret_w_select_vec: Vec<CaretWSelect>,
|
caret_w_select_vec: Vec<CaretWSelect>,
|
||||||
|
selected_expr_opt: &Option<SelectedExpression>,
|
||||||
txt_coords: Vector2<f32>,
|
txt_coords: Vector2<f32>,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
glyph_dim_rect: Rect,
|
glyph_dim_rect: Rect,
|
||||||
) -> EdResult<Vec<Rect>> {
|
) -> EdResult<RenderedWgpu> {
|
||||||
let mut rects = Vec::new();
|
let mut all_rendered = RenderedWgpu::new();
|
||||||
let char_width = glyph_dim_rect.width;
|
let char_width = glyph_dim_rect.width;
|
||||||
let char_height = glyph_dim_rect.height;
|
let char_height = glyph_dim_rect.height;
|
||||||
|
|
||||||
@ -90,16 +121,31 @@ pub fn build_selection_graphics(
|
|||||||
let width =
|
let width =
|
||||||
((end_pos.column as f32) * char_width) - ((start_pos.column as f32) * char_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_x,
|
||||||
sel_rect_y,
|
sel_rect_y,
|
||||||
width,
|
width,
|
||||||
&glyph_dim_rect,
|
&glyph_dim_rect,
|
||||||
&config.ed_theme.ui_theme,
|
&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_x,
|
||||||
top_left_y,
|
top_left_y,
|
||||||
&glyph_dim_rect,
|
&glyph_dim_rect,
|
||||||
@ -107,5 +153,5 @@ pub fn build_selection_graphics(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(rects)
|
Ok(all_rendered)
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use super::markup::nodes::{MarkupNode, BLANK_PLACEHOLDER};
|
use super::markup::nodes::{MarkupNode, BLANK_PLACEHOLDER};
|
||||||
|
use crate::editor::mvc::ed_view::RenderedWgpu;
|
||||||
use crate::editor::slow_pool::SlowPool;
|
use crate::editor::slow_pool::SlowPool;
|
||||||
use crate::editor::{ed_error::EdResult, theme::EdTheme, util::map_get};
|
use crate::editor::{ed_error::EdResult, theme::EdTheme, util::map_get};
|
||||||
use crate::graphics::primitives::rect::Rect;
|
use crate::graphics::primitives::rect::Rect;
|
||||||
@ -15,9 +16,10 @@ pub fn build_code_graphics<'a>(
|
|||||||
config: &Config,
|
config: &Config,
|
||||||
glyph_dim_rect: Rect,
|
glyph_dim_rect: Rect,
|
||||||
markup_node_pool: &'a SlowPool,
|
markup_node_pool: &'a SlowPool,
|
||||||
) -> EdResult<(glyph_brush::OwnedSection, Vec<Rect>)> {
|
) -> EdResult<RenderedWgpu> {
|
||||||
let area_bounds = (size.width as f32, size.height as f32);
|
let area_bounds = (size.width as f32, size.height as f32);
|
||||||
let layout = wgpu_glyph::Layout::default().h_align(wgpu_glyph::HorizontalAlign::Left);
|
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(
|
let (glyph_text_vec, rects) = markup_to_wgpu(
|
||||||
markup_node,
|
markup_node,
|
||||||
@ -33,7 +35,10 @@ pub fn build_code_graphics<'a>(
|
|||||||
let section =
|
let section =
|
||||||
gr_text::section_from_glyph_text(glyph_text_vec, txt_coords.into(), area_bounds, layout);
|
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> {
|
struct CodeStyle<'a> {
|
||||||
|
@ -1 +1 @@
|
|||||||
pub const CODE_TXT_XY: (f32, f32) = (30.0, 30.0);
|
pub const CODE_TXT_XY: (f32, f32) = (40.0, 60.0);
|
||||||
|
@ -84,8 +84,8 @@ fn section_from_text<'a>(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn owned_section_from_text<'a>(
|
pub fn owned_section_from_text(
|
||||||
text: &'a Text,
|
text: &Text,
|
||||||
layout: wgpu_glyph::Layout<wgpu_glyph::BuiltInLineBreaker>,
|
layout: wgpu_glyph::Layout<wgpu_glyph::BuiltInLineBreaker>,
|
||||||
) -> OwnedSection {
|
) -> OwnedSection {
|
||||||
OwnedSection {
|
OwnedSection {
|
||||||
|
@ -26,7 +26,7 @@ impl Default for UITheme {
|
|||||||
text: gr_colors::WHITE,
|
text: gr_colors::WHITE,
|
||||||
caret: gr_colors::WHITE,
|
caret: gr_colors::WHITE,
|
||||||
select_highlight: from_hsba(240, 55, 100, 0.3),
|
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,
|
tooltip_text: gr_colors::WHITE,
|
||||||
default_font_size: 30.0,
|
default_font_size: 30.0,
|
||||||
}
|
}
|
||||||
|
@ -4,25 +4,46 @@ use crate::graphics::primitives::text::layout_from_text;
|
|||||||
use crate::graphics::primitives::text::Text;
|
use crate::graphics::primitives::text::Text;
|
||||||
use crate::ui::theme::UITheme;
|
use crate::ui::theme::UITheme;
|
||||||
|
|
||||||
struct ToolTip {
|
pub struct ToolTip {
|
||||||
position_x: f32,
|
pub position_x: f32,
|
||||||
position_y: f32,
|
pub position_y: f32,
|
||||||
text: String,
|
pub text: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToolTip {
|
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 {
|
Rect {
|
||||||
top_left_coords: (self.position_x, self.position_y).into(),
|
top_left_coords: (
|
||||||
height,
|
self.position_x,
|
||||||
|
self.position_y - (height_padding + y_margin),
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
height: height + height_padding,
|
||||||
width,
|
width,
|
||||||
color: ui_theme.tooltip_bg,
|
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 {
|
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,
|
color: ui_theme.tooltip_text,
|
||||||
text: &self.text,
|
text: &self.text,
|
||||||
size: ui_theme.default_font_size,
|
size: ui_theme.default_font_size,
|
||||||
@ -34,18 +55,27 @@ impl ToolTip {
|
|||||||
&self,
|
&self,
|
||||||
glyph_dim_rect: &Rect,
|
glyph_dim_rect: &Rect,
|
||||||
ui_theme: &UITheme,
|
ui_theme: &UITheme,
|
||||||
) -> (glyph_brush::OwnedSection, Rect) {
|
) -> (Rect, glyph_brush::OwnedSection) {
|
||||||
let text = self.make_tooltip_text(ui_theme);
|
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_layout = layout_from_text(&text);
|
||||||
let text_section = gr_text::owned_section_from_text(&text, text_layout);
|
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(
|
let rect = self.make_tooltip_rect(
|
||||||
glyph_dim_rect.width * (text.text.len() as f32) + padding,
|
glyph_dim_rect.width * (text.text.len() as f32) + width_padding,
|
||||||
glyph_dim_rect.height + padding,
|
glyph_dim_rect.height,
|
||||||
|
height_padding,
|
||||||
|
y_margin,
|
||||||
ui_theme,
|
ui_theme,
|
||||||
);
|
);
|
||||||
|
|
||||||
(text_section, rect)
|
(rect, text_section)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user