public void FitViewRectToGraph(bool immediately) { if (immediately) { transform = GetOptimalTransform(); return; } // viewRect: canvas shrunk down to 80% Rect viewRect = parent.GetViewRect(); viewRect = Util.CenterRect(viewRect.center, viewRect.GetExtents() * 0.8f); // find graphRect (logical coords) var logicalPositions = graph.VerticesData.Values.Select(v => v.pos); Rect logicalPosBounds = Util.GetBounds(logicalPositions).ClampExtents(0.01f, 0.01f, float.MaxValue, float.MaxValue); var logicalExtents = logicalPosBounds.GetExtents(); var viewExtents = viewRect.GetExtents(); // fit logical extents into display extents var fullScale = new Vector2( viewExtents.x / logicalExtents.x, viewExtents.y / logicalExtents.y ); var targetScale = transform.scale.Clamp(fullScale * 0.5f, fullScale); bool scaleChange = targetScale != transform.scale; var targetTransform = new Transform2d(transform.translation, targetScale, transform.rotation); var targetViewGraphBounds = targetTransform.Apply(logicalPosBounds); float xOver = targetViewGraphBounds.xMax - viewRect.xMax; float xUnder = targetViewGraphBounds.xMin - viewRect.xMin; float yOver = targetViewGraphBounds.yMax - viewRect.yMax; float yUnder = targetViewGraphBounds.yMin - viewRect.yMin; var shift = new Vector2( xOver > 0 ? xOver : xUnder < 0 ? xUnder : 0, yOver > 0 ? yOver : yUnder < 0 ? yUnder : 0); bool translateChanged = shift != Vector2.zero; if (scaleChange || translateChanged) { targetTransform.translation -= shift; Tweener.gen.Add(new Tween <Transform2d>(t => transform = t, 0.2f, TweenUtil.Transform2(transform, targetTransform, TwoValueEasing.Linear))); } }
public void HandleEvent(Event ev) { switch (ev.rawType) { case EventType.mouseUp: draggedEntity = null; selectionRectActive = false; parent.RepaintView(); break; } switch (ev.type) { case EventType.mouseDown: // clicked on minimap -> focos camera on click pos if (Settings.Instance.showMinimap && minimapRect.Contains(ev.mousePosition)) { SetCenter(minimapTransform.Revert(ev.mousePosition)); break; } var clickEntity = GetEntityAtPosition(ev.mousePosition); if (clickEntity != null) { foreach (var source in dragEdgeSource) { parent.GetBackend().CreateRelation(source, clickEntity); } dragEdgeSource = new HashSet <T>(); if (ev.button == 0) // left click { draggedEntity = clickEntity; // update selection bool controlHeld = (ev.modifiers & EventModifiers.Control) != 0; if (controlHeld) { if (entitySelection.Contains(clickEntity)) { entitySelection.Remove(clickEntity); } else { entitySelection.Add(clickEntity); } } else { entitySelection = new HashSet <T>(new[] { clickEntity }); } OnEntitySelectionChange(); parent.RepaintView(); } } else // clickEntity == null { var clickEdge = GetEdgeAtPosition(ev.mousePosition); if (clickEdge == null) // clickEdge == null && clickEntity == null { if (ev.button != 1) // not a right click { bool controlHeld = (ev.modifiers & EventModifiers.Control) != 0; if (!controlHeld) { entitySelection = new HashSet <T>(); } // stop edge creation dragEdgeSource = new HashSet <T>(); // start rect selection selectionRectActive = true; selectionRectOrigin = ev.mousePosition; parent.RepaintView(); } } } break; case EventType.ContextClick: var ccEntity = GetEntityAtPosition(ev.mousePosition); if (ccEntity != null) { if (!entitySelection.Contains(ccEntity)) { entitySelection = new HashSet <T>() { ccEntity } } ; HandleEntityContextClick(entitySelection); Event.current.Use(); break; } var ccEdge = GetEdgeAtPosition(ev.mousePosition); if (ccEdge != null) { HandleRelationContextClick(ccEdge); Event.current.Use(); break; } break; case EventType.MouseMove: // update hover item and repaint if it changed var newHoverEntity = GetEntityAtPosition(ev.mousePosition); var newHoverRelation = (newHoverEntity != null) ? null : GetEdgeAtPosition(ev.mousePosition); bool hoverChange = newHoverEntity != hoverEntity || newHoverRelation != hoverRelation; hoverEntity = newHoverEntity; hoverRelation = newHoverRelation; bool doRepaint = hoverChange; // movement over the hover-item requires a repainted tooltip // also repaint if we are dragging an edge doRepaint |= dragEdgeSource.Any(); if (doRepaint) { parent.RepaintView(); } break; case EventType.MouseUp: draggedEntity = null; selectionRectActive = false; parent.RepaintView(); break; case EventType.MouseDrag: if (draggedEntity != null) { parent.MoveEntity(draggedEntity, transform.RevertScale(ev.delta)); } else if (selectionRectActive) // update selection { // GetBounds ensures that xmin < xmax and ymin < ymax var selectionRect = Util.GetBounds(new[] { ev.mousePosition, selectionRectOrigin }); var touchedEntityBounds = entityDrawerBounds.Where(pair => selectionRect.Intersects(pair.Value)); entitySelection = new HashSet <T>(touchedEntityBounds.Select(pair => pair.Key)); OnEntitySelectionChange(); } else { Shift(ev.delta); } parent.RepaintView(); break; case EventType.ScrollWheel: bool xZoom = (ev.modifiers & EventModifiers.Control) == 0; bool yZoom = (ev.modifiers & EventModifiers.Shift) == 0; bool zoomIn = Settings.Instance.invertZoom ? ev.delta.y > 0 : ev.delta.y < 0; var targetTransform = Zoom(transform, zoomIn, xZoom, yZoom, ev.mousePosition); Tweener.gen.Add(new Tween <Transform2d>(t => transform = t, 0.1f, TweenUtil.Transform2(transform, targetTransform, TwoValueEasing.Linear))); //.MoveTransform2dTo(transform, t=>Zoom(t, zoomIn, xZoom, yZoom, ev.mousePosition), 0.1f, true); ev.Use(); parent.RepaintView(); break; } }