From 54055d34a19e9c44962a9193d8b0c70fe2f2baab Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Thu, 22 Apr 2021 00:27:52 +0300 Subject: [PATCH 01/91] Update .build_livekeys.yml --- .github/workflows/.build_livekeys.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/.build_livekeys.yml b/.github/workflows/.build_livekeys.yml index 7fe2b1d1..143899d4 100644 --- a/.github/workflows/.build_livekeys.yml +++ b/.github/workflows/.build_livekeys.yml @@ -98,12 +98,12 @@ jobs: - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v1 with: - python-version: 3.9 + python-version: 3.7 - name: Setup Qt MacOS if: runner.os == 'macOS' run: | - pip3 install aqtinstall + pip3 install aqtinstall==1.1.4 aqt install 5.14.2 --outputdir /opt/qt mac desktop clang_64 -m qtwebengine qtquick3d aqt doc 5.14.2 --outputdir /opt/qt mac desktop -m qtwebengine export QTDIR=/opt/qt/5.14.2/clang_64 @@ -112,7 +112,7 @@ jobs: - name: Setup Qt Linux if: runner.os == 'Linux' run: | - pip3 install aqtinstall + pip3 install aqtinstall==1.1.4 echo "Installed aqtinstall" aqt install 5.14.2 --outputdir /opt/qt linux desktop gcc_64 -m qtwebengine qtquick3d aqt doc 5.14.2 --outputdir /opt/qt linux desktop -m qtwebengine From 718e5d1ea36289d5c1d807d020245c6c6d7b273f Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Thu, 22 Apr 2021 00:49:53 +0300 Subject: [PATCH 02/91] Update .build_livekeys.yml --- .github/workflows/.build_livekeys.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/.build_livekeys.yml b/.github/workflows/.build_livekeys.yml index 143899d4..88571eca 100644 --- a/.github/workflows/.build_livekeys.yml +++ b/.github/workflows/.build_livekeys.yml @@ -98,7 +98,7 @@ jobs: - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v1 with: - python-version: 3.7 + python-version: 3.8 - name: Setup Qt MacOS if: runner.os == 'macOS' From 079fed38ddb8b10ff8f7be378e90d841a00e8a72 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 4 May 2021 11:10:37 +0300 Subject: [PATCH 03/91] Workspace: Updated API Added workspace.wizards. Documented workspace.wizards. Updated ProjectFileSystem context menu. --- application/qml/ProjectEnvironment.qml | 572 +++++++++++------- application/qml/ProjectFileSystem.qml | 163 +---- application/qml/StartupBox.qml | 6 +- application/qml/Top.qml | 6 +- doc/pages/layer-workspace-wizards.md | 145 +++++ doc/pages/layer-workspace.md | 31 + lib/lveditor/src/workspacelayer.cpp | 2 + lib/lveditor/src/workspacelayer.h | 8 + .../qml/WorkspaceControlsExtension.qml | 102 ++++ 9 files changed, 673 insertions(+), 362 deletions(-) create mode 100644 doc/pages/layer-workspace-wizards.md create mode 100644 doc/pages/layer-workspace.md diff --git a/application/qml/ProjectEnvironment.qml b/application/qml/ProjectEnvironment.qml index cffa6b77..b369b560 100644 --- a/application/qml/ProjectEnvironment.qml +++ b/application/qml/ProjectEnvironment.qml @@ -22,6 +22,7 @@ import base 1.0 import editor 1.0 import editor.private 1.0 import fs 1.0 as Fs +import visual.input 1.0 as Input Item{ id: root @@ -30,10 +31,43 @@ Item{ property QtObject panes: null property QtObject runSpace: null + property QtObject theme: lk.layers.workspace.themes.current + property var documentationViewFactory : Component{ DocumentationView{} } + property Item addEntryOverlay : ProjectAddEntry{ + + property var callbackFunction: null + + style: QtObject{ + property color background: root.theme.colorScheme.middlegroundOverlay + property double borderWidth: 1 + property color borderColor: root.theme.colorScheme.middlegroundBorder + property double radius: 5 + + property QtObject headerStyle: root.theme.inputLabelStyle.textStyle + property QtObject inputStyle: root.theme.inputStyle + + property QtObject applyButton: root.theme.buttons.apply + } + + onAccepted: { + if ( isFile ){ + var f = project.fileModel.addFile(entry, name) + if ( callbackFunction ){ + callbackFunction(f) + } + } else { + var e = project.fileModel.addDirectory(entry, name) + if ( callbackFunction ){ + callbackFunction(e) + } + } + } + } + property Item navigation : ProjectNavigation{ id: projectNavigation anchors.fill: parent @@ -43,35 +77,7 @@ Item{ projectEnvironment.openFile(path, ProjectDocument.EditIfNotOpen) } onCloseFile: { - var doc = project.documentModel.isOpened(path) - if ( doc ){ - if ( doc.isDirty ){ - lk.layers.window.dialogs.message('File contains unsaved changes. Would you like to save them before closing?', - { - button1Name : 'Yes', - button1Function : function(mbox){ - doc.save() - project.closeFile(path) - mbox.close() - }, - button2Name : 'No', - button2Function : function(mbox){ - project.closeFile(path) - mbox.close() - }, - button3Name : 'Cancel', - button3Function : function(mbox){ - mbox.close() - }, - returnPressed : function(mbox){ - doc.save() - project.closeFile(path) - mbox.close() - } - }) - } else - project.closeFile(path) - } + root.wizards.closeFile(path) } onCancel: { if ( lk.layers.workspace.panes.activeItem ) @@ -79,6 +85,7 @@ Item{ } } + Connections{ target: project function onActiveChanged(){ @@ -199,231 +206,380 @@ Item{ function onLayerReady(layer){ if ( layer.name === 'workspace' ){ layer.commands.add(root, { - 'close' : [closeProject, "Close Project"], - 'open' : [openProject, "Open Project"], - 'new' : [newProject, "New Project"], - 'openFile' : [openFileDialog, "Open File"], - 'toggleVisibility' : [toggleVisibility, "Project: Toggle Visibility"] + 'close' : [wizards.closeProject, "Close Project"], + 'open' : [wizards.openProjectViaDialog, "Open Project"], + 'new' : [wizards.newProject, "New Project"], + 'openFile' : [wizards.openFileViaDialog, "Open File"], + 'toggleProjectVisibility' : [toggleVisibility, "Project: Toggle Visibility"] }) } } } - function checkUnsavedFiles(callback){ - var documentList = project.documentModel.listUnsavedDocuments() - callback = callback ? callback : function(){} - var message = '' - if ( documentList.length === 0 ){ - callback() - return; - } else if ( !project.isDirProject() ){ - message = "Your project file has unsaved changes. Would you like to save them before closing it?"; - } else { - var unsavedFiles = ''; - for ( var i = 0; i < documentList.length; ++i ){ - unsavedFiles += documentList[i] + "\n"; - } + property QtObject wizards : QtObject{ + + function openProjectDirViaDialog(callback){ + root.wizards.checkUnsavedFiles(function(){ + lk.layers.window.dialogs.openDir({}, function(url){ + project.closeProject() + project.openProject(url) + var path = Fs.UrlInfo.toLocalFile(url) + if ( callback ) + callback(path) + // lk.openProjectInstance(url) + }) + }) + } - message = "The following files have unsaved changes:\n"; - message += unsavedFiles - message += "Would you like to save them before closing the project?\n" + function openProjectFileViaDialog(callback){ + root.wizards.checkUnsavedFiles(function(){ + lk.layers.window.dialogs.openFile({}, function(url){ + project.closeProject() + project.openProject(url) + var path = Fs.UrlInfo.toLocalFile(url) + if ( callback ) + callback(path) + }) + }) + } + + function openProject(url, callback){ + root.wizards.checkUnsavedFiles(function(){ + project.closeProject() + project.openProject(url) + var path = Fs.UrlInfo.toLocalFile(url) + if ( callback ) + callback(path) + // lk.openProjectInstance(url) + }) + } + + function newProject(callback){ + root.wizards.closeProject(function(){ + project.newProject() + if ( callback ) + callback() + // lk.newProjectInstance() + }) + } + + function closeProject(callback){ + root.wizards.checkUnsavedFiles(function(){ + project.closeProject() + if ( callback ) + callback() + }) } - lk.layers.window.dialogs.message(message, { - button1Name : 'Yes', - button1Function : function(box){ - box.close() - if ( !project.isDirProject() && documentList.length === 1 && documentList[0] === ':/0'){ - var closeCallback = callback; - var untitledDocument = project.documentModel.isOpened(documentList[0]) - lk.layers.window.dialogs.saveFile( - { filters: [ "Qml files (*.qml)", "All files (*)" ] }, + function openFileViaDialog(callback){ + var openCallback = function(url){ + if ( project.rootPath === '' ){ + project.openProject(url) + var path = Fs.UrlInfo.toLocalFile(url) + if ( callback ) + callback(path) + } else if ( project.isFileInProject(url) ){ + root.wizards.openFile(url, ProjectDocument.EditIfNotOpen, callback) + } else { + var fileUrl = url + lk.layers.window.dialogs.message( + 'File is outside project scope. Would you like to open it as a new project?', + { + button1Name : 'Open as project', + button1Function : function(mbox){ + var projectUrl = fileUrl + root.wizards.closeProject(function(){ + project.openProject(projectUrl) + var path = Fs.UrlInfo.toLocalFile(projectUrl) + if ( callback ) + callback(path) + }) + mbox.close() + }, + button3Name : 'Cancel', + button3Function : function(mbox){ + mbox.close() + }, + returnPressed : function(mbox){ + var projectUrl = fileUrl + root.wizards.closeProject(function(){ + project.openProject(projectUrl) + var path = Fs.UrlInfo.toLocalFile(projectUrl) + if ( callback ) + callback(path) + }) + mbox.close() + } + }) + } + } + + if ( !project.isDirProject() ){ + root.wizards.checkUnsavedFiles(function(){ + lk.layers.window.dialogs.openFile( + { filters: ["Qml files (*.qml)", "All files (*)"] }, function(url){ - if ( !untitledDocument.saveAs(url) ){ - lk.layers.window.dialogs.message( - 'Failed to save file to: ' + url, - { - button3Name : 'Ok', - button3Function : function(mbox){ mbox.close() } - } - ) - return; - } project.closeProject() - closeCallback() + project.openProject(url) + var path = Fs.UrlInfo.toLocalFile(url) + if ( callback ) + callback(path) } ) - } else if ( !project.documentModel.saveDocuments() ){ - var unsavedList = project.documentModel.listUnsavedDocuments() - unsavedFiles = ''; - for ( var i = 0; i < unsavedList.length; ++i ){ - unsavedFiles += project.fileModel.printableName(unsavedList[i]) + "\n"; + }) + } else { + lk.layers.window.dialogs.openFile( + { filters: ["Qml files (*.qml)", "All files (*)"] }, + openCallback + ) + } + } + + /// callback will receive: path, document, pane + function openFile(path, mode, callback){ + var pane = lk.layers.workspace.interceptFile(path, mode) + if ( pane ) + return pane + + if ( Fs.Path.hasExtensions(path, 'html')){ + if ( Fs.Path.hasExtensions(path, 'doc.html')){ + var docItem = documentationViewFactory.createObject() + if ( docItem ){ + docItem.loadDocumentationHtml(path) + var docPane = mainSplit.findPaneByType('documentation') + if ( !docPane ){ + var storeWidth = root.width + docPane = root.panes.createPane('documentation', {}, [400, 400]) + root.panes.container.splitPane(0, docPane) + } + docPane.pageTitle = Fs.Path.baseName(path) + docPane.page = docItem + + if ( callback ) + callback(path, null, docPane) + + return docPane } + } + } - message = 'Failed to save the following files:\n' - message += unsavedFiles - box.close() - lk.layers.window.dialogs.message(message,{ - button1Name : 'Close', + var doc = project.openTextFile(path, mode) + if ( !doc ) + return; + var fe = root.panes.focusPane('editor') + if ( !fe ){ + fe = root.panes.createPane('editor', {}, [400, 0]) + root.panes.container.splitPane(0, fe) + + var containerPanes = root.panes.container.panes + if ( containerPanes.length > 2 && containerPanes[2].width > 500 + containerPanes[0].width){ + containerPanes[0].width = containerPanes[0].width * 2 + fe.width = 400 + } + } + if ( callback ) + callback(path, doc, fe) + fe.document = doc + return fe + } + + function closeFile(path, callback){ + var doc = project.documentModel.isOpened(path) + if ( doc ){ + if ( doc.isDirty ){ + lk.layers.window.dialogs.message('File contains unsaved changes. Would you like to save them before closing?', + { + button1Name : 'Yes', button1Function : function(mbox){ + doc.save() + project.closeFile(path) + callback() mbox.close() + }, + button2Name : 'No', + button2Function : function(mbox){ + project.closeFile(path) callback() + mbox.close() }, button3Name : 'Cancel', button3Function : function(mbox){ mbox.close() }, returnPressed : function(mbox){ - mbox.close() + doc.save() + project.closeFile(path) callback() + mbox.close() } }) } else { - box.close() + project.closeFile(path) callback() } - }, - button2Name : 'No', - button2Function : function(mbox){ - mbox.close() - callback() - }, - button3Name : 'Cancel', - button3Function : function(mbox){ - mbox.close() - }, - returnPressed : function(mbox){ - mbox.close() - callback() } - }) - } - - function closeProject(callback){ - root.checkUnsavedFiles(function(){ - project.closeProject() - if ( callback ) - callback() - }) + } - } - function openProject(){ - root.checkUnsavedFiles(function(){ - lk.layers.window.dialogs.openDir({}, function(url){ - project.closeProject() - project.openProject(url) -// lk.openProjectInstance(url) - }) - }) - } - function openProjectPath(url){ - root.checkUnsavedFiles(function(){ - project.closeProject() - project.openProject(url) -// lk.openProjectInstance(url) - }) - } + function addFile(path, opt, callback){ - function newProject(){ - closeProject(function(){ - project.newProject() -// lk.newProjectInstance() - }) - } + var entry = project.fileModel.findPath(path) + if ( !entry ){ + //TODO: Enable if directory is outside the project + lk.layers.workspace.messages.pushError("Path not found in project: " + path, 100) + return + } - function openFileDialog(){ - var openCallback = function(url){ - if ( project.rootPath === '' ){ - project.openProject(url) - } else if ( project.isFileInProject(url) ){ - openFile(url, ProjectDocument.EditIfNotOpen) + root.addEntryOverlay.isFile = true + root.addEntryOverlay.entry = entry + if ( opt.hasOwnProperty('heading') ){ + root.addEntryOverlay.heading = opt['heading'] } else { - var fileUrl = url - lk.layers.window.dialogs.message( - 'File is outside project scope. Would you like to open it as a new project?', - { - button1Name : 'Open as project', - button1Function : function(mbox){ - var projectUrl = fileUrl - root.closeProject(function(){ - project.openProject(projectUrl) - }) - mbox.close() - }, - button3Name : 'Cancel', - button3Function : function(mbox){ - mbox.close() - }, - returnPressed : function(mbox){ - var projectUrl = fileUrl - root.closeProject(function(){ - project.openProject(projectUrl) - }) - mbox.close() - } - }) + root.addEntryOverlay.heading = 'Add file in ' + entry.path + } + if ( opt.hasOwnProperty('suggestion') ){ + root.addEntryOverlay.setInitialValue(opt['suggestion']) + } else { + root.addEntryOverlay.setInitialValue('') + } + if ( opt.hasOwnProperty('extension') ){ + root.addEntryOverlay.extension = opt['extension'] + } else { + root.addEntryOverlay.extension = '' } - } - if ( !project.isDirProject() ){ - root.checkUnsavedFiles(function(){ - lk.layers.window.dialogs.openFile( - { filters: ["Qml files (*.qml)", "All files (*)"] }, - function(url){ - project.closeProject() - project.openProject(url) - } - ) - }) - } else { - lk.layers.window.dialogs.openFile( - { filters: ["Qml files (*.qml)", "All files (*)"] }, - openCallback - ) + root.addEntryOverlay.callbackFunction = function(file){ + if ( callback ) + callback(file) + } + + lk.layers.window.dialogs.overlayBox(root.addEntryOverlay) } - } - function openFile(path, mode){ - var pane = lk.layers.workspace.interceptFile(path, mode) - if ( pane ) - return pane - - if ( Fs.Path.hasExtensions(path, 'html')){ - if ( Fs.Path.hasExtensions(path, 'doc.html')){ - var docItem = documentationViewFactory.createObject() - if ( docItem ){ - docItem.loadDocumentationHtml(path) - var docPane = mainSplit.findPaneByType('documentation') - if ( !docPane ){ - var storeWidth = root.width - docPane = root.panes.createPane('documentation', {}, [400, 400]) - root.panes.container.splitPane(0, docPane) - } - docPane.pageTitle = Fs.Path.baseName(path) - docPane.page = docItem + function addDirectory(path, opt, callback){ + var entry = project.fileModel.findPath(path) + if ( !entry ){ + //TODO: Enable if directory is outside the project + lk.layers.workspace.messages.pushError("Path not found in project: " + path, 100) + } - return docPane - } + root.addEntryOverlay.isFile = false + root.addEntryOverlay.entry = entry + if ( opt.hasOwnProperty('heading') ){ + root.addEntryOverlay.heading = opt['heading'] + } else { + root.addEntryOverlay.heading = 'Add file in ' + entry.path + } + if ( opt.hasOwnProperty('suggestion') ){ + root.addEntryOverlay.setInitialValue(opt['suggestion']) + } else { + root.addEntryOverlay.setInitialValue('') } + if ( opt.hasOwnProperty('extension') ){ + root.addEntryOverlay.extension = opt['extension'] + } else { + root.addEntryOverlay.extension = '' + } + + root.addEntryOverlay.callbackFunction = function(dir){ + if ( callback ) + callback(dir) + } + + lk.layers.window.dialogs.overlayBox(root.addEntryOverlay) } - var doc = project.openTextFile(path, mode) - if ( !doc ) - return; - var fe = root.panes.focusPane('editor') - if ( !fe ){ - fe = root.panes.createPane('editor', {}, [400, 0]) - root.panes.container.splitPane(0, fe) + function checkUnsavedFiles(callback){ + var documentList = project.documentModel.listUnsavedDocuments() + callback = callback ? callback : function(){} + var message = '' + if ( documentList.length === 0 ){ + callback() + return; + } else if ( !project.isDirProject() ){ + message = "Your project file has unsaved changes. Would you like to save them before closing it?"; + } else { + var unsavedFiles = ''; + for ( var i = 0; i < documentList.length; ++i ){ + unsavedFiles += documentList[i] + "\n"; + } - var containerPanes = root.panes.container.panes - if ( containerPanes.length > 2 && containerPanes[2].width > 500 + containerPanes[0].width){ - containerPanes[0].width = containerPanes[0].width * 2 - fe.width = 400 + message = "The following files have unsaved changes:\n"; + message += unsavedFiles + message += "Would you like to save them before closing the project?\n" } + lk.layers.window.dialogs.message(message, { + button1Name : 'Yes', + button1Function : function(box){ + box.close() + + if ( !project.isDirProject() && documentList.length === 1 && documentList[0] === ':/0'){ + var closeCallback = callback; + var untitledDocument = project.documentModel.isOpened(documentList[0]) + + lk.layers.window.dialogs.saveFile( + { filters: [ "Qml files (*.qml)", "All files (*)" ] }, + function(url){ + if ( !untitledDocument.saveAs(url) ){ + lk.layers.window.dialogs.message( + 'Failed to save file to: ' + url, + { + button3Name : 'Ok', + button3Function : function(mbox){ mbox.close() } + } + ) + return; + } + project.closeProject() + closeCallback() + } + ) + } else if ( !project.documentModel.saveDocuments() ){ + var unsavedList = project.documentModel.listUnsavedDocuments() + unsavedFiles = ''; + for ( var i = 0; i < unsavedList.length; ++i ){ + unsavedFiles += project.fileModel.printableName(unsavedList[i]) + "\n"; + } + + message = 'Failed to save the following files:\n' + message += unsavedFiles + box.close() + lk.layers.window.dialogs.message(message,{ + button1Name : 'Close', + button1Function : function(mbox){ + mbox.close() + callback() + }, + button3Name : 'Cancel', + button3Function : function(mbox){ + mbox.close() + }, + returnPressed : function(mbox){ + mbox.close() + callback() + } + }) + } else { + box.close() + callback() + } + }, + button2Name : 'No', + button2Function : function(mbox){ + mbox.close() + callback() + }, + button3Name : 'Cancel', + button3Function : function(mbox){ + mbox.close() + }, + returnPressed : function(mbox){ + mbox.close() + callback() + } + }) } - fe.document = doc - return fe } + } diff --git a/application/qml/ProjectFileSystem.qml b/application/qml/ProjectFileSystem.qml index 9532a979..5641af01 100644 --- a/application/qml/ProjectFileSystem.qml +++ b/application/qml/ProjectFileSystem.qml @@ -35,30 +35,13 @@ Pane{ property Theme currentTheme : lk.layers.workspace.themes.current - property Item addEntryOverlay : ProjectAddEntry{ - onAccepted: { - if ( isFile ){ - var f = project.fileModel.addFile(entry, name) - lk.layers.workspace.project.openFile(f.path, ProjectDocument.Edit) - } else { - project.fileModel.addDirectory(entry, name) - } - } - } - - function addEntry(parentEntry, isFile){ - root.addEntryOverlay.entry = parentEntry - root.addEntryOverlay.isFile = isFile - - lk.layers.window.dialogs.overlayBox(root.addEntryOverlay) - } function openEntry(entry, monitor){ - lk.layers.workspace.project.openFile( + lk.layers.workspace.wizards.openFile( entry.path, monitor ? ProjectDocument.Monitor : ProjectDocument.EditIfNotOpen ) } function editEntry(entry){ - lk.layers.workspace.project.openFile(entry.path, ProjectDocument.Edit) + lk.layers.workspace.wizards.openFile(entry.path, ProjectDocument.Edit) } function removeEntry(entry, isFile){ var message = '' @@ -153,6 +136,10 @@ Pane{ project.fileModel.renameEntry(entry, newName) } + property QtObject delegateOperations: QtObject{ + + } + Rectangle{ id: paneTop anchors.left: parent.left @@ -405,13 +392,19 @@ Pane{ if( mouse.button === Qt.RightButton ){ if ( styleData.value.isFile ){ view.setContextDelegate(entryDelegate) - fileContextMenu.popup() + lk.layers.workspace.panes.activateItem(entryDelegate, root) + lk.layers.workspace.panes.openContextMenu(entryDelegate, root) +// fileContextMenu.popup() } else if ( styleData.value.path === project.rootPath ){ view.setContextDelegate(entryDelegate) - projectContextMenu.popup() + lk.layers.workspace.panes.activateItem(entryDelegate, root) + lk.layers.workspace.panes.openContextMenu(entryDelegate, root) +// projectContextMenu.popup() } else { view.setContextDelegate(entryDelegate) - dirContextMenu.popup() + lk.layers.workspace.panes.activateItem(entryDelegate, root) + lk.layers.workspace.panes.openContextMenu(entryDelegate, root) +// dirContextMenu.popup() } } else if ( mouse.button === Qt.LeftButton ) { if ( entryDelegate.editMode){ @@ -484,132 +477,6 @@ Pane{ view.expand(index) } } - - Menu { - id: fileContextMenu - - style: ContextMenuStyle{} - - MenuItem{ - text: "Edit File" - onTriggered: { - view.contextDelegate.openFile() - } - } - MenuItem{ - text: "Monitor file" - onTriggered: { - view.contextDelegate.monitorFile() - } - } - - MenuItem{ - text: "Set As Active" - onTriggered: { - view.contextDelegate.setActive() - } - } - MenuItem{ - text: "Add As Runnable" - onTriggered: { - view.contextDelegate.addRunnable() - } - } - MenuItem { - text: "Rename" - onTriggered: { - view.contextDelegate.editMode = true - view.contextDelegate.focusText() - } - } - MenuItem { - text: "Delete" - onTriggered: { - root.removeEntry(view.contextDelegate.entry(), false) - } - } - } - - Menu { - id: dirContextMenu - style: ContextMenuStyle{} - MenuItem{ - text: "Show in Explorer" - onTriggered: { - view.contextDelegate.openExternally() - } - } - MenuItem { - text: "Rename" - onTriggered: { - view.contextDelegate.editMode = true - view.contextDelegate.focusText() - } - } - MenuItem{ - text: "Delete" - onTriggered: { - root.removeEntry(view.contextDelegate.entry(), true) - } - } - MenuItem { - text: "Add File" - onTriggered: { - root.addEntry(view.contextDelegate.entry(), true) - } - } - MenuItem { - text: "Add Directory" - onTriggered: { - root.addEntry(view.contextDelegate.entry(), false) - } - } - } - - Menu { - id: projectContextMenu - style: ContextMenuStyle{} - MenuItem{ - text: "Show in Explorer" - onTriggered: { - view.contextDelegate.openExternally() - } - } - MenuItem{ - text: "Close Project" - onTriggered: { - lk.layers.workspace.commands.execute('window.workspace.project.close') - } - } - MenuItem{ - text: "New Document" - onTriggered: { - var fe = project.fileModel.addTemporaryFile() - lk.layers.workspace.project.openFile(fe.path, ProjectDocument.Edit) - } - } - - MenuItem{ - text: "New Runnable" - onTriggered: { - var fe = project.fileModel.addTemporaryFile() - lk.layers.workspace.project.openFile(fe.path, ProjectDocument.Edit) - project.openRunnable(fe.path, [fe.path]) - } - } - MenuItem { - text: "Add File" - onTriggered: { - root.addEntry(view.contextDelegate.entry(), true) - } - } - MenuItem { - text: "Add Directory" - onTriggered: { - root.addEntry(view.contextDelegate.entry(), false) - } - } - } } } diff --git a/application/qml/StartupBox.qml b/application/qml/StartupBox.qml index 07dc9309..95cddb5f 100644 --- a/application/qml/StartupBox.qml +++ b/application/qml/StartupBox.qml @@ -67,7 +67,7 @@ Rectangle{ id : newMArea anchors.fill: parent hoverEnabled: true - onClicked: lk.layers.workspace.project.newProject() + onClicked: lk.layers.workspace.wizards.newProject() } Image { @@ -106,7 +106,7 @@ Rectangle{ id : openProjectMArea anchors.fill: parent hoverEnabled: true - onClicked: lk.layers.workspace.project.openProject() + onClicked: lk.layers.workspace.wizards.openProjectDirViaDialog() } Image { @@ -147,7 +147,7 @@ Rectangle{ id : openMArea anchors.fill: parent hoverEnabled: true - onClicked: lk.layers.workspace.project.openFileDialog() + onClicked: lk.layers.workspace.wizards.openProjectFileViaDialog() } Image { diff --git a/application/qml/Top.qml b/application/qml/Top.qml index 961bd58e..fd0a8c17 100644 --- a/application/qml/Top.qml +++ b/application/qml/Top.qml @@ -113,7 +113,7 @@ Rectangle { id : newMArea anchors.fill: parent hoverEnabled: true - onClicked: lk.layers.workspace.project.newProject() + onClicked: lk.layers.workspace.wizards.newProject() } Workspace.Tooltip{ mouseOver: newMArea.containsMouse @@ -183,7 +183,7 @@ Rectangle { id : openMArea anchors.fill: parent hoverEnabled: true - onClicked: lk.layers.workspace.project.openFileDialog() + onClicked: lk.layers.workspace.wizards.openFileViaDialog() } Workspace.Tooltip{ mouseOver: openMArea.containsMouse @@ -217,7 +217,7 @@ Rectangle { id : openProjectMArea anchors.fill: parent hoverEnabled: true - onClicked: lk.layers.workspace.project.openProject() + onClicked: lk.layers.workspace.wizards.openProjectDirViaDialog() } Workspace.Tooltip{ mouseOver: openProjectMArea.containsMouse diff --git a/doc/pages/layer-workspace-wizards.md b/doc/pages/layer-workspace-wizards.md new file mode 100644 index 00000000..3c2a6f3b --- /dev/null +++ b/doc/pages/layer-workspace-wizards.md @@ -0,0 +1,145 @@ +# Workspace Layer Wizards + +Wizards are predefined user interactions that go through different checks when +working with the project. + +For example, a file in the project can be closed using the workspace project object: + +```js +lk.layers.workspace.project.closeFile('/path/to/file') +``` + +This will however, close the file without saving, and without checking with the user first. +By using a wizard, we avoid this problem, and let Livekeys deal with all the checks: + +```js +lk.layers.workspace.wizards.closeFile('/path/to/file') +``` + +This will prompt the user to save the file if the file has any unsaved changes. + + +The following wizards are available: + +#### `openProjectDirViaDialog(callback)` + +Opens a new project directory through a dialog box, allowing the user to choose a path. If a project is opened before, it will close it via the `closeProject()` function. + +```js +lk.layers.workspace.wizards.openProjectDirViaDialog(function(path){ + console.log('Project opened:' + path) +}) +``` + +#### `openProjectFileViaDialog(callback) + +Opens a new project file through a dialog box, allowing the user to choose a path. If a project is opened before, it will close it via the `closeProject()` function. + +```js +lk.layers.workspace.wizards.openProjectFileViaDialog(function(path){ + console.log('Project opened:' + path) +}) +``` + +#### `openProject(url, callback)` + +Opens a project at `path`. If there's a project already opened, it will close +it before. + +```js +lk.layers.workspace.wizards.openProject('/path/to/project', function(path){ + console.log('Project opened:' + path) +}) +``` + +#### `newProject(callback)` + +Creates a new project. If there's a project already opened, it will close +it before. + + +```js +lk.layers.workspace.wizards.newProject(function(){ + console.log('Project created.') +}) +``` + + +#### `closeProject(callback)` + +Closes the current project, checking for any unsaved files, and asking the user for confirmation: + +```js +lk.layers.workspace.wizards.closeProject(function(){ + console.log('Project closed') +}) +``` + + +#### `openFileViaDialog(callback)` + +Opens a new file by opening a dialog box for the user to choose one. Depending on +the extensions installed, the file might be opened as a TextDocument, or a simple +Document. A pane will be initialised as well if needed. + +```js +lk.layers.workspace.wizards.openFileViaDialog(function(path, document, pane){ + console.log('File opened: ' + path, document, pane) +}) +``` + +#### `openFile(path, mode, callback)` + +Opens a new file at the given `path`. The mode can be `Document.Edit`, +`Document.Monitor` or `Document.EditIfNotOpen`. + +```js +lk.layers.workspace.wizards.openFile('/path/to/file', Document.Edit, function(path, document, pane){ + console.log('File opened: ' + path, document, pane) +}) +``` + +#### `closeFile(path, callback)` + +Closes a file at the given `path` if there's a file opened. Will perform a check +to save the file if the file has been changed since the last save. + +```js +lk.layers.workspace.wizards.closeFile('/path/to/file', function(){ + console.log('File closed.') +}) +``` + +#### `addFile(path, opt, callback)` + +Queries the user for a file name, after which it will create it at the given `path`. `path` must be inside the project directory. +Options can be one of the following: + * heading: specific heading shown in the add box + * suggestion: any suggestion on the name of the file + * extension: extension to be set when adding the file. + +```js +lk.layers.workspace.wizards.addFile('/path/to/path/in/project', {}, function(path){ + console.log('File added: ' + path) +}) +``` + +#### `addDirectory(path, callback)` + +Queries the user for a directory name, after which it will create it at the given `path`. `path` must be inside the project directory. + +```js +lk.layers.workspace.wizards.addDirectory('/path/to/path/in/project', function(path){ + console.log('Directory added: ' + path) +}) +``` + +#### `checkUnsavedFiles(callback)` + +Performs a check and asks the user what he wants to do with all the unsaved files. + +```js +lk.layers.workspace.wizards.checkUnsavedFiles(function(){ + console.log('Check finished.') +}) +``` diff --git a/doc/pages/layer-workspace.md b/doc/pages/layer-workspace.md new file mode 100644 index 00000000..3705653a --- /dev/null +++ b/doc/pages/layer-workspace.md @@ -0,0 +1,31 @@ +# Workspace Layer + +The workspace layer adds full support for a development environment, with a large number of features: + + * Project management: Opening, closing projects + * Project file system manamgent: Creating, Editing, Deleting files + * Pane management with various pane types: + * Code Editor + * Logging + * Project view + * Runnable view + * Documentation view + * Minimal Browser + * Customisable Themes + * Code editor with highlighting and auto-completion support + * Customisable Palettes + * Keyboard shortcuts + * Commands + +The workspace layer is loaded by default when starting livekeys. + + +## Workspace Layer API + +Access to the workspace layer is done via `lk.layers` property: `lk.layers.workspace` + +The API is split in the following sections: + + * Project: Project functionality, like closing the project, opening a new file, monitoring file changes. + * Wizzards: Provides wizzards for users to work with the project such as opening/closing files, etc + * Panes: Working with panes: splitting, creating, removing different pane types diff --git a/lib/lveditor/src/workspacelayer.cpp b/lib/lveditor/src/workspacelayer.cpp index fdc7b187..24899feb 100644 --- a/lib/lveditor/src/workspacelayer.cpp +++ b/lib/lveditor/src/workspacelayer.cpp @@ -38,6 +38,7 @@ namespace lv{ WorkspaceLayer::WorkspaceLayer(QObject *parent) : Layer(parent) , m_projectEnvironment(nullptr) + , m_wizards(nullptr) , m_panes(nullptr) , m_viewRoot(nullptr) , m_messageStack(new lv::WorkspaceMessageStack(this)) @@ -165,6 +166,7 @@ void WorkspaceLayer::loadView(ViewEngine *engine, QObject *parent){ ); m_projectEnvironment = m_viewRoot->property("projectEnvironment").value(); + m_wizards = m_projectEnvironment->property("wizards").value(); m_panes = m_viewRoot->property("panes").value(); m_nextViewParent = m_viewRoot->property("runSpace").value(); QJSValue paneFactories = m_panes->property("factories").value(); diff --git a/lib/lveditor/src/workspacelayer.h b/lib/lveditor/src/workspacelayer.h index 0ef1a83f..03b0039c 100644 --- a/lib/lveditor/src/workspacelayer.h +++ b/lib/lveditor/src/workspacelayer.h @@ -29,6 +29,7 @@ class WorkspaceLayer : public Layer{ Q_OBJECT Q_PROPERTY(QObject* project READ project NOTIFY projectChanged) + Q_PROPERTY(QObject* wizards READ wizards NOTIFY wizardsChanged) Q_PROPERTY(QObject* panes READ panes NOTIFY panesChanged) Q_PROPERTY(lv::WorkspaceMessageStack* messages READ messages CONSTANT) Q_PROPERTY(lv::Commands* commands READ commands CONSTANT) @@ -49,6 +50,7 @@ class WorkspaceLayer : public Layer{ QObject * viewRoot() override; QObject* project() const; + QObject* wizards() const; QObject* panes() const; lv::WorkspaceMessageStack* messages() const; @@ -87,6 +89,7 @@ public slots: signals: void projectChanged(); + void wizardsChanged(); void panesChanged(); private: @@ -100,6 +103,7 @@ public slots: QObject* m_nextViewParent; QObject* m_projectEnvironment; + QObject* m_wizards; QObject* m_panes; QObject* m_viewRoot; @@ -126,6 +130,10 @@ inline QObject *WorkspaceLayer::project() const{ return m_projectEnvironment; } +inline QObject *WorkspaceLayer::wizards() const{ + return m_wizards; +} + inline QObject *WorkspaceLayer::panes() const{ return m_panes; } diff --git a/plugins/workspace/qml/WorkspaceControlsExtension.qml b/plugins/workspace/qml/WorkspaceControlsExtension.qml index 768cab48..805b504d 100644 --- a/plugins/workspace/qml/WorkspaceControlsExtension.qml +++ b/plugins/workspace/qml/WorkspaceControlsExtension.qml @@ -73,6 +73,108 @@ WorkspaceExtension{ } ] } + }, + { + whenPane: 'projectFileSystem', + intercept: function(pane, item){ + if ( item.entry().isFile ){ + return [ + { + name : "Edit File", + action : item.openFile + }, { + name : "Monitor file", + action : item.monitorFile + }, { + name : "Set As Active", + action : item.setActive + }, { + name : "Add As Runnable", + action : item.addRunnable + }, { + name : "Rename", + action : function(){ + item.editMode = true + item.focusText() + } + }, { + name : "Delete", + action : function(){ + pane.removeEntry(item.entry(), false) + } + } + ] + } else if ( item.path() === project.rootPath ){ + return [ + { + name : "Show in Explorer", + action : item.openExternally + }, { + name : "Close Project", + action : function(){ + lk.layers.workspace.commands.execute('window.workspace.project.close') + } + }, { + name : "New Document", + action : function(){ + var fe = project.fileModel.addTemporaryFile() + lk.layers.workspace.wizards.openFile(fe.path, ProjectDocument.Edit) + } + }, { + name : "New Runnable", + action : function(){ + var fe = project.fileModel.addTemporaryFile() + lk.layers.workspace.wizards.openFile(fe.path, ProjectDocument.Edit) + project.openRunnable(fe.path, [fe.path]) + } + }, { + name : "Add File", + action : function(){ + lk.layers.workspace.wizards.addFile(item.entry().path, {}, function(f){ + lk.layers.workspace.wizards.openFile(f.path, ProjectDocument.Edit) + }) + } + }, { + name : "Add Directory", + action : function(){ + lk.layers.workspace.wizards.addDirectory(item.entry().path, {}, function(d){}) + } + } + ] + } else { + return [ + { + name : "Show in Explorer", + action : item.openExternally + }, + { + name : "Rename", + action : function(){ + item.editMode = true + item.focusText() + } + }, + { + name : "Delete", + action : function(){ + pane.removeEntry(item.entry(), true) + } + }, { + name : "Add File", + action : function(){ + lk.layers.workspace.wizards.addFile(item.entry().path, function(f){ + lk.layers.workspace.wizards.openFile(f.path, ProjectDocument.Edit) + }) + } + }, { + name : "Add Directory", + action : function(){ + lk.layers.workspace.wizards.addDirectory(item.entry().path, function(d){}) + } + } + ] + } + } } ] From 85ad4c262fda62c8ee4310939efa172b138ad13f Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 4 May 2021 11:12:12 +0300 Subject: [PATCH 04/91] Updated editor.Document and editor.ProjectDocument Added Document::contentLength and added editing state to ProjectDocument::insert method. --- lib/lveditor/src/document.cpp | 7 ++++++ lib/lveditor/src/document.h | 1 + lib/lveditor/src/projectdocument.cpp | 37 ++++++++++++++++++++-------- lib/lveditor/src/projectdocument.h | 4 ++- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/lib/lveditor/src/document.cpp b/lib/lveditor/src/document.cpp index 25926f97..544a36b3 100644 --- a/lib/lveditor/src/document.cpp +++ b/lib/lveditor/src/document.cpp @@ -47,6 +47,13 @@ void Document::readContent(){ } } +/** + * \brief Returns the content legnth of this document + */ +int Document::contentLength(){ + return m_content.length(); +} + /** * \brief Save modified document to its respective file */ diff --git a/lib/lveditor/src/document.h b/lib/lveditor/src/document.h index 16194b62..7756883c 100644 --- a/lib/lveditor/src/document.h +++ b/lib/lveditor/src/document.h @@ -78,6 +78,7 @@ class LV_EDITOR_EXPORT Document : public QObject{ public slots: virtual void setContent(const QByteArray& content); virtual void readContent(); + virtual int contentLength(); bool save(); bool saveAs(const QString& path); bool saveAs(const QUrl& url); diff --git a/lib/lveditor/src/projectdocument.cpp b/lib/lveditor/src/projectdocument.cpp index 604ae224..186d0196 100644 --- a/lib/lveditor/src/projectdocument.cpp +++ b/lib/lveditor/src/projectdocument.cpp @@ -105,6 +105,10 @@ void ProjectDocument::readContent(){ } } +int ProjectDocument::contentLength(){ + return m_textDocument->characterCount(); +} + /** * @brief ProjectDocument::updateSections * @@ -481,18 +485,31 @@ QString ProjectDocument::substring(int from, int length) const{ return tc.selectedText(); } -void ProjectDocument::insert(int from, int length, const QString &text){ - addEditingState(ProjectDocument::Assisted); +void ProjectDocument::insert(int from, int length, const QString &text, int editingState){ + if ( editingState == ProjectDocument::Assisted || editingState == ProjectDocument::Palette || editingState == ProjectDocument::Runtime ){ + auto es = static_cast(editingState); + addEditingState(es); + + QTextCursor tc(m_textDocument); + tc.beginEditBlock(); + tc.setPosition(from); + tc.setPosition(from + length - 1, QTextCursor::KeepAnchor); + tc.removeSelectedText(); + tc.insertText(text); + tc.endEditBlock(); + + removeEditingState(es); + } else { + QTextCursor tc(m_textDocument); + tc.beginEditBlock(); + tc.setPosition(from); + tc.setPosition(from + length, QTextCursor::KeepAnchor); + tc.removeSelectedText(); + tc.insertText(text); + tc.endEditBlock(); + } - QTextCursor tc(m_textDocument); - tc.beginEditBlock(); - tc.setPosition(from); - tc.setPosition(from + length, QTextCursor::KeepAnchor); - tc.removeSelectedText(); - tc.insertText(text); - tc.endEditBlock(); - removeEditingState(ProjectDocument::Assisted); } int ProjectDocument::offsetAtLine(int line) const{ diff --git a/lib/lveditor/src/projectdocument.h b/lib/lveditor/src/projectdocument.h index 03f3a1fc..b963848d 100644 --- a/lib/lveditor/src/projectdocument.h +++ b/lib/lveditor/src/projectdocument.h @@ -188,6 +188,7 @@ class LV_EDITOR_EXPORT ProjectDocumentBlockData : public QTextBlockUserData{ class LV_EDITOR_EXPORT ProjectDocument : public Document{ Q_OBJECT + Q_ENUMS(EditingState) public: /** Iterator through sections */ @@ -268,8 +269,9 @@ public slots: void __documentContentsChanged(int position, int charsRemoved, int charsAdded); virtual void readContent() override; + virtual int contentLength() override; QString substring(int from, int length) const; - void insert(int from, int length, const QString& text); + void insert(int from, int length, const QString& text, int editingState = ProjectDocument::Assisted); int offsetAtLine(int line) const; signals: From 9cb0d4ce34258c8807ea0f081391cee40113e10c Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 4 May 2021 11:14:31 +0300 Subject: [PATCH 05/91] base: Replaced StreamIterator to StreamValue. --- lib/lveditqmljs/src/qmljssettings.cpp | 1 + lib/lvview/src/lvview.pri | 2 - lib/lvview/src/qmlstreamiterator.cpp | 18 ---- lib/lvview/src/qmlstreamiterator.h | 57 ----------- lib/lvview/src/viewengine.cpp | 2 - plugins/base/baseqml/baseqml.pro | 1 + .../baseqml/palettes/StreamValuePalette.json | 7 ++ plugins/base/baseqml/qml/live.plugin.json | 3 +- plugins/base/baseqml/qml/plugins.qmltypes | 60 ++++++------ plugins/base/baseqml/src/base_plugin.cpp | 2 + plugins/base/baseqml/src/baseqml.pri | 2 + plugins/base/baseqml/src/qmlstreamvalue.cpp | 95 +++++++++++++++++++ plugins/base/baseqml/src/qmlstreamvalue.h | 66 +++++++++++++ 13 files changed, 203 insertions(+), 113 deletions(-) delete mode 100644 lib/lvview/src/qmlstreamiterator.cpp delete mode 100644 lib/lvview/src/qmlstreamiterator.h create mode 100644 plugins/base/baseqml/palettes/StreamValuePalette.json create mode 100644 plugins/base/baseqml/src/qmlstreamvalue.cpp create mode 100644 plugins/base/baseqml/src/qmlstreamvalue.h diff --git a/lib/lveditqmljs/src/qmljssettings.cpp b/lib/lveditqmljs/src/qmljssettings.cpp index 7f0afb91..e9ed2e88 100644 --- a/lib/lveditqmljs/src/qmljssettings.cpp +++ b/lib/lveditqmljs/src/qmljssettings.cpp @@ -60,6 +60,7 @@ QmlJsSettings::QmlJsSettings(EditorSettings *parent) m_defaultPalettes["qml/int"] = "IntPalette"; m_defaultPalettes["qml/string"] = "TextPalette"; m_defaultPalettes["qml/color"] = "ColorPalette"; + m_defaultPalettes["qml/base#StreamValue"] = "StreamValuePalette"; m_defaultPalettes["qml/lcvcore#VideoDecoderView"] = "VideoDecoderViewPalette"; m_defaultPalettes["qml/lcvcore#VideoFile"] = "VideoFilePropertiesPalette"; m_defaultPalettes["qml/lcvcore#GrayscaleView"] = "GrayscaleViewPalette"; diff --git a/lib/lvview/src/lvview.pri b/lib/lvview/src/lvview.pri index ec731fdb..a32f563a 100644 --- a/lib/lvview/src/lvview.pri +++ b/lib/lvview/src/lvview.pri @@ -7,7 +7,6 @@ HEADERS += \ $$PWD/metainfo.h \ $$PWD/qmlbuild.h \ $$PWD/qmlerror.h \ - $$PWD/qmlstreamiterator.h \ $$PWD/qmlwritablestream.h \ $$PWD/settings.h \ $$PWD/visuallogbasemodel.h \ @@ -46,7 +45,6 @@ SOURCES += \ $$PWD/metainfo.cpp \ $$PWD/qmlbuild.cpp \ $$PWD/qmlerror.cpp \ - $$PWD/qmlstreamiterator.cpp \ $$PWD/qmlwritablestream.cpp \ $$PWD/settings.cpp \ $$PWD/qmlclipboard.cpp \ diff --git a/lib/lvview/src/qmlstreamiterator.cpp b/lib/lvview/src/qmlstreamiterator.cpp deleted file mode 100644 index 4015d863..00000000 --- a/lib/lvview/src/qmlstreamiterator.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "qmlstreamiterator.h" - -namespace lv{ - -QmlStreamIterator::QmlStreamIterator(QObject *parent) - : QObject(parent) - , m_stream(nullptr) -{ - -} - -void QmlStreamIterator::streamHandler(QObject *that, const QJSValue &val){ - QmlStreamIterator* sf = static_cast(that); - sf->m_current = val; - emit sf->currentChanged(); -} - -}// namespace diff --git a/lib/lvview/src/qmlstreamiterator.h b/lib/lvview/src/qmlstreamiterator.h deleted file mode 100644 index e4910372..00000000 --- a/lib/lvview/src/qmlstreamiterator.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef LVQMLSTREAMITERATOR_H -#define LVQMLSTREAMITERATOR_H - -#include -#include "qmlstream.h" - -namespace lv{ - -class QmlStreamIterator : public QObject{ - - Q_OBJECT - Q_PROPERTY(lv::QmlStream* stream READ stream WRITE setStream NOTIFY streamChanged) - Q_PROPERTY(QJSValue current READ current NOTIFY currentChanged) - -public: - explicit QmlStreamIterator(QObject *parent = nullptr); - - lv::QmlStream* stream() const; - void setStream(lv::QmlStream* stream); - - QJSValue current() const; - - static void streamHandler(QObject* that, const QJSValue& val); - -signals: - void streamChanged(); - void currentChanged(); - -private: - lv::QmlStream* m_stream; - QJSValue m_current; -}; - -inline QmlStream *QmlStreamIterator::stream() const{ - return m_stream; -} - -inline void QmlStreamIterator::setStream(QmlStream *stream){ - if (m_stream == stream) - return; - - if( m_stream ) - m_stream->forward(nullptr, nullptr); - - m_stream = stream; - m_stream->forward(this, &QmlStreamIterator::streamHandler); - - emit streamChanged(); -} - -inline QJSValue QmlStreamIterator::current() const{ - return m_current; -} - -}// namespace - -#endif // LVQMLSTREAMITERATOR_H diff --git a/lib/lvview/src/viewengine.cpp b/lib/lvview/src/viewengine.cpp index 354c5a04..d790e10c 100644 --- a/lib/lvview/src/viewengine.cpp +++ b/lib/lvview/src/viewengine.cpp @@ -33,7 +33,6 @@ #include "windowlayer.h" #include "qmlstream.h" #include "qmlwritablestream.h" -#include "qmlstreamiterator.h" #include "qmlclipboard.h" #include "private/qqmlcontext_p.h" @@ -287,7 +286,6 @@ void ViewEngine::registerBaseTypes(const char *uri){ qmlRegisterType( uri, 1, 0, "Clipboard"); qmlRegisterType( uri, 1, 0, "Stream"); qmlRegisterType( uri, 1, 0, "WritableStream"); - qmlRegisterType( uri, 1, 0, "StreamIterator"); qmlRegisterUncreatableType( uri, 1, 0, "Shared", "Shared is of abstract type."); diff --git a/plugins/base/baseqml/baseqml.pro b/plugins/base/baseqml/baseqml.pro index 0e6ca42a..122b9d97 100644 --- a/plugins/base/baseqml/baseqml.pro +++ b/plugins/base/baseqml/baseqml.pro @@ -49,6 +49,7 @@ QMAKE_EXTRA_TARGETS += first palettecopy samplescopy DISTFILES += \ + palettes/StreamValuePalette.json \ qml/ConvertToInt.qml \ qml/JsonDecoder.qml \ qml/JsonEncoder.qml \ diff --git a/plugins/base/baseqml/palettes/StreamValuePalette.json b/plugins/base/baseqml/palettes/StreamValuePalette.json new file mode 100644 index 00000000..15144fd5 --- /dev/null +++ b/plugins/base/baseqml/palettes/StreamValuePalette.json @@ -0,0 +1,7 @@ +{ + "type": "qml/base#StreamValue", + "properties" : [ + ["value"] + ] +} + diff --git a/plugins/base/baseqml/qml/live.plugin.json b/plugins/base/baseqml/qml/live.plugin.json index 989ded18..1ce75cc0 100644 --- a/plugins/base/baseqml/qml/live.plugin.json +++ b/plugins/base/baseqml/qml/live.plugin.json @@ -3,6 +3,7 @@ "package" : ".", "libraryModules" : ["lvbase"], "palettes" : { - "palettes/ExecPalette.qml" : "qml/base#Exec" + "palettes/ExecPalette.qml" : "qml/base#Exec", + "palettes/StreamValuePalette.json" : "qml/base#StreamValue" } } diff --git a/plugins/base/baseqml/qml/plugins.qmltypes b/plugins/base/baseqml/qml/plugins.qmltypes index e37ec4e7..94218bbd 100644 --- a/plugins/base/baseqml/qml/plugins.qmltypes +++ b/plugins/base/baseqml/qml/plugins.qmltypes @@ -4,33 +4,11 @@ import QtQuick.tooling 1.2 // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'Livekeys 1.8.0' +// 'Livekeys 1.9.0' Module { dependencies: [] Component { name: "QAbstractListModel"; prototype: "QAbstractItemModel" } - Component { - name: "QObject" - exports: [ - "QML/QtObject 1.0", - "QtQml/QtObject 2.0", - "QtQuick/QtObject 2.0", - "base/Shared 1.0" - ] - isCreatable: false - exportMetaObjectRevisions: [0, 0, 0, 0] - Property { name: "objectName"; type: "QString" } - Signal { - name: "objectNameChanged" - Parameter { name: "objectName"; type: "QString" } - } - Method { name: "toString" } - Method { name: "destroy" } - Method { - name: "destroy" - Parameter { name: "delay"; type: "int" } - } - } Component { name: "lv::Environment" prototype: "QObject" @@ -231,7 +209,7 @@ Module { } Component { name: "lv::QmlObjectList" - prototype: "QObject" + prototype: "lv::Shared" exports: ["base/ObjectList 1.0"] exportMetaObjectRevisions: [0] Property { name: "items"; type: "QObject"; isList: true; isReadonly: true } @@ -334,14 +312,6 @@ Module { Property { name: "result"; type: "lv::QmlWritableStream"; isReadonly: true; isPointer: true } Property { name: "childObjects"; type: "QObject"; isList: true; isReadonly: true } } - Component { - name: "lv::QmlStreamIterator" - prototype: "QObject" - exports: ["base/StreamIterator 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "stream"; type: "lv::QmlStream"; isPointer: true } - Property { name: "current"; type: "QJSValue"; isReadonly: true } - } Component { name: "lv::QmlStreamLog" prototype: "QObject" @@ -361,6 +331,23 @@ Module { Parameter { name: "input"; type: "QJSValue" } } } + Component { + name: "lv::QmlStreamValue" + prototype: "QObject" + exports: ["base/StreamValue 1.0"] + exportMetaObjectRevisions: [0] + Property { name: "stream"; type: "lv::QmlStream"; isPointer: true } + Property { name: "valueType"; type: "QString" } + Property { name: "value"; type: "QJSValue"; isReadonly: true } + Signal { + name: "valueTypeChanged" + Parameter { name: "valueType"; type: "QString" } + } + Method { + name: "setValueType" + Parameter { name: "valueType"; type: "QString" } + } + } Component { name: "lv::QmlThreadInfo" prototype: "QObject" @@ -397,7 +384,7 @@ Module { } Component { name: "lv::QmlVariantList" - prototype: "QObject" + prototype: "lv::Shared" exports: ["base/VariantList 1.0"] exportMetaObjectRevisions: [0] Property { name: "items"; type: "QVariantList" } @@ -486,6 +473,13 @@ Module { Parameter { name: "object"; type: "QObject"; isPointer: true } } } + Component { + name: "lv::Shared" + prototype: "QObject" + exports: ["base/Shared 1.0"] + isCreatable: false + exportMetaObjectRevisions: [0] + } Component { name: "lv::ViewEngine" prototype: "QObject" diff --git a/plugins/base/baseqml/src/base_plugin.cpp b/plugins/base/baseqml/src/base_plugin.cpp index 4bf4575f..0427d103 100644 --- a/plugins/base/baseqml/src/base_plugin.cpp +++ b/plugins/base/baseqml/src/base_plugin.cpp @@ -32,6 +32,7 @@ #include "qmlfollowup.h" #include "groupcollector.h" #include "qmlstreamfilter.h" +#include "qmlstreamvalue.h" #include "qmlthreadinfo.h" #include "qmltime.h" @@ -78,6 +79,7 @@ void BasePlugin::registerTypes(const char *uri){ qmlRegisterType( uri, 1, 0, "GroupCollector"); qmlRegisterType( uri, 1, 0, "StreamFilter"); qmlRegisterType( uri, 1, 0, "StreamSink"); + qmlRegisterType( uri, 1, 0, "StreamValue"); qmlRegisterSingletonType( uri, 1, 0, "Script", &scriptProvider); qmlRegisterSingletonType( uri, 1, 0, "WorkerPool", &workerPoolProvider); diff --git a/plugins/base/baseqml/src/baseqml.pri b/plugins/base/baseqml/src/baseqml.pri index d8ef388a..75efbd00 100644 --- a/plugins/base/baseqml/src/baseqml.pri +++ b/plugins/base/baseqml/src/baseqml.pri @@ -9,6 +9,7 @@ HEADERS += \ $$PWD/qmlpropertylog.h \ $$PWD/qmlscript.h \ $$PWD/qmlstreamsink.h \ + $$PWD/qmlstreamvalue.h \ $$PWD/qmlthreadinfo.h \ $$PWD/qmltime.h \ $$PWD/qmlworkerpoolobject.h \ @@ -31,6 +32,7 @@ SOURCES += \ $$PWD/qmlindexselector.cpp \ $$PWD/qmlpropertylog.cpp \ $$PWD/qmlscript.cpp \ + $$PWD/qmlstreamvalue.cpp \ $$PWD/qmlstreamsink.cpp \ $$PWD/qmlthreadinfo.cpp \ $$PWD/qmltime.cpp \ diff --git a/plugins/base/baseqml/src/qmlstreamvalue.cpp b/plugins/base/baseqml/src/qmlstreamvalue.cpp new file mode 100644 index 00000000..18109160 --- /dev/null +++ b/plugins/base/baseqml/src/qmlstreamvalue.cpp @@ -0,0 +1,95 @@ +#include "qmlstreamvalue.h" +#include "qmlstreamfilter.h" +#include "live/exception.h" +#include "live/viewengine.h" + +namespace lv{ + +QmlStreamValue::QmlStreamValue(QObject *parent) + : QObject(parent) + , m_isComponentComplete(false) + , m_follow(nullptr) + , m_stream(nullptr) +{ +} + +void QmlStreamValue::streamHandler(QObject *that, const QJSValue &val){ + QmlStreamValue* sf = static_cast(that); + sf->m_current = val; + emit sf->valueChanged(); +} + +void QmlStreamValue::classBegin(){ +} + +void QmlStreamValue::componentComplete(){ + if ( m_stream ) + return; + + QmlStreamFilter* filter = qobject_cast(parent()); + if ( filter ){ + m_follow = filter; + connect(filter, &QmlStreamFilter::pullChanged, this, &QmlStreamValue::updateFollowsObject); + updateFollowsObject(); + } +} + +void QmlStreamValue::setValueType(const QString &valueType){ + if (m_valueType == valueType) + return; + + if ( m_isComponentComplete ){ + Exception e = CREATE_EXCEPTION(lv::Exception, "StreamValue: Cannot set valueType after component is complete.", Exception::toCode("~StreamValue")); + ViewEngine* engine = ViewEngine::grab(this); + engine->throwError(&e, this); + return; + } + + if ( valueType == "qml/object" ){ + m_current = QJSValue(QJSValue::NullValue); + } + + m_valueType = valueType; + emit valueTypeChanged(m_valueType); +} + +void QmlStreamValue::updateFollowsObject(){ + QmlStreamFilter* filter = qobject_cast(m_follow); + if ( filter ){ + if( m_stream ) + m_stream->forward(nullptr, nullptr); + + if ( filter->pull() ){ + m_stream = filter->pull(); + m_stream->forward(this, &QmlStreamValue::streamHandler); + emit streamChanged(); + } + } +} + +void QmlStreamValue::removeFollowsObject(){ + QmlStreamFilter* filter = qobject_cast(m_follow); + if ( filter ){ + disconnect(filter, &QmlStreamFilter::pullChanged, this, &QmlStreamValue::updateFollowsObject); + } + m_follow = nullptr; +} + +void lv::QmlStreamValue::setStream(QmlStream *stream){ + if (m_stream == stream) + return; + + if ( m_follow ){ + removeFollowsObject(); + } + + if( m_stream ) + m_stream->forward(nullptr, nullptr); + + m_stream = stream; + m_stream->forward(this, &QmlStreamValue::streamHandler); + + emit streamChanged(); +} + +}// namespace diff --git a/plugins/base/baseqml/src/qmlstreamvalue.h b/plugins/base/baseqml/src/qmlstreamvalue.h new file mode 100644 index 00000000..42cd8df6 --- /dev/null +++ b/plugins/base/baseqml/src/qmlstreamvalue.h @@ -0,0 +1,66 @@ +#ifndef LVQMLSTREAMVALUE_H +#define LVQMLSTREAMVALUE_H + +#include +#include "live/qmlstream.h" + +namespace lv{ + +class QmlStreamValue : public QObject, public QQmlParserStatus{ + + Q_OBJECT + Q_INTERFACES(QQmlParserStatus) + Q_PROPERTY(lv::QmlStream* stream READ stream WRITE setStream NOTIFY streamChanged) + Q_PROPERTY(QString valueType READ valueType WRITE setValueType NOTIFY valueTypeChanged) + Q_PROPERTY(QJSValue value READ value NOTIFY valueChanged) + +public: + explicit QmlStreamValue(QObject *parent = nullptr); + + lv::QmlStream* stream() const; + void setStream(lv::QmlStream* stream); + + QJSValue value() const; + + static void streamHandler(QObject* that, const QJSValue& val); + + void classBegin(); + void componentComplete(); + + const QString& valueType() const; + +public slots: + void setValueType(const QString& valueType); + +signals: + void streamChanged(); + void valueChanged(); + + void valueTypeChanged(QString valueType); + +private: + void updateFollowsObject(); + void removeFollowsObject(); + + bool m_isComponentComplete; + QObject* m_follow; + lv::QmlStream* m_stream; + QJSValue m_current; + QString m_valueType; +}; + +inline QmlStream *QmlStreamValue::stream() const{ + return m_stream; +} + +inline QJSValue QmlStreamValue::value() const{ + return m_current; +} + +inline const QString &QmlStreamValue::valueType() const{ + return m_valueType; +} + +}// namespace + +#endif // LVQMLSTREAMVALUE_H From 8fecc4ed1b16c9a2f9477e8322a5abe51d3ea870 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 4 May 2021 11:15:28 +0300 Subject: [PATCH 06/91] editor: Added support for finding a path in ProjectFileModel. --- lib/lveditor/src/projectfilemodel.cpp | 14 ++++++++++++++ lib/lveditor/src/projectfilemodel.h | 1 + 2 files changed, 15 insertions(+) diff --git a/lib/lveditor/src/projectfilemodel.cpp b/lib/lveditor/src/projectfilemodel.cpp index 2a1fa126..bca8f27f 100644 --- a/lib/lveditor/src/projectfilemodel.cpp +++ b/lib/lveditor/src/projectfilemodel.cpp @@ -150,6 +150,20 @@ ProjectFile *ProjectFileModel::openFile(const QString &file){ return openExternalFile(absolutePath); } +ProjectEntry *ProjectFileModel::findPath(const QString &path){ + QString absolutePath = QFileInfo(path).absoluteFilePath(); + if ( m_root->childCount() == 0 ) + return nullptr; + ProjectEntry* projectEntry = m_root->child(0); + if ( absolutePath.indexOf(projectEntry->path()) == 0 ){ + QString pathLeft = absolutePath.mid(projectEntry->path().size()); + pathLeft.prepend(pathLeft.startsWith("/") ? projectEntry->name() : (projectEntry->name() + "/")); + return findPathInEntry(projectEntry, pathLeft); + } + + return nullptr; +} + ProjectEntry *ProjectFileModel::findPathInEntry(ProjectEntry *entry, const QString &path){ if ( path.indexOf(entry->name()) == 0 ){ QString pathLeft = path.mid(entry->name().size()); diff --git a/lib/lveditor/src/projectfilemodel.h b/lib/lveditor/src/projectfilemodel.h index aeab5245..7d3dce6b 100644 --- a/lib/lveditor/src/projectfilemodel.h +++ b/lib/lveditor/src/projectfilemodel.h @@ -76,6 +76,7 @@ public slots: lv::ProjectFile* addFile(lv::ProjectEntry* parentEntry, const QString& name); lv::ProjectFile* addTemporaryFile(); lv::ProjectEntry* addDirectory(lv::ProjectEntry* parentEntry, const QString& name); + lv::ProjectEntry* findPath(const QString& path); bool removeEntry(lv::ProjectEntry* entry); void expandEntry(lv::ProjectEntry* entry) const; From 1b42a6f16b64c4b8ac95380107938acee91f0219 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 4 May 2021 11:15:52 +0300 Subject: [PATCH 07/91] editqml: CodeHandler: Added support for fetching the DocumentHandler --- lib/lveditqmljs/src/codeqmlhandler.cpp | 5 ++++- lib/lveditqmljs/src/codeqmlhandler.h | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/lveditqmljs/src/codeqmlhandler.cpp b/lib/lveditqmljs/src/codeqmlhandler.cpp index de935178..b0ef086d 100644 --- a/lib/lveditqmljs/src/codeqmlhandler.cpp +++ b/lib/lveditqmljs/src/codeqmlhandler.cpp @@ -1205,7 +1205,6 @@ QList CodeQmlHandler::getDeclarations(int position, int len */ QmlEditFragment *CodeQmlHandler::createInjectionChannel(QmlDeclaration::Ptr declaration, QmlEditFragment* parentEdit){ Q_D(CodeQmlHandler); - Project* project = d->projectHandler->project(); if ( m_document ){ d->syncParse(m_document); @@ -3459,6 +3458,10 @@ void CodeQmlHandler::newDocumentScanReady(DocumentQmlInfo::Ptr documentInfo){ } } +DocumentHandler *CodeQmlHandler::documentHandler() const{ + return qobject_cast(parent()); +} + void CodeQmlHandler::__whenLibraryScanQueueCleared(){ QLinkedList callbacks = m_importsScannedListeners; m_importsScannedListeners.clear(); diff --git a/lib/lveditqmljs/src/codeqmlhandler.h b/lib/lveditqmljs/src/codeqmlhandler.h index a82379f5..681d6380 100644 --- a/lib/lveditqmljs/src/codeqmlhandler.h +++ b/lib/lveditqmljs/src/codeqmlhandler.h @@ -58,6 +58,7 @@ class LV_EDITQMLJS_EXPORT CodeQmlHandler : public QObject{ Q_OBJECT Q_DISABLE_COPY(CodeQmlHandler) + Q_PROPERTY(lv::DocumentHandler* documentHandler READ documentHandler CONSTANT) Q_PROPERTY(lv::QmlEditFragmentContainer* editContainer READ editContainer CONSTANT) Q_PROPERTY(lv::DocumentQmlChannels* bindingChannels READ bindingChannels CONSTANT) @@ -116,11 +117,13 @@ class LV_EDITQMLJS_EXPORT CodeQmlHandler : public QObject{ GroupOnly = 4, NoReadOnly = 8 }; + Q_ENUMS(AddOptionsFilter); QmlEditFragmentContainer *editContainer(); DocumentQmlChannels* bindingChannels() const; + DocumentHandler* documentHandler() const; + - Q_ENUMS(AddOptionsFilter); public slots: void __whenLibraryScanQueueCleared(); bool areImportsScanned(); @@ -320,6 +323,7 @@ public slots: QScopedPointer d_ptr; Q_DECLARE_PRIVATE(CodeQmlHandler) + lv::DocumentHandler* m_documentHandler; }; inline ProjectDocument *CodeQmlHandler::document() const{ From c20be7eb0b0cbd171b1d475d21abc48ed6c28671 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 4 May 2021 11:16:02 +0300 Subject: [PATCH 08/91] base: Updated Act error reporting. --- plugins/base/baseqml/src/qmlact.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/base/baseqml/src/qmlact.cpp b/plugins/base/baseqml/src/qmlact.cpp index 205a8917..29f54302 100644 --- a/plugins/base/baseqml/src/qmlact.cpp +++ b/plugins/base/baseqml/src/qmlact.cpp @@ -260,7 +260,7 @@ void QmlAct::setReturns(QString returns){ return; if ( m_isComponentComplete ){ - Exception e = CREATE_EXCEPTION(lv::Exception, "ActFn: Cannot set run method after component is complete.", Exception::toCode("~ActFnConfig")); + Exception e = CREATE_EXCEPTION(lv::Exception, "ActFn: Cannot set return type after component is complete.", Exception::toCode("~ActConfig")); ViewContext::instance().engine()->throwError(&e, this); return; } From 3af4c76e8490168201cdb048ece38d69161be513 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 4 May 2021 11:16:18 +0300 Subject: [PATCH 09/91] editor: Added TextEdit.getEditor --- plugins/editor/qml/Editor.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/editor/qml/Editor.qml b/plugins/editor/qml/Editor.qml index cf62b900..de0955c7 100644 --- a/plugins/editor/qml/Editor.qml +++ b/plugins/editor/qml/Editor.qml @@ -303,6 +303,7 @@ Rectangle{ NewTextEdit { id : textEdit + anchors.left: parent.left anchors.leftMargin: 2 viewport: Qt.rect(flick.flickableItem.contentX,flick.flickableItem.contentY,flick.width,flick.height) @@ -319,6 +320,7 @@ Rectangle{ } } + function getEditor(){ return root } property int lastLength: 0 From 80a8df83c15ef997fa5cc40674894368018e0aef Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 4 May 2021 11:16:43 +0300 Subject: [PATCH 10/91] lcvcore: VideoSegment: Fixed watcher call. --- plugins/lcvcore/src/videosegment.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/lcvcore/src/videosegment.cpp b/plugins/lcvcore/src/videosegment.cpp index af4f553c..11651a14 100644 --- a/plugins/lcvcore/src/videosegment.cpp +++ b/plugins/lcvcore/src/videosegment.cpp @@ -230,7 +230,9 @@ void VideoSegment::addWatcher(){ ViewEngine* ve = ViewContext::instance().engine(); QmlWatcher* watcher = new QmlWatcher(m_filtersObject); + //TODO: Generate unique name + watcher->setTarget(m_filtersObject); watcher->initialize(ve, hooks, m_filters, m_videoTrack->name() + "_" + QString::number(position())); } From 154a268418853a73b8c40a3fc2ed3fdb08fd1ba8 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 4 May 2021 11:17:14 +0300 Subject: [PATCH 11/91] LK: Added lcvcore extension to be loaded by default. --- application/src/livekeys.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/application/src/livekeys.cpp b/application/src/livekeys.cpp index e13fa3c2..120f48a5 100644 --- a/application/src/livekeys.cpp +++ b/application/src/livekeys.cpp @@ -421,6 +421,11 @@ const MLNode &Livekeys::startupConfiguration(){ {"package", "workspace"}, {"enabled", true}, {"component", "WorkspaceControlsExtension.qml"} + }, + { + {"package", "lcvcore"}, + {"enabled", true}, + {"component", "EditCvExtension.qml"} }/*, { {"package", "editlv"}, From 7d3c4ca831bcbdae5789a41a352225004353e94c Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 4 May 2021 11:19:17 +0300 Subject: [PATCH 12/91] editor: Document handler exports fetching the textEdit() --- lib/lveditor/src/documenthandler.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/lveditor/src/documenthandler.h b/lib/lveditor/src/documenthandler.h index 07e6e702..ef301830 100644 --- a/lib/lveditor/src/documenthandler.h +++ b/lib/lveditor/src/documenthandler.h @@ -79,8 +79,6 @@ class LV_EDITOR_EXPORT DocumentHandler : public QObject, public QQmlParserStatus void classBegin(){} void componentComplete(); - /** Returns the TextEdit */ - TextEdit* textEdit(); void setTextEdit(TextEdit* te); int currentCursorPosition() const; @@ -112,6 +110,9 @@ public slots: void frameBox(QQuickItem *box, int position, int length); + /** Returns the TextEdit */ + lv::TextEdit* textEdit(); + bool has(int feature); signals: From bd68fa313098289cdef679fdc948600844091960 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 4 May 2021 11:22:35 +0300 Subject: [PATCH 13/91] editor: HookContainer: support for updating entries during runtime. --- lib/lveditor/src/hookcontainer.cpp | 2 +- lib/lveditor/src/hookcontainer.h | 2 +- .../src/qmlbindingchannelsdispatcher.cpp | 40 +++++++++++++++++-- .../src/qmlbindingchannelsdispatcher.h | 1 + 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/lib/lveditor/src/hookcontainer.cpp b/lib/lveditor/src/hookcontainer.cpp index 7eb9e2b9..db118110 100644 --- a/lib/lveditor/src/hookcontainer.cpp +++ b/lib/lveditor/src/hookcontainer.cpp @@ -27,7 +27,7 @@ void HookContainer::insertKey(const QString &file, const QString &id, QObject *o idIt.value().append(obj); - emit entryAdded(file, id, obj); + emit entryAdded(m_runnable, file, id, obj); } void HookContainer::removeEntry(const QString &sourceFile, const QString &id, QObject *obj){ diff --git a/lib/lveditor/src/hookcontainer.h b/lib/lveditor/src/hookcontainer.h index 75708391..a41eb9bc 100644 --- a/lib/lveditor/src/hookcontainer.h +++ b/lib/lveditor/src/hookcontainer.h @@ -31,7 +31,7 @@ class LV_EDITOR_EXPORT HookContainer : public QObject{ QList entriesFor(const QString& file, const QString& id); signals: - void entryAdded(const QString& file, const QString& id, QObject* object); + void entryAdded(Runnable* runnable, const QString& file, const QString& id, QObject* object); void entryRemoved(const QString& file, const QString& id, QObject* object); private: diff --git a/lib/lveditqmljs/src/qmlbindingchannelsdispatcher.cpp b/lib/lveditqmljs/src/qmlbindingchannelsdispatcher.cpp index da463e24..69635012 100644 --- a/lib/lveditqmljs/src/qmlbindingchannelsdispatcher.cpp +++ b/lib/lveditqmljs/src/qmlbindingchannelsdispatcher.cpp @@ -62,7 +62,9 @@ void QmlBindingChannelsDispatcher::__qmlBuildReady(){ QmlBindingPath::Ptr watcherBp = QmlBindingPath::create(); watcherBp->appendFile(run->path()); watcherBp->appendWatcher(w->referencedFile(), objectId); + QmlBindingChannel::Ptr bpChannel = DocumentQmlChannels::traverseBindingPath(watcherBp, run); + if ( bpChannel ){ documentChannels->updateChannel(bpChannel); } @@ -80,11 +82,43 @@ void QmlBindingChannelsDispatcher::__qmlBuildReady(){ } } } - } - //HERE: Add connection to hook container - // Define scenario first + // For watchers that initialize after the build is ready, connect them later + connect(hooks, &HookContainer::entryAdded, this, &QmlBindingChannelsDispatcher::__hookEntryAdded); +} + +void QmlBindingChannelsDispatcher::__hookEntryAdded(Runnable *runnable, const QString &file, const QString &id, QObject *object){ + for ( auto it = m_channeledDocuments.begin(); it != m_channeledDocuments.end(); ++it ){ + DocumentQmlChannels* documentChannels = *it; + QString filePath = documentChannels->document()->file()->path(); + if ( filePath == file ){ + if ( qobject_cast(object) ){ + + QmlWatcher* w = qobject_cast(object); + + QmlBindingPath::Ptr watcherBp = QmlBindingPath::create(); + watcherBp->appendFile(runnable->path()); + watcherBp->appendWatcher(w->referencedFile(), id); + QmlBindingChannel::Ptr bpChannel = DocumentQmlChannels::traverseBindingPath(watcherBp, runnable); + if ( bpChannel ){ + documentChannels->updateChannel(bpChannel); + } + + } else if ( qobject_cast(object) ){ + + QmlBindingPath::Ptr builderBp = QmlBindingPath::create(); + builderBp->appendFile(filePath); + builderBp->appendComponent(id, id); + QmlBindingChannel::Ptr builderC = QmlBindingChannel::create(builderBp, runnable); + if ( builderC ){ + builderC->setIsBuilder(true); + builderC->setEnabled(true); + documentChannels->updateChannel(builderC); + } + } + } + } } void QmlBindingChannelsDispatcher::removeDocumentChannels(DocumentQmlChannels *documentChannels){ diff --git a/lib/lveditqmljs/src/qmlbindingchannelsdispatcher.h b/lib/lveditqmljs/src/qmlbindingchannelsdispatcher.h index a7eecc44..14e9dfc0 100644 --- a/lib/lveditqmljs/src/qmlbindingchannelsdispatcher.h +++ b/lib/lveditqmljs/src/qmlbindingchannelsdispatcher.h @@ -26,6 +26,7 @@ class QmlBindingChannelsDispatcher : public QObject{ public slots: void __newQmlBuild(Runnable* runnable, QmlBuild* build); void __qmlBuildReady(); + void __hookEntryAdded(Runnable* runnable, const QString& file, const QString& id, QObject* object); private: From c1ac77ed4bf2a9798f48993634641864c7e14025 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 4 May 2021 11:23:45 +0300 Subject: [PATCH 14/91] Timeline: Added support for segment adjustment. Forwarding of segment right click handler. Forwarding of context menu. CvExtension: Support for VideoSegment context menu. --- plugins/lcvcore/qml/EditCvExtension.qml | 118 ++++++++++++++++++ plugins/timeline/palettes/TimelinePalette.qml | 17 +++ plugins/timeline/qml/SegmentView.qml | 17 ++- plugins/timeline/qml/TimelineRow.qml | 1 + plugins/timeline/qml/TimelineView.qml | 6 +- 5 files changed, 156 insertions(+), 3 deletions(-) diff --git a/plugins/lcvcore/qml/EditCvExtension.qml b/plugins/lcvcore/qml/EditCvExtension.qml index e93f201d..7b6b25bd 100644 --- a/plugins/lcvcore/qml/EditCvExtension.qml +++ b/plugins/lcvcore/qml/EditCvExtension.qml @@ -1,5 +1,6 @@ import QtQuick 2.3 import editor 1.0 +import editor.private 1.0 import base 1.0 import live 1.0 import fs 1.0 as Fs @@ -53,6 +54,123 @@ WorkspaceExtension{ }, } + menuInterceptors: [ + { + whenItem: 'timelineResizableSegment', + intercept: function(pane, item){ + if ( item.currentSegment instanceof Cv.VideoSegment ){ + var segment = item.currentSegment + return [{ + name : "Adjust", + action : function(){ + if ( !project.isDirProject() ){ + lk.layers.workspace.messages.pushError( + "Cannot adjust for non-directory project. Open the project as a directory to adjust.", 3000 + ) + } + + if ( segment.filters === '' ){ + lk.layers.workspace.wizards.addFile( + project.dir(), + { + 'extension': 'qml', + 'heading' : 'Add adjustments file in ' + project.dir() + }, + function(file){ + var pd = project.openTextFile(file, Document.Edit) + pd.insert( + 0, + pd.contentLength(), + 'import QtQuick 2.3\n' + + 'import base 1.0\n' + + 'import lcvcore 1.0\n' + + 'import lcvphoto 1.0\n' + + '\n' + + 'StreamFilter{\n' + + ' id: streamFilter\n' + + ' StreamValue{\n' + + ' id: streamValue\n' + + ' valueType: \'qml/object\'\n' + + ' }\n' + + ' StreamSink{\n' + + ' id: streamSink\n' + + ' input: streamValue.value\n' + + ' }\n' + + '}\n', + ProjectDocument.Palette + ) + pd.save() + + var pane = lk.layers.workspace.panes.createPane('editor', {}, [400, 0]) + + var panes = lk.layers.workspace.panes.findPanesByType('editor') + if ( panes.length === 0 ){ + var foundPane = panes[0] + var foundPaneIndex = foundPane.parentSplitterIndex + + lk.layers.workspace.panes.splitPaneVerticallyWith(foundPane.parentSplitter, foundPaneIndex, pane) + } else { + var containerUsed = lk.layers.workspace.panes.container + if ( containerUsed.orientation === Qt.Vertical ){ + for ( var i = 0; i < containerUsed.panes.length; ++i ){ + if ( containerUsed.panes[i].paneType === 'splitview' && + containerUsed.panes[i].orientation === Qt.Horizontal ) + { + containerUsed = containerUsed.panes[i] + break + } + } + } + lk.layers.workspace.panes.splitPaneHorizontallyWith(containerUsed, 0, pane) + } + + pane.document = pd + segment.filters = file.path + + lk.layers.workspace.extensions.editqml.shapeAllInEditor(pane) + } + ) + + } else { + var path = segment.filters + + var pd = project.openTextFile(path, Document.Edit) + + var pane = lk.layers.workspace.panes.createPane('editor', {}, [400, 0]) + + var panes = lk.layers.workspace.panes.findPanesByType('editor') + if ( panes.length === 0 ){ + var foundPane = panes[0] + var foundPaneIndex = foundPane.parentSplitterIndex + lk.layers.workspace.panes.splitPaneVerticallyWith(foundPane.parentSplitter, foundPaneIndex, pane) + } else { + var containerUsed = lk.layers.workspace.panes.container + if ( containerUsed.orientation === Qt.Vertical ){ + for ( var i = 0; i < containerUsed.panes.length; ++i ){ + if ( containerUsed.panes[i].paneType === 'splitview' && + containerUsed.panes[i].orientation === Qt.Horizontal ) + { + containerUsed = containerUsed.panes[i] + break + } + } + } + lk.layers.workspace.panes.splitPaneHorizontallyWith(containerUsed, 0, pane) + } + + pane.document = pd + lk.layers.workspace.extensions.editqml.shapeAllInEditor(pane) + } + } + }] + } + + + return [] + } + } + ] + property Component imagePaneFactory : Component{ MatViewPane{} } diff --git a/plugins/timeline/palettes/TimelinePalette.qml b/plugins/timeline/palettes/TimelinePalette.qml index b3439740..305e3cdf 100644 --- a/plugins/timeline/palettes/TimelinePalette.qml +++ b/plugins/timeline/palettes/TimelinePalette.qml @@ -24,6 +24,23 @@ CodePalette{ focus : true timelineStyle: theme.timelineStyle + onSegmentRightClicked: { + var pane = null + var p = parent + while ( p ){ + if ( p.paneType !== undefined ){ + break + } + p = p.parent + } + + if ( p ){ + lk.layers.workspace.panes.activateItem(delegate, p) + lk.layers.workspace.panes.openContextMenu(delegate, p) + + } + } + onSegmentDoubleClicked: { var trackProperties = track.configuredProperties(segment) diff --git a/plugins/timeline/qml/SegmentView.qml b/plugins/timeline/qml/SegmentView.qml index ad1ece4e..bb829b83 100644 --- a/plugins/timeline/qml/SegmentView.qml +++ b/plugins/timeline/qml/SegmentView.qml @@ -27,6 +27,11 @@ Loader{ if ( root.parent ) root.parent.segmentDoubleClicked(segment) } + signal segmentRightClicked(Item delegate, Segment segment) + onSegmentRightClicked: { + if ( root.parent ) + root.parent.segmentRightClicked(delegate, segment) + } sourceComponent: segment ? (segment instanceof Keyframe) ? keyframe : resizableSegment @@ -69,6 +74,9 @@ Loader{ Item{ id: rootItem anchors.fill: parent + objectName: "timelineResizableSegment" + + property var currentSegment: segment Keys.onPressed: { if (event.key === Qt.Key_Delete || event.key === Qt.Key_Backspace) { @@ -136,10 +144,15 @@ Loader{ drag.axis: Drag.XAndYAxis drag.minimumX: 0 drag.maximumX: segment ? segment.segmentModel().contentWidth - root.width : 0 + acceptedButtons: Qt.LeftButton | Qt.RightButton onPressed: { - rootItem.forceActiveFocus() - root.__segmentFocused(segment) + if ( mouse.button === Qt.LeftButton ){ + rootItem.forceActiveFocus() + root.__segmentFocused(segment) + } else if ( mouse.button === Qt.RightButton ){ + root.segmentRightClicked(rootItem, segment) + } } onDoubleClicked: { root.segmentDoubleClicked(segment) diff --git a/plugins/timeline/qml/TimelineRow.qml b/plugins/timeline/qml/TimelineRow.qml index f0f4cdfa..5b2b473c 100644 --- a/plugins/timeline/qml/TimelineRow.qml +++ b/plugins/timeline/qml/TimelineRow.qml @@ -7,6 +7,7 @@ Rectangle{ signal segmentFocused(Segment segment) signal segmentDoubleClicked(Segment segment) + signal segmentRightClicked(Item delegate, Segment segment) signal trackClicked(int position) signal trackDoubleClicked(int position) diff --git a/plugins/timeline/qml/TimelineView.qml b/plugins/timeline/qml/TimelineView.qml index f6666760..f9fc1fce 100644 --- a/plugins/timeline/qml/TimelineView.qml +++ b/plugins/timeline/qml/TimelineView.qml @@ -237,6 +237,7 @@ Rectangle{ signal mouseDoubleClicked(int position, int trackIndex) signal segmentSelected(Track track, Segment segment) signal segmentDoubleClicked(Track track, Segment segment, Item delegate) + signal segmentRightClicked(Track track, Segment segment, Item delegate) Rectangle{ id: timelineOptionsContainer @@ -468,6 +469,9 @@ Rectangle{ segmentDelegate: root.segmentDelegate + onSegmentRightClicked: { + root.segmentRightClicked(track, segment, delegate) + } onSegmentDoubleClicked: { root.segmentDoubleClicked(track, segment, timelineRow) } @@ -510,7 +514,7 @@ Rectangle{ } if ( availableSpace < segment.length ){ - segment.length = avialableSpace + segment.length = availableSpace } segment.position = root.timeline.cursorPosition From face3513c50eb8343afe6e7ccee3dede58efd125 Mon Sep 17 00:00:00 2001 From: nenad-popovic-91 <42581059+nenad-popovic-91@users.noreply.github.com> Date: Tue, 4 May 2021 10:24:29 +0200 Subject: [PATCH 15/91] Gradient generalized to multicolors (#210) * Fixes for documentation of samples * ObjectContainer and NodeEditor interactions fixed * Generalization of Gradient drawing * Documentation updates --- plugins/lcvcore/qml/GradientTool.qml | 3 +- .../imagetransformations.md | 2 +- .../ImageTransformationsHighlight.qml | 2 + plugins/lcvcore/src/qgradient.cpp | 57 ++++++++++++++----- plugins/lcvcore/src/qgradient.h | 11 ++-- .../tutorials/workspace/workspacetutorial.md | 3 - 6 files changed, 52 insertions(+), 26 deletions(-) diff --git a/plugins/lcvcore/qml/GradientTool.qml b/plugins/lcvcore/qml/GradientTool.qml index cc3aaacb..bddb71cf 100644 --- a/plugins/lcvcore/qml/GradientTool.qml +++ b/plugins/lcvcore/qml/GradientTool.qml @@ -90,8 +90,7 @@ Tool{ imageContainer.writableImage, Qt.point(root.lastX, root.lastY), Qt.point(event.imageX, event.imageY), - toolbox.foreground, - toolbox.background + [[0, toolbox.foreground], [1, toolbox.background]] ) root.lastX = event.imageX diff --git a/plugins/lcvcore/samples/imagetransformations/imagetransformations.md b/plugins/lcvcore/samples/imagetransformations/imagetransformations.md index 63918e42..0897b3b4 100644 --- a/plugins/lcvcore/samples/imagetransformations/imagetransformations.md +++ b/plugins/lcvcore/samples/imagetransformations/imagetransformations.md @@ -7,7 +7,7 @@ In this sample, we can add a series of image transformations using a single transformations object. The object will create a pipeline through which the image will pass in order to get our output. -Currently you can [crop]({livekeys-hover:livekeys://open/resources/ImageTransformationsHighlight.qml#crop-button;livekeys://open/resources/ImageTransformationsRemoveHighlight.qml#crop-button}), [resize]({livekeys-hover:livekeys://open/resources/ImageTransformationsHighlight.qml#resize-button;livekeys://open/resources/ImageTransformationsRemoveHighlight.qml#resize-button}) or [rotate]({livekeys-hover:livekeys://open/resources/ImageTransformationsHighlight.qml#rotate-button;livekeys://open/resources/ImageTransformationsRemoveHighlight.qml#rotate-button}) the image. Try for example to crop the image using the crop tool. You will notice the [transformation]({livekeys-hover:livekeys://open/resources/ImageTransformationsHighlight.qml#transformation;livekeys://open/resources/ImageTransformationsRemoveHighlight.qml#transformation}) +Currently you can [crop]({livekeys-hover:livekeys://open/resources/ImageTransformationsHighlight.qml#crop-button;livekeys://open/resources/ImageTransformationsRemoveHighlight.qml#crop-button}), [resize]({livekeys-hover:livekeys://open/resources/ImageTransformationsHighlight.qml#resize-button;livekeys://open/resources/ImageTransformationsRemoveHighlight.qml#resize-button}), [rotate]({livekeys-hover:livekeys://open/resources/ImageTransformationsHighlight.qml#rotate-button;livekeys://open/resources/ImageTransformationsRemoveHighlight.qml#rotate-button}) or [warp]({livekeys-hover:livekeys://open/resources/ImageTransformationsHighlight.qml#warp-button;livekeys://open/resources/ImageTransformationsRemoveHighlight.qml#warp-button}) the image. Try for example to crop the image using the crop tool. You will notice the [transformation]({livekeys-hover:livekeys://open/resources/ImageTransformationsHighlight.qml#transformation;livekeys://open/resources/ImageTransformationsRemoveHighlight.qml#transformation}) added to our list. [Switching to a new image](livekeys://open/resources/AddDifferentImage.qml) won't reset our transformations, but rather will apply them diff --git a/plugins/lcvcore/samples/imagetransformations/resources/ImageTransformationsHighlight.qml b/plugins/lcvcore/samples/imagetransformations/resources/ImageTransformationsHighlight.qml index afa7d960..5795ddcc 100644 --- a/plugins/lcvcore/samples/imagetransformations/resources/ImageTransformationsHighlight.qml +++ b/plugins/lcvcore/samples/imagetransformations/resources/ImageTransformationsHighlight.qml @@ -77,6 +77,8 @@ WorkspaceControl{ highlight = highlightTransformButton(state, 24,60) } else if ( fragment === 'rotate-button' ){ highlight = highlightTransformButton(state, -2,86) + } else if ( fragment === 'warp-button' ){ + highlight = highlightTransformButton(state, 24,86) } else if ( fragment === 'transformation' ){ var editorPane = lk.layers.workspace.panes.focusPane('editor') if ( !editorPane ) diff --git a/plugins/lcvcore/src/qgradient.cpp b/plugins/lcvcore/src/qgradient.cpp index e8767a9f..df0ee060 100644 --- a/plugins/lcvcore/src/qgradient.cpp +++ b/plugins/lcvcore/src/qgradient.cpp @@ -3,29 +3,44 @@ #include "qwritablemat.h" #include "opencv2/core.hpp" #include +#include QGradient::QGradient(QObject *parent) : QObject(parent) { } -void QGradient::draw(QWritableMat* result, QPointF p1, QPointF p2, QColor c1, QColor c2) +void QGradient::draw(QWritableMat *result, QPointF p1, QPointF p2, QJSValue list) { if (p1 == p2) return; auto mat = result->internal(); if (mat.rows == 0 || mat.cols == 0) return; + QVariantList vList = list.toVariant().toList(); + if (vList.empty()) return; - start = p1; end = p2; - startColor = c1; endColor = c2; + double prev = -1.0; + colorList.clear(); + for (int i = 0; i < vList.length(); ++i) + { + auto elem = vList.at(i); + QVariantList pvList = elem.toList(); + if (pvList.empty() || pvList.length() != 2) return; + + double t = pvList.at(0).toDouble(); + if (t < prev || qFuzzyCompare(t, prev)) return; // the array should be increasing + prev = t; + QColor c = pvList.at(1).value(); + + colorList.push_back(std::make_pair(t, c)); + } - calculateLineParams(); + if (colorList.size() < 2) return; + if (!qFuzzyCompare(colorList[0].first, 0.0)) return; // the first array element should be 0 + if (!qFuzzyCompare(colorList[colorList.size() - 1].first, 1.0)) return; // the last array element should be 1 - linearSC = linearFromRGB(startColor); - linearEC = linearFromRGB(endColor); - brightness1 = pow(linearSC.x()+linearSC.y()+linearSC.z(), Gamma); - brightness2 = pow(linearEC.x()+linearEC.y()+linearEC.z(), Gamma); + calculateLineParams(p2, p1); for (int y = 0; y < mat.rows; ++y) for (int x = 0; x < mat.cols; ++x) @@ -42,7 +57,7 @@ void QGradient::draw(QWritableMat* result, QPointF p1, QPointF p2, QColor c1, QC } } -void QGradient::calculateLineParams() +void QGradient::calculateLineParams(QPointF start, QPointF end) { A = end.x() - start.x(); @@ -103,10 +118,26 @@ qreal QGradient::weightedValue(qreal v1, qreal v2, qreal t) QColor QGradient::weightedColor(qreal t) { - qreal brightness = pow(weightedValue(brightness1, brightness2, t), 1/Gamma); - qreal c1 = weightedValue(linearSC.x(), linearEC.x(), t); - qreal c2 = weightedValue(linearSC.y(), linearEC.y(), t); - qreal c3 = weightedValue(linearSC.z(), linearEC.z(), t); + int i = 0; + for (; i < colorList.size() - 1; ++i) + if (colorList[i].first <= t && t <= colorList[i+1].first) break; + + QColor startColor = colorList[i].second; + QColor endColor = colorList[i+1].second; + double t1 = colorList[i].first; + double t2 = colorList[i+1].first; + + QVector3D linearSC = linearFromRGB(startColor); + QVector3D linearEC = linearFromRGB(endColor); + qreal brightness1 = pow(linearSC.x()+linearSC.y()+linearSC.z(), Gamma); + qreal brightness2 = pow(linearEC.x()+linearEC.y()+linearEC.z(), Gamma); + + qreal scaledT = (t-t2)/(t1 - t2); + + qreal brightness = pow(weightedValue(brightness1, brightness2, scaledT), 1/Gamma); + qreal c1 = weightedValue(linearSC.x(), linearEC.x(), scaledT); + qreal c2 = weightedValue(linearSC.y(), linearEC.y(), scaledT); + qreal c3 = weightedValue(linearSC.z(), linearEC.z(), scaledT); qreal total = c1 + c2 + c3; if (total != 0){ diff --git a/plugins/lcvcore/src/qgradient.h b/plugins/lcvcore/src/qgradient.h index c603caa3..223f7506 100644 --- a/plugins/lcvcore/src/qgradient.h +++ b/plugins/lcvcore/src/qgradient.h @@ -5,6 +5,7 @@ #include #include #include +#include class QWritableMat; @@ -19,20 +20,16 @@ class QGradient : public QObject{ public slots: - void draw(QWritableMat* result, QPointF p1, QPointF p2, QColor c1, QColor c2); - + void draw(QWritableMat* result, QPointF p1, QPointF p2, QJSValue list); private: const double Gamma = 0.43; - QPointF start, end; qreal A, B, C; qreal radius; - QColor startColor, endColor; - QVector3D linearSC, linearEC; - qreal brightness1, brightness2; qreal correctiveSign; + std::vector> colorList; - void calculateLineParams(); + void calculateLineParams(QPointF start, QPointF end); qreal calculateSignedDistance(QPointF p); qreal linearFromComponent(qreal x); qreal componentFromLinear(qreal x); diff --git a/plugins/squareone/tutorials/workspace/workspacetutorial.md b/plugins/squareone/tutorials/workspace/workspacetutorial.md index 8407de1d..a7b60a5b 100644 --- a/plugins/squareone/tutorials/workspace/workspacetutorial.md +++ b/plugins/squareone/tutorials/workspace/workspacetutorial.md @@ -31,9 +31,6 @@ In the left part of the header, you will find the buttons to manage your project * [Change settings]({livekeys-hover:livekeys://open/resources/MenuIconHighlight.qml#settings-view;livekeys://open/resources/MenuRemoveHighlight.qml#settings-view}). View and edit the settings file. * [Manage licenses]({livekeys-hover:livekeys://open/resources/MenuIconHighlight.qml#license-view;livekeys://open/resources/MenuRemoveHighlight.qml#license-view}). Manage licenses for different plugins. -The right part of the header shows the [active file]({livekeys-hover:livekeys://open/resources/MenuIconHighlight.qml#active-file;livekeys://open/resources/MenuRemoveHighlight.qml#active-file}) (or main file) used by the project. A project can have more than one file, -and users are free to organize the project structure depending on what they need. We will cover these in detail later. - Below the header you will find the [pane area]({livekeys-hover:livekeys://open/resources/MenuIconHighlight.qml#pane-area;livekeys://open/resources/MenuRemoveHighlight.qml#pane-area}), a customizable workspace where you can open, close and manage different types of views depending on what you are looking to achieve. From 7bd81176e90181b03fb9f112675ca1bd0200251e Mon Sep 17 00:00:00 2001 From: nenad-popovic-91 <42581059+nenad-popovic-91@users.noreply.github.com> Date: Tue, 4 May 2021 10:25:23 +0200 Subject: [PATCH 16/91] Upgraded v8 version, new Elements parser tests and related fixes (#211) * Fix for build with new v8 version * Elements: Increased parser tests. --- lib/lvelements/src/callable.cpp | 28 +- lib/lvelements/src/container.cpp | 4 +- lib/lvelements/src/element.cpp | 86 ++-- lib/lvelements/src/elementsplugin.cpp | 12 +- lib/lvelements/src/engine.cpp | 209 ++++++---- lib/lvelements/src/errorhandler.cpp | 27 +- lib/lvelements/src/function.cpp | 33 +- lib/lvelements/src/imports.cpp | 43 +- lib/lvelements/src/languagenodes.cpp | 382 ++++++++++++++---- lib/lvelements/src/languagenodes_p.h | 23 +- lib/lvelements/src/mlnodetojs.cpp | 30 +- lib/lvelements/src/modulefile.cpp | 18 +- lib/lvelements/src/object.cpp | 116 ++++-- lib/lvelements/src/object.h | 14 +- lib/lvelements/src/script.cpp | 33 +- lib/lvelements/src/v8nowarnings.h | 1 + lib/lvelements/src/value.cpp | 44 +- lib/lvelements/src/value.h | 2 + lib/lvelements/src/value_p.h | 91 +++-- lib/lvelements/src/visuallogjsobject.h | 40 +- plugins/editlv/src/lveditfragment.cpp | 4 +- plugins/language/src/moduleinfocapture.cpp | 4 +- plugins/test/src/testcase.cpp | 4 +- project/3rdparty/v8.pri | 2 - .../lvelementstest/data/ParserTest13.lv.js | 19 + .../lvelementstest/data/ParserTest14.lv.js | 4 +- .../unit/lvelementstest/data/ParserTest15.lv | 9 + .../lvelementstest/data/ParserTest15.lv.js | 22 + .../unit/lvelementstest/data/ParserTest16.lv | 7 + .../lvelementstest/data/ParserTest16.lv.js | 20 + .../unit/lvelementstest/data/ParserTest17.lv | 10 + .../lvelementstest/data/ParserTest17.lv.js | 19 + .../unit/lvelementstest/data/ParserTest18.lv | 12 + .../lvelementstest/data/ParserTest18.lv.js | 34 ++ .../unit/lvelementstest/data/ParserTest19.lv | 14 + .../lvelementstest/data/ParserTest19.lv.js | 66 +++ .../unit/lvelementstest/data/ParserTest20.lv | 14 + .../lvelementstest/data/ParserTest20.lv.js | 43 ++ .../unit/lvelementstest/data/ParserTest21.lv | 24 ++ .../lvelementstest/data/ParserTest21.lv.js | 57 +++ .../unit/lvelementstest/data/ParserTest22.lv | 7 + .../lvelementstest/data/ParserTest22.lv.js | 25 ++ .../unit/lvelementstest/data/ParserTest23.lv | 13 + .../lvelementstest/data/ParserTest23.lv.js | 29 ++ tests/unit/lvelementstest/jspropertytest.cpp | 4 +- tests/unit/lvelementstest/jstupletest.cpp | 4 +- tests/unit/lvelementstest/lvelementstest.pro | 3 +- tests/unit/lvelementstest/lvparsetest.cpp | 264 +++--------- tests/unit/lvelementstest/lvparsetest.h | 11 + tests/unit/lvelementstest/main.cpp | 3 +- tests/unit/lvelementstest/mlnodetojstest.cpp | 12 +- 51 files changed, 1379 insertions(+), 620 deletions(-) create mode 100644 tests/unit/lvelementstest/data/ParserTest13.lv.js create mode 100644 tests/unit/lvelementstest/data/ParserTest15.lv create mode 100644 tests/unit/lvelementstest/data/ParserTest15.lv.js create mode 100644 tests/unit/lvelementstest/data/ParserTest16.lv create mode 100644 tests/unit/lvelementstest/data/ParserTest16.lv.js create mode 100644 tests/unit/lvelementstest/data/ParserTest17.lv create mode 100644 tests/unit/lvelementstest/data/ParserTest17.lv.js create mode 100644 tests/unit/lvelementstest/data/ParserTest18.lv create mode 100644 tests/unit/lvelementstest/data/ParserTest18.lv.js create mode 100644 tests/unit/lvelementstest/data/ParserTest19.lv create mode 100644 tests/unit/lvelementstest/data/ParserTest19.lv.js create mode 100644 tests/unit/lvelementstest/data/ParserTest20.lv create mode 100644 tests/unit/lvelementstest/data/ParserTest20.lv.js create mode 100644 tests/unit/lvelementstest/data/ParserTest21.lv create mode 100644 tests/unit/lvelementstest/data/ParserTest21.lv.js create mode 100644 tests/unit/lvelementstest/data/ParserTest22.lv create mode 100644 tests/unit/lvelementstest/data/ParserTest22.lv.js create mode 100644 tests/unit/lvelementstest/data/ParserTest23.lv create mode 100644 tests/unit/lvelementstest/data/ParserTest23.lv.js diff --git a/lib/lvelements/src/callable.cpp b/lib/lvelements/src/callable.cpp index 7eb72eb0..309a7f6f 100644 --- a/lib/lvelements/src/callable.cpp +++ b/lib/lvelements/src/callable.cpp @@ -47,8 +47,9 @@ Callable::Callable(Engine* engine, const v8::Local &data) : m_d(nullptr) , m_ref(nullptr) { - - v8::Local shared = data->Get(v8::String::NewFromUtf8(engine->isolate(), "__shared__")); + auto isolate = engine->isolate(); + auto context = isolate->GetCurrentContext(); + v8::Local shared = data->Get(context, v8::String::NewFromUtf8(engine->isolate(), "__shared__").ToLocalChecked()).ToLocalChecked(); if ( shared->IsExternal() ){ m_d = reinterpret_cast(v8::Local::Cast(shared)->Value()); @@ -57,18 +58,29 @@ Callable::Callable(Engine* engine, const v8::Local &data) m_d = new CallablePrivate(engine, data); m_ref = new int; m_d->ref = m_ref; - data->Set(v8::String::NewFromUtf8(engine->isolate(), "__shared__"), v8::External::New(engine->isolate(), m_d)); + data->Set( + context, + v8::String::NewFromUtf8(engine->isolate(), "__shared__").ToLocalChecked(), + v8::External::New(engine->isolate(), m_d) + ).IsNothing(); } ++(*m_ref); } Callable::~Callable(){ + + auto isolate = m_d->engine->isolate(); + auto context = isolate->GetCurrentContext(); --(*m_ref); if ( *m_ref == 0 ){ if ( !m_d->data.IsEmpty() ){ v8::Local v = m_d->data.Get(m_d->engine->isolate()); - v->Set(v8::String::NewFromUtf8(m_d->engine->isolate(), "__shared__"), v8::Undefined(m_d->engine->isolate())); + v->Set( + context, + v8::String::NewFromUtf8(m_d->engine->isolate(), "__shared__").ToLocalChecked(), + v8::Undefined(m_d->engine->isolate()) + ).IsNothing(); m_d->data.SetWeak(); } @@ -112,14 +124,18 @@ Component Callable::toComponent() const{ } ScopedValue Callable::call(Element *that, const Function::Parameters ¶ms) const{ + auto isolate = m_d->engine->isolate(); + auto context = isolate->GetCurrentContext(); v8::Local local = m_d->data.Get(that->engine()->isolate()); v8::Local localThat = ElementPrivate::localObject(that); - return ScopedValue(local->Call(localThat, params.m_length, params.m_args)); + return ScopedValue(local->Call(context, localThat, params.m_length, params.m_args).ToLocalChecked()); } ScopedValue Callable::call(Engine *engine, const Function::Parameters ¶ms) const{ + auto isolate = m_d->engine->isolate(); + auto context = isolate->GetCurrentContext(); v8::Local local = m_d->data.Get(engine->isolate()); - return ScopedValue(local->Call(engine->currentContext()->asLocal()->Global(), params.m_length, params.m_args)); + return ScopedValue(local->Call(context, engine->currentContext()->asLocal()->Global(), params.m_length, params.m_args).ToLocalChecked()); } ScopedValue Callable::callAsConstructor(Engine *engine, const Function::Parameters ¶ms) const{ diff --git a/lib/lvelements/src/container.cpp b/lib/lvelements/src/container.cpp index 394044fe..90ebfcce 100644 --- a/lib/lvelements/src/container.cpp +++ b/lib/lvelements/src/container.cpp @@ -24,10 +24,12 @@ void Container::setChildren(ScopedValue children){ } m_data.clear(); + auto isolate = engine()->isolate(); + auto context = isolate->GetCurrentContext(); if ( data->IsArray()){ v8::Local arr = v8::Local::Cast(data); for ( unsigned int i = 0; i < arr->Length(); ++i ){ - ScopedValue v(arr->Get(i)); + ScopedValue v(arr->Get(context, i).ToLocalChecked()); Element* e = v.toElement(engine()); e->setParent(this); m_data.push_back(e); diff --git a/lib/lvelements/src/element.cpp b/lib/lvelements/src/element.cpp index de829c69..4ed3f5f1 100644 --- a/lib/lvelements/src/element.cpp +++ b/lib/lvelements/src/element.cpp @@ -82,19 +82,19 @@ void Element::setLifeTimeWithObject(const v8::Local &obj){ if ( p->isWritable() ){ obj->SetAccessor( context, - v8::Local::Cast(v8::String::NewFromUtf8(engine()->isolate(), p->name().c_str())), + v8::Local::Cast(v8::String::NewFromUtf8(engine()->isolate(), p->name().c_str()).ToLocalChecked()), &Property::ptrGetImplementation, &Property::ptrSetImplementation, pdata - ); + ).IsNothing(); } else { obj->SetAccessor( context, - v8::Local::Cast(v8::String::NewFromUtf8(engine()->isolate(), p->name().c_str())), + v8::Local::Cast(v8::String::NewFromUtf8(engine()->isolate(), p->name().c_str()).ToLocalChecked()), &Property::ptrGetImplementation, 0, pdata - ); + ).IsNothing();; } } @@ -135,7 +135,9 @@ void Element::unref(){ bool Element::hasScriptReference() const{ if ( m_d->persistent.IsEmpty() ) return false; - return !m_d->persistent.IsNearDeath(); + + return true; + // return !m_d->persistent.IsNearDeath(); } void Element::destroy(Element *e){ @@ -256,8 +258,10 @@ void Element::addEvent(Element *e, const std::string &ekey, const std::vector fdata = v8::External::New(d->engine->isolate(), ie); v->Set( - v8::String::NewFromUtf8(d->engine->isolate(), ekey.c_str()), - v8::FunctionTemplate::New(d->engine->isolate(), &InstanceEvent::callbackImplementation, fdata)->GetFunction()); + d->engine->isolate()->GetCurrentContext(), + v8::String::NewFromUtf8(d->engine->isolate(), ekey.c_str()).ToLocalChecked(), + v8::FunctionTemplate::New(d->engine->isolate(), &InstanceEvent::callbackImplementation, fdata)->GetFunction(d->engine->isolate()->GetCurrentContext()).ToLocalChecked() + ).IsNothing(); } } @@ -265,6 +269,9 @@ void Element::addEvent(Element *e, ScopedValue eventKey, ScopedValue types){ ElementPrivate* d = e->m_d; std::string ekey = eventKey.toStdString(e->engine()); + auto isolate = e->engine()->isolate(); + auto context = isolate->GetCurrentContext(); + if ( d->instanceEvents.find(ekey) != d->instanceEvents.end() ) { auto exc = CREATE_EXCEPTION(lv::Exception, "An event with the same name already exists.", lv::Exception::toCode("~Element")); @@ -284,8 +291,10 @@ void Element::addEvent(Element *e, ScopedValue eventKey, ScopedValue types){ v8::Local fdata = v8::External::New(d->engine->isolate(), ie); v->Set( - v8::String::NewFromUtf8(d->engine->isolate(), ekey.c_str()), - v8::FunctionTemplate::New(d->engine->isolate(), &InstanceEvent::callbackImplementation, fdata)->GetFunction()); + context, + v8::String::NewFromUtf8(isolate, ekey.c_str()).ToLocalChecked(), + v8::FunctionTemplate::New(isolate, &InstanceEvent::callbackImplementation, fdata)->GetFunction(context).ToLocalChecked() + ).IsNothing(); } } @@ -318,35 +327,39 @@ void Element::addProperty(Element *e, ScopedValue propertyName, ScopedValue prop bool isWritable = true; std::string notifyEvent; + auto isolate = e->engine()->isolate(); + auto context = isolate->GetCurrentContext(); + std::list > bindings; - v8::Local options = propertyOptions.data()->ToObject(); + v8::Local options = propertyOptions.data()->ToObject(context).ToLocalChecked(); - v8::Local typeKey = v8::String::NewFromUtf8(e->engine()->isolate(), "type"); - if ( options->Has(typeKey) ){ - type = *v8::String::Utf8Value(options->Get(typeKey)->ToString()); + v8::Local typeKey = v8::String::NewFromUtf8(e->engine()->isolate(), "type").ToLocalChecked(); + if ( options->Has(context, typeKey).ToChecked() ){ + type = *v8::String::Utf8Value(isolate, options->Get(context, typeKey).ToLocalChecked()->ToString(context).ToLocalChecked()); } - v8::Local isDefaultKey = v8::String::NewFromUtf8(e->engine()->isolate(), "isDefault"); - if ( options->Has(isDefaultKey) ){ - isDefault = options->Get(isDefaultKey)->BooleanValue(); + v8::Local isDefaultKey = v8::String::NewFromUtf8(isolate, "isDefault").ToLocalChecked(); + if ( options->Has(context, isDefaultKey).ToChecked() ){ + isDefault = options->Get(context, isDefaultKey).ToLocalChecked()->BooleanValue(isolate); } - v8::Local isWritableKey = v8::String::NewFromUtf8(e->engine()->isolate(), "isWritable"); - if ( options->Has(isWritableKey) ){ - isWritable = options->Get(isWritableKey)->BooleanValue(); + v8::Local isWritableKey = v8::String::NewFromUtf8(isolate, "isWritable").ToLocalChecked(); + if ( options->Has(context, isWritableKey).ToChecked() ){ + isWritable = options->Get(context, isWritableKey).ToLocalChecked()->BooleanValue(isolate); } if ( isWritable ){ - v8::Local notifyKey = v8::String::NewFromUtf8(e->engine()->isolate(), "notify"); - notifyEvent = *v8::String::Utf8Value(options->Get(notifyKey)->ToString()); + v8::Local notifyKey = v8::String::NewFromUtf8(isolate, "notify").ToLocalChecked(); + notifyEvent = *v8::String::Utf8Value(isolate, options->Get(context, notifyKey).ToLocalChecked()->ToString(context).ToLocalChecked()); } - v8::Local valueKey = v8::String::NewFromUtf8(e->engine()->isolate(), "value"); - if ( options->Has(valueKey) ){ - v8::Local v = options->Get(valueKey); - v8::Local bindingsKey = v8::String::NewFromUtf8(e->engine()->isolate(), "bindings"); - if ( v->IsFunction() && options->Has(bindingsKey) ){ + v8::Local valueKey = v8::String::NewFromUtf8(e->engine()->isolate(), "value").ToLocalChecked(); + if ( options->Has(context, valueKey).ToChecked() ){ + v8::Local v = options->Get(context, valueKey).ToLocalChecked(); + v8::Local bindingsKey = v8::String::NewFromUtf8(e->engine()->isolate(), "bindings").ToLocalChecked(); + if ( v->IsFunction() && options->Has(context, bindingsKey).ToChecked() ){ e->addProperty(name, type, value, isDefault, isWritable, notifyEvent); - assignPropertyExpression(e, propertyName, ScopedValue(v), ScopedValue(options->Get(bindingsKey))); + assignPropertyExpression(e, propertyName, ScopedValue(v), + ScopedValue(options->Get(context, bindingsKey).ToLocalChecked())); } else { value = ScopedValue(e->engine(), v); e->addProperty(name, type, value, isDefault, isWritable, notifyEvent); @@ -368,6 +381,9 @@ void Element::assignPropertyExpression( Callable expression = propertyExpression.toCallable(e->engine()); Property* p = e->property(name); + auto isolate = e->engine()->isolate(); + auto context = isolate->GetCurrentContext(); + auto it = d->boundPropertyExpressions.find(name); if ( it != d->boundPropertyExpressions.end() ){ Element::BindableExpression* be = it->second; @@ -404,7 +420,7 @@ void Element::assignPropertyExpression( v8::Local bindingsArray = v8::Local::Cast(bindings.data()); for ( uint32_t i = 0; i < bindingsArray->Length(); ++i ){ - v8::Local baItem = v8::Local::Cast(bindingsArray->Get(i)); + v8::Local baItem = v8::Local::Cast(bindingsArray->Get(context, i).ToLocalChecked()); if ( baItem->Length() != 2 ){ lv::Exception exc = CREATE_EXCEPTION( lv::Exception, "Bindings require array of dual arrays: [[object, name]].", Exception::toCode("~Binding") @@ -413,10 +429,10 @@ void Element::assignPropertyExpression( return; } - ScopedValue bindingElementValue = ScopedValue(e->engine(), baItem->Get(0)); + ScopedValue bindingElementValue = ScopedValue(e->engine(), baItem->Get(context, 0).ToLocalChecked()); if ( bindingElementValue.isElement() ){ Element* bindingElement = bindingElementValue.toElement(e->engine()); - std::string bindingEvent = ScopedValue(e->engine(), baItem->Get(1)).toStdString(e->engine()); + std::string bindingEvent = ScopedValue(e->engine(), baItem->Get(context, 1).ToLocalChecked()).toStdString(e->engine()); try { EventConnection* bec = bindingElement->on(bindingEvent, [be](const Function::Parameters&){ @@ -478,6 +494,8 @@ InstanceProperty* Element::addProperty( { ElementPrivate* d = m_d; + auto isolate = engine()->isolate(); + auto context = isolate->GetCurrentContext(); if ( d->instanceProperties.find(name) != d->instanceProperties.end() ) { auto exc = CREATE_EXCEPTION(lv::Exception, "A property under such name already exists", lv::Exception::toCode("~Element")); @@ -512,19 +530,19 @@ InstanceProperty* Element::addProperty( if ( isWritable ){ v->SetAccessor( context, - v8::Local::Cast(v8::String::NewFromUtf8(d->engine->isolate(), name.c_str())), + v8::Local::Cast(v8::String::NewFromUtf8(d->engine->isolate(), name.c_str()).ToLocalChecked()), &Property::ptrGetImplementation, &Property::ptrSetImplementation, pdata - ); + ).IsNothing(); } else { v->SetAccessor( context, - v8::Local::Cast(v8::String::NewFromUtf8(d->engine->isolate(), name.c_str())), + v8::Local::Cast(v8::String::NewFromUtf8(d->engine->isolate(), name.c_str()).ToLocalChecked()), &Property::ptrGetImplementation, 0, pdata - ); + ).IsNothing(); } } diff --git a/lib/lvelements/src/elementsplugin.cpp b/lib/lvelements/src/elementsplugin.cpp index 6bda72ed..69da8640 100644 --- a/lib/lvelements/src/elementsplugin.cpp +++ b/lib/lvelements/src/elementsplugin.cpp @@ -103,16 +103,18 @@ const Plugin::Ptr& ElementsPlugin::plugin() const{ } Object ElementsPlugin::collectExportsObject(){ - v8::Local result = v8::Object::New(m_d->engine->isolate()); + auto isolate = m_d->engine->isolate(); + auto context = isolate->GetCurrentContext(); + v8::Local result = v8::Object::New(isolate); v8::Local lo = m_d->libraryExports.data(); - v8::Local pn = lo->GetOwnPropertyNames(); + v8::Local pn = lo->GetOwnPropertyNames(context, v8::ALL_PROPERTIES).ToLocalChecked(); for (uint32_t i = 0; i < pn->Length(); ++i) { - v8::Local key = pn->Get(i); - v8::Local value = lo->Get(key); + v8::Local key = pn->Get(context, i).ToLocalChecked(); + v8::Local value = lo->Get(context, key).ToLocalChecked(); - result->Set(key, value); + result->Set(context, key, value).IsNothing(); } //TODO: Capture file exports diff --git a/lib/lvelements/src/engine.cpp b/lib/lvelements/src/engine.cpp index a1fb0064..818a6a86 100644 --- a/lib/lvelements/src/engine.cpp +++ b/lib/lvelements/src/engine.cpp @@ -107,9 +107,9 @@ void EnginePrivate::messageListener(v8::Local message, v8::Local engineData = v8::Local::Cast(data); Engine* engine = reinterpret_cast(engineData->Value()); - v8::String::Utf8Value msg(message->Get()); - v8::String::Utf8Value file(v8::Local::Cast(message->GetScriptResourceName())); - int line = message->GetScriptOrigin().ResourceLineOffset()->Int32Value(); + v8::String::Utf8Value msg(engine->isolate(), message->Get()); + v8::String::Utf8Value file(engine->isolate(), v8::Local::Cast(message->GetScriptResourceName())); + int line = message->GetScriptOrigin().ResourceLineOffset()->Int32Value(engine->isolate()->GetCurrentContext()).ToChecked(); engine->handleError(*msg, "", *file, line); } @@ -119,7 +119,7 @@ void EnginePrivate::messageListener(v8::Local message, v8::Local platform; bool disposeAtExit; }; @@ -131,10 +131,10 @@ void Engine::initialize(const std::string &defaultLocation){ v8::V8::InitializeExternalStartupData(defaultLocation.c_str()); m_initializeData = new Engine::InitializeData; - m_initializeData->platform = v8::platform::CreateDefaultPlatform(); + m_initializeData->platform = v8::platform::NewDefaultPlatform(); m_initializeData->disposeAtExit = false; - v8::V8::InitializePlatform(m_initializeData->platform); + v8::V8::InitializePlatform(m_initializeData->platform.get()); v8::V8::Initialize(); } } @@ -233,7 +233,7 @@ Script::Ptr Engine::compileJs(const std::string &str){ v8::Context::Scope context_scope(context); v8::Local source = - v8::String::NewFromUtf8(isolate(), str.c_str()); + v8::String::NewFromUtf8(isolate(), str.c_str()).ToLocalChecked(); v8::MaybeLocal r = v8::Script::Compile(context, source); @@ -266,7 +266,7 @@ Script::Ptr Engine::compileJsEnclosed(const std::string &str){ v8::Context::Scope context_scope(context); v8::Local source = - v8::String::NewFromUtf8(isolate(), (Script::encloseStart + str + Script::encloseEnd).c_str()); + v8::String::NewFromUtf8(isolate(), (Script::encloseStart + str + Script::encloseEnd).c_str()).ToLocalChecked(); Script::Ptr sc(new Script(this, v8::Script::Compile(context, source).ToLocalChecked())); return sc; @@ -284,7 +284,7 @@ Script::Ptr Engine::compileJsModuleFile(const std::string &path){ std::stringstream sstr; sstr << Script::moduleEncloseStart << file.rdbuf() << Script::moduleEncloseEnd; - v8::Local source = v8::String::NewFromUtf8(isolate(), (sstr.str()).c_str()); + v8::Local source = v8::String::NewFromUtf8(isolate(), (sstr.str()).c_str()).ToLocalChecked(); v8::MaybeLocal script = v8::Script::Compile(context, source); if ( script.IsEmpty() ) @@ -365,7 +365,7 @@ Script::Ptr Engine::compileModuleSource(const std::string &path, const std::stri std::string jssourceEnclosed = Script::moduleEncloseStart + jssource + Script::moduleEncloseEnd; - v8::Local sourceLocal = v8::String::NewFromUtf8(isolate(), jssourceEnclosed.c_str()); + v8::Local sourceLocal = v8::String::NewFromUtf8(isolate(), jssourceEnclosed.c_str()).ToLocalChecked(); v8::MaybeLocal script = v8::Script::Compile(context, sourceLocal); if ( script.IsEmpty() ) @@ -465,7 +465,7 @@ ComponentTemplate *Engine::registerTemplate(const MetaObject *t){ } else { tpl->SetCallHandler(&Constructor::nullImplementation); } - tpl->SetClassName(v8::String::NewFromUtf8(isolate(), t->name().c_str())); + tpl->SetClassName(v8::String::NewFromUtf8(isolate(), t->name().c_str()).ToLocalChecked()); v8::Local tplInstance = tpl->InstanceTemplate(); tplInstance->SetInternalFieldCount(1); @@ -492,14 +492,14 @@ ComponentTemplate *Engine::registerTemplate(const MetaObject *t){ if ( p->isWritable() ){ tplInstance->SetAccessor( - v8::String::NewFromUtf8(isolate(), propIt->first.c_str()), + v8::String::NewFromUtf8(isolate(), propIt->first.c_str()).ToLocalChecked(), &Property::ptrGetImplementation, &Property::ptrSetImplementation, pdata ); } else { tplInstance->SetAccessor( - v8::String::NewFromUtf8(isolate(), propIt->first.c_str()), + v8::String::NewFromUtf8(isolate(), propIt->first.c_str()).ToLocalChecked(), &Property::ptrGetImplementation, nullptr, pdata @@ -523,14 +523,15 @@ ComponentTemplate *Engine::registerTemplate(const MetaObject *t){ } // Functions - v8::Local ftpl = tpl->GetFunction(); + v8::Local ftpl = tpl->GetFunction(isolate()->GetCurrentContext()).ToLocalChecked(); for ( auto funcIt = t->functionsBegin(); funcIt != t->functionsEnd(); ++funcIt ){ Function* f = funcIt->second; v8::Local fdata = v8::External::New(isolate(), f); ftpl->Set( - v8::String::NewFromUtf8(isolate(), funcIt->first.c_str()), - v8::FunctionTemplate::New(isolate(), f->ptr(), fdata)->GetFunction() - ); + isolate()->GetCurrentContext(), + v8::String::NewFromUtf8(isolate(), funcIt->first.c_str()).ToLocalChecked(), + v8::FunctionTemplate::New(isolate(), f->ptr(), fdata)->GetFunction(isolate()->GetCurrentContext()).ToLocalChecked() + ).IsNothing(); } ComponentTemplate* compTpl = new ComponentTemplate(this, tpl); @@ -568,11 +569,11 @@ v8::Local Engine::importsTemplate(){ // } bool Engine::isElementConstructor(const Callable &c){ - v8::Local elemClass = m_d->elementTemplate->data.Get(isolate())->GetFunction(); + v8::Local elemClass = m_d->elementTemplate->data.Get(isolate())->GetFunction(isolate()->GetCurrentContext()).ToLocalChecked(); v8::Local childClass = c.data(); - v8::Local elemClassPrototype = elemClass->Get(v8::String::NewFromUtf8(isolate(), "prototype")); - v8::Local childClassPrototype = childClass->Get(v8::String::NewFromUtf8(isolate(), "prototype")); + v8::Local elemClassPrototype = elemClass->Get(isolate()->GetCurrentContext(), v8::String::NewFromUtf8(isolate(), "prototype").ToLocalChecked()).ToLocalChecked(); + v8::Local childClassPrototype = childClass->Get(isolate()->GetCurrentContext(), v8::String::NewFromUtf8(isolate(), "prototype").ToLocalChecked()).ToLocalChecked(); while (childClassPrototype->IsObject()){ v8::Maybe eq = childClassPrototype->Equals(m_d->context->asLocal(), elemClassPrototype); @@ -581,7 +582,7 @@ bool Engine::isElementConstructor(const Callable &c){ } v8::Local fncPrototypeCast = v8::Local::Cast(childClassPrototype); - childClassPrototype = fncPrototypeCast->Get(v8::String::NewFromUtf8(isolate(), "__proto__")); + childClassPrototype = fncPrototypeCast->Get(isolate()->GetCurrentContext(), v8::String::NewFromUtf8(isolate(), "__proto__").ToLocalChecked()).ToLocalChecked(); } return false; @@ -604,11 +605,11 @@ void Engine::throwError(const Exception *exception, Element *object){ if (se) { e = v8::Exception::SyntaxError( - v8::String::NewFromUtf8(m_d->isolate, exception->message().c_str())); + v8::String::NewFromUtf8(m_d->isolate, exception->message().c_str()).ToLocalChecked()); } else { e = v8::Exception::Error( - v8::String::NewFromUtf8(m_d->isolate, exception->message().c_str())); + v8::String::NewFromUtf8(m_d->isolate, exception->message().c_str()).ToLocalChecked()); } v8::Local o = v8::Local::Cast(e); @@ -619,9 +620,9 @@ void Engine::throwError(const Exception *exception, Element *object){ for (int i = 0; i sf = st->GetFrame(i); - v8::String::Utf8Value scriptName(sf->GetScriptName()); - v8::String::Utf8Value functionName(sf->GetFunctionName()); + v8::Local sf = st->GetFrame(isolate(), i); + v8::String::Utf8Value scriptName(isolate(), sf->GetScriptName()); + v8::String::Utf8Value functionName(isolate(), sf->GetFunctionName()); stackCapture << "at "; if (functionName.length() != 0) @@ -651,36 +652,36 @@ void Engine::throwError(const Exception *exception, Element *object){ } - v8::Local stackKey = v8::String::NewFromUtf8(isolate(), "stack", v8::String::kInternalizedString); - v8::Local stackValue = v8::String::NewFromUtf8(isolate(), stackCapture.str().c_str(), v8::String::kInternalizedString); + v8::Local stackKey = v8::String::NewFromUtf8(isolate(), "stack", v8::NewStringType::kInternalized).ToLocalChecked(); + v8::Local stackValue = v8::String::NewFromUtf8(isolate(), stackCapture.str().c_str(), v8::NewStringType::kInternalized).ToLocalChecked(); - o->Set(stackKey, stackValue); + o->Set(isolate()->GetCurrentContext(), stackKey, stackValue).IsNothing(); if (se) { - v8::Local lineNumberKey = v8::String::NewFromUtf8(isolate(), "lineNumber", v8::String::kInternalizedString); - o->Set(lineNumberKey, v8::Integer::New(isolate(), se->parsedLine())); + v8::Local lineNumberKey = v8::String::NewFromUtf8(isolate(), "lineNumber", v8::NewStringType::kInternalized).ToLocalChecked(); + o->Set(isolate()->GetCurrentContext(), lineNumberKey, v8::Integer::New(isolate(), se->parsedLine())).IsNothing(); - v8::Local columnKey = v8::String::NewFromUtf8(isolate(), "column", v8::String::kInternalizedString); - o->Set(columnKey, v8::Integer::New(isolate(), se->parsedColumn())); + v8::Local columnKey = v8::String::NewFromUtf8(isolate(), "column", v8::NewStringType::kInternalized).ToLocalChecked(); + o->Set(isolate()->GetCurrentContext(), columnKey, v8::Integer::New(isolate(), se->parsedColumn())).IsNothing(); - v8::Local offsetKey = v8::String::NewFromUtf8(isolate(), "offset", v8::String::kInternalizedString); - o->Set(offsetKey, v8::Integer::New(isolate(), se->parsedColumn())); + v8::Local offsetKey = v8::String::NewFromUtf8(isolate(), "offset", v8::NewStringType::kInternalized).ToLocalChecked(); + o->Set(isolate()->GetCurrentContext(), offsetKey, v8::Integer::New(isolate(), se->parsedColumn())).IsNothing(); - v8::Local fileNameKey = v8::String::NewFromUtf8(isolate(), "fileName", v8::String::kInternalizedString); - o->Set(fileNameKey, v8::String::NewFromUtf8(isolate(), se->fileName().c_str(), v8::String::kInternalizedString)); + v8::Local fileNameKey = v8::String::NewFromUtf8(isolate(), "fileName", v8::NewStringType::kInternalized).ToLocalChecked(); + o->Set(isolate()->GetCurrentContext(), fileNameKey, v8::String::NewFromUtf8(isolate(), se->fileName().c_str(), v8::NewStringType::kInternalized).ToLocalChecked()).IsNothing(); } else { if ( object ){ - v8::Local objectKey = v8::String::NewFromUtf8(isolate(), "object", v8::String::kInternalizedString); - o->Set(objectKey, ElementPrivate::localObject(object)); + v8::Local objectKey = v8::String::NewFromUtf8(isolate(), "object", v8::NewStringType::kInternalized).ToLocalChecked(); + o->Set(isolate()->GetCurrentContext(), objectKey, ElementPrivate::localObject(object)).IsNothing(); } - v8::Local fileNameKey = v8::String::NewFromUtf8(isolate(), "fileName", v8::String::kInternalizedString); - o->Set(fileNameKey, v8::String::NewFromUtf8(isolate(), exception->file().c_str(), v8::String::kInternalizedString)); + v8::Local fileNameKey = v8::String::NewFromUtf8(isolate(), "fileName", v8::NewStringType::kInternalized).ToLocalChecked(); + o->Set(isolate()->GetCurrentContext(), fileNameKey, v8::String::NewFromUtf8(isolate(), exception->file().c_str(), v8::NewStringType::kInternalized).ToLocalChecked()).IsNothing(); - v8::Local lineNumberKey = v8::String::NewFromUtf8(isolate(), "lineNumber", v8::String::kInternalizedString); - o->Set(lineNumberKey, v8::Integer::New(isolate(), exception->line())); + v8::Local lineNumberKey = v8::String::NewFromUtf8(isolate(), "lineNumber", v8::NewStringType::kInternalized).ToLocalChecked(); + o->Set(isolate()->GetCurrentContext(), lineNumberKey, v8::Integer::New(isolate(), exception->line())).IsNothing(); } m_d->pendingExceptionNesting = m_d->tryCatchNesting; @@ -771,44 +772,80 @@ void Engine::importInternals(){ ComponentTemplate* tupleTemplate = registerTemplate(&Tuple::metaObject()); v8::Local tpl = m_d->elementTemplate->data.Get(isolate()); - context->Global()->Set(v8::String::NewFromUtf8(isolate(), "Element"), tpl->GetFunction()); + context->Global()->Set( + isolate()->GetCurrentContext(), + v8::String::NewFromUtf8(isolate(), "Element").ToLocalChecked(), + tpl->GetFunction(isolate()->GetCurrentContext()).ToLocalChecked() + ).IsNothing(); v8::Local listTpl = listTemplate->data.Get(isolate()); - context->Global()->Set(v8::String::NewFromUtf8(isolate(), "List"), listTpl->GetFunction()); + context->Global()->Set( + isolate()->GetCurrentContext(), + v8::String::NewFromUtf8(isolate(), "List").ToLocalChecked(), + listTpl->GetFunction(isolate()->GetCurrentContext()).ToLocalChecked() + ).IsNothing(); v8::Local containerTpl = containerTemplate->data.Get(isolate()); - context->Global()->Set(v8::String::NewFromUtf8(isolate(), "Container"), containerTpl->GetFunction()); + context->Global()->Set( + isolate()->GetCurrentContext(), + v8::String::NewFromUtf8(isolate(), "Container").ToLocalChecked(), + containerTpl->GetFunction(isolate()->GetCurrentContext()).ToLocalChecked() + ).IsNothing(); v8::Local errorHandlerTpl = errorHandlerTemplate->data.Get(isolate()); - context->Global()->Set(v8::String::NewFromUtf8(isolate(), "ErrorHandler"), errorHandlerTpl->GetFunction()); + context->Global()->Set( + isolate()->GetCurrentContext(), + v8::String::NewFromUtf8(isolate(), "ErrorHandler").ToLocalChecked(), + errorHandlerTpl->GetFunction(isolate()->GetCurrentContext()).ToLocalChecked() + ).IsNothing(); v8::Local tupleTpl = tupleTemplate->data.Get(isolate()); - context->Global()->Set(v8::String::NewFromUtf8(isolate(), "Tuple"), tupleTpl->GetFunction()); + context->Global()->Set( + isolate()->GetCurrentContext(), + v8::String::NewFromUtf8(isolate(), "Tuple").ToLocalChecked(), + tupleTpl->GetFunction(isolate()->GetCurrentContext()).ToLocalChecked() + ).IsNothing(); m_d->pointTemplate.Reset(isolate(), Point::functionTemplate(isolate())); - context->Global()->Set(v8::String::NewFromUtf8(isolate(), "Point"), pointTemplate()->GetFunction()); + context->Global()->Set( + isolate()->GetCurrentContext(), + v8::String::NewFromUtf8(isolate(), "Point").ToLocalChecked(), + pointTemplate()->GetFunction(isolate()->GetCurrentContext()).ToLocalChecked() + ).IsNothing(); m_d->sizeTemplate.Reset(isolate(), Size::functionTemplate(isolate())); - context->Global()->Set(v8::String::NewFromUtf8(isolate(), "Size"), sizeTemplate()->GetFunction()); + context->Global()->Set( + isolate()->GetCurrentContext(), + v8::String::NewFromUtf8(isolate(), "Size").ToLocalChecked(), + sizeTemplate()->GetFunction(isolate()->GetCurrentContext()).ToLocalChecked() + ).IsNothing(); m_d->rectangleTemplate.Reset(isolate(), Rectangle::functionTemplate(isolate())); - context->Global()->Set(v8::String::NewFromUtf8(isolate(), "Rectangle"), rectangleTemplate()->GetFunction()); + context->Global()->Set( + isolate()->GetCurrentContext(), + v8::String::NewFromUtf8(isolate(), "Rectangle").ToLocalChecked(), + rectangleTemplate()->GetFunction(isolate()->GetCurrentContext()).ToLocalChecked() + ).IsNothing(); m_d->importsTemplate.Reset(isolate(), Imports::functionTemplate(isolate())); context->Global()->Set( - v8::String::NewFromUtf8(isolate(), "vlog"), - VisualLogJsObject::functionTemplate(isolate())->InstanceTemplate()->NewInstance()); + isolate()->GetCurrentContext(), + v8::String::NewFromUtf8(isolate(), "vlog").ToLocalChecked(), + VisualLogJsObject::functionTemplate(isolate())->InstanceTemplate()->NewInstance(isolate()->GetCurrentContext()).ToLocalChecked() + ).IsNothing(); context->Global()->Set( - v8::String::NewFromUtf8(isolate(), "linkError"), - v8::FunctionTemplate::New(isolate(), &linkError)->GetFunction()); + isolate()->GetCurrentContext(), + v8::String::NewFromUtf8(isolate(), "linkError").ToLocalChecked(), + v8::FunctionTemplate::New(isolate(), &linkError)->GetFunction(isolate()->GetCurrentContext()).ToLocalChecked() + ).IsNothing(); } void Engine::wrapScriptObject(Element *element){ ComponentTemplate* ctpl = registerTemplate(&element->typeMetaObject()); v8::Local tpl = ctpl->data.Get(isolate()); - v8::Local instance = tpl->InstanceTemplate()->NewInstance(); + v8::Local instance = tpl->InstanceTemplate()->NewInstance(isolate()->GetCurrentContext()).ToLocalChecked(); element->setLifeTimeWithObject(instance); } @@ -836,14 +873,22 @@ Object Engine::require(ModuleLibrary *module, const Object& o){ ComponentTemplate* ctpl = registerTemplate(t); v8::Local tpl = ctpl->data.Get(isolate()); - base->Set(v8::String::NewFromUtf8(isolate(), t->name().c_str()), tpl->GetFunction()); + base->Set( + isolate()->GetCurrentContext(), + v8::String::NewFromUtf8(isolate(), t->name().c_str()).ToLocalChecked(), + tpl->GetFunction(isolate()->GetCurrentContext()).ToLocalChecked() + ).IsNothing(); } for ( auto it = module->instancesBegin(); it != module->instancesEnd(); ++it ){ std::string name = it->first; Element* e = it->second; v8::Local lo = ElementPrivate::localObject(e); - base->Set(v8::String::NewFromUtf8(isolate(), name.c_str()), lo); + base->Set( + isolate()->GetCurrentContext(), + v8::String::NewFromUtf8(isolate(), name.c_str()).ToLocalChecked(), + lo + ).IsNothing(); } return exportsObject; @@ -889,50 +934,60 @@ void Engine::CatchData::rethrow(){ } std::string Engine::CatchData::message() const{ - v8::Local messageKey = v8::String::NewFromUtf8(m_engine->isolate(), "message", v8::String::kInternalizedString); - v8::Local exceptionObj = m_tryCatch->Exception()->ToObject(); - if ( exceptionObj->Has(messageKey) ){ - v8::String::Utf8Value result(exceptionObj->Get(messageKey)->ToString()); + auto isolate = m_engine->isolate(); + auto context = isolate->GetCurrentContext(); + + v8::Local messageKey = v8::String::NewFromUtf8(isolate, "message", v8::NewStringType::kInternalized).ToLocalChecked(); + v8::Local exceptionObj = m_tryCatch->Exception()->ToObject(context).ToLocalChecked(); + if ( exceptionObj->Has(context, messageKey).ToChecked() ){ + v8::String::Utf8Value result(isolate, exceptionObj->Get(context, messageKey).ToLocalChecked()); return *result; } else { - v8::String::Utf8Value msg(m_tryCatch->Message()->Get()); + v8::String::Utf8Value msg(isolate, m_tryCatch->Message()->Get()); return *msg; } } std::string Engine::CatchData::stack() const{ - v8::String::Utf8Value msg(m_tryCatch->StackTrace()->ToString()); + auto context = m_engine->isolate()->GetCurrentContext(); + v8::String::Utf8Value msg(m_engine->isolate(), m_tryCatch->StackTrace(context).ToLocalChecked()); return *msg; } std::string Engine::CatchData::fileName() const{ - v8::Local fileNameKey = v8::String::NewFromUtf8(m_engine->isolate(), "fileName", v8::String::kInternalizedString); - v8::Local exceptionObj = m_tryCatch->Exception()->ToObject(); - if ( exceptionObj->Has(fileNameKey) ){ - v8::String::Utf8Value result(exceptionObj->Get(fileNameKey)->ToString()); + auto isolate = m_engine->isolate(); + auto context = isolate->GetCurrentContext(); + v8::Local fileNameKey = v8::String::NewFromUtf8(m_engine->isolate(), "fileName", v8::NewStringType::kInternalized).ToLocalChecked(); + v8::Local exceptionObj = m_tryCatch->Exception()->ToObject(context).ToLocalChecked(); + if ( exceptionObj->Has(context, fileNameKey).ToChecked() ){ + v8::String::Utf8Value result(isolate, exceptionObj->Get(context, fileNameKey).ToLocalChecked()); return *result; } else { - v8::String::Utf8Value file(m_tryCatch->Message()->GetScriptResourceName()->ToString()); + v8::String::Utf8Value file(isolate, m_tryCatch->Message()->GetScriptResourceName()->ToString(context).ToLocalChecked()); return *file; } } int Engine::CatchData::lineNumber() const{ - v8::Local lineNumberKey = v8::String::NewFromUtf8(m_engine->isolate(), "lineNumber", v8::String::kInternalizedString); - v8::Local exceptionObj = m_tryCatch->Exception()->ToObject(); - if ( exceptionObj->Has(lineNumberKey) ){ - return exceptionObj->Get(lineNumberKey)->Int32Value(); + auto isolate = m_engine->isolate(); + auto context = isolate->GetCurrentContext(); + v8::Local lineNumberKey = v8::String::NewFromUtf8(m_engine->isolate(), "lineNumber", v8::NewStringType::kInternalized).ToLocalChecked(); + v8::Local exceptionObj = m_tryCatch->Exception()->ToObject(context).ToLocalChecked(); + if ( exceptionObj->Has(context, lineNumberKey).ToChecked() ){ + return exceptionObj->Get(context, lineNumberKey).ToLocalChecked()->ToInteger(context).ToLocalChecked()->Value(); } - return m_tryCatch->Message()->GetLineNumber(); + return m_tryCatch->Message()->GetLineNumber(context).ToChecked(); } Element *Engine::CatchData::object() const{ + auto isolate = m_engine->isolate(); + auto context = isolate->GetCurrentContext(); v8::Local o = v8::Local::Cast(m_tryCatch->Exception()); - v8::Local oKey = v8::String::NewFromUtf8(m_engine->isolate(), "object", v8::String::kInternalizedString); + v8::Local oKey = v8::String::NewFromUtf8(m_engine->isolate(), "object", v8::NewStringType::kInternalized).ToLocalChecked(); - if ( o->Has(oKey) ){ - v8::Local obj = o->Get(oKey)->ToObject(); + if ( o->Has(context, oKey).ToChecked() ){ + v8::Local obj = o->Get(context, oKey).ToLocalChecked()->ToObject(context).ToLocalChecked(); if ( obj->InternalFieldCount() == 1 ){ v8::Local wrap = v8::Local::Cast(obj->GetInternalField(0)); void* ptr = wrap->Value(); diff --git a/lib/lvelements/src/errorhandler.cpp b/lib/lvelements/src/errorhandler.cpp index 6ccc41cd..0d3e2ab2 100644 --- a/lib/lvelements/src/errorhandler.cpp +++ b/lib/lvelements/src/errorhandler.cpp @@ -16,22 +16,25 @@ void ErrorHandler::setTarget(Element *target){ if ( target == m_target ) return; + auto isolate = engine()->isolate(); + auto context = isolate->GetCurrentContext(); + if ( m_target != nullptr ){ v8::Local lo = ElementPrivate::localObject(m_target); v8::Local ehKey = v8::String::NewFromUtf8( - engine()->isolate(), "__errorhandler__", v8::String::kInternalizedString - ); + engine()->isolate(), "__errorhandler__", v8::NewStringType::kInternalized + ).ToLocalChecked(); - if ( lo->Has(ehKey) ) - lo->Delete(ehKey); + if ( lo->Has(context, ehKey).ToChecked() ) + lo->Delete(context, ehKey).IsNothing(); } if ( target != nullptr ){ v8::Local lo = ElementPrivate::localObject(target); v8::Local ehKey = v8::String::NewFromUtf8( - engine()->isolate(), "__errorhandler__", v8::String::kInternalizedString - ); + engine()->isolate(), "__errorhandler__", v8::NewStringType::kInternalized + ).ToLocalChecked(); - lo->Set(ehKey, ElementPrivate::localObject(this)); + lo->Set(context, ehKey, ElementPrivate::localObject(this)).IsNothing(); } m_target = target; @@ -43,14 +46,16 @@ void ErrorHandler::rethrow(ScopedValue e){ if ( current ) current = m_target->parent(); + auto isolate = engine()->isolate(); + auto context = isolate->GetCurrentContext(); v8::Local ehKey = v8::String::NewFromUtf8( - engine()->isolate(), "__errorhandler__", v8::String::kInternalizedString - ); + engine()->isolate(), "__errorhandler__", v8::NewStringType::kInternalized + ).ToLocalChecked(); while ( current ){ v8::Local lo = ElementPrivate::localObject(current); - if ( lo->Has(ehKey) ){ - Element* elem = ElementPrivate::elementFromObject(lo->Get(ehKey)->ToObject()); + if ( lo->Has(context, ehKey).ToChecked() ){ + Element* elem = ElementPrivate::elementFromObject(lo->Get(context, ehKey).ToLocalChecked()->ToObject(context).ToLocalChecked()); ErrorHandler* ehandler = elem->cast(); ehandler->handlerError(e.data(), m_lastError); break; diff --git a/lib/lvelements/src/function.cpp b/lib/lvelements/src/function.cpp index 93da4018..c89f5489 100644 --- a/lib/lvelements/src/function.cpp +++ b/lib/lvelements/src/function.cpp @@ -3,33 +3,38 @@ #include "live/elements/element.h" #include "live/exception.h" #include "v8nowarnings.h" +#include "context_p.h" namespace lv{ namespace el{ template<> bool Function::CallInfo::extractValue(const v8::FunctionCallbackInfo *info, int index){ - return (*info)[index]->BooleanValue(); + return (*info)[index]->BooleanValue(info->GetIsolate()); } template<> Value::Int32 Function::CallInfo::extractValue(v8::FunctionCallbackInfo const* info, int index){ - return (*info)[index]->Int32Value(); + auto engine = reinterpret_cast(info->GetIsolate()->GetData(0)); + return (*info)[index]->Int32Value(engine->currentContext()->asLocal()).ToChecked(); } template<> Value::Int64 Function::CallInfo::extractValue(const v8::FunctionCallbackInfo *info, int index){ - return (*info)[index]->IntegerValue(); + auto engine = reinterpret_cast(info->GetIsolate()->GetData(0)); + return (*info)[index]->IntegerValue(engine->currentContext()->asLocal()).ToChecked(); } template<> Value::Number Function::CallInfo::extractValue(const v8::FunctionCallbackInfo *info, int index){ - return (*info)[index]->NumberValue(); + auto engine = reinterpret_cast(info->GetIsolate()->GetData(0)); + return (*info)[index]->NumberValue(engine->currentContext()->asLocal()).ToChecked(); } template<> std::string Function::CallInfo::extractValue(const v8::FunctionCallbackInfo *info, int index){ - return *v8::String::Utf8Value((*info)[index]->ToString(info->GetIsolate())); + auto engine = reinterpret_cast(info->GetIsolate()->GetData(0)); + return *v8::String::Utf8Value(info->GetIsolate(), (*info)[index]->ToString(engine->currentContext()->asLocal()).ToLocalChecked()); } template<> @@ -171,28 +176,28 @@ int Function::Parameters::length() const{ template<> -bool Function::Parameters::extractValue(Engine *, const v8::Local *args, int index){ - return args[index]->BooleanValue(); +bool Function::Parameters::extractValue(Engine *engine, const v8::Local *args, int index){ + return args[index]->BooleanValue(engine->isolate()); } template<> -int Function::Parameters::extractValue(Engine*, const v8::Local *args, int index){ - return args[index]->Int32Value(); +int Function::Parameters::extractValue(Engine *engine, const v8::Local *args, int index){ + return args[index]->Int32Value(engine->currentContext()->asLocal()).ToChecked(); } template<> -Value::Int64 Function::Parameters::extractValue(Engine*, const v8::Local *args, int index){ - return args[index]->IntegerValue(); +Value::Int64 Function::Parameters::extractValue(Engine *engine, const v8::Local *args, int index){ + return args[index]->IntegerValue(engine->currentContext()->asLocal()).ToChecked(); } template<> -double Function::Parameters::extractValue(Engine*, const v8::Local *args, int index){ - return args[index]->NumberValue(); +double Function::Parameters::extractValue(Engine *engine, const v8::Local *args, int index){ + return args[index]->NumberValue(engine->currentContext()->asLocal()).ToChecked(); } template<> std::string Function::Parameters::extractValue(Engine *engine, const v8::Local *args, int index){ - return *v8::String::Utf8Value(args[index]->ToString(engine->isolate())); + return *v8::String::Utf8Value(engine->isolate(), args[index]->ToString(engine->currentContext()->asLocal()).ToLocalChecked()); } template<> diff --git a/lib/lvelements/src/imports.cpp b/lib/lvelements/src/imports.cpp index 8f2e7701..1014c93b 100644 --- a/lib/lvelements/src/imports.cpp +++ b/lib/lvelements/src/imports.cpp @@ -2,6 +2,7 @@ #include "element_p.h" #include "modulefile.h" #include "live/elements/value.h" +#include "context_p.h" namespace lv{ namespace el{ @@ -9,7 +10,8 @@ Imports::Imports(Engine *engine, ModuleFile *mf) : m_engine(engine) , m_moduleFile(mf) { - v8::Local obj = engine->importsTemplate()->InstanceTemplate()->NewInstance(); + v8::Local obj = + engine->importsTemplate()->InstanceTemplate()->NewInstance(engine->currentContext()->asLocal()).ToLocalChecked(); obj->SetInternalField(0, v8::External::New(engine->isolate(), this)); m_object.Reset(engine->isolate(), obj); @@ -55,12 +57,13 @@ v8::Local Imports::get(const std::string &key){ mf = currentPluginExportSearch->second; } - v8::Local v8key = v8::String::NewFromUtf8(m_engine->isolate(), key.c_str()); + v8::Local v8key = v8::String::NewFromUtf8(m_engine->isolate(), key.c_str()).ToLocalChecked(); for ( auto it = m_libraryExports.begin(); it != m_libraryExports.end(); ++it ){ v8::Local vo = it->data(); - if ( vo->Has(v8key) ){ - return vo->Get(v8key); + auto context = m_engine->currentContext()->asLocal(); + if ( vo->Has(context, v8key).ToChecked() ){ + return vo->Get(context, v8key).ToLocalChecked(); } } @@ -86,14 +89,14 @@ void Imports::get(const v8::FunctionCallbackInfo &info){ if ( info.Length() != 1 ){ info.GetIsolate()->ThrowException(v8::String::NewFromUtf8( - info.GetIsolate(), "\'imports.get()\' needs one argument.") + info.GetIsolate(), "\'imports.get()\' needs one argument.").ToLocalChecked() ); return; } try{ - v8::Local arg = info[0]->ToString(info.GetIsolate()); - v8::Local val = imports->get(*v8::String::Utf8Value(arg)); + v8::Local arg = info[0]->ToString(info.GetIsolate()->GetCurrentContext()).ToLocalChecked(); + v8::Local val = imports->get(*v8::String::Utf8Value(info.GetIsolate(), arg)); info.GetReturnValue().Set(val); } catch ( lv::Exception& e ){ engine->throwError(&e, nullptr); @@ -107,13 +110,13 @@ void Imports::require(const v8::FunctionCallbackInfo &info){ Engine* engine = reinterpret_cast(info.GetIsolate()->GetData(0)); if ( info.Length() != 1 ){ info.GetIsolate()->ThrowException(v8::String::NewFromUtf8( - info.GetIsolate(), "\'imports.require()\' needs one argument.") + info.GetIsolate(), "\'imports.require()\' needs one argument.").ToLocalChecked() ); return; } try{ - v8::Local arg = info[0]->ToString(info.GetIsolate()); - imports->require(*v8::String::Utf8Value(arg)); + v8::Local arg = info[0]->ToString(info.GetIsolate()->GetCurrentContext()).ToLocalChecked(); + imports->require(*v8::String::Utf8Value(info.GetIsolate(), arg)); } catch ( lv::Exception& e ){ engine->throwError(&e, nullptr); } @@ -125,12 +128,12 @@ void Imports::requireAs(const v8::FunctionCallbackInfo &info){ Imports* imports = reinterpret_cast(wrap->Value()); Engine* engine = reinterpret_cast(info.GetIsolate()->GetData(0)); if ( info.Length() != 1 ){ - info.GetIsolate()->ThrowException(v8::String::NewFromUtf8(info.GetIsolate(), "\'imports.requireAs()\' needs one argument.")); + info.GetIsolate()->ThrowException(v8::String::NewFromUtf8(info.GetIsolate(), "\'imports.requireAs()\' needs one argument.").ToLocalChecked()); return; } try{ - v8::Local arg = info[0]->ToString(info.GetIsolate()); - v8::Local obj = imports->requireAs(*v8::String::Utf8Value(arg)); + v8::Local arg = info[0]->ToString(info.GetIsolate()->GetCurrentContext()).ToLocalChecked(); + v8::Local obj = imports->requireAs(*v8::String::Utf8Value(info.GetIsolate(), arg)); info.GetReturnValue().Set(obj); } catch ( lv::Exception& e ){ engine->throwError(&e, nullptr); @@ -144,13 +147,13 @@ void Imports::getImport(v8::Local name, const v8::PropertyCallbackInfo if ( !name->IsString() ){ info.GetIsolate()->ThrowException(v8::String::NewFromUtf8( - info.GetIsolate(), "imports object accessor must be a string.") + info.GetIsolate(), "imports object accessor must be a string.").ToLocalChecked() ); return; } - v8::Local nameString = name->ToString(); - std::string n = *v8::String::Utf8Value(nameString); + v8::Local nameString = name->ToString(info.GetIsolate()->GetCurrentContext()).ToLocalChecked(); + std::string n = *v8::String::Utf8Value(info.GetIsolate(), nameString); if ( n == "require" || n == "requireAs" || n == "get" ){ return; @@ -166,13 +169,13 @@ void Imports::getImport(v8::Local name, const v8::PropertyCallbackInfo v8::Local Imports::functionTemplate(v8::Isolate *isolate){ v8::Local localTpl; localTpl = v8::FunctionTemplate::New(isolate); - localTpl->SetClassName(v8::String::NewFromUtf8(isolate, "Imports")); + localTpl->SetClassName(v8::String::NewFromUtf8(isolate, "Imports").ToLocalChecked()); v8::Local tplPrototype = localTpl->PrototypeTemplate(); - tplPrototype->Set(v8::String::NewFromUtf8(isolate, "get"), v8::FunctionTemplate::New(isolate, &Imports::get)); - tplPrototype->Set(v8::String::NewFromUtf8(isolate, "require"), v8::FunctionTemplate::New(isolate, &Imports::require)); - tplPrototype->Set(v8::String::NewFromUtf8(isolate, "requireAs"), v8::FunctionTemplate::New(isolate, &Imports::requireAs)); + tplPrototype->Set(isolate, "get", v8::FunctionTemplate::New(isolate, &Imports::get)); + tplPrototype->Set(isolate, "require", v8::FunctionTemplate::New(isolate, &Imports::require)); + tplPrototype->Set(isolate, "requireAs", v8::FunctionTemplate::New(isolate, &Imports::requireAs)); v8::Local tplInstance = localTpl->InstanceTemplate(); tplInstance->SetInternalFieldCount(1); diff --git a/lib/lvelements/src/languagenodes.cpp b/lib/lvelements/src/languagenodes.cpp index b57d36cd..44ec5511 100644 --- a/lib/lvelements/src/languagenodes.cpp +++ b/lib/lvelements/src/languagenodes.cpp @@ -110,6 +110,11 @@ void BaseNode::moveToDeclarations(BaseNode *parent, IdentifierNode *idNode) if (jsbn) { jsbn->m_declarations.push_back(idNode); + + if (jsbn->typeString() == "StatementBlock"){ + auto sb = dynamic_cast(jsbn); + sb->m_localVariables.push_back(idNode); + } break; } p = p->parent(); @@ -203,6 +208,8 @@ void BaseNode::visit(BaseNode *parent, const TSNode &node){ visitNewExpression(parent, node); } else if ( strcmp(ts_node_type(node), "return_statement") == 0 ){ visitReturnStatement(parent, node); + } else if ( strcmp(ts_node_type(node), "object") == 0 ){ + visitObject(parent, node); } else if ( strcmp(ts_node_type(node), "ERROR") == 0 ){ SyntaxException se = CREATE_EXCEPTION(SyntaxException, "Syntax error has happened", Exception::toCode("~LanguageNodes")); BaseNode* p = parent; @@ -812,8 +819,6 @@ void BaseNode::visitVariableDeclaration(BaseNode *parent, const TSNode &node) decl->setParent(vdn); vdn->m_declarators.push_back(decl); - - uint32_t subcount = ts_node_child_count(child); for ( uint32_t k = 0; k < subcount; ++k ){ @@ -823,8 +828,12 @@ void BaseNode::visitVariableDeclaration(BaseNode *parent, const TSNode &node) IdentifierNode* id = new IdentifierNode(smaller_child); decl->insert(id); moveToDeclarations(decl, id); + } else if ( strcmp(ts_node_type(smaller_child), "new_component_expression") == 0 ){ + visitNewComponentExpression(decl, smaller_child); } } + } else if ( strcmp(ts_node_type(child), ";") == 0 ) { + vdn->m_hasSemicolon = true; } else { visit(vdn, child); } @@ -853,6 +862,13 @@ void BaseNode::visitArrowFunction(BaseNode *parent, const TSNode &node) visitChildren(afnode, node); } +void BaseNode::visitObject(BaseNode *parent, const TSNode &node) +{ + ObjectNode* onode = new ObjectNode(node); + parent->insert(onode); + visitChildren(onode, node); +} + std::string ImportNode::toString(int indent) const{ std::string result; if ( indent > 0 ) @@ -1189,12 +1205,30 @@ void ComponentDeclarationNode::convertToJs(const std::string &source, std::vecto for (int i=0; ihasBindings()) { - *compose << indent(indentValue + 1) << "Element.assignPropertyExpression(this,\n '" - << slice(source, m_properties[i]->name()) - << "',\n function(){ return " << slice(source, m_properties[i]->expression()) << "}.bind(this),\n" - << "[\n"; + numOfBindings = m_properties[i]->bindings().size(); + std::string comp = indent(indentValue + 1) + "Element.assignPropertyExpression(this,\n '" + + slice(source, m_properties[i]->name()) + "',\n"; + if (m_properties[i]->expression()){ + comp += "function(){ return " + slice(source, m_properties[i]->expression()) + "}.bind(this),\n"; + } else if (m_properties[i]->statementBlock()){ + auto block = m_properties[i]->statementBlock(); + comp += "(function()\n" ; + el::JSSection* section = new el::JSSection; + section->from = block->startByte(); + section->to = block->endByte(); + block->convertToJs(source, section->m_children); + + std::vector flat; + section->flatten(source, flat); + for (auto s: flat) comp += s; + delete section; + comp += "\n)(),\n"; + } + comp += "[\n"; + std::set> bindingPairs; for (auto idx = m_properties[i]->bindings().begin(); idx != m_properties[i]->bindings().end(); ++idx) { @@ -1202,31 +1236,58 @@ void ComponentDeclarationNode::convertToJs(const std::string &source, std::vecto if (node->typeString() == "MemberExpression") { MemberExpressionNode* men = node->as(); + bool skip = false; - std::pair pair = std::make_pair( - slice(source, men->children()[0]), - slice(source, men->children()[1]) - ); - if (bindingPairs.find(pair) == bindingPairs.end()) - { - if (!bindingPairs.empty()) *compose << ",\n"; - *compose << "[ " << pair.first << ", '" << pair.second << "Changed' ]"; - bindingPairs.insert(pair); + auto sb = men->parent(); + while (sb && sb->typeString() != "StatementBlock"){ + sb = sb->parent(); } - BaseNode* left = men->children()[0]; - while (left->typeString() != "Identifier") - left = left->children()[0]; + if (sb){ + auto sbc = dynamic_cast(sb); + auto localVars = sbc->m_localVariables; + if (men->children()[0]->typeString() == "Identifier"){ + auto ident = dynamic_cast(men->children()[0]); + auto ids = slice(source, ident->startByte(), ident->endByte()); + for (auto ch: localVars){ + auto localVar = slice(source, ch->startByte(), ch->endByte()); + + if (localVar == ids){ + --numOfBindings; + skip = true; + break; + } + } + } + } + + if (!skip){ + std::pair pair = std::make_pair( + slice(source, men->children()[0]), + slice(source, men->children()[1]) + ); + + if (bindingPairs.find(pair) == bindingPairs.end()) + { + if (!bindingPairs.empty()) comp += ",\n"; + comp += "[ " + pair.first + ", '" + pair.second + "Changed' ]"; + bindingPairs.insert(pair); + } - checkIdentifierDeclared(source, left, slice(source, left)); + BaseNode* left = men->children()[0]; + while (left->typeString() != "Identifier") + left = left->children()[0]; + checkIdentifierDeclared(source, left, slice(source, left)); + } } } - *compose << "]\n)\n"; + comp += "]\n)\n"; + if (numOfBindings > 0) + *compose << comp; } - else - { + if (numOfBindings == 0){ *compose << "this." << slice(source,m_properties[i]->name()) << " = "; if (m_properties[i]->expression() && m_properties[i]->expression()->children().size() == 1 @@ -1260,33 +1321,105 @@ void ComponentDeclarationNode::convertToJs(const std::string &source, std::vecto } else if (m_properties[i]->statementBlock()) { - *compose << "(function()" << slice(source, m_properties[i]->statementBlock())<< "())\n\n"; + auto block = m_properties[i]->statementBlock(); + *compose << "(function()\n" ; + el::JSSection* section = new el::JSSection; + section->from = block->startByte(); + section->to = block->endByte(); + block->convertToJs(source, section->m_children); + std::vector flat; + section->flatten(source, flat); + for (auto s: flat) *compose << s; + delete section; + *compose << "\n)()\n\n"; + } - std::queue q; - q.push(m_properties[i]->statementBlock()); - while (!q.empty()) + *compose << "\n\n"; + } + } + + for (unsigned i=0; im_bindings.size() > 0) + { + if (m_assignments[i]->m_expression) + { + auto& property = m_assignments[i]->m_property; + std::string object = "this"; + for (int x = 0; xm_expression) << "}.bind(" << object << "),\n" + << "[\n"; + std::set> bindingPairs; + for (auto idx = m_assignments[i]->m_bindings.begin(); idx != m_assignments[i]->m_bindings.end(); ++idx) { - BaseNode* b = q.front(); q.pop(); - if (b->typeString() == "NewExpression" /*|| other stuff*/) + BaseNode* node = *idx; + if (node->typeString() == "MemberExpression") { - for (auto child: b->children()) - { - if (child->typeString() == "Identifier") - checkIdentifierDeclared(source, child, slice(source, child)); - } - } else { - for (auto child: b->children()) + MemberExpressionNode* men = node->as(); + + std::pair pair = std::make_pair( + slice(source, men->children()[0]), + slice(source, men->children()[1]) + ); + + if (bindingPairs.find(pair) == bindingPairs.end()) { - q.push(child); + if (!bindingPairs.empty()) *compose << ",\n"; + *compose << "[ " << pair.first << ", '" << pair.second << "Changed' ]"; + bindingPairs.insert(pair); } + } } + *compose << "]\n)\n"; } + } + else { + if (m_assignments[i]->m_expression && !m_assignments[i]->m_property.empty()) + { - *compose << "\n\n"; + *compose << "this"; + + for (int prop=0; propm_property.size(); ++prop) + { + *compose << "." << slice(source, m_assignments[i]->m_property[prop]); + } + + auto exp = m_assignments[i]->m_expression; + std::string comp = "" ; + el::JSSection* section = new el::JSSection; + section->from = exp->startByte(); + section->to = exp->endByte(); + exp->convertToJs(source, section->m_children); + std::vector flat; + section->flatten(source, flat); + for (auto s: flat) { + comp += s; + } + delete section; + + *compose << " = " << comp << "\n"; //slice(source, m_assignments[i]->m_expression) << "\n\n"; + } + else if (m_assignments[i]->m_statementBlock) { + std::string propName = "this"; + + for (int prop=0; propm_property.size(); ++prop) + { + propName += "." + slice(source, m_assignments[i]->m_property[prop]); + } + *compose << propName << " = " + << "(function()" << slice(source, m_assignments[i]->m_statementBlock) << "())\n\n"; + } } + } + if (!m_default.empty()) { *compose << "Element.assignDefaultProperty(this, [\n"; @@ -1396,14 +1529,17 @@ void NewComponentExpressionNode::convertToJs(const std::string &source, std::vec for (int i=0; ihasBindings()) { + std::string comp = ""; + numOfBindings = m_properties[i]->bindings().size(); if (m_properties[i]->expression()) { - *compose << "Element.assignPropertyExpression(this,\n '" - << slice(source, m_properties[i]->name()) - << "',\n function(){ return " << slice(source, m_properties[i]->expression()) << "}.bind(this),\n" - << "[\n"; + comp += "Element.assignPropertyExpression(this,\n '" + + slice(source, m_properties[i]->name()) + + "',\n function(){ return " + slice(source, m_properties[i]->expression()) + "}.bind(this),\n" + + "[\n"; std::set> bindingPairs; for (auto idx = m_properties[i]->bindings().begin(); idx != m_properties[i]->bindings().end(); ++idx) { @@ -1419,19 +1555,27 @@ void NewComponentExpressionNode::convertToJs(const std::string &source, std::vec if (bindingPairs.find(pair) == bindingPairs.end()) { - if (!bindingPairs.empty()) *compose << ",\n"; - *compose << "[ " << pair.first << ", '" << pair.second << "Changed' ]"; + if (!bindingPairs.empty()) comp += ",\n"; + comp += "[ " + pair.first + ", '" + pair.second + "Changed' ]"; bindingPairs.insert(pair); } } } - *compose << "]\n)\n"; + comp += "]\n)\n"; } else { - *compose << "Element.assignPropertyExpression(this,\n '" - << slice(source, m_properties[i]->name()) - << "',\n function()" << slice(source, m_properties[i]->statementBlock()) << ".bind(this),\n" - << "[\n"; + comp += "Element.assignPropertyExpression(this,\n '" + + slice(source, m_properties[i]->name()) + "',\n function()"; + el::JSSection* section = new el::JSSection; + auto block = m_properties[i]->statementBlock(); + section->from = block->startByte(); + section->to = block->endByte(); + block->convertToJs(source, section->m_children); + std::vector flat; + section->flatten(source, flat); + for (auto s: flat) comp += s; + delete section; + comp += ".bind(this),\n[\n"; std::set> bindingPairs; for (auto idx = m_properties[i]->bindings().begin(); idx != m_properties[i]->bindings().end(); ++idx) { @@ -1440,34 +1584,89 @@ void NewComponentExpressionNode::convertToJs(const std::string &source, std::vec { MemberExpressionNode* men = node->as(); - std::pair pair = std::make_pair( - slice(source, men->children()[0]), - slice(source, men->children()[1]) - ); + bool skip = false; - if (bindingPairs.find(pair) == bindingPairs.end()) - { - if (!bindingPairs.empty()) *compose << ",\n"; - *compose << "[ " << pair.first << ", '" << pair.second << "Changed' ]"; - bindingPairs.insert(pair); + auto sb = men->parent(); + while (sb && sb->typeString() != "StatementBlock"){ + sb = sb->parent(); + } + + if (sb){ + auto sbc = dynamic_cast(sb); + auto localVars = sbc->m_localVariables; + if (men->children()[0]->typeString() == "Identifier"){ + auto ident = dynamic_cast(men->children()[0]); + auto ids = slice(source, ident->startByte(), ident->endByte()); + for (auto ch: localVars){ + auto localVar = slice(source, ch->startByte(), ch->endByte()); + + if (localVar == ids){ + --numOfBindings; + skip = true; + break; + } + } + } + } + + if (!skip){ + std::pair pair = std::make_pair( + slice(source, men->children()[0]), + slice(source, men->children()[1]) + ); + + if (bindingPairs.find(pair) == bindingPairs.end()) + { + if (!bindingPairs.empty()) comp += ",\n"; + comp += "[ " + pair.first + ", '" + pair.second + "Changed' ]"; + bindingPairs.insert(pair); + } + + BaseNode* left = men->children()[0]; + while (left->typeString() != "Identifier") + left = left->children()[0]; + + checkIdentifierDeclared(source, left, slice(source, left)); } } } - *compose << "]\n)\n"; + comp += "]\n)\n"; } + if (numOfBindings > 0) + *compose << comp; } - else - { + if (numOfBindings == 0){ if (m_properties[i]->expression()) { - *compose << "this." << slice(source,m_properties[i]->name()) - << " = " << slice(source, m_properties[i]->expression()) << "\n"; + auto expr = m_properties[i]->expression(); + *compose << "this." << slice(source,m_properties[i]->name()) << " = "; + + // convert the subexpression + JSSection* expressionSection = new JSSection; + expressionSection->from = expr->startByte(); + expressionSection->to = expr->endByte(); + expr->convertToJs(source, expressionSection->m_children); + std::vector flat; + expressionSection->flatten(source, flat); + for (auto s: flat) *compose << s; + + *compose << "\n"; } else if (m_properties[i]->statementBlock()) { - *compose << "this." << slice(source,m_properties[i]->name()) << " = " - << "(function()" << slice(source, m_properties[i]->statementBlock()) << "())\n\n"; + *compose << "this." << slice(source,m_properties[i]->name()) << " = " << "(function()"; + el::JSSection* section = new el::JSSection; + auto block = m_properties[i]->statementBlock(); + section->from = block->startByte(); + section->to = block->endByte(); + block->convertToJs(source, section->m_children); + std::vector flat; + section->flatten(source, flat); + for (auto s: flat) *compose << s; + delete section; + + *compose << "())\n\n"; } } } @@ -1576,7 +1775,7 @@ void NewComponentExpressionNode::convertToJs(const std::string &source, std::vec } } - *compose << ("Element.addEvent(__current, \'" + slice(source, edn->name()) + "\', [" + paramList + "])\n"); + *compose << ("Element.addEvent(this, \'" + slice(source, edn->name()) + "\', [" + paramList + "])\n"); } else if ( c->typeString() == "ListenerDeclaration" ){ ListenerDeclarationNode* ldn = c->as(); @@ -1589,12 +1788,17 @@ void NewComponentExpressionNode::convertToJs(const std::string &source, std::vec paramList += slice(source, pit->second); } } + + *compose << "this.on(\'" << slice(source, ldn->name()) << "\', function(" << paramList << ")"; JSSection* jssection = new JSSection; jssection->from = ldn->body()->startByte(); jssection->to = ldn->body()->endByte(); - *compose << "__current.on(\'" << slice(source, ldn->name()) << "\', function(" << paramList << ")" << jssection << "\n"; + ldn->convertToJs(source, jssection->m_children); + std::vector flat; + jssection->flatten(source, flat); + for (auto s: flat) *compose << s; + *compose << ".bind(this));\n"; - ldn->body()->convertToJs(source, jssection->m_children); } else if ( c->typeString() == "MethodDefinition"){ MethodDefinitionNode* mdn = c->as(); @@ -1618,7 +1822,7 @@ void NewComponentExpressionNode::convertToJs(const std::string &source, std::vec JSSection* jssection = new JSSection; jssection->from = tfdn->body()->startByte(); jssection->to = tfdn->body()->endByte(); - *compose << "__current." << slice(source, tfdn->name()) << " = function(" << paramList << ")" << jssection << "\n"; + *compose << "this." << slice(source, tfdn->name()) << " = function(" << paramList << ")" << jssection << "\n"; tfdn->body()->convertToJs(source, jssection->m_children); } @@ -2002,9 +2206,7 @@ std::string ArgumentsNode::toString(int indent) const void ArgumentsNode::convertToJs(const std::string &source, std::vector &fragments, int indent) { - ElementsInsertion* compose = new ElementsInsertion; - compose->from = startByte(); - compose->to = endByte(); + BaseNode::convertToJs(source, fragments, indent + 1); for (auto child: children()) { @@ -2014,9 +2216,6 @@ void ArgumentsNode::convertToJs(const std::string &source, std::vector &fragments, int indent) +{ + ElementsInsertion* compose = new ElementsInsertion; + compose->from = startByte(); + compose->to = endByte(); + + for (auto decl: m_declarators){ + auto children = decl->children(); + if (children.size() != 2){ + *compose << "\nvar " << slice(source, decl->startByte(), decl->endByte()); + continue; + } + + if (children[0]->typeString() == "Identifier" && children[1]->typeString() == "NewComponentExpression"){ + *compose << "\nvar " << slice(source, children[0]->startByte(), children[0]->endByte()) << " = "; + + el::JSSection* section = new el::JSSection; + section->from = children[1]->startByte(); + section->to = children[1]->endByte(); + children[1]->convertToJs(source, section->m_children); + std::vector flat; + section->flatten(source, flat); + for (auto s: flat) *compose << s; + delete section; + + } else { + *compose << slice(source, decl->startByte(), decl->endByte()); + } + + } + *compose << (m_hasSemicolon ? "; ": "\n"); + + fragments.push_back(compose); +} + }} // namespace lv, el diff --git a/lib/lvelements/src/languagenodes_p.h b/lib/lvelements/src/languagenodes_p.h index b7992f4c..e57c4fd4 100644 --- a/lib/lvelements/src/languagenodes_p.h +++ b/lib/lvelements/src/languagenodes_p.h @@ -33,6 +33,7 @@ class MemberExpressionNode; class SubscriptExpressionNode; class StatementBlockNode; class ArgumentsNode; +class ObjectNode; class BaseNode{ friend class JsBlockNode; @@ -101,6 +102,7 @@ class BaseNode{ static void visitNewExpression(BaseNode* parent, const TSNode& node); static void visitReturnStatement(BaseNode* parent, const TSNode& node); static void visitArrowFunction(BaseNode* parent, const TSNode& node); + static void visitObject(BaseNode* parent, const TSNode& node); BaseNode* m_parent; TSNode m_node; @@ -114,10 +116,10 @@ class NumberNode: public BaseNode { NumberNode(const TSNode& node, const std::string& typeString = "Number") : BaseNode(node, typeString){} }; -class ArrowFunctionNode: public BaseNode { +class ObjectNode: public BaseNode { friend class BaseNode; public: - ArrowFunctionNode(const TSNode& node, const std::string& typeString = "ArrowFunction") : BaseNode(node, typeString){} + ObjectNode(const TSNode& node, const std::string& typeString = "Object") : BaseNode(node, typeString){} }; class FunctionDeclarationNode: public BaseNode { @@ -147,6 +149,12 @@ class JsBlockNode : public BaseNode{ std::vector m_declarations; }; +class ArrowFunctionNode: public JsBlockNode { + friend class BaseNode; +public: + ArrowFunctionNode(const TSNode& node, const std::string& typeString = "ArrowFunction") : JsBlockNode(node, typeString){} +}; + class ProgramNode : public JsBlockNode { friend class BaseNode; public: @@ -184,10 +192,13 @@ class VariableDeclaratorNode : public BaseNode{ class VariableDeclarationNode : public BaseNode{ friend class BaseNode; public: - VariableDeclarationNode(const TSNode& node) : BaseNode(node, "VariableDeclaration"){} + VariableDeclarationNode(const TSNode& node) : BaseNode(node, "VariableDeclaration"), m_hasSemicolon(false){} virtual std::string toString(int indent = 0) const; + virtual void convertToJs(const std::string& source, std::vector& fragments, int indent = 0); + private: std::vector m_declarators; + bool m_hasSemicolon; }; @@ -317,6 +328,7 @@ class ClassDeclarationNode : public BaseNode{ class PropertyAssignmentNode : public JsBlockNode{ friend class BaseNode; + friend class ComponentDeclarationNode; public: PropertyAssignmentNode(const TSNode& node); virtual std::string toString(int indent = 0) const; @@ -421,9 +433,10 @@ class BindableExpressionNode : public BaseNode{ BindableExpressionNode(const TSNode& node) : BaseNode(node, "BindableExpression"){} }; -class StatementBlockNode : public BaseNode{ +class StatementBlockNode : public JsBlockNode{ public: - StatementBlockNode(const TSNode& node) : BaseNode(node, "StatementBlock"){} + StatementBlockNode(const TSNode& node) : JsBlockNode(node, "StatementBlock"){} + std::vector m_localVariables; }; class MemberExpressionNode : public BaseNode{ diff --git a/lib/lvelements/src/mlnodetojs.cpp b/lib/lvelements/src/mlnodetojs.cpp index e9748f69..193db0ee 100644 --- a/lib/lvelements/src/mlnodetojs.cpp +++ b/lib/lvelements/src/mlnodetojs.cpp @@ -13,7 +13,11 @@ void toJs(const MLNode &n, v8::Local& v, el::Engine *engine){ for ( auto it = n.begin(); it != n.end(); ++it ){ v8::Local result; toJs(it.value(), result, engine); - lo->Set(v8::String::NewFromUtf8(engine->isolate(), it.key().c_str()), result); + lo->Set( + engine->isolate()->GetCurrentContext(), + v8::String::NewFromUtf8(engine->isolate(), it.key().c_str()).ToLocalChecked(), + result + ).IsNothing(); } v = lo; break; @@ -25,7 +29,7 @@ void toJs(const MLNode &n, v8::Local& v, el::Engine *engine){ for ( auto it = n.begin(); it != n.end(); ++it ){ v8::Local result; toJs(it.value(), result, engine); - la->Set(index, result); + la->Set(engine->isolate()->GetCurrentContext(), index, result).IsNothing(); ++index; } v = la; @@ -36,7 +40,7 @@ void toJs(const MLNode &n, v8::Local& v, el::Engine *engine){ break; } case MLNode::Type::String:{ - v = v8::String::NewFromUtf8(engine->isolate(), n.asString().c_str()); + v = v8::String::NewFromUtf8(engine->isolate(), n.asString().c_str()).ToLocalChecked(); break; } case MLNode::Type::Boolean:{ @@ -58,27 +62,29 @@ void toJs(const MLNode &n, v8::Local& v, el::Engine *engine){ } void fromJs(const v8::Local v, MLNode& n, el::Engine* engine){ + auto isolate = engine->isolate(); + auto context = isolate->GetCurrentContext(); if ( v->IsArray() ){ v8::Local va = v8::Local::Cast(v); n = MLNode(MLNode::Type::Array); for ( unsigned int i = 0; i < va->Length(); ++i ){ MLNode result; - fromJs(va->Get(i), result, engine); + fromJs(va->Get(context, i).ToLocalChecked(), result, engine); n.append(result); } } else if ( v->IsString() || v->IsStringObject() ){ - n = MLNode(*v8::String::Utf8Value(v->ToString(engine->isolate()))); + n = MLNode(*v8::String::Utf8Value(isolate, v->ToString(context).ToLocalChecked())); } else if ( v->IsObject() ){ v8::Local vo = v8::Local::Cast(v); n = MLNode(MLNode::Type::Object); - v8::Local pn = vo->GetOwnPropertyNames(); + v8::Local pn = vo->GetOwnPropertyNames(context, v8::ALL_PROPERTIES).ToLocalChecked(); for (uint32_t i = 0; i < pn->Length(); ++i) { - v8::Local key = pn->Get(i); - v8::Local value = vo->Get(key); + v8::Local key = pn->Get(context, i).ToLocalChecked(); + v8::Local value = vo->Get(context, key).ToLocalChecked(); - v8::String::Utf8Value utf8Key(key); + v8::String::Utf8Value utf8Key(isolate, key); MLNode result; fromJs(value, result, engine); @@ -87,11 +93,11 @@ void fromJs(const v8::Local v, MLNode& n, el::Engine* engine){ } } else if ( v->IsBoolean() ){ - n = MLNode(v->BooleanValue()); + n = MLNode(v->BooleanValue(isolate)); } else if ( v->IsInt32() ){ - n = MLNode(v->IntegerValue()); + n = MLNode(v->IntegerValue(context).ToChecked()); } else if ( v->IsNumber() ){ - n = MLNode(v->NumberValue()); + n = MLNode(v->NumberValue(context).ToChecked()); } else { n = MLNode(); } diff --git a/lib/lvelements/src/modulefile.cpp b/lib/lvelements/src/modulefile.cpp index cce84234..5870fee8 100644 --- a/lib/lvelements/src/modulefile.cpp +++ b/lib/lvelements/src/modulefile.cpp @@ -140,18 +140,20 @@ ScopedValue ModuleFile::createObject(Engine* engine) const{ v8::Local obj = v8::Object::New(engine->isolate()); v8::Local exports = ScopedValue(engine, *m_d->exports).data(); + auto isolate = engine->isolate(); + auto context = isolate->GetCurrentContext(); v8::Local exportsKey = v8::String::NewFromUtf8( - engine->isolate(), "exports", v8::String::kInternalizedString - ); + engine->isolate(), "exports", v8::NewStringType::kInternalized + ).ToLocalChecked(); v8::Local pathKey = v8::String::NewFromUtf8( - engine->isolate(), "path", v8::String::kInternalizedString - ); + engine->isolate(), "path", v8::NewStringType::kInternalized + ).ToLocalChecked(); v8::Local pathStr = v8::String::NewFromUtf8( - engine->isolate(), filePath().c_str(), v8::String::kInternalizedString - ); + engine->isolate(), filePath().c_str(), v8::NewStringType::kInternalized + ).ToLocalChecked(); - obj->Set(exportsKey, exports); - obj->Set(pathKey, pathStr); + obj->Set(context, exportsKey, exports).IsNothing(); + obj->Set(context, pathKey, pathStr).IsNothing(); return ScopedValue(obj); } diff --git a/lib/lvelements/src/object.cpp b/lib/lvelements/src/object.cpp index 074316b6..bb5e5c77 100644 --- a/lib/lvelements/src/object.cpp +++ b/lib/lvelements/src/object.cpp @@ -40,7 +40,12 @@ Object::Object(Engine* engine, const v8::Local &data) : m_d(nullptr) , m_ref(nullptr) { - v8::Local shared = data->Get(v8::String::NewFromUtf8(engine->isolate(), "__shared__")); + auto isolate = engine->isolate(); + auto context = isolate->GetCurrentContext(); + v8::Local shared = data->Get( + context, + v8::String::NewFromUtf8(engine->isolate(), "__shared__").ToLocalChecked() + ).ToLocalChecked(); if ( shared->IsExternal() ){ m_d = reinterpret_cast(v8::Local::Cast(shared)->Value()); @@ -51,7 +56,7 @@ Object::Object(Engine* engine, const v8::Local &data) m_d->ref = m_ref; v8::Maybe result = data->DefineOwnProperty( engine->currentContext()->asLocal(), - v8::String::NewFromUtf8(engine->isolate(), "__shared__"), + v8::String::NewFromUtf8(engine->isolate(), "__shared__").ToLocalChecked(), v8::External::New(engine->isolate(), m_d), v8::DontEnum ); @@ -69,11 +74,17 @@ Object::Object(Engine* engine, const v8::Local &data) } Object::~Object(){ + auto isolate = m_d->engine->isolate(); + auto context = isolate->GetCurrentContext(); --(*m_ref); if ( *m_ref == 0 ){ if ( !m_d->data.IsEmpty() ){ v8::Local v = m_d->data.Get(m_d->engine->isolate()); - v->Set(v8::String::NewFromUtf8(m_d->engine->isolate(), "__shared__"), v8::Undefined(m_d->engine->isolate())); + v->Set( + context, + v8::String::NewFromUtf8(m_d->engine->isolate(), "__shared__").ToLocalChecked(), + v8::Undefined(m_d->engine->isolate()) + ).IsNothing(); m_d->data.SetWeak(); } @@ -94,8 +105,10 @@ std::string Object::toString() const{ if ( m_d->data.IsEmpty() ) return std::string(); - v8::Local s = m_d->data.Get(m_d->engine->isolate()); - return *v8::String::Utf8Value(s->ToString(m_d->engine->isolate())); + auto isolate = m_d->engine->isolate(); + auto context = isolate->GetCurrentContext(); + v8::Local s = m_d->data.Get(isolate); + return *v8::String::Utf8Value(isolate, s->ToString(context).ToLocalChecked()); } Buffer Object::toBuffer() const{ @@ -159,15 +172,24 @@ bool Object::isPoint() const{ } void Object::toPoint(double &x, double &y) const{ - v8::Local lo = m_d->data.Get(m_d->engine->isolate()); + + auto isolate = m_d->engine->isolate(); + auto context = isolate->GetCurrentContext(); + v8::Local lo = m_d->data.Get(isolate); if ( !isPoint() ){ lv::Exception e = CREATE_EXCEPTION(lv::Exception, "Object is not of Point type.", 1); m_d->engine->throwError(&e, nullptr); return; } - x = lo->Get(v8::String::NewFromUtf8(m_d->engine->isolate(), "x", v8::String::kInternalizedString))->NumberValue(); - y = lo->Get(v8::String::NewFromUtf8(m_d->engine->isolate(), "y", v8::String::kInternalizedString))->NumberValue(); + x = lo->Get( + context, + v8::String::NewFromUtf8(isolate, "x", v8::NewStringType::kInternalized).ToLocalChecked() + ).ToLocalChecked()->NumberValue(context).ToChecked(); + y = lo->Get( + context, + v8::String::NewFromUtf8(isolate, "y", v8::NewStringType::kInternalized).ToLocalChecked() + ).ToLocalChecked()->NumberValue(context).ToChecked(); } bool Object::isSize() const{ @@ -177,15 +199,24 @@ bool Object::isSize() const{ } void Object::toSize(double &width, double &height) const{ - v8::Local lo = m_d->data.Get(m_d->engine->isolate()); + + auto isolate = m_d->engine->isolate(); + auto context = isolate->GetCurrentContext(); + v8::Local lo = m_d->data.Get(isolate); if ( !isSize() ){ lv::Exception e = CREATE_EXCEPTION(lv::Exception, "Object is not of Size type.", 1); m_d->engine->throwError(&e, nullptr); return; } - width = lo->Get(v8::String::NewFromUtf8(m_d->engine->isolate(), "width", v8::String::kInternalizedString))->NumberValue(); - height = lo->Get(v8::String::NewFromUtf8(m_d->engine->isolate(), "height", v8::String::kInternalizedString))->NumberValue(); + width = lo->Get( + context, + v8::String::NewFromUtf8(isolate, "width", v8::NewStringType::kInternalized).ToLocalChecked() + ).ToLocalChecked()->NumberValue(context).ToChecked(); + height = lo->Get( + context, + v8::String::NewFromUtf8(isolate, "height", v8::NewStringType::kInternalized).ToLocalChecked() + ).ToLocalChecked()->NumberValue(context).ToChecked(); } bool Object::isRectangle() const{ @@ -195,6 +226,8 @@ bool Object::isRectangle() const{ } void Object::toRectangle(double &x, double &y, double &width, double &height){ + auto isolate = m_d->engine->isolate(); + auto context = isolate->GetCurrentContext(); v8::Local lo = m_d->data.Get(m_d->engine->isolate()); if ( !isRectangle() ){ lv::Exception e = CREATE_EXCEPTION(lv::Exception, "Object is not of Rectangle type.", 1); @@ -202,10 +235,22 @@ void Object::toRectangle(double &x, double &y, double &width, double &height){ return; } - x = lo->Get(v8::String::NewFromUtf8(m_d->engine->isolate(), "x", v8::String::kInternalizedString))->NumberValue(); - y = lo->Get(v8::String::NewFromUtf8(m_d->engine->isolate(), "y", v8::String::kInternalizedString))->NumberValue(); - width = lo->Get(v8::String::NewFromUtf8(m_d->engine->isolate(), "width", v8::String::kInternalizedString))->NumberValue(); - height = lo->Get(v8::String::NewFromUtf8(m_d->engine->isolate(), "height", v8::String::kInternalizedString))->NumberValue(); + x = lo->Get( + context, + v8::String::NewFromUtf8(isolate, "x", v8::NewStringType::kInternalized).ToLocalChecked() + ).ToLocalChecked()->NumberValue(context).ToChecked(); + y = lo->Get( + context, + v8::String::NewFromUtf8(isolate, "y", v8::NewStringType::kInternalized).ToLocalChecked() + ).ToLocalChecked()->NumberValue(context).ToChecked(); + width = lo->Get( + context, + v8::String::NewFromUtf8(isolate, "width", v8::NewStringType::kInternalized).ToLocalChecked() + ).ToLocalChecked()->NumberValue(context).ToChecked(); + height = lo->Get( + context, + v8::String::NewFromUtf8(isolate, "height", v8::NewStringType::kInternalized).ToLocalChecked() + ).ToLocalChecked()->NumberValue(context).ToChecked(); } bool Object::isDate() const{ @@ -254,28 +299,37 @@ Object::Accessor::~Accessor(){ delete m_d; } -ScopedValue Object::Accessor::get(int index){ - return ScopedValue(m_d->data->Get(static_cast(index))); +ScopedValue Object::Accessor::get(Engine* engine, int index){ + + return ScopedValue(m_d->data->Get(engine->isolate()->GetCurrentContext(), static_cast(index)).ToLocalChecked()); } -ScopedValue Object::Accessor::get(const ScopedValue &key){ - return m_d->data->Get(key.data()); +ScopedValue Object::Accessor::get(Engine* engine, const ScopedValue &key){ + return m_d->data->Get(engine->isolate()->GetCurrentContext(), key.data()).ToLocalChecked(); } ScopedValue Object::Accessor::get(Engine *engine, const std::string &str){ - return get(ScopedValue(engine, str)); + return get(engine, ScopedValue(engine, str)); } -void Object::Accessor::set(int index, const ScopedValue &value){ - m_d->data->Set(static_cast(index), value.data()); +void Object::Accessor::set(Engine* engine, int index, const ScopedValue &value){ + m_d->data->Set( + engine->isolate()->GetCurrentContext(), + static_cast(index), + value.data() + ).IsNothing(); } -void Object::Accessor::set(const ScopedValue &key, const ScopedValue &value){ - m_d->data->Set(key.data(), value.data()); +void Object::Accessor::set(Engine* engine, const ScopedValue &key, const ScopedValue &value){ + m_d->data->Set( + engine->isolate()->GetCurrentContext(), + key.data(), + value.data() + ).IsNothing(); } void Object::Accessor::set(Engine *engine, const std::string &key, const ScopedValue &value){ - set(ScopedValue(engine, key), value); + set(engine, ScopedValue(engine, key), value); } bool Object::Accessor::has(Engine* engine, const ScopedValue &key) const{ @@ -283,8 +337,8 @@ bool Object::Accessor::has(Engine* engine, const ScopedValue &key) const{ return result.IsJust() && result.ToChecked(); } -ScopedValue Object::Accessor::ownProperties() const{ - return ScopedValue(m_d->data->GetOwnPropertyNames()); +ScopedValue Object::Accessor::ownProperties(Engine *engine) const{ + return ScopedValue(m_d->data->GetOwnPropertyNames(engine->isolate()->GetCurrentContext(), v8::ALL_PROPERTIES).ToLocalChecked()); } @@ -316,12 +370,12 @@ int Object::ArrayAccessor::length() const{ return static_cast(m_d->data->Length()); } -ScopedValue Object::ArrayAccessor::get(int index){ - return m_d->data->Get(static_cast(index)); +ScopedValue Object::ArrayAccessor::get(Engine *engine, int index){ + return m_d->data->Get(engine->isolate()->GetCurrentContext(), static_cast(index)).ToLocalChecked(); } -void Object::ArrayAccessor::set(int index, const ScopedValue &value){ - m_d->data->Set(static_cast(index), value.data()); +void Object::ArrayAccessor::set(Engine* engine, int index, const ScopedValue &value){ + m_d->data->Set(engine->isolate()->GetCurrentContext(), static_cast(index), value.data()).IsNothing(); } diff --git a/lib/lvelements/src/object.h b/lib/lvelements/src/object.h index 0979c74b..a4c27602 100644 --- a/lib/lvelements/src/object.h +++ b/lib/lvelements/src/object.h @@ -44,16 +44,16 @@ class LV_ELEMENTS_EXPORT Object{ Accessor(Context* context); ~Accessor(); - ScopedValue get(int index); - ScopedValue get(const ScopedValue& key); + ScopedValue get(Engine* engine, int index); + ScopedValue get(Engine* engine, const ScopedValue& key); ScopedValue get(Engine* engine, const std::string& str); - void set(int index, const ScopedValue& value); - void set(const ScopedValue& key, const ScopedValue& value); + void set(Engine* engine, int index, const ScopedValue& value); + void set(Engine* engine, const ScopedValue& key, const ScopedValue& value); void set(Engine* engine, const std::string& key, const ScopedValue& value); bool has(Engine* engine, const ScopedValue& key) const; - ScopedValue ownProperties() const; + ScopedValue ownProperties(Engine *engine) const; private: DISABLE_COPY(Accessor); @@ -72,8 +72,8 @@ class LV_ELEMENTS_EXPORT Object{ int length() const; - ScopedValue get(int index); - void set(int index, const ScopedValue& value); + ScopedValue get(Engine *engine, int index); + void set(Engine* engine, int index, const ScopedValue& value); private: DISABLE_COPY(ArrayAccessor); diff --git a/lib/lvelements/src/script.cpp b/lib/lvelements/src/script.cpp index e4bfbbf5..c3e0e948 100644 --- a/lib/lvelements/src/script.cpp +++ b/lib/lvelements/src/script.cpp @@ -49,8 +49,9 @@ Value Script::run(){ } Object Script::loadAsModule(ModuleFile* file){ - v8::HandleScope handle(m_d->engine->isolate()); - v8::Local context = m_d->engine->currentContext()->asLocal(); + auto isolate = m_d->engine->isolate(); + auto context = isolate->GetCurrentContext(); + v8::HandleScope handle(isolate); v8::Context::Scope context_scope(context); if ( m_d->engine->tryCatchNesting() == 0){ @@ -63,14 +64,14 @@ Object Script::loadAsModule(ModuleFile* file){ Engine::CatchData cd(m_d->engine, &tc); v8::Local ehKey = v8::String::NewFromUtf8( - m_d->engine->isolate(), "__errorhandler__", v8::String::kInternalizedString - ); + m_d->engine->isolate(), "__errorhandler__", v8::NewStringType::kInternalized + ).ToLocalChecked(); Element* current = cd.object(); while ( current ){ v8::Local lo = ElementPrivate::localObject(current); - if ( lo->Has(ehKey) ){ - Element* elem = ElementPrivate::elementFromObject(lo->Get(ehKey)->ToObject()); + if ( lo->Has(context, ehKey).ToChecked() ){ + Element* elem = ElementPrivate::elementFromObject(lo->Get(context, ehKey).ToLocalChecked()->ToObject(context).ToLocalChecked()); ErrorHandler* ehandler = elem->cast(); ErrorHandler::ErrorData ed; ed.fileName = cd.fileName(); @@ -122,9 +123,9 @@ Object Script::loadAsModuleImpl(ModuleFile *mf, const v8::Local &co ScopedValue module = mf->createObject(m_d->engine); v8::Local name = v8::String::NewFromUtf8( - m_d->engine->isolate(), mf->name().c_str(), v8::String::kInternalizedString); + m_d->engine->isolate(), mf->name().c_str(), v8::NewStringType::kInternalized).ToLocalChecked(); v8::Local filePath = v8::String::NewFromUtf8( - m_d->engine->isolate(), mf->filePath().c_str(), v8::String::kInternalizedString); + m_d->engine->isolate(), mf->filePath().c_str(), v8::NewStringType::kInternalized).ToLocalChecked(); v8::Local args[4]; args[0] = module.data(); @@ -132,13 +133,13 @@ Object Script::loadAsModuleImpl(ModuleFile *mf, const v8::Local &co args[2] = name; args[3] = filePath; - loadFunction->Call(context->Global(), 4, args); + loadFunction->Call(context, context->Global(), 4, args).IsEmpty(); v8::Local moduleValue = v8::Local::Cast(module.data()); - v8::Local exportsKey = v8::String::NewFromUtf8(m_d->engine->isolate(), "exports"); + v8::Local exportsKey = v8::String::NewFromUtf8(m_d->engine->isolate(), "exports").ToLocalChecked(); - v8::Local exportsValue = moduleValue->Get(exportsKey); + v8::Local exportsValue = moduleValue->Get(context, exportsKey).ToLocalChecked(); if ( !exportsValue->IsObject() ){ lv::Exception e = CREATE_EXCEPTION( lv::Exception, @@ -151,9 +152,9 @@ Object Script::loadAsModuleImpl(ModuleFile *mf, const v8::Local &co v8::Local exportsObject = v8::Local::Cast(exportsValue); - v8::Local propertyNames = exportsObject->GetOwnPropertyNames(); + v8::Local propertyNames = exportsObject->GetOwnPropertyNames(context, v8::ALL_PROPERTIES).ToLocalChecked(); for (uint32_t i = 0; i < propertyNames->Length(); ++i) { - v8::Local key = propertyNames->Get(i); + v8::Local key = propertyNames->Get(context, i).ToLocalChecked(); if ( !key->IsString() ){ lv::Exception e = CREATE_EXCEPTION( @@ -165,10 +166,12 @@ Object Script::loadAsModuleImpl(ModuleFile *mf, const v8::Local &co return module.toObject(m_d->engine); } - v8::String::Utf8Value utf8_key(key); + auto isolate = m_d->engine->isolate(); + auto context = isolate->GetCurrentContext(); + v8::String::Utf8Value utf8_key(isolate, key); if ( strcmp(*utf8_key, "__shared__") != 0 && strlen(*utf8_key) > 0 ){ - v8::Local value = exportsObject->Get(key); + v8::Local value = exportsObject->Get(context, key).ToLocalChecked(); if ( value->IsFunction() ){ v8::Local func = v8::Local::Cast(value); diff --git a/lib/lvelements/src/v8nowarnings.h b/lib/lvelements/src/v8nowarnings.h index 4cbb9cca..76f8c61d 100644 --- a/lib/lvelements/src/v8nowarnings.h +++ b/lib/lvelements/src/v8nowarnings.h @@ -2,6 +2,7 @@ #pragma warning(push) #pragma warning(disable : 4100) +#define V8_COMPRESS_POINTERS #include "v8.h" #include "libplatform/libplatform.h" diff --git a/lib/lvelements/src/value.cpp b/lib/lvelements/src/value.cpp index c4f86edb..49791525 100644 --- a/lib/lvelements/src/value.cpp +++ b/lib/lvelements/src/value.cpp @@ -63,19 +63,19 @@ ScopedValue::ScopedValue(Engine *engine, const std::string &val) : m_d(nullptr) , m_ref(new int) { - v8::Local s = v8::String::NewFromUtf8(engine->isolate(), val.c_str()); + v8::Local s = v8::String::NewFromUtf8(engine->isolate(), val.c_str()).ToLocalChecked(); m_d = new LocalValuePrivate(s); ++(*m_ref); } -ScopedValue::ScopedValue(Engine *, Callable val) +ScopedValue::ScopedValue(Engine *engine, Callable val) : m_d(new LocalValuePrivate(val.data())) , m_ref(new int) { ++(*m_ref); } -ScopedValue::ScopedValue(Engine *, Object val) +ScopedValue::ScopedValue(Engine *engine, Object val) : m_d(new LocalValuePrivate(val.data())) , m_ref(new int) { @@ -89,7 +89,7 @@ ScopedValue::ScopedValue(Engine *engine, const Buffer &val) ++(*m_ref); } -ScopedValue::ScopedValue(Engine *, Element* val) +ScopedValue::ScopedValue(Engine *engine, Element* val) : m_d(new LocalValuePrivate(ElementPrivate::localObject(val))) , m_ref(new int) { @@ -128,7 +128,7 @@ ScopedValue::ScopedValue(Engine *engine, const Value &value) } } -ScopedValue::ScopedValue(Engine *, const ScopedValue &other) +ScopedValue::ScopedValue(Engine *engine, const ScopedValue &other) : m_d(other.m_d) , m_ref(other.m_ref) { @@ -172,24 +172,24 @@ const v8::Local &ScopedValue::data() const{ return m_d->data; } -bool ScopedValue::toBool(Engine*) const{ - return m_d->data->BooleanValue(); +bool ScopedValue::toBool(Engine *engine) const{ + return m_d->data->BooleanValue(engine->isolate()); } Value::Int32 ScopedValue::toInt32(Engine *engine) const{ - return m_d->data->ToInt32(engine->isolate())->Value(); + return m_d->data->ToInt32(engine->isolate()->GetCurrentContext()).ToLocalChecked()->Value(); } Value::Int64 ScopedValue::toInt64(Engine *engine) const{ - return (Value::Int64)m_d->data->ToNumber(engine->isolate())->Value(); + return (Value::Int64)m_d->data->ToNumber(engine->isolate()->GetCurrentContext()).ToLocalChecked()->Value(); } Value::Number ScopedValue::toNumber(Engine *engine) const{ - return m_d->data->ToNumber(engine->isolate())->Value(); + return m_d->data->ToNumber(engine->isolate()->GetCurrentContext()).ToLocalChecked()->Value(); } std::string ScopedValue::toStdString(Engine *engine) const{ - return *v8::String::Utf8Value(m_d->data->ToString(engine->isolate())); + return *v8::String::Utf8Value(engine->isolate(), m_d->data->ToString(engine->isolate()->GetCurrentContext()).ToLocalChecked()); } Callable ScopedValue::toCallable(Engine* engine) const{ @@ -202,8 +202,8 @@ Buffer ScopedValue::toBuffer(Engine *) const{ Object ScopedValue::toObject(Engine *engine) const{ if ( isString() && !isObject() ){ - v8::Local vs = m_d->data->ToString(); - v8::Local vo = v8::Local::Cast(v8::StringObject::New(vs)); + v8::Local vs = m_d->data->ToString(engine->isolate()->GetCurrentContext()).ToLocalChecked(); + v8::Local vo = v8::Local::Cast(v8::StringObject::New(engine->isolate(), vs)); return Object(engine, vo); } else { v8::Local vo = v8::Local::Cast(m_d->data); @@ -292,29 +292,29 @@ ScopedValue::ScopedValue(const v8::Local &data) } template<> -bool convertFromV8(Engine *, const v8::Local &value){ - return value->BooleanValue(); +bool convertFromV8(Engine *engine, const v8::Local &value){ + return value->BooleanValue(engine->isolate()); } template<> -Value::Int32 convertFromV8(Engine *, const v8::Local &value){ - return value->Int32Value(); +Value::Int32 convertFromV8(Engine *engine, const v8::Local &value){ + return value->Int32Value(engine->isolate()->GetCurrentContext()).ToChecked(); } template<> -Value::Int64 convertFromV8(Engine *, const v8::Local &value){ - return value->IntegerValue(); +Value::Int64 convertFromV8(Engine *engine, const v8::Local &value){ + return value->IntegerValue(engine->isolate()->GetCurrentContext()).ToChecked(); } template<> -Value::Number convertFromV8(Engine *, const v8::Local &value){ - return value->NumberValue(); +Value::Number convertFromV8(Engine *engine, const v8::Local &value){ + return value->NumberValue(engine->isolate()->GetCurrentContext()).ToChecked(); } template<> std::string convertFromV8(Engine *engine, const v8::Local &value){ - return *v8::String::Utf8Value(value->ToString(engine->isolate())); + return *v8::String::Utf8Value(engine->isolate(), value->ToString(engine->isolate()->GetCurrentContext()).ToLocalChecked()); } template<> diff --git a/lib/lvelements/src/value.h b/lib/lvelements/src/value.h index ca60355e..813b1664 100644 --- a/lib/lvelements/src/value.h +++ b/lib/lvelements/src/value.h @@ -176,6 +176,8 @@ class LV_ELEMENTS_EXPORT ScopedValue{ bool isArray() const; bool isElement() const; + + template static ScopedValue createValue(Engine* engine, const T& val){ return ScopedValue(engine, val); } diff --git a/lib/lvelements/src/value_p.h b/lib/lvelements/src/value_p.h index 0491425c..4f96eae0 100644 --- a/lib/lvelements/src/value_p.h +++ b/lib/lvelements/src/value_p.h @@ -14,17 +14,24 @@ class Point{ public: static void constructPoint(const v8::FunctionCallbackInfo& info){ - double x = info.Length() > 0 ? info[0]->ToNumber(info.GetIsolate())->Value() : 0; - double y = info.Length() > 1 ? info[1]->ToNumber(info.GetIsolate())->Value() : 0; + auto context = info.GetIsolate()->GetCurrentContext(); + double x = (info.Length() > 0) ? info[0]->ToNumber(context).ToLocalChecked()->Value() : 0; + double y = (info.Length() > 1) ? info[1]->ToNumber(context).ToLocalChecked()->Value() : 0; - info.This()->Set( - v8::String::NewFromUtf8(info.GetIsolate(), "x", v8::String::kInternalizedString), + auto setX = info.This()->Set( + info.GetIsolate()->GetCurrentContext(), + v8::String::NewFromUtf8(info.GetIsolate(), "x", v8::NewStringType::kInternalized).ToLocalChecked(), v8::Number::New(info.GetIsolate(), x) ); - info.This()->Set( - v8::String::NewFromUtf8(info.GetIsolate(), "y", v8::String::kInternalizedString), + setX.IsNothing(); + + auto setY = info.This()->Set( + info.GetIsolate()->GetCurrentContext(), + v8::String::NewFromUtf8(info.GetIsolate(), "y", v8::NewStringType::kInternalized).ToLocalChecked(), v8::Number::New(info.GetIsolate(), y) ); + setY.IsNothing(); + info.GetReturnValue().Set(info.This()); } @@ -32,7 +39,7 @@ class Point{ v8::Local localTpl; localTpl = v8::FunctionTemplate::New(isolate); localTpl->SetCallHandler(&Point::constructPoint); - localTpl->SetClassName(v8::String::NewFromUtf8(isolate, "Point")); + localTpl->SetClassName(v8::String::NewFromUtf8(isolate, "Point").ToLocalChecked()); return localTpl; } @@ -45,17 +52,24 @@ class Size{ public: static void constructSize(const v8::FunctionCallbackInfo& info){ - double width = info.Length() > 0 ? info[0]->ToNumber(info.GetIsolate())->Value() : 0; - double height = info.Length() > 1 ? info[1]->ToNumber(info.GetIsolate())->Value() : 0; + auto context = info.GetIsolate()->GetCurrentContext(); + double width = (info.Length() > 0) ? info[0]->ToNumber(context).ToLocalChecked()->Value() : 0; + double height = (info.Length() > 1) ? info[1]->ToNumber(context).ToLocalChecked()->Value() : 0; - info.This()->Set( - v8::String::NewFromUtf8(info.GetIsolate(), "width", v8::String::kInternalizedString), + auto setWidth = info.This()->Set( + info.GetIsolate()->GetCurrentContext(), + v8::String::NewFromUtf8(info.GetIsolate(), "width", v8::NewStringType::kInternalized).ToLocalChecked(), v8::Number::New(info.GetIsolate(), width) ); - info.This()->Set( - v8::String::NewFromUtf8(info.GetIsolate(), "height", v8::String::kInternalizedString), + setWidth.IsNothing(); + + auto setHeight = info.This()->Set( + info.GetIsolate()->GetCurrentContext(), + v8::String::NewFromUtf8(info.GetIsolate(), "height", v8::NewStringType::kInternalized).ToLocalChecked(), v8::Number::New(info.GetIsolate(), height) ); + setHeight.IsNothing(); + info.GetReturnValue().Set(info.This()); } @@ -63,7 +77,7 @@ class Size{ v8::Local localTpl; localTpl = v8::FunctionTemplate::New(isolate); localTpl->SetCallHandler(&Size::constructSize); - localTpl->SetClassName(v8::String::NewFromUtf8(isolate, "Size")); + localTpl->SetClassName(v8::String::NewFromUtf8(isolate, "Size").ToLocalChecked()); return localTpl; } @@ -77,27 +91,40 @@ class Rectangle{ public: static void constructRectangle(const v8::FunctionCallbackInfo& info){ - double x = info.Length() > 0 ? info[0]->ToNumber(info.GetIsolate())->Value() : 0; - double y = info.Length() > 1 ? info[1]->ToNumber(info.GetIsolate())->Value() : 0; - double width = info.Length() > 2 ? info[2]->ToNumber(info.GetIsolate())->Value() : 0; - double height = info.Length() > 3 ? info[3]->ToNumber(info.GetIsolate())->Value() : 0; - - info.This()->Set( - v8::String::NewFromUtf8(info.GetIsolate(), "x", v8::String::kInternalizedString), + auto context = info.GetIsolate()->GetCurrentContext(); + double x = (info.Length() > 0) ? info[0]->ToNumber(context).ToLocalChecked()->Value() : 0; + double y = (info.Length() > 1) ? info[1]->ToNumber(context).ToLocalChecked()->Value() : 0; + double width = (info.Length() > 2) ? info[2]->ToNumber(context).ToLocalChecked()->Value() : 0; + double height = (info.Length() > 3) ? info[3]->ToNumber(context).ToLocalChecked()->Value() : 0; + + auto setX = info.This()->Set( + info.GetIsolate()->GetCurrentContext(), + v8::String::NewFromUtf8(info.GetIsolate(), "x", v8::NewStringType::kInternalized).ToLocalChecked(), v8::Number::New(info.GetIsolate(), x) ); - info.This()->Set( - v8::String::NewFromUtf8(info.GetIsolate(), "y", v8::String::kInternalizedString), + setX.IsNothing(); + + auto setY = info.This()->Set( + info.GetIsolate()->GetCurrentContext(), + v8::String::NewFromUtf8(info.GetIsolate(), "y", v8::NewStringType::kInternalized).ToLocalChecked(), v8::Number::New(info.GetIsolate(), y) ); - info.This()->Set( - v8::String::NewFromUtf8(info.GetIsolate(), "width", v8::String::kInternalizedString), + setY.IsNothing(); + + auto setWidth = info.This()->Set( + info.GetIsolate()->GetCurrentContext(), + v8::String::NewFromUtf8(info.GetIsolate(), "width", v8::NewStringType::kInternalized).ToLocalChecked(), v8::Number::New(info.GetIsolate(), width) ); - info.This()->Set( - v8::String::NewFromUtf8(info.GetIsolate(), "height", v8::String::kInternalizedString), + setWidth.IsNothing(); + + auto setHeight = info.This()->Set( + info.GetIsolate()->GetCurrentContext(), + v8::String::NewFromUtf8(info.GetIsolate(), "height", v8::NewStringType::kInternalized).ToLocalChecked(), v8::Number::New(info.GetIsolate(), height) ); + setHeight.IsNothing(); + info.GetReturnValue().Set(info.This()); } @@ -105,7 +132,7 @@ class Rectangle{ v8::Local localTpl; localTpl = v8::FunctionTemplate::New(isolate); localTpl->SetCallHandler(&Rectangle::constructRectangle); - localTpl->SetClassName(v8::String::NewFromUtf8(isolate, "Rectangle")); + localTpl->SetClassName(v8::String::NewFromUtf8(isolate, "Rectangle").ToLocalChecked()); return localTpl; } @@ -117,16 +144,16 @@ class Rectangle{ inline void linkError(const v8::FunctionCallbackInfo& info){ if ( info.Length() != 2 ){ info.GetIsolate()->ThrowException( - v8::String::NewFromUtf8(info.GetIsolate(), "linkError requires 2 arguments to be provided.")); + v8::String::NewFromUtf8(info.GetIsolate(), "linkError requires 2 arguments to be provided.").ToLocalChecked()); return; } - v8::Local errorObject = info[0]->ToObject(info.GetIsolate()); - v8::Local bindingObject = info[1]->ToObject(info.GetIsolate()); + v8::Local errorObject = info[0]->ToObject(info.GetIsolate()->GetCurrentContext()).ToLocalChecked(); + v8::Local bindingObject = info[1]->ToObject(info.GetIsolate()->GetCurrentContext()).ToLocalChecked(); v8::Maybe result = errorObject->Set( info.GetIsolate()->GetCurrentContext(), - v8::String::NewFromUtf8(info.GetIsolate(), "object", v8::String::kInternalizedString), + v8::String::NewFromUtf8(info.GetIsolate(), "object", v8::NewStringType::kInternalized).ToLocalChecked(), bindingObject ); result.IsNothing(); diff --git a/lib/lvelements/src/visuallogjsobject.h b/lib/lvelements/src/visuallogjsobject.h index ce672214..6fabc2f2 100644 --- a/lib/lvelements/src/visuallogjsobject.h +++ b/lib/lvelements/src/visuallogjsobject.h @@ -43,7 +43,7 @@ class VisualLogJsObject{ return; } - v8::String::Utf8Value utfKey(info[0]->ToString(info.GetIsolate())); + v8::String::Utf8Value utfKey(info.GetIsolate(), info[0]->ToString(info.GetIsolate()->GetCurrentContext()).ToLocalChecked()); ScopedValue val(info[1]); MLNode mlopt; @@ -53,9 +53,9 @@ class VisualLogJsObject{ static void captureStackHelper(Engine* engine, VisualLog& vl){ v8::Local st = v8::StackTrace::CurrentStackTrace(engine->isolate(), 1, v8::StackTrace::kScriptName); - v8::Local sf = st->GetFrame(0); - v8::String::Utf8Value scriptName(sf->GetScriptName()); - v8::String::Utf8Value functionName(sf->GetFunctionName()); + v8::Local sf = st->GetFrame(engine->isolate(), 0); + v8::String::Utf8Value scriptName(engine->isolate(), sf->GetScriptName()); + v8::String::Utf8Value functionName(engine->isolate(), sf->GetFunctionName()); sf->GetLineNumber(); vl.at(*scriptName, sf->GetLineNumber(), *functionName); @@ -63,19 +63,23 @@ class VisualLogJsObject{ static void logHelper(VisualLog::MessageInfo::Level level, const v8::FunctionCallbackInfo& info){ - bool captureStack = info.This()->Get(v8::String::NewFromUtf8(info.GetIsolate(), "sourceInfo"))->BooleanValue(); + bool captureStack = info.This()->Get( + info.GetIsolate()->GetCurrentContext(), + v8::String::NewFromUtf8(info.GetIsolate(), "sourceInfo").ToLocalChecked() + ).ToLocalChecked()->BooleanValue(info.GetIsolate()); + + Engine* engine = reinterpret_cast(info.GetIsolate()->GetData(0)); if ( info.Length() == 0 ){ VisualLog vl(level); if ( captureStack ){ - Engine* engine = reinterpret_cast(info.GetIsolate()->GetData(0)); captureStackHelper(engine, vl); } } else if ( info.Length() == 1 ){ VisualLog vl(level); + if ( captureStack ){ - Engine* engine = reinterpret_cast(info.GetIsolate()->GetData(0)); captureStackHelper(engine, vl); } @@ -91,11 +95,11 @@ class VisualLogJsObject{ } } - v8::String::Utf8Value utfVal(arg->ToString()); + v8::String::Utf8Value utfVal(engine->isolate(), arg->ToString(engine->isolate()->GetCurrentContext()).ToLocalChecked()); vl << *utfVal; } else if ( info.Length() == 2 ){ - v8::String::Utf8Value utfKey(info[0]->ToString()); + v8::String::Utf8Value utfKey(engine->isolate(), info[0]->ToString(engine->isolate()->GetCurrentContext()).ToLocalChecked()); VisualLog vl(*utfKey, level); if ( captureStack ){ @@ -116,7 +120,7 @@ class VisualLogJsObject{ } } - v8::String::Utf8Value utfVal(arg->ToString()); + v8::String::Utf8Value utfVal(engine->isolate(), arg->ToString(engine->isolate()->GetCurrentContext()).ToLocalChecked()); vl << *utfVal; } else { @@ -133,17 +137,17 @@ class VisualLogJsObject{ static v8::Local functionTemplate(v8::Isolate* isolate){ v8::Local localTpl; localTpl = v8::FunctionTemplate::New(isolate); - localTpl->SetClassName(v8::String::NewFromUtf8(isolate, "VisualLog")); + localTpl->SetClassName(v8::String::NewFromUtf8(isolate, "VisualLog").ToLocalChecked()); v8::Local tplPrototype = localTpl->PrototypeTemplate(); - tplPrototype->Set(v8::String::NewFromUtf8(isolate, "f"), v8::FunctionTemplate::New(isolate, &VisualLogJsObject::f)); - tplPrototype->Set(v8::String::NewFromUtf8(isolate, "e"), v8::FunctionTemplate::New(isolate, &VisualLogJsObject::e)); - tplPrototype->Set(v8::String::NewFromUtf8(isolate, "w"), v8::FunctionTemplate::New(isolate, &VisualLogJsObject::w)); - tplPrototype->Set(v8::String::NewFromUtf8(isolate, "i"), v8::FunctionTemplate::New(isolate, &VisualLogJsObject::i)); - tplPrototype->Set(v8::String::NewFromUtf8(isolate, "d"), v8::FunctionTemplate::New(isolate, &VisualLogJsObject::d)); - tplPrototype->Set(v8::String::NewFromUtf8(isolate, "v"), v8::FunctionTemplate::New(isolate, &VisualLogJsObject::v)); - tplPrototype->Set(v8::String::NewFromUtf8(isolate, "configure"), v8::FunctionTemplate::New(isolate, &VisualLogJsObject::configure)); + tplPrototype->Set(isolate, "f", v8::FunctionTemplate::New(isolate, &VisualLogJsObject::f)); + tplPrototype->Set(isolate, "e", v8::FunctionTemplate::New(isolate, &VisualLogJsObject::e)); + tplPrototype->Set(isolate, "w", v8::FunctionTemplate::New(isolate, &VisualLogJsObject::w)); + tplPrototype->Set(isolate, "i", v8::FunctionTemplate::New(isolate, &VisualLogJsObject::i)); + tplPrototype->Set(isolate, "d", v8::FunctionTemplate::New(isolate, &VisualLogJsObject::d)); + tplPrototype->Set(isolate, "v", v8::FunctionTemplate::New(isolate, &VisualLogJsObject::v)); + tplPrototype->Set(isolate, "configure", v8::FunctionTemplate::New(isolate, &VisualLogJsObject::configure)); return localTpl; } diff --git a/plugins/editlv/src/lveditfragment.cpp b/plugins/editlv/src/lveditfragment.cpp index 4ef07a26..27d7d909 100644 --- a/plugins/editlv/src/lveditfragment.cpp +++ b/plugins/editlv/src/lveditfragment.cpp @@ -251,8 +251,8 @@ void LvEditFragment::updateValue(){ } if ( m_bindingPalette ){ // m_bindingPalette->setValueFromBinding(inputPath->property().read()); // TODO: ELEMENTS #381 - CodeConverter* cvt = static_cast(m_bindingPalette->extension()); - cvt->whenBinding().call(); + // CodeConverter* cvt = static_cast(m_bindingPalette->extension()); + // cvt->whenBinding().call(); } } } diff --git a/plugins/language/src/moduleinfocapture.cpp b/plugins/language/src/moduleinfocapture.cpp index ef43bc4e..9dcd66b5 100644 --- a/plugins/language/src/moduleinfocapture.cpp +++ b/plugins/language/src/moduleinfocapture.cpp @@ -52,11 +52,11 @@ void ModuleInfoCapture::readModule(){ ElementsPlugin::Ptr ep = engine()->require(m_current->importUri().data()); Object epexports = ep->collectExportsObject(); Object::Accessor lo(epexports); - ScopedValue lokeys = lo.ownProperties(); + ScopedValue lokeys = lo.ownProperties(engine()); Object::ArrayAccessor lokeysArray(engine(), lokeys); for ( int i = 0; i < lokeysArray.length(); ++i ){ - ScopedValue exportValue = lo.get(lokeysArray.get(i)); + ScopedValue exportValue = lo.get(engine(), lokeysArray.get(engine(), i)); if ( exportValue.isElement() ){ TypeInfo::Ptr ti = TypeInfo::extract( exportValue.toElement(engine())->typeMetaObject(), m_current->importUri(), true, false diff --git a/plugins/test/src/testcase.cpp b/plugins/test/src/testcase.cpp index 54d8f3ba..259de143 100644 --- a/plugins/test/src/testcase.cpp +++ b/plugins/test/src/testcase.cpp @@ -22,7 +22,7 @@ ScopedValue TestCase::children(){ Object o = Object::createArray(engine(), static_cast(m_data.size())); Object::ArrayAccessor la(o); for ( int i = 0; i < static_cast(m_data.size()); ++i ){ - la.set(i, ScopedValue(engine(), m_data[static_cast(i)])); + la.set(engine(), i, ScopedValue(engine(), m_data[static_cast(i)])); } return ScopedValue(engine(), o); } @@ -35,7 +35,7 @@ void TestCase::setChildren(ScopedValue children){ if ( children.isArray() ){ Object::ArrayAccessor la(engine(), children); for ( int i = 0; i < la.length(); ++i ){ - ScopedValue lval = la.get(i); + ScopedValue lval = la.get(engine(), i); if ( lval.isElement() ){ Element* el = lval.toElement(engine()); if (el){ diff --git a/project/3rdparty/v8.pri b/project/3rdparty/v8.pri index 6727d9e2..38e2c32e 100644 --- a/project/3rdparty/v8.pri +++ b/project/3rdparty/v8.pri @@ -56,8 +56,6 @@ win32{ copyV8($${V8_LIBRARY_PATH}/v8_libbase.dll, $$DEPLOY_PATH) copyV8($${V8_LIBRARY_PATH}/v8_libplatform.dll, $$DEPLOY_PATH) - copyV8($${V8_LIBRARY_PATH}/natives_blob.bin, $${DEPLOY_PATH}/external/v8) - copyV8($${V8_LIBRARY_PATH}/snapshot_blob.bin, $${DEPLOY_PATH}/external/v8) } } diff --git a/tests/unit/lvelementstest/data/ParserTest13.lv.js b/tests/unit/lvelementstest/data/ParserTest13.lv.js new file mode 100644 index 00000000..9cb75143 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest13.lv.js @@ -0,0 +1,19 @@ +imports.require('test') + +var Scenario = imports.get('Scenario') +var TestCase = imports.get('TestCase') + +module.exports["ParserTest13"] = (function(parent){ + this.setParent(parent) + Element.assignDefaultProperty(this, [ + (function(parent){ + this.setParent(parent) + this.describe = "assert true test" + this.run = (t) => { + t.assert(true) + } + return this + }.bind(new Scenario())(this)) + ]) + return this +}.bind(new TestCase())(null)) \ No newline at end of file diff --git a/tests/unit/lvelementstest/data/ParserTest14.lv.js b/tests/unit/lvelementstest/data/ParserTest14.lv.js index 630b948a..df1c554d 100644 --- a/tests/unit/lvelementstest/data/ParserTest14.lv.js +++ b/tests/unit/lvelementstest/data/ParserTest14.lv.js @@ -1,11 +1,11 @@ imports.require('test') imports.require('language') +var LanguageScanner = imports.get('LanguageScanner') var Scenario = imports.get('Scenario') var TestCase = imports.get('TestCase') -var LanguageScanner = imports.get('LanguageScanner') -module.exports["languagetest"] = (function(parent){ +module.exports["ParserTest14"] = (function(parent){ this.setParent(parent) Element.addProperty(this, 'ls', { type: 'LanguageScanner', notify: 'lsChanged' }) this.ls = (function(parent){ diff --git a/tests/unit/lvelementstest/data/ParserTest15.lv b/tests/unit/lvelementstest/data/ParserTest15.lv new file mode 100644 index 00000000..d37fe387 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest15.lv @@ -0,0 +1,9 @@ +component default { + int c: { + var newElement = Element { + int y: 20 + } + return newElement.y + } +} + diff --git a/tests/unit/lvelementstest/data/ParserTest15.lv.js b/tests/unit/lvelementstest/data/ParserTest15.lv.js new file mode 100644 index 00000000..77b5fe20 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest15.lv.js @@ -0,0 +1,22 @@ +module.exports["ParserTest15"] = class ParserTest15 extends Element{ + + constructor(){ + super() + this.__initialize() + } + + __initialize(){ + Element.addProperty(this, 'c', { type: "int", notify: "cChanged" }) + this.c = (function(){ + var newElement = (function(parent){ + this.setParent(parent) + Element.addProperty(this, 'y', { type: 'int', notify: 'yChanged' }) + this.y = 20 + return this + }.bind(new Element())(null)) + + return newElement.y + })() + + } +} diff --git a/tests/unit/lvelementstest/data/ParserTest16.lv b/tests/unit/lvelementstest/data/ParserTest16.lv new file mode 100644 index 00000000..ac8d765e --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest16.lv @@ -0,0 +1,7 @@ +component TodoList < Ul{ + + children: this.items.map((item, index) => { + return TodoListItem{ + } + }) +} \ No newline at end of file diff --git a/tests/unit/lvelementstest/data/ParserTest16.lv.js b/tests/unit/lvelementstest/data/ParserTest16.lv.js new file mode 100644 index 00000000..2fb66181 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest16.lv.js @@ -0,0 +1,20 @@ +var TodoListItem = imports.get('TodoListItem') +var Ul = imports.get('Ul') + +module.exports["TodoList"] = class TodoList extends Ul{ + + constructor(){ + super() + this.__initialize() + } + + __initialize(){ + this.children = this.items.map((item, index) => { + return(function(parent){ + this.setParent(parent) + return this + }.bind(new TodoListItem())(null)) + }) + } + +} \ No newline at end of file diff --git a/tests/unit/lvelementstest/data/ParserTest17.lv b/tests/unit/lvelementstest/data/ParserTest17.lv new file mode 100644 index 00000000..24468b59 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest17.lv @@ -0,0 +1,10 @@ +component TodoListItem{ + key: index + item: item + on remove: (index) => { + todoList.remove(index) + } + on markDone: (index) => { + todoList.markTodoDone(index) + } +} \ No newline at end of file diff --git a/tests/unit/lvelementstest/data/ParserTest17.lv.js b/tests/unit/lvelementstest/data/ParserTest17.lv.js new file mode 100644 index 00000000..7a6b9591 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest17.lv.js @@ -0,0 +1,19 @@ +module.exports["TodoListItem"] = class TodoListItem extends Element{ + + constructor(){ + super() + this.__initialize() + } + + __initialize(){ + this.on('remove', function(index){ + todoList.remove(index) + }.bind(this)); + this.on('markDone', function(index){ + todoList.markTodoDone(index) + }.bind(this)); + this.key = index + this.item = item + } + +} \ No newline at end of file diff --git a/tests/unit/lvelementstest/data/ParserTest18.lv b/tests/unit/lvelementstest/data/ParserTest18.lv new file mode 100644 index 00000000..af49d926 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest18.lv @@ -0,0 +1,12 @@ +component TodoList < Ul{ + id: todoList + list items: [] + classes: ['list-group'] + + event remove(int index) + event markTodoDone(int index) + + children: this.items.map((item, index) => { + return TodoListItem{key: index; item: item; on remove: (index) => { todoList.remove(index) }; on markDone: (index) => { todoList.markDone(index) } } + }) +} \ No newline at end of file diff --git a/tests/unit/lvelementstest/data/ParserTest18.lv.js b/tests/unit/lvelementstest/data/ParserTest18.lv.js new file mode 100644 index 00000000..d386ed8e --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest18.lv.js @@ -0,0 +1,34 @@ +var TodoListItem = imports.get('TodoListItem') +var Ul = imports.get('Ul') + +module.exports["TodoList"] = class TodoList extends Ul{ + + constructor(){ + super() + this.__initialize() + } + + __initialize(){ + this.ids = {} + + var todoList = this + this.ids["todoList"] = todoList + + Element.addProperty(this, 'items', { type: "list", notify: "itemsChanged" }) + Element.addEvent(this, 'remove', []) + Element.addEvent(this, 'markTodoDone', []) + this.items = [] + this.classes = ['list-group'] + this.children = this.items.map((item, index) => { + return(function(parent){ + this.setParent(parent) + this.key = index; + this.item = item; + this.on('remove', function(index){ todoList.remove(index) }.bind(this)); + this.on('markDone', function(index){ todoList.markDone(index) }.bind(this)); + return this + }.bind(new TodoListItem())(null)) + }) + } + +} diff --git a/tests/unit/lvelementstest/data/ParserTest19.lv b/tests/unit/lvelementstest/data/ParserTest19.lv new file mode 100644 index 00000000..e596b465 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest19.lv @@ -0,0 +1,14 @@ +component TodoListItem < Li{ + id: todoListItem + var item: null + event remove() + event markDone() + classes: "list-group-item" + + Div{ + classes: item.done ? "done" : "undone" + Span{ classes: "glyphicon glyphicon-ok icon"; ariaHidden: true; on click: () => { todoListItem.markDone() } } + T{ text: item.value } + Button{ classes: "close"; on click: () => { todoListItem.remove()} ; text: "×" } + } +} \ No newline at end of file diff --git a/tests/unit/lvelementstest/data/ParserTest19.lv.js b/tests/unit/lvelementstest/data/ParserTest19.lv.js new file mode 100644 index 00000000..b56152f2 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest19.lv.js @@ -0,0 +1,66 @@ +var Button = imports.get('Button') +var Div = imports.get('Div') +var Li = imports.get('Li') +var Span = imports.get('Span') +var T = imports.get('T') + +module.exports["TodoListItem"] = class TodoListItem extends Li{ + + constructor(){ + super() + this.__initialize() + } + + __initialize(){ + this.ids = {} + var todoListItem = this + this.ids["todoListItem"] = todoListItem + + Element.addProperty(this, 'item', { type: "var", notify: "itemChanged" }) + Element.addEvent(this, 'remove', []) + Element.addEvent(this, 'markDone', []) + this.item = null + this.classes = "list-group-item" + Element.assignDefaultProperty(this, [ + (function(parent){ + this.setParent(parent) + Element.assignPropertyExpression(this, + 'classes', + function(){ return item.done ? "done" : "undone"}.bind(this), + [ + [ item, 'doneChanged' ] + ] + ) + Element.assignDefaultProperty(this, [ + (function(parent){ + this.setParent(parent) + this.classes = "glyphicon glyphicon-ok icon"; + this.ariaHidden = true; + this.on('click', function(){ todoListItem.markDone() }.bind(this)); + return this + }.bind(new Span())(this)), + (function(parent){ + this.setParent(parent) + Element.assignPropertyExpression(this, + 'text', + function(){ return item.value}.bind(this), + [ + [ item, 'valueChanged' ] + ] + ) + return this + }.bind(new T())(this)), + (function(parent){ + this.setParent(parent) + this.classes = "close"; + this.text = "×" + this.on('click', function(){ todoListItem.remove()}.bind(this)); + return this + }.bind(new Button())(this)) + ]) + return this + }.bind(new Div())(this)) + ]) + } + +} \ No newline at end of file diff --git a/tests/unit/lvelementstest/data/ParserTest20.lv b/tests/unit/lvelementstest/data/ParserTest20.lv new file mode 100644 index 00000000..655ee515 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest20.lv @@ -0,0 +1,14 @@ +component TodoForm < Form{ + event addItem(string name) + + on submit: (event) => { + event.preventDefault(); + if(itemName.value) { + this.addItem(itemName.value) + this.reset() + } + } + + Input{ id: itemName; type: "text"; classes: "form-control"; placeholder: "Add New TODO..." } + Button{ type: "submit"; classes: "btn btn-default"; text: "Add" } +} \ No newline at end of file diff --git a/tests/unit/lvelementstest/data/ParserTest20.lv.js b/tests/unit/lvelementstest/data/ParserTest20.lv.js new file mode 100644 index 00000000..99441d2f --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest20.lv.js @@ -0,0 +1,43 @@ +var Button = imports.get('Button') +var Form = imports.get('Form') + +module.exports["TodoForm"] = class TodoForm extends Form{ + + constructor(){ + super() + this.__initialize() + } + + __initialize(){ + this.ids = {} + + var itemName = new Input() + this.ids["itemName"] = itemName + + Element.addEvent(this, 'addItem', []) + this.on('submit', function(event){ + event.preventDefault(); + if(itemName.value) { + this.addItem(itemName.value) + this.reset() + } + }.bind(this)); + Element.assignDefaultProperty(this, [ + (function(parent){ + this.setParent(parent) + Element.assignId(itemName, "itemName") + this.type = "text"; + this.classes = "form-control"; + this.placeholder = "Add New TODO..." + return this + }.bind(itemName)(this)), + (function(parent){ + this.setParent(parent) + this.type = "submit"; + this.classes = "btn btn-default"; + this.text = "Add" + return this + }.bind(new Button())(this)) + ]) + } +} \ No newline at end of file diff --git a/tests/unit/lvelementstest/data/ParserTest21.lv b/tests/unit/lvelementstest/data/ParserTest21.lv new file mode 100644 index 00000000..b3a5dec9 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest21.lv @@ -0,0 +1,24 @@ +component TodoApp < Div{ + id: main + + var todoItems: todoItems + + TodoHeader{} + TodoList{ + items: this.todoItems + on remove: (index) => { this.todoItems.splice(index, 1); this.todoItemsChanged() } + on markTodoDone: (index) => { + var todo = todoItems[itemIndex]; + todoItems.splice(itemIndex, 1); + todo.done = !todo.done; + todo.done ? todoItems.push(todo) : todoItems.unshift(todo); + this.todoItemsChanged() + } + } + + TodoForm{ + onAddItem(name) => { + this.todoItems.unshift({ index: todoItems.length+1, value: name, done: false }) + } + } +} \ No newline at end of file diff --git a/tests/unit/lvelementstest/data/ParserTest21.lv.js b/tests/unit/lvelementstest/data/ParserTest21.lv.js new file mode 100644 index 00000000..f53a809e --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest21.lv.js @@ -0,0 +1,57 @@ +var Div = imports.get('Div') +var TodoForm = imports.get('TodoForm') +var TodoHeader = imports.get('TodoHeader') +var TodoList = imports.get('TodoList') + +module.exports["TodoApp"] = class TodoApp extends Div{ + + constructor(){ + super() + this.__initialize() + } + + __initialize(){ + this.ids = {} + + var main = this + this.ids["main"] = main + + Element.addProperty(this, 'todoItems', { type: "var", notify: "todoItemsChanged" }) + this.todoItems = todoItems + + + Element.assignDefaultProperty(this, [ + (function(parent){ + this.setParent(parent) + return this + }.bind(new TodoHeader())(this)), + (function(parent){ + this.setParent(parent) + Element.assignPropertyExpression(this, + 'items', + function(){ return this.todoItems}.bind(this), + [ + [ this, 'todoItemsChanged' ] + ] + ) + this.on('remove', function(index){ this.todoItems.splice(index, 1); this.todoItemsChanged() }.bind(this)); + this.on('markTodoDone', function(index){ + var todo = todoItems[itemIndex]; + todoItems.splice(itemIndex, 1); + todo.done = !todo.done; + todo.done ? todoItems.push(todo) : todoItems.unshift(todo); + this.todoItemsChanged() + }.bind(this)); + return this + }.bind(new TodoList())(this)), + (function(parent){ + this.setParent(parent) + onAddItem(name) => { + this.todoItems.unshift({ index: todoItems.length+1, value: name, done: false }) + } + return this + }.bind(new TodoForm())(this)) + ]) + } + +} diff --git a/tests/unit/lvelementstest/data/ParserTest22.lv b/tests/unit/lvelementstest/data/ParserTest22.lv new file mode 100644 index 00000000..57135b76 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest22.lv @@ -0,0 +1,7 @@ +component A { + var x : this.y ? (function(x){ + return x + 20 + })(100) : 15 + + bool y: true +} \ No newline at end of file diff --git a/tests/unit/lvelementstest/data/ParserTest22.lv.js b/tests/unit/lvelementstest/data/ParserTest22.lv.js new file mode 100644 index 00000000..be90cd12 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest22.lv.js @@ -0,0 +1,25 @@ + +module.exports["A"] = class A extends Element{ + + constructor(){ + super() + this.__initialize() + } + + __initialize(){ + Element.addProperty(this, 'x', { type: "var", notify: "xChanged" }) + Element.addProperty(this, 'y', { type: "bool", notify: "yChanged" }) + Element.assignPropertyExpression(this, + 'x', + function(){ return this.y ? (function(x){ + return x + 20 + })(100) : 15 + }.bind(this), + [ + [ this, 'yChanged' ] + ] + ) + this.y = true + } + +} \ No newline at end of file diff --git a/tests/unit/lvelementstest/data/ParserTest23.lv b/tests/unit/lvelementstest/data/ParserTest23.lv new file mode 100644 index 00000000..2954d0d9 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest23.lv @@ -0,0 +1,13 @@ +component A { + function c(){ + return Element { + var x: { + var d = Element { + var y : 10 + } + + return d.y + } + } + } +} \ No newline at end of file diff --git a/tests/unit/lvelementstest/data/ParserTest23.lv.js b/tests/unit/lvelementstest/data/ParserTest23.lv.js new file mode 100644 index 00000000..bfd4304f --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest23.lv.js @@ -0,0 +1,29 @@ +module.exports["A"] = class A extends Element{ + + constructor(){ + super() + this.__initialize() + } + + __initialize(){ + } + + function c(){ + return (function(parent){ + this.setParent(parent) + Element.addProperty(this, 'x', { type: 'var', notify: 'xChanged' }) + this.x = (function(){ + var d = (function(parent){ + this.setParent(parent) + Element.addProperty(this, 'y', { type: 'var', notify: 'yChanged' }) + this.y = 10 + return this + }.bind(new Element())(null)) + + return d.y + }()) + + return this + }.bind(new Element())(null)) + } +} \ No newline at end of file diff --git a/tests/unit/lvelementstest/jspropertytest.cpp b/tests/unit/lvelementstest/jspropertytest.cpp index 9445063d..19ecd61f 100644 --- a/tests/unit/lvelementstest/jspropertytest.cpp +++ b/tests/unit/lvelementstest/jspropertytest.cpp @@ -406,7 +406,7 @@ void JsPropertyTest::propertyTypes(){ QVERIFY(!o.isNull()); e->set("objectProperty", ScopedValue(engine, o)); Object::Accessor lo(e->objectProperty()); - QCOMPARE(lo.get(ScopedValue(engine, std::string("a"))).toInt32(engine), 2); + QCOMPARE(lo.get(engine, ScopedValue(engine, std::string("a"))).toInt32(engine), 2); QVERIFY(e->objectProperty() == o); e->set("localValueProperty", ScopedValue(engine, 200.0)); @@ -485,7 +485,7 @@ void JsPropertyTest::propertyTypes(){ QVERIFY(e->stdStringProperty() == std::string("abcd")); QVERIFY(e->callableProperty().call(engine, Function::Parameters(0)).toInt32(engine) == 700); Object::Accessor lop(e->objectProperty()); - QVERIFY(lop.get(ScopedValue(engine, std::string("b"))).toInt32(engine) == 7); + QVERIFY(lop.get(engine, ScopedValue(engine, std::string("b"))).toInt32(engine) == 7); QVERIFY(e->localValueProperty().toStdString(engine) == "abcd"); QVERIFY(ScopedValue(engine, e->valueProperty()).toStdString(engine) == "abcd"); QVERIFY(e->bufferProperty().size() == 8); diff --git a/tests/unit/lvelementstest/jstupletest.cpp b/tests/unit/lvelementstest/jstupletest.cpp index b4053e1f..ec7684e5 100644 --- a/tests/unit/lvelementstest/jstupletest.cpp +++ b/tests/unit/lvelementstest/jstupletest.cpp @@ -52,8 +52,8 @@ void JsTupleTest::propertyAdditionTest(){ int totalPropertiesChanged = lo.get(engine, "length").toInt32(engine); QVERIFY(totalPropertiesChanged == 2); - QVERIFY(lo.get(0).toStdString(engine) == "p"); - QVERIFY(lo.get(1).toStdString(engine) == "x"); + QVERIFY(lo.get(engine, 0).toStdString(engine) == "p"); + QVERIFY(lo.get(engine, 1).toStdString(engine) == "x"); }); } diff --git a/tests/unit/lvelementstest/lvelementstest.pro b/tests/unit/lvelementstest/lvelementstest.pro index 9ec887e8..76d34c1c 100644 --- a/tests/unit/lvelementstest/lvelementstest.pro +++ b/tests/unit/lvelementstest/lvelementstest.pro @@ -6,6 +6,7 @@ CONFIG += console testcase linkLocalLibrary(lvbase, lvbase) linkLocalLibrary(lvelements, lvelements) +include($$PROJECT_ROOT/project/3rdparty/v8.pri) include($$PWD/lvelementsstubs/lvelementsstubs.pri) HEADERS += \ @@ -111,4 +112,4 @@ DISTFILES += \ data/ParserTest8.lv \ data/ParserTest8.lv.js \ data/ParserTest9.lv \ - data/ParserTest9.lv.js \ No newline at end of file + data/ParserTest9.lv.js diff --git a/tests/unit/lvelementstest/lvparsetest.cpp b/tests/unit/lvelementstest/lvparsetest.cpp index 87e82e31..f1ab6f53 100644 --- a/tests/unit/lvelementstest/lvparsetest.cpp +++ b/tests/unit/lvelementstest/lvparsetest.cpp @@ -23,267 +23,121 @@ void LvParseTest::initTestCase(){ m_scriptPath = lv::ApplicationContext::instance().releasePath() + "/data"; } -void LvParseTest::constructorParseTest(){ - std::string contents = m_fileSession->readFromFile(m_scriptPath + "/ParserTest1.lv"); - std::string expect = m_fileSession->readFromFile(m_scriptPath + "/ParserTest1.lv.js"); - - el::LanguageParser::Ptr parser = el::LanguageParser::createForElements(); - - std::string conversion = parser->toJs(contents); - - el::LanguageParser::AST* conversionAST = parser->parse(conversion); - el::LanguageParser::AST* expectedAST = parser->parse(expect); - - el::LanguageParser::ComparisonResult compare = parser->compare(expect, expectedAST, conversion, conversionAST); - - parser->destroy(conversionAST); - parser->destroy(expectedAST); - QVERIFY(compare.isEqual()); +void LvParseTest::constructorParseTest(){ + parseTestTemplate("ParserTest1"); } void LvParseTest::functionParseTest(){ - std::string contents = m_fileSession->readFromFile(m_scriptPath + "/ParserTest2.lv"); - std::string expect = m_fileSession->readFromFile(m_scriptPath + "/ParserTest2.lv.js"); - - el::LanguageParser::Ptr parser = el::LanguageParser::createForElements(); - - std::string conversion = parser->toJs(contents); - - el::LanguageParser::AST* conversionAST = parser->parse(conversion); - el::LanguageParser::AST* expectedAST = parser->parse(expect); - - el::LanguageParser::ComparisonResult compare = parser->compare(expect, expectedAST, conversion, conversionAST); - - parser->destroy(conversionAST); - parser->destroy(expectedAST); - - QVERIFY(compare.isEqual()); + parseTestTemplate("ParserTest2"); } void LvParseTest::nestingAndShortIdParseTest(){ - std::string contents = m_fileSession->readFromFile(m_scriptPath + "/ParserTest3.lv"); - std::string expect = m_fileSession->readFromFile(m_scriptPath + "/ParserTest3.lv.js"); - - el::LanguageParser::Ptr parser = el::LanguageParser::createForElements(); - - std::string conversion = parser->toJs(contents); - - el::LanguageParser::AST* conversionAST = parser->parse(conversion); - el::LanguageParser::AST* expectedAST = parser->parse(expect); - - el::LanguageParser::ComparisonResult compare = parser->compare(expect, expectedAST, conversion, conversionAST); - - parser->destroy(conversionAST); - parser->destroy(expectedAST); - - QVERIFY(compare.isEqual()); + parseTestTemplate("ParserTest3"); } void LvParseTest::scopeParseTest(){ - std::string contents = m_fileSession->readFromFile(m_scriptPath + "/ParserTest4.lv"); - std::string expect = m_fileSession->readFromFile(m_scriptPath + "/ParserTest4.lv.js"); - - el::LanguageParser::Ptr parser = el::LanguageParser::createForElements(); - - std::string conversion = parser->toJs(contents); - - el::LanguageParser::AST* conversionAST = parser->parse(conversion); - el::LanguageParser::AST* expectedAST = parser->parse(expect); - - el::LanguageParser::ComparisonResult compare = parser->compare(expect, expectedAST, conversion, conversionAST); - - parser->destroy(conversionAST); - parser->destroy(expectedAST); - - QVERIFY(compare.isEqual()); + parseTestTemplate("ParserTest4"); } void LvParseTest::propertyNewExpressionParseTest(){ - std::string contents = m_fileSession->readFromFile(m_scriptPath + "/ParserTest5.lv"); - std::string expect = m_fileSession->readFromFile(m_scriptPath + "/ParserTest5.lv.js"); - - el::LanguageParser::Ptr parser = el::LanguageParser::createForElements(); - - std::string conversion = parser->toJs(contents, "ParserTest5"); - - el::LanguageParser::AST* conversionAST = parser->parse(conversion); - el::LanguageParser::AST* expectedAST = parser->parse(expect); - - el::LanguageParser::ComparisonResult compare = parser->compare(expect, expectedAST, conversion, conversionAST); - - parser->destroy(conversionAST); - parser->destroy(expectedAST); - - QVERIFY(compare.isEqual()); + parseTestTemplate("ParserTest5"); } void LvParseTest::propertyDeclarationParseTest(){ - std::string contents = m_fileSession->readFromFile(m_scriptPath + "/ParserTest6.lv"); - std::string expect = m_fileSession->readFromFile(m_scriptPath + "/ParserTest6.lv.js"); - - el::LanguageParser::Ptr parser = el::LanguageParser::createForElements(); - - std::string conversion = parser->toJs(contents, "ParserTest6"); - - el::LanguageParser::AST* conversionAST = parser->parse(conversion); - el::LanguageParser::AST* expectedAST = parser->parse(expect); - - el::LanguageParser::ComparisonResult compare = parser->compare(expect, expectedAST, conversion, conversionAST); - - parser->destroy(conversionAST); - parser->destroy(expectedAST); - - QVERIFY(compare.isEqual()); + parseTestTemplate("ParserTest6"); } void LvParseTest::propertyExpressionsParseTest(){ - std::string contents = m_fileSession->readFromFile(m_scriptPath + "/ParserTest7.lv"); - std::string expect = m_fileSession->readFromFile(m_scriptPath + "/ParserTest7.lv.js"); - - el::LanguageParser::Ptr parser = el::LanguageParser::createForElements(); - - std::string conversion = parser->toJs(contents, "ParserTest7"); - - el::LanguageParser::AST* conversionAST = parser->parse(conversion); - el::LanguageParser::AST* expectedAST = parser->parse(expect); - - el::LanguageParser::ComparisonResult compare = parser->compare(expect, expectedAST, conversion, conversionAST); - - parser->destroy(conversionAST); - parser->destroy(expectedAST); - - QVERIFY(compare.isEqual()); + parseTestTemplate("ParserTest7"); } void LvParseTest::taggedStringParseTest(){ - std::string contents = m_fileSession->readFromFile(m_scriptPath + "/ParserTest8.lv"); - std::string expect = m_fileSession->readFromFile(m_scriptPath + "/ParserTest8.lv.js"); - - el::LanguageParser::Ptr parser = el::LanguageParser::createForElements(); - - std::string conversion = parser->toJs(contents, "ParserTest8"); - - el::LanguageParser::AST* conversionAST = parser->parse(conversion); - el::LanguageParser::AST* expectedAST = parser->parse(expect); - - el::LanguageParser::ComparisonResult compare = parser->compare(expect, expectedAST, conversion, conversionAST); - - parser->destroy(conversionAST); - parser->destroy(expectedAST); - - QVERIFY(compare.isEqual()); + parseTestTemplate("ParserTest8"); } void LvParseTest::instanceParseTest(){ - std::string contents = m_fileSession->readFromFile(m_scriptPath + "/ParserTest9.lv"); - std::string expect = m_fileSession->readFromFile(m_scriptPath + "/ParserTest9.lv.js"); - - el::LanguageParser::Ptr parser = el::LanguageParser::createForElements(); - - std::string conversion = parser->toJs(contents, "ParserTest9"); - - el::LanguageParser::AST* conversionAST = parser->parse(conversion); - el::LanguageParser::AST* expectedAST = parser->parse(expect); - - el::LanguageParser::ComparisonResult compare = parser->compare(expect, expectedAST, conversion, conversionAST); - - parser->destroy(conversionAST); - parser->destroy(expectedAST); - - QVERIFY(compare.isEqual()); + parseTestTemplate("ParserTest9"); } void LvParseTest::namespaceInheritance() { - std::string contents = m_fileSession->readFromFile(m_scriptPath + "/ParserTest10.lv"); - std::string expect = m_fileSession->readFromFile(m_scriptPath + "/ParserTest10.lv.js"); - - el::LanguageParser::Ptr parser = el::LanguageParser::createForElements(); - - std::string conversion = parser->toJs(contents, "ParserTest10"); - - el::LanguageParser::AST* conversionAST = parser->parse(conversion); - el::LanguageParser::AST* expectedAST = parser->parse(expect); - - el::LanguageParser::ComparisonResult compare = parser->compare(expect, expectedAST, conversion, conversionAST); - - parser->destroy(conversionAST); - parser->destroy(expectedAST); - - QVERIFY(compare.isEqual()); + parseTestTemplate("ParserTest10"); } void LvParseTest::testComplexPropertyAssignment() { - std::string contents = m_fileSession->readFromFile(m_scriptPath + "/ParserTest11.lv"); - std::string expect = m_fileSession->readFromFile(m_scriptPath + "/ParserTest11.lv.js"); - - el::LanguageParser::Ptr parser = el::LanguageParser::createForElements(); - - std::string conversion = parser->toJs(contents, "ParserTest11"); - - el::LanguageParser::AST* conversionAST = parser->parse(conversion); - - el::LanguageParser::AST* expectedAST = parser->parse(expect); - - el::LanguageParser::ComparisonResult compare = parser->compare(expect, expectedAST, conversion, conversionAST); - - parser->destroy(conversionAST); - parser->destroy(expectedAST); - - QVERIFY(compare.isEqual()); + parseTestTemplate("ParserTest11"); } void LvParseTest::testSimplePropertyAssignment() { - std::string contents = m_fileSession->readFromFile(m_scriptPath + "/ParserTest12.lv"); - std::string expect = m_fileSession->readFromFile(m_scriptPath + "/ParserTest12.lv.js"); - - el::LanguageParser::Ptr parser = el::LanguageParser::createForElements(); - - std::string conversion = parser->toJs(contents, "ParserTest12"); + parseTestTemplate("ParserTest12"); +} - el::LanguageParser::AST* conversionAST = parser->parse(conversion); - el::LanguageParser::AST* expectedAST = parser->parse(expect); +void LvParseTest::testScenarioTest(){ + parseTestTemplate("ParserTest13"); +} - el::LanguageParser::ComparisonResult compare = parser->compare(expect, expectedAST, conversion, conversionAST); +void LvParseTest::nestedLanguageScannerTest(){ + parseTestTemplate("ParserTest14"); +} - parser->destroy(conversionAST); - parser->destroy(expectedAST); +void LvParseTest::nestedFunctionAssignment() +{ + parseTestTemplate("ParserTest15"); +} - QVERIFY(compare.isEqual()); +void LvParseTest::arrowFunctionElement() +{ + parseTestTemplate("ParserTest16"); } -void LvParseTest::testScenarioTest(){ - std::string contents = m_fileSession->readFromFile(m_scriptPath + "/ParserTest13.lv"); -// std::string expect = m_fileSession->readFromFile(m_scriptPath + "/ParserTest10.lv.js"); +void LvParseTest::todoListItemSmall() +{ + parseTestTemplate("ParserTest17"); +} - el::LanguageParser::Ptr parser = el::LanguageParser::createForElements(); +void LvParseTest::todoList() +{ + parseTestTemplate("ParserTest18"); +} - std::string conversion = parser->toJs(contents, "ParserTest11"); +void LvParseTest::todoListItem() +{ + parseTestTemplate("ParserTest19"); +} - el::LanguageParser::AST* conversionAST = parser->parse(conversion); -// vlog() << conversion; +void LvParseTest::todoForm() +{ + parseTestTemplate("ParserTest20"); +} -// el::LanguageParser::AST* expectedAST = parser->parse(expect); -// el::LanguageParser::ComparisonResult compare = parser->compare(expect, expectedAST, conversion, conversionAST); +void LvParseTest::todoApp() +{ + parseTestTemplate("ParserTest21"); +} -// parser->destroy(conversionAST); -// parser->destroy(expectedAST); +void LvParseTest::complexTernaryOperator() +{ + parseTestTemplate("ParserTest22"); +} - // QVERIFY(compare.isEqual()); +void LvParseTest::doublyNestedElement() +{ + parseTestTemplate("ParserTest23"); } -void LvParseTest::nestedLanguageScannerTest(){ - std::string contents = m_fileSession->readFromFile(m_scriptPath + "/ParserTest14.lv"); - std::string expect = m_fileSession->readFromFile(m_scriptPath + "/ParserTest14.lv.js"); +void LvParseTest::parseTestTemplate(std::string name) +{ + std::string contents = m_fileSession->readFromFile(m_scriptPath + "/" + name + ".lv"); + std::string expect = m_fileSession->readFromFile(m_scriptPath + "/" + name + ".lv.js"); el::LanguageParser::Ptr parser = el::LanguageParser::createForElements(); - std::string conversion = parser->toJs(contents, "ParserTest14"); + std::string conversion = parser->toJs(contents, name); el::LanguageParser::AST* conversionAST = parser->parse(conversion); el::LanguageParser::AST* expectedAST = parser->parse(expect); diff --git a/tests/unit/lvelementstest/lvparsetest.h b/tests/unit/lvelementstest/lvparsetest.h index 21802090..f7fb9fa9 100644 --- a/tests/unit/lvelementstest/lvparsetest.h +++ b/tests/unit/lvelementstest/lvparsetest.h @@ -31,8 +31,19 @@ private slots: void testSimplePropertyAssignment(); void testScenarioTest(); void nestedLanguageScannerTest(); + void nestedFunctionAssignment(); + void arrowFunctionElement(); + void todoListItemSmall(); + void todoList(); + void todoListItem(); + void todoForm(); + void todoApp(); + void complexTernaryOperator(); + void doublyNestedElement(); private: + void parseTestTemplate(std::string name); + lv::LockedFileIOSession::Ptr m_fileSession; std::string m_scriptPath; }; diff --git a/tests/unit/lvelementstest/main.cpp b/tests/unit/lvelementstest/main.cpp index bd37597b..830ae11a 100644 --- a/tests/unit/lvelementstest/main.cpp +++ b/tests/unit/lvelementstest/main.cpp @@ -49,8 +49,7 @@ int main(int argc, char *argv[]){ QCoreApplication app(argc, argv); app.setAttribute(Qt::AA_Use96Dpi, true); - std::string blobsPath = lv::ApplicationContext::instance().applicationPath() + "/../../../../bin/external/v8/"; - lv::el::Engine::InitializeScope initializer(blobsPath); + lv::el::Engine::InitializeScope initializer(""); return lv::TestRunner::runTests(argc, argv); } diff --git a/tests/unit/lvelementstest/mlnodetojstest.cpp b/tests/unit/lvelementstest/mlnodetojstest.cpp index cb52acc8..35fa9282 100644 --- a/tests/unit/lvelementstest/mlnodetojstest.cpp +++ b/tests/unit/lvelementstest/mlnodetojstest.cpp @@ -63,12 +63,12 @@ void MLNodeToJsTest::jsConvertTest(){ int oaLen = loa.get(engine, "length").toInt32(engine); QVERIFY(oaLen == 3); - QVERIFY(loa.get(0).isInt()); - QVERIFY(loa.get(0).toInt32(engine) == 100); - QVERIFY(loa.get(1).isString()); - QVERIFY(loa.get(1).toStdString(engine) == "200"); - QVERIFY(loa.get(2).isBool()); - QVERIFY(loa.get(2).toBool(engine) == false); + QVERIFY(loa.get(engine, 0).isInt()); + QVERIFY(loa.get(engine, 0).toInt32(engine) == 100); + QVERIFY(loa.get(engine, 1).isString()); + QVERIFY(loa.get(engine, 1).toStdString(engine) == "200"); + QVERIFY(loa.get(engine, 2).isBool()); + QVERIFY(loa.get(engine, 2).toBool(engine) == false); QVERIFY(lo.get(engine, "bool").isBool()); QVERIFY(lo.get(engine, "bool").toBool(engine) == true); From dba1cc6b5ac151cd97e6520d81eb90262e0f4a5f Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 4 May 2021 12:07:30 +0300 Subject: [PATCH 17/91] Updated ProjectAddEntry style. --- application/qml/ProjectAddEntry.qml | 123 ++++++++++++++++++---------- 1 file changed, 80 insertions(+), 43 deletions(-) diff --git a/application/qml/ProjectAddEntry.qml b/application/qml/ProjectAddEntry.qml index 3475b385..d30515ab 100644 --- a/application/qml/ProjectAddEntry.qml +++ b/application/qml/ProjectAddEntry.qml @@ -18,6 +18,8 @@ import QtQuick 2.3 import editor 1.0 import editor.private 1.0 import base 1.0 +import visual.input 1.0 as Input +import workspace 1.0 as Workspace Rectangle{ id: root @@ -28,66 +30,101 @@ Rectangle{ signal accepted(ProjectEntry entry, string name, bool isFile) signal canceled() + property QtObject style: QtObject{ + property color background: "#02070b" + property double borderWidth: 1 + property color borderColor: "#0f1921" + property double radius: 5 + + property QtObject headerStyle: Input.TextStyle{} + property QtObject inputStyle: Input.InputBoxStyle{} + + property QtObject applyButton: Item{} + } + clip: true width: 500 - height: 80 - radius: 5 - color:"#02070b" - border.width: 1 - border.color: "#0f1921" + height: 60 + heading.height + + radius: style.radius + color: style.background + border.width: style.borderWidth + border.color: style.borderColor + + property string heading: 'Add ' + (root.isFile ? 'file' : 'directory') + ' in ' + (root.entry ? root.entry.path : '') + property string extension: '' + + function __accept(){ + if ( inputBox.text === '' ){ + root.__cancel() + } else { + var txt = inputBox.text + if ( root.extension.length > 0 ){ + if ( !txt.endsWith('.' + root.extension) ){ + txt += '.' + root.extension + } + } + + root.accepted(root.entry, txt, root.isFile) + inputBox.text = '' + root.extension = '' + root.parent.parent.box = null + } + } + + function __cancel(){ + root.parent.parent.box = null + inputBox.text = '' + root.canceled() + } + + function setInitialValue(value){ + inputBox.text = value + } opacity: root.visible ? 1 : 0 Behavior on opacity{ NumberAnimation{ duration: 250} } - Text{ + Input.Label{ + id: heading anchors.top: parent.top anchors.topMargin: 14 anchors.left: parent.left anchors.leftMargin: 14 - text: 'Add ' + (root.isFile ? 'file' : 'directory') + ' in ' + (root.entry ? root.entry.path : '') - font.family: 'Open Sans, Arial, sans-serif' - font.pixelSize: 12 - font.weight: Font.Normal - color: "#afafaf" + anchors.right: parent.right + anchors.rightMargin: 14 + text: root.heading + wrapMode: Text.WordWrap + textStyle: root.style.headerStyle } - Rectangle{ + + Input.InputBox{ + id: inputBox anchors.bottom: parent.bottom anchors.bottomMargin: 10 anchors.left: parent.left anchors.leftMargin: 14 - width: parent.width - 28 + width: parent.width - 55 height: 28 - color: "#0b1319" - border.width: 1 - border.color: "#0c1720" - - TextInput{ - id: addEntryInput - anchors.left: parent.left - anchors.leftMargin: 10 - anchors.right: parent.right - anchors.rightMargin: 10 - anchors.verticalCenter: parent.verticalCenter - color: '#aaa' - text: '' - font.family: 'Open Sans, Arial, sans-serif' - font.pixelSize: 12 - font.weight: Font.Normal - selectByMouse: true - - Keys.onReturnPressed: { - root.accepted(root.entry, text, root.isFile) - root.parent.parent.box = null - } - Keys.onEscapePressed: { - root.parent.parent.box = null - root.canceled() - } - MouseArea{ - anchors.fill: parent - acceptedButtons: Qt.NoButton - cursorShape: Qt.IBeamCursor + style: root.style.inputStyle + + Keys.onPressed: { + if ( event.key === Qt.Key_Return || event.key === Qt.Key_Enter ){ + root.__accept() + } else if ( event.key === Qt.Key_Escape ){ + root.__cancel() } } } + + Workspace.Button{ + anchors.right: parent.right + anchors.rightMargin: 10 + anchors.bottom: parent.bottom + anchors.bottomMargin: 12 + width: 30 + height: 25 + content: root.style.applyButton + onClicked: root.__accept() + } } From cf78fc6b9cfa53924d143bc8e0c3aa820d09b64d Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 4 May 2021 12:08:23 +0300 Subject: [PATCH 18/91] Added support for initialising main file in empty project. --- application/qml/ProjectEnvironment.qml | 33 +++++++++++++++++++++++++- application/qml/StartupBox.qml | 2 +- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/application/qml/ProjectEnvironment.qml b/application/qml/ProjectEnvironment.qml index b369b560..df50436b 100644 --- a/application/qml/ProjectEnvironment.qml +++ b/application/qml/ProjectEnvironment.qml @@ -246,8 +246,39 @@ Item{ function openProject(url, callback){ root.wizards.checkUnsavedFiles(function(){ project.closeProject() - project.openProject(url) + var path = Fs.UrlInfo.toLocalFile(url) + + project.openProject(url) + + if ( !project.active ){ + var message = 'Project has no file to run. Would you like to create one?' + var createFile = function(mbox){ + root.wizards.addFile( + project.dir(), + { + 'extension': 'qml', + 'heading' : 'Add main file in ' + project.dir() + }, + function(file){ + project.setActive(file.path) + } + ) + mbox.close() + } + + lk.layers.window.dialogs.message(message, { + button1Name : 'Yes', + button1Function : createFile, + button3Name : 'No', + button3Function : function(mbox){ mbox.close() }, + returnPressed : createFile + }) + + } + + + if ( callback ) callback(path) // lk.openProjectInstance(url) diff --git a/application/qml/StartupBox.qml b/application/qml/StartupBox.qml index 95cddb5f..e8f54441 100644 --- a/application/qml/StartupBox.qml +++ b/application/qml/StartupBox.qml @@ -261,7 +261,7 @@ Rectangle{ anchors.fill: parent hoverEnabled: true onClicked: { - project.openProject(model.path) + lk.layers.workspace.wizards.openProject(model.path) } } From 32d4ad7c1f29064248d8b43a0d5704d06668b1d3 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 4 May 2021 15:22:58 +0300 Subject: [PATCH 19/91] window layer: Added support for styling MessageBox. --- application/application.qrc | 1 - application/qml/MessageDialogButton.qml | 48 ---------------- application/qml/MessageDialogConfirm.qml | 70 +++++++++++++++++++++-- application/qml/MessageDialogInternal.qml | 26 +++++++-- application/qml/window.qml | 25 +++++++- application/qml/workspace.qml | 18 +++++- 6 files changed, 126 insertions(+), 62 deletions(-) delete mode 100644 application/qml/MessageDialogButton.qml diff --git a/application/application.qrc b/application/application.qrc index a8ea9464..1d30a9ce 100644 --- a/application/application.qrc +++ b/application/application.qrc @@ -3,7 +3,6 @@ qml/LogWindow.qml qml/Top.qml qml/ProjectEnvironment.qml - qml/MessageDialogButton.qml qml/MessageDialogInternal.qml qml/ProjectNavigation.qml qml/ProjectAddEntry.qml diff --git a/application/qml/MessageDialogButton.qml b/application/qml/MessageDialogButton.qml deleted file mode 100644 index f28b3e0c..00000000 --- a/application/qml/MessageDialogButton.qml +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ - -import QtQuick 2.3 - -Rectangle{ - id: root - - property alias text: buttonLabel.text - property var callback : function(){} - - signal clicked() - - color: buttonMouseArea.containsMouse ? "#11212c" : "#0b151c" - width: 100 - height: 30 - - Text{ - id: buttonLabel - anchors.centerIn: parent - text: "" - color: "#ccc" - font.pixelSize: 12 - font.family: "Open Sans, sans-serif" - font.weight: Font.Light - } - MouseArea{ - id: buttonMouseArea - anchors.fill: parent - hoverEnabled: true - onClicked: { - root.clicked() - } - } -} diff --git a/application/qml/MessageDialogConfirm.qml b/application/qml/MessageDialogConfirm.qml index d7343eb6..44e1687d 100644 --- a/application/qml/MessageDialogConfirm.qml +++ b/application/qml/MessageDialogConfirm.qml @@ -55,23 +55,85 @@ MessageDialogInternal{ aitem.forceActiveFocus() } - MessageDialogButton{ + property Component buttonStyle: Rectangle{ + id: dialogButton + + property alias text: buttonLabel.text + property var callback : function(){} + + signal clicked() + onClicked: parent.clicked() + + color: buttonMouseArea.containsMouse ? "#11212c" : "#0b151c" + width: 100 + height: 30 + + Text{ + id: buttonLabel + anchors.centerIn: parent + text: "" + color: "#ccc" + font.pixelSize: 12 + font.family: "Open Sans, sans-serif" + font.weight: Font.Light + } + MouseArea{ + id: buttonMouseArea + anchors.fill: parent + hoverEnabled: true + onClicked: { + dialogButton.clicked() + } + } + } + + Loader{ id: messageBoxButton1 + + property string text: '' + property var callback: function(){} + signal clicked() + visible : text !== '' + sourceComponent: root.buttonStyle + onItemChanged: { + if ( item ) + item.text = Qt.binding(function(){ return messageBoxButton1.text } ) + } onClicked: messageBoxButton1.callback(root) } - MessageDialogButton{ + Loader{ id: messageBoxButton2 - anchors.centerIn: parent + + property string text: '' + property var callback: function(){} + signal clicked() + + anchors.horizontalCenter: parent.horizontalCenter visible : text !== '' + sourceComponent: root.buttonStyle + onItemChanged: { + if ( item ) + item.text = Qt.binding(function(){ return messageBoxButton2.text } ) + } onClicked: messageBoxButton2.callback(root) } - MessageDialogButton{ + Loader{ id: messageBoxButton3 + + property string text: '' + property var callback: function(){} + signal clicked() + anchors.right: parent.right visible : text !== '' + sourceComponent: root.buttonStyle + onItemChanged: { + if ( item ) + item.text = Qt.binding(function(){ return messageBoxButton3.text } ) + } onClicked: messageBoxButton3.callback(root) } } diff --git a/application/qml/MessageDialogInternal.qml b/application/qml/MessageDialogInternal.qml index a62b2e68..7d5c0dea 100644 --- a/application/qml/MessageDialogInternal.qml +++ b/application/qml/MessageDialogInternal.qml @@ -38,12 +38,30 @@ Rectangle{ Keys.onEscapePressed: root.escapePressed(root) anchors.centerIn: parent - color: "#fff" + color: style.background + border.width: style.borderWidth + border.color: style.borderColor + radius: style.radius + width: 400 height: messageLabel.height < 100 ? messageLabel.height + 100 : 200 focus: true opacity: root.visible ? 1 : 0 + property QtObject style: QtObject{ + property color background: "#02070b" + property color borderColor: "#0c151c" + property int borderWidth: 1 + property int radius: 5 + property color textColor: "#fff" + property font font : Qt.font({ + family: 'Open Sans, sans-serif', + weight: Font.Normal, + italic: false, + pixelSize: 12 + }) + } + Behavior on opacity{ NumberAnimation{ duration: 250} } ScrollView{ @@ -87,10 +105,8 @@ Rectangle{ wrapMode: Text.WordWrap - color: "#ccc" - font.pixelSize: 12 - font.family: "Open Sans, sans-serif" - font.weight: Font.Light + color: root.style.textColor + font: root.style.font } } diff --git a/application/qml/window.qml b/application/qml/window.qml index 3b4b1b13..dfdd9e57 100644 --- a/application/qml/window.qml +++ b/application/qml/window.qml @@ -39,6 +39,24 @@ ApplicationWindow{ property QtObject dialogs : QtObject{ + property QtObject messageStyle : QtObject{ + property QtObject box: QtObject{ + property color background: "#02070b" + property color borderColor: "#0c151c" + property int borderWidth: 1 + property int radius: 5 + property color textColor: "#fff" + property font font : Qt.font({ + family: 'Open Sans, sans-serif', + weight: Font.Normal, + italic: false, + pixelSize: 12 + }) + } + property Component button: null + + } + function saveFile(options, callback){ var title = options.title ? options.title : "Pleace choose a file"; var filters = options.filters ? options.filters : ["All files (*)"] @@ -77,6 +95,10 @@ ApplicationWindow{ function message(message, options){ var ob = overlayBoxFactory.createObject(root) ob.box = messageDialogConfirmFactory.createObject() + ob.box.style = root.dialogs.messageStyle.box + if ( root.dialogs.messageStyle.button ) + ob.box.buttonStyle = root.dialogs.messageStyle.button + ob.box.show(message, options) return ob } @@ -213,9 +235,6 @@ ApplicationWindow{ MessageDialogConfirm{ anchors.fill: parent - color: "#02070b" - border.width: 1 - border.color: "#0c151c" } } diff --git a/application/qml/workspace.qml b/application/qml/workspace.qml index 42b6010f..dd27d91d 100644 --- a/application/qml/workspace.qml +++ b/application/qml/workspace.qml @@ -388,9 +388,16 @@ Item{ runSpace: root.runSpace } - property color paneSplitterColor: "transparent" + property Component messageDialogButton: Workspace.TextButton{ + height: 28 + width: 100 + style: lk.layers.workspace.themes.current.formButtonStyle + onClicked: parent.clicked() + } + property color paneSplitterColor: "transparent" property bool documentsReloaded : false + Connections{ target: lk.layers.window function onIsActiveChanged(isActive){ @@ -411,6 +418,7 @@ Item{ Connections{ target: lk + function onLayerReady(layer){ if ( layer.name === 'workspace' ){ layer.commands.add(root, { @@ -437,6 +445,14 @@ Item{ removePaneBox.style.iconColorAlternate = layer.themes.current.colorScheme.topIconColorAlternate paneSplitterColor = layer.themes.current.paneSplitterColor contextMenu.style = layer.themes.current.popupMenuStyle + + var messageDialogStyle = lk.layers.window.dialogs.messageStyle + messageDialogStyle.box.background = layer.themes.current.colorScheme.middleground + messageDialogStyle.box.borderColor = layer.themes.current.colorScheme.middlegroundBorder + messageDialogStyle.box.borderWidth = 1 + messageDialogStyle.box.textColor = layer.themes.current.colorScheme.foreground + messageDialogStyle.box.font = layer.themes.current.inputLabelStyle.textStyle.font + messageDialogStyle.button = root.messageDialogButton } } } From 7f0d7c26784a8697479c63bb1f0be1970f428e0b Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Wed, 5 May 2021 13:18:36 +0300 Subject: [PATCH 20/91] Timeline: Integrated support for context menu when right clicking TrackTitle and TimelineHeader. --- application/qml/ProjectEnvironment.qml | 2 +- plugins/editqml/qml/ObjectContainer.qml | 2 +- plugins/editqml/qml/PaletteControls.qml | 3 +- plugins/timeline/palettes/TimelinePalette.qml | 34 +++ plugins/timeline/qml/TimelineView.qml | 236 +++++++++++------- plugins/timeline/qml/TrackTitle.qml | 33 +-- plugins/workspace/qml/EditableLabel.qml | 8 + .../qml/WorkspaceControlsExtension.qml | 46 +++- 8 files changed, 250 insertions(+), 114 deletions(-) diff --git a/application/qml/ProjectEnvironment.qml b/application/qml/ProjectEnvironment.qml index df50436b..1edf924a 100644 --- a/application/qml/ProjectEnvironment.qml +++ b/application/qml/ProjectEnvironment.qml @@ -74,7 +74,7 @@ Item{ visible: false onOpen: { root.panes.setActiveItem(projectNavigation.parent.textEdit, projectNavigation.parent) - projectEnvironment.openFile(path, ProjectDocument.EditIfNotOpen) + root.wizards.openFile(path, ProjectDocument.EditIfNotOpen) } onCloseFile: { root.wizards.closeFile(path) diff --git a/plugins/editqml/qml/ObjectContainer.qml b/plugins/editqml/qml/ObjectContainer.qml index e6be5569..049543e0 100644 --- a/plugins/editqml/qml/ObjectContainer.qml +++ b/plugins/editqml/qml/ObjectContainer.qml @@ -239,7 +239,7 @@ Item{ if (child.objectName !== "propertyContainer") continue if (child.title !== propName) continue - if (child.valueContainer.palettesOpened.indexOf(propPalette) !== -1) break + if (child.valueContainer.palettesOpened && child.valueContainer.palettesOpened.indexOf(propPalette) !== -1) break paletteControls.openPaletteByName(propPalette, ef, editor, child.valueContainer) break } diff --git a/plugins/editqml/qml/PaletteControls.qml b/plugins/editqml/qml/PaletteControls.qml index 0642d844..2bc4a7f5 100644 --- a/plugins/editqml/qml/PaletteControls.qml +++ b/plugins/editqml/qml/PaletteControls.qml @@ -136,7 +136,8 @@ QtObject{ newPaletteBox.name = palette.name newPaletteBox.type = palette.type - paletteBoxParent.palettesOpened.push(palette.name) + if ( paletteBoxParent.palettesOpened ) + paletteBoxParent.palettesOpened.push(palette.name) newPaletteBox.documentHandler = editor.documentHandler newPaletteBox.cursorRectangle = editor.getCursorRectangle() newPaletteBox.editorPosition = editor.cursorWindowCoords() diff --git a/plugins/timeline/palettes/TimelinePalette.qml b/plugins/timeline/palettes/TimelinePalette.qml index 305e3cdf..712adf05 100644 --- a/plugins/timeline/palettes/TimelinePalette.qml +++ b/plugins/timeline/palettes/TimelinePalette.qml @@ -23,6 +23,25 @@ CodePalette{ anchors.fill: parent focus : true timelineStyle: theme.timelineStyle + handleContextMenu: function(item){ + if ( item.objectName === 'timelineTrackTitle' ){ + timelineArea.trackTitleRightClicked(item.trackIndex, item) + } else if ( item.objectName === 'timelineOptions' ){ + var pane = null + var p = parent + while ( p ){ + if ( p.paneType !== undefined ){ + break + } + p = p.parent + } + + if ( p ){ + lk.layers.workspace.panes.activateItem(item, p) + lk.layers.workspace.panes.openContextMenu(item, p) + } + } + } onSegmentRightClicked: { var pane = null @@ -37,7 +56,22 @@ CodePalette{ if ( p ){ lk.layers.workspace.panes.activateItem(delegate, p) lk.layers.workspace.panes.openContextMenu(delegate, p) + } + } + onTrackTitleRightClicked: { + var pane = null + var p = parent + while ( p ){ + if ( p.paneType !== undefined ){ + break + } + p = p.parent + } + + if ( p ){ + lk.layers.workspace.panes.activateItem(delegate, p) + lk.layers.workspace.panes.openContextMenu(delegate, p) } } diff --git a/plugins/timeline/qml/TimelineView.qml b/plugins/timeline/qml/TimelineView.qml index f9fc1fce..f1a3cdc2 100644 --- a/plugins/timeline/qml/TimelineView.qml +++ b/plugins/timeline/qml/TimelineView.qml @@ -26,8 +26,143 @@ Rectangle{ property int zoom : 1 property bool interactive: true + + signal mouseHover(int position, int trackIndex) + signal mouseLeave(int position) + signal mouseDoubleClicked(int position, int trackIndex) + signal segmentSelected(Track track, Segment segment) + signal segmentDoubleClicked(Track track, Segment segment, Item delegate) + signal segmentRightClicked(Track track, Segment segment, Item delegate) + signal trackTitleRightClicked(int index, Item delegate) + property SegmentInsertMenu segmentInsertMenu: segmentInsertMenu + property var headerContextMenu: { + + function addTrack(){ + var objectPath = lk.layers.workspace.pluginsPath() + '/lcvcore/VideoTrackFactory.qml' + var objectPathUrl = Fs.UrlInfo.urlFromLocalFile(objectPath) + + var objectComponent = Qt.createComponent(objectPathUrl); + if ( objectComponent.status === Component.Error ){ + throw linkError(new Error(objectComponent.errorString()), timelineArea) + } + + var object = objectComponent.createObject(); + + var videoTrack = object.create() + videoTrack.name = 'Video Track #' + (root.timeline.trackList.totalTracks() + 1) + + root.timeline.appendTrack(videoTrack) + } + + var menuOptions = [{ + name: "Add Video Track", + enabled: true, + action: function(){ + if ( !root.timeline.properties.videoSurface ){ + + var objectPath = lk.layers.workspace.pluginsPath() + '/lcvcore/VideoSurfaceCreator.qml' + var objectPathUrl = Fs.UrlInfo.urlFromLocalFile(objectPath) + + var objectComponent = Qt.createComponent(objectPathUrl); + if ( objectComponent.status === Component.Error ){ + throw linkError(new Error(objectComponent.errorString()), this) + } + + var object = objectComponent.createObject(); + var overlay = lk.layers.window.dialogs.overlayBox(object) + + object.surfaceCreated.connect(function(videoSurface){ + root.timeline.properties.videoSurface = videoSurface + addTrack() + overlay.closeBox() + object.destroy() + }) + + object.cancelled.connect(function(){ + overlay.closeBox() + object.destroy() + }) + } else { + addTrack() + } + } + }, { + name: "Add Keyframe Track", + enabled: true, + action: function(){ + + var objectPath = lk.layers.workspace.pluginsPath() + '/timeline/KeyframeTrackFactory.qml' + var objectPathUrl = Fs.UrlInfo.urlFromLocalFile(objectPath) + + var objectComponent = Qt.createComponent(objectPathUrl); + if ( objectComponent.status === Component.Error ){ + throw linkError(new Error(objectComponent.errorString()), timelineArea) + } + + var object = objectComponent.createObject(); + + var keyframeTrack = object.create() + keyframeTrack.name = 'Keyframe Track #' + (root.timeline.trackList.totalTracks() + 1) + + root.timeline.appendTrack(keyframeTrack) + } + },{ + name: "Save", + enabled: true, + action: function(){ + root.timeline.save() + } + }, { + name: "Save As...", + enabled: true, + action: function(){ + lk.layers.window.dialogs.saveFile({filters : "Json files (*.json)"}, function(path){ + var localFile = Fs.UrlInfo.toLocalFile(path) + root.timeline.saveAs(localFile) + }) + } + }] + + return menuOptions + } + + property var handleContextMenu: function(item){ + if ( item.objectName === 'timelineTrackTitle' ){ + var track = item.timelineArea.timeline.trackList.trackAt(item.trackIndex) + var tr = track + + for ( var i = 0; i < trackTitleContextMenu.toClear.length; ++i ){ + trackTitleContextMenu.removeItem(trackTitleContextMenu.toClear[i]) + } + + for ( var i = 0; i < item.menuOptions.length; ++i ){ + var menuitem = trackTitleContextMenu.insertItem(i, item.menuOptions[i].name) + menuitem.enabled = item.menuOptions[i].enabled + menuitem.triggered.connect(item.menuOptions[i].action.bind(this, track)) + trackTitleContextMenu.toClear.push(menuitem) + } + trackTitleContextMenu.popup() + + } else if ( item.objectName === 'timelineOptions' ){ + + var menuOptions = headerContextMenu + + for ( var i = 0; i < contextMenu.toClear.length; ++i ){ + contextMenu.removeItem(contextMenu.toClear[i]) + } + + for ( var i = 0; i < menuOptions.length; ++i ){ + var menuitem = contextMenu.insertItem(i, menuOptions[i].name) + menuitem.enabled = menuOptions[i].enabled + menuitem.triggered.connect(menuOptions[i].action) + contextMenu.toClear.push(menuitem) + } + contextMenu.popup() + } + } + property QtObject timelineStyle : TimelineStyle{} property Timeline timeline : Timeline{ fps: 30 @@ -55,13 +190,17 @@ Rectangle{ property Component trackTitleDelegate : TrackTitle{ trackIndex: index timelineStyle: root.timelineStyle + timelineArea: root onAddSegment: { segmentInsertMenu.currentTrack = root.timeline.trackList.trackAt(index) } + onRightClicked: root.trackTitleRightClicked(index, trackTitleItem) } property Item timelineOptions : Item{ + objectName: "timelineOptions" anchors.fill: parent + property Item timelineArea: root Icons.MenuIcon{ anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left @@ -72,7 +211,7 @@ Rectangle{ MouseArea{ anchors.fill: parent onClicked: { - contextMenu.popup() + root.handleContextMenu(root.timelineOptions) } } } @@ -146,99 +285,20 @@ Rectangle{ } Menu{ - id: contextMenu + id: trackTitleContextMenu + property var toClear: [] MenuItem { - text: qsTr("Add Video Track") - - function addTrack(){ - var objectPath = lk.layers.workspace.pluginsPath() + '/lcvcore/VideoTrackFactory.qml' - var objectPathUrl = Fs.UrlInfo.urlFromLocalFile(objectPath) - - var objectComponent = Qt.createComponent(objectPathUrl); - if ( objectComponent.status === Component.Error ){ - throw linkError(new Error(objectComponent.errorString()), timelineArea) - } - - var object = objectComponent.createObject(); - - var videoTrack = object.create() - videoTrack.name = 'Video Track #' + (root.timeline.trackList.totalTracks() + 1) - - root.timeline.appendTrack(videoTrack) - } - - onTriggered: { - if ( !root.timeline.properties.videoSurface ){ - - var objectPath = lk.layers.workspace.pluginsPath() + '/lcvcore/VideoSurfaceCreator.qml' - var objectPathUrl = Fs.UrlInfo.urlFromLocalFile(objectPath) - - var objectComponent = Qt.createComponent(objectPathUrl); - if ( objectComponent.status === Component.Error ){ - throw linkError(new Error(objectComponent.errorString()), this) - } - - var object = objectComponent.createObject(); - var overlay = lk.layers.window.dialogs.overlayBox(object) - - object.surfaceCreated.connect(function(videoSurface){ - root.timeline.properties.videoSurface = videoSurface - addTrack() - overlay.closeBox() - object.destroy() - }) - - object.cancelled.connect(function(){ - overlay.closeBox() - object.destroy() - }) - } else { - addTrack() - } - } + text: qsTr("Remove Track") + onTriggered: root.timeline.removeTrack(index) } - MenuItem { - text: qsTr("Add Keyframe Track") - onTriggered: { - var objectPath = lk.layers.workspace.pluginsPath() + '/timeline/KeyframeTrackFactory.qml' - var objectPathUrl = Fs.UrlInfo.urlFromLocalFile(objectPath) - - var objectComponent = Qt.createComponent(objectPathUrl); - if ( objectComponent.status === Component.Error ){ - throw linkError(new Error(objectComponent.errorString()), timelineArea) - } - - var object = objectComponent.createObject(); - - var keyframeTrack = object.create() - keyframeTrack.name = 'Keyframe Track #' + (root.timeline.trackList.totalTracks() + 1) + } - root.timeline.appendTrack(keyframeTrack) - } - } - MenuItem { - text: qsTr("Save") - onTriggered: root.timeline.save() - } - MenuItem { - text: qsTr("Save As...") - onTriggered: { - lk.layers.window.dialogs.saveFile({filters : "Json files (*.json)"}, function(path){ - var localFile = Fs.UrlInfo.toLocalFile(path) - root.timeline.saveAs(localFile) - }) - } - } + Menu{ + id: contextMenu + property var toClear: [] } } - signal mouseHover(int position, int trackIndex) - signal mouseLeave(int position) - signal mouseDoubleClicked(int position, int trackIndex) - signal segmentSelected(Track track, Segment segment) - signal segmentDoubleClicked(Track track, Segment segment, Item delegate) - signal segmentRightClicked(Track track, Segment segment, Item delegate) - Rectangle{ id: timelineOptionsContainer width: timelineLeftHeader.width diff --git a/plugins/timeline/qml/TrackTitle.qml b/plugins/timeline/qml/TrackTitle.qml index f9de07fe..8048b404 100644 --- a/plugins/timeline/qml/TrackTitle.qml +++ b/plugins/timeline/qml/TrackTitle.qml @@ -9,10 +9,16 @@ Item{ width: parent.width height: 25 + objectName: "timelineTrackTitle" + + property Item timelineArea: null property QtObject timelineStyle : null property int trackIndex : 0 + property var menuOptions: null + signal addSegment(int index) + signal rightClicked(int index, Item trackTitleItem) property alias labelColor: editableLabel.textColor property alias borderColor: borderBottom.color @@ -35,8 +41,8 @@ Item{ Icons.MenuIcon{ id: menuIcon - width: 5 - height: 6 + width: 2 + height: 10 anchors.centerIn: parent color: root.timelineStyle.iconColor } @@ -45,7 +51,7 @@ Item{ anchors.fill: parent hoverEnabled: true onClicked: { - contextMenu.popup() + root.timelineArea.handleContextMenu(root) } } } @@ -60,28 +66,11 @@ Item{ onTextChanged: { track.name = text } - } - - Menu{ - id: contextMenu - MenuItem { - text: qsTr("Remove Track") - onTriggered: timelineArea.timeline.removeTrack(index) - } + onRightClicked: root.rightClicked(root.trackIndex, root) } Component.onCompleted: { // load menu for this track type - var menuOptions = timelineArea.timeline.config.trackMenu(track) - if ( !menuOptions ) - return - - var tr = track - - for ( var i = 0; i < menuOptions.length; ++i ){ - var menuitem = contextMenu.insertItem(i, menuOptions[i].name) - menuitem.enabled = menuOptions[i].enabled - menuitem.triggered.connect(menuOptions[i].action.bind(this, track)) - } + root.menuOptions = timelineArea.timeline.config.trackMenu(track) } } diff --git a/plugins/workspace/qml/EditableLabel.qml b/plugins/workspace/qml/EditableLabel.qml index add98853..7718f4ba 100644 --- a/plugins/workspace/qml/EditableLabel.qml +++ b/plugins/workspace/qml/EditableLabel.qml @@ -17,6 +17,8 @@ Item{ property alias boxBackgroundColor: inputBox.color property bool isEditing : false + + signal rightClicked(var mouse) Workspace.Label{ id: labelText @@ -50,11 +52,17 @@ Item{ MouseArea{ anchors.fill: parent visible: !parent.isEditing + acceptedButtons: Qt.LeftButton | Qt.RightButton onDoubleClicked: { parent.isEditing = !parent.isEditing if ( parent.isEditing ) inputBox.selectAll() } + onClicked: { + if ( mouse.button === Qt.RightButton) + root.rightClicked(mouse) + } + } } diff --git a/plugins/workspace/qml/WorkspaceControlsExtension.qml b/plugins/workspace/qml/WorkspaceControlsExtension.qml index 805b504d..ad759c12 100644 --- a/plugins/workspace/qml/WorkspaceControlsExtension.qml +++ b/plugins/workspace/qml/WorkspaceControlsExtension.qml @@ -175,7 +175,51 @@ WorkspaceExtension{ ] } } - } + }, + { + whenItem: 'timelineTrackTitle', + intercept: function(pane, item){ + var track = item.timelineArea.timeline.trackList.trackAt(item.trackIndex) + + var optionsConverted = [] + + for ( var i = 0; i < item.menuOptions.length; ++i ){ + var option = item.menuOptions[i] + optionsConverted.push({ + name : option.name, + action : option.action.bind(item, track), + enabled: option.enabled + }) + } + + optionsConverted.push({ + name : "Remove Track", + action : function(){ item.timelineArea.timeline.removeTrack(item.trackIndex) }, + enabled: true + }) + + return optionsConverted + } + }, + { + whenItem: 'timelineOptions', + intercept: function(pane, item){ + var optionsConverted = [] + + var menuOptions = item.timelineArea.headerContextMenu + + for ( var i = 0; i < menuOptions.length; ++i ){ + var option = menuOptions[i] + optionsConverted.push({ + name : option.name, + action : option.action, + enabled: option.enabled + }) + } + + return optionsConverted + } + }, ] } From 675c50149e096748044790f4f9145880f88c4976 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Wed, 5 May 2021 16:13:30 +0300 Subject: [PATCH 21/91] Timeline: Added ImageSegment support for adjustments --- plugins/lcvcore/qml/EditCvExtension.qml | 2 +- plugins/lcvcore/src/imagesegment.cpp | 118 ++++++++++++++++++++++-- plugins/lcvcore/src/imagesegment.h | 47 +++++++++- 3 files changed, 154 insertions(+), 13 deletions(-) diff --git a/plugins/lcvcore/qml/EditCvExtension.qml b/plugins/lcvcore/qml/EditCvExtension.qml index 7b6b25bd..d7ce3cdc 100644 --- a/plugins/lcvcore/qml/EditCvExtension.qml +++ b/plugins/lcvcore/qml/EditCvExtension.qml @@ -58,7 +58,7 @@ WorkspaceExtension{ { whenItem: 'timelineResizableSegment', intercept: function(pane, item){ - if ( item.currentSegment instanceof Cv.VideoSegment ){ + if ( item.currentSegment instanceof Cv.VideoSegment || item.currentSegment instanceof Cv.ImageSegment ){ var segment = item.currentSegment return [{ name : "Adjust", diff --git a/plugins/lcvcore/src/imagesegment.cpp b/plugins/lcvcore/src/imagesegment.cpp index f6baa162..c690ca9a 100644 --- a/plugins/lcvcore/src/imagesegment.cpp +++ b/plugins/lcvcore/src/imagesegment.cpp @@ -17,17 +17,23 @@ #include "opencv2/core.hpp" #include "opencv2/highgui.hpp" +#include "live/hookcontainer.h" +#include "live/qmlwatcher.h" + namespace lv{ ImageSegment::ImageSegment(QObject *parent) : Segment(parent) , m_videoTrack(nullptr) , m_image(new QMat) + , m_filtersObject(nullptr) + , m_filtersPosition(-1) { } ImageSegment::~ImageSegment(){ delete m_image; + delete m_filtersObject; } void ImageSegment::openFile(){ @@ -42,6 +48,7 @@ void ImageSegment::serialize(QQmlEngine *engine, MLNode &node) const{ Segment::serialize(engine, node); QString filePath = m_file; + QString filtersPath = m_filters; QObject* projectOb = engine->rootContext()->contextProperty("project").value(); Project* project = qobject_cast(projectOb); @@ -50,6 +57,13 @@ void ImageSegment::serialize(QQmlEngine *engine, MLNode &node) const{ if ( filePath.startsWith(project->dir()) ){ filePath = filePath.mid(project->dir().length()); } + + if ( filtersPath.startsWith(project->dir() ) ){ + filtersPath = filtersPath.mid(project->dir().length() + 1); + } + } + if ( !m_filters.isEmpty() ){ + node["filters"] = filtersPath.toStdString(); } node["file"] = filePath.toStdString(); @@ -62,14 +76,25 @@ void ImageSegment::deserialize(Track *track, QQmlEngine *engine, const MLNode &n QString fileName = QString::fromStdString(node["file"].asString()); QFileInfo finfo(fileName); - if ( finfo.isRelative() ){ - QObject* projectOb = engine->rootContext()->contextProperty("project").value(); - Project* project = qobject_cast(projectOb); - if ( project ){ - fileName = QFileInfo(project->dir() + "/" + fileName).canonicalFilePath(); + + + QObject* projectOb = engine->rootContext()->contextProperty("project").value(); + Project* project = qobject_cast(projectOb); + + if ( finfo.isRelative() && project ){ + fileName = QFileInfo(project->dir() + "/" + fileName).canonicalFilePath(); + } + + if ( node.hasKey("filters") ){ + QString filtersPath = QString::fromStdString(node["filters"].asString()); + QFileInfo filterPathInfo(filtersPath); + if ( filterPathInfo.isRelative() ){ + filtersPath = QFileInfo(project->dir() + "/" + filtersPath).canonicalFilePath(); } + setFilters(filtersPath); } + setFile(fileName); } @@ -82,13 +107,16 @@ void ImageSegment::assignTrack(Track *track){ } m_videoTrack = nt; Segment::assignTrack(track); + + if ( m_filtersObject ) + addWatcher(); } void ImageSegment::cursorEnter(qint64 pos){ if ( !m_videoTrack || !m_videoTrack->surface() || !m_image) return; - m_videoTrack->surface()->updateSurface(position() + pos, m_image->cloneMat()); + frameCaptured(m_image->cloneMat(), position() + pos); } void ImageSegment::cursorExit(qint64){ @@ -100,14 +128,88 @@ void ImageSegment::cursorNext(qint64 pos){ if ( !m_videoTrack || !m_videoTrack->surface() || !m_image) return; - m_videoTrack->surface()->updateSurface(position() + pos, m_image->cloneMat()); + frameCaptured(m_image->cloneMat(), position() + pos); } void ImageSegment::cursorMove(qint64 pos){ if ( !m_videoTrack || !m_videoTrack->surface() || !m_image) return; - m_videoTrack->surface()->updateSurface(position() + pos, m_image->cloneMat()); + frameCaptured(m_image->cloneMat(), position() + pos); +} + +void ImageSegment::filtersStreamHandler(QObject *that, const QJSValue &val){ + ImageSegment* vs = static_cast(that); + vs->streamUpdate(val); +} + +void ImageSegment::streamUpdate(const QJSValue &val){ + QMat* frame = static_cast(val.toQObject()); + + if ( m_filtersPosition > -1 ){ + m_videoTrack->surface()->updateSurface(m_filtersPosition, frame); + qint64 processedPosition = m_filtersPosition; + m_filtersPosition = -1; + if ( isProcessing() ){ + setIsProcessing(false); + m_videoTrack->notifyCursorProcessed(processedPosition); + } + } else { + m_videoTrack->refreshPosition(); + } +} + +void ImageSegment::frameCaptured(QMat *frame, qint64 position){ + if ( m_filtersObject ){ + setIsProcessing(true); + m_filtersPosition = position; + m_filtersObject->pull()->push(frame); + } else { + m_videoTrack->surface()->updateSurface(position, frame); + } +} + +void ImageSegment::createFilters(){ + if ( m_filtersObject ){ + m_filtersObject->deleteLater(); + m_filtersObject = nullptr; + } + + if ( !m_filters.isEmpty() ){ + ViewEngine* ve = ViewContext::instance().engine(); + ViewEngine::ComponentResult::Ptr cr = ve->createObject(m_filters, this); + if ( cr->hasError() ){ + QmlError::join(cr->errors).jsThrow(); + return; + } + + QmlStreamFilter* sfilter = qobject_cast(cr->object); + if ( !sfilter ){ + //TODO: + qWarning("Not of filter object."); + } + + m_filtersObject = sfilter; + m_filtersObject->setPull(new QmlStream(m_filtersObject)); + m_filtersObject->result()->stream()->forward(this, &ImageSegment::filtersStreamHandler); + + emit filtersObjectChanged(); + + if ( m_videoTrack ){ + addWatcher(); + } + } +} + +void ImageSegment::addWatcher(){ + HookContainer* hooks = qobject_cast(m_videoTrack->timelineContext()->contextProperty("hooks").value()); + ViewEngine* ve = ViewContext::instance().engine(); + + QmlWatcher* watcher = new QmlWatcher(m_filtersObject); + + //TODO: Generate unique name + watcher->setTarget(m_filtersObject); + watcher->initialize(ve, hooks, m_filters, m_videoTrack->name() + "_" + QString::number(position())); } }// namespace diff --git a/plugins/lcvcore/src/imagesegment.h b/plugins/lcvcore/src/imagesegment.h index e0537f55..00703fb4 100644 --- a/plugins/lcvcore/src/imagesegment.h +++ b/plugins/lcvcore/src/imagesegment.h @@ -3,6 +3,8 @@ #include #include "live/segment.h" +#include "live/qmlstreamfilter.h" + #include "videosurface.h" #include "videotrack.h" @@ -11,7 +13,9 @@ namespace lv{ class ImageSegment : public Segment{ Q_OBJECT - Q_PROPERTY(QString file READ file WRITE setFile NOTIFY fileChanged) + Q_PROPERTY(QString file READ file WRITE setFile NOTIFY fileChanged) + Q_PROPERTY(QString filters READ filters WRITE setFilters NOTIFY filtersChanged) + Q_PROPERTY(lv::QmlStreamFilter* filtersObject READ filtersObject NOTIFY filtersObjectChanged) public: explicit ImageSegment(QObject *parent = nullptr); @@ -31,15 +35,32 @@ class ImageSegment : public Segment{ void cursorNext(qint64 position) override; void cursorMove(qint64 position) override; + const QString& filters() const; + void setFilters(const QString &filters); + + QmlStreamFilter* filtersObject() const; + + static void filtersStreamHandler(QObject* that, const QJSValue& val); + void streamUpdate(const QJSValue& val); + signals: void surfaceChanged(); void imageChanged(); void fileChanged(); + void filtersChanged(); + void filtersObjectChanged(); private: - VideoTrack* m_videoTrack; - QString m_file; - QMat* m_image; + void frameCaptured(QMat* frame, qint64 position); + void createFilters(); + void addWatcher(); + + VideoTrack* m_videoTrack; + QString m_file; + QMat* m_image; + QString m_filters; + lv::QmlStreamFilter* m_filtersObject; + qint64 m_filtersPosition; }; inline const QString& ImageSegment::file() const{ @@ -56,6 +77,24 @@ inline void ImageSegment::setFile(const QString& file){ openFile(); } +inline const QString &ImageSegment::filters() const{ + return m_filters; +} + +inline void ImageSegment::setFilters(const QString& filters){ + if (m_filters == filters) + return; + + m_filters = filters; + emit filtersChanged(); + + createFilters(); +} + +inline QmlStreamFilter *ImageSegment::filtersObject() const{ + return m_filtersObject; +} + }// namespace #endif // IMAGESEGMENT_H From 8617c8bb0192b51ac398c71e4131971aa0dcf488 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Thu, 6 May 2021 10:32:15 +0300 Subject: [PATCH 22/91] lcvimgproc: Added image padding functionality. --- lib/lveditqmljs/src/qmljssettings.cpp | 1 + plugins/lcvimgproc/lcvimgproc.pro | 4 +++- plugins/lcvimgproc/qml/Pad.qml | 18 +++++++++++++++++ plugins/lcvimgproc/qml/live.plugin.json | 3 ++- .../lcvimgproc/qml/palettes/PadPalette.json | 12 +++++++++++ plugins/lcvimgproc/qml/qmldir | 1 + plugins/lcvimgproc/src/qgeometry.cpp | 20 +++++++++++++++++++ plugins/lcvimgproc/src/qgeometry.h | 1 + 8 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 plugins/lcvimgproc/qml/Pad.qml create mode 100644 plugins/lcvimgproc/qml/palettes/PadPalette.json diff --git a/lib/lveditqmljs/src/qmljssettings.cpp b/lib/lveditqmljs/src/qmljssettings.cpp index e9ed2e88..7f2e7441 100644 --- a/lib/lveditqmljs/src/qmljssettings.cpp +++ b/lib/lveditqmljs/src/qmljssettings.cpp @@ -67,6 +67,7 @@ QmlJsSettings::QmlJsSettings(EditorSettings *parent) m_defaultPalettes["qml/QtQuick#Rectangle"] = "RectangleSizePalette"; m_defaultPalettes["qml/fs#VisualFileSelector"] = "VisualFileSelectorPropertiesPalette"; m_defaultPalettes["qml/lcvimgproc#Blend"] = "BlendPalette"; + m_defaultPalettes["qml/lcvimgproc#Pad"] = "PadPalette"; m_defaultPalettes["qml/lcvcore#ImageRead"] = "ImageReadPalette"; m_defaultPalettes["qml/lcvcore#ImageFile"] = "ImageFilePalette"; m_defaultPalettes["qml/lcvcore#BlankImage"] = "BlankImagePalette"; diff --git a/plugins/lcvimgproc/lcvimgproc.pro b/plugins/lcvimgproc/lcvimgproc.pro index fb3ae26e..d44b0f98 100644 --- a/plugins/lcvimgproc/lcvimgproc.pro +++ b/plugins/lcvimgproc/lcvimgproc.pro @@ -54,6 +54,7 @@ OTHER_FILES *= \ DISTFILES += \ qml/Blend.qml \ qml/FaceDetection.qml \ + qml/Pad.qml \ qml/Resize.qml \ qml/ResizeTool.qml \ qml/ResizeWithAspect.qml \ @@ -62,4 +63,5 @@ DISTFILES += \ qml/Scale.qml \ qml/Threshold.qml \ qml/live.package.json \ - qml/live.plugin.json + qml/live.plugin.json \ + qml/palettes/PadPalette.json diff --git a/plugins/lcvimgproc/qml/Pad.qml b/plugins/lcvimgproc/qml/Pad.qml new file mode 100644 index 00000000..ffffc47e --- /dev/null +++ b/plugins/lcvimgproc/qml/Pad.qml @@ -0,0 +1,18 @@ +import QtQuick 2.3 +import base 1.0 +import lcvcore 1.0 +import lcvimgproc 1.0 as Img + +Act{ + id: act + property int left: 0 + property int top: 0 + property int right: 0 + property int bottom: 0 + property color color: "#00000000" + property Mat input: null + + returns: "qml/object" + run: Img.Geometry.pad + args: ["$input", "$color", "$top", "$right", "$bottom", "$left"] +} diff --git a/plugins/lcvimgproc/qml/live.plugin.json b/plugins/lcvimgproc/qml/live.plugin.json index 1f990c1c..a0ea9564 100644 --- a/plugins/lcvimgproc/qml/live.plugin.json +++ b/plugins/lcvimgproc/qml/live.plugin.json @@ -4,6 +4,7 @@ "palettes" : { "palettes/TransformPalette.qml" : "qml/lcvimgproc#TransformImage", "palettes/ThresholdPalette.qml" : "qml/lcvimgproc#Threshold", - "palettes/BlendPalette.json" : "qml/lcvimgproc#Blend" + "palettes/BlendPalette.json" : "qml/lcvimgproc#Blend", + "palettes/PadPalette.json" : "qml/lcvimgproc#Pad" } } diff --git a/plugins/lcvimgproc/qml/palettes/PadPalette.json b/plugins/lcvimgproc/qml/palettes/PadPalette.json new file mode 100644 index 00000000..f00222c3 --- /dev/null +++ b/plugins/lcvimgproc/qml/palettes/PadPalette.json @@ -0,0 +1,12 @@ +{ + "type": "qml/lcvimgproc#Pad", + "properties" : [ + ["input"], + ["top", "IntPalette"], + ["right", "IntPalette"], + ["bottom", "IntPalette"], + ["left", "IntPalette"], + ["result"] + ] +} + diff --git a/plugins/lcvimgproc/qml/qmldir b/plugins/lcvimgproc/qml/qmldir index e8d4e470..a5ccf0e9 100644 --- a/plugins/lcvimgproc/qml/qmldir +++ b/plugins/lcvimgproc/qml/qmldir @@ -14,3 +14,4 @@ RotateTool 1.0 RotateTool.qml Threshold 1.0 Threshold.qml Blend 1.0 Blend.qml FaceDetection 1.0 FaceDetection.qml +Pad 1.0 Pad.qml diff --git a/plugins/lcvimgproc/src/qgeometry.cpp b/plugins/lcvimgproc/src/qgeometry.cpp index 639a6de0..e7891ee7 100644 --- a/plugins/lcvimgproc/src/qgeometry.cpp +++ b/plugins/lcvimgproc/src/qgeometry.cpp @@ -87,6 +87,26 @@ QMat *QGeometry::transform(QMat *input, QMat *m){ return r; } +QMat *QGeometry::pad(QMat *input, QColor color, int top, int right, int bottom, int left){ + if ( !input ) + return nullptr; + + QMat* r = new QMat(input->internal().cols + left + right, input->internal().rows + top + bottom, QMat::CV8U, 4); + + try { + cv::Mat* surface = r->internalPtr(); + cv::Mat surfaceSelect = (*surface)(cv::Rect(left, top, input->internal().cols, input->internal().rows)); + surface->setTo(cv::Scalar(color.blue(), color.green(), color.red(), color.alpha())); + lv::CvExtras::copyTo4Channels(input->internal(), surfaceSelect); + } catch (cv::Exception& e){ + lv::CvExtras::toLocalError(e, lv::ViewEngine::grab(this), this, "Geometry: ").jsThrow(); + delete r; + return nullptr; + } + + return r; +} + QMat *QGeometry::getPerspectiveTransform(QJSValue src, QJSValue dst) { return getPerspectiveTransform(src.toVariant().toList(), dst.toVariant().toList()); diff --git a/plugins/lcvimgproc/src/qgeometry.h b/plugins/lcvimgproc/src/qgeometry.h index 6eb65288..19381ed8 100644 --- a/plugins/lcvimgproc/src/qgeometry.h +++ b/plugins/lcvimgproc/src/qgeometry.h @@ -46,6 +46,7 @@ public slots: QMat* resizeBy(QMat* input, QJSValue ob, int interpolation); QMat* rotate(QMat* input, double degrees); QMat* transform(QMat* input, QMat* m); + QMat* pad(QMat* input, QColor color, int top, int right, int bottom, int left); QMat* getPerspectiveTransform(QJSValue src, QJSValue dst); QMat* getPerspectiveTransform(QVariantList src, QVariantList dst); From 077df01bbb4895476096476f881bea28eecbc182 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Thu, 6 May 2021 12:02:36 +0300 Subject: [PATCH 23/91] Palettes: Added support for dragging into new panes. --- application/qml/workspace.qml | 18 +++++++++-- plugins/editor/qml/PaneDropArea.qml | 2 ++ plugins/editqml/qml/PaletteContainer.qml | 20 +++++++++++++ .../editqml/qml/PaletteContainerHeader.qml | 30 +++++++++++++++---- 4 files changed, 62 insertions(+), 8 deletions(-) diff --git a/application/qml/workspace.qml b/application/qml/workspace.qml index dd27d91d..92b36bf8 100644 --- a/application/qml/workspace.qml +++ b/application/qml/workspace.qml @@ -113,13 +113,19 @@ Item{ w.paneDropArea.visible = true } - paneDropArea.currentPane = pane + if (typeof pane === 'function') { + paneDropArea.paneFactory = pane + } else { + paneDropArea.currentPane = pane + } + paneDropArea.model = mainSplit.createPositioningModel() paneDropArea.visible = true } function __dragFinished(pane){ paneDropArea.currentPane = null + paneDropArea.paneFactory = null paneDropArea.model = [] for ( var i = 0; i < openWindows.length; ++i ){ var w = openWindows[i] @@ -696,8 +702,14 @@ Item{ if ( data.pane === currentPane ) return - var clone = currentPane - root.panes.removePane(currentPane) + var clone = null + if ( currentPane ){ + clone = currentPane + root.panes.removePane(currentPane) + } else { + clone = paneFactory() + } + var parentSplitter = data.pane.parentSplitter var paneIndex = data.pane.parentSplitterIndex() diff --git a/plugins/editor/qml/PaneDropArea.qml b/plugins/editor/qml/PaneDropArea.qml index 56fb10f0..c2e047bf 100644 --- a/plugins/editor/qml/PaneDropArea.qml +++ b/plugins/editor/qml/PaneDropArea.qml @@ -16,6 +16,8 @@ Rectangle{ property int leftPosition: 3 property Item currentPane : null + property var paneFactory: null + property alias model: repeater.model Repeater{ diff --git a/plugins/editqml/qml/PaletteContainer.qml b/plugins/editqml/qml/PaletteContainer.qml index cd48a54d..24f4d2f6 100644 --- a/plugins/editqml/qml/PaletteContainer.qml +++ b/plugins/editqml/qml/PaletteContainer.qml @@ -40,6 +40,7 @@ Rectangle{ property var editorPosition : null property var editor: null property Item pane: null + property Item dragPane: null property bool paletteSwapVisible: false property bool paletteAddVisible: false @@ -240,6 +241,25 @@ Rectangle{ item.moveToNewPane.connect(function(){ paletteContainer.paletteToPane() }) + item.dragToNewPaneStarted.connect(function(){ + lk.layers.workspace.panes.__dragStarted(function(){ + var palettePane = lk.layers.workspace.panes.createPane('palette', {}, [400, 400]) + paletteContainer.dragPane = palettePane + return palettePane + }) + }) + item.dragToNewPaneFinished.connect(function(){ + lk.layers.workspace.panes.__dragFinished() + + var palettePane = paletteContainer.dragPane + paletteContainer.dragPane = null + + paletteContainer.pane = palettePane + + palettePane.paletteContainer = paletteChild + palettePane.title = paletteContainer.title + paletteChild.y = 0 + }) } } } diff --git a/plugins/editqml/qml/PaletteContainerHeader.qml b/plugins/editqml/qml/PaletteContainerHeader.qml index 8e87e45e..95085265 100644 --- a/plugins/editqml/qml/PaletteContainerHeader.qml +++ b/plugins/editqml/qml/PaletteContainerHeader.qml @@ -24,6 +24,8 @@ Rectangle{ signal addPalette() signal viewConnections() signal moveToNewPane() + signal dragToNewPaneStarted() + signal dragToNewPaneFinished() signal collapse() signal rebuild() signal close() @@ -32,21 +34,39 @@ Rectangle{ id: paletteBoxMoveArea anchors.fill: parent - enabled: root.enableMove - cursorShape: enabled ? Qt.SizeAllCursor : Qt.ArrowCursor + enabled: root.enableMove || root.canMoveToNewPane + cursorShape: enabled && !root.canMoveToNewPane ? Qt.SizeAllCursor : Qt.ArrowCursor property point lastMousePos : Qt.point(0, 0) onPressed: { - root.handleMovePress(mouse) - lastMousePos = paletteBoxMoveArea.mapToGlobal(mouse.x, mouse.y) + if ( !root.canMoveToNewPane ){ + root.handleMovePress(mouse) + lastMousePos = paletteBoxMoveArea.mapToGlobal(mouse.x, mouse.y) + } + } onPositionChanged: { - if ( mouse.buttons & Qt.LeftButton ){ + if ( mouse.buttons & Qt.LeftButton && !root.canMoveToNewPane){ var currentMousePos = item.mapToGlobal(mouse.x, mouse.y) root.handleMovePositionChanged(mouse, currentMousePos, lastMousePos) lastMousePos = currentMousePos } } + + drag.target: root.canMoveToNewPane ? draggable : undefined + drag.onActiveChanged: draggable.Drag.active = drag.active + } + + Item { + id: draggable + anchors.fill: parent + visible: root.canMoveToNewPane + Drag.hotSpot.x: 0 + Drag.hotSpot.y: 0 + Drag.mimeData: { "text/plain": root.title } + Drag.dragType: Drag.Automatic + Drag.onDragStarted: root.dragToNewPaneStarted() + Drag.onDragFinished: root.dragToNewPaneFinished() } Item{ From 56f5fca82938acb1a3a70664e00cad3faea7cb31 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Mon, 10 May 2021 18:17:31 +0300 Subject: [PATCH 24/91] ProjectEngironment: Added fix to initialising project. --- application/qml/ProjectEnvironment.qml | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/application/qml/ProjectEnvironment.qml b/application/qml/ProjectEnvironment.qml index 1edf924a..ce9aa650 100644 --- a/application/qml/ProjectEnvironment.qml +++ b/application/qml/ProjectEnvironment.qml @@ -221,11 +221,7 @@ Item{ function openProjectDirViaDialog(callback){ root.wizards.checkUnsavedFiles(function(){ lk.layers.window.dialogs.openDir({}, function(url){ - project.closeProject() - project.openProject(url) - var path = Fs.UrlInfo.toLocalFile(url) - if ( callback ) - callback(path) + root.wizards.openProject(url, callback) // lk.openProjectInstance(url) }) }) @@ -262,6 +258,8 @@ Item{ }, function(file){ project.setActive(file.path) + if ( callback ) + callback(path) } ) mbox.close() @@ -275,12 +273,10 @@ Item{ returnPressed : createFile }) + } else { + if ( callback ) + callback(path) } - - - - if ( callback ) - callback(path) // lk.openProjectInstance(url) }) } From 566e2951017f5db627082b5dd4ce0316ccf121a0 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Mon, 10 May 2021 18:17:52 +0300 Subject: [PATCH 25/91] ViewEngine: Removed hooks. --- lib/lvview/src/viewengine.cpp | 22 ---------------------- lib/lvview/src/viewengine.h | 15 --------------- 2 files changed, 37 deletions(-) diff --git a/lib/lvview/src/viewengine.cpp b/lib/lvview/src/viewengine.cpp index d790e10c..d14e3d7c 100644 --- a/lib/lvview/src/viewengine.cpp +++ b/lib/lvview/src/viewengine.cpp @@ -200,25 +200,6 @@ void ViewEngine::removeErrorHandler(QObject *object){ m_errorHandlers.remove(object); } -/** Added after the compilation is finished, to be run as a callback */ -void ViewEngine::addCompileHook(ViewEngine::CompileHook ch, void *userData){ - CompileHookEntry che; - che.m_hook = ch; - che.m_userData = userData; - - m_compileHooks.append(che); -} - -/** Removes the given compile hook */ -void ViewEngine::removeCompileHook(ViewEngine::CompileHook ch, void *userData){ - for ( auto it = m_compileHooks.begin(); it != m_compileHooks.end(); ++it ){ - if ( it->m_hook == ch && it->m_userData == userData ){ - m_compileHooks.erase(it); - return; - } - } -} - /** Returns the type info for a given meta-object*/ MetaInfo::Ptr ViewEngine::typeInfo(const QMetaObject *key) const{ auto it = m_types.find(key); @@ -410,9 +391,6 @@ void ViewEngine::createObjectAsync( item->setParentItem(parentItem); } - for (auto it = m_compileHooks.begin(); it != m_compileHooks.end(); ++it) - (it->m_hook)(qmlCode, url, obj, it->m_userData); - setIsLoading(false); m_engineMutex->unlock(); diff --git a/lib/lvview/src/viewengine.h b/lib/lvview/src/viewengine.h index 6792c388..3ab3bd95 100644 --- a/lib/lvview/src/viewengine.h +++ b/lib/lvview/src/viewengine.h @@ -95,16 +95,6 @@ class LV_VIEW_EXPORT ViewEngine : public QObject{ ComponentResult& operator=(const ComponentResult&); }; - /** Callback function type to be run after the engine finishes compiling */ - typedef void(*CompileHook)(const QString&, const QUrl&, QObject*, void*); - -private: - class CompileHookEntry{ - public: - CompileHook m_hook; - void* m_userData; - }; - public: explicit ViewEngine(QQmlEngine* engine, QObject *parent = nullptr); ~ViewEngine(); @@ -129,9 +119,6 @@ class LV_VIEW_EXPORT ViewEngine : public QObject{ void registerErrorHandler(QObject* object, ErrorHandler* handler); void removeErrorHandler(QObject* object); - void addCompileHook(CompileHook ch, void* userData); - void removeCompileHook(CompileHook ch, void* userData); - template MetaInfo::Ptr registerQmlTypeInfo( const std::function& serializeFunction, const std::function& deserializeFunction, @@ -226,8 +213,6 @@ public slots: QJSValue m_errorType; PackageGraph* m_packageGraph; - QLinkedList m_compileHooks; - QList m_lastErrors; int m_errorCounter; QMap m_errorHandlers; From cdea580f00580202ed5596ee3522bcaa22557655 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Mon, 10 May 2021 18:19:10 +0300 Subject: [PATCH 26/91] Removed engine hook from ProjectQmlExtension. --- lib/lveditqmljs/src/projectqmlextension.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/lib/lveditqmljs/src/projectqmlextension.cpp b/lib/lveditqmljs/src/projectqmlextension.cpp index 7321d412..3230f9d1 100644 --- a/lib/lveditqmljs/src/projectqmlextension.cpp +++ b/lib/lveditqmljs/src/projectqmlextension.cpp @@ -83,7 +83,6 @@ ProjectQmlExtension::ProjectQmlExtension(QObject *parent) * @brief ProjectQmlExtension destructor */ ProjectQmlExtension::~ProjectQmlExtension(){ - m_engine->removeCompileHook(&ProjectQmlExtension::engineHook, this); for ( auto it = m_codeHandlers.begin(); it != m_codeHandlers.end(); ++it ){ CodeQmlHandler* cqh = *it; cqh->resetProjectQmlExtension(); @@ -126,17 +125,6 @@ void ProjectQmlExtension::componentComplete(){ } } -/** - * \brief Hook that get's executed for each engine recompile, notifying all codeHandlers assigned to this object. - */ -void ProjectQmlExtension::engineHook(const QString &, const QUrl &, QObject *, void* /*data*/){ -// ProjectQmlExtension* that = reinterpret_cast(data); -// for ( auto it = that->m_codeHandlers.begin(); it != that->m_codeHandlers.end(); ++it ){ -// CodeQmlHandler* h = *it; -//// h->updateRuntimeBindings(); -// } -} - /** * \brief Adds a codeHandler to this object. * @@ -194,8 +182,6 @@ void ProjectQmlExtension::setParams(Settings *settings, Project *project, ViewEn m_settings = new QmlJsSettings(editorSettings); editorSettings->syncWithFile(); - m_engine->addCompileHook(&ProjectQmlExtension::engineHook, this); - EditorGlobalObject* editor = static_cast(engine->engine()->rootContext()->contextProperty("editor").value()); if ( !editor ){ qWarning("Failed to find editor global object."); From e43204374c2f5a8af06b84484830db8d1f60b9b1 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Mon, 10 May 2021 18:19:54 +0300 Subject: [PATCH 27/91] CodeHandler: Added support for context when adding item to runtime. --- lib/lveditqmljs/src/codeqmlhandler.cpp | 10 +++++++++- lib/lveditqmljs/src/projectqmlextension.h | 2 -- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/lveditqmljs/src/codeqmlhandler.cpp b/lib/lveditqmljs/src/codeqmlhandler.cpp index b0ef086d..b19e24cc 100644 --- a/lib/lveditqmljs/src/codeqmlhandler.cpp +++ b/lib/lveditqmljs/src/codeqmlhandler.cpp @@ -1297,8 +1297,16 @@ void CodeQmlHandler::addItemToRunTimeImpl(QmlEditFragment *edit, const QString & QString creationPath = m_document->file()->path(); creationPath.replace(".qml", "_a.qml"); + + QQmlContext* creationCtx = nullptr; + if ( bc->type() == QmlBindingChannel::ListIndex || bc->type() == QmlBindingChannel::Object ){ + QObject* creationObj = bc->object(); + if ( creationObj ) + creationCtx = qmlContext(creationObj); + } + QObject* result = QmlEditFragment::createObject( - d->documentInfo(), type + "{}", creationPath + d->documentInfo(), type + "{}", creationPath, nullptr, creationCtx ); if ( !result ) THROW_EXCEPTION(lv::Exception, "Failed to create object: " + type.toStdString(), Exception::toCode("~CreateObject")); diff --git a/lib/lveditqmljs/src/projectqmlextension.h b/lib/lveditqmljs/src/projectqmlextension.h index 3ab6a654..198d3fb9 100644 --- a/lib/lveditqmljs/src/projectqmlextension.h +++ b/lib/lveditqmljs/src/projectqmlextension.h @@ -52,8 +52,6 @@ class LV_EDITQMLJS_EXPORT ProjectQmlExtension : public QObject, public QQmlParse QmlProjectMonitor* scanMonitor(); QmlBindingChannelsDispatcher* channelsDispatcher(); - static void engineHook(const QString& code, const QUrl& file, QObject* result, void *data); - void addCodeQmlHandler(CodeQmlHandler* handler); void removeCodeQmlHandler(CodeQmlHandler* handler); From af168560856edee2c08c352d7b8c25b4ed313d8c Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Mon, 10 May 2021 18:21:26 +0300 Subject: [PATCH 28/91] Added additional timeline palettes. VideoSurfaceView: Added VideoSurfacePalette and VideoSurfacePropertiesPalette. ImageTransform: Added TransformPaletteProperties. --- lib/lveditqmljs/src/qmljssettings.cpp | 15 +- plugins/lcvcore/lcvcore.pro | 2 + plugins/lcvcore/palettes/ImagePalette.qml | 1 - .../lcvcore/palettes/VideoSurfacePalette.qml | 164 ++++++++++++++++++ .../VideoSurfacePropertiesPalette.json | 8 + plugins/lcvcore/qml/EditCvExtension.qml | 1 + plugins/lcvcore/qml/live.plugin.json | 2 + plugins/lcvcore/src/imagesegment.cpp | 7 +- plugins/lcvimgproc/lcvimgproc.pro | 3 +- plugins/lcvimgproc/qml/live.plugin.json | 1 + .../palettes/TransformPaletteProperties.json | 9 + plugins/timeline/palettes/TimelinePalette.qml | 104 +++++++++++ 12 files changed, 309 insertions(+), 8 deletions(-) create mode 100644 plugins/lcvcore/palettes/VideoSurfacePalette.qml create mode 100644 plugins/lcvcore/palettes/VideoSurfacePropertiesPalette.json create mode 100644 plugins/lcvimgproc/qml/palettes/TransformPaletteProperties.json diff --git a/lib/lveditqmljs/src/qmljssettings.cpp b/lib/lveditqmljs/src/qmljssettings.cpp index 7f2e7441..4d05df7c 100644 --- a/lib/lveditqmljs/src/qmljssettings.cpp +++ b/lib/lveditqmljs/src/qmljssettings.cpp @@ -65,24 +65,29 @@ QmlJsSettings::QmlJsSettings(EditorSettings *parent) m_defaultPalettes["qml/lcvcore#VideoFile"] = "VideoFilePropertiesPalette"; m_defaultPalettes["qml/lcvcore#GrayscaleView"] = "GrayscaleViewPalette"; m_defaultPalettes["qml/QtQuick#Rectangle"] = "RectangleSizePalette"; + m_defaultPalettes["qml/timeline#Timeline"] = "TimelinePalette"; m_defaultPalettes["qml/fs#VisualFileSelector"] = "VisualFileSelectorPropertiesPalette"; m_defaultPalettes["qml/lcvimgproc#Blend"] = "BlendPalette"; m_defaultPalettes["qml/lcvimgproc#Pad"] = "PadPalette"; + m_defaultPalettes["qml/lcvimgproc#TransformImage"] = "TransformPaletteProperties"; m_defaultPalettes["qml/lcvcore#ImageRead"] = "ImageReadPalette"; m_defaultPalettes["qml/lcvcore#ImageFile"] = "ImageFilePalette"; m_defaultPalettes["qml/lcvcore#BlankImage"] = "BlankImagePalette"; m_defaultPalettes["qml/lcvcore#DrawSurface"] = "DrawSurfacePalette"; m_defaultPalettes["qml/lcvcore#ImageView"] = "ImageViewPalette"; + m_defaultPalettes["qml/lcvcore#VideoSurfaceView"] = "VideoSurfacePropertiesPalette"; m_defaultPalettes["qml/lcvphoto#HueSaturationLightness"] = "HueSaturationLightnessPalette"; m_defaultPalettes["qml/lcvphoto#Levels"] = "LevelsDefaultPalette"; m_defaultPalettes["qml/lcvphoto#BrightnessAndContrast"] = "BrightnessAndContrastPalette"; m_defaultPalettes["qml/lcvcore#PerspectiveOnBackground"] = "PerspectiveOnBackgroundPropertiesPalette"; - MLNode s = parent->readFor("qmljs"); - if ( s.type() == MLNode::Object ) - fromJson(s); - else - parent->write("qmljs", toJson()); + if (parent){ + MLNode s = parent->readFor("qmljs"); + if ( s.type() == MLNode::Object ) + fromJson(s); + else + parent->write("qmljs", toJson()); + } } QmlJsSettings::~QmlJsSettings(){ diff --git a/plugins/lcvcore/lcvcore.pro b/plugins/lcvcore/lcvcore.pro index c0f17e67..0fc33485 100644 --- a/plugins/lcvcore/lcvcore.pro +++ b/plugins/lcvcore/lcvcore.pro @@ -75,6 +75,8 @@ DISTFILES += \ palettes/VideoFilePropertiesPalette.json \ palettes/ImageViewPalette.json \ palettes/VideoPlayerPalette.qml \ + palettes/VideoSurfacePalette.qml \ + palettes/VideoSurfacePropertiesPalette.json \ qml/BlankImage.qml \ qml/BrushTool.qml \ qml/ColorHistogramView.qml \ diff --git a/plugins/lcvcore/palettes/ImagePalette.qml b/plugins/lcvcore/palettes/ImagePalette.qml index 510c0b3c..e7305b54 100644 --- a/plugins/lcvcore/palettes/ImagePalette.qml +++ b/plugins/lcvcore/palettes/ImagePalette.qml @@ -138,7 +138,6 @@ CodePalette{ } } - ResizeArea{ minimumWidth: 400 minimumHeight: 200 diff --git a/plugins/lcvcore/palettes/VideoSurfacePalette.qml b/plugins/lcvcore/palettes/VideoSurfacePalette.qml new file mode 100644 index 00000000..50e25dfc --- /dev/null +++ b/plugins/lcvcore/palettes/VideoSurfacePalette.qml @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2014-2019 Dinu SV. +** (contact: mail@dinusv.com) +** This file is part of Livekeys Application. +** +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +****************************************************************************/ + +import QtQuick 2.3 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.2 +import live 1.0 +import editor 1.0 +import fs 1.0 as Fs +import lcvcore 1.0 as Cv +import lcvimgproc 1.0 as Img +import workspace 1.0 as Workspace + +CodePalette{ + id: palette + + type : "qml/lcvcore#VideoSurfaceView" + + property QtObject theme: lk.layers.workspace.themes.current + + property QtObject style: QtObject{ + property color toolbarColor: theme.colorScheme.middleground + property color boxColor: theme.colorScheme.background + property color boxBorderColor: theme.colorScheme.backgroundBorder + property real boxRadius: 3 + property QtObject labelStyle: theme.inputLabelStyle + property Component saveButton: theme.buttons.save + } + + item: Item{ + id: paletteItem + width: 500 + height: 300 + + property QtObject videoSurfaceView: null + onVideoSurfaceViewChanged: { + videoSurface = Qt.binding(function(){ return videoSurfaceView.timeline.properties.videoSurface }) + imageView.image = Qt.binding(function(){ return videoSurfaceView.image }) + } + + property var videoSurface: null + onVideoSurfaceChanged: { + if ( videoSurface ){ + var scaleW = (imageView.maxWidth - 10) / videoSurface.imageWidth + var scaleH = (imageView.maxHeight - 10) / videoSurface.imageHeight + var scale = scaleW > scaleH ? scaleH : scaleW + imageView.setScale(scale) + } + } + + Rectangle{ + id: topBar + width: imageView.width > parent.width ? imageView.width : parent.width + height: 30 + color: palette.style.toolbarColor + + Workspace.Button{ + anchors.left: parent.left + anchors.leftMargin: 30 + anchors.verticalCenter: parent.verticalCenter + width: 30 + height: 25 + content: palette.style.saveButton + + onClicked: { + lk.layers.window.dialogs.saveFile({}, function(url){ + var file = Fs.UrlInfo.toLocalFile(url) + Cv.MatIO.write(file, imageView.image, null) + }) + } + } + + Item{ + height: parent.height + width: zoomInfo.width + anchors.left: parent.left + anchors.leftMargin: 70 + Workspace.Label{ + id: zoomInfo + anchors.verticalCenter: parent.verticalCenter + text: Math.floor(imageView.scale * 100) + '%' + } + } + + Item{ + height: parent.height + width: imageInfo.width + anchors.right: parent.right + anchors.rightMargin: 10 + Workspace.Label{ + id: imageInfo + anchors.verticalCenter: parent.verticalCenter + text: { + if ( !imageView.image ) + return '-' + var dim = imageView.image.dimensions() + return dim.width + 'x' + dim.height + ', ' + imageView.image.channels() + ' Ch' + } + } + } + } + + Cv.NavigableImageView{ + id: imageView + anchors.top: parent.top + anchors.topMargin: 31 + + maxWidth: paletteItem.width + maxHeight: paletteItem.height - anchors.topMargin + + style: QtObject{ + property Component scrollStyle: ScrollViewStyle { + transientScrollBars: false + handle: Item { + implicitWidth: 10 + implicitHeight: 10 + Rectangle { + color: "#1f2227" + anchors.fill: parent + } + } + scrollBarBackground: Item{ + implicitWidth: 10 + implicitHeight: 10 + Rectangle{ + anchors.fill: parent + color: 'transparent' + } + } + decrementControl: null + incrementControl: null + frame: Item{} + corner: Rectangle{color: 'transparent'} + } + } + } + + ResizeArea{ + minimumWidth: 400 + minimumHeight: 200 + } + + } + + onInit: { + paletteItem.videoSurfaceView = value + } + onValueFromBindingChanged: { + paletteItem.videoSurfaceView = value + } +} diff --git a/plugins/lcvcore/palettes/VideoSurfacePropertiesPalette.json b/plugins/lcvcore/palettes/VideoSurfacePropertiesPalette.json new file mode 100644 index 00000000..34a33c6f --- /dev/null +++ b/plugins/lcvcore/palettes/VideoSurfacePropertiesPalette.json @@ -0,0 +1,8 @@ +{ + "type": "qml/lcvcore#VideoSurfaceView", + "palettes": ["VideoSurfacePalette"], + "properties" : [ + ["timeline"] + ] +} + diff --git a/plugins/lcvcore/qml/EditCvExtension.qml b/plugins/lcvcore/qml/EditCvExtension.qml index d7ce3cdc..812b8fa7 100644 --- a/plugins/lcvcore/qml/EditCvExtension.qml +++ b/plugins/lcvcore/qml/EditCvExtension.qml @@ -84,6 +84,7 @@ WorkspaceExtension{ 'import QtQuick 2.3\n' + 'import base 1.0\n' + 'import lcvcore 1.0\n' + + 'import lcvimgproc 1.0\n' + 'import lcvphoto 1.0\n' + '\n' + 'StreamFilter{\n' + diff --git a/plugins/lcvcore/qml/live.plugin.json b/plugins/lcvcore/qml/live.plugin.json index 070dd0a4..ea32a7ee 100644 --- a/plugins/lcvcore/qml/live.plugin.json +++ b/plugins/lcvcore/qml/live.plugin.json @@ -7,6 +7,8 @@ "palettes/DrawPalette.qml" : "qml/lcvcore#DrawSurface", "palettes/DrawSurfacePalette.json" : "qml/lcvcore#DrawSurface", "palettes/ImageViewPalette.json" : "qml/lcvcore#ImageView", + "palettes/VideoSurfacePalette.qml" : "qml/lcvcore#VideoSurfaceView", + "palettes/VideoSurfacePropertiesPalette.json" : "qml/lcvcore#VideoSurfaceView", "palettes/VideoCapturePalette.qml": "qml/lcvcore#VideoCapture", "palettes/VideoPlayerPalette.qml": "qml/lcvcore#VideoDecoderView", "palettes/VideoFilePalette.qml": "qml/lcvcore#VideoFile", diff --git a/plugins/lcvcore/src/imagesegment.cpp b/plugins/lcvcore/src/imagesegment.cpp index c690ca9a..b49a5b68 100644 --- a/plugins/lcvcore/src/imagesegment.cpp +++ b/plugins/lcvcore/src/imagesegment.cpp @@ -101,7 +101,7 @@ void ImageSegment::deserialize(Track *track, QQmlEngine *engine, const MLNode &n void ImageSegment::assignTrack(Track *track){ VideoTrack* nt = qobject_cast(track); if ( !nt ){ - Exception e = CREATE_EXCEPTION(lv::Exception, "NumberAnimationSegment needs NumberTrack at '" + track->name().toStdString() + "'.", Exception::toCode("~Track") ); + Exception e = CREATE_EXCEPTION(lv::Exception, "ImageSegment needs NumberTrack at '" + track->name().toStdString() + "'.", Exception::toCode("~Track") ); lv::ViewContext::instance().engine()->throwError(&e, this); return; } @@ -203,6 +203,11 @@ void ImageSegment::createFilters(){ void ImageSegment::addWatcher(){ HookContainer* hooks = qobject_cast(m_videoTrack->timelineContext()->contextProperty("hooks").value()); + if ( !hooks ){ + Exception e = CREATE_EXCEPTION(lv::Exception, "ImageSegment cannot access the hook container.", Exception::toCode("~hooks")); + lv::ViewContext::instance().engine()->throwError(&e, this); + return; + } ViewEngine* ve = ViewContext::instance().engine(); QmlWatcher* watcher = new QmlWatcher(m_filtersObject); diff --git a/plugins/lcvimgproc/lcvimgproc.pro b/plugins/lcvimgproc/lcvimgproc.pro index d44b0f98..7895395a 100644 --- a/plugins/lcvimgproc/lcvimgproc.pro +++ b/plugins/lcvimgproc/lcvimgproc.pro @@ -64,4 +64,5 @@ DISTFILES += \ qml/Threshold.qml \ qml/live.package.json \ qml/live.plugin.json \ - qml/palettes/PadPalette.json + qml/palettes/PadPalette.json \ + qml/palettes/TransformPaletteProperties.json diff --git a/plugins/lcvimgproc/qml/live.plugin.json b/plugins/lcvimgproc/qml/live.plugin.json index a0ea9564..148feccb 100644 --- a/plugins/lcvimgproc/qml/live.plugin.json +++ b/plugins/lcvimgproc/qml/live.plugin.json @@ -3,6 +3,7 @@ "package" : ".", "palettes" : { "palettes/TransformPalette.qml" : "qml/lcvimgproc#TransformImage", + "palettes/TransformPaletteProperties.json" : "qml/lcvimgproc#TransformImage", "palettes/ThresholdPalette.qml" : "qml/lcvimgproc#Threshold", "palettes/BlendPalette.json" : "qml/lcvimgproc#Blend", "palettes/PadPalette.json" : "qml/lcvimgproc#Pad" diff --git a/plugins/lcvimgproc/qml/palettes/TransformPaletteProperties.json b/plugins/lcvimgproc/qml/palettes/TransformPaletteProperties.json new file mode 100644 index 00000000..898cba27 --- /dev/null +++ b/plugins/lcvimgproc/qml/palettes/TransformPaletteProperties.json @@ -0,0 +1,9 @@ +{ + "type": "qml/lcvimgproc#TranformImage", + "palettes" : ["TransformPalette"], + "properties" : [ + ["input"], + ["result", "", "true"] + ] +} + diff --git a/plugins/timeline/palettes/TimelinePalette.qml b/plugins/timeline/palettes/TimelinePalette.qml index 712adf05..aaed2ae7 100644 --- a/plugins/timeline/palettes/TimelinePalette.qml +++ b/plugins/timeline/palettes/TimelinePalette.qml @@ -5,7 +5,9 @@ import editor 1.0 import live 1.0 import lcvcore 1.0 import timeline 1.0 +import workspace 1.0 as Workspace import fs 1.0 as Fs +import visual.input 1.0 as Input CodePalette{ id: palette @@ -15,9 +17,97 @@ CodePalette{ property QtObject defaultTimelineStyle: TimelineStyle{} item: Item{ + id: paletteItem width : 500 height: 200 + property Component timelineConfigComponent: Rectangle{ + anchors.fill: parent + color: "#cc000000" + + Input.Label{ + textStyle: theme.inputStyle.textStyle + text: "Setup Timeline" + anchors.top: parent.top + anchors.topMargin: 20 + anchors.horizontalCenter: parent.horizontalCenter + } + + Item{ + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + anchors.topMargin: 50 + + width: 180 + height: 30 + + Input.Label{ + textStyle: theme.inputStyle.textStyle + text: "Fps:" + anchors.verticalCenter: parent.verticalCenter + } + + Input.InputBox{ + id: fpsInput + style: theme.inputStyle + text: "30" + width: 100 + + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: 80 + } + } + + Item{ + anchors.top: parent.top + anchors.topMargin: 90 + anchors.horizontalCenter: parent.horizontalCenter + width: 180 + height: 30 + + Input.Label{ + textStyle: theme.inputStyle.textStyle + text: "Length:" + anchors.verticalCenter: parent.verticalCenter + } + + Input.InputBox{ + id: lengthInput + style: theme.inputStyle + text: "1000" + width: 100 + + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: 80 + } + } + + Workspace.TextButton{ + text: "Ready" + style: theme.formButtonStyle + anchors.top: parent.top + anchors.topMargin: 160 + anchors.horizontalCenter: parent.horizontalCenter + + width: 100 + height: 25 + + onClicked: { + timelineArea.timeline.fps = parseFloat(fpsInput.text) + timelineArea.timeline.contentLength = parseFloat(lengthInput.text) + + editFragment.writeProperties({ + 'fps' : timelineArea.timeline.fps, + 'contentLength' : timelineArea.timeline.contentLength + }) + + timelineConfig.sourceComponent = null + } + } + } + TimelineView{ id: timelineArea anchors.fill: parent @@ -104,6 +194,11 @@ CodePalette{ } } + Loader{ + id: timelineConfig + anchors.fill: parent + } + ResizeArea{ minimumHeight: 200 minimumWidth: 400 @@ -113,6 +208,15 @@ CodePalette{ onInit: { timelineArea.timeline = value + if ( value ){ + if ( value.fps === 0 || value.contentLength === 0 ){ + timelineConfig.sourceComponent = paletteItem.timelineConfigComponent + } else { + timelineConfig.sourceComponent = null + } + } else { + timelineConfig.sourceComponent = null + } } onValueFromBindingChanged: { timelineArea.timeline = value From 568fefe43d6e272a4506cda68d7142141e1228f0 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Mon, 10 May 2021 22:05:24 +0300 Subject: [PATCH 29/91] Timeline: Fixed crash when segments cause multi refresh to trigger. --- plugins/timeline/src/timeline.cpp | 21 +++++++++++++++------ plugins/timeline/src/timeline.h | 1 + 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/plugins/timeline/src/timeline.cpp b/plugins/timeline/src/timeline.cpp index 404519ac..03c7edf4 100644 --- a/plugins/timeline/src/timeline.cpp +++ b/plugins/timeline/src/timeline.cpp @@ -24,7 +24,7 @@ namespace lv{ namespace{ - static const int WAIT_NOTRACK = -1; + static const int INDEX_NOTRACK = -1; } Timeline::Timeline(QObject *parent) @@ -35,7 +35,8 @@ Timeline::Timeline(QObject *parent) , m_loop(false) , m_isRecording(false) , m_isRunning(false) - , m_waitingForTrackAt(WAIT_NOTRACK) + , m_processingTrackAt(INDEX_NOTRACK) + , m_waitingForTrackAt(INDEX_NOTRACK) , m_isComponentComplete(false) , m_config(new TimelineConfig(this)) , m_trackList(new TrackListModel()) @@ -148,7 +149,7 @@ QString Timeline::positionToLabel(qint64 frameNumber, bool shortZero){ } void Timeline::__tick(){ - if ( m_waitingForTrackAt != WAIT_NOTRACK ){ + if ( m_waitingForTrackAt != INDEX_NOTRACK ){ m_timer.stop(); } else { @@ -162,7 +163,7 @@ void Timeline::__tick(){ } void Timeline::__trackCursorProcessed(Track* track, qint64 position){ - if ( m_waitingForTrackAt == WAIT_NOTRACK ) + if ( m_waitingForTrackAt == INDEX_NOTRACK ) return; if ( position != m_waitingForTrackAt ){ @@ -200,7 +201,7 @@ void Timeline::__trackCursorProcessed(Track* track, qint64 position){ --i; } - m_waitingForTrackAt = WAIT_NOTRACK; + m_waitingForTrackAt = INDEX_NOTRACK; for ( int i = 0; i < m_trackList->totalTracks(); ++i ){ m_trackList->trackAt(i)->cursorPositionProcessed(position); @@ -211,6 +212,8 @@ void Timeline::__trackCursorProcessed(Track* track, qint64 position){ m_timer.start(); } + m_processingTrackAt = INDEX_NOTRACK; + emit cursorPositionProcessed(position); } @@ -382,7 +385,9 @@ void Timeline::signalTrackNameChanged(Track *track){ } void Timeline::refreshPosition(){ - updateCursorPosition(m_cursorPosition); + // Make sure no tracks are being processed to avoid an infinite loop + if ( m_processingTrackAt == INDEX_NOTRACK ) + updateCursorPosition(m_cursorPosition); } void Timeline::load(){ @@ -452,6 +457,8 @@ void Timeline::updateCursorPosition(qint64 position){ if ( m_waitingForTrackAt >= 0 ) return; + m_processingTrackAt = m_cursorPosition; + int i = m_trackList->totalTracks() - 1; while ( i >= 0 ){ Track* tr = m_trackList->trackAt(i); @@ -471,6 +478,8 @@ void Timeline::updateCursorPosition(qint64 position){ --i; } + m_processingTrackAt = INDEX_NOTRACK; + emit cursorPositionProcessed(position); } diff --git a/plugins/timeline/src/timeline.h b/plugins/timeline/src/timeline.h index 1340737e..d83ee29a 100644 --- a/plugins/timeline/src/timeline.h +++ b/plugins/timeline/src/timeline.h @@ -125,6 +125,7 @@ public slots: bool m_loop; bool m_isRecording; bool m_isRunning; + qint64 m_processingTrackAt; qint64 m_waitingForTrackAt; bool m_isComponentComplete; From b0e88c2195c9cf114c50c98bc8267e1e4b8db49d Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 11 May 2021 10:04:31 +0300 Subject: [PATCH 30/91] PropertyWatcher: Fixed an exception being thrown when the property watcher is not yet initialized.. --- lib/lvview/src/qmlpropertywatcher.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/lvview/src/qmlpropertywatcher.cpp b/lib/lvview/src/qmlpropertywatcher.cpp index daa0ea1a..33e2de1e 100644 --- a/lib/lvview/src/qmlpropertywatcher.cpp +++ b/lib/lvview/src/qmlpropertywatcher.cpp @@ -22,7 +22,8 @@ QmlPropertyWatcher::~QmlPropertyWatcher(){ } void QmlPropertyWatcher::propertyChanged() const{ - m_propertyChange(*this); + if ( m_propertyChange ) + m_propertyChange(*this); } }// namespace From b819a032a27278c80e1f01ac68090e204ab18281 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 11 May 2021 10:04:54 +0300 Subject: [PATCH 31/91] Timeline: Fixed fps being set when loading from file. --- plugins/timeline/src/timeline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/timeline/src/timeline.cpp b/plugins/timeline/src/timeline.cpp index 03c7edf4..9d03e1bd 100644 --- a/plugins/timeline/src/timeline.cpp +++ b/plugins/timeline/src/timeline.cpp @@ -296,7 +296,7 @@ void Timeline::deserialize(Timeline *timeline, ViewEngine *engine, const MLNode try{ timeline->m_contentLength = node["length"].asInt(); - timeline->m_fps = node["fps"].asFloat(); + timeline->setFps(node["fps"].asFloat()); TimelineProperties* properties = new TimelineProperties(timeline); timeline->m_properties = properties; From 4594dcde1176d6810478684c803eb8f6b81bb430 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 11 May 2021 10:05:10 +0300 Subject: [PATCH 32/91] CodeHandler: Fixed Context ownership when creating new objects. --- lib/lveditqmljs/src/codeqmlhandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/lveditqmljs/src/codeqmlhandler.cpp b/lib/lveditqmljs/src/codeqmlhandler.cpp index b19e24cc..e45e4a00 100644 --- a/lib/lveditqmljs/src/codeqmlhandler.cpp +++ b/lib/lveditqmljs/src/codeqmlhandler.cpp @@ -1302,7 +1302,7 @@ void CodeQmlHandler::addItemToRunTimeImpl(QmlEditFragment *edit, const QString & if ( bc->type() == QmlBindingChannel::ListIndex || bc->type() == QmlBindingChannel::Object ){ QObject* creationObj = bc->object(); if ( creationObj ) - creationCtx = qmlContext(creationObj); + creationCtx = new QQmlContext(qmlContext(creationObj)); } QObject* result = QmlEditFragment::createObject( From 243c104e4c179ce5db0cc814fc24fa7f61855e8d Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Wed, 12 May 2021 08:17:36 +0300 Subject: [PATCH 33/91] Timeline: Added VideoSegment support for seek and limits when being stretched. --- plugins/lcvcore/src/videosegment.cpp | 86 ++++++++++++++++++---------- plugins/lcvcore/src/videosegment.h | 12 ++++ 2 files changed, 67 insertions(+), 31 deletions(-) diff --git a/plugins/lcvcore/src/videosegment.cpp b/plugins/lcvcore/src/videosegment.cpp index 11651a14..436edde7 100644 --- a/plugins/lcvcore/src/videosegment.cpp +++ b/plugins/lcvcore/src/videosegment.cpp @@ -25,6 +25,9 @@ VideoSegment::VideoSegment(QObject *parent) : Segment(parent) , m_videoTrack(nullptr) , m_capture(new cv::VideoCapture) + , m_videoStart(0) + , m_videoPosition(-1) + , m_videoLength(0) , m_filtersObject(nullptr) , m_filtersPosition(-1) { @@ -39,7 +42,10 @@ void VideoSegment::openFile(){ return; setLabel(m_file.mid(m_file.lastIndexOf('/') + 1)); - m_capture->open(m_file.toStdString()); + if ( m_capture->open(m_file.toStdString()) ){ + m_videoLength = static_cast(m_capture->get(cv::CAP_PROP_FRAME_COUNT)); + updateStrechLimits(); + } } void VideoSegment::serialize(QQmlEngine *engine, MLNode &node) const{ @@ -111,22 +117,7 @@ void VideoSegment::cursorEnter(qint64 pos){ if ( !m_videoTrack || !m_videoTrack->surface() ) return; - if ( pos == 0 ){ - if ( m_capture->grab() ){ - cv::Mat* frame = new cv::Mat; - m_capture->retrieve(*frame); - QMat* mat = new QMat(frame); - frameCaptured(mat, position() + pos); - } - } else { - m_capture->set(cv::CAP_PROP_POS_FRAMES, pos); - if ( m_capture->grab() ){ - cv::Mat* frame = new cv::Mat; - m_capture->retrieve(*frame); - QMat* mat = new QMat(frame); - frameCaptured(mat, position() + pos); - } - } + captureFrame(pos); } void VideoSegment::cursorExit(qint64){ @@ -138,26 +129,14 @@ void VideoSegment::cursorNext(qint64 pos){ if ( !m_videoTrack || !m_videoTrack->surface() ) return; - if ( m_capture->grab() ){ - cv::Mat* frame = new cv::Mat; - m_capture->retrieve(*frame); - QMat* mat = new QMat(frame); - frameCaptured(mat, position() + pos); - } + captureFrame(pos); } void VideoSegment::cursorMove(qint64 pos){ if ( !m_videoTrack || !m_videoTrack->surface() ) return; - m_capture->set(cv::CAP_PROP_POS_FRAMES, pos); - cv::Mat frame; - if ( m_capture->grab() ){ - cv::Mat* frame = new cv::Mat; - m_capture->retrieve(*frame); - QMat* mat = new QMat(frame); - frameCaptured(mat, position() + pos); - } + captureFrame(pos); } void VideoSegment::filtersStreamHandler(QObject *that, const QJSValue &val){ @@ -182,6 +161,46 @@ void VideoSegment::streamUpdate(const QJSValue &val){ } +void VideoSegment::stretchLeftTo(unsigned int pos){ + m_videoStart += static_cast(pos) - static_cast(position()); + Segment::stretchLeftTo(pos); + updateStrechLimits(); +} + +void VideoSegment::stretchRightTo(unsigned int pos){ + Segment::stretchRightTo(pos); + updateStrechLimits(); +} + +void VideoSegment::captureFrame(qint64 segmentPosition){ + qint64 nextPosition = segmentToVideoPosition(segmentPosition); + + if ( nextPosition == m_videoPosition + 1 ){ + if ( m_capture->grab() ){ + m_videoPosition = nextPosition; + + cv::Mat* frame = new cv::Mat; + m_capture->retrieve(*frame); + QMat* mat = new QMat(frame); + frameCaptured(mat, position() + segmentPosition); + } + } else { + m_capture->set(cv::CAP_PROP_POS_FRAMES, nextPosition); + if ( m_capture->grab() ){ + m_videoPosition = nextPosition; + + cv::Mat* frame = new cv::Mat; + m_capture->retrieve(*frame); + QMat* mat = new QMat(frame); + frameCaptured(mat, position() + segmentPosition); + } + } +} + +qint64 VideoSegment::segmentToVideoPosition(qint64 segmentPosition){ + return segmentPosition + m_videoStart; +} + void VideoSegment::frameCaptured(QMat *frame, qint64 position){ if ( m_filtersObject ){ setIsProcessing(true); @@ -192,6 +211,11 @@ void VideoSegment::frameCaptured(QMat *frame, qint64 position){ } } +void VideoSegment::updateStrechLimits(){ + setMaxStretchLeft(m_videoStart); + setMaxStretchRight(m_videoLength - m_videoStart); +} + void VideoSegment::createFilters(){ if ( m_filtersObject ){ m_filtersObject->deleteLater(); diff --git a/plugins/lcvcore/src/videosegment.h b/plugins/lcvcore/src/videosegment.h index 8113761a..a4904cf9 100644 --- a/plugins/lcvcore/src/videosegment.h +++ b/plugins/lcvcore/src/videosegment.h @@ -51,19 +51,31 @@ public slots: void setFile(const QString& file); void setFilters(const QString& filters); + virtual void stretchLeftTo(unsigned int position) override; + virtual void stretchRightTo(unsigned int position) override; + signals: void fileChanged(); void filtersChanged(); void filtersObjectChanged(); private: + qint64 segmentToVideoPosition(qint64 segmentPosition); + + void captureFrame(qint64 segmentPosition); void frameCaptured(QMat* frame, qint64 position); + + void updateStrechLimits(); + void createFilters(); void addWatcher(); VideoTrack* m_videoTrack; QString m_file; cv::VideoCapture* m_capture; + qint64 m_videoStart; + qint64 m_videoPosition; + qint64 m_videoLength; QString m_filters; QmlStreamFilter* m_filtersObject; qint64 m_filtersPosition; From 59bdca27e55f9c461e59fcec2f66553140a4d44a Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Fri, 14 May 2021 13:28:05 +0300 Subject: [PATCH 34/91] Added support for adjustments with nodes. --- plugins/lcvcore/qml/EditCvExtension.qml | 137 ++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/plugins/lcvcore/qml/EditCvExtension.qml b/plugins/lcvcore/qml/EditCvExtension.qml index 812b8fa7..49b37507 100644 --- a/plugins/lcvcore/qml/EditCvExtension.qml +++ b/plugins/lcvcore/qml/EditCvExtension.qml @@ -163,6 +163,143 @@ WorkspaceExtension{ lk.layers.workspace.extensions.editqml.shapeAllInEditor(pane) } } + },{ + name : "Adjust Using Nodes", + action : function(){ + if ( !project.isDirProject() ){ + lk.layers.workspace.messages.pushError( + "Cannot adjust for non-directory project. Open the project as a directory to adjust.", 3000 + ) + } + + if ( segment.filters === '' ){ + lk.layers.workspace.wizards.addFile( + project.dir(), + { + 'extension': 'qml', + 'heading' : 'Add adjustments file in ' + project.dir() + }, + function(file){ + var pd = project.openTextFile(file, Document.Edit) + pd.insert( + 0, + pd.contentLength(), + 'import QtQuick 2.3\n' + + 'import base 1.0\n' + + 'import lcvcore 1.0\n' + + 'import lcvimgproc 1.0\n' + + 'import lcvphoto 1.0\n' + + '\n' + + 'StreamFilter{\n' + + ' id: streamFilter\n' + + ' StreamValue{\n' + + ' id: videoFrame\n' + + ' valueType: \'qml/object\'\n' + + ' }\n' + + ' StreamSink{\n' + + ' id: videoSurface\n' + + ' input: videoFrame.value\n' + + ' }\n' + + '}\n', + ProjectDocument.Palette + ) + pd.save() + + var pane = lk.layers.workspace.panes.createPane('editor', {}, [400, 0]) + + var panes = lk.layers.workspace.panes.findPanesByType('editor') + if ( panes.length === 0 ){ + var foundPane = panes[0] + var foundPaneIndex = foundPane.parentSplitterIndex + + lk.layers.workspace.panes.splitPaneVerticallyWith(foundPane.parentSplitter, foundPaneIndex, pane) + } else { + var containerUsed = lk.layers.workspace.panes.container + if ( containerUsed.orientation === Qt.Vertical ){ + for ( var i = 0; i < containerUsed.panes.length; ++i ){ + if ( containerUsed.panes[i].paneType === 'splitview' && + containerUsed.panes[i].orientation === Qt.Horizontal ) + { + containerUsed = containerUsed.panes[i] + break + } + } + } + lk.layers.workspace.panes.splitPaneHorizontallyWith(containerUsed, 0, pane) + } + + pane.document = pd + segment.filters = file.path + + var editor = pane + var codeHandler = editor.documentHandler.codeHandler + var rootPosition = lk.layers.workspace.extensions.editqml.rootPosition = codeHandler.findRootPosition() + lk.layers.workspace.extensions.editqml.shapeImports(editor, codeHandler) + lk.layers.workspace.extensions.editqml.shapeRootObject(editor, editor.documentHandler.codeHandler, function(){ + var paletteRoot = codeHandler.findPalettes(rootPosition) + var oc = lk.layers.workspace.extensions.editqml.paletteControls.shapePalette(editor, paletteRoot, 0) + oc.contentWidth = Qt.binding(function(){ + return oc.containerContentWidth > oc.editorContentWidth ? oc.containerContentWidth : oc.editorContentWidth + }) + + editor.editor.rootShaped = true + + var pb = lk.layers.workspace.extensions.editqml.paletteControls.openPaletteByName('NodePalette', oc.editingFragment, editor, oc.groupsContainer.children[0], oc) + + pb.child.resize(oc.width - 50, editor.height - 170) + }) + } + ) + + } else { + var path = segment.filters + + var pd = project.openTextFile(path, Document.Edit) + + var pane = lk.layers.workspace.panes.createPane('editor', {}, [400, 0]) + + var panes = lk.layers.workspace.panes.findPanesByType('editor') + if ( panes.length === 0 ){ + var foundPane = panes[0] + var foundPaneIndex = foundPane.parentSplitterIndex + lk.layers.workspace.panes.splitPaneVerticallyWith(foundPane.parentSplitter, foundPaneIndex, pane) + } else { + var containerUsed = lk.layers.workspace.panes.container + if ( containerUsed.orientation === Qt.Vertical ){ + for ( var i = 0; i < containerUsed.panes.length; ++i ){ + if ( containerUsed.panes[i].paneType === 'splitview' && + containerUsed.panes[i].orientation === Qt.Horizontal ) + { + containerUsed = containerUsed.panes[i] + break + } + } + } + lk.layers.workspace.panes.splitPaneHorizontallyWith(containerUsed, 0, pane) + } + + pane.document = pd + + var editor = pane + var codeHandler = editor.documentHandler.codeHandler + var rootPosition = lk.layers.workspace.extensions.editqml.rootPosition = codeHandler.findRootPosition() + lk.layers.workspace.extensions.editqml.shapeImports(editor, codeHandler) + lk.layers.workspace.extensions.editqml.shapeRootObject(editor, editor.documentHandler.codeHandler, function(){ + var paletteRoot = codeHandler.findPalettes(rootPosition) + var oc = lk.layers.workspace.extensions.editqml.paletteControls.shapePalette(editor, paletteRoot, 0) + oc.contentWidth = Qt.binding(function(){ + return oc.containerContentWidth > oc.editorContentWidth ? oc.containerContentWidth : oc.editorContentWidth + }) + + editor.editor.rootShaped = true + + var pb = lk.layers.workspace.extensions.editqml.paletteControls.openPaletteByName('NodePalette', oc.editingFragment, editor, oc.groupsContainer.children[0], oc) + + pb.child.resize(oc.width - 50, editor.height - 170) + }) + + } + } }] } From 7da90edd981fef6424210ebcaae9294d9ddd34f0 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Fri, 14 May 2021 13:28:21 +0300 Subject: [PATCH 35/91] lcvcore: Added export to CvExtras. --- plugins/lcvcore/src/cvextras.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/lcvcore/src/cvextras.h b/plugins/lcvcore/src/cvextras.h index bf340ced..afefb5d0 100644 --- a/plugins/lcvcore/src/cvextras.h +++ b/plugins/lcvcore/src/cvextras.h @@ -4,10 +4,11 @@ #include "opencv2/core.hpp" #include "live/exception.h" #include "live/qmlerror.h" +#include "qlcvcoreglobal.h" namespace lv{ -class CvExtras{ +class Q_LCVCORE_EXPORT CvExtras{ public: CvExtras(); From e1f854b8fa9fc73a6a33af2214099862ae7a091f Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Fri, 14 May 2021 13:28:34 +0300 Subject: [PATCH 36/91] Fixed ObjectGraph AddQmlBox style. --- plugins/workspace/nodeeditor/qml/ObjectGraph.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/workspace/nodeeditor/qml/ObjectGraph.qml b/plugins/workspace/nodeeditor/qml/ObjectGraph.qml index 15149e8c..3de0613a 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectGraph.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectGraph.qml @@ -274,6 +274,7 @@ Rectangle{ var addBox = lk.layers.editor.environment.createEditorBox( addBoxItem, rect, cursorCoords, lk.layers.editor.environment.placement.bottom ) + addBox.color = 'transparent' addBoxItem.accept = function(type, data){ var opos = documentHandler.codeHandler.addItem( From 6eb6317fec2e8954843001d2a74fbc6d2c4e6f43 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Fri, 14 May 2021 13:28:59 +0300 Subject: [PATCH 37/91] Timeline: Added cursor position change after manually adding new segments. --- plugins/lcvcore/qml/VideoTrackExtension.qml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/plugins/lcvcore/qml/VideoTrackExtension.qml b/plugins/lcvcore/qml/VideoTrackExtension.qml index 0cffe7bc..ffb4c89e 100644 --- a/plugins/lcvcore/qml/VideoTrackExtension.qml +++ b/plugins/lcvcore/qml/VideoTrackExtension.qml @@ -40,6 +40,10 @@ QtObject{ if ( segment.surface ) segment.surface = timeline.properties.videoSurface currentTrack.addSegment(segment) + if ( timeline.cursorPosition === segment.position ){ + timeline.cursorPosition += segment.length + } + overlay.closeBox() }) @@ -83,6 +87,9 @@ QtObject{ if ( segment.surface ) segment.surface = timeline.properties.videoSurface + if ( timeline.cursorPosition === segment.position ){ + timeline.cursorPosition += segment.length + } currentTrack.addSegment(segment) overlay.closeBox() }) @@ -126,6 +133,9 @@ QtObject{ if ( segment.surface ) segment.surface = timeline.properties.videoSurface + if ( timeline.cursorPosition === segment.position ){ + timeline.cursorPosition += segment.length + } currentTrack.addSegment(segment) overlay.closeBox() }) From 085115e2171a115cab5c98569c5bb233c906db35 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Fri, 14 May 2021 13:30:10 +0300 Subject: [PATCH 38/91] Timeline: Added predefined VideoSurfaces. Timeline: Fixed Image and Video segment creation Styling. --- plugins/lcvcore/palettes/ImagePalette.qml | 3 +- .../lcvcore/palettes/VideoSurfacePalette.qml | 3 +- plugins/lcvcore/qml/ImageSegmentCreator.qml | 13 +++-- .../lcvcore/qml/ScriptVideoSegmentCreator.qml | 15 ++++-- .../qml/VideoCaptureSegmentCreator.qml | 15 ++++-- plugins/lcvcore/qml/VideoSurfaceCreator.qml | 52 +++++++++++++++---- 6 files changed, 79 insertions(+), 22 deletions(-) diff --git a/plugins/lcvcore/palettes/ImagePalette.qml b/plugins/lcvcore/palettes/ImagePalette.qml index e7305b54..e1b23e19 100644 --- a/plugins/lcvcore/palettes/ImagePalette.qml +++ b/plugins/lcvcore/palettes/ImagePalette.qml @@ -40,10 +40,11 @@ CodePalette{ property Component saveButton: theme.buttons.save } - item: Item{ + item: Rectangle{ id: paletteItem width: 500 height: 300 + color: '#111' property QtObject image: null onImageChanged: { diff --git a/plugins/lcvcore/palettes/VideoSurfacePalette.qml b/plugins/lcvcore/palettes/VideoSurfacePalette.qml index 50e25dfc..f26c1673 100644 --- a/plugins/lcvcore/palettes/VideoSurfacePalette.qml +++ b/plugins/lcvcore/palettes/VideoSurfacePalette.qml @@ -40,10 +40,11 @@ CodePalette{ property Component saveButton: theme.buttons.save } - item: Item{ + item: Rectangle{ id: paletteItem width: 500 height: 300 + color: '#111' property QtObject videoSurfaceView: null onVideoSurfaceViewChanged: { diff --git a/plugins/lcvcore/qml/ImageSegmentCreator.qml b/plugins/lcvcore/qml/ImageSegmentCreator.qml index 2212266c..55c9a35b 100644 --- a/plugins/lcvcore/qml/ImageSegmentCreator.qml +++ b/plugins/lcvcore/qml/ImageSegmentCreator.qml @@ -7,7 +7,9 @@ import workspace 1.0 as Workspace Rectangle{ width: 300 height: 80 - color: '#03070a' + color: '#141b20' + border.width: 1 + border.color: '#232b30' signal segmentCreated(Segment segment) signal cancelled() @@ -45,14 +47,19 @@ Rectangle{ } } - - TextButton{ + Workspace.TextButton{ anchors.right: parent.right anchors.rightMargin: 10 radius: 5 width: 30 height: 30 text: 'X' + style: Workspace.TextButtonStyle{ + backgroundColor: '#3f444d' + backgroundHoverColor: Qt.lighter('#3f444d', 1.2) + borderColor: '#575b63' + } + onClicked: { parent.cancelled() } diff --git a/plugins/lcvcore/qml/ScriptVideoSegmentCreator.qml b/plugins/lcvcore/qml/ScriptVideoSegmentCreator.qml index 81c29985..54452efb 100644 --- a/plugins/lcvcore/qml/ScriptVideoSegmentCreator.qml +++ b/plugins/lcvcore/qml/ScriptVideoSegmentCreator.qml @@ -8,7 +8,9 @@ import fs 1.0 as Fs Rectangle{ width: 300 height: 80 - color: '#03070a' + color: '#141b20' + border.width: 1 + border.color: '#232b30' signal segmentCreated(Segment segment) signal cancelled() @@ -23,7 +25,7 @@ Rectangle{ anchors.topMargin: 14 anchors.left: parent.left anchors.leftMargin: 14 - text: 'Add video segment' + text: 'Add script video segment' font.family: 'Open Sans, Arial, sans-serif' font.pixelSize: 12 font.weight: Font.Normal @@ -52,14 +54,19 @@ Rectangle{ } } - - TextButton{ + Workspace.TextButton{ anchors.right: parent.right anchors.rightMargin: 10 radius: 5 width: 30 height: 30 text: 'X' + style: Workspace.TextButtonStyle{ + backgroundColor: '#3f444d' + backgroundHoverColor: Qt.lighter('#3f444d', 1.2) + borderColor: '#575b63' + } + onClicked: { parent.cancelled() } diff --git a/plugins/lcvcore/qml/VideoCaptureSegmentCreator.qml b/plugins/lcvcore/qml/VideoCaptureSegmentCreator.qml index 489e1499..7018b56d 100644 --- a/plugins/lcvcore/qml/VideoCaptureSegmentCreator.qml +++ b/plugins/lcvcore/qml/VideoCaptureSegmentCreator.qml @@ -7,7 +7,9 @@ import workspace 1.0 as Workspace Rectangle{ width: 300 height: 80 - color: '#03070a' + color: '#141b20' + border.width: 1 + border.color: '#232b30' signal segmentCreated(Segment segment) signal cancelled() @@ -40,19 +42,24 @@ Rectangle{ onPathSelected: { var newSegment = segmentFactory.createObject() newSegment.file = path - newSegment.length = 20 + newSegment.length = 100 parent.segmentCreated(newSegment) } } - - TextButton{ + Workspace.TextButton{ anchors.right: parent.right anchors.rightMargin: 10 radius: 5 width: 30 height: 30 text: 'X' + style: Workspace.TextButtonStyle{ + backgroundColor: '#3f444d' + backgroundHoverColor: Qt.lighter('#3f444d', 1.2) + borderColor: '#575b63' + } + onClicked: { parent.cancelled() } diff --git a/plugins/lcvcore/qml/VideoSurfaceCreator.qml b/plugins/lcvcore/qml/VideoSurfaceCreator.qml index a4173057..5b19609f 100644 --- a/plugins/lcvcore/qml/VideoSurfaceCreator.qml +++ b/plugins/lcvcore/qml/VideoSurfaceCreator.qml @@ -3,12 +3,15 @@ import timeline 1.0 import lcvcore 1.0 import live 1.0 import workspace 1.0 as Workspace +import visual.input 1.0 as Input Rectangle{ id: root width: 300 - height: 80 - color: '#03070a' + height: 160 + color: '#141b20' + border.width: 1 + border.color: '#232b30' property QtObject currentTheme: lk.layers.workspace ? lk.layers.workspace.themes.current : null @@ -42,21 +45,46 @@ Rectangle{ color: "#afafaf" } + Input.DropDown{ + id: presetInput + anchors.left: parent.left + anchors.leftMargin: 75 + anchors.top: parent.top + anchors.topMargin: 47 + width: 150 + style: currentTheme.dropDownStyle + + property var values: [ + { w: 800, h: 600, label: '800x600 4:3 (Default)'}, + { w: 1280, h: 720, label: '1280x720 16:9 (HD)'}, + { w: 800, h: 600, label: '1920x1080 16:9 (Full HD)'}, + { w: 3840, h: 2160, label: '3840x600 16:9 (Ultra HD)'} + ] + + model: values.map(function(val){ return val.label }) + + onCurrentIndexChanged: { + var val = values[currentIndex] + widthInput.text = val.w + heightInput.text = val.h + } + } + Workspace.InputBox{ id: widthInput anchors.left: parent.left - anchors.leftMargin: 20 + anchors.leftMargin: 75 anchors.top: parent.top - anchors.topMargin: 50 + anchors.topMargin: 97 width: 50 text: '800' } Workspace.InputBox{ id: heightInput anchors.left: parent.left - anchors.leftMargin: 80 + anchors.leftMargin: 75 + 60 anchors.top: parent.top - anchors.topMargin: 50 + anchors.topMargin: 97 width: 50 text: '600' } @@ -64,22 +92,28 @@ Rectangle{ Workspace.Button{ id: applyButton anchors.top: parent.top - anchors.topMargin: 50 + anchors.topMargin: 100 anchors.left: parent.left - anchors.leftMargin: 140 + anchors.leftMargin: 75 + 60 + 60 width: 25 height: 25 content: root.currentTheme ? root.currentTheme.buttons.apply : null onClicked: { root.surfaceCreated(root.createSurface()) } } - TextButton{ + Workspace.TextButton{ anchors.right: parent.right anchors.rightMargin: 10 radius: 5 width: 30 height: 30 text: 'X' + style: Workspace.TextButtonStyle{ + backgroundColor: '#3f444d' + backgroundHoverColor: Qt.lighter('#3f444d', 1.2) + borderColor: '#575b63' + } + onClicked: { parent.cancelled() } From 920282179eb2fbcfdeeff8bc9882e9804da61e41 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Fri, 14 May 2021 13:30:24 +0300 Subject: [PATCH 39/91] Editor: Fixed background styling during load. --- plugins/editor/qml/EditorPane.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/editor/qml/EditorPane.qml b/plugins/editor/qml/EditorPane.qml index f1c2feeb..bc7fb4df 100644 --- a/plugins/editor/qml/EditorPane.qml +++ b/plugins/editor/qml/EditorPane.qml @@ -153,7 +153,7 @@ Pane{ visible: loadingAnimation.visible anchors.fill: parent anchors.topMargin: 30 - color: "#030609" + color: currentTheme ? currentTheme.colorScheme.background : 'black' opacity: loadingAnimation.visible ? 0.95 : 0 Behavior on opacity{ NumberAnimation{ duration: 250} } z: 900 From eb0217e53641437074eb5588b1bf780cd8326f08 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Fri, 14 May 2021 13:30:49 +0300 Subject: [PATCH 40/91] Project: Updated user message when initializing new main file. --- application/qml/ProjectEnvironment.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/qml/ProjectEnvironment.qml b/application/qml/ProjectEnvironment.qml index ce9aa650..5bb116c3 100644 --- a/application/qml/ProjectEnvironment.qml +++ b/application/qml/ProjectEnvironment.qml @@ -248,7 +248,7 @@ Item{ project.openProject(url) if ( !project.active ){ - var message = 'Project has no file to run. Would you like to create one?' + var message = 'Folder doesn\'t have a main project file. Would you like to create one?' var createFile = function(mbox){ root.wizards.addFile( project.dir(), From cbcb29b25e4228ca63823cb7e1166a6f8d88d873 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Fri, 14 May 2021 15:05:58 +0300 Subject: [PATCH 41/91] VisualFileSelector: Added support for highlighted file connection. --- plugins/fs/fsqml/qml/SelectableFolderView.qml | 2 ++ plugins/fs/fsqml/qml/VisualFileSelector.qml | 1 + .../fs/fsqml/qml/palettes/VisualFileSelectorPalette.qml | 8 ++++++++ 3 files changed, 11 insertions(+) diff --git a/plugins/fs/fsqml/qml/SelectableFolderView.qml b/plugins/fs/fsqml/qml/SelectableFolderView.qml index be3404df..5aa88f69 100644 --- a/plugins/fs/fsqml/qml/SelectableFolderView.qml +++ b/plugins/fs/fsqml/qml/SelectableFolderView.qml @@ -20,6 +20,7 @@ Workspace.SelectableListView{ model = wdlist } + signal itemHighlighted(int index) signal itemSelected(int index) onItemSelected: { var item = model[index] @@ -99,6 +100,7 @@ Workspace.SelectableListView{ } } else { root.selectedIndexes = [index] + root.itemHighlighted(index) } root.forceActiveFocus() } diff --git a/plugins/fs/fsqml/qml/VisualFileSelector.qml b/plugins/fs/fsqml/qml/VisualFileSelector.qml index 90281661..2fc6dc85 100644 --- a/plugins/fs/fsqml/qml/VisualFileSelector.qml +++ b/plugins/fs/fsqml/qml/VisualFileSelector.qml @@ -2,5 +2,6 @@ import QtQuick 2.3 QtObject{ property string workingDirectory: project.dir() + property string highlightedFile: '' property string selectedFile: '' } diff --git a/plugins/fs/fsqml/qml/palettes/VisualFileSelectorPalette.qml b/plugins/fs/fsqml/qml/palettes/VisualFileSelectorPalette.qml index b94b74c6..313b1884 100644 --- a/plugins/fs/fsqml/qml/palettes/VisualFileSelectorPalette.qml +++ b/plugins/fs/fsqml/qml/palettes/VisualFileSelectorPalette.qml @@ -39,6 +39,14 @@ CodePalette{ parent.visualFileSelector.selectedFile = itemPath } } + onItemHighlighted: { + var item = model[index] + + if ( !item.isDir ){ + var itemPath = Fs.Path.absolutePath(item.path ? item.path : Fs.Path.join(cwd, item.name)) + parent.visualFileSelector.highlightedFile = itemPath + } + } } } From c4109227fb69a4785c7eca49429a12545204ffb9 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Fri, 14 May 2021 21:16:40 +0300 Subject: [PATCH 42/91] Added ImageSegmentFactory and ImageSegmentFactory palettes. --- lib/lveditqmljs/src/qmljssettings.cpp | 1 + plugins/lcvcore/lcvcore.pro | 3 + .../palettes/ImageSegmentFactoryPalette.qml | 64 +++++++++++++++++++ .../ImageSegmentFactoryPropertiesPalette.json | 10 +++ plugins/lcvcore/qml/ImageSegmentFactory.qml | 61 ++++++++++++++++++ plugins/lcvcore/qml/live.plugin.json | 4 +- plugins/lcvcore/qml/qmldir | 1 + 7 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 plugins/lcvcore/palettes/ImageSegmentFactoryPalette.qml create mode 100644 plugins/lcvcore/palettes/ImageSegmentFactoryPropertiesPalette.json create mode 100644 plugins/lcvcore/qml/ImageSegmentFactory.qml diff --git a/lib/lveditqmljs/src/qmljssettings.cpp b/lib/lveditqmljs/src/qmljssettings.cpp index 4d05df7c..d7d392ef 100644 --- a/lib/lveditqmljs/src/qmljssettings.cpp +++ b/lib/lveditqmljs/src/qmljssettings.cpp @@ -80,6 +80,7 @@ QmlJsSettings::QmlJsSettings(EditorSettings *parent) m_defaultPalettes["qml/lcvphoto#Levels"] = "LevelsDefaultPalette"; m_defaultPalettes["qml/lcvphoto#BrightnessAndContrast"] = "BrightnessAndContrastPalette"; m_defaultPalettes["qml/lcvcore#PerspectiveOnBackground"] = "PerspectiveOnBackgroundPropertiesPalette"; + m_defaultPalettes["qml/lcvcore#ImageSegmentFactory"] = "ImageSegmentFactoryPropertiesPalette"; if (parent){ MLNode s = parent->readFor("qmljs"); diff --git a/plugins/lcvcore/lcvcore.pro b/plugins/lcvcore/lcvcore.pro index 0fc33485..c579fd85 100644 --- a/plugins/lcvcore/lcvcore.pro +++ b/plugins/lcvcore/lcvcore.pro @@ -66,6 +66,8 @@ DISTFILES += \ palettes/ImageReadPalette.json \ palettes/BlankImagePalette.json \ palettes/DrawSurfacePalette.json \ + palettes/ImageSegmentFactoryPalette.qml \ + palettes/ImageSegmentFactoryPropertiesPalette.json \ palettes/PaperSurfacePalette.qml \ palettes/PerspectiveOnBackgroundPalette.qml \ palettes/PerspectiveOnBackgroundPropertiesPalette.json \ @@ -88,6 +90,7 @@ DISTFILES += \ qml/GrayscaleView.qml \ qml/ImageRead.qml \ qml/ImageSegmentCreator.qml \ + qml/ImageSegmentFactory.qml \ qml/MatViewPane.qml \ qml/NavigableImageView.qml \ qml/PaperSurface.qml \ diff --git a/plugins/lcvcore/palettes/ImageSegmentFactoryPalette.qml b/plugins/lcvcore/palettes/ImageSegmentFactoryPalette.qml new file mode 100644 index 00000000..2ae3c1d9 --- /dev/null +++ b/plugins/lcvcore/palettes/ImageSegmentFactoryPalette.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2014-2019 Dinu SV. +** (contact: mail@dinusv.com) +** This file is part of Livekeys Application. +** +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +****************************************************************************/ + +import QtQuick 2.3 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.4 +import editor 1.0 +import live 1.0 +import base 1.0 +import workspace 1.0 as Workspace + +CodePalette{ + id: palette + + type: "qml/lcvcore#ImageSegmentFactory" + + property QtObject theme: lk.layers.workspace.themes.current + + item: Item{ + id: paletteItem + width: 100 + height: 25 + + property var current : null + + Workspace.TextButton{ + anchors.horizontalCenter: parent.horizontalCenter + anchors.left: parent.left + anchors.leftMargin: 10 + height: 28 + width: 80 + style: theme.formButtonStyle + + text: "Create" + onClicked: { + paletteItem.current.create() + } + } + } + + onValueFromBindingChanged: { + paletteItem.current = value + } + onInit: { + paletteItem.current = value + } + + onEditFragmentChanged: { + editFragment.whenBinding = function(){} + } +} diff --git a/plugins/lcvcore/palettes/ImageSegmentFactoryPropertiesPalette.json b/plugins/lcvcore/palettes/ImageSegmentFactoryPropertiesPalette.json new file mode 100644 index 00000000..1affe644 --- /dev/null +++ b/plugins/lcvcore/palettes/ImageSegmentFactoryPropertiesPalette.json @@ -0,0 +1,10 @@ +{ + "type": "qml/lcvcore#ImageSegmentFactory", + "palettes": ["ImageSegmentFactoryPalette"], + "properties" : [ + ["file", "FilePathPalette"], + ["trackName", "TextPalette"], + ["timeline"] + ] +} + diff --git a/plugins/lcvcore/qml/ImageSegmentFactory.qml b/plugins/lcvcore/qml/ImageSegmentFactory.qml new file mode 100644 index 00000000..5dc36df0 --- /dev/null +++ b/plugins/lcvcore/qml/ImageSegmentFactory.qml @@ -0,0 +1,61 @@ +import QtQuick 2.3 +import lcvcore 1.0 +import timeline 1.0 + +QtObject{ + + property string file: '' + property int position: 0 + property int length: 0 + + property Component factory: ImageSegment{} + + property QtObject timeline: null + property string trackName: '' + + property var track: null + + function create(){ + if ( !file ){ + return + } + + var segment = factory.createObject() + segment.file = file + segment.length = 10 + if ( length > 0 ) + segment.length = length + if ( position > 0 ) + segment.position = position + + var _track = null + var _timeline = timeline ? timeline : track.timeline() + if ( !_track ){ + var tlist = _timeline.trackList + for ( var i = 0; i < tlist.totalTracks(); ++i ){ + var t = tlist.trackAt(i) + if ( t.name === trackName ){ + _track = t + break + } + } + } + + if ( _track ){ + if ( _timeline && position === 0 ){ + segment.position = _timeline.cursorPosition + } + + _track.addSegment(segment) + if ( _timeline.cursorPosition === segment.position ) + _timeline.cursorPosition += segment.length + } + + newSegment(segment) + + return segment + } + + signal newSegment(ImageSegment segment) + +} diff --git a/plugins/lcvcore/qml/live.plugin.json b/plugins/lcvcore/qml/live.plugin.json index ea32a7ee..d1b01ac0 100644 --- a/plugins/lcvcore/qml/live.plugin.json +++ b/plugins/lcvcore/qml/live.plugin.json @@ -19,6 +19,8 @@ "palettes/ImageFilePalette.json" : "qml/lcvcore#ImageFile", "palettes/BlankImagePalette.json" : "qml/lcvcore#BlankImage", "palettes/PerspectiveOnBackgroundPalette.qml": "qml/lcvcore#PerspectiveOnBackground", - "palettes/PerspectiveOnBackgroundPropertiesPalette.json": "qml/lcvcore#PerspectiveOnBackground" + "palettes/PerspectiveOnBackgroundPropertiesPalette.json": "qml/lcvcore#PerspectiveOnBackground", + "palettes/ImageSegmentFactoryPalette.qml": "qml/lcvcore#ImageSegmentFactory", + "palettes/ImageSegmentFactoryPropertiesPalette.json": "qml/lcvcore#ImageSegmentFactory" } } diff --git a/plugins/lcvcore/qml/qmldir b/plugins/lcvcore/qml/qmldir index 3acd2f11..349bed21 100644 --- a/plugins/lcvcore/qml/qmldir +++ b/plugins/lcvcore/qml/qmldir @@ -10,6 +10,7 @@ VideoDecoderView 1.0 VideoDecoderView.qml VideoFile 1.0 VideoFile.qml GrayscaleView 1.0 GrayscaleView.qml VideoCaptureSegmentFactory 1.0 VideoCaptureSegmentFactory.qml +ImageSegmentFactory 1.0 ImageSegmentFactory.qml NavigableImageView 1.0 NavigableImageView.qml Crop 1.0 Crop.qml ImageDrawView 1.0 ImageDrawView.qml From 2af5c7bd13e2132b99e9ff8cd212c69874790fb3 Mon Sep 17 00:00:00 2001 From: nenad-popovic-91 <42581059+nenad-popovic-91@users.noreply.github.com> Date: Wed, 19 May 2021 13:22:22 +0200 Subject: [PATCH 43/91] Changes to id management of different scopes (#212) * Changes to id management of different scopes --- lib/lvelements/src/languagenodes.cpp | 181 +++++++++++------- lib/lvelements/src/languagenodes_p.h | 36 ++-- .../lvelementstest/data/ParserTest20.lv.js | 1 + .../unit/lvelementstest/data/ParserTest24.lv | 9 + .../lvelementstest/data/ParserTest24.lv.js | 27 +++ .../unit/lvelementstest/data/ParserTest25.lv | 22 +++ .../lvelementstest/data/ParserTest25.lv.js | 62 ++++++ .../unit/lvelementstest/data/ParserTest26.lv | 14 ++ .../lvelementstest/data/ParserTest26.lv.js | 44 +++++ .../lvelementstest/data/ParserTest9.lv.js | 16 +- tests/unit/lvelementstest/lvparsetest.cpp | 16 ++ tests/unit/lvelementstest/lvparsetest.h | 3 + 12 files changed, 335 insertions(+), 96 deletions(-) create mode 100644 tests/unit/lvelementstest/data/ParserTest24.lv create mode 100644 tests/unit/lvelementstest/data/ParserTest24.lv.js create mode 100644 tests/unit/lvelementstest/data/ParserTest25.lv create mode 100644 tests/unit/lvelementstest/data/ParserTest25.lv.js create mode 100644 tests/unit/lvelementstest/data/ParserTest26.lv create mode 100644 tests/unit/lvelementstest/data/ParserTest26.lv.js diff --git a/lib/lvelements/src/languagenodes.cpp b/lib/lvelements/src/languagenodes.cpp index 44ec5511..aeecba4e 100644 --- a/lib/lvelements/src/languagenodes.cpp +++ b/lib/lvelements/src/languagenodes.cpp @@ -110,11 +110,6 @@ void BaseNode::moveToDeclarations(BaseNode *parent, IdentifierNode *idNode) if (jsbn) { jsbn->m_declarations.push_back(idNode); - - if (jsbn->typeString() == "StatementBlock"){ - auto sb = dynamic_cast(jsbn); - sb->m_localVariables.push_back(idNode); - } break; } p = p->parent(); @@ -316,7 +311,27 @@ void BaseNode::visitComponentBody(BaseNode *parent, const TSNode &node){ } void BaseNode::visitNewComponentExpression(BaseNode *parent, const TSNode &node){ - NewComponentExpressionNode* enode = new NewComponentExpressionNode(node); + + NewComponentExpressionNode* enode = nullptr; + + if (parent->typeString() == "ExpressionStatement" + && parent->parent() + && parent->parent()->typeString() == "Program"){ + enode = new RootNewComponentExpressionNode(node); + } else { + BaseNode* p = parent; + while (p && dynamic_cast(p) == nullptr) + { + p = p->parent(); + } + if (p && p->typeString() == "JSScope"){ + enode = new RootNewComponentExpressionNode(node); + } else { + enode = new NewComponentExpressionNode(node); + } + + } + parent->insert(enode); uint32_t count = ts_node_child_count(node); for ( uint32_t i = 0; i < count; ++i ){ @@ -347,10 +362,9 @@ void BaseNode::visitNewComponentExpression(BaseNode *parent, const TSNode &node) // for id components BaseNode* p = parent; - while (enode->m_id && p) + while (enode->m_id && p && enode->typeString() != "RootNewComponentExpression") { - if (p->typeString() == "ComponentBody") - { + if (p->typeString() == "ComponentBody"){ auto body = p->as(); if (body->parent()->typeString() == "ComponentDeclaration") { @@ -358,9 +372,10 @@ void BaseNode::visitNewComponentExpression(BaseNode *parent, const TSNode &node) decl->pushToIdComponents(enode); break; } - } else if (p->typeString() == "Program"){ - auto prog = p->as(); - prog->m_idComponents.push_back(enode); + } else if (p->typeString() == "RootNewComponentExpression"){ + auto rnce = p->as(); + rnce->m_idComponents.push_back(enode); + break; } p = p->parent(); @@ -377,7 +392,7 @@ void BaseNode::visitNewComponentExpression(BaseNode *parent, const TSNode &node) decl->pushToDefault(enode); } - else if (body->parent()->typeString() == "NewComponentExpression") + else if (body->parent()->typeString() == "NewComponentExpression" || body->parent()->typeString() == "RootNewComponentExpression") { auto expr = body->parent()->as(); expr->pushToDefault(enode); @@ -405,7 +420,7 @@ void BaseNode::visitPropertyDeclaration(BaseNode *parent, const TSNode &node){ enode->m_expression->setParent(enode); visitChildren(enode->m_expression, child); } else if (strcmp(ts_node_type(child),"statement_block") == 0) { - enode->m_statementBlock = new StatementBlockNode(child); + enode->m_statementBlock = new JsBlockNode(child); enode->m_statementBlock->setParent(enode); visitChildren(enode->m_statementBlock, child); } else if (strcmp(ts_node_type(child),"component_declaration") == 0) { @@ -419,7 +434,7 @@ void BaseNode::visitPropertyDeclaration(BaseNode *parent, const TSNode &node){ parent->parent()->as()->pushToProperties(enode); } - if (parent->parent() && parent->parent()->typeString() == "NewComponentExpression") + if (parent->parent() && (parent->parent()->typeString() == "NewComponentExpression" || parent->parent()->typeString() == "RootNewComponentExpression")) { parent->parent()->as()->pushToProperties(enode); } @@ -494,7 +509,7 @@ void BaseNode::visitPropertyAssignment(BaseNode *parent, const TSNode &node){ enode->m_expression->setParent(enode); visitChildren(enode->m_expression, rhs); } else if (strcmp(ts_node_type(rhs),"statement_block") == 0) { - enode->m_statementBlock = new StatementBlockNode(rhs); + enode->m_statementBlock = new JsBlockNode(rhs); enode->m_statementBlock->setParent(enode); visitChildren(enode->m_statementBlock, rhs); } @@ -505,7 +520,7 @@ void BaseNode::visitPropertyAssignment(BaseNode *parent, const TSNode &node){ parent->parent()->as()->pushToAssignments(enode); } - if (parent->parent() && parent->parent()->typeString() == "NewComponentExpression") + if (parent->parent() && (parent->parent()->typeString() == "NewComponentExpression" || parent->parent()->typeString() == "RootNewComponentExpression")) { parent->parent()->as()->pushToAssignments(enode); } @@ -523,7 +538,7 @@ void BaseNode::visitIdentifierAssignment(BaseNode *parent, const TSNode &node){ cdn->m_id = new IdentifierNode(idChild); // provide id to outside scope moveToDeclarations(componentParent, cdn->m_id); - } else if ( componentParent->typeString() == "NewComponentExpression" ){ + } else if ( componentParent->typeString() == "NewComponentExpression" || componentParent->typeString() == "RootNewComponentExpression"){ NewComponentExpressionNode* ncen = componentParent->as(); ncen->m_id = new IdentifierNode(idChild); // provide id to outside scope @@ -694,7 +709,7 @@ void BaseNode::visitConstructorDefinition(BaseNode *parent, const TSNode &node) for ( uint32_t i = 0; i < count; ++i ){ TSNode child = ts_node_child(node, i); if ( strcmp(ts_node_type(child), "statement_block") == 0 ){ - cdnode->m_block = new StatementBlockNode(child); + cdnode->m_block = new JsBlockNode(child); cdnode->m_block->setParent(cdnode); visitChildren(cdnode->m_block, child); // enode->m_name = new IdentifierNode(child); @@ -761,7 +776,7 @@ void BaseNode::visitNewTaggedComponentExpression(BaseNode *parent, const TSNode decl->pushToDefault(tagnode); } - else if (body->parent()->typeString() == "NewComponentExpression") + else if (body->parent()->typeString() == "NewComponentExpression" || body->parent()->typeString() == "RootNewComponentExpression") { auto expr = body->parent()->as(); expr->pushToDefault(tagnode); @@ -992,31 +1007,6 @@ void ProgramNode::convertToJs(const std::string &source, std::vectorid()) << " = new " << slice(source, m_idComponents[i]->name()); - checkIdentifierDeclared(source, m_idComponents[i]->name(), slice(source, m_idComponents[i]->name())); - if (m_idComponents[i]->arguments()) *compose << slice(source, m_idComponents[i]->arguments()) << "\n"; - else *compose << "()\n"; - } - - for (int i = 0; i < m_idComponents.size();++i) - { - std::string id = slice(source, m_idComponents[i]->id()); - auto properties = m_idComponents[i]->properties(); - - for (int idx = 0; idxname()) - << "', { type: '" << slice(source, properties[idx]->type()) << "', notify: '" - << slice(source, properties[idx]->name()) << "Changed' })\n"; - } - - } - } - fragments.insert(iter, compose); } @@ -1139,6 +1129,7 @@ void ComponentDeclarationNode::convertToJs(const std::string &source, std::vecto for (int i = 0; i < m_idComponents.size();++i) { *compose << indent(indentValue + 1) << "var " << slice(source, m_idComponents[i]->id()) << " = new " << slice(source, m_idComponents[i]->name()); + checkIdentifierDeclared(source, m_idComponents[i]->name(), slice(source, m_idComponents[i]->name())); if (m_idComponents[i]->arguments()) *compose << slice(source, m_idComponents[i]->arguments()) << "\n"; else *compose << "()\n"; *compose << indent(indentValue + 1) << "this.ids[\"" << slice(source, m_idComponents[i]->id()) << "\"] = " << slice(source, m_idComponents[i]->id()) << "\n\n"; @@ -1239,18 +1230,20 @@ void ComponentDeclarationNode::convertToJs(const std::string &source, std::vecto bool skip = false; - auto sb = men->parent(); - while (sb && sb->typeString() != "StatementBlock"){ - sb = sb->parent(); + auto p = men->parent(); + JsBlockNode* sb = nullptr; + while (p){ + sb = dynamic_cast(p); + if (sb) break; + p = p->parent(); } if (sb){ - auto sbc = dynamic_cast(sb); - auto localVars = sbc->m_localVariables; + auto decl = sb->m_declarations; if (men->children()[0]->typeString() == "Identifier"){ auto ident = dynamic_cast(men->children()[0]); auto ids = slice(source, ident->startByte(), ident->endByte()); - for (auto ch: localVars){ + for (auto ch: decl){ auto localVar = slice(source, ch->startByte(), ch->endByte()); if (localVar == ids){ @@ -1291,7 +1284,7 @@ void ComponentDeclarationNode::convertToJs(const std::string &source, std::vecto *compose << "this." << slice(source,m_properties[i]->name()) << " = "; if (m_properties[i]->expression() && m_properties[i]->expression()->children().size() == 1 - && m_properties[i]->expression()->children()[0]->typeString() == "NewComponentExpression") + && (m_properties[i]->expression()->children()[0]->typeString() == "NewComponentExpression" || m_properties[i]->expression()->children()[0]->typeString() == "RootNewComponentExpression")) { auto nce = m_properties[i]->expression()->children()[0]->as(); @@ -1516,15 +1509,53 @@ void NewComponentExpressionNode::convertToJs(const std::string &source, std::vec } *compose << ("(function(parent){\n this.setParent(parent)\n"); - if (!m_id) - for (int i = 0; iname()) - << "', { type: '" << slice(source, m_properties[i]->type()) << "', notify: '" - << slice(source, m_properties[i]->name()) << "Changed' })\n"; - } - else { + std::string id_root = "this"; + bool isRoot = (dynamic_cast(this) != nullptr); + if (m_id) { *compose << "Element.assignId(" << slice(source,m_id) << ", \"" << slice(source,m_id) << "\")\n"; + if (isRoot){ + id_root = slice(source,m_id); + *compose << "var " << id_root << " = this\n\n"; + } + } + + + if (isRoot && !m_idComponents.empty()){ + for (int i = 0; i < m_idComponents.size();++i) + { + auto type = slice(source, m_idComponents[i]->name()); + + *compose << "var " << slice(source, m_idComponents[i]->id()) << " = new " << type; + checkIdentifierDeclared(source, m_idComponents[i]->name(), type); + if (m_idComponents[i]->arguments()) *compose << slice(source, m_idComponents[i]->arguments()) << "\n"; + else *compose << "()\n"; + } + } + + if (isRoot || !m_id){ + for (int i = 0; iname()) + << "', { type: '" << slice(source, m_properties[i]->type()) << "', notify: '" + << slice(source, m_properties[i]->name()) << "Changed' })\n"; + } + } + + if (isRoot && !m_idComponents.empty()){ + for (int i = 0; i < m_idComponents.size();++i) + { + std::string id = slice(source, m_idComponents[i]->id()); + auto properties = m_idComponents[i]->properties(); + + for (int idx = 0; idxname()) + << "', { type: '" << slice(source, properties[idx]->type()) << "', notify: '" + << slice(source, properties[idx]->name()) << "Changed' })\n"; + } + + } + } for (int i=0; iparent(); - while (sb && sb->typeString() != "StatementBlock"){ - sb = sb->parent(); + auto p = men->parent(); + JsBlockNode* sb = nullptr; + while (p){ + sb = dynamic_cast(p); + if (sb) break; + p = p->parent(); } if (sb){ - auto sbc = dynamic_cast(sb); - auto localVars = sbc->m_localVariables; + auto decl = sb->m_declarations; if (men->children()[0]->typeString() == "Identifier"){ auto ident = dynamic_cast(men->children()[0]); auto ids = slice(source, ident->startByte(), ident->endByte()); - for (auto ch: localVars){ + for (auto ch: decl){ auto localVar = slice(source, ch->startByte(), ch->endByte()); if (localVar == ids){ @@ -1830,7 +1863,7 @@ void NewComponentExpressionNode::convertToJs(const std::string &source, std::vec *compose << "return this\n}.bind("; - if (!m_id) + if (!m_id || isRoot) { *compose << "new " << slice(source, m_name); checkIdentifierDeclared(source, m_name, slice(source, m_name)); @@ -1860,8 +1893,8 @@ void NewComponentExpressionNode::convertToJs(const std::string &source, std::vec } -NewComponentExpressionNode::NewComponentExpressionNode(const TSNode &node) - : JsBlockNode(node, "NewComponentExpression") +NewComponentExpressionNode::NewComponentExpressionNode(const TSNode &node, const std::string& typeString) + : JsBlockNode(node, typeString) , m_name(nullptr) , m_id(nullptr) , m_body(nullptr) @@ -1871,6 +1904,12 @@ NewComponentExpressionNode::NewComponentExpressionNode(const TSNode &node) } +NewComponentExpressionNode::NewComponentExpressionNode(const TSNode &node): + NewComponentExpressionNode(node, "NewComponentExpression") +{ + +} + std::string NewComponentExpressionNode::toString(int indent) const{ std::string result; if ( indent > 0 ) @@ -1887,7 +1926,7 @@ std::string NewComponentExpressionNode::toString(int indent) const{ if (m_arguments) args = "(args " + m_arguments->rangeString() + ")"; - result += "NewComponentExpression " + name + identifier +args + rangeString() + "\n"; + result += typeString() + " " + name + identifier +args + rangeString() + "\n"; if ( m_body ){ result += m_body->toString(indent >= 0 ? indent + 1 : indent); } @@ -2250,7 +2289,7 @@ void VariableDeclarationNode::convertToJs(const std::string &source, std::vector continue; } - if (children[0]->typeString() == "Identifier" && children[1]->typeString() == "NewComponentExpression"){ + if (children[0]->typeString() == "Identifier" && (children[1]->typeString() == "NewComponentExpression" || children[1]->typeString() == "RootNewComponentExpression")){ *compose << "\nvar " << slice(source, children[0]->startByte(), children[0]->endByte()) << " = "; el::JSSection* section = new el::JSSection; diff --git a/lib/lvelements/src/languagenodes_p.h b/lib/lvelements/src/languagenodes_p.h index e57c4fd4..dce45ecb 100644 --- a/lib/lvelements/src/languagenodes_p.h +++ b/lib/lvelements/src/languagenodes_p.h @@ -31,9 +31,9 @@ class NewComponentExpressionNode; class BindableExpressionNode; class MemberExpressionNode; class SubscriptExpressionNode; -class StatementBlockNode; class ArgumentsNode; class ObjectNode; +class RootNewComponentExpressionNode; class BaseNode{ friend class JsBlockNode; @@ -142,17 +142,20 @@ class NewExpressionNode: public BaseNode { class JsBlockNode : public BaseNode{ friend class BaseNode; + friend class ComponentDeclarationNode; + friend class NewComponentExpressionNode; public: JsBlockNode(const TSNode& node, const std::string& typeString = "JSScope") : BaseNode(node, typeString){} const std::vector& identifiers() const { return m_declarations; } -private: +protected: std::vector m_declarations; + }; class ArrowFunctionNode: public JsBlockNode { friend class BaseNode; public: - ArrowFunctionNode(const TSNode& node, const std::string& typeString = "ArrowFunction") : JsBlockNode(node, typeString){} + ArrowFunctionNode(const TSNode& node) : JsBlockNode(node, "ArrowFunction"){} }; class ProgramNode : public JsBlockNode { @@ -172,9 +175,7 @@ class ProgramNode : public JsBlockNode { std::vector m_exports; std::set m_undeclared; std::string m_fileName; - std::vector m_idComponents; - }; class IdentifierNode : public BaseNode{ @@ -279,7 +280,7 @@ class ConstructorDefinitionNode : public BaseNode{ void setSuperCall(CallExpressionNode* super) { m_superCall = super; } // virtual void convertToJs(const std::string& source, std::vector& fragments); private: - StatementBlockNode* m_block; + JsBlockNode* m_block; CallExpressionNode* m_superCall; FormalParametersNode* m_formalParameters; @@ -297,7 +298,7 @@ class PropertyDeclarationNode : public JsBlockNode{ IdentifierNode* type() const{ return m_type; } IdentifierNode* name() const{ return m_name; } BindableExpressionNode* expression() const{ return m_expression; } - StatementBlockNode* statementBlock() const {return m_statementBlock; } + JsBlockNode* statementBlock() const {return m_statementBlock; } ComponentDeclarationNode* componentDeclaration() const { return m_componentDeclaration; } void pushToBindings(BaseNode* bn) { m_bindings.push_back(bn); } @@ -307,7 +308,7 @@ class PropertyDeclarationNode : public JsBlockNode{ IdentifierNode* m_type; IdentifierNode* m_name; BindableExpressionNode* m_expression; - StatementBlockNode* m_statementBlock; + JsBlockNode* m_statementBlock; ComponentDeclarationNode* m_componentDeclaration; std::vector m_bindings; }; @@ -338,7 +339,7 @@ class PropertyAssignmentNode : public JsBlockNode{ std::vector m_property; BindableExpressionNode* m_expression; std::vector m_bindings; - StatementBlockNode* m_statementBlock; + JsBlockNode* m_statementBlock; friend class BaseNode; friend class NewComponentExpressionNode; @@ -387,8 +388,8 @@ class ComponentDeclarationNode : public JsBlockNode{ std::vector m_events; std::vector m_listeners; std::vector m_default; - std::vector m_idComponents; std::vector m_assignments; + std::vector m_idComponents; }; class NewComponentExpressionNode : public JsBlockNode{ @@ -407,6 +408,8 @@ class NewComponentExpressionNode : public JsBlockNode{ std::vector& assignments() { return m_assignments; } void pushToDefault(BaseNode* nce){ m_default.push_back(nce); } +protected: + NewComponentExpressionNode(const TSNode& node, const std::string& typeString); private: IdentifierNode* m_name; IdentifierNode* m_id; @@ -417,11 +420,18 @@ class NewComponentExpressionNode : public JsBlockNode{ std::vector m_default; std::vector m_properties; std::vector m_assignments; + std::vector m_idComponents; friend class BaseNode; }; +class RootNewComponentExpressionNode: public NewComponentExpressionNode { + friend class BaseNode; +public: + RootNewComponentExpressionNode(const TSNode& node) : NewComponentExpressionNode(node, "RootNewComponentExpression"){} +}; + class ExpressionStatementNode : public BaseNode{ public: ExpressionStatementNode(const TSNode& node) : BaseNode(node, "ExpressionStatement"){} @@ -433,12 +443,6 @@ class BindableExpressionNode : public BaseNode{ BindableExpressionNode(const TSNode& node) : BaseNode(node, "BindableExpression"){} }; -class StatementBlockNode : public JsBlockNode{ -public: - StatementBlockNode(const TSNode& node) : JsBlockNode(node, "StatementBlock"){} - std::vector m_localVariables; -}; - class MemberExpressionNode : public BaseNode{ public: MemberExpressionNode(const TSNode& node) : BaseNode(node, "MemberExpression"){} diff --git a/tests/unit/lvelementstest/data/ParserTest20.lv.js b/tests/unit/lvelementstest/data/ParserTest20.lv.js index 99441d2f..f1f783fe 100644 --- a/tests/unit/lvelementstest/data/ParserTest20.lv.js +++ b/tests/unit/lvelementstest/data/ParserTest20.lv.js @@ -1,5 +1,6 @@ var Button = imports.get('Button') var Form = imports.get('Form') +var Input = imports.get('Input') module.exports["TodoForm"] = class TodoForm extends Form{ diff --git a/tests/unit/lvelementstest/data/ParserTest24.lv b/tests/unit/lvelementstest/data/ParserTest24.lv new file mode 100644 index 00000000..98aff145 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest24.lv @@ -0,0 +1,9 @@ +component A{ + var x : { + var d = Element{ + id: did + int y: 10 + } + return d.y + } +} diff --git a/tests/unit/lvelementstest/data/ParserTest24.lv.js b/tests/unit/lvelementstest/data/ParserTest24.lv.js new file mode 100644 index 00000000..d2c8fb59 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest24.lv.js @@ -0,0 +1,27 @@ + +module.exports["A"] = class A extends Element{ + + constructor(){ + super() + this.__initialize() + } + + __initialize(){ + Element.addProperty(this, 'x', { type: "var", notify: "xChanged" }) + this.x = (function(){ + var d = (function(parent){ + this.setParent(parent) + Element.assignId(did, "did") + var did = this + + Element.addProperty(did, 'y', { type: 'int', notify: 'yChanged' }) + this.y = 10 + return this + }.bind(new Element())(null)) + + return d.y + })() + + } + +} \ No newline at end of file diff --git a/tests/unit/lvelementstest/data/ParserTest25.lv b/tests/unit/lvelementstest/data/ParserTest25.lv new file mode 100644 index 00000000..1e0855b7 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest25.lv @@ -0,0 +1,22 @@ +component B{ + Test { + id: test + var x: 10 + } + + Element { + id: extra + } + + var x : { + var d = Element{ + id: did + int y: 10 + + Element { + id: nested + } + } + return d.y + } +} diff --git a/tests/unit/lvelementstest/data/ParserTest25.lv.js b/tests/unit/lvelementstest/data/ParserTest25.lv.js new file mode 100644 index 00000000..373fbf31 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest25.lv.js @@ -0,0 +1,62 @@ +var Test = imports.get('Test') + +module.exports["B"] = class B extends Element{ + + constructor(){ + super() + this.__initialize() + } + + __initialize(){ + this.ids = {} + + var test = new Test() + this.ids["test"] = test + + var extra = new Element() + this.ids["extra"] = extra + + Element.addProperty(test, 'x', { type: "var", notify: "xChanged" }) + Element.addProperty(this, 'x', { type: "var", notify: "xChanged" }) + this.x = (function(){ + var d = (function(parent){ + this.setParent(parent) + Element.assignId(did, "did") + var did = this + var nested = new Element() + + Element.addProperty(did, 'y', { type: 'int', notify: 'yChanged' }) + this.y = 10 + Element.assignDefaultProperty(this, [ + (function(parent){ + this.setParent(parent) + Element.assignId(nested, "nested") + return this + }.bind(nested)(this)) + ]) + return this + }.bind(new Element())(null)) + + return d.y + })() + + + + Element.assignDefaultProperty(this, [ + + (function(parent){ + this.setParent(parent) + Element.assignId(test, "test") + this.x = 10 + return this + }.bind(test)(this)), + + (function(parent){ + this.setParent(parent) + Element.assignId(extra, "extra") + return this + }.bind(extra)(this)) + ]) + } + +} diff --git a/tests/unit/lvelementstest/data/ParserTest26.lv b/tests/unit/lvelementstest/data/ParserTest26.lv new file mode 100644 index 00000000..647c65b5 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest26.lv @@ -0,0 +1,14 @@ +component C{ + Test { + id: test + var x: 10 + } + + var x : { + var d = Element{ + id: test + int y: 10 + } + return d.y + } +} diff --git a/tests/unit/lvelementstest/data/ParserTest26.lv.js b/tests/unit/lvelementstest/data/ParserTest26.lv.js new file mode 100644 index 00000000..e55dd5e0 --- /dev/null +++ b/tests/unit/lvelementstest/data/ParserTest26.lv.js @@ -0,0 +1,44 @@ +var Test = imports.get('Test') + +module.exports["C"] = class C extends Element{ + + constructor(){ + super() + this.__initialize() + } + + __initialize(){ + this.ids = {} + + var test = new Test() + this.ids["test"] = test + + Element.addProperty(test, 'x', { type: "var", notify: "xChanged" }) + Element.addProperty(this, 'x', { type: "var", notify: "xChanged" }) + this.x = (function(){ + var d = (function(parent){ + this.setParent(parent) + Element.assignId(test, "test") + var test = this + + Element.addProperty(test, 'y', { type: 'int', notify: 'yChanged' }) + this.y = 10 + return this + }.bind(new Element())(null)) + + return d.y + })() + + + + Element.assignDefaultProperty(this, [ + (function(parent){ + this.setParent(parent) + Element.assignId(test, "test") + this.x = 10 + return this + }.bind(test)(this)) + ]) + } + +} \ No newline at end of file diff --git a/tests/unit/lvelementstest/data/ParserTest9.lv.js b/tests/unit/lvelementstest/data/ParserTest9.lv.js index 268379f1..e02c2696 100644 --- a/tests/unit/lvelementstest/data/ParserTest9.lv.js +++ b/tests/unit/lvelementstest/data/ParserTest9.lv.js @@ -1,16 +1,14 @@ -// Create all Ids first -var rootChild = new Element() -var root = new Container() - -// Declare all properties for ids -Element.addProperty(rootChild, "y", {type: "int", notify: "yChanged"}) -Element.addProperty(root, "x", {type: "int", notify: "xChanged"}) - // Assign module module.exports["ParserTest9"] = (function(parent){ this.setParent(parent) Element.assignId(root, "root") + var root = this + var rootChild = new Element() + + Element.addProperty(root, 'x', { type: 'int', notify: 'xChanged' }) + Element.addProperty(rootChild, 'y', { type: 'int', notify: 'yChanged' }) + // assign properties this.x = 20 @@ -26,4 +24,4 @@ module.exports["ParserTest9"] = (function(parent){ ]) return this -}.bind(root)(null)) +}.bind(new Container())(null)) diff --git a/tests/unit/lvelementstest/lvparsetest.cpp b/tests/unit/lvelementstest/lvparsetest.cpp index f1ab6f53..68999691 100644 --- a/tests/unit/lvelementstest/lvparsetest.cpp +++ b/tests/unit/lvelementstest/lvparsetest.cpp @@ -130,6 +130,22 @@ void LvParseTest::doublyNestedElement() parseTestTemplate("ParserTest23"); } +void LvParseTest::idObjectInJsScope() +{ + parseTestTemplate("ParserTest24"); +} + +void LvParseTest::nestedObjectsInJsScope() +{ + parseTestTemplate("ParserTest25"); +} + +void LvParseTest::sameIdInBothScopes() +{ + parseTestTemplate("ParserTest26"); + +} + void LvParseTest::parseTestTemplate(std::string name) { std::string contents = m_fileSession->readFromFile(m_scriptPath + "/" + name + ".lv"); diff --git a/tests/unit/lvelementstest/lvparsetest.h b/tests/unit/lvelementstest/lvparsetest.h index f7fb9fa9..eae42669 100644 --- a/tests/unit/lvelementstest/lvparsetest.h +++ b/tests/unit/lvelementstest/lvparsetest.h @@ -40,6 +40,9 @@ private slots: void todoApp(); void complexTernaryOperator(); void doublyNestedElement(); + void idObjectInJsScope(); + void nestedObjectsInJsScope(); + void sameIdInBothScopes(); private: void parseTestTemplate(std::string name); From 319826606e50726526929b9b5944ea194d33bfc5 Mon Sep 17 00:00:00 2001 From: nenad-popovic-91 <42581059+nenad-popovic-91@users.noreply.github.com> Date: Wed, 19 May 2021 13:22:45 +0200 Subject: [PATCH 44/91] Modified Exec Palette with stop feature (#213) * Modified Exec Palette with stop feature --- plugins/base/baseqml/palettes/ExecPalette.qml | 46 +++++++++++++++++-- plugins/base/baseqml/src/qmlexec.cpp | 17 +++++++ plugins/base/baseqml/src/qmlexec.h | 2 +- 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/plugins/base/baseqml/palettes/ExecPalette.qml b/plugins/base/baseqml/palettes/ExecPalette.qml index 0368fd8f..1137817e 100644 --- a/plugins/base/baseqml/palettes/ExecPalette.qml +++ b/plugins/base/baseqml/palettes/ExecPalette.qml @@ -37,19 +37,59 @@ CodePalette{ property var current : null Workspace.TextButton{ + id: textButton anchors.horizontalCenter: parent.horizontalCenter anchors.left: parent.left anchors.leftMargin: 10 height: 28 width: 80 style: theme.formButtonStyle + text: "Start" - - text: "Run" onClicked: { - execBox.current.run() + if (execBox.state == "NOT_RUNNING"){ + execBox.state = "STARTING" + execBox.current.run() + } else if (execBox.state == "RUNNING"){ + execBox.current.stop() + } + } + } + + Connections { + target: execBox.current + ignoreUnknownSignals: true + function onAboutToRun(){ + execBox.state = "RUNNING" + } + + function onFinished(){ + execBox.state = "NOT_RUNNING" } } + + state: "NOT_RUNNING" + + states: [ + State { + name: "NOT_RUNNING" + PropertyChanges { + target: textButton + text: "Start" + } + }, + + State { + name: "STARTING" + }, + State { + name: "RUNNING" + PropertyChanges { + target: textButton + text: "Stop" + } + } + ] } onValueFromBindingChanged: { diff --git a/plugins/base/baseqml/src/qmlexec.cpp b/plugins/base/baseqml/src/qmlexec.cpp index 02cd0b91..7ba1147c 100644 --- a/plugins/base/baseqml/src/qmlexec.cpp +++ b/plugins/base/baseqml/src/qmlexec.cpp @@ -92,4 +92,21 @@ void QmlExec::closeInput(){ m_process->closeWriteChannel(); } +void QmlExec::stop() +{ + if ( m_process->state() == QProcess::NotRunning){ + Exception e = CREATE_EXCEPTION(Exception, "Process has already stopped.", Exception::toCode("~Process")); + ViewContext::instance().engine()->throwError(&e, this); + return; + } + + if ( m_out ){ + disconnect(m_process, &QProcess::readyRead, this, &QmlExec::__processRead); + } + + closeInput(); + + m_process->kill(); +} + }// namespace diff --git a/plugins/base/baseqml/src/qmlexec.h b/plugins/base/baseqml/src/qmlexec.h index 8cbaa791..5357541a 100644 --- a/plugins/base/baseqml/src/qmlexec.h +++ b/plugins/base/baseqml/src/qmlexec.h @@ -68,7 +68,7 @@ public slots: void run(); void closeInput(); - + void stop(); private: bool m_componentComplete; From 329e96961e49e57b13293c85d4debc3c6b651f2f Mon Sep 17 00:00:00 2001 From: nenad-popovic-91 <42581059+nenad-popovic-91@users.noreply.github.com> Date: Wed, 26 May 2021 17:20:03 +0200 Subject: [PATCH 45/91] Our own Edge implementation for internal node property connections (#214) * Custom Edge implementation for internal node property connections * Alternative solution for uniform edges --- plugins/squareone/qml/qmldir | 1 + plugins/workspace/nodeeditor/qml/Edge.qml | 6 +- .../workspace/nodeeditor/qml/EdgeTemplate.qml | 326 ++++++++++++++++++ .../workspace/nodeeditor/qml/ObjectGraph.qml | 18 +- .../quickqanava/qml/VisualConnector.qml | 4 +- .../quickqanava/src/qanConnector.cpp | 7 +- .../workspace/quickqanava/src/qanConnector.h | 2 +- .../workspace/quickqanava/src/qanGraph.cpp | 5 +- 8 files changed, 358 insertions(+), 11 deletions(-) create mode 100644 plugins/workspace/nodeeditor/qml/EdgeTemplate.qml diff --git a/plugins/squareone/qml/qmldir b/plugins/squareone/qml/qmldir index d3fdd9c9..9bb576f2 100644 --- a/plugins/squareone/qml/qmldir +++ b/plugins/squareone/qml/qmldir @@ -3,6 +3,7 @@ module workspace.nodeeditor depends QtQuick 2.3 Edge 1.0 Edge.qml +EdgeTemplate 1.0 EdgeTemplate.qml ObjectGraph 1.0 ObjectGraph.qml ObjectNode 1.0 ObjectNode.qml ObjectNodeProperty 1.0 ObjectNodeProperty.qml diff --git a/plugins/workspace/nodeeditor/qml/Edge.qml b/plugins/workspace/nodeeditor/qml/Edge.qml index 330764a3..892f4dd9 100644 --- a/plugins/workspace/nodeeditor/qml/Edge.qml +++ b/plugins/workspace/nodeeditor/qml/Edge.qml @@ -8,10 +8,12 @@ Qan.EdgeItem { id: edgeItem // Private hack for visual connector edge color dynamic modification - property color color: '#6a6a6a' - Qan.EdgeTemplate { + property color color: style ? style.lineColor : Qt.rgba(0.,0.,0.,1.) + property var lineType: Qan.EdgeStyle.Straight + EdgeTemplate { anchors.fill: parent edgeItem: parent color: parent.color + lineType: parent.lineType } } diff --git a/plugins/workspace/nodeeditor/qml/EdgeTemplate.qml b/plugins/workspace/nodeeditor/qml/EdgeTemplate.qml new file mode 100644 index 00000000..3f57a95f --- /dev/null +++ b/plugins/workspace/nodeeditor/qml/EdgeTemplate.qml @@ -0,0 +1,326 @@ +/* + Copyright (c) 2008-2018, Benoit AUTHEMAN All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the author or Destrat.io nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +//----------------------------------------------------------------------------- +// This file is a part of the QuickQanava software library. Copyright 2014 Benoit AUTHEMAN. +// +// \file CurvedEdge.qml +// \author benoit@destrat.io +// \date 2017 11 17 +//----------------------------------------------------------------------------- + +import QtQuick 2.7 +import QtQuick.Layouts 1.3 +import QtQuick.Shapes 1.0 + +import workspace.quickqanava 2.0 as Qan + +Item { + id: edgeTemplate + antialiasing: true + property var edgeItem: undefined + + property color color: edgeItem && + edgeItem.style ? edgeItem.style.lineColor : Qt.rgba(0.,0.,0.,1.) + // Allow direct bypass of lstyle + property var lineType: edgeItem.style ? edgeItem.style.lineType : Qan.EdgeStyle.Straight + property var dashed : edgeItem.style && style.dashed ? ShapePath.DashLine : ShapePath.SolidLine + + property var k: { + if (!edgeItem || edgeItem.p2.x === edgeItem.p1.x) return 0 + return (edgeItem.p2.y - edgeItem.p1.y)/(edgeItem.p2.x - edgeItem.p1.x) + } + property var n: { + if (!edgeItem || edgeItem.p2.x === edgeItem.p1.x) return 0 + return edgeItem.p2.y - k*edgeItem.p2.x + } + + function lineYValue(x){ + if (edgeItem.p2.x === edgeItem.p1.x) + return (edgeItem.p1.y + edgeItem.p2.y)/2 + + return k*x+n + } + + Shape { + id: arrowHead + transformOrigin: Item.TopLeft + rotation: edgeItem.dstAngle + x: edgeItem.p2.x + y: edgeItem.p2.y + visible: ((edgeItem.dstShape === Qan.EdgeStyle.Arrow) || (edgeItem.dstShape === Qan.EdgeStyle.ArrowOpen)) + && edgeItem.visible && !edgeItem.hidden && edgeTemplate.lineType === Qan.EdgeStyle.Straight + ShapePath { + strokeColor: edgeTemplate.color + fillColor: edgeItem.dstShape === Qan.EdgeStyle.ArrowOpen ? Qt.rgba(0.,0.,0.,0.) : edgeTemplate.color + strokeWidth: edgeItem.style ? edgeItem.style.lineWidth : 2 + startX: edgeItem.dstA1.x; startY: edgeItem.dstA1.y + PathLine { x: edgeItem.dstA3.x; y: edgeItem.dstA3.y } + PathLine { x: edgeItem.dstA2.x; y: edgeItem.dstA2.y } + PathLine { x: edgeItem.dstA1.x; y: edgeItem.dstA1.y } + } + } + + Shape { + id: arrowHeadCurved + visible: ((edgeItem.dstShape === Qan.EdgeStyle.Arrow) || (edgeItem.dstShape === Qan.EdgeStyle.ArrowOpen)) + && edgeItem.visible && !edgeItem.hidden && edgeTemplate.lineType === Qan.EdgeStyle.Curved + ShapePath { + id: shapePathCurved + strokeColor: edgeTemplate.color + fillColor: edgeItem.dstShape === Qan.EdgeStyle.ArrowOpen ? Qt.rgba(0.,0.,0.,0.) : edgeTemplate.color + strokeWidth: edgeItem.style ? edgeItem.style.lineWidth : 2 + property var dx: 12 + property var dy: k*dx + startX: edgeItem.p2.x - shapePathCurved.dx; startY: edgeItem.p2.y - shapePathCurved.dy + PathLine { x: edgeItem.p2.x - 15 - shapePathCurved.dx; y: lineYValue(x) + 5 - shapePathCurved.dy} + PathLine { x: edgeItem.p2.x - 15 - shapePathCurved.dx; y: lineYValue(x) - 5 - shapePathCurved.dy} + PathLine { x: edgeItem.p2.x - shapePathCurved.dx; y: edgeItem.p2.y - shapePathCurved.dy } + } + } + Shape { + transformOrigin: Item.TopLeft + rotation: edgeItem.dstAngle + x: edgeItem.p2.x + y: edgeItem.p2.y + visible: ((edgeItem.dstShape === Qan.EdgeStyle.Circle) || (edgeItem.dstShape === Qan.EdgeStyle.CircleOpen)) + && edgeItem.visible && !edgeItem.hidden + ShapePath { + strokeColor: edgeTemplate.color + fillColor: edgeItem.dstShape === Qan.EdgeStyle.CircleOpen ? Qt.rgba(0.,0.,0.,0.) : edgeTemplate.color + strokeWidth: edgeItem.style ? edgeItem.style.lineWidth : 2 + startX: 0; startY: 0 + PathArc { + relativeX: edgeItem.dstA2.x; relativeY: edgeItem.dstA2.y + radiusX: edgeItem.dstA1.x; radiusY: edgeItem.dstA1.y; + } + PathArc { + relativeX: -edgeItem.dstA2.x; relativeY: edgeItem.dstA2.y + radiusX: edgeItem.dstA1.x; radiusY: edgeItem.dstA1.y; + } + } + } + Shape { + transformOrigin: Item.TopLeft + rotation: edgeItem.dstAngle + x: edgeItem.p2.x + y: edgeItem.p2.y + visible: ((edgeItem.dstShape === Qan.EdgeStyle.Rect) || (edgeItem.dstShape === Qan.EdgeStyle.RectOpen)) + && edgeItem.visible && !edgeItem.hidden + ShapePath { + strokeColor: edgeTemplate.color + fillColor: edgeItem.dstShape === Qan.EdgeStyle.RectOpen ? Qt.rgba(0.,0.,0.,0.) : edgeTemplate.color + strokeWidth: edgeItem.style ? edgeItem.style.lineWidth : 2 + startX: edgeItem.dstA1.x; startY: edgeItem.dstA1.y + PathLine { x: 0.; y: 0. } + PathLine { x: edgeItem.dstA3.x; y: edgeItem.dstA3.y } + PathLine { x: edgeItem.dstA2.x; y: edgeItem.dstA2.y } + PathLine { x: edgeItem.dstA1.x; y: edgeItem.dstA1.y } + } + } + Shape { + transformOrigin: Item.TopLeft + rotation: edgeItem.srcAngle + x: edgeItem.p1.x + y: edgeItem.p1.y + visible: ((edgeItem.srcShape === Qan.EdgeStyle.Arrow) || (edgeItem.srcShape === Qan.EdgeStyle.ArrowOpen)) + && edgeItem.visible && !edgeItem.hidden + ShapePath { + strokeColor: edgeTemplate.color + fillColor: edgeItem.srcShape === Qan.EdgeStyle.ArrowOpen ? Qt.rgba(0.,0.,0.,0.) : edgeTemplate.color + strokeWidth: edgeItem.style ? edgeItem.style.lineWidth : 2 + startX: edgeItem.srcA1.x; startY: edgeItem.srcA1.y + PathLine { x: edgeItem.srcA3.x; y: edgeItem.srcA3.y } + PathLine { x: edgeItem.srcA2.x; y: edgeItem.srcA2.y } + PathLine { x: edgeItem.srcA1.x; y: edgeItem.srcA1.y } + } + } + Shape { + transformOrigin: Item.TopLeft + rotation: edgeItem.srcAngle + x: edgeItem.p1.x + y: edgeItem.p1.y + visible: ((edgeItem.srcShape === Qan.EdgeStyle.Circle) || (edgeItem.srcShape === Qan.EdgeStyle.CircleOpen)) + && edgeItem.visible && !edgeItem.hidden + ShapePath { + strokeColor: edgeTemplate.color + fillColor: edgeItem.srcShape === Qan.EdgeStyle.CircleOpen ? Qt.rgba(0.,0.,0.,0.) : edgeTemplate.color + strokeWidth: edgeItem.style ? edgeItem.style.lineWidth : 2 + startX: 0; startY: 0 + PathArc { + relativeX: edgeItem.srcA2.x; relativeY: edgeItem.srcA2.y + radiusX: edgeItem.srcA1.x; radiusY: edgeItem.srcA1.y; + } + PathArc { + relativeX: -edgeItem.srcA2.x; relativeY: edgeItem.srcA2.y + radiusX: edgeItem.srcA1.x; radiusY: edgeItem.srcA1.y; + } + } + } + Shape { + transformOrigin: Item.TopLeft + rotation: edgeItem.srcAngle + x: edgeItem.p1.x + y: edgeItem.p1.y + visible: ((edgeItem.srcShape === Qan.EdgeStyle.Rect) || (edgeItem.srcShape === Qan.EdgeStyle.RectOpen)) + && edgeItem.visible && !edgeItem.hidden + ShapePath { + strokeColor: edgeTemplate.color + fillColor: edgeItem.srcShape === Qan.EdgeStyle.RectOpen ? Qt.rgba(0.,0.,0.,0.) : edgeTemplate.color + strokeWidth: edgeItem.style ? edgeItem.style.lineWidth : 2 + startX: edgeItem.srcA1.x; startY: edgeItem.srcA1.y + PathLine { x: 0.; y: 0. } + PathLine { x: edgeItem.srcA3.x; y: edgeItem.srcA3.y } + PathLine { x: edgeItem.srcA2.x; y: edgeItem.srcA2.y } + PathLine { x: edgeItem.srcA1.x; y: edgeItem.srcA1.y } + } + } + Component { + id: straightShapePath + ShapePath { + id: edgeShapePath + startX: edgeItem.p1.x + startY: edgeItem.p1.y + capStyle: ShapePath.FlatCap + strokeWidth: edgeItem.style ? edgeItem.style.lineWidth : 2 + strokeColor: edgeTemplate.color + strokeStyle: edgeTemplate.dashed + dashPattern: style ? style.dashPattern : [4, 2] + fillColor: Qt.rgba(0,0,0,0) + PathLine { + x: edgeItem.p2.x + y: edgeItem.p2.y + } + } + } + Component { + id: orthoShapePath + ShapePath { + id: edgeShapePath + startX: edgeItem.p1.x + startY: edgeItem.p1.y + capStyle: ShapePath.FlatCap + strokeWidth: edgeItem.style ? edgeItem.style.lineWidth : 2 + strokeColor: edgeTemplate.color + strokeStyle: edgeTemplate.dashed + dashPattern: style ? style.dashPattern : [4, 2] + fillColor: Qt.rgba(0,0,0,0) + PathLine { + x: edgeItem.c1.x + y: edgeItem.c1.y + } + PathLine { + x: edgeItem.p2.x + y: edgeItem.p2.y + } + } + } + Component { + id: curvedShapePath + ShapePath { + id: edgeShapePath + startX: edgeItem.p1.x + startY: edgeItem.p1.y + capStyle: ShapePath.FlatCap + strokeWidth: edgeItem.style ? edgeItem.style.lineWidth : 2 + strokeColor: edgeTemplate.color + strokeStyle: edgeTemplate.dashed + dashPattern: edgeItem.style ? style.dashPattern : [4, 2] + fillColor: Qt.rgba(0,0,0,0) + + PathLine { + x: edgeItem.p1.x + 30 + y: edgeTemplate.lineYValue(x) + } + + PathLine { + x: edgeItem.p1.x + 30 + y: edgeTemplate.lineYValue(x) + 30 + } + + PathLine { + x: edgeItem.p2.x - 40 + y: edgeTemplate.lineYValue(x) + 30 + } + + PathLine { + x: edgeItem.p2.x - 40 + y: edgeTemplate.lineYValue(x) + } + + + PathLine { + x: edgeItem.p2.x + y: edgeItem.p2.y + } + + } + } + + Shape { + id: edgeShape + anchors.fill: parent + visible: edgeItem.visible && !edgeItem.hidden + //asynchronous: true // FIXME: Benchmark that + antialiasing: true + smooth: true + property var curvedLine : undefined + property var straightLine : undefined + property var orthoLine : undefined + property var lineType: edgeTemplate.lineType + onLineTypeChanged: { + switch (lineType) { + case Qan.EdgeStyle.Straight: + if ( orthoLine ) + orthoLine.destroy() + if ( curvedLine ) + curvedLine.destroy() + straightLine = straightShapePath.createObject(edgeShape) + edgeShape.data = straightLine + break; + + case Qan.EdgeStyle.Ortho: + if ( straightLine ) + straightLine.destroy() + if ( curvedLine ) + curvedLine.destroy() + orthoLine = orthoShapePath.createObject(edgeShape) + edgeShape.data = orthoLine + break; + + case Qan.EdgeStyle.Curved: + if ( straightLine ) + straightLine.destroy() + if ( orthoLine ) + orthoLine.destroy() + curvedLine = curvedShapePath.createObject(edgeShape) + edgeShape.data = curvedLine + break; + } + } + } + +} diff --git a/plugins/workspace/nodeeditor/qml/ObjectGraph.qml b/plugins/workspace/nodeeditor/qml/ObjectGraph.qml index 3de0613a..16b2e177 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectGraph.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectGraph.qml @@ -308,8 +308,13 @@ Rectangle{ function bindPorts(src, dst){ var srcNode = src.objectProperty.node var dstNode = dst.objectProperty.node - - var edge = graph.insertEdge(srcNode, dstNode, graph.edgeDelegate) + var edge = null + if (srcNode === dstNode){ + edge = graph.insertEdge(srcNode, dstNode, graph.edgeDelegateCurved) + } else { + edge = graph.insertEdge(srcNode, dstNode, graph.edgeDelegate ) + } + graph.bindEdge(edge, src, dst) src.outEdges.push(edge) @@ -482,6 +487,7 @@ Rectangle{ connectorEdgeColor: root.style.connectorEdgeColor connectorColor: root.style.connectorColor edgeDelegate: Edge{} + property Component edgeDelegateCurved: Edge { lineType: Qan.EdgeStyle.Curved } verticalDockDelegate : VerticalDock{} portDelegate: Port{} selectionDelegate: Selection{} @@ -489,14 +495,18 @@ Rectangle{ onEdgeClicked: root.edgeClicked(edge) onNodeClicked : root.nodeClicked(node) onConnectorEdgeInserted : root.userEdgeInserted(edge) - selectionColor: "#fff" selectionWeight: 1 - nodeDelegate: ObjectNode{ nodeStyle: root.style.objectNodeStyle } Component.onCompleted : { + graph.connector.edgeComponent = graph.edgeDelegate + graph.connector.createEdgeHook = function(src, dst){ + if (src === dst) + return graph.edgeDelegateCurved + return graph.edgeDelegate + } graphView.navigable = Qt.binding(function(){ return root.isInteractive }) styleManager.styles.at(1).lineColor = root.style.connectorColor } diff --git a/plugins/workspace/quickqanava/qml/VisualConnector.qml b/plugins/workspace/quickqanava/qml/VisualConnector.qml index bf6a6d29..6b69e9d9 100644 --- a/plugins/workspace/quickqanava/qml/VisualConnector.qml +++ b/plugins/workspace/quickqanava/qml/VisualConnector.qml @@ -72,6 +72,8 @@ Qan.Connector { //! True when the connector item is currently dragged. property bool connectorDragged: dropDestArea.drag.active + property var createEdgeHook: null + edgeComponent: Component{ Qan.Edge{} } onEdgeColorChanged: { if (edgeItem) @@ -214,7 +216,7 @@ Qan.Connector { enabled: true onReleased: { if ( connectorItem.state === "HILIGHT" ) { - connectorReleased(visualConnector.Drag.target) + connectorReleased(visualConnector.Drag.target, createEdgeHook) } configureConnectorPosition() if (edgeItem) // Hide the edgeItem after a mouse release or it could diff --git a/plugins/workspace/quickqanava/src/qanConnector.cpp b/plugins/workspace/quickqanava/src/qanConnector.cpp index 65445aac..b30137f5 100644 --- a/plugins/workspace/quickqanava/src/qanConnector.cpp +++ b/plugins/workspace/quickqanava/src/qanConnector.cpp @@ -91,7 +91,7 @@ qan::NodeStyle* Connector::style() noexcept //----------------------------------------------------------------------------- /* Connector Configuration *///------------------------------------------------ -void Connector::connectorReleased(QQuickItem* target) noexcept +void Connector::connectorReleased(QQuickItem* target, QJSValue callback) noexcept { // qWarning() << "connectorReleased..."; // Restore original position @@ -140,8 +140,11 @@ void Connector::connectorReleased(QQuickItem* target) noexcept dstPortItem == nullptr ) create = _graph->isEdgeSourceBindable(*srcPortItem); if ( getCreateDefaultEdge() ) { + auto engine = qmlEngine(_graph); if ( create ) - createdEdge = _graph->insertEdge( srcNode, dstNode ); + createdEdge = _graph->insertEdge( srcNode, dstNode, + callback.isCallable() && engine ? qobject_cast(callback.call(QJSValueList() << engine->newQObject(srcNode) << engine->newQObject(dstNode)).toQObject()) : nullptr); + if ( createdEdge != nullptr ) { // Special handling for src or dst port item binding if ( srcPortItem ) _graph->bindEdgeSource(*createdEdge, *srcPortItem); diff --git a/plugins/workspace/quickqanava/src/qanConnector.h b/plugins/workspace/quickqanava/src/qanConnector.h index d8528587..15b82954 100644 --- a/plugins/workspace/quickqanava/src/qanConnector.h +++ b/plugins/workspace/quickqanava/src/qanConnector.h @@ -100,7 +100,7 @@ class Connector : public qan::NodeItem protected: //! Should be called from QML when connector draggable item is released other a target. - Q_INVOKABLE void connectorReleased(QQuickItem* target) noexcept; + Q_INVOKABLE void connectorReleased(QQuickItem* target, QJSValue callback) noexcept; //! Should be called from QML when connector draggable item is pressed. Q_INVOKABLE void connectorPressed() noexcept; diff --git a/plugins/workspace/quickqanava/src/qanGraph.cpp b/plugins/workspace/quickqanava/src/qanGraph.cpp index ae460da0..587a94d6 100644 --- a/plugins/workspace/quickqanava/src/qanGraph.cpp +++ b/plugins/workspace/quickqanava/src/qanGraph.cpp @@ -699,7 +699,10 @@ qan::Edge* Graph::insertEdge( QObject* source, QObject* destination, QQmlCompon } qan::Edge* Graph::insertEdge( qan::Node* source, qan::Node* destination, QQmlComponent* edgeComponent ) -{ +{ + if ( !edgeComponent ) + edgeComponent = getEdgeDelegate(); + // PRECONDITION; // source and destination can't be nullptr if ( source == nullptr || From 95d067e9a42239d34fb9700683c89b9e1d8d6f47 Mon Sep 17 00:00:00 2001 From: nenad-popovic-91 <42581059+nenad-popovic-91@users.noreply.github.com> Date: Thu, 27 May 2021 13:29:19 +0200 Subject: [PATCH 46/91] Helper objects for displaying detection results (#215) lcvcore: Added DrawFaces --- plugins/lcvimgproc/lcvimgproc.pro | 1 + plugins/lcvimgproc/qml/DrawDetectedFaces.qml | 29 ++++++++++++++++++++ plugins/lcvimgproc/qml/qmldir | 23 ++++++++-------- 3 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 plugins/lcvimgproc/qml/DrawDetectedFaces.qml diff --git a/plugins/lcvimgproc/lcvimgproc.pro b/plugins/lcvimgproc/lcvimgproc.pro index 7895395a..cddce9f8 100644 --- a/plugins/lcvimgproc/lcvimgproc.pro +++ b/plugins/lcvimgproc/lcvimgproc.pro @@ -53,6 +53,7 @@ OTHER_FILES *= \ DISTFILES += \ qml/Blend.qml \ + qml/DrawDetectedFaces.qml \ qml/FaceDetection.qml \ qml/Pad.qml \ qml/Resize.qml \ diff --git a/plugins/lcvimgproc/qml/DrawDetectedFaces.qml b/plugins/lcvimgproc/qml/DrawDetectedFaces.qml new file mode 100644 index 00000000..20188c2f --- /dev/null +++ b/plugins/lcvimgproc/qml/DrawDetectedFaces.qml @@ -0,0 +1,29 @@ +import QtQuick 2.3 +import lcvcore 1.0 as LcvCore +import base 1.0 +import lcvimgproc 1.0 as ImgProc +import fs 1.0 as Fs + +Act{ + id: drawDetectedFaces + + property var mat: null + property var faces: null + + run: function(mat, faces){ + if (!mat || !faces) return null + var writable = LcvCore.MatOp.createWritableFromMat(mat) + for (var i=0; i < faces.length; ++i){ + var face = faces[i] + + ImgProc.Draw.rectangle( + writable, + Qt.point(face.x, face.y), + Qt.point(face.x+face.width, face.y + face.height), + "lightblue") + } + return writable + } + args: ["$mat", "$faces"] + +} diff --git a/plugins/lcvimgproc/qml/qmldir b/plugins/lcvimgproc/qml/qmldir index a5ccf0e9..4fe448f5 100644 --- a/plugins/lcvimgproc/qml/qmldir +++ b/plugins/lcvimgproc/qml/qmldir @@ -4,14 +4,15 @@ plugin lcvimgproc depends QtQuick 2.3 depends lcvcore 1.0 -PanAndZoom 1.0 PanAndZoom.qml -Resize 1.0 Resize.qml -ResizeWithAspect 1.0 ResizeWithAspect.qml -Scale 1.0 Scale.qml -Rotate 1.0 Rotate.qml -ResizeTool 1.0 ResizeTool.qml -RotateTool 1.0 RotateTool.qml -Threshold 1.0 Threshold.qml -Blend 1.0 Blend.qml -FaceDetection 1.0 FaceDetection.qml -Pad 1.0 Pad.qml +PanAndZoom 1.0 PanAndZoom.qml +Resize 1.0 Resize.qml +ResizeWithAspect 1.0 ResizeWithAspect.qml +Scale 1.0 Scale.qml +Rotate 1.0 Rotate.qml +ResizeTool 1.0 ResizeTool.qml +RotateTool 1.0 RotateTool.qml +Threshold 1.0 Threshold.qml +Blend 1.0 Blend.qml +FaceDetection 1.0 FaceDetection.qml +DrawDetectedFaces 1.0 DrawDetectedFaces.qml +Pad 1.0 Pad.qml From 48f861443890b1a7f64fdbb190cbe2883d6f51a2 Mon Sep 17 00:00:00 2001 From: nenad-popovic-91 <42581059+nenad-popovic-91@users.noreply.github.com> Date: Mon, 31 May 2021 10:22:45 +0200 Subject: [PATCH 47/91] Curved edges with fixed positioning (#216) * Fixes arrow positioning on ortho edges --- .../workspace/nodeeditor/qml/EdgeTemplate.qml | 73 +++++++++++-------- 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/plugins/workspace/nodeeditor/qml/EdgeTemplate.qml b/plugins/workspace/nodeeditor/qml/EdgeTemplate.qml index 3f57a95f..4b336a90 100644 --- a/plugins/workspace/nodeeditor/qml/EdgeTemplate.qml +++ b/plugins/workspace/nodeeditor/qml/EdgeTemplate.qml @@ -49,21 +49,12 @@ Item { property var lineType: edgeItem.style ? edgeItem.style.lineType : Qan.EdgeStyle.Straight property var dashed : edgeItem.style && style.dashed ? ShapePath.DashLine : ShapePath.SolidLine - property var k: { - if (!edgeItem || edgeItem.p2.x === edgeItem.p1.x) return 0 - return (edgeItem.p2.y - edgeItem.p1.y)/(edgeItem.p2.x - edgeItem.p1.x) - } - property var n: { - if (!edgeItem || edgeItem.p2.x === edgeItem.p1.x) return 0 - return edgeItem.p2.y - k*edgeItem.p2.x - } + property var rightSideHeight: 0 + property var nodeWidth: 0 + property var padWidth: 0 - function lineYValue(x){ - if (edgeItem.p2.x === edgeItem.p1.x) - return (edgeItem.p1.y + edgeItem.p2.y)/2 - - return k*x+n - } + property var p1y: edgeItem.p1.y + (edgeItem.p1.y > edgeItem.p2.y ? 8 : -8) + property var p2y: edgeItem.p2.y + (edgeItem.p1.y > edgeItem.p2.y ? -10 : 10) Shape { id: arrowHead @@ -93,12 +84,10 @@ Item { strokeColor: edgeTemplate.color fillColor: edgeItem.dstShape === Qan.EdgeStyle.ArrowOpen ? Qt.rgba(0.,0.,0.,0.) : edgeTemplate.color strokeWidth: edgeItem.style ? edgeItem.style.lineWidth : 2 - property var dx: 12 - property var dy: k*dx - startX: edgeItem.p2.x - shapePathCurved.dx; startY: edgeItem.p2.y - shapePathCurved.dy - PathLine { x: edgeItem.p2.x - 15 - shapePathCurved.dx; y: lineYValue(x) + 5 - shapePathCurved.dy} - PathLine { x: edgeItem.p2.x - 15 - shapePathCurved.dx; y: lineYValue(x) - 5 - shapePathCurved.dy} - PathLine { x: edgeItem.p2.x - shapePathCurved.dx; y: edgeItem.p2.y - shapePathCurved.dy } + startX: edgeItem.p2.x - 15; startY: edgeTemplate.p2y + PathLine { x: edgeItem.p2.x - 30; y: edgeTemplate.p2y + 5} + PathLine { x: edgeItem.p2.x - 30; y: edgeTemplate.p2y - 5} + PathLine { x: edgeItem.p2.x - 15; y: edgeTemplate.p2y } } } Shape { @@ -243,7 +232,7 @@ Item { ShapePath { id: edgeShapePath startX: edgeItem.p1.x - startY: edgeItem.p1.y + startY: edgeTemplate.p1y capStyle: ShapePath.FlatCap strokeWidth: edgeItem.style ? edgeItem.style.lineWidth : 2 strokeColor: edgeTemplate.color @@ -252,34 +241,58 @@ Item { fillColor: Qt.rgba(0,0,0,0) PathLine { - x: edgeItem.p1.x + 30 - y: edgeTemplate.lineYValue(x) + x: edgeItem.p1.x + edgeTemplate.padWidth + y: edgeTemplate.p1y + } PathLine { - x: edgeItem.p1.x + 30 - y: edgeTemplate.lineYValue(x) + 30 + x: edgeItem.p1.x + edgeTemplate.padWidth + y: edgeTemplate.p1y + edgeTemplate.rightSideHeight } PathLine { - x: edgeItem.p2.x - 40 - y: edgeTemplate.lineYValue(x) + 30 + x: edgeItem.p1.x - edgeTemplate.padWidth - edgeTemplate.nodeWidth + y: edgeTemplate.p1y + edgeTemplate.rightSideHeight } PathLine { - x: edgeItem.p2.x - 40 - y: edgeTemplate.lineYValue(x) + x: edgeItem.p1.x - edgeTemplate.padWidth - edgeTemplate.nodeWidth + y: edgeTemplate.p2y } PathLine { x: edgeItem.p2.x - y: edgeItem.p2.y + y: edgeTemplate.p2y } } } + Connections { + target: edgeItem + ignoreUnknownSignals: false + function onSourceItemChanged(){ + if (!edgeItem.sourceItem) return + var p = edgeItem.sourceItem + + while (p && p.objectName !== "objectNode"){ + p = p.parent + } + if (p){ + edgeTemplate.padWidth = 25 + (edgeItem.sourceItem.outEdges ? edgeItem.sourceItem.outEdges.length*5 : 0) + + edgeTemplate.rightSideHeight = Qt.binding(function(){ + return p.height - edgeItem.p1.y + (edgeItem.sourceItem.outEdges ? edgeItem.sourceItem.outEdges.length*5 : 0) + }) + edgeTemplate.nodeWidth = Qt.binding(function(){ + return p.width + }) + } + } + } + Shape { id: edgeShape anchors.fill: parent From fb45ef06b4f3f0b847ca52509d8139ea0f143c83 Mon Sep 17 00:00:00 2001 From: nenad-popovic-91 <42581059+nenad-popovic-91@users.noreply.github.com> Date: Wed, 2 Jun 2021 19:39:48 +0200 Subject: [PATCH 48/91] Moved input objects from workspace to visual.input (#217) Moved input objects from workspace to visual.input --- application/qml/MessagesContainer.qml | 8 +- application/qml/ProjectAddEntry.qml | 3 +- application/qml/workspace.qml | 4 +- plugins/base/baseqml/palettes/ExecPalette.qml | 4 +- plugins/editor/palettes/BuilderPalette.qml | 10 +- plugins/editor/palettes/ColorPalette.qml | 3 +- plugins/editor/palettes/ConnectionPalette.qml | 6 +- plugins/editor/palettes/DoublePalette.qml | 8 +- plugins/editor/palettes/FilePathPalette.qml | 3 +- plugins/editor/palettes/FolderPathPalette.qml | 3 +- plugins/editor/palettes/ImportsPalette.qml | 14 +- plugins/editor/palettes/IntInputPalette.qml | 6 +- plugins/editor/palettes/IntPalette.qml | 8 +- plugins/editor/palettes/SizePalette.qml | 8 +- plugins/editor/palettes/StringListPalette.qml | 6 +- plugins/editor/palettes/TextPalette.qml | 6 +- plugins/editor/palettes/TriggerPalette.qml | 6 +- plugins/editor/qml/Editor.qml | 4 +- plugins/editor/qml/EditorPane.qml | 3 +- plugins/editor/qml/PaletteConnection.qml | 16 +-- plugins/editor/qml/PaletteListView.qml | 6 +- plugins/editor/qml/WorkspaceTheme.qml | 62 ++++----- plugins/editqml/qml/AddQmlBox.qml | 24 ++-- plugins/editqml/qml/PaletteStyle.qml | 15 +- plugins/fs/fsqml/qml/SelectableFolderView.qml | 6 +- plugins/lcvcore/palettes/ImagePalette.qml | 8 +- .../palettes/ImageSegmentFactoryPalette.qml | 4 +- .../PerspectiveOnBackgroundPalette.qml | 7 +- .../lcvcore/palettes/VideoSurfacePalette.qml | 8 +- plugins/lcvcore/qml/BrushTool.qml | 15 +- plugins/lcvcore/qml/CropTool.qml | 12 +- plugins/lcvcore/qml/GradientTool.qml | 5 +- plugins/lcvcore/qml/ImageDrawView.qml | 14 +- plugins/lcvcore/qml/ImageSegmentCreator.qml | 8 +- plugins/lcvcore/qml/PerspectiveTool.qml | 11 +- .../lcvcore/qml/ScriptVideoSegmentCreator.qml | 8 +- .../qml/VideoCaptureSegmentCreator.qml | 8 +- .../lcvcore/qml/VideoCaptureSegmentEditor.qml | 8 +- plugins/lcvcore/qml/VideoSurfaceCreator.qml | 11 +- plugins/lcvimgproc/qml/ResizeTool.qml | 13 +- plugins/lcvimgproc/qml/RotateTool.qml | 12 +- .../qml/palettes/TransformPalette.qml | 8 +- .../palettes/BrightnessAndContrastPalette.qml | 6 +- .../qml/HueSaturationLightnessSliders.qml | 14 +- plugins/lcvphoto/qml/LevelsSliders.qml | 10 +- plugins/timeline/palettes/TimelinePalette.qml | 3 +- plugins/timeline/qml/KeyframeEditor.qml | 5 +- plugins/timeline/qml/TimelineStyle.qml | 8 +- plugins/timeline/qml/TimelineView.qml | 6 +- plugins/timeline/qml/TrackTitle.qml | 4 +- .../visualqml/input}/qml/Button.qml | 0 .../visualqml/input/qml/ColorHSVPicker.qml} | 16 +-- .../input}/qml/ConvexQuadSelection.qml | 0 .../visualqml/input/qml/DropDownStyle.qml | 3 +- .../visualqml/input}/qml/EditableLabel.qml | 15 +- .../visualqml/input}/qml/LabelOnRectangle.qml | 5 +- .../input}/qml/LabelOnRectangleStyle.qml | 0 .../visualqml/input}/qml/NumberLabel.qml | 2 +- .../visualqml/input}/qml/PathInputBox.qml | 4 +- .../visual/visualqml/input/qml/PlayPause.qml | 42 ++++++ .../visualqml/input}/qml/RectangleButton.qml | 3 +- .../input}/qml/RectangleButtonStyle.qml | 0 .../input}/qml/RectangleSelection.qml | 0 .../input}/qml/SelectableListView.qml | 3 +- .../input}/qml/SelectableListViewStyle.qml | 0 .../visualqml/input}/qml/TextButton.qml | 7 +- .../visualqml/input}/qml/TextButtonStyle.qml | 0 plugins/visual/visualqml/input/qml/qmldir | 34 +++-- .../workspace/nodeeditor/qml/ObjectGraph.qml | 6 +- .../workspace/nodeeditor/qml/ObjectNode.qml | 6 +- .../nodeeditor/qml/ObjectNodeProperty.qml | 5 +- plugins/workspace/qml/InputBox.qml | 130 ------------------ plugins/workspace/qml/InputBoxStyle.qml | 11 -- plugins/workspace/qml/Label.qml | 7 - plugins/workspace/qml/PopupMenuStyle.qml | 5 +- plugins/workspace/qml/TextStyle.qml | 11 -- plugins/workspace/qml/Tooltip.qml | 4 +- plugins/workspace/qml/qmldir | 20 --- 78 files changed, 346 insertions(+), 451 deletions(-) rename plugins/{workspace => visual/visualqml/input}/qml/Button.qml (100%) rename plugins/{workspace/qml/ColorPicker.qml => visual/visualqml/input/qml/ColorHSVPicker.qml} (97%) rename plugins/{workspace => visual/visualqml/input}/qml/ConvexQuadSelection.qml (100%) rename plugins/{workspace => visual/visualqml/input}/qml/EditableLabel.qml (95%) rename plugins/{workspace => visual/visualqml/input}/qml/LabelOnRectangle.qml (78%) rename plugins/{workspace => visual/visualqml/input}/qml/LabelOnRectangleStyle.qml (100%) rename plugins/{workspace => visual/visualqml/input}/qml/NumberLabel.qml (98%) rename plugins/{workspace => visual/visualqml/input}/qml/PathInputBox.qml (97%) create mode 100644 plugins/visual/visualqml/input/qml/PlayPause.qml rename plugins/{workspace => visual/visualqml/input}/qml/RectangleButton.qml (87%) rename plugins/{workspace => visual/visualqml/input}/qml/RectangleButtonStyle.qml (100%) rename plugins/{workspace => visual/visualqml/input}/qml/RectangleSelection.qml (100%) rename plugins/{workspace => visual/visualqml/input}/qml/SelectableListView.qml (97%) rename plugins/{workspace => visual/visualqml/input}/qml/SelectableListViewStyle.qml (100%) rename plugins/{workspace => visual/visualqml/input}/qml/TextButton.qml (89%) rename plugins/{workspace => visual/visualqml/input}/qml/TextButtonStyle.qml (100%) delete mode 100644 plugins/workspace/qml/InputBox.qml delete mode 100644 plugins/workspace/qml/InputBoxStyle.qml delete mode 100644 plugins/workspace/qml/Label.qml delete mode 100644 plugins/workspace/qml/TextStyle.qml diff --git a/application/qml/MessagesContainer.qml b/application/qml/MessagesContainer.qml index 26bf510e..ef9b3299 100644 --- a/application/qml/MessagesContainer.qml +++ b/application/qml/MessagesContainer.qml @@ -1,8 +1,8 @@ import QtQuick 2.3 import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.2 -import workspace 1.0 as Workspace import workspace.icons 1.0 as Icons +import visual.input 1.0 as Input Rectangle { id: root @@ -97,7 +97,7 @@ Rectangle { } } - Workspace.SelectableListView { + Input.SelectableListView { id: listView anchors.top: parent.top anchors.topMargin: 30 @@ -149,7 +149,7 @@ Rectangle { width: parent.width - 35 height: msgText.height - Workspace.Label{ + Input.Label{ id: msgText width: listView.width - 55 text: model.message @@ -203,7 +203,7 @@ Rectangle { width: parent.width - 35 height: noMsgsText.height - Workspace.Label{ + Input.Label{ id: noMsgsText width: listView.width - 55 font.italic: true diff --git a/application/qml/ProjectAddEntry.qml b/application/qml/ProjectAddEntry.qml index d30515ab..6ed13281 100644 --- a/application/qml/ProjectAddEntry.qml +++ b/application/qml/ProjectAddEntry.qml @@ -19,7 +19,6 @@ import editor 1.0 import editor.private 1.0 import base 1.0 import visual.input 1.0 as Input -import workspace 1.0 as Workspace Rectangle{ id: root @@ -117,7 +116,7 @@ Rectangle{ } } - Workspace.Button{ + Input.Button{ anchors.right: parent.right anchors.rightMargin: 10 anchors.bottom: parent.bottom diff --git a/application/qml/workspace.qml b/application/qml/workspace.qml index 92b36bf8..b7f9f7c3 100644 --- a/application/qml/workspace.qml +++ b/application/qml/workspace.qml @@ -22,9 +22,9 @@ import QtQuick.Window 2.0 import base 1.0 import editor 1.0 import editor.private 1.0 -import workspace 1.0 as Workspace import workspace.icons 1.0 as Icons import live 1.0 +import visual.input 1.0 as Input Item{ id: root @@ -394,7 +394,7 @@ Item{ runSpace: root.runSpace } - property Component messageDialogButton: Workspace.TextButton{ + property Component messageDialogButton: Input.TextButton{ height: 28 width: 100 style: lk.layers.workspace.themes.current.formButtonStyle diff --git a/plugins/base/baseqml/palettes/ExecPalette.qml b/plugins/base/baseqml/palettes/ExecPalette.qml index 1137817e..f1a9a7fb 100644 --- a/plugins/base/baseqml/palettes/ExecPalette.qml +++ b/plugins/base/baseqml/palettes/ExecPalette.qml @@ -20,7 +20,7 @@ import QtQuick.Controls.Styles 1.4 import editor 1.0 import live 1.0 import base 1.0 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input CodePalette{ id: palette @@ -36,7 +36,7 @@ CodePalette{ property var current : null - Workspace.TextButton{ + Input.TextButton{ id: textButton anchors.horizontalCenter: parent.horizontalCenter anchors.left: parent.left diff --git a/plugins/editor/palettes/BuilderPalette.qml b/plugins/editor/palettes/BuilderPalette.qml index 8713301c..5df99407 100644 --- a/plugins/editor/palettes/BuilderPalette.qml +++ b/plugins/editor/palettes/BuilderPalette.qml @@ -20,7 +20,7 @@ import QtQuick.Controls.Styles 1.4 import editor 1.0 import editqml 1.0 as QmlEdit import live 1.0 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input CodePalette{ id: palette @@ -89,7 +89,7 @@ CodePalette{ width: 280 height: 50 - Workspace.TextButton{ + Input.TextButton{ visible: !hasBuilder text: 'Add Builder' height: 22 @@ -98,7 +98,7 @@ CodePalette{ onClicked : palette.createBuilder() } - Workspace.Label{ + Input.Label{ id: title anchors.top: parent.top anchors.topMargin: 2 @@ -112,7 +112,7 @@ CodePalette{ visible: hasBuilder } - Workspace.PathInputBox{ + Input.PathInputBox{ id: pathInput anchors.left: parent.left anchors.leftMargin: 5 @@ -127,7 +127,7 @@ CodePalette{ } } - Workspace.Button{ + Input.Button{ anchors.top: parent.top anchors.topMargin: 25 anchors.right: parent.right diff --git a/plugins/editor/palettes/ColorPalette.qml b/plugins/editor/palettes/ColorPalette.qml index b67aeb9d..271d3d36 100644 --- a/plugins/editor/palettes/ColorPalette.qml +++ b/plugins/editor/palettes/ColorPalette.qml @@ -20,7 +20,6 @@ import QtQuick.Controls.Styles 1.4 import QtGraphicalEffects 1.0 import live 1.0 import editor 1.0 -import workspace 1.0 as Workspace import visual.input 1.0 as Input CodePalette{ @@ -79,7 +78,7 @@ CodePalette{ anchors.left: parent.left anchors.leftMargin: colorDisplay.width + 2 - Workspace.InputBox{ + Input.InputBox{ id: input height: 25 anchors.top: parent.top diff --git a/plugins/editor/palettes/ConnectionPalette.qml b/plugins/editor/palettes/ConnectionPalette.qml index b9f5d65a..a698b04b 100644 --- a/plugins/editor/palettes/ConnectionPalette.qml +++ b/plugins/editor/palettes/ConnectionPalette.qml @@ -20,7 +20,7 @@ import QtQuick.Controls.Styles 1.4 import editor 1.0 import editqml 1.0 as QmlEdit import live 1.0 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input CodePalette{ id: palette @@ -72,7 +72,7 @@ CodePalette{ height: 25 color: 'transparent' - Workspace.InputBox{ + Input.InputBox{ id: input anchors.left: parent.left anchors.right: parent.right @@ -166,7 +166,7 @@ CodePalette{ } } - Workspace.Button{ + Input.Button{ id: commitButton anchors.right: parent.right width: 30 diff --git a/plugins/editor/palettes/DoublePalette.qml b/plugins/editor/palettes/DoublePalette.qml index 670c022f..abf210dd 100644 --- a/plugins/editor/palettes/DoublePalette.qml +++ b/plugins/editor/palettes/DoublePalette.qml @@ -19,8 +19,8 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.2 import editor 1.0 import live 1.0 as L -import workspace 1.0 as Workspace import visual.shapes 1.0 as Vs +import visual.input 1.0 as Input CodePalette{ id: palette @@ -32,7 +32,7 @@ CodePalette{ width: 330 height: 25 - Workspace.InputBox{ + Input.InputBox{ id: numberInput anchors.left: parent.left width: 70 @@ -166,7 +166,7 @@ CodePalette{ } } - Workspace.NumberLabel{ + Input.NumberLabel{ id: leftLabel mode: 1 anchors.top: parent.top @@ -216,7 +216,7 @@ CodePalette{ - Workspace.NumberLabel{ + Input.NumberLabel{ id: rightLabel mode: 2 anchors.top: parent.top diff --git a/plugins/editor/palettes/FilePathPalette.qml b/plugins/editor/palettes/FilePathPalette.qml index 8de77df1..d0272ca7 100644 --- a/plugins/editor/palettes/FilePathPalette.qml +++ b/plugins/editor/palettes/FilePathPalette.qml @@ -4,6 +4,7 @@ import QtQuick.Controls.Styles 1.2 import editor 1.0 import live 1.0 import workspace 1.0 +import visual.input 1.0 as Input CodePalette{ id: palette @@ -15,7 +16,7 @@ CodePalette{ width: 180 height: 25 - PathInputBox{ + Input.PathInputBox{ id: inputBox width: parent.width height: 25 diff --git a/plugins/editor/palettes/FolderPathPalette.qml b/plugins/editor/palettes/FolderPathPalette.qml index 8f46f57f..fce30b81 100644 --- a/plugins/editor/palettes/FolderPathPalette.qml +++ b/plugins/editor/palettes/FolderPathPalette.qml @@ -4,6 +4,7 @@ import QtQuick.Controls.Styles 1.2 import editor 1.0 import live 1.0 import workspace 1.0 +import visual.input 1.0 as Input CodePalette{ id: palette @@ -15,7 +16,7 @@ CodePalette{ width: 180 height: 25 - PathInputBox{ + Input.PathInputBox{ id: inputBox width: parent.width height: 25 diff --git a/plugins/editor/palettes/ImportsPalette.qml b/plugins/editor/palettes/ImportsPalette.qml index bf2e954c..82e1c003 100644 --- a/plugins/editor/palettes/ImportsPalette.qml +++ b/plugins/editor/palettes/ImportsPalette.qml @@ -3,8 +3,8 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.2 import editor 1.0 import live 1.0 -import workspace 1.0 as Workspace import workspace.icons 1.0 as Icons +import visual.input 1.0 as Input CodePalette{ id: palette @@ -63,7 +63,7 @@ CodePalette{ height : 20 color: palette.theme.colorScheme.backgroundOverlay - Workspace.Label{ + Input.Label{ id: moduleText anchors.top: parent.top anchors.topMargin: 3 @@ -100,7 +100,7 @@ CodePalette{ anchors.bottom: parent.bottom anchors.bottomMargin: 2 - Workspace.InputBox{ + Input.InputBox{ id: moduleInput anchors.left: parent.left anchors.leftMargin: 3 @@ -124,7 +124,7 @@ CodePalette{ style: theme.inputStyle } - Workspace.InputBox{ + Input.InputBox{ id: versionInput anchors.left: parent.left anchors.leftMargin: 149 @@ -149,7 +149,7 @@ CodePalette{ } } - Workspace.InputBox{ + Input.InputBox{ id: qualifierInput anchors.left: parent.left anchors.leftMargin: 191 @@ -175,7 +175,7 @@ CodePalette{ } - Workspace.Button{ + Input.Button{ anchors.left: qualifierInput.right anchors.leftMargin: 5 anchors.top: parent.top @@ -190,7 +190,7 @@ CodePalette{ } } - Workspace.Button{ + Input.Button{ id: showAddImportsButton anchors.top: parent.top anchors.topMargin: 5 diff --git a/plugins/editor/palettes/IntInputPalette.qml b/plugins/editor/palettes/IntInputPalette.qml index 44d50bc4..8329e6f5 100644 --- a/plugins/editor/palettes/IntInputPalette.qml +++ b/plugins/editor/palettes/IntInputPalette.qml @@ -3,7 +3,7 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.2 import editor 1.0 import live 1.0 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input CodePalette{ id: palette @@ -19,7 +19,7 @@ CodePalette{ property alias path: pathInput.text property alias font: pathInput.font - Workspace.InputBox{ + Input.InputBox{ id: pathInput anchors.left: parent.left width: parent.width - 30 @@ -38,7 +38,7 @@ CodePalette{ } } - Workspace.Button{ + Input.Button{ anchors.right: parent.right width: 30 height: 25 diff --git a/plugins/editor/palettes/IntPalette.qml b/plugins/editor/palettes/IntPalette.qml index 5a71f787..5d6d719b 100644 --- a/plugins/editor/palettes/IntPalette.qml +++ b/plugins/editor/palettes/IntPalette.qml @@ -19,7 +19,7 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.4 import editor 1.0 import live 1.0 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input CodePalette{ id: palette @@ -33,7 +33,7 @@ CodePalette{ color: 'transparent' - Workspace.InputBox{ + Input.InputBox{ id: numberInput anchors.left: parent.left width: 70 @@ -76,7 +76,7 @@ CodePalette{ wheelEnabled: intSlider.activeFocus } - Workspace.NumberLabel{ + Input.NumberLabel{ id: leftLabel mode: 1 anchors.top: parent.top @@ -125,7 +125,7 @@ CodePalette{ - Workspace.NumberLabel{ + Input.NumberLabel{ id: rightLabel mode: 2 anchors.top: parent.top diff --git a/plugins/editor/palettes/SizePalette.qml b/plugins/editor/palettes/SizePalette.qml index 0a5eb64e..2d0585ca 100644 --- a/plugins/editor/palettes/SizePalette.qml +++ b/plugins/editor/palettes/SizePalette.qml @@ -3,7 +3,7 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.2 import editor 1.0 import live 1.0 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input CodePalette { id: palette @@ -14,7 +14,7 @@ CodePalette { height: 24 width: 160 - Workspace.InputBox{ + Input.InputBox{ id: widthInput anchors.left: parent.left width: 50 @@ -44,7 +44,7 @@ CodePalette { color: "white" } - Workspace.InputBox{ + Input.InputBox{ id: heightInput anchors.left: widthInput.right anchors.leftMargin: 20 @@ -65,7 +65,7 @@ CodePalette { } } - Workspace.Button{ + Input.Button{ anchors.right: parent.right width: 30 height: 25 diff --git a/plugins/editor/palettes/StringListPalette.qml b/plugins/editor/palettes/StringListPalette.qml index d5d3d9fd..201eb276 100644 --- a/plugins/editor/palettes/StringListPalette.qml +++ b/plugins/editor/palettes/StringListPalette.qml @@ -3,7 +3,7 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.2 import editor 1.0 import live 1.0 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input CodePalette{ id: palette @@ -113,7 +113,7 @@ CodePalette{ anchors.bottom: parent.bottom anchors.bottomMargin: updateButton.height + 10 - Workspace.InputBox{ + Input.InputBox{ id: inputBox anchors.left: parent.left anchors.leftMargin: 10 @@ -157,7 +157,7 @@ CodePalette{ } } - Workspace.TextButton{ + Input.TextButton{ id: updateButton anchors.horizontalCenter: parent.horizontalCenter anchors.left: parent.left diff --git a/plugins/editor/palettes/TextPalette.qml b/plugins/editor/palettes/TextPalette.qml index 5804a441..b6431f3b 100644 --- a/plugins/editor/palettes/TextPalette.qml +++ b/plugins/editor/palettes/TextPalette.qml @@ -3,7 +3,7 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.2 import editor 1.0 import live 1.0 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input CodePalette{ id: palette @@ -19,7 +19,7 @@ CodePalette{ property alias path: pathInput.text property alias font: pathInput.font - Workspace.InputBox{ + Input.InputBox{ id: pathInput anchors.left: parent.left width: parent.width - 30 @@ -38,7 +38,7 @@ CodePalette{ } } - Workspace.Button{ + Input.Button{ anchors.right: parent.right width: 30 height: 25 diff --git a/plugins/editor/palettes/TriggerPalette.qml b/plugins/editor/palettes/TriggerPalette.qml index 42747281..552827db 100644 --- a/plugins/editor/palettes/TriggerPalette.qml +++ b/plugins/editor/palettes/TriggerPalette.qml @@ -20,7 +20,7 @@ import QtQuick.Controls.Styles 1.4 import editor 1.0 import editqml 1.0 as QmlEdit import live 1.0 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input CodePalette{ id: palette @@ -77,7 +77,7 @@ CodePalette{ //TODO: ErrorBox when not binding - Workspace.InputBox{ + Input.InputBox{ id: input anchors.left: parent.left anchors.right: parent.right @@ -171,7 +171,7 @@ CodePalette{ } } - Workspace.Button{ + Input.Button{ id: commitButton anchors.right: parent.right width: 30 diff --git a/plugins/editor/qml/Editor.qml b/plugins/editor/qml/Editor.qml index de0955c7..b7badd9c 100644 --- a/plugins/editor/qml/Editor.qml +++ b/plugins/editor/qml/Editor.qml @@ -5,7 +5,7 @@ import editor 1.0 import editor.private 1.0 import base 1.0 import live 1.0 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input Rectangle{ id: root @@ -521,7 +521,7 @@ Rectangle{ } - Workspace.TextButton{ + Input.TextButton{ id: addRootButton anchors.left: lineSurfaceBackground.right anchors.leftMargin: 10 diff --git a/plugins/editor/qml/EditorPane.qml b/plugins/editor/qml/EditorPane.qml index bc7fb4df..664c6e89 100644 --- a/plugins/editor/qml/EditorPane.qml +++ b/plugins/editor/qml/EditorPane.qml @@ -22,6 +22,7 @@ import editor.private 1.0 import workspace 1.0 as Workspace import base 1.0 import fs 1.0 as Fs +import visual.input 1.0 as Input Pane{ id : root @@ -263,7 +264,7 @@ Pane{ } } - Workspace.Button{ + Input.Button{ id: shapeAllButton anchors.right: parent.right anchors.rightMargin: 110 diff --git a/plugins/editor/qml/PaletteConnection.qml b/plugins/editor/qml/PaletteConnection.qml index c3ca7146..637886b7 100644 --- a/plugins/editor/qml/PaletteConnection.qml +++ b/plugins/editor/qml/PaletteConnection.qml @@ -5,9 +5,9 @@ import base 1.0 import live 1.0 import editor 1.0 import editor.private 1.0 -import workspace 1.0 as Workspace import workspace.icons 1.0 as Icons import visual.shapes 1.0 +import visual.input 1.0 as Input Rectangle{ id: root @@ -32,8 +32,8 @@ Rectangle{ property QtObject editingFragment: null - property Workspace.TextStyle labelStyle: theme.inputLabelStyle.textStyle - property Workspace.TextStyle smallLabelStyle: theme.smallLabelStyle + property Input.TextStyle labelStyle: theme.inputLabelStyle.textStyle + property Input.TextStyle smallLabelStyle: theme.smallLabelStyle property int maxHeight: 160 @@ -103,7 +103,7 @@ Rectangle{ height: 23 width: parent.width - 5 color: root.theme.colorScheme.middleground - Workspace.Label{ + Input.Label{ id: componentLabel anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left @@ -164,7 +164,7 @@ Rectangle{ } } - Workspace.Label{ + Input.Label{ id: pathText anchors.left: pathIconLoader.right anchors.leftMargin: pathIconLoader.visible ? 8 : 0 @@ -200,7 +200,7 @@ Rectangle{ height: 23 width: parent.width - 5 color: root.theme.colorScheme.middleground - Workspace.Label{ + Input.Label{ id: fileLabel anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left @@ -285,7 +285,7 @@ Rectangle{ color: root.connectionRunnableColor anchors.verticalCenter: parent.verticalCenter - Workspace.Label{ + Input.Label{ id: label anchors.left: parent.left anchors.leftMargin: 15 @@ -353,7 +353,7 @@ Rectangle{ } } - Workspace.Label{ + Input.Label{ id: pathText anchors.left: pathIconLoader.right anchors.leftMargin: pathIconLoader.visible ? 8 : 0 diff --git a/plugins/editor/qml/PaletteListView.qml b/plugins/editor/qml/PaletteListView.qml index 3dcfcaaa..8f29974e 100644 --- a/plugins/editor/qml/PaletteListView.qml +++ b/plugins/editor/qml/PaletteListView.qml @@ -3,9 +3,9 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.2 import base 1.0 import editor.private 1.0 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input -Workspace.SelectableListView{ +Input.SelectableListView{ id: root signal paletteSelected(int index) @@ -16,7 +16,7 @@ Workspace.SelectableListView{ width : root.width height : 25 color : ListView.isCurrentItem ? root.style.selectionBackgroundColor : "transparent" - Workspace.Label{ + Input.Label{ id: label anchors.left: parent.left anchors.leftMargin: 10 diff --git a/plugins/editor/qml/WorkspaceTheme.qml b/plugins/editor/qml/WorkspaceTheme.qml index 004d0d5b..2b56264f 100644 --- a/plugins/editor/qml/WorkspaceTheme.qml +++ b/plugins/editor/qml/WorkspaceTheme.qml @@ -75,7 +75,7 @@ Theme{ borderWidth: 1 radius: 2 - textStyle: TextStyle{ + textStyle: Input.TextStyle{ color: colorScheme.foregroundFaded font : Qt.font({ family: 'Open Sans, sans-serif', @@ -84,7 +84,7 @@ Theme{ pixelSize: 11 }) } - highlightTextStyle: TextStyle{ + highlightTextStyle: Input.TextStyle{ color: Qt.lighter(colorScheme.foregroundFaded) font : Qt.font({ family: 'Open Sans, sans-serif', @@ -138,7 +138,7 @@ Theme{ // Labels - property QtObject monoTextStyle : TextStyle{ + property QtObject monoTextStyle : Input.TextStyle{ color: colorScheme.foreground font : Qt.font({ family: 'Source Code Pro, Ubuntu Mono, Courier New, Courier', @@ -148,7 +148,7 @@ Theme{ }) } - property QtObject smallLabelStyle: TextStyle{ + property QtObject smallLabelStyle: Input.TextStyle{ color: colorScheme.foregroundFaded font : Qt.font({ family: 'Open Sans, sans-serif', @@ -160,10 +160,10 @@ Theme{ // Forms - property QtObject inputLabelStyle: LabelOnRectangleStyle{ + property QtObject inputLabelStyle: Input.LabelOnRectangleStyle{ background: colorScheme.middleground radius: 3 - textStyle: TextStyle{ + textStyle: Input.TextStyle{ color: colorScheme.foregroundFaded font : Qt.font({ family: 'Open Sans, sans-serif', @@ -174,8 +174,8 @@ Theme{ } } - property QtObject inputStyle: InputBoxStyle{ - textStyle: TextStyle{ + property QtObject inputStyle: Input.InputBoxStyle{ + textStyle: Input.TextStyle{ color: colorScheme.foreground font : Qt.font({ family: 'Open Sans, sans-serif', @@ -185,7 +185,7 @@ Theme{ }) } radius: 2 - hintTextStyle: TextStyle{ + hintTextStyle: Input.TextStyle{ color: colorScheme.foreground font : Qt.font({ family: 'Open Sans, sans-serif', @@ -201,8 +201,8 @@ Theme{ } - property QtObject monoInputStyle: InputBoxStyle{ - textStyle: TextStyle{ + property QtObject monoInputStyle: Input.InputBoxStyle{ + textStyle: Input.TextStyle{ color: colorScheme.foreground font : Qt.font({ family: 'Source Code Pro, Ubuntu Mono, Courier New, Courier', @@ -212,7 +212,7 @@ Theme{ }) } radius: 3 - hintTextStyle: TextStyle{ + hintTextStyle: Input.TextStyle{ color: 'white' font : Qt.font({ family: 'Source Code Pro, Ubuntu Mono, Courier New, Courier', @@ -228,8 +228,8 @@ Theme{ } - property QtObject formButtonStyle : TextButtonStyle{ - textStyle: TextStyle{ + property QtObject formButtonStyle : Input.TextButtonStyle{ + textStyle: Input.TextStyle{ color: colorScheme.foreground font : Qt.font({ family: 'Open Sans, sans-serif', @@ -238,7 +238,7 @@ Theme{ pixelSize: 11 }) } - hoverTextStyle: TextStyle{ + hoverTextStyle: Input.TextStyle{ color: colorScheme.foreground font : Qt.font({ family: 'Open Sans, sans-serif', @@ -256,7 +256,7 @@ Theme{ } - property QtObject iconButtonStyle : RectangleButtonStyle{ + property QtObject iconButtonStyle : Input.RectangleButtonStyle{ backgroundColor: 'transparent' backgroundHoverColor: 'transparent' borderColor: 'transparent' @@ -265,7 +265,7 @@ Theme{ radius: 3 } - property QtObject minimalIconButtonStyle : RectangleButtonStyle{ + property QtObject minimalIconButtonStyle : Input.RectangleButtonStyle{ backgroundColor: 'transparent' backgroundHoverColor: 'transparent' borderColor: 'transparent' @@ -331,7 +331,7 @@ Theme{ property QtObject buttons: QtObject{ - property Component apply: RectangleButton{ + property Component apply: Input.RectangleButton{ width: parent ? parent.width : 20 height: parent ? parent.height: 20 @@ -345,7 +345,7 @@ Theme{ } onClicked: parent.clicked() } - property Component cancel: RectangleButton{ + property Component cancel: Input.RectangleButton{ width: parent ? parent.width : 20 height: parent ? parent.height: 20 @@ -359,7 +359,7 @@ Theme{ } onClicked: parent.clicked() } - property Component add: RectangleButton{ + property Component add: Input.RectangleButton{ width: parent ? parent.width : 20 height: parent ? parent.height: 20 @@ -374,7 +374,7 @@ Theme{ onClicked: parent.clicked() } - property Component save: RectangleButton{ + property Component save: Input.RectangleButton{ width: parent ? parent.width : 20 height: parent ? parent.height: 20 @@ -387,7 +387,7 @@ Theme{ onClicked: parent.clicked() } - property Component connect: RectangleButton{ + property Component connect: Input.RectangleButton{ width: parent ? parent.width : 20 height: parent ? parent.height: 20 @@ -400,7 +400,7 @@ Theme{ onClicked: parent.clicked() } - property Component penSize: RectangleButton{ + property Component penSize: Input.RectangleButton{ width: parent ? parent.width : 20 height: parent ? parent.height: 20 @@ -413,7 +413,7 @@ Theme{ onClicked: parent.clicked() } - property Component editorCode: RectangleButton{ + property Component editorCode: Input.RectangleButton{ width: parent ? parent.width : 20 height: parent ? parent.height: 20 @@ -428,7 +428,7 @@ Theme{ onClicked: parent.clicked() } - property Component editorShape: RectangleButton{ + property Component editorShape: Input.RectangleButton{ width: parent ? parent.width : 20 height: parent ? parent.height: 20 @@ -445,7 +445,7 @@ Theme{ // Tooltip property QtObject tooltip: QtObject{ - property QtObject labelStyle: TextStyle{ + property QtObject labelStyle: Input.TextStyle{ color: colorScheme.foreground font : Qt.font({ family: 'Open Sans, sans-serif', @@ -463,8 +463,8 @@ Theme{ // Lists - property QtObject selectableListView: SelectableListViewStyle{ - labelStyle: TextStyle{ + property QtObject selectableListView: Input.SelectableListViewStyle{ + labelStyle: Input.TextStyle{ color: colorScheme.foreground font : Qt.font({ family: 'Open Sans, sans-serif', @@ -507,13 +507,13 @@ Theme{ property color titleBackground: root.colorScheme.middlegroundOverlayDominant property double titleRadius: 3 - property QtObject titleTextStyle : TextStyle{} + property QtObject titleTextStyle : Input.TextStyle{} } property QtObject propertyDelegateStyle : QtObject{ property color background: root.colorScheme.middlegroundOverlay property double radius: 5 - property QtObject textStyle: TextStyle{} + property QtObject textStyle: Input.TextStyle{} } } @@ -528,7 +528,7 @@ Theme{ inputStyle: root.inputStyle - timeLabelStyle: TextStyle{ + timeLabelStyle: Input.TextStyle{ color: root.colorScheme.foregroundFaded font.family: "Source Code Pro, Ubuntu Mono" font.pixelSize: 14 diff --git a/plugins/editqml/qml/AddQmlBox.qml b/plugins/editqml/qml/AddQmlBox.qml index d5785eef..0144ba90 100644 --- a/plugins/editqml/qml/AddQmlBox.qml +++ b/plugins/editqml/qml/AddQmlBox.qml @@ -20,7 +20,7 @@ import QtQuick.Controls.Styles 1.2 import base 1.0 import live 1.0 import editor.private 1.0 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input Rectangle{ id: root @@ -103,7 +103,7 @@ Rectangle{ height: title.height + buttonsContainer.height anchors.top: parent.top - Workspace.Label{ + Input.Label{ id: title anchors.top: parent.top anchors.topMargin: 5 @@ -134,7 +134,7 @@ Rectangle{ height: 30 spacing: 2 - Workspace.TextButton{ + Input.TextButton{ visible: mode !== AddQmlBox.DisplayMode.ObjectsOnly text: 'All' height: 22 @@ -148,7 +148,7 @@ Rectangle{ } } - Workspace.TextButton{ + Input.TextButton{ visible: mode !== AddQmlBox.DisplayMode.ObjectsOnly text: 'Property' height: 22 @@ -162,7 +162,7 @@ Rectangle{ } } - Workspace.TextButton{ + Input.TextButton{ text: 'Object' height: 22 width: 70 @@ -178,7 +178,7 @@ Rectangle{ } } - Workspace.TextButton{ + Input.TextButton{ visible: mode !== AddQmlBox.DisplayMode.ObjectsOnly text: 'Event' height: 22 @@ -193,7 +193,7 @@ Rectangle{ } } - Workspace.TextButton{ + Input.TextButton{ visible: mode & AddQmlBox.DisplayMode.WithFunctions text: 'Function' height: 22 @@ -263,7 +263,7 @@ Rectangle{ anchors.rightMargin: 0 color: "transparent" - Workspace.InputBox { + Input.InputBox { id : idInput @@ -347,7 +347,7 @@ Rectangle{ color: "transparent" height: 28 - Workspace.InputBox { + Input.InputBox { id : searchInput anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left @@ -439,7 +439,7 @@ Rectangle{ anchors.rightMargin: 1 anchors.bottomMargin: 1 - Workspace.SelectableListView { + Input.SelectableListView { id: categoryList anchors.top : parent.top anchors.left: parent.left @@ -471,7 +471,7 @@ Rectangle{ height : 25 color : ListView.isCurrentItem ? root.theme.selectableListView.selectionBackgroundColor : "transparent" - Workspace.Label{ + Input.Label{ id: label anchors.left: parent.left anchors.leftMargin: 10 @@ -523,7 +523,7 @@ Rectangle{ } } - Workspace.SelectableListView { + Input.SelectableListView { id: listView anchors.top : parent.top anchors.right: parent.right diff --git a/plugins/editqml/qml/PaletteStyle.qml b/plugins/editqml/qml/PaletteStyle.qml index d3a2d335..b6826f2f 100644 --- a/plugins/editqml/qml/PaletteStyle.qml +++ b/plugins/editqml/qml/PaletteStyle.qml @@ -1,6 +1,7 @@ import QtQuick 2.3 import QtQuick.Controls.Styles 1.2 import workspace 1.0 +import visual.input 1.0 as Input QtObject{ @@ -13,13 +14,13 @@ QtObject{ property color scrollbarColor: "#555" property QtObject colorScheme: QtObject{} - property QtObject labelStyle : LabelOnRectangleStyle{} - property QtObject inputStyle : InputBoxStyle{} - property QtObject monoInputStyle : InputBoxStyle{ - textStyle: TextStyle{ font.family : 'Source Code Pro, Ubuntu Mono, Courier New, Courier' } - hintTextStyle: TextStyle{ font.family : 'Source Code Pro, Ubuntu Mono, Courier New, Courier'} + property QtObject labelStyle : Input.LabelOnRectangleStyle{} + property QtObject inputStyle : Input.InputBoxStyle{} + property QtObject monoInputStyle : Input.InputBoxStyle{ + textStyle: Input.TextStyle{ font.family : 'Source Code Pro, Ubuntu Mono, Courier New, Courier' } + hintTextStyle: Input.TextStyle{ font.family : 'Source Code Pro, Ubuntu Mono, Courier New, Courier'} } - property QtObject buttonStyle : TextButtonStyle{} + property QtObject buttonStyle : Input.TextButtonStyle{} property QtObject propertyLabelStyle : QtObject{ property color background: '#555' @@ -29,7 +30,7 @@ QtObject{ property QtObject buttons : QtObject{} property QtObject nodeEditor: QtObject{} - property QtObject selectableListView: SelectableListViewStyle{} + property QtObject selectableListView: Input.SelectableListViewStyle{} property QtObject timelineStyle: QtObject{} } diff --git a/plugins/fs/fsqml/qml/SelectableFolderView.qml b/plugins/fs/fsqml/qml/SelectableFolderView.qml index 5aa88f69..faf518ed 100644 --- a/plugins/fs/fsqml/qml/SelectableFolderView.qml +++ b/plugins/fs/fsqml/qml/SelectableFolderView.qml @@ -3,11 +3,11 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.2 import base 1.0 import editor.private 1.0 -import workspace 1.0 as Workspace import workspace.icons 1.0 as Icons import fs 1.0 as Fs +import visual.input 1.0 as Input -Workspace.SelectableListView{ +Input.SelectableListView{ id: root property var selectedIndexes : [] @@ -53,7 +53,7 @@ Workspace.SelectableListView{ return 'transparent' } - Workspace.Label{ + Input.Label{ id: label anchors.left: parent.left anchors.leftMargin: 25 diff --git a/plugins/lcvcore/palettes/ImagePalette.qml b/plugins/lcvcore/palettes/ImagePalette.qml index e1b23e19..3ecb31e5 100644 --- a/plugins/lcvcore/palettes/ImagePalette.qml +++ b/plugins/lcvcore/palettes/ImagePalette.qml @@ -22,7 +22,7 @@ import editor 1.0 import fs 1.0 as Fs import lcvcore 1.0 as Cv import lcvimgproc 1.0 as Img -import workspace 1.0 as Workspace +import visual.input 1.0 as Input CodePalette{ id: palette @@ -58,7 +58,7 @@ CodePalette{ height: 30 color: palette.style.toolbarColor - Workspace.Button{ + Input.Button{ anchors.left: parent.left anchors.leftMargin: 30 anchors.verticalCenter: parent.verticalCenter @@ -79,7 +79,7 @@ CodePalette{ width: zoomInfo.width anchors.left: parent.left anchors.leftMargin: 70 - Workspace.Label{ + Input.Label{ id: zoomInfo anchors.verticalCenter: parent.verticalCenter text: Math.floor(imageView.scale * 100) + '%' @@ -91,7 +91,7 @@ CodePalette{ width: imageInfo.width anchors.right: parent.right anchors.rightMargin: 10 - Workspace.Label{ + Input.Label{ id: imageInfo anchors.verticalCenter: parent.verticalCenter text: { diff --git a/plugins/lcvcore/palettes/ImageSegmentFactoryPalette.qml b/plugins/lcvcore/palettes/ImageSegmentFactoryPalette.qml index 2ae3c1d9..57a6f967 100644 --- a/plugins/lcvcore/palettes/ImageSegmentFactoryPalette.qml +++ b/plugins/lcvcore/palettes/ImageSegmentFactoryPalette.qml @@ -20,7 +20,7 @@ import QtQuick.Controls.Styles 1.4 import editor 1.0 import live 1.0 import base 1.0 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input CodePalette{ id: palette @@ -36,7 +36,7 @@ CodePalette{ property var current : null - Workspace.TextButton{ + Input.TextButton{ anchors.horizontalCenter: parent.horizontalCenter anchors.left: parent.left anchors.leftMargin: 10 diff --git a/plugins/lcvcore/palettes/PerspectiveOnBackgroundPalette.qml b/plugins/lcvcore/palettes/PerspectiveOnBackgroundPalette.qml index f4aedcc6..20fdf5a5 100644 --- a/plugins/lcvcore/palettes/PerspectiveOnBackgroundPalette.qml +++ b/plugins/lcvcore/palettes/PerspectiveOnBackgroundPalette.qml @@ -8,6 +8,7 @@ import lcvimgproc 1.0 as Img import workspace 1.0 as Workspace import workspace.icons 1.0 as Icons import fs 1.0 as Fs +import visual.input 1.0 as Input CodePalette{ id: palette @@ -116,7 +117,7 @@ CodePalette{ border.color: palette.style.toolbarBorder border.width: 1 - Workspace.Button{ + Input.Button{ anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter width: 25 @@ -145,7 +146,7 @@ CodePalette{ width: zoomInfo.width anchors.right: dimensionsPanel.left anchors.rightMargin: 20 - Workspace.Label{ + Input.Label{ id: zoomInfo textStyle: palette.style.labelStyle.textStyle anchors.verticalCenter: parent.verticalCenter @@ -160,7 +161,7 @@ CodePalette{ width: imageInfo.width anchors.right: parent.right anchors.rightMargin: 10 - Workspace.Label{ + Input.Label{ id: imageInfo textStyle: palette.style.labelStyle.textStyle anchors.verticalCenter: parent.verticalCenter diff --git a/plugins/lcvcore/palettes/VideoSurfacePalette.qml b/plugins/lcvcore/palettes/VideoSurfacePalette.qml index f26c1673..3b53983f 100644 --- a/plugins/lcvcore/palettes/VideoSurfacePalette.qml +++ b/plugins/lcvcore/palettes/VideoSurfacePalette.qml @@ -22,7 +22,7 @@ import editor 1.0 import fs 1.0 as Fs import lcvcore 1.0 as Cv import lcvimgproc 1.0 as Img -import workspace 1.0 as Workspace +import visual.input 1.0 as Input CodePalette{ id: palette @@ -68,7 +68,7 @@ CodePalette{ height: 30 color: palette.style.toolbarColor - Workspace.Button{ + Input.Button{ anchors.left: parent.left anchors.leftMargin: 30 anchors.verticalCenter: parent.verticalCenter @@ -89,7 +89,7 @@ CodePalette{ width: zoomInfo.width anchors.left: parent.left anchors.leftMargin: 70 - Workspace.Label{ + Input.Label{ id: zoomInfo anchors.verticalCenter: parent.verticalCenter text: Math.floor(imageView.scale * 100) + '%' @@ -101,7 +101,7 @@ CodePalette{ width: imageInfo.width anchors.right: parent.right anchors.rightMargin: 10 - Workspace.Label{ + Input.Label{ id: imageInfo anchors.verticalCenter: parent.verticalCenter text: { diff --git a/plugins/lcvcore/qml/BrushTool.qml b/plugins/lcvcore/qml/BrushTool.qml index ea846d5f..9b861d7c 100644 --- a/plugins/lcvcore/qml/BrushTool.qml +++ b/plugins/lcvcore/qml/BrushTool.qml @@ -4,15 +4,16 @@ import QtQuick.Controls.Styles 1.2 import workspace 1.0 as Workspace import workspace.icons 1.0 import lcvimgproc 1.0 as Img +import visual.input 1.0 as Input Workspace.Tool{ id: root toolLabel: 'Brush' - property QtObject labelInfoStyle: Workspace.TextStyle{} - property QtObject labelBoxStyle: Workspace.LabelOnRectangleStyle{} - property QtObject formButtonStyle: Workspace.RectangleButtonStyle{} + property QtObject labelInfoStyle: Input.TextStyle{} + property QtObject labelBoxStyle: Input.LabelOnRectangleStyle{} + property QtObject formButtonStyle: Input.RectangleButtonStyle{} property Component sizeButton : null property real brushSize: 1 @@ -20,7 +21,7 @@ Workspace.Tool{ infoBarContent: Item{ anchors.fill: parent - Workspace.Label{ + Input.Label{ id: selectionInfo anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left @@ -29,13 +30,13 @@ Workspace.Tool{ text: 'Brush' } - Workspace.Button{ + Input.Button{ anchors.left: selectionInfo.right anchors.leftMargin: 15 anchors.verticalCenter: parent.verticalCenter width: 15 height: 15 - content: Workspace.RectangleButton{ + content: Input.RectangleButton{ width: parent ? parent.width : 20 height: parent ? parent.height: 20 @@ -88,7 +89,7 @@ Workspace.Tool{ } } - Workspace.LabelOnRectangle{ + Input.LabelOnRectangle{ id: valueLabel anchors.left: parent.left anchors.leftMargin: 2 diff --git a/plugins/lcvcore/qml/CropTool.qml b/plugins/lcvcore/qml/CropTool.qml index ca82e249..34cd562b 100644 --- a/plugins/lcvcore/qml/CropTool.qml +++ b/plugins/lcvcore/qml/CropTool.qml @@ -1,13 +1,13 @@ import QtQuick 2.3 import workspace 1.0 - +import visual.input 1.0 as Input Tool{ id: root toolLabel: 'Crop' - property QtObject labelInfoStyle: TextStyle{} + property QtObject labelInfoStyle: Input.TextStyle{} property Component applyButton : null property Component cancelButton : null @@ -22,7 +22,7 @@ Tool{ infoBarContent: Item{ anchors.fill: parent - Label{ + Input.Label{ id: selectionInfo anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left @@ -38,7 +38,7 @@ Tool{ } } - Button{ + Input.Button{ anchors.left: parent.left anchors.leftMargin: 140 width: 25 @@ -46,7 +46,7 @@ Tool{ content: root.applyButton onClicked: root.apply(root.selectedX, root.selectedY, root.selectedWidth, root.selectedHeight) } - Button{ + Input.Button{ anchors.left: parent.left anchors.leftMargin: 168 width: 25 @@ -100,7 +100,7 @@ Tool{ } - RectangleSelection{ + Input.RectangleSelection{ id: rectangleSelection onRegionModified: { diff --git a/plugins/lcvcore/qml/GradientTool.qml b/plugins/lcvcore/qml/GradientTool.qml index bddb71cf..93a39a63 100644 --- a/plugins/lcvcore/qml/GradientTool.qml +++ b/plugins/lcvcore/qml/GradientTool.qml @@ -2,13 +2,14 @@ import QtQuick 2.3 import workspace 1.0 import lcvcore 1.0 as Cv import lcvimgproc 1.0 as Img +import visual.input 1.0 as Input Tool{ id: root toolLabel: 'Brush' - property QtObject labelInfoStyle: TextStyle{} + property QtObject labelInfoStyle: Input.TextStyle{} property Component sizeButton : null property real brushSize: 1 @@ -16,7 +17,7 @@ Tool{ infoBarContent: Item{ anchors.fill: parent - Label{ + Input.Label{ id: selectionInfo anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left diff --git a/plugins/lcvcore/qml/ImageDrawView.qml b/plugins/lcvcore/qml/ImageDrawView.qml index 13442713..65fc0a2b 100644 --- a/plugins/lcvcore/qml/ImageDrawView.qml +++ b/plugins/lcvcore/qml/ImageDrawView.qml @@ -37,16 +37,16 @@ Item{ property real boxRadius: 3 property color toolHighlightColor: "#444" property QtObject labelStyle: colorPicker.style.labelStyle - property QtObject labelBoxStyle: Workspace.LabelOnRectangleStyle{} - property QtObject formButtonStyle: Workspace.RectangleButtonStyle{} + property QtObject labelBoxStyle: Input.LabelOnRectangleStyle{} + property QtObject formButtonStyle: Input.RectangleButtonStyle{} - property Component saveButton: Workspace.TextButton{ + property Component saveButton: Input.TextButton{ width: 50 height: 25 text: 'Save' onClicked: parent.clicked() } - property Component brushSizeButton: Workspace.TextButton{ + property Component brushSizeButton: Input.TextButton{ width: 30 height: 25 text: 'B' @@ -317,7 +317,7 @@ Item{ visible: root.image ? true : false color: root.style.toolbarColor - Workspace.Button{ + Input.Button{ anchors.left: parent.left anchors.leftMargin: 5 anchors.verticalCenter: parent.verticalCenter @@ -338,7 +338,7 @@ Item{ width: zoomInfo.width anchors.left: parent.left anchors.leftMargin: 35 - Workspace.Label{ + Input.Label{ id: zoomInfo anchors.verticalCenter: parent.verticalCenter textStyle: root.style.labelStyle.textStyle @@ -361,7 +361,7 @@ Item{ width: imageInfo.width anchors.right: parent.right anchors.rightMargin: 10 - Workspace.Label{ + Input.Label{ id: imageInfo anchors.verticalCenter: parent.verticalCenter textStyle: root.style.labelStyle.textStyle diff --git a/plugins/lcvcore/qml/ImageSegmentCreator.qml b/plugins/lcvcore/qml/ImageSegmentCreator.qml index 55c9a35b..bc3a791e 100644 --- a/plugins/lcvcore/qml/ImageSegmentCreator.qml +++ b/plugins/lcvcore/qml/ImageSegmentCreator.qml @@ -2,7 +2,7 @@ import QtQuick 2.0 import timeline 1.0 import lcvcore 1.0 import live 1.0 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input Rectangle{ width: 300 @@ -33,7 +33,7 @@ Rectangle{ color: "#afafaf" } - Workspace.PathInputBox{ + Input.PathInputBox{ anchors.left: parent.left anchors.leftMargin: 20 anchors.top: parent.top @@ -47,14 +47,14 @@ Rectangle{ } } - Workspace.TextButton{ + Input.TextButton{ anchors.right: parent.right anchors.rightMargin: 10 radius: 5 width: 30 height: 30 text: 'X' - style: Workspace.TextButtonStyle{ + style: Input.TextButtonStyle{ backgroundColor: '#3f444d' backgroundHoverColor: Qt.lighter('#3f444d', 1.2) borderColor: '#575b63' diff --git a/plugins/lcvcore/qml/PerspectiveTool.qml b/plugins/lcvcore/qml/PerspectiveTool.qml index d496d2bc..81a6f2f8 100644 --- a/plugins/lcvcore/qml/PerspectiveTool.qml +++ b/plugins/lcvcore/qml/PerspectiveTool.qml @@ -1,12 +1,13 @@ import QtQuick 2.3 import workspace 1.0 +import visual.input 1.0 as Input Tool{ id: root toolLabel: 'Perspective' - property QtObject labelInfoStyle: TextStyle{} + property QtObject labelInfoStyle: Input.TextStyle{} property Component applyButton : null property Component cancelButton : null @@ -21,7 +22,7 @@ Tool{ infoBarContent: Item { anchors.fill: parent - Label { + Input.Label{ id: pointsInfo anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left @@ -43,7 +44,7 @@ Tool{ } } - Button{ + Input.Button{ id: applyBttn anchors.left: pointsInfo.right anchors.leftMargin: 5 @@ -52,7 +53,7 @@ Tool{ content: root.applyButton onClicked: root.apply(root.p1, root.p2, root.p3, root.p4) } - Button{ + Input.Button{ id: cancelBttn anchors.left: applyBttn.right anchors.leftMargin: 5 @@ -101,7 +102,7 @@ Tool{ onWheel: parent.wheel(wheel) } - ConvexQuadSelection { + Input.ConvexQuadSelection { id: cqSelection onRegionModified: { diff --git a/plugins/lcvcore/qml/ScriptVideoSegmentCreator.qml b/plugins/lcvcore/qml/ScriptVideoSegmentCreator.qml index 54452efb..1d17ca13 100644 --- a/plugins/lcvcore/qml/ScriptVideoSegmentCreator.qml +++ b/plugins/lcvcore/qml/ScriptVideoSegmentCreator.qml @@ -2,8 +2,8 @@ import QtQuick 2.0 import timeline 1.0 import lcvcore 1.0 import live 1.0 -import workspace 1.0 as Workspace import fs 1.0 as Fs +import visual.input 1.0 as Input Rectangle{ width: 300 @@ -32,7 +32,7 @@ Rectangle{ color: "#afafaf" } - Workspace.PathInputBox{ + Input.PathInputBox{ anchors.left: parent.left anchors.leftMargin: 20 anchors.top: parent.top @@ -54,14 +54,14 @@ Rectangle{ } } - Workspace.TextButton{ + Input.TextButton{ anchors.right: parent.right anchors.rightMargin: 10 radius: 5 width: 30 height: 30 text: 'X' - style: Workspace.TextButtonStyle{ + style: Input.TextButtonStyle{ backgroundColor: '#3f444d' backgroundHoverColor: Qt.lighter('#3f444d', 1.2) borderColor: '#575b63' diff --git a/plugins/lcvcore/qml/VideoCaptureSegmentCreator.qml b/plugins/lcvcore/qml/VideoCaptureSegmentCreator.qml index 7018b56d..a5a2c489 100644 --- a/plugins/lcvcore/qml/VideoCaptureSegmentCreator.qml +++ b/plugins/lcvcore/qml/VideoCaptureSegmentCreator.qml @@ -2,7 +2,7 @@ import QtQuick 2.0 import timeline 1.0 import lcvcore 1.0 import live 1.0 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input Rectangle{ width: 300 @@ -33,7 +33,7 @@ Rectangle{ color: "#afafaf" } - Workspace.PathInputBox{ + Input.PathInputBox{ anchors.left: parent.left anchors.leftMargin: 20 anchors.top: parent.top @@ -47,14 +47,14 @@ Rectangle{ } } - Workspace.TextButton{ + Input.TextButton{ anchors.right: parent.right anchors.rightMargin: 10 radius: 5 width: 30 height: 30 text: 'X' - style: Workspace.TextButtonStyle{ + style: Input.TextButtonStyle{ backgroundColor: '#3f444d' backgroundHoverColor: Qt.lighter('#3f444d', 1.2) borderColor: '#575b63' diff --git a/plugins/lcvcore/qml/VideoCaptureSegmentEditor.qml b/plugins/lcvcore/qml/VideoCaptureSegmentEditor.qml index d3d20cef..bfcbfcab 100644 --- a/plugins/lcvcore/qml/VideoCaptureSegmentEditor.qml +++ b/plugins/lcvcore/qml/VideoCaptureSegmentEditor.qml @@ -3,7 +3,7 @@ import timeline 1.0 import lcvcore 1.0 import live 1.0 import editor 1.0 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input Rectangle{ id: root @@ -31,7 +31,7 @@ Rectangle{ color: "#afafaf" } - Workspace.PathInputBox{ + Input.PathInputBox{ id: pathInputBox anchors.right: parent.right anchors.rightMargin: 60 @@ -46,7 +46,7 @@ Rectangle{ path: root.currentSegment ? root.currentSegment.filters : '' } - Workspace.Button{ + Input.Button{ anchors.top: parent.top anchors.topMargin: 4 anchors.right: parent.right @@ -61,7 +61,7 @@ Rectangle{ } - TextButton{ + Input.TextButton{ anchors.top: parent.top anchors.topMargin: 4 anchors.right: parent.right diff --git a/plugins/lcvcore/qml/VideoSurfaceCreator.qml b/plugins/lcvcore/qml/VideoSurfaceCreator.qml index 5b19609f..53ee05ba 100644 --- a/plugins/lcvcore/qml/VideoSurfaceCreator.qml +++ b/plugins/lcvcore/qml/VideoSurfaceCreator.qml @@ -2,7 +2,6 @@ import QtQuick 2.0 import timeline 1.0 import lcvcore 1.0 import live 1.0 -import workspace 1.0 as Workspace import visual.input 1.0 as Input Rectangle{ @@ -70,7 +69,7 @@ Rectangle{ } } - Workspace.InputBox{ + Input.InputBox{ id: widthInput anchors.left: parent.left anchors.leftMargin: 75 @@ -79,7 +78,7 @@ Rectangle{ width: 50 text: '800' } - Workspace.InputBox{ + Input.InputBox{ id: heightInput anchors.left: parent.left anchors.leftMargin: 75 + 60 @@ -89,7 +88,7 @@ Rectangle{ text: '600' } - Workspace.Button{ + Input.Button{ id: applyButton anchors.top: parent.top anchors.topMargin: 100 @@ -101,14 +100,14 @@ Rectangle{ onClicked: { root.surfaceCreated(root.createSurface()) } } - Workspace.TextButton{ + Input.TextButton{ anchors.right: parent.right anchors.rightMargin: 10 radius: 5 width: 30 height: 30 text: 'X' - style: Workspace.TextButtonStyle{ + style: Input.TextButtonStyle{ backgroundColor: '#3f444d' backgroundHoverColor: Qt.lighter('#3f444d', 1.2) borderColor: '#575b63' diff --git a/plugins/lcvimgproc/qml/ResizeTool.qml b/plugins/lcvimgproc/qml/ResizeTool.qml index 8e5a7163..50c9517e 100644 --- a/plugins/lcvimgproc/qml/ResizeTool.qml +++ b/plugins/lcvimgproc/qml/ResizeTool.qml @@ -1,12 +1,13 @@ import QtQuick 2.3 import workspace 1.0 +import visual.input 1.0 as Input Tool{ id: root toolLabel: 'Resize' property QtObject theme: lk.layers.workspace.themes.current - property QtObject labelInfoStyle: TextStyle{} + property QtObject labelInfoStyle: Input.TextStyle{} property Component applyButton : null property Component cancelButton : null property Component preserveAspectButton: null @@ -19,7 +20,7 @@ Tool{ infoBarContent: Item{ anchors.fill: parent - Label{ + Input.Label{ id: selectionInfo anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left @@ -28,7 +29,7 @@ Tool{ text: 'Resize' } - InputBox{ + Input.InputBox{ id: widthInput anchors.left: parent.left anchors.leftMargin: 40 @@ -79,7 +80,7 @@ Tool{ } - InputBox{ + Input.InputBox{ id: heightInput anchors.left: parent.left anchors.leftMargin: 110 @@ -105,7 +106,7 @@ Tool{ } - Button{ + Input.Button{ anchors.left: parent.left anchors.leftMargin: 170 width: 25 @@ -113,7 +114,7 @@ Tool{ content: root.applyButton onClicked: root.apply(parseInt(widthInput.text), parseInt(heightInput.text)) } - Button{ + Input.Button{ anchors.left: parent.left anchors.leftMargin: 198 width: 25 diff --git a/plugins/lcvimgproc/qml/RotateTool.qml b/plugins/lcvimgproc/qml/RotateTool.qml index 58b0b8ea..a97cd5a2 100644 --- a/plugins/lcvimgproc/qml/RotateTool.qml +++ b/plugins/lcvimgproc/qml/RotateTool.qml @@ -1,12 +1,12 @@ import QtQuick 2.3 import workspace 1.0 - +import visual.input 1.0 as Input Tool{ id: root toolLabel: 'Rotate' property QtObject theme: lk.layers.workspace.themes.current - property QtObject labelInfoStyle: TextStyle{} + property QtObject labelInfoStyle: Input.TextStyle{} property Component applyButton : null property Component cancelButton : null @@ -16,7 +16,7 @@ Tool{ infoBarContent: Item{ anchors.fill: parent - Label{ + Input.Label{ id: selectionInfo anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left @@ -25,7 +25,7 @@ Tool{ text: 'Rotate' } - InputBox{ + Input.InputBox{ id: angleInput anchors.left: parent.left anchors.leftMargin: 40 @@ -40,7 +40,7 @@ Tool{ style: theme.inputStyle } - Button{ + Input.Button{ anchors.left: parent.left anchors.leftMargin: 90 width: 25 @@ -52,7 +52,7 @@ Tool{ root.apply(value) } } - Button{ + Input.Button{ anchors.left: parent.left anchors.leftMargin: 118 width: 25 diff --git a/plugins/lcvimgproc/qml/palettes/TransformPalette.qml b/plugins/lcvimgproc/qml/palettes/TransformPalette.qml index b3f088f0..a90d7764 100644 --- a/plugins/lcvimgproc/qml/palettes/TransformPalette.qml +++ b/plugins/lcvimgproc/qml/palettes/TransformPalette.qml @@ -23,6 +23,8 @@ import lcvcore 1.0 as Cv import lcvimgproc 1.0 as Img import workspace 1.0 as Workspace import workspace.icons 1.0 as Icons +import visual.input 1.0 as Input + CodePalette{ id: palette @@ -336,7 +338,7 @@ CodePalette{ border.color: palette.style.toolbarBorder border.width: 1 - Workspace.Button{ + Input.Button{ anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter width: 25 @@ -365,7 +367,7 @@ CodePalette{ width: zoomInfo.width anchors.right: dimensionsPanel.left anchors.rightMargin: 20 - Workspace.Label{ + Input.Label{ id: zoomInfo textStyle: palette.style.labelStyle.textStyle anchors.verticalCenter: parent.verticalCenter @@ -380,7 +382,7 @@ CodePalette{ width: imageInfo.width anchors.right: parent.right anchors.rightMargin: 10 - Workspace.Label{ + Input.Label{ id: imageInfo textStyle: palette.style.labelStyle.textStyle anchors.verticalCenter: parent.verticalCenter diff --git a/plugins/lcvphoto/palettes/BrightnessAndContrastPalette.qml b/plugins/lcvphoto/palettes/BrightnessAndContrastPalette.qml index 8fad235f..b51af7d1 100644 --- a/plugins/lcvphoto/palettes/BrightnessAndContrastPalette.qml +++ b/plugins/lcvphoto/palettes/BrightnessAndContrastPalette.qml @@ -20,7 +20,7 @@ import QtQuick.Controls.Styles 1.4 import editor 1.0 import live 1.0 import lcvphoto 1.0 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input CodePalette{ id: palette @@ -77,7 +77,7 @@ CodePalette{ } } - Workspace.LabelOnRectangle{ + Input.LabelOnRectangle{ anchors.top: parent.top width: 35 height: 22 @@ -129,7 +129,7 @@ CodePalette{ } } - Workspace.LabelOnRectangle{ + Input.LabelOnRectangle{ anchors.top: parent.top anchors.topMargin: 30 width: 35 diff --git a/plugins/lcvphoto/qml/HueSaturationLightnessSliders.qml b/plugins/lcvphoto/qml/HueSaturationLightnessSliders.qml index aef2c7eb..b3a130be 100644 --- a/plugins/lcvphoto/qml/HueSaturationLightnessSliders.qml +++ b/plugins/lcvphoto/qml/HueSaturationLightnessSliders.qml @@ -3,7 +3,7 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.2 import QtQuick.Controls 2.12 as QC2 import QtGraphicalEffects 1.0 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input Rectangle{ id: root @@ -95,7 +95,7 @@ Rectangle{ } } - Workspace.LabelOnRectangle{ + Input.LabelOnRectangle{ id: hueLabelLeft width: 35 height: 22 @@ -104,7 +104,7 @@ Rectangle{ style: root.style ? root.style.labelStyle : defaultStyle } - Workspace.LabelOnRectangle{ + Input.LabelOnRectangle{ anchors.top: parent.top anchors.right: parent.right width: 35 @@ -163,14 +163,14 @@ Rectangle{ } } - Workspace.LabelOnRectangle{ + Input.LabelOnRectangle{ anchors.top: parent.top width: 35 text: saturationSlider.from style: root.style ? root.style.labelStyle : defaultStyle } - Workspace.LabelOnRectangle{ + Input.LabelOnRectangle{ anchors.top: parent.top anchors.right: parent.right width: 35 @@ -230,7 +230,7 @@ Rectangle{ } } - Workspace.LabelOnRectangle{ + Input.LabelOnRectangle{ anchors.top: parent.top text: valueSlider.from width: 35 @@ -238,7 +238,7 @@ Rectangle{ style: root.style ? root.style.labelStyle : defaultStyle } - Workspace.LabelOnRectangle{ + Input.LabelOnRectangle{ anchors.top: parent.top anchors.right: parent.right text: valueSlider.to diff --git a/plugins/lcvphoto/qml/LevelsSliders.qml b/plugins/lcvphoto/qml/LevelsSliders.qml index cef14bb9..0d33610a 100644 --- a/plugins/lcvphoto/qml/LevelsSliders.qml +++ b/plugins/lcvphoto/qml/LevelsSliders.qml @@ -1,8 +1,8 @@ import QtQuick 2.5 import live 1.0 -import workspace 1.0 as Workspace import lcvcore 1.0 as Cv import lcvphoto 1.0 as Photo +import visual.input 1.0 as Input Rectangle{ id: root @@ -11,7 +11,7 @@ Rectangle{ color: 'transparent' property QtObject style: QtObject{ - property QtObject textStyle: Workspace.TextStyle{} + property QtObject textStyle: Input.TextStyle{} } property alias input: colorHistogram.input @@ -313,7 +313,7 @@ Rectangle{ } } - Workspace.Label{ + Input.Label{ anchors.bottom: parent.bottom anchors.bottomMargin: 5 anchors.left: parent.left @@ -321,7 +321,7 @@ Rectangle{ textStyle: root.style.textStyle } - Workspace.Label{ + Input.Label{ anchors.bottom: parent.bottom anchors.bottomMargin: 5 anchors.horizontalCenter: parent.horizontalCenter @@ -329,7 +329,7 @@ Rectangle{ textStyle: root.style.textStyle } - Workspace.Label{ + Input.Label{ anchors.bottom: parent.bottom anchors.bottomMargin: 5 anchors.right: parent.right diff --git a/plugins/timeline/palettes/TimelinePalette.qml b/plugins/timeline/palettes/TimelinePalette.qml index aaed2ae7..4b43b7de 100644 --- a/plugins/timeline/palettes/TimelinePalette.qml +++ b/plugins/timeline/palettes/TimelinePalette.qml @@ -5,7 +5,6 @@ import editor 1.0 import live 1.0 import lcvcore 1.0 import timeline 1.0 -import workspace 1.0 as Workspace import fs 1.0 as Fs import visual.input 1.0 as Input @@ -84,7 +83,7 @@ CodePalette{ } } - Workspace.TextButton{ + Input.TextButton{ text: "Ready" style: theme.formButtonStyle anchors.top: parent.top diff --git a/plugins/timeline/qml/KeyframeEditor.qml b/plugins/timeline/qml/KeyframeEditor.qml index dd7a4786..3ea625bc 100644 --- a/plugins/timeline/qml/KeyframeEditor.qml +++ b/plugins/timeline/qml/KeyframeEditor.qml @@ -4,6 +4,7 @@ import lcvcore 1.0 import live 1.0 import editor 1.0 import workspace 1.0 as Workspace +import visual.input 1.0 as Input Rectangle{ id: root @@ -31,7 +32,7 @@ Rectangle{ color: "#afafaf" } - Workspace.InputBox{ + Input.InputBox{ id: inputBox anchors.right: parent.right anchors.rightMargin: 60 @@ -42,7 +43,7 @@ Rectangle{ text: currentSegment ? currentSegment.value : 0 } - Workspace.Button{ + Input.Button{ anchors.top: parent.top anchors.topMargin: 4 anchors.right: parent.right diff --git a/plugins/timeline/qml/TimelineStyle.qml b/plugins/timeline/qml/TimelineStyle.qml index 91df4662..21055c51 100644 --- a/plugins/timeline/qml/TimelineStyle.qml +++ b/plugins/timeline/qml/TimelineStyle.qml @@ -1,7 +1,7 @@ import QtQuick 2.0 import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.1 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input QtObject{ id: root @@ -23,8 +23,8 @@ QtObject{ property color markerLabelColor: "#999" property QtObject inputStyle: QtObject{ - property QtObject textStyle: Workspace.TextStyle{} - property QtObject hintTextStyle: Workspace.TextStyle{} + property QtObject textStyle: Input.TextStyle{} + property QtObject hintTextStyle: Input.TextStyle{} property color backgroundColor: '#070b0f' property color borderColor: '#323232' property double borderThickness: 1 @@ -32,7 +32,7 @@ QtObject{ property double radius: 3 } - property QtObject timeLabelStyle: Workspace.TextStyle{} + property QtObject timeLabelStyle: Input.TextStyle{} property Component scrollStyle: ScrollViewStyle { transientScrollBars: false diff --git a/plugins/timeline/qml/TimelineView.qml b/plugins/timeline/qml/TimelineView.qml index f1a3cdc2..029c7e93 100644 --- a/plugins/timeline/qml/TimelineView.qml +++ b/plugins/timeline/qml/TimelineView.qml @@ -4,8 +4,8 @@ import QtQuick.Layouts 1.1 import QtQuick.Controls.Styles 1.2 import timeline 1.0 import fs 1.0 as Fs -import workspace 1.0 as Workspace import workspace.icons 1.0 as Icons +import visual.input 1.0 as Input Rectangle{ id: root @@ -259,7 +259,7 @@ Rectangle{ } } - Workspace.PlayPause{ + Input.PlayPause{ width: 15 height: 15 anchors.verticalCenter: parent.verticalCenter @@ -276,7 +276,7 @@ Rectangle{ } } - Workspace.Label{ + Input.Label{ anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.leftMargin: 80 diff --git a/plugins/timeline/qml/TrackTitle.qml b/plugins/timeline/qml/TrackTitle.qml index 8048b404..6277b5a2 100644 --- a/plugins/timeline/qml/TrackTitle.qml +++ b/plugins/timeline/qml/TrackTitle.qml @@ -1,8 +1,8 @@ import QtQuick 2.3 import QtQuick.Controls 1.3 import timeline 1.0 -import workspace 1.0 as Workspace import workspace.icons 1.0 as Icons +import visual.input 1.0 as Input Item{ id: root @@ -56,7 +56,7 @@ Item{ } } - Workspace.EditableLabel{ + Input.EditableLabel{ id: editableLabel anchors.left: parent.left anchors.leftMargin: 20 diff --git a/plugins/workspace/qml/Button.qml b/plugins/visual/visualqml/input/qml/Button.qml similarity index 100% rename from plugins/workspace/qml/Button.qml rename to plugins/visual/visualqml/input/qml/Button.qml diff --git a/plugins/workspace/qml/ColorPicker.qml b/plugins/visual/visualqml/input/qml/ColorHSVPicker.qml similarity index 97% rename from plugins/workspace/qml/ColorPicker.qml rename to plugins/visual/visualqml/input/qml/ColorHSVPicker.qml index 8eeb19b7..5407b060 100644 --- a/plugins/workspace/qml/ColorPicker.qml +++ b/plugins/visual/visualqml/input/qml/ColorHSVPicker.qml @@ -21,7 +21,7 @@ import QtGraphicalEffects 1.0 import live 1.0 import editor 1.0 import workspace 1.0 as Workspace - +import visual.input 1.0 as Input Item{ id: root @@ -85,7 +85,7 @@ Item{ anchors.left: parent.left anchors.leftMargin: colorDisplay.width + 2 - Workspace.InputBox{ + Input.InputBox{ id: input height: 25 anchors.top: parent.top @@ -215,7 +215,7 @@ Item{ } } - Workspace.LabelOnRectangle{ + Input.LabelOnRectangle{ id: hueLabelLeft width: 35 height: 22 @@ -224,7 +224,7 @@ Item{ style: root.style.labelStyle } - Workspace.LabelOnRectangle{ + Input.LabelOnRectangle{ anchors.top: parent.top anchors.right: parent.right width: 35 @@ -288,7 +288,7 @@ Item{ } } - Workspace.LabelOnRectangle{ + Input.LabelOnRectangle{ anchors.top: parent.top width: 35 height: 22 @@ -296,7 +296,7 @@ Item{ style: root.style.labelStyle } - Workspace.LabelOnRectangle{ + Input.LabelOnRectangle{ anchors.top: parent.top anchors.right: parent.right width: 35 @@ -361,7 +361,7 @@ Item{ } } - Workspace.LabelOnRectangle{ + Input.LabelOnRectangle{ anchors.top: parent.top text: valueSlider.minimumValue width: 35 @@ -370,7 +370,7 @@ Item{ style: root.style.labelStyle } - Workspace.LabelOnRectangle{ + Input.LabelOnRectangle{ anchors.top: parent.top anchors.right: parent.right text: valueSlider.maximumValue diff --git a/plugins/workspace/qml/ConvexQuadSelection.qml b/plugins/visual/visualqml/input/qml/ConvexQuadSelection.qml similarity index 100% rename from plugins/workspace/qml/ConvexQuadSelection.qml rename to plugins/visual/visualqml/input/qml/ConvexQuadSelection.qml diff --git a/plugins/visual/visualqml/input/qml/DropDownStyle.qml b/plugins/visual/visualqml/input/qml/DropDownStyle.qml index 728dd87e..63a55785 100644 --- a/plugins/visual/visualqml/input/qml/DropDownStyle.qml +++ b/plugins/visual/visualqml/input/qml/DropDownStyle.qml @@ -1,4 +1,5 @@ import QtQuick 2.11 +import visual.input 1.0 as Input QtObject{ property color backgroundColor: "#1b242c" @@ -7,6 +8,6 @@ QtObject{ property double borderSize: 1 property double radius: 3 - property QtObject textStyle: TextStyle{} + property QtObject textStyle: Input.TextStyle{} } diff --git a/plugins/workspace/qml/EditableLabel.qml b/plugins/visual/visualqml/input/qml/EditableLabel.qml similarity index 95% rename from plugins/workspace/qml/EditableLabel.qml rename to plugins/visual/visualqml/input/qml/EditableLabel.qml index 7718f4ba..36c239e7 100644 --- a/plugins/workspace/qml/EditableLabel.qml +++ b/plugins/visual/visualqml/input/qml/EditableLabel.qml @@ -1,6 +1,7 @@ import QtQuick 2.3 import live 1.0 import workspace 1.0 as Workspace +import visual.input 1.0 as Input Item{ id: root @@ -9,18 +10,18 @@ Item{ property QtObject defaultStyle: inputBox.defaultStyle property QtObject style: defaultStyle - + property alias font: inputBox.font property string text: 'label' property real margins: 6 property color textColor: 'white' property alias boxBackgroundColor: inputBox.color - + property bool isEditing : false signal rightClicked(var mouse) - - Workspace.Label{ + + Input.Label{ id: labelText anchors.fill: parent anchors.margins: parent.margins @@ -28,8 +29,8 @@ Item{ text: parent.text textStyle: root.style.textStyle } - - Workspace.InputBox{ + + Input.InputBox{ id: inputBox text: parent.text visible: parent.isEditing @@ -48,7 +49,7 @@ Item{ } } } - + MouseArea{ anchors.fill: parent visible: !parent.isEditing diff --git a/plugins/workspace/qml/LabelOnRectangle.qml b/plugins/visual/visualqml/input/qml/LabelOnRectangle.qml similarity index 78% rename from plugins/workspace/qml/LabelOnRectangle.qml rename to plugins/visual/visualqml/input/qml/LabelOnRectangle.qml index 800d63dd..d687fc00 100644 --- a/plugins/workspace/qml/LabelOnRectangle.qml +++ b/plugins/visual/visualqml/input/qml/LabelOnRectangle.qml @@ -1,5 +1,6 @@ import QtQuick 2.3 import workspace 1.0 as Workspace +import visual.input 1.0 as Input Rectangle{ id: root @@ -10,13 +11,13 @@ Rectangle{ property alias label: label - property QtObject defaultStyle: LabelOnRectangleStyle{} + property QtObject defaultStyle: Input.LabelOnRectangleStyle{} property QtObject style: defaultStyle property int margins: 0 property string text: 'Label' - Workspace.Label{ + Input.Label{ id: label anchors.centerIn: parent text: root.text diff --git a/plugins/workspace/qml/LabelOnRectangleStyle.qml b/plugins/visual/visualqml/input/qml/LabelOnRectangleStyle.qml similarity index 100% rename from plugins/workspace/qml/LabelOnRectangleStyle.qml rename to plugins/visual/visualqml/input/qml/LabelOnRectangleStyle.qml diff --git a/plugins/workspace/qml/NumberLabel.qml b/plugins/visual/visualqml/input/qml/NumberLabel.qml similarity index 98% rename from plugins/workspace/qml/NumberLabel.qml rename to plugins/visual/visualqml/input/qml/NumberLabel.qml index 43d2b21a..b6479fea 100644 --- a/plugins/workspace/qml/NumberLabel.qml +++ b/plugins/visual/visualqml/input/qml/NumberLabel.qml @@ -64,7 +64,7 @@ LabelOnRectangle{ MouseArea { anchors.fill: parent - onWheel: { + onWheel: { if (!wheelEnabled) { wheel.accepted = false return diff --git a/plugins/workspace/qml/PathInputBox.qml b/plugins/visual/visualqml/input/qml/PathInputBox.qml similarity index 97% rename from plugins/workspace/qml/PathInputBox.qml rename to plugins/visual/visualqml/input/qml/PathInputBox.qml index fa023124..c62067e5 100644 --- a/plugins/workspace/qml/PathInputBox.qml +++ b/plugins/visual/visualqml/input/qml/PathInputBox.qml @@ -1,7 +1,7 @@ import QtQuick 2.3 import fs 1.0 as Fs import workspace 1.0 - +import visual.input 1.0 as Input Item{ id: root height: 30 @@ -65,7 +65,7 @@ Item{ } } - TextButton{ + Input.TextButton{ anchors.right: parent.right radius: 5 width: 30 diff --git a/plugins/visual/visualqml/input/qml/PlayPause.qml b/plugins/visual/visualqml/input/qml/PlayPause.qml new file mode 100644 index 00000000..628f214e --- /dev/null +++ b/plugins/visual/visualqml/input/qml/PlayPause.qml @@ -0,0 +1,42 @@ +import QtQuick 2.3 +import live 1.0 +import visual.shapes 1.0 + +Item{ + id : root + width : 20 + height : 20 + + property bool isRunning: false + signal clicked(bool value) + + property color color: "#aeaeae" + + Triangle{ + id: triangle + anchors.centerIn: parent + width: root.width * 2 / 3 + height: root.height * 2 / 3 + color: root.color + rotation: Triangle.Right + visible: !root.isRunning + } + + Text{ + id: text + anchors.centerIn : parent + text : '||' + color : root.color + font.pixelSize: root.height + font.bold: true + font.letterSpacing: -1 + visible: root.isRunning + } + + MouseArea{ + anchors.fill : parent + onClicked : { + root.clicked(!root.isRunning) + } + } +} diff --git a/plugins/workspace/qml/RectangleButton.qml b/plugins/visual/visualqml/input/qml/RectangleButton.qml similarity index 87% rename from plugins/workspace/qml/RectangleButton.qml rename to plugins/visual/visualqml/input/qml/RectangleButton.qml index a6749e9d..45c143c0 100644 --- a/plugins/workspace/qml/RectangleButton.qml +++ b/plugins/visual/visualqml/input/qml/RectangleButton.qml @@ -1,10 +1,11 @@ import QtQuick 2.3 import workspace 1.0 +import visual.input 1.0 as Input Rectangle{ id: root - property QtObject defaultStyle : RectangleButtonStyle{} + property QtObject defaultStyle : Input.RectangleButtonStyle{} property QtObject style: defaultStyle signal clicked() diff --git a/plugins/workspace/qml/RectangleButtonStyle.qml b/plugins/visual/visualqml/input/qml/RectangleButtonStyle.qml similarity index 100% rename from plugins/workspace/qml/RectangleButtonStyle.qml rename to plugins/visual/visualqml/input/qml/RectangleButtonStyle.qml diff --git a/plugins/workspace/qml/RectangleSelection.qml b/plugins/visual/visualqml/input/qml/RectangleSelection.qml similarity index 100% rename from plugins/workspace/qml/RectangleSelection.qml rename to plugins/visual/visualqml/input/qml/RectangleSelection.qml diff --git a/plugins/workspace/qml/SelectableListView.qml b/plugins/visual/visualqml/input/qml/SelectableListView.qml similarity index 97% rename from plugins/workspace/qml/SelectableListView.qml rename to plugins/visual/visualqml/input/qml/SelectableListView.qml index 4923b38b..0f4ca421 100644 --- a/plugins/workspace/qml/SelectableListView.qml +++ b/plugins/visual/visualqml/input/qml/SelectableListView.qml @@ -2,6 +2,7 @@ import QtQuick 2.3 import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.2 import workspace 1.0 +import visual.input 1.0 as Input Rectangle{ id: root @@ -21,7 +22,7 @@ Rectangle{ property alias currentIndex: listView.currentIndex property alias currentItem: listView.currentItem - property QtObject defaultStyle: SelectableListViewStyle{} + property QtObject defaultStyle: Input.SelectableListViewStyle{} property QtObject style: defaultStyle signal triggered(int index) diff --git a/plugins/workspace/qml/SelectableListViewStyle.qml b/plugins/visual/visualqml/input/qml/SelectableListViewStyle.qml similarity index 100% rename from plugins/workspace/qml/SelectableListViewStyle.qml rename to plugins/visual/visualqml/input/qml/SelectableListViewStyle.qml diff --git a/plugins/workspace/qml/TextButton.qml b/plugins/visual/visualqml/input/qml/TextButton.qml similarity index 89% rename from plugins/workspace/qml/TextButton.qml rename to plugins/visual/visualqml/input/qml/TextButton.qml index 74b91461..9260d0ef 100644 --- a/plugins/workspace/qml/TextButton.qml +++ b/plugins/visual/visualqml/input/qml/TextButton.qml @@ -1,11 +1,12 @@ import QtQuick 2.3 import workspace 1.0 +import visual.input 1.0 as Input Rectangle{ id: root - property QtObject style: TextButtonStyle{} - + property QtObject style: Input.TextButtonStyle{} + signal clicked() color : buttonMouseArea.containsMouse ? style.backgroundHoverColor : style.backgroundColor @@ -21,7 +22,7 @@ Rectangle{ gradient: buttonMouseArea.containsMouse ? style.backgroundHoverGradient : style.backgroundGradient - Label{ + Input.Label{ id: label textStyle: buttonMouseArea.containsMouse ? root.style.hoverTextStyle : root.style.textStyle text: root.text diff --git a/plugins/workspace/qml/TextButtonStyle.qml b/plugins/visual/visualqml/input/qml/TextButtonStyle.qml similarity index 100% rename from plugins/workspace/qml/TextButtonStyle.qml rename to plugins/visual/visualqml/input/qml/TextButtonStyle.qml diff --git a/plugins/visual/visualqml/input/qml/qmldir b/plugins/visual/visualqml/input/qml/qmldir index 2194903e..b9996428 100644 --- a/plugins/visual/visualqml/input/qml/qmldir +++ b/plugins/visual/visualqml/input/qml/qmldir @@ -2,18 +2,34 @@ module visual.input depends QtQuick 2.3 +AlphaSlider 1.0 AlphaSlider.qml +Button 1.0 Button.qml CheckBox 1.0 CheckBox.qml CheckBoxStyle 1.0 CheckBoxStyle.qml -NumberSpinBox 1.0 NumberSpinBox.qml -NumberSpinBoxStyle 1.0 NumberSpinBoxStyle.qml -TextStyle 1.0 TextStyle.qml -Label 1.0 Label.qml -InputBox 1.0 InputBox.qml -InputBoxStyle 1.0 InputBoxStyle.qml -DropDown 1.0 DropDown.qml -DropDownStyle 1.0 DropDownStyle.qml -AlphaSlider 1.0 AlphaSlider.qml ColorPicker 1.0 ColorPicker.qml +ColorHSVPicker 1.0 ColorHSVPicker.qml ColorPickerStyle 1.0 ColorPickerStyle.qml +ConvexQuadSelection 1.0 ConvexQuadSelection.qml +DropDown 1.0 DropDown.qml +DropDownStyle 1.0 DropDownStyle.qml +EditableLabel 1.0 EditableLabel.qml HueSlider 1.0 HueSlider.qml +InputBox 1.0 InputBox.qml +InputBoxStyle 1.0 InputBoxStyle.qml +Label 1.0 Label.qml +LabelOnRectangle 1.0 LabelOnRectangle.qml +LabelOnRectangleStyle 1.0 LabelOnRectangleStyle.qml +NumberLabel 1.0 NumberLabel.qml +NumberSpinBox 1.0 NumberSpinBox.qml +NumberSpinBoxStyle 1.0 NumberSpinBoxStyle.qml +PathInputBox 1.0 PathInputBox.qml +PlayPause 1.0 PlayPause.qml +RectangleButton 1.0 RectangleButton.qml +RectangleButtonStyle 1.0 RectangleButtonStyle.qml +RectangleSelection 1.0 RectangleSelection.qml +SelectableListView 1.0 SelectableListView.qml +SelectableListViewStyle 1.0 SelectableListViewStyle.qml SaturationBrightnessSlider 1.0 SaturationBrightnessSlider.qml +TextButton 1.0 TextButton.qml +TextButtonStyle 1.0 TextButtonStyle.qml +TextStyle 1.0 TextStyle.qml diff --git a/plugins/workspace/nodeeditor/qml/ObjectGraph.qml b/plugins/workspace/nodeeditor/qml/ObjectGraph.qml index 16b2e177..7afb196e 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectGraph.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectGraph.qml @@ -4,9 +4,9 @@ import QtQuick.Controls.Material 2.1 import QtQuick.Layouts 1.3 import live 1.0 -import workspace 1.0 as Workspace import workspace.quickqanava 2.0 as Qan import editqml 1.0 +import visual.input 1.0 as Input Rectangle{ id: root @@ -48,13 +48,13 @@ Rectangle{ property color titleBackground: "#666" property double titleRadius: 5 - property QtObject titleTextStyle : Workspace.TextStyle{} + property QtObject titleTextStyle : Input.TextStyle{} } property QtObject propertyDelegateStyle : QtObject{ property color background: "#333" property double radius: 5 - property QtObject textStyle: Workspace.TextStyle{} + property QtObject textStyle: Input.TextStyle{} } } diff --git a/plugins/workspace/nodeeditor/qml/ObjectNode.qml b/plugins/workspace/nodeeditor/qml/ObjectNode.qml index 9570cffc..d2328e07 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectNode.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectNode.qml @@ -4,8 +4,8 @@ import editor 1.0 import editor.private 1.0 import editqml 1.0 -import workspace 1.0 as Workspace import workspace.quickqanava 2.0 as Qan +import visual.input 1.0 as Input Qan.NodeItem{ id: root @@ -178,7 +178,7 @@ Qan.NodeItem{ property color titleBackground: "#666" property double titleRadius: 5 - property QtObject titleTextStyle : Workspace.TextStyle{} + property QtObject titleTextStyle : Input.TextStyle{} } property QtObject nodeStyle : defaultStyle @@ -201,7 +201,7 @@ Qan.NodeItem{ color: root.nodeStyle.titleBackground radius: root.nodeStyle.titleRadius - Workspace.Label{ + Input.Label{ anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.leftMargin: 15 diff --git a/plugins/workspace/nodeeditor/qml/ObjectNodeProperty.qml b/plugins/workspace/nodeeditor/qml/ObjectNodeProperty.qml index 41f8988a..8fa9b747 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectNodeProperty.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectNodeProperty.qml @@ -4,6 +4,7 @@ import editor.private 1.0 import editqml 1.0 import workspace 1.0 as Workspace +import visual.input 1.0 as Input Item{ id: propertyItem @@ -43,7 +44,7 @@ Item{ property QtObject defaultStyle : QtObject{ property color background: "#333" property double radius: 5 - property QtObject textStyle: Workspace.TextStyle{} + property QtObject textStyle: Input.TextStyle{} } property QtObject style: defaultStyle @@ -81,7 +82,7 @@ Item{ width: parent.width - 10 height: 30 - Workspace.Label{ + Input.Label{ anchors.verticalCenter : parent.verticalCenter anchors.left: parent.left anchors.leftMargin: 10 diff --git a/plugins/workspace/qml/InputBox.qml b/plugins/workspace/qml/InputBox.qml deleted file mode 100644 index 969867ab..00000000 --- a/plugins/workspace/qml/InputBox.qml +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ - -import QtQuick 2.3 -import workspace 1.0 - -Rectangle { - id : root - width: 100 - height: 30 - - border.color : style.borderColor - border.width : style.borderThickness - color : style.backgroundColor - radius: style.radius - clip: true - - property real margins: 6 - - property QtObject defaultStyle : InputBoxStyle{} - property QtObject style: defaultStyle - - property alias text : textInput.text - property alias font: textInput.font - property alias inputActiveFocus: textInput.activeFocus - property string textHint : '' - - property alias validator: textInput.validator - - property Item nextFocusItem: null - property Item prevFocusItem: null - - signal keyPressed(var event) - signal activeFocusLost() - - function selectAll(){ - textInput.selectAll() - } - function forceFocus(){ - textInput.forceActiveFocus() - } - - TextInput{ - id : textInput - anchors.fill: parent - anchors.margins : root.margins - font: root.style.textStyle.font - text: '' - color : root.style.textStyle.color - selectByMouse: true - selectionColor: root.style.textSelectionColor - - property bool touched : false - - Keys.onTabPressed: { - if ( root.nextFocusItem ){ - if ( root.nextFocusItem.forceFocus ) - root.nextFocusItem.forceFocus() - else - root.nextFocusItem.forceActiveFocus() - event.accepted = true - } - } - Keys.onBacktabPressed: { - if ( root.prevFocusItem ){ - if ( root.prevFocusItem.forceFocus ) - root.prevFocusItem.forceFocus() - else - root.prevFocusItem.forceActiveFocus() - event.accepted = true - } - } - - Keys.onPressed : { - if ( event.key === Qt.Key_Tab ){ - if ( root.nextFocusItem ){ - if ( root.nextFocusItem.forceFocus ) - root.nextFocusItem.forceFocus() - else - root.nextFocusItem.forceActiveFocus() - event.accepted = true - } - } else if ( event.ey === Qt.Key_Backtab ){ - if ( root.prevFocusItem ){ - if ( root.prevFocusItem.forceFocus ) - root.prevFocusItem.forceFocus() - else - root.prevFocusItem.forceActiveFocus() - event.accepted = true - } - } - - root.keyPressed(event) - } - - MouseArea{ - anchors.fill: parent - acceptedButtons: Qt.NoButton - cursorShape: Qt.IBeamCursor - } - - onActiveFocusChanged: { - if (!activeFocus) - root.activeFocusLost() - } - } - - Text { - anchors.fill: parent - anchors.margins : textInput.anchors.margins - text: root.textHint - font: root.style.hintTextStyle.font - color: root.style.hintTextStyle.color - visible: !textInput.text && !textInput.activeFocus - } -} - diff --git a/plugins/workspace/qml/InputBoxStyle.qml b/plugins/workspace/qml/InputBoxStyle.qml deleted file mode 100644 index f0b90646..00000000 --- a/plugins/workspace/qml/InputBoxStyle.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.3 - -QtObject{ - property QtObject textStyle: TextStyle{} - property QtObject hintTextStyle: TextStyle{} - property color backgroundColor: '#070b0f' - property color borderColor: '#323232' - property double borderThickness: 1 - property color textSelectionColor: '#3d4856' - property double radius: 3 -} diff --git a/plugins/workspace/qml/Label.qml b/plugins/workspace/qml/Label.qml deleted file mode 100644 index ce7a3e21..00000000 --- a/plugins/workspace/qml/Label.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.3 - -Text{ - property QtObject textStyle: TextStyle{} - font: textStyle.font - color: textStyle.color -} diff --git a/plugins/workspace/qml/PopupMenuStyle.qml b/plugins/workspace/qml/PopupMenuStyle.qml index a3a2704f..462dbb2c 100644 --- a/plugins/workspace/qml/PopupMenuStyle.qml +++ b/plugins/workspace/qml/PopupMenuStyle.qml @@ -1,5 +1,6 @@ import QtQuick 2.0 import workspace 1.0 +import visual.input 1.0 as Input QtObject{ property color backgroundColor: "#000" @@ -8,8 +9,8 @@ QtObject{ property double borderWidth: 1 property double radius: 0 - property QtObject textStyle: TextStyle{} - property QtObject highlightTextStyle: TextStyle{} + property QtObject textStyle: Input.TextStyle{} + property QtObject highlightTextStyle: Input.TextStyle{} } diff --git a/plugins/workspace/qml/TextStyle.qml b/plugins/workspace/qml/TextStyle.qml deleted file mode 100644 index 58b8aff2..00000000 --- a/plugins/workspace/qml/TextStyle.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.3 - -QtObject{ - property color color: "#fff" - property font font : Qt.font({ - family: 'Open Sans, sans-serif', - weight: Font.Normal, - italic: false, - pixelSize: 12 - }) -} diff --git a/plugins/workspace/qml/Tooltip.qml b/plugins/workspace/qml/Tooltip.qml index 61989ea3..50289fce 100644 --- a/plugins/workspace/qml/Tooltip.qml +++ b/plugins/workspace/qml/Tooltip.qml @@ -1,5 +1,5 @@ import QtQuick 2.3 -import workspace 1.0 as Workspace +import visual.input 1.0 as Input Item{ id: tooltip @@ -56,7 +56,7 @@ Item{ property alias labelStyle: label.textStyle - Workspace.Label{ + Input.Label{ id: label anchors.left: parent.left anchors.leftMargin: 5 diff --git a/plugins/workspace/qml/qmldir b/plugins/workspace/qml/qmldir index e84ab84a..27f70925 100644 --- a/plugins/workspace/qml/qmldir +++ b/plugins/workspace/qml/qmldir @@ -2,33 +2,13 @@ module workspace depends QtQuick 2.3 -EditableLabel 1.0 EditableLabel.qml -PlayPause 1.0 PlayPause.qml Highlighter 1.0 Highlighter.qml -Button 1.0 Button.qml -TextStyle 1.0 TextStyle.qml -TextButton 1.0 TextButton.qml -TextButtonStyle 1.0 TextButtonStyle.qml -Label 1.0 Label.qml -LabelOnRectangle 1.0 LabelOnRectangle.qml -LabelOnRectangleStyle 1.0 LabelOnRectangleStyle.qml -InputBox 1.0 InputBox.qml -InputBoxStyle 1.0 InputBoxStyle.qml -PathInputBox 1.0 PathInputBox.qml -RectangleButton 1.0 RectangleButton.qml -RectangleButtonStyle 1.0 RectangleButtonStyle.qml -NumberLabel 1.0 NumberLabel.qml PaneMenu 1.0 PaneMenu.qml PaneMenuItem 1.0 PaneMenuItem.qml PopupMenuStyle 1.0 PopupMenuStyle.qml -SelectableListView 1.0 SelectableListView.qml -SelectableListViewStyle 1.0 SelectableListViewStyle.qml -ColorPicker 1.0 ColorPicker.qml -RectangleSelection 1.0 RectangleSelection.qml Tooltip 1.0 Tooltip.qml Tool 1.0 Tool.qml Toolbar 1.0 Toolbar.qml Toolbox 1.0 Toolbox.qml ToolButton 1.0 ToolButton.qml -ConvexQuadSelection 1.0 ConvexQuadSelection.qml From ead74cf520e5dbaf34ae6c355936b9b3a87ad292 Mon Sep 17 00:00:00 2001 From: nenad-popovic-91 <42581059+nenad-popovic-91@users.noreply.github.com> Date: Wed, 2 Jun 2021 19:49:50 +0200 Subject: [PATCH 49/91] GalleryFileSelector (#218) Added GalleryFileSelector --- plugins/lcvcore/lcvcore.pro | 2 + .../palettes/GalleryFileSelectorPalette.qml | 162 ++++++++++++++++++ plugins/lcvcore/qml/GalleryFileSelector.qml | 7 + plugins/lcvcore/qml/live.plugin.json | 3 +- plugins/lcvcore/qml/qmldir | 1 + 5 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 plugins/lcvcore/palettes/GalleryFileSelectorPalette.qml create mode 100644 plugins/lcvcore/qml/GalleryFileSelector.qml diff --git a/plugins/lcvcore/lcvcore.pro b/plugins/lcvcore/lcvcore.pro index c579fd85..6a489f50 100644 --- a/plugins/lcvcore/lcvcore.pro +++ b/plugins/lcvcore/lcvcore.pro @@ -61,6 +61,7 @@ QMAKE_EXTRA_TARGETS += first palettecopy samplescopy DISTFILES += \ palettes/DrawPalette.qml \ + palettes/GalleryFileSelectorPalette.qml \ palettes/GrayscaleViewPalette.json \ palettes/ImageFilePalette.json \ palettes/ImageReadPalette.json \ @@ -86,6 +87,7 @@ DISTFILES += \ qml/CropTool.qml \ qml/DrawSurface.qml \ qml/EditCvExtension.qml \ + qml/GalleryFileSelector.qml \ qml/GradientTool.qml \ qml/GrayscaleView.qml \ qml/ImageRead.qml \ diff --git a/plugins/lcvcore/palettes/GalleryFileSelectorPalette.qml b/plugins/lcvcore/palettes/GalleryFileSelectorPalette.qml new file mode 100644 index 00000000..839fb4f7 --- /dev/null +++ b/plugins/lcvcore/palettes/GalleryFileSelectorPalette.qml @@ -0,0 +1,162 @@ +import QtQuick 2.3 +import workspace 1.0 as Workspace +import workspace.icons 1.0 as Icons +import editor 1.0 +import fs 1.0 as Fs +import lcvcore 1.0 as Cv +import lcvimgproc 1.0 +import QtQuick.Controls.Styles 1.2 + +CodePalette{ + id: palette + type : "qml/lcvcore#GalleryFileSelector" + + property QtObject theme: lk.layers.workspace.themes.current + + property QtObject style: QtObject{} + + item: Item{ + id: root + width: 450 + height: 200 + + property QtObject galleryFileSelector: null + + GridView { + id: gridView + width: 450 + height: 200 + cellWidth: 140 + cellHeight: 160 + property var path: { + if (!parent.galleryFileSelector) + return '' + if (!Fs.Path.exists(parent.galleryFileSelector.workingDirectory)) + return project.dir() + else + return parent.galleryFileSelector.workingDirectory + } + model: { + var res = Fs.Dir.listDetail(gridView.path) + if (res) + res = res.filter(item => item.isDir === false) + return res + } + delegate: Rectangle { + width: 140 + height: 160 + color: 'transparent' + property bool isImage: modelData.name.toLowerCase().endsWith('.jpg') + || modelData.name.toLowerCase().endsWith('.png') + || modelData.name.toLowerCase().endsWith('.bmp') + || modelData.name.toLowerCase().endsWith('.jpeg') + + + Rectangle { + id: rec + anchors.top: parent.top + anchors.topMargin: 10 + width: 110 + height: 110 + color: "transparent" + anchors.horizontalCenter: parent.horizontalCenter + + Loader { + property var imageDelegate: Component { + Item { + width: imageView.width + height: imageView.height + Cv.ImageRead { + id: imRead + file: gridView.path + "/" + modelData.name + } + + Resize { + id: resize + input: imRead.result + size: { + var dims = input ? input.dimensions() : Qt.size(100, 100) + if (dims.width > dims.height){ + return Qt.size(100.0, 100.0 * dims.height / dims.width) + } else { + return Qt.size(100.0 * dims.width / dims.height, 100.0) + } + } + } + + Cv.ImageView{ + id: imageView + image: resize.result + width: image ? image.dimensions().width: 100 + height: image ? image.dimensions().height: 100 + + linearFilter: false + } + + } + } + property var nonImageDelegate: Component { + Icons.FileIcon{ + width: 50 + height: 50 + } + } + sourceComponent: isImage ? imageDelegate : nonImageDelegate + anchors.centerIn: parent + + } + } + Rectangle { + width: text.width + height: text.height + color: "transparent" + anchors.top: rec.bottom + anchors.topMargin: 5 + Text { + id: text + text: modelData.name + color: "white" + height: 20 + width: 120 + elide: Text.ElideRight + horizontalAlignment: Text.AlignHCenter + } + anchors.horizontalCenter: parent.horizontalCenter + } + + MouseArea { + id: ma + anchors.fill: parent + onClicked: { + gridView.currentIndex = index + if (root.galleryFileSelector) + root.galleryFileSelector.highlightedFile = gridView.path + "/" + modelData.name + } + onDoubleClicked: { + if (root.galleryFileSelector && parent.isImage){ + root.galleryFileSelector.selectedFile = gridView.path + "/" + modelData.name + } + } + } + + + } + + highlight: Rectangle { + color: "#66cccccc" + } + highlightFollowsCurrentItem: true + focus: true + clip: true + + } + + } + + onInit: { + palette.item.galleryFileSelector = value + } + +} + + diff --git a/plugins/lcvcore/qml/GalleryFileSelector.qml b/plugins/lcvcore/qml/GalleryFileSelector.qml new file mode 100644 index 00000000..2fc6dc85 --- /dev/null +++ b/plugins/lcvcore/qml/GalleryFileSelector.qml @@ -0,0 +1,7 @@ +import QtQuick 2.3 + +QtObject{ + property string workingDirectory: project.dir() + property string highlightedFile: '' + property string selectedFile: '' +} diff --git a/plugins/lcvcore/qml/live.plugin.json b/plugins/lcvcore/qml/live.plugin.json index d1b01ac0..c3ef7556 100644 --- a/plugins/lcvcore/qml/live.plugin.json +++ b/plugins/lcvcore/qml/live.plugin.json @@ -21,6 +21,7 @@ "palettes/PerspectiveOnBackgroundPalette.qml": "qml/lcvcore#PerspectiveOnBackground", "palettes/PerspectiveOnBackgroundPropertiesPalette.json": "qml/lcvcore#PerspectiveOnBackground", "palettes/ImageSegmentFactoryPalette.qml": "qml/lcvcore#ImageSegmentFactory", - "palettes/ImageSegmentFactoryPropertiesPalette.json": "qml/lcvcore#ImageSegmentFactory" + "palettes/ImageSegmentFactoryPropertiesPalette.json": "qml/lcvcore#ImageSegmentFactory", + "palettes/GalleryFileSelectorPalette.qml": "qml/lcvcore#GalleryFileSelector" } } diff --git a/plugins/lcvcore/qml/qmldir b/plugins/lcvcore/qml/qmldir index 349bed21..168f1afc 100644 --- a/plugins/lcvcore/qml/qmldir +++ b/plugins/lcvcore/qml/qmldir @@ -27,3 +27,4 @@ GradientTool 1.0 GradientTool.qml Perspective 1.0 Perspective.qml PaperSurface 1.0 PaperSurface.qml PerspectiveOnBackground 1.0 PerspectiveOnBackground.qml +GalleryFileSelector 1.0 GalleryFileSelector.qml From 2c965d2cd1fe4a847a9380a4f8baa30b1f4bb65e Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Wed, 2 Jun 2021 21:00:33 +0300 Subject: [PATCH 50/91] Fixed event to function binding in nodes. --- plugins/workspace/nodeeditor/qml/ObjectGraph.qml | 2 +- plugins/workspace/nodeeditor/qml/ObjectNode.qml | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/workspace/nodeeditor/qml/ObjectGraph.qml b/plugins/workspace/nodeeditor/qml/ObjectGraph.qml index 16b2e177..95db81c0 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectGraph.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectGraph.qml @@ -217,7 +217,7 @@ Rectangle{ if (!srcPort.objectProperty.editingFragment) return - var result = srcPort.objectProperty.editingFragment.bindExpression(value) + var result = srcPort.objectProperty.editingFragment.bindFunctionExpression(value) if ( result ){ srcPort.objectProperty.editingFragment.write( {'__ref': value} diff --git a/plugins/workspace/nodeeditor/qml/ObjectNode.qml b/plugins/workspace/nodeeditor/qml/ObjectNode.qml index 9570cffc..c537a022 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectNode.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectNode.qml @@ -325,7 +325,9 @@ Qan.NodeItem{ propertiesOpened.push(name) var portState = ObjectGraph.PortMode.OutPort - if (prop.isWritable) portState = portState | ObjectGraph.PortMode.InPort + if (prop.isWritable || ef.location === QmlEditFragment.Slot) { + portState = portState | ObjectGraph.PortMode.InPort + } addSubobject(nodeParent, name, portState, prop.connection) } From a03d4b33d8eb39a5ee40d446468ad15f9e76021e Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Wed, 2 Jun 2021 21:00:46 +0300 Subject: [PATCH 51/91] Timeline: Added "Add video surface" action. --- plugins/timeline/qml/TimelineView.qml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/plugins/timeline/qml/TimelineView.qml b/plugins/timeline/qml/TimelineView.qml index f1a3cdc2..0006b644 100644 --- a/plugins/timeline/qml/TimelineView.qml +++ b/plugins/timeline/qml/TimelineView.qml @@ -89,6 +89,32 @@ Rectangle{ } } }, { + name: "Add Video Surface...", + enabled: true, + action: function(){ + var objectPath = lk.layers.workspace.pluginsPath() + '/lcvcore/VideoSurfaceCreator.qml' + var objectPathUrl = Fs.UrlInfo.urlFromLocalFile(objectPath) + + var objectComponent = Qt.createComponent(objectPathUrl); + if ( objectComponent.status === Component.Error ){ + throw linkError(new Error(objectComponent.errorString()), this) + } + + var object = objectComponent.createObject(); + var overlay = lk.layers.window.dialogs.overlayBox(object) + + object.surfaceCreated.connect(function(videoSurface){ + root.timeline.properties.videoSurface = videoSurface + overlay.closeBox() + object.destroy() + }) + + object.cancelled.connect(function(){ + overlay.closeBox() + object.destroy() + }) + } + },{ name: "Add Keyframe Track", enabled: true, action: function(){ From 3e14bb46a23b0c017217bfb09b0b3cdbc7e2c04c Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Wed, 2 Jun 2021 21:01:36 +0300 Subject: [PATCH 52/91] lcvcore: Fixed ImageSegmentFactory file creation. --- plugins/lcvcore/qml/ImageSegmentFactory.qml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/lcvcore/qml/ImageSegmentFactory.qml b/plugins/lcvcore/qml/ImageSegmentFactory.qml index 5dc36df0..0969bb5a 100644 --- a/plugins/lcvcore/qml/ImageSegmentFactory.qml +++ b/plugins/lcvcore/qml/ImageSegmentFactory.qml @@ -5,6 +5,7 @@ import timeline 1.0 QtObject{ property string file: '' + property int position: 0 property int length: 0 @@ -16,13 +17,15 @@ QtObject{ property var track: null function create(){ - if ( !file ){ + var fileTrim = file.trim() + + if ( !fileTrim || fileTrim.length === 0){ return } var segment = factory.createObject() - segment.file = file - segment.length = 10 + segment.file = fileTrim + segment.length = 30 if ( length > 0 ) segment.length = length if ( position > 0 ) From fb4b2ee9771e36c1c8ac0ba45c3ab1e6335cefec Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Wed, 2 Jun 2021 21:01:57 +0300 Subject: [PATCH 53/91] lcvcore, timeline: Renamed filter creation context menu actions. --- plugins/lcvcore/qml/EditCvExtension.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/lcvcore/qml/EditCvExtension.qml b/plugins/lcvcore/qml/EditCvExtension.qml index 49b37507..db267097 100644 --- a/plugins/lcvcore/qml/EditCvExtension.qml +++ b/plugins/lcvcore/qml/EditCvExtension.qml @@ -61,7 +61,7 @@ WorkspaceExtension{ if ( item.currentSegment instanceof Cv.VideoSegment || item.currentSegment instanceof Cv.ImageSegment ){ var segment = item.currentSegment return [{ - name : "Adjust", + name : "Create Filter", action : function(){ if ( !project.isDirProject() ){ lk.layers.workspace.messages.pushError( @@ -164,7 +164,7 @@ WorkspaceExtension{ } } },{ - name : "Adjust Using Nodes", + name : "Create Filter using Nodes", action : function(){ if ( !project.isDirProject() ){ lk.layers.workspace.messages.pushError( From f55641dddd4d1dc4d2b3c561a361ec07763c4fe0 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Wed, 2 Jun 2021 21:03:56 +0300 Subject: [PATCH 54/91] Added StreamLog, ExecProperties, StreamValue, VisualFileSelectorProperties, ImageSegmentFactoryProperties palettes. Updated TextPalette commit button. --- lib/lveditqmljs/src/qmljssettings.cpp | 2 ++ plugins/base/baseqml/baseqml.pro | 2 ++ .../base/baseqml/palettes/ExecPropertiesPalette.json | 11 +++++++++++ .../baseqml/palettes/StreamLogPropertiesPalette.json | 7 +++++++ plugins/base/baseqml/palettes/StreamValuePalette.json | 1 + plugins/base/baseqml/qml/live.plugin.json | 4 +++- plugins/editor/palettes/TextPalette.qml | 4 ++++ plugins/editqml/qml/PaletteControls.qml | 6 +++++- .../palettes/VisualFileSelectorPropertiesPalette.json | 3 ++- .../ImageSegmentFactoryPropertiesPalette.json | 4 ++-- 10 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 plugins/base/baseqml/palettes/ExecPropertiesPalette.json create mode 100644 plugins/base/baseqml/palettes/StreamLogPropertiesPalette.json diff --git a/lib/lveditqmljs/src/qmljssettings.cpp b/lib/lveditqmljs/src/qmljssettings.cpp index d7d392ef..38d17bda 100644 --- a/lib/lveditqmljs/src/qmljssettings.cpp +++ b/lib/lveditqmljs/src/qmljssettings.cpp @@ -60,7 +60,9 @@ QmlJsSettings::QmlJsSettings(EditorSettings *parent) m_defaultPalettes["qml/int"] = "IntPalette"; m_defaultPalettes["qml/string"] = "TextPalette"; m_defaultPalettes["qml/color"] = "ColorPalette"; + m_defaultPalettes["qml/base#Exec"] = "ExecPropertiesPalette"; m_defaultPalettes["qml/base#StreamValue"] = "StreamValuePalette"; + m_defaultPalettes["qml/base#StreamLog"] = "StreamLogPropertiesPalette"; m_defaultPalettes["qml/lcvcore#VideoDecoderView"] = "VideoDecoderViewPalette"; m_defaultPalettes["qml/lcvcore#VideoFile"] = "VideoFilePropertiesPalette"; m_defaultPalettes["qml/lcvcore#GrayscaleView"] = "GrayscaleViewPalette"; diff --git a/plugins/base/baseqml/baseqml.pro b/plugins/base/baseqml/baseqml.pro index 122b9d97..8f5a9a78 100644 --- a/plugins/base/baseqml/baseqml.pro +++ b/plugins/base/baseqml/baseqml.pro @@ -49,6 +49,8 @@ QMAKE_EXTRA_TARGETS += first palettecopy samplescopy DISTFILES += \ + palettes/ExecPropertiesPalette.json \ + palettes/StreamLogPropertiesPalette.json \ palettes/StreamValuePalette.json \ qml/ConvertToInt.qml \ qml/JsonDecoder.qml \ diff --git a/plugins/base/baseqml/palettes/ExecPropertiesPalette.json b/plugins/base/baseqml/palettes/ExecPropertiesPalette.json new file mode 100644 index 00000000..5a9648ec --- /dev/null +++ b/plugins/base/baseqml/palettes/ExecPropertiesPalette.json @@ -0,0 +1,11 @@ +{ + "type": "qml/base#Exec", + "palettes" : ["ExecPalette"], + "properties" : [ + ["path", "TextPalette"], + ["args", "StringListPalette"], + ["input"], + ["out", "", "true"] + ] +} + diff --git a/plugins/base/baseqml/palettes/StreamLogPropertiesPalette.json b/plugins/base/baseqml/palettes/StreamLogPropertiesPalette.json new file mode 100644 index 00000000..8e622d2a --- /dev/null +++ b/plugins/base/baseqml/palettes/StreamLogPropertiesPalette.json @@ -0,0 +1,7 @@ +{ + "type": "qml/base#StreamLog", + "properties" : [ + ["stream"] + ] +} + diff --git a/plugins/base/baseqml/palettes/StreamValuePalette.json b/plugins/base/baseqml/palettes/StreamValuePalette.json index 15144fd5..44a7a761 100644 --- a/plugins/base/baseqml/palettes/StreamValuePalette.json +++ b/plugins/base/baseqml/palettes/StreamValuePalette.json @@ -1,6 +1,7 @@ { "type": "qml/base#StreamValue", "properties" : [ + ["stream"], ["value"] ] } diff --git a/plugins/base/baseqml/qml/live.plugin.json b/plugins/base/baseqml/qml/live.plugin.json index 1ce75cc0..81267443 100644 --- a/plugins/base/baseqml/qml/live.plugin.json +++ b/plugins/base/baseqml/qml/live.plugin.json @@ -4,6 +4,8 @@ "libraryModules" : ["lvbase"], "palettes" : { "palettes/ExecPalette.qml" : "qml/base#Exec", - "palettes/StreamValuePalette.json" : "qml/base#StreamValue" + "palettes/ExecPropertiesPalette.json" : "qml/base#Exec", + "palettes/StreamValuePalette.json" : "qml/base#StreamValue", + "palettes/StreamLogPropertiesPalette.json" : "qml/base#StreamLog" } } diff --git a/plugins/editor/palettes/TextPalette.qml b/plugins/editor/palettes/TextPalette.qml index 5804a441..233214bf 100644 --- a/plugins/editor/palettes/TextPalette.qml +++ b/plugins/editor/palettes/TextPalette.qml @@ -26,6 +26,7 @@ CodePalette{ height: 25 style: theme.inputStyle + onTextChanged: commitButton.visible = true onKeyPressed: { if ( event.key === Qt.Key_Return ){ @@ -33,12 +34,14 @@ CodePalette{ if ( !palette.isBindingChange() ){ editFragment.write(palette.value) } + commitButton.visible = false event.accepted = true } } } Workspace.Button{ + id: commitButton anchors.right: parent.right width: 30 height: 25 @@ -48,6 +51,7 @@ CodePalette{ if ( !palette.isBindingChange() ){ editFragment.write(palette.value) } + commitButton.visible = false } } diff --git a/plugins/editqml/qml/PaletteControls.qml b/plugins/editqml/qml/PaletteControls.qml index 2bc4a7f5..9bb596d1 100644 --- a/plugins/editqml/qml/PaletteControls.qml +++ b/plugins/editqml/qml/PaletteControls.qml @@ -379,7 +379,11 @@ QtObject{ } } else if (isForNode && addBoxItem.activeIndex === 4 ){ - container.nodeParent.item.addSubobject(container.nodeParent, data, container.nodeParent.item.id ? ObjectGraph.PortMode.InPort : ObjectGraph.PortMode.Node, null) + container.nodeParent.item.addSubobject( + container.nodeParent, + data, + container.nodeParent.item.id ? ObjectGraph.PortMode.InPort : ObjectGraph.PortMode.Node, + null) } if (isForNode) objectGraph.activateFocus() diff --git a/plugins/fs/fsqml/qml/palettes/VisualFileSelectorPropertiesPalette.json b/plugins/fs/fsqml/qml/palettes/VisualFileSelectorPropertiesPalette.json index 5c94e40a..8f153d9b 100644 --- a/plugins/fs/fsqml/qml/palettes/VisualFileSelectorPropertiesPalette.json +++ b/plugins/fs/fsqml/qml/palettes/VisualFileSelectorPropertiesPalette.json @@ -3,7 +3,8 @@ "palettes": ["VisualFileSelectorPalette"], "properties" : [ ["workingDirectory", "FolderPathPalette"], - ["selectedFile", "", "true"] + ["selectedFile", "", "true"], + ["highlightedFile", "", "true"] ] } diff --git a/plugins/lcvcore/palettes/ImageSegmentFactoryPropertiesPalette.json b/plugins/lcvcore/palettes/ImageSegmentFactoryPropertiesPalette.json index 1affe644..e806cac1 100644 --- a/plugins/lcvcore/palettes/ImageSegmentFactoryPropertiesPalette.json +++ b/plugins/lcvcore/palettes/ImageSegmentFactoryPropertiesPalette.json @@ -2,9 +2,9 @@ "type": "qml/lcvcore#ImageSegmentFactory", "palettes": ["ImageSegmentFactoryPalette"], "properties" : [ - ["file", "FilePathPalette"], + ["timeline"], ["trackName", "TextPalette"], - ["timeline"] + ["file", "FilePathPalette"] ] } From 975e915553e3c9e859584e0d82bd24872dd12478 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Wed, 2 Jun 2021 21:04:20 +0300 Subject: [PATCH 55/91] lvview: Shared: Added support for ArrayBuffer when deserializing. --- lib/lvview/src/shared.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/lvview/src/shared.cpp b/lib/lvview/src/shared.cpp index 01c44f66..6b1d406c 100644 --- a/lib/lvview/src/shared.cpp +++ b/lib/lvview/src/shared.cpp @@ -90,6 +90,10 @@ QVariant Shared::transfer(const QJSValue &value, QList &shared){ } else if ( value.isDate() ){ return QVariant(value.toDateTime()); } else if ( value.isObject() ){ + if ( value.property("constructor").property("name").toString() == "ArrayBuffer" ){ + return QVariant(value.toString()); + } + QJSValueIterator it(value); QVariantMap vm; while ( it.next() ){ From 9dc97d69a3420590375a23e301e2f8b5376173ba Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Wed, 2 Jun 2021 21:04:43 +0300 Subject: [PATCH 56/91] editqml: QmlEditFragmment: Updated location function. --- lib/lveditqmljs/src/qmleditfragment.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/lveditqmljs/src/qmleditfragment.h b/lib/lveditqmljs/src/qmleditfragment.h index e7f85efa..860faca2 100644 --- a/lib/lveditqmljs/src/qmleditfragment.h +++ b/lib/lveditqmljs/src/qmleditfragment.h @@ -121,6 +121,8 @@ class LV_EDITQMLJS_EXPORT QmlEditFragment : public QObject{ QSharedPointer fullBindingPath(); + Location location() const; + public slots: int fragmentType() const; bool isOfFragmentType(FragmentType type) const; @@ -178,8 +180,6 @@ public slots: void setObjectId(QString id); QString objectId(); - Location location() const; - void writeProperties(const QJSValue& properties); void write(const QJSValue options); void writeCode(const QString& code); From 504b6917de167c83256430c931f84d8046541bb6 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Wed, 2 Jun 2021 21:06:20 +0300 Subject: [PATCH 57/91] editqml: SuggestionModel: Added better separation between categories. --- lib/lveditqmljs/src/qmlsuggestionmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/lveditqmljs/src/qmlsuggestionmodel.cpp b/lib/lveditqmljs/src/qmlsuggestionmodel.cpp index 518625d6..f7f4ee29 100644 --- a/lib/lveditqmljs/src/qmlsuggestionmodel.cpp +++ b/lib/lveditqmljs/src/qmlsuggestionmodel.cpp @@ -167,7 +167,7 @@ void QmlSuggestionModel::addPropertiesAndFunctionsToModel(const QmlInheritanceIn name, QmlSuggestionModel::ItemData::Event) ); - } else if (filter & CodeQmlHandler::ForNode) { + } else if ( method.functionType != QmlFunctionInfo::SlotGenerated && (filter & CodeQmlHandler::ForNode)){ auto name = method.name; addItem(QmlSuggestionModel::ItemData( From ff621361f963782f6e2f5584d57267d2bde2f740 Mon Sep 17 00:00:00 2001 From: nenad-popovic-91 <42581059+nenad-popovic-91@users.noreply.github.com> Date: Tue, 8 Jun 2021 14:22:16 +0200 Subject: [PATCH 58/91] msvc2017 -> msvc2019, fixes for Gallery palettes, refactor lcvcore into Functions and Acts (#219) * Added GalleryFileSelectorPropertiesPalette, minor modifications to original palette * Changed msvc2017 to msvc2019 * Refactor lcvcore and lcvimgproc into Functions and Acts --- appveyor.yml | 4 +- lib/lveditqmljs/src/qmljssettings.cpp | 1 + livekeys.json | 28 +- plugins/lcvcore/lcvcore.pro | 3 + .../palettes/GalleryFileSelectorPalette.qml | 3 +- .../GalleryFileSelectorPropertiesPalette.json | 8 + plugins/lcvcore/qml/ChannelSelect.qml | 11 + plugins/lcvcore/qml/CopyMakeBorder.qml | 16 ++ plugins/lcvcore/qml/live.plugin.json | 3 +- plugins/lcvcore/qml/qmldir | 2 + plugins/lcvcore/src/qmatop.cpp | 55 ++++ plugins/lcvcore/src/qmatop.h | 19 +- plugins/lcvimgproc/lcvimgproc.pro | 12 + plugins/lcvimgproc/qml/Blur.qml | 13 + plugins/lcvimgproc/qml/Canny.qml | 15 + plugins/lcvimgproc/qml/CvtColor.qml | 12 + plugins/lcvimgproc/qml/Dilate.qml | 14 + plugins/lcvimgproc/qml/Erode.qml | 13 + plugins/lcvimgproc/qml/Filter2D.qml | 14 + plugins/lcvimgproc/qml/GaussianBlur.qml | 15 + plugins/lcvimgproc/qml/HoughLines.qml | 16 ++ plugins/lcvimgproc/qml/HoughLinesP.qml | 16 ++ plugins/lcvimgproc/qml/Sobel.qml | 14 + plugins/lcvimgproc/qml/StructuringElement.qml | 14 + plugins/lcvimgproc/qml/plugins.qmltypes | 151 ---------- plugins/lcvimgproc/qml/qmldir | 11 + plugins/lcvimgproc/src/colorspace.cpp | 27 ++ .../src/{qcvtcolor.h => colorspace.h} | 83 +----- plugins/lcvimgproc/src/lcvimgproc.pri | 30 +- plugins/lcvimgproc/src/lcvimgproc_plugin.cpp | 46 ++- plugins/lcvimgproc/src/qblur.cpp | 71 ----- plugins/lcvimgproc/src/qblur.h | 92 ------ plugins/lcvimgproc/src/qcanny.cpp | 50 ---- plugins/lcvimgproc/src/qcanny.h | 108 ------- plugins/lcvimgproc/src/qchannelselect.cpp | 55 ---- plugins/lcvimgproc/src/qchannelselect.h | 58 ---- plugins/lcvimgproc/src/qcopymakeborder.cpp | 65 ----- plugins/lcvimgproc/src/qcopymakeborder.h | 156 ---------- plugins/lcvimgproc/src/qcvtcolor.cpp | 266 ------------------ plugins/lcvimgproc/src/qdilate.cpp | 93 ------ plugins/lcvimgproc/src/qdilate.h | 126 --------- plugins/lcvimgproc/src/qerode.cpp | 95 ------- plugins/lcvimgproc/src/qerode.h | 125 -------- plugins/lcvimgproc/src/qfeaturedetection.cpp | 43 +++ plugins/lcvimgproc/src/qfeaturedetection.h | 21 ++ plugins/lcvimgproc/src/qfilter2d.cpp | 65 ----- plugins/lcvimgproc/src/qfilter2d.h | 130 --------- .../lcvimgproc/src/qfilteringoperations.cpp | 181 ++++++++++++ plugins/lcvimgproc/src/qfilteringoperations.h | 58 ++++ plugins/lcvimgproc/src/qgaussianblur.cpp | 59 ---- plugins/lcvimgproc/src/qgaussianblur.h | 107 ------- plugins/lcvimgproc/src/qhoughlines.cpp | 109 ------- plugins/lcvimgproc/src/qhoughlines.h | 167 ----------- plugins/lcvimgproc/src/qsobel.cpp | 77 ----- plugins/lcvimgproc/src/qsobel.h | 164 ----------- .../lcvimgproc/src/qstructuringelement.cpp | 57 ---- plugins/lcvimgproc/src/qstructuringelement.h | 122 -------- 57 files changed, 681 insertions(+), 2708 deletions(-) create mode 100644 plugins/lcvcore/palettes/GalleryFileSelectorPropertiesPalette.json create mode 100644 plugins/lcvcore/qml/ChannelSelect.qml create mode 100644 plugins/lcvcore/qml/CopyMakeBorder.qml create mode 100644 plugins/lcvimgproc/qml/Blur.qml create mode 100644 plugins/lcvimgproc/qml/Canny.qml create mode 100644 plugins/lcvimgproc/qml/CvtColor.qml create mode 100644 plugins/lcvimgproc/qml/Dilate.qml create mode 100644 plugins/lcvimgproc/qml/Erode.qml create mode 100644 plugins/lcvimgproc/qml/Filter2D.qml create mode 100644 plugins/lcvimgproc/qml/GaussianBlur.qml create mode 100644 plugins/lcvimgproc/qml/HoughLines.qml create mode 100644 plugins/lcvimgproc/qml/HoughLinesP.qml create mode 100644 plugins/lcvimgproc/qml/Sobel.qml create mode 100644 plugins/lcvimgproc/qml/StructuringElement.qml create mode 100644 plugins/lcvimgproc/src/colorspace.cpp rename plugins/lcvimgproc/src/{qcvtcolor.h => colorspace.h} (78%) delete mode 100644 plugins/lcvimgproc/src/qblur.cpp delete mode 100644 plugins/lcvimgproc/src/qblur.h delete mode 100644 plugins/lcvimgproc/src/qcanny.cpp delete mode 100644 plugins/lcvimgproc/src/qcanny.h delete mode 100644 plugins/lcvimgproc/src/qchannelselect.cpp delete mode 100644 plugins/lcvimgproc/src/qchannelselect.h delete mode 100644 plugins/lcvimgproc/src/qcopymakeborder.cpp delete mode 100644 plugins/lcvimgproc/src/qcopymakeborder.h delete mode 100644 plugins/lcvimgproc/src/qcvtcolor.cpp delete mode 100644 plugins/lcvimgproc/src/qdilate.cpp delete mode 100644 plugins/lcvimgproc/src/qdilate.h delete mode 100644 plugins/lcvimgproc/src/qerode.cpp delete mode 100644 plugins/lcvimgproc/src/qerode.h create mode 100644 plugins/lcvimgproc/src/qfeaturedetection.cpp create mode 100644 plugins/lcvimgproc/src/qfeaturedetection.h delete mode 100644 plugins/lcvimgproc/src/qfilter2d.cpp delete mode 100644 plugins/lcvimgproc/src/qfilter2d.h create mode 100644 plugins/lcvimgproc/src/qfilteringoperations.cpp create mode 100644 plugins/lcvimgproc/src/qfilteringoperations.h delete mode 100644 plugins/lcvimgproc/src/qgaussianblur.cpp delete mode 100644 plugins/lcvimgproc/src/qgaussianblur.h delete mode 100644 plugins/lcvimgproc/src/qhoughlines.cpp delete mode 100644 plugins/lcvimgproc/src/qhoughlines.h delete mode 100644 plugins/lcvimgproc/src/qsobel.cpp delete mode 100644 plugins/lcvimgproc/src/qsobel.h delete mode 100644 plugins/lcvimgproc/src/qstructuringelement.cpp delete mode 100644 plugins/lcvimgproc/src/qstructuringelement.h diff --git a/appveyor.yml b/appveyor.yml index ce29c289..35b70890 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -43,8 +43,8 @@ build_script: - npm audit fix - SET LIVEDOC=%APPVEYOR_BUILD_FOLDER%\build\live-doc-master\live-doc.js - cd .. - - python livepm/main.py build .. msvc2017_64 - - python livepm/main.py deploy .. msvc2017_64 + - python livepm/main.py build .. msvc2019_64 + - python livepm/main.py deploy .. msvc2019_64 - dir artifacts: diff --git a/lib/lveditqmljs/src/qmljssettings.cpp b/lib/lveditqmljs/src/qmljssettings.cpp index d7d392ef..3a8df0a6 100644 --- a/lib/lveditqmljs/src/qmljssettings.cpp +++ b/lib/lveditqmljs/src/qmljssettings.cpp @@ -81,6 +81,7 @@ QmlJsSettings::QmlJsSettings(EditorSettings *parent) m_defaultPalettes["qml/lcvphoto#BrightnessAndContrast"] = "BrightnessAndContrastPalette"; m_defaultPalettes["qml/lcvcore#PerspectiveOnBackground"] = "PerspectiveOnBackgroundPropertiesPalette"; m_defaultPalettes["qml/lcvcore#ImageSegmentFactory"] = "ImageSegmentFactoryPropertiesPalette"; + m_defaultPalettes["qml/lcvcore#GalleryFileSelector"] = "GalleryFileSelectorPropertiesPalette"; if (parent){ MLNode s = parent->readFor("qmljs"); diff --git a/livekeys.json b/livekeys.json index 679b8f2f..25c01874 100644 --- a/livekeys.json +++ b/livekeys.json @@ -455,8 +455,8 @@ } ] }, - "msvc2017_64": { - "compiler": "msvc2017_64", + "msvc2019_64": { + "compiler": "msvc2019_64", "environment": { "OPENCV_DIR": "opencv_dir", "QTDIR": "qtdir", @@ -714,51 +714,51 @@ "populate": { "plugins/base/live.package.json": { "release": "win", - "build": "msvc2017" + "build": "msvc2019" }, "plugins/editor/live.package.json": { "release": "win", - "build": "msvc2017" + "build": "msvc2019" }, "plugins/editqml/live.package.json": { "release": "win", - "build": "msvc2017" + "build": "msvc2019" }, "plugins/fs/live.package.json": { "release": "win", - "build": "msvc2017" + "build": "msvc2019" }, "plugins/live/live.package.json": { "release": "win", - "build": "msvc2017" + "build": "msvc2019" }, "plugins/lcvcore/live.package.json": { "release": "win", - "build": "msvc2017" + "build": "msvc2019" }, "plugins/lcvimgproc/live.package.json": { "release": "win", - "build": "msvc2017" + "build": "msvc2019" }, "plugins/lcvvideo/live.package.json": { "release": "win", - "build": "msvc2017" + "build": "msvc2019" }, "plugins/lcvfeatures2d/live.package.json": { "release": "win", - "build": "msvc2017" + "build": "msvc2019" }, "plugins/lcvphoto/live.package.json": { "release": "win", - "build": "msvc2017" + "build": "msvc2019" }, "plugins/timeline/live.package.json": { "release": "win", - "build": "msvc2017" + "build": "msvc2019" }, "plugins/workspace/live.package.json": { "release": "win", - "build": "msvc2017" + "build": "msvc2019" } } }, diff --git a/plugins/lcvcore/lcvcore.pro b/plugins/lcvcore/lcvcore.pro index 6a489f50..60e28a4f 100644 --- a/plugins/lcvcore/lcvcore.pro +++ b/plugins/lcvcore/lcvcore.pro @@ -62,6 +62,7 @@ QMAKE_EXTRA_TARGETS += first palettecopy samplescopy DISTFILES += \ palettes/DrawPalette.qml \ palettes/GalleryFileSelectorPalette.qml \ + palettes/GalleryFileSelectorPropertiesPalette.json \ palettes/GrayscaleViewPalette.json \ palettes/ImageFilePalette.json \ palettes/ImageReadPalette.json \ @@ -82,7 +83,9 @@ DISTFILES += \ palettes/VideoSurfacePropertiesPalette.json \ qml/BlankImage.qml \ qml/BrushTool.qml \ + qml/ChannelSelect.qml \ qml/ColorHistogramView.qml \ + qml/CopyMakeBorder.qml \ qml/Crop.qml \ qml/CropTool.qml \ qml/DrawSurface.qml \ diff --git a/plugins/lcvcore/palettes/GalleryFileSelectorPalette.qml b/plugins/lcvcore/palettes/GalleryFileSelectorPalette.qml index 839fb4f7..50076168 100644 --- a/plugins/lcvcore/palettes/GalleryFileSelectorPalette.qml +++ b/plugins/lcvcore/palettes/GalleryFileSelectorPalette.qml @@ -143,9 +143,10 @@ CodePalette{ } highlight: Rectangle { - color: "#66cccccc" + color: palette.theme.colorScheme.middlegroundOverlayDominant } highlightFollowsCurrentItem: true + highlightMoveDuration: 0 focus: true clip: true diff --git a/plugins/lcvcore/palettes/GalleryFileSelectorPropertiesPalette.json b/plugins/lcvcore/palettes/GalleryFileSelectorPropertiesPalette.json new file mode 100644 index 00000000..27afe68a --- /dev/null +++ b/plugins/lcvcore/palettes/GalleryFileSelectorPropertiesPalette.json @@ -0,0 +1,8 @@ +{ + "type": "qml/lcvcore#GalleryFileSelector", + "palettes": ["GalleryFileSelectorPalette"], + "properties" : [ + ["workingDirectory", "FolderPathPalette"], + ["selectedFile", "", "true"] + ] +} diff --git a/plugins/lcvcore/qml/ChannelSelect.qml b/plugins/lcvcore/qml/ChannelSelect.qml new file mode 100644 index 00000000..01d98b4e --- /dev/null +++ b/plugins/lcvcore/qml/ChannelSelect.qml @@ -0,0 +1,11 @@ +import QtQuick 2.3 +import base 1.0 +import lcvcore 1.0 as Cv + +Act{ + property Cv.Mat input: null + property int channel: 0 + + run: Cv.MatOp.selectChannel + args: ["$input", "$channel"] +} diff --git a/plugins/lcvcore/qml/CopyMakeBorder.qml b/plugins/lcvcore/qml/CopyMakeBorder.qml new file mode 100644 index 00000000..d0e0183e --- /dev/null +++ b/plugins/lcvcore/qml/CopyMakeBorder.qml @@ -0,0 +1,16 @@ +import QtQuick 2.3 +import base 1.0 +import lcvcore 1.0 as Cv + +Act{ + property Cv.Mat input: null + property int top: 0 + property int bottom: 0 + property int left: 0 + property int right: 0 + property int borderType: Cv.MatOp.BORDER_DEFAULT + property color color: "white" + + run: Cv.MatOp.copyMakeBorder + args: ["$input", "$top", "$bottom", "$left", "$right", "$borderType", "$color"] +} diff --git a/plugins/lcvcore/qml/live.plugin.json b/plugins/lcvcore/qml/live.plugin.json index c3ef7556..97bcf732 100644 --- a/plugins/lcvcore/qml/live.plugin.json +++ b/plugins/lcvcore/qml/live.plugin.json @@ -22,6 +22,7 @@ "palettes/PerspectiveOnBackgroundPropertiesPalette.json": "qml/lcvcore#PerspectiveOnBackground", "palettes/ImageSegmentFactoryPalette.qml": "qml/lcvcore#ImageSegmentFactory", "palettes/ImageSegmentFactoryPropertiesPalette.json": "qml/lcvcore#ImageSegmentFactory", - "palettes/GalleryFileSelectorPalette.qml": "qml/lcvcore#GalleryFileSelector" + "palettes/GalleryFileSelectorPalette.qml": "qml/lcvcore#GalleryFileSelector", + "palettes/GalleryFileSelectorPropertiesPalette.json": "qml/lcvcore#GalleryFileSelector" } } diff --git a/plugins/lcvcore/qml/qmldir b/plugins/lcvcore/qml/qmldir index 168f1afc..dad2e04a 100644 --- a/plugins/lcvcore/qml/qmldir +++ b/plugins/lcvcore/qml/qmldir @@ -28,3 +28,5 @@ Perspective 1.0 Perspective.qml PaperSurface 1.0 PaperSurface.qml PerspectiveOnBackground 1.0 PerspectiveOnBackground.qml GalleryFileSelector 1.0 GalleryFileSelector.qml +ChannelSelect 1.0 ChannelSelect.qml +CopyMakeBorder 1.0 CopyMakeBorder.qml diff --git a/plugins/lcvcore/src/qmatop.cpp b/plugins/lcvcore/src/qmatop.cpp index 6a36025f..13071e09 100644 --- a/plugins/lcvcore/src/qmatop.cpp +++ b/plugins/lcvcore/src/qmatop.cpp @@ -457,6 +457,61 @@ QMat *QMatOp::bitwiseNot(QMat *arg) return result; } +QMat *QMatOp::selectChannel(QMat *input, int channel) +{ + if ( !input || input->internal().empty()) + return nullptr; + + try{ + cv::Mat* rMat = new cv::Mat( + input->dimensions().height(), + input->dimensions().width(), + CV_MAKETYPE(CV_8UC1, 1)); + + + if ( input->channels() == 1 ){ + input->internal().copyTo(*rMat); + return new QMat(rMat); + } else if ( input->channels() == 3 ){ + std::vector channels; + cv::split(input->internal(), channels); + channels[channel].copyTo(*rMat); + } + + return new QMat(rMat); + + } catch (cv::Exception& e){ + lv::CvExtras::toLocalError(e, lv::ViewContext::instance().engine(), this, "MatOp: ").jsThrow(); + return nullptr; + } +} + +QMat *QMatOp::copyMakeBorder(QMat *input, int top, int bottom, int left, int right, int borderType, const QColor& color) +{ + if ( !input || input->internal().empty() ) + return nullptr; + + try{ + cv::Mat* rMat = new cv::Mat( + input->dimensions().height(), + input->dimensions().width(), + CV_MAKETYPE(input->depth(), input->channels())); + cv::Scalar value; + if ( color.isValid() ){ + if ( rMat->channels() == 1 ) + value = color.red(); + else if ( rMat->channels() == 3 ) + value = cv::Scalar(color.blue(), color.green(), color.red()); + } + cv::copyMakeBorder(input->internal(), *rMat, top, bottom, left, right, borderType, value); + return new QMat(rMat); + + } catch (cv::Exception& e){ + lv::CvExtras::toLocalError(e, lv::ViewContext::instance().engine(), this, "MatOp: ").jsThrow(); + return nullptr; + } +} + lv::ViewEngine *QMatOp::engine(){ return lv::ViewContext::instance().engine(); } diff --git a/plugins/lcvcore/src/qmatop.h b/plugins/lcvcore/src/qmatop.h index 69a38441..ef474526 100644 --- a/plugins/lcvcore/src/qmatop.h +++ b/plugins/lcvcore/src/qmatop.h @@ -14,8 +14,21 @@ class QMatOp : public QObject{ Q_OBJECT Q_PROPERTY(QMat* nullMat READ nullMat CONSTANT) - + Q_ENUMS(BorderType) public: + enum BorderType { + BORDER_CONSTANT = cv::BORDER_CONSTANT, + BORDER_REPLICATE = cv::BORDER_REPLICATE, + BORDER_REFLECT = cv::BORDER_REFLECT, + BORDER_WRAP = cv::BORDER_WRAP, + BORDER_REFLECT_101 = cv::BORDER_REFLECT_101, + BORDER_TRANSPARENT = cv::BORDER_TRANSPARENT, + + BORDER_REFLECT101 = BORDER_REFLECT_101, + BORDER_DEFAULT = BORDER_REFLECT_101, + BORDER_ISOLATED = cv::BORDER_ISOLATED + }; + explicit QMatOp(QObject *parent = nullptr); static cv::Scalar toScalar(const QColor& color); @@ -66,6 +79,10 @@ public slots: QMat* bitwiseAnd(QMat* arg1, QMat* arg2); QMat* bitwiseNot(QMat* arg); + QMat* selectChannel(QMat* input, int channel); + QMat* copyMakeBorder(QMat* input, + int top, int bottom, int left, int right, + int borderType = BORDER_DEFAULT, const QColor& color = QColor()); private: lv::ViewEngine* engine(); }; diff --git a/plugins/lcvimgproc/lcvimgproc.pro b/plugins/lcvimgproc/lcvimgproc.pro index cddce9f8..43e4b164 100644 --- a/plugins/lcvimgproc/lcvimgproc.pro +++ b/plugins/lcvimgproc/lcvimgproc.pro @@ -53,8 +53,18 @@ OTHER_FILES *= \ DISTFILES += \ qml/Blend.qml \ + qml/Blur.qml \ + qml/Canny.qml \ + qml/ChannelSelect.qml \ + qml/CvtColor.qml \ + qml/Dilate.qml \ qml/DrawDetectedFaces.qml \ + qml/Erode.qml \ qml/FaceDetection.qml \ + qml/Filter2D.qml \ + qml/GaussianBlur.qml \ + qml/HoughLines.qml \ + qml/HoughLinesP.qml \ qml/Pad.qml \ qml/Resize.qml \ qml/ResizeTool.qml \ @@ -62,6 +72,8 @@ DISTFILES += \ qml/Rotate.qml \ qml/RotateTool.qml \ qml/Scale.qml \ + qml/Sobel.qml \ + qml/StructuringElement.qml \ qml/Threshold.qml \ qml/live.package.json \ qml/live.plugin.json \ diff --git a/plugins/lcvimgproc/qml/Blur.qml b/plugins/lcvimgproc/qml/Blur.qml new file mode 100644 index 00000000..cc8dee20 --- /dev/null +++ b/plugins/lcvimgproc/qml/Blur.qml @@ -0,0 +1,13 @@ +import QtQuick 2.3 +import lcvcore 1.0 +import base 1.0 +import lcvimgproc 1.0 as Img + +Act{ + property Mat input: null + property size size: "0x0" + property var anchor: Qt.point(0, 0) + + run: Img.FilteringOperations.blur + args: ["$input", "$size", "$anchor"] +} diff --git a/plugins/lcvimgproc/qml/Canny.qml b/plugins/lcvimgproc/qml/Canny.qml new file mode 100644 index 00000000..04e5a6f1 --- /dev/null +++ b/plugins/lcvimgproc/qml/Canny.qml @@ -0,0 +1,15 @@ +import QtQuick 2.3 +import lcvcore 1.0 +import base 1.0 +import lcvimgproc 1.0 as Img + +Act{ + property Mat input: null + property double threshold1: 0 + property double threshold2: 1 + property int apertureSize: 3 + property bool l2gradient: false + + run: Img.FilteringOperations.canny + args: ["$input", "$threshold1", "$threshold2", "$apertureSize", "$l2gradient"] +} diff --git a/plugins/lcvimgproc/qml/CvtColor.qml b/plugins/lcvimgproc/qml/CvtColor.qml new file mode 100644 index 00000000..783d0203 --- /dev/null +++ b/plugins/lcvimgproc/qml/CvtColor.qml @@ -0,0 +1,12 @@ +import QtQuick 2.3 +import lcvcore 1.0 +import base 1.0 +import lcvimgproc 1.0 as Img + +Act{ + property Mat input: null + property int code: 0 + property int dstCn: 0 + run: Img.ColorSpace.cvtColor + args: ["$input", "$code", "$dstCn"] +} diff --git a/plugins/lcvimgproc/qml/Dilate.qml b/plugins/lcvimgproc/qml/Dilate.qml new file mode 100644 index 00000000..df4e2c7a --- /dev/null +++ b/plugins/lcvimgproc/qml/Dilate.qml @@ -0,0 +1,14 @@ +import QtQuick 2.3 +import lcvcore 1.0 +import base 1.0 +import lcvimgproc 1.0 as Img + +Act{ + property Mat input: null + property Mat kernel: null + property var anchor: Qt.point(0, 0) + property int iterations: 0 + + run: Img.FilteringOperations.dilate + args: ["$input", "$kernel", "$anchor", "$iterations"] +} diff --git a/plugins/lcvimgproc/qml/Erode.qml b/plugins/lcvimgproc/qml/Erode.qml new file mode 100644 index 00000000..bdfdd786 --- /dev/null +++ b/plugins/lcvimgproc/qml/Erode.qml @@ -0,0 +1,13 @@ +import QtQuick 2.3 +import lcvcore 1.0 +import base 1.0 +import lcvimgproc 1.0 as Img + +Act{ + property Mat input: null + property Mat kernel: null + property var anchor: Qt.point(0, 0) + property int iterations: 0 + run: Img.FilteringOperations.erode + args: ["$input", "$kernel", "$anchor", "$iterations"] +} diff --git a/plugins/lcvimgproc/qml/Filter2D.qml b/plugins/lcvimgproc/qml/Filter2D.qml new file mode 100644 index 00000000..6b0e67d6 --- /dev/null +++ b/plugins/lcvimgproc/qml/Filter2D.qml @@ -0,0 +1,14 @@ +import QtQuick 2.3 +import lcvcore 1.0 +import base 1.0 +import lcvimgproc 1.0 as Img + +Act{ + property Mat input: null + property int ddepth: 0 + property Mat kernel: null + property point anchor: Qt.point(0, 0) + + run: Img.FilteringOperations.filter2D + args: ["$input", "$ddepth", "$kernel", "$anchor"] +} diff --git a/plugins/lcvimgproc/qml/GaussianBlur.qml b/plugins/lcvimgproc/qml/GaussianBlur.qml new file mode 100644 index 00000000..b862950e --- /dev/null +++ b/plugins/lcvimgproc/qml/GaussianBlur.qml @@ -0,0 +1,15 @@ +import QtQuick 2.3 +import lcvcore 1.0 +import base 1.0 +import lcvimgproc 1.0 as Img + +Act{ + property Mat input: null + property size size: "0x0" + property double sigmaX: 0.0 + property double sigmaY: 0.0 + property int borderType: Img.FilteringOperations.BORDER_DEFAULT + + run: Img.FilteringOperations.gaussianBlur + args: ["$input", "$size", "$sigmaX", "$sigmaY", "$borderType"] +} diff --git a/plugins/lcvimgproc/qml/HoughLines.qml b/plugins/lcvimgproc/qml/HoughLines.qml new file mode 100644 index 00000000..4de8f935 --- /dev/null +++ b/plugins/lcvimgproc/qml/HoughLines.qml @@ -0,0 +1,16 @@ +import QtQuick 2.3 +import lcvcore 1.0 +import base 1.0 +import lcvimgproc 1.0 as Img + +Act{ + property Mat input: null + property double rho: 0.0 + property double theta: 0.0 + property int threshold: 0 + property double srn: 0.0 + property double stn: 0.0 + + run: Img.FeatureDetection.houghLines + args: ["$input", "$rho", "$theta", "$threshold", "$srn", "$stn"] +} diff --git a/plugins/lcvimgproc/qml/HoughLinesP.qml b/plugins/lcvimgproc/qml/HoughLinesP.qml new file mode 100644 index 00000000..22a5340f --- /dev/null +++ b/plugins/lcvimgproc/qml/HoughLinesP.qml @@ -0,0 +1,16 @@ +import QtQuick 2.3 +import lcvcore 1.0 +import base 1.0 +import lcvimgproc 1.0 as Img + +Act{ + property Mat input: null + property double rho: 0.0 + property double theta: 0.0 + property int threshold: 0 + property double minLineLength: 0.0 + property double maxLineGap: 0.0 + + run: Img.FeatureDetection.houghLinesP + args: ["$input", "$rho", "$theta", "$threshold", "$minLineLength", "$maxLineGap"] +} diff --git a/plugins/lcvimgproc/qml/Sobel.qml b/plugins/lcvimgproc/qml/Sobel.qml new file mode 100644 index 00000000..ffa98edb --- /dev/null +++ b/plugins/lcvimgproc/qml/Sobel.qml @@ -0,0 +1,14 @@ +import QtQuick 2.3 +import lcvcore 1.0 +import base 1.0 +import lcvimgproc 1.0 as Img + +Act{ + property Mat input: null + property int ddepth: 0 + property int xOrder: 0.0 + property int yOrder: 0.0 + + run: Img.FilteringOperations.sobel + args: ["$input", "$ddepth", "$xOrder", "$yOrder"] +} diff --git a/plugins/lcvimgproc/qml/StructuringElement.qml b/plugins/lcvimgproc/qml/StructuringElement.qml new file mode 100644 index 00000000..13be8487 --- /dev/null +++ b/plugins/lcvimgproc/qml/StructuringElement.qml @@ -0,0 +1,14 @@ +import QtQuick 2.3 +import lcvcore 1.0 +import base 1.0 +import lcvimgproc 1.0 as Img + +Act{ + property int shape: Img.FilteringOperations.MORPH_ELLIPSE + property size size: "11x11" + property point anchor: Qt.point(3, 5) + + run: Img.FilteringOperations.getStructuringElement + args: ["$shape", "$size", "$anchor"] + onComplete: exec() +} diff --git a/plugins/lcvimgproc/qml/plugins.qmltypes b/plugins/lcvimgproc/qml/plugins.qmltypes index 81ccc95d..0ad689b3 100644 --- a/plugins/lcvimgproc/qml/plugins.qmltypes +++ b/plugins/lcvimgproc/qml/plugins.qmltypes @@ -8,31 +8,6 @@ import QtQuick.tooling 1.2 Module { dependencies: [] - Component { - name: "QBlur" - defaultProperty: "data" - prototype: "QMatFilter" - exports: ["lcvimgproc/Blur 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "ksize"; type: "QSize" } - Property { name: "anchor"; type: "QPoint" } - Property { name: "borderType"; type: "int" } - Method { name: "ksize" } - Method { - name: "setKsize" - Parameter { name: "ksize"; type: "QSize" } - } - Method { name: "anchor" } - Method { - name: "setAnchor" - Parameter { name: "anchor"; type: "QPoint" } - } - Method { name: "borderType"; type: "int" } - Method { - name: "setBorderType" - Parameter { name: "borderType"; type: "int" } - } - } Component { name: "QCachedWarpPerspective" defaultProperty: "data" @@ -44,51 +19,6 @@ Module { Property { name: "m"; type: "QMat"; isPointer: true } Property { name: "interpolation"; type: "int" } } - Component { - name: "QCanny" - defaultProperty: "data" - prototype: "QMatFilter" - exports: ["lcvimgproc/Canny 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "threshold1"; type: "double" } - Property { name: "threshold2"; type: "double" } - Property { name: "apertureSize"; type: "int" } - Property { name: "l2gradient"; type: "bool" } - } - Component { - name: "QChannelSelect" - defaultProperty: "data" - prototype: "QMatFilter" - exports: ["lcvimgproc/ChannelSelect 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "channel"; type: "int" } - } - Component { - name: "QCopyMakeBorder" - defaultProperty: "data" - prototype: "QMatFilter" - exports: ["lcvimgproc/CopyMakeBorder 1.0"] - exportMetaObjectRevisions: [0] - Enum { - name: "BorderType" - values: { - "BORDER_REPLICATE": 1, - "BORDER_CONSTANT": 0, - "BORDER_REFLECT": 2, - "BORDER_WRAP": 3, - "BORDER_REFLECT_101": 4, - "BORDER_TRANSPARENT": 5, - "BORDER_DEFAULT": 4, - "BORDER_ISOLATED": 16 - } - } - Property { name: "top"; type: "int" } - Property { name: "bottom"; type: "int" } - Property { name: "left"; type: "int" } - Property { name: "right"; type: "int" } - Property { name: "borderType"; type: "int" } - Property { name: "color"; type: "QColor" } - } Component { name: "QCvtColor" defaultProperty: "data" @@ -281,18 +211,6 @@ Module { Property { name: "code"; type: "CvtType" } Property { name: "dstCn"; type: "int" } } - Component { - name: "QDilate" - defaultProperty: "data" - prototype: "QMatFilter" - exports: ["lcvimgproc/Dilate 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "kernel"; type: "QMat"; isPointer: true } - Property { name: "anchor"; type: "QPoint" } - Property { name: "iterations"; type: "int" } - Property { name: "borderType"; type: "int" } - Property { name: "borderValue"; type: "QColor" } - } Component { name: "QDraw" prototype: "QObject" @@ -477,41 +395,6 @@ Module { Parameter { name: "color"; type: "QColor" } } } - Component { - name: "QErode" - defaultProperty: "data" - prototype: "QMatFilter" - exports: ["lcvimgproc/Erode 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "kernel"; type: "QMat"; isPointer: true } - Property { name: "anchor"; type: "QPoint" } - Property { name: "iterations"; type: "int" } - Property { name: "borderType"; type: "int" } - Property { name: "borderValue"; type: "QColor" } - } - Component { - name: "QFilter2D" - defaultProperty: "data" - prototype: "QMatFilter" - exports: ["lcvimgproc/Filter2D 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "ddepth"; type: "int" } - Property { name: "kernel"; type: "QMat"; isPointer: true } - Property { name: "anchor"; type: "QPoint" } - Property { name: "delta"; type: "double" } - Property { name: "borderType"; type: "int" } - } - Component { - name: "QGaussianBlur" - defaultProperty: "data" - prototype: "QMatFilter" - exports: ["lcvimgproc/GaussianBlur 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "ksize"; type: "QSize" } - Property { name: "sigmaX"; type: "double" } - Property { name: "sigmaY"; type: "double" } - Property { name: "borderType"; type: "int" } - } Component { name: "QGeometry" prototype: "QObject" @@ -690,40 +573,6 @@ Module { Parameter { name: "depth"; type: "int" } } } - Component { - name: "QSobel" - defaultProperty: "data" - prototype: "QMatFilter" - exports: ["lcvimgproc/Sobel 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "ddepth"; type: "QMat::Type" } - Property { name: "xorder"; type: "int" } - Property { name: "yorder"; type: "int" } - Property { name: "ksize"; type: "int" } - Property { name: "scale"; type: "double" } - Property { name: "delta"; type: "double" } - Property { name: "borderType"; type: "int" } - Signal { name: "scaleChagned" } - } - Component { - name: "QStructuringElement" - defaultProperty: "data" - prototype: "QQuickItem" - exports: ["lcvimgproc/StructuringElement 1.0"] - exportMetaObjectRevisions: [0] - Enum { - name: "ElementShape" - values: { - "MORPH_RECT": 0, - "MORPH_ELLIPSE": 2, - "MORPH_CROSS": 1 - } - } - Property { name: "shape"; type: "ElementShape" } - Property { name: "ksize"; type: "QSize" } - Property { name: "anchor"; type: "QPoint" } - Property { name: "output"; type: "QMat"; isPointer: true } - } Component { name: "QWarpPerspective" defaultProperty: "data" diff --git a/plugins/lcvimgproc/qml/qmldir b/plugins/lcvimgproc/qml/qmldir index 4fe448f5..b0c0c457 100644 --- a/plugins/lcvimgproc/qml/qmldir +++ b/plugins/lcvimgproc/qml/qmldir @@ -16,3 +16,14 @@ Blend 1.0 Blend.qml FaceDetection 1.0 FaceDetection.qml DrawDetectedFaces 1.0 DrawDetectedFaces.qml Pad 1.0 Pad.qml +Blur 1.0 Blur.qml +Canny 1.0 Canny.qml +Dilate 1.0 Dilate.qml +Erode 1.0 Erode.qml +Filter2D 1.0 Filter2D.qml +GaussianBlur 1.0 GaussianBlur.qml +Sobel 1.0 Sobel.qml +StructuringElement 1.0 StructuringElement.qml +CvtColor 1.0 CvtColor.qml +HoughLines 1.0 HoughLines.qml +HoughLinesP 1.0 HoughLinesP.qml diff --git a/plugins/lcvimgproc/src/colorspace.cpp b/plugins/lcvimgproc/src/colorspace.cpp new file mode 100644 index 00000000..ff8cceab --- /dev/null +++ b/plugins/lcvimgproc/src/colorspace.cpp @@ -0,0 +1,27 @@ +#include "colorspace.h" +#include "cvextras.h" +#include "live/viewcontext.h" +#include "live/visuallogqt.h" + +ColorSpace::ColorSpace(QObject *parent) + : QObject(parent) +{ + +} + +QMat *ColorSpace::cvtColor(QMat *input, int code, int dstCn) +{ + if (!input || input->internal().empty()) return nullptr; + try{ + cv::Mat* rMat = new cv::Mat( + input->dimensions().height(), + input->dimensions().width(), + CV_MAKETYPE(input->depth(), input->channels())); + cv::cvtColor(input->internal(), *rMat, code, dstCn); + return new QMat(rMat); + + } catch (cv::Exception& e){ + lv::CvExtras::toLocalError(e, lv::ViewContext::instance().engine(), this, "ColorSpace: ").jsThrow(); + return nullptr; + } +} diff --git a/plugins/lcvimgproc/src/qcvtcolor.h b/plugins/lcvimgproc/src/colorspace.h similarity index 78% rename from plugins/lcvimgproc/src/qcvtcolor.h rename to plugins/lcvimgproc/src/colorspace.h index b3207df1..3ba3daaf 100644 --- a/plugins/lcvimgproc/src/qcvtcolor.h +++ b/plugins/lcvimgproc/src/colorspace.h @@ -1,32 +1,14 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ - -#ifndef QCVTCOLOR_H -#define QCVTCOLOR_H - -#include "qmatfilter.h" - -class QCvtColor : public QMatFilter{ +#ifndef COLORSPACE_H +#define COLORSPACE_H - Q_OBJECT - Q_PROPERTY(CvtType code READ code WRITE setCode NOTIFY codeChanged) - Q_PROPERTY(int dstCn READ dstCn WRITE setDstCn NOTIFY dstCnChanged) +#include +#include "qmat.h" +#include "opencv2/imgproc.hpp" +class ColorSpace: public QObject +{ + Q_OBJECT Q_ENUMS(CvtType) - public: enum CvtType{ CV_BGR2BGRA =0, @@ -255,50 +237,9 @@ class QCvtColor : public QMatFilter{ CV_COLORCVT_MAX = 127 }; - -public: - explicit QCvtColor(QQuickItem *parent = 0); - - virtual void transform(const cv::Mat &in, cv::Mat&); - - CvtType code() const; - void setCode(CvtType arg); - - int dstCn() const; - void setDstCn(int arg); - - -signals: - void codeChanged(); - void dstCnChanged(); - -private: - CvtType m_code; - int m_dstCn; + ColorSpace(QObject* parent = nullptr); +public slots: + QMat* cvtColor(QMat* input, int code, int dstCn); }; -inline QCvtColor::CvtType QCvtColor::code() const{ - return m_code; -} - -inline void QCvtColor::setCode(QCvtColor::CvtType arg){ - if (m_code != arg) { - m_code = arg; - emit codeChanged(); - QMatFilter::transform(); - } -} - -inline int QCvtColor::dstCn() const{ - return m_dstCn; -} - -inline void QCvtColor::setDstCn(int arg){ - if (m_dstCn != arg) { - m_dstCn = arg; - emit dstCnChanged(); - QMatFilter::transform(); - } -} - -#endif // QCVTCOLOR_H +#endif // COLORSPACE_H diff --git a/plugins/lcvimgproc/src/lcvimgproc.pri b/plugins/lcvimgproc/src/lcvimgproc.pri index a54dc862..69d6a6b6 100644 --- a/plugins/lcvimgproc/src/lcvimgproc.pri +++ b/plugins/lcvimgproc/src/lcvimgproc.pri @@ -1,19 +1,10 @@ HEADERS += \ - $$PWD/qblur.h \ - $$PWD/qcanny.h \ + $$PWD/colorspace.h \ $$PWD/qcascadeclassifier.h \ - $$PWD/qchannelselect.h \ - $$PWD/qcopymakeborder.h \ - $$PWD/qcvtcolor.h \ - $$PWD/qdilate.h \ - $$PWD/qerode.h \ - $$PWD/qfilter2d.h \ - $$PWD/qgaussianblur.h \ - $$PWD/qhoughlines.h \ + $$PWD/qfeaturedetection.h \ + $$PWD/qfilteringoperations.h \ $$PWD/qhoughlinesp.h \ $$PWD/qshapedescriptors.h \ - $$PWD/qsobel.h \ - $$PWD/qstructuringelement.h \ $$PWD/lcvimgproc_plugin.h \ $$PWD/qtransformations.h \ $$PWD/qtransformimage.h \ @@ -23,22 +14,13 @@ HEADERS += \ # $$PWD/qbilateralfilter.h SOURCES += \ + $$PWD/colorspace.cpp \ $$PWD/lcvimgproc_plugin.cpp \ - $$PWD/qblur.cpp \ - $$PWD/qcanny.cpp \ $$PWD/qcascadeclassifier.cpp \ - $$PWD/qchannelselect.cpp \ - $$PWD/qcopymakeborder.cpp \ - $$PWD/qcvtcolor.cpp \ - $$PWD/qdilate.cpp \ - $$PWD/qerode.cpp \ - $$PWD/qfilter2d.cpp \ - $$PWD/qgaussianblur.cpp \ - $$PWD/qhoughlines.cpp \ + $$PWD/qfeaturedetection.cpp \ + $$PWD/qfilteringoperations.cpp \ $$PWD/qhoughlinesp.cpp \ $$PWD/qshapedescriptors.cpp \ - $$PWD/qsobel.cpp \ - $$PWD/qstructuringelement.cpp \ $$PWD/qtransformations.cpp \ $$PWD/qtransformimage.cpp \ $$PWD/qcachedwarpperspective.cpp \ diff --git a/plugins/lcvimgproc/src/lcvimgproc_plugin.cpp b/plugins/lcvimgproc/src/lcvimgproc_plugin.cpp index 2b5d73d8..f0f6561f 100644 --- a/plugins/lcvimgproc/src/lcvimgproc_plugin.cpp +++ b/plugins/lcvimgproc/src/lcvimgproc_plugin.cpp @@ -17,19 +17,6 @@ #include "lcvimgproc_plugin.h" #include -#include "qblur.h" -#include "qcanny.h" -#include "qgaussianblur.h" -#include "qhoughlines.h" -#include "qhoughlinesp.h" -#include "qsobel.h" -#include "qcvtcolor.h" -#include "qfilter2d.h" -#include "qchannelselect.h" -#include "qstructuringelement.h" -#include "qdilate.h" -#include "qerode.h" -#include "qcopymakeborder.h" #include "qdraw.h" #include "qcachedwarpperspective.h" #include "qgeometry.h" @@ -37,6 +24,9 @@ #include "qtransformimage.h" #include "qtransformations.h" #include "qcascadeclassifier.h" +#include "qfilteringoperations.h" +#include "colorspace.h" +#include "qfeaturedetection.h" #include @@ -55,21 +45,20 @@ static QObject* transformationsProvider(QQmlEngine *engine, QJSEngine *){ return new QTransformations(engine); } +static QObject* filteringOperationsProvider(QQmlEngine *engine, QJSEngine *){ + return new QFilteringOperations(engine); +} + +static QObject* colorSpaceProvider(QQmlEngine *engine, QJSEngine *){ + return new ColorSpace(engine); +} + +static QObject* featureDetectionProvider(QQmlEngine *engine, QJSEngine *){ + return new QFeatureDetection(engine); +} + void LcvimgprocPlugin::registerTypes(const char *uri){ // @uri modules.lcvimgproc - qmlRegisterType( uri, 1, 0, "Blur"); - qmlRegisterType( uri, 1, 0, "Canny"); - qmlRegisterType( uri, 1, 0, "GaussianBlur"); - qmlRegisterType( uri, 1, 0, "HoughLines"); - qmlRegisterType( uri, 1, 0, "HoughLinesP"); - qmlRegisterType( uri, 1, 0, "Sobel"); - qmlRegisterType( uri, 1, 0, "CvtColor"); - qmlRegisterType( uri, 1, 0, "ChannelSelect"); - qmlRegisterType( uri, 1, 0, "StructuringElement"); - qmlRegisterType( uri, 1, 0, "Filter2D"); - qmlRegisterType( uri, 1, 0, "Dilate"); - qmlRegisterType( uri, 1, 0, "Erode"); - qmlRegisterType( uri, 1, 0, "CopyMakeBorder"); qmlRegisterType( uri, 1, 0, "CachedWarpPerspective"); qmlRegisterType( uri, 1, 0, "TransformImage"); qmlRegisterType( uri, 1, 0, "CascadeClassifier"); @@ -79,6 +68,11 @@ void LcvimgprocPlugin::registerTypes(const char *uri){ qmlRegisterSingletonType( uri, 1, 0, "ShapeDescriptors", &shapeDescriptorsProvider); qmlRegisterSingletonType(uri, 1, 0, "Transformations", &transformationsProvider); + qmlRegisterSingletonType( uri, 1, 0, "FilteringOperations", + &filteringOperationsProvider); + qmlRegisterSingletonType( uri, 1, 0, "ColorSpace", &colorSpaceProvider); + qmlRegisterSingletonType( uri, 1, 0, "FeatureDetection", &featureDetectionProvider); + } diff --git a/plugins/lcvimgproc/src/qblur.cpp b/plugins/lcvimgproc/src/qblur.cpp deleted file mode 100644 index bbae6bb7..00000000 --- a/plugins/lcvimgproc/src/qblur.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ -#include "qblur.h" -#include "opencv2/imgproc.hpp" - -using namespace cv; - -/*! - \class QBlur - \internal - \inmodule lcvimgproc_cpp - \brief Box image blur. - */ - -/*! - \brief QBlur constructor - - Parameters : - \a parent - */ -QBlur::QBlur(QQuickItem *parent) - : QMatFilter(parent) - , m_borderType(BORDER_DEFAULT) - , m_anchor(QPoint(-1, -1)) -{ -} - -/*! - \brief QBlur destructor - */ -QBlur::~QBlur(){ -} - -/*! - \property QBlur::ksize - \sa Blur::ksize - */ - -/*! - \property QBlur::anchor - \sa Blur::anchor - */ - -/*! - \property QBlur::borderType - \sa Blur::borderType - */ - -/*! - \brief Transformation function - - Parameters : - \a in - \a out - */ -void QBlur::transform(const cv::Mat &in, cv::Mat &out){ - blur(in, out, Size(m_ksize.width(), m_ksize.height()), Point(m_anchor.x(), m_anchor.y()), m_borderType); -} diff --git a/plugins/lcvimgproc/src/qblur.h b/plugins/lcvimgproc/src/qblur.h deleted file mode 100644 index d98022c2..00000000 --- a/plugins/lcvimgproc/src/qblur.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ - -#ifndef QBLUR_H -#define QBLUR_H - -#include -#include "qmatfilter.h" - -class QBlur : public QMatFilter{ - - Q_OBJECT - Q_PROPERTY(QSize ksize READ ksize WRITE setKsize NOTIFY ksizeChanged) - Q_PROPERTY(QPoint anchor READ anchor WRITE setAnchor NOTIFY anchorChanged) - Q_PROPERTY(int borderType READ borderType WRITE setBorderType NOTIFY borderTypeChanged) - -public: - explicit QBlur(QQuickItem *parent = 0); - ~QBlur(); - - virtual void transform(const cv::Mat &in, cv::Mat &out); - -signals: - void ksizeChanged(); - void anchorChanged(); - void borderTypeChanged(); - -public slots: - const QSize& ksize() const; - void setKsize(const QSize& ksize); - - const QPoint& anchor() const; - void setAnchor(const QPoint& anchor); - - int borderType() const; - void setBorderType(int borderType); - -private: - int m_borderType; - QSize m_ksize; - QPoint m_anchor; - -}; - -inline int QBlur::borderType() const{ - return m_borderType; -} - -inline void QBlur::setBorderType(int borderType){ - if (m_borderType != borderType){ - m_borderType = borderType; - emit borderTypeChanged(); - } -} - -inline const QPoint& QBlur::anchor() const{ - return m_anchor; -} - -inline void QBlur::setAnchor(const QPoint& anchor){ - if (m_anchor != anchor){ - m_anchor = anchor; - emit anchorChanged(); - } -} - -inline const QSize& QBlur::ksize() const{ - return m_ksize; -} - -inline void QBlur::setKsize(const QSize& ksize){ - if (m_ksize != ksize){ - m_ksize = ksize; - emit ksizeChanged(); - } -} - - -#endif // QBLUR_H diff --git a/plugins/lcvimgproc/src/qcanny.cpp b/plugins/lcvimgproc/src/qcanny.cpp deleted file mode 100644 index fb9fe19b..00000000 --- a/plugins/lcvimgproc/src/qcanny.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ -#include "qcanny.h" -#include "opencv2/imgproc.hpp" - -/*! - \class QCanny - \internal - \inmodule lcvimgproc_cpp - \brief Finds edges within an image. - */ - -/*! - \brief QCanny constructor - - Parameters : - \a parent - */ -QCanny::QCanny(QQuickItem *parent) : - QMatFilter(parent), - m_apertureSize(3), - m_l2gradient(false){ -} - -QCanny::~QCanny(){ -} - -/*! - \brief Filter function. - - Parameters: - \a in - \a out - */ -void QCanny::transform(const cv::Mat &in, cv::Mat &out){ - cv::Canny(in, out, m_threshold1, m_threshold2, m_apertureSize, m_l2gradient); -} diff --git a/plugins/lcvimgproc/src/qcanny.h b/plugins/lcvimgproc/src/qcanny.h deleted file mode 100644 index c6e86d2b..00000000 --- a/plugins/lcvimgproc/src/qcanny.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ - -#ifndef QCANNY_H -#define QCANNY_H - -#include "qmatfilter.h" - -class QCanny : public QMatFilter{ - - Q_OBJECT - Q_PROPERTY(double threshold1 READ threshold1 WRITE setThreshold1 NOTIFY threshold1Changed) - Q_PROPERTY(double threshold2 READ threshold2 WRITE setThreshold2 NOTIFY threshold2Changed) - Q_PROPERTY(int apertureSize READ apertureSize WRITE setApertureSize NOTIFY apertureSizeChanged) - Q_PROPERTY(bool l2gradient READ l2gradient WRITE setL2gradient NOTIFY l2gradientChanged) - -public: - explicit QCanny(QQuickItem *parent = 0); - ~QCanny(); - - virtual void transform(const cv::Mat &in, cv::Mat &out); - - double threshold1() const; - double threshold2() const; - int apertureSize()const; - bool l2gradient() const; - - void setThreshold1( double threshold ); - void setThreshold2( double threshold ); - void setApertureSize( int aperture ); - void setL2gradient( bool gradient ); - -signals: - void threshold1Changed(); - void threshold2Changed(); - void apertureSizeChanged(); - void l2gradientChanged(); - -private: - double m_threshold1; - double m_threshold2; - int m_apertureSize; - bool m_l2gradient; - -}; - -inline double QCanny::threshold1() const{ - return m_threshold1; -} - -inline double QCanny::threshold2() const{ - return m_threshold2; -} - -inline int QCanny::apertureSize() const{ - return m_apertureSize; -} - -inline bool QCanny::l2gradient() const{ - return m_l2gradient; -} - -inline void QCanny::setThreshold1(double threshold){ - if ( m_threshold1 != threshold ){ - m_threshold1 = threshold; - emit threshold1Changed(); - QMatFilter::transform(); - } -} - -inline void QCanny::setThreshold2(double threshold){ - if ( m_threshold2 != threshold ){ - m_threshold2 = threshold; - emit threshold2Changed(); - QMatFilter::transform(); - } -} - -inline void QCanny::setApertureSize(int aperture){ - if ( m_apertureSize != aperture ){ - m_apertureSize = aperture; - emit apertureSizeChanged(); - QMatFilter::transform(); - } -} - -inline void QCanny::setL2gradient(bool gradient){ - if( m_l2gradient != gradient){ - m_l2gradient = gradient; - emit l2gradientChanged(); - QMatFilter::transform(); - } -} - -#endif // QCANNY_H diff --git a/plugins/lcvimgproc/src/qchannelselect.cpp b/plugins/lcvimgproc/src/qchannelselect.cpp deleted file mode 100644 index 5f812517..00000000 --- a/plugins/lcvimgproc/src/qchannelselect.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ -#include "qchannelselect.h" -#include "opencv2/imgproc.hpp" - -/*! - \class QChannelSelect - \internal - \inmodule lcvimgproc_cpp - \brief Selects an image channel by its index. - */ - -QChannelSelect::QChannelSelect(QQuickItem *parent) - : QMatFilter(parent) - , m_channel(0) - , m_channels(3) -{ -} - -QChannelSelect::~QChannelSelect(){ -} - -/*! - \brief Filter function - - Parameters: - \a in - \a out - */ -void QChannelSelect::transform(const cv::Mat &in, cv::Mat &out){ - if ( out.channels() == 3 ) - cv::cvtColor(out, out, cv::COLOR_BGR2GRAY); - if ( !in.empty() ){ - if ( in.channels() == 1 ){ - in.copyTo(out); - return; - } else if ( in.channels() == 3 ){ - cv::split(in, m_channels); - m_channels[m_channel].copyTo(out); - } - } -} diff --git a/plugins/lcvimgproc/src/qchannelselect.h b/plugins/lcvimgproc/src/qchannelselect.h deleted file mode 100644 index e7aff86d..00000000 --- a/plugins/lcvimgproc/src/qchannelselect.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ - -#ifndef QCHANNELSELECT_H -#define QCHANNELSELECT_H - -#include "qmatfilter.h" - -class QChannelSelect : public QMatFilter{ - - Q_OBJECT - Q_PROPERTY(int channel READ channelNo WRITE setChannelNo NOTIFY channelChanged ) - -public: - explicit QChannelSelect(QQuickItem *parent = 0); - virtual ~QChannelSelect(); - - virtual void transform(const cv::Mat &in, cv::Mat &out); - - int channelNo() const; - void setChannelNo(int channel); - -signals: - void channelChanged(); - -private: - int m_channel; - - std::vector m_channels; - -}; - -inline int QChannelSelect::channelNo() const{ - return m_channel; -} - -inline void QChannelSelect::setChannelNo(int channel){ - if ( channel != m_channel ){ - m_channel = channel; - emit channelChanged(); - QMatFilter::transform(); - } -} - -#endif // QCHANNELSELECT_H diff --git a/plugins/lcvimgproc/src/qcopymakeborder.cpp b/plugins/lcvimgproc/src/qcopymakeborder.cpp deleted file mode 100644 index acfeb27a..00000000 --- a/plugins/lcvimgproc/src/qcopymakeborder.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ -#include "qcopymakeborder.h" -#include "opencv2/imgproc.hpp" - -using namespace cv; - -/*! - \class QCopyMakeBorder - \internal - \inmodule lcvimgproc_cpp - \brief Copies the source image into the middle of the destination image. - */ -QCopyMakeBorder::QCopyMakeBorder(QQuickItem *parent) - : QMatFilter(parent) - , m_color() -{ -} - -QCopyMakeBorder::~QCopyMakeBorder(){ -} - -/*! - \enum QCopyMakeBorder::BorderType - - \value BORDER_REPLICATE - \value BORDER_CONSTANT - \value BORDER_REFLECT - \value BORDER_WRAP - \value BORDER_REFLECT_101 - \value BORDER_TRANSPARENT - \value BORDER_DEFAULT - \value BORDER_ISOLATED - */ - -/*! - \brief Filtering function. - - Parameters: - \a in - \a out - */ -void QCopyMakeBorder::transform(const cv::Mat &in, cv::Mat &out){ - Scalar value; - if ( m_color.isValid() ){ - if ( out.channels() == 1 ) - value = m_color.red(); - else if ( out.channels() == 3 ) - value = Scalar(m_color.blue(), m_color.green(), m_color.red()); - } - copyMakeBorder(in, out, m_top, m_bottom, m_left, m_right, m_borderType, value); -} diff --git a/plugins/lcvimgproc/src/qcopymakeborder.h b/plugins/lcvimgproc/src/qcopymakeborder.h deleted file mode 100644 index c4e45c0c..00000000 --- a/plugins/lcvimgproc/src/qcopymakeborder.h +++ /dev/null @@ -1,156 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ - -#ifndef QCOPYMAKEBORDER_H -#define QCOPYMAKEBORDER_H - -#include "qmatfilter.h" -#include "opencv2/imgproc.hpp" - -class QCopyMakeBorder : public QMatFilter{ - - Q_OBJECT - Q_PROPERTY(int top READ top WRITE setTop NOTIFY topChanged) - Q_PROPERTY(int bottom READ bottom WRITE setBottom NOTIFY bottomChanged) - Q_PROPERTY(int left READ left WRITE setLeft NOTIFY leftChanged) - Q_PROPERTY(int right READ right WRITE setRight NOTIFY rightChanged) - Q_PROPERTY(int borderType READ borderType WRITE setBorderType NOTIFY borderTypeChanged) - Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) - - Q_ENUMS(BorderType) - -public: - enum BorderType{ - BORDER_REPLICATE = cv::BORDER_REPLICATE, - BORDER_CONSTANT = cv::BORDER_CONSTANT, - BORDER_REFLECT = cv::BORDER_REFLECT, - BORDER_WRAP = cv::BORDER_WRAP, - BORDER_REFLECT_101 = cv::BORDER_REFLECT_101, - BORDER_TRANSPARENT = cv::BORDER_TRANSPARENT, - BORDER_DEFAULT = cv::BORDER_REFLECT_101, - BORDER_ISOLATED = cv::BORDER_ISOLATED - }; - -public: - explicit QCopyMakeBorder(QQuickItem *parent = 0); - ~QCopyMakeBorder(); - - virtual void transform(const cv::Mat& in, cv::Mat& out); - -signals: - void topChanged(); - void bottomChanged(); - void leftChanged(); - void rightChanged(); - void borderTypeChanged(); - void colorChanged(); - -public: - int top() const; - void setTop(int top); - - int bottom() const; - void setBottom(int bottom); - - int left() const; - void setLeft(int left); - - int right() const; - void setRight(int right); - - int borderType() const; - void setBorderType(int borderType); - - const QColor& color() const; - void setColor(const QColor& color); - -private: - int m_top; - int m_left; - int m_right; - int m_bottom; - int m_borderType; - QColor m_color; -}; - -inline const QColor& QCopyMakeBorder::color() const{ - return m_color; -} - -inline void QCopyMakeBorder::setColor(const QColor& color){ - if (m_color != color){ - m_color = color; - emit colorChanged(); - } -} - -inline int QCopyMakeBorder::borderType() const{ - return m_borderType; -} - -inline void QCopyMakeBorder::setBorderType(int borderType){ - if (m_borderType != borderType){ - m_borderType = borderType; - emit borderTypeChanged(); - } -} - -inline int QCopyMakeBorder::right() const{ - return m_right; -} - -inline void QCopyMakeBorder::setRight(int right){ - if (m_right != right){ - m_right = right; - emit rightChanged(); - } -} - -inline int QCopyMakeBorder::left() const{ - return m_left; -} - -inline void QCopyMakeBorder::setLeft(int left){ - if (m_left != left){ - m_left = left; - emit leftChanged(); - } -} - -inline int QCopyMakeBorder::bottom() const{ - return m_bottom; -} - -inline void QCopyMakeBorder::setBottom(int bottom){ - if (m_bottom != bottom){ - m_bottom = bottom; - emit bottomChanged(); - } -} - -inline int QCopyMakeBorder::top() const{ - return m_top; -} - -inline void QCopyMakeBorder::setTop(int top){ - if (m_top != top){ - m_top = top; - emit topChanged(); - } -} - - -#endif // QCOPYMAKEBORDER_H diff --git a/plugins/lcvimgproc/src/qcvtcolor.cpp b/plugins/lcvimgproc/src/qcvtcolor.cpp deleted file mode 100644 index eb2f3a15..00000000 --- a/plugins/lcvimgproc/src/qcvtcolor.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ -#include "qcvtcolor.h" -#include "opencv2/imgproc.hpp" - -using namespace cv; - -/*! - \class QCvtColor - \inmodule lcvimgproc_cpp - \internal - \brief Converts an image from one color space to another - */ - -QCvtColor::QCvtColor(QQuickItem *parent) : - QMatFilter(parent) -{ -} - -/*! - \enum QCvtColor::CvtType - - \value CV_BGR2BGRA - \value CV_RGB2RGBA - \value CV_BGRA2BGR - \value CV_RGBA2RGB - - \value CV_BGR2RGBA - \value CV_RGB2BGRA - - \value CV_RGBA2BGR - \value CV_BGRA2RGB - - \value CV_BGR2RGB - \value CV_RGB2BGR - - \value CV_BGRA2RGBA - \value CV_RGBA2BGRA - - \value CV_BGR2GRAY - \value CV_RGB2GRAY - \value CV_GRAY2BGR - \value CV_GRAY2RGB - \value CV_GRAY2BGRA - \value CV_GRAY2RGBA - \value CV_BGRA2GRAY - \value CV_RGBA2GRAY - - \value CV_BGR2BGR565 - \value CV_RGB2BGR565 - \value CV_BGR5652BGR - \value CV_BGR5652RGB - - \value CV_BGRA2BGR565 - \value CV_RGBA2BGR565 - \value CV_BGR5652BGRA - \value CV_BGR5652RGBA - \value CV_GRAY2BGR565 - \value CV_BGR5652GRAY - - \value CV_BGR2BGR555 - \value CV_RGB2BGR555 - \value CV_BGR5552BGR - \value CV_BGR5552RGB - \value CV_BGRA2BGR555 - \value CV_RGBA2BGR555 - \value CV_BGR5552BGRA - \value CV_BGR5552RGBA - \value CV_GRAY2BGR555 - \value CV_BGR5552GRAY - - \value CV_BGR2XYZ - \value CV_RGB2XYZ - \value CV_XYZ2BGR - \value CV_XYZ2RGB - - \value CV_BGR2YCrCb - \value CV_RGB2YCrCb - \value CV_YCrCb2BGR - \value CV_YCrCb2RGB - - \value CV_BGR2HSV - \value CV_RGB2HSV - - \value CV_BGR2Lab - \value CV_RGB2Lab - - \value CV_BayerBG2BGR - \value CV_BayerGB2BGR - \value CV_BayerRG2BGR - \value CV_BayerGR2BGR - - \value CV_BayerBG2RGB - \value CV_BayerGB2RGB - \value CV_BayerRG2RGB - \value CV_BayerGR2RGB - - \value CV_BGR2Luv - \value CV_RGB2Luv - \value CV_BGR2HLS - \value CV_RGB2HLS - - \value CV_HSV2BGR - \value CV_HSV2RGB - - \value CV_Lab2BGR - \value CV_Lab2RGB - \value CV_Luv2BGR - \value CV_Luv2RGB - \value CV_HLS2BGR - \value CV_HLS2RGB - - \value CV_BayerBG2BGR_VNG - \value CV_BayerGB2BGR_VNG - \value CV_BayerRG2BGR_VNG - \value CV_BayerGR2BGR_VNG - - \value CV_BayerBG2RGB_VNG - \value CV_BayerGB2RGB_VNG - \value CV_BayerRG2RGB_VNG - \value CV_BayerGR2RGB_VNG - - \value CV_BGR2HSV_FULL - \value CV_RGB2HSV_FULL - \value CV_BGR2HLS_FULL - \value CV_RGB2HLS_FULL - - \value CV_HSV2BGR_FULL - \value CV_HSV2RGB_FULL - \value CV_HLS2BGR_FULL - \value CV_HLS2RGB_FULL - - \value CV_LBGR2Lab - \value CV_LRGB2Lab - \value CV_LBGR2Luv - \value CV_LRGB2Luv - - \value CV_Lab2LBGR - \value CV_Lab2LRGB - \value CV_Luv2LBGR - \value CV_Luv2LRGB - - \value CV_BGR2YUV - \value CV_RGB2YUV - \value CV_YUV2BGR - \value CV_YUV2RGB - - \value CV_BayerBG2GRAY - \value CV_BayerGB2GRAY - \value CV_BayerRG2GRAY - \value CV_BayerGR2GRAY - - \value CV_YUV2RGB_NV12 - \value CV_YUV2BGR_NV12 - \value CV_YUV2RGB_NV21 - \value CV_YUV2BGR_NV21 - \value CV_YUV420sp2RGB - \value CV_YUV420sp2BGR - - \value CV_YUV2RGBA_NV12 - \value CV_YUV2BGRA_NV12 - \value CV_YUV2RGBA_NV21 - \value CV_YUV2BGRA_NV21 - \value CV_YUV420sp2RGBA - \value CV_YUV420sp2BGRA - \value CV_YUV2RGB_YV12 - \value CV_YUV2BGR_YV12 - \value CV_YUV2RGB_IYUV - \value CV_YUV2BGR_IYUV - \value CV_YUV2RGB_I420 - \value CV_YUV2BGR_I420 - \value CV_YUV420p2RGB - \value CV_YUV420p2BGR - - \value CV_YUV2RGBA_YV12 - \value CV_YUV2BGRA_YV12 - \value CV_YUV2RGBA_IYUV - \value CV_YUV2BGRA_IYUV - \value CV_YUV2RGBA_I420 - \value CV_YUV2BGRA_I420 - \value CV_YUV420p2RGBA - \value CV_YUV420p2BGRA - - \value CV_YUV2GRAY_420 - \value CV_YUV2GRAY_NV21 - \value CV_YUV2GRAY_NV12 - \value CV_YUV2GRAY_YV12 - \value CV_YUV2GRAY_IYUV - \value CV_YUV2GRAY_I420 - \value CV_YUV420sp2GRAY - \value CV_YUV420p2GRAY - - \value CV_YUV2RGB_UYVY - \value CV_YUV2BGR_UYVY - \value CV_YUV2RGB_Y422 - \value CV_YUV2BGR_Y422 - \value CV_YUV2RGB_UYNV - \value CV_YUV2BGR_UYNV - - \value CV_YUV2RGBA_UYVY - \value CV_YUV2BGRA_UYVY - \value CV_YUV2RGBA_Y422 - \value CV_YUV2BGRA_Y422 - \value CV_YUV2RGBA_UYNV - \value CV_YUV2BGRA_UYNV - - \value CV_YUV2RGB_YUY2 - \value CV_YUV2BGR_YUY2 - \value CV_YUV2RGB_YVYU - \value CV_YUV2BGR_YVYU - \value CV_YUV2RGB_YUYV - \value CV_YUV2BGR_YUYV - \value CV_YUV2RGB_YUNV - \value CV_YUV2BGR_YUNV - - \value CV_YUV2RGBA_YUY2 - \value CV_YUV2BGRA_YUY2 - \value CV_YUV2RGBA_YVYU - \value CV_YUV2BGRA_YVYU - \value CV_YUV2RGBA_YUYV - \value CV_YUV2BGRA_YUYV - \value CV_YUV2RGBA_YUNV - \value CV_YUV2BGRA_YUNV - - \value CV_YUV2GRAY_UYVY - \value CV_YUV2GRAY_YUY2 - \value CV_YUV2GRAY_Y422 - \value CV_YUV2GRAY_UYNV - \value CV_YUV2GRAY_YVYU - \value CV_YUV2GRAY_YUYV - \value CV_YUV2GRAY_YUNV - - \value CV_RGBA2mRGBA - \value CV_mRGBA2RGBA - - \value CV_COLORCVT_MAX - */ -enum CvtType{ - - - -}; - -/*! - \brief Filtering function. - - Parameters: - \a in - \a out - */ -void QCvtColor::transform(const cv::Mat &in, cv::Mat &out){ - cvtColor(in, out, m_code, m_dstCn); -} diff --git a/plugins/lcvimgproc/src/qdilate.cpp b/plugins/lcvimgproc/src/qdilate.cpp deleted file mode 100644 index cc4631da..00000000 --- a/plugins/lcvimgproc/src/qdilate.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ -#include "qdilate.h" -#include "opencv2/imgproc.hpp" - -using namespace cv; - -/*! - \class QDilate - \inmodule lcvimgproc_cpp - \internal - \brief Erodes an image by using a specific structuring element. - */ - -/*! - \brief QDilate constructor - - Parameters: - \a parent - */ -QDilate::QDilate(QQuickItem *parent) - : QMatFilter(parent) - , m_kernel(0) - , m_anchorCv(-1, -1) - , m_iterations(1) - , m_borderType(BORDER_CONSTANT) -{ -} - -/*! - \brief QDilate destructor - */ -QDilate::~QDilate(){ -} - - -/*! - \property QDilate::kernel - \sa Dilate::kernel - */ - -/*! - \property QDilate::anchor - \sa Dilate::anchor - */ - -/*! - \property QDilate::iterations - \sa Dilate::iterations - */ - -/*! - \property QDilate::borderType - \sa Dilate::borderType - */ - -/*! - \property QDilate::borderValue - \sa Dilate::borderValue - */ - -/*! - \brief Filtering function. - - Parameters: - \a in - \a out - */ -void QDilate::transform(const cv::Mat &in, cv::Mat &out){ - if ( m_kernel ){ - Scalar borderValue = morphologyDefaultBorderValue(); - if ( m_borderValue.isValid() ){ - if ( in.channels() == 3 ) - borderValue = Scalar(m_borderValue.blue(), m_borderValue.green(), m_borderValue.red()); - else - borderValue = Scalar(m_borderValue.red()); - } - dilate(in, out, *(m_kernel->internalPtr()), m_anchorCv, m_iterations, m_borderType, borderValue); - } -} diff --git a/plugins/lcvimgproc/src/qdilate.h b/plugins/lcvimgproc/src/qdilate.h deleted file mode 100644 index 6b3a2193..00000000 --- a/plugins/lcvimgproc/src/qdilate.h +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ - -#ifndef QDILATE_H -#define QDILATE_H - -#include "qmatfilter.h" - -class QDilate : public QMatFilter{ - - Q_OBJECT - Q_PROPERTY(QMat* kernel READ kernel WRITE setKernel NOTIFY kernelChanged) - Q_PROPERTY(QPoint anchor READ anchor WRITE setAnchor NOTIFY anchorChanged) - Q_PROPERTY(int iterations READ iterations WRITE setIterations NOTIFY iterationsChanged) - Q_PROPERTY(int borderType READ borderType WRITE setBorderType NOTIFY borderTypeChanged) - Q_PROPERTY(QColor borderValue READ borderValue WRITE setBorderValue NOTIFY borderValueChanged) - -public: - QDilate(QQuickItem* parent = 0); - ~QDilate(); - -signals: - void kernelChanged(); - void anchorChanged(); - void iterationsChanged(); - void borderTypeChanged(); - void borderValueChanged(); - -public: - QMat* kernel() const; - void setKernel(QMat* kernel); - - const QPoint& anchor() const; - void setAnchor(const QPoint& anchor); - - int iterations() const; - void setIterations(int iterations); - - int borderType() const; - void setBorderType(int borderType); - - const QColor& borderValue() const; - void setBorderValue(const QColor& borderValue); - - void transform(const cv::Mat& in, cv::Mat& out); - -private: - QMat* m_kernel; - QPoint m_anchor; - cv::Point m_anchorCv; - int m_iterations; - int m_borderType; - QColor m_borderValue; -}; - -inline const QColor& QDilate::borderValue() const{ - return m_borderValue; -} - -inline void QDilate::setBorderValue(const QColor& borderValue){ - if (m_borderValue != borderValue){ - m_borderValue = borderValue; - emit borderValueChanged(); - } -} - -inline int QDilate::borderType() const{ - return m_borderType; -} - -inline void QDilate::setBorderType(int borderType){ - if (m_borderType != borderType){ - m_borderType = borderType; - emit borderTypeChanged(); - } -} - -inline int QDilate::iterations() const{ - return m_iterations; -} - -inline void QDilate::setIterations(int iterations){ - if (m_iterations != iterations){ - m_iterations = iterations; - emit iterationsChanged(); - } -} - -inline const QPoint& QDilate::anchor() const{ - return m_anchor; -} - -inline void QDilate::setAnchor(const QPoint& anchor){ - if (m_anchor != anchor){ - m_anchor = anchor; - m_anchorCv = cv::Point(anchor.x(), anchor.y()); - emit anchorChanged(); - } -} - -inline QMat* QDilate::kernel() const{ - return m_kernel; -} - -inline void QDilate::setKernel(QMat*kernel){ - if (m_kernel != kernel){ - m_kernel = kernel; - emit kernelChanged(); - } -} - - -#endif // QDILATE_H diff --git a/plugins/lcvimgproc/src/qerode.cpp b/plugins/lcvimgproc/src/qerode.cpp deleted file mode 100644 index 05aae085..00000000 --- a/plugins/lcvimgproc/src/qerode.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ -#include "qerode.h" -#include "opencv2/imgproc.hpp" - -using namespace cv; - -/*! - \class QErode - \inmodule lcvimgproc_cpp - \internal - \brief Dilates an image by using a specific structuring element. - */ - - -/*! - \brief QErode constructor - - Parameters: - \a parent - */ -QErode::QErode(QQuickItem *parent) - : QMatFilter(parent) - , m_kernel(0) - , m_anchorCv(-1, -1) - , m_iterations(1) - , m_borderType(BORDER_CONSTANT) -{ -} - -/*! - \brief QErode destructor - */ -QErode::~QErode(){ -} - - -/*! - \property QErode::kernel - \sa Erode::kernel - */ - - -/*! - \property QErode::anchor - \sa Erode::anchor - */ - -/*! - \property QErode::iterations - \sa Erode::iterations - */ - -/*! - \property QErode::borderType - \sa Erode::borderType - */ - -/*! - \property QErode::borderValue - \sa Erode::borderValue - */ - -/*! - \brief Filtering function. - - Parameters: - \a in - \a out - */ -void QErode::transform(const cv::Mat &in, cv::Mat &out){ - if ( m_kernel ){ - Scalar borderValue = morphologyDefaultBorderValue(); - if ( m_borderValue.isValid() ){ - if ( in.channels() == 3 ) - borderValue = Scalar(m_borderValue.blue(), m_borderValue.green(), m_borderValue.red()); - else - borderValue = Scalar(m_borderValue.red()); - } - erode(in, out, *(m_kernel->internalPtr()), m_anchorCv, m_iterations, m_borderType, borderValue); - } -} diff --git a/plugins/lcvimgproc/src/qerode.h b/plugins/lcvimgproc/src/qerode.h deleted file mode 100644 index ff1131f8..00000000 --- a/plugins/lcvimgproc/src/qerode.h +++ /dev/null @@ -1,125 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ - -#ifndef QERODE_H -#define QERODE_H - -#include "qmatfilter.h" - -class QErode : public QMatFilter{ - - Q_OBJECT - Q_PROPERTY(QMat* kernel READ kernel WRITE setKernel NOTIFY kernelChanged) - Q_PROPERTY(QPoint anchor READ anchor WRITE setAnchor NOTIFY anchorChanged) - Q_PROPERTY(int iterations READ iterations WRITE setIterations NOTIFY iterationsChanged) - Q_PROPERTY(int borderType READ borderType WRITE setBorderType NOTIFY borderTypeChanged) - Q_PROPERTY(QColor borderValue READ borderValue WRITE setBorderValue NOTIFY borderValueChanged) - -public: - QErode(QQuickItem* parent = 0); - ~QErode(); - -signals: - void kernelChanged(); - void anchorChanged(); - void iterationsChanged(); - void borderTypeChanged(); - void borderValueChanged(); - -public: - QMat* kernel() const; - void setKernel(QMat* kernel); - - const QPoint& anchor() const; - void setAnchor(const QPoint& anchor); - - int iterations() const; - void setIterations(int iterations); - - int borderType() const; - void setBorderType(int borderType); - - const QColor& borderValue() const; - void setBorderValue(const QColor& borderValue); - - void transform(const cv::Mat& in, cv::Mat& out); - -private: - QMat* m_kernel; - QPoint m_anchor; - cv::Point m_anchorCv; - int m_iterations; - int m_borderType; - QColor m_borderValue; -}; - -inline const QColor& QErode::borderValue() const{ - return m_borderValue; -} - -inline void QErode::setBorderValue(const QColor& borderValue){ - if (m_borderValue != borderValue){ - m_borderValue = borderValue; - emit borderValueChanged(); - } -} - -inline int QErode::borderType() const{ - return m_borderType; -} - -inline void QErode::setBorderType(int borderType){ - if (m_borderType != borderType){ - m_borderType = borderType; - emit borderTypeChanged(); - } -} - -inline int QErode::iterations() const{ - return m_iterations; -} - -inline void QErode::setIterations(int iterations){ - if (m_iterations != iterations){ - m_iterations = iterations; - emit iterationsChanged(); - } -} - -inline const QPoint& QErode::anchor() const{ - return m_anchor; -} - -inline void QErode::setAnchor(const QPoint& anchor){ - if (m_anchor != anchor){ - m_anchor = anchor; - m_anchorCv = cv::Point(anchor.x(), anchor.y()); - emit anchorChanged(); - } -} - -inline QMat* QErode::kernel() const{ - return m_kernel; -} - -inline void QErode::setKernel(QMat*kernel){ - if (m_kernel != kernel){ - m_kernel = kernel; - emit kernelChanged(); - } -} - -#endif // QERODE_H diff --git a/plugins/lcvimgproc/src/qfeaturedetection.cpp b/plugins/lcvimgproc/src/qfeaturedetection.cpp new file mode 100644 index 00000000..5a527a1f --- /dev/null +++ b/plugins/lcvimgproc/src/qfeaturedetection.cpp @@ -0,0 +1,43 @@ +#include "qfeaturedetection.h" +#include "cvextras.h" +#include "live/viewcontext.h" + +QFeatureDetection::QFeatureDetection(QObject *parent) : QObject(parent) +{ + +} + +QMat *QFeatureDetection::houghLines(QMat* input, double rho, double theta, int threshold, + double srn, double stn) +{ + if (!input || input->internal().empty()) return nullptr; + try{ + cv::Mat* rMat = new cv::Mat( + input->dimensions().height(), + input->dimensions().width(), + CV_MAKETYPE(input->depth(), input->channels())); + cv::HoughLines(input->internal(), *rMat, rho, theta, threshold, srn, stn); + return new QMat(rMat); + + } catch (cv::Exception& e){ + lv::CvExtras::toLocalError(e, lv::ViewContext::instance().engine(), this, "FeatureDetection: ").jsThrow(); + return nullptr; + } +} + +QMat *QFeatureDetection::houghLinesP(QMat *input, double rho, double theta, int threshold, double minLineLength, double maxLineGap) +{ + if (!input || input->internal().empty()) return nullptr; + try{ + cv::Mat* rMat = new cv::Mat( + input->dimensions().height(), + input->dimensions().width(), + CV_MAKETYPE(input->depth(), input->channels())); + cv::HoughLinesP(input->internal(), *rMat, rho, theta, threshold, minLineLength, maxLineGap); + return new QMat(rMat); + + } catch (cv::Exception& e){ + lv::CvExtras::toLocalError(e, lv::ViewContext::instance().engine(), this, "FeatureDetection: ").jsThrow(); + return nullptr; + } +} diff --git a/plugins/lcvimgproc/src/qfeaturedetection.h b/plugins/lcvimgproc/src/qfeaturedetection.h new file mode 100644 index 00000000..b1d74c3b --- /dev/null +++ b/plugins/lcvimgproc/src/qfeaturedetection.h @@ -0,0 +1,21 @@ +#ifndef QFEATUREDETECTION_H +#define QFEATUREDETECTION_H + +#include +#include "qmat.h" +#include "opencv2/imgproc.hpp" + +class QFeatureDetection : public QObject +{ + Q_OBJECT +public: + explicit QFeatureDetection(QObject *parent = nullptr); + +public slots: + QMat* houghLines(QMat* input, double rho, double theta, int threshold, + double srn = 0, double stn = 0); + QMat* houghLinesP(QMat* input, double rho, double theta, int threshold, + double minLineLength = 0, double maxLineGap = 0); +}; + +#endif // QFEATUREDETECTION_H diff --git a/plugins/lcvimgproc/src/qfilter2d.cpp b/plugins/lcvimgproc/src/qfilter2d.cpp deleted file mode 100644 index 25fd0399..00000000 --- a/plugins/lcvimgproc/src/qfilter2d.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ -#include "qfilter2d.h" -#include "opencv2/imgproc.hpp" - -using namespace cv; - -/*! - \class QFilter2D - \inmodule lcvimgproc_cpp - \internal - \brief Converts an image with the specified kernel - */ - - -/*! - \brief QFilter2D constructor - - Parameters: - \a parent - */ -QFilter2D::QFilter2D(QQuickItem *parent) - : QMatFilter(parent) - , m_kernel(0) - , m_ddepth(-1) - , m_anchorCv(-1, -1) - , m_delta(0) - , m_borderType(BORDER_DEFAULT) -{ -} - -/*! - \brief QFilter2D destructor - */ -QFilter2D::~QFilter2D(){ -} - -/*! - \brief Filtering function. - - Parameters: - \a in - \a out - */ -void QFilter2D::transform(const cv::Mat &in, cv::Mat &out){ - if ( m_kernel ){ - Mat* m = m_kernel->internalPtr(); - if ( m->cols > 0 || m->rows > 0 ){ - filter2D(in, out, m_ddepth, *(m_kernel->internalPtr()), m_anchorCv, m_delta, m_borderType); - } - } -} diff --git a/plugins/lcvimgproc/src/qfilter2d.h b/plugins/lcvimgproc/src/qfilter2d.h deleted file mode 100644 index 26759d8d..00000000 --- a/plugins/lcvimgproc/src/qfilter2d.h +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ - -#ifndef QFILTER2D_H -#define QFILTER2D_H - -#include "qmatfilter.h" - -class QFilter2D : public QMatFilter{ - - Q_OBJECT - Q_PROPERTY(int ddepth READ ddepth WRITE setDdepth NOTIFY ddepthChanged) - Q_PROPERTY(QMat* kernel READ kernel WRITE setKernel NOTIFY kernelChanged) - Q_PROPERTY(QPoint anchor READ anchor WRITE setAnchor NOTIFY anchorChanged) - Q_PROPERTY(double delta READ delta WRITE setDelta NOTIFY deltaChanged) - Q_PROPERTY(int borderType READ borderType WRITE setBorderType NOTIFY borderTypeChanged) - -public: - explicit QFilter2D(QQuickItem *parent = 0); - ~QFilter2D(); - - void transform(const cv::Mat& in, cv::Mat& out); - -signals: - void ddepthChanged(); - void kernelChanged(); - void anchorChanged(); - void deltaChanged(); - void borderTypeChanged(); - -public: - int ddepth() const; - void setDdepth(int ddepth); - - QMat* kernel() const; - void setKernel(QMat* kernel); - - const QPoint& anchor() const; - void setAnchor(const QPoint& anchor); - - double delta() const; - void setDelta(double delta); - - int borderType() const; - void setBorderType(int borderType); - -private: - QMat* m_kernel; - int m_ddepth; - QPoint m_anchor; - cv::Point m_anchorCv; - double m_delta; - int m_borderType; - -}; - -inline int QFilter2D::borderType() const{ - return m_borderType; -} - -inline void QFilter2D::setBorderType(int borderType){ - if (m_borderType != borderType){ - m_borderType = borderType; - emit borderTypeChanged(); - QMatFilter::transform(); - } -} - -inline double QFilter2D::delta() const{ - return m_delta; -} - -inline void QFilter2D::setDelta(double delta){ - if (m_delta != delta){ - m_delta = delta; - emit deltaChanged(); - QMatFilter::transform(); - } -} - -inline const QPoint& QFilter2D::anchor() const{ - return m_anchor; -} - -inline void QFilter2D::setAnchor(const QPoint& anchor){ - if (m_anchor != anchor){ - m_anchor = anchor; - m_anchorCv = cv::Point(anchor.x(), anchor.y()); - emit anchorChanged(); - QMatFilter::transform(); - } -} - -inline QMat* QFilter2D::kernel() const{ - return m_kernel; -} - -inline void QFilter2D::setKernel(QMat*kernel){ - m_kernel = kernel; - emit kernelChanged(); - QMatFilter::transform(); -} - -inline int QFilter2D::ddepth() const{ - return m_ddepth; -} - -inline void QFilter2D::setDdepth(int ddepth){ - if (m_ddepth != ddepth){ - m_ddepth = ddepth; - emit ddepthChanged(); - QMatFilter::transform(); - } -} - - -#endif // QFILTER2D_H diff --git a/plugins/lcvimgproc/src/qfilteringoperations.cpp b/plugins/lcvimgproc/src/qfilteringoperations.cpp new file mode 100644 index 00000000..b72d05bc --- /dev/null +++ b/plugins/lcvimgproc/src/qfilteringoperations.cpp @@ -0,0 +1,181 @@ +#include "qfilteringoperations.h" +#include "cvextras.h" +#include "live/viewcontext.h" + +QFilteringOperations::QFilteringOperations(QObject* parent) + : QObject(parent) +{ + +} + +QMat *QFilteringOperations::blur(QMat *input, QSize size, QPoint point, int borderType) +{ + if (!input || input->internal().empty()) return nullptr; + try{ + cv::Mat* rMat = new cv::Mat( + input->dimensions().height(), + input->dimensions().width(), + CV_MAKETYPE(input->depth(), input->channels())); + cv::blur(input->internal(), *rMat, cv::Size(size.width(), size.height()), cv::Point(point.x(), point.y()), borderType); + QMat* result = new QMat(rMat); + return result; + + } catch (cv::Exception& e){ + lv::CvExtras::toLocalError(e, lv::ViewContext::instance().engine(), this, "FilteringOperations: ").jsThrow(); + return nullptr; + } + +} + +QMat *QFilteringOperations::canny(QMat *input, double threshold1, double threshold2, int apertureSize, bool L2gradient) +{ + if (!input || input->internal().empty()) return nullptr; + try{ + cv::Mat* rMat = new cv::Mat( + input->dimensions().height(), + input->dimensions().width(), + CV_MAKETYPE(input->depth(), input->channels())); + cv::Canny(input->internal(), *rMat, threshold1, threshold2, apertureSize, L2gradient); + QMat* result = new QMat(rMat); + return result; + + } catch (cv::Exception& e){ + lv::CvExtras::toLocalError(e, lv::ViewContext::instance().engine(), this, "FilteringOperations: ").jsThrow(); + return nullptr; + } +} + +QMat *QFilteringOperations::dilate(QMat *input, QMat *kernel, QPoint anchor, int iterations, int borderType, QColor borderValue) +{ + if (!input || input->internal().empty() || !kernel || kernel->internal().empty()) return nullptr; + try{ + cv::Mat* rMat = new cv::Mat( + input->dimensions().height(), + input->dimensions().width(), + CV_MAKETYPE(input->depth(), input->channels())); + cv::Scalar bv = cv::morphologyDefaultBorderValue(); + if ( borderValue.isValid() ){ + if ( input->channels() == 3 ) + bv = cv::Scalar(borderValue.blue(), borderValue.green(), borderValue.red()); + else + bv = cv::Scalar(borderValue.red()); + } + cv::dilate(input->internal(), + *rMat, kernel->internal(), + cv::Point(anchor.x(), anchor.y()), + iterations, + borderType, + bv); + QMat* result = new QMat(rMat); + return result; + + } catch (cv::Exception& e){ + lv::CvExtras::toLocalError(e, lv::ViewContext::instance().engine(), this, "FilteringOperations: ").jsThrow(); + return nullptr; + } +} + +QMat *QFilteringOperations::erode(QMat *input, QMat *kernel, QPoint anchor, int iterations, int borderType, QColor borderValue) +{ + if (!input || input->internal().empty() || !kernel || kernel->internal().empty()) return nullptr; + try{ + cv::Mat* rMat = new cv::Mat( + input->dimensions().height(), + input->dimensions().width(), + CV_MAKETYPE(input->depth(), input->channels())); + cv::Scalar bv = cv::morphologyDefaultBorderValue(); + if ( borderValue.isValid() ){ + if ( input->channels() == 3 ) + bv = cv::Scalar(borderValue.blue(), borderValue.green(), borderValue.red()); + else + bv = cv::Scalar(borderValue.red()); + } + cv::erode(input->internal(), + *rMat, kernel->internal(), + cv::Point(anchor.x(), anchor.y()), + iterations, + borderType, + bv); + QMat* result = new QMat(rMat); + return result; + + } catch (cv::Exception& e){ + lv::CvExtras::toLocalError(e, lv::ViewContext::instance().engine(), this, "FilteringOperations: ").jsThrow(); + return nullptr; + } +} + +QMat *QFilteringOperations::filter2D(QMat *input, int ddepth, QMat *kernel, QPoint anchor, double delta, int borderType) +{ + if (!input || input->internal().empty() || !kernel || kernel->internal().empty()) return nullptr; + try{ + cv::Mat* rMat = new cv::Mat( + input->dimensions().height(), + input->dimensions().width(), + CV_MAKETYPE(input->depth(), input->channels())); + cv::filter2D(input->internal(), + *rMat, + ddepth, + kernel->internal(), + cv::Point(anchor.x(), anchor.y()), + delta, borderType); + QMat* result = new QMat(rMat); + return result; + + } catch (cv::Exception& e){ + lv::CvExtras::toLocalError(e, lv::ViewContext::instance().engine(), this, "FilteringOperations: ").jsThrow(); + return nullptr; + } +} + +QMat *QFilteringOperations::gaussianBlur(QMat *input, QSize size, double sigmaX, double sigmaY, int borderType) +{ + if (!input || input->internal().empty()) return nullptr; + try{ + cv::Mat* rMat = new cv::Mat( + input->dimensions().height(), + input->dimensions().width(), + CV_MAKETYPE(input->depth(), input->channels())); + cv::GaussianBlur(input->internal(), *rMat, cv::Size(size.width(), size.height()), sigmaX, sigmaY, borderType); + QMat* result = new QMat(rMat); + return result; + + } catch (cv::Exception& e){ + lv::CvExtras::toLocalError(e, lv::ViewContext::instance().engine(), this, "FilteringOperations: ").jsThrow(); + return nullptr; + } +} + +QMat *QFilteringOperations::sobel(QMat *input, int ddepth, int xorder, int yorder, int ksize, double scale, double delta, int borderType) +{ + if (!input || input->internal().empty()) return nullptr; + try{ + cv::Mat* rMat = new cv::Mat( + input->dimensions().height(), + input->dimensions().width(), + CV_MAKETYPE(input->depth(), input->channels())); + cv::Sobel(input->internal(), *rMat, ddepth, xorder, yorder, ksize, scale, delta, borderType); + QMat* result = new QMat(rMat); + return result; + + } catch (cv::Exception& e){ + lv::CvExtras::toLocalError(e, lv::ViewContext::instance().engine(), this, "FilteringOperations: ").jsThrow(); + return nullptr; + } +} + +QMat *QFilteringOperations::getStructuringElement(int shape, QSize size, QPoint anchor) +{ + try{ + cv::Mat mat = cv::getStructuringElement(shape, + cv::Size(size.width(), size.height()), + cv::Point(anchor.x(), anchor.y())); + QMat* result = new QMat(); + *result->internalPtr() = mat; + return result; + + } catch (cv::Exception& e){ + lv::CvExtras::toLocalError(e, lv::ViewContext::instance().engine(), this, "FilteringOperations: ").jsThrow(); + return nullptr; + } +} diff --git a/plugins/lcvimgproc/src/qfilteringoperations.h b/plugins/lcvimgproc/src/qfilteringoperations.h new file mode 100644 index 00000000..249e4cb0 --- /dev/null +++ b/plugins/lcvimgproc/src/qfilteringoperations.h @@ -0,0 +1,58 @@ +#ifndef QFILTERINGOPERATIONS_H +#define QFILTERINGOPERATIONS_H + +#include +#include "qmat.h" +#include "opencv2/imgproc.hpp" + +class QFilteringOperations: public QObject +{ + Q_OBJECT + Q_ENUMS(BorderType) + Q_ENUMS(ElementShape) +public: + enum BorderType { + BORDER_CONSTANT = cv::BORDER_CONSTANT, + BORDER_REPLICATE = cv::BORDER_REPLICATE, + BORDER_REFLECT = cv::BORDER_REFLECT, + BORDER_WRAP = cv::BORDER_WRAP, + BORDER_REFLECT_101 = cv::BORDER_REFLECT_101, + BORDER_TRANSPARENT = cv::BORDER_TRANSPARENT, + + BORDER_REFLECT101 = BORDER_REFLECT_101, + BORDER_DEFAULT = BORDER_REFLECT_101, + BORDER_ISOLATED = cv::BORDER_ISOLATED + }; + + enum ElementShape{ + MORPH_RECT = cv::MORPH_RECT, + MORPH_ELLIPSE = cv::MORPH_ELLIPSE, + MORPH_CROSS = cv::MORPH_CROSS + }; + + QFilteringOperations(QObject* parent = nullptr); +public slots: + QMat* blur(QMat *input, QSize size, QPoint point, int borderType = BORDER_DEFAULT); + QMat* canny(QMat* input, double threshold1, double threshold2, + int apertureSize = 3, bool L2gradient = false); + QMat* dilate(QMat* input, QMat* kernel, + QPoint anchor, int iterations = 1, + int borderType = BORDER_CONSTANT, QColor borderValue = QColor()); + QMat* erode(QMat* input, QMat* kernel, + QPoint anchor, int iterations = 1, + int borderType = BORDER_CONSTANT, QColor borderValue = QColor()); + QMat* filter2D(QMat* src, int ddepth, + QMat* kernel, QPoint anchor = QPoint(1, 1), + double delta = 0, int borderType = BORDER_DEFAULT); + QMat* gaussianBlur(QMat* src, QSize size, + double sigmaX, double sigmaY = 0, + int borderType = BORDER_DEFAULT); + QMat* sobel(QMat* input, int ddepth, int xorder, int yorder, + int ksize = 3, + double scale = 1, + double delta = 0, + int borderType = BORDER_DEFAULT); + QMat* getStructuringElement(int shape, QSize size, QPoint anchor); +}; + +#endif // QFILTERINGOPERATIONS_H diff --git a/plugins/lcvimgproc/src/qgaussianblur.cpp b/plugins/lcvimgproc/src/qgaussianblur.cpp deleted file mode 100644 index 2e8efb2c..00000000 --- a/plugins/lcvimgproc/src/qgaussianblur.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ -#include "qgaussianblur.h" -#include "opencv2/imgproc.hpp" - -using namespace cv; - - -/*! - \class QGaussianBlur - \internal - \inmodule lcvimgproc_cpp - \brief Blurs an image using a Gaussian filter. - */ - -/*! - \brief QGaussianBlur constructor - - Parameters: - \a parent - */ -QGaussianBlur::QGaussianBlur(QQuickItem *parent) - : QMatFilter(parent) - , m_ksize(QSize(3, 3)) - , m_sigmaX(0) - , m_sigmaY(0) - , m_borderType(BORDER_DEFAULT) -{ -} - -/*! - \brief QGaussianBlur destructor - */ -QGaussianBlur::~QGaussianBlur(){ -} - -/*! - \brief Filtering function. - - Parameters: - \a in - \a out - */ -void QGaussianBlur::transform(const cv::Mat &in, cv::Mat &out){ - GaussianBlur(in, out, cv::Size(m_ksize.width(), m_ksize.height()), m_sigmaX, m_sigmaY, m_borderType); -} diff --git a/plugins/lcvimgproc/src/qgaussianblur.h b/plugins/lcvimgproc/src/qgaussianblur.h deleted file mode 100644 index 84709f4d..00000000 --- a/plugins/lcvimgproc/src/qgaussianblur.h +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ - -#ifndef QGAUSSIANBLUR_H -#define QGAUSSIANBLUR_H - -#include "qmatfilter.h" - -class QGaussianBlur : public QMatFilter{ - - Q_OBJECT - Q_PROPERTY(QSize ksize READ ksize WRITE setKsize NOTIFY ksizeChanged) - Q_PROPERTY(double sigmaX READ sigmaX WRITE setSigmaX NOTIFY sigmaXChanged) - Q_PROPERTY(double sigmaY READ sigmaY WRITE setSigmaY NOTIFY sigmaYChanged) - Q_PROPERTY(int borderType READ borderType WRITE setBorderType NOTIFY borderTypeChanged) - -public: - explicit QGaussianBlur(QQuickItem *parent = 0); - ~QGaussianBlur(); - - virtual void transform(const cv::Mat& in, cv::Mat& out); - - const QSize& ksize() const; - double sigmaX() const; - double sigmaY() const; - int borderType() const; - - void setKsize(const QSize& arg); - void setSigmaX(double arg); - void setSigmaY(double arg); - void setBorderType(int arg); - -signals: - void ksizeChanged(); - void sigmaXChanged(); - void sigmaYChanged(); - void borderTypeChanged(); - -private: - QSize m_ksize; - double m_sigmaX; - double m_sigmaY; - int m_borderType; -}; - -inline const QSize& QGaussianBlur::ksize() const{ - return m_ksize; -} - -inline double QGaussianBlur::sigmaX() const{ - return m_sigmaX; -} - -inline double QGaussianBlur::sigmaY() const{ - return m_sigmaY; -} - -inline int QGaussianBlur::borderType() const{ - return m_borderType; -} - -inline void QGaussianBlur::setKsize(const QSize& arg){ - if (m_ksize != arg) { - m_ksize = arg; - emit ksizeChanged(); - QMatFilter::transform(); - } -} - -inline void QGaussianBlur::setSigmaX(double arg){ - if (m_sigmaX != arg) { - m_sigmaX = arg; - emit sigmaXChanged(); - QMatFilter::transform(); - } -} - -inline void QGaussianBlur::setSigmaY(double arg){ - if (m_sigmaY != arg) { - m_sigmaY = arg; - emit sigmaYChanged(); - QMatFilter::transform(); - } -} - -inline void QGaussianBlur::setBorderType(int arg){ - if (m_borderType != arg) { - m_borderType = arg; - emit borderTypeChanged(); - QMatFilter::transform(); - } -} - -#endif // QGAUSSIANBLUR_H diff --git a/plugins/lcvimgproc/src/qhoughlines.cpp b/plugins/lcvimgproc/src/qhoughlines.cpp deleted file mode 100644 index a64e9076..00000000 --- a/plugins/lcvimgproc/src/qhoughlines.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ -#include "qhoughlines.h" -#include "opencv2/imgproc.hpp" -#include - -using namespace cv; -using namespace std; - -/*! - \class QHoughLines - \inmodule lcvimgproc_cpp - \internal - \brief Finds line segments in a binary image using the Hough transform. - */ - -class QHoughLinesPrivate{ - -public: - vector lines; - bool linesDirty; - bool outDirty; - -}; - -/*! - \brief QHoughLines constructor - - Parameters: - \a parent - */ -QHoughLines::QHoughLines(QQuickItem *parent) - : QMatFilter(parent) - , m_srn(0) - , m_stn(0) - , m_lineColor(0, 255, 0) - , m_lineThickness(2) - , d_ptr(new QHoughLinesPrivate){ - - Q_D(QHoughLines); - d->linesDirty = false; - d->outDirty = false; -} - -QHoughLines::~QHoughLines(){ - delete d_ptr; -} - -/*! - \brief Filtering function. - - Parameters: - \a in - \a out - */ -void QHoughLines::transform(const cv::Mat &in, cv::Mat&){ - Q_D(QHoughLines); - if ( in.size() != Size(0, 0) ) - HoughLines(in, d->lines, m_rho, m_theta, m_threshold, m_srn, m_stn); - d->linesDirty = true; - d->outDirty = true; -} - -/*! - \fn virtual QSGNode* QHoughLines::updatePaintNode(QSGNode*, UpdatePaintNodeData*) - - \brief Updates the scene graph node with the drawn lines. - - Parameters : - \a node - \a nodeData - */ - -QSGNode *QHoughLines::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *nodeData){ - Q_D(QHoughLines); - if ( d->outDirty ){ - Mat* surface = output()->internalPtr(); - surface->create(inputMat()->internalPtr()->size(), CV_8UC4); - surface->setTo(Scalar(0, 0, 0, 0)); - for( size_t i = 0; i < d->lines.size(); ++i ){ - float rho = d->lines[i][0], theta = d->lines[i][1]; - double a = cos(theta), b = sin(theta); - double x0 = a * rho, y0 = b * rho; - Point pt1, pt2; - pt1.x = cvRound(x0 + 1000*(-b)); - pt1.y = cvRound(y0 + 1000*(a)); - pt2.x = cvRound(x0 - 1000*(-b)); - pt2.y = cvRound(y0 - 1000*(a)); - line( *surface, pt1, pt2, - Scalar(m_lineColor.blue(), m_lineColor.green(), m_lineColor.red(), 255), - m_lineThickness, cv::LINE_AA ); - } - d->outDirty = false; - } - return QMatDisplay::updatePaintNode(node, nodeData); -} diff --git a/plugins/lcvimgproc/src/qhoughlines.h b/plugins/lcvimgproc/src/qhoughlines.h deleted file mode 100644 index 4e7a1656..00000000 --- a/plugins/lcvimgproc/src/qhoughlines.h +++ /dev/null @@ -1,167 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ - -#ifndef QHOUGHLINES_H -#define QHOUGHLINES_H - -#include "qmatfilter.h" - -class QHoughLinesPrivate; -class QHoughLines : public QMatFilter{ - - Q_OBJECT - Q_PROPERTY(double rho READ rho WRITE setRho NOTIFY rhoChanged) - Q_PROPERTY(double theta READ theta WRITE setTheta NOTIFY thetaChanged) - Q_PROPERTY(int threshold READ threshold WRITE setThreshold NOTIFY thresholdChanged) - Q_PROPERTY(double srn READ srn WRITE setSrn NOTIFY srnChanged) - Q_PROPERTY(double stn READ stn WRITE setStn NOTIFY stnChanged) - Q_PROPERTY(QColor lineColor READ lineColor WRITE setLineColor NOTIFY lineColorChanged) - Q_PROPERTY(int lineThickness READ lineThickness WRITE setLineThickness NOTIFY lineThicknessChanged) - -public: - explicit QHoughLines(QQuickItem *parent = 0); - ~QHoughLines(); - - virtual void transform(const cv::Mat& in, cv::Mat& out); - virtual QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *nodeData); - - double rho() const; - double theta() const; - int threshold() const; - double srn() const; - double stn() const; - const QColor& lineColor() const; - int lineThickness() const; - - void setRho(double arg); - void setTheta(double arg); - void setThreshold(int arg); - void setSrn(double srn); - void setStn(double stn); - void setLineColor(const QColor& lineColor); - void setLineThickness(int lineThickness); - -signals: - void rhoChanged(); - void thetaChanged(); - void thresholdChanged(); - void srnChanged(); - void stnChanged(); - void lineColorChanged(); - void lineThicknessChanged(); - -private: - QHoughLines(const QHoughLines& other); - QHoughLines& operator= (const QHoughLines& other); - - double m_rho; - double m_theta; - int m_threshold; - double m_srn; - double m_stn; - QColor m_lineColor; - int m_lineThickness; - - QHoughLinesPrivate* const d_ptr; - - Q_DECLARE_PRIVATE(QHoughLines) - -}; - -inline double QHoughLines::rho() const{ - return m_rho; -} - -inline double QHoughLines::theta() const{ - return m_theta; -} - -inline int QHoughLines::threshold() const{ - return m_threshold; -} - -inline double QHoughLines::srn() const{ - return m_srn; -} - -inline double QHoughLines::stn() const{ - return m_stn; -} - -inline const QColor&QHoughLines::lineColor() const{ - return m_lineColor; -} - -inline int QHoughLines::lineThickness() const{ - return m_lineThickness; -} - -inline void QHoughLines::setRho(double arg){ - if (m_rho != arg) { - m_rho = arg; - emit rhoChanged(); - QMatFilter::transform(); - } -} - -inline void QHoughLines::setTheta(double arg){ - if (m_theta != arg) { - m_theta = arg; - emit thetaChanged(); - } -} - -inline void QHoughLines::setThreshold(int arg){ - if (m_threshold != arg) { - m_threshold = arg; - emit thresholdChanged(); - QMatFilter::transform(); - } -} - -inline void QHoughLines::setSrn(double srn){ - if ( m_srn != srn ){ - m_srn = srn; - emit srnChanged(); - QMatFilter::transform(); - } -} - -inline void QHoughLines::setStn(double stn){ - if ( m_stn != stn ){ - m_stn = stn; - emit stnChanged(); - QMatFilter::transform(); - } -} - -inline void QHoughLines::setLineColor(const QColor& lineColor){ - if ( m_lineColor != lineColor ){ - m_lineColor = lineColor; - emit lineColorChanged(); - update(); - } -} - -inline void QHoughLines::setLineThickness(int lineThickness){ - if ( m_lineThickness != lineThickness ){ - m_lineThickness = lineThickness; - emit lineThicknessChanged(); - update(); - } -} - -#endif // QHOUGHLINES_H diff --git a/plugins/lcvimgproc/src/qsobel.cpp b/plugins/lcvimgproc/src/qsobel.cpp deleted file mode 100644 index fb0c6a9a..00000000 --- a/plugins/lcvimgproc/src/qsobel.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ -#include "qsobel.h" -#include "opencv2/imgproc.hpp" -#include "qmatnode.h" -#include - -using namespace cv; - -/*! - \class QSobel - \inmodule lcvimgproc_cpp - \internal - \brief Calculates the first, second, third, or mixed image derivatives using an extended Sobel operator. - */ - -QSobel::QSobel(QQuickItem *parent) - : QMatFilter(parent) - , m_ddepth(QMat::CV16S) - , m_xorder(1) - , m_yorder(0) - , m_ksize(3) - , m_scale(1) - , m_delta(0) - , m_borderType(BORDER_DEFAULT) - , m_display(new QMat) -{ -} - - -QSobel::~QSobel(){ - delete m_display; -} - -/*! - \fn virtual QSGNode* QSobel::updatePaintNode(QSGNode*, QQuickItem::UpdatePaintNodeData*) - - \brief Updates the scene graph node with the drawn lines. - - Parameters : - \a node - \a nodeData - */ - -QSGNode *QSobel::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *nodeData){ - if ( output()->internalPtr()->size() != Size(0, 0) ) - convertScaleAbs(*output()->internalPtr(), *m_display->internalPtr()); - - QMatNode *n = static_cast(QMatDisplay::updatePaintNode(node, nodeData)); - static_cast*>(n->material())->state()->mat = m_display; - return n; -} - -/*! - \brief Filtering function. - - Parameters: - \a in - \a out - */ -void QSobel::transform(const cv::Mat &in, cv::Mat &out){ - if ( in.size() != Size(0, 0) ) - Sobel(in, out, m_ddepth, m_xorder, m_yorder, m_ksize, m_scale, m_delta, m_borderType); -} diff --git a/plugins/lcvimgproc/src/qsobel.h b/plugins/lcvimgproc/src/qsobel.h deleted file mode 100644 index b434590b..00000000 --- a/plugins/lcvimgproc/src/qsobel.h +++ /dev/null @@ -1,164 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ - -#ifndef QSOBEL_H -#define QSOBEL_H - -#include "qmatfilter.h" - -//- Sobel operator - QSobel Class - -class QSobel : public QMatFilter{ - - Q_OBJECT - Q_PROPERTY(QMat::Type ddepth READ ddepth WRITE setDdepth NOTIFY ddepthChanged) - Q_PROPERTY(int xorder READ xorder WRITE setXOrder NOTIFY xorderChanged) - Q_PROPERTY(int yorder READ yorder WRITE setYOrder NOTIFY yorderChanged) - Q_PROPERTY(int ksize READ ksize WRITE setKsize NOTIFY ksizeChanged) - Q_PROPERTY(double scale READ scale WRITE setScale NOTIFY scaleChagned) - Q_PROPERTY(double delta READ delta WRITE setDelta NOTIFY deltaChanged) - Q_PROPERTY(int borderType READ borderType WRITE setBorderType NOTIFY borderTypeChanged) - -public: - explicit QSobel(QQuickItem *parent = 0); - virtual ~QSobel(); - - virtual QSGNode *updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *nodeData); - virtual void transform(const cv::Mat& in, cv::Mat& out); - - QMat::Type ddepth() const; - int xorder() const; - int yorder() const; - int ksize() const; - double scale() const; - double delta() const; - int borderType() const; - - void setDdepth(QMat::Type arg); - void setXOrder(int arg); - void setYOrder(int arg); - void setKsize(int arg); - void setScale(double arg); - void setDelta(double arg); - void setBorderType(int arg); - -signals: - void ddepthChanged(); - void xorderChanged(); - void yorderChanged(); - void ksizeChanged(); - void scaleChagned(); - void deltaChanged(); - void borderTypeChanged(); - -private: - QMat::Type m_ddepth; - int m_xorder; - int m_yorder; - int m_ksize; - double m_scale; - double m_delta; - int m_borderType; - - QMat* m_display; - -}; - -inline QMat::Type QSobel::ddepth() const{ - return m_ddepth; -} - -inline int QSobel::xorder() const{ - return m_xorder; -} - -inline int QSobel::yorder() const{ - return m_yorder; -} - -inline int QSobel::ksize() const{ - return m_ksize; -} - -inline double QSobel::scale() const{ - return m_scale; -} - -inline double QSobel::delta() const{ - return m_delta; -} - -inline int QSobel::borderType() const{ - return m_borderType; -} - -inline void QSobel::setDdepth(QMat::Type arg){ - if (m_ddepth != arg) { - m_ddepth = arg; - emit ddepthChanged(); - QMatFilter::transform(); - } -} - -inline void QSobel::setXOrder(int arg){ - if (m_xorder != arg) { - m_xorder = arg; - emit xorderChanged(); - QMatFilter::transform(); - } -} - -inline void QSobel::setYOrder(int arg){ - if (m_yorder != arg) { - m_yorder = arg; - emit yorderChanged(); - QMatFilter::transform(); - } -} - -inline void QSobel::setKsize(int arg){ - if (m_ksize != arg) { - m_ksize = arg; - emit ksizeChanged(); - QMatFilter::transform(); - } -} - -inline void QSobel::setScale(double arg){ - if (m_scale != arg) { - m_scale = arg; - emit scaleChagned(); - QMatFilter::transform(); - } -} - -inline void QSobel::setDelta(double arg){ - if (m_delta != arg) { - m_delta = arg; - emit deltaChanged(); - QMatFilter::transform(); - } -} - -inline void QSobel::setBorderType(int arg){ - if (m_borderType != arg) { - m_borderType = arg; - emit borderTypeChanged(); - QMatFilter::transform(); - } -} - -#endif // QSOBEL_H diff --git a/plugins/lcvimgproc/src/qstructuringelement.cpp b/plugins/lcvimgproc/src/qstructuringelement.cpp deleted file mode 100644 index c7eba975..00000000 --- a/plugins/lcvimgproc/src/qstructuringelement.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ -#include "qstructuringelement.h" -#include "opencv2/imgproc.hpp" - -using namespace cv; - -/*! - \class QStructuringElement - \inmodule lcvimgproc_cpp - \internal - \brief Creates a structuring element of the specified size and shape for morphological operations. - */ - -QStructuringElement::QStructuringElement(QQuickItem *parent) - : QQuickItem(parent) - , m_output(new QMat) - , m_outputDirty(false) -{ - setFlag(ItemHasContents, false); -} - -QStructuringElement::~QStructuringElement(){ - delete m_output; -} - -/*! - \enum QStructuringElement::ElementShape - - \value MORPH_RECT - \value MORPH_ELLIPSE - \value MORPH_CROSS - */ - - -QMat* QStructuringElement::output() const{ - if ( m_outputDirty ) - *m_output->internalPtr() = getStructuringElement( - m_shape, - Size(m_ksize.width(), m_ksize.height()), - Point(m_anchor.x(), m_anchor.y())); - - return m_output; -} diff --git a/plugins/lcvimgproc/src/qstructuringelement.h b/plugins/lcvimgproc/src/qstructuringelement.h deleted file mode 100644 index 09dffb10..00000000 --- a/plugins/lcvimgproc/src/qstructuringelement.h +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ - -#ifndef QSTRUCTURINGELEMENT_H -#define QSTRUCTURINGELEMENT_H - -#include -#include "qmat.h" -#include "opencv2/imgproc.hpp" - -class QStructuringElement : public QQuickItem{ - - Q_OBJECT - Q_PROPERTY(ElementShape shape READ shape WRITE setShape NOTIFY shapeChanged) - Q_PROPERTY(QSize ksize READ ksize WRITE setKsize NOTIFY ksizeChanged) - Q_PROPERTY(QPoint anchor READ anchor WRITE setAnchor NOTIFY anchorChanged) - Q_PROPERTY(QMat* output READ output WRITE setOutput NOTIFY outputChanged) - - Q_ENUMS(ElementShape) - -public: - enum ElementShape{ - MORPH_RECT = cv::MORPH_RECT, - MORPH_ELLIPSE = cv::MORPH_ELLIPSE, - MORPH_CROSS = cv::MORPH_CROSS - }; - - QStructuringElement(QQuickItem* parent = 0); - ~QStructuringElement(); - - ElementShape shape() const; - void setShape(ElementShape shape); - - const QSize& ksize() const; - void setKsize(const QSize& ksize); - - const QPoint& anchor() const; - void setAnchor(const QPoint& anchor); - - QMat* output() const; - void setOutput(QMat* output); - -signals: - void ksizeChanged(); - void shapeChanged(); - void anchorChanged(); - void outputChanged(); - -private: - void setOutputDirty(); - -private: - ElementShape m_shape; - QPoint m_anchor; - QSize m_ksize; - QMat* m_output; - bool m_outputDirty; -}; - -inline void QStructuringElement::setOutputDirty(){ - m_outputDirty = true; - emit outputChanged(); -} - -inline void QStructuringElement::setOutput(QMat* output){ - if (m_output != output){ - m_output = output; - emit outputChanged(); - } -} - -inline const QPoint& QStructuringElement::anchor() const{ - return m_anchor; -} - -inline void QStructuringElement::setAnchor(const QPoint& anchor){ - if (m_anchor != anchor){ - m_anchor = anchor; - emit anchorChanged(); - setOutputDirty(); - } -} - -inline const QSize& QStructuringElement::ksize() const{ - return m_ksize; -} - -inline void QStructuringElement::setKsize(const QSize& ksize){ - if (m_ksize != ksize){ - m_ksize = ksize; - emit ksizeChanged(); - setOutputDirty(); - } -} - -inline QStructuringElement::ElementShape QStructuringElement::shape() const{ - return m_shape; -} - -inline void QStructuringElement::setShape(ElementShape shape){ - if (m_shape != shape){ - m_shape = shape; - emit shapeChanged(); - setOutputDirty(); - } -} - - -#endif // QSTRUCTURINGELEMENT_H From 60a28d32d16f465bf7ef368abc99ddb31cd658b5 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Mon, 14 Jun 2021 12:08:23 +0300 Subject: [PATCH 59/91] Removed PaletteStyle and ShapingOptions --- plugins/editqml/qml/PaletteStyle.qml | 37 ---------------------- plugins/editqml/qml/ShapingOptions.qml | 26 --------------- plugins/editqml/qml/palettestyleeditor.qml | 16 ---------- 3 files changed, 79 deletions(-) delete mode 100644 plugins/editqml/qml/PaletteStyle.qml delete mode 100644 plugins/editqml/qml/ShapingOptions.qml delete mode 100644 plugins/editqml/qml/palettestyleeditor.qml diff --git a/plugins/editqml/qml/PaletteStyle.qml b/plugins/editqml/qml/PaletteStyle.qml deleted file mode 100644 index b6826f2f..00000000 --- a/plugins/editqml/qml/PaletteStyle.qml +++ /dev/null @@ -1,37 +0,0 @@ -import QtQuick 2.3 -import QtQuick.Controls.Styles 1.2 -import workspace 1.0 -import visual.input 1.0 as Input - -QtObject{ - - property color backgroundColor: 'black' - property color paletteBackgroundColor: 'black' - property color paletteHeaderColor: '#333' - property color sectionLabelColor: '#686868' - property color sectionHeaderBackgroundColor: '#777' - property color sectionHeaderFocusBackgroundColor: '#888' - property color scrollbarColor: "#555" - property QtObject colorScheme: QtObject{} - - property QtObject labelStyle : Input.LabelOnRectangleStyle{} - property QtObject inputStyle : Input.InputBoxStyle{} - property QtObject monoInputStyle : Input.InputBoxStyle{ - textStyle: Input.TextStyle{ font.family : 'Source Code Pro, Ubuntu Mono, Courier New, Courier' } - hintTextStyle: Input.TextStyle{ font.family : 'Source Code Pro, Ubuntu Mono, Courier New, Courier'} - } - property QtObject buttonStyle : Input.TextButtonStyle{} - - property QtObject propertyLabelStyle : QtObject{ - property color background: '#555' - property double borderThickness: 1 - property color borderColor: 'black' - } - - property QtObject buttons : QtObject{} - property QtObject nodeEditor: QtObject{} - property QtObject selectableListView: Input.SelectableListViewStyle{} - property QtObject timelineStyle: QtObject{} - -} - diff --git a/plugins/editqml/qml/ShapingOptions.qml b/plugins/editqml/qml/ShapingOptions.qml deleted file mode 100644 index ba1bad79..00000000 --- a/plugins/editqml/qml/ShapingOptions.qml +++ /dev/null @@ -1,26 +0,0 @@ -import QtQuick 2.3 -import editor 1.0 - -QtObject{ - property Component addBoxFactory: Component{ AddQmlBox{} } - property Component propertyContainerFactory: Component{ PropertyContainer{} } - property Component paletteContainerFactory: Component{ PaletteContainer{} } - property Component paletteGroupFactory : Component{ PaletteGroup{} } - - function createAddBox(parent){ - return addBoxFactory.createObject(parent) - } - - function createPropertyContainer(parent){ - return propertyContainerFactory.createObject(parent) - } - - function createPaletteGroup(parent){ - return paletteGroupFactory.createObject(parent) - } - - function createPaletteContainer(parent){ - return paletteContainerFactory.createObject(parent) - } - -} diff --git a/plugins/editqml/qml/palettestyleeditor.qml b/plugins/editqml/qml/palettestyleeditor.qml deleted file mode 100644 index 68f9c7f5..00000000 --- a/plugins/editqml/qml/palettestyleeditor.qml +++ /dev/null @@ -1,16 +0,0 @@ -import QtQuick 2.3 -import editqml 1.0 - -Grid{ - - PaletteStyle{ - id: paletteStyle - sectionHeaderBackgroundColor: 'purple' - } - - Component.onCompleted: { - var pstyle = lk.layers.workspace.extensions.editqml.paletteStyle - pstyle.sectionHeaderBackgroundColor = Qt.binding(function(){return paletteStyle.sectionHeaderBackgroundColor}) - } - -} From b4b15374835e660f29578190f56d4b6f9b122b69 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Fri, 18 Jun 2021 14:46:44 +0300 Subject: [PATCH 60/91] QmlEditFragment: Added support for method check. --- lib/lveditqmljs/src/qmleditfragment.cpp | 4 ++++ lib/lveditqmljs/src/qmleditfragment.h | 1 + 2 files changed, 5 insertions(+) diff --git a/lib/lveditqmljs/src/qmleditfragment.cpp b/lib/lveditqmljs/src/qmleditfragment.cpp index 09a756e6..591356e1 100644 --- a/lib/lveditqmljs/src/qmleditfragment.cpp +++ b/lib/lveditqmljs/src/qmleditfragment.cpp @@ -788,6 +788,10 @@ bool QmlEditFragment::isNull() return readValueText() == "null"; } +bool QmlEditFragment::isMethod(){ + return m_channel ? m_channel->type() == QmlBindingChannel::Method : false; +} + void QmlEditFragment::__channelObjectErased(){ if ( !m_channel ) return; diff --git a/lib/lveditqmljs/src/qmleditfragment.h b/lib/lveditqmljs/src/qmleditfragment.h index e7f85efa..d52c4341 100644 --- a/lib/lveditqmljs/src/qmleditfragment.h +++ b/lib/lveditqmljs/src/qmleditfragment.h @@ -196,6 +196,7 @@ public slots: bool bindFunctionExpression(const QString& expression); bool isNull(); + bool isMethod(); void __channelObjectErased(); From 3267640d6401ec612b143a5280b3ab2dcdf8ef00 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Fri, 18 Jun 2021 14:48:41 +0300 Subject: [PATCH 61/91] Palettes: Added support for event and function icons. --- plugins/editqml/qml/PaletteControls.qml | 2 +- plugins/editqml/qml/PropertyContainer.qml | 38 +++++++++++++++---- plugins/workspace/icons/icons.pro | 2 + plugins/workspace/icons/qml/EventIcon.qml | 11 ++++++ plugins/workspace/icons/qml/FunctionIcon.qml | 13 +++++++ plugins/workspace/icons/qml/qmldir | 2 + .../workspace/nodeeditor/qml/ObjectGraph.qml | 6 ++- .../nodeeditor/qml/ObjectNodeProperty.qml | 20 +++++++++- 8 files changed, 84 insertions(+), 10 deletions(-) create mode 100644 plugins/workspace/icons/qml/EventIcon.qml create mode 100644 plugins/workspace/icons/qml/FunctionIcon.qml diff --git a/plugins/editqml/qml/PaletteControls.qml b/plugins/editqml/qml/PaletteControls.qml index 2bc4a7f5..e3ea75fb 100644 --- a/plugins/editqml/qml/PaletteControls.qml +++ b/plugins/editqml/qml/PaletteControls.qml @@ -379,7 +379,7 @@ QtObject{ } } else if (isForNode && addBoxItem.activeIndex === 4 ){ - container.nodeParent.item.addSubobject(container.nodeParent, data, container.nodeParent.item.id ? ObjectGraph.PortMode.InPort : ObjectGraph.PortMode.Node, null) + container.nodeParent.item.addSubobject(container.nodeParent, data, container.nodeParent.item.id ? ObjectGraph.PortMode.InPort : ObjectGraph.PortMode.Node, null, {isMethod: true}) } if (isForNode) objectGraph.activateFocus() diff --git a/plugins/editqml/qml/PropertyContainer.qml b/plugins/editqml/qml/PropertyContainer.qml index cb362df5..4c2ab70b 100644 --- a/plugins/editqml/qml/PropertyContainer.qml +++ b/plugins/editqml/qml/PropertyContainer.qml @@ -1,6 +1,8 @@ import QtQuick 2.0 import editor 1.0 import editor.private 1.0 +import editqml 1.0 as EditQml +import workspace.icons 1.0 as Icons Item{ id: propertyContainer @@ -13,6 +15,7 @@ Item{ property Item paletteGroup : null property alias groupsContainer: container property QtObject editingFragment : null + property QtObject documentHandler : null property Item editor: null property Item valueContainer : null @@ -24,6 +27,9 @@ Item{ property var paletteControls: lk.layers.workspace.extensions.editqml.paletteControls + property Component methodIcon: Icons.MenuIcon{} + property Component eventIcon: Icons.EventIcon{ color: theme.colorScheme.middlegroundOverlayDominantBorder; width: 15; height: 15 } + property Connections editingFragmentRemovals: Connections{ target: editingFragment function onAboutToBeRemoved(){ @@ -56,11 +62,27 @@ Item{ radius: 3 border.width: theme.inputStyle.borderThickness border.color: theme.colorScheme.middlegroundBorder + + Loader{ + id: iconLoader + anchors.top: parent.top + anchors.topMargin: 6 + anchors.right: parent.right + anchors.rightMargin: 20 + sourceComponent: { + if ( !propertyContainer.editingFragment ) + return null + return propertyContainer.editingFragment.location === EditQml.QmlEditFragment.Slot + ? propertyContainer.eventIcon + : propertyContainer.editingFragment.isMethod() ? propertyContainer.methodIcon : null + } + } + Text{ anchors.left: parent.left anchors.leftMargin: 25 anchors.right: parent.right - anchors.rightMargin: 15 + anchors.rightMargin: iconLoader.sourceComponent ? 38 : 20 anchors.top: parent.top anchors.topMargin: 6 text: propertyContainer.title @@ -108,16 +130,18 @@ Item{ Item{ anchors.left: parent.left - anchors.leftMargin: 8 + anchors.leftMargin: 4 anchors.top: parent.top - anchors.topMargin: 2 + anchors.topMargin: 4 width: 15 height: 20 - Text{ - anchors.verticalCenter: parent.verticalCenter - text: 'x' - color: '#ffffff' + Icons.XIcon{ + width: 6 + height: 6 + strokeWidth: 1 + color: propertyContainer.theme.colorScheme.foregroundFaded } + MouseArea{ id: propertyCloseArea anchors.fill: parent diff --git a/plugins/workspace/icons/icons.pro b/plugins/workspace/icons/icons.pro index 67c3ba1c..fe8bfcb1 100644 --- a/plugins/workspace/icons/icons.pro +++ b/plugins/workspace/icons/icons.pro @@ -21,5 +21,7 @@ OTHER_FILES += \ DISTFILES += \ qml/BrushIcon.qml \ + qml/EventIcon.qml \ + qml/FunctionIcon.qml \ qml/GradientIcon.qml diff --git a/plugins/workspace/icons/qml/EventIcon.qml b/plugins/workspace/icons/qml/EventIcon.qml new file mode 100644 index 00000000..4c845299 --- /dev/null +++ b/plugins/workspace/icons/qml/EventIcon.qml @@ -0,0 +1,11 @@ +import QtQuick 2.3 +import visual.shapes 1.0 + +SvgView{ + property color color: 'white' + + content: + '' + + '' + + '' +} diff --git a/plugins/workspace/icons/qml/FunctionIcon.qml b/plugins/workspace/icons/qml/FunctionIcon.qml new file mode 100644 index 00000000..25a3e3e5 --- /dev/null +++ b/plugins/workspace/icons/qml/FunctionIcon.qml @@ -0,0 +1,13 @@ +import QtQuick 2.3 +import visual.shapes 1.0 + +SvgView{ + property color color: 'white' + + content: + '' + + '' + + '' +} + + diff --git a/plugins/workspace/icons/qml/qmldir b/plugins/workspace/icons/qml/qmldir index 3e465b76..51b64042 100644 --- a/plugins/workspace/icons/qml/qmldir +++ b/plugins/workspace/icons/qml/qmldir @@ -33,3 +33,5 @@ UndoIcon 1.0 UndoIcon.qml RedoIcon 1.0 RedoIcon.qml BrushIcon 1.0 BrushIcon.qml GradientIcon 1.0 GradientIcon.qml +EventIcon 1.0 EventIcon.qml +FunctionIcon 1.0 FunctionIcon.qml diff --git a/plugins/workspace/nodeeditor/qml/ObjectGraph.qml b/plugins/workspace/nodeeditor/qml/ObjectGraph.qml index 7afb196e..ab43a129 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectGraph.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectGraph.qml @@ -411,7 +411,7 @@ Rectangle{ return node } - function addObjectNodeProperty(node, propertyName, ports, editingFragment){ + function addObjectNodeProperty(node, propertyName, ports, editingFragment, options){ var item = node.item var propertyItem = root.propertyDelegate.createObject(item.propertyContainer) @@ -419,6 +419,10 @@ Rectangle{ propertyItem.node = node propertyItem.editingFragment = editingFragment + if ( options && options.hasOwnProperty('isMethod') ){ + propertyItem.isMethod = options.isMethod + } + var isForObject = propertyItem.isForObject propertyItem.width = node.item.width - (isForObject ? 30 : 0) diff --git a/plugins/workspace/nodeeditor/qml/ObjectNodeProperty.qml b/plugins/workspace/nodeeditor/qml/ObjectNodeProperty.qml index 8fa9b747..df373df8 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectNodeProperty.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectNodeProperty.qml @@ -4,6 +4,7 @@ import editor.private 1.0 import editqml 1.0 import workspace 1.0 as Workspace +import workspace.icons 1.0 as Icons import visual.input 1.0 as Input Item{ @@ -24,6 +25,10 @@ Item{ property var isForObject: editingFragment && editingFragment.location === QmlEditFragment.Object property var editor: null + property bool isMethod: false + + property Component methodIcon: Icons.FunctionIcon{ color: theme.colorScheme.foregroundFaded; width: 15; height: 15 } + property Component eventIcon: Icons.EventIcon{ color: theme.colorScheme.foregroundFaded; width: 15; height: 15 } property var paletteControls: lk.layers.workspace.extensions.editqml.paletteControls @@ -38,7 +43,6 @@ Item{ anchors.leftMargin: isForObject ? 30 : 0 height: propertyTitle.height + paletteContainer.height - property int contentWidth: 355 - anchors.leftMargin property QtObject defaultStyle : QtObject{ @@ -83,6 +87,7 @@ Item{ height: 30 Input.Label{ + id: propertyLabel anchors.verticalCenter : parent.verticalCenter anchors.left: parent.left anchors.leftMargin: 10 @@ -90,6 +95,19 @@ Item{ textStyle: propertyItem.style.textStyle } + Loader{ + id: iconLoader + anchors.verticalCenter: parent.verticalCenter + anchors.left: propertyLabel.right + anchors.leftMargin: 5 + sourceComponent: { + return propertyItem.editingFragment && propertyItem.editingFragment.location === QmlEditFragment.Slot + ? propertyItem.eventIcon + : propertyItem.isMethod ? propertyItem.methodIcon : null + } + } + + Item{ visible:!isForObject id: paletteAddButton From 3bcf3af5cb7e1789a742fdc86769e981dbed4353 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Fri, 18 Jun 2021 14:49:15 +0300 Subject: [PATCH 62/91] base.Stream: Added support for subscribing to multiple streams. --- lib/lvview/src/qmlstream.cpp | 159 ++++++++++++++++--- lib/lvview/src/qmlstream.h | 79 ++++++++- plugins/base/baseqml/src/qmlexec.cpp | 4 +- plugins/base/baseqml/src/qmlstreamfilter.cpp | 2 +- plugins/base/baseqml/src/qmlstreamlog.cpp | 4 +- plugins/base/baseqml/src/qmlstreamvalue.cpp | 7 +- plugins/base/baseqml/src/qmlstreamvalue.h | 1 + 7 files changed, 223 insertions(+), 33 deletions(-) diff --git a/lib/lvview/src/qmlstream.cpp b/lib/lvview/src/qmlstream.cpp index 62b584db..f73b3fc4 100644 --- a/lib/lvview/src/qmlstream.cpp +++ b/lib/lvview/src/qmlstream.cpp @@ -1,4 +1,5 @@ #include "qmlstream.h" +#include #include "live/viewcontext.h" #include "live/viewengine.h" @@ -6,50 +7,164 @@ namespace lv{ +// QmlStream::Observer +// ---------------------------------------------------------------------------- + +QmlStream::Observer::~Observer() +{ +} + +QmlStream::JsCallbackObserver::JsCallbackObserver(unsigned int id, QJSValue callback) + : Observer(id, QmlStream::Observer::JsCallback) + , m_callback(callback) +{ +} + +void QmlStream::JsCallbackObserver::push(ViewEngine* engine, QObject *object){ + m_callback.call(QJSValueList() << engine->engine()->newQObject(object)); +} + +void QmlStream::JsCallbackObserver::push(ViewEngine*, const QJSValue &value){ + m_callback.call(QJSValueList() << value); +} + + + +QmlStream::CppCallbackObserver::CppCallbackObserver(unsigned int id, QObject *object, QmlStream::CppCallbackObserver::CppCallback cb) + : Observer(id, QmlStream::Observer::CppCallback) + , m_object(object) + , m_callback(cb) +{ +} + +void QmlStream::CppCallbackObserver::push(ViewEngine *, const QJSValue &value){ + m_callback(m_object, value); +} + +void QmlStream::CppCallbackObserver::push(ViewEngine *engine, QObject *object){ + m_callback(m_object, engine->engine()->newQObject(object)); +} + +QObject *QmlStream::CppCallbackObserver::object(){ + return m_object; +} + +QmlStream::PropertyObserver::PropertyObserver(unsigned int id, QJSValue callback) + : Observer(id, QmlStream::Observer::Property) +{ + QObject* ob = callback.property(0).toQObject(); + QString prop = callback.property(1).toString(); + + m_callback = QQmlProperty(ob, prop); +} + +void QmlStream::PropertyObserver::push(ViewEngine*, const QJSValue &value){ + m_callback.write(value.toVariant()); +} + +void QmlStream::PropertyObserver::push(ViewEngine*, QObject *object){ + m_callback.write(QVariant::fromValue(object)); +} + +// QmlStream +// ---------------------------------------------------------------------------- + QmlStream::QmlStream(QObject *parent) : QObject(parent) - , m_object(nullptr) + , m_idCounter(1) + , m_observers(new std::list()) { - m_engine = lv::ViewContext::instance().engine()->engine(); + //TODO: Capture engine from component complete + m_engine = lv::ViewContext::instance().engine(); } QmlStream::~QmlStream(){ + delete m_observers; } void QmlStream::push(QObject *object){ - if ( m_callbackForward.isCallable() ){ - m_callbackForward.call(QJSValueList() << m_engine->newQObject(object)); - } else if ( m_objectForward.isWritable() ){ - m_objectForward.write(QVariant::fromValue(object)); - } else if ( m_object ){ - m_functionForward(m_object, m_engine->newQObject(object)); + for(auto it = m_observers->begin(); it != m_observers->end(); ++it ){ + QmlStream::Observer* observer = *it; + observer->push(m_engine, object); } } void QmlStream::push(const QJSValue &value){ - if ( m_callbackForward.isCallable() ){ - m_callbackForward.call(QJSValueList() << value); - } else if ( m_objectForward.isWritable() ){ - m_objectForward.write(value.toVariant()); - } else if ( m_object ){ - m_functionForward(m_object, value); + for(auto it = m_observers->begin(); it != m_observers->end(); ++it ){ + QmlStream::Observer* observer = *it; + observer->push(m_engine, value); + } +} + +QmlStream::Observer* QmlStream::forward(QObject *object, std::function fn){ + QmlStream::Observer* observer = new QmlStream::CppCallbackObserver(m_idCounter, object, fn); + incrementIdCounter(); + m_observers->push_back(observer); + return observer; +} + +void QmlStream::unsubscribeObject(QObject *object){ + auto it = m_observers->begin(); + while ( it != m_observers->end() ){ + QmlStream::Observer* observer = *it; + if ( observer->type() == QmlStream::Observer::CppCallback ){ + QmlStream::CppCallbackObserver* cppobserver = static_cast(observer); + if ( cppobserver->object() == object ){ + delete observer; + it = m_observers->erase(it); + continue; + } + } + ++it; } } -void QmlStream::forward(QObject *object, std::function fn){ - m_object = object; - m_functionForward = fn; +void QmlStream::unsubscribe(QmlStream::Observer *observer){ + for(auto it = m_observers->begin(); it != m_observers->end(); ++it ){ + QmlStream::Observer* o = *it; + if ( o == observer ){ + delete o; + m_observers->erase(it); + return; + } + } } -void QmlStream::forward(const QJSValue &callback){ +QJSValue QmlStream::forward(const QJSValue &callback){ if ( callback.isCallable() ){ - m_callbackForward = callback; + m_observers->push_back(new QmlStream::JsCallbackObserver(m_idCounter, callback)); } else if ( callback.isArray() && callback.property("length").toInt() == 2 ){ - QObject* ob = callback.property(0).toQObject(); - QString prop = callback.property(1).toString(); + m_observers->push_back(new QmlStream::PropertyObserver(m_idCounter, callback)); + } + QJSValue observerId(m_idCounter); + incrementIdCounter(); + return observerId; +} - m_objectForward = QQmlProperty(ob, prop); +bool QmlStream::unsubscribe(const QJSValue &val){ + unsigned int id = val.toUInt(); + for(auto it = m_observers->begin(); it != m_observers->end(); ++it ){ + QmlStream::Observer* o = *it; + if ( o->id() == id ){ + delete o; + m_observers->erase(it); + return true; + } } + return false; } +void QmlStream::incrementIdCounter(){ + m_idCounter++; + if ( m_idCounter == std::numeric_limits::max() ) + m_idCounter = 1; +} + +void QmlStream::clearObservers(){ + for(auto it = m_observers->begin(); it != m_observers->end(); ++it ) + delete *it; + m_observers->clear(); +} + + }// namespace diff --git a/lib/lvview/src/qmlstream.h b/lib/lvview/src/qmlstream.h index 13c893e8..dbb61bf8 100644 --- a/lib/lvview/src/qmlstream.h +++ b/lib/lvview/src/qmlstream.h @@ -9,10 +9,72 @@ namespace lv{ +class ViewEngine; class LV_VIEW_EXPORT QmlStream : public QObject{ Q_OBJECT +public: + class LV_VIEW_EXPORT Observer{ + + public: + enum Type{ + JsCallback, + CppCallback, + Property + }; + + public: + virtual ~Observer(); + + Type type(){ return m_type; } + unsigned int id(){ return m_id; } + + virtual void push(ViewEngine* engine, const QJSValue& value) = 0; + virtual void push(ViewEngine* engine, QObject* object) = 0; + + protected: + Observer(unsigned int id, Type type) : m_id(id), m_type(type){} + + private: + unsigned int m_id; + Type m_type; + }; + +private: + class JsCallbackObserver : public Observer{ + public: + JsCallbackObserver(unsigned int id, QJSValue callback); + void push(ViewEngine* engine, const QJSValue& value) override; + void push(ViewEngine* engine, QObject* object) override; + private: + QJSValue m_callback; + }; + + class CppCallbackObserver : public Observer{ + public: + typedef std::function CppCallback; + + CppCallbackObserver(unsigned int id, QObject* object, CppCallback cb); + void push(ViewEngine* engine, const QJSValue& value) override; + void push(ViewEngine* engine, QObject* object) override; + QObject* object(); + + private: + QObject* m_object; + CppCallback m_callback; + }; + + class PropertyObserver : public Observer{ + public: + PropertyObserver(unsigned int id, QJSValue callback); + void push(ViewEngine* engine, const QJSValue& value) override; + void push(ViewEngine* engine, QObject* object) override; + private: + QQmlProperty m_callback; + }; + + public: explicit QmlStream(QObject *parent = nullptr); ~QmlStream(); @@ -20,18 +82,21 @@ class LV_VIEW_EXPORT QmlStream : public QObject{ void push(QObject* object); void push(const QJSValue& value); - void forward(QObject* object, std::function fn); + Observer* forward(QObject* object, std::function fn); + void unsubscribeObject(QObject* object); + void unsubscribe(Observer* observer); public slots: - void forward(const QJSValue& callback); + QJSValue forward(const QJSValue& callback); + bool unsubscribe(const QJSValue& val); private: - QQmlEngine* m_engine; - QJSValue m_callbackForward; - QQmlProperty m_objectForward; + void incrementIdCounter(); + void clearObservers(); - QObject* m_object; - std::function m_functionForward; + ViewEngine* m_engine; + unsigned int m_idCounter; + std::list* m_observers; }; }// namespace diff --git a/plugins/base/baseqml/src/qmlexec.cpp b/plugins/base/baseqml/src/qmlexec.cpp index 7ba1147c..baa17417 100644 --- a/plugins/base/baseqml/src/qmlexec.cpp +++ b/plugins/base/baseqml/src/qmlexec.cpp @@ -22,6 +22,8 @@ QmlExec::QmlExec(QObject *parent) } QmlExec::~QmlExec(){ + if ( m_in ) + m_in->unsubscribeObject(this); } void QmlExec::componentComplete(){ @@ -59,7 +61,7 @@ void QmlExec::setInput(QmlStream *in){ return; if ( m_in ) - m_in->forward(nullptr, nullptr); + m_in->unsubscribeObject(this); m_in = in; emit inChanged(); diff --git a/plugins/base/baseqml/src/qmlstreamfilter.cpp b/plugins/base/baseqml/src/qmlstreamfilter.cpp index 836739d3..eb274337 100644 --- a/plugins/base/baseqml/src/qmlstreamfilter.cpp +++ b/plugins/base/baseqml/src/qmlstreamfilter.cpp @@ -67,7 +67,7 @@ void QmlStreamFilter::setPull(QmlStream *pull){ return; if ( m_pull ) - m_pull->forward(nullptr, nullptr); + m_pull->unsubscribeObject(this); m_pull = pull; m_pull->forward(this, &QmlStreamFilter::streamHandler); diff --git a/plugins/base/baseqml/src/qmlstreamlog.cpp b/plugins/base/baseqml/src/qmlstreamlog.cpp index 8947b397..36e7dcdd 100644 --- a/plugins/base/baseqml/src/qmlstreamlog.cpp +++ b/plugins/base/baseqml/src/qmlstreamlog.cpp @@ -16,7 +16,7 @@ void QmlStreamLog::setStream(QmlStream *stream){ return; if ( m_stream ){ - m_stream->forward(nullptr, nullptr); + m_stream->unsubscribeObject(this); } m_stream = stream; @@ -36,6 +36,8 @@ void QmlStreamLog::onStreamData(QObject *that, const QJSValue &val){ } QmlStreamLog::~QmlStreamLog(){ + if ( m_stream ) + m_stream->unsubscribeObject(this); } }// namespace diff --git a/plugins/base/baseqml/src/qmlstreamvalue.cpp b/plugins/base/baseqml/src/qmlstreamvalue.cpp index 18109160..d58a8a70 100644 --- a/plugins/base/baseqml/src/qmlstreamvalue.cpp +++ b/plugins/base/baseqml/src/qmlstreamvalue.cpp @@ -13,6 +13,11 @@ QmlStreamValue::QmlStreamValue(QObject *parent) { } +QmlStreamValue::~QmlStreamValue(){ + if ( m_stream ) + m_stream->unsubscribeObject(this); +} + void QmlStreamValue::streamHandler(QObject *that, const QJSValue &val){ QmlStreamValue* sf = static_cast(that); sf->m_current = val; @@ -57,7 +62,7 @@ void QmlStreamValue::updateFollowsObject(){ QmlStreamFilter* filter = qobject_cast(m_follow); if ( filter ){ if( m_stream ) - m_stream->forward(nullptr, nullptr); + m_stream->unsubscribeObject(this); if ( filter->pull() ){ m_stream = filter->pull(); diff --git a/plugins/base/baseqml/src/qmlstreamvalue.h b/plugins/base/baseqml/src/qmlstreamvalue.h index 42cd8df6..76a52075 100644 --- a/plugins/base/baseqml/src/qmlstreamvalue.h +++ b/plugins/base/baseqml/src/qmlstreamvalue.h @@ -16,6 +16,7 @@ class QmlStreamValue : public QObject, public QQmlParserStatus{ public: explicit QmlStreamValue(QObject *parent = nullptr); + ~QmlStreamValue(); lv::QmlStream* stream() const; void setStream(lv::QmlStream* stream); From f3c336376d296bf1201fb4b7376d7be722498655 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Fri, 18 Jun 2021 17:11:45 +0300 Subject: [PATCH 63/91] FirstTimeStartupBox: Fixed popping up in some scenarios after the user clicks no. --- application/qml/StartupBox.qml | 2 +- lib/lveditor/src/workspace.cpp | 47 +++++++++++++++++------------ lib/lveditor/src/workspace.h | 4 ++- lib/lveditor/src/workspacelayer.cpp | 4 +++ lib/lveditor/src/workspacelayer.h | 2 ++ 5 files changed, 38 insertions(+), 21 deletions(-) diff --git a/application/qml/StartupBox.qml b/application/qml/StartupBox.qml index e8f54441..14de34f3 100644 --- a/application/qml/StartupBox.qml +++ b/application/qml/StartupBox.qml @@ -167,7 +167,6 @@ Rectangle{ font.weight: Font.Light } - Rectangle { width: parent.width height: 5 @@ -588,6 +587,7 @@ Rectangle{ hoverEnabled: true onClicked: { noThanks = true + lk.layers.workspace.saveRecentsToFile() } } diff --git a/lib/lveditor/src/workspace.cpp b/lib/lveditor/src/workspace.cpp index a0d50943..92e5e62e 100644 --- a/lib/lveditor/src/workspace.cpp +++ b/lib/lveditor/src/workspace.cpp @@ -73,7 +73,7 @@ Workspace::Workspace(Project *project, WorkspaceLayer *parent) Workspace::~Workspace(){ delete m_currentProjectWorkspace; - saveRecents(); + saveRecentsIfChanged(); delete m_recentsModel; } @@ -122,26 +122,13 @@ void Workspace::whenProjectPathChange(const QString &path){ } } -void Workspace::saveRecents(){ - QString recentsPath = absolutePath("workspaces.json"); - QFile recentsFile(recentsPath); - int modelSize = m_recentsModel->rowCount(QModelIndex()); - if ( (m_recentsChanged || modelSize == 0) && recentsFile.open(QIODevice::WriteOnly) ){ - MLNode recents(MLNode::Array); - for (int i = 0; i < modelSize; ++i) - recents.append(MLNode(m_recentsModel->entryAt(i).m_path.toStdString())); - - MLNode n(MLNode::Object); - n["projects"] = recents; - - std::string result; - ml::toJson(n, result); +//HERE - vlog("appdata").v() << "Saving projects to: " << recentsPath; +void Workspace::saveRecentsIfChanged(){ + if ( !m_recentsChanged ) + return; - recentsFile.write(result.c_str()); - recentsFile.close(); - } + saveRecents(); } @@ -177,4 +164,26 @@ StartupModel *Workspace::recents() return m_recentsModel; } +void Workspace::saveRecents(){ + QString recentsPath = absolutePath("workspaces.json"); + QFile recentsFile(recentsPath); + int modelSize = m_recentsModel->rowCount(QModelIndex()); + if ( recentsFile.open(QIODevice::WriteOnly) ){ + MLNode recents(MLNode::Array); + for (int i = 0; i < modelSize; ++i) + recents.append(MLNode(m_recentsModel->entryAt(i).m_path.toStdString())); + + MLNode n(MLNode::Object); + n["projects"] = recents; + + std::string result; + ml::toJson(n, result); + + vlog("appdata").v() << "Saving projects to: " << recentsPath; + + recentsFile.write(result.c_str()); + recentsFile.close(); + } +} + }// namespace diff --git a/lib/lveditor/src/workspace.h b/lib/lveditor/src/workspace.h index 9e20968a..33cb6353 100644 --- a/lib/lveditor/src/workspace.h +++ b/lib/lveditor/src/workspace.h @@ -63,6 +63,8 @@ class LV_EDITOR_EXPORT Workspace : public QObject{ bool wasRecentsFileFound() const; StartupModel* recents(); + void saveRecents(); + signals: void projectOpen(const QString& path); void projectInitialized(const QString& path, ProjectWorkspace* workspace); @@ -73,7 +75,7 @@ public slots: private: - void saveRecents(); + void saveRecentsIfChanged(); Project* m_project; ProjectWorkspace* m_currentProjectWorkspace; diff --git a/lib/lveditor/src/workspacelayer.cpp b/lib/lveditor/src/workspacelayer.cpp index 24899feb..d9e5456b 100644 --- a/lib/lveditor/src/workspacelayer.cpp +++ b/lib/lveditor/src/workspacelayer.cpp @@ -428,6 +428,10 @@ void WorkspaceLayer::cancelTooltip(QObject *tooltip){ } } +void WorkspaceLayer::saveRecentsToFile(){ + m_workspace->saveRecents(); +} + void WorkspaceLayer::__tooltipDestroyed(){ if ( m_tooltip ){ QObject* contentBox = m_tooltip->property("contentBox").value(); diff --git a/lib/lveditor/src/workspacelayer.h b/lib/lveditor/src/workspacelayer.h index 03b0039c..2fb88b89 100644 --- a/lib/lveditor/src/workspacelayer.h +++ b/lib/lveditor/src/workspacelayer.h @@ -84,6 +84,8 @@ public slots: void triggerTooltip(QObject* tooltip); void cancelTooltip(QObject* tooltip); + void saveRecentsToFile(); + void __tooltipDestroyed(); void __tooltipTimeout(); From 6cb1b90cd20042c6895161d90186d0dbd02196b9 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Fri, 18 Jun 2021 18:04:40 +0300 Subject: [PATCH 64/91] base.Act: Added support for trigger configuration. --- lib/lveditqmljs/lveditqmljs.pro | 2 +- plugins/base/baseqml/src/qmlact.cpp | 20 +++++++++++++++--- plugins/base/baseqml/src/qmlact.h | 32 +++++++++++++++++++++++++++-- 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/lib/lveditqmljs/lveditqmljs.pro b/lib/lveditqmljs/lveditqmljs.pro index b9a78ef0..565a02cd 100644 --- a/lib/lveditqmljs/lveditqmljs.pro +++ b/lib/lveditqmljs/lveditqmljs.pro @@ -21,7 +21,7 @@ macx{ QMAKE_SONAME_PREFIX = @rpath/Live.framework/Libraries } -#ENABLE_PLUGINTYPES = true +ENABLE_PLUGINTYPES = true !isEmpty(ENABLE_PLUGINTYPES){ message(Plugin Types Enabled: Livekeys will use private libraries) diff --git a/plugins/base/baseqml/src/qmlact.cpp b/plugins/base/baseqml/src/qmlact.cpp index 29f54302..e94ae8a1 100644 --- a/plugins/base/baseqml/src/qmlact.cpp +++ b/plugins/base/baseqml/src/qmlact.cpp @@ -25,6 +25,7 @@ namespace lv{ QmlAct::QmlAct(QObject *parent) : QObject(parent) , m_isComponentComplete(false) + , m_trigger(QmlAct::PropertyChange) , m_worker(nullptr) , m_source(nullptr) , m_currentTask(nullptr) @@ -68,9 +69,16 @@ void QmlAct::componentComplete(){ for ( int i = 0; i < meta->propertyCount(); i++ ){ QMetaProperty property = meta->property(i); QByteArray name = property.name(); - if ( name != "objectName" && name != "result" ){ + if ( name != "objectName" && + name != "run" && + name != "args" && + name != "returns" && + name != "result" && + name != "trigger" && + name != "worker") + { QQmlProperty pp(this, name); - pp.connectNotifySignal(this, SLOT(exec())); + pp.connectNotifySignal(this, SLOT(__propertyChange())); } } @@ -79,7 +87,7 @@ void QmlAct::componentComplete(){ void QmlAct::setArgs(QJSValue args){ if ( m_isComponentComplete ){ - Exception e = CREATE_EXCEPTION(lv::Exception, "ActFn: Cannot configure arguments after component is complete.", Exception::toCode("~ActFnConfig")); + Exception e = CREATE_EXCEPTION(lv::Exception, "Act: Cannot configure arguments after component is complete.", Exception::toCode("~ActFnConfig")); ViewContext::instance().engine()->throwError(&e, this); return; } @@ -211,6 +219,12 @@ void QmlAct::exec(){ } } +void QmlAct::__propertyChange(){ + if ( m_trigger == QmlAct::PropertyChange ){ + exec(); + } +} + bool QmlAct::event(QEvent *ev){ QmlWorkerPool::TaskReadyEvent* tr = dynamic_cast(ev); if (!tr) diff --git a/plugins/base/baseqml/src/qmlact.h b/plugins/base/baseqml/src/qmlact.h index e8d0aee9..9eb0be88 100644 --- a/plugins/base/baseqml/src/qmlact.h +++ b/plugins/base/baseqml/src/qmlact.h @@ -16,14 +16,21 @@ namespace lv{ class LV_BASEQML_EXPORT QmlAct : public QObject, public QQmlParserStatus{ Q_OBJECT + Q_ENUMS(Trigger) Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(QJSValue run READ run WRITE setRun NOTIFY runChanged) Q_PROPERTY(QJSValue args READ args WRITE setArgs NOTIFY argsChanged) Q_PROPERTY(QString returns READ returns WRITE setReturns NOTIFY returnsChanged) Q_PROPERTY(QJSValue result READ result NOTIFY resultChanged) + Q_PROPERTY(Trigger trigger READ trigger WRITE setTrigger NOTIFY triggerChanged) Q_PROPERTY(lv::QmlWorkerInterface* worker READ worker WRITE setWorker NOTIFY workerChanged) public: + enum Trigger{ + PropertyChange, + Manual + }; + class RunSource{ public: RunSource(ComponentDeclaration cd) : declarationLocation(cd){} @@ -44,9 +51,10 @@ class LV_BASEQML_EXPORT QmlAct : public QObject, public QQmlParserStatus{ virtual void process(){} void setRun(QJSValue run); + const QJSValue& run() const; + void setArgs(QJSValue args); const QJSValue& args() const; - const QJSValue& run() const; void setResult(const QJSValue& result); void setResult(const QVariant& result); @@ -55,12 +63,17 @@ class LV_BASEQML_EXPORT QmlAct : public QObject, public QQmlParserStatus{ void setReturns(QString returns); lv::QmlWorkerInterface* worker() const; + void setWorker(lv::QmlWorkerInterface* worker); bool event(QEvent *event) override; + Trigger trigger() const; + void setTrigger(Trigger trigger); + public slots: void exec(); - void setWorker(lv::QmlWorkerInterface* worker); + + void __propertyChange(); signals: void complete(); @@ -69,6 +82,8 @@ public slots: void argsChanged(); void workerChanged(); void returnsChanged(); + void triggerChanged(); + protected: void classBegin() override{} @@ -78,6 +93,7 @@ public slots: void extractSource(ViewEngine* engine); bool m_isComponentComplete; + Trigger m_trigger; QJSValue m_result; QJSValue m_run; QJSValue m_args; @@ -115,6 +131,18 @@ inline QmlWorkerInterface *QmlAct::worker() const{ return m_worker; } +inline QmlAct::Trigger QmlAct::trigger() const{ + return m_trigger; +} + +inline void QmlAct::setTrigger(QmlAct::Trigger trigger){ + if (m_trigger == trigger) + return; + + m_trigger = trigger; + emit triggerChanged(); +} + } // namespace #endif // LVQMLACT_H From 1707791f29bd5b2a7a8888d45a08efaae8329d47 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Fri, 18 Jun 2021 22:11:18 +0300 Subject: [PATCH 65/91] Palettes: Added support for inheritance based search, and property palettes. --- lib/lveditqmljs/src/codeqmlhandler.cpp | 27 ++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/lib/lveditqmljs/src/codeqmlhandler.cpp b/lib/lveditqmljs/src/codeqmlhandler.cpp index e45e4a00..8b073417 100644 --- a/lib/lveditqmljs/src/codeqmlhandler.cpp +++ b/lib/lveditqmljs/src/codeqmlhandler.cpp @@ -2590,6 +2590,7 @@ lv::PaletteList* CodeQmlHandler::findPalettes(int position, bool includeLayoutCo cancelEdit(); QList declarations = getDeclarations(position); + return declarations.isEmpty() ? nullptr : findPalettesForDeclaration(declarations.first(), includeLayoutConfigurations); } @@ -3824,11 +3825,37 @@ PaletteList *CodeQmlHandler::findPalettesForDeclaration(QmlDeclaration::Ptr decl // every fragment has a declaration -> should end up here Q_D(CodeQmlHandler); + QmlScopeSnap scope = d->snapScope(); PaletteContainer::PaletteSearch configurations = includeLayoutConfigurations ? PaletteContainer::IncludeLayoutConfigurations : PaletteContainer::Empty; PaletteList* lpl = d->projectHandler->paletteContainer()->findPalettes(declaration->type().join(), configurations); + if ( declaration->type().language() == QmlTypeReference::Qml ){ + QmlInheritanceInfo typePath = scope.getTypePath(declaration->type()); + for ( int i = 1; i < typePath.nodes.size(); ++i ){ + QmlTypeInfo::Ptr ti = typePath.nodes[i]; + if ( !ti->exportType().isEmpty() ){ + lpl = d->projectHandler->paletteContainer()->findPalettes(ti->exportType().join(), configurations, lpl); + } + } + } + + if ( declaration->isForProperty() && declaration->parentType().language() == QmlTypeReference::Qml && !declaration->identifierChain().isEmpty() ){ + QmlInheritanceInfo typePath = scope.getTypePath(declaration->parentType()); + + for ( auto it = typePath.nodes.begin(); it != typePath.nodes.end(); ++it ){ + QmlTypeInfo::Ptr ti = *it; + QmlPropertyInfo pi = ti->propertyAt(declaration->identifierChain().last()); + + if ( pi.isValid() && !ti->exportType().isEmpty() ){ + QString propSearch = ti->exportType().join() + "." + pi.name; + lpl = d->projectHandler->paletteContainer()->findPalettes(propSearch, configurations, lpl); + } + } + } + + if (declaration->isForComponent()){ lpl = d->projectHandler->paletteContainer()->findPalettes("qml/Component", configurations, lpl); } else { From fa42d356021d69c17d0b86f75abcd8ff45a56270 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Fri, 18 Jun 2021 22:14:15 +0300 Subject: [PATCH 66/91] Palettes: Added Act.trigger palette. --- plugins/base/baseqml/baseqml.pro | 1 + .../palettes/ActTriggerTypePalette.qml | 94 +++++++++++++++++++ plugins/base/baseqml/qml/live.plugin.json | 1 + plugins/base/baseqml/qml/plugins.qmltypes | 20 +++- 4 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 plugins/base/baseqml/palettes/ActTriggerTypePalette.qml diff --git a/plugins/base/baseqml/baseqml.pro b/plugins/base/baseqml/baseqml.pro index 122b9d97..e0c46207 100644 --- a/plugins/base/baseqml/baseqml.pro +++ b/plugins/base/baseqml/baseqml.pro @@ -49,6 +49,7 @@ QMAKE_EXTRA_TARGETS += first palettecopy samplescopy DISTFILES += \ + palettes/ActTriggerTypePalette.qml \ palettes/StreamValuePalette.json \ qml/ConvertToInt.qml \ qml/JsonDecoder.qml \ diff --git a/plugins/base/baseqml/palettes/ActTriggerTypePalette.qml b/plugins/base/baseqml/palettes/ActTriggerTypePalette.qml new file mode 100644 index 00000000..28ec5adc --- /dev/null +++ b/plugins/base/baseqml/palettes/ActTriggerTypePalette.qml @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2014-2019 Dinu SV. +** (contact: mail@dinusv.com) +** This file is part of Livekeys Application. +** +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +****************************************************************************/ + +import QtQuick 2.3 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.4 +import editor 1.0 +import live 1.0 +import base 1.0 +import visual.input 1.0 as Input + +CodePalette{ + id: palette + + type: "qml/base#Act.trigger" + + property QtObject theme: lk.layers.workspace.themes.current + + item: Input.DropDown { + id: dropdown + width: 150 + model: ["PropertyChange", "Manual"] + property var values: [ + Act.PropertyChange, + Act.Manual + ] + + function baseQualifier(){ + var imports = editFragment.codeHandler.importsModel() + if (!imports) + return '' + + var baseImport = imports.getImportAtUri('base') + if (!baseImport) + return '' + + return baseImport.as.length ? baseImport.as : '' + } + + onCurrentIndexChanged: { + if ( isBindingChange() ) + return + if (!editFragment) + return + + var type = values[dropdown.currentIndex] + var qual = baseQualifier() + palette.value = type + + if (qual.length){ + var writeValue = qual + ".Act." + model[dropdown.currentIndex] + editFragment.write({ + "__ref": writeValue + }) + } else { + editFragment.write({ + '__ref' : "Act." + model[dropdown.currentIndex] + }) + } + } + } + + onValueFromBindingChanged: { + if ( value === Act.Manual ){ + dropdown.currentIndex = 1 + } else { + dropdown.currentIndex = 0 + } + } + onInit: { + if ( value === Act.Manual ){ + dropdown.currentIndex = 1 + } else { + dropdown.currentIndex = 0 + } + } + + onEditFragmentChanged: { + editFragment.whenBinding = function(){} + } +} diff --git a/plugins/base/baseqml/qml/live.plugin.json b/plugins/base/baseqml/qml/live.plugin.json index 1ce75cc0..1d0e52dc 100644 --- a/plugins/base/baseqml/qml/live.plugin.json +++ b/plugins/base/baseqml/qml/live.plugin.json @@ -4,6 +4,7 @@ "libraryModules" : ["lvbase"], "palettes" : { "palettes/ExecPalette.qml" : "qml/base#Exec", + "palettes/ActTriggerTypePalette.qml" : "qml/base#Act.trigger", "palettes/StreamValuePalette.json" : "qml/base#StreamValue" } } diff --git a/plugins/base/baseqml/qml/plugins.qmltypes b/plugins/base/baseqml/qml/plugins.qmltypes index 94218bbd..42445bf8 100644 --- a/plugins/base/baseqml/qml/plugins.qmltypes +++ b/plugins/base/baseqml/qml/plugins.qmltypes @@ -103,17 +103,22 @@ Module { prototype: "QObject" exports: ["base/Act 1.0"] exportMetaObjectRevisions: [0] + Enum { + name: "Trigger" + values: { + "PropertyChange": 0, + "Manual": 1 + } + } Property { name: "run"; type: "QJSValue" } Property { name: "args"; type: "QJSValue" } Property { name: "returns"; type: "QString" } Property { name: "result"; type: "QJSValue"; isReadonly: true } + Property { name: "trigger"; type: "Trigger" } Property { name: "worker"; type: "lv::QmlWorkerInterface"; isPointer: true } Signal { name: "complete" } Method { name: "exec" } - Method { - name: "setWorker" - Parameter { name: "worker"; type: "lv::QmlWorkerInterface"; isPointer: true } - } + Method { name: "__propertyChange" } } Component { name: "lv::QmlClipboard" @@ -189,6 +194,7 @@ Module { } Method { name: "run" } Method { name: "closeInput" } + Method { name: "stop" } } Component { name: "lv::QmlFollowUp" @@ -298,8 +304,14 @@ Module { exportMetaObjectRevisions: [0] Method { name: "forward" + type: "QJSValue" Parameter { name: "callback"; type: "QJSValue" } } + Method { + name: "unsubscribe" + type: "bool" + Parameter { name: "val"; type: "QJSValue" } + } } Component { name: "lv::QmlStreamFilter" From 143472b6d26e7a8396844389c7dd2cd5d53f111c Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Fri, 18 Jun 2021 22:16:18 +0300 Subject: [PATCH 67/91] Updated plugin types. --- lib/lveditqmljs/lveditqmljs.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/lveditqmljs/lveditqmljs.pro b/lib/lveditqmljs/lveditqmljs.pro index 565a02cd..b9a78ef0 100644 --- a/lib/lveditqmljs/lveditqmljs.pro +++ b/lib/lveditqmljs/lveditqmljs.pro @@ -21,7 +21,7 @@ macx{ QMAKE_SONAME_PREFIX = @rpath/Live.framework/Libraries } -ENABLE_PLUGINTYPES = true +#ENABLE_PLUGINTYPES = true !isEmpty(ENABLE_PLUGINTYPES){ message(Plugin Types Enabled: Livekeys will use private libraries) From 164874830dbc9ca7572df638897f15b16597dac7 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Sun, 20 Jun 2021 18:45:44 +0300 Subject: [PATCH 68/91] Updated pane functions and documentation. Moved workspace pane functions to PaneEnvironment. PaneEnvironment: Added support for pane insertion. Commands: Added 'add editor pane'. Added workspace.panes documentation. Moved editorPane, palettePane and objectPalettePane to workspace extension. --- application/application.qrc | 3 +- application/qml/LogContainer.qml | 8 +- application/qml/LogWindow.qml | 42 -- application/qml/PaneEnvironment.qml | 525 ++++++++++++++++++ application/qml/ProjectEnvironment.qml | 6 +- application/qml/RunView.qml | 8 +- application/qml/StartupBox.qml | 2 +- application/qml/Top.qml | 2 +- application/qml/Viewer.qml | 8 +- application/qml/workspace.qml | 511 ++--------------- doc/pages/layer-workspace-panes.md | 225 ++++++++ lib/lveditor/src/workspacelayer.cpp | 17 +- lib/lveditor/src/workspacelayer.h | 8 + plugins/editor/qml/ContextMenuStyle.qml | 57 -- plugins/editor/qml/EditorPane.qml | 14 +- plugins/editor/qml/Pane.qml | 24 +- plugins/editor/qml/PaneSplitView.qml | 74 ++- plugins/editor/qml/PaneWindow.qml | 12 +- plugins/editor/qml/qmldir | 1 - plugins/editqml/qml/PaletteContainer.qml | 4 +- plugins/editqml/qml/PaletteControls.qml | 4 +- plugins/lcvcore/qml/EditCvExtension.qml | 33 +- .../workspace}/qml/ContextMenu.qml | 0 .../qml/WorkspaceControlsExtension.qml | 61 ++ plugins/workspace/qml/qmldir | 1 + 25 files changed, 991 insertions(+), 659 deletions(-) delete mode 100644 application/qml/LogWindow.qml create mode 100644 application/qml/PaneEnvironment.qml create mode 100644 doc/pages/layer-workspace-panes.md delete mode 100644 plugins/editor/qml/ContextMenuStyle.qml rename {application => plugins/workspace}/qml/ContextMenu.qml (100%) diff --git a/application/application.qrc b/application/application.qrc index 1d30a9ce..7cda53da 100644 --- a/application/application.qrc +++ b/application/application.qrc @@ -1,6 +1,5 @@ - qml/LogWindow.qml qml/Top.qml qml/ProjectEnvironment.qml qml/MessageDialogInternal.qml @@ -25,9 +24,9 @@ qml/DocumentationViewPane.qml qml/TextEditNodeView.qml qml/StartupBox.qml - qml/ContextMenu.qml qml/Viewer.qml qml/MessagesContainer.qml + qml/PaneEnvironment.qml fonts/UbuntuMono-Bold.ttf diff --git a/application/qml/LogContainer.qml b/application/qml/LogContainer.qml index 94380d47..d1f294ed 100644 --- a/application/qml/LogContainer.qml +++ b/application/qml/LogContainer.qml @@ -379,8 +379,8 @@ Pane{ onClicked : { logMenu.visible = false var clone = root.paneClone() - var index = root.parentSplitterIndex() - lk.layers.workspace.panes.splitPaneHorizontallyWith(root.parentSplitter, index, clone) + var index = root.parentSplitViewIndex() + lk.layers.workspace.panes.splitPaneHorizontallyWith(root.parentSplitView, index, clone) } } @@ -390,8 +390,8 @@ Pane{ onClicked : { logMenu.visible = false var clone = root.paneClone() - var index = root.parentSplitterIndex() - lk.layers.workspace.panes.splitPaneVerticallyWith(root.parentSplitter, index, clone) + var index = root.parentSplitViewIndex() + lk.layers.workspace.panes.splitPaneVerticallyWith(root.parentSplitView, index, clone) } } diff --git a/application/qml/LogWindow.qml b/application/qml/LogWindow.qml deleted file mode 100644 index 77288d1a..00000000 --- a/application/qml/LogWindow.qml +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ - -import QtQuick 2.0 -import QtQuick.Window 2.1 -import QtQuick.Controls 1.2 -import QtQuick.Controls.Styles 1.2 - -Window { - id : root - width: 400 - height: 200 - title: "Livekeys Log" - color : "#081017" - - property alias contentWidth : container.width - property alias contentHeight : container.height - - property Item content : null - - signal itemAdded() - - Item{ - id: container - anchors.fill: parent - children: root.content ? [root.content] : [] - } - -} diff --git a/application/qml/PaneEnvironment.qml b/application/qml/PaneEnvironment.qml new file mode 100644 index 00000000..f67aac22 --- /dev/null +++ b/application/qml/PaneEnvironment.qml @@ -0,0 +1,525 @@ +import QtQuick 2.3 +import workspace 1.0 + +QtObject{ + id: root + property Item activePane : null + property Item activeItem : null + property Item container : null + + property Item paneDropArea: null + property ContextMenu contextMenu: null + +// property var logsOpened: [] + + property QtObject style: QtObject{ + property color splitterColor: 'transparent' + } + + property var openWindows : [] + + property QtObject __factories: QtObject{ + + property ProjectFileSystem projectFileSystem: ProjectFileSystem{ + id: projectView + width: 300 + panes: root + } + + property Item viewer : Viewer { + id: viewer + panes: root + } + + property Component runView: Component{ + RunView{ + id: runViewComponent + panes: root + } + } + + property Component documentation: Component{ + DocumentationViewPane{ + id: documentationViewComponent + panes: root + } + } + + property Component log: Component{ + LogContainer{ + id: logView + isInWindow: false + width: 300 + height: 200 + } + } + + property LogContainer mainLog : LogContainer{ + visible: false + isInWindow: false + width: 300 + height: 200 + + //HERE: Fix this + + onItemAdded: { + if ( !parent ) + header.isLogWindowDirty = true + } + } + } + + property var types : { + return { + "projectFileSystem" : { + create : function(p, s){ + if ( s ) + root.__factories.projectFileSystem.paneInitialize(s) + return root.__factories.projectFileSystem + }, + single: true + }, + "viewer" : { + create: function(p, s){ + return root.__factories.viewer + }, + single: true + }, + "runView" : { + create: function(p, s){ + var pane = root.__factories.runView.createObject(p) + if ( s ) + pane.paneInitialize(s) + return pane + }, + single: false + }, + "documentation" : { + create: function(p, s){ + var pane = root.__factories.documentation.createObject(p) + if ( s ) + pane.paneInitialize(s) + return pane + }, + single: false + }, + "log" : { + create: function(p, s){ + if ( !root.__factories.mainLog.parent ){ + root.__factories.mainLog.visible = true + root.__factories.mainLog.parent = p + header.isLogWindowDirty = false + return root.__factories.mainLog + } else { + var pane = root.__factories.log.createObject(p) + return pane + } + }, + single: false + } + } + } + + property var initializePanes: function(windowConfiguration, paneConfiguration){ + lk.layers.workspace.startup.close() + + var currentWindowPanes = paneConfiguration[0] + + var initializeStructure = [ + [lk.layers.window.window()], + [initializeSplitterPanes(container, currentWindowPanes)] + ] + + for ( var i = 1; i < paneConfiguration.length; ++i ){ + var window = paneWindowFactory.createObject(root) + openWindows.push(window) + initializeStructure[0].push(window) + initializeStructure[1].push(initializeSplitterPanes(window.mainSplit, paneConfiguration[i])) + + window.closing.connect(function(){ + var index = openWindows.indexOf(window); + if (index > -1) { + openWindows.splice(index, 1); + } + }) + } + + return initializeStructure + } + + property var createPane: function(paneType, paneState, paneSize){ + + if ( paneType in root.types ){ + var paneFactory = root.types[paneType] + var paneObject = paneFactory.create(null, paneState) + if ( paneSize ){ + paneObject.width = paneSize[0] + paneObject.height = paneSize[1] + } + + return paneObject + + } else { + throw new Error('Pane type not found: ' + paneType) + } + } + + property var movePaneToNewWindow : function(pane){ + removePane(pane) + + var window = paneWindowFactory.createObject(root) + openWindows.push(window) + + window.closing.connect(function(){ + var index = openWindows.indexOf(window); + if (index > -1) { + openWindows.splice(index, 1); + } + }) + + lk.layers.workspace.addWindow(window) + + splitPaneVerticallyWith(window.mainSplit, 0, pane) + } + + property var splitPaneHorizontallyWith : function(splitter, index, pane){ + splitter.splitHorizontally(index, pane) + + lk.layers.workspace.addPane(pane, pane.paneWindow(), pane.splitterHierarchyPositioning()) + } + + property var splitPaneVerticallyWith : function(splitter, index, pane){ + splitter.splitVertically(index, pane) + + lk.layers.workspace.addPane(pane, pane.paneWindow(), pane.splitterHierarchyPositioning()) + } + + property var splitPaneHorizontallyBeforeWith : function(splitter, index, pane){ + splitter.splitHorizontallyBefore(index, pane) + + lk.layers.workspace.addPane(pane, pane.paneWindow(), pane.splitterHierarchyPositioning()) + } + + property var splitPaneVerticallyBeforeWith : function(splitter, index, pane){ + splitter.splitVerticallyBefore(index, pane) + + lk.layers.workspace.addPane(pane, pane.paneWindow(), pane.splitterHierarchyPositioning()) + } + + property var splitPaneHorizontally : function(pane, newPane){ + var index = pane.parentSplitViewIndex() + splitPaneHorizontallyWith(pane.parentSplitView, index, newPane) + } + property var splitPaneVertically : function(pane, newPane){ + var index = pane.parentSplitViewIndex() + splitPaneVerticallyWith(pane.parentSplitView, index, newPane) + } + property var splitPaneHorizontallyBefore : function(pane, newPane){ + var index = pane.parentSplitViewIndex() + splitPaneHorizontallyBeforeWith(pane.parentSplitView, index, newPane) + } + property var splitPaneVerticallyBefore : function(pane, newPane){ + var index = pane.parentSplitViewIndex() + splitPaneVerticallyBeforeWith(pane.parentSplitView, index, newPane) + } + + property var insertPaneAtIndex: function(splitView, index, newPane){ + if ( !splitView.__canFitPane(newPane) ){ + throw new Error("Failed to fit pane inside layout.") + } + + if ( splitView.orientation === Qt.Horizontal ){ + var delta = splitView.width - newPane.width + if ( delta < 0 ){ + delta = splitView.width - newPane.minimumPaneWidth + newPane.width = newPane.minimumPaneWidth + } + + var scale = delta / splitView.width + + var newPaneSizes = splitView.paneSizes.map(function(size){ return size * scale }) + newPaneSizes.splice(index, 0, newPane.width) + + splitView.__splitPaneForHorizontal(index, newPane, true) + + // resize all panes smaller than minimum width + for ( var i = 0; i < splitView.panes.length; ++i ){ + if ( newPaneSizes[i] < splitView.panes[i].paneMinimumWidth ){ + newPaneSizes[i] = splitView.panes[i].paneMinimumWidth + } + } + + var totalSize = 0; + for ( var i = 0; i < newPaneSizes.length; ++i ){ + totalSize += newPaneSizes[i] + } + var sizeLeft = totalSize - splitView.width + + // due to the previous resize, panes might exceed splitView width and need to be resized + for ( var i = newPaneSizes.length - 1; i >= 0; --i ){ + if ( sizeLeft < 0 ) + break; + + if ( newPaneSizes[i] > splitView.panes[i].paneMinimumWidth){ + sizeLeft -= (newPaneSizes[i] - splitView.panes[i].paneMinimumWidth) + newPaneSizes[i] = splitView.panes[i].paneMinimumWidth + } + } + + for ( var i = 0; i < splitView.panes.length; ++i ){ + splitView.panes[i].width = newPaneSizes[i] + splitView.paneSizes[i] = newPaneSizes[i] + } + + } else { + var delta = splitView.height - newPane.height + if ( delta < 0 ){ + delta = splitView.height - newPane.minimumPaneHeight + newPane.height = newPane.minimumPaneHeight + } + + var scale = delta / splitView.height + + var newPaneSizes = splitView.paneSizes.map(function(size){ return size * scale }) + newPaneSizes.splice(index, 0, newPane.height) + + splitView.__splitPaneForVertical(index, newPane, true) + + // resize all panes smaller than minimum height + for ( var i = 0; i < splitView.panes.length; ++i ){ + if ( newPaneSizes[i] < splitView.panes[i].paneMinimumHeight ){ + newPaneSizes[i] = splitView.panes[i].paneMinimumHeight + } + } + + var totalSize = 0; + for ( var i = 0; i < newPaneSizes.length; ++i ){ + totalSize += newPaneSizes[i] + } + var sizeLeft = totalSize - splitView.height + + // due to the previous resize, panes might exceed splitView height and need to be resized + for ( var i = newPaneSizes.length - 1; i >= 0; --i ){ + if ( sizeLeft < 0 ) + break; + + if ( newPaneSizes[i] > splitView.panes[i].paneMinimumHeight){ + sizeLeft -= (newPaneSizes[i] - splitView.panes[i].paneMinimumHeight) + newPaneSizes[i] = splitView.panes[i].paneMinimumHeight + } + } + + for ( var i = 0; i < splitView.panes.length; ++i ){ + splitView.panes[i].height = newPaneSizes[i] + splitView.paneSizes[i] = newPaneSizes[i] + } + } + + lk.layers.workspace.addPane(newPane, newPane.paneWindow(), newPane.splitterHierarchyPositioning()) + } + property var insertPane: function(newPane, options){ + var splitViewToFit = root.container.__findLocationToFitPane(newPane, options) + if ( !splitViewToFit ){ + throw new Error("Failed to fit pane inside layout.") + } + + root.insertPaneAtIndex(splitViewToFit, splitViewToFit.panes.length, newPane) + } + + property var canFitPane : function(splitView, pane){ + return splitView.__canFitPane(pane) + } + + property var paneTypes: function(){ + var result = [] + for (var key in root.types) { + // check if the property/key is defined in the object itself, not in parent + if (root.types.hasOwnProperty(key)) { + result.push({name: key, single: root.types[key].single}) + } + } + return result + } + + function clearPane(pane){ + removePane(pane) + pane.paneCleared() + } + + function removePane(pane){ + if ( pane.parentSplitView ){ + var split = pane.parentSplitView + var paneIndex = split.paneIndex(pane) + + if ( pane.paneType !== 'splitview' ) + lk.layers.workspace.removePane(pane) + + split.removeAt(paneIndex) + + if ( root.activePane === pane ){ + root.activePane = null + root.activeItem = null + } + + if ( split.panes.length === 0 && split !== root.container ){ + removePane(split) + } + } else if ( pane.paneType === 'splitview' ){ + if ( pane.currentWindow !== lk.layers.window.window() ){ + pane.currentWindow.close() + } + } + } + + function reset(){ + __clearAll() + var split = root.container.createNewSplitter(Qt.Horizontal) + root.container.initialize([split]) + } + + function focusPane(paneType){ + var ap = root.activePane + if ( ap && ap.paneType === paneType ){ + return ap + } + + var pane = root.container.findPaneByType(paneType) + if ( pane ) + return pane + + for ( var i = 0; i < root.openWindows.length; ++i ){ + var w = root.openWindows[i] + var p = w.mainSplit.findPaneByType(paneType) + if ( p ) + return p + } + return null + } + + function findPanesByType(paneType){ + var result = [] + result = result.concat(root.container.findPanesByType(paneType)) + + for ( var i = 0; i < root.openWindows.length; ++i ){ + var w = root.openWindows[i] + result = result.concat(w.mainSplit.findPanesByType(paneType)) + } + return result + } + + function setActiveItem(item, pane){ + activeItem = item + var p = pane ? pane : item + while ( p !== null ){ + if ( p.objectName === 'editor' || p.objectName === 'project' || p.objectName === 'viewer' ){ + activePane = p + return + } + p = p.parent + } + } + + function activateItem(item, pane){ + if ( activeItem && activeItem !== item ){ + activeItem.focus = false + } + + activeItem = item + activeItem.forceActiveFocus() + var p = pane ? pane : item + while ( p !== null ){ + if ( p.objectName === 'editor' || p.objectName === 'project' || p.objectName === 'viewer' ){ + activePane = p + return + } + p = p.parent + } + } + + function openContextMenu(item, pane){ + if ( !item ) + item = activeItem + if ( !pane ) + pane = activePane + + var res = lk.layers.workspace.interceptMenu(pane, item) + contextMenu.show(res) + } + + property var __clearAll: function(){ + root.container.clearPanes() + activePane = null + activeItem = null + } + + function __dragStarted(pane){ + for ( var i = 0; i < openWindows.length; ++i ){ + var w = openWindows[i] + w.paneDropArea.currentPane = pane + w.paneDropArea.model = w.mainSplit.createPositioningModel() + w.paneDropArea.visible = true + } + + if (typeof pane === 'function') { + root.paneDropArea.paneFactory = pane + } else { + root.paneDropArea.currentPane = pane + } + + root.paneDropArea.model = root.container.createPositioningModel() + root.paneDropArea.visible = true + } + + function __dragFinished(pane){ + root.paneDropArea.currentPane = null + root.paneDropArea.paneFactory = null + root.paneDropArea.model = [] + for ( var i = 0; i < openWindows.length; ++i ){ + var w = openWindows[i] + w.paneDropArea.currentPane = null + w.paneDropArea.model = [] + w.paneDropArea.visible = false + } + root.paneDropArea.visible = false + } + + function initializeSplitterPanes(splitter, paneConfiguration){ + var orientation = paneConfiguration[0] === 'h' ? Qt.Horizontal : Qt.Vertical + splitter.orientation = orientation + + if ( splitter !== root.container ){ + if ( orientation === Qt.Vertical && paneConfiguration.length > 1 ){ + splitter.width = paneConfiguration[1].width + } else { + splitter.height = paneConfiguration[1].width + } + } + + var panesToOpen = [] + var recurseSplitters = [] + + for ( var i = 1; i < paneConfiguration.length; ++i ){ + + if ( Array.isArray(paneConfiguration[i]) ){ + var split = splitter.createNewSplitter(Qt.Vertical) + panesToOpen.push(split) + recurseSplitters.push(i) + } else { + var state = 'state' in paneConfiguration[i] ? paneConfiguration[i].state : null + var pane = createPane(paneConfiguration[i].type, state, paneConfiguration[i].size) + panesToOpen.push(pane) + } + } + + splitter.initialize(panesToOpen) + + for ( var i = 0; i < recurseSplitters.length; ++i ){ + var configIndex = recurseSplitters[i] + initializeSplitterPanes(panesToOpen[configIndex - 1], paneConfiguration[configIndex]) + } + + splitter.__updatePaneSizes() + + return panesToOpen + } +} diff --git a/application/qml/ProjectEnvironment.qml b/application/qml/ProjectEnvironment.qml index 5bb116c3..583870f1 100644 --- a/application/qml/ProjectEnvironment.qml +++ b/application/qml/ProjectEnvironment.qml @@ -222,7 +222,7 @@ Item{ root.wizards.checkUnsavedFiles(function(){ lk.layers.window.dialogs.openDir({}, function(url){ root.wizards.openProject(url, callback) - // lk.openProjectInstance(url) + // lk.openProjectInstance(url) }) }) } @@ -277,7 +277,7 @@ Item{ if ( callback ) callback(path) } - // lk.openProjectInstance(url) + // lk.openProjectInstance(url) }) } @@ -286,7 +286,7 @@ Item{ project.newProject() if ( callback ) callback() - // lk.newProjectInstance() + // lk.newProjectInstance() }) } diff --git a/application/qml/RunView.qml b/application/qml/RunView.qml index b9c13ff3..ae26f705 100644 --- a/application/qml/RunView.qml +++ b/application/qml/RunView.qml @@ -236,8 +236,8 @@ Pane{ onClicked: { paneMenu.visible = false var clone = root.paneClone() - var index = root.parentSplitterIndex() - root.panes.splitPaneHorizontallyWith(root.parentSplitter, index, clone) + var index = root.parentSplitViewIndex() + root.panes.splitPaneHorizontallyWith(root.parentSplitView, index, clone) } } } @@ -266,8 +266,8 @@ Pane{ onClicked: { paneMenu.visible = false var clone = root.paneClone() - var index = root.parentSplitterIndex() - root.panes.splitPaneVerticallyWith(root.parentSplitter, index, clone) + var index = root.parentSplitViewIndex() + root.panes.splitPaneVerticallyWith(root.parentSplitView, index, clone) } } } diff --git a/application/qml/StartupBox.qml b/application/qml/StartupBox.qml index 14de34f3..babccd43 100644 --- a/application/qml/StartupBox.qml +++ b/application/qml/StartupBox.qml @@ -28,7 +28,7 @@ Rectangle{ MouseArea{ anchors.fill: parent onClicked: { - lk.layers.workspace.panes.removeStartupBox() + lk.layers.workspace.startup.close() } } } diff --git a/application/qml/Top.qml b/application/qml/Top.qml index fd0a8c17..b2c7574f 100644 --- a/application/qml/Top.qml +++ b/application/qml/Top.qml @@ -81,7 +81,7 @@ Rectangle { height: parent.height hoverEnabled: true onClicked: { - lk.layers.workspace.panes.initializeStartupBox() + lk.layers.workspace.startup.show() } Workspace.Tooltip{ mouseOver: logoFunction.containsMouse diff --git a/application/qml/Viewer.qml b/application/qml/Viewer.qml index d29de56f..6ff2354e 100644 --- a/application/qml/Viewer.qml +++ b/application/qml/Viewer.qml @@ -241,8 +241,12 @@ Pane{ id: error anchors.bottom: parent.bottom width : parent.width - color : root.style.errorBackgroundColor - font: root.style.errorFont + color : "#000" + font: Qt.font({ + family: "Source Code Pro, Ubuntu Mono, Courier New, Courier", + pixelSize: 12, + weight: Font.Normal + }) } RunnablesMenu{ diff --git a/application/qml/workspace.qml b/application/qml/workspace.qml index b7f9f7c3..f1d49c02 100644 --- a/application/qml/workspace.qml +++ b/application/qml/workspace.qml @@ -20,6 +20,7 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.2 import QtQuick.Window 2.0 import base 1.0 +import workspace 1.0 import editor 1.0 import editor.private 1.0 import workspace.icons 1.0 as Icons @@ -31,369 +32,42 @@ Item{ anchors.fill: parent objectName: "workspace" - property Item runSpace : viewer.runSpace + property Item runSpace : root.panes.__factories.viewer.runSpace - property QtObject style : QtObject{ - property font errorFont : Qt.font({ - family: "Source Code Pro, Ubuntu Mono, Courier New, Courier", - pixelSize: 12, - weight: Font.Normal - }) - property color errorFontColor : "#fff" - property color errorBackgroundColor: "#000" + property QtObject panes : PaneEnvironment{ + container: mainSplit + contextMenu: contextMenu + paneDropArea: paneDropArea } - property QtObject panes : QtObject{ - property Item activePane : null - property Item activeItem : null - property Item container : mainSplit - property ContextMenu contextMenu: contextMenu - - property var openWindows : [] - - property var factories : { - return { - "editor" : function(p, s){ - var pane = editorFactory.createObject(p) - if ( s ) - pane.paneInitialize(s) - return pane - }, - "projectFileSystem" : function(p, s){ - if ( s ) - root.projectFileSystemSingle.paneInitialize(s) - return root.projectFileSystemSingle - }, - "viewer" : function(p, s){ - return root.viewer - }, - "runView" : function(p, s){ - var pane = runViewFactory.createObject(p) - if ( s ) - pane.paneInitialize(s) - return pane - }, - "documentation" : function(p, s){ - var pane = documentationFactory.createObject(p) - if ( s ) - pane.paneInitialize(s) - return pane - }, - "objectPalette" : function(p, s){ - var pane = objectPaletteFactory.createObject(p) - if ( s ) - pane.paneInitialize(s) - return pane - }, - "palette" : function(p, s){ - var pane = paletteFactory.createObject(p) - if ( s ) - pane.paneInitialize(s) - return pane - }, - "log" : function(p, s){ - if ( !root.logView.parent ){ - root.logView.visible = true - root.logView.parent = p - header.isLogWindowDirty = false - return root.logView - } - - var pane = logFactory.createObject(p) - return pane - } - } - } - - function __dragStarted(pane){ - for ( var i = 0; i < openWindows.length; ++i ){ - var w = openWindows[i] - w.paneDropArea.currentPane = pane - w.paneDropArea.model = w.mainSplit.createPositioningModel() - w.paneDropArea.visible = true - } - - if (typeof pane === 'function') { - paneDropArea.paneFactory = pane - } else { - paneDropArea.currentPane = pane - } - - paneDropArea.model = mainSplit.createPositioningModel() - paneDropArea.visible = true - } - - function __dragFinished(pane){ - paneDropArea.currentPane = null - paneDropArea.paneFactory = null - paneDropArea.model = [] - for ( var i = 0; i < openWindows.length; ++i ){ - var w = openWindows[i] - w.paneDropArea.currentPane = null - w.paneDropArea.model = [] - w.paneDropArea.visible = false - } - paneDropArea.visible = false - } - - function initializeSplitterPanes(splitter, paneConfiguration){ - var orientation = paneConfiguration[0] === 'h' ? Qt.Horizontal : Qt.Vertical - splitter.orientation = orientation - - if ( splitter !== mainSplit ){ - if ( orientation === Qt.Vertical && paneConfiguration.length > 1 ){ - splitter.width = paneConfiguration[1].width - } else { - splitter.height = paneConfiguration[1].width - } - } - - var panesToOpen = [] - var recurseSplitters = [] - - for ( var i = 1; i < paneConfiguration.length; ++i ){ - - if ( Array.isArray(paneConfiguration[i]) ){ - var split = splitter.createNewSplitter(Qt.Vertical) - panesToOpen.push(split) - recurseSplitters.push(i) - } else { - var state = 'state' in paneConfiguration[i] ? paneConfiguration[i].state : null - var pane = createPane(paneConfiguration[i].type, state, paneConfiguration[i].size) - panesToOpen.push(pane) - } - } - - splitter.initialize(panesToOpen) - - for ( var i = 0; i < recurseSplitters.length; ++i ){ - var configIndex = recurseSplitters[i] - initializeSplitterPanes(panesToOpen[configIndex - 1], paneConfiguration[configIndex]) - } - - splitter.__updatePaneSizes() - - return panesToOpen - } - - property var initializePanes : function(windowConfiguration, paneConfiguration){ - removeStartupBox() - - var currentWindowPanes = paneConfiguration[0] - - var initializeStructure = [ - [lk.layers.window.window()], - [initializeSplitterPanes(container, currentWindowPanes)] - ] - - for ( var i = 1; i < paneConfiguration.length; ++i ){ - var window = paneWindowFactory.createObject(root) - openWindows.push(window) - initializeStructure[0].push(window) - initializeStructure[1].push(initializeSplitterPanes(window.mainSplit, paneConfiguration[i])) - - window.closing.connect(function(){ - var index = openWindows.indexOf(window); - if (index > -1) { - openWindows.splice(index, 1); - } - }) - } - - return initializeStructure - } - - property var createPane : function(paneType, paneState, paneSize){ - - if ( paneType in root.panes.factories ){ - var paneFactory = root.panes.factories[paneType] - var paneObject = paneFactory(null, paneState) - if ( paneSize ){ - paneObject.width = paneSize[0] - paneObject.height = paneSize[1] - } - - return paneObject - - } else { - throw new Error('Key not found: ' + paneType) - } - } - - property var movePaneToNewWindow : function(pane){ - removePane(pane) - - var window = paneWindowFactory.createObject(root) - openWindows.push(window) - - window.closing.connect(function(){ - var index = openWindows.indexOf(window); - if (index > -1) { - openWindows.splice(index, 1); - } - }) - - lk.layers.workspace.addWindow(window) - - splitPaneVerticallyWith(window.mainSplit, 0, pane) - } - - property var splitPaneHorizontallyWith : function(splitter, index, pane){ - splitter.splitHorizontally(index, pane) - - lk.layers.workspace.addPane(pane, pane.paneWindow(), pane.splitterHierarchyPositioning()) - } - - property var splitPaneVerticallyWith : function(splitter, index, pane){ - splitter.splitVertically(index, pane) - - lk.layers.workspace.addPane(pane, pane.paneWindow(), pane.splitterHierarchyPositioning()) - } - - property var splitPaneHorizontallyBeforeWith : function(splitter, index, pane){ - splitter.splitHorizontallyBefore(index, pane) - - lk.layers.workspace.addPane(pane, pane.paneWindow(), pane.splitterHierarchyPositioning()) - } - - property var splitPaneVerticallyBeforeWith : function(splitter, index, pane){ - splitter.splitVerticallyBefore(index, pane) - - lk.layers.workspace.addPane(pane, pane.paneWindow(), pane.splitterHierarchyPositioning()) - } - - property var clearPane : function(pane){ - removePane(pane) - pane.paneCleared() - } - - property var removePane : function(pane){ - if ( pane.parentSplitter ){ - var split = pane.parentSplitter - var paneIndex = split.paneIndex(pane) - - if ( pane.paneType !== 'splitview' ) - lk.layers.workspace.removePane(pane) - - split.removeAt(paneIndex) - - if ( panes.activePane === pane ){ - panes.activePane = null - panes.activeItem = null - } - - if ( split.panes.length === 0 && split !== mainSplit ){ - removePane(split) - } - } else if ( pane.paneType === 'splitview' ){ - if ( pane.currentWindow !== lk.layers.window.window() ){ - pane.currentWindow.close() - } - } - } - - property var reset: function(){ - __clearAll() - var split = mainSplit.createNewSplitter(Qt.Horizontal) - mainSplit.initialize([split]) - } - - property var __clearAll : function(){ - mainSplit.clearPanes() - activePane = null - activeItem = null - } - - property var removeStartupBox : function(){ - if ( root.startupBox ){ - root.startupBox.box.destroy() - root.startupBox.destroy() - root.startupBox = null - } - } - - property var initializeStartupBox : function(){ - if ( !root.startupBox ){ - var startup = startupBoxFactory.createObject() - root.startupBox = lk.layers.window.dialogs.overlayBox(startup) - } - } - - function setActiveItem(item, pane){ - activeItem = item - var p = pane ? pane : item - while ( p !== null ){ - if ( p.objectName === 'editor' || p.objectName === 'project' || p.objectName === 'viewer' ){ - activePane = p - return - } - p = p.parent - } - } - - function activateItem(item, pane){ - if ( activeItem && activeItem !== item ){ - activeItem.focus = false - } + property QtObject projectEnvironment : ProjectEnvironment{ + panes: root.panes + runSpace: root.runSpace + } - activeItem = item - activeItem.forceActiveFocus() - var p = pane ? pane : item - while ( p !== null ){ - if ( p.objectName === 'editor' || p.objectName === 'project' || p.objectName === 'viewer' ){ - activePane = p - return - } - p = p.parent - } + property QtObject startup: QtObject{ + property Component __factory: Component{ + StartupBox{} } - function focusPane(paneType){ - var ap = root.panes.activePane - if ( ap && ap.paneType === paneType ){ - return ap - } - - var pane = mainSplit.findPaneByType(paneType) - if ( pane ) - return pane + property Item instance: null - for ( var i = 0; i < root.panes.openWindows.length; ++i ){ - var w = root.panes.openWindows[i] - var p = w.mainSplit.findPaneByType(paneType) - if ( p ) - return p + property var show: function(){ + if ( !root.startup.instance ){ + var startup = root.startup.__factory.createObject() + root.startup.instance = lk.layers.window.dialogs.overlayBox(startup) } - return null } - function findPanesByType(paneType){ - var result = [] - result = result.concat(mainSplit.findPanesByType(paneType)) - - for ( var i = 0; i < root.panes.openWindows.length; ++i ){ - var w = root.panes.openWindows[i] - result = result.concat(w.mainSplit.findPanesByType(paneType)) + property var close: function(){ + if ( root.startup.instance ){ + root.startup.instance.box.destroy() + root.startup.instance.destroy() + root.startup.instance = null } - return result - } - - function openContextMenu(item, pane){ - if ( !item ) - item = activeItem - if ( !pane ) - pane = activePane - - var res = lk.layers.workspace.interceptMenu(pane, item) - contextMenu.show(res) } } - property QtObject projectEnvironment : ProjectEnvironment{ - panes: root.panes - runSpace: root.runSpace - } - property Component messageDialogButton: Input.TextButton{ height: 28 width: 100 @@ -401,7 +75,6 @@ Item{ onClicked: parent.clicked() } - property color paneSplitterColor: "transparent" property bool documentsReloaded : false Connections{ @@ -432,13 +105,13 @@ Item{ // 'openLogInWindow' : [mainVerticalSplit.openLogInWindow, "Open Log In Window"], // 'openLogInEditor' : [mainVerticalSplit.openLogInEditor, "Open Log In Editor"], 'toggleLog' : [function(){}, "Toggle Log"], - 'toggleLogPrefix' : [logView.toggleLogPrefix, "Toggle Log Prefix"], + 'toggleLogPrefix' : [root.panes.__factories.mainLog.toggleLogPrefix, "Toggle Log Prefix"], // 'addHorizontalEditorView' : [mainVerticalSplit.addHorizontalEditor, "Add Horizontal Editor"], // 'addHorizontalFragmentEditorView': [mainVerticalSplit.addHorizontalFragmentEditor, "Add Horizontal Fragment Editor"], // 'removeHorizontalEditorView' : [mainVerticalSplit.removeHorizontalEditor, "Remove Horizontal Editor"], - 'setLiveCodingMode': [viewer.modeContainer.setLiveCodingMode, "Set 'Live' Coding Mode"], - 'setOnSaveCodingMode': [viewer.modeContainer.setOnSaveCodingMode, "Set 'On Save' Coding Mode"], - 'setDisabledCodingMode': [viewer.modeContainer.setDisabledCodingMode, "Set 'Disabled' Coding Mode"], + 'setLiveCodingMode': [root.panes.__factories.viewer.modeContainer.setLiveCodingMode, "Set 'Live' Coding Mode"], + 'setOnSaveCodingMode': [root.panes.__factories.viewer.modeContainer.setOnSaveCodingMode, "Set 'On Save' Coding Mode"], + 'setDisabledCodingMode': [root.panes.__factories.viewer.modeContainer.setDisabledCodingMode, "Set 'Disabled' Coding Mode"], 'runProject': [project.run, "Run Project"], 'addRunView' : [root.addRunView, "Add Run View"], "help" : [root.help, "Help"] @@ -449,7 +122,7 @@ Item{ removePaneBox.style.borderHighlightColor = layer.themes.current.colorScheme.error removePaneBox.style.iconColor = layer.themes.current.colorScheme.topIconColor removePaneBox.style.iconColorAlternate = layer.themes.current.colorScheme.topIconColorAlternate - paneSplitterColor = layer.themes.current.paneSplitterColor + root.panes.style.splitterColor = layer.themes.current.paneSplitterColor contextMenu.style = layer.themes.current.popupMenuStyle var messageDialogStyle = lk.layers.window.dialogs.messageStyle @@ -463,15 +136,6 @@ Item{ } } - LogWindow{ - id : logWindow - visible : false - onVisibleChanged: if (!visible){ - logView.visible = false - } - Component.onCompleted: width = root.width - } - Top{ id : header anchors.top : parent.top @@ -529,67 +193,6 @@ Item{ z: 3000 } - Component{ - id: editorFactory - - EditorPane{ - id: editorComponent - height: parent ? parent.height : 0 - width: 400 - panes: root.panes - onInternalActiveFocusChanged: if ( internalActiveFocus ) { - root.panes.setActiveItem(editorComponent.textEdit, editorComponent) - } - Component.onCompleted: { - editorComponent.editor.forceFocus() - } - } - } - - Component{ - id: runViewFactory - - RunView{ - id: runViewComponent - panes: root.panes - } - } - - Component{ - id: documentationFactory - - DocumentationViewPane{ - id: documentationViewComponent - panes: root.panes - } - } - - Component{ - id: objectPaletteFactory - - ObjectPalettePane{ - id: objectPaletteComponent - panes: root.panes - } - } - Component{ - id: paletteFactory - - PalettePane{ - id: paletteComponent - panes: root.panes - } - } - - Component{ - id: startupBoxFactory - - StartupBox{ - } - } - - property Item startupBox : null - function addRunView(){ var pane = root.panes.createPane('runView', {}, [400, 0]) @@ -607,18 +210,6 @@ Item{ activePane.paneHelp() } - Component{ - id: logFactory - - LogContainer{ - id: logView - isInWindow: false - width: 300 - height: 200 - } - } - - Component{ id: paneWindowFactory @@ -635,26 +226,6 @@ Item{ } } - property ProjectFileSystem projectFileSystemSingle : ProjectFileSystem{ - id: projectView - width: 300 - panes: root.panes - } - - property Item viewer : Viewer { - id: viewer - panes: root.panes - } - - Component{ - id: projectFileSystemFactory - - ProjectFileSystem{ - id: projectView - width: 240 - panes: root.panes - } - } Component{ id: paneSplitViewFactory @@ -683,7 +254,7 @@ Item{ createNewSplitter: function(orientation){ var ob = paneSplitViewFactory.createObject(null) - ob.handleColor = root.paneSplitterColor + ob.handleColor = root.panes.style.splitterColor ob.orientation = orientation ob.createNewSplitter = mainSplit.createNewSplitter ob.currentWindow = mainSplit.currentWindow @@ -711,17 +282,17 @@ Item{ } - var parentSplitter = data.pane.parentSplitter - var paneIndex = data.pane.parentSplitterIndex() + var parentSplitView = data.pane.parentSplitView + var paneIndex = data.pane.parentSplitViewIndex() if ( location === paneDropArea.topPosition ){ - root.panes.splitPaneVerticallyBeforeWith(parentSplitter, paneIndex, clone) + root.panes.splitPaneVerticallyBeforeWith(parentSplitView, paneIndex, clone) } else if ( location === paneDropArea.rightPosition ){ - root.panes.splitPaneHorizontallyWith(parentSplitter, paneIndex, clone) + root.panes.splitPaneHorizontallyWith(parentSplitView, paneIndex, clone) } else if ( location === paneDropArea.bottomPosition ){ - root.panes.splitPaneVerticallyWith(parentSplitter, paneIndex, clone) + root.panes.splitPaneVerticallyWith(parentSplitView, paneIndex, clone) } else if ( location === paneDropArea.leftPosition ){ - root.panes.splitPaneHorizontallyBeforeWith(parentSplitter, paneIndex, clone) + root.panes.splitPaneHorizontallyBeforeWith(parentSplitView, paneIndex, clone) } } } @@ -772,18 +343,6 @@ Item{ } } - property LogContainer logView : LogContainer{ - visible: false - isInWindow: false - width: 300 - height: 200 - - onItemAdded: { - if ( !parent ) - header.isLogWindowDirty = true - } - } - ContextMenu { id: contextMenu } diff --git a/doc/pages/layer-workspace-panes.md b/doc/pages/layer-workspace-panes.md new file mode 100644 index 00000000..1f8dba88 --- /dev/null +++ b/doc/pages/layer-workspace-panes.md @@ -0,0 +1,225 @@ +# Workspace Layer Panes + +Panes are the main visual items that describe the layout of a workspace. Panes +are configurable by the user, meaning they can be dragged, resized, split, and +removed depending on the users preferences. + +Panes can be of different types: + + * An **editor** pane contains the code editor + * A **project file system** pane shows the files in the given project + * A **log** pane contains the log outputs of the application + * A **view** pane contains the application output + +Some pane types are *single* or *singletons*, meaning there can be only one opened. For example, the main **view** pane, and the **project file system** pane can only be opened once. On the other hand, multiple **editors** can exist side by side. + +The type of panes available can be extended to custom panes, which will be covered a bit later in this page. + +Depending on the type, some panes have a `state`. A `state` is a property describing the current state of the pane. For example, an **editor** pane will have the opened document as part of it's state. This is useful when pane layouts are restored for different projects. Each pane will initialize with the state it was last seen in. + +Panes can also be distributed throghout multiple windows. Users can open multiple Livekeys windows, and drag and +drop panes depending on what they want to view on each side. + +The pane API handles the management of these panes. The API can be accessed through: + +```js +lk.layers.workspace.panes +``` + +## Viewing available pane types + +#### ```paneTypes()``` + +Returns a list of available pane types: + +```js +var paneTypes = lk.layers.workspace.panes.paneTypes() +// paneTypes == [{name: 'editor', single: false}, {name: 'projectFileSystem', single: false}, ...] +``` + +## Creating panes + +The `createPane` function is used to create panes: + +```js +var editorPane = lk.layers.workspace.panes.createPane('editor') +``` + +The pane state and size can also be sent as arguments to this function: + +```js +var editorPane = lk.layers.workspace.panes.createPane('editor', {document: ''}, [800, 600]) +``` + +This function will only create a pane, but won't add it to the pane layout. This means the pane will be invisible, and it won't be usable from the view. + +## Adding a pane to the layout + + + + + +When adding a pane to the layout, other panes need to be resized in order to make room for the newly added pane. +Depending on the resize method, there are 2 types of functions available: + +### Functions that split panes + +#### ```splitPaneHorizontally(currentPane, newPane)``` + +This function will split a pane horizontally, reducing it's size to half, and inserting the new pane in the other half. + +#### ```splitPaneVertically(currentPane, newPane)``` + +This function will split a pane vertically, reducing it's size to half, and inserting the new pane in the other half. + +#### ```splitPaneHorizontallyBefore(currentPane, newPane)``` + +This function will split a pane horizontally, reducing it's size to half and moving it to the right, and inserting the new pane in the other half. + +#### ```splitPaneVerticallyBefore(currentPane, newPane)``` + +This function will split a pane vertically, reducing it's size to half and moving it to the bottom, and inserting the new pane in the other half. + +For all these functions, if the pane size will be smaller than the minimum size of the pane being split, +the panes following it will be resized in order to fit the new pane. If that is not possible, an error +will be thrown. + +### Functions that insert panes + +Panes can also be inserted at a specified index in a `SplitView`. + +#### ```insertPaneAtIndex(splitView, index, newPane)``` + +The panes within that splitView are resized proportionally, so the new pane can fit in. If the panes cannot fit the new + +#### ```insertPane(newPane, options)``` + +Tries to find a position to insert the pane at. + +The preferred orientation can be specified: + +```js +lk.layers.workspace.panes.insertPane(pane, { orientation: Qt.Horizontal } ) +``` + +### Checking if pane can fit + +#### ```canFitPane(splitView, pane)``` + +Returns true if the `splitView` has enough size available to fit `pane`, false otherwise. This function takes into account the minimum sizes of all the panes inside the `splitView`. + +## Searching for panes + +#### ```focusPane(paneType)``` + +If the pane in focus fits the `paneType`, the pane in focus is returned. Otherwise, the first pane that fits +the `paneType` is returned. + +```js +var pane = lk.layers.workspace.panes.focusPane('editor') +if ( pane && pane === lk.layers.workspace.panes.activePane ) + console.log('Found pane in focus') +``` + +#### ```findPanesByType(paneType)``` + +Returns all the panes of `paneType`: + +```js +var panes = lk.layers.workspace.panes.findPaneByType('editor') +console.log("Total panes found: " + panes.length) +``` + +## Active panes and items. + +A single pane together with an item inside a pane can be active at the same time. For example, the `TextEdit` inside the `Editor` pane is the item actually in focus, but the active pane is the `Editor` pane. + +There are 2 properties to get the active item and active pane. + +#### ```activeItem``` + +#### ```activePane``` + +#### ```activateItem(item, pane)``` + +This function activates the `item` inside `pane` and sets it in focus. + +#### ```setActiveItem(item, pane)``` + +Sets the active `item` and `pane`. The focus needs to be set manually. + +## Removing panes from the layout + +#### ```removePane(pane)``` + +This function removes the pane from the layout, without destroying it. The pane should be cleared manually +when not used anymore using `clearPane`. + +#### ```clearPane(pane)` + +This function removes the pane from the layout if it's there, and clears it, making it unusable. Use this if +you don't want to reuse the pane. + +#### ```reset()``` + +Resets the entire layout, clearing all panes. + +## Moving panes to new windows + +#### ```movePaneToNewWindow(pane)``` + +Moves `pane` to a new window. + +## Extending pane types + +The type of panes available can be extended to custom panes, by adding a package with a *workspace extensions*. An extension can add a pane type by configuring the `panes` property: + + ```js +WorkspaceExtension{ + id: root + + property Component myPane : Component{ + MyPane{} + } + + panes: { + "myPane" : { + create: function(p, s){ + var pane = root.myPane.createObject(p) + if ( s ) + pane.paneInitialize(s) + return pane + }, + single: false + } + } +} +``` + +The `panes` property can include multiple panes through key-value pairs. The keys represent the unique name +the pane will be created from, and on the value side there are 2 properties. One is the `create` function, which +returns the created pane, and the `single` property, which describes whether the pane is a singleton or not. + + +The custom created pane is a `Pane` component: + +*MyPane.qml* + +```js +Pane{ + paneType: 'myPane' + paneState : { return {} } + paneInitialize : function(s){ + console.log("Initializing state") + } + paneCleared: function(){ + console.log("Pane cleared") + } +} +``` + + * `paneType` describes the pane type + * `paneState` is the state of the pane, which will be saved in the layout file, and can be retrieved if the same pane is recreated + * `paneInitialize` is a function that will be called when the pane initializes from the layout file, given `s` as its state + * `paneCleared` gets triggered when the pane gets removed and cleared from the layout. + diff --git a/lib/lveditor/src/workspacelayer.cpp b/lib/lveditor/src/workspacelayer.cpp index d9e5456b..5fd9ee17 100644 --- a/lib/lveditor/src/workspacelayer.cpp +++ b/lib/lveditor/src/workspacelayer.cpp @@ -40,6 +40,7 @@ WorkspaceLayer::WorkspaceLayer(QObject *parent) , m_projectEnvironment(nullptr) , m_wizards(nullptr) , m_panes(nullptr) + , m_startup(nullptr) , m_viewRoot(nullptr) , m_messageStack(new lv::WorkspaceMessageStack(this)) , m_commands(nullptr) @@ -168,8 +169,9 @@ void WorkspaceLayer::loadView(ViewEngine *engine, QObject *parent){ m_projectEnvironment = m_viewRoot->property("projectEnvironment").value(); m_wizards = m_projectEnvironment->property("wizards").value(); m_panes = m_viewRoot->property("panes").value(); + m_startup = m_viewRoot->property("startup").value(); m_nextViewParent = m_viewRoot->property("runSpace").value(); - QJSValue paneFactories = m_panes->property("factories").value(); + QJSValue paneTypes = m_panes->property("types").value(); m_keymap->store(0, Qt::Key_O, lv::KeyMap::CONTROL_OR_COMMAND, "window.workspace.project.openFile"); m_keymap->store(0, Qt::Key_Backslash, lv::KeyMap::CONTROL_OR_COMMAND, "window.workspace.project.toggleVisibility"); @@ -188,12 +190,12 @@ void WorkspaceLayer::loadView(ViewEngine *engine, QObject *parent){ QJSValueIterator panesIt(panes); while ( panesIt.hasNext() ){ panesIt.next(); - paneFactories.setProperty(panesIt.name(), panesIt.value()); + paneTypes.setProperty(panesIt.name(), panesIt.value()); } } } - m_panes->property("initializeStartupBox").value().call(); + m_startup->property("show").value().call(); emit viewReady(this, m_nextViewParent); } @@ -337,7 +339,7 @@ void WorkspaceLayer::whenMainWindowClose(){ } void WorkspaceLayer::whenProjectOpen(const QString &, ProjectWorkspace *workspace){ - QJSValue v = m_panes->property("initializePanes").value(); + QJSValue initializePanesFn = m_panes->property("initializePanes").value(); const MLNode& layout = workspace->currentLayout(); @@ -368,7 +370,12 @@ void WorkspaceLayer::whenProjectOpen(const QString &, ProjectWorkspace *workspac QJSValue jsWindows; ml::toQml(layout["windows"], jsWindows, engine); - QJSValue initialPanes = v.callWithInstance(engine->newQObject(m_panes), QJSValueList() << jsWindows << jsPanes); + QJSValue initialPanes = initializePanesFn.callWithInstance(engine->newQObject(m_panes), QJSValueList() << jsWindows << jsPanes); + if ( initialPanes.isError() ){ + lv::ViewContext::instance().engine()->throwError(initialPanes, this); + return; + } + initializePanesAndWindows(workspace, initialPanes); } diff --git a/lib/lveditor/src/workspacelayer.h b/lib/lveditor/src/workspacelayer.h index 2fb88b89..6f17e6ba 100644 --- a/lib/lveditor/src/workspacelayer.h +++ b/lib/lveditor/src/workspacelayer.h @@ -31,6 +31,7 @@ class WorkspaceLayer : public Layer{ Q_PROPERTY(QObject* project READ project NOTIFY projectChanged) Q_PROPERTY(QObject* wizards READ wizards NOTIFY wizardsChanged) Q_PROPERTY(QObject* panes READ panes NOTIFY panesChanged) + Q_PROPERTY(QObject* startup READ startup NOTIFY startupChanged) Q_PROPERTY(lv::WorkspaceMessageStack* messages READ messages CONSTANT) Q_PROPERTY(lv::Commands* commands READ commands CONSTANT) Q_PROPERTY(lv::KeyMap* keymap READ keymap CONSTANT) @@ -52,6 +53,7 @@ class WorkspaceLayer : public Layer{ QObject* project() const; QObject* wizards() const; QObject* panes() const; + QObject* startup() const; lv::WorkspaceMessageStack* messages() const; lv::Commands* commands() const; @@ -93,6 +95,7 @@ public slots: void projectChanged(); void wizardsChanged(); void panesChanged(); + void startupChanged(); private: void initializePanes(ProjectWorkspace* workspace, QJSValue panes); @@ -107,6 +110,7 @@ public slots: QObject* m_projectEnvironment; QObject* m_wizards; QObject* m_panes; + QObject* m_startup; QObject* m_viewRoot; lv::WorkspaceMessageStack* m_messageStack; @@ -140,6 +144,10 @@ inline QObject *WorkspaceLayer::panes() const{ return m_panes; } +inline QObject *WorkspaceLayer::startup() const{ + return m_startup; +} + inline Commands *WorkspaceLayer::commands() const{ return m_commands; } diff --git a/plugins/editor/qml/ContextMenuStyle.qml b/plugins/editor/qml/ContextMenuStyle.qml deleted file mode 100644 index 4e1ce7b1..00000000 --- a/plugins/editor/qml/ContextMenuStyle.qml +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2019 Dinu SV. -** (contact: mail@dinusv.com) -** This file is part of Livekeys Application. -** -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -****************************************************************************/ - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -MenuStyle{ - frame: Rectangle{ - color: "#0d1621" - } - itemDelegate.label: Rectangle{ - width: dirLabelMenu.width - height: dirLabelMenu.height + 6 - color: 'transparent' - Text{ - id: dirLabelMenu - color: styleData.enabled ? "#9babb8" : "#505961" - anchors.centerIn: parent - text: styleData.text - font.family: 'Open Sans, Arial, sans-serif' - font.pixelSize: 12 - font.weight: Font.Light - } - } - itemDelegate.shortcut: Rectangle{ - width: dirShortCutText.width - height: dirShortCutText.height + 6 - color: 'transparent' - Text{ - id: dirShortCutText - color: "#7b8b98" - anchors.right: parent.right - anchors.bottom: parent.bottom - text: styleData.shortcut - font.family: 'Open Sans, Arial, sans-serif' - font.pixelSize: 9 - font.weight: Font.Light - } - } - itemDelegate.background: Rectangle{ - color: styleData.selected && styleData.enabled ? "#132740" : "transparent" - } -} diff --git a/plugins/editor/qml/EditorPane.qml b/plugins/editor/qml/EditorPane.qml index 664c6e89..4d3f650f 100644 --- a/plugins/editor/qml/EditorPane.qml +++ b/plugins/editor/qml/EditorPane.qml @@ -30,7 +30,7 @@ Pane{ property alias internalActiveFocus : editor.internalActiveFocus property alias internalFocus: editor.internalFocus onInternalActiveFocusChanged: { - if ( panes.activePane !== root ){ + if ( internalActiveFocus && panes.activePane !== root ){ panes.activateItem(textEdit, root) } } @@ -98,8 +98,8 @@ Pane{ var storeWidth = root.width docPane = root.panes.createPane('documentation', {}, [root.width, root.height]) - var index = root.parentSplitterIndex() - root.panes.splitPaneHorizontallyWith(root.parentSplitter, index, docPane) + var index = root.parentSplitViewIndex() + root.panes.splitPaneHorizontallyWith(root.parentSplitView, index, docPane) root.width = storeWidth docPane.width = storeWidth @@ -128,6 +128,8 @@ Pane{ color : lk.layers.workspace.themes.current.paneBackground clip : true + height: parent ? parent.height : 0 + width: 400 objectName: "editor" @@ -389,8 +391,7 @@ Pane{ onClicked: { editorAddRemoveMenu.visible = false var clone = root.paneClone() - var index = root.parentSplitterIndex() - root.panes.splitPaneHorizontallyWith(root.parentSplitter, index, clone) + root.panes.splitPaneHorizontally(root, clone) } } Workspace.PaneMenuItem{ @@ -398,8 +399,7 @@ Pane{ onClicked: { editorAddRemoveMenu.visible = false var clone = root.paneClone() - var index = root.parentSplitterIndex() - root.panes.splitPaneVerticallyWith(root.parentSplitter, index, clone) + root.panes.splitPaneVertically(root, clone) } } Workspace.PaneMenuItem{ diff --git a/plugins/editor/qml/Pane.qml b/plugins/editor/qml/Pane.qml index 74eb75d7..ce981212 100644 --- a/plugins/editor/qml/Pane.qml +++ b/plugins/editor/qml/Pane.qml @@ -2,28 +2,28 @@ import QtQuick 2.3 Rectangle{ - property var parentSplitter : null - property var parentSplitterIndex : function(){ - return parentSplitter ? parentSplitter.paneIndex(this) : -1 + property var parentSplitView : null + property var parentSplitViewIndex : function(){ + return parentSplitView ? parentSplitView.paneIndex(this) : -1 } property var splitterHierarchyIndex : function(){ - if (!parentSplitter){ + if (!parentSplitView){ return [] } - return parentSplitter.splitterHierarchyIndex().concat([parentSplitter.paneIndex(this)]) + return parentSplitView.splitterHierarchyIndex().concat([parentSplitView.paneIndex(this)]) } property var splitterHierarchyPositioning : function(){ - if (!parentSplitter){ + if (!parentSplitView){ return [] } - var currentIndex = (parentSplitter.paneIndex(this) + 1) * - (parentSplitter.orientation === Qt.Vertical ? -1 : 1) + var currentIndex = (parentSplitView.paneIndex(this) + 1) * + (parentSplitView.orientation === Qt.Vertical ? -1 : 1) - return parentSplitter.splitterHierarchyPositioning().concat([currentIndex]) + return parentSplitView.splitterHierarchyPositioning().concat([currentIndex]) } property var paneWindow : function(){ - return parentSplitter ? parentSplitter.currentWindow : null + return parentSplitView ? parentSplitView.currentWindow : null } property var paneHelp : function(){ @@ -31,8 +31,8 @@ Rectangle{ } property var mapGlobalPosition: function(){ - if ( parentSplitter ){ - var parentPoint = parentSplitter.mapGlobalPosition() + if ( parentSplitView ){ + var parentPoint = parentSplitView.mapGlobalPosition() return Qt.point(parentPoint.x + x, parentPoint.y + y) } return Qt.point(x, y) diff --git a/plugins/editor/qml/PaneSplitView.qml b/plugins/editor/qml/PaneSplitView.qml index 9723d7d1..31fef865 100644 --- a/plugins/editor/qml/PaneSplitView.qml +++ b/plugins/editor/qml/PaneSplitView.qml @@ -19,30 +19,30 @@ SplitView{ property string paneType : "splitview" - property var parentSplitter : null - property var parentSplitterIndex : function(){ - return parentSplitter ? parentSplitter.paneIndex(this) : -1 + property var parentSplitView : null + property var parentSplitViewIndex : function(){ + return parentSplitView ? parentSplitView.paneIndex(this) : -1 } property var splitterHierarchyIndex : function(){ - if (!parentSplitter){ + if (!parentSplitView){ return [] } - return parentSplitter.splitterHierarchyIndex().concat([parentSplitter.paneIndex(this)]) + return parentSplitView.splitterHierarchyIndex().concat([parentSplitView.paneIndex(this)]) } property var splitterHierarchyPositioning : function(){ - if (!parentSplitter){ + if (!parentSplitView){ return [] } - var currentIndex = (parentSplitter.paneIndex(this) + 1) * - (parentSplitter.orientation === Qt.Vertical ? -1 : 1) + var currentIndex = (parentSplitView.paneIndex(this) + 1) * + (parentSplitView.orientation === Qt.Vertical ? -1 : 1) - return parentSplitter.splitterHierarchyPositioning().concat([currentIndex]) + return parentSplitView.splitterHierarchyPositioning().concat([currentIndex]) } property var mapGlobalPosition: function(){ - if ( parentSplitter ){ - var parentPoint = parentSplitter.mapGlobalPosition() + if ( parentSplitView ){ + var parentPoint = parentSplitView.mapGlobalPosition() return Qt.point(parentPoint.x + x, parentPoint.y + y) } return Qt.point(x, y) @@ -50,6 +50,9 @@ SplitView{ property var createNewSplitter : function(){} + property int paneMinimumWidth: 100 + property int paneMinimumHeight: 100 + property var panes : [] property var paneSizes : [] property var paneCleared : function(){} @@ -152,7 +155,44 @@ SplitView{ } downJ-- } + } + + function __findLocationToFitPane(pane, options){ + if ( options && options.hasOwnProperty('orientation') ){ + if ( options.orientation === splitRoot.orientation ) + if ( __canFitPane(pane) ) + return splitRoot + } else { + if ( __canFitPane(pane) ) + return splitRoot + } + + for ( var i = 0; i < panes.length; ++i ){ + if ( panes[i].paneType === "splitview" ){ + var fit = panes[i].__findLocationToFitPane(pane) + if ( fit ) + return fit + } + } + return null + } + + function __canFitPane(pane){ + if ( orientation === Qt.Horizontal ){ + var minimumWidth = 0 + for ( var i = 0; i < panes.length; ++i ){ + minimumWidth += panes[i].paneMinimumWidth + } + return minimumWidth + pane.paneMinimumWidth < width + } else { + var minimumHeight = 0 + for ( var i = 0; i < panes.length; ++i ){ + minimumHeight += panes[i].paneMinimumHeight + } + + return minimumHeight + pane.paneMinimumHeight < height + } } function resizePane(pane, newSize){ @@ -280,7 +320,7 @@ SplitView{ function __splitPaneForVertical(i, item, positionBefore){ if ( i === 0 && panes.length === 0 ){ splitRoot.addItem(item) - item.parentSplitter = splitRoot + item.parentSplitView = splitRoot panes.push(item) paneSizes.push(item.height) return @@ -302,7 +342,7 @@ SplitView{ var insertIndex = positionBefore ? i : i + 1 - item.parentSplitter = splitRoot + item.parentSplitView = splitRoot panes.splice(insertIndex, 0, item) paneSizes.splice(insertIndex, 0, h) @@ -324,7 +364,7 @@ SplitView{ splitRoot.addItem(item) panes.push(item) paneSizes.push(item.width) - item.parentSplitter = splitRoot + item.parentSplitView = splitRoot return } @@ -344,7 +384,7 @@ SplitView{ var insertIndex = positionBefore ? i : i + 1 - item.parentSplitter = splitRoot + item.parentSplitView = splitRoot panes.splice(insertIndex, 0, item) paneSizes.splice(insertIndex, 0, w) @@ -452,7 +492,7 @@ SplitView{ } for ( var j = 0; j < panes.length; ++j ){ - panes[j].parentSplitter = this + panes[j].parentSplitView = this splitRoot.addItem(panes[j]) } @@ -514,7 +554,7 @@ SplitView{ splitRoot.removeItem(panes[j]) } - item.parentSplitter = splitRoot + item.parentSplitView = splitRoot panes[i] = item for ( var j = i; j < panes.length; ++j ){ diff --git a/plugins/editor/qml/PaneWindow.qml b/plugins/editor/qml/PaneWindow.qml index fb9d11f8..fe00cd74 100644 --- a/plugins/editor/qml/PaneWindow.qml +++ b/plugins/editor/qml/PaneWindow.qml @@ -30,20 +30,20 @@ Window{ if ( data.pane === currentPane ) return - var parentSplitter = data.pane.parentSplitter - var paneIndex = data.pane.parentSplitterIndex() + var parentSplitView = data.pane.parentSplitView + var paneIndex = data.pane.parentSplitViewIndex() var clone = currentPane root.panes.removePane(currentPane) if ( location === paneDropArea.topPosition ){ - root.panes.splitPaneVerticallyBeforeWith(parentSplitter, paneIndex, clone) + root.panes.splitPaneVerticallyBeforeWith(parentSplitView, paneIndex, clone) } else if ( location === paneDropArea.rightPosition ){ - root.panes.splitPaneHorizontallyWith(parentSplitter, paneIndex, clone) + root.panes.splitPaneHorizontallyWith(parentSplitView, paneIndex, clone) } else if ( location === paneDropArea.bottomPosition ){ - root.panes.splitPaneVerticallyWith(parentSplitter, paneIndex, clone) + root.panes.splitPaneVerticallyWith(parentSplitView, paneIndex, clone) } else if ( location === paneDropArea.leftPosition ){ - root.panes.splitPaneHorizontallyBeforeWith(parentSplitter, paneIndex, clone) + root.panes.splitPaneHorizontallyBeforeWith(parentSplitView, paneIndex, clone) } } } diff --git a/plugins/editor/qml/qmldir b/plugins/editor/qml/qmldir index 21b3aa1e..8bb1715a 100644 --- a/plugins/editor/qml/qmldir +++ b/plugins/editor/qml/qmldir @@ -6,7 +6,6 @@ depends QtQuick 2.3 Editor 1.0 Editor.qml EditorPane 1.0 EditorPane.qml SuggestionBox 1.0 SuggestionBox.qml -ContextMenuStyle 1.0 ContextMenuStyle.qml LoadingAnimation 1.0 LoadingAnimation.qml PaletteListView 1.0 PaletteListView.qml PaletteConnection 1.0 PaletteConnection.qml diff --git a/plugins/editqml/qml/PaletteContainer.qml b/plugins/editqml/qml/PaletteContainer.qml index 24f4d2f6..03a6e386 100644 --- a/plugins/editqml/qml/PaletteContainer.qml +++ b/plugins/editqml/qml/PaletteContainer.qml @@ -114,8 +114,8 @@ Rectangle{ var palettePane = lk.layers.workspace.panes.createPane('palette', {}, [400, 400]) lk.layers.workspace.panes.splitPaneHorizontallyWith( - paletteContainer.editor.parentSplitter, - paletteContainer.editor.parentSplitterIndex(), + paletteContainer.editor.parentSplitView, + paletteContainer.editor.parentSplitViewIndex(), palettePane ) diff --git a/plugins/editqml/qml/PaletteControls.qml b/plugins/editqml/qml/PaletteControls.qml index e3ea75fb..1fbe3890 100644 --- a/plugins/editqml/qml/PaletteControls.qml +++ b/plugins/editqml/qml/PaletteControls.qml @@ -816,8 +816,8 @@ QtObject{ var objectPane = lk.layers.workspace.panes.createPane('objectPalette', {}, [400, 400]) lk.layers.workspace.panes.splitPaneHorizontallyWith( - objectContainer.editor.parentSplitter, - objectContainer.editor.parentSplitterIndex(), + objectContainer.editor.parentSplitView, + objectContainer.editor.parentSplitViewIndex(), objectPane ) diff --git a/plugins/lcvcore/qml/EditCvExtension.qml b/plugins/lcvcore/qml/EditCvExtension.qml index 49b37507..813c4727 100644 --- a/plugins/lcvcore/qml/EditCvExtension.qml +++ b/plugins/lcvcore/qml/EditCvExtension.qml @@ -25,7 +25,7 @@ WorkspaceExtension{ var editor = lk.layers.workspace.panes.focusPane('editor') if ( editor ){ lk.layers.workspace.panes.splitPaneHorizontallyWith( - editor.parentSplitter, editor.parentSplitterIndex(), fe + editor.parentSplitView, editor.parentSplitViewIndex(), fe ) } else { lk.layers.workspace.panes.container.splitPane(0, fe) @@ -46,12 +46,15 @@ WorkspaceExtension{ } panes: { - "matImage" : function(p, s){ - var pane = root.imagePaneFactory.createObject(p) - if ( s ) - pane.paneInitialize(s) - return pane - }, + "matImage" : { + create: function(p, s){ + var pane = root.imagePaneFactory.createObject(p) + if ( s ) + pane.paneInitialize(s) + return pane + }, + single: false + } } menuInterceptors: [ @@ -107,9 +110,9 @@ WorkspaceExtension{ var panes = lk.layers.workspace.panes.findPanesByType('editor') if ( panes.length === 0 ){ var foundPane = panes[0] - var foundPaneIndex = foundPane.parentSplitterIndex + var foundPaneIndex = foundPane.parentSplitViewIndex - lk.layers.workspace.panes.splitPaneVerticallyWith(foundPane.parentSplitter, foundPaneIndex, pane) + lk.layers.workspace.panes.splitPaneVerticallyWith(foundPane.parentSplitView, foundPaneIndex, pane) } else { var containerUsed = lk.layers.workspace.panes.container if ( containerUsed.orientation === Qt.Vertical ){ @@ -142,8 +145,8 @@ WorkspaceExtension{ var panes = lk.layers.workspace.panes.findPanesByType('editor') if ( panes.length === 0 ){ var foundPane = panes[0] - var foundPaneIndex = foundPane.parentSplitterIndex - lk.layers.workspace.panes.splitPaneVerticallyWith(foundPane.parentSplitter, foundPaneIndex, pane) + var foundPaneIndex = foundPane.parentSplitViewIndex + lk.layers.workspace.panes.splitPaneVerticallyWith(foundPane.parentSplitView, foundPaneIndex, pane) } else { var containerUsed = lk.layers.workspace.panes.container if ( containerUsed.orientation === Qt.Vertical ){ @@ -210,9 +213,9 @@ WorkspaceExtension{ var panes = lk.layers.workspace.panes.findPanesByType('editor') if ( panes.length === 0 ){ var foundPane = panes[0] - var foundPaneIndex = foundPane.parentSplitterIndex + var foundPaneIndex = foundPane.parentSplitViewIndex - lk.layers.workspace.panes.splitPaneVerticallyWith(foundPane.parentSplitter, foundPaneIndex, pane) + lk.layers.workspace.panes.splitPaneVerticallyWith(foundPane.parentSplitView, foundPaneIndex, pane) } else { var containerUsed = lk.layers.workspace.panes.container if ( containerUsed.orientation === Qt.Vertical ){ @@ -261,8 +264,8 @@ WorkspaceExtension{ var panes = lk.layers.workspace.panes.findPanesByType('editor') if ( panes.length === 0 ){ var foundPane = panes[0] - var foundPaneIndex = foundPane.parentSplitterIndex - lk.layers.workspace.panes.splitPaneVerticallyWith(foundPane.parentSplitter, foundPaneIndex, pane) + var foundPaneIndex = foundPane.parentSplitViewIndex + lk.layers.workspace.panes.splitPaneVerticallyWith(foundPane.parentSplitView, foundPaneIndex, pane) } else { var containerUsed = lk.layers.workspace.panes.container if ( containerUsed.orientation === Qt.Vertical ){ diff --git a/application/qml/ContextMenu.qml b/plugins/workspace/qml/ContextMenu.qml similarity index 100% rename from application/qml/ContextMenu.qml rename to plugins/workspace/qml/ContextMenu.qml diff --git a/plugins/workspace/qml/WorkspaceControlsExtension.qml b/plugins/workspace/qml/WorkspaceControlsExtension.qml index ad759c12..f7a16d38 100644 --- a/plugins/workspace/qml/WorkspaceControlsExtension.qml +++ b/plugins/workspace/qml/WorkspaceControlsExtension.qml @@ -3,12 +3,41 @@ import editor 1.0 import workspace.nodeeditor 1.0 WorkspaceExtension{ + id: root objectName: "workspace" property ObjectGraphControls objectGraphControls: ObjectGraphControls{} + function addEditorPane(){ + var pane = lk.layers.workspace.panes.createPane('editor') + lk.layers.workspace.panes.insertPane(pane, {orientation: Qt.Horizontal} ) + } + + property Component editorPane: Component{ + EditorPane{ + id: editorComponent + panes: lk.layers.workspace.panes + Component.onCompleted: { + editorComponent.editor.forceFocus() + } + } + } + property Component objectPalettePane: Component{ + ObjectPalettePane{ + id: objectPaletteComponent + panes: root.panes + } + } + property Component palettePane: Component{ + PalettePane{ + id: paletteComponent + panes: root.panes + } + } + commands: { 'minimize' : [lk.layers.window.handle.minimize, "Minimize"], + 'addEditor' : [root.addEditorPane, "Add editor pane"], 'toggleFullScreen': [lk.layers.window.handle.toggleFullScreen, "Toggle Fullscreen"], "node_delete_active": [objectGraphControls.removeActiveItem, "Deletes the activated item in the node editor."], "nodeEditMode" : [objectGraphControls.nodeEditMode, "Switch to node editing mode."] @@ -22,6 +51,38 @@ WorkspaceExtension{ "alt+n": {command: "workspace.nodeEditMode" } } + panes: { + return { + "editor" : { + create: function(p, s){ + var pane = root.editorPane.createObject(p) + if ( s ) + pane.paneInitialize(s) + return pane + }, + single: false + }, + "objectPalette" : { + create: function(p, s){ + var pane = root.objectPalettePane.createObject(p) + if ( s ) + pane.paneInitialize(s) + return pane + }, + single: false + }, + "palette" : { + create: function(p, s){ + var pane = root.palettePane.createObject(p) + if ( s ) + pane.paneInitialize(s) + return pane + }, + single: false + } + } + } + menuInterceptors: [ { whenPane: 'editor', diff --git a/plugins/workspace/qml/qmldir b/plugins/workspace/qml/qmldir index 27f70925..111a651d 100644 --- a/plugins/workspace/qml/qmldir +++ b/plugins/workspace/qml/qmldir @@ -3,6 +3,7 @@ module workspace depends QtQuick 2.3 Highlighter 1.0 Highlighter.qml +ContextMenu 1.0 ContextMenu.qml PaneMenu 1.0 PaneMenu.qml PaneMenuItem 1.0 PaneMenuItem.qml PopupMenuStyle 1.0 PopupMenuStyle.qml From b60f0b3d09b67a6178deadd907f510fe42f42f59 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Sun, 20 Jun 2021 21:23:34 +0300 Subject: [PATCH 69/91] QmlEditFragment: Fixed __selectedChannelChanged function getting triggered twice for nested edit fragments. --- lib/lveditqmljs/src/codeqmlhandler.cpp | 4 ---- lib/lveditqmljs/src/qmleditfragment.cpp | 11 ++++++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/lveditqmljs/src/codeqmlhandler.cpp b/lib/lveditqmljs/src/codeqmlhandler.cpp index 8b073417..710f1d9b 100644 --- a/lib/lveditqmljs/src/codeqmlhandler.cpp +++ b/lib/lveditqmljs/src/codeqmlhandler.cpp @@ -2176,7 +2176,6 @@ QmlEditFragment *CodeQmlHandler::openNestedConnection(QmlEditFragment* editParen } editParent->addChildFragment(ef); - ef->setParent(editParent); if (ef->location() == QmlEditFragment::Object) populateObjectInfoForFragment(ef); @@ -2235,7 +2234,6 @@ lv::QmlEditFragment *CodeQmlHandler::createReadOnlyPropertyFragment(QmlEditFragm result->addFragmentType(QmlEditFragment::FragmentType::ReadOnly); parentFragment->addChildFragment(result); - result->setParent(parentFragment); return result; } @@ -2317,7 +2315,6 @@ QList CodeQmlHandler::openNestedObjects(QmlEditFragment *edit){ }); edit->addChildFragment(ef); - ef->setParent(edit); if (ef->location() == QmlEditFragment::Object) populateObjectInfoForFragment(ef); @@ -2447,7 +2444,6 @@ QList CodeQmlHandler::openNestedProperties(QmlEditFragment *edit){ populatePropertyInfoForFragment(ef); p->addChildFragment(ef); - ef->setParent(p); rehighlightSection(ef->valuePosition(), ef->valuePosition() + ef->valueLength()); diff --git a/lib/lveditqmljs/src/qmleditfragment.cpp b/lib/lveditqmljs/src/qmleditfragment.cpp index 591356e1..c4f097f5 100644 --- a/lib/lveditqmljs/src/qmleditfragment.cpp +++ b/lib/lveditqmljs/src/qmleditfragment.cpp @@ -205,7 +205,11 @@ void QmlEditFragment::setBindingPalette(CodePalette *palette){ void QmlEditFragment::addChildFragment(QmlEditFragment *edit){ m_childFragments.append(edit); - + edit->setParent(this); + if ( m_channel ){ + DocumentQmlChannels* channels = m_codeHandler->bindingChannels(); + disconnect(channels, &DocumentQmlChannels::selectedChannelChanged, edit, &QmlEditFragment::__selectedChannelChanged); + } } void QmlEditFragment::removeChildFragment(QmlEditFragment *edit){ @@ -674,9 +678,10 @@ void QmlEditFragment::setObjectInfo(QVariantMap &info) void QmlEditFragment::setChannel(QSharedPointer channel){ if ( !m_channel ){ - DocumentQmlChannels* channels = m_codeHandler->bindingChannels(); - if ( !parentFragment() ) + if ( !parentFragment() ){ + DocumentQmlChannels* channels = m_codeHandler->bindingChannels(); connect(channels, &DocumentQmlChannels::selectedChannelChanged, this, &QmlEditFragment::__selectedChannelChanged); + } } m_channel = channel; if ( m_channel && !m_channel->isBuilder() && m_channel->type() == QmlBindingChannel::Object ){ From 5a67db24e8c312b7de42e908335b1fdf2424cd18 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 22 Jun 2021 12:47:12 +0300 Subject: [PATCH 70/91] Palettes: Added support for writer function. Added property initialisation via writer functions. --- lib/lveditor/src/codepalette.h | 20 ++++++++++++++++++++ lib/lveditor/src/workspace.cpp | 2 -- plugins/editor/palettes/DoublePalette.qml | 5 +++++ plugins/editor/palettes/IntPalette.qml | 4 ++++ plugins/editqml/qml/PaletteControls.qml | 8 ++++++++ 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/lib/lveditor/src/codepalette.h b/lib/lveditor/src/codepalette.h index 643c821b..79df113d 100644 --- a/lib/lveditor/src/codepalette.h +++ b/lib/lveditor/src/codepalette.h @@ -32,6 +32,7 @@ class LV_EDITOR_EXPORT CodePalette : public QObject{ Q_PROPERTY(QQuickItem* item READ item WRITE setItem NOTIFY itemChanged) Q_PROPERTY(QString type READ type WRITE setType NOTIFY typeChanged) Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged) + Q_PROPERTY(QJSValue writer READ writer WRITE setWriter NOTIFY writerChanged) Q_PROPERTY(QString name READ name CONSTANT) Q_PROPERTY(lv::QmlEditFragment* editFragment READ editFragment CONSTANT) @@ -65,9 +66,13 @@ class LV_EDITOR_EXPORT CodePalette : public QObject{ QString type() const; void setType(QString type); + const QJSValue& writer() const; + public slots: bool isBindingChange() const; + void setWriter(QJSValue writer); + signals: /** Item changed */ void itemChanged(); @@ -77,6 +82,8 @@ public slots: void editFragmentChanged(); /** Type changed */ void typeChanged(); + /** Writer changed */ + void writerChanged(); /** Value was initialized */ void init(const QVariant& value); @@ -84,6 +91,7 @@ public slots: void valueFromBindingChanged(const QVariant& value); + private: Q_DISABLE_COPY(CodePalette) @@ -93,6 +101,7 @@ public slots: QVariant m_value; QString m_path; QString m_type; + QJSValue m_writer; QmlEditFragment* m_editFragment; }; @@ -166,6 +175,12 @@ inline void CodePalette::setType(QString type){ m_type = type; emit typeChanged(); } +/** + * \brief Returns the writer function set by this palette + */ +inline const QJSValue &CodePalette::writer() const{ + return m_writer; +} /** * \brief Shows if palette is currently in the middle of a binding change @@ -174,6 +189,11 @@ inline bool CodePalette::isBindingChange() const{ return m_bindingChange; } +inline void CodePalette::setWriter(QJSValue writer){ + m_writer = writer; + emit writerChanged(); +} + }// namespace #endif // LVCODEPALLETE_H diff --git a/lib/lveditor/src/workspace.cpp b/lib/lveditor/src/workspace.cpp index 92e5e62e..6473c29c 100644 --- a/lib/lveditor/src/workspace.cpp +++ b/lib/lveditor/src/workspace.cpp @@ -122,8 +122,6 @@ void Workspace::whenProjectPathChange(const QString &path){ } } -//HERE - void Workspace::saveRecentsIfChanged(){ if ( !m_recentsChanged ) return; diff --git a/plugins/editor/palettes/DoublePalette.qml b/plugins/editor/palettes/DoublePalette.qml index abf210dd..4c73c6a9 100644 --- a/plugins/editor/palettes/DoublePalette.qml +++ b/plugins/editor/palettes/DoublePalette.qml @@ -28,6 +28,10 @@ CodePalette{ property QtObject theme: lk.layers.workspace.themes.current + writer: function(){ + editFragment.write(palette.value) + } + item: Item{ width: 330 height: 25 @@ -297,6 +301,7 @@ CodePalette{ } onInit: { + console.log("ON INTIALIZE:" + value) if (isNaN(value)){ palette.value = NaN numberInput.text = 'NaN' diff --git a/plugins/editor/palettes/IntPalette.qml b/plugins/editor/palettes/IntPalette.qml index 5d6d719b..4a7ea476 100644 --- a/plugins/editor/palettes/IntPalette.qml +++ b/plugins/editor/palettes/IntPalette.qml @@ -27,6 +27,10 @@ CodePalette{ property QtObject theme: lk.layers.workspace.themes.current + writer: function(){ + editFragment.write(palette.value) + } + item: Rectangle{ width: 330 height: 23 diff --git a/plugins/editqml/qml/PaletteControls.qml b/plugins/editqml/qml/PaletteControls.qml index 1fbe3890..891d63cc 100644 --- a/plugins/editqml/qml/PaletteControls.qml +++ b/plugins/editqml/qml/PaletteControls.qml @@ -339,6 +339,14 @@ QtObject{ lk.layers.workspace.messages.pushError("Error: Can't create a palette in a non-compiled program", 1) } + var paletteList = ef.paletteList() + for ( var i = 0; i < paletteList.length; ++i ){ + if ( paletteList[i].writer ){ + paletteList[i].writer() + break + } + } + } else if ( addBoxItem.activeIndex === 2 ){ // object From 8b0e6fe8f21f819a40a60b4c4a040b4be524b6f7 Mon Sep 17 00:00:00 2001 From: nenad-popovic-91 <42581059+nenad-popovic-91@users.noreply.github.com> Date: Tue, 22 Jun 2021 14:16:51 +0200 Subject: [PATCH 71/91] ProjectDocumentPrivate, Timeline sample fix (#220) * Added ProjectDocumentPrivate * Timeline sample fix --- lib/lveditor/src/projectdocument.cpp | 277 +++++++++++++----- lib/lveditor/src/projectdocument.h | 113 +------ livekeys.json | 2 +- .../lcvcore/palettes/VideoSurfacePalette.qml | 6 +- plugins/timeline/qml/TimelineView.qml | 28 +- 5 files changed, 221 insertions(+), 205 deletions(-) diff --git a/lib/lveditor/src/projectdocument.cpp b/lib/lveditor/src/projectdocument.cpp index 186d0196..f1aab365 100644 --- a/lib/lveditor/src/projectdocument.cpp +++ b/lib/lveditor/src/projectdocument.cpp @@ -69,44 +69,157 @@ */ namespace lv{ +class ProjectDocumentPrivate { +public: + QTextDocument* textDocument; + + std::list sections; + std::list markers; + + std::list sectionsToRemove; + bool iteratingSections; + + std::list changes; + mutable std::list::iterator lastChange; + + QString contentString; + bool contentStringDirty; + + mutable int editingState; + mutable bool isSynced; + int lastCursorPosition; +}; + +/** + * \brief Begin-iterator of the sections + */ +inline ProjectDocument::SectionIterator ProjectDocument::sectionsBegin(){ + return d_ptr->sections.begin(); +} + +/** + * \brief End-iterator of the sections + */ +inline ProjectDocument::SectionIterator ProjectDocument::sectionsEnd(){ + return d_ptr->sections.end(); +} + + +/** + * \brief Const begin-iterator of the sections + */ +inline ProjectDocument::SectionConstIterator ProjectDocument::sectionsBegin() const{ + return d_ptr->sections.begin(); +} + + +/** + * \brief Const end-iterator of the sections + */ +inline ProjectDocument::SectionConstIterator ProjectDocument::sectionsEnd() const{ + return d_ptr->sections.end(); +} + +/** + * \brief Number of sections + */ +inline int ProjectDocument::totalSections() const{ + return d_ptr->sections.size(); +} + + +/** + * \brief Shows if the object has any sections + */ +inline bool ProjectDocument::hasSections() const{ + return totalSections() > 0; +} + + +inline void ProjectDocument::resetSync() const{ + d_ptr->isSynced = false; +} + +/** + * \brief Text document which is wrapped inside the ProjectDocument + */ +inline QTextDocument *ProjectDocument::textDocument(){ + return d_ptr->textDocument; +} + +/** + * \brief Adds editing state flag + */ +inline void ProjectDocument::addEditingState(EditingState state){ + d_ptr->editingState |= state; +} + +/** + * \brief Removes the given editing state flag + */ +inline void ProjectDocument::removeEditingState(EditingState state){ + if ( d_ptr->editingState & state ){ + bool restoreSilent = editingStateIs(ProjectDocument::Palette | ProjectDocument::Runtime); + d_ptr->editingState = d_ptr->editingState & ~state; + if ( restoreSilent ){ + d_ptr->editingState |= ProjectDocument::Silent; + } + } +} + +/** + * \brief Shows if the editing state includes the given flags + */ +inline bool ProjectDocument::editingStateIs(int flag) const{ + return (flag & d_ptr->editingState) == flag; +} + +/** + * \brief Resets all of the editing state flags + */ +inline void ProjectDocument::resetEditingState(){ + d_ptr->editingState = 0; +} + /** Default constructor */ ProjectDocument::ProjectDocument(ProjectFile *file, bool isMonitored, Project *parent) : Document(file, parent) - , m_textDocument(new QTextDocument(this)) - , m_iteratingSections(false) - , m_lastChange(m_changes.end()) - , m_editingState(0) - , m_isSynced(true) - , m_lastCursorPosition(-1) - , m_contentStringDirty(true) + , d_ptr(new ProjectDocumentPrivate) { + d_ptr->textDocument = new QTextDocument(this); + d_ptr->iteratingSections = false; + d_ptr->lastChange = d_ptr->changes.end(); + d_ptr->editingState = 0; + d_ptr->isSynced = true; + d_ptr->lastCursorPosition = -1; + d_ptr->contentStringDirty = true; setIsMonitored(isMonitored); - m_textDocument->setDocumentMargin(0); - m_textDocument->setDocumentLayout(new TextDocumentLayout(m_textDocument)); + d_ptr->textDocument->setDocumentMargin(0); + d_ptr->textDocument->setDocumentLayout(new TextDocumentLayout(d_ptr->textDocument)); readContent(); - connect(m_textDocument, &QTextDocument::contentsChange, this, &ProjectDocument::__documentContentsChanged); + connect(d_ptr->textDocument, &QTextDocument::contentsChange, this, &ProjectDocument::__documentContentsChanged); } void ProjectDocument::readContent(){ if ( file()->exists() ){ addEditingState(ProjectDocument::Read); - m_textDocument->setPlainText( + d_ptr->textDocument->setPlainText( QString::fromStdString(parentAsProject()->lockedFileIO()->readFromFile(file()->path().toStdString())) ); removeEditingState(ProjectDocument::Read); - m_textDocument->setModified(false); + d_ptr->textDocument->setModified(false); setLastModified(QFileInfo(file()->path()).lastModified()); - m_changes.clear(); - m_lastChange = m_changes.end(); - m_isSynced = true; + d_ptr->changes.clear(); + d_ptr->lastChange = d_ptr->changes.end(); + d_ptr->isSynced = true; emit contentChanged(); } } int ProjectDocument::contentLength(){ - return m_textDocument->characterCount(); + return d_ptr->textDocument->characterCount(); } /** @@ -120,17 +233,17 @@ int ProjectDocument::contentLength(){ * @param addedText */ void ProjectDocument::updateSections(int position, int charsRemoved, const QString &addedText){ - if ( m_sections.isEmpty() ) + if ( d_ptr->sections.empty() ) return; // Invalidation scenario - m_iteratingSections = true; + d_ptr->iteratingSections = true; int charsAdded = addedText.length(); - ProjectDocument::SectionIterator it = m_sections.begin(); - while( it != m_sections.end() ){ + ProjectDocument::SectionIterator it = d_ptr->sections.begin(); + while( it != d_ptr->sections.end() ){ ProjectDocumentSection::Ptr& section = *it; if ( section->position() + section->length() <= position ){ ++it; @@ -163,8 +276,8 @@ void ProjectDocument::updateSections(int position, int charsRemoved, const QStri // update other bindings positions section->m_position = section->position() - charsRemoved + charsAdded; - if ( charsRemoved > 0 && m_textDocument && !section->parentBlock() ){ - QTextBlock block = m_textDocument->findBlock(section->position()); + if ( charsRemoved > 0 && d_ptr->textDocument && !section->parentBlock() ){ + QTextBlock block = d_ptr->textDocument->findBlock(section->position()); ProjectDocumentBlockData* bd = static_cast(block.userData()); if ( !bd ){ bd = new ProjectDocumentBlockData; @@ -177,19 +290,20 @@ void ProjectDocument::updateSections(int position, int charsRemoved, const QStri if ( !section->isValid() ){ - it = m_sections.erase(it); + it = d_ptr->sections.erase(it); - QTextBlock tb = m_textDocument->findBlock(sectionPosition); + QTextBlock tb = d_ptr->textDocument->findBlock(sectionPosition); emit formatChanged(tb.position(), tb.length()); } else { ++it; } } - m_iteratingSections = false; + d_ptr->iteratingSections = false; - while ( !m_sectionsToRemove.isEmpty() ){ - ProjectDocumentSection::Ptr se = m_sectionsToRemove.takeLast(); + while ( !d_ptr->sectionsToRemove.empty() ){ + ProjectDocumentSection::Ptr se = d_ptr->sectionsToRemove.back(); + d_ptr->sectionsToRemove.pop_back(); removeSection(se); } @@ -198,18 +312,18 @@ void ProjectDocument::updateSections(int position, int charsRemoved, const QStri } void ProjectDocument::updateMarkers(int position, int charsRemoved, int charsAdded){ - if ( m_markers.isEmpty() ) + if ( d_ptr->markers.empty() ) return; - auto it = m_markers.begin(); - while ( it != m_markers.end() ){ + auto it = d_ptr->markers.begin(); + while ( it != d_ptr->markers.end() ){ ProjectDocumentMarker::Ptr& marker = *it; if ( marker->m_position <= position ) break; if ( charsRemoved > 0 && marker->position() <= position + charsRemoved ){ marker->invalidate(); - it = m_markers.erase(it); + it = d_ptr->markers.erase(it); } else { marker->m_position = marker->m_position - charsRemoved + charsAdded; } @@ -218,10 +332,10 @@ void ProjectDocument::updateMarkers(int position, int charsRemoved, int charsAdd } void ProjectDocument::updateSectionBlocks(int position, const QString &addedText){ - QTextBlock block = m_textDocument->findBlock(position); - QTextBlock otherBlock = m_textDocument->findBlock(position + addedText.length()); - if ( m_sections.size() > 0 && - m_textDocument && + QTextBlock block = d_ptr->textDocument->findBlock(position); + QTextBlock otherBlock = d_ptr->textDocument->findBlock(position + addedText.length()); + if ( d_ptr->sections.size() > 0 && + d_ptr->textDocument && // ( addedText.contains(QChar(QChar::ParagraphSeparator)) || // addedText.contains(QChar(QChar::LineFeed)))) block.blockNumber() != otherBlock.blockNumber()) @@ -241,7 +355,7 @@ void ProjectDocument::updateSectionBlocks(int position, const QString &addedText if ( itSection->position() >= blockEnd ){ if ( !bddestination ){ - destinationBlock = m_textDocument->findBlock(position + addedText.length()); + destinationBlock = d_ptr->textDocument->findBlock(position + addedText.length()); bddestination = static_cast(destinationBlock.userData()); if ( !bddestination ){ bddestination = new ProjectDocumentBlockData; @@ -266,7 +380,7 @@ void ProjectDocument::updateSectionBlocks(int position, const QString &addedText QString ProjectDocument::getCharsRemoved(int position, int count){ if ( count > 0 ){ syncContent(); - QTextCursor c(m_textDocument); + QTextCursor c(d_ptr->textDocument); c.setPosition(position); c.setPosition(position + count, QTextCursor::MoveMode::KeepAnchor); return c.selectedText(); @@ -279,14 +393,14 @@ QString ProjectDocument::getCharsRemoved(int position, int count){ */ ProjectDocumentMarker::Ptr ProjectDocument::addMarker(int position){ // markers are added in descending order according to their position - auto it = m_markers.begin(); - while( it != m_markers.end() ){ + auto it = d_ptr->markers.begin(); + while( it != d_ptr->markers.end() ){ if ( (*it)->position() <= position ) break; ++it; } ProjectDocumentMarker::Ptr result(new ProjectDocumentMarker(position)); - m_markers.insert(it, result); + d_ptr->markers.insert(it, result); return result; } @@ -294,10 +408,10 @@ ProjectDocumentMarker::Ptr ProjectDocument::addMarker(int position){ * \brief Removes a given marker */ void ProjectDocument::removeMarker(ProjectDocumentMarker::Ptr marker){ - auto it = m_markers.begin(); - while ( it != m_markers.end() ){ + auto it = d_ptr->markers.begin(); + while ( it != d_ptr->markers.end() ){ if ( (*it).data() == marker.data() ){ - m_markers.erase(it); + d_ptr->markers.erase(it); return; } ++it; @@ -313,9 +427,9 @@ ProjectDocumentSection::Ptr ProjectDocument::createSection(int type, int positio ProjectDocumentSection::Ptr section = ProjectDocumentSection::create(this, type, position, length); // sections are added in descending order according to their position - SectionIterator it = m_sections.begin(); + SectionIterator it = d_ptr->sections.begin(); - while( it != m_sections.end() ){ + while( it != d_ptr->sections.end() ){ ProjectDocumentSection::Ptr& itSection = *it; if ( itSection->position() < section->position() ) @@ -323,10 +437,10 @@ ProjectDocumentSection::Ptr ProjectDocument::createSection(int type, int positio ++it; } - m_sections.insert(it, section); + d_ptr->sections.insert(it, section); - if ( m_textDocument ){ - QTextBlock bl = m_textDocument->findBlock(section->position()); + if ( d_ptr->textDocument ){ + QTextBlock bl = d_ptr->textDocument->findBlock(section->position()); ProjectDocumentBlockData* blockdata = static_cast(bl.userData()); if ( !blockdata ){ blockdata = new ProjectDocumentBlockData; @@ -342,8 +456,8 @@ ProjectDocumentSection::Ptr ProjectDocument::createSection(int type, int positio * \brief Returns the section at the given position */ ProjectDocumentSection::Ptr ProjectDocument::sectionAt(int position){ - SectionIterator it = m_sections.begin(); - while( it != m_sections.end() ){ + SectionIterator it = d_ptr->sections.begin(); + while( it != d_ptr->sections.end() ){ ProjectDocumentSection::Ptr& section = *it; if ( section->position() == position ) return section; @@ -361,13 +475,13 @@ ProjectDocumentSection::Ptr ProjectDocument::sectionAt(int position){ * \brief Removes section at given position */ bool ProjectDocument::removeSectionAt(int position){ - SectionIterator it = m_sections.begin(); - while( it != m_sections.end() ){ + SectionIterator it = d_ptr->sections.begin(); + while( it != d_ptr->sections.end() ){ ProjectDocumentSection::Ptr& section = *it; if ( section->position() == position ){ section->invalidate(); - m_sections.erase(it); + d_ptr->sections.erase(it); return true; } @@ -385,17 +499,17 @@ bool ProjectDocument::removeSectionAt(int position){ void ProjectDocument::removeSection(ProjectDocumentSection::Ptr section){ int sectionPosition = section->position(); section->invalidate(); - if ( m_iteratingSections ){ - m_sectionsToRemove.append(section); + if ( d_ptr->iteratingSections ){ + d_ptr->sectionsToRemove.push_back(section); } else { - SectionIterator it = m_sections.begin(); - while( it != m_sections.end() ){ + SectionIterator it = d_ptr->sections.begin(); + while( it != d_ptr->sections.end() ){ ProjectDocumentSection::Ptr& currentSection = *it; if ( currentSection.data() == section.data() ){ - m_sections.erase(it); + d_ptr->sections.erase(it); - if ( m_textDocument ){ - QTextBlock tb = m_textDocument->findBlock(sectionPosition); + if ( d_ptr->textDocument ){ + QTextBlock tb = d_ptr->textDocument->findBlock(sectionPosition); emit formatChanged(tb.position(), tb.length()); } @@ -437,15 +551,15 @@ QByteArray ProjectDocument::content(){ * \brief Overrides Document::setContent */ void ProjectDocument::setContent(const QByteArray &content){ - m_textDocument->setPlainText(QString::fromUtf8(content)); + d_ptr->textDocument->setPlainText(QString::fromUtf8(content)); } const QString& ProjectDocument::contentString(){ - if ( m_contentStringDirty ){ - m_contentString = m_textDocument->toPlainText(); - m_contentStringDirty = false; + if ( d_ptr->contentStringDirty ){ + d_ptr->contentString = d_ptr->textDocument->toPlainText(); + d_ptr->contentStringDirty = false; } - return m_contentString; + return d_ptr->contentString; } /** @@ -453,10 +567,10 @@ const QString& ProjectDocument::contentString(){ */ QString ProjectDocument::peekContent(int position) const{ QString result = ""; - if ( position >= m_textDocument->characterCount() ) + if ( position >= d_ptr->textDocument->characterCount() ) return result; - QTextBlock bl = m_textDocument->findBlock(position); + QTextBlock bl = d_ptr->textDocument->findBlock(position); QString linePointer; int positionInBlock = position - bl.position(); @@ -479,7 +593,7 @@ QString ProjectDocument::peekContent(int position) const{ } QString ProjectDocument::substring(int from, int length) const{ - QTextCursor tc(m_textDocument); + QTextCursor tc(d_ptr->textDocument); tc.setPosition(from); tc.setPosition(from + length, QTextCursor::KeepAnchor); return tc.selectedText(); @@ -490,7 +604,7 @@ void ProjectDocument::insert(int from, int length, const QString &text, int edit auto es = static_cast(editingState); addEditingState(es); - QTextCursor tc(m_textDocument); + QTextCursor tc(d_ptr->textDocument); tc.beginEditBlock(); tc.setPosition(from); tc.setPosition(from + length - 1, QTextCursor::KeepAnchor); @@ -500,7 +614,7 @@ void ProjectDocument::insert(int from, int length, const QString &text, int edit removeEditingState(es); } else { - QTextCursor tc(m_textDocument); + QTextCursor tc(d_ptr->textDocument); tc.beginEditBlock(); tc.setPosition(from); tc.setPosition(from + length, QTextCursor::KeepAnchor); @@ -513,17 +627,17 @@ void ProjectDocument::insert(int from, int length, const QString &text, int edit } int ProjectDocument::offsetAtLine(int line) const{ - return m_textDocument->findBlockByLineNumber(line - 1).position(); + return d_ptr->textDocument->findBlockByLineNumber(line - 1).position(); } int ProjectDocument::lastCursorPosition() { - return m_lastCursorPosition; + return d_ptr->lastCursorPosition; } void ProjectDocument::setLastCursorPosition(int pos) { - m_lastCursorPosition = pos; + d_ptr->lastCursorPosition = pos; } ProjectDocument *ProjectDocument::castFrom(Document *document){ @@ -562,18 +676,18 @@ void ProjectDocument::removeLineAtBlockNumber(int pos){ * \brief Slot for tracking text document changes which updates markers and sections */ void ProjectDocument::__documentContentsChanged(int position, int charsRemoved, int charsAdded){ - m_contentStringDirty = true; + d_ptr->contentStringDirty = true; emit contentsChange(position, charsRemoved, charsAdded); //m_isDirty = true; QString addedText = ""; if ( charsAdded == 1 ){ - QChar c = m_textDocument->characterAt(position); + QChar c = d_ptr->textDocument->characterAt(position); if ( c == DocumentHandler::ParagraphSeparator ) c = DocumentHandler::NewLine; addedText = c; } else if ( charsAdded > 0 ){ - QTextCursor cursor(m_textDocument); + QTextCursor cursor(d_ptr->textDocument); cursor.setPosition(position); cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, charsAdded); addedText = cursor.selection().toPlainText(); @@ -582,21 +696,22 @@ void ProjectDocument::__documentContentsChanged(int position, int charsRemoved, updateMarkers(position, charsRemoved, addedText.size()); updateSections(position, charsRemoved, addedText); - setIsDirty(m_textDocument->isModified()); + setIsDirty(d_ptr->textDocument->isModified()); } void ProjectDocument::syncContent() const{ - while ( m_lastChange != m_changes.end() ){ - m_lastChange->redo(); - ++m_lastChange; + while ( d_ptr->lastChange != d_ptr->changes.end() ){ + d_ptr->lastChange->redo(); + ++d_ptr->lastChange; } - m_isSynced = true; + d_ptr->isSynced = true; } /** * \brief ProjectDocument destructor */ ProjectDocument::~ProjectDocument(){ + delete d_ptr; } /** diff --git a/lib/lveditor/src/projectdocument.h b/lib/lveditor/src/projectdocument.h index b963848d..d46d3162 100644 --- a/lib/lveditor/src/projectdocument.h +++ b/lib/lveditor/src/projectdocument.h @@ -36,6 +36,7 @@ class ProjectFile; class ProjectDocument; class ProjectDocumentBlockData; class DocumentHandler; +class ProjectDocumentPrivate; class LV_EDITOR_EXPORT ProjectDocumentMarker{ @@ -192,9 +193,9 @@ class LV_EDITOR_EXPORT ProjectDocument : public Document{ public: /** Iterator through sections */ - typedef QLinkedList::iterator SectionIterator; + typedef std::list::iterator SectionIterator; /** Const iterator through sections */ - typedef QLinkedList::const_iterator SectionConstIterator; + typedef std::list::const_iterator SectionConstIterator; friend class ProjectDocumentAction; friend class ProjectDocumentMarker; @@ -289,115 +290,9 @@ public slots: void updateSectionBlocks(int position, const QString& addedText); QString getCharsRemoved(int position, int count); - QTextDocument* m_textDocument; - - QLinkedList m_sections; - QLinkedList m_markers; - - QLinkedList m_sectionsToRemove; - bool m_iteratingSections; - - QLinkedList m_changes; - mutable QLinkedList::iterator m_lastChange; - - QString m_contentString; - bool m_contentStringDirty; - - mutable int m_editingState; - mutable bool m_isSynced; - int m_lastCursorPosition; -// mutable bool m_isDirty; + ProjectDocumentPrivate* d_ptr; }; -/** - * \brief Begin-iterator of the sections - */ -inline ProjectDocument::SectionIterator ProjectDocument::sectionsBegin(){ - return m_sections.begin(); -} - -/** - * \brief End-iterator of the sections - */ -inline ProjectDocument::SectionIterator ProjectDocument::sectionsEnd(){ - return m_sections.end(); -} - - -/** - * \brief Const begin-iterator of the sections - */ -inline ProjectDocument::SectionConstIterator ProjectDocument::sectionsBegin() const{ - return m_sections.begin(); -} - - -/** - * \brief Const end-iterator of the sections - */ -inline ProjectDocument::SectionConstIterator ProjectDocument::sectionsEnd() const{ - return m_sections.end(); -} - -/** - * \brief Number of sections - */ -inline int ProjectDocument::totalSections() const{ - return m_sections.size(); -} - -/** - * \brief Shows if the object has any sections - */ -inline bool ProjectDocument::hasSections() const{ - return totalSections() > 0; -} - -inline void ProjectDocument::resetSync() const{ - m_isSynced = false; -} - -/** - * \brief Text document which is wrapped inside the ProjectDocument - */ -inline QTextDocument *ProjectDocument::textDocument(){ - return m_textDocument; -} - -/** - * \brief Adds editing state flag - */ -inline void ProjectDocument::addEditingState(EditingState state){ - m_editingState |= state; -} - -/** - * \brief Removes the given editing state flag - */ -inline void ProjectDocument::removeEditingState(EditingState state){ - if ( m_editingState & state ){ - bool restoreSilent = editingStateIs(ProjectDocument::Palette | ProjectDocument::Runtime); - m_editingState = m_editingState & ~state; - if ( restoreSilent ){ - m_editingState |= ProjectDocument::Silent; - } - } -} - -/** - * \brief Shows if the editing state includes the given flags - */ -inline bool ProjectDocument::editingStateIs(int flag) const{ - return (flag & m_editingState) == flag; -} - -/** - * \brief Resets all of the editing state flags - */ -inline void ProjectDocument::resetEditingState(){ - m_editingState = 0; -} - }// namespace #endif // LVPROJECTDOCUMENT_H diff --git a/livekeys.json b/livekeys.json index 25c01874..bebb1a5d 100644 --- a/livekeys.json +++ b/livekeys.json @@ -636,7 +636,7 @@ }, "{qtdir}/resources": "resources", "{qtdir}/translations": "translations", - "{vs142comntools}/../../VC/Redist/MSVC/14.28.29910/x64/Microsoft.VC142.CRT": { + "{vs142comntools}/../../VC/Redist/MSVC/14.29.30036/x64/Microsoft.VC142.CRT": { "concrt140.dll": "-", "msvcp140.dll": "-", "msvcp140_1.dll": "-", diff --git a/plugins/lcvcore/palettes/VideoSurfacePalette.qml b/plugins/lcvcore/palettes/VideoSurfacePalette.qml index 3b53983f..dd44a443 100644 --- a/plugins/lcvcore/palettes/VideoSurfacePalette.qml +++ b/plugins/lcvcore/palettes/VideoSurfacePalette.qml @@ -48,7 +48,11 @@ CodePalette{ property QtObject videoSurfaceView: null onVideoSurfaceViewChanged: { - videoSurface = Qt.binding(function(){ return videoSurfaceView.timeline.properties.videoSurface }) + videoSurface = Qt.binding(function(){ + return videoSurfaceView.timeline + ? videoSurfaceView.timeline.properties.videoSurface + :null + }) imageView.image = Qt.binding(function(){ return videoSurfaceView.image }) } diff --git a/plugins/timeline/qml/TimelineView.qml b/plugins/timeline/qml/TimelineView.qml index 029c7e93..17f5cff2 100644 --- a/plugins/timeline/qml/TimelineView.qml +++ b/plugins/timeline/qml/TimelineView.qml @@ -14,6 +14,7 @@ Rectangle{ color: timelineStyle.borderColor Keys.onPressed: { + if (!root.timeline) return if ( event.key === Qt.Key_Space ){ if ( root.timeline.isRunning ) root.timeline.stop() @@ -170,6 +171,7 @@ Rectangle{ headerModel.scale: root.zoom } onTimelineChanged: { + if (!root.timeline) return root.timeline.headerModel.scale = Qt.binding(function(){return root.zoom }) segmentInsertMenu.segmentSelection = root.timeline.config.loaders() segmentInsertMenu.model = Object.keys(segmentInsertMenu.segmentSelection) @@ -226,7 +228,7 @@ Rectangle{ width: 12 height: 12 color: root.timelineStyle.iconColor - visible: !root.timeline.isRunning + visible: root.timeline ? !root.timeline.isRunning: true } Icons.StopIcon{ anchors.centerIn: parent @@ -234,7 +236,7 @@ Rectangle{ height: 12 padding: 2 color: root.timelineStyle.iconColor - visible: root.timeline.isRecording + visible: root.timeline ? root.timeline.isRecording: false } MouseArea{ @@ -265,9 +267,9 @@ Rectangle{ anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.leftMargin: 50 - isRunning: root.timeline.isRunning + isRunning: root.timeline ? root.timeline.isRunning : false color: root.timelineStyle.iconColor - visible: !root.timeline.isRecording + visible: root.timeline ? !root.timeline.isRecording : false onClicked : { if ( value ) root.timeline.start() @@ -280,7 +282,7 @@ Rectangle{ anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.leftMargin: 80 - text: root.timeline.positionToLabel(timelineArea.timeline.cursorPosition, false) + text: root.timeline ? root.timeline.positionToLabel(timelineArea.timeline.cursorPosition, false): "" textStyle: root.timelineStyle.timeLabelStyle } @@ -327,7 +329,7 @@ Rectangle{ interactive: false contentY: timelineView.contentY - model: root.timeline.trackList + model: root.timeline ? root.timeline.trackList: null delegate: root.trackTitleDelegate MouseArea{ @@ -379,7 +381,7 @@ Rectangle{ Rectangle{ id : timelineTopHeader - width : root.zoom * root.timeline.contentLength + width : root.zoom * (root.timeline ? root.timeline.contentLength : 10) height : 35 color : root.timelineStyle.topHeaderBackgroundColor @@ -387,7 +389,7 @@ Rectangle{ id: timelineHeaderView height: parent.height width: parent.width - model: root.timeline.headerModel + model: root.timeline ? root.timeline.headerModel: null viewportX: timelineView.contentX viewportWidth: timelineView.width @@ -403,7 +405,7 @@ Rectangle{ anchors.left: isDelimiter ? parent.left : undefined anchors.horizontalCenter: isDelimiter ? undefined : parent.horizontalCenter - text: root.timeline.positionToLabel(label, true) + text: root.timeline ? root.timeline.positionToLabel(label, true) : "" color: root.timelineStyle.markerColor font.pixelSize: 8 visible: hasLabel @@ -437,7 +439,7 @@ Rectangle{ height : parent.height / 2 color: root.timelineStyle.cursorColor - x: root.timeline.cursorPosition * root.zoom + x: (root.timeline ? root.timeline.cursorPosition: 0) * root.zoom onXChanged: { if ( x > mainScroll.flickableItem.contentX + timeline.width - 10 ){ var newContentXForwardPos = x - 30 @@ -500,8 +502,8 @@ Rectangle{ boundsBehavior: Flickable.StopAtBounds height: parent.height - contentWidth: root.timeline.contentLength * root.zoom + 5 - model: root.timeline.trackList + contentWidth: (root.timeline ? root.timeline.contentLength: 0) * root.zoom + 5 + model: root.timeline ? root.timeline.trackList : null delegate: Rectangle{ objectName: "timelineRowDelegate" height: 25 @@ -541,7 +543,7 @@ Rectangle{ width : 1 height : parent.height color: root.timelineStyle.cursorColor - x: root.timeline.cursorPosition * root.zoom + x: (root.timeline ? root.timeline.cursorPosition : 0) * root.zoom } } } From c8f53de975f668fd17a1ad5247bd05df58a3e404 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 22 Jun 2021 18:32:20 +0300 Subject: [PATCH 72/91] ProjectDocument: Removed compiler errors. --- lib/lveditor/src/projectdocument.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/lveditor/src/projectdocument.cpp b/lib/lveditor/src/projectdocument.cpp index f1aab365..819f4ead 100644 --- a/lib/lveditor/src/projectdocument.cpp +++ b/lib/lveditor/src/projectdocument.cpp @@ -93,14 +93,14 @@ class ProjectDocumentPrivate { /** * \brief Begin-iterator of the sections */ -inline ProjectDocument::SectionIterator ProjectDocument::sectionsBegin(){ +ProjectDocument::SectionIterator ProjectDocument::sectionsBegin(){ return d_ptr->sections.begin(); } /** * \brief End-iterator of the sections */ -inline ProjectDocument::SectionIterator ProjectDocument::sectionsEnd(){ +ProjectDocument::SectionIterator ProjectDocument::sectionsEnd(){ return d_ptr->sections.end(); } @@ -108,7 +108,7 @@ inline ProjectDocument::SectionIterator ProjectDocument::sectionsEnd(){ /** * \brief Const begin-iterator of the sections */ -inline ProjectDocument::SectionConstIterator ProjectDocument::sectionsBegin() const{ +ProjectDocument::SectionConstIterator ProjectDocument::sectionsBegin() const{ return d_ptr->sections.begin(); } @@ -116,14 +116,14 @@ inline ProjectDocument::SectionConstIterator ProjectDocument::sectionsBegin() co /** * \brief Const end-iterator of the sections */ -inline ProjectDocument::SectionConstIterator ProjectDocument::sectionsEnd() const{ +ProjectDocument::SectionConstIterator ProjectDocument::sectionsEnd() const{ return d_ptr->sections.end(); } /** * \brief Number of sections */ -inline int ProjectDocument::totalSections() const{ +int ProjectDocument::totalSections() const{ return d_ptr->sections.size(); } @@ -131,33 +131,33 @@ inline int ProjectDocument::totalSections() const{ /** * \brief Shows if the object has any sections */ -inline bool ProjectDocument::hasSections() const{ +bool ProjectDocument::hasSections() const{ return totalSections() > 0; } -inline void ProjectDocument::resetSync() const{ +void ProjectDocument::resetSync() const{ d_ptr->isSynced = false; } /** * \brief Text document which is wrapped inside the ProjectDocument */ -inline QTextDocument *ProjectDocument::textDocument(){ +QTextDocument *ProjectDocument::textDocument(){ return d_ptr->textDocument; } /** * \brief Adds editing state flag */ -inline void ProjectDocument::addEditingState(EditingState state){ +void ProjectDocument::addEditingState(EditingState state){ d_ptr->editingState |= state; } /** * \brief Removes the given editing state flag */ -inline void ProjectDocument::removeEditingState(EditingState state){ +void ProjectDocument::removeEditingState(EditingState state){ if ( d_ptr->editingState & state ){ bool restoreSilent = editingStateIs(ProjectDocument::Palette | ProjectDocument::Runtime); d_ptr->editingState = d_ptr->editingState & ~state; @@ -170,14 +170,14 @@ inline void ProjectDocument::removeEditingState(EditingState state){ /** * \brief Shows if the editing state includes the given flags */ -inline bool ProjectDocument::editingStateIs(int flag) const{ +bool ProjectDocument::editingStateIs(int flag) const{ return (flag & d_ptr->editingState) == flag; } /** * \brief Resets all of the editing state flags */ -inline void ProjectDocument::resetEditingState(){ +void ProjectDocument::resetEditingState(){ d_ptr->editingState = 0; } From 086073effab2c6705f1e459572f3912d1ef4533b Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Tue, 22 Jun 2021 18:43:22 +0300 Subject: [PATCH 73/91] Update .build_livekeys.yml --- .github/workflows/.build_livekeys.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/.build_livekeys.yml b/.github/workflows/.build_livekeys.yml index 88571eca..8dc3623d 100644 --- a/.github/workflows/.build_livekeys.yml +++ b/.github/workflows/.build_livekeys.yml @@ -48,6 +48,7 @@ jobs: - name: Download dependencies Linux if: runner.os == 'Linux' run: | + sudo apt-get update sudo apt-get install -y gcc-7 g++-7 build-essential cmake cmake-data libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev sudo apt-get install -y python-dev python-numpy python3 python3-pip libtbb2 libtbb-dev libjpeg-dev libpng-dev libdc1394-22-dev libgl1-mesa-dev unzip sudo apt-get install -y libtiff5 libtiff5-dev python3-setuptools doxygen libssl1.0-dev nodejs-dev npm From 6078c9dc4752bbafae2d47d365ace9e195550384 Mon Sep 17 00:00:00 2001 From: nenad-popovic-91 <42581059+nenad-popovic-91@users.noreply.github.com> Date: Wed, 23 Jun 2021 14:54:39 +0200 Subject: [PATCH 74/91] Scroll message fix (+ProjectDocumentPrivate from dev) (#221) * Scroll messages removal. --- plugins/editor/palettes/NodePalette.qml | 1 + plugins/editqml/qml/PaletteGroup.qml | 7 ++++++- plugins/workspace/nodeeditor/qml/ObjectGraph.qml | 1 + plugins/workspace/nodeeditor/qml/ObjectNode.qml | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/plugins/editor/palettes/NodePalette.qml b/plugins/editor/palettes/NodePalette.qml index 5319c538..4c5aeb37 100644 --- a/plugins/editor/palettes/NodePalette.qml +++ b/plugins/editor/palettes/NodePalette.qml @@ -148,6 +148,7 @@ CodePalette{ function clean(){ for (var i=0; i< allObjects.length; ++i){ + if (!allObjects[i].item) return var numofProps = allObjects[i].item.propertyContainer.children.length for (var j=0; j < numofProps; ++j){ var child = allObjects[i].item.propertyContainer.children[j] diff --git a/plugins/editqml/qml/PaletteGroup.qml b/plugins/editqml/qml/PaletteGroup.qml index d66c7537..b02d2797 100644 --- a/plugins/editqml/qml/PaletteGroup.qml +++ b/plugins/editqml/qml/PaletteGroup.qml @@ -31,7 +31,7 @@ Column{ } } else { if ( box && box.objectName === 'editorBox' ){ - codeHandler.removeConnection(editingFragment) + editingFragment.codeHandler.removeConnection(editingFragment) paletteGroup.destroy() } } @@ -58,6 +58,11 @@ Column{ } } + function closePalettes(){ + for (var i = 0; i < paletteGroup.children.length; ++i) + editingFragment.codeHandler.removePalette(paletteGroup.children[i].palette) + } + onWidthChanged: { // objectNodeProperty palette var p = parent diff --git a/plugins/workspace/nodeeditor/qml/ObjectGraph.qml b/plugins/workspace/nodeeditor/qml/ObjectGraph.qml index ab43a129..662c84ac 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectGraph.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectGraph.qml @@ -443,6 +443,7 @@ Rectangle{ port.label = propertyName + " In" port.y = Qt.binding( function(){ + if (!node.item) return 0 return node.item.paletteContainer.height + propertyItem.y + (propertyItem.propertyTitle.height / 2) + diff --git a/plugins/workspace/nodeeditor/qml/ObjectNode.qml b/plugins/workspace/nodeeditor/qml/ObjectNode.qml index d2328e07..39129961 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectNode.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectNode.qml @@ -303,6 +303,7 @@ Qan.NodeItem{ target: editingFragment ignoreUnknownSignals: true function onAboutToBeRemoved(){ + paletteContainer.closePalettes() if (removeNode) removeNode(nodeParent) } From d462469b5ceb20a71cbd924b24e145d93ea32372 Mon Sep 17 00:00:00 2001 From: nenad-popovic-91 <42581059+nenad-popovic-91@users.noreply.github.com> Date: Wed, 23 Jun 2021 15:27:51 +0200 Subject: [PATCH 75/91] Palettelist refactoring and fix (#222) PaletteList refactoring --- lib/lveditor/include/live/palettelist.h | 1 - lib/lveditor/include/lveditorheaders.pri | 1 - lib/lveditor/src/documenthandler.cpp | 1 - lib/lveditor/src/lveditor.pri | 2 - lib/lveditor/src/palettecontainer.cpp | 29 +-- lib/lveditor/src/palettecontainer.h | 4 +- lib/lveditor/src/palettelist.cpp | 92 ---------- lib/lveditor/src/palettelist.h | 83 --------- lib/lveditqmljs/src/codeqmlhandler.cpp | 166 ++++++++++-------- lib/lveditqmljs/src/codeqmlhandler.h | 11 +- plugins/editor/qml/PaletteListView.qml | 2 +- plugins/editor/qml/plugins.qmltypes | 19 -- plugins/editor/src/editor_plugin.cpp | 4 - plugins/editqml/qml/EditQmlExtension.qml | 16 +- plugins/editqml/qml/PaletteControls.qml | 101 +++++++---- plugins/lcvcore/qml/EditCvExtension.qml | 20 ++- .../visualqml/input/qml/PathInputBox.qml | 6 +- .../nodeeditor/qml/ObjectGraphControls.qml | 10 +- 18 files changed, 222 insertions(+), 346 deletions(-) delete mode 100644 lib/lveditor/include/live/palettelist.h delete mode 100644 lib/lveditor/src/palettelist.cpp delete mode 100644 lib/lveditor/src/palettelist.h diff --git a/lib/lveditor/include/live/palettelist.h b/lib/lveditor/include/live/palettelist.h deleted file mode 100644 index 19fb154a..00000000 --- a/lib/lveditor/include/live/palettelist.h +++ /dev/null @@ -1 +0,0 @@ -#include "../../src/palettelist.h" diff --git a/lib/lveditor/include/lveditorheaders.pri b/lib/lveditor/include/lveditorheaders.pri index 82b82e62..becbc598 100644 --- a/lib/lveditor/include/lveditorheaders.pri +++ b/lib/lveditor/include/lveditorheaders.pri @@ -16,7 +16,6 @@ HEADERS += \ $$PWD/live/editorglobalobject.h \ $$PWD/live/editorprivate_plugin.h \ $$PWD/live/palettecontainer.h \ - $$PWD/live/palettelist.h \ $$PWD/live/codepalette.h \ $$PWD/live/linecontrol.h \ $$PWD/live/syntaxhighlighter.h \ diff --git a/lib/lveditor/src/documenthandler.cpp b/lib/lveditor/src/documenthandler.cpp index 49327a53..405f608f 100644 --- a/lib/lveditor/src/documenthandler.cpp +++ b/lib/lveditor/src/documenthandler.cpp @@ -24,7 +24,6 @@ #include "live/viewengine.h" #include "live/visuallog.h" #include "live/visuallogqt.h" -#include "live/palettelist.h" #include "live/palettecontainer.h" #include "live/extensions.h" diff --git a/lib/lveditor/src/lveditor.pri b/lib/lveditor/src/lveditor.pri index 15440c81..c108f3d6 100644 --- a/lib/lveditor/src/lveditor.pri +++ b/lib/lveditor/src/lveditor.pri @@ -22,7 +22,6 @@ HEADERS += \ $$PWD/linesurface.h \ $$PWD/lveditorglobal.h \ $$PWD/palettecontainer.h \ - $$PWD/palettelist.h \ $$PWD/project.h \ $$PWD/projectdocument.h \ $$PWD/projectdocumentmodel.h \ @@ -66,7 +65,6 @@ SOURCES += \ $$PWD/linecontrol.cpp \ $$PWD/linesurface.cpp \ $$PWD/palettecontainer.cpp \ - $$PWD/palettelist.cpp \ $$PWD/project.cpp \ $$PWD/projectdocument.cpp \ $$PWD/projectdocumentmodel.cpp \ diff --git a/lib/lveditor/src/palettecontainer.cpp b/lib/lveditor/src/palettecontainer.cpp index 2f9ac8db..997701fb 100644 --- a/lib/lveditor/src/palettecontainer.cpp +++ b/lib/lveditor/src/palettecontainer.cpp @@ -19,7 +19,6 @@ #include "live/project.h" #include "live/visuallog.h" #include "live/visuallogqt.h" -#include "live/palettelist.h" #include "live/mlnode.h" #include "live/mlnodetojson.h" @@ -53,9 +52,9 @@ class PaletteLoader{ CodePalette* getItem(QQmlEngine* engine); QJSValue getContent(QQmlEngine* engine); const QString& path() const{ return m_path; } + const QString& type() const{ return m_type; } const QString& name() const{ return m_name; } bool configuresLayout() const{ return m_configuresLayout; } - private: void handleError(const QQmlComponent &component) const; @@ -140,6 +139,7 @@ QJSValue PaletteLoader::getContent(QQmlEngine *engine){ return QJSValue(); } + void PaletteLoader::handleError(const QQmlComponent &component) const{ foreach ( const QQmlError& error, component.errors() ){ qWarning( @@ -259,24 +259,19 @@ PaletteLoader *PaletteContainer::findPalette(const QString &type) const{ * * This list is Javascript-owned! */ -PaletteList *PaletteContainer::findPalettes(const QString &type, PaletteContainer::PaletteSearch searchType, lv::PaletteList *l){ +QList PaletteContainer::findPalettes(const QString &type){ Q_D(PaletteContainer); - if ( !l ){ - l = new PaletteList(this); - d->engine->setObjectOwnership(l, QQmlEngine::JavaScriptOwnership); - } + QList result; PaletteContainerPrivate::PaletteHash::Iterator it = d->items.find(type); while ( it != d->items.end() && it.key() == type ){ - if ( !it.value()->configuresLayout() || (searchType & IncludeLayoutConfigurations ) ){ - l->append(it.value()); - } + result.push_back(it.value()); ++it; } - return l; + return result; } /** @@ -335,6 +330,18 @@ bool PaletteContainer::configuresLayout(PaletteLoader *loader){ return loader->configuresLayout(); } +QJSValue PaletteContainer::paletteData(PaletteLoader *loader) +{ + Q_D(PaletteContainer); + QJSValue result = d->engine->newObject(); + result.setProperty("name", loader->name()); + result.setProperty("type", loader->type()); + result.setProperty("path", loader->path()); + result.setProperty("configuresLayout", loader->configuresLayout()); + + return result; +} + /** * \brief Return number of palette inside the container */ diff --git a/lib/lveditor/src/palettecontainer.h b/lib/lveditor/src/palettecontainer.h index e532ba00..daebc0eb 100644 --- a/lib/lveditor/src/palettecontainer.h +++ b/lib/lveditor/src/palettecontainer.h @@ -29,7 +29,6 @@ class QQmlComponent; namespace lv{ class CodePalette; -class PaletteList; class PaletteLoader; class PaletteContainerPrivate; class LV_EDITOR_EXPORT PaletteContainer{ @@ -50,7 +49,7 @@ class LV_EDITOR_EXPORT PaletteContainer{ PaletteLoader* findPaletteByName(const QString& name) const; PaletteLoader* findPalette(const QString& type) const; - PaletteList* findPalettes(const QString& type, PaletteSearch searchType, PaletteList* list = nullptr); + QList findPalettes(const QString& type); int countPalettes(const QString& type) const; static QString paletteName(PaletteLoader* loader); @@ -58,6 +57,7 @@ class LV_EDITOR_EXPORT PaletteContainer{ CodePalette* createPalette(PaletteLoader* loader); QJSValue paletteContent(PaletteLoader* loader); static bool configuresLayout(PaletteLoader* loader); + QJSValue paletteData(PaletteLoader* loader); int size() const; diff --git a/lib/lveditor/src/palettelist.cpp b/lib/lveditor/src/palettelist.cpp deleted file mode 100644 index d3025f99..00000000 --- a/lib/lveditor/src/palettelist.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include "palettelist.h" -#include "palettecontainer.h" -#include -#include "palettecontainer.h" - -/** - * \class lv::PaletteList - * \brief List of available palettes returned by a PaletteLoader - * - * \ingroup lveditor - */ -namespace lv{ - -/** - * \brief Default constructor - */ -PaletteList::PaletteList(PaletteContainer *container, QObject *parent) - : QAbstractListModel(parent) - , m_position(-1) - , m_paletteContainer(container) -{ -} - -/** - * \brief Default destructor - */ -PaletteList::~PaletteList(){ -} - -/** - * \brief Override of the respective QAbstractListModel function - */ -QVariant PaletteList::data(const QModelIndex &index, int role) const{ - if ( index.row() >= m_palettes.size() ) - return QVariant(); - if ( role == Qt::UserRole ) - return m_paletteContainer->paletteName(m_palettes[index.row()]); - return QVariant(); -} - -/** - * \brief Override of the respective QAbstractListModel function - */ -QHash PaletteList::roleNames() const{ - QHash roles; - roles[Qt::UserRole] = "name"; - return roles; -} - -/** - * \brief Appends the loader to the list - */ -void PaletteList::append(PaletteLoader *loader){ - m_palettes.append(loader); -} - -/** - * \brief Creates a palette from a loader at the given index - * - * It's a cpp-owned object! - */ -CodePalette* PaletteList::loadAt(int index){ - if ( index < m_palettes.size() ){ - CodePalette* lp = m_paletteContainer->createPalette(m_palettes[index]); - qmlEngine(this)->setObjectOwnership(lp, QQmlEngine::CppOwnership); - return lp; - } - return nullptr; -} - -QJSValue PaletteList::contentAt(int index){ - if ( index < m_palettes.size() ){ - return m_paletteContainer->paletteContent(m_palettes[index]); - } - return QJSValue(); -} - -void PaletteList::filterOut(const QStringList &names) -{ - decltype (m_palettes) result; - for (auto it = m_palettes.begin(); it != m_palettes.end(); ++it){ - auto paletteLoader = *it; - if (!names.contains(m_paletteContainer->paletteName(paletteLoader))){ - result.push_back(*it); - } - } - m_palettes = result; -} - - - -}// namespace diff --git a/lib/lveditor/src/palettelist.h b/lib/lveditor/src/palettelist.h deleted file mode 100644 index 40b569ef..00000000 --- a/lib/lveditor/src/palettelist.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef LVPALETTELIST_H -#define LVPALETTELIST_H - -#include -#include -#include "lveditorglobal.h" -#include "live/codepalette.h" - -namespace lv{ - -class PaletteLoader; -class PaletteContainer; -class LV_EDITOR_EXPORT PaletteList : public QAbstractListModel{ - - Q_OBJECT - -public: - explicit PaletteList(PaletteContainer* container, QObject *parent = nullptr); - ~PaletteList(); - - void setPosition(int position); - - QVariant data(const QModelIndex& index, int role) const; - int rowCount(const QModelIndex& parent) const; - QHash roleNames() const; - - void append(PaletteLoader* loader); - void remove(PaletteLoader* loader); - PaletteLoader* loaderAt(int index); - -public slots: - int position() const; - int size() const; - lv::CodePalette *loadAt(int index); - QJSValue contentAt(int index); - void filterOut(const QStringList& names); -private: - int m_position; - PaletteContainer* m_paletteContainer; - QList m_palettes; -}; - -/** Sets position */ -inline void PaletteList::setPosition(int position){ - m_position = position; -} - -/** - * \brief Override of the respective QAbstractListModel function - */ -inline int PaletteList::rowCount(const QModelIndex &) const{ - return size(); -} - -/** - * \brief Remove all appearances of this loader in the palettes - */ -inline void PaletteList::remove(PaletteLoader *loader){ - m_palettes.removeAll(loader); -} - -/** - * \brief Returns loader at given index - */ -inline PaletteLoader *PaletteList::loaderAt(int index){ - return m_palettes.at(index); -} - -/** - * \brief Returns position of palette - */ -inline int PaletteList::position() const{ - return m_position; -} - -/** Palettes size */ -inline int PaletteList::size() const{ - return m_palettes.size(); -} - -}// namespace - -#endif // LVPALETTELIST_H diff --git a/lib/lveditqmljs/src/codeqmlhandler.cpp b/lib/lveditqmljs/src/codeqmlhandler.cpp index 710f1d9b..adaf24dd 100644 --- a/lib/lveditqmljs/src/codeqmlhandler.cpp +++ b/lib/lveditqmljs/src/codeqmlhandler.cpp @@ -64,6 +64,7 @@ #include #include #include +#include "live/codepalette.h" namespace lv{ @@ -2570,59 +2571,48 @@ QString CodeQmlHandler::propertyType(QmlEditFragment *edit, const QString &prope return ""; } -lv::PaletteList* CodeQmlHandler::findPalettesFromFragment(lv::QmlEditFragment* fragment, bool includeLayoutConfigurations){ - if (!fragment || !fragment->declaration()) - return nullptr; +QJSValue CodeQmlHandler::findPalettesFromFragment(lv::QmlEditFragment* fragment){ + if (!fragment || !fragment->declaration()){ + + QJSValue res = m_engine->engine()->newObject(); + QJSValue data = m_engine->engine()->newArray(0); + res.setProperty("data", data); + QJSValue decl = m_engine->engine()->newObject(); + decl.setProperty("position", fragment->position()); + res.setProperty("declaration", decl); - return findPalettesForDeclaration(fragment->declaration(), includeLayoutConfigurations); + return res; + } + return findPalettesForDeclaration(fragment->declaration()); } /** * \brief Finds the available list of palettes at the current \p cursor position */ -lv::PaletteList* CodeQmlHandler::findPalettes(int position, bool includeLayoutConfigurations){ - if ( !m_document ) - return nullptr; +QJSValue CodeQmlHandler::findPalettes(int position){ + if ( !m_document ){ + QJSValue res = m_engine->engine()->newObject(); + QJSValue data = m_engine->engine()->newArray(0); + res.setProperty("data", data); + QJSValue decl = m_engine->engine()->newObject(); + decl.setProperty("position", position); + res.setProperty("declaration", decl); + return res; + } cancelEdit(); QList declarations = getDeclarations(position); - - return declarations.isEmpty() ? nullptr : findPalettesForDeclaration(declarations.first(), includeLayoutConfigurations); -} - -/** - * \brief Opens the palette \p index from a given \p paletteList - */ -QJSValue CodeQmlHandler::openPalette(lv::QmlEditFragment* edit, lv::PaletteList *paletteList, int index){ - if ( !m_document || !edit || !paletteList ) - return QJSValue(); - - // check if duplicate - PaletteLoader* paletteLoader = paletteList->loaderAt(index); - - if ( edit->bindingPalette() && edit->bindingPalette()->path() == PaletteContainer::palettePath(paletteLoader) ){ - edit->addPalette(edit->bindingPalette()); - return m_engine->engine()->newQObject(edit->bindingPalette()); + if (declarations.isEmpty()) { + QJSValue res = m_engine->engine()->newObject(); + QJSValue data = m_engine->engine()->newArray(0); + res.setProperty("data", data); + QJSValue decl = m_engine->engine()->newObject(); + decl.setProperty("position", position); + res.setProperty("declaration", decl); + return res; } - if ( !PaletteContainer::configuresLayout(paletteLoader) ){ - CodePalette* palette = paletteList->loadAt(index); - palette->setEditFragment(edit); - edit->addPalette(palette); - edit->initializePaletteValue(palette); - - connect(palette, &CodePalette::valueChanged, edit, &QmlEditFragment::updateFromPalette); - - rehighlightSection(edit->position(), edit->valuePosition() + edit->valueLength()); - - DocumentHandler* dh = static_cast(parent()); - if ( dh ) - dh->requestCursorPosition(edit->valuePosition()); - - return m_engine->engine()->newQObject(palette); - } else { - return paletteList->contentAt(index); - } + return findPalettesForDeclaration(declarations.first()); } bool CodeQmlHandler::isForAnObject(lv::QmlEditFragment *ef){ @@ -2671,12 +2661,13 @@ QString CodeQmlHandler::defaultPalette(QmlEditFragment *fragment){ * * \returns A pointer to the opened lv::CodePalette. */ -CodePalette *CodeQmlHandler::openBinding(QmlEditFragment *edit, PaletteList *paletteList, int index){ - if ( !m_document || !edit || !paletteList ) +CodePalette *CodeQmlHandler::openBinding(QmlEditFragment *edit, QString paletteName){ + Q_D(CodeQmlHandler); + if ( !m_document || !edit ) return nullptr; // check if duplicate - PaletteLoader* paletteLoader = paletteList->loaderAt(index); + PaletteLoader* paletteLoader = d->projectHandler->paletteContainer()->findPaletteByName(paletteName); if ( edit->bindingPalette() ){ if ( edit->bindingPalette()->path() == PaletteContainer::palettePath(paletteLoader) ) return edit->bindingPalette(); @@ -2687,7 +2678,8 @@ CodePalette *CodeQmlHandler::openBinding(QmlEditFragment *edit, PaletteList *pal return cp; } - CodePalette* palette = paletteList->loadAt(index); + CodePalette* palette = d->projectHandler->paletteContainer()->createPalette(paletteLoader); + qmlEngine(this)->setObjectOwnership(palette, QQmlEngine::CppOwnership); palette->setEditFragment(edit); edit->setBindingPalette(palette); @@ -2748,24 +2740,7 @@ QJSValue CodeQmlHandler::declarationInfo(int position, int length){ auto declaration = properties.first(); - QJSValue result = m_engine->engine()->newObject(); - result.setProperty("position", declaration->position()); - result.setProperty("length", declaration->length()); - result.setProperty("type", declaration->type().join()); - result.setProperty("parentType", declaration->parentType().join()); - if ( declaration->isForComponent() ){ - result.setProperty("type", "component"); - } else if ( declaration->isForImports() ){ - result.setProperty("type", "imports"); - } else if ( declaration->isForList() ){ - result.setProperty("type", "list"); - } else if ( declaration->isForProperty() ){ - result.setProperty("type", "property"); - } else if ( declaration->isForSlot() ){ - result.setProperty("type", "slot"); - } - result.setProperty("hasObject", declaration->isForObject()); - return result; + return declarationToQml(declaration); } /** @@ -3816,23 +3791,22 @@ bool CodeQmlHandler::isForAnObject(const lv::QmlDeclaration::Ptr &declaration){ return QmlTypeInfo::isObject(declaration->type().name()); } -PaletteList *CodeQmlHandler::findPalettesForDeclaration(QmlDeclaration::Ptr declaration, bool includeLayoutConfigurations) +QJSValue CodeQmlHandler::findPalettesForDeclaration(QmlDeclaration::Ptr declaration) { // every fragment has a declaration -> should end up here Q_D(CodeQmlHandler); QmlScopeSnap scope = d->snapScope(); - PaletteContainer::PaletteSearch configurations = includeLayoutConfigurations ? PaletteContainer::IncludeLayoutConfigurations : PaletteContainer::Empty; - - PaletteList* lpl = d->projectHandler->paletteContainer()->findPalettes(declaration->type().join(), configurations); + QList result = d->projectHandler->paletteContainer()->findPalettes(declaration->type().join()); if ( declaration->type().language() == QmlTypeReference::Qml ){ QmlInheritanceInfo typePath = scope.getTypePath(declaration->type()); for ( int i = 1; i < typePath.nodes.size(); ++i ){ QmlTypeInfo::Ptr ti = typePath.nodes[i]; if ( !ti->exportType().isEmpty() ){ - lpl = d->projectHandler->paletteContainer()->findPalettes(ti->exportType().join(), configurations, lpl); + auto list = d->projectHandler->paletteContainer()->findPalettes(ti->exportType().join()); + result.append(list); } } } @@ -3846,30 +3820,44 @@ PaletteList *CodeQmlHandler::findPalettesForDeclaration(QmlDeclaration::Ptr decl if ( pi.isValid() && !ti->exportType().isEmpty() ){ QString propSearch = ti->exportType().join() + "." + pi.name; - lpl = d->projectHandler->paletteContainer()->findPalettes(propSearch, configurations, lpl); + auto list = d->projectHandler->paletteContainer()->findPalettes(propSearch); + result.append(list); } } } if (declaration->isForComponent()){ - lpl = d->projectHandler->paletteContainer()->findPalettes("qml/Component", configurations, lpl); + auto components = d->projectHandler->paletteContainer()->findPalettes("qml/Component"); + result.append(components); } else { - if ( declaration->isForObject()) - if (declaration->type().name()[0].isUpper() && declaration->type().language() == QmlTypeReference::Qml){ - lpl = d->projectHandler->paletteContainer()->findPalettes("qml/Object", configurations, lpl); + if ( declaration->isForObject()){ + if (declaration->type().name()[0].isUpper() && declaration->type().language() == QmlTypeReference::Qml){ + auto object = d->projectHandler->paletteContainer()->findPalettes("qml/Object"); + result.append(object); + } } if ( declaration->isForList() ){ - lpl = d->projectHandler->paletteContainer()->findPalettes("qml/childlist", configurations, lpl); + auto child = d->projectHandler->paletteContainer()->findPalettes("qml/childlist"); + result.append(child); } else { - lpl = d->projectHandler->paletteContainer()->findPalettes("qml/property", configurations, lpl); + auto prop = d->projectHandler->paletteContainer()->findPalettes("qml/property"); + result.append(prop); } } + QJSValue res = m_engine->engine()->newObject(); + QJSValue data = m_engine->engine()->newArray(result.length()); + for (int i = 0; i < result.length(); ++i){ + data.setProperty(i, d->projectHandler->paletteContainer()->paletteData(result[i])); + } + res.setProperty("data", data); + + QJSValue decl = declarationToQml(declaration); + res.setProperty("declaration", decl); - lpl->setPosition(declaration->position() + (declaration->isForImports() ? 7 : 0)); - return lpl; + return res; } void CodeQmlHandler::createChannelForFragment(QmlEditFragment *parentFragment, QmlEditFragment *fragment, QmlBindingPath::Ptr bindingPath){ @@ -3912,6 +3900,28 @@ void CodeQmlHandler::createChannelForFragment(QmlEditFragment *parentFragment, Q } +QJSValue CodeQmlHandler::declarationToQml(QmlDeclaration::Ptr declaration) +{ + QJSValue result = m_engine->engine()->newObject(); + result.setProperty("position", declaration->position()); + result.setProperty("length", declaration->length()); + result.setProperty("type", declaration->type().join()); + result.setProperty("parentType", declaration->parentType().join()); + if ( declaration->isForComponent() ){ + result.setProperty("type", "component"); + } else if ( declaration->isForImports() ){ + result.setProperty("type", "imports"); + } else if ( declaration->isForList() ){ + result.setProperty("type", "list"); + } else if ( declaration->isForProperty() ){ + result.setProperty("type", "property"); + } else if ( declaration->isForSlot() ){ + result.setProperty("type", "slot"); + } + result.setProperty("hasObject", declaration->isForObject()); + return result; +} + void CodeQmlHandler::populateNestedObjectsForFragment(lv::QmlEditFragment *edit) { Q_D(CodeQmlHandler); diff --git a/lib/lveditqmljs/src/codeqmlhandler.h b/lib/lveditqmljs/src/codeqmlhandler.h index 681d6380..1dc9acb4 100644 --- a/lib/lveditqmljs/src/codeqmlhandler.h +++ b/lib/lveditqmljs/src/codeqmlhandler.h @@ -24,7 +24,6 @@ #include "live/lockedfileiosession.h" #include "live/viewengine.h" #include "live/settings.h" -#include "live/palettelist.h" #include "live/codecompletionmodel.h" #include "live/qmlimportsmodel.h" #include "live/documentqmlinfo.h" @@ -165,15 +164,14 @@ public slots: QString propertyType(lv::QmlEditFragment* edit, const QString& propertyName); - lv::PaletteList *findPalettesFromFragment(lv::QmlEditFragment* fragment, bool includeLayoutConfigurations = false); - lv::PaletteList *findPalettes(int position, bool includeLayoutConfigurations = false); + QJSValue findPalettesFromFragment(lv::QmlEditFragment* fragment); + QJSValue findPalettes(int position); - QJSValue openPalette(lv::QmlEditFragment* fragment, lv::PaletteList* palette, int index); lv::QmlEditFragment* removePalette(lv::CodePalette* palette); QString defaultPalette(lv::QmlEditFragment* fragment); - lv::CodePalette* openBinding(lv::QmlEditFragment* edit, lv::PaletteList* paletteList, int index); + lv::CodePalette* openBinding(lv::QmlEditFragment* edit, QString paletteName); void closeBinding(int position, int length); QJSValue expand(lv::QmlEditFragment* edit, const QJSValue& val); @@ -297,9 +295,10 @@ public slots: bool isBlockEmptySpace(const QTextBlock& bl); bool isForAnObject(const QmlDeclaration::Ptr& declaration); - lv::PaletteList* findPalettesForDeclaration(QmlDeclaration::Ptr decl, bool includeExpandables = false); + QJSValue findPalettesForDeclaration(QmlDeclaration::Ptr decl); void createChannelForFragment(QmlEditFragment* parentFragment, QmlEditFragment* fragment, QmlBindingPath::Ptr bindingPath); + QJSValue declarationToQml(QmlDeclaration::Ptr decl); private: QTextDocument* m_target; QmlJsHighlighter* m_highlighter; diff --git a/plugins/editor/qml/PaletteListView.qml b/plugins/editor/qml/PaletteListView.qml index 8f29974e..c4595f68 100644 --- a/plugins/editor/qml/PaletteListView.qml +++ b/plugins/editor/qml/PaletteListView.qml @@ -22,7 +22,7 @@ Input.SelectableListView{ anchors.leftMargin: 10 anchors.verticalCenter: parent.verticalCenter textStyle: root.style.labelStyle - text: model.name + text: modelData.name } MouseArea{ diff --git a/plugins/editor/qml/plugins.qmltypes b/plugins/editor/qml/plugins.qmltypes index 26a20424..0f8665a8 100644 --- a/plugins/editor/qml/plugins.qmltypes +++ b/plugins/editor/qml/plugins.qmltypes @@ -128,25 +128,6 @@ Module { exportMetaObjectRevisions: [0] Property { name: "load"; type: "QJSValue" } } - Component { - name: "lv::PaletteList" - prototype: "QAbstractListModel" - exports: ["editor/PaletteList 1.0"] - isCreatable: false - exportMetaObjectRevisions: [0] - Method { name: "position"; type: "int" } - Method { name: "size"; type: "int" } - Method { - name: "loadAt" - type: "lv::CodePalette*" - Parameter { name: "index"; type: "int" } - } - Method { - name: "contentAt" - type: "QJSValue" - Parameter { name: "index"; type: "int" } - } - } Component { name: "lv::TextSearch" prototype: "QObject" diff --git a/plugins/editor/src/editor_plugin.cpp b/plugins/editor/src/editor_plugin.cpp index a648c33a..cc51cd03 100644 --- a/plugins/editor/src/editor_plugin.cpp +++ b/plugins/editor/src/editor_plugin.cpp @@ -16,7 +16,6 @@ #include "editor_plugin.h" #include "live/codepalette.h" -#include "live/palettelist.h" #include "live/applicationcontext.h" #include "live/visuallog.h" #include "live/settings.h" @@ -35,9 +34,6 @@ void EditorPlugin::registerTypes(const char *uri){ // @uri editor - qmlRegisterUncreatableType( - uri, 1, 0, "PaletteList", "PaletteList can be accessed through a DocumentHandler." - ); qmlRegisterType(uri, 1, 0, "DocumentHandler"); qmlRegisterType(uri, 1, 0, "CodeCompletionModel"); qmlRegisterType(uri, 1, 0, "CodePalette"); diff --git a/plugins/editqml/qml/EditQmlExtension.qml b/plugins/editqml/qml/EditQmlExtension.qml index 5c8466dd..059a141c 100644 --- a/plugins/editqml/qml/EditQmlExtension.qml +++ b/plugins/editqml/qml/EditQmlExtension.qml @@ -121,7 +121,9 @@ WorkspaceExtension{ var importsPosition = codeHandler.findImportsPosition() var paletteImports = codeHandler.findPalettes(importsPosition) if (paletteImports) { - var pc = globals.paletteControls.shapePalette(editor, paletteImports, 0) + var position = paletteImports.declaration.position + paletteImports.data = globals.paletteControls.filterOutPalettes(paletteImports.data) + var pc = globals.paletteControls.shapePalette(editor, paletteImports.data[0].name, position) pc.item.width = Qt.binding(function(){ if (!pc.item.parent || !pc.item.parent.parent) return var editorSize = editor.width - editor.editor.lineSurfaceWidth - 30 - pc.item.parent.parent.headerWidth @@ -143,12 +145,18 @@ WorkspaceExtension{ return } - var paletteRoot = codeHandler.findPalettes(rootPosition) - if (paletteRoot){ + var palettesForRoot = codeHandler.findPalettes(rootPosition) + if (palettesForRoot){ if (callback) callback() else { - var oc = globals.paletteControls.shapePalette(editor, paletteRoot, 0) + var position = palettesForRoot.declaration.position + palettesForRoot.data = globals.paletteControls.filterOutPalettes(palettesForRoot.data) + var oc = globals.paletteControls.shapePalette( + editor, + palettesForRoot.data.length > 0 ? palettesForRoot.data[0].name: "", + position + ) oc.contentWidth = Qt.binding(function(){ return oc.containerContentWidth > oc.editorContentWidth ? oc.containerContentWidth : oc.editorContentWidth }) diff --git a/plugins/editqml/qml/PaletteControls.qml b/plugins/editqml/qml/PaletteControls.qml index 891d63cc..8361d450 100644 --- a/plugins/editqml/qml/PaletteControls.qml +++ b/plugins/editqml/qml/PaletteControls.qml @@ -696,22 +696,42 @@ QtObject{ openNestedProperties(objectContainer, true) } + function filterOutPalettes(palettes, names, includeLayouts){ + if ((!names || names.length === 0) && includeLayouts) + return palettes + + var result = [] + for (var i = 0; i < palettes.length; ++i){ + if (names && names.includes(palettes[i].name)) continue + if (!includeLayouts && palettes[i].configuresLayout) continue + + result.push(palettes[i]) + } + + return result + } + function addPaletteList(container, paletteGroup, aroundBox, mode, swap, listParent){ if (!container.editingFragment) return null var palettes = container.editor.documentHandler.codeHandler.findPalettesFromFragment( - container.editingFragment, - mode === PaletteControls.PaletteListMode.ObjectContainer || mode === PaletteControls.PaletteListMode.NodeEditor + container.editingFragment ) - palettes.filterOut(paletteGroup.palettesOpened) + var position = palettes.declaration.position + + palettes.data = filterOutPalettes( + palettes.data, + paletteGroup.palettesOpened, + mode === PaletteControls.PaletteListMode.ObjectContainer || mode === PaletteControls.PaletteListMode.NodeEditor + ) - if (!palettes || palettes.size() === 0) return null + if (!palettes.data || palettes.data.length === 0) return null var paletteList = createPaletteListView(listParent ? listParent : null, theme.selectableListView) - paletteList.model = palettes + paletteList.model = palettes.data var palListBox = null if (mode !== PaletteControls.PaletteListMode.NodeEditor){ @@ -759,7 +779,9 @@ QtObject{ paletteList.focus = false paletteList.model = null - var palette = container.editor.documentHandler.codeHandler.openPalette(container.editingFragment, palettes, index) + var palette = container.editor.documentHandler.codeHandler.expand(container.editingFragment, { + "palettes" : [palettes.data[index].name] + }) var paletteBox = openPalette(palette, container.editingFragment, container.editor, @@ -902,12 +924,16 @@ QtObject{ var rect = editor.getCursorRectangle() var paneCoords = editor.mapGlobalPosition() - if ( !palettes || palettes.size() === 0){ + + var position = palettes.declaration.position + palettes.data = filterOutPalettes(palettes.data) + + if ( !palettes.data || palettes.data.length === 0){ return } - if ( palettes.size() === 1 ){ - loadPalette(editor, palettes, 0) + if ( palettes.data.length === 1 ){ + loadPalette(editor, palettes.data, 0, position) } else { //Palette list box @@ -916,7 +942,7 @@ QtObject{ palList, rect, paneCoords, lk.layers.editor.environment.placement.bottom ) palListBox.color = 'transparent' - palList.model = palettes + palList.model = palettes.data editor.internalFocus = false palList.forceActiveFocus() lk.layers.workspace.panes.setActiveItem(palList, editor) @@ -932,28 +958,30 @@ QtObject{ editor.editor.forceFocus() palList.destroy() palListBox.destroy() - loadPalette(editor, palettes, index) + loadPalette(editor, palettes.data, index, position) }) } } function shape(editor){ var codeHandler = editor.documentHandler.codeHandler + var palettes = codeHandler.findPalettes(editor.textEdit.cursorPosition) + + var position = palettes.declaration.position - var palettes = codeHandler.findPalettes(editor.textEdit.cursorPosition, true) var rect = editor.getCursorRectangle() var cursorCoords = editor.mapGlobalPosition() - if ( !palettes || palettes.size() === 0 ){ - shapePalette(editor, palettes, -1) - } else if ( palettes.size() === 1 ){ - shapePalette(editor, palettes, 0) + if ( !palettes.data || palettes.data.length === 0 ){ + shapePalette(editor, "", position) + } else if ( palettes.length === 1 ){ + shapePalette(editor, palettes.data[0].name, position) } else { //Palette list box var palList = globals.paletteControls.createPaletteListView(null, currentTheme.selectableListView) var palListBox = lk.layers.editor.environment.createEditorBox(palList, rect, cursorCoords, lk.layers.editor.environment.placement.bottom) palListBox.color = 'transparent' - palList.model = palettes + palList.model = palettes.data editor.internalFocus = false palList.forceActiveFocus() lk.layers.workspace.panes.setActiveItem(palList, editor) @@ -969,7 +997,7 @@ QtObject{ editor.editor.forceFocus() palList.destroy() palListBox.destroy() - shapePalette(editor, palettes, index) + shapePalette(editor, palettes.data[index].name, position) }) } } @@ -978,17 +1006,20 @@ QtObject{ var codeHandler = editor.documentHandler.codeHandler var palettes = codeHandler.findPalettes(editor.textEdit.cursorPosition) + var position = palettes.declaration.position + palettes = filterOutPalettes(palettes) + var rect = editor.getCursorRectangle() var cursorCoords = editor.mapGlobalPosition() - if ( palettes.size() === 1 ){ - var ef = codeHandler.openConnection(palettes.position()) + if ( palettes.data.length === 1 ){ + var ef = codeHandler.openConnection(position) ef.incrementRefCount() - codeHandler.openBinding(ef, palettes, 0) + codeHandler.openBinding(ef, palettes.data[0].name) } else { var palList = createPaletteListView(null, theme.selectableListView) var palListBox = lk.layers.editor.environment.createEditorBox(palList, rect, cursorCoords, lk.layers.editor.environment.placement.bottom) palListBox.color = 'transparent' - palList.model = palettes + palList.model = palettes.data editor.internalFocus = false palList.forceActiveFocus() lk.layers.workspace.panes.setActiveItem(palList, editor) @@ -1005,21 +1036,20 @@ QtObject{ palList.destroy() palListBox.destroy() - var ef = codeHandler.openConnection(palettes.position()) + var ef = codeHandler.openConnection(position) ef.incrementRefCount() - - codeHandler.openBinding(ef, palettes, index) + codeHandler.openBinding(ef, palettes.data[index].name) }) } } - function shapePalette(editor, palettes, index){ + function shapePalette(editor, paletteName, position){ var codeHandler = editor.documentHandler.codeHandler - var ef = codeHandler.openConnection(palettes.position()) + var ef = codeHandler.openConnection(position) if (!ef){ lk.layers.workspace.panes.focusPane('viewer').error.text += "
Error: Can't shape palette" - throw linkError(new Error('Failed to find editing fragment for palette at: ' + palettes.position(), 300)) + throw linkError(new Error('Failed to find editing fragment for palette at: ' + position, 300)) } var forAnObject = ef.location === QmlEditFragment.Object @@ -1051,7 +1081,12 @@ QtObject{ objectContainer = p } - var palette = palettes.size() > 0 && !(forAnObject && palettes.size() === 1)? codeHandler.openPalette(ef, palettes, index) : null + + var palette = paletteName !== "" + ? editor.documentHandler.codeHandler.expand(ef, { + "palettes" : [paletteName] + }) + : null var forImports = ef.location === QmlEditFragment.Imports if (palette){ @@ -1079,13 +1114,13 @@ QtObject{ return objectContainer ? objectContainer : palette } - function loadPalette(editor, palettes, index){ + function loadPalette(editor, palettes, index, position){ var codeHandler = editor.documentHandler.codeHandler var rect = editor.editor.getCursorRectangle() var cursorCoords = editor.cursorWindowCoords() - var ef = codeHandler.openConnection(palettes.position()) + var ef = codeHandler.openConnection(position) if (!ef) { @@ -1094,7 +1129,9 @@ QtObject{ } ef.incrementRefCount() - var palette = codeHandler.openPalette(ef, palettes, index) + var palette = editor.documentHandler.codeHandler.expand(ef, { + "palettes" : [palettes[index].name] + }) var editorBox = ef.visualParent ? ef.visualParent.parent : null var paletteBoxGroup = editorBox ? editorBox.child : null diff --git a/plugins/lcvcore/qml/EditCvExtension.qml b/plugins/lcvcore/qml/EditCvExtension.qml index 813c4727..b9c3eef2 100644 --- a/plugins/lcvcore/qml/EditCvExtension.qml +++ b/plugins/lcvcore/qml/EditCvExtension.qml @@ -239,8 +239,14 @@ WorkspaceExtension{ var rootPosition = lk.layers.workspace.extensions.editqml.rootPosition = codeHandler.findRootPosition() lk.layers.workspace.extensions.editqml.shapeImports(editor, codeHandler) lk.layers.workspace.extensions.editqml.shapeRootObject(editor, editor.documentHandler.codeHandler, function(){ - var paletteRoot = codeHandler.findPalettes(rootPosition) - var oc = lk.layers.workspace.extensions.editqml.paletteControls.shapePalette(editor, paletteRoot, 0) + var palettesForRoot = codeHandler.findPalettes(rootPosition) + var pos = palettesForRoot.declaration.position + palettesForRoot.data = lk.layers.workspace.extensions.editqml.paletteControls.filterOutPalettes(palettesForRoot.data) + var oc = lk.layers.workspace.extensions.editqml.paletteControls.shapePalette( + editor, + palettesForRoot.data.length > 0 ? palettesForRoot.data[0].name: "", + pos + ) oc.contentWidth = Qt.binding(function(){ return oc.containerContentWidth > oc.editorContentWidth ? oc.containerContentWidth : oc.editorContentWidth }) @@ -288,8 +294,14 @@ WorkspaceExtension{ var rootPosition = lk.layers.workspace.extensions.editqml.rootPosition = codeHandler.findRootPosition() lk.layers.workspace.extensions.editqml.shapeImports(editor, codeHandler) lk.layers.workspace.extensions.editqml.shapeRootObject(editor, editor.documentHandler.codeHandler, function(){ - var paletteRoot = codeHandler.findPalettes(rootPosition) - var oc = lk.layers.workspace.extensions.editqml.paletteControls.shapePalette(editor, paletteRoot, 0) + var palettesForRoot = codeHandler.findPalettes(rootPosition) + var pos = palettesForRoot.declaration.position + palettesForRoot.data = lk.layers.workspace.extensions.editqml.paletteControls.filterOutPalettes(palettesForRoot.data) + var oc = lk.layers.workspace.extensions.editqml.paletteControls.shapePalette( + editor, + palettesForRoot.data.length > 0 ? palettesForRoot.data[0].name: "", + pos + ) oc.contentWidth = Qt.binding(function(){ return oc.containerContentWidth > oc.editorContentWidth ? oc.containerContentWidth : oc.editorContentWidth }) diff --git a/plugins/visual/visualqml/input/qml/PathInputBox.qml b/plugins/visual/visualqml/input/qml/PathInputBox.qml index c62067e5..d9c9660a 100644 --- a/plugins/visual/visualqml/input/qml/PathInputBox.qml +++ b/plugins/visual/visualqml/input/qml/PathInputBox.qml @@ -52,8 +52,8 @@ Item{ InputBox{ id: pathInput - anchors.left: parent.left - width: parent.width - 31 + anchors.left: parent ? parent.left : undefined + width: parent ? parent.width - 31 : 0 height: root.height style: root.style.inputBoxStyle @@ -66,7 +66,7 @@ Item{ } Input.TextButton{ - anchors.right: parent.right + anchors.right: parent ? parent.right : undefined radius: 5 width: 30 height: root.height diff --git a/plugins/workspace/nodeeditor/qml/ObjectGraphControls.qml b/plugins/workspace/nodeeditor/qml/ObjectGraphControls.qml index cb657cc3..7aa613bf 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectGraphControls.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectGraphControls.qml @@ -39,8 +39,14 @@ QtObject{ var rootPosition = lk.layers.workspace.extensions.editqml.rootPosition = codeHandler.findRootPosition() lk.layers.workspace.extensions.editqml.shapeImports(editor, codeHandler) lk.layers.workspace.extensions.editqml.shapeRootObject(editor, editor.documentHandler.codeHandler, function(){ - var paletteRoot = codeHandler.findPalettes(rootPosition) - var oc = lk.layers.workspace.extensions.editqml.paletteControls.shapePalette(editor, paletteRoot, 0) + var palettesForRoot = codeHandler.findPalettes(rootPosition) + var pos = palettesForRoot.declaration.position + palettesForRoot.data = lk.layers.workspace.extensions.editqml.paletteControls.filterOutPalettes(palettesForRoot.data) + var oc = lk.layers.workspace.extensions.editqml.paletteControls.shapePalette( + editor, + palettesForRoot.data.length > 0 ? palettesForRoot.data[0] : "", + pos + ) oc.contentWidth = Qt.binding(function(){ return oc.containerContentWidth > oc.editorContentWidth ? oc.containerContentWidth : oc.editorContentWidth }) From efdd90d95662c4d2ccb596bf23ae63d8fac322af Mon Sep 17 00:00:00 2001 From: nenad-popovic-91 <42581059+nenad-popovic-91@users.noreply.github.com> Date: Fri, 25 Jun 2021 16:46:33 +0200 Subject: [PATCH 76/91] Removing extra variables in PaletteControls, removing editFragment slots (#223) PaletteControls, removing editFragment slots --- lib/lveditqmljs/src/codeqmlhandler.cpp | 36 +--- .../palettes/ActTriggerTypePalette.qml | 4 - plugins/base/baseqml/palettes/ExecPalette.qml | 3 - plugins/editor/palettes/BooleanPalette.qml | 7 - plugins/editor/palettes/ColorPalette.qml | 6 - plugins/editor/palettes/ConnectionPalette.qml | 6 - .../palettes/DoubleHistoryPlotPalette.qml | 6 - plugins/editor/palettes/DoublePalette.qml | 7 - plugins/editor/palettes/FilePathPalette.qml | 5 - plugins/editor/palettes/FolderPathPalette.qml | 6 - plugins/editor/palettes/ImportsPalette.qml | 6 - .../editor/palettes/IntHistoryPlotPalette.qml | 6 - plugins/editor/palettes/IntInputPalette.qml | 5 - plugins/editor/palettes/IntPalette.qml | 5 - plugins/editor/palettes/NodePalette.qml | 32 ++-- plugins/editor/palettes/SizePalette.qml | 8 - plugins/editor/palettes/StringListPalette.qml | 6 - plugins/editor/palettes/TextPalette.qml | 5 - plugins/editor/palettes/TriggerPalette.qml | 6 - plugins/editqml/qml/EditQmlExtension.qml | 2 +- plugins/editqml/qml/ObjectContainer.qml | 16 +- plugins/editqml/qml/PaletteContainer.qml | 15 +- plugins/editqml/qml/PaletteControls.qml | 168 ++++++++---------- .../palettes/ImageSegmentFactoryPalette.qml | 4 - .../lcvcore/palettes/VideoCapturePalette.qml | 9 - plugins/lcvcore/palettes/VideoFilePalette.qml | 9 - .../lcvcore/palettes/VideoPlayerPalette.qml | 10 -- plugins/lcvcore/qml/EditCvExtension.qml | 4 +- .../qml/palettes/TransformPalette.qml | 11 +- .../palettes/BrightnessAndContrastPalette.qml | 8 - .../HueSaturationLightnessPalette.qml | 10 -- plugins/lcvphoto/palettes/LevelsPalette.qml | 9 - plugins/timeline/palettes/TimelinePalette.qml | 3 - .../workspace/nodeeditor/qml/ObjectGraph.qml | 21 ++- .../nodeeditor/qml/ObjectGraphControls.qml | 2 +- .../workspace/nodeeditor/qml/ObjectNode.qml | 8 +- 36 files changed, 135 insertions(+), 339 deletions(-) diff --git a/lib/lveditqmljs/src/codeqmlhandler.cpp b/lib/lveditqmljs/src/codeqmlhandler.cpp index adaf24dd..950a0e3b 100644 --- a/lib/lveditqmljs/src/codeqmlhandler.cpp +++ b/lib/lveditqmljs/src/codeqmlhandler.cpp @@ -2572,17 +2572,9 @@ QString CodeQmlHandler::propertyType(QmlEditFragment *edit, const QString &prope } QJSValue CodeQmlHandler::findPalettesFromFragment(lv::QmlEditFragment* fragment){ - if (!fragment || !fragment->declaration()){ - - QJSValue res = m_engine->engine()->newObject(); - QJSValue data = m_engine->engine()->newArray(0); - res.setProperty("data", data); - QJSValue decl = m_engine->engine()->newObject(); - decl.setProperty("position", fragment->position()); - res.setProperty("declaration", decl); + if (!fragment || !fragment->declaration()) + return QJSValue(); - return res; - } return findPalettesForDeclaration(fragment->declaration()); } @@ -2590,27 +2582,15 @@ QJSValue CodeQmlHandler::findPalettesFromFragment(lv::QmlEditFragment* fragment) * \brief Finds the available list of palettes at the current \p cursor position */ QJSValue CodeQmlHandler::findPalettes(int position){ - if ( !m_document ){ - QJSValue res = m_engine->engine()->newObject(); - QJSValue data = m_engine->engine()->newArray(0); - res.setProperty("data", data); - QJSValue decl = m_engine->engine()->newObject(); - decl.setProperty("position", position); - res.setProperty("declaration", decl); - return res; - } + if ( !m_document ) + return QJSValue(); + cancelEdit(); QList declarations = getDeclarations(position); - if (declarations.isEmpty()) { - QJSValue res = m_engine->engine()->newObject(); - QJSValue data = m_engine->engine()->newArray(0); - res.setProperty("data", data); - QJSValue decl = m_engine->engine()->newObject(); - decl.setProperty("position", position); - res.setProperty("declaration", decl); - return res; - } + if (declarations.isEmpty()) + return QJSValue(); + return findPalettesForDeclaration(declarations.first()); } diff --git a/plugins/base/baseqml/palettes/ActTriggerTypePalette.qml b/plugins/base/baseqml/palettes/ActTriggerTypePalette.qml index 28ec5adc..98631477 100644 --- a/plugins/base/baseqml/palettes/ActTriggerTypePalette.qml +++ b/plugins/base/baseqml/palettes/ActTriggerTypePalette.qml @@ -87,8 +87,4 @@ CodePalette{ dropdown.currentIndex = 0 } } - - onEditFragmentChanged: { - editFragment.whenBinding = function(){} - } } diff --git a/plugins/base/baseqml/palettes/ExecPalette.qml b/plugins/base/baseqml/palettes/ExecPalette.qml index f1a9a7fb..8f595e9b 100644 --- a/plugins/base/baseqml/palettes/ExecPalette.qml +++ b/plugins/base/baseqml/palettes/ExecPalette.qml @@ -99,7 +99,4 @@ CodePalette{ execBox.current = value } - onEditFragmentChanged: { - editFragment.whenBinding = function(){} - } } diff --git a/plugins/editor/palettes/BooleanPalette.qml b/plugins/editor/palettes/BooleanPalette.qml index e82a26b0..194b4595 100644 --- a/plugins/editor/palettes/BooleanPalette.qml +++ b/plugins/editor/palettes/BooleanPalette.qml @@ -50,11 +50,4 @@ CodePalette { checked = value } - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.write(palette.value) - } - } - - } diff --git a/plugins/editor/palettes/ColorPalette.qml b/plugins/editor/palettes/ColorPalette.qml index 271d3d36..6c4b3b5a 100644 --- a/plugins/editor/palettes/ColorPalette.qml +++ b/plugins/editor/palettes/ColorPalette.qml @@ -112,12 +112,6 @@ CodePalette{ } } - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.write(palette.value) - } - } - onInit: { palette.selectedColor = value colorPicker.color = value diff --git a/plugins/editor/palettes/ConnectionPalette.qml b/plugins/editor/palettes/ConnectionPalette.qml index a698b04b..d0f6ca2d 100644 --- a/plugins/editor/palettes/ConnectionPalette.qml +++ b/plugins/editor/palettes/ConnectionPalette.qml @@ -231,12 +231,6 @@ CodePalette{ input.forceActiveFocus() } - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.write(palette.value) - } - } - Component.onDestruction: { if (!qmlSuggestionBox) return var par = qmlSuggestionBox.parent diff --git a/plugins/editor/palettes/DoubleHistoryPlotPalette.qml b/plugins/editor/palettes/DoubleHistoryPlotPalette.qml index 45f07a73..2bb5e5d8 100644 --- a/plugins/editor/palettes/DoubleHistoryPlotPalette.qml +++ b/plugins/editor/palettes/DoubleHistoryPlotPalette.qml @@ -29,12 +29,6 @@ CodePalette{ } } - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.write(palette.value) - } - } - onInit: { valueHistory.currentValue = value } diff --git a/plugins/editor/palettes/DoublePalette.qml b/plugins/editor/palettes/DoublePalette.qml index 4c73c6a9..487f492b 100644 --- a/plugins/editor/palettes/DoublePalette.qml +++ b/plugins/editor/palettes/DoublePalette.qml @@ -270,12 +270,6 @@ CodePalette{ } - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.write(palette.value) - } - } - function updateSliders(value){ if (value < intSlider.minimumValue || value > intSlider.maximumValue){ if (value > 0){ @@ -301,7 +295,6 @@ CodePalette{ } onInit: { - console.log("ON INTIALIZE:" + value) if (isNaN(value)){ palette.value = NaN numberInput.text = 'NaN' diff --git a/plugins/editor/palettes/FilePathPalette.qml b/plugins/editor/palettes/FilePathPalette.qml index d0272ca7..89abe65a 100644 --- a/plugins/editor/palettes/FilePathPalette.qml +++ b/plugins/editor/palettes/FilePathPalette.qml @@ -40,9 +40,4 @@ CodePalette{ inputBox.path = value } - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.write(palette.value) - } - } } diff --git a/plugins/editor/palettes/FolderPathPalette.qml b/plugins/editor/palettes/FolderPathPalette.qml index fce30b81..c942442f 100644 --- a/plugins/editor/palettes/FolderPathPalette.qml +++ b/plugins/editor/palettes/FolderPathPalette.qml @@ -40,10 +40,4 @@ CodePalette{ onInit: { inputBox.path = value } - - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.write(palette.value) - } - } } diff --git a/plugins/editor/palettes/ImportsPalette.qml b/plugins/editor/palettes/ImportsPalette.qml index 82e1c003..0d2001cc 100644 --- a/plugins/editor/palettes/ImportsPalette.qml +++ b/plugins/editor/palettes/ImportsPalette.qml @@ -228,10 +228,4 @@ CodePalette{ } } - - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.write(palette.value) - } - } } diff --git a/plugins/editor/palettes/IntHistoryPlotPalette.qml b/plugins/editor/palettes/IntHistoryPlotPalette.qml index fb4c5dbb..89b30b4f 100644 --- a/plugins/editor/palettes/IntHistoryPlotPalette.qml +++ b/plugins/editor/palettes/IntHistoryPlotPalette.qml @@ -24,10 +24,4 @@ CodePalette{ onValueFromBindingChanged: { valueHistory.currentValue = value } - - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.write(palette.value) - } - } } diff --git a/plugins/editor/palettes/IntInputPalette.qml b/plugins/editor/palettes/IntInputPalette.qml index 8329e6f5..2f1fb2fd 100644 --- a/plugins/editor/palettes/IntInputPalette.qml +++ b/plugins/editor/palettes/IntInputPalette.qml @@ -60,9 +60,4 @@ CodePalette{ root.path = value } - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.write(palette.value) - } - } } diff --git a/plugins/editor/palettes/IntPalette.qml b/plugins/editor/palettes/IntPalette.qml index 4a7ea476..27aed672 100644 --- a/plugins/editor/palettes/IntPalette.qml +++ b/plugins/editor/palettes/IntPalette.qml @@ -220,9 +220,4 @@ CodePalette{ intSlider.value = floorValue } - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.write(palette.value) - } - } } diff --git a/plugins/editor/palettes/NodePalette.qml b/plugins/editor/palettes/NodePalette.qml index 4c5aeb37..cff15522 100644 --- a/plugins/editor/palettes/NodePalette.qml +++ b/plugins/editor/palettes/NodePalette.qml @@ -11,7 +11,6 @@ CodePalette{ id: palette type: "qml/Object" - property var editingFragment: null property var documentHandler: null property var editor: null property var objectsWithId: ({}) @@ -20,12 +19,6 @@ CodePalette{ property QtObject theme: lk.layers.workspace.themes.current - onEditingFragmentChanged: { - if (!editingFragment) return - - nodeItem.init() - } - function addObject(object, cursorCoords){ var n if (cursorCoords){ @@ -65,7 +58,7 @@ CodePalette{ } function init(){ - var objectList = editingFragment.nestedObjectsInfo() + var objectList = editFragment.nestedObjectsInfo() var props = [] for (var i = 0; i < objectList.length; ++i) { @@ -170,23 +163,24 @@ CodePalette{ palette: palette documentHandler: palette.documentHandler editor: palette.editor - editingFragment: palette ? palette.editingFragment: null + editingFragment: palette.editFragment style: theme.nodeEditor } } - property Connections connTest: Connections{ - id: efConnection - target: editingFragment - - function onObjectAdded(obj, cursorCoords){ + onInit: { + if (!editFragment) return + editor = editFragment.codeHandler.documentHandler.textEdit().getEditor() + documentHandler = editFragment.codeHandler.documentHandler + editFragment.codeHandler.populateNestedObjectsForFragment(editFragment) + objectGraph.editingFragment = editFragment + nodeItem.init() + editFragment.objectAdded.connect(function(obj, cursorCoords){ addObject(obj.objectInfo(), cursorCoords) - } - function onAboutToRemovePalette(palette){ + }) + editFragment.aboutToRemovePalette.connect(function(palette){ nodeItem.clean() - } - ignoreUnknownSignals: true + }) } - } diff --git a/plugins/editor/palettes/SizePalette.qml b/plugins/editor/palettes/SizePalette.qml index 2d0585ca..056eef40 100644 --- a/plugins/editor/palettes/SizePalette.qml +++ b/plugins/editor/palettes/SizePalette.qml @@ -87,12 +87,4 @@ CodePalette { widthInput.text = value.width heightInput.text = value.height } - - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.write(palette.value) - } - } - - } diff --git a/plugins/editor/palettes/StringListPalette.qml b/plugins/editor/palettes/StringListPalette.qml index 201eb276..31f5c6a6 100644 --- a/plugins/editor/palettes/StringListPalette.qml +++ b/plugins/editor/palettes/StringListPalette.qml @@ -179,12 +179,6 @@ CodePalette{ } } - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.write(itemList.modelToArray()) - } - } - onValueFromBindingChanged: { argsContainer.model.clear() for (var i = 0; i < value.length; ++i) diff --git a/plugins/editor/palettes/TextPalette.qml b/plugins/editor/palettes/TextPalette.qml index b6431f3b..5e223809 100644 --- a/plugins/editor/palettes/TextPalette.qml +++ b/plugins/editor/palettes/TextPalette.qml @@ -60,9 +60,4 @@ CodePalette{ root.path = value } - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.write(palette.value) - } - } } diff --git a/plugins/editor/palettes/TriggerPalette.qml b/plugins/editor/palettes/TriggerPalette.qml index 552827db..83dcad82 100644 --- a/plugins/editor/palettes/TriggerPalette.qml +++ b/plugins/editor/palettes/TriggerPalette.qml @@ -227,12 +227,6 @@ CodePalette{ input.forceActiveFocus() } - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.write(palette.value) - } - } - Component.onDestruction: { if (!qmlSuggestionBox) return var par = qmlSuggestionBox.parent diff --git a/plugins/editqml/qml/EditQmlExtension.qml b/plugins/editqml/qml/EditQmlExtension.qml index 059a141c..b53fe4c2 100644 --- a/plugins/editqml/qml/EditQmlExtension.qml +++ b/plugins/editqml/qml/EditQmlExtension.qml @@ -303,7 +303,7 @@ WorkspaceExtension{ var activePane = lk.layers.workspace.panes.activePane var activeItem = lk.layers.workspace.panes.activeItem if ( activePane.paneType === 'editor' && activeItem.objectName === 'objectContainerFrame' ){ - lk.layers.workspace.extensions.editqml.paletteControls.compose(activeItem, false) + lk.layers.workspace.extensions.editqml.paletteControls.compose(activeItem) } } diff --git a/plugins/editqml/qml/ObjectContainer.qml b/plugins/editqml/qml/ObjectContainer.qml index 049543e0..283b44b7 100644 --- a/plugins/editqml/qml/ObjectContainer.qml +++ b/plugins/editqml/qml/ObjectContainer.qml @@ -43,7 +43,7 @@ Item{ } property double containerContentWidth : 0 - property double editorContentWidth: editor && !parentObjectContainer ? editor.width - editor.editor.lineSurfaceWidth - 50 : 0 + property double editorContentWidth: editor && !parentObjectContainer ? editor.width - editor.lineSurfaceWidth - 50 : 0 property alias editingFragment : objectContainer.editingFragment property alias editor : objectContainer.editor @@ -107,12 +107,6 @@ Item{ return childObjectContainer } - function addPropertyFragmentToContainer(ef, expandDefault){ - if (!ef) return - - paletteControls.addPropertyContainer(root, ef, expandDefault) - } - function destroyObjectContainer(oc){ for (var pi = 0; pi < oc.groupsContainer.children.length; ++pi){ var child = oc.groupsContainer.children[pi] @@ -195,7 +189,7 @@ Item{ var palettes = options['palettes'] for ( var i = 0; i < palettes.length; ++i){ if (paletteGroup.palettesOpened.indexOf(palettes[i]) !== -1) continue - paletteControls.openPaletteByName(palettes[i], objectContainer.editingFragment, editor, paletteGroup) + paletteControls.openPaletteByName(palettes[i], objectContainer.editingFragment, paletteGroup) } } @@ -240,7 +234,7 @@ Item{ if (child.title !== propName) continue if (child.valueContainer.palettesOpened && child.valueContainer.palettesOpened.indexOf(propPalette) !== -1) break - paletteControls.openPaletteByName(propPalette, ef, editor, child.valueContainer) + paletteControls.openPaletteByName(propPalette, ef, child.valueContainer) break } @@ -339,7 +333,7 @@ Item{ editor.documentHandler.codeHandler.populateNestedObjectsForFragment(editingFragment) if (compact) expand() - addPropertyFragmentToContainer(ef, expandDefault) + paletteControls.addPropertyContainer(root, ef, expandDefault) container.sortChildren() } } @@ -424,7 +418,7 @@ Item{ } } onCompose : { - paletteControls.compose(objectContainer, false) + paletteControls.compose(objectContainer) } onCreateObject: { diff --git a/plugins/editqml/qml/PaletteContainer.qml b/plugins/editqml/qml/PaletteContainer.qml index 03a6e386..9697daef 100644 --- a/plugins/editqml/qml/PaletteContainer.qml +++ b/plugins/editqml/qml/PaletteContainer.qml @@ -26,15 +26,15 @@ Rectangle{ property bool compact: true property bool isBuilder : false - property Item child : null + property Item child : palette ? palette.item : null property QtObject palette : null property bool isCompactVertical: child && child.height > 48 color: "black" - property string name : '' - property string type : '' + property string name : palette ? palette.name : '' + property string type : palette ? palette.type : '' property string title : type + ' - ' + name property var cursorRectangle : null property var editorPosition : null @@ -42,6 +42,13 @@ Rectangle{ property Item pane: null property Item dragPane: null + onEditingFragmentChanged: { + if (!editingFragment) return + editor = editingFragment.codeHandler.documentHandler.textEdit().getEditor() + cursorRectangle = editor.getCursorRectangle() + editorPosition = editor.cursorWindowCoords() + } + property bool paletteSwapVisible: false property bool paletteAddVisible: false @@ -51,7 +58,7 @@ Rectangle{ property double titleLeftMargin : 50 property double titleRightMargin : 50 - property DocumentHandler documentHandler : null + property DocumentHandler documentHandler : editor ? editor.documentHandler: null property var paletteControls: lk.layers.workspace.extensions.editqml.paletteControls diff --git a/plugins/editqml/qml/PaletteControls.qml b/plugins/editqml/qml/PaletteControls.qml index 8361d450..2b4472a7 100644 --- a/plugins/editqml/qml/PaletteControls.qml +++ b/plugins/editqml/qml/PaletteControls.qml @@ -86,27 +86,27 @@ QtObject{ ////////////////////////////////////////////// - function openDefaultPalette(editingFragment, editor, paletteBoxParent, objectRoot){ + function openDefaultPalette(editingFragment, paletteBoxParent, objectRoot){ + if (!editingFragment) return + var editor = editingFragment.codeHandler.documentHandler.textEdit().getEditor() var defaultPaletteName = editor.documentHandler.codeHandler.defaultPalette(editingFragment) if ( defaultPaletteName.length ){ openPaletteByName(defaultPaletteName, editingFragment, - editor, paletteBoxParent, objectRoot) } } - function openPaletteByName(paletteName, editingFragment, editor, paletteBoxParent, objectRoot){ + function openPaletteByName(paletteName, editingFragment, paletteBoxParent, objectRoot){ if ( !editingFragment ) return + var editor = editingFragment.codeHandler.documentHandler.textEdit().getEditor() var palette = editor.documentHandler.codeHandler.expand(editingFragment, { "palettes" : [paletteName] }) var paletteBox = openPalette(palette, - editingFragment, - editor, paletteBoxParent, objectRoot) if (paletteBox) paletteBox.moveEnabledSet = false @@ -114,34 +114,19 @@ QtObject{ return paletteBox } - function openPalette(palette, editingFragment, editor, paletteBoxParent, objectRoot){ - if (!palette) return + function openPalette(palette, paletteBoxParent, objectRoot){ - if (palette.type === "qml/Object") - { - palette.documentHandler = editor.documentHandler - palette.editor = editor - editor.documentHandler.codeHandler.populateNestedObjectsForFragment(editingFragment) - palette.editingFragment = editingFragment - } + if (!palette) return if ( palette.item ){ var newPaletteBox = createPaletteContainer(paletteBoxParent) palette.item.x = 2 palette.item.y = 2 - newPaletteBox.child = palette.item newPaletteBox.palette = palette - newPaletteBox.name = palette.name - newPaletteBox.type = palette.type - if ( paletteBoxParent.palettesOpened ) paletteBoxParent.palettesOpened.push(palette.name) - newPaletteBox.documentHandler = editor.documentHandler - newPaletteBox.cursorRectangle = editor.getCursorRectangle() - newPaletteBox.editorPosition = editor.cursorWindowCoords() - newPaletteBox.editor = editor if (objectRoot && objectRoot.compact) objectRoot.expand() @@ -151,16 +136,9 @@ QtObject{ if (objectRoot) objectRoot.expandOptions(palette) } - function addChildObjectContainer(parentObjectContainer, ef, expandDefault, propertyContainer, propPalette){ - if (propertyContainer) - propertyContainer.isAnObject = true - + function addChildObjectContainer(parentObjectContainer, ef, expandDefault){ var childObjectContainer = createObjectContainer(parentObjectContainer.groupsContainer) - if (propertyContainer){ - propertyContainer.childObjectContainer = childObjectContainer - childObjectContainer.isForProperty = true - } childObjectContainer.parentObjectContainer = parentObjectContainer childObjectContainer.editor = parentObjectContainer.editor @@ -176,29 +154,19 @@ QtObject{ ef.visualParent = paletteBoxGroup childObjectContainer.paletteGroup = paletteBoxGroup - if (propertyContainer) - propertyContainer.valueContainer = childObjectContainer - if ( propPalette ){ - openPaletteByName(propPalette, - ef, - childObjectContainer.editor, - paletteBoxGroup, - childObjectContainer) - } else if (expandDefault) { + if (expandDefault) { openDefaultPalette(ef, - childObjectContainer.editor, - childObjectContainer.paletteGroup, - childObjectContainer) + childObjectContainer.paletteGroup, + childObjectContainer) } - if (propertyContainer) - propertyContainer.paletteAddButtonVisible = false return childObjectContainer } - function addItemToRuntime(codeHandler, ef, insPosition, parentType, type){ + function addItemToRuntime(ef, insPosition, parentType, type){ + var codeHandler = ef.codeHandler var opos = codeHandler.addItem( insPosition, parentType, @@ -215,9 +183,7 @@ QtObject{ } function addItemToRuntimeWithNotification(container, insPosition, parentType, type, isForNode){ - var codeHandler = container.editor.documentHandler.codeHandler - - var ef = addItemToRuntime(codeHandler, container.editingFragment, insPosition, parentType, type) + var ef = addItemToRuntime(container.editingFragment, insPosition, parentType, type) if (!ef) return @@ -229,11 +195,21 @@ QtObject{ container.sortChildren() } - function compose(container, isForNode, objectGraph){ + function compose(container){ var codeHandler = container.editor.documentHandler.codeHandler + var isForNode = container.objectName === "objectNode" var isGroup = container.editingFragment.isGroup() + var objectGraph = null + if (isForNode){ + var par = container + while (par && par.objectName !== "objectGraph") + par = par.parent + if (par) + objectGraph = par + } + var position = 0 if (isGroup){ position = container.editingFragment.position() @@ -400,7 +376,7 @@ QtObject{ lk.layers.workspace.panes.setActiveItem(addBox, container.editor) } - function addPropertyContainer(objectContainer, ef, expandDefault, propPalette){ + function addPropertyContainer(objectContainer, ef, expandDefault){ for (var i = 0; i < objectContainer.propertiesOpened.length; ++i) if (objectContainer.propertiesOpened[i] === ef.identifier()) return @@ -414,7 +390,12 @@ QtObject{ propertyContainer.editingFragment = ef if ( codeHandler.isForAnObject(ef)){ - var childObjectContainer = addChildObjectContainer(objectContainer, ef, !instructionsShaping, propertyContainer, propPalette) + propertyContainer.isAnObject = true + var childObjectContainer = addChildObjectContainer(objectContainer, ef, !instructionsShaping, propertyContainer) + propertyContainer.childObjectContainer = childObjectContainer + childObjectContainer.isForProperty = true + propertyContainer.valueContainer = childObjectContainer + propertyContainer.paletteAddButtonVisible = false childObjectContainer.expand() } else { propertyContainer.valueContainer = createPaletteGroup() @@ -423,16 +404,8 @@ QtObject{ propertyContainer.valueContainer.editingFragment = ef propertyContainer.valueContainer.codeHandler = objectContainer.editor.documentHandler.codeHandler - if ( propPalette ){ - openPaletteByName(propPalette, - ef, - objectContainer.editor, - propertyContainer.valueContainer) - - } else if (expandDefault){ - openDefaultPalette(ef, - objectContainer.editor, - propertyContainer.valueContainer) + if (expandDefault){ + openDefaultPalette(ef, propertyContainer.valueContainer) } } ef.visualParent.owner = propertyContainer @@ -441,7 +414,9 @@ QtObject{ ef.incrementRefCount() } - function createObjectContainerForFragment(editor, ef){ + function createObjectContainerForFragment(ef){ + var editor = ef.codeHandler.documentHandler.textEdit().getEditor() + var codeHandler = editor.documentHandler.codeHandler var editorBox = lk.layers.editor.environment.createEmptyEditorBox(editor.textEdit) @@ -459,7 +434,7 @@ QtObject{ paletteBoxGroup.codeHandler = codeHandler objectContainer.paletteGroup = paletteBoxGroup - var rect = editor.editor.getCursorRectangle() + var rect = editor.getCursorRectangle() var cursorCoords = editor.cursorWindowCoords() editorBox.setChild(objectContainer, rect, cursorCoords, lk.layers.editor.environment.placement.top) @@ -474,12 +449,13 @@ QtObject{ objectContainer.contentWidth = Qt.binding(function(){ return objectContainer.containerContentWidth > objectContainer.editorContentWidth ? objectContainer.containerContentWidth : objectContainer.editorContentWidth }) - editor.editor.rootShaped = true + editor.rootShaped = true } return objectContainer } - function createEditorBoxForFragment(editor, ef, shape){ + function createEditorBoxForFragment(ef, shape){ + var editor = ef.codeHandler.documentHandler.textEdit().getEditor() var codeHandler = editor.documentHandler.codeHandler var par = editor if (shape) @@ -491,7 +467,7 @@ QtObject{ ef.visualParent = paletteBoxGroup paletteBoxGroup.codeHandler = codeHandler - var rect = editor.editor.getCursorRectangle() + var rect = editor.getCursorRectangle() var cursorCoords = editor.cursorWindowCoords() editorBox.setChild(paletteBoxGroup, rect, cursorCoords, lk.layers.editor.environment.placement.top) @@ -514,7 +490,7 @@ QtObject{ if (!ef) return - var objectContainer = createObjectContainerForFragment(editor, ef) + var objectContainer = createObjectContainerForFragment(ef) if (objectContainer.editingFragment.position() === codeHandler.findRootPosition()) objectContainer.contentWidth = Qt.binding(function(){ return objectContainer.containerContentWidth > objectContainer.editorContentWidth @@ -525,12 +501,12 @@ QtObject{ ef.incrementRefCount() editor.documentHandler.frameBox(objectContainer.parent, ef.position(), ef.length()) - shapeContainerWithInstructions(objectContainer, editor, instructions) + shapeContainerWithInstructions(objectContainer, instructions) instructionsShaping = false } - function shapeContainerWithInstructions(objectContainer, editor, instructions){ - + function shapeContainerWithInstructions(objectContainer, instructions){ + var editor = objectContainer.editor if (instructions['type'] !== objectContainer.editingFragment.type()) return var containers = openEmptyNestedObjects(objectContainer) @@ -542,7 +518,6 @@ QtObject{ var palette = palettes[i] openPaletteByName(palettes[i], objectContainer.editingFragment, - editor, objectContainer.groupsContainer.children[0], objectContainer) @@ -554,7 +529,7 @@ QtObject{ var children = instructions['children'] if (children.length === containers.length){ for (var i = 0; i < containers.length; ++i){ - shapeContainerWithInstructions(containers[i], editor, children[i]) + shapeContainerWithInstructions(containers[i], children[i]) if (!hasChildren) hasChildren = true } } @@ -575,9 +550,9 @@ QtObject{ } } - function openPropertyInContainer(objectContainer, property){ + function openPropertyInContainer(objectContainer, prop){ - var ef = addPropertyByName(objectContainer, property['name']) + var ef = addPropertyByName(objectContainer, prop['name']) if (!ef) return @@ -595,24 +570,23 @@ QtObject{ propertyContainer.editingFragment = ef } - var isAnObject = ('isAnObject' in property) && property['isAnObject'] + var isAnObject = ('isAnObject' in prop) && prop['isAnObject'] if (isAnObject){ var childObjectContainer = ef.visualParent.parent.parent.parent - if ('instructions' in property) - shapeContainerWithInstructions(childObjectContainer, childObjectContainer.editor, property['instructions']) + if ('instructions' in prop) + shapeContainerWithInstructions(childObjectContainer, prop['instructions']) } - if ('palettes' in property){ - var palettes = property['palettes'] + if ('palettes' in prop){ + var palettes = prop['palettes'] for (var i = 0; i < palettes.length; ++i) { var palette = palettes[i] openPaletteByName(palette, ef, - objectContainer.editor, ef.visualParent) } @@ -633,11 +607,12 @@ QtObject{ } var codeHandler = container.editor.documentHandler.codeHandler - return addPropertyByFragment(container.editingFragment, codeHandler, name) + return addPropertyByFragment(container.editingFragment, name) } - function addPropertyByFragment(ef, codeHandler, name){ + function addPropertyByFragment(ef, name){ + var codeHandler = ef.codeHandler var position = ef.valuePosition() + ef.valueLength() - 1 @@ -683,15 +658,14 @@ QtObject{ var properties = objectContainer.editor.documentHandler.codeHandler.openNestedProperties(objectContainer.editingFragment) for (var i=0; i < properties.length; ++i){ - objectContainer.addPropertyFragmentToContainer(properties[i], expandDefault) + addPropertyContainer(objectContainer, properties[i], expandDefault) } } function openDefaults(objectContainer){ openDefaultPalette(objectContainer.editingFragment, - objectContainer.editor, - objectContainer.paletteGroup, - objectContainer) + objectContainer.paletteGroup, + objectContainer) openNestedProperties(objectContainer, true) } @@ -782,13 +756,13 @@ QtObject{ var palette = container.editor.documentHandler.codeHandler.expand(container.editingFragment, { "palettes" : [palettes.data[index].name] }) + + var objectRoot = mode === PaletteControls.PaletteListMode.ObjectContainer + ? container.parent + : (container.objectName === "objectNode" ? container : null) var paletteBox = openPalette(palette, - container.editingFragment, - container.editor, paletteGroup, - mode === PaletteControls.PaletteListMode.ObjectContainer - ? container.parent - : (container.objectName === "objectNode" ? container : null)) + objectRoot) if (paletteBox){ if (mode === PaletteControls.PaletteListMode.ObjectContainer || mode === PaletteControls.PaletteListMode.NodeEditor){ @@ -904,7 +878,7 @@ QtObject{ editorBox.border.width = 1 editorBox.border.color = "#141c25" - var paletteBox = openPalette(palette, ef, editor, paletteGroup) + var paletteBox = openPalette(palette, paletteGroup) palette.item.x = 5 palette.item.y = 7 if (paletteBox){ @@ -1059,7 +1033,7 @@ QtObject{ var paletteBoxGroup = editorBox ? editorBox.child : null if ( paletteBoxGroup === null ){ if (forAnObject){ - objectContainer = createObjectContainerForFragment(editor, ef) + objectContainer = createObjectContainerForFragment(ef) if (objectContainer.editingFragment.position() === codeHandler.findRootPosition()) objectContainer.contentWidth = Qt.binding(function(){ return objectContainer.containerContentWidth > objectContainer.editorContentWidth @@ -1072,7 +1046,7 @@ QtObject{ paletteBoxGroup = objectContainer.paletteGroup editorBox = objectContainer.parent } else { - editorBox = createEditorBoxForFragment(editor, ef, true) + editorBox = createEditorBoxForFragment(ef, true) paletteBoxGroup = ef.visualParent } } else { @@ -1098,7 +1072,7 @@ QtObject{ objectContainer.expandOptions(palette) } - var paletteBox = openPalette(palette, ef, editor, paletteBoxGroup) + var paletteBox = openPalette(palette, paletteBoxGroup) if (paletteBox) paletteBox.moveEnabledSet = false } @@ -1137,12 +1111,12 @@ QtObject{ var paletteBoxGroup = editorBox ? editorBox.child : null if ( paletteBoxGroup === null ){ - editorBox = createEditorBoxForFragment(editor, ef, false) + editorBox = createEditorBoxForFragment(ef, false) editorBox.color = "black" paletteBoxGroup = ef.visualParent } - var paletteBox = openPalette(palette, ef, editor, paletteBoxGroup) + var paletteBox = openPalette(palette, paletteBoxGroup) editorBox.updatePlacement(rect, cursorCoords, lk.layers.editor.environment.placement.top) } diff --git a/plugins/lcvcore/palettes/ImageSegmentFactoryPalette.qml b/plugins/lcvcore/palettes/ImageSegmentFactoryPalette.qml index 57a6f967..ecee9a4d 100644 --- a/plugins/lcvcore/palettes/ImageSegmentFactoryPalette.qml +++ b/plugins/lcvcore/palettes/ImageSegmentFactoryPalette.qml @@ -57,8 +57,4 @@ CodePalette{ onInit: { paletteItem.current = value } - - onEditFragmentChanged: { - editFragment.whenBinding = function(){} - } } diff --git a/plugins/lcvcore/palettes/VideoCapturePalette.qml b/plugins/lcvcore/palettes/VideoCapturePalette.qml index 0b1c0fae..1b628a86 100644 --- a/plugins/lcvcore/palettes/VideoCapturePalette.qml +++ b/plugins/lcvcore/palettes/VideoCapturePalette.qml @@ -109,13 +109,4 @@ CodePalette{ captureContainer.videoCapture = value } - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.writeProperties({ - 'fps' : palette.value.fps, - 'currentFrame' : palette.value.currentFrame, - 'paused' : palette.value.paused - }) - } - } } diff --git a/plugins/lcvcore/palettes/VideoFilePalette.qml b/plugins/lcvcore/palettes/VideoFilePalette.qml index 00a52c9b..6e0b5673 100644 --- a/plugins/lcvcore/palettes/VideoFilePalette.qml +++ b/plugins/lcvcore/palettes/VideoFilePalette.qml @@ -105,13 +105,4 @@ CodePalette{ captureContainer.videoDecoderView = value } - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.writeProperties({ - 'fps' : palette.value.fps, - 'currentFrame' : palette.value.currentFrame, - 'paused' : palette.value.paused - }) - } - } } diff --git a/plugins/lcvcore/palettes/VideoPlayerPalette.qml b/plugins/lcvcore/palettes/VideoPlayerPalette.qml index 6756ec48..819f8872 100644 --- a/plugins/lcvcore/palettes/VideoPlayerPalette.qml +++ b/plugins/lcvcore/palettes/VideoPlayerPalette.qml @@ -104,14 +104,4 @@ CodePalette{ onValueFromBindingChanged: { captureContainer.videoDecoderView = value } - - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.writeProperties({ - 'fps' : palette.value.fps, - 'currentFrame' : palette.value.currentFrame, - 'paused' : palette.value.paused - }) - } - } } diff --git a/plugins/lcvcore/qml/EditCvExtension.qml b/plugins/lcvcore/qml/EditCvExtension.qml index b9c3eef2..853964a1 100644 --- a/plugins/lcvcore/qml/EditCvExtension.qml +++ b/plugins/lcvcore/qml/EditCvExtension.qml @@ -253,7 +253,7 @@ WorkspaceExtension{ editor.editor.rootShaped = true - var pb = lk.layers.workspace.extensions.editqml.paletteControls.openPaletteByName('NodePalette', oc.editingFragment, editor, oc.groupsContainer.children[0], oc) + var pb = lk.layers.workspace.extensions.editqml.paletteControls.openPaletteByName('NodePalette', oc.editingFragment, oc.groupsContainer.children[0], oc) pb.child.resize(oc.width - 50, editor.height - 170) }) @@ -308,7 +308,7 @@ WorkspaceExtension{ editor.editor.rootShaped = true - var pb = lk.layers.workspace.extensions.editqml.paletteControls.openPaletteByName('NodePalette', oc.editingFragment, editor, oc.groupsContainer.children[0], oc) + var pb = lk.layers.workspace.extensions.editqml.paletteControls.openPaletteByName('NodePalette', oc.editingFragment, oc.groupsContainer.children[0], oc) pb.child.resize(oc.width - 50, editor.height - 170) }) diff --git a/plugins/lcvimgproc/qml/palettes/TransformPalette.qml b/plugins/lcvimgproc/qml/palettes/TransformPalette.qml index a90d7764..4bcb7f58 100644 --- a/plugins/lcvimgproc/qml/palettes/TransformPalette.qml +++ b/plugins/lcvimgproc/qml/palettes/TransformPalette.qml @@ -79,10 +79,9 @@ CodePalette{ { p = p.parent } - var codeHandler = p.documentHandler.codeHandler var position = ef.valuePosition() + ef.valueLength() - 1 - var childEf = paletteControls.addItemToRuntime(codeHandler, ef, position, "TransformImage", name) + var childEf = paletteControls.addItemToRuntime(ef, position, "TransformImage", name) childEf.visualParent = p return childEf } @@ -141,7 +140,7 @@ CodePalette{ if (!crop) return var codeHandler = crop.visualParent.documentHandler.codeHandler - fragment = paletteControls.addPropertyByFragment(crop, codeHandler, "region") + fragment = paletteControls.addPropertyByFragment(crop, "region") } var toWrite = '"' + Math.round(x) + "," + Math.round(y) + "," + Math.round(width) + "x" + Math.round(height) + '"' fragment.write({"__ref": toWrite}) @@ -203,7 +202,7 @@ CodePalette{ if (!resize) return var codeHandler = resize.visualParent.documentHandler.codeHandler - fragment = paletteControls.addPropertyByFragment(resize, codeHandler, "size") + fragment = paletteControls.addPropertyByFragment(resize, "size") } var toWrite = '"' + Math.round(width) + "x" + Math.round(height) + '"' fragment.write({"__ref": toWrite}) @@ -251,7 +250,7 @@ CodePalette{ if (!rotate) return var codeHandler = rotate.visualParent.documentHandler.codeHandler - fragment = paletteControls.addPropertyByFragment(rotate, codeHandler, "degrees") + fragment = paletteControls.addPropertyByFragment(rotate, "degrees") } fragment.write(-angle) fragment.commit(-angle) @@ -296,7 +295,7 @@ CodePalette{ if (!perspective) return var codeHandler = perspective.visualParent.documentHandler.codeHandler - fragment = paletteControls.addPropertyByFragment(perspective, codeHandler, "points") + fragment = paletteControls.addPropertyByFragment(perspective, "points") } var value = '[' value += 'Qt.point(' + Math.round(p1.x) + ", " + Math.round(p1.y) +'), ' diff --git a/plugins/lcvphoto/palettes/BrightnessAndContrastPalette.qml b/plugins/lcvphoto/palettes/BrightnessAndContrastPalette.qml index b51af7d1..0e8e235b 100644 --- a/plugins/lcvphoto/palettes/BrightnessAndContrastPalette.qml +++ b/plugins/lcvphoto/palettes/BrightnessAndContrastPalette.qml @@ -147,12 +147,4 @@ CodePalette{ adjustmentBox.bandc = value } - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.writeProperties({ - 'brightness' : palette.value.brightness, - 'contrast' : palette.value.contrast - }) - } - } } diff --git a/plugins/lcvphoto/palettes/HueSaturationLightnessPalette.qml b/plugins/lcvphoto/palettes/HueSaturationLightnessPalette.qml index 187ef46d..c450d9c7 100644 --- a/plugins/lcvphoto/palettes/HueSaturationLightnessPalette.qml +++ b/plugins/lcvphoto/palettes/HueSaturationLightnessPalette.qml @@ -93,14 +93,4 @@ CodePalette{ onValueFromBindingChanged: { adjustmentBox.hsl = value } - - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.writeProperties({ - 'hue' : palette.value.hue, - 'saturation' : palette.value.saturation, - 'lightness': palette.value.lightness - }) - } - } } diff --git a/plugins/lcvphoto/palettes/LevelsPalette.qml b/plugins/lcvphoto/palettes/LevelsPalette.qml index c29b17df..560d5d5a 100644 --- a/plugins/lcvphoto/palettes/LevelsPalette.qml +++ b/plugins/lcvphoto/palettes/LevelsPalette.qml @@ -73,15 +73,6 @@ CodePalette{ } } - onEditFragmentChanged: { - editFragment.whenBinding = function(){ - editFragment.writeProperties({ - 'lightness' : palette.value.lightness, - 'channels' : palette.value.channels - }) - } - } - onValueFromBindingChanged: { levelsSliders.levels = value } diff --git a/plugins/timeline/palettes/TimelinePalette.qml b/plugins/timeline/palettes/TimelinePalette.qml index 4b43b7de..1cddb0ab 100644 --- a/plugins/timeline/palettes/TimelinePalette.qml +++ b/plugins/timeline/palettes/TimelinePalette.qml @@ -221,7 +221,4 @@ CodePalette{ timelineArea.timeline = value } - onEditFragmentChanged: { - editFragment.whenBinding = function(){} - } } diff --git a/plugins/workspace/nodeeditor/qml/ObjectGraph.qml b/plugins/workspace/nodeeditor/qml/ObjectGraph.qml index 662c84ac..691e1199 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectGraph.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectGraph.qml @@ -150,6 +150,12 @@ Rectangle{ property var editor: null property var editingFragment: null + onEditingFragmentChanged: { + if (!editingFragment) return + documentHandler = editingFragment.codeHandler.documentHandler + editor = editingFragment.codeHandler.documentHandler.textEdit().getEditor() + } + property alias zoom: graphView.zoom property alias zoomOrigin: graphView.zoomOrigin @@ -260,16 +266,17 @@ Rectangle{ onDoubleClicked: { var addBoxItem = paletteControls.createAddQmlBox(null) if (!addBoxItem) return - var position = editingFragment.valuePosition() + editingFragment.valueLength() - 1 - var addOptions = documentHandler.codeHandler.getAddOptions(position) + + var position = root.editingFragment.valuePosition() + root.editingFragment.valueLength() - 1 + var addOptions = root.editingFragment.codeHandler.getAddOptions(position) addBoxItem.addContainer = addOptions - addBoxItem.codeQmlHandler = documentHandler.codeHandler + addBoxItem.codeQmlHandler = root.editingFragment.codeHandler addBoxItem.mode = AddQmlBox.DisplayMode.ObjectsOnly var rect = Qt.rect(pos.x, pos.y, 1, 1) - var coords = editor.mapGlobalPosition() + var coords = root.editor.parent.mapGlobalPosition() var cursorCoords = Qt.point(coords.x, coords.y) var addBox = lk.layers.editor.environment.createEditorBox( addBoxItem, rect, cursorCoords, lk.layers.editor.environment.placement.bottom @@ -277,11 +284,11 @@ Rectangle{ addBox.color = 'transparent' addBoxItem.accept = function(type, data){ - var opos = documentHandler.codeHandler.addItem( + var opos = root.documentHandler.codeHandler.addItem( addBoxItem.addContainer.model.addPosition, addBoxItem.addContainer.objectType, data ) - documentHandler.codeHandler.addItemToRuntime(editingFragment, data, project.appRoot()) - var ef = documentHandler.codeHandler.openNestedConnection( + root.documentHandler.codeHandler.addItemToRuntime(editingFragment, data, project.appRoot()) + var ef = root.documentHandler.codeHandler.openNestedConnection( editingFragment, opos ) cursorCoords = Qt.point((pos.x - graphView.containerItem.x ) / zoom, (pos.y - graphView.containerItem.y) / zoom) diff --git a/plugins/workspace/nodeeditor/qml/ObjectGraphControls.qml b/plugins/workspace/nodeeditor/qml/ObjectGraphControls.qml index 7aa613bf..e34821e8 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectGraphControls.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectGraphControls.qml @@ -53,7 +53,7 @@ QtObject{ editor.editor.rootShaped = true - var pb = lk.layers.workspace.extensions.editqml.paletteControls.openPaletteByName('NodePalette', oc.editingFragment, editor, oc.groupsContainer.children[0], oc) + var pb = lk.layers.workspace.extensions.editqml.paletteControls.openPaletteByName('NodePalette', oc.editingFragment, oc.groupsContainer.children[0], oc) pb.child.resize(oc.width - 50, editor.height - 170) }) diff --git a/plugins/workspace/nodeeditor/qml/ObjectNode.qml b/plugins/workspace/nodeeditor/qml/ObjectNode.qml index 39129961..2b962757 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectNode.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectNode.qml @@ -58,7 +58,7 @@ Qan.NodeItem{ resizable: false function expandDefaultPalette(){ - paletteControls.openDefaultPalette(editingFragment, editor, paletteContainer, root) + paletteControls.openDefaultPalette(editingFragment, paletteContainer, root) } function expandOptions(options){ @@ -69,7 +69,7 @@ Qan.NodeItem{ for ( var i = 0; i < palettes.length; ++i){ if (paletteContainer.palettesOpened.indexOf(palettes[i]) !== -1) continue - paletteControls.openPaletteByName(palettes[i], root.editingFragment, editor, paletteContainer) + paletteControls.openPaletteByName(palettes[i], root.editingFragment, paletteContainer) } } @@ -110,7 +110,7 @@ Qan.NodeItem{ if (propertyContainer.children[j].propertyName !== propName) continue if (propertyContainer.children[j].paletteContainer.palettesOpened.indexOf(propPalette) !== -1) break - paletteControls.openPaletteByName(propPalette, ef, editor, propertyContainer.children[j].paletteContainer) + paletteControls.openPaletteByName(propPalette, ef, propertyContainer.children[j].paletteContainer) break } } else { @@ -242,7 +242,7 @@ Qan.NodeItem{ MouseArea{ anchors.fill: parent onClicked: { - paletteControls.compose(root, true, objectGraph) + paletteControls.compose(root) } } } From 9b41ec0bc0ec2114bfa7b93262a1701ca655ee51 Mon Sep 17 00:00:00 2001 From: nenad-popovic-91 <42581059+nenad-popovic-91@users.noreply.github.com> Date: Sat, 26 Jun 2021 14:06:57 +0200 Subject: [PATCH 77/91] Palette objects moved from editor to workspace (#224) * Palette objects moved from editor to workspace --- application/qml/DocumentationViewPane.qml | 1 + application/qml/LiveKeysTheme.qml | 1 + application/qml/LogContainer.qml | 4 ++-- application/qml/ProjectEnvironment.qml | 1 + application/qml/RunView.qml | 1 + application/qml/Viewer.qml | 4 ++-- .../baseqml/palettes/ActTriggerTypePalette.qml | 1 + plugins/base/baseqml/palettes/ExecPalette.qml | 1 + plugins/editor/editor.pro | 6 ------ plugins/editor/palettes/BooleanPalette.qml | 3 +++ plugins/editor/palettes/ColorPalette.qml | 3 +++ plugins/editor/palettes/ConnectionPalette.qml | 4 ++++ .../editor/palettes/DoubleHistoryPlotPalette.qml | 3 +++ plugins/editor/palettes/DoublePalette.qml | 3 +++ plugins/editor/palettes/FilePathPalette.qml | 3 +++ plugins/editor/palettes/FolderPathPalette.qml | 3 +++ plugins/editor/palettes/ImportsPalette.qml | 6 ++++++ plugins/editor/palettes/IntHistoryPlotPalette.qml | 4 ++++ plugins/editor/palettes/IntInputPalette.qml | 3 +++ plugins/editor/palettes/IntPalette.qml | 3 +++ plugins/editor/palettes/NodePalette.qml | 7 ++----- plugins/editor/palettes/SizePalette.qml | 3 +++ plugins/editor/palettes/StringListPalette.qml | 6 ++++++ plugins/editor/palettes/TextPalette.qml | 3 +++ plugins/editor/palettes/TriggerPalette.qml | 3 +++ plugins/editor/qml/EditorPane.qml | 6 +++--- plugins/editor/qml/ObjectPalettePane.qml | 4 ++-- plugins/editor/qml/PalettePane.qml | 4 ++-- plugins/editor/qml/loaddocs.qml | 1 + plugins/editor/qml/qmldir | 9 --------- plugins/editqml/qml/EditQmlExtension.qml | 1 + plugins/editqml/qml/PaletteContainer.qml | 14 ++++---------- .../palettes/ImageSegmentFactoryPalette.qml | 1 + plugins/lcvcore/palettes/VideoCapturePalette.qml | 7 +++++++ plugins/lcvcore/palettes/VideoFilePalette.qml | 7 +++++++ plugins/lcvcore/palettes/VideoPlayerPalette.qml | 7 +++++++ plugins/lcvcore/qml/MatViewPane.qml | 1 + .../palettes/BrightnessAndContrastPalette.qml | 6 ++++++ .../palettes/HueSaturationLightnessPalette.qml | 7 +++++++ plugins/lcvphoto/palettes/LevelsPalette.qml | 6 ++++++ .../firstapplication/resources/AddDefaultVideo.qml | 1 + .../resources/FirstApplicationRemoveHighlight.qml | 1 + .../firstapplication/resources/ShapeSwitch.qml | 1 + .../workspace/resources/ClickedMessage.qml | 1 + .../workspace/resources/EditorPaneRemove.qml | 1 + .../workspace/resources/MenuRemoveHighlight.qml | 1 + plugins/timeline/palettes/TimelinePalette.qml | 1 + plugins/workspace/nodeeditor/qml/ObjectGraph.qml | 11 +++-------- plugins/workspace/nodeeditor/qml/ObjectNode.qml | 9 ++++----- .../nodeeditor/qml/ObjectNodeProperty.qml | 3 +-- .../qml/DocumentationView.qml | 0 .../{editor => workspace}/qml/LoadingAnimation.qml | 0 plugins/{editor => workspace}/qml/Pane.qml | 0 plugins/{editor => workspace}/qml/PaneDragItem.qml | 0 plugins/{editor => workspace}/qml/PaneDropArea.qml | 0 .../{editor => workspace}/qml/PaneSplitView.qml | 0 plugins/{editor => workspace}/qml/PaneWindow.qml | 1 + .../{editor => workspace}/qml/WorkspaceControl.qml | 0 .../{editor => workspace}/qml/WorkspaceTheme.qml | 0 plugins/workspace/qml/qmldir | 10 +++++++++- plugins/workspace/quickqanava/qml/Port.qml | 2 +- 61 files changed, 146 insertions(+), 58 deletions(-) rename plugins/{editor => workspace}/qml/DocumentationView.qml (100%) rename plugins/{editor => workspace}/qml/LoadingAnimation.qml (100%) rename plugins/{editor => workspace}/qml/Pane.qml (100%) rename plugins/{editor => workspace}/qml/PaneDragItem.qml (100%) rename plugins/{editor => workspace}/qml/PaneDropArea.qml (100%) rename plugins/{editor => workspace}/qml/PaneSplitView.qml (100%) rename plugins/{editor => workspace}/qml/PaneWindow.qml (98%) rename plugins/{editor => workspace}/qml/WorkspaceControl.qml (100%) rename plugins/{editor => workspace}/qml/WorkspaceTheme.qml (100%) diff --git a/application/qml/DocumentationViewPane.qml b/application/qml/DocumentationViewPane.qml index bd68c390..5423bd5b 100644 --- a/application/qml/DocumentationViewPane.qml +++ b/application/qml/DocumentationViewPane.qml @@ -3,6 +3,7 @@ import editor 1.0 import base 1.0 import live 1.0 import fs 1.0 as Fs +import workspace 1.0 Pane{ id: root diff --git a/application/qml/LiveKeysTheme.qml b/application/qml/LiveKeysTheme.qml index 92e9e41d..56d15946 100644 --- a/application/qml/LiveKeysTheme.qml +++ b/application/qml/LiveKeysTheme.qml @@ -1,5 +1,6 @@ import QtQuick 2.3 import editor 1.0 +import workspace 1.0 WorkspaceTheme{ name: "LiveKeys" diff --git a/application/qml/LogContainer.qml b/application/qml/LogContainer.qml index d1f294ed..2bd2ead8 100644 --- a/application/qml/LogContainer.qml +++ b/application/qml/LogContainer.qml @@ -7,7 +7,7 @@ import live 1.0 import editor 1.0 import workspace 1.0 as Workspace -Pane{ +Workspace.Pane{ id: root paneType: 'log' paneState : { return {} } @@ -192,7 +192,7 @@ Pane{ height: 30 color : root.topColor - PaneDragItem{ + Workspace.PaneDragItem{ anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.leftMargin: 5 diff --git a/application/qml/ProjectEnvironment.qml b/application/qml/ProjectEnvironment.qml index 583870f1..9887df37 100644 --- a/application/qml/ProjectEnvironment.qml +++ b/application/qml/ProjectEnvironment.qml @@ -23,6 +23,7 @@ import editor 1.0 import editor.private 1.0 import fs 1.0 as Fs import visual.input 1.0 as Input +import workspace 1.0 Item{ id: root diff --git a/application/qml/RunView.qml b/application/qml/RunView.qml index ae26f705..30be264e 100644 --- a/application/qml/RunView.qml +++ b/application/qml/RunView.qml @@ -4,6 +4,7 @@ import editor.private 1.0 import base 1.0 import live 1.0 import visual.shapes 1.0 +import workspace 1.0 Pane{ id: root diff --git a/application/qml/Viewer.qml b/application/qml/Viewer.qml index 6ff2354e..4cd65a95 100644 --- a/application/qml/Viewer.qml +++ b/application/qml/Viewer.qml @@ -5,7 +5,7 @@ import editor.private 1.0 import workspace 1.0 as Workspace import visual.shapes 1.0 -Pane{ +Workspace.Pane{ id : viewer objectName: "viewer" paneType: "viewer" @@ -37,7 +37,7 @@ Pane{ height: 30 color: currentTheme ? currentTheme.paneTopBackground : 'black' - PaneDragItem{ + Workspace.PaneDragItem{ anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.leftMargin: 5 diff --git a/plugins/base/baseqml/palettes/ActTriggerTypePalette.qml b/plugins/base/baseqml/palettes/ActTriggerTypePalette.qml index 98631477..9b4fa969 100644 --- a/plugins/base/baseqml/palettes/ActTriggerTypePalette.qml +++ b/plugins/base/baseqml/palettes/ActTriggerTypePalette.qml @@ -86,5 +86,6 @@ CodePalette{ } else { dropdown.currentIndex = 0 } + editFragment.whenBinding = function(){} } } diff --git a/plugins/base/baseqml/palettes/ExecPalette.qml b/plugins/base/baseqml/palettes/ExecPalette.qml index 8f595e9b..1e049839 100644 --- a/plugins/base/baseqml/palettes/ExecPalette.qml +++ b/plugins/base/baseqml/palettes/ExecPalette.qml @@ -97,6 +97,7 @@ CodePalette{ } onInit: { execBox.current = value + editFragment.whenBinding = function(){} } } diff --git a/plugins/editor/editor.pro b/plugins/editor/editor.pro index 7ab35862..c47f8329 100644 --- a/plugins/editor/editor.pro +++ b/plugins/editor/editor.pro @@ -68,20 +68,14 @@ DISTFILES += \ palettes/StringListPalette.qml \ palettes/TextPalette.qml \ palettes/TriggerPalette.qml \ - qml/DocumentationView.qml \ qml/EditorPane.qml \ qml/ObjectPalettePane.qml \ qml/PaletteConnection.qml \ qml/PalettePane.qml \ - qml/WorkspaceControl.qml \ qml/live.package.json \ qml/live.plugin.json \ qml/PaletteListView.qml \ palettes/EditPalette.qml \ - qml/Pane.qml \ - qml/PaneWindow.qml \ - qml/WorkspaceTheme.qml \ qml/PaneMenuButton.qml \ - qml/LoadingAnimation.qml \ qml/loaddocs.qml \ qml/loadqtdocs.qml diff --git a/plugins/editor/palettes/BooleanPalette.qml b/plugins/editor/palettes/BooleanPalette.qml index 194b4595..82c29a63 100644 --- a/plugins/editor/palettes/BooleanPalette.qml +++ b/plugins/editor/palettes/BooleanPalette.qml @@ -45,6 +45,9 @@ CodePalette { onInit: { checked = value + editFragment.whenBinding = function(){ + editFragment.write(palette.value) + } } onValueFromBindingChanged: { checked = value diff --git a/plugins/editor/palettes/ColorPalette.qml b/plugins/editor/palettes/ColorPalette.qml index 6c4b3b5a..35981e3a 100644 --- a/plugins/editor/palettes/ColorPalette.qml +++ b/plugins/editor/palettes/ColorPalette.qml @@ -115,6 +115,9 @@ CodePalette{ onInit: { palette.selectedColor = value colorPicker.color = value + editFragment.whenBinding = function(){ + editFragment.write(palette.value) + } } onValueFromBindingChanged: { palette.selectedColor = value diff --git a/plugins/editor/palettes/ConnectionPalette.qml b/plugins/editor/palettes/ConnectionPalette.qml index d0f6ca2d..8e8927e7 100644 --- a/plugins/editor/palettes/ConnectionPalette.qml +++ b/plugins/editor/palettes/ConnectionPalette.qml @@ -203,6 +203,10 @@ CodePalette{ } input.forceActiveFocus() + + editFragment.whenBinding = function(){ + editFragment.write(palette.value) + } } onSourceInit: { diff --git a/plugins/editor/palettes/DoubleHistoryPlotPalette.qml b/plugins/editor/palettes/DoubleHistoryPlotPalette.qml index 2bb5e5d8..5c651bb3 100644 --- a/plugins/editor/palettes/DoubleHistoryPlotPalette.qml +++ b/plugins/editor/palettes/DoubleHistoryPlotPalette.qml @@ -31,6 +31,9 @@ CodePalette{ onInit: { valueHistory.currentValue = value + editFragment.whenBinding = function(){ + editFragment.write(palette.value) + } } onValueFromBindingChanged: { valueHistory.currentValue = value diff --git a/plugins/editor/palettes/DoublePalette.qml b/plugins/editor/palettes/DoublePalette.qml index 487f492b..5c3304e9 100644 --- a/plugins/editor/palettes/DoublePalette.qml +++ b/plugins/editor/palettes/DoublePalette.qml @@ -305,6 +305,9 @@ CodePalette{ return } updateSliders(value) + editFragment.whenBinding = function(){ + editFragment.write(palette.value) + } } onValueFromBindingChanged: { if (isNaN(value)){ diff --git a/plugins/editor/palettes/FilePathPalette.qml b/plugins/editor/palettes/FilePathPalette.qml index 89abe65a..916664a2 100644 --- a/plugins/editor/palettes/FilePathPalette.qml +++ b/plugins/editor/palettes/FilePathPalette.qml @@ -38,6 +38,9 @@ CodePalette{ } onInit: { inputBox.path = value + editFragment.whenBinding = function(){ + editFragment.write(palette.value) + } } } diff --git a/plugins/editor/palettes/FolderPathPalette.qml b/plugins/editor/palettes/FolderPathPalette.qml index c942442f..9e64ac85 100644 --- a/plugins/editor/palettes/FolderPathPalette.qml +++ b/plugins/editor/palettes/FolderPathPalette.qml @@ -39,5 +39,8 @@ CodePalette{ } onInit: { inputBox.path = value + editFragment.whenBinding = function(){ + editFragment.write(palette.value) + } } } diff --git a/plugins/editor/palettes/ImportsPalette.qml b/plugins/editor/palettes/ImportsPalette.qml index 0d2001cc..2d2db364 100644 --- a/plugins/editor/palettes/ImportsPalette.qml +++ b/plugins/editor/palettes/ImportsPalette.qml @@ -228,4 +228,10 @@ CodePalette{ } } + + onInit: { + editFragment.whenBinding = function(){ + editFragment.write(palette.value) + } + } } diff --git a/plugins/editor/palettes/IntHistoryPlotPalette.qml b/plugins/editor/palettes/IntHistoryPlotPalette.qml index 89b30b4f..1960db05 100644 --- a/plugins/editor/palettes/IntHistoryPlotPalette.qml +++ b/plugins/editor/palettes/IntHistoryPlotPalette.qml @@ -19,6 +19,10 @@ CodePalette{ onInit: { valueHistory.currentValue = value + editFragment.whenBinding = function(){ + editFragment.write(palette.value) + } + } onValueFromBindingChanged: { diff --git a/plugins/editor/palettes/IntInputPalette.qml b/plugins/editor/palettes/IntInputPalette.qml index 2f1fb2fd..8cc27838 100644 --- a/plugins/editor/palettes/IntInputPalette.qml +++ b/plugins/editor/palettes/IntInputPalette.qml @@ -55,6 +55,9 @@ CodePalette{ onInit: { root.path = value + editFragment.whenBinding = function(){ + editFragment.write(palette.value) + } } onValueFromBindingChanged: { root.path = value diff --git a/plugins/editor/palettes/IntPalette.qml b/plugins/editor/palettes/IntPalette.qml index 27aed672..7d0606ff 100644 --- a/plugins/editor/palettes/IntPalette.qml +++ b/plugins/editor/palettes/IntPalette.qml @@ -197,6 +197,9 @@ CodePalette{ } } intSlider.value = floorValue + editFragment.whenBinding = function(){ + editFragment.write(palette.value) + } } onValueFromBindingChanged: { diff --git a/plugins/editor/palettes/NodePalette.qml b/plugins/editor/palettes/NodePalette.qml index cff15522..865be451 100644 --- a/plugins/editor/palettes/NodePalette.qml +++ b/plugins/editor/palettes/NodePalette.qml @@ -11,7 +11,6 @@ CodePalette{ id: palette type: "qml/Object" - property var documentHandler: null property var editor: null property var objectsWithId: ({}) property var numOfObjects: 0 @@ -146,10 +145,10 @@ CodePalette{ for (var j=0; j < numofProps; ++j){ var child = allObjects[i].item.propertyContainer.children[j] if (child.editingFragment) - palette.documentHandler.codeHandler.removeConnection(child.editingFragment) + editFragment.codeHandler.removeConnection(child.editingFragment) child.destroy() } - palette.documentHandler.codeHandler.removeConnection(allObjects[i].item.editingFragment) + editFragment.codeHandler.removeConnection(allObjects[i].item.editingFragment) } allObjects = [] @@ -161,7 +160,6 @@ CodePalette{ width: 600 height: 300 palette: palette - documentHandler: palette.documentHandler editor: palette.editor editingFragment: palette.editFragment style: theme.nodeEditor @@ -172,7 +170,6 @@ CodePalette{ onInit: { if (!editFragment) return editor = editFragment.codeHandler.documentHandler.textEdit().getEditor() - documentHandler = editFragment.codeHandler.documentHandler editFragment.codeHandler.populateNestedObjectsForFragment(editFragment) objectGraph.editingFragment = editFragment nodeItem.init() diff --git a/plugins/editor/palettes/SizePalette.qml b/plugins/editor/palettes/SizePalette.qml index 056eef40..455c01f6 100644 --- a/plugins/editor/palettes/SizePalette.qml +++ b/plugins/editor/palettes/SizePalette.qml @@ -82,6 +82,9 @@ CodePalette { onInit: { widthInput.text = value.width heightInput.text = value.height + editFragment.whenBinding = function(){ + editFragment.write(palette.value) + } } onValueFromBindingChanged: { widthInput.text = value.width diff --git a/plugins/editor/palettes/StringListPalette.qml b/plugins/editor/palettes/StringListPalette.qml index 31f5c6a6..be397aa9 100644 --- a/plugins/editor/palettes/StringListPalette.qml +++ b/plugins/editor/palettes/StringListPalette.qml @@ -184,4 +184,10 @@ CodePalette{ for (var i = 0; i < value.length; ++i) argsContainer.model.append({'value': value[i]}) } + + onInit: { + editFragment.whenBinding = function(){ + editFragment.write(itemList.modelToArray()) + } + } } diff --git a/plugins/editor/palettes/TextPalette.qml b/plugins/editor/palettes/TextPalette.qml index 5e223809..e108b55a 100644 --- a/plugins/editor/palettes/TextPalette.qml +++ b/plugins/editor/palettes/TextPalette.qml @@ -58,6 +58,9 @@ CodePalette{ } onInit: { root.path = value + editFragment.whenBinding = function(){ + editFragment.write(palette.value) + } } } diff --git a/plugins/editor/palettes/TriggerPalette.qml b/plugins/editor/palettes/TriggerPalette.qml index 83dcad82..cd1144c1 100644 --- a/plugins/editor/palettes/TriggerPalette.qml +++ b/plugins/editor/palettes/TriggerPalette.qml @@ -225,6 +225,9 @@ CodePalette{ } input.forceActiveFocus() + editFragment.whenBinding = function(){ + editFragment.write(palette.value) + } } Component.onDestruction: { diff --git a/plugins/editor/qml/EditorPane.qml b/plugins/editor/qml/EditorPane.qml index 4d3f650f..8bec5fa2 100644 --- a/plugins/editor/qml/EditorPane.qml +++ b/plugins/editor/qml/EditorPane.qml @@ -24,7 +24,7 @@ import base 1.0 import fs 1.0 as Fs import visual.input 1.0 as Input -Pane{ +Workspace.Pane{ id : root property alias internalActiveFocus : editor.internalActiveFocus @@ -143,7 +143,7 @@ Pane{ return editor.cursorWindowCoords(root) } - LoadingAnimation{ + Workspace.LoadingAnimation{ id: loadingAnimation visible: false x: parent.width/2 - width/2 @@ -208,7 +208,7 @@ Pane{ color : root.topColor - PaneDragItem{ + Workspace.PaneDragItem{ anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.leftMargin: 5 diff --git a/plugins/editor/qml/ObjectPalettePane.qml b/plugins/editor/qml/ObjectPalettePane.qml index 8ca753f7..8d2526f0 100644 --- a/plugins/editor/qml/ObjectPalettePane.qml +++ b/plugins/editor/qml/ObjectPalettePane.qml @@ -7,7 +7,7 @@ import live 1.0 import fs 1.0 as Fs import workspace 1.0 as Workspace -Pane{ +Workspace.Pane{ id: root objectName : 'objectPalette' paneType: 'objectPalette' @@ -36,7 +36,7 @@ Pane{ height: 30 color: root.topColor - PaneDragItem{ + Workspace.PaneDragItem{ anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.leftMargin: 5 diff --git a/plugins/editor/qml/PalettePane.qml b/plugins/editor/qml/PalettePane.qml index fa39f914..efbe740b 100644 --- a/plugins/editor/qml/PalettePane.qml +++ b/plugins/editor/qml/PalettePane.qml @@ -7,7 +7,7 @@ import live 1.0 import fs 1.0 as Fs import workspace 1.0 as Workspace -Pane{ +Workspace.Pane{ id: root objectName : 'palette' paneType: 'palette' @@ -36,7 +36,7 @@ Pane{ height: 30 color: root.topColor - PaneDragItem{ + Workspace.PaneDragItem{ anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.leftMargin: 5 diff --git a/plugins/editor/qml/loaddocs.qml b/plugins/editor/qml/loaddocs.qml index 6fdfe165..5684bccb 100644 --- a/plugins/editor/qml/loaddocs.qml +++ b/plugins/editor/qml/loaddocs.qml @@ -2,6 +2,7 @@ import QtQuick 2.3 import QtWebEngine 1.7 import editor 1.0 import fs 1.0 as Fs +import workspace 1.0 DocumentationLoader{ id: root diff --git a/plugins/editor/qml/qmldir b/plugins/editor/qml/qmldir index 8bb1715a..81882e9d 100644 --- a/plugins/editor/qml/qmldir +++ b/plugins/editor/qml/qmldir @@ -6,16 +6,7 @@ depends QtQuick 2.3 Editor 1.0 Editor.qml EditorPane 1.0 EditorPane.qml SuggestionBox 1.0 SuggestionBox.qml -LoadingAnimation 1.0 LoadingAnimation.qml PaletteListView 1.0 PaletteListView.qml PaletteConnection 1.0 PaletteConnection.qml -Pane 1.0 Pane.qml -PaneSplitView 1.0 PaneSplitView.qml -PaneDragItem 1.0 PaneDragItem.qml -PaneDropArea 1.0 PaneDropArea.qml -PaneWindow 1.0 PaneWindow.qml -WorkspaceTheme 1.0 WorkspaceTheme.qml -WorkspaceControl 1.0 WorkspaceControl.qml -DocumentationView 1.0 DocumentationView.qml ObjectPalettePane 1.0 ObjectPalettePane.qml PalettePane 1.0 PalettePane.qml diff --git a/plugins/editqml/qml/EditQmlExtension.qml b/plugins/editqml/qml/EditQmlExtension.qml index b53fe4c2..f66c29f0 100644 --- a/plugins/editqml/qml/EditQmlExtension.qml +++ b/plugins/editqml/qml/EditQmlExtension.qml @@ -1,6 +1,7 @@ import QtQuick 2.3 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceExtension{ id: root diff --git a/plugins/editqml/qml/PaletteContainer.qml b/plugins/editqml/qml/PaletteContainer.qml index 9697daef..494a1b21 100644 --- a/plugins/editqml/qml/PaletteContainer.qml +++ b/plugins/editqml/qml/PaletteContainer.qml @@ -36,8 +36,6 @@ Rectangle{ property string name : palette ? palette.name : '' property string type : palette ? palette.type : '' property string title : type + ' - ' + name - property var cursorRectangle : null - property var editorPosition : null property var editor: null property Item pane: null property Item dragPane: null @@ -45,8 +43,6 @@ Rectangle{ onEditingFragmentChanged: { if (!editingFragment) return editor = editingFragment.codeHandler.documentHandler.textEdit().getEditor() - cursorRectangle = editor.getCursorRectangle() - editorPosition = editor.cursorWindowCoords() } property bool paletteSwapVisible: false @@ -58,8 +54,6 @@ Rectangle{ property double titleLeftMargin : 50 property double titleRightMargin : 50 - property DocumentHandler documentHandler : editor ? editor.documentHandler: null - property var paletteControls: lk.layers.workspace.extensions.editqml.paletteControls function swapOrAddPalette(swap){ @@ -93,7 +87,7 @@ Rectangle{ paletteConnection.editingFragment = null } else { paletteConnection.forceActiveFocus() - paletteConnection.model = editor.documentHandler.codeHandler.bindingChannels + paletteConnection.model = editingFragment.codeHandler.bindingChannels paletteConnection.editingFragment = editingFragment } } @@ -121,8 +115,8 @@ Rectangle{ var palettePane = lk.layers.workspace.panes.createPane('palette', {}, [400, 400]) lk.layers.workspace.panes.splitPaneHorizontallyWith( - paletteContainer.editor.parentSplitView, - paletteContainer.editor.parentSplitViewIndex(), + paletteContainer.editor.parent.parentSplitView, + paletteContainer.editor.parent.parentSplitViewIndex(), palettePane ) @@ -142,7 +136,7 @@ Rectangle{ p = p.parent } p.palettesOpened = p.palettesOpened.filter(function(name){ return name !== paletteContainer.palette.name }) - documentHandler.codeHandler.removePalette(paletteContainer.palette) + editingFragment.codeHandler.removePalette(paletteContainer.palette) } Component.onCompleted: { diff --git a/plugins/lcvcore/palettes/ImageSegmentFactoryPalette.qml b/plugins/lcvcore/palettes/ImageSegmentFactoryPalette.qml index ecee9a4d..46c729a7 100644 --- a/plugins/lcvcore/palettes/ImageSegmentFactoryPalette.qml +++ b/plugins/lcvcore/palettes/ImageSegmentFactoryPalette.qml @@ -56,5 +56,6 @@ CodePalette{ } onInit: { paletteItem.current = value + editFragment.whenBinding = function(){} } } diff --git a/plugins/lcvcore/palettes/VideoCapturePalette.qml b/plugins/lcvcore/palettes/VideoCapturePalette.qml index 1b628a86..c970b6bb 100644 --- a/plugins/lcvcore/palettes/VideoCapturePalette.qml +++ b/plugins/lcvcore/palettes/VideoCapturePalette.qml @@ -104,6 +104,13 @@ CodePalette{ onInit: { captureContainer.videoCapture = value + editFragment.whenBinding = function(){ + editFragment.writeProperties({ + 'fps' : palette.value.fps, + 'currentFrame' : palette.value.currentFrame, + 'paused' : palette.value.paused + }) + } } onValueFromBindingChanged: { captureContainer.videoCapture = value diff --git a/plugins/lcvcore/palettes/VideoFilePalette.qml b/plugins/lcvcore/palettes/VideoFilePalette.qml index 6e0b5673..86c40b12 100644 --- a/plugins/lcvcore/palettes/VideoFilePalette.qml +++ b/plugins/lcvcore/palettes/VideoFilePalette.qml @@ -100,6 +100,13 @@ CodePalette{ onInit: { captureContainer.videoDecoderView = value + editFragment.whenBinding = function(){ + editFragment.writeProperties({ + 'fps' : palette.value.fps, + 'currentFrame' : palette.value.currentFrame, + 'paused' : palette.value.paused + }) + } } onValueFromBindingChanged: { captureContainer.videoDecoderView = value diff --git a/plugins/lcvcore/palettes/VideoPlayerPalette.qml b/plugins/lcvcore/palettes/VideoPlayerPalette.qml index 819f8872..0c702bfe 100644 --- a/plugins/lcvcore/palettes/VideoPlayerPalette.qml +++ b/plugins/lcvcore/palettes/VideoPlayerPalette.qml @@ -100,6 +100,13 @@ CodePalette{ onInit: { captureContainer.videoDecoderView = value + editFragment.whenBinding = function(){ + editFragment.writeProperties({ + 'fps' : palette.value.fps, + 'currentFrame' : palette.value.currentFrame, + 'paused' : palette.value.paused + }) + } } onValueFromBindingChanged: { captureContainer.videoDecoderView = value diff --git a/plugins/lcvcore/qml/MatViewPane.qml b/plugins/lcvcore/qml/MatViewPane.qml index 7fb51a2a..ea6abbd1 100644 --- a/plugins/lcvcore/qml/MatViewPane.qml +++ b/plugins/lcvcore/qml/MatViewPane.qml @@ -6,6 +6,7 @@ import base 1.0 import live 1.0 import fs 1.0 as Fs import lcvcore 1.0 as Cv +import workspace 1.0 Pane{ id: root diff --git a/plugins/lcvphoto/palettes/BrightnessAndContrastPalette.qml b/plugins/lcvphoto/palettes/BrightnessAndContrastPalette.qml index 0e8e235b..46c534aa 100644 --- a/plugins/lcvphoto/palettes/BrightnessAndContrastPalette.qml +++ b/plugins/lcvphoto/palettes/BrightnessAndContrastPalette.qml @@ -142,6 +142,12 @@ CodePalette{ onInit: { adjustmentBox.bandc = value + editFragment.whenBinding = function(){ + editFragment.writeProperties({ + 'brightness' : palette.value.brightness, + 'contrast' : palette.value.contrast + }) + } } onValueFromBindingChanged: { adjustmentBox.bandc = value diff --git a/plugins/lcvphoto/palettes/HueSaturationLightnessPalette.qml b/plugins/lcvphoto/palettes/HueSaturationLightnessPalette.qml index c450d9c7..022c1c24 100644 --- a/plugins/lcvphoto/palettes/HueSaturationLightnessPalette.qml +++ b/plugins/lcvphoto/palettes/HueSaturationLightnessPalette.qml @@ -89,6 +89,13 @@ CodePalette{ onInit: { adjustmentBox.hsl = value + editFragment.whenBinding = function(){ + editFragment.writeProperties({ + 'hue' : palette.value.hue, + 'saturation' : palette.value.saturation, + 'lightness': palette.value.lightness + }) + } } onValueFromBindingChanged: { adjustmentBox.hsl = value diff --git a/plugins/lcvphoto/palettes/LevelsPalette.qml b/plugins/lcvphoto/palettes/LevelsPalette.qml index 560d5d5a..dfb96391 100644 --- a/plugins/lcvphoto/palettes/LevelsPalette.qml +++ b/plugins/lcvphoto/palettes/LevelsPalette.qml @@ -78,5 +78,11 @@ CodePalette{ } onInit: { levelsSliders.levels = value + editFragment.whenBinding = function(){ + editFragment.writeProperties({ + 'lightness' : palette.value.lightness, + 'channels' : palette.value.channels + }) + } } } diff --git a/plugins/squareone/tutorials/firstapplication/resources/AddDefaultVideo.qml b/plugins/squareone/tutorials/firstapplication/resources/AddDefaultVideo.qml index deb73453..b4be0bc4 100644 --- a/plugins/squareone/tutorials/firstapplication/resources/AddDefaultVideo.qml +++ b/plugins/squareone/tutorials/firstapplication/resources/AddDefaultVideo.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ diff --git a/plugins/squareone/tutorials/firstapplication/resources/FirstApplicationRemoveHighlight.qml b/plugins/squareone/tutorials/firstapplication/resources/FirstApplicationRemoveHighlight.qml index 00ebe26a..5925fe5f 100644 --- a/plugins/squareone/tutorials/firstapplication/resources/FirstApplicationRemoveHighlight.qml +++ b/plugins/squareone/tutorials/firstapplication/resources/FirstApplicationRemoveHighlight.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ diff --git a/plugins/squareone/tutorials/firstapplication/resources/ShapeSwitch.qml b/plugins/squareone/tutorials/firstapplication/resources/ShapeSwitch.qml index 1d00e125..a39613e8 100644 --- a/plugins/squareone/tutorials/firstapplication/resources/ShapeSwitch.qml +++ b/plugins/squareone/tutorials/firstapplication/resources/ShapeSwitch.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ diff --git a/plugins/squareone/tutorials/workspace/resources/ClickedMessage.qml b/plugins/squareone/tutorials/workspace/resources/ClickedMessage.qml index 6e2bedfe..b74c3254 100644 --- a/plugins/squareone/tutorials/workspace/resources/ClickedMessage.qml +++ b/plugins/squareone/tutorials/workspace/resources/ClickedMessage.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ diff --git a/plugins/squareone/tutorials/workspace/resources/EditorPaneRemove.qml b/plugins/squareone/tutorials/workspace/resources/EditorPaneRemove.qml index 983b21d1..b2e45c11 100644 --- a/plugins/squareone/tutorials/workspace/resources/EditorPaneRemove.qml +++ b/plugins/squareone/tutorials/workspace/resources/EditorPaneRemove.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ diff --git a/plugins/squareone/tutorials/workspace/resources/MenuRemoveHighlight.qml b/plugins/squareone/tutorials/workspace/resources/MenuRemoveHighlight.qml index 00ebe26a..5925fe5f 100644 --- a/plugins/squareone/tutorials/workspace/resources/MenuRemoveHighlight.qml +++ b/plugins/squareone/tutorials/workspace/resources/MenuRemoveHighlight.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ diff --git a/plugins/timeline/palettes/TimelinePalette.qml b/plugins/timeline/palettes/TimelinePalette.qml index 1cddb0ab..d612c64f 100644 --- a/plugins/timeline/palettes/TimelinePalette.qml +++ b/plugins/timeline/palettes/TimelinePalette.qml @@ -216,6 +216,7 @@ CodePalette{ } else { timelineConfig.sourceComponent = null } + editFragment.whenBinding = function(){} } onValueFromBindingChanged: { timelineArea.timeline = value diff --git a/plugins/workspace/nodeeditor/qml/ObjectGraph.qml b/plugins/workspace/nodeeditor/qml/ObjectGraph.qml index 691e1199..191a2500 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectGraph.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectGraph.qml @@ -146,13 +146,11 @@ Rectangle{ property alias nodeDelegate : graph.nodeDelegate property var palette: null - property var documentHandler: null property var editor: null property var editingFragment: null onEditingFragmentChanged: { if (!editingFragment) return - documentHandler = editingFragment.codeHandler.documentHandler editor = editingFragment.codeHandler.documentHandler.textEdit().getEditor() } @@ -284,11 +282,11 @@ Rectangle{ addBox.color = 'transparent' addBoxItem.accept = function(type, data){ - var opos = root.documentHandler.codeHandler.addItem( + var opos = editingFragment.codeHandler.addItem( addBoxItem.addContainer.model.addPosition, addBoxItem.addContainer.objectType, data ) - root.documentHandler.codeHandler.addItemToRuntime(editingFragment, data, project.appRoot()) - var ef = root.documentHandler.codeHandler.openNestedConnection( + editingFragment.codeHandler.addItemToRuntime(editingFragment, data, project.appRoot()) + var ef = editingFragment.codeHandler.openNestedConnection( editingFragment, opos ) cursorCoords = Qt.point((pos.x - graphView.containerItem.x ) / zoom, (pos.y - graphView.containerItem.y) / zoom) @@ -400,7 +398,6 @@ Rectangle{ node.item.label = label node.label = label - node.item.documentHandler = documentHandler node.item.editor = editor node.item.objectGraph = root @@ -433,8 +430,6 @@ Rectangle{ var isForObject = propertyItem.isForObject propertyItem.width = node.item.width - (isForObject ? 30 : 0) - propertyItem.documentHandler = root.documentHandler - if (editingFragment) editingFragment.incrementRefCount() propertyItem.editor = root.editor diff --git a/plugins/workspace/nodeeditor/qml/ObjectNode.qml b/plugins/workspace/nodeeditor/qml/ObjectNode.qml index 2b962757..5fdbdbd4 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectNode.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectNode.qml @@ -28,7 +28,6 @@ Qan.NodeItem{ property var removeNode: null property var addSubobject: null property string id: "" - property var documentHandler: null property var editor: null property var objectGraph: null @@ -62,7 +61,7 @@ Qan.NodeItem{ } function expandOptions(options){ - var codeHandler = root.documentHandler.codeHandler + var codeHandler = editingFragment.codeHandler if ( 'palettes' in options){ var palettes = options['palettes'] @@ -134,7 +133,7 @@ Qan.NodeItem{ } } - var codeHandler = documentHandler.codeHandler + var codeHandler = editingFragment.codeHandler var position = editingFragment.valuePosition() + editingFragment.valueLength() - 1 @@ -310,13 +309,13 @@ Qan.NodeItem{ function onObjectAdded(obj, cursorCoords){ if (!addSubobject) return - documentHandler.codeHandler.populateObjectInfoForFragment(obj) + editingFragment.codeHandler.populateObjectInfoForFragment(obj) var object = obj.objectInfo() addSubobject(nodeParent, object.name + (object.id ? ("#" + object.id) : ""), ObjectGraph.PortMode.None, object.connection) } function onPropertyAdded(ef, expandDefault){ - documentHandler.codeHandler.populatePropertyInfoForFragment(ef) + editingFragment.codeHandler.populatePropertyInfoForFragment(ef) var prop = ef.objectInfo() var name = ef.identifier() diff --git a/plugins/workspace/nodeeditor/qml/ObjectNodeProperty.qml b/plugins/workspace/nodeeditor/qml/ObjectNodeProperty.qml index df373df8..91aa7c0e 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectNodeProperty.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectNodeProperty.qml @@ -19,7 +19,6 @@ Item{ property QtObject node : null property var objectGraph: node ? node.item.objectGraph : null property var editingFragment: null - property var documentHandler: null property alias propertyTitle: propertyTitle property alias paletteContainer: paletteContainer @@ -163,7 +162,7 @@ Item{ id: paletteCloseArea anchors.fill: parent onClicked: { - documentHandler.codeHandler.removeConnection(editingFragment) + editingFragment.codeHandler.removeConnection(editingFragment) if (editingFragment.refCount > 0) { destroyObjectNodeProperty() diff --git a/plugins/editor/qml/DocumentationView.qml b/plugins/workspace/qml/DocumentationView.qml similarity index 100% rename from plugins/editor/qml/DocumentationView.qml rename to plugins/workspace/qml/DocumentationView.qml diff --git a/plugins/editor/qml/LoadingAnimation.qml b/plugins/workspace/qml/LoadingAnimation.qml similarity index 100% rename from plugins/editor/qml/LoadingAnimation.qml rename to plugins/workspace/qml/LoadingAnimation.qml diff --git a/plugins/editor/qml/Pane.qml b/plugins/workspace/qml/Pane.qml similarity index 100% rename from plugins/editor/qml/Pane.qml rename to plugins/workspace/qml/Pane.qml diff --git a/plugins/editor/qml/PaneDragItem.qml b/plugins/workspace/qml/PaneDragItem.qml similarity index 100% rename from plugins/editor/qml/PaneDragItem.qml rename to plugins/workspace/qml/PaneDragItem.qml diff --git a/plugins/editor/qml/PaneDropArea.qml b/plugins/workspace/qml/PaneDropArea.qml similarity index 100% rename from plugins/editor/qml/PaneDropArea.qml rename to plugins/workspace/qml/PaneDropArea.qml diff --git a/plugins/editor/qml/PaneSplitView.qml b/plugins/workspace/qml/PaneSplitView.qml similarity index 100% rename from plugins/editor/qml/PaneSplitView.qml rename to plugins/workspace/qml/PaneSplitView.qml diff --git a/plugins/editor/qml/PaneWindow.qml b/plugins/workspace/qml/PaneWindow.qml similarity index 98% rename from plugins/editor/qml/PaneWindow.qml rename to plugins/workspace/qml/PaneWindow.qml index fe00cd74..67aa17bc 100644 --- a/plugins/editor/qml/PaneWindow.qml +++ b/plugins/workspace/qml/PaneWindow.qml @@ -1,5 +1,6 @@ import QtQuick 2.3 import QtQuick.Window 2.2 +import workspace 1.0 Window{ id: root diff --git a/plugins/editor/qml/WorkspaceControl.qml b/plugins/workspace/qml/WorkspaceControl.qml similarity index 100% rename from plugins/editor/qml/WorkspaceControl.qml rename to plugins/workspace/qml/WorkspaceControl.qml diff --git a/plugins/editor/qml/WorkspaceTheme.qml b/plugins/workspace/qml/WorkspaceTheme.qml similarity index 100% rename from plugins/editor/qml/WorkspaceTheme.qml rename to plugins/workspace/qml/WorkspaceTheme.qml diff --git a/plugins/workspace/qml/qmldir b/plugins/workspace/qml/qmldir index 111a651d..ab2bf9c5 100644 --- a/plugins/workspace/qml/qmldir +++ b/plugins/workspace/qml/qmldir @@ -12,4 +12,12 @@ Tool 1.0 Tool.qml Toolbar 1.0 Toolbar.qml Toolbox 1.0 Toolbox.qml ToolButton 1.0 ToolButton.qml - +Pane 1.0 Pane.qml +PaneSplitView 1.0 PaneSplitView.qml +PaneDragItem 1.0 PaneDragItem.qml +PaneDropArea 1.0 PaneDropArea.qml +PaneWindow 1.0 PaneWindow.qml +WorkspaceTheme 1.0 WorkspaceTheme.qml +WorkspaceControl 1.0 WorkspaceControl.qml +LoadingAnimation 1.0 LoadingAnimation.qml +DocumentationView 1.0 DocumentationView.qml diff --git a/plugins/workspace/quickqanava/qml/Port.qml b/plugins/workspace/quickqanava/qml/Port.qml index 148ff76b..58d8d67e 100644 --- a/plugins/workspace/quickqanava/qml/Port.qml +++ b/plugins/workspace/quickqanava/qml/Port.qml @@ -34,6 +34,7 @@ import QtQuick 2.7 import QtQuick.Controls 2.1 import workspace.quickqanava 2.0 as Qan +import workspace 1.0 Qan.PortItem { id: portItem @@ -122,7 +123,6 @@ Qan.PortItem { Pane { id: labelPane opacity: 0.80 - padding: 0 z: 2 width: label.implicitWidth height: label.implicitHeight From d270c032e2da091baab82a7bfeb419145f2c6ad2 Mon Sep 17 00:00:00 2001 From: nenad-popovic-91 <42581059+nenad-popovic-91@users.noreply.github.com> Date: Tue, 29 Jun 2021 09:19:54 +0200 Subject: [PATCH 78/91] AddQmlBox refactoring (#226) * Refactored AddQmlBox adding --- plugins/editqml/qml/AddQmlBox.qml | 70 +++-- plugins/editqml/qml/EditQmlExtension.qml | 108 ++++---- plugins/editqml/qml/PaletteControls.qml | 258 ++++++++++-------- .../workspace/nodeeditor/qml/ObjectGraph.qml | 71 +++-- 4 files changed, 280 insertions(+), 227 deletions(-) diff --git a/plugins/editqml/qml/AddQmlBox.qml b/plugins/editqml/qml/AddQmlBox.qml index 0144ba90..23bf8c4e 100644 --- a/plugins/editqml/qml/AddQmlBox.qml +++ b/plugins/editqml/qml/AddQmlBox.qml @@ -25,18 +25,13 @@ import visual.input 1.0 as Input Rectangle{ id: root - width: 380 + (mode & AddQmlBox.DisplayMode.WithFunctions ? 100: 0) + width: 380 + (categories.includes('functions') ? 100: 0) height: 280 color: root.theme.colorScheme.background opacity: 0.95 objectName: "addQmlBox" - enum DisplayMode { - ObjectsOnly = 0, - Default = 1, - WithFunctions = 2, - NoObjects = 4 - } + property var categories: ['objects', 'properties', 'events'] enum AddPropertyMode { Default = 0, @@ -54,13 +49,11 @@ Rectangle{ property int smallFontSize: 9 property var codeQmlHandler: null - property var mode: AddQmlBox.DisplayMode.Default - border.color: root.theme.colorScheme.middlegroundOverlayDominant border.width: 1 - onModeChanged: { - if (mode === AddQmlBox.DisplayMode.ObjectsOnly) + onCategoriesChanged: { + if (categories.length === 1 && categories[0] === 'objects') activeIndex = 2 } @@ -82,8 +75,9 @@ Rectangle{ searchInput.forceFocus() } - property var cancel: function(){ } - property var accept : function(type, data, mode){ } + property var cancel : function(){} + property var accept : function(selection){} + property var finalize : function(){} function getCompletion(){ if ( listView.currentItem ){ @@ -135,7 +129,7 @@ Rectangle{ spacing: 2 Input.TextButton{ - visible: mode !== AddQmlBox.DisplayMode.ObjectsOnly + visible: categories.length !== 1 || categories[0] !== 'objects' text: 'All' height: 22 width: 70 @@ -149,7 +143,7 @@ Rectangle{ } Input.TextButton{ - visible: mode !== AddQmlBox.DisplayMode.ObjectsOnly + visible: categories.includes('properties') text: 'Property' height: 22 width: 70 @@ -166,7 +160,7 @@ Rectangle{ text: 'Object' height: 22 width: 70 - visible: !(mode & AddQmlBox.DisplayMode.NoObjects) + visible: categories.includes('objects') style: root.theme.formButtonStyle color: { @@ -179,7 +173,7 @@ Rectangle{ } Input.TextButton{ - visible: mode !== AddQmlBox.DisplayMode.ObjectsOnly + visible: categories.includes('events') text: 'Event' height: 22 width: 70 @@ -194,7 +188,7 @@ Rectangle{ } Input.TextButton{ - visible: mode & AddQmlBox.DisplayMode.WithFunctions + visible: categories.includes('functions') text: 'Function' height: 22 width: 70 @@ -420,15 +414,43 @@ Rectangle{ } } - if (selector === 2){ + var selection = null + if (selector === 1){ + selection = { + category: 'property', + position: root.addContainer.model.addPosition, + name: code, + type: type, + mode: mode, + objectType: root.addContainer.objectType + } + } + else if (selector === 2){ var result = code if (idChecked && idInput.text !== "") result = result + "#" + idInput.text - root.activeIndex = 2 - root.accept(importSpace, result, mode) - } else { - root.activeIndex = selector - root.accept(type, code, mode) + selection = { + category: 'object', + position: root.addContainer.model.addPosition, + objectType: root.addContainer.objectType, + name: result + } + } else if (selector === 3){ + selection = { + category: 'event', + position: root.addContainer.model.addPosition, + objectType: root.addContainer.objectType, + name: code + } + } else if (selector === 4){ + selection = { + category: 'function', + position: root.addContainer.model.addPosition, + name: code + } } + + root.activeIndex = selector + root.accept(selection) } Item{ diff --git a/plugins/editqml/qml/EditQmlExtension.qml b/plugins/editqml/qml/EditQmlExtension.qml index f66c29f0..8d1e24de 100644 --- a/plugins/editqml/qml/EditQmlExtension.qml +++ b/plugins/editqml/qml/EditQmlExtension.qml @@ -210,66 +210,70 @@ WorkspaceExtension{ function add(activeIndex, objectsOnly, forRoot){ var activePane = lk.layers.workspace.panes.activePane - if ( activePane.objectName === 'editor' && - activePane.document && - canBeQml(activePane.document) ) - { - var addContainer = activePane.documentHandler.codeHandler.getAddOptions(activePane.textEdit.cursorPosition, CodeQmlHandler.NoReadOnly) - if ( !addContainer ) - return - var rect = activePane.getCursorRectangle() - var paneCoords = activePane.mapGlobalPosition() - var addBoxItem = globals.paletteControls.createAddQmlBox(null) - if (!addBoxItem) return - - addBoxItem.assignFocus() - addBoxItem.addContainer = addContainer - addBoxItem.codeQmlHandler = activePane.documentHandler.codeHandler + if (activePane.objectName !== 'editor' || + !activePane.document || + !canBeQml(activePane.document) ) + return - addBoxItem.activeIndex = activeIndex ? activeIndex : 0 - if (objectsOnly) - addBoxItem.mode = AddQmlBox.DisplayMode.ObjectsOnly + var addContainer = activePane.documentHandler.codeHandler.getAddOptions(activePane.textEdit.cursorPosition, CodeQmlHandler.NoReadOnly) + if ( !addContainer ) + return - var addBox = lk.layers.editor.environment.createEditorBox( - addBoxItem, rect, Qt.point(paneCoords.x, paneCoords.y), lk.layers.editor.environment.placement.bottom - ) - addBox.color = 'transparent' - addBoxItem.cancel = function(){ - addBoxItem.destroy() - addBox.destroy() - } - addBoxItem.accept = function(type, data){ - if ( addBoxItem.activeIndex === 1 ){ - activePane.documentHandler.codeHandler.addProperty( - addContainer.model.addPosition, addContainer.objectType, type, data, true - ) - } else if ( addBoxItem.activeIndex === 2 ){ - if (forRoot){ - var position = activePane.documentHandler.codeHandler.insertRootItem(data) - if (position === -1){ - lk.layers.workspace.messages.pushError("Error: Can't create object with name " + data, 1) - } else { - root.rootPosition = position - shapeRootObject(activePane, activePane.documentHandler.codeHandler) + var rect = activePane.getCursorRectangle() + var paneCoords = activePane.mapGlobalPosition() + + var categories = objectsOnly ? ['objects'] : ['objects', 'properties', 'events'] + + var addEditorBox = globals.paletteControls.views.openAddOptionsBox( + addContainer, + activePane.documentHandler.codeHandler, + { + aroundRect: rect, + panePosition: Qt.point(paneCoords.x, paneCoords.y), + relativePlacement: lk.layers.editor.environment.placement.bottom + }, + { + categories: categories, + onCancelled: function(box){ + box.child.finalize() + }, + onAccepted: function(box, selection){ + if ( selection.category === 'property' ){ + activePane.documentHandler.codeHandler.addProperty( + selection.position, selection.objectType, selection.type, selection.name, true + ) + } else if ( selection.category === 'object' ){ + if (forRoot){ + var position = activePane.documentHandler.codeHandler.insertRootItem(selection.name) + if (position === -1){ + lk.layers.workspace.messages.pushError("Error: Can't create object with name " + selection.name, 1) + } else { + root.rootPosition = position + shapeRootObject(activePane, activePane.documentHandler.codeHandler) + } } - } - else - activePane.documentHandler.codeHandler.addItem( - addContainer.model.addPosition, addContainer.objectType, data + else + activePane.documentHandler.codeHandler.addItem( + selection.position, selection.objectType, selection.name + ) + } else if ( selection.category === 'event' ){ + activePane.documentHandler.codeHandler.addEvent( + selection.position, selection.objectType, selection.type, selection.name ) - } else if ( addBoxItem.activeIndex === 3 ){ - activePane.documentHandler.codeHandler.addEvent( - addContainer.model.addPosition, addContainer.objectType, type, data - ) + } + box.child.finalize() + }, + onFinalized: function(box){ + box.child.destroy() + box.destroy() } - addBoxItem.destroy() - addBox.destroy() } + ) + + addEditorBox.child.activeIndex = activeIndex ? activeIndex : 0 + lk.layers.workspace.panes.setActiveItem(addEditorBox, activePane) - addBoxItem.assignFocus() - lk.layers.workspace.panes.setActiveItem(addBox, activePane) - } } function bind(){ diff --git a/plugins/editqml/qml/PaletteControls.qml b/plugins/editqml/qml/PaletteControls.qml index 2b4472a7..7fdfb4a3 100644 --- a/plugins/editqml/qml/PaletteControls.qml +++ b/plugins/editqml/qml/PaletteControls.qml @@ -86,6 +86,43 @@ QtObject{ ////////////////////////////////////////////// + property QtObject views: QtObject { + + function openAddOptionsBox(addContainer, codeHandler, editorBoxParams, handlers){ + var addBoxItem = createAddQmlBox(null) + if (!addBoxItem) return null + + addBoxItem.addContainer = addContainer + addBoxItem.codeQmlHandler = codeHandler + + addBoxItem.categories = handlers.categories + + var addEditorBox = lk.layers.editor.environment.createEditorBox( + addBoxItem, + editorBoxParams.aroundRect, + editorBoxParams.panePosition, + editorBoxParams.relativePlacement + ) + addEditorBox.color = 'transparent' + + if (handlers){ + addBoxItem.accept = function(selection){ + handlers.onAccepted(addEditorBox, selection) + } + addBoxItem.cancel = function(){ + handlers.onCancelled(addEditorBox) + } + addBoxItem.finalize = function(){ + handlers.onFinalized(addEditorBox) + } + } + + addBoxItem.assignFocus() + + return addEditorBox + } + } + function openDefaultPalette(editingFragment, paletteBoxParent, objectRoot){ if (!editingFragment) return var editor = editingFragment.codeHandler.documentHandler.textEdit().getEditor() @@ -224,17 +261,6 @@ QtObject{ if ( !addContainer ) return - var addBoxItem = createAddQmlBox(null) - - if (!addBoxItem) - return - addBoxItem.addContainer = addContainer - addBoxItem.codeQmlHandler = codeHandler - if (isForNode) - addBoxItem.mode = addBoxItem.mode | AddQmlBox.DisplayMode.WithFunctions - if (isGroup || !addContainer.model.supportsObjectNesting()) - addBoxItem.mode = addBoxItem.mode | AddQmlBox.DisplayMode.NoObjects - var oct = container.parent var pane = container.parent @@ -248,132 +274,138 @@ QtObject{ var paneCoords = pane.mapGlobalPosition() - var addBox = lk.layers.editor.environment.createEditorBox( - addBoxItem, - Qt.rect(coords.x + container.width - 180 / 2, coords.y, 30, 30), - Qt.point(paneCoords.x, paneCoords.y - 35), - lk.layers.editor.environment.placement.top - ) - - addBox.color = 'transparent' - addBoxItem.cancel = function(){ - if (isForNode) - objectGraph.activateFocus() - addBoxItem.destroy() - addBox.destroy() + var categories = ['properties', 'events'] + if (!isGroup && addContainer.model.supportsObjectNesting()){ + categories.push('objects') } + if (isForNode){ + categories.push('functions') + } + var addEditorBox = views.openAddOptionsBox( + addContainer, + codeHandler, + { + aroundRect: Qt.rect(coords.x + container.width - 180 / 2, coords.y, 30, 30), + panePosition: Qt.point(paneCoords.x, paneCoords.y - 35), + relativePlacement: lk.layers.editor.environment.placement.top + }, + { + categories: categories, + onCancelled: function(box){ + box.child.finalize() + }, + onFinalized: function(box){ + if (isForNode) objectGraph.activateFocus() + box.child.destroy() + box.destroy() + }, + onAccepted: function(box, selection){ + if ( selection.category === 'property' ){ // property + + // check if property is opened already + for (var i = 0; i < container.propertiesOpened.length; ++i){ + if (container.propertiesOpened[i] === selection.name){ + if (!isForNode && container.compact) container.expand() + box.child.finalize() + return + } + } - addBoxItem.accept = function(type, data, mode){ - if ( addBoxItem.activeIndex === 1 ){ // property - - // check if property is opened already - for (var i = 0; i < container.propertiesOpened.length; ++i){ - if (container.propertiesOpened[i] === data){ if (!isForNode && container.compact) container.expand() - addBoxItem.destroy() - addBox.destroy() - return - } - } - if (!isForNode && container.compact) container.expand() + var propsWritable = codeHandler.propertiesWritable(container.editingFragment) - var propsWritable = codeHandler.propertiesWritable(container.editingFragment) + var ef = null - var ef = null + var isWritable = propsWritable[selection.name] + if (selection.mode === AddQmlBox.AddPropertyMode.AddAsReadOnly){ + isWritable = false + } - var isWritable = propsWritable[data] - if (mode === AddQmlBox.AddPropertyMode.AddAsReadOnly){ - isWritable = false - } + if (isWritable){ + var ppos = codeHandler.addProperty( + selection.position, + selection.objectType, + selection.type, + selection.name, + true, + isGroup ? container.editingFragment : null + ) - if (isWritable){ - var ppos = codeHandler.addProperty( - addContainer.model.addPosition, - addContainer.objectType, - type, - data, - true, - isGroup ? container.editingFragment : null - ) - - ef = codeHandler.openNestedConnection( - container.editingFragment, ppos, project.appRoot() - ) - - if (isGroup) ef.addFragmentType(QmlEditFragment.GroupChild) - } else { - ef = codeHandler.createReadOnlyPropertyFragment(container.editingFragment, data) - } + ef = codeHandler.openNestedConnection( + container.editingFragment, ppos, project.appRoot() + ) - if (ef) { - container.editingFragment.signalPropertyAdded(ef) - } + if (isGroup) ef.addFragmentType(QmlEditFragment.GroupChild) + } else { + ef = codeHandler.createReadOnlyPropertyFragment(container.editingFragment, selection.name) + } - if (!ef) { - lk.layers.workspace.messages.pushError("Error: Can't create a palette in a non-compiled program", 1) - } + if (ef) { + container.editingFragment.signalPropertyAdded(ef) + } - var paletteList = ef.paletteList() - for ( var i = 0; i < paletteList.length; ++i ){ - if ( paletteList[i].writer ){ - paletteList[i].writer() - break - } - } + if (!ef) { + lk.layers.workspace.messages.pushError("Error: Can't create a palette in a non-compiled program", 1) + } + var paletteList = ef.paletteList() + for ( var i = 0; i < paletteList.length; ++i ){ + if ( paletteList[i].writer ){ + paletteList[i].writer() + break + } + } - } else if ( addBoxItem.activeIndex === 2 ){ // object - addItemToRuntimeWithNotification(container, addContainer.model.addPosition, addContainer.objectType, data, isForNode) + } else if ( selection.category === 'object' ){ // object - } else if ( addBoxItem.activeIndex === 3 ){ // event + addItemToRuntimeWithNotification(container, selection.position, selection.objectType, selection.name, isForNode) - // check if event is opened already - for (var i = 0; i < container.propertiesOpened.length; ++i){ - if (container.propertiesOpened[i] === data){ - if (!isForNode && container.compact) container.expand() - addBoxItem.destroy() - addBox.destroy() - return - } - } + } else if ( selection.category === 'event' ){ // event - var ppos = codeHandler.addEvent( - addContainer.model.addPosition, - addContainer.objectType, - type, - data, - true - ) - - var ef = codeHandler.openNestedConnection( - container.editingFragment, ppos, project.appRoot() - ) - - if (ef) { - container.editingFragment.signalPropertyAdded(ef) - if (!isForNode && container.compact) container.sortChildren() - } + // check if event is opened already + for (var i = 0; i < container.propertiesOpened.length; ++i){ + if (container.propertiesOpened[i] === selection.name){ + if (!isForNode && container.compact) container.expand() + box.child.finalize() + return + } + } - if (!ef) { - lk.layers.workspace.messages.pushError("Error: Can't create a palette in a non-compiled program", 1) + var ppos = codeHandler.addEvent( + selection.position, + selection.objectType, + selection.type, + selection.name, + true + ) - } + var ef = codeHandler.openNestedConnection( + container.editingFragment, ppos, project.appRoot() + ) - } else if (isForNode && addBoxItem.activeIndex === 4 ){ - container.nodeParent.item.addSubobject(container.nodeParent, data, container.nodeParent.item.id ? ObjectGraph.PortMode.InPort : ObjectGraph.PortMode.Node, null, {isMethod: true}) - } + if (ef) { + container.editingFragment.signalPropertyAdded(ef) + if (!isForNode && container.compact) container.sortChildren() + } - if (isForNode) objectGraph.activateFocus() - addBoxItem.destroy() - addBox.destroy() - } + if (!ef) { + lk.layers.workspace.messages.pushError("Error: Can't create a palette in a non-compiled program", 1) + + } + } else if (isForNode && selection.category === 'function' ){ + container.nodeParent.item.addSubobject(container.nodeParent, selection.name, container.nodeParent.item.id ? ObjectGraph.PortMode.InPort : ObjectGraph.PortMode.Node, null, {isMethod: true}) + } + + box.child.finalize() + } + } + ) - addBoxItem.assignFocus() - lk.layers.workspace.panes.setActiveItem(addBox, container.editor) + lk.layers.workspace.panes.setActiveItem(addEditorBox, container.editor) } function addPropertyContainer(objectContainer, ef, expandDefault){ diff --git a/plugins/workspace/nodeeditor/qml/ObjectGraph.qml b/plugins/workspace/nodeeditor/qml/ObjectGraph.qml index 191a2500..e5558daa 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectGraph.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectGraph.qml @@ -262,52 +262,47 @@ Rectangle{ } onDoubleClicked: { - var addBoxItem = paletteControls.createAddQmlBox(null) - if (!addBoxItem) return - var position = root.editingFragment.valuePosition() + root.editingFragment.valueLength() - 1 var addOptions = root.editingFragment.codeHandler.getAddOptions(position) - addBoxItem.addContainer = addOptions - addBoxItem.codeQmlHandler = root.editingFragment.codeHandler - - addBoxItem.mode = AddQmlBox.DisplayMode.ObjectsOnly - - var rect = Qt.rect(pos.x, pos.y, 1, 1) var coords = root.editor.parent.mapGlobalPosition() var cursorCoords = Qt.point(coords.x, coords.y) - var addBox = lk.layers.editor.environment.createEditorBox( - addBoxItem, rect, cursorCoords, lk.layers.editor.environment.placement.bottom - ) - addBox.color = 'transparent' - - addBoxItem.accept = function(type, data){ - var opos = editingFragment.codeHandler.addItem( - addBoxItem.addContainer.model.addPosition, addBoxItem.addContainer.objectType, data - ) - editingFragment.codeHandler.addItemToRuntime(editingFragment, data, project.appRoot()) - var ef = editingFragment.codeHandler.openNestedConnection( - editingFragment, opos - ) - cursorCoords = Qt.point((pos.x - graphView.containerItem.x ) / zoom, (pos.y - graphView.containerItem.y) / zoom) - if (ef) - editingFragment.signalObjectAdded(ef, cursorCoords) - root.activateFocus() - - addBoxItem.destroy() - addBox.destroy() - } - - addBoxItem.cancel = function(){ - root.activateFocus() - - addBoxItem.destroy() - addBox.destroy() - } + var addBoxItem = paletteControls.views.openAddOptionsBox( + addOptions, + root.editingFragment.codeHandler, + { + aroundRect: Qt.rect(pos.x, pos.y, 1, 1), + panePosition: cursorCoords, + relativePlacement: lk.layers.editor.environment.placement.bottom + }, + { + categories: ['objects'], + onCancelled: function(box){ + box.child.finalize() + }, + onFinalized: function(box){ + root.activateFocus() + box.child.destroy() + box.destroy() + }, + onAccepted: function(box, selection){ + var opos = editingFragment.codeHandler.addItem( + selection.position, selection.objectType, selection.name + ) + editingFragment.codeHandler.addItemToRuntime(editingFragment, selection.name, project.appRoot()) + var ef = editingFragment.codeHandler.openNestedConnection( + editingFragment, opos + ) + cursorCoords = Qt.point((pos.x - graphView.containerItem.x ) / zoom, (pos.y - graphView.containerItem.y) / zoom) - addBoxItem.assignFocus() + if (ef) + editingFragment.signalObjectAdded(ef, cursorCoords) + box.child.finalize() + } + } + ) } function bindPorts(src, dst){ From aeaf3cfbb18e298e67bdf20bd01afcaeed16ec09 Mon Sep 17 00:00:00 2001 From: nenad-popovic-91 <42581059+nenad-popovic-91@users.noreply.github.com> Date: Thu, 1 Jul 2021 08:36:59 +0200 Subject: [PATCH 79/91] PaletteList view updates. (#225) Modification for palettelist functions --- plugins/editqml/qml/ObjectContainer.qml | 2 +- plugins/editqml/qml/PaletteContainer.qml | 2 +- plugins/editqml/qml/PaletteControls.qml | 441 ++++++++++-------- plugins/editqml/qml/PropertyContainer.qml | 2 +- .../workspace/nodeeditor/qml/ObjectNode.qml | 5 +- .../nodeeditor/qml/ObjectNodeProperty.qml | 5 +- 6 files changed, 259 insertions(+), 198 deletions(-) diff --git a/plugins/editqml/qml/ObjectContainer.qml b/plugins/editqml/qml/ObjectContainer.qml index 283b44b7..b4e5cc7f 100644 --- a/plugins/editqml/qml/ObjectContainer.qml +++ b/plugins/editqml/qml/ObjectContainer.qml @@ -406,7 +406,7 @@ Item{ if ( container.pane ) coords.y -= 30 // if this container is in the title of a pane - var paletteList = paletteControls.addPaletteList( + var paletteList = paletteControls.views.openPaletetListBoxForContainer( objectContainer, paletteGroup, Qt.rect(coords.x + objectContainerTitle.width - (180 / 2), coords.y, 30, 30), diff --git a/plugins/editqml/qml/PaletteContainer.qml b/plugins/editqml/qml/PaletteContainer.qml index 494a1b21..bb109731 100644 --- a/plugins/editqml/qml/PaletteContainer.qml +++ b/plugins/editqml/qml/PaletteContainer.qml @@ -65,7 +65,7 @@ Rectangle{ var coords = paletteContainer.mapToItem(pane, 0, 0) coords.y -= 35; - var paletteList = paletteControls.addPaletteList( + var paletteList = paletteControls.views.openPaletetListBoxForContainer( paletteContainer, paletteContainer.parent, Qt.rect(coords.x - 180 / 2, coords.y, 30, 30), diff --git a/plugins/editqml/qml/PaletteControls.qml b/plugins/editqml/qml/PaletteControls.qml index 7fdfb4a3..f608f8e5 100644 --- a/plugins/editqml/qml/PaletteControls.qml +++ b/plugins/editqml/qml/PaletteControls.qml @@ -33,9 +33,18 @@ QtObject{ property var selectedHandler : function(){} property var cancelledHandler : function(index){} - onPaletteSelected: selectedHandler(index) - onCancelled : cancelledHandler() - + onPaletteSelected : function(index){ + focus = false + model = null + destroy() + selectedHandler(index) + } + onCancelled : function(){ + focus = false + model = null + destroy() + cancelledHandler() + } onParentChanged: { if (parent) anchors.top = parent.top } @@ -88,6 +97,163 @@ QtObject{ property QtObject views: QtObject { + function openPaletteList(style, model, parent, handlers){ + var paletteList = createPaletteListView(parent, style) + paletteList.model = model + + if (handlers){ + paletteList.cancelledHandler = handlers.onCancelled + paletteList.selectedHandler = handlers.onSelected + } + + return paletteList + } + + function openPaletteListBox(style, model, editorBoxParams, handlers){ + var paletteList = openPaletteList(style, model, null) + + var paletteListBox = lk.layers.editor.environment.createEditorBox( + paletteList, + editorBoxParams.aroundRect, + editorBoxParams.panePosition, + editorBoxParams.relativePlacement + ) + + paletteList.forceActiveFocus() + paletteListBox.color = 'transparent' + + if (handlers){ + paletteList.cancelledHandler = function(){ + handlers.onCancelled(paletteListBox) + } + paletteList.selectedHandler = function(index){ + handlers.onSelected(index, paletteListBox) + } + } + return paletteList + } + + function openPaletteListForNode(container, paletteGroup, parent){ + + var palettes = findPalettesFromFragment(container.editingFragment, paletteGroup.palettesOpened, true) + + if (!palettes.data || palettes.data.length === 0) return null + + var paletteList = openPaletteList(theme.selectableListView, palettes.data, parent, + { + onCancelled: function(){ + container.objectGraph.paletteListOpened = false + container.objectGraph.activateFocus() + }, + onSelected: function(index){ + var palette = container.editor.documentHandler.codeHandler.expand(container.editingFragment, { + "palettes" : [palettes.data[index].name] + }) + + var objectRoot = container.objectName === "objectNode" ? container : null + var paletteBox = openPalette(palette, + paletteGroup, + objectRoot) + + if (paletteBox){ + paletteBox.moveEnabledSet = false + } + + container.objectGraph.paletteListOpened = false + container.objectGraph.activateFocus() + } + }) + + container.objectGraph.paletteListOpened = true + + return paletteList + } + + function openPaletetListBoxForContainer(container, paletteGroup, aroundBox, mode, swap){ + + var palettes = findPalettesFromFragment( + container.editingFragment, + paletteGroup.palettesOpened, + mode === PaletteControls.PaletteListMode.ObjectContainer + ) + + if (!palettes.data || palettes.data.length === 0) return null + + var pane = container.parent + if ( container.pane ) + pane = container.pane + while (pane && pane.objectName !== "editor" && pane.objectName !== "objectPalette"){ + pane = pane.parent + if ( pane && pane.pane && pane.pane.objectName === 'objectPalette' ){ + pane = pane.pane + } + } + var paneCoords = pane.mapGlobalPosition() + + var editorBoxParams = { + aroundRect: aroundBox, + panePosition: Qt.point(paneCoords.x, paneCoords.y - 35), + relativePlacement: lk.layers.editor.environment.placement.bottom + } + + var cancelledHandler = function(paletteListBox){ + paletteListBox.destroy() + } + + var selectedHandler = function(index, paletteListBox){ + var palette = container.editor.documentHandler.codeHandler.expand(container.editingFragment, { + "palettes" : [palettes.data[index].name] + }) + + var objectRoot = mode === PaletteControls.PaletteListMode.ObjectContainer + ? container.parent + : (container.objectName === "objectNode" ? container : null) + var paletteBox = openPalette(palette, + paletteGroup, + objectRoot) + + if (paletteBox){ + if (mode === PaletteControls.PaletteListMode.ObjectContainer){ + paletteBox.moveEnabledSet = false + } else if (mode === PaletteControls.PaletteListMode.PaletteContainer){ + paletteBox.moveEnabledSet = container.moveEnabledGet + } + } + + if (swap === PaletteControls.PaletteListSwap.Swap){ + + var p = container.parent + while (p && p.objectName !== "paletteGroup"){ + p = p.parent + } + p.palettesOpened = p.palettesOpened.filter(function(name){ return name !== container.palette.name }) + container.parent = null + container.documentHandler.codeHandler.removePalette(container.palette) + container.destroy() + } + + paletteListBox.destroy() + } + + var handlers = { + onCancelled: cancelledHandler, + onSelected: selectedHandler + } + + var paletteList = openPaletteListBox( + theme.selectableListView, + palettes.data, + { + aroundRect: aroundBox, + panePosition: Qt.point(paneCoords.x, paneCoords.y - 35), + relativePlacement: lk.layers.editor.environment.placement.bottom + }, + handlers + ) + + return paletteList + } + function openAddOptionsBox(addContainer, codeHandler, editorBoxParams, handlers){ var addBoxItem = createAddQmlBox(null) if (!addBoxItem) return null @@ -103,6 +269,7 @@ QtObject{ editorBoxParams.panePosition, editorBoxParams.relativePlacement ) + addEditorBox.color = 'transparent' if (handlers){ @@ -121,6 +288,22 @@ QtObject{ return addEditorBox } + + } + + function findPalettesFromFragment(editingFragment, palettesOpened, includeLayouts){ + if (!editingFragment) + return null + + var palettes = editingFragment.codeHandler.findPalettesFromFragment(editingFragment) + + palettes.data = filterOutPalettes( + palettes.data, + palettesOpened, + includeLayouts + ) + + return palettes } function openDefaultPalette(editingFragment, paletteBoxParent, objectRoot){ @@ -717,116 +900,6 @@ QtObject{ return result } - function addPaletteList(container, paletteGroup, aroundBox, mode, swap, listParent){ - - if (!container.editingFragment) - return null - - var palettes = container.editor.documentHandler.codeHandler.findPalettesFromFragment( - container.editingFragment - ) - - var position = palettes.declaration.position - - palettes.data = filterOutPalettes( - palettes.data, - paletteGroup.palettesOpened, - mode === PaletteControls.PaletteListMode.ObjectContainer || mode === PaletteControls.PaletteListMode.NodeEditor - ) - - if (!palettes.data || palettes.data.length === 0) return null - - var paletteList = createPaletteListView(listParent ? listParent : null, theme.selectableListView) - paletteList.model = palettes.data - - var palListBox = null - if (mode !== PaletteControls.PaletteListMode.NodeEditor){ - - var pane = container.parent - if ( container.pane ) - pane = container.pane - while (pane && pane.objectName !== "editor" && pane.objectName !== "objectPalette"){ - pane = pane.parent - if ( pane && pane.pane && pane.pane.objectName === 'objectPalette' ){ - pane = pane.pane - } - } - - var paneCoords = pane.mapGlobalPosition() - - palListBox = lk.layers.editor.environment.createEditorBox( - paletteList, - aroundBox, - Qt.point(paneCoords.x, paneCoords.y - 35), - lk.layers.editor.environment.placement.bottom - ) - - palListBox.color = 'transparent' - - } else { - container.objectGraph.paletteListOpened = true - } - - paletteList.forceActiveFocus() - - - paletteList.cancelledHandler = function(){ - paletteList.focus = false - paletteList.model = null - paletteList.destroy() - if (mode !== PaletteControls.PaletteListMode.NodeEditor) palListBox.destroy() - else { - container.objectGraph.paletteListOpened = false - container.objectGraph.activateFocus() - } - } - - paletteList.selectedHandler = function(index){ - paletteList.focus = false - paletteList.model = null - - var palette = container.editor.documentHandler.codeHandler.expand(container.editingFragment, { - "palettes" : [palettes.data[index].name] - }) - - var objectRoot = mode === PaletteControls.PaletteListMode.ObjectContainer - ? container.parent - : (container.objectName === "objectNode" ? container : null) - var paletteBox = openPalette(palette, - paletteGroup, - objectRoot) - - if (paletteBox){ - if (mode === PaletteControls.PaletteListMode.ObjectContainer || mode === PaletteControls.PaletteListMode.NodeEditor){ - paletteBox.moveEnabledSet = false - } else if (mode === PaletteControls.PaletteListMode.PaletteContainer){ - paletteBox.moveEnabledSet = container.moveEnabledGet - } - } - - if (mode === PaletteControls.PaletteListMode.PaletteContainer && swap === PaletteControls.PaletteListSwap.Swap){ - - var p = container.parent - while (p && p.objectName !== "paletteGroup"){ - p = p.parent - } - p.palettesOpened = p.palettesOpened.filter(function(name){ return name !== container.palette.name }) - container.parent = null - container.documentHandler.codeHandler.removePalette(container.palette) - container.destroy() - } - - paletteList.destroy() - if (mode !== PaletteControls.PaletteListMode.NodeEditor) palListBox.destroy() - else { - container.objectGraph.paletteListOpened = false - container.objectGraph.activateFocus() - } - } - - return paletteList - } - function eraseObject(objectContainer){ var rootDeleted = (objectContainer.editingFragment.position() === objectContainer.editor.documentHandler.codeHandler.findRootPosition()) objectContainer.editor.documentHandler.codeHandler.eraseObject(objectContainer.editingFragment, !objectContainer.isForProperty) @@ -875,7 +948,7 @@ QtObject{ objectContainer.collapse() var rootPos = codeHandler.findRootPosition() if (rootPos === objectContainer.editingFragment.position()) - objectContainer.editor.editor.rootShaped = false + objectContainer.editor.rootShaped = false codeHandler.removeConnection(objectContainer.editingFragment) @@ -927,9 +1000,6 @@ QtObject{ var codeHandler = editor.documentHandler.codeHandler var palettes = codeHandler.findPalettes(editor.textEdit.cursorPosition) - var rect = editor.getCursorRectangle() - var paneCoords = editor.mapGlobalPosition() - var position = palettes.declaration.position palettes.data = filterOutPalettes(palettes.data) @@ -942,30 +1012,29 @@ QtObject{ loadPalette(editor, palettes.data, 0, position) } else { //Palette list box + editor.internalFocus = false - var palList = createPaletteListView(null, theme.selectableListView) - var palListBox = lk.layers.editor.environment.createEditorBox( - palList, rect, paneCoords, lk.layers.editor.environment.placement.bottom + var paletteList = views.openPaletteListBox( + theme.selectableListView, + palettes.data, + { + aroundRect: editor.getCursorRectangle(), + panePosition: editor.mapGlobalPosition(), + relativePlacement: lk.layers.editor.environment.placement.bottom + }, + { + onCancelled: function(paletteListBox){ + editor.editor.forceFocus() + paletteListBox.destroy() + }, + onSelected: function(index, paletteListBox){ + editor.editor.forceFocus() + paletteListBox.destroy() + loadPalette(editor, palettes.data, index, position) + } + } ) - palListBox.color = 'transparent' - palList.model = palettes.data - editor.internalFocus = false - palList.forceActiveFocus() - lk.layers.workspace.panes.setActiveItem(palList, editor) - - palList.cancelled.connect(function(){ - palList.focus = false - editor.editor.forceFocus() - palList.destroy() - palListBox.destroy() - }) - palList.paletteSelected.connect(function(index){ - palList.focus = false - editor.editor.forceFocus() - palList.destroy() - palListBox.destroy() - loadPalette(editor, palettes.data, index, position) - }) + lk.layers.workspace.panes.setActiveItem(paletteList, editor) } } @@ -975,36 +1044,35 @@ QtObject{ var position = palettes.declaration.position - var rect = editor.getCursorRectangle() - var cursorCoords = editor.mapGlobalPosition() - if ( !palettes.data || palettes.data.length === 0 ){ shapePalette(editor, "", position) } else if ( palettes.length === 1 ){ shapePalette(editor, palettes.data[0].name, position) } else { //Palette list box - var palList = globals.paletteControls.createPaletteListView(null, currentTheme.selectableListView) - var palListBox = lk.layers.editor.environment.createEditorBox(palList, rect, cursorCoords, lk.layers.editor.environment.placement.bottom) - palListBox.color = 'transparent' - palList.model = palettes.data editor.internalFocus = false - palList.forceActiveFocus() - lk.layers.workspace.panes.setActiveItem(palList, editor) - - palList.cancelled.connect(function(){ - palList.focus = false - editor.editor.forceFocus() - palList.destroy() - palListBox.destroy() - }) - palList.paletteSelected.connect(function(index){ - palList.focus = false - editor.editor.forceFocus() - palList.destroy() - palListBox.destroy() - shapePalette(editor, palettes.data[index].name, position) - }) + + var paletteList = views.openPaletteListBox( + theme.selectableListView, + palettes.data, + { + aroundRect: editor.getCursorRectangle(), + panePosition: editor.mapGlobalPosition(), + relativePlacement: lk.layers.editor.environment.placement.bottom + }, + { + onCancelled: function(paletteListBox){ + editor.editor.forceFocus() + paletteListBox.destroy() + }, + onSelected: function(index, paletteListBox){ + editor.editor.forceFocus() + paletteListBox.destroy() + shapePalette(editor, palettes.data[index].name, position) + } + } + ) + lk.layers.workspace.panes.setActiveItem(paletteList, editor) } } @@ -1015,37 +1083,36 @@ QtObject{ var position = palettes.declaration.position palettes = filterOutPalettes(palettes) - var rect = editor.getCursorRectangle() - var cursorCoords = editor.mapGlobalPosition() if ( palettes.data.length === 1 ){ var ef = codeHandler.openConnection(position) ef.incrementRefCount() codeHandler.openBinding(ef, palettes.data[0].name) } else { - var palList = createPaletteListView(null, theme.selectableListView) - var palListBox = lk.layers.editor.environment.createEditorBox(palList, rect, cursorCoords, lk.layers.editor.environment.placement.bottom) - palListBox.color = 'transparent' - palList.model = palettes.data editor.internalFocus = false - palList.forceActiveFocus() - lk.layers.workspace.panes.setActiveItem(palList, editor) - - palList.cancelled.connect(function(){ - palList.focus = false - editor.editor.forceFocus() - palList.destroy() - palListBox.destroy() - }) - palList.paletteSelected.connect(function(index){ - palList.focus = false - editor.editor.forceFocus() - palList.destroy() - palListBox.destroy() - - var ef = codeHandler.openConnection(position) - ef.incrementRefCount() - codeHandler.openBinding(ef, palettes.data[index].name) - }) + + var paletteList = views.openPaletteListBox( + theme.selectableListView, + palettes.data, + { + aroundRect: editor.getCursorRectangle(), + panePosition: editor.mapGlobalPosition(), + relativePlacement: lk.layers.editor.environment.placement.bottom + }, + { + onCancelled: function(paletteListBox){ + editor.editor.forceFocus() + paletteListBox.destroy() + }, + onSelected: function(index, paletteListBox){ + editor.editor.forceFocus() + paletteListBox.destroy() + var ef = codeHandler.openConnection(position) + ef.incrementRefCount() + codeHandler.openBinding(ef, palettes.data[index].name) + } + } + ) + lk.layers.workspace.panes.setActiveItem(paletteList, editor) } } diff --git a/plugins/editqml/qml/PropertyContainer.qml b/plugins/editqml/qml/PropertyContainer.qml index 4c2ab70b..81e99241 100644 --- a/plugins/editqml/qml/PropertyContainer.qml +++ b/plugins/editqml/qml/PropertyContainer.qml @@ -113,7 +113,7 @@ Item{ } var coords = paletteAddButton.mapToItem(pane, 0, 0) - var paletteList = paletteControls.addPaletteList( + var paletteList = paletteControls.views.openPaletetListBoxForContainer( propertyContainer, propertyContainer.valueContainer, Qt.rect(coords.x + 150, coords.y, 30, 30), diff --git a/plugins/workspace/nodeeditor/qml/ObjectNode.qml b/plugins/workspace/nodeeditor/qml/ObjectNode.qml index 5fdbdbd4..f9fb1e85 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectNode.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectNode.qml @@ -262,12 +262,9 @@ Qan.NodeItem{ anchors.fill: parent onClicked: { root.selected = false - var paletteList = paletteControls.addPaletteList( + var paletteList = paletteControls.views.openPaletteListForNode( root, paletteContainer, - {"x": 0, "y": 0}, - PaletteControls.PaletteListMode.NodeEditor, - PaletteControls.PaletteListSwap.NoSwap, wrapper ) diff --git a/plugins/workspace/nodeeditor/qml/ObjectNodeProperty.qml b/plugins/workspace/nodeeditor/qml/ObjectNodeProperty.qml index 91aa7c0e..25b862d1 100644 --- a/plugins/workspace/nodeeditor/qml/ObjectNodeProperty.qml +++ b/plugins/workspace/nodeeditor/qml/ObjectNodeProperty.qml @@ -124,12 +124,9 @@ Item{ anchors.fill: parent onClicked: { var coords = propertyItem.mapToItem(node.item, 0, 0) - var paletteList = paletteControls.addPaletteList( + var paletteList = paletteControls.views.openPaletteListForNode( propertyItem, paletteContainer, - Qt.rect(coords.x, coords.y ,1,1), - PaletteControls.PaletteListMode.NodeEditor, - PaletteControls.PaletteListSwap.NoSwap, node.item ) From dd1d8b00405c8c1b221f6667026a23d3d807ac3d Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Thu, 1 Jul 2021 09:39:16 +0300 Subject: [PATCH 80/91] Fixed VideoSurfaceCreator surface types. --- plugins/lcvcore/qml/VideoSurfaceCreator.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/lcvcore/qml/VideoSurfaceCreator.qml b/plugins/lcvcore/qml/VideoSurfaceCreator.qml index 53ee05ba..59df509a 100644 --- a/plugins/lcvcore/qml/VideoSurfaceCreator.qml +++ b/plugins/lcvcore/qml/VideoSurfaceCreator.qml @@ -56,7 +56,7 @@ Rectangle{ property var values: [ { w: 800, h: 600, label: '800x600 4:3 (Default)'}, { w: 1280, h: 720, label: '1280x720 16:9 (HD)'}, - { w: 800, h: 600, label: '1920x1080 16:9 (Full HD)'}, + { w: 1920, h: 1080, label: '1920x1080 16:9 (Full HD)'}, { w: 3840, h: 2160, label: '3840x600 16:9 (Ultra HD)'} ] From 91cabebb847cb1ab8d769c0db51ac994a4493504 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Thu, 1 Jul 2021 09:39:47 +0300 Subject: [PATCH 81/91] Workspace: Added support for checking files that can be run. --- application/qml/ProjectEnvironment.qml | 7 +++++++ lib/lveditor/src/project.cpp | 7 +++++++ lib/lveditor/src/project.h | 1 + 3 files changed, 15 insertions(+) diff --git a/application/qml/ProjectEnvironment.qml b/application/qml/ProjectEnvironment.qml index 5bb116c3..6690b484 100644 --- a/application/qml/ProjectEnvironment.qml +++ b/application/qml/ProjectEnvironment.qml @@ -301,6 +301,7 @@ Item{ function openFileViaDialog(callback){ var openCallback = function(url){ + var localPath = Fs.UrlInfo.toLocalFile(url) if ( project.rootPath === '' ){ project.openProject(url) var path = Fs.UrlInfo.toLocalFile(url) @@ -308,6 +309,8 @@ Item{ callback(path) } else if ( project.isFileInProject(url) ){ root.wizards.openFile(url, ProjectDocument.EditIfNotOpen, callback) + } else if ( !project.canRunFile(localPath) ){ + root.wizards.openFile(url, ProjectDocument.EditIfNotOpen, callback) } else { var fileUrl = url lk.layers.window.dialogs.message( @@ -324,6 +327,10 @@ Item{ }) mbox.close() }, + button2Name : 'Open file', + button2Function : function(mbox){ + root.wizards.openFile(url, ProjectDocument.EditIfNotOpen, callback) + }, button3Name : 'Cancel', button3Function : function(mbox){ mbox.close() diff --git a/lib/lveditor/src/project.cpp b/lib/lveditor/src/project.cpp index 1be04c9a..e0b68d7b 100644 --- a/lib/lveditor/src/project.cpp +++ b/lib/lveditor/src/project.cpp @@ -330,6 +330,13 @@ bool Project::isFileInProject(const QString &path) const{ return !path.isEmpty() && path.startsWith(m_path); } +/** + * \brief Checks whether the file can be run + */ +bool Project::canRunFile(const QString &path) const{ + return path.endsWith(".qml") || path.endsWith(".lv"); +} + /** * \brief Set the active file given its path * diff --git a/lib/lveditor/src/project.h b/lib/lveditor/src/project.h index 7c7d7408..73c3c261 100644 --- a/lib/lveditor/src/project.h +++ b/lib/lveditor/src/project.h @@ -130,6 +130,7 @@ public slots: bool isDirProject() const; bool isFileInProject(const QUrl& rootPath) const; bool isFileInProject(const QString& rootPath) const; + bool canRunFile(const QString& path) const; void openProject(const QString& rootPath); void openProject(const QUrl& url); From 2163c66b5380711475ea80025ca44b287d85977e Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Thu, 1 Jul 2021 10:13:23 +0300 Subject: [PATCH 82/91] Updated compiler warnings. --- application/src/livekeys.cpp | 6 ++++-- lib/lveditor/3rdparty/textedit.cpp | 6 +++--- lib/lveditor/3rdparty/textedit_p.h | 4 ++-- lib/lveditor/src/projectdocument.cpp | 2 +- lib/lveditor/src/startupmodel.cpp | 9 +++++---- lib/lveditor/src/textdocumentdata.cpp | 4 ++-- lib/lveditor/src/textdocumentdata.h | 2 +- lib/lveditqmljs/src/codeqmlhandler.cpp | 6 ++---- plugins/base/baseqml/src/qmlstreamsink.h | 1 + plugins/lcvimgproc/src/qcascadeclassifier.cpp | 2 +- plugins/lcvimgproc/src/qgeometry.cpp | 2 +- plugins/lcvimgproc/src/qtransformations.cpp | 9 +++++---- plugins/timeline/src/segmentmodel.cpp | 2 +- plugins/timeline/src/tracklistmodel.cpp | 2 +- 14 files changed, 30 insertions(+), 27 deletions(-) diff --git a/application/src/livekeys.cpp b/application/src/livekeys.cpp index 120f48a5..f66d6a63 100644 --- a/application/src/livekeys.cpp +++ b/application/src/livekeys.cpp @@ -289,8 +289,8 @@ int Livekeys::exec(const QGuiApplication& app){ #endif } -int Livekeys::execElements(const QGuiApplication &app){ #ifdef BUILD_ELEMENTS +int Livekeys::execElements(const QGuiApplication &app){ int result = 0; m_engine->setPackageImportPaths({lv::ApplicationContext::instance().pluginPath()}); m_engine->scope([&result, this, &app](){ @@ -298,11 +298,13 @@ int Livekeys::execElements(const QGuiApplication &app){ result = app.exec(); }); return result; +} #else +int Livekeys::execElements(const QGuiApplication &){ vlog().e() << "Support for elements is disabled."; return 0; -#endif } +#endif void Livekeys::loadDefaultLayers(){ QStringList layersToLoad = {"window", "workspace", "editor"}; // defaults diff --git a/lib/lveditor/3rdparty/textedit.cpp b/lib/lveditor/3rdparty/textedit.cpp index 9955e2a0..0de60dd9 100644 --- a/lib/lveditor/3rdparty/textedit.cpp +++ b/lib/lveditor/3rdparty/textedit.cpp @@ -4082,14 +4082,14 @@ void TextEdit::linePaletteRemoved(QQuickItem *palette) if (result == -1) return; } -void TextEdit::linePaletteHeightChanged(QQuickItem *palette, int newHeight) +void TextEdit::linePaletteHeightChanged(QQuickItem *palette, int) { Q_D(TextEdit); d->lineControl->resizePaletteHeight(palette); } -void TextEdit::linePaletteWidthChanged(QQuickItem *palette, int newWidth) +void TextEdit::linePaletteWidthChanged(QQuickItem *palette, int) { Q_D(TextEdit); @@ -4245,7 +4245,7 @@ void TextEdit::manageExpandCollapse(int pos, bool collapsed) d->lineControl->collapseChange(pos, delta); } -void TextEdit::updateLineSurface(int oldLineNum, int newLineNum, int dirtyPos) +void TextEdit::updateLineSurface(int, int, int) { Q_D(TextEdit); if (d->lineSurface) d->lineSurface->triggerUpdate(); diff --git a/lib/lveditor/3rdparty/textedit_p.h b/lib/lveditor/3rdparty/textedit_p.h index b2bd8bfa..9b419a7f 100644 --- a/lib/lveditor/3rdparty/textedit_p.h +++ b/lib/lveditor/3rdparty/textedit_p.h @@ -110,8 +110,8 @@ class TextEdit : public QQuickImplicitSizeItem Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6) Q_PROPERTY(QString preeditText READ preeditText NOTIFY preeditTextChanged REVISION 7) Q_PROPERTY(lv::DocumentHandler* documentHandler READ documentHandler WRITE setDocumentHandler NOTIFY documentHandlerChanged) - Q_PROPERTY(int fragmentStart WRITE setFragmentStart RESET resetFragmentStart NOTIFY fragmentStartChanged) - Q_PROPERTY(int fragmentEnd WRITE setFragmentEnd RESET resetFragmentEnd NOTIFY fragmentEndChanged) + Q_PROPERTY(int fragmentStart READ fragmentStart WRITE setFragmentStart RESET resetFragmentStart NOTIFY fragmentStartChanged) + Q_PROPERTY(int fragmentEnd READ fragmentEnd WRITE setFragmentEnd RESET resetFragmentEnd NOTIFY fragmentEndChanged) Q_PROPERTY(int lineNumber READ lineNumber NOTIFY lineNumberChanged) Q_PROPERTY(int columnNumber READ columnNumber NOTIFY columnNumberChanged) Q_PROPERTY(QRect viewport READ viewport WRITE setViewport NOTIFY viewportChanged) diff --git a/lib/lveditor/src/projectdocument.cpp b/lib/lveditor/src/projectdocument.cpp index 819f4ead..9fec0d6a 100644 --- a/lib/lveditor/src/projectdocument.cpp +++ b/lib/lveditor/src/projectdocument.cpp @@ -124,7 +124,7 @@ ProjectDocument::SectionConstIterator ProjectDocument::sectionsEnd() const{ * \brief Number of sections */ int ProjectDocument::totalSections() const{ - return d_ptr->sections.size(); + return static_cast(d_ptr->sections.size()); } diff --git a/lib/lveditor/src/startupmodel.cpp b/lib/lveditor/src/startupmodel.cpp index f0d8f8d6..3f22eb86 100644 --- a/lib/lveditor/src/startupmodel.cpp +++ b/lib/lveditor/src/startupmodel.cpp @@ -38,7 +38,7 @@ QVariant StartupModel::data(const QModelIndex &index, int role) const int StartupModel::rowCount(const QModelIndex &) const { - return m_entries.size(); + return static_cast(m_entries.size()); } QHash StartupModel::roleNames() const @@ -48,7 +48,7 @@ QHash StartupModel::roleNames() const void StartupModel::addStartupEntry(StartupModel::StartupEntry e) { - beginInsertRows(QModelIndex(), m_entries.size(), m_entries.size()); + beginInsertRows(QModelIndex(), static_cast(m_entries.size()), static_cast(m_entries.size())); m_entries.push_back(e); if (e.m_isGroupTitle) ++m_numberOfTitles; endInsertRows(); @@ -72,13 +72,14 @@ void StartupModel::addEntryAt(StartupEntry e, int i) lv::StartupModel::StartupEntry lv::StartupModel::entryAt(int i) { - if (i < 0 || i>= m_entries.size()) return StartupEntry(false, "", "", ""); + if (i < 0 || i >= static_cast(m_entries.size()) ) + return StartupEntry(false, "", "", ""); return m_entries[i]; } void lv::StartupModel::clear() { - beginRemoveRows(QModelIndex(), 0, m_entries.size() - 1); + beginRemoveRows(QModelIndex(), 0, static_cast(m_entries.size() - 1)); m_entries.clear(); m_numberOfTitles = 0; endRemoveRows(); diff --git a/lib/lveditor/src/textdocumentdata.cpp b/lib/lveditor/src/textdocumentdata.cpp index 54ae6067..e554916f 100644 --- a/lib/lveditor/src/textdocumentdata.cpp +++ b/lib/lveditor/src/textdocumentdata.cpp @@ -14,8 +14,8 @@ std::vector> TextDocumentData::contentsChange(QTex { // assumption: we will always have blocks containing "position" and "removed" blocks - unsigned i = 0; - unsigned total = 0; + size_t i = 0; + size_t total = 0; std::pair start, old_end, new_end; diff --git a/lib/lveditor/src/textdocumentdata.h b/lib/lveditor/src/textdocumentdata.h index c5e4490e..ecce75c8 100644 --- a/lib/lveditor/src/textdocumentdata.h +++ b/lib/lveditor/src/textdocumentdata.h @@ -18,7 +18,7 @@ class LV_EDITOR_EXPORT TextDocumentData std::vector> contentsChange(QTextDocument* document, int position, int removed, int added); void clear(); std::u16string &rowAt(unsigned i); - unsigned size() { return rows.size(); } + unsigned int size() { return static_cast(rows.size()); } private: std::vector rows; diff --git a/lib/lveditqmljs/src/codeqmlhandler.cpp b/lib/lveditqmljs/src/codeqmlhandler.cpp index 950a0e3b..dceb14b4 100644 --- a/lib/lveditqmljs/src/codeqmlhandler.cpp +++ b/lib/lveditqmljs/src/codeqmlhandler.cpp @@ -1294,8 +1294,6 @@ void CodeQmlHandler::addItemToRunTimeImpl(QmlEditFragment *edit, const QString & QmlBindingChannel::Ptr bc = edit->channel(); if ( bc->canModify() ){ - QQmlProperty& p = bc->property(); - QString creationPath = m_document->file()->path(); creationPath.replace(".qml", "_a.qml"); @@ -3099,7 +3097,7 @@ int CodeQmlHandler::addProperty( int CodeQmlHandler::addEvent( int position, const QString &object, - const QString &type, + const QString &, const QString &name) { DocumentQmlValueScanner qvs(m_document, position, 1); @@ -3340,7 +3338,7 @@ void CodeQmlHandler::addItemToRuntime(QmlEditFragment *edit, const QString &ctyp } } -QmlEditFragment *CodeQmlHandler::createObject(int position, const QString &type, QmlEditFragment *parent, QObject *currentApp) +QmlEditFragment *CodeQmlHandler::createObject(int position, const QString &type, QmlEditFragment *parent, QObject *) { try{ int opos = addItem(position, "", type); diff --git a/plugins/base/baseqml/src/qmlstreamsink.h b/plugins/base/baseqml/src/qmlstreamsink.h index f38d2797..1931b88a 100644 --- a/plugins/base/baseqml/src/qmlstreamsink.h +++ b/plugins/base/baseqml/src/qmlstreamsink.h @@ -11,6 +11,7 @@ class QmlStream; class QmlStreamSink : public QObject, public QQmlParserStatus{ Q_OBJECT + Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(QJSValue input READ input WRITE setInput NOTIFY inputChanged) public: diff --git a/plugins/lcvimgproc/src/qcascadeclassifier.cpp b/plugins/lcvimgproc/src/qcascadeclassifier.cpp index e47952e7..0a08b3fc 100644 --- a/plugins/lcvimgproc/src/qcascadeclassifier.cpp +++ b/plugins/lcvimgproc/src/qcascadeclassifier.cpp @@ -47,7 +47,7 @@ QVariantList QCascadeClassifier::detectFaces(QMat *input, double scaleFactor, in } catch (cv::Exception& e){ lv::CvExtras::toLocalError(e, lv::ViewContext::instance().engine(), this, "CascadeClassifier: ").jsThrow(); } - + return result; } diff --git a/plugins/lcvimgproc/src/qgeometry.cpp b/plugins/lcvimgproc/src/qgeometry.cpp index e7891ee7..b9c69875 100644 --- a/plugins/lcvimgproc/src/qgeometry.cpp +++ b/plugins/lcvimgproc/src/qgeometry.cpp @@ -191,7 +191,7 @@ QMat *QGeometry::perspectiveProjection(QMat *input, QMat *background, QJSValue p } catch (cv::Exception& e){ lv::CvExtras::toLocalError(e, lv::ViewContext::instance().engine(), this, "Geometry: ").jsThrow(); } - + return nullptr; } QMat *QGeometry::warpPerspective(QMat *input, QMat *transform, QSize size, int flags, int borderMode) diff --git a/plugins/lcvimgproc/src/qtransformations.cpp b/plugins/lcvimgproc/src/qtransformations.cpp index d80a3fa7..7c9c92ce 100644 --- a/plugins/lcvimgproc/src/qtransformations.cpp +++ b/plugins/lcvimgproc/src/qtransformations.cpp @@ -9,8 +9,7 @@ QTransformations::QTransformations(QObject *parent) : QObject(parent) } -QMat* QTransformations::threshold(QMat* input, double thresh, double maxVal, int type) -{ +QMat* QTransformations::threshold(QMat* input, double thresh, double maxVal, int type){ if (!input) return nullptr; try { @@ -20,9 +19,10 @@ QMat* QTransformations::threshold(QMat* input, double thresh, double maxVal, int } catch (cv::Exception& e){ lv::CvExtras::toLocalError(e, lv::ViewContext::instance().engine(), this, "Transformations: ").jsThrow(); } + return nullptr; } -QMat *QTransformations::blend(QMat *src1, QMat *src2, QMat *mask) -{ + +QMat *QTransformations::blend(QMat *src1, QMat *src2, QMat *mask){ if (!src1 && src2) return src2; if (src1 && !src2) return src1; @@ -72,4 +72,5 @@ QMat *QTransformations::blend(QMat *src1, QMat *src2, QMat *mask) } catch (cv::Exception& e){ lv::CvExtras::toLocalError(e, lv::ViewContext::instance().engine(), this, "Transformations: ").jsThrow(); } + return nullptr; } diff --git a/plugins/timeline/src/segmentmodel.cpp b/plugins/timeline/src/segmentmodel.cpp index 6ff7bab3..cf7adc3b 100644 --- a/plugins/timeline/src/segmentmodel.cpp +++ b/plugins/timeline/src/segmentmodel.cpp @@ -225,7 +225,7 @@ QHash SegmentModel::roleNames() const{ bool SegmentModel::addSegment(Segment *segment){ if ( !segment ) - return -1; + return false; beginDataChange(segment->position(), segment->position() + 1); int index = insertItemImpl(segment); diff --git a/plugins/timeline/src/tracklistmodel.cpp b/plugins/timeline/src/tracklistmodel.cpp index 97b34171..59e7dfad 100644 --- a/plugins/timeline/src/tracklistmodel.cpp +++ b/plugins/timeline/src/tracklistmodel.cpp @@ -73,7 +73,7 @@ void TrackListModel::serialize(ViewEngine *engine, const QObject *o, MLNode &nod } } -QObject *TrackListModel::deserialize(ViewEngine *engine, const MLNode &node){ +QObject *TrackListModel::deserialize(ViewEngine *, const MLNode &){ return nullptr; } From 30344a81774e41cfd3dbfaaa3473c739d17e6299 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Thu, 1 Jul 2021 10:21:06 +0300 Subject: [PATCH 83/91] TextEdit: Fixed loose functions. --- lib/lveditor/3rdparty/textedit.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/lveditor/3rdparty/textedit.cpp b/lib/lveditor/3rdparty/textedit.cpp index 0de60dd9..fddba9e5 100644 --- a/lib/lveditor/3rdparty/textedit.cpp +++ b/lib/lveditor/3rdparty/textedit.cpp @@ -705,6 +705,10 @@ void TextEdit::resetFragmentStart() { setFragmentStart(0); } +int TextEdit::fragmentEnd() const{ + return 0; +} + void TextEdit::resetFragmentEnd() { setFragmentEnd(INT_MAX); } @@ -3990,6 +3994,10 @@ void TextEdit::resetBottomPadding() d->setBottomPadding(0, true); } +int TextEdit::fragmentStart() const{ + return 0; +} + /*! \qmlmethod QtQuick::TextEdit::clear() \since 5.7 From 81b82c5ccd113fb5a85680c033b933a495bb4595 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Thu, 1 Jul 2021 13:12:55 +0300 Subject: [PATCH 84/91] Palettes: Fixed editor calls when shaping the document. --- plugins/editqml/qml/ObjectContainer.qml | 2 +- plugins/editqml/qml/PaletteControls.qml | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/editqml/qml/ObjectContainer.qml b/plugins/editqml/qml/ObjectContainer.qml index b4e5cc7f..b017cb92 100644 --- a/plugins/editqml/qml/ObjectContainer.qml +++ b/plugins/editqml/qml/ObjectContainer.qml @@ -290,7 +290,7 @@ Item{ var p = root.parent if (editingFragment.position() === rootPosition) - editor.editor.rootShaped = false + editor.rootShaped = false if (!p) return if ( p.objectName === 'editorBox' ){ // if this is root for the editor box diff --git a/plugins/editqml/qml/PaletteControls.qml b/plugins/editqml/qml/PaletteControls.qml index 367d5fa9..278edf48 100644 --- a/plugins/editqml/qml/PaletteControls.qml +++ b/plugins/editqml/qml/PaletteControls.qml @@ -907,10 +907,9 @@ QtObject{ var rootDeleted = (objectContainer.editingFragment.position() === objectContainer.editor.documentHandler.codeHandler.findRootPosition()) objectContainer.editor.documentHandler.codeHandler.eraseObject(objectContainer.editingFragment, !objectContainer.isForProperty) - if (rootDeleted) { - objectContainer.editor.editor.rootShaped = false - objectContainer.editor.editor.addRootButton.visible = true + objectContainer.editor.rootShaped = false + objectContainer.editor.addRootButton.visible = true } if ( objectContainer.isForProperty ) { From 80d8379b010d39defa75b0977365ffac7ebbbcce Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Thu, 1 Jul 2021 13:13:29 +0300 Subject: [PATCH 85/91] Workspace.ProjectQmlScope: Removed parent from shared pointer type. --- lib/lveditqmljs/src/projectqmlscope.cpp | 2 +- lib/lveditqmljs/src/projectqmlscope.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/lveditqmljs/src/projectqmlscope.cpp b/lib/lveditqmljs/src/projectqmlscope.cpp index 942eb76e..8631c4e6 100644 --- a/lib/lveditqmljs/src/projectqmlscope.cpp +++ b/lib/lveditqmljs/src/projectqmlscope.cpp @@ -114,7 +114,7 @@ ProjectQmlScope::~ProjectQmlScope(){ /** * \brief Creates a new ProjectQmlScope object */ -ProjectQmlScope::Ptr ProjectQmlScope::create(LockedFileIOSession::Ptr ioSession, QQmlEngine *engine, QObject *parent){ +ProjectQmlScope::Ptr ProjectQmlScope::create(LockedFileIOSession::Ptr ioSession, QQmlEngine *engine){ return ProjectQmlScope::Ptr(new ProjectQmlScope(ioSession, engine)); } diff --git a/lib/lveditqmljs/src/projectqmlscope.h b/lib/lveditqmljs/src/projectqmlscope.h index 99235c41..c3471e08 100644 --- a/lib/lveditqmljs/src/projectqmlscope.h +++ b/lib/lveditqmljs/src/projectqmlscope.h @@ -54,7 +54,7 @@ class LV_EDITQMLJS_EXPORT ProjectQmlScope : public QObject{ public: ~ProjectQmlScope(); - static Ptr create(LockedFileIOSession::Ptr ioSession, QQmlEngine* engine, QObject* parent = nullptr); + static Ptr create(LockedFileIOSession::Ptr ioSession, QQmlEngine* engine); static QmlLibraryInfo::Ptr findQmlLibraryInImports( const QStringList& importPaths, From 61e241f0a4ab3e841c23dbe7bb2b928b065d5844 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Thu, 1 Jul 2021 17:05:07 +0300 Subject: [PATCH 86/91] lcvcore: Fixed imageView mat sharing. --- plugins/lcvcore/src/qimageview.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/lcvcore/src/qimageview.cpp b/plugins/lcvcore/src/qimageview.cpp index c19e47a4..6fdb0458 100644 --- a/plugins/lcvcore/src/qimageview.cpp +++ b/plugins/lcvcore/src/qimageview.cpp @@ -1,6 +1,7 @@ #include "qimageview.h" #include "qmatnode.h" #include "qmatshader.h" +#include "live/shared.h" #include QImageView::QImageView(QQuickItem *parent) @@ -38,7 +39,12 @@ void QImageView::setImage(QMat *arg){ setImplicitWidth(matData->cols); setImplicitHeight(matData->rows); } + + if ( m_mat ) + lv::Shared::unref(m_mat); + m_mat = arg; + lv::Shared::ref(arg); emit imageChanged(); update(); From 6c2624ba711dd9e4cc54a41d53b6d85488e6ee66 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Thu, 1 Jul 2021 17:05:21 +0300 Subject: [PATCH 87/91] base.Time: Added support for async delay --- lib/lvview/include/live/qmlstreamprovider.h | 1 + lib/lvview/src/qmlstreamprovider.h | 19 +++ plugins/base/baseqml/src/qmlstreamact.cpp | 123 ++++++++++++++++++ plugins/base/baseqml/src/qmlstreamact.h | 79 +++++++++++ .../base/baseqml/src/qmlstreamoperator.cpp | 102 +++++++++++++++ plugins/base/baseqml/src/qmlstreamoperator.h | 67 ++++++++++ plugins/base/baseqml/src/qmltime.cpp | 7 + plugins/base/baseqml/src/qmltime.h | 2 + 8 files changed, 400 insertions(+) create mode 100644 lib/lvview/include/live/qmlstreamprovider.h create mode 100644 lib/lvview/src/qmlstreamprovider.h create mode 100644 plugins/base/baseqml/src/qmlstreamact.cpp create mode 100644 plugins/base/baseqml/src/qmlstreamact.h create mode 100644 plugins/base/baseqml/src/qmlstreamoperator.cpp create mode 100644 plugins/base/baseqml/src/qmlstreamoperator.h diff --git a/lib/lvview/include/live/qmlstreamprovider.h b/lib/lvview/include/live/qmlstreamprovider.h new file mode 100644 index 00000000..721f7fa8 --- /dev/null +++ b/lib/lvview/include/live/qmlstreamprovider.h @@ -0,0 +1 @@ +#include "../../src/qmlstreamprovider.h" diff --git a/lib/lvview/src/qmlstreamprovider.h b/lib/lvview/src/qmlstreamprovider.h new file mode 100644 index 00000000..145110c8 --- /dev/null +++ b/lib/lvview/src/qmlstreamprovider.h @@ -0,0 +1,19 @@ +#ifndef LVQMLSTREAMPROVIDER_H +#define LVQMLSTREAMPROVIDER_H + +#include "live/lvviewglobal.h" + +namespace lv{ + +class LV_VIEW_EXPORT QmlStreamProvider{ + +public: + virtual void wait() = 0; + virtual void resume() = 0; +}; + + +}// namespace + + +#endif // LVQMLSTREAMPROVIDER_H diff --git a/plugins/base/baseqml/src/qmlstreamact.cpp b/plugins/base/baseqml/src/qmlstreamact.cpp new file mode 100644 index 00000000..0546141a --- /dev/null +++ b/plugins/base/baseqml/src/qmlstreamact.cpp @@ -0,0 +1,123 @@ +#include "qmlstreamact.h" + +namespace lv{ + +QmlStreamAct::QmlStreamAct(QObject *parent) + : QObject(parent) + , m_input(nullptr) + , m_output(nullptr) + , m_act(nullptr) + , m_isRunning(false) +{ +} + +QmlStreamAct::~QmlStreamAct(){ + delete m_output; +} + +void QmlStreamAct::onStreamValue(const QJSValue &val){ + if ( m_isRunning ){ + return; + } + + if ( !m_act || !m_propertyMeta.isValid() ) + return; + + m_propertyMeta.write(m_act, val.toVariant()); + m_act->exec(); + m_isRunning = true; + + if ( m_input->provider() ) + m_input->provider()->wait(); +} + +void QmlStreamAct::setInput(QmlStream *stream){ + if (m_input == stream) + return; + + if ( m_input ){ + m_input->unsubscribeObject(this); + delete m_output; + m_output = nullptr; + } + + m_input = stream; + if ( m_input ){ + m_input->forward(this, &QmlStreamAct::streamHandler); + m_output = new QmlStream(this, this); + } + + emit inputChanged(); + emit outChanged(); +} + +void QmlStreamAct::streamHandler(QObject *that, const QJSValue &val){ + QmlStreamAct* streamAct = static_cast(that); + streamAct->onStreamValue(val); +} + +void QmlStreamAct::__actResultReady(){ + m_isRunning = false; + if ( m_input->provider() ) + m_input->provider()->resume(); +} + +void QmlStreamAct::initMetaProperty(){ + if ( m_actProperty.isEmpty() ) + return; + + const QMetaObject* meta = m_act->metaObject(); + + for ( int i = 0; i < meta->propertyCount(); i++ ){ + QMetaProperty property = meta->property(i); + if ( property.name() == m_actProperty ){ + m_propertyMeta = property; + return; + } + } +} + +void QmlStreamAct::wait(){ + if ( m_input && m_input->provider() ){ + m_input->provider()->wait(); + } +} + +void QmlStreamAct::resume(){ + if ( m_input && m_input->provider() ){ + m_input->provider()->resume(); + } +} + +void QmlStreamAct::setAct(lv::QmlAct *act){ + if (m_act == act) + return; + + if ( m_act ){ + disconnect(m_act, &QmlAct::resultChanged, this, &QmlStreamAct::__actResultReady); + } + + m_act = act; + if ( m_act ){ + connect(m_act, &QmlAct::resultChanged, this, &QmlStreamAct::__actResultReady); + m_act->setTrigger(QmlAct::Manual); + initMetaProperty(); + } + + m_act = act; + emit actChanged(); +} + +void QmlStreamAct::setActProperty(const QString &argument){ + if (m_actProperty == argument) + return; + + m_actProperty = argument; + if ( m_act ) + initMetaProperty(); + + emit actPropertyChanged(); +} + + +}// namespace diff --git a/plugins/base/baseqml/src/qmlstreamact.h b/plugins/base/baseqml/src/qmlstreamact.h new file mode 100644 index 00000000..fabb368c --- /dev/null +++ b/plugins/base/baseqml/src/qmlstreamact.h @@ -0,0 +1,79 @@ +#ifndef LVQMLSTREAMACT_H +#define LVQMLSTREAMACT_H + +#include +#include "live/qmlact.h" +#include "live/qmlstream.h" +#include "live/qmlstreamprovider.h" + +namespace lv{ + +class QmlStreamAct : public QObject, public QmlStreamProvider{ + + Q_OBJECT + Q_PROPERTY(lv::QmlStream* input READ input WRITE setInput NOTIFY inputChanged) + Q_PROPERTY(lv::QmlAct* act READ act WRITE setAct NOTIFY actChanged) + Q_PROPERTY(QString actProperty READ actProperty WRITE setActProperty NOTIFY actPropertyChanged) + Q_PROPERTY(lv::QmlStream* output READ output NOTIFY outChanged) + +public: + explicit QmlStreamAct(QObject *parent = nullptr); + virtual ~QmlStreamAct(); + + lv::QmlStream* input() const; + void setInput(lv::QmlStream* stream); + + lv::QmlStream* output() const; + + // QmlStreamProvider interface + void wait() override; + void resume() override; + + lv::QmlAct* act() const; + void setAct(lv::QmlAct* act); + + const QString &actProperty() const; + void setActProperty(const QString& argument); + + static void streamHandler(QObject* that, const QJSValue& val); + +public slots: + void __actResultReady(); + +signals: + void inputChanged(); + void outChanged(); + void actChanged(); + void actPropertyChanged(); + +private: + void initMetaProperty(); + void onStreamValue(const QJSValue& val); + + lv::QmlStream* m_input; + lv::QmlStream* m_output; + lv::QmlAct* m_act; + QString m_actProperty; + QMetaProperty m_propertyMeta; + bool m_isRunning; +}; + +inline QmlStream *QmlStreamAct::input() const{ + return m_input; +} + +inline QmlStream *QmlStreamAct::output() const{ + return m_output; +} + +inline QmlAct *QmlStreamAct::act() const{ + return m_act; +} + +inline const QString& QmlStreamAct::actProperty() const{ + return m_actProperty; +} + +}// namespace + +#endif // LVQMLSTREAMACT_H diff --git a/plugins/base/baseqml/src/qmlstreamoperator.cpp b/plugins/base/baseqml/src/qmlstreamoperator.cpp new file mode 100644 index 00000000..c303af7d --- /dev/null +++ b/plugins/base/baseqml/src/qmlstreamoperator.cpp @@ -0,0 +1,102 @@ +#include "qmlstreamoperator.h" +#include "live/viewengine.h" +#include "live/qmlstreamprovider.h" + +namespace lv{ + +QmlStreamOperator::QmlStreamOperator(QObject *parent) + : QObject(parent) + , m_input(nullptr) + , m_output(nullptr) + , m_isRunning(false) + , m_wait(0) +{ +} + +QmlStreamOperator::~QmlStreamOperator(){ + delete m_output; +} + +void QmlStreamOperator::streamHandler(QObject *that, const QJSValue &val){ + QmlStreamOperator* streamOperator = static_cast(that); + streamOperator->onStreamValue(val); +} + +void QmlStreamOperator::onStreamValue(const QJSValue &val){ + if ( m_isRunning ){ + return; + } + + if ( m_next.isCallable() ){ + QJSValue res = m_next.call(QJSValueList() << val); + if ( res.isError() ){ + ViewEngine* ve = ViewEngine::grab(this); + if ( ve ){ + ve->throwError(res, this); + return; + } + } else if ( res.isString() && res.toString() == "async" ){ + m_isRunning = true; + + if ( m_input->provider() ) + m_input->provider()->wait(); + } + } +} + +void QmlStreamOperator::wait(){ + ++m_wait; + if ( m_input && m_input->provider() ){ + m_input->provider()->wait(); + } +} + +void QmlStreamOperator::resume(){ + if ( m_wait > 0 ){ + --m_wait; + } + if ( m_wait == 0 ){ + if ( m_input && m_input->provider() ){ + m_input->provider()->resume(); + } + } +} + +void QmlStreamOperator::writeNext(QJSValue val){ + if ( m_output ){ + m_output->push(val); + } +} + +void QmlStreamOperator::ready(){ + m_isRunning = false; + if ( m_input->provider() ) + m_input->provider()->resume(); +} + +void QmlStreamOperator::setInput(QmlStream *stream){ + if (m_input == stream) + return; + + if ( m_input ){ + m_input->unsubscribeObject(this); + delete m_output; + m_output = nullptr; + } + + m_input = stream; + if ( m_input ){ + m_input->forward(this, &QmlStreamOperator::streamHandler); + m_output = new QmlStream(this, this); + } + + emit inputChanged(); + emit outChanged(); +} + +void QmlStreamOperator::setNext(QJSValue next){ + m_next = next; + emit nextChanged(); +} + +}// namespace diff --git a/plugins/base/baseqml/src/qmlstreamoperator.h b/plugins/base/baseqml/src/qmlstreamoperator.h new file mode 100644 index 00000000..b8bd135f --- /dev/null +++ b/plugins/base/baseqml/src/qmlstreamoperator.h @@ -0,0 +1,67 @@ +#ifndef LVQMLSTREAMOPERATOR_H +#define LVQMLSTREAMOPERATOR_H + +#include +#include "live/qmlstream.h" +#include "live/qmlstreamprovider.h" + +namespace lv{ + +class QmlStreamOperator : public QObject, public QmlStreamProvider{ + + Q_OBJECT + Q_PROPERTY(lv::QmlStream* input READ input WRITE setInput NOTIFY inputChanged) + Q_PROPERTY(lv::QmlStream* output READ output NOTIFY outChanged) + Q_PROPERTY(QJSValue next READ next WRITE setNext NOTIFY nextChanged) + +public: + explicit QmlStreamOperator(QObject *parent = nullptr); + virtual ~QmlStreamOperator(); + + lv::QmlStream* input() const; + void setInput(lv::QmlStream* stream); + + lv::QmlStream* output() const; + + QJSValue next() const; + void setNext(QJSValue next); + + static void streamHandler(QObject* that, const QJSValue& val); + void onStreamValue(const QJSValue& val); + + // QmlStreamProvider interface + void wait() override; + void resume() override; + +public slots: + void writeNext(QJSValue val); + void ready(); + +signals: + void inputChanged(); + void outChanged(); + void nextChanged(); + +private: + lv::QmlStream* m_input; + lv::QmlStream* m_output; + QJSValue m_next; + bool m_isRunning; + int m_wait; +}; + +inline QmlStream *QmlStreamOperator::input() const{ + return m_input; +} + +inline QmlStream *QmlStreamOperator::output() const{ + return m_output; +} + +inline QJSValue QmlStreamOperator::next() const{ + return m_next; +} + +}// namespace + +#endif // LVQMLSTREAMOPERATOR_H diff --git a/plugins/base/baseqml/src/qmltime.cpp b/plugins/base/baseqml/src/qmltime.cpp index d8649ee5..1309d78d 100644 --- a/plugins/base/baseqml/src/qmltime.cpp +++ b/plugins/base/baseqml/src/qmltime.cpp @@ -1,5 +1,6 @@ #include "qmltime.h" +#include #include namespace lv{ @@ -24,4 +25,10 @@ void QmlTime::usleep(int useconds){ return QThread::usleep(useconds); } +void QmlTime::delay(int mseconds, QJSValue callback){ + QTimer::singleShot(mseconds, [callback]() mutable{ + callback.call(); + }); +} + } // namespace diff --git a/plugins/base/baseqml/src/qmltime.h b/plugins/base/baseqml/src/qmltime.h index 6e3b0f70..1fd81be5 100644 --- a/plugins/base/baseqml/src/qmltime.h +++ b/plugins/base/baseqml/src/qmltime.h @@ -2,6 +2,7 @@ #define LVQMLTIME_H #include +#include namespace lv{ @@ -17,6 +18,7 @@ public slots: void sleep(int seconds); void msleep(int mseconds); void usleep(int useconds); + void delay(int mseconds, QJSValue callback); }; }// namespace From 1363cdd3488f156ff3d7eaa8645ec4f1d84ad974 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Thu, 1 Jul 2021 17:06:06 +0300 Subject: [PATCH 88/91] base: Added support for Stream operators and Stream Act Operators. Modified stream to support stream provider. Added QmlStreamOperator. Added QmlStreamActOperator. --- lib/lvview/include/lvviewheaders.pri | 1 + lib/lvview/src/lvview.pri | 1 + lib/lvview/src/qmlstream.cpp | 15 +++++++++++++ lib/lvview/src/qmlstream.h | 9 ++++++-- plugins/base/baseqml/src/base_plugin.cpp | 4 ++++ plugins/base/baseqml/src/baseqml.pri | 4 ++++ plugins/base/baseqml/src/qmlact.h | 7 +++++- plugins/base/baseqml/src/qmlstreamvalue.cpp | 13 ++++++++--- plugins/base/baseqml/src/qmlstreamvalue.h | 3 ++- plugins/fs/fsqml/src/qmlfilestream.cpp | 25 ++++++++++++--------- plugins/fs/fsqml/src/qmlfilestream.h | 12 +++++++--- plugins/lcvcore/qml/VideoDecoderView.qml | 1 + plugins/lcvcore/qml/VideoFile.qml | 1 + 13 files changed, 76 insertions(+), 20 deletions(-) diff --git a/lib/lvview/include/lvviewheaders.pri b/lib/lvview/include/lvviewheaders.pri index 42ff2845..9262b47f 100644 --- a/lib/lvview/include/lvviewheaders.pri +++ b/lib/lvview/include/lvviewheaders.pri @@ -7,6 +7,7 @@ HEADERS += \ $$PWD/live/metainfo.h \ $$PWD/live/qmlbuild.h \ $$PWD/live/qmlerror.h \ + $$PWD/live/qmlstreamprovider.h \ $$PWD/live/qmlwritablestream.h \ $$PWD/live/settings.h \ $$PWD/live/visuallogbasemodel.h \ diff --git a/lib/lvview/src/lvview.pri b/lib/lvview/src/lvview.pri index a32f563a..f3aeb3d3 100644 --- a/lib/lvview/src/lvview.pri +++ b/lib/lvview/src/lvview.pri @@ -7,6 +7,7 @@ HEADERS += \ $$PWD/metainfo.h \ $$PWD/qmlbuild.h \ $$PWD/qmlerror.h \ + $$PWD/qmlstreamprovider.h \ $$PWD/qmlwritablestream.h \ $$PWD/settings.h \ $$PWD/visuallogbasemodel.h \ diff --git a/lib/lvview/src/qmlstream.cpp b/lib/lvview/src/qmlstream.cpp index f73b3fc4..7273afce 100644 --- a/lib/lvview/src/qmlstream.cpp +++ b/lib/lvview/src/qmlstream.cpp @@ -71,6 +71,17 @@ void QmlStream::PropertyObserver::push(ViewEngine*, QObject *object){ QmlStream::QmlStream(QObject *parent) : QObject(parent) + , m_provider(nullptr) + , m_idCounter(1) + , m_observers(new std::list()) +{ + //TODO: Capture engine from component complete + m_engine = lv::ViewContext::instance().engine(); +} + +QmlStream::QmlStream(QmlStreamProvider *provider, QObject *parent) + : QObject(parent) + , m_provider(provider) , m_idCounter(1) , m_observers(new std::list()) { @@ -130,6 +141,10 @@ void QmlStream::unsubscribe(QmlStream::Observer *observer){ } } +QmlStreamProvider *QmlStream::provider(){ + return m_provider; +} + QJSValue QmlStream::forward(const QJSValue &callback){ if ( callback.isCallable() ){ m_observers->push_back(new QmlStream::JsCallbackObserver(m_idCounter, callback)); diff --git a/lib/lvview/src/qmlstream.h b/lib/lvview/src/qmlstream.h index dbb61bf8..9a8bf2d3 100644 --- a/lib/lvview/src/qmlstream.h +++ b/lib/lvview/src/qmlstream.h @@ -10,6 +10,7 @@ namespace lv{ class ViewEngine; +class QmlStreamProvider; class LV_VIEW_EXPORT QmlStream : public QObject{ Q_OBJECT @@ -77,6 +78,7 @@ class LV_VIEW_EXPORT QmlStream : public QObject{ public: explicit QmlStream(QObject *parent = nullptr); + QmlStream(QmlStreamProvider* provider, QObject* parent); ~QmlStream(); void push(QObject* object); @@ -86,6 +88,8 @@ class LV_VIEW_EXPORT QmlStream : public QObject{ void unsubscribeObject(QObject* object); void unsubscribe(Observer* observer); + QmlStreamProvider* provider(); + public slots: QJSValue forward(const QJSValue& callback); bool unsubscribe(const QJSValue& val); @@ -94,8 +98,9 @@ public slots: void incrementIdCounter(); void clearObservers(); - ViewEngine* m_engine; - unsigned int m_idCounter; + QmlStreamProvider* m_provider; + ViewEngine* m_engine; + unsigned int m_idCounter; std::list* m_observers; }; diff --git a/plugins/base/baseqml/src/base_plugin.cpp b/plugins/base/baseqml/src/base_plugin.cpp index 0427d103..87111e6e 100644 --- a/plugins/base/baseqml/src/base_plugin.cpp +++ b/plugins/base/baseqml/src/base_plugin.cpp @@ -33,8 +33,10 @@ #include "groupcollector.h" #include "qmlstreamfilter.h" #include "qmlstreamvalue.h" +#include "qmlstreamact.h" #include "qmlthreadinfo.h" #include "qmltime.h" +#include "qmlstreamoperator.h" #include #include @@ -80,6 +82,8 @@ void BasePlugin::registerTypes(const char *uri){ qmlRegisterType( uri, 1, 0, "StreamFilter"); qmlRegisterType( uri, 1, 0, "StreamSink"); qmlRegisterType( uri, 1, 0, "StreamValue"); + qmlRegisterType( uri, 1, 0, "StreamAct"); + qmlRegisterType( uri, 1, 0, "StreamOperator"); qmlRegisterSingletonType( uri, 1, 0, "Script", &scriptProvider); qmlRegisterSingletonType( uri, 1, 0, "WorkerPool", &workerPoolProvider); diff --git a/plugins/base/baseqml/src/baseqml.pri b/plugins/base/baseqml/src/baseqml.pri index 75efbd00..1b701a32 100644 --- a/plugins/base/baseqml/src/baseqml.pri +++ b/plugins/base/baseqml/src/baseqml.pri @@ -8,6 +8,8 @@ HEADERS += \ $$PWD/qmlindexselector.h \ $$PWD/qmlpropertylog.h \ $$PWD/qmlscript.h \ + $$PWD/qmlstreamact.h \ + $$PWD/qmlstreamoperator.h \ $$PWD/qmlstreamsink.h \ $$PWD/qmlstreamvalue.h \ $$PWD/qmlthreadinfo.h \ @@ -32,6 +34,8 @@ SOURCES += \ $$PWD/qmlindexselector.cpp \ $$PWD/qmlpropertylog.cpp \ $$PWD/qmlscript.cpp \ + $$PWD/qmlstreamact.cpp \ + $$PWD/qmlstreamoperator.cpp \ $$PWD/qmlstreamvalue.cpp \ $$PWD/qmlstreamsink.cpp \ $$PWD/qmlthreadinfo.cpp \ diff --git a/plugins/base/baseqml/src/qmlact.h b/plugins/base/baseqml/src/qmlact.h index 9eb0be88..dd640f67 100644 --- a/plugins/base/baseqml/src/qmlact.h +++ b/plugins/base/baseqml/src/qmlact.h @@ -70,6 +70,8 @@ class LV_BASEQML_EXPORT QmlAct : public QObject, public QQmlParserStatus{ Trigger trigger() const; void setTrigger(Trigger trigger); + bool isRunning() const; + public slots: void exec(); @@ -84,7 +86,6 @@ public slots: void returnsChanged(); void triggerChanged(); - protected: void classBegin() override{} virtual void componentComplete() override; @@ -143,6 +144,10 @@ inline void QmlAct::setTrigger(QmlAct::Trigger trigger){ emit triggerChanged(); } +inline bool QmlAct::isRunning() const{ + return m_currentTask; +} + } // namespace #endif // LVQMLACT_H diff --git a/plugins/base/baseqml/src/qmlstreamvalue.cpp b/plugins/base/baseqml/src/qmlstreamvalue.cpp index d58a8a70..68239f84 100644 --- a/plugins/base/baseqml/src/qmlstreamvalue.cpp +++ b/plugins/base/baseqml/src/qmlstreamvalue.cpp @@ -58,6 +58,10 @@ void QmlStreamValue::setValueType(const QString &valueType){ emit valueTypeChanged(m_valueType); } +void QmlStreamValue::__streamRemoved(){ + m_stream = nullptr; +} + void QmlStreamValue::updateFollowsObject(){ QmlStreamFilter* filter = qobject_cast(m_follow); if ( filter ){ @@ -80,7 +84,7 @@ void QmlStreamValue::removeFollowsObject(){ m_follow = nullptr; } -void lv::QmlStreamValue::setStream(QmlStream *stream){ +void QmlStreamValue::setStream(QmlStream *stream){ if (m_stream == stream) return; @@ -88,11 +92,14 @@ void lv::QmlStreamValue::setStream(QmlStream *stream){ removeFollowsObject(); } - if( m_stream ) - m_stream->forward(nullptr, nullptr); + if( m_stream ){ + m_stream->unsubscribeObject(this); + disconnect(m_stream, &QObject::destroyed, this, &QmlStreamValue::__streamRemoved); + } m_stream = stream; m_stream->forward(this, &QmlStreamValue::streamHandler); + connect(m_stream, &QObject::destroyed, this, &QmlStreamValue::__streamRemoved); emit streamChanged(); } diff --git a/plugins/base/baseqml/src/qmlstreamvalue.h b/plugins/base/baseqml/src/qmlstreamvalue.h index 76a52075..8ab601af 100644 --- a/plugins/base/baseqml/src/qmlstreamvalue.h +++ b/plugins/base/baseqml/src/qmlstreamvalue.h @@ -29,9 +29,10 @@ class QmlStreamValue : public QObject, public QQmlParserStatus{ void componentComplete(); const QString& valueType() const; + void setValueType(const QString& valueType); public slots: - void setValueType(const QString& valueType); + void __streamRemoved(); signals: void streamChanged(); diff --git a/plugins/fs/fsqml/src/qmlfilestream.cpp b/plugins/fs/fsqml/src/qmlfilestream.cpp index 93c4f519..249c0c3f 100644 --- a/plugins/fs/fsqml/src/qmlfilestream.cpp +++ b/plugins/fs/fsqml/src/qmlfilestream.cpp @@ -11,24 +11,29 @@ namespace lv{ QmlFileStream::QmlFileStream(QObject *parent) : QObject(parent) , m_stream(nullptr) - , m_synced(false) + , m_wait(0) { } QmlFileStream::~QmlFileStream(){ } -void QmlFileStream::next(){ - if ( !m_synced ){ - while ( !m_text.atEnd() ) - m_stream->push(m_text.readLine()); - } else { - if ( !m_text.atEnd() ){ - m_stream->push(m_text.readLine()); - } +void QmlFileStream::wait(){ + ++m_wait; +} + +void QmlFileStream::resume(){ + if ( m_wait > 0 ){ + --m_wait; + next(); } } +void QmlFileStream::next(){ + while ( !m_text.atEnd() && !m_wait ) + m_stream->push(m_text.readLine()); +} + QmlStream *QmlFileStream::lines(const QString &file){ if ( m_stream ){ if ( m_filePath == file ) @@ -53,7 +58,7 @@ QmlStream *QmlFileStream::lines(const QString &file){ m_text.setDevice(&m_file); m_filePath = file; - m_stream = new QmlStream(this); + m_stream = new QmlStream(this, this); QTimer::singleShot(0, this, &QmlFileStream::next); diff --git a/plugins/fs/fsqml/src/qmlfilestream.h b/plugins/fs/fsqml/src/qmlfilestream.h index 765b9771..80ddb529 100644 --- a/plugins/fs/fsqml/src/qmlfilestream.h +++ b/plugins/fs/fsqml/src/qmlfilestream.h @@ -6,10 +6,11 @@ #include #include "live/qmlstream.h" +#include "live/qmlstreamprovider.h" namespace lv{ -class QmlFileStream : public QObject{ +class QmlFileStream : public QObject, public QmlStreamProvider{ Q_OBJECT @@ -17,6 +18,10 @@ class QmlFileStream : public QObject{ explicit QmlFileStream(QObject *parent = nullptr); ~QmlFileStream(); + // QmlStreamProvider interface + void wait() override; + void resume() override; + signals: public slots: @@ -29,11 +34,12 @@ public slots: QFile m_file; QTextStream m_text; QString m_filePath; - bool m_synced; + int m_wait; + }; inline QmlFileStream *QmlFileStream::synced(){ - m_synced = true; + m_wait = true; return this; } diff --git a/plugins/lcvcore/qml/VideoDecoderView.qml b/plugins/lcvcore/qml/VideoDecoderView.qml index bf17cbd0..d9b28891 100644 --- a/plugins/lcvcore/qml/VideoDecoderView.qml +++ b/plugins/lcvcore/qml/VideoDecoderView.qml @@ -14,6 +14,7 @@ ImageView{ property alias paused: decoder.paused property alias currentFrame: decoder.currentFrame property alias totalFrames: decoder.totalFrames + property alias stream: decoder.stream function seekTo(value){ decoder.seekTo(value) diff --git a/plugins/lcvcore/qml/VideoFile.qml b/plugins/lcvcore/qml/VideoFile.qml index 79b47fa6..84fa8d6d 100644 --- a/plugins/lcvcore/qml/VideoFile.qml +++ b/plugins/lcvcore/qml/VideoFile.qml @@ -14,6 +14,7 @@ ImageView{ property alias paused: decoder.paused property alias currentFrame: decoder.currentFrame property alias totalFrames: decoder.totalFrames + property alias stream: decoder.stream function seekTo(value){ decoder.seekTo(value) From 7984b1a8fb92c7f8b9c0bdeaeceb9fc923918d20 Mon Sep 17 00:00:00 2001 From: nenad-popovic-91 <42581059+nenad-popovic-91@users.noreply.github.com> Date: Thu, 1 Jul 2021 19:06:13 +0200 Subject: [PATCH 89/91] Minor bugs related to samples (#227) Some fixes on Palette controls --- application/qml/ProjectEnvironment.qml | 8 ++--- lib/lveditqmljs/src/codeqmlhandler.cpp | 2 ++ ...gExecutablesAdjustmentsRemoveHighlight.qml | 1 + .../resources/ShapeLinkingExecutablesWin.qml | 1 + .../resources/ShapeWinSwitch.qml | 1 + plugins/editqml/qml/ObjectContainer.qml | 11 +++++-- plugins/editqml/qml/PaletteControls.qml | 29 +++++++++---------- .../resources/FileExplorerRemoveHighlight.qml | 1 + .../resources/ShapeFileExplorer.qml | 1 + .../resources/ReadingFilesRemoveHighlight.qml | 1 + .../resources/ShapeReadingFiles.qml | 1 + .../ColorAdjustmentsRemoveHighlight.qml | 1 + .../resources/ShapeColorAdjustments.qml | 1 + .../resources/DrawingRemoveHighlight.qml | 1 + .../drawing/resources/ShapeDrawing.qml | 1 + .../resources/AddDifferentImage.qml | 1 + .../ImageTransformationsRemoveHighlight.qml | 1 + .../resources/ShapeImageTransformations.qml | 1 + .../resources/MultiImageRemoveHighlight.qml | 1 + .../multiimage/resources/ShapeMultiImage.qml | 1 + .../resources/ShapeVideoColorAdjustments.qml | 1 + .../VideoColorAdjustmentsRemoveHighlight.qml | 1 + .../resources/ShapeVideoTimeline.qml | 1 + .../VideoTimelineRemoveHighlight.qml | 1 + plugins/workspace/qml/DocumentationView.qml | 2 +- 25 files changed, 49 insertions(+), 23 deletions(-) diff --git a/application/qml/ProjectEnvironment.qml b/application/qml/ProjectEnvironment.qml index f9064704..a2db1d6a 100644 --- a/application/qml/ProjectEnvironment.qml +++ b/application/qml/ProjectEnvironment.qml @@ -429,13 +429,13 @@ Item{ button1Function : function(mbox){ doc.save() project.closeFile(path) - callback() + if (callback) callback() mbox.close() }, button2Name : 'No', button2Function : function(mbox){ project.closeFile(path) - callback() + if (callback) callback() mbox.close() }, button3Name : 'Cancel', @@ -445,13 +445,13 @@ Item{ returnPressed : function(mbox){ doc.save() project.closeFile(path) - callback() + if (callback) callback() mbox.close() } }) } else { project.closeFile(path) - callback() + if (callback) callback() } } } diff --git a/lib/lveditqmljs/src/codeqmlhandler.cpp b/lib/lveditqmljs/src/codeqmlhandler.cpp index dceb14b4..dbeff9e5 100644 --- a/lib/lveditqmljs/src/codeqmlhandler.cpp +++ b/lib/lveditqmljs/src/codeqmlhandler.cpp @@ -2449,6 +2449,8 @@ QList CodeQmlHandler::openNestedProperties(QmlEditFragment *edit){ DocumentHandler* dh = static_cast(parent()); if ( dh ) dh->requestCursorPosition(ef->valuePosition()); + + child = ef; } else { child = createReadOnlyPropertyFragment(p, propName); } diff --git a/plugins/base/baseqml/samples/linkingexecutables/resources/LinkingExecutablesAdjustmentsRemoveHighlight.qml b/plugins/base/baseqml/samples/linkingexecutables/resources/LinkingExecutablesAdjustmentsRemoveHighlight.qml index 00ebe26a..5925fe5f 100644 --- a/plugins/base/baseqml/samples/linkingexecutables/resources/LinkingExecutablesAdjustmentsRemoveHighlight.qml +++ b/plugins/base/baseqml/samples/linkingexecutables/resources/LinkingExecutablesAdjustmentsRemoveHighlight.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ diff --git a/plugins/base/baseqml/samples/linkingexecutables/resources/ShapeLinkingExecutablesWin.qml b/plugins/base/baseqml/samples/linkingexecutables/resources/ShapeLinkingExecutablesWin.qml index eb62f83d..f39d8ea1 100644 --- a/plugins/base/baseqml/samples/linkingexecutables/resources/ShapeLinkingExecutablesWin.qml +++ b/plugins/base/baseqml/samples/linkingexecutables/resources/ShapeLinkingExecutablesWin.qml @@ -2,6 +2,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 import base 1.0 as B +import workspace 1.0 WorkspaceControl{ run: function(workspace){ diff --git a/plugins/base/baseqml/samples/linkingexecutables/resources/ShapeWinSwitch.qml b/plugins/base/baseqml/samples/linkingexecutables/resources/ShapeWinSwitch.qml index 916abb42..c165631c 100644 --- a/plugins/base/baseqml/samples/linkingexecutables/resources/ShapeWinSwitch.qml +++ b/plugins/base/baseqml/samples/linkingexecutables/resources/ShapeWinSwitch.qml @@ -2,6 +2,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 import base 1.0 as B +import workspace 1.0 WorkspaceControl{ diff --git a/plugins/editqml/qml/ObjectContainer.qml b/plugins/editqml/qml/ObjectContainer.qml index b017cb92..233596ba 100644 --- a/plugins/editqml/qml/ObjectContainer.qml +++ b/plugins/editqml/qml/ObjectContainer.qml @@ -233,8 +233,15 @@ Item{ if (child.objectName !== "propertyContainer") continue if (child.title !== propName) continue - if (child.valueContainer.palettesOpened && child.valueContainer.palettesOpened.indexOf(propPalette) !== -1) break - paletteControls.openPaletteByName(propPalette, ef, child.valueContainer) + var pg = null + if (child.valueContainer.objectName === "objectContainer"){ + pg = child.valueContainer.paletteGroup + } else { + pg = child.valueContainer + } + + if (pg.palettesOpened && pg.palettesOpened.indexOf(propPalette) !== -1) break + paletteControls.openPaletteByName(propPalette, ef, pg) break } diff --git a/plugins/editqml/qml/PaletteControls.qml b/plugins/editqml/qml/PaletteControls.qml index 278edf48..0b3e3d95 100644 --- a/plugins/editqml/qml/PaletteControls.qml +++ b/plugins/editqml/qml/PaletteControls.qml @@ -565,22 +565,14 @@ QtObject{ true ) - } else if (isForNode && addBoxItem.activeIndex === 4 ){ - container.nodeParent.item.addSubobject( - container.nodeParent, - data, - container.nodeParent.item.id ? ObjectGraph.PortMode.InPort : ObjectGraph.PortMode.Node, - null) + ef = codeHandler.openNestedConnection( + container.editingFragment, ppos, project.appRoot() + ) if (ef) { container.editingFragment.signalPropertyAdded(ef) - if (!isForNode && container.compact) container.sortChildren() } - if (!ef) { - lk.layers.workspace.messages.pushError("Error: Can't create a palette in a non-compiled program", 1) - - } } else if (isForNode && selection.category === 'function' ){ container.nodeParent.item.addSubobject(container.nodeParent, selection.name, container.nodeParent.item.id ? ObjectGraph.PortMode.InPort : ObjectGraph.PortMode.Node, null, {isMethod: true}) @@ -1253,14 +1245,19 @@ QtObject{ result['type'] = object.type() var paletteList = object.paletteList() var nameList = [] - for (var p = 0; p < paletteList.length; ++p) - nameList.push(paletteList[p].name) + for (var idx = 0; idx < paletteList.length; ++idx) + nameList.push(paletteList[idx].name) if (nameList.length > 0) result['palettes'] = nameList - var objectContainer = container ? container : object.visualParent.parent.parent.parent - - if (objectContainer.compact) return result + var objectContainer = container + if (!container){ + var p = object.visualParent + while (p && p.objectName !== "objectContainer") + p = p.parent + if (p) objectContainer = p + } + if (objectContainer && objectContainer.compact) return result var childFragments = object.getChildFragments() var objects = [] var properties = [] diff --git a/plugins/fs/fsqml/samples/fileexplorer/resources/FileExplorerRemoveHighlight.qml b/plugins/fs/fsqml/samples/fileexplorer/resources/FileExplorerRemoveHighlight.qml index 00ebe26a..5925fe5f 100644 --- a/plugins/fs/fsqml/samples/fileexplorer/resources/FileExplorerRemoveHighlight.qml +++ b/plugins/fs/fsqml/samples/fileexplorer/resources/FileExplorerRemoveHighlight.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ diff --git a/plugins/fs/fsqml/samples/fileexplorer/resources/ShapeFileExplorer.qml b/plugins/fs/fsqml/samples/fileexplorer/resources/ShapeFileExplorer.qml index afd42868..35e68fa5 100644 --- a/plugins/fs/fsqml/samples/fileexplorer/resources/ShapeFileExplorer.qml +++ b/plugins/fs/fsqml/samples/fileexplorer/resources/ShapeFileExplorer.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ run: function(workspace){ diff --git a/plugins/fs/fsqml/samples/readingfiles/resources/ReadingFilesRemoveHighlight.qml b/plugins/fs/fsqml/samples/readingfiles/resources/ReadingFilesRemoveHighlight.qml index 00ebe26a..5925fe5f 100644 --- a/plugins/fs/fsqml/samples/readingfiles/resources/ReadingFilesRemoveHighlight.qml +++ b/plugins/fs/fsqml/samples/readingfiles/resources/ReadingFilesRemoveHighlight.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ diff --git a/plugins/fs/fsqml/samples/readingfiles/resources/ShapeReadingFiles.qml b/plugins/fs/fsqml/samples/readingfiles/resources/ShapeReadingFiles.qml index cc033471..ff68d5a9 100644 --- a/plugins/fs/fsqml/samples/readingfiles/resources/ShapeReadingFiles.qml +++ b/plugins/fs/fsqml/samples/readingfiles/resources/ShapeReadingFiles.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ run: function(workspace){ diff --git a/plugins/lcvcore/samples/coloradjustments/resources/ColorAdjustmentsRemoveHighlight.qml b/plugins/lcvcore/samples/coloradjustments/resources/ColorAdjustmentsRemoveHighlight.qml index 00ebe26a..5925fe5f 100644 --- a/plugins/lcvcore/samples/coloradjustments/resources/ColorAdjustmentsRemoveHighlight.qml +++ b/plugins/lcvcore/samples/coloradjustments/resources/ColorAdjustmentsRemoveHighlight.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ diff --git a/plugins/lcvcore/samples/coloradjustments/resources/ShapeColorAdjustments.qml b/plugins/lcvcore/samples/coloradjustments/resources/ShapeColorAdjustments.qml index e2ffabc5..417d5208 100644 --- a/plugins/lcvcore/samples/coloradjustments/resources/ShapeColorAdjustments.qml +++ b/plugins/lcvcore/samples/coloradjustments/resources/ShapeColorAdjustments.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ run: function(workspace){ diff --git a/plugins/lcvcore/samples/drawing/resources/DrawingRemoveHighlight.qml b/plugins/lcvcore/samples/drawing/resources/DrawingRemoveHighlight.qml index 00ebe26a..5925fe5f 100644 --- a/plugins/lcvcore/samples/drawing/resources/DrawingRemoveHighlight.qml +++ b/plugins/lcvcore/samples/drawing/resources/DrawingRemoveHighlight.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ diff --git a/plugins/lcvcore/samples/drawing/resources/ShapeDrawing.qml b/plugins/lcvcore/samples/drawing/resources/ShapeDrawing.qml index e24727f9..33bddf04 100644 --- a/plugins/lcvcore/samples/drawing/resources/ShapeDrawing.qml +++ b/plugins/lcvcore/samples/drawing/resources/ShapeDrawing.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ run: function(workspace){ diff --git a/plugins/lcvcore/samples/imagetransformations/resources/AddDifferentImage.qml b/plugins/lcvcore/samples/imagetransformations/resources/AddDifferentImage.qml index f383a48e..1cb7f969 100644 --- a/plugins/lcvcore/samples/imagetransformations/resources/AddDifferentImage.qml +++ b/plugins/lcvcore/samples/imagetransformations/resources/AddDifferentImage.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ diff --git a/plugins/lcvcore/samples/imagetransformations/resources/ImageTransformationsRemoveHighlight.qml b/plugins/lcvcore/samples/imagetransformations/resources/ImageTransformationsRemoveHighlight.qml index 00ebe26a..5925fe5f 100644 --- a/plugins/lcvcore/samples/imagetransformations/resources/ImageTransformationsRemoveHighlight.qml +++ b/plugins/lcvcore/samples/imagetransformations/resources/ImageTransformationsRemoveHighlight.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ diff --git a/plugins/lcvcore/samples/imagetransformations/resources/ShapeImageTransformations.qml b/plugins/lcvcore/samples/imagetransformations/resources/ShapeImageTransformations.qml index c1424fb7..45375d2f 100644 --- a/plugins/lcvcore/samples/imagetransformations/resources/ShapeImageTransformations.qml +++ b/plugins/lcvcore/samples/imagetransformations/resources/ShapeImageTransformations.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ run: function(workspace){ diff --git a/plugins/lcvcore/samples/multiimage/resources/MultiImageRemoveHighlight.qml b/plugins/lcvcore/samples/multiimage/resources/MultiImageRemoveHighlight.qml index 00ebe26a..5925fe5f 100644 --- a/plugins/lcvcore/samples/multiimage/resources/MultiImageRemoveHighlight.qml +++ b/plugins/lcvcore/samples/multiimage/resources/MultiImageRemoveHighlight.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ diff --git a/plugins/lcvcore/samples/multiimage/resources/ShapeMultiImage.qml b/plugins/lcvcore/samples/multiimage/resources/ShapeMultiImage.qml index a6df33e0..ade28dc2 100644 --- a/plugins/lcvcore/samples/multiimage/resources/ShapeMultiImage.qml +++ b/plugins/lcvcore/samples/multiimage/resources/ShapeMultiImage.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ run: function(workspace){ diff --git a/plugins/lcvcore/samples/videocoloradjustments/resources/ShapeVideoColorAdjustments.qml b/plugins/lcvcore/samples/videocoloradjustments/resources/ShapeVideoColorAdjustments.qml index 399872d8..ddefbd13 100644 --- a/plugins/lcvcore/samples/videocoloradjustments/resources/ShapeVideoColorAdjustments.qml +++ b/plugins/lcvcore/samples/videocoloradjustments/resources/ShapeVideoColorAdjustments.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ run: function(workspace){ diff --git a/plugins/lcvcore/samples/videocoloradjustments/resources/VideoColorAdjustmentsRemoveHighlight.qml b/plugins/lcvcore/samples/videocoloradjustments/resources/VideoColorAdjustmentsRemoveHighlight.qml index 00ebe26a..5925fe5f 100644 --- a/plugins/lcvcore/samples/videocoloradjustments/resources/VideoColorAdjustmentsRemoveHighlight.qml +++ b/plugins/lcvcore/samples/videocoloradjustments/resources/VideoColorAdjustmentsRemoveHighlight.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ diff --git a/plugins/lcvcore/samples/videotimeline/resources/ShapeVideoTimeline.qml b/plugins/lcvcore/samples/videotimeline/resources/ShapeVideoTimeline.qml index 9c66039d..affa4c51 100644 --- a/plugins/lcvcore/samples/videotimeline/resources/ShapeVideoTimeline.qml +++ b/plugins/lcvcore/samples/videotimeline/resources/ShapeVideoTimeline.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ run: function(workspace){ diff --git a/plugins/lcvcore/samples/videotimeline/resources/VideoTimelineRemoveHighlight.qml b/plugins/lcvcore/samples/videotimeline/resources/VideoTimelineRemoveHighlight.qml index 00ebe26a..5925fe5f 100644 --- a/plugins/lcvcore/samples/videotimeline/resources/VideoTimelineRemoveHighlight.qml +++ b/plugins/lcvcore/samples/videotimeline/resources/VideoTimelineRemoveHighlight.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import editor 1.0 import editqml 1.0 +import workspace 1.0 WorkspaceControl{ diff --git a/plugins/workspace/qml/DocumentationView.qml b/plugins/workspace/qml/DocumentationView.qml index 627b1472..55d5859f 100644 --- a/plugins/workspace/qml/DocumentationView.qml +++ b/plugins/workspace/qml/DocumentationView.qml @@ -193,7 +193,7 @@ WebEngineView{ var path = Fs.UrlInfo.path(request.requestedUrl) path = Fs.Path.join(lk.layers.workspace.pluginsPath(), path) - lk.layers.workspace.project.openProjectPath(path) + lk.layers.workspace.wizards.openProject(path) } } } From 505976073ff08bf0f272ded602c4424921a904e4 Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Thu, 1 Jul 2021 20:18:48 +0300 Subject: [PATCH 90/91] BuildErrors: Updated StreamProvider build. --- lib/lvview/src/lvview.pri | 1 + lib/lvview/src/qmlstreamprovider.cpp | 9 +++++++++ lib/lvview/src/qmlstreamprovider.h | 3 +++ 3 files changed, 13 insertions(+) create mode 100644 lib/lvview/src/qmlstreamprovider.cpp diff --git a/lib/lvview/src/lvview.pri b/lib/lvview/src/lvview.pri index f3aeb3d3..7c0066e8 100644 --- a/lib/lvview/src/lvview.pri +++ b/lib/lvview/src/lvview.pri @@ -46,6 +46,7 @@ SOURCES += \ $$PWD/metainfo.cpp \ $$PWD/qmlbuild.cpp \ $$PWD/qmlerror.cpp \ + $$PWD/qmlstreamprovider.cpp \ $$PWD/qmlwritablestream.cpp \ $$PWD/settings.cpp \ $$PWD/qmlclipboard.cpp \ diff --git a/lib/lvview/src/qmlstreamprovider.cpp b/lib/lvview/src/qmlstreamprovider.cpp new file mode 100644 index 00000000..fc695236 --- /dev/null +++ b/lib/lvview/src/qmlstreamprovider.cpp @@ -0,0 +1,9 @@ +#include "qmlstreamprovider.h" + +namespace lv{ + +QmlStreamProvider::QmlStreamProvider(){} +QmlStreamProvider::~QmlStreamProvider(){} + + +} diff --git a/lib/lvview/src/qmlstreamprovider.h b/lib/lvview/src/qmlstreamprovider.h index 145110c8..fe7ef90f 100644 --- a/lib/lvview/src/qmlstreamprovider.h +++ b/lib/lvview/src/qmlstreamprovider.h @@ -8,6 +8,9 @@ namespace lv{ class LV_VIEW_EXPORT QmlStreamProvider{ public: + QmlStreamProvider(); + virtual ~QmlStreamProvider(); + virtual void wait() = 0; virtual void resume() = 0; }; From d0710bdadf8d0a9587b72abae40a2f8d694d37ce Mon Sep 17 00:00:00 2001 From: Dinu SV Date: Thu, 1 Jul 2021 20:18:56 +0300 Subject: [PATCH 91/91] Version update. --- .qmake.conf | 2 +- README.md | 2 +- application/src/livekeys.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.qmake.conf b/.qmake.conf index 80517c84..2d38ff52 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -14,7 +14,7 @@ PROJECT_ROOT = $$PWD BUILD_PATH = $$shadowed($$PWD) -LIVEKEYS_VERSION = 1.8.0 +LIVEKEYS_VERSION = 1.9.1 macx:DEPLOY_PATH = $$BUILD_PATH/bin/livekeys.app/Contents else:DEPLOY_PATH = $$BUILD_PATH/bin diff --git a/README.md b/README.md index 82c82c83..7c3d7795 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ [![Build Status](https://travis-ci.com/live-keys/livekeys.svg?branch=master)](https://travis-ci.com/live-keys/livekeys) [![Build status](https://ci.appveyor.com/api/projects/status/3l5t69h7q3gpkec1?svg=true)](https://ci.appveyor.com/project/dinusv/livekeys) - * **Version**: 1.9.0 + * **Version**: 1.9.1 * **License**: LGPL * **Website**: [livekeys.io](https://livekeys.io) * **Demo**: [www.youtube.com/watch?v=ZPt5KSy1wh0](https://www.youtube.com/watch?v=ZPt5KSy1wh0) diff --git a/application/src/livekeys.h b/application/src/livekeys.h index 49ad0e39..81c10414 100644 --- a/application/src/livekeys.h +++ b/application/src/livekeys.h @@ -31,7 +31,7 @@ #define LIVEKEYS_VERSION_MAJOR 1 #define LIVEKEYS_VERSION_MINOR 9 -#define LIVEKEYS_VERSION_PATCH 0 +#define LIVEKEYS_VERSION_PATCH 1 // Forward declarations // --------------------