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 void RatioLayoutedFrame::setImage(const QImage& image)//, QMutex* image_mutex)
00056 {
00057   qimage_mutex_.lock();
00058   qimage_ = image.copy();
00059   qimage_mutex_.unlock();
00060   setAspectRatio(qimage_.width(), qimage_.height());
00061   emit delayed_update();
00062 }
00063 
00064 void RatioLayoutedFrame::resizeToFitAspectRatio()
00065 {
00066   QRect rect = contentsRect();
00067 
00068   // reduce longer edge to aspect ration
00069   double width = double(rect.width());
00070   double height = double(rect.height());
00071   if (width * aspect_ratio_.height() / height > aspect_ratio_.width())
00072   {
00073     // too large width
00074     width = height * aspect_ratio_.width() / aspect_ratio_.height();
00075     rect.setWidth(int(width));
00076   }
00077   else
00078   {
00079     // too large height
00080     height = width * aspect_ratio_.height() / aspect_ratio_.width();
00081     rect.setHeight(int(height));
00082   }
00083 
00084   // resize taking the border line into account
00085   int border = lineWidth();
00086   resize(rect.width() + 2 * border, rect.height() + 2 * border);
00087 }
00088 
00089 void RatioLayoutedFrame::setInnerFrameMinimumSize(const QSize& size)
00090 {
00091   int border = lineWidth();
00092   QSize new_size = size;
00093   new_size += QSize(2 * border, 2 * border);
00094   setMinimumSize(new_size);
00095   emit delayed_update();
00096 }
00097 
00098 void RatioLayoutedFrame::setInnerFrameMaximumSize(const QSize& size)
00099 {
00100   int border = lineWidth();
00101   QSize new_size = size;
00102   new_size += QSize(2 * border, 2 * border);
00103   setMaximumSize(new_size);
00104   emit delayed_update();
00105 }
00106 
00107 void RatioLayoutedFrame::setInnerFrameFixedSize(const QSize& size)
00108 {
00109   setInnerFrameMinimumSize(size);
00110   setInnerFrameMaximumSize(size);
00111 }
00112 
00113 void RatioLayoutedFrame::setAspectRatio(unsigned short width, unsigned short height)
00114 {
00115   int divisor = greatestCommonDivisor(width, height);
00116   if (divisor != 0) {
00117     aspect_ratio_.setWidth(width / divisor);
00118     aspect_ratio_.setHeight(height / divisor);
00119   }
00120 }
00121 
00122 void RatioLayoutedFrame::paintEvent(QPaintEvent* event)
00123 {
00124   QPainter painter(this);
00125   qimage_mutex_.lock();
00126   if (!qimage_.isNull())
00127   {
00128     resizeToFitAspectRatio();
00129     // TODO: check if full draw is really necessary
00130     //QPaintEvent* paint_event = dynamic_cast<QPaintEvent*>(event);
00131     //painter.drawImage(paint_event->rect(), qimage_);
00132     painter.drawImage(contentsRect(), qimage_);
00133   } else {
00134     // default image with gradient
00135     QLinearGradient gradient(0, 0, frameRect().width(), frameRect().height());
00136     gradient.setColorAt(0, Qt::white);
00137     gradient.setColorAt(1, Qt::black);
00138     painter.setBrush(gradient);
00139     painter.drawRect(0, 0, frameRect().width() + 1, frameRect().height() + 1);
00140   }
00141   qimage_mutex_.unlock();
00142 }
00143 
00144 int RatioLayoutedFrame::greatestCommonDivisor(int a, int b)
00145 {
00146   if (b==0)
00147   {
00148     return a;
00149   }
00150   return greatestCommonDivisor(b, a % b);
00151 }
00152 
00153 }


rqt_image_view
Author(s): Dirk Thomas
autogenerated on Mon Oct 6 2014 07:15:02