Allow move and resize edit window using keyboard.

Add "Window" menu entry in editor main menu to handle editor windows.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Andrew Borodin 2011-07-23 15:30:31 +04:00
parent d9bb50b013
commit b50f4f07e5
9 changed files with 283 additions and 10 deletions

View File

@ -1,13 +1,13 @@
/*
Definitions of key bindings.
Copyright (C) 2009, 2011
Copyright (C) 2005, 2009, 2010, 2011, 2011, 2012
The Free Software Foundation, Inc.
Written by:
Vitja Makarov, 2005
Ilia Maslakov <il.smind@gmail.com>, 2009
Andrew Borodin <aborodin@vmail.ru>, 2009, 2010
Andrew Borodin <aborodin@vmail.ru>, 2009, 2010, 2011, 2012
This file is part of the Midnight Commander.
@ -311,6 +311,8 @@ static name_keymap_t command_names[] = {
{"About", CK_About},
/* An action to run external script from macro */
{"ExecuteScript", CK_PipeBlock (0)},
{"WindowMove", CK_WindowMove},
{"WindowResize", CK_WindowResize},
#endif /* USE_INTERNAL_EDIT */
/* viewer */

View File

@ -278,6 +278,9 @@ enum
CK_RepeatStartRecord,
CK_RepeatStopRecord,
CK_RepeatStartStopRecord,
/* window commands */
CK_WindowMove,
CK_WindowResize,
/* misc commands */
CK_InsertOverwrite,
CK_ParagraphFormat,

View File

@ -337,6 +337,8 @@ SelectCodepage = alt-e
Options =
OptionsSaveMode =
LearnKeys =
WindowMove =
WindowResize =
ExtendedKeyMap =
[viewer]

View File

@ -337,6 +337,8 @@ SelectCodepage = alt-e
Options =
OptionsSaveMode =
LearnKeys =
WindowMove =
WindowResize =
ExtendedKeyMap = ctrl-x
[editor:xmap]

View File

@ -178,6 +178,7 @@ extern gboolean search_create_bookmark;
/*** declarations of public functions ************************************************************/
gboolean edit_widget_is_editor (const Widget * w);
gboolean edit_drop_hotkey_menu (Dlg_head * h, int key);
void edit_menu_cmd (Dlg_head * h);
void user_menu (WEdit * edit, const char *menu_file, int selected_entry);
@ -261,6 +262,8 @@ void edit_info_status (WEdit * edit);
void edit_status (WEdit * edit);
void edit_execute_key_command (WEdit * edit, unsigned long command, int char_for_insertion);
void edit_update_screen (WEdit * edit);
void edit_save_size (WEdit * edit);
gboolean edit_handle_move_resize (WEdit * edit, unsigned long command);
void edit_move_to_line (WEdit * e, long line);
void edit_move_display (WEdit * e, long line);
void edit_word_wrap (WEdit * edit);

View File

@ -2269,6 +2269,7 @@ edit_init (WEdit * edit, int y, int x, int lines, int cols, const vfs_path_t * f
edit->widget.x = x;
edit->widget.lines = lines;
edit->widget.cols = cols;
edit_save_size (edit);
edit->stat1.st_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
edit->stat1.st_uid = getuid ();
@ -3513,6 +3514,10 @@ edit_execute_key_command (WEdit * edit, unsigned long command, int char_for_inse
void
edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion)
{
/* at first, handle window state */
if (edit_handle_move_resize (edit, command))
return;
edit->force |= REDRAW_LINE;
/* The next key press will unhighlight the found string, so update
@ -4160,9 +4165,6 @@ edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion)
case CK_Find:
edit_get_match_keyword_cmd (edit);
break;
case CK_Quit:
dlg_stop (edit->widget.owner);
break;
case CK_EditNew:
edit_new_cmd (edit);
break;

View File

@ -1,11 +1,12 @@
/*
Editor menu definitions and initialisation
Copyright (C) 1996, 1998, 2001, 2002, 2003, 2005, 2007, 2011
Copyright (C) 1996, 1998, 2001, 2002, 2003, 2005, 2007, 2011, 2012
The Free Software Foundation, Inc.
Written by:
Paul Sheer, 1996, 1997
Andrew Borodin <aborodin@vmail.ru> 2012
This file is part of the Midnight Commander.
@ -202,6 +203,22 @@ create_format_menu (void)
return g_list_reverse (entries);
}
/* --------------------------------------------------------------------------------------------- */
/**
* Create the 'window' popup menu
*/
static GList *
create_window_menu (void)
{
GList *entries = NULL;
entries = g_list_append (entries, menu_entry_create (_("&Move"), CK_WindowMove));
entries = g_list_append (entries, menu_entry_create (_("&Resize"), CK_WindowResize));
return entries;
}
/* --------------------------------------------------------------------------------------------- */
static GList *
@ -263,6 +280,8 @@ edit_init_menu (struct WMenuBar *menubar)
"[Internal File Editor]"));
menubar_add_menu (menubar,
create_menu (_("For&mat"), create_format_menu (), "[Internal File Editor]"));
menubar_add_menu (menubar,
create_menu (_("&Window"), create_window_menu (), "[Internal File Editor]"));
menubar_add_menu (menubar,
create_menu (_("&Options"), create_options_menu (),
"[Internal File Editor]"));
@ -299,9 +318,12 @@ edit_drop_hotkey_menu (Dlg_head * h, int key)
case ALT ('m'):
m = 4;
break;
case ALT ('o'):
case ALT ('w'):
m = 5;
break;
case ALT ('o'):
m = 6;
break;
default:
return FALSE;
}

View File

@ -63,6 +63,9 @@
/*** file scope macro definitions ****************************************************************/
#define WINDOW_MIN_LINES (2 + 2)
#define WINDOW_MIN_COLS (2 + LINE_STATE_WIDTH)
/*** file scope type declarations ****************************************************************/
/*** file scope variables ************************************************************************/
@ -71,6 +74,102 @@
static cb_ret_t edit_callback (Widget * w, widget_msg_t msg, int parm);
/* --------------------------------------------------------------------------------------------- */
/**
* Restore saved window size.
*
* @param edit editor object
*/
static void
edit_restore_size (WEdit * edit)
{
edit->drag_state = MCEDIT_DRAG_NORMAL;
widget_set_size ((Widget *) edit, edit->y_prev, edit->x_prev,
edit->lines_prev, edit->cols_prev);
dlg_redraw (((Widget *) edit)->owner);
}
/* --------------------------------------------------------------------------------------------- */
/**
* Move window by one row or column in any direction.
*
* @param edit editor object
* @param command direction (CK_Up, CK_Down, CK_Left, CK_Right)
*/
static void
edit_window_move (WEdit * edit, unsigned long command)
{
Widget *w = (Widget *) edit;
Dlg_head *h = w->owner;
switch (command)
{
case CK_Up:
if (w->y > h->y + 1) /* menubar */
w->y--;
break;
case CK_Down:
if (w->y < h->y + h->lines - 2) /* buttonbar */
w->y++;
break;
case CK_Left:
if (w->x + w->cols > h->x)
w->x--;
break;
case CK_Right:
if (w->x < h->x + h->cols)
w->x++;
break;
default:
return;
}
edit->force |= REDRAW_PAGE;
dlg_redraw (h);
}
/* --------------------------------------------------------------------------------------------- */
/**
* Resize window by one row or column in any direction.
*
* @param edit editor object
* @param command direction (CK_Up, CK_Down, CK_Left, CK_Right)
*/
static void
edit_window_resize (WEdit * edit, unsigned long command)
{
Widget *w = (Widget *) edit;
Dlg_head *h = w->owner;
switch (command)
{
case CK_Up:
if (w->lines > WINDOW_MIN_LINES)
w->lines--;
break;
case CK_Down:
if (w->y + w->lines < h->y + h->lines - 1) /* buttonbar */
w->lines++;
break;
case CK_Left:
if (w->cols > WINDOW_MIN_COLS)
w->cols--;
break;
case CK_Right:
if (w->x + w->cols < h->x + h->cols)
w->cols++;
break;
default:
return;
}
edit->force |= REDRAW_COMPLETELY;
dlg_redraw (h);
}
/* --------------------------------------------------------------------------------------------- */
static char *
@ -294,8 +393,8 @@ edit_event (Gpm_Event * event, void *data)
local = mouse_get_local (event, w);
/* don't use widget_set_size() here to avoid double draw */
w->lines = max (2 + 2, local.y);
w->cols = max (2 + LINE_STATE_WIDTH, local.x);
w->lines = max (WINDOW_MIN_LINES, local.y);
w->cols = max (WINDOW_MIN_COLS, local.x);
edit->force |= REDRAW_COMPLETELY;
}
@ -318,6 +417,23 @@ edit_dialog_command_execute (Dlg_head * h, unsigned long command)
case CK_Menu:
edit_menu_cmd (h);
break;
case CK_Quit:
case CK_Cancel:
{
Widget *w = (Widget *) h->current->data;
if (!edit_widget_is_editor (w) || ((WEdit *) w)->drag_state == MCEDIT_DRAG_NORMAL)
dlg_stop (h);
else
edit_restore_size ((WEdit *) w);
}
break;
case CK_WindowMove:
case CK_WindowResize:
if (edit_widget_is_editor ((Widget *) h->current->data))
edit_handle_move_resize ((WEdit *) h->current->data, command);
break;
default:
ret = MSG_NOT_HANDLED;
break;
@ -430,7 +546,9 @@ edit_dialog_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, vo
case DLG_VALIDATE:
h->state = DLG_ACTIVE; /* don't stop the dialog before final decision */
if (edit_ok_to_exit (edit))
if (edit->drag_state != MCEDIT_DRAG_NORMAL)
edit_restore_size (edit);
else if (edit_ok_to_exit (edit))
h->state = DLG_CLOSED;
return MSG_HANDLED;
@ -568,6 +686,20 @@ edit_get_file_name (const WEdit * edit)
return vfs_path_to_str (edit->filename_vpath);
}
/* --------------------------------------------------------------------------------------------- */
/**
* Check if widget is an WEdit class.
*
* @param w probably editor object
* @return TRUE if widget is an WEdit class, FALSE otherwise
*/
gboolean
edit_widget_is_editor (const Widget * w)
{
return (w != NULL && w->callback == edit_callback);
}
/* --------------------------------------------------------------------------------------------- */
void
@ -602,3 +734,104 @@ edit_update_screen (WEdit * e)
}
/* --------------------------------------------------------------------------------------------- */
/**
* Save current window size.
*
* @param edit editor object
*/
void
edit_save_size (WEdit * edit)
{
edit->y_prev = edit->widget.y;
edit->x_prev = edit->widget.x;
edit->lines_prev = edit->widget.lines;
edit->cols_prev = edit->widget.cols;
}
/* --------------------------------------------------------------------------------------------- */
/**
* Handle move/resize events.
*
* @param edit editor object
* @param command action id
* @return TRUE if mouse actions was handled, FALSE otherwise
*/
gboolean
edit_handle_move_resize (WEdit * edit, unsigned long command)
{
gboolean ret = FALSE;
switch (edit->drag_state)
{
case MCEDIT_DRAG_NORMAL:
/* possible start move/resize */
switch (command)
{
case CK_WindowMove:
edit->drag_state = MCEDIT_DRAG_MOVE;
edit_save_size (edit);
ret = TRUE;
break;
case CK_WindowResize:
edit->drag_state = MCEDIT_DRAG_RESIZE;
edit_save_size (edit);
ret = TRUE;
break;
default:
break;
}
break;
case MCEDIT_DRAG_MOVE:
switch (command)
{
case CK_WindowResize:
edit->drag_state = MCEDIT_DRAG_RESIZE;
ret = TRUE;
break;
case CK_Up:
case CK_Down:
case CK_Left:
case CK_Right:
edit_window_move (edit, command);
ret = TRUE;
break;
case CK_Enter:
case CK_WindowMove:
edit->drag_state = MCEDIT_DRAG_NORMAL;
default:
ret = TRUE;
break;
}
break;
case MCEDIT_DRAG_RESIZE:
switch (command)
{
case CK_WindowMove:
edit->drag_state = MCEDIT_DRAG_MOVE;
ret = TRUE;
break;
case CK_Up:
case CK_Down:
case CK_Left:
case CK_Right:
edit_window_resize (edit, command);
ret = TRUE;
break;
case CK_Enter:
case CK_WindowResize:
edit->drag_state = MCEDIT_DRAG_NORMAL;
default:
ret = TRUE;
break;
}
break;
}
return ret;
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -64,6 +64,10 @@ struct WEdit
mcedit_drag_state_t drag_state;
int drag_state_start; /* save cursor position before window moving */
/* save location before move/resize */
int x_prev, y_prev;
int cols_prev, lines_prev;
vfs_path_t *filename_vpath; /* Name of the file */
vfs_path_t *dir_vpath; /* NULL if filename is absolute */