mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-12 16:52:50 +00:00
Merge branch 'develop' into touch-walkthrough-update
This commit is contained in:
@@ -176,6 +176,7 @@ input[type=email] {
|
||||
height: 30px;
|
||||
border-radius: 4px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
.ideditor[dir='rtl'] textarea,
|
||||
.ideditor[dir='rtl'] input[type=text],
|
||||
@@ -779,9 +780,9 @@ a.hide-toggle {
|
||||
.sidebar-resizer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -6px;
|
||||
right: -10px;
|
||||
width: 10px;
|
||||
height: 100%;
|
||||
width: 6px;
|
||||
cursor: col-resize;
|
||||
/* disable drag-to-select */
|
||||
user-select: none;
|
||||
@@ -911,7 +912,6 @@ a.hide-toggle {
|
||||
width: 100%;
|
||||
}
|
||||
.no-results-item,
|
||||
.geocode-item,
|
||||
.feature-list-item {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
@@ -920,11 +920,13 @@ a.hide-toggle {
|
||||
}
|
||||
|
||||
.geocode-item {
|
||||
width: 50%;
|
||||
width: 100%;
|
||||
max-width: 200px;
|
||||
background-color: #ccc;
|
||||
left: 25%;
|
||||
margin-top: 30px;
|
||||
border-radius: 2px;
|
||||
margin: 30px auto;
|
||||
padding: 5px;
|
||||
height: auto;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.ideditor[dir='rtl'] .geocode-item {
|
||||
@@ -2319,7 +2321,7 @@ div.combobox {
|
||||
|
||||
.more-fields input {
|
||||
margin-left: 10px;
|
||||
flex: 1 1 50%;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
.ideditor[dir='rtl'] .more-fields input {
|
||||
margin-left: auto;
|
||||
|
||||
@@ -95,6 +95,8 @@ export function behaviorSelect(context) {
|
||||
|
||||
if (d3_event.buttons && d3_event.buttons !== 1) return;
|
||||
|
||||
context.ui().closeEditMenu();
|
||||
|
||||
_longPressTimeout = window.setTimeout(didLongPress, 500, id, 'longdown-' + (d3_event.pointerType || 'mouse'));
|
||||
|
||||
_downPointers[id] = {
|
||||
|
||||
@@ -641,7 +641,6 @@ export function rendererMap(context) {
|
||||
function resetTransform() {
|
||||
if (!_isTransformed) return false;
|
||||
|
||||
supersurface.selectAll('.edit-menu').interrupt().remove();
|
||||
utilSetTransform(supersurface, 0, 0);
|
||||
_isTransformed = false;
|
||||
if (context.inIntro()) {
|
||||
|
||||
@@ -11,6 +11,7 @@ export function uiEditMenu(context) {
|
||||
var _operations = [];
|
||||
// the position the menu should be displayed relative to
|
||||
var _anchorLoc = [0, 0];
|
||||
var _anchorLocLonLat = [0, 0];
|
||||
// a string indicating how the menu was opened
|
||||
var _triggerType = '';
|
||||
|
||||
@@ -18,6 +19,10 @@ export function uiEditMenu(context) {
|
||||
var _vpBottomMargin = 45; // viewport bottom margin
|
||||
var _vpSideMargin = 35; // viewport side margin
|
||||
|
||||
var _menuTop = false;
|
||||
var _menuHeight;
|
||||
var _menuWidth;
|
||||
|
||||
// hardcode these values to make menu positioning easier
|
||||
var _verticalPadding = 4;
|
||||
|
||||
@@ -27,6 +32,8 @@ export function uiEditMenu(context) {
|
||||
// offset the menu slightly from the target location
|
||||
var _menuSideMargin = 10;
|
||||
|
||||
var _tooltips = [];
|
||||
|
||||
var editMenu = function(selection) {
|
||||
|
||||
var isTouchMenu = _triggerType.includes('touch') || _triggerType.includes('pen');
|
||||
@@ -37,59 +44,32 @@ export function uiEditMenu(context) {
|
||||
|
||||
if (!ops.length) return;
|
||||
|
||||
var offset = [0, 0];
|
||||
var viewport = context.surfaceRect();
|
||||
_tooltips = [];
|
||||
|
||||
// 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;
|
||||
_menuTop = isTouchMenu;
|
||||
|
||||
// Show labels for touch input since there aren't hover tooltips
|
||||
var showLabels = isTouchMenu;
|
||||
|
||||
var buttonHeight = showLabels ? 32 : 34;
|
||||
var menuWidth;
|
||||
if (showLabels) {
|
||||
// Get a general idea of the width based on the length of the label
|
||||
menuWidth = 52 + Math.min(120, 6 * Math.max.apply(Math, ops.map(function(op) {
|
||||
_menuWidth = 52 + Math.min(120, 6 * Math.max.apply(Math, ops.map(function(op) {
|
||||
return op.title.length;
|
||||
})));
|
||||
} else {
|
||||
menuWidth = 44;
|
||||
_menuWidth = 44;
|
||||
}
|
||||
|
||||
var menuLeft = displayOnLeft(viewport);
|
||||
|
||||
offset[0] = menuLeft ? -1 * (_menuSideMargin + menuWidth) : _menuSideMargin;
|
||||
|
||||
var menuHeight = _verticalPadding * 2 + ops.length * buttonHeight;
|
||||
|
||||
|
||||
if (menuTop) {
|
||||
if (_anchorLoc[1] - menuHeight < _vpTopMargin) {
|
||||
// menu is near top viewport edge, shift downward
|
||||
offset[1] = -_anchorLoc[1] + _vpTopMargin;
|
||||
} else {
|
||||
offset[1] = -menuHeight;
|
||||
}
|
||||
} else {
|
||||
if (_anchorLoc[1] + menuHeight > (viewport.height - _vpBottomMargin)) {
|
||||
// menu is near bottom viewport edge, shift upwards
|
||||
offset[1] = -_anchorLoc[1] - menuHeight + viewport.height - _vpBottomMargin;
|
||||
} else {
|
||||
offset[1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
var origin = geoVecAdd(_anchorLoc, offset);
|
||||
_menuHeight = _verticalPadding * 2 + ops.length * buttonHeight;
|
||||
|
||||
_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');
|
||||
.style('padding', _verticalPadding + 'px 0');
|
||||
|
||||
var buttons = _menu.selectAll('.edit-menu-item')
|
||||
.data(ops);
|
||||
@@ -107,16 +87,16 @@ export function uiEditMenu(context) {
|
||||
d3_event.stopPropagation();
|
||||
});
|
||||
|
||||
var tooltipSide = tooltipPosition(viewport, menuLeft);
|
||||
|
||||
buttonsEnter.each(function(d) {
|
||||
var tooltip = uiTooltip()
|
||||
.heading(d.title)
|
||||
.title(d.tooltip())
|
||||
.keys([d.keys[0]]);
|
||||
|
||||
_tooltips.push(tooltip);
|
||||
|
||||
d3_select(this)
|
||||
.call(uiTooltip()
|
||||
.heading(d.title)
|
||||
.title(d.tooltip())
|
||||
.keys([d.keys[0]])
|
||||
.placement(tooltipSide)
|
||||
)
|
||||
.call(tooltip)
|
||||
.append('div')
|
||||
.attr('class', 'icon-wrap')
|
||||
.call(svgIcon('#iD-operation-' + d.id, 'operation'));
|
||||
@@ -135,6 +115,18 @@ export function uiEditMenu(context) {
|
||||
.merge(buttons)
|
||||
.classed('disabled', function(d) { return d.disabled(); });
|
||||
|
||||
updatePosition();
|
||||
|
||||
var initialScale = context.projection.scale();
|
||||
context.map()
|
||||
.on('move.edit-menu', function() {
|
||||
if (initialScale !== context.projection.scale()) {
|
||||
editMenu.close();
|
||||
}
|
||||
})
|
||||
.on('drawn.edit-menu', function(info) {
|
||||
if (info.full) updatePosition();
|
||||
});
|
||||
|
||||
var lastPointerUpType;
|
||||
// `pointerup` is always called before `click`
|
||||
@@ -169,10 +161,62 @@ export function uiEditMenu(context) {
|
||||
}
|
||||
lastPointerUpType = null;
|
||||
}
|
||||
};
|
||||
|
||||
function updatePosition() {
|
||||
|
||||
if (!_menu || _menu.empty()) return;
|
||||
|
||||
var anchorLoc = context.projection(_anchorLocLonLat);
|
||||
|
||||
var viewport = context.surfaceRect();
|
||||
|
||||
if (anchorLoc[0] < 0 ||
|
||||
anchorLoc[0] > viewport.width ||
|
||||
anchorLoc[1] < 0 ||
|
||||
anchorLoc[1] > viewport.height) {
|
||||
// close the menu if it's gone offscreen
|
||||
|
||||
editMenu.close();
|
||||
return;
|
||||
}
|
||||
|
||||
var menuLeft = displayOnLeft(viewport);
|
||||
|
||||
var offset = [0, 0];
|
||||
|
||||
offset[0] = menuLeft ? -1 * (_menuSideMargin + _menuWidth) : _menuSideMargin;
|
||||
|
||||
if (_menuTop) {
|
||||
if (anchorLoc[1] - _menuHeight < _vpTopMargin) {
|
||||
// menu is near top viewport edge, shift downward
|
||||
offset[1] = -anchorLoc[1] + _vpTopMargin;
|
||||
} else {
|
||||
offset[1] = -_menuHeight;
|
||||
}
|
||||
} else {
|
||||
if (anchorLoc[1] + _menuHeight > (viewport.height - _vpBottomMargin)) {
|
||||
// menu is near bottom viewport edge, shift upwards
|
||||
offset[1] = -anchorLoc[1] - _menuHeight + viewport.height - _vpBottomMargin;
|
||||
} else {
|
||||
offset[1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
var origin = geoVecAdd(anchorLoc, offset);
|
||||
|
||||
_menu
|
||||
.style('left', origin[0] + 'px')
|
||||
.style('top', origin[1] + 'px');
|
||||
|
||||
var tooltipSide = tooltipPosition(viewport, menuLeft);
|
||||
_tooltips.forEach(function(tooltip) {
|
||||
tooltip.placement(tooltipSide);
|
||||
});
|
||||
|
||||
function displayOnLeft(viewport) {
|
||||
if (localizer.textDirection() === 'ltr') {
|
||||
if ((_anchorLoc[0] + _menuSideMargin + menuWidth) > (viewport.width - _vpSideMargin)) {
|
||||
if ((anchorLoc[0] + _menuSideMargin + _menuWidth) > (viewport.width - _vpSideMargin)) {
|
||||
// right menu would be too close to the right viewport edge, go left
|
||||
return true;
|
||||
}
|
||||
@@ -180,7 +224,7 @@ export function uiEditMenu(context) {
|
||||
return false;
|
||||
|
||||
} else { // rtl
|
||||
if ((_anchorLoc[0] - _menuSideMargin - menuWidth) < _vpSideMargin) {
|
||||
if ((anchorLoc[0] - _menuSideMargin - _menuWidth) < _vpSideMargin) {
|
||||
// left menu would be too close to the left viewport edge, go right
|
||||
return false;
|
||||
}
|
||||
@@ -196,7 +240,7 @@ export function uiEditMenu(context) {
|
||||
// isn't room for right-side tooltips
|
||||
return 'left';
|
||||
}
|
||||
if ((_anchorLoc[0] + _menuSideMargin + menuWidth + _tooltipWidth) > (viewport.width - _vpSideMargin)) {
|
||||
if ((anchorLoc[0] + _menuSideMargin + _menuWidth + _tooltipWidth) > (viewport.width - _vpSideMargin)) {
|
||||
// right tooltips would be too close to the right viewport edge, go left
|
||||
return 'left';
|
||||
}
|
||||
@@ -207,7 +251,7 @@ export function uiEditMenu(context) {
|
||||
if (!menuLeft) {
|
||||
return 'right';
|
||||
}
|
||||
if ((_anchorLoc[0] - _menuSideMargin - menuWidth - _tooltipWidth) < _vpSideMargin) {
|
||||
if ((anchorLoc[0] - _menuSideMargin - _menuWidth - _tooltipWidth) < _vpSideMargin) {
|
||||
// left tooltips would be too close to the left viewport edge, go right
|
||||
return 'right';
|
||||
}
|
||||
@@ -215,16 +259,22 @@ export function uiEditMenu(context) {
|
||||
return 'left';
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
editMenu.close = function () {
|
||||
_menu
|
||||
.remove();
|
||||
|
||||
context.map()
|
||||
.on('move.edit-menu', null)
|
||||
.on('drawn.edit-menu', null);
|
||||
|
||||
_menu.remove();
|
||||
_tooltips = [];
|
||||
};
|
||||
|
||||
editMenu.anchorLoc = function(val) {
|
||||
if (!arguments.length) return _anchorLoc;
|
||||
_anchorLoc = val;
|
||||
_anchorLocLonLat = context.projection.invert(_anchorLoc);
|
||||
return editMenu;
|
||||
};
|
||||
|
||||
|
||||
@@ -76,11 +76,16 @@ export function uiFormFields(context) {
|
||||
more.exit()
|
||||
.remove();
|
||||
|
||||
more = more.enter()
|
||||
var moreEnter = more.enter()
|
||||
.append('div')
|
||||
.attr('class', 'more-fields')
|
||||
.append('label')
|
||||
.text(t('inspector.add_fields'))
|
||||
.append('label');
|
||||
|
||||
moreEnter
|
||||
.append('span')
|
||||
.text(t('inspector.add_fields'));
|
||||
|
||||
more = moreEnter
|
||||
.merge(more);
|
||||
|
||||
|
||||
|
||||
@@ -146,9 +146,6 @@ export function uiPopover(klass) {
|
||||
popoverSelection.classed('fade', true);
|
||||
}
|
||||
|
||||
var placement = _placement.apply(this, arguments);
|
||||
popoverSelection.classed(placement, true);
|
||||
|
||||
var display = _displayType.apply(this, arguments);
|
||||
|
||||
if (display === 'hover') {
|
||||
@@ -251,6 +248,13 @@ export function uiPopover(klass) {
|
||||
var scrollTop = scrollNode ? scrollNode.scrollTop : 0;
|
||||
|
||||
var placement = _placement.apply(this, arguments);
|
||||
popoverSelection
|
||||
.classed('left', false)
|
||||
.classed('right', false)
|
||||
.classed('top', false)
|
||||
.classed('bottom', false)
|
||||
.classed(placement, true);
|
||||
|
||||
var alignment = _alignment.apply(this, arguments);
|
||||
var alignFactor = 0.5;
|
||||
if (alignment === 'leading') {
|
||||
|
||||
@@ -317,15 +317,27 @@ export function uiSectionRawMembershipEditor(context) {
|
||||
.append('li')
|
||||
.attr('class', 'member-row member-row-new form-field');
|
||||
|
||||
newMembershipEnter
|
||||
var newLabelEnter = newMembershipEnter
|
||||
.append('label')
|
||||
.attr('class', 'field-label')
|
||||
.attr('class', 'field-label');
|
||||
|
||||
newLabelEnter
|
||||
.append('input')
|
||||
.attr('placeholder', t('inspector.choose_relation'))
|
||||
.attr('type', 'text')
|
||||
.attr('class', 'member-entity-input')
|
||||
.call(utilNoAuto);
|
||||
|
||||
newLabelEnter
|
||||
.append('button')
|
||||
.attr('tabindex', -1)
|
||||
.attr('class', 'remove member-delete')
|
||||
.call(svgIcon('#iD-operation-delete'))
|
||||
.on('click', function() {
|
||||
list.selectAll('.member-row-new')
|
||||
.remove();
|
||||
});
|
||||
|
||||
var newWrapEnter = newMembershipEnter
|
||||
.append('div')
|
||||
.attr('class', 'form-field-input-wrap form-field-input-member');
|
||||
@@ -337,16 +349,6 @@ export function uiSectionRawMembershipEditor(context) {
|
||||
.attr('placeholder', t('inspector.role'))
|
||||
.call(utilNoAuto);
|
||||
|
||||
newWrapEnter
|
||||
.append('button')
|
||||
.attr('tabindex', -1)
|
||||
.attr('class', 'remove form-field-button member-delete')
|
||||
.call(svgIcon('#iD-operation-delete'))
|
||||
.on('click', function() {
|
||||
list.selectAll('.member-row-new')
|
||||
.remove();
|
||||
});
|
||||
|
||||
// Update
|
||||
newMembership = newMembership
|
||||
.merge(newMembershipEnter);
|
||||
|
||||
@@ -38,7 +38,7 @@ export function uiSidebar(context) {
|
||||
|
||||
function sidebar(selection) {
|
||||
var container = context.container();
|
||||
var minWidth = 280;
|
||||
var minWidth = 240;
|
||||
var sidebarWidth;
|
||||
var containerWidth;
|
||||
var dragOffset;
|
||||
@@ -59,6 +59,8 @@ export function uiSidebar(context) {
|
||||
function pointerdown() {
|
||||
if (downPointerId) return;
|
||||
|
||||
if ('button' in d3_event && d3_event.button !== 0) return;
|
||||
|
||||
downPointerId = d3_event.pointerId || 'mouse';
|
||||
|
||||
lastClientX = d3_event.clientX;
|
||||
|
||||
Reference in New Issue
Block a user