1 /*$
2 Copyright (C) 2016-2020 Azel.
3
4 This file is part of AzPainterB.
5
6 AzPainterB 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 AzPainterB 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 * グラデーション編集ダイアログ
22 ********************************/
23
24 #include "mDef.h"
25 #include "mWidget.h"
26 #include "mDialog.h"
27 #include "mContainer.h"
28 #include "mWindow.h"
29 #include "mWidgetBuilder.h"
30 #include "mCheckButton.h"
31 #include "mColorButton.h"
32 #include "mArrowButton.h"
33 #include "mLineEdit.h"
34 #include "mSliderBar.h"
35 #include "mMenu.h"
36 #include "mTrans.h"
37 #include "mEvent.h"
38 #include "mUtilStr.h"
39
40 #include "GradationList.h"
41 #include "GradationEditWidget.h"
42
43 #include "trgroup.h"
44
45
46 //--------------------
47
48 typedef struct
49 {
50 mWidget wg;
51 mContainerData ct;
52 mWindowData win;
53 mDialogData dlg;
54
55 GradItem *item;
56
57 GradEditWidget *editwg[2];
58 mLineEdit *ledit_pos[2],
59 *ledit_opa;
60 mSliderBar *sl_opa;
61 mArrowButton *menubtt[2];
62 mColorButton *colbt;
63 mCheckButton *ck_coltype,
64 *ck_flag[2];
65 }_edit_dlg;
66
67 //--------------------
68
69 static const char *g_wb_gradeditdlg =
70 //色
71 "gb:cts=h:lf=w:tr=1:sep=5;"
72 "lb:lf=m:tr=2;"
73 "le#cs:id=100:wlen=7;"
74 "colbt#d:id=105:lf=m;"
75 "ck#r:id=102:tr=3:lf=m;"
76 "ck#r:id=103:tr=4:lf=m;"
77 "ck#r:id=104:tr=5:lf=m;"
78 "-;"
79 //不透明度
80 "gb:cts=h:lf=w:tr=6:sep=5:mg=0,8,0,10;"
81 "lb:tr=2:lf=m;"
82 "le#cs:id=101:wlen=7;"
83 "lb:tr=7:lf=m;"
84 "sl:id=106:lf=wm:range=0,255;"
85 "le#cs:id=107:wlen=4:range=0,255;"
86 "-;"
87 //チェック
88 "ct#h:sep=4:mg=b10;"
89 "ck:id=108:tr=8;"
90 "ck:id=109:tr=9;"
91 "-;"
92 //ヘルプ
93 "lb#B:tr=10:lf=w:mg=b12;"
94 ;
95
96 //--------------------
97
98 enum
99 {
100 WID_EDIT_COL_POS = 100,
101 WID_EDIT_A_POS,
102 WID_CK_COL_SPEC,
103 WID_CK_COL_DRAW,
104 WID_CK_COL_BKGND,
105 WID_COLBTT,
106 WID_SLIDER_A,
107 WID_EDIT_A_VAL,
108 WID_CK_LOOP,
109 WID_CK_SINGLE_COL,
110
111 WID_EDITWG_COL = 200,
112 WID_EDITWG_A,
113 WID_BTT_COL_MOVELEFT,
114 WID_BTT_A_MOVELEFT,
115 WID_BTT_COL_MOVERIGHT,
116 WID_BTT_A_MOVERIGHT,
117 WID_MENUBTT_COL,
118 WID_MENUBTT_A
119 };
120
121 enum
122 {
123 TRID_MENU_DELETE = 100,
124 TRID_MENU_DIVIDE,
125 TRID_MENU_MOVE_CENTER,
126 TRID_MENU_ALL_EVEN,
127 TRID_MENU_REVERSE
128 };
129
130 //--------------------
131
132
133
134 //==========================
135 // sub
136 //==========================
137
138
139 /** GradEditWidget の更新 */
140
_update_editwg(_edit_dlg * p,int no)141 static void _update_editwg(_edit_dlg *p,int no)
142 {
143 mWidgetUpdate(M_WIDGET(p->editwg[no]));
144 }
145
146 /** カレントポイントの情報セット */
147
_set_curinfo(_edit_dlg * p,int no)148 static void _set_curinfo(_edit_dlg *p,int no)
149 {
150 int n;
151 uint32_t col;
152
153 //位置
154
155 mLineEditSetNum(p->ledit_pos[no],
156 (int)((double)GradEditWidget_getCurrentPos(p->editwg[no]) / (1 << GRADDAT_POS_BIT) * 1000+ 0.5));
157
158 //値
159
160 if(no == 0)
161 {
162 //RGB
163
164 n = GradEditWidget_getCurrentColor(p->editwg[no], &col);
165
166 mCheckButtonSetRadioSel(p->ck_coltype, n);
167
168 mColorButtonSetColor(p->colbt, col);
169 mWidgetEnable(M_WIDGET(p->colbt), (n == 0));
170 }
171 else
172 {
173 //A
174
175 n = GradEditWidget_getCurrentOpacity(p->editwg[no]);
176
177 mSliderBarSetPos(p->sl_opa, n);
178 mLineEditSetNum(p->ledit_opa, n);
179 }
180 }
181
182 /** メニュー実行 */
183
_run_menu(_edit_dlg * p,int no)184 static void _run_menu(_edit_dlg *p,int no)
185 {
186 GradEditWidget *editwg;
187 mMenu *menu,*sub;
188 mMenuItemInfo *mi;
189 int i,n;
190 char m[4];
191 mBox box;
192 uint16_t id[] = {
193 TRID_MENU_DELETE, 0xfffe, TRID_MENU_DIVIDE, 0xfffe,
194 TRID_MENU_MOVE_CENTER, TRID_MENU_ALL_EVEN, TRID_MENU_REVERSE, 0xffff
195 };
196
197 editwg = p->editwg[no];
198
199 //------- メニュー作成
200
201 M_TR_G(TRGROUP_DLG_GRADATION_EDIT);
202
203 menu = mMenuNew();
204
205 mMenuAddTrArray16(menu, id);
206
207 //無効
208
209 n = GradEditWidget_getCurrentPos(editwg);
210
211 if(n == 0 || n == GRADDAT_POS_MAX)
212 {
213 mMenuSetEnable(menu, TRID_MENU_DELETE, 0);
214 mMenuSetEnable(menu, TRID_MENU_MOVE_CENTER, 0);
215 }
216
217 //分割数
218
219 n = GradEditWidget_getMaxSplitNum_toright(editwg);
220
221 if(n < 2)
222 mMenuSetEnable(menu, TRID_MENU_DIVIDE, FALSE);
223 else
224 {
225 sub = mMenuNew();
226
227 for(i = 2; i <= n && i <= 10; i++)
228 {
229 mIntToStr(m, i);
230 mMenuAddText_copy(sub, 1000 + i, m);
231 }
232
233 mMenuSetSubmenu(menu, TRID_MENU_DIVIDE, sub);
234 }
235
236 //--------- メニュー実行
237
238 mWidgetGetRootBox(M_WIDGET(p->menubtt[no]), &box);
239
240 mi = mMenuPopup(menu, NULL, box.x + box.w, box.y + box.h, MMENU_POPUP_F_RIGHT);
241 i = (mi)? mi->id: -1;
242
243 mMenuDestroy(menu);
244
245 if(i == -1) return;
246
247 //-------- コマンド実行
248
249 if(i >= 1000)
250 {
251 //分割
252 GradEditWidget_splitPoint_toright(editwg, i - 1000);
253 }
254 else
255 {
256 switch(i)
257 {
258 //カレント削除
259 case TRID_MENU_DELETE:
260 GradEditWidget_deletePoint(editwg, -1);
261 break;
262 //中間位置へ
263 case TRID_MENU_MOVE_CENTER:
264 GradEditWidget_moveCurrentPos_middle(editwg);
265 break;
266 //すべて等間隔に
267 case TRID_MENU_ALL_EVEN:
268 GradEditWidget_evenAllPoints(editwg);
269 break;
270 //反転
271 case TRID_MENU_REVERSE:
272 GradEditWidget_reversePoints(editwg);
273 break;
274 }
275 }
276 }
277
278
279 //==========================
280 // イベント
281 //==========================
282
283
284 /** OK 時、グラデーションデータをセット */
285
_set_graddat(_edit_dlg * p)286 static void _set_graddat(_edit_dlg *p)
287 {
288 int colnum,anum;
289 uint8_t flags;
290
291 colnum = GradEditWidget_getPointNum(p->editwg[0]);
292 anum = GradEditWidget_getPointNum(p->editwg[1]);
293
294 //フラグ
295
296 flags = 0;
297 if(mCheckButtonIsChecked(p->ck_flag[0])) flags |= GRADDAT_F_LOOP;
298 if(mCheckButtonIsChecked(p->ck_flag[1])) flags |= GRADDAT_F_SINGLE_COL;
299
300 //セット
301
302 GradItem_setDat(p->item, flags, colnum, anum,
303 GradEditWidget_getBuf(p->editwg[0]),
304 GradEditWidget_getBuf(p->editwg[1]));
305 }
306
307 /** イベント */
308
_event_handle(mWidget * wg,mEvent * ev)309 static int _event_handle(mWidget *wg,mEvent *ev)
310 {
311 _edit_dlg *p = (_edit_dlg *)wg;
312
313 if(ev->type == MEVENT_NOTIFY)
314 {
315 int id,type,n;
316
317 id = ev->notify.id;
318 type = ev->notify.type;
319
320 switch(id)
321 {
322 //グラデ編集 (col)
323 case WID_EDITWG_COL:
324 _set_curinfo(p, 0);
325 break;
326 //グラデ編集 (A)
327 case WID_EDITWG_A:
328 _set_curinfo(p, 1);
329
330 //ポインタに変更があれば色のグラデーションも再描画
331 if(type == GRADEDITWIDGET_N_MODIFY)
332 _update_editwg(p, 0);
333 break;
334
335 //位置 エディット
336 case WID_EDIT_COL_POS:
337 case WID_EDIT_A_POS:
338 if(type == MLINEEDIT_N_CHANGE)
339 {
340 id -= WID_EDIT_COL_POS;
341
342 if(GradEditWidget_setCurrentPos(p->editwg[id], mLineEditGetNum(p->ledit_pos[id]))
343 && id == 1)
344 {
345 //A の値が変わったらカラーを再描画
346 _update_editwg(p, 0);
347 }
348 }
349 break;
350 //色タイプ
351 case WID_CK_COL_SPEC:
352 case WID_CK_COL_DRAW:
353 case WID_CK_COL_BKGND:
354 n = id - WID_CK_COL_SPEC;
355
356 mWidgetEnable(M_WIDGET(p->colbt), (n == 0));
357
358 GradEditWidget_setColorType(p->editwg[0], n);
359 break;
360 //指定色
361 case WID_COLBTT:
362 if(type == MCOLORBUTTON_N_PRESS)
363 GradEditWidget_setColorRGB(p->editwg[0], ev->notify.param1);
364 break;
365 //不透明度スライダー
366 case WID_SLIDER_A:
367 if(type == MSLIDERBAR_N_HANDLE
368 && (ev->notify.param2 & MSLIDERBAR_HANDLE_F_CHANGE))
369 {
370 GradEditWidget_setOpacity(p->editwg[1], ev->notify.param1);
371
372 mLineEditSetNum(p->ledit_opa, ev->notify.param1);
373
374 _update_editwg(p, 0);
375 }
376 break;
377 //不透明度、値のエディット
378 case WID_EDIT_A_VAL:
379 if(type == MLINEEDIT_N_CHANGE)
380 {
381 n = mLineEditGetNum(p->ledit_opa);
382
383 GradEditWidget_setOpacity(p->editwg[1], n);
384
385 mSliderBarSetPos(p->sl_opa, n);
386
387 _update_editwg(p, 0);
388 }
389 break;
390
391 //カレントポイント変更
392 case WID_BTT_COL_MOVELEFT:
393 case WID_BTT_A_MOVELEFT:
394 case WID_BTT_COL_MOVERIGHT:
395 case WID_BTT_A_MOVERIGHT:
396 id -= WID_BTT_COL_MOVELEFT;
397
398 GradEditWidget_moveCurrentPoint(p->editwg[id & 1], (id >= 2));
399 _set_curinfo(p, id & 1);
400 break;
401 //メニューボタン
402 case WID_MENUBTT_COL:
403 case WID_MENUBTT_A:
404 _run_menu(p, id - WID_MENUBTT_COL);
405 break;
406
407 //単色化
408 case WID_CK_SINGLE_COL:
409 GradEditWidget_setSingleColor(p->editwg[0], -1);
410
411 _update_editwg(p, 0);
412 break;
413
414 //OK
415 case M_WID_OK:
416 _set_graddat(p);
417 mDialogEnd(M_DIALOG(wg), TRUE);
418 break;
419 //キャンセル
420 case M_WID_CANCEL:
421 mDialogEnd(M_DIALOG(wg), FALSE);
422 break;
423 }
424 }
425
426 return mDialogEventHandle(wg, ev);
427 }
428
429
430 //==========================
431 // 作成
432 //==========================
433
434
435 /** 編集部分のウィジェット作成 */
436
_create_edit_widget(_edit_dlg * p,int no)437 static void _create_edit_widget(_edit_dlg *p,int no)
438 {
439 mWidget *ct_toph,*ct_v,*ct_h;
440 mArrowButton *abtt;
441
442 ct_toph = mContainerCreate(M_WIDGET(p), MCONTAINER_TYPE_HORZ, 0, 8, MLF_EXPAND_W);
443 ct_toph->margin.bottom = 6;
444
445 p->editwg[no] = GradEditWidget_new(ct_toph, WID_EDITWG_COL + no, no, p->item->buf);
446
447 //----- ボタン
448
449 ct_v = mContainerCreate(ct_toph, MCONTAINER_TYPE_VERT, 0, 4, 0);
450 ct_h = mContainerCreate(ct_v, MCONTAINER_TYPE_HORZ, 0, 0, 0);
451
452 //移動
453
454 abtt = mArrowButtonCreate(ct_h, WID_BTT_COL_MOVELEFT + no, MARROWBUTTON_S_LEFT, 0, 0);
455 abtt->wg.hintOverW = abtt->wg.hintOverH = 19;
456
457 abtt = mArrowButtonCreate(ct_h, WID_BTT_COL_MOVERIGHT + no, MARROWBUTTON_S_RIGHT, 0, 0);
458 abtt->wg.hintOverW = abtt->wg.hintOverH = 19;
459
460 //メニューボタン
461
462 p->menubtt[no] = mArrowButtonCreate(ct_v,
463 WID_MENUBTT_COL + no, MARROWBUTTON_S_DOWN, MLF_RIGHT, 0);
464 }
465
466 /** ダイアログ作成 */
467
_create_dlg(mWindow * owner,GradItem * item)468 static _edit_dlg *_create_dlg(mWindow *owner,GradItem *item)
469 {
470 _edit_dlg *p;
471 int i,flag;
472
473 p = (_edit_dlg *)mDialogNew(sizeof(_edit_dlg),
474 owner, MWINDOW_S_DIALOG_NORMAL);
475 if(!p) return NULL;
476
477 p->item = item;
478 p->wg.event = _event_handle;
479
480 //
481
482 mContainerSetPadding_one(M_CONTAINER(p), 8);
483
484 M_TR_G(TRGROUP_DLG_GRADATION_EDIT);
485
486 mWindowSetTitle(M_WINDOW(p), M_TR_T(0));
487
488 //------- 編集部分
489
490 _create_edit_widget(p, 0);
491 _create_edit_widget(p, 1);
492
493 GradEditWidget_setAnotherModeBuf(p->editwg[0], GradEditWidget_getBuf(p->editwg[1]));
494 GradEditWidget_setAnotherModeBuf(p->editwg[1], GradEditWidget_getBuf(p->editwg[0]));
495
496 //------- 以降
497
498 mWidgetBuilderCreateFromText(M_WIDGET(p), g_wb_gradeditdlg);
499
500 //位置
501
502 for(i = 0; i < 2; i++)
503 {
504 p->ledit_pos[i] = (mLineEdit *)mWidgetFindByID(M_WIDGET(p), WID_EDIT_COL_POS + i);
505 mLineEditSetNumStatus(p->ledit_pos[i], 0, 1000, 1);
506 }
507
508 //色
509
510 p->ck_coltype = (mCheckButton *)mWidgetFindByID(M_WIDGET(p), WID_CK_COL_SPEC);
511
512 p->colbt = (mColorButton *)mWidgetFindByID(M_WIDGET(p), WID_COLBTT);
513
514 //不透明度、値
515
516 p->sl_opa = (mSliderBar *)mWidgetFindByID(M_WIDGET(p), WID_SLIDER_A);
517
518 p->ledit_opa = (mLineEdit *)mWidgetFindByID(M_WIDGET(p), WID_EDIT_A_VAL);
519
520 //フラグ
521
522 flag = item->buf[0];
523
524 for(i = 0; i < 2; i++)
525 {
526 p->ck_flag[i] = (mCheckButton *)mWidgetFindByID(M_WIDGET(p), WID_CK_LOOP + i);
527
528 mCheckButtonSetState(p->ck_flag[i], flag & (1 << i));
529 }
530
531 //OK/キャンセル
532
533 mContainerCreateOkCancelButton(M_WIDGET(p));
534
535 //------ 初期化
536
537 _set_curinfo(p, 0);
538 _set_curinfo(p, 1);
539
540 GradEditWidget_setSingleColor(p->editwg[0], flag & GRADDAT_F_SINGLE_COL);
541
542 return p;
543 }
544
545
546 //==========================
547 //
548 //==========================
549
550
551 /** ダイアログ実行 */
552
GradationEditDlg_run(mWindow * owner,GradItem * item)553 mBool GradationEditDlg_run(mWindow *owner,GradItem *item)
554 {
555 _edit_dlg *p;
556
557 p = _create_dlg(owner, item);
558 if(!p) return FALSE;
559
560 mWindowMoveResizeShow_hintSize(M_WINDOW(p));
561
562 return mDialogRun(M_DIALOG(p), TRUE);
563 }
564