Skip to content
Snippets Groups Projects
cosmic_edit.rs 6.92 KiB
Newer Older
sam edelsten's avatar
sam edelsten committed
use crate::*;
use bevy::prelude::*;

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

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

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

sam edelsten's avatar
sam edelsten committed
/// Internal value used to decide what section of a [`Buffer`] to render
sam edelsten's avatar
sam edelsten committed
#[derive(Component, Debug, Default)]
pub struct XOffset {
    pub left: f32,
    pub width: f32,
}

sam edelsten's avatar
sam edelsten committed
/// Default text attributes to be used on a [`CosmicBuffer`]
sam edelsten's avatar
sam edelsten committed
#[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
sam edelsten's avatar
sam edelsten committed
#[derive(Component, Default)]
pub struct CosmicBackgroundImage(pub Option<Handle<Image>>);
/// Color to be used as a buffer's background
sam edelsten's avatar
sam edelsten committed
#[derive(Component, Default, Deref)]
pub struct CosmicBackgroundColor(pub Color);
/// Color to be used for the text cursor
sam edelsten's avatar
sam edelsten committed
#[derive(Component, Default, Deref)]
pub struct CursorColor(pub Color);

/// Color to be used as the selected text background
sam edelsten's avatar
sam edelsten committed
#[derive(Component, Default, Deref)]
pub struct SelectionColor(pub Color);

/// Maximum number of lines allowed in a buffer
sam edelsten's avatar
sam edelsten committed
#[derive(Component, Default)]
pub struct MaxLines(pub usize);
/// Maximum number of characters allowed in a buffer
// TODO: Check this functionality with widechars; Use graphemes to test?
sam edelsten's avatar
sam edelsten committed
#[derive(Component, Default)]
pub struct MaxChars(pub usize);
sam edelsten's avatar
sam edelsten committed
/// A pointer to an entity with a [`CosmicEditBundle`], used to apply cosmic rendering to a UI
///```
/// # use bevy::prelude::*;
/// # use bevy_cosmic_edit::*;
/// #
/// # fn setup(mut commands: Commands) {
sam edelsten's avatar
sam edelsten committed
/// // Create a new cosmic bundle
/// let cosmic_edit = commands.spawn(CosmicEditBundle::default()).id();
sam edelsten's avatar
sam edelsten committed
/// // Spawn the target bundle
/// commands
///     .spawn(ButtonBundle {
///         style: Style {
///             width: Val::Percent(100.),
///             height: Val::Percent(100.),
///             ..default()
///         },
///         background_color: BackgroundColor(Color::WHITE),
///         ..default()
///     })
///     // Add the source component to the target element
///     .insert(CosmicSource(cosmic_edit));
/// # }
/// #
/// # fn main() {
/// #     App::new()
/// #         .add_plugins(MinimalPlugins)
/// #         .add_plugins(CosmicEditPlugin::default())
sam edelsten's avatar
sam edelsten committed
/// #         .add_systems(Startup, setup);
sam edelsten's avatar
sam edelsten committed
#[derive(Component)]
pub struct CosmicSource(pub Entity);

sam edelsten's avatar
sam edelsten committed
/// A bundle containing all the required components for [`CosmicBuffer`] functionality.
sam edelsten's avatar
sam edelsten committed
/// Uses an invisible [`SpriteBundle`] for rendering by default, so should either be paired with another
/// entity with a [`CosmicSource`] pointing to it's entity, or have the sprite set.
///```
/// # use bevy::prelude::*;
/// # use bevy_cosmic_edit::*;
/// #
/// # fn setup(mut commands: Commands) {
sam edelsten's avatar
sam edelsten committed
/// // Create a new cosmic bundle
/// let cosmic_edit = commands.spawn(CosmicEditBundle::default()).id();
sam edelsten's avatar
sam edelsten committed
/// // Spawn the target bundle
/// commands
///     .spawn(ButtonBundle {
///         style: Style {
///             width: Val::Percent(100.),
///             height: Val::Percent(100.),
///             ..default()
///         },
///         background_color: BackgroundColor(Color::WHITE),
///         ..default()
///     })
///     // Add the source component to the target element
///     .insert(CosmicSource(cosmic_edit));
/// # }
/// #
/// # fn main() {
/// #     App::new()
/// #         .add_plugins(MinimalPlugins)
/// #         .add_plugins(CosmicEditPlugin::default())
sam edelsten's avatar
sam edelsten committed
/// #         .add_systems(Startup, setup);
/// # }
/// ```
/// ### Sprite mode
/// ```
/// # use bevy::prelude::*;
/// # use bevy_cosmic_edit::*;
/// #
/// # fn setup(mut commands: Commands) {
/// // Create a new cosmic bundle
/// commands.spawn(CosmicEditBundle {
///     sprite_bundle: SpriteBundle {
///         sprite: Sprite {
///             custom_size: Some(Vec2::new(300.0, 40.0)),
///             ..default()
///         },
///         ..default()
///     },
///     ..default()
/// });
/// # }
/// #
/// # fn main() {
/// #     App::new()
/// #         .add_plugins(MinimalPlugins)
/// #         .add_plugins(CosmicEditPlugin::default())
sam edelsten's avatar
sam edelsten committed
/// #         .add_systems(Startup, setup);
sam edelsten's avatar
sam edelsten committed
#[derive(Bundle)]
pub struct CosmicEditBundle {
    // cosmic bits
    pub buffer: CosmicBuffer,
    // render bits
    pub fill_color: CosmicBackgroundColor,
sam edelsten's avatar
sam edelsten committed
    pub cursor_color: CursorColor,
    pub selection_color: SelectionColor,
    pub default_attrs: DefaultAttrs,
    pub background_image: CosmicBackgroundImage,
sam edelsten's avatar
sam edelsten committed
    pub sprite_bundle: SpriteBundle,
    // restriction bits
    pub max_lines: MaxLines,
    pub max_chars: MaxChars,
sam edelsten's avatar
sam edelsten committed
    // layout bits
    pub x_offset: XOffset,
    pub mode: CosmicWrap,
    pub text_position: CosmicTextAlign,
sam edelsten's avatar
sam edelsten committed
    pub padding: CosmicPadding,
    pub widget_size: CosmicWidgetSize,
    pub hover_cursor: HoverCursor,
sam edelsten's avatar
sam edelsten committed
}

impl Default for CosmicEditBundle {
    fn default() -> Self {
        CosmicEditBundle {
            buffer: Default::default(),
            fill_color: Default::default(),
            cursor_color: CursorColor(Color::BLACK),
            selection_color: SelectionColor(Color::GRAY),
            text_position: Default::default(),
            default_attrs: Default::default(),
            background_image: Default::default(),
            max_lines: Default::default(),
            max_chars: Default::default(),
            mode: Default::default(),
            sprite_bundle: SpriteBundle {
                sprite: Sprite {
                    custom_size: Some(Vec2::ONE * 128.0),
                    ..default()
                },
                visibility: Visibility::Hidden,
                ..default()
            },
            x_offset: Default::default(),
            padding: Default::default(),
            widget_size: Default::default(),
            hover_cursor: Default::default(),
sam edelsten's avatar
sam edelsten committed
/// Holds the font system used internally by [`cosmic_text`]
sam edelsten's avatar
sam edelsten committed
#[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
sam edelsten's avatar
sam edelsten committed
#[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,
            cursor_timer: Timer::new(Duration::from_millis(530), TimerMode::Repeating),
        }
    }
}