first commit
This commit is contained in:
714
project/fm_viewer/ui/fm_thumbnail_dialog.cpp
Normal file
714
project/fm_viewer/ui/fm_thumbnail_dialog.cpp
Normal file
@@ -0,0 +1,714 @@
|
||||
#include "fm_thumbnail_dialog.h"
|
||||
//#include "fm_thumbnail.h"
|
||||
#if (RM_MODEL == RM_MODEL_TYPE_TB4000)
|
||||
#include <QFileInfo>
|
||||
#include <QGridLayout>
|
||||
#include "../data/rm_video_list.h"
|
||||
#include "../data/rm_video_item_2ch.h"
|
||||
#include "../core/rm_math.h"
|
||||
#include "fm_button.h"
|
||||
#include <QLabel>
|
||||
#include <QRunnable>
|
||||
#include <QScrollArea>
|
||||
#include <QApplication>
|
||||
|
||||
#include <QResizeEvent>
|
||||
#include <QStyleOption>
|
||||
#include <QPainter>
|
||||
#include <QPushButton>
|
||||
#include <QDir>
|
||||
|
||||
#include <QShortcut>
|
||||
|
||||
#include <QTableWidget>
|
||||
#include <QHeaderView>
|
||||
#include <QMainWindow>
|
||||
|
||||
#include <QtConcurrent>
|
||||
#if (DETECT_USB_CHANGE)
|
||||
#include "../core/rm_usb.h"
|
||||
#endif // #if (DETECT_USB_CHANGE)
|
||||
|
||||
int g_thumbnail_dialog_width = 814;
|
||||
int g_thumbnail_dialog_height = 600;
|
||||
int g_thumbnail_column_count = 4;
|
||||
const int g_thumbnail_row_count = 4; // 표시 줄...
|
||||
const int g_thumbnail_title_height = 22; // 타이틀 높이
|
||||
const int g_thumbnail_width = 200;
|
||||
const int g_thumbnail_height = (int)((double)g_thumbnail_width / 480.0 * 320.0);
|
||||
const int g_thumbnail_border_size = 4; // 선택영역 처리 ETC
|
||||
const bool g_dual_ch_thumbnail = true; // 전후방 모두 처리
|
||||
//const int td_width = 1024;
|
||||
|
||||
#if (USE_DATE_FILTER)
|
||||
QStringList FMThumbnailDialog::_files = QStringList();
|
||||
#endif // #if (USE_DATE_FILTER)
|
||||
|
||||
#if (USE_1HOUR_FILTER)
|
||||
QList<QPair<QString,QString>> FMThumbnailDialog::_thumbnails = QList<QPair<QString,QString>>();
|
||||
QList<RMVideoItem*> FMThumbnailDialog::_items = QList<RMVideoItem*>();
|
||||
#endif
|
||||
|
||||
QRect rectAspectFit(QRect src,int w, int h) {
|
||||
int l = src.left();
|
||||
int t = src.top();
|
||||
if(src.width() > w )
|
||||
{
|
||||
l += (src.width() - w) / 2;
|
||||
}
|
||||
if(src.height() > h )
|
||||
{
|
||||
t += (src.height() - h) / 2;
|
||||
}
|
||||
return QRect(l,t,w,h);
|
||||
}
|
||||
|
||||
FM_COLOR_SET g_thumb_button_colors[5] = {
|
||||
0x595959, // normal
|
||||
0x2e2e2e, // pressed
|
||||
0x343434, // hover
|
||||
0x595959, // disabled
|
||||
0x3a3a3a, // checked
|
||||
};
|
||||
|
||||
|
||||
void FMThumbnailDialog::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
|
||||
|
||||
/*
|
||||
// accept, reject 호출되지 않음
|
||||
//qInfo() << playItems << __FUNCTION__;
|
||||
selectedItem = NULL;
|
||||
if(FMThumbnailLoader::bRunning) {
|
||||
FMThumbnailLoader::bStop = true;
|
||||
event->ignore();
|
||||
#if !(THUMBNAIL_ITEM_CONNECT_EACH)
|
||||
for(int i=0;i<_items.size();i++) {
|
||||
disconnect(_items.at(i),SIGNAL(thumnbnailsLoaded(RMVideoItem*)),this,SLOT(onThumbnailLoaded(RMVideoItem*)));
|
||||
// for(int j=0;j<_items.at(i)->thumbnails.size();j++)
|
||||
// {
|
||||
// FMThumbnail* thumbnail = _items.at(i)->thumbnails.at(j);
|
||||
// total += thumbnail->size;
|
||||
// delete _items.at(i)->thumbnails.at(j);
|
||||
// }
|
||||
// _items.at(i)->thumbnails.clear();
|
||||
}
|
||||
#endif // THUMBNAIL_ITEM_CONNECT_EACH
|
||||
|
||||
// 강제 종료 후 연결
|
||||
FMThumbnailSignal::instance()->mode = FMThumbnailSignal::MODE_REJECT; // 종료 모드
|
||||
connect(FMThumbnailSignal::instance(),SIGNAL(finished()),SLOT(onProcessFinished()));
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
#if (USE_DATE_FILTER)
|
||||
FMThumbnailDialog::FMThumbnailDialog(QWidget *parent, QString folder) : QDialog(parent,Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint)
|
||||
#else // USE_DATE_FILTER
|
||||
FMThumbnailDialog::FMThumbnailDialog(QWidget *parent, bool bAll) : QDialog(parent,Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint)
|
||||
#endif // USE_DATE_FILTER
|
||||
{
|
||||
_bFirst = false;
|
||||
_mode = MODE_SIMPLE;
|
||||
#if (USE_DATE_FILTER)
|
||||
_folder = folder;
|
||||
#endif
|
||||
|
||||
|
||||
if( RMApp::instance()->pMainWindow->isFullScreen()) {
|
||||
int maxWidth = RMApp::instance()->pMainWindow->width() - 360;
|
||||
g_thumbnail_column_count = (maxWidth / 400) * 2;
|
||||
g_thumbnail_dialog_width = (g_thumbnail_column_count * 200) + 14;
|
||||
g_thumbnail_dialog_height = RMApp::instance()->pMainWindow->height() - 240;
|
||||
qInfo() << g_thumbnail_dialog_width << g_thumbnail_column_count << __FUNCTION__;
|
||||
} else {
|
||||
g_thumbnail_dialog_width = 814;
|
||||
g_thumbnail_dialog_height = 600;
|
||||
g_thumbnail_column_count = 4;
|
||||
}
|
||||
|
||||
//qInfo() << "isMaximized:" << RMApp::instance()->pMainWindow->isFullScreen() << __FUNCTION__;
|
||||
|
||||
setFixedWidth(g_thumbnail_dialog_width+5);
|
||||
resize(g_thumbnail_dialog_width+5,g_thumbnail_dialog_height);
|
||||
|
||||
QVBoxLayout* l = new QVBoxLayout(this);
|
||||
ZERO_LAYOUT(l);
|
||||
|
||||
QWidget* top = new QWidget(this);
|
||||
top->setStyleSheet("background-color: #595959;");
|
||||
top->setFixedHeight(40);
|
||||
l->addWidget(top);
|
||||
QHBoxLayout* topL = new QHBoxLayout(top);
|
||||
ZERO_LAYOUT(topL);
|
||||
_titleBar = new QLabel(top);
|
||||
_titleBar->setAlignment(Qt::AlignCenter);
|
||||
_titleBar->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
|
||||
_titleBar->setStyleSheet("font-family: Malgun Gothic;font-size: 16px; color : #FFFFFF;");
|
||||
topL->addWidget(_titleBar);
|
||||
//_titleBar->setText(FM_WSTR(L"1시간 대표 이미지"));
|
||||
|
||||
_backButton = FMButton::btnType0(top,topL,"thumbnail_back",FM_WSTR(L"1시간 리스트로 돌아가기"),QSize(40,40),g_thumb_button_colors);
|
||||
_backButton->setHidden(true);
|
||||
//l->addWidget(_backButton);
|
||||
connect(_backButton,SIGNAL(clicked()),this,SLOT(onBack()));
|
||||
|
||||
_tableView = new QTableWidget(this);
|
||||
_tableView->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
|
||||
_tableView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
_tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
_tableView->verticalHeader()->hide();
|
||||
_tableView->horizontalHeader()->hide();
|
||||
|
||||
_tableView->verticalHeader()->setDefaultSectionSize(g_thumbnail_height + g_thumbnail_title_height);
|
||||
_tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
|
||||
_tableView->horizontalHeader()->setDefaultSectionSize(g_thumbnail_width);
|
||||
_tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
|
||||
_tableView->setAttribute(Qt::WA_Hover);
|
||||
_tableView->viewport()->setAttribute(Qt::WA_Hover);
|
||||
_tableView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
_tableView->setSelectionBehavior(QAbstractItemView::SelectItems);
|
||||
_tableView->setShowGrid(false);
|
||||
_tableView->setObjectName("thumbnail");
|
||||
_tableView->setStyleSheet("QTableWidget#thumbnail{background-color: #333333;}");
|
||||
|
||||
_tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
|
||||
_delegate = new FMThumbnailDelegate(this);
|
||||
//_tableView->setItemDelegate(_delegate);
|
||||
|
||||
l->addWidget(_tableView);
|
||||
|
||||
// 배경색만 바꿈..
|
||||
connect(_tableView->selectionModel(),SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),this,SLOT(onSelectionChanged(const QItemSelection &, const QItemSelection &)));
|
||||
|
||||
createLayout(MODE_SIMPLE);
|
||||
|
||||
connect(thumbnail_cache::instance(),SIGNAL(thumbnailLoaded(int)),this,SLOT(onThumbnailUpdated(int)));
|
||||
|
||||
if(bAll) {
|
||||
_mode = MODE_SUB;
|
||||
}
|
||||
|
||||
QTimer::singleShot(100,Qt::PreciseTimer,this,SLOT(onLoadThumbnails()));
|
||||
|
||||
connect(_tableView, SIGNAL(cellDoubleClicked(int,int)), this, SLOT(onDoubleClickItem(int,int)));
|
||||
|
||||
#if (DETECT_USB_CHANGE)
|
||||
connect(RMApp::instance()->usb,SIGNAL(usbChanged(bool,QString&)),SLOT(onUSBChange(bool,QString&)));
|
||||
#endif // DETECT_USB_CHANGE
|
||||
|
||||
}
|
||||
#if (DETECT_USB_CHANGE)
|
||||
void FMThumbnailDialog::onUSBChange(bool inserted, QString& drive)
|
||||
{
|
||||
// 제거시 리스트 삭제
|
||||
if(!inserted && drive.toUpper() == _usb->_openDrive) {
|
||||
reject();
|
||||
}
|
||||
}
|
||||
#endif // #if (DETECT_USB_CHANGE)
|
||||
void FMThumbnailDialog::showEvent(QShowEvent * event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
_tableView->setItemDelegate(_delegate);
|
||||
}
|
||||
void FMThumbnailDialog::onThumbnailUpdated(int index)
|
||||
{
|
||||
int row_start = qMax(_tableView->verticalHeader()->visualIndexAt(0), 0);
|
||||
int row_end = _tableView->verticalHeader()->visualIndexAt(_tableView->verticalHeader()->height());
|
||||
if(row_end == -1) {
|
||||
row_end = _tableView->rowCount() - 1;
|
||||
}
|
||||
|
||||
if (index >= row_start && index <= row_end) {
|
||||
_tableView->viewport()->update();
|
||||
//qInfo() << "row_start:" << row_start << index << "row_end:" << row_end << "loaded";
|
||||
}
|
||||
}
|
||||
void FMThumbnailDialog::scrollTo()
|
||||
{
|
||||
if(_lastIndex.isValid()) {
|
||||
_tableView->setItemDelegate(_delegate);
|
||||
_tableView->scrollTo(_lastIndex); // ,QTableView::PositionAtTop
|
||||
_lastIndex = QModelIndex();
|
||||
}
|
||||
}
|
||||
void FMThumbnailDialog::onDoubleClickItem(int row, int column)
|
||||
{
|
||||
if(_mode == MODE_SIMPLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
int idx = ((row * g_thumbnail_column_count) + column) / 2;
|
||||
bool ch1 = column % 2 == 0;// ? " - [CH1]" : " - [CH2]";
|
||||
selectedFile = _items.at(idx)->filePath;// ch1 ? FMThumbnailDialog::_thumbnails.at(idx).first : FMThumbnailDialog::_thumbnails.at(idx).second;
|
||||
accept();
|
||||
//qInfo() << "idx:" << idx << selectedFile << __FUNCTION__;
|
||||
}
|
||||
void FMThumbnailDialog::onSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
|
||||
{
|
||||
//qInfo() << __FUNCTION__;
|
||||
|
||||
QModelIndex index = selected.indexes().first();
|
||||
int idx = ((index.row() * g_thumbnail_column_count) + index.column()) / 2;
|
||||
// bool ch1 = index.column() % 2 == 0;// ? " - [CH1]" : " - [CH2]"; // 더블클릭 재생으로 이동
|
||||
#if (USE_DATE_FILTER)
|
||||
selectedFile = FMThumbnailDialog::_files.at((idx * 2) + (ch1 ? 0 : 1));
|
||||
accept();
|
||||
#endif // USE_DATE_FILTER
|
||||
|
||||
#if (USE_1HOUR_FILTER)
|
||||
if (FMThumbnailDialog::_thumbnails.size() <= idx) {
|
||||
return;
|
||||
}
|
||||
if(_mode == MODE_SIMPLE) {
|
||||
RMVideoItem* item = FMThumbnailDialog::_items.at(idx);
|
||||
_selectedDateTime = item->startTime();
|
||||
_mode = MODE_SUB;
|
||||
onLoadThumbnails();
|
||||
_tableView->setEnabled(false);
|
||||
QTimer::singleShot(300,Qt::PreciseTimer,this,SLOT(onEnableClick()));
|
||||
} else {
|
||||
// 더블클릭 재생으로 변경
|
||||
//selectedFile = ch1 ? FMThumbnailDialog::_thumbnails.at(idx).first : FMThumbnailDialog::_thumbnails.at(idx).second;
|
||||
//accept();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void FMThumbnailDialog::onEnableClick()
|
||||
{
|
||||
_tableView->setEnabled(true);
|
||||
}
|
||||
void FMThumbnailDialog::createLayout(MODE mode,RMVideoItem* selected)
|
||||
{
|
||||
}
|
||||
#if (USE_DATE_FILTER)
|
||||
void FMThumbnailDialog::loadThumbnails(QString folder)
|
||||
{
|
||||
thumbnail_cache::instance()->clear();
|
||||
QDir dir(folder);
|
||||
dir.setFilter(QDir::Dirs);
|
||||
foreach (const QString& eachFolder, dir.entryList()) {
|
||||
|
||||
if(eachFolder == "." || eachFolder == "..")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// 폴더는 탐색
|
||||
QString fullPath = QDir::cleanPath(folder + PATH_COMPONENT + eachFolder);
|
||||
loadThumbnails(fullPath);
|
||||
}
|
||||
|
||||
QDir dirFile(folder);
|
||||
dirFile.setNameFilters(QList<QString>() << QString("*.JPG"));
|
||||
QStringList allFiles = dirFile.entryList();
|
||||
foreach (const QString& eachFile, allFiles) {
|
||||
//QDateTime dateTime;
|
||||
QString fullPath = QDir::cleanPath(folder + PATH_COMPONENT + eachFile);
|
||||
|
||||
QRegExp regexp("[0-9]{8}-[0-9]{6}_(?:REC|MOT|PSR|EVT)[0,1,2]_[0-9]{4}_[0-9]{1}.jpg"); // $
|
||||
//QRegExp regexp("[0-9]{8}-[0-9]{6}_(?:REC|EVT)_[0-9]{4}_[0-9]{1}.jpg"); // $
|
||||
if(regexp.exactMatch(eachFile)) {
|
||||
_files.append(fullPath);
|
||||
//qInfo() << eachFile << __FUNCTION__;
|
||||
}
|
||||
}
|
||||
}
|
||||
void FMThumbnailDialog::onLoadThumbnails()
|
||||
{
|
||||
_files.clear();
|
||||
_tableView->setItemDelegate(NULL);
|
||||
loadThumbnails(_folder);
|
||||
|
||||
qSort(_files.begin(),_files.end());
|
||||
|
||||
int itemCount = _files.size(); // 파일개수
|
||||
int rowCount = qMax((int)ceil((double)(itemCount) / ((double)g_thumbnail_column_count)),g_thumbnail_row_count);
|
||||
|
||||
//_tableView->clear();
|
||||
_tableView->setItemDelegate(_delegate);
|
||||
_tableView->setColumnCount(g_thumbnail_column_count);
|
||||
_tableView->setRowCount(rowCount); // ON LOADED 에서 처리
|
||||
//qInfo() << __FUNCTION__;
|
||||
}
|
||||
#else // USE_DATE_FILTER
|
||||
void FMThumbnailDialog::loadThumbnails()
|
||||
{
|
||||
FMThumbnailDialog::_items.clear();
|
||||
//QList<RMVideoItem*> res = QList<RMVideoItem*>();
|
||||
// 1시간 단위
|
||||
if(_mode == MODE_SIMPLE) {
|
||||
RMVideoFileList::instance()->load1HourList(_items);
|
||||
} else {
|
||||
RMVideoFileList::instance()->load1HourInList(_selectedDateTime,_items);
|
||||
}
|
||||
RMVideoFileList::instance()->loadThumbnails(_items,_thumbnails);
|
||||
}
|
||||
void FMThumbnailDialog::onLoadThumbnails()
|
||||
{
|
||||
// 선택해제하지 않으면 이후 이전 선택된 CELL 선택이 안됨
|
||||
_tableView->selectionModel()->blockSignals(true);
|
||||
_tableView->clearSelection();
|
||||
_tableView->selectionModel()->blockSignals(false);
|
||||
|
||||
_tableView->setItemDelegate(NULL);
|
||||
|
||||
loadThumbnails();
|
||||
|
||||
int itemCount = FMThumbnailDialog::_thumbnails.size() * 2;// 0;//_files.size(); // 파일개수
|
||||
int rowCount = qMax((int)ceil((double)(itemCount) / ((double)g_thumbnail_column_count)),g_thumbnail_row_count);
|
||||
|
||||
_tableView->setItemDelegate(_delegate);
|
||||
_tableView->setColumnCount(g_thumbnail_column_count);
|
||||
_tableView->setRowCount(rowCount); // ON LOADED 에서 처리
|
||||
|
||||
_backButton->setHidden(_mode == MODE_SIMPLE);
|
||||
QString wTitle = "";
|
||||
QString barTitle = "";
|
||||
if(_mode == MODE_SIMPLE) {
|
||||
barTitle = FM_WSTR(L"1시간 대표 이미지");
|
||||
wTitle = FM_WSTR(L"1시간리스트 (이미지 클릭 시 1시간내 전체 이미지를 볼 수 있습니다.)");
|
||||
} else {
|
||||
wTitle = FM_WSTR(L"세부리스트 (이미지 더블 클릭 시 해당 영상이 재생됩니다.)");
|
||||
|
||||
QString title = _items.first()->startTime().toString("yyyy-MM-dd HH:mm:ss");
|
||||
title += " ~ ";
|
||||
title += _items.last()->startTime().toString("yyyy-MM-dd HH:mm:ss");
|
||||
barTitle = title;
|
||||
}
|
||||
_titleBar->setText(barTitle + QString().sprintf(" [%d]",_items.size()));
|
||||
//setWindowTitle(wTitle + QString().sprintf(" [%d]",_items.size()));
|
||||
setWindowTitle(wTitle);
|
||||
|
||||
}
|
||||
void FMThumbnailDialog::onBack() {
|
||||
_mode = MODE_SIMPLE;
|
||||
onLoadThumbnails();
|
||||
}
|
||||
#endif // USE_DATE_FILTER
|
||||
|
||||
|
||||
FMThumbnailDelegate::FMThumbnailDelegate(QObject *parent) :
|
||||
QStyledItemDelegate(parent)
|
||||
{
|
||||
_dialog = (FMThumbnailDialog*)parent;
|
||||
}
|
||||
#if (USE_DATE_FILTER)
|
||||
void FMThumbnailDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
QRect rect = option.rect;
|
||||
|
||||
painter->fillRect(rect,QColor(0x33,0x33,0x33));
|
||||
|
||||
//qInfo() << rect << index << index.column() << __FUNCTION__;
|
||||
painter->setRenderHint(QPainter::NonCosmeticDefaultPen); // Antialiasing
|
||||
int idx = ((index.row() * g_thumbnail_column_count) + index.column()) / 2;
|
||||
bool ch1 = index.column() % 2 == 0;// ? " - [CH1]" : " - [CH2]";
|
||||
|
||||
// _dialog->_items.size()
|
||||
bool drawItem = true;
|
||||
// if(_dialog->_loadedCount <= idx) {
|
||||
// drawItem = false;
|
||||
// }
|
||||
|
||||
if(drawItem) {
|
||||
//RMVideoItem* item = _dialog->_items.at(idx);
|
||||
//qInfo() << idx << __FUNCTION__;
|
||||
QString p1 = FMThumbnailDialog::_files.at((idx * 2) + (ch1 ? 0 : 1));
|
||||
|
||||
//painter->fillRect(option.rect,background);
|
||||
QFont font = QFont("Arial", 1);
|
||||
font.setPixelSize(12);
|
||||
painter->setFont(font);
|
||||
QRect tr = QRect(rect.left()+1,rect.bottom()-g_thumbnail_title_height,rect.width(),g_thumbnail_title_height);
|
||||
//tr.adjust(0,tr.height() - g_thumbnail_title_height,0,- g_thumbnail_title_height);
|
||||
//tr.setHeight(g_thumbnail_height);
|
||||
|
||||
painter->fillRect(tr,QColor(0x33,0x33,0x33)); // "#333333"
|
||||
|
||||
QFileInfo fi(p1);
|
||||
|
||||
painter->setPen(QPen(QColor(0xDD,0xDD,0xDD))); // "#DDDDDD"
|
||||
painter->drawText(tr, Qt::AlignCenter | Qt::AlignVCenter, fi.baseName());
|
||||
//qInfo() << "TR:" << tr << "RECT:" << rect.size() << __LINE__;
|
||||
|
||||
|
||||
|
||||
//QPixmap map;
|
||||
if (fi.exists()) {
|
||||
|
||||
QRect ir = rect;
|
||||
ir.adjust(0,0,-0,-g_thumbnail_title_height);
|
||||
|
||||
|
||||
//int iid = (index.row() * g_thumbnail_column_count) + index.column();
|
||||
QPixmap pix = thumbnail_cache::instance()->thumbnail(p1,index.row(),ir.size());
|
||||
if (!pix.isNull()) {
|
||||
painter->drawPixmap(rectAspectFit(ir,pix.width(),pix.height()),pix);
|
||||
}
|
||||
|
||||
// if(p1.contains("040556_PSR0_0017_") || p1.contains("040536_PSR0_0016_")) {
|
||||
// qInfo() << "DRAW:" << p1 << ir << __FUNCTION__;
|
||||
// }
|
||||
// painter->scale(1*((double)(ir.width())/(double)(map.width())),1*((double)(ir.height())/(double)(map.height())));
|
||||
// painter->scale(1,1);
|
||||
}
|
||||
|
||||
// IR: QRect(0,166 254x143) PIX SIZE: QSize(247, 138) RECT: QRect(0,166 254x165) 930
|
||||
/*
|
||||
if(thumbnails.size() > 1) {
|
||||
QRect ir = rect;
|
||||
ir.adjust(0,0,-0,-g_thumbnail_title_height);
|
||||
//ir.adjust(g_thumbnail_border_size,g_thumbnail_border_size,-g_thumbnail_border_size,-(g_thumbnail_title_height+g_thumbnail_border_size));
|
||||
|
||||
FMThumbnail* thumb = item->thumbnails.at(ch1 ? 0 : 1);
|
||||
|
||||
//qInfo() << thumb->size << __FUNCTION__;
|
||||
|
||||
if(thumb->size == 0) {
|
||||
painter->fillRect(ir,QColor(0x11,0x11,0x11));// "#111111"
|
||||
painter->drawText(ir, Qt::AlignCenter | Qt::AlignVCenter, QString::fromWCharArray(L"로딩 실패"));
|
||||
}
|
||||
else {
|
||||
QPixmap pix;
|
||||
pix.loadFromData(thumb->buffer,thumb->size);
|
||||
painter->drawPixmap(ir,pix);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
// 외곽선 그리기
|
||||
QPen pen2; // c5ff5f
|
||||
pen2.setJoinStyle(Qt::MiterJoin);
|
||||
pen2.setColor(QColor(0xd0,0xd5,0xef)); // d0d5ef,b8bee0
|
||||
pen2.setWidth(4);
|
||||
painter->setPen(pen2);
|
||||
|
||||
QLine lines[3];
|
||||
int al = rect.left()+1;
|
||||
int ar = rect.right() - (ch1 ? 0 : 1);
|
||||
int at = rect.top()+1;
|
||||
int ab = rect.bottom();
|
||||
lines[0] = !ch1 ? QLine(al,at,ar,at) : QLine(ar,at,al,at);
|
||||
lines[1] = !ch1 ? QLine(ar,at,ar,ab) : QLine(al,at,al,ab);
|
||||
lines[2] = !ch1 ? QLine(ar,ab,al,ab) : QLine(al,ab,ar,ab);
|
||||
|
||||
painter->drawLines(lines,3);
|
||||
|
||||
// GRID LINE
|
||||
pen2.setColor(QColor(0x31,0x33,0x4A)); // fcc186,31334a
|
||||
pen2.setWidth(1);
|
||||
painter->setPen(pen2);
|
||||
if(!ch1) {
|
||||
painter->drawLine(QLine(ar+1,at,ar+1,ab));
|
||||
}
|
||||
//painter->drawLine(QLine(al-1,ab,ar,ab));
|
||||
|
||||
if(drawItem) {
|
||||
bool hover = option.state & QStyle::State_MouseOver;
|
||||
if (hover) {
|
||||
//qInfo() << "STATE:" << QString().sprintf("%0X",(int)option.state) << __FUNCTION__;
|
||||
int iw = g_thumbnail_border_size / 2;
|
||||
QRect br = rect;
|
||||
br.adjust(iw,iw,-iw,-iw);
|
||||
QPen pen; // c5ff5f
|
||||
pen.setJoinStyle(Qt::MiterJoin);
|
||||
pen.setColor(QColor(0xFF,0x99,0x33)); // "#FF9933"
|
||||
pen.setWidth(g_thumbnail_border_size);
|
||||
painter->setPen(pen);
|
||||
//QPalette palette = _checkContainerWidget->palette();
|
||||
//palette.setColor(_checkContainerWidget->backgroundRole(),background);
|
||||
//qInfo() << "index:" << index << "option:" << option.rect << __FUNCTION__;
|
||||
painter->drawRect(br);// fillRect(r, QColor(0,0,0,10));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#else // #if (USE_DATE_FILTER)
|
||||
void FMThumbnailDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
QRect rect = option.rect;
|
||||
|
||||
painter->fillRect(rect,QColor(0x33,0x33,0x33));
|
||||
|
||||
painter->setRenderHint(QPainter::NonCosmeticDefaultPen); // Antialiasing
|
||||
int idx = ((index.row() * g_thumbnail_column_count) + index.column()) / 2;
|
||||
bool ch1 = index.column() % 2 == 0;// ? " - [CH1]" : " - [CH2]";
|
||||
|
||||
if(FMThumbnailDialog::_thumbnails.size() <= idx) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool drawItem = true;
|
||||
|
||||
if(drawItem) {
|
||||
QString p1 = ch1 ? FMThumbnailDialog::_thumbnails.at(idx).first : FMThumbnailDialog::_thumbnails.at(idx).second;
|
||||
//painter->fillRect(option.rect,background);
|
||||
QFont font = QFont("Arial", 1);
|
||||
font.setPixelSize(12);
|
||||
painter->setFont(font);
|
||||
QRect tr = QRect(rect.left()+1,rect.bottom()-g_thumbnail_title_height,rect.width(),g_thumbnail_title_height);
|
||||
//tr.adjust(0,tr.height() - g_thumbnail_title_height,0,- g_thumbnail_title_height);
|
||||
//tr.setHeight(g_thumbnail_height);
|
||||
|
||||
painter->fillRect(tr,QColor(0x33,0x33,0x33)); // "#333333"
|
||||
|
||||
QFileInfo fi(p1);
|
||||
|
||||
painter->setPen(QPen(QColor(0xDD,0xDD,0xDD))); // "#DDDDDD"
|
||||
//painter->drawText(tr, Qt::AlignCenter | Qt::AlignVCenter, fi.baseName());
|
||||
if(ch1) {
|
||||
painter->drawText(tr, Qt::AlignRight | Qt::AlignVCenter, fi.baseName().left(8));
|
||||
} else {
|
||||
painter->drawText(tr, Qt::AlignLeft | Qt::AlignVCenter, fi.baseName().mid(8, 7));
|
||||
}
|
||||
//qInfo() << "TR:" << tr << "RECT:" << rect.size() << __LINE__;
|
||||
|
||||
//QPixmap map;
|
||||
|
||||
|
||||
QRect ir = rect;
|
||||
ir.adjust(0,0,-0,-g_thumbnail_title_height);
|
||||
|
||||
QPixmap pix;
|
||||
//int iid = (index.row() * g_thumbnail_column_count) + index.column();
|
||||
if (fi.exists()) {
|
||||
pix = thumbnail_cache::instance()->thumbnail(p1,index.row(),ir.size());
|
||||
} else {
|
||||
static QPixmap no_image;
|
||||
// 200,133
|
||||
//qInfo() << ir.size() << __FUNCTION__;
|
||||
if(no_image.isNull()) {
|
||||
QPixmap ni = QPixmap(":/image/no_thumbnail.png");
|
||||
if(ni.width() != ir.size().width() || ni.height() != ir.size().width()) {
|
||||
no_image = ni.scaled(ir.size().width(),ir.size().width(),Qt::KeepAspectRatio,Qt::SmoothTransformation);
|
||||
} else {
|
||||
no_image = ni;
|
||||
}
|
||||
}
|
||||
pix = no_image;
|
||||
}
|
||||
if (!pix.isNull()) {
|
||||
painter->drawPixmap(rectAspectFit(ir,pix.width(),pix.height()),pix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 외곽선 그리기
|
||||
QPen pen2; // c5ff5f
|
||||
pen2.setJoinStyle(Qt::MiterJoin);
|
||||
pen2.setColor(QColor(0xd0,0xd5,0xef)); // d0d5ef,b8bee0
|
||||
pen2.setWidth(4);
|
||||
painter->setPen(pen2);
|
||||
|
||||
QLine lines[3];
|
||||
int al = rect.left()+1;
|
||||
int ar = rect.right() - (ch1 ? 0 : 1);
|
||||
int at = rect.top()+1;
|
||||
int ab = rect.bottom();
|
||||
lines[0] = !ch1 ? QLine(al,at,ar,at) : QLine(ar,at,al,at);
|
||||
lines[1] = !ch1 ? QLine(ar,at,ar,ab) : QLine(al,at,al,ab);
|
||||
lines[2] = !ch1 ? QLine(ar,ab,al,ab) : QLine(al,ab,ar,ab);
|
||||
|
||||
painter->drawLines(lines,3);
|
||||
|
||||
// GRID LINE
|
||||
pen2.setColor(QColor(0x31,0x33,0x4A)); // fcc186,31334a
|
||||
pen2.setWidth(1);
|
||||
painter->setPen(pen2);
|
||||
if(!ch1) {
|
||||
painter->drawLine(QLine(ar+1,at,ar+1,ab));
|
||||
}
|
||||
//painter->drawLine(QLine(al-1,ab,ar,ab));
|
||||
|
||||
if(drawItem) {
|
||||
bool hover = option.state & QStyle::State_MouseOver;
|
||||
if (hover) {
|
||||
//qInfo() << "STATE:" << QString().sprintf("%0X",(int)option.state) << __FUNCTION__;
|
||||
int iw = g_thumbnail_border_size / 2;
|
||||
QRect br = rect;
|
||||
br.adjust(iw,iw,-iw,-iw-g_thumbnail_title_height);
|
||||
QPen pen; // c5ff5f
|
||||
pen.setJoinStyle(Qt::MiterJoin);
|
||||
pen.setColor(QColor(0xFF,0x99,0x33)); // "#FF9933"
|
||||
pen.setWidth(g_thumbnail_border_size);
|
||||
painter->setPen(pen);
|
||||
painter->drawRect(br);// fillRect(r, QColor(0,0,0,10));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif // #else // #if (USE_DATE_FILTER)
|
||||
|
||||
void FMThumbnailDelegate::entered(const QModelIndex &index)
|
||||
{
|
||||
qInfo() << index << __FUNCTION__ << __LINE__;
|
||||
}
|
||||
|
||||
|
||||
thumbnail_cache::thumbnail_cache(QObject* parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
QPixmap thumbnail_cache::_load(QString path, const QSize& wh)
|
||||
{
|
||||
QPixmap map;
|
||||
map.load(path);
|
||||
|
||||
// 1:1 이미지 CROP
|
||||
if((float)map.width() / (float)map.height() < 1.1) {
|
||||
|
||||
|
||||
// 16:9 = 1.7777
|
||||
qreal wr = (qreal)wh.width() / (qreal)wh.height(); // 1.7777
|
||||
//qreal tw = wr; // 0.88888
|
||||
|
||||
int width = map.width();
|
||||
int height = map.height() / wr;
|
||||
|
||||
// 50% 크롭 영역 계산 (가운데 50%만 남기기)
|
||||
// 시작점은 너비와 높이의 25% 지점
|
||||
|
||||
// 잘라낼 영역의 너비와 높이는 원본의 50%
|
||||
//int cropHeight = height * 0.5;
|
||||
//int cropWidth = cropHeight * wr;
|
||||
int yOffset = (map.width() - height) / 2;
|
||||
//int xOffset = (width - cropWidth) / 2;
|
||||
|
||||
//qInfo() << "wh:" << wh << "width:" << width << "height:" << height << "X:" << xOffset << cropWidth << "Y:" << yOffset << cropHeight;
|
||||
map = map.copy(QRect(0, yOffset, width, height));
|
||||
}
|
||||
|
||||
|
||||
// resize
|
||||
if(map.width() > wh.width() || map.height() > wh.height())
|
||||
{
|
||||
map = map.scaled(wh.width(),wh.height(),Qt::KeepAspectRatio,Qt::SmoothTransformation);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
const QPixmap thumbnail_cache::thumbnail(const QString path,int index, const QSize& wh)
|
||||
{
|
||||
// 존재할 경우 리턴
|
||||
if(cache.contains(path)) {
|
||||
//qInfo() << "E" << path << __FUNCTION__;
|
||||
return cache.value(path);
|
||||
}
|
||||
|
||||
// 없으면 생성
|
||||
QFuture<QPixmap> loaded = QtConcurrent::run(this,&thumbnail_cache::_load,path,wh);
|
||||
cache[path] = loaded;
|
||||
|
||||
emit thumbnailLoaded(index);
|
||||
return _dummy;
|
||||
}
|
||||
|
||||
#endif // #if (GENERATE_THUMBNAIL)
|
||||
Reference in New Issue
Block a user