• Re: how to create a dialog that is hidden/shown rather than created/des

    From Mark Summerfield@21:1/5 to Mark Summerfield on Fri Jun 21 11:58:56 2024
    On Fri, 21 Jun 2024 11:49:54 +0000, Mark Summerfield wrote:

    I figured it out.

    I replaced this:

    catch { tkwait visibility $form }

    with

    catch {
    tkwait visibility $form grab release $form
    }

    and now it works.

    Actually, it doesn't work. Firstly it stops the Options form from being
    modal. Secondly, if you leave it up you can click the main form or the
    About button.

    What I'm trying to do is create a show/hide form (so it preserves state
    between appearances).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Summerfield@21:1/5 to All on Fri Jun 21 11:49:54 2024
    I figured it out.

    I replaced this:

    catch { tkwait visibility $form }

    with

    catch {
    tkwait visibility $form
    grab release $form
    }

    and now it works.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Summerfield@21:1/5 to Mark Summerfield on Fri Jun 21 15:17:56 2024
    On Fri, 21 Jun 2024 09:55:13 +0000, Mark Summerfield wrote:

    Below is a tiny program.

    The "About" form is created and destroyed. So you can click About then
    close the About form, then repeat as often as you like.

    The "Options" form is supposed to be shown and hidden. But once you
    click it and then close it, the entire app is blocked. So clearly I'm
    doing something wrong.

    Here's the code using Tcl/Tk 9.0b2 on Linux.

    #!/usr/bin/env wish9

    if {[info exists env(TK_SCALING)]} { tk scaling $env(TK_SCALING) }

    proc prepare_modal {form} {
    wm withdraw $form wm attributes $form -type dialog wm transient
    $form .
    }

    proc show_modal {form {focus_widget ""}} {
    wm deiconify $form raise $form focus $form if {$focus_widget ne ""}
    {
    focus $focus_widget
    }
    catch {grab set $form}
    catch {tkwait visibility $form}
    }

    variable optionsForm

    proc main {} {
    wm title . "Dialog Tests"
    wm minsize . 240 240 wm attributes . -type dialog ttk::button
    .optionsButton -text Options… -underline 1 \
    -command on_options
    ttk::button .aboutButton -text About -underline 1 -command on_about
    pack .optionsButton -side top pack .aboutButton -side top
    }

    proc on_options {} {
    if {![info exists ::optionsForm]} {
    puts "on_options init"
    set ::optionsForm [toplevel .optionsForm] prepare_modal
    .optionsForm wm protocol .optionsForm WM_DELETE_WINDOW {wm
    withdraw .optionsForm}
    ttk::label .optionsForm.label -text Options pack
    .optionsForm.label
    }
    puts on_options ;# TODO use show_modal hide/show show_modal
    $::optionsForm ;# TODO give focus widget
    }

    proc on_about {} {
    toplevel .aboutForm prepare_modal .aboutForm wm protocol .aboutForm
    WM_DELETE_WINDOW {destroy .aboutForm} ttk::label .aboutForm.label
    -text About pack .aboutForm.label show_modal .aboutForm
    }

    main

    I think I have solved it this time.

    I added this proc:

    proc hide_modal {form} {
    wm withdraw $form
    grab release $form
    }

    and changed the protocol call to:

    wm protocol .optionsForm WM_DELETE_WINDOW {hide_modal .aboutForm}

    It seems to work, but is this now correct?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Mark Summerfield on Fri Jun 21 16:58:28 2024
    Mark Summerfield <[email protected]> wrote:
    On Fri, 21 Jun 2024 09:55:13 +0000, Mark Summerfield wrote:

    Below is a tiny program.

    The "Options" form is supposed to be shown and hidden. But once you
    click it and then close it, the entire app is blocked. So clearly I'm
    doing something wrong.


    I think I have solved it this time.

    I added this proc:

    proc hide_modal {form} {
    wm withdraw $form
    grab release $form
    }

    and changed the protocol call to:

    wm protocol .optionsForm WM_DELETE_WINDOW {hide_modal .aboutForm}

    It seems to work, but is this now correct?

    Yes, the 'grab' is what makes the options dialog modal. You also need
    to release the grab to remove the modalness so the rest of the app can
    receive UI events.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Mark Summerfield on Fri Jun 21 16:56:53 2024
    Mark Summerfield <[email protected]> wrote:
    Below is a tiny program.

    The "About" form is created and destroyed. So you can click About then
    close the About form, then repeat as often as you like.

    The "Options" form is supposed to be shown and hidden. But once you click
    it and then close it, the entire app is blocked. So clearly I'm doing something wrong.

    Based on your code you are showing the options as a "modal" dialog.
    Modal means it blocks the rest of the app. Withdrawing the window does
    not change its "modalness". You need to not only withdraw the window
    but also turn off the "modalness" of the window at the same time.

    I.e., you need to "grab release" on the window as part of withdrawing
    it.


    As a suggestion, you might also consider making the options window
    'non-modal' in that it can be open and the rest of the app can still
    function. Modality is more often evil than anything else in a GUI.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Summerfield@21:1/5 to Rich on Sat Jun 22 09:44:12 2024
    On Fri, 21 Jun 2024 16:56:53 -0000 (UTC), Rich wrote:

    Mark Summerfield <[email protected]> wrote:
    Below is a tiny program.

    The "About" form is created and destroyed. So you can click About then
    close the About form, then repeat as often as you like.

    The "Options" form is supposed to be shown and hidden. But once you
    click it and then close it, the entire app is blocked. So clearly I'm
    doing something wrong.

    Based on your code you are showing the options as a "modal" dialog.
    Modal means it blocks the rest of the app. Withdrawing the window does
    not change its "modalness". You need to not only withdraw the window
    but also turn off the "modalness" of the window at the same time.

    I.e., you need to "grab release" on the window as part of withdrawing
    it.


    As a suggestion, you might also consider making the options window 'non-modal' in that it can be open and the rest of the app can still function. Modality is more often evil than anything else in a GUI.

    I was trying to create a family of functions to support creating dialogs
    of the kinds: modal and modeless hide/show (i.e., created once and
    reused), and modal create/destroy, and have now done so.

    As for modality being "evil". Over the decades many aspects of UI design
    have come and gone, mostly driven more by fashion than by issues of
    usability or functionality. Modality is confusing and inconvenient for
    some or even many users in some contexts, but it can be very convenient
    and useful for others in other contexts. The same is true of MDI (multiple document interface), a UI idea which has been out of fashion for at least
    25 years but which remains useful for some applications in some contexts.
    (I use it for a "pinboard" type application, and I've seen other current
    uses.) There are many other fashionable inconveniences I could mention.
    For example, some of my notification icons are black and white when color
    would be more useful.

    Personally I think a UI toolkit's role is to provide functionality and it
    is for the programmer to choose what to do with that functionality. I
    dislike toolkits which try to impose on the programmer (I'm thinking of
    Gtk here for example).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)