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 * メニュー・サブ処理
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