racket / plot

Other
40 stars 37 forks source link

Support Interactive Overlays in Standalone Frames #98

Closed nick-chandoke closed 3 years ago

nick-chandoke commented 3 years ago

plot-frame currently accepts only a renderer tree. it should also accept a snip, so that we can have interactive overlays in standalone frames.

while we're at it, we may as well allow the user to specify the frame title (without the "Plot: " prefix) and border width(s) as parameters.

alex-hhh commented 3 years ago

You can both set interactive overlays and set custom titles to plot frames.

The plot title is the easiest, all you have to do is call set-label on the plot frame:

#lang racket
(require plot)
(define frame (plot-frame (function sin -5 5)))
(send frame show #t)
(send frame set-label "A Custom Plot Title")

To set an overlay renderer is a bit more complicated, you have to get the snip out of the plot frame, but this is created sometimes after the frame is show. The simplest thing is to wait in a loop for it to be created:

#lang racket
(require plot racket/gui)
(define frame (plot-frame (function sin -5 5)))
(send frame show #t) ;; Frame MUST be show, otherwise we loop forever 

(define snip
  (let loop ()
    (define snip
      (let ([c (first (send frame get-children))])
        (send c get-snip)))
    (or snip
        (begin
          (sleep/yield 0.1)
          (loop)))))

(send snip set-mouse-event-callback
      (lambda (snip event x y)
        (when x
          (send snip set-overlay-renderers (vrule x)))))

You can combine both of these techniques into your own custom function. As an alternative you can use snip-canvas% to add a plot snip to a frame

alex-hhh commented 3 years ago

I hope my previous message answered your question, so I will close this issue.

For other questions about the plot package or Racket in general, I recommend posting on the racket-users list or on the Racket slack channel (you can sign up for Slack here)