summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/graphics/opie-eye/gui/imagescrollview.cpp185
-rw-r--r--noncore/graphics/opie-eye/gui/imagescrollview.h23
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