mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-20 07:25:15 +02:00
Remove old, unused implementations of favorite, recent, and search-to-add preset toolbar items
This commit is contained in:
-217
@@ -607,223 +607,6 @@ button.add-note svg.icon {
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
/* Add a feature search bar
|
||||
------------------------------------------------------- */
|
||||
|
||||
.search-add {
|
||||
width: 200%;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
min-width: 150px;
|
||||
max-width: 325px;
|
||||
}
|
||||
.search-add .search-wrap {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
[dir='ltr'] .search-add .search-wrap {
|
||||
border-radius: 20px 4px 4px 20px;
|
||||
}
|
||||
[dir='rtl'] .search-add .search-wrap {
|
||||
border-radius: 4px 20px 20px 4px;
|
||||
}
|
||||
.search-add .search-wrap.focused .tooltip {
|
||||
display: none;
|
||||
}
|
||||
.search-add .search-wrap:last-child {
|
||||
border-radius: 20px;
|
||||
}
|
||||
.search-add input[type='search'] {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
font-size: 14px;
|
||||
text-indent: 25px;
|
||||
padding: 5px 10px;
|
||||
border-radius: inherit;
|
||||
}
|
||||
.search-add input[type='search'][disabled] {
|
||||
opacity: 0.25;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.search-add .search-icon {
|
||||
color: #333;
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 10px;
|
||||
pointer-events: none;
|
||||
}
|
||||
[dir='rtl'] .search-add .search-icon {
|
||||
left: auto;
|
||||
right: 10px;
|
||||
}
|
||||
.search-add .popover {
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
position: absolute;
|
||||
max-height: 600px;
|
||||
top: 44px;
|
||||
width: 200%;
|
||||
max-width: 325px;
|
||||
margin: auto;
|
||||
left: auto;
|
||||
right: auto;
|
||||
z-index: 300;
|
||||
}
|
||||
.search-add .popover .popover-content {
|
||||
overflow-y: auto;
|
||||
height: 100%;
|
||||
max-height: 60vh;
|
||||
}
|
||||
.search-add .popover,
|
||||
.search-add .popover .popover-content {
|
||||
/* ensure corners are rounded in Chrome */
|
||||
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
|
||||
}
|
||||
.search-add .popover .popover-footer {
|
||||
padding: 5px 10px 5px 10px;
|
||||
background: #f6f6f6;
|
||||
border-top: 1px solid #DCDCDC;
|
||||
display: flex;
|
||||
}
|
||||
.search-add .popover .popover-footer .message {
|
||||
color: #666666;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.search-add .popover .popover-footer button.filter {
|
||||
height: 20px;
|
||||
background: transparent;
|
||||
color: #666;
|
||||
}
|
||||
.search-add .popover .popover-footer button.filter.active {
|
||||
color: #7092ff;
|
||||
}
|
||||
.search-add .popover .popover-footer button.filter:hover {
|
||||
color: #333;
|
||||
}
|
||||
.search-add .popover .popover-footer button.filter.active:hover {
|
||||
color: #597be7;
|
||||
}
|
||||
.search-add .popover::-webkit-scrollbar {
|
||||
/* don't overlap rounded corners */
|
||||
background: transparent;
|
||||
}
|
||||
.search-add .popover .list {
|
||||
height: 100%;
|
||||
}
|
||||
.search-add .list-item > .row {
|
||||
display: flex;
|
||||
position: relative;
|
||||
padding: 2px;
|
||||
}
|
||||
.search-add .list-item:not(:last-of-type) .row,
|
||||
.search-add .subsection.subitems .list-item .row,
|
||||
.search-add .subsection > .tag-reference-body {
|
||||
border-bottom: 1px solid #DCDCDC;
|
||||
}
|
||||
.search-add .list-item .label {
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
padding-left: 2px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 1.3em;
|
||||
width: 100%;
|
||||
}
|
||||
.search-add .list-item .label .namepart:nth-child(2) {
|
||||
font-weight: normal;
|
||||
}
|
||||
.search-add .list-item.disabled .preset-icon-container,
|
||||
.search-add .list-item.disabled .label {
|
||||
opacity: 0.55;
|
||||
}
|
||||
[dir='ltr'] .search-add .list-item .label .icon.inline {
|
||||
margin-left: 0;
|
||||
}
|
||||
[dir='rtl'] .search-add .list-item .label .icon.inline {
|
||||
margin-right: 0;
|
||||
}
|
||||
.search-add .list-item .row > *:not(button) {
|
||||
pointer-events: none;
|
||||
}
|
||||
.search-add .list-item button.choose {
|
||||
position: absolute;
|
||||
border-radius: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.search-add .list-item button.choose:hover,
|
||||
.search-add .list-item button.choose:focus {
|
||||
background: #fff;
|
||||
}
|
||||
.search-add .list-item.focused:not(.disabled) button.choose {
|
||||
background: #e8ebff;
|
||||
}
|
||||
.search-add .list-item button.choose.disabled {
|
||||
background-color: #ececec;
|
||||
}
|
||||
.search-add .subsection .list-item button.choose {
|
||||
opacity: 0.85;
|
||||
}
|
||||
.search-add .subsection .tag-reference-body {
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
padding: 10px;
|
||||
}
|
||||
.search-add .list-item button.accessory {
|
||||
position: relative;
|
||||
flex: 0 0 auto;
|
||||
color: #808080;
|
||||
background: transparent;
|
||||
padding-right: 3px;
|
||||
padding-left: 3px;
|
||||
}
|
||||
.search-add .list-item button.accessory:hover {
|
||||
color: #666;
|
||||
}
|
||||
.search-add .list-item button.tag-reference-open path {
|
||||
fill: #000;
|
||||
}
|
||||
.search-add .subsection {
|
||||
background-color: #CBCBCB;
|
||||
}
|
||||
[dir='ltr'] .search-add .subitems {
|
||||
padding-left: 6px;
|
||||
}
|
||||
[dir='rtl'] .search-add .subitems {
|
||||
padding-right: 6px;
|
||||
}
|
||||
|
||||
/* Add a preset mode buttons
|
||||
------------------------------------------------------- */
|
||||
|
||||
button.bar-button.add-preset {
|
||||
border-radius: 4px;
|
||||
}
|
||||
[dir='ltr'] button.bar-button.add-preset {
|
||||
margin-left: 1px;
|
||||
}
|
||||
[dir='rtl'] button.bar-button.add-preset {
|
||||
margin-right: 1px;
|
||||
}
|
||||
[dir='ltr'] button.bar-button.add-preset.first-recent {
|
||||
margin-left: 10px;
|
||||
}
|
||||
[dir='rtl'] button.bar-button.add-preset.first-recent {
|
||||
margin-right: 10px;
|
||||
}
|
||||
button.bar-button.add-preset {
|
||||
padding: 0;
|
||||
}
|
||||
button.add-preset.disabled .preset-icon-container {
|
||||
opacity: 0.5;
|
||||
}
|
||||
/* Header for modals / panes
|
||||
------------------------------------------------------- */
|
||||
.header {
|
||||
|
||||
@@ -1,295 +0,0 @@
|
||||
import _debounce from 'lodash-es/debounce';
|
||||
|
||||
import { drag as d3_drag } from 'd3-drag';
|
||||
import { event as d3_event, select as d3_select } from 'd3-selection';
|
||||
|
||||
import { modeAddArea, modeAddLine, modeAddPoint, modeBrowse } from '../../modes';
|
||||
import { t, textDirection } from '../../util/locale';
|
||||
import { tooltip } from '../../util/tooltip';
|
||||
import { uiPresetIcon } from '../preset_icon';
|
||||
import { uiTooltipHtml } from '../tooltipHtml';
|
||||
|
||||
|
||||
export function uiToolAddFavorite(context) {
|
||||
|
||||
var tool = {
|
||||
id: 'add_favorite',
|
||||
klass: 'modes',
|
||||
label: t('toolbar.favorites')
|
||||
};
|
||||
|
||||
function enabled() {
|
||||
return osmEditable();
|
||||
}
|
||||
|
||||
function osmEditable() {
|
||||
return context.editable();
|
||||
}
|
||||
|
||||
function toggleMode(d) {
|
||||
if (!enabled(d)) return;
|
||||
|
||||
if (d.button === context.mode().button) {
|
||||
context.enter(modeBrowse(context));
|
||||
} else {
|
||||
if (d.preset) {
|
||||
context.presets().setMostRecent(d.preset, d.geometry);
|
||||
}
|
||||
context.enter(d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tool.render = function(selection) {
|
||||
context
|
||||
.on('enter.editor.favorite', function(entered) {
|
||||
selection.selectAll('button.add-button')
|
||||
.classed('active', function(mode) { return entered.button === mode.button; });
|
||||
context.container()
|
||||
.classed('mode-' + entered.id, true);
|
||||
});
|
||||
|
||||
context
|
||||
.on('exit.editor.favorite', function(exited) {
|
||||
context.container()
|
||||
.classed('mode-' + exited.id, false);
|
||||
});
|
||||
|
||||
var debouncedUpdate = _debounce(update, 500, { leading: true, trailing: true });
|
||||
|
||||
context.map()
|
||||
.on('move.favorite', debouncedUpdate)
|
||||
.on('drawn.favorite', debouncedUpdate);
|
||||
|
||||
context
|
||||
.on('enter.favorite', update)
|
||||
.presets()
|
||||
.on('favoritePreset.favorite', update)
|
||||
.on('recentsChange.favorite', update);
|
||||
|
||||
update();
|
||||
|
||||
|
||||
function update() {
|
||||
|
||||
for (var i = 0; i <= 9; i++) {
|
||||
context.keybinding().off(i.toString());
|
||||
}
|
||||
|
||||
var items = context.presets().getFavorites();
|
||||
|
||||
var modes = items.map(function(d, index) {
|
||||
var presetName = d.preset.name().split(' – ')[0];
|
||||
var markerClass = 'add-preset add-' + d.geometry + ' add-preset-' + presetName.replace(/\s+/g, '_')
|
||||
+ '-' + d.geometry + ' add-' + d.source; // replace spaces with underscores to avoid css interpretation
|
||||
if (d.preset.isFallback()) {
|
||||
markerClass += ' add-generic-preset';
|
||||
}
|
||||
|
||||
var supportedGeometry = d.preset.geometry.filter(function(geometry) {
|
||||
return ['vertex', 'point', 'line', 'area'].indexOf(geometry) !== -1;
|
||||
});
|
||||
var vertexIndex = supportedGeometry.indexOf('vertex');
|
||||
if (vertexIndex !== -1 && supportedGeometry.indexOf('point') !== -1) {
|
||||
// both point and vertex allowed, just combine them
|
||||
supportedGeometry.splice(vertexIndex, 1);
|
||||
}
|
||||
var tooltipTitleID = 'modes.add_preset.title';
|
||||
if (supportedGeometry.length !== 1) {
|
||||
if (d.preset.setTags({}, d.geometry).building) {
|
||||
tooltipTitleID = 'modes.add_preset.building.title';
|
||||
} else {
|
||||
tooltipTitleID = 'modes.add_preset.' + context.presets().fallback(d.geometry).id + '.title';
|
||||
}
|
||||
}
|
||||
var protoMode = Object.assign({}, d); // shallow copy
|
||||
protoMode.button = markerClass;
|
||||
protoMode.title = presetName;
|
||||
protoMode.description = t(tooltipTitleID, { feature: '<strong>' + presetName + '</strong>' });
|
||||
|
||||
var keyCode;
|
||||
// use number row order: 1 2 3 4 5 6 7 8 9 0
|
||||
// use the same for RTL even though the layout is backward: #6107
|
||||
if (index === 9) {
|
||||
keyCode = 0;
|
||||
} else if (index < 10) {
|
||||
keyCode = index + 1;
|
||||
}
|
||||
if (keyCode !== undefined) {
|
||||
protoMode.key = keyCode.toString();
|
||||
}
|
||||
|
||||
var mode;
|
||||
switch (d.geometry) {
|
||||
case 'point':
|
||||
case 'vertex':
|
||||
mode = modeAddPoint(context, protoMode);
|
||||
break;
|
||||
case 'line':
|
||||
mode = modeAddLine(context, protoMode);
|
||||
break;
|
||||
case 'area':
|
||||
mode = modeAddArea(context, protoMode);
|
||||
}
|
||||
|
||||
if (mode.key) {
|
||||
context.keybinding().off(mode.key);
|
||||
context.keybinding().on(mode.key, function() {
|
||||
toggleMode(mode);
|
||||
});
|
||||
}
|
||||
|
||||
return mode;
|
||||
});
|
||||
|
||||
var buttons = selection.selectAll('button.add-button')
|
||||
.data(modes, function(d, index) { return d.button + index; });
|
||||
|
||||
// exit
|
||||
buttons.exit()
|
||||
.remove();
|
||||
|
||||
// enter
|
||||
var buttonsEnter = buttons.enter()
|
||||
.append('button')
|
||||
.attr('tabindex', -1)
|
||||
.attr('class', function(d) {
|
||||
return d.button + ' add-button bar-button';
|
||||
})
|
||||
.on('click.mode-buttons', function(d) {
|
||||
|
||||
// When drawing, ignore accidental clicks on mode buttons - #4042
|
||||
if (/^draw/.test(context.mode().id)) return;
|
||||
|
||||
toggleMode(d);
|
||||
})
|
||||
.call(tooltip()
|
||||
.placement('bottom')
|
||||
.html(true)
|
||||
.title(function(d) { return uiTooltipHtml(d.description, d.key); })
|
||||
.scrollContainer(d3_select('#bar'))
|
||||
);
|
||||
|
||||
buttonsEnter
|
||||
.each(function(d) {
|
||||
d3_select(this)
|
||||
.call(uiPresetIcon(context)
|
||||
.geometry((d.geometry === 'point' && !d.preset.matchGeometry(d.geometry)) ? 'vertex' : d.geometry)
|
||||
.preset(d.preset)
|
||||
.sizeClass('small')
|
||||
);
|
||||
});
|
||||
|
||||
var dragOrigin, dragMoved, targetIndex;
|
||||
|
||||
buttonsEnter.call(d3_drag()
|
||||
.on('start', function() {
|
||||
dragOrigin = {
|
||||
x: d3_event.x,
|
||||
y: d3_event.y
|
||||
};
|
||||
targetIndex = null;
|
||||
dragMoved = false;
|
||||
})
|
||||
.on('drag', function(d, index) {
|
||||
dragMoved = true;
|
||||
var x = d3_event.x - dragOrigin.x,
|
||||
y = d3_event.y - dragOrigin.y;
|
||||
|
||||
if (!d3_select(this).classed('dragging') &&
|
||||
// don't display drag until dragging beyond a distance threshold
|
||||
Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) <= 5) return;
|
||||
|
||||
d3_select(this)
|
||||
.classed('dragging', true)
|
||||
.classed('removing', y > 50);
|
||||
|
||||
targetIndex = null;
|
||||
|
||||
selection.selectAll('button.add-preset')
|
||||
.style('transform', function(d2, index2) {
|
||||
var node = d3_select(this).node();
|
||||
if (index === index2) {
|
||||
return 'translate(' + x + 'px, ' + y + 'px)';
|
||||
} else if (y > 50) {
|
||||
if (index2 > index) {
|
||||
return 'translateX(' + (textDirection === 'rtl' ? '' : '-') + '100%)';
|
||||
}
|
||||
} else if (d.source === d2.source) {
|
||||
if (index2 > index && (
|
||||
(d3_event.x > node.offsetLeft && textDirection === 'ltr') ||
|
||||
(d3_event.x < node.offsetLeft + node.offsetWidth && textDirection === 'rtl')
|
||||
)) {
|
||||
if (targetIndex === null || index2 > targetIndex) {
|
||||
targetIndex = index2;
|
||||
}
|
||||
return 'translateX(' + (textDirection === 'rtl' ? '' : '-') + '100%)';
|
||||
} else if (index2 < index && (
|
||||
(d3_event.x < node.offsetLeft + node.offsetWidth && textDirection === 'ltr') ||
|
||||
(d3_event.x > node.offsetLeft && textDirection === 'rtl')
|
||||
)) {
|
||||
if (targetIndex === null || index2 < targetIndex) {
|
||||
targetIndex = index2;
|
||||
}
|
||||
return 'translateX(' + (textDirection === 'rtl' ? '-' : '') + '100%)';
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
})
|
||||
.on('end', function(d, index) {
|
||||
|
||||
if (dragMoved && !d3_select(this).classed('dragging')) {
|
||||
toggleMode(d);
|
||||
return;
|
||||
}
|
||||
|
||||
d3_select(this)
|
||||
.classed('dragging', false)
|
||||
.classed('removing', false);
|
||||
|
||||
selection.selectAll('button.add-preset')
|
||||
.style('transform', null);
|
||||
|
||||
var y = d3_event.y - dragOrigin.y;
|
||||
if (y > 50) {
|
||||
// dragged out of the top bar, remove
|
||||
if (d.isFavorite()) {
|
||||
context.presets().removeFavorite(d.preset, d.geometry);
|
||||
// also remove this as a recent so it doesn't still appear
|
||||
context.presets().removeRecent(d.preset, d.geometry);
|
||||
}
|
||||
} else if (targetIndex !== null) {
|
||||
// dragged to a new position, reorder
|
||||
if (d.isFavorite()) {
|
||||
context.presets().moveFavorite(index, targetIndex);
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
// update
|
||||
buttons = buttons
|
||||
.merge(buttonsEnter)
|
||||
.classed('disabled', function(d) { return !enabled(d); });
|
||||
}
|
||||
};
|
||||
|
||||
tool.uninstall = function() {
|
||||
|
||||
context
|
||||
.on('enter.editor.favorite', null)
|
||||
.on('exit.editor.favorite', null)
|
||||
.on('enter.favorite', null);
|
||||
|
||||
context.presets()
|
||||
.on('favoritePreset.favorite', null)
|
||||
.on('recentsChange.favorite', null);
|
||||
|
||||
context.map()
|
||||
.on('move.favorite', null)
|
||||
.on('drawn.favorite', null);
|
||||
};
|
||||
|
||||
return tool;
|
||||
}
|
||||
@@ -1,336 +0,0 @@
|
||||
import _debounce from 'lodash-es/debounce';
|
||||
|
||||
import { drag as d3_drag } from 'd3-drag';
|
||||
import { event as d3_event, select as d3_select } from 'd3-selection';
|
||||
|
||||
import { modeAddArea, modeAddLine, modeAddPoint, modeBrowse } from '../../modes';
|
||||
import { t, textDirection } from '../../util/locale';
|
||||
import { tooltip } from '../../util/tooltip';
|
||||
import { uiPresetIcon } from '../preset_icon';
|
||||
import { uiTooltipHtml } from '../tooltipHtml';
|
||||
|
||||
|
||||
export function uiToolAddRecent(context) {
|
||||
|
||||
var tool = {
|
||||
id: 'add_recent',
|
||||
klass: 'modes',
|
||||
label: t('toolbar.recent')
|
||||
};
|
||||
|
||||
function enabled() {
|
||||
return osmEditable();
|
||||
}
|
||||
|
||||
function osmEditable() {
|
||||
return context.editable();
|
||||
}
|
||||
|
||||
function toggleMode(d) {
|
||||
if (!enabled(d)) return;
|
||||
|
||||
if (d.button === context.mode().button) {
|
||||
context.enter(modeBrowse(context));
|
||||
} else {
|
||||
if (d.preset &&
|
||||
// don't set a recent as most recent to avoid reordering buttons
|
||||
!d.isRecent()) {
|
||||
context.presets().setMostRecent(d.preset, d.geometry);
|
||||
}
|
||||
context.enter(d);
|
||||
}
|
||||
}
|
||||
|
||||
function recentsToDraw() {
|
||||
var maxShown = 10;
|
||||
var maxRecents = 5;
|
||||
|
||||
var favorites = context.presets().getFavorites().slice(0, maxShown);
|
||||
|
||||
function isAFavorite(recent) {
|
||||
return favorites.some(function(favorite) {
|
||||
return favorite.matches(recent.preset, recent.geometry);
|
||||
});
|
||||
}
|
||||
|
||||
var favoritesCount = favorites.length;
|
||||
maxRecents = Math.min(maxRecents, maxShown - favoritesCount);
|
||||
var items = [];
|
||||
if (maxRecents > 0) {
|
||||
var recents = context.presets().getRecents().filter(function(recent) {
|
||||
return recent.geometry !== 'relation';
|
||||
});
|
||||
for (var i in recents) {
|
||||
var recent = recents[i];
|
||||
if (!isAFavorite(recent)) {
|
||||
items.push(recent);
|
||||
if (items.length === maxRecents) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
tool.shouldShow = function() {
|
||||
return recentsToDraw().length > 0;
|
||||
};
|
||||
|
||||
|
||||
tool.render = function(selection) {
|
||||
context
|
||||
.on('enter.editor.recent', function(entered) {
|
||||
selection.selectAll('button.add-button')
|
||||
.classed('active', function(mode) { return entered.button === mode.button; });
|
||||
context.container()
|
||||
.classed('mode-' + entered.id, true);
|
||||
});
|
||||
|
||||
context
|
||||
.on('exit.editor.recent', function(exited) {
|
||||
context.container()
|
||||
.classed('mode-' + exited.id, false);
|
||||
});
|
||||
|
||||
var debouncedUpdate = _debounce(update, 500, { leading: true, trailing: true });
|
||||
|
||||
context.map()
|
||||
.on('move.recent', debouncedUpdate)
|
||||
.on('drawn.recent', debouncedUpdate);
|
||||
|
||||
context
|
||||
.on('enter.recent', update)
|
||||
.presets()
|
||||
.on('favoritePreset.recent', update)
|
||||
.on('recentsChange.recent', update);
|
||||
|
||||
update();
|
||||
|
||||
|
||||
function update() {
|
||||
|
||||
var items = recentsToDraw();
|
||||
var favoritesCount = context.presets().getFavorites().length;
|
||||
|
||||
var modes = items.map(function(d, index) {
|
||||
var presetName = d.preset.name().split(' – ')[0];
|
||||
var markerClass = 'add-preset add-' + d.geometry + ' add-preset-' + presetName.replace(/\s+/g, '_')
|
||||
+ '-' + d.geometry + ' add-' + d.source; // replace spaces with underscores to avoid css interpretation
|
||||
if (d.preset.isFallback()) {
|
||||
markerClass += ' add-generic-preset';
|
||||
}
|
||||
|
||||
var supportedGeometry = d.preset.geometry.filter(function(geometry) {
|
||||
return ['vertex', 'point', 'line', 'area'].indexOf(geometry) !== -1;
|
||||
});
|
||||
var vertexIndex = supportedGeometry.indexOf('vertex');
|
||||
if (vertexIndex !== -1 && supportedGeometry.indexOf('point') !== -1) {
|
||||
// both point and vertex allowed, just combine them
|
||||
supportedGeometry.splice(vertexIndex, 1);
|
||||
}
|
||||
var tooltipTitleID = 'modes.add_preset.title';
|
||||
if (supportedGeometry.length !== 1) {
|
||||
if (d.preset.setTags({}, d.geometry).building) {
|
||||
tooltipTitleID = 'modes.add_preset.building.title';
|
||||
} else {
|
||||
tooltipTitleID = 'modes.add_preset.' + context.presets().fallback(d.geometry).id + '.title';
|
||||
}
|
||||
}
|
||||
var protoMode = Object.assign({}, d); // shallow copy
|
||||
protoMode.button = markerClass;
|
||||
protoMode.title = presetName;
|
||||
protoMode.description = t(tooltipTitleID, { feature: '<strong>' + presetName + '</strong>' });
|
||||
|
||||
var totalIndex = favoritesCount + index;
|
||||
var keyCode;
|
||||
// use number row order: 1 2 3 4 5 6 7 8 9 0
|
||||
// use the same for RTL even though the layout is backward: #6107
|
||||
if (totalIndex === 9) {
|
||||
keyCode = 0;
|
||||
} else if (totalIndex < 10) {
|
||||
keyCode = totalIndex + 1;
|
||||
}
|
||||
if (keyCode !== undefined) {
|
||||
protoMode.key = keyCode.toString();
|
||||
}
|
||||
|
||||
var mode;
|
||||
switch (d.geometry) {
|
||||
case 'point':
|
||||
case 'vertex':
|
||||
mode = modeAddPoint(context, protoMode);
|
||||
break;
|
||||
case 'line':
|
||||
mode = modeAddLine(context, protoMode);
|
||||
break;
|
||||
case 'area':
|
||||
mode = modeAddArea(context, protoMode);
|
||||
}
|
||||
|
||||
if (mode.key) {
|
||||
context.keybinding().off(mode.key);
|
||||
context.keybinding().on(mode.key, function() {
|
||||
toggleMode(mode);
|
||||
});
|
||||
}
|
||||
|
||||
return mode;
|
||||
});
|
||||
|
||||
var buttons = selection.selectAll('button.add-button')
|
||||
.data(modes, function(d, index) { return d.button + index; });
|
||||
|
||||
// exit
|
||||
buttons.exit()
|
||||
.remove();
|
||||
|
||||
// enter
|
||||
var buttonsEnter = buttons.enter()
|
||||
.append('button')
|
||||
.attr('tabindex', -1)
|
||||
.attr('class', function(d) {
|
||||
return d.button + ' add-button bar-button';
|
||||
})
|
||||
.on('click.mode-buttons', function(d) {
|
||||
|
||||
// When drawing, ignore accidental clicks on mode buttons - #4042
|
||||
if (/^draw/.test(context.mode().id)) return;
|
||||
|
||||
toggleMode(d);
|
||||
})
|
||||
.call(tooltip()
|
||||
.placement('bottom')
|
||||
.html(true)
|
||||
.title(function(d) { return uiTooltipHtml(d.description, d.key); })
|
||||
.scrollContainer(d3_select('#bar'))
|
||||
);
|
||||
|
||||
buttonsEnter
|
||||
.each(function(d) {
|
||||
d3_select(this)
|
||||
.call(uiPresetIcon(context)
|
||||
.geometry((d.geometry === 'point' && !d.preset.matchGeometry(d.geometry)) ? 'vertex' : d.geometry)
|
||||
.preset(d.preset)
|
||||
.sizeClass('small')
|
||||
);
|
||||
});
|
||||
|
||||
var dragOrigin, dragMoved, targetIndex, targetData;
|
||||
|
||||
buttonsEnter.call(d3_drag()
|
||||
.on('start', function() {
|
||||
dragOrigin = {
|
||||
x: d3_event.x,
|
||||
y: d3_event.y
|
||||
};
|
||||
targetIndex = null;
|
||||
targetData = null;
|
||||
dragMoved = false;
|
||||
})
|
||||
.on('drag', function(d, index) {
|
||||
dragMoved = true;
|
||||
var x = d3_event.x - dragOrigin.x,
|
||||
y = d3_event.y - dragOrigin.y;
|
||||
|
||||
if (!d3_select(this).classed('dragging') &&
|
||||
// don't display drag until dragging beyond a distance threshold
|
||||
Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) <= 5) return;
|
||||
|
||||
d3_select(this)
|
||||
.classed('dragging', true)
|
||||
.classed('removing', y > 50);
|
||||
|
||||
targetIndex = null;
|
||||
targetData = null;
|
||||
|
||||
selection.selectAll('button.add-preset')
|
||||
.style('transform', function(d2, index2) {
|
||||
var node = d3_select(this).node();
|
||||
if (index === index2) {
|
||||
return 'translate(' + x + 'px, ' + y + 'px)';
|
||||
} else if (y > 50) {
|
||||
if (index2 > index) {
|
||||
return 'translateX(' + (textDirection === 'rtl' ? '' : '-') + '100%)';
|
||||
}
|
||||
} else if (d.source === d2.source) {
|
||||
if (index2 > index && (
|
||||
(d3_event.x > node.offsetLeft && textDirection === 'ltr') ||
|
||||
(d3_event.x < node.offsetLeft + node.offsetWidth && textDirection === 'rtl')
|
||||
)) {
|
||||
if (targetIndex === null || index2 > targetIndex) {
|
||||
targetIndex = index2;
|
||||
targetData = d2;
|
||||
}
|
||||
return 'translateX(' + (textDirection === 'rtl' ? '' : '-') + '100%)';
|
||||
} else if (index2 < index && (
|
||||
(d3_event.x < node.offsetLeft + node.offsetWidth && textDirection === 'ltr') ||
|
||||
(d3_event.x > node.offsetLeft && textDirection === 'rtl')
|
||||
)) {
|
||||
if (targetIndex === null || index2 < targetIndex) {
|
||||
targetIndex = index2;
|
||||
targetData = d2;
|
||||
}
|
||||
return 'translateX(' + (textDirection === 'rtl' ? '-' : '') + '100%)';
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
})
|
||||
.on('end', function(d) {
|
||||
|
||||
if (dragMoved && !d3_select(this).classed('dragging')) {
|
||||
toggleMode(d);
|
||||
return;
|
||||
}
|
||||
|
||||
d3_select(this)
|
||||
.classed('dragging', false)
|
||||
.classed('removing', false);
|
||||
|
||||
selection.selectAll('button.add-preset')
|
||||
.style('transform', null);
|
||||
|
||||
var y = d3_event.y - dragOrigin.y;
|
||||
if (y > 50) {
|
||||
// dragged out of the top bar, remove
|
||||
if (d.isRecent()) {
|
||||
context.presets().removeRecent(d.preset, d.geometry);
|
||||
}
|
||||
} else if (targetIndex !== null) {
|
||||
// dragged to a new position, reorder
|
||||
if (d.isRecent()) {
|
||||
var item = context.presets().recentMatching(d.preset, d.geometry);
|
||||
var beforeItem = context.presets().recentMatching(targetData.preset, targetData.geometry);
|
||||
context.presets().moveRecent(item, beforeItem);
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
// update
|
||||
buttons = buttons
|
||||
.merge(buttonsEnter)
|
||||
.classed('disabled', function(d) { return !enabled(d); });
|
||||
}
|
||||
};
|
||||
|
||||
tool.uninstall = function() {
|
||||
|
||||
context
|
||||
.on('enter.editor.recent', null)
|
||||
.on('exit.editor.recent', null)
|
||||
.on('enter.recent', null);
|
||||
|
||||
context.presets()
|
||||
.on('favoritePreset.recent', null)
|
||||
.on('recentsChange.recent', null);
|
||||
|
||||
context.map()
|
||||
.on('move.recent', null)
|
||||
.on('drawn.recent', null);
|
||||
};
|
||||
|
||||
return tool;
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
export * from './add_favorite';
|
||||
export * from './add_recent';
|
||||
export * from './modes';
|
||||
export * from './notes';
|
||||
export * from './save';
|
||||
export * from './search_add';
|
||||
export * from './sidebar_toggle';
|
||||
export * from './undo_redo';
|
||||
|
||||
@@ -1,655 +0,0 @@
|
||||
import _debounce from 'lodash-es/debounce';
|
||||
|
||||
import { dispatch as d3_dispatch } from 'd3-dispatch';
|
||||
import {
|
||||
event as d3_event,
|
||||
select as d3_select,
|
||||
selectAll as d3_selectAll
|
||||
} from 'd3-selection';
|
||||
|
||||
import { modeAddArea, modeAddLine, modeAddPoint } from '../../modes';
|
||||
import { t, textDirection } from '../../util/locale';
|
||||
import { svgIcon } from '../../svg/index';
|
||||
import { tooltip } from '../../util/tooltip';
|
||||
import { uiTagReference } from '../tag_reference';
|
||||
import { uiTooltipHtml } from '../tooltipHtml';
|
||||
import { uiPresetFavoriteButton } from '../preset_favorite_button';
|
||||
import { uiPresetIcon } from '../preset_icon';
|
||||
import { utilKeybinding, utilNoAuto, utilRebind } from '../../util';
|
||||
|
||||
|
||||
export function uiToolSearchAdd(context) {
|
||||
|
||||
var tool = {
|
||||
id: 'search_add',
|
||||
label: t('inspector.search')
|
||||
};
|
||||
|
||||
var dispatch = d3_dispatch('choose');
|
||||
var presets;
|
||||
var searchWrap = d3_select(null),
|
||||
search = d3_select(null),
|
||||
popover = d3_select(null),
|
||||
popoverContent = d3_select(null),
|
||||
list = d3_select(null),
|
||||
footer = d3_select(null),
|
||||
message = d3_select(null);
|
||||
|
||||
var allowedGeometry = ['area', 'line', 'point', 'vertex'];
|
||||
var shownGeometry = [];
|
||||
var key = t('modes.add_feature.key');
|
||||
|
||||
function updateShownGeometry(geom) {
|
||||
shownGeometry = geom.sort();
|
||||
presets = context.presets().matchAnyGeometry(shownGeometry);
|
||||
}
|
||||
|
||||
function toggleShownGeometry(d) {
|
||||
var geom = shownGeometry;
|
||||
var index = geom.indexOf(d);
|
||||
if (index === -1) {
|
||||
geom.push(d);
|
||||
if (d === 'point') geom.push('vertex');
|
||||
} else {
|
||||
geom.splice(index, 1);
|
||||
if (d === 'point') geom.splice(geom.indexOf('vertex'), 1);
|
||||
}
|
||||
updateShownGeometry(geom);
|
||||
}
|
||||
|
||||
function updateFilterButtonsStates() {
|
||||
footer.selectAll('button.filter')
|
||||
.classed('active', function(d) {
|
||||
return shownGeometry.indexOf(d) !== -1;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
tool.render = function(selection) {
|
||||
updateShownGeometry(allowedGeometry.slice()); // shallow copy
|
||||
|
||||
searchWrap = selection
|
||||
.append('div')
|
||||
.attr('class', 'search-wrap')
|
||||
.call(tooltip()
|
||||
.placement('bottom')
|
||||
.html(true)
|
||||
.title(function() { return uiTooltipHtml(t('modes.add_feature.description'), key); })
|
||||
.scrollContainer(d3_select('#bar'))
|
||||
);
|
||||
|
||||
search = searchWrap
|
||||
.append('input')
|
||||
.attr('class', 'search-input')
|
||||
.attr('placeholder', t('modes.add_feature.title'))
|
||||
.attr('type', 'search')
|
||||
.call(utilNoAuto)
|
||||
.on('mousedown', function() {
|
||||
search.attr('clicking', true);
|
||||
})
|
||||
.on('mouseup', function() {
|
||||
search.attr('clicking', null);
|
||||
})
|
||||
.on('focus', function() {
|
||||
searchWrap.classed('focused', true);
|
||||
if (search.attr('clicking')) {
|
||||
search.attr('focusing', true);
|
||||
search.attr('clicking', null);
|
||||
} else {
|
||||
search.node().setSelectionRange(0, search.property('value').length);
|
||||
}
|
||||
popover.classed('hide', false);
|
||||
})
|
||||
.on('blur', function() {
|
||||
searchWrap.classed('focused', false);
|
||||
popover.classed('hide', true);
|
||||
})
|
||||
.on('click', function() {
|
||||
if (search.attr('focusing')) {
|
||||
search.node().setSelectionRange(0, search.property('value').length);
|
||||
search.attr('focusing', null);
|
||||
}
|
||||
})
|
||||
.on('keypress', keypress)
|
||||
.on('keydown', keydown)
|
||||
.on('input', updateResultsList);
|
||||
|
||||
searchWrap
|
||||
.call(svgIcon('#iD-icon-search', 'search-icon pre-text'));
|
||||
|
||||
popover = searchWrap
|
||||
.append('div')
|
||||
.attr('class', 'popover fillL hide')
|
||||
.on('mousedown', function() {
|
||||
// don't blur the search input (and thus close results)
|
||||
d3_event.preventDefault();
|
||||
d3_event.stopPropagation();
|
||||
});
|
||||
|
||||
popoverContent = popover
|
||||
.append('div')
|
||||
.attr('class', 'popover-content');
|
||||
|
||||
list = popoverContent.append('div')
|
||||
.attr('class', 'list');
|
||||
|
||||
footer = popover
|
||||
.append('div')
|
||||
.attr('class', 'popover-footer');
|
||||
|
||||
message = footer.append('div')
|
||||
.attr('class', 'message');
|
||||
|
||||
footer.append('div')
|
||||
.attr('class', 'filter-wrap')
|
||||
.selectAll('button.filter')
|
||||
.data(['point', 'line', 'area'])
|
||||
.enter()
|
||||
.append('button')
|
||||
.attr('class', 'filter active')
|
||||
.attr('title', function(d) {
|
||||
return t('modes.add_' + d + '.filter_tooltip');
|
||||
})
|
||||
.each(function(d) {
|
||||
d3_select(this).call(svgIcon('#iD-icon-' + d));
|
||||
})
|
||||
.on('click', function(d) {
|
||||
toggleShownGeometry(d);
|
||||
if (shownGeometry.length === 0) {
|
||||
updateShownGeometry(allowedGeometry.slice()); // shallow copy
|
||||
toggleShownGeometry(d);
|
||||
}
|
||||
updateFilterButtonsStates();
|
||||
updateResultsList();
|
||||
});
|
||||
|
||||
context.features()
|
||||
.on('change.search-add', updateForFeatureHiddenState);
|
||||
|
||||
context.keybinding().on(key, function() {
|
||||
search.node().focus();
|
||||
d3_event.preventDefault();
|
||||
d3_event.stopPropagation();
|
||||
});
|
||||
|
||||
var debouncedUpdate = _debounce(updateEnabledState, 500, { leading: true, trailing: true });
|
||||
|
||||
context.map()
|
||||
.on('move.search-add', debouncedUpdate)
|
||||
.on('drawn.search-add', debouncedUpdate);
|
||||
|
||||
updateEnabledState();
|
||||
|
||||
updateResultsList();
|
||||
};
|
||||
|
||||
tool.uninstall = function() {
|
||||
context.keybinding().off(key);
|
||||
|
||||
context.features()
|
||||
.on('change.search-add', null);
|
||||
|
||||
context.map()
|
||||
.on('move.search-add', null)
|
||||
.on('drawn.search-add', null);
|
||||
};
|
||||
|
||||
function osmEditable() {
|
||||
return context.editable();
|
||||
}
|
||||
|
||||
function updateEnabledState() {
|
||||
var isEnabled = osmEditable();
|
||||
searchWrap.classed('disabled', !isEnabled);
|
||||
if (!isEnabled) {
|
||||
search.node().blur();
|
||||
}
|
||||
search.attr('disabled', isEnabled ? null : true);
|
||||
}
|
||||
|
||||
function keypress() {
|
||||
if (d3_event.keyCode === utilKeybinding.keyCodes.enter) {
|
||||
popover.selectAll('.list .list-item.focused button.choose')
|
||||
.each(function(d) { d.choose.call(this); });
|
||||
d3_event.preventDefault();
|
||||
d3_event.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
function keydown() {
|
||||
|
||||
var nextFocus,
|
||||
priorFocus,
|
||||
parentSubsection;
|
||||
if (d3_event.keyCode === utilKeybinding.keyCodes['↓'] ||
|
||||
d3_event.keyCode === utilKeybinding.keyCodes.tab && !d3_event.shiftKey) {
|
||||
d3_event.preventDefault();
|
||||
d3_event.stopPropagation();
|
||||
|
||||
priorFocus = popover.selectAll('.list .list-item.focused');
|
||||
if (priorFocus.empty()) {
|
||||
nextFocus = popover.selectAll('.list > .list-item:first-child');
|
||||
} else {
|
||||
nextFocus = d3_select(priorFocus.nodes()[0].nextElementSibling);
|
||||
if (!nextFocus.empty() && !nextFocus.classed('list-item')) {
|
||||
nextFocus = nextFocus.selectAll('.list-item:first-child');
|
||||
}
|
||||
if (nextFocus.empty()) {
|
||||
parentSubsection = priorFocus.nodes()[0].closest('.list .subsection');
|
||||
if (parentSubsection && parentSubsection.nextElementSibling) {
|
||||
nextFocus = d3_select(parentSubsection.nextElementSibling);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!nextFocus.empty()) {
|
||||
focusListItem(nextFocus, true);
|
||||
priorFocus.classed('focused', false);
|
||||
}
|
||||
|
||||
} else if (d3_event.keyCode === utilKeybinding.keyCodes['↑'] ||
|
||||
d3_event.keyCode === utilKeybinding.keyCodes.tab && d3_event.shiftKey) {
|
||||
d3_event.preventDefault();
|
||||
d3_event.stopPropagation();
|
||||
|
||||
priorFocus = popover.selectAll('.list .list-item.focused');
|
||||
if (!priorFocus.empty()) {
|
||||
|
||||
nextFocus = d3_select(priorFocus.nodes()[0].previousElementSibling);
|
||||
if (!nextFocus.empty() && !nextFocus.classed('list-item')) {
|
||||
nextFocus = nextFocus.selectAll('.list-item:last-child');
|
||||
}
|
||||
if (nextFocus.empty()) {
|
||||
parentSubsection = priorFocus.nodes()[0].closest('.list .subsection');
|
||||
if (parentSubsection && parentSubsection.previousElementSibling) {
|
||||
nextFocus = d3_select(parentSubsection.previousElementSibling);
|
||||
}
|
||||
}
|
||||
if (!nextFocus.empty()) {
|
||||
focusListItem(nextFocus, true);
|
||||
priorFocus.classed('focused', false);
|
||||
}
|
||||
}
|
||||
} else if (d3_event.keyCode === utilKeybinding.keyCodes.esc) {
|
||||
search.node().blur();
|
||||
d3_event.preventDefault();
|
||||
d3_event.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
function updateResultsList() {
|
||||
|
||||
var value = search.property('value');
|
||||
var results;
|
||||
if (value.length) {
|
||||
results = presets.search(value, shownGeometry).collection;
|
||||
} else {
|
||||
var recents = context.presets().getRecents();
|
||||
recents = recents.filter(function(d) {
|
||||
return shownGeometry.indexOf(d.geometry) !== -1;
|
||||
});
|
||||
results = recents.slice(0, 35);
|
||||
}
|
||||
|
||||
list.call(drawList, results);
|
||||
|
||||
popover.selectAll('.list .list-item.focused')
|
||||
.classed('focused', false);
|
||||
focusListItem(popover.selectAll('.list > .list-item:first-child'), false);
|
||||
|
||||
popoverContent.node().scrollTop = 0;
|
||||
|
||||
var resultCount = results.length;
|
||||
message.text(t('modes.add_feature.' + (resultCount === 1 ? 'result' : 'results'), { count: resultCount }));
|
||||
}
|
||||
|
||||
function focusListItem(selection, scrollingToShow) {
|
||||
if (!selection.empty()) {
|
||||
selection.classed('focused', true);
|
||||
if (scrollingToShow) {
|
||||
// scroll to keep the focused item visible
|
||||
scrollPopoverToShow(selection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function scrollPopoverToShow(selection) {
|
||||
if (selection.empty()) return;
|
||||
|
||||
var node = selection.nodes()[0];
|
||||
var scrollableNode = popoverContent.node();
|
||||
|
||||
if (node.offsetTop < scrollableNode.scrollTop) {
|
||||
scrollableNode.scrollTop = node.offsetTop;
|
||||
|
||||
} else if (node.offsetTop + node.offsetHeight > scrollableNode.scrollTop + scrollableNode.offsetHeight &&
|
||||
node.offsetHeight < scrollableNode.offsetHeight) {
|
||||
scrollableNode.scrollTop = node.offsetTop + node.offsetHeight - scrollableNode.offsetHeight;
|
||||
}
|
||||
}
|
||||
|
||||
function itemForPreset(preset) {
|
||||
if (preset.members) {
|
||||
return CategoryItem(preset);
|
||||
}
|
||||
if (preset.preset && preset.geometry) {
|
||||
return AddablePresetItem(preset.preset, preset.geometry);
|
||||
}
|
||||
var supportedGeometry = preset.geometry.filter(function(geometry) {
|
||||
return shownGeometry.indexOf(geometry) !== -1;
|
||||
}).sort();
|
||||
var vertexIndex = supportedGeometry.indexOf('vertex');
|
||||
if (vertexIndex !== -1 && supportedGeometry.indexOf('point') !== -1) {
|
||||
// both point and vertex allowed, just show point
|
||||
supportedGeometry.splice(vertexIndex, 1);
|
||||
}
|
||||
if (supportedGeometry.length === 1) {
|
||||
return AddablePresetItem(preset, supportedGeometry[0]);
|
||||
}
|
||||
return MultiGeometryPresetItem(preset, supportedGeometry);
|
||||
}
|
||||
|
||||
function drawList(list, data) {
|
||||
|
||||
list.selectAll('.subsection.subitems').remove();
|
||||
|
||||
var dataItems = [];
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var preset = data[i];
|
||||
if (i < data.length - 1) {
|
||||
var nextPreset = data[i+1];
|
||||
// group neighboring presets with the same name
|
||||
if (preset.name && nextPreset.name && preset.name() === nextPreset.name()) {
|
||||
var groupedPresets = [preset, nextPreset].sort(function(p1, p2) {
|
||||
return (p1.geometry[0] < p2.geometry[0]) ? -1 : 1;
|
||||
});
|
||||
dataItems.push(MultiPresetItem(groupedPresets));
|
||||
i++; // skip the next preset since we accounted for it
|
||||
continue;
|
||||
}
|
||||
}
|
||||
dataItems.push(itemForPreset(preset));
|
||||
}
|
||||
|
||||
var items = list.selectAll('.list-item')
|
||||
.data(dataItems, function(d) { return d.id(); });
|
||||
|
||||
items.order();
|
||||
|
||||
items.exit()
|
||||
.remove();
|
||||
|
||||
drawItems(items.enter());
|
||||
|
||||
list.selectAll('.list-item.expanded')
|
||||
.classed('expanded', false)
|
||||
.selectAll('.label svg.icon use')
|
||||
.attr('href', textDirection === 'rtl' ? '#iD-icon-backward' : '#iD-icon-forward');
|
||||
|
||||
updateForFeatureHiddenState();
|
||||
}
|
||||
|
||||
function drawItems(selection) {
|
||||
|
||||
var item = selection
|
||||
.append('div')
|
||||
.attr('class', 'list-item')
|
||||
.attr('id', function(d) {
|
||||
return 'search-add-list-item-preset-' + d.id().replace(/[^a-zA-Z\d:]/g, '-');
|
||||
})
|
||||
.on('mouseover', function() {
|
||||
list.selectAll('.list-item.focused')
|
||||
.classed('focused', false);
|
||||
d3_select(this)
|
||||
.classed('focused', true);
|
||||
})
|
||||
.on('mouseout', function() {
|
||||
d3_select(this)
|
||||
.classed('focused', false);
|
||||
});
|
||||
|
||||
var row = item.append('div')
|
||||
.attr('class', 'row');
|
||||
|
||||
row.append('button')
|
||||
.attr('class', 'choose')
|
||||
.on('click', function(d) {
|
||||
d.choose.call(this);
|
||||
});
|
||||
|
||||
row.each(function(d) {
|
||||
d3_select(this).call(
|
||||
uiPresetIcon(context)
|
||||
.geometry(d.geometry)
|
||||
.preset(d.preset || d.presets[0])
|
||||
.sizeClass('small')
|
||||
);
|
||||
});
|
||||
var label = row.append('div')
|
||||
.attr('class', 'label');
|
||||
|
||||
label.each(function(d) {
|
||||
if (d.subitems) {
|
||||
d3_select(this)
|
||||
.call(svgIcon((textDirection === 'rtl' ? '#iD-icon-backward' : '#iD-icon-forward'), 'inline'));
|
||||
}
|
||||
});
|
||||
|
||||
label.each(function(d) {
|
||||
// NOTE: split/join on en-dash, not a hypen (to avoid conflict with fr - nl names in Brussels etc)
|
||||
d3_select(this)
|
||||
.append('div')
|
||||
.attr('class', 'label-inner')
|
||||
.selectAll('.namepart')
|
||||
.data(d.name().split(' – '))
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'namepart')
|
||||
.text(function(d) { return d; });
|
||||
});
|
||||
|
||||
row.each(function(d) {
|
||||
if (d.geometry) {
|
||||
var presetFavorite = uiPresetFavoriteButton(d.preset, d.geometry, context, 'accessory');
|
||||
d3_select(this).call(presetFavorite.button);
|
||||
}
|
||||
});
|
||||
item.each(function(d) {
|
||||
if ((d.geometry && (!d.isSubitem || d.isInNameGroup)) || d.geometries) {
|
||||
|
||||
var reference = uiTagReference(d.preset.reference(d.geometry || d.geometries[0]), context);
|
||||
|
||||
var thisItem = d3_select(this);
|
||||
thisItem.selectAll('.row').call(reference.button, 'accessory', 'info');
|
||||
|
||||
var subsection = thisItem
|
||||
.append('div')
|
||||
.attr('class', 'subsection reference');
|
||||
subsection.call(reference.body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateForFeatureHiddenState() {
|
||||
|
||||
var listItem = d3_selectAll('.search-add .popover .list-item');
|
||||
|
||||
// remove existing tooltips
|
||||
listItem.selectAll('button.choose').call(tooltip().destroyAny);
|
||||
|
||||
listItem.each(function(item, index) {
|
||||
if (!item.geometry) return;
|
||||
|
||||
var hiddenPresetFeaturesId = context.features().isHiddenPreset(item.preset, item.geometry);
|
||||
var isHiddenPreset = !!hiddenPresetFeaturesId;
|
||||
|
||||
var button = d3_select(this).selectAll('button.choose');
|
||||
|
||||
d3_select(this).classed('disabled', isHiddenPreset);
|
||||
button.classed('disabled', isHiddenPreset);
|
||||
|
||||
if (isHiddenPreset) {
|
||||
var isAutoHidden = context.features().autoHidden(hiddenPresetFeaturesId);
|
||||
var tooltipIdSuffix = isAutoHidden ? 'zoom' : 'manual';
|
||||
var tooltipObj = { features: t('feature.' + hiddenPresetFeaturesId + '.description') };
|
||||
button.call(tooltip('dark')
|
||||
.html(true)
|
||||
.title(t('inspector.hidden_preset.' + tooltipIdSuffix, tooltipObj))
|
||||
.placement(index < 2 ? 'bottom' : 'top')
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function chooseExpandable(item, itemSelection) {
|
||||
|
||||
var shouldExpand = !itemSelection.classed('expanded');
|
||||
|
||||
itemSelection.classed('expanded', shouldExpand);
|
||||
|
||||
var iconName = shouldExpand ?
|
||||
'#iD-icon-down' : (textDirection === 'rtl' ? '#iD-icon-backward' : '#iD-icon-forward');
|
||||
itemSelection.selectAll('.label svg.icon use')
|
||||
.attr('href', iconName);
|
||||
|
||||
if (shouldExpand) {
|
||||
var subitems = item.subitems();
|
||||
var selector = '#' + itemSelection.node().id + ' + *';
|
||||
item.subsection = d3_select(itemSelection.node().parentNode).insert('div', selector)
|
||||
.attr('class', 'subsection subitems');
|
||||
var subitemsEnter = item.subsection.selectAll('.list-item')
|
||||
.data(subitems)
|
||||
.enter();
|
||||
drawItems(subitemsEnter);
|
||||
updateForFeatureHiddenState();
|
||||
scrollPopoverToShow(item.subsection);
|
||||
} else {
|
||||
item.subsection.remove();
|
||||
}
|
||||
}
|
||||
|
||||
function CategoryItem(preset) {
|
||||
var item = {};
|
||||
item.id = function() {
|
||||
return preset.id;
|
||||
};
|
||||
item.name = function() {
|
||||
return preset.name();
|
||||
};
|
||||
item.subsection = d3_select(null);
|
||||
item.preset = preset;
|
||||
item.choose = function() {
|
||||
var selection = d3_select(this);
|
||||
if (selection.classed('disabled')) return;
|
||||
chooseExpandable(item, d3_select(selection.node().closest('.list-item')));
|
||||
};
|
||||
item.subitems = function() {
|
||||
return preset.members.matchAnyGeometry(shownGeometry).collection.map(function(preset) {
|
||||
return itemForPreset(preset);
|
||||
});
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
function MultiPresetItem(presets) {
|
||||
var item = {};
|
||||
item.id = function() {
|
||||
return presets.map(function(preset) { return preset.id; }).join();
|
||||
};
|
||||
item.name = function() {
|
||||
return presets[0].name();
|
||||
};
|
||||
item.subsection = d3_select(null);
|
||||
item.presets = presets;
|
||||
item.choose = function() {
|
||||
var selection = d3_select(this);
|
||||
if (selection.classed('disabled')) return;
|
||||
chooseExpandable(item, d3_select(selection.node().closest('.list-item')));
|
||||
};
|
||||
item.subitems = function() {
|
||||
var items = [];
|
||||
presets.forEach(function(preset) {
|
||||
preset.geometry.filter(function(geometry) {
|
||||
return shownGeometry.indexOf(geometry) !== -1;
|
||||
}).forEach(function(geometry) {
|
||||
items.push(AddablePresetItem(preset, geometry, true, true));
|
||||
});
|
||||
});
|
||||
return items;
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
function MultiGeometryPresetItem(preset, geometries) {
|
||||
|
||||
var item = {};
|
||||
item.id = function() {
|
||||
return preset.id + geometries;
|
||||
};
|
||||
item.name = function() {
|
||||
return preset.name();
|
||||
};
|
||||
item.subsection = d3_select(null);
|
||||
item.preset = preset;
|
||||
item.geometries = geometries;
|
||||
item.choose = function() {
|
||||
var selection = d3_select(this);
|
||||
if (selection.classed('disabled')) return;
|
||||
chooseExpandable(item, d3_select(selection.node().closest('.list-item')));
|
||||
};
|
||||
item.subitems = function() {
|
||||
return geometries.map(function(geometry) {
|
||||
return AddablePresetItem(preset, geometry, true);
|
||||
});
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
function AddablePresetItem(preset, geometry, isSubitem, isInNameGroup) {
|
||||
var item = {};
|
||||
item.id = function() {
|
||||
return preset.id + geometry + isSubitem;
|
||||
};
|
||||
item.name = function() {
|
||||
if (isSubitem) {
|
||||
if (preset.setTags({}, geometry).building) {
|
||||
return t('presets.presets.building.name');
|
||||
}
|
||||
return t('modes.add_' + context.presets().fallback(geometry).id + '.title');
|
||||
}
|
||||
return preset.name();
|
||||
};
|
||||
item.isInNameGroup = isInNameGroup;
|
||||
item.isSubitem = isSubitem;
|
||||
item.preset = preset;
|
||||
item.geometry = geometry;
|
||||
item.choose = function() {
|
||||
if (d3_select(this).classed('disabled')) return;
|
||||
|
||||
var markerClass = 'add-preset add-' + geometry +
|
||||
' add-preset-' + preset.name().replace(/\s+/g, '_') + '-' + geometry;
|
||||
var modeInfo = {
|
||||
button: markerClass,
|
||||
preset: preset,
|
||||
geometry: geometry
|
||||
};
|
||||
var mode;
|
||||
switch (geometry) {
|
||||
case 'point':
|
||||
case 'vertex':
|
||||
mode = modeAddPoint(context, modeInfo);
|
||||
break;
|
||||
case 'line':
|
||||
mode = modeAddLine(context, modeInfo);
|
||||
break;
|
||||
case 'area':
|
||||
mode = modeAddArea(context, modeInfo);
|
||||
}
|
||||
search.node().blur();
|
||||
context.presets().setMostRecent(preset, geometry);
|
||||
context.enter(mode);
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
return utilRebind(tool, dispatch, 'on');
|
||||
}
|
||||
@@ -5,16 +5,13 @@ import {
|
||||
} from 'd3-selection';
|
||||
|
||||
import _debounce from 'lodash-es/debounce';
|
||||
import { /*uiToolAddFavorite, uiToolAddRecent, uiToolSearchAdd, */ uiToolOldDrawModes, uiToolNotes, uiToolSave, uiToolSidebarToggle, uiToolUndoRedo } from './tools';
|
||||
import { uiToolOldDrawModes, uiToolNotes, uiToolSave, uiToolSidebarToggle, uiToolUndoRedo } from './tools';
|
||||
|
||||
|
||||
export function uiTopToolbar(context) {
|
||||
|
||||
var sidebarToggle = uiToolSidebarToggle(context),
|
||||
modes = uiToolOldDrawModes(context),
|
||||
//searchAdd = uiToolSearchAdd(context),
|
||||
//addFavorite = uiToolAddFavorite(context),
|
||||
//addRecent = uiToolAddRecent(context),
|
||||
notes = uiToolNotes(context),
|
||||
undoRedo = uiToolUndoRedo(context),
|
||||
save = uiToolSave(context);
|
||||
@@ -50,16 +47,7 @@ export function uiTopToolbar(context) {
|
||||
sidebarToggle,
|
||||
'spacer',
|
||||
modes
|
||||
// searchAdd
|
||||
];
|
||||
/*
|
||||
if (context.presets().getFavorites().length > 0) {
|
||||
tools.push(addFavorite);
|
||||
}
|
||||
|
||||
if (addRecent.shouldShow()) {
|
||||
tools.push(addRecent);
|
||||
}*/
|
||||
|
||||
tools.push('spacer');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user