;;;; ;;;; f o n t - c h o o s e r . s t k l o s -- A simple font editor widget ;;;; ;;;; Copyright © 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@unice.fr] ;;;; Creation date: 1-Feb-1999 08:55 ;;;; Last file update: 3-Sep-1999 19:51 (eg) (require "Tk-classes") (select-module STklos+Tk) (export make-font-chooser) ;============================================================================= ; ; Global variables ; ;============================================================================= (define *fc:font* #f) ;;; the prototype font (define *fc:lock* #f) ;;; to grab the window while choosing font ;============================================================================= ; ; Utilities ; ;============================================================================= (define (font-wait-result chooser) (let ((cur-grab (grab 'current chooser)) (old-font (font 'actual *fc:font*)) (pretty (lambda () (append (list (font 'conf *fc:font* :family) (font 'conf *fc:font* :size) (string->symbol (font 'conf *fc:font* :weight)) (string->symbol (font 'conf *fc:font* :slant))) (if (font 'conf *fc:font* :underline) '(underline) '()) (if (font 'conf *fc:font* :overstrike) '(overstrike) '()))))) (tkwait 'visibility chooser) (grab 'set chooser) (tkwait 'variable '*fc:lock*) (and cur-grab (grab 'set cur-grab)) ;; Compute result (case *fc:lock* ((ok) (destroy chooser) ;; return a pretty result (pretty)) ((cancel) (destroy chooser) ;; restore the font we have when entering the widget (apply font 'configure *fc:font* old-font) #f)))) (define (%make-font-chooser fnt) ;; ;; Some utilities ;; (define (toggle-weight) (font 'configure *fc:font* :weight (if (equal? (font 'conf *fc:font* :weight) "normal") "bold" "normal"))) (define (toggle-slant) (font 'configure *fc:font* :slant (if (equal? (font 'conf *fc:font* :slant) "roman") "italic" "roman"))) (define (toggle-underline) (font 'configure *fc:font* :underline (not (font 'configure *fc:font* :underline)))) (define (toggle-overstrike) (font 'configure *fc:font* :overstrike (not (font 'configure *fc:font* :overstrike)))) ;; ;; Top frame building ;; (define (make-top-frame parent) (let* ((fonts (sort (font 'families) string<?)) (f (make <Frame> :parent parent :relief "groove" :border-width 2)) (family (make <Label> :parent f :text "Font Family:")) (choice1 (make <Combobox> :parent f :values fonts :state "disabled" :value (font 'configure *fc:font* :family) :command (lambda (v) (font 'conf *fc:font* :family v)))) (size (make <Label> :parent f :text "Font Size:")) (choice2 (make <Combobox> :parent f :values '(8 10 12 14 20 24 36 48) :width 3 :string-value #f :value (font 'configure *fc:font* :size) :command (lambda (v) (font 'conf *fc:font* :size v)))) (bold (make <Check-button> :parent f :text "B" :width 3 :font (font 'create :weight 'bold) :indicator-on #f :command toggle-weight)) (italic (make <Check-button> :parent f :text "i" :width 3 :font (font 'create :slant 'italic) :indicator-on #f :command toggle-slant)) (under (make <Check-button> :parent f :text "U" :width 3 :font (font 'create :underline #t) :indicator-on #f :command toggle-underline)) (over (make <Check-button> :parent f :text "O" :width 3 :font (font 'create :overstrike #t) :indicator-on #f :command toggle-overstrike))) ;; See the buttons that must be toggled (if (equal? (font 'conf *fc:font* :weight) "bold") (toggle bold)) (if (equal? (font 'conf *fc:font* :slant) "italic") (toggle italic)) (if (font 'conf *fc:font* :underline) (toggle under)) (if (font 'conf *fc:font* :overstrike) (toggle over)) ;; Change binding of "Font size" box to allow direct manipulation (bind (entry-of choice2) "<Return>" (lambda () (font 'conf *fc:font* :size (value choice2)))) ;; Pack everybody (pack family choice1 size choice2 :side 'left :padx 2) (pack bold under italic over :fill 'y :side 'left :padx 2 :pady 2) f)) ;;; ;;; Center part of the widget (the sample) ;;; (define (make-sample parent) (make <Label> :parent parent :font *fc:font* :text (string-append "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n" "abcdefghijklmnopqrstuvwxyz\n" "0123456789~`!@#$%^&*()_-+=\n" "{}[]:;\"'<>,.?/"))) ;;; ;;; Bottom part of the widget (the closing buttons) ;;; (define (make-buttons parent) (let* ((f (make <Frame> :parent parent :relief "groove" :border-width 2)) (sel (make <Button> :parent f :text "Select" :command (lambda () (set! *fc:lock* 'ok)))) (cancel (make <Button> :parent f :text "Cancel" :command (lambda () (set! *fc:lock* 'cancel))))) (wm 'protocol parent "WM_DELETE_WINDOW" (lambda() (set! *fc:lock* 'cancel))) (pack sel cancel :side 'left :padx 2 :pady 2) f)) ;;; ;;; Start of %make-font-chooser ;;; (let* ((t (make <Toplevel> :title "Font chooser ..." :class "FontChooser" :geometry "500x300")) (top (make-top-frame t)) (txt (make-sample t)) (but (make-buttons t))) ; The internal frame (pack top :fill 'x :expand #f) (pack txt :fill 'both :expand #t) (pack but :fill 'x :expand #f :side 'bottom) t)) ;============================================================================= ; ; make-font-chooser (the only exported procedure) ; ;============================================================================= (define (make-font-chooser . fnt) (unless *fc:font* ;; If this is the first call to this function. Create the prototype font ;; with a plausible font (let ((tmp (button (gensym ".tmp__font")))) (set! *fc:font* (apply font 'create (font 'actual (tk-get tmp :font)))) (destroy tmp))) (unless (null? fnt) (apply font 'configure *fc:font* (font 'actual (car fnt)))) ;; Call the chooser box (font-wait-result (%make-font-chooser *fc:font*))) (provide "font-chooser")