summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore 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,105 +1,276 @@
1#include "imagescrollview.h" 1#include "imagescrollview.h"
2 2
3#include <opie2/odebug.h> 3#include <opie2/odebug.h>
4 4
5using namespace Opie::Core; 5using namespace Opie::Core;
6 6
7#include <qimage.h> 7#include <qimage.h>
8#include <qlayout.h> 8#include <qlayout.h>
9 9
10ImageScrollView::ImageScrollView (const QImage&img, QWidget * parent, const char * name, WFlags f) 10ImageScrollView::ImageScrollView (const QImage&img, QWidget * parent, const char * name, WFlags f,bool always_scale,bool rfit)
11 :QScrollView(parent,name,f|Qt::WRepaintNoErase),_image_data(img) 11 :QScrollView(parent,name,f|Qt::WRepaintNoErase),_image_data(),_original_data(img),scale_to_fit(always_scale),
12 rotate_to_fit(rfit),first_resize_done(false)
12{ 13{
13 init(); 14 init();
14} 15}
15 16
16ImageScrollView::ImageScrollView (const QString&img, QWidget * parent, const char * name, WFlags f) 17ImageScrollView::ImageScrollView (const QString&img, QWidget * parent, const char * name, WFlags f,bool always_scale,bool rfit)
17 :QScrollView(parent,name,f|Qt::WRepaintNoErase),_image_data(img) 18 :QScrollView(parent,name,f|Qt::WRepaintNoErase),_image_data(),_original_data(img),scale_to_fit(always_scale),
19 rotate_to_fit(rfit),first_resize_done(false)
18{ 20{
19 init(); 21 init();
20} 22}
21 23
22void ImageScrollView::setImage(const QImage&img) 24void ImageScrollView::setImage(const QImage&img)
23{ 25{
24 _image_data = img; 26 _image_data = QImage();
27 _original_data=img;
28 first_resize_done = false;
25 init(); 29 init();
26} 30}
27 31
28/* should be called every time the QImage changed it content */ 32/* should be called every time the QImage changed it content */
29void ImageScrollView::init() 33void ImageScrollView::init()
30{ 34{
31 viewport()->setBackgroundColor(white); 35 viewport()->setBackgroundColor(white);
32 resizeContents(_image_data.width(),_image_data.height()); 36 if (_original_data.size().isValid()) {
37 resizeContents(_original_data.width(),_original_data.height());
38 }
39 last_rot = Rotate0;
33} 40}
34 41
35ImageScrollView::~ImageScrollView() 42ImageScrollView::~ImageScrollView()
36{ 43{
37} 44}
38 45
46void ImageScrollView::rescaleImage(int w, int h)
47{
48 if (_image_data.width()==w && _image_data.height()==h) {
49 return;
50 }
51 double hs = (double)h / (double)_image_data.height() ;
52 double ws = (double)w / (double)_image_data.width() ;
53 double scaleFactor = (hs > ws) ? ws : hs;
54 int smoothW = (int)(scaleFactor * _image_data.width());
55 int smoothH = (int)(scaleFactor * _image_data.height());
56 _image_data = _image_data.smoothScale(smoothW,smoothH);
57}
58
59void ImageScrollView::rotate_into_data(Rotation r)
60{
61 /* realy - we must do this that way, 'cause when acting direct on _image_data the app will
62 segfault :( */
63 QImage dest;
64 int x, y;
65 if ( _original_data.depth() > 8 )
66 {
67 unsigned int *srcData, *destData;
68 switch ( r )
69 {
70 case Rotate90:
71 dest.create(_original_data.height(), _original_data.width(), _original_data.depth());
72 for ( y=0; y < _original_data.height(); ++y )
73 {
74 srcData = (unsigned int *)_original_data.scanLine(y);
75 for ( x=0; x < _original_data.width(); ++x )
76 {
77 destData = (unsigned int *)dest.scanLine(x);
78 destData[_original_data.height()-y-1] = srcData[x];
79 }
80 }
81 break;
82 case Rotate180:
83 dest.create(_original_data.width(), _original_data.height(), _original_data.depth());
84 for ( y=0; y < _original_data.height(); ++y )
85 {
86 srcData = (unsigned int *)_original_data.scanLine(y);
87 destData = (unsigned int *)dest.scanLine(_original_data.height()-y-1);
88 for ( x=0; x < _original_data.width(); ++x )
89 destData[_original_data.width()-x-1] = srcData[x];
90 }
91 break;
92 case Rotate270:
93 dest.create(_original_data.height(), _original_data.width(), _original_data.depth());
94 for ( y=0; y < _original_data.height(); ++y )
95 {
96 srcData = (unsigned int *)_original_data.scanLine(y);
97 for ( x=0; x < _original_data.width(); ++x )
98 {
99 destData = (unsigned int *)dest.scanLine(_original_data.width()-x-1);
100 destData[y] = srcData[x];
101 }
102 }
103 break;
104 default:
105 dest = _original_data;
106 break;
107 }
108 }
109 else
110 {
111 unsigned char *srcData, *destData;
112 unsigned int *srcTable, *destTable;
113 switch ( r )
114 {
115 case Rotate90:
116 dest.create(_original_data.height(), _original_data.width(), _original_data.depth());
117 dest.setNumColors(_original_data.numColors());
118 srcTable = (unsigned int *)_original_data.colorTable();
119 destTable = (unsigned int *)dest.colorTable();
120 for ( x=0; x < _original_data.numColors(); ++x )
121 destTable[x] = srcTable[x];
122 for ( y=0; y < _original_data.height(); ++y )
123 {
124 srcData = (unsigned char *)_original_data.scanLine(y);
125 for ( x=0; x < _original_data.width(); ++x )
126 {
127 destData = (unsigned char *)dest.scanLine(x);
128 destData[_original_data.height()-y-1] = srcData[x];
129 }
130 }
131 break;
132 case Rotate180:
133 dest.create(_original_data.width(), _original_data.height(), _original_data.depth());
134 dest.setNumColors(_original_data.numColors());
135 srcTable = (unsigned int *)_original_data.colorTable();
136 destTable = (unsigned int *)dest.colorTable();
137 for ( x=0; x < _original_data.numColors(); ++x )
138 destTable[x] = srcTable[x];
139 for ( y=0; y < _original_data.height(); ++y )
140 {
141 srcData = (unsigned char *)_original_data.scanLine(y);
142 destData = (unsigned char *)dest.scanLine(_original_data.height()-y-1);
143 for ( x=0; x < _original_data.width(); ++x )
144 destData[_original_data.width()-x-1] = srcData[x];
145 }
146 break;
147 case Rotate270:
148 dest.create(_original_data.height(), _original_data.width(), _original_data.depth());
149 dest.setNumColors(_original_data.numColors());
150 srcTable = (unsigned int *)_original_data.colorTable();
151 destTable = (unsigned int *)dest.colorTable();
152 for ( x=0; x < _original_data.numColors(); ++x )
153 destTable[x] = srcTable[x];
154 for ( y=0; y < _original_data.height(); ++y )
155 {
156 srcData = (unsigned char *)_original_data.scanLine(y);
157 for ( x=0; x < _original_data.width(); ++x )
158 {
159 destData = (unsigned char *)dest.scanLine(_original_data.width()-x-1);
160 destData[y] = srcData[x];
161 }
162 }
163 break;
164 default:
165 dest = _original_data;
166 break;
167 }
168
169 }
170 _image_data = dest;
171}
172
173void ImageScrollView::resizeEvent(QResizeEvent * e)
174{
175 odebug << "ImageScrollView resizeEvent" << oendl;
176 QScrollView::resizeEvent(e);
177 Rotation r = Rotate0;
178 if (width()>height()&&_original_data.width()<_original_data.height() ||
179 width()<height()&&_original_data.width()>_original_data.height()) {
180 if (rotate_to_fit) r = Rotate90;
181 }
182 odebug << " r = " << r << oendl;
183 if (scale_to_fit) {
184 if (!_image_data.size().isValid()||width()>_image_data.width()||height()>_image_data.height()) {
185 if (r==Rotate0) {
186 _image_data = _original_data;
187 } else {
188 rotate_into_data(r);
189 }
190 }
191 rescaleImage(width(),height());
192 resizeContents(width()-10,height()-10);
193 } else if (!first_resize_done||r!=last_rot) {
194 if (r==Rotate0) {
195 _image_data = _original_data;
196 } else {
197 rotate_into_data(r);
198 }
199 last_rot = r;
200 resizeContents(_image_data.width(),_image_data.height());
201 }
202 first_resize_done = true;
203}
204
39void ImageScrollView::drawContents(QPainter * p, int clipx, int clipy, int clipw, int cliph) 205void ImageScrollView::drawContents(QPainter * p, int clipx, int clipy, int clipw, int cliph)
40{ 206{
41 int w = clipw; 207 int w = clipw;
42 int h = cliph; 208 int h = cliph;
43 int x = clipx; 209 int x = clipx;
44 int y = clipy; 210 int y = clipy;
45 bool erase = false; 211 bool erase = false;
46 212
213 if (!_image_data.size().isValid()) {
214 p->fillRect(clipx,clipy,clipw,cliph,white);
215 return;
216 }
47 if (w>_image_data.width()) { 217 if (w>_image_data.width()) {
48 w=_image_data.width(); 218 w=_image_data.width();
49 x = 0; 219 x = 0;
50 erase = true; 220 erase = true;
51 } else if (x+w>_image_data.width()){ 221 } else if (x+w>_image_data.width()){
52 x = _image_data.width()-w; 222 x = _image_data.width()-w;
53 } 223 }
54 if (h>_image_data.height()) { 224 if (h>_image_data.height()) {
55 h=_image_data.height(); 225 h=_image_data.height();
56 y = 0; 226 y = 0;
57 erase = true; 227 erase = true;
58 } else if (y+h>_image_data.height()){ 228 } else if (y+h>_image_data.height()){
59 y = _image_data.height()-h; 229 y = _image_data.height()-h;
60 } 230 }
61 if (erase) { 231 if (erase||_image_data.hasAlphaBuffer()) {
62 p->fillRect(clipx,clipy,clipw,cliph,white); 232 p->fillRect(clipx,clipy,clipw,cliph,white);
63 } 233 }
64 p->drawImage(clipx,clipy,_image_data,x,y,w,h); 234 p->drawImage(clipx,clipy,_image_data,x,y,w,h);
65} 235}
66 236
67/* using the real geometry points and not the translated points is wanted! */ 237/* using the real geometry points and not the translated points is wanted! */
68void ImageScrollView::viewportMouseMoveEvent(QMouseEvent* e) 238void ImageScrollView::viewportMouseMoveEvent(QMouseEvent* e)
69{ 239{
70 int mx, my; 240 int mx, my;
71 mx = e->x(); 241 mx = e->x();
72 my = e->y(); 242 my = e->y();
73 int diffx = _mouseStartPosX-mx; 243 int diffx = _mouseStartPosX-mx;
74 int diffy = _mouseStartPosY-my; 244 int diffy = _mouseStartPosY-my;
75 scrollBy(diffx,diffy); 245 scrollBy(diffx,diffy);
76 _mouseStartPosX=mx; 246 _mouseStartPosX=mx;
77 _mouseStartPosY=my; 247 _mouseStartPosY=my;
78} 248}
79 249
80void ImageScrollView::contentsMouseReleaseEvent ( QMouseEvent * e) 250void ImageScrollView::contentsMouseReleaseEvent ( QMouseEvent * e)
81{ 251{
82 _mouseStartPosX = e->x(); 252 _mouseStartPosX = e->x();
83 _mouseStartPosY = e->y(); 253 _mouseStartPosY = e->y();
84} 254}
85 255
86void ImageScrollView::contentsMousePressEvent ( QMouseEvent * e) 256void ImageScrollView::contentsMousePressEvent ( QMouseEvent * e)
87{ 257{
88 _mouseStartPosX = e->x(); 258 _mouseStartPosX = e->x();
89 _mouseStartPosY = e->y(); 259 _mouseStartPosY = e->y();
90} 260}
91 261
92/* for testing */ 262/* for testing */
93ImageDlg::ImageDlg(const QString&fname,QWidget * parent, const char * name) 263ImageDlg::ImageDlg(const QString&fname,QWidget * parent, const char * name)
94 :QDialog(parent,name,true,WStyle_ContextHelp) 264 :QDialog(parent,name,true,WStyle_ContextHelp)
95{ 265{
96 QVBoxLayout*dlglayout = new QVBoxLayout(this); 266 QVBoxLayout*dlglayout = new QVBoxLayout(this);
97 dlglayout->setSpacing(2); 267 dlglayout->setSpacing(2);
98 dlglayout->setMargin(1); 268 dlglayout->setMargin(1);
99 ImageScrollView*inf = new ImageScrollView(fname,this); 269 ImageScrollView*inf = new ImageScrollView(fname,this);
100 dlglayout->addWidget(inf); 270 dlglayout->addWidget(inf);
271 odebug << "Imagedlg constructor end" << oendl;
101} 272}
102 273
103ImageDlg::~ImageDlg() 274ImageDlg::~ImageDlg()
104{ 275{
105} 276}
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 @@
1#ifndef _IMAGE_SCROLL_VIEW_H 1#ifndef _IMAGE_SCROLL_VIEW_H
2#define _IMAGE_SCROLL_VIEW_H 2#define _IMAGE_SCROLL_VIEW_H
3 3
4#include <qscrollview.h> 4#include <qscrollview.h>
5#include <qimage.h> 5#include <qimage.h>
6#include <qstring.h> 6#include <qstring.h>
7#include <qdialog.h> 7#include <qdialog.h>
8 8
9class QPainter; 9class QPainter;
10 10
11class ImageScrollView:public QScrollView 11class ImageScrollView:public QScrollView
12{ 12{
13 Q_OBJECT 13 Q_OBJECT
14public: 14public:
15 ImageScrollView (const QImage&, QWidget * parent=0, const char * name=0, WFlags f=0 ); 15 ImageScrollView (const QImage&, QWidget * parent=0, const char * name=0, WFlags f=0,bool always_scale=false,bool rfit=false );
16 ImageScrollView (const QString&, QWidget * parent=0, const char * name=0, WFlags f=0 ); 16 ImageScrollView (const QString&, QWidget * parent=0, const char * name=0, WFlags f=0,bool always_scale=false,bool rfit=false );
17 virtual ~ImageScrollView(); 17 virtual ~ImageScrollView();
18 18
19 void setImage(const QImage&); 19 void setImage(const QImage&);
20
21 enum Rotation {
22 Rotate0,
23 Rotate90,
24 Rotate180,
25 Rotate270
26 };
27
20protected: 28protected:
21 virtual void drawContents ( QPainter * p, int clipx, int clipy, int clipw, int cliph ); 29 virtual void drawContents ( QPainter * p, int clipx, int clipy, int clipw, int cliph );
22 void init(); 30 void init();
23 31
24 QImage _image_data; 32 QImage _image_data;
33 QImage _original_data;
25 34
26 int _mouseStartPosX,_mouseStartPosY; 35 int _mouseStartPosX,_mouseStartPosY;
27 36
37 bool scale_to_fit;
38 bool rotate_to_fit;
39 bool first_resize_done;
40 Rotation last_rot;
41
42 void rescaleImage(int w, int h);
43
44 void rotate_into_data(Rotation r);
45
28protected slots: 46protected slots:
29 virtual void viewportMouseMoveEvent(QMouseEvent* e); 47 virtual void viewportMouseMoveEvent(QMouseEvent* e);
30 virtual void contentsMousePressEvent ( QMouseEvent * e); 48 virtual void contentsMousePressEvent ( QMouseEvent * e);
31 virtual void contentsMouseReleaseEvent ( QMouseEvent * e); 49 virtual void contentsMouseReleaseEvent ( QMouseEvent * e);
50 virtual void resizeEvent(QResizeEvent * e);
32}; 51};
33 52
34/* for testing */ 53/* for testing */
35class ImageDlg:public QDialog 54class ImageDlg:public QDialog
36{ 55{
37 Q_OBJECT 56 Q_OBJECT
38public: 57public:
39 ImageDlg(const QString&,QWidget * parent=0, const char * name=0); 58 ImageDlg(const QString&,QWidget * parent=0, const char * name=0);
40 virtual ~ImageDlg(); 59 virtual ~ImageDlg();
41}; 60};
42 61
43#endif 62#endif