diff --git a/YACReader/YACReader.pri b/YACReader/YACReader.pri index a894b7f4..446932e8 100644 --- a/YACReader/YACReader.pri +++ b/YACReader/YACReader.pri @@ -4,6 +4,12 @@ INCLUDEPATH += . INCLUDEPATH += $$PWD/../common \ $$PWD/../custom_widgets +CONFIG(legacy_gl_widget) { + INCLUDEPATH += ../common/gl_legacy \ +} else { + INCLUDEPATH += ../common/gl \ +} + win32 { LIBS += -L$$PWD/../dependencies/poppler/lib -loleaut32 -lole32 @@ -94,8 +100,13 @@ HEADERS += $$PWD/../common/comic.h \ $$PWD/../common/scroll_management.h !CONFIG(no_opengl) { - HEADERS += $$PWD/goto_flow_gl.h \ - $$PWD/../common/yacreader_flow_gl.h + CONFIG(legacy_gl_widget) { + message("using legacy YACReaderFlowGL (QGLWidget) header") + HEADERS += ../common/gl_legacy/yacreader_flow_gl.h + } else { + HEADERS += ../common/gl/yacreader_flow_gl.h + } + HEADERS += $$PWD/goto_flow_gl.h } SOURCES += $$PWD/../common/comic.cpp \ @@ -132,8 +143,13 @@ SOURCES += $$PWD/../common/comic.cpp \ $$PWD/../common/scroll_management.cpp !CONFIG(no_opengl) { - SOURCES += $$PWD/goto_flow_gl.cpp \ - $$PWD/../common/yacreader_flow_gl.cpp + CONFIG(legacy_gl_widget) { + message("using legacy YACReaderFlowGL (QGLWidget) source code") + SOURCES += ../common/gl_legacy/yacreader_flow_gl.cpp + } else { + SOURCES += ../common/gl/yacreader_flow_gl.cpp + } + SOURCES += $$PWD/goto_flow_gl.cpp } include($$PWD/../custom_widgets/custom_widgets_yacreader.pri) diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index c9af2ffb..1d8a350e 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -888,58 +888,6 @@ void MainWindowViewer::toggleFullScreen() Configuration::getConfiguration().setFullScreen(fullscreen = !fullscreen); } -//QTBUG-41883 -#ifdef Q_OS_WIN -void MainWindowViewer::toFullScreen() -{ - _size = size(); - _pos = pos(); - hide(); - fromMaximized = this->isMaximized(); - - hideToolBars(); - viewer->hide(); - viewer->fullscreen = true;//TODO, change by the right use of windowState(); - - setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); - setWindowState(windowState() | Qt::WindowFullScreen); - resize(windowHandle()->screen()->size()-QSize(0,1)); - - viewer->show(); - if(viewer->magnifyingGlassIsVisible()) - viewer->showMagnifyingGlass(); - - show(); -} - -//QTBUG-41883 -void MainWindowViewer::toNormal() -{ - hide(); - //show all - viewer->hide(); - viewer->fullscreen = false;//TODO, change by the right use of windowState(); - //viewer->hideMagnifyingGlass(); - setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint); - setWindowState(windowState() & ~Qt::WindowFullScreen); - resize(_size); - move(_pos); - if(fromMaximized) - showMaximized(); - else - showNormal(); - - if(Configuration::getConfiguration().getShowToolbars()) - showToolBars(); - viewer->show(); - if(viewer->magnifyingGlassIsVisible()) - viewer->showMagnifyingGlass(); - - show(); -} - -#else - void MainWindowViewer::toFullScreen() { fromMaximized = this->isMaximized(); @@ -971,8 +919,6 @@ void MainWindowViewer::toNormal() viewer->showMagnifyingGlass(); } -#endif - void MainWindowViewer::toggleToolBars() { toolbars?hideToolBars():showToolBars(); diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 0efa4369..bd0659ba 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -16,9 +16,15 @@ INCLUDEPATH += ../common \ DEFINES += SERVER_RELEASE NOMINMAX YACREADER_LIBRARY CONFIG(no_opengl) { - DEFINES += NO_OPENGL + DEFINES += NO_OPENGL } - + +CONFIG(legacy_gl_widget) { + INCLUDEPATH += ../common/gl_legacy \ +} else { + INCLUDEPATH += ../common/gl \ +} + win32 { LIBS += -L../dependencies/poppler/lib -loleaut32 -lole32 -lshell32 @@ -135,8 +141,13 @@ HEADERS += comic_flow.h \ ../common/scroll_management.h !CONFIG(no_opengl) { - HEADERS += ../common/yacreader_flow_gl.h - } + CONFIG(legacy_gl_widget) { + message("using legacy YACReaderFlowGL (QGLWidget) header") + HEADERS += ../common/gl_legacy/yacreader_flow_gl.h + } else { + HEADERS += ../common/gl/yacreader_flow_gl.h + } +} SOURCES += comic_flow.cpp \ create_library_dialog.cpp \ @@ -198,7 +209,12 @@ SOURCES += comic_flow.cpp \ ../common/scroll_management.cpp !CONFIG(no_opengl) { - SOURCES += ../common/yacreader_flow_gl.cpp + CONFIG(legacy_gl_widget) { + message("using legacy YACReaderFlowGL (QGLWidget) source code") + SOURCES += ../common/gl_legacy/yacreader_flow_gl.cpp + } else { + SOURCES += ../common/gl/yacreader_flow_gl.cpp + } } diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 63d0a54c..2b620a09 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -2085,64 +2085,6 @@ void LibraryWindow::toggleFullScreen() fullscreen = !fullscreen; } -#ifdef Q_OS_WIN - -//QTBUG-41883 -void LibraryWindow::toFullScreen() -{ - _size = size(); - _pos = pos(); - hide(); - - fromMaximized = this->isMaximized(); - - sideBar->hide(); - libraryToolBar->hide(); - - comicsView->toFullScreen(); - - setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); - setWindowState(windowState() | Qt::WindowFullScreen); - resize(windowHandle()->screen()->size()-QSize(0,1)); - - show(); -} - -//QTBUG-41883 -void LibraryWindow::toNormal() -{ - hide(); - - sideBar->show(); - - comicsView->toNormal(); - - setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint); - setWindowState(windowState() & ~Qt::WindowFullScreen); - resize(_size); - move(_pos); - - if(fromMaximized) - showMaximized(); - else - showNormal(); - -#ifdef Q_OS_MAC - QTimer * timer = new QTimer(); - timer->setSingleShot(true); - timer->start(); - connect(timer,SIGNAL(timeout()),libraryToolBar,SLOT(show())); - connect(timer,SIGNAL(timeout()),timer,SLOT(deleteLater())); -#else - libraryToolBar->show(); -#endif - - show(); - -} - -#else - void LibraryWindow::toFullScreen() { fromMaximized = this->isMaximized(); @@ -2178,8 +2120,6 @@ void LibraryWindow::toNormal() } -#endif - void LibraryWindow::setSearchFilter(const YACReader::SearchModifiers modifier, QString filter) { if(!filter.isEmpty()) diff --git a/common/yacreader_flow_gl.cpp b/common/gl/yacreader_flow_gl.cpp similarity index 100% rename from common/yacreader_flow_gl.cpp rename to common/gl/yacreader_flow_gl.cpp diff --git a/common/yacreader_flow_gl.h b/common/gl/yacreader_flow_gl.h similarity index 100% rename from common/yacreader_flow_gl.h rename to common/gl/yacreader_flow_gl.h diff --git a/common/gl_legacy/yacreader_flow_gl.cpp b/common/gl_legacy/yacreader_flow_gl.cpp new file mode 100644 index 00000000..c585189b --- /dev/null +++ b/common/gl_legacy/yacreader_flow_gl.cpp @@ -0,0 +1,1593 @@ +#include "yacreader_flow_gl.h" + +#include +#include +//#include + +#ifdef Q_OS_MAC + #include +#else + #include +#endif + +#include +#include +#include + +/*** Animation Settings ***/ + +/*** Position Configuration ***/ + +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) + :QGLWidget(QGLFormat(QGL::SampleBuffers), parent),numObjects(0),lazyPopulateObjects(-1),bUseVSync(false),hasBeenInitialized(false) +{ + updateCount = 0; + config = p; + + currentSelected = 0; + + centerPos.x = 0.f; + centerPos.y = 0.f; + centerPos.z = 1.f; + centerPos.rot = 0.f; + + /*** Style ***/ + shadingTop = 0.8f; + shadingBottom = 0.02f; + reflectionUp = 0.f; + reflectionBottom = 0.6f; + + /*** System variables ***/ + numObjects = 0; + //CFImage Dummy; + viewRotate = 0.f; + viewRotateActive = 0; + stepBackup = config.animationStep/config.animationSpeedUp; + + /*QTimer * timer = new QTimer(); + connect(timer, SIGNAL(timeout()), this, SLOT(updateImageData())); + timer->start(70); + */ + + /*loader = new WidgetLoader(0,this); + loader->flow = this; + QThread * loaderThread = new QThread(parent); + + loader->moveToThread(loaderThread); + + loaderThread->start();*/ + + QGLFormat f = format(); + f.setVersion(2, 1); + f.setSwapInterval(0); + setFormat(f); + + timerId = startTimer(updateInterval); + +} + +void YACReaderFlowGL::timerEvent(QTimerEvent * event) +{ + if(timerId == event->timerId()) + updateGL(); + + //if(!worker->isRunning()) + //worker->start(); +} + +void YACReaderFlowGL::startAnimationTimer() +{ + if(timerId == -1) + timerId = startTimer(updateInterval); +} + +void YACReaderFlowGL::stopAnimationTimer() +{ + if(timerId != -1) + { + killTimer(timerId); + timerId = -1; + } +} + +YACReaderFlowGL::~YACReaderFlowGL() +{ + +} + +QSize YACReaderFlowGL::minimumSizeHint() const +{ + return QSize(320, 200); +} + +/*QSize YACReaderFlowGL::sizeHint() const +{ + return QSize(320, 200); +}*/ + +void YACReaderFlowGL::initializeGL() +{ + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_COLOR_MATERIAL); + glShadeModel(GL_SMOOTH); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + defaultTexture = bindTexture(QImage(":/images/defaultCover.png"),GL_TEXTURE_2D,GL_RGBA,QGLContext::LinearFilteringBindOption | QGLContext::MipmapBindOption); + markTexture = bindTexture(QImage(":/images/readRibbon.png"),GL_TEXTURE_2D,GL_RGBA,QGLContext::LinearFilteringBindOption | QGLContext::MipmapBindOption); + readingTexture = bindTexture(QImage(":/images/readingRibbon.png"),GL_TEXTURE_2D,GL_RGBA,QGLContext::LinearFilteringBindOption | QGLContext::MipmapBindOption); + if(lazyPopulateObjects!=-1) + populate(lazyPopulateObjects); + + hasBeenInitialized = true; +} + +void YACReaderFlowGL::paintGL() +{ + /*glClearDepth(1.0); + glClearColor(1,1,1,1);*/ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + /*glLoadIdentity(); + glTranslatef(0.0, 0.0, -10.0); + glPopMatrix();*/ + if(numObjects>0) + { + updatePositions(); + udpatePerspective(width(),height()); + draw(); + } +} + +void YACReaderFlowGL::resizeGL(int width, int height) +{ + + fontSize = (width + height) * 0.010; + if(fontSize < 10) + fontSize = 10; + + //int side = qMin(width, height); + udpatePerspective(width,height); + + if(numObjects>0) + updatePositions(); +} + +void YACReaderFlowGL::udpatePerspective(int width, int height) +{ + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + gluPerspective(20.0, GLdouble(width) / (float)height, 1.0, 200.0); + + glMatrixMode(GL_MODELVIEW); +} + +//----------------------------------------------------------------------------- +/*Private*/ +void YACReaderFlowGL::calcPos(YACReader3DImage & image, int pos) +{ + 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 & currentVector,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; + + //calculate and apply positions + 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) +{ + float w = image.width; + float h = image.height; + + //fadeout + float opacity = 1-1/(config.animationFadeOutDist+config.viewRotateLightStrenght*fabs(viewRotate))*fabs(0-image.current.x); + + glLoadIdentity(); + glTranslatef(config.cfX,config.cfY,config.cfZ); + glRotatef(config.cfRX,1,0,0); + glRotatef(viewRotate*config.viewAngle+config.cfRY,0,1,0); + glRotatef(config.cfRZ,0,0,1); + + glTranslatef( image.current.x, image.current.y, image.current.z ); + + glPushMatrix(); + glRotatef(image.current.rot,0,1,0); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, image.texture); + + //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;; + + + //DrawCover + glBegin(GL_QUADS); + + //esquina inferior izquierda + glColor4f(LDOWN*opacity,LDOWN*opacity,LDOWN*opacity,1); + glTexCoord2f(0.0f, 1.0f); + glVertex3f(w/2.f*-1.f, -0.5f, 0.f); + + //esquina inferior derecha + glColor4f(RDOWN*opacity,RDOWN*opacity,RDOWN*opacity,1); + glTexCoord2f(1.0f, 1.0f); + glVertex3f(w/2.f, -0.5f, 0.f); + + //esquina superior derecha + glColor4f(RUP*opacity,RUP*opacity,RUP*opacity,1); + glTexCoord2f(1.0f, 0.0f); + glVertex3f(w/2.f, -0.5f+h, 0.f); + + //esquina superior izquierda + glColor4f(LUP*opacity,LUP*opacity,LUP*opacity,1); + glTexCoord2f(0.0f, 0.0f); + glVertex3f(w/2.f*-1.f, -0.5f+h, 0.f); + + glEnd(); + + + + //Draw reflection + glBegin(GL_QUADS); + + //esquina inferior izquierda + glColor4f(LUP*opacity*reflectionUp/2,LUP*opacity*reflectionUp/2,LUP*opacity*reflectionUp/2,1); + glTexCoord2f(0.0f, 0.0f); + glVertex3f(w/2.f*-1.f, -0.5f-h, 0.f); + + //esquina inferior derecha + glColor4f(RUP*opacity*reflectionUp/2,RUP*opacity*reflectionUp/2,RUP*opacity*reflectionUp/2,1); + glTexCoord2f(1.0f, 0.0f); + glVertex3f(w/2.f, -0.5f-h, 0.f); + + //esquina superior derecha + glColor4f(RDOWN*opacity/3,RDOWN*opacity/3,RDOWN*opacity/3,1); + glTexCoord2f(1.0f, 1.0f); + glVertex3f(w/2.f, -0.5f, 0.f); + + //esquina superior izquierda + glColor4f(LDOWN*opacity/3,LDOWN*opacity/3,LDOWN*opacity/3,1); + glTexCoord2f(0.0f, 1.0f); + glVertex3f(w/2.f*-1.f, -0.5f, 0.f); + + glEnd(); + glDisable(GL_TEXTURE_2D); + + if(showMarks && loaded[image.index] && marks[image.index] != Unread) + { + glEnable(GL_TEXTURE_2D); + if(marks[image.index] == Read) + glBindTexture(GL_TEXTURE_2D, markTexture); + else + glBindTexture(GL_TEXTURE_2D, readingTexture); + glBegin(GL_QUADS); + + //esquina inferior izquierda + glColor4f(RUP*opacity,RUP*opacity,RUP*opacity,1); + glTexCoord2f(0.0f, 1.0f); + glVertex3f(w/2.f-0.2, -0.685f+h, 0.001f); + + //esquina inferior derecha + glColor4f(RUP*opacity,RUP*opacity,RUP*opacity,1); + glTexCoord2f(1.0f, 1.0f); + glVertex3f(w/2.f-0.05, -0.685f+h, 0.001f); + + //esquina superior derecha + glColor4f(RUP*opacity,RUP*opacity,RUP*opacity,1); + glTexCoord2f(1.0f, 0.0f); + glVertex3f(w/2.f-0.05, -0.485f+h, 0.001f); + + //esquina superior izquierda + glColor4f(RUP*opacity,RUP*opacity,RUP*opacity,1); + glTexCoord2f(0.0f, 0.0f); + glVertex3f(w/2.f-0.2, -0.485f+h, 0.001f); + + glEnd(); + glDisable(GL_TEXTURE_2D); + } + + + glPopMatrix(); +} + +/*Public*/ +void YACReaderFlowGL::cleanupAnimation() +{ + config.animationStep = stepBackup; + viewRotateActive = 0; +} + +void YACReaderFlowGL::draw() +{ + int CS = currentSelected; + int count; + + + //Draw right Covers + for(count = numObjects-1;count > -1;count--){ + if(count > CS){ + drawCover(images[count]); + } + } + + //Draw left Covers + for(count = 0;count < numObjects-1;count++){ + if(count < CS){ + drawCover(images[count]); + } + } + + //Draw Center Cover + drawCover(images[CS]); + + //glDisable(GL_DEPTH_TEST); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(-(float(width())/height())/2.0,(float(width())/height())/2.0, 0, 1, -10, 10); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glColor4f( 0.3f, 0.3f, 0.3f, 1.0f ); + + renderText(10, fontSize + 10,QString("%1/%2").arg(currentSelected+1).arg(numObjects),QFont("Arial", fontSize)); + + glEnable(GL_DEPTH_TEST); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); +} + +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; + } + + //slowly reset view angle + if(!viewRotateActive){ + viewRotate += (0-viewRotate)*config.viewRotateSub; + } + + if(fabs (images[currentSelected].current.x - images[currentSelected].animEnd.x) < 1)//viewRotate < 0.2) + { + cleanupAnimation(); + if(updateCount >= 0) //TODO parametrizar + { + + updateCount = 0; + updateImageData(); + } + else + updateCount++; + } + else + updateCount++; + + if(stopAnimation) + stopAnimationTimer(); + +} + +void YACReaderFlowGL::insert(const char *name, GLuint texture, float x, float y,int item) +{ + startAnimationTimer(); + + Q_UNUSED(name) + //set a new entry + 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; + //strcpy(cfImages[item].name,name); +} + +void YACReaderFlowGL::remove(int item) +{ + if(item < 0 || item >= images.size()) + return; + + startAnimationTimer(); + + loaded.remove(item); + marks.remove(item); + + //reposition current selection + if(item <= currentSelected && currentSelected != 0){ + currentSelected--; + } + + int count = item; + while(count <= numObjects-2){ + images[count].index--; + count++; + } + images.removeAt(item); + + + numObjects--; +} + +/*Info*/ +YACReader3DImage YACReaderFlowGL::getCurrentSelected() +{ + return images[currentSelected]; +} + +void YACReaderFlowGL::replace(const char *name, GLuint 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,false); + //marks = QVector(n,false); + + + + //worker->start(); +} + +void YACReaderFlowGL::reset() +{ + startAnimationTimer(); + + currentSelected = 0; + loaded.clear(); + + for(int i = 0;iwidth(); + int height = this->height(); + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + //float sideX = ((float(width)/height)/2)*1.5; + //float sideY = 0.5*1.5; + gluPerspective(zoom, (float)width / (float)height, 1.0, 200.0); + //glOrtho(-sideX, sideX, -sideY+0.2, +sideY+0.2, 4, 11.0); + + glMatrixMode(GL_MODELVIEW); + +} + +void YACReaderFlowGL::setRotation(int angle) +{ + startAnimationTimer(); + + config.rotation = -angle; +} +//sets the distance between the covers +void YACReaderFlowGL::setX_Distance(int distance) +{ + startAnimationTimer(); + + config.xDistance = distance/100.0; +} +//sets the distance between the centered and the non centered covers +void YACReaderFlowGL::setCenter_Distance(int distance) +{ + startAnimationTimer(); + + config.centerDistance = distance/100.0; +} +//sets the pushback amount +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::setPerformance(Performance performance) +{ + if(this->performance != performance) + { + startAnimationTimer(); + + this->performance = performance; + reload(); + } +} + +void YACReaderFlowGL::useVSync(bool b) +{ + if(bUseVSync != b) + { + bUseVSync = b; + if(b) + { + QGLFormat f = format(); + f.setVersion(2, 1); + f.setSwapInterval(1); + setFormat(f); + } + else + { + QGLFormat f = format(); + f.setVersion(2, 1); + f.setSwapInterval(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); + //qué pasa la primera vez?? + //deleteTexture(markTexture); + //markTexture = bindTexture(image,GL_TEXTURE_2D,GL_RGBA,QGLContext::LinearFilteringBindOption | QGLContext::MipmapBindOption); +} +void YACReaderFlowGL::markSlide(int index, YACReaderComicReadStatus status) +{ + startAnimationTimer(); + + marks[index] = status; +} +void YACReaderFlowGL::unmarkSlide(int index) +{ + startAnimationTimer(); + + marks[index] = YACReader::Unread; +} +void YACReaderFlowGL::setSlideSize(QSize size) +{ + Q_UNUSED(size); + //TODO calcular el tamaño del widget +} +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() +{ + //do nothing +} +/*void YACReaderFlowGL::setFlowType(FlowType flowType) +{ + //TODO esperar a que se reimplemente flowtype +}*/ +void YACReaderFlowGL::render() +{ + //do nothing +} + +//EVENTOS +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) + { + if(event->modifiers() == Qt::ControlModifier) + setCurrentIndex((currentSelected-10<0)?0:currentSelected-10); + else + showPrevious(); + event->accept(); + return; + } + + if(event->key() == Qt::Key_Right) + { + if(event->modifiers() == Qt::ControlModifier) + setCurrentIndex((currentSelected+10>=numObjects)?numObjects-1:currentSelected+10); + else + showNext(); + event->accept(); + return; + } + + if(event->key() == Qt::Key_Up) + { + //emit selected(centerIndex()); + return; + } + + event->ignore(); +} + +void YACReaderFlowGL::mousePressEvent(QMouseEvent *event) +{ + if(event->button() == Qt::LeftButton) + { + float x,y; + x = event->x(); + y = event->y(); + GLint viewport[4]; + GLdouble modelview[16]; + GLdouble projection[16]; + GLfloat winX, winY, winZ; + GLdouble posX, posY, posZ; + + glGetDoublev( GL_MODELVIEW_MATRIX, modelview ); + glGetDoublev( GL_PROJECTION_MATRIX, projection ); + glGetIntegerv( GL_VIEWPORT, viewport ); + + winX = (float)x; + winY = (float)viewport[3] - (float)y; + glReadPixels( x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ ); + + gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ); + + if(posX >= 0.5) + { + //int index = currentSelected+1; + //while((cfImages[index].current.x-cfImages[index].width/(2.0*config.rotation)) < posX) + // index++; + //setCurrentIndex(index-1); + showNext(); + } + else if(posX <=-0.5) + showPrevious(); + } else + QGLWidget::mousePressEvent(event); +} + +void YACReaderFlowGL::mouseDoubleClickEvent(QMouseEvent* event) +{ + float x,y; + x = event->x(); + y = event->y(); + GLint viewport[4]; + GLdouble modelview[16]; + GLdouble projection[16]; + GLfloat winX, winY, winZ; + GLdouble posX, posY, posZ; + + glGetDoublev( GL_MODELVIEW_MATRIX, modelview ); + glGetDoublev( GL_PROJECTION_MATRIX, projection ); + glGetIntegerv( GL_VIEWPORT, viewport ); + + winX = (float)x; + winY = (float)viewport[3] - (float)y; + glReadPixels( x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ ); + + gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ); + + if(posX <= 0.5 && posX >= -0.5) + { + emit selected(centerIndex()); + event->accept(); + } + +} + +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; + //numObjects = paths.size(); +} + + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +void YACReaderComicFlowGL::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(!loaded[idx]) + { + float x = 1; + QImage img = worker->result(); + GLuint cover; + if(performance == high || performance == ultraHigh) + cover = bindTexture(img, GL_TEXTURE_2D,GL_RGB,QGLContext::LinearFilteringBindOption | QGLContext::MipmapBindOption); + else + cover = bindTexture(img, GL_TEXTURE_2D,GL_RGB,QGLContext::LinearFilteringBindOption); + float y = 1 * (float(img.height())/img.width()); + QString s = "cover"; + replace(s.toLocal8Bit().data(), cover, x, y,idx); + /*CFImages[idx].width = x; + CFImages[idx].height = y; + CFImages[idx].img = worker->resultTexture; + strcpy(CFImages[idx].name,"cover");*/ + //loaded[idx] = true; + //numImagesLoaded++; + } + } + + // try to load only few images on the left and right side + // i.e. all visible ones plus some extra + 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(!loaded[i])//slide(i).isNull()) + { + //loader->loadTexture(i); + //loaded[i]=true; + // schedule thumbnail generation + if(paths.size()>0) + { + QString fname = paths.at(i); + //loaded[i]=true; + + worker->generate(i, fname); + } + delete[] indexes; + return; + } + } +} + +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::resortCovers(QList newOrder) +{ + worker->lock(); + worker->reset();//is this necesary? + startAnimationTimer(); + QList pathsNew; + QVector loadedNew; + QVector marksNew; + QVector imagesNew; + + int index = 0; + foreach (int i, newOrder) { + 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::YACReaderPageFlowGL(QWidget *parent,struct Preset p ) + :YACReaderFlowGL(parent,p) +{ + worker = new ImageLoaderByteArrayGL(this); + worker->flow = this; +} + +YACReaderPageFlowGL::~YACReaderPageFlowGL() +{ + this->killTimer(timerId); + //worker->deleteLater(); + rawImages.clear(); +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +void YACReaderPageFlowGL::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(!loaded[idx]) + { + float x = 1; + QImage img = worker->result(); + GLuint cover; + if(performance == high || performance == ultraHigh) + cover = bindTexture(img, GL_TEXTURE_2D,GL_RGB,QGLContext::LinearFilteringBindOption | QGLContext::MipmapBindOption); + else + cover = bindTexture(img, GL_TEXTURE_2D,GL_RGB,QGLContext::LinearFilteringBindOption); + float y = 1 * (float(img.height())/img.width()); + QString s = "cover"; + replace(s.toLocal8Bit().data(), cover, x, y,idx); + loaded[idx] = true; + + } + } + + // try to load only few images on the left and right side + // i.e. all visible ones plus some extra + 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])//slide(i).isNull()) + { + worker->generate(i, rawImages.at(i)); + + delete[] indexes; + return; + } + } +} + +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); //puede sobrar +} + + +//----------------------------------------------------------------------------- +//ImageLoader +//----------------------------------------------------------------------------- +QImage ImageLoaderGL::loadImage(const QString& fileName) +{ + QImage image; + bool result = image.load(fileName); + + 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; + + } + + if(!result) + return QImage(); + + 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 + { + // already running, wake up whenever ready + restart = true; + condition.wakeOne(); + } +} + +void ImageLoaderGL::lock() +{ + mutex.lock(); +} + +void ImageLoaderGL::unlock() +{ + mutex.unlock(); +} + +void ImageLoaderGL::run() +{ + for(;;) + { + // copy necessary data + mutex.lock(); + this->working = true; + QString fileName = this->fileName; + mutex.unlock(); + + QImage image = loadImage(fileName); + + // let everyone knows it is ready + mutex.lock(); + this->working = false; + this->img = image; + mutex.unlock(); + + // put to sleep + mutex.lock(); + if (!this->restart) + condition.wait(&mutex); + restart = false; + mutex.unlock(); + } +} + +QImage ImageLoaderGL::result() +{ + return img; +} + +//----------------------------------------------------------------------------- +//ImageLoader +//----------------------------------------------------------------------------- +QImage ImageLoaderByteArrayGL::loadImage(const QByteArray& raw) +{ + QImage image; + bool result = image.loadFromData(raw); + + 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; + } + + if(!result) + return QImage(); + + 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 + { + // already running, wake up whenever ready + restart = true; + condition.wakeOne(); + } +} + +void ImageLoaderByteArrayGL::run() +{ + for(;;) + { + // copy necessary data + mutex.lock(); + this->working = true; + QByteArray raw = this->rawData; + mutex.unlock(); + + QImage image = loadImage(raw); + + // let everyone knows it is ready + mutex.lock(); + this->working = false; + this->img = image; + mutex.unlock(); + + // put to sleep + mutex.lock(); + if (!this->restart) + condition.wait(&mutex); + restart = false; + mutex.unlock(); + } +} + +QImage ImageLoaderByteArrayGL::result() +{ + return img; +} + diff --git a/common/gl_legacy/yacreader_flow_gl.h b/common/gl_legacy/yacreader_flow_gl.h new file mode 100644 index 00000000..ba025253 --- /dev/null +++ b/common/gl_legacy/yacreader_flow_gl.h @@ -0,0 +1,380 @@ +//OpenGL Coverflow API by J.Roth +#ifndef __YACREADER_FLOW_GL_H +#define __YACREADER_FLOW_GL_H + +#include +#include +#include +#include + +#include +#include +#include + +#include "pictureflow.h" //TODO mover los tipos de flow de sitio +#include "scroll_management.h" + +class ImageLoaderGL; +class QGLContext; +class WidgetLoader; +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{ + GLuint texture; + //char name[256]; + + 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 QGLWidget, 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); + //returns true if the animation is finished for Current + bool animate(YACReader3DVector ¤tVector, YACReader3DVector &toVector); + void drawCover(const YACReader3DImage & image); + + void udpatePerspective(int width, int height); + + int updateCount; + WidgetLoader * loader; + int fontSize; + + GLuint defaultTexture; + GLuint markTexture; + GLuint readingTexture; + void initializeGL(); + void paintGL(); + void timerEvent(QTimerEvent *); + + //number of Covers + int numObjects; + int lazyPopulateObjects; + bool showMarks; + QVector loaded; + QVector marks; + QVector images; + bool hasBeenInitialized; + + Performance performance; + bool bUseVSync; + + /*** Animation Settings ***/ + Preset config; + + //sets/returns the curent selected cover + int currentSelected; + + //defines the position of the centered cover + YACReader3DVector centerPos; + + /*** Style ***/ + //sets the amount of shading of the covers in the back (0-1) + float shadingTop; + float shadingBottom; + + //sets the reflection strenght (0-1) + float reflectionUp; + float reflectionBottom; + + /*** System info ***/ + float viewRotate; + + //sets the updateInterval in ms + static int updateInterval; + + void startAnimationTimer(); + void stopAnimationTimer(); + +public: + + + /*Constructor*/ + YACReaderFlowGL(QWidget *parent = 0,struct Preset p = pressetYACReaderFlowDownConfig); + virtual ~YACReaderFlowGL(); + + //size; + QSize minimumSizeHint() const; + //QSize sizeHint() const; + + /*functions*/ + + //if called it moves the coverflow to the left + void showPrevious(); + //if called it moves the coverflow to the right + void showNext(); + //go to + void setCurrentIndex(int pos); + //must be called whenever the coverflow animation is stopped + void cleanupAnimation(); + //Draws the coverflow + void draw(); + //updates the coverflow + void updatePositions(); + //inserts a new item to the coverflow + //if item is set to a value > -1 it updates a already set value + //otherwise a new entry is set + void insert(const char *name, GLuint Tex, float x, float y,int item = -1); + //removes a item + virtual void remove(int item); + //replaces the texture of the item 'item' with Tex + void replace(const char *name, GLuint Tex, float x, float y,int item); + //create n covers with the default nu + void populate(int n); + /*Info*/ + //retuns the YACReader3DImage Struct of the current selected item + //to read title or textures + YACReader3DImage getCurrentSelected(); + + 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 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); + + virtual void updateImageData() = 0; + + void reset(); + void reload(); + + //interface with yacreaderlibrary, compatibility + void setShowMarks(bool value); + void setMarks(QVector marks); + void setMarkImage(QImage & image); + void markSlide(int index, 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 setFlowType(PictureFlow::FlowType flowType); + void render(); + + //void paintEvent(QPaintEvent *event); + 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 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(); + // returns FALSE if worker is still busy and can't take the task + 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(); + // returns FALSE if worker is still busy and can't take the task + 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