src/GradientEditor.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 2005-2007 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the demonstration applications of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://trolltech.com/products/qt/licenses/licensing/opensource/
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
00017 ** or contact the sales department at sales@trolltech.com.
00018 **
00019 ** In addition, as a special exception, Trolltech gives you certain
00020 ** additional rights. These rights are described in the Trolltech GPL
00021 ** Exception version 1.0, which can be found at
00022 ** http://www.trolltech.com/products/qt/gplexception/ and in the file
00023 ** GPL_EXCEPTION.txt in this package.
00024 **
00025 ** In addition, as a special exception, Trolltech, as the sole copyright
00026 ** holder for Qt Designer, grants users of the Qt/Eclipse Integration
00027 ** plug-in the right for the Qt/Eclipse Integration to link to
00028 ** functionality provided by Qt Designer and its related libraries.
00029 **
00030 ** Trolltech reserves all rights not expressly granted herein.
00031 ** 
00032 ** Trolltech ASA (c) 2007
00033 **
00034 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00035 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00036 **
00037 ****************************************************************************/
00038 
00039 #include "GradientEditor.h"
00040 #include "HoverPoints.h"
00041 #include <fstream>
00042 #include <QWidget>
00043 
00044 static int start = 0;
00045 
00046 GradientEditor::GradientEditor(QWidget *parent, Qt::WindowFlags flags)
00047     : QWidget(parent, flags)
00048 {
00049     printf("creating GradientEditor\n");
00050     
00051     setWindowTitle("Transferfunktion");
00052     m_parent = parent;
00053 
00054     vbox = new QVBoxLayout(this);
00055     vbox->setSpacing(1);
00056     vbox->setMargin(1);
00057 
00058     m_red_shade   = new ShadeWidget(ShadeWidget::RedShade,   this, "red"   );
00059     m_green_shade = new ShadeWidget(ShadeWidget::GreenShade, this, "green" );
00060     m_blue_shade  = new ShadeWidget(ShadeWidget::BlueShade,  this, "blue"  );
00061     m_alpha_shade = new ShadeWidget(ShadeWidget::ARGBShade,  this, "alpha" );
00062 
00063     vbox->addWidget( m_red_shade   );
00064     vbox->addWidget( m_green_shade );
00065     vbox->addWidget( m_blue_shade  );
00066     vbox->addWidget( m_alpha_shade, 3 );
00067 
00068     connect(m_red_shade,   SIGNAL( colorsChanged() ), this, SLOT( pointsUpdated() ));
00069     connect(m_green_shade, SIGNAL( colorsChanged() ), this, SLOT( pointsUpdated() ));
00070     connect(m_blue_shade,  SIGNAL( colorsChanged() ), this, SLOT( pointsUpdated() ));
00071     connect(m_alpha_shade, SIGNAL( colorsChanged() ), this, SLOT( pointsUpdated() ));
00072 
00073     if(start++)
00074       show();
00075 }
00076 
00077 //void GradientEditor::setRenderer(GradientRenderer* renderer)
00078 //{
00079 //  vbox->addWidget(renderer, 1);
00080 //}
00081 
00082 inline static bool x_less_than(const QPointF &p1, const QPointF &p2)
00083 {
00084     return p1.x() < p2.x();
00085 }
00086 
00087 
00088 
00089 void GradientEditor::pointsUpdated()
00090 {
00091     double w = m_alpha_shade->width();
00092 
00093     QGradientStops stops;
00094 
00095     QPolygonF points;
00096 
00097     points += m_red_shade->points();
00098     points += m_green_shade->points();
00099     points += m_blue_shade->points();
00100     points += m_alpha_shade->points();
00101 
00102     qSort(points.begin(), points.end(), x_less_than);
00103 
00104     for (int i=0; i<points.size(); ++i) 
00105     {
00106         double x = int( points.at(i).x() );
00107 
00108         if ( i < points.size()-1 && x == points.at(i+1).x() )
00109             continue;
00110 
00111         // ??
00112         QColor color((0x00ff0000 & m_red_shade->colorAt(int(x))) >> 16,
00113                      (0x0000ff00 & m_green_shade->colorAt(int(x))) >> 8,
00114                      (0x000000ff & m_blue_shade->colorAt(int(x))),
00115                      (0xff000000 & m_alpha_shade->colorAt(int(x))) >> 24);
00116 /*
00117             std::cout << "color: " <<
00118               ", R: " << color.red()   <<
00119               ", G: " << color.green() <<
00120               ", B: " << color.blue()  <<
00121               ", A: " << color.alpha() << std::endl;
00122 */
00123 
00124         if (x / w > 1)
00125             return;
00126 
00127         stops << QGradientStop(x / w, color);
00128     }
00129 
00130     m_alpha_shade->setGradientStops(stops);
00131 
00132     emit gradientStopsChanged(stops);
00133 }
00134 
00135 void GradientEditor::showHistogram(const int *density)
00136 {
00137   m_alpha_shade->setHistogram(density);
00138   this->update();
00139 }
00140 
00141 void GradientEditor::clearHistogram()
00142 {
00143   m_alpha_shade->clearHistogram();
00144   this->update();
00145 
00146 }
00147 
00148 
00149 static void set_shade_points(const QPolygonF &points, ShadeWidget *shade)
00150 {
00151     shade->hoverPoints()->setPoints(points);
00152     shade->hoverPoints()->setPointLock(0, HoverPoints::LockToLeft);
00153     shade->hoverPoints()->setPointLock(points.size() - 1, HoverPoints::LockToRight);
00154     shade->update();
00155 }
00156 
00157 void GradientEditor::setGradientStops(const QGradientStops &stops)
00158 {
00159     QPolygonF pts_red, pts_green, pts_blue, pts_alpha;
00160 
00161     double h_red = m_red_shade->height();
00162     double h_green = m_green_shade->height();
00163     double h_blue = m_blue_shade->height();
00164     double h_alpha = m_alpha_shade->height();
00165 
00166     for (int i=0; i<stops.size(); ++i) {
00167         double pos = stops.at(i).first;
00168         QRgb color = stops.at(i).second.rgba();
00169         pts_red << QPointF(pos * m_red_shade->width(), h_red - qRed(color) * h_red / 255);
00170         pts_green << QPointF(pos * m_green_shade->width(), h_green - qGreen(color) * h_green / 255);
00171         pts_blue << QPointF(pos * m_blue_shade->width(), h_blue - qBlue(color) * h_blue / 255);
00172         pts_alpha << QPointF(pos * m_alpha_shade->width(), h_alpha - qAlpha(color) * h_alpha / 255);
00173     }
00174 
00175     set_shade_points(pts_red, m_red_shade);
00176     set_shade_points(pts_green, m_green_shade);
00177     set_shade_points(pts_blue, m_blue_shade);
00178     set_shade_points(pts_alpha, m_alpha_shade);
00179 }
00180 
00181 void GradientEditor::loadTransferFunction( std::string filename )
00182 {
00183   ShadeWidget* shades[SHADES_COUNT] = { m_red_shade, m_green_shade, m_blue_shade, m_alpha_shade };
00184   QPolygonF pts;
00185   QGradientStops stops;
00186   int shadeIndex = -1;
00187   float px, py;
00188   std::string line, num;
00189 
00190   // Load file
00191   std::ifstream in(filename.c_str());
00192 
00193   if(!in)
00194     std::cerr << "- Error opening file!" << std::endl << std::endl;
00195 
00196   while(std::getline(in, line))
00197   {
00198     // find name of shade channel
00199     for(int s = 0; s < SHADES_COUNT; s++)
00200     {
00201       if(!line.compare(shades[s]->getName()))
00202       {
00203         if(shadeIndex != -1)
00204         {
00205           shades[shadeIndex]->setPoints(pts);
00206           shades[shadeIndex]->update();
00207           pts.clear();
00208         }
00209 
00210         // set current channel
00211         shadeIndex = s;
00212         break;
00213       }
00214     } // for
00215 
00216     if(isdigit(line.at(0)))
00217     {
00218       sscanf_s(line.c_str(), "%f %f\n", &px, &py);
00219       pts << QPointF(px, py);
00220     }
00221 
00222   } // while
00223 
00224   // set alpha value and update widget
00225   shades[ALPHA]->setPoints(pts);
00226   pointsUpdated();
00227 }
00228 
00229 void GradientEditor::saveTransferFunction( std::string filename )
00230 {
00231   ShadeWidget* shades[SHADES_COUNT] = { m_red_shade, m_green_shade, m_blue_shade, m_alpha_shade };
00232   QGradientStops stops;
00233   QPolygonF pts;  
00234   int px, py;
00235 
00236   FILE *fp = NULL;
00237         fopen_s( &fp, filename.c_str(), "w" );
00238 
00239   if(!fp)
00240     std::cerr << "- Error saving file!" << std::endl << std::endl;
00241 
00242   // Write TF to file
00243   for( int s = 0; s < SHADES_COUNT; s++ )
00244   {
00245     // Set name in file 
00246     fprintf(fp, "%s\n", shades[s]->getName().c_str());
00247     
00248     pts = shades[s]->points();
00249     stops = shades[s]->getGradientStops();
00250    
00251     // save control points
00252     for( int i = 0; i < pts.size(); i++ )
00253     {
00254       px = (int) pts.at(i).x();
00255       py = (int) pts.at(i).y();
00256       fprintf(fp, "%d %d\n", px, py);
00257     }
00258   }
00259 
00260   fclose(fp);
00261 }

Generated on Mon Dec 10 18:18:11 2007 for VisLU by  doxygen 1.5.4