1
1

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>
Этот коммит содержится в:
Andrew Borodin 2014-02-08 19:37:11 +04:00
родитель 25bc34a4b5
Коммит bf474e1241
17 изменённых файлов: 272 добавлений и 27 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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 " Биты символов..."
Этот пункт меню используется для задания диапазона отображаемых на

Просмотреть файл

@ -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},

Просмотреть файл

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

Просмотреть файл

@ -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 */

Просмотреть файл

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

Просмотреть файл

@ -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);

Просмотреть файл

@ -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)
{

Просмотреть файл

@ -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;
}
/* --------------------------------------------------------------------------------------------- */

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -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)
{

Просмотреть файл

@ -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);

Просмотреть файл

@ -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 */

Просмотреть файл

@ -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 */