[Mobile] Gestures

Added styling to back and selection
arrow (tree). Also increased the space
allowed for selection arrow on tree item.
Info Button created on grid items for mobile.
Info bubble appears on tablet like desktop.
Also on mobile, info bubble fits to width.
New QueryService that returns if on iPhone.
Also formatted dialog box so that their is no
margin and takes up fullscreen on mobile.
This commit is contained in:
Shivam Dave 2015-08-04 09:59:08 -07:00
parent 560a2e035e
commit 9b922913a0
17 changed files with 284 additions and 142 deletions

View File

@ -24,5 +24,5 @@
<span ng-controller="BrowseController"
ng-click='backArrow()'
ng-class="checkRoot(); atRoot ? 'mobile-back-hide' : 'mobile-back-unhide'">
<a class='type-icon icon ui-symbol'>&lt;</a>
<a class='type-icon icon ui-symbol'>{</a>
</span>

View File

@ -371,7 +371,7 @@
.items-holder .item.grid-item .mobile-grid-nav {
top: 0px;
bottom: 0px;
right: 50px; }
right: 55px; }
/* line 39, ../sass/mobile/_item.scss */
.items-holder .item.grid-item .mobile-info {
text-align: center;

View File

@ -4432,6 +4432,17 @@ input[type="text"] {
left: 5px;
overflow: auto; }
@media screen and (orientation: portrait) and (max-width: 514px) and (max-height: 740px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (max-height: 514px) and (max-width: 740px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (max-height: 514px) and (max-width: 740px) and (max-device-width: 1024px) and (max-device-height: 799px), screen and (orientation: portrait) and (min-width: 515px) and (max-width: 799px) and (min-height: 741px) and (max-height: 1024px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (min-height: 515px) and (max-height: 799px) and (min-width: 741px) and (max-width: 1024px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (min-height: 515px) and (max-height: 799px) and (min-width: 741px) and (max-width: 1024px) and (max-device-width: 1024px) and (max-device-height: 799px) {
/* line 6, ../sass/mobile/overlay/_overlay.scss */
.overlay > .holder {
-moz-border-radius: 0;
-webkit-border-radius: 0;
border-radius: 0;
top: 0;
right: 0;
bottom: 0;
left: 0; } }
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
@ -4757,33 +4768,40 @@ input[type="text"] {
margin-left: 20px; }
/* line 80, ../sass/helpers/_bubbles.scss */
.l-infobubble-wrapper.arw-left .l-infobubble::before {
right: 100%;
width: 0;
height: 0;
border-top: 6.66667px solid transparent;
border-bottom: 6.66667px solid transparent;
border-right: 10px solid #ddd; }
/* line 86, ../sass/helpers/_bubbles.scss */
.l-infobubble-wrapper.arw-right {
margin-right: 20px; }
/* line 88, ../sass/helpers/_bubbles.scss */
.l-infobubble-wrapper.arw-right .l-infobubble::before {
left: 100%;
width: 0;
height: 0;
border-top: 6.66667px solid transparent;
border-bottom: 6.66667px solid transparent;
border-left: 10px solid #ddd; }
/* line 95, ../sass/helpers/_bubbles.scss */
right: 100%; }
@media screen and (orientation: portrait) and (min-width: 515px) and (max-width: 799px) and (min-height: 741px) and (max-height: 1024px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (min-height: 515px) and (max-height: 799px) and (min-width: 741px) and (max-width: 1024px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (min-height: 515px) and (max-height: 799px) and (min-width: 741px) and (max-width: 1024px) and (max-device-width: 1024px) and (max-device-height: 799px), screen and (min-device-width: 800px) and (min-device-height: 1025px), screen and (min-device-width: 1025px) and (min-device-height: 800px) {
/* line 80, ../sass/helpers/_bubbles.scss */
.l-infobubble-wrapper.arw-left .l-infobubble::before {
width: 0;
height: 0;
border-top: 6.66667px solid transparent;
border-bottom: 6.66667px solid transparent;
border-right: 10px solid #ddd; } }
@media screen and (orientation: portrait) and (min-width: 515px) and (max-width: 799px) and (min-height: 741px) and (max-height: 1024px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (min-height: 515px) and (max-height: 799px) and (min-width: 741px) and (max-width: 1024px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (min-height: 515px) and (max-height: 799px) and (min-width: 741px) and (max-width: 1024px) and (max-device-width: 1024px) and (max-device-height: 799px), screen and (min-device-width: 800px) and (min-device-height: 1025px), screen and (min-device-width: 1025px) and (min-device-height: 800px) {
/* line 92, ../sass/helpers/_bubbles.scss */
.l-infobubble-wrapper.arw-right {
margin-right: 20px; } }
/* line 99, ../sass/helpers/_bubbles.scss */
.l-infobubble-wrapper.arw-right .l-infobubble::before {
left: 100%; }
@media screen and (orientation: portrait) and (min-width: 515px) and (max-width: 799px) and (min-height: 741px) and (max-height: 1024px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (min-height: 515px) and (max-height: 799px) and (min-width: 741px) and (max-width: 1024px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (min-height: 515px) and (max-height: 799px) and (min-width: 741px) and (max-width: 1024px) and (max-device-width: 1024px) and (max-device-height: 799px), screen and (min-device-width: 800px) and (min-device-height: 1025px), screen and (min-device-width: 1025px) and (min-device-height: 800px) {
/* line 99, ../sass/helpers/_bubbles.scss */
.l-infobubble-wrapper.arw-right .l-infobubble::before {
width: 0;
height: 0;
border-top: 6.66667px solid transparent;
border-bottom: 6.66667px solid transparent;
border-left: 10px solid #ddd; } }
/* line 112, ../sass/helpers/_bubbles.scss */
.l-infobubble-wrapper.arw-top .l-infobubble::before {
top: 20px; }
/* line 101, ../sass/helpers/_bubbles.scss */
/* line 118, ../sass/helpers/_bubbles.scss */
.l-infobubble-wrapper.arw-btm .l-infobubble::before {
bottom: 20px; }
/* line 106, ../sass/helpers/_bubbles.scss */
/* line 123, ../sass/helpers/_bubbles.scss */
.l-infobubble-wrapper.arw-down {
margin-bottom: 10px; }
/* line 108, ../sass/helpers/_bubbles.scss */
/* line 125, ../sass/helpers/_bubbles.scss */
.l-infobubble-wrapper.arw-down .l-infobubble::before {
left: 50%;
top: 100%;
@ -4791,21 +4809,21 @@ input[type="text"] {
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 7.5px solid #ddd; }
/* line 117, ../sass/helpers/_bubbles.scss */
/* line 134, ../sass/helpers/_bubbles.scss */
.l-infobubble-wrapper .arw {
z-index: 2; }
/* line 120, ../sass/helpers/_bubbles.scss */
/* line 137, ../sass/helpers/_bubbles.scss */
.l-infobubble-wrapper.arw-up .arw.arw-down, .l-infobubble-wrapper.arw-down .arw.arw-up {
display: none; }
/* line 127, ../sass/helpers/_bubbles.scss */
/* line 144, ../sass/helpers/_bubbles.scss */
.l-thumbsbubble-wrapper .arw-up {
width: 0;
height: 0;
border-left: 6.66667px solid transparent;
border-right: 6.66667px solid transparent;
border-bottom: 10px solid #4d4d4d; }
/* line 130, ../sass/helpers/_bubbles.scss */
/* line 147, ../sass/helpers/_bubbles.scss */
.l-thumbsbubble-wrapper .arw-down {
width: 0;
height: 0;
@ -4813,7 +4831,7 @@ input[type="text"] {
border-right: 6.66667px solid transparent;
border-top: 10px solid #4d4d4d; }
/* line 134, ../sass/helpers/_bubbles.scss */
/* line 151, ../sass/helpers/_bubbles.scss */
.s-infobubble {
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
@ -4824,22 +4842,22 @@ input[type="text"] {
background: #ddd;
color: #666;
font-size: 0.8rem; }
/* line 141, ../sass/helpers/_bubbles.scss */
/* line 158, ../sass/helpers/_bubbles.scss */
.s-infobubble .title {
color: #333333;
font-weight: bold; }
/* line 146, ../sass/helpers/_bubbles.scss */
/* line 163, ../sass/helpers/_bubbles.scss */
.s-infobubble tr td {
border-top: 1px solid #c4c4c4;
font-size: 0.9em; }
/* line 150, ../sass/helpers/_bubbles.scss */
/* line 167, ../sass/helpers/_bubbles.scss */
.s-infobubble tr:first-child td {
border-top: none; }
/* line 154, ../sass/helpers/_bubbles.scss */
/* line 171, ../sass/helpers/_bubbles.scss */
.s-infobubble .value {
color: #333333; }
/* line 159, ../sass/helpers/_bubbles.scss */
/* line 176, ../sass/helpers/_bubbles.scss */
.s-thumbsbubble {
background: #4d4d4d;
color: #b3b3b3; }

View File

@ -344,14 +344,16 @@ ul.tree {
right: 13px;
font-size: 1.8em;
right: 0px;
width: auto; }
/* line 44, ../sass/mobile/_tree.scss */
width: 35px;
text-align: center; }
/* line 45, ../sass/mobile/_tree.scss */
ul.tree li span.tree-item .label {
left: 3px;
right: 45px;
font-size: 1.2em; }
/* line 51, ../sass/mobile/_tree.scss */
/* line 54, ../sass/mobile/_tree.scss */
ul.tree li span.tree-item .label .title-label {
right: 16.9px; }
/* line 60, ../sass/mobile/_tree.scss */
/* line 63, ../sass/mobile/_tree.scss */
ul.tree ul.tree {
margin-left: 7px; } }

View File

@ -64,6 +64,7 @@
@import "forms/filter";
@import "plots/plots-main";
@import "overlay/overlay";
@import "mobile/overlay/overlay";
@import "user-environ/frame";
@import "user-environ/top-bar";
@import "user-environ/bottom-bar";

View File

@ -79,15 +79,32 @@
margin-left: $bubbleArwSize*2;
.l-infobubble::before {
right: 100%;
@include triangle('left', $bubbleArwSize, 1.5, $colorInfoBubbleBg);
// NOTE: [MOBILE] REMOVES TRIANGLE
// Removes the triangle located on the info
// bubble for phones only, for tablets and
// desktops, triangle remains.
@include desktopandtablet {
@include triangle('left', $bubbleArwSize, 1.5, $colorInfoBubbleBg);
}
}
}
&.arw-right {
margin-right: $bubbleArwSize*2;
// NOTE: [MOBILE] REMOVES RIGHT MARGIN
// Removes right margin made for the
// triangle on mobile
@include desktopandtablet {
margin-right: $bubbleArwSize*2;
}
.l-infobubble::before {
left: 100%;
@include triangle('right', $bubbleArwSize, 1.5, $colorInfoBubbleBg);
// NOTE: [MOBILE] REMOVES TRIANGLE
// Removes the triangle located on the info
// bubble for phones only, for tablets and
// desktops, triangle remains.
@include desktopandtablet {
@include triangle('right', $bubbleArwSize, 1.5, $colorInfoBubbleBg);
}
}
}
@ -124,12 +141,12 @@
//************************************************* LOOK AND FEEL
.l-thumbsbubble-wrapper {
.arw-up {
@include triangle('up', $bubbleArwSize, 1.5, $colorThumbsBubbleBg);
}
.arw-down {
@include triangle('down', $bubbleArwSize, 1.5, $colorThumbsBubbleBg);
}
.arw-up {
@include triangle('up', $bubbleArwSize, 1.5, $colorThumbsBubbleBg);
}
.arw-down {
@include triangle('down', $bubbleArwSize, 1.5, $colorThumbsBubbleBg);
}
}
.s-infobubble {
$emFg: darken($colorInfoBubbleFg, 20%);

View File

@ -34,7 +34,7 @@
.mobile-grid-nav {
top: 0px;
bottom: 0px;
right: 50px;
right: 55px;
}
.mobile-info {
text-align: center;

View File

@ -75,7 +75,18 @@
#{$phoneLandscapeEmu},
#{$tabletPortrait},
#{$tabletLandscape},
#{$tabletLandscapeEmu}{
#{$tabletLandscapeEmu} {
@content
}
}
// Desktop monitors in any orientation
@mixin desktopandtablet {
@media #{$tabletPortrait},
#{$tabletLandscape},
#{$tabletLandscapeEmu},
#{$desktopPortrait},
#{$desktopLandscape} {
@content
}
}

View File

@ -38,19 +38,22 @@ ul.tree {
right: $mobile-treeRight;
font-size: 1.8em;
right: 0px;
width: auto;
width: 35px;
text-align: center;
}
.label {
// Designates the starting left margin
// (indentation) of 'My Items'
// Also adds right space for selection button
left: $mobile-startingTreeLeft;
right: 45px;
font-size: 1.2em;
// Allows tree item name to stop prior
// to the arrow
.title-label {
right: $mobile-treeRight * 1.3;
}
}
}
}
}

View File

@ -0,0 +1,11 @@
.overlay {
@include phoneandtablet {
$m: 0;
// Removes curved edges on the dialog box
// and makes it take up fullscreen
>.holder {
@include border-radius($m);
top: $m; right: $m; bottom: $m; left: $m;
}
}
}

View File

@ -41,7 +41,7 @@
toggle.toggle(); treeNode.trackExpansion()"
ng-if="model.composition !== undefined || treeNode.checkMobile()"
>
{{treeNode.checkMobile() ? ">" : toggle.isActive() ? "v" : ">"}}
{{treeNode.checkMobile() ? "}" : toggle.isActive() ? "v" : ">"}}
</span>
</span>
<span

View File

@ -54,6 +54,17 @@ define(
return false;
}
}
// Checks if device is phone,
// phone is designated as only an
// iPhone device
function isPhone(ua) {
if (getDeviceUA(ua) == "iPhone") {
return true;
} else {
return false;
}
}
// Returns the orientation of the device based on the
// device's window dimensions
@ -76,7 +87,13 @@ define(
* on a mobile or non-mobile device. (mobile: true,
* non-mobile: false)
*/
isMobile: isMobile
isMobile: isMobile,
/**
* Returns the a boolean checking if the user is on
* a phone device. (phone: true, non-phone: false)
*/
isPhone: isPhone
};
}

View File

@ -9,13 +9,6 @@
"key": "info-bubble",
"templateUrl": "info-bubble.html"
}
],
"controllers": [
{
"key": "InfoController",
"implementation": "controllers/InfoController.js",
"depends": [ "$scope", "$timeout", "infoService" ]
}
],
"containers": [
{
@ -35,6 +28,15 @@
"infoService",
"INFO_HOVER_DELAY"
]
},
{
"key": "infobutton",
"implementation": "gestures/InfoButtonGesture.js",
"depends": [
"$document",
"queryService",
"infoService"
]
}
],
"services": [
@ -45,7 +47,8 @@
"$compile",
"$document",
"$window",
"$rootScope"
"$rootScope",
"queryService"
]
}
],
@ -58,7 +61,8 @@
"representations": [
{
"key": "info-button",
"templateUrl": "templates/info-button.html"
"templateUrl": "templates/info-button.html",
"gestures": [ "infobutton" ]
}
]
}

View File

@ -20,6 +20,7 @@
at runtime from the About dialog for additional information.
-->
<div ng-controller="InfoController" ng-click='tryToDis($event)'>
<!--The icon for the info button appearing in a grid item (list in folder)-->
<div>
<a class='ui-symbol icon mobile-info'>i</a>
</div>

View File

@ -1,69 +0,0 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise*/
/**
* Module defining InfoController.
*/
define(
[],
function () {
"use strict";
function InfoController($scope, $timeout, infoService) {
var touchPosition,
bubble;
function trackPosition(event) {
// Record mouse position, so bubble can be shown at latest
// mouse position (not just where the mouse entered)
touchPosition = [ event.pageX, event.pageY ];
}
function display(event) {
var domainObject = $scope.domainObject;
console.log(domainObject.getId());
trackPosition(event);
if(!bubble) {
bubble = infoService.display(
"info-table",
domainObject.getModel().name,
domainObject.useCapability('metadata'),
touchPosition
);
} else {
bubble();
bubble = undefined;
}
$timeout(function () {
// If a bubble is showing, dismiss it after timeout
if (bubble) {
bubble();
bubble = undefined;
}
}, 750);
}
$scope.tryToDis = display;
}
return InfoController;
}
);

View File

@ -0,0 +1,116 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define(
[],
function () {
"use strict";
/**
* The `info` gesture displays domain object metadata in a
* bubble on hover.
*
* @constructor
* @param $document Angular's `$document`
* @param {InfoService} infoService a service which shows info bubbles
* @param element jqLite-wrapped DOM element
* @param {DomainObject} domainObject the domain object for which to
* show information
*/
function InfoGestureButton($document, queryService, infoService, element, domainObject) {
var dismissBubble,
pendingBubble,
touchPosition,
scopeOff,
body = $document.find('body');
function trackPosition(event) {
// Record touch position, so bubble can be shown at latest
// touch position, also offset by 22px to left (accounts for
// a finger-sized touch on the info button)
touchPosition = [ event.clientX - 22, event.clientY ];
}
// Hides the bubble and detaches the
// body hidebubble listener
function hideBubble() {
// If a bubble is showing, dismiss it
if (dismissBubble) {
dismissBubble();
dismissBubble = undefined;
}
// Detaches body touch listener
body.off('touchstart', hideBubble);
}
// Displays the bubble by tracking position of
// touch, using infoService to display the bubble,
// and then on any body touch the bubble is dismissed
function showBubble(event) {
trackPosition(event);
// Show the bubble, but on any touchstart on the
// body (anywhere) call hidebubble
pendingBubble =
dismissBubble = infoService.display(
"info-table",
domainObject.getModel().name,
domainObject.useCapability('metadata'),
touchPosition
);
body.on('touchstart', hideBubble);
}
// Checks if you are on a mobile device, if the device is
// mobile (queryService.isMobile() = true), then
// the a click on something (info button) brings up
// the bubble
if (queryService.isMobile(navigator.userAgent)) {
element.on('click', showBubble);
}
// Also make sure we dismiss bubble if representation is destroyed
// before the mouse actually leaves it
scopeOff = element.scope().$on('$destroy', hideBubble);
return {
/**
* Detach any event handlers associated with this gesture.
* @memberof InfoGesture
* @method
*/
destroy: function () {
// Dismiss any active bubble...
hideBubble();
// ...and detach listeners
element.off('click', showBubble);
scopeOff();
}
};
}
return InfoGestureButton;
}
);

View File

@ -33,7 +33,7 @@ define(
* Displays informative content ("info bubbles") for the user.
* @constructor
*/
function InfoService($compile, $document, $window, $rootScope) {
function InfoService($compile, $document, $window, $rootScope, queryService) {
function display(templateKey, title, content, position) {
var body = $document.find('body'),
@ -54,19 +54,29 @@ define(
// Create the context menu
bubble = $compile(BUBBLE_TEMPLATE)(scope);
// Position the bubble
// Position the bubble:
// Phone: On a phone the bubble is specifically positioned
// so that it takes up the width of the screen.
// Tablet/Desktop: On other devices with larger screens, the
// info bubble positioned as normal (with triangle pointing
// to where clicked or pressed)
bubble.css('position', 'absolute');
if (goLeft) {
bubble.css('right', (winDim[0] - position[0] + OFFSET[0]) + 'px');
if(queryService.isPhone(navigator.userAgent)) {
bubble.css('right', 5 + 'px');
bubble.css('left', 5 + 'px');
bubble.css('top', 40 + 'px');
} else {
bubble.css('left', position[0] + OFFSET[0] + 'px');
if (goLeft) {
bubble.css('right', (winDim[0] - position[0] + OFFSET[0]) + 'px');
} else {
bubble.css('left', position[0] + OFFSET[0] + 'px');
}
if (goUp) {
bubble.css('bottom', (winDim[1] - position[1] + OFFSET[1]) + 'px');
} else {
bubble.css('top', position[1] + OFFSET[1] + 'px');
}
}
if (goUp) {
bubble.css('bottom', (winDim[1] - position[1] + OFFSET[1]) + 'px');
} else {
bubble.css('top', position[1] + OFFSET[1] + 'px');
}
// Add the menu to the body
body.append(bubble);