;;;;
;;;; S c r o l l b o x . s t k 	  --  Scroll Listbox composite widget
;;;;
;;;; Copyright © 1993-1999 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
;;;; 
;;;; Permission to use, copy, modify, distribute,and license this
;;;; software and its documentation for any purpose is hereby granted,
;;;; provided that existing copyright notices are retained in all
;;;; copies and that this notice is included verbatim in any
;;;; distributions.  No written agreement, license, or royalty fee is
;;;; required for any of the authorized uses.
;;;; This software is provided ``AS IS'' without express or implied
;;;; warranty.
;;;;
;;;;           Author: Erick Gallesio [eg@kaolin.unice.fr]
;;;;    Creation date: 22-Mar-1994 13:05
;;;; Last file update:  3-Sep-1999 20:14 (eg)

(require "Basics")

(select-module STklos+Tk)

;=============================================================================
;
; 		     < S c r o l l - l i s t b o x >
;
;=============================================================================

;;;;
;;;; Resources
;;;;


;;;;
;;;; Class definition
;;;;

(define-class <Scroll-listbox> (<Tk-composite-widget> <Listbox>)
  ((class 	  :init-keyword :class
		  :init-form	"ScrollListbox")
   (listbox 	  :accessor     listbox-of)
   (h-scrollbar	  :accessor     h-scrollbar-of)
   (v-scrollbar	  :accessor     v-scrollbar-of)
   (h-scroll-side :accessor     h-scroll-side
		  :allocation   :virtual
		  :init-keyword :h-scroll-side
		  :slot-ref     (lambda (o) 
				  (STk:h-scroll-side (slot-ref o 'h-scrollbar)))
		  :slot-set!    (lambda (o v)
				  (STk:h-scroll-side-set! 
				      (slot-ref o 'h-scrollbar) v)))
   (v-scroll-side :accessor     v-scroll-side
		  :allocation   :virtual
		  :init-keyword :v-scroll-side
		  :slot-ref     (lambda (o)
				  (STk:v-scroll-side (slot-ref o 'v-scrollbar)))
		  :slot-set!    (lambda (o v)
				  (STk:v-scroll-side-set! 
				      (slot-ref o 'v-scrollbar) v)))
   ;; Non allocated slots
   (background   :accessor     background
		 :init-keyword :background
		 :allocation   :propagated
		 :propagate-to (frame listbox h-scrollbar v-scrollbar))
   (border-width :accessor     border-width 
		 :allocation   :propagated
		 :init-keyword :border-width
		 :propagate-to (frame))
   (relief	 :accessor     relief
		 :init-keyword :relief
		 :allocation   :propagated
		 :propagate-to (frame))))

;;;;
;;;;  <Scroll-listbox> methods
;;;;

(define-method initialize-composite-widget ((self <Scroll-listbox>) initargs parent)
  (let* ((hs (make <Scrollbar> :parent parent :orientation "horizontal"))
	 (vs (make <Scrollbar> :parent parent :orientation "vertical"))
	 (l  (make <Listbox>   :parent parent)))

    ;; Set internal true slots 
    (slot-set! self 'Id	          (slot-ref l 'Id))
    (slot-set! self 'listbox      l)
    (slot-set! self 'h-scrollbar  hs)
    (slot-set! self 'v-scrollbar  vs)

    ;; Place internal widgets
    (grid hs :row 0 :column 1 :sticky "we")     (grid 'remove hs)
    (grid l  :row 1 :column 1 :sticky "nswe")
    (grid vs :row 1 :column 2 :sticky "ns")
    (grid 'rowconf    parent 1 :weight 1)
    (grid 'columnconf parent 1 :weight 1)
    ;; Attach command to scrollbar and listbox
    (slot-set! l 'x-scroll-command (lambda l (apply (slot-ref hs 'Id) 'set l)))
    (slot-set! l 'y-scroll-command (lambda l (apply (slot-ref vs 'Id) 'set l)))

    (slot-set! hs 'command (lambda args (apply (slot-ref l 'Id) 'xview args)))
    (slot-set! vs 'command (lambda args (apply (slot-ref l 'Id) 'yview args)))
))

(provide "Scrollbox")

#|
   Example:

	(define l1 (make <Scroll-listbox> :h-scroll-side "bottom" 
			 :relief "ridge" :border-width 2
		         :value '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17)))
	(define l2 (make <Scroll-listbox> :v-scroll-side #f :h-scroll-side "top"
			 :relief "ridge" :border-width 2
                         :value '("A long long phrase which can be scrolled ...")))
	(pack l1 l2 :side 'left :expand #t :fill 'both)
|#
