Files
XCEngine/new_editor/app/Host/BorderlessWindowFrame.cpp

177 lines
5.5 KiB
C++

#include "BorderlessWindowFrame.h"
#include <algorithm>
namespace XCEngine::UI::Editor::Host {
namespace {
using ::XCEngine::UI::UIPoint;
using ::XCEngine::UI::UIRect;
bool IsPointInsideRect(const UIRect& rect, const UIPoint& point) {
return rect.width > 0.0f &&
rect.height > 0.0f &&
point.x >= rect.x &&
point.x <= rect.x + rect.width &&
point.y >= rect.y &&
point.y <= rect.y + rect.height;
}
int ClampMinimum(int value, int minimum) {
return (std::max)(value, minimum);
}
} // namespace
BorderlessWindowResizeEdge HitTestBorderlessWindowResizeEdge(
const UIRect& clientRect,
const UIPoint& point,
const BorderlessWindowFrameMetrics& metrics) {
const float edge = (std::max)(metrics.resizeBorderThickness, 0.0f);
if (edge <= 0.0f || !IsPointInsideRect(clientRect, point)) {
return BorderlessWindowResizeEdge::None;
}
const bool left = point.x <= clientRect.x + edge;
const bool right = point.x >= clientRect.x + clientRect.width - edge;
const bool top = point.y <= clientRect.y + edge;
const bool bottom = point.y >= clientRect.y + clientRect.height - edge;
if (left && top) {
return BorderlessWindowResizeEdge::TopLeft;
}
if (right && top) {
return BorderlessWindowResizeEdge::TopRight;
}
if (left && bottom) {
return BorderlessWindowResizeEdge::BottomLeft;
}
if (right && bottom) {
return BorderlessWindowResizeEdge::BottomRight;
}
if (left) {
return BorderlessWindowResizeEdge::Left;
}
if (right) {
return BorderlessWindowResizeEdge::Right;
}
if (top) {
return BorderlessWindowResizeEdge::Top;
}
if (bottom) {
return BorderlessWindowResizeEdge::Bottom;
}
return BorderlessWindowResizeEdge::None;
}
LPCWSTR ResolveBorderlessWindowResizeCursor(BorderlessWindowResizeEdge edge) {
switch (edge) {
case BorderlessWindowResizeEdge::Left:
case BorderlessWindowResizeEdge::Right:
return IDC_SIZEWE;
case BorderlessWindowResizeEdge::Top:
case BorderlessWindowResizeEdge::Bottom:
return IDC_SIZENS;
case BorderlessWindowResizeEdge::TopLeft:
case BorderlessWindowResizeEdge::BottomRight:
return IDC_SIZENWSE;
case BorderlessWindowResizeEdge::TopRight:
case BorderlessWindowResizeEdge::BottomLeft:
return IDC_SIZENESW;
case BorderlessWindowResizeEdge::None:
default:
return IDC_ARROW;
}
}
RECT ComputeBorderlessWindowResizeRect(
const RECT& initialRect,
const POINT& initialScreenPoint,
const POINT& currentScreenPoint,
BorderlessWindowResizeEdge edge,
int minimumOuterWidth,
int minimumOuterHeight) {
RECT result = initialRect;
const LONG deltaX = currentScreenPoint.x - initialScreenPoint.x;
const LONG deltaY = currentScreenPoint.y - initialScreenPoint.y;
const int minimumWidth = ClampMinimum(minimumOuterWidth, 1);
const int minimumHeight = ClampMinimum(minimumOuterHeight, 1);
switch (edge) {
case BorderlessWindowResizeEdge::Left:
case BorderlessWindowResizeEdge::TopLeft:
case BorderlessWindowResizeEdge::BottomLeft:
result.left += deltaX;
if (result.right - result.left < minimumWidth) {
result.left = result.right - minimumWidth;
}
break;
case BorderlessWindowResizeEdge::None:
case BorderlessWindowResizeEdge::Top:
case BorderlessWindowResizeEdge::Bottom:
case BorderlessWindowResizeEdge::Right:
case BorderlessWindowResizeEdge::TopRight:
case BorderlessWindowResizeEdge::BottomRight:
break;
}
switch (edge) {
case BorderlessWindowResizeEdge::Right:
case BorderlessWindowResizeEdge::TopRight:
case BorderlessWindowResizeEdge::BottomRight:
result.right += deltaX;
if (result.right - result.left < minimumWidth) {
result.right = result.left + minimumWidth;
}
break;
case BorderlessWindowResizeEdge::None:
case BorderlessWindowResizeEdge::Left:
case BorderlessWindowResizeEdge::Top:
case BorderlessWindowResizeEdge::Bottom:
case BorderlessWindowResizeEdge::TopLeft:
case BorderlessWindowResizeEdge::BottomLeft:
break;
}
switch (edge) {
case BorderlessWindowResizeEdge::Top:
case BorderlessWindowResizeEdge::TopLeft:
case BorderlessWindowResizeEdge::TopRight:
result.top += deltaY;
if (result.bottom - result.top < minimumHeight) {
result.top = result.bottom - minimumHeight;
}
break;
case BorderlessWindowResizeEdge::None:
case BorderlessWindowResizeEdge::Left:
case BorderlessWindowResizeEdge::Right:
case BorderlessWindowResizeEdge::Bottom:
case BorderlessWindowResizeEdge::BottomLeft:
case BorderlessWindowResizeEdge::BottomRight:
break;
}
switch (edge) {
case BorderlessWindowResizeEdge::Bottom:
case BorderlessWindowResizeEdge::BottomLeft:
case BorderlessWindowResizeEdge::BottomRight:
result.bottom += deltaY;
if (result.bottom - result.top < minimumHeight) {
result.bottom = result.top + minimumHeight;
}
break;
case BorderlessWindowResizeEdge::None:
case BorderlessWindowResizeEdge::Left:
case BorderlessWindowResizeEdge::Top:
case BorderlessWindowResizeEdge::Right:
case BorderlessWindowResizeEdge::TopLeft:
case BorderlessWindowResizeEdge::TopRight:
break;
}
return result;
}
} // namespace XCEngine::UI::Editor::Host