#include #include "gm-color-table.h" #include "string.h" #include "ansi.h" #include "debug.h" #define GM_COLOR_TABLE_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GM_TYPE_COLOR_TABLE, GmColorTablePrivate)) void gm_color_table_item_free(gpointer item); typedef struct _GmColorTableItem GmColorTableItem; struct _GmColorTableItem { gchar *hex; GdkColor color; }; typedef struct _GmColorTableSchemeItem { const gchar *name; const gchar *hex; } GmColorTableSchemeItem; static const GmColorTableSchemeItem scheme_default[] = { {"fg_default", "#000000"}, {"fg_black", "#000000"}, {"fg_red", "#663822"}, {"fg_green", "#445632"}, {"fg_yellow", "#D1940C"}, {"fg_blue", "#314E6C"}, {"fg_purple", "#494066"}, {"fg_cyan", "#0000FFFFFFFF"}, {"fg_white", "#BAB5AB"}, {"fg_default_h", "#565248"}, {"fg_black_h", "#565248"}, {"fg_red_h", "#990000"}, {"fg_green_h", "#267726"}, {"fg_yellow_h", "#EED680"}, {"fg_blue_h", "#9DB8D2"}, {"fg_purple_h", "#ADA7C8"}, {"fg_cyan_h", "#86EEFFFFFFFF"}, {"fg_white_h", "#807D74"}, //{"bg_default", "#EAE8E3"}, {"bg_default", "#FFFFFF"}, {"bg_black", "#000000"}, {"bg_red", "#663822"}, {"bg_green", "#445632"}, {"bg_yellow", "#D1940C"}, {"bg_blue", "#314E6C"}, {"bg_purple", "#494066"}, {"bg_cyan", "#0000FFFFFFFF"}, {"bg_white", "#FFFFFFFFFFFF"}, {NULL, NULL} }; static const GmColorTableSchemeItem scheme_white_on_black[] = { {"fg_default", "#D6B5D6B5D6B5"}, {"fg_black", "#2D6B2D6B2D6B"}, {"fg_red", "#FFFF00000000"}, {"fg_green", "#0000FFFF0000"}, {"fg_yellow", "#FFFFD0450000"}, {"fg_blue", "#3EF73EF7BFFF"}, {"fg_purple", "#A0A02020F0F0"}, {"fg_cyan", "#0000FFFFFFFF"}, {"fg_white", "#D8C5D8C5D8C5"}, {"fg_default_h", "#FFFFFFFFFFFF"}, {"fg_black_h", "#529452945294"}, {"fg_red_h", "#FFFF785F785F"}, {"fg_green_h", "#66ADFFFF66AD"}, {"fg_yellow_h", "#FFFFFFFF58C6"}, {"fg_blue_h", "#86318631FFFF"}, {"fg_purple_h", "#C6576A18FFFF"}, {"fg_cyan_h", "#86EEFFFFFFFF"}, {"fg_white_h", "#FFFFFFFFFFFF"}, {"bg_default", "#000000000000"}, {"bg_black", "#2B5B2B5B2B5B"}, {"bg_red", "#FFFF00000000"}, {"bg_green", "#000080000000"}, {"bg_yellow", "#C047C0470000"}, {"bg_blue", "#00000000FFFF"}, {"bg_purple", "#A0A02020F0F0"}, {"bg_cyan", "#0000B74CB74C"}, {"bg_white", "#FFFFFFFFFFFF"}, {NULL, NULL} }; typedef struct _GmColorScheme { GmColorTableScheme scheme; const gchar *name; const GmColorTableSchemeItem *values; } GmColorScheme; static const GmColorScheme scheme_names[] = { {SCHEME_NONE, "none", NULL}, {SCHEME_DEFAULT, "default", scheme_default}, {SCHEME_WHITE_ON_BLACK, "white_on_black", scheme_white_on_black}, {SCHEME_USER, "user", NULL}, {SCHEME_NONE, NULL, NULL} }; struct _GmColorTablePrivate { GHashTable *colors; gchar *font_description; GmOptions *options; GmColorTableScheme scheme; }; /* Signals */ enum { COLOR_CHANGED, FONT_CHANGED, NUM_SIGNALS }; static guint color_table_signals[NUM_SIGNALS] = {0}; G_DEFINE_TYPE(GmColorTable, gm_color_table, G_TYPE_OBJECT) static void gm_color_table_finalize(GObject *object) { //GmColorTable *table = GM_COLOR_TABLE(object); G_OBJECT_CLASS(gm_color_table_parent_class)->finalize(object); } static void gm_color_table_class_init(GmColorTableClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); object_class->finalize = gm_color_table_finalize; color_table_signals[COLOR_CHANGED] = g_signal_new("color_changed", G_OBJECT_CLASS_TYPE(object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GmColorTableClass, color_changed), NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); color_table_signals[FONT_CHANGED] = g_signal_new("font_changed", G_OBJECT_CLASS_TYPE(object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GmColorTableClass, font_changed), NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); g_type_class_add_private(object_class, sizeof(GmColorTablePrivate)); } static void gm_color_table_init(GmColorTable *table) { table->priv = GM_COLOR_TABLE_GET_PRIVATE(table); table->priv->colors = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, gm_color_table_item_free); table->priv->scheme = SCHEME_NONE; } /* Private functions */ void gm_color_table_item_free(gpointer item) { GmColorTableItem *i = (GmColorTableItem *)(item); g_free(i->hex); g_free(i); } void gm_color_table_load_scheme(GmColorTable *table, GmColorTableScheme scheme) { int i = 0; const GmColorTableSchemeItem *values = scheme_names[scheme].values; while (values[i].name != NULL) { gm_color_table_set(table, values[i].name, values[i].hex); ++i; } table->priv->scheme = scheme; } void gm_color_table_initialize(GmColorTable *table) { gm_color_table_set_font_description(table, "Monospace 10"); gm_color_table_load_scheme(table, SCHEME_DEFAULT); } void gm_color_table_fill_from_options(GmColorTable *table) { unsigned int i; const gchar *value; GmOptions *options = table->priv->options; // New, color schemes value = gm_options_get(options, "color_scheme"); if (value == NULL || strcmp(value, "user") == 0) { for (i = 0; i < sizeof(ansi_colors) / sizeof(ansinamepair); i++) { value = gm_options_get(options, ansi_colors[i].name); if (value != NULL) { gm_color_table_set(table, ansi_colors[i].name, value); } } } else { gm_color_table_set_from_scheme_name(table, value); } value = gm_options_get(options, "font_family"); if (value && *value != '\0') { gm_color_table_set_font_description(table, value); } else { gm_options_set(options, "font_family", "Monospace 10"); } } /* Public functions */ GmColorTable * gm_color_table_new(void) { GmColorTable *table = GM_COLOR_TABLE(g_object_new(GM_TYPE_COLOR_TABLE, NULL)); gm_color_table_load_scheme(table, SCHEME_DEFAULT); return table; } GmColorTable * gm_color_table_new_from_options(gchar *filename) { GmColorTable *table = GM_COLOR_TABLE(g_object_new(GM_TYPE_COLOR_TABLE, NULL)); table->priv->options = gm_options_new(); gm_options_set(table->priv->options, "color_scheme", "default"); gm_options_load(table->priv->options, filename); gm_color_table_fill_from_options(table); return table; } void gm_color_table_save(GmColorTable *table) { if (table->priv->options) { gm_options_save(table->priv->options); } } void gm_color_table_set(GmColorTable *table, const gchar *name, const gchar *hex) { GmColorTableItem *item; item = g_hash_table_lookup(table->priv->colors, name); if (table->priv->scheme == SCHEME_USER) { gm_options_set(table->priv->options, name, hex); } if (!item) { item = g_new0(GmColorTableItem, 1); g_hash_table_insert(table->priv->colors, g_strdup(name), item); } if (item->hex == NULL || strcmp(hex, item->hex) != 0) { g_free(item->hex); item->hex = g_strdup(hex); gdk_color_parse(item->hex, &(item->color)); g_signal_emit(table, color_table_signals[COLOR_CHANGED], 0, name); } } gboolean gm_color_table_get(GmColorTable *table, const gchar *name, GdkColor *color) { GmColorTableItem *item; item = g_hash_table_lookup(table->priv->colors, name); if (item != NULL) { *color = item->color; return TRUE; } else { return FALSE; } } const gchar * gm_color_table_get_hex(GmColorTable *table, const gchar *name) { GmColorTableItem *item; item = g_hash_table_lookup(table->priv->colors, name); if (item != NULL) { return item->hex; } else { return FALSE; } } void gm_color_table_set_font_description(GmColorTable *table, const gchar *font_description) { const gchar *fd; if (font_description == NULL) { fd = "Monospace 10"; } else { fd = font_description; } gm_options_set(table->priv->options, "font_family", fd); if (table->priv->font_description == NULL || strcmp(table->priv->font_description, fd) != 0) { g_free(table->priv->font_description); table->priv->font_description = g_strdup(fd); g_signal_emit(table, color_table_signals[FONT_CHANGED], 0, table->priv->font_description); } } const gchar * gm_color_table_font_description(GmColorTable *table) { return table->priv->font_description; } void gm_color_table_set_from_scheme_name(GmColorTable *table, const gchar *scheme) { int i = 0; while (scheme_names[i].name != NULL) { if (strcasecmp(scheme_names[i].name, scheme) == 0 && scheme_names[i].values != NULL) { gm_color_table_load_scheme(table, scheme_names[i].scheme); break; } ++i; } if (scheme_names[i].name == NULL) { gm_color_table_load_scheme(table, SCHEME_DEFAULT); gm_options_set(table->priv->options, "color_scheme", "default"); } else { gm_options_set(table->priv->options, "color_scheme", scheme_names[i].name); } }