Newer
Older
Import / applications / Photoframe / src / iconview.cpp
@John Ryland John Ryland on 22 Dec 2020 10 KB import of apps from backup copy of dell-pc
#include <QPainter>
#include <QPixmapCache>
#include <QTimerEvent>
#include <QKeyEvent>
#include <QImageReader>
#include <QDir>
#include <QTimer>
#include <QLabel>
#include "iconview.h"


IconView::IconView(QWidget *parent) : QWidget(parent)
{
	paintTimerId = 0;
	thumbTimerId = 0;
	index = 0;
	changeDirectory("Internal");
	QPixmapCache::setCacheLimit(64000);
	QPixmapCache::insert("folder", QPixmap("icons/b/folder.png"));
	QPixmapCache::insert("thumb", QPixmap("icons/b/thumb.png"));
	curItemX = 0;
	curItemY = 0;
	offset = 0;
}


IconView::~IconView()
{
}


void IconView::changeDirectory(QString dirStr)
{
	if (paintTimerId)
		killTimer(paintTimerId);
	if (thumbTimerId)
		killTimer(thumbTimerId);
	paintTimerId = 0;
	thumbTimerId = 0;

	QDir d1("photos/" + dirStr);
	dirStr = d1.absolutePath();
	QDir d2("photos");
	directory = d2.relativeFilePath(dirStr);

	index = 0;
	curItemX = -1;
	curItemY = -1;
	offset = 0;
	repaint();

	if ( !QFile::exists("photos/" + directory) )
		return;

	emit directoryChanged(directory);

	dir = QDir("photos/" + directory);
	dir.setSorting(QDir::Name | QDir::DirsFirst);
	entryList = dir.entryList();
	entryInfoList = dir.entryInfoList();
	QPixmap folder = QPixmap("icons/b/folder.png");
	QPixmap thumb = QPixmap("icons/b/thumb.png");
	QPixmap back = QPixmap("icons/b/back.png");
	QFont font("Arial",11);
	for (int i = 0; i < (int)dir.count(); i++) {
		QFileInfo fi = entryInfoList[i];
		QString filename = "photos/" + directory + "/" + fi.fileName();
		QPixmap dummy(88,68);
		if (!QPixmapCache::find(filename, dummy)) {
			dummy.fill(QColor(0,0,0,0));
			QPainter p(&dummy);
			p.setPen(Qt::NoPen);
			p.setBrush(QColor(178,178,178,64));
			p.drawRect(0, 0, 88, 68);
			QString label = fi.fileName();
			if ( fi.isFile() ) {
				p.drawPixmap(20, 3, thumb);
			} else if ( fi.isDir() ) {
				if (label == "..") {
					label = "Up";
					p.drawPixmap(20, 3, back);
				} else {
					p.drawPixmap(20, 3, folder);
				}
			}
			QFontMetrics fm(font);
			p.setFont(font);
			QString str = fm.elidedText(label, Qt::ElideRight, 88);
			int w = fm.width(str);
			p.setPen(QColor(64,64,64));
			p.drawText((88-w)/2+1, 66, str);
			p.setPen(Qt::white);
			p.drawText((88-w)/2, 65, str);
			p.end();
			QPixmapCache::insert(filename, dummy);
		}
	}

	thumbTimerId = startTimer(5);
	paintTimerId = startTimer(30);
}


static QPixmap loadThumbnail(QString filename, QSize size)
{
	QPixmap thumb;
	ExifLoader *loader = exif_loader_new();
	if ( !loader )
		return thumb;
	exif_loader_write_file(loader, filename.toLatin1().data());
	ExifData *ed = exif_loader_get_data(loader);
	if (ed && ed->data && ed->size) {
		thumb.loadFromData(ed->data, ed->size);
		thumb = thumb.scaled(size.width(), size.height());
	} else {
		QImageReader iio(filename);
		iio.setScaledSize(size);
		iio.setQuality(0);
		QImage img = iio.read();
		if ( img.isNull() )
			return thumb;
		thumb = thumb.fromImage(img);
	}
	exif_data_unref(ed);
	exif_loader_unref(loader);
	return thumb;
}


void IconView::timerEvent(QTimerEvent *te)
{
	if (te->timerId() == thumbTimerId) {
		for (int i = 0; i < 4; i++) {
			QFileInfo fi = entryInfoList[index];
			QString filename = "photos/" + directory + "/" + fi.fileName();
			if ( fi.isFile() ) {
				QPixmap thumb = loadThumbnail(filename, QSize(88,68));
				if (!thumb.isNull())
					QPixmapCache::insert(filename, thumb);
			}
			index++;
			if (index >= dir.count()) {
				killTimer(thumbTimerId);
				thumbTimerId = 0;
				return;
			}
/*
			else if (index >= 21 ) {
				killTimer(thumbTimerId);
				thumbTimerId = startTimer(200);
			}
*/
		}
	} else if (te->timerId() == paintTimerId) {
		update();
		if (index >= offset + 30 || index >= dir.count()) {
			// deliberately seperate to the killTimer for thumbTimerId
			// because doing it here will allow the last update() to happpen
			killTimer(paintTimerId);
			paintTimerId = 0;
		}
	}
}


void IconView::setFocusItem(int x, int y)
{
	curItemX = x;
	curItemY = y;
	offset = 1;
	repaint();
}


class FadeInOutPreview : public QWidget
{
public:
	int speed;
	bool autoOut;
	FadeInOutPreview(QWidget *parent, QString file, int _x, int _y, int exp, int s, bool ao = false) : QWidget(parent) {
		expandFactor = exp;
		autoOut = ao;
		speed = s;
		tick = 0;
		x = _x;
		y = _y;
		pix = QPixmap(file);
		QSize size = pix.size();
		size.scale(600,350,Qt::KeepAspectRatio);
		pix = pix.scaled(size);
		setGeometry(0, 0, 800, 480);
		//QTimer::singleShot(2000, this, SLOT(deleteLater()));
		fadeInId = 0;
		fadeOutId = 0;
		tmp = 0;
	}
	~FadeInOutPreview() { }
	void fadeIn() {
		show();
		fadeInId = startTimer(speed);
	}
	void fadeOut() {
		fadeOutId = startTimer(speed);
	}
	int fadeInId;
	int fadeOutId;
	int tmp;
	void timerEvent(QTimerEvent *te) {
		if (te->timerId() == fadeInId) {
			tick++;
			if (tick > 30) {
				tick = 30;
				tmp++;
				if (tmp > 40) {
					killTimer(fadeInId);
					fadeInId = 0;
					if (autoOut)
						fadeOut();
				}
			}
		}
		if (te->timerId() == fadeOutId) {
			tick++;
			if ( tick > 60 ) {
				hide();
				killTimer(fadeOutId);
				fadeOutId = 0;
			}
		}
		update();
	}
	void paintEvent(QPaintEvent *pe) {
		QPainter p(this);
		QPixmap p2;
		QSize size = pix.size();
		float ratio = 1.0;
		float fadeRatio = 1.0;

		if ( tick < 20 - expandFactor ) {
			ratio = tick / 20.0;
		} else if ( tick < 40 + expandFactor ) {
			ratio = (60.0 - 40 - expandFactor) / 20.0;
		} else {
			ratio = (60.0 - tick) / 20.0;
		}

		if ( tick < 20 ) {
			fadeRatio = tick / 20.0;
		} else if ( tick < 40 ) {
			fadeRatio = 1.0;
		} else {
			fadeRatio = (60.0 - tick) / 20.0;
		}

		size.scale(ratio*(800-90)+90, ratio*(480-70)+70, Qt::KeepAspectRatio);

		p2 = pix.scaled(size);

		int _x =  -15+(1.0-ratio)*x+((ratio*(800-90)+90)/2)-size.width()/2;
		int _y =  -15+(1.0-ratio)*y+((ratio*(480-70)+70)/2)-size.height()/2;

		p.setPen(Qt::NoPen);
		p.setBrush(QColor(32,32,32,128));
		p.drawRect(12 + _x, 12 + _y, size.width(), size.height());
		p.setOpacity(fadeRatio);
		p.drawPixmap(_x, _y, p2);
	}
	QPixmap pix;
	int tick;
	int x, y;
	int expandFactor;
};

void IconView::keyPressEvent(QKeyEvent *ke)
{
/*
	static FadeInOutPreview *oldI = 0;
	static FadeInOutPreview *newI = 0;
	static int oldCurItemX = 0;
	static int oldCurItemY = 0;

	QString filename = "photos/" + directory + "/" + entryList[curItemX+curItemY*5+offset];
	if (oldI)
		oldI->deleteLater();
	oldI = new FadeInOutPreview(parentWidget(), filename, curItemX*100+320, curItemY*80+180, 17, 1);
	oldI->fadeIn();
	oldCurItemX = curItemX;
	oldCurItemY = curItemY;
*/

	if (ke->key() == Qt::Key_Down) {
		if ( dir.count() > (offset + curItemX + curItemY * 5 + 5) )
			curItemY++;
		if (curItemY > 3) {
			curItemY = 3;
			if ( dir.count() - offset >= 21 + curItemX ) {
				offset += 5;
			}
		}
	}
	if (ke->key() == Qt::Key_Right) {
		if ( dir.count() > (offset + curItemX + curItemY * 5 + 1) )
			curItemX++;
		if (curItemX > 4) {
			if (curItemY > 2) {
				if ( dir.count() - offset <= 20 ) {
					curItemX = 4;
					curItemY = 3;
				} else {
					curItemX = 0;
					curItemY = 3;
					offset += 5;
				}
			} else {
				curItemX = 0;
				curItemY++;
			}
		}
	}
	if (ke->key() == Qt::Key_Up) {
		curItemY--;
		if (curItemY < 0) {
			curItemY = 0;
			if ( offset > 5 ) {
				offset -= 5;
			}
		}
	}
	if (ke->key() == Qt::Key_Left) {
		curItemX--;
		if (curItemX < -1) {
			curItemX = -1;
		}
		if (curItemX == -1) {
			if (curItemY == 0) {
				if ( offset > 5 ) {
					curItemX = 4;
					offset -= 5;
				} else {
					emit switchFocus();
				}
			} else {
				curItemY--;
				curItemX = 4;
			}
		}
	}

/*
	if ( curItemX != oldCurItemX || curItemY != oldCurItemY ) {
		oldI->fadeOut();
		if (newI)
			newI->deleteLater();
		QString filename = "photos/" + directory + "/" + entryList[curItemX+curItemY*5+offset];
		newI = new FadeInOutPreview(parentWidget(), filename, curItemX*100+320, curItemY*80+180, 17, 1);
		newI->fadeIn();
		oldCurItemX = curItemX;
		oldCurItemY = curItemY;
		FadeInOutPreview *oldITmp = oldI;
		oldI = newI;
		newI = oldITmp;
	}
*/


	if (ke->key() == Qt::Key_Return) {
		QString filename = "photos/" + directory + "/" + entryList[curItemX+curItemY*5+offset];
		if (QFileInfo(filename).isDir()) {
			changeDirectory(directory + "/" + entryList[curItemX+curItemY*5+offset]);
			setFocusItem(0,0);
		} else {
//			QPoint topLeft = mapToGlobal(QPoint(0,0));
			int _x = 280;//topLeft.x();
			int _y = 140;//topLeft.y();
			FadeInOutPreview *tmp = new FadeInOutPreview(parentWidget(), filename, curItemX*100+_x, curItemY*80+_y, 3, 3, true);
//			FadeInOutPreview *tmp = new FadeInOutPreview(parentWidget(), filename, curItemX*100+320, curItemY*80+180, 13, 5, true);
			tmp->fadeIn();
/*
			static QLabel *lab = 0;
			if (lab) {
				lab->hide();
				delete lab;
			}
			lab = new QLabel(parentWidget());
			QPixmap pix = QPixmap(filename);
			QSize size = pix.size();
			size.scale(700,380,Qt::KeepAspectRatio);
			pix.fill(QColor(0,0,0,0));
			QPainter p(&pix);
			p.setOpacity(0.8);
			p.drawPixmap(0, 0, QPixmap(filename));			
			p.end();
			lab->setPixmap(pix.scaled(size));
			lab->setGeometry((800 - size.width()) / 2, (480 - size.height()) / 2, size.width(), size.height());
			lab->show();
			QTimer::singleShot(2000, lab, SLOT(hide()));
*/
		}
	}
	repaint();
}


void IconView::paintEvent(QPaintEvent *pe)
{
	QPainter p(this);
	p.setPen(QColor(32,32,64));
	for (int y = 0; y < 320; y+=80)
		for (int x = 0; x < 500; x+=100)
			p.drawRect(x, y, 90, 70);
	p.setPen(QColor(178,178,255));
	for (int y = 1; y < 321; y+=80)
		for (int x = 1; x < 501; x+=100)
			p.drawRect(x, y, 90, 70);
	p.setPen(Qt::NoPen);
	p.setBrush(QColor(178,178,178,64));
	for (int y = 2; y < 322; y+=80)
		for (int x = 2; x < 502; x+=100)
			p.drawRect(x, y, 88, 68);

	int x2 = curItemX * 100;
	int y2 = curItemY * 80;
	if (x2 >= 0) {
		p.setPen(QColor(255,255,255));
		p.drawRect(x2, y2, 88+2, 68+2);
		p.drawRect(x2, y2, 88+3, 68+3);
	}

	int i = offset;
	for (int y = 0; y < 4; y++)
		for (int x = 0; x < 5; x++) {
			QPixmap thumb;
			if ( (int)dir.count() > i ) {
				if ( entryList[i] == "." )
					i++;
				QString filename = "photos/" + directory + "/" + entryList[i];
				if (QPixmapCache::find(filename, thumb)) {
					p.drawPixmap(x*100+2, y*80+2, thumb.scaled(88,68));
				//} else {
					//p.drawPixmap(x*100+2, y*80+2, QPixmap(filename).scaled(88,68));
				}
				i++;
			}
		}

	if (x2 >= 0) {
		p.setPen(Qt::NoPen);
		QRadialGradient g1(x2+80,y2-45,80,x2+60,y2-2);
		g1.setColorAt(0,QColor(255,255,255,255));
		g1.setColorAt(1,QColor(255,255,255,12));
		p.setBrush(g1);
		p.drawRect(x2+2, y2+2, 88, 68);

		QRadialGradient g2(x2+50,y2-50,140,x2+90,y2+50);
		g2.setColorAt(0,QColor(255,255,255,0));
		g2.setColorAt(0.50,QColor(255,255,255,0));
		g2.setColorAt(0.51,QColor(200,200,245,100));
		g2.setColorAt(1,QColor(200,200,245,100));
		p.setBrush(g2);
		p.drawRect(x2+2, y2+2, 88, 68);
	}
}