use bevy::prelude::EventWriter;
use bevy_egui::egui::{self, *};
use crate::easy_mark::easy_mark_parser::Style;
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
pub struct EasyLink {
url: String,
text: String,
style: Style,
}
#[derive(Clone, Debug)]
pub struct EasyLinkEvent {
pub link: String,
pub new_tab: bool,
}
impl EasyLinkEvent {
pub fn new(link: String, new_tab: bool) -> Self {
Self { link, new_tab, }
}
}
impl From<String> for EasyLinkEvent {
fn from(link: String) -> Self {
Self::new(link, false)
}
}
impl From<&str> for EasyLinkEvent {
fn from(link: &str) -> Self {
Self::new(link.to_owned(), false)
}
}
impl EasyLink {
pub const INTERNAL_LINK_PREFIX: &'static str = ":";
#[allow(clippy::needless_pass_by_value)]
pub fn new(url: impl ToString, text: impl ToString, style: Style) -> Self {
let url = url.to_string();
Self {
url: url.to_string(),
text: text.to_string(),
style,
}
}
pub fn ui(self, ui: &mut Ui, link_evts: &mut EventWriter<EasyLinkEvent>) -> Response {
let EasyLink { url, text, style } = self;
let label = super::label_from_style(&text, &style);
let color = ui.visuals().hyperlink_color;
let label = label.text_color(color);
let response = ui.add(label.sense(Sense::click()));
if response.hovered() {
ui.ctx().output().cursor_icon = CursorIcon::PointingHand;
}
let is_internal = url.starts_with(EasyLink::INTERNAL_LINK_PREFIX);
if response.clicked() {
let modifiers = ui.ctx().input().modifiers;
let new_tab = modifiers.any();
if is_internal {
link_evts.send(EasyLinkEvent{
link: url.clone(),
new_tab,
});
} else {
ui.ctx().output().open_url = Some(egui::output::OpenUrl {
url: url.clone(),
new_tab,
});
}
}
if response.middle_clicked() {
let new_tab = true;
if is_internal {
link_evts.send(EasyLinkEvent{
link: url.clone(),
new_tab,
});
} else {
ui.ctx().output().open_url = Some(egui::output::OpenUrl {
url: url.clone(),
new_tab,
});
}
}
if is_internal {
response
} else {
response.on_hover_ui_at_pointer(|ui| {
ui.horizontal(|ui| {
ui.separator();
ui.label(url);
});
})
}
}
}