mirror of
https://github.com/YGGverse/Yoda.git
synced 2025-09-07 12:21:48 +00:00
replace tag link tooltip with gutter widget
This commit is contained in:
parent
7800ec6c26
commit
537ee92fb7
@ -1,10 +1,12 @@
|
|||||||
mod ansi;
|
mod ansi;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
mod gutter;
|
||||||
mod icon;
|
mod icon;
|
||||||
mod syntax;
|
mod syntax;
|
||||||
mod tag;
|
mod tag;
|
||||||
|
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
|
use gutter::Gutter;
|
||||||
use icon::Icon;
|
use icon::Icon;
|
||||||
use syntax::Syntax;
|
use syntax::Syntax;
|
||||||
use tag::Tag;
|
use tag::Tag;
|
||||||
@ -98,6 +100,9 @@ impl Gemini {
|
|||||||
.build()
|
.build()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Init gutter widget (the tooltip on URL tags hover)
|
||||||
|
let gutter = Gutter::build(&text_view);
|
||||||
|
|
||||||
// Parse gemtext lines
|
// Parse gemtext lines
|
||||||
for line in gemtext.lines() {
|
for line in gemtext.lines() {
|
||||||
// Is inline code
|
// Is inline code
|
||||||
@ -375,8 +380,8 @@ impl Gemini {
|
|||||||
Window::NONE,
|
Window::NONE,
|
||||||
Cancellable::NONE,
|
Cancellable::NONE,
|
||||||
|result| {
|
|result| {
|
||||||
if let Err(error) = result {
|
if let Err(e) = result {
|
||||||
println!("{error}")
|
println!("{e}")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -460,12 +465,12 @@ impl Gemini {
|
|||||||
// Keep hovered tag in memory
|
// Keep hovered tag in memory
|
||||||
hover.replace(Some(tag.clone()));
|
hover.replace(Some(tag.clone()));
|
||||||
|
|
||||||
|
// Show tooltip
|
||||||
|
gutter.set_uri(Some(uri));
|
||||||
|
|
||||||
// Toggle cursor
|
// Toggle cursor
|
||||||
text_view.set_cursor_from_name(Some("pointer"));
|
text_view.set_cursor_from_name(Some("pointer"));
|
||||||
|
|
||||||
// Show tooltip | @TODO set_gutter option?
|
|
||||||
text_view.set_tooltip_text(Some(&uri.to_string()));
|
|
||||||
|
|
||||||
// Redraw required to apply changes immediately
|
// Redraw required to apply changes immediately
|
||||||
text_view.queue_draw();
|
text_view.queue_draw();
|
||||||
|
|
||||||
@ -475,8 +480,8 @@ impl Gemini {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Restore defaults
|
// Restore defaults
|
||||||
|
gutter.set_uri(None);
|
||||||
text_view.set_cursor_from_name(Some("text"));
|
text_view.set_cursor_from_name(Some("text"));
|
||||||
text_view.set_tooltip_text(None);
|
|
||||||
text_view.queue_draw();
|
text_view.queue_draw();
|
||||||
}
|
}
|
||||||
}); // @TODO may be expensive for CPU, add timeout?
|
}); // @TODO may be expensive for CPU, add timeout?
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
use gtk::{
|
||||||
|
glib::{timeout_add_local_once, Uri},
|
||||||
|
pango::EllipsizeMode,
|
||||||
|
prelude::{TextViewExt, WidgetExt},
|
||||||
|
Align, Label, TextView, TextWindowType,
|
||||||
|
};
|
||||||
|
use std::{cell::Cell, rc::Rc, time::Duration};
|
||||||
|
|
||||||
|
pub struct Gutter {
|
||||||
|
pub label: Label,
|
||||||
|
is_active: Rc<Cell<bool>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Gutter {
|
||||||
|
pub fn build(text_view: &TextView) -> Self {
|
||||||
|
const MARGIN_X: i32 = 8;
|
||||||
|
const MARGIN_Y: i32 = 2;
|
||||||
|
let label = Label::builder()
|
||||||
|
.css_classes([
|
||||||
|
// "caption",
|
||||||
|
"dim-label",
|
||||||
|
])
|
||||||
|
.halign(Align::Start)
|
||||||
|
.margin_start(MARGIN_X)
|
||||||
|
.margin_end(MARGIN_X)
|
||||||
|
.margin_top(MARGIN_Y)
|
||||||
|
.margin_bottom(MARGIN_Y)
|
||||||
|
.ellipsize(EllipsizeMode::Middle)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
text_view.set_gutter(TextWindowType::Bottom, Some(&label));
|
||||||
|
text_view
|
||||||
|
.gutter(TextWindowType::Bottom)
|
||||||
|
.unwrap()
|
||||||
|
.set_css_classes(&["view"]); // @TODO unspecified patch
|
||||||
|
|
||||||
|
Self {
|
||||||
|
is_active: Rc::new(Cell::new(false)),
|
||||||
|
label,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_uri(&self, uri: Option<&Uri>) {
|
||||||
|
match uri {
|
||||||
|
Some(uri) => {
|
||||||
|
if !self.label.is_visible() {
|
||||||
|
if !self.is_active.replace(true) {
|
||||||
|
timeout_add_local_once(Duration::from_millis(500), {
|
||||||
|
let label = self.label.clone();
|
||||||
|
let is_active = self.is_active.clone();
|
||||||
|
let uri = uri.clone();
|
||||||
|
move || {
|
||||||
|
if is_active.replace(false) {
|
||||||
|
label.set_label(&uri.to_string());
|
||||||
|
label.set_visible(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.label.set_label(&uri.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
self.is_active.replace(false);
|
||||||
|
self.label.set_visible(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user