;; -*- lisp -*- (in-package :it.bese.ucw) (def (constant e :test #'string=) +default-collapsible-collapsed-image-url+ "static/ucw/images/collapsible-off.png") (def (constant e :test #'string=) +default-collapsible-expanded-image-url+ "static/ucw/images/collapsible-on.png") ;;;; ** Collapsible pane component (defcomponent collapsible-pane (widget-component-with-body) ((switch :initform nil :initarg :switch :accessor switch-of) (collapsedp :initform t :initarg :collapsed :accessor collapsedp) (client-side :initform nil :initarg :client-side-p :accessor client-side-p)) (:default-initargs :css-class "ucw-collapsible" :dom-id (js:gen-js-name-string :prefix "_collaps")) (:documentation "Component for good.")) (flet ((setup-body-parent (self) ;; break the parent relation of the body component when collapsed, so the ajax/dirty component ;; renderings will properly detect that this component is not visible currently (awhen (body-of self) (if (and (collapsedp self) (not (client-side-p self))) (setf (parent it) nil) (setf (parent it) self))))) (defmethod initialize-instance :after ((self collapsible-pane) &key) (setup-body-parent self)) (defmethod (setf body-of) :after (value (self collapsible-pane)) (setup-body-parent self)) (defmethod (setf collapsedp) :around (value (self collapsible-pane)) (let ((old-value (collapsedp self))) (when (xor old-value value) (call-next-method) (setup-body-parent self) (mark-dirty self))))) (defun render-standard-collapsible-pane-switch (self &rest args &key (action-class 'ajax-action) title (collapsed-title title) (expanded-title title) (escape-title t) (collapsed-image +default-collapsible-collapsed-image-url+) (expanded-image +default-collapsible-expanded-image-url+)) (if (client-side-p self) (apply 'render-standard-client-side-collapsible-switch self args) (<:div :class (list "switch" (if (collapsedp self) "collapsed" "expanded")) (