ratio_layouted_frame.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011, Dirk Thomas, TU Darmstadt
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  *   * Redistributions of source code must retain the above copyright
00010  *     notice, this list of conditions and the following disclaimer.
00011  *   * Redistributions in binary form must reproduce the above
00012  *     copyright notice, this list of conditions and the following
00013  *     disclaimer in the documentation and/or other materials provided
00014  *     with the distribution.
00015  *   * Neither the name of the TU Darmstadt nor the names of its
00016  *     contributors may be used to endorse or promote products derived
00017  *     from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00022  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00023  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00024  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00025  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00026  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00027  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00028  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00029  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00030  * POSSIBILITY OF SUCH DAMAGE.
00031  */
00032 
00033 #include <rqt_image_view/ratio_layouted_frame.h>
00034 
00035 #include <assert.h>
00036 
00037 namespace rqt_image_view {
00038 
00039 RatioLayoutedFrame::RatioLayoutedFrame(QWidget* parent, Qt::WFlags flags)
00040   : QFrame()
00041   , aspect_ratio_(4, 3)
00042 {
00043   connect(this, SIGNAL(delayed_update()), this, SLOT(update()), Qt::QueuedConnection);
00044 }
00045 
00046 RatioLayoutedFrame::~RatioLayoutedFrame()
00047 {
00048 }
00049 
00050 const QImage& RatioLayoutedFrame::getImage() const
00051 {
00052   return qimage_;
00053 }
00054 
00055 QImage RatioLayoutedFrame::getImageCopy() const
00056 {
00057   QImage img;
00058   qimage_mutex_.lock();
00059   img = qimage_.copy();
00060   qimage_mutex_.unlock();
00061   return img;
00062 }
00063 
00064 void RatioLayoutedFrame::setImage(const QImage& image)//, QMutex* image_mutex)
00065 {
00066   qimage_mutex_.lock();
00067   qimage_ = image.copy();
00068   qimage_mutex_.unlock();
00069   setAspectRatio(qimage_.width(), qimage_.height());
00070   emit delayed_update();
00071 }
00072 
00073 void RatioLayoutedFrame::resizeToFitAspectRatio()
00074 {
00075   QRect rect = contentsRect();
00076 
00077   // reduce longer edge to aspect ration
00078   double width = double(rect.width());
00079   double height = double(rect.height());
00080   if (width * aspect_ratio_.height() / height > aspect_ratio_.width())
00081   {
00082     // too large width
00083     width = height * aspect_ratio_.width() / aspect_ratio_.height();
00084     rect.setWidth(int(width + 0.5));
00085   }
00086   else
00087   {
00088     // too large height
00089     height = width * aspect_ratio_.height() / aspect_ratio_.width();
00090     rect.setHeight(int(height + 0.5));
00091   }
00092 
00093   // resize taking the border line into account
00094   int border = lineWidth();
00095   resize(rect.width() + 2 * border, rect.height() + 2 * border);
00096 }
00097 
00098 void RatioLayoutedFrame::setInnerFrameMinimumSize(const QSize& size)
00099 {
00100   int border = lineWidth();
00101   QSize new_size = size;
00102   new_size += QSize(2 * border, 2 * border);
00103   setMinimumSize(new_size);
00104   emit delayed_update();
00105 }
00106 
00107 void RatioLayoutedFrame::setInnerFrameMaximumSize(const QSize& size)
00108 {
00109   int border = lineWidth();
00110   QSize new_size = size;
00111   new_size += QSize(2 * border, 2 * border);
00112   setMaximumSize(new_size);
00113   emit delayed_update();
00114 }
00115 
00116 void RatioLayoutedFrame::setInnerFrameFixedSize(const QSize& size)
00117 {
00118   setInnerFrameMinimumSize(size);
00119   setInnerFrameMaximumSize(size);
00120 }
00121 
00122 void RatioLayoutedFrame::setAspectRatio(unsigned short width, unsigned short height)
00123 {
00124   int divisor = greatestCommonDivisor(width, height);
00125   if (divisor != 0) {
00126     aspect_ratio_.setWidth(width / divisor);
00127     aspect_ratio_.setHeight(height / divisor);
00128   }
00129 }
00130 
00131 void RatioLayoutedFrame::paintEvent(QPaintEvent* event)
00132 {
00133   QPainter painter(this);
00134   qimage_mutex_.lock();
00135   if (!qimage_.isNull())
00136   {
00137     resizeToFitAspectRatio();
00138     // TODO: check if full draw is really necessary
00139     //QPaintEvent* paint_event = dynamic_cast<QPaintEvent*>(event);
00140     //painter.drawImage(paint_event->rect(), qimage_);
00141     painter.drawImage(contentsRect(), qimage_);
00142   } else {
00143     // default image with gradient
00144     QLinearGradient gradient(0, 0, frameRect().width(), frameRect().height());
00145     gradient.setColorAt(0, Qt::white);
00146     gradient.setColorAt(1, Qt::black);
00147     painter.setBrush(gradient);
00148     painter.drawRect(0, 0, frameRect().width() + 1, frameRect().height() + 1);
00149   }
00150   qimage_mutex_.unlock();
00151 }
00152 
00153 int RatioLayoutedFrame::greatestCommonDivisor(int a, int b)
00154 {
00155   if (b==0)
00156   {
00157     return a;
00158   }
00159   return greatestCommonDivisor(b, a % b);
00160 }
00161 
00162 }


rqt_image_view
Author(s): Dirk Thomas
autogenerated on Wed Sep 16 2015 06:57:52