Add "pane" prefix to pane UI objects

Move background and overlay layer lists to their own files
This commit is contained in:
Quincy Morgan
2020-02-18 13:33:12 -08:00
parent 5c150718a3
commit d8a0f030cc
11 changed files with 441 additions and 326 deletions
-2
View File
@@ -1,8 +1,6 @@
export { uiInit } from './init';
export { uiAccount } from './account';
export { uiAttribution } from './attribution';
export { uiBackgroundDisplayOptions } from './background_display_options';
export { uiBackgroundOffset } from './background_offset';
export { uiChangesetEditor } from './changeset_editor';
export { uiCmd } from './cmd';
export { uiCombobox } from './combobox';
+10 -10
View File
@@ -37,11 +37,11 @@ import { uiVersion } from './version';
import { uiZoom } from './zoom';
import { uiCmd } from './cmd';
import { uiBackground } from './panes/background';
import { uiHelp } from './panes/help';
import { uiIssues } from './panes/issues';
import { uiMapData } from './panes/map_data';
import { uiPreferences } from './panes/preferences';
import { uiPaneBackground } from './panes/background';
import { uiPaneHelp } from './panes/help';
import { uiPaneIssues } from './panes/issues';
import { uiPaneMapData } from './panes/map_data';
import { uiPanePreferences } from './panes/preferences';
export function uiInit(context) {
var _initCounter = 0;
@@ -107,11 +107,11 @@ export function uiInit(context) {
.call(uiGeolocate(context));
var uiPanes = [
uiBackground(context),
uiMapData(context),
uiIssues(context),
uiPreferences(context),
uiHelp(context)
uiPaneBackground(context),
uiPaneMapData(context),
uiPaneIssues(context),
uiPanePreferences(context),
uiPaneHelp(context)
];
uiPanes.forEach(function(pane) {
+27 -302
View File
@@ -1,304 +1,36 @@
import _debounce from 'lodash-es/debounce';
import { descending as d3_descending, ascending as d3_ascending } from 'd3-array';
import { event as d3_event, select as d3_select } from 'd3-selection';
import { t, textDirection } from '../../util/locale';
import { tooltip } from '../../util/tooltip';
import { svgIcon } from '../../svg/icon';
import { uiBackgroundDisplayOptions } from '../background_display_options';
import { uiBackgroundOffset } from '../background_offset';
import { t } from '../../util/locale';
import { uiCmd } from '../cmd';
import { uiDisclosure } from '../disclosure';
import { uiMapInMap } from '../map_in_map';
import { uiSettingsCustomBackground } from '../settings/custom_background';
import { uiTooltipHtml } from '../tooltipHtml';
import { uiPane } from '../pane';
import { uiBackgroundDisplayOptions } from '../sections/background_display_options';
import { uiBackgroundList } from '../sections/background_list';
import { uiBackgroundOffset } from '../sections/background_offset';
import { uiOverlayList } from '../sections/overlay_list';
export function uiBackground(context) {
export function uiPaneBackground(context) {
var _key = t('background.key');
var _customSource = context.background().findSource('custom');
var _previousBackground = context.background().findSource(context.storage('background-last-used-toggle'));
var _backgroundList = d3_select(null);
var _overlayList = d3_select(null);
var _backgroundListContainer = d3_select(null);
var _overlayListContainer = d3_select(null);
var _displayOptionsContainer = d3_select(null);
var _offsetContainer = d3_select(null);
var backgroundList = uiBackgroundList(context);
var backgroundDisplayOptions = uiBackgroundDisplayOptions(context);
var backgroundOffset = uiBackgroundOffset(context);
var settingsCustomBackground = uiSettingsCustomBackground(context)
.on('change', customChanged);
function setTooltips(selection) {
selection.each(function(d, i, nodes) {
var item = d3_select(this).select('label');
var span = item.select('span');
var placement = (i < nodes.length / 2) ? 'bottom' : 'top';
var description = d.description();
var isOverflowing = (span.property('clientWidth') !== span.property('scrollWidth'));
item.call(tooltip().destroyAny);
if (d === _previousBackground) {
item.call(tooltip()
.placement(placement)
.html(true)
.title(function() {
var tip = '<div>' + t('background.switch') + '</div>';
return uiTooltipHtml(tip, uiCmd('⌘' + _key));
})
);
} else if (description || isOverflowing) {
item.call(tooltip()
.placement(placement)
.title(description || d.name())
);
}
});
}
function updateLayerSelections(selection) {
function active(d) {
return context.background().showsLayer(d);
}
selection.selectAll('li')
.classed('active', active)
.classed('switch', function(d) { return d === _previousBackground; })
.call(setTooltips)
.selectAll('input')
.property('checked', active);
}
function chooseBackground(d) {
if (d.id === 'custom' && !d.template()) {
return editCustom();
}
d3_event.preventDefault();
_previousBackground = context.background().baseLayerSource();
context.storage('background-last-used-toggle', _previousBackground.id);
context.storage('background-last-used', d.id);
context.background().baseLayerSource(d);
_backgroundList.call(updateLayerSelections);
document.activeElement.blur();
}
function customChanged(d) {
if (d && d.template) {
_customSource.template(d.template);
chooseBackground(_customSource);
} else {
_customSource.template('');
chooseBackground(context.background().findSource('none'));
}
}
function editCustom() {
d3_event.preventDefault();
context.container()
.call(settingsCustomBackground);
}
function chooseOverlay(d) {
d3_event.preventDefault();
context.background().toggleOverlayLayer(d);
_overlayList.call(updateLayerSelections);
document.activeElement.blur();
}
function drawListItems(layerList, type, change, filter) {
var sources = context.background()
.sources(context.map().extent(), context.map().zoom(), true)
.filter(filter);
var layerLinks = layerList.selectAll('li')
.data(sources, function(d) { return d.name(); });
layerLinks.exit()
.remove();
var enter = layerLinks.enter()
.append('li')
.classed('layer-custom', function(d) { return d.id === 'custom'; })
.classed('best', function(d) { return d.best(); });
var label = enter
.append('label');
label
.append('input')
.attr('type', type)
.attr('name', 'layers')
.on('change', change);
label
.append('span')
.text(function(d) { return d.name(); });
enter.filter(function(d) { return d.id === 'custom'; })
.append('button')
.attr('class', 'layer-browse')
.call(tooltip()
.title(t('settings.custom_background.tooltip'))
.placement((textDirection === 'rtl') ? 'right' : 'left')
)
.on('click', editCustom)
.call(svgIcon('#iD-icon-more'));
enter.filter(function(d) { return d.best(); })
.append('div')
.attr('class', 'best')
.call(tooltip()
.title(t('background.best_imagery'))
.placement((textDirection === 'rtl') ? 'right' : 'left')
)
.append('span')
.html('&#9733;');
layerList.selectAll('li')
.sort(sortSources);
layerList
.call(updateLayerSelections);
function sortSources(a, b) {
return a.best() && !b.best() ? -1
: b.best() && !a.best() ? 1
: d3_descending(a.area(), b.area()) || d3_ascending(a.name(), b.name()) || 0;
}
}
function renderBackgroundList(selection) {
// the background list
var container = selection.selectAll('.layer-background-list')
.data([0]);
_backgroundList = container.enter()
.append('ul')
.attr('class', 'layer-list layer-background-list')
.attr('dir', 'auto')
.merge(container);
// add minimap toggle below list
var bgExtrasListEnter = selection.selectAll('.bg-extras-list')
.data([0])
.enter()
.append('ul')
.attr('class', 'layer-list bg-extras-list');
var minimapLabelEnter = bgExtrasListEnter
.append('li')
.attr('class', 'minimap-toggle-item')
.append('label')
.call(tooltip()
.html(true)
.title(uiTooltipHtml(t('background.minimap.tooltip'), t('background.minimap.key')))
.placement('top')
);
minimapLabelEnter
.append('input')
.attr('type', 'checkbox')
.on('change', function() {
d3_event.preventDefault();
uiMapInMap.toggle();
});
minimapLabelEnter
.append('span')
.text(t('background.minimap.description'));
var panelLabelEnter = bgExtrasListEnter
.append('li')
.attr('class', 'background-panel-toggle-item')
.append('label')
.call(tooltip()
.html(true)
.title(uiTooltipHtml(t('background.panel.tooltip'), uiCmd('⌘⇧' + t('info_panels.background.key'))))
.placement('top')
);
panelLabelEnter
.append('input')
.attr('type', 'checkbox')
.on('change', function() {
d3_event.preventDefault();
context.ui().info.toggle('background');
});
panelLabelEnter
.append('span')
.text(t('background.panel.description'));
// "Info / Report a Problem" link
selection.selectAll('.imagery-faq')
.data([0])
.enter()
.append('div')
.attr('class', 'imagery-faq')
.append('a')
.attr('target', '_blank')
.call(svgIcon('#iD-icon-out-link', 'inline'))
.attr('href', 'https://github.com/openstreetmap/iD/blob/master/FAQ.md#how-can-i-report-an-issue-with-background-imagery')
.append('span')
.text(t('background.imagery_problem_faq'));
updateBackgroundList();
}
function renderOverlayList(selection) {
var container = selection.selectAll('.layer-overlay-list')
.data([0]);
_overlayList = container.enter()
.append('ul')
.attr('class', 'layer-list layer-overlay-list')
.attr('dir', 'auto')
.merge(container);
updateOverlayList();
}
function updateBackgroundList() {
_backgroundList
.call(drawListItems, 'radio', chooseBackground, function(d) { return !d.isHidden() && !d.overlay; });
}
function updateOverlayList() {
_overlayList
.call(drawListItems, 'checkbox', chooseOverlay, function(d) { return !d.isHidden() && d.overlay; });
}
var overlayList = uiOverlayList(context);
function update() {
if (!backgroundPane.selection().select('.disclosure-wrap-background_list').classed('hide')) {
updateBackgroundList();
}
_backgroundListContainer
.call(backgroundList);
if (!backgroundPane.selection().select('.disclosure-wrap-overlay_list').classed('hide')) {
updateOverlayList();
}
_overlayListContainer
.call(overlayList);
_displayOptionsContainer
.call(backgroundDisplayOptions);
@@ -307,18 +39,21 @@ export function uiBackground(context) {
.call(backgroundOffset);
}
function quickSwitch() {
if (d3_event) {
d3_event.stopImmediatePropagation();
d3_event.preventDefault();
}
if (_previousBackground) {
chooseBackground(_previousBackground);
var previousBackground = context.background().findSource(context.storage('background-last-used-toggle'));
if (previousBackground) {
var newPreviousBackground = context.background().baseLayerSource();
context.storage('background-last-used-toggle', newPreviousBackground.id);
context.storage('background-last-used', previousBackground.id);
context.background().baseLayerSource(previousBackground);
document.activeElement.blur();
}
}
var backgroundPane = uiPane('background', context)
.key(_key)
.title(t('background.title'))
@@ -328,22 +63,14 @@ export function uiBackground(context) {
backgroundPane.renderContent = function(content) {
// background list
content
_backgroundListContainer = content
.append('div')
.attr('class', 'background-background-list-container')
.call(uiDisclosure(context, 'background_list', true)
.title(t('background.backgrounds'))
.content(renderBackgroundList)
);
.attr('class', 'background-background-list-container');
// overlay list
content
_overlayListContainer = content
.append('div')
.attr('class', 'background-overlay-list-container')
.call(uiDisclosure(context, 'overlay_list', true)
.title(t('background.overlays'))
.content(renderOverlayList)
);
.attr('class', 'background-overlay-list-container');
// display options
_displayOptionsContainer = content
@@ -355,6 +82,8 @@ export function uiBackground(context) {
.append('div')
.attr('class', 'background-offset');
update();
// add listeners
context.map()
@@ -362,13 +91,9 @@ export function uiBackground(context) {
_debounce(function() { window.requestIdleCallback(update); }, 1000)
);
context.background()
.on('change.background-update', update);
update();
context.keybinding()
.on(uiCmd('⌘' + _key), quickSwitch);
};
+1 -1
View File
@@ -11,7 +11,7 @@ import { t, textDirection } from '../../util/locale';
import { tooltip } from '../../util/tooltip';
import { icon } from '../intro/helper';
export function uiHelp(context) {
export function uiPaneHelp(context) {
var docKeys = [
['help', [
+1 -1
View File
@@ -13,7 +13,7 @@ import { utilGetSetValue, utilHighlightEntities, utilNoAuto } from '../../util';
import { uiPane } from '../pane';
export function uiIssues(context) {
export function uiPaneIssues(context) {
var MINSQUARE = 0;
var MAXSQUARE = 20;
+1 -1
View File
@@ -15,7 +15,7 @@ import { uiCmd } from '../cmd';
import { uiPane } from '../pane';
export function uiMapData(context) {
export function uiPaneMapData(context) {
var osmDataToggleKey = uiCmd('⌥' + t('area_fill.wireframe.key'));
var features = context.features().keys();
var layers = context.layers();
+1 -1
View File
@@ -7,7 +7,7 @@ import { uiDisclosure } from '../disclosure';
import { uiPane } from '../pane';
export function uiPreferences(context) {
export function uiPanePreferences(context) {
let _showThirdPartyIcons = context.storage('preferences.privacy.thirdpartyicons') || 'true';
function renderPrivacyOptions(selection) {
@@ -3,10 +3,10 @@ import {
select as d3_select
} from 'd3-selection';
import { t, textDirection } from '../util/locale';
import { svgIcon } from '../svg/icon';
import { uiDisclosure } from './disclosure';
import { utilDetect } from '../util/detect';
import { t, textDirection } from '../../util/locale';
import { svgIcon } from '../../svg/icon';
import { uiDisclosure } from '../disclosure';
import { utilDetect } from '../../util/detect';
export function uiBackgroundDisplayOptions(context) {
+268
View File
@@ -0,0 +1,268 @@
import { descending as d3_descending, ascending as d3_ascending } from 'd3-array';
import {
event as d3_event,
select as d3_select
} from 'd3-selection';
import { t, textDirection } from '../../util/locale';
import { tooltip } from '../../util/tooltip';
import { svgIcon } from '../../svg/icon';
import { uiCmd } from '../cmd';
import { uiDisclosure } from '../disclosure';
import { uiSettingsCustomBackground } from '../settings/custom_background';
import { uiMapInMap } from '../map_in_map';
import { uiTooltipHtml } from '../tooltipHtml';
export function uiBackgroundList(context) {
var _backgroundList = d3_select(null);
var _customSource = context.background().findSource('custom');
var settingsCustomBackground = uiSettingsCustomBackground(context)
.on('change', customChanged);
function previousBackgroundID() {
return context.storage('background-last-used-toggle');
}
function render(selection) {
// the background list
var container = selection.selectAll('.layer-background-list')
.data([0]);
_backgroundList = container.enter()
.append('ul')
.attr('class', 'layer-list layer-background-list')
.attr('dir', 'auto')
.merge(container);
// add minimap toggle below list
var bgExtrasListEnter = selection.selectAll('.bg-extras-list')
.data([0])
.enter()
.append('ul')
.attr('class', 'layer-list bg-extras-list');
var minimapLabelEnter = bgExtrasListEnter
.append('li')
.attr('class', 'minimap-toggle-item')
.append('label')
.call(tooltip()
.html(true)
.title(uiTooltipHtml(t('background.minimap.tooltip'), t('background.minimap.key')))
.placement('top')
);
minimapLabelEnter
.append('input')
.attr('type', 'checkbox')
.on('change', function() {
d3_event.preventDefault();
uiMapInMap.toggle();
});
minimapLabelEnter
.append('span')
.text(t('background.minimap.description'));
var panelLabelEnter = bgExtrasListEnter
.append('li')
.attr('class', 'background-panel-toggle-item')
.append('label')
.call(tooltip()
.html(true)
.title(uiTooltipHtml(t('background.panel.tooltip'), uiCmd('⌘⇧' + t('info_panels.background.key'))))
.placement('top')
);
panelLabelEnter
.append('input')
.attr('type', 'checkbox')
.on('change', function() {
d3_event.preventDefault();
context.ui().info.toggle('background');
});
panelLabelEnter
.append('span')
.text(t('background.panel.description'));
// "Info / Report a Problem" link
selection.selectAll('.imagery-faq')
.data([0])
.enter()
.append('div')
.attr('class', 'imagery-faq')
.append('a')
.attr('target', '_blank')
.call(svgIcon('#iD-icon-out-link', 'inline'))
.attr('href', 'https://github.com/openstreetmap/iD/blob/master/FAQ.md#how-can-i-report-an-issue-with-background-imagery')
.append('span')
.text(t('background.imagery_problem_faq'));
updateBackgroundList();
}
function setTooltips(selection) {
selection.each(function(d, i, nodes) {
var item = d3_select(this).select('label');
var span = item.select('span');
var placement = (i < nodes.length / 2) ? 'bottom' : 'top';
var description = d.description();
var isOverflowing = (span.property('clientWidth') !== span.property('scrollWidth'));
item.call(tooltip().destroyAny);
if (d.id === previousBackgroundID()) {
item.call(tooltip()
.placement(placement)
.html(true)
.title(function() {
var tip = '<div>' + t('background.switch') + '</div>';
return uiTooltipHtml(tip, uiCmd('⌘' + t('background.key')));
})
);
} else if (description || isOverflowing) {
item.call(tooltip()
.placement(placement)
.title(description || d.name())
);
}
});
}
function updateBackgroundList() {
_backgroundList
.call(drawListItems, 'radio', chooseBackground, function(d) { return !d.isHidden() && !d.overlay; });
}
function drawListItems(layerList, type, change, filter) {
var sources = context.background()
.sources(context.map().extent(), context.map().zoom(), true)
.filter(filter);
var layerLinks = layerList.selectAll('li')
.data(sources, function(d) { return d.name(); });
layerLinks.exit()
.remove();
var enter = layerLinks.enter()
.append('li')
.classed('layer-custom', function(d) { return d.id === 'custom'; })
.classed('best', function(d) { return d.best(); });
var label = enter
.append('label');
label
.append('input')
.attr('type', type)
.attr('name', 'layers')
.on('change', change);
label
.append('span')
.text(function(d) { return d.name(); });
enter.filter(function(d) { return d.id === 'custom'; })
.append('button')
.attr('class', 'layer-browse')
.call(tooltip()
.title(t('settings.custom_background.tooltip'))
.placement((textDirection === 'rtl') ? 'right' : 'left')
)
.on('click', editCustom)
.call(svgIcon('#iD-icon-more'));
enter.filter(function(d) { return d.best(); })
.append('div')
.attr('class', 'best')
.call(tooltip()
.title(t('background.best_imagery'))
.placement((textDirection === 'rtl') ? 'right' : 'left')
)
.append('span')
.html('&#9733;');
layerList.selectAll('li')
.sort(sortSources);
layerList
.call(updateLayerSelections);
function sortSources(a, b) {
return a.best() && !b.best() ? -1
: b.best() && !a.best() ? 1
: d3_descending(a.area(), b.area()) || d3_ascending(a.name(), b.name()) || 0;
}
}
function updateLayerSelections(selection) {
function active(d) {
return context.background().showsLayer(d);
}
selection.selectAll('li')
.classed('active', active)
.classed('switch', function(d) { return d.id === previousBackgroundID(); })
.call(setTooltips)
.selectAll('input')
.property('checked', active);
}
function chooseBackground(d) {
if (d.id === 'custom' && !d.template()) {
return editCustom();
}
d3_event.preventDefault();
var previousBackground = context.background().baseLayerSource();
context.storage('background-last-used-toggle', previousBackground.id);
context.storage('background-last-used', d.id);
context.background().baseLayerSource(d);
document.activeElement.blur();
}
function customChanged(d) {
if (d && d.template) {
_customSource.template(d.template);
chooseBackground(_customSource);
} else {
_customSource.template('');
chooseBackground(context.background().findSource('none'));
}
}
function editCustom() {
d3_event.preventDefault();
context.container()
.call(settingsCustomBackground);
}
function backgroundList(selection) {
selection
.call(uiDisclosure(context, 'background_list', true)
.title(t('background.backgrounds'))
.content(render)
);
}
context.background()
.on('change.background_list', function() {
_backgroundList.call(updateLayerSelections);
});
return backgroundList;
}
@@ -4,10 +4,10 @@ import {
selectAll as d3_selectAll
} from 'd3-selection';
import { t, textDirection } from '../util/locale';
import { geoMetersToOffset, geoOffsetToMeters } from '../geo';
import { svgIcon } from '../svg/icon';
import { uiDisclosure } from './disclosure';
import { t, textDirection } from '../../util/locale';
import { geoMetersToOffset, geoOffsetToMeters } from '../../geo';
import { svgIcon } from '../../svg/icon';
import { uiDisclosure } from '../disclosure';
export function uiBackgroundOffset(context) {
+124
View File
@@ -0,0 +1,124 @@
import { descending as d3_descending, ascending as d3_ascending } from 'd3-array';
import {
event as d3_event,
select as d3_select
} from 'd3-selection';
import { t } from '../../util/locale';
import { tooltip } from '../../util/tooltip';
import { uiDisclosure } from '../disclosure';
export function uiOverlayList(context) {
var _overlayList = d3_select(null);
function render(selection) {
var container = selection.selectAll('.layer-overlay-list')
.data([0]);
_overlayList = container.enter()
.append('ul')
.attr('class', 'layer-list layer-overlay-list')
.attr('dir', 'auto')
.merge(container);
updateOverlayList();
}
function setTooltips(selection) {
selection.each(function(d, i, nodes) {
var item = d3_select(this).select('label');
var span = item.select('span');
var placement = (i < nodes.length / 2) ? 'bottom' : 'top';
var description = d.description();
var isOverflowing = (span.property('clientWidth') !== span.property('scrollWidth'));
item.call(tooltip().destroyAny);
if (description || isOverflowing) {
item.call(tooltip()
.placement(placement)
.title(description || d.name())
);
}
});
}
function updateLayerSelections(selection) {
function active(d) {
return context.background().showsLayer(d);
}
selection.selectAll('li')
.classed('active', active)
.call(setTooltips)
.selectAll('input')
.property('checked', active);
}
function chooseOverlay(d) {
d3_event.preventDefault();
context.background().toggleOverlayLayer(d);
_overlayList.call(updateLayerSelections);
document.activeElement.blur();
}
function drawListItems(layerList, type, change, filter) {
var sources = context.background()
.sources(context.map().extent(), context.map().zoom(), true)
.filter(filter);
var layerLinks = layerList.selectAll('li')
.data(sources, function(d) { return d.name(); });
layerLinks.exit()
.remove();
var enter = layerLinks.enter()
.append('li');
var label = enter
.append('label');
label
.append('input')
.attr('type', type)
.attr('name', 'layers')
.on('change', change);
label
.append('span')
.text(function(d) { return d.name(); });
layerList.selectAll('li')
.sort(sortSources);
layerList
.call(updateLayerSelections);
function sortSources(a, b) {
return a.best() && !b.best() ? -1
: b.best() && !a.best() ? 1
: d3_descending(a.area(), b.area()) || d3_ascending(a.name(), b.name()) || 0;
}
}
function updateOverlayList() {
_overlayList
.call(drawListItems, 'checkbox', chooseOverlay, function(d) { return !d.isHidden() && d.overlay; });
}
function overlayList(selection) {
selection
.call(uiDisclosure(context, 'overlay_list', true)
.title(t('background.overlays'))
.content(render)
);
}
return overlayList;
}