mirror of
https://github.com/YGGverse/Yoda.git
synced 2026-04-02 09:35:28 +00:00
begin identity dialog implementation
This commit is contained in:
parent
12b4d441ca
commit
14c31734fd
18 changed files with 439 additions and 72 deletions
86
src/app/browser/window/tab/item/identity/gemini/widget.rs
Normal file
86
src/app/browser/window/tab/item/identity/gemini/widget.rs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
mod form;
|
||||
|
||||
use form::Form;
|
||||
|
||||
use adw::{
|
||||
prelude::{AdwDialogExt, AlertDialogExt, AlertDialogExtManual},
|
||||
AlertDialog, ResponseAppearance,
|
||||
};
|
||||
use gtk::prelude::IsA;
|
||||
|
||||
// Defaults
|
||||
const HEADING: &str = "Ident";
|
||||
const BODY: &str = "Select identity certificate";
|
||||
|
||||
// Response variants
|
||||
const RESPONSE_APPLY: (&str, &str) = ("apply", "Apply");
|
||||
const RESPONSE_CANCEL: (&str, &str) = ("cancel", "Cancel");
|
||||
// const RESPONSE_MANAGE: (&str, &str) = ("manage", "Manage");
|
||||
|
||||
// List options
|
||||
const OPTION_CREATE: (Option<i64>, &str) = (None, "Create new..");
|
||||
|
||||
// Select options
|
||||
|
||||
pub struct Widget {
|
||||
gobject: AlertDialog,
|
||||
}
|
||||
|
||||
impl Widget {
|
||||
// Constructors
|
||||
|
||||
/// Create new `Self`
|
||||
pub fn new() -> Self {
|
||||
// Collect identity certificates
|
||||
let mut options: Vec<(Option<i64>, String, bool)> = Vec::new();
|
||||
options.push((OPTION_CREATE.0, OPTION_CREATE.1.to_owned(), false));
|
||||
|
||||
// Init child container
|
||||
let form = Form::new(options);
|
||||
|
||||
// Init main `GObject`
|
||||
let gobject = AlertDialog::builder()
|
||||
.heading(HEADING)
|
||||
.body(BODY)
|
||||
.close_response(RESPONSE_CANCEL.0)
|
||||
.default_response(RESPONSE_APPLY.0)
|
||||
.extra_child(form.gobject())
|
||||
.build();
|
||||
|
||||
// Set response variants
|
||||
gobject.add_responses(&[
|
||||
RESPONSE_CANCEL,
|
||||
// RESPONSE_MANAGE,
|
||||
RESPONSE_APPLY,
|
||||
]);
|
||||
|
||||
// Deactivate not implemented feature @TODO
|
||||
// gobject.set_response_enabled(RESPONSE_MANAGE.0, false);
|
||||
|
||||
// Decorate default response preset
|
||||
gobject.set_response_appearance(RESPONSE_APPLY.0, ResponseAppearance::Suggested);
|
||||
gobject.set_response_appearance(RESPONSE_CANCEL.0, ResponseAppearance::Destructive);
|
||||
|
||||
// Return new activated `Self`
|
||||
Self { gobject }
|
||||
}
|
||||
|
||||
// Actions
|
||||
|
||||
/// Wrapper for default [response](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/signal.AlertDialog.response.html) signal
|
||||
/// * return `profile_identity_gemini_id` or new record request on `None`
|
||||
pub fn connect_response(&self, callback: impl Fn(Option<i64>) + 'static) {
|
||||
self.gobject.connect_response(None, move |_, response| {
|
||||
if response == RESPONSE_APPLY.0 {
|
||||
callback(None)
|
||||
} else {
|
||||
callback(None)
|
||||
} // @TODO
|
||||
});
|
||||
}
|
||||
|
||||
/// Show dialog with new preset
|
||||
pub fn present(&self, parent: Option<&impl IsA<gtk::Widget>>) {
|
||||
self.gobject.present(parent)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
mod list;
|
||||
mod name;
|
||||
|
||||
use list::List;
|
||||
use name::Name;
|
||||
|
||||
use gtk::{
|
||||
prelude::{BoxExt, WidgetExt},
|
||||
Box, Orientation,
|
||||
};
|
||||
|
||||
pub struct Form {
|
||||
gobject: Box,
|
||||
}
|
||||
|
||||
impl Form {
|
||||
// Constructors
|
||||
|
||||
/// Create new `Self`
|
||||
pub fn new(list_options: Vec<(Option<i64>, String, bool)>) -> Self {
|
||||
// Init components
|
||||
let list = List::new(&list_options);
|
||||
let name = Name::new();
|
||||
|
||||
// Init main container
|
||||
let gobject = Box::builder().orientation(Orientation::Vertical).build();
|
||||
|
||||
gobject.append(list.gobject());
|
||||
gobject.append(name.gobject());
|
||||
|
||||
// Init events
|
||||
list.gobject().connect_selected_notify(move |this| {
|
||||
// Get selection ID from vector @TODO use GObject storage instead
|
||||
// https://gtk-rs.org/gtk4-rs/stable/latest/book/list_widgets.html
|
||||
match list_options.get(this.selected() as usize) {
|
||||
// Hide name entry on existing identity selected
|
||||
Some((id, _, _)) => name.gobject().set_visible(id.is_none()),
|
||||
None => todo!(),
|
||||
}
|
||||
});
|
||||
|
||||
// Return activated `Self`
|
||||
Self { gobject }
|
||||
}
|
||||
|
||||
// Getters
|
||||
|
||||
pub fn gobject(&self) -> &Box {
|
||||
&self.gobject
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
use gtk::{DropDown, StringList};
|
||||
|
||||
pub struct List {
|
||||
gobject: DropDown,
|
||||
}
|
||||
|
||||
impl List {
|
||||
// Constructors
|
||||
|
||||
/// Create new `Self`
|
||||
pub fn new(list_options: &Vec<(Option<i64>, String, bool)>) -> Self {
|
||||
// Init empty list model
|
||||
let model = StringList::new(&[]);
|
||||
|
||||
// Init `GObject`
|
||||
let gobject = DropDown::builder().model(&model).build();
|
||||
|
||||
// Build selection list
|
||||
let mut index = 0;
|
||||
|
||||
for (_key, value, is_selected) in list_options {
|
||||
model.append(&value);
|
||||
|
||||
if *is_selected {
|
||||
gobject.set_selected(index);
|
||||
}
|
||||
|
||||
index += 1;
|
||||
}
|
||||
|
||||
// Done
|
||||
Self { gobject }
|
||||
}
|
||||
|
||||
// Getters
|
||||
|
||||
pub fn gobject(&self) -> &DropDown {
|
||||
&self.gobject
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
use gtk::Entry;
|
||||
|
||||
const PLACEHOLDER_TEXT: &str = "Identity name (optional)";
|
||||
const MARGIN: i32 = 8;
|
||||
|
||||
pub struct Name {
|
||||
gobject: Entry,
|
||||
}
|
||||
|
||||
impl Name {
|
||||
// Constructors
|
||||
|
||||
/// Create new `Self`
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
gobject: Entry::builder()
|
||||
.max_length(36) // @TODO use profile const
|
||||
.placeholder_text(PLACEHOLDER_TEXT)
|
||||
.margin_top(MARGIN)
|
||||
.build(),
|
||||
}
|
||||
}
|
||||
|
||||
// Getters
|
||||
|
||||
pub fn gobject(&self) -> &Entry {
|
||||
&self.gobject
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue