Skip to content

Commit

Permalink
subtask cont'd & redraw optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
Deezzir committed Feb 10, 2023
1 parent ffe3b88 commit dc697d9
Show file tree
Hide file tree
Showing 7 changed files with 244 additions and 145 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ edition = "2021"
regex = "1.3.9"
chrono = "0.4.23"
ncurses = { version = "5.101.0", features = ["wide"] }
libc = "0.2.139"
libc = "0.2.97"
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ cargo run
|-----------------------------------------------------|--------------------------------------|
| <kbd>k/↑</kbd>,<kbd>j/↓</kbd> | Move UP/DOWN |
| <kbd>SHIFT+k</kbd>,<kbd>SHIFT+j</kbd> | Drag item UP/DOWN |
| <kbd>g</kbd>,<kbd>G</kbd> | Jump to START/END of the list |
| <kbd>g</kbd>,<kbd>G</kbd>,<kbd>h</kbd> | Jump to START/END/HALF of the list |
| <kbd>d</kbd> | Delete 'Done' item |
| <kbd>i</kbd> | Insert a new 'Todo' item |
| <kbd>a</kbd> | Add subtask to current 'Todo' item |
Expand Down
1 change: 1 addition & 0 deletions TODO.list
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ TODO(): Finish a Rust TODO app
TODO(): deleting
TODO(): unmarking
TODO(): Fix autoresizing
TODO(): cut text if its going out of bounds
TODO(): optimize redraw
TODO(): clear before adding child
TODO(): Finish a Game of Life with Rust with GUI
Expand Down
213 changes: 119 additions & 94 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ use mods::todo::*;
use mods::ui::*;
use mods::utils::*;

const TIMEOUT: i32 = 1000; // 1 second
const FPS: i32 = 30; // 30 frames per second

const SELECTED_PAIR: i16 = 1;
const UNSELECTED_PAIR: i16 = 2;
const HIGHLIGHT_PAIR: i16 = 3;
Expand All @@ -26,13 +29,15 @@ Author: Iurii Kondrakov <[email protected]>
Controls:
<k/up>, <j/down> ~ Move the cursor up
<K>, <J> ~ Drag item UP/DOWN
<g>, <G> ~ Go to the top/bottom of the list
<d> ~ Delete 'Done' element
<i> ~ Insert a new 'Todo' element
<a> ~ Add a subtask to the current 'Todo' element
<g>, <G>, <h> ~ Jump to the top/bottom/half of the list
<d> ~ Delete 'Done' item
<i> ~ Insert a new 'Todo' item
<a> ~ Add a subtask to the current 'Todo' item
<u> ~ Undo last action
<r> ~ Edit current item
<enter> ~ Transfer current elemen/Save edited element
<t> ~ Hide subtasks
<H> ~ Show help
<enter> ~ Transfer current item/Save edited item
<esc> ~ Cancel editing
<tab> ~ Switch between Switch between 'Todos'/'Dones'
<q>, <ctrl-c> ~ Quit
Expand All @@ -46,6 +51,13 @@ enum Mode {
Normal,
}

#[allow(dead_code)]
enum Display {
All(Mode),
Hide(Mode),
Help,
}

fn main() {
sig_handler_init();

Expand All @@ -58,121 +70,127 @@ fn main() {
.to_string();

ncurses_init();
let mut mode: Mode = Mode::Normal;

let mut editing_cursor: usize = 0;
let mut term_size = Vec2::new(0, 0);
let mut timeout = 0;

let mut mode: Mode = Mode::Normal;
let mut app: TodoApp = TodoApp::new();
let mut ui = UI::new();

app.parse(&file_path);
while !poll() {
erase();
let date = Local::now().format("%Y %a %b %d %H:%M:%S");
let mut w = 0;
let mut h = 0;
getmaxyx(stdscr(), &mut h, &mut w);

ui.begin(Vec2::new(0, 0), LayoutKind::Vert, Vec2::new(w, h));
{
ui.begin_layout(LayoutKind::Horz);
getmaxyx(stdscr(), &mut term_size.y, &mut term_size.x);

if timeout <= 0 {
erase();
let date = Local::now().format("%Y %a %b %d %H:%M:%S");

ui.begin(Vec2::new(0, 0), LayoutKind::Vert, term_size);
{
ui.begin_layout(LayoutKind::Vert);
ui.begin_layout(LayoutKind::Horz);
{
ui.label_styled(
&format!(
"[CONTENT]: ({})todos and ({})dones",
app.get_todos_n(),
app.get_dones_n()
),
UI_PAIR,
Some(A_BOLD()),
);
ui.label_styled(
&format!("[MESSAGE]: {}", app.get_message()),
UI_PAIR,
Some(A_BOLD()),
);
}
ui.end_layout();
ui.begin_layout(LayoutKind::Vert);
{
ui.label_styled(
&format!(
"[CONTENT]: ({})todos and ({})dones",
app.get_todos_n(),
app.get_dones_n()
),
UI_PAIR,
Some(A_BOLD()),
);
ui.label_styled(
&format!("[MESSAGE]: {}", app.get_message()),
UI_PAIR,
Some(A_BOLD()),
);
}
ui.end_layout();

ui.begin_layout(LayoutKind::Vert);
{
ui.label_styled(&format!("[DATE]: {date}"), UI_PAIR, Some(A_BOLD()));
ui.label_styled(&format!("[FILE]: {file_name}"), UI_PAIR, Some(A_BOLD()));
ui.begin_layout(LayoutKind::Vert);
{
ui.label_styled(&format!("[DATE]: {date}"), UI_PAIR, Some(A_BOLD()));
ui.label_styled(&format!("[FILE]: {file_name}"), UI_PAIR, Some(A_BOLD()));
}
ui.end_layout();
}
ui.end_layout();
}
ui.end_layout();

ui.hl();
ui.br();
ui.hl();
ui.br();

ui.begin_layout(LayoutKind::Horz);
{
ui.begin_layout(LayoutKind::Vert);
ui.begin_layout(LayoutKind::Horz);
{
if app.is_in_todo_panel() {
ui.label_styled("[TODO]", HIGHLIGHT_PAIR, None);
} else {
ui.label_styled(" TODO ", UNSELECTED_PAIR, None);
}
ui.hl();
for (todo, i) in app.iter_todos() {
let indent = " ".repeat(i);
if app.is_cur_todo(todo) && app.is_in_todo_panel() {
if mode == Mode::Edit {
ui.edit_label(
todo.get_text(),
editing_cursor,
format!("{indent}[ ] "),
);
ui.begin_layout(LayoutKind::Vert);
{
if app.is_in_todo_panel() {
ui.label_styled("[TODO]", HIGHLIGHT_PAIR, None);
} else {
ui.label_styled(" TODO ", UNSELECTED_PAIR, None);
}
ui.hl();
for (todo, level) in app.iter_todos() {
let indent = " ".repeat(level);
if app.is_cur_todo(todo) && app.is_in_todo_panel() {
if mode == Mode::Edit {
ui.edit_label(
todo.get_text(),
editing_cursor,
format!("{indent}[ ] "),
);
} else {
ui.label_styled(
&format!("{indent}[ ] {}", todo.get_text()),
SELECTED_PAIR,
None,
);
}
} else {
ui.label_styled(
&format!("{indent}[ ] {}", todo.get_text()),
SELECTED_PAIR,
None,
);
ui.label(&format!("{indent}[ ] {}", todo.get_text()));
}
} else {
ui.label(&format!("{indent}[ ] {}", todo.get_text()));
}
}
}
ui.end_layout();
ui.end_layout();

ui.begin_layout(LayoutKind::Vert);
{
if app.is_in_done_panel() {
ui.label_styled("[DONE]", HIGHLIGHT_PAIR, None);
} else {
ui.label_styled(" DONE ", UNSELECTED_PAIR, None);
}
ui.hl();
for (done, i) in app.iter_dones() {
let indent = " ".repeat(i);
if app.is_cur_done(done) && app.is_in_done_panel() {
if mode == Mode::Edit {
ui.edit_label(
done.get_text(),
editing_cursor,
format!("{indent}[X] "),
);
ui.begin_layout(LayoutKind::Vert);
{
if app.is_in_done_panel() {
ui.label_styled("[DONE]", HIGHLIGHT_PAIR, None);
} else {
ui.label_styled(" DONE ", UNSELECTED_PAIR, None);
}
ui.hl();
for (done, level) in app.iter_dones() {
let indent = " ".repeat(level);
if app.is_cur_done(done) && app.is_in_done_panel() {
if mode == Mode::Edit {
ui.edit_label(
done.get_text(),
editing_cursor,
format!("{indent}[X] "),
);
} else {
ui.label_styled(
&format!("[X] ({}) {}", done.get_date(), done.get_text()),
SELECTED_PAIR,
None,
);
}
} else {
ui.label_styled(
&format!("[X] ({}) {}", done.get_date(), done.get_text()),
SELECTED_PAIR,
None,
);
ui.label(&format!("[X]|{}| {}", done.get_date(), done.get_text()));
}
} else {
ui.label(&format!("[X]|{}| {}", done.get_date(), done.get_text()));
}
}
ui.end_layout();
}
ui.end_layout();
}
ui.end_layout();
ui.end();
timeout = TIMEOUT;
}
ui.end();

refresh();
let key = getch();
Expand All @@ -185,6 +203,7 @@ fn main() {
'j' | '\u{102}' => app.go_down(), // 'j' or 'down'
'g' => app.go_top(),
'G' => app.go_bottom(),
'h' => app.go_half(),
'K' => app.drag_up(),
'J' => app.drag_down(),
'\n' => app.transfer_item(),
Expand All @@ -209,8 +228,9 @@ fn main() {
}
'u' => app.undo(),
'\t' => app.toggle_panel(),
't' => todo!(),
'H' => todo!(),
'q' => break,
// 'q' | '\u{3}' => break,
_ => {}
}
}
Expand All @@ -229,9 +249,14 @@ fn main() {
}
}
}
timeout = 0;
} else {
timeout -= 1000 / FPS;
}
}

endwin();
app.save(&file_path).unwrap();
println!("[INFO]: Saved to '{file_path}', Bye!");
// println!("{app:#?}");
}
Loading

0 comments on commit dc697d9

Please sign in to comment.