Ask Reuben

Automatic HBOX/VBOX Creation

Why do splitters appear in the middle of my GRID?

I have been involved with Genero for over 20 years but even now there are occasions where I learn of some functionality that when I investigate has been there for a number of years.

In this case a question was asked why were they seeing a splitter that allowed them to resize elements inside a GRID.  We knew that there was the SPLITTER attribute that enabled you to resize stretchable children of HBOX/VBOX but were unaware of such an attribute inside a GRID container.

What we learnt was that there was a feature called “Automatic HBox/VBox with splitter“. and this had been in the product since version 2.02.

So to see this feature, run the sample code at the end of the article.  You will get the following screenshot, you will notice that on the left hand side, there are two splitters.  These can be dragged to alter the size of the adjacent stretchable widgets.


BeforeAfter

The important key factor that leads to the creation of these automatic HBox/VBox and the resulting splitter is that there are two stretchable elements touching each other.  If you don’t want this automatic creation to occur then the simple thing to do is to make sure the elements do not touch each other.  That is either by using ][ instead of | to move the elements apart horizontally, or in the vertical dimension add a blank link in the form file.  Alternatively it maybe that the widgets are stretching when that is not your intent, so add STRETCH=NONE.

Sometimes there is a good reason for this Automatic HBox/VBox creation and resultant splitter not to occur.  With the example, add some titles adjacent to the TEXTEDIT widgets on our form.  You will note that the Automatic VBOX/HBox is not around these titles and hence use of the splitter does not move these titles and so the titles are not next to the intended widget (Field 02 and Field 12)


BeforeAfter

So that is at least one scenario where you would need to code so that the two stretchable widgets are not touching each other, and thus the automatic HBox/VBox creation would not occur.


MAIN
    DEFINE rec RECORD
        field1 STRING,
        field2 STRING,
        field3 STRING,
        field4 STRING,
        field11 STRING,
        field12 STRING,
        field13 STRING,
        field14 STRING,
        dummy STRING -- Have a field that will take the initial focus.  

END RECORD = NULL

DEFINE program_name STRING

    WHENEVER ANY ERROR STOP
    DEFER INTERRUPT
    DEFER QUIT
    OPTIONS FIELD ORDER FORM
    OPTIONS INPUT WRAP

    LET program_name = base.Application.getProgramName()
    CALL ui.Dialog.setDefaultUnbuffered(TRUE)
    CLOSE WINDOW SCREEN

    OPEN WINDOW w WITH FORM  program_name ATTRIBUTES(TEXT=program_name)
    INPUT BY NAME rec.* ATTRIBUTES(WITHOUT DEFAULTS=TRUE)
END MAIN

LAYOUT (TEXT="Automatic HBox/VBox")
VBOX
GRID
{
Input field to take 4gl focus so focus rectangle does not obscure splitter [f99]
}
END
HBOX
GROUP (TEXT="Automatic HBOX Splitter")
GRID
{
[f01         |f02         ]
[            |            ]
}
END
END
GROUP (TEXT="No HBOX Splitter")
GRID
{
[f03         ][f04         ]
[            ][            ]
}
END
END

END

HBOX
GROUP (TEXT="Automatic VBOX  Splitter")
GRID
{
[f11         ]
[            ]
[f12         ]
[            ]
}
END
END
GROUP (TEXT="No VBOX Splitter")
GRID
{
[f13         ]
[            ]

[f14         ]
[            ]
}
END
END
END

END



ATTRIBUTES
TEXTEDIT f01 = formonly.field1, STRETCH=BOTH, PLACEHOLDER="Enter a value";
TEXTEDIT f02 = formonly.field2, STRETCH=BOTH, PLACEHOLDER="Enter a value";
TEXTEDIT f03 = formonly.field3, STRETCH=BOTH, PLACEHOLDER="Enter a value";
TEXTEDIT f04 = formonly.field4, STRETCH=BOTH, PLACEHOLDER="Enter a value";
TEXTEDIT f11 = formonly.field11, STRETCH=BOTH, PLACEHOLDER="Enter a value";
TEXTEDIT f12 = formonly.field12, STRETCH=BOTH, PLACEHOLDER="Enter a value";
TEXTEDIT f13 = formonly.field13, STRETCH=BOTH, PLACEHOLDER="Enter a value";
TEXTEDIT f14 = formonly.field14, STRETCH=BOTH, PLACEHOLDER="Enter a value";

EDIT f99 = formonly.dummy, STRETCH=X;

INSTRUCTIONS
SCREEN RECORD scr(field1, field2, field3, field4, field11, field12, field13, field14);