From ce76f870fd09edb1dd05ddba399c599c210b2d34 Mon Sep 17 00:00:00 2001 From: JoeZane Date: Sun, 20 Apr 2025 00:33:17 +0800 Subject: [PATCH 1/7] add: complete `remove chidlren` function in split_pane --- tmui/src/split_pane.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tmui/src/split_pane.rs b/tmui/src/split_pane.rs index 6b9ae27..e1bbec5 100644 --- a/tmui/src/split_pane.rs +++ b/tmui/src/split_pane.rs @@ -82,8 +82,15 @@ impl ContainerImplExt for SplitPane { self.update(); } - fn remove_children(&mut self, _id: ObjectId) { - // TODO + fn remove_children(&mut self, id: ObjectId) { + if let Some(index) = self.container.children.iter().position(|w| w.id() == id) { + let removed = self.container.children.remove(index); + self.close_pane(removed.id()); + + let window = ApplicationWindow::window(); + window._add_removed_widget(removed); + window.layout_change(self); + } } } From 4944dc9ed91d625a75ef26d3d51cda857c6b446c Mon Sep 17 00:00:00 2001 From: JoeZane Date: Sun, 20 Apr 2025 01:54:12 +0800 Subject: [PATCH 2/7] upd: Add unified pointer prototype. --- tmui/src/application_window.rs | 4 +- tmui/src/prelude.rs | 1 + tmui/src/primitive/mod.rs | 3 +- tmui/src/primitive/obj/alloc.rs | 37 ++++++++++++++++++ tmui/src/primitive/obj/dyn_tr.rs | 59 +++++++++++++++++++++++++++++ tmui/src/primitive/obj/mod.rs | 7 ++++ tmui/src/primitive/obj/tr.rs | 65 ++++++++++++++++++++++++++++++++ 7 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 tmui/src/primitive/obj/alloc.rs create mode 100644 tmui/src/primitive/obj/dyn_tr.rs create mode 100644 tmui/src/primitive/obj/mod.rs create mode 100644 tmui/src/primitive/obj/tr.rs diff --git a/tmui/src/application_window.rs b/tmui/src/application_window.rs index c787906..a5ebf0c 100644 --- a/tmui/src/application_window.rs +++ b/tmui/src/application_window.rs @@ -11,7 +11,7 @@ use crate::{ loading::LoadingMgr, platform::{ipc_bridge::IpcBridge, PlatformType}, prelude::*, - primitive::{global_watch::GlobalWatchEvent, Message}, + primitive::{global_watch::GlobalWatchEvent, obj::TrAllocater, Message}, runtime::{wed, window_context::OutputSender}, shortcut::mgr::ShortcutMgr, tooltip::TooltipStrat, @@ -772,6 +772,8 @@ impl ApplicationWindow { FocusMgr::with(|mgr| mgr.borrow_mut().remove(id)); ShortcutMgr::with(|mgr| mgr.borrow_mut().remove_shortcut_all(id)); CloseHandlerMgr::remove(id); + + TrAllocater::remove(id); } } diff --git a/tmui/src/prelude.rs b/tmui/src/prelude.rs index 131e686..6570c35 100644 --- a/tmui/src/prelude.rs +++ b/tmui/src/prelude.rs @@ -49,6 +49,7 @@ pub use crate::primitive::close_handler::{ pub use crate::primitive::global_watch::{ GlobalWatch, GlobalWatchEvent, GlobalWatchImpl, ReflectGlobalWatch, }; +pub use crate::primitive::obj::*; pub use crate::scroll_area::{ LayoutMode, ReflectScrollAreaExt, ScrollArea, ScrollAreaExt, ScrollAreaGenericExt, ScrollAreaSlots, diff --git a/tmui/src/primitive/mod.rs b/tmui/src/primitive/mod.rs index 871b1c2..b590c1b 100644 --- a/tmui/src/primitive/mod.rs +++ b/tmui/src/primitive/mod.rs @@ -3,8 +3,9 @@ pub mod close_handler; pub mod cpu_balance; pub mod frame; pub mod global_watch; +pub mod obj; pub(crate) mod message; pub(crate) mod shared_channel; -pub(crate) use message::*; \ No newline at end of file +pub(crate) use message::*; diff --git a/tmui/src/primitive/obj/alloc.rs b/tmui/src/primitive/obj/alloc.rs new file mode 100644 index 0000000..72eaf25 --- /dev/null +++ b/tmui/src/primitive/obj/alloc.rs @@ -0,0 +1,37 @@ +use super::Tr; +use crate::widget::WidgetImpl; +use nohash_hasher::IntMap; +use std::cell::RefCell; +use tlib::{ + object::{ObjectId, ObjectSubclass}, + Object, +}; + +thread_local! { + static OWNER_STORAGE: RefCell>> = RefCell::new(IntMap::default()); +} + +pub(crate) struct TrAllocater; +impl TrAllocater { + #[inline] + pub(crate) fn insert(owner: Box) { + OWNER_STORAGE.with_borrow_mut(|map| map.insert(owner.id(), owner)); + } + + #[inline] + pub(crate) fn remove(id: ObjectId) { + OWNER_STORAGE.with_borrow_mut(|map| map.remove(&id)); + } +} + +pub trait TrAlloc { + #[inline] + fn new_alloc() -> Tr { + let mut obj: Box = Object::new(&[]); + let tr = Tr::from_raw(obj.as_mut()); + TrAllocater::insert(obj); + tr + } +} + +impl TrAlloc for T {} diff --git a/tmui/src/primitive/obj/dyn_tr.rs b/tmui/src/primitive/obj/dyn_tr.rs new file mode 100644 index 0000000..edd009e --- /dev/null +++ b/tmui/src/primitive/obj/dyn_tr.rs @@ -0,0 +1,59 @@ +use super::Tr; +use crate::widget::WidgetImpl; +use std::ops::{Deref, DerefMut}; + +#[repr(transparent)] +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub struct DynTr { + raw: *mut dyn WidgetImpl, +} + +impl DynTr { + /// # SAFETY + /// + /// The raw pointer becomes invalid when the widget is removed. + #[inline] + pub fn bind(&self) -> &dyn WidgetImpl { + unsafe { + self.raw + .as_ref() + .expect("Fatal error, try to access the removed reference.") + } + } + + /// # SAFETY + /// + /// The raw pointer becomes invalid when the widget is removed. + #[inline] + pub fn bind_mut(&mut self) -> &mut dyn WidgetImpl { + unsafe { + self.raw + .as_mut() + .expect("Fatal error, try to access the removed reference.") + } + } +} + +impl From> for DynTr { + fn from(mut value: Tr) -> Self { + let dyn_mut = value.as_dyn_mut(); + + Self { raw: dyn_mut } + } +} + +impl Deref for DynTr { + type Target = dyn WidgetImpl; + + #[inline] + fn deref(&self) -> &Self::Target { + self.bind() + } +} + +impl DerefMut for DynTr { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + self.bind_mut() + } +} diff --git a/tmui/src/primitive/obj/mod.rs b/tmui/src/primitive/obj/mod.rs new file mode 100644 index 0000000..752fead --- /dev/null +++ b/tmui/src/primitive/obj/mod.rs @@ -0,0 +1,7 @@ +pub mod alloc; +pub mod dyn_tr; +pub mod tr; + +pub use alloc::*; +pub use dyn_tr::*; +pub use tr::*; diff --git a/tmui/src/primitive/obj/tr.rs b/tmui/src/primitive/obj/tr.rs new file mode 100644 index 0000000..0738920 --- /dev/null +++ b/tmui/src/primitive/obj/tr.rs @@ -0,0 +1,65 @@ +use crate::widget::WidgetImpl; +use std::ops::{Deref, DerefMut}; + +#[repr(transparent)] +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub struct Tr { + raw: *mut R, +} + +impl Tr { + #[inline] + pub(crate) fn from_raw(raw: *mut R) -> Tr { + Tr { raw } + } + + /// # SAFETY + /// + /// The raw pointer becomes invalid when the widget is removed. + #[inline] + pub fn bind(&self) -> &R { + unsafe { + self.raw + .as_ref() + .expect("Fatal error, try to access the removed reference.") + } + } + + /// # SAFETY + /// + /// The raw pointer becomes invalid when the widget is removed. + #[inline] + pub fn bind_mut(&mut self) -> &mut R { + unsafe { + self.raw + .as_mut() + .expect("Fatal error, try to access the removed reference.") + } + } + + #[inline] + pub fn as_dyn(&self) -> &dyn WidgetImpl { + self.bind() as &dyn WidgetImpl + } + + #[inline] + pub fn as_dyn_mut(&mut self) -> &mut dyn WidgetImpl { + self.bind_mut() as &mut dyn WidgetImpl + } +} + +impl Deref for Tr { + type Target = R; + + #[inline] + fn deref(&self) -> &Self::Target { + self.bind() + } +} + +impl DerefMut for Tr { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + self.bind_mut() + } +} From 28e4adc33a96d2df6d4e93cc809a7de5bad74c2a Mon Sep 17 00:00:00 2001 From: JoeZane Date: Sun, 20 Apr 2025 18:46:39 +0800 Subject: [PATCH 3/7] upd: Add `ref_count` to `Tr`, `DynTr` --- tmui/src/application_window.rs | 4 +- tmui/src/primitive/obj/alloc.rs | 2 +- tmui/src/primitive/obj/dyn_tr.rs | 52 ++++++++++++++++++++---- tmui/src/primitive/obj/tr.rs | 69 +++++++++++++++++++++++++++++--- tmui/src/widget/widget_inner.rs | 13 +++--- 5 files changed, 114 insertions(+), 26 deletions(-) diff --git a/tmui/src/application_window.rs b/tmui/src/application_window.rs index a5ebf0c..c787906 100644 --- a/tmui/src/application_window.rs +++ b/tmui/src/application_window.rs @@ -11,7 +11,7 @@ use crate::{ loading::LoadingMgr, platform::{ipc_bridge::IpcBridge, PlatformType}, prelude::*, - primitive::{global_watch::GlobalWatchEvent, obj::TrAllocater, Message}, + primitive::{global_watch::GlobalWatchEvent, Message}, runtime::{wed, window_context::OutputSender}, shortcut::mgr::ShortcutMgr, tooltip::TooltipStrat, @@ -772,8 +772,6 @@ impl ApplicationWindow { FocusMgr::with(|mgr| mgr.borrow_mut().remove(id)); ShortcutMgr::with(|mgr| mgr.borrow_mut().remove_shortcut_all(id)); CloseHandlerMgr::remove(id); - - TrAllocater::remove(id); } } diff --git a/tmui/src/primitive/obj/alloc.rs b/tmui/src/primitive/obj/alloc.rs index 72eaf25..443ac7b 100644 --- a/tmui/src/primitive/obj/alloc.rs +++ b/tmui/src/primitive/obj/alloc.rs @@ -11,7 +11,7 @@ thread_local! { static OWNER_STORAGE: RefCell>> = RefCell::new(IntMap::default()); } -pub(crate) struct TrAllocater; +pub(crate) struct TrAllocater {} impl TrAllocater { #[inline] pub(crate) fn insert(owner: Box) { diff --git a/tmui/src/primitive/obj/dyn_tr.rs b/tmui/src/primitive/obj/dyn_tr.rs index edd009e..98c4378 100644 --- a/tmui/src/primitive/obj/dyn_tr.rs +++ b/tmui/src/primitive/obj/dyn_tr.rs @@ -1,17 +1,21 @@ -use super::Tr; +use super::{Tr, TrAllocater}; use crate::widget::WidgetImpl; -use std::ops::{Deref, DerefMut}; +use std::{ + cell::Cell, + ops::{Deref, DerefMut}, + rc::Rc, +}; -#[repr(transparent)] -#[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[derive(Debug, PartialEq, Eq)] pub struct DynTr { raw: *mut dyn WidgetImpl, + ref_count: Rc>, } impl DynTr { /// # SAFETY /// - /// The raw pointer becomes invalid when the widget is removed. + /// Destruction of the underlying object is managed by reference counting, and exceptions should never occur. #[inline] pub fn bind(&self) -> &dyn WidgetImpl { unsafe { @@ -23,7 +27,7 @@ impl DynTr { /// # SAFETY /// - /// The raw pointer becomes invalid when the widget is removed. + /// Destruction of the underlying object is managed by reference counting, and exceptions should never occur. #[inline] pub fn bind_mut(&mut self) -> &mut dyn WidgetImpl { unsafe { @@ -35,10 +39,42 @@ impl DynTr { } impl From> for DynTr { + #[inline] fn from(mut value: Tr) -> Self { - let dyn_mut = value.as_dyn_mut(); + let ref_count = value.clone_ref_count(); + ref_count.set(ref_count.get() + 1); + + Self { + raw: value.as_dyn_mut(), + ref_count, + } + } +} + +impl Clone for DynTr { + #[inline] + fn clone(&self) -> Self { + let ref_count = self.ref_count.clone(); + ref_count.set(ref_count.get() + 1); - Self { raw: dyn_mut } + Self { + raw: self.raw, + ref_count, + } + } +} + +impl Drop for DynTr { + #[inline] + fn drop(&mut self) { + self.ref_count.set(self.ref_count.get() - 1); + + let ref_cnt = self.ref_count.get(); + debug_assert!(ref_cnt >= 0); + + if ref_cnt == 0 { + TrAllocater::remove(self.id()); + } } } diff --git a/tmui/src/primitive/obj/tr.rs b/tmui/src/primitive/obj/tr.rs index 0738920..089b15d 100644 --- a/tmui/src/primitive/obj/tr.rs +++ b/tmui/src/primitive/obj/tr.rs @@ -1,21 +1,34 @@ +use super::TrAllocater; use crate::widget::WidgetImpl; -use std::ops::{Deref, DerefMut}; +use std::{ + cell::Cell, + ops::{Deref, DerefMut}, + rc::Rc, +}; -#[repr(transparent)] -#[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[derive(Debug, PartialEq, Eq)] pub struct Tr { raw: *mut R, + ref_count: Rc>, } impl Tr { #[inline] pub(crate) fn from_raw(raw: *mut R) -> Tr { - Tr { raw } + Tr { + raw, + ref_count: Rc::new(Cell::new(1)), + } + } + + #[inline] + pub(crate) fn clone_ref_count(&self) -> Rc> { + self.ref_count.clone() } /// # SAFETY /// - /// The raw pointer becomes invalid when the widget is removed. + /// Destruction of the underlying object is managed by reference counting, and exceptions should never occur. #[inline] pub fn bind(&self) -> &R { unsafe { @@ -27,7 +40,7 @@ impl Tr { /// # SAFETY /// - /// The raw pointer becomes invalid when the widget is removed. + /// Destruction of the underlying object is managed by reference counting, and exceptions should never occur. #[inline] pub fn bind_mut(&mut self) -> &mut R { unsafe { @@ -48,6 +61,33 @@ impl Tr { } } +impl Clone for Tr { + #[inline] + fn clone(&self) -> Self { + let ref_count = self.ref_count.clone(); + ref_count.set(ref_count.get() + 1); + + Self { + raw: self.raw, + ref_count, + } + } +} + +impl Drop for Tr { + #[inline] + fn drop(&mut self) { + self.ref_count.set(self.ref_count.get() - 1); + + let ref_cnt = self.ref_count.get(); + debug_assert!(ref_cnt >= 0); + + if ref_cnt == 0 { + TrAllocater::remove(self.id()); + } + } +} + impl Deref for Tr { type Target = R; @@ -63,3 +103,20 @@ impl DerefMut for Tr { self.bind_mut() } } + +#[cfg(test)] +mod tests { + use crate::{ + prelude::{DynTr, TrAlloc}, + widget::Widget, + }; + + #[test] + fn test_tr() { + let tr = Widget::new_alloc(); + { + let dyn_tr: DynTr = tr.clone().into(); + let _ = dyn_tr.clone(); + } + } +} diff --git a/tmui/src/widget/widget_inner.rs b/tmui/src/widget/widget_inner.rs index 4673c3d..b61200f 100644 --- a/tmui/src/widget/widget_inner.rs +++ b/tmui/src/widget/widget_inner.rs @@ -264,20 +264,17 @@ macro_rules! widget_inner_ext_impl { fn set_redraw_shadow_box(&mut self, redraw: bool) { self.widget_props_mut().redraw_shadow_box = redraw } + + #[inline] + fn set_in_tree(&mut self) { + self.widget_props_mut().in_tree = true; + } }; } impl WidgetInnerExt for T { widget_inner_ext_impl!(); - - fn set_in_tree(&mut self) { - self.widget_props_mut().in_tree = true; - } } impl WidgetInnerExt for dyn WidgetImpl { widget_inner_ext_impl!(); - - fn set_in_tree(&mut self) { - self.widget_props_mut().in_tree = true; - } } From 36bf14517d70b49858065209bd94416f2df3bab2 Mon Sep 17 00:00:00 2001 From: JoeZane Date: Sun, 20 Apr 2025 20:31:44 +0800 Subject: [PATCH 4/7] upd: refactor tr alloc --- tmui/src/primitive/obj/alloc.rs | 76 +++++++++++++++++++++++++++++--- tmui/src/primitive/obj/dyn_tr.rs | 10 +++++ tmui/src/primitive/obj/tr.rs | 29 +++++------- 3 files changed, 90 insertions(+), 25 deletions(-) diff --git a/tmui/src/primitive/obj/alloc.rs b/tmui/src/primitive/obj/alloc.rs index 443ac7b..fe68973 100644 --- a/tmui/src/primitive/obj/alloc.rs +++ b/tmui/src/primitive/obj/alloc.rs @@ -1,21 +1,27 @@ use super::Tr; +use crate::prelude::*; use crate::widget::WidgetImpl; use nohash_hasher::IntMap; -use std::cell::RefCell; +use std::{ + cell::{Cell, RefCell}, + rc::Rc, +}; use tlib::{ object::{ObjectId, ObjectSubclass}, Object, }; +type OwnerMap = IntMap, Rc>)>; + thread_local! { - static OWNER_STORAGE: RefCell>> = RefCell::new(IntMap::default()); + static OWNER_STORAGE: RefCell = RefCell::new(IntMap::default()); } pub(crate) struct TrAllocater {} impl TrAllocater { #[inline] - pub(crate) fn insert(owner: Box) { - OWNER_STORAGE.with_borrow_mut(|map| map.insert(owner.id(), owner)); + pub(crate) fn insert(owner: Box, ref_count: Rc>) { + OWNER_STORAGE.with_borrow_mut(|map| map.insert(owner.id(), (owner, ref_count))); } #[inline] @@ -24,14 +30,70 @@ impl TrAllocater { } } -pub trait TrAlloc { +pub trait TrAlloc: ObjectOperation { #[inline] fn new_alloc() -> Tr { let mut obj: Box = Object::new(&[]); let tr = Tr::from_raw(obj.as_mut()); - TrAllocater::insert(obj); + let ref_count = tr.clone_ref_count(); + TrAllocater::insert(obj, ref_count); tr } -} + #[inline] + fn to_tr(&self) -> Tr { + let id = self.id(); + OWNER_STORAGE.with_borrow_mut(|map| { + if let Some((widget, ref_count)) = map.get_mut(&id) { + Tr::new_directly(widget.downcast_mut::().unwrap(), ref_count.clone()) + } else { + panic!("The widget is not managed internally by `tmui`.") + } + }) + } + + #[inline] + fn to_dyn_tr(&self) -> DynTr { + let id = self.id(); + OWNER_STORAGE.with_borrow_mut(|map| { + if let Some((widget, ref_count)) = map.get_mut(&id) { + DynTr::new_directly(widget.as_mut(), ref_count.clone()) + } else { + panic!("The widget is not managed internally by `tmui`.") + } + }) + } +} impl TrAlloc for T {} + +pub trait DynTrAlloc: WidgetImpl { + #[inline] + fn to_tr(&self) -> DynTr { + let id = self.id(); + OWNER_STORAGE.with_borrow_mut(|map| { + if let Some((widget, ref_count)) = map.get_mut(&id) { + DynTr::new_directly(widget.as_mut(), ref_count.clone()) + } else { + panic!("The widget is not managed internally by `tmui`.") + } + }) + } +} +impl DynTrAlloc for dyn WidgetImpl {} + +#[cfg(test)] +mod tests { + use crate::{ + prelude::{DynTr, TrAlloc}, + widget::Widget, + }; + + #[test] + fn test_tr() { + let tr = Widget::new_alloc(); + { + let dyn_tr: DynTr = tr.clone().into(); + let _ = dyn_tr.clone(); + } + } +} diff --git a/tmui/src/primitive/obj/dyn_tr.rs b/tmui/src/primitive/obj/dyn_tr.rs index 98c4378..3495152 100644 --- a/tmui/src/primitive/obj/dyn_tr.rs +++ b/tmui/src/primitive/obj/dyn_tr.rs @@ -13,6 +13,11 @@ pub struct DynTr { } impl DynTr { + #[inline] + pub(crate) fn new_directly(raw: *mut dyn WidgetImpl, ref_count: Rc>) -> Self { + Self { raw, ref_count } + } + /// # SAFETY /// /// Destruction of the underlying object is managed by reference counting, and exceptions should never occur. @@ -36,6 +41,11 @@ impl DynTr { .expect("Fatal error, try to access the removed reference.") } } + + #[inline] + pub fn get_ref_count(&self) -> usize { + self.ref_count.get() as usize + } } impl From> for DynTr { diff --git a/tmui/src/primitive/obj/tr.rs b/tmui/src/primitive/obj/tr.rs index 089b15d..0667981 100644 --- a/tmui/src/primitive/obj/tr.rs +++ b/tmui/src/primitive/obj/tr.rs @@ -15,12 +15,17 @@ pub struct Tr { impl Tr { #[inline] pub(crate) fn from_raw(raw: *mut R) -> Tr { - Tr { + Self { raw, ref_count: Rc::new(Cell::new(1)), } } + #[inline] + pub(crate) fn new_directly(raw: *mut R, ref_count: Rc>) -> Tr { + Self { raw, ref_count } + } + #[inline] pub(crate) fn clone_ref_count(&self) -> Rc> { self.ref_count.clone() @@ -59,6 +64,11 @@ impl Tr { pub fn as_dyn_mut(&mut self) -> &mut dyn WidgetImpl { self.bind_mut() as &mut dyn WidgetImpl } + + #[inline] + pub fn get_ref_count(&self) -> usize { + self.ref_count.get() as usize + } } impl Clone for Tr { @@ -103,20 +113,3 @@ impl DerefMut for Tr { self.bind_mut() } } - -#[cfg(test)] -mod tests { - use crate::{ - prelude::{DynTr, TrAlloc}, - widget::Widget, - }; - - #[test] - fn test_tr() { - let tr = Widget::new_alloc(); - { - let dyn_tr: DynTr = tr.clone().into(); - let _ = dyn_tr.clone(); - } - } -} From 140571b6561b95abd247b6bc06e39a88cc461de8 Mon Sep 17 00:00:00 2001 From: JoeZane Date: Mon, 21 Apr 2025 02:53:26 +0800 Subject: [PATCH 5/7] upd: all reference change to `Tr`,`DynTr`. --- benchmark/benches/size_probe_benchmark.rs | 4 +- examples/async_task/async_task_widget.rs | 4 +- examples/border/main.rs | 4 +- examples/box_layout/hbox_layout.rs | 6 +- examples/box_layout/vbox_layout.rs | 10 +- examples/box_shadow/main.rs | 2 +- .../child_attr_widget/child_attr_widget.rs | 6 +- examples/complex_layout/ctx_menu.rs | 6 +- .../complex_layout/layouts/central_panel.rs | 6 +- examples/complex_layout/layouts/left_panel.rs | 6 +- .../complex_layout/layouts/right_panel/mod.rs | 4 +- .../layouts/right_panel/split_pane.rs | 4 +- .../layouts/right_panel/stack.rs | 11 +- examples/complex_layout/layouts/title_bar.rs | 8 +- examples/complex_layout/layouts/view.rs | 10 +- .../complex_layout/layouts/win_ctrl_btns.rs | 6 +- .../complex_layout/layouts/workspace_panel.rs | 2 +- examples/custom_diff_handle/my_diff_widget.rs | 4 +- examples/custom_diff_handle/my_split_pane.rs | 6 +- examples/custom_popup/my_box.rs | 8 +- examples/custom_popup/my_widget.rs | 16 +-- examples/custom_popup/popups/rba_popup.rs | 6 +- examples/custom_popup/popups/tba_popup.rs | 6 +- examples/event_bubble/my_widget.rs | 8 +- examples/event_bus/widget.rs | 4 +- examples/icon_list/ctrl_button.rs | 6 +- examples/icon_list/font_icons.rs | 14 +- examples/icon_list/icons.rs | 8 +- examples/icon_list/svg_icons.rs | 17 ++- examples/input_element/holder.rs | 23 ++-- examples/input_element/popup.rs | 6 +- examples/key_event/key_widget.rs | 4 +- examples/layout_widget/layout_widget.rs | 13 +- examples/list_view/list_view_holder.rs | 14 +- examples/mouse_evt/test_widget.rs | 6 +- examples/multi_window/input_dialog.rs | 10 +- examples/multi_window/my_widget.rs | 6 +- examples/multi_window/password_bundle.rs | 8 +- examples/multi_window/text_bundle.rs | 8 +- .../non_strict_clip/non_strict_clip_widget.rs | 4 +- examples/pane_layout/central_pane.rs | 19 +-- examples/pane_layout/pane_layout.rs | 13 +- examples/remove_demo/child_widget.rs | 8 +- examples/remove_demo/remove_widget.rs | 12 +- examples/remove_demo/stack_widget.rs | 4 +- examples/run_after/run_after_layout_widget.rs | 6 +- examples/run_after/run_after_widget.rs | 4 +- .../scroll_area_layout/scroll_area_layout.rs | 4 +- examples/scrolled/main.rs | 3 +- examples/scrolled/scroll_window.rs | 2 +- .../self_adaption_widget.rs | 4 +- .../shared_window_master/shared_widget.rs | 4 +- examples/shared_window_slave/test_widget.rs | 4 +- examples/skia_paint/main.rs | 5 +- examples/split_pane_layout/main.rs | 5 +- examples/tree_view/ctx_menu.rs | 6 +- examples/tree_view/tree_view_holder.rs | 12 +- examples/win_widget/main.rs | 7 +- examples/window/test_widget.rs | 4 +- macros/src/childable.rs | 119 +++++++++++++---- macros/src/extend_container.rs | 57 +++++--- macros/src/extend_widget.rs | 12 +- macros/src/layout.rs | 22 ++-- macros/src/pane.rs | 4 +- macros/src/popupable.rs | 13 +- macros/src/scroll_area.rs | 16 +-- macros/src/split_pane.rs | 23 ++-- macros/src/stack.rs | 4 +- macros/src/win_widget.rs | 8 +- tmui/src/application_window.rs | 60 +++++---- tmui/src/button.rs | 8 +- tmui/src/container.rs | 76 ++--------- tmui/src/graphics/board.rs | 4 +- tmui/src/graphics/element.rs | 43 +++++- tmui/src/hbox.rs | 14 +- tmui/src/icons/font_icon.rs | 10 +- tmui/src/icons/svg_icon.rs | 8 +- tmui/src/icons/svg_toggle_icon.rs | 13 +- tmui/src/image.rs | 4 +- tmui/src/input/dialog.rs | 16 +-- tmui/src/input/number.rs | 4 +- tmui/src/input/password.rs | 4 +- tmui/src/input/radio.rs | 8 +- tmui/src/input/select/dropdown_list.rs | 11 +- tmui/src/input/select/mod.rs | 30 +++-- tmui/src/input/text.rs | 4 +- tmui/src/label.rs | 11 +- tmui/src/layout.rs | 32 +++-- tmui/src/overlay.rs | 13 +- tmui/src/pane.rs | 14 +- tmui/src/popup.rs | 8 +- tmui/src/primitive/obj/alloc.rs | 33 ++++- tmui/src/primitive/obj/dyn_popup_tr.rs | 122 ++++++++++++++++++ tmui/src/primitive/obj/dyn_tr.rs | 16 +++ tmui/src/primitive/obj/mod.rs | 2 + tmui/src/primitive/obj/tr.rs | 23 +++- tmui/src/scroll_area.rs | 20 +-- tmui/src/scroll_bar.rs | 4 +- tmui/src/split_pane.rs | 22 ++-- tmui/src/stack.rs | 15 +-- tmui/src/tooltip.rs | 8 +- tmui/src/vbox.rs | 14 +- tmui/src/views/list_view/list_view_image.rs | 4 +- tmui/src/views/list_view/mod.rs | 4 +- tmui/src/views/tree_view/mod.rs | 4 +- tmui/src/views/tree_view/tree_view_image.rs | 4 +- tmui/src/widget/mod.rs | 94 ++------------ tmui/src/widget/widget_ext.rs | 48 +------ tmui/tests/container_test.rs | 25 ++-- tmui/tests/layout_extend_test.rs | 6 +- 110 files changed, 865 insertions(+), 706 deletions(-) create mode 100644 tmui/src/primitive/obj/dyn_popup_tr.rs diff --git a/benchmark/benches/size_probe_benchmark.rs b/benchmark/benches/size_probe_benchmark.rs index 04ffe00..37f8008 100644 --- a/benchmark/benches/size_probe_benchmark.rs +++ b/benchmark/benches/size_probe_benchmark.rs @@ -46,7 +46,7 @@ impl ObjectImpl for TestWidget {} impl WidgetImpl for TestWidget {} impl TestWidget { - pub fn new() -> Box { - Object::new(&[]) + pub fn new() -> Tr { + Self::new_alloc() } } diff --git a/examples/async_task/async_task_widget.rs b/examples/async_task/async_task_widget.rs index 90ae928..9addb6c 100644 --- a/examples/async_task/async_task_widget.rs +++ b/examples/async_task/async_task_widget.rs @@ -89,7 +89,7 @@ impl WidgetImpl for AsyncTaskWidget {} impl AsyncTaskWidget { #[inline] - pub fn new() -> Box { - Object::new(&[]) + pub fn new() -> Tr { + Self::new_alloc() } } diff --git a/examples/border/main.rs b/examples/border/main.rs index a8f0915..f250885 100644 --- a/examples/border/main.rs +++ b/examples/border/main.rs @@ -16,8 +16,8 @@ fn main() { fn build_ui(window: &mut ApplicationWindow) { let mut hbox = HBox::new(); - let mut widget1: Box = Object::new(&[]); - let mut widget2: Box = Object::new(&[]); + let mut widget1 = Widget::new_alloc(); + let mut widget2 = Widget::new_alloc(); widget1.set_background(Color::CYAN); widget1.width_request(400); diff --git a/examples/box_layout/hbox_layout.rs b/examples/box_layout/hbox_layout.rs index 60a684e..84528f5 100644 --- a/examples/box_layout/hbox_layout.rs +++ b/examples/box_layout/hbox_layout.rs @@ -6,13 +6,13 @@ use tmui::{label::Label, prelude::*}; #[derive(Childrenable)] pub struct HBoxLayout { #[children] - label_1: Box