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());
|
||||
|
||||
// Add new identity option
|
||||
widget.form.list.append(None, "Create new..");
|
||||
widget.form.list.append(None, "Create new..", true);
|
||||
|
||||
// Collect additional options from database
|
||||
match profile.identity.gemini.database.records() {
|
||||
@ -49,6 +49,7 @@ impl Gemini {
|
||||
Some(name) => format!("{name} ({expires})"),
|
||||
None => format!("{expires}"),
|
||||
},
|
||||
true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
use gtk::{gio::ListStore, DropDown, Label};
|
||||
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||
mod item;
|
||||
use item::Item;
|
||||
|
||||
use gio::prelude::{Cast, CastNone};
|
||||
use gtk::{gio::ListStore, prelude::ListItemExt, DropDown, Label, ListItem, SignalListItemFactory};
|
||||
|
||||
pub struct List {
|
||||
pub gobject: DropDown,
|
||||
model: ListStore,
|
||||
index: Rc<RefCell<HashMap<Label, Option<i64>>>>,
|
||||
}
|
||||
|
||||
impl List {
|
||||
@ -12,31 +14,40 @@ impl List {
|
||||
|
||||
/// Create new `Self`
|
||||
pub fn new() -> Self {
|
||||
let index = Rc::new(RefCell::new(HashMap::new()));
|
||||
let model = ListStore::new::<Label>();
|
||||
let gobject = DropDown::builder().model(&model).build();
|
||||
// Init model with custom `GObject` properties
|
||||
let model = ListStore::new::<Item>();
|
||||
|
||||
Self {
|
||||
model,
|
||||
index,
|
||||
gobject,
|
||||
}
|
||||
// Setup item factory to append items after `DropDown` init
|
||||
let factory = SignalListItemFactory::new();
|
||||
|
||||
// @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
|
||||
|
||||
/// 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) {
|
||||
// Create new label for item
|
||||
let item = Label::new(Some(label));
|
||||
|
||||
// Append formatted record
|
||||
self.model.append(&item);
|
||||
|
||||
// Register ID in hash map index
|
||||
self.index
|
||||
.borrow_mut()
|
||||
.insert(item, profile_identity_gemini_id);
|
||||
pub fn append(&self, profile_identity_gemini_id: Option<i64>, label: &str, is_enabled: bool) {
|
||||
self.model
|
||||
.append(&Item::new(profile_identity_gemini_id, label, is_enabled));
|
||||
}
|
||||
|
||||
// Events
|
||||
@ -44,9 +55,13 @@ impl List {
|
||||
/// Run callback function on `connect_selected_notify` event
|
||||
/// * return formatted `profile_identity_gemini_id` match selected
|
||||
pub fn connect_selected_notify(&self, callback: impl Fn(Option<i64>) + 'static) {
|
||||
self.gobject.connect_selected_notify({
|
||||
let index = self.index.clone();
|
||||
move |list| callback(*index.borrow().get(&list.selected_item().unwrap()).unwrap())
|
||||
self.gobject.connect_selected_notify(move |list| {
|
||||
callback(
|
||||
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