diff --git a/clog-gui.lisp b/clog-gui.lisp index 3819535..3d5ab6c 100644 --- a/clog-gui.lisp +++ b/clog-gui.lisp @@ -12,6 +12,9 @@ ;; Implementation - clog-gui - Desktop GUI abstraction ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defconstant menu-bar-height 37) +(defconstant top-bar-height 20) + (defclass clog-gui () ((body :accessor body @@ -28,6 +31,14 @@ :accessor last-z :initform -9999 :documentation "Top z-order for windows") + (last-x + :accessor last-x + :initform 0 + :documentation "Last default open x point") + (last-y + :accessor last-y + :initform menu-bar-height + :documentation "Last default open y point") (copy-buf :accessor copy-buf :initform "" @@ -350,7 +361,7 @@ The on-window-change clog-obj received is the new window")) (y (getf data ':screen-y)) (adj-y (- y (drag-y app))) (adj-x (- x (drag-x app)))) - (when (and (> adj-x 0) (> adj-y 30)) + (when (and (> adj-x 0) (> adj-y menu-bar-height)) (cond ((equalp (in-drag app) "m") (fire-on-window-move (drag-obj app)) (setf (top (drag-obj app)) (unit :px adj-y)) @@ -395,104 +406,111 @@ on-window-resize-done at end of resize.")) (defmethod create-gui-window ((obj clog-obj) &key (title "New Window") (content "") - (left 60) - (top 60) - (width 400) - (height 300) + (left nil) + (top nil) + (width 300) + (height 200) (maximize nil) (client-movement nil) (html-id nil)) - (unless html-id - (setf html-id (clog-connection:generate-id))) - - (let* ((app (connection-data-item obj "clog-gui")) - (win (create-child (body app) - (format nil - "
-
- ~A - X -
-
~A
-
+
-
" - top left width height (incf (last-z app)) ; outer div - html-id html-id html-id ; title bar - title html-id ; title - html-id content ; body - html-id html-id) ; size - :clog-type 'clog-gui-window - :html-id html-id))) - (setf (win-title win) - (attach-as-child win (format nil "~A-title" html-id))) - (setf (title-bar win) - (attach-as-child win (format nil "~A-title-bar" html-id))) - (setf (closer win) (attach-as-child win (format nil "~A-closer" html-id))) - (setf (sizer win) (attach-as-child win (format nil "~A-sizer" html-id))) - (setf (content win) (attach-as-child win (format nil "~A-body" html-id))) - (flet ((maximize-window (obj) - (cond ((last-width win) - (setf (width win) (last-width win)) - (setf (height win) (last-height win)) - (setf (top win) (last-y win)) - (setf (left win) (last-x win)) - (setf (last-width win) nil)) - (t - (setf (last-x win) (left win)) - (setf (last-y win) (top win)) - (setf (last-height win) (height win)) - (setf (last-width win) (width win)) - (setf (top win) (unit :px 35)) - (setf (left win) (unit :px 0)) - (setf (width win) (unit :vw 100)) - (setf (height win) - (- (inner-height (window (body app))) 30)))))) - (set-on-double-click (win-title win) #'maximize-window) - (when maximize - (maximize-window win))) - (set-on-click (closer win) (lambda (obj) - (declare (ignore obj)) - (when (fire-on-window-can-close win) - (remhash (format nil "~A" html-id) - (windows app)) - (remove-from-dom win) - (fire-on-window-change nil app) - (fire-on-window-close win)))) - (setf (gethash (format nil "~A" html-id) (windows app)) win) - (fire-on-window-change win app) - (cond (client-movement - (jquery-execute win - (format nil "draggable({handle:'#~A-title-bar'})" html-id)) - (jquery-execute win "resizable({handles:'se'})") - (set-on-pointer-down (win-title win) - (lambda (obj data) - (setf (z-index win) (incf (last-z app))) - (fire-on-window-change win app))) - (set-on-event win "dragstart" - (lambda (obj) - (fire-on-window-move win))) - (set-on-event win "dragstop" - (lambda (obj) - (fire-on-window-move-done win))) - (set-on-event win "resizestart" - (lambda (obj) - (fire-on-window-size win))) - (set-on-event win "resizestop" - (lambda (obj) - (fire-on-window-size-done win)))) - (t - (set-on-pointer-down - (win-title win) 'on-gui-drag-down :capture-pointer t) - (set-on-pointer-down - (sizer win) 'on-gui-drag-down :capture-pointer t))) - win)) + (let ((app (connection-data-item obj "clog-gui"))) + (unless html-id + (setf html-id (clog-connection:generate-id))) + (unless left + (setf left (last-x app)) + (incf (last-x app) 10)) + (unless top + (setf top (last-y app)) + (incf (last-y app) top-bar-height) + (when (> top (- (inner-height (window (body app))) (last-y app))) + (setf (last-y app) menu-bar-height))) + (let ((win (create-child (body app) + (format nil + "
+
+ ~A + X +
+
~A
+
+
+
" + top left width height (incf (last-z app)) ; outer div + html-id html-id html-id ; title bar + title html-id ; title + html-id content ; body + html-id html-id) ; size + :clog-type 'clog-gui-window + :html-id html-id))) + (setf (win-title win) + (attach-as-child win (format nil "~A-title" html-id))) + (setf (title-bar win) + (attach-as-child win (format nil "~A-title-bar" html-id))) + (setf (closer win) (attach-as-child win (format nil "~A-closer" html-id))) + (setf (sizer win) (attach-as-child win (format nil "~A-sizer" html-id))) + (setf (content win) (attach-as-child win (format nil "~A-body" html-id))) + (flet ((maximize-window (obj) + (cond ((last-width win) + (setf (width win) (last-width win)) + (setf (height win) (last-height win)) + (setf (top win) (last-y win)) + (setf (left win) (last-x win)) + (setf (last-width win) nil)) + (t + (setf (last-x win) (left win)) + (setf (last-y win) (top win)) + (setf (last-height win) (height win)) + (setf (last-width win) (width win)) + (setf (top win) (unit :px menu-bar-height)) + (setf (left win) (unit :px 0)) + (setf (width win) (unit :vw 100)) + (setf (height win) + (- (inner-height (window (body app))) 30)))))) + (set-on-double-click (win-title win) #'maximize-window) + (when maximize + (maximize-window win))) + (set-on-click (closer win) (lambda (obj) + (declare (ignore obj)) + (when (fire-on-window-can-close win) + (remhash (format nil "~A" html-id) + (windows app)) + (remove-from-dom win) + (fire-on-window-change nil app) + (fire-on-window-close win)))) + (setf (gethash (format nil "~A" html-id) (windows app)) win) + (fire-on-window-change win app) + (cond (client-movement + (jquery-execute win + (format nil "draggable({handle:'#~A-title-bar'})" html-id)) + (jquery-execute win "resizable({handles:'se'})") + (set-on-pointer-down (win-title win) + (lambda (obj data) + (setf (z-index win) (incf (last-z app))) + (fire-on-window-change win app))) + (set-on-event win "dragstart" + (lambda (obj) + (fire-on-window-move win))) + (set-on-event win "dragstop" + (lambda (obj) + (fire-on-window-move-done win))) + (set-on-event win "resizestart" + (lambda (obj) + (fire-on-window-size win))) + (set-on-event win "resizestop" + (lambda (obj) + (fire-on-window-size-done win)))) + (t + (set-on-pointer-down + (win-title win) 'on-gui-drag-down :capture-pointer t) + (set-on-pointer-down + (sizer win) 'on-gui-drag-down :capture-pointer t))) + win))) ;;;;;;;;;;;;;;;;;; ;; window-title ;; diff --git a/tutorial/22-tutorial.lisp b/tutorial/22-tutorial.lisp index d09358d..1ba3ea9 100644 --- a/tutorial/22-tutorial.lisp +++ b/tutorial/22-tutorial.lisp @@ -12,22 +12,19 @@ ;; and :client-movement is set to nil. This mode offers numerous events ;; for fine control and is best for local applications although will be a bit ;; more choppy cross continent or via satellite. - (let ((win (create-gui-window body :left (random 600) :top (+ 40 (random 400)) - :client-movement t))) + (let ((win (create-gui-window body :client-movement t))) (dotimes (n 100) ;; window-content is the root element for the clog-gui ;; windows (create-div (window-content win) :content n)))) (defun on-file-browse (body) - (let* ((win (create-gui-window body :left (random 600) :top (+ 40 (random 400)) - :client-movement t)) + (let* ((win (create-gui-window body :client-movement t)) (browser (create-child (window-content win) ""))))) (defun on-file-drawing (body) - (let* ((win (create-gui-window body :left (random 600) :top (+ 40 (random 400)) - :client-movement nil)) + (let* ((win (create-gui-window body :client-movement nil)) (canvas (create-canvas (window-content win) :width 600 :height 400)) (cx (create-context2d canvas))) (set-border canvas :thin :solid :black) @@ -43,8 +40,7 @@ (path-fill cx))) (defun on-file-movies (body) - (let ((win (create-gui-window body :left (random 600) :top (+ 40 (random 400)) - :client-movement t))) + (let ((win (create-gui-window body :client-movement t))) (create-video (window-content win) :source "https://www.w3schools.com/html/mov_bbb.mp4"))) (defun on-help-about (body)