Ticket #2165: basic version of the user-friendly skin selector.

Thanks Egmont Koblinger and Vitaliy Filippov for original patches.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Andrew Borodin 2014-02-08 19:37:11 +04:00
parent 25bc34a4b5
commit bf474e1241
17 changed files with 272 additions and 27 deletions

View File

@ -1771,6 +1771,12 @@ confirm.
.PP
The
.\"LINK2"
Appearance
.\"Appearance"
command pops up a dialog from which you specify the skin.
.PP
The
.\"LINK2"
Display bits
.\"Display bits"
command pops up a dialog from which you may select which characters is your
@ -2123,7 +2129,15 @@ to the the panel sort order: case sensitive or not.
In this dialog you configure the confirmation options for file deletion,
overwriting files, execution by pressing enter, quitting the program,
directory hotlist entries deletion and history cleanup.
and.
.\"NODE " Appearance"
.SH " Appearance"
In this dialog you can select the skin to be used.
.PP
See the
.\"LINK2"
Skins
.\"Skins"
section for technical details about the skin definition files.
.\"NODE " Display bits"
.SH " Display bits"
This is used to configure the range of visible characters on the

View File

@ -1882,6 +1882,12 @@ mc на экране.
.PP
Пункт
.\"LINK2"
Оформление
.\"Appearance"
вызывает диалоговое окно, в котором вы можете выбрать скин.
.PP
Пункт
.\"LINK2"
Биты символов
.\"Display bits"
вызывает диалоговое окно, в котором вы указываете, в каком формате ваш
@ -2277,6 +2283,14 @@ Commander, выделены цветом, определенным ключев
перед выходом из программы MC, перед удаленим каталога из каталогов быстрого
доступа, а также перед очисткой истории выдавался дополнительный запрос
на подтверждение.
.\"NODE " Appearance"
.SH " Оформление"
Используя это диалоговое окно, вы можете выбрать скин.
.PP
Для получения более подробной информации о скинах обратитесь к разделу
.\"LINK2"
Внешний вид\&.
.\"Skins"
.\"NODE " Display bits"
.SH " Биты символов..."
Этот пункт меню используется для задания диапазона отображаемых на

View File

@ -176,6 +176,7 @@ static name_keymap_t command_names[] = {
{"Jobs", CK_Jobs},
#endif
{"OptionsLayout", CK_OptionsLayout},
{"OptionsAppearance", CK_OptionsAppearance},
{"Link", CK_Link},
{"PanelListingChange", CK_PanelListingChange},
{"PanelListing", CK_PanelListing},

View File

@ -155,6 +155,7 @@ enum
CK_PanelInfo,
CK_Jobs,
CK_OptionsLayout,
CK_OptionsAppearance,
CK_Link,
CK_PanelListing,
CK_ListMode,

View File

@ -129,7 +129,7 @@ extern mc_skin_t mc_skin__default;
/*** declarations of public functions ************************************************************/
gboolean mc_skin_init (GError **);
gboolean mc_skin_init (const gchar * skin_override, GError ** error);
void mc_skin_deinit (void);
int mc_skin_color_get (const gchar *, const gchar *);
@ -138,4 +138,6 @@ void mc_skin_lines_parse_ini_file (mc_skin_t *);
gchar *mc_skin_get (const gchar *, const gchar *, const gchar *);
GPtrArray *mc_skin_list (void);
#endif /* MC_SKIN_H */

View File

@ -178,6 +178,7 @@ mc_skin_color_set_default_for_terminal (mc_skin_t * mc_skin)
}
/* --------------------------------------------------------------------------------------------- */
static void
mc_skin_color_cache_init (void)
{

View File

@ -110,13 +110,14 @@ mc_skin_try_to_load_default (void)
/* --------------------------------------------------------------------------------------------- */
gboolean
mc_skin_init (GError ** error)
mc_skin_init (const gchar * skin_override, GError ** error)
{
gboolean is_good_init = TRUE;
mc_skin__default.have_256_colors = FALSE;
mc_skin__default.name = mc_skin_get_default_name ();
mc_skin__default.name =
skin_override != NULL ? g_strdup (skin_override) : mc_skin_get_default_name ();
mc_skin__default.colors = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, mc_skin_hash_destroy_value);
@ -165,6 +166,9 @@ mc_skin_init (GError ** error)
void
mc_skin_deinit (void)
{
tty_color_free_all_tmp ();
tty_color_free_all_non_tmp ();
g_free (mc_skin__default.name);
mc_skin__default.name = NULL;
g_hash_table_destroy (mc_skin__default.colors);

View File

@ -25,8 +25,11 @@
*/
#include <config.h>
#include <string.h>
#include "lib/global.h" /* <glib.h> */
#include "internal.h"
#include "lib/fileloc.h"
#include "lib/util.h" /* exist_file() */
@ -43,6 +46,57 @@
/* --------------------------------------------------------------------------------------------- */
static void
mc_skin_get_list_from_dir (const gchar * base_dir, GPtrArray * list)
{
gchar *name;
GDir *dir;
name = g_build_filename (base_dir, MC_SKINS_SUBDIR, (char *) NULL);
dir = g_dir_open (name, 0, NULL);
g_free (name);
if (dir != NULL)
{
while ((name = (gchar *) g_dir_read_name (dir)) != NULL)
{
gchar *sname;
size_t slen;
unsigned int i;
slen = strlen (name);
sname = g_strndup (name, slen);
if (slen > 4 && strcmp (sname + slen - 4, ".ini") == 0)
sname[slen - 4] = '\0';
for (i = 0; i < list->len; i++)
if (strcmp (sname, g_ptr_array_index (list, i)) == 0)
break;
if (i < list->len)
g_free (sname);
else
g_ptr_array_add (list, sname);
}
g_dir_close (dir);
}
}
/* --------------------------------------------------------------------------------------------- */
static int
string_array_comparator (gconstpointer a, gconstpointer b)
{
char *aa = *(char **) a;
char *bb = *(char **) b;
return strcmp (aa, bb);
}
/* --------------------------------------------------------------------------------------------- */
static gboolean
mc_skin_ini_file_load_search_in_dir (mc_skin_t * mc_skin, const gchar * base_dir)
{
@ -75,6 +129,22 @@ mc_skin_ini_file_load_search_in_dir (mc_skin_t * mc_skin, const gchar * base_dir
/*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */
GPtrArray *
mc_skin_list (void)
{
GPtrArray *list;
list = g_ptr_array_new ();
mc_skin_get_list_from_dir (mc_config_get_data_path (), list);
mc_skin_get_list_from_dir (mc_global.sysconfig_dir, list);
mc_skin_get_list_from_dir (mc_global.share_data_dir, list);
g_ptr_array_sort (list, (GCompareFunc) string_array_comparator);
return list;
}
/* --------------------------------------------------------------------------------------------- */
gboolean
mc_skin_ini_file_load (mc_skin_t * mc_skin)
{

View File

@ -50,6 +50,7 @@
/* Color styles for normal and error dialogs */
dlg_colors_t dialog_colors;
dlg_colors_t alarm_colors;
dlg_colors_t listbox_colors;
/* Primitive way to check if the the current dialog is our dialog */
/* This is needed by async routines like load_prompt */
@ -779,8 +780,7 @@ dlg_create (gboolean modal, int y1, int x1, int lines, int cols,
new_d->state = DLG_CONSTRUCT;
new_d->modal = modal;
if (colors != NULL)
memmove (new_d->color, colors, sizeof (dlg_colors_t));
new_d->color = colors;
new_d->help_ctx = help_ctx;
new_d->flags = flags;
new_d->data = NULL;
@ -823,6 +823,12 @@ dlg_set_default_colors (void)
alarm_colors[DLG_COLOR_HOT_NORMAL] = ERROR_HOT_NORMAL;
alarm_colors[DLG_COLOR_HOT_FOCUS] = ERROR_HOT_FOCUS;
alarm_colors[DLG_COLOR_TITLE] = ERROR_TITLE;
listbox_colors[DLG_COLOR_NORMAL] = PMENU_ENTRY_COLOR;
listbox_colors[DLG_COLOR_FOCUS] = PMENU_SELECTED_COLOR;
listbox_colors[DLG_COLOR_HOT_NORMAL] = PMENU_ENTRY_COLOR;
listbox_colors[DLG_COLOR_HOT_FOCUS] = PMENU_SELECTED_COLOR;
listbox_colors[DLG_COLOR_TITLE] = PMENU_TITLE_COLOR;
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -83,7 +83,7 @@ struct WDialog
gboolean modal; /* type of dialog: modal or not */
dlg_flags_t flags; /* User flags */
const char *help_ctx; /* Name of the help entry */
dlg_colors_t color; /* Color set. Unused in viewer and editor */
const int *color; /* Color set. Unused in viewer and editor */
char *title; /* Title of the dialog */
/* Set and received by the user */
@ -111,6 +111,7 @@ struct WDialog
/* Color styles for normal and error dialogs */
extern dlg_colors_t dialog_colors;
extern dlg_colors_t alarm_colors;
extern dlg_colors_t listbox_colors;
extern GList *top_dlg;

View File

@ -59,14 +59,6 @@ Listbox *
create_listbox_window_centered (int center_y, int center_x, int lines, int cols,
const char *title, const char *help)
{
const dlg_colors_t listbox_colors = {
PMENU_ENTRY_COLOR,
PMENU_SELECTED_COLOR,
PMENU_ENTRY_COLOR,
PMENU_SELECTED_COLOR,
PMENU_TITLE_COLOR
};
const int space = 4;
int xpos, ypos;

View File

@ -38,6 +38,7 @@ Unselect = kpminus
SelectInvert = kpasterisk
ScreenList = alt-prime
# OptionsLayout =
# OptionsAppearance =
# OptionsPanel =
# OptionsConfirm =
# OptionsDisplayBits =

View File

@ -38,6 +38,7 @@ Unselect = kpminus
SelectInvert = kpasterisk
ScreenList = alt-prime
# OptionsLayout =
# OptionsAppearance =
# OptionsPanel =
# OptionsConfirm =
# OptionsDisplayBits =

View File

@ -103,6 +103,8 @@ static int listing_user_hotkey = 'u';
static unsigned long panel_listing_types_id, panel_user_format_id;
static unsigned long mini_user_status_id, mini_user_format_id;
static unsigned long skin_name_id;
#ifdef HAVE_CHARSET
static int new_display_codepage;
static unsigned long disp_bits_name_id;
@ -112,6 +114,9 @@ static unsigned long disp_bits_name_id;
static unsigned long ftpfs_always_use_proxy_id, ftpfs_proxy_host_id;
#endif /* ENABLE_VFS && ENABLE_VFS_FTP */
GPtrArray *skin_names;
gchar *current_skin_name;
#ifdef ENABLE_BACKGROUND
static WListbox *bg_list = NULL;
#endif /* ENABLE_BACKGROUND */
@ -515,6 +520,141 @@ configure_box (void)
/* --------------------------------------------------------------------------------------------- */
static void
skin_apply (const gchar * skin_override)
{
GError *error = NULL;
mc_skin_deinit ();
mc_skin_init (skin_override, &error);
mc_fhl_free (&mc_filehighlight);
mc_filehighlight = mc_fhl_new (TRUE);
dlg_set_default_colors ();
panel_deinit ();
panel_init ();
repaint_screen ();
if (error != NULL)
{
message (D_ERROR, _("Warning"), "%s", error->message);
g_error_free (error);
}
}
/* --------------------------------------------------------------------------------------------- */
static const gchar *
skin_name_to_label (const gchar * name)
{
if (strcmp (name, "default") == 0)
return _("< Default >");
return name;
}
/* --------------------------------------------------------------------------------------------- */
static int
sel_skin_button (WButton * button, int action)
{
int result;
WListbox *skin_list;
WDialog *skin_dlg;
const gchar *skin_name;
int lxx, lyy;
unsigned int i;
unsigned int pos = 1;
(void) action;
lxx = COLS / 2;
lyy = (LINES - 13) / 2;
skin_dlg =
dlg_create (TRUE, lyy, lxx, 13, 24, dialog_colors, NULL, NULL, "[Appearance]", _("Skins"),
DLG_COMPACT);
skin_list = listbox_new (1, 1, 11, 22, FALSE, NULL);
skin_name = "default";
listbox_add_item (skin_list, LISTBOX_APPEND_AT_END, 0, skin_name_to_label (skin_name),
(void *) skin_name);
if (strcmp (skin_name, current_skin_name) == 0)
listbox_select_entry (skin_list, 0);
for (i = 0; i < skin_names->len; i++)
{
skin_name = g_ptr_array_index (skin_names, i);
if (strcmp (skin_name, "default") != 0)
{
listbox_add_item (skin_list, LISTBOX_APPEND_AT_END, 0, skin_name_to_label (skin_name),
(void *) skin_name);
if (strcmp (skin_name, current_skin_name) == 0)
listbox_select_entry (skin_list, pos);
pos++;
}
}
add_widget (skin_dlg, skin_list);
result = dlg_run (skin_dlg);
if (result == B_ENTER)
{
Widget *w;
gchar *skin_label;
listbox_get_current (skin_list, &skin_label, (void **) &skin_name);
g_free (current_skin_name);
current_skin_name = g_strdup (skin_name);
skin_apply (skin_name);
w = dlg_find_by_id (WIDGET (button)->owner, skin_name_id);
button_set_text (BUTTON (w), str_fit_to_term (skin_label, 20, J_LEFT_FIT));
}
dlg_destroy (skin_dlg);
return 0;
}
/* --------------------------------------------------------------------------------------------- */
void
appearance_box (void)
{
current_skin_name = g_strdup (mc_skin__default.name);
skin_names = mc_skin_list ();
{
quick_widget_t quick_widgets[] = {
/* *INDENT-OFF* */
QUICK_START_COLUMNS,
QUICK_LABEL (N_("Skin:"), NULL),
QUICK_NEXT_COLUMN,
QUICK_BUTTON (str_fit_to_term (skin_name_to_label (current_skin_name), 20, J_LEFT_FIT),
B_USER, sel_skin_button, &skin_name_id),
QUICK_STOP_COLUMNS,
QUICK_BUTTONS_OK_CANCEL,
QUICK_END
/* *INDENT-ON* */
};
quick_dialog_t qdlg = {
-1, -1, 54,
N_("Appearance"), "[Appearance]",
quick_widgets, dlg_default_callback, NULL
};
if (quick_dialog (&qdlg) == B_ENTER)
mc_config_set_string (mc_main_config, CONFIG_APP_SECTION, "skin", current_skin_name);
else
skin_apply (NULL);
}
g_free (current_skin_name);
g_ptr_array_foreach (skin_names, (GFunc) g_free, NULL);
g_ptr_array_free (skin_names, TRUE);
}
/* --------------------------------------------------------------------------------------------- */
void
panel_options_box (void)
{

View File

@ -19,6 +19,7 @@
/*** declarations of public functions ************************************************************/
void configure_box (void);
void appearance_box (void);
void panel_options_box (void);
int panel_listing_box (WPanel * p, char **user, char **mini, int *use_msformat, int num);
const panel_field_t *sort_box (dir_sort_options_t * op, const panel_field_t * sort_field);

View File

@ -335,6 +335,8 @@ create_options_menu (void)
entries = g_list_prepend (entries, menu_entry_create (_("&Panel options..."), CK_OptionsPanel));
entries =
g_list_prepend (entries, menu_entry_create (_("C&onfirmation..."), CK_OptionsConfirm));
entries =
g_list_prepend (entries, menu_entry_create (_("&Appearance..."), CK_OptionsAppearance));
entries =
g_list_prepend (entries, menu_entry_create (_("&Display bits..."), CK_OptionsDisplayBits));
entries = g_list_prepend (entries, menu_entry_create (_("Learn &keys..."), CK_LearnKeys));
@ -1251,6 +1253,9 @@ midnight_execute_cmd (Widget * sender, unsigned long command)
case CK_OptionsLayout:
layout_box ();
break;
case CK_OptionsAppearance:
appearance_box ();
break;
case CK_LearnKeys:
learn_keys ();
break;
@ -1744,19 +1749,11 @@ do_nc (void)
{
gboolean ret;
dlg_colors_t midnight_colors;
midnight_colors[DLG_COLOR_NORMAL] = mc_skin_color_get ("dialog", "_default_");
midnight_colors[DLG_COLOR_FOCUS] = mc_skin_color_get ("dialog", "focus");
midnight_colors[DLG_COLOR_HOT_NORMAL] = mc_skin_color_get ("dialog", "hotnormal");
midnight_colors[DLG_COLOR_HOT_FOCUS] = mc_skin_color_get ("dialog", "hotfocus");
midnight_colors[DLG_COLOR_TITLE] = mc_skin_color_get ("dialog", "title");
#ifdef USE_INTERNAL_EDIT
edit_stack_init ();
#endif
midnight_dlg = dlg_create (FALSE, 0, 0, LINES, COLS, midnight_colors, midnight_callback,
midnight_dlg = dlg_create (FALSE, 0, 0, LINES, COLS, dialog_colors, midnight_callback,
midnight_event, "[main]", NULL, DLG_NONE);
/* Check if we were invoked as an editor or file viewer */

View File

@ -370,7 +370,8 @@ main (int argc, char *argv[])
tty_init_colors (mc_global.tty.disable_colors, mc_args__force_colors);
mc_skin_init (&error);
mc_skin_init (NULL, &error);
dlg_set_default_colors ();
if (error != NULL)
{
message (D_ERROR, _("Warning"), "%s", error->message);
@ -378,8 +379,6 @@ main (int argc, char *argv[])
error = NULL;
}
dlg_set_default_colors ();
#ifdef ENABLE_SUBSHELL
/* Done here to ensure that the subshell doesn't */
/* inherit the file descriptors opened below, etc */