1 #include "e.h"
2
3 typedef struct _E_Font_Size_Data E_Font_Size_Data;
4 typedef struct _E_Text_Class_Pair E_Text_Class_Pair;
5 typedef struct _CFText_Class CFText_Class;
6
7 static void *_create_data(E_Config_Dialog *cfd);
8 static void _free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
9 static int _basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
10 static Evas_Object *_basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
11 static int _advanced_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
12 static Evas_Object *_advanced_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
13
14 static void _basic_font_cb_change(void *data, Evas_Object *obj);
15 static void _basic_enable_cb_change(void *data, Evas_Object *obj);
16 static void _basic_init_data_fill(E_Config_Dialog_Data *cfdata);
17
18 static void _adv_class_cb_change(void *data, Evas_Object *obj);
19 static void _adv_enabled_font_cb_change(void *data, Evas_Object *obj);
20 static void _adv_enabled_fallback_cb_change(void *data, Evas_Object *obj);
21 static void _adv_font_cb_change(void *data, Evas_Object *obj);
22 static void _adv_style_cb_change(void *data, Evas_Object *obj);
23 static void _size_cb_change(void *data);
24
25 static int _sort_fonts(const void *data1, const void *data2);
26 static void _font_list_load(E_Config_Dialog_Data *cfdata, const char *cur_font);
27 static void _size_list_load(E_Config_Dialog_Data *cfdata, Eina_List *size_list, Evas_Font_Size cur_size, int clear);
28 static void _class_list_load(E_Config_Dialog_Data *cfdata);
29 static void _font_preview_update(E_Config_Dialog_Data *cfdata);
30
31 static Eina_Bool _font_hash_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata);
32
33 struct _E_Font_Size_Data
34 {
35 E_Config_Dialog_Data *cfdata;
36 const char *size_str;
37 Evas_Font_Size size;
38 };
39
40 struct _E_Text_Class_Pair
41 {
42 const char *class_name;
43 const char *class_description;
44 };
45
46 struct _CFText_Class
47 {
48 const char *class_name;
49 const char *class_description;
50 const char *font;
51 const char *style;
52 Evas_Font_Size size;
53 int enabled;
54 };
55
56 const E_Text_Class_Pair text_class_predefined_names[] = {
57 { NULL, N_("Core")},
58 { "application", N_("Applications")},
59 { "title_bar", N_("Title Bar")},
60 { "menu_item", N_("Menu Item")},
61 { "menu_title", N_("Menu Title")},
62 { "tb_plain", N_("Textblock Plain")},
63 { "tb_light", N_("Textblock Light")},
64 { "tb_big", N_("Textblock Big")},
65 { "move_text", N_("Move Text")},
66 { "resize_text", N_("Resize Text")},
67 { "winlist_title", N_("Winlist Title")},
68 { "configure", N_("Settings Heading")},
69 { "about_title", N_("About Title")},
70 { "about_version", N_("About Version")},
71 { "button_text", N_("Button Text")},
72 { "desklock_title", N_("Desklock Title")},
73 { "desklock_passwd", N_("Desklock Password")},
74 { "dialog_error", N_("Dialog Error")},
75 { "exebuf_command", N_("Exebuf Command")},
76 { "init_title", N_("Splash Title")},
77 { "init_text", N_("Splash Text")},
78 { "init_version", N_("Splash Version")},
79 { "clock", N_("Digital Clock")},
80
81 { NULL, N_("Widgets")},
82 { "entry", N_("Entry")},
83 { "frame", N_("Frame")},
84 { "label", N_("Label")},
85 { "button", N_("Buttons")},
86 { "slider", N_("Slider")},
87 { "radio_button", N_("Radio Buttons")},
88 { "check_button", N_("Check Buttons")},
89 { "tlist", N_("Text List Item")},
90 { "ilist_item", N_("List Item")},
91 { "ilist_header", N_("List Header")},
92
93 { NULL, N_("Filemanager")},
94 { "fileman_typebuf", N_("Typebuf")},
95 { "fileman_icon", N_("Icon")},
96 { "desktop_icon", N_("Desktop Icon")},
97
98 { NULL, N_("Modules")},
99 { "module_small", N_("Small")},
100 { "module_normal", N_("Normal")},
101 { "module_large", N_("Large")},
102 { "module_small_s", N_("Small Styled")},
103 { "module_normal_s", N_("Normal Styled")},
104 { "module_large_s", N_("Large Styled")},
105
106 { NULL, NULL}
107 };
108
109 struct _E_Config_Dialog_Data
110 {
111 E_Config_Dialog *cfd;
112 Evas *evas;
113
114 /* Text Classes */
115 Eina_List *text_classes;
116
117 /* Font Data */
118 Eina_Hash *font_hash;
119 Eina_List *font_list;
120 Eina_List *font_px_list;
121 Eina_List *font_scale_list;
122
123 /* Current data */
124 const char *cur_font;
125 const char *cur_style;
126 double cur_size;
127 int cur_enabled;
128 CFText_Class *cur_class;
129
130 /* Font Fallbacks */
131 int cur_fallbacks_enabled;
132
133 /* Font Hinting */
134 int hinting;
135
136 struct
137 {
138 /* Font Classes */
139 Evas_Object *class_list;
140 Evas_Object *font_list;
141 Evas_Object *style_list;
142 Evas_Object *size_list;
143 Evas_Object *enabled;
144 Evas_Object *preview;
145
146 /* Font Fallbacks */
147 Evas_Object *fallback_list; /* Selecting a list entry starts edit*/
148 } gui;
149 };
150
151 E_Config_Dialog *
e_int_config_fonts(Evas_Object * parent EINA_UNUSED,const char * params EINA_UNUSED)152 e_int_config_fonts(Evas_Object *parent EINA_UNUSED, const char *params EINA_UNUSED)
153 {
154 E_Config_Dialog *cfd;
155 E_Config_Dialog_View *v;
156
157 if (e_config_dialog_find("E", "appearance/fonts")) return NULL;
158 v = E_NEW(E_Config_Dialog_View, 1);
159
160 v->create_cfdata = _create_data;
161 v->free_cfdata = _free_data;
162 v->basic.create_widgets = _basic_create_widgets;
163 v->basic.apply_cfdata = _basic_apply_data;
164 v->advanced.create_widgets = _advanced_create_widgets;
165 v->advanced.apply_cfdata = _advanced_apply_data;
166
167 cfd = e_config_dialog_new(NULL, _("Font Settings"),
168 "E", "appearance/fonts",
169 "preferences-desktop-font", 0, v, NULL);
170 return cfd;
171 }
172
173 static void
_fill_data(E_Config_Dialog_Data * cfdata)174 _fill_data(E_Config_Dialog_Data *cfdata)
175 {
176 Eina_List *font_list;
177 Eina_List *next;
178 E_Font_Default *efd;
179 E_Font_Size_Data *size_data;
180 CFText_Class *tc;
181 int i;
182
183 font_list = e_font_default_list();
184
185 /* Fill out the font list */
186 for (i = 0; text_class_predefined_names[i].class_description; i++ )
187 {
188 tc = E_NEW(CFText_Class, 1);
189 tc->class_name = text_class_predefined_names[i].class_name;
190 tc->class_description =
191 _(text_class_predefined_names[i].class_description);
192 tc->font = NULL;
193 tc->size = 0;
194 tc->enabled = 0;
195
196 if (text_class_predefined_names[i].class_name)
197 {
198 /* Search manually because we dont want to fallback */
199 for (next = font_list; next; next = next->next)
200 {
201 efd = next->data;
202
203 if (!strcmp(tc->class_name, efd->text_class))
204 {
205 if (efd->font)
206 {
207 E_Font_Properties *efp;
208
209 efp = e_font_fontconfig_name_parse(efd->font);
210 if (efp->name)
211 tc->font = eina_stringshare_add(efp->name);
212 if (efp->styles)
213 tc->style = eina_stringshare_add(efp->styles->data);
214 e_font_properties_free(efp);
215 }
216 tc->size = efd->size;
217 tc->enabled = 1;
218 }
219 }
220
221 if (!tc->enabled)
222 {
223 /* search with default fallbacks */
224 efd = e_font_default_get(tc->class_name);
225 if (efd)
226 {
227 if (efd->font)
228 {
229 E_Font_Properties *efp;
230
231 efp = e_font_fontconfig_name_parse(efd->font);
232 if (efp->name)
233 tc->font = eina_stringshare_add(efp->name);
234 if (efp->styles)
235 tc->style = eina_stringshare_add(efp->styles->data);
236 e_font_properties_free(efp);
237 }
238 tc->size = efd->size;
239 }
240 }
241 }
242
243 /* Append the class */
244 cfdata->text_classes = eina_list_append(cfdata->text_classes, tc);
245 }
246
247 /* Fill Hinting */
248 cfdata->hinting = e_config->font_hinting;
249
250 size_data = E_NEW(E_Font_Size_Data, 1);
251 size_data->cfdata = cfdata;
252 size_data->size_str = eina_stringshare_add(_("Tiny"));
253 size_data->size = -50;
254 cfdata->font_scale_list = eina_list_append(cfdata->font_scale_list, size_data);
255
256 size_data = E_NEW(E_Font_Size_Data, 1);
257 size_data->cfdata = cfdata;
258 size_data->size_str = eina_stringshare_add(_("Small"));
259 size_data->size = -80;
260 cfdata->font_scale_list = eina_list_append(cfdata->font_scale_list, size_data);
261
262 size_data = E_NEW(E_Font_Size_Data, 1);
263 size_data->cfdata = cfdata;
264 size_data->size_str = eina_stringshare_add(_("Normal"));
265 size_data->size = -100;
266 cfdata->font_scale_list = eina_list_append(cfdata->font_scale_list, size_data);
267
268 size_data = E_NEW(E_Font_Size_Data, 1);
269 size_data->cfdata = cfdata;
270 size_data->size_str = eina_stringshare_add(_("Big"));
271 size_data->size = -150;
272 cfdata->font_scale_list = eina_list_append(cfdata->font_scale_list, size_data);
273
274 size_data = E_NEW(E_Font_Size_Data, 1);
275 size_data->cfdata = cfdata;
276 size_data->size_str = eina_stringshare_add(_("Really Big"));
277 size_data->size = -190;
278 cfdata->font_scale_list = eina_list_append(cfdata->font_scale_list, size_data);
279
280 size_data = E_NEW(E_Font_Size_Data, 1);
281 size_data->cfdata = cfdata;
282 size_data->size_str = eina_stringshare_add(_("Huge"));
283 size_data->size = -250;
284 cfdata->font_scale_list = eina_list_append(cfdata->font_scale_list, size_data);
285
286 for (i = 5; i < 21; i++)
287 {
288 char str[256];
289
290 str[0] = 0;
291 snprintf(str, sizeof(str), P_("%d pixel", "%d pixels", i), i);
292
293 size_data = E_NEW(E_Font_Size_Data, 1);
294 size_data->cfdata = cfdata;
295 size_data->size_str = eina_stringshare_add(str);
296 size_data->size = i;
297 cfdata->font_px_list = eina_list_append(cfdata->font_px_list, size_data);
298 }
299 }
300
301 static void *
_create_data(E_Config_Dialog * cfd)302 _create_data(E_Config_Dialog *cfd)
303 {
304 E_Config_Dialog_Data *cfdata;
305
306 cfdata = E_NEW(E_Config_Dialog_Data, 1);
307 cfdata->cfd = cfd;
308 _fill_data(cfdata);
309 return cfdata;
310 }
311
312 static void
_free_data(E_Config_Dialog * cfd EINA_UNUSED,E_Config_Dialog_Data * cfdata)313 _free_data(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
314 {
315 E_Font_Size_Data *size_data;
316 CFText_Class *tc;
317
318 e_font_available_hash_free(cfdata->font_hash);
319 cfdata->font_list = eina_list_free(cfdata->font_list);
320
321 EINA_LIST_FREE(cfdata->text_classes, tc)
322 {
323 eina_stringshare_del(tc->font);
324 eina_stringshare_del(tc->style);
325 E_FREE(tc);
326 }
327
328 EINA_LIST_FREE(cfdata->font_scale_list, size_data)
329 {
330 eina_stringshare_del(size_data->size_str);
331 E_FREE(size_data);
332 }
333
334 EINA_LIST_FREE(cfdata->font_px_list, size_data)
335 {
336 eina_stringshare_del(size_data->size_str);
337 E_FREE(size_data);
338 }
339
340 eina_stringshare_del(cfdata->cur_font);
341 eina_stringshare_del(cfdata->cur_style);
342 E_FREE(cfdata);
343 }
344
345 static int
_basic_apply_data(E_Config_Dialog * cfd EINA_UNUSED,E_Config_Dialog_Data * cfdata)346 _basic_apply_data(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
347 {
348 CFText_Class *tc;
349 Eina_List *next;
350 int i;
351
352 if (cfdata->cur_enabled && !cfdata->cur_font)
353 return 0;
354
355 for (i = 0; text_class_predefined_names[i].class_description; i++ )
356 {
357 if (!text_class_predefined_names[i].class_name) continue;
358
359 if (cfdata->cur_enabled)
360 {
361 const char *class_name;
362 const char *font_name;
363
364 class_name = text_class_predefined_names[i].class_name;
365 font_name =
366 e_font_fontconfig_name_get(cfdata->cur_font, cfdata->cur_style);
367 e_font_default_set(class_name, font_name, cfdata->cur_size);
368
369 if (i == 1)
370 e_font_default_set("e_basic_font", font_name, cfdata->cur_size);
371
372 eina_stringshare_del(font_name);
373 }
374 else
375 {
376 e_font_default_remove(text_class_predefined_names[i].class_name);
377 if (i == 1)
378 e_font_default_remove("e_basic_font");
379 }
380 }
381
382 e_font_apply();
383 e_config_save_queue();
384
385 #ifndef HAVE_WAYLAND_ONLY
386 e_xsettings_config_update();
387 #endif
388
389 /* Apply to advanced */
390 EINA_LIST_FOREACH(cfdata->text_classes, next, tc)
391 {
392 tc->size = cfdata->cur_size;
393
394 eina_stringshare_del(tc->font);
395 tc->font = eina_stringshare_ref(cfdata->cur_font);
396
397 eina_stringshare_del(tc->style);
398 tc->style = eina_stringshare_ref(cfdata->cur_style);
399 tc->enabled = cfdata->cur_enabled;
400 }
401
402 return 1;
403 }
404
405 static Eina_Bool
_font_hash_cb(const Eina_Hash * hash EINA_UNUSED,const void * key EINA_UNUSED,void * data,void * fdata)406 _font_hash_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
407 {
408 E_Config_Dialog_Data *cfdata;
409 E_Font_Properties *efp;
410
411 cfdata = fdata;
412 efp = data;
413 cfdata->font_list = eina_list_append(cfdata->font_list, efp->name);
414
415 return EINA_TRUE;
416 }
417
418 static Evas_Object *
_basic_create_widgets(E_Config_Dialog * cfd EINA_UNUSED,Evas * evas,E_Config_Dialog_Data * cfdata)419 _basic_create_widgets(E_Config_Dialog *cfd EINA_UNUSED, Evas *evas, E_Config_Dialog_Data *cfdata)
420 {
421 Evas_Object *ot, *ob, *of;
422
423 cfdata->evas = evas;
424
425 e_dialog_resizable_set(cfd->dia, 1);
426 ot = e_widget_table_add(e_win_evas_win_get(evas), 0);
427
428 cfdata->gui.class_list = NULL;
429
430 ob = e_widget_check_add(evas, _("Enable Custom Font Classes"),
431 &(cfdata->cur_enabled));
432 cfdata->gui.enabled = ob;
433 e_widget_on_change_hook_set(ob, _basic_enable_cb_change, cfdata);
434 e_widget_table_object_append(ot, ob, 0, 0, 1, 1, 1, 0, 1, 0);
435
436 of = e_widget_framelist_add(evas, _("Fonts"), 1);
437 ob = e_widget_ilist_add(evas, 16, 16, &(cfdata->cur_font));
438 cfdata->gui.font_list = ob;
439 e_widget_on_change_hook_set(ob, _basic_font_cb_change, cfdata);
440 e_widget_ilist_go(ob);
441 e_widget_framelist_object_append(of, ob);
442 e_widget_table_object_append(ot, of, 0, 1, 1, 1, 1, 1, 1, 1);
443
444 of = e_widget_framelist_add(evas, _("Size"), 1);
445 ob = e_widget_ilist_add(evas, 16, 16, NULL);
446 cfdata->gui.size_list = ob;
447 e_widget_ilist_go(ob);
448 e_widget_size_min_set(ob, 100, 200);
449 e_widget_framelist_object_append(of, ob);
450 e_widget_table_object_append(ot, of, 1, 1, 1, 1, 1, 1, 1, 1);
451 ob = e_widget_font_preview_add
452 (evas, _("English 012 #!? 日本語 にほんご ソフト 中文 華語 한국"));
453 cfdata->gui.preview = ob;
454 e_widget_table_object_append(ot, ob, 0, 2, 2, 1, 1, 0, 1, 0);
455
456 _basic_init_data_fill(cfdata);
457
458 e_widget_disabled_set(cfdata->gui.font_list, !cfdata->cur_enabled);
459 e_widget_disabled_set(cfdata->gui.size_list, !cfdata->cur_enabled);
460
461 return ot;
462 }
463
464 static void
_basic_font_list_select(E_Config_Dialog_Data * cfdata,const char * cur_font)465 _basic_font_list_select(E_Config_Dialog_Data *cfdata, const char *cur_font)
466 {
467 const char *f;
468 Eina_List *next;
469 int n;
470 /* Select Current Font */
471 n = 0;
472 EINA_LIST_FOREACH(cfdata->font_list, next, f)
473 {
474 if (!strcasecmp(f, cur_font))
475 {
476 e_widget_ilist_selected_set(cfdata->gui.font_list, n);
477 break;
478 }
479 n++;
480 }
481 }
482
483 static void
_basic_size_list_select(Evas_Object * ob,int cur_size)484 _basic_size_list_select(Evas_Object *ob, int cur_size)
485 {
486 int n;
487
488 for (n = 0; n < e_widget_ilist_count(ob); n++)
489 {
490 E_Font_Size_Data *size_data;
491
492 if (!(size_data = e_widget_ilist_nth_data_get(ob, n))) continue;
493 if (cur_size == size_data->size)
494 {
495 e_widget_ilist_selected_set(ob, n);
496 break;
497 }
498 }
499 }
500
501 static void
_basic_font_cb_change(void * data,Evas_Object * obj EINA_UNUSED)502 _basic_font_cb_change(void *data, Evas_Object *obj EINA_UNUSED)
503 {
504 E_Config_Dialog_Data *cfdata;
505
506 cfdata = data;
507 if (!cfdata) return;
508 _font_preview_update(cfdata);
509 }
510
511 static void
_basic_enable_cb_change(void * data,Evas_Object * obj EINA_UNUSED)512 _basic_enable_cb_change(void *data, Evas_Object *obj EINA_UNUSED)
513 {
514 E_Config_Dialog_Data *cfdata;
515
516 cfdata = data;
517 if (!cfdata) return;
518
519 e_widget_disabled_set(cfdata->gui.font_list, !cfdata->cur_enabled);
520 e_widget_disabled_set(cfdata->gui.size_list, !cfdata->cur_enabled);
521
522 if (cfdata->cur_enabled)
523 _basic_size_list_select(cfdata->gui.size_list, cfdata->cur_size);
524 else
525 {
526 e_widget_ilist_unselect(cfdata->gui.font_list);
527 e_widget_ilist_unselect(cfdata->gui.size_list);
528 }
529 }
530
531 /* fill the basic dialog with initial data and select it */
532 static void
_basic_init_data_fill(E_Config_Dialog_Data * cfdata)533 _basic_init_data_fill(E_Config_Dialog_Data *cfdata)
534 {
535 Evas_Object *ob;
536 E_Font_Default *efd;
537 const char *init_font;
538 Evas_Font_Size init_size;
539
540 init_font = NULL;
541 init_size = -100;
542
543 /* Get initial basic basic */
544 efd = e_font_default_get("e_basic_font");
545 if (efd)
546 {
547 if (efd->font)
548 {
549 E_Font_Properties *efp;
550
551 efp = e_font_fontconfig_name_parse(efd->font);
552 init_font = eina_stringshare_add(efp->name);
553 e_font_properties_free(efp);
554 }
555 init_size = efd->size;
556 }
557
558 /* Check based on efd */
559 ob = cfdata->gui.enabled;
560 if (!efd)
561 e_widget_check_checked_set(ob, 0);
562 else if (!strcmp(efd->text_class, "default"))
563 e_widget_check_checked_set(ob, 0);
564 else
565 {
566 e_widget_check_checked_set(ob, 1);
567 cfdata->cur_enabled = 1;
568 }
569
570 /* Populate font list (Select current font) */
571 _font_list_load(cfdata, init_font);
572
573 /* Populate size list (Select current font) */
574 _size_list_load(cfdata, cfdata->font_scale_list, init_size, 1);
575 _size_list_load(cfdata, cfdata->font_px_list, init_size, 0);
576 }
577
578 static int
_advanced_apply_data(E_Config_Dialog * cfd EINA_UNUSED,E_Config_Dialog_Data * cfdata)579 _advanced_apply_data(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
580 {
581 int i;
582 const Eina_List *l;
583 CFText_Class *tc;
584 E_Ilist_Item *ili;
585
586 /* Save current data */
587 if (cfdata->cur_class)
588 {
589 tc = cfdata->cur_class;
590 tc->size = cfdata->cur_size;
591 if (cfdata->cur_font)
592 eina_stringshare_replace(&tc->font, cfdata->cur_font);
593 if (cfdata->cur_style)
594 eina_stringshare_replace(&tc->style, cfdata->cur_style);
595 }
596
597 EINA_LIST_FOREACH(cfdata->text_classes, l, tc)
598 {
599 if (!tc->class_name) continue;
600 if (tc->enabled && tc->font)
601 {
602 const char *name;
603
604 name = e_font_fontconfig_name_get(tc->font, tc->style);
605 e_font_default_set(tc->class_name, name, tc->size);
606 eina_stringshare_del(name);
607 }
608 else
609 e_font_default_remove(tc->class_name);
610 }
611 i = 0;
612 EINA_LIST_FOREACH(e_widget_ilist_items_get(cfdata->gui.class_list), l, ili)
613 {
614 Evas_Object *ic;
615 tc = e_widget_ilist_item_data_get(ili);
616 if (!tc)
617 {
618 i++;
619 continue;
620 }
621 if (tc->enabled)
622 {
623 ic = e_icon_add(cfdata->evas);
624 e_util_icon_theme_set(ic, "dialog-ok-apply");
625 e_widget_ilist_nth_icon_set(cfdata->gui.class_list, i, ic);
626 }
627 else
628 e_widget_ilist_nth_icon_set(cfdata->gui.class_list, i, NULL);
629 i++;
630 }
631
632 /* Fallbacks configure */
633 e_font_fallback_clear();
634
635 if (cfdata->cur_fallbacks_enabled)
636 {
637 for (i = 0; i < e_widget_config_list_count(cfdata->gui.fallback_list); i++)
638 {
639 const char *fallback;
640
641 fallback =
642 e_widget_config_list_nth_get(cfdata->gui.fallback_list, i);
643 if ((fallback) && (fallback[0]))
644 e_font_fallback_append(fallback);
645 }
646 }
647 e_font_apply();
648
649 /* Apply Hinting */
650 e_config->font_hinting = cfdata->hinting;
651 e_config_save_queue();
652 /* e font hinting is different */
653 if (e_config->font_hinting == 0)
654 elm_config_font_hint_type_set(EVAS_FONT_HINTING_BYTECODE);
655 else if (e_config->font_hinting == 1)
656 elm_config_font_hint_type_set(EVAS_FONT_HINTING_AUTO);
657 else if (e_config->font_hinting == 2)
658 elm_config_font_hint_type_set(EVAS_FONT_HINTING_NONE);
659
660 #ifndef HAVE_WAYLAND_ONLY
661 e_xsettings_config_update();
662 #endif
663
664 return 1;
665 }
666
667 static Evas_Object *
_advanced_create_widgets(E_Config_Dialog * cfd EINA_UNUSED,Evas * evas,E_Config_Dialog_Data * cfdata)668 _advanced_create_widgets(E_Config_Dialog *cfd EINA_UNUSED, Evas *evas, E_Config_Dialog_Data *cfdata)
669 {
670 Evas_Object *ot, *ob, *of, *otb;
671 E_Radio_Group *rg;
672 Eina_List *next = NULL;
673 int option_enable;
674 E_Font_Fallback *eff;
675
676 cfdata->evas = evas;
677
678 otb = e_widget_toolbook_add(evas, 48 * e_scale, 48 * e_scale);
679
680 ot = e_widget_table_add(e_win_evas_win_get(evas), 0);
681 of = e_widget_frametable_add(evas, _("Font Classes"), 0);
682 ob = e_widget_ilist_add(evas, 16, 16, NULL);
683 cfdata->gui.class_list = ob;
684 _class_list_load(cfdata);
685 e_widget_size_min_set(ob, 110, 220);
686 e_widget_on_change_hook_set(ob, _adv_class_cb_change, cfdata);
687 e_widget_frametable_object_append(of, ob, 0, 0, 1, 1, 1, 1, 1, 1);
688 ob = e_widget_check_add(evas, _("Enable Font Class"), NULL);
689 cfdata->gui.enabled = ob;
690 e_widget_on_change_hook_set(ob, _adv_enabled_font_cb_change, cfdata);
691 e_widget_disabled_set(ob, 1);
692 e_widget_frametable_object_append(of, ob, 0, 1, 1, 1, 1, 0, 1, 0);
693 e_widget_table_object_append(ot, of, 0, 0, 1, 2, 1, 1, 1, 1);
694
695 of = e_widget_framelist_add(evas, _("Font"), 1);
696 ob = e_widget_ilist_add(evas, 16, 16, &(cfdata->cur_font));
697 cfdata->gui.font_list = ob;
698 e_widget_on_change_hook_set(ob, _adv_font_cb_change, cfdata);
699 _font_list_load(cfdata, NULL);
700 e_widget_size_min_set(ob, 110, 220);
701 e_widget_framelist_object_append(of, ob);
702 e_widget_table_object_append(ot, of, 1, 0, 1, 2, 1, 1, 1, 1);
703
704 of = e_widget_framelist_add(evas, _("Style"), 1);
705 ob = e_widget_ilist_add(evas, 16, 16, &(cfdata->cur_style));
706 cfdata->gui.style_list = ob;
707 e_widget_on_change_hook_set(ob, _adv_style_cb_change, cfdata);
708 e_widget_ilist_go(ob);
709 e_widget_size_min_set(ob, 110, 50);
710 e_widget_framelist_object_append(of, ob);
711 e_widget_table_object_append(ot, of, 2, 0, 1, 1, 1, 1, 1, 1);
712
713 of = e_widget_framelist_add(evas, _("Size"), 1);
714 ob = e_widget_ilist_add(evas, 16, 16, NULL);
715 cfdata->gui.size_list = ob;
716 e_widget_ilist_go(ob);
717 e_widget_size_min_set(ob, 110, 50);
718 e_widget_framelist_object_append(of, ob);
719 e_widget_table_object_append(ot, of, 2, 1, 1, 1, 1, 1, 1, 1);
720
721 ob = e_widget_font_preview_add
722 (evas, _("English 012 #!? 日本語 にほんご ソフト 中文 華語 한국"));
723
724 cfdata->gui.preview = ob;
725 e_widget_table_object_append(ot, ob, 0, 2, 3, 1, 1, 0, 1, 0);
726
727 e_widget_toolbook_page_append(otb, NULL, _("General Settings"),
728 ot, 1, 1, 1, 1, 0.5, 0.0);
729
730 ot = e_widget_table_add(e_win_evas_win_get(evas), 0);
731 of = e_widget_frametable_add(evas, _("Hinting"), 0);
732 rg = e_widget_radio_group_new(&(cfdata->hinting));
733 option_enable = evas_font_hinting_can_hint(evas, EVAS_FONT_HINTING_BYTECODE);
734 ob = e_widget_radio_add(evas, _("Bytecode"), 0, rg);
735 e_widget_disabled_set(ob, !option_enable);
736 e_widget_frametable_object_append(of, ob, 0, 0, 1, 1, 1, 0, 1, 0);
737 option_enable = evas_font_hinting_can_hint(evas, EVAS_FONT_HINTING_AUTO);
738 ob = e_widget_radio_add(evas, _("Automatic"), 1, rg);
739 e_widget_disabled_set(ob, !option_enable);
740 e_widget_frametable_object_append(of, ob, 0, 1, 1, 1, 1, 0, 1, 0);
741 option_enable = evas_font_hinting_can_hint(evas, EVAS_FONT_HINTING_NONE);
742 ob = e_widget_radio_add(evas, _("None"), 2, rg);
743 e_widget_disabled_set(ob, !option_enable);
744 e_widget_frametable_object_append(of, ob, 0, 2, 1, 1, 1, 0, 1, 0);
745 e_widget_table_object_append(ot, of, 0, 0, 1, 1, 1, 1, 1, 0);
746
747 of = e_widget_framelist_add(evas, _("Font Fallbacks"), 0);
748 ob = e_widget_config_list_add(evas, e_widget_entry_add, _("Fallback Name"), 2);
749 cfdata->gui.fallback_list = ob;
750 option_enable = 0;
751 EINA_LIST_FOREACH(e_font_fallback_list(), next, eff)
752 {
753 e_widget_config_list_append(ob, eff->name);
754 option_enable = 1;
755 }
756 ob = e_widget_check_add(evas, _("Enable Fallbacks"), &(cfdata->cur_fallbacks_enabled));
757 e_widget_config_list_object_append(cfdata->gui.fallback_list, ob,
758 0, 0, 2, 1, 1, 0, 1, 0);
759 e_widget_on_change_hook_set(ob, _adv_enabled_fallback_cb_change, cfdata);
760 e_widget_check_checked_set(ob, option_enable);
761 e_widget_change(ob);
762 e_widget_framelist_object_append(of, cfdata->gui.fallback_list);
763 e_widget_table_object_append(ot, of, 1, 0, 1, 1, 1, 1, 1, 0);
764
765 e_widget_toolbook_page_append(otb, NULL, _("Hinting / Fallbacks"),
766 ot, 1, 0, 1, 0, 0.5, 0.0);
767
768 e_widget_toolbook_page_show(otb, 0);
769 return otb;
770 }
771
772 /* Private Font Class Functions */
773 static void
_class_list_load(E_Config_Dialog_Data * cfdata)774 _class_list_load(E_Config_Dialog_Data *cfdata)
775 {
776 Evas *evas;
777 Eina_List *next;
778
779 if (!cfdata->gui.class_list) return;
780 evas = evas_object_evas_get(cfdata->gui.class_list);
781 evas_event_freeze(evas);
782 edje_freeze();
783 e_widget_ilist_freeze(cfdata->gui.class_list);
784 e_widget_ilist_clear(cfdata->gui.class_list);
785
786 /* Fill in Class Ilist */
787 for (next = cfdata->text_classes; next; next = next->next)
788 {
789 CFText_Class *tc;
790 Evas_Object *ic;
791
792 tc = next->data;
793 if (tc)
794 {
795 if (tc->class_name)
796 {
797 if (tc->enabled)
798 {
799 ic = e_icon_add(evas);
800 e_util_icon_theme_set(ic, "dialog-ok-apply");
801 }
802 else
803 ic = NULL;
804 e_widget_ilist_append(cfdata->gui.class_list, ic, tc->class_description, NULL, tc, NULL);
805 }
806 else
807 e_widget_ilist_header_append(cfdata->gui.class_list, NULL, tc->class_description);
808 }
809 }
810 e_widget_ilist_go(cfdata->gui.class_list);
811 e_widget_ilist_thaw(cfdata->gui.class_list);
812 edje_thaw();
813 evas_event_thaw(evas);
814 }
815
816 /* Called whenever class list selection changes */
817 static void
_adv_class_cb_change(void * data,Evas_Object * obj EINA_UNUSED)818 _adv_class_cb_change(void *data, Evas_Object *obj EINA_UNUSED)
819 {
820 int indx;
821 E_Config_Dialog_Data *cfdata;
822 CFText_Class *tc;
823
824 if (!(cfdata = data)) return;
825
826 /* Save Current */
827 if (cfdata->cur_class)
828 {
829 tc = cfdata->cur_class;
830 tc->size = cfdata->cur_size;
831
832 eina_stringshare_replace(&tc->font, cfdata->cur_font);
833 eina_stringshare_replace(&tc->style, cfdata->cur_style);
834
835 if (cfdata->gui.style_list)
836 e_widget_ilist_unselect(cfdata->gui.style_list);
837 if (cfdata->gui.size_list)
838 e_widget_ilist_unselect(cfdata->gui.size_list);
839 if (cfdata->gui.font_list)
840 e_widget_ilist_unselect(cfdata->gui.font_list);
841 }
842
843 /* If no class is selected unselect all and return */
844 indx = e_widget_ilist_selected_get(cfdata->gui.class_list);
845 if (indx < 0)
846 {
847 e_widget_disabled_set(cfdata->gui.enabled, 1);
848 e_widget_disabled_set(cfdata->gui.font_list, 1);
849 e_widget_disabled_set(cfdata->gui.size_list, 1);
850 e_widget_check_checked_set(cfdata->gui.enabled, 0);
851 if (cfdata->gui.font_list)
852 e_widget_ilist_unselect(cfdata->gui.font_list);
853 return;
854 }
855 tc = e_widget_ilist_selected_data_get(cfdata->gui.class_list);
856 if (!tc) return;
857 e_widget_check_valptr_set(cfdata->gui.enabled, &tc->enabled);
858
859 cfdata->cur_class = tc;
860
861 e_widget_disabled_set(cfdata->gui.enabled, 0);
862 e_widget_disabled_set(cfdata->gui.font_list, !tc->enabled);
863 e_widget_disabled_set(cfdata->gui.size_list, !tc->enabled);
864 if (!tc->enabled) return;
865 if (!cfdata->gui.font_list) return;
866
867 {
868 E_Ilist_Item *ili;
869 const Eina_List *l;
870 unsigned int sel = 0;
871
872 /* Select the configured font */
873 EINA_LIST_FOREACH(e_widget_ilist_items_get(cfdata->gui.font_list), l, ili)
874 {
875 const char *f;
876
877 f = ili->label;
878 if (tc->font && !strcasecmp(f, tc->font))
879 {
880 e_widget_ilist_selected_set(cfdata->gui.font_list, sel);
881 break;
882 }
883 sel++;
884 }
885 }
886 }
887
888 static void
_adv_enabled_font_cb_change(void * data,Evas_Object * obj EINA_UNUSED)889 _adv_enabled_font_cb_change(void *data, Evas_Object *obj EINA_UNUSED)
890 {
891 E_Config_Dialog_Data *cfdata;
892 CFText_Class *tc;
893
894 if (!(cfdata = data)) return;
895 tc = e_widget_ilist_selected_data_get(cfdata->gui.class_list);
896 if ((!tc) || (!tc->enabled))
897 {
898 e_widget_disabled_set(cfdata->gui.font_list, 1);
899 e_widget_ilist_unselect(cfdata->gui.font_list);
900 e_widget_disabled_set(cfdata->gui.style_list, 1);
901 e_widget_ilist_unselect(cfdata->gui.font_list);
902 e_widget_disabled_set(cfdata->gui.size_list, 1);
903 e_widget_ilist_unselect(cfdata->gui.font_list);
904 if (tc)
905 e_widget_ilist_nth_icon_set(cfdata->gui.class_list, e_widget_ilist_selected_get(cfdata->gui.class_list), NULL);
906 return;
907 }
908
909 e_widget_disabled_set(cfdata->gui.font_list, 0);
910 e_widget_disabled_set(cfdata->gui.style_list, 0);
911 e_widget_disabled_set(cfdata->gui.size_list, 0);
912 /* Search class list fot selected and enable Icon */
913 {
914 Evas_Object *icon = NULL;
915
916 tc->size = cfdata->cur_size;
917 eina_stringshare_replace(&tc->font, cfdata->cur_font);
918 if (tc->enabled)
919 {
920 icon = e_icon_add(cfdata->evas);
921 e_util_icon_theme_set(icon, "enlightenment");
922 }
923
924 e_widget_ilist_nth_icon_set(cfdata->gui.class_list, e_widget_ilist_selected_get(cfdata->gui.class_list), icon);
925 }
926 }
927
928 static void
_size_cb_change(void * data)929 _size_cb_change(void *data)
930 {
931 E_Config_Dialog_Data *cfdata;
932 E_Font_Size_Data *size_data;
933 const Eina_List *l;
934 int n;
935
936 size_data = data;
937 if (!(cfdata = size_data->cfdata)) return;
938
939 cfdata->cur_size = size_data->size;
940
941 _font_preview_update(cfdata);
942
943 if (!cfdata->gui.class_list) return;
944
945 for (n = 0, l = e_widget_ilist_items_get(cfdata->gui.class_list); l; l = l->next, n++)
946 {
947 E_Ilist_Item *i;
948 CFText_Class *tc;
949
950 if (!(i = l->data)) continue;
951 if (!i->selected) continue;
952
953 tc = eina_list_nth(cfdata->text_classes, n);
954 tc->size = cfdata->cur_size;
955 }
956 }
957
958 static void
_adv_font_cb_change(void * data,Evas_Object * obj EINA_UNUSED)959 _adv_font_cb_change(void *data, Evas_Object *obj EINA_UNUSED)
960 {
961 E_Config_Dialog_Data *cfdata;
962 CFText_Class *tc;
963 int n;
964
965 if (!(cfdata = data)) return;
966
967 /* Set up the new font name for each selected class */
968 tc = e_widget_ilist_selected_data_get(cfdata->gui.class_list);
969 if (tc)
970 eina_stringshare_replace(&tc->font, cfdata->cur_font);
971
972 /* Load the style list */
973 if (cfdata->cur_font)
974 {
975 E_Font_Properties *efp;
976 Eina_List *next;
977
978 efp = eina_hash_find(cfdata->font_hash, cfdata->cur_font);
979 evas_event_freeze(evas_object_evas_get(cfdata->gui.style_list));
980 edje_freeze();
981 e_widget_ilist_freeze(cfdata->gui.style_list);
982 e_widget_ilist_clear(cfdata->gui.style_list);
983
984 for (next = efp->styles; next; next = next->next)
985 {
986 const char *style;
987
988 style = next->data;
989 e_widget_ilist_append(cfdata->gui.style_list, NULL, style,
990 NULL, NULL, style);
991 }
992
993 e_widget_ilist_go(cfdata->gui.style_list);
994 e_widget_ilist_thaw(cfdata->gui.style_list);
995 edje_thaw();
996 evas_event_thaw(evas_object_evas_get(cfdata->gui.style_list));
997 }
998
999 /* select configured style from list */
1000 if ((tc) && (tc->style))
1001 {
1002 for (n = 0; n < e_widget_ilist_count(cfdata->gui.style_list); n++)
1003 {
1004 const char *f;
1005
1006 f = e_widget_ilist_nth_label_get(cfdata->gui.style_list, n);
1007 if ((!f) || (!tc->style)) continue;
1008 if (!strcasecmp(f, tc->style))
1009 {
1010 e_widget_ilist_selected_set(cfdata->gui.style_list, n);
1011 break;
1012 }
1013 }
1014 }
1015
1016 /* load and select size list */
1017 if (tc)
1018 {
1019 cfdata->cur_size = tc->size;
1020 _size_list_load(cfdata, cfdata->font_scale_list, tc->size, 1);
1021 _size_list_load(cfdata, cfdata->font_px_list, tc->size, 0);
1022 }
1023
1024 _font_preview_update(cfdata);
1025 }
1026
1027 static void
_size_list_load(E_Config_Dialog_Data * cfdata,Eina_List * size_list,Evas_Font_Size cur_size,int clear)1028 _size_list_load(E_Config_Dialog_Data *cfdata, Eina_List *size_list, Evas_Font_Size cur_size, int clear)
1029 {
1030 Eina_List *next;
1031 Evas_Object *ob;
1032 Evas *evas;
1033
1034 ob = cfdata->gui.size_list;
1035 evas = evas_object_evas_get(ob);
1036
1037 evas_event_freeze(evas);
1038 edje_freeze();
1039 e_widget_ilist_freeze(ob);
1040 if (clear) e_widget_ilist_clear(ob);
1041
1042 for (next = size_list; next; next = next->next)
1043 {
1044 E_Font_Size_Data *size_data;
1045
1046 size_data = next->data;
1047 e_widget_ilist_append(ob, NULL, size_data->size_str, _size_cb_change,
1048 size_data, NULL);
1049 }
1050
1051 e_widget_ilist_go(ob);
1052 e_widget_ilist_thaw(ob);
1053 edje_thaw();
1054 evas_event_thaw(evas);
1055
1056 _basic_size_list_select(ob, cur_size);
1057 }
1058
1059 static void
_font_list_load(E_Config_Dialog_Data * cfdata,const char * cur_font)1060 _font_list_load(E_Config_Dialog_Data *cfdata, const char *cur_font)
1061 {
1062 const char *f;
1063 Eina_List *next;
1064 Evas_Object *ob;
1065 Evas *evas;
1066 Evas_Coord w;
1067
1068 ob = cfdata->gui.font_list;
1069 evas = evas_object_evas_get(ob);
1070
1071 evas_event_freeze(evas);
1072 edje_freeze();
1073 e_widget_ilist_freeze(ob);
1074
1075 /* Load Hash a single time */
1076 if (!cfdata->font_hash)
1077 {
1078 Eina_List *fonts;
1079
1080 fonts = evas_font_available_list(evas);
1081 cfdata->font_hash = e_font_available_list_parse(fonts);
1082 eina_hash_foreach(cfdata->font_hash, _font_hash_cb, cfdata);
1083 if (cfdata->font_list)
1084 {
1085 cfdata->font_list =
1086 eina_list_sort(cfdata->font_list,
1087 eina_list_count(cfdata->font_list),
1088 _sort_fonts);
1089 }
1090 evas_font_available_list_free(evas, fonts);
1091 }
1092
1093 /* Load the list */
1094 if (cfdata->font_list)
1095 {
1096 EINA_LIST_FOREACH(cfdata->font_list, next, f)
1097 {
1098 e_widget_ilist_append(ob, NULL, f, NULL, NULL, f);
1099 }
1100 }
1101
1102 e_widget_ilist_go(ob);
1103 e_widget_size_min_get(ob, &w, NULL);
1104 e_widget_size_min_set(ob, w, 250);
1105 e_widget_ilist_thaw(ob);
1106 edje_thaw();
1107 evas_event_thaw(evas);
1108
1109 if (cur_font) _basic_font_list_select(cfdata, cur_font);
1110 }
1111
1112 static void
_adv_style_cb_change(void * data,Evas_Object * obj EINA_UNUSED)1113 _adv_style_cb_change(void *data, Evas_Object *obj EINA_UNUSED)
1114 {
1115 E_Config_Dialog_Data *cfdata;
1116 E_Ilist_Item *i;
1117 const Eina_List *l;
1118 int n = 0;
1119
1120 if (!(cfdata = data)) return;
1121
1122 /* Setup the new style name */
1123 EINA_LIST_FOREACH(e_widget_ilist_items_get(cfdata->gui.class_list), l, i)
1124 {
1125 CFText_Class *tc;
1126 const char *tmp;
1127
1128 if (!i->selected) continue;
1129
1130 tc = eina_list_nth(cfdata->text_classes, n);
1131 tmp = eina_stringshare_ref(cfdata->cur_style);
1132 eina_stringshare_del(tc->style);
1133 tc->style = tmp;
1134 n++;
1135 }
1136
1137 _font_preview_update(cfdata);
1138 }
1139
1140 /* Private Font Fallback Functions */
1141 static void
_adv_enabled_fallback_cb_change(void * data,Evas_Object * obj EINA_UNUSED)1142 _adv_enabled_fallback_cb_change(void *data, Evas_Object *obj EINA_UNUSED)
1143 {
1144 E_Config_Dialog_Data *cfdata;
1145
1146 if (!(cfdata = data)) return;
1147 e_widget_disabled_set(cfdata->gui.fallback_list,
1148 !cfdata->cur_fallbacks_enabled);
1149 }
1150
1151 static int
_sort_fonts(const void * data1,const void * data2)1152 _sort_fonts(const void *data1, const void *data2)
1153 {
1154 if (!data1) return 1;
1155 if (!data2) return -1;
1156 return e_util_strcmp(data1, data2);
1157 }
1158
1159 static void
_font_preview_update(E_Config_Dialog_Data * cfdata)1160 _font_preview_update(E_Config_Dialog_Data *cfdata)
1161 {
1162 /* update preview */
1163 if (cfdata->cur_font)
1164 {
1165 const char *name;
1166
1167 name = e_font_fontconfig_name_get(cfdata->cur_font, cfdata->cur_style);
1168 e_widget_font_preview_font_set(cfdata->gui.preview, name,
1169 cfdata->cur_size);
1170 eina_stringshare_del(name);
1171 }
1172 }
1173
1174