Merge branch 'development' of https://github.com/aws-lumberyard-dev/o3de into mnaumov/2679
This commit is contained in:
@@ -728,6 +728,7 @@ namespace AZ
|
||||
DestroyReflectionManager();
|
||||
|
||||
static_cast<SettingsRegistryImpl*>(m_settingsRegistry.get())->ClearNotifiers();
|
||||
static_cast<SettingsRegistryImpl*>(m_settingsRegistry.get())->ClearMergeEvents();
|
||||
|
||||
// Uninit and unload any dynamic modules.
|
||||
m_moduleManager->UnloadModules();
|
||||
|
||||
@@ -123,6 +123,36 @@ namespace AZ
|
||||
using NotifyEvent = AZ::Event<AZStd::string_view, Type>;
|
||||
using NotifyEventHandler = typename NotifyEvent::Handler;
|
||||
|
||||
using PreMergeEventCallback = AZStd::function<void(AZStd::string_view path, AZStd::string_view rootKey)>;
|
||||
using PostMergeEventCallback = AZStd::function<void(AZStd::string_view path, AZStd::string_view rootKey)>;
|
||||
using PreMergeEvent = AZ::Event<AZStd::string_view, AZStd::string_view>;
|
||||
using PostMergeEvent = AZ::Event<AZStd::string_view, AZStd::string_view>;
|
||||
using PreMergeEventHandler = typename PreMergeEvent::Handler;
|
||||
using PostMergeEventHandler = typename PostMergeEvent::Handler;
|
||||
|
||||
struct ScopedMergeEvent
|
||||
{
|
||||
ScopedMergeEvent(
|
||||
PreMergeEvent& preMergeEvent, PostMergeEvent& postMergeEvent, AZStd::string_view filePath, AZStd::string_view rootKey)
|
||||
: m_preMergeEvent{ preMergeEvent }
|
||||
, m_postMergeEvent{ postMergeEvent }
|
||||
, m_filePath{ filePath }
|
||||
, m_rootKey{ rootKey }
|
||||
{
|
||||
preMergeEvent.Signal(m_filePath, m_rootKey);
|
||||
}
|
||||
|
||||
~ScopedMergeEvent()
|
||||
{
|
||||
m_postMergeEvent.Signal(m_filePath, m_rootKey);
|
||||
}
|
||||
|
||||
PreMergeEvent& m_preMergeEvent;
|
||||
PostMergeEvent& m_postMergeEvent;
|
||||
AZStd::string_view m_filePath;
|
||||
AZStd::string_view m_rootKey;
|
||||
};
|
||||
|
||||
using VisitorCallback =
|
||||
AZStd::function<VisitResponse(AZStd::string_view path, AZStd::string_view valueName, VisitAction action, Type type)>;
|
||||
//! Base class for the visitor class during traversal over the Settings Registry. The type-agnostic function is always
|
||||
@@ -169,6 +199,20 @@ namespace AZ
|
||||
//! @callback The function to call when an entry gets a new/updated value.
|
||||
[[nodiscard]] virtual NotifyEventHandler RegisterNotifier(NotifyCallback&& callback) = 0;
|
||||
|
||||
//! Register a function that will be called before a file is merged.
|
||||
//! @callback The function to call before a file is merged.
|
||||
[[nodiscard]] virtual PreMergeEventHandler RegisterPreMergeEvent(const PreMergeEventCallback& callback) = 0;
|
||||
//! Register a function that will be called before a file is merged.
|
||||
//! @callback The function to call before a file is merged.
|
||||
[[nodiscard]] virtual PreMergeEventHandler RegisterPreMergeEvent (PreMergeEventCallback&& callback) = 0;
|
||||
|
||||
//! Register a function that will be called after a file is merged.
|
||||
//! @callback The function to call after a file is merged.
|
||||
[[nodiscard]] virtual PostMergeEventHandler RegisterPostMergeEvent(const PostMergeEventCallback& callback) = 0;
|
||||
//! Register a function that will be called after a file is merged.
|
||||
//! @callback The function to call after a file is merged.
|
||||
[[nodiscard]] virtual PostMergeEventHandler RegisterPostMergeEvent (PostMergeEventCallback&& callback) = 0;
|
||||
|
||||
//! Gets the boolean value at the provided path.
|
||||
//! @param result The target to write the result to.
|
||||
//! @param path The path to the value.
|
||||
|
||||
@@ -228,6 +228,53 @@ namespace AZ
|
||||
m_notifiers.DisconnectAllHandlers();
|
||||
}
|
||||
|
||||
auto SettingsRegistryImpl::RegisterPreMergeEvent(const PreMergeEventCallback& callback) -> PreMergeEventHandler
|
||||
{
|
||||
PreMergeEventHandler preMergeHandler{ callback };
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
preMergeHandler.Connect(m_preMergeEvent);
|
||||
}
|
||||
return preMergeHandler;
|
||||
}
|
||||
|
||||
auto SettingsRegistryImpl::RegisterPreMergeEvent(PreMergeEventCallback&& callback) -> PreMergeEventHandler
|
||||
{
|
||||
PreMergeEventHandler preMergeHandler{ AZStd::move(callback) };
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
preMergeHandler.Connect(m_preMergeEvent);
|
||||
}
|
||||
return preMergeHandler;
|
||||
}
|
||||
|
||||
auto SettingsRegistryImpl::RegisterPostMergeEvent(const PostMergeEventCallback& callback) -> PostMergeEventHandler
|
||||
{
|
||||
PostMergeEventHandler postMergeHandler{ callback };
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
postMergeHandler.Connect(m_postMergeEvent);
|
||||
}
|
||||
return postMergeHandler;
|
||||
}
|
||||
|
||||
auto SettingsRegistryImpl::RegisterPostMergeEvent(PostMergeEventCallback&& callback) -> PostMergeEventHandler
|
||||
{
|
||||
PostMergeEventHandler postMergeHandler{ AZStd::move(callback) };
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
postMergeHandler.Connect(m_postMergeEvent);
|
||||
}
|
||||
return postMergeHandler;
|
||||
}
|
||||
|
||||
void SettingsRegistryImpl::ClearMergeEvents()
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
m_preMergeEvent.DisconnectAllHandlers();
|
||||
m_postMergeEvent.DisconnectAllHandlers();
|
||||
}
|
||||
|
||||
void SettingsRegistryImpl::SignalNotifier(AZStd::string_view jsonPath, Type type)
|
||||
{
|
||||
// Move the Notifier AZ::Event to a local AZ::Event in order to allow
|
||||
@@ -1165,6 +1212,8 @@ namespace AZ
|
||||
return false;
|
||||
}
|
||||
|
||||
ScopedMergeEvent scopedMergeEvent(m_preMergeEvent, m_postMergeEvent, path, rootKey);
|
||||
|
||||
JsonSerializationResult::ResultCode mergeResult(JsonSerializationResult::Tasks::Merge);
|
||||
if (rootKey.empty())
|
||||
{
|
||||
|
||||
@@ -48,6 +48,12 @@ namespace AZ
|
||||
[[nodiscard]] NotifyEventHandler RegisterNotifier(NotifyCallback&& callback) override;
|
||||
void ClearNotifiers();
|
||||
|
||||
[[nodiscard]] PreMergeEventHandler RegisterPreMergeEvent(const PreMergeEventCallback& callback) override;
|
||||
[[nodiscard]] PreMergeEventHandler RegisterPreMergeEvent(PreMergeEventCallback&& callback) override;
|
||||
[[nodiscard]] PostMergeEventHandler RegisterPostMergeEvent(const PostMergeEventCallback& callback) override;
|
||||
[[nodiscard]] PostMergeEventHandler RegisterPostMergeEvent(PostMergeEventCallback&& callback) override;
|
||||
void ClearMergeEvents();
|
||||
|
||||
bool Get(bool& result, AZStd::string_view path) const override;
|
||||
bool Get(s64& result, AZStd::string_view path) const override;
|
||||
bool Get(u64& result, AZStd::string_view path) const override;
|
||||
@@ -106,6 +112,9 @@ namespace AZ
|
||||
mutable AZStd::recursive_mutex m_settingMutex;
|
||||
mutable AZStd::recursive_mutex m_notifierMutex;
|
||||
NotifyEvent m_notifiers;
|
||||
PreMergeEvent m_preMergeEvent;
|
||||
PostMergeEvent m_postMergeEvent;
|
||||
|
||||
rapidjson::Document m_settings;
|
||||
JsonSerializerSettings m_serializationSettings;
|
||||
JsonDeserializerSettings m_deserializationSettings;
|
||||
|
||||
@@ -25,6 +25,10 @@ namespace AZ
|
||||
MOCK_CONST_METHOD2(Visit, bool(const VisitorCallback&, AZStd::string_view));
|
||||
MOCK_METHOD1(RegisterNotifier, NotifyEventHandler(const NotifyCallback&));
|
||||
MOCK_METHOD1(RegisterNotifier, NotifyEventHandler(NotifyCallback&&));
|
||||
MOCK_METHOD1(RegisterPreMergeEvent, PreMergeEventHandler(const PreMergeEventCallback&));
|
||||
MOCK_METHOD1(RegisterPreMergeEvent, PreMergeEventHandler(PreMergeEventCallback&&));
|
||||
MOCK_METHOD1(RegisterPostMergeEvent, PostMergeEventHandler(const PostMergeEventCallback&));
|
||||
MOCK_METHOD1(RegisterPostMergeEvent, PostMergeEventHandler(PostMergeEventCallback&&));
|
||||
|
||||
MOCK_CONST_METHOD2(Get, bool(bool&, AZStd::string_view));
|
||||
MOCK_CONST_METHOD2(Get, bool(s64&, AZStd::string_view));
|
||||
|
||||
+11
-3
@@ -207,7 +207,10 @@ namespace AzFramework
|
||||
// Handles Win32 Window Event callbacks
|
||||
LRESULT CALLBACK NativeWindowImpl_Win32::WindowCallback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
NativeWindowImpl_Win32* nativeWindowImpl = reinterpret_cast<NativeWindowImpl_Win32*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
|
||||
NativeWindowImpl_Win32* nativeWindowImpl = reinterpret_cast<NativeWindowImpl_Win32*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
|
||||
|
||||
// If set to true, call DefWindowProc to ensure the default Windows behavior occurs
|
||||
bool shouldBubbleEventUp = false;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
@@ -276,14 +279,19 @@ namespace AzFramework
|
||||
uint32_t refreshRate = DisplayConfig.dmDisplayFrequency;
|
||||
WindowNotificationBus::Event(
|
||||
nativeWindowImpl->GetWindowHandle(), &WindowNotificationBus::Events::OnRefreshRateChanged, refreshRate);
|
||||
shouldBubbleEventUp = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
shouldBubbleEventUp = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (!shouldBubbleEventUp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
void NativeWindowImpl_Win32::WindowSizeChanged(const uint32_t width, const uint32_t height)
|
||||
|
||||
@@ -10,22 +10,9 @@
|
||||
|
||||
namespace AzNetworking
|
||||
{
|
||||
StringifySerializer::StringifySerializer(char delimeter, bool outputFieldNames, const AZStd::string& seperator)
|
||||
: m_delimeter(delimeter)
|
||||
, m_outputFieldNames(outputFieldNames)
|
||||
, m_separator(seperator)
|
||||
const StringifySerializer::ValueMap& StringifySerializer::GetValueMap() const
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
const AZStd::string& StringifySerializer::GetString() const
|
||||
{
|
||||
return m_string;
|
||||
}
|
||||
|
||||
const StringifySerializer::StringMap& StringifySerializer::GetValueMap() const
|
||||
{
|
||||
return m_map;
|
||||
return m_valueMap;
|
||||
}
|
||||
|
||||
SerializerMode StringifySerializer::GetSerializerMode() const
|
||||
@@ -137,22 +124,9 @@ namespace AzNetworking
|
||||
template <typename T>
|
||||
bool StringifySerializer::ProcessData(const char* name, const T& value)
|
||||
{
|
||||
// Only add delimeters after we have processed at least one element
|
||||
if (!m_string.empty())
|
||||
{
|
||||
m_string += m_delimeter;
|
||||
}
|
||||
|
||||
if (m_outputFieldNames)
|
||||
{
|
||||
m_string += m_prefix;
|
||||
m_string += name;
|
||||
m_string += m_separator;
|
||||
}
|
||||
|
||||
AZ::CVarFixedString string = AZ::ConsoleTypeHelpers::ValueToString(value);
|
||||
m_string += string.c_str();
|
||||
m_map[m_prefix + name] = string.c_str();
|
||||
const AZStd::string keyString = m_prefix + name;
|
||||
AZ::CVarFixedString valueString = AZ::ConsoleTypeHelpers::ValueToString(value);
|
||||
m_valueMap[keyString] = valueString.c_str();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,17 +20,12 @@ namespace AzNetworking
|
||||
{
|
||||
public:
|
||||
|
||||
using StringMap = AZStd::map<AZStd::string, AZStd::string>;
|
||||
using ValueMap = AZStd::map<AZStd::string, AZStd::string>;
|
||||
|
||||
StringifySerializer(char delimeter = ' ', bool outputFieldNames = true, const AZStd::string& seperator = "=");
|
||||
StringifySerializer() = default;
|
||||
|
||||
// GetString
|
||||
// After serializing objects, get the serialized values as a single string
|
||||
const AZStd::string& GetString() const;
|
||||
|
||||
// GetValueMap
|
||||
// After serializing objects, get the serialized values as key value pairs
|
||||
const StringMap& GetValueMap() const;
|
||||
//! After serializing objects, get the serialized values as a map of key/value pairs.
|
||||
const ValueMap& GetValueMap() const;
|
||||
|
||||
// ISerializer interfaces
|
||||
SerializerMode GetSerializerMode() const override;
|
||||
@@ -62,15 +57,8 @@ namespace AzNetworking
|
||||
template <typename T>
|
||||
bool ProcessData(const char* name, const T& value);
|
||||
|
||||
private:
|
||||
|
||||
char m_delimeter;
|
||||
bool m_outputFieldNames = true;
|
||||
|
||||
StringMap m_map;
|
||||
AZStd::string m_string;
|
||||
ValueMap m_valueMap;
|
||||
AZStd::string m_prefix;
|
||||
AZStd::string m_separator;
|
||||
AZStd::deque<AZStd::size_t> m_prefixSizeStack;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -841,9 +841,6 @@ namespace AzToolsFramework
|
||||
*/
|
||||
virtual AZStd::string GetComponentIconPath(const AZ::Uuid& /*componentType*/, AZ::Crc32 /*componentIconAttrib*/, AZ::Component* /*component*/) { return AZStd::string(); }
|
||||
|
||||
/// Resource Selector hook, returns a path for a resource.
|
||||
virtual AZStd::string SelectResource(const AZStd::string& /*resourceType*/, const AZStd::string& /*previousValue*/) { return AZStd::string(); }
|
||||
|
||||
/**
|
||||
* Calculate the navigation 2D radius in units of an agent given its Navigation Type Name
|
||||
* @param angentTypeName the name that identifies the agent navigation type
|
||||
|
||||
+20
-29
@@ -162,7 +162,6 @@ namespace AzToolsFramework
|
||||
: QObject(sourceWidget)
|
||||
, m_sourceWidget(sourceWidget)
|
||||
, m_keyboardModifiers(AZStd::make_shared<AzFramework::ModifierKeyStates>())
|
||||
, m_cursorPosition(AZStd::make_shared<AzFramework::InputChannel::PositionData2D>())
|
||||
{
|
||||
InitializeKeyMappings();
|
||||
InitializeMouseButtonMappings();
|
||||
@@ -230,24 +229,17 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
// Because there's no "end" to mouse movement and wheel events, we reset mouse movement channels that have been opened
|
||||
// during the next processed non-mouse event.
|
||||
if (m_mouseChannelsNeedUpdate && event->type() != QEvent::Type::MouseMove && event->type() != QEvent::Type::Wheel)
|
||||
{
|
||||
m_cursorPosition->m_normalizedPositionDelta = AZ::Vector2::CreateZero();
|
||||
ProcessPendingMouseEvents();
|
||||
m_mouseChannelsNeedUpdate = false;
|
||||
}
|
||||
const auto eventType = event->type();
|
||||
|
||||
// Only accept mouse & key release events that originate from an object that is not our target widget,
|
||||
// as we don't want to erroneously intercept user input meant for another component.
|
||||
if (object != m_sourceWidget && event->type() != QEvent::Type::KeyRelease && event->type() != QEvent::Type::MouseButtonRelease)
|
||||
if (object != m_sourceWidget && eventType != QEvent::Type::KeyRelease && eventType != QEvent::Type::MouseButtonRelease)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If our focus changes, go ahead and reset all input devices.
|
||||
if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut)
|
||||
if (eventType == QEvent::FocusIn || eventType == QEvent::FocusOut)
|
||||
{
|
||||
HandleFocusChange(event);
|
||||
}
|
||||
@@ -255,27 +247,28 @@ namespace AzToolsFramework
|
||||
// ShortcutOverride is used in lieu of KeyPress for high priority input channels like Alt
|
||||
// that need to be accepted and stopped before they bubble up and cause unintended behavior.
|
||||
else if (
|
||||
event->type() == QEvent::Type::KeyPress || event->type() == QEvent::Type::KeyRelease ||
|
||||
event->type() == QEvent::Type::ShortcutOverride)
|
||||
eventType == QEvent::Type::KeyPress || eventType == QEvent::Type::KeyRelease || eventType == QEvent::Type::ShortcutOverride)
|
||||
{
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
HandleKeyEvent(keyEvent);
|
||||
}
|
||||
// Map mouse events to input channels.
|
||||
else if (event->type() == QEvent::Type::MouseButtonPress || event->type() == QEvent::Type::MouseButtonRelease || event->type() == QEvent::Type::MouseButtonDblClick)
|
||||
else if (
|
||||
eventType == QEvent::Type::MouseButtonPress || eventType == QEvent::Type::MouseButtonRelease ||
|
||||
eventType == QEvent::Type::MouseButtonDblClick)
|
||||
{
|
||||
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
HandleMouseButtonEvent(mouseEvent);
|
||||
}
|
||||
// Map mouse movement to the movement input channels.
|
||||
// This includes SystemCursorPosition alongside Movement::X and Movement::Y.
|
||||
else if (event->type() == QEvent::Type::MouseMove)
|
||||
else if (eventType == QEvent::Type::MouseMove)
|
||||
{
|
||||
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
HandleMouseMoveEvent(mouseEvent);
|
||||
}
|
||||
// Map wheel events to the mouse Z movement channel.
|
||||
else if (event->type() == QEvent::Type::Wheel)
|
||||
else if (eventType == QEvent::Type::Wheel)
|
||||
{
|
||||
QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event);
|
||||
HandleWheelEvent(wheelEvent);
|
||||
@@ -303,14 +296,16 @@ namespace AzToolsFramework
|
||||
auto mouseWheelChannel =
|
||||
GetInputChannel<AzFramework::InputChannelDeltaWithSharedPosition2D>(AzFramework::InputDeviceMouse::Movement::Z);
|
||||
|
||||
systemCursorChannel->ProcessRawInputEvent(m_cursorPosition->m_normalizedPositionDelta.GetLength());
|
||||
systemCursorChannel->ProcessRawInputEvent(m_mouseDevice->m_cursorPositionData2D->m_normalizedPositionDelta.GetLength());
|
||||
// Generate movement events based on the pixel delta divided by the DPI scaling factor, to calculate a rough approximation
|
||||
// of cursor movement velocity.
|
||||
movementXChannel->ProcessRawInputEvent(
|
||||
m_cursorPosition->m_normalizedPositionDelta.GetX() * aznumeric_cast<float>(m_sourceWidget->width()) / m_sourceWidget->devicePixelRatioF());
|
||||
m_mouseDevice->m_cursorPositionData2D->m_normalizedPositionDelta.GetX() * aznumeric_cast<float>(m_sourceWidget->width()) /
|
||||
m_sourceWidget->devicePixelRatioF());
|
||||
movementYChannel->ProcessRawInputEvent(
|
||||
m_cursorPosition->m_normalizedPositionDelta.GetY() * aznumeric_cast<float>(m_sourceWidget->height()) / m_sourceWidget->devicePixelRatioF());
|
||||
mouseWheelChannel->ProcessRawInputEvent(0.f);
|
||||
m_mouseDevice->m_cursorPositionData2D->m_normalizedPositionDelta.GetY() * aznumeric_cast<float>(m_sourceWidget->height()) /
|
||||
m_sourceWidget->devicePixelRatioF());
|
||||
mouseWheelChannel->ProcessRawInputEvent(0.0f);
|
||||
|
||||
NotifyUpdateChannelIfNotIdle(systemCursorChannel, nullptr);
|
||||
NotifyUpdateChannelIfNotIdle(movementXChannel, nullptr);
|
||||
@@ -358,14 +353,13 @@ namespace AzToolsFramework
|
||||
|
||||
void QtEventToAzInputMapper::HandleMouseMoveEvent(QMouseEvent* mouseEvent)
|
||||
{
|
||||
AZ::Vector2 lastCursorPosition = m_cursorPosition->m_normalizedPosition;
|
||||
AZ::Vector2 lastCursorPosition = m_mouseDevice->m_cursorPositionData2D->m_normalizedPosition;
|
||||
|
||||
const QPoint mousePos = mouseEvent->pos();
|
||||
const AZ::Vector2 normalizedPosition = WidgetPositionToNormalizedPosition(mousePos);
|
||||
m_cursorPosition->m_normalizedPositionDelta = normalizedPosition - m_cursorPosition->m_normalizedPosition;
|
||||
m_cursorPosition->m_normalizedPosition = normalizedPosition;
|
||||
m_mouseDevice->m_cursorPositionData2D->m_normalizedPositionDelta = normalizedPosition - m_mouseDevice->m_cursorPositionData2D->m_normalizedPosition;
|
||||
m_mouseDevice->m_cursorPositionData2D->m_normalizedPosition = normalizedPosition;
|
||||
ProcessPendingMouseEvents();
|
||||
m_mouseChannelsNeedUpdate = true;
|
||||
|
||||
if (m_capturingCursor)
|
||||
{
|
||||
@@ -376,7 +370,7 @@ namespace AzToolsFramework
|
||||
// Even though we just set the cursor position, there are edge cases such as remote desktop that will leave
|
||||
// the cursor position unchanged. For safety, we re-cache our last cursor position for delta generation.
|
||||
QPoint actualWidgetPosition = m_sourceWidget->mapFromGlobal(QCursor::pos());
|
||||
m_cursorPosition->m_normalizedPosition = WidgetPositionToNormalizedPosition(actualWidgetPosition);
|
||||
m_mouseDevice->m_cursorPositionData2D->m_normalizedPosition = WidgetPositionToNormalizedPosition(actualWidgetPosition);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -427,21 +421,18 @@ namespace AzToolsFramework
|
||||
}
|
||||
cursorZChannel->ProcessRawInputEvent(aznumeric_cast<float>(wheelAngle));
|
||||
NotifyUpdateChannelIfNotIdle(cursorZChannel, wheelEvent);
|
||||
m_mouseChannelsNeedUpdate = true;
|
||||
}
|
||||
|
||||
void QtEventToAzInputMapper::HandleFocusChange(QEvent* event)
|
||||
{
|
||||
for (auto& channelData : m_channels)
|
||||
{
|
||||
// If resetting the input device changed the channel state, submit it to the mapped channel list
|
||||
// for processing.
|
||||
// If resetting the input device changed the channel state, submit it to the mapped channel list for processing.
|
||||
if (channelData.second->IsActive())
|
||||
{
|
||||
channelData.second->UpdateState(false);
|
||||
NotifyUpdateChannelIfNotIdle(channelData.second, event);
|
||||
}
|
||||
}
|
||||
m_mouseChannelsNeedUpdate = false;
|
||||
}
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -138,8 +138,6 @@ namespace AzToolsFramework
|
||||
|
||||
// The current keyboard modifier state used by our synthetic key input channels.
|
||||
AZStd::shared_ptr<AzFramework::ModifierKeyStates> m_keyboardModifiers;
|
||||
// The current normalized cursor position used by our synthetic system cursor event.
|
||||
AZStd::shared_ptr<AzFramework::InputChannel::PositionData2D> m_cursorPosition;
|
||||
// A lookup table for Qt key -> AZ input channel.
|
||||
AZStd::unordered_map<Qt::Key, AzFramework::InputChannelId> m_keyMappings;
|
||||
// A lookup table for Qt mouse button -> AZ input channel.
|
||||
@@ -152,8 +150,6 @@ namespace AzToolsFramework
|
||||
AZStd::unordered_map<AzFramework::InputChannelId, AzFramework::InputChannel*> m_channels;
|
||||
// The source widget to map events from, used to calculate the relative mouse position within the widget bounds.
|
||||
QWidget* m_sourceWidget;
|
||||
// Flags when mouse movement channels have been opened and may need to be closed (as there are no movement ended events).
|
||||
bool m_mouseChannelsNeedUpdate = false;
|
||||
// Flags whether or not Qt events should currently be processed.
|
||||
bool m_enabled = true;
|
||||
// Flags whether or not the cursor is being constrained to the source widget (for invisible mouse movement).
|
||||
|
||||
@@ -5,11 +5,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzToolsFramework/Logger/TraceLogger.h>
|
||||
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
|
||||
#include <AzToolsFramework/Logger/TraceLogger.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
@@ -25,6 +23,22 @@ namespace AzToolsFramework
|
||||
|
||||
bool TraceLogger::OnOutput(const char* window, const char* message)
|
||||
{
|
||||
for (const auto& filter : m_windowFilters)
|
||||
{
|
||||
if (AZ::StringFunc::Contains(window, filter))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& filter : m_messageFilters)
|
||||
{
|
||||
if (AZ::StringFunc::Contains(message, filter))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_logFile)
|
||||
{
|
||||
m_logFile->AppendLog(AzFramework::LogFile::SEV_NORMAL, window, message);
|
||||
@@ -36,10 +50,10 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
void TraceLogger::WriteStartupLog(const AZStd::string& logFileName)
|
||||
{
|
||||
void TraceLogger::PrepareLogFile(const AZStd::string& logFileName)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
|
||||
|
||||
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
|
||||
AZ_Assert(fileIO != nullptr, "FileIO should be running at this point");
|
||||
|
||||
@@ -71,4 +85,34 @@ namespace AzToolsFramework
|
||||
m_logFile->FlushLog();
|
||||
}
|
||||
}
|
||||
|
||||
void TraceLogger::AddWindowFilter(const AZStd::string& filter)
|
||||
{
|
||||
m_windowFilters.insert(filter);
|
||||
}
|
||||
|
||||
void TraceLogger::RemoveWindowFilter(const AZStd::string& filter)
|
||||
{
|
||||
m_windowFilters.erase(filter);
|
||||
}
|
||||
|
||||
void TraceLogger::ClearWindowFilter()
|
||||
{
|
||||
m_windowFilters.clear();
|
||||
}
|
||||
|
||||
void TraceLogger::AddMessageFilter(const AZStd::string& filter)
|
||||
{
|
||||
m_messageFilters.insert(filter);
|
||||
}
|
||||
|
||||
void TraceLogger::RemoveMessageFilter(const AZStd::string& filter)
|
||||
{
|
||||
m_messageFilters.erase(filter);
|
||||
}
|
||||
|
||||
void TraceLogger::ClearMessageFilter()
|
||||
{
|
||||
m_messageFilters.clear();
|
||||
}
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -22,8 +22,26 @@ namespace AzToolsFramework
|
||||
TraceLogger();
|
||||
~TraceLogger();
|
||||
|
||||
//! Intalize logging for O3DEToolsApplications
|
||||
void WriteStartupLog(const AZStd::string& logFileName);
|
||||
//! Open log file and dump log sink into it
|
||||
void PrepareLogFile(const AZStd::string& logFileName);
|
||||
|
||||
//! Add filter to ignore messages for windows with matching names
|
||||
void AddWindowFilter(const AZStd::string& filter);
|
||||
|
||||
//! Remove window filter
|
||||
void RemoveWindowFilter(const AZStd::string& filter);
|
||||
|
||||
//! Clear window filters
|
||||
void ClearWindowFilter();
|
||||
|
||||
//! Add filter to ignore messages with matching names
|
||||
void AddMessageFilter(const AZStd::string& filter);
|
||||
|
||||
//! Remove message filter
|
||||
void RemoveMessageFilter(const AZStd::string& filter);
|
||||
|
||||
//! Clear message filters
|
||||
void ClearMessageFilter();
|
||||
|
||||
protected:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -38,6 +56,8 @@ namespace AzToolsFramework
|
||||
AZStd::string message;
|
||||
};
|
||||
AZStd::vector<LogMessage> m_startupLogSink;
|
||||
AZStd::unordered_set<AZStd::string> m_windowFilters;
|
||||
AZStd::unordered_set<AZStd::string> m_messageFilters;
|
||||
AZStd::unique_ptr<AzFramework::LogFile> m_logFile;
|
||||
};
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+40
-1
@@ -6,7 +6,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// Description : For listing available script commands with their descriptions
|
||||
|
||||
#include "ScriptHelpDialog.h"
|
||||
@@ -23,6 +22,7 @@
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/API/EditorPythonConsoleBus.h> // for EditorPythonConsoleInterface
|
||||
#include <AzToolsFramework/API/EditorWindowRequestBus.h>
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
#include <AzToolsFramework/PythonTerminal/ui_ScriptHelpDialog.h>
|
||||
@@ -313,6 +313,45 @@ namespace AzToolsFramework
|
||||
connect(ui->tableView, &ScriptTableView::doubleClicked, this, &CScriptHelpDialog::OnDoubleClick);
|
||||
}
|
||||
|
||||
CScriptHelpDialog* CScriptHelpDialog::GetInstance()
|
||||
{
|
||||
static CScriptHelpDialog* pInstance = nullptr;
|
||||
if (!pInstance)
|
||||
{
|
||||
QMainWindow* mainWindow = GetMainWindowOfCurrentApplication();
|
||||
if (!mainWindow)
|
||||
{
|
||||
AZ_Assert(false, "Failed to find MainWindow.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QWidget* parentWidget = mainWindow->window()
|
||||
? mainWindow->window()
|
||||
: mainWindow; // MainWindow might have a WindowDecorationWrapper parent. Makes a difference on macOS.
|
||||
pInstance = new CScriptHelpDialog(parentWidget);
|
||||
}
|
||||
return pInstance;
|
||||
}
|
||||
|
||||
QMainWindow* CScriptHelpDialog::GetMainWindowOfCurrentApplication()
|
||||
{
|
||||
QWidget* mainWindowWidget = nullptr;
|
||||
EditorWindowRequestBus::BroadcastResult(mainWindowWidget, &EditorWindowRequests::GetAppMainWindow);
|
||||
if (QMainWindow* mainWindow = qobject_cast<QMainWindow*>(mainWindowWidget))
|
||||
{
|
||||
return mainWindow;
|
||||
}
|
||||
|
||||
for (QWidget* topLevelWidget : qApp->topLevelWidgets())
|
||||
{
|
||||
if (QMainWindow* mainWindow = qobject_cast<QMainWindow*>(topLevelWidget))
|
||||
{
|
||||
return mainWindow;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CScriptHelpDialog::OnDoubleClick(const QModelIndex& index)
|
||||
{
|
||||
if (!index.isValid())
|
||||
|
||||
@@ -132,43 +132,13 @@ namespace AzToolsFramework
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static CScriptHelpDialog* GetInstance()
|
||||
{
|
||||
static CScriptHelpDialog* pInstance = nullptr;
|
||||
if (!pInstance)
|
||||
{
|
||||
QMainWindow* mainWindow = GetMainWindowOfCurrentApplication();
|
||||
if (!mainWindow)
|
||||
{
|
||||
AZ_Assert(false, "Failed to find MainWindow.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QWidget* parentWidget = mainWindow->window() ? mainWindow->window() : mainWindow; // MainWindow might have a WindowDecorationWrapper parent. Makes a difference on macOS.
|
||||
pInstance = new CScriptHelpDialog(parentWidget);
|
||||
}
|
||||
return pInstance;
|
||||
}
|
||||
|
||||
static CScriptHelpDialog* GetInstance();
|
||||
private Q_SLOTS:
|
||||
void OnDoubleClick(const QModelIndex&);
|
||||
|
||||
private:
|
||||
static QMainWindow* GetMainWindowOfCurrentApplication()
|
||||
{
|
||||
QMainWindow* mainWindow = nullptr;
|
||||
for (QWidget* w : qApp->topLevelWidgets())
|
||||
{
|
||||
mainWindow = qobject_cast<QMainWindow*>(w);
|
||||
if (mainWindow)
|
||||
{
|
||||
return mainWindow;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
explicit CScriptHelpDialog(QWidget* parent = nullptr);
|
||||
static QMainWindow* GetMainWindowOfCurrentApplication();
|
||||
QScopedPointer<Ui::ScriptDialog> ui;
|
||||
};
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+10
-9
@@ -7,8 +7,8 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "PropertyAudioCtrl.h"
|
||||
#include "PropertyQTConstants.h"
|
||||
#include <UI/PropertyEditor/PropertyAudioCtrl.h>
|
||||
#include <UI/PropertyEditor/PropertyQTConstants.h>
|
||||
|
||||
#include <QtWidgets/QLabel>
|
||||
#include <QtWidgets/QLineEdit>
|
||||
@@ -34,7 +34,7 @@ namespace AzToolsFramework
|
||||
: QWidget(parent)
|
||||
, m_browseEdit(nullptr)
|
||||
, m_mainLayout(nullptr)
|
||||
, m_propertyType(AudioPropertyType::Invalid)
|
||||
, m_propertyType(AudioPropertyType::NumTypes)
|
||||
{
|
||||
// create the gui
|
||||
m_mainLayout = new QHBoxLayout();
|
||||
@@ -96,7 +96,7 @@ namespace AzToolsFramework
|
||||
return;
|
||||
}
|
||||
|
||||
if (type != AudioPropertyType::Invalid)
|
||||
if (type != AudioPropertyType::NumTypes)
|
||||
{
|
||||
m_propertyType = type;
|
||||
}
|
||||
@@ -136,10 +136,11 @@ namespace AzToolsFramework
|
||||
|
||||
void AudioControlSelectorWidget::OnOpenAudioControlSelector()
|
||||
{
|
||||
AZStd::string resourceResult;
|
||||
AZStd::string resourceType(GetResourceSelectorNameFromType(m_propertyType));
|
||||
AZStd::string currentValue(m_controlName.toStdString().c_str());
|
||||
EditorRequests::Bus::BroadcastResult(resourceResult, &EditorRequests::Bus::Events::SelectResource, resourceType, currentValue);
|
||||
AZStd::string resourceResult;
|
||||
AudioControlSelectorRequestBus::EventResult(
|
||||
resourceResult, m_propertyType,
|
||||
&AudioControlSelectorRequestBus::Events::SelectResource, currentValue);
|
||||
SetControlName(QString(resourceResult.c_str()));
|
||||
}
|
||||
|
||||
@@ -167,12 +168,12 @@ namespace AzToolsFramework
|
||||
{
|
||||
case AudioPropertyType::Trigger:
|
||||
return { "AudioTrigger" };
|
||||
case AudioPropertyType::Rtpc:
|
||||
return { "AudioRTPC" };
|
||||
case AudioPropertyType::Switch:
|
||||
return { "AudioSwitch" };
|
||||
case AudioPropertyType::SwitchState:
|
||||
return { "AudioSwitchState" };
|
||||
case AudioPropertyType::Rtpc:
|
||||
return { "AudioRTPC" };
|
||||
case AudioPropertyType::Environment:
|
||||
return { "AudioEnvironment" };
|
||||
case AudioPropertyType::Preload:
|
||||
|
||||
+21
@@ -29,6 +29,27 @@ class QMimeData;
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
//=============================================================================
|
||||
// Audio Control Selector Request Bus
|
||||
// For connecting UI proper
|
||||
//=============================================================================
|
||||
class AudioControlSelectorRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
// EBusTraits
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
using BusIdType = AudioPropertyType;
|
||||
|
||||
virtual AZStd::string SelectResource(AZStd::string_view previousValue)
|
||||
{
|
||||
return previousValue;
|
||||
}
|
||||
};
|
||||
|
||||
using AudioControlSelectorRequestBus = AZ::EBus<AudioControlSelectorRequests>;
|
||||
|
||||
//=============================================================================
|
||||
// Audio Control Selector Widget
|
||||
//=============================================================================
|
||||
|
||||
+5
-5
@@ -18,15 +18,15 @@
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
//=========================================================================
|
||||
enum class AudioPropertyType
|
||||
enum class AudioPropertyType : AZ::u32
|
||||
{
|
||||
Invalid = 0,
|
||||
Trigger,
|
||||
Trigger = 0,
|
||||
Rtpc,
|
||||
Switch,
|
||||
SwitchState,
|
||||
Rtpc,
|
||||
Environment,
|
||||
Preload,
|
||||
NumTypes,
|
||||
};
|
||||
|
||||
//=========================================================================
|
||||
@@ -40,7 +40,7 @@ namespace AzToolsFramework
|
||||
virtual ~CReflectedVarAudioControl() = default;
|
||||
|
||||
AZStd::string m_controlName;
|
||||
AudioPropertyType m_propertyType = AudioPropertyType::Invalid;
|
||||
AudioPropertyType m_propertyType = AudioPropertyType::NumTypes;
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
|
||||
+29
@@ -27,6 +27,35 @@ using namespace AzToolsFramework;
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
void MousePressAndMove(
|
||||
QWidget* widget, const QPoint& initialPositionWidget, const QPoint& mouseDelta, const Qt::MouseButton mouseButton)
|
||||
{
|
||||
QPoint position = widget->mapToGlobal(initialPositionWidget);
|
||||
QTest::mousePress(widget, mouseButton, Qt::NoModifier, position);
|
||||
|
||||
MouseMove(widget, initialPositionWidget, mouseDelta, mouseButton);
|
||||
}
|
||||
|
||||
// Note: There are a series of bugs in Qt that appear to be preventing mouseMove events
|
||||
// firing when sent through the QTest framework. This is a work around for our version
|
||||
// of Qt. In future this can hopefully be simplified. See ^1 for workaround.
|
||||
// More info: Issues with mouse move in Qt
|
||||
// - https://bugreports.qt.io/browse/QTBUG-5232
|
||||
// - https://bugreports.qt.io/browse/QTBUG-69414
|
||||
// - https://lists.qt-project.org/pipermail/development/2019-July/036873.html
|
||||
void MouseMove(QWidget* widget, const QPoint& initialPositionWidget, const QPoint& mouseDelta, const Qt::MouseButton mouseButton)
|
||||
{
|
||||
QPoint nextPosition = widget->mapToGlobal(initialPositionWidget + mouseDelta);
|
||||
|
||||
// ^1 To ensure a mouse move event is fired we must call the test mouse move function
|
||||
// and also send a mouse move event that matches. Each on their own do not appear to
|
||||
// work - please see the links above for more context.
|
||||
QTest::mouseMove(widget, nextPosition);
|
||||
QMouseEvent mouseMoveEvent(
|
||||
QEvent::MouseMove, QPointF(nextPosition), QPointF(nextPosition), Qt::NoButton, mouseButton, Qt::NoModifier);
|
||||
QApplication::sendEvent(widget, &mouseMoveEvent);
|
||||
}
|
||||
|
||||
bool TestWidget::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
AZ_UNUSED(watched);
|
||||
|
||||
+15
@@ -59,6 +59,21 @@ namespace UnitTest
|
||||
{
|
||||
constexpr AZStd::string_view prefabSystemSetting = "/Amazon/Preferences/EnablePrefabSystem";
|
||||
|
||||
/// Performs a mouse press and move event on the provided widget.
|
||||
/// @param widget The widget to perform the mouse press and move on.
|
||||
/// @param initialPositionWidget The position of the mouse relative to the widget (will be remapped to a global position internally).
|
||||
/// @param mouseDelta How far to move the mouse.
|
||||
/// @param mouseButton The button to be used during the press and move.
|
||||
void MousePressAndMove(
|
||||
QWidget* widget, const QPoint& initialPositionWidget, const QPoint& mouseDelta, Qt::MouseButton mouseButton = Qt::LeftButton);
|
||||
|
||||
/// Performs a mouse move event on the provided widget.
|
||||
/// @param widget The widget to perform the mouse move on.
|
||||
/// @param initialPositionWidget The position of the mouse relative to the widget (will be remapped to a global position internally).
|
||||
/// @param mouseDelta How far to move the mouse (note: mouseDelta may be zero and the mouse will only be moved to initialPosition).
|
||||
/// @param mouseButton The button to be held during the move.
|
||||
void MouseMove(QWidget* widget, const QPoint& initialPosition, const QPoint& mouseDelta, Qt::MouseButton mouseButton = Qt::NoButton);
|
||||
|
||||
/// Test widget to store QActions generated by EditorTransformComponentSelection.
|
||||
class TestWidget : public QWidget
|
||||
{
|
||||
|
||||
@@ -313,7 +313,7 @@ namespace AzToolsFramework
|
||||
//! Utility function to return EntityContextId.
|
||||
inline AzFramework::EntityContextId GetEntityContextId()
|
||||
{
|
||||
AzFramework::EntityContextId entityContextId;
|
||||
auto entityContextId = AzFramework::EntityContextId::CreateNull();
|
||||
EditorEntityContextRequestBus::BroadcastResult(entityContextId, &EditorEntityContextRequests::GetEditorEntityContextId);
|
||||
|
||||
return entityContextId;
|
||||
|
||||
@@ -60,6 +60,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
|
||||
PUBLIC
|
||||
AZ::AzTestShared
|
||||
PRIVATE
|
||||
3rdParty::Qt::Test
|
||||
3rdParty::googletest::GMock
|
||||
3rdParty::GoogleBenchmark
|
||||
AZ::AzToolsFramework
|
||||
@@ -76,8 +77,9 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
|
||||
PRIVATE
|
||||
Tests
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
PUBLIC
|
||||
AZ::AzTestShared
|
||||
PRIVATE
|
||||
3rdParty::Qt::Test
|
||||
AZ::AzFrameworkTestShared
|
||||
AZ::AzToolsFramework
|
||||
|
||||
@@ -107,31 +107,6 @@ namespace UnitTest
|
||||
EXPECT_THAT(m_doubleSpinBoxWithLineEdit, Ne(nullptr));
|
||||
}
|
||||
|
||||
// Note: There are a series of bugs in Qt that appear to be preventing mouseMove events
|
||||
// firing when sent through the QTest framework. This is a work around for our version
|
||||
// of Qt. In future this can hopefully be simplified. See ^1 for workaround.
|
||||
// More info: Issues with mouse move in Qt
|
||||
// - https://bugreports.qt.io/browse/QTBUG-5232
|
||||
// - https://bugreports.qt.io/browse/QTBUG-69414
|
||||
// - https://lists.qt-project.org/pipermail/development/2019-July/036873.html
|
||||
void MousePressAndMove(
|
||||
QWidget* widget, const QPoint& widgetScreenPosition, const QPoint& mouseDelta)
|
||||
{
|
||||
QPoint position = widget->mapToGlobal(widgetScreenPosition);
|
||||
QPoint nextPosition = widget->mapToGlobal(widgetScreenPosition + mouseDelta);
|
||||
|
||||
QTest::mousePress(widget, Qt::LeftButton, Qt::NoModifier, position);
|
||||
|
||||
// ^1 To ensure a mouse move event is fired we must call the test mouse move function
|
||||
// and also send a mouse move event that matches. Each on their own do not appear to
|
||||
// work - please see the links above for more context.
|
||||
QTest::mouseMove(widget, nextPosition);
|
||||
QMouseEvent mouseMoveEvent(
|
||||
QEvent::MouseMove, QPointF(nextPosition), QPointF(nextPosition),
|
||||
Qt::NoButton, Qt::LeftButton, Qt::NoModifier);
|
||||
QApplication::sendEvent(widget, &mouseMoveEvent);
|
||||
}
|
||||
|
||||
TEST_F(SpinBoxFixture, SpinBoxMousePressAndMoveRightScrollsValue)
|
||||
{
|
||||
m_doubleSpinBox->setValue(10.0);
|
||||
|
||||
Reference in New Issue
Block a user