static cb_ret_t edit_callback (Widget * w, widget_msg_t msg, int parm) { WEdit *e = (WEdit *) w; switch (msg) { case WIDGET_DRAW: e->force |= REDRAW_COMPLETELY; /* fallthrough */ case WIDGET_FOCUS: edit_update_screen (e); return MSG_HANDLED; case WIDGET_KEY: { int cmd, ch; cb_ret_t ret = MSG_NOT_HANDLED; /* The user may override the access-keys for the menu bar. */ if (macro_index == -1 && edit_execute_macro (e, parm)) ret = MSG_HANDLED; else if (edit_translate_key (e, parm, &cmd, &ch)) { edit_execute_key_command (e, cmd, ch); edit_update_screen (e); ret = MSG_HANDLED; } else if (edit_drop_hotkey_menu (e, parm)) ret = MSG_HANDLED; return ret; } case WIDGET_COMMAND: /* command from menubar or buttonbar */ return edit_command_execute (e, parm); case WIDGET_CURSOR: widget_move (w, e->curs_row + EDIT_TEXT_VERTICAL_OFFSET, e->curs_col + e->start_col + e->over_col + EDIT_TEXT_HORIZONTAL_OFFSET + option_line_state_width); return MSG_HANDLED; case WIDGET_DESTROY: edit_clean (e); return MSG_HANDLED; default: return default_proc (msg, parm); } }
static void edit_total_update (WEdit * edit) { edit_find_bracket (edit); edit->force |= REDRAW_COMPLETELY; edit_update_curs_row (edit); edit_update_screen (edit); }
static cb_ret_t edit_command_execute (WEdit * edit, unsigned long command) { if (command == CK_Menu) edit_menu_cmd (edit); else { edit_execute_key_command (edit, command, -1); edit_update_screen (edit); } return MSG_HANDLED; }
/** * Handle move/resize mouse events. */ static void edit_mouse_handle_move_resize (Widget * w, mouse_msg_t msg, mouse_event_t * event) { WEdit *edit = (WEdit *) (w); Widget *h = WIDGET (w->owner); int global_x, global_y; if (msg == MSG_MOUSE_UP) { /* Exit move/resize mode. */ edit_execute_cmd (edit, CK_Enter, -1); edit_update_screen (edit); /* Paint the buttonbar over our possibly overlapping frame. */ return; } if (msg != MSG_MOUSE_DRAG) /** * We ignore any other events. Specifically, MSG_MOUSE_DOWN. * * When the move/resize is initiated by the menu, we let the user * stop it by clicking with the mouse. Which is why we don't want * a mouse down to affect the window. */ return; /* Convert point to global coordinates for easier calculations. */ global_x = event->x + w->x; global_y = event->y + w->y; /* Clamp the point to the dialog's client area. */ global_y = CLAMP (global_y, h->y + 1, h->y + h->lines - 2); /* Status line, buttonbar */ global_x = CLAMP (global_x, h->x, h->x + h->cols - 1); /* Currently a no-op, as the dialog has no left/right margins. */ if (edit->drag_state == MCEDIT_DRAG_MOVE) { w->y = global_y; w->x = global_x - edit->drag_state_start; } else if (edit->drag_state == MCEDIT_DRAG_RESIZE) { w->lines = MAX (WINDOW_MIN_LINES, global_y - w->y + 1); w->cols = MAX (WINDOW_MIN_COLS, global_x - w->x + 1); } edit->force |= REDRAW_COMPLETELY; /* Not really needed as WEdit's MSG_DRAW already does this. */ /* We draw the whole dialog because dragging/resizing exposes area beneath. */ dlg_redraw (w->owner); }
void edit_toggle_fullscreen (WEdit * edit) { Dlg_head *h = ((Widget *) edit)->owner; edit->fullscreen = !edit->fullscreen; edit->force = REDRAW_COMPLETELY; if (!edit->fullscreen) edit_restore_size (edit); else { edit_save_size (edit); widget_set_size ((Widget *) edit, h->y + 1, h->x, h->lines - 2, h->cols); edit->force |= REDRAW_PAGE; edit_update_screen (edit); } }
void edit_toggle_fullscreen (WEdit * edit) { edit->fullscreen = !edit->fullscreen; edit->force = REDRAW_COMPLETELY; if (!edit->fullscreen) edit_restore_size (edit); else { Widget *w = WIDGET (edit); Widget *h = WIDGET (w->owner); edit_save_size (edit); widget_set_size (w, h->y + 1, h->x, h->lines - 2, h->cols); edit->force |= REDRAW_PAGE; edit_update_screen (edit); } }
static cb_ret_t edit_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data) { WEdit *e = (WEdit *) w; switch (msg) { case MSG_FOCUS: edit_set_buttonbar (e, find_buttonbar (w->owner)); return MSG_HANDLED; case MSG_DRAW: e->force |= REDRAW_COMPLETELY; edit_update_screen (e); return MSG_HANDLED; case MSG_KEY: { int cmd, ch; cb_ret_t ret = MSG_NOT_HANDLED; /* The user may override the access-keys for the menu bar. */ if (macro_index == -1 && edit_execute_macro (e, parm)) { edit_update_screen (e); ret = MSG_HANDLED; } else if (edit_translate_key (e, parm, &cmd, &ch)) { edit_execute_key_command (e, cmd, ch); edit_update_screen (e); ret = MSG_HANDLED; } return ret; } case MSG_ACTION: /* command from menubar or buttonbar */ edit_execute_key_command (e, parm, -1); edit_update_screen (e); return MSG_HANDLED; case MSG_CURSOR: { int y, x; y = (e->fullscreen ? 0 : 1) + EDIT_TEXT_VERTICAL_OFFSET + e->curs_row; x = (e->fullscreen ? 0 : 1) + EDIT_TEXT_HORIZONTAL_OFFSET + option_line_state_width + e->curs_col + e->start_col + e->over_col; widget_move (w, y, x); return MSG_HANDLED; } case MSG_IDLE: edit_update_screen (e); return MSG_HANDLED; case MSG_DESTROY: edit_clean (e); return MSG_HANDLED; default: return widget_default_callback (w, sender, msg, parm, data); } }
/** * Handle mouse events of editor window * * @param w Widget object (the editor window) * @param msg mouse event message * @param event mouse event data */ static void edit_mouse_callback (Widget * w, mouse_msg_t msg, mouse_event_t * event) { WEdit *edit = (WEdit *) w; /* buttons' distance from right edge */ int dx = edit->fullscreen ? 0 : 2; /* location of 'Close' and 'Toggle fullscreen' pictograms */ int close_x, toggle_fullscreen_x; close_x = (w->cols - 1) - dx - 1; toggle_fullscreen_x = close_x - 3; if (edit->drag_state != MCEDIT_DRAG_NONE) { /* window is being resized/moved */ edit_mouse_handle_move_resize (w, msg, event); return; } /* If it's the last line on the screen, we abort the event to make the * system channel it to the overlapping buttonbar instead. We have to do * this because a WEdit has the WOP_TOP_SELECT flag, which makes it above * the buttonbar in Z-order. */ if (msg == MSG_MOUSE_DOWN && (event->y + w->y == LINES - 1)) { event->result.abort = TRUE; return; } switch (msg) { case MSG_MOUSE_DOWN: widget_select (w); edit_update_curs_row (edit); edit_update_curs_col (edit); if (!edit->fullscreen) { if (event->y == 0) { if (event->x >= close_x - 1 && event->x <= close_x + 1) ; /* do nothing (see MSG_MOUSE_CLICK) */ else if (event->x >= toggle_fullscreen_x - 1 && event->x <= toggle_fullscreen_x + 1) ; /* do nothing (see MSG_MOUSE_CLICK) */ else { /* start window move */ edit_execute_cmd (edit, CK_WindowMove, -1); edit_update_screen (edit); /* Paint the buttonbar over our possibly overlapping frame. */ edit->drag_state_start = event->x; } break; } if (event->y == w->lines - 1 && event->x == w->cols - 1) { /* bottom-right corner -- start window resize */ edit_execute_cmd (edit, CK_WindowResize, -1); break; } } MC_FALLTHROUGH; /* to start/stop text selection */ case MSG_MOUSE_UP: edit_update_cursor (edit, event); edit_total_update (edit); break; case MSG_MOUSE_CLICK: if (event->y == 0) { if (event->x >= close_x - 1 && event->x <= close_x + 1) send_message (w->owner, NULL, MSG_ACTION, CK_Close, NULL); else if (event->x >= toggle_fullscreen_x - 1 && event->x <= toggle_fullscreen_x + 1) edit_toggle_fullscreen (edit); else if (!edit->fullscreen && event->count == GPM_DOUBLE) /* double click on top line (toggle fullscreen) */ edit_toggle_fullscreen (edit); } else if (event->count == GPM_DOUBLE) { /* double click */ edit_mark_current_word_cmd (edit); edit_total_update (edit); } else if (event->count == GPM_TRIPLE) { /* triple click: works in GPM only, not in xterm */ edit_mark_current_line_cmd (edit); edit_total_update (edit); } break; case MSG_MOUSE_DRAG: edit_update_cursor (edit, event); edit_total_update (edit); break; case MSG_MOUSE_SCROLL_UP: edit_move_up (edit, 2, TRUE); edit_total_update (edit); break; case MSG_MOUSE_SCROLL_DOWN: edit_move_down (edit, 2, TRUE); edit_total_update (edit); break; default: break; } }
static int edit_event (Gpm_Event * event, void *data) { WEdit *edit = (WEdit *) data; /* Unknown event type */ if (!(event->type & (GPM_DOWN | GPM_DRAG | GPM_UP))) 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; /* Double click */ if ((event->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)) { edit_mark_current_line_cmd (edit); goto update; } #endif /* Wheel events */ if ((event->buttons & GPM_B_UP) && (event->type & GPM_DOWN)) { edit_move_up (edit, 2, 1); goto update; } if ((event->buttons & GPM_B_DOWN) && (event->type & GPM_DOWN)) { 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)) return MOU_NORMAL; if (event->type & (GPM_DOWN | GPM_UP)) edit_push_key_press (edit); if (!option_cursor_beyond_eol) edit->prev_col = event->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) { edit->over_col = event->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; } } --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); else edit_move_to_prev_col (edit, edit_bol (edit, edit->curs1)); if (event->type & GPM_DOWN) { edit_mark_cmd (edit, 1); /* reset */ edit->highlight = 0; } if (!(event->type & GPM_DRAG)) edit_mark_cmd (edit, 0); update: edit_find_bracket (edit); edit->force |= REDRAW_COMPLETELY; edit_update_curs_row (edit); edit_update_curs_col (edit); edit_update_screen (edit); return MOU_NORMAL; }
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; local = mouse_get_local (event, w); /* Unknown event type */ if ((event->type & (GPM_DOWN | GPM_DRAG | GPM_UP)) == 0) return MOU_NORMAL; dlg_set_top_widget (w); edit_update_curs_row (edit); edit_update_curs_col (edit); if (edit->fullscreen || (local.buttons & GPM_B_LEFT) == 0 || (local.type & GPM_UP) != 0) edit->drag_state = MCEDIT_DRAG_NORMAL; else if (local.y == 1 && edit->drag_state != MCEDIT_DRAG_RESIZE) { /* click on the top line (move) */ int dx = edit->fullscreen ? 0 : 2; if (local.x == w->cols - dx - 1) { send_message (w->owner, NULL, MSG_ACTION, CK_Close, NULL); return MOU_NORMAL; } if (local.x == w->cols - dx - 4) { edit_toggle_fullscreen (edit); return MOU_NORMAL; } if ((local.type & (GPM_DOWN | GPM_DRAG)) != 0) { /* move if not fullscreen */ edit->drag_state_start = local.x; edit->drag_state = MCEDIT_DRAG_MOVE; edit->force |= REDRAW_COMPLETELY; edit_update_screen (edit); } } else if (!edit->fullscreen && local.y == w->lines && local.x == w->cols) { /* click on bottom-right corner (resize) */ if ((local.type & (GPM_DOWN | GPM_DRAG)) != 0) { edit->drag_state = MCEDIT_DRAG_RESIZE; edit->force |= REDRAW_COMPLETELY; edit_update_screen (edit); } } if (edit->drag_state == MCEDIT_DRAG_NORMAL) { gboolean done = TRUE; /* Double click */ if ((local.type & (GPM_DOUBLE | GPM_UP)) == (GPM_UP | GPM_DOUBLE)) { edit_mark_current_word_cmd (edit); goto update; } #if 0 /* Triple click */ if ((local.type & (GPM_TRIPLE | GPM_UP)) == (GPM_UP | GPM_TRIPLE)) { edit_mark_current_line_cmd (edit); goto update; } #endif /* Wheel events */ if ((local.buttons & GPM_B_UP) != 0 && (local.type & GPM_DOWN) != 0) { edit_move_up (edit, 2, 1); goto update; } if ((local.buttons & GPM_B_DOWN) != 0 && (local.type & GPM_DOWN) != 0) { edit_move_down (edit, 2, 1); goto update; } /* continue handle current event */ goto cont; /* handle DRAG mouse event, don't use standard way to continue * event handling outside of widget */ do { int c; c = tty_get_event (event, FALSE, TRUE); if (c == EV_NONE || c != EV_MOUSE) break; local = mouse_get_local (event, w); cont: /* A lone up mustn't do anything */ if (edit->mark2 != -1 && (local.type & (GPM_UP | GPM_DRAG)) != 0) return MOU_NORMAL; if ((local.type & (GPM_DOWN | GPM_UP)) != 0) edit_push_key_press (edit); if (!edit->fullscreen) local.x--; if (!option_cursor_beyond_eol) edit->prev_col = local.x - edit->start_col - option_line_state_width - 1; else { long line_len; line_len = edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), 0, edit_buffer_get_current_eol (&edit->buffer)); if (local.x > line_len) { 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 = local.x - option_line_state_width - edit->start_col - 1; } } if (!edit->fullscreen) local.y--; if (local.y > (edit->curs_row + 1)) edit_move_down (edit, local.y - (edit->curs_row + 1), 0); else if (local.y < (edit->curs_row + 1)) edit_move_up (edit, (edit->curs_row + 1) - local.y, 0); else edit_move_to_prev_col (edit, edit_buffer_get_current_bol (&edit->buffer)); if ((local.type & GPM_DOWN) != 0) { edit_mark_cmd (edit, TRUE); /* reset */ edit->highlight = 0; } done = (local.type & GPM_DRAG) == 0; if (done) edit_mark_cmd (edit, FALSE); update: edit_find_bracket (edit); edit->force |= REDRAW_COMPLETELY; edit_update_curs_row (edit); edit_update_curs_col (edit); edit_update_screen (edit); } while (!edit->fullscreen && !done); } else while (edit->drag_state != MCEDIT_DRAG_NORMAL) { int c; int y; c = tty_get_event (event, FALSE, TRUE); y = event->y - 1; if (c == EV_NONE || c != EV_MOUSE) { /* redraw frame */ edit->drag_state = MCEDIT_DRAG_NORMAL; edit->force |= REDRAW_COMPLETELY; edit_update_screen (edit); } else if (y == w->y && (event->type & (GPM_DOUBLE | GPM_UP)) == (GPM_DOUBLE | GPM_UP)) { /* double click on top line (toggle fullscreen) */ edit_toggle_fullscreen (edit); edit->drag_state = MCEDIT_DRAG_NORMAL; edit->force |= REDRAW_COMPLETELY; edit_update_screen (edit); } else if ((event->type & (GPM_DRAG | GPM_DOWN)) == 0) { /* redraw frame */ edit->drag_state = MCEDIT_DRAG_NORMAL; edit->force |= REDRAW_COMPLETELY; edit_update_screen (edit); } else if (!edit->fullscreen) { Widget *h = WIDGET (w->owner); if (edit->drag_state == MCEDIT_DRAG_MOVE) { int x = event->x - 1; y = max (y, h->y + 1); /* status line */ y = min (y, h->y + h->lines - 2); /* buttonbar */ x = max (x, h->x); x = min (x, h->x + h->cols - 1); /* don't use widget_set_size() here to avoid double draw */ w->y = y; w->x = x - edit->drag_state_start; edit->force |= REDRAW_COMPLETELY; } else if (edit->drag_state == MCEDIT_DRAG_RESIZE) { event->y = min (event->y, h->y + h->lines - 1); /* buttonbar */ event->x = min (event->x, h->x + h->cols); local = mouse_get_local (event, w); /* don't use widget_set_size() here to avoid double draw */ w->lines = max (WINDOW_MIN_LINES, local.y); w->cols = max (WINDOW_MIN_COLS, local.x); edit->force |= REDRAW_COMPLETELY; } dlg_redraw (w->owner); } } return MOU_NORMAL; }
static void menu_cmd (int command) { edit_execute_key_command (wedit, command, -1); edit_update_screen (wedit); }
static cb_ret_t edit_callback (Widget * w, widget_msg_t msg, int parm) { WEdit *e = (WEdit *) w; switch (msg) { case WIDGET_FOCUS: edit_set_buttonbar (e, find_buttonbar (e->widget.owner)); /* fall through */ case WIDGET_DRAW: e->force |= REDRAW_COMPLETELY; edit_update_screen (e); return MSG_HANDLED; case WIDGET_UNFOCUS: /* redraw frame and status */ edit_status (e, FALSE); return MSG_HANDLED; case WIDGET_KEY: { int cmd, ch; cb_ret_t ret = MSG_NOT_HANDLED; /* The user may override the access-keys for the menu bar. */ if (macro_index == -1 && edit_execute_macro (e, parm)) { edit_update_screen (e); ret = MSG_HANDLED; } else if (edit_translate_key (e, parm, &cmd, &ch)) { edit_execute_key_command (e, cmd, ch); edit_update_screen (e); ret = MSG_HANDLED; } return ret; } case WIDGET_COMMAND: /* command from menubar or buttonbar */ edit_execute_key_command (e, parm, -1); edit_update_screen (e); return MSG_HANDLED; case WIDGET_CURSOR: { int y, x; y = (e->fullscreen ? 0 : 1) + EDIT_TEXT_VERTICAL_OFFSET + e->curs_row; x = (e->fullscreen ? 0 : 1) + EDIT_TEXT_HORIZONTAL_OFFSET + option_line_state_width + e->curs_col + e->start_col + e->over_col; widget_move (w, y, x); return MSG_HANDLED; } case WIDGET_DESTROY: edit_clean (e); return MSG_HANDLED; default: return default_proc (msg, parm); } }