Browse Source

Drag clones are now positioned correctly when their ancestors use transforms, or when the cloned element uses auto- or percentage-margins. See #269.

Michael Ragazzon 3 years ago
parent
commit
e945973c7a
3 changed files with 71 additions and 4 deletions
  1. 12 4
      Source/Core/Context.cpp
  2. 57 0
      Tests/Data/VisualTests/drag.rml
  3. 2 0
      changelog.md

+ 12 - 4
Source/Core/Context.cpp

@@ -1237,11 +1237,19 @@ void Context::CreateDragClone(Element* element)
 	// Append the clone to the cursor proxy element.
 	cursor_proxy->AppendChild(std::move(element_drag_clone));
 
-	// Set all the required properties and pseudo-classes on the clone.
-	drag_clone->SetPseudoClass("drag", true);
+	// Position the clone. Use projected mouse coordinates to handle any ancestor transforms.
+	const Vector2f absolute_pos = element->GetAbsoluteOffset(Box::BORDER);
+	Vector2f projected_mouse_position = Vector2f(mouse_position);
+	if (Element* parent = element->GetParentNode())
+		parent->Project(projected_mouse_position);
+
 	drag_clone->SetProperty(PropertyId::Position, Property(Style::Position::Absolute));
-	drag_clone->SetProperty(PropertyId::Left, Property(element->GetAbsoluteLeft() - element->GetBox().GetEdge(Box::MARGIN, Box::LEFT) - mouse_position.x, Property::PX));
-	drag_clone->SetProperty(PropertyId::Top, Property(element->GetAbsoluteTop() - element->GetBox().GetEdge(Box::MARGIN, Box::TOP) - mouse_position.y, Property::PX));
+	drag_clone->SetProperty(PropertyId::Left, Property(absolute_pos.x - projected_mouse_position.x, Property::PX));
+	drag_clone->SetProperty(PropertyId::Top, Property(absolute_pos.y - projected_mouse_position.y, Property::PX));
+	// We remove margins so that percentage- and auto-margins are evaluated correctly.
+	drag_clone->SetProperty(PropertyId::MarginLeft, Property(0.f, Property::PX));
+	drag_clone->SetProperty(PropertyId::MarginTop, Property(0.f, Property::PX));
+	drag_clone->SetPseudoClass("drag", true);
 }
 
 // Releases the drag clone, if one exists.

+ 57 - 0
Tests/Data/VisualTests/drag.rml

@@ -0,0 +1,57 @@
+<rml>
+<head>
+    <title>Drag</title>
+    <link type="text/rcss" href="../style.rcss"/>
+	<link rel="Issue #269" href="https://github.com/mikke89/RmlUi/issues/269" />
+	<meta name="Description" content="Clone dragging should respect parent transforms when determining starting location. However, parent transforms themselves are not applied to the clone." />
+	<meta name="Assert" content="When the upper button is dragged, it should generate a clone at the same location and orientation." />
+	<meta name="Assert" content="When the lower button is dragged, it should generate a clone at approximately the same location, but at another orientation and scale." />
+	<style>
+			body {
+				width: 800dp;
+				perspective: 500dp;
+			}
+			.container {
+				width: 300dp;
+				height: 300dp;
+				position: absolute;
+				top: 0;
+				right: 50%;
+				transform: translate(50%, 50dp);
+				background-color: #C2C2C2;
+			}
+			.container.rotate {
+				top: auto;
+				bottom: 0;
+				transform: translate(50%, -30%) rotate3d(1, 0, 1, 65deg) scale(0.8);
+			}
+			.item {
+				width: 100dp;
+				height: 100dp;
+				margin: 100dp auto;
+				background-color: #1F1F1F;
+				transform: translate(100dp, 50dp) rotate(-18deg) scale(0.7);
+				drag: clone;
+			}
+			.item:hover {
+				background: #860;
+			}
+			.item:active {
+				background: #973;
+			}
+			.item:drag {
+				background: #f00;
+			}
+	</style>
+</head>
+
+<body>
+<div class="container">
+	<div class="item"></div>
+</div>
+<div class="container rotate">
+	<div class="item"></div>
+</div>
+<handle size_target="#document"/>
+</body>
+</rml>

+ 2 - 0
changelog.md

@@ -16,6 +16,8 @@
 - Fix classes not always copied over to a cloned element. [#264](https://github.com/mikke89/RmlUi/issues/264)
 - `select` element: Fix clipping on select box.
 - The `opacity` property is now also applied to font effects. [#270](https://github.com/mikke89/RmlUi/issues/270)
+- Drag clones are now positioned correctly when their ancestors use transforms. [#269](https://github.com/mikke89/RmlUi/issues/269)
+- Drag clones no longer inherit backgrounds and decoration from the cloned element's document body.
 
 ### Layout