1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00
elinks/src/bfu/checkbox.c
Witold Filipczyk 0fea79cc8f [cflags] Removed -Wno-pointer-sign
Likely some new bugs were introduced by this change.
The long term goal is clean compilation by g++.
2021-01-02 16:20:27 +01:00

175 lines
4.3 KiB
C

/* Checkbox widget handlers. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "elinks.h"
#include "bfu/button.h"
#include "bfu/checkbox.h"
#include "bfu/dialog.h"
#include "bfu/text.h"
#include "intl/gettext/libintl.h"
#include "terminal/draw.h"
#include "terminal/mouse.h"
#include "terminal/terminal.h"
#define CHECKBOX_HEIGHT 1
#define CHECKBOX_LEN 3 /* "[X]" or "(X)" */
#define CHECKBOX_SPACING 1 /* "[X]" + " " + "Label" */
#define CHECKBOX_LS (CHECKBOX_LEN + CHECKBOX_SPACING) /* "[X] " */
void
add_dlg_radio_do(struct dialog *dlg, char *text,
int groupid, int groupnum, int *data)
{
struct widget *widget = &dlg->widgets[dlg->number_of_widgets++];
widget->type = WIDGET_CHECKBOX;
widget->text = text;
widget->datalen = sizeof(*data);
widget->data = (void *) data;
widget->info.checkbox.gid = groupid;
widget->info.checkbox.gnum = groupnum;
}
void
dlg_format_checkbox(struct dialog_data *dlg_data,
struct widget_data *widget_data,
int x, int *y, int w, int *rw,
enum format_align align, int format_only)
{
struct terminal *term = dlg_data->win->term;
char *text = widget_data->widget->text;
set_box(&widget_data->box, x, *y, CHECKBOX_LEN, CHECKBOX_HEIGHT);
if (w <= CHECKBOX_LS) return;
if (text && *text) {
if (rw) *rw -= CHECKBOX_LS;
dlg_format_text_do(dlg_data, text, x + CHECKBOX_LS, y,
w - CHECKBOX_LS, rw,
get_bfu_color(term, "dialog.checkbox-label"),
align, format_only);
if (rw) *rw += CHECKBOX_LS;
}
}
static widget_handler_status_T
display_checkbox(struct dialog_data *dlg_data, struct widget_data *widget_data)
{
struct terminal *term = dlg_data->win->term;
struct color_pair *color;
char *text;
struct el_box *pos = &widget_data->box;
int selected = is_selected_widget(dlg_data, widget_data);
if (selected) {
color = get_bfu_color(term, "dialog.checkbox-selected");
} else {
color = get_bfu_color(term, "dialog.checkbox");
}
if (!color) return EVENT_PROCESSED;
if (widget_data->info.checkbox.checked)
text = widget_data->widget->info.checkbox.gid ? "(X)" : "[X]";
else
text = widget_data->widget->info.checkbox.gid ? "( )" : "[ ]";
draw_dlg_text(dlg_data, pos->x, pos->y, text, CHECKBOX_LEN, 0, color);
if (selected) {
set_dlg_cursor(term, dlg_data, pos->x + 1, pos->y, 1);
set_dlg_window_ptr(dlg_data, dlg_data->win, pos->x, pos->y);
}
return EVENT_PROCESSED;
}
static widget_handler_status_T
init_checkbox(struct dialog_data *dlg_data, struct widget_data *widget_data)
{
int *cdata = (int *) widget_data->cdata;
assert(cdata);
if (widget_data->widget->info.checkbox.gid) {
if (*cdata == widget_data->widget->info.checkbox.gnum)
widget_data->info.checkbox.checked = 1;
} else {
if (*cdata)
widget_data->info.checkbox.checked = 1;
}
return EVENT_PROCESSED;
}
static widget_handler_status_T
mouse_checkbox(struct dialog_data *dlg_data, struct widget_data *widget_data)
{
struct terminal *term = dlg_data->win->term;
struct term_event *ev = dlg_data->term_event;
if (check_mouse_wheel(ev)
|| !check_mouse_position(ev, &widget_data->box))
return EVENT_NOT_PROCESSED;
select_widget(dlg_data, widget_data);
do_not_ignore_next_mouse_event(term);
if (check_mouse_action(ev, B_UP) && widget_data->widget->ops->select)
widget_data->widget->ops->select(dlg_data, widget_data);
return EVENT_PROCESSED;
}
static widget_handler_status_T
select_checkbox(struct dialog_data *dlg_data, struct widget_data *widget_data)
{
if (!widget_data->widget->info.checkbox.gid) {
/* Checkbox. */
int *cdata = (int *) widget_data->cdata;
assert(cdata);
widget_data->info.checkbox.checked = *cdata = !*cdata;
} else {
/* Group of radio buttons. */
struct widget_data *wdata;
foreach_widget(dlg_data, wdata) {
int *cdata = (int *) wdata->cdata;
if (wdata->widget->type != WIDGET_CHECKBOX)
continue;
if (wdata->widget->info.checkbox.gid
!= widget_data->widget->info.checkbox.gid)
continue;
assert(cdata);
*cdata = widget_data->widget->info.checkbox.gnum;
wdata->info.checkbox.checked = 0;
display_widget(dlg_data, wdata);
}
widget_data->info.checkbox.checked = 1;
}
display_widget(dlg_data, widget_data);
return EVENT_PROCESSED;
}
const struct widget_ops checkbox_ops = {
display_checkbox,
init_checkbox,
mouse_checkbox,
NULL,
select_checkbox,
NULL,
};