Re: Multiple Dialogs in BBCSDL

Discussions related to mouse, keyboard, fonts and Graphical User Interface
Hated Moron

Re: Multiple Dialogs in BBCSDL

Post by Hated Moron »

On 14/09/2023 03:10, Daniel Bingamon wrote (cross-posted from the Discussion Group):
My new question regarding dialogs in SDL is more of an advice question.

When using multiple dialogs would it be better to use the CHAIN keyword and open up another dialog in a different program file?

Or is it perfectly alright to have multiple dialogs in one file?
It's perfectly alright to have multiple dialogues in one file, of course; indeed it would be rare for a program to have only one dialogue box. Consider for example SDLIDE.bbc, one of the IDEs supplied with BBCSDL (and the one I prefer, because I wrote it!). It contains dialogue boxes for File Load, Find & Replace, Goto Line, Renumber, Set Font, Set Colours etc.

In fact the BBCSDL dialogue manager (dlglib.bbc) ensures that different dialogue boxes are completely independent, there is (or at least should be) no shared state at all. Of course BBCSDL dialogues are all 'modal', you can only interact with the one which was most recently opened (so is 'on top'). There was a discussion a while ago about how 'modeless' dialogues could be simulated in BBCSDL, but that's more complicated.
I managed to create a dialog that comes up over top the original but when I try to get rid of it the PROCclosedialog doesn't remove the new one.
That's rather concerning. In case you've found a bug can you create a small, but self-contained, program which illustrates the issue please? If there is a bug, using CHAIN would be unlikely to make any difference anyway (the two programs would still be sharing the same dlglib library).
Hated Moron

Re: Multiple Dialogs in BBCSDL

Post by Hated Moron »

On 14/09/2023 11:28, Daniel Bingamon wrote (cross-posted from the Discussion Group):
Russel,
My name is Richard and my surname is Russell (with two Ls). :roll:
I'm list program below to show how these two dialog boxes are working - in the same .bbc file.
I requested a self-contained program (meaning one that I can easily run here); if I run your code I get an 'Invalid channel' error. :(
What you'll see on the main form is that the "Edit Song" is bringing up a dialog box called "Edit Song" that currently has only the "Exit" button.
If you click on "Exit" it will return to the calling dialog but when you move the mouse the "Exit" button from "Edit Song" is still there.
Since I can't run the program I can't comment in much detail, but one thing I do notice is that in your program you call FN_newdialog() multiple times for the same dialogue box; just as in BBC BASIC for Windows you must not do that since it will cause a memory leak at least.

The documentation states: "FN_newdialog: Before you can use a dialogue box, you must first specify its size and title. This should be done only once, typically in an initialisation routine, for each dialogue box your program contains (the dialogue box can subsequently be displayed as many times as you like)".

I would also draw to your attention that the Cross-Reference Utility produces a large number of warnings. That isn't necessarily a problem, it could simply be that you are not adhering to recommended 'good practice' but that otherwise your code is valid. But it does make it more difficult for me to check your code for correctness because that's the first thing I try.

If you can eliminate the 'Invalid channel' error and correct the multiple calls to FN_newdialog() I will take a more detailed look.
Hated Moron

Re: Multiple Dialogs in BBCSDL

Post by Hated Moron »

On 14/09/2023 21:41, Daniel Bingamon wrote (cross-posted from the Discussion Group):
When I click Exit the original dialog appears but as soon as I move the mouse the other dialog is also shown on the screen.
This is happening because you attempt to close a dialogue box from within a button handler for that same dialogue box:

Code: Select all

      DEF PROCexit(D%, I%)
      boolExit = TRUE
      PROC_closedialog(D%)
      ENDPROC
and similarly:

Code: Select all

      DEF PROCEdExit(D%, I%)
      PROC_closedialog(D%)
      PROC_refreshdialog(intHdlg%)
      ENDPROC
Even if the documentation doesn't explicitly say you can't do that, it should be obvious that it's asking for trouble. Once a dialogue box has been closed, no calls to any of its associated routines should be made, but you are returning (via ENDPROC) into one of those routines.

Really you are misusing the FN_setproc() capability. Its purpose is to allow you to take some action when a button is clicked, but that certainly shouldn't include an Exit (more conventionally called Close) button! That should simply be given the standard ID for a Close button, which is 2, and handled when FN_showdialog() returns.

I would remind you that BBCSDL dialogue boxes are modal.

Here is some code which seems to work correctly:

Code: Select all

      REM Beginnings of Electronic Songbook
      INSTALL @lib$ + "dlglib"

      REM!WC Windows Constants:
      ES_NUMBER = 8192
      SS_CENTER = 1
      WS_GROUP = &20000

      REM Set colour palette
      PROC_setdialogpalette
      REM Set font according to platform:
      IF INKEY(-256) = &57 THEN
        *FONT Segoe UI,10
      ELSE
        OSCLI "FONT """ + @lib$ + "FreeMono"",12"
      ENDIF

      REM Adjust caret shape and size according to font:
      VDU 23,0,10,0,0;0;0;         : REM Set start line
      VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line
      VDU 23,0,18,2,0;0;0;         : REM Set caret width

      REM Create the dialogue box 'templates':
      intHdlg% = FN_newdialog("Electric Songbook - BBC Basic Edition By D.Bingamon", 319, 234)
      btnSongEdit% = FN_setproc(PROCeditsong())
      PROC_button(intHdlg%, "Edit Song", btnSongEdit%, 5, 4, 56, 14, WS_GROUP)
      PROC_button(intHdlg%, "Exit", 2, 262, 4, 40, 14, 0)

      intEHdlg% = FN_newdialog("Edit Song", 319, 234)
      PROC_button(intEHdlg%, "Exit", 2, 62, 4, 40, 14, 0)

      REM Open the first dialogue box:
      X% = &FFFFFFFF80000000
      Y% = &FFFFFFFF80000000
      REPEAT
        result% = FN_showdialog(intHdlg%, X%, Y%)
        PROC_getdlgrect(intHdlg%, X%, Y%, W%, H%)
        IF result% = 1 THEN
          PROCdblClkSong(intHdlg%, intSongListCtrlLB%)
        ENDIF
      UNTIL result% <> 1

      PROC_closedialog(intHdlg%)
      END

      REM
      REM ===============================================================================
      REM

      DEF PROCeditsong(D%, I%)
      LOCAL intResult%
      intResult% = FN_showdialog(intEHdlg%, &80000000, &80000000)
      REM Possibly do something with intResult% here
      PROC_closedialog(intEHdlg%)
      ENDPROC
Hated Moron

Re: Multiple Dialogs in BBCSDL

Post by Hated Moron »

Hated Moron wrote: Thu 14 Sep 2023, 22:42 Even if the documentation doesn't explicitly say you can't do that, it should be obvious that it's asking for trouble.
I still think common sense should be a sufficient guide, but for the avoidance of doubt I have now modified the documentation to state explicitly that you must not close the dialogue box within a button handler function for that same dialogue.
Hated Moron

Re: Multiple Dialogs in BBCSDL

Post by Hated Moron »

On 15/09/2023 03:23, Daniel Bingamon wrote (cross-posted from the Discussiom Group):
I will be reading up on the multi-line edit control next and trying it.
Coincidentally I am currently adding programmable tab stops to the multi-line edit control, so if you want that feature it should be coming soon.
I have been quite surprised of the power this BBC Basic code to do quite a lot with so little.
I've had BB4W for a number of years but I haven't had really a lot of time to pursue it. I've had a desire to get this program running in a multi-platform manner and so I decided to give the SDL a try and it's really something.
Thank you. Having to do everything in BASIC code for cross-platform compatibility reasons, including the dialogue manager, certainly forces you to squeeze the most from the language.