egui_canvas 0.1.2

A TKinter-like canvas widget for egui.
Documentation
use egui::{epaint::{TextShape, Color32}, Shape, Pos2, Stroke, Ui, WidgetText};
use crate::predicate;
/// This struct represents an unfinished [`egui::epaint::TextShape`].
///
/// Since a proper [`egui::epaint::TextShape`] object can not be constructed
/// without a current [`egui::Ui`] object, which should not be accessed for
/// this when building an app that mainly uses the [`Canvas`](crate::Canvas)
/// widget. Programmers using this crate need to use this struct to define
/// text on screen, which will be
/// [`finalised`](predicate::ShapePredicate::finalise()) into a
/// [`egui::Shape`] object right before rendering.
///
/// This struct contains all the fields of the [`egui::epaint::TextShape`]
/// struct except for [`egui::Galley`] (which is substituted by the `text`
/// field), so that limitations of costumisability are minimised.
#[derive(Debug, Clone, PartialEq)]
pub struct TextShapePredicate {
    pub pos: Pos2,
    pub underline: Stroke,
    pub fallback_color: Color32,
    pub override_text_color: Option<Color32>,
    pub opacity_factor: f32,
    pub angle: f32,
    pub text: String
}

/// Implementation of [`ShapePredicate`](predicate::ShapePredicate) trait for
/// the [`TextShapePredicate`] struct, which constructs a
/// [`egui::Galley`] from the stored text using the current [`egui::Ui`]
/// object.
impl predicate::ShapePredicate for TextShapePredicate {
    fn finalise(&self, ui: &Ui) -> Option<Shape> {

        let valign = ui.text_valign();
        let widget_text: WidgetText = self.text.clone().into();
        let layout_job = widget_text.into_layout_job(
            ui.style(), egui::FontSelection::Default, valign
        );
        let galley = ui.fonts(|fonts| fonts.layout_job(layout_job));
        Some(TextShape {
            pos: self.pos,
            galley,
            underline: self.underline,
            fallback_color: self.fallback_color,
            override_text_color: self.override_text_color,
            opacity_factor: self.opacity_factor,
            angle: self.angle
        }.into())
    }
}