how to display to app forms at once?

Discussion in 'Cadence' started by Jimka, Dec 24, 2005.

  1. Jimka

    Jimka Guest

    Does anyone know how i can define and display two GUI froms
    programatically?
    It is easy interactively. You simply define the forms, and from the
    CIW call hiDisplayForm
    twice, once for each form. the first hiDisplayForm displays the form
    and waits, but
    you can enter another command in the CIW.

    However, if you call hiDisplayForm twice from a SKILL function while
    neither form
    is already displayed, then only one is displayed, and when the user
    presses
    OK/Cancel on that form, then the next hiDisplayForm is called.

    I have a solution (in the next post) but it is not very pretty.
     
    Jimka, Dec 24, 2005
    #1
  2. Jimka

    Jimka Guest

    Here is a function that will display one or more hi GUI forms
    simultaneously. It depends on a behaviour of the load function
    which i discovered accidentally. I do not know if the behavior
    is documented or dependable. But the accidentally discovered
    behavor is that if you call hiDisplayForm multiple times
    in a file, and load the file, then hiDisplayForm either does not
    wait, or the load function recognizes then and continues loading
    just as if the user were typing the same SKILL into the CIWindow.
    It appears that load, treats the input file identically to
    input read from the CIWindow.

    The function, creates code, writes it to a file, then loads the file.
    This is ugly, and i'd love someone to suggest a way to
    do this without having to write to a tmp file.

    Does anyone know if this behavior is dependable
    or advertised?

    ;; This function takes one or more form names (as symbols) and
    ;; displays them all simultaneously.
    ;; E.g., (display_multiple_forms 'form1 'form2)
    (defun display_multiple_forms (@rest forms)
    (let ((fileName (makeTempFileName "/tmp/XXXXX")))
    (let ((fp (outfile fileName)))
    (foreach form forms
    (println `(hiDisplayForm ',form) fp))
    (close fp))
    (load fileName)
    (deleteFile fileName)))
     
    Jimka, Dec 24, 2005
    #2
  3. Jimka

    Guest Guest

    You are using blocking forms, so the code execution is suspended on each until
    you close each form (and you have to close the second form before closing the
    first form will cause it to return to program execution).

    To avoid this, pass "?dontBlock t" as an argument to hiCreateAppForm() for at
    least the first form).

    -Pete Zakel
    ()

    "Probably the best operating system in the world is the [operating system]
    made for the PDP-11 by Bell Laboratories." - Ted Nelson, October 1977
     
    Guest, Dec 27, 2005
    #3
  4. It's a side effect - in fact we had a customer reporting such behaviour as a
    bug... (but it won't be fixed). However, it is not (as far as I know)
    documented, and you should not depend on it (it could well be changed in
    future). It's also pretty ghastly as you say...

    The best solution is to the the ?dontBlock t argument when you create the form
    in the first place, and then displaying the form will not block, and so you can
    display as many as you like...

    Another approach (if the forms already exist, and cannot be recreated with
    ?dontBlock for some reason) is to use hiRegTimer() to display the forms (with a
    time of 0 tenths of a second, say).

    Andrew.
     
    Andrew Beckett, Dec 27, 2005
    #4
  5. Jimka

    Jimka Guest

    Do you know of any reason why this behavior should not be documented.
    It could potentially be very powerful. Especially if there were a more
    lispy interface such as load_from_list, or load_from_string.
    It seems reasonable that loading a file have the same semantics as
    typing the same
    contents into the CIWindow.

    Yes i know a little about ?dontBlock, but doesn't that have to be given
    on form definition?
    I do not have the source code to all form definitions, or can
    ?dontBlock be given
    on form instantiation even if the definition of the form did not
    provide it?
     
    Jimka, Dec 29, 2005
    #5
  6. I think one reason would be that it would have to work that way forever - and we
    might not want to tie ourselves down. This definitely smacks of side effect
    behaviour, rather than something is designed to work this way - and it is pretty
    inelegant.
    No, it has to be defined at form creation time. But you can use the hiRegTimer()
    approach that I suggested to allow multiple blocking forms to be launched at
    once (I'm not talking about "modal" type blocking, but blocking in the sense
    that the hiDisplayForm() does not return).

    Regards,

    Andrew.
     
    Andrew Beckett, Dec 29, 2005
    #6
  7. Jimka

    Guest Guest

    Loading a file has the same semantics, but not the same behavior. When
    a blocking operation is instigated, a new Skill top-level is started. That
    new top-level will continue reading an input file (or replay file), but the
    new top-level cannot return to a procedure -- that return only happens when
    the blocking call returns.

    That's why the behavior is different.
    No, ?dontBlock has to be supplied when the form is created.

    Another workaround is to use hiRegTimer() calls to invoke the forms, but
    that is not a recommended way to do it, since calling blocking operations
    from a timer callback is usually not a good idea.

    -Pete Zakel
    ()

    The invariable mark of wisdom is to see the miraculous in the common.

    - Emerson
     
    Guest, Dec 29, 2005
    #7
  8. Jimka

    Jimka Guest

    Loading a file has the same semantics, but not the same behavior. When
    I do not see any difference. If i open two forms from in input file,
    then two
    forms open and consequently a new skill top-level is started.

    If i open two forms from the CIWindow, then two forms open and
    consequently a new skill top-level is started.

    Is there something i'm missing here? It seems to me that they have the
    same behavior exactly. Where is the difference you see Pete?
     
    Jimka, Dec 31, 2005
    #8
  9. Jimka

    Guest Guest

    The difference is that a new top-level cannot return.

    A new top-level will continue reading a file, so in-line blocking calls
    will not block the execution of further statements in the file.

    I cannot explain it any clearer than that.

    -Pete Zakel
    ()

    "Slang is language that takes off its coat, spits on its hands, and goes
    to work."
     
    Guest, Dec 31, 2005
    #9
  10. Jimka

    Jimka Guest

    Hi pete, are you sure you are not mistaken here?
    This is not a difference that i can see: the new top-level cannot
    return in either case,
    neither when started from the CIW nor when started from a file load.

    When loading a file, after the first form has been
    poped up, a NEW top level continues reading the file and pops up the
    second form.

    When reading from the CIW, a NEW top level continues reading after the
    first form
    is poped up, and that new top level pops up the second form.

    In both cases neither top-level can return until the user OKs or
    Cancels the form.
    In both cases a different top level pops up each form.

    I do not see any difference.

    -jim
     
    Jimka, Dec 31, 2005
    #10
  11. Jimka

    Guest Guest

    Try this:

    enter (all in one line) the following into the CIW:

    MyTestString = "before" hiDisplayForm(<blocking form>) MyTestString = "after"

    Now enter:

    printf( "MyTestString = %s\n" MyTestString)

    while the form is still up and you'll see the value of MyTestString is
    "before". That is because the hiDisplayForm() is blocked and won't return to
    the statement that sets MyTestString to "after" until you close the form.

    If you put the above two lines into a procedure:

    procedure( MyTestProcedure()
    MyTestString = "before" hiDisplayForm(<blocking form>) MyTestString = "after"
    printf( "MyTestString = %s\n" MyTestString)
    )

    and then call the procedure the printf line will not be executed until after
    the form is closed and MyTestString has been set to "after".

    If you put the two lines entered originally into a file and load or replay the
    file, they will act just as if you had entered them into the CIW.

    -Pete Zakel
    ()

    "Now and then an innocent person is sent to the legislature."
     
    Guest, Jan 1, 2006
    #11
  12. Jimka

    Guest Guest

    Yes, they do.

    However, loading from a file and executing a procedure works differently
    with relation to blocking behavior for the same reason that the string
    assignment won't occur until the form is closed.

    -Pete Zakel
    ()

    "This `telephone' has too many shortcomings to be seriously considered as a
    means of communication. The device is inherently of no value to us."

    -Western Union internal memo, 1876
     
    Guest, Jan 2, 2006
    #12
  13. Jimka

    Jimka Guest

    Yes pete, this illustrates my point. Entering into the CIW works
    exactly
    the same as reading the code from a file. There does not seem to be
    any difference
    that I can detect.

    If you enter these two lines into a file or type them into the CIW, the
    same thing will
    happen:

    MyTestString = "before" hiDisplayForm(<blocking form>) MyTestString =
    "after"
    printf( "MyTestString = %s\n" MyTestString)

    I believe you claimed:
    Can you think of an example that works differently if you load it from
    a file
    or if you type the same thing into the CIW?
    My experimentation has shown they have the same behavior.

    -jim
     
    Jimka, Jan 2, 2006
    #13
  14. Jimka

    Guest Guest

     
    Guest, Jan 2, 2006
    #14
  15. Jimka

    Jimka Guest

    Yes, loading a file seems the same as entering into the CIW,
    but evaluating a procedure that contains the content of that file
    is different. That was indeed the point of my first posting.

    And if you want to popup two (or more) forms (which you did not
    write, and for which you do not have the source code) from a single
    procedure, how can you do it?

    My proposed solution was have the procedure actually print to
    a file and load it.


    ;; This function takes one or more form names (as symbols) and
    ;; displays them all simultaneously.
    ;; E.g., (display_multiple_forms 'form1 'form2)
    (defun display_multiple_forms (@rest forms)
    (let ((fileName (makeTempFileName "/tmp/XXXXX")))
    (let ((fp (outfile fileName)))
    (foreach form forms
    (println `(hiDisplayForm ',form) fp))
    (close fp))
    (load fileName)
    (deleteFile fileName)))
     
    Jimka, Jan 2, 2006
    #15
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.