Create WFrame widget.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Andrew Borodin 2016-10-16 11:01:30 +03:00
parent c77dc88ff9
commit ed9199e94e
14 changed files with 358 additions and 128 deletions

View File

@ -18,6 +18,7 @@ typedef struct WGroup WGroup;
#include "lib/widget/rect.h"
#include "lib/widget/widget-common.h"
#include "lib/widget/group.h"
#include "lib/widget/frame.h"
#include "lib/widget/dialog.h"
#include "lib/widget/history.h"
#include "lib/widget/button.h"

View File

@ -7,6 +7,7 @@ libmcwidget_la_SOURCES = \
check.c check.h \
dialog.c dialog.h \
dialog-switch.c dialog-switch.h \
frame.c frame.h \
gauge.c gauge.h \
group.c group.h \
groupbox.c groupbox.h \

View File

@ -448,56 +448,14 @@ frontend_dlg_run (WDialog * h)
/* --------------------------------------------------------------------------------------------- */
/*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */
/** Clean the dialog area, draw the frame and the title */
void
dlg_default_repaint (WDialog * h)
{
Widget *wh = WIDGET (h);
int space;
if (!widget_get_state (wh, WST_ACTIVE))
return;
space = h->compact ? 0 : 1;
tty_setcolor (h->color[DLG_COLOR_NORMAL]);
dlg_erase (h);
tty_draw_box (wh->y + space, wh->x + space, wh->lines - 2 * space, wh->cols - 2 * space, FALSE);
if (h->title != NULL)
{
/* TODO: truncate long title */
tty_setcolor (h->color[DLG_COLOR_TITLE]);
widget_gotoyx (h, space, (wh->cols - str_term_width1 (h->title)) / 2);
tty_print_string (h->title);
}
}
/* --------------------------------------------------------------------------------------------- */
/** Default dialog callback */
cb_ret_t
dlg_default_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
{
WDialog *h = DIALOG (w);
(void) sender;
(void) parm;
(void) data;
switch (msg)
{
case MSG_DRAW:
if (h->color != NULL)
{
dlg_default_repaint (h);
return MSG_HANDLED;
}
return MSG_NOT_HANDLED;
case MSG_IDLE:
/* we don't want endless loop */
widget_idle (w, FALSE);
@ -517,19 +475,18 @@ dlg_create (gboolean modal, int y1, int x1, int lines, int cols, widget_pos_flag
{
WDialog *new_d;
Widget *w;
WGroup *g;
new_d = g_new0 (WDialog, 1);
w = WIDGET (new_d);
g = GROUP (new_d);
widget_adjust_position (pos_flags, &y1, &x1, &lines, &cols);
group_init (GROUP (new_d), y1, x1, lines, cols,
callback != NULL ? callback : dlg_default_callback, mouse_callback);
group_init (g, y1, x1, lines, cols, callback != NULL ? callback : dlg_default_callback,
mouse_callback);
w->pos_flags = pos_flags;
w->options |= WOP_SELECTABLE | WOP_TOP_SELECT;
w->state |= WST_CONSTRUCT | WST_FOCUSED;
if (modal)
w->state |= WST_MODAL;
new_d->color = colors;
new_d->help_ctx = help_ctx;
@ -538,7 +495,24 @@ dlg_create (gboolean modal, int y1, int x1, int lines, int cols, widget_pos_flag
new_d->mouse_status = MOU_UNHANDLED;
dlg_set_title (new_d, title);
if (modal)
{
frame_colors_t frame_colors;
w->state |= WST_MODAL;
if (new_d->color != NULL)
{
frame_colors[FRAME_COLOR_NORMAL] = new_d->color[DLG_COLOR_NORMAL];
frame_colors[FRAME_COLOR_TITLE] = new_d->color[DLG_COLOR_TITLE];
}
new_d->frame =
frame_new (0, 0, w->lines, w->cols, title,
new_d->color != NULL ? frame_colors : NULL, FALSE, new_d->compact);
group_add_widget (g, new_d->frame);
frame_set_title (new_d->frame, title);
}
/* unique name of event group for this dialog */
new_d->event_group = g_strdup_printf ("%s_%p", MCEVENT_GROUP_DIALOG, (void *) new_d);
@ -745,7 +719,6 @@ dlg_destroy (WDialog * h)
group_default_callback (WIDGET (h), NULL, MSG_DESTROY, 0, NULL);
mc_event_group_del (h->event_group);
g_free (h->event_group);
g_free (h->title);
g_free (h);
do_refresh ();
@ -790,25 +763,6 @@ dlg_save_history (WDialog * h)
/* --------------------------------------------------------------------------------------------- */
void
dlg_set_title (WDialog * h, const char *title)
{
MC_PTR_FREE (h->title);
/* Strip existing spaces, add one space before and after the title */
if (title != NULL && title[0] != '\0')
{
char *t;
t = g_strstrip (g_strdup (title));
if (t[0] != '\0')
h->title = g_strdup_printf (" %s ", t);
g_free (t);
}
}
/* --------------------------------------------------------------------------------------------- */
char *
dlg_get_title (const WDialog * h, size_t len)
{

View File

@ -66,7 +66,6 @@ struct WDialog
gboolean compact; /* Suppress spaces around the frame */
const char *help_ctx; /* Name of the help entry */
const int *color; /* Color set. Unused in viewer and editor */
char *title; /* Title of the dialog */
/* Set and received by the user */
int ret_value; /* Result of dlg_run() */
@ -77,6 +76,7 @@ struct WDialog
/* Internal variables */
void *data; /* Data can be passed to dialog */
char *event_group; /* Name of event group for this dialog */
WFrame *frame; /* Frame. Frame is used as background */
dlg_shortcut_str get_shortcut; /* Shortcut string */
dlg_title_str get_title; /* useless for modal dialogs */
@ -117,7 +117,6 @@ void dlg_run_done (WDialog * h);
void dlg_save_history (WDialog * h);
void dlg_process_event (WDialog * h, int key, Gpm_Event * event);
void dlg_set_title (WDialog * h, const char *title);
char *dlg_get_title (const WDialog * h, size_t len);
void dlg_draw (WDialog * h);
@ -125,9 +124,6 @@ void dlg_draw (WDialog * h);
/* Default callback for dialogs */
cb_ret_t dlg_default_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data);
/* Default paint routine for dialogs */
void dlg_default_repaint (WDialog * h);
void dlg_erase (WDialog * h);
void dlg_stop (WDialog * h);

168
lib/widget/frame.c Normal file
View File

@ -0,0 +1,168 @@
/*
Widgets for the Midnight Commander
Copyright (C) 2020
The Free Software Foundation, Inc.
Authors:
Andrew Borodin <aborodin@vmail.ru>, 2020
This file is part of the Midnight Commander.
The Midnight Commander is free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the License,
or (at your option) any later version.
The Midnight Commander is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file frame.c
* \brief Source: WFrame widget (frame of dialogs)
*/
#include <config.h>
#include <stdlib.h>
#include "lib/global.h"
#include "lib/tty/tty.h"
#include "lib/tty/color.h"
#include "lib/skin.h"
#include "lib/strutil.h"
#include "lib/util.h" /* MC_PTR_FREE */
#include "lib/widget.h"
/*** global variables ****************************************************************************/
/*** file scope macro definitions ****************************************************************/
/*** file scope type declarations ****************************************************************/
/*** file scope variables ************************************************************************/
/* --------------------------------------------------------------------------------------------- */
/*** file scope functions ************************************************************************/
/* --------------------------------------------------------------------------------------------- */
static void
frame_adjust (WFrame * f)
{
Widget *w = WIDGET (f);
Widget *wo = WIDGET (w->owner);
w->y = wo->y;
w->x = wo->x;
w->lines = wo->lines;
w->cols = wo->cols;
w->pos_flags |= WPOS_KEEP_ALL;
}
/* --------------------------------------------------------------------------------------------- */
static void
frame_draw (const WFrame * f)
{
const Widget *w = CONST_WIDGET (f);
int d = f->compact ? 0 : 1;
tty_setcolor (f->colors[FRAME_COLOR_NORMAL]);
tty_fill_region (w->y, w->x, w->lines, w->cols, ' ');
tty_draw_box (w->y + d, w->x + d, w->lines - 2 * d, w->cols - 2 * d, f->single);
if (f->title != NULL)
{
/* TODO: truncate long title */
tty_setcolor (f->colors[FRAME_COLOR_TITLE]);
widget_gotoyx (w, d, (w->cols - str_term_width1 (f->title)) / 2);
tty_print_string (f->title);
}
}
/* --------------------------------------------------------------------------------------------- */
/*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */
WFrame *
frame_new (int y, int x, int lines, int cols, const char *title, const int *colors, gboolean single,
gboolean compact)
{
WFrame *f;
Widget *w;
f = g_new (WFrame, 1);
w = WIDGET (f);
widget_init (w, y, x, lines, cols, frame_callback, NULL);
if (colors != NULL)
memmove (f->colors, colors, sizeof (frame_colors_t));
else
{
f->colors[FRAME_COLOR_NORMAL] = COLOR_NORMAL;
f->colors[FRAME_COLOR_TITLE] = COLOR_TITLE;
}
f->single = single;
f->compact = compact;
f->title = NULL;
frame_set_title (f, title);
return f;
}
/* --------------------------------------------------------------------------------------------- */
cb_ret_t
frame_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
{
WFrame *f = FRAME (w);
switch (msg)
{
case MSG_INIT:
frame_adjust (f);
return MSG_HANDLED;
case MSG_DRAW:
frame_draw (f);
return MSG_HANDLED;
case MSG_DESTROY:
g_free (f->title);
return MSG_HANDLED;
default:
return widget_default_callback (w, sender, msg, parm, data);
}
}
/* --------------------------------------------------------------------------------------------- */
void
frame_set_title (WFrame * f, const char *title)
{
MC_PTR_FREE (f->title);
/* Strip existing spaces, add one space before and after the title */
if (title != NULL && *title != '\0')
{
char *t;
t = g_strstrip (g_strdup (title));
if (*t != '\0')
f->title = g_strdup_printf (" %s ", t);
g_free (t);
}
widget_draw (WIDGET (f));
}
/* --------------------------------------------------------------------------------------------- */

51
lib/widget/frame.h Normal file
View File

@ -0,0 +1,51 @@
/** \file frame.h
* \brief Header: WFrame widget
*/
#ifndef MC__WIDGET_FRAME_H
#define MC__WIDGET_FRAME_H
/*** typedefs(not structures) and defined constants **********************************************/
#define FRAME(x) ((WFrame *)(x))
#define CONST_FRAME(x) ((const WFrame *)(x))
/*** enums ***************************************************************************************/
/* Frame color constants */
typedef enum
{
FRAME_COLOR_NORMAL = 0,
FRAME_COLOR_TITLE,
FRAME_COLOR_COUNT
} frame_colors_enum_t;
/*** typedefs(not structures) ********************************************************************/
typedef int frame_colors_t[FRAME_COLOR_COUNT];
/*** structures declarations (and typedefs of structures)*****************************************/
typedef struct
{
Widget widget;
char *title;
frame_colors_t colors;
gboolean single;
gboolean compact;
} WFrame;
/*** global variables defined in .c file *********************************************************/
/*** declarations of public functions ************************************************************/
WFrame *frame_new (int y, int x, int lines, int cols, const char *title, const int *colors,
gboolean single, gboolean compact);
cb_ret_t frame_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data);
void frame_set_title (WFrame * f, const char *title);
/*** inline functions ****************************************************************************/
#endif /* MC__WIDGET_FRAME_H */

View File

@ -571,6 +571,10 @@ quick_dialog_skip (quick_dialog_t * quick_dlg, int nskip)
}
}
/* skip frame widget */
if (dd->frame != NULL)
nskip++;
while (nskip-- != 0)
group_set_current_widget_next (GROUP (dd));

View File

@ -759,7 +759,6 @@ edit_dialog_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, v
return MSG_HANDLED;
case MSG_DRAW:
/* don't use dlg_default_repaint() -- we don't need a frame */
tty_setcolor (EDITOR_BACKGROUND);
dlg_erase (h);
return MSG_HANDLED;

View File

@ -281,8 +281,6 @@ print_flags (const WDialog * h)
static void
advanced_chown_refresh (WDialog * h)
{
dlg_default_repaint (h);
tty_setcolor (COLOR_NORMAL);
widget_gotoyx (h, BY - 1, advanced_chown_but[0].x + 5);
@ -657,20 +655,32 @@ user_group_button_cb (WButton * button, int action)
/* --------------------------------------------------------------------------------------------- */
static cb_ret_t
advanced_chown_bg_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
{
switch (msg)
{
case MSG_DRAW:
frame_callback (w, NULL, MSG_DRAW, 0, NULL);
advanced_chown_refresh (DIALOG (w->owner));
advanced_chown_info_update ();
return MSG_HANDLED;
default:
return frame_callback (w, sender, msg, parm, data);
}
}
/* --------------------------------------------------------------------------------------------- */
static cb_ret_t
advanced_chown_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
{
WGroup *g = GROUP (w);
WDialog *h = DIALOG (w);
int i = 0;
switch (msg)
{
case MSG_DRAW:
advanced_chown_refresh (h);
advanced_chown_info_update ();
return MSG_HANDLED;
case MSG_KEY:
switch (parm)
{
@ -744,6 +754,9 @@ advanced_chown_init (void)
advanced_chown_callback, NULL, "[Advanced Chown]", _("Chown advanced command"));
ch_grp = GROUP (ch_dlg);
/* draw background */
WIDGET (ch_dlg->frame)->callback = advanced_chown_bg_callback;
l_filename = label_new (2, 3, "");
group_add_widget (ch_grp, l_filename);

View File

@ -191,13 +191,11 @@ chmod_toggle_select (WDialog * h, int Id)
/* --------------------------------------------------------------------------------------------- */
static void
chmod_refresh (WDialog * h)
chmod_refresh (void)
{
int y = WIDGET (file_gb)->y + 1;
int x = WIDGET (file_gb)->x + 2;
dlg_default_repaint (h);
tty_setcolor (COLOR_NORMAL);
tty_gotoyx (y, x);
@ -212,6 +210,23 @@ chmod_refresh (WDialog * h)
/* --------------------------------------------------------------------------------------------- */
static cb_ret_t
chmod_bg_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
{
switch (msg)
{
case MSG_DRAW:
frame_callback (w, NULL, MSG_DRAW, 0, NULL);
chmod_refresh ();
return MSG_HANDLED;
default:
return frame_callback (w, sender, msg, parm, data);
}
}
/* --------------------------------------------------------------------------------------------- */
static cb_ret_t
chmod_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
{
@ -220,10 +235,6 @@ chmod_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *d
switch (msg)
{
case MSG_DRAW:
chmod_refresh (h);
return MSG_HANDLED;
case MSG_NOTIFY:
{
/* handle checkboxes */
@ -313,6 +324,9 @@ chmod_init (const char *fname, const struct stat *sf_stat)
chmod_callback, NULL, "[Chmod]", _("Chmod command"));
g = GROUP (ch_dlg);
/* draw background */
WIDGET (ch_dlg->frame)->callback = chmod_bg_callback;
group_add_widget (g, groupbox_new (PY, PX, BUTTONS_PERM + 2, perm_gb_len, _("Permission")));
for (i = 0; i < BUTTONS_PERM; i++)

View File

@ -148,13 +148,11 @@ chown_i18n (void)
/* --------------------------------------------------------------------------------------------- */
static void
chown_refresh (WDialog * h)
chown_refresh (const Widget * h)
{
int y = 3;
int x = 7 + GW * 2;
dlg_default_repaint (h);
tty_setcolor (COLOR_NORMAL);
widget_gotoyx (h, y + 0, x);
@ -172,16 +170,17 @@ chown_refresh (WDialog * h)
/* --------------------------------------------------------------------------------------------- */
static cb_ret_t
chown_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
chown_bg_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
{
switch (msg)
{
case MSG_DRAW:
chown_refresh (DIALOG (w));
frame_callback (w, NULL, MSG_DRAW, 0, NULL);
chown_refresh (WIDGET (w->owner));
return MSG_HANDLED;
default:
return dlg_default_callback (w, sender, msg, parm, data);
return frame_callback (w, sender, msg, parm, data);
}
}
@ -203,10 +202,13 @@ chown_init (void)
cols = GW * 3 + 2 + 6;
ch_dlg =
dlg_create (TRUE, 0, 0, lines, cols, WPOS_CENTER, FALSE, dialog_colors, chown_callback,
NULL, "[Chown]", _("Chown command"));
dlg_create (TRUE, 0, 0, lines, cols, WPOS_CENTER, FALSE, dialog_colors, NULL, NULL,
"[Chown]", _("Chown command"));
g = GROUP (ch_dlg);
/* draw background */
WIDGET (ch_dlg->frame)->callback = chown_bg_callback;
group_add_widget (g, groupbox_new (2, 3, GH, GW, _("User name")));
l_user = listbox_new (3, 4, GH - 2, GW - 2, FALSE, NULL);
group_add_widget (g, l_user);

View File

@ -1526,7 +1526,7 @@ find_adjust_header (WDialog * h)
memmove (title + title_len, "...", 4);
}
dlg_set_title (h, title);
frame_set_title (h->frame, title);
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -313,6 +313,36 @@ bminus_cback (WButton * button, int action)
/* --------------------------------------------------------------------------------------------- */
static cb_ret_t
layout_bg_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
{
switch (msg)
{
case MSG_DRAW:
frame_callback (w, NULL, MSG_DRAW, 0, NULL);
old_layout.output_lines = -1;
update_split (DIALOG (w->owner));
if (old_layout.output_lines != _output_lines)
{
old_layout.output_lines = _output_lines;
tty_setcolor (mc_global.tty.console_flag != '\0' ? COLOR_NORMAL : DISABLED_COLOR);
widget_gotoyx (w, 9, 5);
tty_print_string (output_lines_label);
widget_gotoyx (w, 9, 5 + 3 + output_lines_label_len);
tty_printf ("%02d", _output_lines);
}
return MSG_HANDLED;
default:
return frame_callback (w, sender, msg, parm, data);
}
}
/* --------------------------------------------------------------------------------------------- */
static cb_ret_t
layout_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
{
@ -320,26 +350,6 @@ layout_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *
switch (msg)
{
case MSG_DRAW:
/* When repainting the whole dialog (e.g. with C-l) we have to
update everything */
dlg_default_repaint (h);
old_layout.output_lines = -1;
update_split (h);
if (old_layout.output_lines != _output_lines)
{
old_layout.output_lines = _output_lines;
tty_setcolor (mc_global.tty.console_flag != '\0' ? COLOR_NORMAL : DISABLED_COLOR);
widget_gotoyx (h, 9, 5);
tty_print_string (output_lines_label);
widget_gotoyx (h, 9, 5 + 3 + output_lines_label_len);
tty_printf ("%02d", _output_lines);
}
return MSG_HANDLED;
case MSG_POST_KEY:
{
const Widget *mw = CONST_WIDGET (midnight_dlg);
@ -550,6 +560,9 @@ layout_dlg_create (void)
"[Layout]", _("Layout"));
g = GROUP (layout_dlg);
/* draw background */
WIDGET (layout_dlg->frame)->callback = layout_bg_callback;
#define XTRACT(i) (*check_options[i].variable != 0), check_options[i].text
/* "Panel split" groupbox */

View File

@ -617,7 +617,7 @@ help_help (WDialog * h)
{
currentpoint = p + 1; /* Skip the newline following the start of the node */
selected_item = NULL;
send_message (h, NULL, MSG_DRAW, 0, NULL);
dlg_redraw (h);
}
}
@ -640,7 +640,7 @@ help_index (WDialog * h)
currentpoint = new_item + 1; /* Skip the newline following the start of the node */
selected_item = NULL;
send_message (h, NULL, MSG_DRAW, 0, NULL);
dlg_redraw (h);
}
}
@ -655,7 +655,7 @@ help_back (WDialog * h)
if (history_ptr < 0)
history_ptr = HISTORY_SIZE - 1;
send_message (h, NULL, MSG_DRAW, 0, NULL); /* FIXME: unneeded? */
dlg_redraw (h); /* FIXME: unneeded? */
}
/* --------------------------------------------------------------------------------------------- */
@ -854,12 +854,29 @@ help_handle_key (WDialog * h, int c)
if ((command == CK_IgnoreKey) || (help_execute_cmd (command) == MSG_NOT_HANDLED))
return MSG_NOT_HANDLED;
send_message (h, NULL, MSG_DRAW, 0, NULL);
dlg_redraw (h);
return MSG_HANDLED;
}
/* --------------------------------------------------------------------------------------------- */
static cb_ret_t
help_bg_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
{
switch (msg)
{
case MSG_DRAW:
frame_callback (w, NULL, MSG_DRAW, 0, NULL);
help_show (DIALOG (w->owner), currentpoint);
return MSG_HANDLED;
default:
return frame_callback (w, sender, msg, parm, data);
}
}
/* --------------------------------------------------------------------------------------------- */
static cb_ret_t
help_resize (WDialog * h)
{
@ -888,11 +905,6 @@ help_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *da
case MSG_RESIZE:
return help_resize (h);
case MSG_DRAW:
dlg_default_repaint (h);
help_show (h, currentpoint);
return MSG_HANDLED;
case MSG_KEY:
return help_handle_key (h, parm);
@ -1026,7 +1038,7 @@ help_mouse_callback (Widget * w, mouse_msg_t msg, mouse_event_t * event)
move_forward (1);
/* Show the new node */
send_message (w->owner, NULL, MSG_DRAW, 0, NULL);
dlg_redraw (DIALOG (w->owner));
}
/* --------------------------------------------------------------------------------------------- */
@ -1117,6 +1129,8 @@ help_interactive_display (const gchar * event_group_name, const gchar * event_na
FALSE, help_colors, help_callback, NULL, "[Help]", _("Help"));
g = GROUP (whelp);
widget_want_tab (WIDGET (whelp), TRUE);
/* draw background */
WIDGET (whelp->frame)->callback = help_bg_callback;
selected_item = search_string_node (main_node, STRING_LINK_START) - 1;
currentpoint = main_node + 1; /* Skip the newline following the start of the node */