urgViewDemo.cpp

00001 /*
00002   URGView のデモクラス
00003   Satofumi KAMIMURA
00004   $Id$
00005 */
00006 
00007 #include "urgViewDemo.h"
00008 #include "urgViewResource.h"
00009 #include "fileUtils.h"
00010 
00011 
00012 void URGViewDemo::URGViewProperty::evaluate(void) {
00013   const char* home_str = getenv("HOME");
00014   std::string home_path = std::string((home_str ? home_str : ".")) + "/.vxv";
00015   value(ttf_file, "ttf_path", (home_path + "/font.ttf").c_str());
00016 }
00017 
00018 
00019 URGViewDemo::URGViewDemo(void)
00020   : times_text(NULL), times_label(NULL),
00021     back(NULL), frame(NULL), button_back(NULL), button_focused_back(NULL),
00022     larger_text(NULL), larger_normal(NULL), larger_focused(NULL),
00023     smaller_text(NULL), smaller_normal(NULL), smaller_focused(NULL),
00024     quit_text(NULL), quit_normal(NULL), quit_focused(NULL), pause_text(NULL), 
00025     urg(NULL), view_offset(Grid(0, 0)), property(*new URGViewProperty()) {
00026   for (unsigned int i = 0; i < M_LINES; ++i) {
00027     m_surface[i] = NULL;
00028   }
00029 
00030   const char* home_str = getenv("HOME");
00031   std::string home_path = std::string((home_str ? home_str : ".")) + "/.vxv";
00032   const char* searchPath[] = { ".", home_path.c_str(), NULL };
00033   property.load("monitorconf", searchPath);
00034 
00035   // monitorconf からフォント位置の読み出し
00036   const char* dummyPath[] = { "", NULL };
00037   ttf_path = VXV::searchFile(property.ttf_file.c_str(), dummyPath);
00038   if (ttf_path.empty() && (ttf_path = searchTTF()).empty()) {
00039     printf("Please edit ttf_path in ~/.vxv/moniorconf\n");
00040   }
00041 }
00042 
00043 
00044 URGViewDemo::~URGViewDemo(void) {
00045   win->activate(false);
00046 
00047   delete times_text;
00048   delete back;
00049   delete frame;
00050   delete button_back;
00051   delete button_focused_back;
00052   delete larger_text;
00053   delete larger_normal;
00054   delete larger_focused;
00055   delete smaller_text;
00056   delete smaller_normal;
00057   delete smaller_focused;
00058   delete quit_text;
00059   delete quit_normal;
00060   delete quit_focused;
00061   delete pause_text;
00062   delete urg;
00063   for (unsigned int i = 0; i < M_LINES; ++i) {
00064     delete m_surface[i];
00065   }
00066 }
00067 
00068 
00069 void URGViewDemo::updateMagnify(double magnify) {
00070   view->updateMagnify(magnify);
00071   view->setViewToRangeGrid(view_offset,
00072                            Grid((win->w - FrameWidth)/2, win->h/2));
00073 
00074   sensed->updateMagnify(magnify);
00075   sensed->setViewToRangeGrid(view_offset,
00076                              Grid((win->w - FrameWidth)/2, win->h/2));
00077 
00078   // 単位の描画位置を調整
00079   for (unsigned int i = 0; i < M_LINES; ++i) {
00080     int x = (win->w -FrameWidth)/2 - static_cast<int>(magnify * view_offset.x);
00081     int y = win->h/2
00082       - static_cast<int>(magnify * view_offset.y + magnify * 1000*(i+1));
00083     m_label[i]->setPosition(Grid(x, y), Center | Middle);
00084   }
00085 }
00086 
00087 
00088 int URGViewDemo::Initialize(int argc, char *argv[]) {
00089 #ifdef Monitor
00090   urg = new mURGCtrl();
00091 #else
00092   urg = new URGCtrl();
00093 #endif
00094   int ret_value = urg->connect(argc, argv, false);
00095   if (ret_value < 0) {
00096     printf("URGCtrl::connect: %s\n", urg->what());
00097     return ret_value;
00098   }
00099   urg->adjustCrdPosition(Position(0, 0, Direction::deg(-90)));
00100 
00101   win->setTitle("URG View");
00102   win->activate(true);
00103 
00104   ttf = new TTF_Draw();
00105   ttf->load(ttf_path.c_str());
00106 
00107   // 画面の初期描画
00108   enum { FontSize = 22, };
00109   back = new FillSurface(Rect(win->w - FrameWidth, win->h), BackColor);
00110   win->add(new LabelComponent(back));
00111 
00112   // 補助線
00113   view = new ViewComponent(Rect(win->w -FrameWidth, win->h));
00114   int line_pos = static_cast<int>(10000 * sqrt(2) / 2.0);
00115   view->add(new LineDraw(Grid(0, 0),
00116                          Grid(+line_pos, -line_pos), LineColor));
00117   view->add(new LineDraw(Grid(0, 0),
00118                          Grid(-line_pos, -line_pos), LineColor));
00119   for (unsigned int i = 1; i <= M_LINES; ++i) {
00120     view->add(new CircleDraw(Grid(0, 0), 1000 * i, LineColor));
00121     for (unsigned int j = 1; j <= 9; ++j) {
00122       view->add(new CircleDraw(Grid(0, 0), 1000 * (i-1) + 100 * j, Gray7));
00123     }
00124   }
00125   base_magnify = win->h / 4000.0;
00126   int_magnify = 0;
00127   magnify_max = win->h / 400.0;
00128   magnify_min = win->h / 22000.0;
00129   win->add(view);
00130 
00131   // 距離単位のラベル
00132   for (unsigned int i = 0; i < M_LINES; ++i) {
00133     char text[] =  "XX[m]";
00134     sprintf(text, "%d[m]", i+1);
00135     m_surface[i] = new DrawSurface(ttf->createText(text, 16,
00136                                                    LineColor, BackColor));
00137     m_label[i] = new LabelComponent(m_surface[i]);
00138     win->add(m_label[i]);
00139   }
00140   // センサ値の表示用
00141   sensed = new ViewComponent(Rect(view->w, view->h));
00142   win->add(sensed);
00143 
00144   // フレーム
00145   frame = new FillSurface(Rect(win->w - FrameWidth, FrameWidth, 100, win->h),
00146                           Black);
00147   win->add((new LabelComponent(frame))
00148            ->setPosition(Grid(win->w - FrameWidth, 0)));
00149 
00150   // ボタン
00151   Rect button_size = Rect(0,0, 76, 24);
00152   button_back = new FillSurface(button_size, Gray6);
00153   button_focused_back = new FillSurface(button_size, Gray8);
00154 
00155   // 拡大ボタン
00156   larger_button = new ButtonComponent(button_size);
00157   larger_text = new DrawSurface(ttf->createText(Button_Larger,
00158                                                 FontSize, White, Gray7), true);
00159   larger_normal = new MultiSurface(button_size);
00160   larger_normal->addSurface(button_back);
00161   larger_normal->addSurface(larger_text, Center | Middle);
00162 
00163   larger_focused = new MultiSurface(button_size);
00164   larger_focused->addSurface(button_focused_back);
00165   larger_focused->addSurface(larger_text, Center | Middle);
00166 
00167   larger_button->setNormalSurface(larger_normal);
00168   larger_button->setFocusedSurface(larger_focused);
00169   larger_button->setPosition(Grid(win->w -12, 12), Right | Top);
00170   win->add(larger_button);
00171 
00172   // 縮小ボタン
00173   smaller_button = new ButtonComponent(button_size);
00174   smaller_text =
00175     new DrawSurface(ttf->createText(Button_Smaller,
00176                                     FontSize, White, Gray7), true);
00177   smaller_normal = new MultiSurface(button_size);
00178   smaller_normal->addSurface(button_back);
00179   smaller_normal->addSurface(smaller_text, Center | Middle);
00180 
00181   smaller_focused = new MultiSurface(button_size);
00182   smaller_focused->addSurface(button_focused_back);
00183   smaller_focused->addSurface(smaller_text, Center | Middle);
00184 
00185   smaller_button->setNormalSurface(smaller_normal);
00186   smaller_button->setFocusedSurface(smaller_focused);
00187   smaller_button->setPosition(Grid(win->w -12, 12 + button_size.h + 12),
00188                               Right | Top);
00189   win->add(smaller_button);
00190 
00191   // 終了ボタン
00192   quit_button = new ButtonComponent(button_size);
00193   quit_text = new DrawSurface(ttf->createText(Button_Quit,
00194                                               FontSize, White, Gray7), true);
00195 
00196   quit_normal = new MultiSurface(button_size);
00197   quit_normal->addSurface(button_back);
00198   quit_normal->addSurface(quit_text, Center | Middle);
00199 
00200   quit_focused = new MultiSurface(button_size);
00201   quit_focused->addSurface(button_focused_back);
00202   quit_focused->addSurface(quit_text, Center | Middle);
00203 
00204   quit_button->setNormalSurface(quit_normal);
00205   quit_button->setFocusedSurface(quit_focused);
00206   quit_button->setPosition(Grid(win->w -12, win->h -12), Right | Bottom);
00207   win->add(quit_button);
00208 
00209   // "pause" 文字
00210   pause_text =
00211     new DrawSurface(ttf->createText("Pause", 32, White, Gray7), true);
00212   updateMagnify(base_magnify);
00213 
00214   return 0;
00215 }
00216 
00217 
00218 int URGViewDemo::MainLoop(void) {
00219 
00220   UserInput::userInput_t ui;
00221   bool quit = false;
00222   bool pause = false;
00223   bool next = false;
00224   int times = 0;
00225   Grid drag_begin, drag_diff = Grid(0, 0);
00226   bool now_drag = false;
00227   do{
00228     // センサ値を取得
00229     if (!pause || next) {
00230       urg->capture();
00231       times = urg->getCaptureTimes();
00232       next = false;
00233     }
00234 
00235     // 入力処理
00236     win->lock();
00237     ui = UserInput::getInputed();
00238 
00239     // ドラッグ変位の作成
00240     if (ui.left_clicked) {
00241       if (ui.mpos.x < (win->w - FrameWidth)) {
00242         drag_begin = ui.mpos;
00243         now_drag = true;
00244       }
00245     }
00246     if (ui.left_released && now_drag) {
00247       now_drag = false;
00248       if (ui.mpos.x < (win->w - FrameWidth)) {
00249         drag_diff = ui.mpos - drag_begin;
00250       }
00251     }
00252 
00253     // 終了判定
00254     quit = ui.quit | quit_button->isPressed();
00255 
00256     // カーソルによる表示範囲のスクロール
00257     double magnify = base_magnify * pow(1.3, int_magnify);
00258     int scroll = static_cast<int>(50 / magnify);
00259     Grid pre_offset = view_offset;
00260     if (ui.isPressedCode(SDLK_UP)) {
00261       view_offset.y -= scroll;
00262     } else if (ui.isPressedCode(SDLK_DOWN)) {
00263       view_offset.y += scroll;
00264     } else if (ui.isPressedCode(SDLK_RIGHT)) {
00265       view_offset.x += scroll;
00266     } else if (ui.isPressedCode(SDLK_LEFT)) {
00267       view_offset.x -= scroll;
00268     }
00269 
00270     // マウスドラッグによる表示範囲のスクロール
00271     view_offset -= Grid(static_cast<int>(drag_diff.x / magnify),
00272                         static_cast<int>(drag_diff.y / magnify));
00273     drag_diff = Grid(0, 0);
00274 
00275     // 改行で表示範囲を標準状態に設定
00276     if (ui.isPressedCode(SDLK_RETURN)) {
00277       view_offset = Grid(0, 0);
00278       int_magnify = 0;
00279     }
00280 
00281     // スペースによる一時停止
00282     if (ui.isPressed(' ')) {
00283       pause = !pause;
00284       if (pause) {
00285         win->add((new LabelComponent(pause_text))
00286                  ->setPosition(Grid(10,10)), LogLevel);
00287       } else {
00288         win->clear(LogLevel);
00289       }
00290     }
00291     // 一時停止時のコマ送り
00292     if (ui.isPressedCode(SDLK_n)) {
00293       next = true;
00294     }
00295 
00296     // 拡大、縮小の処理
00297     int magnify_diff = ui.wheel_moved
00298       + ((larger_button->isPressed() || ui.isPressed('0')) ? +1 : 0)
00299       + ((smaller_button->isPressed() || ui.isPressed('9')) ? -1 : 0);
00300     if (magnify_diff ||
00301         (view_offset.x != pre_offset.x || view_offset.y != pre_offset.y)) {
00302       if ((magnify_diff < 0) && (magnify > magnify_min)) {
00303         --int_magnify;
00304       } else if ((magnify_diff > 0) && (magnify < magnify_max)) {
00305         ++int_magnify;
00306       }
00307       double next_magnify = base_magnify * pow(1.3, int_magnify);
00308       if ((next_magnify < magnify_max) || (next_magnify > magnify_min)) {
00309         if (ui.wheel_moved) {
00310           // 拡大、縮小時に、カーソル位置の座標を移動させない
00311           view_offset.x += static_cast<int>((ui.mpos.x - (win->w-FrameWidth)/2)
00312                                             * (1/magnify - 1/next_magnify));
00313           view_offset.y += static_cast<int>((ui.mpos.y - win->h/2)
00314                                             * (1/magnify -  1/next_magnify));
00315         }
00316         magnify = next_magnify;
00317         updateMagnify(magnify);
00318       }
00319     }
00320 
00321     // 表示センサデータの更新
00322     urg->convert();
00323     sensed->clear();
00324     for (std::vector<Grid3D>::iterator it = urg->crd_points.begin();
00325          it != urg->crd_points.end(); ++it) {
00326       sensed->add(new PixelDraw(-it->x, -it->y, Red));
00327     }
00328 
00329     // ticks の描画
00330     if (times_text) {
00331       win->del(times_label, LogLevel);
00332       delete times_text;
00333     }
00334     char times_str[20];
00335     sprintf(times_str, "%d [capture]", times);
00336     times_text =
00337       new DrawSurface(ttf->createText(times_str, 24, White, Gray7), true);
00338     times_label = new LabelComponent(times_text);
00339     win->add(times_label
00340              ->setPosition(Grid(win->w - FrameWidth - 8 - times_text->w,
00341                                 win->h -8), Bottom), LogLevel);
00342     win->unlock();
00343 
00344     SDL_Delay(10);
00345   } while (!quit);
00346 
00347   win->activate(false);
00348   return 0;
00349 }
00350 

Generated on Mon Apr 13 22:52:02 2009 by  doxygen 1.5.7.1