From ccbc82d2f5b06c64ddcd363e2714599cc231e769 Mon Sep 17 00:00:00 2001 From: yggverse Date: Mon, 9 Dec 2024 21:20:58 +0200 Subject: [PATCH] add go to the address feature as secondary_icon for request entry widget --- .../item/page/navigation/request/widget.rs | 60 +++++++++++++++---- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/src/app/browser/window/tab/item/page/navigation/request/widget.rs b/src/app/browser/window/tab/item/page/navigation/request/widget.rs index 3c882ec4..ea8d23ab 100644 --- a/src/app/browser/window/tab/item/page/navigation/request/widget.rs +++ b/src/app/browser/window/tab/item/page/navigation/request/widget.rs @@ -2,14 +2,20 @@ mod database; use crate::app::browser::{window::tab::item::Action as TabAction, Action as BrowserAction}; use gtk::{ + gio::Icon, glib::{timeout_add_local, ControlFlow, SourceId}, prelude::{EditableExt, EntryExt, WidgetExt}, - Entry, StateFlags, + Entry, EntryIconPosition, StateFlags, }; 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 GO_TOOLTIP_TEXT: &str = "Go to the address"; // Progress bar animation setup const PROGRESS_ANIMATION_STEP: f64 = 0.05; @@ -28,32 +34,62 @@ pub struct Widget { impl Widget { // Construct pub fn new(action: (Rc, Rc)) -> Self { + // Set actions name + let (browser_action, tab_action) = action; + // Init animated progress bar state let progress = Rc::new(Progress { fraction: RefCell::new(0.0), source_id: RefCell::new(None), }); - // Init widget + // Init main widget let entry = Entry::builder() .placeholder_text(PLACEHOLDER_TEXT) .hexpand(true) .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 - entry.connect_changed(move |_| { - action.0.update.activate(None); + entry.connect_icon_release({ + 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| { - action.1.load().activate(Some(&this.text()), true); + entry.connect_changed(move |_| { + browser_action.update.activate(None); + }); + + entry.connect_activate(move |entry| { + tab_action.load().activate(Some(&entry.text()), true); }); entry.connect_state_flags_changed({ // Define last focus state container - let has_focus = RefCell::new(false); - move |this, state| { - // Select entire text on first click release + let has_focus = Cell::new(false); + move |entry, state| { + // Select entire text on first click (release) // this behavior implemented in most web-browsers, // to simply overwrite current request with new value // Note: @@ -61,9 +97,9 @@ impl Widget { // * This is experimental feature does not follow native GTK behavior @TODO make optional if !has_focus.take() && 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 has_focus.replace(state.contains(StateFlags::FOCUS_WITHIN));