;;;; -*- lisp -*- ;; Copyright (c) 2003-2005 Edward Marco Baringer ;; All rights reserved. ;; ;; Redistribution and use in source and binary forms, with or without ;; modification, are permitted provided that the following conditions are ;; met: ;; ;; - Redistributions of source code must retain the above copyright ;; notice, this list of conditions and the following disclaimer. ;; ;; - Redistributions in binary form must reproduce the above copyright ;; notice, this list of conditions and the following disclaimer in the ;; documentation and/or other materials provided with the distribution. ;; ;; - Neither the name of Edward Marco Baringer, nor BESE, nor the names ;; of its contributors may be used to endorse or promote products ;; derived from this software without specific prior written permission. ;; ;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ;; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (in-package :it.bese.ucw.presentations) (defcomponent presentation () ((css-class :accessor css-class :initarg :css-class :initform nil)) (:metaclass standard-presentation-class) (:documentation "The super class of all UCW presentations. A presentation object is a UCW component which knows how to read/write different kinds of data types. There are three major kinds of presentations: 1) object-presentation - Managing a single object. 2) slot-presentation - Managing the single parts (slots) which make up an object. 3) collection-presentation - Managing multiple objects. Presentations are independant of the underlying application specific lisp objects they manage. A presentation can be created once and reused or modified before and after it has been used. Presentations fulfill two distinct roles: on the one hand they create, given a lisp object, a grahpical (html) rendering of that object, they also deal with whatever operations the user might wish to perform on that object. * Creating Presentation Objects Presentation objects are created by making an instance of either an object-presentation or a collection-presentation and then filling the slots property of this object.")) (defmethod presentation-slots ((presentation presentation)) (mapcar #'(lambda (slot-name) (slot-value presentation slot-name)) (presentation-slots (class-of presentation)))) (defmacro present-object (object &key using presentation) (assert (xor using presentation) (using presentation) "Must specify exactly one of :USING and :PRESENTATION.") (if using (destructuring-bind (type &rest args) (ensure-list using) `(call ',type ,@args :instance ,object)) (rebinding (presentation) `(progn (setf (slot-value ,presentation 'instance) ,object) (call-component self ,presentation))))) (defmacro present-collection (presentation-type &rest initargs) `(call ',presentation-type ,@initargs)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; object-presentation (defcomponent object-presentation (presentation) ((instance :initform nil :initarg :instance :accessor instance)) (:metaclass standard-presentation-class) (:documentation "Presentations for single objects.")) (defmethod render ((o object-presentation)) (unless (slot-value o 'instance) (error "Attempting to render the presentation ~S, but it has no instance object to present." o)) (present o t)) (defmethod present ((pres object-presentation) (view t)) (declare (ignore view)) (<:table :class (css-class pres) (dolist (slot (presentation-slots pres)) (<:tr :class "presentation-slot-row" (<:td :class "presentation-slot-label" (<:as-html (label slot))) (<:td :class "presentation-slot-value" (present-slot slot (instance pres))))) (render-options pres))) (defmethod render-options ((pres object-presentation)) (declare (ignore instance)) (<:tr (<:td :colspan 2 :align "center" ( slot-value number-input)) :label "~A is greater than:" :render-prefix "~A > ") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Integers (defslot-presentation integer-slot-presentation (number-slot-presentation) () (:type-name integer)) (defmethod presentation-slot-value ((slot integer-slot-presentation) instance) (declare (ignore instance)) (or (call-next-method) "")) (defmethod (setf presentation-slot-value) ((value string) (slot integer-slot-presentation) instance) (unless (string= "" value) (let ((i (parse-integer value :junk-allowed t))) (when i (setf (presentation-slot-value slot instance) i))))) (defmethod present-slot ((slot integer-slot-presentation) instance) (if (editablep slot) (