diff --git a/README.md b/README.md index 40482de..81b0359 100644 --- a/README.md +++ b/README.md @@ -187,6 +187,7 @@ Demo Summary - 01-demo.lisp - Sparkey the Snake Game - 02-demo.lisp - Chat - Private instant messenger +- 03-demo.lisp - IDE - A very simple common lisp IDE Enhancements underway: diff --git a/demos/03-demo.lisp b/demos/03-demo.lisp new file mode 100644 index 0000000..e766f78 --- /dev/null +++ b/demos/03-demo.lisp @@ -0,0 +1,145 @@ +(defpackage #:clog-user + (:use #:cl #:clog) + (:export start-demo)) + +(in-package :clog-user) + +(defclass app-data () + ((body + :accessor body + :documentation "Store top level access on new window") + (drag-mutex + :reader drag-mutex + :initform (bordeaux-threads:make-lock) + :documentation "Serialize access to the on-mouse-down event.") + (in-drag + :accessor in-drag-p + :initform nil + :documentation "Ensure only one box is dragged at a time.") + (drag-x + :accessor drag-x + :documentation "The location of the left side of the box relative to mouse during drag.") + (drag-y + :accessor drag-y + :documentation "The location of the top of the box relative to mouse during drag."))) + +(defun on-mouse-down (obj data) + (let ((app (connection-data-item obj "app-data"))) + (bordeaux-threads:with-lock-held ((drag-mutex app)) + (setf (z-index obj) 1) + (unless (in-drag-p app) + (setf (in-drag-p app) t) + (let* ((mouse-x (getf data ':screen-x)) + (mouse-y (getf data ':screen-y)) + (obj-top (parse-integer (top obj) :junk-allowed t)) + (obj-left (parse-integer (left obj) :junk-allowed t))) + (setf (drag-x app) (- mouse-x obj-left)) + (setf (drag-y app) (- mouse-y obj-top)) + (if (eq (getf data ':event-type) :touch) + (progn + (set-on-touch-move obj 'on-mouse-move) + (set-on-touch-end obj 'stop-obj-grab) + (set-on-touch-cancel obj 'on-mouse-leave)) + (progn + (set-on-mouse-move obj 'on-mouse-move) + (set-on-mouse-up obj 'stop-obj-grab) + (set-on-mouse-leave obj 'on-mouse-leave)))))))) + +(defun on-mouse-move (obj data) + (let* ((app (connection-data-item obj "app-data")) + (x (getf data ':screen-x)) + (y (getf data ':screen-y))) + (setf (top obj) (format nil "~Apx" (- y (drag-y app)))) + (setf (left obj) (format nil "~Apx" (- x (drag-x app)))))) + +(defun on-mouse-leave (obj) + (let ((app (connection-data-item obj "app-data"))) + (setf (in-drag-p app) nil) + (set-on-touch-move obj nil) + (set-on-touch-end obj nil) + (set-on-touch-cancel obj nil) + (set-on-mouse-move obj nil) + (set-on-mouse-up obj nil) + (set-on-mouse-leave obj nil))) + +(defun stop-obj-grab (obj data) + (on-mouse-move obj data) + (on-mouse-leave obj)) + +(defgeneric create-window (clog-obj title + &key html-id content left top width height) + (:documentation "Create an html-window")) + +(defmethod create-window ((obj clog-obj) title &key + (html-id nil) + (top-bar "") + (content "") + (left 60) + (top 60) + (width 400) + (height 300)) + (unless html-id + (setf html-id (clog-connection:generate-id))) + + (let* ((app (connection-data-item obj "app-data")) + (win (create-child (body app) + (format nil + "