Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <rqt_image_view/ratio_layouted_frame.h>
00034
00035 #include <assert.h>
00036 #include <QMouseEvent>
00037
00038 namespace rqt_image_view {
00039
00040 RatioLayoutedFrame::RatioLayoutedFrame(QWidget* parent, Qt::WindowFlags flags)
00041 : QFrame()
00042 , outer_layout_(NULL)
00043 , aspect_ratio_(4, 3)
00044 , smoothImage_(false)
00045 {
00046 connect(this, SIGNAL(delayed_update()), this, SLOT(update()), Qt::QueuedConnection);
00047 }
00048
00049 RatioLayoutedFrame::~RatioLayoutedFrame()
00050 {
00051 }
00052
00053 const QImage& RatioLayoutedFrame::getImage() const
00054 {
00055 return qimage_;
00056 }
00057
00058 QImage RatioLayoutedFrame::getImageCopy() const
00059 {
00060 QImage img;
00061 qimage_mutex_.lock();
00062 img = qimage_.copy();
00063 qimage_mutex_.unlock();
00064 return img;
00065 }
00066
00067 void RatioLayoutedFrame::setImage(const QImage& image)
00068 {
00069 qimage_mutex_.lock();
00070 qimage_ = image.copy();
00071 setAspectRatio(qimage_.width(), qimage_.height());
00072 qimage_mutex_.unlock();
00073 emit delayed_update();
00074 }
00075
00076 void RatioLayoutedFrame::resizeToFitAspectRatio()
00077 {
00078 QRect rect = contentsRect();
00079
00080
00081 double width;
00082 double height;
00083
00084 if (outer_layout_)
00085 {
00086 width = outer_layout_->contentsRect().width();
00087 height = outer_layout_->contentsRect().height();
00088 }
00089 else
00090 {
00091
00092
00093
00094 width = rect.width();
00095 height = rect.height();
00096 }
00097
00098 double layout_ar = width / height;
00099 const double image_ar = double(aspect_ratio_.width()) / double(aspect_ratio_.height());
00100 if (layout_ar > image_ar)
00101 {
00102
00103 width = height * image_ar;
00104 }
00105 else
00106 {
00107
00108 height = width / image_ar;
00109 }
00110 rect.setWidth(int(width + 0.5));
00111 rect.setHeight(int(height + 0.5));
00112
00113
00114 int border = lineWidth();
00115 resize(rect.width() + 2 * border, rect.height() + 2 * border);
00116 }
00117
00118 void RatioLayoutedFrame::setOuterLayout(QHBoxLayout* outer_layout)
00119 {
00120 outer_layout_ = outer_layout;
00121 }
00122
00123 void RatioLayoutedFrame::setInnerFrameMinimumSize(const QSize& size)
00124 {
00125 int border = lineWidth();
00126 QSize new_size = size;
00127 new_size += QSize(2 * border, 2 * border);
00128 setMinimumSize(new_size);
00129 emit delayed_update();
00130 }
00131
00132 void RatioLayoutedFrame::setInnerFrameMaximumSize(const QSize& size)
00133 {
00134 int border = lineWidth();
00135 QSize new_size = size;
00136 new_size += QSize(2 * border, 2 * border);
00137 setMaximumSize(new_size);
00138 emit delayed_update();
00139 }
00140
00141 void RatioLayoutedFrame::setInnerFrameFixedSize(const QSize& size)
00142 {
00143 setInnerFrameMinimumSize(size);
00144 setInnerFrameMaximumSize(size);
00145 }
00146
00147 void RatioLayoutedFrame::setAspectRatio(unsigned short width, unsigned short height)
00148 {
00149 int divisor = greatestCommonDivisor(width, height);
00150 if (divisor != 0) {
00151 aspect_ratio_.setWidth(width / divisor);
00152 aspect_ratio_.setHeight(height / divisor);
00153 }
00154 }
00155
00156 void RatioLayoutedFrame::paintEvent(QPaintEvent* event)
00157 {
00158 QPainter painter(this);
00159 qimage_mutex_.lock();
00160 if (!qimage_.isNull())
00161 {
00162 resizeToFitAspectRatio();
00163
00164
00165
00166 if (!smoothImage_) {
00167 painter.drawImage(contentsRect(), qimage_);
00168 } else {
00169 if (contentsRect().width() == qimage_.width()) {
00170 painter.drawImage(contentsRect(), qimage_);
00171 } else {
00172 QImage image = qimage_.scaled(contentsRect().width(), contentsRect().height(),
00173 Qt::KeepAspectRatio, Qt::SmoothTransformation);
00174 painter.drawImage(contentsRect(), image);
00175 }
00176 }
00177 } else {
00178
00179 QLinearGradient gradient(0, 0, frameRect().width(), frameRect().height());
00180 gradient.setColorAt(0, Qt::white);
00181 gradient.setColorAt(1, Qt::black);
00182 painter.setBrush(gradient);
00183 painter.drawRect(0, 0, frameRect().width() + 1, frameRect().height() + 1);
00184 }
00185 qimage_mutex_.unlock();
00186 }
00187
00188 int RatioLayoutedFrame::greatestCommonDivisor(int a, int b)
00189 {
00190 if (b==0)
00191 {
00192 return a;
00193 }
00194 return greatestCommonDivisor(b, a % b);
00195 }
00196
00197 void RatioLayoutedFrame::mousePressEvent(QMouseEvent * mouseEvent)
00198 {
00199 if(mouseEvent->button() == Qt::LeftButton)
00200 {
00201 emit mouseLeft(mouseEvent->x(), mouseEvent->y());
00202 }
00203 QFrame::mousePressEvent(mouseEvent);
00204 }
00205
00206 void RatioLayoutedFrame::onSmoothImageChanged(bool checked) {
00207 smoothImage_ = checked;
00208 }
00209
00210 }