diff --git a/edit/editcmd.c b/edit/editcmd.c index 7387b933c..7a41945eb 100644 --- a/edit/editcmd.c +++ b/edit/editcmd.c @@ -47,7 +47,7 @@ #include "../src/global.h" -#include "../src/tty/tty.h" /* COLS */ +#include "../src/tty/tty.h" #include "../src/tty/key.h" /* XCTRL */ #include "../src/history.h" @@ -123,17 +123,17 @@ void edit_help_cmd (WEdit * edit) edit->force |= REDRAW_COMPLETELY; } -void edit_refresh_cmd (WEdit * edit) +void +edit_refresh_cmd (WEdit * edit) { #ifdef HAVE_SLANG - { - int color; - edit_get_syntax_color (edit, -1, &color); - } + int color; + + edit_get_syntax_color (edit, -1, &color); tty_touch_screen (); - tty_refresh (); + mc_refresh (); #else - clr_scr(); + clr_scr (); repaint_screen (); #endif /* !HAVE_SLANG */ tty_keypad (TRUE); diff --git a/src/dialog.c b/src/dialog.c index 13b32a44d..4826e3729 100644 --- a/src/dialog.c +++ b/src/dialog.c @@ -38,7 +38,7 @@ #include "help.h" /* interactive_display() */ #include "dialog.h" -#include "layout.h" /* winch_flag, change_screen_size() */ +#include "layout.h" #include "execute.h" /* suspend_cmd() */ #include "main.h" /* fast_refresh */ #include "strutil.h" @@ -97,27 +97,6 @@ init_widget (Widget *w, int y, int x, int lines, int cols, w->options = W_WANT_CURSOR; } -/* Default callback for widgets */ -cb_ret_t -default_proc (widget_msg_t msg, int parm) -{ - (void) parm; - - switch (msg) { - case WIDGET_INIT: - case WIDGET_FOCUS: - case WIDGET_UNFOCUS: - case WIDGET_DRAW: - case WIDGET_DESTROY: - case WIDGET_CURSOR: - case WIDGET_IDLE: - return MSG_HANDLED; - - default: - return MSG_NOT_HANDLED; - } -} - /* Clean the dialog area, draw the frame and the title */ void common_dialog_repaint (struct Dlg_head *h) @@ -137,19 +116,123 @@ common_dialog_repaint (struct Dlg_head *h) } } +/* this function allows to set dialog position */ +void +dlg_set_position (Dlg_head *h, int y1, int x1, int y2, int x2) +{ + /* save old positions, will be used to reposition childs */ + int ox, oy, oc, ol; + int shift_x, shift_y, scale_x, scale_y; + + /* save old positions, will be used to reposition childs */ + ox = h->x; + oy = h->y; + oc = h->cols; + ol = h->lines; + + h->x = x1; + h->y = y1; + h->lines = y2 - y1; + h->cols = x2 - x1; + + /* values by which controls should be moved */ + shift_x = h->x - ox; + shift_y = h->y - oy; + scale_x = h->cols - oc; + scale_y = h->lines - ol; + + if (h->current == NULL) + return; + + if ((shift_x != 0) || (shift_y != 0) || (scale_x != 0) || (scale_y != 0)) { + Widget *c = h->current; + + do { + /* there are, mainly, 2 generally possible + situations: + + 1. control sticks to one side - it + should be moved + + 2. control sticks to two sides of + one direction - it should be sized */ + + int x = c->x; + int y = c->y; + int cols = c->cols; + int lines = c->lines; + + if ((c->pos_flags & WPOS_KEEP_LEFT) && (c->pos_flags & WPOS_KEEP_RIGHT)) { + x += shift_x; + cols += scale_x; + } else if (c->pos_flags & WPOS_KEEP_LEFT) + x += shift_x; + else if (c->pos_flags & WPOS_KEEP_RIGHT) + x += shift_x + scale_x; + + if ((c->pos_flags & WPOS_KEEP_TOP) && (c->pos_flags & WPOS_KEEP_BOTTOM)) { + y += shift_y; + lines += scale_y; + } else if (c->pos_flags & WPOS_KEEP_TOP) + y += shift_y; + else if (c->pos_flags & WPOS_KEEP_BOTTOM) + y += shift_y + scale_y; + + widget_set_size (c, y, x, lines, cols); + + c = c->next; + } while (h->current != c); + } +} + +/* this function sets only size, leaving positioning to automatic methods */ +void +dlg_set_size (Dlg_head *h, int lines, int cols) +{ + int x = h->x; + int y = h->y; + + if (h->flags & DLG_CENTER) { + y = (LINES - lines) / 2; + x = (COLS - cols) / 2; + } + + if ((h->flags & DLG_TRYUP) && (y > 3)) + y -= 2; + + dlg_set_position (h, y, x, y + lines, x + cols); +} + /* Default dialog callback */ cb_ret_t default_dlg_callback (Dlg_head *h, dlg_msg_t msg, int parm) { (void) parm; - if (msg == DLG_DRAW && h->color) { - common_dialog_repaint (h); - return MSG_HANDLED; - } - if (msg == DLG_IDLE){ + switch (msg) { + case DLG_DRAW: + if (h->color != NULL) { + common_dialog_repaint (h); + return MSG_HANDLED; + } + return MSG_NOT_HANDLED; + + case DLG_IDLE: dlg_broadcast_msg_to (h, WIDGET_IDLE, 0, W_WANT_IDLE); return MSG_HANDLED; + + case DLG_RESIZE: + /* this is default resizing mechanism */ + /* the main idea of this code is to resize dialog + according to flags (if any of flags require automatic + resizing, like DLG_CENTER, end after that reposition + controls in dialog according to flags of widget) */ + dlg_set_size (h, h->lines, h->cols); + return MSG_HANDLED; + + default: + break; } + return MSG_NOT_HANDLED; } @@ -160,14 +243,6 @@ create_dlg (int y1, int x1, int lines, int cols, const int *color_set, { Dlg_head *new_d; - if (flags & DLG_CENTER) { - y1 = (LINES - lines) / 2; - x1 = (COLS - cols) / 2; - } - - if ((flags & DLG_TRYUP) && (y1 > 3)) - y1 -= 2; - new_d = g_new0 (Dlg_head, 1); if (color_set != NULL) { new_d->color = g_new (int, DLG_COLOR_NUM); @@ -177,9 +252,10 @@ create_dlg (int y1, int x1, int lines, int cols, const int *color_set, new_d->callback = callback ? callback : default_dlg_callback; new_d->x = x1; new_d->y = y1; - new_d->cols = cols; - new_d->lines = lines; new_d->flags = flags; + new_d->data = NULL; + + dlg_set_size (new_d, lines, cols); /* Strip existing spaces, add one space before and after the title */ if (title) { @@ -220,7 +296,7 @@ set_idle_proc (Dlg_head *d, int enable) * from the bottom, make the widget current. Return widget number. */ int -add_widget (Dlg_head *h, void *w) +add_widget_autopos (Dlg_head *h, void *w, widget_pos_flags_t pos_flags) { Widget *widget = (Widget *) w; @@ -232,6 +308,7 @@ add_widget (Dlg_head *h, void *w) widget->y += h->y; widget->parent = h; widget->dlg_id = h->count++; + widget->pos_flags = pos_flags; if (h->current) { widget->next = h->current; @@ -249,6 +326,13 @@ add_widget (Dlg_head *h, void *w) return widget->dlg_id; } +/* wrapper to simply add lefttop positioned controls */ +int +add_widget (Dlg_head *h, void *w) +{ + add_widget_autopos (h, w, WPOS_KEEP_LEFT | WPOS_KEEP_TOP); +} + enum { REFRESH_COVERS_PART, /* If the refresh fn convers only a part */ REFRESH_COVERS_ALL /* If the refresh fn convers all the screen */ @@ -541,7 +625,7 @@ dialog_handle_key (Dlg_head *h, int d_key) case XCTRL('l'): #ifdef HAVE_SLANG tty_touch_screen (); - tty_refresh (); + mc_refresh (); #else /* Use this if the refreshes fail */ clr_scr (); diff --git a/src/dialog.h b/src/dialog.h index 5fa1830da..4cb2bda70 100644 --- a/src/dialog.h +++ b/src/dialog.h @@ -112,6 +112,7 @@ typedef struct Dlg_head { /* Internal variables */ int count; /* Number of widgets */ struct Widget *current; /* Curently active widget */ + void *data; /* data can be passed to dialog */ dlg_cb_fn callback; struct Dlg_head *parent; /* Parent dialog */ } Dlg_head; @@ -125,17 +126,32 @@ typedef struct Widget Widget; /* Widget callback */ typedef cb_ret_t (*callback_fn) (Widget *widget, widget_msg_t msg, int parm); +/* widget options */ +typedef enum { + W_WANT_HOTKEY = (1 << 1), + W_WANT_CURSOR = (1 << 2), + W_WANT_IDLE = (1 << 3), + W_IS_INPUT = (1 << 4) +} widget_options_t; + +/* Flags for widget repositioning on dialog resize */ +typedef enum { + WPOS_KEEP_LEFT = (1 << 0), /* keep widget distance to left border of dialog */ + WPOS_KEEP_RIGHT = (1 << 1), /* keep widget distance to right border of dialog */ + WPOS_KEEP_TOP = (1 << 2), /* keep widget distance to top border of dialog */ + WPOS_KEEP_BOTTOM = (1 << 3), /* keep widget distance to bottom border of dialog */ + WPOS_KEEP_HORZ = WPOS_KEEP_LEFT | WPOS_KEEP_RIGHT, + WPOS_KEEP_VERT = WPOS_KEEP_TOP | WPOS_KEEP_BOTTOM, + WPOS_KEEP_ALL = WPOS_KEEP_HORZ | WPOS_KEEP_VERT +} widget_pos_flags_t; + /* Every Widget must have this as its first element */ struct Widget { int x, y; int cols, lines; - -#define W_WANT_HOTKEY (1 << 1) -#define W_WANT_CURSOR (1 << 2) -#define W_WANT_IDLE (1 << 3) -#define W_IS_INPUT (1 << 4) - int options; - int dlg_id; /* Number of the widget, starting with 0 */ + widget_options_t options; + widget_pos_flags_t pos_flags; /* repositioning flags */ + int dlg_id; /* Number of the widget, starting with 0 */ struct Widget *next; struct Widget *prev; callback_fn callback; @@ -162,7 +178,14 @@ Dlg_head *create_dlg (int y1, int x1, int lines, int cols, void dlg_set_default_colors (void); -int add_widget (Dlg_head *dest, void *Widget); +int add_widget_autopos (Dlg_head *dest, void *w, widget_pos_flags_t pos_flags); +int add_widget (Dlg_head *dest, void *w); + +/* sets size of dialog, leaving positioning to automatic mehtods + according to dialog flags */ +void dlg_set_size (Dlg_head *h, int lines, int cols); +/* this function allows to set dialog position */ +void dlg_set_position (Dlg_head *h, int y1, int x1, int y2, int x2); /* Runs dialog d */ int run_dlg (Dlg_head *d); @@ -177,7 +200,7 @@ void set_idle_proc (Dlg_head *d, int enable); void dlg_redraw (Dlg_head *h); void destroy_dlg (Dlg_head *h); -void widget_set_size (Widget *widget, int x1, int y1, int x2, int y2); +void widget_set_size (Widget *widget, int y, int x, int lines, int cols); void dlg_broadcast_msg (Dlg_head *h, widget_msg_t message, int reverse); @@ -187,9 +210,6 @@ void init_widget (Widget *w, int y, int x, int lines, int cols, /* Default callback for dialogs */ cb_ret_t default_dlg_callback (Dlg_head *h, dlg_msg_t msg, int parm); -/* Default callback for widgets */ -cb_ret_t default_proc (widget_msg_t msg, int parm); - /* Default paint routine for dialogs */ void common_dialog_repaint (struct Dlg_head *h); diff --git a/src/file.c b/src/file.c index 5d1ab9adc..2e41bb5fe 100644 --- a/src/file.c +++ b/src/file.c @@ -427,7 +427,7 @@ copy_file_file (FileOpContext *ctx, const char *src_path, const char *dst_path, file_progress_show_target (ctx, dst_path) == FILE_ABORT) return FILE_ABORT; - tty_refresh (); + mc_refresh (); while (mc_stat (dst_path, &sb2) == 0) { if (S_ISDIR (sb2.st_mode)) { @@ -582,7 +582,7 @@ copy_file_file (FileOpContext *ctx, const char *src_path, const char *dst_path, return_status = file_progress_show (ctx, 0, file_size); - tty_refresh (); + mc_refresh (); if (return_status != FILE_CONT) goto ret; @@ -682,7 +682,7 @@ copy_file_file (FileOpContext *ctx, const char *src_path, const char *dst_path, return_status = file_progress_show (ctx, n_read_total + ctx->do_reget, file_size); } - tty_refresh (); + mc_refresh (); if (return_status != FILE_CONT) goto ret; } @@ -996,7 +996,7 @@ move_file_file (FileOpContext *ctx, const char *s, const char *d, || file_progress_show_target (ctx, d) == FILE_ABORT) return FILE_ABORT; - tty_refresh (); + mc_refresh (); while (mc_lstat (s, &src_stats) != 0) { /* Source doesn't exist */ @@ -1071,7 +1071,7 @@ move_file_file (FileOpContext *ctx, const char *s, const char *d, || (return_status = file_progress_show (ctx, 0, 0)) != FILE_CONT) return return_status; - tty_refresh (); + mc_refresh (); retry_src_remove: if (mc_unlink (s)) { @@ -1107,7 +1107,7 @@ move_dir_dir (FileOpContext *ctx, const char *s, const char *d, file_progress_show_target (ctx, d) == FILE_ABORT) return FILE_ABORT; - tty_refresh (); + mc_refresh (); mc_stat (s, &sbuf); dstat_ok = (mc_stat (d, &dbuf) == 0); @@ -1178,7 +1178,7 @@ move_dir_dir (FileOpContext *ctx, const char *s, const char *d, || (return_status = file_progress_show (ctx, 0, 0)) != FILE_CONT) goto ret; - tty_refresh (); + mc_refresh (); if (ctx->erase_at_end) { for (; erase_list && return_status != FILE_ABORT;) { if (S_ISDIR (erase_list->st_mode)) { @@ -1217,7 +1217,7 @@ erase_file (FileOpContext *ctx, const char *s, off_t *progress_count, if (file_progress_show_deleting (ctx, s) == FILE_ABORT) return FILE_ABORT; - tty_refresh (); + mc_refresh (); if (progress_count && mc_lstat (s, &buf)) { /* ignore, most likely the mc_unlink fails, too */ @@ -1282,7 +1282,7 @@ recursive_erase (FileOpContext *ctx, const char *s, off_t *progress_count, return return_status; if (file_progress_show_deleting (ctx, s) == FILE_ABORT) return FILE_ABORT; - tty_refresh (); + mc_refresh (); while (my_rmdir (s)) { return_status = @@ -1334,7 +1334,7 @@ erase_dir (FileOpContext *ctx, const char *s, off_t *progress_count, if (file_progress_show_deleting (ctx, s) == FILE_ABORT) return FILE_ABORT; - tty_refresh (); + mc_refresh (); /* The old way to detect a non empty directory was: error = my_rmdir (s); @@ -1376,7 +1376,7 @@ erase_dir_iff_empty (FileOpContext *ctx, const char *s) if (file_progress_show_deleting (ctx, s) == FILE_ABORT) return FILE_ABORT; - tty_refresh (); + mc_refresh (); if (1 != check_dir_is_empty (s)) /* not empty or error */ return FILE_CONT; @@ -2110,7 +2110,7 @@ panel_operate (void *source_panel, FileOperation operation, && file_progress_show (ctx, 0, 0) == FILE_ABORT) goto clean_up; - tty_refresh (); + mc_refresh (); } /* Loop for every file */ } /* Many entries */ clean_up: diff --git a/src/find.c b/src/find.c index fbff017c8..cba7a2809 100644 --- a/src/find.c +++ b/src/find.c @@ -52,6 +52,7 @@ #include "cmd.h" /* view_file_at_line */ #include "boxes.h" #include "history.h" /* MC_HISTORY_SHARED_SEARCH */ +#include "layout.h" /* mc_refresh() */ /* Size of the find parameters window */ #if HAVE_CHARSET @@ -664,7 +665,7 @@ search_content (Dlg_head *h, const char *directory, const char *filename) g_snprintf (buffer, sizeof (buffer), _("Grepping in %s"), str_trunc (filename, FIND2_X_USE)); status_update (buffer); - tty_refresh (); + mc_refresh (); tty_enable_interrupt_key (); tty_got_interrupt (); @@ -896,7 +897,7 @@ do_search (struct Dlg_head *h) tty_setcolor (DLG_NORMALC (h)); dlg_move (h, FIND2_Y - 7, FIND2_X - 4); tty_print_char (rotating_dash [pos]); - tty_refresh (); + mc_refresh (); } } else goto do_search_begin; diff --git a/src/hotlist.c b/src/hotlist.c index bc873ae37..8cc5dc7b0 100644 --- a/src/hotlist.c +++ b/src/hotlist.c @@ -124,21 +124,22 @@ static struct _hotlist_but { int ret_cmd, flags, y, x; const char *text; int type; + widget_pos_flags_t pos_flags; } hotlist_but[] = { - { B_MOVE, NORMAL_BUTTON, 1, 42, N_("&Move"), LIST_HOTLIST}, - { B_REMOVE, NORMAL_BUTTON, 1, 30, N_("&Remove"), LIST_HOTLIST}, - { B_APPEND, NORMAL_BUTTON, 1, 15, N_("&Append"), LIST_MOVELIST}, - { B_INSERT, NORMAL_BUTTON, 1, 0, N_("&Insert"), LIST_MOVELIST}, - { B_NEW_ENTRY, NORMAL_BUTTON, 1, 15, N_("New &Entry"), LIST_HOTLIST}, - { B_NEW_GROUP, NORMAL_BUTTON, 1, 0, N_("New &Group"), LIST_HOTLIST}, - { B_CANCEL, NORMAL_BUTTON, 0, 53, N_("&Cancel"), LIST_HOTLIST|LIST_VFSLIST|LIST_MOVELIST}, - { B_UP_GROUP, NORMAL_BUTTON, 0, 42, N_("&Up"), LIST_HOTLIST|LIST_MOVELIST}, - { B_ADD_CURRENT, NORMAL_BUTTON, 0, 20, N_("&Add current"), LIST_HOTLIST}, + { B_MOVE, NORMAL_BUTTON, 1, 42, N_("&Move"), LIST_HOTLIST, WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM }, + { B_REMOVE, NORMAL_BUTTON, 1, 30, N_("&Remove"), LIST_HOTLIST, WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM }, + { B_APPEND, NORMAL_BUTTON, 1, 15, N_("&Append"), LIST_MOVELIST, WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM }, + { B_INSERT, NORMAL_BUTTON, 1, 0, N_("&Insert"), LIST_MOVELIST, WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM }, + { B_NEW_ENTRY, NORMAL_BUTTON, 1, 15, N_("New &Entry"), LIST_HOTLIST, WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM }, + { B_NEW_GROUP, NORMAL_BUTTON, 1, 0, N_("New &Group"), LIST_HOTLIST, WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM }, + { B_CANCEL, NORMAL_BUTTON, 0, 53, N_("&Cancel"), LIST_HOTLIST | LIST_VFSLIST|LIST_MOVELIST, WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM }, + { B_UP_GROUP, NORMAL_BUTTON, 0, 42, N_("&Up"), LIST_HOTLIST | LIST_MOVELIST, WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM }, + { B_ADD_CURRENT, NORMAL_BUTTON, 0, 20, N_("&Add current"), LIST_HOTLIST, WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM }, #ifdef USE_VFS - { B_REFRESH_VFS, NORMAL_BUTTON, 0, 43, N_("&Refresh"), LIST_VFSLIST}, - { B_FREE_ALL_VFS, NORMAL_BUTTON, 0, 20, N_("Fr&ee VFSs now"), LIST_VFSLIST}, + { B_REFRESH_VFS, NORMAL_BUTTON, 0, 43, N_("&Refresh"), LIST_VFSLIST, WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM }, + { B_FREE_ALL_VFS, NORMAL_BUTTON, 0, 20, N_("Fr&ee VFSs now"), LIST_VFSLIST, WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM }, #endif - { B_ENTER, DEFPUSH_BUTTON, 0, 0, N_("Change &To"), LIST_HOTLIST|LIST_VFSLIST|LIST_MOVELIST}, + { B_ENTER, DEFPUSH_BUTTON, 0, 0, N_("Change &To"), LIST_HOTLIST | LIST_VFSLIST | LIST_MOVELIST, WPOS_KEEP_LEFT | WPOS_KEEP_BOTTOM } }; /* Directory hotlist */ @@ -491,6 +492,11 @@ hotlist_callback (Dlg_head *h, dlg_msg_t msg, int parm) update_path_name (); return MSG_HANDLED; + case DLG_RESIZE: + /* simply call dlg_set_size() with new size */ + dlg_set_size (h, LINES - 2, COLS - 6); + return MSG_HANDLED; + default: return default_dlg_callback (h, msg, parm); } @@ -634,13 +640,14 @@ init_hotlist (int list_type) for (i = 0; i < BUTTONS; i++) { if (hotlist_but[i].type & list_type) - add_widget (hotlist_dlg, + add_widget_autopos (hotlist_dlg, button_new (BY + hotlist_but[i].y, BX + hotlist_but[i].x, hotlist_but[i].ret_cmd, hotlist_but[i].flags, hotlist_but[i].text, - hotlist_button_callback)); + hotlist_button_callback), + hotlist_but[i].pos_flags); } /* We add the labels. @@ -648,11 +655,12 @@ init_hotlist (int list_type) * pname_group will hold name of current group */ pname = label_new (UY - 11 + LINES, UX + 2, ""); - add_widget (hotlist_dlg, pname); + add_widget_autopos (hotlist_dlg, pname, WPOS_KEEP_BOTTOM | WPOS_KEEP_LEFT); if (!hotlist_state.moving) { - add_widget (hotlist_dlg, + add_widget_autopos (hotlist_dlg, label_new (UY - 12 + LINES, UX + 1, - _(" Directory path "))); + _(" Directory path ")), + WPOS_KEEP_BOTTOM | WPOS_KEEP_LEFT); /* This one holds the displayed pathname */ pname_group = label_new (UY, UX + 1, _(" Directory label ")); @@ -672,7 +680,7 @@ init_hotlist (int list_type) #endif /* !USE_VFS */ fill_listbox (); - add_widget (hotlist_dlg, l_hotlist); + add_widget_autopos (hotlist_dlg, l_hotlist, WPOS_KEEP_ALL); /* add listbox to the dialogs */ } diff --git a/src/info.c b/src/info.c index 3d287393c..0ad7f4e62 100644 --- a/src/info.c +++ b/src/info.c @@ -29,6 +29,7 @@ #include "../src/tty/mouse.h" /* Gpm_Event */ #include "../src/tty/color.h" #include "dialog.h" +#include "widget.h" /* default_proc*/ #include "info.h" #include "dir.h" /* required by panel */ #include "panel.h" /* for the panel structure */ diff --git a/src/layout.c b/src/layout.c index b94a28696..5b6e8a018 100644 --- a/src/layout.c +++ b/src/layout.c @@ -64,6 +64,7 @@ #include "tree.h" #include "menu.h" #include "strutil.h" +#include "background.h" /* we_are_background */ /* Needed for the extern declarations of integer parameters */ #include "dir.h" @@ -585,6 +586,22 @@ repaint_screen (void) tty_refresh (); } +void +mc_refresh (void) +{ +#ifdef WITH_BACKGROUND + if (we_are_background) + return; +#endif /* WITH_BACKGROUND */ + if (winch_flag == 0) + tty_refresh (); + else { + /* if winch was caugth, we should do not only redraw screen, but + reposition/resize all */ + change_screen_size (); + } +} + static void panel_do_cols (int index) { @@ -645,10 +662,8 @@ setup_panels (void) if (command_prompt) { widget_set_size (&cmdline->widget, LINES - 1 - keybar_visible, - promptl, 1, - COLS - promptl - (keybar_visible ? 0 : 1)); - winput_set_origin (cmdline, promptl, - COLS - promptl - (keybar_visible ? 0 : 1)); + promptl, 1, COLS - promptl); + winput_set_origin (cmdline, promptl, COLS - promptl); widget_set_size (&the_prompt->widget, LINES - 1 - keybar_visible, 0, 1, promptl); } else { @@ -715,6 +730,8 @@ low_level_change_screen_size (void) void change_screen_size (void) { + Dlg_head *d; + winch_flag = 0; #if defined(HAVE_SLANG) || NCURSES_VERSION_MAJOR >= 4 #if defined TIOCGWINSZ @@ -738,8 +755,12 @@ change_screen_size (void) #endif setup_panels (); - /* Inform currently running dialog */ - (*current_dlg->callback) (current_dlg, DLG_RESIZE, 0); + /* Inform all running dialogs */ + d = current_dlg; + while (d != NULL) { + (*d->callback) (d, DLG_RESIZE, 0); + d = d->parent; + } #ifdef RESIZABLE_MENUBAR menubar_arrange (the_menubar); @@ -765,7 +786,7 @@ void set_hintbar(const char *str) { label_set_text (the_hint, str); if (ok_to_refresh > 0) - tty_refresh(); + mc_refresh(); } void print_vfs_message (const char *msg, ...) @@ -796,7 +817,7 @@ void print_vfs_message (const char *msg, ...) /* Restore cursor position */ tty_gotoyx (row, col); - tty_refresh (); + mc_refresh (); return; } @@ -818,7 +839,7 @@ void rotate_dash (void) tty_gotoyx (0, COLS - 1); tty_setcolor (NORMAL_COLOR); tty_print_char (rotating_dash [pos]); - tty_refresh (); + mc_refresh (); pos++; } diff --git a/src/layout.h b/src/layout.h index dc86b18ec..6a68055f5 100644 --- a/src/layout.h +++ b/src/layout.h @@ -35,6 +35,7 @@ void set_hintbar (const char *str); /* Clear screen */ void clr_scr (void); void repaint_screen (void); +void mc_refresh (void); extern int winch_flag; extern int equal_split; diff --git a/src/learn.c b/src/learn.c index 23df9d30f..505973920 100644 --- a/src/learn.c +++ b/src/learn.c @@ -91,7 +91,7 @@ _("Please press the %s\n" "If you want to escape, press a single Escape key\n" "and wait as well."), _(key_name_conv_tab [action - B_USER].longname)); - tty_refresh (); + mc_refresh (); if (learnkeys [action - B_USER].sequence != NULL) { g_free (learnkeys [action - B_USER].sequence); learnkeys [action - B_USER].sequence = NULL; diff --git a/src/main.c b/src/main.c index 7fc028ba5..9e7c8a862 100644 --- a/src/main.c +++ b/src/main.c @@ -553,7 +553,7 @@ directory_history_list (WPanel *panel) if (!panel->dir_history) return; - s = show_hist (panel->dir_history, panel->widget.x, panel->widget.y); + s = show_hist (panel->dir_history, &panel->widget); if (!s) return; @@ -598,7 +598,7 @@ load_prompt (int fd, void *unused) * automatically: force a cursor update and a screen refresh */ update_cursor (midnight_dlg); - tty_refresh (); + mc_refresh (); } update_prompt = 1; return 0; diff --git a/src/menu.c b/src/menu.c index 64b4fc11e..25c8d272a 100644 --- a/src/menu.c +++ b/src/menu.c @@ -37,6 +37,7 @@ #include "menu.h" #include "help.h" #include "dialog.h" +#include "widget.h" #include "main.h" /* is_right */ #include "strutil.h" diff --git a/src/screen.c b/src/screen.c index b76a2b1c6..cfee8a975 100644 --- a/src/screen.c +++ b/src/screen.c @@ -2140,7 +2140,7 @@ start_search (WPanel *panel) panel->search_char[0] = '\0'; panel->search_chpoint = 0; display_mini_info (panel); - tty_refresh (); + mc_refresh (); } } diff --git a/src/tty/key.c b/src/tty/key.c index 456582a36..e7fe3e45c 100644 --- a/src/tty/key.c +++ b/src/tty/key.c @@ -46,7 +46,7 @@ #include "../../src/tty/win.h" /* xterm_flag */ #include "../../src/main.h" -#include "../../src/layout.h" /* winch_flag */ +#include "../../src/layout.h" /* winch_flag, mc_refresh() */ #include "../../src/cons.saver.h" #include "../../src/strutil.h" /* str_casecmp */ @@ -1509,7 +1509,7 @@ tty_get_event (struct Gpm_Event *event, gboolean redo_event, gboolean block) static int dirty = 3; if ((dirty == 3) || is_idle ()) { - tty_refresh (); + mc_refresh (); dirty = 1; } else dirty++; diff --git a/src/tty/tty-ncurses.c b/src/tty/tty-ncurses.c index 0e24a15ea..96085068a 100644 --- a/src/tty/tty-ncurses.c +++ b/src/tty/tty-ncurses.c @@ -47,7 +47,6 @@ #include "../../src/tty/color-internal.h" #include "../../src/tty/win.h" -#include "../../src/background.h" /* we_are_background */ #include "../../src/strutil.h" /* str_term_form */ /* include at last !!! */ @@ -317,13 +316,8 @@ tty_tgetstr (const char *cap) void tty_refresh (void) { -#ifdef WITH_BACKGROUND - if (!we_are_background) -#endif /* WITH_BACKGROUND */ - { - refresh (); - doupdate (); - } + refresh (); + doupdate (); } void diff --git a/src/tty/tty-slang.c b/src/tty/tty-slang.c index 50a47ad1c..c7c9ad91d 100644 --- a/src/tty/tty-slang.c +++ b/src/tty/tty-slang.c @@ -51,7 +51,6 @@ #include "../../src/tty/key.h" /* define_sequence */ #include "../../src/tty/win.h" -#include "../../src/background.h" /* we_are_background */ #include "../../src/strutil.h" /* str_term_form */ /*** global variables **************************************************/ @@ -497,10 +496,7 @@ tty_tgetstr (const char *cap) void tty_refresh (void) { -#ifdef WITH_BACKGROUND - if (!we_are_background) -#endif /* WITH_BACKGROUND */ - SLsmg_refresh (); + SLsmg_refresh (); } void diff --git a/src/tty/tty.h b/src/tty/tty.h index 40806b107..f72cdf164 100644 --- a/src/tty/tty.h +++ b/src/tty/tty.h @@ -45,7 +45,6 @@ extern void tty_nodelay (gboolean set); extern int tty_baudrate (void); extern int tty_lowlevel_getch (void); -extern int tty_getch (void); /* {{{ Output }}} */ diff --git a/src/view.c b/src/view.c index 07d9be34f..8f105aa9d 100644 --- a/src/view.c +++ b/src/view.c @@ -3079,7 +3079,7 @@ view_search_update_cmd_callback(const void *user_data, gsize char_offset) view->update_activate += view->update_steps; if (verbose) { view_percent (view, char_offset); - tty_refresh (); + mc_refresh (); } if (tty_got_interrupt ()) return MC_SEARCH_CB_ABORT; @@ -3169,7 +3169,7 @@ do_search (WView *view) if (verbose) { d = create_message (D_NORMAL, _("Search"), _("Searching %s"), view->last_search_string); - tty_refresh (); + mc_refresh (); } /*for avoid infinite search loop we need to increase or decrease start offset of search */ @@ -3217,7 +3217,7 @@ do_search (WView *view) dlg_run_done (d); destroy_dlg (d); d = create_message (D_NORMAL, _("Search"), _("Seeking to search result")); - tty_refresh (); + mc_refresh (); } view_moveto_match (view); diff --git a/src/widget.c b/src/widget.c index 05ffb1462..eac826c1f 100644 --- a/src/widget.c +++ b/src/widget.c @@ -148,6 +148,28 @@ draw_hotkey (Widget *w, const struct hotkey_t hotkey, gboolean focused) tty_print_string (hotkey.end); } + +/* Default callback for widgets */ +cb_ret_t +default_proc (widget_msg_t msg, int parm) +{ + (void) parm; + + switch (msg) { + case WIDGET_INIT: + case WIDGET_FOCUS: + case WIDGET_UNFOCUS: + case WIDGET_DRAW: + case WIDGET_DESTROY: + case WIDGET_CURSOR: + case WIDGET_IDLE: + return MSG_HANDLED; + + default: + return MSG_NOT_HANDLED; + } +} + static int button_event (Gpm_Event *event, void *); int quote = 0; @@ -1011,55 +1033,111 @@ listbox_fwd (WListbox *l) listbox_select_first (l); } +typedef struct { + Widget *widget; + int count; + size_t maxlen; +} dlg_hist_data; + +static cb_ret_t +dlg_hist_reposition (Dlg_head *dlg_head) +{ + dlg_hist_data *data; + int x = 0, y, he, wi; + + /* guard checks */ + if ((dlg_head == NULL) + || (dlg_head->data == NULL)) + return MSG_NOT_HANDLED; + + data = (dlg_hist_data *) dlg_head->data; + + y = data->widget->y; + he = data->count + 2; + + if (he <= y || y > (LINES - 6)) { + he = min (he, y - 1); + y -= he; + } else { + y++; + he = min (he, LINES - y); + } + + if (data->widget->x > 2) + x = data->widget->x - 2; + + wi = data->maxlen + 4; + + if ((wi + x) > COLS) { + wi = min (wi, COLS); + x = COLS - wi; + } + + dlg_set_position (dlg_head, y, x, y + he, x + wi); + + return MSG_HANDLED; +} + +static cb_ret_t +dlg_hist_callback (Dlg_head *h, dlg_msg_t msg, int parm) +{ + switch (msg) { + case DLG_RESIZE: + return dlg_hist_reposition (h); + + default: + return default_dlg_callback (h, msg, parm); + } +} + char * -show_hist (GList *history, int widget_x, int widget_y) +show_hist (GList *history, Widget *widget) { GList *hi, *z; - size_t maxlen = str_term_width1 (i18n_htitle ()), i, count = 0; - int x, y, w, h; - char *q = NULL, *r = NULL; + size_t maxlen, i, count = 0; + char *q, *r = NULL; Dlg_head *query_dlg; WListbox *query_list; + dlg_hist_data hist_data; - z = history; - if (!z) + if (history == NULL) return NULL; + maxlen = str_term_width1 (i18n_htitle ()); + z = g_list_first (history); hi = z; while (hi) { - if ((i = str_term_width1 ((char *) hi->data)) > maxlen) - maxlen = i; + i = str_term_width1 ((char *) hi->data); + maxlen = max (maxlen, i); count++; hi = g_list_next (hi); } - y = widget_y; - h = count + 2; - if (h <= y || y > LINES - 6) { - h = min (h, y - 1); - y -= h; - } else { - y++; - h = min (h, LINES - y); - } - - if (widget_x > 2) - x = widget_x - 2; - else - x = 0; - if ((w = maxlen + 4) + x > COLS) { - w = min (w, COLS); - x = COLS - w; - } + hist_data.maxlen = maxlen; + hist_data.widget = widget; + hist_data.count = count; query_dlg = - create_dlg (y, x, h, w, dialog_colors, NULL, "[History-query]", - i18n_htitle (), DLG_COMPACT); - query_list = listbox_new (1, 1, h - 2, w - 2, NULL); - add_widget (query_dlg, query_list); + create_dlg (0, 0, 4, 4, dialog_colors, dlg_hist_callback, + "[History-query]", i18n_htitle (), DLG_COMPACT); + query_dlg->data = &hist_data; - if (y < widget_y) { + query_list = listbox_new (1, 1, 2, 2, NULL); + + /* 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); + + /* to avoid diplicating of (calculating sizes in two places) + code, call dlg_hist_callback function here, to set dialog and + controls positions. + The main idea - create 4x4 dialog and add 2x2 list in + center of it, and let dialog function resize it to needed + size. */ + dlg_hist_callback (query_dlg, DLG_RESIZE, 0); + + if (query_dlg->y < widget->y) { /* traverse */ hi = z; while (hi) { @@ -1088,10 +1166,10 @@ show_hist (GList *history, int widget_x, int widget_y) } static void -do_show_hist (WInput * in) +do_show_hist (WInput *in) { char *r; - r = show_hist (in->history, in->widget.x, in->widget.y); + r = show_hist (in->history, &in->widget); if (r) { assign_text (in, r); g_free (r); @@ -2210,6 +2288,9 @@ listbox_callback (Widget *w, widget_msg_t msg, int parm) listbox_destroy (l); return MSG_HANDLED; + case WIDGET_RESIZED: + return MSG_HANDLED; + default: return default_proc (msg, parm); } @@ -2246,7 +2327,7 @@ listbox_event (Gpm_Event *event, void *data) /* We need to refresh ourselves since the dialog manager doesn't */ /* know about this event */ listbox_callback (w, WIDGET_DRAW, 0); - tty_refresh (); + mc_refresh (); return MOU_REPEAT; } diff --git a/src/widget.h b/src/widget.h index b410db2c0..39c17d03d 100644 --- a/src/widget.h +++ b/src/widget.h @@ -92,7 +92,9 @@ typedef struct WGauge { GList *history_get (const char *input_name); void history_put (const char *input_name, GList *h); -char *show_hist (GList *history, int widget_y, int widget_x); +/* for repositioning of history dialog we should pass widget to this + * function, as position of history dialog depends on widget's position */ +char *show_hist (GList *history, Widget *widget); typedef struct { Widget widget; @@ -162,6 +164,9 @@ typedef struct WGroupbox { } WGroupbox; +/* Default callback for widgets */ +cb_ret_t default_proc (widget_msg_t msg, int parm); + /* Constructors */ WButton *button_new (int y, int x, int action, int flags, const char *text, bcback callback); diff --git a/src/wtools.c b/src/wtools.c index 70aa94ae1..590d0cadf 100644 --- a/src/wtools.c +++ b/src/wtools.c @@ -94,20 +94,37 @@ create_listbox_window (int cols, int lines, const char *title, const char *help) } /* Returns the number of the item selected */ -int run_listbox (Listbox *l) +int +run_listbox (Listbox *l) { - int val; - - run_dlg (l->dlg); - if (l->dlg->ret_value == B_CANCEL) - val = -1; - else + int val = -1; + + if (run_dlg (l->dlg) != B_CANCEL) val = l->list->pos; destroy_dlg (l->dlg); g_free (l); return val; } +/* default query callback, used to reposition query */ +static cb_ret_t +default_query_callback (Dlg_head *h, dlg_msg_t msg, int parm) +{ + switch (msg) { + case DLG_RESIZE: + { + int xpos = COLS / 2 - h->cols / 2; + int ypos = LINES / 3 - (h->lines - 3) / 2; + + /* set position */ + dlg_set_position (h, ypos, xpos, ypos + h->lines, xpos + h->cols); + } + return MSG_HANDLED; + + default: + return default_dlg_callback (h, msg, parm); + } +} static Dlg_head *last_query_dlg; @@ -124,16 +141,10 @@ query_dialog (const char *header, const char *text, int flags, int count, ...) int win_len = 0; int i; int result = -1; - int xpos, ypos; int cols, lines; char *cur_name; - static const int *query_colors; - - /* set dialog colors */ - if (flags & D_ERROR) - query_colors = alarm_colors; - else - query_colors = dialog_colors; + const int *query_colors = (flags & D_ERROR) ? + alarm_colors : dialog_colors; if (header == MSG_ERROR) header = _("Error"); @@ -153,18 +164,18 @@ query_dialog (const char *header, const char *text, int flags, int count, ...) str_msg_term_size (text, &lines, &cols); cols = 6 + max (win_len, max (str_term_width1 (header), cols)); lines += 4 + (count > 0 ? 2 : 0); - xpos = COLS / 2 - cols / 2; - ypos = LINES / 3 - (lines - 3) / 2; /* prepare dialog */ query_dlg = - create_dlg (ypos, xpos, lines, cols, query_colors, NULL, + create_dlg (0, 0, lines, cols, query_colors, default_query_callback, "[QueryBox]", header, DLG_NONE); if (count > 0) { cols = (cols - win_len - 2) / 2 + 2; va_start (ap, count); for (i = 0; i < count; i++) { + int xpos; + cur_name = va_arg (ap, char *); xpos = str_term_width1 (cur_name) + 6; if (strchr (cur_name, '&') != NULL) @@ -182,12 +193,14 @@ query_dialog (const char *header, const char *text, int flags, int count, ...) add_widget (query_dlg, label_new (2, 3, text)); + /* do resize before running and selecting any widget */ + default_query_callback (query_dlg, DLG_RESIZE, 0); + if (defbutton) dlg_select_widget (defbutton); /* run dialog and make result */ - run_dlg (query_dlg); - switch (query_dlg->ret_value) { + switch (run_dlg (query_dlg)) { case B_CANCEL: break; default: @@ -223,6 +236,10 @@ do_create_message (int flags, const char *title, const char *text) p = g_strconcat ("\n", text, "\n", (char *) NULL); query_dialog (title, p, flags, 0); d = last_query_dlg; + + /* do resize before initing and running */ + default_query_callback (d, DLG_RESIZE, 0); + init_dlg (d); g_free (p); diff --git a/vfs/ftpfs.c b/vfs/ftpfs.c index 51a1f806a..135733270 100644 --- a/vfs/ftpfs.c +++ b/vfs/ftpfs.c @@ -65,6 +65,7 @@ What to do with this? /* \todo Fix: Namespace pollution: horrible */ #include +#include /* atoi() */ #include /* POSIX-required by sys/socket.h and netdb.h */ #include /* struct hostent */ #include /* AF_INET */ @@ -1039,7 +1040,7 @@ again: port = ntohs (port); - addr = malloc (NI_MAXHOST); + addr = g_malloc (NI_MAXHOST); if (addr == NULL) ERRNOR (ENOMEM, -1);