diff --git a/buttleofx/MainWindow.qml b/buttleofx/MainWindow.qml
index df988b6d..028b10e7 100644
--- a/buttleofx/MainWindow.qml
+++ b/buttleofx/MainWindow.qml
@@ -1,10 +1,10 @@
-import QtQuick 2.0
-import QtQuick.Controls 1.0
-import QtQuick.Layouts 1.0
import QtQml 2.1
+import QtQuick 2.0
import QuickMamba 1.0
-import QtQuick.Dialogs 1.1
import QtQuick.Window 2.1
+import QtQuick.Dialogs 1.1
+import QtQuick.Layouts 1.0
+import QtQuick.Controls 1.0
import QtQuick.LocalStorage 2.0
import "gui/graph/qml"
@@ -13,6 +13,7 @@ import "gui/paramEditor/qml"
import "gui/browser/qml"
import "gui/plugin/qml"
import "gui/shortcut/qml"
+import "gui/dialogs"
ApplicationWindow {
property var settingsDatabase: getInitializedDatabase()
@@ -69,20 +70,18 @@ ApplicationWindow {
width: 1200
height: 800
id: mainWindowQML
- title:"ButtleOFX"
+ title: "ButtleOFX"
// TopFocusHandler {
// anchors.fill: parent
// }
Keys.onPressed: {
-
// Viewer
if ((event.key == Qt.Key_1) && (event.modifiers & Qt.KeypadModifier)) {
player.changeViewer(1)
}
if ((event.key == Qt.Key_2) && (event.modifiers & Qt.KeypadModifier)) {
-
player.changeViewer(2)
}
if ((event.key == Qt.Key_3) && (event.modifiers & Qt.KeypadModifier)) {
@@ -117,15 +116,15 @@ ApplicationWindow {
}
}
- property bool aNodeIsSelected:true
+ property bool aNodeIsSelected: true
// Window of hint for plugins
PluginWindow {
id: doc
title: "Plugin's Documentation"
- selectedNodeLabel: _buttleData.currentSelectedNodeWrappers.count!=0 ? _buttleData.currentSelectedNodeWrappers.get(0).name : ""
- selectedNodeDoc: _buttleData.currentSelectedNodeWrappers.count!=0 ? _buttleData.currentSelectedNodeWrappers.get(0).pluginDoc : ""
- selectedNodeGroup: _buttleData.currentSelectedNodeWrappers.count!=0 ? _buttleData.currentSelectedNodeWrappers.get(0).pluginGroup : ""
+ selectedNodeLabel: _buttleData.currentSelectedNodeWrappers.count != 0 ? _buttleData.currentSelectedNodeWrappers.get(0).name : ""
+ selectedNodeDoc: _buttleData.currentSelectedNodeWrappers.count != 0 ? _buttleData.currentSelectedNodeWrappers.get(0).pluginDoc : ""
+ selectedNodeGroup: _buttleData.currentSelectedNodeWrappers.count != 0 ? _buttleData.currentSelectedNodeWrappers.get(0).pluginGroup : ""
}
// Window of shortcuts
@@ -134,103 +133,102 @@ ApplicationWindow {
title: "Shortcuts"
}
- FileDialog {
+ FileViewerDialog {
id: finderLoadGraph
+ visible: false
title: "Open a graph"
- nameFilters: [ "All files (*)" ]
- selectedNameFilter: "All files (*)"
+ buttonText: "Open"
+ folderModelFolder: _buttleData.homeDir
- onAccepted: {
- if (finderLoadGraph.fileUrl) {
- _buttleData.loadData(finderLoadGraph.fileUrl)
+ onButtonClicked: {
+ if (finderLoadGraph.entryBarText != "") {
+ _buttleData.newData()
+ _buttleData.loadData(currentFile)
+ finderLoadGraph.visible = false
}
}
}
- FileDialog {
+ FileViewerDialog {
id: finderSaveGraph
+ visible: false
title: "Save the graph"
- nameFilters: [ "All files (*)" ]
- selectedNameFilter: "All files (*)"
+ buttonText: "Save"
+ folderModelFolder: _buttleData.homeDir
- onAccepted: {
- if (finderSaveGraph.fileUrl) {
- _buttleData.saveData(finderSaveGraph.fileUrl)
- }
+ // Acceptable values are the verb parts of the callers ID's, i.e. 'open',
+ // 'new', and 'close'
+ property string action
+
+ // This initializer function takes in the action being done by the user so we know
+ // what to do when called.
+ function show(doAction) {
+ action = doAction
+ finderSaveGraph.visible = true
}
- selectExisting: false
+ onButtonClicked: {
+ if (finderSaveGraph.entryBarText != "") {
+ _buttleData.urlOfFileToSave = currentFile
+ _buttleData.saveData(_buttleData.urlOfFileToSave)
+
+ finderSaveGraph.visible = false
+
+ if (action == "open") {
+ finderLoadGraph.visible = true
+ } else if (action == "new") {
+ _buttleData.newData()
+ } else if (action == "close") {
+ Qt.quit()
+ }
+ }
+ }
}
- MessageDialog {
+ ExitDialog {
id: openGraph
- title:"Save the graph?"
- icon: StandardIcon.Warning
- modality: Qt.WindowStaysOnTopHint && Qt.WindowModal
- text: urlOfFileToSave == "" ? "Save graph changes before closing ?" : "Save " + _buttleData.getFileName(urlOfFileToSave) + " changes before closing ?"
- detailedText: "If you don't save the graph, unsaved modifications will be lost. "
- standardButtons: StandardButton.Yes | StandardButton.No | StandardButton.Abort
- Component.onCompleted: visible = false
-
- onYes: {
- if(urlOfFileToSave!="") {
+ visible: false
+ dialogText: "Do you want to save before closing this file?
If you don't, all unsaved changes will be lost"
+
+ onSaveButtonClicked: {
+ if (urlOfFileToSave != "") {
_buttleData.saveData(urlOfFileToSave)
- } else{
- finderSaveGraph.open()
+ } else {
+ finderSaveGraph.show("open")
}
}
- onNo: {
- finderLoadGraph.open()
+ onDiscardButtonClicked: {
+ finderLoadGraph.visible = true
}
- onRejected: {}
}
- MessageDialog {
+ ExitDialog {
id: newGraph
- title: "Save the graph?"
- icon: StandardIcon.Warning
- modality: Qt.WindowStaysOnTopHint && Qt.WindowModal
- text: urlOfFileToSave == "" ? "Save graph changes before closing ?" : "Save " + _buttleData.getFileName(urlOfFileToSave) + " changes before closing ?"
- detailedText: "If you don't save the graph, unsaved modifications will be lost. "
- standardButtons: StandardButton.Yes | StandardButton.No | StandardButton.Abort
- Component.onCompleted: visible = false
-
- onYes: {
- if (urlOfFileToSave!="") {
+ visible: false
+ dialogText: "Do you want to save before closing this file?
If you don't, all unsaved changes will be lost"
+
+ onSaveButtonClicked: {
+ if (urlOfFileToSave != "") {
_buttleData.saveData(urlOfFileToSave)
- _buttleData.newData()
} else {
- finderSaveGraph.open()
- _buttleData.newData()
+ finderSaveGraph.show("new")
}
}
- onNo: {
- _buttleData.newData()
- }
+ onDiscardButtonClicked: _buttleData.newData()
}
- MessageDialog {
+ ExitDialog {
id: closeButtle
- title: "Save the graph?"
- icon: StandardIcon.Warning
- modality: Qt.WindowStaysOnTopHint && Qt.WindowModal
- text: urlOfFileToSave == "" ? "Save graph changes before closing ?" : "Save " + _buttleData.getFileName(urlOfFileToSave) + " changes before closing ?"
- detailedText: "If you don't save the graph, unsaved modifications will be lost. "
- standardButtons: StandardButton.Yes | StandardButton.No | StandardButton.Abort
- Component.onCompleted: visible = false
-
- onYes: {
- if(urlOfFileToSave!="") {
+ visible: false
+
+ onSaveButtonClicked: {
+ if (urlOfFileToSave != "") {
_buttleData.saveData(urlOfFileToSave)
} else {
- finderSaveGraph.open()
- finderSaveGraph.close()
- finderSaveGraph.open()
+ finderSaveGraph.show("close")
}
}
- onNo: {
- Qt.quit()
- }
+ onDiscardButtonClicked: Qt.quit()
}
menuBar: MenuBar {
@@ -245,7 +243,7 @@ ApplicationWindow {
if (!_buttleData.graphCanBeSaved) {
_buttleData.newData()
} else {
- newGraph.open()
+ newGraph.visible = true
}
}
}
@@ -256,11 +254,9 @@ ApplicationWindow {
onTriggered: {
if (!_buttleData.graphCanBeSaved) {
- finderLoadGraph.open()
+ finderLoadGraph.visible = true
} else {
- openGraph.open()
- openGraph.close()
- openGraph.open()
+ openGraph.visible = true
}
}
}
@@ -275,7 +271,7 @@ ApplicationWindow {
MenuItem {
text: "Save As"
shortcut: "Ctrl+Shift+S"
- onTriggered: finderSaveGraph.open()
+ onTriggered: finderSaveGraph.visible = true
}
MenuSeparator { }
@@ -288,7 +284,7 @@ ApplicationWindow {
if (!_buttleData.graphCanBeSaved) {
Qt.quit()
} else {
- closeButtle.open()
+ closeButtle.visible = true
}
}
}
@@ -301,7 +297,7 @@ ApplicationWindow {
id: undoRedoStack
title: "Undo/Redo stack"
- property variant undoRedoList:_buttleData.graphCanBeSaved ? _buttleManager.undoRedoStack:_buttleManager.undoRedoStack
+ property variant undoRedoList: _buttleData.graphCanBeSaved ? _buttleManager.undoRedoStack : _buttleManager.undoRedoStack
Instantiator {
model: undoRedoStack.undoRedoList
@@ -412,10 +408,11 @@ ApplicationWindow {
title: "Nodes"
Instantiator {
- model: _buttleData.getMenu(1,"")
+ model: _buttleData.getMenu(1, "")
+
Menu {
id: firstMenu
- title:object
+ title: object
__parentContentItem: nodesMenu.__contentItem // To remove warning
Instantiator {
@@ -445,11 +442,11 @@ ApplicationWindow {
}
Instantiator {
- model: _buttleData.getMenu(2,firstMenu.title)
+ model: _buttleData.getMenu(2, firstMenu.title)
Menu {
id: secondMenu
- title:object
+ title: object
__parentContentItem: nodesMenu.__contentItem // To remove warning
Instantiator {
@@ -479,11 +476,11 @@ ApplicationWindow {
}
Instantiator {
- model: _buttleData.getMenu(3,secondMenu.title)
+ model: _buttleData.getMenu(3, secondMenu.title)
Menu {
id: thirdMenu
- title:object
+ title: object
__parentContentItem: nodesMenu.__contentItem // To remove warning
Instantiator {
@@ -513,10 +510,10 @@ ApplicationWindow {
}
Instantiator {
- model: _buttleData.getMenu(4,thirdMenu.title)
+ model: _buttleData.getMenu(4, thirdMenu.title)
Menu {
- id:fourthMenu
+ id: fourthMenu
title: object
__parentContentItem: nodesMenu.__contentItem // To remove warning
@@ -547,7 +544,7 @@ ApplicationWindow {
}
Instantiator {
- model: _buttleData.getMenu(5,fourthMenu.title)
+ model: _buttleData.getMenu(5, fourthMenu.title)
Menu {
id: fifthMenu
@@ -620,7 +617,6 @@ ApplicationWindow {
}
}
-
Menu {
title: "View"
@@ -635,7 +631,7 @@ ApplicationWindow {
browserView.checked = false
advancedView.checked = false
selectedView = 1
- saveSetting("view",selectedView)
+ saveSetting("view", selectedView)
lastSelectedDefaultView = view1
topLeftView.visible = true
bottomLeftView.visible = true
@@ -656,7 +652,7 @@ ApplicationWindow {
defaultView.checked = false
advancedView.checked = false
selectedView = 2
- saveSetting("view",selectedView)
+ saveSetting("view", selectedView)
lastSelectedDefaultView = view2
topLeftView.visible = true
bottomLeftView.visible = true
@@ -677,9 +673,9 @@ ApplicationWindow {
defaultView.checked = false
browserView.checked = false
selectedView = 3
- saveSetting("view",selectedView)
+ saveSetting("view", selectedView)
lastSelectedDefaultView = view3
- topLeftView.visible=true
+ topLeftView.visible = true
bottomLeftView.visible = true
topRightView.visible = true
bottomRightView.visible = false
@@ -693,29 +689,41 @@ ApplicationWindow {
MenuItem {
text: "Browser"
checkable: true
- checked: browser.parent.visible==true ? true : false
- onTriggered: browser.parent.visible == false ? browser.parent.visible=true : browser.parent.visible=false
+ checked: browser.parent.visible
+
+ onTriggered: {
+ browser.parent.visible = !browser.parent.visible
+ }
}
MenuItem {
text: "Viewer"
checkable: true
- checked: player.parent.visible==true ? true : false
- onTriggered: player.parent.visible == false ? player.parent.visible=true : player.parent.visible=false
+ checked: player.parent.visible
+
+ onTriggered: {
+ player.parent.visible = !player.parent.visible
+ }
}
MenuItem {
text: "Graph"
checkable: true
- checked: graphEditor.parent.visible==true ? true : false
- onTriggered: graphEditor.parent.visible == false ? graphEditor.parent.visible=true : graphEditor.parent.visible=false
+ checked: graphEditor.parent.visible
+
+ onTriggered: {
+ graphEditor.parent.visible = !graphEditor.parent.visible
+ }
}
MenuItem {
text: "Parameters"
checkable: true
- checked: paramEditor.parent.visible==true ? true : false
- onTriggered: paramEditor.parent.visible == false ? paramEditor.parent.visible=true : paramEditor.parent.visible=false
+ checked: paramEditor.parent.visible
+
+ onTriggered: {
+ paramEditor.parent.visible = !paramEditor.parent.visible
+ }
}
*/
}
@@ -732,7 +740,6 @@ ApplicationWindow {
}
*/
-
// This rectangle represents the zone under the menu, it allows to define the anchors.fill and margins for the SplitterRow
Rectangle {
id: modulsContainer
@@ -796,7 +803,7 @@ ApplicationWindow {
view2[1]
break
case 3:
- if(advancedParamEditor.displayGraph)
+ if (advancedParamEditor.displayGraph)
view3[3]
else
view3[1]
@@ -850,7 +857,7 @@ ApplicationWindow {
implicitWidth: parent.width
implicitHeight: topRightView.visible ? 0.5 * parent.height : parent.height
z: -1
- visible: selectedView ==3 ? false : true
+ visible: selectedView != 3
children:
switch (selectedView) {
@@ -876,7 +883,7 @@ ApplicationWindow {
id: subviews
visible: false
- property variant parentBeforeFullscreen : null
+ property variant parentBeforeFullscreen: null
Player {
id: player
@@ -893,7 +900,7 @@ ApplicationWindow {
}
}
onButtonFullscreenClicked:
- if (parent != fullscreenContent){
+ if (parent != fullscreenContent) {
subviews.parentBeforeFullscreen = parent
fullscreenWindow.visibility = Window.FullScreen
fullscreenContent.children = player
@@ -905,8 +912,8 @@ ApplicationWindow {
anchors.fill: parent
onButtonCloseClicked: {
- if (parent!=fullscreenContent) {
- selectedView=-1
+ if (parent != fullscreenContent) {
+ selectedView = -1
parent.visible = false
} else {
fullscreenWindow.visibility = Window.Hidden
@@ -914,7 +921,7 @@ ApplicationWindow {
}
}
onButtonFullscreenClicked:
- if (parent != fullscreenContent){
+ if (parent != fullscreenContent) {
subviews.parentBeforeFullscreen = parent
fullscreenWindow.visibility = Window.FullScreen
fullscreenContent.children = graphEditor
@@ -928,7 +935,7 @@ ApplicationWindow {
currentParamNode: _buttleData.currentParamNodeWrapper ? _buttleData.currentParamNodeWrapper : null
onButtonCloseClicked: {
- if (parent!=fullscreenContent) {
+ if (parent != fullscreenContent) {
selectedView =- 1
parent.visible = false
} else {
@@ -937,7 +944,7 @@ ApplicationWindow {
}
}
onButtonFullscreenClicked:
- if (parent != fullscreenContent){
+ if (parent != fullscreenContent) {
subviews.parentBeforeFullscreen = parent
fullscreenWindow.visibility = Window.FullScreen
fullscreenContent.children = paramEditor
@@ -958,7 +965,7 @@ ApplicationWindow {
}
}
onButtonFullscreenClicked:
- if (parent != fullscreenContent){
+ if (parent != fullscreenContent) {
subviews.parentBeforeFullscreen = parent
fullscreenWindow.visibility = Window.FullScreen
fullscreenContent.children = advancedParamEditor
@@ -979,7 +986,7 @@ ApplicationWindow {
}
}
onButtonFullscreenClicked:
- if (parent != fullscreenContent){
+ if (parent != fullscreenContent) {
subviews.parentBeforeFullscreen = parent
fullscreenWindow.visibility = Window.FullScreen
fullscreenContent.children = browser
diff --git a/buttleofx/data/buttleData.py b/buttleofx/data/buttleData.py
index 1cb7af8d..43b68acc 100644
--- a/buttleofx/data/buttleData.py
+++ b/buttleofx/data/buttleData.py
@@ -524,9 +524,7 @@ def loadData(self, url='buttleofx/backup/data.bofx'):
"""
Loads all data from a Json file (the default Json file if no url is given)
"""
-
filepath = QtCore.QUrl(url).toLocalFile()
-
self.newData()
with open(filepath, 'r') as f:
@@ -649,11 +647,11 @@ def saveData(self, url):
"""
Saves all data in a json file
"""
+ # If called from Python, it could be a str or a QUrl
if isinstance(url, str):
- # If called from Python, it could be a str or a QUrl.
- filepath = QtCore.QUrl.fromLocalFile(url).toLocalFile()
+ filepath = url
else:
- filepath = QtCore.QUrl(url).toLocalFile()
+ filepath = url.toLocalFile()
if not filepath.lower().endswith(".bofx"):
filepath = filepath + ".bofx"
@@ -739,6 +737,9 @@ def zoom(self, width, height, nodeWidth, zoomCoeff, graphPreviousWidth, graphPre
def getButtlePath(self):
return self._buttlePath
+ def getHomeDir(self):
+ return os.path.expanduser("~")
+
def getCurrentConnectionWrapper(self):
"""
Returns the current currentConnectionWrapper.
@@ -1039,6 +1040,7 @@ def graphCanBeSaved(self):
# filePath
buttlePath = QtCore.pyqtProperty(str, getButtlePath, constant=True)
+ homeDir = QtCore.pyqtProperty(str, getHomeDir, constant=True)
# Current param, view, and selected node
currentParamNodeChanged = QtCore.pyqtSignal()
diff --git a/buttleofx/gui/dialogs/ExitDialog.qml b/buttleofx/gui/dialogs/ExitDialog.qml
new file mode 100644
index 00000000..9f8e9aa3
--- /dev/null
+++ b/buttleofx/gui/dialogs/ExitDialog.qml
@@ -0,0 +1,90 @@
+import QtQuick 2.1
+import QtQuick.Window 2.1
+import QtQuick.Layouts 1.0
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+
+Window {
+ id: exitDialog
+ width: 425
+ height: 100
+ title: "Save Changes?"
+ color: "#141414"
+ flags: Qt.Dialog
+
+ property string dialogText: "Do you want to save before exiting?
If you don't, all unsaved changes will be lost."
+
+ signal saveButtonClicked
+ signal discardButtonClicked
+
+ Component {
+ id: buttonStyle
+
+ ButtonStyle {
+ background: Rectangle {
+ radius: 6
+ implicitWidth: 100
+ implicitHeight: 25
+
+ border.color: control.hovered ? "#00B2A1" : "#9F9C99"
+ border.width: control.hovered ? 3 : 2
+
+ gradient: Gradient {
+ GradientStop { position: 0; color: control.pressed ? "#EFEBE7" : "#EFEBE7" }
+ GradientStop { position: .5; color: control.pressed ? "#D9D9D9" : "#EFEBE7" }
+ GradientStop { position: 0; color: control.pressed ? "#EFEBE7" : "#EFEBE7" }
+ }
+ }
+ }
+ }
+
+ ColumnLayout {
+ anchors.centerIn: parent
+ spacing: 15
+
+ RowLayout {
+ spacing: 20
+
+ Image { source: "../img/icons/logo_icon.png" }
+
+ Text {
+ text: dialogText
+ color: "#FEFEFE"
+ }
+ }
+
+ RowLayout {
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: 6
+
+ Button {
+ id: saveButton
+ text: "Save"
+ style: buttonStyle
+
+ onClicked: {
+ exitDialog.saveButtonClicked()
+ exitDialog.visible = false
+ }
+ }
+
+ Button {
+ id: discardButton
+ text: "Discard"
+ style: buttonStyle
+
+ onClicked: {
+ exitDialog.discardButtonClicked()
+ exitDialog.visible = false
+ }
+ }
+
+ Button {
+ id: abortButton
+ text: "Abort"
+ style: buttonStyle
+ onClicked: exitDialog.visible = false
+ }
+ }
+ }
+}
diff --git a/buttleofx/gui/dialogs/FileViewerDialog.qml b/buttleofx/gui/dialogs/FileViewerDialog.qml
new file mode 100644
index 00000000..0f1088b1
--- /dev/null
+++ b/buttleofx/gui/dialogs/FileViewerDialog.qml
@@ -0,0 +1,206 @@
+import QtQuick 2.1
+import QtQuick.Window 2.1
+import QtQuick.Layouts 1.0
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+import Qt.labs.folderlistmodel 2.1
+
+Window {
+ id: fileViewerWindow
+ width: 630
+ height: 380
+ color: "#141414"
+ flags: Qt.Dialog
+
+ property string buttonText
+ property string folderModelFolder
+ property string entryBarText: entryBar.text
+
+ signal buttonClicked(string currentFile)
+
+ FolderListModel {
+ id: folderModel
+ showDirsFirst: true
+ folder: folderModelFolder
+ }
+
+ ColumnLayout {
+ anchors.fill: parent
+ anchors.margins: 4
+
+ RowLayout {
+ id: headerBar
+ anchors.top: parent.top
+ anchors.leftMargin: parent.spacing
+ anchors.rightMargin: parent.spacing
+
+ Button {
+ id: parentFolderButton
+ width: 15
+ height: 15
+
+ iconSource:
+ if (hovered) {
+ "../img/buttons/browser/parent_hover.png"
+ } else {
+ "../img/buttons/browser/parent.png"
+ }
+
+ style:
+ ButtonStyle {
+ background: Rectangle {
+ anchors.fill: parent
+ color: "transparent"
+ }
+ }
+
+ onClicked: {
+ folderModel.folder = folderModel.parentFolder
+ }
+ }
+
+ Rectangle {
+ Layout.fillWidth: true
+ height: 24
+ color: "black"
+ radius: 5
+ border.color: "grey"
+
+ TextInput {
+ id: urlBar
+ x: 5
+ y: 4
+
+ text: folderModel.folder.toString().substring(7)
+ readOnly: true
+ selectByMouse: true
+ Layout.fillWidth: true
+
+ color: "white"
+ selectionColor: "#00b2a1"
+ }
+ }
+ }
+
+ ScrollView {
+ anchors.top: headerBar.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: bottomRow.top
+ anchors.bottomMargin: 4
+
+ GridView {
+ id: folderView
+ model: folderModel
+ cellWidth: 100
+ cellHeight: 100
+ highlightFollowsCurrentItem: false
+
+ highlight: Rectangle {
+ width: folderView.cellWidth
+ height: folderView.cellHeight
+ color: "#00b2a1"
+ radius: 4
+
+ x: folderView.currentItem.x
+ y: folderView.currentItem.y
+ Behavior on x { SmoothedAnimation { duration: -1; velocity: -1 } }
+ Behavior on y { SmoothedAnimation { duration: -1; velocity: -1 } }
+ }
+
+ delegate: Rectangle {
+ width: folderView.cellWidth
+ height: folderView.cellHeight
+ color: "transparent"
+
+ Column {
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+
+ Image {
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: 55
+ height: 55
+ asynchronous: true
+ fillMode: Image.PreserveAspectFit
+ sourceSize.width: width
+ sourceSize.height: height
+ property variant supportedFormats: ["bmp", "gif", "jpg", "jpeg", "png", "pbm", "pgm", "ppm", "xbm", "xpm"]
+
+ source: {
+ if (folderModel.isFolder(index)) {
+ "../img/buttons/browser/folder-icon.png"
+ } else if (supportedFormats.indexOf(folderModel.get(index, "fileSuffix").toLowerCase()) != -1) {
+ folderModel.get(index, "filePath")
+ } else {
+ "../img/buttons/browser/file-icon.png"
+ }
+ }
+ }
+
+ Text {
+ text: fileName
+ color: "white"
+ width: folderView.cellWidth - 10
+ horizontalAlignment: Text.AlignHCenter
+ wrapMode: Text.WrapAnywhere
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+
+ onClicked: {
+ folderView.currentIndex = index
+ if (!folderModel.isFolder(index)) {
+ entryBar.text = folderModel.get(index, "fileName")
+ } else {
+ entryBar.text = ""
+ }
+ }
+ onDoubleClicked: {
+ if (folderModel.isFolder(index)) {
+ folderModel.folder = folderModel.get(index, "filePath")
+ }
+ }
+ }
+ }
+ }
+ }
+
+ RowLayout {
+ id: bottomRow
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ anchors.bottom: parent.bottom
+
+ TextField {
+ id: entryBar
+ Layout.fillWidth: true
+ }
+
+ Button {
+ text: buttonText
+
+ style:
+ ButtonStyle {
+ background: Rectangle {
+ radius: 6
+ implicitWidth: 100
+ implicitHeight: 25
+
+ border.color: control.hovered ? "#00B2A1" : "#9F9C99"
+ border.width: control.hovered ? 3 : 2
+
+ gradient: Gradient {
+ GradientStop { position: 0; color: control.pressed ? "#EFEBE7" : "#EFEBE7" }
+ GradientStop { position: .5; color: control.pressed ? "#D9D9D9" : "#EFEBE7" }
+ GradientStop { position: 0; color: control.pressed ? "#EFEBE7" : "#EFEBE7" }
+ }
+ }
+ }
+ onClicked: fileViewerWindow.buttonClicked(folderModel.folder + "/" + entryBarText)
+ }
+ }
+ }
+}
diff --git a/buttleofx/gui/graph/qml/FinderLoadGraph.qml b/buttleofx/gui/graph/qml/FinderLoadGraph.qml
deleted file mode 100644
index 5462f2f6..00000000
--- a/buttleofx/gui/graph/qml/FinderLoadGraph.qml
+++ /dev/null
@@ -1,18 +0,0 @@
-import QtQuick 2.0
-import QtQuick.Dialogs 1.0
-
-FileDialog {
- signal getFileUrl(string fileurl)
-
- id: finderLoadGraph
- title: "Open a graph"
- folder: _buttleData.buttlePath
- nameFilters: ["ButtleOFX Graph files (*.bofx)", "All files (*)"]
- selectedNameFilter: "All files (*)"
-
- onAccepted: {
- console.log(finderLoadGraph.fileUrl)
- _buttleData.loadData(finderLoadGraph.fileUrl)
- getFileUrl(finderLoadGraph.fileUrl)
- }
-}
diff --git a/buttleofx/gui/graph/qml/FinderSaveGraph.qml b/buttleofx/gui/graph/qml/FinderSaveGraph.qml
deleted file mode 100644
index 34a964f7..00000000
--- a/buttleofx/gui/graph/qml/FinderSaveGraph.qml
+++ /dev/null
@@ -1,19 +0,0 @@
-import QtQuick 2.0
-import QtQuick.Dialogs 1.0
-
-FileDialog {
- signal getFileUrl(string fileurl)
-
- id: finderSaveGraph
- title: "Save the graph"
- folder: _buttleData.buttlePath
- nameFilters: ["ButtleOFX Graph files (*.bofx)", "All files (*)"]
- selectedNameFilter: "All files (*)"
-
- onAccepted: {
- _buttleData.saveData(finderSaveGraph.fileUrl)
- getFileUrl(finderSaveGraph.fileUrl)
- }
-
- selectExisting: false
-}
diff --git a/buttleofx/gui/graph/qml/Tools.qml b/buttleofx/gui/graph/qml/Tools.qml
index 857a4c63..2b541b6d 100644
--- a/buttleofx/gui/graph/qml/Tools.qml
+++ b/buttleofx/gui/graph/qml/Tools.qml
@@ -1,7 +1,7 @@
import QtQuick 2.0
-import QtQuick.Dialogs 1.0
import "../../plugin/qml"
+import "../../dialogs"
Rectangle {
id: tools
@@ -13,6 +13,72 @@ Rectangle {
signal clickCreationNode(string nodeType)
+ FileViewerDialog {
+ id: finderLoadGraph
+ visible: false
+ title: "Open a graph"
+ buttonText: "Open"
+ folderModelFolder: _buttleData.homeDir
+
+ onButtonClicked: {
+ if (finderLoadGraph.entryBarText != "") {
+ _buttleData.newData()
+ _buttleData.loadData(currentFile)
+ finderLoadGraph.visible = false
+ }
+ }
+ }
+
+ FileViewerDialog {
+ id: finderSaveGraph
+ visible: false
+ title: "Save the graph"
+ buttonText: "Save"
+ folderModelFolder: _buttleData.homeDir
+
+ // Acceptable values are the verb parts of the callers ID's, i.e. 'open'
+ // and 'save' (in which case we do no additional work).
+ property string action
+
+ // This initializer function takes in the action being done by the user so we know
+ // what to do when called.
+ function show(doAction) {
+ action = doAction
+ finderSaveGraph.visible = true
+ }
+
+ onButtonClicked: {
+ if (finderSaveGraph.entryBarText != "") {
+ _buttleData.urlOfFileToSave = currentFile
+ _buttleData.saveData(_buttleData.urlOfFileToSave)
+
+ finderSaveGraph.visible = false
+
+ if (action == "open") {
+ finderLoadGraph.visible = true
+ }
+ }
+ }
+ }
+
+ ExitDialog {
+ id: openGraph
+ visible: false
+ dialogText: "Do you want to save before closing this file?
If you don't, all unsaved changes will be lost"
+
+ onSaveButtonClicked: {
+ if (urlOfFileToSave != "") {
+ _buttleData.saveData(urlOfFileToSave)
+ finderLoadGraph.visible = true
+ } else {
+ finderSaveGraph.show("open")
+ }
+ }
+ onDiscardButtonClicked: {
+ finderLoadGraph.visible = true
+ }
+ }
+
gradient: Gradient {
GradientStop { position: 0.0; color: gradian2 }
GradientStop { position: 0.85; color: gradian2 }
@@ -39,13 +105,13 @@ Rectangle {
locked: false
onClicked: {
- if (pluginVisible==true){
- pluginVisible=false
+ if (pluginVisible == true){
+ pluginVisible = false
} else {
- pluginVisible=true
+ pluginVisible = true
}
- editNode=false
+ editNode = false
}
}
@@ -62,11 +128,9 @@ Rectangle {
editNode = false
if (!_buttleData.graphCanBeSaved) {
- finderLoadGraph.open()
+ finderLoadGraph.visible = true
} else {
- openGraph.open()
- openGraph.close()
- openGraph.open()
+ openGraph.visible = true
}
}
}
@@ -82,10 +146,11 @@ Rectangle {
onClicked: {
pluginVisible = false
editNode = false
+
if (urlOfFileToSave != "") {
_buttleData.saveData(urlOfFileToSave)
} else {
- finderSaveGraph.open()
+ finderSaveGraph.show("save")
}
}
}
diff --git a/buttleofx/main.py b/buttleofx/main.py
index 3275d763..c8d81dec 100644
--- a/buttleofx/main.py
+++ b/buttleofx/main.py
@@ -74,51 +74,57 @@
class EventFilter(QtCore.QObject):
- def eventFilter(self, receiver, event):
- buttleData = ButtleDataSingleton().get()
- browser = FileModelBrowserSingleton().get()
+ def __init__(self, app, engine):
+ self.mainApp = app
+ self.mainEngine = engine
+ self.buttleData = ButtleDataSingleton().get()
+ super(EventFilter, self).__init__()
+
+ def onSaveDialogButtonClicked(self, fileToSave):
+ self.buttleData.urlOfFileToSave = fileToSave
+ self.buttleData.saveData(QtCore.QUrl(self.buttleData.urlOfFileToSave))
+ QtCore.QCoreApplication.quit()
+
+ def onExitDialogDiscardButtonClicked(self):
+ QtCore.QCoreApplication.quit()
+
+ def onExitDialogSaveButtonClicked(self):
+ if self.buttleData.urlOfFileToSave:
+ self.buttleData.saveData(self.buttleData.urlOfFileToSave)
+ QtCore.QCoreApplication.quit()
+ else:
+ saveDialogComponent = QtQml.QQmlComponent(self.mainEngine)
+ saveDialogComponent.loadUrl(QtCore.QUrl("ButtleOFX/buttleofx/gui/dialogs/FileViewerDialog.qml"))
+
+ saveDialog = saveDialogComponent.create()
+ QtQml.QQmlProperty.write(saveDialog, "title", "Save the graph")
+ QtQml.QQmlProperty.write(saveDialog, "buttonText", "Save")
+ QtQml.QQmlProperty.write(saveDialog, "folderModelFolder", self.buttleData.getHomeDir())
+
+ saveDialog.buttonClicked.connect(self.onSaveDialogButtonClicked)
+ saveDialog.show()
+ def eventFilter(self, receiver, event):
if event.type() == QtCore.QEvent.KeyPress:
- # If alt f4 event ignored
+ # If Alt F4 event ignored
if event.modifiers() == QtCore.Qt.AltModifier and event.key() == QtCore.Qt.Key_F4:
event.ignore()
if event.type() != QtCore.QEvent.Close:
return super(EventFilter, self).eventFilter(receiver, event)
if not isinstance(receiver, QtQuick.QQuickWindow) or not receiver.title() == "ButtleOFX":
return False
- if not buttleData.graphCanBeSaved:
+ if not self.buttleData.graphCanBeSaved:
return False
- msgBox = QtWidgets.QMessageBox()
- msgBox.setText("Save graph changes before closing ?")
- msgBox.setModal(True)
- msgBox.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
- msgBox.setInformativeText("If you don't save the graph, unsaved modifications will be lost.")
- msgBox.setStandardButtons(
- QtWidgets.QMessageBox.Save | QtWidgets.QMessageBox.Discard | QtWidgets.QMessageBox.Abort)
- msgBox.setDefaultButton(QtWidgets.QMessageBox.Save)
- ret = msgBox.exec_()
-
- if ret == QtWidgets.QMessageBox.Save:
- if buttleData.urlOfFileToSave:
- # Save on the already existing file
- buttleData.saveData(buttleData.urlOfFileToSave)
- # Close the application
- return super(EventFilter, self).eventFilter(receiver, event)
-
- # This project has never been saved, so ask the user on which file to save.
- dialog = QtWidgets.QFileDialog()
- fileToSave = dialog.getSaveFileName(None, "Save the graph", browser.getFirstFolder())[0]
- if not (fileToSave.endswith(".bofx")):
- fileToSave += ".bofx"
- buttleData.urlOfFileToSave = fileToSave
- buttleData.saveData(fileToSave)
- # Close the application
- return super(EventFilter, self).eventFilter(receiver, event)
+ exitDialogComponent = QtQml.QQmlComponent(self.mainEngine)
+ # Note that we give the path relative to run_buttleofx.sh, because that becomes the PWD when this is run.
+ # We also do this for the saveDialogComponent in self.onExitDialogSaveButtonClicked().
+ exitDialogComponent.loadUrl(QtCore.QUrl("ButtleOFX/buttleofx/gui/dialogs/ExitDialog.qml"))
- if ret == QtWidgets.QMessageBox.Discard:
- # Close the application
- return super(EventFilter, self).eventFilter(receiver, event)
+ exitDialog = exitDialogComponent.create()
+ exitDialog.saveButtonClicked.connect(self.onExitDialogSaveButtonClicked)
+ exitDialog.discardButtonClicked.connect(self.onExitDialogDiscardButtonClicked)
+ exitDialog.show()
# Don't call the parent class, so we don't close the application
return True
@@ -288,7 +294,7 @@ def main(argv, app):
print("Watch directory:", parentDir)
qic.addFilesFromDirectory(parentDir, recursive=True)
- aFilter = EventFilter()
+ aFilter = EventFilter(app, engine)
app.installEventFilter(aFilter)
topLevelItem.show()