add go to the address feature as secondary_icon for request entry widget

This commit is contained in:
yggverse 2024-12-09 21:20:58 +02:00
parent e32e425f65
commit ccbc82d2f5

View File

@ -2,14 +2,20 @@ mod database;
use crate::app::browser::{window::tab::item::Action as TabAction, Action as BrowserAction}; use crate::app::browser::{window::tab::item::Action as TabAction, Action as BrowserAction};
use gtk::{ use gtk::{
gio::Icon,
glib::{timeout_add_local, ControlFlow, SourceId}, glib::{timeout_add_local, ControlFlow, SourceId},
prelude::{EditableExt, EntryExt, WidgetExt}, prelude::{EditableExt, EntryExt, WidgetExt},
Entry, StateFlags, Entry, EntryIconPosition, StateFlags,
}; };
use sqlite::Transaction; use sqlite::Transaction;
use std::{cell::RefCell, rc::Rc, time::Duration}; use std::{
cell::{Cell, RefCell},
rc::Rc,
time::Duration,
};
const PLACEHOLDER_TEXT: &str = "URL or search term..."; const PLACEHOLDER_TEXT: &str = "URL or search term...";
const GO_TOOLTIP_TEXT: &str = "Go to the address";
// Progress bar animation setup // Progress bar animation setup
const PROGRESS_ANIMATION_STEP: f64 = 0.05; const PROGRESS_ANIMATION_STEP: f64 = 0.05;
@ -28,32 +34,62 @@ pub struct Widget {
impl Widget { impl Widget {
// Construct // Construct
pub fn new(action: (Rc<BrowserAction>, Rc<TabAction>)) -> Self { pub fn new(action: (Rc<BrowserAction>, Rc<TabAction>)) -> Self {
// Set actions name
let (browser_action, tab_action) = action;
// Init animated progress bar state // Init animated progress bar state
let progress = Rc::new(Progress { let progress = Rc::new(Progress {
fraction: RefCell::new(0.0), fraction: RefCell::new(0.0),
source_id: RefCell::new(None), source_id: RefCell::new(None),
}); });
// Init widget // Init main widget
let entry = Entry::builder() let entry = Entry::builder()
.placeholder_text(PLACEHOLDER_TEXT) .placeholder_text(PLACEHOLDER_TEXT)
.hexpand(true) .hexpand(true)
.build(); .build();
// Init `go` button feature (if icon available)
let go = match Icon::for_string("pan-end-symbolic") {
Ok(icon) => {
entry.set_secondary_icon_gicon(Some(&icon));
entry.set_secondary_icon_tooltip_text(Some(GO_TOOLTIP_TEXT));
Some(icon)
}
Err(e) => {
println!("{e}"); // drop notice @TODO
None
}
};
// Connect events // Connect events
entry.connect_changed(move |_| { entry.connect_icon_release({
action.0.update.activate(None); let tab_action = tab_action.clone();
let go = go.clone();
move |this, position| match position {
EntryIconPosition::Primary => todo!(),
EntryIconPosition::Secondary => {
if go.is_some() {
tab_action.load().activate(Some(&this.text()), true);
}
}
_ => println!("Undefined icon position"), // drop notice @TODO
}
}); });
entry.connect_activate(move |this| { entry.connect_changed(move |_| {
action.1.load().activate(Some(&this.text()), true); browser_action.update.activate(None);
});
entry.connect_activate(move |entry| {
tab_action.load().activate(Some(&entry.text()), true);
}); });
entry.connect_state_flags_changed({ entry.connect_state_flags_changed({
// Define last focus state container // Define last focus state container
let has_focus = RefCell::new(false); let has_focus = Cell::new(false);
move |this, state| { move |entry, state| {
// Select entire text on first click release // Select entire text on first click (release)
// this behavior implemented in most web-browsers, // this behavior implemented in most web-browsers,
// to simply overwrite current request with new value // to simply overwrite current request with new value
// Note: // Note:
@ -61,9 +97,9 @@ impl Widget {
// * This is experimental feature does not follow native GTK behavior @TODO make optional // * This is experimental feature does not follow native GTK behavior @TODO make optional
if !has_focus.take() if !has_focus.take()
&& state.contains(StateFlags::ACTIVE | StateFlags::FOCUS_WITHIN) && state.contains(StateFlags::ACTIVE | StateFlags::FOCUS_WITHIN)
&& this.selection_bounds().is_none() && entry.selection_bounds().is_none()
{ {
this.select_region(0, this.text_length().into()); entry.select_region(0, entry.text_length().into());
} }
// Update last focus state // Update last focus state
has_focus.replace(state.contains(StateFlags::FOCUS_WITHIN)); has_focus.replace(state.contains(StateFlags::FOCUS_WITHIN));