;;;; ;;;; P a n e d . s t k -- HPaned and VPaned composite widgets ;;;; ;;;; Copyright © 1993-1999 Erick Gallesio - I3S-CNRS/ESSI ;;;; ;;;; 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. ;;;; ;;;; Idea of this implementation was found in comp.lang.tcl. ;;;; Original author seems to be James Noble and the version from which this ;;;; stuff is derivated is from Jay Schmidgall (shmdgljd@ghostwind.rchland.ibm.com). ;;;; ;;;; 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) ;;; ;;; Globals ;;; (define paned:drag-start 0) ;============================================================================= ; ; < H P a n e d > ; ;============================================================================= ;;; ;;; Resources ;;; (option 'add "*HPaned.Grip.Background" "Black" "widgetDefault") (option 'add "*HPaned.Grip.Relief" "raised" "widgetDefault") (option 'add "*HPaned.Grip.BorderWidth" 2 "widgetDefault") (option 'add "*HPaned.Grip.Cursor" "sb_v_double_arrow" "widgetDefault") (option 'add "*HPaned.Grip.Width" 12 "widgetDefault") (option 'add "*HPaned.Grip.Height" 8 "widgetDefault") (option 'add "*HPaned.Separator.BorderWidth" 2 "widgetDefault") (option 'add "*HPaned.Separator.Relief" "solid" "widgetDefault") ;;; ;;; Class definition ;;; (define-class () ((class :init-keyword :class :init-form "HPaned") (top-frame :accessor top-frame-of) (bottom-frame :accessor bottom-frame-of) (grip :accessor grip-of) (separator :accessor separator-of) (fraction :accessor fraction :init-keyword :fraction :allocation :active :after-slot-set! (lambda(o v) (place-grip o))) ;; Fictives slot (background :accessor background :init-keyword :background :allocation :propagated :propagate-to (frame top-frame bottom-frame grip separator)) (grip-background :accessor grip-background :init-keyword :grip-background :allocation :propagated :propagate-to ((grip background))) (border-width :accessor border-width :allocation :propagated :propagate-to (frame)) (internal-relief :accessor internal-relief :init-keyword :internal-relief :allocation :propagated :propagate-to ((separator relief))) (relief :accessor relief :init-keyword :relief :allocation :propagated :propagate-to (frame)) (width :accessor width :init-keyword :width :allocation :propagated :propagate-to (frame)) (height :accessor height :init-keyword :height :allocation :propagated :propagate-to (frame))) :metaclass ) (define-method initialize-composite-widget ((self ) initargs frame) (let ((grip (make :parent frame :class "Grip")) (separ (make :parent frame :class "Separator" :width 1 :height 4)) (top (make :parent frame :border-width 2 :relief "raised")) (bot (make :parent frame :border-width 2 :relief "raised"))) (next-method) ;; Associate bindings to the grip (bind grip "" (lambda (y) (start-grip self y))) (bind grip "" (lambda (y) (motion-grip self y))) (bind grip "" (lambda (y) (stop-grip self y))) ;; initialize true slots (slot-set! self 'Id (Id frame)) (slot-set! self 'top-frame top) (slot-set! self 'bottom-frame bot) (slot-set! self 'grip grip) (slot-set! self 'separator separ) (slot-set! self 'fraction (get-keyword :fraction initargs 0.5)) ;; Place the grip (place-grip self))) ;;; ;;; methods ;;; (define-method place-grip ((self )) (let ((fraction (slot-ref self 'fraction))) (place (separator-of self) :relx 0 :rely fraction :anch "w" :relwi 1) (place (grip-of self) :relx 0.95 :rely fraction :anchor "center") (place (top-frame-of self) :x 0 :y 0 :relwidth 1 :relheight fraction) (place (bottom-frame-of self) :x 0 :rely fraction :relwidth 1 :relheight (- 1.0 fraction)) ;; Hide separator behind the bottom and top frames (lower (separator-of self)) ;; Be sure to raise the grip (raise (grip-of self)))) (define-method start-grip ((self ) y) ;; Raise separator and grip (raise (separator-of self)) (raise (grip-of self)) (set! paned:drag-start y)) (define-method motion-grip ((self ) y) (let ((fraction (slot-ref self 'fraction))) (set! fraction (max 0.0001 (min 0.9999 (+ fraction (/ (- y paned:drag-start) (+ 1 (winfo 'height (frame-of self)))))))) (place (separator-of self) :relx 0 :relwidth 1 :rely fraction :anchor "w") (place (grip-of self) :relx 0.95 :rely fraction :anchor "center") (slot-set! self 'fraction fraction))) (define-method stop-grip ((self ) y) (place-grip self)) ;============================================================================= ; ; < V P a n e d > ; ;============================================================================= ;;; ;;; Resources ;;; (option 'add "*VPaned.Grip.Background" "Black" "widgetDefault") (option 'add "*VPaned.Grip.Relief" "raised" "widgetDefault") (option 'add "*VPaned.Grip.BorderWidth" 2 "widgetDefault") (option 'add "*VPaned.Grip.Cursor" "sb_h_double_arrow" "widgetDefault") (option 'add "*VPaned.Grip.Width" 8 "widgetDefault") (option 'add "*VPaned.Grip.Height" 12 "widgetDefault") (option 'add "*VPaned.Separator.BorderWidth" 2 "widgetDefault") (option 'add "*VPaned.Separator.Relief" "solid" "widgetDefault") ;;; ;;; Class definition ;;; (define-class () ((class :init-keyword :class :init-form "VPaned") (left-frame :accessor left-frame-of) (right-frame :accessor right-frame-of) (grip :accessor grip-of) (separator :accessor separator-of) (fraction :accessor fraction :init-keyword :fraction :allocation :active :after-slot-set! (lambda(o v) (place-grip o))) ;; Fictives slots (background :accessor background :init-keyword :background :allocation :propagated :propagate-to (frame left-frame right-frame grip separator)) (grip-background :accessor grip-background :init-keyword :grip-background :allocation :propagated :propagate-to ((grip background))) (border-width :accessor border-width :allocation :propagated :propagate-to (frame)) (internal-relief :accessor internal-relief :init-keyword :internal-relief :allocation :propagated :propagate-to ((separator relief))) (relief :accessor relief :init-keyword :relief :allocation :propagated :propagate-to (frame)) (width :accessor width :init-keyword :width :allocation :propagated :propagate-to (frame)) (height :accessor height :init-keyword :height :allocation :propagated :propagate-to (frame))) :metaclass ) (define-method initialize-composite-widget ((self ) initargs frame) (let ((grip (make :parent frame :class "Grip")) (separ (make :parent frame :class "Separator":width 4 :height 1)) (left (make :parent frame :border-width 2 :relief "raised")) (right (make :parent frame :border-width 2 :relief "raised"))) (next-method) ;; Associate bindings to the grip (bind grip "" (lambda (x) (start-grip self x))) (bind grip "" (lambda (x) (motion-grip self x))) (bind grip "" (lambda (x) (stop-grip self x))) ;; initialize true slots (slot-set! self 'Id (Id frame)) (slot-set! self 'left-frame left) (slot-set! self 'right-frame right) (slot-set! self 'grip grip) (slot-set! self 'separator separ) (slot-set! self 'fraction (get-keyword :fraction initargs 0.5)) ;; Place the grip (place-grip self))) ;;; ;;; methods ;;; (define-method place-grip ((self )) (let ((fraction (slot-ref self 'fraction))) (place (separator-of self) :rely 0 :relx fraction :anch "n" :relh 1) (place (grip-of self) :rely 0.95 :relx fraction :anchor "center") (place (left-frame-of self) :x 0 :y 0 :relheight 1 :relwidth fraction) (place (right-frame-of self) :y 0 :relx fraction :relheight 1 :relwidth (- 1.0 fraction)) ;; Hide separator behind the right and left frames (lower (separator-of self)) ;; Be sure to raise the grip (raise (grip-of self)))) (define-method start-grip ((self ) x) ;; Raise separator and grip (raise (separator-of self)) (raise (grip-of self)) (set! paned:drag-start x)) (define-method motion-grip ((self ) x) (let ((fraction (slot-ref self 'fraction))) (set! fraction (max 0.0001 (min 0.9999 (+ fraction (/ (- x paned:drag-start) (+ 1 (winfo 'width (frame-of self)))))))) (place (separator-of self) :rely 0 :relheight 1 :relx fraction :anchor "n") (place (grip-of self) :rely 0.95 :relx fraction :anchor "center") (slot-set! self 'fraction fraction))) (define-method stop-grip ((self ) x) (place-grip self)) (provide "Paned") #| Example: (define x (make :width 200 :height 300)) (define y (make :parent (top-frame-of x) :fraction 0.75)) (pack x y :fill "both" :expand #t) |#