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"`.
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
pub struct Hyperlink {
// TODO: wrap Label
url: String,
text: String,
pub(crate) text_style: Option<TextStyle>,
label: Label,
}
impl Hyperlink {
pub fn new(url: impl Into<String>) -> Self {
let url = url.into();
Self {
text: url.clone(),
url,
text_style: None,
url: url.clone(),
label: Label::new(url),
}
}
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
pub fn text(mut self, text: impl Into<String>) -> Self {
self.text = text.into();
self.label.text = text.into();
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 {
self.text_style = Some(text_style);
self.label = self.label.text_style(text_style);
self
}
@ -38,14 +42,8 @@ impl Hyperlink {
impl Widget for Hyperlink {
fn ui(self, ui: &mut Ui) -> Response {
let Hyperlink {
url,
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 Hyperlink { url, label } = self;
let galley = label.layout(ui);
let (rect, response) = ui.allocate_exact_size(galley.size, Sense::click());
if response.hovered() {
@ -60,20 +58,17 @@ impl Widget for Hyperlink {
if response.hovered() {
// Underline:
for line in &galley.rows {
let pos = rect.min;
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();
for row in &galley.rows {
let rect = row.rect().translate(rect.min.to_vec2());
ui.painter().line_segment(
[pos2(min_x, y), pos2(max_x, y)],
[rect.left_bottom(), rect.right_bottom()],
(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)
}