diff --git a/source/clog-connection.lisp b/source/clog-connection.lisp
index 7a78164..eff9891 100644
--- a/source/clog-connection.lisp
+++ b/source/clog-connection.lisp
@@ -405,7 +405,7 @@ instead of the compiled version."
"Execute SCRIPT on CONNECTION-ID, return value. If times out answer
DEFAULT-ANSWER."
(let ((uid (generate-id)))
- (prep-query uid default-answer)
+ (prep-query uid (when default-answer (format nil "~A" default-answer)))
(execute connection-id
(format nil "ws.send (\"~A:\"+eval(\"~A\"));"
uid
diff --git a/tools/clog-builder.lisp b/tools/clog-builder.lisp
index ee93538..f6e49f1 100644
--- a/tools/clog-builder.lisp
+++ b/tools/clog-builder.lisp
@@ -74,17 +74,17 @@
:initform ""
:documentation "Copy buffer")
(next-panel-id
- :accessor next-pannel-id
+ :accessor next-panel-id
:initform 0
- :documentation "Next new pannel id")
+ :documentation "Next new panel id")
(current-control
:accessor current-control
:initform nil
:documentation "Current selected control")
- (selected-tool
- :accessor selected-tool
+ (select-tool
+ :accessor select-tool
:initform nil
- :documentation "Currently selected tool")
+ :documentation "Select tool")
(control-lists
:accessor control-lists
:initform (make-hash-table :test #'equalp)
@@ -106,6 +106,9 @@
:initform nil
:documentation "Current control pallete window")))
+(defparameter *app-sync-hash* (make-hash-table :test #'equal)
+ "Exchange app instance with new external pages")
+
;; Control-List utilities
(defun init-control-list (app panel-id)
@@ -185,7 +188,7 @@
(setf (attribute control "data-clog-type") control-type-name))
control))
-(defun setup-control (win content control)
+(defun setup-control (content control &key win)
"Setup CONTROL by creating pacer and setting up events for manipulation"
(let ((app (connection-data-item content "builder-app-data"))
(panel-id (html-id content))
@@ -212,7 +215,8 @@
(lambda (obj data)
(declare (ignore obj) (ignore data))
(select-control control)
- (window-focus win))
+ (when win
+ (window-focus win)))
:cancel-event t)
(clog::set-on-event placer "resizestop"
(lambda (obj)
@@ -280,8 +284,8 @@ not a temporary attached one when using select-control."
("parent" ,(attribute (parent-element control) "data-clog-name")
t ,(lambda (obj)
(place-inside-bottom-of
- (attach-as-child obj
- (clog::js-query obj (format nil "$(\"[data-clog-name='~A']\").attr('id')"
+ (attach-as-child control
+ (clog::js-query control (format nil "$(\"[data-clog-name='~A']\").attr('id')"
(text obj))))
control)
(place-after control placer)))
@@ -323,7 +327,7 @@ not a temporary attached one when using select-control."
:width (client-width control)
:height (client-height control))))))))))))
-(defun on-populate-loaded-window (win content)
+(defun on-populate-loaded-window (content &key win)
"Setup html imported in to CONTENT for use with Builder"
(let ((app (connection-data-item content "builder-app-data"))
(panel-uid (get-universal-time))
@@ -346,7 +350,7 @@ not a temporary attached one when using select-control."
(setf dct (attribute control "data-clog-type"))
(unless (equal dct "undefined")
(change-class control (getf (control-info dct) :clog-type))
- (setup-control win content control)
+ (setup-control content control :win win)
(add-siblings (first-child control)))
(setf control (next-sibling control))))))
(add-siblings (first-child content)))))
@@ -393,12 +397,17 @@ of controls and double click to select control."
(on-populate-control-list-win content))))
;; drag and drop to change
(set-on-drag-over list-item (lambda (obj)(declare (ignore obj))()))
- (set-on-drop list-item (lambda (obj data)
- (let* ((id (attribute obj "data-clog-control"))
- (control1 (attach-as-child obj id))
- (control2 (attach-as-child obj (getf data :drag-data)))
- (placer1 (get-placer control1))
- (placer2 (get-placer control2)))
+ (set-on-drop list-item
+ (lambda (obj data)
+ (let* ((id (attribute obj "data-clog-control"))
+ (control1 (get-from-control-list app
+ panel-id
+ id))
+ (control2 (get-from-control-list app
+ panel-id
+ (getf data :drag-data)))
+ (placer1 (get-placer control1))
+ (placer2 (get-placer control2)))
(if (getf data :shift-key)
(place-inside-bottom-of control1 control2)
(place-before control1 control2))
@@ -412,8 +421,7 @@ of controls and double click to select control."
:width (client-width control2)
:height (client-height control2))
(on-populate-control-list-win content))))
- (set-on-drag-start list-item (lambda (obj)
- (declare (ignore obj))())
+ (set-on-drag-start list-item (lambda (obj)(declare (ignore obj))())
:drag-data (html-id control))
(add-siblings (first-child control) (format nil "~A→" sim))))
(setf control (next-sibling control))))))
@@ -557,10 +565,7 @@ of controls and double click to select control."
(setf (positioning control-list) :absolute)
(setf (size control-list) 2)
(set-geometry control-list :left 0 :top 0 :bottom 0 :width 190)
- (set-on-change control-list (lambda (obj)
- (setf (selected-tool app) (control-info (value control-list)))))
- (set-on-focus control-list (lambda (obj)
- (setf (selected-tool app) (control-info (value control-list)))))
+ (setf (select-tool app) control-list)
(dolist (control supported-controls)
(add-select-option control-list (getf control :name) (getf control :description)))))))
@@ -589,12 +594,12 @@ of controls and double click to select control."
(defparameter *builder-template2*
"~% (~A (attach-as-child body \"~A\" :clog-type '~A))")
-(defun on-new-builder-window (obj)
+(defun on-new-builder-panel (obj)
"Open new panel"
(let* ((app (connection-data-item obj "builder-app-data"))
(win (create-gui-window obj :top 40 :left 220 :width 400))
(box (create-panel-box-layout (window-content win)
- :left-width 0 :right-width 9
+ :left-width 0 :right-width 0
:top-height 30 :bottom-height 0))
(tool-bar (top-panel box))
(btn-del (create-button tool-bar :content "Del"))
@@ -606,14 +611,14 @@ of controls and double click to select control."
(content (center-panel box))
(in-simulation nil)
(file-name ".")
- (panel-name (format nil "panel-~A" (incf (next-pannel-id app))))
+ (panel-name (format nil "panel-~A" (incf (next-panel-id app))))
(next-id 0)
(panel-uid (get-universal-time)) ;; unique id for panel
(panel-id (html-id content)))
(init-control-list app panel-id)
;; setup panel window
- (setf (background-color tool-bar) :silver)
(setf (attribute content "data-clog-name") panel-name)
+ (setf (background-color tool-bar) :silver)
(setf (window-title win) panel-name)
;; activate associated windows on open
(on-populate-control-list-win content)
@@ -667,7 +672,7 @@ of controls and double click to select control."
(setf file-name fname)
(setf (inner-html content)
(escape-string (read-file fname)))
- (on-populate-loaded-window win content))))))
+ (on-populate-loaded-window content :win win))))))
(set-on-click btn-save (lambda (obj)
(server-file-dialog obj "Save Panel As.." file-name
(lambda (fname)
@@ -741,7 +746,7 @@ of controls and double click to select control."
;; any click on panel directly will focus window
(window-focus win)
;; create control
- (let* ((control-record (selected-tool app))
+ (let* ((control-record (control-info (value (select-tool app))))
(control-type-name (getf control-record :name))
(control (create-control content control-record
(format nil "B~A~A"
@@ -752,13 +757,13 @@ of controls and double click to select control."
;; setup control
(setf (attribute control "data-clog-name")
(format nil "~A-~A" control-type-name (incf next-id)))
- (setf (selected-tool app) nil)
+ (setf (value (select-tool app)) 0)
(setf (box-sizing control) :content-box)
(setf (positioning control) :absolute)
(set-geometry control
:left (getf data :x)
:top (getf data :y))
- (setup-control win content control)
+ (setup-control content control :win win)
(select-control control)
(on-populate-control-list-win content))
(t
@@ -767,6 +772,228 @@ of controls and double click to select control."
(on-populate-control-properties-win obj)
(on-populate-control-list-win content)))))))))
+(defun on-attach-builder-page (body)
+ "New builder page has attached"
+ (let* ((params (form-get-data body))
+ (panel-uid (form-data-item params "bid"))
+ (app (gethash panel-uid *app-sync-hash*))
+ win
+ (box (create-panel-box-layout body
+ :left-width 0 :right-width 0
+ :top-height 0 :bottom-height 0))
+ (content (center-panel box))
+ (panel-name (format nil "page-~A" (incf (next-panel-id app))))
+ (in-simulation nil)
+ (file-name ".")
+ (next-id 0)
+ (panel-id (html-id content)))
+ ;; sync new window with app
+ (setf (connection-data-item body "builder-app-data") app)
+ (remhash panel-uid *app-sync-hash*)
+ (funcall (gethash (format nil "~A-link" panel-uid) *app-sync-hash*) content)
+ (setf win (gethash (format nil "~A-win" panel-uid) *app-sync-hash*))
+ (remhash (format nil "~A-win" panel-uid) *app-sync-hash*)
+
+ ;; setup window and page
+ (setf (attribute content "data-clog-name") panel-name)
+ (setf (title (html-document body)) panel-name)
+ (setf (window-title win) panel-name)
+
+ ;; setup close of page
+ (set-on-before-unload (window body)
+ (lambda (obj)
+ (declare (ignore obj))
+ (window-close win)))
+ ;; activate associated windows on open
+ (on-populate-control-list-win content)
+ ;; setup window events
+ (set-on-window-focus win
+ (lambda (obj)
+ (declare (ignore obj))
+ (on-populate-control-list-win content)))
+ (set-on-window-close win
+ (lambda (obj)
+ (declare (ignore obj))
+ ;; clear associated windows on close
+ (setf (current-control app) nil)
+ (destroy-control-list app panel-id)
+ (close-window (window body))))
+
+ (clog-gui-initialize body)
+ (init-control-list app panel-id)
+ (let* ((pbox (create-panel-box-layout (window-content win)
+ :left-width 0 :right-width 0
+ :top-height 30 :bottom-height 0))
+ (tool-bar (top-panel pbox))
+ (btn-del (create-button tool-bar :content "Del"))
+ (btn-sim (create-button tool-bar :content "Simulate"))
+ (btn-rndr (create-button tool-bar :content "Render"))
+ (btn-prop (create-button tool-bar :content "Properties"))
+ (btn-save (create-button tool-bar :content "Save"))
+ (btn-load (create-button tool-bar :content "Load"))
+ (wcontent (center-panel pbox)))
+ (create-div wcontent :content
+ "