From 243c832c25da214c195bc0a4a70d5c430b5293a9 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 26 Jun 2015 15:32:37 -0700 Subject: [PATCH 01/11] [Common UI] Add mct-split-pane Add mct-split-pane directive, to simplify adding splitters. WTD-1363. --- .../general/src/directives/MCTSplitPane.js | 193 ++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 platform/commonUI/general/src/directives/MCTSplitPane.js diff --git a/platform/commonUI/general/src/directives/MCTSplitPane.js b/platform/commonUI/general/src/directives/MCTSplitPane.js new file mode 100644 index 0000000000..dded5f0ea3 --- /dev/null +++ b/platform/commonUI/general/src/directives/MCTSplitPane.js @@ -0,0 +1,193 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +/*global define*/ + +define( + [], + function () { + 'use strict'; + + // Pixel width to allocate for the splitter itself + var SPLITTER_WIDTH = 8, + HALF_WIDTH = SPLITTER_WIDTH / 2, + DEFAULT_ANCHOR = 'left', + CHILDREN_WARNING_MESSAGE = [ + "Invalid mct-split-pane contents.", + "This element should contain exactly three", + "child elements, where the middle-most element", + "is an mct-splitter." + ].join(" "), + ANCHOR_WARNING_MESSAGE = [ + "Unknown anchor provided to mct-split-pane,", + "defaulting to", + DEFAULT_ANCHOR + "." + ].join(" "), + ANCHORS = { + left: { + edge: "left", + opposite: "right", + dimension: "width", + orientation: "vertical" + }, + right: { + edge: "right", + opposite: "left", + dimension: "width", + orientation: "vertical", + reversed: true + }, + top: { + edge: "top", + opposite: "bottom", + dimension: "height", + orientation: "horizontal" + }, + bottom: { + edge: "bottom", + opposite: "top", + dimension: "height", + orientation: "horizontal", + reversed: true + } + }; + + /** + * Implements `mct-split-pane` directive. + * + * This takes the following attributes: + * * `initial`: Initial positioning to use, as a plain string. + * For example, "30%" + * * `position`: Two-way bound scope variable which will contain + * the pixel position of the splitter, offset from the appropriate + * edge. + * * `anchor`: Plain string, one of "left", "right", "top", + * or "bottom". + * + * When used, an `mct-split-pane` element should contain exactly + * three child elements, where the middle is an `mct-splitter` + * element. These should be included in either left-to-right + * or top-to-bottom order (depending on anchoring.) If the contents + * do not match this form, `mct-split-pane` will issue a warning + * and its behavior will be undefined. + * + * @constructor + */ + function MCTSplitPane($parse, $log) { + var anchors = { + left: true, + right: true, + top: true, + bottom: true + }; + + function controller(scope, element, attrs) { + var anchorKey = attrs.anchor || DEFAULT_ANCHOR, + anchor, + styleValue = attrs.initial, + positionParsed = $parse(attrs.position), + position; // Start undefined, until explicitly set + + // Convert a pixel offset to a calc expression + function calc(offset) { + return "calc(" + styleValue + " + " + offset + "px)"; + } + + // Apply styles to child elements + function updateChildren(children) { + // Pick out correct elements to update, flowing from + // selected anchor edge. + var first = children.eq(anchor.reversed ? 0 : 2), + splitter = children.eq(1), + last = children.eq(anchor.reversed ? 2 : 0); + + first.css(anchor.edge, "0px"); + first.css(anchor.dimension, calc(-HALF_WIDTH)); + + splitter.css(anchor.edge, calc(-HALF_WIDTH)); + splitter.css(anchor.dimension, SPLITTER_WIDTH + "px"); + + last.css(anchor.edge, calc(HALF_WIDTH)); + last.css(anchor.opposite, "0px"); + } + + // Update positioning of contained elements + function updateElementPositions() { + var children = element.children(); + + // Check to make sure contents are well-formed + if (children.length !== 3 || + children[1].nodeName !== 'mct-splitter') { + $log.warn(CHILDREN_WARNING_MESSAGE); + return; + } + + updateChildren(children); + } + + // Getter-setter for the pixel offset of the splitter, + // relative to the current edge. + function getSetPosition(value) { + if (typeof value === 'number') { + position = value; + // Pass change up so this state can be shared + if (positionParsed.assign) { + positionParsed.assign(scope, value); + } + styleValue = position + 'px'; + updateElementPositions(); + } + return position; + } + + // Make sure anchor parameter is something we know + if (!ANCHORS[anchorKey]) { + $log.warn(ANCHOR_WARNING_MESSAGE); + anchorKey = DEFAULT_ANCHOR; + } + anchor = ANCHORS[anchorKey]; + + scope.$watch(attrs.position, getSetPosition); + + // Initialize positions + updateElementPositions(); + + // Interface exposed by controller, for mct-splitter to user + return { + position: getSetPosition, + anchor: function () { + return anchor; + } + }; + } + + return { + // Restrict to attributes + restrict: "A", + // Expose its controller + controller: controller + }; + } + + return MCTSplitPane; + + } +); From 0ee76421e003b5b3351979c6126b570fcf252ba0 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 26 Jun 2015 15:59:16 -0700 Subject: [PATCH 02/11] [Common UI] Add mct-splitter WTD-1363. --- platform/commonUI/general/bundle.json | 13 ++- .../general/src/directives/MCTSplitPane.js | 22 +++-- .../general/src/directives/MCTSplitter.js | 85 +++++++++++++++++++ 3 files changed, 110 insertions(+), 10 deletions(-) create mode 100644 platform/commonUI/general/src/directives/MCTSplitter.js diff --git a/platform/commonUI/general/bundle.json b/platform/commonUI/general/bundle.json index fdac965863..2093a988cd 100644 --- a/platform/commonUI/general/bundle.json +++ b/platform/commonUI/general/bundle.json @@ -8,8 +8,8 @@ "key": "urlService", "implementation": "/services/UrlService.js", "depends": [ "$location" ] - } - ], + } + ], "runs": [ { "implementation": "StyleSheetLoader.js", @@ -131,6 +131,15 @@ "key": "mctScrollY", "implementation": "directives/MCTScroll.js", "depends": [ "$parse", "MCT_SCROLL_Y_PROPERTY", "MCT_SCROLL_Y_ATTRIBUTE" ] + }, + { + "key": "mctSplitPane", + "implementation": "directives/MCTSplitPane.js", + "depends": [ "$parse", "$log" ] + }, + { + "key": "mctSplitter", + "implementation": "directives/MCTSplitter.js" } ], "constants": [ diff --git a/platform/commonUI/general/src/directives/MCTSplitPane.js b/platform/commonUI/general/src/directives/MCTSplitPane.js index dded5f0ea3..88d6e7aeda 100644 --- a/platform/commonUI/general/src/directives/MCTSplitPane.js +++ b/platform/commonUI/general/src/directives/MCTSplitPane.js @@ -27,9 +27,7 @@ define( 'use strict'; // Pixel width to allocate for the splitter itself - var SPLITTER_WIDTH = 8, - HALF_WIDTH = SPLITTER_WIDTH / 2, - DEFAULT_ANCHOR = 'left', + var DEFAULT_ANCHOR = 'left', CHILDREN_WARNING_MESSAGE = [ "Invalid mct-split-pane contents.", "This element should contain exactly three", @@ -111,21 +109,29 @@ define( return "calc(" + styleValue + " + " + offset + "px)"; } + // Get relevant size (height or width) of DOM element + function getSize(splitter) { + return anchor.orientation === 'vertical' ? + splitter.offsetWidth : splitter.offsetHeight; + } + // Apply styles to child elements function updateChildren(children) { // Pick out correct elements to update, flowing from // selected anchor edge. var first = children.eq(anchor.reversed ? 0 : 2), splitter = children.eq(1), - last = children.eq(anchor.reversed ? 2 : 0); + last = children.eq(anchor.reversed ? 2 : 0), + splitterSize = getSize(splitter[0]), + halfSize = splitterSize / 2; first.css(anchor.edge, "0px"); - first.css(anchor.dimension, calc(-HALF_WIDTH)); + first.css(anchor.dimension, calc(-halfSize)); - splitter.css(anchor.edge, calc(-HALF_WIDTH)); - splitter.css(anchor.dimension, SPLITTER_WIDTH + "px"); + splitter.css(anchor.edge, calc(-halfSize)); + splitter.css(anchor.dimension, splitterSize + "px"); - last.css(anchor.edge, calc(HALF_WIDTH)); + last.css(anchor.edge, calc(halfSize)); last.css(anchor.opposite, "0px"); } diff --git a/platform/commonUI/general/src/directives/MCTSplitter.js b/platform/commonUI/general/src/directives/MCTSplitter.js new file mode 100644 index 0000000000..6f87bd8a28 --- /dev/null +++ b/platform/commonUI/general/src/directives/MCTSplitter.js @@ -0,0 +1,85 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +/*global define*/ + +define( + [], + function () { + 'use strict'; + + // Pixel width to allocate for the splitter itself + var SPLITTER_TEMPLATE = "
", + OFFSETS_BY_EDGE = { + left: "offsetLeft", + right: "offsetRight", + top: "offsetTop", + bottom: "offsetBottom" + }; + + /** + * Implements `mct-splitter` directive. + * @constructor + */ + function MCTSplitter() { + function link(scope, element, attrs, mctSplitPane) { + var initialPosition; + + scope.splitter = { + // Begin moving this splitter + startMove: function () { + var splitter = element[0]; + initialPosition = splitter[OFFSETS_BY_EDGE[ + mctSplitPane.anchor().edge + ]]; + }, + // Handle user changes to splitter position + move: function (delta) { + var anchor = mctSplitPane.anchor(), + pixelDelta = delta[ + anchor.orientation === "vertical" ? 0 : 1 + ]; + // Update the position of this splitter + mctSplitPane.position(initialPosition + pixelDelta); + } + }; + } + + return { + // Restrict to attributes + restrict: "E", + // Utilize the mct-split-pane controller + require: "^mctSplitPane", + // Expose its controller + link: link, + // Use the template defined above + template: SPLITTER_TEMPLATE, + // Create a new scope to put the splitter into + scope: true + }; + } + + return MCTSplitter; + + } +); From 39372ea9cadb0448d5c1ba67c7dd82a7d4c5cecf Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 26 Jun 2015 16:21:20 -0700 Subject: [PATCH 03/11] [Common UI] Use mct-split-pane in Browse WTD-1363. --- .../commonUI/browse/res/templates/browse.html | 20 +++++------- .../general/src/directives/MCTSplitPane.js | 31 +++++++++---------- .../general/src/directives/MCTSplitter.js | 4 ++- 3 files changed, 26 insertions(+), 29 deletions(-) diff --git a/platform/commonUI/browse/res/templates/browse.html b/platform/commonUI/browse/res/templates/browse.html index d7991b9649..69211380c9 100644 --- a/platform/commonUI/browse/res/templates/browse.html +++ b/platform/commonUI/browse/res/templates/browse.html @@ -22,10 +22,10 @@
-
-
+ +
@@ -35,18 +35,14 @@
-
-
+ +
-
+
-
\ No newline at end of file +
diff --git a/platform/commonUI/general/src/directives/MCTSplitPane.js b/platform/commonUI/general/src/directives/MCTSplitPane.js index 88d6e7aeda..9e8dd34e58 100644 --- a/platform/commonUI/general/src/directives/MCTSplitPane.js +++ b/platform/commonUI/general/src/directives/MCTSplitPane.js @@ -97,11 +97,11 @@ define( bottom: true }; - function controller(scope, element, attrs) { - var anchorKey = attrs.anchor || DEFAULT_ANCHOR, + function controller($scope, $element, $attrs) { + var anchorKey = $attrs.anchor || DEFAULT_ANCHOR, anchor, - styleValue = attrs.initial, - positionParsed = $parse(attrs.position), + styleValue = $attrs.initial, + positionParsed = $parse($attrs.position), position; // Start undefined, until explicitly set // Convert a pixel offset to a calc expression @@ -119,29 +119,28 @@ define( function updateChildren(children) { // Pick out correct elements to update, flowing from // selected anchor edge. - var first = children.eq(anchor.reversed ? 0 : 2), + var first = children.eq(anchor.reversed ? 2 : 0), splitter = children.eq(1), - last = children.eq(anchor.reversed ? 2 : 0), + last = children.eq(anchor.reversed ? 0 : 2), splitterSize = getSize(splitter[0]), - halfSize = splitterSize / 2; + offsetSize = splitterSize / 2; first.css(anchor.edge, "0px"); - first.css(anchor.dimension, calc(-halfSize)); + first.css(anchor.dimension, calc(-offsetSize)); - splitter.css(anchor.edge, calc(-halfSize)); - splitter.css(anchor.dimension, splitterSize + "px"); + splitter.css(anchor.edge, styleValue); - last.css(anchor.edge, calc(halfSize)); + last.css(anchor.edge, calc(offsetSize)); last.css(anchor.opposite, "0px"); } // Update positioning of contained elements function updateElementPositions() { - var children = element.children(); + var children = $element.children(); // Check to make sure contents are well-formed if (children.length !== 3 || - children[1].nodeName !== 'mct-splitter') { + children[1].nodeName.toLowerCase() !== 'mct-splitter') { $log.warn(CHILDREN_WARNING_MESSAGE); return; } @@ -156,7 +155,7 @@ define( position = value; // Pass change up so this state can be shared if (positionParsed.assign) { - positionParsed.assign(scope, value); + positionParsed.assign($scope, value); } styleValue = position + 'px'; updateElementPositions(); @@ -171,7 +170,7 @@ define( } anchor = ANCHORS[anchorKey]; - scope.$watch(attrs.position, getSetPosition); + $scope.$watch($attrs.position, getSetPosition); // Initialize positions updateElementPositions(); @@ -187,7 +186,7 @@ define( return { // Restrict to attributes - restrict: "A", + restrict: "E", // Expose its controller controller: controller }; diff --git a/platform/commonUI/general/src/directives/MCTSplitter.js b/platform/commonUI/general/src/directives/MCTSplitter.js index 6f87bd8a28..fa14e6af6f 100644 --- a/platform/commonUI/general/src/directives/MCTSplitter.js +++ b/platform/commonUI/general/src/directives/MCTSplitter.js @@ -27,7 +27,7 @@ define( 'use strict'; // Pixel width to allocate for the splitter itself - var SPLITTER_TEMPLATE = "
", OFFSETS_BY_EDGE = { @@ -45,6 +45,8 @@ define( function link(scope, element, attrs, mctSplitPane) { var initialPosition; + element.addClass("splitter"); + scope.splitter = { // Begin moving this splitter startMove: function () { From 72c812cdaa2944251a74af86934d96a022adb550 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 26 Jun 2015 16:30:39 -0700 Subject: [PATCH 04/11] [Common UI] Enforce split pane min/max WTD-1363. --- .../commonUI/browse/res/templates/browse.html | 2 ++ .../general/src/directives/MCTSplitPane.js | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/platform/commonUI/browse/res/templates/browse.html b/platform/commonUI/browse/res/templates/browse.html index 69211380c9..3e180b8bac 100644 --- a/platform/commonUI/browse/res/templates/browse.html +++ b/platform/commonUI/browse/res/templates/browse.html @@ -24,6 +24,8 @@
diff --git a/platform/commonUI/general/src/directives/MCTSplitPane.js b/platform/commonUI/general/src/directives/MCTSplitPane.js index 9e8dd34e58..808acb84ae 100644 --- a/platform/commonUI/general/src/directives/MCTSplitPane.js +++ b/platform/commonUI/general/src/directives/MCTSplitPane.js @@ -79,6 +79,8 @@ define( * edge. * * `anchor`: Plain string, one of "left", "right", "top", * or "bottom". + * * `maximum`: Maximum pixel width, as a literal numeric value + * * `minimum`: Minimum pixel width, as a literal numeric value * * When used, an `mct-split-pane` element should contain exactly * three child elements, where the middle is an `mct-splitter` @@ -99,6 +101,8 @@ define( function controller($scope, $element, $attrs) { var anchorKey = $attrs.anchor || DEFAULT_ANCHOR, + maximum = parseInt($attrs.maximum, 10), + minimum = parseInt($attrs.minimum, 10), anchor, styleValue = $attrs.initial, positionParsed = $parse($attrs.position), @@ -148,11 +152,27 @@ define( updateChildren(children); } + // Enforce minimum/maximum positions + function enforceExtrema() { + // Pick default min/max + var min = isNaN(minimum) ? 0 : minimum, + max = isNaN(maximum) ? + Number.POSITIVE_INFINITY : maximum; + // Disallow a max greater than the element's size + max = Math.min($element[0].offsetWidth, max); + // Finally, restrict position to allowed min/max + position = Math.max(position, min); + position = Math.min(position, max); + } + // Getter-setter for the pixel offset of the splitter, // relative to the current edge. function getSetPosition(value) { + var min, max; if (typeof value === 'number') { position = value; + enforceExtrema(); + // Pass change up so this state can be shared if (positionParsed.assign) { positionParsed.assign($scope, value); From a1eb15db772e779f2143a3fa9969fc86d0cb6223 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Sat, 27 Jun 2015 10:35:49 -0700 Subject: [PATCH 05/11] [Common UI] Change min/max width handling in splitter In split pane, obey the min-width and max-width style properties of first element within the pane. WTD-1363. --- .../commonUI/browse/res/templates/browse.html | 5 ++-- .../general/src/directives/MCTSplitPane.js | 24 +++++++++++-------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/platform/commonUI/browse/res/templates/browse.html b/platform/commonUI/browse/res/templates/browse.html index 3e180b8bac..d8a96ab78e 100644 --- a/platform/commonUI/browse/res/templates/browse.html +++ b/platform/commonUI/browse/res/templates/browse.html @@ -24,10 +24,9 @@
-
+
diff --git a/platform/commonUI/general/src/directives/MCTSplitPane.js b/platform/commonUI/general/src/directives/MCTSplitPane.js index 808acb84ae..11f3d46fad 100644 --- a/platform/commonUI/general/src/directives/MCTSplitPane.js +++ b/platform/commonUI/general/src/directives/MCTSplitPane.js @@ -108,15 +108,16 @@ define( positionParsed = $parse($attrs.position), position; // Start undefined, until explicitly set - // Convert a pixel offset to a calc expression - function calc(offset) { - return "calc(" + styleValue + " + " + offset + "px)"; + // Create a calc CSS expression + function calcSum(a, b) { + return "calc(" + a + " + " + b + ")"; } // Get relevant size (height or width) of DOM element - function getSize(splitter) { - return anchor.orientation === 'vertical' ? - splitter.offsetWidth : splitter.offsetHeight; + function getSize(domElement) { + return (anchor.orientation === 'vertical' ? + domElement.offsetWidth : domElement.offsetHeight) + + "px"; } // Apply styles to child elements @@ -127,14 +128,17 @@ define( splitter = children.eq(1), last = children.eq(anchor.reversed ? 0 : 2), splitterSize = getSize(splitter[0]), - offsetSize = splitterSize / 2; + firstSize; first.css(anchor.edge, "0px"); - first.css(anchor.dimension, calc(-offsetSize)); + first.css(anchor.dimension, styleValue); - splitter.css(anchor.edge, styleValue); + // Get actual size (to obey min-width) + firstSize = getSize(first[0]); - last.css(anchor.edge, calc(offsetSize)); + splitter.css(anchor.edge, firstSize); + + last.css(anchor.edge, calcSum(firstSize, splitterSize)); last.css(anchor.opposite, "0px"); } From c79b018c845ec149a519a79cbbec644f1a332d84 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Sat, 27 Jun 2015 10:40:05 -0700 Subject: [PATCH 06/11] [Common UI] Remove obsolete checks Remove obsolete minimum/maximum checks, WTD-1363. --- .../general/src/directives/MCTSplitPane.js | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/platform/commonUI/general/src/directives/MCTSplitPane.js b/platform/commonUI/general/src/directives/MCTSplitPane.js index 11f3d46fad..c53f50947b 100644 --- a/platform/commonUI/general/src/directives/MCTSplitPane.js +++ b/platform/commonUI/general/src/directives/MCTSplitPane.js @@ -79,8 +79,6 @@ define( * edge. * * `anchor`: Plain string, one of "left", "right", "top", * or "bottom". - * * `maximum`: Maximum pixel width, as a literal numeric value - * * `minimum`: Minimum pixel width, as a literal numeric value * * When used, an `mct-split-pane` element should contain exactly * three child elements, where the middle is an `mct-splitter` @@ -89,6 +87,12 @@ define( * do not match this form, `mct-split-pane` will issue a warning * and its behavior will be undefined. * + * This directive works by setting the width of the element + * nearest the anchor edge, and then positioning the other elements + * based on its observed width. As such, `min-width`, `max-width`, + * etc. can be set on that element to control the splitter's + * allowable positions. + * * @constructor */ function MCTSplitPane($parse, $log) { @@ -101,8 +105,6 @@ define( function controller($scope, $element, $attrs) { var anchorKey = $attrs.anchor || DEFAULT_ANCHOR, - maximum = parseInt($attrs.maximum, 10), - minimum = parseInt($attrs.minimum, 10), anchor, styleValue = $attrs.initial, positionParsed = $parse($attrs.position), @@ -133,7 +135,7 @@ define( first.css(anchor.edge, "0px"); first.css(anchor.dimension, styleValue); - // Get actual size (to obey min-width) + // Get actual size (to obey min-width etc.) firstSize = getSize(first[0]); splitter.css(anchor.edge, firstSize); @@ -158,15 +160,8 @@ define( // Enforce minimum/maximum positions function enforceExtrema() { - // Pick default min/max - var min = isNaN(minimum) ? 0 : minimum, - max = isNaN(maximum) ? - Number.POSITIVE_INFINITY : maximum; - // Disallow a max greater than the element's size - max = Math.min($element[0].offsetWidth, max); - // Finally, restrict position to allowed min/max - position = Math.max(position, min); - position = Math.min(position, max); + position = Math.max(position, 0); + position = Math.min(position, $element[0].offsetWidth); } // Getter-setter for the pixel offset of the splitter, From a0d5a1a196516518540788bfd6a2d54b29c75bea Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Sat, 27 Jun 2015 10:46:42 -0700 Subject: [PATCH 07/11] [Common UI] Get split pane width from elements WTD-1363. --- .../commonUI/browse/res/templates/browse.html | 6 ++---- .../general/src/directives/MCTSplitPane.js | 15 +++++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/platform/commonUI/browse/res/templates/browse.html b/platform/commonUI/browse/res/templates/browse.html index d8a96ab78e..0a7698e8bd 100644 --- a/platform/commonUI/browse/res/templates/browse.html +++ b/platform/commonUI/browse/res/templates/browse.html @@ -22,11 +22,9 @@
- +
+ style="min-width: 150px; max-width: 800px; width: 25%;">
diff --git a/platform/commonUI/general/src/directives/MCTSplitPane.js b/platform/commonUI/general/src/directives/MCTSplitPane.js index c53f50947b..fff3d095c8 100644 --- a/platform/commonUI/general/src/directives/MCTSplitPane.js +++ b/platform/commonUI/general/src/directives/MCTSplitPane.js @@ -72,8 +72,6 @@ define( * Implements `mct-split-pane` directive. * * This takes the following attributes: - * * `initial`: Initial positioning to use, as a plain string. - * For example, "30%" * * `position`: Two-way bound scope variable which will contain * the pixel position of the splitter, offset from the appropriate * edge. @@ -106,7 +104,7 @@ define( function controller($scope, $element, $attrs) { var anchorKey = $attrs.anchor || DEFAULT_ANCHOR, anchor, - styleValue = $attrs.initial, + styleValue, positionParsed = $parse($attrs.position), position; // Start undefined, until explicitly set @@ -133,11 +131,13 @@ define( firstSize; first.css(anchor.edge, "0px"); - first.css(anchor.dimension, styleValue); + if (styleValue !== undefined) { + first.css(anchor.dimension, styleValue); + } // Get actual size (to obey min-width etc.) firstSize = getSize(first[0]); - + first.css(anchor.dimension, firstSize); splitter.css(anchor.edge, firstSize); last.css(anchor.edge, calcSum(firstSize, splitterSize)); @@ -191,6 +191,9 @@ define( $scope.$watch($attrs.position, getSetPosition); + $element.addClass("split-layout"); + $element.addClass(anchor.orientation); + // Initialize positions updateElementPositions(); @@ -207,7 +210,7 @@ define( // Restrict to attributes restrict: "E", // Expose its controller - controller: controller + controller: ['$scope', '$element', '$attrs', controller] }; } From 8c5b497377c2439ee88437d886979403d8369471 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Sat, 27 Jun 2015 11:59:18 -0700 Subject: [PATCH 08/11] [Common UI] Tweak mct-split-pane Tweak mct-split-pane for use in timeline; particularly, improve synchronization between views. WTD-1363. --- .../general/src/directives/MCTSplitPane.js | 26 +++++++++---------- .../general/src/directives/MCTSplitter.js | 15 ++++++----- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/platform/commonUI/general/src/directives/MCTSplitPane.js b/platform/commonUI/general/src/directives/MCTSplitPane.js index fff3d095c8..899a8f5ad2 100644 --- a/platform/commonUI/general/src/directives/MCTSplitPane.js +++ b/platform/commonUI/general/src/directives/MCTSplitPane.js @@ -104,7 +104,6 @@ define( function controller($scope, $element, $attrs) { var anchorKey = $attrs.anchor || DEFAULT_ANCHOR, anchor, - styleValue, positionParsed = $parse($attrs.position), position; // Start undefined, until explicitly set @@ -116,8 +115,7 @@ define( // Get relevant size (height or width) of DOM element function getSize(domElement) { return (anchor.orientation === 'vertical' ? - domElement.offsetWidth : domElement.offsetHeight) - + "px"; + domElement.offsetWidth : domElement.offsetHeight); } // Apply styles to child elements @@ -131,17 +129,18 @@ define( firstSize; first.css(anchor.edge, "0px"); - if (styleValue !== undefined) { - first.css(anchor.dimension, styleValue); - } + first.css(anchor.dimension, (position - splitterSize) + 'px'); // Get actual size (to obey min-width etc.) firstSize = getSize(first[0]); - first.css(anchor.dimension, firstSize); - splitter.css(anchor.edge, firstSize); + first.css(anchor.dimension, firstSize + 'px'); + splitter.css(anchor.edge, (firstSize + splitterSize) + 'px'); + splitter.css(anchor.opposite, "auto"); - last.css(anchor.edge, calcSum(firstSize, splitterSize)); + last.css(anchor.edge, (firstSize + splitterSize * 3) + 'px'); last.css(anchor.opposite, "0px"); + + position = firstSize + splitterSize; } // Update positioning of contained elements @@ -171,13 +170,12 @@ define( if (typeof value === 'number') { position = value; enforceExtrema(); + updateElementPositions(); // Pass change up so this state can be shared if (positionParsed.assign) { - positionParsed.assign($scope, value); + positionParsed.assign($scope, position); } - styleValue = position + 'px'; - updateElementPositions(); } return position; } @@ -195,7 +193,9 @@ define( $element.addClass(anchor.orientation); // Initialize positions - updateElementPositions(); + getSetPosition(getSize( + $element.children().eq(anchor.reversed ? 2 : 0)[0] + )); // Interface exposed by controller, for mct-splitter to user return { diff --git a/platform/commonUI/general/src/directives/MCTSplitter.js b/platform/commonUI/general/src/directives/MCTSplitter.js index fa14e6af6f..0494830057 100644 --- a/platform/commonUI/general/src/directives/MCTSplitter.js +++ b/platform/commonUI/general/src/directives/MCTSplitter.js @@ -47,20 +47,23 @@ define( element.addClass("splitter"); + // Now that we have the above class, the splitter width + // will have changed, so trigger a positioning update. + mctSplitPane.position(mctSplitPane.position()); + scope.splitter = { // Begin moving this splitter startMove: function () { var splitter = element[0]; - initialPosition = splitter[OFFSETS_BY_EDGE[ - mctSplitPane.anchor().edge - ]]; + initialPosition = mctSplitPane.position(); }, // Handle user changes to splitter position move: function (delta) { var anchor = mctSplitPane.anchor(), - pixelDelta = delta[ - anchor.orientation === "vertical" ? 0 : 1 - ]; + index = anchor.orientation === "vertical" ? 0 : 1, + pixelDelta = delta[index] * + (anchor.reversed ? -1 : 1); + // Update the position of this splitter mctSplitPane.position(initialPosition + pixelDelta); } From c262fe814ca12b3bb2b7cf9277f5e020805d33dc Mon Sep 17 00:00:00 2001 From: Charles Hacskaylo Date: Mon, 29 Jun 2015 11:08:28 -0700 Subject: [PATCH 09/11] [Frontend] Added pointer-events: none WTD-1363? --- .../general/res/css/theme-espresso.css | 89 +++++++++++++++++-- platform/commonUI/general/res/css/tree.css | 2 +- .../commonUI/general/res/sass/_mixins.scss | 6 +- 3 files changed, 87 insertions(+), 10 deletions(-) diff --git a/platform/commonUI/general/res/css/theme-espresso.css b/platform/commonUI/general/res/css/theme-espresso.css index 3d7f1572df..12c5c7064b 100644 --- a/platform/commonUI/general/res/css/theme-espresso.css +++ b/platform/commonUI/general/res/css/theme-espresso.css @@ -2268,18 +2268,43 @@ label.checkbox.custom { color: #757575; } /* line 176, ../sass/_mixins.scss */ .slider .knob:before { + -moz-transition-property: "border-color"; + -o-transition-property: "border-color"; + -webkit-transition-property: "border-color"; + transition-property: "border-color"; + -moz-transition-duration: 0.75s; + -o-transition-duration: 0.75s; + -webkit-transition-duration: 0.75s; + transition-duration: 0.75s; + -moz-transition-timing-function: ease-in-out; + -o-transition-timing-function: ease-in-out; + -webkit-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; content: ''; display: block; height: auto; + pointer-events: none; position: absolute; z-index: 2; border-left: 1px solid rgba(0, 0, 0, 0.3); left: 2px; bottom: 5px; top: 5px; } - /* line 197, ../sass/_mixins.scss */ + /* line 198, ../sass/_mixins.scss */ .slider .knob:not(.disabled):hover:before { - border-color: rgba(0, 153, 204, 0.9); } + -moz-transition-property: "border-color"; + -o-transition-property: "border-color"; + -webkit-transition-property: "border-color"; + transition-property: "border-color"; + -moz-transition-duration: 50ms; + -o-transition-duration: 50ms; + -webkit-transition-duration: 50ms; + transition-duration: 50ms; + -moz-transition-timing-function: ease-in-out; + -o-transition-timing-function: ease-in-out; + -webkit-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; + border-color: #0099cc; } /* line 409, ../sass/controls/_controls.scss */ .slider .knob:before { top: 1px; @@ -2444,7 +2469,7 @@ label.checkbox.custom { .menu-element .menu ul { margin: 0; padding: 0; } - /* line 264, ../sass/_mixins.scss */ + /* line 266, ../sass/_mixins.scss */ .menu-element .menu ul li { list-style-type: none; margin: 0; @@ -4523,18 +4548,43 @@ input[type="text"] { height: 5px; } /* line 176, ../sass/_mixins.scss */ .split-layout.horizontal > .splitter:before { + -moz-transition-property: "border-color"; + -o-transition-property: "border-color"; + -webkit-transition-property: "border-color"; + transition-property: "border-color"; + -moz-transition-duration: 0.75s; + -o-transition-duration: 0.75s; + -webkit-transition-duration: 0.75s; + transition-duration: 0.75s; + -moz-transition-timing-function: ease-in-out; + -o-transition-timing-function: ease-in-out; + -webkit-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; content: ''; display: block; height: auto; + pointer-events: none; position: absolute; z-index: 2; border-top: 1px dotted #1a1a1a; top: 2px; left: 5px; right: 5px; } - /* line 197, ../sass/_mixins.scss */ + /* line 198, ../sass/_mixins.scss */ .split-layout.horizontal > .splitter:not(.disabled):hover:before { - border-color: rgba(0, 153, 204, 0.9); } + -moz-transition-property: "border-color"; + -o-transition-property: "border-color"; + -webkit-transition-property: "border-color"; + transition-property: "border-color"; + -moz-transition-duration: 50ms; + -o-transition-duration: 50ms; + -webkit-transition-duration: 50ms; + transition-duration: 50ms; + -moz-transition-timing-function: ease-in-out; + -o-transition-timing-function: ease-in-out; + -webkit-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; + border-color: #0099cc; } /* line 63, ../sass/helpers/_splitter.scss */ .split-layout.vertical .pane { top: 0; @@ -4552,18 +4602,43 @@ input[type="text"] { width: 5px; } /* line 176, ../sass/_mixins.scss */ .split-layout.vertical > .splitter:before { + -moz-transition-property: "border-color"; + -o-transition-property: "border-color"; + -webkit-transition-property: "border-color"; + transition-property: "border-color"; + -moz-transition-duration: 0.75s; + -o-transition-duration: 0.75s; + -webkit-transition-duration: 0.75s; + transition-duration: 0.75s; + -moz-transition-timing-function: ease-in-out; + -o-transition-timing-function: ease-in-out; + -webkit-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; content: ''; display: block; height: auto; + pointer-events: none; position: absolute; z-index: 2; border-left: 1px dotted #1a1a1a; left: 2px; bottom: 5px; top: 5px; } - /* line 197, ../sass/_mixins.scss */ + /* line 198, ../sass/_mixins.scss */ .split-layout.vertical > .splitter:not(.disabled):hover:before { - border-color: rgba(0, 153, 204, 0.9); } + -moz-transition-property: "border-color"; + -o-transition-property: "border-color"; + -webkit-transition-property: "border-color"; + transition-property: "border-color"; + -moz-transition-duration: 50ms; + -o-transition-duration: 50ms; + -webkit-transition-duration: 50ms; + transition-duration: 50ms; + -moz-transition-timing-function: ease-in-out; + -o-transition-timing-function: ease-in-out; + -webkit-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; + border-color: #0099cc; } /* line 86, ../sass/helpers/_splitter.scss */ .browse-area .splitter { diff --git a/platform/commonUI/general/res/css/tree.css b/platform/commonUI/general/res/css/tree.css index 2582522f39..9a19d9401f 100644 --- a/platform/commonUI/general/res/css/tree.css +++ b/platform/commonUI/general/res/css/tree.css @@ -95,7 +95,7 @@ ul.tree { margin: 0; padding: 0; } - /* line 264, ../sass/_mixins.scss */ + /* line 266, ../sass/_mixins.scss */ ul.tree li { list-style-type: none; margin: 0; diff --git a/platform/commonUI/general/res/sass/_mixins.scss b/platform/commonUI/general/res/sass/_mixins.scss index 14a123d954..2674bc8527 100644 --- a/platform/commonUI/general/res/sass/_mixins.scss +++ b/platform/commonUI/general/res/sass/_mixins.scss @@ -174,10 +174,11 @@ @mixin controlGrippy($b, $direction: horizontal, $w: 1px, $style: dotted) { &:before { - // Grippy + @include trans-prop-nice("border-color",0.75s); content: ''; display: block; height: auto; + pointer-events: none; position: absolute; z-index: 2; @@ -195,7 +196,8 @@ } } &:not(.disabled):hover:before { - border-color: rgba($colorKey, 0.9); + @include trans-prop-nice("border-color",50ms); + border-color: $colorKey; } } From b524dc451fb886a10261e1ea594253910ceb4002 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Mon, 29 Jun 2015 11:27:48 -0700 Subject: [PATCH 10/11] [Common UI] Remove unused function Remove obsolete function from mct-split-pane, WTD-1363 --- platform/commonUI/general/src/directives/MCTSplitPane.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/platform/commonUI/general/src/directives/MCTSplitPane.js b/platform/commonUI/general/src/directives/MCTSplitPane.js index 899a8f5ad2..8c9493364a 100644 --- a/platform/commonUI/general/src/directives/MCTSplitPane.js +++ b/platform/commonUI/general/src/directives/MCTSplitPane.js @@ -107,11 +107,6 @@ define( positionParsed = $parse($attrs.position), position; // Start undefined, until explicitly set - // Create a calc CSS expression - function calcSum(a, b) { - return "calc(" + a + " + " + b + ")"; - } - // Get relevant size (height or width) of DOM element function getSize(domElement) { return (anchor.orientation === 'vertical' ? From 66f8ee719465f0b635b90bbc86125401d40dec81 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Mon, 29 Jun 2015 11:54:30 -0700 Subject: [PATCH 11/11] [Common UI] Fix min/max bounds of mct-split-pane WTD-1363. Use correct dimension (width or height) when determining maximum splitter position. --- platform/commonUI/general/src/directives/MCTSplitPane.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/commonUI/general/src/directives/MCTSplitPane.js b/platform/commonUI/general/src/directives/MCTSplitPane.js index 8c9493364a..8d95ff2b69 100644 --- a/platform/commonUI/general/src/directives/MCTSplitPane.js +++ b/platform/commonUI/general/src/directives/MCTSplitPane.js @@ -155,7 +155,7 @@ define( // Enforce minimum/maximum positions function enforceExtrema() { position = Math.max(position, 0); - position = Math.min(position, $element[0].offsetWidth); + position = Math.min(position, getSize($element[0])); } // Getter-setter for the pixel offset of the splitter,