Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ path = "pane_layout/main.rs"
name = "pane_widget"
path = "pane_widget/main.rs"

[[bin]]
name = "remove_demo"
path = "remove_demo/main.rs"

[[bin]]
name = "run_after"
path = "run_after/main.rs"
Expand Down
16 changes: 16 additions & 0 deletions examples/async_task/async_task_element.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use tlib::object::ObjectSubclass;
use tmui::prelude::*;

#[extends(Element)]
#[async_task(name = "AsyncElement", value = "Vec<i32>")]
pub struct AsyncTaskElement {}

impl ObjectSubclass for AsyncTaskElement {
const NAME: &'static str = "AsyncTaskElement";
}

impl ObjectImpl for AsyncTaskElement {}

impl ElementImpl for AsyncTaskElement {
fn on_renderer(&mut self, _cr: &DrawingContext) {}
}
12 changes: 12 additions & 0 deletions examples/async_task/async_task_object.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use tlib::object::ObjectSubclass;
use tmui::prelude::*;

#[extends(Object)]
#[async_task(name = "AsyncObject", value = "bool")]
pub struct AsyncTaskObject {}

impl ObjectSubclass for AsyncTaskObject {
const NAME: &'static str = "AsyncTaskObject";
}

impl ObjectImpl for AsyncTaskObject {}
48 changes: 43 additions & 5 deletions examples/async_task/async_task_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,34 @@ use tmui::{
widget::WidgetImpl,
};

use crate::{async_task_element::AsyncTaskElement, async_task_object::AsyncTaskObject};

#[extends(Widget)]
#[async_task(name = "AsyncTask", value = "i32")]
#[async_task(name = "AsyncTask2", value = "f32")]
#[async_task(name = "AsyncTask3", value = "()")]
pub struct AsyncTaskWidget {}
pub struct AsyncTaskWidget {
async_object: Box<AsyncTaskObject>,
async_element: Box<AsyncTaskElement>,
}

impl ObjectSubclass for AsyncTaskWidget {
const NAME: &'static str = "AsyncTaskWidget";
}

impl ObjectImpl for AsyncTaskWidget {
fn construct(&mut self) {
self.parent_construct();

fn initialize(&mut self) {
self.async_task(
async {
tokio::time::sleep(Duration::from_secs(1)).await;
println!("{} => async do", thread::current().name().unwrap());
12
},
|_, val| {
println!("{} => then", thread::current().name().unwrap());
println!(
"{} => then, should be last one",
thread::current().name().unwrap()
);
assert_eq!(val, 12)
},
);
Expand All @@ -44,6 +50,38 @@ impl ObjectImpl for AsyncTaskWidget {
);

self.async_task3(async {}, |_, _val| {});

self.async_object.async_object(
async {
println!("{} => async obejct", thread::current().name().unwrap());
true
},
|_, val| {
println!("{} => then obejct", thread::current().name().unwrap());
assert!(val)
},
);

self.async_element.async_element(
async {
println!("{} => async element", thread::current().name().unwrap());
vec![1, 2, 3]
},
|_, val| {
println!("{} => then element", thread::current().name().unwrap());
assert_eq!(val, vec![1, 2, 3])
},
);

async_do!(
{
println!("{} => async_do!", thread::current().name().unwrap());
()
} =>
|| {
println!("{} => then async_do!", thread::current().name().unwrap());
}
)
}
}

Expand Down
2 changes: 2 additions & 0 deletions examples/async_task/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod async_task_element;
mod async_task_object;
mod async_task_widget;

use async_task_widget::AsyncTaskWidget;
Expand Down
48 changes: 48 additions & 0 deletions examples/remove_demo/child_widget.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use tmui::{
prelude::*,
tlib::object::{ObjectImpl, ObjectSubclass},
widget::WidgetImpl,
};

#[extends(Widget)]
pub struct ChildWidget {}

impl ObjectSubclass for ChildWidget {
const NAME: &'static str = "ChildWidget";
}

impl ObjectImpl for ChildWidget {
fn construct(&mut self) {
self.parent_construct();

self.width_request(200);
self.height_request(100);
self.set_background(Color::GREY_LIGHT);

let mut child: Box<Widget> = Object::new(&[]);
child.set_halign(Align::Center);
child.set_valign(Align::Center);
child.set_background(Color::YELLOW);
child.width_request(100);
child.height_request(100);

let mut child_c: Box<Widget> = Object::new(&[]);
child_c.set_halign(Align::Center);
child_c.set_valign(Align::Center);
child_c.set_background(Color::GREEN);
child_c.width_request(50);
child_c.height_request(50);
child.child(child_c);

self.child(child);
}
}

impl WidgetImpl for ChildWidget {}

impl ChildWidget {
#[inline]
pub fn new() -> Box<Self> {
Object::new(&[])
}
}
23 changes: 23 additions & 0 deletions examples/remove_demo/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
pub mod child_widget;
pub mod remove_widget;

use remove_widget::RemoveWidget;
use tmui::{application::Application, application_window::ApplicationWindow, prelude::*};

fn main() {
log4rs::init_file("examples/log4rs.yaml", Default::default()).unwrap();

let app = Application::builder()
.width(1280)
.height(800)
.title("Remove Demo")
.build();

app.connect_activate(build_ui);

app.run();
}

fn build_ui(window: &mut ApplicationWindow) {
window.child(RemoveWidget::new());
}
87 changes: 87 additions & 0 deletions examples/remove_demo/remove_widget.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
use tmui::{
button::Button,
label::Label,
prelude::*,
tlib::object::{ObjectImpl, ObjectSubclass},
widget::WidgetImpl,
};

use crate::child_widget::ChildWidget;

#[extends(Widget, Layout(VBox))]
#[derive(Childrenable)]
pub struct RemoveWidget {
#[children]
top: Box<HBox>,
#[children]
bottom: Box<HBox>,

to_remove: ObjectId,
widget_id: ObjectId,
}

impl ObjectSubclass for RemoveWidget {
const NAME: &'static str = "RemoveWidget";
}

impl ObjectImpl for RemoveWidget {
fn construct(&mut self) {
self.parent_construct();

self.bottom.set_margin_top(5);

self.set_hexpand(true);
self.set_vexpand(true);
let mut button_1 = Button::new(Some("Remove Left"));
let mut button_2 = Button::new(Some("Remove Right"));
button_1.width_request(100);
button_2.width_request(100);
connect!(
button_1,
mouse_pressed(),
self,
remove_left_pressed(MouseEvent)
);
connect!(
button_2,
mouse_pressed(),
self,
remove_right_pressed(MouseEvent)
);
self.top.add_child(button_1);
self.top.add_child(button_2);

self.bottom.add_child(Label::new(Some("Label 1")));
let label2 = Label::new(Some("Label 2"));
self.to_remove = label2.id();
self.bottom.add_child(label2);
self.bottom.add_child(Label::new(Some("Label 3")));
self.bottom.add_child(Label::new(Some("Label 4")));

let child_widget = ChildWidget::new();
self.widget_id = child_widget.id();
self.bottom.add_child(child_widget);
}
}

impl WidgetImpl for RemoveWidget {}

impl RemoveWidget {
#[inline]
pub fn new() -> Box<Self> {
Object::new(&[])
}

pub fn remove_left_pressed(&mut self, _: MouseEvent) {
self.bottom.remove_children(self.to_remove);
}

pub fn remove_right_pressed(&mut self, _: MouseEvent) {
self.window()
.find_id_mut(self.widget_id)
.unwrap()
.downcast_mut::<ChildWidget>()
.unwrap()
.remove_child();
}
}
16 changes: 12 additions & 4 deletions examples/window/test_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,17 @@ use lazy_static::lazy_static;
use log::debug;
use std::time::Duration;
use tlib::{
close_handler, connect, disconnect, object::{ObjectImpl, ObjectSubclass}, timer::Timer
close_handler, connect, disconnect,
object::{ObjectImpl, ObjectSubclass},
timer::Timer,
};
use tmui::{
animation::frame_animator::FrameAnimator,
prelude::*,
primitive::frame::Frame,
tlib::{figure::Color, frame_animator},
widget::WidgetImpl,
};
use tmui::{animation::frame_animator::FrameAnimator, prelude::*, primitive::frame::Frame, tlib::{figure::Color, frame_animator}, widget::WidgetImpl};

lazy_static! {
static ref COLORS: [Color; 3] = [Color::RED, Color::GREEN, Color::BLUE];
Expand Down Expand Up @@ -67,7 +75,7 @@ impl TestWidget {

impl FrameAnimator for TestWidget {
#[inline]
fn on_frame(&mut self, frame: Frame){
fn on_frame(&mut self, frame: Frame) {
println!("widget on frame: {:?}", frame)
}
}
Expand All @@ -76,4 +84,4 @@ impl CloseHandler for TestWidget {
fn handle(&mut self) {
println!("Application has closed.");
}
}
}
28 changes: 12 additions & 16 deletions macros/src/async_task.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use std::str::FromStr;
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::{
Attribute, DeriveInput, Meta, MetaList, MetaNameValue, NestedMeta,
};
use std::str::FromStr;
use syn::{Attribute, DeriveInput, Meta, MetaList, MetaNameValue, NestedMeta};

use crate::SplitGenericsRef;

Expand Down Expand Up @@ -32,9 +30,7 @@ impl<'a> AsyncTask<'a> {
for meta in nested {
match meta {
NestedMeta::Meta(Meta::NameValue(MetaNameValue {
ref path,
ref lit,
..
ref path, ref lit, ..
})) => {
let ident = path.get_ident().unwrap();

Expand All @@ -57,8 +53,10 @@ impl<'a> AsyncTask<'a> {
},
"value" => match lit {
syn::Lit::Str(lit) => {
let token = TokenStream::from_str(&lit.value()).expect("`async_task` value parse error.");
let ty = syn::parse2::<syn::Type>(token).expect("`async_task` value parse error.");
let token = TokenStream::from_str(&lit.value())
.expect("`async_task` value parse error.");
let ty = syn::parse2::<syn::Type>(token)
.expect("`async_task` value parse error.");
res.value = Some(ty)
}
_ => return None,
Expand Down Expand Up @@ -142,12 +140,10 @@ impl<'a> AsyncTask<'a> {
}
))
}
_ => {
Err(syn::Error::new_spanned(
ast,
"`async_task` should defined on struct.",
))
}
_ => Err(syn::Error::new_spanned(
ast,
"`async_task` should defined on struct.",
)),
}
}

Expand All @@ -166,7 +162,7 @@ impl<'a> AsyncTask<'a> {
let (_, ty_generics, _) = self.generics;

Ok(quote!(
fn #name_snake<_F, _T>(&mut self, future: _F, then: _T)
pub fn #name_snake<_F, _T>(&mut self, future: _F, then: _T)
where
_F: std::future::Future<Output = #value> + Send + 'static,
_T: FnOnce(&'static mut #widget #ty_generics, #value) + 'static,
Expand Down
Loading