From 5e58259c125b9470b72e1f9e674cac36ae4641db Mon Sep 17 00:00:00 2001 From: Quincy Morgan Date: Fri, 26 Jun 2020 13:34:54 -0400 Subject: [PATCH] Show labels for edit menu items on touch interaction (re: #7577) --- css/80_app.css | 16 ++++- modules/ui/edit_menu.js | 125 ++++++++++++++++++++++------------------ 2 files changed, 84 insertions(+), 57 deletions(-) diff --git a/css/80_app.css b/css/80_app.css index 716e48f16..3af905565 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -5401,8 +5401,22 @@ li.hide + li.version .badge .tooltip .popover-arrow { } .edit-menu-item { + display: flex; + align-items: center; border-radius: 0; - /* width and height are set in edit_menu.js */ + padding: 0 12px; + /* height is set in edit_menu.js */ +} +.edit-menu-item .label { + max-width: 120px; + text-align: initial; + line-height: 1.1em; +} +.ideditor[dir='ltr'] .edit-menu-item .label { + margin-left: 8px; +} +.ideditor[dir='rtl'] .edit-menu-item .label { + margin-right: 8px; } .edit-menu-item use { diff --git a/modules/ui/edit_menu.js b/modules/ui/edit_menu.js index b55edbbc6..b4d784879 100644 --- a/modules/ui/edit_menu.js +++ b/modules/ui/edit_menu.js @@ -19,9 +19,6 @@ export function uiEditMenu(context) { var _vpSideMargin = 35; // viewport side margin // hardcode these values to make menu positioning easier - var _buttonWidth = 44; - var _buttonHeight = 34; - var _menuWidth = _buttonWidth; var _verticalPadding = 4; // see also `.edit-menu .tooltip` CSS; include margin @@ -36,15 +33,23 @@ export function uiEditMenu(context) { var offset = [0, 0]; var viewport = context.surfaceRect(); - // position the menu above the anchor for stylus and finger input - // since the mapper's hand likely obscures the screen below the anchor - var menuTop = _triggerType.includes('touch') || _triggerType.includes('pen'); + var isTouchMenu = _triggerType.includes('touch') || _triggerType.includes('pen'); + // Position the menu above the anchor for stylus and finger input + // since the mapper's hand likely obscures the screen below the anchor + var menuTop = isTouchMenu; + + // Show labels for touch input since there aren't hover tooltips + var showLabels = isTouchMenu; + + var buttonHeight = showLabels ? 32 : 34; + var menuWidth = showLabels ? 172 : 44; var menuLeft = displayOnLeft(viewport); - offset[0] = menuLeft ? -1 * (_menuSideMargin + _menuWidth) : _menuSideMargin; + offset[0] = menuLeft ? -1 * (_menuSideMargin + menuWidth) : _menuSideMargin; + + var menuHeight = _verticalPadding * 2 + _operations.length * buttonHeight; - var menuHeight = _verticalPadding * 2 + _operations.length * _buttonHeight; if (menuTop) { if (_anchorLoc[1] - menuHeight < _vpTopMargin) { @@ -67,6 +72,7 @@ export function uiEditMenu(context) { _menu = selection .append('div') .attr('class', 'edit-menu') + .classed('touch-menu', isTouchMenu) .style('padding', _verticalPadding + 'px 0') .style('left', origin[0] + 'px') .style('top', origin[1] + 'px'); @@ -78,26 +84,38 @@ export function uiEditMenu(context) { var buttonsEnter = buttons.enter() .append('button') .attr('class', function (d) { return 'edit-menu-item edit-menu-item-' + d.id; }) - .style('width', _buttonWidth + 'px') - .style('height', _buttonHeight + 'px') + .style('height', buttonHeight + 'px') .on('click', click) // don't listen for `mouseup` because we only care about non-mouse pointer types .on('pointerup', pointerup) - .on('pointerdown mousedown', pointerdown); + .on('pointerdown mousedown', function pointerdown() { + // don't let button presses also act as map input - #1869 + d3_event.stopPropagation(); + }); var tooltipSide = tooltipPosition(viewport, menuLeft); buttonsEnter.each(function(d) { d3_select(this) - .call(svgIcon('#iD-operation-' + d.id, 'operation-icon')) .call(uiTooltip() .heading(d.title) .title(d.tooltip()) .keys([d.keys[0]]) .placement(tooltipSide) - ); + ) + .append('div') + .attr('class', 'icon-wrap') + .call(svgIcon('#iD-operation-' + d.id, 'operation-icon')); }); + if (showLabels) { + buttonsEnter.append('span') + .attr('class', 'label') + .text(function(d) { + return d.title; + }); + } + // update buttons = buttonsEnter .merge(buttons) @@ -138,57 +156,52 @@ export function uiEditMenu(context) { lastPointerUpType = null; } - function pointerdown() { - // don't let button presses also act as map input - #1869 - d3_event.stopPropagation(); - } - }; + function displayOnLeft(viewport) { + if (localizer.textDirection() === 'ltr') { + if ((_anchorLoc[0] + _menuSideMargin + menuWidth) > (viewport.width - _vpSideMargin)) { + // right menu would be too close to the right viewport edge, go left + return true; + } + // prefer right menu + return false; - function displayOnLeft(viewport) { - if (localizer.textDirection() === 'ltr') { - if ((_anchorLoc[0] + _menuSideMargin + _menuWidth) > (viewport.width - _vpSideMargin)) { - // right menu would be too close to the right viewport edge, go left + } else { // rtl + if ((_anchorLoc[0] - _menuSideMargin - menuWidth) < _vpSideMargin) { + // left menu would be too close to the left viewport edge, go right + return false; + } + // prefer left menu return true; } - // prefer right menu - return false; - - } else { // rtl - if ((_anchorLoc[0] - _menuSideMargin - _menuWidth) < _vpSideMargin) { - // left menu would be too close to the left viewport edge, go right - return false; - } - // prefer left menu - return true; } - } - function tooltipPosition(viewport, menuLeft) { - if (localizer.textDirection() === 'ltr') { - if (menuLeft) { - // if there's not room for a right-side menu then there definitely - // isn't room for right-side tooltips + function tooltipPosition(viewport, menuLeft) { + if (localizer.textDirection() === 'ltr') { + if (menuLeft) { + // if there's not room for a right-side menu then there definitely + // isn't room for right-side tooltips + return 'left'; + } + if ((_anchorLoc[0] + _menuSideMargin + menuWidth + _tooltipWidth) > (viewport.width - _vpSideMargin)) { + // right tooltips would be too close to the right viewport edge, go left + return 'left'; + } + // prefer right tooltips + return 'right'; + + } else { // rtl + if (!menuLeft) { + return 'right'; + } + if ((_anchorLoc[0] - _menuSideMargin - menuWidth - _tooltipWidth) < _vpSideMargin) { + // left tooltips would be too close to the left viewport edge, go right + return 'right'; + } + // prefer left tooltips return 'left'; } - if ((_anchorLoc[0] + _menuSideMargin + _menuWidth + _tooltipWidth) > (viewport.width - _vpSideMargin)) { - // right tooltips would be too close to the right viewport edge, go left - return 'left'; - } - // prefer right tooltips - return 'right'; - - } else { // rtl - if (!menuLeft) { - return 'right'; - } - if ((_anchorLoc[0] - _menuSideMargin - _menuWidth - _tooltipWidth) < _vpSideMargin) { - // left tooltips would be too close to the left viewport edge, go right - return 'right'; - } - // prefer left tooltips - return 'left'; } - } + }; editMenu.close = function () { _menu