1 /*$
2 Copyright (C) 2013-2020 Azel.
3
4 This file is part of AzPainter.
5
6 AzPainter is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 AzPainter is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 $*/
19
20 /*****************************************
21 * mFontDialog
22 *****************************************/
23
24 #include <string.h>
25
26 #include "mDef.h"
27
28 #include "mWidget.h"
29 #include "mContainer.h"
30 #include "mWindow.h"
31 #include "mDialog.h"
32 #include "mLabel.h"
33 #include "mButton.h"
34 #include "mComboBox.h"
35 #include "mLineEdit.h"
36 #include "mListView.h"
37
38 #include "mStr.h"
39 #include "mFont.h"
40 #include "mTrans.h"
41 #include "mEvent.h"
42 #include "mEnumFont.h"
43 #include "mUtilStr.h"
44
45
46 //----------------------
47
48 typedef struct _mFontDialog
49 {
50 mWidget wg;
51 mContainerData ct;
52 mWindowData win;
53 mDialogData dlg;
54 //
55
56 mFontInfo *info;
57 uint32_t mask; //取得する項目
58
59 mListView *lvfont,
60 *lvstyle;
61 mLineEdit *editsize;
62 mComboBox *cbstyle,
63 *cbweight,
64 *cbslant,
65 *cbrender;
66 }mFontDialog;
67
68 //----------------------
69
70 enum
71 {
72 WID_LIST = 100,
73 WID_BTT_PREV,
74 };
75
76 static int _event_handle(mWidget *wg,mEvent *ev);
77
78 //----------------------
79
80
81 //******************************
82 // プレビュー
83 //******************************
84
85
86 /** プレビューダイアログ実行 */
87
_run_previewdlg(mWindow * owner,mFontInfo * info)88 static void _run_previewdlg(mWindow *owner,mFontInfo *info)
89 {
90 mDialog *p;
91 mLineEdit *edit;
92 mButton *btt;
93 mFont *font;
94
95 //------- 作成
96
97 p = (mDialog *)mDialogNew(0, owner, MWINDOW_S_DIALOG_NORMAL);
98 if(!p) return;
99
100 p->wg.event = mDialogEventHandle_okcancel;
101
102 M_TR_G(M_TRGROUP_SYS);
103
104 mWindowSetTitle(M_WINDOW(p), M_TR_T(M_TRSYS_PREVIEW));
105
106 mContainerSetPadding_one(M_CONTAINER(p), 8);
107
108 p->ct.sepW = 12;
109
110 //フォント
111
112 font = mFontCreate(info);
113
114 //エディット
115
116 edit = mLineEditCreate(M_WIDGET(p), 0, 0, MLF_EXPAND_W, 0);
117
118 edit->wg.initW = 300;
119 edit->wg.font = font;
120
121 mLineEditSetText(edit, M_TR_T(M_TRSYS_FONTPREVIEWTEXT));
122
123 //OK
124
125 btt = mButtonCreate(M_WIDGET(p), M_WID_OK, 0, MLF_RIGHT, 0, M_TR_T(M_TRSYS_OK));
126
127 btt->wg.fState |= MWIDGET_STATE_ENTER_DEFAULT;
128
129 //------ 実行
130
131 mWindowMoveResizeShow_hintSize(M_WINDOW(p));
132
133 mDialogRun(p, FALSE);
134
135 mFontFree(font);
136
137 mWidgetDestroy(M_WIDGET(p));
138 }
139
140
141 //******************************
142 // mFontDialog
143 //******************************
144
145
146 /** フォントリストセット */
147
_set_fontlist(mFontDialog * p)148 static void _set_fontlist(mFontDialog *p)
149 {
150 char **buf,**pp;
151 mListViewItem *pi,*focus = NULL;
152 mStr *strdef = &p->info->strFamily;
153
154 //デフォルト
155
156 pi = mListViewAddItem_textparam(p->lvfont, "(default)", -1);
157
158 if(!(p->info->mask & MFONTINFO_MASK_FAMILY) || mStrIsEmpty(strdef))
159 focus = pi;
160
161 //リスト
162
163 buf = mEnumFontFamily();
164 if(!buf) return;
165
166 for(pp = buf; *pp; pp++)
167 {
168 pi = mListViewAddItem_textparam(p->lvfont, *pp, 0);
169
170 if(!focus && mStrCompareEq(strdef, *pp))
171 focus = pi;
172 }
173
174 mFreeStrsBuf(buf);
175
176 //幅
177
178 mListViewSetWidthAuto(p->lvfont, TRUE);
179
180 //フォーカス
181
182 if(focus)
183 {
184 mListViewSetFocusItem(p->lvfont, focus);
185 mListViewScrollToItem(p->lvfont, focus, 0);
186 }
187 }
188
189 /** スタイルリストセット */
190
_set_stylelist(mFontDialog * p,mBool bInit)191 static void _set_stylelist(mFontDialog *p,mBool bInit)
192 {
193 mListViewItem *pi,*focus = NULL;
194 char **buf,**pp;
195 mStr *strdef = &p->info->strStyle;
196
197 if(!p->lvstyle) return;
198
199 //クリア
200
201 mListViewDeleteAllItem(p->lvstyle);
202
203 //指定なし
204
205 mListViewAddItem_textparam(p->lvstyle, "----", -1);
206
207 //現在の選択フォントのスタイル
208
209 pi = mListViewGetFocusItem(p->lvfont);
210
211 if(pi && pi->param == 0)
212 {
213 buf = mEnumFontStyle(pi->text);
214
215 if(buf)
216 {
217 for(pp = buf; *pp; pp++)
218 {
219 pi = mListViewAddItem_textparam(p->lvstyle, *pp, 0);
220
221 if(bInit && !focus && mStrCompareEq(strdef, *pp))
222 focus = pi;
223 }
224 }
225
226 mFreeStrsBuf(buf);
227 }
228
229 //選択 (初期表示時のみ、指定スタイルにセット)
230
231 mListViewSetFocusItem(p->lvstyle,
232 (bInit && focus)? focus: mListViewGetTopItem(p->lvstyle));
233 }
234
235 /** ウィジェット作成 */
236
_create_widget(mFontDialog * p)237 static void _create_widget(mFontDialog *p)
238 {
239 mWidget *cth,*ct;
240 uint32_t mask = p->mask;
241
242 //水平コンテナ
243
244 cth = mContainerCreate(M_WIDGET(p), MCONTAINER_TYPE_HORZ, 0, 10, MLF_EXPAND_WH);
245
246 //---- リスト・プレビュー
247
248 ct = mContainerCreate(cth, MCONTAINER_TYPE_VERT, 0, 6, MLF_EXPAND_H);
249
250 //リスト
251
252 p->lvfont = mListViewNew(0, ct,
253 0, MSCROLLVIEW_S_VERT | MSCROLLVIEW_S_FRAME);
254
255 p->lvfont->wg.id = WID_LIST;
256 p->lvfont->wg.fLayout = MLF_EXPAND_H;
257 p->lvfont->wg.initH = 300;
258
259 _set_fontlist(p);
260
261 //プレビュー
262
263 mButtonCreate(ct, WID_BTT_PREV, 0, MLF_EXPAND_W, 0, M_TR_T(M_TRSYS_PREVIEW));
264
265 //------ 各項目
266
267 ct = mContainerCreate(cth, MCONTAINER_TYPE_GRID, 2, 0, MLF_EXPAND_WH);
268
269 M_CONTAINER(ct)->ct.gridSepCol = 5;
270 M_CONTAINER(ct)->ct.gridSepRow = 6;
271
272 //スタイル
273
274 if(mask & MFONTINFO_MASK_STYLE)
275 {
276 mLabelCreate(ct, 0, MLF_RIGHT, 0, M_TR_T(M_TRSYS_FONTSTYLE));
277
278 p->lvstyle = mListViewNew(0, ct,
279 0, MSCROLLVIEW_S_VERT | MSCROLLVIEW_S_FRAME);
280
281 p->lvstyle->wg.fLayout = MLF_EXPAND_WH;
282 p->lvstyle->wg.initW = 180;
283
284 _set_stylelist(p, TRUE);
285 }
286
287 //サイズ
288
289 if(mask & MFONTINFO_MASK_SIZE)
290 {
291 mLabelCreate(ct, 0, MLF_RIGHT | MLF_MIDDLE, 0, M_TR_T(M_TRSYS_FONTSIZE));
292
293 p->editsize = mLineEditCreate(ct, 0, 0, MLF_EXPAND_W|MLF_MIDDLE, 0);
294
295 p->editsize->wg.initW = 180;
296
297 mLineEditSetDouble(p->editsize,
298 (p->info->mask & MFONTINFO_MASK_SIZE)? p->info->size: 10, 1);
299 }
300
301 //太さ
302
303 if(mask & MFONTINFO_MASK_WEIGHT)
304 {
305 mLabelCreate(ct, 0, MLF_RIGHT | MLF_MIDDLE, 0, M_TR_T(M_TRSYS_FONTWEIGHT));
306
307 p->cbweight = mComboBoxCreate(ct, 0, 0, MLF_EXPAND_W|MLF_MIDDLE, 0);
308
309 mComboBoxAddItem(p->cbweight, "----", -1);
310 mComboBoxAddItem(p->cbweight, "Normal", MFONTINFO_WEIGHT_NORMAL);
311 mComboBoxAddItem(p->cbweight, "Bold", MFONTINFO_WEIGHT_BOLD);
312
313 mComboBoxSetWidthAuto(p->cbweight);
314
315 if(p->info->mask & MFONTINFO_MASK_WEIGHT)
316 mComboBoxSetSel_findParam_notfind(p->cbweight, p->info->weight, 0);
317 else
318 mComboBoxSetSel_index(p->cbweight, 0);
319 }
320
321 //傾き
322
323 if(mask & MFONTINFO_MASK_SLANT)
324 {
325 mLabelCreate(ct, 0, MLF_RIGHT | MLF_MIDDLE, 0, M_TR_T(M_TRSYS_FONTSLANT));
326
327 p->cbslant = mComboBoxCreate(ct, 0, 0, MLF_EXPAND_W|MLF_MIDDLE, 0);
328
329 mComboBoxAddItem(p->cbslant, "----", -1);
330 mComboBoxAddItem(p->cbslant, "Roman", MFONTINFO_SLANT_ROMAN);
331 mComboBoxAddItem(p->cbslant, "Italic", MFONTINFO_SLANT_ITALIC);
332 mComboBoxAddItem(p->cbslant, "Oblique", MFONTINFO_SLANT_OBLIQUE);
333
334 mComboBoxSetWidthAuto(p->cbslant);
335
336 if(p->info->mask & MFONTINFO_MASK_SLANT)
337 mComboBoxSetSel_findParam_notfind(p->cbslant, p->info->slant, 0);
338 else
339 mComboBoxSetSel_index(p->cbslant, 0);
340 }
341
342 //レンダリング
343
344 if(mask & MFONTINFO_MASK_RENDER)
345 {
346 mLabelCreate(ct, 0, MLF_RIGHT | MLF_MIDDLE, 0, M_TR_T(M_TRSYS_FONTRENDER));
347
348 p->cbrender = mComboBoxCreate(ct, 0, 0, MLF_EXPAND_W|MLF_MIDDLE, 0);
349
350 mComboBoxAddItems(p->cbrender,
351 "Default\tMono\tGray\tLCD (RGB)\tLCD (BGR)\tLCD (V RGB)\tLCD (V BGR)",
352 0);
353
354 mComboBoxSetWidthAuto(p->cbrender);
355
356 mComboBoxSetSel_index(p->cbrender,
357 (p->info->mask & MFONTINFO_MASK_RENDER)? p->info->render: 0);
358 }
359 }
360
361 /** 各値を取得 */
362
_get_param(mFontDialog * p,mFontInfo * pd)363 static void _get_param(mFontDialog *p,mFontInfo *pd)
364 {
365 mListViewItem *pi;
366 uint32_t mask = 0;
367
368 //ファミリ名
369
370 pi = mListViewGetFocusItem(p->lvfont);
371
372 if(pi)
373 {
374 if(pi->param == 0)
375 {
376 //選択された名前
377 mask |= MFONTINFO_MASK_FAMILY;
378 mStrSetText(&pd->strFamily, pi->text);
379 }
380 else
381 {
382 //default の場合はファミリ名なし
383 mStrEmpty(&pd->strFamily);
384 }
385 }
386 else if(!mStrIsEmpty(&pd->strFamily))
387 //選択なしの場合は、元の名前が空でなければそのままに
388 mask |= MFONTINFO_MASK_FAMILY;
389
390 //スタイル
391
392 if(p->lvstyle)
393 {
394 pi = mListViewGetFocusItem(p->lvstyle);
395
396 if(pi && pi->param == 0)
397 {
398 mask |= MFONTINFO_MASK_STYLE;
399 mStrSetText(&pd->strStyle, pi->text);
400 }
401 }
402
403 //サイズ
404
405 if(p->editsize)
406 {
407 mask |= MFONTINFO_MASK_SIZE;
408 pd->size = mLineEditGetDouble(p->editsize);
409 }
410
411 //太さ
412
413 if(p->cbweight)
414 {
415 pi = mComboBoxGetSelItem(p->cbweight);
416
417 if(pi && pi->param != -1)
418 {
419 mask |= MFONTINFO_MASK_WEIGHT;
420 pd->weight = pi->param;
421 }
422 }
423
424 //傾き
425
426 if(p->cbslant)
427 {
428 pi = mComboBoxGetSelItem(p->cbslant);
429
430 if(pi && pi->param != -1)
431 {
432 mask |= MFONTINFO_MASK_SLANT;
433 pd->slant = pi->param;
434 }
435 }
436
437 //レンダリング
438
439 if(p->cbrender)
440 {
441 pi = mComboBoxGetSelItem(p->cbrender);
442 if(pi)
443 {
444 mask |= MFONTINFO_MASK_RENDER;
445 pd->render = pi->param;
446 }
447 }
448
449 //マスク
450
451 pd->mask = mask;
452 }
453
454
455 //====================
456
457
458 /** 作成 */
459
mFontDialogNew(mWindow * owner,mFontInfo * info,uint32_t mask)460 mFontDialog *mFontDialogNew(mWindow *owner,mFontInfo *info,uint32_t mask)
461 {
462 mFontDialog *p;
463
464 p = (mFontDialog *)mDialogNew(sizeof(mFontDialog), owner, MWINDOW_S_DIALOG_NORMAL);
465 if(!p) return NULL;
466
467 p->wg.event = _event_handle;
468
469 p->info = info;
470 p->mask = mask;
471
472 //
473
474 M_TR_G(M_TRGROUP_SYS);
475
476 mWindowSetTitle(M_WINDOW(p), M_TR_T(M_TRSYS_TITLE_SELECTFONT));
477
478 //
479
480 mContainerSetPadding_one(M_CONTAINER(p), 8);
481 p->ct.sepW = 15;
482
483 //ウィジェット
484
485 _create_widget(p);
486
487 //OK/Cancel
488
489 mContainerCreateOkCancelButton(M_WIDGET(p));
490
491 return p;
492 }
493
494 /** プレビュー実行 */
495
_run_preview(mFontDialog * p)496 static void _run_preview(mFontDialog *p)
497 {
498 mFontInfo info;
499
500 memset(&info, 0, sizeof(mFontInfo));
501
502 _get_param(p, &info);
503
504 _run_previewdlg(M_WINDOW(p), &info);
505
506 mFontInfoFree(&info);
507 }
508
509 /** イベントハンドラ */
510
_event_handle(mWidget * wg,mEvent * ev)511 int _event_handle(mWidget *wg,mEvent *ev)
512 {
513 mFontDialog *p = (mFontDialog *)wg;
514
515 if(ev->type == MEVENT_NOTIFY)
516 {
517 switch(ev->notify.widgetFrom->id)
518 {
519 //フォントリスト
520 case WID_LIST:
521 if(ev->notify.type == MLISTVIEW_N_CHANGE_FOCUS)
522 _set_stylelist(p, FALSE);
523 break;
524 //プレビュー
525 case WID_BTT_PREV:
526 _run_preview(p);
527 break;
528
529 //OK
530 case M_WID_OK:
531 _get_param(p, p->info);
532
533 mDialogEnd(M_DIALOG(wg), TRUE);
534 break;
535 case M_WID_CANCEL:
536 mDialogEnd(M_DIALOG(wg), FALSE);
537 break;
538 }
539
540 return 1;
541 }
542 else
543 return mDialogEventHandle(wg, ev);
544 }
545
546
547
548 //*******************************
549 // 関数
550 //*******************************
551
552
553 /** フォント選択
554 *
555 * @param mask MFONTINFO_MASK_*。設定を取得したい項目。
556 * @ingroup sysdialog */
557
mSysDlgSelectFont(mWindow * owner,mFontInfo * info,uint32_t mask)558 mBool mSysDlgSelectFont(mWindow *owner,mFontInfo *info,uint32_t mask)
559 {
560 mFontDialog *p;
561
562 p = mFontDialogNew(owner, info, mask);
563 if(!p) return FALSE;
564
565 mWindowMoveResizeShow_hintSize(M_WINDOW(p));
566
567 return mDialogRun(M_DIALOG(p), TRUE);
568 }
569
570 /** フォント選択 (文字列フォーマットで)
571 *
572 * @param mask MFONTINFO_MASK_*。設定を取得したい項目。
573 * @ingroup sysdialog */
574
mSysDlgSelectFont_format(mWindow * owner,mStr * strformat,uint32_t mask)575 mBool mSysDlgSelectFont_format(mWindow *owner,mStr *strformat,uint32_t mask)
576 {
577 mFontDialog *p;
578 mFontInfo info;
579 mBool ret = FALSE;
580
581 //mFontInfo
582
583 mMemzero(&info, sizeof(mFontInfo));
584
585 mFontFormatToInfo(&info, strformat->buf);
586
587 //ダイアログ
588
589 p = mFontDialogNew(owner, &info, mask);
590
591 if(p)
592 {
593 mWindowMoveResizeShow_hintSize(M_WINDOW(p));
594
595 ret = mDialogRun(M_DIALOG(p), TRUE);
596
597 if(ret)
598 mFontInfoToFormat(strformat, &info);
599 }
600
601 mFontInfoFree(&info);
602
603 return ret;
604 }
605
606