Only in tab-layout.space: radio-layout.fasl
Only in tab-layout.space: stack-layout.fasl
Only in tab-layout.space: tab-layout.fasl
diff -ur tab-layout/tab-layout.lisp tab-layout.space/tab-layout.lisp
--- tab-layout/tab-layout.lisp	2005-09-19 17:15:30.000000000 +0200
+++ tab-layout.space/tab-layout.lisp	2006-03-07 01:16:59.000000000 +0100
@@ -6,9 +6,7 @@
 ;;; ---------------------------------------------------------------------------
 ;;;  (c) copyright 2005 by Max-Gerd Retzlaff
 
-(in-package :cl-user)
-
-(defpackage :tab-layout
+(cl:defpackage :tab-layout
   (:use :clim :clim-lisp :radio-layout)
   (:export :tab-layout-pane :add-pane :remove-pane
            :enabled-pane :switch-to-pane
@@ -30,6 +28,9 @@
    (ptype :initform nil :accessor tab-pane-ptype :initarg :ptype)
    (drawing-options :initform nil :accessor drawing-options-of-tab-pane)))
 
+(defclass tab-drag-marker ()
+  ((index :initform nil :initarg :index :accessor marker-index)))
+
 (defgeneric find-in-tab-panes-list (thing parent))
 
 (defmethod find-in-tab-panes-list ((thing sheet) (parent tab-layout-pane))
@@ -40,6 +41,20 @@
   (find thing (tab-panes-of-tab-layout parent)
         :key #'tab-pane-title :test #'string-equal))
 
+(defmethod reorder-pane-in-tab-panes-list ((thing sheet) new-index (parent tab-layout-pane))
+  (let ((pane-entry (find thing (tab-panes-of-tab-layout parent)
+                    :key #'tab-pane-pane :test #'equal)))
+    (loop for pane in (tab-panes-of-tab-layout parent)
+          for index from 0
+          if (= index new-index)
+            collect pane-entry
+          unless (eql pane-entry pane)
+            collect pane)))
+
+(defmethod reorder-pane-in-tab-panes-list ((thing sheet) new-index (parent (eql 'tab-layout-pane)))
+  (reorder-pane-in-tab-panes-list thing new-index (sheet-parent thing)))
+
+
 (defmethod find-in-tab-panes-list ((thing sheet) (parent (eql 'tab-layout-pane)))
   (find-in-tab-panes-list thing (sheet-parent (sheet-parent thing))))
 
@@ -85,6 +100,11 @@
     ((tab-pane 'tab-pane :prompt "Tab pane"))
   (remove-pane tab-pane 'tab-layout-pane))
 
+(define-command (com-reorder-tab-pane :command-table clim:global-command-table)
+    ((tab-pane 'tab-pane :prompt "Tab pane")
+     (position 'integer :prompt "To position"))
+  (reorder-pane-in-tab-panes-list tab-pane position 'tab-layout-pane))
+
 ;;;You probably don't want to uncomment this general command translator.
 ;;;
 ;;; (define-presentation-to-command-translator remove-tab-pane
@@ -102,7 +122,7 @@
 (defparameter +tab-bar-view+ (make-instance 'tab-bar-view))
 
 (define-presentation-method present (tab-pane (type tab-pane) stream
-                                                (view tab-bar-view) &key)
+                                              (view tab-bar-view) &key)
   (stream-increment-cursor-position stream 5 0)
   (multiple-value-bind (x y) (stream-cursor-position stream)
     (let* ((length-top-line (+ x 6 (text-size stream (tab-pane-title tab-pane)) 3))
@@ -123,7 +143,6 @@
         (draw-line stream (apply #'make-point (subseq tab-button-polygon 0 2))
                           (apply #'make-point (subseq tab-button-polygon (- (length tab-button-polygon) 2)))
                           :ink +background-ink+))))
-  
   (stream-increment-cursor-position stream 8 0)
   (apply #'invoke-with-drawing-options stream
          (lambda (rest)
@@ -132,40 +151,72 @@
          (drawing-options-of-tab-pane tab-pane))
   (stream-increment-cursor-position stream 10 0))
 
+(defun drag-marker-polygon (x y)
+  (list
+   (- x 8) y
+   (- x 2) (+ y 14)
+   (+ x 6) (+ y 14)
+   (+ x 11) y))
+
+(define-presentation-method present (tab-pane (type tab-drag-marker) stream
+                                              (view tab-bar-view) &key)
+  (multiple-value-bind (x y) (stream-cursor-position stream)
+    (draw-polygon* stream
+                   (drag-marker-polygon x y) 
+                   :ink +background-ink+)))
+
+(define-presentation-method highlight-presentation ((type tab-drag-marker) record stream (state (eql :highlight)))
+  (multiple-value-bind (x y) (bounding-rectangle* record)
+    (draw-polygon* stream
+                   (drag-marker-polygon x y) 
+                   :ink +blue+)))
+
+(define-presentation-method highlight-presentation ((type tab-drag-marker) record stream (state (eql :unhighlight)))
+  (multiple-value-bind (x y) (bounding-rectangle* record)
+    (draw-polygon* stream
+                   (drag-marker-polygon x y) 
+                   :ink +background-ink+)))
+
+#+(or)(define-drag-and-drop-translator drag-reorder-tabs (tab-pane tab-drag-marker command clim:global-command-table )
+    (object)
+  (print object *debug-io*))
 
+(defun repaint-tab-bar (default-ptype pane)
+  (stream-increment-cursor-position pane 0 3)
+  (draw-line* pane 0 17 (slot-value pane 'climi::current-width) 17 :ink +black+)
+  (loop for tab-pane in (reverse
+                          (tab-panes-of-tab-layout
+                           (sheet-parent (sheet-parent
+                                          (or (climi::pane-border pane) pane)))))
+        for i from 0
+        do (with-output-as-presentation (pane (tab-pane-pane tab-pane)
+                                              (or (tab-pane-ptype tab-pane)
+                                                  default-ptype))
+             (present tab-pane 'tab-pane :stream pane))
+        do (present (make-instance 'tab-drag-marker :index i) 'tab-drag-marker :stream pane)))
 
 (defmacro with-tab-layout ((default-ptype &key name)
-                              &body body)
+                           &body body)
   (let* ((radio-layout-pane (gensym "radio-layout-pane-"))
          (tab-bar-pane (gensym "tab-bar-pane-"))
          (tab-layout-name-gensym (gensym "tab-layout-"))
          (tab-layout-name (or name `',tab-layout-name-gensym)))
     `(let ((,tab-bar-pane (make-clim-stream-pane
-                                   :default-view +tab-bar-view+
-                                   :display-time :command-loop
-                                   :scroll-bars nil
-                                   :borders nil
-                                   :height 22
-                                   :display-function
-                                   (lambda (frame pane)
-                                     (declare (ignore frame))
-                                     (stream-increment-cursor-position pane 0 3)
-                                     (draw-line* pane 0 17 (slot-value pane 'climi::current-width) 17 :ink +black+)
-                                     (mapcar (lambda (tab-pane)
-                                                 (with-output-as-presentation (pane (tab-pane-pane tab-pane)
-                                                                                    (or (tab-pane-ptype tab-pane)
-                                                                                        ,default-ptype))
-                                                   (present tab-pane 'tab-pane :stream pane)))
-                                             (tab-panes-of-tab-layout (sheet-parent
-                                                                             (sheet-parent
-                                                                              (or (climi::pane-border pane) pane))))))))
+                           :default-view +tab-bar-view+
+                           :display-time :command-loop
+                           :scroll-bars nil
+                           :borders nil
+                           :height 22
+                           :display-function  (lambda (frame pane)
+                                                (declare (ignore frame))
+                                                (repaint-tab-bar ,default-ptype pane))))
            (,radio-layout-pane (make-pane 'radio-layout-pane
                                           :contents (list ,@(mapcar #'second body)))))
        (make-pane 'tab-layout-pane
                   :name ,tab-layout-name
                   :tab-panes (list ,@(mapcar (lambda (tab-spec)
-                                                  `(apply #'make-tab-pane-from-list (list ,@tab-spec)))
-                                                body))
+                                               `(apply #'make-tab-pane-from-list (list ,@tab-spec)))
+                                             body))
                   :radio-layout-pane ,radio-layout-pane
                   :tab-bar-pane ,tab-bar-pane
                   :contents (list ,tab-bar-pane
