OSDN Git Service

first
[psychlops/cpp.git] / psychlops / extension / standard / widgets / psychlops_widgets_prototype.cpp
1 /*
2  *  psychlops_figure_prototype.cpp
3  *  Psychlops Standard Library (Universal)
4  *
5  *  Last Modified 2005/10/05 by Kenchi HOSOKAWA
6  *  (C) 2005 Kenchi HOSOKAWA, Kazushi MARUYA, Takao SATO
7  */
8
9 #include "psychlops_widgets_prototype.h"
10 #include <stdio.h>
11 #include <string.h>
12
13
14 namespace Psychlops {
15 namespace Widgets {
16                 bool hook(Figure *f, bool on_off, Canvas *cnvs) {
17                         if(cnvs!=0) {
18                                 if(on_off) {
19                                         for(std::vector<Figure*>::iterator i=cnvs->billboard.begin(); i!=cnvs->billboard.end(); i++) {
20                                                 if(*i==f) { return false; }
21                                         }
22                                         cnvs->billboard.push_back(f);
23                                         return true;
24                                 } else {
25                                         for(std::vector<Figure*>::iterator i=cnvs->billboard.begin(); i!=cnvs->billboard.end(); i++) {
26                                                 if(*i==f) { cnvs->billboard.erase(i); return true; }
27                                         }
28                                 }
29                         }
30                         return false;
31                 }
32
33
34                 RectWidget::RectWidget() : Rectangle() {}
35 //              RectWidget::RectWidget(const double width__, const double height__) : left(0), top(0), right(width__), bottom(height__) {}
36 //              RectWidget::~RectWidget() {}
37 //              RectWidget& RectWidget::set(const double width__, const double height__) {
38         //              static_cast<double>(left) = 0.0;
39         //              static_cast<double>(top) = 0.0;
40         //              static_cast<double>(right) = width__;
41         //              static_cast<double>(bottom) = height__;
42 //                      return *this;
43 //              }
44 //              RectWidget& RectWidget::centering(const Point& p) { Rectangle::centering(p); return *this; }
45 //              RectWidget& RectWidget::centering(const Drawable& target) { Rectangle::centering(target); return *this; }
46 //              RectWidget& RectWidget::centering(const double x, const double y, const double z) { Rectangle::centering(x,y); return *this; }
47 //              RectWidget& RectWidget::shift(const double x, const double y, const double z) { Rectangle::shift(x,y); return *this; }
48
49
50                 Console::LetterStyle::LetterStyle() : line_height_(10) {};
51                 Console::Console() : RectWidget(), changed_(false), buffer(0), last_pos_(0) {
52                         fill = Color(0.2, 0.2, 0.6, 0.35);
53                         stroke = Stroke(Color::white, 2, Stroke::SOLID);
54                         textColor = Color::green;
55                 }
56                 Console::Console(const Rectangle &rect) : RectWidget(), changed_(false), buffer(0), last_pos_(0) {
57                         fill.set(0.2, 0.2, 0.6, 0.35);
58                         stroke = Stroke(Color::white, 2, Stroke::SOLID);
59                         textColor = Color::green;
60                         set(rect);
61                 }
62                 Console::Console(const double width, const double height) : RectWidget(), changed_(false), buffer(0), last_pos_(0) {
63                         fill.set(0.2, 0.2, 0.6, 0.35);
64                         stroke = Stroke(Color::white, 2, Stroke::SOLID);
65                         textColor = Color::green;
66                         set(width, height);
67                 }
68                 Console::~Console() {
69                         if(buffer!=0) delete [] buffer;
70                         hook(false);
71                         buffer = 0;
72                 }
73                 Console & Console::set(const Rectangle &rect) {
74                         if(buffer==0) buffer = new char[1024];
75                         Rectangle::set(rect);
76                         lines_.push_back(std::string());
77                         lines_.at(0) = File::decodePath("%TIME_") + "\r";
78                         view_.push_back(LineView(lines_.back(), 0, lines_.back().length()-1));
79                         lines_.push_back(std::string());
80                         view_.push_back(LineView(lines_.back(), 0, 0));
81                         changed_ = true;
82                         hook();
83                         return *this;
84                 }
85                 Console & Console::set(const double width, const double height) {
86                         return set(Rectangle(width, height));
87                 }
88                 Console & Console::hook(bool on_off, Canvas *cnvs) {
89                         Psychlops::Widgets::hook(this, on_off, cnvs);
90                         return *this;
91                 }
92                 Console & Console::draw(Drawable &target) { return draw(left, top, 0, target); }
93                 Console & Console::draw(const Color &col, Drawable &target) { return draw(left, top, 0, target); }
94                 Console & Console::draw(const Stroke &strk, Drawable &target) { return draw(left, top, 0, target); }
95                 Console & Console::draw(const double x, const double y, const double z, Drawable &target) {
96                         target.rect(*this, fill);
97                         target.rect(*this, stroke);
98                         devideStreamIntoLines();
99                         int line_c=0;
100                         for(std::deque<LineView>::iterator i=view_.begin(); i!=view_.end(); i++) {
101                                 Display::msg((i->target)->substr(i->begin, i->end - i->begin), x+4, y+12 + line_c*10, textColor, Letters::TEXT_ALIGN_LEFT, getWidth()-18);
102                                 line_c++;
103                         }
104                         return *this;
105                 }
106                 void Console::devideStreamIntoLines() {
107                         const int h_limit = ((int)getWidth()-15)/7, v_limit = (int)getHeight()/10-1;
108
109                         if(changed_) {
110                                 strings_.flush();
111                                 //while(!strings_.eof()) {
112                                         strings_.getline(buffer, 1024);
113                                         lines_.back() += buffer;
114                                         char last_char = lines_.back()[lines_.back().length()-1];
115                                         while(lines_.back().length()-last_pos_>h_limit) {
116                                                 last_pos_ = ((last_pos_/h_limit)+1)*h_limit;
117                                                 view_.back().end = last_pos_-1;
118                                                 view_.push_back(LineView(lines_.back(), last_pos_, last_pos_));
119                                                 if( view_.size()>v_limit ) view_.pop_front();
120                                         }
121                                         view_.back().end = lines_.back().length()-1;
122                                         if(last_char=='\r' || last_char=='\n') {
123                                                 lines_.push_back(std::string());
124                                                 view_.push_back(LineView(lines_.back(), 0, 0));
125                                                 last_pos_ = 0;
126                                                 if( view_.size()>v_limit ) view_.pop_front();
127                                         }
128                                 //}
129                                 strings_.clear();
130
131 /*                              int line_c=0, line_limit = getHeight()/8-2;
132                                 if(last_num_lines_ > line_limit) {
133                                         for(int i=lines_.size()-1; i>=0; i--) {
134                                                 line_c += lines_.at(i).lines_in_display_;
135                                                 if(line_c>line_limit) {
136                                                         last_begin_line_ = i+1;
137                                                         break;
138                                                 }
139                                         }
140                                 }
141  */
142                         }
143                         changed_ = false;
144                 }
145                 void Console::save(std::string filename) {
146                         std::ofstream f(File::decodePath(filename).c_str());
147                         for(int i=0; i<lines_.size(); i++) {
148                                 f << lines_.at(i);
149                         }
150                         f.close();
151                         return;
152                 }
153         Console::LineView::LineView() : target(0), begin(0), end(0) {}
154         Console::LineView::LineView(std::string &t, int b, int e) : target(&t), begin(b), end(e) {}
155
156
157
158
159                 HotKeyWidget::HotKeyWidget(const Keyboard::Key &init_key) : key(init_key), func(0) {}
160                 HotKeyWidget::~HotKeyWidget() { hook(this, false); }
161                 const Point HotKeyWidget::getDatum() const { return Point(0,0,0); }
162                 HotKeyWidget& HotKeyWidget::setDatum(const Point &p) { return *this; }
163                 HotKeyWidget& HotKeyWidget::centering(const Point &p) { return *this; }
164                 HotKeyWidget& HotKeyWidget::draw(Drawable &drawable) { return *this; }
165
166                 PauseHotKey::PauseHotKey(const Keyboard::Key &init_key) : HotKeyWidget(init_key) {}
167                 PauseHotKey& PauseHotKey::draw(Drawable &target) {
168                         AppState::ThreadPriority current = AppState::getThreadPriority();
169                         if(Input::get(key, Keyboard::pushed)) {
170                                 while(!Input::get(key, Keyboard::pushed)){
171                                         AppState::setThreadPriority(AppState::IDLE);
172                                 }
173                                 AppState::setThreadPriority(current);
174                         }
175                         return *this;
176                 }
177
178                 ExitHotKey::ExitHotKey(const Keyboard::Key &init_key) : HotKeyWidget(init_key) {
179                 }
180                 ExitHotKey& ExitHotKey::draw(Drawable &target) {
181                         if(Input::get(key, Keyboard::pushed)) {
182                                 exit(0);
183                         }
184                         return *this;
185                 }
186
187                 TabStopHotKey::TabStopHotKey() : HotKeyWidget(Keyboard::tab) {}
188                 TabStopHotKey::TabStopHotKey(const Keyboard::Key &init_key)  : HotKeyWidget(init_key) {
189                         registered = true;
190                 }
191                 void TabStopHotKey::set(void* target) {
192                         if(!registered) {
193                                 hook(this, true);
194                                 registered = true;
195                         }
196                         if(Display::the_canvas!=0) Display::the_canvas->eventroot.appendTabStop__(target);
197                 }
198                 TabStopHotKey& TabStopHotKey::draw(Drawable &target) {
199                         //StackPanel::default_stack.set(400, 1024);
200                         //StackPanel::default_stack.align();
201                         if(Keyboard::tab.pushed()) {
202                                 if(Display::the_canvas!=0)
203                                 {
204                                         if(Keyboard::shift.pressed() || Keyboard::shift_r.pressed())
205                                         {
206                                                 Display::the_canvas->eventroot.prevTabStop();
207                                         } else {
208                                                 Display::the_canvas->eventroot.nextTabStop();
209                                         }
210                                 }
211                         }
212                         return *this;
213                 }
214                 TabStopHotKey TabStopHotKey::tabStopHotKey;
215
216
217         bool MoviePlayer::auto_play = false;
218         MoviePlayer* MoviePlayer::now_playing = 0;
219         Prototype::Thread MoviePlayer::thread;
220         Canvas *MoviePlayer::cnvs = 0;
221         Canvas::CanvasMode MoviePlayer::mode;
222         Display *MoviePlayer::disp;
223
224         void MoviePlayer::paraThread()
225         {
226                 while(true)
227                 {
228                         if(Keyboard::esc.pressed())
229                         {
230                                 now_playing->stop();
231                         }
232                         Prototype::Thread::sleep(1);
233                 }
234         }
235
236         MoviePlayer::MoviePlayer()
237         {
238                 cnvs = 0;
239         }
240         MoviePlayer::MoviePlayer(Figures::Movie &movie)
241         {
242                 cnvs = 0;
243                 appendMovie(movie);
244         }
245         MoviePlayer::~MoviePlayer() {}
246
247         void MoviePlayer::appendMovie(Figures::Movie &movie)
248         {
249                 movies.push_back(&movie);
250         }
251
252         /*
253         void MoviePlayer::start(Canvas::CanvasMode mode_, const Display &disp_)
254         {
255                 if(!auto_play)
256                 {
257                         mode = mode_;
258                         disp = (Display*)&disp_;
259                         now_playing = this;
260                         auto_play = true;
261                         thread.create(&play_loop_in_this_thread);
262                 }
263         }
264         */
265         void MoviePlayer::start(Canvas& target)
266         {
267                 start(&paraThread, target);
268         }
269         void MoviePlayer::start(void (*func)(), Canvas& target)
270         {
271                 if(movies.size()!=1) return;
272                 if(!auto_play)
273                 {
274                         cnvs = &target;
275                         now_playing = this;
276                         auto_play = true;
277                         thread.create(func);
278                         play_loop();
279                 }
280         }
281         void MoviePlayer::play_loop_in_this_thread()
282         {
283                 Canvas c;
284                 c.set(mode, *disp);
285                 cnvs = &c;
286                 play_loop();
287         }
288         void MoviePlayer::play_loop()
289         {
290                 while(true)
291                 {
292                         if(!auto_play) break;
293                         //now_playing->movies[0].current_frame++;
294                         //now_playing->movies->current_frame %= now_playing->movies[0].frame.size();
295                         cnvs->clear();
296                         now_playing->movies[0]->draw(*cnvs);
297                         cnvs->flip();
298                 }
299         }
300         void MoviePlayer::stop()
301         {
302                 auto_play = false;
303         }
304
305                 SequentialScreenshot::SequentialScreenshot()
306                  : max_shot(0), current_shot(0), rec(false), saved(false), directory("%USER_DOCUMENTS%"), filePrefix("%EXPNAME__%TIME_") {
307                 }
308                 SequentialScreenshot::SequentialScreenshot(const Rectangle &rect)
309                  : max_shot(0), current_shot(0), rec(false), saved(false), directory("%USER_DOCUMENTS%"), filePrefix("%EXPNAME__%TIME_") {
310                         set(rect);
311                 }
312                 SequentialScreenshot::~SequentialScreenshot() {
313                         if(!saved) save();
314                         clear();
315                 }
316                 SequentialScreenshot& SequentialScreenshot::set(const Rectangle &rect) {
317                         if(movie.size()==0) {
318                                 source.set(rect);
319 //                              hook();
320                         }
321                         return *this;
322                 }
323                 SequentialScreenshot& SequentialScreenshot::set(const double width, const double height) {
324                         return set(Rectangle(width, height));
325                 }
326                 SequentialScreenshot& SequentialScreenshot::clear() {
327                         if(movie.size() != 0) {
328                                 for(int i=0; i<movie.size(); i++) {
329                                         delete movie[i];
330                                 }
331                                 movie.clear();
332                         }
333                         return *this;
334                 }
335                 SequentialScreenshot& SequentialScreenshot::hook(bool on_off, Canvas *cnvs) {
336                         Psychlops::Widgets::hook(this, on_off, cnvs);
337                         return *this;
338                 }
339                 SequentialScreenshot& SequentialScreenshot::record(int max_num_shots, std::string file_prefix) {
340                         if(max_num_shots<0) throw new Exception("SequentialScreenshot: max_num_shots should be a positive nunmber.");
341                         if(!rec) {
342                                 filePrefix = file_prefix;
343                                 max_shot = max_num_shots;
344                                 current_shot = 0;
345                                 if(max_num_shots!=0) {
346                                         movie.reserve(max_shot);
347                                         for(int i=0; i<max_shot; i++) {
348                                                 movie.push_back(new Image);
349                                         }
350                                 }
351                                 rec = true;
352                         }
353                         return *this;
354                 }
355                 const SequentialScreenshot& SequentialScreenshot::stop() {
356                         if(rec) {
357                                 rec = false;
358                                 if(Drawable::prime_is_a_canvas()) Display::msg("END", Display::getWidth()-5, 10, Color::red, Letters::TEXT_ALIGN_RIGHT);
359                         }
360                         return *this;
361                 }
362                 const SequentialScreenshot& SequentialScreenshot::save() {
363                         char buf[256];
364                         for(int i=0; i<movie.size(); i++) {
365                                 memset(buf, 0, 256);
366                                 sprintf(buf, "%u", i);
367                                 movie[i]->save(directory+'/'+filePrefix+"_"+buf+".png");
368                         }
369                         clear();
370                         saved = true;
371                         return *this;
372                 }
373                 SequentialScreenshot& SequentialScreenshot::draw(Drawable &target) {
374                         if(rec) {
375                                 if(max_shot==0) {
376                                         movie.push_back(new Image);
377                                         if(Drawable::prime_is_a_canvas()) dynamic_cast<Canvas *>(Drawable::prime)->to(*(movie[current_shot]), source);
378                                 } else if(current_shot<max_shot) {
379                                         if(Drawable::prime_is_a_canvas()) dynamic_cast<Canvas *>(Drawable::prime)->to(*(movie[current_shot]), source);
380                                 } else {
381                                         rec = false;
382                                         return *this;
383                                 }
384                                 current_shot++;
385                                 saved = false;
386                         }
387                         Rectangle rect;
388                         Color mean(0.5,0.4,0.4,0.5);
389                         Canvas* the_canvas = dynamic_cast<Canvas *>(Drawable::prime);
390                         if(the_canvas!=0) {
391                                 rect.set(0,0,the_canvas->getWidth(),source.getTop()).draw(mean);
392                                 rect.set(0,source.getTop()+1,source.getLeft(),source.getBottom()-1).draw(mean);
393                                 rect.set(source.getRight(),source.getTop()+1,the_canvas->getWidth(),source.getBottom()-1).draw(mean);
394                                 rect.set(0,source.getBottom(),the_canvas->getWidth(),the_canvas->getHeight()).draw(mean);
395                         }
396                         if(rec) {
397                                 if(Drawable::prime_is_a_canvas()) the_canvas->msg("@REC", Display::getWidth()-5, 10, Color::red, Letters::TEXT_ALIGN_RIGHT);
398                         } else {
399                                 if(Keyboard::shift.pressed() && Mouse::left.pressed()) source.set(Mouse::x, Mouse::y, source.getRight(), source.getBottom());
400                                 if(Keyboard::shift.pressed() && Mouse::right.pressed()) source.set(source.getLeft(), source.getTop(), Mouse::x, Mouse::y);
401                                 if(Drawable::prime_is_a_canvas()) the_canvas->msg("||STOP", Display::getWidth()-5, 10, Color::gray, Letters::TEXT_ALIGN_RIGHT);
402                         }
403
404                         return *this;
405                 }
406
407
408 /*
409                 Movie::Movie(const Rectangle &rect)
410                  : max_shot(0), current_shot(0), rec(false), saved(false), directory("%USER_DOCUMENTS%"), filePrefix("%EXPNAME__%TIME_") {
411                 }
412                 Movie::Movie(const Rectangle &rect)
413                  : max_shot(0), current_shot(0), rec(false), saved(false), directory("%USER_DOCUMENTS%"), filePrefix("%EXPNAME__%TIME_") {
414                         set(rect);
415                 }
416                 Movie::~Movie() {
417                         //if(!saved) save();
418                         clear();
419                 }
420                 Movie& Movie::set(const Rectangle &rect);
421                 Movie& Movie::set(const double width, const double height);
422                 Movie& Movie::load(size_t begin, size_t end) {
423                         saved = true;
424                         return *this;
425                 }
426                 Movie& Movie::load(const char* format, size_t begin, size_t end) {
427                         saved = true;
428                         return *this;
429                 }
430                 Movie& Movie::clear() {
431                         if(movie.size() != 0) {
432                                 for(int i=0; i<movie.size(); i++) {
433                                         delete movie[i];
434                                 }
435                                 movie.clear();
436                         }
437                         return *this;
438                 }
439                 Movie& Movie::hook(bool on_off, Canvas *cnvs);
440                 Movie& Movie::record(int max_num_shots, std::string file_prefix);
441                 Movie& Movie::seek(size_t frame);
442                 Movie& Movie::stop();
443                 Movie& const Movie::save(size_t begin, size_t end) {
444                         char buf[256];
445                         for(int i=0; i<movie.size(); i++) {
446                                 memset(buf, 0, 256);
447                                 sprintf(buf, "%u", i);
448                                 movie[i]->save(directory+'/'+filePrefix+"_"+buf+".png");
449                         }
450                         clear();
451                         saved = true;
452                         return *this;
453                 }
454                 Movie& const Movie::save(const char* format, size_t begin, size_t end) {
455                         char buf[256];
456                         for(int i=0; i<movie.size(); i++) {
457                                 memset(buf, 0, 256);
458                                 sprintf(buf, "%u", i);
459                                 movie[i]->save(directory+'/'+filePrefix+"_"+buf+".png");
460                         }
461                         clear();
462                         saved = true;
463                         return *this;
464                 }
465
466                 Movie& draw(Drawable &target);
467                 Movie& play(Drawable &target);
468 */
469
470
471
472 }       /*      <- namespace Widgets    */
473 }       /*      <- namespace Psycholops         */
474
475