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 * DockOption
22 *
23 * [dock]オプションのタブ内容
24 * (定規、入り抜き)
25 ********************************************/
26
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <math.h>
30
31 #include "mDef.h"
32 #include "mStr.h"
33 #include "mContainerDef.h"
34 #include "mWidget.h"
35 #include "mContainer.h"
36 #include "mEvent.h"
37 #include "mLabel.h"
38 #include "mComboBox.h"
39 #include "mButton.h"
40 #include "mCheckButton.h"
41 #include "mMenu.h"
42 #include "mTrans.h"
43 #include "mPixbuf.h"
44 #include "mSysCol.h"
45
46 #include "defDraw.h"
47
48 #include "DockOption_sub.h"
49 #include "ValueBar.h"
50
51 #include "draw_rule.h"
52
53 #include "trgroup.h"
54
55
56 //--------------------
57
58 //定規タイプイメージ (1bit: 121x21)
59 static const unsigned char g_img_rule[]={
60 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,
61 0x01,0x00,0x10,0x21,0x84,0x21,0x84,0x30,0x40,0x80,0x01,0x00,0x10,0x00,0x00,0x01,
62 0x01,0x00,0x90,0x10,0x42,0x21,0x84,0x50,0x40,0x40,0x01,0x1f,0x10,0x00,0x00,0x01,
63 0x79,0x9e,0x57,0x08,0x21,0x21,0x84,0x90,0x40,0x20,0xc1,0x60,0x10,0x00,0x00,0x01,
64 0xfd,0x9e,0x37,0x84,0x10,0x21,0x84,0x10,0x41,0x10,0x21,0x80,0x10,0xf0,0x01,0x01,
65 0xcd,0x9e,0x17,0x42,0x08,0xff,0xff,0x1f,0x42,0x08,0x11,0x00,0x11,0x0c,0x06,0x01,
66 0x85,0x82,0x10,0x21,0x84,0x21,0x84,0x10,0x44,0x04,0x09,0x0e,0x12,0x02,0x08,0x01,
67 0x85,0x82,0x90,0x10,0x42,0x21,0x84,0x10,0x48,0x02,0x09,0x11,0x12,0x01,0x10,0x01,
68 0x85,0x82,0x50,0x08,0x21,0x21,0x84,0x10,0x50,0x01,0x85,0x20,0x94,0xe0,0x20,0x01,
69 0x85,0x9e,0x37,0x84,0x10,0x21,0x84,0x10,0xe0,0x00,0x45,0x40,0x54,0x10,0x41,0x01,
70 0x85,0x9e,0x17,0x42,0x08,0xff,0xff,0xff,0xff,0xff,0x45,0x40,0x54,0x08,0x42,0x01,
71 0x85,0x9e,0x17,0x21,0x84,0x21,0x84,0x10,0xe0,0x00,0x45,0x40,0x54,0x10,0x41,0x01,
72 0x85,0x82,0x90,0x10,0x42,0x21,0x84,0x10,0x50,0x01,0x85,0x20,0x94,0xe0,0x20,0x01,
73 0x85,0x82,0x50,0x08,0x21,0x21,0x84,0x10,0x48,0x02,0x09,0x11,0x12,0x01,0x10,0x01,
74 0x85,0x82,0x30,0x84,0x10,0x21,0x84,0x10,0x44,0x04,0x09,0x0e,0x12,0x02,0x08,0x01,
75 0xcd,0x82,0x10,0x42,0x08,0xff,0xff,0x1f,0x42,0x08,0x11,0x00,0x11,0x0c,0x06,0x01,
76 0xfd,0x82,0x10,0x21,0x84,0x21,0x84,0x10,0x41,0x10,0x21,0x80,0x10,0xf0,0x01,0x01,
77 0x79,0x82,0x90,0x10,0x42,0x21,0x84,0x90,0x40,0x20,0xc1,0x60,0x10,0x00,0x00,0x01,
78 0x01,0x00,0x50,0x08,0x21,0x21,0x84,0x50,0x40,0x40,0x01,0x1f,0x10,0x00,0x00,0x01,
79 0x01,0x00,0x30,0x84,0x10,0x21,0x84,0x30,0x40,0x80,0x01,0x00,0x10,0x00,0x00,0x01,
80 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01 };
81
82 //--------------------
83
84
85 //******************************
86 // 定規
87 //******************************
88
89
90 typedef struct
91 {
92 mWidget wg;
93 mContainerData ct;
94
95 mWidget *wg_type;
96 mLabel *lb_type;
97 }_tab_rule;
98
99 enum
100 {
101 WID_RULE_TYPE = 100,
102 WID_RULE_BTT_CALL,
103 WID_RULE_BTT_RECORD
104 };
105
106
107 //----------- タイプ選択ウィジェット
108
109 /** 描画 */
110
_rule_type_draw_handle(mWidget * wg,mPixbuf * pixbuf)111 static void _rule_type_draw_handle(mWidget *wg,mPixbuf *pixbuf)
112 {
113 //背景
114
115 mPixbufFillBox(pixbuf, 0, 0, wg->w, wg->h, MSYSCOL(WHITE));
116
117 //選択の背景
118
119 mPixbufFillBox(pixbuf, APP_DRAW->rule.type * 20 + 1, 1, 19, 19, mRGBtoPix(0xff9999));
120
121 //イメージ
122
123 mPixbufDrawBitPattern(pixbuf, 0, 0, g_img_rule, wg->w, wg->h, 0);
124 }
125
126 /** イベント */
127
_rule_type_event_handle(mWidget * wg,mEvent * ev)128 static int _rule_type_event_handle(mWidget *wg,mEvent *ev)
129 {
130 if(ev->type == MEVENT_POINTER
131 && ev->pt.type == MEVENT_POINTER_TYPE_PRESS
132 && ev->pt.btt == M_BTT_LEFT)
133 {
134 //左ボタン押し時、定規タイプ変更
135
136 int n;
137
138 n = ev->pt.x / 20;
139 if(n >= RULE_TYPE_NUM) n = RULE_TYPE_NUM - 1;
140
141 if(n != APP_DRAW->rule.type)
142 {
143 drawRule_setType(APP_DRAW, n);
144
145 mWidgetAppendEvent_notify(NULL, wg, 0, 0, 0);
146
147 mWidgetUpdate(wg);
148 }
149 }
150
151 return 1;
152 }
153
154 //-----------
155
156 /** 記録メニュー実行 */
157
_rule_run_record_menu(mWidget * bttwg)158 static int _rule_run_record_menu(mWidget *bttwg)
159 {
160 mMenu *menu;
161 int i,n;
162 RuleRecord *rec;
163 mStr str = MSTR_INIT;
164 mMenuItemInfo *pi;
165 mBox box;
166
167 M_TR_G(TRGROUP_DOCKOPT_RULE);
168
169 //メニュー
170
171 menu = mMenuNew();
172
173 rec = APP_DRAW->rule.record;
174
175 for(i = 0; i < RULE_RECORD_NUM; i++, rec++)
176 {
177 mStrSetFormat(&str, "[%d] ", i + 1);
178
179 if(rec->type == 0)
180 mStrAppendText(&str, "---");
181 else
182 {
183 mStrAppendFormat(&str, "%s : ", M_TR_T(rec->type));
184
185 switch(rec->type)
186 {
187 //角度
188 case RULE_TYPE_PARALLEL_LINE:
189 case RULE_TYPE_GRID_LINE:
190 n = round(-rec->d[0] * 18000 / M_MATH_PI);
191 mStrAppendFormat(&str, "angle %d.%d", n / 100, abs(n % 100));
192 break;
193 //位置
194 case RULE_TYPE_CONC_LINE:
195 case RULE_TYPE_CIRCLE:
196 mStrAppendFormat(&str, "(%d,%d)", (int)rec->d[0], (int)rec->d[1]);
197 break;
198 //楕円
199 case RULE_TYPE_ELLIPSE:
200 n = round(rec->d[3] * 18000 / M_MATH_PI);
201 mStrAppendFormat(&str, "(%d,%d) angle %d.%d",
202 (int)rec->d[0], (int)rec->d[1], n / 100, abs(n % 100));
203 break;
204 }
205 }
206
207 mMenuAddText_copy(menu, i, str.buf);
208 }
209
210 mWidgetGetRootBox(bttwg, &box);
211
212 pi = mMenuPopup(menu, NULL, box.x, box.y + box.h, 0);
213
214 n = (pi)? pi->id: -1;
215
216 mMenuDestroy(menu);
217
218 mStrFree(&str);
219
220 return n;
221 }
222
223 /** イベント */
224
_rule_event_handle(mWidget * wg,mEvent * ev)225 static int _rule_event_handle(mWidget *wg,mEvent *ev)
226 {
227 if(ev->type == MEVENT_NOTIFY)
228 {
229 _tab_rule *p = (_tab_rule *)wg;
230 int no;
231
232 switch(ev->notify.id)
233 {
234 //タイプ変更
235 case WID_RULE_TYPE:
236 mLabelSetText(p->lb_type, M_TR_T2(TRGROUP_DOCKOPT_RULE, APP_DRAW->rule.type));
237 break;
238 //呼び出し
239 case WID_RULE_BTT_CALL:
240 no = _rule_run_record_menu(ev->notify.widgetFrom);
241 if(no != -1)
242 {
243 drawRule_callRecord(APP_DRAW, no);
244
245 //タイプ選択
246 mWidgetUpdate(p->wg_type);
247 mLabelSetText(p->lb_type, M_TR_T2(TRGROUP_DOCKOPT_RULE, APP_DRAW->rule.type));
248 }
249 break;
250 //記録
251 case WID_RULE_BTT_RECORD:
252 no = _rule_run_record_menu(ev->notify.widgetFrom);
253 if(no != -1)
254 drawRule_setRecord(APP_DRAW, no);
255 break;
256 }
257 }
258
259 return 1;
260 }
261
262 /** 定規ウィジェット作成 */
263
DockOption_createTab_rule(mWidget * parent)264 mWidget *DockOption_createTab_rule(mWidget *parent)
265 {
266 _tab_rule *p;
267 mWidget *ct,*wg;
268
269 M_TR_G(TRGROUP_DOCKOPT_RULE);
270
271 //メインコンテナ
272
273 p = (_tab_rule *)DockOption_createMainContainer(
274 sizeof(_tab_rule), parent, _rule_event_handle);
275
276 p->ct.sepW = 7;
277
278 //タイプ
279
280 p->wg_type = wg = mWidgetNew(0, M_WIDGET(p));
281
282 wg->id = WID_RULE_TYPE;
283 wg->hintW = 121;
284 wg->hintH = 21;
285 wg->draw = _rule_type_draw_handle;
286 wg->event = _rule_type_event_handle;
287 wg->fEventFilter |= MWIDGET_EVENTFILTER_POINTER;
288
289 //タイプ名
290
291 p->lb_type = mLabelCreate(M_WIDGET(p), MLABEL_S_BORDER, MLF_EXPAND_W, 0, 0);
292
293 mLabelSetText(p->lb_type, M_TR_T(APP_DRAW->rule.type));
294
295 //ボタン
296
297 ct = mContainerCreate(M_WIDGET(p), MCONTAINER_TYPE_HORZ, 0, 4, 0);
298
299 mButtonCreate(ct, WID_RULE_BTT_CALL, 0, 0, 0, M_TR_T(100));
300 mButtonCreate(ct, WID_RULE_BTT_RECORD, 0, 0, 0, M_TR_T(101));
301
302 return (mWidget *)p;
303 }
304
305
306 //******************************
307 // 入り抜き
308 //******************************
309
310
311 typedef struct
312 {
313 mWidget wg;
314 mContainerData ct;
315
316 ValueBar *bar[2];
317 }_tab_headtail;
318
319 enum
320 {
321 WID_HEADTAIL_LINE = 100,
322 WID_HEADTAIL_BEZIER,
323 WID_HEADTAIL_BAR_HEAD,
324 WID_HEADTAIL_BAR_TAIL,
325 WID_HEADTAIL_BTT_CALL,
326 WID_HEADTAIL_BTT_RECORD
327 };
328
329 enum
330 {
331 TRID_HEADTAIL_LINE,
332 TRID_HEADTAIL_BEZIER,
333 TRID_HEADTAIL_HEAD,
334 TRID_HEADTAIL_TAIL,
335 TRID_HEADTAIL_CALL,
336 TRID_HEADTAIL_RECORD
337 };
338
339
340 /** 呼出/記録メニュー実行 */
341
_headtail_run_record_menu(mWidget * bttwg)342 static int _headtail_run_record_menu(mWidget *bttwg)
343 {
344 mMenu *menu;
345 mMenuItemInfo *mi;
346 int i,n1,n2;
347 uint32_t *prec;
348 mBox box;
349 char m[32];
350
351 menu = mMenuNew();
352
353 prec = APP_DRAW->headtail.record;
354
355 for(i = 0; i < HEADTAIL_RECORD_NUM; i++, prec++)
356 {
357 n1 = *prec >> 16;
358 n2 = *prec & 0xffff;
359
360 snprintf(m, 32, "[%d] %d.%d - %d.%d", i + 1,
361 n1 / 10, n1 % 10, n2 / 10, n2 % 10);
362
363 mMenuAddText_copy(menu, i, m);
364 }
365
366 mWidgetGetRootBox(bttwg, &box);
367
368 mi = mMenuPopup(menu, NULL, box.x, box.y + box.h, 0);
369
370 n1 = (mi)? mi->id: -1;
371
372 mMenuDestroy(menu);
373
374 return n1;
375 }
376
377 /** バーの値セット */
378
_headtail_set_bar_value(_tab_headtail * p)379 static void _headtail_set_bar_value(_tab_headtail *p)
380 {
381 uint32_t val;
382
383 val = APP_DRAW->headtail.curval[APP_DRAW->headtail.selno];
384
385 ValueBar_setPos(p->bar[0], val >> 16);
386 ValueBar_setPos(p->bar[1], val & 0xffff);
387 }
388
389 /** イベント */
390
_headtail_event_handle(mWidget * wg,mEvent * ev)391 static int _headtail_event_handle(mWidget *wg,mEvent *ev)
392 {
393 if(ev->type == MEVENT_NOTIFY)
394 {
395 _tab_headtail *p = (_tab_headtail *)wg;
396 int no;
397
398 switch(ev->notify.id)
399 {
400 //タイプ選択
401 case WID_HEADTAIL_LINE:
402 case WID_HEADTAIL_BEZIER:
403 APP_DRAW->headtail.selno = ev->notify.id - WID_HEADTAIL_LINE;
404
405 _headtail_set_bar_value(p);
406 break;
407 //バー:入り
408 case WID_HEADTAIL_BAR_HEAD:
409 if(ev->notify.param2)
410 {
411 APP_DRAW->headtail.curval[APP_DRAW->headtail.selno] &= 0xffff;
412 APP_DRAW->headtail.curval[APP_DRAW->headtail.selno] |= (uint32_t)ev->notify.param1 << 16;
413 }
414 break;
415 //バー:抜き
416 case WID_HEADTAIL_BAR_TAIL:
417 if(ev->notify.param2)
418 {
419 APP_DRAW->headtail.curval[APP_DRAW->headtail.selno] &= 0xffff0000;
420 APP_DRAW->headtail.curval[APP_DRAW->headtail.selno] |= ev->notify.param1;
421 }
422 break;
423 //呼び出し
424 case WID_HEADTAIL_BTT_CALL:
425 no = _headtail_run_record_menu(ev->notify.widgetFrom);
426 if(no != -1)
427 {
428 APP_DRAW->headtail.curval[APP_DRAW->headtail.selno] =
429 APP_DRAW->headtail.record[no];
430
431 _headtail_set_bar_value(p);
432 }
433 break;
434 //記録
435 case WID_HEADTAIL_BTT_RECORD:
436 no = _headtail_run_record_menu(ev->notify.widgetFrom);
437 if(no != -1)
438 {
439 APP_DRAW->headtail.record[no] =
440 APP_DRAW->headtail.curval[APP_DRAW->headtail.selno];
441 }
442 break;
443 }
444 }
445
446 return 1;
447 }
448
449 /** 入り抜きウィジェット作成 */
450
DockOption_createTab_headtail(mWidget * parent)451 mWidget *DockOption_createTab_headtail(mWidget *parent)
452 {
453 _tab_headtail *p;
454 mWidget *ct;
455 int i;
456
457 M_TR_G(TRGROUP_DOCKOPT_HEADTAIL);
458
459 //メインコンテナ
460
461 p = (_tab_headtail *)DockOption_createMainContainer(
462 sizeof(_tab_headtail), parent, _headtail_event_handle);
463
464 p->ct.sepW = 7;
465
466 //タイプ選択
467
468 ct = mContainerCreate(M_WIDGET(p), MCONTAINER_TYPE_HORZ, 0, 5, 0);
469
470 for(i = 0; i < 2; i++)
471 {
472 mCheckButtonCreate(ct, WID_HEADTAIL_LINE + i, MCHECKBUTTON_S_RADIO, 0, 0,
473 M_TR_T(TRID_HEADTAIL_LINE + i), (APP_DRAW->headtail.selno == i));
474 }
475
476 //バー
477
478 ct = mContainerCreateGrid(M_WIDGET(p), 2, 4, 5, MLF_EXPAND_W);
479
480 for(i = 0; i < 2; i++)
481 {
482 mLabelCreate(ct, 0, MLF_RIGHT | MLF_MIDDLE, 0, M_TR_T(TRID_HEADTAIL_HEAD + i));
483
484 p->bar[i] = ValueBar_new(ct, WID_HEADTAIL_BAR_HEAD + i, MLF_EXPAND_W | MLF_MIDDLE,
485 1, 0, 1000, 0);
486 }
487
488 _headtail_set_bar_value(p);
489
490 //ボタン
491
492 ct = mContainerCreate(M_WIDGET(p), MCONTAINER_TYPE_HORZ, 0, 4, MLF_RIGHT);
493 ct->margin.top = 4;
494
495 for(i = 0; i < 2; i++)
496 mButtonCreate(ct, WID_HEADTAIL_BTT_CALL + i, 0, 0, 0, M_TR_T(TRID_HEADTAIL_CALL + i));
497
498 return (mWidget *)p;
499 }
500