# gDialog

Definition: | include xpGUI.e gdx id = gDialog(gdx child, [parent=NULL,] [string [title="",] attributes="", [dword_seq args={},]] bool bEsc=true)
Description: | Creates a dialog element, also known as a window, which contains and manages user interaction with the interface elements. For any (other type of) interface element to be shown, it must ultimately be encapsulated in a dialog. child: the identifier of an interface element. The dialog has only one child. parent: must be specified at creation time, or NULL (/omitted) for top-level windows. title: optional, can also be set via `TITLE="xxx"` in the attributes parameter, or even later. For more information on the attributes and args parameters see gSetAttributes(). bEsc: when true (the default) the dialog is automatically closed when escape is keyed. This is a paranormalised function (see technicalia) Returns the identifier of the created element.
pwa/p2js: | Supported.
See Also: | gShow, gMainLoop, gHide
Example: |
    -- demo\xpGUI\gDialog.exw
    include xpGUI.e
    gdx dlg = gDialog(NULL,"gDialog","SIZE=240x80")
    gShow(dlg)
    gMainLoop()
Notes: | All elements (including menus) must be inside a dialog to interact with the user. An interface element will only be visible if the containing dialog is also visible. Technically the child can be NULL, as shown above, but that is only useful for test/incomplete applications, since (unlike pGUI) there is no way to insert or reparent controls, and besides it is pretty easy to show/hide elements.
Attributes: |
CLOSE_ON_ESCAPE | An alternative way to set the same thing as the bEsc parameter, or to check what it is (replaces IupCloseOnEscape).
DEFAULTENTER DEFAULTESC | NULL, XPG_CLOSE, XPG_IGNORE, or the gdx of the button to be activated (more accurately the ACTION handler of said to be invoked) when the user presses (an otherwise unhandled) Enter/Esc when the keyboard focus is on any control within the dialog. Alternatively (/when there is no suitable button) just use a KEY handler on the dialog. Note that DEFAULTESC takes priority over bEsc/CLOSE_ON_ESCAPE.
? FULLSCREEN | Makes the dialog occupy the whole screen over any system bars in the main monitor. All dialog details, such as title bar, borders, maximize button, etc, are removed. Possible values: YES, NO.
MARGIN, PADDING, EXPAND | There are no such things on a dialog itself, however like all containers a dialog is responsible for handling child margin[s], hence instead specify a MARGIN on the (sole) child for some space around the edges of a dialog, and of course should that be a gH/Vbox additional options GAP and SPACE are also available. EXPAND is meaningless on a gDialog: there is nothing for it to expand into (you may be thinking of RESIZE). A dialog is given a natural size sufficient for its contents, unless explicitly overidden by the SIZE, MINSIZE, and/or MAXSIZE attributes.
? MAXBOX, ? MINBOX, ? MENUBOX | DEV post-v1.. (creation only) Requires a maximize/minimize button/system menu box from the window manager. Default: YES. If RESIZE=NO then MAXBOX will be set to NO. If MENUBOX=NO will also remove the Close button. In Windows MENUBOX=NO will also hide MAXBOX and MINBOX. PL: removes the min|(max/restore)|close buttons (Windows). I need to test it on Linux/GTK In Windows MAXBOX/MINBOX is hidden only if MINBOX/MAXBOX is hidden as well, otherwise it is just disabled.
? MAXIMIZED, MINIMIZED | [Windows Only] (read-only) indicates if the dialog is maximized/minimized. Can be YES or NO.
? PLACEMENT+ | Changes how the dialog will be shown. Values: "FULL", "MAXIMIZED", "MINIMIZED" and "NORMAL". Default: NORMAL. After gShow the attribute is set back to "NORMAL". ?? FULL is similar to FULLSCREEN but only the dialog client area covers the screen area, menu and decorations will be there but out of the screen. Under pwa/p2js MINIMIZED is not supported since that is more likely to be the job of the browser, rather than anything on a tab within the browser.
? RESIZE | DEV post-v1, probably... (creation only) Allows interactively changing the dialog’s size. Default: YES. If RESIZE=NO then MAXBOX will be set to NO.
? SIZE | Dialog’s size. Additionally the following values can also be defined for width and/or height: "FULL": Makes the dialog width (or height) equal to the screen width (or height) "HALF": Makes the dialog width (or height) equal to half the screen width (or height) "THIRD": Makes the dialog width (or height) equal to 1/3 the screen width (or height) "QUARTER": Makes the dialog width (or height) equal to 1/4 of the screen width (or height) "EIGHTH": Makes the dialog width (or height) equal to 1/8 of the screen width (or height) NOTE: the above SIZE values are for gDialog only, they will not work with other controls such as gButton, gBox, or gFrame. The dialog natural size is only considered when the user size is not defined. The setting of the SIZE attribute of a dialog is always accepted, regardless of the minimum size required by its children. ?? For a dialog to have the minimum necessary size to fit all elements contained in it, simply define SIZE to NULL. ? Also if you set SIZE to be used as the initial size of the dialog, its contents will be limited to this size as the minimum size, if you do not want that, then after showing the dialog reset this size to NULL so the dialog can be resized to smaller values. For more information see Layout Management.
TITLE | Dialog’s title. Default: NULL. If you want to remove the title bar you must also set MENUBOX=NO, MAXBOX=NO and MINBOX=NO, before map.
? VISIBLE | (read only) Returns true or false. Calling gShow or gHide for the dialog fairly obviously implicitly updates this attribute.
Also accepted: | ACTIVE, FONT, MAXSIZE, MINSIZE, TIP, Note that ACTIVE and FONT also affect all the controls inside the dialog. ? Drag & Drop attributes and handlers are supported.
Handlers: |
? CLOSE_CB | Called right before the dialog is closed. NB: Will not be invoked when a handler returns XPG_CLOSE, instead the programmer should invoke any necessary routines explicitly.
? COPYDATA_CB | [DEV use ipc instead...] [Windows Only] Called at the first instance, when a second instance is running. Must set the global attribute SINGLEINSTANCE to be called. function copydata_cb(Ihandle ih, atom pCmdLine, integer size) ih: identifier of the element that activated the event. pCmdLine: command line (char*) of the second instance. size: size of the command line string including the null character.
? DROPFILES_CB | [Windows and GTK Only] Event generated when one or more files are dropped in the dialog.
also | KEY: All common handlers are supported. ? Drag & Drop attributes and handlers are supported.
Technicalia | As this is a paranormalised function, with a non-optional child, and with no expectation that you should attempt to memorise this lot, except maybe "cptaab", you can assume that all of the following are potentially perfectly valid, bar the commented out one in the middle, with the fairly obvious restrictions that any parameters must be in strict cptaab-order, and no args without attributes:
                            gDialog(child)
                            gDialog(child, attributes)        -- (NB attributes must contain >=1 ’=’)
                            gDialog(child, attributes, args)
                            gDialog(child, attributes, args, bEsc)
                            gDialog(child, attributes, bEsc)
                            gDialog(child, title)                       -- (NB no ’=’ in [any] title)
                            gDialog(child, title, attributes)
                            gDialog(child, title, attributes, args)
                            gDialog(child, title, attributes, args, bEsc)
                            gDialog(child, title, attributes, bEsc)
                            gDialog(child, title, bEsc)
    --                      gDialog(child, bEsc)                -- (NB invalid/mistreated, see below)
                            gDialog(child, parent)
                            gDialog(child, parent, bEsc)
                            gDialog(child, parent, attributes)
                            gDialog(child, parent, attributes, bEsc)
                            gDialog(child, parent, attributes, args)
                            gDialog(child, parent, attributes, args, bEsc)
                            gDialog(child, parent, title)
                            gDialog(child, parent, title, bEsc)
                            gDialog(child, parent, title, attributes)
                            gDialog(child, parent, title, attributes, bEsc)
                            gDialog(child, parent, title, attributes, args)
                            gDialog(child, parent, title, attributes, args, bEsc)   -- (the full set)
In practice parent, title, attributes, and args are actually defined as object, but manually and thoroughly verified to be of the documented types, after being repositioned via xpGUI.e/paranormalise_ptaab(), which isn’t actually passed the non-optional child parameter. Attempting gDialog(child,bEsc) would be mis-treated as gDialog(child,parent), since false is the same as NULL aka no parent, and true is the same as 1 which could be the valid id of a parent dialog, whereas any and all of the following should be fine: gDialog(child,NULL,bEsc), gDialog(child,"",bEsc), gDialog(child,bEsc:=bEsc), gDialog(child,"CLOSE_ON_ESCAPE=%t",{bEsc}), or even gDialog(child) with a later gSetAttribute(dlg,"CLOSE_ON_ESCAPE",bEsc) Typically only the main dialog on a non-trivial program needs bEsc setting, and it is pretty rare you would not want to specify a title or other attributes, so that one problematic case (child,bEsc) almost never occurs anyway. It should perhaps go without saying, but even in an application such as an editor which would be pretty much unusable if escape closed the main window, there are almost always many more sub-windows where that is the desired behaviour, and it is clearly trivial to override to false when needed, which is why the default for bEsc is true. Unlike pGUI there is no PARENTDIALOG attribute in xpGUI, either global or dialog-specific, so should one be needed it must be specified up-front. It may be necessary to restructure some (legacy) pGUI programs such that the main dialog is created before any child windows, possibly by putting the creation of child dialogs into a subroutine (or two) that are only invoked at or after the point where the old code was trying to set PARENTDIALOG. Likewise there is [as yet] no suppport for reparenting, or any way to insert or append controls, besides it is far easier to show/hide elements, or maybe do that with two otherwise identical dialogs, or perhaps even destroy (not yet implemented) and re-create a dialog. While you can set the dialog title via `TITLE="xxxxxx"` in the attributes parameter, it can also be specified separately, for four simple reasons: it is almost always wanted, you can avoid the "TITLE=" bit, thirdly you can avoid the need for nested quotation marks, especially when there are any spaces involved, and fourthly in quite a few of my demos, at least, the title is a separate constant anyway. Note however that a title specified separately cannot contain an '=' character, since that is used to distinguish it from an attributes string, and the internal paranormalise_ptaab() routine strictly validates that, and further there is no sprintf() shorthand on the title parameter, whereas there is one on the attributes parameter (ie the args parameter). See also this note. You could also set the title much later, in a separate gSetAttribute[s]() call. It is not actually an error to never set it, just fairly unlikely to be what you genuinely want, unless you are hiding the whole title bar, if/when that becomes possible, and even then a hidden name could still prove quite useful for debugging purposes. Note that under WinAPI, xpGUI uses plain windows, not "dialogs", which pretty much must be defined in a resource section, and Phix does not have/use them. While dialogs (and making windows behave more like dialogs) offers lots of goodies, such as tabbing between controls, they take away just as much, such as making VK_ESC look for an IDCANCEL button (and should I define a button, I’d rather give it my own id, thank you very much). In the end, the code that explicitly manages tabbing between controls was needed for GTK as well anyway, since that sometimes gets it quite crazily wrong.