draft file form

This commit is contained in:
yggverse 2025-02-07 13:51:14 +02:00
parent a437b9b7a2
commit 86bb0a7578
6 changed files with 176 additions and 30 deletions

View file

@ -1,31 +1,43 @@
use gtk::{prelude::BoxExt, Align, Label, Orientation};
mod control;
const MARGIN: i32 = 8;
const SPACING: i32 = 8;
use super::Header;
use gtk::Box;
pub trait File {
fn file() -> Self;
}
impl File for gtk::Box {
impl File for Box {
fn file() -> Self {
// Init widget
let g_box = gtk::Box::builder()
.halign(Align::Center)
use control::Control;
use gtk::Button;
use std::{cell::Cell, rc::Rc};
// Init components
let header = Rc::new(Cell::new(Header {
mime: None,
token: None,
}));
let control = Box::control(&header);
let form = Button::builder().label("Choose a file..").build();
// Init main widget
{
use gtk::{prelude::BoxExt, Orientation};
const MARGIN: i32 = 8;
let g_box = Box::builder()
.margin_bottom(MARGIN)
.margin_end(MARGIN)
.margin_start(MARGIN)
.orientation(Orientation::Vertical)
.spacing(SPACING)
//.margin_top(MARGIN)
.spacing(MARGIN)
.build();
g_box.append(
&Label::builder()
.css_classes(["dim-label"])
.label("Soon..")
.build(),
); // @TODO
g_box.append(&form);
g_box.append(&control);
g_box
}
}
}

View file

@ -0,0 +1,40 @@
mod counter;
mod options;
mod upload;
use super::Header;
use gtk::Box;
use std::{cell::Cell, rc::Rc};
pub trait Control {
fn control(header: &Rc<Cell<Header>>) -> Self;
}
impl Control for Box {
fn control(header: &Rc<Cell<Header>>) -> Self {
use counter::Counter;
use gtk::{Button, Label};
use options::Options;
use upload::Upload;
// Init components
let counter = Label::counter();
let options = Button::options(header);
let upload = Button::upload();
// Init main widget
{
use gtk::{prelude::BoxExt, Align, Orientation};
let g_box = Box::builder()
.halign(Align::End)
.orientation(Orientation::Horizontal)
.spacing(8)
.build();
g_box.append(&counter);
g_box.append(&options);
g_box.append(&upload);
g_box
}
}
}

View file

@ -0,0 +1,28 @@
use gtk::{prelude::WidgetExt, Label};
use plurify::Plurify;
pub trait Counter {
fn counter() -> Self;
fn update(&self, bytes_total: usize);
}
impl Counter for Label {
// Constructors
fn counter() -> Self {
Label::builder().css_classes(["dim-label"]).build() // @TODO use `dimmed` in Adw 1.6,
}
// Actions
fn update(&self, bytes_total: usize) {
self.set_visible(if bytes_total > 0 {
let format = bytes_total.plurify(&["byte", "bytes", "bytes"]);
self.set_label(format);
self.set_tooltip_text(Some(format));
true
} else {
false
})
}
}

View file

@ -0,0 +1,37 @@
use super::Header;
use gtk::{
prelude::{ButtonExt, WidgetExt},
Button,
};
use std::{cell::Cell, rc::Rc};
pub trait Options {
fn options(header: &Rc<Cell<Header>>) -> Self;
}
impl Options for Button {
fn options(header: &Rc<Cell<Header>>) -> Self {
let button = Button::builder()
.icon_name("emblem-system-symbolic")
.sensitive(false)
.tooltip_text("Options")
.build();
button.connect_clicked({
let header = header.clone();
move |this| {
this.set_sensitive(false); // lock
header.take().dialog(Some(this), {
let this = this.clone();
let header = header.clone();
move |options| {
header.replace(options);
this.set_sensitive(true); // unlock
}
})
}
});
button
}
}

View file

@ -0,0 +1,30 @@
use gtk::{
prelude::{ButtonExt, WidgetExt},
Button,
};
pub trait Upload {
fn upload() -> Self;
fn set_uploading(&self);
fn set_resend(&self);
}
impl Upload for Button {
fn upload() -> Self {
Button::builder()
// @TODO this class not looks well with default GTK Notebook widget
// activate it after upgrade to `ToggleGroup` in Adw v1.7 / Ubuntu 26.04
// .css_classes(["accent"]) // | `suggested-action`
.label("Upload")
.sensitive(false)
.build()
}
fn set_uploading(&self) {
self.set_sensitive(false);
self.set_label("uploading..");
}
fn set_resend(&self) {
self.set_sensitive(true);
self.set_label("Resend");
}
}

View file

@ -2,16 +2,7 @@ mod control;
mod form;
use super::Header;
use control::Control;
use control::Upload;
use form::Form;
use gtk::glib::Bytes;
use gtk::{
prelude::{BoxExt, ButtonExt, TextBufferExt, TextViewExt},
Orientation, TextView,
};
use std::cell::Cell;
use std::rc::Rc;
pub trait Text {
fn text(callback: impl Fn(Header, Bytes, Box<dyn Fn()>) + 'static) -> Self;
@ -19,6 +10,14 @@ pub trait Text {
impl Text for gtk::Box {
fn text(callback: impl Fn(Header, Bytes, Box<dyn Fn()>) + 'static) -> Self {
use control::{Control, Upload};
use form::Form;
use gtk::{
prelude::{BoxExt, ButtonExt, TextBufferExt, TextViewExt},
Orientation, TextView,
};
use std::{cell::Cell, rc::Rc};
// Init components
let header = Rc::new(Cell::new(Header {
mime: Some("text/plain".into()), // some servers require not empty content type