Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Edit annotations #769

Merged
merged 4 commits into from
Feb 20, 2018
Merged

Edit annotations #769

merged 4 commits into from
Feb 20, 2018

Conversation

manthey
Copy link
Contributor

@manthey manthey commented Jan 25, 2018

When enabled, hovering over an annotation will highlight it. Clicking on the annotation will place it in edit mode. Dragging the edit handles will alter the annotation. Escape or clicking outside of edit handles will exit from edit mode.

This PR can stand on its own, but there are a number of future improvements that are desired:

  • escape should revert the edit rather than just exit edit mode (and enter should exit edit mode, keeping the edit)
  • tab should switch between annotations; when an annotation is selected via the enter key, tab would switch between edit handles.
  • edit handles should be adjustable with the arrow keys
  • meta keys (shift, ctrl) should affect how moving edit handles is controlled (for instance, shift might constrain a rectangle's aspect ratio, or ensure 90 degree rotations). I'm not sure of the specifics.
  • the edit handles should be fancier than just points. I'd rather see squares on the vertices, a curved double-headed arrow on the rotation handle, and a double-headed arrow on the resize handle. This would benefit from a more generic marker option for points.
  • we should test with a touch device.
  • for lines, the ability to break or join a line could be disabled.
  • There could be other constraints, too, like discrete rotations or scales.

@manthey
Copy link
Contributor Author

manthey commented Jan 25, 2018

Note that this depends on a number of other PRs and has them as commits (#761, #763, #764, #767, #768). It could be rebased as those get merged in.

@manthey
Copy link
Contributor Author

manthey commented Jan 25, 2018

Resolves #630.

@aashish24
Copy link
Member

@manthey this will take some time to review but overall the feature is great!

@manthey
Copy link
Contributor Author

manthey commented Feb 7, 2018

Now that all relevant previous PRs are merged to master, I've rebased this to resolve merge conflicts.

When enabled, hovering over an annotation will highlight it.  Clicking
on the annotation will place it in edit mode.  Dragging the edit handles
will alter the annotation.  Escape or clicking outside of edit handles
will exit from edit mode.

This PR can stand on its own, but there are a number of future
improvements that are desired:
- escape should revert the edit rather than just exit edit mode (and
  enter should exit edit mode, keeping the edit)
- tab should switch between annotations; when an annotation is selected
  via the enter key, tab would switch between edit handles.
- edit handles should be adjustable with the arrow keys
- meta keys (shift, ctrl) should affect how moving edit handles is
  controlled (for instance, shift might constrain a rectangle's aspect
  ratio, or ensure 90 degree rotations).  I'm not sure of the specifics.
- the edit handles should be fancier than just points.  I'd rather see
  squares on the vertices, a curved double-headed arrow on the rotation
  handle, and a double-headed arrow on the resize handle.  This would
  benefit from a more generic marker option for points.
- we should test with a touch device.
- for lines, the ability to break or join a line could be disabled.
- There could be other constraints, too, like discrete rotations or
  scales.
@@ -127,7 +131,14 @@ var annotationLayer = function (args) {
if (evt.state && evt.state.actionRecord &&
evt.state.actionRecord.owner === geo_annotation.actionOwner &&
m_this.currentAnnotation) {
update = m_this.currentAnnotation.processAction(evt);
switch (m_this.mode()) {
case m_this.modes.edit:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice and clean.. 👍

/**
* Select or deselect an edit handle.
*
* @param {geo.event} evt The mouse move event.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this only applicable/callable when "The mouse move"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This gets called with the mouseon and mouseoff events. Those only occur on a mouse move or when the mouse move is retriggered. When we want to make sure touch devices are fully supported, we should trigger mouseon and mouseoff events (and mouseover and mouseout) before the touch causes a click (but that is an issue for another PR).

$.each(m_features[geo_annotation._editHandleFeatureLevel], function (type, feature) {
feature.feature.modified();
});
m_this.currentAnnotation.selectEditHandle(evt.data, enable);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious...here we are passing enable as it is and 2 lines below we are converting into true boolean representation. I think I may know why but just double checking.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of javascript handles truthy or falsy values they way you'd expect. However, jQuery's toggleClass does not, and must take either an actual boolean or a function that returns a boolean.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, thanks good to know.

},
scaled: false,
stroke: true,
strokeColor: {r: 0, g: 0, b: 1},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably make the default color to orange. What you think @matthewma7 ?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aashish24 The current color works fine for me, because I used some yellow-orange color in the other project.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay great lets keep the default to blue then thanks @matthewma7

maxr2 = Math.max(maxr2, Math.pow(pos.x - dispCenter.x, 2) + Math.pow(pos.y - dispCenter.y, 2));
}
r = Math.sqrt(maxr2) + offset;
pos = map.displayToGcs({x: dispCenter.x + r * Math.cos(rotation), y: dispCenter.y - r * Math.sin(rotation)}, null);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

long line?

y: handle.resizePosition.y + delta.y
}, null),
d01 = Math.pow(Math.pow(p1.y - p0.y, 2) + Math.pow(p1.x - p0.x, 2), 0.5) - handle.handle.style.resizeHandleOffset,
d02 = Math.pow(Math.pow(p2.y - p0.y, 2) + Math.pow(p2.x - p0.x, 2), 0.5) - handle.handle.style.resizeHandleOffset,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrap these long lines?

* edits from collapsing immediately. */
} else if (layer.displayDistance(curPts[index], null, curPts[(index + 1) % curPts.length], null) <= aPP) {
near = (index + 1) % curPts.length;
} else if (layer.displayDistance(curPts[index], null, curPts[(index + curPts.length - 1) % curPts.length], null) <= aPP) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here..wrap?

* Process any edit actions for this annotation.
*
* @param {geo.event} evt The action event.
* @returns {boolean|string} `true` to update the annotation, falsy to not
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'true' --> Truthy to update the annotation? To keep it consistent with other docs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On return values, we can be specific -- it does output true, not just an arbitrary truthy value. On input parameters we try to be flexible and accept any truthy value.

@@ -15,7 +15,8 @@ var geo_action = {
// annotation actions
annotation_line: 'geo_annotation_line',
annotation_polygon: 'geo_annotation_polygon',
annotation_rectangle: 'geo_annotation_rectangle'
annotation_rectangle: 'geo_annotation_rectangle',
annotation_edit_handle: 'geo_annotation_edit_handle'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we just call it annotation_edit? or would that be confusing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may eventually want other edit actions. For instance, suppose we supported an action on selecting the annotation in edit mode, then it might be edit_select to differentiate it.

Copy link
Member

@aashish24 aashish24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks great to me, just looking at the annotation.js more closely, has some minor comments / questions / suggestions. Overall this is looking great, I am also trying to build it locally to try it out.

@aashish24
Copy link
Member

@manthey @matthewma7 this is looking very good. Some points for discussions / future work may be (I am interesting in hearing your thoughts on it):

  1. I feel that sometimes (depending on how I draw my area, the handlers were little too far

  2. When I rotate, the scale handle remain at its place, is that intentional? Should it also rotate?

  3. For point annotations, should we think about scaling as well (only scale handle)?

Copy link
Member

@aashish24 aashish24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍 with some comments left for discussions for future PR/work perhaps.

},
scaled: false,
stroke: true,
strokeColor: {r: 0, g: 0, b: 1},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay great lets keep the default to blue then thanks @matthewma7

var editPoints,
style = $.extend({}, defaultEditHandleStyle, m_this.editHandleStyle()),
handles = util.ensureFunction(style.handles)() || {},
selected = m_this._editHandle && m_this._editHandle.handle && m_this._editHandle.handle.selected ? m_this._editHandle.handle : undefined;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrap this line?

y: evt.mouse.mapgcs.y - evt.state.origin.mapgcs.y
},
curPts = m_this._coordinates();
var pts = start.map(function (elem) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice +1

* @returns {boolean|string} `true` to update the annotation, falsy to not
* update anything.
*/
this._processEditActionRotate = function (evt) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice +1

@manthey
Copy link
Contributor Author

manthey commented Feb 20, 2018

@aashish24, in response to your numbered list:

  1. I'm not sure what you were saying here.

  2. Yes, the scale handle doesn't rotate. It makes it more obvious that it isn't the rotation handle.

  3. We could scale points, but that seems like a mildly odd thing to do conceptually (it would be easy technically). If we want to do that, we can make add it in another PR (and, if desired, the default could be to not show it).

@aashish24
Copy link
Member

@manthey for

  1. what I meant that the handles distance from the center of the shape seemed too far to me in some cases. Perhaps I can show it live.

  2. Sounds good.

  3. Sounds good as well. Not a major request, I felt that it would be nice to be able to scale and move but this is low priority for me.

@manthey manthey merged commit 2854ccb into master Feb 20, 2018
@manthey manthey deleted the edit-annotations branch February 20, 2018 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants