implement some components as traits

This commit is contained in:
yggverse 2025-01-31 22:02:53 +02:00
parent d1c05b6469
commit 1ad3e5006e
8 changed files with 70 additions and 79 deletions

View file

@ -57,9 +57,7 @@ impl Input {
title: Option<&str>, title: Option<&str>,
size_limit: Option<usize>, size_limit: Option<usize>,
) { ) {
self.update(Some( self.update(Some(&gtk::Box::response(action, base, title, size_limit)));
&Response::build(action, base, title, size_limit).g_box,
));
} }
pub fn set_new_sensitive( pub fn set_new_sensitive(
@ -69,9 +67,7 @@ impl Input {
title: Option<&str>, title: Option<&str>,
max_length: Option<i32>, max_length: Option<i32>,
) { ) {
self.update(Some( self.update(Some(&gtk::Box::sensitive(action, base, title, max_length)));
&Sensitive::build(action, base, title, max_length).g_box,
));
} }
pub fn set_new_titan(&self, on_send: impl Fn(&[u8], Box<dyn Fn()>) + 'static) { pub fn set_new_titan(&self, on_send: impl Fn(&[u8], Box<dyn Fn()>) + 'static) {

View file

@ -11,23 +11,27 @@ use gtk::{
gio::SimpleAction, gio::SimpleAction,
glib::{uuid_string_random, Uri, UriHideFlags}, glib::{uuid_string_random, Uri, UriHideFlags},
prelude::BoxExt, prelude::BoxExt,
Box, Orientation, Box, Label, Orientation, TextView,
}; };
use std::rc::Rc; use std::rc::Rc;
const MARGIN: i32 = 6; const MARGIN: i32 = 6;
const SPACING: i32 = 8; const SPACING: i32 = 8;
pub struct Response { pub trait Response {
// Components fn response(
pub g_box: Box, item_action: Rc<ItemAction>,
base: Uri,
title: Option<&str>,
size_limit: Option<usize>,
) -> Self;
} }
impl Response { impl Response for Box {
// Constructors // Constructors
/// Build new `Self` /// Build new `Self`
pub fn build( fn response(
item_action: Rc<ItemAction>, item_action: Rc<ItemAction>,
base: Uri, base: Uri,
title: Option<&str>, title: Option<&str>,
@ -39,8 +43,8 @@ impl Response {
// Init components // Init components
let control = Rc::new(Control::build(action_send.clone())); let control = Rc::new(Control::build(action_send.clone()));
let form = Rc::new(Form::build(action_update.clone())); let form = TextView::form(action_update.clone());
let title = Rc::new(Title::build(title)); let title = Label::title(title);
// Init main widget // Init main widget
let g_box = Box::builder() let g_box = Box::builder()
@ -52,8 +56,8 @@ impl Response {
.orientation(Orientation::Vertical) .orientation(Orientation::Vertical)
.build(); .build();
g_box.append(&title.label); g_box.append(&title);
g_box.append(&form.text_view); g_box.append(&form);
g_box.append(&control.g_box); g_box.append(&control.g_box);
// Init events // Init events
@ -88,7 +92,7 @@ impl Response {
} }
}); });
// Return activated struct // Return activated `Self`
Self { g_box } g_box
} }
} }

View file

@ -2,16 +2,14 @@ mod counter;
mod send; mod send;
use counter::Counter; use counter::Counter;
use gtk::{gio::SimpleAction, prelude::BoxExt, Align, Box, Button, Label, Orientation};
use send::Send; use send::Send;
use gtk::{gio::SimpleAction, prelude::BoxExt, Align, Box, Orientation};
use std::rc::Rc;
const SPACING: i32 = 8; const SPACING: i32 = 8;
pub struct Control { pub struct Control {
pub counter: Rc<Counter>, pub counter: Label,
pub send: Rc<Send>, pub send: Button,
pub g_box: Box, pub g_box: Box,
} }
@ -21,8 +19,8 @@ impl Control {
/// Build new `Self` /// Build new `Self`
pub fn build(action_send: SimpleAction) -> Self { pub fn build(action_send: SimpleAction) -> Self {
// Init components // Init components
let counter = Rc::new(Counter::new()); let counter = Label::counter();
let send = Rc::new(Send::build(action_send)); let send = Button::send(action_send);
// Init main widget // Init main widget
let g_box = Box::builder() let g_box = Box::builder()
@ -31,8 +29,8 @@ impl Control {
.spacing(SPACING) .spacing(SPACING)
.build(); .build();
g_box.append(&counter.label); g_box.append(&counter);
g_box.append(&send.button); g_box.append(&send);
// Return activated struct // Return activated struct
Self { Self {

View file

@ -1,47 +1,38 @@
use gtk::{prelude::WidgetExt, Label}; use gtk::{prelude::WidgetExt, Label};
use plurify::Plurify; use plurify::Plurify;
pub struct Counter { pub trait Counter {
pub label: Label, fn counter() -> Self;
fn update(&self, is_empty: bool, bytes_left: Option<isize>);
} }
impl Default for Counter { impl Counter for Label {
fn default() -> Self { fn counter() -> Self {
Self::new() Label::builder().build()
}
} }
impl Counter { fn update(&self, is_empty: bool, bytes_left: Option<isize>) {
// Construct
pub fn new() -> Self {
Self {
label: Label::builder().build(),
}
}
// Actions
pub fn update(&self, is_empty: bool, bytes_left: Option<isize>) {
match bytes_left { match bytes_left {
Some(value) => { Some(value) => {
// Update color on chars left reached // Update color on chars left reached
self.label.set_css_classes(&[if value.is_positive() { self.set_css_classes(&[if value.is_positive() {
"success" "success"
} else { } else {
"error" "error"
}]); // @TODO add warning step? }]); // @TODO add warning step?
// Update text // Update text
self.label.set_label(&value.to_string()); self.set_label(&value.to_string());
// Toggle visibility on chars left provided // Toggle visibility on chars left provided
self.label.set_visible(!is_empty); self.set_visible(!is_empty);
self.label.set_tooltip_text(Some(&format!( self.set_tooltip_text(Some(&format!(
"{value} {} left", "{value} {} left",
(value as usize).plurify(&["byte", "bytes", "bytes"]) (value as usize).plurify(&["byte", "bytes", "bytes"])
))); )));
} }
None => self.label.set_visible(false), None => self.set_visible(false),
} }
} }
} }

View file

@ -4,15 +4,16 @@ use gtk::{
Button, Button,
}; };
pub struct Send { pub trait Send {
pub button: Button, fn send(action_send: SimpleAction) -> Self;
fn update(&self, is_sensitive: bool);
} }
impl Send { impl Send for Button {
// Constructors // Constructors
/// Build new `Self` /// Build new `Self`
pub fn build(action_send: SimpleAction) -> Self { fn send(action_send: SimpleAction) -> Self {
// Init main widget // Init main widget
let button = Button::builder() let button = Button::builder()
.css_classes(["accent"]) // | `suggested-action` .css_classes(["accent"]) // | `suggested-action`
@ -30,11 +31,11 @@ impl Send {
}); });
// Return activated `Self` // Return activated `Self`
Self { button } button
} }
// Actions // Actions
pub fn update(&self, is_sensitive: bool) { fn update(&self, is_sensitive: bool) {
self.button.set_sensitive(is_sensitive); self.set_sensitive(is_sensitive);
} }
} }

View file

@ -9,15 +9,16 @@ use sourceview::Buffer;
const MARGIN: i32 = 8; const MARGIN: i32 = 8;
pub struct Form { pub trait Form {
pub text_view: TextView, fn form(action_update: SimpleAction) -> Self;
fn text(&self) -> GString;
} }
impl Form { impl Form for TextView {
// Constructors // Constructors
/// Build new `Self` /// Build new `Self`
pub fn build(action_update: SimpleAction) -> Self { fn form(action_update: SimpleAction) -> Self {
// Init [SourceView](https://gitlab.gnome.org/GNOME/gtksourceview) type buffer // Init [SourceView](https://gitlab.gnome.org/GNOME/gtksourceview) type buffer
let buffer = Buffer::builder().build(); let buffer = Buffer::builder().build();
@ -52,13 +53,13 @@ impl Form {
}); });
// Return activated `Self` // Return activated `Self`
Self { text_view } text_view
} }
// Getters // Getters
pub fn text(&self) -> GString { fn text(&self) -> GString {
let buffer = self.text_view.buffer(); let buffer = self.buffer();
buffer.text(&buffer.start_iter(), &buffer.end_iter(), true) buffer.text(&buffer.start_iter(), &buffer.end_iter(), true)
} }
} }

View file

@ -1,20 +1,15 @@
use gtk::{Align, Label}; use gtk::{Align, Label};
pub struct Title { pub trait Title {
pub label: Label, fn title(title: Option<&str>) -> Self;
} }
impl Title { impl Title for Label {
// Constructors fn title(title: Option<&str>) -> Self {
Label::builder()
/// Build new `Self`
pub fn build(title: Option<&str>) -> Self {
let label = Label::builder()
.css_classes(["heading"]) .css_classes(["heading"])
.halign(Align::Start) .halign(Align::Start)
.label(title.unwrap_or("Input expected")) .label(title.unwrap_or("Input expected"))
.build(); .build()
Self { label }
} }
} }

View file

@ -13,15 +13,20 @@ use std::rc::Rc;
const MARGIN: i32 = 6; const MARGIN: i32 = 6;
const SPACING: i32 = 8; const SPACING: i32 = 8;
pub struct Sensitive { pub trait Sensitive {
pub g_box: Box, fn sensitive(
item_action: Rc<ItemAction>,
base: Uri,
title: Option<&str>,
max_length: Option<i32>,
) -> Self;
} }
impl Sensitive { impl Sensitive for Box {
// Constructors // Constructors
/// Build new `Self` /// Build new `Self`
pub fn build( fn sensitive(
item_action: Rc<ItemAction>, item_action: Rc<ItemAction>,
base: Uri, base: Uri,
title: Option<&str>, title: Option<&str>,
@ -69,7 +74,7 @@ impl Sensitive {
form.password_entry_row.grab_focus(); form.password_entry_row.grab_focus();
}); });
// Return activated struct // Return activated `Self`
Self { g_box } g_box
} }
} }