Convert Tail to a behavior

This avoids an extra mousemove listener in base modes.
This commit is contained in:
John Firebaugh
2013-05-14 17:49:13 -07:00
parent 5b69387ea0
commit d238e4eaeb
14 changed files with 121 additions and 108 deletions

View File

@@ -94,7 +94,6 @@
<script src='js/id/ui/taglist.js'></script>
<script src='js/id/ui/preset_grid.js'></script>
<script src='js/id/ui/tag_editor.js'></script>
<script src='js/id/ui/tail.js'></script>
<script src='js/id/ui/preset/access.js'></script>
<script src='js/id/ui/preset/address.js'></script>
@@ -147,6 +146,7 @@
<script src='js/id/behavior/hash.js'></script>
<script src='js/id/behavior/hover.js'></script>
<script src='js/id/behavior/select.js'></script>
<script src='js/id/behavior/tail.js'></script>
<script src='js/id/modes.js'></script>
<script src='js/id/modes/add_area.js'></script>

View File

@@ -18,14 +18,12 @@ iD.behavior.AddWay = function(context) {
addWay.off = function(surface) {
context.map()
.minzoom(0)
.tail(false);
.minzoom(0);
surface.call(draw.off);
};
addWay.cancel = function() {
window.setTimeout(function() {
context.map().dblclickEnable(true);
}, 1000);
@@ -33,5 +31,10 @@ iD.behavior.AddWay = function(context) {
context.enter(iD.modes.Browse(context));
};
addWay.tail = function(text) {
draw.tail(text);
return addWay;
};
return d3.rebind(addWay, event, 'on');
};

View File

@@ -3,6 +3,7 @@ iD.behavior.Draw = function(context) {
'clickNode', 'undo', 'cancel', 'finish'),
keybinding = d3.keybinding('draw'),
hover = iD.behavior.Hover().altDisables(true),
tail = iD.behavior.Tail(),
closeTolerance = 4,
tolerance = 12;
@@ -87,6 +88,7 @@ iD.behavior.Draw = function(context) {
function draw(selection) {
context.install(hover);
context.install(tail);
keybinding
.on('⌫', backspace)
@@ -106,6 +108,7 @@ iD.behavior.Draw = function(context) {
draw.off = function(selection) {
context.uninstall(hover);
context.uninstall(tail);
selection
.on('mousedown.draw', null)
@@ -118,5 +121,15 @@ iD.behavior.Draw = function(context) {
.call(keybinding.off);
};
draw.tail = function(_) {
if (!_ || iD.behavior.Draw.usedTails[_] === undefined) {
tail.text(_);
iD.behavior.Draw.usedTails[_] = true;
}
return draw;
};
return d3.rebind(draw, event, 'on');
};
iD.behavior.Draw.usedTails = {};

View File

@@ -78,7 +78,6 @@ iD.behavior.DrawWay = function(context, wayId, index, mode, baseGraph) {
context.map()
.minzoom(0)
.tail(false)
.on('drawn.draw', null);
surface.call(draw.off)
@@ -192,5 +191,10 @@ iD.behavior.DrawWay = function(context, wayId, index, mode, baseGraph) {
context.enter(iD.modes.Browse(context));
};
drawWay.tail = function(text) {
draw.tail(text);
return drawWay;
};
return drawWay;
};

85
js/id/behavior/tail.js Normal file
View File

@@ -0,0 +1,85 @@
iD.behavior.Tail = function() {
var text,
container,
xmargin = 25,
tooltip_size = [0, 0],
selection_size = [0, 0],
transformProp = iD.util.prefixCSSProperty('Transform');
function tail(selection) {
if (!text) return;
d3.select(window)
.on('resize.tail', function() { selection_size = selection.size(); });
function show() {
container.style('display', 'block');
tooltip_size = container.size();
}
function mousemove() {
if (container.style('display') === 'none') show();
var xoffset = ((d3.event.clientX + tooltip_size[0] + xmargin) > selection_size[0]) ?
-tooltip_size[0] - xmargin : xmargin;
container.classed('left', xoffset > 0);
container.style(transformProp, 'translate(' +
(~~d3.event.clientX + xoffset) + 'px,' +
~~d3.event.clientY + 'px)');
}
function mouseout() {
if (d3.event.relatedTarget !== container.node()) {
container.style('display', 'none');
}
}
function mouseover() {
if (d3.event.relatedTarget !== container.node()) {
show();
}
}
container = d3.select(document.body)
.append('div')
.style('display', 'none')
.attr('class', 'tail tooltip-inner');
container.append('div')
.text(text);
selection
.on('mousemove.tail', mousemove)
.on('mouseover.tail', mouseover)
.on('mouseout.tail', mouseout);
container
.on('mousemove.tail', mousemove);
tooltip_size = container.size();
selection_size = selection.size();
}
tail.off = function(selection) {
if (!text) return;
container
.on('mousemove.tail', null)
.remove();
selection
.on('mousemove.tail', null)
.on('mouseover.tail', null)
.on('mouseout.tail', null);
d3.select(window)
.on('resize.tail', null);
};
tail.text = function(_) {
if (!arguments.length) return text;
text = _;
return tail;
};
return tail;
};

View File

@@ -140,7 +140,6 @@ window.iD = function () {
context.surface = function() { return map.surface; };
context.mouse = map.mouse;
context.projection = map.projection;
context.tail = map.tail;
context.redraw = map.redraw;
context.pan = map.pan;
context.zoomIn = map.zoomIn;

View File

@@ -8,6 +8,7 @@ iD.modes.AddArea = function(context) {
};
var behavior = iD.behavior.AddWay(context)
.tail(t('modes.add_area.tail'))
.on('start', start)
.on('startFromWay', startFromWay)
.on('startFromNode', startFromNode),
@@ -56,7 +57,6 @@ iD.modes.AddArea = function(context) {
mode.enter = function() {
context.install(behavior);
context.tail(t('modes.add_area.tail'));
};
mode.exit = function() {

View File

@@ -8,9 +8,10 @@ iD.modes.AddLine = function(context) {
};
var behavior = iD.behavior.AddWay(context)
.on('start', start)
.on('startFromWay', startFromWay)
.on('startFromNode', startFromNode);
.tail(t('modes.add_line.tail'))
.on('start', start)
.on('startFromWay', startFromWay)
.on('startFromNode', startFromNode);
function start(loc) {
var graph = context.graph(),
@@ -63,7 +64,6 @@ iD.modes.AddLine = function(context) {
mode.enter = function() {
context.install(behavior);
context.tail(t('modes.add_line.tail'));
};
mode.exit = function() {

View File

@@ -7,6 +7,7 @@ iD.modes.AddPoint = function(context) {
};
var behavior = iD.behavior.Draw(context)
.tail(t('modes.add_point.tail'))
.on('click', add)
.on('clickWay', addWay)
.on('clickNode', addNode)
@@ -40,12 +41,10 @@ iD.modes.AddPoint = function(context) {
mode.enter = function() {
context.install(behavior);
context.tail(t('modes.add_point.tail'));
};
mode.exit = function() {
context.uninstall(behavior);
context.tail(false);
};
return mode;

View File

@@ -11,7 +11,8 @@ iD.modes.DrawArea = function(context, wayId, baseGraph) {
headId = way.nodes[way.nodes.length - 2],
tailId = way.first();
behavior = iD.behavior.DrawWay(context, wayId, -1, mode, baseGraph);
behavior = iD.behavior.DrawWay(context, wayId, -1, mode, baseGraph)
.tail(t('modes.draw_area.tail'));
var addNode = behavior.addNode;
@@ -24,7 +25,6 @@ iD.modes.DrawArea = function(context, wayId, baseGraph) {
};
context.install(behavior);
context.tail(t('modes.draw_area.tail'));
};
mode.exit = function() {

View File

@@ -11,7 +11,8 @@ iD.modes.DrawLine = function(context, wayId, direction, baseGraph) {
index = (direction === 'forward') ? undefined : 0,
headId = (direction === 'forward') ? way.last() : way.first();
behavior = iD.behavior.DrawWay(context, wayId, index, mode, baseGraph);
behavior = iD.behavior.DrawWay(context, wayId, index, mode, baseGraph)
.tail(t('modes.draw_line.tail'));
var addNode = behavior.addNode;
@@ -24,7 +25,6 @@ iD.modes.DrawLine = function(context, wayId, direction, baseGraph) {
};
context.install(behavior);
context.tail(t('modes.draw_line.tail'));
};
mode.exit = function() {

View File

@@ -24,7 +24,6 @@ iD.Map = function(context) {
areas = iD.svg.Areas(roundedProjection),
midpoints = iD.svg.Midpoints(roundedProjection, context),
labels = iD.svg.Labels(roundedProjection, context),
tail = iD.ui.Tail(),
supersurface, surface,
mouse;
@@ -91,9 +90,6 @@ iD.Map = function(context) {
labels.supersurface(supersurface);
mouse = iD.util.fastMouse(supersurface.node());
supersurface
.call(tail);
}
function pxCenter() { return [dimensions[0] / 2, dimensions[1] / 2]; }
@@ -421,15 +417,6 @@ iD.Map = function(context) {
return map;
};
var usedTails = {};
map.tail = function(_) {
if (!_ || usedTails[_] === undefined) {
tail.text(_);
usedTails[_] = true;
}
return map;
};
map.editable = function() {
return map.zoom() >= 16;
};

View File

@@ -1,77 +0,0 @@
iD.ui.Tail = function() {
var text = false,
container,
inner,
xmargin = 25,
tooltip_size = [0, 0],
selection_size = [0, 0],
transformProp = iD.util.prefixCSSProperty('Transform');
function tail(selection) {
d3.select(window).on('resize.tail-size', function() {
selection_size = selection.size();
});
function setup() {
container = d3.select(document.body)
.append('div')
.style('display', 'none')
.attr('class', 'tail tooltip-inner');
inner = container.append('div');
selection
.on('mousemove.tail', mousemove)
.on('mouseover.tail', mouseover)
.on('mouseout.tail', mouseout);
container
.on('mousemove.tail', mousemove);
selection_size = selection.size();
}
function show() {
container.style('display', 'block');
tooltip_size = container.size();
}
function mousemove() {
if (text === false) return;
if (container.style('display') === 'none') show();
var xoffset = ((d3.event.clientX + tooltip_size[0] + xmargin) > selection_size[0]) ?
-tooltip_size[0] - xmargin : xmargin;
container.classed('left', xoffset > 0);
container.style(transformProp, 'translate(' +
(~~d3.event.clientX + xoffset) + 'px,' +
~~d3.event.clientY + 'px)');
}
function mouseout() {
if (d3.event.relatedTarget !== container.node() &&
text !== false) container.style('display', 'none');
}
function mouseover() {
if (d3.event.relatedTarget !== container.node() &&
text !== false) show();
}
if (!container) setup();
}
tail.text = function(_) {
if (!arguments.length) return text;
if (_ === false) {
text = _;
container.style('display', 'none');
return tail;
}
text = _;
inner.text(text);
tooltip_size = container.size();
return tail;
};
return tail;
};

View File

@@ -91,7 +91,6 @@
<script src='../js/id/ui/taglist.js'></script>
<script src='../js/id/ui/preset_grid.js'></script>
<script src='../js/id/ui/tag_editor.js'></script>
<script src='../js/id/ui/tail.js'></script>
<script src='../js/id/ui/preset/access.js'></script>
<script src='../js/id/ui/preset/address.js'></script>
@@ -131,6 +130,7 @@
<script src='../js/id/behavior/hover.js'></script>
<script src='../js/id/behavior/lasso.js'></script>
<script src='../js/id/behavior/select.js'></script>
<script src='../js/id/behavior/tail.js'></script>
<script src='../js/id/modes.js'></script>
<script src='../js/id/modes/add_area.js'></script>