Compare commits

...

5 Commits

Author SHA1 Message Date
2a74117294 merging markup from prototype 2016-01-11 14:52:45 -08:00
f8aa123122 [New Edit Mode] Merged styles and markup from prototype 2016-01-11 14:42:49 -08:00
6d4a20c07a Adding elements pane 2016-01-11 13:33:56 -08:00
2c4d53883a [New Edit Mode] Added additional tests for Seamless Edit Mode #464 2016-01-11 13:07:56 -08:00
c71aa43581 [New Edit Mode] “Seamless” Edit Mode #464
* html changes and Edit Action
* Fixed browse controller to correctly navigate to non-editable object
* Added save and cancel actions
2016-01-08 14:25:58 -08:00
41 changed files with 2396 additions and 1012 deletions

View File

@ -19,8 +19,8 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<span ng-controller="BrowseObjectController">
<div class="object-browse-bar l-flex-row">
<div ng-controller="BrowseObjectController" class="abs l-flex-col">
<div class="holder flex-elem l-flex-row object-browse-bar ">
<div class="items-select left flex-elem l-flex-row grows">
<mct-representation key="'back-arrow'"
mct-object="domainObject"
@ -43,8 +43,26 @@
</mct-representation>
</div>
</div>
<mct-representation key="representation.selected.key"
mct-object="representation.selected.key && domainObject"
class="abs object-holder">
</mct-representation>
</span>
<div class="holder l-flex-col flex-elem grows l-object-wrapper">
<div class="holder l-flex-col flex-elem grows l-object-wrapper-inner">
<!-- Toolbar and Save/Cancel buttons -->
<div class="l-edit-controls flex-elem l-flex-row flex-align-end">
<mct-toolbar name="mctToolbar"
structure="toolbar.structure"
ng-model="toolbar.state"
class="flex-elem grows">
</mct-toolbar>
<mct-representation key="'edit-action-buttons'"
mct-object="domainObject"
class='flex-elem conclude-editing'>
</mct-representation>
</div>
<mct-representation key="representation.selected.key"
mct-object="representation.selected.key && domainObject"
class="abs flex-elem grows object-holder-main scroll"
toolbar="toolbar">
</mct-representation>
</div><!--/ l-object-wrapper-inner -->
</div>
</div>

View File

@ -20,7 +20,7 @@
at runtime from the About dialog for additional information.
-->
<div class="abs holder-all browse-mode" ng-controller="BrowseController">
<div class="abs holder-all" ng-controller="BrowseController">
<mct-include key="'topbar-browse'"></mct-include>
<div class="abs holder holder-main browse-area s-browse-area browse-wrapper"
ng-controller="PaneController as modelPaneTree"
@ -72,7 +72,7 @@
<div class="split-pane-component t-inspect pane right mobile-hide">
<mct-representation key="'object-inspector'"
mct-object="domainObject"
mct-object="navigatedObject"
ng-model="treeModel">
</mct-representation>
<a class="mini-tab-icon anchor-right mobile-hide toggle-pane toggle-inspect"

View File

@ -71,10 +71,14 @@ define(
// Callback for updating the in-scope reference to the object
// that is currently navigated-to.
function setNavigation(domainObject) {
//If the domain object has editor capability, retrieve the
// original uneditable domain object
var nonEditableObject = domainObject.hasCapability("editor") ? domainObject.getCapability("editor").getDomainObject() : domainObject;
$scope.navigatedObject = domainObject;
$scope.treeModel.selectedObject = domainObject;
$scope.treeModel.selectedObject = nonEditableObject;
navigationService.setNavigation(domainObject);
updateRoute(domainObject);
updateRoute(nonEditableObject);
}
function navigateTo(domainObject) {

View File

@ -50,6 +50,7 @@ define(
}
beforeEach(function () {
mockScope = jasmine.createSpyObj(
"$scope",
[ "$on", "$watch" ]
@ -82,11 +83,11 @@ define(
);
mockDomainObject = jasmine.createSpyObj(
"domainObject",
[ "getId", "getCapability", "getModel", "useCapability" ]
[ "getId", "hasCapability", "getCapability", "getModel", "useCapability" ]
);
mockNextObject = jasmine.createSpyObj(
"nextObject",
[ "getId", "getCapability", "getModel", "useCapability" ]
[ "getId", "hasCapability", "getCapability", "getModel", "useCapability" ]
);
mockObjectService.getObjects.andReturn(mockPromise({
@ -98,9 +99,13 @@ define(
mockDomainObject.useCapability.andReturn(mockPromise([
mockNextObject
]));
mockNextObject.useCapability.andReturn(undefined);
mockNextObject.getId.andReturn("next");
mockNextObject.hasCapability.andReturn(false);
mockDomainObject.getId.andReturn("mine");
mockDomainObject.hasCapability.andReturn(false);
controller = new BrowseController(
mockScope,

View File

@ -38,7 +38,7 @@
{
"key": "edit",
"implementation": "actions/EditAction.js",
"depends": [ "$location", "navigationService", "$log" ],
"depends": [ "$q", "navigationService", "$log" ],
"description": "Edit this object.",
"category": "view-control",
"glyph": "p"
@ -67,7 +67,7 @@
"implementation": "actions/SaveAction.js",
"name": "Save",
"description": "Save changes made to these objects.",
"depends": [ "$location", "urlService" ],
"depends": [ "navigationService" ],
"priority": "mandatory"
},
{
@ -76,7 +76,7 @@
"implementation": "actions/CancelAction.js",
"name": "Cancel",
"description": "Discard changes made to these objects.",
"depends": [ "$location", "urlService" ]
"depends": ["navigationService" ]
}
],
"policies": [

View File

@ -21,10 +21,11 @@
-->
<span ng-controller="EditActionController">
<span ng-repeat="currentAction in editActions">
<a class='s-btn'
<a class='s-btn t-{{currentAction.getMetadata().key}}'
title='{{currentAction.getMetadata().name}}'
ng-click="currentAction.perform()"
ng-class="{ major: $index === 0, subtle: $index !== 0 }">
{{currentAction.getMetadata().name}}
ng-class="{ major: $index === 0 }">
<span class="title-label">{{currentAction.getMetadata().name}}</span>
</a>
</span>
</span>

View File

@ -33,10 +33,9 @@ define(
* @memberof platform/commonUI/edit
* @implements {Action}
*/
function CancelAction($location, urlService, context) {
function CancelAction(navigationService, context) {
this.domainObject = context.domainObject;
this.$location = $location;
this.urlService = urlService;
this.navigationService = navigationService;
}
/**
@ -47,8 +46,7 @@ define(
*/
CancelAction.prototype.perform = function () {
var domainObject = this.domainObject,
$location = this.$location,
urlService = this.urlService;
navigationService = this.navigationService;
// Look up the object's "editor.completion" capability;
// this is introduced by EditableDomainObject which is
@ -64,13 +62,9 @@ define(
return editor.cancel();
}
// Discard the current root view (which will be the editing
// UI, which will have been pushed atop the Browise UI.)
function returnToBrowse() {
$location.path($location.path(urlService.urlForLocation(
"browse",
domainObject
)));
//Return navigation state to the non-editable version of the object.
function returnToBrowse(nonEditableDomainObject) {
navigationService.setNavigation(nonEditableDomainObject);
}
return doCancel(getEditorCapability())
@ -86,7 +80,7 @@ define(
CancelAction.appliesTo = function (context) {
var domainObject = (context || {}).domainObject;
return domainObject !== undefined &&
domainObject.hasCapability("editor");
domainObject.getCapability('status').get('editing');
};
return CancelAction;

View File

@ -25,8 +25,8 @@
* Module defining EditAction. Created by vwoeltje on 11/14/14.
*/
define(
[],
function () {
['../objects/EditableDomainObject'],
function (EditableDomainObject) {
"use strict";
// A no-op action to return in the event that the action cannot
@ -46,7 +46,7 @@ define(
* @constructor
* @implements {Action}
*/
function EditAction($location, navigationService, $log, context) {
function EditAction($q, navigationService, $log, context) {
var domainObject = (context || {}).domainObject;
// We cannot enter Edit mode if we have no domain object to
@ -63,16 +63,20 @@ define(
}
this.domainObject = domainObject;
this.$location = $location;
this.navigationService = navigationService;
this.$q = $q;
}
EditAction.prototype.createEditableObject = function(domainObject) {
return new EditableDomainObject(domainObject, this.$q);
};
/**
* Enter edit mode.
*/
EditAction.prototype.perform = function () {
this.navigationService.setNavigation(this.domainObject);
this.$location.path("/edit");
this.domainObject.getCapability('status').set('editing', true);
this.navigationService.setNavigation(this.createEditableObject(this.domainObject));
};
/**
@ -85,8 +89,11 @@ define(
var domainObject = (context || {}).domainObject,
type = domainObject && domainObject.getCapability('type');
// Only allow creatable types to be edited
return type && type.hasFeature('creation');
// Only allow creatable types to be edited, and objects that are
// not already being edited
return type
&& type.hasFeature('creation')
&& !domainObject.getCapability('status').get('editing');
};
return EditAction;

View File

@ -34,10 +34,9 @@ define(
* @implements {Action}
* @memberof platform/commonUI/edit
*/
function SaveAction($location, urlService, context) {
function SaveAction(navigationService, context) {
this.domainObject = (context || {}).domainObject;
this.$location = $location;
this.urlService = urlService;
this.navigationService = navigationService;
}
/**
@ -49,8 +48,7 @@ define(
*/
SaveAction.prototype.perform = function () {
var domainObject = this.domainObject,
$location = this.$location,
urlService = this.urlService;
navigationService = this.navigationService;
// Invoke any save behavior introduced by the editor capability;
// this is introduced by EditableDomainObject which is
@ -62,11 +60,8 @@ define(
// Discard the current root view (which will be the editing
// UI, which will have been pushed atop the Browise UI.)
function returnToBrowse() {
return $location.path(urlService.urlForLocation(
"browse",
domainObject
));
function returnToBrowse(nonEditableDomainObject) {
navigationService.setNavigation(nonEditableDomainObject);
}
return doSave().then(returnToBrowse);
@ -81,7 +76,7 @@ define(
SaveAction.appliesTo = function (context) {
var domainObject = (context || {}).domainObject;
return domainObject !== undefined &&
domainObject.hasCapability("editor");
domainObject.getCapability("status").get("editing");
};
return SaveAction;

View File

@ -95,9 +95,16 @@ define(
return domainObject.getCapability('persistence').persist();
}
return nonrecursive ?
resolvePromise(doMutate()).then(doPersist) :
resolvePromise(cache.saveAll());
function saveChanges() {
return nonrecursive ?
resolvePromise(doMutate()).then(doPersist) :
resolvePromise(cache.saveAll());
}
return saveChanges().then(function(){
domainObject.getCapability('status').set('editing', false);
return domainObject;
});
};
/**
@ -109,7 +116,8 @@ define(
* @memberof platform/commonUI/edit.EditorCapability#
*/
EditorCapability.prototype.cancel = function () {
return resolvePromise(undefined);
this.domainObject.getCapability('status').set('editing', false);
return resolvePromise(this.domainObject);
};
/**
@ -121,6 +129,10 @@ define(
return this.cache.dirty();
};
EditorCapability.prototype.getDomainObject = function () {
return this.domainObject;
};
return EditorCapability;
}
);

View File

@ -47,6 +47,7 @@ define(
*/
function EditRepresenter($q, $log, scope) {
var self = this;
this.scope = scope;
// Mutate and persist a new version of a domain object's model.
function doPersist(model) {
@ -100,6 +101,7 @@ define(
this.key = (representation || {}).key;
// Track the represented object
this.domainObject = representedObject;
this.scope.editMode = representedObject.hasCapability("status") && representedObject.getCapability("status").get("editing");
// Ensure existing watches are released
this.destroy();
};

View File

@ -27,10 +27,11 @@ define(
"use strict";
describe("The Cancel action", function () {
var mockLocation,
mockDomainObject,
var mockDomainObject,
mockCapabilities,
mockEditorCapability,
mockUrlService,
mockStatusCapability,
mockNavigationService,
actionContext,
action;
@ -43,45 +44,50 @@ define(
}
beforeEach(function () {
mockLocation = jasmine.createSpyObj(
"$location",
[ "path" ]
);
mockDomainObject = jasmine.createSpyObj(
"domainObject",
[ "getCapability", "hasCapability" ]
[ "getCapability" ]
);
mockEditorCapability = jasmine.createSpyObj(
"editor",
[ "save", "cancel" ]
);
mockUrlService = jasmine.createSpyObj(
"urlService",
["urlForLocation"]
mockStatusCapability = jasmine.createSpyObj(
"status",
[ "get"]
);
mockNavigationService = jasmine.createSpyObj(
"navigationService",
["setNavigation"]
);
mockCapabilities = {
"editor": mockEditorCapability,
"status": mockStatusCapability
};
actionContext = {
domainObject: mockDomainObject
};
mockDomainObject.hasCapability.andReturn(true);
mockDomainObject.getCapability.andReturn(mockEditorCapability);
mockEditorCapability.cancel.andReturn(mockPromise(true));
mockDomainObject.getCapability.andCallFake(function(capability){
return mockCapabilities[capability];
});
action = new CancelAction(mockLocation, mockUrlService, actionContext);
mockEditorCapability.cancel.andReturn(mockPromise(mockDomainObject));
mockStatusCapability.get.andReturn(true);
action = new CancelAction( mockNavigationService, actionContext);
});
it("only applies to domain object with an editor capability", function () {
it("only applies to domain object that is being edited", function () {
expect(CancelAction.appliesTo(actionContext)).toBeTruthy();
expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor");
mockDomainObject.hasCapability.andReturn(false);
mockDomainObject.getCapability.andReturn(undefined);
mockStatusCapability.get.andReturn(false);
expect(CancelAction.appliesTo(actionContext)).toBeFalsy();
});
it("invokes the editor capability's save functionality when performed", function () {
it("invokes the editor capability's cancel functionality when" +
" performed", function () {
// Verify precondition
expect(mockEditorCapability.cancel).not.toHaveBeenCalled();
action.perform();
@ -95,8 +101,8 @@ define(
it("returns to browse when performed", function () {
action.perform();
expect(mockLocation.path).toHaveBeenCalledWith(
mockUrlService.urlForLocation("browse", mockDomainObject)
expect(mockNavigationService.setNavigation).toHaveBeenCalledWith(
mockDomainObject
);
});
});

View File

@ -19,27 +19,41 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,describe,it,expect,beforeEach,jasmine*/
/*global define,describe,it,expect,beforeEach,jasmine,spyOn*/
define(
["../../src/actions/EditAction"],
[
"../../src/actions/EditAction"
],
function (EditAction) {
"use strict";
describe("The Edit action", function () {
var mockLocation,
mockNavigationService,
var mockNavigationService,
mockLog,
mockDomainObject,
mockStatusCapability,
mockType,
actionContext,
mockCapabilities,
mockQ,
action;
function mockPromise(value) {
return {
then: function (callback) {
return mockPromise(callback(value));
}
};
}
beforeEach(function () {
mockLocation = jasmine.createSpyObj(
"$location",
[ "path" ]
mockStatusCapability = jasmine.createSpyObj(
"statusCapability",
[ "get", "set" ]
);
mockNavigationService = jasmine.createSpyObj(
"navigationService",
[ "setNavigation", "getNavigation" ]
@ -50,20 +64,41 @@ define(
);
mockDomainObject = jasmine.createSpyObj(
"domainObject",
[ "getId", "getModel", "getCapability" ]
[ "getId", "getModel", "getCapability", "hasCapability" ]
);
mockType = jasmine.createSpyObj(
"type",
[ "hasFeature" ]
);
mockDomainObject.getCapability.andReturn(mockType);
mockQ = jasmine.createSpyObj(
"q",
[ "when", "all" ]
);
mockQ.when.andReturn(function(value){
return mockPromise(value);
});
mockQ.all.andReturn(mockPromise(undefined));
mockDomainObject.getCapability.andCallFake(function(capability){
return mockCapabilities[capability];
});
mockDomainObject.getModel.andReturn({});
mockDomainObject.getId.andReturn("testId");
mockStatusCapability.get.andReturn(false);
mockType.hasFeature.andReturn(true);
mockCapabilities = {
"status": mockStatusCapability,
"type": mockType
};
actionContext = { domainObject: mockDomainObject };
action = new EditAction(
mockLocation,
mockQ,
mockNavigationService,
mockLog,
actionContext
@ -77,15 +112,30 @@ define(
expect(mockType.hasFeature).toHaveBeenCalledWith('creation');
});
it("changes URL path to edit mode when performed", function () {
it("is only applicable when domain object is not in edit mode", function () {
// Indicates whether object is in edit mode
mockStatusCapability.get.andReturn(false);
expect(EditAction.appliesTo(actionContext)).toBeTruthy();
mockStatusCapability.get.andReturn(true);
expect(EditAction.appliesTo(actionContext)).toBeFalsy();
});
it("navigates to editable domain object", function () {
spyOn(action, 'createEditableObject');
action.perform();
expect(mockLocation.path).toHaveBeenCalledWith("/edit");
expect(mockNavigationService.setNavigation).toHaveBeenCalled();
expect(action.createEditableObject).toHaveBeenCalled();
});
it("ensures that the edited object is navigated-to", function () {
var navigatedObject;
action.perform();
expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockDomainObject);
navigatedObject = mockNavigationService.setNavigation.mostRecentCall.args[0];
expect(navigatedObject.getId())
.toEqual(mockDomainObject.getId());
expect(navigatedObject).not.toBe(mockDomainObject);
});
it("logs a warning if constructed when inapplicable", function () {
@ -94,7 +144,7 @@ define(
// Should not have hit an exception...
new EditAction(
mockLocation,
mockQ,
mockNavigationService,
mockLog,
{}
@ -104,8 +154,6 @@ define(
expect(mockLog.warn).toHaveBeenCalled();
// And should not have had other interactions
expect(mockLocation.path)
.not.toHaveBeenCalled();
expect(mockNavigationService.setNavigation)
.not.toHaveBeenCalled();
});

View File

@ -27,10 +27,11 @@ define(
"use strict";
describe("The Save action", function () {
var mockLocation,
mockDomainObject,
var mockDomainObject,
mockNavigationService,
mockStatusCapability,
mockEditorCapability,
mockUrlService,
mockCapabilities,
actionContext,
action;
@ -43,10 +44,6 @@ define(
}
beforeEach(function () {
mockLocation = jasmine.createSpyObj(
"$location",
[ "path" ]
);
mockDomainObject = jasmine.createSpyObj(
"domainObject",
[ "getCapability", "hasCapability" ]
@ -55,30 +52,39 @@ define(
"editor",
[ "save", "cancel" ]
);
mockUrlService = jasmine.createSpyObj(
"urlService",
["urlForLocation"]
mockStatusCapability = jasmine.createSpyObj(
"statusCapability",
["get"]
);
mockNavigationService = jasmine.createSpyObj(
"mockNavigationService",
[ "setNavigation"]
);
mockCapabilities = {
"editor": mockEditorCapability,
"status": mockStatusCapability
};
actionContext = {
domainObject: mockDomainObject
};
mockDomainObject.hasCapability.andReturn(true);
mockDomainObject.getCapability.andReturn(mockEditorCapability);
mockEditorCapability.save.andReturn(mockPromise(true));
mockDomainObject.getCapability.andCallFake(function(capability){
return mockCapabilities[capability];
});
action = new SaveAction(mockLocation, mockUrlService, actionContext);
mockEditorCapability.save.andReturn(mockPromise(mockDomainObject));
mockStatusCapability.get.andReturn(true);
action = new SaveAction(mockNavigationService, actionContext);
});
it("only applies to domain object with an editor capability", function () {
it("only applies to domain object that is being edited", function () {
expect(SaveAction.appliesTo(actionContext)).toBeTruthy();
expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor");
mockDomainObject.hasCapability.andReturn(false);
mockDomainObject.getCapability.andReturn(undefined);
mockStatusCapability.get.andReturn(false);
expect(SaveAction.appliesTo(actionContext)).toBeFalsy();
});
@ -96,8 +102,8 @@ define(
it("returns to browse when performed", function () {
action.perform();
expect(mockLocation.path).toHaveBeenCalledWith(
mockUrlService.urlForLocation("browse", mockDomainObject)
expect(mockNavigationService.setNavigation).toHaveBeenCalledWith(
mockDomainObject
);
});
});

View File

@ -28,6 +28,8 @@ define(
describe("The editor capability", function () {
var mockPersistence,
mockStatusCapability,
mockCapabilities,
mockEditableObject,
mockDomainObject,
mockCache,
@ -40,6 +42,14 @@ define(
"persistence",
[ "persist" ]
);
mockStatusCapability = jasmine.createSpyObj(
"status",
[ "set" ]
);
mockCapabilities = {
"persistence":mockPersistence,
"status": mockStatusCapability
};
mockEditableObject = {
getModel: function () { return model; }
};
@ -53,7 +63,9 @@ define(
);
mockCallback = jasmine.createSpy("callback");
mockDomainObject.getCapability.andReturn(mockPersistence);
mockDomainObject.getCapability.andCallFake(function(capability){
return mockCapabilities[capability];
});
model = { someKey: "some value", x: 42 };
@ -96,6 +108,19 @@ define(
});
});
it("resets the editing status on successful save", function () {
capability.save().then(mockCallback);
// Wait for promise to resolve
waitsFor(function () {
return mockCallback.calls.length > 0;
}, 250);
runs(function () {
expect(mockStatusCapability.set).toHaveBeenCalledWith('editing', false);
});
});
it("has no interactions on cancel", function () {
capability.cancel().then(mockCallback);
@ -111,6 +136,19 @@ define(
});
});
it("resets editing status on cancel", function () {
capability.cancel().then(mockCallback);
// Wait for promise to resolve
waitsFor(function () {
return mockCallback.calls.length > 0;
}, 250);
runs(function () {
expect(mockStatusCapability.set).toHaveBeenCalledWith('editing', false);
});
});
});
}

View File

@ -32,7 +32,9 @@ define(
mockScope,
testRepresentation,
mockDomainObject,
mockStatusCapability,
mockPersistence,
mockCapabilities,
representer;
function mockPromise(value) {
@ -57,11 +59,21 @@ define(
]);
mockPersistence =
jasmine.createSpyObj("persistence", ["persist"]);
mockStatusCapability = jasmine.createSpyObj("domainObject", [
"get"]);
mockCapabilities = {
"persistence": mockPersistence,
"status": mockStatusCapability
};
mockDomainObject.getModel.andReturn({});
mockDomainObject.hasCapability.andReturn(true);
mockDomainObject.useCapability.andReturn(true);
mockDomainObject.getCapability.andReturn(mockPersistence);
mockStatusCapability.get.andReturn(true);
mockDomainObject.getCapability.andCallFake(function(capability){
return mockCapabilities[capability];
});
representer = new EditRepresenter(mockQ, mockLog, mockScope);
representer.represent(testRepresentation, mockDomainObject);
@ -98,6 +110,14 @@ define(
});
});
it("sets an 'editMode' flag on scope if the object is editable", function() {
expect(mockScope.editMode).toBe(true);
mockStatusCapability.get.andReturn(false);
representer.represent(testRepresentation, mockDomainObject);
expect(mockScope.editMode).toBeFalsy();
});
});
}

View File

@ -47,14 +47,11 @@ a.disabled {
@include animation-name(pulse, 0.2);
}
@include keyframes(pulse) {
0% { opacity: 0.5; }
100% { opacity: 1; }
}
@mixin pulse($dur: 500ms, $iteration: infinite) {
//@include customKeyframes(pulse, 0.2);
@mixin pulse($dur: 500ms, $iteration: infinite, $opacity0: 0.5, $opacity100: 1) {
@include keyframes(pulse) {
0% { opacity: $opacity0; }
100% { opacity: $opacity100; }
}
@include animation-name(pulse);
@include animation-duration($dur);
@include animation-direction(alternate);
@ -62,6 +59,19 @@ a.disabled {
@include animation-timing-function(ease-in-out);
}
@mixin pulseBorder($c: red, $dur: 500ms, $iteration: infinite, $delay: 0s, $opacity0: 0, $opacity100: 1) {
@include keyframes(pulseBorder) {
0% { border-color: rgba($c, $opacity0); }
100% { border-color: rgba($c, $opacity100); }
}
@include animation-name(pulseBorder);
@include animation-duration($dur);
@include animation-direction(alternate);
@include animation-iteration-count($iteration);
@include animation-timing-function(ease);
@include animation-delay($delay);
}
.pulse {
@include pulse(750ms);
}

View File

@ -121,7 +121,12 @@ mct-container {
text-align: center;
}
.scrolling {
.ellipsis {
@include ellipsize();
}
.scrolling,
.scroll {
overflow: auto;
}

View File

@ -23,7 +23,7 @@
.l-inspect,
.l-inspect table tr td {
font-size: 0.7rem;
font-size: 0.75rem;
}
.l-inspect {
@ -31,6 +31,9 @@
background: $colorInspectorBg;
color: $colorInspectorFg;
line-height: 140%;
.flex-elem.holder:not(:last-child) { margin-bottom: $interiorMargin; }
.pane-header {
color: pushBack($colorInspectorFg, 20%);
font-size: 0.8rem;
@ -43,6 +46,16 @@
vertical-align: bottom;
}
}
.split-layout {
.split-pane-component.pane {
&.bottom {
height: 30%;
min-height: 20%;
max-height: 80%;
}
}
}
ul {
@include box-sizing(border-box);
@ -118,4 +131,34 @@
width: 4px;
}
}
}
.holder-elements {
.current-elements {
position: relative;
.tree-item {
.t-object-label {
// Elements pool is a flat list, so don't indent items.
font-size: 0.75rem;
left: 0;
}
}
}
}
}
.l-inspect {
.splitter-inspect-panel,
.split-pane-component.pane.bottom {
@include trans-prop-nice(opacity, 250ms); // Not working as desired currently; entire inspector seems to be destroyed and recreated when switching into and out of edit mode.
opacity: 0;
pointer-events: none;
}
}
.s-status-editing .l-inspect {
.location-item { pointer-events: none; }
.splitter-inspect-panel,
.split-pane-component.pane.bottom {
opacity: 1;
pointer-events: inherit;
}
}

View File

@ -64,6 +64,12 @@
}
}
@mixin trans-prop-nice-resize($t: 0.5s, $tf: ease-in-out) {
@include transition-property(height, width, top, right, bottom, left, opacity);
@include transition-duration($t);
@include transition-timing-function($tf);
}
@mixin trans-prop-nice-resize-h($dur: 500ms, $delay: 0) {
@include transition-property(height, bottom, top);
@include transition-duration($dur);
@ -309,11 +315,11 @@
}
}
@mixin input-base($bg: $colorBodyBg, $fg: $colorBodyFg) {
@mixin input-base($bg: $colorInputBg, $fg: $colorInputFg, $shdw: rgba(black, 0.6) 0 1px 3px) {
@include appearance(none);
@include border-radius($controlCr);
@include box-sizing(border-box);
@include box-shadow(inset rgba(black, 0.4) 0 1px 3px);
@include box-shadow(inset $shdw);
background: $bg;
border: none;
color: $fg;
@ -323,7 +329,7 @@
}
}
@mixin nice-input($bg: $colorBodyBg, $fg: $colorBodyFg) {
@mixin nice-input($bg: $colorInputBg, $fg: $colorInputFg) {
@include input-base($bg, $fg);
padding: 0 $interiorMarginSm;
}

View File

@ -35,6 +35,7 @@ $pad: $interiorMargin * $baseRatio;
@include box-sizing(border-box);
padding: 0 $pad;
font-size: 0.7rem;
vertical-align: top;
.icon {
font-size: 0.8rem;
@ -70,6 +71,18 @@ $pad: $interiorMargin * $baseRatio;
&.pause-play {
}
&.t-save:before {
content:'\e612';
font-family: symbolsfont;
margin-right: $interiorMarginSm;
}
&.t-cancel {
.title-label { display: none; }
&:before {
content:'\78';
font-family: symbolsfont;
}
}
&.pause-play {
.icon:before {

View File

@ -6,10 +6,6 @@
}
}
.l-time-controller-visible {
}
mct-include.l-time-controller {
$minW: 500px;
$knobHOffset: 0px;
@ -22,10 +18,10 @@ mct-include.l-time-controller {
$r2H: nth($ueTimeControlH,2);
$r3H: nth($ueTimeControlH,3);
@include absPosDefault();
//@include absPosDefault();
//@include test();
display: block;
top: auto;
//top: auto;
height: $r1H + $r2H + $r3H + ($interiorMargin * 2);
min-width: $minW;
font-size: 0.8rem;

View File

@ -19,8 +19,10 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
.s-status-editing .l-object-wrapper,
.edit-main {
// .s-status-editing .l-object-wrapper is relevant to New Edit Mode;
// .edit-main is legacy for old edit mode.
$handleD: 15px;
$cr: 5px;
.edit-corner,
@ -92,12 +94,10 @@
}
}
.frame.child-frame.panel {
&:hover {
@include boxShdwLarge();
border-color: $colorKey;
//z-index: 2;
.view-switcher {
opacity: 1;
}

View File

@ -31,7 +31,6 @@
}
.form {
// @include test(orange);
color: $colorFormText;
.form-section {
position: relative;
@ -112,12 +111,8 @@
.selector-list {
// Used in create overlay to display tree view
@include nice-input($colorInputBg, $colorInputFg);
@include nice-input();
$h: 150px;
//@include border-radius($basicCr);
//@include box-sizing(border-box);
//background: rgba(black, 0.2);
//padding: $interiorMargin;
position: relative;
height: $h;
// max-width: 50%;
@ -162,13 +157,9 @@ label.form-control.checkbox {
}
}
input[type="text"] {
@include nice-input($colorInputBg, $colorInputFg);
&.filter {
&.ng-dirty {
// background: red;
}
}
input[type="text"],
input[type="search"] {
@include nice-input();
&.numeric {
text-align: right;
}
@ -176,7 +167,6 @@ input[type="text"] {
textarea {
@include nice-textarea($colorInputBg, $colorInputFg);
// font-size: 0.9em;
position: absolute;
height: 100%;
width: 100%;

View File

@ -21,20 +21,7 @@
*****************************************************************************/
.filter,
.t-filter {
input.filter,
input.t-filter-input {
@include subdued-input();
}
input.t-filter-input {
height: $formInputH;
width: 200px;
&:not(.ng-dirty) {
// TO-DO: Update compass install to support this
// @include input-placeholder {
// color: rgba(#fff, 0.3);
// font-style: italic;
// }
}
&:not(.ng-dirty) + .t-a-clear {
display: none;
}
@ -76,13 +63,6 @@
background-color: $colorKey;
}
}
// &:not(ng-dirty)
}
.l-filter {
// Holds an input and a clear button
display:inline-block;
position: relative;
}
.top-bar {
@ -100,4 +80,75 @@
.icon-filter {
font-size: 1.4em;
}
}
.l-filter {
$iconEdgeM: 4px;
$iconD: $formInputH - ($iconEdgeM * 2);
// Adds a magnifying glass before, holds an input and a clear button
display: inline-block;
position: relative;
input[type="search"] {
padding: 2px ($iconD + $interiorMargin);
}
.clear-icon,
.menu-icon,
&:before {
@include box-sizing(border-box);
display: inline-block;
line-height: inherit;
position: absolute;
top: 50%;
@include transform(translateY(-50%));
z-index: 1;
}
&:before {
// Magnify glass icon
content:'\4d';
left: $interiorMargin;
@include trans-prop-nice(color, 250ms);
pointer-events: none;
}
.clear-icon {
right: $iconEdgeM;
// Icon is visible only when there is text input
visibility: hidden;
opacity: 0;
&.show {
visibility: visible;
opacity: 1;
}
&:hover {
color: pullForward($colorInputIcon, 10%);
}
}
}
.s-filter {
input[type="search"] {
@include input-base();
}
.clear-icon,
.menu-icon,
&:before {
color: $colorInputIcon;
cursor: pointer;
font-family: symbolsfont;
@include trans-prop-nice((opacity, color), 150ms);
}
// Make icon lighten when hovering over search bar
&:hover:before {
color: pullForward($colorInputIcon, 10%);
}
.clear-icon {
// 'x' in circle icon
&:before {
content: '\e607';
}
}
}

View File

@ -102,7 +102,7 @@
}
.object-browse-bar {
left: 45px !important;
margin-left: 45px;
.context-available {
opacity: 1 !important;
}

View File

@ -149,3 +149,32 @@ mct-representation {
border-color: rgba($colorItemTreeSelectedFg, 0.25);
border-top-color: rgba($colorItemTreeSelectedFg, 1.0);
}
.tree .s-status-editing,
.search-results .s-status-editing {
// Item is being edited
.tree-item,
.search-result-item {
background: $colorItemTreeEditingBg;
pointer-events: none;
&:before {
// Pencil icon
@extend .ui-symbol;
@include pulse($dur: 1s, $opacity0: 0.25);
color: $colorItemTreeEditingFg;
content: '\70';
margin-right: $interiorMarginSm;
}
.t-object-label {
.t-item-icon,
.t-title-label {
color: $colorItemTreeEditingFg;
@include text-shadow(none);
}
.t-title-label {
font-style: italic;
}
}
.view-control, + .tree-item-subtree { display: none; }
}
}

View File

@ -25,6 +25,7 @@
&.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
&:hover {
border-color: lighten($bc, 10%);
}

View File

@ -77,38 +77,38 @@
}
}
// from _bottom-bar.scss
.ue-bottom-bar {
@include absPosDefault(0);// New status bar design
top: auto;
height: $ueFooterH;
line-height: $ueFooterH - ($interiorMargin * 2);
background: $colorFooterBg;
color: lighten($colorBodyBg, 30%);
font-size: .7rem;
.status-holder {
@include box-sizing(border-box);
@include absPosDefault($interiorMargin);
@include ellipsize();
right: 120px;
text-transform: uppercase;
z-index: 1;
}
.app-logo {
@include box-sizing(border-box);
@include absPosDefault($interiorMargin);
cursor: pointer;
left: auto;
width: $ueAppLogoW;
z-index: 2;
&.logo-openmctweb {
background: url($dirImgs + 'logo-openmctweb.svg') no-repeat center center;
}
}
}
.ue-bottom-bar {
@include absPosDefault(0);// New status bar design
top: auto;
height: $ueFooterH;
line-height: $ueFooterH - ($interiorMargin * 2);
background: $colorFooterBg;
color: lighten($colorBodyBg, 30%);
font-size: .7rem;
.status-holder {
@include box-sizing(border-box);
@include absPosDefault($interiorMargin);
@include ellipsize();
right: 120px;
text-transform: uppercase;
z-index: 1;
}
.app-logo {
@include box-sizing(border-box);
@include absPosDefault($interiorMargin);
cursor: pointer;
left: auto;
width: $ueAppLogoW;
z-index: 2;
&.logo-openmctweb {
background: url($dirImgs + 'logo-openmctweb.svg') no-repeat center center;
}
}
}
}
.edit-mode {
// Old edit mode
.split-layout {
.split-pane-component.pane.right {
width: 15%;
@ -172,7 +172,7 @@
&.toggle-inspect.anchor-right {
right: $bodyMargin;
&:after {
content: '\e615'; // e615: Crosshair icon; was e608: Info "i" icon
content: '\e615'; // Eye icon
}
&.collapsed {
right: $interiorMargin;
@ -197,6 +197,16 @@
right: 0;
bottom: $bodyMargin;
left: $bodyMargin;
.create-btn-holder {
&.s-status-editing {
display: none;
& + .search-holder .search-bar {
// .search-holder is adjacent sibling to .create-btn-holder
// Add right margin when create button is hidden, to make room for the collapse pane 'x' button
margin-right: $interiorMarginLg * 2;
}
}
}
}
.holder.holder-object-and-inspector {
@ -208,25 +218,50 @@
top: $bodyMargin;
bottom: $bodyMargin;
}
.holder-inspector-elements {
.holder-inspector {
top: $bodyMargin;
bottom: $bodyMargin;
left: $bodyMargin;
right: $bodyMargin;
}
.holder-elements {
top: 0;
bottom: $bodyMargin;
left: $bodyMargin;
right: $bodyMargin;
}
}
}
.object-holder {
@include absPosDefault(0, auto);
top: $ueTopBarH + $interiorMarginLg;
&.l-controls-visible {
&.l-time-controller-visible {
bottom: nth($ueTimeControlH,1) + nth($ueTimeControlH,2) +nth($ueTimeControlH,3) + ($interiorMargin * 3);
}
.l-object-wrapper {
@extend .abs;
.object-holder-main {
@extend .abs;
}
.l-edit-controls {
//@include trans-prop-nice((opacity, height), 0.25s);
border-bottom: 1px solid $colorInteriorBorder;
line-height: $ueEditToolBarH;
height: 0px;
opacity: 0;
.tool-bar {
right: $interiorMargin;
}
}
}
.l-object-wrapper-inner {
@include trans-prop-nice-resize(0.25s);
}
.object-browse-bar .s-btn,
.top-bar .buttons-main .s-btn,
.top-bar .s-menu-btn,
@ -247,7 +282,6 @@
/***************************************************** OBJECT BROWSE BAR */
.object-browse-bar {
@include absPosDefault(0, visible); // Must use visible to avoid hiding view switcher menu
@include box-sizing(border-box);
height: $ueTopBarH;
line-height: $ueTopBarH;
@ -255,15 +289,13 @@
.left {
padding-right: $interiorMarginLg;
.l-back {
.l-back:not(.s-status-editing) {
margin-right: $interiorMarginLg;
}
}
}
// When the tree is hidden, these are the
// classes used for the left menu and the
// right representation.
// When the tree is hidden, these are the classes used for the left menu and the right representation.
.pane-tree-hidden {
// Sets the left tree menu when the tree is hidden.
.tree-holder,
@ -299,9 +331,6 @@
.pane-inspect-hidden {
.l-object-and-inspector {
.t-inspect {
z-index: 1 !important; // Move down so that primary pane elements are clickable
}
.l-inspect,
.splitter-inspect {
opacity: 0;
@ -345,3 +374,22 @@
min-width: 200px; // Needed for nice display when primary pane is constrained severely via splitters
}
}
.s-status-editing {
.l-object-wrapper {
@include pulseBorder($colorEditAreaFg, $dur: 1s, $opacity0: 0.3);
@include border-radius($controlCr);
background-color: $colorEditAreaBg;
border-color: $colorEditAreaFg;
border-width: 2px;
border-style: dotted;
.l-object-wrapper-inner {
@include absPosDefault(3px, hidden);
}
.l-edit-controls {
height: $ueEditToolBarH + $interiorMargin;
margin-bottom: $interiorMargin;
opacity: 1;
}
}
}

View File

@ -20,7 +20,9 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
.tool-bar {
border-bottom: 1px solid $colorInteriorBorder;
&.btn-bar {
white-space: nowrap;
}
.l-control-group {
height: $btnToolbarH;
}

View File

@ -46,8 +46,7 @@
.edit-mode {
.top-bar {
.buttons-main {
// background: red;
// width: 600px;
// Old edit mode
white-space: nowrap;
&.abs {
bottom: auto;

View File

@ -20,15 +20,13 @@
at runtime from the About dialog for additional information.
-->
<!-- look at action-button for example -->
<span class="t-filter l-filter"
<span class="t-filter l-filter s-filter"
ng-controller="GetterSetterController">
<input type="search"
class="t-filter-input"
ng-model="getterSetter.value"
placeholder="Filter..."/>
<a class="ui-symbol t-a-clear s-a-clear"
ng-show="getterSetter.value !== ''"
ng-model="getterSetter.value"/>
<a class="clear-icon"
ng-class="{show: !(getterSetter.value === '' || getterSetter.value === undefined)}"
ng-click="getterSetter.value = ''">
x
</a>
</span>

View File

@ -20,44 +20,61 @@
at runtime from the About dialog for additional information.
-->
<span class="l-inspect" ng-controller="ObjectInspectorController as controller">
<div class="abs holder holder-inspector-elements l-flex-col">
<div class="pane-header flex-elem">Inspection</div>
<ul class="flex-elem grows vscroll">
<li>
<em>Properties</em>
<div class="inspector-properties"
ng-repeat="data in metadata"
ng-class="{ first:$index === 0 }">
<div class="label">{{ data.name }}</div>
<div class="value">{{ data.value }}</div>
<div ng-controller="PaneController as modelPaneEdit">
<mct-split-pane class='abs contents split-layout' anchor='bottom'>
<div class="split-pane-component pane top">
<div class="abs holder holder-inspector l-flex-col">
<div class="pane-header flex-elem">Inspection</div>
<ul class="flex-elem grows vscroll">
<li>
<em>Properties</em>
<div class="inspector-properties"
ng-repeat="data in metadata"
ng-class="{ first:$index === 0 }">
<div class="label">{{ data.name }}</div>
<div class="value">{{ data.value }}</div>
</div>
</li>
<li ng-if="contextutalParents.length > 0">
<em title="The location of this linked object.">Location</em>
<span class="inspector-location"
ng-repeat="parent in contextutalParents"
ng-class="{ last:($index + 1) === contextualParents.length }">
<mct-representation key="'label'"
mct-object="parent"
ng-model="ngModel"
ng-click="ngModel.selectedObject = parent"
class="location-item">
</mct-representation>
</span>
</li>
<li ng-if="primaryParents.length > 0">
<em title="The location of the original object that this was linked from.">Original Location</em>
<span class="inspector-location"
ng-repeat="parent in primaryParents"
ng-class="{ last:($index + 1) === primaryParents.length }">
<mct-representation key="'label'"
mct-object="parent"
ng-model="ngModel"
ng-click="ngModel.selectedObject = parent"
class="location-item">
</mct-representation>
</span>
</li>
</ul>
</div><!--/ holder-inspector -->
</div><!--/ split-pane-component -->
<mct-splitter class="splitter-inspect-panel mobile-hide"></mct-splitter>
<div class="split-pane-component pane bottom">
<div class="abs holder holder-elements l-flex-col">
<em class="flex-elem">Elements</em>
<mct-representation
key="'edit-elements'"
mct-object="domainObject"
class="flex-elem holder grows vscroll current-elements">
</mct-representation>
</div>
</div>
</li>
<li ng-if="contextutalParents.length > 0">
<em title="The location of this linked object.">Location</em>
<span class="inspector-location"
ng-repeat="parent in contextutalParents"
ng-class="{ last:($index + 1) === contextualParents.length }">
<mct-representation key="'label'"
mct-object="parent"
ng-model="ngModel"
ng-click="ngModel.selectedObject = parent"
class="location-item rep-object-label">
</mct-representation>
</span>
</li>
<li ng-if="primaryParents.length > 0">
<em title="The location of the original object that this was linked from.">Original Location</em>
<span class="inspector-location"
ng-repeat="parent in primaryParents"
ng-class="{ last:($index + 1) === primaryParents.length }">
<mct-representation key="'label'"
mct-object="parent"
ng-model="ngModel"
ng-click="ngModel.selectedObject = parent"
class="location-item rep-object-label">
</mct-representation>
</span>
</li>
</ul>
</div>
</mct-split-pane>
</div><!--/ PaneController -->
</span>

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,8 @@ $colorFooterBg: #000;
$colorKey: #0099cc;
$colorKeySelectedBg: #005177;
$colorKeyFg: #fff;
$colorEditAreaBg: #31363e;
$colorEditAreaFg: #587ab5;
$colorInteriorBorder: rgba($colorBodyFg, 0.1);
$colorA: #ccc;
$colorAHov: #fff;
@ -43,8 +45,6 @@ $colorPausedBg: #c56f01;
$colorPausedFg: #fff;
$colorCreateBtn: $colorKey;
$colorGridLines: rgba(#fff, 0.05);
$colorFormLines: rgba(#fff, 0.1);
$colorFormSectionHeader: rgba(#000, 0.2);
$colorInvokeMenu: #fff;
$colorObjHdrTxt: $colorBodyFg;
$colorObjHdrIc: pullForward($colorObjHdrTxt, 20%);
@ -69,8 +69,8 @@ $colorFormValid: #33cc33;
$colorFormError: #cc0000;
$colorFormInvalid: #ff3300;
$colorFormLines: rgba(#fff, 0.1);
$colorFormSectionHeader: rgba(#000, 0.2);
$colorInputBg: rgba(#fff, 0.1);
$colorFormSectionHeader: rgba(#fff, 0.1);
$colorInputBg: rgba(#000, 0.1);
$colorInputFg: pullForward($colorBodyFg, 20%);
$colorFormText: rgba(#fff, 0.5);
$colorInputIcon: pushBack($colorBodyFg, 15%);
@ -80,7 +80,7 @@ $colorInspectorBg: pullForward($colorBodyBg, 3%);
$colorInspectorFg: $colorBodyFg;
$colorInspectorPropName: pushBack($colorBodyFg, 15%);
$colorInspectorPropVal: pullForward($colorInspectorFg, 15%);
$colorInspectorSectionHeaderBg: pullForward($colorInspectorBg, 5%);
$colorInspectorSectionHeaderBg: $colorFormSectionHeader;
$colorInspectorSectionHeaderFg: pullForward($colorInspectorBg, 40%);
// Status colors, mainly used for messaging and item ancillary symbols
@ -109,8 +109,8 @@ $colorLimitRedBg: rgba(red, 0.3);
$colorLimitRedIc: red;
// Bubble colors
$colorInfoBubbleFg: #666;
$colorInfoBubbleBg: #ddd;
$colorInfoBubbleFg: #666;
$colorThumbsBubbleFg: pullForward($colorBodyFg, 10%);
$colorThumbsBubbleBg: pullForward($colorBodyBg, 10%);
@ -126,7 +126,7 @@ $colorItemBg: lighten($colorBodyBg, 5%);
$colorItemBgHov: pullForward($colorItemBg, 15%);
$colorItemFg: lighten($colorItemBg, 50%);
$colorItemFgDetails: lighten($colorItemBg, 30%);
$colorItemIc: $colorKey; //pullForward($colorItemFg, 20%);
$colorItemIc: $colorKey;
$colorItemSubIcons: $colorItemFgDetails;
$colorItemOpenIcon: $colorItemFgDetails;
$shdwItemText: rgba(black, 0.1) 0 1px 2px;
@ -153,12 +153,14 @@ $colorItemTreeHoverBg: rgba($colorBodyFg, 0.1);
$colorItemTreeHoverFg: pullForward($colorBodyFg, 20%);
$colorItemTreeIcon: $colorKey;
$colorItemTreeIconHover: lighten($colorItemTreeIcon, 20%);
$colorItemTreeVCHover: $colorAlt1;
$colorItemTreeFg: $colorBodyFg;
$colorItemTreeSelectedBg: pushBack($colorKey, 15%);
$colorItemTreeSelectedFg: pullForward($colorBodyFg, 20%);
$colorItemTreeEditingBg: #344154;
$colorItemTreeEditingFg: $colorEditAreaFg;
$colorItemTreeVC: rgba(#fff, 0.3);
$colorItemTreeSelectedVC: $colorItemTreeVC;
$colorItemTreeVCHover: $colorAlt1;
$shdwItemTreeIcon: 0.6;
// Scrollbar
@ -171,7 +173,7 @@ $scrollbarTrackShdw: rgba(#000, 0.7) 0 1px 5px;
// Splitter
$splitterD: 25px; // splitterD and HandleD should both be odd, or even
$splitterHandleD: 1px;
$colorSplitterBg: pullForward($colorBodyBg, 5%);
$colorSplitterBg: rgba(#fff, 0.1); //pullForward($colorBodyBg, 5%);
$splitterShdw: rgba(black, 0.4) 0 0 3px;
$splitterEndCr: none;
$colorSplitterHover: pullForward($colorBodyBg, 15%);
@ -191,5 +193,5 @@ $colorCalCellInMonthBg: pushBack($colorMenuBg, 5%);
$colorAboutLink: #84b3ff;
// Loading
$colorLoadingBg: rgba($colorBodyFg, 0.2);
$colorLoadingFg: $colorAlt1;
$colorLoadingBg: rgba($colorBodyFg, 0.2);

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,8 @@ $colorFooterBg: #000;
$colorKey: #0099cc;
$colorKeySelectedBg: $colorKey;
$colorKeyFg: #fff;
$colorEditAreaBg: #eafaff;
$colorEditAreaFg: #4bb1c7; //587ab5;
$colorInteriorBorder: rgba($colorBodyFg, 0.2);
$colorA: #999;
$colorAHov: $colorKey;
@ -55,10 +57,10 @@ $colorMenuIc: $colorKey;
$colorMenuHovBg: pullForward($colorMenuBg, 10%);
$colorMenuHovFg: $colorMenuFg;
$colorMenuHovIc: $colorMenuIc;
$colorCreateMenuLgIcon: $colorKey;
$colorCreateMenuText: $colorBodyFg;
$shdwMenu: rgba(black, 0.5) 0 1px 5px;
$shdwMenuText: none;
$colorCreateMenuLgIcon: $colorKey;
$colorCreateMenuText: $colorBodyFg;
// Form colors
$colorCheck: $colorKey;
@ -107,8 +109,8 @@ $colorLimitRedBg: rgba(red, 0.3);
$colorLimitRedIc: red;
// Bubble colors
$colorInfoBubbleFg: #666;
$colorInfoBubbleBg: $colorMenuBg;
$colorInfoBubbleFg: #666;
$colorThumbsBubbleFg: pullForward($colorBodyFg, 10%);
$colorThumbsBubbleBg: pullForward($colorBodyBg, 10%);
@ -127,12 +129,11 @@ $colorItemFgDetails: pushBack($colorItemFg, 15%);
$colorItemIc: $colorKey;
$colorItemSubIcons: $colorItemFgDetails;
$colorItemOpenIcon: $colorItemFgDetails;
$shdwItemText: none; //rgba(black, 0.2) 0 1px 2px;
$shdwItemText: none;
$colorItemBgSelected: $colorKey;
// Tabular
$colorTabBorder: pullForward($colorBodyBg, 10%);
$colorItemTreeHoverFg: pullForward($colorBodyFg, 20%);
$colorTabBodyBg: $colorBodyBg;
$colorTabBodyFg: pullForward($colorBodyFg, 20%);
$colorTabHeaderBg: pullForward($colorBodyBg, 10%);
@ -149,12 +150,15 @@ $colorPlotLabelFg: pushBack($colorPlotFg, 20%);
// Tree
$colorItemTreeHoverBg: rgba($colorBodyFg, 0.1);
$colorItemTreeHoverFg: pullForward($colorBodyFg, 20%);
$colorItemTreeIcon: $colorKey;
$colorItemTreeIconHover: $colorItemTreeIcon; //pushBack($colorItemTreeIcon, 20%);
$colorItemTreeVCHover: $colorKey;
$colorItemTreeFg: $colorBodyFg;
$colorItemTreeSelectedBg: pushBack($colorKey, 15%);
$colorItemTreeSelectedFg: $colorBodyBg;
$colorItemTreeEditingBg: #caf1ff; //#c6e3ff;
$colorItemTreeEditingFg: $colorEditAreaFg;
$colorItemTreeVC: $colorBodyFg;
$colorItemTreeSelectedVC: $colorBodyBg;
$shdwItemTreeIcon: none;

View File

@ -20,7 +20,8 @@
at runtime from the About dialog for additional information.
-->
<span ng-controller="PlotController as plot"
ng-mouseleave="representation.showControls = false">
ng-mouseleave="representation.showControls = false"
class="abs holder holder-plot">
<div class="gl-plot"
ng-style="{ height: 100 / plot.getSubPlots().length + '%'}"

View File

@ -1,5 +1,5 @@
<!--
Open MCT Web, Copyright (c) 2014-2015, United States Government
Open MCT Web, Copyright (c) 2014-2015, United Statobes Government
as represented by the Administrator of the National Aeronautics and Space
Administration. All rights reserved.
@ -23,7 +23,7 @@
<div class="w2"
ng-controller="ScrollingListController">
<!-- To add filtering, add class 'filterable' to <table> and uncomment 2nd <tr> in <thead> -->
<table class="tabular fixed-header">
<table class="tabular">
<thead>
<tr>
<th ng-repeat="header in headers">

View File

@ -54,7 +54,8 @@
}
}
.edit-mode .s-timeline-gantt {
.edit-mode .s-timeline-gantt,
.s-status-editing .s-timeline-gantt {
.handle {
cursor: col-resize;
&.mid {

View File

@ -69,7 +69,8 @@
}
}
.edit-mode .s-timeline-gantt {
.edit-mode .s-timeline-gantt,
.s-status-editing .s-timeline-gantt {
.bar {
&:hover {
@include background-image(linear-gradient(lighten($colorGanttBarBg, 20), lighten($colorGanttBarBg, 10)));
@ -140,7 +141,8 @@
}
}
.edit-mode .s-swimlane {
.edit-mode .s-swimlane,
.s-status-editing .s-swimlane {
cursor: pointer;
.t-object-label {
@include border-radius($controlCr);