Skip to content

Commit

Permalink
impl From for stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
benfrankel committed Aug 20, 2024
1 parent d5f344a commit 848786f
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 80 deletions.
16 changes: 8 additions & 8 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use bevy_ui::{Interaction, UiStack};
use bevy_window::{PrimaryWindow, Window, WindowRef};
use tiny_bail::prelude::*;

use crate::{PrimaryTooltip, Tooltip, TooltipEntity, TooltipSet};
use crate::{PrimaryTooltip, Tooltip, TooltipContent, TooltipSet};

pub(super) fn plugin(app: &mut App) {
app.register_type::<TooltipContext>();
Expand Down Expand Up @@ -65,7 +65,7 @@ impl Default for TooltipContext {
target: Entity::PLACEHOLDER,
timer: 0,
cursor_pos: Vec2::ZERO,
tooltip: Tooltip::custom(Entity::PLACEHOLDER),
tooltip: Tooltip::new(Entity::PLACEHOLDER),
}
}
}
Expand All @@ -84,9 +84,9 @@ fn update_tooltip_context(
) {
let old_active = matches!(ctx.state, TooltipState::Active);
let old_target = ctx.target;
let old_entity = match ctx.tooltip.entity {
TooltipEntity::Primary(_) => primary.container,
TooltipEntity::Custom(id) => id,
let old_entity = match ctx.tooltip.content {
TooltipContent::Primary(_) => primary.container,
TooltipContent::Custom(id) => id,
};

// TODO: Reconsider whether this is the right way to detect cursor movement.
Expand Down Expand Up @@ -234,14 +234,14 @@ fn show_tooltip(
mut text_query: Query<&mut Text>,
mut visibility_query: Query<&mut Visibility>,
) {
let entity = match &mut ctx.tooltip.entity {
TooltipEntity::Primary(ref mut text) => {
let entity = match &mut ctx.tooltip.content {
TooltipContent::Primary(ref mut text) => {
if let Ok(mut primary_text) = text_query.get_mut(primary.text) {
*primary_text = std::mem::take(text);
}
primary.container
}
TooltipEntity::Custom(id) => *id,
TooltipContent::Custom(id) => *id,
};
*r!(visibility_query.get_mut(entity)) = Visibility::Visible;
}
113 changes: 79 additions & 34 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
//! To customize tooltip behavior, see [`Tooltip`].
//!
//! To set a custom primary tooltip, see [`TooltipPlugin`] and [`PrimaryTooltip`].
//! For fully custom per-entity tooltips, use [`TooltipEntity::Custom`].
//! For fully custom per-entity tooltips, use [`TooltipContent::Custom`].

mod context;
mod placement;
Expand All @@ -43,8 +43,8 @@ mod placement;
/// ```
pub mod prelude {
pub use super::{
PrimaryTooltip, Tooltip, TooltipActivation, TooltipEntity, TooltipPlacement, TooltipPlugin,
TooltipSet, TooltipTransfer,
PrimaryTooltip, Tooltip, TooltipActivation, TooltipContent, TooltipPlacement,
TooltipPlugin, TooltipSet, TooltipTransfer,
};
}

Expand Down Expand Up @@ -196,67 +196,61 @@ pub struct Tooltip {
/// How the position of the tooltip entity should be determined.
pub placement: TooltipPlacement,
/// The entity to display as the tooltip.
pub entity: TooltipEntity,
pub content: TooltipContent,
}

impl Tooltip {
/// Use the provided tooltip entity and default behavior.
fn new(entity: TooltipEntity) -> Self {
/// Construct a new `Tooltip` with default behavior.
pub fn new(content: impl Into<TooltipContent>) -> Self {
Self {
activation: TooltipActivation::IDLE,
transfer: TooltipTransfer::NONE,
placement: TooltipPlacement::CURSOR,
entity,
content: content.into(),
}
}

/// Use a custom tooltip entity and default behavior.
pub fn custom(entity: Entity) -> Self {
Self::new(TooltipEntity::Custom(entity))
}

/// Use the primary tooltip entity with a single [`TextSection`] and default behavior.
/// Construct a new `Tooltip` from a single [`TextSection`] and default behavior.
pub fn from_section(value: impl Into<String>, style: TextStyle) -> Self {
Self::new(TooltipEntity::Primary(Text::from_section(value, style)))
Self::new(TooltipContent::Primary(Text::from_section(value, style)))
}

/// Use the primary tooltip entity with a list of [`TextSection`]s and default behavior.
/// Construct a new `Tooltip` from a list of [`TextSection`]s and default behavior.
pub fn from_sections(sections: impl IntoIterator<Item = TextSection>) -> Self {
Self::new(TooltipEntity::Primary(Text::from_sections(sections)))
Self::new(TooltipContent::Primary(Text::from_sections(sections)))
}

/// Use the primary tooltip entity with a given [`Text`] and default behavior.
/// Construct a new `Tooltip` from a given [`Text`] and default behavior.
pub fn from_text(text: impl Into<Text>) -> Self {
Self::new(TooltipEntity::Primary(text.into()))
Self::new(TooltipContent::Primary(text.into()))
}

/// Set the [`JustifyText`].
/// Set [`JustifyText`].
///
/// NOTE: This does nothing with a custom tooltip.
/// NOTE: This does nothing for custom tooltips.
pub fn with_justify_text(mut self, justify_text: JustifyText) -> Self {
match &mut self.entity {
TooltipEntity::Primary(text) => text.justify = justify_text,
// TODO: Warn?
_ => (),
// TODO: Warn otherwise?
if let TooltipContent::Primary(text) = &mut self.content {
text.justify = justify_text;
}
self
}

/// Set a custom [`TooltipActivation`].
pub fn with_activation(mut self, activation: TooltipActivation) -> Self {
self.activation = activation;
/// Set [`TooltipActivation`].
pub fn with_activation(mut self, activation: impl Into<TooltipActivation>) -> Self {
self.activation = activation.into();
self
}

/// Set a custom [`TooltipTransfer`].
pub fn with_transfer(mut self, transfer: TooltipTransfer) -> Self {
self.transfer = transfer;
/// Set [`TooltipTransfer`].
pub fn with_transfer(mut self, transfer: impl Into<TooltipTransfer>) -> Self {
self.transfer = transfer.into();
self
}

/// Set a custom [`TooltipPlacement`].
pub fn with_placement(mut self, placement: TooltipPlacement) -> Self {
self.placement = placement;
/// Set [`TooltipPlacement`].
pub fn with_placement(mut self, placement: impl Into<TooltipPlacement>) -> Self {
self.placement = placement.into();
self
}
}
Expand Down Expand Up @@ -327,6 +321,16 @@ impl TooltipActivation {
};
}

impl From<u16> for TooltipActivation {
fn from(value: u16) -> Self {
Self {
delay: value,
reset_delay_on_cursor_move: false,
dismiss_radius: f32::INFINITY,
}
}
}

impl Default for TooltipActivation {
fn default() -> Self {
Self::IMMEDIATE
Expand Down Expand Up @@ -369,6 +373,17 @@ impl TooltipTransfer {
};
}

impl From<u16> for TooltipTransfer {
fn from(value: u16) -> Self {
Self {
group: Some(0),
layer: 0,
timeout: value,
from_active: true,
}
}
}

impl Default for TooltipTransfer {
fn default() -> Self {
Self::NONE
Expand All @@ -378,13 +393,43 @@ impl Default for TooltipTransfer {
/// The tooltip entity and content to be displayed.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
pub enum TooltipEntity {
pub enum TooltipContent {
/// Use the primary tooltip entity with custom [`Text`].
Primary(Text),
/// Use a fully custom entity as the tooltip.
Custom(Entity),
}

impl From<&str> for TooltipContent {
fn from(value: &str) -> Self {
Self::Primary(Text::from_section(value.to_string(), TextStyle::default()))
}
}

impl From<String> for TooltipContent {
fn from(value: String) -> Self {
Self::Primary(Text::from_section(value, TextStyle::default()))
}
}

impl From<TextSection> for TooltipContent {
fn from(value: TextSection) -> Self {
Self::Primary(Text::from_section(value.value, value.style))
}
}

impl From<Text> for TooltipContent {
fn from(value: Text) -> Self {
Self::Primary(value)
}
}

impl From<Entity> for TooltipContent {
fn from(value: Entity) -> Self {
Self::Custom(value)
}
}

/// A [`SystemSet`] for tooltip systems.
#[derive(SystemSet, Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum TooltipSet {
Expand Down
74 changes: 36 additions & 38 deletions src/placement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use tiny_bail::prelude::*;

use crate::{
context::{TooltipContext, TooltipState},
PrimaryTooltip, TooltipEntity, TooltipSet,
PrimaryTooltip, TooltipContent, TooltipSet,
};

pub(super) fn plugin(app: &mut App) {
Expand Down Expand Up @@ -58,42 +58,40 @@ impl TooltipPlacement {
offset_y: Val::Px(16.0),
clamp_padding: UiRect::ZERO,
};
}

/// Show tooltip to the left of target.
pub const LEFT: Self = Self {
tooltip_anchor: Anchor::CenterRight,
target_anchor: Some(Anchor::CenterLeft),
offset_x: Val::ZERO,
offset_y: Val::ZERO,
clamp_padding: UiRect::ZERO,
};

/// Show tooltip to the right of target.
pub const RIGHT: Self = Self {
tooltip_anchor: Anchor::CenterLeft,
target_anchor: Some(Anchor::CenterRight),
offset_x: Val::ZERO,
offset_y: Val::ZERO,
clamp_padding: UiRect::ZERO,
};

/// Show tooltip above target.
pub const TOP: Self = Self {
tooltip_anchor: Anchor::BottomCenter,
target_anchor: Some(Anchor::TopCenter),
offset_x: Val::ZERO,
offset_y: Val::ZERO,
clamp_padding: UiRect::ZERO,
};
impl From<Anchor> for TooltipPlacement {
fn from(value: Anchor) -> Self {
Self {
tooltip_anchor: match value {
Anchor::Center | Anchor::Custom(_) => Anchor::Center,
Anchor::BottomLeft => Anchor::TopRight,
Anchor::BottomCenter => Anchor::TopCenter,
Anchor::BottomRight => Anchor::TopLeft,
Anchor::CenterLeft => Anchor::CenterRight,
Anchor::CenterRight => Anchor::CenterLeft,
Anchor::TopLeft => Anchor::BottomRight,
Anchor::TopCenter => Anchor::BottomCenter,
Anchor::TopRight => Anchor::BottomLeft,
},
target_anchor: Some(value),
offset_x: Val::ZERO,
offset_y: Val::ZERO,
clamp_padding: UiRect::ZERO,
}
}
}

/// Show tooltip below target.
pub const BOTTOM: Self = Self {
tooltip_anchor: Anchor::TopCenter,
target_anchor: Some(Anchor::BottomCenter),
offset_x: Val::ZERO,
offset_y: Val::ZERO,
clamp_padding: UiRect::ZERO,
};
impl From<Vec2> for TooltipPlacement {
fn from(value: Vec2) -> Self {
Self {
tooltip_anchor: Anchor::TopLeft,
target_anchor: None,
offset_x: Val::Px(value.x),
offset_y: Val::Px(value.y),
clamp_padding: UiRect::ZERO,
}
}
}

impl Default for TooltipPlacement {
Expand All @@ -116,9 +114,9 @@ fn place_tooltip(
) {
rq!(matches!(ctx.state, TooltipState::Active));
let (target_gt, target_node) = rq!(target_query.get(ctx.target));
let entity = match &ctx.tooltip.entity {
TooltipEntity::Primary(_) => primary.container,
&TooltipEntity::Custom(id) => id,
let entity = match &ctx.tooltip.content {
TooltipContent::Primary(_) => primary.container,
&TooltipContent::Custom(id) => id,
};
let (mut style, mut transform, gt, node) = or_return!(tooltip_query.get_mut(entity));

Expand Down

0 comments on commit 848786f

Please sign in to comment.