#lang scheme/gui
(require "mreddesigner-misc.ss"
)
(define tooltip-label%
(class canvas%
(inherit get-parent get-dc get-client-size
min-width min-height
stretchable-width stretchable-height)
(override on-paint)
(init-field (text ""))
(define/public (set-label-text new-text)
(unless (equal? text new-text)
(set! text new-text) (update-min-sizes) (on-paint))
)
(define/public (get-label-text)
text
)
(define label-inset 1)
(define black-color (make-object color% "BLACK"))
(define bg-color (make-object color% "WHITE"))
(define label-font
(send the-font-list find-or-create-font
9 'decorative 'normal 'normal #f))
(define (draw-label dc text w h)
(send dc set-pen (send the-pen-list find-or-create-pen
bg-color 1 'solid))
(send dc set-brush (send the-brush-list find-or-create-brush
bg-color 'solid))
(send dc draw-rectangle 0 0 w h)
(send dc set-pen (send the-pen-list find-or-create-pen
black-color 1 'solid))
(send dc draw-line 0 0 w 0)
(send dc draw-line (- w 1) 0 (- w 1) h)
(send dc draw-line w (- h 1) 0 (- h 1))
(send dc draw-line 0 h 0 0)
(when text
(send dc set-text-foreground black-color)
(send dc set-text-background bg-color)
(send dc set-font label-font)
(send dc draw-text text
(+ label-inset 1)
(+ label-inset 1))))
(define (calc-min-sizes dc text)
(send dc set-font label-font)
(let-values ([(w h a d) (send dc get-text-extent text label-font)])
(let ([ans-w
(+ label-inset
label-inset
1
(max 0 (inexact->exact (ceiling w))))]
[ans-h
(+ label-inset
label-inset
1
(max 0 (inexact->exact (ceiling h))))])
(values ans-w ans-h))))
(define (update-min-sizes)
(let-values ([(w h) (calc-min-sizes (get-dc) text)])
(min-width (+ w 2))
(min-height (+ h 2))
(send (get-parent) reflow-container)))
(define (on-paint)
(let ([dc (get-dc)])
(let-values ([(w h) (get-client-size)])
(draw-label dc text w h))))
(super-new)
(update-min-sizes)
(stretchable-width #f)
(stretchable-height #f)
)
)
(define/provide tooltip<%> (interface () ))
(define/provide tooltip%%
(mixin (subwindow<%>) (tooltip<%>)
(init-field
(tooltip-text " ")
)
(define start-timer #f)
(define timeout-timer #f)
(define shown? #f)
(define tooltip #f)
(define (tooltip:clear)
(when start-timer
(send start-timer stop)
(set! start-timer #f)
)
(when timeout-timer
(send timeout-timer stop)
(set! timeout-timer #f)
)
(when (and tooltip shown?)
(send tooltip show #f)
(set! tooltip #f)
(set! shown? #f)
)
)
(define (tooltip:setup)
(send start-timer stop)
(set! start-timer #f)
(let
((x (inexact->exact (round (* (send this get-width) 0.5))))
(y (+ (send this get-height) 1))
(text tooltip-text)
)
(let-values
(((sx sy) (send this client->screen x y)))
(let*
((frame (new frame%
(parent #f)
(label "")
(stretchable-height #f)
(stretchable-width #f)
(x sx)
(y sy)
(width 46)
(height 17)
(border 0)
(style '(no-system-menu no-caption no-resize-border float))
)
)
(message (new tooltip-label% (parent frame) (text text)))
)
(set! tooltip frame)
(set! timeout-timer (new timer% (notify-callback tooltip:clear)
(interval 2500)
(just-once? #t)
))
(send tooltip show #t)
(set! shown? #t)
)
)
)
)
(define/override (on-subwindow-event w e)
(cond
( (equal? (send e get-event-type) 'enter)
(when (not shown?)
(set! start-timer (new timer% (notify-callback tooltip:setup)
(interval 600)
(just-once? #t)))
)
)
( (member (send e get-event-type) '(leave left-down left-up))
(tooltip:clear)
)
)
(super on-subwindow-event w e)
#f
)
(super-new)
)
)
(define/provide tooltip-button% (tooltip%% button%))
(define/provide tooltip-check-box% (tooltip%% check-box%))
(define/provide tooltip-radio-box% (tooltip%% radio-box%))
(define/provide tooltip-list-box% (tooltip%% list-box%))