From f62e42664180cac57426f3899f5e845c0ae1a853 Mon Sep 17 00:00:00 2001
From: Paul Kaplan <pkaplan@media.mit.edu>
Date: Wed, 16 May 2018 10:29:10 -0400
Subject: [PATCH] Wrap the monitor list in a CSS scale transform

---
 src/components/monitor-list/monitor-list.css |  2 ++
 src/components/monitor-list/monitor-list.jsx | 17 ++++++++++++++++-
 src/components/monitor/monitor.css           |  1 +
 src/components/stage/stage.jsx               |  2 +-
 4 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/src/components/monitor-list/monitor-list.css b/src/components/monitor-list/monitor-list.css
index 6ee78ce05..c5fad0b64 100644
--- a/src/components/monitor-list/monitor-list.css
+++ b/src/components/monitor-list/monitor-list.css
@@ -2,4 +2,6 @@
     width: 100%;
     height: 100%;
     pointer-events: none;
+    /* Scaling for monitors should happen from the top left */
+    transform-origin: left top;
 }
diff --git a/src/components/monitor-list/monitor-list.jsx b/src/components/monitor-list/monitor-list.jsx
index 07b6a817b..d229b3b29 100644
--- a/src/components/monitor-list/monitor-list.jsx
+++ b/src/components/monitor-list/monitor-list.jsx
@@ -7,10 +7,19 @@ import {OrderedMap} from 'immutable';
 
 import styles from './monitor-list.css';
 
+const stageSizeToTransform = ({width, height, widthDefault, heightDefault}) => {
+    const scaleX = width / widthDefault;
+    const scaleY = height / heightDefault;
+    return `scale(${scaleX},${scaleY})`;
+};
+
 const MonitorList = props => (
     <Box
         // Use static `monitor-overlay` class for bounds of draggables
         className={classNames(styles.monitorList, 'monitor-overlay')}
+        style={{
+            transform: stageSizeToTransform(props.stageSize)
+        }}
     >
         {props.monitors.valueSeq().filter(m => m.visible)
             .map(monitorData => (
@@ -37,7 +46,13 @@ const MonitorList = props => (
 
 MonitorList.propTypes = {
     monitors: PropTypes.instanceOf(OrderedMap),
-    onMonitorChange: PropTypes.func.isRequired
+    onMonitorChange: PropTypes.func.isRequired,
+    stageSize: PropTypes.shape({
+        width: PropTypes.number,
+        height: PropTypes.number,
+        widthDefault: PropTypes.number,
+        heightDefault: PropTypes.number
+    }).isRequired
 };
 
 export default MonitorList;
diff --git a/src/components/monitor/monitor.css b/src/components/monitor/monitor.css
index 348f11e0c..885679979 100644
--- a/src/components/monitor/monitor.css
+++ b/src/components/monitor/monitor.css
@@ -93,6 +93,7 @@
     align-items: center;
     padding: 2px;
     flex-shrink: 0;
+    transform: translateZ(0); /* Keep sharp when scaled */
 }
 
 .list-index {
diff --git a/src/components/stage/stage.jsx b/src/components/stage/stage.jsx
index 37f12706b..d974375ac 100644
--- a/src/components/stage/stage.jsx
+++ b/src/components/stage/stage.jsx
@@ -47,7 +47,7 @@ const StageComponent = props => {
                     {...boxProps}
                 />
                 <Box className={styles.monitorWrapper}>
-                    <MonitorList />
+                    <MonitorList stageSize={stageSize} />
                 </Box>
                 {isColorPicking && colorInfo ? (
                     <Box className={styles.colorPickerWrapper}>
-- 
GitLab