Fix hi-res display issues in UI Editor (#6912)

* Fix dpi scaling issues in UI Editor

Signed-off-by: abrmich <abrmich@amazon.com>

* Remove older method for getting dpi scaling factor

Signed-off-by: abrmich <abrmich@amazon.com>

* Remove direct call to devicePixelRatioF()

Signed-off-by: abrmich <abrmich@amazon.com>

* Use existing convenience function

Signed-off-by: abrmich <abrmich@amazon.com>

* Fix one more text size

Signed-off-by: abrmich <abrmich@amazon.com>

* Fix compile warning

Signed-off-by: abrmich <abrmich@amazon.com>

* Remove unnecessary typecast

Signed-off-by: abrmich <abrmich@amazon.com>
This commit is contained in:
michabr
2022-01-21 12:02:20 -08:00
committed by GitHub
parent 090e12e712
commit a8d97cf8aa
10 changed files with 97 additions and 77 deletions
+2 -3
View File
@@ -134,7 +134,7 @@ namespace GuideHelpers
AZ::Matrix4x4 transform;
EBUS_EVENT_ID_RESULT(transform, canvasEntityId, UiCanvasBus, GetCanvasToViewportMatrix);
AZ::Vector2 viewportSize(aznumeric_cast<float>(viewport->size().width()), aznumeric_cast<float>(viewport->size().height()));
AZ::Vector2 viewportSize = viewport->GetRenderViewportSize();
AZ::Color guideColor;
EBUS_EVENT_ID_RESULT(guideColor, canvasEntityId, UiEditorCanvasBus, GetGuideColor);
@@ -167,8 +167,7 @@ namespace GuideHelpers
void DrawGhostGuideLine(Draw2dHelper& draw2d, AZ::EntityId canvasEntityId, bool guideIsVertical, ViewportWidget* viewport, const AZ::Vector2& canvasPoint)
{
AZ::Vector2 viewportPoint = CanvasHelpers::GetViewportPoint(canvasEntityId, canvasPoint);
AZ::Vector2 viewportSize(aznumeric_cast<float>(viewport->size().width()), aznumeric_cast<float>(viewport->size().height()));
AZ::Vector2 viewportSize = viewport->GetRenderViewportSize();
// the line is drawn as the inverse of the background color
AZ::Color guideColor(1.0f, 1.0f, 1.0f, 1.0f);
-14
View File
@@ -29,18 +29,4 @@ namespace QtHelpers
bool inWidget = (localPos.x() >= 0 && localPos.x() < size.width() && localPos.y() >= 0 && localPos.y() < size.height());
return inWidget;
}
float GetHighDpiScaleFactor(const QWidget& widget)
{
return static_cast<float>(QHighDpiScaling::factor(widget.windowHandle()->screen()));
}
QSize GetDpiScaledViewportSize(const QWidget& widget)
{
float dpiScale = GetHighDpiScaleFactor(widget);
float width = ceilf(widget.size().width() * dpiScale);
float height = ceilf(widget.size().height() * dpiScale);
return QSize(static_cast<int>(width), static_cast<int>(height));
}
} // namespace QtHelpers
-5
View File
@@ -16,9 +16,4 @@ namespace QtHelpers
AZ::Vector2 MapGlobalPosToLocalVector2(const QWidget* widget, const QPoint& pos);
bool IsGlobalPosInWidget(const QWidget* widget, const QPoint& pos);
float GetHighDpiScaleFactor(const QWidget& widget);
QSize GetDpiScaledViewportSize(const QWidget& widget);
} // namespace QtHelpers
+15 -2
View File
@@ -61,6 +61,14 @@ void RulerWidget::paintEvent([[maybe_unused]] QPaintEvent* event)
float scale = translationAndScale.scale;
float translation = (m_orientation == Orientation::Horizontal) ? translationAndScale.translation.GetX() : translationAndScale.translation.GetY();
// Convert back to qt widget coords for painting
float dpiScaleFactor = m_editorWindow->GetViewport()->WidgetToViewportFactor();
if (dpiScaleFactor != 0.0f)
{
scale /= dpiScaleFactor;
translation /= dpiScaleFactor;
}
// If the viewport is really small then scale can be zero (or very close) which would cause a divide by zero in later math so we just don't paint anything
const float epsilon = 0.00001f;
if (scale < epsilon)
@@ -87,7 +95,9 @@ void RulerWidget::paintEvent([[maybe_unused]] QPaintEvent* event)
void RulerWidget::mousePressEvent(QMouseEvent* ev)
{
// start a drag interaction to create a guide
AZ::Vector2 viewportMousePos = QtHelpers::MapGlobalPosToLocalVector2(m_editorWindow->GetViewport(), ev->globalPos());
AZ::Vector2 localMousePos = QtHelpers::MapGlobalPosToLocalVector2(m_editorWindow->GetViewport(), ev->globalPos());
float dpiScaleFactor = m_editorWindow->GetViewport()->WidgetToViewportFactor();
AZ::Vector2 viewportMousePos = localMousePos * dpiScaleFactor;
bool isVertical = m_orientation == Orientation::Vertical;
m_dragInteraction = new ViewportAddGuideInteraction(m_editorWindow, m_editorWindow->GetCanvas(), isVertical, viewportMousePos);
}
@@ -98,7 +108,10 @@ void RulerWidget::mouseMoveEvent(QMouseEvent* ev)
// We only get the events if the mouse is pressed down. So we only get here when adding a ruler.
if (m_dragInteraction)
{
AZ::Vector2 viewportMousePos = QtHelpers::MapGlobalPosToLocalVector2(m_editorWindow->GetViewport(), ev->globalPos());
AZ::Vector2 localMousePos = QtHelpers::MapGlobalPosToLocalVector2(m_editorWindow->GetViewport(), ev->globalPos());
float dpiScaleFactor = m_editorWindow->GetViewport()->WidgetToViewportFactor();
AZ::Vector2 viewportMousePos = localMousePos * dpiScaleFactor;
m_dragInteraction->Update(viewportMousePos);
}
+4 -2
View File
@@ -336,7 +336,7 @@ namespace ViewportHelpers
draw2d.SetTextAlignment(IDraw2d::HAlign::Center, IDraw2d::VAlign::Bottom);
draw2d.SetTextRotation(0.0f);
draw2d.DrawText(rotationString.toUtf8().data(), rotationStringPos, GetDpiScaledSize(16.0f), 1.0f);
draw2d.DrawText(rotationString.toUtf8().data(), rotationStringPos, 8.0f, 1.0f);
}
}
@@ -347,9 +347,11 @@ namespace ViewportHelpers
const AZ::Vector2 textLabelOffset(10.0f, -10.0f);
QPoint viewportCursorPos = viewport->mapFromGlobal(QCursor::pos());
AZ::Vector2 textPos = AZ::Vector2(aznumeric_cast<float>(viewportCursorPos.x()), aznumeric_cast<float>(viewportCursorPos.y())) + textLabelOffset;
float dpiScale = viewport->WidgetToViewportFactor();
textPos *= dpiScale;
draw2d.SetTextAlignment(IDraw2d::HAlign::Left, IDraw2d::VAlign::Bottom);
draw2d.SetTextRotation(0.0f);
draw2d.DrawText(textLabel.c_str(), textPos, GetDpiScaledSize(16.0f), 1.0f);
draw2d.DrawText(textLabel.c_str(), textPos, 8.0f, 1.0f);
}
} // namespace ViewportHelpers
+1 -1
View File
@@ -296,7 +296,7 @@ void ViewportIcon::DrawDistanceLine(Draw2dHelper& draw2d, AZ::Vector2 start, AZ:
draw2d.SetTextAlignment(IDraw2d::HAlign::Center, IDraw2d::VAlign::Bottom);
draw2d.SetTextRotation(rotation);
draw2d.DrawText(textBuf, textPos, 16.0f * ViewportIcon::GetDpiScaleFactor(), 1.0f);
draw2d.DrawText(textBuf, textPos, 8.0f, 1.0f);
}
void ViewportIcon::DrawAnchorLinesSplit(Draw2dHelper& draw2d, AZ::Vector2 anchorPos1, AZ::Vector2 anchorPos2,
@@ -674,13 +674,13 @@ void ViewportInteraction::MouseReleaseEvent(QMouseEvent* ev,
{
// test to see if the mouse position is inside the viewport on each axis
const QPoint& pos = ev->pos();
const QSize& size = m_editorWindow->GetViewport()->size();
const AZ::Vector2 size = m_editorWindow->GetViewport()->GetRenderViewportSize();
ViewportDragInteraction::EndState inWidget;
if (pos.x() >= 0 && pos.x() < size.width())
inWidget = pos.y() >= 0 && pos.y() < size.height() ? ViewportDragInteraction::EndState::Inside : ViewportDragInteraction::EndState::OutsideY;
if (pos.x() >= 0 && pos.x() < size.GetX())
inWidget = pos.y() >= 0 && pos.y() < size.GetY() ? ViewportDragInteraction::EndState::Inside : ViewportDragInteraction::EndState::OutsideY;
else
inWidget = pos.y() >= 0 && pos.y() < size.height() ? ViewportDragInteraction::EndState::OutsideX : ViewportDragInteraction::EndState::OutsideXY;
inWidget = pos.y() >= 0 && pos.y() < size.GetY() ? ViewportDragInteraction::EndState::OutsideX : ViewportDragInteraction::EndState::OutsideXY;
// Some interactions end differently depending on whether the mouse was released inside or outside the viewport
m_dragInteraction->EndInteraction(inWidget);
@@ -709,12 +709,12 @@ void ViewportInteraction::MouseReleaseEvent(QMouseEvent* ev,
UpdateCursor();
}
void ViewportInteraction::MouseWheelEvent(QWheelEvent* ev)
bool ViewportInteraction::MouseWheelEvent(QWheelEvent* ev)
{
if (m_leftButtonIsActive || m_middleButtonIsActive)
{
// Ignore event.
return;
return false;
}
const QPoint numDegrees(ev->angleDelta());
@@ -735,6 +735,8 @@ void ViewportInteraction::MouseWheelEvent(QWheelEvent* ev)
SetCanvasToViewportScale(QuantizeZoomScale(newScale), &pivotPoint);
}
return true;
}
bool ViewportInteraction::KeyPressEvent(QKeyEvent* ev)
@@ -921,27 +923,27 @@ void ViewportInteraction::GetScaleToFitTransformProps(const AZ::Vector2* newCanv
EBUS_EVENT_ID_RESULT(canvasSize, m_editorWindow->GetCanvas(), UiCanvasBus, GetCanvasSize);
}
QSize viewportSize = QtHelpers::GetDpiScaledViewportSize(*m_editorWindow->GetViewport());
const int viewportWidth = viewportSize.width();
const int viewportHeight = viewportSize.height();
AZ::Vector2 viewportSize = m_editorWindow->GetViewport()->GetRenderViewportSize();
const float viewportWidth = viewportSize.GetX();
const float viewportHeight = viewportSize.GetY();
// We pad the edges of the viewport to allow the user to easily see the borders of
// the canvas edges, which is especially helpful if there are anchors sitting on
// the edges of the canvas.
static const int canvasBorderPaddingInPixels = 32;
AZ::Vector2 viewportPaddedSize(
aznumeric_cast<float>(viewportWidth - canvasBorderPaddingInPixels),
aznumeric_cast<float>(viewportHeight - canvasBorderPaddingInPixels));
viewportWidth - canvasBorderPaddingInPixels,
viewportHeight - canvasBorderPaddingInPixels);
// Guard against very small viewports
if (viewportPaddedSize.GetX() <= 0.0f)
{
viewportPaddedSize.SetX(aznumeric_cast<float>(viewportWidth));
viewportPaddedSize.SetX(viewportWidth);
}
if (viewportPaddedSize.GetY() <= 0.0f)
{
viewportPaddedSize.SetY(aznumeric_cast<float>(viewportHeight));
viewportPaddedSize.SetY(viewportHeight);
}
// Use a "scale to fit" approach
@@ -949,8 +951,8 @@ void ViewportInteraction::GetScaleToFitTransformProps(const AZ::Vector2* newCanv
viewportPaddedSize.GetX() / canvasSize.GetX(),
viewportPaddedSize.GetY() / canvasSize.GetY());
const int scaledCanvasWidth = static_cast<int>(canvasSize.GetX() * canvasToViewportScale);
const int scaledCanvasHeight = static_cast<int>(canvasSize.GetY() * canvasToViewportScale);
const float scaledCanvasWidth = canvasSize.GetX() * canvasToViewportScale;
const float scaledCanvasHeight = canvasSize.GetY() * canvasToViewportScale;
// Centers the canvas within the viewport
propsOut.translation = AZ::Vector3(
@@ -1008,9 +1010,12 @@ void ViewportInteraction::SetCanvasToViewportScale(float newScale, Vec2i* option
}
else
{
AZ::Vector2 viewportSize = m_editorWindow->GetViewport()->GetRenderViewportSize();
const float viewportWidth = viewportSize.GetX();
const float viewportHeight = viewportSize.GetY();
pivotPoint = Vec2i(
static_cast<int>(m_editorWindow->GetViewport()->size().width() * 0.5f),
static_cast<int>(m_editorWindow->GetViewport()->size().height() * 0.5f));
static_cast<int>(viewportWidth * 0.5f),
static_cast<int>(viewportHeight * 0.5f));
}
// Get the distance between our pivot point and the upper-left corner of the
@@ -77,7 +77,7 @@ public: // member functions
const QTreeWidgetItemRawPtrQList& selectedItems);
void MouseReleaseEvent(QMouseEvent* ev,
const QTreeWidgetItemRawPtrQList& selectedItems);
void MouseWheelEvent(QWheelEvent* ev);
bool MouseWheelEvent(QWheelEvent* ev);
bool KeyPressEvent(QKeyEvent* ev);
bool KeyReleaseEvent(QKeyEvent* ev);
+45 -26
View File
@@ -351,6 +351,17 @@ void ViewportWidget::SetRedrawEnabled(bool enabled)
m_canvasRenderIsEnabled = enabled;
}
AZ::Vector2 ViewportWidget::GetRenderViewportSize() const
{
AZ::Vector2 widgetSize(aznumeric_cast<float>(size().width()), aznumeric_cast<float>(size().height()));
return widgetSize * WidgetToViewportFactor();
}
float ViewportWidget::WidgetToViewportFactor() const
{
return GetViewportContext()->GetDpiScalingFactor();
}
void ViewportWidget::PickItem(AZ::EntityId entityId)
{
AzToolsFramework::EditorPickModeRequestBus::Broadcast(
@@ -496,7 +507,7 @@ void ViewportWidget::OnRenderTick()
return;
}
const float dpiScale = QtHelpers::GetHighDpiScaleFactor(*this);
const float dpiScale = WidgetToViewportFactor();
ViewportIcon::SetDpiScaleFactor(dpiScale);
UiEditorMode editorMode = m_editorWindow->GetEditorMode();
@@ -510,6 +521,12 @@ void ViewportWidget::OnRenderTick()
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void ViewportWidget::OnViewportDpiScalingChanged(float dpiScale)
{
ViewportIcon::SetDpiScaleFactor(dpiScale);
}
void ViewportWidget::RefreshTick()
{
#ifdef LYSHINE_EDITOR_TODO // still need this?
@@ -640,27 +657,34 @@ void ViewportWidget::mouseReleaseEvent(QMouseEvent* ev)
void ViewportWidget::wheelEvent(QWheelEvent* ev)
{
bool handled = false;
UiEditorMode editorMode = m_editorWindow->GetEditorMode();
QWheelEvent scaledEvent(
WidgetToViewport(ev->position()),
ev->globalPosition(),
ev->pixelDelta(),
ev->angleDelta(),
ev->buttons(),
ev->modifiers(),
ev->phase(),
ev->inverted()
);
if (editorMode == UiEditorMode::Edit)
{
QWheelEvent scaledEvent(
WidgetToViewport(ev->position()),
ev->globalPosition(),
ev->pixelDelta(),
ev->angleDelta(),
ev->buttons(),
ev->modifiers(),
ev->phase(),
ev->inverted()
);
// in Edit mode just send input to ViewportInteraction
m_viewportInteraction->MouseWheelEvent(&scaledEvent);
handled = m_viewportInteraction->MouseWheelEvent(&scaledEvent);
}
RenderViewportWidget::wheelEvent(ev);
Refresh();
if (handled)
{
ev->accept();
Refresh();
}
else
{
RenderViewportWidget::wheelEvent(ev);
}
}
bool ViewportWidget::eventFilter([[maybe_unused]] QObject* watched, QEvent* event)
@@ -975,8 +999,7 @@ void ViewportWidget::RenderEditMode()
EBUS_EVENT_ID(canvasEntityId, UiCanvasBus, SetTargetCanvasSize, false, canvasSize);
// Render this canvas
QSize scaledViewportSize = QtHelpers::GetDpiScaledViewportSize(*this);
AZ::Vector2 viewportSize(static_cast<float>(scaledViewportSize.width()), static_cast<float>(scaledViewportSize.height()));
AZ::Vector2 viewportSize = GetRenderViewportSize();
EBUS_EVENT_ID(canvasEntityId, UiEditorCanvasBus, RenderCanvasInEditorViewport, false, viewportSize);
m_draw2d->SetSortKey(topLayerKey);
@@ -1085,15 +1108,12 @@ void ViewportWidget::UpdatePreviewMode(float deltaTime)
if (canvasEntityId.IsValid())
{
QSize scaledViewportSize = QtHelpers::GetDpiScaledViewportSize(*this);
AZ::Vector2 viewportSize(static_cast<float>(scaledViewportSize.width()), static_cast<float>(scaledViewportSize.height()));
// Get the canvas size
AZ::Vector2 canvasSize = m_editorWindow->GetPreviewCanvasSize();
if (canvasSize.GetX() == 0.0f && canvasSize.GetY() == 0.0f)
{
// special value of (0,0) means use the viewport size
canvasSize = viewportSize;
canvasSize = GetRenderViewportSize();;
}
// Set the target size of the canvas
@@ -1127,8 +1147,7 @@ void ViewportWidget::RenderPreviewMode()
if (canvasEntityId.IsValid())
{
QSize scaledViewportSize = QtHelpers::GetDpiScaledViewportSize(*this);
AZ::Vector2 viewportSize(static_cast<float>(scaledViewportSize.width()), static_cast<float>(scaledViewportSize.height()));
AZ::Vector2 viewportSize = GetRenderViewportSize();
// Get the canvas size
AZ::Vector2 canvasSize = m_editorWindow->GetPreviewCanvasSize();
@@ -1208,13 +1227,13 @@ void ViewportWidget::RenderPreviewMode()
void ViewportWidget::RenderViewportBackground()
{
QSize viewportSize = QtHelpers::GetDpiScaledViewportSize(*this);
AZ::Vector2 viewportSize = GetRenderViewportSize();
AZ::Color backgroundColor = ViewportHelpers::backgroundColorDark;
const AZ::Data::Instance<AZ::RPI::Image>& image = AZ::RPI::ImageSystemInterface::Get()->GetSystemImage(AZ::RPI::SystemImage::White);
Draw2dHelper draw2d(m_draw2d.get());
draw2d.SetImageColor(backgroundColor.GetAsVector3());
draw2d.DrawImage(image, AZ::Vector2(0.0f, 0.0f), AZ::Vector2(static_cast<float>(viewportSize.width()), static_cast<float>(viewportSize.height())));
draw2d.DrawImage(image, AZ::Vector2(0.0f, 0.0f), viewportSize);
}
void ViewportWidget::SetupShortcuts()
+7 -6
View File
@@ -72,6 +72,12 @@ public: // member functions
//! Used by ViewportInteraction for drawing
ViewportHighlight* GetViewportHighlight() { return m_viewportHighlight.get(); }
//! Get the size of the RPI render viewport
AZ::Vector2 GetRenderViewportSize() const;
//! Get the widget to viewport scale factor
float WidgetToViewportFactor() const;
bool IsInObjectPickMode() { return m_inObjectPickMode; }
void PickItem(AZ::EntityId entityId);
@@ -156,6 +162,7 @@ private: // member functions
// AZ::RPI::ViewportContextNotificationBus::Handler overrides...
void OnRenderTick() override;
void OnViewportDpiScalingChanged(float dpiScale) override;
//! Update UI canvases when in edit mode
void UpdateEditMode(float deltaTime);
@@ -187,12 +194,6 @@ private: // data
bool AcceptsMimeData(const QMimeData* mimeData);
double WidgetToViewportFactor() const
{
// Needed for high DPI mode on windows
return devicePixelRatioF();
}
QPointF WidgetToViewport(const QPointF &point) const;
EditorWindow* m_editorWindow;