Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

is there a way to close a dialog programmatically? #24

Open
kurinoku opened this issue Jun 25, 2022 · 5 comments
Open

is there a way to close a dialog programmatically? #24

kurinoku opened this issue Jun 25, 2022 · 5 comments

Comments

@kurinoku
Copy link

Right now closing a rendered dialog is non-trivial, or is too ugly.
Maybe there is a way, but I can only think of either using a mixin or this which doesn't work on dialog but does on frames.

(define (d r)
       (define (close-dialog) (send (renderer-root (force r)) show #f))
       (dialog
        (text (format "~a: first ~a characters" identity len))
        (input "" (λ (evt str)
                    (displayln evt)
                    (when (eq? evt 'return)
                      (cond
                        [(string=? str (substring password 0 len)) 
                         (close-dialog)
                         (next-dialog)]
                        [else
                         (close-dialog)
                         (error-dialog)]))))))
(define r (render (d (delay r)) (get-parent)))

This throws an error since r isn't defined because of how dialog's yield work.

@kurinoku
Copy link
Author

I guess the real question is that if there's a more idiomatic way of doing this?
Right now is not obvious

(define (d)
       (define (close-dialog) (:= @show #f))
       (define @show (@ #t))
       (apply-if-window-view
        dialog
        #:mixin
        (λ (klass)
          (class klass
            (super-new)
            (inherit show)
            (obs-observe! @show (λ (val) (show val)))))
        (text (format "~a: first ~a characters" identity len))
        error
        (text (format "Wrong password: ~a tries left" tries))
        (input "" (λ (evt str)
                    (when (eq? evt 'return)
                      (cond
                        [(string=? str (substring password 0 len)) 
                         (close-dialog)
                         (next-dialog)]
                        [else
                         (close-dialog)
                         (error-dialog)]))))))
     (define r (render (d) (get-parent)))

@Bogdanp
Copy link
Owner

Bogdanp commented Jun 25, 2022

Mixins are the way to go right now -- they're how you can hook in functionality that the library doesn't provide in general, but I agree that the current state is not ideal. Maybe we could get away with windows and dialogs having a #:show? observable arg? I'll try to find some time next week to investigate.

@kurinoku
Copy link
Author

yes, that was what I thought, thank you for answering, maybe having an example in the documentation might be a good idea?

Bogdanp added a commit that referenced this issue Jun 28, 2022
Related to #24, based on an example by @kurinoku.
@benknoble
Copy link
Contributor

Another version:

;; calls `out` with `close-proc`, which closes the window when invoked
(define (make-closing-proc-mixin out)
  (mixin (top-level-window<%>) (top-level-window<%>) (super-new)
    (out (λ ()
           (when (send this can-close?)
             (send this on-close)
             (send this show #f))))))

(define close! (box #f))
(define (set-close! c) (set-box! close! c))
(dialog #:mixin (make-closing-proc-mixin set-close!)
  … call ((unbox close!)) to close the dialog …)

@benknoble
Copy link
Contributor

In fact, I’ve written a macro for this which I use a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants