git.fiddlerwoaroof.com
Browse code

basic functionality demo: lists files and loads them; however, there are probably still some unicode quirks

fiddlerwoaroof authored on 27/10/2014 08:54:27
Showing 3 changed files
... ...
@@ -0,0 +1,3 @@
1
+This is a fairly simple notebook application inspired by nvAlt.
2
+I'm primarily writing it as an exercise in Common Lisp, but I'm
3
+hoping that it'll be useful as well.
... ...
@@ -0,0 +1,3 @@
1
+- Implement saving after changes
2
+
3
+- Markdown highlighting
... ...
@@ -27,12 +27,19 @@
27 27
 ;  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 28
 ;  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 29
 ;  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+(require 'asdf)
31
+(asdf:load-system 'quicklisp)
30 32
 
31 33
 (asdf:load-system :cl-cffi-gtk)
34
+(ql:quickload :cl-fad)
35
+(ql:quickload :x.let-star)
32 36
 
33 37
 (defpackage :gtk-tutorial
34 38
   (:use :gtk :gdk :gdk-pixbuf :gobject
35
-        :glib :gio :pango :cairo :common-lisp))
39
+        :glib :gio :pango :cairo :common-lisp
40
+        :cl-fad :x.let-star)
41
+  (:shadowing-import-from x.let-star let*)
42
+  (:export main))
36 43
 
37 44
 (in-package :gtk-tutorial)
38 45
 
... ...
@@ -46,85 +53,129 @@
46 53
                      (lambda ,bind
47 54
                        ,@body)))
48 55
 
49
-(let ((surface nil))
50
-  (defun example-drawing ()
51
-    (within-main-loop
52
-      (let ((window (make-instance 'gtk-window
53
-                                   :type :toplevel
54
-                                   :title "Example Drawing"))
55
-            (frame (make-instance 'gtk-frame
56
-                                  :shadow-type :in))
57
-            (area (make-instance 'gtk-drawing-area
58
-                                 :width-request 250
59
-                                 :height-request 200)))
60
-
61
-        (on (destroy window) (__)
62
-          (declare (ignore __))
63
-          (leave-gtk-main))
64
-
65
-        (on (draw area) (widget cr)
66
-          (declare (ignore widget))
67
-          (let ((cr (pointer cr)))
68
-            (cairo-set-source-surface cr surface 0.0 0.0)
69
-            (cairo-paint cr)
70
-            (cairo-destroy cr)
71
-            +gdk-event-propagate+))
72
-
73
-        (on (configure-event area) (widget event)
74
-          (declare (ignore widget))
75
-          (when surface
76
-            (format t "surface is not nil~%")
77
-            (cairo-surface-destroy surface))
78
-          (setf surface (gdk-window-create-similar-surface
79
-                          (gtk-widget-window widget)
80
-                          :color
81
-                          (gtk-widget-get-allocated-width widget)
82
-                          (gtk-widget-get-allocated-height widget)))
83
-          (let ((cr (cairo-create surface)))
84
-            (cairo-set-source-rgb cr 1.0 1.0 1.0)
85
-            (cairo-paint cr)
86
-            (cairo-destroy cr)))
87
-
88
-        (on (motion-notify-event area) (widget event)
89
-          (format t "MOTION-NOTIFY-EVENT")
90
-          (when (member :button1-mask (gdk-event-motion-state event))
91
-            (let ((cr (cairo-create surface))
92
-                  (x (gdk-event-motion-x event))
93
-                  (y (gdk-event-motion-y event)))
94
-              (cairo-rectangle cr (- x 3.0) (- y 3.0) 6.0 6.0)
95
-              (cairo-fill cr)
96
-              (cairo-destroy cr)
97
-              (gtk-widget-queue-draw-area widget
98
-                                          (truncate (- x 3.0))
99
-                                          (truncate (- y 3.0))
100
-                                          6
101
-                                          6)))
102
-          +gdk-event-stop+)
103
-
104
-        (on (button-press-event area) (widget event)
105
-          (format t "BUTTON-PRESS-EVENT ~A~%" event)
106
-          (if (eql 1 (gdk-event-button-button event))
107
-            (let ((cr (cairo-create surface))
108
-                  (x (gdk-event-button-x event))
109
-                  (y (gdk-event-button-y event)))
110
-              (cairo-rectangle cr (- x 3.0) (- y 3.0) 6.0 6.0)
111
-              (cairo-fill cr)
112
-              (cairo-destroy cr)
113
-              (gtk-widget-queue-draw-area widget
114
-                                          (truncate (- x 3.0))
115
-                                          (truncate (- y 3.0))
116
-                                          6
117
-                                          6))
118
-            (let ((cr (cairo-create surface)))
119
-              (cairo-set-source-rgb cr 1.0 1.0 1.0)
120
-              (cairo-paint cr)
121
-              (cairo-destroy cr)
122
-              (gtk-widget-queue-draw widget))))
123
-
124
-            (gtk-widget-add-events area '(:button-press-mask :pointer-motion-mask))
125
-            (gtk-container-add frame area)
126
-            (gtk-container-add window frame)
127
-            (gtk-widget-show-all window)))))
128
-
129
-(example-drawing)
56
+(defmacro mainloop (fname winvar title width height &body body)
57
+  `(defun ,fname ()
58
+     (within-main-loop
59
+       (let ((,winvar (make-instance 'gtk-window
60
+                                     :title ,title
61
+                                     :type :toplevel
62
+                                     :default-width ,width
63
+                                     :default-height ,height)))
64
+
65
+         (on (destroy ,winvar) (widget)
66
+           (declare (ignore widget))
67
+           (leave-gtk-main))
68
+
69
+         ,@body
70
+
71
+         (gtk-widget-show-all ,winvar)))))
72
+
73
+;(macroexpand-1
74
+;  (quote
75
+;    (declare-paned-widget (:orientation :vertical)
76
+;      (declare-scroll-window () list-view)
77
+;      (declare-scroll-window (:wrap-mode :word) text-view))))
78
+
79
+;(let ((paned (make-instance 'gtk :orientation :vertical)))
80
+;  (let ((scroller (make-instance 'gtk-scroll-window)))
81
+;    (gtk-container-add list-view))
82
+;  (let ((scroller (make-instance 'gtk-scroll-window :wrap-mode :word)))
83
+;    (gtk-container-add text-view)))
84
+
85
+(defmacro declare-scroll-window (initializers child)
86
+  (let ((sw-sym (gensym)))
87
+    `(let ((,sw-sym (make-instance 'gtk-scrolled-window ,@initializers)))
88
+       (gtk-container-add ,sw-sym ,child)
89
+       ,sw-sym)))
90
+
91
+(defmacro declare-paned-widget (initializers child1 child2)
92
+  (let ((paned-sym (gensym)))
93
+    `(let ((,paned-sym (make-instance 'gtk-paned ,@initializers)))
94
+       (gtk-paned-add1 ,paned-sym ,child1)
95
+       (gtk-paned-add2 ,paned-sym ,child2)
96
+       ,paned-sym)))
97
+
98
+
99
+(defun make-list-view (display-list)
100
+  (let ((store (make-instance 'gtk-list-store :column-types '("gchararray")))
101
+        (list-view (make-instance 'gtk-tree-view :headers-visible nil)))
102
+
103
+    (gtk-tree-view-set-model list-view store)
104
+
105
+    (loop for fn in display-list
106
+          do (gtk-list-store-set store
107
+                                 (gtk-list-store-append store)
108
+                                 (file-namestring fn)))
109
+
110
+    (let* ((renderer (make-instance 'gtk-cell-renderer-text))
111
+           (column
112
+             (gtk-tree-view-column-new-with-attributes "Filename" renderer "text" 0)))
113
+      (gtk-tree-view-append-column list-view column))
114
+    (values store list-view)))
115
+
116
+(defun make-text-view (text)
117
+  (let* ((text-view (make-instance 'gtk-text-view :wrap-mode :word))
118
+         (buffer (gtk-text-view-get-buffer text-view)))
119
+    (gtk-text-buffer-set-text buffer text)
120
+    (values buffer text-view)))
121
+
122
+(defvar *note-directory* "/home/edwlan/Dropbox/Notes/")
123
+(mainloop main window "test" 200 200
124
+  (let* (((:mval list-model list-view) (make-list-view (cl-fad:list-directory *note-directory*)))
125
+         ((:mval text-buffer text-view) (make-text-view "")))
126
+
127
+    (on (row-activated list-view) (tree-view path column)
128
+      (let* ((iter (gtk-tree-model-get-iter list-model path))
129
+             (selected (gtk-tree-model-get-value list-model iter 0))
130
+             (file-contents
131
+               (with-open-file (fd (merge-pathnames-as-file *note-directory* selected))
132
+                 (let ((seq (make-string (file-length fd))))
133
+                   (read-sequence seq fd)
134
+                   seq))))
135
+        (format t "~a ~a ~a~%" tree-view path column)
136
+        (format t "~a~%" iter)
137
+        (format t "~a~%" selected)
138
+        
139
+        (gtk-text-buffer-set-text text-buffer file-contents)))
140
+
141
+    (gtk-container-add window
142
+                       (declare-paned-widget (:orientation :vertical)
143
+                                             (declare-scroll-window (:height-request 400) list-view)
144
+                                             (declare-scroll-window (:wrap-mode :word) text-view)))))
145
+
146
+;(main)
147
+
148
+(labels 
149
+  ((slot-function (descriptor)
150
+     (ecase descriptor
151
+       (:start 'gtk-box-pack-start)
152
+       (:end   'gtk-box-pack-end)))
153
+   (proc-slot (box from-object slot)
154
+     (if (equal (first slot) 'QUOTE)
155
+       `(gtk-box-pack-start ,box (slot-value ,from-object ,slot))   
156
+       (ecase (length slot)
157
+         (1 `(gtk-box-pack-start ,box (slot-value ,from-object ,(first slot))))
158
+         (2 `(,(slot-function (second slot)) ,box (slot-value ,from-object ,(first slot))))))))
159
+
160
+  (defmacro renderwin (window box from-object &body slots)
161
+    (let ((window-sym (gensym))
162
+          (box-sym (gensym))
163
+          (from-obj-sym (gensym)))
164
+      `(let ((,window-sym ,window)
165
+             (,box-sym ,box)
166
+             (,from-obj-sym ,from-object))
167
+         ,@(loop for slot in slots collect (proc-slot box-sym from-obj-sym slot))
168
+         (gtk-container-add ,window-sym ,box-sym)))))
169
+
170
+(defclass mainwin nil
171
+  ((file-view :initarg :file-view)
172
+   (file-list :initarg :file-list)))
173
+
174
+
175
+(defun wrap-with-scrollwindow (widg &key (hscrpolicy :automatic) (vscrpolicy :automatic))
176
+  (let ((scroller (make-instance 'gtk-scrolled-window
177
+                                 :hscrollbar-policy hscrpolicy
178
+                                 :vscrollbar-policy vscrpolicy)))
179
+    (gtk-container-add scroller widg)
180
+    scroller))
130 181