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 
26 #include "mMenu.h"
27 #include "mMenu_pv.h"
28 
29 #include "mFont.h"
30 #include "mAccelerator.h"
31 
32 
33 //-----------------
34 
35 #define _MENUITEM_SEP_H   5
36 #define _MENUITEM_SPACE_V 3
37 
38 //-----------------
39 
40 
41 /** 選択できないアイテムか */
42 
__mMenuItemIsDisableItem(mMenuItem * p)43 mBool __mMenuItemIsDisableItem(mMenuItem *p)
44 {
45 	return ((p->item.flags & (MMENUITEM_F_DISABLE | MMENUITEM_F_SEP)) != 0);
46 }
47 
48 /** 有効なサブメニューか */
49 
__mMenuItemIsEnableSubmenu(mMenuItem * p)50 mBool __mMenuItemIsEnableSubmenu(mMenuItem *p)
51 {
52 	return (p->item.submenu
53 			&& !(p->item.flags & MMENUITEM_F_DISABLE)
54 			&& (p->item.submenu)->list.top);
55 }
56 
57 /** ラジオグループのチェック */
58 
__mMenuItemCheckRadio(mMenuItem * item,int check)59 void __mMenuItemCheckRadio(mMenuItem *item,int check)
60 {
61 	mMenuItem *p;
62 
63 	//前方のフラグをOFF
64 
65 	for(p = M_MENUITEM(item->i.prev);
66 			p && !(p->item.flags & MMENUITEM_F_SEP); p = M_MENUITEM(p->i.prev))
67 		M_FLAG_OFF(p->item.flags, MMENUITEM_F_CHECKED);
68 
69 	//後ろのフラグをOFF
70 
71 	for(p = M_MENUITEM(item->i.next);
72 			p && !(p->item.flags & MMENUITEM_F_SEP); p = M_MENUITEM(p->i.next))
73 		M_FLAG_OFF(p->item.flags, MMENUITEM_F_CHECKED);
74 
75 	//自身
76 
77 	if(check)
78 		M_FLAG_ON(item->item.flags, MMENUITEM_F_CHECKED);
79 	else
80 		M_FLAG_OFF(item->item.flags, MMENUITEM_F_CHECKED);
81 }
82 
83 /** ホットキーからアイテム検索 */
84 
__mMenuFindByHotkey(mMenu * menu,char key)85 mMenuItem *__mMenuFindByHotkey(mMenu *menu,char key)
86 {
87 	mMenuItem *p;
88 
89 	for(p = M_MENUITEM(menu->list.top); p; p = M_MENUITEM(p->i.next))
90 	{
91 		if(p->hotkey == key && !__mMenuItemIsDisableItem(p))
92 			return p;
93 	}
94 
95 	return NULL;
96 }
97 
98 
99 //=======================
100 // 初期化
101 //=======================
102 
103 
104 /** テキスト関連を初期化 */
105 
__mMenuInitText(mMenuItem * p,int flags)106 void __mMenuInitText(mMenuItem *p,int flags)
107 {
108 	const char *pc;
109 	char c;
110 
111 	//------ ショートカットキー文字列
112 
113 	if(flags & MMENU_INITTEXT_SHORTCUT)
114 	{
115 		if(p->item.shortcutkey)
116 			p->sctext = mAcceleratorGetKeyText(p->item.shortcutkey);
117 	}
118 
119 	//------ ラベル
120 
121 	if(flags & MMENU_INITTEXT_LABEL)
122 	{
123 		//ラベルコピー
124 
125 		if(p->item.label && (p->item.flags & MMENUITEM_F_LABEL_COPY))
126 		{
127 			p->labelcopy = mStrdup(p->item.label);
128 			p->item.label = p->labelcopy;
129 		}
130 
131 		//ラベル文字列
132 
133 		p->labelsrc = (p->item.label)? p->item.label: p->labelcopy;
134 
135 		//ラベルからホットキー取得
136 
137 		p->hotkey = 0;
138 
139 		if(p->labelsrc)
140 		{
141 			for(pc = p->labelsrc; *pc; pc++)
142 			{
143 				if(*pc == '&')
144 				{
145 					c = *(++pc);
146 
147 					if(c == '&')
148 						continue;
149 					else if((c >= '0' && c <= '9') ||
150 							(c >= 'A' && c <= 'Z') ||
151 							(c >= 'a' && c <= 'z'))
152 					{
153 						if(c >= 'a' && c <= 'z') c = c - 'a' + 'A';
154 
155 						p->hotkey = c;
156 						break;
157 					}
158 				}
159 			}
160 		}
161 	}
162 }
163 
164 /** 初期化 - 位置や幅 */
165 
_init_size(mMenuItem * p,mFont * font)166 static void _init_size(mMenuItem *p,mFont *font)
167 {
168 	if(p->item.flags & MMENUITEM_F_SEP)
169 	{
170 		//セパレータ
171 
172 		p->labelLeftW  = 1;
173 		p->labelRightW = 0;
174 		p->item.height = _MENUITEM_SEP_H;
175 	}
176 	else if(p->item.draw)
177 	{
178 		//独自描画
179 
180 		p->labelLeftW = p->labelRightW = 0;
181 	}
182 	else if(p->item.label)
183 	{
184 		//------- 通常テキスト
185 
186 		//テキスト
187 
188 		p->labelLeftW  = mFontGetTextWidthHotkey(font, p->labelsrc, -1);
189 		p->labelRightW = mFontGetTextWidth(font, p->sctext, -1);
190 
191 		//高さ
192 
193 		p->item.height = font->height;
194 
195 		if(p->item.height < 9) p->item.height = 9;
196 
197 		p->item.height += _MENUITEM_SPACE_V * 2;
198 	}
199 }
200 
201 /** ウィンドウ表示前の初期化 */
202 
__mMenuInit(mMenu * menu,mFont * font)203 void __mMenuInit(mMenu *menu,mFont *font)
204 {
205 	mMenuItem *p;
206 
207 	for(p = M_MENUITEM(menu->list.top); p; p = M_MENUITEM(p->i.next))
208 	{
209 		//描画幅など処理
210 
211 		if(p->fTmp & MMENUITEM_TMPF_INIT_SIZE)
212 		{
213 			_init_size(p, font);
214 
215 			M_FLAG_OFF(p->fTmp, MMENUITEM_TMPF_INIT_SIZE);
216 		}
217 	}
218 }
219