forked from qt-creator/qt-creator
QmlDesigner: Show and edit texture name instead of ID in MaterialBrowser
Task-number: QDS-13024 Change-Id: I7cb223caf1577942fc273004f0e08df5569c2af0 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -23,7 +23,7 @@ TextInput {
|
|||||||
selectedTextColor: StudioTheme.Values.themeTextSelectedTextColor
|
selectedTextColor: StudioTheme.Values.themeTextSelectedTextColor
|
||||||
|
|
||||||
// allow only alphanumeric characters, underscores, no space at start, and 1 space between words
|
// allow only alphanumeric characters, underscores, no space at start, and 1 space between words
|
||||||
validator: RegExpValidator { regExp: /^(\w+\s)*\w+$/ }
|
validator: RegularExpressionValidator { regularExpression: /^(\w+\s)*\w+$/ }
|
||||||
|
|
||||||
signal renamed(string newName)
|
signal renamed(string newName)
|
||||||
signal clicked()
|
signal clicked()
|
||||||
|
@@ -16,7 +16,7 @@ Item {
|
|||||||
signal showContextMenu()
|
signal showContextMenu()
|
||||||
|
|
||||||
function forceFinishEditing() {
|
function forceFinishEditing() {
|
||||||
txtId.commitRename()
|
txtName.commitRename()
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
@@ -76,16 +76,14 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MaterialBrowserItemName {
|
MaterialBrowserItemName {
|
||||||
id: txtId
|
id: txtName
|
||||||
|
|
||||||
text: textureId
|
text: textureName
|
||||||
width: img.width
|
width: img.width
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
validator: RegularExpressionValidator { regularExpression: /(^$|^[a-z_]\w*$)/ }
|
onRenamed: (newName) => {
|
||||||
|
MaterialBrowserBackend.materialBrowserTexturesModel.setTextureName(index, newName);
|
||||||
onRenamed: (newId) => {
|
|
||||||
MaterialBrowserBackend.materialBrowserTexturesModel.setTextureId(index, newId);
|
|
||||||
mouseArea.forceActiveFocus()
|
mouseArea.forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -34,30 +34,30 @@ QVariant MaterialBrowserTexturesModel::data(const QModelIndex &index, int role)
|
|||||||
QTC_ASSERT(index.isValid() && index.row() < m_textureList.size(), return {});
|
QTC_ASSERT(index.isValid() && index.row() < m_textureList.size(), return {});
|
||||||
QTC_ASSERT(roleNames().contains(role), return {});
|
QTC_ASSERT(roleNames().contains(role), return {});
|
||||||
|
|
||||||
if (role == RoleTexSource) {
|
switch (role) {
|
||||||
|
case RoleTexVisible:
|
||||||
|
return isVisible(index.row());
|
||||||
|
case RoleTexHasDynamicProps:
|
||||||
|
return !m_textureList.at(index.row()).dynamicProperties().isEmpty();
|
||||||
|
case RoleTexInternalId:
|
||||||
|
return m_textureList.at(index.row()).internalId();
|
||||||
|
case RoleTexName:
|
||||||
|
return m_textureList.at(index.row()).variantProperty("objectName").value();
|
||||||
|
case RoleTexSource: {
|
||||||
QString source = QmlObjectNode(m_textureList.at(index.row())).modelValue("source").toString();
|
QString source = QmlObjectNode(m_textureList.at(index.row())).modelValue("source").toString();
|
||||||
if (source.isEmpty())
|
if (source.isEmpty())
|
||||||
return {};
|
return {};
|
||||||
if (Utils::FilePath::fromString(source).isAbsolutePath())
|
if (Utils::FilePath::fromString(source).isAbsolutePath())
|
||||||
return QVariant(source);
|
return QVariant(source);
|
||||||
return QVariant(QmlDesignerPlugin::instance()->documentManager().currentDesignDocument()
|
return QVariant(QmlDesignerPlugin::instance()
|
||||||
->fileName().absolutePath().pathAppended(source).cleanPath().toString());
|
->documentManager()
|
||||||
}
|
.currentDesignDocument()
|
||||||
|
->fileName()
|
||||||
if (role == RoleTexVisible)
|
.absolutePath()
|
||||||
return isVisible(index.row());
|
.pathAppended(source)
|
||||||
|
.toFSPathString());
|
||||||
if (role == RoleTexHasDynamicProps)
|
};
|
||||||
return !m_textureList.at(index.row()).dynamicProperties().isEmpty();
|
case RoleTexToolTip: {
|
||||||
|
|
||||||
if (role == RoleTexInternalId)
|
|
||||||
return m_textureList.at(index.row()).internalId();
|
|
||||||
|
|
||||||
if (role == RoleTexId) {
|
|
||||||
return m_textureList.at(index.row()).id();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (role == RoleTexToolTip) {
|
|
||||||
QString source = data(index, RoleTexSource).toString(); // absolute path
|
QString source = data(index, RoleTexSource).toString(); // absolute path
|
||||||
if (source.isEmpty())
|
if (source.isEmpty())
|
||||||
return tr("Texture has no source image.");
|
return tr("Texture has no source image.");
|
||||||
@@ -68,11 +68,13 @@ QVariant MaterialBrowserTexturesModel::data(const QModelIndex &index, int role)
|
|||||||
if (info.isEmpty())
|
if (info.isEmpty())
|
||||||
return tr("Texture has no data.");
|
return tr("Texture has no data.");
|
||||||
|
|
||||||
|
QString textName = data(index, RoleTexName).toString();
|
||||||
QString sourceRelative = QmlObjectNode(texNode).modelValue("source").toString();
|
QString sourceRelative = QmlObjectNode(texNode).modelValue("source").toString();
|
||||||
return QLatin1String("%1\n%2\n%3").arg(texNode.id(), sourceRelative, info);
|
return QLatin1String("%1 (%2)\n%3\n%4").arg(textName, texNode.id(), sourceRelative, info);
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MaterialBrowserTexturesModel::isVisible(int idx) const
|
bool MaterialBrowserTexturesModel::isVisible(int idx) const
|
||||||
@@ -91,13 +93,13 @@ bool MaterialBrowserTexturesModel::isValidIndex(int idx) const
|
|||||||
|
|
||||||
QHash<int, QByteArray> MaterialBrowserTexturesModel::roleNames() const
|
QHash<int, QByteArray> MaterialBrowserTexturesModel::roleNames() const
|
||||||
{
|
{
|
||||||
static const QHash<int, QByteArray> roles {
|
static const QHash<int, QByteArray> roles{
|
||||||
{RoleTexHasDynamicProps, "hasDynamicProperties"},
|
{RoleTexHasDynamicProps, "hasDynamicProperties"},
|
||||||
{RoleTexInternalId, "textureInternalId"},
|
{RoleTexInternalId, "textureInternalId"},
|
||||||
{RoleTexId, "textureId"},
|
{RoleTexName, "textureName"},
|
||||||
{RoleTexSource, "textureSource"},
|
{RoleTexSource, "textureSource"},
|
||||||
{RoleTexToolTip, "textureToolTip"},
|
{RoleTexToolTip, "textureToolTip"},
|
||||||
{RoleTexVisible, "textureVisible"}
|
{RoleTexVisible, "textureVisible"},
|
||||||
};
|
};
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
@@ -210,7 +212,14 @@ void MaterialBrowserTexturesModel::updateTextureId(const ModelNode &texture)
|
|||||||
{
|
{
|
||||||
int idx = textureIndex(texture);
|
int idx = textureIndex(texture);
|
||||||
if (idx != -1)
|
if (idx != -1)
|
||||||
emit dataChanged(index(idx, 0), index(idx, 0), {RoleTexId, RoleTexSource, RoleTexToolTip});
|
emit dataChanged(index(idx, 0), index(idx, 0), {RoleTexToolTip});
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialBrowserTexturesModel::updateTextureName(const ModelNode &texture)
|
||||||
|
{
|
||||||
|
int idx = textureIndex(texture);
|
||||||
|
if (idx != -1)
|
||||||
|
emit dataChanged(index(idx, 0), index(idx, 0), {RoleTexName, RoleTexToolTip});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialBrowserTexturesModel::updateAllTexturesSources()
|
void MaterialBrowserTexturesModel::updateAllTexturesSources()
|
||||||
@@ -311,7 +320,7 @@ void MaterialBrowserTexturesModel::deleteTexture(int idx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialBrowserTexturesModel::setTextureId(int idx, const QString &newId)
|
void MaterialBrowserTexturesModel::setTextureName(int idx, const QString &newName)
|
||||||
{
|
{
|
||||||
if (!isValidIndex(idx))
|
if (!isValidIndex(idx))
|
||||||
return;
|
return;
|
||||||
@@ -320,14 +329,17 @@ void MaterialBrowserTexturesModel::setTextureId(int idx, const QString &newId)
|
|||||||
if (!node.isValid())
|
if (!node.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (node.id() != newId) {
|
VariantProperty objectNameProperty = node.variantProperty("objectName");
|
||||||
QString nodeId;
|
QString oldName = objectNameProperty.value().toString();
|
||||||
if (!newId.isEmpty()) {
|
|
||||||
const auto model = m_view->model();
|
if (oldName != newName) {
|
||||||
QTC_ASSERT(model, return);
|
const Model *model = m_view->model();
|
||||||
nodeId = model->generateNewId(newId);
|
QTC_ASSERT(model, return);
|
||||||
}
|
|
||||||
node.setIdWithRefactoring(nodeId);
|
m_view->executeInTransaction(__FUNCTION__, [&] {
|
||||||
|
node.setIdWithRefactoring(model->generateNewId(newName, "texture"));
|
||||||
|
objectNameProperty.setValue(newName);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -39,6 +39,7 @@ public:
|
|||||||
void updateSelectedTexture();
|
void updateSelectedTexture();
|
||||||
void updateTextureSource(const ModelNode &texture);
|
void updateTextureSource(const ModelNode &texture);
|
||||||
void updateTextureId(const ModelNode &texture);
|
void updateTextureId(const ModelNode &texture);
|
||||||
|
void updateTextureName(const ModelNode &texture);
|
||||||
void updateAllTexturesSources();
|
void updateAllTexturesSources();
|
||||||
int textureIndex(const ModelNode &texture) const;
|
int textureIndex(const ModelNode &texture) const;
|
||||||
ModelNode textureAt(int idx) const;
|
ModelNode textureAt(int idx) const;
|
||||||
@@ -58,7 +59,7 @@ public:
|
|||||||
Q_INVOKABLE void addNewTexture();
|
Q_INVOKABLE void addNewTexture();
|
||||||
Q_INVOKABLE void duplicateTexture(int idx);
|
Q_INVOKABLE void duplicateTexture(int idx);
|
||||||
Q_INVOKABLE void deleteTexture(int idx);
|
Q_INVOKABLE void deleteTexture(int idx);
|
||||||
Q_INVOKABLE void setTextureId(int idx, const QString &newId);
|
Q_INVOKABLE void setTextureName(int idx, const QString &newName);
|
||||||
Q_INVOKABLE void applyToSelectedMaterial(qint64 internalId);
|
Q_INVOKABLE void applyToSelectedMaterial(qint64 internalId);
|
||||||
Q_INVOKABLE void applyToSelectedModel(qint64 internalId);
|
Q_INVOKABLE void applyToSelectedModel(qint64 internalId);
|
||||||
Q_INVOKABLE void openTextureEditor();
|
Q_INVOKABLE void openTextureEditor();
|
||||||
@@ -97,7 +98,7 @@ private:
|
|||||||
enum {
|
enum {
|
||||||
RoleTexHasDynamicProps = Qt::UserRole + 1,
|
RoleTexHasDynamicProps = Qt::UserRole + 1,
|
||||||
RoleTexInternalId,
|
RoleTexInternalId,
|
||||||
RoleTexId,
|
RoleTexName,
|
||||||
RoleTexSource,
|
RoleTexSource,
|
||||||
RoleTexToolTip,
|
RoleTexToolTip,
|
||||||
RoleTexVisible
|
RoleTexVisible
|
||||||
|
@@ -290,11 +290,15 @@ void MaterialBrowserView::updatePropertyList(const QList<T> &propertyList)
|
|||||||
m_widget->materialBrowserModel()->updateMaterialName(node);
|
m_widget->materialBrowserModel()->updateMaterialName(node);
|
||||||
else
|
else
|
||||||
m_previewRequests << node;
|
m_previewRequests << node;
|
||||||
} else if (property.name() == "source") {
|
} else if (isTexture(node)) {
|
||||||
QmlObjectNode selectedTex = m_widget->materialBrowserTexturesModel()->selectedTexture();
|
QmlObjectNode selectedTex = m_widget->materialBrowserTexturesModel()->selectedTexture();
|
||||||
if (isTexture(node))
|
if (property.name() == "source")
|
||||||
m_widget->materialBrowserTexturesModel()->updateTextureSource(node);
|
m_widget->materialBrowserTexturesModel()->updateTextureSource(node);
|
||||||
else if (selectedTex.propertyChangeForCurrentState() == node)
|
else if (property.name() == "objectName")
|
||||||
|
m_widget->materialBrowserTexturesModel()->updateTextureName(node);
|
||||||
|
} else {
|
||||||
|
QmlObjectNode selectedTex = m_widget->materialBrowserTexturesModel()->selectedTexture();
|
||||||
|
if (property.name() == "source" && selectedTex.propertyChangeForCurrentState() == node)
|
||||||
m_widget->materialBrowserTexturesModel()->updateTextureSource(selectedTex);
|
m_widget->materialBrowserTexturesModel()->updateTextureSource(selectedTex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -48,6 +48,43 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QColorDialog>
|
#include <QColorDialog>
|
||||||
|
|
||||||
|
using namespace Qt::StringLiterals;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
QString nameFromId(const QString &id, const QString &defaultName)
|
||||||
|
{
|
||||||
|
if (id.isEmpty())
|
||||||
|
return defaultName;
|
||||||
|
|
||||||
|
QString newName = id;
|
||||||
|
static const QRegularExpression sideUnderscores{R"((?:^_+)|(?:_+$))"};
|
||||||
|
static const QRegularExpression underscores{R"((?:_+))"};
|
||||||
|
static const QRegularExpression camelCases{R"((?:[A-Z](?=[a-z]))|(?:(?<=[a-z])[A-Z]))"};
|
||||||
|
|
||||||
|
newName.remove(sideUnderscores);
|
||||||
|
|
||||||
|
// Insert underscore to camel case edges
|
||||||
|
QRegularExpressionMatchIterator caseMatch = camelCases.globalMatch(newName);
|
||||||
|
QStack<int> camelCaseIndexes;
|
||||||
|
while (caseMatch.hasNext())
|
||||||
|
camelCaseIndexes.push(caseMatch.next().capturedStart());
|
||||||
|
while (!camelCaseIndexes.isEmpty())
|
||||||
|
newName.insert(camelCaseIndexes.pop(), '_');
|
||||||
|
|
||||||
|
// Replace underscored joints with space
|
||||||
|
newName.replace(underscores, " ");
|
||||||
|
newName = newName.trimmed();
|
||||||
|
|
||||||
|
if (newName.isEmpty())
|
||||||
|
return defaultName;
|
||||||
|
|
||||||
|
newName[0] = newName[0].toUpper();
|
||||||
|
return newName;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
TextureEditorView::TextureEditorView(AsynchronousImageCache &imageCache,
|
TextureEditorView::TextureEditorView(AsynchronousImageCache &imageCache,
|
||||||
@@ -389,6 +426,8 @@ void TextureEditorView::handleToolBarAction(int action)
|
|||||||
metaInfo.minorVersion());
|
metaInfo.minorVersion());
|
||||||
#endif
|
#endif
|
||||||
newTextureNode.ensureIdExists();
|
newTextureNode.ensureIdExists();
|
||||||
|
VariantProperty textureName = newTextureNode.variantProperty("objectName");
|
||||||
|
textureName.setValue(nameFromId(newTextureNode.id(), "Texture"_L1));
|
||||||
matLib.defaultNodeListProperty().reparentHere(newTextureNode);
|
matLib.defaultNodeListProperty().reparentHere(newTextureNode);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user