Merge branch '2608_widget_enhancement'

* 2608_widget_enhancement:
  Make menu always resizable.
  Fixed location of hotlist query dialogs.
  Added D_CENTER flag to query dialog flags
  Workaround for NCurses output routines.
  Allow draw a part of line if some coordinares are out of screen boundaries.
  Allow close help and tree dialogs using ctrl-g shortcut (SIGINT).
  Allow override standard dialog actions in some dialog.
  Don't get dialog hotkey from disabled widget.
  Fixed widget redraw order in dialog.
  Menu hack to keep overlapped widgets order
  Added dlg_set_top_widget() function
  Allow add and remove widgets in runtime.
  Put global mouse coordinates to widgets.
  Fix mouse handling in dialog.
  Ticket #2608: widget enhancements.
This commit is contained in:
Andrew Borodin 2012-03-08 10:38:46 +03:00
commit dba17c8fde
29 changed files with 732 additions and 347 deletions

View File

@ -63,6 +63,7 @@ enum Gpm_Etype
/* Constants returned from the mouse callback */
enum
{
MOU_UNHANDLED = 0,
MOU_NORMAL,
MOU_REPEAT
};

View File

@ -65,12 +65,19 @@
#define CTRL(x) ((x) & 0x1f)
#endif
#define yx_in_screen(y, x) \
(y >= 0 && y < LINES && x >= 0 && x < COLS)
/*** global variables ****************************************************************************/
/*** file scope type declarations ****************************************************************/
/*** file scope variables ************************************************************************/
/* ncurses supports cursor positions only within window */
/* We use our own cursor coordibates to support partially visible widgets */
static int mc_curs_row, mc_curs_col;
/*** file scope functions ************************************************************************/
/* --------------------------------------------------------------------------------------------- */
@ -318,6 +325,19 @@ tty_touch_screen (void)
void
tty_gotoyx (int y, int x)
{
mc_curs_row = y;
mc_curs_col = x;
if (y < 0)
y = 0;
if (y >= LINES)
y = LINES - 1;
if (x < 0)
x = 0;
if (x >= COLS)
x = COLS - 1;
move (y, x);
}
@ -326,35 +346,70 @@ tty_gotoyx (int y, int x)
void
tty_getyx (int *py, int *px)
{
getyx (stdscr, *py, *px);
*py = mc_curs_row;
*px = mc_curs_col;
}
/* --------------------------------------------------------------------------------------------- */
/* if x < 0 or y < 0, draw line starting from current position */
void
tty_draw_hline (int y, int x, int ch, int len)
{
int x1;
if (y < 0 || y >= LINES || x >= COLS)
return;
x1 = x;
if (x < 0)
{
len += x;
if (len <= 0)
return;
x = 0;
}
if ((chtype) ch == ACS_HLINE)
ch = mc_tty_frm[MC_TTY_FRM_HORIZ];
if ((y >= 0) && (x >= 0))
move (y, x);
move (y, x);
hline (ch, len);
move (y, x1);
mc_curs_row = y;
mc_curs_col = x1;
}
/* --------------------------------------------------------------------------------------------- */
/* if x < 0 or y < 0, draw line starting from current position */
void
tty_draw_vline (int y, int x, int ch, int len)
{
int y1;
if (x < 0 || x >= COLS || y >= LINES)
return;
y1 = y;
if (y < 0)
{
len += y;
if (len <= 0)
return;
y = 0;
}
if ((chtype) ch == ACS_VLINE)
ch = mc_tty_frm[MC_TTY_FRM_VERT];
if ((y >= 0) && (x >= 0))
move (y, x);
move (y, x);
vline (ch, len);
move (y1, x);
mc_curs_row = y1;
mc_curs_col = x;
}
/* --------------------------------------------------------------------------------------------- */
@ -396,6 +451,9 @@ tty_fill_region (int y, int x, int rows, int cols, unsigned char ch)
}
move (y, x);
mc_curs_row = y;
mc_curs_col = x;
}
/* --------------------------------------------------------------------------------------------- */
@ -419,7 +477,9 @@ tty_display_8bit (gboolean what)
void
tty_print_char (int c)
{
addch (c);
if (yx_in_screen (mc_curs_row, mc_curs_col))
addch (c);
mc_curs_col++;
}
/* --------------------------------------------------------------------------------------------- */
@ -431,19 +491,37 @@ tty_print_anychar (int c)
if (mc_global.utf8_display || c > 255)
{
int res = g_unichar_to_utf8 (c, (char *) str);
int res;
res = g_unichar_to_utf8 (c, (char *) str);
if (res == 0)
{
str[0] = '.';
str[1] = '\0';
if (yx_in_screen (mc_curs_row, mc_curs_col))
addch ('.');
mc_curs_col++;
}
else
{
const char *s;
str[res] = '\0';
addstr (str_term_form ((char *) str));
s = str_term_form ((char *) str);
if (yx_in_screen (mc_curs_row, mc_curs_col))
addstr (s);
if (g_unichar_iswide (c))
mc_curs_col += 2;
else if (!g_unichar_iszerowidth (c))
mc_curs_col++;
}
}
else
addch (c);
{
if (yx_in_screen (mc_curs_row, mc_curs_col))
addch (c);
mc_curs_col++;
}
}
/* --------------------------------------------------------------------------------------------- */
@ -451,26 +529,31 @@ tty_print_anychar (int c)
void
tty_print_alt_char (int c, gboolean single)
{
if ((chtype) c == ACS_VLINE)
c = mc_tty_frm[single ? MC_TTY_FRM_VERT : MC_TTY_FRM_DVERT];
else if ((chtype) c == ACS_HLINE)
c = mc_tty_frm[single ? MC_TTY_FRM_HORIZ : MC_TTY_FRM_DHORIZ];
else if ((chtype) c == ACS_LTEE)
c = mc_tty_frm[single ? MC_TTY_FRM_LEFTMIDDLE : MC_TTY_FRM_DLEFTMIDDLE];
else if ((chtype) c == ACS_RTEE)
c = mc_tty_frm[single ? MC_TTY_FRM_RIGHTMIDDLE : MC_TTY_FRM_DRIGHTMIDDLE];
else if ((chtype) c == ACS_ULCORNER)
c = mc_tty_frm[single ? MC_TTY_FRM_LEFTTOP : MC_TTY_FRM_DLEFTTOP];
else if ((chtype) c == ACS_LLCORNER)
c = mc_tty_frm[single ? MC_TTY_FRM_LEFTBOTTOM : MC_TTY_FRM_DLEFTBOTTOM];
else if ((chtype) c == ACS_URCORNER)
c = mc_tty_frm[single ? MC_TTY_FRM_RIGHTTOP : MC_TTY_FRM_DRIGHTTOP];
else if ((chtype) c == ACS_LRCORNER)
c = mc_tty_frm[single ? MC_TTY_FRM_RIGHTBOTTOM : MC_TTY_FRM_DRIGHTBOTTOM];
else if ((chtype) c == ACS_PLUS)
c = mc_tty_frm[MC_TTY_FRM_CROSS];
if (yx_in_screen (mc_curs_row, mc_curs_col))
{
if ((chtype) c == ACS_VLINE)
c = mc_tty_frm[single ? MC_TTY_FRM_VERT : MC_TTY_FRM_DVERT];
else if ((chtype) c == ACS_HLINE)
c = mc_tty_frm[single ? MC_TTY_FRM_HORIZ : MC_TTY_FRM_DHORIZ];
else if ((chtype) c == ACS_LTEE)
c = mc_tty_frm[single ? MC_TTY_FRM_LEFTMIDDLE : MC_TTY_FRM_DLEFTMIDDLE];
else if ((chtype) c == ACS_RTEE)
c = mc_tty_frm[single ? MC_TTY_FRM_RIGHTMIDDLE : MC_TTY_FRM_DRIGHTMIDDLE];
else if ((chtype) c == ACS_ULCORNER)
c = mc_tty_frm[single ? MC_TTY_FRM_LEFTTOP : MC_TTY_FRM_DLEFTTOP];
else if ((chtype) c == ACS_LLCORNER)
c = mc_tty_frm[single ? MC_TTY_FRM_LEFTBOTTOM : MC_TTY_FRM_DLEFTBOTTOM];
else if ((chtype) c == ACS_URCORNER)
c = mc_tty_frm[single ? MC_TTY_FRM_RIGHTTOP : MC_TTY_FRM_DRIGHTTOP];
else if ((chtype) c == ACS_LRCORNER)
c = mc_tty_frm[single ? MC_TTY_FRM_RIGHTBOTTOM : MC_TTY_FRM_DRIGHTBOTTOM];
else if ((chtype) c == ACS_PLUS)
c = mc_tty_frm[MC_TTY_FRM_CROSS];
addch (c);
addch (c);
}
mc_curs_col++;
}
/* --------------------------------------------------------------------------------------------- */
@ -478,7 +561,32 @@ tty_print_alt_char (int c, gboolean single)
void
tty_print_string (const char *s)
{
addstr (str_term_form (s));
int len;
int start = 0;
s = str_term_form (s);
len = str_term_width1 (s);
/* line is upper or below the screen or entire line is before or after scrren */
if (mc_curs_row < 0 || mc_curs_row >= LINES || mc_curs_col + len <= 0 || mc_curs_col >= COLS)
{
mc_curs_col += len;
return;
}
/* skip invisible left part */
if (mc_curs_col < 0)
{
start = -mc_curs_col;
len += mc_curs_col;
mc_curs_col = 0;
}
mc_curs_col += len;
if (mc_curs_col >= COLS)
len = COLS - (mc_curs_col - len);
addstr (str_term_substring (s, start, len));
}
/* --------------------------------------------------------------------------------------------- */
@ -487,10 +595,12 @@ void
tty_printf (const char *fmt, ...)
{
va_list args;
char buf[BUF_1K]; /* FIXME: is it enough? */
va_start (args, fmt);
vw_printw (stdscr, fmt, args);
g_vsnprintf (buf, sizeof (buf), fmt, args);
va_end (args);
tty_print_string (buf);
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -509,54 +509,68 @@ tty_getyx (int *py, int *px)
}
/* --------------------------------------------------------------------------------------------- */
/* if x < 0 or y < 0, draw line staring from current position */
void
tty_draw_hline (int y, int x, int ch, int len)
{
int x1;
if (y < 0 || y >= LINES || x >= COLS)
return;
x1 = x;
if (x < 0)
{
len += x;
if (len <= 0)
return;
x = 0;
}
if (ch == ACS_HLINE)
ch = mc_tty_frm[MC_TTY_FRM_HORIZ];
if ((y < 0) || (x < 0))
{
y = SLsmg_get_row ();
x = SLsmg_get_column ();
}
else
SLsmg_gotorc (y, x);
if (ch == 0)
ch = ACS_HLINE;
SLsmg_gotorc (y, x);
if (ch == ACS_HLINE)
SLsmg_draw_hline (len);
else
while (len-- != 0)
tty_print_char (ch);
SLsmg_gotorc (y, x);
SLsmg_gotorc (y, x1);
}
/* --------------------------------------------------------------------------------------------- */
/* if x < 0 or y < 0, draw line staring from current position */
void
tty_draw_vline (int y, int x, int ch, int len)
{
int y1;
if (x < 0 || x >= COLS || y >= LINES)
return;
y1 = y;
if (y < 0)
{
len += y;
if (len <= 0)
return;
y = 0;
}
if (ch == ACS_VLINE)
ch = mc_tty_frm[MC_TTY_FRM_VERT];
if ((y < 0) || (x < 0))
{
y = SLsmg_get_row ();
x = SLsmg_get_column ();
}
else
SLsmg_gotorc (y, x);
if (ch == 0)
ch = ACS_VLINE;
SLsmg_gotorc (y, x);
if (ch == ACS_VLINE)
SLsmg_draw_vline (len);
else
@ -571,7 +585,7 @@ tty_draw_vline (int y, int x, int ch, int len)
}
}
SLsmg_gotorc (y, x);
SLsmg_gotorc (y1, x);
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -177,20 +177,25 @@ tty_print_one_vline (gboolean single)
void
tty_draw_box (int y, int x, int ys, int xs, gboolean single)
{
int y2, x2;
ys--;
xs--;
y2 = y + ys;
x2 = x + xs;
tty_draw_vline (y, x, mc_tty_frm[single ? MC_TTY_FRM_VERT : MC_TTY_FRM_DVERT], ys);
tty_draw_vline (y, x + xs, mc_tty_frm[single ? MC_TTY_FRM_VERT : MC_TTY_FRM_DVERT], ys);
tty_draw_vline (y, x2, mc_tty_frm[single ? MC_TTY_FRM_VERT : MC_TTY_FRM_DVERT], ys);
tty_draw_hline (y, x, mc_tty_frm[single ? MC_TTY_FRM_HORIZ : MC_TTY_FRM_DHORIZ], xs);
tty_draw_hline (y + ys, x, mc_tty_frm[single ? MC_TTY_FRM_HORIZ : MC_TTY_FRM_DHORIZ], xs);
tty_draw_hline (y2, x, mc_tty_frm[single ? MC_TTY_FRM_HORIZ : MC_TTY_FRM_DHORIZ], xs);
tty_gotoyx (y, x);
tty_print_alt_char (ACS_ULCORNER, single);
tty_gotoyx (y + ys, x);
tty_gotoyx (y2, x);
tty_print_alt_char (ACS_LLCORNER, single);
tty_gotoyx (y, x + xs);
tty_gotoyx (y, x2);
tty_print_alt_char (ACS_URCORNER, single);
tty_gotoyx (y + ys, x + xs);
tty_gotoyx (y2, x2);
tty_print_alt_char (ACS_LRCORNER, single);
}

View File

@ -390,7 +390,7 @@ close_error_pipe (int error, const char *text)
if (error_pipe[0] == -1)
return 0;
if (error)
if (error < 0 || (error > 0 && (error & D_ERROR) != 0))
title = MSG_ERROR;
else
title = _("Warning");
@ -398,6 +398,9 @@ close_error_pipe (int error, const char *text)
{
if (dup2 (old_error, 2) == -1)
{
if (error < 0)
error = D_ERROR;
message (error, MSG_ERROR, _("Error dup'ing old error pipe"));
return 1;
}

View File

@ -182,20 +182,21 @@ button_callback (Widget * w, widget_msg_t msg, int parm)
static int
button_event (Gpm_Event * event, void *data)
{
WButton *b = data;
Widget *w = (Widget *) data;
if (!mouse_global_in_widget (event, w))
return MOU_UNHANDLED;
if ((event->type & (GPM_DOWN | GPM_UP)) != 0)
{
Dlg_head *h = b->widget.owner;
dlg_select_widget (b);
dlg_select_widget (w);
if ((event->type & GPM_UP) != 0)
{
button_callback (&b->widget, WIDGET_KEY, ' ');
h->callback (h, &b->widget, DLG_POST_KEY, ' ', NULL);
return MOU_NORMAL;
button_callback (w, WIDGET_KEY, ' ');
w->owner->callback (w->owner, w, DLG_POST_KEY, ' ', NULL);
}
}
return MOU_NORMAL;
}

View File

@ -218,16 +218,23 @@ buttonbar_callback (Widget * w, widget_msg_t msg, int parm)
static int
buttonbar_event (Gpm_Event * event, void *data)
{
WButtonBar *bb = data;
int button;
Widget *w = (Widget *) data;
if (!mouse_global_in_widget (event, w))
return MOU_UNHANDLED;
if ((event->type & GPM_UP) != 0)
{
WButtonBar *bb = (WButtonBar *) data;
Gpm_Event local;
int button;
local = mouse_get_local (event, w);
button = buttonbar_get_button_by_x_coord (bb, local.x - 1);
if (button >= 0)
buttonbar_call (bb, button);
}
if (!(event->type & GPM_UP))
return MOU_NORMAL;
if (event->y == 2)
return MOU_NORMAL;
button = buttonbar_get_button_by_x_coord (bb, event->x - 1);
if (button >= 0)
buttonbar_call (bb, button);
return MOU_NORMAL;
}

View File

@ -108,22 +108,22 @@ check_callback (Widget * w, widget_msg_t msg, int parm)
static int
check_event (Gpm_Event * event, void *data)
{
WCheck *c = data;
Widget *w = data;
Widget *w = (Widget *) data;
if (!mouse_global_in_widget (event, w))
return MOU_UNHANDLED;
if ((event->type & (GPM_DOWN | GPM_UP)) != 0)
{
Dlg_head *h = c->widget.owner;
dlg_select_widget (c);
if (event->type & GPM_UP)
dlg_select_widget (w);
if ((event->type & GPM_UP) != 0)
{
check_callback (w, WIDGET_KEY, ' ');
check_callback (w, WIDGET_FOCUS, 0);
h->callback (h, w, DLG_POST_KEY, ' ', NULL);
return MOU_NORMAL;
w->owner->callback (w->owner, w, DLG_POST_KEY, ' ', NULL);
}
}
return MOU_NORMAL;
}

View File

@ -178,23 +178,22 @@ dlg_read_history (Dlg_head * h)
/* --------------------------------------------------------------------------------------------- */
static int
static gboolean
dlg_unfocus (Dlg_head * h)
{
/* ... but can unfocus disabled widget */
if ((h->current != NULL) && (h->state == DLG_ACTIVE))
/* we can unfocus disabled widget */
if ((h->current != NULL) && (h->state == DLG_CONSTRUCT || h->state == DLG_ACTIVE))
{
Widget *current = (Widget *) h->current->data;
if (send_message (current, WIDGET_UNFOCUS, 0) == MSG_HANDLED)
{
h->callback (h, current, DLG_UNFOCUS, 0, NULL);
return 1;
return TRUE;
}
}
return 0;
return FALSE;
}
/* --------------------------------------------------------------------------------------------- */
@ -343,11 +342,17 @@ static cb_ret_t
dlg_handle_key (Dlg_head * h, int d_key)
{
unsigned long command;
command = keybind_lookup_keymap_command (dialog_map, d_key);
if ((command == CK_IgnoreKey) || (dlg_execute_cmd (h, command) == MSG_NOT_HANDLED))
if (command == CK_IgnoreKey)
return MSG_NOT_HANDLED;
else
if (h->callback (h, NULL, DLG_ACTION, command, NULL) == MSG_HANDLED
|| dlg_execute_cmd (h, command) == MSG_HANDLED)
return MSG_HANDLED;
return MSG_NOT_HANDLED;
}
/* --------------------------------------------------------------------------------------------- */
@ -357,12 +362,12 @@ dlg_mouse_event (Dlg_head * h, Gpm_Event * event)
{
GList *item;
GList *starting_widget = h->current;
Gpm_Event new_event;
int x = event->x;
int y = event->y;
/* close the dialog by mouse click out of dialog area */
if (mouse_close_dialog && !h->fullscreen && ((event->buttons & GPM_B_LEFT) != 0) && ((event->type & GPM_DOWN) != 0) /* left click */
if (mouse_close_dialog && !h->fullscreen && ((event->buttons & GPM_B_LEFT) != 0)
&& ((event->type & GPM_DOWN) != 0) /* left click */
&& !((x > h->x) && (x <= h->x + h->cols) && (y > h->y) && (y <= h->y + h->lines)))
{
h->ret_value = B_CANCEL;
@ -373,26 +378,26 @@ dlg_mouse_event (Dlg_head * h, Gpm_Event * event)
item = starting_widget;
do
{
Widget *widget;
Widget *widget = (Widget *) item->data;
widget = (Widget *) item->data;
item = dlg_widget_next (h, item);
if ((h->flags & DLG_REVERSE) == 0)
item = dlg_widget_prev (h, item);
else
item = dlg_widget_next (h, item);
if (((widget->options & W_DISABLED) == 0)
&& (x > widget->x) && (x <= widget->x + widget->cols)
&& (y > widget->y) && (y <= widget->y + widget->lines))
if ((widget->options & W_DISABLED) == 0 && widget->mouse != NULL)
{
new_event = *event;
new_event.x -= widget->x;
new_event.y -= widget->y;
/* put global cursor position to the widget */
int ret;
if (widget->mouse != NULL)
return widget->mouse (&new_event, widget);
ret = widget->mouse (event, widget);
if (ret != MOU_UNHANDLED)
return ret;
}
}
while (item != starting_widget);
return MOU_NORMAL;
return MOU_UNHANDLED;
}
/* --------------------------------------------------------------------------------------------- */
@ -449,7 +454,7 @@ dlg_try_hotkey (Dlg_head * h, int d_key)
{
current = (Widget *) hot_cur->data;
if ((current->options & W_WANT_HOTKEY) != 0)
if ((current->options & W_WANT_HOTKEY) != 0 && (current->options & W_DISABLED) == 0)
handled = send_message (current, WIDGET_HOTKEY, d_key);
if (handled == MSG_NOT_HANDLED)
@ -759,6 +764,7 @@ create_dlg (gboolean modal, int y1, int x1, int lines, int cols,
Dlg_head *new_d;
new_d = g_new0 (Dlg_head, 1);
new_d->state = DLG_CONSTRUCT;
new_d->modal = modal;
if (colors != NULL)
memmove (new_d->color, colors, sizeof (dlg_colors_t));
@ -773,7 +779,7 @@ create_dlg (gboolean modal, int y1, int x1, int lines, int cols,
new_d->fullscreen = (new_d->x == 0 && new_d->y == 0
&& new_d->cols == COLS && new_d->lines == LINES);
new_d->mouse_status = MOU_NORMAL;
new_d->mouse_status = MOU_UNHANDLED;
/* Strip existing spaces, add one space before and after the title */
if (title != NULL)
@ -832,12 +838,11 @@ set_idle_proc (Dlg_head * d, int enable)
/* --------------------------------------------------------------------------------------------- */
/**
* Insert widget to dialog before current widget. For dialogs populated
* from the bottom, make the widget current. Return widget number.
* Insert widget to dialog before requested widget. Make the widget current. Return widget ID.
*/
int
add_widget_autopos (Dlg_head * h, void *w, widget_pos_flags_t pos_flags)
unsigned long
add_widget_autopos (Dlg_head * h, void *w, widget_pos_flags_t pos_flags, const void *before)
{
Widget *widget = (Widget *) w;
@ -849,14 +854,62 @@ add_widget_autopos (Dlg_head * h, void *w, widget_pos_flags_t pos_flags)
widget->y += h->y;
widget->owner = h;
widget->pos_flags = pos_flags;
widget->id = g_list_length (h->widgets);
widget->id = h->widget_id++;
if ((h->flags & DLG_REVERSE) != 0)
h->widgets = g_list_prepend (h->widgets, widget);
else
h->widgets = g_list_append (h->widgets, widget);
{
if (h->widgets == NULL || before == NULL)
{
h->widgets = g_list_prepend (h->widgets, widget);
h->current = h->widgets;
}
else
{
GList *b;
h->current = h->widgets;
b = g_list_find (h->widgets, before);
/* don't accept widget not from dialog. This shouldn't happen */
if (b == NULL)
abort ();
h->widgets = g_list_insert_before (h->widgets, b, widget);
h->current = g_list_previous (b);
}
}
else
{
if (h->widgets == NULL || before == NULL)
{
h->widgets = g_list_append (h->widgets, widget);
h->current = g_list_last (h->widgets);
}
else
{
GList *b;
b = g_list_find (h->widgets, before);
/* don't accept widget not from dialog. This shouldn't happen */
if (b == NULL)
abort ();
b = g_list_next (b);
h->widgets = g_list_insert_before (h->widgets, b, widget);
if (b != NULL)
h->current = g_list_previous (b);
else
h->current = g_list_last (h->widgets);
}
}
/* widget has been added in runtime */
if (h->state == DLG_ACTIVE)
{
send_message (widget, WIDGET_INIT, 0);
send_message (widget, WIDGET_DRAW, 0);
send_message (widget, WIDGET_FOCUS, 0);
}
return widget->id;
}
@ -864,10 +917,53 @@ add_widget_autopos (Dlg_head * h, void *w, widget_pos_flags_t pos_flags)
/* --------------------------------------------------------------------------------------------- */
/** wrapper to simply add lefttop positioned controls */
int
unsigned long
add_widget (Dlg_head * h, void *w)
{
return add_widget_autopos (h, w, WPOS_KEEP_LEFT | WPOS_KEEP_TOP);
return add_widget_autopos (h, w, WPOS_KEEP_LEFT | WPOS_KEEP_TOP,
h->current != NULL ? h->current->data : NULL);
}
/* --------------------------------------------------------------------------------------------- */
unsigned long
add_widget_before (Dlg_head * h, void *w, void *before)
{
return add_widget_autopos (h, w, WPOS_KEEP_LEFT | WPOS_KEEP_TOP, before);
}
/* --------------------------------------------------------------------------------------------- */
/** delete widget from dialog */
void
del_widget (void *w)
{
Dlg_head *h = ((Widget *) w)->owner;
GList *d;
/* Don't accept NULL widget. This shouldn't happen */
if (w == NULL)
abort ();
d = g_list_find (h->widgets, w);
if (d == h->current)
{
if ((h->flags & DLG_REVERSE) != 0)
h->current = dlg_widget_prev (h, d);
else
h->current = dlg_widget_next (h, d);
}
h->widgets = g_list_remove_link (h->widgets, d);
send_message (d->data, WIDGET_DESTROY, 0);
g_list_free_1 (d);
/* widget has been deleted in runtime */
if (h->state == DLG_ACTIVE)
{
dlg_redraw (h);
dlg_focus (h);
}
}
/* --------------------------------------------------------------------------------------------- */
@ -906,12 +1002,11 @@ dlg_broadcast_msg (Dlg_head * h, widget_msg_t msg, gboolean reverse)
/* --------------------------------------------------------------------------------------------- */
int
gboolean
dlg_focus (Dlg_head * h)
{
/* cannot focus disabled widget ... */
if ((h->current != NULL) && (h->state == DLG_ACTIVE))
/* cannot focus disabled widget */
if ((h->current != NULL) && (h->state == DLG_CONSTRUCT || h->state == DLG_ACTIVE))
{
Widget *current = (Widget *) h->current->data;
@ -919,11 +1014,11 @@ dlg_focus (Dlg_head * h)
&& (send_message (current, WIDGET_FOCUS, 0) == MSG_HANDLED))
{
h->callback (h, current, DLG_FOCUS, 0, NULL);
return 1;
return TRUE;
}
}
return 0;
return FALSE;
}
/* --------------------------------------------------------------------------------------------- */
@ -954,7 +1049,7 @@ find_widget_type (const Dlg_head * h, callback_fn callback)
/** Find the widget with the given id */
Widget *
dlg_find_by_id (const Dlg_head * h, unsigned int id)
dlg_find_by_id (const Dlg_head * h, unsigned long id)
{
GList *w;
@ -966,7 +1061,7 @@ dlg_find_by_id (const Dlg_head * h, unsigned int id)
/** Find the widget with the given id in the dialog h and select it */
void
dlg_select_by_id (const Dlg_head * h, unsigned int id)
dlg_select_by_id (const Dlg_head * h, unsigned long id)
{
Widget *w;
@ -976,7 +1071,7 @@ dlg_select_by_id (const Dlg_head * h, unsigned int id)
}
/* --------------------------------------------------------------------------------------------- */
/*
/**
* Try to select widget in the dialog.
*/
@ -989,6 +1084,36 @@ dlg_select_widget (void *w)
do_select_widget (h, g_list_find (h->widgets, widget), SELECT_EXACT);
}
/* --------------------------------------------------------------------------------------------- */
/**
* Set widget at top of widget list and make it current.
*/
void
dlg_set_top_widget (void *w)
{
Widget *widget = (Widget *) w;
Dlg_head *h = widget->owner;
GList *l;
l = g_list_find (h->widgets, w);
if (l == NULL)
abort (); /* widget is not in dialog, this should not happen */
/* unfocus prevoius widget and focus current one before widget reordering */
if (h->state == DLG_ACTIVE)
do_select_widget (h, l, SELECT_EXACT);
/* widget reordering */
h->widgets = g_list_remove_link (h->widgets, l);
if ((h->flags & DLG_REVERSE) != 0)
h->widgets = g_list_concat (l, h->widgets);
else
h->widgets = g_list_concat (h->widgets, l);
h->current = l;
}
/* --------------------------------------------------------------------------------------------- */
/** Try to select previous widget in the tab order */
@ -1060,7 +1185,7 @@ dlg_redraw (Dlg_head * h)
}
h->callback (h, NULL, DLG_DRAW, 0, NULL);
dlg_broadcast_msg (h, WIDGET_DRAW, TRUE);
dlg_broadcast_msg (h, WIDGET_DRAW, (h->flags & DLG_REVERSE) != 0);
update_cursor (h);
}
@ -1085,7 +1210,7 @@ init_dlg (Dlg_head * h)
top_dlg = g_list_prepend (top_dlg, h);
/* Initialize dialog manager and widgets */
if (h->state == DLG_ACTIVE)
if (h->state == DLG_CONSTRUCT)
{
if (!h->modal)
dialog_switch_add (h);
@ -1095,14 +1220,13 @@ init_dlg (Dlg_head * h)
dlg_read_history (h);
}
h->state = DLG_ACTIVE;
dlg_redraw (h);
/* Select the first widget that takes focus */
while (h->current != NULL && !dlg_focus (h))
h->current = dlg_widget_next (h, h->current);
h->state = DLG_ACTIVE;
dlg_redraw (h);
h->ret_value = 0;
}
@ -1265,7 +1389,8 @@ dlg_replace_widget (Widget * old_w, Widget * new_w)
if (should_focus)
dlg_select_widget (new_w);
send_message (new_w, WIDGET_DRAW, 0);
if (new_w->owner->state == DLG_ACTIVE)
send_message (new_w, WIDGET_DRAW, 0);
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -62,9 +62,10 @@ typedef enum
/* Dialog state */
typedef enum
{
DLG_ACTIVE = 0, /* Dialog is visible and active */
DLG_SUSPENDED = 1, /* Dialog is suspended */
DLG_CLOSED = 2 /* Dialog is closed */
DLG_CONSTRUCT = 0, /* DIalog has been constructed but bot run yet */
DLG_ACTIVE = 1, /* Dialog is visible and active */
DLG_SUSPENDED = 2, /* Dialog is suspended */
DLG_CLOSED = 3 /* Dialog is closed */
} dlg_state_t;
/* Dialog color constants */
@ -122,6 +123,7 @@ struct Dlg_head
/* Internal variables */
GList *widgets; /* widgets list */
GList *current; /* Curently active widget */
unsigned long widget_id; /* maximum id of all widgets */
void *data; /* Data can be passed to dialog */
char *event_group; /* Name of event group for this dialog */
@ -158,8 +160,11 @@ Dlg_head *create_dlg (gboolean modal, int y1, int x1, int lines, int cols,
void dlg_set_default_colors (void);
int add_widget_autopos (Dlg_head * dest, void *w, widget_pos_flags_t pos_flags);
int add_widget (Dlg_head * dest, void *w);
unsigned long add_widget_autopos (Dlg_head * dest, void *w, widget_pos_flags_t pos_flags,
const void *before);
unsigned long add_widget (Dlg_head * dest, void *w);
unsigned long add_widget_before (Dlg_head * h, void *w, void *before);
void del_widget (void *w);
/* sets size of dialog, leaving positioning to automatic mehtods
according to dialog flags */
@ -196,13 +201,14 @@ void dlg_erase (Dlg_head * h);
void dlg_stop (Dlg_head * h);
/* Widget selection */
void dlg_select_widget (void *widget);
void dlg_select_widget (void *w);
void dlg_set_top_widget (void *w);
void dlg_one_up (Dlg_head * h);
void dlg_one_down (Dlg_head * h);
int dlg_focus (Dlg_head * h);
gboolean dlg_focus (Dlg_head * h);
Widget *find_widget_type (const Dlg_head * h, callback_fn callback);
Widget *dlg_find_by_id (const Dlg_head * h, unsigned int id);
void dlg_select_by_id (const Dlg_head * h, unsigned int id);
Widget *dlg_find_by_id (const Dlg_head * h, unsigned long id);
void dlg_select_by_id (const Dlg_head * h, unsigned long id);
/* Redraw all dialogs */
void do_refresh (void);
@ -220,8 +226,9 @@ dlg_widget_active (void *w)
return ((Widget *) w1->owner->current->data == w1);
}
/* --------------------------------------------------------------------------------------------- */
static inline unsigned int
static inline unsigned long
dlg_get_current_widget_id (const struct Dlg_head *h)
{
return ((Widget *) h->current->data)->id;

View File

@ -328,7 +328,7 @@ history_show (GList ** history, Widget * widget)
/* this call makes list stick to all sides of dialog, effectively make
it be resized with dialog */
add_widget_autopos (query_dlg, query_list, WPOS_KEEP_ALL);
add_widget_autopos (query_dlg, query_list, WPOS_KEEP_ALL, NULL);
/* to avoid diplicating of (calculating sizes in two places)
code, call dlg_hist_callback function here, to set dialog and

View File

@ -902,6 +902,10 @@ static int
input_event (Gpm_Event * event, void *data)
{
WInput *in = (WInput *) data;
Widget *w = (Widget *) data;
if (!mouse_global_in_widget (event, w))
return MOU_UNHANDLED;
if ((event->type & GPM_DOWN) != 0)
{
@ -911,19 +915,25 @@ input_event (Gpm_Event * event, void *data)
if ((event->type & (GPM_DOWN | GPM_DRAG)) != 0)
{
dlg_select_widget (in);
Gpm_Event local;
if (event->x >= in->field_width - HISTORY_BUTTON_WIDTH + 1
local = mouse_get_local (event, w);
dlg_select_widget (w);
if (local.x >= in->field_width - HISTORY_BUTTON_WIDTH + 1
&& should_show_history_button (in))
do_show_hist (in);
else
{
in->point = str_length (in->buffer);
if (event->x + in->term_first_shown - 1 < str_term_width1 (in->buffer))
in->point = str_column_to_pos (in->buffer, event->x + in->term_first_shown - 1);
if (local.x + in->term_first_shown - 1 < str_term_width1 (in->buffer))
in->point = str_column_to_pos (in->buffer, local.x + in->term_first_shown - 1);
}
input_update (in, TRUE);
}
/* A lone up mustn't do anything */
if (in->highlight && (event->type & (GPM_UP | GPM_DRAG)) != 0)
return MOU_NORMAL;

View File

@ -434,43 +434,44 @@ listbox_callback (Widget * w, widget_msg_t msg, int parm)
static int
listbox_event (Gpm_Event * event, void *data)
{
WListbox *l = data;
int i;
WListbox *l = (WListbox *) data;
Widget *w = (Widget *) data;
Dlg_head *h = l->widget.owner;
if (!mouse_global_in_widget (event, w))
return MOU_UNHANDLED;
/* Single click */
if (event->type & GPM_DOWN)
if ((event->type & GPM_DOWN) != 0)
dlg_select_widget (l);
if (l->list == NULL)
return MOU_NORMAL;
if (event->type & (GPM_DOWN | GPM_DRAG))
if ((event->type & (GPM_DOWN | GPM_DRAG)) != 0)
{
int ret = MOU_REPEAT;
Gpm_Event local;
int i;
if (event->x < 0 || event->x > l->widget.cols)
return ret;
if (event->y < 1)
for (i = -event->y; i >= 0; i--)
local = mouse_get_local (event, w);
if (local.y < 1)
for (i = -local.y; i >= 0; i--)
listbox_back (l);
else if (event->y > l->widget.lines)
for (i = event->y - l->widget.lines; i > 0; i--)
else if (local.y > w->lines)
for (i = local.y - w->lines; i > 0; i--)
listbox_fwd (l);
else if (event->buttons & GPM_B_UP)
else if ((local.buttons & GPM_B_UP) != 0)
{
listbox_back (l);
ret = MOU_NORMAL;
}
else if (event->buttons & GPM_B_DOWN)
else if ((local.buttons & GPM_B_DOWN) != 0)
{
listbox_fwd (l);
ret = MOU_NORMAL;
}
else
listbox_select_entry (l, listbox_select_pos (l, l->top, event->y - 1));
listbox_select_entry (l, listbox_select_pos (l, l->top, local.y - 1));
/* We need to refresh ourselves since the dialog manager doesn't */
/* know about this event */
@ -481,14 +482,12 @@ listbox_event (Gpm_Event * event, void *data)
/* Double click */
if ((event->type & (GPM_DOUBLE | GPM_UP)) == (GPM_UP | GPM_DOUBLE))
{
Gpm_Event local;
int action;
if (event->x < 0 || event->x >= l->widget.cols
|| event->y < 1 || event->y > l->widget.lines)
return MOU_NORMAL;
local = mouse_get_local (event, w);
dlg_select_widget (l);
listbox_select_entry (l, listbox_select_pos (l, l->top, event->y - 1));
listbox_select_entry (l, listbox_select_pos (l, l->top, local.y - 1));
if (l->callback != NULL)
action = l->callback (l);
@ -497,11 +496,11 @@ listbox_event (Gpm_Event * event, void *data)
if (action == LISTBOX_DONE)
{
h->ret_value = B_ENTER;
dlg_stop (h);
return MOU_NORMAL;
w->owner->ret_value = B_ENTER;
dlg_stop (w->owner);
}
}
return MOU_NORMAL;
}

View File

@ -46,6 +46,8 @@
/*** file scope macro definitions ****************************************************************/
#define RESIZABLE_MENUBAR 1
/*** file scope type declarations ****************************************************************/
/*** file scope variables ************************************************************************/
@ -121,11 +123,14 @@ menubar_paint_idx (WMenuBar * menubar, unsigned int idx, int color)
}
else
{
int yt, xt;
/* menu text */
tty_setcolor (color);
widget_move (&menubar->widget, y, x);
tty_print_char ((unsigned char) entry->first_letter);
tty_draw_hline (-1, -1, ' ', menu->max_entry_len + 2); /* clear line */
tty_getyx (&yt, &xt);
tty_draw_hline (yt, xt, ' ', menu->max_entry_len + 2); /* clear line */
tty_print_string (entry->text.start);
if (entry->text.hotkey != NULL)
@ -233,12 +238,24 @@ menubar_draw (WMenuBar * menubar)
static void
menubar_remove (WMenuBar * menubar)
{
if (menubar->is_dropped)
{
menubar->is_dropped = FALSE;
do_refresh ();
menubar->is_dropped = TRUE;
}
Dlg_head *h;
if (!menubar->is_dropped)
return;
/* HACK: before refresh the dialog, change the current widget to keep the order
of overlapped widgets. This is useful in multi-window editor.
In general, menubar should be a special object, not an ordinary widget
in the current dialog. */
h = menubar->widget.owner;
h->current = g_list_find (h->widgets, dlg_find_by_id (h, menubar->previous_widget));
menubar->is_dropped = FALSE;
do_refresh ();
menubar->is_dropped = TRUE;
/* restore current widget */
h->current = g_list_find (h->widgets, menubar);
}
/* --------------------------------------------------------------------------------------------- */
@ -589,10 +606,15 @@ menubar_callback (Widget * w, widget_msg_t msg, int parm)
static int
menubar_event (Gpm_Event * event, void *data)
{
WMenuBar *menubar = data;
WMenuBar *menubar = (WMenuBar *) data;
Widget *w = (Widget *) data;
gboolean was_active = TRUE;
int left_x, right_x, bottom_y;
Menu *menu;
Gpm_Event local;
if (!mouse_global_in_widget (event, w))
return MOU_UNHANDLED;
/* ignore unsupported events */
if ((event->type & (GPM_UP | GPM_DOWN | GPM_DRAG)) == 0)
@ -604,22 +626,24 @@ menubar_event (Gpm_Event * event, void *data)
if (!menubar->is_dropped)
{
menubar->previous_widget = dlg_get_current_widget_id (menubar->widget.owner);
menubar->previous_widget = dlg_get_current_widget_id (w->owner);
menubar->is_active = TRUE;
menubar->is_dropped = TRUE;
was_active = FALSE;
}
local = mouse_get_local (event, w);
/* Mouse operations on the menubar */
if (event->y == 1 || !was_active)
if (local.y == 1 || !was_active)
{
if ((event->type & GPM_UP) != 0)
if ((local.type & GPM_UP) != 0)
return MOU_NORMAL;
/* wheel events on menubar */
if (event->buttons & GPM_B_UP)
if ((local.buttons & GPM_B_UP) != 0)
menubar_left (menubar);
else if (event->buttons & GPM_B_DOWN)
else if ((local.buttons & GPM_B_DOWN) != 0)
menubar_right (menubar);
else
{
@ -627,8 +651,8 @@ menubar_event (Gpm_Event * event, void *data)
unsigned int new_selection = 0;
while ((new_selection < len)
&& (event->x > ((Menu *) g_list_nth_data (menubar->menu,
new_selection))->start_x))
&& (local.x > ((Menu *) g_list_nth_data (menubar->menu,
new_selection))->start_x))
new_selection++;
if (new_selection != 0) /* Don't set the invalid value -1 */
@ -649,11 +673,11 @@ menubar_event (Gpm_Event * event, void *data)
return MOU_NORMAL;
}
if (!menubar->is_dropped || (event->y < 2))
if (!menubar->is_dropped || (local.y < 2))
return MOU_NORMAL;
/* middle click -- everywhere */
if (((event->buttons & GPM_B_MIDDLE) != 0) && ((event->type & GPM_DOWN) != 0))
if (((local.buttons & GPM_B_MIDDLE) != 0) && ((local.type & GPM_DOWN) != 0))
{
menubar_execute (menubar);
return MOU_NORMAL;
@ -671,18 +695,18 @@ menubar_event (Gpm_Event * event, void *data)
bottom_y = g_list_length (menu->entries) + 3;
if ((event->x >= left_x) && (event->x <= right_x) && (event->y <= bottom_y))
if ((local.x >= left_x) && (local.x <= right_x) && (local.y <= bottom_y))
{
int pos = event->y - 3;
int pos = local.y - 3;
const menu_entry_t *entry = g_list_nth_data (menu->entries, pos);
/* mouse wheel */
if ((event->buttons & GPM_B_UP) && (event->type & GPM_DOWN))
if ((local.buttons & GPM_B_UP) != 0 && (local.type & GPM_DOWN) != 0)
{
menubar_up (menubar);
return MOU_NORMAL;
}
if ((event->buttons & GPM_B_DOWN) && (event->type & GPM_DOWN))
if ((local.buttons & GPM_B_DOWN) != 0 && (local.type & GPM_DOWN) != 0)
{
menubar_down (menubar);
return MOU_NORMAL;
@ -702,10 +726,11 @@ menubar_event (Gpm_Event * event, void *data)
menubar_execute (menubar);
}
}
else
else if (((local.type & GPM_DOWN) != 0) && ((local.buttons & (GPM_B_UP | GPM_B_DOWN)) == 0))
{
/* use click not wheel to close menu */
if (((event->type & GPM_DOWN) != 0) && ((event->buttons & (GPM_B_UP | GPM_B_DOWN)) == 0))
menubar_finish (menubar);
}
return MOU_NORMAL;
}
@ -869,7 +894,10 @@ menubar_arrange (WMenuBar * menubar)
gap -= menu->start_x;
}
gap /= (menubar->menu->len - 1);
if (g_list_next (menubar->menu) == NULL)
gap = 1;
else
gap /= (g_list_length (menubar->menu) - 1);
if (gap <= 0)
{

View File

@ -46,7 +46,7 @@ typedef struct WMenuBar
gboolean is_dropped; /* If the menubar has dropped */
GList *menu; /* The actual menus */
size_t selected; /* Selected menu on the top bar */
int previous_widget; /* Selected widget ID before activating menu */
unsigned long previous_widget; /* Selected widget ID before activating menu */
} WMenuBar;
/*** global variables defined in .c file *********************************************************/

View File

@ -147,22 +147,27 @@ radio_callback (Widget * w, widget_msg_t msg, int parm)
static int
radio_event (Gpm_Event * event, void *data)
{
WRadio *r = data;
Widget *w = data;
Widget *w = (Widget *) data;
if (!mouse_global_in_widget (event, w))
return MOU_UNHANDLED;
if ((event->type & (GPM_DOWN | GPM_UP)) != 0)
{
Dlg_head *h = r->widget.owner;
WRadio *r = (WRadio *) data;
Gpm_Event local;
r->pos = event->y - 1;
dlg_select_widget (r);
local = mouse_get_local (event, w);
r->pos = local.y - 1;
dlg_select_widget (w);
if ((event->type & GPM_UP) != 0)
{
radio_callback (w, WIDGET_KEY, ' ');
h->callback (h, w, DLG_POST_KEY, ' ', NULL);
return MOU_NORMAL;
w->owner->callback (w->owner, w, DLG_POST_KEY, ' ', NULL);
}
}
return MOU_NORMAL;
}

View File

@ -227,3 +227,28 @@ widget_erase (Widget * w)
}
/* --------------------------------------------------------------------------------------------- */
/* get mouse pointer location within widget */
Gpm_Event
mouse_get_local (const Gpm_Event * global, const Widget * w)
{
Gpm_Event local;
local.buttons = global->buttons;
local.x = global->x - w->x;
local.y = global->y - w->y;
local.type = global->type;
return local;
}
/* --------------------------------------------------------------------------------------------- */
gboolean
mouse_global_in_widget (const Gpm_Event * event, const Widget * w)
{
return (event->x > w->x) && (event->y > w->y) && (event->x <= w->x + w->cols)
&& (event->y <= w->y + w->lines);
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -6,7 +6,7 @@
#ifndef MC__WIDGET_INTERNAL_H
#define MC__WIDGET_INTERNAL_H
#include "lib/tty/mouse.h" /* mouse_h */
#include "lib/tty/mouse.h"
/*** typedefs(not structures) and defined constants **********************************************/
@ -124,6 +124,10 @@ void widget_set_size (Widget * widget, int y, int x, int lines, int cols);
void widget_selectcolor (struct Widget *w, gboolean focused, gboolean hotkey);
void widget_erase (Widget * w);
/* get mouse pointer location within widget */
Gpm_Event mouse_get_local (const Gpm_Event * global, const Widget * w);
gboolean mouse_global_in_widget (const Gpm_Event * event, const Widget * w);
/*** inline functions ****************************************************************************/
static inline cb_ret_t

View File

@ -68,6 +68,7 @@ default_query_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm,
switch (msg)
{
case DLG_RESIZE:
if ((h->flags & DLG_CENTER) == 0)
{
Dlg_head *prev_dlg = NULL;
int ypos, xpos;
@ -99,8 +100,10 @@ default_query_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm,
/* set position */
dlg_set_position (h, ypos, xpos, ypos + h->lines, xpos + h->cols);
return MSG_HANDLED;
}
return MSG_HANDLED;
/* fallthrough */
default:
return default_dlg_callback (h, sender, msg, parm, data);
@ -314,7 +317,8 @@ query_dialog (const char *header, const char *text, int flags, int count, ...)
int result = -1;
int cols, lines;
char *cur_name;
const int *query_colors = (flags & D_ERROR) ? alarm_colors : dialog_colors;
const int *query_colors = (flags & D_ERROR) != 0 ? alarm_colors : dialog_colors;
dlg_flags_t dlg_flags = (flags & D_CENTER) != 0 ? (DLG_CENTER | DLG_TRYUP) : DLG_NONE;
if (header == MSG_ERROR)
header = _("Error");
@ -340,7 +344,7 @@ query_dialog (const char *header, const char *text, int flags, int count, ...)
/* prepare dialog */
query_dlg =
create_dlg (TRUE, 0, 0, lines, cols, query_colors, default_query_callback,
"[QueryBox]", header, DLG_NONE);
"[QueryBox]", header, dlg_flags);
if (count > 0)
{

View File

@ -19,7 +19,8 @@
enum
{
D_NORMAL = 0,
D_ERROR = 1
D_ERROR = (1 << 0),
D_CENTER = (1 << 1)
} /* dialog options */ ;
/*** structures declarations (and typedefs of structures)*****************************************/

View File

@ -2847,16 +2847,16 @@ dview_labels (WDiff * dview)
/* --------------------------------------------------------------------------------------------- */
static int
dview_event (Gpm_Event * event, void *x)
dview_event (Gpm_Event * event, void *data)
{
WDiff *dview = (WDiff *) x;
int result = MOU_NORMAL;
WDiff *dview = (WDiff *) data;
/* We are not interested in the release events */
if (!mouse_global_in_widget (event, data))
return MOU_UNHANDLED;
/* We are not interested in release events */
if ((event->type & (GPM_DOWN | GPM_DRAG)) == 0)
{
return result;
}
return MOU_NORMAL;
/* Wheel events */
if ((event->buttons & GPM_B_UP) != 0 && (event->type & GPM_DOWN) != 0)
@ -2872,7 +2872,7 @@ dview_event (Gpm_Event * event, void *x)
dview_update (dview);
}
return result;
return MOU_NORMAL;
}
static gboolean

View File

@ -118,86 +118,88 @@ static int
edit_event (Gpm_Event * event, void *data)
{
WEdit *edit = (WEdit *) data;
Widget *w = (Widget *) data;
Gpm_Event local;
if (!mouse_global_in_widget (event, w))
return MOU_UNHANDLED;
/* Unknown event type */
if (!(event->type & (GPM_DOWN | GPM_DRAG | GPM_UP)))
if ((event->type & (GPM_DOWN | GPM_DRAG | GPM_UP)) == 0)
return MOU_NORMAL;
edit_update_curs_row (edit);
edit_update_curs_col (edit);
/* Outside editor window */
if (event->y < 1 || event->x < 1
|| event->x > edit->widget.cols || event->y > edit->widget.lines)
return MOU_NORMAL;
local = mouse_get_local (event, w);
/* Double click */
if ((event->type & (GPM_DOUBLE | GPM_UP)) == (GPM_UP | GPM_DOUBLE))
if ((local.type & (GPM_DOUBLE | GPM_UP)) == (GPM_UP | GPM_DOUBLE))
{
edit_mark_current_word_cmd (edit);
goto update;
}
#if 0
/* Triple click */
if ((event->type & (GPM_TRIPLE | GPM_UP)) == (GPM_UP | GPM_TRIPLE))
if ((local.type & (GPM_TRIPLE | GPM_UP)) == (GPM_UP | GPM_TRIPLE))
{
edit_mark_current_line_cmd (edit);
goto update;
}
#endif
/* Wheel events */
if ((event->buttons & GPM_B_UP) && (event->type & GPM_DOWN))
if ((local.buttons & GPM_B_UP) != 0 && (local.type & GPM_DOWN) != 0)
{
edit_move_up (edit, 2, 1);
goto update;
}
if ((event->buttons & GPM_B_DOWN) && (event->type & GPM_DOWN))
if ((local.buttons & GPM_B_DOWN) != 0 && (local.type & GPM_DOWN) != 0)
{
edit_move_down (edit, 2, 1);
goto update;
}
/* A lone up mustn't do anything */
if (edit->mark2 != -1 && event->type & (GPM_UP | GPM_DRAG))
if (edit->mark2 != -1 && (local.type & (GPM_UP | GPM_DRAG)) != 0)
return MOU_NORMAL;
if (event->type & (GPM_DOWN | GPM_UP))
if ((local.type & (GPM_DOWN | GPM_UP)) != 0)
edit_push_key_press (edit);
if (!option_cursor_beyond_eol)
edit->prev_col = event->x - edit->start_col - option_line_state_width - 1;
edit->prev_col = local.x - edit->start_col - option_line_state_width - 1;
else
{
long line_len = edit_move_forward3 (edit, edit_bol (edit, edit->curs1), 0,
edit_eol (edit, edit->curs1));
if (event->x > line_len)
if (local.x > line_len)
{
edit->over_col = event->x - line_len - edit->start_col - option_line_state_width - 1;
edit->over_col = local.x - line_len - edit->start_col - option_line_state_width - 1;
edit->prev_col = line_len;
}
else
{
edit->over_col = 0;
edit->prev_col = event->x - option_line_state_width - edit->start_col - 1;
edit->prev_col = local.x - option_line_state_width - edit->start_col - 1;
}
}
--event->y;
if (event->y > edit->curs_row)
edit_move_down (edit, event->y - edit->curs_row, 0);
else if (event->y < edit->curs_row)
edit_move_up (edit, edit->curs_row - event->y, 0);
--local.y;
if (local.y > edit->curs_row)
edit_move_down (edit, local.y - edit->curs_row, 0);
else if (local.y < edit->curs_row)
edit_move_up (edit, edit->curs_row - local.y, 0);
else
edit_move_to_prev_col (edit, edit_bol (edit, edit->curs1));
if (event->type & GPM_DOWN)
if ((local.type & GPM_DOWN) != 0)
{
edit_mark_cmd (edit, 1); /* reset */
edit->highlight = 0;
}
if (!(event->type & GPM_DRAG))
if ((local.type & GPM_DRAG) == 0)
edit_mark_cmd (edit, 0);
update:
@ -283,7 +285,7 @@ edit_dialog_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, vo
return send_message ((Widget *) edit, WIDGET_COMMAND, parm);
if (sender == (Widget *) buttonbar)
return send_message ((Widget *) edit, WIDGET_COMMAND, parm);
return MSG_HANDLED;
return MSG_NOT_HANDLED;
case DLG_VALIDATE:
h->state = DLG_ACTIVE; /* don't stop the dialog before final decision */

View File

@ -788,7 +788,8 @@ init_hotlist (int list_type)
hotlist_but[i].ret_cmd,
hotlist_but[i].flags,
hotlist_but[i].text,
hotlist_button_callback), hotlist_but[i].pos_flags);
hotlist_button_callback), hotlist_but[i].pos_flags,
NULL);
}
/* We add the labels.
@ -796,7 +797,7 @@ init_hotlist (int list_type)
* pname_group will hold name of current group
*/
pname = label_new (UY - 11 + LINES, UX + 2, "");
add_widget_autopos (hotlist_dlg, pname, WPOS_KEEP_BOTTOM | WPOS_KEEP_LEFT);
add_widget_autopos (hotlist_dlg, pname, WPOS_KEEP_BOTTOM | WPOS_KEEP_LEFT, NULL);
if (!hotlist_state.moving)
{
char label_text[BUF_TINY];
@ -804,7 +805,7 @@ init_hotlist (int list_type)
g_snprintf (label_text, sizeof (label_text), " %s ", _("Directory path"));
add_widget_autopos (hotlist_dlg,
label_new (UY - 12 + LINES, UX + 2,
label_text), WPOS_KEEP_BOTTOM | WPOS_KEEP_LEFT);
label_text), WPOS_KEEP_BOTTOM | WPOS_KEEP_LEFT, NULL);
/* This one holds the displayed pathname */
pname_group = label_new (UY, UX + 2, _("Directory label"));
@ -824,7 +825,7 @@ init_hotlist (int list_type)
#endif /* !ENABLE_VFS */
fill_listbox ();
add_widget_autopos (hotlist_dlg, l_hotlist, WPOS_KEEP_ALL);
add_widget_autopos (hotlist_dlg, l_hotlist, WPOS_KEEP_ALL, NULL);
/* add listbox to the dialogs */
}
@ -1232,10 +1233,11 @@ remove_from_hotlist (struct hotlist *entry)
if (safe_delete)
query_set_sel (1);
g_snprintf (text, sizeof (text), _("Are you sure you want to remove entry \"%s\"?"),
str_trunc (entry->label, 30));
result = query_dialog (Q_ ("DialogTitle|Delete"), text, D_ERROR, 2, _("&Yes"), _("&No"));
result = query_dialog (Q_ ("DialogTitle|Delete"), text, D_ERROR | D_CENTER, 2,
_("&Yes"), _("&No"));
if (result != 0)
return;
}
@ -1251,9 +1253,8 @@ remove_from_hotlist (struct hotlist *entry)
g_snprintf (text, sizeof (text), _("Group \"%s\" is not empty.\nRemove it?"),
str_trunc (entry->label, 30));
result = query_dialog (Q_ ("DialogTitle|Delete"), text, D_ERROR, 2, _("&Yes"), _("&No"));
result = query_dialog (Q_ ("DialogTitle|Delete"), text, D_ERROR | D_CENTER, 2,
_("&Yes"), _("&No"));
if (result != 0)
return;
}

View File

@ -321,14 +321,17 @@ info_callback (Widget * w, widget_msg_t msg, int parm)
static int
info_event (Gpm_Event * event, void *data)
{
Widget *w = &((WInfo *) data)->widget;
Widget *w = (Widget *) data;
Gpm_Event local;
if (!mouse_global_in_widget (event, w))
return MOU_UNHANDLED;
local = mouse_get_local (event, w);
/* rest of the upper frame, the menu is invisible - call menu */
if (event->type & GPM_DOWN && event->y == 1 && !menubar_visible)
{
event->x += w->x;
if ((local.type & GPM_DOWN) != 0 && local.y == 1 && !menubar_visible)
return the_menubar->widget.mouse (event, the_menubar);
}
return MOU_NORMAL;
}

View File

@ -864,7 +864,12 @@ format_file (char *dest, int limit, WPanel * panel, int file_index, int width, i
}
if (length < width)
tty_draw_hline (-1, -1, ' ', width - length);
{
int y, x;
tty_getyx (&y, &x);
tty_draw_hline (y, x, ' ', width - length);
}
return res;
}
@ -1583,7 +1588,12 @@ paint_frame (WPanel * panel)
g_string_free (format_txt, TRUE);
if (width > 0)
tty_draw_hline (-1, -1, ' ', width);
{
int y, x;
tty_getyx (&y, &x);
tty_draw_hline (y, x, ' ', width);
}
}
if (panel->list_type != list_long)
@ -1896,7 +1906,6 @@ mini_status_format (WPanel * panel)
switch (panel->list_type)
{
case list_long:
return "full perm space nlink space owner space group space size space mtime space name";
@ -3445,18 +3454,18 @@ mouse_set_mark (WPanel * panel)
/* --------------------------------------------------------------------------------------------- */
static int
static gboolean
mark_if_marking (WPanel * panel, Gpm_Event * event)
{
if (event->buttons & GPM_B_RIGHT)
if ((event->buttons & GPM_B_RIGHT) != 0)
{
if (event->type & GPM_DOWN)
if ((event->type & GPM_DOWN) != 0)
mouse_toggle_mark (panel);
else
mouse_set_mark (panel);
return 1;
return TRUE;
}
return 0;
return FALSE;
}
/* --------------------------------------------------------------------------------------------- */
@ -3522,43 +3531,46 @@ mouse_sort_col (Gpm_Event * event, WPanel * panel)
* Mouse callback of the panel minus repainting.
* If the event is redirected to the menu, *redir is set to TRUE.
*/
static int
static inline int
do_panel_event (Gpm_Event * event, WPanel * panel, gboolean * redir)
{
const int lines = llines (panel);
const gboolean is_active = dlg_widget_active (panel);
const gboolean mouse_down = (event->type & GPM_DOWN) != 0;
Widget *w = (Widget *) panel;
Gpm_Event local;
*redir = FALSE;
local = mouse_get_local (event, w);
/* 1st line */
if (mouse_down && event->y == 1)
if (mouse_down && local.y == 1)
{
/* "<" button */
if (event->x == 2)
if (local.x == 2)
{
directory_history_prev (panel);
return MOU_NORMAL;
}
/* "." button show/hide hidden files */
if (event->x == panel->widget.cols - 5)
if (local.x == panel->widget.cols - 5)
{
panel->widget.owner->callback (panel->widget.owner, NULL,
DLG_ACTION, CK_ShowHidden, NULL);
midnight_dlg->callback (midnight_dlg, NULL, DLG_ACTION, CK_ShowHidden, NULL);
repaint_screen ();
return MOU_NORMAL;
}
/* ">" button */
if (event->x == panel->widget.cols - 1)
if (local.x == panel->widget.cols - 1)
{
directory_history_next (panel);
return MOU_NORMAL;
}
/* "^" button */
if (event->x >= panel->widget.cols - 4 && event->x <= panel->widget.cols - 2)
if (local.x >= panel->widget.cols - 4 && local.x <= panel->widget.cols - 2)
{
directory_history_list (panel);
return MOU_NORMAL;
@ -3568,7 +3580,6 @@ do_panel_event (Gpm_Event * event, WPanel * panel, gboolean * redir)
if (!menubar_visible)
{
*redir = TRUE;
event->x += panel->widget.x;
return the_menubar->widget.mouse (event, the_menubar);
}
@ -3577,14 +3588,14 @@ do_panel_event (Gpm_Event * event, WPanel * panel, gboolean * redir)
}
/* sort on clicked column; don't handle wheel events */
if (mouse_down && (event->buttons & (GPM_B_UP | GPM_B_DOWN)) == 0 && event->y == 2)
if (mouse_down && (local.buttons & (GPM_B_UP | GPM_B_DOWN)) == 0 && local.y == 2)
{
mouse_sort_col (event, panel);
return MOU_NORMAL;
}
/* Mouse wheel events */
if (mouse_down && (event->buttons & GPM_B_UP))
if (mouse_down && (local.buttons & GPM_B_UP) != 0)
{
if (is_active)
{
@ -3596,7 +3607,7 @@ do_panel_event (Gpm_Event * event, WPanel * panel, gboolean * redir)
return MOU_NORMAL;
}
if (mouse_down && (event->buttons & GPM_B_DOWN))
if (mouse_down && (local.buttons & GPM_B_DOWN) != 0)
{
if (is_active)
{
@ -3608,20 +3619,20 @@ do_panel_event (Gpm_Event * event, WPanel * panel, gboolean * redir)
return MOU_NORMAL;
}
event->y -= 2;
if ((event->type & (GPM_DOWN | GPM_DRAG)))
local.y -= 2;
if ((local.type & (GPM_DOWN | GPM_DRAG)) != 0)
{
int my_index;
if (!is_active)
change_panel ();
if (panel->top_file + event->y > panel->count)
if (panel->top_file + local.y > panel->count)
my_index = panel->count - 1;
else
{
my_index = panel->top_file + event->y - 1;
if (panel->split && (event->x > ((panel->widget.cols - 2) / 2)))
my_index = panel->top_file + local.y - 1;
if (panel->split && (local.x > ((panel->widget.cols - 2) / 2)))
my_index += llines (panel);
if (my_index >= panel->count)
@ -3636,13 +3647,14 @@ do_panel_event (Gpm_Event * event, WPanel * panel, gboolean * redir)
}
/* This one is new */
mark_if_marking (panel, event);
mark_if_marking (panel, &local);
}
else if ((event->type & (GPM_UP | GPM_DOUBLE)) == (GPM_UP | GPM_DOUBLE))
else if ((local.type & (GPM_UP | GPM_DOUBLE)) == (GPM_UP | GPM_DOUBLE))
{
if (event->y > 0 && event->y <= lines)
if (local.y > 0 && local.y <= lines)
do_enter (panel);
}
return MOU_NORMAL;
}
@ -3652,10 +3664,13 @@ do_panel_event (Gpm_Event * event, WPanel * panel, gboolean * redir)
static int
panel_event (Gpm_Event * event, void *data)
{
WPanel *panel = data;
WPanel *panel = (WPanel *) data;
int ret;
gboolean redir;
if (!mouse_global_in_widget (event, (Widget *) data))
return MOU_UNHANDLED;
ret = do_panel_event (event, panel, &redir);
if (!redir)
send_message ((Widget *) panel, WIDGET_DRAW, 0);

View File

@ -580,10 +580,10 @@ tree_move_to_bottom (WTree * tree)
}
/* --------------------------------------------------------------------------------------------- */
/** Handle mouse click */
/** Handle mouse click */
static void
tree_event (WTree * tree, int y)
tree_mouse_click (WTree * tree, int y)
{
if (tree->tree_shown[y])
{
@ -630,46 +630,49 @@ maybe_chdir (WTree * tree)
/** Mouse callback */
static int
event_callback (Gpm_Event * event, void *data)
tree_event (Gpm_Event * event, void *data)
{
WTree *tree = data;
WTree *tree = (WTree *) data;
Widget *w = (Widget *) data;
Gpm_Event local;
if (!mouse_global_in_widget (event, w))
return MOU_UNHANDLED;
local = mouse_get_local (event, w);
/* rest of the upper frame, the menu is invisible - call menu */
if (tree->is_panel && (event->type & GPM_DOWN) && event->y == 1 && !menubar_visible)
{
event->x += tree->widget.x;
if (tree->is_panel && (local.type & GPM_DOWN) != 0 && local.y == 1 && !menubar_visible)
return the_menubar->widget.mouse (event, the_menubar);
}
if (!(event->type & GPM_UP))
if ((local.type & GPM_UP) == 0)
return MOU_NORMAL;
if (tree->is_panel)
event->y--;
local.y--;
event->y--;
local.y--;
if (!tree->active)
change_panel ();
if (event->y < 0)
if (local.y < 0)
{
tree_move_backward (tree, tlines (tree) - 1);
show_tree (tree);
}
else if (event->y >= tlines (tree))
else if (local.y >= tlines (tree))
{
tree_move_forward (tree, tlines (tree) - 1);
show_tree (tree);
}
else
{
tree_event (tree, event->y);
if ((event->type & (GPM_UP | GPM_DOUBLE)) == (GPM_UP | GPM_DOUBLE))
{
tree_mouse_click (tree, local.y);
if ((local.type & (GPM_UP | GPM_DOUBLE)) == (GPM_UP | GPM_DOUBLE))
tree_chdir_sel (tree);
}
}
return MOU_NORMAL;
}
@ -1102,9 +1105,10 @@ tree_execute_cmd (WTree * tree, unsigned long command)
case CK_Delete:
tree_rmdir (tree);
break;
case CK_Cancel:
/* don't close tree due to SIGINT */
break;
case CK_Quit:
if (!tree->is_panel)
dlg_stop (((Widget *) tree)->owner);
return res;
default:
res = MSG_NOT_HANDLED;
}
@ -1265,7 +1269,7 @@ tree_new (int y, int x, int lines, int cols, gboolean is_panel)
{
WTree *tree = g_new (WTree, 1);
init_widget (&tree->widget, y, x, lines, cols, tree_callback, event_callback);
init_widget (&tree->widget, y, x, lines, cols, tree_callback, tree_event);
tree->is_panel = is_panel;
tree->selected_ptr = 0;

View File

@ -604,17 +604,23 @@ help_show (Dlg_head * h, const char *paint_start)
static int
help_event (Gpm_Event * event, void *vp)
{
Widget *w = vp;
Widget *w = (Widget *) vp;
GSList *current_area;
Gpm_Event local;
if (!mouse_global_in_widget (event, w))
return MOU_UNHANDLED;
if ((event->type & GPM_UP) == 0)
return 0;
return MOU_NORMAL;
local = mouse_get_local (event, w);
/* The event is relative to the dialog window, adjust it: */
event->x -= 2;
event->y -= 2;
local.x -= 2;
local.y -= 2;
if (event->buttons & GPM_B_RIGHT)
if ((local.buttons & GPM_B_RIGHT) != 0)
{
currentpoint = history[history_ptr].page;
selected_item = history[history_ptr].link;
@ -623,24 +629,26 @@ help_event (Gpm_Event * event, void *vp)
history_ptr = HISTORY_SIZE - 1;
help_callback (w->owner, NULL, DLG_DRAW, 0, NULL);
return 0;
return MOU_NORMAL;
}
/* Test whether the mouse click is inside one of the link areas */
for (current_area = link_area; current_area != NULL; current_area = g_slist_next (current_area))
{
Link_Area *la = (Link_Area *) current_area->data;
/* Test one line link area */
if (event->y == la->y1 && event->x >= la->x1 && event->y == la->y2 && event->x <= la->x2)
if (local.y == la->y1 && local.x >= la->x1 && local.y == la->y2 && local.x <= la->x2)
break;
/* Test two line link area */
if (la->y1 + 1 == la->y2)
{
/* The first line */
if (event->y == la->y1 && event->x >= la->x1)
if (local.y == la->y1 && local.x >= la->x1)
break;
/* The second line */
if (event->y == la->y2 && event->x <= la->x2)
if (local.y == la->y2 && local.x <= la->x2)
break;
}
/* Mouse will not work with link areas of more than two lines */
@ -658,11 +666,11 @@ help_event (Gpm_Event * event, void *vp)
currentpoint = help_follow_link (currentpoint, la->link_name);
selected_item = NULL;
}
else if (event->y < 0)
else if (local.y < 0)
move_backward (help_lines - 1);
else if (event->y >= help_lines)
else if (local.y >= help_lines)
move_forward (help_lines - 1);
else if (event->y < help_lines / 2)
else if (local.y < help_lines / 2)
move_backward (1);
else
move_forward (1);
@ -670,7 +678,7 @@ help_event (Gpm_Event * event, void *vp)
/* Show the new node */
help_callback (w->owner, NULL, DLG_DRAW, 0, NULL);
return 0;
return MOU_NORMAL;
}
/* --------------------------------------------------------------------------------------------- */
@ -909,9 +917,6 @@ help_execute_cmd (unsigned long command)
case CK_Quit:
dlg_stop (whelp);
break;
case CK_Cancel:
/* don't close help due to SIGINT */
break;
default:
ret = MSG_NOT_HANDLED;
}

View File

@ -141,7 +141,7 @@ mcview_display_status (mcview_t * view)
tty_setcolor (STATUSBAR_COLOR);
widget_move (view, top, left);
tty_draw_hline (-1, -1, ' ', width);
tty_draw_hline (top, left, ' ', width);
file_label =
view->filename_vpath != NULL ?

View File

@ -88,40 +88,44 @@ char *mcview_show_eof = NULL;
/* --------------------------------------------------------------------------------------------- */
/** Both views */
static int
mcview_event (mcview_t * view, Gpm_Event * event, int *result)
static gboolean
do_mcview_event (mcview_t * view, Gpm_Event * event, int *result)
{
screen_dimen y, x;
Gpm_Event local;
*result = MOU_NORMAL;
local = mouse_get_local (event, (Widget *) view);
/* rest of the upper frame, the menu is invisible - call menu */
if (mcview_is_in_panel (view) && (event->type & GPM_DOWN) && event->y == 1 && !menubar_visible)
if (mcview_is_in_panel (view) && (local.type & GPM_DOWN) != 0 && local.y == 1
&& !menubar_visible)
{
event->x += view->widget.x;
*result = the_menubar->widget.mouse (event, the_menubar);
return 0; /* don't draw viewer over menu */
return FALSE; /* don't draw viewer over menu */
}
/* We are not interested in the release events */
if (!(event->type & (GPM_DOWN | GPM_DRAG)))
return 0;
if ((local.type & (GPM_DOWN | GPM_DRAG)) == 0)
return FALSE;
/* Wheel events */
if ((event->buttons & GPM_B_UP) && (event->type & GPM_DOWN))
if ((local.buttons & GPM_B_UP) != 0 && (local.type & GPM_DOWN) != 0)
{
mcview_move_up (view, 2);
return 1;
*result = MOU_NORMAL;
return TRUE;
}
if ((event->buttons & GPM_B_DOWN) && (event->type & GPM_DOWN))
if ((local.buttons & GPM_B_DOWN) != 0 && (local.type & GPM_DOWN) != 0)
{
mcview_move_down (view, 2);
return 1;
*result = MOU_NORMAL;
return TRUE;
}
x = event->x;
y = event->y;
x = local.x;
y = local.y;
/* Scrolling left and right */
if (!view->text_wrap_mode)
@ -164,28 +168,30 @@ mcview_event (mcview_t * view, Gpm_Event * event, int *result)
goto processed;
}
return 0;
return FALSE;
processed:
*result = MOU_REPEAT;
return 1;
return TRUE;
}
/* --------------------------------------------------------------------------------------------- */
/** Real view only */
/** Real view only */
static int
mcview_real_event (Gpm_Event * event, void *x)
mcview_event (Gpm_Event * event, void *data)
{
mcview_t *view = (mcview_t *) x;
mcview_t *view = (mcview_t *) data;
int result;
if (mcview_event (view, event, &result))
if (!mouse_global_in_widget (event, (Widget *) data))
return MOU_UNHANDLED;
if (do_mcview_event (view, event, &result))
mcview_update (view);
return result;
}
/* --------------------------------------------------------------------------------------------- */
/*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */
@ -195,7 +201,7 @@ mcview_new (int y, int x, int lines, int cols, gboolean is_panel)
{
mcview_t *view = g_new0 (mcview_t, 1);
init_widget (&view->widget, y, x, lines, cols, mcview_callback, mcview_real_event);
init_widget (&view->widget, y, x, lines, cols, mcview_callback, mcview_event);
view->hex_mode = FALSE;
view->hexedit_mode = FALSE;