remove extra getters, give gobject names

This commit is contained in:
yggverse 2024-12-02 14:28:07 +02:00
parent cd49b36887
commit 2a59bebea9
17 changed files with 104 additions and 221 deletions

View File

@ -69,8 +69,8 @@ impl Page {
let widget = Rc::new(Widget::new( let widget = Rc::new(Widget::new(
&id, &id,
&navigation.widget.gobject, &navigation.widget.gobject,
content.gobject(), &content.gobject,
input.gobject(), &input.widget.clamp,
)); ));
let meta = Rc::new(Meta::new(Status::New, gformat!("New page"))); let meta = Rc::new(Meta::new(Status::New, gformat!("New page")));
@ -495,8 +495,8 @@ impl Page {
&buffer.data &buffer.data
); );
let title = match text_gemini.meta_title() { let title = match text_gemini.meta.title {
Some(title) => title, Some(ref title) => title,
None => &uri_to_title(&uri) None => &uri_to_title(&uri)
}; };

View File

@ -18,7 +18,7 @@ use std::{rc::Rc, time::Duration};
pub struct Content { pub struct Content {
window_action: Rc<WindowAction>, window_action: Rc<WindowAction>,
tab_action: Rc<TabAction>, tab_action: Rc<TabAction>,
gobject: Box, pub gobject: Box,
} }
impl Content { impl Content {
@ -97,7 +97,7 @@ impl Content {
base, base,
(self.window_action.clone(), self.tab_action.clone()), (self.window_action.clone(), self.tab_action.clone()),
); );
self.gobject.append(text.gobject()); self.gobject.append(&text.scrolled_window);
text text
} }
@ -107,11 +107,4 @@ impl Content {
self.gobject.remove(&child); self.gobject.remove(&child);
} }
} }
// Getters
/// Get reference to `Self` gobject
pub fn gobject(&self) -> &Box {
&self.gobject
}
} }

View File

@ -10,12 +10,12 @@ use gtk::{
use std::rc::Rc; use std::rc::Rc;
pub struct Meta { pub struct Meta {
title: Option<GString>, pub title: Option<GString>,
} } // @TODO move to separated mod
pub struct Text { pub struct Text {
meta: Meta, pub meta: Meta,
gobject: ScrolledWindow, pub scrolled_window: ScrolledWindow,
} }
impl Text { impl Text {
@ -26,24 +26,18 @@ impl Text {
// Init meta // Init meta
let meta = Meta { let meta = Meta {
title: gemini.reader_title().clone(), title: gemini.reader.title.clone(),
}; };
// Init gobject // Init scrolled_window
let gobject = ScrolledWindow::builder().build(); let scrolled_window = ScrolledWindow::builder().build();
gobject.set_child(Some(gemini.gobject())); scrolled_window.set_child(Some(&gemini.widget.clamp_scrollable));
// Result // Result
Self { meta, gobject } Self {
} meta,
scrolled_window,
// Getters }
pub fn meta_title(&self) -> &Option<GString> {
&self.meta.title
}
pub fn gobject(&self) -> &ScrolledWindow {
&self.gobject
} }
} }

View File

@ -5,13 +5,12 @@ use reader::Reader;
use widget::Widget; use widget::Widget;
use crate::app::browser::window::{tab::item::Action as TabAction, Action as WindowAction}; use crate::app::browser::window::{tab::item::Action as TabAction, Action as WindowAction};
use adw::ClampScrollable; use gtk::glib::Uri;
use gtk::glib::{GString, Uri};
use std::rc::Rc; use std::rc::Rc;
pub struct Gemini { pub struct Gemini {
reader: Rc<Reader>, pub reader: Rc<Reader>,
widget: Rc<Widget>, pub widget: Rc<Widget>,
} }
impl Gemini { impl Gemini {
@ -19,18 +18,9 @@ impl Gemini {
pub fn new(gemtext: &str, base: &Uri, actions: (Rc<WindowAction>, Rc<TabAction>)) -> Self { pub fn new(gemtext: &str, base: &Uri, actions: (Rc<WindowAction>, Rc<TabAction>)) -> Self {
// Init components // Init components
let reader = Rc::new(Reader::new(gemtext, base, actions)); let reader = Rc::new(Reader::new(gemtext, base, actions));
let widget = Rc::new(Widget::new(reader.gobject())); let widget = Rc::new(Widget::new(&reader.widget.text_view));
// Result // Result
Self { reader, widget } Self { reader, widget }
} }
// Getters
pub fn reader_title(&self) -> &Option<GString> {
self.reader.title()
}
pub fn gobject(&self) -> &ClampScrollable {
self.widget.gobject()
}
} }

View File

@ -20,14 +20,14 @@ use gtk::{
gio::Cancellable, gio::Cancellable,
glib::{GString, TimeZone, Uri}, glib::{GString, TimeZone, Uri},
prelude::{TextBufferExt, TextBufferExtManual, TextViewExt, WidgetExt}, prelude::{TextBufferExt, TextBufferExtManual, TextViewExt, WidgetExt},
EventControllerMotion, GestureClick, TextBuffer, TextTag, TextView, TextWindowType, EventControllerMotion, GestureClick, TextBuffer, TextTag, TextWindowType, UriLauncher, Window,
UriLauncher, Window, WrapMode, WrapMode,
}; };
use std::{collections::HashMap, rc::Rc}; use std::{collections::HashMap, rc::Rc};
pub struct Reader { pub struct Reader {
title: Option<GString>, pub title: Option<GString>,
widget: Rc<Widget>, pub widget: Rc<Widget>,
} }
impl Reader { impl Reader {
@ -46,14 +46,18 @@ impl Reader {
let tag = Tag::new(); let tag = Tag::new();
// Init new text buffer // Init new text buffer
let buffer = TextBuffer::new(Some(tag.gobject())); let buffer = TextBuffer::new(Some(&tag.text_tag_table));
// Parse gemtext lines // Parse gemtext lines
for line in gemtext.lines() { for line in gemtext.lines() {
// Is inline code // Is inline code
if let Some(code) = Code::inline_from(line) { if let Some(code) = Code::inline_from(line) {
// Append value to buffer // Append value to buffer
buffer.insert_with_tags(&mut buffer.end_iter(), code.value.as_str(), &[tag.code()]); buffer.insert_with_tags(
&mut buffer.end_iter(),
code.value.as_str(),
&[&tag.code.text_tag],
);
buffer.insert(&mut buffer.end_iter(), "\n"); buffer.insert(&mut buffer.end_iter(), "\n");
// Skip other actions for this line // Skip other actions for this line
@ -83,7 +87,7 @@ impl Reader {
buffer.insert_with_tags( buffer.insert_with_tags(
&mut buffer.end_iter(), &mut buffer.end_iter(),
alt.as_str(), alt.as_str(),
&[tag.title()], &[&tag.title.text_tag],
); );
buffer.insert(&mut buffer.end_iter(), "\n"); buffer.insert(&mut buffer.end_iter(), "\n");
} }
@ -92,7 +96,7 @@ impl Reader {
buffer.insert_with_tags( buffer.insert_with_tags(
&mut buffer.end_iter(), &mut buffer.end_iter(),
&this.buffer.join("\n"), &this.buffer.join("\n"),
&[tag.code()], &[&tag.code.text_tag],
); );
buffer.insert(&mut buffer.end_iter(), "\n"); buffer.insert(&mut buffer.end_iter(), "\n");
@ -113,9 +117,9 @@ impl Reader {
&mut buffer.end_iter(), &mut buffer.end_iter(),
header.value.as_str(), header.value.as_str(),
&[match header.level { &[match header.level {
Level::H1 => tag.h1(), Level::H1 => &tag.h1.text_tag,
Level::H2 => tag.h2(), Level::H2 => &tag.h2.text_tag,
Level::H3 => tag.h3(), Level::H3 => &tag.h3.text_tag,
}], }],
); );
buffer.insert(&mut buffer.end_iter(), "\n"); buffer.insert(&mut buffer.end_iter(), "\n");
@ -183,7 +187,7 @@ impl Reader {
buffer.insert_with_tags( buffer.insert_with_tags(
&mut buffer.end_iter(), &mut buffer.end_iter(),
format!("{}", list.value).as_str(), format!("{}", list.value).as_str(),
&[tag.list()], &[&tag.list.text_tag],
); );
buffer.insert(&mut buffer.end_iter(), "\n"); buffer.insert(&mut buffer.end_iter(), "\n");
@ -197,7 +201,7 @@ impl Reader {
buffer.insert_with_tags( buffer.insert_with_tags(
&mut buffer.end_iter(), &mut buffer.end_iter(),
quote.value.as_str(), quote.value.as_str(),
&[tag.quote()], &[&tag.quote.text_tag],
); );
buffer.insert(&mut buffer.end_iter(), "\n"); buffer.insert(&mut buffer.end_iter(), "\n");
@ -229,17 +233,17 @@ impl Reader {
// Init events // Init events
primary_button_controller.connect_released({ primary_button_controller.connect_released({
let gobject = widget.gobject().clone(); let text_view = widget.text_view.clone();
let _links_ = links.clone(); // is copy let _links_ = links.clone(); // is copy
move |_, _, window_x, window_y| { move |_, _, window_x, window_y| {
// Detect tag match current coords hovered // Detect tag match current coords hovered
let (buffer_x, buffer_y) = gobject.window_to_buffer_coords( let (buffer_x, buffer_y) = text_view.window_to_buffer_coords(
TextWindowType::Widget, TextWindowType::Widget,
window_x as i32, window_x as i32,
window_y as i32, window_y as i32,
); );
if let Some(iter) = gobject.iter_at_location(buffer_x, buffer_y) { if let Some(iter) = text_view.iter_at_location(buffer_x, buffer_y) {
for tag in iter.tags() { for tag in iter.tags() {
// Tag is link // Tag is link
if let Some(uri) = _links_.get(&tag) { if let Some(uri) = _links_.get(&tag) {
@ -267,16 +271,16 @@ impl Reader {
}); });
middle_button_controller.connect_pressed({ middle_button_controller.connect_pressed({
let gobject = widget.gobject().clone(); let text_view = widget.text_view.clone();
let _links_ = links.clone(); // is copy let _links_ = links.clone(); // is copy
move |_, _, window_x, window_y| { move |_, _, window_x, window_y| {
// Detect tag match current coords hovered // Detect tag match current coords hovered
let (buffer_x, buffer_y) = gobject.window_to_buffer_coords( let (buffer_x, buffer_y) = text_view.window_to_buffer_coords(
TextWindowType::Widget, TextWindowType::Widget,
window_x as i32, window_x as i32,
window_y as i32, window_y as i32,
); );
if let Some(iter) = gobject.iter_at_location(buffer_x, buffer_y) { if let Some(iter) = text_view.iter_at_location(buffer_x, buffer_y) {
for tag in iter.tags() { for tag in iter.tags() {
// Tag is link // Tag is link
if let Some(uri) = _links_.get(&tag) { if let Some(uri) = _links_.get(&tag) {
@ -311,28 +315,28 @@ impl Reader {
}); // for a note: this action sensitive to focus out }); // for a note: this action sensitive to focus out
motion_controller.connect_motion({ motion_controller.connect_motion({
let gobject = widget.gobject().clone(); let text_view = widget.text_view.clone();
let _links_ = links.clone(); // is copy let _links_ = links.clone(); // is copy
move |_, window_x, window_y| { move |_, window_x, window_y| {
// Detect tag match current coords hovered // Detect tag match current coords hovered
let (buffer_x, buffer_y) = gobject.window_to_buffer_coords( let (buffer_x, buffer_y) = text_view.window_to_buffer_coords(
TextWindowType::Widget, TextWindowType::Widget,
window_x as i32, window_x as i32,
window_y as i32, window_y as i32,
); );
if let Some(iter) = gobject.iter_at_location(buffer_x, buffer_y) { if let Some(iter) = text_view.iter_at_location(buffer_x, buffer_y) {
for tag in iter.tags() { for tag in iter.tags() {
// Tag is link // Tag is link
if let Some(uri) = _links_.get(&tag) { if let Some(uri) = _links_.get(&tag) {
// Toggle cursor // Toggle cursor
gobject.set_cursor_from_name(Some("pointer")); text_view.set_cursor_from_name(Some("pointer"));
// Show tooltip | @TODO set_gutter option? // Show tooltip | @TODO set_gutter option?
gobject.set_tooltip_text(Some(uri.to_string().as_str())); text_view.set_tooltip_text(Some(uri.to_string().as_str()));
// Redraw required to apply changes immediately // Redraw required to apply changes immediately
gobject.queue_draw(); text_view.queue_draw();
return; return;
} }
@ -340,22 +344,13 @@ impl Reader {
} }
// Restore defaults // Restore defaults
gobject.set_cursor_from_name(Some("text")); text_view.set_cursor_from_name(Some("text"));
gobject.set_tooltip_text(None); text_view.set_tooltip_text(None);
gobject.queue_draw(); text_view.queue_draw();
} }
}); // @TODO may be expensive for CPU, add timeout? }); // @TODO may be expensive for CPU, add timeout?
// Result // Result
Self { title, widget } Self { title, widget }
} }
// Getters
pub fn title(&self) -> &Option<GString> {
&self.title
}
pub fn gobject(&self) -> &TextView {
self.widget.gobject()
}
} }

View File

@ -17,15 +17,15 @@ use title::Title;
use gtk::{TextTag, TextTagTable}; use gtk::{TextTag, TextTagTable};
pub struct Tag { pub struct Tag {
gobject: TextTagTable, pub text_tag_table: TextTagTable,
// Tags // Tags
code: Code, pub code: Code,
h1: H1, pub h1: H1,
h2: H2, pub h2: H2,
h3: H3, pub h3: H3,
list: List, pub list: List,
quote: Quote, pub quote: Quote,
title: Title, pub title: Title,
} }
impl Tag { impl Tag {
@ -41,18 +41,18 @@ impl Tag {
let title = Title::new(); let title = Title::new();
// Init tag table // Init tag table
let gobject = TextTagTable::new(); let text_tag_table = TextTagTable::new();
gobject.add(code.gobject()); text_tag_table.add(&code.text_tag);
gobject.add(h1.gobject()); text_tag_table.add(&h1.text_tag);
gobject.add(h2.gobject()); text_tag_table.add(&h2.text_tag);
gobject.add(h3.gobject()); text_tag_table.add(&h3.text_tag);
gobject.add(title.gobject()); text_tag_table.add(&title.text_tag);
gobject.add(list.gobject()); text_tag_table.add(&list.text_tag);
gobject.add(quote.gobject()); text_tag_table.add(&quote.text_tag);
Self { Self {
gobject, text_tag_table,
// Tags // Tags
code, code,
h1, h1,
@ -65,40 +65,7 @@ impl Tag {
} }
// Actions // Actions
pub fn add(&self, tag: &TextTag) -> bool { pub fn add(&self, text_tag: &TextTag) -> bool {
self.gobject.add(tag) self.text_tag_table.add(text_tag)
}
// Getters
pub fn gobject(&self) -> &TextTagTable {
&self.gobject
}
pub fn code(&self) -> &TextTag {
self.code.gobject()
}
pub fn h1(&self) -> &TextTag {
self.h1.gobject()
}
pub fn h2(&self) -> &TextTag {
self.h2.gobject()
}
pub fn h3(&self) -> &TextTag {
self.h3.gobject()
}
pub fn list(&self) -> &TextTag {
self.list.gobject()
}
pub fn quote(&self) -> &TextTag {
self.quote.gobject()
}
pub fn title(&self) -> &TextTag {
self.title.gobject()
} }
} }

View File

@ -1,14 +1,14 @@
use gtk::{TextTag, WrapMode}; use gtk::{TextTag, WrapMode};
pub struct Code { pub struct Code {
tag: TextTag, pub text_tag: TextTag,
} }
impl Code { impl Code {
// Construct // Construct
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
tag: TextTag::builder() text_tag: TextTag::builder()
.family("monospace") // @TODO .family("monospace") // @TODO
.left_margin(28) .left_margin(28)
.scale(0.8) .scale(0.8)
@ -16,9 +16,4 @@ impl Code {
.build(), .build(),
} }
} }
// Getters
pub fn gobject(&self) -> &TextTag {
&self.tag
}
} }

View File

@ -1,14 +1,14 @@
use gtk::{TextTag, WrapMode}; use gtk::{TextTag, WrapMode};
pub struct H1 { pub struct H1 {
tag: TextTag, pub text_tag: TextTag,
} }
impl H1 { impl H1 {
// Construct // Construct
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
tag: TextTag::builder() text_tag: TextTag::builder()
.scale(1.6) .scale(1.6)
.sentence(true) .sentence(true)
.weight(500) .weight(500)
@ -16,9 +16,4 @@ impl H1 {
.build(), .build(),
} }
} }
// Getters
pub fn gobject(&self) -> &TextTag {
&self.tag
}
} }

View File

@ -1,14 +1,14 @@
use gtk::{TextTag, WrapMode}; use gtk::{TextTag, WrapMode};
pub struct H2 { pub struct H2 {
tag: TextTag, pub text_tag: TextTag,
} }
impl H2 { impl H2 {
// Construct // Construct
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
tag: TextTag::builder() text_tag: TextTag::builder()
.scale(1.4) .scale(1.4)
.sentence(true) .sentence(true)
.weight(400) .weight(400)
@ -16,9 +16,4 @@ impl H2 {
.build(), .build(),
} }
} }
// Getters
pub fn gobject(&self) -> &TextTag {
&self.tag
}
} }

View File

@ -1,14 +1,14 @@
use gtk::{TextTag, WrapMode}; use gtk::{TextTag, WrapMode};
pub struct H3 { pub struct H3 {
tag: TextTag, pub text_tag: TextTag,
} }
impl H3 { impl H3 {
// Construct // Construct
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
tag: TextTag::builder() text_tag: TextTag::builder()
.scale(1.2) .scale(1.2)
.sentence(true) .sentence(true)
.weight(400) .weight(400)
@ -16,9 +16,4 @@ impl H3 {
.build(), .build(),
} }
} }
// Getters
pub fn gobject(&self) -> &TextTag {
&self.tag
}
} }

View File

@ -1,14 +1,14 @@
use gtk::{TextTag, WrapMode}; use gtk::{TextTag, WrapMode};
pub struct List { pub struct List {
tag: TextTag, pub text_tag: TextTag,
} }
impl List { impl List {
// Construct // Construct
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
tag: TextTag::builder() text_tag: TextTag::builder()
.left_margin(28) .left_margin(28)
.pixels_above_lines(4) .pixels_above_lines(4)
.pixels_below_lines(4) .pixels_below_lines(4)
@ -16,9 +16,4 @@ impl List {
.build(), .build(),
} }
} }
// Getters
pub fn gobject(&self) -> &TextTag {
&self.tag
}
} }

View File

@ -1,22 +1,17 @@
use gtk::{pango::Style, TextTag, WrapMode}; use gtk::{pango::Style, TextTag, WrapMode};
pub struct Quote { pub struct Quote {
tag: TextTag, pub text_tag: TextTag,
} }
impl Quote { impl Quote {
// Construct // Construct
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
tag: TextTag::builder() text_tag: TextTag::builder()
.style(Style::Italic) .style(Style::Italic)
.wrap_mode(WrapMode::Word) .wrap_mode(WrapMode::Word)
.build(), .build(),
} }
} }
// Getters
pub fn gobject(&self) -> &TextTag {
&self.tag
}
} }

View File

@ -1,14 +1,14 @@
use gtk::{TextTag, WrapMode}; use gtk::{TextTag, WrapMode};
pub struct Title { pub struct Title {
tag: TextTag, pub text_tag: TextTag,
} }
impl Title { impl Title {
// Construct // Construct
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
tag: TextTag::builder() text_tag: TextTag::builder()
.pixels_above_lines(4) .pixels_above_lines(4)
.pixels_below_lines(8) .pixels_below_lines(8)
.weight(500) .weight(500)
@ -16,9 +16,4 @@ impl Title {
.build(), .build(),
} }
} }
// Getters
pub fn gobject(&self) -> &TextTag {
&self.tag
}
} }

View File

@ -5,7 +5,7 @@ use gtk::{
const MARGIN: i32 = 8; const MARGIN: i32 = 8;
pub struct Widget { pub struct Widget {
gobject: TextView, pub text_view: TextView,
} }
impl Widget { impl Widget {
@ -16,7 +16,7 @@ impl Widget {
middle_button_controller: GestureClick, middle_button_controller: GestureClick,
motion_controller: EventControllerMotion, motion_controller: EventControllerMotion,
) -> Self { ) -> Self {
let gobject = TextView::builder() let text_view = TextView::builder()
.bottom_margin(MARGIN) .bottom_margin(MARGIN)
.buffer(buffer) .buffer(buffer)
.cursor_visible(false) .cursor_visible(false)
@ -28,15 +28,10 @@ impl Widget {
.wrap_mode(WrapMode::Word) .wrap_mode(WrapMode::Word)
.build(); .build();
gobject.add_controller(primary_button_controller); text_view.add_controller(primary_button_controller);
gobject.add_controller(middle_button_controller); text_view.add_controller(middle_button_controller);
gobject.add_controller(motion_controller); text_view.add_controller(motion_controller);
Self { gobject } Self { text_view }
}
// Getters
pub fn gobject(&self) -> &TextView {
&self.gobject
} }
} }

View File

@ -1,24 +1,19 @@
use adw::ClampScrollable; use adw::ClampScrollable;
use gtk::TextView; use gtk::prelude::IsA;
pub struct Widget { pub struct Widget {
gobject: ClampScrollable, pub clamp_scrollable: ClampScrollable,
} }
impl Widget { impl Widget {
// Construct // Construct
pub fn new(child: &TextView) -> Self { pub fn new(child: &impl IsA<gtk::Widget>) -> Self {
Self { Self {
gobject: ClampScrollable::builder() clamp_scrollable: ClampScrollable::builder()
.child(child) .child(child)
.css_classes(["view"]) .css_classes(["view"])
.maximum_size(800) .maximum_size(800)
.build(), .build(),
} }
} }
// Getters
pub fn gobject(&self) -> &ClampScrollable {
&self.gobject
}
} }

View File

@ -7,12 +7,11 @@ use sensitive::Sensitive;
use widget::Widget; use widget::Widget;
use crate::app::browser::window::tab::item::Action as TabAction; use crate::app::browser::window::tab::item::Action as TabAction;
use adw::Clamp;
use gtk::glib::Uri; use gtk::glib::Uri;
use std::rc::Rc; use std::rc::Rc;
pub struct Input { pub struct Input {
widget: Rc<Widget>, pub widget: Rc<Widget>,
} }
impl Input { impl Input {
@ -54,9 +53,4 @@ impl Input {
Sensitive::new(action, base, title, max_length).gobject(), Sensitive::new(action, base, title, max_length).gobject(),
)); ));
} }
// Getters
pub fn gobject(&self) -> &Clamp {
self.widget.gobject()
}
} }

View File

@ -2,33 +2,28 @@ use adw::Clamp;
use gtk::{prelude::WidgetExt, Box}; use gtk::{prelude::WidgetExt, Box};
pub struct Widget { pub struct Widget {
gobject: Clamp, pub clamp: Clamp,
} }
impl Widget { impl Widget {
// Construct // Construct
pub fn new() -> Self { pub fn new() -> Self {
let gobject = Clamp::builder() let clamp = Clamp::builder()
.css_classes(["app-notification"]) .css_classes(["app-notification"])
.maximum_size(800) .maximum_size(800)
.visible(false) .visible(false)
.build(); .build();
Self { gobject } Self { clamp }
} }
// Actions // Actions
pub fn update(&self, child: Option<&Box>) { pub fn update(&self, child: Option<&Box>) {
if child.is_some() { if child.is_some() {
self.gobject.set_visible(true); // widget may be hidden, make it visible to child redraw self.clamp.set_visible(true); // widget may be hidden, make it visible to child redraw
self.gobject.set_child(child); self.clamp.set_child(child);
} else { } else {
self.gobject.set_visible(false) self.clamp.set_visible(false)
} }
} }
// Getters
pub fn gobject(&self) -> &Clamp {
&self.gobject
}
} }