mirror of
https://github.com/YGGverse/Yoda.git
synced 2025-01-15 17:20:08 +00:00
replace hashmap index with custom gobject properties impl
This commit is contained in:
parent
5d647518c0
commit
46a25306e1
@ -23,7 +23,7 @@ impl Gemini {
|
|||||||
let widget = Rc::new(Widget::new());
|
let widget = Rc::new(Widget::new());
|
||||||
|
|
||||||
// Add new identity option
|
// Add new identity option
|
||||||
widget.form.list.append(None, "Create new..");
|
widget.form.list.append(None, "Create new..", true);
|
||||||
|
|
||||||
// Collect additional options from database
|
// Collect additional options from database
|
||||||
match profile.identity.gemini.database.records() {
|
match profile.identity.gemini.database.records() {
|
||||||
@ -49,6 +49,7 @@ impl Gemini {
|
|||||||
Some(name) => format!("{name} ({expires})"),
|
Some(name) => format!("{name} ({expires})"),
|
||||||
None => format!("{expires}"),
|
None => format!("{expires}"),
|
||||||
},
|
},
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
use gtk::{gio::ListStore, DropDown, Label};
|
mod item;
|
||||||
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
use item::Item;
|
||||||
|
|
||||||
|
use gio::prelude::{Cast, CastNone};
|
||||||
|
use gtk::{gio::ListStore, prelude::ListItemExt, DropDown, Label, ListItem, SignalListItemFactory};
|
||||||
|
|
||||||
pub struct List {
|
pub struct List {
|
||||||
pub gobject: DropDown,
|
pub gobject: DropDown,
|
||||||
model: ListStore,
|
model: ListStore,
|
||||||
index: Rc<RefCell<HashMap<Label, Option<i64>>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl List {
|
impl List {
|
||||||
@ -12,31 +14,40 @@ impl List {
|
|||||||
|
|
||||||
/// Create new `Self`
|
/// Create new `Self`
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let index = Rc::new(RefCell::new(HashMap::new()));
|
// Init model with custom `GObject` properties
|
||||||
let model = ListStore::new::<Label>();
|
let model = ListStore::new::<Item>();
|
||||||
let gobject = DropDown::builder().model(&model).build();
|
|
||||||
|
|
||||||
Self {
|
// Setup item factory to append items after `DropDown` init
|
||||||
model,
|
let factory = SignalListItemFactory::new();
|
||||||
index,
|
|
||||||
gobject,
|
// @TODO factory.connect_setup(move |_, gobject| {});
|
||||||
}
|
factory.connect_bind(move |_, gobject| {
|
||||||
|
// Cast components
|
||||||
|
let list_item = gobject.downcast_ref::<ListItem>().unwrap();
|
||||||
|
let item = list_item.item().and_downcast::<Item>().unwrap();
|
||||||
|
|
||||||
|
// Update menu item
|
||||||
|
list_item.set_child(Some(&Label::new(Some(&item.label()))));
|
||||||
|
|
||||||
|
// @TODO
|
||||||
|
println!("{:?}", item.profile_identity_gemini_id_option());
|
||||||
|
println!("{:?}", item.label());
|
||||||
|
println!("{:?}", item.is_enabled());
|
||||||
|
});
|
||||||
|
|
||||||
|
// Init list `GObject`
|
||||||
|
let gobject = DropDown::builder().model(&model).factory(&factory).build();
|
||||||
|
|
||||||
|
// Return activated `Self`
|
||||||
|
Self { model, gobject }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
|
|
||||||
/// Append new item with `profile_identity_gemini_id` as `key` and label as `value`
|
/// Append new item with `profile_identity_gemini_id` as `key` and label as `value`
|
||||||
pub fn append(&self, profile_identity_gemini_id: Option<i64>, label: &str) {
|
pub fn append(&self, profile_identity_gemini_id: Option<i64>, label: &str, is_enabled: bool) {
|
||||||
// Create new label for item
|
self.model
|
||||||
let item = Label::new(Some(label));
|
.append(&Item::new(profile_identity_gemini_id, label, is_enabled));
|
||||||
|
|
||||||
// Append formatted record
|
|
||||||
self.model.append(&item);
|
|
||||||
|
|
||||||
// Register ID in hash map index
|
|
||||||
self.index
|
|
||||||
.borrow_mut()
|
|
||||||
.insert(item, profile_identity_gemini_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
@ -44,9 +55,13 @@ impl List {
|
|||||||
/// Run callback function on `connect_selected_notify` event
|
/// Run callback function on `connect_selected_notify` event
|
||||||
/// * return formatted `profile_identity_gemini_id` match selected
|
/// * return formatted `profile_identity_gemini_id` match selected
|
||||||
pub fn connect_selected_notify(&self, callback: impl Fn(Option<i64>) + 'static) {
|
pub fn connect_selected_notify(&self, callback: impl Fn(Option<i64>) + 'static) {
|
||||||
self.gobject.connect_selected_notify({
|
self.gobject.connect_selected_notify(move |list| {
|
||||||
let index = self.index.clone();
|
callback(
|
||||||
move |list| callback(*index.borrow().get(&list.selected_item().unwrap()).unwrap())
|
list.selected_item()
|
||||||
|
.and_downcast::<Item>()
|
||||||
|
.unwrap()
|
||||||
|
.profile_identity_gemini_id_option(),
|
||||||
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
mod imp;
|
||||||
|
use gtk::glib::{self, Object};
|
||||||
|
|
||||||
|
glib::wrapper! {
|
||||||
|
pub struct Item(ObjectSubclass<imp::Item>);
|
||||||
|
}
|
||||||
|
|
||||||
|
// C-based conversion for `None` value
|
||||||
|
const PROFILE_IDENTITY_GEMINI_ID_NONE: i64 = -1;
|
||||||
|
|
||||||
|
impl Item {
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
/// Create new `GObject` with formatted properties
|
||||||
|
pub fn new(profile_identity_gemini_id: Option<i64>, label: &str, is_enabled: bool) -> Self {
|
||||||
|
Object::builder()
|
||||||
|
.property(
|
||||||
|
"profile_identity_gemini_id",
|
||||||
|
match profile_identity_gemini_id {
|
||||||
|
Some(value) => value,
|
||||||
|
None => PROFILE_IDENTITY_GEMINI_ID_NONE,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.property("label", label)
|
||||||
|
.property("is_enabled", is_enabled)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
|
||||||
|
/// Additional `profile_identity_gemini_id` wrapper with `Option` value support
|
||||||
|
pub fn profile_identity_gemini_id_option(&self) -> Option<i64> {
|
||||||
|
match self.profile_identity_gemini_id() {
|
||||||
|
PROFILE_IDENTITY_GEMINI_ID_NONE => None,
|
||||||
|
value => Some(value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
//! Custom `GObject` implementation for dropdown
|
||||||
|
//! [ListStore](https://docs.gtk.org/gio/class.ListStore.html) menu item
|
||||||
|
|
||||||
|
use gtk::{
|
||||||
|
gio::subclass::prelude::{DerivedObjectProperties, ObjectImpl, ObjectImplExt, ObjectSubclass},
|
||||||
|
glib::{self, Object, Properties},
|
||||||
|
prelude::ObjectExt,
|
||||||
|
};
|
||||||
|
use std::cell::{Cell, RefCell};
|
||||||
|
|
||||||
|
#[derive(Properties, Default)]
|
||||||
|
#[properties(wrapper_type = super::Item)]
|
||||||
|
pub struct Item {
|
||||||
|
#[property(get, set)]
|
||||||
|
profile_identity_gemini_id: Cell<i64>,
|
||||||
|
#[property(get, set)]
|
||||||
|
label: RefCell<String>,
|
||||||
|
#[property(get, set)]
|
||||||
|
is_enabled: Cell<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[glib::object_subclass]
|
||||||
|
impl ObjectSubclass for Item {
|
||||||
|
const NAME: &str = "Item"; // @TODO make globally unique
|
||||||
|
type Type = super::Item;
|
||||||
|
type ParentType = Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[glib::derived_properties]
|
||||||
|
impl ObjectImpl for Item {
|
||||||
|
fn constructed(&self) {
|
||||||
|
self.parent_constructed();
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user