diff options
author | Dimitrij <kvarkas@gmail.com> | 2022-10-31 00:45:23 +0300 |
---|---|---|
committer | Dimitrij <kvarkas@gmail.com> | 2022-10-31 00:45:23 +0300 |
commit | 302fb2e8ddea1c993552c9a30c02f41d01ca54a9 (patch) | |
tree | d6cf1b32664296ef2cecda33caeafbe39e6695c1 /dialog.h | |
parent | 59105d9b26363e47f00676bd365b2ac8d4cb536a (diff) | |
parent | 4ff82ab29a22936b78510c68f544a99e677efed3 (diff) |
Diffstat (limited to 'dialog.h')
-rw-r--r-- | dialog.h | 792 |
1 files changed, 411 insertions, 381 deletions
@@ -43,11 +43,12 @@ enum { * included with DEFINE_INTORPTR_FNS defined. This is a total pain, * but such is life. */ -typedef union { void *p; int i; } intorptr; +typedef union { void *p; const void *cp; int i; } intorptr; #ifndef INLINE intorptr I(int i); intorptr P(void *p); +intorptr CP(const void *p); #endif #if defined DEFINE_INTORPTR_FNS || defined INLINE @@ -58,6 +59,7 @@ intorptr P(void *p); #endif PREFIX intorptr I(int i) { intorptr ret; ret.i = i; return ret; } PREFIX intorptr P(void *p) { intorptr ret; ret.p = p; return ret; } +PREFIX intorptr CP(const void *p) { intorptr ret; ret.cp = p; return ret; } #undef PREFIX #endif @@ -73,8 +75,6 @@ PREFIX intorptr P(void *p) { intorptr ret; ret.p = p; return ret; } #define COLUMN_START(field) ( (field) & 0xFFFF ) #define COLUMN_SPAN(field) ( (((field) >> 16) & 0xFFFF) + 1 ) -union control; - /* * The number of event types is being deliberately kept small, on * the grounds that not all platforms might be able to report a @@ -103,326 +103,346 @@ enum { EVENT_SELCHANGE, EVENT_CALLBACK }; -typedef void (*handler_fn)(union control *ctrl, dlgparam *dp, +typedef void (*handler_fn)(dlgcontrol *ctrl, dlgparam *dp, void *data, int event); -#define STANDARD_PREFIX \ - int type; \ - char *label; \ - bool tabdelay; \ - int column; \ - handler_fn handler; \ - intorptr context; \ - intorptr helpctx; \ - union control *align_next_to +struct dlgcontrol { + /* + * Generic fields shared by all the control types. + */ + int type; + /* + * Every control except CTRL_COLUMNS has _some_ sort of label. By + * putting it in the `generic' union as well as everywhere else, + * we avoid having to have an irritating switch statement when we + * go through and deallocate all the memory in a config-box + * structure. + * + * Yes, this does mean that any non-NULL value in this field is + * expected to be dynamically allocated and freeable. + * + * For CTRL_COLUMNS, this field MUST be NULL. + */ + char *label; + /* + * If `delay_taborder' is true, it indicates that this particular + * control should not yet appear in the tab order. A subsequent + * CTRL_TABDELAY entry will place it. + */ + bool delay_taborder; + /* + * Indicate which column(s) this control occupies. This can be + * unpacked into starting column and column span by the COLUMN + * macros above. + */ + int column; + /* + * Most controls need to provide a function which gets called when + * that control's setting is changed, or when the control's + * setting needs initialising. + * + * The `data' parameter points to the writable data being modified + * as a result of the configuration activity; for example, the + * PuTTY `Conf' structure, although not necessarily. + * + * The `dlg' parameter is passed back to the platform- specific + * routines to read and write the actual control state. + */ + handler_fn handler; + /* + * Almost all of the above functions will find it useful to be + * able to store one or two pieces of `void *' or `int' data. + */ + intorptr context, context2; + /* + * For any control, we also allow the storage of a piece of data + * for use by context-sensitive help. For example, on Windows you + * can click the magic question mark and then click a control, and + * help for that control should spring up. Hence, here is a slot + * in which to store per-control data that a particular + * platform-specific driver can use to ensure it brings up the + * right piece of help text. + */ + HelpCtx helpctx; + /* + * Setting this to non-NULL coerces two or more controls to have + * their y-coordinates adjusted so that they can sit alongside + * each other and look nicely aligned, even if they're different + * heights. + * + * Set this field on later controls (in terms of order in the data + * structure), pointing back to earlier ones, so that when each + * control is instantiated, the referred-to one is already there + * to be referred to. + * + * Don't expect this to change the position of the _first_ + * control. Currently, the layout is done one control at a time, + * so that once the first control has been placed, the second one + * can't cause the first one to be retrospectively moved. + */ + dlgcontrol *align_next_to; -union control { /* - * The first possibility in this union is the generic header - * shared by all the structures, which we are therefore allowed - * to access through any one of them. + * Union of further fields specific to each control type. */ - struct { - int type; - /* - * Every control except CTRL_COLUMNS has _some_ sort of - * label. By putting it in the `generic' union as well as - * everywhere else, we avoid having to have an irritating - * switch statement when we go through and deallocate all - * the memory in a config-box structure. - * - * Yes, this does mean that any non-NULL value in this - * field is expected to be dynamically allocated and - * freeable. - * - * For CTRL_COLUMNS, this field MUST be NULL. - */ - char *label; - /* - * If `tabdelay' is non-zero, it indicates that this - * particular control should not yet appear in the tab - * order. A subsequent CTRL_TABDELAY entry will place it. - */ - bool tabdelay; - /* - * Indicate which column(s) this control occupies. This can - * be unpacked into starting column and column span by the - * COLUMN macros above. - */ - int column; - /* - * Most controls need to provide a function which gets - * called when that control's setting is changed, or when - * the control's setting needs initialising. - * - * The `data' parameter points to the writable data being - * modified as a result of the configuration activity; for - * example, the PuTTY `Conf' structure, although not - * necessarily. - * - * The `dlg' parameter is passed back to the platform- - * specific routines to read and write the actual control - * state. - */ - handler_fn handler; - /* - * Almost all of the above functions will find it useful to - * be able to store a piece of `void *' or `int' data. - */ - intorptr context; - /* - * For any control, we also allow the storage of a piece of - * data for use by context-sensitive help. For example, on - * Windows you can click the magic question mark and then - * click a control, and help for that control should spring - * up. Hence, here is a slot in which to store per-control - * data that a particular platform-specific driver can use - * to ensure it brings up the right piece of help text. - */ - intorptr helpctx; - /* - * Setting this to non-NULL coerces two controls to have their - * y-coordinates adjusted so that they can sit alongside each - * other and look nicely aligned, even if they're different - * heights. - * - * Set this field on the _second_ control of the pair (in - * terms of order in the data structure), so that when it's - * instantiated, the first one is already there to be referred - * to. - */ - union control *align_next_to; - } generic; - struct { - STANDARD_PREFIX; - union control *ctrl; - } tabdelay; - struct { - STANDARD_PREFIX; - } text; - struct { - STANDARD_PREFIX; - char shortcut; /* keyboard shortcut */ - /* - * Percentage of the dialog-box width used by the edit box. - * If this is set to 100, the label is on its own line; - * otherwise the label is on the same line as the box - * itself. - */ - int percentwidth; - bool password; /* details of input are hidden */ - /* - * A special case of the edit box is the combo box, which - * has a drop-down list built in. (Note that a _non_- - * editable drop-down list is done as a special case of a - * list box.) - * - * Don't try setting has_list and password on the same - * control; front ends are not required to support that - * combination. - */ - bool has_list; - /* - * Edit boxes tend to need two items of context, so here's - * a spare. - */ - intorptr context2; - } editbox; - struct { - STANDARD_PREFIX; - /* - * `shortcut' here is a single keyboard shortcut which is - * expected to select the whole group of radio buttons. It - * can be NO_SHORTCUT if required, and there is also a way - * to place individual shortcuts on each button; see below. - */ - char shortcut; - /* - * There are separate fields for `ncolumns' and `nbuttons' - * for several reasons. - * - * Firstly, we sometimes want the last of a set of buttons - * to have a longer label than the rest; we achieve this by - * setting `ncolumns' higher than `nbuttons', and the - * layout code is expected to understand that the final - * button should be given all the remaining space on the - * line. This sounds like a ludicrously specific special - * case (if we're doing this sort of thing, why not have - * the general ability to have a particular button span - * more than one column whether it's the last one or not?) - * but actually it's reasonably common for the sort of - * three-way control you get a lot of in PuTTY: `yes' - * versus `no' versus `some more complex way to decide'. - * - * Secondly, setting `nbuttons' higher than `ncolumns' lets - * us have more than one line of radio buttons for a single - * setting. A very important special case of this is - * setting `ncolumns' to 1, so that each button is on its - * own line. - */ - int ncolumns; - int nbuttons; - /* - * This points to a dynamically allocated array of `char *' - * pointers, each of which points to a dynamically - * allocated string. - */ - char **buttons; /* `nbuttons' button labels */ - /* - * This points to a dynamically allocated array of `char' - * giving the individual keyboard shortcuts for each radio - * button. The array may be NULL if none are required. - */ - char *shortcuts; /* `nbuttons' shortcuts; may be NULL */ - /* - * This points to a dynamically allocated array of - * intorptr, giving helpful data for each button. - */ - intorptr *buttondata; /* `nbuttons' entries; may be NULL */ - } radio; - struct { - STANDARD_PREFIX; - char shortcut; - } checkbox; - struct { - STANDARD_PREFIX; - char shortcut; - /* - * At least Windows has the concept of a `default push - * button', which gets implicitly pressed when you hit - * Return even if it doesn't have the input focus. - */ - bool isdefault; - /* - * Also, the reverse of this: a default cancel-type button, - * which is implicitly pressed when you hit Escape. - */ - bool iscancel; - } button; - struct { - STANDARD_PREFIX; - char shortcut; /* keyboard shortcut */ - /* - * Height of the list box, in approximate number of lines. - * If this is zero, the list is a drop-down list. - */ - int height; /* height in lines */ - /* - * If this is set, the list elements can be reordered by - * the user (by drag-and-drop or by Up and Down buttons, - * whatever the per-platform implementation feels - * comfortable with). This is not guaranteed to work on a - * drop-down list, so don't try it! - */ - bool draglist; - /* - * If this is non-zero, the list can have more than one - * element selected at a time. This is not guaranteed to - * work on a drop-down list, so don't try it! - * - * Different non-zero values request slightly different - * types of multi-selection (this may well be meaningful - * only in GTK, so everyone else can ignore it if they - * want). 1 means the list box expects to have individual - * items selected, whereas 2 means it expects the user to - * want to select a large contiguous range at a time. - */ - int multisel; - /* - * Percentage of the dialog-box width used by the list box. - * If this is set to 100, the label is on its own line; - * otherwise the label is on the same line as the box - * itself. Setting this to anything other than 100 is not - * guaranteed to work on a _non_-drop-down list, so don't - * try it! - */ - int percentwidth; - /* - * Some list boxes contain strings that contain tab - * characters. If `ncols' is greater than 0, then - * `percentages' is expected to be non-zero and to contain - * the respective widths of `ncols' columns, which together - * will exactly fit the width of the list box. Otherwise - * `percentages' must be NULL. - * - * There should never be more than one column in a - * drop-down list (one with height==0), because front ends - * may have to implement it as a special case of an - * editable combo box. - */ - int ncols; /* number of columns */ - int *percentages; /* % width of each column */ - /* - * Flag which can be set to false to suppress the horizontal - * scroll bar if a list box entry goes off the right-hand - * side. - */ - bool hscroll; - } listbox; - struct { - STANDARD_PREFIX; - char shortcut; - /* - * `filter' dictates what type of files will be selected by - * default; for example, when selecting private key files - * the file selector would do well to only show .PPK files - * (on those systems where this is the chosen extension). - * - * The precise contents of `filter' are platform-defined, - * unfortunately. The special value NULL means `all files' - * and is always a valid fallback. - * - * Unlike almost all strings in this structure, this value - * is NOT expected to require freeing (although of course - * you can always use ctrl_alloc if you do need to create - * one on the fly). This is because the likely mode of use - * is to define string constants in a platform-specific - * header file, and directly reference those. Or worse, a - * particular platform might choose to cast integers into - * this pointer type... - */ - char const *filter; - /* - * Some systems like to know whether a file selector is - * choosing a file to read or one to write (and possibly - * create). - */ - bool for_writing; - /* - * On at least some platforms, the file selector is a - * separate dialog box, and contains a user-settable title. - * - * This value _is_ expected to require freeing. - */ - char *title; - } fileselect; - struct { - /* In this variant, `label' MUST be NULL. */ - STANDARD_PREFIX; - int ncols; /* number of columns */ - int *percentages; /* % width of each column */ - /* - * Every time this control type appears, exactly one of - * `ncols' and the previous number of columns MUST be one. - * Attempting to allow a seamless transition from a four- - * to a five-column layout, for example, would be way more - * trouble than it was worth. If you must lay things out - * like that, define eight unevenly sized columns and use - * column-spanning a lot. But better still, just don't. - * - * `percentages' may be NULL if ncols==1, to save space. - */ - } columns; - struct { - STANDARD_PREFIX; - char shortcut; - } fontselect; + union { + struct { /* for CTRL_TABDELAY */ + dlgcontrol *ctrl; + } tabdelay; + struct { /* for CTRL_EDITBOX */ + char shortcut; /* keyboard shortcut */ + /* + * Percentage of the dialog-box width used by the edit + * box. If this is set to 100, the label is on its own + * line; otherwise the label is on the same line as the + * box itself. + */ + int percentwidth; + bool password; /* details of input are hidden */ + /* + * A special case of the edit box is the combo box, which + * has a drop-down list built in. (Note that a _non_- + * editable drop-down list is done as a special case of a + * list box.) + * + * Don't try setting has_list and password on the same + * control; front ends are not required to support that + * combination. + */ + bool has_list; + } editbox; + struct { /* for CTRL_RADIO */ + /* + * `shortcut' here is a single keyboard shortcut which is + * expected to select the whole group of radio buttons. It + * can be NO_SHORTCUT if required, and there is also a way + * to place individual shortcuts on each button; see + * below. + */ + char shortcut; + /* + * There are separate fields for `ncolumns' and `nbuttons' + * for several reasons. + * + * Firstly, we sometimes want the last of a set of buttons + * to have a longer label than the rest; we achieve this + * by setting `ncolumns' higher than `nbuttons', and the + * layout code is expected to understand that the final + * button should be given all the remaining space on the + * line. This sounds like a ludicrously specific special + * case (if we're doing this sort of thing, why not have + * the general ability to have a particular button span + * more than one column whether it's the last one or not?) + * but actually it's reasonably common for the sort of + * three-way control you get a lot of in PuTTY: `yes' + * versus `no' versus `some more complex way to decide'. + * + * Secondly, setting `nbuttons' higher than `ncolumns' + * lets us have more than one line of radio buttons for a + * single setting. A very important special case of this + * is setting `ncolumns' to 1, so that each button is on + * its own line. + */ + int ncolumns; + int nbuttons; + /* + * This points to a dynamically allocated array of `char *' + * pointers, each of which points to a dynamically + * allocated string. + */ + char **buttons; /* `nbuttons' button labels */ + /* + * This points to a dynamically allocated array of `char' + * giving the individual keyboard shortcuts for each radio + * button. The array may be NULL if none are required. + */ + char *shortcuts; /* `nbuttons' shortcuts; may be NULL */ + /* + * This points to a dynamically allocated array of + * intorptr, giving helpful data for each button. + */ + intorptr *buttondata; /* `nbuttons' entries; may be NULL */ + } radio; + struct { /* for CTRL_CHECKBOX */ + char shortcut; + } checkbox; + struct { /* for CTRL_BUTTON */ + char shortcut; + /* + * At least Windows has the concept of a `default push + * button', which gets implicitly pressed when you hit + * Return even if it doesn't have the input focus. + */ + bool isdefault; + /* + * Also, the reverse of this: a default cancel-type + * button, which is implicitly pressed when you hit + * Escape. + */ + bool iscancel; + } button; + struct { /* for CTRL_LISTBOX */ + char shortcut; /* keyboard shortcut */ + /* + * Height of the list box, in approximate number of lines. + * If this is zero, the list is a drop-down list. + */ + int height; /* height in lines */ + /* + * If this is set, the list elements can be reordered by + * the user (by drag-and-drop or by Up and Down buttons, + * whatever the per-platform implementation feels + * comfortable with). This is not guaranteed to work on a + * drop-down list, so don't try it! + */ + bool draglist; + /* + * If this is non-zero, the list can have more than one + * element selected at a time. This is not guaranteed to + * work on a drop-down list, so don't try it! + * + * Different non-zero values request slightly different + * types of multi-selection (this may well be meaningful + * only in GTK, so everyone else can ignore it if they + * want). 1 means the list box expects to have individual + * items selected, whereas 2 means it expects the user to + * want to select a large contiguous range at a time. + */ + int multisel; + /* + * Percentage of the dialog-box width used by the list + * box. If this is set to 100, the label is on its own + * line; otherwise the label is on the same line as the + * box itself. Setting this to anything other than 100 is + * not guaranteed to work on a _non_-drop-down list, so + * don't try it! + */ + int percentwidth; + /* + * Some list boxes contain strings that contain tab + * characters. If `ncols' is greater than 0, then + * `percentages' is expected to be non-zero and to contain + * the respective widths of `ncols' columns, which + * together will exactly fit the width of the list box. + * Otherwise `percentages' must be NULL. + * + * There should never be more than one column in a + * drop-down list (one with height==0), because front ends + * may have to implement it as a special case of an + * editable combo box. + */ + int ncols; /* number of columns */ + int *percentages; /* % width of each column */ + /* + * Flag which can be set to false to suppress the + * horizontal scroll bar if a list box entry goes off the + * right-hand side. + */ + bool hscroll; + } listbox; + struct { /* for CTRL_FILESELECT */ + char shortcut; + /* + * `filter' dictates what type of files will be selected + * by default; for example, when selecting private key + * files the file selector would do well to only show .PPK + * files (on those systems where this is the chosen + * extension). + * + * The precise contents of `filter' are platform-defined, + * unfortunately. The special value NULL means `all files' + * and is always a valid fallback. + * + * Unlike almost all strings in this structure, this value + * is NOT expected to require freeing (although of course + * you can always use ctrl_alloc if you do need to create + * one on the fly). This is because the likely mode of use + * is to define string constants in a platform-specific + * header file, and directly reference those. Or worse, a + * particular platform might choose to cast integers into + * this pointer type... + */ + char const *filter; + /* + * Some systems like to know whether a file selector is + * choosing a file to read or one to write (and possibly + * create). + */ + bool for_writing; + /* + * On at least some platforms, the file selector is a + * separate dialog box, and contains a user-settable + * title. + * + * This value _is_ expected to require freeing. + */ + char *title; + /* + * Reduce the file selector to just a single browse + * button. + * + * Normally, a file selector is used to set a config + * option that consists of a file name, so that that file + * will be read or written at run time. In that situation, + * it makes sense to have an edit box showing the + * currently selected file name, and a button to change it + * interactively. + * + * But occasionally a file selector is used to load a file + * _during_ configuration. For example, host CA public + * keys are entered directly into the configuration as + * strings, not stored by reference to a filename; but if + * you have one in a file, you want to be able to load it + * during the lifetime of the CA config box rather than + * awkwardly copy-pasting it. So in that case you just + * want a 'pop up a file chooser' button, and when that + * delivers a file name, you'll deal with it there and + * then and write some other thing (like the file's + * contents) into a nearby edit box. + * + * If you set this flag, then you may not call + * dlg_filesel_set on the file selector at all, because it + * doesn't store a filename. And you can only call + * dlg_filesel_get on it in the handler for EVENT_ACTION, + * which is what will be sent to you when the user has + * used it to choose a filename. + */ + bool just_button; + } fileselect; + struct { /* for CTRL_COLUMNS */ + /* In this variant, `label' MUST be NULL. */ + int ncols; /* number of columns */ + int *percentages; /* % width of each column */ + /* + * Every time this control type appears, exactly one of + * `ncols' and the previous number of columns MUST be one. + * Attempting to allow a seamless transition from a four- + * to a five-column layout, for example, would be way more + * trouble than it was worth. If you must lay things out + * like that, define eight unevenly sized columns and use + * column-spanning a lot. But better still, just don't. + * + * `percentages' may be NULL if ncols==1, to save space. + */ + } columns; + struct { /* for CTRL_FONTSELECT */ + char shortcut; + } fontselect; + struct { /* for CTRL_TEXT */ + /* + * If this is true (the default), the text will wrap on to + * multiple lines. If false, it will stay on the same + * line, with a horizontal scrollbar if necessary. + */ + bool wrap; + } text; + }; }; #undef STANDARD_PREFIX /* - * `controlset' is a container holding an array of `union control' + * `controlset' is a container holding an array of `dlgcontrol' * structures, together with a panel name and a title for the whole * set. In Windows and any similar-looking GUI, each `controlset' * in the config will be a container box within a panel. @@ -435,9 +455,9 @@ struct controlset { char *boxname; /* internal short name of controlset */ char *boxtitle; /* title of container box */ int ncolumns; /* current no. of columns at bottom */ - size_t ncontrols; /* number of `union control' in array */ + size_t ncontrols; /* number of `dlgcontrol' in array */ size_t ctrlsize; /* allocated size of array */ - union control **ctrls; /* actual array */ + dlgcontrol **ctrls; /* actual array */ }; typedef void (*ctrl_freefn_t)(void *); /* used by ctrl_alloc_with_free */ @@ -471,7 +491,7 @@ struct controlset *ctrl_getset(struct controlbox *, const char *path, const char *name, const char *boxtitle); void ctrl_free_set(struct controlset *); -void ctrl_free(union control *); +void ctrl_free(dlgcontrol *); /* * This function works like `malloc', but the memory it returns @@ -490,73 +510,77 @@ void *ctrl_alloc_with_free(struct controlbox *b, size_t size, ctrl_freefn_t freefunc); /* - * Individual routines to create `union control' structures in a controlset. + * Individual routines to create `dlgcontrol' structures in a controlset. * * Most of these routines allow the most common fields to be set * directly, and put default values in the rest. Each one returns a - * pointer to the `union control' it created, so that final tweaks + * pointer to the `dlgcontrol' it created, so that final tweaks * can be made. */ /* `ncolumns' is followed by that many percentages, as integers. */ -union control *ctrl_columns(struct controlset *, int ncolumns, ...); -union control *ctrl_editbox(struct controlset *, const char *label, - char shortcut, int percentage, intorptr helpctx, - handler_fn handler, - intorptr context, intorptr context2); -union control *ctrl_combobox(struct controlset *, const char *label, - char shortcut, int percentage, intorptr helpctx, - handler_fn handler, - intorptr context, intorptr context2); +dlgcontrol *ctrl_columns(struct controlset *, int ncolumns, ...); +dlgcontrol *ctrl_editbox(struct controlset *, const char *label, + char shortcut, int percentage, HelpCtx helpctx, + handler_fn handler, + intorptr context, intorptr context2); +dlgcontrol *ctrl_combobox(struct controlset *, const char *label, + char shortcut, int percentage, HelpCtx helpctx, + handler_fn handler, + intorptr context, intorptr context2); /* * `ncolumns' is followed by (alternately) radio button titles and * intorptrs, until a NULL in place of a title string is seen. Each * title is expected to be followed by a shortcut _iff_ `shortcut' * is NO_SHORTCUT. */ -union control *ctrl_radiobuttons(struct controlset *, const char *label, - char shortcut, int ncolumns, intorptr helpctx, +dlgcontrol *ctrl_radiobuttons_fn(struct controlset *, const char *label, + char shortcut, int ncolumns, HelpCtx helpctx, handler_fn handler, intorptr context, ...); -union control *ctrl_pushbutton(struct controlset *, const char *label, - char shortcut, intorptr helpctx, - handler_fn handler, intorptr context); -union control *ctrl_listbox(struct controlset *, const char *label, - char shortcut, intorptr helpctx, +#define ctrl_radiobuttons(...) \ + ctrl_radiobuttons_fn(__VA_ARGS__, (const char *)NULL) +dlgcontrol *ctrl_pushbutton(struct controlset *, const char *label, + char shortcut, HelpCtx helpctx, handler_fn handler, intorptr context); -union control *ctrl_droplist(struct controlset *, const char *label, - char shortcut, int percentage, intorptr helpctx, - handler_fn handler, intorptr context); -union control *ctrl_draglist(struct controlset *, const char *label, - char shortcut, intorptr helpctx, - handler_fn handler, intorptr context); -union control *ctrl_filesel(struct controlset *, const char *label, - char shortcut, const char *filter, bool write, - const char *title, intorptr helpctx, - handler_fn handler, intorptr context); -union control *ctrl_fontsel(struct controlset *, const char *label, - char shortcut, intorptr helpctx, - handler_fn handler, intorptr context); -union control *ctrl_text(struct controlset *, const char *text, - intorptr helpctx); -union control *ctrl_checkbox(struct controlset *, const char *label, - char shortcut, intorptr helpctx, - handler_fn handler, intorptr context); -union control *ctrl_tabdelay(struct controlset *, union control *); +dlgcontrol *ctrl_listbox(struct controlset *, const char *label, + char shortcut, HelpCtx helpctx, + handler_fn handler, intorptr context); +dlgcontrol *ctrl_droplist(struct controlset *, const char *label, + char shortcut, int percentage, HelpCtx helpctx, + handler_fn handler, intorptr context); +dlgcontrol *ctrl_draglist(struct controlset *, const char *label, + char shortcut, HelpCtx helpctx, + handler_fn handler, intorptr context); +dlgcontrol *ctrl_filesel(struct controlset *, const char *label, + char shortcut, const char *filter, bool write, + const char *title, HelpCtx helpctx, + handler_fn handler, intorptr context); +dlgcontrol *ctrl_fontsel(struct controlset *, const char *label, + char shortcut, HelpCtx helpctx, + handler_fn handler, intorptr context); +dlgcontrol *ctrl_text(struct controlset *, const char *text, + HelpCtx helpctx); +dlgcontrol *ctrl_checkbox(struct controlset *, const char *label, + char shortcut, HelpCtx helpctx, + handler_fn handler, intorptr context); +dlgcontrol *ctrl_tabdelay(struct controlset *, dlgcontrol *); /* * Routines the platform-independent dialog code can call to read * and write the values of controls. */ -void dlg_radiobutton_set(union control *ctrl, dlgparam *dp, int whichbutton); -int dlg_radiobutton_get(union control *ctrl, dlgparam *dp); -void dlg_checkbox_set(union control *ctrl, dlgparam *dp, bool checked); -bool dlg_checkbox_get(union control *ctrl, dlgparam *dp); -void dlg_editbox_set(union control *ctrl, dlgparam *dp, char const *text); -char *dlg_editbox_get(union control *ctrl, dlgparam *dp); /* result must be freed by caller */ +void dlg_radiobutton_set(dlgcontrol *ctrl, dlgparam *dp, int whichbutton); +int dlg_radiobutton_get(dlgcontrol *ctrl, dlgparam *dp); +void dlg_checkbox_set(dlgcontrol *ctrl, dlgparam *dp, bool checked); +bool dlg_checkbox_get(dlgcontrol *ctrl, dlgparam *dp); +void dlg_editbox_set(dlgcontrol *ctrl, dlgparam *dp, char const *text); +char *dlg_editbox_get(dlgcontrol *ctrl, dlgparam *dp); /* result must be freed by caller */ +void dlg_editbox_select_range(dlgcontrol *ctrl, dlgparam *dp, + size_t start, size_t len); /* The `listbox' functions can also apply to combo boxes. */ -void dlg_listbox_clear(union control *ctrl, dlgparam *dp); -void dlg_listbox_del(union control *ctrl, dlgparam *dp, int index); -void dlg_listbox_add(union control *ctrl, dlgparam *dp, char const *text); +void dlg_listbox_clear(dlgcontrol *ctrl, dlgparam *dp); +void dlg_listbox_del(dlgcontrol *ctrl, dlgparam *dp, int index); +void dlg_listbox_add(dlgcontrol *ctrl, dlgparam *dp, char const *text); /* * Each listbox entry may have a numeric id associated with it. * Note that some front ends only permit a string to be stored at @@ -564,44 +588,44 @@ void dlg_listbox_add(union control *ctrl, dlgparam *dp, char const *text); * strings in any listbox then you MUST not assign them different * IDs and expect to get meaningful results back. */ -void dlg_listbox_addwithid(union control *ctrl, dlgparam *dp, +void dlg_listbox_addwithid(dlgcontrol *ctrl, dlgparam *dp, char const *text, int id); -int dlg_listbox_getid(union control *ctrl, dlgparam *dp, int index); +int dlg_listbox_getid(dlgcontrol *ctrl, dlgparam *dp, int index); /* dlg_listbox_index returns <0 if no single element is selected. */ -int dlg_listbox_index(union control *ctrl, dlgparam *dp); -bool dlg_listbox_issel(union control *ctrl, dlgparam *dp, int index); -void dlg_listbox_select(union control *ctrl, dlgparam *dp, int index); -void dlg_text_set(union control *ctrl, dlgparam *dp, char const *text); -void dlg_filesel_set(union control *ctrl, dlgparam *dp, Filename *fn); -Filename *dlg_filesel_get(union control *ctrl, dlgparam *dp); -void dlg_fontsel_set(union control *ctrl, dlgparam *dp, FontSpec *fn); -FontSpec *dlg_fontsel_get(union control *ctrl, dlgparam *dp); +int dlg_listbox_index(dlgcontrol *ctrl, dlgparam *dp); +bool dlg_listbox_issel(dlgcontrol *ctrl, dlgparam *dp, int index); +void dlg_listbox_select(dlgcontrol *ctrl, dlgparam *dp, int index); +void dlg_text_set(dlgcontrol *ctrl, dlgparam *dp, char const *text); +void dlg_filesel_set(dlgcontrol *ctrl, dlgparam *dp, Filename *fn); +Filename *dlg_filesel_get(dlgcontrol *ctrl, dlgparam *dp); +void dlg_fontsel_set(dlgcontrol *ctrl, dlgparam *dp, FontSpec *fn); +FontSpec *dlg_fontsel_get(dlgcontrol *ctrl, dlgparam *dp); /* * Bracketing a large set of updates in these two functions will * cause the front end (if possible) to delay updating the screen * until it's all complete, thus avoiding flicker. */ -void dlg_update_start(union control *ctrl, dlgparam *dp); -void dlg_update_done(union control *ctrl, dlgparam *dp); +void dlg_update_start(dlgcontrol *ctrl, dlgparam *dp); +void dlg_update_done(dlgcontrol *ctrl, dlgparam *dp); /* * Set input focus into a particular control. */ -void dlg_set_focus(union control *ctrl, dlgparam *dp); +void dlg_set_focus(dlgcontrol *ctrl, dlgparam *dp); /* * Change the label text on a control. */ -void dlg_label_change(union control *ctrl, dlgparam *dp, char const *text); +void dlg_label_change(dlgcontrol *ctrl, dlgparam *dp, char const *text); /* * Return the `ctrl' structure for the most recent control that had * the input focus apart from the one mentioned. This is NOT * GUARANTEED to work on all platforms, so don't base any critical * functionality on it! */ -union control *dlg_last_focused(union control *ctrl, dlgparam *dp); +dlgcontrol *dlg_last_focused(dlgcontrol *ctrl, dlgparam *dp); /* * Find out whether a particular control is currently visible. */ -bool dlg_is_visible(union control *ctrl, dlgparam *dp); +bool dlg_is_visible(dlgcontrol *ctrl, dlgparam *dp); /* * During event processing, you might well want to give an error * indication to the user. dlg_beep() is a quick and easy generic @@ -629,9 +653,9 @@ void dlg_end(dlgparam *dp, int value); * dlg_coloursel_start() accepts an RGB triple which is used to * initialise the colour selector to its starting value. */ -void dlg_coloursel_start(union control *ctrl, dlgparam *dp, +void dlg_coloursel_start(dlgcontrol *ctrl, dlgparam *dp, int r, int g, int b); -bool dlg_coloursel_results(union control *ctrl, dlgparam *dp, +bool dlg_coloursel_results(dlgcontrol *ctrl, dlgparam *dp, int *r, int *g, int *b); /* @@ -643,7 +667,7 @@ bool dlg_coloursel_results(union control *ctrl, dlgparam *dp, * If `ctrl' is NULL, _all_ controls in the dialog get refreshed * (for loading or saving entire sets of settings). */ -void dlg_refresh(union control *ctrl, dlgparam *dp); +void dlg_refresh(dlgcontrol *ctrl, dlgparam *dp); /* * Standard helper functions for reading a controlbox structure. @@ -663,3 +687,9 @@ int ctrl_path_elements(const char *path); /* Return the number of matching path elements at the starts of p1 and p2, * or INT_MAX if the paths are identical. */ int ctrl_path_compare(const char *p1, const char *p2); + +/* + * Normalise the align_next_to fields in a controlset so that they + * form a backwards linked list. + */ +void ctrlset_normalise_aligns(struct controlset *s); |