-rw-r--r-- | noncore/graphics/opie-eye/gui/imagescrollview.cpp | 185 | ||||
-rw-r--r-- | noncore/graphics/opie-eye/gui/imagescrollview.h | 23 |
2 files changed, 199 insertions, 9 deletions
diff --git a/noncore/graphics/opie-eye/gui/imagescrollview.cpp b/noncore/graphics/opie-eye/gui/imagescrollview.cpp index 019f376..0d35354 100644 --- a/noncore/graphics/opie-eye/gui/imagescrollview.cpp +++ b/noncore/graphics/opie-eye/gui/imagescrollview.cpp @@ -1,77 +1,247 @@ #include "imagescrollview.h" #include <opie2/odebug.h> using namespace Opie::Core; #include <qimage.h> #include <qlayout.h> -ImageScrollView::ImageScrollView (const QImage&img, QWidget * parent, const char * name, WFlags f) - :QScrollView(parent,name,f|Qt::WRepaintNoErase),_image_data(img) +ImageScrollView::ImageScrollView (const QImage&img, QWidget * parent, const char * name, WFlags f,bool always_scale,bool rfit) + :QScrollView(parent,name,f|Qt::WRepaintNoErase),_image_data(),_original_data(img),scale_to_fit(always_scale), + rotate_to_fit(rfit),first_resize_done(false) { init(); } -ImageScrollView::ImageScrollView (const QString&img, QWidget * parent, const char * name, WFlags f) - :QScrollView(parent,name,f|Qt::WRepaintNoErase),_image_data(img) +ImageScrollView::ImageScrollView (const QString&img, QWidget * parent, const char * name, WFlags f,bool always_scale,bool rfit) + :QScrollView(parent,name,f|Qt::WRepaintNoErase),_image_data(),_original_data(img),scale_to_fit(always_scale), + rotate_to_fit(rfit),first_resize_done(false) { init(); } void ImageScrollView::setImage(const QImage&img) { - _image_data = img; + _image_data = QImage(); + _original_data=img; + first_resize_done = false; init(); } /* should be called every time the QImage changed it content */ void ImageScrollView::init() { viewport()->setBackgroundColor(white); - resizeContents(_image_data.width(),_image_data.height()); + if (_original_data.size().isValid()) { + resizeContents(_original_data.width(),_original_data.height()); + } + last_rot = Rotate0; } ImageScrollView::~ImageScrollView() { } +void ImageScrollView::rescaleImage(int w, int h) +{ + if (_image_data.width()==w && _image_data.height()==h) { + return; + } + double hs = (double)h / (double)_image_data.height() ; + double ws = (double)w / (double)_image_data.width() ; + double scaleFactor = (hs > ws) ? ws : hs; + int smoothW = (int)(scaleFactor * _image_data.width()); + int smoothH = (int)(scaleFactor * _image_data.height()); + _image_data = _image_data.smoothScale(smoothW,smoothH); +} + +void ImageScrollView::rotate_into_data(Rotation r) +{ + /* realy - we must do this that way, 'cause when acting direct on _image_data the app will + segfault :( */ + QImage dest; + int x, y; + if ( _original_data.depth() > 8 ) + { + unsigned int *srcData, *destData; + switch ( r ) + { + case Rotate90: + dest.create(_original_data.height(), _original_data.width(), _original_data.depth()); + for ( y=0; y < _original_data.height(); ++y ) + { + srcData = (unsigned int *)_original_data.scanLine(y); + for ( x=0; x < _original_data.width(); ++x ) + { + destData = (unsigned int *)dest.scanLine(x); + destData[_original_data.height()-y-1] = srcData[x]; + } + } + break; + case Rotate180: + dest.create(_original_data.width(), _original_data.height(), _original_data.depth()); + for ( y=0; y < _original_data.height(); ++y ) + { + srcData = (unsigned int *)_original_data.scanLine(y); + destData = (unsigned int *)dest.scanLine(_original_data.height()-y-1); + for ( x=0; x < _original_data.width(); ++x ) + destData[_original_data.width()-x-1] = srcData[x]; + } + break; + case Rotate270: + dest.create(_original_data.height(), _original_data.width(), _original_data.depth()); + for ( y=0; y < _original_data.height(); ++y ) + { + srcData = (unsigned int *)_original_data.scanLine(y); + for ( x=0; x < _original_data.width(); ++x ) + { + destData = (unsigned int *)dest.scanLine(_original_data.width()-x-1); + destData[y] = srcData[x]; + } + } + break; + default: + dest = _original_data; + break; + } + } + else + { + unsigned char *srcData, *destData; + unsigned int *srcTable, *destTable; + switch ( r ) + { + case Rotate90: + dest.create(_original_data.height(), _original_data.width(), _original_data.depth()); + dest.setNumColors(_original_data.numColors()); + srcTable = (unsigned int *)_original_data.colorTable(); + destTable = (unsigned int *)dest.colorTable(); + for ( x=0; x < _original_data.numColors(); ++x ) + destTable[x] = srcTable[x]; + for ( y=0; y < _original_data.height(); ++y ) + { + srcData = (unsigned char *)_original_data.scanLine(y); + for ( x=0; x < _original_data.width(); ++x ) + { + destData = (unsigned char *)dest.scanLine(x); + destData[_original_data.height()-y-1] = srcData[x]; + } + } + break; + case Rotate180: + dest.create(_original_data.width(), _original_data.height(), _original_data.depth()); + dest.setNumColors(_original_data.numColors()); + srcTable = (unsigned int *)_original_data.colorTable(); + destTable = (unsigned int *)dest.colorTable(); + for ( x=0; x < _original_data.numColors(); ++x ) + destTable[x] = srcTable[x]; + for ( y=0; y < _original_data.height(); ++y ) + { + srcData = (unsigned char *)_original_data.scanLine(y); + destData = (unsigned char *)dest.scanLine(_original_data.height()-y-1); + for ( x=0; x < _original_data.width(); ++x ) + destData[_original_data.width()-x-1] = srcData[x]; + } + break; + case Rotate270: + dest.create(_original_data.height(), _original_data.width(), _original_data.depth()); + dest.setNumColors(_original_data.numColors()); + srcTable = (unsigned int *)_original_data.colorTable(); + destTable = (unsigned int *)dest.colorTable(); + for ( x=0; x < _original_data.numColors(); ++x ) + destTable[x] = srcTable[x]; + for ( y=0; y < _original_data.height(); ++y ) + { + srcData = (unsigned char *)_original_data.scanLine(y); + for ( x=0; x < _original_data.width(); ++x ) + { + destData = (unsigned char *)dest.scanLine(_original_data.width()-x-1); + destData[y] = srcData[x]; + } + } + break; + default: + dest = _original_data; + break; + } + + } + _image_data = dest; +} + +void ImageScrollView::resizeEvent(QResizeEvent * e) +{ + odebug << "ImageScrollView resizeEvent" << oendl; + QScrollView::resizeEvent(e); + Rotation r = Rotate0; + if (width()>height()&&_original_data.width()<_original_data.height() || + width()<height()&&_original_data.width()>_original_data.height()) { + if (rotate_to_fit) r = Rotate90; + } + odebug << " r = " << r << oendl; + if (scale_to_fit) { + if (!_image_data.size().isValid()||width()>_image_data.width()||height()>_image_data.height()) { + if (r==Rotate0) { + _image_data = _original_data; + } else { + rotate_into_data(r); + } + } + rescaleImage(width(),height()); + resizeContents(width()-10,height()-10); + } else if (!first_resize_done||r!=last_rot) { + if (r==Rotate0) { + _image_data = _original_data; + } else { + rotate_into_data(r); + } + last_rot = r; + resizeContents(_image_data.width(),_image_data.height()); + } + first_resize_done = true; +} + void ImageScrollView::drawContents(QPainter * p, int clipx, int clipy, int clipw, int cliph) { int w = clipw; int h = cliph; int x = clipx; int y = clipy; bool erase = false; + if (!_image_data.size().isValid()) { + p->fillRect(clipx,clipy,clipw,cliph,white); + return; + } if (w>_image_data.width()) { w=_image_data.width(); x = 0; erase = true; } else if (x+w>_image_data.width()){ x = _image_data.width()-w; } if (h>_image_data.height()) { h=_image_data.height(); y = 0; erase = true; } else if (y+h>_image_data.height()){ y = _image_data.height()-h; } - if (erase) { + if (erase||_image_data.hasAlphaBuffer()) { p->fillRect(clipx,clipy,clipw,cliph,white); } p->drawImage(clipx,clipy,_image_data,x,y,w,h); } /* using the real geometry points and not the translated points is wanted! */ void ImageScrollView::viewportMouseMoveEvent(QMouseEvent* e) { int mx, my; mx = e->x(); my = e->y(); int diffx = _mouseStartPosX-mx; int diffy = _mouseStartPosY-my; scrollBy(diffx,diffy); _mouseStartPosX=mx; _mouseStartPosY=my; @@ -85,21 +255,22 @@ void ImageScrollView::contentsMouseReleaseEvent ( QMouseEvent * e) void ImageScrollView::contentsMousePressEvent ( QMouseEvent * e) { _mouseStartPosX = e->x(); _mouseStartPosY = e->y(); } /* for testing */ ImageDlg::ImageDlg(const QString&fname,QWidget * parent, const char * name) :QDialog(parent,name,true,WStyle_ContextHelp) { QVBoxLayout*dlglayout = new QVBoxLayout(this); dlglayout->setSpacing(2); dlglayout->setMargin(1); ImageScrollView*inf = new ImageScrollView(fname,this); dlglayout->addWidget(inf); + odebug << "Imagedlg constructor end" << oendl; } ImageDlg::~ImageDlg() { } diff --git a/noncore/graphics/opie-eye/gui/imagescrollview.h b/noncore/graphics/opie-eye/gui/imagescrollview.h index edea235..e25f955 100644 --- a/noncore/graphics/opie-eye/gui/imagescrollview.h +++ b/noncore/graphics/opie-eye/gui/imagescrollview.h @@ -1,43 +1,62 @@ #ifndef _IMAGE_SCROLL_VIEW_H #define _IMAGE_SCROLL_VIEW_H #include <qscrollview.h> #include <qimage.h> #include <qstring.h> #include <qdialog.h> class QPainter; class ImageScrollView:public QScrollView { Q_OBJECT public: - ImageScrollView (const QImage&, QWidget * parent=0, const char * name=0, WFlags f=0 ); - ImageScrollView (const QString&, QWidget * parent=0, const char * name=0, WFlags f=0 ); + ImageScrollView (const QImage&, QWidget * parent=0, const char * name=0, WFlags f=0,bool always_scale=false,bool rfit=false ); + ImageScrollView (const QString&, QWidget * parent=0, const char * name=0, WFlags f=0,bool always_scale=false,bool rfit=false ); virtual ~ImageScrollView(); void setImage(const QImage&); + + enum Rotation { + Rotate0, + Rotate90, + Rotate180, + Rotate270 + }; + protected: virtual void drawContents ( QPainter * p, int clipx, int clipy, int clipw, int cliph ); void init(); QImage _image_data; + QImage _original_data; int _mouseStartPosX,_mouseStartPosY; + bool scale_to_fit; + bool rotate_to_fit; + bool first_resize_done; + Rotation last_rot; + + void rescaleImage(int w, int h); + + void rotate_into_data(Rotation r); + protected slots: virtual void viewportMouseMoveEvent(QMouseEvent* e); virtual void contentsMousePressEvent ( QMouseEvent * e); virtual void contentsMouseReleaseEvent ( QMouseEvent * e); + virtual void resizeEvent(QResizeEvent * e); }; /* for testing */ class ImageDlg:public QDialog { Q_OBJECT public: ImageDlg(const QString&,QWidget * parent=0, const char * name=0); virtual ~ImageDlg(); }; #endif |