示例#1
0
        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;
 }
示例#3
0
        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;
        }
示例#4
0
        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);
        }
示例#6
0
 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));
        }
示例#13
0
 public SelectFeatureOperation(ISelectionModel model, Guid id)
 {
     this.model = model;
     this.id    = id;
 }
示例#14
0
 public void SetSelectionModel(ISelectionModel selectionModel)
 {
 }
示例#15
0
        public void SetSelectionModel(ISelectionModel selectionModel)
        {

        }
示例#16
0
 /// <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));
 }
示例#17
0
        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));
 }
示例#20
0
 public SelectedItemsSync(ISelectionModel model)
 {
     model = model ?? throw new ArgumentNullException(nameof(model));
     Model = model;
 }
示例#21
0
 public DeselectOperation(ISelectionModel model)
 {
     this.model = model;
 }
示例#22
0
        /// <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&lt;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...
            }
        }
示例#23
0
 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);
                };
            }
        }