Merge "Tweak TopologyScale API according to current usage" into main
This commit is contained in:
committed by
Android (Google) Code Review
commit
ace72e4455
@@ -75,16 +75,16 @@ class TopologyScale(
|
|||||||
paneWidth : Int, minEdgeLength : Int, maxBlockRatio : Float,
|
paneWidth : Int, minEdgeLength : Int, maxBlockRatio : Float,
|
||||||
displaysPos : Collection<RectF>) {
|
displaysPos : Collection<RectF>) {
|
||||||
/** Scale of block sizes to real-world display sizes. Should be less than 1. */
|
/** Scale of block sizes to real-world display sizes. Should be less than 1. */
|
||||||
val blockRatio : Float
|
val blockRatio: Float
|
||||||
|
|
||||||
/** Height of topology pane needed to allow all display blocks to appear with some padding. */
|
/** Height of topology pane needed to allow all display blocks to appear with some padding. */
|
||||||
val paneHeight : Int
|
val paneHeight: Float
|
||||||
|
|
||||||
/** Pane's X view coordinate that corresponds with topology's X=0 coordinate. */
|
/** Pane's X view coordinate that corresponds with topology's X=0 coordinate. */
|
||||||
val originPaneX : Int
|
val originPaneX: Float
|
||||||
|
|
||||||
/** Pane's Y view coordinate that corresponds with topology's Y=0 coordinate. */
|
/** Pane's Y view coordinate that corresponds with topology's Y=0 coordinate. */
|
||||||
val originPaneY : Int
|
val originPaneY: Float
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val displayBounds = RectF(
|
val displayBounds = RectF(
|
||||||
@@ -114,15 +114,14 @@ class TopologyScale(
|
|||||||
// 20% padding above and below the display bounds - this is where the 0.6 comes from.
|
// 20% padding above and below the display bounds - this is where the 0.6 comes from.
|
||||||
val rawPaneHeight = max(
|
val rawPaneHeight = max(
|
||||||
paneWidth.toDouble() / displayBounds.width() * displayBounds.height(),
|
paneWidth.toDouble() / displayBounds.width() * displayBounds.height(),
|
||||||
displayBounds.height() * blockRatio / 0.6)
|
displayBounds.height() * blockRatio / 0.6).toFloat()
|
||||||
|
|
||||||
// It is easy for the aspect ratio to result in an excessively tall pane, since the width is
|
// It is easy for the aspect ratio to result in an excessively tall pane, since the width is
|
||||||
// pre-determined and may be considerably wider than necessary. So we prevent the height
|
// pre-determined and may be considerably wider than necessary. So we prevent the height
|
||||||
// from growing too large here, by limiting vertical padding to the size of the tallest
|
// from growing too large here, by limiting vertical padding to the size of the tallest
|
||||||
// display. This improves results for very tall display bounds.
|
// display. This improves results for very tall display bounds.
|
||||||
paneHeight = min(
|
paneHeight = min(
|
||||||
rawPaneHeight.toInt(),
|
rawPaneHeight, blockRatio * (displayBounds.height() + biggestDisplayHeight * 2f))
|
||||||
(blockRatio * (displayBounds.height() + biggestDisplayHeight * 2f)).toInt())
|
|
||||||
|
|
||||||
// Set originPaneXY (the location of 0,0 in display space in the pane's coordinate system)
|
// Set originPaneXY (the location of 0,0 in display space in the pane's coordinate system)
|
||||||
// such that the display bounds rect is centered in the pane.
|
// such that the display bounds rect is centered in the pane.
|
||||||
@@ -134,28 +133,24 @@ class TopologyScale(
|
|||||||
val blockMostLeft = (paneWidth - displayBounds.width() * blockRatio) / 2
|
val blockMostLeft = (paneWidth - displayBounds.width() * blockRatio) / 2
|
||||||
val blockMostTop = (paneHeight - displayBounds.height() * blockRatio) / 2
|
val blockMostTop = (paneHeight - displayBounds.height() * blockRatio) / 2
|
||||||
|
|
||||||
originPaneX = (blockMostLeft - displayBounds.left * blockRatio).toInt()
|
originPaneX = blockMostLeft - displayBounds.left * blockRatio
|
||||||
originPaneY = (blockMostTop - displayBounds.top * blockRatio).toInt()
|
originPaneY = blockMostTop - displayBounds.top * blockRatio
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Transforms coordinates in view pane space to display space. */
|
/** Transforms coordinates in view pane space to display space. */
|
||||||
fun paneToDisplayCoor(panePos : Point) : PointF {
|
fun paneToDisplayCoor(paneX: Float, paneY: Float): PointF {
|
||||||
return PointF(
|
return PointF((paneX - originPaneX) / blockRatio, (paneY - originPaneY) / blockRatio)
|
||||||
(panePos.x - originPaneX).toFloat() / blockRatio,
|
|
||||||
(panePos.y - originPaneY).toFloat() / blockRatio)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Transforms coordinates in display space to view pane space. */
|
/** Transforms coordinates in display space to view pane space. */
|
||||||
fun displayToPaneCoor(displayPos : PointF) : Point {
|
fun displayToPaneCoor(displayX: Float, displayY: Float): PointF {
|
||||||
return Point(
|
return PointF(displayX * blockRatio + originPaneX, displayY * blockRatio + originPaneY)
|
||||||
(displayPos.x * blockRatio).toInt() + originPaneX,
|
|
||||||
(displayPos.y * blockRatio).toInt() + originPaneY)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString() : String {
|
override fun toString() : String {
|
||||||
return String.format(
|
return String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"{TopoScale blockRatio=%f originPaneXY=%d,%d paneHeight=%d}",
|
"{TopologyScale blockRatio=%f originPaneXY=%.1f,%.1f paneHeight=%.1f}",
|
||||||
blockRatio, originPaneX, originPaneY, paneHeight)
|
blockRatio, originPaneX, originPaneY, paneHeight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -163,7 +158,7 @@ class TopologyScale(
|
|||||||
const val PREFERENCE_KEY = "display_topology_preference"
|
const val PREFERENCE_KEY = "display_topology_preference"
|
||||||
|
|
||||||
/** Padding in pane coordinate pixels on each side of a display block. */
|
/** Padding in pane coordinate pixels on each side of a display block. */
|
||||||
const val BLOCK_PADDING = 2
|
const val BLOCK_PADDING = 2f
|
||||||
|
|
||||||
/** Represents a draggable block in the topology pane. */
|
/** Represents a draggable block in the topology pane. */
|
||||||
class DisplayBlock(context : Context) : Button(context) {
|
class DisplayBlock(context : Context) : Button(context) {
|
||||||
@@ -174,24 +169,24 @@ class DisplayBlock(context : Context) : Button(context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Sets position of the block given unpadded coordinates. */
|
/** Sets position of the block given unpadded coordinates. */
|
||||||
fun place(topLeft : Point) {
|
fun place(topLeft: PointF) {
|
||||||
x = (topLeft.x + BLOCK_PADDING).toFloat()
|
x = topLeft.x + BLOCK_PADDING
|
||||||
y = (topLeft.y + BLOCK_PADDING).toFloat()
|
y = topLeft.y + BLOCK_PADDING
|
||||||
}
|
}
|
||||||
|
|
||||||
val unpaddedX : Int
|
val unpaddedX: Float
|
||||||
get() = (x - BLOCK_PADDING).toInt()
|
get() = x - BLOCK_PADDING
|
||||||
|
|
||||||
val unpaddedY : Int
|
val unpaddedY: Float
|
||||||
get() = (y - BLOCK_PADDING).toInt()
|
get() = y - BLOCK_PADDING
|
||||||
|
|
||||||
/** Sets position and size of the block given unpadded bounds. */
|
/** Sets position and size of the block given unpadded bounds. */
|
||||||
fun placeAndSize(bounds : RectF, scale : TopologyScale) {
|
fun placeAndSize(bounds : RectF, scale : TopologyScale) {
|
||||||
val topLeft = scale.displayToPaneCoor(PointF(bounds.left, bounds.top))
|
val topLeft = scale.displayToPaneCoor(bounds.left, bounds.top)
|
||||||
val bottomRight = scale.displayToPaneCoor(PointF(bounds.right, bounds.bottom))
|
val bottomRight = scale.displayToPaneCoor(bounds.right, bounds.bottom)
|
||||||
val layout = layoutParams
|
val layout = layoutParams
|
||||||
layout.width = bottomRight.x - topLeft.x - BLOCK_PADDING * 2
|
layout.width = (bottomRight.x - topLeft.x - BLOCK_PADDING * 2f).toInt()
|
||||||
layout.height = bottomRight.y - topLeft.y - BLOCK_PADDING * 2
|
layout.height = (bottomRight.y - topLeft.y - BLOCK_PADDING * 2f).toInt()
|
||||||
layoutParams = layout
|
layoutParams = layout
|
||||||
place(topLeft)
|
place(topLeft)
|
||||||
}
|
}
|
||||||
@@ -327,8 +322,9 @@ class DisplayTopologyPreference(context : Context)
|
|||||||
mPaneContent.width, minEdgeLength = 60, maxBlockRatio = 0.12f,
|
mPaneContent.width, minEdgeLength = 60, maxBlockRatio = 0.12f,
|
||||||
blocksPos.map { it.second }.toList())
|
blocksPos.map { it.second }.toList())
|
||||||
mPaneHolder.layoutParams.let {
|
mPaneHolder.layoutParams.let {
|
||||||
if (it.height != scaling.paneHeight) {
|
val newHeight = scaling.paneHeight.toInt()
|
||||||
it.height = scaling.paneHeight
|
if (it.height != newHeight) {
|
||||||
|
it.height = newHeight
|
||||||
mPaneHolder.layoutParams = it
|
mPaneHolder.layoutParams = it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -378,15 +374,14 @@ class DisplayTopologyPreference(context : Context)
|
|||||||
private fun onBlockTouchMove(ev: MotionEvent): Boolean {
|
private fun onBlockTouchMove(ev: MotionEvent): Boolean {
|
||||||
val drag = mDrag ?: return false
|
val drag = mDrag ?: return false
|
||||||
val topology = mTopologyInfo ?: return false
|
val topology = mTopologyInfo ?: return false
|
||||||
val dispDragCoor = topology.scaling.paneToDisplayCoor(Point(
|
val dispDragCoor = topology.scaling.paneToDisplayCoor(
|
||||||
(ev.rawX - drag.dragOffsetX).toInt(),
|
ev.rawX - drag.dragOffsetX, ev.rawY - drag.dragOffsetY)
|
||||||
(ev.rawY - drag.dragOffsetY).toInt()))
|
|
||||||
val dispDragRect = RectF(
|
val dispDragRect = RectF(
|
||||||
dispDragCoor.x, dispDragCoor.y,
|
dispDragCoor.x, dispDragCoor.y,
|
||||||
dispDragCoor.x + drag.displayWidth, dispDragCoor.y + drag.displayHeight)
|
dispDragCoor.x + drag.displayWidth, dispDragCoor.y + drag.displayHeight)
|
||||||
val snapRect = clampPosition(drag.stationaryDisps.map { it.second }, dispDragRect)
|
val snapRect = clampPosition(drag.stationaryDisps.map { it.second }, dispDragRect)
|
||||||
|
|
||||||
drag.display.place(topology.scaling.displayToPaneCoor(PointF(snapRect.left, snapRect.top)))
|
drag.display.place(topology.scaling.displayToPaneCoor(snapRect.left, snapRect.top))
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -397,7 +392,7 @@ class DisplayTopologyPreference(context : Context)
|
|||||||
mPaneContent.requestDisallowInterceptTouchEvent(false)
|
mPaneContent.requestDisallowInterceptTouchEvent(false)
|
||||||
|
|
||||||
val newCoor = topology.scaling.paneToDisplayCoor(
|
val newCoor = topology.scaling.paneToDisplayCoor(
|
||||||
Point(drag.display.unpaddedX, drag.display.unpaddedY))
|
drag.display.unpaddedX, drag.display.unpaddedY)
|
||||||
val newTopology = topology.topology.copy()
|
val newTopology = topology.topology.copy()
|
||||||
val newPositions = drag.stationaryDisps.map { (id, pos) -> id to PointF(pos.left, pos.top) }
|
val newPositions = drag.stationaryDisps.map { (id, pos) -> id to PointF(pos.left, pos.top) }
|
||||||
.plus(drag.displayId to newCoor)
|
.plus(drag.displayId to newCoor)
|
||||||
|
@@ -41,11 +41,12 @@ class TopologyScaleTest {
|
|||||||
// blockRatio is higher than 0.05 in order to make the smallest display edge (480 dp) 48dp
|
// blockRatio is higher than 0.05 in order to make the smallest display edge (480 dp) 48dp
|
||||||
// in the pane.
|
// in the pane.
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"{TopoScale blockRatio=0.100000 originPaneXY=288,48 paneHeight=144}", "" + scale)
|
"{TopologyScale blockRatio=0.100000 originPaneXY=288.0,48.0 paneHeight=144.0}",
|
||||||
|
"" + scale)
|
||||||
|
|
||||||
assertEquals(Point(352, 96), scale.displayToPaneCoor(PointF(640f, 480f)))
|
assertPointF(352f, 96f, 0.001f, scale.displayToPaneCoor(640f, 480f))
|
||||||
assertEquals(Point(320, 72), scale.displayToPaneCoor(PointF(320f, 240f)))
|
assertPointF(320f, 72f, 0.001f, scale.displayToPaneCoor(320f, 240f))
|
||||||
assertEquals(PointF(640f, 480f), scale.paneToDisplayCoor(Point(352, 96)))
|
assertPointF(640f, 480f, 0.001f, scale.paneToDisplayCoor(352f, 96f))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -56,11 +57,12 @@ class TopologyScaleTest {
|
|||||||
listOf(RectF(0f, 0f, 1920f, 1200f), RectF(1920f, -300f, 3840f, 900f)))
|
listOf(RectF(0f, 0f, 1920f, 1200f), RectF(1920f, -300f, 3840f, 900f)))
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"{TopoScale blockRatio=0.046875 originPaneXY=60,37 paneHeight=117}", "" + scale)
|
"{TopologyScale blockRatio=0.046875 originPaneXY=60.0,37.5 paneHeight=117.2}",
|
||||||
|
"" + scale)
|
||||||
|
|
||||||
assertEquals(Point(78, 55), scale.displayToPaneCoor(PointF(400f, 400f)))
|
assertPointF(78.75f, 56.25f, 0.001f, scale.displayToPaneCoor(400f, 400f))
|
||||||
assertEquals(Point(42, 37), scale.displayToPaneCoor(PointF(-400f, 0f)))
|
assertPointF(41.25f, 37.5f, 0.001f, scale.displayToPaneCoor(-400f, 0f))
|
||||||
assertPointF(-384f, 106.6666f, 0.001f, scale.paneToDisplayCoor(Point(42, 42)))
|
assertPointF(-384f, 96f, 0.001f, scale.paneToDisplayCoor(42f, 42f))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -73,11 +75,12 @@ class TopologyScaleTest {
|
|||||||
// blockRatio is higher than 0.05 in order to make the smallest display edge (240 dp) 48dp
|
// blockRatio is higher than 0.05 in order to make the smallest display edge (240 dp) 48dp
|
||||||
// in the pane.
|
// in the pane.
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"{TopoScale blockRatio=0.200000 originPaneXY=96,128 paneHeight=256}", "" + scale)
|
"{TopologyScale blockRatio=0.200000 originPaneXY=96.0,128.0 paneHeight=256.0}",
|
||||||
|
"" + scale)
|
||||||
|
|
||||||
assertEquals(Point(192, 256), scale.displayToPaneCoor(PointF(480f, 640f)))
|
assertPointF(192f, 256f, 0.001f, scale.displayToPaneCoor(480f, 640f))
|
||||||
assertEquals(Point(96, 64), scale.displayToPaneCoor(PointF(0f, -320f)))
|
assertPointF(96f, 64f, 0.001f, scale.displayToPaneCoor(0f, -320f))
|
||||||
assertPointF(220f, -430f, 0.001f, scale.paneToDisplayCoor(Point(140, 42)))
|
assertPointF(220f, -430f, 0.001f, scale.paneToDisplayCoor(140f, 42f))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -94,9 +97,10 @@ class TopologyScaleTest {
|
|||||||
RectF(0f, 2400f, 640f, 2880f)))
|
RectF(0f, 2400f, 640f, 2880f)))
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"{TopoScale blockRatio=0.100000 originPaneXY=118,48 paneHeight=384}", "" + scale)
|
"{TopologyScale blockRatio=0.100000 originPaneXY=118.0,48.0 paneHeight=384.0}",
|
||||||
assertEquals(Point(150, 48), scale.displayToPaneCoor(PointF(320f, 0f)))
|
"" + scale)
|
||||||
assertPointF(-180f, 2880f, 0.001f, scale.paneToDisplayCoor(Point(100, 336)))
|
assertPointF(150f, 48f, 0.001f, scale.displayToPaneCoor(320f, 0f))
|
||||||
|
assertPointF(-180f, 2880f, 0.001f, scale.paneToDisplayCoor(100f, 336f))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -109,9 +113,10 @@ class TopologyScaleTest {
|
|||||||
RectF(0f, 480f, 640f, 960f)))
|
RectF(0f, 480f, 640f, 960f)))
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"{TopoScale blockRatio=0.120000 originPaneXY=111,57 paneHeight=230}", "" + scale)
|
"{TopologyScale blockRatio=0.120000 originPaneXY=111.6,57.6 paneHeight=230.4}",
|
||||||
assertEquals(Point(149, 57), scale.displayToPaneCoor(PointF(320f, 0f)))
|
"" + scale)
|
||||||
assertPointF(-91.6667f, 2325f, 0.001f, scale.paneToDisplayCoor(Point(100, 336)))
|
assertPointF(150f, 57.6f, 0.001f, scale.displayToPaneCoor(320f, 0f))
|
||||||
|
assertPointF(-96.6667f, 2320f, 0.001f, scale.paneToDisplayCoor(100f, 336f))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -125,8 +130,9 @@ class TopologyScaleTest {
|
|||||||
RectF(0f, 480f, 640f, 960f)))
|
RectF(0f, 480f, 640f, 960f)))
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"{TopoScale blockRatio=0.166667 originPaneXY=96,80 paneHeight=320}", "" + scale)
|
"{TopologyScale blockRatio=0.166667 originPaneXY=96.7,80.0 paneHeight=320.0}",
|
||||||
assertEquals(Point(149, 80), scale.displayToPaneCoor(PointF(320f, 0f)))
|
"" + scale)
|
||||||
assertPointF(24f, 1536f, 0.001f, scale.paneToDisplayCoor(Point(100, 336)))
|
assertPointF(150f, 80f, 0.001f, scale.displayToPaneCoor(320f, 0f))
|
||||||
|
assertPointF(20f, 1536f, 0.001f, scale.paneToDisplayCoor(100f, 336f))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user