Skip to content

Commit

Permalink
Iced app can display the todo items (no checkboxes)
Browse files Browse the repository at this point in the history
  • Loading branch information
matta committed Aug 20, 2024
1 parent ccc4c83 commit 84c0e8a
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 25 deletions.
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions sift-iced/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ version = "0.1.0"
edition = "2021"

[dependencies]
sift-core = { path = "../sift-core" }
sift-persist = { path = "../sift-persist" }
sift-state= { path = "../sift-state" }
anyhow = "1.0.86"

[dependencies.iced]
git = "https://github.com/iced-rs/iced.git"
Expand Down
125 changes: 106 additions & 19 deletions sift-iced/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,120 @@
use iced::widget::{button, column, text, Column};
use iced::{
widget::{center, column, container, keyed_column, row, scrollable, text},
Alignment::Center,
Element,
Length::Fill,
};

#[derive(Default)]
pub struct App {
value: i64,
use sift_persist::MemoryStore;
use sift_state::State;

pub enum App {
Loading,
Loaded(State),
}

#[derive(Debug, Clone)]
#[derive(Debug)]
pub enum Message {
Increment,
Decrement,
Loaded(anyhow::Result<MemoryStore>),
}

impl App {
pub fn new() -> (Self, iced::Task<Message>) {
(
App::Loading,
iced::Task::perform(App::load(), Message::Loaded),
)
}

async fn load() -> anyhow::Result<MemoryStore> {
let path = sift_core::save_name();
MemoryStore::load(&path)
// unwrap();
// let state = State::new(store);

// Ok(Self {
// state: State::new(MemoryStore::load(&path)?),
// })
}

pub fn update(&mut self, message: Message) {
match message {
Message::Increment => {
self.value += 1;
}
Message::Decrement => {
self.value -= 1;
match self {
App::Loading => {
self.update_loading(message);
}
App::Loaded(_) => self.update_loaded(),
}
}

fn update_loading(&mut self, message: Message) {
match message {
Message::Loaded(result) => match result {
Ok(store) => *self = App::Loaded(State::new(store)),
Err(_) => unimplemented!("report error and/or implement default state"),
},
}
}

pub fn view(&self) -> Column<Message> {
column![
button("+").on_press(Message::Increment),
text(self.value),
button("-").on_press(Message::Decrement),
]
fn update_loaded(&mut self) {
todo!()
}

pub fn view(&self) -> Element<Message> {
match self {
App::Loading => self.view_loading(),
App::Loaded(state) => self.view_loaded(state),
}
}

fn view_loading(&self) -> Element<Message> {
center(text("Loading...").width(Fill).align_x(Center).size(50)).into()
}

fn view_loaded(&self, state: &State) -> Element<Message> {
let title = text("todos")
.width(Fill)
.size(100)
.color([0.5, 0.5, 0.5])
.align_x(Center);
let tasks = state.list_tasks_for_display();
let tasks: Element<_> = if tasks.is_empty() {
unimplemented!("implement display of zero tasks; see https://github.com/iced-rs/iced/blob/9b99b932bced46047ec2e18c2b6ec5a6c5b3636f/examples/todos/src/main.rs#L229");
} else {
keyed_column(tasks.iter().map(|task| {
let text = text(task.title().to_string());
let row = row![text];

(task.id(), row.into())
}))
.into()
};

let content = column![title, tasks];
scrollable(container(content).center_x(Fill)).into()
}
}

// impl eframe::App for App {
// fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
// egui::CentralPanel::default().show(ctx, |ui| {
// ui.heading("Todos");

// let tasks = self.state.list_tasks_for_display();
// let height = TextStyle::Body.resolve(ui.style()).size;
// ScrollArea::vertical().show_rows(ui, height, tasks.len(), |ui, row_range| {
// ui.allocate_space(vec2(ui.available_width(), 0.0));
// for (index, task) in tasks.iter().enumerate() {
// if !row_range.contains(&index) {
// continue;
// }
// let checked = task.completed().is_some();
// let mut checkbox_checked = checked;
// ui.checkbox(&mut checkbox_checked, task.title());
// if checkbox_checked != checked {
// self.state.toggle_id(task.id());
// }
// }
// });
// });
// }
// }
2 changes: 1 addition & 1 deletion sift-iced/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use sift_iced::App;

pub fn main() -> iced::Result {
iced::run("A cool counter", App::update, App::view)
iced::application("Sift", App::update, App::view).run_with(App::new)
}
18 changes: 14 additions & 4 deletions sift-persist/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub trait Transaction {
pub trait Store {
fn get_task(&mut self, id: &TaskId) -> anyhow::Result<Task>;

fn list_tasks(&mut self) -> anyhow::Result<Vec<Task>>;
fn list_tasks(&self) -> anyhow::Result<Vec<Task>>;

fn undo(&mut self) -> anyhow::Result<()>;

Expand All @@ -41,7 +41,7 @@ pub trait Store {
}

pub(crate) mod memory {
use std::path::Path;
use std::{fmt, path::Path};

use anyhow::bail;

Expand Down Expand Up @@ -110,7 +110,7 @@ pub(crate) mod memory {
self.order.insert(index, *id);
}

fn list_tasks(&mut self) -> Vec<Task> {
fn list_tasks(&self) -> Vec<Task> {
self.order
.iter()
.map(|id| {
Expand All @@ -130,6 +130,16 @@ pub(crate) mod memory {
redo_stack: Vec<Record>,
}

impl fmt::Debug for MemoryStore {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("MemoryStore")
.field("current", &"Record")
.field("undo_stack", &format_args!("Vec<Record>"))
.field("redo_stack", &format_args!("Vec<Record>"))
.finish()
}
}

struct MemoryTransaction<'a> {
store: &'a mut MemoryStore,
start: Record,
Expand Down Expand Up @@ -240,7 +250,7 @@ pub(crate) mod memory {
self.get_task_impl(id)
}

fn list_tasks(&mut self) -> anyhow::Result<Vec<Task>> {
fn list_tasks(&self) -> anyhow::Result<Vec<Task>> {
let tasks = self.current.list_tasks();
Ok(tasks)
}
Expand Down
2 changes: 1 addition & 1 deletion sift-state/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl State {
)
}

pub fn list_tasks_for_display(&mut self) -> Vec<Task> {
pub fn list_tasks_for_display(&self) -> Vec<Task> {
let today = today();
let mut tasks = self.store.list_tasks().expect("XXX: handle error");
tasks.retain(|task| {
Expand Down

0 comments on commit 84c0e8a

Please sign in to comment.