All Classes Namespaces Files Functions Variables Enumerations Enumerator
programs/UrgViewer/RangeViewWidget.cpp
Go to the documentation of this file.
00001 
00010 #include "RangeViewWidget.h"
00011 #include "CaptureSettingWidget.h"
00012 #include "RangeSensorParameter.h"
00013 #include "MathUtils.h"
00014 #include <QPainter>
00015 
00016 using namespace qrk;
00017 using namespace std;
00018 
00019 
00020 struct RangeViewWidget::pImpl
00021 {
00022   RangeViewWidget* widget_;
00023   CaptureSettingWidget* widget_parent_;
00024 
00025   bool is_parameter_loaded_;
00026   RangeSensorParameter parameter_;
00027 
00028   int first_index_;
00029   int last_index_;
00030 
00031 
00032   pImpl(RangeViewWidget* widget, CaptureSettingWidget* widget_parent)
00033     : widget_(widget), widget_parent_(widget_parent),
00034       is_parameter_loaded_(false), first_index_(0), last_index_(0)
00035   {
00036   }
00037 
00038 
00039   void initializeForm(void)
00040   {
00041     widget_->setMinimumSize(200, 200);
00042     widget_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
00043 
00044     connect(widget_parent_, SIGNAL(rangeChanged(int, int)),
00045             widget_, SLOT(isRangeChanged(int, int)));
00046   }
00047 
00048 
00049   double index2rad(int index)
00050   {
00051     int index_from_front = index - parameter_.area_front;
00052     return index_from_front * (2.0 * M_PI) / parameter_.area_total;
00053   }
00054 
00055 
00056   QPoint calculatePoint(int radius, double radian)
00057   {
00058     int x = static_cast<int>(radius * cos(radian));
00059     int y = static_cast<int>(radius * sin(radian));
00060 
00061     return QPoint(x, y);
00062   }
00063 };
00064 
00065 
00066 RangeViewWidget::RangeViewWidget(CaptureSettingWidget* parent)
00067   : QWidget(parent), pimpl(new pImpl(this, parent))
00068 {
00069   pimpl->initializeForm();
00070 }
00071 
00072 
00073 RangeViewWidget::~RangeViewWidget(void)
00074 {
00075 }
00076 
00077 
00078 void RangeViewWidget::paintEvent(QPaintEvent* event)
00079 {
00080   static_cast<void>(event);
00081 
00082   QPainter painter;
00083   painter.begin(this);
00084   QRect this_rect = rect();
00085   painter.fillRect(this_rect, QBrush(QColor(Qt::white)));
00086   painter.drawRect(0, 0, this_rect.width() - 1, this_rect.height() - 1);
00087 
00088   // !!! 最初にオブジェクトを作って使いまわすように変更すべき
00089   enum { FontSize = 12 };
00090   QFont font("times", FontSize);
00091   QFontMetrics fm(font);
00092   size_t text_height = fm.height();
00093   size_t text_width = fm.width("-XXX[deg]");
00094 
00095   const int offset = 2;
00096   int width_radius = (this_rect.width() / 2) - text_width - offset;
00097   int height_radius = (this_rect.height() / 2) - (text_height * 2) - offset;
00098 
00099   // 円の描画
00100   painter.setPen(QColor(Qt::gray));
00101   size_t radius = min(width_radius, height_radius);
00102   QPoint center(this_rect.width() / 2, this_rect.height() / 2);
00103   int cx = center.x() - radius;
00104   int cy = center.y() - radius;
00105   painter.drawEllipse(cx, cy,
00106                       static_cast<int>(radius * 2.02),
00107                       static_cast<int>(radius * 2.02));
00108 
00109   // X 軸, Y 軸の描画
00110   painter.drawLine(offset, center.y(), this_rect.width() - offset, center.y());
00111   painter.drawLine(center.x(), offset, center.x(), this_rect.height() - offset);
00112 
00113   if (! pimpl->is_parameter_loaded_) {
00114     painter.setPen(QColor(Qt::black));
00115     painter.drawText(0, 0, this_rect.width(), this_rect.height() / 2,
00116                      Qt::AlignVCenter | Qt::AlignHCenter,
00117                      tr("no range parameters."));
00118     return;
00119   }
00120 
00121   // 選択範囲の描画
00122   // !!! first, last の共通部分をまとめる
00123   painter.setPen(Qt::black);
00124   double first_radian = pimpl->index2rad(pimpl->first_index_) + (M_PI / 2.0);
00125   double last_radian = pimpl->index2rad(pimpl->last_index_) + (M_PI / 2.0);
00126   QPoint first_point =
00127     pimpl->calculatePoint(radius + (offset * 2), first_radian);
00128   QPoint last_point =
00129     pimpl->calculatePoint(radius + (text_height / 2) + offset, last_radian);
00130   first_point.setY(-first_point.y());
00131   first_point += center;
00132   last_point.setY(-last_point.y());
00133   last_point += center;
00134 
00135   // !!! 表示用と描画用の角度計算まわりは実装し直すこと
00136   int first_deg = lrint(first_radian * 180.0 / M_PI) - 90;
00137   int last_deg = lrint(last_radian * 180.0 / M_PI) - 90;
00138 
00139   // 楕円の描画
00140   painter.setBrush(QColor(0x33, 0x77, 0xff));
00141   painter.drawPie(cx, cy, radius * 2, radius * 2,
00142                   (first_deg + 90) * 16, (last_deg - first_deg) * 16);
00143 
00144   painter.drawText(first_point.x() + (offset * 3),
00145                    first_point.y() - (text_height / 2),
00146                    text_width, text_height,
00147                    Qt::AlignLeft | Qt::AlignBottom,
00148                    tr("%1[deg]").arg(first_deg));
00149 
00150   painter.drawText(last_point.x() - text_width,
00151                    last_point.y() - (text_height / 2),
00152                    text_width, text_height,
00153                    Qt::AlignRight | Qt::AlignBottom,
00154                    tr("%1[deg]").arg(last_deg));
00155 
00156   painter.end();
00157 }
00158 
00159 
00160 void RangeViewWidget::isRangeChanged(int first_index, int last_index)
00161 {
00162   pimpl->first_index_ = first_index;
00163   pimpl->last_index_ = last_index;
00164 
00165   repaint();
00166 }
00167 
00168 
00169 void RangeViewWidget::setParameter(const qrk::RangeSensorParameter& parameter)
00170 {
00171   pimpl->parameter_ = parameter;
00172   pimpl->is_parameter_loaded_ = true;
00173 
00174   repaint();
00175 }
00176