Skip to content

Instantly share code, notes, and snippets.

@pawarherschel
Last active November 28, 2023 10:37
Show Gist options
  • Save pawarherschel/9b9b823c56259a0b8e945e8d4330283b to your computer and use it in GitHub Desktop.
Save pawarherschel/9b9b823c56259a0b8e945e8d4330283b to your computer and use it in GitHub Desktop.
use makepad_widgets::KeyCode::ReturnKey;
use makepad_widgets::*;
#[derive(Live)]
pub struct App {
#[live]
ui: WidgetRef,
#[rust]
input: Option<String>,
#[rust]
todo_id: u64,
#[rust]
todos: Vec<TodoItem>,
}
#[derive(Debug, Clone)]
struct TodoItem {
id: u64,
text: String,
draw: bool,
}
impl PartialEq for TodoItem {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl LiveHook for App {
fn before_live_design(cx: &mut Cx) {
makepad_widgets::live_design(cx);
}
}
impl AppMain for App {
fn handle_event(&mut self, cx: &mut Cx, event: &Event) {
let todo_list = self.ui.portal_list_set(ids!(todos));
if let Event::Draw(draw_event) = event {
let cx = &mut Cx2d::new(cx, draw_event);
let mut counter = -1;
while let Some(next) = self.ui.draw_widget(cx).hook_widget() {
println!();
println!("list len: {}", self.todos.len());
if let Some(mut list) = todo_list.has_widget(&next).borrow_mut() {
list.set_item_range(cx, 0, self.todos.len() as u64);
while let Some(item_id) = list.next_visible_item(cx) {
let (template, draw) =
if let Some(TodoItem { draw: true, .. }) = self.get(item_id) {
(live_id!(Todo), true)
} else {
println!("skipping {}: {:?}", item_id, self.get(item_id));
(live_id!(Empty), false)
};
counter += 1;
println!("{:?}", (counter, template, draw));
if draw {
let todo_item = self.get(item_id).unwrap();
assert!(todo_item.draw);
if let Some(widget_ref) = list.item(cx, item_id, template) {
widget_ref
.label(id!(text))
.set_text(todo_item.text.as_str());
widget_ref
.button(id!(delete))
.set_text(format!("Delete {}", todo_item.id).as_str());
widget_ref.draw_widget_all(cx);
};
} else {
if let Some(widget_ref) = list.item(cx, item_id, template) {}
}
}
}
}
return self.ui.draw_widget_all(cx);
}
let actions = self.ui.handle_widget_event(cx, event);
if let Some(new_text) = self.ui.text_input(id!(todo_input)).changed(&actions) {
if new_text.is_empty() {
self.input = None;
} else {
self.input = Some(new_text);
}
}
if let Event::KeyUp(KeyEvent {
key_code: ReturnKey,
..
}) = event
{
if self.input.is_some() {
self.push(self.input.clone().unwrap(), cx);
}
}
for (item_id, item) in todo_list.items_with_actions(&actions) {
if item.button(id!(delete)).clicked(&actions) {
let button = item.button(id!(delete));
let id = button.text().split_once(' ').unwrap().1.parse().unwrap();
self.remove(id);
item.redraw(cx)
}
}
}
}
impl App {
fn push(&mut self, text: String, cx: &mut Cx) {
let new_todo = TodoItem {
id: self.todo_id,
text: text.clone(),
draw: true,
};
self.todos.push(new_todo.clone());
self.input = None;
self.ui
.label(id!(todo_input))
.set_text_and_redraw(cx, &"Add a new task...");
self.todo_id += 1;
println!("PUSHED! new len: {}", self.todos.len());
}
fn get(&self, id: u64) -> Option<TodoItem> {
self.todos.get(id as usize).cloned()
}
fn remove(&mut self, id: u64) {
self.todos = Iterator::collect(self.todos.iter().filter(|it| it.id != id).cloned());
}
}
live_design! {
import makepad_widgets::base::*;
import makepad_widgets::theme_desktop_dark::*;
Todo = <View> {
width: Fit,
height: Fit,
flow: Down,
body = <View> {
width: Fit,
height: Fit
flow: Right,
padding: 10.0,
spacing: 10.0
text = <Label> {
draw_text: {
color: #90c0a0ff
},
text: "replace me!"
}
delete = <Button> {
padding: 10.0,
text: "Delete id",
}
}
}
Empty = <View> {}
App = {{App}} {
ui: <Window> {
show_bg: true,
height: Fill,
width: Fill,
draw_bg: {
fn pixel(self) -> vec4 {
return #6f577eff;
}
}
body = <View> {
flow: Down,
spacing: 20,
align: { x: 0.5, y: 0.1 },
label = <Label> {
draw_text: {
color: #90c0a0ff
},
text: "Hello, world!"
}
todo_input = <TextInput> {
text: "Add a new task..."
}
todos = <PortalList> {
height: Fill,
width: Fill,
flow: Down,
align: {
x: 0.5
}
Todo = <Todo> {}
Empty = <Empty> {}
}
label1 = <Label> {
draw_text: {
color: #90c0a0ff
},
text: "Hello, world!"
}
}
}
}
}
app_main!(App);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment