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 #include"SDL.h"
|
|
29 #include"event.h"
|
|
30 #include<vector>
|
|
31 #include<list>
|
|
32 #include<algorithm>
|
|
33 #include<iostream>
|
|
34 #include<sys/stat.h>
|
|
35
|
|
36 using namespace std;
|
|
37
|
|
38 extern bool save_req = false, load_req = false, grpdump_req = false; // scn2k/scn2k_impl.cc: キーボードからセーブ・ロードできるように
|
|
39 extern bool pressAreq=false,pressFreq=false,pressDreq=false;
|
|
40 namespace Event {
|
|
41 /* Impl: struct Event::Video */
|
|
42
|
|
43 Video::Video(Container& container) : region(0, 0, 0, 0), z(0), parent(container) {
|
|
44 activated = false;
|
|
45 parent.Add(this);
|
|
46 }
|
|
47 Video::Video(Container& container, const Rect& init_rect) : region(init_rect), z(0), parent(container) {
|
|
48 activated = false;
|
|
49 parent.Add(this);
|
|
50 }
|
|
51 Video::Video(Container& container, const Rect& init_rect, int _z) : region(init_rect), z(_z), parent(container) {
|
|
52 activated = false;
|
|
53 parent.Add(this);
|
|
54 }
|
|
55 Video::~Video() {
|
|
56 parent.Delete(this);
|
|
57 };
|
|
58 void Video::SetRegion(const Rect& new_rect) {
|
|
59 region = new_rect;
|
|
60 }
|
|
61 void Video::SetZ(int new_z) {
|
|
62 z = new_z;
|
|
63 }
|
|
64 void Video::activate(void) {
|
|
65 activated = true;
|
|
66 }
|
|
67 void Video::deactivate(void) {
|
|
68 activated = false;
|
|
69 }
|
|
70 inline int Video::point_in(int x, int y) {
|
|
71 if (!activated) return -1;
|
|
72 if (region.point_in(x,y)) return z;
|
|
73 else return -1;
|
|
74 }
|
|
75
|
|
76 /* カーソルの動く順序:上、左の順に準位付け */
|
|
77 bool operator <(const Video& pos1, const Video& pos2) {
|
|
78 if (pos1.region.ty < pos2.region.ty) return true;
|
|
79 if (pos1.region.ty == pos2.region.ty) return pos1.region.lx < pos2.region.lx;
|
|
80 if (pos1.region.by >= pos2.region.by) return pos1.region.lx <= pos2.region.lx;
|
|
81 return false;
|
|
82 }
|
|
83
|
|
84
|
|
85 /* Impl: struct Event::Time */
|
|
86 Time::Time(Container& container) : wakeup_time(container.current_time), parent(container) {
|
|
87 parent.Add(this);
|
|
88 }
|
|
89 Time::~Time() {
|
|
90 parent.Delete(this);
|
|
91 }
|
|
92 /* Define: struct Event::ContainerImpl */
|
|
93
|
|
94 struct ContainerImplTime_Item {
|
|
95 Time* instance;
|
|
96 bool valid;
|
|
97 bool operator ==(Time* const& to) const {
|
|
98 return to == instance;
|
|
99 }
|
|
100 ContainerImplTime_Item(Time* _time) :
|
|
101 instance(_time), valid(true) {
|
|
102 }
|
|
103 };
|
|
104
|
|
105 class ContainerImplTime : private vector<ContainerImplTime_Item> {
|
|
106 public:
|
|
107 ContainerImplTime(void);
|
|
108 bool Exec(unsigned int current_time);
|
|
109 void Add(Time* new_event);
|
|
110 void Delete(Time* delete_event);
|
|
111 private:
|
|
112 static vector<ContainerImplTime_Item> new_item;
|
|
113 unsigned int prev_execed_time;
|
|
114 static bool is_invalid(const_reference value) {
|
|
115 return !value.valid;
|
|
116 }
|
|
117 };
|
|
118
|
|
119 vector<ContainerImplTime_Item> ContainerImplTime::new_item;
|
|
120
|
|
121 ContainerImplTime::ContainerImplTime(void) {
|
|
122 prev_execed_time = 0;
|
|
123 }
|
|
124 void ContainerImplTime::Add(Time* event) {
|
|
125 ContainerImplTime_Item item(event);
|
|
126 new_item.push_back(item);
|
|
127 }
|
|
128 void ContainerImplTime::Delete(Time* delete_event) {
|
|
129 iterator it = find(begin(), end(), delete_event);
|
|
130 if (it != end()) {
|
|
131 it->valid = false;
|
|
132 it->instance = 0;
|
|
133 return;
|
|
134 }
|
|
135 it = find(new_item.begin(), new_item.end(), delete_event);
|
|
136 if (it != end()) {
|
|
137 it->valid = false;
|
|
138 it->instance = 0;
|
|
139 return;
|
|
140 }
|
|
141 return;
|
|
142 }
|
|
143 bool ContainerImplTime::Exec(unsigned int current_time) {
|
|
144 if (current_time == Time::NEVER_WAKE) return true;
|
|
145 // 呼び出しまでに作製されたitemを追加
|
|
146 insert(end(), new_item.begin(), new_item.end());
|
|
147 new_item.clear();
|
|
148 if (empty()) return true;
|
|
149 if (current_time == Time::FRAME_UPDATE) { // ビデオフレームの更新時
|
|
150 for (iterator it = begin(); it != end(); it++) {
|
|
151 if (! it->valid) continue;
|
|
152
|
|
153 unsigned tm = it->instance->Wakeup();
|
|
154 if (tm == Time::FRAME_UPDATE) {
|
|
155 it->instance->Elapsed(prev_execed_time);
|
|
156 }
|
|
157 }
|
|
158 } else { // 時間変化時
|
|
159 if (current_time < prev_execed_time) prev_execed_time = 0; /* 時間が一回りして0に戻ったとき */
|
|
160 for (iterator it = begin(); it != end(); it++) {
|
|
161 if (! it->valid) continue;
|
|
162 unsigned tm = it->instance->Wakeup();
|
|
163 if (tm >= prev_execed_time && tm < current_time) {
|
|
164 it->instance->Elapsed(current_time);
|
|
165 }
|
|
166 }
|
|
167 prev_execed_time = current_time;
|
|
168 }
|
|
169 // 処理中に削除された item を実際に削除
|
|
170 erase(remove_if(begin(), end(), is_invalid), end());
|
|
171 return true;
|
|
172 }
|
|
173
|
|
174
|
|
175 class ContainerImplVideo : private vector<Video*> {
|
|
176 public:
|
|
177 bool Exec(void);
|
|
178
|
|
179 ContainerImplVideo(void);
|
|
180 ~ContainerImplVideo();
|
|
181 void Add(Video* item);
|
|
182 void Delete(Video* item);
|
|
183 void RegisterGlobalMotionFunc(Container::motionfunc, void* pointer);
|
|
184 void DeleteGlobalMotionFunc(Container::motionfunc, void* pointer);
|
|
185 void RegisterGlobalPressFunc(Container::motionfunc, void* pointer);
|
|
186 void DeleteGlobalPressFunc(Container::motionfunc, void* pointer);
|
|
187 private:
|
|
188 struct Motionfunc {
|
|
189 Container::motionfunc func;
|
|
190 void* pointer;
|
|
191 bool operator ==(const Motionfunc& m) const { return func == m.func && pointer == m.pointer;}
|
|
192 };
|
|
193 list<Motionfunc> motion_vec;
|
|
194 list<Motionfunc> press_vec;
|
|
195 typedef list<Motionfunc>::iterator MotionIterator;
|
|
196 bool is_sorted;
|
|
197 public:
|
|
198 int button_pressed;
|
|
199 int button_released;
|
|
200 int mouse_x, mouse_y;
|
|
201 int new_mouse_x, new_mouse_y;
|
|
202 private:
|
|
203 void SetChanged(void);
|
|
204 static bool SortLess(const Video* pos1, const Video* pos2) {
|
|
205 return pos1 < pos2;
|
|
206 }
|
|
207 void Sort(void);
|
|
208 void Motion(int x, int y); // mouse motion
|
|
209 void Press(void);
|
|
210 void TakeScreenshot(void);
|
|
211 iterator cur_pos;
|
|
212 Video* cur_item; // 現在のフォーカス位置
|
|
213 int cur_pressed_x, cur_pressed_y;
|
|
214 };
|
|
215
|
|
216 void ContainerImplVideo::SetChanged(void) {
|
|
217 if (is_sorted) {
|
|
218 if (cur_item) {
|
|
219 cur_pos = find(begin(), end(), cur_item);
|
|
220 if (cur_pos == end()) cur_item = 0;
|
|
221 }
|
|
222 is_sorted = false;
|
|
223 }
|
|
224 }
|
|
225
|
|
226 void ContainerImplVideo::Sort(void) {
|
|
227 sort(begin(), end(), SortLess);
|
|
228 if (cur_item) {
|
|
229 cur_pos = lower_bound(begin(), end(), cur_item, SortLess);
|
|
230 } else {
|
|
231 cur_pos = end();
|
|
232 }
|
|
233 is_sorted = true;
|
|
234 }
|
|
235
|
|
236 ContainerImplVideo::ContainerImplVideo(void) {
|
|
237 is_sorted = false;
|
|
238 button_pressed = 0;
|
|
239 button_released = 0;
|
|
240 cur_item = 0;
|
|
241 mouse_x = 0; mouse_y = 0;
|
|
242 new_mouse_x = 0; new_mouse_y = 0;
|
|
243 }
|
|
244 ContainerImplVideo::~ContainerImplVideo(void) {
|
|
245 };
|
|
246 void ContainerImplVideo::Add(Video* event) {
|
|
247 push_back(event);
|
|
248 SetChanged();
|
|
249 }
|
|
250 void ContainerImplVideo::Delete(Video* delete_event) {
|
|
251 iterator it = find(begin(), end(), delete_event);
|
|
252 if (it != end()) {
|
|
253 erase(it);
|
|
254 SetChanged();
|
|
255 } else {
|
|
256 fprintf(stderr,"\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n");
|
|
257 fprintf(stderr,"X ContainerImplVideo: Cannot delete node %x\n",delete_event);
|
|
258 fprintf(stderr,"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n\n");
|
|
259 fprintf(stderr,"vector from:\n");
|
|
260 for(it=begin(); it!=end(); it++) {
|
|
261 fprintf(stderr,"%x, ",*it);
|
|
262 }
|
|
263 fprintf(stderr,"\n");
|
|
264 }
|
|
265 if (delete_event == cur_item) {
|
|
266 cur_pos = end();
|
|
267 cur_item = 0;
|
|
268 Motion(mouse_x, mouse_y);
|
|
269 }
|
|
270 return;
|
|
271 }
|
|
272 void ContainerImplVideo::RegisterGlobalMotionFunc(Container::motionfunc func, void* pointer) {
|
|
273 Motionfunc f;
|
|
274 f.func = func;
|
|
275 f.pointer = pointer;
|
|
276 if (find(motion_vec.begin(), motion_vec.end(), f) == motion_vec.end()) {
|
|
277 motion_vec.push_back(f);
|
|
278 }
|
|
279 }
|
|
280 void ContainerImplVideo::DeleteGlobalMotionFunc(Container::motionfunc func, void* pointer) {
|
|
281 Motionfunc f;
|
|
282 f.func = func;
|
|
283 f.pointer = pointer;
|
|
284 list<Motionfunc>::iterator it = find(motion_vec.begin(), motion_vec.end(), f);
|
|
285 if (it != motion_vec.end())
|
|
286 motion_vec.erase(it);
|
|
287 return;
|
|
288 }
|
|
289 void ContainerImplVideo::RegisterGlobalPressFunc(Container::motionfunc func, void* pointer) {
|
|
290 Motionfunc f;
|
|
291 f.func = func;
|
|
292 f.pointer = pointer;
|
|
293 if (find(press_vec.begin(), press_vec.end(), f) == press_vec.end()) {
|
|
294 press_vec.push_back(f);
|
|
295 }
|
|
296 }
|
|
297 void ContainerImplVideo::DeleteGlobalPressFunc(Container::motionfunc func, void* pointer) {
|
|
298 Motionfunc f;
|
|
299 f.func = func;
|
|
300 f.pointer = pointer;
|
|
301 list<Motionfunc>::iterator it = find(press_vec.begin(), press_vec.end(), f);
|
|
302 if (it != press_vec.end())
|
|
303 press_vec.erase(it);
|
|
304 return;
|
|
305 }
|
|
306 void ContainerImplVideo::Motion(int x, int y) {
|
|
307 mouse_x = x; mouse_y = y;
|
|
308 MotionIterator mit;
|
|
309 for (mit=motion_vec.begin(); mit != motion_vec.end();) {
|
|
310 MotionIterator mit_next = mit;
|
|
311 mit_next++;
|
|
312 if (!(*mit->func)(x, y, mit->pointer)) motion_vec.erase(mit);
|
|
313 mit = mit_next;
|
|
314
|
|
315 }
|
|
316
|
|
317 /* @@@ ドラッグ処理とマウスを押す処理のバッティングで「二回ボタンを押さないと云々」関連のバグの可能性あり */
|
|
318 if (button_pressed & (1<<MOUSE_LEFT)) {
|
|
319 if (cur_item) cur_item->Drag(cur_pressed_x, cur_pressed_y, x, y);
|
|
320 return;
|
|
321 }
|
|
322 if (cur_item) cur_item->Motion(x,y);
|
|
323 int z = -1; iterator z_it;
|
|
324 iterator it;
|
|
325 for (it = begin(); it != end(); it++) {
|
|
326 int new_z = (*it)->point_in(x, y);
|
|
327 if (z < new_z) {
|
|
328 z = new_z;
|
|
329 z_it = it;
|
|
330 }
|
|
331 }
|
|
332 if (z != -1) {
|
|
333 if (cur_item == *z_it) return;
|
|
334 if (cur_item) cur_item->Out();
|
|
335 cur_pos = z_it;
|
|
336 cur_item = *z_it;
|
|
337 cur_item->In();
|
|
338 return;
|
|
339 } else {
|
|
340 if (cur_item) cur_item->Out();
|
|
341 cur_pos = end();
|
|
342 cur_item = 0;
|
|
343 }
|
|
344 return;
|
|
345 }
|
|
346
|
|
347 void ContainerImplVideo::Press(void) {
|
|
348 if (cur_item) {
|
|
349 cur_pressed_x = mouse_x;
|
|
350 cur_pressed_y = mouse_y;
|
|
351 cur_item->Press();
|
|
352 return;
|
|
353 }
|
|
354 MotionIterator mit;
|
|
355 for (mit=press_vec.begin(); mit != press_vec.end(); ) {
|
|
356 MotionIterator mit_next = mit;
|
|
357 mit_next++;
|
|
358 if (!(*mit->func)(mouse_x, mouse_y, mit->pointer)) {
|
|
359 press_vec.erase(mit);
|
|
360 }
|
|
361 mit = mit_next;
|
|
362 }
|
|
363 }
|
|
364 void ContainerImplVideo::TakeScreenshot(void) {
|
|
365 int n=0;
|
|
366 char filename[1024];
|
|
367 struct stat buffer;
|
|
368 for(n=0; n<9999; n++) {
|
|
369 // XXX: put screenshots in a seperate dir?
|
|
370 sprintf(filename, "xclannad_%04i.bmp", n);
|
|
371 if(stat(filename, &buffer) == -1) break;
|
|
372 }
|
|
373 SDL_SaveBMP(SDL_GetVideoSurface(), filename);
|
|
374 }
|
|
375 bool ContainerImplVideo::Exec(void) {
|
|
376
|
|
377 bool is_mouse_motion = false;
|
|
378 int motion_x = 0, motion_y = 0;
|
|
379 SDL_Event event;
|
|
380 SDL_PumpEvents();
|
|
381 while(SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_ALLEVENTS) == 1) {
|
|
382 switch(event.type) {
|
|
383 case SDL_QUIT: return false; // @@@ なにかやらないと
|
|
384 case SDL_ACTIVEEVENT: // なにもしない
|
|
385 // cout<<"active : gain "<<int(event.active.gain)<<", state "<<int(event.active.state)<<endl;
|
|
386 break;
|
|
387 case SDL_KEYDOWN:
|
|
388 if (!is_sorted) Sort();
|
|
389 switch(event.key.keysym.sym) {
|
|
390 case SDLK_F12:
|
|
391 case SDLK_PRINT:
|
|
392 case SDLK_p: // for Zaurus
|
|
393 TakeScreenshot();
|
|
394 break;
|
|
395 // Some window managers (eg enlightenment) use Alt-Enter for
|
|
396 // themselves, F11 is a good alternative
|
|
397 case SDLK_F11:
|
|
398 SDL_WM_ToggleFullScreen(SDL_GetVideoSurface());
|
|
399 break;
|
|
400 case SDLK_RETURN:
|
|
401 if (SDL_GetModState() & KMOD_ALT) {
|
|
402 SDL_WM_ToggleFullScreen(SDL_GetVideoSurface());
|
|
403 break;
|
|
404 }
|
|
405 case SDLK_SPACE:
|
|
406 Press();
|
|
407 break;
|
|
408 case SDLK_TAB: // move to next widget
|
|
409 if (cur_pos != end()) cur_pos++;
|
|
410 if (cur_pos == end()) cur_pos = begin();
|
|
411 if (cur_pos != end()) {
|
|
412 cur_item = *cur_pos;
|
|
413 cur_item->In();
|
|
414 } else {
|
|
415 cur_item = 0;
|
|
416 }
|
|
417 break;
|
|
418 case SDLK_LEFT: if (cur_pos != end()) (*cur_pos)->KeyLeft(); break;
|
|
419 case SDLK_RIGHT:if (cur_pos != end()) (*cur_pos)->KeyRight(); break;
|
|
420 case SDLK_LSHIFT: case SDLK_RSHIFT: button_pressed |= (1<<KEY_SHIFT); break;
|
|
421 case SDLK_ESCAPE: button_pressed |= (1<<MOUSE_RIGHT); break; /* for Zaurus */
|
|
422 case SDLK_s: save_req = true; break;
|
|
423 case SDLK_l: load_req = true; break;
|
|
424 case SDLK_g: grpdump_req = true; break;
|
|
425 case SDLK_a: pressAreq = true; break;
|
|
426 case SDLK_d: pressDreq = true; break;
|
|
427 case SDLK_f: pressFreq = true; break;
|
|
428 }
|
|
429 break;
|
|
430 case SDL_KEYUP:
|
|
431 // cout << "keyup which "<<int(event.key.which)<<", sym "<<int(event.key.keysym.sym)<<endl;
|
|
432 switch(event.key.keysym.sym) {
|
|
433 case SDLK_RETURN: case SDLK_SPACE:
|
|
434 if (cur_item) cur_item->Release();
|
|
435 case SDLK_LSHIFT: case SDLK_RSHIFT: button_pressed &= ~(1<<KEY_SHIFT); button_released |= 1<<KEY_SHIFT; break;
|
|
436 case SDLK_ESCAPE: button_pressed &= ~(1<<MOUSE_RIGHT); button_released |= 1<<MOUSE_RIGHT; break; /* for Zaurus */
|
|
437 }
|
|
438 break;
|
|
439 case SDL_MOUSEMOTION:
|
|
440 motion_x = event.motion.x;
|
|
441 motion_y = event.motion.y;
|
|
442 is_mouse_motion = true;
|
|
443 // Motion(event.motion.x, event.motion.y);
|
|
444 // cout<< "motion which "<<int(event.motion.which)<<
|
|
445 // "x "<<event.motion.x << "y "<<event.motion.y<<endl;
|
|
446 break;
|
|
447 case SDL_MOUSEBUTTONUP:
|
|
448 if (event.button.button == 1) {
|
|
449 Motion(event.button.x, event.button.y);
|
|
450 is_mouse_motion = false;
|
|
451 if (cur_item) cur_item->Release();
|
|
452 }
|
|
453 switch(event.button.button) {
|
|
454 case 1: button_pressed &= ~(1<<MOUSE_LEFT); button_released |= 1<<MOUSE_LEFT; break;
|
|
455 case 2: button_pressed &= ~(1<<MOUSE_MIDDLE); button_released |= 1<<MOUSE_MIDDLE; break;
|
|
456 case 3: button_pressed &= ~(1<<MOUSE_RIGHT); button_released |= 1<<MOUSE_RIGHT; break;
|
|
457 case 4: button_pressed &= ~(1<<MOUSE_UP); button_released |= 1<<MOUSE_UP; break;
|
|
458 case 5: button_pressed &= ~(1<<MOUSE_DOWN); button_released |= 1<<MOUSE_DOWN; break;
|
|
459 }
|
|
460 break;
|
|
461 case SDL_MOUSEBUTTONDOWN:
|
|
462 if (event.button.button == 1) {
|
|
463 Motion(event.button.x, event.button.y);
|
|
464 is_mouse_motion = false;
|
|
465 Press();
|
|
466 }
|
|
467 switch(event.button.button) {
|
|
468 case 1: button_pressed |= (1<<MOUSE_LEFT); break;
|
|
469 case 2: button_pressed |= (1<<MOUSE_MIDDLE); break;
|
|
470 case 3: button_pressed |= (1<<MOUSE_RIGHT); break;
|
|
471 case 4: button_pressed |= (1<<MOUSE_UP); break;
|
|
472 case 5: button_pressed |= (1<<MOUSE_DOWN); break;
|
|
473 }
|
|
474 // cout << "mouse which "<<int(event.button.which)<<"button "<<int(event.button.button)<<
|
|
475 // "state "<<int(event.button.state)<<"x "<<event.button.x << "y "<<event.button.y<<endl;
|
|
476 break;
|
|
477 case SDL_VIDEOEXPOSE: // redraw の必要がある?
|
|
478 // cout<<"expose."<<endl;
|
|
479 break;
|
|
480 }
|
|
481 }
|
|
482 // Motion 呼び出しは一回だけ
|
|
483 if (is_mouse_motion)
|
|
484 Motion(motion_x, motion_y);
|
|
485 return true;
|
|
486 };
|
|
487 /* Impl: struct Event::Container */
|
|
488 Container::Container(void) {
|
|
489 pimpl_video = new ContainerImplVideo;
|
|
490 try {
|
|
491 pimpl_time = new ContainerImplTime;
|
|
492 } catch(...) {
|
|
493 delete pimpl_video;
|
|
494 throw;
|
|
495 }
|
|
496 button_pressed = 0;
|
|
497 current_time = 0;
|
|
498 int i; for (i=0; i<BUTTON_MAX; i++) button_presscount[i] = 0;
|
|
499 return;
|
|
500 }
|
|
501 Container::~Container(void) {
|
|
502 delete pimpl_video;
|
|
503 delete pimpl_time;
|
|
504 }
|
|
505 void Container::Add(Video* item) {
|
|
506 pimpl_video->Add(item);
|
|
507 }
|
|
508 void Container::Delete(Video* item) {
|
|
509 pimpl_video->Delete(item);
|
|
510 }
|
|
511 void Container::Add(Time* item) {
|
|
512 pimpl_time->Add(item);
|
|
513 }
|
|
514 void Container::Delete(Time* item) {
|
|
515 pimpl_time->Delete(item);
|
|
516 }
|
|
517 void Container::RegisterGlobalMotionFunc(Container::motionfunc f, void* pointer) {
|
|
518 pimpl_video->RegisterGlobalMotionFunc(f, pointer);
|
|
519 }
|
|
520 void Container::DeleteGlobalMotionFunc(Container::motionfunc f, void* pointer) {
|
|
521 pimpl_video->DeleteGlobalMotionFunc(f, pointer);
|
|
522 }
|
|
523 void Container::RegisterGlobalPressFunc(Container::motionfunc f, void* pointer) {
|
|
524 pimpl_video->RegisterGlobalPressFunc(f, pointer);
|
|
525 }
|
|
526 void Container::DeleteGlobalPressFunc(Container::motionfunc f, void* pointer) {
|
|
527 pimpl_video->DeleteGlobalPressFunc(f, pointer);
|
|
528 }
|
|
529 bool Container::Exec(unsigned int time) {
|
|
530 current_time = time;
|
|
531 bool ret = true;
|
|
532 ret = ret && pimpl_video->Exec();
|
|
533 ret = ret && pimpl_time->Exec(time);
|
|
534 int i; int mask = 1;
|
|
535 int new_button_pressed = pimpl_video->button_pressed;
|
|
536 for (i=0; i<BUTTON_MAX; i++) {
|
|
537 if (pimpl_video->button_released&mask) {
|
|
538 button_presscount[i]++;
|
|
539 }
|
|
540 mask <<= 1;
|
|
541 }
|
|
542 pimpl_video->button_released = 0;
|
|
543 button_pressed = pimpl_video->button_pressed;
|
|
544 return ret;
|
|
545 }
|
|
546
|
|
547 void Container::MousePos(int& x, int& y) {
|
|
548 x = pimpl_video->mouse_x;
|
|
549 y = pimpl_video->mouse_y;
|
|
550 }
|
|
551
|
|
552 bool Container::pressed(int mask) {
|
|
553 if (mask < 0 || mask >= BUTTON_MAX) return 0;
|
|
554 return (button_pressed & (1<<mask)) != 0;
|
|
555 }
|
|
556 bool Container::presscount(int mask) {
|
|
557 if (mask < 0 || mask >= BUTTON_MAX) return 0;
|
|
558 int count = button_presscount[mask];
|
|
559 button_presscount[mask] = 0;
|
|
560 return count;
|
|
561 }
|
|
562
|
|
563 }; /* end of namespace Container */
|
|
564
|
|
565 // 問題:
|
|
566 // z 軸と xy 軸の相互干渉;高速化
|
|
567 // 移動するウィジット描画の高速化
|
|
568 // キャッシュ
|
|
569 // 文字列の一部のみ更新の高速化
|
|
570 // 「階層 z で x なる領域無効化、y なる領域生成」で良い?>Expose
|