From 9b8b1d41e30a8ad8a5aa772c738ae87697b1ddf6 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 15 Mar 2016 08:41:25 -0700 Subject: [PATCH] Edit in place --- interface/resources/qml/AssetServer.qml | 27 ++++++ interface/resources/qml/controls-uit/Tree.qml | 92 +++++++++++++++++-- 2 files changed, 113 insertions(+), 6 deletions(-) diff --git a/interface/resources/qml/AssetServer.qml b/interface/resources/qml/AssetServer.qml index 82970011a0..453ecfeb6c 100644 --- a/interface/resources/qml/AssetServer.qml +++ b/interface/resources/qml/AssetServer.qml @@ -164,6 +164,28 @@ Window { Window.copyToClipboard(url); } + function renameEl(index, data) { + if (!index) { + return false; + } + + var path = assetProxyModel.data(index, 0x100); + if (!path) { + return false; + } + + var destinationPath = path.split('/'); + destinationPath[destinationPath.length - (path[path.length - 1] === '/' ? 2 : 1)] = data; + destinationPath = destinationPath.join('/').trim(); + + console.log("Renaming " + path + " to " + destinationPath); + if (path === destinationPath) { + return; + } + if (!fileExists(destinationPath)) { + doRenameFile(path, destinationPath); + } + } function renameFile(index) { if (!index) { index = treeView.selection.currentIndex; @@ -371,8 +393,13 @@ Window { height: 400 treeModel: assetProxyModel colorScheme: root.colorScheme + canEdit: true + anchors.left: parent.left anchors.right: parent.right + + modifyEl: renameEl + MouseArea { propagateComposedEvents: true anchors.fill: parent diff --git a/interface/resources/qml/controls-uit/Tree.qml b/interface/resources/qml/controls-uit/Tree.qml index a2572a2f5c..2dfa289096 100644 --- a/interface/resources/qml/controls-uit/Tree.qml +++ b/interface/resources/qml/controls-uit/Tree.qml @@ -19,9 +19,12 @@ TreeView { id: treeView property var treeModel: ListModel { } + property var canEdit: false property int colorScheme: hifi.colorSchemes.light readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light + property var modifyEl: function(index, data) { return false; } + model: treeModel selection: ItemSelectionModel { model: treeModel @@ -124,7 +127,9 @@ TreeView { : (styleData.alternate ? hifi.colors.tableRowDarkEven : hifi.colors.tableRowDarkOdd) } - itemDelegate: FiraSansSemiBold { + itemDelegate: Loader { + id: itemDelegateLoader + anchors { left: parent ? parent.left : undefined leftMargin: (2 + styleData.depth) * hifi.dimensions.tablePadding @@ -133,11 +138,86 @@ TreeView { verticalCenter: parent ? parent.verticalCenter : undefined } - text: styleData.value - size: hifi.fontSizes.tableText - color: colorScheme == hifi.colorSchemes.light - ? (styleData.selected ? hifi.colors.black : hifi.colors.baseGrayHighlight) - : (styleData.selected ? hifi.colors.black : hifi.colors.lightGrayText) + function getComponent() { + if (treeView.canEdit && styleData.selected) { + return textFieldComponent; + } else { + return labelComponent; + } + + } + sourceComponent: getComponent() + + Component { + id: labelComponent + FiraSansSemiBold { + + text: styleData.value + size: hifi.fontSizes.tableText + color: colorScheme == hifi.colorSchemes.light + ? (styleData.selected ? hifi.colors.black : hifi.colors.baseGrayHighlight) + : (styleData.selected ? hifi.colors.black : hifi.colors.lightGrayText) + } + } + Component { + id: textFieldComponent + + TextField { + id: textField + readOnly: !activeFocus + + text: styleData.value + + FontLoader { id: firaSansSemiBold; source: "../../fonts/FiraSans-SemiBold.ttf"; } + font.family: firaSansSemiBold.name + font.pixelSize: hifi.fontSizes.textFieldInput + height: hifi.dimensions.tableRowHeight + + style: TextFieldStyle { + textColor: readOnly + ? hifi.colors.black + : (treeView.isLightColorScheme ? hifi.colors.black : hifi.colors.white) + background: Rectangle { + visible: !readOnly + color: treeView.isLightColorScheme ? hifi.colors.white : hifi.colors.black + border.color: hifi.colors.primaryHighlight + border.width: 1 + } + selectedTextColor: hifi.colors.black + selectionColor: hifi.colors.primaryHighlight + padding.left: readOnly ? 0 : hifi.dimensions.textPadding + padding.right: readOnly ? 0 : hifi.dimensions.textPadding + } + + validator: RegExpValidator { + regExp: /[^/]+/ + } + + Keys.onPressed: { + if (event.key == Qt.Key_Escape) { + text = styleData.value; + unfocusHelper.forceActiveFocus(); + event.accepted = true; + } + } + onAccepted: { + console.log("Data " + acceptableInput + " " + styleData.selected); + console.log("Index " + selection.currentIndex + " " + styleData.index); + if (acceptableInput && styleData.selected) { + console.log("Accepted " + styleData.index + " " + text); + if (!modifyEl(selection.currentIndex, text)) { + text = styleData.value; + } + unfocusHelper.forceActiveFocus(); + } + } + } + } + } + + Item { + id: unfocusHelper + visible: false } onDoubleClicked: isExpanded(index) ? collapse(index) : expand(index)