Jump to content
Developer Wiki and Function Reference Links ×

Big Picture Dialog Best Practices?


Recommended Posts

For those of you who regularly use Custom Dialogs and/or Dialog Builder, what do you recommend as Best Practices?

 

Please feel free to go way beyond my novice questions below.

 

1. Where do you run Dialog Builder/create your dialogs?

   a. In the file containing the script you are working on?

   b. In a separate file as part of the project for the script?

   c. In a separate file that you use for "all" of your dialogs?

   d. Something else?

 

2. How do you use the code generated by Dialog Builder?

   a. Copy and Paste into your script?

   b. {$INCLUDE} into your script?

   c. {$INCLUDE} your script into the Dialog Builder generated file?

   d. Something else?

 

3. What type of an Export from Dialog Builder do you do if you are going to just use the code in a VS?

 

4. What type of Export for Dialog Builder do you do if you are going to use the code in a PIO?

 

On an even more basic level, Dialog Builder creates a unable script that does nothing except show the dialog box, ie it has no dialog handler.  It sets up global constants and vars, creates three functions (GetPlugInString, GetStr, GetHelpStr, and then in the main body it creates the actual dialog box.

 

Is it better in an actual (non-trivial) script to put the dialog box creation in a function/procedure of it's own and call that from the main script? Or is there a reason you want the code in the main script?

 

Any other best practices that I should be familiar with?  

 

I would like to simplify creating dialog boxes as much as possible. This is one part of VW that I have never gotten my head around.  Any suggestions are appreciated.

 

  • Like 1
Link to comment

Hi Pat,

   I never use Dialog Builder as I find it much easier to build them by hand. Usually dialogs are pretty simple in structure so hand coding is pretty straight forward. If ever you are interested, I can elaborate, but that seems to be beyond the scope of your questions here.

 

On 11/21/2022 at 7:32 PM, Pat Stanford said:

Is it better in an actual (non-trivial) script to put the dialog box creation in a function/procedure of it's own and call that from the main script? Or is there a reason you want the code in the main script?

 

If my script is really short and the dialog small (<100 lines total) I will usually make the dialog code a procedure and leave it at the top of the program. For larger scripts, I will make the dialog code a procedure/function and place it in its own $INCLUDE file. 

 

For the Dialog Procedure/Function, I structure it as follows:

{ In the MyDialog1 file... }
Function MyDialog1 :Longint;
Const
Var
	Dialog :Longint;

	Function CreateDialogItems(DialogName :String) :Longint;
	{ Create all the elements that are, or may be, displayed in the dialog box. }
	{ Return the DialogID when done. }
	
	Procedure PositionDialogItems(DialogID :Longint);
	{ Define the Control Tree (i.e., positions) of the dialog box elements relative to each other. }

	Procedure AlignDialogItems(DialogID :Longint);
	{ Define the alignment of the dialog box items. }
	{ This section is OPTIONAL, and often not needed. }

	Procedure SetDialogHelpItems(dlogID :Longint; DialogName :String);
	{ Lastly, define the Help Strings that describe each dialog box item. }

	Procedure DialogEventLoop(var item :Longint; data :Longint);
	{ Contains a CASE statement to process events for each editable or control ITEM in the dialog. }
	
BEGIN	{ MyDialog1 }
	DialogID := CreateDialogItems(DialogName);
	PositionDialogItems(DialogID);
	AlignDialogItems(DialogID);
	SetDialogHelpItems(dlogID, DialogName);
	
	if VerifyLayout(DialogID) then 
		MyDialog1 := RunLayoutDialog(DialogID, DialogEventLoop);
END;		{ MyDialog1 }

****************************************

{ In the MAIN program file... }
...
{$INCLUDE  \File Path\MyDialog1.px }
BEGIN	{ main program }
	...
	if (MyDialog1 = 1) then		{ User pressed OK button }
	begin 
		{ continue with your program }
	end;		{ if MyDialog1 }
	...
END;		{ main program }

 

Raymond

  • Like 1
Link to comment

Let's try again.  First, if Andy Dunning or Josh Benghiat chime in, pay attention.  Andy's dialogs are beautiful not only in organization but also in clarity of function.  Josh knows more about VS than anyone outside the mothership.

Second, I love the DialogBuilder.  I cannot conceive of making dialogs without it.  Thinking about doing what Raymond does gives me a headache and chills at the same time.  However, Raymond also makes exquisite dialogs.

Also, Pat, you have my phone number.

So...

 

On 11/21/2022 at 5:32 PM, Pat Stanford said:

1. Where do you run Dialog Builder/create your dialogs?

In a separate file for EACH dialog with a 1:1 design layer. No matter how simple the dialog, since simple dialogs seem to grow and expand to encompass new functionality requests.

 

 

 

On 11/21/2022 at 5:32 PM, Pat Stanford said:

2. How do you use the code generated by Dialog Builder?

"a."  I'm not sure this is the most efficient, but it is the easiest way for me to put it where I want to make it easier think about the organization of my  script.  I do separate the constants out and place them with the other constant declarations at the beginning of the script, but grouped all together between comments identifying them as for what dialog.

 

 

 

On 11/21/2022 at 5:32 PM, Pat Stanford said:

3. What type of an Export from Dialog Builder do you do if you are going to just use the code in a VS?

 

4. What type of Export for Dialog Builder do you do if you are going to use the code in a PIO?

Since I make extensive use of the GetPlugInString() call, I use the VS export for both

image.thumb.png.80451afc7b6094dd769963fc845979ef.png

 

In the resulting dialog:

I use the "Embed Resources into VSO/VST/VSM..." button.  This wonderful functionality allows you to pick your Script/Plug-in file (vso or vsm) in which to embed the strings that label all the buttons and other proscribed text into the "Strings" resources of the command/plug-in definition; this eliminates having to double enter.  (I love this).  However, I do comment in the actual string values next to the "GetPlugInString()" calls.

 

 

 

On 11/21/2022 at 5:32 PM, Pat Stanford said:

Is it better in an actual (non-trivial) script to put the dialog box creation in a function/procedure of it's own and call that from the main script? Or is there a reason you want the code in the main script?

 

Without claiming to be "better", I put the entire creation code, with the exception of constant creation, in a subroutine,  "SetUpDialog", and call that routine later in the code.  I also make the generated functions below Global and not subroutines of the "SetUpDialog" procedure.

 

{==============================================================}
 
    FUNCTION GetStr(ndx :INTEGER) :STRING;
    BEGIN
        GetStr := GetPluginString( kTextStrTableID + ndx - 1 )
    END;

{==============================================================}

    FUNCTION GetHelpStr(ndx :INTEGER) :STRING;
    BEGIN
        GetHelpStr := GetPluginString( kTextStrTableID + ndx + 5 - 1 )
    END;

{==============================================================}

 

 

In general, I feel it is better to compartmentalize code functionality, even if the code is called only once.  It seems to make debugging easier and the the functionality of the code easier to follow.  Also, subroutine effects on global variables are easier to follow.  Unless, of course, your subroutines are liberally sprinkled with said global variables.

 

HTH.

 

 

 

image.png

Link to comment
16 hours ago, Sam Jones said:

Since I make extensive use of the GetPlugInString() call, I use the VS export for both

image.thumb.png.80451afc7b6094dd769963fc845979ef.png

 

In the resulting dialog:

I use the "Embed Resources into VSO/VST/VSM..." button.  This wonderful functionality allows you to pick your Script/Plug-in file (vso or vsm) in which to embed the strings that label all the buttons and other proscribed text into the "Strings" resources of the command/plug-in definition; this eliminates having to double enter.  (I love this).  However, I do comment in the actual string values next to the "GetPlugInString()" calls.

 

 

I forgot to add it also asks for a destination for where to save the code that constructs the dialog.  I copy the text of the saved file into the "SetUpDialog" subroutine of the script/PIO.  Unfortunately, the labeling is poor.  The first ask is for the destination of the creation script file and the second ask is for the choosing of the command in which to embed the string resources.

 

Edited by Sam Jones
  • Like 1
Link to comment

And I forgot to add, be sure to use long descriptive names for the field constants, so that you know what field your code is referring to in all of the calls in the SetupDialog code and the code that you want to create in the dialog handler.

 

For example

{ control IDs for Breakin Edit Dialog}

{Instead of:

kUnnamed1 = 4;

kUnnamed2 = 5;

kUnnamed3 = 6;

kUnnamed4 = 7;

kUnnamed5 = 8;

kUnnamed6 = 9;

kUnnamed7 = 10;

kUnnamed8 = 11;
kUnnamed9 = 12;
}

Use:


kBIInventoryNameLbl   = 4;
kBIistLbl             = 5;
kBIListBx             = 6;
kBILengthsLbl         = 7;
kBILenEditTxt         = 8;
kDeleteSelectedBIsBtn = 9;
kAddBIsBtn            = 10;
kAddBIBtnLbl          = 11;
kSaveBIAsNewBtn       = 12;

 

{Part of the SetupDialog for the  Breakin Edit Dialog}

    BEGIN
        Dialog10 := CreateLayout(GetStr10(3), TRUE, GetStr10(kOK), GetStr10(kCancel));

        {create controls}
        CreateStaticText( Dialog10, kBOInventoryNameLbl, GetStr10(kBOInventoryNameLbl), -1 );
        SetStaticTextStyle( Dialog10, kBOInventoryNameLbl, 3 );
        CreateStaticText( Dialog10, kBIistLbl, GetStr10(kBIistLbl), -1 );
        SetStaticTextStyle( Dialog10, kBIistLbl, 1 );
        CreateListBox( Dialog10, kBIListBx, 30, 15 );
        CreateStaticText( Dialog10, kBILengthsLbl, GetStr10(kBILengthsLbl), -1 );
        SetStaticTextStyle( Dialog10, kBILengthsLbl, 1 );
        CreateEditText( Dialog10, kBILenEditTxt, GetStr10(kBILenEditTxt), 10 );
        CreatePushButton( Dialog10, kDeleteSelectedBIsBtn, GetStr10(kDeleteSelectedBIsBtn) );
        CreatePushButton( Dialog10, kAddBIsBtn, GetStr10(kAddBIsBtn) );
        CreateStaticText( Dialog10, kAddBIBtnLbl, GetStr10(kAddBIBtnLbl), -1 );
        CreateCheckBox( Dialog10, kSaveBIAsNewBtn, GetStr10(kSaveBIAsNewBtn) );

 

 

{Part of the Dialog handler}

        CASE biEditItem OF
            SetupDialogC:
                BEGIN
                    ReNameNum := 0;
                    SetItemText(Dialog10, kBIInventoryNameLbl, CurrInventory);
                    index := 0;
                    WHILE ((BIList[index + 1].Name <> '') & (index < kMaxBreakInKinds)) DO
                        BEGIN
                            AddChoice(Dialog10, kBIListBx, BIList[index + 1].Name, index);
                            index := index + 1;
                        END;
                    SelectChoice(Dialog10, kBIListBx, 0, TRUE);
                    SetItemText(Dialog10, kLenEditTxt, BIList[1].TailLength);
                END; {SetupDialogC}

            kBIListBx:
                BEGIN
                    GetSelectedChoiceInfo(Dialog10, kBIListBx, 0, endSel, gTempStr);
                    ...
                END; {kBIListBx}


            kDeleteSelectedBIsBtn:
                BEGIN
                    FindNumSelected(Dialog10, kBIListBx, numSelected, selItemArray);
                    GetChoiceCount(Dialog10, kBIListBx, numItems);
                    ...
                END; {kDeleteSelectedBIsBtn}

            kAddBIsBtn:
                BEGIN
                    GetChoiceCount(Dialog10, kBIListBx, numItems);
                    GetSelectedChoiceInfo(Dialog10, kBIListBx, 0, endSel, gTempStr);
                    ...
                END; {kAddBIsBtn}

            kOK:
                BEGIN
                    GetSelectedChoiceInfo(Dialog10, kBIListBx, 0, endSel, gTempStr);
                    IF endSel < 0 THEN
                        endSel := 0;
                    GetItemText(Dialog10, kBILenEditTxt, BIList[endSel + 1].TailLength);
                    GetBooleanItem(Dialog10, kSaveBIAsNewBtn, saveAsNew);
                    ...
                END; {kOK}

        END; {CASE biEditItem}

 

 

Edited by Sam Jones
Saved too early
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...