[ui] Inspector3D: add media contextual menu

Contextual menu to expose additional actions:
 * open media containing folder
 * copy media path
 * advanced manual control over media (un)loading
+ fix MediaLibrary to avoid binding loop on 'visible' when directly modifying 'request' property
This commit is contained in:
Yann Lanthony 2018-12-10 13:23:20 +01:00
parent 272cd24fb9
commit c3750a33c3
3 changed files with 37 additions and 5 deletions

View file

@ -72,3 +72,9 @@ class FilepathHelper(QObject):
def stringToUrl(self, path): def stringToUrl(self, path):
""" Convert a path (string) to a QUrl using 'QUrl.fromLocalFile' method """ """ Convert a path (string) to a QUrl using 'QUrl.fromLocalFile' method """
return QUrl.fromLocalFile(path) return QUrl.fromLocalFile(path)
@Slot(str, result=str)
@Slot(QUrl, result=str)
def normpath(self, path):
""" Returns native normalized path """
return os.path.normpath(self.asStr(path))

View file

@ -193,7 +193,7 @@ FloatingPane {
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
text: model.visible ? MaterialIcons.visibility : MaterialIcons.visibility_off text: model.visible ? MaterialIcons.visibility : MaterialIcons.visibility_off
font.pointSize: 10 font.pointSize: 10
ToolTip.text: model.visible ? "Hide" : "Show" ToolTip.text: model.visible ? "Hide" : model.requested ? "Show" : model.valid ? "Load and Show" : "Load and Show when Available"
flat: true flat: true
opacity: model.visible ? 1.0 : 0.6 opacity: model.visible ? 1.0 : 0.6
onClicked: { onClicked: {
@ -272,6 +272,7 @@ FloatingPane {
id: mouseArea id: mouseArea
anchors.fill: centralLayout anchors.fill: centralLayout
hoverEnabled: true hoverEnabled: true
acceptedButtons: Qt.AllButtons
onEntered: { if(model.attribute) uigraph.hoveredNode = model.attribute.node } onEntered: { if(model.attribute) uigraph.hoveredNode = model.attribute.node }
onExited: { if(model.attribute) uigraph.hoveredNode = null } onExited: { if(model.attribute) uigraph.hoveredNode = null }
onClicked: { onClicked: {
@ -279,6 +280,8 @@ FloatingPane {
uigraph.selectedNode = model.attribute.node; uigraph.selectedNode = model.attribute.node;
else else
uigraph.selectedNode = null; uigraph.selectedNode = null;
if(mouse.button == Qt.RightButton)
contextMenu.popup();
mediaListView.currentIndex = index; mediaListView.currentIndex = index;
} }
onDoubleClicked: { onDoubleClicked: {
@ -286,6 +289,27 @@ FloatingPane {
camera.viewEntity(mediaLibrary.entityAt(index)); camera.viewEntity(mediaLibrary.entityAt(index));
} }
} }
Menu {
id: contextMenu
MenuItem {
text: "Open Containing Folder"
enabled: model.valid
onTriggered: Qt.openUrlExternally(Filepath.dirname(model.source))
}
MenuItem {
text: "Copy Path"
// hidden TextEdit to copy to clipboard
TextEdit { id: fullpath; visible: false; text: Filepath.normpath(model.source) }
onTriggered: { fullpath.selectAll(); fullpath.copy(); }
}
MenuSeparator {}
MenuItem {
text: model.requested ? "Unload Media" : "Load Media"
enabled: model.valid
onTriggered: model.requested = !model.requested
}
}
} }
// Media unavailability indicator // Media unavailability indicator

View file

@ -194,10 +194,8 @@ Entity {
if(attribute) { if(attribute) {
model.source = rawSource; model.source = rawSource;
} }
// auto-restore entity if raw source is in cache ... // auto-restore entity if raw source is in cache
model.requested = forceRequest || (!model.valid && model.requested) || cache.contains(rawSource); model.requested = forceRequest || (!model.valid && model.requested) || cache.contains(rawSource);
// ... and update media visibility (useful if media was hidden but loaded back from cache)
model.visible = model.requested;
model.valid = Filepath.exists(rawSource) && dependencyReady; model.valid = Filepath.exists(rawSource) && dependencyReady;
} }
@ -211,9 +209,13 @@ Entity {
remove(index) remove(index)
} }
onCurrentSourceChanged: updateModelAndCache() onCurrentSourceChanged: updateModelAndCache(false)
onFinalSourceChanged: { onFinalSourceChanged: {
// update media visibility
// (useful if media was explicitly unloaded or hidden but loaded back from cache)
model.visible = model.requested;
var cachedObject = cache.pop(rawSource); var cachedObject = cache.pop(rawSource);
cached = cachedObject !== undefined; cached = cachedObject !== undefined;
if(cached) { if(cached) {