Skip to content
Snippets Groups Projects
cosmic_edit.rs 4.51 KiB
Newer Older
Caleb Yates's avatar
Caleb Yates committed
use crate::prelude::*;
use cosmic_text::{Attrs, AttrsOwned, Editor, FontSystem};
Caleb Yates's avatar
Caleb Yates committed
pub(crate) fn plugin(app: &mut App) {
    app.register_type::<CosmicWrap>()
        .register_type::<CosmicTextAlign>()
        .register_type::<XOffset>()
        .register_type::<CosmicBackgroundImage>()
        .register_type::<CosmicBackgroundColor>()
        .register_type::<CursorColor>()
        .register_type::<SelectionColor>()
        .register_type::<MaxLines>()
        .register_type::<MaxChars>()
        .register_type::<ScrollEnabled>();
}

sam edelsten's avatar
sam edelsten committed
/// Enum representing text wrapping in a cosmic [`Buffer`]
#[derive(Component, Reflect, Clone, PartialEq, Default)]
pub enum CosmicWrap {
    InfiniteLine,
    #[default]
    Wrap,
}

Caleb Yates's avatar
Caleb Yates committed
/// Enum representing the text alignment in a cosmic [`Buffer`].
/// Defaults to [`CosmicTextAlign::Center`]
#[derive(Component, Reflect, Clone)]
pub enum CosmicTextAlign {
    Center { padding: i32 },
    TopLeft { padding: i32 },
    Left { padding: i32 },
}

impl Default for CosmicTextAlign {
    fn default() -> Self {
        CosmicTextAlign::Center { padding: 5 }
Caleb Yates's avatar
Caleb Yates committed
/// Tag component to disable writing to a [`CosmicEditBuffer`]
// TODO: Code example
#[derive(Component, Default)]
pub struct ReadOnly; // tag component

sam edelsten's avatar
sam edelsten committed
/// Internal value used to decide what section of a [`Buffer`] to render
#[derive(Component, Reflect, Debug, Default)]
Caleb Yates's avatar
Caleb Yates committed
pub(crate) struct XOffset {
    /// How much space in logical units from the left of the [`Buffer`]
    /// to start rendering text.
    pub left: f32,
Caleb Yates's avatar
Caleb Yates committed

    /// Width of buffer that includes text that should be rendered,
    /// in logical units.
    ///
    /// Should only be [None] if in default state
    pub width: Option<f32>,
Caleb Yates's avatar
Caleb Yates committed
/// Default text attributes to be used on a [`CosmicEditBuffer`]
#[derive(Component, Deref, DerefMut)]
pub struct DefaultAttrs(pub AttrsOwned);

impl Default for DefaultAttrs {
    fn default() -> Self {
        DefaultAttrs(AttrsOwned::new(Attrs::new()))
    }
}

/// Image to be used as a buffer's background
#[derive(Component, Reflect, Default)]
pub struct CosmicBackgroundImage(pub Option<Handle<Image>>);
/// Color to be used as a buffer's background
#[derive(Component, Reflect, Default, Deref)]
pub struct CosmicBackgroundColor(pub Color);
Caleb Yates's avatar
Caleb Yates committed
/// Color to be used for the text cursor.
/// Defaults to [`Color::BLACK`]
#[derive(Component, Reflect, Deref)]
pub struct CursorColor(pub Color);

Caleb Yates's avatar
Caleb Yates committed
impl Default for CursorColor {
    fn default() -> Self {
        CursorColor(Color::BLACK)
    }
}

/// Color to be used as the selected text background.
/// Defaults to [`Color::GRAY`]
#[derive(Component, Reflect, Deref)]
pub struct SelectionColor(pub Color);

Caleb Yates's avatar
Caleb Yates committed
impl Default for SelectionColor {
    fn default() -> Self {
        SelectionColor(bevy::color::palettes::basic::GRAY.into())
    }
}

/// Color to be used for the selected text
#[derive(Component, Reflect, Default, Deref)]
pub struct SelectedTextColor(pub Color);

/// Maximum number of lines allowed in a buffer
Caleb Yates's avatar
Caleb Yates committed
// TODO: Actually test this? I'm not sure this does anything afaik
#[derive(Component, Reflect, Default)]
pub struct MaxLines(pub usize);
/// Maximum number of characters allowed in a buffer
// TODO: Check this functionality with widechars; Use graphemes to test?
#[derive(Component, Reflect, Default)]
pub struct MaxChars(pub usize);
Caleb Yates's avatar
Caleb Yates committed
/// Should [`CosmicEditBuffer`] respond to scroll events?
#[derive(Component, Reflect, Default)]
pub enum ScrollEnabled {
    #[default]
    Enabled,
    Disabled,
Caleb Yates's avatar
Caleb Yates committed
impl ScrollEnabled {
    pub fn should_scroll(&self) -> bool {
        matches!(self, ScrollEnabled::Enabled)
sam edelsten's avatar
sam edelsten committed
/// Holds the font system used internally by [`cosmic_text`]
Caleb Yates's avatar
Caleb Yates committed
///
/// Note: When bevy provides enough initialisation flexibility,
/// this should be merged with its builtin resource
#[derive(Resource, Deref, DerefMut)]
pub struct CosmicFontSystem(pub FontSystem);

sam edelsten's avatar
sam edelsten committed
/// Wrapper component for an [`Editor`] with a few helpful values for cursor blinking
Caleb Yates's avatar
Caleb Yates committed
///
/// [`cosmic_text::Editor`] is basically a mutable version of [`cosmic_text::Buffer`].
///
/// This component should be on a focussed [`CosmicEditBuffer`]
// Managed by crate::focus::add_editor_to_focussed and similar systems
#[derive(Component, Deref, DerefMut)]
pub struct CosmicEditor {
    #[deref]
    pub editor: Editor<'static>,
    pub cursor_visible: bool,
    pub cursor_timer: Timer,
}

impl CosmicEditor {
    pub fn new(editor: Editor<'static>) -> Self {
        Self {
            editor,
            cursor_visible: true,
Caleb Yates's avatar
Caleb Yates committed
            cursor_timer: Timer::new(std::time::Duration::from_millis(530), TimerMode::Repeating),