mirror of
https://github.com/YGGverse/Yoda.git
synced 2026-04-02 09:35:28 +00:00
draft file form
This commit is contained in:
parent
a437b9b7a2
commit
86bb0a7578
6 changed files with 176 additions and 30 deletions
|
|
@ -1,31 +1,43 @@
|
||||||
use gtk::{prelude::BoxExt, Align, Label, Orientation};
|
mod control;
|
||||||
|
|
||||||
const MARGIN: i32 = 8;
|
use super::Header;
|
||||||
const SPACING: i32 = 8;
|
use gtk::Box;
|
||||||
|
|
||||||
pub trait File {
|
pub trait File {
|
||||||
fn file() -> Self;
|
fn file() -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl File for gtk::Box {
|
impl File for Box {
|
||||||
fn file() -> Self {
|
fn file() -> Self {
|
||||||
// Init widget
|
use control::Control;
|
||||||
let g_box = gtk::Box::builder()
|
use gtk::Button;
|
||||||
.halign(Align::Center)
|
use std::{cell::Cell, rc::Rc};
|
||||||
.margin_bottom(MARGIN)
|
|
||||||
.margin_end(MARGIN)
|
|
||||||
.margin_start(MARGIN)
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.spacing(SPACING)
|
|
||||||
//.margin_top(MARGIN)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
g_box.append(
|
// Init components
|
||||||
&Label::builder()
|
let header = Rc::new(Cell::new(Header {
|
||||||
.css_classes(["dim-label"])
|
mime: None,
|
||||||
.label("Soon..")
|
token: None,
|
||||||
.build(),
|
}));
|
||||||
); // @TODO
|
let control = Box::control(&header);
|
||||||
g_box
|
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(MARGIN)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
g_box.append(&form);
|
||||||
|
g_box.append(&control);
|
||||||
|
g_box
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,16 +2,7 @@ mod control;
|
||||||
mod form;
|
mod form;
|
||||||
|
|
||||||
use super::Header;
|
use super::Header;
|
||||||
use control::Control;
|
|
||||||
use control::Upload;
|
|
||||||
use form::Form;
|
|
||||||
use gtk::glib::Bytes;
|
use gtk::glib::Bytes;
|
||||||
use gtk::{
|
|
||||||
prelude::{BoxExt, ButtonExt, TextBufferExt, TextViewExt},
|
|
||||||
Orientation, TextView,
|
|
||||||
};
|
|
||||||
use std::cell::Cell;
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
pub trait Text {
|
pub trait Text {
|
||||||
fn text(callback: impl Fn(Header, Bytes, Box<dyn Fn()>) + 'static) -> Self;
|
fn text(callback: impl Fn(Header, Bytes, Box<dyn Fn()>) + 'static) -> Self;
|
||||||
|
|
@ -19,6 +10,14 @@ pub trait Text {
|
||||||
|
|
||||||
impl Text for gtk::Box {
|
impl Text for gtk::Box {
|
||||||
fn text(callback: impl Fn(Header, Bytes, Box<dyn Fn()>) + 'static) -> Self {
|
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
|
// Init components
|
||||||
let header = Rc::new(Cell::new(Header {
|
let header = Rc::new(Cell::new(Header {
|
||||||
mime: Some("text/plain".into()), // some servers require not empty content type
|
mime: Some("text/plain".into()), // some servers require not empty content type
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue