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