public void SetModel(ISelectionModel model) { model = model ?? throw new ArgumentNullException(nameof(model)); if (_items != null) { Model.SelectionChanged -= SelectionModelSelectionChanged; Model = model; Model.SelectionChanged += SelectionModelSelectionChanged; try { _updatingItems = true; _items.Clear(); foreach (var i in model.SelectedItems) { _items.Add(i); } } finally { _updatingItems = false; } } }
protected SelectingItemsControlAutomationPeer(SelectingItemsControl owner) : base(owner) { _selection = owner.GetValue(ListBox.SelectionProperty); _selection.SelectionChanged += OwnerSelectionChanged; owner.PropertyChanged += OwnerPropertyChanged; }
public UndoableMapModel(ISelectionModel model, string path, bool readOnly) { this.FilePath = path; this.IsFileReadOnly = readOnly; this.model = model; model.PropertyChanged += this.ModelOnPropertyChanged; model.FloatingTilesChanged += this.FloatingTilesOnListChanged; model.TileGridChanged += this.TileOnTileGridChanged; model.HeightGridChanged += this.TileOnHeightGridChanged; model.Attributes.StartPositionChanged += this.AttributesOnStartPositionChanged; this.bandboxBehaviour = new TileBandboxBehaviour(this); this.bandboxBehaviour.PropertyChanged += this.BandboxBehaviourPropertyChanged; this.undoManager.CanUndoChanged += this.UndoManagerOnCanUndoChanged; this.undoManager.CanRedoChanged += this.UndoManagerOnCanRedoChanged; this.undoManager.IsMarkedChanged += this.UndoManagerOnIsMarkedChanged; this.model.SelectedFeatures.CollectionChanged += this.SelectedFeaturesCollectionChanged; }
public static IReplayableOperation CreateDeselectAndMergeOperation(ISelectionModel model) { var deselectOp = new DeselectOperation(model); var mergeOp = CreateFlattenOperation(model); return(new CompositeOperation(deselectOp, mergeOp)); }
public HighlightManager(GraphControl canvas, [CanBeNull] ISelectionModel <IModelItem> selectionModel = null) : base(canvas, selectionModel) { var graphModelManager = canvas.GraphModelManager; edgeHighlightGroup = graphModelManager.ContentGroup.AddGroup(); edgeHighlightGroup.Below(graphModelManager.EdgeLabelGroup); }
public SelectedItemsSync(ISelectionModel model) { _selectionModel = model ?? throw new ArgumentNullException(nameof(model)); _selectedItems = new AvaloniaList <object?>(); SyncSelectedItemsWithSelectionModel(); SubscribeToSelectedItems(_selectedItems); SubscribeToSelectionModel(model); }
protected virtual void OwnerPropertyChanged(object?sender, AvaloniaPropertyChangedEventArgs e) { if (e.Property == ListBox.SelectionProperty) { _selection.SelectionChanged -= OwnerSelectionChanged; _selection = Owner.GetValue(ListBox.SelectionProperty); _selection.SelectionChanged += OwnerSelectionChanged; RaiseSelectionChanged(); } }
public virtual bool IsSelected(ILookup context, IModelItem item) { ISelectionModel <IModelItem> selectionModel = context.Lookup <ISelectionModel <IModelItem> >(); if (selectionModel != null) { return(selectionModel.IsSelected(item)); } return(false); }
private static void AddNodeHalos(GenericLayoutData data, IGraph graph, ISelectionModel <IModelItem> selection, bool layoutOnlySelection) { var nodeHalos = new DictionaryMapper <INode, NodeHalo>(); foreach (var node in graph.Nodes) { var top = 0.0; var left = 0.0; var bottom = 0.0; var right = 0.0; // for each port with an EventPortStyle extend the node halo to cover the ports render size foreach (var port in node.Ports) { var eventPortStyle = port.Style as EventPortStyle; if (eventPortStyle != null) { var renderSize = eventPortStyle.RenderSize; var location = port.GetLocation(); top = Math.Max(top, node.Layout.Y - location.Y - renderSize.Height / 2); left = Math.Max(left, node.Layout.X - location.X - renderSize.Width / 2); bottom = Math.Max(bottom, location.Y + renderSize.Height / 2 - node.Layout.GetMaxY()); right = Math.Max(right, location.X + renderSize.Width / 2 - node.Layout.GetMaxX()); } } // for each node without incoming or outgoing edges reserve space for laid out exterior labels if (graph.InDegree(node) == 0 || graph.OutDegree(node) == 0) { foreach (var label in node.Labels) { if (IsNodeLabelAffected(graph, selection, label, layoutOnlySelection)) { var labelBounds = label.GetLayout().GetBounds(); if (graph.InDegree(node) == 0) { left = Math.Max(left, labelBounds.Width); top = Math.Max(top, labelBounds.Height); } if (graph.OutDegree(node) == 0) { right = Math.Max(right, labelBounds.Width); bottom = Math.Max(bottom, labelBounds.Height); } } } } nodeHalos[node] = NodeHalo.Create(top, left, bottom, right); } data.AddItemMapping(NodeHalo.NodeHaloDpKey).Mapper = nodeHalos; }
/// <summary> /// The bounds including the nodes of the selection. /// </summary> public RectD GetBounds(ISelectionModel <IModelItem> selection) { var bounds = RectD.Empty; foreach (var item in selection) { var node = item as INode; if (node != null) { bounds += node.Layout.ToRectD(); } } return(bounds); }
private static bool IsNodeLabelAffected(IGraph graph, ISelectionModel <IModelItem> selection, ILabel label, bool layoutOnlySelection) { var node = label.Owner as INode; if (node != null) { var isInnerLabel = node.Layout.Contains(label.GetLayout().GetCenter()); bool isPool = node.Style is PoolNodeStyle; bool isChoreography = node.Style is ChoreographyNodeStyle; var isGroupNode = graph.IsGroupNode(node); return(!isInnerLabel && !isPool && !isChoreography && !isGroupNode && (!layoutOnlySelection || selection.IsSelected(node))); } return(false); }
public LayoutData Create(IGraph graph, ISelectionModel <IModelItem> selection, Scope layoutScope) { var data = new GenericLayoutData(); var hierarchicLayoutData = new HierarchicLayoutData(); // check if only selected elements should be laid out var layoutOnlySelection = layoutScope == Scope.SelectedElements; // mark 'flow' edges, i.e. sequence flows, default flows and conditional flows data.AddItemCollection(BpmnLayout.SequenceFlowEdgesDpKey).Delegate = IsSequenceFlow; // mark boundary interrupting edges for the BalancingPortOptimizer data.AddItemCollection(BpmnLayout.BoundaryInterruptingEdgesDpKey).Delegate = edge => edge.SourcePort.Style is EventPortStyle; // mark conversations, events and gateways so their port locations are adjusted data.AddItemCollection(PortLocationAdjuster.AffectedNodesDpKey).Delegate = (INode node) => (node.Style is ConversationNodeStyle || node.Style is EventNodeStyle || node.Style is GatewayNodeStyle); // add NodeHalos around nodes with event ports or specific exterior labels so the layout keeps space for the event ports and labels as well AddNodeHalos(data, graph, selection, layoutOnlySelection); // add PreferredPlacementDescriptors for labels on sequence, default or conditional flows to place them at source side AddEdgeLabelPlacementDescriptors(data); // mark nodes, edges and labels as either fixed or affected by the layout and configure port constraints and incremental hints MarkFixedAndAffectedItems(data, hierarchicLayoutData, selection, layoutOnlySelection); // mark associations and message flows as undirected so they have less impact on layering hierarchicLayoutData.EdgeDirectedness.Delegate = edge => (IsMessageFlow(edge) || IsAssociation(edge)) ? 0 : 1; // add layer constraints for start events, sub processes and message flows AddLayerConstraints(graph, hierarchicLayoutData); // add EdgeLayoutDescriptor to specify minimum edge length for edges AddMinimumEdgeLength(MinimumEdgeLength, hierarchicLayoutData); return(data.CombineWith(hierarchicLayoutData)); }
public SelectFeatureOperation(ISelectionModel model, Guid id) { this.model = model; this.id = id; }
public void SetSelectionModel(ISelectionModel selectionModel) { }
/// <summary> /// Check whether the specified model item has been selected in the underlying /// IGraph. /// </summary> private static bool IsSelected(ISelectionModel <IModelItem> selectionModel, IModelItem item) { return(selectionModel != null && selectionModel.IsSelected(item)); }
protected override async Task StartWithIGraph(IGraph graph, ILookup newContext) { OptionGroup layoutGroup = Handler.GetGroupByName(GROUP_LAYOUT); string busDetermination = (string)layoutGroup[BUSES].Value; ISelectionModel <IModelItem> selectionModel = newContext.Lookup <ISelectionModel <IModelItem> >(); var mapperRegistry = graph.MapperRegistry; var originalBusIds = mapperRegistry.GetMapper(BusRouter.EdgeDescriptorDpKey); IMapper <IEdge, BusDescriptor> busIds; if (busDetermination != CUSTOM) { mapperRegistry.RemoveMapper(BusRouter.EdgeDescriptorDpKey); busIds = mapperRegistry.CreateMapper <IEdge, BusDescriptor>(BusRouter.EdgeDescriptorDpKey); var scopePartial = (string)layoutGroup[SCOPE].Value == PARTIAL; foreach (var edge in graph.Edges) { bool isFixed = scopePartial && !IsSelected(selectionModel, edge.GetSourceNode()) && !IsSelected(selectionModel, edge.GetTargetNode()); busIds[edge] = new BusDescriptor(GetBusId(edge, busDetermination), isFixed); } } else { busIds = originalBusIds ?? mapperRegistry.CreateConstantMapper(BusRouter.EdgeDescriptorDpKey, new BusDescriptor(SingleBusId)); } var originalEdgeSubsetMapper = mapperRegistry.GetMapper(BusRouter.DefaultAffectedEdgesDpKey); if (originalEdgeSubsetMapper != null) { mapperRegistry.RemoveMapper(BusRouter.DefaultAffectedEdgesDpKey); } var selectedIds = new System.Collections.Generic.HashSet <object>(); switch ((string)layoutGroup[SCOPE].Value) { case SUBSET: mapperRegistry.CreateDelegateMapper(BusRouter.DefaultAffectedEdgesDpKey, e => IsSelected(selectionModel, e)); break; case SUBSET_BUS: foreach (var edge in graph.Edges.Where(edge => IsSelected(selectionModel, edge))) { selectedIds.Add(busIds[edge].BusId); } mapperRegistry.CreateDelegateMapper(BusRouter.DefaultAffectedEdgesDpKey, e => selectedIds.Contains(busIds[e].BusId)); break; case PARTIAL: foreach (var edge in graph.Nodes.Where(node => IsSelected(selectionModel, node)).SelectMany((node) => graph.EdgesAt(node))) { selectedIds.Add(busIds[edge].BusId); } mapperRegistry.CreateDelegateMapper(BusRouter.DefaultAffectedEdgesDpKey, e => selectedIds.Contains(busIds[e].BusId)); break; } try { await base.StartWithIGraph(graph, newContext); } finally { mapperRegistry.RemoveMapper(BusRouter.EdgeDescriptorDpKey); if (originalBusIds != null) { mapperRegistry.AddMapper(BusRouter.EdgeDescriptorDpKey, originalBusIds); } mapperRegistry.RemoveMapper(BusRouter.DefaultAffectedEdgesDpKey); if (originalEdgeSubsetMapper != null) { mapperRegistry.AddMapper(BusRouter.DefaultAffectedEdgesDpKey, originalEdgeSubsetMapper); } } }
public BatchUpdateOperation(ISelectionModel owner) { _owner = owner; _isDisposed = false; owner.BeginBatchUpdate(); }
public static IDisposable BatchUpdate(this ISelectionModel model) { return(new BatchUpdateOperation(model)); }
public SelectedItemsSync(ISelectionModel model) { model = model ?? throw new ArgumentNullException(nameof(model)); Model = model; }
public DeselectOperation(ISelectionModel model) { this.model = model; }
/// <summary> /// Executes the module on the given graph using the provided context. /// </summary> /// <remarks> /// The layout will be calculated <see cref="RunInBackground">optionally</see> /// in a separate thread in method <see cref="RunModuleAsync"/>. /// </remarks> /// <param name="graph">The graph to execute on.</param> /// <param name="newContext">The context to use. This method will query a <c>ISelectionModel<IModelItem></c></param> /// for the selected nodes and edges and the <c>GraphControl</c> to morph the layout. protected virtual async Task StartWithIGraph(IGraph graph, ILookup newContext) { this.graph = graph; if (ShouldConfigureTableLayout()) { PrepareTableLayout(); } ISelectionModel <IModelItem> selectionModel = newContext.Lookup <ISelectionModel <IModelItem> >(); LayoutGraphAdapter adapter = new LayoutGraphAdapter(graph, selectionModel); this.layoutGraph = adapter.CreateCopiedLayoutGraph(); ILookup additionalLookup = Lookups.Single(layoutGraph, typeof(LayoutGraph)); ILookup wrappedLookup = Lookups.Wrapped(newContext, additionalLookup); try { ICompoundEdit compoundEdit = graph.BeginEdit("Layout", "Layout"); CheckReentrant(wrappedLookup); ConfigureModule(); if (RunInBackground) { // without the LayoutExecutor helper class on the layout graph side of things, we register the aborthandler // to the layout graph with the utility method provided by AbortHandler var abortHandler = AbortHandler.CreateForGraph(layoutGraph); // now create the dialog that controls the abort handler abortDialog = new AbortDialog { AbortHandler = abortHandler, Owner = Application.Current.MainWindow }; // start the layout in another thread. var layoutThread = new Thread(async() => await RunModuleAsync(wrappedLookup, graph, compoundEdit)); // now if we are not doing a quick layout - and if it takes more than a few seconds, we open the dialog to // enable the user to stop or cancel the execution var showDialogTimer = new DispatcherTimer(DispatcherPriority.Normal, abortDialog.Dispatcher) { Interval = TimeSpan.FromSeconds(2) }; showDialogTimer.Tick += delegate { // it could be that the layout is already done - so check whether we still // need to open the dialog var dialogInstance = abortDialog; if (dialogInstance != null) { // open the abort dialog dialogInstance.Show(); } // we only want to let it go off once - so stop the timer showDialogTimer.Stop(); }; // kick-off the timer and the layout showDialogTimer.Start(); layoutThread.Start(); } else { await RunModuleAsync(wrappedLookup, graph, compoundEdit); } } catch (Exception e) { FreeReentrant(); TableLayoutConfigurator.CleanUp(graph); OnDone(new LayoutEventArgs(e)); //optionally do something here... } }
public SelectTileOperation(ISelectionModel model, int tileId) { this.model = model; this.tileId = tileId; }
public SelectStartPositionOperation(ISelectionModel model, int index) { this.model = model; this.index = index; }
private static void MarkFixedAndAffectedItems(GenericLayoutData data, HierarchicLayoutData hierarchicLayoutData, ISelectionModel <IModelItem> graphSelection, bool layoutOnlySelection) { if (layoutOnlySelection) { var affectedEdges = Mappers.FromDelegate((IEdge edge) => graphSelection.IsSelected(edge) || graphSelection.IsSelected(edge.GetSourceNode()) || graphSelection.IsSelected(edge.GetTargetNode())); data.AddItemCollection(LayoutKeys.AffectedEdgesDpKey).Mapper = affectedEdges; // fix ports of unselected edges and edges at event ports data.AddItemMapping(PortConstraintKeys.SourcePortConstraintDpKey).Delegate = edge => (!affectedEdges[edge] || edge.SourcePort.Style is EventPortStyle) ? PortConstraint.Create(GetSide(edge, true)) : null; data.AddItemMapping(PortConstraintKeys.TargetPortConstraintDpKey).Delegate = edge => !affectedEdges[edge] ? PortConstraint.Create(GetSide(edge, false)) : null; // give core layout hints that selected nodes and edges should be incremental hierarchicLayoutData.IncrementalHints.ContextDelegate = (item, factory) => { if (item is INode && graphSelection.IsSelected(item)) { return(factory.CreateLayerIncrementallyHint(item)); } else if (item is IEdge && affectedEdges[(IEdge)item]) { return(factory.CreateSequenceIncrementallyHint(item)); } return(null); }; data.AddItemCollection(BpmnLayout.AffectedLabelsDpKey).Delegate = label => { var edge = label.Owner as IEdge; if (edge != null) { return(affectedEdges[edge]); } var node = label.Owner as INode; if (node != null) { var isInnerLabel = node.Layout.Contains(label.GetLayout().GetCenter()); bool isPool = node.Style is PoolNodeStyle; bool isChoreography = node.Style is ChoreographyNodeStyle; return(!isInnerLabel && !isPool && !isChoreography && graphSelection.IsSelected(node)); } return(false); }; } else { // fix source port of edges at event ports data.AddItemMapping(PortConstraintKeys.SourcePortConstraintDpKey).Delegate = edge => edge.SourcePort.Style is EventPortStyle?PortConstraint.Create(GetSide(edge, true)) : null; data.AddItemCollection(BpmnLayout.AffectedLabelsDpKey).Delegate = label => { if (label.Owner is IEdge) { return(true); } var node = label.Owner as INode; if (node != null) { var isInnerLabel = node.Layout.Contains(label.GetLayout().GetCenter()); bool isPool = node.Style is PoolNodeStyle; bool isChoreography = node.Style is ChoreographyNodeStyle; return(!isInnerLabel && !isPool && !isChoreography); } return(false); }; } }