Add Hyperlink::from_label_and_url
This commit is contained in:
parent
c50190a7e8
commit
953a652c29
1 changed files with 20 additions and 25 deletions
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue