Add Hyperlink::from_label_and_url

This commit is contained in:
Emil Ernerfeldt 2021-01-30 15:45:57 +01:00
parent c50190a7e8
commit 953a652c29

View file

@ -3,31 +3,35 @@ use crate::*;
/// A clickable hyperlink, e.g. to `"https://github.com/emilk/egui"`. /// A clickable hyperlink, e.g. to `"https://github.com/emilk/egui"`.
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"] #[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
pub struct Hyperlink { pub struct Hyperlink {
// TODO: wrap Label
url: String, url: String,
text: String, label: Label,
pub(crate) text_style: Option<TextStyle>,
} }
impl Hyperlink { impl Hyperlink {
pub fn new(url: impl Into<String>) -> Self { pub fn new(url: impl Into<String>) -> Self {
let url = url.into(); let url = url.into();
Self { Self {
text: url.clone(), url: url.clone(),
url, label: Label::new(url),
text_style: None, }
}
pub fn from_label_and_url(label: impl Into<Label>, url: impl Into<String>) -> Self {
Self {
url: url.into(),
label: label.into(),
} }
} }
/// Show some other text than the url /// Show some other text than the url
pub fn text(mut self, text: impl Into<String>) -> Self { pub fn text(mut self, text: impl Into<String>) -> Self {
self.text = text.into(); self.label.text = text.into();
self self
} }
/// If you do not set a `TextStyle`, the default `style.text_style`. /// The default is [`Style::body_text_style`] (generally [`TextStyle::Body`]).
pub fn text_style(mut self, text_style: TextStyle) -> Self { pub fn text_style(mut self, text_style: TextStyle) -> Self {
self.text_style = Some(text_style); self.label = self.label.text_style(text_style);
self self
} }
@ -38,14 +42,8 @@ impl Hyperlink {
impl Widget for Hyperlink { impl Widget for Hyperlink {
fn ui(self, ui: &mut Ui) -> Response { fn ui(self, ui: &mut Ui) -> Response {
let Hyperlink { let Hyperlink { url, label } = self;
url, let galley = label.layout(ui);
text,
text_style,
} = self;
let text_style = text_style.unwrap_or_else(|| ui.style().body_text_style);
let font = &ui.fonts()[text_style];
let galley = font.layout_multiline(text, ui.available_width());
let (rect, response) = ui.allocate_exact_size(galley.size, Sense::click()); let (rect, response) = ui.allocate_exact_size(galley.size, Sense::click());
if response.hovered() { if response.hovered() {
@ -60,20 +58,17 @@ impl Widget for Hyperlink {
if response.hovered() { if response.hovered() {
// Underline: // Underline:
for line in &galley.rows { for row in &galley.rows {
let pos = rect.min; let rect = row.rect().translate(rect.min.to_vec2());
let y = pos.y + line.y_max;
let y = ui.painter().round_to_pixel(y);
let min_x = pos.x + line.min_x();
let max_x = pos.x + line.max_x();
ui.painter().line_segment( ui.painter().line_segment(
[pos2(min_x, y), pos2(max_x, y)], [rect.left_bottom(), rect.right_bottom()],
(visuals.fg_stroke.width, color), (visuals.fg_stroke.width, color),
); );
} }
} }
ui.painter().galley(rect.min, galley, text_style, color); let label = label.text_color(color);
label.paint_galley(ui, rect.min, galley);
response.on_hover_text(url) response.on_hover_text(url)
} }