diff --git a/cl-todo.lisp b/cl-todo.lisp index 550f9bc..d805769 100644 --- a/cl-todo.lisp +++ b/cl-todo.lisp @@ -9,7 +9,7 @@ (in-package :cl-todo) (defvar *task-list* NIL) -(defconstant +runfile+ (uiop:native-namestring "~/.todo")) +(defvar *runfile* (uiop:native-namestring "~/.todo")) (defun launch () @@ -18,7 +18,7 @@ ;;TODO ) -(defun load-task-file (&optional (file-name +runfile+)) +(defun load-task-file (&optional (file-name *runfile*)) "Load a list of (task) strings from the run file" (with-open-file (f file-name :if-does-not-exist nil) (when (null f) @@ -30,19 +30,21 @@ ((null line) tasks) (setf tasks (append tasks (list line)))))) -(defun write-task-list (&optional (lst *task-list*) (filename +runfile+)) +(defun write-task-list (&optional (lst *task-list*) (filename *runfile*)) "Write the task list to file, one entry per line." (let ((f (open filename :direction :output))) (dolist (i lst) (format f "~&~S" i)) (close f))) (defun add-task! (task) - "Append a task to the task list" - (setf *task-list* (append *task-list* (list task)))) + "Append a task to the task list and save to file" + (setf *task-list* (append *task-list* (list task))) + (write-task-list)) (defun remove-task! (task) - "Remove a task from the list" + "Remove a task from the list and save to file" (setf *task-list* (remove-if #'(lambda (s) (equalp s task)) *task-list* :count 1))) + ;;(write-task-list)) ;;FIXME caused a file-access error diff --git a/cl-todo.lisp b/cl-todo.lisp index 550f9bc..d805769 100644 --- a/cl-todo.lisp +++ b/cl-todo.lisp @@ -9,7 +9,7 @@ (in-package :cl-todo) (defvar *task-list* NIL) -(defconstant +runfile+ (uiop:native-namestring "~/.todo")) +(defvar *runfile* (uiop:native-namestring "~/.todo")) (defun launch () @@ -18,7 +18,7 @@ ;;TODO ) -(defun load-task-file (&optional (file-name +runfile+)) +(defun load-task-file (&optional (file-name *runfile*)) "Load a list of (task) strings from the run file" (with-open-file (f file-name :if-does-not-exist nil) (when (null f) @@ -30,19 +30,21 @@ ((null line) tasks) (setf tasks (append tasks (list line)))))) -(defun write-task-list (&optional (lst *task-list*) (filename +runfile+)) +(defun write-task-list (&optional (lst *task-list*) (filename *runfile*)) "Write the task list to file, one entry per line." (let ((f (open filename :direction :output))) (dolist (i lst) (format f "~&~S" i)) (close f))) (defun add-task! (task) - "Append a task to the task list" - (setf *task-list* (append *task-list* (list task)))) + "Append a task to the task list and save to file" + (setf *task-list* (append *task-list* (list task))) + (write-task-list)) (defun remove-task! (task) - "Remove a task from the list" + "Remove a task from the list and save to file" (setf *task-list* (remove-if #'(lambda (s) (equalp s task)) *task-list* :count 1))) + ;;(write-task-list)) ;;FIXME caused a file-access error diff --git a/gtk-ui.lisp b/gtk-ui.lisp index ba95544..dba0779 100644 --- a/gtk-ui.lisp +++ b/gtk-ui.lisp @@ -8,42 +8,53 @@ (in-package :cl-todo) -(defvar *widget-list*) - (defun make-gui (task-list) (within-main-loop (let ((window (make-instance 'gtk-window :type :toplevel :title "cl-todo" ;;remove when undecorating :default-width 300 - :default-height 200)) - (box (make-instance 'gtk-box - :orientation :vertical - :spacing 10)) - ;;TODO input pane and scratchpad - (input-pane NIL) ;(make-instance 'gtk-text-field)) - (scratch-pad NIL) - (task-buttons (create-widget-list task-list))) - ;;(gtk-box-pack-start input-pane) - (dolist (tb task-buttons) - (gtk-box-pack-start tb)) - (gtk-container-add window box) + :default-height 200 + :border-width 10)) + (input-field (make-instance 'gtk-entry)) + (outer-box (make-instance 'gtk-box + :orientation :vertical + :spacing 5)) + (scroller (make-instance 'gtk-scrolled-window + :hscrollbar-policy :automatic + :vscrollbar-policy :automatic)) + (inner-box (make-instance 'gtk-box + :orientation :vertical + :valign :start + :border-width 5 + :spacing 2))) + (g-signal-connect input-field "activate" + #'(lambda (field) + (add-task! (gtk-entry-text field)) + (create-task-widgets task-list inner-box) + (setf (gtk-entry-text field) ""))) + (gtk-container-add outer-box input-field) + (gtk-container-add scroller (create-task-widgets task-list inner-box)) + (gtk-box-pack-start outer-box scroller) + (gtk-container-add window outer-box) ;;TODO undecorate (gtk-widget-show-all window)))) -(defun create-widget-list (task-list) - "Create a check button widget for each task" +(defun create-task-widgets (task-list box) + "Create a check button widget for each task in the given gtk-box" ;;XXX This would probably be neater with LOOP (do* ((tl task-list (cdr tl)) + (task (car tl) (car tl)) (task-button - (gtk-check-button-new-with-label (car tl)) - (gtk-check-button-new-with-label (car tl))) - (task-button-list nil)) - ((null task) task-button-list) + (when task (gtk-check-button-new-with-label task)) + (when task (gtk-check-button-new-with-label task)))) + ((null task) box) (g-signal-connect task-button "clicked" #'(lambda (button) - ;;TODO also remove the button from the UI - (remove-task! (gtk-check-button-label button)))) - (setf task-button-list - (append task-button-list (list task-button))))) + (gtk-container-remove box button) + (remove-task! task))) + (gtk-box-pack-start box task-button))) + +;;TODO undo delete? +;;TODO help window