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  * DockLayer
22  *
23  * [dock] レイヤ
24  *****************************************/
25 
26 #include "mDef.h"
27 #include "mWindowDef.h"
28 #include "mWidget.h"
29 #include "mContainer.h"
30 #include "mDockWidget.h"
31 #include "mIconButtons.h"
32 #include "mMenu.h"
33 #include "mEvent.h"
34 #include "mTrans.h"
35 
36 #include "defWidgets.h"
37 #include "defDraw.h"
38 #include "defConfig.h"
39 
40 #include "DockObject.h"
41 #include "AppResource.h"
42 #include "draw_layer.h"
43 
44 #include "trgroup.h"
45 #include "trid_word.h"
46 #include "trid_mainmenu.h"
47 
48 
49 //------------------------
50 
51 #define _DOCKLAYER(p)  ((DockLayer *)(p))
52 #define _DL_PTR        ((DockLayer *)APP_WIDGETS->dockobj[DOCKWIDGET_LAYER])
53 
54 //------------------------
55 
56 typedef struct _DockLayerArea DockLayerArea;
57 
58 typedef struct
59 {
60 	DockObject obj;
61 
62 	mWidget *param_ct;
63 	mIconButtons *ib;
64 	DockLayerArea *area;
65 }DockLayer;
66 
67 //------------------------
68 
69 /* DockLayer_param.c */
70 
71 mWidget *DockLayer_parameter_new(mWidget *parent);
72 void DockLayer_parameter_setValue(mWidget *wg);
73 
74 /* DockLayer_area.c */
75 
76 DockLayerArea *DockLayerArea_new(mWidget *parent);
77 void DockLayerArea_drawLayer(DockLayerArea *p,LayerItem *pi);
78 void DockLayerArea_setScrollInfo(DockLayerArea *p);
79 void DockLayerArea_changeCurrent_visible(DockLayerArea *p,LayerItem *lastitem,mBool update_all);
80 
81 //------------------------
82 
83 
84 
85 /** ツールバー[新規レイヤ]のドロップダウンメニュー */
86 
_run_new_dropdown_menu(DockLayer * p)87 static void _run_new_dropdown_menu(DockLayer *p)
88 {
89 	mMenu *menu;
90 	mMenuItemInfo *pi;
91 	int type;
92 	mBox box;
93 
94 	menu = mMenuNew();
95 
96 	M_TR_G(TRGROUP_LAYERTYPE);
97 
98 	mMenuAddText_static(menu, 100, M_TR_T2(TRGROUP_WORD, TRID_WORD_FOLDER));
99 	mMenuAddSep(menu);
100 	mMenuAddTrTexts(menu, 0, 4);
101 
102 	mIconButtonsGetItemBox(p->ib, TRMENU_LAYER_NEW, &box, TRUE);
103 
104 	pi = mMenuPopup(menu, NULL, box.x, box.y + box.h, 0);
105 
106 	type = (pi)? pi->id: -100;
107 
108 	mMenuDestroy(menu);
109 
110 	//
111 
112 	if(type != -100)
113 		drawLayer_newLayer_direct(APP_DRAW, (type == 100)? -1: type);
114 }
115 
116 /** イベント */
117 
_event_handle(mWidget * wg,mEvent * ev)118 static int _event_handle(mWidget *wg,mEvent *ev)
119 {
120 	if(ev->type == MEVENT_COMMAND)
121 	{
122 		if(ev->cmd.id == TRMENU_LAYER_NEW && ev->cmd.by == MEVENT_COMMAND_BY_ICONBUTTONS_DROP)
123 			//新規作成のドロップダウンメニュー
124 			_run_new_dropdown_menu(_DOCKLAYER(wg->param));
125 		else
126 			//メインウィンドウへ送る
127 			(((mWidget *)APP_WIDGETS->mainwin)->event)((mWidget *)APP_WIDGETS->mainwin, ev);
128 	}
129 
130 	return 1;
131 }
132 
133 /** mDockWidget ハンドラ : 内容作成 */
134 
_dock_func_create(mDockWidget * dockwg,int id,mWidget * parent)135 static mWidget *_dock_func_create(mDockWidget *dockwg,int id,mWidget *parent)
136 {
137 	DockLayer *p = _DL_PTR;
138 	mWidget *ct;
139 	mIconButtons *ib;
140 	int i;
141 	uint16_t bttid[] = {
142 		TRMENU_LAYER_NEW, TRMENU_LAYER_COPY, TRMENU_LAYER_ERASE,
143 		TRMENU_LAYER_DELETE, TRMENU_LAYER_COMBINE, TRMENU_LAYER_DROP,
144 		TRMENU_LAYER_TB_MOVE_UP, TRMENU_LAYER_TB_MOVE_DOWN
145 	};
146 
147 	//コンテナ
148 
149 	ct = mContainerCreate(parent, MCONTAINER_TYPE_VERT, 0, 0, MLF_EXPAND_WH);
150 
151 	ct->event = _event_handle;
152 	ct->notifyTarget = MWIDGET_NOTIFYTARGET_SELF;
153 	ct->param = (intptr_t)p;
154 
155 	//上部のパラメータ部分
156 	/* 起動中にパレットを破棄->作成した場合のためにパラメータセット。
157 	 * 起動時はカレントレイヤが NULL なのでその場合はセットしない。 */
158 
159 	p->param_ct = DockLayer_parameter_new(ct);
160 
161 	DockLayer_parameter_setValue(p->param_ct);
162 
163 	//エリア (レイヤ名用に 12px フォントセット)
164 
165 	p->area = DockLayerArea_new(ct);
166 
167 	M_WIDGET(p->area)->font = APP_WIDGETS->font_dock12px;
168 
169 	//ツールバー
170 
171 	p->ib = ib = mIconButtonsNew(0, ct,
172 		MICONBUTTONS_S_TOOLTIP | MICONBUTTONS_S_DESTROY_IMAGELIST);
173 
174 	ib->wg.fLayout = MLF_EXPAND_W;
175 
176 	mIconButtonsSetImageList(ib, AppResource_loadIconImage("layer.png", APP_CONF->iconsize_layer));
177 	mIconButtonsSetTooltipTrGroup(ib, TRGROUP_DOCK_LAYER);
178 
179 	for(i = 0; i < 8; i++)
180 	{
181 		mIconButtonsAdd(ib, bttid[i], i, i,
182 			(i == 0)? MICONBUTTONS_ITEMF_DROPDOWN: 0);
183 	}
184 
185 	mIconButtonsCalcHintSize(ib);
186 
187 	return ct;
188 }
189 
190 /** 作成 */
191 
DockLayer_new(mDockWidgetState * state)192 void DockLayer_new(mDockWidgetState *state)
193 {
194 	DockObject *p;
195 
196 	p = DockObject_new(DOCKWIDGET_LAYER,
197 			sizeof(DockLayer), MDOCKWIDGET_S_EXPAND, MWINDOW_S_ENABLE_DND,
198 			state, _dock_func_create);
199 
200 	mDockWidgetCreateWidget(p->dockwg);
201 }
202 
203 
204 //===============================
205 // 外部からの呼び出し
206 //===============================
207 
208 
209 /** アイコンサイズ変更 */
210 
DockLayer_changeIconSize()211 void DockLayer_changeIconSize()
212 {
213 	DockLayer *p = _DL_PTR;
214 
215 	if(DockObject_canDoWidget((DockObject *)p))
216 	{
217 		mIconButtonsReplaceImageList(p->ib,
218 			AppResource_loadIconImage("layer.png", APP_CONF->iconsize_layer));
219 
220 		DockObject_relayout_inWindowMode(DOCKWIDGET_LAYER);
221 	}
222 }
223 
224 /** すべて更新 */
225 
DockLayer_update_all()226 void DockLayer_update_all()
227 {
228 	DockLayer *p = _DL_PTR;
229 
230 	if(DockObject_canDoWidget((DockObject *)p))
231 	{
232 		DockLayer_parameter_setValue(p->param_ct);
233 
234 		DockLayerArea_setScrollInfo(p->area);
235 
236 		mWidgetUpdate(M_WIDGET(p->area));
237 	}
238 }
239 
240 /** カレントレイヤの上部パラメータ更新 */
241 
DockLayer_update_curparam()242 void DockLayer_update_curparam()
243 {
244 	DockLayer *p = _DL_PTR;
245 
246 	if(DockObject_canDoWidget((DockObject *)p))
247 		DockLayer_parameter_setValue(p->param_ct);
248 }
249 
250 /** カレントレイヤを更新 */
251 
DockLayer_update_curlayer(mBool setparam)252 void DockLayer_update_curlayer(mBool setparam)
253 {
254 	DockLayer *p = _DL_PTR;
255 
256 	if(DockObject_canDoWidget((DockObject *)p))
257 	{
258 		if(setparam)
259 			DockLayer_parameter_setValue(p->param_ct);
260 
261 		DockLayerArea_drawLayer(p->area, APP_DRAW->curlayer);
262 	}
263 }
264 
265 /** 指定レイヤのみ更新 (一覧部分のみ) */
266 
DockLayer_update_layer(LayerItem * item)267 void DockLayer_update_layer(LayerItem *item)
268 {
269 	DockLayer *p = _DL_PTR;
270 
271 	if(item && DockObject_canDoWidget_visible((DockObject *)p))
272 		DockLayerArea_drawLayer(p->area, item);
273 }
274 
275 /** 指定レイヤのみ更新
276  *
277  * 指定レイヤがカレントの場合は上部パラメータも更新 */
278 
DockLayer_update_layer_curparam(LayerItem * item)279 void DockLayer_update_layer_curparam(LayerItem *item)
280 {
281 	DockLayer *p = _DL_PTR;
282 
283 	if(item)
284 	{
285 		if(DockObject_canDoWidget_visible((DockObject *)p))
286 			DockLayerArea_drawLayer(p->area, item);
287 
288 		if(item == APP_DRAW->curlayer
289 			&& DockObject_canDoWidget((DockObject *)p))
290 			DockLayer_parameter_setValue(p->param_ct);
291 	}
292 }
293 
294 /** カレント変更時の更新 (カレントが一覧上に見えるように)
295  *
296  * @param lastitem   カレント変更前のカレントレイヤ
297  * @param update_all フォルダ展開などによりリスト全体を更新 */
298 
DockLayer_update_changecurrent_visible(LayerItem * lastitem,mBool update_all)299 void DockLayer_update_changecurrent_visible(LayerItem *lastitem,mBool update_all)
300 {
301 	DockLayer *p = _DL_PTR;
302 
303 	if(DockObject_canDoWidget((DockObject *)p))
304 	{
305 		DockLayer_parameter_setValue(p->param_ct);
306 
307 		if(update_all)
308 			DockLayerArea_setScrollInfo(p->area);
309 
310 		DockLayerArea_changeCurrent_visible(p->area, lastitem, update_all);
311 	}
312 }
313 
314