QmlDesigner: Fix 3D split view issues

- Corrected the splitter resize handle area to be centered on splitter
- Changed view order in 3+1 view so that view 0 is the big one
- Made split view borders only appear on inner edges of splits

Fixes: QDS-15293
Fixes: QDS-15295
Fixes: QDS-15303
Change-Id: I39e832f1e49e4a36112ad79bbcc498b9780df7cb
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
Miikka Heikkinen
2025-05-08 15:59:33 +03:00
parent 6487ea2cbd
commit 8590d79401
2 changed files with 99 additions and 69 deletions

View File

@@ -64,10 +64,10 @@ Item {
"3Left1Right": {
numViewports: 4,
viewRects: [
{ x: 0.25, y: 0.0, width: 0.75, height: 1.0 },
{ x: 0.0, y: 0.0, width: 0.25, height: 0.33 },
{ x: 0.0, y: 0.33, width: 0.25, height: 0.34 },
{ x: 0.0, y: 0.67, width: 0.25, height: 0.33 },
{ x: 0.25, y: 0.0, width: 0.75, height: 1.0 }
{ x: 0.0, y: 0.3333, width: 0.25, height: 0.34 },
{ x: 0.0, y: 0.6667, width: 0.25, height: 0.33 }
]
},
"2Horizontal": {
@@ -84,7 +84,6 @@ Item {
{ x: 0.5, y: 0.0, width: 0.5, height: 1.0 }
]
}
//TODO: reset of presets
};
enum SelectionMode { Item, Group }
@@ -136,6 +135,7 @@ Item {
onActivePresetChanged: {
_generalHelper.storeToolState(sceneId, "activePreset", activePreset);
_generalHelper.requestOverlayUpdate();
applyViewportPreset()
}
onActiveViewportChanged: {
_generalHelper.storeToolState(sceneId, "activeViewport", activeViewport);
@@ -440,18 +440,16 @@ Item {
viewRoot.showCameraSpeed = false;
}
if ("activePreset" in toolStates)
activePreset = toolStates.activePreset;
else if (resetToDefault)
activePreset = "Quad";
applyViewportPreset(activePreset);
if ("activeViewport" in toolStates)
activeViewport = toolStates.activeViewport;
else if (resetToDefault)
activeViewport = 0;
if ("activePreset" in toolStates)
activePreset = toolStates.activePreset;
else if (resetToDefault)
activePreset = "Single";
if ("showWireframe" in toolStates)
showWireframes = toolStates.showWireframe;
else if (resetToDefault)
@@ -719,24 +717,30 @@ Item {
cameraControls[activeViewport].moveCamera(amounts);
}
function updateSplitResizers()
{
verticalResizer.x = dividerX * viewContainer.width - verticalResizer.grabSize
horizontalResizer.y = dividerY * viewContainer.height - horizontalResizer.grabSize
}
function resetDividers()
{
dividerX = activePreset === "3Left1Right" ? 0.25 : 0.5
dividerY = 0.5
verticalResizer.x = dividerX * viewContainer.width
horizontalResizer.y = dividerY * viewContainer.height
}
// Update viewports based on selected preset
function applyViewportPreset(presetName)
function applyViewportPreset()
{
let preset = viewportPresets[presetName];
let preset = viewportPresets[activePreset];
if (!preset)
return;
let count = preset.numViewports;
if (activeViewport >= count)
activeViewport = 0;
for (let i = 0; i < 4; ++i) {
if (i < count) {
viewRects[i].visible = true;
@@ -750,8 +754,8 @@ Item {
}
resetDividers();
updateViewRects();
updateSplitResizers();
//TODO: Do we need this here?
cameraView.updateSnapping();
}
@@ -764,28 +768,28 @@ Item {
case "Single":
viewRect0.width = w;
viewRect0.height = h;
viewRect1.visible = viewRect2.visible = viewRect3.visible = false;
break;
case "2Vertical":
viewRect0.width = dividerX * w;
viewRect0.height = h;
viewRect1.x = dividerX * w;
viewRect1.y = 0;
viewRect1.width = (1 - dividerX) * w;
viewRect1.height = h;
viewRect2.visible = viewRect3.visible = false;
break
splitBorderV.x = dividerX * w;
break;
case "2Horizontal":
viewRect0.width = w;
viewRect0.height = dividerY * h;
viewRect1.x = 0;
viewRect1.y = dividerY * h;
viewRect1.width = w;
viewRect1.height = (1 - dividerY) * h;
viewRect2.visible = viewRect3.visible = false;
break
splitBorderH1.y = dividerY * h;
splitBorderH1.width = w;
break;
case "Quad":
// topleft
@@ -793,11 +797,9 @@ Item {
viewRect0.height = dividerY * h;
// topright
viewRect1.x = dividerX * w;
viewRect1.y = 0;
viewRect1.width = (1 - dividerX) * w;
viewRect1.height = dividerY * h;
// bottomleft
viewRect2.x = 0;
viewRect2.y = dividerY * h;
viewRect2.width = dividerX * w;
viewRect2.height = (1 - dividerY) * h;
@@ -806,29 +808,35 @@ Item {
viewRect3.y = dividerY * h
viewRect3.width = (1 - dividerX) * w;
viewRect3.height = (1 - dividerY) * h;
break
splitBorderV.x = dividerX * w;
splitBorderH1.y = dividerY * h;
splitBorderH1.width = w;
break;
case "3Left1Right":
// left column 3 rows
viewRect0.width = dividerX * w;
viewRect0.height = dividerY1 * h;
viewRect1.x = 0;
viewRect1.y = dividerY1 * h;
viewRect1.width = dividerX * w;
viewRect1.height = (dividerY2 - dividerY1) * h;
viewRect2.x = 0;
viewRect2.y = dividerY2 * h;
viewRect2.width = dividerX * w;
viewRect2.height = (1 - dividerY2) * h;
// big right view
viewRect3.x = dividerX * w;
viewRect3.y = 0;
viewRect3.width = (1 - dividerX) * w;
viewRect3.height = h;
break
viewRect0.x = dividerX * w;
viewRect0.width = (1 - dividerX) * w;
viewRect0.height = h;
// left column 3 rows
viewRect1.width = dividerX * w;
viewRect1.height = dividerY1 * h;
viewRect2.y = dividerY1 * h;
viewRect2.width = dividerX * w;
viewRect2.height = (dividerY2 - dividerY1) * h;
viewRect3.y = dividerY2 * h;
viewRect3.width = dividerX * w;
viewRect3.height = (1 - dividerY2) * h;
splitBorderV.x = dividerX * w;
splitBorderH1.y = dividerY1 * h;
splitBorderH1.width = dividerX * w;
splitBorderH2.y = dividerY2 * h;
break;
}
// Request overlays to redraw
@@ -838,18 +846,20 @@ Item {
Component.onCompleted: {
createEditViews();
selectObjects([]);
applyViewportPreset(activePreset)
applyViewportPreset()
// Work-around the fact that the projection matrix for the camera is not calculated until
// the first frame is rendered, so any initial calls to mapFrom3DScene() will fail.
_generalHelper.requestOverlayUpdate();
}
onWidthChanged: {
applyViewportPreset(activePreset)
updateViewRects()
updateSplitResizers()
_generalHelper.requestOverlayUpdate()
}
onHeightChanged: {
applyViewportPreset(activePreset)
updateViewRects()
updateSplitResizers()
_generalHelper.requestOverlayUpdate()
}
@@ -921,8 +931,6 @@ Item {
Rectangle {
id: viewRect0
gradient: bgGradient
border.width: 1
border.color: viewportBorderColor
OverlayView3D {
id: overlayView0
viewportId: 0
@@ -946,8 +954,6 @@ Item {
Rectangle {
id: viewRect1
gradient: bgGradient
border.width: 1
border.color: viewportBorderColor
OverlayView3D {
id: overlayView1
viewportId: 1
@@ -971,8 +977,6 @@ Item {
Rectangle {
id: viewRect2
gradient: bgGradient
border.width: 1
border.color: viewportBorderColor
OverlayView3D {
id: overlayView2
viewportId: 2
@@ -996,8 +1000,6 @@ Item {
Rectangle {
id: viewRect3
gradient: bgGradient
border.width: 1
border.color: viewportBorderColor
OverlayView3D {
id: overlayView3
viewportId: 3
@@ -1018,6 +1020,39 @@ Item {
}
}
Rectangle {
id: splitBorderV
visible: viewRoot.activePreset === "2Vertical"
|| viewRoot.activePreset === "3Left1Right"
|| viewRoot.activePreset === "Quad"
y: 0
width: 1
height: parent.height
border.width: 1
border.color: "#aaaaaa"
}
Rectangle {
id: splitBorderH1
visible: viewRoot.activePreset === "2Horizontal"
|| viewRoot.activePreset === "3Left1Right"
|| viewRoot.activePreset === "Quad"
x: 0
height: 1
border.width: 1
border.color: "#aaaaaa"
}
Rectangle {
id: splitBorderH2
visible: viewRoot.activePreset === "3Left1Right"
x: 0
height: 1
width: splitBorderH1.width
border.width: 1
border.color: "#aaaaaa"
}
// Active viewport highlight
Rectangle {
visible: activePreset !== "Single" && viewRects[viewRoot.activeViewport].visible

View File

@@ -11,12 +11,12 @@ Item {
property real containerSize
property int orientation
property real _dragMin: 0.0
property real _dragMax: 0.0
readonly property real _size: 12
property real _dragMin: containerSize * 0.1
property real _dragMax: containerSize * 0.9
readonly property real grabSize: 4
width: orientation === Qt.Vertical ? _size : parent.width
height: orientation === Qt.Horizontal ? _size : parent.height
width: orientation === Qt.Vertical ? grabSize * 2 : parent.width
height: orientation === Qt.Horizontal ? grabSize * 2 : parent.height
signal currentDividerChanged(real value)
@@ -33,14 +33,9 @@ Item {
drag.smoothed: true
onPositionChanged: {
var deltaPx = (orientation === Qt.Vertical ? root.x : root.y);
var deltaNorm = deltaPx / root.containerSize;
var deltaPx = (orientation === Qt.Vertical ? root.x : root.y) + grabSize;
var deltaNorm = (deltaPx / root.containerSize);
currentDividerChanged(deltaNorm);
}
Component.onCompleted: {
_dragMin = containerSize * 0.1; // Drag constraint
_dragMax = containerSize - _dragMin;
}
}
}