Merge remote-tracking branch 'github/master' into open181

Conflicts:
	platform/commonUI/general/res/templates/controls/time-controller.html
This commit is contained in:
Victor Woeltjen
2015-10-21 14:40:42 -07:00
32 changed files with 1295 additions and 731 deletions

View File

@@ -375,20 +375,6 @@
overflow-y: $showBar;
}
@mixin wait-spinner($b: 5px, $c: $colorAlt1) {
display: block;
position: absolute;
-webkit-animation: rotation .6s infinite linear;
-moz-animation: rotation .6s infinite linear;
-o-animation: rotation .6s infinite linear;
animation: rotation .6s infinite linear;
border-color: rgba($c, 0.25);
border-top-color: rgba($c, 1.0);
border-style: solid;
border-width: $b;
border-radius: 100%;
}
@mixin test($c: #ffcc00, $a: 0.2) {
background-color: rgba($c, $a) !important;
}

View File

@@ -356,7 +356,7 @@ label.checkbox.custom {
.l-month-year-pager {
$pagerW: 20px;
//@include test();
font-size: 0.8rem;
//font-size: 0.8rem;
height: $r1H;
margin-bottom: $interiorMargin;
position: relative;

View File

@@ -10,8 +10,8 @@
}
.l-time-controller {
$minW: 400px;
mct-include.l-time-controller {
$minW: 500px;
$knobHOffset: 0px;
$knobM: ($sliderKnobW + $knobHOffset) * -1;
$rangeValPad: $interiorMargin;
@@ -22,11 +22,17 @@
$r2H: nth($ueTimeControlH,2);
$r3H: nth($ueTimeControlH,3);
//height: $r1H + $r2H + $r3H + ($interiorMargin * 2);
@include absPosDefault();
//@include test();
display: block;
top: auto;
height: $r1H + $r2H + $r3H + ($interiorMargin * 2);
min-width: $minW;
font-size: 0.8rem;
.l-time-range-inputs-holder,
.l-time-range-slider {
font-size: 0.8em;
//font-size: 0.8em;
}
.l-time-range-inputs-holder,
@@ -36,7 +42,6 @@
//@include test();
@include absPosDefault(0, visible);
@include box-sizing(border-box);
min-width: $minW;
top: auto;
}
.l-time-range-slider,
@@ -141,7 +146,7 @@
@include webkitProp(transform, translateX(-50%));
color: $colorPlotLabelFg;
display: inline-block;
font-size: 0.7em;
font-size: 0.9em;
position: absolute;
top: 8px;
white-space: nowrap;

View File

@@ -19,24 +19,45 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
@-webkit-keyframes rotation {
from {-webkit-transform: rotate(0deg);}
to {-webkit-transform: rotate(359deg);}
@include keyframes(rotation) {
0% { transform: rotate(0deg); }
100% { transform: rotate(359deg); }
}
@-moz-keyframes rotation {
from {-moz-transform: rotate(0deg);}
to {-moz-transform: rotate(359deg);}
@mixin wait-spinner2($b: 5px, $c: $colorAlt1) {
@include keyframes(rotateCentered) {
0% { transform: translateX(-50%) translateY(-50%) rotate(0deg); }
100% { transform: translateX(-50%) translateY(-50%) rotate(359deg); }
}
@include animation-name(rotateCentered);
@include animation-duration(0.5s);
@include animation-iteration-count(infinite);
@include animation-timing-function(linear);
border-color: rgba($c, 0.25);
border-top-color: rgba($c, 1.0);
border-style: solid;
border-width: 5px;
@include border-radius(100%);
@include box-sizing(border-box);
display: block;
position: absolute;
height: 0; width: 0;
padding: 7%;
left: 50%; top: 50%;
}
@-o-keyframes rotation {
from {-o-transform: rotate(0deg);}
to {-o-transform: rotate(359deg);}
}
@keyframes rotation {
from {transform: rotate(0deg);}
to {transform: rotate(359deg);}
@mixin wait-spinner($b: 5px, $c: $colorAlt1) {
display: block;
position: absolute;
-webkit-animation: rotation .6s infinite linear;
-moz-animation: rotation .6s infinite linear;
-o-animation: rotation .6s infinite linear;
animation: rotation .6s infinite linear;
border-color: rgba($c, 0.25);
border-top-color: rgba($c, 1.0);
border-style: solid;
border-width: $b;
@include border-radius(100%);
}
.t-wait-spinner,
@@ -96,4 +117,28 @@
margin-top: 0 !important;
padding: 0 !important;
top: 0; left: 0;
}
.loading {
// Can be applied to any block element with height and width
pointer-events: none;
&:before,
&:after {
content: '';
}
&:before {
@include wait-spinner2(5px, $colorLoadingFg);
z-index: 10;
}
&:after {
@include absPosDefault();
background: $colorLoadingBg;
display: block;
z-index: 9;
}
&.tree-item:before {
padding: $menuLineH / 4;
border-width: 2px;
}
}

View File

@@ -214,8 +214,6 @@
.search-scroll {
order: 3;
//padding-right: $rightPadding;
margin-top: 4px;
// Adjustable scrolling size
@@ -227,28 +225,6 @@
.load-icon {
position: relative;
&.loading {
pointer-events: none;
margin-left: $leftMargin;
.title-label {
// Text styling
font-style: italic;
font-size: .9em;
opacity: 0.5;
// Text positioning
margin-left: $iconWidth + $leftMargin;
line-height: 24px;
}
.wait-spinner {
margin-left: $leftMargin;
}
}
&:not(.loading) {
cursor: pointer;
}
}
.load-more-button {

View File

@@ -83,7 +83,6 @@ ul.tree {
.icon {
&.l-icon-link,
&.l-icon-alert {
//@include txtShdw($shdwItemTreeIcon);
position: absolute;
z-index: 2;
}
@@ -105,26 +104,12 @@ ul.tree {
@include absPosDefault();
display: block;
left: $runningItemW + ($interiorMargin * 3);
//right: $treeContextTriggerW + $interiorMargin;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
&.loading {
pointer-events: none;
.label {
opacity: 0.5;
.title-label {
font-style: italic;
}
}
.wait-spinner {
margin-left: 14px;
}
}
&.selected {
background: $colorItemTreeSelectedBg;
color: $colorItemTreeSelectedFg;
@@ -142,9 +127,6 @@ ul.tree {
&:hover {
background: rgba($colorBodyFg, 0.1); //lighten($colorBodyBg, 5%);
color: pullForward($colorBodyFg, 20%);
//.context-trigger {
// display: block;
//}
.icon {
color: $colorItemTreeIconHover;
}
@@ -158,7 +140,6 @@ ul.tree {
.context-trigger {
$h: 0.9rem;
//display: none;
top: -1px;
position: absolute;
right: $interiorMarginSm;

View File

@@ -294,9 +294,7 @@
}
&.l-controls-visible {
&.l-time-controller-visible {
> ng-include {
bottom: nth($ueTimeControlH,1) + nth($ueTimeControlH,2) +nth($ueTimeControlH,3) + ($interiorMargin * 3);
}
bottom: nth($ueTimeControlH,1) + nth($ueTimeControlH,2) +nth($ueTimeControlH,3) + ($interiorMargin * 3);
}
}
}

View File

@@ -19,16 +19,14 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<!-- MINE -->
<div class="l-time-controller" ng-controller="TimeRangeController">
<div ng-controller="TimeRangeController">
<div class="l-time-range-inputs-holder">
<span class="l-time-range-inputs-elem ui-symbol type-icon">&#x43;</span>
<span class="l-time-range-input" ng-controller="ToggleController as t1">
<!--<span class="lbl">Start</span>-->
<span class="s-btn time-range-start">
<input type="text" ng-model="boundsModel.start"></input>
<a class="ui-symbol icon icon-calendar" ng-click="t1.toggle()">
</a>
<a class="ui-symbol icon icon-calendar" ng-click="t1.toggle()"></a>
<mct-popup ng-if="t1.isActive()">
<div mct-click-elsewhere="t1.setState(false)">
<mct-control key="'datetime-picker'"

View File

@@ -35,6 +35,8 @@ define(
*/
function TimeConductorController($scope, now) {
var tickCount = 2,
innerMinimumSpan = 1000, // 1 second
outerMinimumSpan = 1000 * 60 * 60, // 1 hour
initialDragValue;
function formatTimestamp(ts) {
@@ -139,7 +141,7 @@ define(
$scope.ngModel.inner.start = clamp(
initialDragValue + delta,
$scope.ngModel.outer.start,
$scope.ngModel.inner.end
$scope.ngModel.inner.end - innerMinimumSpan
);
updateViewFromModel($scope.ngModel);
}
@@ -148,7 +150,7 @@ define(
var delta = toMillis(pixels);
$scope.ngModel.inner.end = clamp(
initialDragValue + delta,
$scope.ngModel.inner.start,
$scope.ngModel.inner.start + innerMinimumSpan,
$scope.ngModel.outer.end
);
updateViewFromModel($scope.ngModel);
@@ -174,12 +176,18 @@ define(
function updateOuterStart(t) {
var ngModel = $scope.ngModel;
ngModel.outer.end =
Math.max(ngModel.outer.start, ngModel.outer.end);
ngModel.outer.end = Math.max(
ngModel.outer.start + outerMinimumSpan,
ngModel.outer.end
);
ngModel.inner.start =
Math.max(ngModel.outer.start, ngModel.inner.start);
ngModel.inner.end =
Math.max(ngModel.outer.start, ngModel.inner.end);
ngModel.inner.end = Math.max(
ngModel.inner.start + innerMinimumSpan,
ngModel.inner.end
);
$scope.startOuterText = formatTimestamp(t);
@@ -188,12 +196,18 @@ define(
function updateOuterEnd(t) {
var ngModel = $scope.ngModel;
ngModel.outer.start =
Math.min(ngModel.outer.end, ngModel.outer.start);
ngModel.inner.start =
Math.min(ngModel.outer.end, ngModel.inner.start);
ngModel.outer.start = Math.min(
ngModel.outer.end - outerMinimumSpan,
ngModel.outer.start
);
ngModel.inner.end =
Math.min(ngModel.outer.end, ngModel.inner.end);
ngModel.inner.start = Math.min(
ngModel.inner.end - innerMinimumSpan,
ngModel.inner.start
);
$scope.endOuterText = formatTimestamp(t);

View File

@@ -26,6 +26,11 @@ define(
function (TimeRangeController) {
"use strict";
var SEC = 1000,
MIN = 60 * SEC,
HOUR = 60 * MIN,
DAY = 24 * HOUR;
describe("The TimeRangeController", function () {
var mockScope,
mockNow,
@@ -61,6 +66,107 @@ define(
.toHaveBeenCalledWith("ngModel", jasmine.any(Function));
});
describe("when dragged", function () {
beforeEach(function () {
mockScope.ngModel = {
outer: {
start: DAY * 1000,
end: DAY * 1001
},
inner: {
start: DAY * 1000 + HOUR * 3,
end: DAY * 1001 - HOUR * 3
}
};
mockScope.spanWidth = 1000;
fireWatch("spanWidth", mockScope.spanWidth);
fireWatchCollection("ngModel", mockScope.ngModel);
});
it("updates the start time for left drags", function () {
mockScope.startLeftDrag();
mockScope.leftDrag(250);
expect(mockScope.ngModel.inner.start)
.toEqual(DAY * 1000 + HOUR * 9);
});
it("updates the end time for right drags", function () {
mockScope.startRightDrag();
mockScope.rightDrag(-250);
expect(mockScope.ngModel.inner.end)
.toEqual(DAY * 1000 + HOUR * 15);
});
it("updates both start and end for middle drags", function () {
mockScope.startMiddleDrag();
mockScope.middleDrag(-125);
expect(mockScope.ngModel.inner).toEqual({
start: DAY * 1000,
end: DAY * 1000 + HOUR * 18
});
mockScope.middleDrag(250);
expect(mockScope.ngModel.inner).toEqual({
start: DAY * 1000 + HOUR * 6,
end: DAY * 1001
});
});
it("enforces a minimum inner span", function () {
mockScope.startRightDrag();
mockScope.rightDrag(-9999999);
expect(mockScope.ngModel.inner.end)
.toBeGreaterThan(mockScope.ngModel.inner.start);
});
});
describe("when outer bounds are changed", function () {
beforeEach(function () {
mockScope.ngModel = {
outer: {
start: DAY * 1000,
end: DAY * 1001
},
inner: {
start: DAY * 1000 + HOUR * 3,
end: DAY * 1001 - HOUR * 3
}
};
mockScope.spanWidth = 1000;
fireWatch("spanWidth", mockScope.spanWidth);
fireWatchCollection("ngModel", mockScope.ngModel);
});
it("enforces a minimum outer span", function () {
mockScope.ngModel.outer.end =
mockScope.ngModel.outer.start - DAY * 100;
fireWatch(
"ngModel.outer.end",
mockScope.ngModel.outer.end
);
expect(mockScope.ngModel.outer.end)
.toBeGreaterThan(mockScope.ngModel.outer.start);
mockScope.ngModel.outer.start =
mockScope.ngModel.outer.end + DAY * 100;
fireWatch(
"ngModel.outer.start",
mockScope.ngModel.outer.start
);
expect(mockScope.ngModel.outer.end)
.toBeGreaterThan(mockScope.ngModel.outer.start);
});
it("enforces a minimum inner span when outer span changes", function () {
mockScope.ngModel.outer.end =
mockScope.ngModel.outer.start - DAY * 100;
fireWatch(
"ngModel.outer.end",
mockScope.ngModel.outer.end
);
expect(mockScope.ngModel.inner.end)
.toBeGreaterThan(mockScope.ngModel.inner.start);
});
});
});
}