From 02fbabff5c4d53fa224ec0d1239c4594316ce341 Mon Sep 17 00:00:00 2001 From: jkriege2 Date: Fri, 26 Aug 2022 12:31:27 +0200 Subject: [PATCH] added Code+CMake facilities to auto-generate screenshots --- doc/CMakeLists.txt | 35 +++++ examples/CMakeLists.txt | 5 + examples/libexampletools/CMakeLists.txt | 55 +++++++ .../jkqtpexampleapplication.cpp | 138 ++++++++++++++++++ .../libexampletools/jkqtpexampleapplication.h | 26 ++++ examples/libexampletools/libexampletools.pri | 14 ++ 6 files changed, 273 insertions(+) create mode 100644 examples/libexampletools/CMakeLists.txt create mode 100644 examples/libexampletools/jkqtpexampleapplication.cpp create mode 100644 examples/libexampletools/jkqtpexampleapplication.h create mode 100644 examples/libexampletools/libexampletools.pri diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 9420373733..3a6d6c8f80 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -57,3 +57,38 @@ if(JKQtPlotter_BUILD_TOOLS) add_dependencies(JKQTMathText_GenerateDocImages JKQTMathText_GenerateDocImages_listsymbols) endif() + + + + + + + +if(JKQtPlotter_BUILD_EXAMPLES) + + # custom target that generates the images for the JKQTMathText documentation + set(JKQTPlotter_GenerateDocScreenshots_DefaultOptions --screenshotdir="${CMAKE_CURRENT_LIST_DIR}/../screenshots/" --screenshot --smallscreenshotplot) + set(JKQTPlotter_GenerateDocScreenshots_From + ) + + add_custom_target(JKQTPlotter_GenerateDocScreenshots + COMMENT "Building JKQTPlotter Documentation Screenshots ..." + ) + + foreach(example ${JKQTPlotter_GenerateDocScreenshots_From}) + set(loc_target_name JKQTPlotter_GenerateDocScreenshots_${example}) + set(dep_name jkqtptest_${example}) + add_custom_target(${loc_target_name} + COMMENT "Building JKQTPlotter Documentation Screenshot: ${loc_name_upper}" + COMMAND $ ${JKQTPlotter_GenerateDocScreenshots_DefaultOptions} --screenshotbasename=${example} + WORKING_DIRECTORY ${JKQtPlotter_QT_BINDIR} + DEPENDS ${dep_name} + ) + + add_dependencies(JKQTPlotter_GenerateDocScreenshots ${loc_target_name}) + + unset(loc_target_name) + unset(dep_name) + endforeach() + +endif() diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index eb6fd3b84e..767f7bd0f2 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -25,6 +25,11 @@ message( STATUS "............................................................... +# examples for libexampletools +message( STATUS ".. BUILDING EXAMPLE TOOLS LIB:" ) +add_subdirectory(libexampletools) + + # examples for JKQtFastPlotter message( STATUS ".. BUILDING EXAMPLES FOR JKQTFASTPLOTTER:" ) add_subdirectory(jkqtfastplotter_test) diff --git a/examples/libexampletools/CMakeLists.txt b/examples/libexampletools/CMakeLists.txt new file mode 100644 index 0000000000..72313a0a6d --- /dev/null +++ b/examples/libexampletools/CMakeLists.txt @@ -0,0 +1,55 @@ +cmake_minimum_required(VERSION 3.15) + +set(libBasename JKQTPExampleTools) + +set(lib_name ${libBasename}Lib) +message( STATUS "-- Building ${lib_name}" ) + +set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + +# Set up source files +set(SOURCES + ${CMAKE_CURRENT_LIST_DIR}/jkqtpexampleapplication.cpp +) + +set(HEADERS + ${CMAKE_CURRENT_LIST_DIR}/jkqtpexampleapplication.h +) + + +include(CMakePackageConfigHelpers) + +function(jkqtpexampletools_setDefaultLibOptions TARGETNAME) + set_property(TARGET ${TARGETNAME} PROPERTY VERSION "${PROJECT_VERSION}") + target_link_libraries(${TARGETNAME} PUBLIC Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Widgets) + set_property(TARGET ${TARGETNAME} PROPERTY CXX_STANDARD ${JKQtPlotter_QT_CXX_STANDARD}) + set_property(TARGET ${TARGETNAME} PROPERTY CXX_STANDARD_REQUIRED ${JKQtPlotter_QT_CXX_STANDARD_REQUIRED}) + target_compile_features(${TARGETNAME} PUBLIC ${JKQtPlotter_QT_CXX_COMPILE_FEATURE}) + + if(MINGW) + # COMPILER-SETTINGS FOR MINGW + target_compile_options(${TARGETNAME} PUBLIC -fexceptions) + elseif(MSVC) + # COMPILER-SETTINGS FOR MS VISUAL C++ + target_compile_options(${TARGETNAME} PUBLIC /EHsc) + target_compile_definitions(${TARGETNAME} PUBLIC NOMINMAX) + endif() + target_include_directories(${TARGETNAME} PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/../ + ${CMAKE_CURRENT_LIST_DIR} + ) +endfunction() + + +add_library(${lib_name} STATIC ${SOURCES} ${RESOURCES} ${HEADERS}) +jkqtpexampletools_setDefaultLibOptions(${lib_name}) +if(JKQtPlotter_BUILD_STATIC_LIBS) + target_link_libraries(${lib_name} PUBLIC JKQTPlotterLib) +elseif(JKQtPlotter_BUILD_SHARED_LIBS) + target_link_libraries(${lib_name} PUBLIC JKQTPlotterSharedLib) +endif() +write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${lib_name}Version.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY AnyNewerVersion ) + + diff --git a/examples/libexampletools/jkqtpexampleapplication.cpp b/examples/libexampletools/jkqtpexampleapplication.cpp new file mode 100644 index 0000000000..b35279b9d0 --- /dev/null +++ b/examples/libexampletools/jkqtpexampleapplication.cpp @@ -0,0 +1,138 @@ +#include "jkqtpexampleapplication.h" +#include +#include +#include +#include +#include +#include "jkqtplotter/jkqtplotter.h" + + +JKQTPExampleApplication::JKQTPExampleApplication(int &argc, char **argv): + QApplication(argc, argv), + saveScreenshot(false), + saveSmallScreenshot(false), + saveScreenshotPlot(false), + saveSmallScreenshotPlot(false), + screenshotBasename("screenshot") +{ + screenshotDir=QDir::current(); + +} + +JKQTPExampleApplication::~JKQTPExampleApplication() +{ + +} + +void JKQTPExampleApplication::readCmdLine() { + QCommandLineParser parser; + parser.setApplicationDescription(QString("JKQTPlotter example program '%1'").arg(applicationName())); + parser.addHelpOption(); + parser.addVersionOption(); + QCommandLineOption outputDirectoryOption("screenshotdir", "write results into this directory.", "outputdir", applicationDirPath()); + parser.addOption(outputDirectoryOption); + QCommandLineOption basenameOption("screenshotbasename", "basename for screenshots.", "basename", QFileInfo(applicationFilePath()).baseName()); + parser.addOption(basenameOption); + QCommandLineOption screenshotOption(QStringList()<<"screenshot", "save screenshot(s) of the window(s)."); + parser.addOption(screenshotOption); + QCommandLineOption smallscreenshotOption(QStringList()<<"smallscreenshot", "save small screenshot(s) of the window(s)."); + parser.addOption(smallscreenshotOption); + QCommandLineOption screenshotPlotOption(QStringList()<<"screenshotplot", "save screenshot(s) of the plot(s)."); + parser.addOption(screenshotPlotOption); + QCommandLineOption smallscreenshotPlotOption(QStringList()<<"smallscreenshotplot", "save screenshot(s) of the plot(s)."); + parser.addOption(smallscreenshotPlotOption); + + parser.process(*this); + + screenshotDir=QDir(parser.value(outputDirectoryOption)); + screenshotBasename=parser.value(basenameOption); + saveScreenshot = parser.isSet(screenshotOption); + saveSmallScreenshot = parser.isSet(smallscreenshotOption); + saveScreenshotPlot = parser.isSet(screenshotPlotOption); + saveSmallScreenshotPlot = parser.isSet(smallscreenshotPlotOption); +} + +QRect JKQTPExampleApplication::getBoundsWithoutColor(QImage qImage, const QColor &exclusionColor) +{ + QRect ofTheKing; + + int maxX = 0; int minX = qImage.width(); + int maxY = 0; int minY = qImage.height(); + + for(int x=0; x < qImage.width(); x++) + for(int y=0; y < qImage.height(); y++) + if (QColor::fromRgb(qImage.pixel(x, y)) != exclusionColor) + { + if(x < minX) minX = x; + if(x > maxX) maxX = x; + if(y < minY) minY = y; + if(y > maxY) maxY = y; + } + + if (minX > maxX || minY > maxY) + ofTheKing=QRect(); + else + ofTheKing.setCoords(minX, minY, maxX+1, maxY+1); + + return ofTheKing; + } + +int JKQTPExampleApplication::exec() +{ + readCmdLine(); + if (saveScreenshot||saveSmallScreenshot) { + QElapsedTimer timer; + timer.start(); + while(timer.elapsed()<150) { + QApplication::processEvents(); + } + QWidgetList widgets=topLevelWidgets(); + int iVisible=0; + for (int i=0; iisVisible()) { + JKQTPlotter* plot=dynamic_cast(w); + QString bn=screenshotBasename; + if (iVisible>0) { + bn+=QString("_win%1").arg(iVisible, 2, 10, QLatin1Char('0')); + } + if (w) { + QPixmap pix_win=w->grab(); + /*QPixmap pix; + if (screenshotIncludeWindowTitle) { + pix=w->screen()->grabWindow(0, w->frameGeometry().x(), w->frameGeometry().y(), w->frameGeometry().width(), w->frameGeometry().height()); + } else { + pix=pix_win; + }*/ + if (saveScreenshot) { + pix_win.save(screenshotDir.absoluteFilePath(bn+".png")); + } + if (saveSmallScreenshot) { + QPixmap img=pix_win.scaledToWidth(150, Qt::SmoothTransformation); + img.save(screenshotDir.absoluteFilePath(bn+"_small.png")); + } + } + if (plot) { + QString bnp=bn+"_plot"; + QImage gr=plot->grabPixelImage(); + + if (saveScreenshotPlot) { + QString fn=bn+"_small.png"; + if (saveScreenshot) fn=bnp+"_small.png"; + gr.save(screenshotDir.absoluteFilePath(fn)); + } + if (saveSmallScreenshotPlot) { + QString fn=bn+"_small.png"; + if (saveSmallScreenshot) fn=bnp+"_small.png"; + QImage img=gr.scaledToWidth(150, Qt::SmoothTransformation); + img.save(screenshotDir.absoluteFilePath(fn)); + } + } + iVisible++; + } + } + return 0; + } else { + return QApplication::exec(); + } +} diff --git a/examples/libexampletools/jkqtpexampleapplication.h b/examples/libexampletools/jkqtpexampleapplication.h new file mode 100644 index 0000000000..67f1b5ddb6 --- /dev/null +++ b/examples/libexampletools/jkqtpexampleapplication.h @@ -0,0 +1,26 @@ +#pragma once +#include +#include "jkqtplotter/jkqtplotter.h" +#include + + + +class JKQTPExampleApplication: public QApplication { + Q_OBJECT +public: + JKQTPExampleApplication(int &argc, char **argv); + + virtual ~JKQTPExampleApplication(); + + int exec(); + +protected: + QDir screenshotDir; + bool saveScreenshot; + bool saveSmallScreenshot; + bool saveScreenshotPlot; + bool saveSmallScreenshotPlot; + QString screenshotBasename; + void readCmdLine(); + QRect getBoundsWithoutColor(QImage qImage, const QColor &exclusionColor = Qt::white); +}; diff --git a/examples/libexampletools/libexampletools.pri b/examples/libexampletools/libexampletools.pri new file mode 100644 index 0000000000..e562b87238 --- /dev/null +++ b/examples/libexampletools/libexampletools.pri @@ -0,0 +1,14 @@ + +isEmpty(JKQTP_LIBEXAMPLETOOLS_PRI_INCLUDED) { + JKQTP_LIBEXAMPLETOOLS_PRI_INCLUDED = 1 + + INCLUDEPATH += $PWD + + + HEADERS += $$PWD/jkqtpexampleapplication.h + + + SOURCES += $$PWD/jkqtpexampleapplication.cpp + + +}