📄 dialog.c
字号:
(void)va_arg(ap, int); /* char promotes to int in arg lists */
(void)va_arg(ap, intorptr);
}
va_end(ap);
c->radio.nbuttons = i;
if (c->radio.shortcut == NO_SHORTCUT)
c->radio.shortcuts = snewn(c->radio.nbuttons, char);
else
c->radio.shortcuts = NULL;
c->radio.buttons = snewn(c->radio.nbuttons, char *);
c->radio.buttondata = snewn(c->radio.nbuttons, intorptr);
/*
* Second pass along variable argument list to actually fill in
* the structure.
*/
va_start(ap, context);
for (i = 0; i < c->radio.nbuttons; i++) {
c->radio.buttons[i] = dupstr(va_arg(ap, char *));
if (c->radio.shortcut == NO_SHORTCUT)
c->radio.shortcuts[i] = va_arg(ap, int);
/* char promotes to int in arg lists */
c->radio.buttondata[i] = va_arg(ap, intorptr);
}
va_end(ap);
return c;
}
union control *ctrl_pushbutton(struct controlset *s,char *label,char shortcut,
intorptr helpctx, handler_fn handler,
intorptr context)
{
union control *c = ctrl_new(s, CTRL_BUTTON, helpctx, handler, context);
c->button.label = label ? dupstr(label) : NULL;
c->button.shortcut = shortcut;
c->button.isdefault = 0;
c->button.iscancel = 0;
return c;
}
union control *ctrl_listbox(struct controlset *s,char *label,char shortcut,
intorptr helpctx, handler_fn handler,
intorptr context)
{
union control *c = ctrl_new(s, CTRL_LISTBOX, helpctx, handler, context);
c->listbox.label = label ? dupstr(label) : NULL;
c->listbox.shortcut = shortcut;
c->listbox.height = 5; /* *shrug* a plausible default */
c->listbox.draglist = 0;
c->listbox.multisel = 0;
c->listbox.percentwidth = 100;
c->listbox.ncols = 0;
c->listbox.percentages = NULL;
return c;
}
union control *ctrl_droplist(struct controlset *s, char *label, char shortcut,
int percentage, intorptr helpctx,
handler_fn handler, intorptr context)
{
union control *c = ctrl_new(s, CTRL_LISTBOX, helpctx, handler, context);
c->listbox.label = label ? dupstr(label) : NULL;
c->listbox.shortcut = shortcut;
c->listbox.height = 0; /* means it's a drop-down list */
c->listbox.draglist = 0;
c->listbox.multisel = 0;
c->listbox.percentwidth = percentage;
c->listbox.ncols = 0;
c->listbox.percentages = NULL;
return c;
}
union control *ctrl_draglist(struct controlset *s,char *label,char shortcut,
intorptr helpctx, handler_fn handler,
intorptr context)
{
union control *c = ctrl_new(s, CTRL_LISTBOX, helpctx, handler, context);
c->listbox.label = label ? dupstr(label) : NULL;
c->listbox.shortcut = shortcut;
c->listbox.height = 5; /* *shrug* a plausible default */
c->listbox.draglist = 1;
c->listbox.multisel = 0;
c->listbox.percentwidth = 100;
c->listbox.ncols = 0;
c->listbox.percentages = NULL;
return c;
}
union control *ctrl_filesel(struct controlset *s,char *label,char shortcut,
char const *filter, int write, char *title,
intorptr helpctx, handler_fn handler,
intorptr context)
{
union control *c = ctrl_new(s, CTRL_FILESELECT, helpctx, handler, context);
c->fileselect.label = label ? dupstr(label) : NULL;
c->fileselect.shortcut = shortcut;
c->fileselect.filter = filter;
c->fileselect.for_writing = write;
c->fileselect.title = dupstr(title);
return c;
}
union control *ctrl_fontsel(struct controlset *s,char *label,char shortcut,
intorptr helpctx, handler_fn handler,
intorptr context)
{
union control *c = ctrl_new(s, CTRL_FONTSELECT, helpctx, handler, context);
c->fontselect.label = label ? dupstr(label) : NULL;
c->fontselect.shortcut = shortcut;
return c;
}
union control *ctrl_tabdelay(struct controlset *s, union control *ctrl)
{
union control *c = ctrl_new(s, CTRL_TABDELAY, P(NULL), NULL, P(NULL));
c->tabdelay.ctrl = ctrl;
return c;
}
union control *ctrl_text(struct controlset *s, char *text, intorptr helpctx)
{
union control *c = ctrl_new(s, CTRL_TEXT, helpctx, NULL, P(NULL));
c->text.label = dupstr(text);
return c;
}
union control *ctrl_checkbox(struct controlset *s, char *label, char shortcut,
intorptr helpctx, handler_fn handler,
intorptr context)
{
union control *c = ctrl_new(s, CTRL_CHECKBOX, helpctx, handler, context);
c->checkbox.label = label ? dupstr(label) : NULL;
c->checkbox.shortcut = shortcut;
return c;
}
void ctrl_free(union control *ctrl)
{
int i;
sfree(ctrl->generic.label);
switch (ctrl->generic.type) {
case CTRL_RADIO:
for (i = 0; i < ctrl->radio.nbuttons; i++)
sfree(ctrl->radio.buttons[i]);
sfree(ctrl->radio.buttons);
sfree(ctrl->radio.shortcuts);
sfree(ctrl->radio.buttondata);
break;
case CTRL_COLUMNS:
sfree(ctrl->columns.percentages);
break;
case CTRL_LISTBOX:
sfree(ctrl->listbox.percentages);
break;
case CTRL_FILESELECT:
sfree(ctrl->fileselect.title);
break;
}
sfree(ctrl);
}
void dlg_stdradiobutton_handler(union control *ctrl, void *dlg,
void *data, int event)
{
int button;
/*
* For a standard radio button set, the context parameter gives
* offsetof(targetfield, Config), and the extra data per button
* gives the value the target field should take if that button
* is the one selected.
*/
if (event == EVENT_REFRESH) {
for (button = 0; button < ctrl->radio.nbuttons; button++)
if (*(int *)ATOFFSET(data, ctrl->radio.context.i) ==
ctrl->radio.buttondata[button].i)
break;
/* We expected that `break' to happen, in all circumstances. */
assert(button < ctrl->radio.nbuttons);
dlg_radiobutton_set(ctrl, dlg, button);
} else if (event == EVENT_VALCHANGE) {
button = dlg_radiobutton_get(ctrl, dlg);
assert(button >= 0 && button < ctrl->radio.nbuttons);
*(int *)ATOFFSET(data, ctrl->radio.context.i) =
ctrl->radio.buttondata[button].i;
}
}
void dlg_stdcheckbox_handler(union control *ctrl, void *dlg,
void *data, int event)
{
int offset, invert;
/*
* For a standard checkbox, the context parameter gives
* offsetof(targetfield, Config), optionally ORed with
* CHECKBOX_INVERT.
*/
offset = ctrl->checkbox.context.i;
if (offset & CHECKBOX_INVERT) {
offset &= ~CHECKBOX_INVERT;
invert = 1;
} else
invert = 0;
/*
* C lacks a logical XOR, so the following code uses the idiom
* (!a ^ !b) to obtain the logical XOR of a and b. (That is, 1
* iff exactly one of a and b is nonzero, otherwise 0.)
*/
if (event == EVENT_REFRESH) {
dlg_checkbox_set(ctrl,dlg, (!*(int *)ATOFFSET(data,offset) ^ !invert));
} else if (event == EVENT_VALCHANGE) {
*(int *)ATOFFSET(data, offset) = !dlg_checkbox_get(ctrl,dlg) ^ !invert;
}
}
void dlg_stdeditbox_handler(union control *ctrl, void *dlg,
void *data, int event)
{
/*
* The standard edit-box handler expects the main `context'
* field to contain the `offsetof' a field in the structure
* pointed to by `data'. The secondary `context2' field
* indicates the type of this field:
*
* - if context2 > 0, the field is a char array and context2
* gives its size.
* - if context2 == -1, the field is an int and the edit box
* is numeric.
* - if context2 < -1, the field is an int and the edit box is
* _floating_, and (-context2) gives the scale. (E.g. if
* context2 == -1000, then typing 1.2 into the box will set
* the field to 1200.)
*/
int offset = ctrl->editbox.context.i;
int length = ctrl->editbox.context2.i;
if (length > 0) {
char *field = (char *)ATOFFSET(data, offset);
if (event == EVENT_REFRESH) {
dlg_editbox_set(ctrl, dlg, field);
} else if (event == EVENT_VALCHANGE) {
dlg_editbox_get(ctrl, dlg, field, length);
}
} else if (length < 0) {
int *field = (int *)ATOFFSET(data, offset);
char data[80];
if (event == EVENT_REFRESH) {
if (length == -1)
sprintf(data, "%d", *field);
else
sprintf(data, "%g", (double)*field / (double)(-length));
dlg_editbox_set(ctrl, dlg, data);
} else if (event == EVENT_VALCHANGE) {
dlg_editbox_get(ctrl, dlg, data, lenof(data));
if (length == -1)
*field = atoi(data);
else
*field = (int)((-length) * atof(data));
}
}
}
void dlg_stdfilesel_handler(union control *ctrl, void *dlg,
void *data, int event)
{
/*
* The standard file-selector handler expects the `context'
* field to contain the `offsetof' a Filename field in the
* structure pointed to by `data'.
*/
int offset = ctrl->fileselect.context.i;
if (event == EVENT_REFRESH) {
dlg_filesel_set(ctrl, dlg, *(Filename *)ATOFFSET(data, offset));
} else if (event == EVENT_VALCHANGE) {
dlg_filesel_get(ctrl, dlg, (Filename *)ATOFFSET(data, offset));
}
}
void dlg_stdfontsel_handler(union control *ctrl, void *dlg,
void *data, int event)
{
/*
* The standard file-selector handler expects the `context'
* field to contain the `offsetof' a FontSpec field in the
* structure pointed to by `data'.
*/
int offset = ctrl->fontselect.context.i;
if (event == EVENT_REFRESH) {
dlg_fontsel_set(ctrl, dlg, *(FontSpec *)ATOFFSET(data, offset));
} else if (event == EVENT_VALCHANGE) {
dlg_fontsel_get(ctrl, dlg, (FontSpec *)ATOFFSET(data, offset));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -