use crate::prelude::*;
use crate::ui::hyperlink::events::EventData;
#[CustomControl(overwrite=OnPaint+OnDefaultAction+OnKeyPressed+OnMouseEvent, internal=true)]
pub struct HyperLink {
url: String,
tooltip: String,
name: String,
pressed: bool,
}
impl HyperLink {
pub fn new(name: &str, url: &str, layout: Layout) -> Self {
Self::inner_create(name, url, "", layout, StatusFlags::None)
}
pub fn with_url(url: &str, layout: Layout) -> Self {
Self::inner_create("", url, "", layout, StatusFlags::None)
}
pub fn with_tooltip(name: &str, url: &str, tooltip: &str, layout: Layout) -> Self {
Self::inner_create(name, url, tooltip, layout, StatusFlags::None)
}
fn inner_create(name: &str, url: &str, tooltip: &str, layout: Layout, status: StatusFlags) -> Self {
let mut hyper_link = HyperLink {
base: ControlBase::with_status_flags(layout, StatusFlags::Visible | StatusFlags::Enabled | StatusFlags::AcceptInput | status),
url: url.to_string(),
tooltip: tooltip.to_string(),
name: name.to_string(),
pressed: false,
};
hyper_link.set_size_bounds(1, 1, u16::MAX, 1);
hyper_link
}
pub fn set_url(&mut self, url: &str) {
self.url.clear();
self.url.push_str(url);
}
pub fn url(&self) -> &str {
self.url.as_str()
}
pub fn set_tooltip(&mut self, tooltip: &str) {
self.tooltip.clear();
self.tooltip.push_str(tooltip);
}
pub fn tooltip(&self) -> &str {
self.tooltip.as_str()
}
pub fn set_name(&mut self, name: &str) {
self.name.clear();
self.name.push_str(name);
}
pub fn name(&self) -> &str {
self.name.as_str()
}
}
impl OnDefaultAction for HyperLink {
fn on_default_action(&mut self) {
self.raise_event(ControlEvent {
emitter: self.handle,
receiver: self.event_processor,
data: ControlEventData::HyperLink(EventData),
});
}
}
impl OnKeyPressed for HyperLink {
fn on_key_pressed(&mut self, key: Key, _character: char) -> EventProcessStatus {
match key.value() {
key!("Enter") => {
self.on_default_action();
EventProcessStatus::Processed
}
_ => EventProcessStatus::Ignored,
}
}
}
impl OnPaint for HyperLink {
fn on_paint(&self, surface: &mut Surface, theme: &Theme) {
let col_text = match () {
_ if !self.is_enabled() => theme.hyperlink.inactive,
_ if self.pressed => theme.hyperlink.pressed_or_selected,
_ if self.has_focus() => theme.hyperlink.focused,
_ if self.is_mouse_over() => theme.hyperlink.hovered,
_ => theme.hyperlink.normal,
};
let name = if self.name.trim().is_empty() { &self.url } else { &self.name };
let w = self.size().width;
let format = TextFormatBuilder::new()
.position(0, 0)
.attribute(col_text)
.align(TextAlignment::Left)
.chars_count(name.chars().count() as u16)
.wrap_type(WrapType::SingleLineWrap(w as u16))
.build();
surface.write_text(name, &format);
}
}
impl OnMouseEvent for HyperLink {
fn on_mouse_event(&mut self, event: &MouseEvent) -> EventProcessStatus {
match event {
MouseEvent::Enter => {
if !self.tooltip.trim().is_empty() {
self.show_tooltip(&self.tooltip);
}
self.pressed = false;
EventProcessStatus::Processed
}
MouseEvent::Leave => {
self.hide_tooltip();
self.pressed = false;
EventProcessStatus::Processed
}
MouseEvent::Pressed(_) => {
self.pressed = true;
EventProcessStatus::Processed
}
MouseEvent::Released(_) => {
if self.pressed {
self.on_default_action();
}
self.pressed = false;
EventProcessStatus::Processed
}
_ => EventProcessStatus::Ignored,
}
}
}