Added support for translating variables types in the variable manager

Signed-off-by: lsemp3d <58790905+lsemp3d@users.noreply.github.com>
This commit is contained in:
lsemp3d
2021-11-29 18:22:53 -08:00
parent 3922280cec
commit 8e472a030b
8 changed files with 1577 additions and 443 deletions
@@ -8,15 +8,8 @@
#pragma once
#include <QCoreApplication>
#include <AzCore/Serialization/Json/StackedString.h>
#include <AzCore/std/string/conversions.h>
#include <ScriptCanvas/Core/Slot.h>
#include <Source/Translation/TranslationBus.h>
#include <AzFramework/Gem/GemInfo.h>
#include <AzCore/Settings/SettingsRegistry.h>
#include <ScriptCanvas/Data/Data.h>
namespace Translation
{
@@ -27,447 +20,32 @@ namespace Translation
static constexpr const char* MissingFunctionKey = "Globals.MissingFunction";
static constexpr const char* EBusHandlerOutSlot = "Globals.EBusHandler.OutSlot";
}
static inline bool GetValue(const AZStd::string key, AZStd::string& value)
{
GraphCanvas::TranslationKey tkey;
tkey = key;
bool result = false;
GraphCanvas::TranslationRequestBus::BroadcastResult(result, &GraphCanvas::TranslationRequests::Get, key, value);
return result;
}
}
namespace GraphCanvasAttributeHelper
{
template <typename T>
AZStd::string GetStringAttribute(const T* source, const AZ::Crc32& attribute)
{
AZStd::string attributeValue = "";
if (auto attributeItem = azrtti_cast<AZ::AttributeData<AZStd::string>*>(AZ::FindAttribute(attribute, source->m_attributes)))
{
attributeValue = attributeItem->Get(nullptr);
}
return attributeValue;
}
inline AZStd::string ReadStringAttribute(const AZ::AttributeArray& attributes, const AZ::Crc32& attribute)
{
AZStd::string attributeValue = "";
if (auto attributeItem = azrtti_cast<AZ::AttributeData<AZStd::string>*>(AZ::FindAttribute(attribute, attributes)))
{
attributeValue = attributeItem->Get(nullptr);
return attributeValue;
}
if (auto attributeItem = azrtti_cast<AZ::AttributeData<const char*>*>(AZ::FindAttribute(attribute, attributes)))
{
attributeValue = attributeItem->Get(nullptr);
return attributeValue;
}
return {};
}
}
namespace ScriptCanvasEditor
{
enum class TranslationContextGroup : AZ::u32
namespace TranslationHelper
{
EbusSender,
EbusHandler,
ClassMethod,
GlobalMethod,
Invalid
};
enum class TranslationItemType : AZ::u32
{
Node,
Wrapper,
ExecutionInSlot,
ExecutionOutSlot,
ParamDataSlot,
ReturnDataSlot,
BusIdSlot,
Invalid
};
enum class TranslationKeyId : AZ::u32
{
Name,
Tooltip,
Category,
Invalid
};
namespace TranslationKeyParts
{
const char* const handler = "HANDLER_";
const char* const name = "NAME";
const char* const tooltip = "TOOLTIP";
const char* const category = "CATEGORY";
const char* const in = "IN";
const char* const out = "OUT";
const char* const param = "PARAM";
const char* const output = "OUTPUT";
const char* const busid = "BUSID";
}
namespace TranslationContextGroupParts
{
const char* const ebusSender = "EBus";
const char* const ebusHandler = "Handler";
const char* const classMethod = "Method";
constexpr const char* const globalMethod = "GlobalMethod";
};
// The context name and keys generated by TranslationHelper should match the keys
// being exported by the TSGenerateAction.cpp in the ScriptCanvasDeveloper Gem.
class TranslationHelper
{
public:
static AZStd::string GetContextName(TranslationContextGroup group, AZStd::string_view keyBase)
{
if (group == TranslationContextGroup::Invalid || keyBase.empty())
{
// Missing information
return AZStd::string();
}
const char* groupPart;
switch (group)
{
case TranslationContextGroup::EbusSender:
groupPart = TranslationContextGroupParts::ebusSender;
break;
case TranslationContextGroup::EbusHandler:
groupPart = TranslationContextGroupParts::ebusHandler;
break;
case TranslationContextGroup::ClassMethod:
groupPart = TranslationContextGroupParts::classMethod;
break;
case TranslationContextGroup::GlobalMethod:
groupPart = TranslationContextGroupParts::globalMethod;
break;
default:
AZ_Warning("TranslationComponent", false, "Invalid translation group ID.");
groupPart = "";
}
AZStd::string fullKey = AZStd::string::format("%s: %.*s", groupPart,
aznumeric_cast<int>(keyBase.size()), keyBase.data());
return fullKey;
}
// UserDefined
static AZStd::string GetUserDefinedNodeKey(AZStd::string_view contextName, AZStd::string_view nodeName, TranslationKeyId keyId)
{
return GetKey(TranslationContextGroup::ClassMethod, contextName, nodeName, TranslationItemType::Node, keyId);
}
////
static AZStd::string GetKey(TranslationContextGroup group, AZStd::string_view keyBase, AZStd::string_view keyName, TranslationItemType type, TranslationKeyId keyId, int paramIndex = 0)
{
if (group == TranslationContextGroup::Invalid || keyBase.empty()
|| type == TranslationItemType::Invalid || keyId == TranslationKeyId::Invalid)
{
// Missing information
return AZStd::string();
}
if (type != TranslationItemType::Wrapper && keyName.empty())
{
// Missing information
return AZStd::string();
}
AZStd::string fullKey;
const char* prefix = "";
if (group == TranslationContextGroup::EbusHandler)
{
prefix = TranslationKeyParts::handler;
}
const char* keyPart = GetKeyPart(keyId);
switch (type)
{
case TranslationItemType::Node:
fullKey = AZStd::string::format("%s%.*s_%.*s_%s",
prefix,
aznumeric_cast<int>(keyBase.size()),
keyBase.data(),
aznumeric_cast<int>(keyName.size()),
keyName.data(),
keyPart
);
break;
case TranslationItemType::Wrapper:
fullKey = GetClassKey(group, keyBase, keyId);
break;
case TranslationItemType::ExecutionInSlot:
fullKey = AZStd::string::format("%s%.*s_%.*s_%s_%s",
prefix,
aznumeric_cast<int>(keyBase.size()),
keyBase.data(),
aznumeric_cast<int>(keyName.size()),
keyName.data(),
TranslationKeyParts::in,
keyPart
);
break;
case TranslationItemType::ExecutionOutSlot:
fullKey = AZStd::string::format("%s%.*s_%.*s_%s_%s",
prefix,
aznumeric_cast<int>(keyBase.size()),
keyBase.data(),
aznumeric_cast<int>(keyName.size()),
keyName.data(),
TranslationKeyParts::out,
keyPart
);
break;
case TranslationItemType::ParamDataSlot:
fullKey = AZStd::string::format("%s%.*s_%.*s_%s%d_%s",
prefix,
aznumeric_cast<int>(keyBase.size()),
keyBase.data(),
aznumeric_cast<int>(keyName.size()),
keyName.data(),
TranslationKeyParts::param,
paramIndex,
keyPart
);
break;
case TranslationItemType::ReturnDataSlot:
fullKey = AZStd::string::format("%s%.*s_%.*s_%s%d_%s",
prefix,
aznumeric_cast<int>(keyBase.size()),
keyBase.data(),
aznumeric_cast<int>(keyName.size()),
keyName.data(),
TranslationKeyParts::output,
paramIndex,
keyPart
);
break;
case TranslationItemType::BusIdSlot:
fullKey = AZStd::string::format("%s%.*s_%.*s_%s_%s",
prefix,
aznumeric_cast<int>(keyBase.size()),
keyBase.data(),
aznumeric_cast<int>(keyName.size()),
keyName.data(),
TranslationKeyParts::busid,
keyPart
);
break;
default:
AZ_Warning("ScriptCanvas TranslationHelper", false, "Invalid translation item type.");
}
AZStd::to_upper(fullKey.begin(), fullKey.end());
return fullKey;
}
static AZStd::string GetClassKey(TranslationContextGroup group, AZStd::string_view keyBase, TranslationKeyId keyId)
{
const char* prefix = "";
if (group == TranslationContextGroup::EbusHandler)
{
prefix = TranslationKeyParts::handler;
}
const char* keyPart = GetKeyPart(keyId);
AZStd::string fullKey = AZStd::string::format("%s%.*s_%s",
prefix,
aznumeric_cast<int>(keyBase.size()),
keyBase.data(),
keyPart
);
AZStd::to_upper(fullKey.begin(), fullKey.end());
return fullKey;
}
static AZStd::string GetGlobalMethodKey(AZStd::string_view keyName, TranslationItemType keyType,
TranslationKeyId keyId, int paramIndex = 0)
{
const char* keyPart = GetKeyPart(keyId);
AZStd::string fullKey;
switch (keyType)
{
case TranslationItemType::Node:
fullKey = AZStd::string::format("%.*s_%s",
aznumeric_cast<int>(keyName.size()),
keyName.data(),
keyPart
);
break;
case TranslationItemType::ExecutionInSlot:
fullKey = AZStd::string::format("%.*s_%s_%s",
aznumeric_cast<int>(keyName.size()),
keyName.data(),
TranslationKeyParts::in,
keyPart
);
break;
case TranslationItemType::ExecutionOutSlot:
fullKey = AZStd::string::format("%.*s_%s_%s",
aznumeric_cast<int>(keyName.size()),
keyName.data(),
TranslationKeyParts::out,
keyPart
);
break;
case TranslationItemType::ParamDataSlot:
fullKey = AZStd::string::format("%.*s_%s%d_%s",
aznumeric_cast<int>(keyName.size()),
keyName.data(),
TranslationKeyParts::param,
paramIndex,
keyPart
);
break;
case TranslationItemType::ReturnDataSlot:
fullKey = AZStd::string::format("%.*s_%s%d_%s",
aznumeric_cast<int>(keyName.size()),
keyName.data(),
TranslationKeyParts::output,
paramIndex,
keyPart
);
break;
default:
AZ_Warning("ScriptCanvas TranslationHelper", false, "Invalid translation item type.");
}
AZStd::to_upper(fullKey.begin(), fullKey.end());
return fullKey;
}
static const char* GetKeyPart(TranslationKeyId keyId)
{
const char* keyPart = "";
switch (keyId)
{
case TranslationKeyId::Name:
keyPart = TranslationKeyParts::name;
break;
case TranslationKeyId::Tooltip:
keyPart = TranslationKeyParts::tooltip;
break;
case TranslationKeyId::Category:
keyPart = TranslationKeyParts::category;
break;
default:
AZ_Warning("ScriptCanvas TranslationHelper", false, "Invalid translation key ID.");
}
return keyPart;
}
static TranslationItemType GetItemType(ScriptCanvas::SlotDescriptor slotDescriptor)
{
if (slotDescriptor == ScriptCanvas::SlotDescriptors::ExecutionIn())
{
return TranslationItemType::ExecutionInSlot;
}
else if (slotDescriptor == ScriptCanvas::SlotDescriptors::ExecutionOut())
{
return TranslationItemType::ExecutionOutSlot;
}
else if (slotDescriptor == ScriptCanvas::SlotDescriptors::DataIn())
{
return TranslationItemType::ParamDataSlot;
}
else if (slotDescriptor == ScriptCanvas::SlotDescriptors::DataOut())
{
return TranslationItemType::ReturnDataSlot;
}
return TranslationItemType::Invalid;
}
static AZStd::string GetSafeTypeName(ScriptCanvas::Data::Type dataType)
inline AZStd::string GetSafeTypeName(ScriptCanvas::Data::Type dataType)
{
if (!dataType.IsValid())
{
return "";
}
return ScriptCanvas::Data::GetName(dataType);
AZStd::string azType = dataType.GetAZType().ToString<AZStd::string>();
GraphCanvas::TranslationKey key;
key << "BehaviorType" << azType << "details";
GraphCanvas::TranslationRequests::Details details;
details.m_name = ScriptCanvas::Data::GetName(dataType);
GraphCanvas::TranslationRequestBus::BroadcastResult(details, &GraphCanvas::TranslationRequests::GetDetails, key, details);
return details.m_name;
}
static AZStd::string GetKeyTranslation(TranslationContextGroup group, AZStd::string_view keyBase, AZStd::string_view keyName, TranslationItemType type, TranslationKeyId keyId, int paramIndex = 0)
{
AZStd::string translationContext = TranslationHelper::GetContextName(group, keyBase);
AZStd::string translationKey = TranslationHelper::GetKey(group, keyBase, keyName, type, keyId, paramIndex);
AZStd::string translated = QCoreApplication::translate(translationContext.c_str(), translationKey.c_str()).toUtf8().data();
if (translated == translationKey)
{
return AZStd::string();
}
return translated;
}
static AZStd::string GetClassKeyTranslation(TranslationContextGroup group, AZStd::string_view keyBase, TranslationKeyId keyId)
{
AZStd::string translationContext = TranslationHelper::GetContextName(group, keyBase);
AZStd::string translationKey = TranslationHelper::GetClassKey(group, keyBase, keyId);
AZStd::string translated = QCoreApplication::translate(translationContext.c_str(), translationKey.c_str()).toUtf8().data();
if (translated == translationKey)
{
return AZStd::string();
}
return translated;
}
static AZStd::string GetGlobalMethodKeyTranslation(AZStd::string_view keyName,
TranslationItemType keyType, TranslationKeyId keyId, int paramIndex = 0)
{
AZStd::string translationKey = TranslationHelper::GetGlobalMethodKey(keyName, keyType, keyId, paramIndex);
AZStd::string translated = QCoreApplication::translate(TranslationContextGroupParts::globalMethod, translationKey.c_str()).toUtf8().data();
if (translated == translationKey)
{
return AZStd::string();
}
return translated;
}
// Use the StackedString to index the translation keys as a Json Pointer
static AZ::StackedString GetAzEventHandlerRootPointer(AZStd::string_view eventName)
{
AZ::StackedString path(AZ::StackedString::Format::JsonPointer);
path.Push(eventName);
return path;
}
};
}
}
@@ -243,7 +243,16 @@ namespace ScriptCanvasEditor
AZStd::string DataTypePaletteModel::FindTypeNameForTypeId(const AZ::TypeId& typeId) const
{
return TranslationHelper::GetSafeTypeName(ScriptCanvas::Data::FromAZType(typeId));
GraphCanvas::TranslationKey key;
key << "BehaviorType" << typeId.ToString<AZStd::string>() << "details";
GraphCanvas::TranslationRequests::Details details;
details.m_name = TranslationHelper::GetSafeTypeName(ScriptCanvas::Data::FromAZType(typeId));
GraphCanvas::TranslationRequestBus::BroadcastResult(details, &GraphCanvas::TranslationRequests::GetDetails, key, details);
return details.m_name;
}
void DataTypePaletteModel::TogglePendingPinChange(const AZ::Uuid& azVarType)
@@ -26,12 +26,18 @@
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/UserSettings/UserSettings.h>
#include <AzCore/std/containers/map.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzFramework/Gem/GemInfo.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/AssetBrowser/Entries/ProductAssetBrowserEntry.h>
#include <AzToolsFramework/AssetBrowser/Entries/SourceAssetBrowserEntry.h>
#include <AzToolsFramework/AssetEditor/AssetEditorUtils.h>
#include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
#include <AzQtComponents/Utilities/DesktopUtilities.h>
#include <Editor/Assets/ScriptCanvasAssetHelpers.h>
#include <Editor/Components/IconComponent.h>
#include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
@@ -50,9 +56,11 @@
#include <Editor/View/Widgets/NodePalette/VariableNodePaletteTreeItemTypes.h>
#include <Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.h>
#include <Editor/View/Widgets/ui_ScriptCanvasNodePaletteToolbar.h>
#include <GraphCanvas/Widgets/NodePalette/NodePaletteTreeView.h>
#include <GraphCanvas/Widgets/NodePalette/NodePaletteWidget.h>
#include <GraphCanvas/Widgets/NodePalette/TreeItems/NodePaletteTreeItem.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Core/Attributes.h>
#include <ScriptCanvas/Core/SubgraphInterfaceUtility.h>
@@ -63,7 +71,6 @@
#include <ScriptCanvas/Libraries/Libraries.h>
#include <ScriptCanvas/Utils/NodeUtils.h>
#include <ScriptEvents/ScriptEventsAsset.h>
#include "AzQtComponents/Utilities/DesktopUtilities.h"
namespace ScriptCanvasEditor
{