From db44fff212798213d6dc2218d1ff6f5f322bcc0b Mon Sep 17 00:00:00 2001 From: yggverse Date: Sun, 15 Dec 2024 13:08:57 +0200 Subject: [PATCH] draft find widget --- .../page/content/text/gemini/reader/widget.rs | 32 +++++++++- .../content/text/gemini/reader/widget/find.rs | 62 +++++++++++++++++++ 2 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 src/app/browser/window/tab/item/page/content/text/gemini/reader/widget/find.rs diff --git a/src/app/browser/window/tab/item/page/content/text/gemini/reader/widget.rs b/src/app/browser/window/tab/item/page/content/text/gemini/reader/widget.rs index 18e2aa60..460fc5cb 100644 --- a/src/app/browser/window/tab/item/page/content/text/gemini/reader/widget.rs +++ b/src/app/browser/window/tab/item/page/content/text/gemini/reader/widget.rs @@ -1,21 +1,33 @@ +mod find; + +use find::Find; + use gtk::{ - prelude::WidgetExt, EventControllerMotion, GestureClick, TextBuffer, TextView, WrapMode, + prelude::{TextViewExt, WidgetExt}, + EventControllerMotion, GestureClick, TextBuffer, TextView, TextWindowType, WrapMode, }; const MARGIN: i32 = 8; pub struct Widget { + find: Find, pub text_view: TextView, } impl Widget { - // Construct + // Constructors + + /// Create new `Self` pub fn new( buffer: &TextBuffer, primary_button_controller: GestureClick, middle_button_controller: GestureClick, motion_controller: EventControllerMotion, ) -> Self { + // Init components + let find = Find::new(); + + // Init main widget let text_view = TextView::builder() .bottom_margin(MARGIN) .buffer(buffer) @@ -32,6 +44,20 @@ impl Widget { text_view.add_controller(middle_button_controller); text_view.add_controller(motion_controller); - Self { text_view } + // Done + Self { find, text_view } + } + + // Actions + + pub fn find(&self, is_visible: bool) { + if is_visible { + self.text_view + .set_gutter(TextWindowType::Bottom, Some(&self.find.g_box)); + self.find.g_box.grab_focus(); + } else { + self.text_view + .set_gutter(TextWindowType::Bottom, gtk::Widget::NONE); + } } } diff --git a/src/app/browser/window/tab/item/page/content/text/gemini/reader/widget/find.rs b/src/app/browser/window/tab/item/page/content/text/gemini/reader/widget/find.rs new file mode 100644 index 00000000..1a20a066 --- /dev/null +++ b/src/app/browser/window/tab/item/page/content/text/gemini/reader/widget/find.rs @@ -0,0 +1,62 @@ +use gtk::{ + gdk::Cursor, + prelude::{BoxExt, EditableExt, EntryExt}, + Box, Button, Entry, EntryIconPosition, Orientation, +}; + +const MARGIN: i32 = 6; + +pub struct Find { + pub g_box: Box, +} + +impl Find { + // Construct + pub fn new() -> Self { + // Init components + let close = Button::builder() + .cursor(&Cursor::from_name("default", None).unwrap()) + .icon_name("window-close-symbolic") + .margin_bottom(MARGIN) + .margin_end(MARGIN) + .margin_top(MARGIN) + .tooltip_text("Close find bar") + .build(); + + let entry = Entry::builder() + .hexpand(true) + .margin_bottom(MARGIN) + .margin_end(MARGIN) + .margin_start(MARGIN) + .margin_top(MARGIN) + .placeholder_text("Find in text..") + .primary_icon_activatable(false) + .primary_icon_name("system-search-symbolic") + .build(); + + // Init main container + let g_box = Box::builder().orientation(Orientation::Horizontal).build(); + + g_box.append(&entry); + g_box.append(&close); + + // Connect events + entry.connect_activate(|_| {}); // @TODO + + entry.connect_changed(move |this| { + if this.text().is_empty() { + this.set_secondary_icon_name(None); + } else { + this.set_secondary_icon_name(Some("edit-clear-symbolic")); + } + }); + + entry.connect_icon_release(move |this, position| match position { + EntryIconPosition::Secondary => this.delete_text(0, -1), + _ => todo!(), // unexpected + }); + + // Done + Self { g_box } + } +}