diff --git a/legacy/elementary/data/objects/Makefile.am b/legacy/elementary/data/objects/Makefile.am index 7a2a16e11f..0f80b6c4be 100644 --- a/legacy/elementary/data/objects/Makefile.am +++ b/legacy/elementary/data/objects/Makefile.am @@ -6,13 +6,14 @@ EDJE_FLAGS = -v -id $(top_srcdir)/data/objects -fd $(top_srcdir)/data/objects filesdir = $(datadir)/elementary/objects -files_DATA = test.edj multip.edj colorpreview.edj cursors.edj +files_DATA = test.edj multip.edj colorpreview.edj cursors.edj font_preview.edj EXTRA_DIST = \ test.edc \ multip.edc \ colorpreview.edc \ cursors.edc \ +font_preview.edc \ grid_bg.png \ over.png \ under.png \ @@ -24,7 +25,7 @@ test.edj: Makefile $(EXTRA_DIST) $(EDJE_CC) $(EDJE_FLAGS) \ $(top_srcdir)/data/objects/test.edc \ $(top_builddir)/data/objects/test.edj - + multip.edj: Makefile $(EXTRA_DIST) $(EDJE_CC) $(EDJE_FLAGS) \ $(top_srcdir)/data/objects/multip.edc \ @@ -39,6 +40,11 @@ cursors.edj: Makefile $(EXTRA_DIST) $(EDJE_CC) $(EDJE_FLAGS) \ $(top_srcdir)/data/objects/cursors.edc \ $(top_builddir)/data/objects/cursors.edj - + +font_preview.edj: Makefile $(EXTRA_DIST) + $(EDJE_CC) $(EDJE_FLAGS) \ + $(top_srcdir)/data/objects/font_preview.edc \ + $(top_builddir)/data/objects/font_preview.edj + clean-local: rm -f *.edj diff --git a/legacy/elementary/data/objects/font_preview.edc b/legacy/elementary/data/objects/font_preview.edc new file mode 100644 index 0000000000..302c2e85e5 --- /dev/null +++ b/legacy/elementary/data/objects/font_preview.edc @@ -0,0 +1,40 @@ +color_classes { + color_class { + name: "entry_text"; + color: 0 0 0 255; + } +} + +collections { + + group { name: "font_preview"; + parts { + + /* some fonts have weird alignments, thus they overflow badly */ + part { name: "clipper"; + type: RECT; + description { + state: "default" 0.0; + } + } + + part { name: "elm.text"; + type: TEXT; + mouse_events: 0; + scale: 1; + clip_to: "clipper"; + description { + state: "default" 0.0; + color_class: "entry_text"; + text { + font: "Sans"; + min: 0 1; + size: 10; + align: 0.5 0.5; + text_class: "font_preview"; + } + } + } + } + } +} diff --git a/legacy/elementary/data/themes/default.edc b/legacy/elementary/data/themes/default.edc index 561ed780b2..6367ab4747 100644 --- a/legacy/elementary/data/themes/default.edc +++ b/legacy/elementary/data/themes/default.edc @@ -639,6 +639,20 @@ collections { } } } + part { name: "disabler"; + type: RECT; + description { state: "default" 0.0; + rel1.to: "clipper"; + rel2.to: "clipper"; + color: 0 0 0 0; + visible: 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 1; + color: 128 128 128 128; + } + } } programs { program { name: "load"; @@ -809,6 +823,18 @@ collections { target: "focus_highlight"; target: "conf_over"; } + program { name: "disable"; + signal: "elm,state,disabled"; + source: "elm"; + action: STATE_SET "disabled" 0.0; + target: "disabler"; + } + program { name: "enable"; + signal: "elm,state,enabled"; + source: "elm"; + action: STATE_SET "default" 0.0; + target: "disabler"; + } } } @@ -1628,6 +1654,7 @@ collections { size: 10; min: 0 0; align: 0.5 0.5; + text_class: "button"; } } description { state: "visible" 0.0; @@ -1966,6 +1993,7 @@ collections { size: 10; min: 0 0; align: 0.5 0.5; + text_class: "button"; } } description { state: "visible" 0.0; @@ -2247,6 +2275,7 @@ collections { size: 10; min: 0 0; align: 0.5 0.5; + text_class: "button"; } } description { state: "visible" 0.0; @@ -2428,6 +2457,7 @@ collections { size: 10; min: 0 0; align: 0.5 0.5; + text_class: "button"; } } description { state: "visible" 0.0; diff --git a/legacy/elementary/src/bin/config.c b/legacy/elementary/src/bin/config.c index 28ab7b44ad..a1b5feaffb 100644 --- a/legacy/elementary/src/bin/config.c +++ b/legacy/elementary/src/bin/config.c @@ -5,6 +5,9 @@ #ifndef ELM_LIB_QUICKLAUNCH typedef struct _Theme Theme; +typedef struct _Fonts_Data Fonts_Data; +typedef struct _Elm_Text_Class_Data Elm_Text_Class_Data; +typedef struct _Elm_Font_Size_Data Elm_Font_Size_Data; struct _Theme { @@ -17,18 +20,101 @@ struct _Theme static Theme *tsel = NULL; static Eina_List *themes = NULL; +struct _Elm_Text_Class_Data +{ + const char *name; + const char *desc; + const char *font; + const char *style; + Evas_Font_Size size; +}; + +struct _Elm_Font_Size_Data +{ + const char *size_str; + Evas_Font_Size size; +}; + +struct _Fonts_Data +{ + Eina_List *text_classes; + + Eina_Hash *font_hash; + Eina_List *font_px_list; + Eina_List *font_scale_list; + + const char *cur_font; + const char *cur_style; + double cur_size; +}; + +#define ELM_LIST_DISABLE(list) \ + do \ + { \ + const Eina_List *l = elm_list_items_get(list); \ + if (l) \ + { \ + elm_list_item_show(eina_list_data_get(l)); \ + elm_object_disabled_set(list, EINA_TRUE); \ + } \ + } \ + while (0); + +#define ELM_LIST_ENABLE(list) \ + do \ + { \ + elm_object_disabled_set(list, EINA_FALSE); \ + } \ + while (0); + static int quiet = 0; static int interactive = 1; static const char *theme_set = NULL; static const char *finger_size_set = NULL; static const char *scale_set = NULL; +static Fonts_Data fdata = {NULL, NULL, NULL, NULL, NULL, NULL, 0.0}; static void -my_win_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +_font_styles_list_sel(void *data __UNUSED__, + Evas_Object *obj, + void *event_info); + +static void +config_exit(void *data __UNUSED__, + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) { + Elm_Text_Class_Data *tc_data; + Elm_Font_Size_Data *sd; + + EINA_LIST_FREE(fdata.text_classes, tc_data) + { + eina_stringshare_del(tc_data->name); + eina_stringshare_del(tc_data->desc); + eina_stringshare_del(tc_data->font); + eina_stringshare_del(tc_data->style); + free(tc_data); + } + + elm_font_available_hash_del(fdata.font_hash); + + EINA_LIST_FREE(fdata.font_px_list, sd) + { + eina_stringshare_del(sd->size_str); + free(sd); + } + + EINA_LIST_FREE(fdata.font_scale_list, sd) + { + eina_stringshare_del(sd->size_str); + free(sd); + } + + if (fdata.cur_font) eina_stringshare_del(fdata.cur_font); + if (fdata.cur_style) eina_stringshare_del(fdata.cur_style); + elm_config_save(); - /* called when my_win_main is requested to be deleted */ elm_exit(); /* exit the program's main loop that runs in elm_run() */ } @@ -260,6 +346,110 @@ _elm_theme_current_get(const char *theme_search_order) return ret; } +static void +_font_overlay_reset(void *data, + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) +{ + Evas_Object *win, *fclasses, *fnames, *fstyles, *fsizes; + Elm_Text_Class_Data *tc_data; + Elm_List_Item *it; + + win = data; + + fclasses = evas_object_data_get(win, "font_classes_list"); + it = elm_list_selected_item_get(fclasses); + if (!it) return; + tc_data = elm_list_item_data_get(it); + + fnames = evas_object_data_get(win, "font_names_list"); + fstyles = evas_object_data_get(win, "font_styles_list"); + fsizes = evas_object_data_get(win, "font_sizes_list"); + + elm_font_overlay_unset(tc_data->name); + + eina_stringshare_replace(&fdata.cur_font, NULL); + eina_stringshare_replace(&tc_data->font, NULL); + eina_stringshare_replace(&fdata.cur_style, NULL); + eina_stringshare_replace(&tc_data->style, NULL); + fdata.cur_size = 0.0; + tc_data->size = 0.0; + + ELM_LIST_DISABLE(fnames); + ELM_LIST_DISABLE(fstyles); + ELM_LIST_DISABLE(fsizes); + + elm_config_save(); +} + +static void +_font_overlay_reset_all(void *data, + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) +{ + Evas_Object *win, *fclasses, *fnames, *fstyles, *fsizes; + Elm_Text_Class_Data *tc_data; + Elm_List_Item *it; + Eina_List *l; + + win = data; + eina_stringshare_replace(&fdata.cur_font, NULL); + eina_stringshare_replace(&fdata.cur_style, NULL); + fdata.cur_size = 0.0; + + EINA_LIST_FOREACH(fdata.text_classes, l, tc_data) + { + elm_font_overlay_unset(tc_data->name); + + eina_stringshare_replace(&tc_data->font, NULL); + eina_stringshare_replace(&tc_data->style, NULL); + tc_data->size = 0.0; + } + + fclasses = evas_object_data_get(win, "font_classes_list"); + fnames = evas_object_data_get(win, "font_names_list"); + fstyles = evas_object_data_get(win, "font_styles_list"); + fsizes = evas_object_data_get(win, "font_sizes_list"); + + it = elm_list_selected_item_get(fclasses); + if (it) elm_list_item_selected_set(it, EINA_FALSE); + + ELM_LIST_DISABLE(fnames); + ELM_LIST_DISABLE(fstyles); + ELM_LIST_DISABLE(fsizes); + + elm_config_save(); +} + +static void +_font_overlay_change(void *data __UNUSED__, + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) +{ + Elm_Text_Class_Data *tc_data; + Eina_List *l; + + EINA_LIST_FOREACH(fdata.text_classes, l, tc_data) + { + if (tc_data->font) + { + const char *name; + + name = elm_font_fontconfig_name_get(tc_data->font, tc_data->style); + elm_font_overlay_set(tc_data->name, name, + tc_data->size ? tc_data->size : -100); + elm_font_fontconfig_name_free(name); + } + else + elm_font_overlay_unset(tc_data->name); + } + + elm_config_save(); + elm_font_overlay_all_apply(); + + /* TODO: apply hinting */ +} + static void _profile_change_do(Evas_Object *win, const char *profile) { @@ -774,9 +964,614 @@ _unimplemented(Evas_Object *win, Evas_Object *pager, const char *name) } static void -_status_config_fonts(Evas_Object *win, Evas_Object *pager) +_font_preview_update(Evas_Object *win) { - _unimplemented(win, pager, "fonts"); + Evas_Font_Size sz; + const char *name; + + if (!fdata.cur_font) + return; + + name = elm_font_fontconfig_name_get(fdata.cur_font, fdata.cur_style); + sz = fdata.cur_size; + + if (sz < 0) + sz = (-sz * 10) / 100; + if (sz == 0) + sz = 10; + + edje_object_text_class_set(evas_object_data_get(win, "font_preview"), + "font_preview", name, sz); + + elm_font_fontconfig_name_free(name); +} + +static void +_font_classes_list_sel(void *data __UNUSED__, + Evas_Object *obj, + void *event_info) +{ + const Eina_List *f_names_items, *l; + Elm_Text_Class_Data *tc_data; + Evas_Object *f_names_list; + Elm_List_Item *it; + + tc_data = elm_list_item_data_get(event_info); + + f_names_list = evas_object_data_get(elm_object_top_widget_get(obj), + "font_names_list"); + ELM_LIST_ENABLE(f_names_list); + + f_names_items = elm_list_items_get(f_names_list); + + EINA_LIST_FOREACH(f_names_items, l, it) + { + const char *l; + + l = elm_list_item_label_get(it); + + if (tc_data->font && !strcmp(l, tc_data->font)) + { + elm_list_item_selected_set(it, EINA_TRUE); + elm_list_item_show(it); + break; + } + } +} + +static void +_font_names_list_sel(void *data __UNUSED__, + Evas_Object *obj, + void *event_info) +{ + Evas_Object *style_list, *cls_list, *sizes_list, *win; + const char *style, *sel_font; + Elm_Text_Class_Data *tc_data; + Elm_List_Item *it, *fc_it; + Elm_Font_Properties *efp; + const Eina_List *l; + + it = event_info; + sel_font = elm_list_item_label_get(it); + + win = elm_object_top_widget_get(obj); + style_list = evas_object_data_get(win, "font_styles_list"); + cls_list = evas_object_data_get(win, "font_classes_list"); + sizes_list = evas_object_data_get(win, "font_sizes_list"); + + fc_it = elm_list_selected_item_get(cls_list); + if (!fc_it) return; /* should not happen, fonts list disabled in + * this case */ + + eina_stringshare_replace(&fdata.cur_font, sel_font); + + tc_data = elm_list_item_data_get(fc_it); + if (tc_data->font) eina_stringshare_del(tc_data->font); + if (fdata.cur_font) tc_data->font = eina_stringshare_ref(fdata.cur_font); + + /* load styles list */ + efp = eina_hash_find(fdata.font_hash, sel_font); + + ELM_LIST_ENABLE(style_list); + elm_list_clear(style_list); + + evas_event_freeze(evas_object_evas_get(style_list)); + edje_freeze(); + + it = NULL; + + EINA_LIST_FOREACH(efp->styles, l, style) + { + Elm_List_Item *i; + + i = elm_list_item_append(style_list, style, NULL, NULL, + _font_styles_list_sel, NULL); + + if (tc_data->style && (!strcmp(style, tc_data->style))) + it = i; + } + + elm_list_go(style_list); + + edje_thaw(); + evas_event_thaw(evas_object_evas_get(style_list)); + + if (it) + elm_list_item_selected_set(it, EINA_TRUE); + + _font_preview_update(win); +} + +static void +_font_styles_list_sel(void *data __UNUSED__, + Evas_Object *obj, + void *event_info) +{ + Evas_Object *fc_list, *fs_list, *win; + Elm_Text_Class_Data *tc_data; + const Eina_List *l; + Elm_List_Item *it; + + win = elm_object_top_widget_get(obj); + fc_list = evas_object_data_get(win, "font_classes_list"); + fs_list = evas_object_data_get(win, "font_sizes_list"); + + it = elm_list_selected_item_get(fc_list); + if (!it) return; /* should not happen */ + + eina_stringshare_replace(&fdata.cur_style, + elm_list_item_label_get(event_info)); + ELM_LIST_ENABLE(fs_list); + + tc_data = elm_list_item_data_get(it); + eina_stringshare_del(tc_data->style); + tc_data->style = eina_stringshare_ref(fdata.cur_style); + + evas_event_freeze(evas_object_evas_get(fs_list)); + edje_freeze(); + + EINA_LIST_FOREACH(elm_list_items_get(fs_list), l, it) + { + Elm_Font_Size_Data *sdata; + + sdata = elm_list_item_data_get(it); + elm_list_item_selected_set(l->data, EINA_FALSE); + + if (tc_data->size == sdata->size) + { + elm_list_item_selected_set(it, EINA_TRUE); + elm_list_item_show(it); + break; + } + } + + edje_thaw(); + evas_event_thaw(evas_object_evas_get(fs_list)); + + _font_preview_update(win); +} + +static void +_font_sizes_list_sel(void *data __UNUSED__, + Evas_Object *obj __UNUSED__, + void *event_info __UNUSED__) +{ + Elm_Text_Class_Data *tc_data; + Evas_Object *fc_list, *win; + Elm_Font_Size_Data *sd; + Elm_List_Item *it; + + win = elm_object_top_widget_get(obj); + fc_list = evas_object_data_get(win, "font_classes_list"); + + it = elm_list_selected_item_get(fc_list); + if (!it) return; /* should not happen */ + + sd = elm_list_item_data_get(event_info); + fdata.cur_size = sd->size; + + tc_data = elm_list_item_data_get(it); + tc_data->size = fdata.cur_size; + + _font_preview_update(win); +} + +static void +_fstyle_list_unselect_cb(void *data __UNUSED__, + Evas_Object *obj, + void *event_info __UNUSED__) +{ + Evas_Object *sizes_list, *win; + + if (elm_list_selected_item_get(obj)) return; + + win = elm_object_top_widget_get(obj); + + sizes_list = evas_object_data_get(win, "font_sizes_list"); + ELM_LIST_DISABLE(sizes_list); +} + +static void +_fc_list_unselect_cb(void *data __UNUSED__, + Evas_Object *obj, + void *event_info __UNUSED__) +{ + Evas_Object *font_names_list, *styles_list, *sizes_list, *win; + + if (elm_list_selected_item_get(obj)) return; + + win = elm_object_top_widget_get(obj); + + font_names_list = evas_object_data_get(win, "font_names_list"); + ELM_LIST_DISABLE(font_names_list); + + styles_list = evas_object_data_get(win, "font_styles_list"); + ELM_LIST_DISABLE(styles_list); + + sizes_list = evas_object_data_get(win, "font_sizes_list"); + ELM_LIST_DISABLE(sizes_list); +} + +static void +_font_classes_list_load(Evas_Object *li) +{ + Elm_Text_Class_Data *tc_data; + Eina_List *l; + Evas *evas; + + evas = evas_object_evas_get(li); + evas_event_freeze(evas); + edje_freeze(); + + EINA_LIST_FOREACH(fdata.text_classes, l, tc_data) + elm_list_item_append(li, tc_data->desc, NULL, NULL, _font_classes_list_sel, + tc_data); + + evas_object_smart_callback_add(li, "unselected", _fc_list_unselect_cb, + NULL); + + elm_list_go(li); + edje_thaw(); + evas_event_thaw(evas); +} + +static void +_fonts_data_fill(Evas *evas) +{ + const Eina_List *fo_list, *text_classes, *l; + Elm_Text_Class_Data *tc_data; + Elm_Font_Size_Data *sd; + Elm_Font_Overlay *efo; + Eina_List *evas_fonts; + Elm_Text_Class *etc; + int i; + + evas_fonts = evas_font_available_list(evas); + fdata.font_hash = elm_font_available_hash_add(evas_fonts); + evas_font_available_list_free(evas, evas_fonts); + + text_classes = elm_text_classes_list_get(); + fo_list = elm_font_overlay_list_get(); + + EINA_LIST_FOREACH(text_classes, l, etc) + { + const Eina_List *ll; + + tc_data = calloc(1, sizeof(*tc_data)); + tc_data->name = eina_stringshare_add(etc->name); + tc_data->desc = eina_stringshare_add(etc->desc); + + EINA_LIST_FOREACH(fo_list, ll, efo) + { + if (strcmp(tc_data->name, efo->text_class)) + continue; + + if (efo->font) + { + Elm_Font_Properties *efp; + + efp = elm_font_properties_get(efo->font); + if (efp) + { + tc_data->font = eina_stringshare_add(efp->name); + /* we're sure we recorded with only 1 style selected */ + tc_data->style = eina_stringshare_add(efp->styles->data); + elm_font_properties_free(efp); + } + } + tc_data->size = efo->size; + } + + fdata.text_classes = eina_list_append(fdata.text_classes, tc_data); + } + + elm_text_classes_list_free(text_classes); + + /* FIXME: hinting later */ + /* fdata.hinting = e_config->font_hinting; */ + + sd = calloc(1, sizeof(Elm_Font_Size_Data)); + sd->size_str = eina_stringshare_add("Tiny"); + sd->size = -50; + fdata.font_scale_list = eina_list_append(fdata.font_scale_list, sd); + + sd = calloc(1, sizeof(Elm_Font_Size_Data)); + sd->size_str = eina_stringshare_add("Small"); + sd->size = -80; + fdata.font_scale_list = eina_list_append(fdata.font_scale_list, sd); + + sd = calloc(1, sizeof(Elm_Font_Size_Data)); + sd->size_str = eina_stringshare_add("Normal"); + sd->size = -100; + fdata.font_scale_list = eina_list_append(fdata.font_scale_list, sd); + + sd = calloc(1, sizeof(Elm_Font_Size_Data)); + sd->size_str = eina_stringshare_add("Big"); + sd->size = -150; + fdata.font_scale_list = eina_list_append(fdata.font_scale_list, sd); + + sd = calloc(1, sizeof(Elm_Font_Size_Data)); + sd->size_str = eina_stringshare_add("Really Big"); + sd->size = -190; + fdata.font_scale_list = eina_list_append(fdata.font_scale_list, sd); + + sd = calloc(1, sizeof(Elm_Font_Size_Data)); + sd->size_str = eina_stringshare_add("Huge"); + sd->size = -250; + fdata.font_scale_list = eina_list_append(fdata.font_scale_list, sd); + + for (i = 5; i < 21; i++) + { + char str[16]; + + str[0] = 0; + snprintf(str, sizeof(str), "%d pixels", i); + + sd = calloc(1, sizeof(Elm_Font_Size_Data)); + sd->size_str = eina_stringshare_add(str); + sd->size = i; + fdata.font_px_list = eina_list_append(fdata.font_px_list, sd); + } +} + +static int +_font_sort_cb(const void *data1, + const void *data2) +{ + if (!data1) return 1; + if (!data2) return -1; + return strcmp(data1, data2); +} + +static void +_font_sizes_list_load(Evas_Object *size_list) +{ + Elm_Font_Size_Data *size_data; + Eina_List *l; + Evas *evas; + + evas = evas_object_evas_get(size_list); + evas_event_freeze(evas); + edje_freeze(); + + EINA_LIST_FOREACH(fdata.font_scale_list, l, size_data) + elm_list_item_append(size_list, size_data->size_str, NULL, NULL, + _font_sizes_list_sel, size_data); + + EINA_LIST_FOREACH(fdata.font_px_list, l, size_data) + elm_list_item_append(size_list, size_data->size_str, NULL, NULL, + _font_sizes_list_sel, size_data); + + elm_list_go(size_list); + edje_thaw(); + evas_event_thaw(evas); +} + +static void +_fnames_list_unselect_cb(void *data __UNUSED__, + Evas_Object *obj, + void *event_info __UNUSED__) +{ + Evas_Object *styles_list, *sizes_list, *win; + + if (elm_list_selected_item_get(obj)) return; + + win = elm_object_top_widget_get(obj); + + styles_list = evas_object_data_get(win, "font_styles_list"); + ELM_LIST_DISABLE(styles_list); + + sizes_list = evas_object_data_get(win, "font_sizes_list"); + ELM_LIST_DISABLE(sizes_list); +} + +static Eina_Bool +_font_list_fill(const Eina_Hash *hash __UNUSED__, + const void *key __UNUSED__, + void *data, + void *fdata) +{ + Elm_Font_Properties *efp; + Eina_List **flist; + + flist = fdata; + efp = data; + + *flist = eina_list_append(*flist, efp->name); + + return EINA_TRUE; +} + +static void +_font_names_list_load(Evas_Object *flist) +{ + Eina_List *l, *names_list = NULL; + const char *font; + Evas *evas; + + evas = evas_object_evas_get(flist); + evas_event_freeze(evas); + edje_freeze(); + + eina_hash_foreach(fdata.font_hash, _font_list_fill, &names_list); + names_list = eina_list_sort(names_list, eina_list_count(names_list), + _font_sort_cb); + + EINA_LIST_FOREACH(names_list, l, font) + elm_list_item_append(flist, font, NULL, NULL, _font_names_list_sel, NULL); + + EINA_LIST_FREE(names_list, font); + + evas_object_smart_callback_add(flist, "unselected", _fnames_list_unselect_cb, + NULL); + + elm_list_go(flist); + + edje_thaw(); + evas_event_thaw(evas); +} + +static void +_status_config_fonts(Evas_Object *win, + Evas_Object *pager) +{ + Evas_Object *base, *fr, *li, *rc, *preview, *sp, *pd, *bt, *bx; + char buf[PATH_MAX]; + + _fonts_data_fill(evas_object_evas_get(win)); + + base = elm_table_add(win); + evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(base, EVAS_HINT_FILL, EVAS_HINT_FILL); + + /* yeah, dummy rectangles are ugly as hell, but no good way yet of + fixing sizes */ + rc = evas_object_rectangle_add(evas_object_evas_get(win)); + evas_object_size_hint_min_set(rc, 70, 170); + elm_table_pack(base, rc, 1, 0, 1, 1); + + fr = elm_frame_add(win); + elm_frame_label_set(fr, "Font Class"); + elm_table_pack(base, fr, 0, 0, 1, 2); + evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(fr); + + /* FIXME: no multiselection for this list, for now */ + li = elm_list_add(win); + evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_frame_content_set(fr, li); + evas_object_show(li); + + evas_object_data_set(win, "font_classes_list", li); + _font_classes_list_load(li); + + fr = elm_frame_add(win); + elm_frame_label_set(fr, "Font"); + elm_table_pack(base, fr, 1, 0, 1, 2); + evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(fr); + + li = elm_list_add(win); + evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_frame_content_set(fr, li); + evas_object_show(li); + + evas_object_data_set(win, "font_names_list", li); + _font_names_list_load(li); + ELM_LIST_DISABLE(li); + + rc = evas_object_rectangle_add(evas_object_evas_get(win)); + evas_object_size_hint_min_set(rc, 70, 130); + elm_table_pack(base, rc, 1, 2, 1, 1); + + fr = elm_frame_add(win); + elm_frame_label_set(fr, "Style"); + elm_table_pack(base, fr, 0, 2, 1, 1); + evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(fr); + ELM_LIST_DISABLE(li); + + li = elm_list_add(win); + evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_frame_content_set(fr, li); + evas_object_show(li); + + evas_object_data_set(win, "font_styles_list", li); + evas_object_smart_callback_add(li, "unselected", _fstyle_list_unselect_cb, + NULL); + + fr = elm_frame_add(win); + elm_frame_label_set(fr, "Size"); + elm_table_pack(base, fr, 1, 2, 1, 1); + evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(fr); + + li = elm_list_add(win); + evas_object_size_hint_weight_set(li, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_frame_content_set(fr, li); + evas_object_show(li); + + evas_object_data_set(win, "font_sizes_list", li); + _font_sizes_list_load(li); + ELM_LIST_DISABLE(li); + + bx = elm_box_add(win); + evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_table_pack(base, bx, 0, 3, 2, 1); + evas_object_show(bx); + + /* FIXME: what to do here? dedicated widget? some new entry API set? */ + snprintf(buf, sizeof(buf), "%s/objects/font_preview.edj", PACKAGE_DATA_DIR); + preview = elm_layout_add(win); + elm_layout_file_set(preview, buf, "font_preview"); + elm_layout_text_set(preview, "elm.text", "Preview Text — 我真的会写中文"); + evas_object_size_hint_weight_set(preview, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(preview, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(preview); + + elm_box_pack_end(bx, preview); + evas_object_data_set(win, "font_preview", elm_layout_edje_get(preview)); + + ///////////////////////////////////////////// + sp = elm_separator_add(win); + elm_separator_horizontal_set(sp, EINA_TRUE); + evas_object_size_hint_weight_set(sp, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(sp, EVAS_HINT_FILL, 0.5); + elm_table_pack(base, sp, 0, 4, 2, 1); + evas_object_show(sp); + + pd = elm_frame_add(win); + elm_object_style_set(pd, "pad_medium"); + evas_object_size_hint_weight_set(pd, 0.0, 0.0); + evas_object_size_hint_align_set(pd, 0.5, 0.5); + elm_table_pack(base, pd, 0, 5, 2, 1); + evas_object_show(pd); + + bx = elm_box_add(win); + elm_box_horizontal_set(bx, EINA_TRUE); + evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(bx); + + bt = elm_button_add(win); + evas_object_smart_callback_add(bt, "clicked", _font_overlay_reset, win); + elm_button_label_set(bt, "Reset"); + evas_object_size_hint_weight_set(bt, 0.0, 0.0); + evas_object_size_hint_align_set(bt, 0.5, 0.5); + elm_box_pack_end(bx, bt); + evas_object_show(bt); + + bt = elm_button_add(win); + evas_object_smart_callback_add(bt, "clicked", _font_overlay_reset_all, win); + elm_button_label_set(bt, "Reset All"); + evas_object_size_hint_weight_set(bt, 0.0, 0.0); + evas_object_size_hint_align_set(bt, 0.5, 0.5); + elm_box_pack_end(bx, bt); + evas_object_show(bt); + + bt = elm_button_add(win); + evas_object_smart_callback_add(bt, "clicked", _font_overlay_change, win); + elm_button_label_set(bt, "Apply"); + evas_object_size_hint_weight_set(bt, 0.0, 0.0); + evas_object_size_hint_align_set(bt, 0.5, 0.5); + elm_box_pack_end(bx, bt); + evas_object_show(bt); + + elm_frame_content_set(pd, bx); + + evas_object_data_set(win, "fonts", base); + + elm_pager_content_push(pager, base); } static void @@ -1264,7 +2059,7 @@ status_win(void) win = elm_win_add(NULL, "main", ELM_WIN_BASIC); elm_win_title_set(win, "Elementary Config"); - evas_object_smart_callback_add(win, "delete,request", my_win_del, NULL); + evas_object_smart_callback_add(win, "delete,request", config_exit, NULL); bg = elm_bg_add(win); evas_object_size_hint_weight_set(bg, 1.0, 1.0); elm_win_resize_object_add(win, bg); diff --git a/legacy/elementary/src/lib/Elementary.h.in b/legacy/elementary/src/lib/Elementary.h.in index e2aa52265f..4af619597e 100644 --- a/legacy/elementary/src/lib/Elementary.h.in +++ b/legacy/elementary/src/lib/Elementary.h.in @@ -282,6 +282,41 @@ extern "C" { EAPI const char *elm_engine_current_get(void); EAPI void elm_engine_set(const char *engine); + typedef struct _Elm_Text_Class + { + const char *name; + const char *desc; + } Elm_Text_Class; + + typedef struct _Elm_Font_Overlay + { + const char *text_class; + const char *font; + Evas_Font_Size size; + } Elm_Font_Overlay; + + typedef struct _Elm_Font_Properties + { + const char *name; + Eina_List *styles; + } Elm_Font_Properties; + + EAPI const Eina_List *elm_text_classes_list_get(void); + EAPI void elm_text_classes_list_free(const Eina_List *list); + + EAPI const Eina_List *elm_font_overlay_list_get(void); + EAPI void elm_font_overlay_set(const char *text_class, const char *font, Evas_Font_Size size); + EAPI void elm_font_overlay_unset(const char *text_class); + EAPI void elm_font_overlay_apply(); + EAPI void elm_font_overlay_all_apply(); + + EAPI Elm_Font_Properties *elm_font_properties_get(const char *font); + EAPI void elm_font_properties_free(Elm_Font_Properties *efp); + EAPI const char *elm_font_fontconfig_name_get(const char *name, const char *style); + EAPI void elm_font_fontconfig_name_free(const char *name); + EAPI Eina_Hash *elm_font_available_hash_add(Eina_List *list); + EAPI void elm_font_available_hash_del(Eina_Hash *hash); + EAPI Evas_Coord elm_finger_size_get(void); EAPI void elm_finger_size_set(Evas_Coord size); EAPI void elm_finger_size_all_set(Evas_Coord size); diff --git a/legacy/elementary/src/lib/Makefile.am b/legacy/elementary/src/lib/Makefile.am index e737fd91d6..d297f27ea2 100644 --- a/legacy/elementary/src/lib/Makefile.am +++ b/legacy/elementary/src/lib/Makefile.am @@ -80,6 +80,7 @@ elm_conform.c \ elm_mapbuf.c \ elm_thumb.c \ elm_config.c \ +elm_font.c \ elm_animator.c \ elm_transit.c \ elm_calendar.c \ diff --git a/legacy/elementary/src/lib/elm_config.c b/legacy/elementary/src/lib/elm_config.c index e24ac91b23..62f970b00e 100644 --- a/legacy/elementary/src/lib/elm_config.c +++ b/legacy/elementary/src/lib/elm_config.c @@ -12,6 +12,7 @@ Elm_Config *_elm_config = NULL; char *_elm_profile = NULL; static Eet_Data_Descriptor *_config_edd = NULL; +static Eet_Data_Descriptor *_config_font_overlay_edd = NULL; const char *_elm_engines[] = { "software_x11", @@ -29,6 +30,34 @@ const char *_elm_engines[] = { NULL }; +/* whenever you want to add a new text class support into Elementary, + declare it both here and in the (default) theme */ +static const Elm_Text_Class _elm_text_classes[] = { + {"button", "Button Labels"}, + + /* FIXME: put in the right/definitive font classes */ + {"title_bar", "Title Bar"}, + {"menu_item", "Menu Item"}, + {"menu_title", "Menu Title"}, + {"tb_plain", "Textblock Plain"}, + {"tb_light", "Textblock Light"}, + {"tb_big", "Textblock Big"}, + {"move_text", "Move Text"}, + {"resize_text", "Resize Text"}, + {"winlist_title", "Winlist Title"}, + {"configure", "Settings Heading"}, + {"about_title", "About Title"}, + {"about_version", "About Version"}, + {"desklock_title", "Desklock Title"}, + {"desklock_passwd", "Desklock Password"}, + {"dialog_error", "Dialog Error"}, + {"exebuf_command", "Exebuf Command"}, + {"init_title", "Splash Title"}, + {"init_text", "Splash Text"}, + {"init_version", "Splash Version"}, + {NULL, NULL} +}; + static void _desc_init(void); static void _desc_shutdown(void); static void _profile_fetch_from_conf(void); @@ -50,7 +79,7 @@ static size_t _elm_user_dir_snprintf(char *dst, size_t size, const char *fmt, .. #ifdef HAVE_ELEMENTARY_X static Ecore_Event_Handler *_prop_change_handler = NULL; static Ecore_X_Window _root_1st = 0; -#define ATOM_COUNT 5 +#define ATOM_COUNT 6 static Ecore_X_Atom _atom[ATOM_COUNT]; static Ecore_X_Atom _atom_config = 0; static const char *_atom_names[ATOM_COUNT] = @@ -59,13 +88,15 @@ static const char *_atom_names[ATOM_COUNT] = "ENLIGHTENMENT_FINGER_SIZE", "ENLIGHTENMENT_THEME", "ENLIGHTENMENT_PROFILE", + "ENLIGHTENMENT_FONT_OVERLAY", "ENLIGHTENMENT_CONFIG" }; #define ATOM_E_SCALE 0 #define ATOM_E_FINGER_SIZE 1 #define ATOM_E_THEME 2 #define ATOM_E_PROFILE 3 -#define ATOM_E_CONFIG 4 +#define ATOM_E_FONT_OVERLAY 4 +#define ATOM_E_CONFIG 5 static Eina_Bool _prop_config_get(void); static Eina_Bool _prop_change(void *data __UNUSED__, int ev_type __UNUSED__, void *ev); @@ -117,6 +148,7 @@ _prop_config_get(void) _config_free(); _elm_config = config_data; _config_apply(); + _elm_config_font_overlay_apply(); _elm_rescale(); return EINA_TRUE; } @@ -195,11 +227,27 @@ _prop_change(void *data __UNUSED__, int ev_type __UNUSED__, void *ev) _config_free(); _config_load(); _config_apply(); + _elm_config_font_overlay_apply(); _elm_rescale(); } } } } + else if (event->atom == _atom[ATOM_E_FONT_OVERLAY]) + { + unsigned int val = 1000; + + if (ecore_x_window_prop_card32_get(event->win, + event->atom, + &val, 1) > 0) + { + _config_free(); + _config_load(); + _config_apply(); + _elm_config_font_overlay_apply(); + _elm_rescale(); + } + } else if (((_atom_config > 0) && (event->atom == _atom_config)) || (event->atom == _atom[ATOM_E_CONFIG])) { @@ -226,12 +274,33 @@ _desc_init(void) return; } -#define T Elm_Config -#define D _config_edd + memset(&eddc, 0, sizeof(eddc)); /* just in case... */ + EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Font_Overlay); + eddc.func.str_direct_alloc = NULL; + eddc.func.str_direct_free = NULL; + + _config_font_overlay_edd = eet_data_descriptor_stream_new(&eddc); + if (!_config_font_overlay_edd) + { + printf("EEEK! eet_data_descriptor_stream_new() failed\n"); + eet_data_descriptor_free(_config_edd); + return; + } #define T_INT EET_T_INT #define T_DOUBLE EET_T_DOUBLE #define T_STRING EET_T_STRING #define T_UCHAR EET_T_UCHAR + +#define T Elm_Font_Overlay +#define D _config_font_overlay_edd + ELM_CONFIG_VAL(D, T, text_class, EET_T_STRING); + ELM_CONFIG_VAL(D, T, font, EET_T_STRING); + ELM_CONFIG_VAL(D, T, size, EET_T_INT); +#undef T +#undef D + +#define T Elm_Config +#define D _config_edd ELM_CONFIG_VAL(D, T, config_version, T_INT); ELM_CONFIG_VAL(D, T, engine, T_STRING); ELM_CONFIG_VAL(D, T, thumbscroll_enable, T_UCHAR); @@ -248,6 +317,7 @@ _desc_init(void) ELM_CONFIG_VAL(D, T, bgpixmap, T_INT); ELM_CONFIG_VAL(D, T, compositing, T_INT); /* EET_DATA_DESCRIPTOR_ADD_LIST(D, T, "font_dirs", font_dirs, sub_edd); */ + ELM_CONFIG_LIST(D, T, font_overlays, _config_font_overlay_edd); ELM_CONFIG_VAL(D, T, font_hinting, T_INT); ELM_CONFIG_VAL(D, T, image_cache, T_INT); ELM_CONFIG_VAL(D, T, font_cache, T_INT); @@ -274,9 +344,17 @@ _desc_init(void) static void _desc_shutdown(void) { - if (!_config_edd) return; - eet_data_descriptor_free(_config_edd); - _config_edd = NULL; + if (_config_edd) + { + eet_data_descriptor_free(_config_edd); + _config_edd = NULL; + } + + if (_config_font_overlay_edd) + { + eet_data_descriptor_free(_config_font_overlay_edd); + _config_font_overlay_edd = NULL; + } } static int @@ -365,6 +443,106 @@ _elm_config_profile_dir_get(const char *prof, Eina_Bool is_user) return NULL; } +Eina_List * +_elm_config_font_overlays_list(void) +{ + return _elm_config->font_overlays; +} + +void +_elm_config_font_overlay_set(const char *text_class, + const char *font, + Evas_Font_Size size) +{ + Elm_Font_Overlay *efd; + Eina_List *l; + + EINA_LIST_FOREACH(_elm_config->font_overlays, l, efd) + { + if (strcmp(efd->text_class, text_class)) + continue; + + if (efd->font) eina_stringshare_del(efd->font); + efd->font = eina_stringshare_add(font); + efd->size = size; + _elm_config->font_overlays = + eina_list_promote_list(_elm_config->font_overlays, l); + return; + } + + /* the text class doesn't exist */ + efd = calloc(1, sizeof(Elm_Font_Overlay)); + efd->text_class = eina_stringshare_add(text_class); + efd->font = eina_stringshare_add(font); + efd->size = size; + + _elm_config->font_overlays = eina_list_prepend(_elm_config->font_overlays, + efd); +} + +void +_elm_config_font_overlay_remove(const char *text_class) +{ + Elm_Font_Overlay *efd; + Eina_List *l; + + EINA_LIST_FOREACH(_elm_config->font_overlays, l, efd) + { + if (strcmp(efd->text_class, text_class)) + continue; + + _elm_config->font_overlays = + eina_list_remove_list(_elm_config->font_overlays, l); + if (efd->text_class) eina_stringshare_del(efd->text_class); + if (efd->font) eina_stringshare_del(efd->font); + free(efd); + + return; + } +} + +void +_elm_config_font_overlay_apply(void) +{ + Elm_Font_Overlay *efd; + Eina_List *l; + int i; + + for (i = 0; _elm_text_classes[i].desc; i++) + edje_text_class_del(_elm_text_classes[i].name); + + EINA_LIST_FOREACH(_elm_config->font_overlays, l, efd) + edje_text_class_set(efd->text_class, efd->font, efd->size); +} + +Eina_List * +_elm_config_text_classes_get(void) +{ + Eina_List *ret = NULL; + int i; + + for (i = 0; _elm_text_classes[i].desc; i++) + { + Elm_Text_Class *tc; + tc = malloc(sizeof(*tc)); + + *tc = _elm_text_classes[i]; + + ret = eina_list_append(ret, tc); + } + + return ret; +} + +void +_elm_config_text_classes_free(Eina_List *l) +{ + Elm_Text_Class *tc; + + EINA_LIST_FREE(l, tc) + free(tc); +} + Eina_List * _elm_config_profiles_list(void) { @@ -512,6 +690,7 @@ _profile_fetch_from_conf(void) static void _config_free(void) { + Elm_Font_Overlay *fo; const char *fontdir; if (!_elm_config) return; @@ -520,6 +699,12 @@ _config_free(void) eina_stringshare_del(fontdir); } if (_elm_config->engine) eina_stringshare_del(_elm_config->engine); + EINA_LIST_FREE(_elm_config->font_overlays, fo) + { + if (fo->text_class) eina_stringshare_del(fo->text_class); + if (fo->font) eina_stringshare_del(fo->font); + free(fo); + } if (_elm_config->theme) eina_stringshare_del(_elm_config->theme); if (_elm_config->modules) eina_stringshare_del(_elm_config->modules); free(_elm_config); @@ -1040,6 +1225,7 @@ _elm_config_init(void) _config_load(); _env_get(); _config_apply(); + _elm_config_font_overlay_apply(); } void @@ -1143,6 +1329,7 @@ _elm_config_reload(void) _config_free(); _config_load(); _config_apply(); + _elm_config_font_overlay_apply(); _elm_rescale(); } @@ -1174,6 +1361,7 @@ _elm_config_profile_set(const char *profile) _config_free(); _config_load(); _config_apply(); + _elm_config_font_overlay_apply(); _elm_rescale(); } } diff --git a/legacy/elementary/src/lib/elm_font.c b/legacy/elementary/src/lib/elm_font.c new file mode 100644 index 0000000000..844fc7bdb9 --- /dev/null +++ b/legacy/elementary/src/lib/elm_font.c @@ -0,0 +1,128 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif + +#ifdef HAVE_EVIL +# include +#endif + +#include +#include "elm_priv.h" + +Elm_Font_Properties * +_elm_font_properties_get(Eina_Hash **font_hash, + const char *font) +{ + Elm_Font_Properties *efp = NULL; + char *s1; + + s1 = strchr(font, ':'); + if (s1) + { + char *s2, *name, *style; + int len; + + len = s1 - font; + name = calloc(sizeof(char), len + 1); + strncpy(name, font, len); + + /* get subname (should be english) */ + s2 = strchr(name, ','); + if (s2) + { + len = s2 - name; + name = realloc(name, sizeof(char) * len + 1); + memset(name, 0, sizeof(char) * len + 1); + strncpy(name, font, len); + } + + if (!strncmp(s1, ELM_FONT_TOKEN_STYLE, strlen(ELM_FONT_TOKEN_STYLE))) + { + style = s1 + strlen(ELM_FONT_TOKEN_STYLE); + + if (font_hash) efp = eina_hash_find(*font_hash, name); + if (!efp) + { + efp = calloc(1, sizeof(Elm_Font_Properties)); + efp->name = eina_stringshare_add(name); + if (font_hash) + { + if (!*font_hash) + *font_hash = eina_hash_string_superfast_new(NULL); + eina_hash_add(*font_hash, name, efp); + } + } + s2 = strchr(style, ','); + if (s2) + { + char *style_old; + + len = s2 - style; + style_old = style; + style = calloc(sizeof(char), len + 1); + strncpy(style, style_old, len); + efp->styles = eina_list_append(efp->styles, + eina_stringshare_add(style)); + free(style); + } + else + efp->styles = eina_list_append(efp->styles, + eina_stringshare_add(style)); + } + free(name); + } + else + { + if (font_hash) efp = eina_hash_find(*font_hash, font); + if (!efp) + { + efp = calloc(1, sizeof(Elm_Font_Properties)); + efp->name = eina_stringshare_add(font); + if (font_hash) + { + if (!*font_hash) + *font_hash = eina_hash_string_superfast_new(NULL); + eina_hash_add(*font_hash, font, efp); + } + } + } + return efp; +} + +/* FIXME: do we really need it? */ +Eina_Hash * +_elm_font_available_hash_add(Eina_Hash *font_hash, + const char *full_name) +{ + _elm_font_properties_get(&font_hash, full_name); + return font_hash; +} + +static void +_elm_font_properties_free(Elm_Font_Properties *efp) +{ + const char *str; + + EINA_LIST_FREE(efp->styles, str) + if (str) eina_stringshare_del(str); + + if (efp->name) eina_stringshare_del(efp->name); + free(efp); +} + +static Eina_Bool +_font_hash_free_cb(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__) +{ + Elm_Font_Properties *efp; + + efp = data; + _elm_font_properties_free(efp); + return EINA_TRUE; +} + +void +_elm_font_available_hash_del(Eina_Hash *hash) +{ + eina_hash_foreach(hash, _font_hash_free_cb, NULL); + eina_hash_free(hash); +} diff --git a/legacy/elementary/src/lib/elm_main.c b/legacy/elementary/src/lib/elm_main.c index 76d8f7db2c..4a860b79be 100644 --- a/legacy/elementary/src/lib/elm_main.c +++ b/legacy/elementary/src/lib/elm_main.c @@ -1439,6 +1439,280 @@ elm_engine_set(const char *engine) _elm_config_engine_set(engine); } +/** + * @defgroup Fonts Elementary Fonts + * + * These are functions dealing with font rendering, selection and the + * like for Elementary applications. One might fetch which system + * fonts are there to use and set custom fonts for individual classes + * of UI items containing text (text classes). + */ + +/** + * Get Elementary's list of supported text classes. + * + * @return The text classes list, with @c Elm_Text_Class blobs as data. + * @ingroup Fonts + * + * Release the list with elm_text_classes_list_free(). + */ +EAPI const Eina_List * +elm_text_classes_list_get(void) +{ + return _elm_config_text_classes_get(); +} + +/** + * Free Elementary's list of supported text classes. + * + * @ingroup Fonts + * + * @see elm_text_classes_list_get(). + */ +EAPI void +elm_text_classes_list_free(const Eina_List *list) +{ + _elm_config_text_classes_free((Eina_List *)list); +} + +/** + * Get Elementary's list of font overlays, set with + * elm_font_overlay_set(). + * + * @return The font overlays list, with @c Elm_Font_Overlay blobs as + * data. + * + * @ingroup Fonts + * + * For each text class, one can set a font overlay for it, + * overriding the default font properties for that class coming from + * the theme in use. There is no need to free this list. + * + * @see elm_font_overlay_set() and elm_font_overlay_unset(). + */ +EAPI const Eina_List * +elm_font_overlay_list_get(void) +{ + return _elm_config_font_overlays_list(); +} + +/** + * Set a font overlay for a given Elementary text class. + * + * @param text_class Text class name + * @param font Font name and style string + * @param size Font size + * + * @ingroup Fonts + * + * @p font has to be in the format returned by + * elm_font_fontconfig_name_get(). @see elm_font_overlay_list_get() + * and @elm_font_overlay_unset(). + */ +EAPI void +elm_font_overlay_set(const char *text_class, + const char *font, + Evas_Font_Size size) +{ + _elm_config_font_overlay_set(text_class, font, size); +} + +/** + * Unset a font overlay for a given Elementary text class. + * + * @param text_class Text class name + * + * @ingroup Fonts + * + * This will bring back text elements belonging to text class @p + * text_class back to their default font settings. + */ +EAPI void +elm_font_overlay_unset(const char *text_class) +{ + _elm_config_font_overlay_remove(text_class); +} + +/** + * Apply the changes made with elm_font_overlay_set() and + * elm_font_overlay_unset() on the current Elementary window. + * + * @ingroup Fonts + * + * This applies all font overlays set to all objects in the UI. + */ +EAPI void +elm_font_overlay_apply(void) +{ + _elm_config_font_overlay_apply(); +} + +/** + * Apply the changes made with elm_font_overlay_set() and + * elm_font_overlay_unset() on all Elementary application windows. + * + * @ingroup Fonts + * + * This applies all font overlays set to all objects in the UI. + */ +EAPI void +elm_font_overlay_all_apply(void) +{ +#ifdef HAVE_ELEMENTARY_X + static Ecore_X_Atom atom = 0; + unsigned int dummy = (unsigned int)(1 * 1000.0); + + if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_FONT_OVERLAY"); + ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(), atom, &dummy, + 1); +#endif +} + +/** + * Translate a font (family) name string in fontconfig's font names + * syntax into an @c Elm_Font_Properties struct. + * + * @param font The font name and styles string + * @return the font properties struct + * + * @ingroup Fonts + * + * @note The reverse translation can be achived with + * elm_font_fontconfig_name_get(), for one style only (single font + * instance, not family). + */ +EAPI Elm_Font_Properties * +elm_font_properties_get(const char *font) +{ + if (!font) return NULL; + return _elm_font_properties_get(NULL, font); +} + +/** + * Free font properties return by elm_font_properties_get(). + * + * @param efp the font properties struct + * + * @ingroup Fonts + */ +EAPI void +elm_font_properties_free(Elm_Font_Properties *efp) +{ + const char *str; + + EINA_LIST_FREE(efp->styles, str) + if (str) eina_stringshare_del(str); + if (efp->name) eina_stringshare_del(efp->name); + free(efp); +} + +/** + * Translate a font name, bound to a style, into fontconfig's font names + * syntax. + * + * @param name The font (family) name + * @param style The given style (may be @c NULL) + * + * @return the font name and style string + * + * @ingroup Fonts + * + * @note The reverse translation can be achived with + * elm_font_properties_get(), for one style only (single font + * instance, not family). + */ +EAPI const char * +elm_font_fontconfig_name_get(const char *name, + const char *style) +{ + char buf[256]; + + if (!name) return NULL; + if (!style || style[0] == 0) return eina_stringshare_add(name); + snprintf(buf, 256, "%s" ELM_FONT_TOKEN_STYLE "%s", name, style); + return eina_stringshare_add(buf); +} + +/** + * Free the font string return by elm_font_fontconfig_name_get(). + * + * @param efp the font properties struct + * + * @ingroup Fonts + */ +EAPI void +elm_font_fontconfig_name_free(const char *name) +{ + eina_stringshare_del(name); +} + +/** + * Create a font hash table of available system fonts. + * + * One must call it with @p list being the return value of + * evas_font_available_list(). The hash will be indexed by font + * (family) names, being its values @c Elm_Font_Properties blobs. + * + * @param list The list of available system fonts, as returned by + * evas_font_available_list(). + * @return the font hash. + * + * @ingroup Fonts + * + * @note The user is supposed to get it populated at least with 3 + * default font families (Sans, Serif, Monospace), which should be + * present on most systems. + */ +EAPI Eina_Hash * +elm_font_available_hash_add(Eina_List *list) +{ + Eina_Hash *font_hash; + Eina_List *l; + void *key; + + font_hash = NULL; + + /* populate with default font families */ + font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Regular"); + font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Bold"); + font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Oblique"); + font_hash = _elm_font_available_hash_add(font_hash, + "Sans:style=Bold Oblique"); + + font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Regular"); + font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Bold"); + font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Oblique"); + font_hash = _elm_font_available_hash_add(font_hash, + "Serif:style=Bold Oblique"); + + font_hash = _elm_font_available_hash_add(font_hash, + "Monospace:style=Regular"); + font_hash = _elm_font_available_hash_add(font_hash, + "Monospace:style=Bold"); + font_hash = _elm_font_available_hash_add(font_hash, + "Monospace:style=Oblique"); + font_hash = _elm_font_available_hash_add(font_hash, + "Monospace:style=Bold Oblique"); + + EINA_LIST_FOREACH(list, l, key) + font_hash = _elm_font_available_hash_add(font_hash, key); + + return font_hash; +} + +/** + * Free the hash return by elm_font_available_hash_add(). + * + * @param hash the hash to be freed. + * + * @ingroup Fonts + */ +EAPI void +elm_font_available_hash_del(Eina_Hash *hash) +{ + _elm_font_available_hash_del(hash); +} + /** * @defgroup Fingers Fingers * diff --git a/legacy/elementary/src/lib/elm_priv.h b/legacy/elementary/src/lib/elm_priv.h index 526a58b429..cb39ad3993 100644 --- a/legacy/elementary/src/lib/elm_priv.h +++ b/legacy/elementary/src/lib/elm_priv.h @@ -67,6 +67,8 @@ extern const char *_elm_engines[]; #define ELM_SOFTWARE_16_SDL (_elm_engines[10]) #define ELM_OPENGL_SDL (_elm_engines[11]) +#define ELM_FONT_TOKEN_STYLE ":style=" + struct _Elm_Config { int config_version; @@ -85,6 +87,7 @@ struct _Elm_Config int bgpixmap; int compositing; Eina_List *font_dirs; + Eina_List *font_overlays; int font_hinting; int image_cache; int font_cache; @@ -156,6 +159,17 @@ void _elm_config_profile_set(const char *profile); void _elm_config_engine_set(const char *engine); +Eina_List *_elm_config_font_overlays_list(void); +void _elm_config_font_overlay_set(const char *text_class, const char *font, Evas_Font_Size size); +void _elm_config_font_overlay_remove(const char *text_class); +void _elm_config_font_overlay_apply(void); +Eina_List *_elm_config_text_classes_get(void); +void _elm_config_text_classes_free(Eina_List *l); + +Elm_Font_Properties *_elm_font_properties_get(Eina_Hash **font_hash, const char *font); +Eina_Hash *_elm_font_available_hash_add(Eina_Hash *font_hash, const char *full_name); +void _elm_font_available_hash_del(Eina_Hash *hash); + void elm_tooltip_theme(Elm_Tooltip *tt); void elm_object_sub_tooltip_content_cb_set(Evas_Object *eventarea, Evas_Object *owner, Elm_Tooltip_Content_Cb func, const void *data, Evas_Smart_Cb del_cb); void elm_cursor_theme(Elm_Cursor *cur);