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
Showing 3 changed files
... | ... |
@@ -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 |
|