Mercurial > otakunoraifu
annotate window/menuitem.cc @ 66:d112357a0ec1
Fix a bug with savegames introduced with changeset c7bcc0ec2267.
Warning: savegames created since c7bcc0ec2267 are probably corrupted,
you may have to start the game over.
If you chose not to do so, you should replace all occurrences of 'TextWindow' by 'TextImplWindow',
and 'Text Window' by 'TextImpl Window' in your save files.
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Sat, 11 Dec 2010 18:36:20 +0100 |
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 } |