mirror of
https://github.com/nasa/openmct.git
synced 2025-01-31 08:25:31 +00:00
Merge pull request #1666 from nasa/layout-issue-1658
Added selection capability for the panels in layout. Also, added a to…
This commit is contained in:
commit
e205bf1fa4
@ -28,8 +28,4 @@
|
|||||||
key="'menu-arrow'"
|
key="'menu-arrow'"
|
||||||
mct-object='domainObject'
|
mct-object='domainObject'
|
||||||
class="flex-elem context-available-w"></mct-representation>
|
class="flex-elem context-available-w"></mct-representation>
|
||||||
</span>
|
</span>
|
||||||
<a class="s-button icon-expand t-btn-view-large"
|
|
||||||
title="View large"
|
|
||||||
mct-trigger-modal>
|
|
||||||
</a>
|
|
@ -21,32 +21,11 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
.t-fixed-position {
|
.t-fixed-position {
|
||||||
&.l-fixed-position {
|
&.l-fixed-position {
|
||||||
position: absolute;
|
@extend .abs;
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
width: auto;
|
|
||||||
height: auto;
|
|
||||||
|
|
||||||
.l-grid-holder {
|
|
||||||
position: relative;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
.l-grid {
|
|
||||||
position: absolute;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
pointer-events: none;
|
|
||||||
z-index: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.l-fixed-position-item {
|
.l-fixed-position-item {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border: 1px solid transparent;
|
|
||||||
|
|
||||||
&.s-not-selected {
|
&.s-not-selected {
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
@ -105,37 +84,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.l-fixed-position-item-handle {
|
|
||||||
$brd: 1px solid $colorKey;
|
|
||||||
background: rgba($colorKey, 0.5);
|
|
||||||
cursor: crosshair;
|
|
||||||
border: $brd;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit-mode .t-fixed-position {
|
.s-status-editing {
|
||||||
&.l-fixed-position {
|
.l-fixed-position-item-handle.edit-corner { display: block; }
|
||||||
.l-grid-holder {
|
|
||||||
.l-grid {
|
|
||||||
&.l-grid-x {
|
|
||||||
@include bgTicks($colorGridLines, 'x');
|
|
||||||
}
|
|
||||||
|
|
||||||
&.l-grid-y {
|
|
||||||
@include bgTicks($colorGridLines, 'y');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.l-fixed-position-item {
|
|
||||||
&:not(.s-selected) {
|
|
||||||
border: 1px dotted rgba($colorKey, 0.75);
|
|
||||||
&:hover {
|
|
||||||
border: 1px dotted rgba($colorKey, 1.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -704,11 +704,6 @@ textarea {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.view-switcher,
|
|
||||||
.t-btn-view-large {
|
|
||||||
@include trans-prop-nice-fade($controlFadeMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************** BROWSER ELEMENTS */
|
/******************************************************** BROWSER ELEMENTS */
|
||||||
body.desktop {
|
body.desktop {
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
|
@ -19,12 +19,24 @@
|
|||||||
* this source code distribution or the Licensing information page available
|
* this source code distribution or the Licensing information page available
|
||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
.s-status-editing .l-object-wrapper,
|
.t-edit-handle-holder { display: none; }
|
||||||
.edit-main {
|
|
||||||
// .s-status-editing .l-object-wrapper is relevant to New Edit Mode;
|
.l-grid-holder {
|
||||||
// .edit-main is legacy for old edit mode.
|
display: none;
|
||||||
$handleD: 15px;
|
position: relative;
|
||||||
$cr: 5px;
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
.l-grid {
|
||||||
|
@extend .abs;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
|
&.l-grid-y { background-position: 0 1px; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.s-status-editing {
|
||||||
|
$handleD: 5px;
|
||||||
|
.t-edit-handle-holder { display: block; }
|
||||||
.edit-corner,
|
.edit-corner,
|
||||||
.edit-handle {
|
.edit-handle {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -32,81 +44,59 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.edit-corner {
|
.edit-corner {
|
||||||
|
background: rgba($colorSelectableSelectedPrimary, 0.5);
|
||||||
|
cursor: crosshair;
|
||||||
|
display: none; // Hide by default
|
||||||
|
border: 1px solid $colorSelectableSelectedPrimary;
|
||||||
width: $handleD;
|
width: $handleD;
|
||||||
height: $handleD;
|
height: $handleD;
|
||||||
|
$o: (-1 * $handleD) + 1px;
|
||||||
&:hover {
|
&:hover {
|
||||||
z-index: 11;
|
z-index: 11;
|
||||||
}
|
}
|
||||||
&.edit-resize-nw {
|
&.edit-resize-nw { top: $o; left: $o; }
|
||||||
border-bottom-right-radius: $cr;
|
&.edit-resize-ne { top: $o; right: $o; }
|
||||||
cursor: nw-resize;
|
&.edit-resize-se { bottom: $o; right: $o; }
|
||||||
top: 0; left: 0;
|
&.edit-resize-sw { bottom: $o; left: $o; }
|
||||||
}
|
|
||||||
&.edit-resize-ne {
|
|
||||||
border-bottom-left-radius: $cr;
|
|
||||||
cursor: ne-resize;
|
|
||||||
top: 0; right: 0;
|
|
||||||
}
|
|
||||||
&.edit-resize-se {
|
|
||||||
border-top-left-radius: $cr;
|
|
||||||
cursor: se-resize;
|
|
||||||
bottom: 0; right: 0;
|
|
||||||
}
|
|
||||||
&.edit-resize-sw {
|
|
||||||
border-top-right-radius: $cr;
|
|
||||||
cursor: sw-resize;
|
|
||||||
bottom: 0; left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit-handle {
|
.edit-handle.edit-move {
|
||||||
top: $handleD; right: $handleD; bottom: $handleD; left: $handleD;
|
// main move box for the whole frame element
|
||||||
&.edit-move {
|
$m: 0;
|
||||||
$m: 0; //$handleD;
|
left: $m;
|
||||||
cursor: move;
|
right: $m;
|
||||||
left: $m;
|
top: $m;
|
||||||
right: $m;
|
bottom: $m;
|
||||||
top: $m;
|
z-index: 1;
|
||||||
bottom: $m;
|
|
||||||
z-index: 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
&.edit-resize-n {
|
|
||||||
top: 0px; bottom: auto;
|
|
||||||
height: $handleD;
|
|
||||||
cursor: n-resize;
|
|
||||||
}
|
|
||||||
&.edit-resize-e {
|
|
||||||
right: 0px; left: auto;
|
|
||||||
width: $handleD;
|
|
||||||
cursor: e-resize;
|
|
||||||
}
|
|
||||||
&.edit-resize-s {
|
|
||||||
bottom: 0px; top: auto;
|
|
||||||
height: $handleD;
|
|
||||||
cursor: s-resize;
|
|
||||||
}
|
|
||||||
&.edit-resize-w {
|
|
||||||
left: 0px; right: auto;
|
|
||||||
width: $handleD;
|
|
||||||
cursor: w-resize;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.frame.child-frame.panel {
|
.frame.child-frame.panel {
|
||||||
&:hover {
|
&:hover {
|
||||||
@include boxShdwLarge();
|
|
||||||
border-color: $colorSelectableSelectedPrimary;
|
|
||||||
.view-switcher {
|
.view-switcher {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
.edit-corner {
|
|
||||||
background-color: rgba($colorKey, 0.8);
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba($colorKey, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Editing Grids
|
||||||
|
.l-grid-holder {
|
||||||
|
display: block;
|
||||||
|
.l-grid {
|
||||||
|
&.l-grid-x { @include bgTicks($colorGridLines, 'x'); }
|
||||||
|
&.l-grid-y { @include bgTicks($colorGridLines, 'y'); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent nested frames from showing their grids
|
||||||
|
.t-frame-outer .l-grid-holder { display: none !important; }
|
||||||
|
|
||||||
|
// Prevent nested elements from showing s-hover-border
|
||||||
|
.t-frame-outer .s-hover-border {
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent nested frames from being selectable until we have proper sub-object editing
|
||||||
|
.t-frame-outer .t-frame-outer {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,6 +193,7 @@
|
|||||||
|
|
||||||
@include animToParams(overlayIn, $dur: $durLargeViewExpand, $delay: 0);
|
@include animToParams(overlayIn, $dur: $durLargeViewExpand, $delay: 0);
|
||||||
background: $colorBodyBg;
|
background: $colorBodyBg;
|
||||||
|
z-index: 101;
|
||||||
|
|
||||||
.abs.inner-holder {
|
.abs.inner-holder {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
@ -203,10 +204,19 @@
|
|||||||
@include animToParams(contentsIn, $dur: 50ms, $delay: $durLargeViewExpand * 1.25);
|
@include animToParams(contentsIn, $dur: 50ms, $delay: $durLargeViewExpand * 1.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hide View Large button
|
||||||
.t-btn-view-large {
|
.t-btn-view-large {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
z-index: 101;
|
|
||||||
|
// But show View Large button when it's nested inside a Layout
|
||||||
|
.t-frame-inner .t-frame-inner .t-btn-view-large { display: block; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// When multiple Large Views are visible, hide the blocker for all but the first
|
||||||
|
& + .l-large-view {
|
||||||
|
.blocker {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,28 +23,43 @@
|
|||||||
$ohH: $btnFrameH;
|
$ohH: $btnFrameH;
|
||||||
$bc: $colorInteriorBorder;
|
$bc: $colorInteriorBorder;
|
||||||
&.child-frame.panel {
|
&.child-frame.panel {
|
||||||
background: $colorBodyBg;
|
|
||||||
border: 1px solid $bc;
|
|
||||||
z-index: 0; // Needed to prevent child-frame controls from showing through when another child-frame is above
|
z-index: 0; // Needed to prevent child-frame controls from showing through when another child-frame is above
|
||||||
&:hover {
|
&:not(.no-frame) {
|
||||||
border-color: lighten($bc, 10%);
|
background: $colorBodyBg;
|
||||||
|
border: 1px solid $bc;
|
||||||
|
&:hover {
|
||||||
|
border-color: lighten($bc, 10%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.object-browse-bar {
|
.object-browse-bar {
|
||||||
font-size: 0.75em;
|
font-size: 0.75em;
|
||||||
height: $ohH;
|
height: $ohH;
|
||||||
line-height: $ohH;
|
line-height: $ohH;
|
||||||
|
.right {
|
||||||
|
@include trans-prop-nice-fade($controlFadeMs);
|
||||||
|
padding-left: $interiorMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.t-object-type-timer,
|
||||||
|
&.t-object-type-clock,
|
||||||
|
&.t-object-type-hyperlink {
|
||||||
|
// Hide the right side buttons for objects where they don't make sense
|
||||||
|
// Note that this will hide the view Switcher button if applied
|
||||||
|
// to an object that it.
|
||||||
|
.object-browse-bar .right { display: none; }
|
||||||
}
|
}
|
||||||
|
|
||||||
> .object-holder.abs {
|
> .object-holder.abs {
|
||||||
top: $ohH + $interiorMargin;
|
top: $ohH + $interiorMargin;
|
||||||
}
|
}
|
||||||
.contents {
|
.contents {
|
||||||
$myM: $interiorMargin;
|
$m: $interiorMargin;
|
||||||
top: $myM;
|
top: $m;
|
||||||
right: $myM;
|
right: $m;
|
||||||
bottom: $myM;
|
bottom: $m;
|
||||||
left: $myM;
|
left: $m;
|
||||||
}
|
}
|
||||||
&.frame-template {
|
&.frame-template {
|
||||||
.s-button,
|
.s-button,
|
||||||
@ -67,15 +82,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.view-switcher {
|
.view-switcher {
|
||||||
margin-left: $interiorMargin; // Kick other top bar elements away when I'm present.
|
margin-right: $interiorMargin; // Kick other top bar elements away when I'm present.
|
||||||
// Hide the name when the view switcher is in a frame context
|
// Hide the name when the view switcher is in a frame context
|
||||||
.title-label {
|
.title-label {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.no-frame {
|
&.no-frame {
|
||||||
background: transparent !important;
|
background: transparent !important;
|
||||||
border: none !important;
|
border: none !important;
|
||||||
|
.object-browse-bar .right {
|
||||||
|
$m: 0; // $interiorMarginSm;
|
||||||
|
background: rgba(black, 0.3);
|
||||||
|
border-radius: $basicCr;
|
||||||
|
padding: $interiorMarginSm;
|
||||||
|
position: absolute;
|
||||||
|
top: $m; right: $m;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
&.t-frame-outer > .t-rep-frame {
|
&.t-frame-outer > .t-rep-frame {
|
||||||
&.contents {
|
&.contents {
|
||||||
$m: 2px;
|
$m: 2px;
|
||||||
@ -85,7 +110,7 @@
|
|||||||
left: $m;
|
left: $m;
|
||||||
}
|
}
|
||||||
> .t-frame-inner {
|
> .t-frame-inner {
|
||||||
> .object-browse-bar {
|
> .object-browse-bar .left {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
> .object-holder.abs {
|
> .object-holder.abs {
|
||||||
@ -117,8 +142,7 @@
|
|||||||
body.desktop .frame {
|
body.desktop .frame {
|
||||||
// Hide local controls initially and show it them on hover when they're in an element that's in a frame context
|
// Hide local controls initially and show it them on hover when they're in an element that's in a frame context
|
||||||
// Frame template is used because we need to target the lowest nested frame
|
// Frame template is used because we need to target the lowest nested frame
|
||||||
.view-switcher,
|
.right {
|
||||||
.t-btn-view-large {
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
@ -126,8 +150,7 @@ body.desktop .frame {
|
|||||||
// Target the first descendant so that we only show the elements in the outermost container.
|
// Target the first descendant so that we only show the elements in the outermost container.
|
||||||
// Handles the case where we have layouts in layouts.
|
// Handles the case where we have layouts in layouts.
|
||||||
&:hover > .object-browse-bar {
|
&:hover > .object-browse-bar {
|
||||||
.view-switcher,
|
.right {
|
||||||
.t-btn-view-large {
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
pointer-events: inherit;
|
pointer-events: inherit;
|
||||||
}
|
}
|
||||||
|
@ -19,21 +19,36 @@
|
|||||||
* this source code distribution or the Licensing information page available
|
* this source code distribution or the Licensing information page available
|
||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
.s-selectable {
|
.s-hover-border {
|
||||||
border: 1px solid transparent;
|
border: 1px dotted transparent;
|
||||||
|
}
|
||||||
|
|
||||||
&.s-hover {
|
.s-status-editing {
|
||||||
// Styles when hovering over a selectable object
|
// Limit to editing mode until we have sub-object selection
|
||||||
border-color: $colorSelectableHov !important;
|
.s-hover-border {
|
||||||
|
// Show a border by default so user can see object bounds and empty objects
|
||||||
|
border: 1px dotted rgba($colorSelectableSelectedPrimary, 0.3) !important;
|
||||||
|
&:hover {
|
||||||
|
border-color: rgba($colorSelectableSelectedPrimary, 0.7) !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.s-selected {
|
.s-selected > .s-hover-border,
|
||||||
|
.s-selected.s-hover-border {
|
||||||
// Styles for a selected object. Also used by legacy Fixed Position/Panel objects.
|
// Styles for a selected object. Also used by legacy Fixed Position/Panel objects.
|
||||||
border-color: $colorSelectableSelectedPrimary !important;
|
border-color: $colorSelectableSelectedPrimary !important;
|
||||||
|
@include boxShdwLarge();
|
||||||
|
// Show edit-corners if you got 'em
|
||||||
|
.edit-corner {
|
||||||
|
display: block;
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba($colorKey, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.s-moveable {
|
.s-selected > .s-moveable,
|
||||||
@include boxShdwLarge();
|
.s-selected.s-moveable {
|
||||||
cursor: move;
|
cursor: move;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -62,7 +62,29 @@ define([
|
|||||||
"type": "layout",
|
"type": "layout",
|
||||||
"template": layoutTemplate,
|
"template": layoutTemplate,
|
||||||
"editable": true,
|
"editable": true,
|
||||||
"uses": []
|
"uses": [],
|
||||||
|
"toolbar": {
|
||||||
|
"sections": [
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"method": "showFrame",
|
||||||
|
"cssClass": "icon-frame-show",
|
||||||
|
"control": "button",
|
||||||
|
"title": "Show frame",
|
||||||
|
"description": "Show frame"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "hideFrame",
|
||||||
|
"cssClass": "icon-frame-hide",
|
||||||
|
"control": "button",
|
||||||
|
"title": "Hide frame",
|
||||||
|
"description": "Hide frame"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "fixed",
|
"key": "fixed",
|
||||||
|
@ -25,15 +25,20 @@
|
|||||||
<!-- Background grid -->
|
<!-- Background grid -->
|
||||||
<div class="l-grid-holder" ng-click="controller.clearSelection()">
|
<div class="l-grid-holder" ng-click="controller.clearSelection()">
|
||||||
<div class="l-grid l-grid-x"
|
<div class="l-grid l-grid-x"
|
||||||
|
ng-if="!controller.getGridSize()[0] < 3"
|
||||||
ng-style="{ 'background-size': controller.getGridSize() [0] + 'px 100%' }"></div>
|
ng-style="{ 'background-size': controller.getGridSize() [0] + 'px 100%' }"></div>
|
||||||
<div class="l-grid l-grid-y"
|
<div class="l-grid l-grid-y"
|
||||||
|
ng-if="!controller.getGridSize()[1] < 3"
|
||||||
ng-style="{ 'background-size': '100% ' + controller.getGridSize() [1] + 'px' }"></div>
|
ng-style="{ 'background-size': '100% ' + controller.getGridSize() [1] + 'px' }"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Fixed position elements -->
|
<!-- Fixed position elements -->
|
||||||
<div ng-repeat="element in controller.getElements()"
|
<div ng-repeat="element in controller.getElements()"
|
||||||
class="l-fixed-position-item"
|
class="l-fixed-position-item s-selectable s-moveable s-hover-border"
|
||||||
ng-class="{ 's-not-selected': controller.selected() && !controller.selected(element) }"
|
ng-class="{
|
||||||
|
's-not-selected': controller.selected() && !controller.selected(element),
|
||||||
|
's-selected': controller.selected(element)
|
||||||
|
}"
|
||||||
ng-style="element.style"
|
ng-style="element.style"
|
||||||
ng-click="controller.select(element)">
|
ng-click="controller.select(element)">
|
||||||
<mct-include key="element.template"
|
<mct-include key="element.template"
|
||||||
@ -43,15 +48,15 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Selection highlight, handles -->
|
<!-- Selection highlight, handles -->
|
||||||
<span ng-if="controller.selected()">
|
<span class="s-selected s-moveable" ng-if="controller.selected()">
|
||||||
<div class="l-fixed-position-item s-selectable s-selected s-moveable"
|
<div class="l-fixed-position-item t-edit-handle-holder"
|
||||||
mct-drag-down="controller.moveHandle().startDrag(controller.selected())"
|
mct-drag-down="controller.moveHandle().startDrag(controller.selected())"
|
||||||
mct-drag="controller.moveHandle().continueDrag(delta)"
|
mct-drag="controller.moveHandle().continueDrag(delta)"
|
||||||
mct-drag-up="controller.moveHandle().endDrag()"
|
mct-drag-up="controller.moveHandle().endDrag()"
|
||||||
ng-style="controller.selected().style">
|
ng-style="controller.selected().style">
|
||||||
</div>
|
</div>
|
||||||
<div ng-repeat="handle in controller.handles()"
|
<div ng-repeat="handle in controller.handles()"
|
||||||
class="l-fixed-position-item-handle"
|
class="l-fixed-position-item-handle edit-corner"
|
||||||
ng-style="handle.style()"
|
ng-style="handle.style()"
|
||||||
mct-drag-down="handle.startDrag()"
|
mct-drag-down="handle.startDrag()"
|
||||||
mct-drag="handle.continueDrag(delta)"
|
mct-drag="handle.continueDrag(delta)"
|
||||||
|
@ -29,15 +29,21 @@
|
|||||||
</mct-representation>
|
</mct-representation>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-bar right l-flex-row flex-elem flex-justify-end flex-fixed">
|
<div class="btn-bar right l-flex-row flex-elem flex-justify-end flex-fixed">
|
||||||
<mct-representation key="'switcher'"
|
<mct-representation
|
||||||
ng-model="representation"
|
key="'switcher'"
|
||||||
mct-object="domainObject">
|
ng-model="representation"
|
||||||
|
mct-object="domainObject">
|
||||||
</mct-representation>
|
</mct-representation>
|
||||||
|
<a class="s-button icon-expand t-btn-view-large"
|
||||||
|
title="View large"
|
||||||
|
mct-trigger-modal>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="abs object-holder">
|
<div class="abs object-holder">
|
||||||
<mct-representation key="representation.selected.key"
|
<mct-representation
|
||||||
mct-object="representation.selected.key && domainObject">
|
key="representation.selected.key"
|
||||||
|
mct-object="representation.selected.key && domainObject">
|
||||||
</mct-representation>
|
</mct-representation>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,19 +19,33 @@
|
|||||||
this source code distribution or the Licensing information page available
|
this source code distribution or the Licensing information page available
|
||||||
at runtime from the About dialog for additional information.
|
at runtime from the About dialog for additional information.
|
||||||
-->
|
-->
|
||||||
<div class="l-layout"
|
|
||||||
ng-controller="LayoutController as controller">
|
|
||||||
|
|
||||||
<div class='frame child-frame panel abs'
|
<div class="abs l-layout"
|
||||||
|
ng-controller="LayoutController as controller"
|
||||||
|
ng-click="controller.clearSelection()">
|
||||||
|
|
||||||
|
<!-- Background grid -->
|
||||||
|
<div class="l-grid-holder" ng-click="controller.clearSelection()">
|
||||||
|
<div class="l-grid l-grid-x"
|
||||||
|
ng-if="!controller.getGridSize()[0] < 3"
|
||||||
|
ng-style="{ 'background-size': controller.getGridSize() [0] + 'px 100%' }"></div>
|
||||||
|
<div class="l-grid l-grid-y"
|
||||||
|
ng-if="!controller.getGridSize()[1] < 3"
|
||||||
|
ng-style="{ 'background-size': '100% ' + controller.getGridSize() [1] + 'px' }"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='abs frame t-frame-outer child-frame panel s-selectable s-moveable s-hover-border'
|
||||||
|
ng-class="{ 'no-frame': !controller.hasFrame(childObject), 's-selected':controller.selected(childObject) }"
|
||||||
ng-repeat="childObject in composition"
|
ng-repeat="childObject in composition"
|
||||||
|
ng-click="controller.select($event, childObject.getId())"
|
||||||
ng-style="controller.getFrameStyle(childObject.getId())">
|
ng-style="controller.getFrameStyle(childObject.getId())">
|
||||||
|
|
||||||
<mct-representation key="'frame'"
|
<mct-representation key="'frame'"
|
||||||
class="frame child-frame holder contents abs"
|
class="t-rep-frame holder contents abs"
|
||||||
mct-object="childObject">
|
mct-object="childObject">
|
||||||
</mct-representation>
|
</mct-representation>
|
||||||
<!-- Drag handles -->
|
<!-- Drag handles -->
|
||||||
<span ng-show="domainObject.hasCapability('editor')">
|
<span class="abs t-edit-handle-holder s-hover-border" ng-if="controller.selected(childObject)">
|
||||||
<span class="edit-handle edit-move"
|
<span class="edit-handle edit-move"
|
||||||
mct-drag-down="controller.startDrag(childObject.getId(), [1,1], [0,0])"
|
mct-drag-down="controller.startDrag(childObject.getId(), [1,1], [0,0])"
|
||||||
mct-drag="controller.continueDrag(delta)"
|
mct-drag="controller.continueDrag(delta)"
|
||||||
|
@ -33,6 +33,10 @@ define(
|
|||||||
DEFAULT_GRID_SIZE = [32, 32],
|
DEFAULT_GRID_SIZE = [32, 32],
|
||||||
MINIMUM_FRAME_SIZE = [320, 180];
|
MINIMUM_FRAME_SIZE = [320, 180];
|
||||||
|
|
||||||
|
var DEFAULT_HIDDEN_FRAME_TYPES = [
|
||||||
|
'hyperlink'
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The LayoutController is responsible for supporting the
|
* The LayoutController is responsible for supporting the
|
||||||
* Layout view. It arranges frames according to saved configuration
|
* Layout view. It arranges frames according to saved configuration
|
||||||
@ -65,13 +69,10 @@ define(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that configuration field is populated
|
|
||||||
$scope.configuration = $scope.configuration || {};
|
$scope.configuration = $scope.configuration || {};
|
||||||
// Make sure there is a "panels" field in the
|
|
||||||
// view configuration.
|
|
||||||
$scope.configuration.panels =
|
$scope.configuration.panels =
|
||||||
$scope.configuration.panels || {};
|
$scope.configuration.panels || {};
|
||||||
// Store the position of this panel.
|
|
||||||
$scope.configuration.panels[id] = {
|
$scope.configuration.panels[id] = {
|
||||||
position: [
|
position: [
|
||||||
Math.floor(position.x / self.gridSize[0]),
|
Math.floor(position.x / self.gridSize[0]),
|
||||||
@ -79,6 +80,11 @@ define(
|
|||||||
],
|
],
|
||||||
dimensions: self.defaultDimensions()
|
dimensions: self.defaultDimensions()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Store the id so that the newly-dropped object
|
||||||
|
// gets selected during refresh composition
|
||||||
|
self.droppedIdToSelectAfterRefresh = id;
|
||||||
|
|
||||||
// Mark change as persistable
|
// Mark change as persistable
|
||||||
if ($scope.commit) {
|
if ($scope.commit) {
|
||||||
$scope.commit("Dropped a frame.");
|
$scope.commit("Dropped a frame.");
|
||||||
@ -111,6 +117,13 @@ define(
|
|||||||
|
|
||||||
$scope.composition = composition;
|
$scope.composition = composition;
|
||||||
self.layoutPanels(ids);
|
self.layoutPanels(ids);
|
||||||
|
self.setFrames(ids);
|
||||||
|
|
||||||
|
// If there is a newly-dropped object, select it.
|
||||||
|
if (self.droppedIdToSelectAfterRefresh) {
|
||||||
|
self.select(null, self.droppedIdToSelectAfterRefresh);
|
||||||
|
delete self.droppedIdToSelectAfterRefresh;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -123,13 +136,18 @@ define(
|
|||||||
// saved by the EditRepresenter.
|
// saved by the EditRepresenter.
|
||||||
$scope.configuration =
|
$scope.configuration =
|
||||||
$scope.configuration || {};
|
$scope.configuration || {};
|
||||||
// Make sure there is a "panels" field in the
|
|
||||||
// view configuration.
|
|
||||||
$scope.configuration.panels =
|
$scope.configuration.panels =
|
||||||
$scope.configuration.panels || {};
|
$scope.configuration.panels || {};
|
||||||
// Store the position of this panel.
|
|
||||||
$scope.configuration.panels[self.activeDragId] =
|
$scope.configuration.panels[self.activeDragId] =
|
||||||
self.rawPositions[self.activeDragId];
|
$scope.configuration.panels[self.activeDragId] || {};
|
||||||
|
|
||||||
|
$scope.configuration.panels[self.activeDragId].position =
|
||||||
|
self.rawPositions[self.activeDragId].position;
|
||||||
|
$scope.configuration.panels[self.activeDragId].dimensions =
|
||||||
|
self.rawPositions[self.activeDragId].dimensions;
|
||||||
|
|
||||||
// Mark this object as dirty to encourage persistence
|
// Mark this object as dirty to encourage persistence
|
||||||
if ($scope.commit) {
|
if ($scope.commit) {
|
||||||
$scope.commit("Moved frame.");
|
$scope.commit("Moved frame.");
|
||||||
@ -144,6 +162,10 @@ define(
|
|||||||
// Watch for changes to the grid size in the model
|
// Watch for changes to the grid size in the model
|
||||||
$scope.$watch("model.layoutGrid", updateGridSize);
|
$scope.$watch("model.layoutGrid", updateGridSize);
|
||||||
|
|
||||||
|
$scope.$watch("selection", function (selection) {
|
||||||
|
this.selection = selection;
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
// Update composed objects on screen, and position panes
|
// Update composed objects on screen, and position panes
|
||||||
$scope.$watchCollection("model.composition", refreshComposition);
|
$scope.$watchCollection("model.composition", refreshComposition);
|
||||||
|
|
||||||
@ -151,6 +173,42 @@ define(
|
|||||||
$scope.$on("mctDrop", handleDrop);
|
$scope.$on("mctDrop", handleDrop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Utility function to copy raw positions from configuration,
|
||||||
|
// without writing directly to configuration (to avoid triggering
|
||||||
|
// persistence from watchers during drags).
|
||||||
|
function shallowCopy(obj, keys) {
|
||||||
|
var copy = {};
|
||||||
|
keys.forEach(function (k) {
|
||||||
|
copy[k] = obj[k];
|
||||||
|
});
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the frames value. If a configuration panel has "hasFrame' property,
|
||||||
|
* use that value, otherwise set a default value. A 'hyperlink' object should
|
||||||
|
* have no frame by default.
|
||||||
|
*
|
||||||
|
* @param {string[]} ids the object ids
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
LayoutController.prototype.setFrames = function (ids) {
|
||||||
|
var panels = shallowCopy(this.$scope.configuration.panels || {}, ids);
|
||||||
|
|
||||||
|
this.frames = {};
|
||||||
|
|
||||||
|
this.$scope.composition.forEach(function (object) {
|
||||||
|
var id = object.getId();
|
||||||
|
panels[id] = panels[id] || {};
|
||||||
|
|
||||||
|
if (panels[id].hasOwnProperty('hasFrame')) {
|
||||||
|
this.frames[id] = panels[id].hasFrame;
|
||||||
|
} else {
|
||||||
|
this.frames[id] = DEFAULT_HIDDEN_FRAME_TYPES.indexOf(object.getModel().type) === -1;
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
};
|
||||||
|
|
||||||
// Convert from { positions: ..., dimensions: ... } to an
|
// Convert from { positions: ..., dimensions: ... } to an
|
||||||
// appropriate ng-style argument, to position frames.
|
// appropriate ng-style argument, to position frames.
|
||||||
LayoutController.prototype.convertPosition = function (raw) {
|
LayoutController.prototype.convertPosition = function (raw) {
|
||||||
@ -237,6 +295,7 @@ define(
|
|||||||
this.gridSize
|
this.gridSize
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Continue an active drag gesture.
|
* Continue an active drag gesture.
|
||||||
* @param {number[]} delta the offset, in pixels,
|
* @param {number[]} delta the offset, in pixels,
|
||||||
@ -251,17 +310,6 @@ define(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Utility function to copy raw positions from configuration,
|
|
||||||
// without writing directly to configuration (to avoid triggering
|
|
||||||
// persistence from watchers during drags).
|
|
||||||
function shallowCopy(obj, keys) {
|
|
||||||
var copy = {};
|
|
||||||
keys.forEach(function (k) {
|
|
||||||
copy[k] = obj[k];
|
|
||||||
});
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute panel positions based on the layout's object model.
|
* Compute panel positions based on the layout's object model.
|
||||||
* Defined as member function to facilitate testing.
|
* Defined as member function to facilitate testing.
|
||||||
@ -293,9 +341,99 @@ define(
|
|||||||
* view configuration.
|
* view configuration.
|
||||||
*/
|
*/
|
||||||
LayoutController.prototype.endDrag = function () {
|
LayoutController.prototype.endDrag = function () {
|
||||||
|
this.dragInProgress = true;
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
this.dragInProgress = false;
|
||||||
|
}.bind(this), 0);
|
||||||
|
|
||||||
this.endDragInScope();
|
this.endDragInScope();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the object is currently selected.
|
||||||
|
*
|
||||||
|
* @param {string} obj the object to check for selection
|
||||||
|
* @returns {boolean} true if selected, otherwise false
|
||||||
|
*/
|
||||||
|
LayoutController.prototype.selected = function (obj) {
|
||||||
|
return !!this.selectedId && this.selectedId === obj.getId();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the active user selection in this view.
|
||||||
|
*
|
||||||
|
* @param event the mouse event
|
||||||
|
* @param {string} id the object id
|
||||||
|
*/
|
||||||
|
LayoutController.prototype.select = function (event, id) {
|
||||||
|
if (event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
if (this.selection) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.selectedId = id;
|
||||||
|
|
||||||
|
var selectedObj = {};
|
||||||
|
selectedObj[this.frames[id] ? 'hideFrame' : 'showFrame'] = this.toggleFrame.bind(this, id);
|
||||||
|
|
||||||
|
if (this.selection) {
|
||||||
|
this.selection.select(selectedObj);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to show/hide the object frame.
|
||||||
|
*
|
||||||
|
* @param {string} id the object id
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
LayoutController.prototype.toggleFrame = function (id) {
|
||||||
|
var configuration = this.$scope.configuration;
|
||||||
|
|
||||||
|
if (!configuration.panels[id]) {
|
||||||
|
configuration.panels[id] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
this.frames[id] = configuration.panels[id].hasFrame = !this.frames[id];
|
||||||
|
this.select(undefined, id); // reselect so toolbar updates
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the current user selection.
|
||||||
|
*/
|
||||||
|
LayoutController.prototype.clearSelection = function () {
|
||||||
|
if (this.dragInProgress) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.selection) {
|
||||||
|
this.selection.deselect();
|
||||||
|
delete this.selectedId;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the object has frame.
|
||||||
|
*
|
||||||
|
* @param {object} obj the object
|
||||||
|
* @return {boolean} true if object has frame, otherwise false
|
||||||
|
*/
|
||||||
|
LayoutController.prototype.hasFrame = function (obj) {
|
||||||
|
return this.frames[obj.getId()];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size of the grid, in pixels. The returned array
|
||||||
|
* is in the form `[x, y]`.
|
||||||
|
* @returns {number[]} the grid size
|
||||||
|
*/
|
||||||
|
LayoutController.prototype.getGridSize = function () {
|
||||||
|
return this.gridSize;
|
||||||
|
};
|
||||||
|
|
||||||
return LayoutController;
|
return LayoutController;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -27,7 +27,6 @@ define([
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
var OVERLAY_TEMPLATE = '' +
|
var OVERLAY_TEMPLATE = '' +
|
||||||
'<div class="abs overlay l-large-view">' +
|
|
||||||
' <div class="abs blocker"></div>' +
|
' <div class="abs blocker"></div>' +
|
||||||
' <div class="abs outer-holder">' +
|
' <div class="abs outer-holder">' +
|
||||||
' <a class="close icon-x-in-circle"></a>' +
|
' <a class="close icon-x-in-circle"></a>' +
|
||||||
@ -37,8 +36,7 @@ define([
|
|||||||
' <a class="t-done s-button major">Done</a>' +
|
' <a class="t-done s-button major">Done</a>' +
|
||||||
' </div>' +
|
' </div>' +
|
||||||
' </div>' +
|
' </div>' +
|
||||||
' </div>' +
|
' </div>';
|
||||||
'</div>';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MCT Trigger Modal is intended for use in only one location: inside the
|
* MCT Trigger Modal is intended for use in only one location: inside the
|
||||||
@ -81,7 +79,8 @@ define([
|
|||||||
function openOverlay() {
|
function openOverlay() {
|
||||||
// Remove frame classes from being applied in a non-frame context
|
// Remove frame classes from being applied in a non-frame context
|
||||||
$(frame).removeClass('frame frame-template');
|
$(frame).removeClass('frame frame-template');
|
||||||
overlay = document.createElement('span');
|
overlay = document.createElement('div');
|
||||||
|
$(overlay).addClass('abs overlay l-large-view');
|
||||||
overlay.innerHTML = OVERLAY_TEMPLATE;
|
overlay.innerHTML = OVERLAY_TEMPLATE;
|
||||||
overlayContainer = overlay.querySelector('.t-contents');
|
overlayContainer = overlay.querySelector('.t-contents');
|
||||||
closeButton = overlay.querySelector('a.close');
|
closeButton = overlay.querySelector('a.close');
|
||||||
|
@ -49,10 +49,30 @@ define(
|
|||||||
},
|
},
|
||||||
useCapability: function () {
|
useCapability: function () {
|
||||||
return mockCompositionCapability;
|
return mockCompositionCapability;
|
||||||
|
},
|
||||||
|
getModel: function () {
|
||||||
|
if (id === 'b') {
|
||||||
|
return {
|
||||||
|
type : 'hyperlink'
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Utility function to find a watch for a given expression
|
||||||
|
function findWatch(expr) {
|
||||||
|
var watch;
|
||||||
|
mockScope.$watch.calls.forEach(function (call) {
|
||||||
|
if (call.args[0] === expr) {
|
||||||
|
watch = call.args[1];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return watch;
|
||||||
|
}
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
mockScope = jasmine.createSpyObj(
|
mockScope = jasmine.createSpyObj(
|
||||||
"$scope",
|
"$scope",
|
||||||
@ -60,7 +80,7 @@ define(
|
|||||||
);
|
);
|
||||||
mockEvent = jasmine.createSpyObj(
|
mockEvent = jasmine.createSpyObj(
|
||||||
'event',
|
'event',
|
||||||
['preventDefault']
|
['preventDefault', 'stopPropagation']
|
||||||
);
|
);
|
||||||
|
|
||||||
testModel = {};
|
testModel = {};
|
||||||
@ -68,6 +88,7 @@ define(
|
|||||||
mockComposition = ["a", "b", "c"];
|
mockComposition = ["a", "b", "c"];
|
||||||
mockCompositionObjects = mockComposition.map(mockDomainObject);
|
mockCompositionObjects = mockComposition.map(mockDomainObject);
|
||||||
|
|
||||||
|
|
||||||
testConfiguration = {
|
testConfiguration = {
|
||||||
panels: {
|
panels: {
|
||||||
a: {
|
a: {
|
||||||
@ -82,10 +103,19 @@ define(
|
|||||||
mockScope.domainObject = mockDomainObject("mockDomainObject");
|
mockScope.domainObject = mockDomainObject("mockDomainObject");
|
||||||
mockScope.model = testModel;
|
mockScope.model = testModel;
|
||||||
mockScope.configuration = testConfiguration;
|
mockScope.configuration = testConfiguration;
|
||||||
|
mockScope.selection = jasmine.createSpyObj(
|
||||||
|
'selection',
|
||||||
|
['select', 'get', 'selected', 'deselect']
|
||||||
|
);
|
||||||
|
|
||||||
spyOn(mockScope.domainObject, "useCapability").andCallThrough();
|
spyOn(mockScope.domainObject, "useCapability").andCallThrough();
|
||||||
|
|
||||||
controller = new LayoutController(mockScope);
|
controller = new LayoutController(mockScope);
|
||||||
spyOn(controller, "layoutPanels").andCallThrough();
|
spyOn(controller, "layoutPanels").andCallThrough();
|
||||||
|
|
||||||
|
findWatch("selection")(mockScope.selection);
|
||||||
|
|
||||||
|
jasmine.Clock.useMock();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Model changes will indicate that panel positions
|
// Model changes will indicate that panel positions
|
||||||
@ -289,6 +319,111 @@ define(
|
|||||||
expect(controller.getFrameStyle("b"))
|
expect(controller.getFrameStyle("b"))
|
||||||
.not.toEqual(oldStyle);
|
.not.toEqual(oldStyle);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("allows panels to be selected", function () {
|
||||||
|
mockScope.$watchCollection.mostRecentCall.args[1]();
|
||||||
|
var childObj = mockCompositionObjects[0];
|
||||||
|
|
||||||
|
controller.select(mockEvent, childObj.getId());
|
||||||
|
|
||||||
|
expect(mockEvent.stopPropagation).toHaveBeenCalled();
|
||||||
|
|
||||||
|
expect(controller.selected(childObj)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("allows selection to be cleared", function () {
|
||||||
|
mockScope.$watchCollection.mostRecentCall.args[1]();
|
||||||
|
var childObj = mockCompositionObjects[0];
|
||||||
|
|
||||||
|
controller.select(null, childObj.getId());
|
||||||
|
controller.clearSelection();
|
||||||
|
|
||||||
|
expect(controller.selected(childObj)).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("prevents clearing selection while drag is in progress", function () {
|
||||||
|
mockScope.$watchCollection.mostRecentCall.args[1]();
|
||||||
|
var childObj = mockCompositionObjects[0];
|
||||||
|
var id = childObj.getId();
|
||||||
|
|
||||||
|
controller.select(mockEvent, id);
|
||||||
|
|
||||||
|
// Do a drag
|
||||||
|
controller.startDrag(id, [1, 1], [0, 0]);
|
||||||
|
controller.continueDrag([100, 100]);
|
||||||
|
controller.endDrag();
|
||||||
|
|
||||||
|
// Because mouse position could cause clearSelection to be called, this should be ignored.
|
||||||
|
controller.clearSelection();
|
||||||
|
|
||||||
|
expect(controller.selected(childObj)).toBe(true);
|
||||||
|
|
||||||
|
// Shoud be able to clear the selection after dragging is done.
|
||||||
|
jasmine.Clock.tick(0);
|
||||||
|
controller.clearSelection();
|
||||||
|
|
||||||
|
expect(controller.selected(childObj)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("clears selection after moving/resizing", function () {
|
||||||
|
mockScope.$watchCollection.mostRecentCall.args[1]();
|
||||||
|
var childObj = mockCompositionObjects[0];
|
||||||
|
var id = childObj.getId();
|
||||||
|
|
||||||
|
controller.select(mockEvent, id);
|
||||||
|
|
||||||
|
// Do a drag
|
||||||
|
controller.startDrag(id, [1, 1], [0, 0]);
|
||||||
|
controller.continueDrag([100, 100]);
|
||||||
|
controller.endDrag();
|
||||||
|
|
||||||
|
jasmine.Clock.tick(0);
|
||||||
|
controller.clearSelection();
|
||||||
|
|
||||||
|
expect(controller.selected(childObj)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows frames by default", function () {
|
||||||
|
mockScope.$watchCollection.mostRecentCall.args[1]();
|
||||||
|
|
||||||
|
expect(controller.hasFrame(mockCompositionObjects[0])).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("hyperlinks hide frame by default", function () {
|
||||||
|
mockScope.$watchCollection.mostRecentCall.args[1]();
|
||||||
|
|
||||||
|
expect(controller.hasFrame(mockCompositionObjects[1])).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("hides frame when selected object has frame ", function () {
|
||||||
|
mockScope.$watchCollection.mostRecentCall.args[1]();
|
||||||
|
var childObj = mockCompositionObjects[0];
|
||||||
|
controller.select(mockEvent, childObj.getId());
|
||||||
|
|
||||||
|
expect(mockScope.selection.select).toHaveBeenCalled();
|
||||||
|
|
||||||
|
var selectedObj = mockScope.selection.select.mostRecentCall.args[0];
|
||||||
|
|
||||||
|
expect(controller.hasFrame(childObj)).toBe(true);
|
||||||
|
expect(selectedObj.hideFrame).toBeDefined();
|
||||||
|
expect(selectedObj.hideFrame).toEqual(jasmine.any(Function));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows frame when selected object has no frame", function () {
|
||||||
|
mockScope.$watchCollection.mostRecentCall.args[1]();
|
||||||
|
|
||||||
|
var childObj = mockCompositionObjects[1];
|
||||||
|
controller.select(mockEvent, childObj.getId());
|
||||||
|
|
||||||
|
expect(mockScope.selection.select).toHaveBeenCalled();
|
||||||
|
|
||||||
|
var selectedObj = mockScope.selection.select.mostRecentCall.args[0];
|
||||||
|
|
||||||
|
expect(controller.hasFrame(childObj)).toBe(false);
|
||||||
|
expect(selectedObj.showFrame).toBeDefined();
|
||||||
|
expect(selectedObj.showFrame).toEqual(jasmine.any(Function));
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user