diff --git a/YACReader/YACReader.pro b/YACReader/YACReader.pro index 42f78184..612112e4 100644 --- a/YACReader/YACReader.pro +++ b/YACReader/YACReader.pro @@ -24,24 +24,13 @@ SOURCES += main.cpp INCLUDEPATH += ../common \ ../custom_widgets +INCLUDEPATH += ../common/rhi -!CONFIG(no_opengl) { - INCLUDEPATH += ../common/gl - greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { - INCLUDEPATH += ../common/rhi - DEFINES += YACREADER_USE_RHI - } -} +HEADERS += ../common/rhi/flow_types.h +SOURCES += ../common/rhi/flow_types.cpp win32 { - LIBS += -loleaut32 -lole32 -lshell32 -luser32 - # When using RHI (Qt 6.7+), don't link OpenGL directly - QRhiWidget handles graphics APIs - greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { - message("RHI mode: not linking opengl32 (using QRhiWidget)") - } else { - LIBS += -lopengl32 - } - + LIBS += -loleaut32 -lole32 -lshell32 -luser32 msvc { QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT /GL QMAKE_LFLAGS_RELEASE += /LTCG @@ -59,7 +48,7 @@ macx { QT += network widgets core multimedia svg -greaterThan(QT_MAJOR_VERSION, 5): QT += openglwidgets core5compat +greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { QT += gui-private @@ -76,7 +65,6 @@ HEADERS += ../common/comic.h \ main_window_viewer.h \ mouse_handler.h \ viewer.h \ - goto_flow.h \ options_dialog.h \ ../common/bookmarks.h \ bookmarks_dialog.h \ @@ -87,7 +75,6 @@ HEADERS += ../common/comic.h \ goto_flow_toolbar.h \ width_slider.h \ notifications_label_widget.h \ - ../common/pictureflow.h \ ../common/custom_widgets.h \ ../common/check_new_version.h \ ../common/qnaturalsorting.h \ @@ -100,20 +87,12 @@ HEADERS += ../common/comic.h \ ../common/http_worker.h \ ../common/exit_check.h \ ../common/scroll_management.h \ - ../common/opengl_checker.h \ ../common/pdf_comic.h \ ../common/global_info_provider.h \ + ../common/rhi/yacreader_flow_rhi.h \ + ../common/rhi/yacreader_comic_flow_rhi.h \ + ../common/rhi/yacreader_page_flow_rhi.h -!CONFIG(no_opengl) { - HEADERS += ../common/gl/yacreader_flow_gl.h \ - goto_flow_gl.h - - greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { - HEADERS += ../common/rhi/yacreader_flow_rhi.h - HEADERS += ../common/rhi/yacreader_comic_flow_rhi.h \ - ../common/rhi/yacreader_page_flow_rhi.h - } -} SOURCES += ../common/comic.cpp \ configuration.cpp \ @@ -122,7 +101,6 @@ SOURCES += ../common/comic.cpp \ main_window_viewer.cpp \ mouse_handler.cpp \ viewer.cpp \ - goto_flow.cpp \ options_dialog.cpp \ ../common/bookmarks.cpp \ bookmarks_dialog.cpp \ @@ -133,7 +111,6 @@ SOURCES += ../common/comic.cpp \ goto_flow_toolbar.cpp \ width_slider.cpp \ notifications_label_widget.cpp \ - ../common/pictureflow.cpp \ ../common/custom_widgets.cpp \ ../common/check_new_version.cpp \ ../common/qnaturalsorting.cpp \ @@ -146,23 +123,15 @@ SOURCES += ../common/comic.cpp \ ../common/yacreader_global_gui.cpp \ ../common/exit_check.cpp \ ../common/scroll_management.cpp \ - ../common/opengl_checker.cpp \ ../common/global_info_provider.cpp \ + ../common/rhi/yacreader_flow_rhi.cpp \ + ../common/rhi/yacreader_comic_flow_rhi.cpp \ + ../common/rhi/yacreader_page_flow_rhi.cpp -!CONFIG(no_opengl) { - SOURCES += ../common/gl/yacreader_flow_gl.cpp \ - goto_flow_gl.cpp - - greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { - SOURCES += ../common/rhi/yacreader_flow_rhi.cpp - SOURCES += ../common/rhi/yacreader_comic_flow_rhi.cpp \ - ../common/rhi/yacreader_page_flow_rhi.cpp - RESOURCES += ../common/rhi/shaders/shaders.qrc - # Make raw GLSL shader sources editable in Qt Creator - OTHER_FILES += ../common/rhi/shaders/flow.vert \ - ../common/rhi/shaders/flow.frag - } -} +RESOURCES += ../common/rhi/shaders/shaders.qrc +# Make raw GLSL shader sources editable in Qt Creator +OTHER_FILES += ../common/rhi/shaders/flow.vert \ + ../common/rhi/shaders/flow.frag include(../custom_widgets/custom_widgets_yacreader.pri) diff --git a/YACReader/goto_flow.cpp b/YACReader/goto_flow.cpp deleted file mode 100644 index 96e42e84..00000000 --- a/YACReader/goto_flow.cpp +++ /dev/null @@ -1,297 +0,0 @@ -#include "goto_flow.h" -#include "configuration.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "yacreader_flow.h" - -#include "goto_flow_toolbar.h" - -GoToFlow::GoToFlow(QWidget *parent, FlowType flowType) - : GoToFlowWidget(parent), ready(false) -{ - updateTimer = new QTimer; - connect(updateTimer, &QTimer::timeout, this, &GoToFlow::updateImageData); - - worker = new PageLoader(&mutexGoToFlow); - - flow = new YACReaderFlow(this, flowType); - flow->setReflectionEffect(PictureFlow::PlainReflection); - imageSize = Configuration::getConfiguration().getGotoSlideSize(); - - flow->setSlideSize(imageSize); - connect(flow, &PictureFlow::centerIndexChanged, this, &GoToFlowWidget::setPageNumber); - connect(flow, &YACReaderFlow::selected, this, &GoToFlow::goToPage); - connect(flow, &PictureFlow::centerIndexChanged, this, &GoToFlow::preload); - connect(flow, &PictureFlow::centerIndexChangedSilent, this, &GoToFlow::preload); - - connect(toolBar, &GoToFlowToolBar::goToPage, this, &GoToFlow::goToPage); - connect(toolBar, &GoToFlowToolBar::setCenter, flow, &PictureFlow::showSlide); - - mainLayout->addWidget(flow); - toolBar->raise(); - - resize(static_cast(5 * imageSize.width()), toolBar->height() + static_cast(imageSize.height() * 1.7)); - - this->setCursor(QCursor(Qt::ArrowCursor)); -} - -GoToFlow::~GoToFlow() -{ - delete flow; - delete updateTimer; - worker->deleteLater(); -} - -void GoToFlow::keyPressEvent(QKeyEvent *event) -{ - switch (event->key()) { - case Qt::Key_Left: - case Qt::Key_Right: - case Qt::Key_Up: - QApplication::sendEvent(flow, event); - return; - default: - break; - } - - GoToFlowWidget::keyPressEvent(event); -} - -void GoToFlow::resizeEvent(QResizeEvent *event) -{ - QWidget::resizeEvent(event); - - toolBar->move(0, event->size().height() - toolBar->height()); - toolBar->setFixedWidth(width()); -} - -void GoToFlow::centerSlide(int slide) -{ - if (flow->centerIndex() != slide) { - flow->setCenterIndex(slide); - if (ready) // load images if pages are loaded. - { - // worker->reset(); //BUG FIXED : image didn't load if worker was working - preload(); - } - } -} - -void GoToFlow::setNumSlides(unsigned int slides) -{ - // numPagesLabel->setText(tr("Total pages : ")+QString::number(slides)); - // numPagesLabel->adjustSize(); - imagesReady.clear(); - imagesReady.fill(false, slides); - - rawImages.clear(); - rawImages.resize(slides); - - toolBar->setTop(slides); - - imagesLoaded.clear(); - imagesLoaded.fill(false, slides); - - imagesSetted.clear(); - imagesSetted.fill(false, slides); - - numImagesLoaded = 0; - - ready = true; - worker->reset(); - - flow->clear(); - for (unsigned int i = 0; i < slides; i++) - flow->addSlide(QImage()); - flow->setCenterIndex(0); -} - -void GoToFlow::reset() -{ - updateTimer->stop(); - /*imagesLoaded.clear(); - numImagesLoaded = 0; - imagesReady.clear(); - rawImages.clear();*/ - ready = false; -} - -void GoToFlow::setImageReady(int index, const QByteArray &image) -{ - rawImages[index] = image; - imagesReady[index] = true; - preload(); -} - -void GoToFlow::preload() -{ - if (numImagesLoaded < imagesLoaded.size()) - updateTimer->start(30); // TODO comprobar rendimiento, antes era 70 -} - -void GoToFlow::updateImageData() -{ - // can't do anything, wait for the next possibility - if (worker->busy()) - return; - - // set image of last one - int idx = worker->index(); - if (idx >= 0 && !worker->result().isNull()) { - if (!imagesSetted[idx]) { - flow->setSlide(idx, worker->result()); - imagesSetted[idx] = true; - numImagesLoaded++; - rawImages[idx].clear(); - ; // release memory - imagesLoaded[idx] = true; - } - } - - // try to load only few images on the left and right side - // i.e. all visible ones plus some extra -#define COUNT 8 - int indexes[2 * COUNT + 1]; - int center = flow->centerIndex(); - indexes[0] = center; - for (int j = 0; j < COUNT; j++) { - indexes[j * 2 + 1] = center + j + 1; - indexes[j * 2 + 2] = center - j - 1; - } - for (int c = 0; c < 2 * COUNT + 1; c++) { - int i = indexes[c]; - if ((i >= 0) && (i < flow->slideCount())) - if (!imagesLoaded[i] && imagesReady[i]) // slide(i).isNull()) - { - // schedule thumbnail generation - - worker->generate(i, flow->slideSize(), rawImages[i]); - return; - } - } - - // no need to generate anything? stop polling... - updateTimer->stop(); -} - -void GoToFlow::wheelEvent(QWheelEvent *event) -{ - if (event->angleDelta().y() < 0) - flow->showNext(); - else - flow->showPrevious(); - event->accept(); -} - -void GoToFlow::setFlowType(YACReader::FlowType flowType) -{ - flow->setFlowType(flowType); -} - -void GoToFlow::updateConfig(QSettings *settings) -{ - GoToFlowWidget::updateConfig(settings); - - imageSize = Configuration::getConfiguration().getGotoSlideSize(); - flow->setFlowType(Configuration::getConfiguration().getFlowType()); - resize(5 * imageSize.width(), toolBar->height() + imageSize.height() * 1.7); - updateSize(); -} - -void GoToFlow::setFlowRightToLeft(bool b) -{ - flow->setFlowRightToLeft(b); -} - -//----------------------------------------------------------------------------- -// PageLoader -//----------------------------------------------------------------------------- - -PageLoader::PageLoader(QMutex *m) - : QThread(), mutex(m), restart(false), working(false), idx(-1) -{ -} - -PageLoader::~PageLoader() -{ - // TODO this destructor never runs. If it is ever called, it will hang, because - // the implementation is broken due to the absolutely endless loop in run(). - mutex->lock(); - condition.wakeOne(); - mutex->unlock(); - wait(); -} - -bool PageLoader::busy() const -{ - return isRunning() ? working.load() : false; -} - -void PageLoader::generate(int index, QSize size, const QByteArray &rImage) -{ - mutex->lock(); - this->idx = index; - // this->img = QImage(); - this->size = size; - this->rawImage = rImage; - mutex->unlock(); - - if (!isRunning()) - start(); - else { - mutex->lock(); - // already running, wake up whenever ready - restart = true; - condition.wakeOne(); - mutex->unlock(); - } -} - -void PageLoader::run() -{ - for (;;) { - // copy necessary data - mutex->lock(); - this->working = true; - // int idx = this->idx; - - QImage image; - image.loadFromData(this->rawImage); - // let everyone knows it is ready - image = image.scaled(this->size, Qt::KeepAspectRatio, Qt::SmoothTransformation); - - mutex->unlock(); - - mutex->lock(); - this->img = image; - this->working = false; - mutex->unlock(); - - // put to sleep - mutex->lock(); - while (!this->restart) - condition.wait(mutex); - restart = false; - mutex->unlock(); - } -} diff --git a/YACReader/goto_flow.h b/YACReader/goto_flow.h deleted file mode 100644 index 14b52929..00000000 --- a/YACReader/goto_flow.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef __GOTO_FLOW_H -#define __GOTO_FLOW_H - -#include "goto_flow_widget.h" -#include "yacreader_global_gui.h" - -#include - -#include -#include - -#include - -class QLineEdit; -class QPushButton; -class QPixmap; -class QThread; -class QSize; -class QIntValidator; -class QWaitCondition; -class QEvent; -class QLabel; - -class Comic; -class PageLoader; -class YACReaderFlow; -class PictureFlow; -class QKeyEvent; - -class GoToFlow : public GoToFlowWidget -{ - Q_OBJECT -public: - GoToFlow(QWidget *parent = nullptr, FlowType flowType = CoverFlowLike); - ~GoToFlow() override; - bool ready; // comic is ready for read. -private: - YACReaderFlow *flow; - void keyPressEvent(QKeyEvent *event) override; - // Comic * comic; - QSize imageSize; - - QVector imagesLoaded; - QVector imagesSetted; - int numImagesLoaded; - QVector imagesReady; - QVector rawImages; - QTimer *updateTimer; - PageLoader *worker; - void wheelEvent(QWheelEvent *event) override; - QMutex mutexGoToFlow; - -private slots: - void preload(); - void updateImageData(); - void resizeEvent(QResizeEvent *event) override; - -public slots: - void centerSlide(int slide) override; - void reset() override; - void setNumSlides(unsigned int slides) override; - void setImageReady(int index, const QByteArray &image) override; - void setFlowType(YACReader::FlowType flowType) override; - void updateConfig(QSettings *settings) override; - void setFlowRightToLeft(bool b) override; -}; - -//----------------------------------------------------------------------------- -// PageLoader -//----------------------------------------------------------------------------- -class PageLoader : public QThread -{ -public: - PageLoader(QMutex *m); - ~PageLoader() override; - // returns FALSE if worker is still busy and can't take the task - bool busy() const; - void generate(int index, QSize size, const QByteArray &rImage); - void reset() { idx = -1; }; - int index() const { return idx; } - QImage result() const { return img; } - -protected: - void run() override; - -private: - QMutex *mutex; - QWaitCondition condition; - - bool restart; - std::atomic working; - int idx; - - QSize size; - QImage img; - QByteArray rawImage; -}; - -#endif diff --git a/YACReader/goto_flow_gl.cpp b/YACReader/goto_flow_gl.cpp deleted file mode 100644 index 27772e21..00000000 --- a/YACReader/goto_flow_gl.cpp +++ /dev/null @@ -1,164 +0,0 @@ -#include "goto_flow_gl.h" - -#include -#include -#include -#include -#include -#include - -#include "configuration.h" - -#include "goto_flow_toolbar.h" - -GoToFlowGL::GoToFlowGL(QWidget *parent, FlowType flowType) - : GoToFlowWidget(parent) -{ - Q_UNUSED(flowType) - flow = new YACReaderPageFlowImpl(this); - flow->setShowMarks(false); - - imageSize = Configuration::getConfiguration().getGotoSlideSize(); - - flow->setSlideSize(imageSize); - connect(flow, &YACReaderPageFlowImpl::centerIndexChanged, this, &GoToFlowWidget::setPageNumber); - connect(flow, &YACReaderPageFlowImpl::selected, this, &GoToFlowGL::goToPage); - - connect(toolBar, &GoToFlowToolBar::goToPage, this, &GoToFlowGL::goToPage); - connect(toolBar, &GoToFlowToolBar::setCenter, flow, &YACReaderPageFlowImpl::setCenterIndex); - - mainLayout->addWidget(flow); - toolBar->raise(); - - resize(static_cast(5 * imageSize.width()), toolBar->height() + static_cast(imageSize.height() * 1.7)); - - this->setCursor(QCursor(Qt::ArrowCursor)); -} - -GoToFlowGL::~GoToFlowGL() -{ - delete flow; -} - -void GoToFlowGL::reset() -{ - flow->reset(); -} - -void GoToFlowGL::centerSlide(int slide) -{ - if (flow->centerIndex() != slide) { - flow->setCenterIndex(slide); - } -} - -void GoToFlowGL::setFlowType(FlowType flowType) -{ - if (flowType == CoverFlowLike) - flow->setPreset(presetYACReaderFlowClassicConfig); - else if (flowType == Strip) - flow->setPreset(presetYACReaderFlowStripeConfig); - else if (flowType == StripOverlapped) - flow->setPreset(presetYACReaderFlowOverlappedStripeConfig); - else - flow->setPreset(defaultYACReaderFlowConfig); -} - -void GoToFlowGL::setNumSlides(unsigned int slides) -{ - flow->populate(slides); - toolBar->setTop(slides); -} -void GoToFlowGL::setImageReady(int index, const QByteArray &imageData) -{ - flow->rawImages[index] = imageData; - flow->imagesReady[index] = true; -} - -void GoToFlowGL::updateConfig(QSettings *settings) -{ - GoToFlowWidget::updateConfig(settings); - - Performance performance = medium; - switch (settings->value(PERFORMANCE).toInt()) { - case 0: - performance = low; - break; - case 1: - performance = medium; - break; - case 2: - performance = high; - break; - case 3: - performance = ultraHigh; - break; - } - - imageSize = Configuration::getConfiguration().getGotoSlideSize(); - resize(5 * imageSize.width(), toolBar->height() + imageSize.height() * 1.7); - updateSize(); - - flow->setPerformance(performance); - - switch (settings->value(FLOW_TYPE_GL).toInt()) { - case FlowType::CoverFlowLike: - flow->setPreset(presetYACReaderFlowClassicConfig); - break; - case FlowType::Strip: - flow->setPreset(presetYACReaderFlowStripeConfig); - break; - case FlowType::StripOverlapped: - flow->setPreset(presetYACReaderFlowOverlappedStripeConfig); - break; - case FlowType::Modern: - flow->setPreset(defaultYACReaderFlowConfig); - break; - case FlowType::Roulette: - flow->setPreset(pressetYACReaderFlowDownConfig); - break; - case FlowType::Custom: - flow->setCF_RX(settings->value(X_ROTATION).toInt()); - flow->setCF_Y(settings->value(Y_POSITION).toInt()); - flow->setX_Distance(settings->value(COVER_DISTANCE).toInt()); - flow->setCenter_Distance(settings->value(CENTRAL_DISTANCE).toInt()); - flow->setCF_Z(settings->value(ZOOM_LEVEL).toInt()); - flow->setY_Distance(settings->value(Y_COVER_OFFSET).toInt()); - flow->setZ_Distance(settings->value(Z_COVER_OFFSET).toInt()); - flow->setRotation(settings->value(COVER_ROTATION).toInt()); - flow->setFadeOutDist(settings->value(FADE_OUT_DIST).toInt()); - flow->setLightStrenght(settings->value(LIGHT_STRENGTH).toInt()); - flow->setMaxAngle(settings->value(MAX_ANGLE).toInt()); - break; - } - if (Configuration::getConfiguration().getQuickNaviMode()) - flow->setFadeOutDist(20); -} - -void GoToFlowGL::keyPressEvent(QKeyEvent *event) -{ - switch (event->key()) { - case Qt::Key_Left: - case Qt::Key_Right: - case Qt::Key_Up: - QApplication::sendEvent(flow, event); - return; - default: - break; - } - - GoToFlowWidget::keyPressEvent(event); -} - -void GoToFlowGL::resizeEvent(QResizeEvent *event) -{ - QWidget::resizeEvent(event); - - toolBar->move(0, event->size().height() - toolBar->height()); - toolBar->setFixedWidth(width()); -} - -void GoToFlowGL::setFlowRightToLeft(bool b) -{ - flow->setFlowRightToLeft(b); -} diff --git a/YACReader/goto_flow_gl.h b/YACReader/goto_flow_gl.h deleted file mode 100644 index 8afc0ce3..00000000 --- a/YACReader/goto_flow_gl.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef __GOTO_FLOW_GL_H -#define __GOTO_FLOW_GL_H - -#include "yacreader_global.h" -#include "goto_flow_widget.h" - -// Conditional include based on Qt version and RHI availability -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) -#include "yacreader_page_flow_rhi.h" -using YACReaderPageFlowImpl = YACReaderPageFlow3D; -#else -#include "yacreader_flow_gl.h" -using YACReaderPageFlowImpl = YACReaderPageFlowGL; -#endif - -class QLineEdit; -class QIntValidator; -class QPushButton; -class QPushButton; -class QSize; -class QKeyEvent; - -class GoToFlowGL : public GoToFlowWidget -{ - Q_OBJECT -public: - GoToFlowGL(QWidget *parent = nullptr, FlowType flowType = CoverFlowLike); - ~GoToFlowGL() override; - void reset() override; - void centerSlide(int slide) override; - void setFlowType(FlowType flowType) override; - void setNumSlides(unsigned int slides) override; - void setImageReady(int index, const QByteArray &image) override; - - void updateConfig(QSettings *settings) override; - void setFlowRightToLeft(bool b) override; - -private: - YACReaderPageFlowImpl *flow; - void keyPressEvent(QKeyEvent *event) override; - void resizeEvent(QResizeEvent *event) override; - // Comic * comic; - QSize imageSize; -}; - -#endif diff --git a/YACReader/goto_flow_widget.cpp b/YACReader/goto_flow_widget.cpp index 0b32bf7d..1fc339d3 100644 --- a/YACReader/goto_flow_widget.cpp +++ b/YACReader/goto_flow_widget.cpp @@ -1,16 +1,19 @@ #include "goto_flow_widget.h" -#include #include #include #include +#include +#include #include "goto_flow_toolbar.h" #include "configuration.h" -GoToFlowWidget::GoToFlowWidget(QWidget *parent) +GoToFlowWidget::GoToFlowWidget(QWidget *parent, FlowType flowType) : QWidget(parent) { + Q_UNUSED(flowType) + mainLayout = new QVBoxLayout(this); mainLayout->setContentsMargins(0, 0, 0, 0); mainLayout->setSpacing(0); @@ -19,19 +22,151 @@ GoToFlowWidget::GoToFlowWidget(QWidget *parent) setLayout(mainLayout); - // toolBar->installEventFilter(this); + flow = new YACReaderPageFlow3D(this); + flow->setShowMarks(false); + + imageSize = Configuration::getConfiguration().getGotoSlideSize(); + + flow->setSlideSize(imageSize); + connect(flow, &YACReaderPageFlow3D::centerIndexChanged, this, &GoToFlowWidget::setPageNumber); + connect(flow, &YACReaderPageFlow3D::selected, this, &GoToFlowWidget::goToPage); + + connect(toolBar, &GoToFlowToolBar::goToPage, this, &GoToFlowWidget::goToPage); + connect(toolBar, &GoToFlowToolBar::setCenter, flow, &YACReaderPageFlow3D::setCenterIndex); + + mainLayout->addWidget(flow); + toolBar->raise(); + + resize(static_cast(5 * imageSize.width()), toolBar->height() + static_cast(imageSize.height() * 1.7)); + + this->setCursor(QCursor(Qt::ArrowCursor)); } -GoToFlowWidget::~GoToFlowWidget() { } +GoToFlowWidget::~GoToFlowWidget() +{ + delete flow; +} + +void GoToFlowWidget::reset() +{ + flow->reset(); +} + +void GoToFlowWidget::centerSlide(int slide) +{ + if (flow->centerIndex() != slide) { + flow->setCenterIndex(slide); + } +} void GoToFlowWidget::setPageNumber(int page) { toolBar->setPage(page); } +void GoToFlowWidget::setFlowType(FlowType flowType) +{ + if (flowType == CoverFlowLike) + flow->setPreset(presetYACReaderFlowClassicConfig); + else if (flowType == Strip) + flow->setPreset(presetYACReaderFlowStripeConfig); + else if (flowType == StripOverlapped) + flow->setPreset(presetYACReaderFlowOverlappedStripeConfig); + else + flow->setPreset(defaultYACReaderFlowConfig); +} + +void GoToFlowWidget::setNumSlides(unsigned int slides) +{ + flow->populate(slides); + toolBar->setTop(slides); +} + +void GoToFlowWidget::setImageReady(int index, const QByteArray &imageData) +{ + flow->rawImages[index] = imageData; + flow->imagesReady[index] = true; +} + +void GoToFlowWidget::updateSize() +{ + if (Configuration::getConfiguration().getQuickNaviMode() && parentWidget() != nullptr) + resize(parentWidget()->width(), height()); +} + +void GoToFlowWidget::updateConfig(QSettings *settings) +{ + toolBar->updateOptions(); + + Performance performance = medium; + switch (settings->value(PERFORMANCE).toInt()) { + case 0: + performance = low; + break; + case 1: + performance = medium; + break; + case 2: + performance = high; + break; + case 3: + performance = ultraHigh; + break; + } + + imageSize = Configuration::getConfiguration().getGotoSlideSize(); + resize(5 * imageSize.width(), toolBar->height() + imageSize.height() * 1.7); + updateSize(); + + flow->setPerformance(performance); + + switch (settings->value(FLOW_TYPE_GL).toInt()) { + case FlowType::CoverFlowLike: + flow->setPreset(presetYACReaderFlowClassicConfig); + break; + case FlowType::Strip: + flow->setPreset(presetYACReaderFlowStripeConfig); + break; + case FlowType::StripOverlapped: + flow->setPreset(presetYACReaderFlowOverlappedStripeConfig); + break; + case FlowType::Modern: + flow->setPreset(defaultYACReaderFlowConfig); + break; + case FlowType::Roulette: + flow->setPreset(pressetYACReaderFlowDownConfig); + break; + case FlowType::Custom: + flow->setCF_RX(settings->value(X_ROTATION).toInt()); + flow->setCF_Y(settings->value(Y_POSITION).toInt()); + flow->setX_Distance(settings->value(COVER_DISTANCE).toInt()); + flow->setCenter_Distance(settings->value(CENTRAL_DISTANCE).toInt()); + flow->setCF_Z(settings->value(ZOOM_LEVEL).toInt()); + flow->setY_Distance(settings->value(Y_COVER_OFFSET).toInt()); + flow->setZ_Distance(settings->value(Z_COVER_OFFSET).toInt()); + flow->setRotation(settings->value(COVER_ROTATION).toInt()); + flow->setFadeOutDist(settings->value(FADE_OUT_DIST).toInt()); + flow->setLightStrenght(settings->value(LIGHT_STRENGTH).toInt()); + flow->setMaxAngle(settings->value(MAX_ANGLE).toInt()); + break; + } + if (Configuration::getConfiguration().getQuickNaviMode()) + flow->setFadeOutDist(20); +} + +void GoToFlowWidget::setFlowRightToLeft(bool b) +{ + flow->setFlowRightToLeft(b); +} + void GoToFlowWidget::keyPressEvent(QKeyEvent *event) { switch (event->key()) { + case Qt::Key_Left: + case Qt::Key_Right: + case Qt::Key_Up: + QApplication::sendEvent(flow, event); + return; case Qt::Key_Return: case Qt::Key_Enter: toolBar->goTo(); @@ -48,31 +183,10 @@ void GoToFlowWidget::keyPressEvent(QKeyEvent *event) event->accept(); } -void GoToFlowWidget::updateConfig(QSettings *settings) +void GoToFlowWidget::resizeEvent(QResizeEvent *event) { - Q_UNUSED(settings) - toolBar->updateOptions(); -} + QWidget::resizeEvent(event); -void GoToFlowWidget::updateSize() -{ - // called by parent in resizeEvent - // no need to update width when QuickNaviMode disabled - // height is set in updateConfig - if (Configuration::getConfiguration().getQuickNaviMode() && parentWidget() != nullptr) - resize(parentWidget()->width(), height()); + toolBar->move(0, event->size().height() - toolBar->height()); + toolBar->setFixedWidth(width()); } - -/*bool GoToFlowWidget::eventFilter(QObject * target, QEvent * event) -{ - if(event->type() == QEvent::KeyPress) - { - QKeyEvent * e = static_cast(event); - if(e->key()==Qt::Key_S || e->key() == Qt::Key_Space) - { - this->keyPressEvent(e); - return true; - } - } - return QWidget::eventFilter(target,event); -}*/ diff --git a/YACReader/goto_flow_widget.h b/YACReader/goto_flow_widget.h index 1cb26d14..f8f93fc7 100644 --- a/YACReader/goto_flow_widget.h +++ b/YACReader/goto_flow_widget.h @@ -3,40 +3,48 @@ #include #include +#include "yacreader_global.h" #include "yacreader_global_gui.h" +#include "yacreader_page_flow_rhi.h" + using namespace YACReader; class QSettings; class GoToFlowToolBar; class QVBoxLayout; +class QKeyEvent; class GoToFlowWidget : public QWidget { Q_OBJECT -protected: - QVBoxLayout *mainLayout; - GoToFlowToolBar *toolBar; - public: - GoToFlowWidget(QWidget *paret = nullptr); - ~GoToFlowWidget() override = 0; + GoToFlowWidget(QWidget *parent = nullptr, FlowType flowType = CoverFlowLike); + ~GoToFlowWidget() override; + public slots: - virtual void reset() = 0; - virtual void centerSlide(int slide) = 0; - virtual void setPageNumber(int page); - virtual void setFlowType(YACReader::FlowType flowType) = 0; - virtual void setNumSlides(unsigned int slides) = 0; - virtual void setImageReady(int index, const QByteArray &image) = 0; - virtual void updateSize(); - virtual void updateConfig(QSettings *settings); - virtual void setFlowRightToLeft(bool b) = 0; + void reset(); + void centerSlide(int slide); + void setPageNumber(int page); + void setFlowType(FlowType flowType); + void setNumSlides(unsigned int slides); + void setImageReady(int index, const QByteArray &image); + void updateSize(); + void updateConfig(QSettings *settings); + void setFlowRightToLeft(bool b); + signals: void goToPage(unsigned int); protected: void keyPressEvent(QKeyEvent *event) override; - // bool eventFilter(QObject *, QEvent *); + void resizeEvent(QResizeEvent *event) override; + +private: + QVBoxLayout *mainLayout; + GoToFlowToolBar *toolBar; + YACReaderPageFlow3D *flow; + QSize imageSize; }; #endif diff --git a/YACReader/mouse_handler.cpp b/YACReader/mouse_handler.cpp index d4b7a6c1..331d33f2 100644 --- a/YACReader/mouse_handler.cpp +++ b/YACReader/mouse_handler.cpp @@ -3,17 +3,11 @@ #include #include "configuration.h" +#include "goto_flow_widget.h" #include "magnifying_glass.h" #include "render.h" #include "viewer.h" -#include "goto_flow.h" -#ifndef NO_OPENGL -#include "goto_flow_gl.h" -#else -#include -#endif - using namespace YACReader; YACReader::MouseHandler::MouseHandler(Viewer *viewer) diff --git a/YACReader/options_dialog.cpp b/YACReader/options_dialog.cpp index 611ce8d3..10d73439 100644 --- a/YACReader/options_dialog.cpp +++ b/YACReader/options_dialog.cpp @@ -14,10 +14,7 @@ #include #include "yacreader_spin_slider_widget.h" -#include "yacreader_flow_config_widget.h" -#ifndef NO_OPENGL -#include "yacreader_gl_flow_config_widget.h" -#endif +#include "yacreader_3d_flow_config_widget.h" OptionsDialog::OptionsDialog(QWidget *parent) : YACReaderOptionsDialog(parent) @@ -120,19 +117,13 @@ OptionsDialog::OptionsDialog(QWidget *parent) quickNavi = new QCheckBox(tr("Quick Navigation Mode")); disableShowOnMouseOver = new QCheckBox(tr("Disable mouse over activation")); - layoutFlow->addWidget(sw); -#ifndef NO_OPENGL layoutFlow->addWidget(gl); - layoutFlow->addWidget(useGL); -#endif + layoutFlow->addWidget(quickNavi); layoutFlow->addWidget(disableShowOnMouseOver); layoutFlow->addStretch(); - // disable vSyncCheck -#ifndef NO_OPENGL gl->vSyncCheck->hide(); -#endif // PAGE FLOW END ------------------------------------- @@ -249,13 +240,6 @@ void OptionsDialog::saveOptions() { settings->setValue(GO_TO_FLOW_SIZE, QSize(static_cast(slideSize->sliderPosition() / SLIDE_ASPECT_RATIO), slideSize->sliderPosition())); - if (sw->radio1->isChecked()) - settings->setValue(FLOW_TYPE_SW, 0); - if (sw->radio2->isChecked()) - settings->setValue(FLOW_TYPE_SW, 1); - if (sw->radio3->isChecked()) - settings->setValue(FLOW_TYPE_SW, 2); - settings->setValue(PATH, pathEdit->text()); Configuration::getConfiguration().setShowTimeInInformation(showTimeInInformationLabel->isChecked()); @@ -289,20 +273,6 @@ void OptionsDialog::restoreOptions(QSettings *settings) YACReaderOptionsDialog::restoreOptions(settings); slideSize->setSliderPosition(settings->value(GO_TO_FLOW_SIZE).toSize().height()); - switch (settings->value(FLOW_TYPE_SW).toInt()) { - case 0: - sw->radio1->setChecked(true); - break; - case 1: - sw->radio2->setChecked(true); - break; - case 2: - sw->radio3->setChecked(true); - break; - default: - sw->radio1->setChecked(true); - break; - } pathEdit->setText(settings->value(PATH).toString()); diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index c4e4bfb5..d689e90b 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -1,12 +1,7 @@ #include "viewer.h" #include "configuration.h" #include "magnifying_glass.h" -#include "goto_flow.h" -#ifndef NO_OPENGL -#include "goto_flow_gl.h" -#else -#include -#endif +#include "goto_flow_widget.h" #include "bookmarks_dialog.h" #include "render.h" #include "goto_dialog.h" @@ -16,8 +11,6 @@ #include "comic_db.h" #include "shortcuts_manager.h" -#include "opengl_checker.h" - #include #include @@ -81,34 +74,9 @@ Viewer::Viewer(QWidget *parent) goToDialog = new GoToDialog(this); - QSettings *settings = new QSettings(YACReader::getSettingsPath() + "/YACReader.ini", QSettings::IniFormat); - // CONFIG GOTO_FLOW-------------------------------------------------------- -#ifndef NO_OPENGL + goToFlow = new GoToFlowWidget(this, Configuration::getConfiguration().getFlowType()); -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) - // When using RHI, don't check OpenGL - assume hardware acceleration is available - bool openGLAvailable = true; - - if (!settings->contains(USE_OPEN_GL)) - settings->setValue(USE_OPEN_GL, 2); -#else - OpenGLChecker openGLChecker; - bool openGLAvailable = openGLChecker.hasCompatibleOpenGLVersion(); - - if (openGLAvailable && !settings->contains(USE_OPEN_GL)) - settings->setValue(USE_OPEN_GL, 2); - else if (!openGLAvailable) - settings->setValue(USE_OPEN_GL, 0); -#endif - - if ((settings->value(USE_OPEN_GL).toBool() == true)) - goToFlow = new GoToFlowGL(this, Configuration::getConfiguration().getFlowType()); - else - goToFlow = new GoToFlow(this, Configuration::getConfiguration().getFlowType()); -#else - goToFlow = new GoToFlow(this, Configuration::getConfiguration().getFlowType()); -#endif goToFlow->setFocusPolicy(Qt::StrongFocus); goToFlow->hide(); showGoToFlowAnimation = new QPropertyAnimation(goToFlow, "pos"); diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 1a79aadb..12726d28 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -18,21 +18,10 @@ DEFINES += SERVER_RELEASE YACREADER_LIBRARY include (../config.pri) include (../dependencies/pdf_backend.pri) -INCLUDEPATH += ../common/gl +INCLUDEPATH += ../common/rhi -greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { - INCLUDEPATH += ../common/rhi - DEFINES += YACREADER_USE_RHI -} win32 { - LIBS += -loleaut32 -lole32 -lshell32 -luser32 - # When using RHI (Qt 6.7+), don't link OpenGL directly - QRhiWidget handles graphics APIs - message("RHI mode: not linking opengl32 (using QRhiWidget)") - greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { - } else { - LIBS += -lopengl32 - } - + LIBS += -loleaut32 -lole32 -lshell32 -luser32 msvc { QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT /GL QMAKE_LFLAGS_RELEASE += /LTCG @@ -59,16 +48,16 @@ macx { CONFIG -= flat QT += sql network widgets svg quickcontrols2 -greaterThan(QT_MAJOR_VERSION, 5): QT += openglwidgets core5compat +greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { QT += gui-private } # Input -HEADERS += comic_flow.h \ +HEADERS += \ ../common/concurrent_queue.h \ - ../common/cover_utils.h \ + ../common/cover_utils.h \ create_library_dialog.h \ db/comic_query_result_processor.h \ db/folder_query_result_processor.h \ @@ -105,7 +94,6 @@ HEADERS += comic_flow.h \ ../common/library_item.h \ ../common/comic.h \ ../common/bookmarks.h \ - ../common/pictureflow.h \ ../common/release_acquire_atomic.h \ ../common/worker_thread.h \ ../common/custom_widgets.h \ @@ -142,7 +130,6 @@ HEADERS += comic_flow.h \ empty_special_list.h \ empty_reading_list_widget.h \ ../common/scroll_management.h \ - ../common/opengl_checker.h \ info_comics_view.h \ yacreader_comics_selection_helper.h \ yacreader_comic_info_helper.h \ @@ -151,18 +138,12 @@ HEADERS += comic_flow.h \ current_comic_view_helper.h \ ip_config_helper.h \ ../common/global_info_provider.h \ + ../common/rhi/flow_types.h \ + ../common/rhi/yacreader_flow_rhi.h \ + ../common/rhi/yacreader_comic_flow_rhi.h \ + ../common/rhi/yacreader_page_flow_rhi.h -!CONFIG(no_opengl) { - HEADERS += ../common/gl/yacreader_flow_gl.h - - greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { - HEADERS += ../common/rhi/yacreader_flow_rhi.h - HEADERS += ../common/rhi/yacreader_comic_flow_rhi.h \ - ../common/rhi/yacreader_page_flow_rhi.h - } -} - -SOURCES += comic_flow.cpp \ +SOURCES += \ ../common/concurrent_queue.cpp \ ../common/cover_utils.cpp \ create_library_dialog.cpp \ @@ -202,7 +183,6 @@ SOURCES += comic_flow.cpp \ ../common/library_item.cpp \ ../common/comic.cpp \ ../common/bookmarks.cpp \ - ../common/pictureflow.cpp \ ../common/custom_widgets.cpp \ ../common/qnaturalsorting.cpp \ no_libraries_widget.cpp \ @@ -236,7 +216,6 @@ SOURCES += comic_flow.cpp \ empty_special_list.cpp \ empty_reading_list_widget.cpp \ ../common/scroll_management.cpp \ - ../common/opengl_checker.cpp \ info_comics_view.cpp \ yacreader_comics_selection_helper.cpp \ yacreader_comic_info_helper.cpp\ @@ -245,20 +224,15 @@ SOURCES += comic_flow.cpp \ db/query_parser.cpp \ ip_config_helper.cpp \ ../common/global_info_provider.cpp \ + ../common/rhi/flow_types.cpp \ + ../common/rhi/yacreader_flow_rhi.cpp \ + ../common/rhi/yacreader_comic_flow_rhi.cpp \ + ../common/rhi/yacreader_page_flow_rhi.cpp -!CONFIG(no_opengl) { - SOURCES += ../common/gl/yacreader_flow_gl.cpp - - greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { - SOURCES += ../common/rhi/yacreader_flow_rhi.cpp - SOURCES += ../common/rhi/yacreader_comic_flow_rhi.cpp \ - ../common/rhi/yacreader_page_flow_rhi.cpp - RESOURCES += ../common/rhi/shaders/shaders.qrc - # Make raw GLSL shader sources editable in Qt Creator - OTHER_FILES += ../common/rhi/shaders/flow.vert \ - ../common/rhi/shaders/flow.frag - } -} + RESOURCES += ../common/rhi/shaders/shaders.qrc + # Make raw GLSL shader sources editable in Qt Creator + OTHER_FILES += ../common/rhi/shaders/flow.vert \ + ../common/rhi/shaders/flow.frag macx { HEADERS += trayhandler.h diff --git a/YACReaderLibrary/classic_comics_view.cpp b/YACReaderLibrary/classic_comics_view.cpp index 9368779d..e3280f1e 100644 --- a/YACReaderLibrary/classic_comics_view.cpp +++ b/YACReaderLibrary/classic_comics_view.cpp @@ -19,14 +19,7 @@ ClassicComicsView::ClassicComicsView(QWidget *parent) settings->beginGroup("libraryConfig"); // FLOW----------------------------------------------------------------------- //--------------------------------------------------------------------------- -#ifndef NO_OPENGL - if ((settings->value(USE_OPEN_GL).toBool() == true)) - comicFlow = new ComicFlowWidgetGL(0); - else - comicFlow = new ComicFlowWidgetSW(0); -#else - comicFlow = new ComicFlowWidgetSW(0); -#endif + comicFlow = new ComicFlowWidget(0); comicFlow->updateConfig(settings); comicFlow->setFocusPolicy(Qt::StrongFocus); comicFlow->setShowMarks(true); diff --git a/YACReaderLibrary/comic_flow.cpp b/YACReaderLibrary/comic_flow.cpp deleted file mode 100644 index a746ecd7..00000000 --- a/YACReaderLibrary/comic_flow.cpp +++ /dev/null @@ -1,159 +0,0 @@ -#include "comic_flow.h" -#include "worker_thread.h" - -#include "yacreader_global.h" - -ComicFlow::ComicFlow(QWidget *parent, FlowType flowType) - : YACReaderFlow(parent, flowType), worker(new WorkerThread) -{ - resetWorkerIndex(); - connect(&updateTimer, &QTimer::timeout, this, &ComicFlow::updateImageData); - - connect(this, &PictureFlow::centerIndexChanged, this, &ComicFlow::preload); - connect(this, &PictureFlow::centerIndexChangedSilent, this, &ComicFlow::preload); - - setReflectionEffect(PlainReflection); -} - -ComicFlow::~ComicFlow() = default; - -void ComicFlow::setImagePaths(const QStringList &paths) -{ - clear(); - - imageFiles = paths; - imagesLoaded.clear(); - imagesLoaded.fill(false, imageFiles.size()); - numImagesLoaded = 0; - - imagesSetted.clear(); - imagesSetted.fill(false, imageFiles.size()); - - // populate with empty images - QImage img; // TODO remove - QString s; - for (int i = 0; i < (int)imageFiles.size(); i++) { - addSlide(img); - s = imageFiles.at(i); - s.remove(s.size() - 4, 4); - if (QFileInfo::exists(s + ".r")) - markSlide(i); - } - - setCenterIndex(0); - - resetWorkerIndex(); - preload(); -} - -void ComicFlow::preload() -{ - if (numImagesLoaded < imagesLoaded.size()) - updateTimer.start(30); // TODO comprobar rendimiento, originalmente era 70 -} - -void ComicFlow::updateImageData() -{ - // can't do anything, wait for the next possibility - if (worker->busy()) - return; - - // set image of last one - const int idx = workerIndex; - if (idx >= 0) { - const QImage result = worker->extractResult(); - if (!result.isNull() && !imagesSetted[idx]) { - setSlide(idx, result); - imagesSetted[idx] = true; - numImagesLoaded++; - imagesLoaded[idx] = true; - } - } - - // try to load only few images on the left and right side - // i.e. all visible ones plus some extra -#define COUNT 8 - int indexes[2 * COUNT + 1]; - int center = centerIndex(); - indexes[0] = center; - for (int j = 0; j < COUNT; j++) { - indexes[j * 2 + 1] = center + j + 1; - indexes[j * 2 + 2] = center - j - 1; - } - for (int c = 0; c < 2 * COUNT + 1; c++) { - int i = indexes[c]; - if ((i >= 0) && (i < slideCount())) - if (!imagesLoaded[i]) // slide(i).isNull()) - { - // schedule thumbnail generation - QString fname = imageFiles[i]; - - workerIndex = i; - worker->performTask([fname] { return QImage { fname }; }); - return; - } - } - - // no need to generate anything? stop polling... - updateTimer.stop(); -} - -void ComicFlow::keyPressEvent(QKeyEvent *event) -{ - PictureFlow::keyPressEvent(event); -} - -void ComicFlow::wheelEvent(QWheelEvent *event) -{ - if (event->angleDelta().y() < 0) - showNext(); - else - showPrevious(); - event->accept(); -} - -void ComicFlow::insertSlide(const QString &path, int index) -{ - imageFiles.insert(index, path); - imagesLoaded.insert(index, false); - imagesSetted.insert(index, false); - - YACReaderFlow::insertSlide(index); - - resetWorkerIndex(); - preload(); -} - -void ComicFlow::removeSlide(int cover) -{ - imageFiles.removeAt(cover); - if (imagesLoaded[cover]) - numImagesLoaded--; - imagesLoaded.remove(cover); - imagesSetted.remove(cover); - - YACReaderFlow::removeSlide(cover); - - resetWorkerIndex(); - preload(); -} - -void ComicFlow::resortCovers(QList newOrder) -{ - YACReaderFlow::resortCovers(newOrder); - - QStringList imageFilesNew; - QVector imagesLoadedNew; - QVector imagesSettedNew; - foreach (int index, newOrder) { - imageFilesNew << imageFiles.at(index); - imagesLoadedNew << imagesLoaded.at(index); - imagesSettedNew << imagesSetted.at(index); - } - - imageFiles = imageFilesNew; - imagesLoaded = imagesLoadedNew; - imagesSetted = imagesSettedNew; - - resetWorkerIndex(); -} diff --git a/YACReaderLibrary/comic_flow.h b/YACReaderLibrary/comic_flow.h deleted file mode 100644 index f8cc9a4d..00000000 --- a/YACReaderLibrary/comic_flow.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef __COMICFLOW_H -#define __COMICFLOW_H - -#include "yacreader_flow.h" - -#include -#include -#include -#include -#include - -#include - -template -class WorkerThread; - -class ComicFlow : public YACReaderFlow -{ - Q_OBJECT -public: - ComicFlow(QWidget *parent = nullptr, FlowType flowType = CoverFlowLike); - ~ComicFlow() override; - - void setImagePaths(const QStringList &paths); - // bool eventFilter(QObject *target, QEvent *event); - void keyPressEvent(QKeyEvent *event) override; - void insertSlide(const QString &path, int index); - void removeSlide(int cover); - void resortCovers(QList newOrder); - -private slots: - void preload(); - void updateImageData(); - -private: - void resetWorkerIndex() { workerIndex = -1; } - - QStringList imageFiles; - QVector imagesLoaded; - QVector imagesSetted; - int numImagesLoaded; - int workerIndex; - QTimer updateTimer; - std::unique_ptr> worker; - virtual void wheelEvent(QWheelEvent *event) override; -}; - -#endif diff --git a/YACReaderLibrary/comic_flow_widget.cpp b/YACReaderLibrary/comic_flow_widget.cpp index f0bc487c..5df9bd08 100644 --- a/YACReaderLibrary/comic_flow_widget.cpp +++ b/YACReaderLibrary/comic_flow_widget.cpp @@ -1,281 +1,138 @@ #include "comic_flow_widget.h" #include + ComicFlowWidget::ComicFlowWidget(QWidget *parent) : QWidget(parent) { -} + flow = new YACReaderComicFlow3D(this); -ComicFlowWidgetSW::ComicFlowWidgetSW(QWidget *parent) - : ComicFlowWidget(parent) -{ - flow = new ComicFlow(parent); - - connect(flow, &PictureFlow::centerIndexChanged, this, &ComicFlowWidget::centerIndexChanged); - connect(flow, &YACReaderFlow::selected, this, &ComicFlowWidget::selected); - - auto l = new QVBoxLayout; - l->addWidget(flow); - setLayout(l); - - // TODO eleminar "padding" - QPalette Pal(palette()); - // set black background - Pal.setColor(QPalette::Window, Qt::black); - setAutoFillBackground(true); - setPalette(Pal); - - // config - QTransform m; - m.rotate(-90); - m.scale(-1, 1); - QImage image(":/images/setRead.png"); - QImage imageTransformed = image.transformed(m, Qt::SmoothTransformation); - setMarkImage(imageTransformed); -} - -QSize ComicFlowWidgetSW::minimumSizeHint() const -{ - return flow->minimumSizeHint(); -} -QSize ComicFlowWidgetSW::sizeHint() const -{ - return flow->sizeHint(); -} - -void ComicFlowWidgetSW::setShowMarks(bool value) -{ - flow->setShowMarks(value); -} -void ComicFlowWidgetSW::setMarks(QVector marks) -{ - flow->setMarks(marks); -} -void ComicFlowWidgetSW::setMarkImage(QImage &image) -{ - flow->setMarkImage(image); -} -void ComicFlowWidgetSW::markSlide(int index, YACReaderComicReadStatus status) -{ - flow->markSlide(index, status); -} -void ComicFlowWidgetSW::unmarkSlide(int index) -{ - flow->unmarkSlide(index); -} -void ComicFlowWidgetSW::setSlideSize(QSize size) -{ - flow->setSlideSize(size); -} -void ComicFlowWidgetSW::clear() -{ - flow->clear(); -} -void ComicFlowWidgetSW::setImagePaths(QStringList paths) -{ - flow->setImagePaths(paths); -} -void ComicFlowWidgetSW::setCenterIndex(int index) -{ - flow->setCenterIndex(index); -} -void ComicFlowWidgetSW::showSlide(int index) -{ - flow->showSlide(index); -} -int ComicFlowWidgetSW::centerIndex() -{ - return flow->centerIndex(); -} -void ComicFlowWidgetSW::updateMarks() -{ - flow->updateMarks(); -} -void ComicFlowWidgetSW::setFlowType(FlowType flowType) -{ - flow->setFlowType(flowType); -} -void ComicFlowWidgetSW::render() -{ - flow->render(); -} -void ComicFlowWidgetSW::keyPressEvent(QKeyEvent *event) -{ - flow->keyPressEvent(event); -} -void ComicFlowWidgetSW::paintEvent(QPaintEvent *event) -{ - ComicFlowWidget::paintEvent(event); -} -void ComicFlowWidgetSW::mousePressEvent(QMouseEvent *event) -{ - flow->mousePressEvent(event); -} -void ComicFlowWidgetSW::resizeEvent(QResizeEvent *event) -{ - flow->resizeEvent(event); -} -void ComicFlowWidgetSW::mouseDoubleClickEvent(QMouseEvent *event) -{ - flow->mouseDoubleClickEvent(event); -} -void ComicFlowWidgetSW::updateConfig(QSettings *settings) -{ - switch (settings->value(FLOW_TYPE_SW).toInt()) { - case CoverFlowLike: - flow->setFlowType(CoverFlowLike); - return; - case Strip: - flow->setFlowType(Strip); - return; - case StripOverlapped: - flow->setFlowType(StripOverlapped); - return; - } -} - -void ComicFlowWidgetSW::add(const QString &path, int index) -{ - flow->insertSlide(path, index); -} - -void ComicFlowWidgetSW::remove(int cover) -{ - flow->removeSlide(cover); -} - -void ComicFlowWidgetSW::resortCovers(QList newOrder) -{ - flow->resortCovers(newOrder); -} - -#ifndef NO_OPENGL -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -/// OpenGL ComicFlow -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -ComicFlowWidgetGL::ComicFlowWidgetGL(QWidget *parent) - : ComicFlowWidget(parent) -{ -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) - qDebug() << "ComicFlowWidgetGL: Creating YACReaderComicFlow3D (RHI implementation)"; -#else - qDebug() << "ComicFlowWidgetGL: Creating YACReaderComicFlowGL (OpenGL implementation)"; -#endif - flow = new YACReaderComicFlowImpl(this); - - connect(flow, &YACReaderComicFlowImpl::centerIndexChanged, this, &ComicFlowWidget::centerIndexChanged); - connect(flow, &YACReaderComicFlowImpl::selected, this, &ComicFlowWidget::selected); + connect(flow, &YACReaderComicFlow3D::centerIndexChanged, this, &ComicFlowWidget::centerIndexChanged); + connect(flow, &YACReaderComicFlow3D::selected, this, &ComicFlowWidget::selected); auto l = new QVBoxLayout; l->addWidget(flow); l->setContentsMargins(0, 0, 0, 0); setLayout(l); - // TODO eleminar "padding" QPalette Pal(palette()); - // set black background Pal.setColor(QPalette::Window, Qt::black); setAutoFillBackground(true); setPalette(Pal); } -QSize ComicFlowWidgetGL::minimumSizeHint() const +QSize ComicFlowWidget::minimumSizeHint() const { return flow->minimumSizeHint(); } -QSize ComicFlowWidgetGL::sizeHint() const + +QSize ComicFlowWidget::sizeHint() const { return flow->sizeHint(); } -void ComicFlowWidgetGL::setShowMarks(bool value) +void ComicFlowWidget::setShowMarks(bool value) { flow->setShowMarks(value); } -void ComicFlowWidgetGL::setMarks(QVector marks) + +void ComicFlowWidget::setMarks(QVector marks) { flow->setMarks(marks); } -void ComicFlowWidgetGL::setMarkImage(QImage &image) + +void ComicFlowWidget::setMarkImage(QImage &image) { flow->setMarkImage(image); } -void ComicFlowWidgetGL::markSlide(int index, YACReaderComicReadStatus status) + +void ComicFlowWidget::markSlide(int index, YACReader::YACReaderComicReadStatus status) { flow->markSlide(index, status); } -void ComicFlowWidgetGL::unmarkSlide(int index) + +void ComicFlowWidget::unmarkSlide(int index) { flow->unmarkSlide(index); } -void ComicFlowWidgetGL::setSlideSize(QSize size) + +void ComicFlowWidget::setSlideSize(QSize size) { flow->setSlideSize(size); } -void ComicFlowWidgetGL::clear() + +void ComicFlowWidget::clear() { flow->clear(); } -void ComicFlowWidgetGL::setImagePaths(QStringList paths) + +void ComicFlowWidget::setImagePaths(QStringList paths) { flow->setImagePaths(paths); } -void ComicFlowWidgetGL::setCenterIndex(int index) + +void ComicFlowWidget::setCenterIndex(int index) { flow->setCenterIndex(index); } -void ComicFlowWidgetGL::showSlide(int index) + +void ComicFlowWidget::showSlide(int index) { flow->showSlide(index); } -int ComicFlowWidgetGL::centerIndex() + +int ComicFlowWidget::centerIndex() { return flow->centerIndex(); } -void ComicFlowWidgetGL::updateMarks() + +void ComicFlowWidget::updateMarks() { flow->updateMarks(); } -void ComicFlowWidgetGL::setFlowType(FlowType flowType) + +void ComicFlowWidget::setFlowType(YACReader::FlowType flowType) { - if (flowType == CoverFlowLike) + if (flowType == YACReader::CoverFlowLike) flow->setPreset(presetYACReaderFlowClassicConfig); - else if (flowType == Strip) + else if (flowType == YACReader::Strip) flow->setPreset(presetYACReaderFlowStripeConfig); - else if (flowType == StripOverlapped) + else if (flowType == YACReader::StripOverlapped) flow->setPreset(presetYACReaderFlowOverlappedStripeConfig); else flow->setPreset(defaultYACReaderFlowConfig); } -void ComicFlowWidgetGL::render() + +void ComicFlowWidget::render() { flow->render(); } -void ComicFlowWidgetGL::keyPressEvent(QKeyEvent *event) + +void ComicFlowWidget::keyPressEvent(QKeyEvent *event) { flow->keyPressEvent(event); } -void ComicFlowWidgetGL::paintEvent(QPaintEvent *event) + +void ComicFlowWidget::paintEvent(QPaintEvent *event) { - // flow->paintEvent(event); - ComicFlowWidget::paintEvent(event); + QWidget::paintEvent(event); } -void ComicFlowWidgetGL::mousePressEvent(QMouseEvent *event) + +void ComicFlowWidget::mousePressEvent(QMouseEvent *event) { flow->mousePressEvent(event); } -void ComicFlowWidgetGL::resizeEvent(QResizeEvent *event) + +void ComicFlowWidget::resizeEvent(QResizeEvent *event) { flow->resizeGL(event->size().width(), event->size().height()); } -void ComicFlowWidgetGL::mouseDoubleClickEvent(QMouseEvent *event) + +void ComicFlowWidget::mouseDoubleClickEvent(QMouseEvent *event) { flow->mouseDoubleClickEvent(event); } -void ComicFlowWidgetGL::updateConfig(QSettings *settings) +void ComicFlowWidget::updateConfig(QSettings *settings) { Performance performance = medium; @@ -319,7 +176,6 @@ void ComicFlowWidgetGL::updateConfig(QSettings *settings) } // custom config - flow->setCF_RX(settings->value(X_ROTATION).toInt()); flow->setCF_Y(settings->value(Y_POSITION).toInt()); flow->setX_Distance(settings->value(COVER_DISTANCE).toInt()); @@ -331,35 +187,19 @@ void ComicFlowWidgetGL::updateConfig(QSettings *settings) flow->setFadeOutDist(settings->value(FADE_OUT_DIST).toInt()); flow->setLightStrenght(settings->value(LIGHT_STRENGTH).toInt()); flow->setMaxAngle(settings->value(MAX_ANGLE).toInt()); - - /* flow->setVisibility(settings->value("visibilityDistance").toInt()); - flow->setLightStrenght(settings->value("lightStrength").toInt())*/ - ; } -void ComicFlowWidgetGL::add(const QString &path, int index) +void ComicFlowWidget::add(const QString &path, int index) { flow->add(path, index); } -void ComicFlowWidgetGL::remove(int cover) +void ComicFlowWidget::remove(int cover) { flow->remove(cover); } -void ComicFlowWidgetGL::resortCovers(QList newOrder) +void ComicFlowWidget::resortCovers(QList newOrder) { flow->resortCovers(newOrder); } -#endif -// void ComicFlowWidgetGL::setCF_RX(int value){ flow->setCF_RX(value);} -// void ComicFlowWidgetGL::setCF_RY(int value){ flow->setCF_RY(value);} -// void ComicFlowWidgetGL::setCF_RZ(int value){ flow->setCF_RZ(value);} -// void ComicFlowWidgetGL::setZoom(int zoom){ flow->setZoom(zoom);} -// void ComicFlowWidgetGL::setRotation(int angle){ flow->setRotation(angle);} -// void ComicFlowWidgetGL::setX_Distance(int distance){ flow->setX_Distance(distance);} -// void ComicFlowWidgetGL::setCenter_Distance(int distance){ flow->setCenter_Distance(distance);} -// void ComicFlowWidgetGL::setZ_Distance(int distance){ flow->setZ_Distance(distance);} -// void ComicFlowWidgetGL::setCF_Y(int value){ flow->setCF_Y(value);} -// void ComicFlowWidgetGL::setY_Distance(int value){ flow->setY_Distance(value);} -// void ComicFlowWidgetGL::setPreset(const Preset & p){ flow->setPreset(p);} diff --git a/YACReaderLibrary/comic_flow_widget.h b/YACReaderLibrary/comic_flow_widget.h index 51217cc4..b99c90a8 100644 --- a/YACReaderLibrary/comic_flow_widget.h +++ b/YACReaderLibrary/comic_flow_widget.h @@ -3,75 +3,40 @@ #include -#include "pictureflow.h" -#include "comic_flow.h" -#ifndef NO_OPENGL -// Conditional include based on Qt version and RHI availability -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) +#include "yacreader_global.h" + #include "yacreader_comic_flow_rhi.h" -using YACReaderComicFlowImpl = YACReaderComicFlow3D; -#else -#include "yacreader_flow_gl.h" -using YACReaderComicFlowImpl = YACReaderComicFlowGL; -#endif -#endif +#include "yacreader_global_gui.h" + class ComicFlowWidget : public QWidget { Q_OBJECT public: - ComicFlowWidget(QWidget *paret = nullptr); + ComicFlowWidget(QWidget *parent = nullptr); public slots: - virtual void setShowMarks(bool value) = 0; - virtual void setMarks(QVector marks) = 0; - virtual void setMarkImage(QImage &image) = 0; - virtual void markSlide(int index, YACReaderComicReadStatus status) = 0; - virtual void unmarkSlide(int index) = 0; - virtual void setSlideSize(QSize size) = 0; - virtual void clear() = 0; - virtual void setImagePaths(QStringList paths) = 0; - virtual void setCenterIndex(int index) = 0; - virtual void showSlide(int index) = 0; - virtual int centerIndex() = 0; - virtual void updateMarks() = 0; - virtual void setFlowType(FlowType flowType) = 0; - virtual void render() = 0; - virtual void updateConfig(QSettings *settings) = 0; - virtual void add(const QString &path, int index) = 0; - virtual void remove(int cover) = 0; - virtual void resortCovers(QList newOrder) = 0; + void setShowMarks(bool value); + void setMarks(QVector marks); + void setMarkImage(QImage &image); + void markSlide(int index, YACReader::YACReaderComicReadStatus status); + void unmarkSlide(int index); + void setSlideSize(QSize size); + void clear(); + void setImagePaths(QStringList paths); + void setCenterIndex(int index); + void showSlide(int index); + int centerIndex(); + void updateMarks(); + void setFlowType(YACReader::FlowType flowType); + void render(); + void updateConfig(QSettings *settings); + void add(const QString &path, int index); + void remove(int cover); + void resortCovers(QList newOrder); + signals: void centerIndexChanged(int); void selected(unsigned int); -}; - -class ComicFlowWidgetSW : public ComicFlowWidget -{ - Q_OBJECT -private: - ComicFlow *flow; - -public: - ComicFlowWidgetSW(QWidget *parent = nullptr); - - void setShowMarks(bool value) override; - void setMarks(QVector marks) override; - void setMarkImage(QImage &image) override; - void markSlide(int index, YACReaderComicReadStatus status) override; - void unmarkSlide(int index) override; - void setSlideSize(QSize size) override; - void clear() override; - void setImagePaths(QStringList paths) override; - void setCenterIndex(int index) override; - void showSlide(int index) override; - int centerIndex() override; - void updateMarks() override; - void setFlowType(FlowType flowType) override; - void render() override; - void updateConfig(QSettings *settings) override; - void add(const QString &path, int index) override; - void remove(int cover) override; - void resortCovers(QList newOrder) override; protected: void keyPressEvent(QKeyEvent *event) override; @@ -81,64 +46,9 @@ protected: void mouseDoubleClickEvent(QMouseEvent *event) override; QSize minimumSizeHint() const override; QSize sizeHint() const override; - QSize slideSizeW; - QSize slideSizeF; -}; -#ifndef NO_OPENGL -class ComicFlowWidgetGL : public ComicFlowWidget -{ - Q_OBJECT private: - YACReaderComicFlowImpl *flow; - -public: - ComicFlowWidgetGL(QWidget *parent = nullptr); - - void setShowMarks(bool value) override; - void setMarks(QVector marks) override; - void setMarkImage(QImage &image) override; - void markSlide(int index, YACReaderComicReadStatus status) override; - void unmarkSlide(int index) override; - void setSlideSize(QSize size) override; - void clear() override; - void setImagePaths(QStringList paths) override; - void setCenterIndex(int index) override; - void showSlide(int index) override; - int centerIndex() override; - void updateMarks() override; - void setFlowType(FlowType flowType) override; - void render() override; - void updateConfig(QSettings *settings) override; - void add(const QString &path, int index) override; - void remove(int cover) override; - void resortCovers(QList newOrder) override; - // public slots: - // void setCF_RX(int value); - // //the Y Rotation of the Coverflow - // void setCF_RY(int value); - // //the Z Rotation of the Coverflow - // void setCF_RZ(int value); - // //perspective - // void setZoom(int zoom); - // void setRotation(int angle); - // //sets the distance between the covers - // void setX_Distance(int distance); - // //sets the distance between the centered and the non centered covers - // void setCenter_Distance(int distance); - // //sets the pushback amount - // void setZ_Distance(int distance); - // void setCF_Y(int value); - // void setY_Distance(int value); - // void setPreset(const Preset & p); -protected: - void keyPressEvent(QKeyEvent *event) override; - void paintEvent(QPaintEvent *event) override; - void mousePressEvent(QMouseEvent *event) override; - void resizeEvent(QResizeEvent *event) override; - void mouseDoubleClickEvent(QMouseEvent *event) override; - QSize minimumSizeHint() const override; - QSize sizeHint() const override; + YACReaderComicFlow3D *flow; }; -#endif + #endif diff --git a/YACReaderLibrary/comics_view.cpp b/YACReaderLibrary/comics_view.cpp index 88ac2e6e..f3e705f1 100644 --- a/YACReaderLibrary/comics_view.cpp +++ b/YACReaderLibrary/comics_view.cpp @@ -17,11 +17,6 @@ ComicsView::ComicsView(QWidget *parent) view = new QQuickWidget(); - // In Qt 6, QQuickWidget supports Qt RHI and can use any graphics backend - // (Vulkan, Metal, Direct3D, OpenGL, or software rendering). - // The backend can be configured via QQuickWindow::setGraphicsApi() or QSG_RHI_BACKEND env var. - // Note: All widgets in the same top-level window must use the same graphics API. - view->setResizeMode(QQuickWidget::SizeRootObjectToView); connect( view, &QQuickWidget::statusChanged, this, diff --git a/YACReaderLibrary/folder_content_view.cpp b/YACReaderLibrary/folder_content_view.cpp index 8d31844e..d3cc901d 100644 --- a/YACReaderLibrary/folder_content_view.cpp +++ b/YACReaderLibrary/folder_content_view.cpp @@ -26,11 +26,6 @@ FolderContentView::FolderContentView(QAction *toogleRecentVisibilityAction, QWid view = new QQuickWidget(); - // In Qt 6, QQuickWidget supports Qt RHI and can use any graphics backend - // (Vulkan, Metal, Direct3D, OpenGL, or software rendering). - // The backend can be configured via QQuickWindow::setGraphicsApi() or QSG_RHI_BACKEND env var. - // Note: All widgets in the same top-level window must use the same graphics API. - view->setResizeMode(QQuickWidget::SizeRootObjectToView); connect( view, &QQuickWidget::statusChanged, this, diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 158a2010..2ae2f521 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -71,7 +71,6 @@ #include "db_helper.h" #include "reading_list_item.h" -#include "opengl_checker.h" #include "yacreader_content_views_manager.h" #include "folder_content_view.h" @@ -198,33 +197,8 @@ void LibraryWindow::createSettings() settings->beginGroup("libraryConfig"); } -void LibraryWindow::setupOpenglSetting() -{ -#ifndef NO_OPENGL - // FLOW----------------------------------------------------------------------- - //--------------------------------------------------------------------------- - -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) - // When using RHI, assume hardware acceleration is available - bool openGLAvailable = true; - if (!settings->contains(USE_OPEN_GL)) - settings->setValue(USE_OPEN_GL, 2); -#else - OpenGLChecker openGLChecker; - bool openGLAvailable = openGLChecker.hasCompatibleOpenGLVersion(); - - if (openGLAvailable && !settings->contains(USE_OPEN_GL)) - settings->setValue(USE_OPEN_GL, 2); - else if (!openGLAvailable) - settings->setValue(USE_OPEN_GL, 0); -#endif -#endif -} - void LibraryWindow::setupUI() { - setupOpenglSetting(); - setUnifiedTitleAndToolBarOnMac(true); libraryCreator = new LibraryCreator(settings); diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index b78a149c..4f153a54 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -189,7 +189,6 @@ public: NavigationStatus status; void createSettings(); - void setupOpenglSetting(); void setupUI(); void createToolBars(); void createMenus(); diff --git a/YACReaderLibrary/main.cpp b/YACReaderLibrary/main.cpp index e60e9ae6..1697e0ae 100644 --- a/YACReaderLibrary/main.cpp +++ b/YACReaderLibrary/main.cpp @@ -21,7 +21,6 @@ #include "db_helper.h" #include "yacreader_libraries.h" #include "exit_check.h" -#include "opengl_checker.h" #ifdef Q_OS_MACOS #include "trayhandler.h" #endif @@ -77,19 +76,6 @@ void logSystemAndConfig() else QLOG_INFO() << "server : disabled"; - if (settings.value(USE_OPEN_GL).toBool()) - QLOG_INFO() << "OpenGL : enabled" - << " - " << (settings.value(V_SYNC).toBool() ? "VSync on" : "VSync off"); - else - QLOG_INFO() << "OpenGL : disabled"; - -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) - QLOG_INFO() << "Using RHI (Qt Rendering Hardware Interface) - graphics backend will be auto-selected"; -#else - OpenGLChecker checker; - QLOG_INFO() << "OpenGL version : " << checker.textVersionDescription(); -#endif - auto libraries = DBHelper::getLibraries().getLibraries(); QLOG_INFO() << "Libraries: "; for (auto library : libraries) { @@ -199,32 +185,8 @@ int main(int argc, char **argv) parser.addHelpOption(); parser.addVersionOption(); parser.addOption({ "loglevel", "Set log level. Valid values: trace, info, debug, warn, error.", "loglevel", "warning" }); -#ifdef Q_OS_WIN - parser.addOption({ "opengl", "Set opengl renderer. Valid values: desktop, es, software.", "gl_renderer" }); -#endif parser.process(app); -// When using RHI (Qt 6.7+), don't allow OpenGL attribute overrides -#if !defined(YACREADER_USE_RHI) || QT_VERSION < QT_VERSION_CHECK(6, 7, 0) -#ifdef Q_OS_WIN - if (parser.isSet("opengl")) { - QTextStream qout(stdout); - if (parser.value("opengl") == "desktop") { - app.setAttribute(Qt::AA_UseDesktopOpenGL); - } else if (parser.value("opengl") == "es") { - app.setAttribute(Qt::AA_UseOpenGLES); - } else if (parser.value("opengl") == "software") { - qout << "Warning! This will be slow as hell. Only use this setting for" - "testing or as a last resort."; - app.setAttribute(Qt::AA_UseSoftwareOpenGL); - } else { - qout << "Invalid value:" << parser.value("gl_renderer"); - parser.showHelp(); - } - } -#endif -#endif - if (parser.isSet("loglevel")) { if (parser.value("loglevel") == "trace") { logger.setLoggingLevel(QsLogging::TraceLevel); diff --git a/YACReaderLibrary/options_dialog.cpp b/YACReaderLibrary/options_dialog.cpp index dd702675..53210ac8 100644 --- a/YACReaderLibrary/options_dialog.cpp +++ b/YACReaderLibrary/options_dialog.cpp @@ -1,17 +1,11 @@ #include "options_dialog.h" -#ifndef NO_OPENGL -#include "yacreader_flow_gl.h" -#include "yacreader_gl_flow_config_widget.h" -#endif -#include "yacreader_flow_config_widget.h" +#include "yacreader_3d_flow_config_widget.h" #include "api_key_dialog.h" #include "yacreader_global_gui.h" -#ifndef NO_OPENGL FlowType flowType = Strip; -#endif OptionsDialog::OptionsDialog(QWidget *parent) : YACReaderOptionsDialog(parent) @@ -25,9 +19,7 @@ OptionsDialog::OptionsDialog(QWidget *parent) tabWidget->addTab(generalW, tr("General")); tabWidget->addTab(librariesW, tr("Libraries")); tabWidget->addTab(comicFlowW, tr("Comic Flow")); -#ifndef NO_OPENGL tabWidget->addTab(gridViewW, tr("Grid view")); -#endif auto buttons = new QHBoxLayout(); buttons->addStretch(); @@ -333,21 +325,11 @@ QWidget *OptionsDialog::createFlowTab() { auto switchFlowType = new QHBoxLayout(); switchFlowType->addStretch(); -#ifndef NO_OPENGL - switchFlowType->addWidget(useGL); -#endif auto flowLayout = new QVBoxLayout; - flowLayout->addWidget(sw); -#ifndef NO_OPENGL flowLayout->addWidget(gl); -#endif flowLayout->addLayout(switchFlowType); -#ifndef NO_OPENGL - sw->hide(); -#endif - auto comicFlowW = new QWidget; comicFlowW->setLayout(flowLayout); diff --git a/YACReaderLibrary/yacreader_content_views_manager.cpp b/YACReaderLibrary/yacreader_content_views_manager.cpp index 294a072c..e2597cb1 100644 --- a/YACReaderLibrary/yacreader_content_views_manager.cpp +++ b/YACReaderLibrary/yacreader_content_views_manager.cpp @@ -126,6 +126,7 @@ void YACReaderContentViewsManager::showComicsView() { comicsViewStack->setCurrentWidget(comicsView); + // TODO: check if this is still needed in the rhi implementation // BUG, ugly workaround for glitch when QOpenGLWidget (flow) is used just after any other widget in the views stack // Somehow QOpenGLWidget is messing with the rendering of the side bar (wrong buffer swapping) libraryWindow->sideBar->update(); diff --git a/common/gl/yacreader_flow_gl.cpp b/common/gl/yacreader_flow_gl.cpp deleted file mode 100644 index aba6dffb..00000000 --- a/common/gl/yacreader_flow_gl.cpp +++ /dev/null @@ -1,1999 +0,0 @@ -#include "yacreader_flow_gl.h" - -#include -#include -#include - -// Structure for per-instance data -struct InstanceData { - QMatrix4x4 modelMatrix; - float leftUpShading; - float leftDownShading; - float rightUpShading; - float rightDownShading; - float opacity; - float padding[3]; // Align to 16 bytes -}; - -/*** Preset Configurations ***/ - -int YACReaderFlowGL::updateInterval = 16; - -struct Preset defaultYACReaderFlowConfig = { - 0.08f, // Animation_step sets the speed of the animation - 1.5f, // Animation_speedup sets the acceleration of the animation - 0.1f, // Animation_step_max sets the maximum speed of the animation - 3.f, // Animation_Fade_out_dis sets the distance of view - - 1.5f, // pre_rotation sets the rotation increasion - 3.f, // View_rotate_light_strenght sets the light strenght on rotation - 0.01f, // View_rotate_add sets the speed of the rotation - 0.02f, // View_rotate_sub sets the speed of reversing the rotation - 20.f, // View_angle sets the maximum view angle - - 0.f, // CF_X the X Position of the Coverflow - 0.f, // CF_Y the Y Position of the Coverflow - -8.f, // CF_Z the Z Position of the Coverflow - - 15.f, // CF_RX the X Rotation of the Coverflow - 0.f, // CF_RY the Y Rotation of the Coverflow - 0.f, // CF_RZ the Z Rotation of the Coverflow - - -50.f, // Rotation sets the rotation of each cover - 0.18f, // X_Distance sets the distance between the covers - 1.f, // Center_Distance sets the distance between the centered and the non centered covers - 0.1f, // Z_Distance sets the pushback amount - 0.0f, // Y_Distance sets the elevation amount - - 30.f // zoom level - -}; - -struct Preset presetYACReaderFlowClassicConfig = { - 0.08f, // Animation_step sets the speed of the animation - 1.5f, // Animation_speedup sets the acceleration of the animation - 0.1f, // Animation_step_max sets the maximum speed of the animation - 2.f, // Animation_Fade_out_dis sets the distance of view - - 1.5f, // pre_rotation sets the rotation increasion - 3.f, // View_rotate_light_strenght sets the light strenght on rotation - 0.08f, // View_rotate_add sets the speed of the rotation - 0.08f, // View_rotate_sub sets the speed of reversing the rotation - 30.f, // View_angle sets the maximum view angle - - 0.f, // CF_X the X Position of the Coverflow - -0.2f, // CF_Y the Y Position of the Coverflow - -7.f, // CF_Z the Z Position of the Coverflow - - 0.f, // CF_RX the X Rotation of the Coverflow - 0.f, // CF_RY the Y Rotation of the Coverflow - 0.f, // CF_RZ the Z Rotation of the Coverflow - - -40.f, // Rotation sets the rotation of each cover - 0.18f, // X_Distance sets the distance between the covers - 1.f, // Center_Distance sets the distance between the centered and the non centered covers - 0.1f, // Z_Distance sets the pushback amount - 0.0f, // Y_Distance sets the elevation amount - - 22.f // zoom level - -}; - -struct Preset presetYACReaderFlowStripeConfig = { - 0.08f, // Animation_step sets the speed of the animation - 1.5f, // Animation_speedup sets the acceleration of the animation - 0.1f, // Animation_step_max sets the maximum speed of the animation - 6.f, // Animation_Fade_out_dis sets the distance of view - - 1.5f, // pre_rotation sets the rotation increasion - 4.f, // View_rotate_light_strenght sets the light strenght on rotation - 0.08f, // View_rotate_add sets the speed of the rotation - 0.08f, // View_rotate_sub sets the speed of reversing the rotation - 30.f, // View_angle sets the maximum view angle - - 0.f, // CF_X the X Position of the Coverflow - -0.2f, // CF_Y the Y Position of the Coverflow - -7.f, // CF_Z the Z Position of the Coverflow - - 0.f, // CF_RX the X Rotation of the Coverflow - 0.f, // CF_RY the Y Rotation of the Coverflow - 0.f, // CF_RZ the Z Rotation of the Coverflow - - 0.f, // Rotation sets the rotation of each cover - 1.1f, // X_Distance sets the distance between the covers - 0.2f, // Center_Distance sets the distance between the centered and the non centered covers - 0.01f, // Z_Distance sets the pushback amount - 0.0f, // Y_Distance sets the elevation amount - - 22.f // zoom level - -}; - -struct Preset presetYACReaderFlowOverlappedStripeConfig = { - 0.08f, // Animation_step sets the speed of the animation - 1.5f, // Animation_speedup sets the acceleration of the animation - 0.1f, // Animation_step_max sets the maximum speed of the animation - 2.f, // Animation_Fade_out_dis sets the distance of view - - 1.5f, // pre_rotation sets the rotation increasion - 3.f, // View_rotate_light_strenght sets the light strenght on rotation - 0.08f, // View_rotate_add sets the speed of the rotation - 0.08f, // View_rotate_sub sets the speed of reversing the rotation - 30.f, // View_angle sets the maximum view angle - - 0.f, // CF_X the X Position of the Coverflow - -0.2f, // CF_Y the Y Position of the Coverflow - -7.f, // CF_Z the Z Position of the Coverflow - - 0.f, // CF_RX the X Rotation of the Coverflow - 0.f, // CF_RY the Y Rotation of the Coverflow - 0.f, // CF_RZ the Z Rotation of the Coverflow - - 0.f, // Rotation sets the rotation of each cover - 0.18f, // X_Distance sets the distance between the covers - 1.f, // Center_Distance sets the distance between the centered and the non centered covers - 0.1f, // Z_Distance sets the pushback amount - 0.0f, // Y_Distance sets the elevation amount - - 22.f // zoom level - -}; - -struct Preset pressetYACReaderFlowUpConfig = { - 0.08f, // Animation_step sets the speed of the animation - 1.5f, // Animation_speedup sets the acceleration of the animation - 0.1f, // Animation_step_max sets the maximum speed of the animation - 2.5f, // Animation_Fade_out_dis sets the distance of view - - 1.5f, // pre_rotation sets the rotation increasion - 3.f, // View_rotate_light_strenght sets the light strenght on rotation - 0.08f, // View_rotate_add sets the speed of the rotation - 0.08f, // View_rotate_sub sets the speed of reversing the rotation - 5.f, // View_angle sets the maximum view angle - - 0.f, // CF_X the X Position of the Coverflow - -0.2f, // CF_Y the Y Position of the Coverflow - -7.f, // CF_Z the Z Position of the Coverflow - - 0.f, // CF_RX the X Rotation of the Coverflow - 0.f, // CF_RY the Y Rotation of the Coverflow - 0.f, // CF_RZ the Z Rotation of the Coverflow - - -50.f, // Rotation sets the rotation of each cover - 0.18f, // X_Distance sets the distance between the covers - 1.f, // Center_Distance sets the distance between the centered and the non centered covers - 0.1f, // Z_Distance sets the pushback amount - -0.1f, // Y_Distance sets the elevation amount - - 22.f // zoom level - -}; - -struct Preset pressetYACReaderFlowDownConfig = { - 0.08f, // Animation_step sets the speed of the animation - 1.5f, // Animation_speedup sets the acceleration of the animation - 0.1f, // Animation_step_max sets the maximum speed of the animation - 2.5f, // Animation_Fade_out_dis sets the distance of view - - 1.5f, // pre_rotation sets the rotation increasion - 3.f, // View_rotate_light_strenght sets the light strenght on rotation - 0.08f, // View_rotate_add sets the speed of the rotation - 0.08f, // View_rotate_sub sets the speed of reversing the rotation - 5.f, // View_angle sets the maximum view angle - - 0.f, // CF_X the X Position of the Coverflow - -0.2f, // CF_Y the Y Position of the Coverflow - -7.f, // CF_Z the Z Position of the Coverflow - - 0.f, // CF_RX the X Rotation of the Coverflow - 0.f, // CF_RY the Y Rotation of the Coverflow - 0.f, // CF_RZ the Z Rotation of the Coverflow - - -50.f, // Rotation sets the rotation of each cover - 0.18f, // X_Distance sets the distance between the covers - 1.f, // Center_Distance sets the distance between the centered and the non centered covers - 0.1f, // Z_Distance sets the pushback amount - 0.1f, // Y_Distance sets the elevation amount - - 22.f // zoom level -}; -/*Constructor*/ -YACReaderFlowGL::YACReaderFlowGL(QWidget *parent, struct Preset p) - : QOpenGLWidget(parent), numObjects(0), lazyPopulateObjects(-1), hasBeenInitialized(false), bUseVSync(false), flowRightToLeft(false) -{ - updateCount = 0; - config = p; - currentSelected = 0; - - centerPos.x = 0.f; - centerPos.y = 0.f; - centerPos.z = 1.f; - centerPos.rot = 0.f; - - shadingTop = 0.8f; - shadingBottom = 0.02f; - reflectionUp = 0.f; - reflectionBottom = 0.6f; - - setBackgroundColor(Qt::black); - - numObjects = 0; - viewRotate = 0.f; - viewRotateActive = 0; - stepBackup = config.animationStep / config.animationSpeedUp; - - QSurfaceFormat f = format(); - f.setSamples(4); - f.setSwapInterval(0); - - // Detect if we should use OpenGL ES - // Check if app-level ES is forced (via Qt::AA_UseOpenGLES) - bool forceES = QCoreApplication::testAttribute(Qt::AA_UseOpenGLES); - - if (forceES) { - // Use OpenGL ES 3.0 - f.setRenderableType(QSurfaceFormat::OpenGLES); - f.setVersion(3, 0); - qDebug() << "YACReaderFlowGL: Requesting OpenGL ES 3.0 context"; - } else { - // Use Desktop OpenGL 3.3 Core - f.setRenderableType(QSurfaceFormat::OpenGL); - f.setVersion(3, 3); - f.setProfile(QSurfaceFormat::CoreProfile); - qDebug() << "YACReaderFlowGL: Requesting Desktop OpenGL 3.3 Core context"; - } - - setFormat(f); - - timerId = startTimer(updateInterval); -} - -void YACReaderFlowGL::timerEvent(QTimerEvent *event) -{ - if (timerId == event->timerId()) - update(); -} - -void YACReaderFlowGL::startAnimationTimer() -{ - if (timerId == -1) - timerId = startTimer(updateInterval); -} - -void YACReaderFlowGL::stopAnimationTimer() -{ - if (timerId != -1) { - killTimer(timerId); - timerId = -1; - } -} - -YACReaderFlowGL::~YACReaderFlowGL() -{ - makeCurrent(); - - delete vao; - delete vbo; - delete instanceVBO; - delete shaderProgram; - - if (defaultTexture) { - if (defaultTexture->isCreated()) - defaultTexture->destroy(); - delete defaultTexture; - } - -#ifdef YACREADER_LIBRARY - if (markTexture) { - if (markTexture->isCreated()) - markTexture->destroy(); - delete markTexture; - } - - if (readingTexture) { - if (readingTexture->isCreated()) - readingTexture->destroy(); - delete readingTexture; - } -#endif - - doneCurrent(); -} - -QSize YACReaderFlowGL::minimumSizeHint() const -{ - return QSize(320, 200); -} - -void YACReaderFlowGL::setupShaders() -{ - bool isES = QOpenGLContext::currentContext()->isOpenGLES(); - - // Vertex Shader - Desktop GL 3.3 - const char *vertexShaderSourceGL = R"( - #version 330 core - layout(location = 0) in vec3 position; - layout(location = 1) in vec2 texCoord; - layout(location = 2) in mat4 instanceModel; - layout(location = 6) in vec4 instanceShading1; - layout(location = 7) in float instanceOpacity; - - out vec2 vTexCoord; - out vec4 vColor; - - uniform mat4 viewProjectionMatrix; - - void main() - { - gl_Position = viewProjectionMatrix * instanceModel * vec4(position, 1.0); - vTexCoord = texCoord; - - float leftUpShading = instanceShading1.x; - float leftDownShading = instanceShading1.y; - float rightUpShading = instanceShading1.z; - float rightDownShading = instanceShading1.w; - - float leftShading = mix(leftDownShading, leftUpShading, (position.y + 0.5)); - float rightShading = mix(rightDownShading, rightUpShading, (position.y + 0.5)); - float shading = mix(leftShading, rightShading, (position.x + 0.5)); - - vColor = vec4(shading * instanceOpacity); - } - )"; - - // Vertex Shader - OpenGL ES 3.0 - const char *vertexShaderSourceES = R"( - #version 300 es - precision highp float; - - layout(location = 0) in vec3 position; - layout(location = 1) in vec2 texCoord; - layout(location = 2) in mat4 instanceModel; - layout(location = 6) in vec4 instanceShading1; - layout(location = 7) in float instanceOpacity; - - out vec2 vTexCoord; - out vec4 vColor; - - uniform mat4 viewProjectionMatrix; - - void main() - { - gl_Position = viewProjectionMatrix * instanceModel * vec4(position, 1.0); - vTexCoord = texCoord; - - float leftUpShading = instanceShading1.x; - float leftDownShading = instanceShading1.y; - float rightUpShading = instanceShading1.z; - float rightDownShading = instanceShading1.w; - - float leftShading = mix(leftDownShading, leftUpShading, (position.y + 0.5)); - float rightShading = mix(rightDownShading, rightUpShading, (position.y + 0.5)); - float shading = mix(leftShading, rightShading, (position.x + 0.5)); - - vColor = vec4(shading * instanceOpacity); - } - )"; - - // Fragment Shader - Desktop GL 3.3 - const char *fragmentShaderSourceGL = R"( - #version 330 core - in vec2 vTexCoord; - in vec4 vColor; - - out vec4 fragColor; - - uniform sampler2D texture; - uniform bool isReflection; - uniform float reflectionUp; - uniform float reflectionDown; - uniform vec3 backgroundColor; - uniform vec3 shadingColor; - - void main() - { - vec2 texCoord = vTexCoord; - - if (isReflection) { - texCoord.y = 1.0 - vTexCoord.y; - vec4 texColor = texture2D(texture, texCoord); - float gradientFade = mix(1.0/3.0, reflectionUp / 2.0, vTexCoord.y); - float shadingAmount = vColor.r * gradientFade; - vec3 shadedColor = mix(backgroundColor, texColor.rgb, shadingAmount); - fragColor = vec4(shadedColor, texColor.a); - } else { - vec4 texColor = texture2D(texture, texCoord); - float shadingAmount = vColor.r; - vec3 shadedColor = mix(backgroundColor, texColor.rgb, shadingAmount); - fragColor = vec4(shadedColor, texColor.a); - } - } - )"; - - // Fragment Shader - OpenGL ES 3.0 - const char *fragmentShaderSourceES = R"( - #version 300 es - precision highp float; - - in vec2 vTexCoord; - in vec4 vColor; - - out vec4 fragColor; - - uniform sampler2D texture; - uniform bool isReflection; - uniform float reflectionUp; - uniform float reflectionDown; - uniform vec3 backgroundColor; - uniform vec3 shadingColor; - - void main() - { - vec2 texCoord = vTexCoord; - - if (isReflection) { - texCoord.y = 1.0 - vTexCoord.y; - vec4 texColor = texture(texture, texCoord); - float gradientFade = mix(1.0/3.0, reflectionUp / 2.0, vTexCoord.y); - float shadingAmount = vColor.r * gradientFade; - vec3 shadedColor = mix(backgroundColor, texColor.rgb, shadingAmount); - fragColor = vec4(shadedColor, texColor.a); - } else { - vec4 texColor = texture(texture, texCoord); - float shadingAmount = vColor.r; - vec3 shadedColor = mix(backgroundColor, texColor.rgb, shadingAmount); - fragColor = vec4(shadedColor, texColor.a); - } - } - )"; - - // Select shaders based on context type - const char *vertexShader = isES ? vertexShaderSourceES : vertexShaderSourceGL; - const char *fragmentShader = isES ? fragmentShaderSourceES : fragmentShaderSourceGL; - - qDebug() << "YACReaderFlowGL: Using" << (isES ? "OpenGL ES 3.0" : "Desktop OpenGL 3.3") << "shaders"; - - shaderProgram = new QOpenGLShaderProgram(this); - shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShader); - shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShader); - - if (!shaderProgram->link()) { - qWarning() << "YACReaderFlowGL: Shader linking failed:" << shaderProgram->log(); - } -} - -void YACReaderFlowGL::setupGeometry() -{ - // VAO for regular covers - vao = new QOpenGLVertexArrayObject(this); - vao->create(); - vao->bind(); - - vbo = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); - vbo->create(); - vbo->bind(); - - // Quad vertices with texture coordinates - GLfloat vertices[] = { - // Position (x, y, z), TexCoord (u, v) - -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-left - 0.5f, -0.5f, 0.0f, 1.0f, 1.0f, // Bottom-right - 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right - -0.5f, 0.5f, 0.0f, 0.0f, 0.0f // Top-left - }; - - vbo->allocate(vertices, sizeof(vertices)); - - // Position attribute - shaderProgram->enableAttributeArray(0); - shaderProgram->setAttributeBuffer(0, GL_FLOAT, 0, 3, 5 * sizeof(GLfloat)); - - // TexCoord attribute - shaderProgram->enableAttributeArray(1); - shaderProgram->setAttributeBuffer(1, GL_FLOAT, 3 * sizeof(GLfloat), 2, 5 * sizeof(GLfloat)); - - // Create instance buffer (will be filled per-frame) - instanceVBO = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); - instanceVBO->create(); - instanceVBO->bind(); - - // Per-instance attributes (model matrix = 4 vec4s, shading = 1 vec4, opacity = 1 float) - // Location 2-5: model matrix (mat4) - for (int i = 0; i < 4; i++) { - shaderProgram->enableAttributeArray(2 + i); - shaderProgram->setAttributeBuffer(2 + i, GL_FLOAT, i * 4 * sizeof(GLfloat), 4, 21 * sizeof(GLfloat)); - glVertexAttribDivisor(2 + i, 1); // Advance once per instance - } - - // Location 6: shading vec4 (leftUp, leftDown, rightUp, rightDown) - shaderProgram->enableAttributeArray(6); - shaderProgram->setAttributeBuffer(6, GL_FLOAT, 16 * sizeof(GLfloat), 4, 21 * sizeof(GLfloat)); - glVertexAttribDivisor(6, 1); - - // Location 7: opacity float - shaderProgram->enableAttributeArray(7); - shaderProgram->setAttributeBuffer(7, GL_FLOAT, 20 * sizeof(GLfloat), 1, 21 * sizeof(GLfloat)); - glVertexAttribDivisor(7, 1); - - vao->release(); - instanceVBO->release(); - vbo->release(); -} - -void YACReaderFlowGL::initializeGL() -{ - if (!context() || !context()->isValid()) { - qWarning() << "YACReaderFlowGL: Invalid OpenGL context"; - return; - } - - initializeOpenGLFunctions(); - - // Verify instancing support (available in OpenGL 3.3+ and ES 3.0+) - bool hasInstancing = context()->hasExtension(QByteArrayLiteral("GL_ARB_instanced_arrays")) || - context()->format().majorVersion() >= 3; - - if (!hasInstancing) { - qWarning() << "YACReaderFlowGL: Instanced rendering not supported!"; - qWarning() << "YACReaderFlowGL: OpenGL version:" << context()->format().majorVersion() << "." << context()->format().minorVersion(); - return; - } - - setupShaders(); - setupGeometry(); - - defaultTexture = new QOpenGLTexture(QImage(":/images/defaultCover.png")); - defaultTexture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::LinearMipMapLinear); - -#ifdef YACREADER_LIBRARY - markTexture = new QOpenGLTexture(QImage(":/images/readRibbon.png")); - markTexture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::LinearMipMapLinear); - - readingTexture = new QOpenGLTexture(QImage(":/images/readingRibbon.png")); - readingTexture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::LinearMipMapLinear); -#endif - - if (lazyPopulateObjects != -1) - populate(lazyPopulateObjects); - - hasBeenInitialized = true; -} - -void YACReaderFlowGL::paintGL() -{ - if (!context() || !context()->isValid() || !shaderProgram) - return; - - QPainter painter; - painter.begin(this); - painter.beginNativePainting(); - - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glEnable(GL_BLEND); - glEnable(GL_MULTISAMPLE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glClearColor(backgroundColor.redF(), backgroundColor.greenF(), backgroundColor.blueF(), 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - if (numObjects > 0) { - updatePositions(); - updatePerspective(width(), height()); - draw(); - } - - glDisable(GL_MULTISAMPLE); - glDisable(GL_BLEND); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - - painter.endNativePainting(); - - QFont font = painter.font(); - font.setFamily("Arial"); - font.setPointSize(fontSize); - painter.setFont(font); - painter.setPen(textColor); - painter.drawText(10, fontSize + 10, QString("%1/%2").arg(currentSelected + 1).arg(numObjects)); - - painter.end(); -} - -void YACReaderFlowGL::resizeGL(int width, int height) -{ - if (!context() || !context()->isValid()) - return; - - fontSize = (width + height) * 0.010; - if (fontSize < 10) - fontSize = 10; - - updatePerspective(width, height); - - if (numObjects > 0) - updatePositions(); -} - -void YACReaderFlowGL::updatePerspective(int width, int height) -{ - if (!context() || !context()->isValid()) - return; - - float pixelRatio = devicePixelRatioF(); - glViewport(0, 0, width * pixelRatio, height * pixelRatio); -} - -void YACReaderFlowGL::calcPos(YACReader3DImage &image, int pos) -{ - if (flowRightToLeft) { - pos = pos * -1; - } - - if (pos == 0) { - image.current = centerPos; - } else { - if (pos > 0) { - image.current.x = (config.centerDistance) + (config.xDistance * pos); - image.current.y = config.yDistance * pos * -1; - image.current.z = config.zDistance * pos * -1; - image.current.rot = config.rotation; - } else { - image.current.x = (config.centerDistance) * -1 + (config.xDistance * pos); - image.current.y = config.yDistance * pos; - image.current.z = config.zDistance * pos; - image.current.rot = config.rotation * -1; - } - } -} - -void YACReaderFlowGL::calcVector(YACReader3DVector &vector, int pos) -{ - calcPos(dummy, pos); - vector.x = dummy.current.x; - vector.y = dummy.current.y; - vector.z = dummy.current.z; - vector.rot = dummy.current.rot; -} - -bool YACReaderFlowGL::animate(YACReader3DVector ¤tVector, YACReader3DVector &toVector) -{ - float rotDiff = toVector.rot - currentVector.rot; - float xDiff = toVector.x - currentVector.x; - float yDiff = toVector.y - currentVector.y; - float zDiff = toVector.z - currentVector.z; - - if (fabs(rotDiff) < 0.01 && fabs(xDiff) < 0.001 && fabs(yDiff) < 0.001 && fabs(zDiff) < 0.001) - return true; - - currentVector.x = currentVector.x + (xDiff)*config.animationStep; - currentVector.y = currentVector.y + (yDiff)*config.animationStep; - currentVector.z = currentVector.z + (zDiff)*config.animationStep; - - if (fabs(rotDiff) > 0.01) { - currentVector.rot = currentVector.rot + (rotDiff) * (config.animationStep * config.preRotation); - } else { - viewRotateActive = 0; - } - - return false; -} - -void YACReaderFlowGL::drawCover(const YACReader3DImage &image) -{ - if (!shaderProgram || !vao || !image.texture) - return; - - float w = image.width; - float h = image.height; - - // Calculate opacity - original formula exactly - float opacity = 1 - 1 / (config.animationFadeOutDist + config.viewRotateLightStrenght * fabs(viewRotate)) * fabs(0 - image.current.x); - - // Setup matrices - QMatrix4x4 projectionMatrix; - projectionMatrix.perspective(config.zoom, GLdouble(width()) / (float)height(), 1.0, 200.0); - - QMatrix4x4 viewMatrix; - viewMatrix.translate(config.cfX, config.cfY, config.cfZ); - viewMatrix.rotate(config.cfRX, 1, 0, 0); - viewMatrix.rotate(viewRotate * config.viewAngle + config.cfRY, 0, 1, 0); - viewMatrix.rotate(config.cfRZ, 0, 0, 1); - - QMatrix4x4 modelMatrix; - modelMatrix.translate(image.current.x, image.current.y, image.current.z); - modelMatrix.rotate(image.current.rot, 0, 1, 0); - modelMatrix.translate(0.0f, -0.5f + h / 2.0f, 0.0f); - modelMatrix.scale(w, h, 1.0f); - - QMatrix4x4 mvpMatrix = projectionMatrix * viewMatrix * modelMatrix; - - // Calculate per-corner shading exactly as original - float LShading = ((config.rotation != 0) ? ((image.current.rot < 0) ? 1 - 1 / config.rotation * image.current.rot : 1) : 1); - float RShading = ((config.rotation != 0) ? ((image.current.rot > 0) ? 1 - 1 / (config.rotation * -1) * image.current.rot : 1) : 1); - float LUP = shadingTop + (1 - shadingTop) * LShading; - float LDOWN = shadingBottom + (1 - shadingBottom) * LShading; - float RUP = shadingTop + (1 - shadingTop) * RShading; - float RDOWN = shadingBottom + (1 - shadingBottom) * RShading; - - // Bind shader and set uniforms - shaderProgram->bind(); - shaderProgram->setUniformValue("mvpMatrix", mvpMatrix); - shaderProgram->setUniformValue("leftUpShading", LUP); - shaderProgram->setUniformValue("leftDownShading", LDOWN); - shaderProgram->setUniformValue("rightUpShading", RUP); - shaderProgram->setUniformValue("rightDownShading", RDOWN); - shaderProgram->setUniformValue("opacity", opacity); - shaderProgram->setUniformValue("isReflection", false); - - // Bind texture and VAO - image.texture->bind(); - vao->bind(); - - // Draw cover - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - // Draw marks if needed - if (showMarks && loaded[image.index] && marks[image.index] != Unread) { - QOpenGLTexture *markTex = (marks[image.index] == Read) ? markTexture : readingTexture; - - QMatrix4x4 markModel; - markModel.translate(image.current.x, image.current.y, image.current.z); - markModel.rotate(image.current.rot, 0, 1, 0); - - float markWidth = 0.15f; - float markHeight = 0.2f; - float markCenterX = w / 2.0f - 0.125f; - float markCenterY = -0.588f + h; - - markModel.translate(markCenterX, markCenterY, 0.001f); - markModel.scale(markWidth, markHeight, 1.0f); - - QMatrix4x4 mvpMark = projectionMatrix * viewMatrix * markModel; - - shaderProgram->setUniformValue("mvpMatrix", mvpMark); - shaderProgram->setUniformValue("leftUpShading", RUP * opacity); - shaderProgram->setUniformValue("leftDownShading", RUP * opacity); - shaderProgram->setUniformValue("rightUpShading", RUP * opacity); - shaderProgram->setUniformValue("rightDownShading", RUP * opacity); - shaderProgram->setUniformValue("opacity", 1.0f); - shaderProgram->setUniformValue("isReflection", false); - - markTex->bind(); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - - vao->release(); - shaderProgram->release(); -} - -void YACReaderFlowGL::drawReflection(const YACReader3DImage &image) -{ - if (!shaderProgram || !vao || !image.texture) - return; - - float w = image.width; - float h = image.height; - - // Calculate opacity - original formula exactly - float opacity = 1 - 1 / (config.animationFadeOutDist + config.viewRotateLightStrenght * fabs(viewRotate)) * fabs(0 - image.current.x); - - // Setup matrices - QMatrix4x4 projectionMatrix; - projectionMatrix.perspective(config.zoom, GLdouble(width()) / (float)height(), 1.0, 200.0); - - QMatrix4x4 viewMatrix; - viewMatrix.translate(config.cfX, config.cfY, config.cfZ); - viewMatrix.rotate(config.cfRX, 1, 0, 0); - viewMatrix.rotate(viewRotate * config.viewAngle + config.cfRY, 0, 1, 0); - viewMatrix.rotate(config.cfRZ, 0, 0, 1); - - // Calculate per-corner shading exactly as original - float LShading = ((config.rotation != 0) ? ((image.current.rot < 0) ? 1 - 1 / config.rotation * image.current.rot : 1) : 1); - float RShading = ((config.rotation != 0) ? ((image.current.rot > 0) ? 1 - 1 / (config.rotation * -1) * image.current.rot : 1) : 1); - float LUP = shadingTop + (1 - shadingTop) * LShading; - float LDOWN = shadingBottom + (1 - shadingBottom) * LShading; - float RUP = shadingTop + (1 - shadingTop) * RShading; - float RDOWN = shadingBottom + (1 - shadingBottom) * RShading; - - // Draw reflection - // In the old code, the reflection quad had vertices from y=-0.5-h (bottom) to y=-0.5 (top) - // The OLD reflection shading was: - // - Bottom corners (y = -0.5-h): LUP*opacity*reflectionUp/2, RUP*opacity*reflectionUp/2 - // - Top corners (y = -0.5): LDOWN*opacity/3, RDOWN*opacity/3 - // This means the reflection uses INVERTED vertical shading (LUP/RUP at bottom, LDOWN/RDOWN at top) - // We need to pass swapped values to match this - QMatrix4x4 reflectionMatrix; - reflectionMatrix.translate(image.current.x, image.current.y, image.current.z); - reflectionMatrix.rotate(image.current.rot, 0, 1, 0); - reflectionMatrix.translate(0.0f, -0.5f - h / 2.0f, 0.0f); - reflectionMatrix.scale(w, h, 1.0f); - - QMatrix4x4 mvpReflection = projectionMatrix * viewMatrix * reflectionMatrix; - - shaderProgram->bind(); - shaderProgram->setUniformValue("mvpMatrix", mvpReflection); - // Swap UP and DOWN for reflection to match old behavior - shaderProgram->setUniformValue("leftUpShading", LDOWN); - shaderProgram->setUniformValue("leftDownShading", LUP); - shaderProgram->setUniformValue("rightUpShading", RDOWN); - shaderProgram->setUniformValue("rightDownShading", RUP); - shaderProgram->setUniformValue("opacity", opacity); - shaderProgram->setUniformValue("isReflection", true); - shaderProgram->setUniformValue("reflectionUp", reflectionUp); - shaderProgram->setUniformValue("reflectionDown", reflectionBottom); - - image.texture->bind(); - vao->bind(); - - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - vao->release(); - shaderProgram->release(); -} - -void YACReaderFlowGL::cleanupAnimation() -{ - config.animationStep = stepBackup; - viewRotateActive = 0; -} - -void YACReaderFlowGL::draw() -{ - if (!shaderProgram || !vao || numObjects == 0) - return; - - // Calculate view-projection matrix once - // Note: Old implementation used fixed 20.0 degrees FOV, not config.zoom - QMatrix4x4 projectionMatrix; - projectionMatrix.perspective(20.0, GLdouble(width()) / (float)height(), 1.0, 200.0); - - QMatrix4x4 viewMatrix; - viewMatrix.translate(config.cfX, config.cfY, config.cfZ); - viewMatrix.rotate(config.cfRX, 1, 0, 0); - viewMatrix.rotate(viewRotate * config.viewAngle + config.cfRY, 0, 1, 0); - viewMatrix.rotate(config.cfRZ, 0, 0, 1); - - QMatrix4x4 viewProjectionMatrix = projectionMatrix * viewMatrix; - - // Bind shader once - shaderProgram->bind(); - shaderProgram->setUniformValue("viewProjectionMatrix", viewProjectionMatrix); - shaderProgram->setUniformValue("backgroundColor", - QVector3D(backgroundColor.redF(), backgroundColor.greenF(), backgroundColor.blueF())); - shaderProgram->setUniformValue("shadingColor", - QVector3D(shadingColor.redF(), shadingColor.greenF(), shadingColor.blueF())); - - int CS = currentSelected; - - // Prepare instance data for all covers - QVector instanceData; - QVector drawOrder; - - // Build draw order (back to front) - for (int count = numObjects - 1; count > -1; count--) { - if (count > CS) { - drawOrder.append(count); - } - } - for (int count = 0; count < numObjects - 1; count++) { - if (count < CS) { - drawOrder.append(count); - } - } - drawOrder.append(CS); - - // Draw reflections first - shaderProgram->setUniformValue("isReflection", true); - shaderProgram->setUniformValue("reflectionUp", reflectionUp); - shaderProgram->setUniformValue("reflectionDown", reflectionBottom); - - for (int idx : drawOrder) { - if (images[idx].texture) { - prepareInstanceData(images[idx], true, instanceData); - - instanceVBO->bind(); - instanceVBO->allocate(instanceData.data(), instanceData.size() * sizeof(GLfloat)); - - images[idx].texture->bind(); - vao->bind(); - glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, 1); - - instanceData.clear(); - } - } - - // Draw covers - shaderProgram->setUniformValue("isReflection", false); - - for (int idx : drawOrder) { - if (images[idx].texture) { - prepareInstanceData(images[idx], false, instanceData); - - instanceVBO->bind(); - instanceVBO->allocate(instanceData.data(), instanceData.size() * sizeof(GLfloat)); - - images[idx].texture->bind(); - vao->bind(); - glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, 1); - - // Draw marks if needed - if (showMarks && loaded[images[idx].index] && marks[images[idx].index] != Unread) { - drawMark(images[idx], viewProjectionMatrix); - } - - instanceData.clear(); - } - } - - vao->release(); - shaderProgram->release(); -} - -void YACReaderFlowGL::prepareInstanceData(const YACReader3DImage &image, bool isReflection, QVector &data) -{ - float w = image.width; - float h = image.height; - - // Calculate opacity - float opacity = 1 - 1 / (config.animationFadeOutDist + config.viewRotateLightStrenght * fabs(viewRotate)) * fabs(0 - image.current.x); - - // Calculate model matrix - QMatrix4x4 modelMatrix; - modelMatrix.translate(image.current.x, image.current.y, image.current.z); - modelMatrix.rotate(image.current.rot, 0, 1, 0); - - if (isReflection) { - modelMatrix.translate(0.0f, -0.5f - h / 2.0f, 0.0f); - } else { - modelMatrix.translate(0.0f, -0.5f + h / 2.0f, 0.0f); - } - modelMatrix.scale(w, h, 1.0f); - - // Calculate shading - float LShading = ((config.rotation != 0) ? ((image.current.rot < 0) ? 1 - 1 / config.rotation * image.current.rot : 1) : 1); - float RShading = ((config.rotation != 0) ? ((image.current.rot > 0) ? 1 - 1 / (config.rotation * -1) * image.current.rot : 1) : 1); - float LUP = shadingTop + (1 - shadingTop) * LShading; - float LDOWN = shadingBottom + (1 - shadingBottom) * LShading; - float RUP = shadingTop + (1 - shadingTop) * RShading; - float RDOWN = shadingBottom + (1 - shadingBottom) * RShading; - - // For reflection, swap vertical shading - if (isReflection) { - float temp = LUP; - LUP = LDOWN; - LDOWN = temp; - temp = RUP; - RUP = RDOWN; - RDOWN = temp; - } - - // Pack instance data: mat4 (16 floats) + vec4 shading (4 floats) + float opacity (1 float) = 21 floats - const float *matData = modelMatrix.constData(); - for (int i = 0; i < 16; i++) { - data.append(matData[i]); - } - data.append(LUP); - data.append(LDOWN); - data.append(RUP); - data.append(RDOWN); - data.append(opacity); -} - -void YACReaderFlowGL::drawMark(const YACReader3DImage &image, const QMatrix4x4 &viewProjectionMatrix) -{ - QOpenGLTexture *markTex = (marks[image.index] == Read) ? markTexture : readingTexture; - - float w = image.width; - float h = image.height; - float opacity = 1 - 1 / (config.animationFadeOutDist + config.viewRotateLightStrenght * fabs(viewRotate)) * fabs(0 - image.current.x); - - float LShading = ((config.rotation != 0) ? ((image.current.rot < 0) ? 1 - 1 / config.rotation * image.current.rot : 1) : 1); - float RShading = ((config.rotation != 0) ? ((image.current.rot > 0) ? 1 - 1 / (config.rotation * -1) * image.current.rot : 1) : 1); - float RUP = shadingTop + (1 - shadingTop) * RShading; - - QMatrix4x4 markModel; - markModel.translate(image.current.x, image.current.y, image.current.z); - markModel.rotate(image.current.rot, 0, 1, 0); - - float markWidth = 0.15f; - float markHeight = 0.2f; - float markCenterX = w / 2.0f - 0.125f; - float markCenterY = -0.588f + h; - - markModel.translate(markCenterX, markCenterY, 0.001f); - markModel.scale(markWidth, markHeight, 1.0f); - - // Prepare instance data for mark - QVector markData; - const float *matData = markModel.constData(); - for (int i = 0; i < 16; i++) { - markData.append(matData[i]); - } - float shadingValue = RUP * opacity; - markData.append(shadingValue); - markData.append(shadingValue); - markData.append(shadingValue); - markData.append(shadingValue); - markData.append(1.0f); - - instanceVBO->bind(); - instanceVBO->allocate(markData.data(), markData.size() * sizeof(GLfloat)); - - markTex->bind(); - vao->bind(); - glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, 1); -} - -void YACReaderFlowGL::showPrevious() -{ - startAnimationTimer(); - - if (currentSelected > 0) { - currentSelected--; - emit centerIndexChanged(currentSelected); - config.animationStep *= config.animationSpeedUp; - - if (config.animationStep > config.animationStepMax) { - config.animationStep = config.animationStepMax; - } - - if (viewRotateActive && viewRotate > -1) { - viewRotate -= config.viewRotateAdd; - } - - viewRotateActive = 1; - } -} - -void YACReaderFlowGL::showNext() -{ - startAnimationTimer(); - - if (currentSelected < numObjects - 1) { - currentSelected++; - emit centerIndexChanged(currentSelected); - config.animationStep *= config.animationSpeedUp; - - if (config.animationStep > config.animationStepMax) { - config.animationStep = config.animationStepMax; - } - - if (viewRotateActive && viewRotate < 1) { - viewRotate += config.viewRotateAdd; - } - - viewRotateActive = 1; - } -} - -void YACReaderFlowGL::setCurrentIndex(int pos) -{ - if (!(pos >= 0 && pos < images.length() && images.length() > 0)) - return; - if (pos >= images.length() && images.length() > 0) - pos = images.length() - 1; - - startAnimationTimer(); - - currentSelected = pos; - config.animationStep *= config.animationSpeedUp; - - if (config.animationStep > config.animationStepMax) { - config.animationStep = config.animationStepMax; - } - - if (viewRotateActive && viewRotate < 1) { - viewRotate += config.viewRotateAdd; - } - - viewRotateActive = 1; -} - -void YACReaderFlowGL::updatePositions() -{ - int count; - bool stopAnimation = true; - - for (count = numObjects - 1; count > -1; count--) { - calcVector(images[count].animEnd, count - currentSelected); - if (!animate(images[count].current, images[count].animEnd)) - stopAnimation = false; - } - - if (!viewRotateActive) { - viewRotate += (0 - viewRotate) * config.viewRotateSub; - } - - if (fabs(images[currentSelected].current.x - images[currentSelected].animEnd.x) < 1) { - cleanupAnimation(); - if (updateCount >= 0) { - updateCount = 0; - updateImageData(); - } else - updateCount++; - } else - updateCount++; - - if (stopAnimation) - stopAnimationTimer(); -} - -void YACReaderFlowGL::insert(char *name, QOpenGLTexture *texture, float x, float y, int item) -{ - startAnimationTimer(); - - Q_UNUSED(name) - if (item == -1) { - images.push_back(YACReader3DImage()); - item = numObjects; - numObjects++; - calcVector(images[item].current, item); - images[item].current.z = images[item].current.z - 1; - } - - images[item].texture = texture; - images[item].width = x; - images[item].height = y; - images[item].index = item; -} - -void YACReaderFlowGL::remove(int item) -{ - if (item < 0 || item >= images.size()) - return; - - startAnimationTimer(); - - loaded.remove(item); - marks.remove(item); - - if (item <= currentSelected && currentSelected != 0) { - currentSelected--; - } - - QOpenGLTexture *texture = images[item].texture; - - int count = item; - while (count <= numObjects - 1) { - images[count].index--; - count++; - } - images.removeAt(item); - - if (texture != defaultTexture) - delete (texture); - - numObjects--; -} - -void YACReaderFlowGL::add(int item) -{ - float x = 1; - float y = 1 * (700.f / 480.0f); - QString s = "cover"; - - images.insert(item, YACReader3DImage()); - loaded.insert(item, false); - marks.insert(item, Unread); - numObjects++; - - for (int i = item + 1; i < numObjects; i++) { - images[i].index++; - } - - insert(s.toLocal8Bit().data(), defaultTexture, x, y, item); -} - -YACReader3DImage YACReaderFlowGL::getCurrentSelected() -{ - return images[currentSelected]; -} - -void YACReaderFlowGL::replace(char *name, QOpenGLTexture *texture, float x, float y, int item) -{ - startAnimationTimer(); - - Q_UNUSED(name) - if (images[item].index == item) { - images[item].texture = texture; - images[item].width = x; - images[item].height = y; - loaded[item] = true; - } else - loaded[item] = false; -} - -void YACReaderFlowGL::populate(int n) -{ - emit centerIndexChanged(0); - - float x = 1; - float y = 1 * (700.f / 480.0f); - int i; - - for (i = 0; i < n; i++) { - QString s = "cover"; - insert(s.toLocal8Bit().data(), defaultTexture, x, y); - } - - loaded = QVector(n, false); -} - -void YACReaderFlowGL::reset() -{ - makeCurrent(); - startAnimationTimer(); - - currentSelected = 0; - loaded.clear(); - - for (int i = 0; i < numObjects; i++) { - if (images[i].texture != defaultTexture) - delete (images[i].texture); - } - - numObjects = 0; - images.clear(); - - if (!hasBeenInitialized) - lazyPopulateObjects = -1; - - doneCurrent(); -} - -void YACReaderFlowGL::reload() -{ - startAnimationTimer(); - int n = numObjects; - reset(); - populate(n); -} - -// Slot implementations -void YACReaderFlowGL::setCF_RX(int value) -{ - startAnimationTimer(); - config.cfRX = value; -} -void YACReaderFlowGL::setCF_RY(int value) -{ - startAnimationTimer(); - config.cfRY = value; -} -void YACReaderFlowGL::setCF_RZ(int value) -{ - startAnimationTimer(); - config.cfRZ = value; -} -void YACReaderFlowGL::setRotation(int angle) -{ - startAnimationTimer(); - config.rotation = -angle; -} -void YACReaderFlowGL::setX_Distance(int distance) -{ - startAnimationTimer(); - config.xDistance = distance / 100.0; -} -void YACReaderFlowGL::setCenter_Distance(int distance) -{ - startAnimationTimer(); - config.centerDistance = distance / 100.0; -} -void YACReaderFlowGL::setZ_Distance(int distance) -{ - startAnimationTimer(); - config.zDistance = distance / 100.0; -} -void YACReaderFlowGL::setCF_Y(int value) -{ - startAnimationTimer(); - config.cfY = value / 100.0; -} -void YACReaderFlowGL::setCF_Z(int value) -{ - startAnimationTimer(); - config.cfZ = value; -} -void YACReaderFlowGL::setY_Distance(int value) -{ - startAnimationTimer(); - config.yDistance = value / 100.0; -} -void YACReaderFlowGL::setFadeOutDist(int value) -{ - startAnimationTimer(); - config.animationFadeOutDist = value; -} -void YACReaderFlowGL::setLightStrenght(int value) -{ - startAnimationTimer(); - config.viewRotateLightStrenght = value; -} -void YACReaderFlowGL::setMaxAngle(int value) -{ - startAnimationTimer(); - config.viewAngle = value; -} -void YACReaderFlowGL::setPreset(const Preset &p) -{ - startAnimationTimer(); - config = p; -} - -void YACReaderFlowGL::setZoom(int zoom) -{ - startAnimationTimer(); - config.zoom = zoom; -} - -void YACReaderFlowGL::setPerformance(Performance performance) -{ - if (this->performance != performance) { - startAnimationTimer(); - this->performance = performance; - reload(); - } -} - -void YACReaderFlowGL::useVSync(bool b) -{ - if (bUseVSync != b) { - bUseVSync = b; - QSurfaceFormat f = format(); - f.setVersion(3, 3); - f.setProfile(QSurfaceFormat::CoreProfile); - f.setSwapInterval(b ? 1 : 0); - setFormat(f); - reset(); - } -} - -void YACReaderFlowGL::setShowMarks(bool value) -{ - startAnimationTimer(); - showMarks = value; -} -void YACReaderFlowGL::setMarks(QVector marks) -{ - startAnimationTimer(); - this->marks = marks; -} -void YACReaderFlowGL::setMarkImage(QImage &image) -{ - Q_UNUSED(image); -} -void YACReaderFlowGL::markSlide(int index, YACReader::YACReaderComicReadStatus status) -{ - startAnimationTimer(); - marks[index] = status; -} -void YACReaderFlowGL::unmarkSlide(int index) -{ - startAnimationTimer(); - marks[index] = YACReader::Unread; -} -void YACReaderFlowGL::setSlideSize(QSize size) -{ - Q_UNUSED(size); -} -void YACReaderFlowGL::clear() -{ - reset(); -} -void YACReaderFlowGL::setCenterIndex(unsigned int index) -{ - setCurrentIndex(index); -} -void YACReaderFlowGL::showSlide(int index) -{ - setCurrentIndex(index); -} -int YACReaderFlowGL::centerIndex() -{ - return currentSelected; -} -void YACReaderFlowGL::updateMarks() { } -void YACReaderFlowGL::render() { } -void YACReaderFlowGL::setFlowRightToLeft(bool b) -{ - flowRightToLeft = b; -} - -void YACReaderFlowGL::setBackgroundColor(const QColor &color) -{ - backgroundColor = color; - - // Auto-calculate shadingColor based on background brightness - qreal luminance = (backgroundColor.redF() * 0.299 + - backgroundColor.greenF() * 0.587 + - backgroundColor.blueF() * 0.114); - - if (luminance < 0.5) { - // Dark background - shade towards white - shadingColor = QColor(255, 255, 255); - // Use original shading values for dark backgrounds - shadingTop = 0.8f; - shadingBottom = 0.02f; - } else { - // Light background - shade towards black - shadingColor = QColor(0, 0, 0); - // Adjust shading range for better contrast on light backgrounds - shadingTop = 0.95f; - shadingBottom = 0.3f; - } - - update(); -} - -void YACReaderFlowGL::setTextColor(const QColor &color) -{ - textColor = color; - update(); -} - -void YACReaderFlowGL::setShadingColor(const QColor &color) -{ - shadingColor = color; - update(); -} - -// Event handlers -void YACReaderFlowGL::wheelEvent(QWheelEvent *event) -{ - Movement m = getMovement(event); - switch (m) { - case None: - return; - case Forward: - showNext(); - break; - case Backward: - showPrevious(); - break; - default: - break; - } -} - -void YACReaderFlowGL::keyPressEvent(QKeyEvent *event) -{ - if ((event->key() == Qt::Key_Left && !flowRightToLeft) || (event->key() == Qt::Key_Right && flowRightToLeft)) { - if (event->modifiers() == Qt::ControlModifier) - setCurrentIndex((currentSelected - 10 < 0) ? 0 : currentSelected - 10); - else - showPrevious(); - event->accept(); - return; - } - - if ((event->key() == Qt::Key_Right && !flowRightToLeft) || (event->key() == Qt::Key_Left && flowRightToLeft)) { - if (event->modifiers() == Qt::ControlModifier) - setCurrentIndex((currentSelected + 10 >= numObjects) ? numObjects - 1 : currentSelected + 10); - else - showNext(); - event->accept(); - return; - } - - if (event->key() == Qt::Key_Up) { - return; - } - - event->ignore(); -} - -void YACReaderFlowGL::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) { - QVector3D intersection = getPlaneIntersection(event->x(), event->y(), images[currentSelected]); - if ((intersection.x() > 0.5 && !flowRightToLeft) || (intersection.x() < -0.5 && flowRightToLeft)) { - showNext(); - } else if ((intersection.x() < -0.5 && !flowRightToLeft) || (intersection.x() > 0.5 && flowRightToLeft)) { - showPrevious(); - } - } else { - QOpenGLWidget::mousePressEvent(event); - } - doneCurrent(); -} - -void YACReaderFlowGL::mouseDoubleClickEvent(QMouseEvent *event) -{ - QVector3D intersection = getPlaneIntersection(event->x(), event->y(), images[currentSelected]); - - if (intersection.x() < 0.5 && intersection.x() > -0.5) { - emit selected(centerIndex()); - event->accept(); - } -} - -QVector3D YACReaderFlowGL::getPlaneIntersection(int x, int y, YACReader3DImage plane) -{ - if (!context() || !context()->isValid()) - return QVector3D(0, 0, 0); - - GLint viewport[4]; - QMatrix4x4 m_modelview; - QMatrix4x4 m_projection; - - makeCurrent(); - glGetIntegerv(GL_VIEWPORT, viewport); - - m_projection.perspective(config.zoom, GLdouble(width()) / (float)height(), 1.0, 200.0); - - m_modelview.translate(config.cfX, config.cfY, config.cfZ); - m_modelview.rotate(config.cfRX, 1, 0, 0); - m_modelview.rotate(viewRotate * config.viewAngle + config.cfRY, 0, 1, 0); - m_modelview.rotate(config.cfRZ, 0, 0, 1); - m_modelview.translate(plane.current.x, plane.current.y, plane.current.z); - m_modelview.rotate(plane.current.rot, 0, 1, 0); - m_modelview.scale(plane.width, plane.height, 1.0f); - - doneCurrent(); - - QVector3D ray_origin(x * devicePixelRatioF(), y * devicePixelRatioF(), 0); - QVector3D ray_end(x * devicePixelRatioF(), y * devicePixelRatioF(), 1.0); - - ray_origin = ray_origin.unproject(m_modelview, m_projection, QRect(viewport[0], viewport[1], viewport[2], viewport[3])); - ray_end = ray_end.unproject(m_modelview, m_projection, QRect(viewport[0], viewport[1], viewport[2], viewport[3])); - - QVector3D ray_vector = ray_end - ray_origin; - - QVector3D plane_origin(-0.5f, -0.5f, 0); - QVector3D plane_vektor_1 = QVector3D(0.5f, -0.5f, 0) - plane_origin; - QVector3D plane_vektor_2 = QVector3D(-0.5f, 0.5f, 0) - plane_origin; - - double intersection_LES_determinant = ((plane_vektor_1.x() * plane_vektor_2.y() * (-1) * ray_vector.z()) + - (plane_vektor_2.x() * (-1) * ray_vector.y() * plane_vektor_1.z()) + - ((-1) * ray_vector.x() * plane_vektor_1.y() * plane_vektor_2.z()) - - ((-1) * ray_vector.x() * plane_vektor_2.y() * plane_vektor_1.z()) - - (plane_vektor_1.x() * (-1) * ray_vector.y() * plane_vektor_2.z()) - - (plane_vektor_2.x() * plane_vektor_1.y() * (-1) * ray_vector.z())); - - QVector3D det = ray_origin - plane_origin; - - double intersection_ray_determinant = ((plane_vektor_1.x() * plane_vektor_2.y() * det.z()) + - (plane_vektor_2.x() * det.y() * plane_vektor_1.z()) + - (det.x() * plane_vektor_1.y() * plane_vektor_2.z()) - - (det.x() * plane_vektor_2.y() * plane_vektor_1.z()) - - (plane_vektor_1.x() * det.y() * plane_vektor_2.z()) - - (plane_vektor_2.x() * plane_vektor_1.y() * det.z())); - - return ray_origin + ray_vector * (intersection_ray_determinant / intersection_LES_determinant); -} - -// YACReaderComicFlowGL implementation -YACReaderComicFlowGL::YACReaderComicFlowGL(QWidget *parent, struct Preset p) - : YACReaderFlowGL(parent, p) -{ - worker = new ImageLoaderGL(this); - worker->flow = this; -} - -void YACReaderComicFlowGL::setImagePaths(QStringList paths) -{ - worker->reset(); - reset(); - numObjects = 0; - if (lazyPopulateObjects != -1 || hasBeenInitialized) - YACReaderFlowGL::populate(paths.size()); - lazyPopulateObjects = paths.size(); - this->paths = paths; -} - -void YACReaderComicFlowGL::updateImageData() -{ - if (worker->busy()) - return; - - int idx = worker->index(); - if (idx >= 0 && !worker->result().isNull()) { - if (!loaded[idx]) { - float x = 1; - QImage img = worker->result(); - QOpenGLTexture *texture = new QOpenGLTexture(img); - - if (performance == high || performance == ultraHigh) { - texture->setAutoMipMapGenerationEnabled(true); - texture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::LinearMipMapLinear); - } else { - texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear); - } - - float y = 1 * (float(img.height()) / img.width()); - QString s = "cover"; - replace(s.toLocal8Bit().data(), texture, x, y, idx); - } - } - - int count = 8; - switch (performance) { - case low: - count = 8; - break; - case medium: - count = 10; - break; - case high: - count = 12; - break; - case ultraHigh: - count = 16; - break; - } - - int *indexes = new int[2 * count + 1]; - int center = currentSelected; - indexes[0] = center; - for (int j = 0; j < count; j++) { - indexes[j * 2 + 1] = center + j + 1; - indexes[j * 2 + 2] = center - j - 1; - } - - for (int c = 0; c < 2 * count + 1; c++) { - int i = indexes[c]; - if ((i >= 0) && (i < numObjects)) - if (!loaded[i]) { - if (paths.size() > 0) { - QString fname = paths.at(i); - worker->generate(i, fname); - } - delete[] indexes; - return; - } - } - - delete[] indexes; -} - -void YACReaderComicFlowGL::remove(int item) -{ - worker->lock(); - worker->reset(); - YACReaderFlowGL::remove(item); - if (item >= 0 && item < paths.size()) { - paths.removeAt(item); - } - worker->unlock(); -} - -void YACReaderComicFlowGL::add(const QString &path, int index) -{ - worker->lock(); - worker->reset(); - paths.insert(index, path); - YACReaderFlowGL::add(index); - worker->unlock(); -} - -void YACReaderComicFlowGL::resortCovers(QList newOrder) -{ - worker->lock(); - worker->reset(); - startAnimationTimer(); - - QList pathsNew; - QVector loadedNew; - QVector marksNew; - QVector imagesNew; - - int index = 0; - foreach (int i, newOrder) { - if (i < 0 || i >= images.size()) { - continue; - } - - pathsNew << paths.at(i); - loadedNew << loaded.at(i); - marksNew << marks.at(i); - imagesNew << images.at(i); - imagesNew.last().index = index++; - } - - paths = pathsNew; - loaded = loadedNew; - marks = marksNew; - images = imagesNew; - - worker->unlock(); -} - -// YACReaderPageFlowGL implementation -YACReaderPageFlowGL::YACReaderPageFlowGL(QWidget *parent, struct Preset p) - : YACReaderFlowGL(parent, p) -{ - worker = new ImageLoaderByteArrayGL(this); - worker->flow = this; -} - -YACReaderPageFlowGL::~YACReaderPageFlowGL() -{ - this->killTimer(timerId); - rawImages.clear(); - - makeCurrent(); - - for (auto &image : images) { - if (image.texture != defaultTexture) { - if (image.texture->isCreated()) { - image.texture->destroy(); - } - delete image.texture; - } - } - - if (defaultTexture != nullptr) { - if (defaultTexture->isCreated()) { - defaultTexture->destroy(); - } - delete defaultTexture; - } - - doneCurrent(); -} - -void YACReaderPageFlowGL::updateImageData() -{ - if (worker->busy()) - return; - - int idx = worker->index(); - if (idx >= 0 && !worker->result().isNull()) { - if (!loaded[idx]) { - float x = 1; - QImage img = worker->result(); - QOpenGLTexture *texture = new QOpenGLTexture(img); - - if (performance == high || performance == ultraHigh) { - texture->setAutoMipMapGenerationEnabled(true); - texture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::LinearMipMapLinear); - } else { - texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear); - } - - float y = 1 * (float(img.height()) / img.width()); - QString s = "cover"; - replace(s.toLocal8Bit().data(), texture, x, y, idx); - loaded[idx] = true; - } - } - - int count = 8; - switch (performance) { - case low: - count = 8; - break; - case medium: - count = 10; - break; - case high: - count = 12; - break; - case ultraHigh: - count = 14; - break; - } - - int *indexes = new int[2 * count + 1]; - int center = currentSelected; - indexes[0] = center; - for (int j = 0; j < count; j++) { - indexes[j * 2 + 1] = center + j + 1; - indexes[j * 2 + 2] = center - j - 1; - } - - for (int c = 0; c < 2 * count + 1; c++) { - int i = indexes[c]; - if ((i >= 0) && (i < numObjects)) - if (rawImages.size() > 0) - if (!loaded[i] && imagesReady[i]) { - worker->generate(i, rawImages.at(i)); - delete[] indexes; - return; - } - } - - delete[] indexes; -} - -void YACReaderPageFlowGL::populate(int n) -{ - worker->reset(); - if (lazyPopulateObjects != -1 || hasBeenInitialized) - YACReaderFlowGL::populate(n); - lazyPopulateObjects = n; - imagesReady = QVector(n, false); - rawImages = QVector(n); - imagesSetted = QVector(n, false); -} - -// ImageLoaderGL implementation -QImage ImageLoaderGL::loadImage(const QString &fileName) -{ - QImage image; - - if (!image.load(fileName)) { - return QImage(); - } - - switch (flow->performance) { - case low: - image = image.scaledToWidth(200, Qt::SmoothTransformation); - break; - case medium: - image = image.scaledToWidth(256, Qt::SmoothTransformation); - break; - case high: - image = image.scaledToWidth(320, Qt::SmoothTransformation); - break; - case ultraHigh: - break; - } - - return image; -} - -ImageLoaderGL::ImageLoaderGL(YACReaderFlowGL *flow) - : QThread(), flow(flow), restart(false), working(false), idx(-1) -{ -} - -ImageLoaderGL::~ImageLoaderGL() -{ - mutex.lock(); - condition.wakeOne(); - mutex.unlock(); - wait(); -} - -bool ImageLoaderGL::busy() const -{ - return isRunning() ? working : false; -} - -void ImageLoaderGL::generate(int index, const QString &fileName) -{ - mutex.lock(); - this->idx = index; - this->fileName = fileName; - this->size = size; - this->img = QImage(); - mutex.unlock(); - - if (!isRunning()) - start(); - else { - restart = true; - condition.wakeOne(); - } -} - -void ImageLoaderGL::lock() -{ - mutex.lock(); -} - -void ImageLoaderGL::unlock() -{ - mutex.unlock(); -} - -void ImageLoaderGL::run() -{ - for (;;) { - mutex.lock(); - this->working = true; - QString fileName = this->fileName; - mutex.unlock(); - - QImage image = loadImage(fileName); - - mutex.lock(); - this->working = false; - this->img = image; - mutex.unlock(); - - mutex.lock(); - if (!this->restart) - condition.wait(&mutex); - restart = false; - mutex.unlock(); - } -} - -QImage ImageLoaderGL::result() -{ - return img; -} - -// ImageLoaderByteArrayGL implementation -QImage ImageLoaderByteArrayGL::loadImage(const QByteArray &raw) -{ - QImage image; - - if (!image.loadFromData(raw)) { - return QImage(); - } - - switch (flow->performance) { - case low: - image = image.scaledToWidth(128, Qt::SmoothTransformation); - break; - case medium: - image = image.scaledToWidth(196, Qt::SmoothTransformation); - break; - case high: - image = image.scaledToWidth(256, Qt::SmoothTransformation); - break; - case ultraHigh: - image = image.scaledToWidth(320, Qt::SmoothTransformation); - break; - } - - return image; -} - -ImageLoaderByteArrayGL::ImageLoaderByteArrayGL(YACReaderFlowGL *flow) - : QThread(), flow(flow), restart(false), working(false), idx(-1) -{ -} - -ImageLoaderByteArrayGL::~ImageLoaderByteArrayGL() -{ - mutex.lock(); - condition.wakeOne(); - mutex.unlock(); - wait(); -} - -bool ImageLoaderByteArrayGL::busy() const -{ - return isRunning() ? working : false; -} - -void ImageLoaderByteArrayGL::generate(int index, const QByteArray &raw) -{ - mutex.lock(); - this->idx = index; - this->rawData = raw; - this->size = size; - this->img = QImage(); - mutex.unlock(); - - if (!isRunning()) - start(); - else { - restart = true; - condition.wakeOne(); - } -} - -void ImageLoaderByteArrayGL::run() -{ - for (;;) { - mutex.lock(); - this->working = true; - QByteArray raw = this->rawData; - mutex.unlock(); - - QImage image = loadImage(raw); - - mutex.lock(); - this->working = false; - this->img = image; - mutex.unlock(); - - mutex.lock(); - if (!this->restart) - condition.wait(&mutex); - restart = false; - mutex.unlock(); - } -} - -QImage ImageLoaderByteArrayGL::result() -{ - return img; -} diff --git a/common/gl/yacreader_flow_gl.h b/common/gl/yacreader_flow_gl.h deleted file mode 100644 index 5571c24b..00000000 --- a/common/gl/yacreader_flow_gl.h +++ /dev/null @@ -1,372 +0,0 @@ -// OpenGL Coverflow API by J.Roth - Modernized with Shaders -#ifndef __YACREADER_FLOW_GL_H -#define __YACREADER_FLOW_GL_H - -#include - -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) -#include -#include -#else -#include -#include -#endif - -#include -#include -#include -#include -#include -#include - -#include "pictureflow.h" -#include "scroll_management.h" - -class ImageLoaderGL; -class ImageLoaderByteArrayGL; - -enum Performance { - low = 0, - medium, - high, - ultraHigh -}; - -// Cover Vector -struct YACReader3DVector { - float x; - float y; - float z; - float rot; -}; - -// the image/texture info struct -struct YACReader3DImage { - QOpenGLTexture *texture; - - float width; - float height; - - int index; - - YACReader3DVector current; - YACReader3DVector animEnd; -}; - -struct Preset { - /*** Animation Settings ***/ - // sets the speed of the animation - float animationStep; - // sets the acceleration of the animation - float animationSpeedUp; - // sets the maximum speed of the animation - float animationStepMax; - // sets the distance of view - float animationFadeOutDist; - // sets the rotation increasion - float preRotation; - // sets the light strenght on rotation - float viewRotateLightStrenght; - // sets the speed of the rotation - float viewRotateAdd; - // sets the speed of reversing the rotation - float viewRotateSub; - // sets the maximum view angle - float viewAngle; - - /*** Position Configuration ***/ - // the X Position of the Coverflow - float cfX; - // the Y Position of the Coverflow - float cfY; - // the Z Position of the Coverflow - float cfZ; - // the X Rotation of the Coverflow - float cfRX; - // the Y Rotation of the Coverflow - float cfRY; - // the Z Rotation of the Coverflow - float cfRZ; - // sets the rotation of each cover - float rotation; - // sets the distance between the covers - float xDistance; - // sets the distance between the centered and the non centered covers - float centerDistance; - // sets the pushback amount - float zDistance; - // sets the elevation amount - float yDistance; - - float zoom; -}; - -extern struct Preset defaultYACReaderFlowConfig; -extern struct Preset presetYACReaderFlowClassicConfig; -extern struct Preset presetYACReaderFlowStripeConfig; -extern struct Preset presetYACReaderFlowOverlappedStripeConfig; -extern struct Preset pressetYACReaderFlowUpConfig; -extern struct Preset pressetYACReaderFlowDownConfig; - -class YACReaderFlowGL : public QOpenGLWidget, protected QOpenGLExtraFunctions, public ScrollManagement -{ - Q_OBJECT -protected: - int timerId; - /*** System variables ***/ - YACReader3DImage dummy; - int viewRotateActive; - float stepBackup; - - /*functions*/ - void calcPos(YACReader3DImage &image, int pos); - void calcVector(YACReader3DVector &vector, int pos); - bool animate(YACReader3DVector ¤tVector, YACReader3DVector &toVector); - void drawCover(const YACReader3DImage &image); - void drawReflection(const YACReader3DImage &image); - void prepareInstanceData(const YACReader3DImage &image, bool isReflection, QVector &data); - void drawMark(const YACReader3DImage &image, const QMatrix4x4 &viewProjectionMatrix); - - void updatePerspective(int width, int height); - - int updateCount; - int fontSize; - - QOpenGLTexture *defaultTexture = nullptr; - QOpenGLTexture *markTexture = nullptr; - QOpenGLTexture *readingTexture = nullptr; - - // Shader program and buffers - QOpenGLShaderProgram *shaderProgram = nullptr; - QOpenGLBuffer *vbo = nullptr; - QOpenGLBuffer *instanceVBO = nullptr; - QOpenGLVertexArrayObject *vao = nullptr; - - void initializeGL(); - void paintGL(); - void timerEvent(QTimerEvent *); - void setupShaders(); - void setupGeometry(); - - int numObjects; - int lazyPopulateObjects; - bool showMarks; - QVector loaded; - QVector marks; - - QVector images; - - bool hasBeenInitialized; - - Performance performance; - bool bUseVSync; - - /*** Animation Settings ***/ - Preset config; - - int currentSelected; - - YACReader3DVector centerPos; - - /*** Style ***/ - float shadingTop; - float shadingBottom; - - float reflectionUp; - float reflectionBottom; - - /*** Theme Colors ***/ - QColor backgroundColor; - QColor textColor; - QColor shadingColor; - - /*** System info ***/ - float viewRotate; - - static int updateInterval; - - bool flowRightToLeft; - - void startAnimationTimer(); - void stopAnimationTimer(); - -public: - YACReaderFlowGL(QWidget *parent = 0, struct Preset p = pressetYACReaderFlowDownConfig); - virtual ~YACReaderFlowGL(); - - QSize minimumSizeHint() const; - - void showPrevious(); - void showNext(); - void setCurrentIndex(int pos); - void cleanupAnimation(); - void draw(); - void updatePositions(); - void insert(char *name, QOpenGLTexture *texture, float x, float y, int item = -1); - virtual void remove(int item); - void add(int item); - void replace(char *name, QOpenGLTexture *texture, float x, float y, int item); - void populate(int n); - YACReader3DImage getCurrentSelected(); - -public slots: - void setCF_RX(int value); - void setCF_RY(int value); - void setCF_RZ(int value); - void setZoom(int zoom); - void setRotation(int angle); - void setX_Distance(int distance); - void setCenter_Distance(int distance); - void setZ_Distance(int distance); - void setCF_Y(int value); - void setCF_Z(int value); - void setY_Distance(int value); - void setFadeOutDist(int value); - void setLightStrenght(int value); - void setMaxAngle(int value); - void setPreset(const Preset &p); - void setPerformance(Performance performance); - void useVSync(bool b); - void setFlowRightToLeft(bool b); - - // Theme color setters - void setBackgroundColor(const QColor &color); - void setTextColor(const QColor &color); - void setShadingColor(const QColor &color); - - virtual void updateImageData() = 0; - - void reset(); - void reload(); - - void setShowMarks(bool value); - void setMarks(QVector marks); - void setMarkImage(QImage &image); - void markSlide(int index, YACReader::YACReaderComicReadStatus status); - void unmarkSlide(int index); - void setSlideSize(QSize size); - void clear(); - void setCenterIndex(unsigned int index); - void showSlide(int index); - int centerIndex(); - void updateMarks(); - void render(); - - QVector3D getPlaneIntersection(int x, int y, YACReader3DImage plane); - void mouseDoubleClickEvent(QMouseEvent *event); - void mousePressEvent(QMouseEvent *event); - void wheelEvent(QWheelEvent *event); - void keyPressEvent(QKeyEvent *event); - void resizeGL(int width, int height); - - friend class ImageLoaderGL; - friend class ImageLoaderByteArrayGL; - -signals: - void centerIndexChanged(int); - void selected(unsigned int); -}; - -class YACReaderComicFlowGL : public YACReaderFlowGL -{ -public: - YACReaderComicFlowGL(QWidget *parent = 0, struct Preset p = defaultYACReaderFlowConfig); - void setImagePaths(QStringList paths); - void updateImageData(); - void remove(int item); - void add(const QString &path, int index); - void resortCovers(QList newOrder); - friend class ImageLoaderGL; - -private: - ImageLoaderGL *worker; - -protected: - QList paths; -}; - -class YACReaderPageFlowGL : public YACReaderFlowGL -{ -public: - YACReaderPageFlowGL(QWidget *parent = 0, struct Preset p = defaultYACReaderFlowConfig); - ~YACReaderPageFlowGL(); - void updateImageData(); - void populate(int n); - QVector imagesReady; - QVector rawImages; - QVector imagesSetted; - friend class ImageLoaderByteArrayGL; - -private: - ImageLoaderByteArrayGL *worker; -}; - -class ImageLoaderGL : public QThread -{ -public: - ImageLoaderGL(YACReaderFlowGL *flow); - ~ImageLoaderGL(); - bool busy() const; - void generate(int index, const QString &fileName); - void reset() - { - idx = -1; - fileName = ""; - } - int index() const { return idx; } - void lock(); - void unlock(); - QImage result(); - YACReaderFlowGL *flow; - GLuint resultTexture; - QImage loadImage(const QString &fileName); - -protected: - void run(); - -private: - QMutex mutex; - QWaitCondition condition; - - bool restart; - bool working; - int idx; - QString fileName; - QSize size; - QImage img; -}; - -class ImageLoaderByteArrayGL : public QThread -{ -public: - ImageLoaderByteArrayGL(YACReaderFlowGL *flow); - ~ImageLoaderByteArrayGL(); - bool busy() const; - void generate(int index, const QByteArray &raw); - void reset() - { - idx = -1; - rawData.clear(); - } - int index() const { return idx; } - QImage result(); - YACReaderFlowGL *flow; - GLuint resultTexture; - QImage loadImage(const QByteArray &rawData); - -protected: - void run(); - -private: - QMutex mutex; - QWaitCondition condition; - - bool restart; - bool working; - int idx; - QByteArray rawData; - QSize size; - QImage img; -}; - -#endif diff --git a/common/opengl_checker.cpp b/common/opengl_checker.cpp deleted file mode 100644 index a6d1840f..00000000 --- a/common/opengl_checker.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "opengl_checker.h" - -OpenGLChecker::OpenGLChecker() - : compatibleOpenGLVersion(true) -{ - QOpenGLContext *openGLContext = new QOpenGLContext(); - openGLContext->create(); - - if (!openGLContext->isValid()) { - compatibleOpenGLVersion = false; - description = "unable to create QOpenGLContext"; - } - - QSurfaceFormat format = openGLContext->format(); - - int majorVersion = format.majorVersion(); - int minorVersion = format.minorVersion(); - QString type; - - switch (format.renderableType()) { - case QSurfaceFormat::OpenGL: - type = "desktop"; - break; - - case QSurfaceFormat::OpenGLES: - type = "OpenGL ES"; - break; - - case QSurfaceFormat::OpenVG: - type = "OpenVG"; - break; - - default: - case QSurfaceFormat::DefaultRenderableType: - type = "unknown"; - break; - } - - delete openGLContext; - - description = QString("%1.%2 %3").arg(majorVersion).arg(minorVersion).arg(type); - - // Check for Desktop OpenGL OR OpenGL ES 3.0+ - bool isDesktopGL = (format.renderableType() == QSurfaceFormat::OpenGL); - bool isOpenGLES = (format.renderableType() == QSurfaceFormat::OpenGLES); - - if (isDesktopGL) { - // Desktop OpenGL requirements -#ifdef Q_OS_WIN - if (majorVersion < 1 || (majorVersion == 1 && minorVersion < 4)) - compatibleOpenGLVersion = false; -#else - if (majorVersion < 2) - compatibleOpenGLVersion = false; -#endif - } else if (isOpenGLES) { - // OpenGL ES requirements: 3.0 or higher - if (majorVersion < 3) - compatibleOpenGLVersion = false; - } else { - // Unknown or unsupported renderable type - compatibleOpenGLVersion = false; - } -} - -QString OpenGLChecker::textVersionDescription() -{ - return description; -} - -bool OpenGLChecker::hasCompatibleOpenGLVersion() -{ - return compatibleOpenGLVersion; -} diff --git a/common/opengl_checker.h b/common/opengl_checker.h deleted file mode 100644 index 0258ce79..00000000 --- a/common/opengl_checker.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef OPENGL_CHECKER_H -#define OPENGL_CHECKER_H - -#include - -class OpenGLChecker -{ -public: - OpenGLChecker(); - bool hasCompatibleOpenGLVersion(); - QString textVersionDescription(); - -private: - QString description; - bool compatibleOpenGLVersion; -}; - -#endif // OPENGL_CHECKER_H diff --git a/common/pictureflow.cpp b/common/pictureflow.cpp deleted file mode 100644 index 323db42f..00000000 --- a/common/pictureflow.cpp +++ /dev/null @@ -1,1410 +0,0 @@ -/* - PictureFlow - animated image show widget - http://pictureflow.googlecode.com - - Copyright (C) 2008 Ariya Hidayat (ariya@kde.org) - Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#include "pictureflow.h" - -#include - -// detect Qt version -#if QT_VERSION >= 0x040000 -#define PICTUREFLOW_QT4 -#elif QT_VERSION >= 0x030000 -#define PICTUREFLOW_QT3 -#elif QT_VERSION >= 235 -#define PICTUREFLOW_QT2 -#else -#error PictureFlow widgets need Qt 2, Qt 3 or Qt 4 -#endif - -#ifdef PICTUREFLOW_QT4 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif - -#ifdef PICTUREFLOW_QT3 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define qMax(x, y) ((x) > (y)) ? (x) : (y) -#define qMin(x, y) ((x) < (y)) ? (x) : (y) - -#define QVector QValueVector - -#define toImage convertToImage -#define contains find -#define modifiers state -#define ControlModifier ControlButton -#endif - -#ifdef PICTUREFLOW_QT2 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define qMax(x, y) ((x) > (y)) ? (x) : (y) -#define qMin(x, y) ((x) < (y)) ? (x) : (y) - -#define QVector QArray - -#define toImage convertToImage -#define contains find -#define modifiers state -#define ControlModifier ControlButton -#define flush flushX -#endif - -// for fixed-point arithmetic, we need minimum 32-bit long -// long long (64-bit) might be useful for multiplication and division -typedef long PFreal; -#define PFREAL_SHIFT 10 -#define PFREAL_ONE (1 << PFREAL_SHIFT) - -#define IANGLE_MAX 1024 -#define IANGLE_MASK 1023 - -inline PFreal fmul(PFreal a, PFreal b) -{ - return ((long long)(a)) * ((long long)(b)) >> PFREAL_SHIFT; -} - -inline PFreal fdiv(PFreal num, PFreal den) -{ - long long p = (long long)(num) << (PFREAL_SHIFT * 2); - long long q = p / (long long)den; - long long r = q >> PFREAL_SHIFT; - - return r; -} - -inline PFreal fsin(int iangle) -{ - // warning: regenerate the table if IANGLE_MAX and PFREAL_SHIFT are changed! - static const PFreal tab[] = { - 3, 103, 202, 300, 394, 485, 571, 652, - 726, 793, 853, 904, 947, 980, 1004, 1019, - 1023, 1018, 1003, 978, 944, 901, 849, 789, - 721, 647, 566, 479, 388, 294, 196, 97, - -4, -104, -203, -301, -395, -486, -572, -653, - -727, -794, -854, -905, -948, -981, -1005, -1020, - -1024, -1019, -1004, -979, -945, -902, -850, -790, - -722, -648, -567, -480, -389, -295, -197, -98, - 3 - }; - - while (iangle < 0) - iangle += IANGLE_MAX; - iangle &= IANGLE_MASK; - - int i = (iangle >> 4); - PFreal p = tab[i]; - PFreal q = tab[(i + 1)]; - PFreal g = (q - p); - return p + g * (iangle - i * 16) / 16; -} - -inline PFreal fcos(int iangle) -{ - return fsin(iangle + (IANGLE_MAX >> 2)); -} - -/* ---------------------------------------------------------- - -PictureFlowState stores the state of all slides, i.e. all the necessary -information to be able to render them. - -PictureFlowAnimator is responsible to move the slides during the -transition between slides, to achieve the effect similar to Cover Flow, -by changing the state. - -PictureFlowSoftwareRenderer (or PictureFlowOpenGLRenderer) is -the actual 3-d renderer. It should render all slides given the state -(an instance of PictureFlowState). - -Instances of all the above three classes are stored in -PictureFlowPrivate. - -------------------------------------------------------- */ - -struct SlideInfo { - int slideIndex; - int angle; - PFreal cx; - PFreal cy; - int blend; -}; - -class PictureFlowState -{ -public: - PictureFlowState(int angle = 50, float spacingRatio = 0); - ~PictureFlowState(); - - void reposition(); - void reset(); - - QRgb backgroundColor; - int slideWidth; - int slideHeight; - PictureFlow::ReflectionEffect reflectionEffect; - QVector slideImages; - - QVector marks; - bool showMarks; - QImage mark; - - int angle; - int rawAngle; - int spacing; - float spacingRatio; - PFreal offsetX; - PFreal offsetY; - - SlideInfo centerSlide; - QVector leftSlides; - QVector rightSlides; - int centerIndex; - - bool flowRightToLeft; -}; - -class PictureFlowAnimator -{ -public: - PictureFlowAnimator(); - PictureFlowState *state; - - void start(int slide); - void stop(int slide); - void update(); - - int target; - int step; - int frame; - QTimer animateTimer; - bool animating; -}; - -class PictureFlowAbstractRenderer -{ -public: - PictureFlowAbstractRenderer() - : state(0), dirty(false), widget(0) { } - virtual ~PictureFlowAbstractRenderer() { } - - PictureFlowState *state; - bool dirty; - QWidget *widget; - - virtual void init() = 0; - virtual void paint() = 0; -}; - -class PictureFlowSoftwareRenderer : public PictureFlowAbstractRenderer -{ -public: - PictureFlowSoftwareRenderer(); - ~PictureFlowSoftwareRenderer(); - - virtual void init(); - virtual void paint(); - void render(); - -private: - QSize size; - QRgb bgcolor; - int effect; - QImage buffer; - QVector rays; - QImage *blankSurface; -#ifdef PICTUREFLOW_QT4 - QCache surfaceCache; - QHash imageHash; -#endif -#ifdef PICTUREFLOW_QT3 - QCache surfaceCache; - QMap imageHash; -#endif -#ifdef PICTUREFLOW_QT2 - QCache surfaceCache; - QIntDict imageHash; -#endif - - void renderSlides(); - QRect renderSlide(const SlideInfo &slide, int col1 = -1, int col2 = -1); - QImage *surface(int slideIndex); -}; - -// ------------- PictureFlowState --------------------------------------- - -PictureFlowState::PictureFlowState(int a, float sr) - : backgroundColor(0), slideWidth(150), slideHeight(200), reflectionEffect(PictureFlow::BlurredReflection), rawAngle(a), spacingRatio(sr), centerIndex(0), flowRightToLeft(false) -{ -} - -PictureFlowState::~PictureFlowState() -{ - for (int i = 0; i < (int)slideImages.count(); i++) - delete slideImages[i]; -} - -// readjust the settings, call this when slide dimension is changed -void PictureFlowState::reposition() -{ - // angle = 70 * IANGLE_MAX / 360; // approx. 70 degrees tilted - angle = rawAngle * IANGLE_MAX / 360; - offsetX = slideWidth / 2 * (PFREAL_ONE - fcos(angle)); - offsetY = slideWidth / 2 * fsin(angle); - offsetX += slideWidth * PFREAL_ONE; - offsetY += slideWidth * PFREAL_ONE / 3; - if (rawAngle < 45) - offsetX += offsetX / 4; - if (angle > 0) - spacing = slideWidth * 0.35; - else - spacing = slideWidth * spacingRatio + slideWidth * (spacingRatio ? 0.10 : 0.2); -} - -// adjust slides so that they are in "steady state" position -void PictureFlowState::reset() -{ - centerSlide.angle = 0; - centerSlide.cx = 0; - centerSlide.cy = 0; - centerSlide.slideIndex = centerIndex; - centerSlide.blend = 256; - - if (angle == 0 && spacingRatio) - leftSlides.resize(4); - else - leftSlides.resize(6); - for (int i = 0; i < (int)leftSlides.count(); i++) { - SlideInfo &si = leftSlides[i]; - si.angle = angle; - si.cx = -(offsetX + spacing * (i)*PFREAL_ONE); - si.cy = offsetY; - if (!flowRightToLeft) - si.slideIndex = centerIndex - 1 - i; - else - si.slideIndex = centerIndex + 1 + i; - si.blend = 200; - if (i == (int)leftSlides.count() - 2) - si.blend = 128; - if (i == (int)leftSlides.count() - 1) - si.blend = 0; - } - if (angle == 0 && spacingRatio) - rightSlides.resize(4); - else - rightSlides.resize(6); - for (int i = 0; i < (int)rightSlides.count(); i++) { - SlideInfo &si = rightSlides[i]; - si.angle = -angle; - si.cx = offsetX + spacing * (i)*PFREAL_ONE; - si.cy = offsetY; - if (!flowRightToLeft) - si.slideIndex = centerIndex + 1 + i; - else - si.slideIndex = centerIndex - 1 - i; - si.blend = 200; - if (i == (int)rightSlides.count() - 2) - si.blend = 128; - if (i == (int)rightSlides.count() - 1) - si.blend = 0; - } -} - -// ------------- PictureFlowAnimator --------------------------------------- - -PictureFlowAnimator::PictureFlowAnimator() - : state(0), target(0), step(0), frame(0), animating(false) -{ -} - -void PictureFlowAnimator::start(int slide) -{ - target = slide; - if (!animateTimer.isActive() && state) { - step = (target < state->centerSlide.slideIndex) ? -1 : 1; - animateTimer.setSingleShot(true); - animateTimer.start(30); // TODO comprobar rendimiento, originalmente era 30 - animating = true; - } -} - -void PictureFlowAnimator::stop(int slide) -{ - step = 0; - target = slide; - frame = slide << 16; - animateTimer.stop(); - animating = false; -} - -void PictureFlowAnimator::update() -{ - /*if(!animateTimer.isActive()) - return;*/ - if (step == 0) - return; - if (!state) - return; - - int speed = 16384 / 4; // TODO comprobar rendimiento, originalmente era /4 - -#if 1 - // deaccelerate when approaching the target - const int max = 2 * 65536; // TODO cambiado de 2 * a 4 * comprobar rendimiento - - int fi = frame; - fi -= (target << 16); - if (fi < 0) - fi = -fi; - fi = qMin(fi, max); - - int ia = IANGLE_MAX * (fi - max / 2) / (max * 2); - speed = 512 + 16384 * (PFREAL_ONE + fsin(ia)) / PFREAL_ONE; -#endif - - frame += speed * step; - - int index = frame >> 16; - int pos = frame & 0xffff; - int neg = 65536 - pos; - int tick = (step < 0) ? neg : pos; - PFreal ftick = (tick * PFREAL_ONE) >> 16; - - if (step < 0) - index++; - - if (state->centerIndex != index) { - state->centerIndex = index; - frame = index << 16; - state->centerSlide.slideIndex = state->centerIndex; - for (int i = 0; i < (int)state->leftSlides.count(); i++) { - if (!state->flowRightToLeft) - state->leftSlides[i].slideIndex = state->centerIndex - 1 - i; - else - state->leftSlides[i].slideIndex = state->centerIndex + 1 + i; - } - for (int i = 0; i < (int)state->rightSlides.count(); i++) { - if (!state->flowRightToLeft) - state->rightSlides[i].slideIndex = state->centerIndex + 1 + i; - else - state->rightSlides[i].slideIndex = state->centerIndex - 1 - i; - } - } - - if (!state->flowRightToLeft) { - state->centerSlide.angle = (step * tick * state->angle) >> 16; - state->centerSlide.cx = -step * fmul(state->offsetX, ftick); - } else { - state->centerSlide.angle = (-step * tick * state->angle) >> 16; - state->centerSlide.cx = step * fmul(state->offsetX, ftick); - } - state->centerSlide.cy = fmul(state->offsetY, ftick); - - if (state->centerIndex == target) { - stop(target); - state->reset(); - return; - } - - for (int i = 0; i < (int)state->leftSlides.count(); i++) { - SlideInfo &si = state->leftSlides[i]; - si.angle = state->angle; - if (!state->flowRightToLeft) - si.cx = -(state->offsetX + state->spacing * (i)*PFREAL_ONE + step * state->spacing * ftick); - else - si.cx = -(state->offsetX + state->spacing * (i)*PFREAL_ONE - step * state->spacing * ftick); - si.cy = state->offsetY; - } - - for (int i = 0; i < (int)state->rightSlides.count(); i++) { - SlideInfo &si = state->rightSlides[i]; - si.angle = -state->angle; - if (!state->flowRightToLeft) - si.cx = state->offsetX + state->spacing * (i)*PFREAL_ONE - step * state->spacing * ftick; - else - si.cx = state->offsetX + state->spacing * (i)*PFREAL_ONE + step * state->spacing * ftick; - si.cy = state->offsetY; - } - - if (step > 0 && !state->flowRightToLeft) { - PFreal ftick = (neg * PFREAL_ONE) >> 16; - state->rightSlides[0].angle = -(neg * state->angle) >> 16; - state->rightSlides[0].cx = fmul(state->offsetX, ftick); - state->rightSlides[0].cy = fmul(state->offsetY, ftick); - } else if (!state->flowRightToLeft) { - PFreal ftick = (pos * PFREAL_ONE) >> 16; - state->leftSlides[0].angle = (pos * state->angle) >> 16; - state->leftSlides[0].cx = -fmul(state->offsetX, ftick); - state->leftSlides[0].cy = fmul(state->offsetY, ftick); - } else if (step < 0) { - PFreal ftick = (pos * PFREAL_ONE) >> 16; - state->rightSlides[0].angle = -(pos * state->angle) >> 16; - state->rightSlides[0].cx = fmul(state->offsetX, ftick); - state->rightSlides[0].cy = fmul(state->offsetY, ftick); - } else { - PFreal ftick = (neg * PFREAL_ONE) >> 16; - state->leftSlides[0].angle = (neg * state->angle) >> 16; - state->leftSlides[0].cx = -fmul(state->offsetX, ftick); - state->leftSlides[0].cy = fmul(state->offsetY, ftick); - } - - // must change direction ? - if (target < index) - if (step > 0) - step = -1; - if (target > index) - if (step < 0) - step = 1; - - // the first and last slide must fade in/fade out - int nleft = state->leftSlides.count(); - int nright = state->rightSlides.count(); - int fade = pos / 256; - - for (int index = 0; index < nleft; index++) { - int blend = 200; - if (index == nleft - 1) - blend = (step > 0) ? 0 : 128 - fade / 2; - if (index == nleft - 2) - blend = (step > 0) ? 128 - fade / 2 : 200 - (0.5625 * fade / 2); - if (index == nleft - 3) - blend = (step > 0) ? 200 - (0.5625 * fade / 2) : 200; - if (index == 0) - blend = (step > 0) ? 200 : 200 + 56 - (0.4375 * fade / 2); - state->leftSlides[index].blend = blend; - } - for (int index = 0; index < nright; index++) { - int blend = (index < nright - 2) ? 200 : 128; - if (index == nright - 1) - blend = (step > 0) ? fade / 2 : 0; - if (index == nright - 2) - blend = (step > 0) ? 128 + (0.5625 * fade / 2) : (0.5625 * fade / 2); - if (index == nright - 3) - blend = (step > 0) ? 200 : 128 + (0.5625 * fade / 2); - if (index == 0) - blend = (step > 0) ? 200 + (0.4375 * fade / 2) : 200; - state->rightSlides[index].blend = blend; - } - - state->centerSlide.blend = (step > 0) ? 256 - (0.4375 * fade / 2) : 200 + (0.4375 * fade / 2); -} - -// ------------- PictureFlowSoftwareRenderer --------------------------------------- - -PictureFlowSoftwareRenderer::PictureFlowSoftwareRenderer() - : PictureFlowAbstractRenderer(), size(0, 0), bgcolor(0), effect(-1), blankSurface(0) -{ -#ifdef PICTUREFLOW_QT3 - surfaceCache.setAutoDelete(true); -#endif -} - -PictureFlowSoftwareRenderer::~PictureFlowSoftwareRenderer() -{ - surfaceCache.clear(); - buffer = QImage(); - delete blankSurface; -} - -void PictureFlowSoftwareRenderer::paint() -{ - if (!widget) - return; - - if (widget->size() != size) - init(); - - if (state->backgroundColor != bgcolor) { - bgcolor = state->backgroundColor; - surfaceCache.clear(); - } - - if ((int)(state->reflectionEffect) != effect) { - effect = (int)state->reflectionEffect; - surfaceCache.clear(); - } - - if (dirty) - render(); - - QPainter painter(widget); - painter.drawImage(QPoint(0, 0), buffer); -} - -void PictureFlowSoftwareRenderer::init() -{ - if (!widget) - return; - - surfaceCache.clear(); - blankSurface = 0; - - size = widget->size(); - int ww = size.width(); - int wh = size.height(); - int w = (ww + 1) / 2; - int h = (wh + 1) / 2; - if (h < 10) // TODO a partir de qué h es seguro?? - return; - -#ifdef PICTUREFLOW_QT4 - buffer = QImage(ww, wh, QImage::Format_RGB32); -#endif -#if defined(PICTUREFLOW_QT3) || defined(PICTUREFLOW_QT2) - buffer.create(ww, wh, 32); -#endif - buffer.fill(bgcolor); - - rays.resize(w * 2); - for (int i = 0; i < w; i++) { - PFreal gg = ((PFREAL_ONE >> 1) + i * PFREAL_ONE) / (2 * h); - rays[w - i - 1] = -gg; - rays[w + i] = gg; - } - - dirty = true; -} - -// TODO: optimize this with lookup tables -static QRgb blendColor(QRgb c1, QRgb c2, int blend) -{ - int r = qRed(c1) * blend / 256 + qRed(c2) * (256 - blend) / 256; - int g = qGreen(c1) * blend / 256 + qGreen(c2) * (256 - blend) / 256; - int b = qBlue(c1) * blend / 256 + qBlue(c2) * (256 - blend) / 256; - return qRgb(r, g, b); -} - -static QImage *prepareSurface(const QImage *slideImage, int w, int h, QRgb bgcolor, - PictureFlow::ReflectionEffect reflectionEffect) -{ - - int iw, ih; - iw = slideImage->width(); - ih = slideImage->height(); - int psw, psh; - if (iw > ih) { - psw = w; - psh = w * (1.0 * ih / iw); - } else { - int h1 = h; - psw = h1 * (1.0 * iw / ih); - psh = h1; - - while (psw > w) { - h1 -= 2; - psw = h1 * (1.0 * iw / ih); - psh = h1; - } - } - w = psw; - -#ifdef PICTUREFLOW_QT4 - Qt::TransformationMode mode = Qt::SmoothTransformation; - QImage img = slideImage->scaled(psw, psh, Qt::IgnoreAspectRatio, mode); -#endif -#if defined(PICTUREFLOW_QT3) || defined(PICTUREFLOW_QT2) - QImage img = slideImage->smoothScale(w, h); -#endif - - // slightly larger, to accomodate for the reflection - int hs = h * 2; - int hofs = h / 3; - - // offscreen buffer: black is sweet -#ifdef PICTUREFLOW_QT4 - QImage *result = new QImage(hs, w, QImage::Format_RGB32); -#endif -#if defined(PICTUREFLOW_QT3) || defined(PICTUREFLOW_QT2) - QImage *result = new QImage; - result->create(hs, w, 32); -#endif - result->fill(bgcolor); - - // transpose the image, this is to speed-up the rendering - // because we process one column at a time - // (and much better and faster to work row-wise, i.e in one scanline) - int lhof = (h - psh); - // int lwof = (w-psw)/2; - for (int x = 0; x < psw; x++) - for (int y = 0; y < psh; y++) - - result->setPixel(hofs + y + lhof, x, img.pixel(x, y)); - - if (reflectionEffect != PictureFlow::NoReflection) { - // create the reflection - int ht = hs - (h + hofs); - int hte = ht; - for (int x = 0; x < psw; x++) - for (int y = 0; y < ht; y++) { - QRgb color; - if (y < psh) - color = img.pixel(x, psh - y - 1); - else - color = bgcolor; - result->setPixel(h + hofs + y, x, blendColor(color, bgcolor, 80 * (hte - y) / hte)); - } - } - - return result; -} - -QImage *PictureFlowSoftwareRenderer::surface(int slideIndex) -{ - if (!state) - return 0; - if (slideIndex < 0) - return 0; - if (slideIndex >= (int)state->slideImages.count()) - return 0; - -#ifdef PICTUREFLOW_QT4 - int key = slideIndex; -#endif -#if defined(PICTUREFLOW_QT3) || defined(PICTUREFLOW_QT2) - QString key = QString::number(slideIndex); -#endif - - QImage *img = state->slideImages.at(slideIndex); - - bool empty = img ? img->isNull() : true; - if (empty) { - surfaceCache.remove(key); - imageHash.remove(slideIndex); - if (!blankSurface) { - int sw = state->slideWidth; - int sh = state->slideHeight; - -#ifdef PICTUREFLOW_QT4 - QImage img = QImage(sw, sh, QImage::Format_RGB32); - - QPainter painter(&img); - QPoint p1(sw * 4 / 10, 0); - QPoint p2(sw * 6 / 10, sh); - QLinearGradient linearGrad(p1, p2); - linearGrad.setColorAt(0, Qt::black); - linearGrad.setColorAt(1, Qt::white); - painter.setBrush(linearGrad); - painter.fillRect(0, 0, sw, sh, QBrush(linearGrad)); - - painter.end(); -#endif -#if defined(PICTUREFLOW_QT3) || defined(PICTUREFLOW_QT2) - QPixmap pixmap(sw, sh, 32); - QPainter painter(&pixmap); - painter.fillRect(pixmap.rect(), QColor(192, 192, 192)); - painter.fillRect(5, 5, sw - 10, sh - 10, QColor(64, 64, 64)); - painter.end(); - QImage img = pixmap.convertToImage(); -#endif - - blankSurface = prepareSurface(&img, sw, sh, bgcolor, state->reflectionEffect); - } - return blankSurface; - } - -#ifdef PICTUREFLOW_QT4 - bool exist = imageHash.contains(slideIndex); - if (exist) - if (img == imageHash.find(slideIndex).value()) -#endif -#ifdef PICTUREFLOW_QT3 - bool exist = imageHash.find(slideIndex) != imageHash.end(); - if (exist) - if (img == imageHash.find(slideIndex).data()) -#endif -#ifdef PICTUREFLOW_QT2 - if (img == imageHash[slideIndex]) -#endif - if (surfaceCache.contains(key)) - return surfaceCache[key]; - - QImage *sr = prepareSurface(img, state->slideWidth, state->slideHeight, bgcolor, state->reflectionEffect); - // check if this slide must be marked - // if(marks[slideIndex]) - if (state->showMarks) { - if (state->marks[slideIndex]) { - QPainter painter(sr); - painter.setPen(QColor(255, 0, 0).rgb()); - int sh = sr->height(); - int jInit = sh * 4 / 5; - int iInit = state->slideHeight + state->slideHeight / 3; - /*for(int j = jInit; j < sh; j ++) - { - for(int i = iInit-(j-jInit); i < iInit; i ++) - { - - painter.drawPoint(i,j); - } - }*/ - painter.drawImage(QRect(iInit - (sh - jInit), jInit, sh - jInit, sh - jInit), state->mark); - } - } - surfaceCache.insert(key, sr); - imageHash.insert(slideIndex, img); - - return sr; -} - -// Renders a slide to offscreen buffer. Returns a rect of the rendered area. -// col1 and col2 limit the column for rendering. -QRect PictureFlowSoftwareRenderer::renderSlide(const SlideInfo &slide, int col1, int col2) -{ - int blend = slide.blend; - if (!blend) - return QRect(); - - QImage *src = surface(slide.slideIndex); - if (!src) - return QRect(); - - QRect rect(0, 0, 0, 0); - - int sw = src->height(); - int sh = src->width(); - int h = buffer.height(); - int w = buffer.width(); - - if (col1 > col2) { - int c = col2; - col2 = col1; - col1 = c; - } - - col1 = (col1 >= 0) ? col1 : 0; - col2 = (col2 >= 0) ? col2 : w - 1; - col1 = qMin(col1, w - 1); - col2 = qMin(col2, w - 1); - - int zoom = 100; - int distance = h * 100 / zoom; - PFreal sdx = fcos(slide.angle); - PFreal sdy = fsin(slide.angle); - PFreal xs = slide.cx - state->slideWidth * sdx / 2; - PFreal ys = slide.cy - state->slideWidth * sdy / 2; - PFreal dist = distance * PFREAL_ONE; - - int xi = qMax((PFreal)0, ((w * PFREAL_ONE / 2) + fdiv(xs * h, dist + ys)) >> PFREAL_SHIFT); - if (xi >= w) - return rect; - - bool flag = false; - rect.setLeft(xi); - for (int x = qMax(xi, col1); x <= col2; x++) { - PFreal hity = 0; - PFreal fk = rays[x]; - if (sdy) { - fk = fk - fdiv(sdx, sdy); - hity = -fdiv((rays[x] * distance - slide.cx + slide.cy * sdx / sdy), fk); - } - - dist = distance * PFREAL_ONE + hity; - if (dist < 0) - continue; - - PFreal hitx = fmul(dist, rays[x]); - PFreal hitdist = fdiv(hitx - slide.cx, sdx); - - int column = sw / 2 + (hitdist >> PFREAL_SHIFT); - if (column >= sw) - break; - if (column < 0) - continue; - - rect.setRight(x); - if (!flag) - rect.setLeft(x); - flag = true; - - int y1 = h / 2; - int y2 = y1 + 1; - QRgb *pixel1 = (QRgb *)(buffer.scanLine(y1)) + x; - QRgb *pixel2 = (QRgb *)(buffer.scanLine(y2)) + x; - QRgb pixelstep = pixel2 - pixel1; - - int center = (sh / 2); - int dy = dist / h; - int p1 = center * PFREAL_ONE - dy / 2; - int p2 = center * PFREAL_ONE + dy / 2; - - const QRgb *ptr = (const QRgb *)(src->scanLine(column)); - if (blend == 256) - while ((y1 >= 0) && (y2 < h) && (p1 >= 0)) { - *pixel1 = ptr[p1 >> PFREAL_SHIFT]; - *pixel2 = ptr[p2 >> PFREAL_SHIFT]; - p1 -= dy; - p2 += dy; - y1--; - y2++; - pixel1 -= pixelstep; - pixel2 += pixelstep; - } - else - while ((y1 >= 0) && (y2 < h) && (p1 >= 0)) { - QRgb c1 = ptr[p1 >> PFREAL_SHIFT]; - QRgb c2 = ptr[p2 >> PFREAL_SHIFT]; - *pixel1 = blendColor(c1, bgcolor, blend); - *pixel2 = blendColor(c2, bgcolor, blend); - p1 -= dy; - p2 += dy; - y1--; - y2++; - pixel1 -= pixelstep; - pixel2 += pixelstep; - } - } - - rect.setTop(0); - rect.setBottom(h - 1); - return rect; -} - -void PictureFlowSoftwareRenderer::renderSlides() -{ - int nleft = state->leftSlides.count(); - int nright = state->rightSlides.count(); - - QRect r = renderSlide(state->centerSlide); - int c1 = r.left(); - int c2 = r.right(); - - for (int index = 0; index < nleft; index++) { - QRect rs = renderSlide(state->leftSlides[index], 0, c1 - 1); - if (!rs.isEmpty()) - c1 = rs.left(); - } - for (int index = 0; index < nright; index++) { - QRect rs = renderSlide(state->rightSlides[index], c2 + 1, buffer.width()); - if (!rs.isEmpty()) - c2 = rs.right(); - } -} - -// Render the slides. Updates only the offscreen buffer. -void PictureFlowSoftwareRenderer::render() -{ - buffer.fill(state->backgroundColor); - renderSlides(); - if (state->slideImages.size() > 0) { - int size = buffer.width() * 0.015; - int start = buffer.width() * 0.010; - - QPainter painter(&buffer); - painter.setPen(QColor(255, 255, 255).rgb() - state->backgroundColor); - painter.setFont(QFont("Arial", start + size * 0.5)); - painter.drawText(start, start + size, QString().setNum(state->centerIndex + 1) + "/" + QString().setNum(state->slideImages.size())); - } - dirty = false; -} - -// ----------------------------------------- - -class PictureFlowPrivate -{ -public: - PictureFlowState *state; - PictureFlowAnimator *animator; - PictureFlowAbstractRenderer *renderer; - QTimer triggerTimer; -}; - -PictureFlow::PictureFlow(QWidget *parent, FlowType flowType) - : QWidget(parent) -{ - d = new PictureFlowPrivate; - - switch (flowType) { - case CoverFlowLike: - d->state = new PictureFlowState(50, 0); - break; - case Strip: - d->state = new PictureFlowState(0, 1); - break; - case StripOverlapped: - d->state = new PictureFlowState(0, 0); - break; - default: - break; - } - - framesSkip = 0; - - d->state->reset(); - d->state->reposition(); - - d->renderer = new PictureFlowSoftwareRenderer; - d->renderer->state = d->state; - d->renderer->widget = this; - d->renderer->init(); - - d->animator = new PictureFlowAnimator; - d->animator->state = d->state; - QObject::connect(&d->animator->animateTimer, &QTimer::timeout, this, &PictureFlow::updateAnimation); - - QObject::connect(&d->triggerTimer, &QTimer::timeout, this, QOverload<>::of(&PictureFlow::render)); - -#ifdef PICTUREFLOW_QT4 - setAttribute(Qt::WA_StaticContents, true); - setAttribute(Qt::WA_OpaquePaintEvent, true); - setAttribute(Qt::WA_NoSystemBackground, true); -#endif -#ifdef PICTUREFLOW_QT3 - setWFlags(getWFlags() | Qt::WStaticContents); - setWFlags(getWFlags() | Qt::WNoAutoErase); -#endif -#ifdef PICTUREFLOW_QT2 - setWFlags(getWFlags() | Qt::WPaintClever); - setWFlags(getWFlags() | Qt::WRepaintNoErase); - setWFlags(getWFlags() | Qt::WResizeNoErase); -#endif -} - -PictureFlow::~PictureFlow() -{ - delete d->renderer; - delete d->animator; - delete d->state; - delete d; -} - -int PictureFlow::slideCount() const -{ - return d->state->slideImages.count(); -} - -QColor PictureFlow::backgroundColor() const -{ - return QColor(d->state->backgroundColor); -} - -void PictureFlow::setBackgroundColor(const QColor &c) -{ - d->state->backgroundColor = c.rgb(); - triggerRender(); -} - -QSize PictureFlow::slideSize() const -{ - return QSize(d->state->slideWidth, d->state->slideHeight); -} - -void PictureFlow::setSlideSize(QSize size) -{ - d->state->slideWidth = size.width(); - d->state->slideHeight = size.height(); - d->state->reposition(); - triggerRender(); -} - -PictureFlow::ReflectionEffect PictureFlow::reflectionEffect() const -{ - return d->state->reflectionEffect; -} - -void PictureFlow::setReflectionEffect(ReflectionEffect effect) -{ - d->state->reflectionEffect = effect; - triggerRender(); -} - -void PictureFlow::setFlowRightToLeft(bool b) -{ - d->state->flowRightToLeft = b; - d->state->reset(); - triggerRender(); -} - -QImage PictureFlow::slide(int index) const -{ - QImage *i = 0; - if ((index >= 0) && (index < slideCount())) - i = d->state->slideImages[index]; - return i ? QImage(*i) : QImage(); -} - -void PictureFlow::addSlide(const QImage &image) -{ - int c = d->state->slideImages.count(); - d->state->slideImages.resize(c + 1); - d->state->slideImages[c] = new QImage(image); - d->state->marks.resize(c + 1); - d->state->marks[c] = YACReader::Unread; - triggerRender(); -} - -void PictureFlow::addSlide(const QPixmap &pixmap) -{ - addSlide(pixmap.toImage()); -} - -void PictureFlow::insertSlide(int index) -{ - d->state->slideImages.insert(index, new QImage()); - d->state->marks.insert(index, YACReader::Unread); - triggerRender(); -} - -void PictureFlow::removeSlide(int index) -{ - int c = d->state->slideImages.count(); - if (index >= 0 && index < c) { - d->state->slideImages.remove(index); - d->state->marks.remove(index); - setCenterIndex(index); - } -} - -void PictureFlow::setSlide(int index, const QImage &image) -{ - if ((index >= 0) && (index < slideCount())) { - QImage *i = image.isNull() ? 0 : new QImage(image); - delete d->state->slideImages[index]; - d->state->slideImages[index] = i; - triggerRender(); - } -} - -void PictureFlow::setSlide(int index, const QPixmap &pixmap) -{ - setSlide(index, pixmap.toImage()); -} - -int PictureFlow::centerIndex() const -{ - return d->state->centerIndex; -} - -void PictureFlow::setCenterIndex(int index) -{ - index = qMin(index, slideCount() - 1); - index = qMax(index, 0); - d->state->centerIndex = index; - d->state->reset(); - d->animator->stop(index); - triggerRender(); -} - -void PictureFlow::clear() -{ - int c = d->state->slideImages.count(); - for (int i = 0; i < c; i++) - delete d->state->slideImages[i]; - d->state->slideImages.resize(0); - - d->state->marks.resize(0); - - d->state->reset(); - triggerRender(); -} - -void PictureFlow::render() -{ - d->renderer->dirty = true; - update(); -} - -void PictureFlow::triggerRender() -{ -#ifdef PICTUREFLOW_QT4 - d->triggerTimer.setSingleShot(true); - d->triggerTimer.start(0); -#endif -#if defined(PICTUREFLOW_QT3) || defined(PICTUREFLOW_QT2) - d->triggerTimer.start(0, true); -#endif -} - -void PictureFlow::showPrevious() -{ - int step = d->animator->step; - int center = d->state->centerIndex; - - if (step > 0) { - d->animator->start(center); - emit centerIndexChanged(center); - } - - if (step == 0) - if (center > 0) { - d->animator->start(center - 1); - emit centerIndexChanged(center - 1); - } - - if (step < 0) { - d->animator->target = qMax(0, center - 2); - emit centerIndexChanged(qMax(0, center - 2)); - } -} - -void PictureFlow::showNext() -{ - int step = d->animator->step; - int center = d->state->centerIndex; - - if (step < 0) { - d->animator->start(center); - emit centerIndexChanged(center); - } - - if (step == 0) - if (center < slideCount() - 1) { - d->animator->start(center + 1); - emit centerIndexChanged(center + 1); - } - - if (step > 0) { - d->animator->target = qMin(center + 2, slideCount() - 1); - emit centerIndexChanged(qMin(center + 2, slideCount() - 1)); - } -} - -void PictureFlow::showSlide(unsigned int index) -{ - index = qMax(index, 0); - index = qMin(slideCount() - 1, index); - if ((int)index == d->state->centerSlide.slideIndex) { - return; - } - - int distance = centerIndex() - index; - - if (abs(distance) > 10) { - if (distance < 0) - setCenterIndex(centerIndex() + (-distance) - 10); - else - setCenterIndex(centerIndex() - distance + 10); - } - - d->state->centerIndex = index; - d->animator->start(index); -} - -void PictureFlow::keyPressEvent(QKeyEvent *event) -{ - if ((event->key() == Qt::Key_Left && !(d->state->flowRightToLeft)) || (event->key() == Qt::Key_Right && d->state->flowRightToLeft)) { - /*if(event->modifiers() == Qt::ControlModifier) - showSlide(centerIndex()-10); - else*/ - showPrevious(); - event->accept(); - return; - } - - if ((event->key() == Qt::Key_Right && !(d->state->flowRightToLeft)) || (event->key() == Qt::Key_Left && d->state->flowRightToLeft)) { - /*if(event->modifiers() == Qt::ControlModifier) - showSlide(centerIndex()+10); - else*/ - showNext(); - event->accept(); - return; - } - - if (event->key() == Qt::Key_Up) { - // TODO emit selected signal - return; - } - - event->ignore(); -} - -void PictureFlow::mousePressEvent(QMouseEvent *event) -{ - mousePressEvent(event, 0); -} - -void PictureFlow::mousePressEvent(QMouseEvent *event, int slideWidth) -{ - if ((event->x() > (width() + slideWidth) / 2 && !(d->state->flowRightToLeft)) || (event->x() < (width() - slideWidth) / 2 && d->state->flowRightToLeft)) - showNext(); - else if ((event->x() < (width() - slideWidth) / 2 && !(d->state->flowRightToLeft)) || (event->x() > (width() + slideWidth) / 2 && d->state->flowRightToLeft)) - showPrevious(); - - // else (centered slide space) -} - -void PictureFlow::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - d->renderer->paint(); -} - -void PictureFlow::resizeEvent(QResizeEvent *event) -{ - int heightWidget = event->size().height(); - int height, width; - height = heightWidget * 0.55; - width = height * 0.65; - setSlideSize(QSize(width, height)); - - render(); - d->animator->start(centerIndex()); - QWidget::resizeEvent(event); -} -#include -void PictureFlow::updateAnimation() // bucle principal -{ - QElapsedTimer timer; - timer.start(); - bool frameSkiped = false; - - int old_center = d->state->centerIndex; - d->animator->update(); - if (framesSkip == 0) - render(); // triggerRender(); - else { - framesSkip--; - frameSkiped = true; - } - - if (d->state->centerIndex != old_center) - emit centerIndexChangedSilent(d->state->centerIndex); - if (d->animator->animating == true) { - int difference = 10 - timer.elapsed(); - if (difference >= 0 && !frameSkiped) - QTimer::singleShot(difference, this, &PictureFlow::updateAnimation); - else { - QTimer::singleShot(0, this, &PictureFlow::updateAnimation); - if (!frameSkiped) - framesSkip = -((difference - 10) / 10); - } - } -} - -void PictureFlow::setFlowType(FlowType flowType) -{ - switch (flowType) { - case CoverFlowLike: - d->state->rawAngle = 50; - d->state->spacingRatio = 0, - d->state->reposition(); - break; - case Strip: - d->state->rawAngle = 0; - d->state->spacingRatio = 1; - d->state->reposition(); - break; - case StripOverlapped: - d->state->rawAngle = 0; - d->state->spacingRatio = 0; - d->state->reposition(); - break; - default: - break; - } - d->state->reset(); - d->renderer->init(); -} - -void PictureFlow::setMarkImage(const QImage &m) -{ - d->state->mark = m; -} - -void PictureFlow::markSlide(int index, YACReader::YACReaderComicReadStatus readStatus) -{ - if (index < d->state->marks.size()) - d->state->marks[index] = readStatus; -} - -void PictureFlow::updateMarks() -{ - d->renderer->init(); - repaint(); -} - -void PictureFlow::unmarkSlide(int index) -{ - if (index < d->state->marks.size()) - d->state->marks[index] = YACReader::Unread; -} - -void PictureFlow::setMarks(const QVector &m) -{ - d->state->marks = m; - updateMarks(); -} - -void PictureFlow::setShowMarks(bool enable) -{ - d->state->showMarks = enable; - updateMarks(); -} - -QVector PictureFlow::getMarks() -{ - return d->state->marks; -} - -void PictureFlow::resortCovers(QList newOrder) -{ - QVector slideImagesNew; - - QVector marksNew; - - QVector slidesInfo; - slidesInfo << d->state->leftSlides << d->state->centerSlide << d->state->rightSlides; - QVector slidesInfoNew; - - int order = 0; - foreach (int index, newOrder) { - slideImagesNew << d->state->slideImages.at(index); - marksNew << d->state->marks.at(index); - slidesInfoNew << slidesInfo.at(index); - slidesInfoNew.last().slideIndex = order++; - } - - d->state->slideImages = slideImagesNew; - d->state->marks = marksNew; - d->state->leftSlides = slidesInfoNew.mid(0, d->state->leftSlides.length()); - d->state->centerSlide = slidesInfoNew.at(d->state->centerIndex); - d->state->leftSlides = slidesInfoNew.mid(d->state->centerIndex + 1, d->state->leftSlides.length()); - - setCenterIndex(d->state->centerIndex); -} diff --git a/common/pictureflow.h b/common/pictureflow.h deleted file mode 100644 index e1d9c68d..00000000 --- a/common/pictureflow.h +++ /dev/null @@ -1,233 +0,0 @@ -/* - PictureFlow - animated image show widget - http://pictureflow.googlecode.com - - Copyright (C) 2008 Ariya Hidayat (ariya@kde.org) - Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#ifndef PICTUREFLOW_H -#define PICTUREFLOW_H - -#include -#include "yacreader_global_gui.h" //FlowType - -class PictureFlowPrivate; - -using namespace YACReader; - -/*! - Class PictureFlow implements an image show widget with animation effect - like Apple's CoverFlow (in iTunes and iPod). Images are arranged in form - of slides, one main slide is shown at the center with few slides on - the left and right sides of the center slide. When the next or previous - slide is brought to the front, the whole slides flow to the right or - the right with smooth animation effect; until the new slide is finally - placed at the center. - - */ -class PictureFlow : public QWidget -{ - Q_OBJECT - - Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) - Q_PROPERTY(QSize slideSize READ slideSize WRITE setSlideSize) - Q_PROPERTY(int slideCount READ slideCount) - Q_PROPERTY(int centerIndex READ centerIndex WRITE setCenterIndex) - -public: - enum ReflectionEffect { - NoReflection, - PlainReflection, - BlurredReflection - }; - - /*! - Creates a new PictureFlow widget. - */ - PictureFlow(QWidget *parent = 0, FlowType flowType = CoverFlowLike); - - /*! - Destroys the widget. - */ - ~PictureFlow(); - - /*! - Returns the background color. - */ - QColor backgroundColor() const; - - /*! - Sets the background color. By default it is black. - */ - void setBackgroundColor(const QColor &c); - - /*! - Returns the dimension of each slide (in pixels). - */ - QSize slideSize() const; - - /*! - Sets the dimension of each slide (in pixels). - */ - void setSlideSize(QSize size); - - /*! - Returns the total number of slides. - */ - int slideCount() const; - - /*! - Returns QImage of specified slide. - */ - QImage slide(int index) const; - - /*! - Returns the index of slide currently shown in the middle of the viewport. - */ - int centerIndex() const; - - /*! - Returns the effect applied to the reflection. - */ - ReflectionEffect reflectionEffect() const; - - /*! - Sets the effect applied to the reflection. The default is PlainReflection. - */ - void setReflectionEffect(ReflectionEffect effect); - - /*! - Sets the flow direction right-to-left (manga mode) - */ - void setFlowRightToLeft(bool b); - -public slots: - - /*! - Adds a new slide. - */ - void addSlide(const QImage &image); - - /*! - Adds a new slide. - */ - void addSlide(const QPixmap &pixmap); - - /*! - Insert and empty slide at index. - */ - void insertSlide(int index); - - /*! - Removes an existing slide. - */ - void removeSlide(int index); - - /*! - Sets an image for specified slide. If the slide already exists, - it will be replaced. - */ - void setSlide(int index, const QImage &image); - - /*! - Sets a pixmap for specified slide. If the slide already exists, - it will be replaced. - */ - void setSlide(int index, const QPixmap &pixmap); - - /*! - Sets slide to be shown in the middle of the viewport. No animation - effect will be produced, unlike using showSlide. - */ - void setCenterIndex(int index); - - /*! - Clears all slides. - */ - void clear(); - - /*! - Shows previous slide using animation effect. - */ - void showPrevious(); - - /*! - Shows next slide using animation effect. - */ - void showNext(); - - /*! - Go to specified slide using animation effect. - */ - void showSlide(unsigned int index); - - /*! - Rerender the widget. Normally this function will be automatically invoked - whenever necessary, e.g. during the transition animation. - */ - void render(); - - /*! - Schedules a rendering update. Unlike render(), this function does not cause - immediate rendering. - */ - void triggerRender(); - - void setFlowType(YACReader::FlowType flowType); - - void setMarkImage(const QImage &mark); - - void markSlide(int index, YACReader::YACReaderComicReadStatus readStatus = Read); - - void updateMarks(); - - void unmarkSlide(int index); - - void setMarks(const QVector &marks); - - void setShowMarks(bool enable); - - QVector getMarks(); - - void resortCovers(QList newOrder); - -signals: - void centerIndexChanged(int index); - void centerIndexChangedSilent(int index); - -public: - void paintEvent(QPaintEvent *event); - void keyPressEvent(QKeyEvent *event); - void mousePressEvent(QMouseEvent *event); - void mousePressEvent(QMouseEvent *event, int slideWidth); - void resizeEvent(QResizeEvent *event); - -private slots: - void updateAnimation(); - -private: - PictureFlowPrivate *d; - QImage mark; - int framesSkip; -}; - -#endif // PICTUREFLOW_H diff --git a/common/rhi/flow_types.cpp b/common/rhi/flow_types.cpp new file mode 100644 index 00000000..9d9bd200 --- /dev/null +++ b/common/rhi/flow_types.cpp @@ -0,0 +1,182 @@ +#include "flow_types.h" + +/*** Preset Configurations ***/ + +struct Preset defaultYACReaderFlowConfig = { + 0.08f, // Animation_step sets the speed of the animation + 1.5f, // Animation_speedup sets the acceleration of the animation + 0.1f, // Animation_step_max sets the maximum speed of the animation + 3.f, // Animation_Fade_out_dis sets the distance of view + + 1.5f, // pre_rotation sets the rotation increasion + 3.f, // View_rotate_light_strenght sets the light strenght on rotation + 0.01f, // View_rotate_add sets the speed of the rotation + 0.02f, // View_rotate_sub sets the speed of reversing the rotation + 20.f, // View_angle sets the maximum view angle + + 0.f, // CF_X the X Position of the Coverflow + 0.f, // CF_Y the Y Position of the Coverflow + -8.f, // CF_Z the Z Position of the Coverflow + + 15.f, // CF_RX the X Rotation of the Coverflow + 0.f, // CF_RY the Y Rotation of the Coverflow + 0.f, // CF_RZ the Z Rotation of the Coverflow + + -50.f, // Rotation sets the rotation of each cover + 0.18f, // X_Distance sets the distance between the covers + 1.f, // Center_Distance sets the distance between the centered and the non centered covers + 0.1f, // Z_Distance sets the pushback amount + 0.0f, // Y_Distance sets the elevation amount + + 30.f // zoom level + +}; + +struct Preset presetYACReaderFlowClassicConfig = { + 0.08f, // Animation_step sets the speed of the animation + 1.5f, // Animation_speedup sets the acceleration of the animation + 0.1f, // Animation_step_max sets the maximum speed of the animation + 2.f, // Animation_Fade_out_dis sets the distance of view + + 1.5f, // pre_rotation sets the rotation increasion + 3.f, // View_rotate_light_strenght sets the light strenght on rotation + 0.08f, // View_rotate_add sets the speed of the rotation + 0.08f, // View_rotate_sub sets the speed of reversing the rotation + 30.f, // View_angle sets the maximum view angle + + 0.f, // CF_X the X Position of the Coverflow + -0.2f, // CF_Y the Y Position of the Coverflow + -7.f, // CF_Z the Z Position of the Coverflow + + 0.f, // CF_RX the X Rotation of the Coverflow + 0.f, // CF_RY the Y Rotation of the Coverflow + 0.f, // CF_RZ the Z Rotation of the Coverflow + + -40.f, // Rotation sets the rotation of each cover + 0.18f, // X_Distance sets the distance between the covers + 1.f, // Center_Distance sets the distance between the centered and the non centered covers + 0.1f, // Z_Distance sets the pushback amount + 0.0f, // Y_Distance sets the elevation amount + + 22.f // zoom level + +}; + +struct Preset presetYACReaderFlowStripeConfig = { + 0.08f, // Animation_step sets the speed of the animation + 1.5f, // Animation_speedup sets the acceleration of the animation + 0.1f, // Animation_step_max sets the maximum speed of the animation + 6.f, // Animation_Fade_out_dis sets the distance of view + + 1.5f, // pre_rotation sets the rotation increasion + 4.f, // View_rotate_light_strenght sets the light strenght on rotation + 0.08f, // View_rotate_add sets the speed of the rotation + 0.08f, // View_rotate_sub sets the speed of reversing the rotation + 30.f, // View_angle sets the maximum view angle + + 0.f, // CF_X the X Position of the Coverflow + -0.2f, // CF_Y the Y Position of the Coverflow + -7.f, // CF_Z the Z Position of the Coverflow + + 0.f, // CF_RX the X Rotation of the Coverflow + 0.f, // CF_RY the Y Rotation of the Coverflow + 0.f, // CF_RZ the Z Rotation of the Coverflow + + 0.f, // Rotation sets the rotation of each cover + 1.1f, // X_Distance sets the distance between the covers + 0.2f, // Center_Distance sets the distance between the centered and the non centered covers + 0.01f, // Z_Distance sets the pushback amount + 0.0f, // Y_Distance sets the elevation amount + + 22.f // zoom level + +}; + +struct Preset presetYACReaderFlowOverlappedStripeConfig = { + 0.08f, // Animation_step sets the speed of the animation + 1.5f, // Animation_speedup sets the acceleration of the animation + 0.1f, // Animation_step_max sets the maximum speed of the animation + 2.f, // Animation_Fade_out_dis sets the distance of view + + 1.5f, // pre_rotation sets the rotation increasion + 3.f, // View_rotate_light_strenght sets the light strenght on rotation + 0.08f, // View_rotate_add sets the speed of the rotation + 0.08f, // View_rotate_sub sets the speed of reversing the rotation + 30.f, // View_angle sets the maximum view angle + + 0.f, // CF_X the X Position of the Coverflow + -0.2f, // CF_Y the Y Position of the Coverflow + -7.f, // CF_Z the Z Position of the Coverflow + + 0.f, // CF_RX the X Rotation of the Coverflow + 0.f, // CF_RY the Y Rotation of the Coverflow + 0.f, // CF_RZ the Z Rotation of the Coverflow + + 0.f, // Rotation sets the rotation of each cover + 0.18f, // X_Distance sets the distance between the covers + 1.f, // Center_Distance sets the distance between the centered and the non centered covers + 0.1f, // Z_Distance sets the pushback amount + 0.0f, // Y_Distance sets the elevation amount + + 22.f // zoom level + +}; + +struct Preset pressetYACReaderFlowUpConfig = { + 0.08f, // Animation_step sets the speed of the animation + 1.5f, // Animation_speedup sets the acceleration of the animation + 0.1f, // Animation_step_max sets the maximum speed of the animation + 2.5f, // Animation_Fade_out_dis sets the distance of view + + 1.5f, // pre_rotation sets the rotation increasion + 3.f, // View_rotate_light_strenght sets the light strenght on rotation + 0.08f, // View_rotate_add sets the speed of the rotation + 0.08f, // View_rotate_sub sets the speed of reversing the rotation + 5.f, // View_angle sets the maximum view angle + + 0.f, // CF_X the X Position of the Coverflow + -0.2f, // CF_Y the Y Position of the Coverflow + -7.f, // CF_Z the Z Position of the Coverflow + + 0.f, // CF_RX the X Rotation of the Coverflow + 0.f, // CF_RY the Y Rotation of the Coverflow + 0.f, // CF_RZ the Z Rotation of the Coverflow + + -50.f, // Rotation sets the rotation of each cover + 0.18f, // X_Distance sets the distance between the covers + 1.f, // Center_Distance sets the distance between the centered and the non centered covers + 0.1f, // Z_Distance sets the pushback amount + -0.1f, // Y_Distance sets the elevation amount + + 22.f // zoom level + +}; + +struct Preset pressetYACReaderFlowDownConfig = { + 0.08f, // Animation_step sets the speed of the animation + 1.5f, // Animation_speedup sets the acceleration of the animation + 0.1f, // Animation_step_max sets the maximum speed of the animation + 2.5f, // Animation_Fade_out_dis sets the distance of view + + 1.5f, // pre_rotation sets the rotation increasion + 3.f, // View_rotate_light_strenght sets the light strenght on rotation + 0.08f, // View_rotate_add sets the speed of the rotation + 0.08f, // View_rotate_sub sets the speed of reversing the rotation + 5.f, // View_angle sets the maximum view angle + + 0.f, // CF_X the X Position of the Coverflow + -0.2f, // CF_Y the Y Position of the Coverflow + -7.f, // CF_Z the Z Position of the Coverflow + + 0.f, // CF_RX the X Rotation of the Coverflow + 0.f, // CF_RY the Y Rotation of the Coverflow + 0.f, // CF_RZ the Z Rotation of the Coverflow + + -50.f, // Rotation sets the rotation of each cover + 0.18f, // X_Distance sets the distance between the covers + 1.f, // Center_Distance sets the distance between the centered and the non centered covers + 0.1f, // Z_Distance sets the pushback amount + 0.1f, // Y_Distance sets the elevation amount + + 22.f // zoom level +}; diff --git a/common/rhi/flow_types.h b/common/rhi/flow_types.h new file mode 100644 index 00000000..79fe08dc --- /dev/null +++ b/common/rhi/flow_types.h @@ -0,0 +1,75 @@ +// Shared types for YACReader Flow implementations (GL and RHI) +#ifndef __YACREADER_FLOW_TYPES_H +#define __YACREADER_FLOW_TYPES_H + +enum Performance { + low = 0, + medium, + high, + ultraHigh +}; + +// Cover Vector +struct YACReader3DVector { + float x; + float y; + float z; + float rot; +}; + +struct Preset { + /*** Animation Settings ***/ + // sets the speed of the animation + float animationStep; + // sets the acceleration of the animation + float animationSpeedUp; + // sets the maximum speed of the animation + float animationStepMax; + // sets the distance of view + float animationFadeOutDist; + // sets the rotation increasion + float preRotation; + // sets the light strenght on rotation + float viewRotateLightStrenght; + // sets the speed of the rotation + float viewRotateAdd; + // sets the speed of reversing the rotation + float viewRotateSub; + // sets the maximum view angle + float viewAngle; + + /*** Position Configuration ***/ + // the X Position of the Coverflow + float cfX; + // the Y Position of the Coverflow + float cfY; + // the Z Position of the Coverflow + float cfZ; + // the X Rotation of the Coverflow + float cfRX; + // the Y Rotation of the Coverflow + float cfRY; + // the Z Rotation of the Coverflow + float cfRZ; + // sets the rotation of each cover + float rotation; + // sets the distance between the covers + float xDistance; + // sets the distance between the centered and the non centered covers + float centerDistance; + // sets the pushback amount + float zDistance; + // sets the elevation amount + float yDistance; + + float zoom; +}; + +extern struct Preset defaultYACReaderFlowConfig; +extern struct Preset presetYACReaderFlowClassicConfig; +extern struct Preset presetYACReaderFlowStripeConfig; +extern struct Preset presetYACReaderFlowOverlappedStripeConfig; +extern struct Preset pressetYACReaderFlowUpConfig; +extern struct Preset pressetYACReaderFlowDownConfig; + +#endif // __YACREADER_FLOW_TYPES_H diff --git a/common/rhi/yacreader_comic_flow_rhi.cpp b/common/rhi/yacreader_comic_flow_rhi.cpp index a5ec18fe..c57d38e9 100644 --- a/common/rhi/yacreader_comic_flow_rhi.cpp +++ b/common/rhi/yacreader_comic_flow_rhi.cpp @@ -121,7 +121,7 @@ void YACReaderComicFlow3D::resortCovers(QList newOrder) QList pathsNew; QVector loadedNew; - QVector marksNew; + QVector marksNew; QVector imagesNew; int index = 0; diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index 1391e3ea..8ef969ea 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -169,7 +169,6 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) // Two triangles forming a quad (triangle list): // Tri 1: bottom-left, bottom-right, top-right // Tri 2: bottom-left, top-right, top-left - // Texture coords flipped vertically to match OpenGL convention float vertices[] = { // Position (x, y, z), TexCoord (u, v) -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-left @@ -189,7 +188,7 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) scene.alignedUniformSize = m_rhi->ubufAligned(sizeof(UniformData)); } - // Create sampler with trilinear filtering (like the OpenGL version) + // Create sampler with trilinear filtering if (!scene.sampler) { scene.sampler.reset(m_rhi->newSampler( QRhiSampler::Linear, // mag filter @@ -481,7 +480,6 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) }; // Collect all draws we need to make - // Important: OpenGL draws reflections FIRST, then covers+marks (for correct depth sorting) QVector draws; // Start timing for this render call (measures CPU time spent in this function) @@ -532,8 +530,8 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) continue; // Add mark draw immediately after its cover - if (showMarks && loaded[idx] && marks[idx] != Unread) { - QRhiTexture *markTex = (marks[idx] == Read) ? scene.markTexture.get() : scene.readingTexture.get(); + if (showMarks && loaded[idx] && marks[idx] != YACReader::Unread) { + QRhiTexture *markTex = (marks[idx] == YACReader::Read) ? scene.markTexture.get() : scene.readingTexture.get(); if (markTex) { if (!isVisibleInNDC(images[idx], false, true)) continue; @@ -1001,7 +999,7 @@ void YACReaderFlow3D::add(int item) images.insert(item, YACReader3DImageRHI()); loaded.insert(item, false); - marks.insert(item, Unread); + marks.insert(item, YACReader::Unread); numObjects++; for (int i = item + 1; i < numObjects; i++) { diff --git a/common/rhi/yacreader_flow_rhi.h b/common/rhi/yacreader_flow_rhi.h index 6f850a8b..b7b31fe4 100644 --- a/common/rhi/yacreader_flow_rhi.h +++ b/common/rhi/yacreader_flow_rhi.h @@ -12,25 +12,10 @@ #include #include -#include "pictureflow.h" +#include "flow_types.h" +#include "yacreader_global.h" #include "scroll_management.h" -// Reuse enums and structs from OpenGL version -enum Performance { - low = 0, - medium, - high, - ultraHigh -}; - -// Cover Vector -struct YACReader3DVector { - float x; - float y; - float z; - float rot; -}; - // the image/texture info struct struct YACReader3DImageRHI { QRhiTexture *texture; @@ -47,41 +32,6 @@ struct YACReader3DImageRHI { YACReader3DVector animEnd; }; -struct Preset { - /*** Animation Settings ***/ - float animationStep; - float animationSpeedUp; - float animationStepMax; - float animationFadeOutDist; - float preRotation; - float viewRotateLightStrenght; - float viewRotateAdd; - float viewRotateSub; - float viewAngle; - - /*** Position Configuration ***/ - float cfX; - float cfY; - float cfZ; - float cfRX; - float cfRY; - float cfRZ; - float rotation; - float xDistance; - float centerDistance; - float zDistance; - float yDistance; - - float zoom; -}; - -extern struct Preset defaultYACReaderFlowConfig; -extern struct Preset presetYACReaderFlowClassicConfig; -extern struct Preset presetYACReaderFlowStripeConfig; -extern struct Preset presetYACReaderFlowOverlappedStripeConfig; -extern struct Preset pressetYACReaderFlowUpConfig; -extern struct Preset pressetYACReaderFlowDownConfig; - class QLabel; class ImageLoader3D; class ImageLoaderByteArray3D; @@ -204,7 +154,7 @@ protected: int lazyPopulateObjects; bool showMarks; QVector loaded; - QVector marks; + QVector marks; QVector images; diff --git a/config.pri b/config.pri index 8d1b6be4..d76a258d 100644 --- a/config.pri +++ b/config.pri @@ -49,17 +49,6 @@ CONFIG += silent isEmpty(QMAKE_TARGET.arch) { QMAKE_TARGET.arch = $$QMAKE_HOST.arch } -contains(QMAKE_TARGET.arch, arm.*)|contains(QMAKE_TARGET.arch, aarch.*) { - !macx:!win32 { # Apple silicon supports opengl (for now lets flag windows as experimental) - CONFIG += no_opengl - message("Building for ARM architecture. Disabling OpenGL coverflow. If you know that your ARM arquitecture supports opengl, please edit config.pri to enable it.") - } -} - -# build without opengl widget support -CONFIG(no_opengl) { - DEFINES += NO_OPENGL -} # default value for comic archive decompression backend unix:!macx:!CONFIG(unarr):!CONFIG(7zip):!CONFIG(libarchive) { diff --git a/custom_widgets/custom_widgets_yacreader.pri b/custom_widgets/custom_widgets_yacreader.pri index 51c9999d..92e474ae 100644 --- a/custom_widgets/custom_widgets_yacreader.pri +++ b/custom_widgets/custom_widgets_yacreader.pri @@ -5,44 +5,30 @@ HEADERS += \ $$PWD/help_about_dialog.h \ $$PWD/yacreader_field_edit.h \ $$PWD/yacreader_field_plain_text_edit.h \ - $$PWD/yacreader_flow.h \ - $$PWD/yacreader_flow_config_widget.h \ $$PWD/yacreader_options_dialog.h \ $$PWD/yacreader_spin_slider_widget.h \ $$PWD/yacreader_tool_bar_stretch.h \ $$PWD/yacreader_busy_widget.h \ $$PWD/rounded_corners_dialog.h \ $$PWD/whats_new_dialog.h \ - $$PWD/whats_new_controller.h - -!CONFIG(no_opengl) { - HEADERS += $$PWD/yacreader_gl_flow_config_widget.h -} - + $$PWD/whats_new_controller.h \ + $$PWD/yacreader_3d_flow_config_widget.h macx{ HEADERS += $$PWD/yacreader_macosx_toolbar.h -} - - +} SOURCES += \ $$PWD/help_about_dialog.cpp \ $$PWD/yacreader_field_edit.cpp \ $$PWD/yacreader_field_plain_text_edit.cpp \ - $$PWD/yacreader_flow.cpp \ - $$PWD/yacreader_flow_config_widget.cpp \ $$PWD/yacreader_options_dialog.cpp \ $$PWD/yacreader_spin_slider_widget.cpp \ $$PWD/yacreader_tool_bar_stretch.cpp \ $$PWD/yacreader_busy_widget.cpp \ $$PWD/rounded_corners_dialog.cpp \ $$PWD/whats_new_dialog.cpp \ - $$PWD/whats_new_controller.cpp - -!CONFIG(no_opengl) { - SOURCES += $$PWD/yacreader_gl_flow_config_widget.cpp -} + $$PWD/whats_new_controller.cpp \ + $$PWD/yacreader_3d_flow_config_widget.cpp macx{ OBJECTIVE_SOURCES += $$PWD/yacreader_macosx_toolbar.mm } - diff --git a/custom_widgets/custom_widgets_yacreaderlibrary.pri b/custom_widgets/custom_widgets_yacreaderlibrary.pri index 1b218b77..3341bd40 100644 --- a/custom_widgets/custom_widgets_yacreaderlibrary.pri +++ b/custom_widgets/custom_widgets_yacreaderlibrary.pri @@ -8,8 +8,6 @@ HEADERS += \ $$PWD/whats_new_controller.h \ $$PWD/yacreader_field_edit.h \ $$PWD/yacreader_field_plain_text_edit.h \ - $$PWD/yacreader_flow.h \ - $$PWD/yacreader_flow_config_widget.h \ $$PWD/yacreader_options_dialog.h \ $$PWD/yacreader_search_line_edit.h \ $$PWD/yacreader_spin_slider_widget.h \ @@ -22,11 +20,8 @@ HEADERS += \ $$PWD/yacreader_library_item_widget.h \ $$PWD/yacreader_treeview.h \ $$PWD/yacreader_busy_widget.h \ - $$PWD/yacreader_cover_label.h -!CONFIG(no_opengl){ - HEADERS += $$PWD/yacreader_gl_flow_config_widget.h -} - + $$PWD/yacreader_cover_label.h \ + $$PWD/yacreader_3d_flow_config_widget.h macx{ HEADERS += $$PWD/yacreader_macosx_toolbar.h } @@ -38,8 +33,6 @@ SOURCES += \ $$PWD/whats_new_controller.cpp \ $$PWD/yacreader_field_edit.cpp \ $$PWD/yacreader_field_plain_text_edit.cpp \ - $$PWD/yacreader_flow.cpp \ - $$PWD/yacreader_flow_config_widget.cpp \ $$PWD/yacreader_options_dialog.cpp \ $$PWD/yacreader_search_line_edit.cpp \ $$PWD/yacreader_spin_slider_widget.cpp \ @@ -52,11 +45,8 @@ SOURCES += \ $$PWD/yacreader_library_item_widget.cpp \ $$PWD/yacreader_treeview.cpp \ $$PWD/yacreader_busy_widget.cpp \ - $$PWD/yacreader_cover_label.cpp -!CONFIG(no_opengl){ - SOURCES += $$PWD/yacreader_gl_flow_config_widget.cpp -} - + $$PWD/yacreader_cover_label.cpp \ + $$PWD/yacreader_3d_flow_config_widget.cpp macx{ OBJECTIVE_SOURCES += $$PWD/yacreader_macosx_toolbar.mm } diff --git a/custom_widgets/help_about_dialog.cpp b/custom_widgets/help_about_dialog.cpp index 2ba8bf6a..25538c80 100644 --- a/custom_widgets/help_about_dialog.cpp +++ b/custom_widgets/help_about_dialog.cpp @@ -1,6 +1,5 @@ #include "help_about_dialog.h" -#include "opengl_checker.h" #include "global_info_provider.h" #include @@ -100,10 +99,8 @@ void HelpAboutDialog::loadSystemInfo() { auto text = YACReader::getGlobalInfo(); - auto openGLChecker = OpenGLChecker(); text.append("\nGRAPHIC INFORMATION\n"); text.append(QString("Screen pixel ratio: %1\n").arg(devicePixelRatioF())); - text.append(QString("OpenGL version: %1\n").arg(openGLChecker.textVersionDescription())); systemInfoText->setText(text); } diff --git a/custom_widgets/yacreader_gl_flow_config_widget.cpp b/custom_widgets/yacreader_3d_flow_config_widget.cpp similarity index 96% rename from custom_widgets/yacreader_gl_flow_config_widget.cpp rename to custom_widgets/yacreader_3d_flow_config_widget.cpp index 813f01c5..a3db5fef 100644 --- a/custom_widgets/yacreader_gl_flow_config_widget.cpp +++ b/custom_widgets/yacreader_3d_flow_config_widget.cpp @@ -1,15 +1,16 @@ -#include "yacreader_gl_flow_config_widget.h" +#include "yacreader_3d_flow_config_widget.h" #include "yacreader_spin_slider_widget.h" -#include "yacreader_flow_gl.h" //TODO +#include #include #include #include #include #include +#include -YACReaderGLFlowConfigWidget::YACReaderGLFlowConfigWidget(QWidget *parent /* = 0 */) +YACReader3DFlowConfigWidget::YACReader3DFlowConfigWidget(QWidget *parent /* = 0 */) : QWidget(parent) { QVBoxLayout *layout = new QVBoxLayout(this); @@ -75,7 +76,7 @@ YACReaderGLFlowConfigWidget::YACReaderGLFlowConfigWidget(QWidget *parent /* = 0 showAdvancedOptions = new QPushButton(tr("Show advanced settings")); showAdvancedOptions->setCheckable(true); - connect(showAdvancedOptions, &QAbstractButton::toggled, this, &YACReaderGLFlowConfigWidget::avancedOptionToogled); + connect(showAdvancedOptions, &QAbstractButton::toggled, this, &YACReader3DFlowConfigWidget::avancedOptionToogled); vbox->addWidget(showAdvancedOptions, 0, Qt::AlignRight); @@ -213,7 +214,7 @@ YACReaderGLFlowConfigWidget::YACReaderGLFlowConfigWidget(QWidget *parent /* = 0 setLayout(layout); } -void YACReaderGLFlowConfigWidget::avancedOptionToogled(bool show) +void YACReader3DFlowConfigWidget::avancedOptionToogled(bool show) { if (show) optionsGroupBox->show(); @@ -221,7 +222,7 @@ void YACReaderGLFlowConfigWidget::avancedOptionToogled(bool show) optionsGroupBox->hide(); } -void YACReaderGLFlowConfigWidget::setValues(Preset preset) +void YACReader3DFlowConfigWidget::setValues(Preset preset) { xRotation->setValue(preset.cfRX); yPosition->setValue(preset.cfY * 100); diff --git a/custom_widgets/yacreader_gl_flow_config_widget.h b/custom_widgets/yacreader_3d_flow_config_widget.h similarity index 79% rename from custom_widgets/yacreader_gl_flow_config_widget.h rename to custom_widgets/yacreader_3d_flow_config_widget.h index b29a1abc..cdf855f9 100644 --- a/custom_widgets/yacreader_gl_flow_config_widget.h +++ b/custom_widgets/yacreader_3d_flow_config_widget.h @@ -1,7 +1,7 @@ -#ifndef YACREADER_GL_FLOW_CONFIG_WIDGET_H -#define YACREADER_GL_FLOW_CONFIG_WIDGET_H +#ifndef YACREADER_3D_FLOW_CONFIG_WIDGET_H +#define YACREADER_3D_FLOW_CONFIG_WIDGET_H -#include "yacreader_flow_gl.h" //TODO +#include "flow_types.h" //TODO #include class QRadioButton; @@ -11,11 +11,11 @@ class QCheckBox; class QPushButton; class QGroupBox; -class YACReaderGLFlowConfigWidget : public QWidget +class YACReader3DFlowConfigWidget : public QWidget { Q_OBJECT public: - YACReaderGLFlowConfigWidget(QWidget *parent = 0); + YACReader3DFlowConfigWidget(QWidget *parent = 0); // GL......................... QRadioButton *radioClassic; @@ -47,4 +47,4 @@ public slots: void avancedOptionToogled(bool show); }; -#endif // YACREADER_GL_FLOW_CONFIG_WIDGET_H \ No newline at end of file +#endif // YACREADER_3D_FLOW_CONFIG_WIDGET_H diff --git a/custom_widgets/yacreader_flow.cpp b/custom_widgets/yacreader_flow.cpp deleted file mode 100644 index f930136e..00000000 --- a/custom_widgets/yacreader_flow.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "yacreader_flow.h" - -#include - -YACReaderFlow::YACReaderFlow(QWidget *parent, FlowType flowType) - : PictureFlow(parent, flowType) { } - -void YACReaderFlow::mousePressEvent(QMouseEvent *event) -{ - PictureFlow::mousePressEvent(event, slideSize().width()); -} - -void YACReaderFlow::mouseDoubleClickEvent(QMouseEvent *event) -{ - if ((event->x() > (width() - slideSize().width()) / 2) && (event->x() < (width() + slideSize().width()) / 2)) - emit selected(centerIndex()); -} diff --git a/custom_widgets/yacreader_flow.h b/custom_widgets/yacreader_flow.h deleted file mode 100644 index d08ae3a8..00000000 --- a/custom_widgets/yacreader_flow.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef YACREADER_FLOW_H -#define YACREADER_FLOW_H - -#include "pictureflow.h" - -class QMouseEvent; - -class YACReaderFlow : public PictureFlow -{ - Q_OBJECT -public: - YACReaderFlow(QWidget *parent, FlowType flowType = CoverFlowLike); - - void mousePressEvent(QMouseEvent *event); - void mouseDoubleClickEvent(QMouseEvent *event); - -signals: - void selected(unsigned int centerIndex); -}; - -#endif // YACREADER_FLOW_H \ No newline at end of file diff --git a/custom_widgets/yacreader_flow_config_widget.cpp b/custom_widgets/yacreader_flow_config_widget.cpp deleted file mode 100644 index cdf47cc5..00000000 --- a/custom_widgets/yacreader_flow_config_widget.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "yacreader_flow_config_widget.h" - -#include -#include -#include -#include - -YACReaderFlowConfigWidget::YACReaderFlowConfigWidget(QWidget *parent) - : QWidget(parent) -{ - QVBoxLayout *layout = new QVBoxLayout(this); - - QGroupBox *groupBox = new QGroupBox(tr("How to show covers:")); - - radio1 = new QRadioButton(tr("CoverFlow look")); - radio2 = new QRadioButton(tr("Stripe look")); - radio3 = new QRadioButton(tr("Overlapped Stripe look")); - - QVBoxLayout *vbox = new QVBoxLayout; - QHBoxLayout *opt1 = new QHBoxLayout; - opt1->addWidget(radio1); - QLabel *lOpt1 = new QLabel(); - lOpt1->setPixmap(QPixmap(":/images/flow1.png")); - opt1->addStretch(); - opt1->addWidget(lOpt1); - vbox->addLayout(opt1); - - QHBoxLayout *opt2 = new QHBoxLayout; - opt2->addWidget(radio2); - QLabel *lOpt2 = new QLabel(); - lOpt2->setPixmap(QPixmap(":/images/flow2.png")); - opt2->addStretch(); - opt2->addWidget(lOpt2); - vbox->addLayout(opt2); - - QHBoxLayout *opt3 = new QHBoxLayout; - opt3->addWidget(radio3); - QLabel *lOpt3 = new QLabel(); - lOpt3->setPixmap(QPixmap(":/images/flow3.png")); - opt3->addStretch(); - opt3->addWidget(lOpt3); - vbox->addLayout(opt3); - - // vbox->addStretch(1); - groupBox->setLayout(vbox); - - layout->addWidget(groupBox); - - layout->setContentsMargins(0, 0, 0, 0); - - setLayout(layout); -} \ No newline at end of file diff --git a/custom_widgets/yacreader_flow_config_widget.h b/custom_widgets/yacreader_flow_config_widget.h deleted file mode 100644 index 2d23d462..00000000 --- a/custom_widgets/yacreader_flow_config_widget.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef YACREADER_FLOW_CONFIG_WIDGET_H -#define YACREADER_FLOW_CONFIG_WIDGET_H - -#include - -class QRadioButton; - -class YACReaderFlowConfigWidget : public QWidget -{ - Q_OBJECT -public: - QRadioButton *radio1; - QRadioButton *radio2; - QRadioButton *radio3; - - YACReaderFlowConfigWidget(QWidget *parent = 0); -}; - -#endif // YACREADER_FLOW_CONFIG_WIDGET_H \ No newline at end of file diff --git a/custom_widgets/yacreader_options_dialog.cpp b/custom_widgets/yacreader_options_dialog.cpp index 6f5178cc..72f45ce8 100644 --- a/custom_widgets/yacreader_options_dialog.cpp +++ b/custom_widgets/yacreader_options_dialog.cpp @@ -1,13 +1,8 @@ #include "yacreader_options_dialog.h" -#include "yacreader_flow_config_widget.h" -#ifndef NO_OPENGL -#include "yacreader_gl_flow_config_widget.h" -#else -#include "pictureflow.h" -#endif +#include "yacreader_3d_flow_config_widget.h" +#include "yacreader_global_gui.h" #include "yacreader_spin_slider_widget.h" -#include "yacreader_global.h" #include #include @@ -20,11 +15,7 @@ YACReaderOptionsDialog::YACReaderOptionsDialog(QWidget *parent) : QDialog(parent) { - - sw = new YACReaderFlowConfigWidget(this); -#ifndef NO_OPENGL - gl = new YACReaderGLFlowConfigWidget(this); -#endif + gl = new YACReader3DFlowConfigWidget(this); accept = new QPushButton(tr("Save")); cancel = new QPushButton(tr("Cancel")); @@ -42,15 +33,7 @@ YACReaderOptionsDialog::YACReaderOptionsDialog(QWidget *parent) connect(accept, &QAbstractButton::clicked, this, &YACReaderOptionsDialog::saveOptions); connect(cancel, &QAbstractButton::clicked, this, QOverload<>::of(&YACReaderOptionsDialog::restoreOptions)); connect(cancel, &QAbstractButton::clicked, this, &QWidget::close); -#ifndef NO_OPENGL - useGL = new QCheckBox(tr("Use hardware acceleration (restart needed)")); - connect(useGL, &QCheckBox::stateChanged, this, &YACReaderOptionsDialog::saveUseGL); -#endif - // sw CONNECTIONS - connect(sw->radio1, &QAbstractButton::toggled, this, &YACReaderOptionsDialog::setClassicConfigSW); - connect(sw->radio2, &QAbstractButton::toggled, this, &YACReaderOptionsDialog::setStripeConfigSW); - connect(sw->radio3, &QAbstractButton::toggled, this, &YACReaderOptionsDialog::setOverlappedStripeConfigSW); -#ifndef NO_OPENGL + // gl CONNECTIONS connect(gl->radioClassic, &QAbstractButton::toggled, this, &YACReaderOptionsDialog::setClassicConfig); connect(gl->radioStripe, &QAbstractButton::toggled, this, &YACReaderOptionsDialog::setStripeConfig); @@ -100,11 +83,9 @@ YACReaderOptionsDialog::YACReaderOptionsDialog(QWidget *parent) connect(gl->performanceSlider, &QAbstractSlider::valueChanged, this, &YACReaderOptionsDialog::savePerformance); connect(gl->performanceSlider, &QAbstractSlider::valueChanged, this, &YACReaderOptionsDialog::optionsChanged); - connect(gl->vSyncCheck, &QCheckBox::stateChanged, this, &YACReaderOptionsDialog::saveUseVSync); -#endif + connect(gl->vSyncCheck, &QCheckBox::checkStateChanged, this, &YACReaderOptionsDialog::saveUseVSync); } -#ifndef NO_OPENGL void YACReaderOptionsDialog::savePerformance(int value) { settings->setValue(PERFORMANCE, value); @@ -129,7 +110,6 @@ void YACReaderOptionsDialog::saveFlowParameters() settings->setValue(LIGHT_STRENGTH, gl->lightStrength->getValue()); settings->setValue(MAX_ANGLE, gl->maxAngle->getValue()); } -#endif void YACReaderOptionsDialog::saveOptions() { @@ -137,96 +117,68 @@ void YACReaderOptionsDialog::saveOptions() close(); } -#ifndef NO_OPENGL -void YACReaderOptionsDialog::saveUseGL(int b) -{ - - if (Qt::Checked == b) { - sw->setVisible(false); - gl->setVisible(true); - } else { - gl->setVisible(false); - sw->setVisible(true); - } - resize(0, 0); - - settings->setValue(USE_OPEN_GL, b); -} -#endif - -#ifndef NO_OPENGL void YACReaderOptionsDialog::saveXRotation(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(X_ROTATION, value); } void YACReaderOptionsDialog::saveYPosition(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(Y_POSITION, value); } void YACReaderOptionsDialog::saveCoverDistance(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(COVER_DISTANCE, value); } void YACReaderOptionsDialog::saveCentralDistance(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(CENTRAL_DISTANCE, value); } void YACReaderOptionsDialog::saveZoomLevel(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(ZOOM_LEVEL, value); } void YACReaderOptionsDialog::saveYCoverOffset(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(Y_COVER_OFFSET, value); } void YACReaderOptionsDialog::saveZCoverOffset(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(Z_COVER_OFFSET, value); } void YACReaderOptionsDialog::saveCoverRotation(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(COVER_ROTATION, value); } void YACReaderOptionsDialog::saveFadeOutDist(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(FADE_OUT_DIST, value); } void YACReaderOptionsDialog::saveLightStrength(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(LIGHT_STRENGTH, value); } void YACReaderOptionsDialog::saveMaxAngle(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(MAX_ANGLE, value); } -#endif + void YACReaderOptionsDialog::restoreOptions(QSettings *settings) { this->settings = settings; // FLOW CONFIG -#ifndef NO_OPENGL - if (settings->contains(USE_OPEN_GL) && settings->value(USE_OPEN_GL).toInt() == Qt::Checked) { - sw->setVisible(false); - gl->setVisible(true); - useGL->setChecked(true); - } else { - gl->setVisible(false); - sw->setVisible(true); - useGL->setChecked(false); - } if (!settings->contains(FLOW_TYPE_GL)) { setClassicConfig(); @@ -242,67 +194,66 @@ void YACReaderOptionsDialog::restoreOptions(QSettings *settings) gl->performanceSlider->setValue(settings->value(PERFORMANCE).toInt()); - FlowType flowType; + YACReader::FlowType flowType; switch (settings->value(FLOW_TYPE_GL).toInt()) { case 0: - flowType = CoverFlowLike; + flowType = YACReader::CoverFlowLike; break; case 1: - flowType = Strip; + flowType = YACReader::Strip; break; case 2: - flowType = StripOverlapped; + flowType = YACReader::StripOverlapped; break; case 3: - flowType = Modern; + flowType = YACReader::Modern; break; case 4: - flowType = Roulette; + flowType = YACReader::Roulette; break; case 5: - flowType = Custom; + flowType = YACReader::Custom; break; default: - flowType = CoverFlowLike; + flowType = YACReader::CoverFlowLike; } - if (flowType == Custom) { + if (flowType == YACReader::Custom) { loadConfig(); return; } - if (flowType == CoverFlowLike) { + if (flowType == YACReader::CoverFlowLike) { setClassicConfig(); gl->radioClassic->setChecked(true); return; } - if (flowType == Strip) { + if (flowType == YACReader::Strip) { setStripeConfig(); gl->radioStripe->setChecked(true); return; } - if (flowType == StripOverlapped) { + if (flowType == YACReader::StripOverlapped) { setOverlappedStripeConfig(); gl->radioOver->setChecked(true); return; } - if (flowType == Modern) { + if (flowType == YACReader::Modern) { setModernConfig(); gl->radionModern->setChecked(true); return; } - if (flowType == Roulette) { + if (flowType == YACReader::Roulette) { setRouletteConfig(); gl->radioDown->setChecked(true); return; } // END FLOW CONFIG -#endif } void YACReaderOptionsDialog::restoreOptions() @@ -310,7 +261,6 @@ void YACReaderOptionsDialog::restoreOptions() restoreOptions(settings); } -#ifndef NO_OPENGL void YACReaderOptionsDialog::loadConfig() { gl->xRotation->setValue(settings->value(X_ROTATION).toInt()); @@ -325,30 +275,14 @@ void YACReaderOptionsDialog::loadConfig() gl->lightStrength->setValue(settings->value(LIGHT_STRENGTH).toInt()); gl->maxAngle->setValue(settings->value(MAX_ANGLE).toInt()); } -#endif -void YACReaderOptionsDialog::setClassicConfigSW() -{ - settings->setValue(FLOW_TYPE_SW, CoverFlowLike); -} -void YACReaderOptionsDialog::setStripeConfigSW() -{ - settings->setValue(FLOW_TYPE_SW, Strip); -} - -void YACReaderOptionsDialog::setOverlappedStripeConfigSW() -{ - settings->setValue(FLOW_TYPE_SW, StripOverlapped); -} - -#ifndef NO_OPENGL void YACReaderOptionsDialog::setClassicConfig() { gl->setValues(presetYACReaderFlowClassicConfig); saveFlowParameters(); - settings->setValue(FLOW_TYPE_GL, CoverFlowLike); + settings->setValue(FLOW_TYPE_GL, YACReader::CoverFlowLike); } void YACReaderOptionsDialog::setStripeConfig() @@ -357,7 +291,7 @@ void YACReaderOptionsDialog::setStripeConfig() saveFlowParameters(); - settings->setValue(FLOW_TYPE_GL, Strip); + settings->setValue(FLOW_TYPE_GL, YACReader::Strip); } void YACReaderOptionsDialog::setOverlappedStripeConfig() @@ -366,7 +300,7 @@ void YACReaderOptionsDialog::setOverlappedStripeConfig() saveFlowParameters(); - settings->setValue(FLOW_TYPE_GL, StripOverlapped); + settings->setValue(FLOW_TYPE_GL, YACReader::StripOverlapped); } void YACReaderOptionsDialog::setModernConfig() @@ -375,7 +309,7 @@ void YACReaderOptionsDialog::setModernConfig() saveFlowParameters(); - settings->setValue(FLOW_TYPE_GL, Modern); + settings->setValue(FLOW_TYPE_GL, YACReader::Modern); } void YACReaderOptionsDialog::setRouletteConfig() @@ -384,6 +318,5 @@ void YACReaderOptionsDialog::setRouletteConfig() saveFlowParameters(); - settings->setValue(FLOW_TYPE_GL, Roulette); + settings->setValue(FLOW_TYPE_GL, YACReader::Roulette); } -#endif diff --git a/custom_widgets/yacreader_options_dialog.h b/custom_widgets/yacreader_options_dialog.h index 4669e0d6..44a0b9a9 100644 --- a/custom_widgets/yacreader_options_dialog.h +++ b/custom_widgets/yacreader_options_dialog.h @@ -3,10 +3,7 @@ #include -class YACReaderFlowConfigWidget; -#ifndef NO_OPENGL -class YACReaderGLFlowConfigWidget; -#endif +class YACReader3DFlowConfigWidget; class QCheckBox; class QPushButton; class QSettings; @@ -16,11 +13,7 @@ class YACReaderOptionsDialog : public QDialog { Q_OBJECT protected: - YACReaderFlowConfigWidget *sw; -#ifndef NO_OPENGL - YACReaderGLFlowConfigWidget *gl; - QCheckBox *useGL; -#endif + YACReader3DFlowConfigWidget *gl; QPushButton *accept; QPushButton *cancel; @@ -37,10 +30,8 @@ public slots: virtual void restoreOptions(); virtual void saveOptions(); protected slots: -#ifndef NO_OPENGL virtual void savePerformance(int value); virtual void saveUseVSync(int b); - virtual void saveUseGL(int b); virtual void saveXRotation(int value); virtual void saveYPosition(int value); virtual void saveCoverDistance(int value); @@ -59,10 +50,6 @@ protected slots: virtual void setModernConfig(); virtual void setRouletteConfig(); virtual void saveFlowParameters(); -#endif - virtual void setClassicConfigSW(); - virtual void setStripeConfigSW(); - virtual void setOverlappedStripeConfigSW(); signals: void optionsChanged();