diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c67c2fc03..fd45e3aa8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -29,7 +29,7 @@ env: # BSD related variables BSD_DEPS: "llvm17 libinotify openal-soft xorg 7-zip cmake-core ninja pkgconf ccache4" - BSD_QT: "qt5-widgets qt5-core qt5-gamepad qt5-gui qt5-svg qt5-xml qt5 qmake" + BSD_QT: "qt5-widgets qt5-core qt5-gui qt5-svg qt5-xml qt5 qmake" BSD_CC: "clang17" BSD_CXX: "clang++17" BSD_VERSION: "14.1" @@ -68,7 +68,7 @@ jobs: - name: Install Qt run: | - sudo ./build/install-qt.sh --version ${QT_VERSION} qtbase qtmultimedia qtscript qtsvg qtimageformats qtgraphicaleffects qtquickcontrols2 qttools qtxmlpatterns qtdeclarative qtgamepad icu | tee -a $GITHUB_PATH + sudo ./build/install-qt.sh --version ${QT_VERSION} qtbase qtmultimedia qtscript qtsvg qtimageformats qttools qtxmlpatterns qtdeclarative icu | tee -a $GITHUB_PATH sudo ./build/install-qt.sh --version ${QTCREATOR_VERSION} qtcreator | tee -a $GITHUB_PATH - name: Setup Qbs @@ -235,7 +235,7 @@ jobs: - name: Install Qt run: | - echo "QT_PATH=$(./build/install-qt.sh -d ${QT_INSTALL_DIR} --version ${QT_VERSION} qtbase qtmultimedia qtscript qtsvg qtimageformats qtgraphicaleffects qtquickcontrols2 qttools qtxmlpatterns qtdeclarative qtgamepad)" >> $GITHUB_ENV + echo "QT_PATH=$(./build/install-qt.sh -d ${QT_INSTALL_DIR} --version ${QT_VERSION} qtbase qtmultimedia qtscript qtsvg qtimageformats qttools qtxmlpatterns qtdeclarative)" >> $GITHUB_ENV - name: Install Qbs run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index 606d89247..3f6cd68b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,22 +75,17 @@ set(INC_PATH "${SDK_PATH}/include") set(TOOLS_PATH "${SDK_PATH}/tools") set(PLUGINS_PATH "${BIN_PATH}/plugins") -if(desktop) - find_package(Qt5 COMPONENTS - Core - Gui - Widgets - QuickWidgets - Xml - Multimedia - Gamepad - Svg - ) - - set(QT_BIN_DIR "$ENV{QT5_DIR}/bin") - set(QT_PLUGINS_DIR "$ENV{QT5_DIR}/plugins") - set(QT_QML_DIR "$ENV{QT5_DIR}/qml") -endif() +find_package(Qt5 COMPONENTS + Core + Gui + Widgets + Xml + Multimedia + Svg +) + +set(QT_BIN_DIR "$ENV{QT5_DIR}/bin") +set(QT_PLUGINS_DIR "$ENV{QT5_DIR}/plugins") # Add subdirectories add_subdirectory(thirdparty) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 35b1ee297..96fc117b8 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -18,47 +18,27 @@ if(desktop) DESTINATION "${PLATFORM_PATH}/plugins" ) - # Install QML plugins - install(DIRECTORY ${QT_QML_DIR}/QtGraphicalEffects - DESTINATION "${PLATFORM_PATH}/qml" - ) - - install(DIRECTORY ${QT_QML_DIR}/QtQuick - DESTINATION "${PLATFORM_PATH}/qml" - ) - - install(DIRECTORY ${QT_QML_DIR}/QtQuick.2 - DESTINATION "${PLATFORM_PATH}/qml" - ) - - set(libPrefix "${QT_BIN_DIR}/") - - if(WIN32) - set(libSuffix "$<$:d>.dll") - endif() - - set(QT_LIBS - "Qt5Core" - "Qt5Gui" - "Qt5Xml" - "Qt5XmlPatterns" - "Qt5Network" - "Qt5Multimedia" - "Qt5QuickWidgets" - "Qt5Quick" - "Qt5QuickTemplates2" - "Qt5QuickShapes" - "Qt5QuickControls2" - "Qt5Qml" - "Qt5Svg" - "Qt5Widgets" - "Qt5Gamepad" - "Qt5Script" - ) - - if (Qt5Core_VERSION VERSION_GREATER_EQUAL 5.14.0) - list(APPEND QT_LIBS "Qt5QmlModels") - list(APPEND QT_LIBS "Qt5QmlWorkerScript") + set(libPrefix "${QT_BIN_DIR}/") + + if(WIN32) + set(libSuffix "$<$:d>.dll") + endif() + + set(QT_LIBS + "Qt5Core" + "Qt5Gui" + "Qt5Xml" + "Qt5XmlPatterns" + "Qt5Network" + "Qt5Multimedia" + "Qt5Svg" + "Qt5Widgets" + "Qt5Script" + ) + + list(TRANSFORM QT_LIBS PREPEND ${libPrefix}) + if(WIN32) + list(TRANSFORM QT_LIBS APPEND ${libSuffix}) endif() list(TRANSFORM QT_LIBS PREPEND ${libPrefix}) diff --git a/build/build-osx.sh b/build/build-osx.sh index 360f75323..541557955 100644 --- a/build/build-osx.sh +++ b/build/build-osx.sh @@ -6,7 +6,7 @@ export QTCREATOR_VERSION=5.0.3 export QT_BIN=$QT_INSTALL_DIR/$QT_VERSION/clang_64/bin export PATH="$QT_INSTALL_DIR/Qt Creator.app/Contents/MacOS:$QT_BIN:$PATH" -./build/install-qt.sh -d $QT_INSTALL_DIR --version $QT_VERSION qtbase qtmultimedia qtscript qtsvg qtimageformats qtgraphicaleffects qtquickcontrols2 qttools qtxmlpatterns qtdeclarative +./build/install-qt.sh -d $QT_INSTALL_DIR --version $QT_VERSION qtbase qtmultimedia qtscript qtsvg qtimageformats qttools qtxmlpatterns qtdeclarative ./build/install-qt.sh -d $QT_INSTALL_DIR --version $QTCREATOR_VERSION qtcreator qbs --version diff --git a/build/build-win.sh b/build/build-win.sh index c265cd0b8..1a6789f84 100644 --- a/build/build-win.sh +++ b/build/build-win.sh @@ -7,7 +7,7 @@ export QTCREATOR_VERSION=5.0.3 export QT_BIN=$QT_INSTALL_DIR/$QT_VERSION/clang_64/bin export PATH="$QT_INSTALL_DIR/Qt Creator.app/Contents/MacOS:$QT_BIN:$PATH" -./build/install-qt.sh -d $QT_INSTALL_DIR --version $QT_VERSION qtbase qtmultimedia qtscript qtsvg qtimageformats qtgraphicaleffects qtquickcontrols2 qttools qtxmlpatterns qtdeclarative +./build/install-qt.sh -d $QT_INSTALL_DIR --version $QT_VERSION qtbase qtmultimedia qtscript qtsvg qtimageformats qttools qtxmlpatterns qtdeclarative ./build/install-qt.sh -d $QT_INSTALL_DIR --version $QTCREATOR_VERSION qtcreator qbs --version diff --git a/build/darwin/qt.conf b/build/darwin/qt.conf index 02408feba..64d729736 100644 --- a/build/darwin/qt.conf +++ b/build/darwin/qt.conf @@ -1,4 +1,2 @@ [Paths] Plugins = PlugIns -Imports = Resources/qml -Qml2Imports = Resources/qml diff --git a/build/install.qbs b/build/install.qbs index 6f312b6f9..3cb452327 100644 --- a/build/install.qbs +++ b/build/install.qbs @@ -28,13 +28,6 @@ Product { return install.PLATFORM_PATH + "/plugins" } - property string QML_PATH: { - if(qbs.targetOS.contains("darwin")) { - return install.BIN_PATH + "/../Resources/qml" - } - - return install.PLATFORM_PATH + "/qml" - } property var pluginFiles: { var files = [] @@ -75,14 +68,8 @@ Product { if (!Qt.core.frameworkBuild) { var libPrefix = (qbs.targetOS.contains("linux")) ? "lib" : "" var libPostfix = ((qbs.targetOS.contains("windows") && qbs.debugInformation) ? "d": "") + cpp.dynamicLibrarySuffix - var libs = ["Qt5Core", "Qt5Gui", "Qt5Xml", - "Qt5XmlPatterns", "Qt5Network", "Qt5Multimedia", - "Qt5QuickWidgets", "Qt5Quick", "Qt5QuickTemplates2", "Qt5QuickShapes", - "Qt5QuickControls2", "Qt5Qml", "Qt5Svg", "Qt5Widgets"] - if(Qt.core.versionMajor >= 5 && Qt.core.versionMinor >= 14) { - libs.push("Qt5QmlModels") - libs.push("Qt5QmlWorkerScript") - } + var libs = ["Qt5Core", "Qt5Gui", "Qt5Xml", "Qt5XmlPatterns", + "Qt5Network", "Qt5Multimedia", "Qt5Svg", "Qt5Widgets"] if(qbs.targetOS.contains("linux")) { for(var it in libs) { @@ -116,11 +103,6 @@ Product { list.push("**/QtXmlPatterns.framework/**") list.push("**/QtNetwork.framework/**") list.push("**/QtMultimedia.framework/**") - list.push("**/QtQml.framework/**") - list.push("**/QtQuick.framework/**") - list.push("**/QtQuickTemplates2.framework/**") - list.push("**/QtQuickControls2.framework/**") - list.push("**/QtQuickWidgets.framework/**") list.push("**/QtSvg.framework/**") list.push("**/QtPrintSupport.framework/**") list.push("**/QtDBus.framework/**") @@ -209,26 +191,6 @@ Product { qbs.installPrefix: install.PREFIX } - Group { - name: "QML Plugins" - prefix: FileInfo.joinPaths(Qt.core.pluginPath, "/../qml/") - files: [ - "QtGraphicalEffects/**", - "QtQuick/Controls.2/**", - "QtQuick/Shapes/**", - "QtQuick/Templates.2/**", - "QtQuick/XmlListModel/**", - "QtQuick/Layouts/**", - "QtQuick/Window.2/**", - "QtQuick.2/**" - ] - excludeFiles: pluginExcludeFiles - qbs.install: true - qbs.installDir: install.QML_PATH - qbs.installPrefix: install.PREFIX - qbs.installSourceBase: prefix - } - Group { name: "Shaders Engine" files: [ diff --git a/doc/config.qdocconf b/doc/config.qdocconf index 15d0f65a1..68ea897eb 100644 --- a/doc/config.qdocconf +++ b/doc/config.qdocconf @@ -47,7 +47,7 @@ excludedirs += \ ../engine/includes/systems \ ../thirdparty/assimp -sources.fileextensions = "*.cpp *.qdoc *.mm *.qml" +sources.fileextensions = "*.cpp *.qdoc *.mm" headers.fileextensions = "*.h *.ch *.h++ *.hh *.hpp *.hxx" exampledirs = . diff --git a/engine/includes/pipelinecontext.h b/engine/includes/pipelinecontext.h index 0700f6786..b5b9941a6 100644 --- a/engine/includes/pipelinecontext.h +++ b/engine/includes/pipelinecontext.h @@ -39,8 +39,6 @@ class ENGINE_EXPORT PipelineContext : public Object { void drawRenderers(const std::list &list, uint32_t layer, uint32_t flags = 0); - void setMaxTexture(uint32_t size); - World *world(); void setWorld(World *world); diff --git a/engine/src/editor/viewport/viewport.cpp b/engine/src/editor/viewport/viewport.cpp index 10f966e2b..2db6a5b47 100644 --- a/engine/src/editor/viewport/viewport.cpp +++ b/engine/src/editor/viewport/viewport.cpp @@ -489,6 +489,11 @@ void Viewport::init() { m_rhiWindow = m_renderSystem->createRhiWindow(); if(m_rhiWindow) { + static bool first = true; + if(first) { + m_rhiWindow->show(); + first = false; + } m_renderSystem->init(); m_rhiWindow->installEventFilter(this); diff --git a/engine/src/pipelinecontext.cpp b/engine/src/pipelinecontext.cpp index 0d05b9556..b99ab3cc5 100644 --- a/engine/src/pipelinecontext.cpp +++ b/engine/src/pipelinecontext.cpp @@ -71,6 +71,9 @@ PipelineContext::PipelineContext() : } m_buffer->setGlobalTexture(m_radianceMap->name().c_str(), m_radianceMap); + + uint32_t size = Texture::maxTextureSize(); + m_buffer->setGlobalValue("shadow.pageSize", Vector4(1.0f / size, 1.0f / size, size, size)); } PipelineContext::~PipelineContext() { @@ -133,13 +136,6 @@ void PipelineContext::setCurrentCamera(Camera *camera) { void PipelineContext::cameraReset() { m_buffer->setViewProjection(m_cameraView, m_cameraProjection); } -/*! - \internal - Sets the maximum texture \a size in the command buffer for shadow mapping. -*/ -void PipelineContext::setMaxTexture(uint32_t size) { - m_buffer->setGlobalValue("shadow.pageSize", Vector4(1.0f / size, 1.0f / size, size, size)); -} /*! Resizes the pipeline context to the specified \a width and \a height. Updates render tasks accordingly. */ diff --git a/modules/editor/particletools/CMakeLists.txt b/modules/editor/particletools/CMakeLists.txt index f79440420..4ca4c8991 100644 --- a/modules/editor/particletools/CMakeLists.txt +++ b/modules/editor/particletools/CMakeLists.txt @@ -54,7 +54,6 @@ if (desktop) Qt5::Core Qt5::Gui Qt5::Widgets - Qt5::QuickWidgets ) target_compile_definitions(${PROJECT_NAME} PRIVATE diff --git a/modules/renders/rendergl/src/renderglsystem.cpp b/modules/renders/rendergl/src/renderglsystem.cpp index 262331315..853c9f2b4 100644 --- a/modules/renders/rendergl/src/renderglsystem.cpp +++ b/modules/renders/rendergl/src/renderglsystem.cpp @@ -87,34 +87,36 @@ RenderGLSystem::~RenderGLSystem() { bool RenderGLSystem::init() { PROFILE_FUNCTION(); + static bool done = false; + if(!done) { #ifndef THUNDER_MOBILE - if(!gladLoadGL()) { + if(!gladLoadGL()) { + CheckGLError(); + aWarning() << "[ RenderGL ] Failed to initialize OpenGL context."; + return false; + } + glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); CheckGLError(); - aWarning() << "[ RenderGL ] Failed to initialize OpenGL context."; - return false; - } - glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); - CheckGLError(); #endif - bool result = RenderSystem::init(); + int32_t texture; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texture); + CheckGLError(); - int32_t texture; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texture); - CheckGLError(); + texture = MIN(texture, MAX_RESOLUTION); - texture = MIN(texture, MAX_RESOLUTION); + Texture::setMaxTextureSize(texture); - Texture::setMaxTextureSize(texture); - pipelineContext()->setMaxTexture(texture); + glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &texture); + CheckGLError(); - glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &texture); - CheckGLError(); + Texture::setMaxCubemapSize(texture); - Texture::setMaxCubemapSize(texture); + CommandBufferGL::setInited(); - CommandBufferGL::setInited(); + done = true; + } - return result; + return RenderSystem::init(); } /*! Main drawing procedure. diff --git a/worldeditor/CMakeLists.txt b/worldeditor/CMakeLists.txt index 99c9649a6..bfc0c6954 100644 --- a/worldeditor/CMakeLists.txt +++ b/worldeditor/CMakeLists.txt @@ -154,7 +154,6 @@ if (desktop) Qt5::Gui Qt5::Widgets Qt5::Xml - Qt5::QuickWidgets ) if(WIN32) diff --git a/worldeditor/res/WorldEditor.qrc b/worldeditor/res/WorldEditor.qrc index 9fa278c2b..343cba132 100644 --- a/worldeditor/res/WorldEditor.qrc +++ b/worldeditor/res/WorldEditor.qrc @@ -98,15 +98,6 @@ styles/dark/images/css.svg styles/dark/images/ui.svg - - qml/Theme.qml - qml/CurveEditor.qml - qml/Startup.qml - qml/Projects.qml - qml/Blog.qml - qml/BlogTile.qml - qml/ResizableScrollBar.qml - workspaces/Default.ws diff --git a/worldeditor/res/qml/Blog.qml b/worldeditor/res/qml/Blog.qml deleted file mode 100644 index f7333cb21..000000000 --- a/worldeditor/res/qml/Blog.qml +++ /dev/null @@ -1,119 +0,0 @@ -import QtQuick 2.0 -import QtQuick.XmlListModel 2.0 -import QtQuick.Layouts 1.3 -import QtQuick.Controls 2.3 - -Item { - id: element - - ColumnLayout { - id: view - anchors.fill: parent - anchors.margins: spacing - spacing: 30 - - Rectangle { - id: tile00 - height: 300 - color: theme.greyDark - Layout.fillWidth: true - - property variant headerData: undefined - - Row { - spacing: view.spacing - anchors.fill: parent - - Image { - anchors.bottom: parent.bottom - anchors.top: parent.top - width: parent.width / 2 - fillMode: Image.PreserveAspectCrop - clip: true - source: (typeof(tile00.headerData) !== "undefined") ? tile00.headerData.thumbnail : "" - } - Column { - anchors.top: parent.top - anchors.topMargin: 30 - spacing: 20 - width: parent.width / 2 - anchors.margins: spacing - Text { - width: parent.width - parent.spacing * 2 - font.pixelSize: 24 - color: theme.textColor - text: (typeof(tile00.headerData) !== "undefined") ? tile00.headerData.title : "" - wrapMode: Text.WordWrap - } - Text { - width: parent.width - parent.spacing * 2 - font.pixelSize: 16 - color: theme.textColor - text: (typeof(tile00.headerData) !== "undefined") ? tile00.headerData.summary : "" - wrapMode: Text.WordWrap - } - } - } - - MouseArea { - anchors.fill: parent - hoverEnabled: true - onEntered: parent.color = "#404040" - onExited: parent.color = theme.greyDark - onClicked: { - if(typeof(headerData) !== "undefined") { - Qt.openUrlExternally(blogData.link) - } - } - } - } - - RowLayout { - Layout.fillWidth: true - spacing: view.spacing - - BlogTile { - id: tile11 - Layout.fillWidth: true - } - BlogTile { - id: tile12 - Layout.fillWidth: true - } - BlogTile { - id: tile13 - Layout.fillWidth: true - } - BlogTile { - id: tile14 - Layout.fillWidth: true - } - } - - Item { - Layout.fillHeight: true - } - } - - XmlListModel { - xml: feedManager.blogFeed - query: "/feed/entry" - namespaceDeclarations: "declare default element namespace 'http://www.w3.org/2005/Atom';declare namespace media='http://search.yahoo.com/mrss/';" - - XmlRole { name: "title"; query: "title/string()" } - XmlRole { name: "summary"; query: "fn:replace(summary/string(), '\<a href=.*\/a\>', '')" } - XmlRole { name: "thumbnail"; query: "media:thumbnail/@url/string()" } - XmlRole { name: "link"; query: "link/@href/string()" } - - onStatusChanged: { - if(status == XmlListModel.Ready) { - tile00.headerData = get(0) - - tile11.blogData = get(1) - tile12.blogData = get(2) - tile13.blogData = get(3) - tile14.blogData = get(4) - } - } - } -} diff --git a/worldeditor/res/qml/BlogTile.qml b/worldeditor/res/qml/BlogTile.qml deleted file mode 100644 index 0c203f274..000000000 --- a/worldeditor/res/qml/BlogTile.qml +++ /dev/null @@ -1,52 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: rect - height: 500 - color: theme.greyDark - - property variant blogData: undefined - - Image { - id: thumbnail - width: rect.width - height: rect.height / 2 - fillMode: Image.PreserveAspectCrop - clip: true - source: (typeof(blogData) !== "undefined") ? blogData.thumbnail : "" - } - Column { - anchors.left: parent.left - anchors.top: thumbnail.bottom - anchors.margins: spacing - spacing: 20 - Text { - anchors.leftMargin: 20 - width: rect.width - 20 - font.pixelSize: 24 - color: theme.textColor - text: (typeof(blogData) !== "undefined") ? blogData.title : "" - wrapMode: Text.WordWrap - } - Text { - anchors.leftMargin: 20 - width: rect.width - 20 - font.pixelSize: 16 - color: theme.textColor - text: (typeof(blogData) !== "undefined") ? blogData.summary : "" - wrapMode: Text.WordWrap - } - } - - MouseArea { - anchors.fill: parent - hoverEnabled: true - onEntered: parent.color = "#404040" - onExited: parent.color = theme.greyDark - onClicked: { - if(typeof(blogData) !== "undefined") { - Qt.openUrlExternally(blogData.link) - } - } - } -} diff --git a/worldeditor/res/qml/CurveEditor.qml b/worldeditor/res/qml/CurveEditor.qml deleted file mode 100644 index dd6b2704e..000000000 --- a/worldeditor/res/qml/CurveEditor.qml +++ /dev/null @@ -1,515 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 2.3 - -Rectangle { - id: curveEditor - - color: "#80808080" - clip: true - - focus: true - - property int selectInd: -1 - property int selectCol: -1 - - property int row: 0 - property int col: clipModel.col - property variant curve: clipModel.trackData(row) - - property int timeStep: minStep - property real timeScale: 0.01 - - property int minValue: 20 - property int maxValue: 100 - - property int valueStep: minStep - property real valueScale: 0.01 - - property int posX: 0 - property int posY: 0 - - property real minimum: 0 - property real maximum: 0 - - onPosXChanged: canvas.requestPaint() - onPosYChanged: canvas.requestPaint() - - onValueStepChanged: canvas.requestPaint() - - function toScreenSpaceX(pos) { - return ((pos / 1000.0) / timeScale) * timeStep + minStep - } - - function toScreenSpaceY(pos) { - return (pos / valueScale) * valueStep - } - - function toLocalSpaceX(pos) { - return (pos / timeStep) * timeScale - } - - function toLocalSpaceY(pos) { - return (pos / valueStep) * valueScale - } - - function deleteKey() { - removeKey(row, selectCol, selectInd) - selectInd = -1 - selectCol = -1 - } - - Connections { - target: clipModel - onLayoutChanged: { - curve = undefined - curve = clipModel.trackData(row) - canvas.requestPaint() - } - - onRowChanged: { - var r = clipModel.row - curve = clipModel.trackData(r) - - minimum = Number.MAX_VALUE - maximum =-Number.MAX_VALUE - for(var i = 0; i < canvas.componentsNumber; i++) { - var keysNumber = curve[i].length - 1 - for(var k = 0; k < keysNumber; k++) { - var key = curve[i][k + 1] - var py = -(key[canvas.valueOffset]) - - minimum = Math.min(py, minimum) - maximum = Math.max(py, maximum) - } - } - var size = Math.abs(maximum - minimum) - var value = 0.01 - while(true) { - var v = value * 10.0 - if((size / v) <= 0.5) { - break; - } - value = v - } - valueScale = value - valueStep = minValue - - canvas.requestPaint() - - row = r - } - } - - onCurveChanged: { - if(curve !== undefined) { - canvas.componentsNumber = curve.length - canvas.requestPaint() - } - } - - Canvas { - id: canvas - anchors.fill: parent - contextType: "2d" - - antialiasing: false - - property int componentsNumber: 0 - - property int positionOffset: 0 - property int typeOffset: 1 - property int valueOffset: 2 - property int leftOffset: valueOffset + 1 - property int rightOffset: leftOffset + 1 - - property int dist: 50 - - onPaint: { - context.clearRect(0, 0, canvas.width, canvas.height); - if(curveEditor.curve !== undefined) { - context.translate(-posX, posY) - - for(var i = 0; i < componentsNumber; i++) { - if(col > -1 && i !== col) { - continue - } - - context.strokeStyle = theme.colors[i] - context.fillStyle = Qt.rgba(1,0.5,0) - context.beginPath() - - var keysNumber = curve[i].length - 1 - - var key = curve[i][1] - context.moveTo(toScreenSpaceX(key[positionOffset]), -toScreenSpaceY(key[valueOffset])) - - for(var k = 0; k < keysNumber; k++) { - var key1 = curve[i][k + 1] - var px1 = toScreenSpaceX(key1[positionOffset]) - var py1 = -toScreenSpaceY(key1[valueOffset]) - - switch(key1[typeOffset]) { - case 1: // Line - context.lineTo(px1,py1) - break - case 2: // Cubic - var tx0 = px1 - var ty0 = py1 - - var d = 0 - if((k - 1) >= 0) { - var key0 = curve[i][k] - var px0 = toScreenSpaceX(key0[positionOffset]) - var py0 = -toScreenSpaceY(key0[valueOffset]) - - d = (px1 - px0) * 0.5 - - tx0 = px0 + d - ty0 = -toScreenSpaceY(key0[rightOffset]) - } - var tx1 = px1 - d - var ty1 = -toScreenSpaceY(key1[leftOffset]) - - context.bezierCurveTo(tx0,ty0, tx1,ty1, px1,py1) - - break - default: break - } - - - } - context.stroke() - - if(selectInd >= 0 && selectCol === i) { - context.strokeStyle = Qt.rgba(0.3, 0.3, 0.3) - - key1 = curve[selectCol][selectInd + 1] - px1 = toScreenSpaceX(key1[positionOffset]) - py1 = -toScreenSpaceY(key1[valueOffset]) - // Right tangent - d = 0 - if((selectInd + 1) < (curve[selectCol].length - 1)) { - key0 = curve[selectCol][selectInd + 2] - d = (px1 - toScreenSpaceX(key0[positionOffset])) * 0.5 - - tx1 = -d - ty1 = -toScreenSpaceY(key1[rightOffset]) - py1 - - var l = (1.0 / Math.sqrt(tx1 * tx1 + ty1 * ty1)) - tx1 = l * tx1 * dist - ty1 = l * ty1 * dist - - context.beginPath() - context.moveTo(px1, py1) - context.lineTo(tx1 + px1, ty1 + py1) - context.stroke() - context.fillRect(tx1 + px1 - 2, ty1 + py1 - 2, 4, 4); - } - - // Left tangent - d = 0 - if((selectInd - 1) >= 0) { - key0 = curve[selectCol][selectInd] - d = (px1 - toScreenSpaceX(key0[positionOffset])) * 0.5 - - tx1 = -d - ty1 = -toScreenSpaceY(key1[leftOffset]) - py1 - - l = (1.0 / Math.sqrt(tx1 * tx1 + ty1 * ty1)) - tx1 = l * tx1 * dist - ty1 = l * ty1 * dist - - context.beginPath() - context.moveTo(px1, py1) - context.lineTo(tx1 + px1, ty1 + py1) - context.stroke() - context.fillRect(tx1 + px1 - 2, ty1 + py1 - 2, 4, 4); - } - } - } - context.setTransform(1, 0, 0, 1, 0, 0) - } - } - } - - Repeater { - model: Math.ceil(curveEditor.height / valueStep) - Item { - anchors.left: curveEditor.left - anchors.right: curveEditor.right - y: index * valueStep + (posY % valueStep) - - property int shift: posY / valueStep - Label { - anchors.bottom: parent.top - anchors.left: parent.left - color: theme.textColor - text: { - var value = -(index - parent.shift) * valueScale - return value.toLocaleString(Qt.locale("en_EN"), 'f', 2) - } - font.pointSize: 8 - renderType: Text.NativeRendering - } - } - } - - Repeater { - model: (curve === undefined) ? 0 : ((curveEditor.col > -1) ? 1 : canvas.componentsNumber) - Repeater { - id: points - model: curve[col].length - 1 - - property int col: (curveEditor.col > -1) ? curveEditor.col : index - property int component: curve[col][0] - - property int pointSize: 6 - property int pointCenter: pointSize * 0.5 - - Item { - id: item - property variant key: curve[points.col][index + 1] - property bool breaked: false - - x: toScreenSpaceX(key[canvas.positionOffset]) - posX - points.pointCenter - y: -toScreenSpaceY(key[canvas.valueOffset]) + posY - points.pointCenter - - function commitKey() { - var data = curve - data[points.col][index + 1] = item.key - curve = data - } - - Rectangle { - color: (selectInd == index && selectCol == points.col) ? theme.blueHover : "#a0606060" - border.color: theme.textColor - - height: points.pointSize - width: points.pointSize - - rotation: 45 - - MouseArea { - anchors.fill: parent - - acceptedButtons: Qt.LeftButton | Qt.RightButton - - drag.target: item - drag.axis: Drag.XAxis | Drag.YAxis - drag.minimumX: 0 - drag.maximumX: rect.width - drag.minimumY: 0 - drag.maximumY: rect.height - drag.threshold: 0 - - drag.onActiveChanged: { - if(!drag.active) { - selectKey(row, selectCol, selectInd) - clipModel.setTrackData(curveEditor.row, curveEditor.curve) - } - } - - onPressed: { - selectInd = index - selectCol = points.col - - selectKey(row, selectCol, selectInd) - - canvas.requestPaint() - - xLabel.visible = true - xLabel.x = item.x - - yLabel.visible = true - yLabel.y = item.y - } - - onReleased: { - xLabel.visible = false - yLabel.visible = false - } - - onPositionChanged: { - if(drag.active) { - xLabel.x = item.x - yLabel.y = item.y - - var x = Math.round(item.x / timeStep) * timeStep - points.pointSize - - item.key[0] = Math.max(Math.round((x + posX) / timeStep), 0) * timeScale * 1000 - var value = (-((item.y - posY + 3) / valueStep) * valueScale) - item.key[canvas.valueOffset] - item.key[canvas.valueOffset] += value - item.key[canvas.leftOffset] += value - item.key[canvas.rightOffset] += value - - item.commitKey() - } - } - } - } - - Item { - id: leftTangent - visible: (selectInd == index) && (selectCol == points.col) && (index > 0) - height: 16 - width: 16 - - property real d: { - var result = 0 - if(index > 0) { - var key0 = curve[points.col][index] - result = (toScreenSpaceX(item.key[canvas.positionOffset]) - toScreenSpaceX(key0[canvas.positionOffset])) * 0.5 - } - - var py1 = -toScreenSpaceY(item.key[canvas.valueOffset]) - var tx1 = -result - var ty1 = -toScreenSpaceY(item.key[canvas.leftOffset]) - py1 - - var l = (1.0 / Math.sqrt(tx1 * tx1 + ty1 * ty1)) - x = l * tx1 * canvas.dist - width * 0.5 - y = l * ty1 * canvas.dist - height * 0.5 - - return result - } - - MouseArea { - anchors.fill: parent - - drag.target: parent - drag.axis: Drag.XAxis | Drag.YAxis - drag.minimumX:-canvas.dist - drag.maximumX: 0 - drag.minimumY:-canvas.dist - drag.maximumY: canvas.dist - drag.threshold: 0 - - drag.onActiveChanged: { - if(!drag.active) { - clipModel.setTrackData(curveEditor.row, curve) - } - } - - onPositionChanged: { - if(drag.active) { - var value = toLocalSpaceY((parent.y / parent.x) * parent.d) - item.key[canvas.leftOffset] = item.key[canvas.valueOffset] + value - if(!item.breaked) { - item.key[canvas.rightOffset] = item.key[canvas.valueOffset] - value - } - item.commitKey() - } - } - } - } - - Item { - id: rightTangent - visible: (selectInd == index) && (selectCol == points.col) && ((index + 1) < (curve[points.col].length - 1)) - height: 16 - width: 16 - - property real d: { - var result = 0 - if((index + 1) < (curve[points.col].length - 1)) { - var key0 = curve[points.col][index + 2] - result = (toScreenSpaceX(item.key[canvas.positionOffset]) - toScreenSpaceX(key0[canvas.positionOffset])) * 0.5 - } - - var py1 = -toScreenSpaceY(item.key[canvas.valueOffset]) - var tx1 = -result - var ty1 = -toScreenSpaceY(item.key[canvas.rightOffset]) - py1 - - var l = (1.0 / Math.sqrt(tx1 * tx1 + ty1 * ty1)) - x = l * tx1 * canvas.dist - width * 0.5 - y = l * ty1 * canvas.dist - height * 0.5 - - return result - } - - MouseArea { - anchors.fill: parent - - drag.target: parent - drag.axis: Drag.XAxis | Drag.YAxis - drag.minimumX: 0 - drag.maximumX: canvas.dist - drag.minimumY:-canvas.dist - drag.maximumY: canvas.dist - drag.threshold: 0 - - drag.onActiveChanged: { - if(!drag.active) { - clipModel.setTrackData(curveEditor.row, curve) - } - } - - onPositionChanged: { - if(drag.active) { - var value = toLocalSpaceY((parent.y / parent.x) * parent.d) - item.key[canvas.rightOffset] = item.key[canvas.valueOffset] + value - if(!item.breaked) { - item.key[canvas.leftOffset] = item.key[canvas.valueOffset] - value - } - item.commitKey() - } - } - } - } - } - } - } - - Rectangle { - id: xLabel - visible: false - anchors.top: parent.top - color: "#a0000000" - radius: 3 - - width: xlabel.width + 6 - height: xlabel.height - - Label { - id: xlabel - color: theme.textColor - text: { - if(selectInd >= 0 && selectCol >= 0 && curve !== undefined) { - var key = curve[selectCol][selectInd + 1] - if(key !== undefined) { - var value = key[0] / 1000.0 - return value.toLocaleString(Qt.locale("en_EN"), 'f', 3) - } - } - return "" - } - anchors.centerIn: parent - } - } - - Rectangle { - id: yLabel - visible: false - anchors.left: parent.left - color: "#a0000000" - radius: 3 - - width: ylabel.width + 6 - height: ylabel.height - - Label { - id: ylabel - color: theme.textColor - text: { - if(selectInd >= 0 && selectCol >= 0 && curve !== undefined) { - var key = curve[selectCol][selectInd + 1] - if(key !== undefined) { - var value = key[canvas.valueOffset] - return value.toLocaleString(Qt.locale("en_EN"), 'f', 3) * 1 - } - } - return "" - } - anchors.centerIn: parent - } - } -} diff --git a/worldeditor/res/qml/Projects.qml b/worldeditor/res/qml/Projects.qml deleted file mode 100644 index e9db41ba1..000000000 --- a/worldeditor/res/qml/Projects.qml +++ /dev/null @@ -1,53 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 2.3 - -Item { - anchors.fill: parent - GridView { - id: gridView - cellHeight: 180 - cellWidth: 200 - anchors.margins: 20 - anchors.fill: parent - model: projectsModel - delegate: Rectangle { - x: 5 - width: 190 - height: 170 - color: theme.greyDark - radius: theme.frameRadius - - Column { - spacing: 5 - anchors.fill: parent - Image { - width: 128 - height: 128 - source: icon - anchors.horizontalCenter: parent.horizontalCenter - } - Rectangle { - width: parent.width - height: 1 - color: theme.blue - } - Text { - text: name - anchors.horizontalCenter: parent.horizontalCenter - verticalAlignment: Text.AlignBottom - color: theme.textColor - font.bold: false - font.pixelSize: 14 - } - } - - MouseArea { - anchors.fill: parent - hoverEnabled: true - onClicked: openProject(path) - onEntered: parent.color = "#404040" - onExited: parent.color = theme.greyDark - } - } - } -} diff --git a/worldeditor/res/qml/ResizableScrollBar.qml b/worldeditor/res/qml/ResizableScrollBar.qml deleted file mode 100644 index 211934049..000000000 --- a/worldeditor/res/qml/ResizableScrollBar.qml +++ /dev/null @@ -1,85 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 2.3 - -ScrollBar { - id: bar - hoverEnabled: true - active: hovered || pressed - - property bool isResizable: false - - signal headPositionChanged(real value); - signal tailPositionChanged(real value); - - Rectangle { - id: head - color: "red" - - visible: bar.active && isResizable - - width: 10 - height: 10 - - x: parent.width * parent.position - - MouseArea { - anchors.fill: parent - - drag.target: parent - drag.axis: (bar.orientation === Qt.Horizontal) ? Drag.XAxis : Drag.YAxis - drag.minimumX: 0 - drag.maximumX: tail.x - drag.minimumY: 0 - drag.maximumY: tail.y - drag.threshold: 0 - - cursorShape: (bar.orientation === Qt.Horizontal) ? Qt.SizeHorCursor : Qt.SizeVerCursor - - onPositionChanged: { - if(drag.active) { - if(bar.orientation === Qt.Horizontal) { - headPositionChanged((tail.x - head.x + width) / bar.width); - } else { - headPositionChanged((tail.y - head.y + height) / bar.height); - } - } - } - } - } - - Rectangle { - id: tail - color: "blue" - - visible: bar.active && isResizable - - width: 10 - height: 10 - - x: (parent.position + parent.size) * parent.width - width - - MouseArea { - anchors.fill: parent - - drag.target: parent - drag.axis: (bar.orientation === Qt.Horizontal) ? Drag.XAxis : Drag.YAxis - drag.minimumX: head.x - drag.maximumX: bar.width - width - drag.minimumY: head.y - drag.maximumY: bar.height - height - drag.threshold: 0 - - cursorShape: (bar.orientation === Qt.Horizontal) ? Qt.SizeHorCursor : Qt.SizeVerCursor - - onPositionChanged: { - if(drag.active) { - if(bar.orientation === Qt.Horizontal) { - tailPositionChanged((tail.x - head.x + width) / bar.width); - } else { - tailPositionChanged((tail.y - head.y + height) / bar.height); - } - } - } - } - } -} diff --git a/worldeditor/res/qml/Startup.qml b/worldeditor/res/qml/Startup.qml deleted file mode 100644 index 698dacfba..000000000 --- a/worldeditor/res/qml/Startup.qml +++ /dev/null @@ -1,205 +0,0 @@ -import QtQuick 2.12 -import QtQuick.Controls 2.3 - -import "qrc:/QML/qml/." - -Rectangle { - id: rect - color: theme.grey - - Theme { - id: theme - } - - signal openProject(string path) - signal newProject() - signal importProject() - - Rectangle { - id: leftPanel - width: 200 - color: theme.greyDark - anchors.bottom: parent.bottom - anchors.top: parent.top - anchors.left: parent.left - - Item { - id: rectangle - height: 40 - anchors.rightMargin: 10 - anchors.leftMargin: 10 - anchors.topMargin: 10 - anchors.right: parent.right - anchors.left: parent.left - anchors.top: parent.top - - Image { - id: image - x: 0 - y: 0 - width: 40 - height: 40 - source: "qrc:/Images/icons/thunderlight.svg" - } - - Text { - anchors.fill: parent - anchors.leftMargin: 50 - horizontalAlignment: Text.AlignLeft - verticalAlignment: Text.AlignBottom - text: "Thunder Engine" - font.bold: false - font.pixelSize: 18 - color: theme.textColor - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: Qt.openUrlExternally("http://thunderengine.org") - } - } - - ButtonGroup { - buttons: column.children - } - - Column { - id: column - anchors.top: parent.top - anchors.topMargin: 100 - anchors.right: parent.right - anchors.left: parent.left - anchors.rightMargin: 10 - anchors.leftMargin: 10 - - RadioButton { - checked: true - text: qsTr("Projects") - indicator: Rectangle { - width: 4 - height: parent.height - visible: parent.checked - color: theme.blue - } - contentItem: Text { - text: parent.text - font.pixelSize: 24 - color: parent.checked ? theme.textColor : theme.greyLight - verticalAlignment: Text.AlignVCenter - leftPadding: 10 - } - onClicked: pageLoader.source = "Projects.qml" - } - - RadioButton { - text: qsTr("Blog") - indicator: Rectangle { - width: 4 - height: parent.height - visible: parent.checked - color: theme.blue - } - contentItem: Text { - text: parent.text - font.pixelSize: 24 - color: parent.checked ? theme.textColor : theme.greyLight - verticalAlignment: Text.AlignVCenter - leftPadding: 10 - } - onClicked: pageLoader.source = "Blog.qml" - } -/* - RadioButton { - text: qsTr("Learn") - indicator: Rectangle { - width: 4 - height: parent.height - visible: parent.checked - color: theme.blue - } - contentItem: Text { - text: parent.text - font.pixelSize: 24 - color: parent.checked ? theme.textColor : theme.greyLight - verticalAlignment: Text.AlignVCenter - leftPadding: 10 - } - onClicked: pageLoader.source = "Learn.qml" - } -*/ - } - - Button { - y: 500 - height: 30 - anchors.right: parent.right - anchors.left: parent.left - anchors.bottom: addProject.top - anchors.rightMargin: 10 - anchors.leftMargin: 10 - - text: qsTr("Import") - anchors.bottomMargin: 10 - - background: Rectangle { - anchors.fill: parent - radius: theme.frameRadius - color: parent.hovered ? theme.blue : "#00000000" - border.color: parent.hovered ? "#00000000" : theme.blue - } - contentItem: Text { - text: parent.text - font.bold: false - font.pixelSize: 16 - color: theme.textColor - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - } - onClicked: importProject() - } - - Button { - id: addProject - height: 30 - anchors.right: parent.right - anchors.left: parent.left - anchors.bottom: parent.bottom - anchors.rightMargin: 10 - anchors.leftMargin: 10 - hoverEnabled: true - - text: qsTr("New") - anchors.bottomMargin: 50 - - background: Rectangle { - anchors.fill: parent - radius: theme.frameRadius - color: parent.hovered ? theme.blue : "#00000000" - border.color: parent.hovered ? "#00000000" : theme.blue - } - contentItem: Text { - text: parent.text - font.bold: false - font.pixelSize: 16 - color: theme.textColor - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - } - onClicked: newProject() - } - } - - Item { - anchors.left: leftPanel.right - anchors.top: parent.top - anchors.bottom: parent.bottom - width: 1400 - - Loader { - id: pageLoader - anchors.fill: parent - source: "Projects.qml" - } - } -} diff --git a/worldeditor/res/qml/Theme.qml b/worldeditor/res/qml/Theme.qml deleted file mode 100644 index 2e5024820..000000000 --- a/worldeditor/res/qml/Theme.qml +++ /dev/null @@ -1,37 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 2.3 - -Item { - property string textColor: "#ffffff" - - property string backColor: "#606060" - - property string emitterColor: "#40000000" - property string functionColor: "#40000000" - property string hoverColor: "#60000000" - - property string grey: "#606060" - property string greyLight: "#8d8d8d" - property string greyDark: "#363636" - - property string blue: "#0277bd" - property string blueLight: "#58a5f0" - property string blueDark: "#004c8c" - property string blueHover: "#0288d1" - - property string green: "#2e7d32" - property string greenLight: "#60ad5e" - property string greenDark: "#005005" - property string greenHover: "#388e3c" - - property string red: "#c62828" - property string redLight: "#ff5f52" - property string redDark: "#8e0000" - property string redHover: "#d32f2f" - - property int frameRadius: 4 - - property int textSize: 10 - - property var colors: [Qt.rgba(1,0,0), Qt.rgba(0,1,0), Qt.rgba(0,0,1), Qt.rgba(1,1,0), Qt.rgba(1,0,1), Qt.rgba(0,1,1)] -} diff --git a/worldeditor/src/main.cpp b/worldeditor/src/main.cpp index 93e7cd283..3408b681b 100644 --- a/worldeditor/src/main.cpp +++ b/worldeditor/src/main.cpp @@ -7,6 +7,8 @@ #include "main/mainwindow.h" +#include "screens/projectbrowser/projectbrowser.h" + #include #include #include @@ -33,17 +35,31 @@ int main(int argc, char *argv[]) { QCoreApplication::setApplicationName(EDITOR_NAME); QCoreApplication::setApplicationVersion(SDK_VERSION); - QPixmap pixmap(":/splash.png"); - QSplashScreen splash(pixmap); - splash.show(); - app.processEvents(); - QFile qss(":/Style/styles/dark/style.qss"); if(qss.open(QIODevice::ReadOnly)) { qApp->setStyleSheet(qss.readAll()); qss.close(); } + QString project; + if(argc > 1) { + project = QApplication::arguments().at(1); + } else { + ProjectBrowser browser; + if(browser.exec() == QDialog::Accepted) { + project = browser.projectPath(); + } + } + + if(project.isEmpty()) { + return 0; + } + + QPixmap pixmap(":/splash.png"); + QSplashScreen splash(pixmap); + splash.show(); + app.processEvents(); + File *file = new File(); file->finit(qPrintable(QApplication::arguments().at(0))); @@ -55,12 +71,10 @@ int main(int argc, char *argv[]) { MainWindow window(&engine); - window.show(); splash.finish(&window); - if(argc > 1) { - window.onOpenProject(QApplication::arguments().at(1)); - } + window.onOpenProject(project); + window.show(); int result = app.exec(); diff --git a/worldeditor/src/main/aboutdialog.ui b/worldeditor/src/main/aboutdialog.ui index 2ce4adb16..647e4ac64 100644 --- a/worldeditor/src/main/aboutdialog.ui +++ b/worldeditor/src/main/aboutdialog.ui @@ -28,7 +28,7 @@ - :/Images/icons/thunder.svg + :/Images/icons/thunder.svg true @@ -119,7 +119,8 @@ - + + diff --git a/worldeditor/src/main/mainwindow.cpp b/worldeditor/src/main/mainwindow.cpp index 3d8b7d9b2..450731fd5 100644 --- a/worldeditor/src/main/mainwindow.cpp +++ b/worldeditor/src/main/mainwindow.cpp @@ -6,9 +6,6 @@ #include #include -#include -#include - #include #include #include @@ -19,7 +16,6 @@ // Misc #include "managers/assetimporter/importqueue.h" -#include "managers/feedmanager/feedmanager.h" #include "managers/projectmanager/projectmodel.h" #include @@ -60,9 +56,7 @@ MainWindow::MainWindow(Engine *engine, QWidget *parent) : ui(new Ui::MainWindow), m_currentWorkspace(":/Workspaces/Default.ws"), m_engine(engine), - m_queue(new ImportQueue), - m_projectModel(new ProjectModel), - m_feedManager(new FeedManager), + m_queue(nullptr), m_documentModel(nullptr), m_editorSettings(EditorSettings::instance()), m_projectSettings(ProjectSettings::instance()), @@ -84,8 +78,6 @@ MainWindow::MainWindow(Engine *engine, QWidget *parent) : qRegisterMetaType ("uint8_t"); qRegisterMetaType ("uint32_t"); - qmlRegisterType("com.frostspear.thunderengine", 1, 0, "ProjectModel"); - m_editorSettings->value("General/Language", QLocale(QLocale::English, QLocale::UnitedStates)); ui->setupUi(this); @@ -108,14 +100,6 @@ MainWindow::MainWindow(Engine *engine, QWidget *parent) : connect(ui->actionBuild_All, &QAction::triggered, this, &MainWindow::onBuildProject); - ui->quickWidget->rootContext()->setContextProperty("projectsModel", m_projectModel); - ui->quickWidget->rootContext()->setContextProperty("feedManager", m_feedManager); - ui->quickWidget->setSource(QUrl("qrc:/QML/qml/Startup.qml")); - QQuickItem *item = ui->quickWidget->rootObject(); - connect(item, SIGNAL(openProject(QString)), this, SLOT(onOpenProject(QString))); - connect(item, SIGNAL(newProject()), this, SLOT(onNewProject())); - connect(item, SIGNAL(importProject()), this, SLOT(onImportProject())); - findWorkspaces(":/Workspaces"); findWorkspaces("workspaces"); ui->menuWorkspace->insertSeparator(ui->actionReset_Workspace); @@ -311,14 +295,14 @@ void MainWindow::setGameMode(bool mode) { } void MainWindow::onOpenProject(const QString &path) { - connect(m_queue, &ImportQueue::importFinished, this, &MainWindow::onImportFinished, Qt::QueuedConnection); - - ui->quickWidget->setVisible(false); - - m_projectModel->addProject(path); + ProjectModel::addProject(path); m_projectSettings->init(path); PluginManager::instance()->init(m_engine); + + m_queue = new ImportQueue; + connect(m_queue, &ImportQueue::importFinished, this, &MainWindow::onImportFinished, Qt::QueuedConnection); + AssetManager::instance()->init(); m_projectSettings->loadPlatforms(); @@ -354,30 +338,6 @@ void MainWindow::onOpenProject(const QString &path) { m_contentBrowser->createContextMenus(); } -void MainWindow::onNewProject() { - QString path = QFileDialog::getSaveFileName(this, tr("Create New Project"), - m_projectSettings->myProjectsPath(), "*" + gProjectExt); - if(!path.isEmpty()) { - QFileInfo info(path); - if(info.suffix().isEmpty()) { - path += gProjectExt; - } - QFile file(path); - if(file.open(QIODevice::WriteOnly)) { - file.close(); - onOpenProject(path); - } - } -} - -void MainWindow::onImportProject() { - QString path = QFileDialog::getOpenFileName(this, tr("Import Existing Project"), - m_projectSettings->myProjectsPath(), "*" + gProjectExt); - if(!path.isEmpty()) { - onOpenProject(path); - } -} - void MainWindow::onImportFinished() { m_documentModel = new DocumentModel; diff --git a/worldeditor/src/main/mainwindow.h b/worldeditor/src/main/mainwindow.h index 3297848be..d1311147a 100644 --- a/worldeditor/src/main/mainwindow.h +++ b/worldeditor/src/main/mainwindow.h @@ -80,8 +80,6 @@ public slots: ImportQueue *m_queue; - ProjectModel *m_projectModel; - FeedManager *m_feedManager; DocumentModel *m_documentModel; EditorSettings *m_editorSettings; @@ -105,9 +103,6 @@ public slots: bool m_forceReimport; private slots: - void onNewProject(); - void onImportProject(); - void onBuildProject(); void onImportFinished(); diff --git a/worldeditor/src/main/mainwindow.ui b/worldeditor/src/main/mainwindow.ui index 0cd745e84..5417d2903 100644 --- a/worldeditor/src/main/mainwindow.ui +++ b/worldeditor/src/main/mainwindow.ui @@ -121,25 +121,11 @@ - - - - - 0 - 0 - - - - QQuickWidget::SizeRootObjectToView - - - toolWidget - quickWidget toolPanel @@ -439,11 +425,6 @@ - - QQuickWidget - QWidget -
QtQuickWidgets/QQuickWidget
-
QToolWindowManager QWidget diff --git a/worldeditor/src/managers/assetimporter/iconrender.cpp b/worldeditor/src/managers/assetimporter/iconrender.cpp index 54751532e..820ff3a15 100644 --- a/worldeditor/src/managers/assetimporter/iconrender.cpp +++ b/worldeditor/src/managers/assetimporter/iconrender.cpp @@ -1,6 +1,7 @@ #include "iconrender.h" #include +#include #include @@ -21,12 +22,15 @@ IconRender::IconRender(QObject *parent) : QObject(parent), m_world(Engine::objectCreate()), m_scene(Engine::objectCreate("", m_world)), - m_init(false), - m_light(nullptr) { + m_light(nullptr), + m_render(nullptr) { m_actor = Engine::composeActor("Camera", "ActiveCamera", m_scene); m_actor->transform()->setPosition(Vector3(0.0f, 0.0f, 0.0f)); m_camera = static_cast(m_actor->component("Camera")); + + m_light = Engine::composeActor("DirectLight", "LightSource", m_scene); + m_light->transform()->setQuaternion(Vector3(-45.0f, 45.0f, 0.0f)); } IconRender::~IconRender() { @@ -34,12 +38,6 @@ IconRender::~IconRender() { } const QImage IconRender::render(const QString &resource, const QString &) { - if(!m_init) { - m_light = Engine::composeActor("DirectLight", "LightSource", m_scene); - m_light->transform()->setQuaternion(Vector3(-45.0f, 45.0f, 0.0f)); - - m_init = true; - } Camera::setCurrent(m_camera); Actor *object = AssetManager::instance()->createActor(resource); @@ -59,12 +57,11 @@ const QImage IconRender::render(const QString &resource, const QString &) { return QImage(); } - static RenderSystem *render = nullptr; - if(render == nullptr) { - render = PluginManager::instance()->createRenderer(); - render->init(); + if(m_render == nullptr) { + m_render = PluginManager::instance()->createRenderer(); + m_render->init(); } - ByteArray data = render->renderOffscreen(m_world, 128, 128); + ByteArray data = m_render->renderOffscreen(m_world, 128, 128); QImage result(reinterpret_cast(data.data()), 128, 128, QImage::Format_RGBA8888); object->setParent(nullptr); diff --git a/worldeditor/src/managers/assetimporter/iconrender.h b/worldeditor/src/managers/assetimporter/iconrender.h index edd6426b8..acf58ceec 100644 --- a/worldeditor/src/managers/assetimporter/iconrender.h +++ b/worldeditor/src/managers/assetimporter/iconrender.h @@ -11,6 +11,8 @@ class Actor; class Camera; class Scene; +class RenderSystem; + class IconRender : public QObject { public: IconRender(QObject *parent = nullptr); @@ -30,7 +32,7 @@ class IconRender : public QObject { Camera *m_camera; - bool m_init; + RenderSystem *m_render; }; #endif // ICONRENDER_H diff --git a/worldeditor/src/managers/feedmanager/feedmanager.cpp b/worldeditor/src/managers/feedmanager/feedmanager.cpp deleted file mode 100644 index 49e02545d..000000000 --- a/worldeditor/src/managers/feedmanager/feedmanager.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "feedmanager.h" - -#include -#include -#include -#include - -FeedManager::FeedManager(QObject *parent) : - QObject(parent) { - - m_pManager = new QNetworkAccessManager(this); - connect(m_pManager, &QNetworkAccessManager::finished, - this, &FeedManager::replyFinished); - - QNetworkRequest req(QUrl("http://thunderengine.org/feed.xml")); - req.setRawHeader("Accept", "application/xml,*/*"); - - m_pManager->get(req); -} - -QString FeedManager::blogFeed() const { - return m_BlogData; -} - -void FeedManager::replyFinished(QNetworkReply *reply) { - m_BlogData = reply->readAll(); - emit blogFeedChanged(); -} diff --git a/worldeditor/src/managers/feedmanager/feedmanager.h b/worldeditor/src/managers/feedmanager/feedmanager.h deleted file mode 100644 index 703b7e7e6..000000000 --- a/worldeditor/src/managers/feedmanager/feedmanager.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef FEEDMANAGER_H -#define FEEDMANAGER_H - -#include - -class QNetworkAccessManager; -class QNetworkReply; - -class FeedManager : public QObject { - Q_OBJECT - - Q_PROPERTY(QString blogFeed READ blogFeed NOTIFY blogFeedChanged) - -public: - explicit FeedManager(QObject *parent = nullptr); - - QString blogFeed () const; - -signals: - void blogFeedChanged(); - -private slots: - void replyFinished(QNetworkReply *reply); - -private: - QNetworkAccessManager *m_pManager; - - QString m_BlogData; -}; - -#endif // FEEDMANAGER_H diff --git a/worldeditor/src/managers/projectmanager/projectmodel.cpp b/worldeditor/src/managers/projectmanager/projectmodel.cpp index d786a67ac..af05b81c1 100644 --- a/worldeditor/src/managers/projectmanager/projectmodel.cpp +++ b/worldeditor/src/managers/projectmanager/projectmodel.cpp @@ -1,7 +1,6 @@ #include "projectmodel.h" #include -#include #include "config.h" @@ -13,64 +12,63 @@ ProjectModel::ProjectModel() : QSettings settings(COMPANY_NAME, EDITOR_NAME); QVariant value = settings.value(gProjects); if(value.isValid()) { - m_List = value.toStringList(); - foreach(const QString it, m_List) { + m_list = value.toStringList(); + for(const QString it : m_list) { if(!QFileInfo::exists(it)) { - m_List.removeAll(it); + m_list.removeAll(it); } } + + for(const QString it : m_list) { + QFileInfo info(it); + QFileInfo icon(info.absolutePath() + "/cache/thumbnails/auto.png"); + + QImage image(":/Images/icons/thunderlight.svg"); + if(icon.isReadable()) { + image = QImage(icon.absoluteFilePath()); + } + + image = image.scaledToWidth(90); + + m_iconCache[info.absoluteFilePath()] = image; + } } } ProjectModel::~ProjectModel() { QSettings settings(COMPANY_NAME, EDITOR_NAME); - settings.setValue(gProjects, m_List); + settings.setValue(gProjects, m_list); } int ProjectModel::rowCount(const QModelIndex &parent) const { if(parent.isValid()) { return 0; } - return m_List.size(); + return m_list.size(); } QVariant ProjectModel::data(const QModelIndex &index, int role) const { if(!index.isValid()) { return QVariant(); } - QFileInfo info( m_List.at(index.row()) ); + QFileInfo info(m_list.at(index.row())); switch(role) { - case NameRole: { return info.baseName(); } - case PathRole: { return info.absoluteFilePath(); } - case DirRole: { return info.absolutePath(); } - case IconRole: { - QFileInfo icon(info.absolutePath() + "/cache/thumbnails/auto.png"); - if(icon.isReadable()) { - return "file:///" + icon.absoluteFilePath(); - } - return "qrc:/Images/icons/thunderlight.svg"; - } + case Qt::DisplayRole: { return info.baseName(); } + case Qt::EditRole: { return info.absoluteFilePath(); } + case Qt::DecorationRole: { return m_iconCache.value(info.absoluteFilePath()); } default: break; } return QVariant(); } -QHash ProjectModel::roleNames() const { - QHash roles = QAbstractListModel::roleNames(); - roles[NameRole] = "name"; - roles[PathRole] = "path"; - roles[DirRole] = "dir"; - roles[IconRole] = "icon"; - - return roles; -} - void ProjectModel::addProject(const QString &path) { - m_List.push_front(QDir::fromNativeSeparators(path)); - m_List.removeDuplicates(); QSettings settings(COMPANY_NAME, EDITOR_NAME); - settings.setValue(gProjects, m_List); + QVariant value = settings.value(gProjects); + if(value.isValid()) { + QStringList list = value.toStringList(); + list << QDir::fromNativeSeparators(path); + list.removeDuplicates(); - emit layoutAboutToBeChanged(); - emit layoutChanged(); + settings.setValue(gProjects, list); + } } diff --git a/worldeditor/src/managers/projectmanager/projectmodel.h b/worldeditor/src/managers/projectmanager/projectmodel.h index 5057908bf..cf6905197 100644 --- a/worldeditor/src/managers/projectmanager/projectmodel.h +++ b/worldeditor/src/managers/projectmanager/projectmodel.h @@ -7,27 +7,20 @@ class ProjectModel : public QAbstractListModel { Q_OBJECT public: - enum Roles { - NameRole = Qt::UserRole + 1, - PathRole, - DirRole, - IconRole - }; + ProjectModel(); - ProjectModel (); + ~ProjectModel(); - ~ProjectModel (); + int rowCount(const QModelIndex &parent) const; - int rowCount (const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; - QVariant data (const QModelIndex &index, int role) const; - - QHash roleNames () const; - - void addProject (const QString &path); + static void addProject(const QString &path); protected: - QStringList m_List; + QStringList m_list; + + mutable QMap m_iconCache; }; #endif // PROJECTMODEL_H diff --git a/worldeditor/src/screens/projectbrowser/projectbrowser.cpp b/worldeditor/src/screens/projectbrowser/projectbrowser.cpp new file mode 100644 index 000000000..44a78325a --- /dev/null +++ b/worldeditor/src/screens/projectbrowser/projectbrowser.cpp @@ -0,0 +1,75 @@ +#include "projectbrowser.h" +#include "ui_projectbrowser.h" + +#include "managers/projectmanager/projectmodel.h" +#include "editor/projectsettings.h" + +#include +#include + +#include "config.h" + +ProjectBrowser::ProjectBrowser(QWidget *parent) : + QDialog(parent), + ui(new Ui::ProjectBrowser) { + + setWindowFlags(windowFlags() ^ Qt::WindowContextHelpButtonHint); + + ui->setupUi(this); + ui->listView->setModel(new ProjectModel); + + connect(ui->newButton, &QPushButton::clicked, this, &ProjectBrowser::onNewProject); + connect(ui->importButton, &QPushButton::clicked, this, &ProjectBrowser::onImportProject); + connect(ui->openButton, &QPushButton::clicked, this, &ProjectBrowser::onOpenProject); + + connect(ui->listView, &QListView::doubleClicked, this, &ProjectBrowser::onProjectSelected); +} + +ProjectBrowser::~ProjectBrowser() { + delete ui; +} + +void ProjectBrowser::onNewProject() { + m_projectPath = QFileDialog::getSaveFileName(this, tr("Create New Project"), + ProjectSettings::instance()->myProjectsPath(), "*" + gProjectExt); + if(!m_projectPath.isEmpty()) { + QFileInfo info(m_projectPath); + if(info.suffix().isEmpty()) { + m_projectPath += gProjectExt; + } + QFile file(m_projectPath); + if(file.open(QIODevice::WriteOnly)) { + file.close(); + + done(QDialog::Accepted); + } + } +} + +void ProjectBrowser::onImportProject() { + m_projectPath = QFileDialog::getOpenFileName(this, tr("Import Existing Project"), + ProjectSettings::instance()->myProjectsPath(), "*" + gProjectExt); + if(!m_projectPath.isEmpty()) { + done(QDialog::Accepted); + } +} + +void ProjectBrowser::onOpenProject() { + QItemSelectionModel *selection = ui->listView->selectionModel(); + if(selection->hasSelection()) { + onProjectSelected(selection->selectedIndexes().front()); + } +} + +void ProjectBrowser::onProjectSelected(const QModelIndex &index) { + m_projectPath = ui->listView->model()->data(index, Qt::EditRole).toString(); + if(!m_projectPath.isEmpty()) { + done(QDialog::Accepted); + } +} + +void ProjectBrowser::keyPressEvent(QKeyEvent *e) { + if(e->key() != Qt::Key_Escape) { + QDialog::keyPressEvent(e); + } +} diff --git a/worldeditor/src/screens/projectbrowser/projectbrowser.h b/worldeditor/src/screens/projectbrowser/projectbrowser.h new file mode 100644 index 000000000..9579631c0 --- /dev/null +++ b/worldeditor/src/screens/projectbrowser/projectbrowser.h @@ -0,0 +1,34 @@ +#ifndef PROJECTBROWSER_H +#define PROJECTBROWSER_H + +#include + +namespace Ui { + class ProjectBrowser; +} + +class ProjectBrowser : public QDialog { + Q_OBJECT + +public: + explicit ProjectBrowser(QWidget *parent = nullptr); + ~ProjectBrowser(); + + QString projectPath() const { return m_projectPath; } + +private: + void onNewProject(); + void onImportProject(); + void onOpenProject(); + + void onProjectSelected(const QModelIndex &index); + + void keyPressEvent(QKeyEvent *e) override; + +private: + Ui::ProjectBrowser *ui; + + QString m_projectPath; +}; + +#endif // PROJECTBROWSER_H diff --git a/worldeditor/src/screens/projectbrowser/projectbrowser.ui b/worldeditor/src/screens/projectbrowser/projectbrowser.ui new file mode 100644 index 000000000..b63a10284 --- /dev/null +++ b/worldeditor/src/screens/projectbrowser/projectbrowser.ui @@ -0,0 +1,84 @@ + + + ProjectBrowser + + + + 0 + 0 + 661 + 502 + + + + Dialog + + + + + + QAbstractItemView::NoEditTriggers + + + + 32 + 32 + + + + QListView::Static + + + + 100 + 120 + + + + QListView::IconMode + + + + + + + + + New + + + + + + + Import + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Open + + + + + + + + + + diff --git a/worldeditor/worldeditor.qbs b/worldeditor/worldeditor.qbs index bfae314f9..e16f8291b 100644 --- a/worldeditor/worldeditor.qbs +++ b/worldeditor/worldeditor.qbs @@ -32,13 +32,13 @@ Project { Depends { name: "bundle" } Depends { name: "next-editor" } Depends { name: "engine-editor" } - Depends { name: "Qt"; submodules: ["core", "gui", "widgets", "xml", "quickwidgets"]; } + Depends { name: "Qt"; submodules: ["core", "gui", "widgets", "xml"]; } property bool isBundle: qbs.targetOS.contains("darwin") && bundle.isBundle bundle.infoPlist: ({ "NSHumanReadableCopyright": "(C) 2007-" + worldEditor.COPYRIGHT_YEAR + " by " + worldEditor.COPYRIGHT_AUTHOR }) - bundle.identifierPrefix: "com.thunderengine" + bundle.identifierPrefix: "org.thunderengine" consoleApplication: false