Advertisement
Guest User

Untitled

a guest
Mar 26th, 2021
415
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.58 KB | None | 0 0
  1. #include "PageView.h"
  2.  
  3. PageView::PageView(QString path, int pageIndex, QWidget *sizeTarget)
  4.     :mPath{path}, mCurrentPage{pageIndex}
  5. {
  6.     mSizeTarget = sizeTarget;
  7.  
  8.  
  9.     mTimer = new QTimer();
  10.     connect(mTimer, SIGNAL(timeout()),
  11.             this, SLOT(on_time_out()));
  12.     connect(this, SIGNAL(load_finished(int, MediaRecord *)),
  13.             this, SLOT(on_load_finished(int, MediaRecord *)));
  14.  
  15.     initData();
  16.     initUI();
  17.  
  18.     mLastSize = mSizeTarget->size();
  19.     resizeAllMedium(Vertical);
  20.  
  21.     on_time_out();
  22.     mLabels->at(mCurrentPage)->show();
  23. }
  24.  
  25. PageView::~PageView(){
  26.  
  27.     if (mZipReader != nullptr)
  28.         delete mZipReader;
  29.  
  30.     if (mTimer != nullptr)
  31.         mTimer->deleteLater();
  32.  
  33.     if (mThread != nullptr){
  34.         if (mThread->isRunning()){
  35.             mThread->quit();
  36.             mThread->wait();
  37.         }
  38.         mThread->deleteLater();
  39.     }
  40.  
  41.     if (mReaders != nullptr){
  42.         while (!mReaders->isEmpty())
  43.             delete mReaders->dequeue();
  44.         delete mReaders;
  45.     }
  46.  
  47.     if (mLabels != nullptr){
  48.         while (!mLabels->isEmpty()){
  49.             PageLabel *label = mLabels->dequeue();
  50.             if (label->movie() != nullptr)
  51.                 delete label->movie();
  52.             label->clear();
  53.             label->deleteLater();
  54.         }
  55.         delete mLabels;
  56.     }
  57.  
  58.  
  59.  
  60.     if (mMedia != nullptr){
  61.         while (!mMedia->isEmpty()){
  62.             MediaRecord *record = mMedia->dequeue();
  63.             delete record->movieData;
  64.             delete record->pixmap;
  65.             delete record;
  66.         }
  67.         delete mMedia;
  68.     }
  69. }
  70.  
  71. void PageView::initData(){
  72.     mReaders = new QQueue<QImageReader *>();
  73.     mMedia = new QQueue<MediaRecord *>();
  74.     mLabels = new QQueue<PageLabel *>();
  75.  
  76.     if (ArkUtility::isCompressed(QFileInfo{mPath}.fileName())){
  77.         mZipReader = new QZipReader(mPath);
  78.  
  79.         foreach(QZipReader::FileInfo item, mZipReader->fileInfoList()){
  80.             if (item.isFile){
  81.                 if (item.filePath.endsWith("jpg", Qt::CaseInsensitive) ||
  82.                     item.filePath.endsWith("png", Qt::CaseInsensitive) ||
  83.                     item.filePath.endsWith("gif", Qt::CaseInsensitive) ||
  84.                     item.filePath.endsWith("bmp", Qt::CaseInsensitive)){
  85.  
  86.                     mReaders->enqueue(new QImageReader{item.filePath});
  87.                     mMedia->enqueue(new MediaRecord());
  88.                 }
  89.             }
  90.         }
  91.     }
  92.     else{
  93.         QFileInfoList fileInfoList = QDir{mPath}.entryInfoList(
  94.                     QStringList()<< "*.jpg" << "*.png" << "*.gif" << "*.bmp",
  95.                     QDir::Files|QDir::NoDotAndDotDot, QDir::Name|QDir::IgnoreCase);
  96.  
  97.         foreach(QFileInfo item, fileInfoList){
  98.             mReaders->enqueue(new QImageReader(item.absoluteFilePath()));
  99.             mMedia->enqueue(new MediaRecord());
  100.         }
  101.     }
  102.  
  103. }
  104.  
  105. void PageView::initUI(){
  106.  
  107.     createLabels();
  108.  
  109.     mMultiLayout = createMultiLayout();
  110.     mMultiArea = getScrollArea(mMultiLayout);
  111.     mVScrollBar = mMultiArea->verticalScrollBar();
  112.     mHScrollBar = mMultiArea->horizontalScrollBar();
  113.  
  114.     connect(mVScrollBar, SIGNAL(valueChanged(int)),
  115.              this, SLOT(on_scroll_changed(int)));
  116.  
  117.     mMainLayout = new QGridLayout();
  118.     mMainLayout->addWidget(mMultiArea, 0, 0);
  119.     mMainLayout->setMargin(0);
  120.  
  121.     setLayout(mMainLayout);
  122. }
  123.  
  124. QScrollArea* PageView::getScrollArea(QGridLayout *layout){
  125.     QGridLayout *arealayout = new QGridLayout();
  126.     arealayout->addLayout(layout,0,0);
  127.  
  128.     QWidget *widget = new QWidget(this);
  129.     widget->setLayout(arealayout);
  130.  
  131.     QScrollArea *area = new QScrollArea(this);
  132.     area->setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded );
  133.     area->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
  134.     area->setWidgetResizable(true);
  135.     area->setWidget(widget);
  136.  
  137.     return area;
  138. }
  139.  
  140. void PageView::createLabels(){
  141.     for (int i = 0; i < mReaders->size(); i++ ) {
  142.         PageLabel *label = new PageLabel(QString::number(i+1));
  143.         label->hide();
  144.         label->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
  145.         label->setScaledContents(true);
  146.         connect(label, SIGNAL(page_clicked(Qt::MouseButton)),
  147.                 this, SLOT(on_page_clicked(Qt::MouseButton)));
  148.         mLabels->enqueue(label);
  149.     }
  150. }
  151.  
  152.  
  153. QGridLayout* PageView::createMultiLayout(){
  154.  
  155.     QGridLayout *multiLayout = new QGridLayout();
  156.  //   QVBoxLayout *v = new QVBoxLayout();
  157.  
  158.     for (int i = 0; i < mLabels->size(); i++ )
  159.         multiLayout->addWidget(mLabels->at(i), i, 0, Qt::AlignHCenter|Qt::AlignBaseline);
  160. //        v->addWidget(mLabels->at(i), 0, Qt::AlignHCenter);
  161. //multiLayout->addLayout(v,0,0,Qt::AlignCenter);
  162.     qDebug() << "================================spacing: "  << multiLayout->count();
  163.  
  164.     multiLayout->setSpacing(5);
  165.     return multiLayout;
  166. }
  167.  
  168. void PageView::on_scroll_changed(int value){
  169.     if (mIsClickMode){
  170. //        qDebug()<< mCurrentPage<<  " mCurrentPage: " << mLabels->at(mCurrentPage)->size();
  171. //        qDebug()<< mCurrentPage << ", mSizeTarget:  " << mSizeTarget->size() - QSize{50,60};
  172. //        qDebug() << "" ;
  173.         return;
  174.     }
  175.  
  176.  
  177.  
  178.     int spacing = 5;
  179.     int total = 0 + spacing;
  180.  
  181.     for (int i = 0; i < mLabels->size(); i++){
  182.         total += mLabels->at(i)->size().height() + spacing;
  183.         mCurrentPage = i;
  184.         if (total - mLabels->at(i)->size().height() / 2  > value)
  185.             break;
  186.     }
  187. //    qDebug()<< mCurrentPage<<  " mCurrentPage: " << mLabels->at(mCurrentPage)->size();
  188. //    qDebug()<< mCurrentPage << ", mSizeTarget:  " << mSizeTarget->size() - QSize{50,60};
  189. //    qDebug() << "" ;
  190.  
  191.  
  192.     mTimer->stop();    
  193.     mTimer->start(200);
  194. }
  195.  
  196. void PageView::on_time_out(){
  197.     mTimer->stop();
  198.  
  199.     if (mThread != nullptr ){
  200.         mThread->quit();
  201.         mThread->wait();
  202.         mThread->deleteLater();
  203.     }
  204.  
  205.     mThread = QThread::create([=]{        
  206.         int size = mLabels->size();
  207.         int buffCount = 3;
  208.  
  209.         for (int i = 0; i < size; i++){
  210.  
  211.             if (mLabels->at(i)->visibleRegion().isEmpty())
  212.                 continue;
  213.  
  214.             MediaRecord *theMedia = mMedia->at(i);
  215.             if (theMedia->movieData->isNull() && theMedia->pixmap->isNull())
  216.                 emit load_finished(i, loadPixmap(i));
  217.         }
  218.  
  219.         for (int i = 1; i < size; i++){
  220.  
  221.             if (mLabels->at(i)->visibleRegion().isEmpty())
  222.                 continue;
  223.             else {
  224.                 for (int j = i-buffCount; j <= i; j++){
  225.                     if (j < 0)
  226.                         continue;
  227.  
  228.                     MediaRecord *theMedia = mMedia->at(j);
  229.                     if (theMedia->movieData->isNull() && theMedia->pixmap->isNull())
  230.                         emit load_finished(j, loadPixmap(j));
  231.                 }
  232.                 break;
  233.             }
  234.         }
  235.         for (int i = size - 2; i > 0; i--){
  236.  
  237.             if (mLabels->at(i)->visibleRegion().isEmpty())
  238.                 continue;
  239.             else {
  240.                 for (int j = i+buffCount; j >= i; j--){
  241.                     if (j > size - 1)
  242.                         continue;
  243.  
  244.                     MediaRecord *theMedia = mMedia->at(j);
  245.                     if (theMedia->movieData->isNull() && theMedia->pixmap->isNull())
  246.                         emit load_finished(j, loadPixmap(j));
  247.                 }
  248.                 break;
  249.             }
  250.         }
  251.  
  252.         MediaRecord *theMedia = mMedia->at(mCurrentPage);
  253.         if (theMedia->movieData->isNull() && theMedia->pixmap->isNull())
  254.             emit load_finished(mCurrentPage, loadPixmap(mCurrentPage));
  255.     });
  256.     mThread->start();
  257. }
  258.  
  259. MediaRecord* PageView::loadPixmap(int index){
  260.  
  261.     QString path{mReaders->at(index)->fileName()};
  262.  
  263.  
  264.     MediaRecord *record = new MediaRecord;
  265.  
  266.     if (path.endsWith(".gif", Qt::CaseInsensitive)){
  267.  
  268.         if (mZipReader != nullptr){            
  269.             record->movieData->append(mZipReader->fileData(path));
  270.             return record;
  271.         }
  272.         else {          
  273.             QFile *movieFile = new QFile(path);
  274.             if (movieFile->open(QIODevice::ReadOnly))
  275.                 record->movieData->append(movieFile->readAll());
  276.             return record;
  277.         }
  278.     }
  279.  
  280.     QImage image;
  281.  
  282.     bool isSuccessed;
  283.  
  284.     isSuccessed = (mZipReader != nullptr) ?
  285.                 image.loadFromData(mZipReader->fileData(path)):
  286.                 image.load(path);
  287.  
  288.     if (!isSuccessed)
  289.         return record;
  290.  
  291.     QPixmap pixmap = QPixmap::fromImage(image);
  292.  
  293.  
  294.  
  295.     record->pixmap->swap(pixmap);
  296.  
  297.     return record;
  298. }
  299.  
  300. void PageView::on_load_finished(int index, MediaRecord *record){
  301.  
  302.     MediaRecord *theMediam = mMedia->at(index);
  303.     PageLabel *theLabel = mLabels->at(index);
  304.  
  305.     //theLabel->setText("");
  306.  
  307.     if (!record->pixmap->isNull()){
  308.        theMediam->pixmap->swap(*record->pixmap);
  309.        theLabel->setPixmap(*theMediam->pixmap);
  310.     }
  311.     else if (!record->movieData->isNull()){
  312.  
  313.        theMediam->movieData->append(*record->movieData);
  314.  
  315.        QBuffer *buffer = new QBuffer(theMediam->movieData);
  316.  
  317.        if (buffer->open(QIODevice::ReadOnly)){
  318.            QMovie *movie = new QMovie{buffer, "GIF"};
  319.            movie->setCacheMode(QMovie::CacheAll);
  320.            movie->setScaledSize(QSize{QImageReader{buffer, "GIF"}.size()});
  321.            movie->start();
  322.            theLabel->setMovie(movie);
  323.        }
  324.     }
  325.     resizeAfterLoad(index);
  326.  
  327.     delete record;
  328. }
  329.  
  330. void PageView::on_page_clicked(Qt::MouseButton button){
  331.  
  332.  
  333.     qDebug() << "sizeHint " <<mLabels->at(mCurrentPage)->sizeHint();
  334.     qDebug() << "minimumSizeHint " <<mLabels->at(mCurrentPage)->minimumSizeHint();
  335.     qDebug() << "maximumSize " <<mLabels->at(mCurrentPage)->maximumSize();
  336.  
  337.     qDebug() << "size " <<mLabels->at(mCurrentPage)->size();
  338.     qDebug() << "" <<mLabels->at(mCurrentPage)->pixmap()->size();
  339.  
  340.     qDebug() << "max" << mVScrollBar->maximum() ;
  341.  
  342.  
  343.  
  344.     if (!mIsClickMode)
  345.         return;
  346.  
  347.     switch (button) {
  348.     case Qt::LeftButton:
  349.     case Qt::ForwardButton:
  350.         if (mCurrentPage >= mLabels->size() -1)
  351.             return;
  352.         mLabels->at(mCurrentPage)->hide();
  353.         mCurrentPage++;
  354.         mLabels->at(mCurrentPage)->show();
  355.  
  356.         break;
  357.     case Qt::RightButton:
  358.     case Qt::BackButton:
  359.         if (mCurrentPage <= 0)
  360.             return;
  361.         mLabels->at(mCurrentPage)->hide();
  362.         mCurrentPage--;
  363.         mLabels->at(mCurrentPage)->show();
  364.         break;
  365.     default:
  366.         break;
  367.     }
  368.     on_time_out();
  369.  
  370.  
  371.     moveToCurrentPage();
  372.  
  373. }
  374.  
  375. QSize PageView::getNewSize(QSize oldSize, ScaleMode mode){
  376.  
  377.       QSize targetSize = mLastSize - QSize{50,60};
  378.       int newWidth;
  379.       int newHeight;
  380.  
  381.       switch (mode) {
  382.       case Vertical:
  383.           newWidth = static_cast<int>(
  384.                       static_cast<double>(targetSize.height()) *
  385.                       static_cast<double>(oldSize.width()) /
  386.                       static_cast<double>(oldSize.height())
  387.                       );
  388.           newHeight = targetSize.height();
  389.           break;
  390.       case Horizontal:
  391.           newWidth = targetSize.width();
  392.           newHeight = static_cast<int>(
  393.                       static_cast<double>(targetSize.width()) *
  394.                       static_cast<double>(oldSize.height()) /
  395.                       static_cast<double>(oldSize.width())
  396.                       );
  397.           break;
  398.       default:
  399.           newWidth = targetSize.width();
  400.           newHeight = targetSize.height();
  401.           break;
  402.       }
  403.       return QSize{newWidth, newHeight};
  404. }
  405.  
  406.  
  407. void PageView::resizeMedium(int index, QSize newSize){
  408.     PageLabel *theLabel = mLabels->at(index);
  409.     MediaRecord *theMediam = mMedia->at(index);
  410.  
  411.  
  412. //    if (index < 15){
  413. //    qDebug() << index << " lab bf" << theLabel->size();
  414. //    qDebug() << "sizeHint: " << theLabel->sizeHint();
  415. //    qDebug() << "minimumSizeHint: " << theLabel->minimumSizeHint();
  416. //    }
  417.     theLabel->setFixedSize(newSize);
  418.  
  419.  
  420.     if (!theMediam->pixmap->isNull()){
  421.         QPixmap newPix = theMediam->pixmap->scaled(
  422.                     newSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
  423.         theLabel->setPixmap(newPix);
  424.     } else if (!theMediam->movieData->isNull()){
  425.         theLabel->movie()->setScaledSize(newSize);
  426.         theLabel->movie()->start();
  427.     }
  428.     mHScrollBar->setValue(mHScrollBar->maximum() / 2);
  429. }
  430.  
  431. void PageView::resizeAfterLoad(int index){
  432.  
  433.  
  434.     QSize newSize = getNewSize(getOriginSize(index), (mIsVertical)?
  435.                                    Vertical:
  436.                                    Horizontal);
  437.     resizeMedium(index, newSize);
  438. }
  439.  
  440. void PageView::resizeAllMedium(ScaleMode mode){
  441.  
  442.     for (int i = 0; i < mLabels->size(); i++){
  443.         QSize oldSize = getOriginSize(i);
  444.         QSize newSize = getNewSize(oldSize, mode);
  445.         resizeMedium(i, newSize);
  446.  
  447.     }
  448.     moveToCurrentPage();
  449.     qDebug() << "count: " << mMultiLayout->count() ;
  450.  
  451. }
  452.  
  453.  
  454. QSize PageView::getOriginSize(int index){
  455.     QSize size = mReaders->at(index)->size();
  456.  
  457.     if (size.isValid())
  458.         return size;
  459.  
  460.     MediaRecord *theMedia = mMedia->at(index);
  461.     if (!theMedia->pixmap->isNull())
  462.         return theMedia->pixmap->size();
  463.  
  464.     PageLabel *theLabel = mLabels->at(index);
  465.     if (!theMedia->movieData->isNull())
  466.         return theLabel->movie()->scaledSize();
  467.  
  468.     return theLabel->size();
  469.  
  470. }
  471.  
  472. void PageView::moveToCurrentPage(){
  473.  
  474.     if (mIsClickMode)
  475.         return;;
  476.  
  477.     int spacing = 5;
  478.     int moveTo = spacing;
  479.     int max = spacing;
  480.  
  481.     for (int i = 0; i < mLabels->size(); i++ ){
  482.         max += mLabels->at(i)->size().height() + spacing;
  483.         if (i < mCurrentPage)
  484.             moveTo += mLabels->at(i)->size().height() + spacing;
  485.     }
  486.  
  487.     mVScrollBar->setMaximum(max);
  488.     mVScrollBar->setValue(moveTo);
  489. }
  490.  
  491.  
  492. void PageView::enlarge(){
  493.     qDebug() << "PageView enlarge" ;
  494. }
  495. void PageView::shrink(){
  496.     qDebug() << "PageView shrink" ;
  497. }
  498.  
  499. void PageView::vertical(){
  500.     mIsVertical = true;
  501.     mLastSize = mSizeTarget->size();
  502.     resizeAllMedium(Vertical);    
  503. }
  504.  
  505. void PageView::horizontal(){
  506.     mIsVertical = false;
  507.     mLastSize = mSizeTarget->size();
  508.     resizeAllMedium(Horizontal);
  509. }
  510.  
  511. bool PageView::switchMode(){
  512.  
  513.     mIsClickMode = !mIsClickMode;
  514.  
  515.  
  516.     if (mIsClickMode){
  517.         for (int i=0; i < mLabels->size(); i++)
  518.             mLabels->at(i)->hide();
  519.         mLabels->at(mCurrentPage)->show();
  520.     }else
  521.         for (int i=0; i < mLabels->size(); i++)
  522.             mLabels->at(i)->show();
  523.  
  524.  
  525.     moveToCurrentPage();
  526.  
  527.     return mIsClickMode;
  528. }
  529.  
  530.  
  531.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement