Mercurial > otakunoraifu
annotate window/menuitem.cc @ 74:f8751d74918b default tip
Remove “duplicate” functions as they can be remplaced by a nearly-identical existing function.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Sat, 02 Apr 2011 19:13:54 +0200 |
parents | 4416cfac86ae |
children |
rev | line source |
---|---|
0 | 1 /* |
2 * Copyright (c) 2004-2006 Kazunori "jagarl" Ueno | |
3 * All rights reserved. | |
4 * | |
5 * Redistribution and use in source and binary forms, with or without | |
6 * modification, are permitted provided that the following conditions | |
7 * are met: | |
8 * 1. Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * 2. Redistributions in binary form must reproduce the above copyright | |
11 * notice, this list of conditions and the following disclaimer in the | |
12 * documentation and/or other materials provided with the distribution. | |
13 * 3. The name of the author may not be used to endorse or promote products | |
14 * derived from this software without specific prior written permission. | |
15 * | |
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
26 */ | |
27 | |
28 | |
52 | 29 #include "menuitem.h" |
0 | 30 |
31 #define Button WidButton | |
32 #define Scale WidScale | |
33 #define Label WidLabel | |
34 #define TextButton WidTextButton | |
35 #define Text WidText | |
36 | |
37 #define MenuItem WidMenuItem | |
38 #define RadioGroup WidRadioGroup | |
39 #define ScaleMenu WidScaleMenu | |
40 void fill(Surface* src, const Rect& rect, int r, int g, int b, int a = 0xff); | |
41 | |
42 MenuItem::MenuItem(PicContainer* parent, const Rect& r_orig, int _x_size, int _y_size, int* _value_ptr) : | |
43 x_size(_x_size), y_size(_y_size), value_ptr(_value_ptr), set_func(0), set_pointer(0) { | |
44 SetPic(parent->create_node(r_orig, 0)); | |
45 menu_width = r_orig.width(); | |
46 menu_height = r_orig.height(); | |
52 | 47 label = NULL; |
0 | 48 lb_width = 0; lb_right = 0; |
49 lb_left = -1; lb_bottom = -1; | |
50 int i; | |
51 for (i=0; i<x_size*y_size; i++) item.push_back(0); | |
52 | 52 } |
53 | |
0 | 54 void MenuItem::SetLabelLeft(PicWidget* lb, const Rect& min_rect, const Rect& min_margin) { |
55 lb_width = min_rect.width(); | |
56 lb_right = min_margin.width(); | |
57 lb_left = -1; | |
58 lb_bottom = -1; | |
59 label = lb; | |
60 } | |
52 | 61 |
0 | 62 void MenuItem::SetLabelTop(PicWidget* lb, const Rect& left_margin, const Rect& bottom_margin) { |
63 lb_left = left_margin.width(); | |
64 lb_bottom = bottom_margin.height(); | |
65 lb_width = -1; | |
66 lb_right = -1; | |
67 label = lb; | |
68 } | |
52 | 69 |
0 | 70 void MenuItem::SetValue(int new_value) { |
71 SetValueImpl(new_value); | |
72 if (value_ptr) *value_ptr = new_value; | |
73 if (set_func) (*set_func)(set_pointer, this); | |
74 } | |
52 | 75 |
0 | 76 void MenuItem::activate(void) { |
77 iterator it; | |
78 for (it=item.begin(); it!=item.end(); it++) { | |
52 | 79 if (*it == NULL) continue; |
0 | 80 (*it)->activate(); |
81 } | |
82 } | |
52 | 83 |
0 | 84 void MenuItem::deactivate(void) { |
85 iterator it; | |
86 for (it=item.begin(); it!=item.end(); it++) { | |
52 | 87 if (*it == NULL) continue; |
0 | 88 (*it)->deactivate(); |
89 } | |
90 } | |
52 | 91 |
0 | 92 void MenuItem::pack(void) { |
93 int x_min = 0, y_min = 0; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
52
diff
changeset
|
94 if (lb_width == -1) { // 上にラベルを貼る |
0 | 95 if (lb_left < 0) lb_left = 0; |
96 if (lb_bottom < 0) lb_bottom = 0; | |
97 if (label && label->Pic()) { | |
98 label->Pic()->Move(lb_left, 0); | |
99 y_min = lb_bottom + label->Pic()->Height(); | |
100 } else { | |
101 y_min = lb_bottom; | |
102 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
52
diff
changeset
|
103 } else { // 左にラベルを貼る |
0 | 104 if (lb_right < 0) lb_right = 0; |
105 if (label && label->Pic()) { | |
106 int label_width = label->Pic()->Width(); | |
107 int label_height = label->Pic()->Height(); | |
108 if (label_width > lb_width - lb_right) { | |
109 x_min = label_width + lb_right; | |
110 } else { | |
111 x_min = lb_width; | |
112 } | |
113 } else { | |
114 x_min = lb_width; | |
115 } | |
116 } | |
117 int* item_width = new int[x_size]; | |
118 int* item_height = new int[y_size]; | |
119 int* item_x = new int[x_size]; | |
120 int* item_y = new int[y_size]; | |
52 | 121 int i, j; |
0 | 122 for (i=0; i<x_size; i++) item_width[i]=0; |
123 for (i=0; i<y_size; i++) item_height[i]=0; | |
124 | |
125 iterator it = item.begin(); | |
126 for (i=0; i<y_size; i++) { | |
127 for (j=0; j<x_size; j++) { | |
52 | 128 if (*it != NULL && (*it)->Pic() != NULL) { |
0 | 129 PicBase* pic = (*it)->Pic(); |
130 if (item_width[j] < pic->Width()) item_width[j] = pic->Width(); | |
131 if (item_height[i] < pic->Height()) item_height[i] = pic->Height(); | |
132 } | |
133 it++; | |
134 } | |
135 } | |
136 int width=0, height=0; | |
137 for (i=0; i<x_size; i++) { | |
138 width += item_width[i]; | |
139 } | |
140 for (i=0; i<y_size; i++) { | |
141 height += item_height[i]; | |
142 } | |
143 | |
144 int x=x_min, y=y_min; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
52
diff
changeset
|
145 // width / height の再割り当て |
0 | 146 if (menu_width > width + x_min) { |
147 int dif = menu_width - width - x_min; | |
148 int n = x_size + 1; | |
149 x += dif/n; | |
150 for (i=0; i<x_size; i++) { | |
151 item_x[i] = x + item_width[i] / 2; | |
152 x += item_width[i] + dif*(i+2)/n - dif*(i+1)/n; | |
153 } | |
154 } else { | |
155 if (menu_width == 0) { | |
156 Pic()->SetSurfaceRect(Rect(0, 0, width+x_min, Pic()->Height())); | |
157 } | |
158 for (i=0; i<x_size; i++) { | |
159 item_x[i] = x + item_width[i] / 2; | |
160 x += item_width[i]; | |
161 } | |
162 } | |
163 if (menu_height > height+y_min) { | |
164 int dif = menu_height - height - y_min; | |
165 int n = y_size + 1; | |
166 y += dif/n; | |
167 for (i=0; i<y_size; i++) { | |
168 item_y[i] = y + item_height[i] / 2; | |
169 y += item_height[i] + dif*(i+2)/n - dif*(i+1)/n; | |
170 } | |
171 } else { | |
172 if (menu_height == 0) { | |
173 Pic()->SetSurfaceRect(Rect(0, 0, Pic()->Width(), height+y_min)); | |
174 } | |
175 for (i=0; i<y_size; i++) { | |
176 item_y[i] = y + item_height[i] / 2; | |
177 y += item_height[i]; | |
178 } | |
179 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
52
diff
changeset
|
180 // 位置の再割り当て |
0 | 181 it = item.begin(); |
182 for (i=0; i<y_size; i++) { | |
183 for (j=0; j<x_size; j++) { | |
52 | 184 if (*it != NULL && (*it)->Pic() != NULL) { |
0 | 185 PicBase* pic = (*it)->Pic(); |
186 int x0 = item_x[j]-pic->Width()/2; | |
187 int y0 = item_y[i]-pic->Height()/2; | |
188 pic->Move(x0, y0); | |
189 } | |
190 it++; | |
191 } | |
192 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
52
diff
changeset
|
193 // 左にラベルがある場合、ラベルの高さ方向のセンタリング |
0 | 194 if (label && label->Pic() && lb_width != -1) { |
195 int label_width = label->Pic()->Width(); | |
196 int label_height = label->Pic()->Height(); | |
197 label->Pic()->Move(x_min-label_width-lb_right, (Pic()->Height() - label_height) / 2); | |
198 } | |
199 | |
200 delete[] item_width; | |
201 delete[] item_height; | |
202 delete[] item_x; | |
203 delete[] item_y; | |
52 | 204 } |
0 | 205 |
206 RadioButton::RadioButton(Event::Container& _container, PicContainer* _parent, const Rect& r_orig, int _x_size, int _y_size, int* _value_ptr, const Rect& _button_r, int _text_size, const Color& _fore, const Color& _pressed, const Color& _back) : | |
207 MenuItem(_parent, r_orig, _x_size, _y_size,_value_ptr), | |
208 container(_container), parent(_parent), text_size(_text_size), button_rect(_button_r), buttons(0), | |
209 fore_color(_fore), pressed_color(_pressed), back_color(_back) { | |
210 } | |
52 | 211 |
0 | 212 void RadioButton::Add(const char* s, bool is_center) { |
213 Add(s, fore_color, pressed_color, back_color, is_center); | |
214 } | |
52 | 215 |
0 | 216 void RadioButton::Add(const char* s, const Color& fore, const Color& pressed, const Color& back, bool is_center) { |
217 if (buttons >= x_size*y_size) { | |
218 fprintf(stderr,"too many buttons (%d/%d) in RadioButton::Add ; text = %s\n",x_size,y_size,s); | |
219 return; | |
220 } | |
221 TextButton* wid = new TextButton(container, PicNode(), s, text_size, TextButton::Attribute(is_center ? TextButton::CENTER : 0), button_rect, 1, fore, pressed, back); | |
222 | |
223 wid->press_func = &PressCallback; | |
224 wid->press_pointer = (void*)this; | |
225 | |
226 if (value_ptr && buttons == *value_ptr) wid->Toggle(true); | |
227 int x_pos, y_pos; | |
228 if (y_size == 0) x_pos=buttons; | |
229 else x_pos = buttons / y_size, y_pos = buttons % y_size; | |
230 item[x_pos + y_pos*x_size] = wid; | |
231 buttons++; | |
52 | 232 } |
233 | |
0 | 234 void RadioButton::PressCallback(void* pointer, Button* from) { |
235 RadioButton* wid = (RadioButton*)pointer; | |
236 int i; | |
237 for (i=0; i<wid->x_size*wid->y_size; i++) { | |
238 if (from == wid->item[i]) { | |
239 wid->SetValue(i); | |
240 return; | |
241 } | |
242 } | |
243 } | |
52 | 244 |
0 | 245 void RadioButton::SetValueImpl(int new_value) { |
246 int i; | |
247 for (i=0; i<x_size*y_size; i++) { | |
248 Button* wid = dynamic_cast<Button*>(item[i]); | |
52 | 249 if (wid != NULL) { |
0 | 250 if (i == new_value) wid->Toggle(true); |
251 else wid->Toggle(false); | |
252 } | |
253 } | |
254 } |