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

Add preliminary support for Cubic Bézier curve edge #245

Merged
merged 6 commits into from
Nov 3, 2021

Conversation

kaisalmen
Copy link
Contributor

@kaisalmen kaisalmen commented Oct 4, 2021

This PR introduces preliminary support for cubic Bézier curve edges.

What has been achieved:

  • Support one or many Bezier curves
  • Allow interactive manipulation of curves
  • Interactively add and remove new curves on an edge
  • Smooth interpolation on curve junctions

Issues that should be fixed before PR is ready

  • Add +/- to green/red circles for add/remove curve
  • New Curve should be created on "click" and not "move" of add/remove
  • Visual connections (lines) between control points and curve endings

What is still missing (reason for being preliminary). To be discussed if done in scope of this PR or later:

  • Add unit tests
  • Support Text-Layout
  • Line jumps according curve

The classdiagram has been enhanced to show the new capabilities.

@gitpod-io
Copy link

gitpod-io bot commented Oct 4, 2021

Copy link
Contributor

@spoenemann spoenemann left a comment

Choose a reason for hiding this comment

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

Thanks for this huge contribution!

The approach of using green and red handles for adding / deleting sections is interesting and probably a good match for handling Bezier edge sections. I'd propose to add + / - icons to those handles. However, a single click on those handles has no effect, but you need to move the mouse before anything happens; this is probably unintuitive.

Interesting: Bezier control points are handled as regular line segments for the computation of line jumps, see below. This is not critical, but should be noted in a separate issue once we merge this.
Screen Shot 2021-10-11 at 09 47 54

Keep up the good work!

@@ -0,0 +1,44 @@
/********************************************************************************
* Copyright (c) 2019 TypeFox and others.
Copy link
Contributor

Choose a reason for hiding this comment

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

Please use an up-to-date-year for new files.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I will. Thanks.

@kaisalmen
Copy link
Contributor Author

kaisalmen commented Oct 18, 2021

The approach of using green and red handles for adding / deleting sections is interesting and probably a good match for handling Bezier edge sections. I'd propose to add + / - icons to those handles. However, a single click on those handles has no effect, but you need to move the mouse before anything happens; this is probably unintuitive.

+/- icons, yes definitely. Colors-only was a short-cut.
Handle control is identical to the others edges, but this is not good here.
At least these two things should be corrected before this PR is ready, I think. I will add WIP to the title and add the list these things to the open points in the description.

Interesting: Bezier control points are handled as regular line segments for the computation of line jumps, see below. This is not critical, but should be noted in a separate issue once we merge this.

Fixing this behaviour is likely not easy (needs investigation). Actually the curve should define the line jumps and not the handles.

@kaisalmen kaisalmen changed the title Add preliminary support for Cubic Bézier curve edge WIP: Add preliminary support for Cubic Bézier curve edge Oct 18, 2021
Copy link
Contributor

@spoenemann spoenemann left a comment

Choose a reason for hiding this comment

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

A few things left to fix, otherwise it's looking great!

  • Clicking on + / - still doesn't work unless I move the mouse a bit. We should listen on the mouseUp event, not mouseMove.
  • When moving a split point between two Bezier segments, I'd expect the connected control points to move by the same amount.
  • The source and target anchors seem to be determined by the position of the other node instead of the nearest control point. For example, moving around the "Ada" node affects the anchor position on the Foo node.

import { LinearEdgeRouter } from './linear-edge-router';

@injectable()
export abstract class BezierEdgeRouter extends LinearEdgeRouter {
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks strange to inherit from LinearEdgeRouter. Shall we rename that to "AbstractEdgeRouter", or rather copy some code to avoid the inheritance?

Copy link
Contributor Author

@kaisalmen kaisalmen Oct 26, 2021

Choose a reason for hiding this comment

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

Renaming it sounds better. I need to check how much code is really required from the inherited class. I will come back with a proposal.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I go for rename, otherwise we have to copy too much code.

x: relH2.x + BezierEdgeRouter.DEFAULT_BEZIER_HANDLE_OFFSET,
y: relH2.y
};
return { h1: h1, h2: h2 };
Copy link
Contributor

Choose a reason for hiding this comment

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

Hint: you can write this as { h1, h2 }. But in this case I'd propose to return a tuple instead: [h1, h2] of type [Point, Point].

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, will do so.

Only one segment for now

Signed-off-by: Kai Salmen <kai.salmen@typefox.io>
Allow to add but not yet remove additional new curve segment
Classpath example now features to curves
Control handle movement is mirrored on control handle opposite to bezier-junction

Signed-off-by: Kai Salmen <kai.salmen@typefox.io>
Add and remove is done via new red and green handles available at source or junction. If only one curve is available, then there is no delete

Signed-off-by: Kai Salmen <kai.salmen@typefox.io>
Add separate handle view for add/remove of bezier curves
Add SBezierControlHandleView for handle visualization

Signed-off-by: Kai Salmen <kai.salmen@typefox.io>
@kaisalmen kaisalmen force-pushed the ks-bezier-edge branch 2 times, most recently from 509694d to e97073f Compare October 28, 2021 13:02
@kaisalmen
Copy link
Contributor Author

kaisalmen commented Oct 28, 2021

Only thing left now is the +/- button behaviour. I fixed some issue with the mirrored control point alignment (when model is initially loaded) as well.

- Renamed LinearEdgeRouter to AbstractEdgeRouter
- Bezier control points move along with source, target and bezier-junctions
- Fixed eslint issues
- Fixed source and target anchors when moving control points and attached objects

Signed-off-by: Kai Salmen <kai.salmen@typefox.io>
- Add MouseListener that reacts on mouseDown on bezier-add and bezier-remove elements. It triggers an Action and Command that adds or removes a curve segment
- Adjust class diagram layout

Signed-off-by: Kai Salmen <kai.salmen@typefox.io>
@kaisalmen kaisalmen changed the title WIP: Add preliminary support for Cubic Bézier curve edge Add preliminary support for Cubic Bézier curve edge Nov 2, 2021
@kaisalmen
Copy link
Contributor Author

Ready for review. The last open point is now resolved: Add MouseListener that reacts on mouseDown on bezier-add and bezier-remove handles. The event riggers a new Action and Command that adds or removes a curve segment.

Copy link
Contributor

@spoenemann spoenemann left a comment

Choose a reason for hiding this comment

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

Thanks! I have a few more remarks, but I'll merge it anyway so we can start the work on #243. @kaisalmen please create a new PR to address the remaining comments when the restructuring is done (will submit a PR for that today).


const result = [];
let router;
const element = target.root.index.getById(target.id);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this will just point to the same element, so target and element are the same?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True. I will simplify it.

edgeId: string;
actionTask: BezierActionTask;

constructor(@inject(TYPES.IEdgeRouter) protected readonly router: BezierEdgeRouter,
Copy link
Contributor

Choose a reason for hiding this comment

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

Actions should be serializable, so please remove the router and fetch it in the BezierCurveCommand instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, the action will only contain the targetId and a value from the enum in the future.

this.edgeId = edgeId;
}

getRouter(): BezierEdgeRouter {
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't need these getters because the properties are public.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

✅ It was a bit late yesterday evening.

};

@injectable()
export class BezierCurveCommand extends Command {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the command name should be more specific, like AddRemoveBezierSegmentCommand.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, good idea. I will rename the action accordingly

@spoenemann spoenemann merged commit 5b094df into eclipse-sprotty:master Nov 3, 2021
@kaisalmen kaisalmen deleted the ks-bezier-edge branch November 3, 2021 07:36
@spoenemann spoenemann added this to the v0.11.0 milestone Nov 30, 2021
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.

2 participants