package jetbrains.mps.lang.editor.diagram.runtime.jetpad.views;
/*Generated by MPS */
import jetbrains.jetpad.model.property.Property;
import jetbrains.jetpad.values.Color;
import jetbrains.jetpad.model.property.ValueProperty;
import jetbrains.jetpad.geometry.Segment;
import jetbrains.jetpad.mapper.Mapper;
import jetbrains.jetpad.mapper.Synchronizers;
import jetbrains.jetpad.mapper.MapperFactory;
import jetbrains.jetpad.projectional.view.GroupView;
import jetbrains.jetpad.geometry.Vector;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.jetpad.model.event.SimpleEventSource;
import jetbrains.jetpad.model.property.PropertyChangeEvent;
public class ConnectorDecoratorView extends AbstractDecoratorView {
public Property<Color> color = new ValueProperty<Color>(Color.BLACK);
public Property<Color> backgroundColor = new ValueProperty<Color>(Color.LIGHT_GRAY);
private Iterable<Segment> mySegments;
private Property<Boolean> myValid = new ConnectorDecoratorView.EventSourceProperty<Boolean>(Boolean.TRUE);
public ConnectorDecoratorView() {
new Mapper<ConnectorDecoratorView, ConnectorDecoratorView>(this, this) {
@Override
protected void registerSynchronizers(Mapper.SynchronizersConfiguration configuration) {
super.registerSynchronizers(configuration);
configuration.add(Synchronizers.forObservableRole(this, selectionDecorator, childSubList(), createSelectionDecoratorMapperFactory()));
configuration.add(Synchronizers.forObservableRole(this, errorDecorator, childSubList(), createErrorDecoratorMapperFactory()));
}
}.attachRoot();
}
private MapperFactory<Boolean, GroupView> createSelectionDecoratorMapperFactory() {
return new MapperFactory<Boolean, GroupView>() {
public Mapper<? extends Boolean, ? extends GroupView> createMapper(Boolean selected) {
return new Mapper<Boolean, GroupView>(selected, createSelectionView()) {
@Override
protected void registerSynchronizers(Mapper.SynchronizersConfiguration configuration) {
super.registerSynchronizers(configuration);
configuration.add(Synchronizers.forProperty(myValid, new Runnable() {
public void run() {
updateSelectionView(getTarget());
}
}));
}
};
}
};
}
private MapperFactory<Boolean, CrossView> createErrorDecoratorMapperFactory() {
return new MapperFactory<Boolean, CrossView>() {
public Mapper<? extends Boolean, ? extends CrossView> createMapper(Boolean error) {
return new Mapper<Boolean, CrossView>(error, createErrorView()) {
@Override
protected void registerSynchronizers(Mapper.SynchronizersConfiguration configuration) {
super.registerSynchronizers(configuration);
configuration.add(Synchronizers.forProperty(myValid, new Runnable() {
public void run() {
getTarget().centerLocation.set(getErrorPoint());
}
}));
}
};
}
};
}
public void setSegments(Iterable<Segment> segments) {
mySegments = segments;
}
public Property<Boolean> isValid() {
return myValid;
}
private CrossView createErrorView() {
CrossView errorView = new CrossView();
errorView.color.set(Color.RED);
return errorView;
}
protected GroupView createSelectionView() {
return new GroupView();
}
private Vector getErrorPoint() {
if (Sequence.fromIterable(mySegments).isEmpty()) {
return null;
}
double sumLength = 0;
for (Segment segment : Sequence.fromIterable(mySegments)) {
sumLength += segment.length();
}
if (sumLength == 0) {
return Sequence.fromIterable(mySegments).first().start;
}
double halfLength = sumLength / 2.0;
sumLength = 0;
for (Segment segment : Sequence.fromIterable(mySegments)) {
double currentLength = segment.length();
if (sumLength + currentLength >= halfLength) {
Vector se = segment.end.sub(segment.start);
double d = (halfLength - sumLength) / se.length();
double xToAdd = se.x * d;
double yToAdd = se.y * d;
Vector result = segment.start.add(new Vector(((int) xToAdd), ((int) yToAdd)));
return result;
}
sumLength += currentLength;
}
return null;
}
private void updateSelectionView(GroupView selectionView) {
selectionView.children().clear();
for (Segment segment : Sequence.fromIterable(mySegments)) {
if (neq_2z6621_a0a0b0o(segment, Sequence.fromIterable(mySegments).last())) {
ResizeHandleView handleView = new ResizeHandleView(segment.end);
handleView.color.set(color.get());
handleView.backgroundColor.set(backgroundColor.get());
selectionView.children().add(handleView);
}
if (segment.length() > SELECTION_SQUARE_HALF_WIDTH * 20) {
ResizeHandleView handleView = new ResizeHandleView(new Vector((segment.end.x + segment.start.x) / 2, (segment.end.y + segment.start.y) / 2));
handleView.color.set(color.get());
handleView.backgroundColor.set(backgroundColor.get());
selectionView.children().add(handleView);
}
}
}
private class EventSourceProperty<T> extends SimpleEventSource<PropertyChangeEvent<T>> implements Property<T> {
private T myDefautlValue;
public EventSourceProperty(T defaultValue) {
myDefautlValue = defaultValue;
}
public String getPropExpr() {
return "eventSourceProperty()";
}
public T get() {
return myDefautlValue;
}
public void set(T value) {
fire(new PropertyChangeEvent(myDefautlValue, value));
}
}
private static boolean neq_2z6621_a0a0b0o(Object a, Object b) {
return !(((a != null ? a.equals(b) : a == b)));
}
}