Example #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="T:FolderMaterial"/> class.
 /// </summary>
 /// <param name="title">The title.</param>
 /// <param name="entries">The entries.</param>
 public FolderMaterial(string title, string[] entries)
     : this(title)
 {
     IconLabelMaterial label;
     for (int k = 0; k < entries.Length; k++)
     {
         label = new IconLabelMaterial("Resources.Text.png", entries[k]);
         mEntries.Add(label);
     }
     Collapse();
 }
        /// <summary>
        /// Perform undo of this command.
        /// </summary>
        public override void Undo()
        {
            //create a new group
            GroupShape group = new GroupShape(this.Controller.Model);

            //asign the entities to the group
            group.Entities = bundle.Entities;

            foreach (IDiagramEntity entity in group.Entities)
            {
                //this will be recursive if an entity is itself an IGroup
                entity.Group = group;
            }
            //add the new group to the layer
            this.Controller.Model.DefaultPage.DefaultLayer.Entities.Add(group);

            mGroup = group;

            //select the newly created group
            CollectionBase <IDiagramEntity> col = new CollectionBase <IDiagramEntity>();

            col.Add(mGroup);
            Selection.SelectedItems = col;
            mGroup.Invalidate();
        }
        /// <summary>
        /// Perform redo of this command.
        /// </summary>
        public override void Redo()
        {
            //create a new group; use the standard GroupShape or the CollapsibleGroupShape for a painted group with collapse/expand features.
            //GroupShape group = new GroupShape(this.Controller.Model);
            CollapsibleGroupShape group = new CollapsibleGroupShape(this.controller.Model);

            //asign the entities to the group
            group.Entities.Clear();

            foreach (IDiagramEntity entity in bundle.Entities)
            {
                //this will be recursive if an entity is itself an IGroup
                entity.Group = group;
                group.Entities.Add(entity);
            }
            //add the new group to the layer
            this.Controller.Model.DefaultPage.DefaultLayer.Entities.Add(group);

            mGroup = group;

            //select the newly created group
            CollectionBase <IDiagramEntity> col = new CollectionBase <IDiagramEntity>();

            col.Add(mGroup);
            Selection.SelectedItems = col;
            mGroup.Invalidate();
        }
Example #4
0
        /// <summary>
        /// Adds the given tool.
        /// </summary>
        /// <param name="tool">The tool.</param>
        public void AddTool(ITool tool)
        {
            tool.Controller = this;
            //add the tool to the collection even if it doesn't attach to anything (yet)
            registeredTools.Add(tool);

            IMouseListener mouseTool = null;

            if ((mouseTool = tool as IMouseListener) != null)
            {
                mouseListeners.Add(mouseTool);
            }

            IKeyboardListener keyboardTool = null;

            if ((keyboardTool = tool as IKeyboardListener) != null)
            {
                keyboardListeners.Add(keyboardTool);
            }

            IDragDropListener dragdropTool = null;

            if ((dragdropTool = tool as IDragDropListener) != null)
            {
                dragdropListeners.Add(dragdropTool);
            }
        }
Example #5
0
        /// <summary>
        /// Depth-first traversal of an <see cref="IGroup"/>
        /// </summary>
        /// <param name="group"></param>
        /// <param name="collection"></param>
        public static void TraverseCollect(IGroup group, ref CollectionBase <IDiagramEntity> collection)
        {
            #region Checks
            if (group == null)
            {
                throw new InconsistencyException("Cannot collect entities of a 'null' IGroup");
            }
            if (collection == null)
            {
                throw new InconsistencyException("You need to instantiate a collection before using this method.");
            }
            #endregion

            foreach (IDiagramEntity entity in group.Entities)
            {
                if (entity is IGroup)
                {
                    TraverseCollect(entity as IGroup, ref collection);
                }
                else
                {
                    collection.Add(entity);
                }
            }
        }
Example #6
0
        // ------------------------------------------------------------------
        /// <summary>
        /// Sets the current page.
        /// </summary>
        /// <param name="page">The page.</param>
        // ------------------------------------------------------------------
        public void SetCurrentPage(IPage page)
        {
            mCurrentPage = page;
            RaiseOnAmbienceChanged(new AmbienceEventArgs(page.Ambience));
            RaiseOnCurrentPageChanged(new PageEventArgs(page));

            //change the paintables as well
            //Paintables = new CollectionBase<IDiagramEntity>();

            #region Reload of the z-order, usually only necessary after deserialization

            CollectionBase <IDiagramEntity> collected = new CollectionBase <IDiagramEntity>();
            //pick up the non-group entities
            foreach (IDiagramEntity entity in Paintables)
            {
                if (!typeof(IGroup).IsInstanceOfType(entity))
                {
                    collected.Add(entity);
                }
            }

            if (collected.Count > 0)
            {
                Algorithms.SortInPlace <IDiagramEntity>(collected, new SceneIndexComparer <IDiagramEntity>());
                //Paintables.AddRange(collected);
            }
            #endregion
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="T:FolderMaterial"/> class.
        /// </summary>
        /// <param name="title">The title.</param>
        /// <param name="entries">The entries.</param>
        public FolderMaterial(string title, string[] entries)
            : this(title) {
            myTextStyle = new TextStyle(
                Color.Black,
                new Font("Arial", 10),
                StringAlignment.Near,
                StringAlignment.Near);
            IconLabelMaterial label;
            for (int k = 0; k < entries.Length; k++)
            {
                label = new IconLabelMaterial("Resources.Text.png", entries[k]);

                // We attach our ITextStyle to items when they're added to the
                // collection.
                mEntries.Add(label);
            }
            Collapse();
        }
        /// <summary>
        /// Returns a copy of this instance.
        /// </summary>
        /// <returns></returns>
        public CollectionBase <T> Copy()
        {
            CollectionBase <T> copy = new CollectionBase <T>();

            foreach (T item in this.innerList)
            {
                copy.Add(item);
            }
            return(copy);
        }
Example #9
0
        /// <summary>
        /// Default constructor
        /// </summary>
        public Model()
        {
            //here I'll have to work on the scene graph
            //this.mShapes = new CollectionBase<IShape>();
            //the default page

            //the page collection
            mPages = new CollectionBase <IPage>();
            mPages.Add(new Page("Default Page", this));

            Init();
        }
Example #10
0
        ///<summary>
        ///Default constructor
        ///</summary>
        public Page(string name, IModel model)
        {
            this.mModel = model;

            mName     = name;
            mAmbience = new Ambience(this);

            //the one and only and indestructible layer
            mLayers = new CollectionBase <ILayer>();
            mLayers.Add(new Layer("Default Layer"));

            Init();
        }
Example #11
0
 /// <summary>
 /// Handles the OnEntityAdded event of the Page and adds the new entity to the Paintables.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="T:Netron.Diagramming.Core.EntityEventArgs"/> instance containing the event data.</param>
 void mDefaultPage_OnEntityAdded(object sender, EntityEventArgs e)
 {
     //don't add it if it's already there or if it's a group (unless you want to deploy something special to emphasize a group shape).
     if (!mPaintables.Contains(e.Entity))
     {
         if ((e.Entity is IGroup) && !(e.Entity as IGroup).EmphasizeGroup)
         {
             return;
         }
         //set the new entity on top of the stack
         e.Entity.SceneIndex = mPaintables.Count;
         mPaintables.Add(e.Entity);
     }
     #region Addition callback
     IAdditionCallback callback = e.Entity.GetService(typeof(IAdditionCallback)) as IAdditionCallback;
     if (callback != null)
     {
         callback.OnAddition();
     }
     #endregion
     RaiseOnEntityAdded(e);
 }
Example #12
0
        /// <summary>
        /// Sets the items.
        /// </summary>
        /// <param name="editValue">The edit value.</param>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        protected override object SetItems(object editValue, object[] value)
        {
            CollectionBase <IShapeMaterial> entries = editValue as CollectionBase <IShapeMaterial>;

            entries.Clear();
            for (int k = 0; k < value.Length; k++)
            {
                entries.Add(value[k] as IShapeMaterial);
            }
            object retValue = base.SetItems(entries, value);

            return(retValue);
        }
Example #13
0
        /// <summary>
        /// Default constructor
        /// </summary>
        public Model()
        {
            //here I'll have to work on the scene graph
            //this.mShapes = new CollectionBase<IShape>();
            //the default page

            //the page collection
            mPages = new CollectionBase <IPage>();
            mPages.Add(new Page("Default Page", this));

            mConnectorHolders = new Dictionary <IConnector, IDiagramEntity>();

            Init();
        }
Example #14
0
        /// <summary>
        /// Handles the OnEntityAdded event of the Page and adds the new entity to the Paintables.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="T:Netron.Diagramming.Core.EntityEventArgs"/> instance containing the event data.</param>
        void mDefaultPage_OnEntityAdded(object sender, EntityEventArgs e)
        {
            IConnection cn = e.Entity as IConnection;

            if (cn != null)
            {
                mConnectorHolders.Add(cn.From, cn);
                mConnectorHolders.Add(cn.To, cn);
            }
            //IShape sp = e.Entity as IShape;
            //if(sp != null)
            //{
            //    foreach(IConnector cr in sp.Connectors)
            //        mConnectorHolders.Add(cr, sp);
            //}

            //don't add it if it's already there or if it's a group (unless you want to deploy something special to emphasize a group shape).
            if (!mPaintables.Contains(e.Entity))
            {
                if ((e.Entity is IGroup) && !(e.Entity as IGroup).EmphasizeGroup)
                {
                    return;
                }
                //set the new entity on top of the stack
                e.Entity.SceneIndex = mPaintables.Count;
                mPaintables.Add(e.Entity);
            }
            #region Addition callback
            IAdditionCallback callback = e.Entity.GetService(typeof(IAdditionCallback)) as IAdditionCallback;
            if (callback != null)
            {
                callback.OnAddition();
            }
            #endregion
            RaiseOnEntityAdded(e);
        }
Example #15
0
        // ------------------------------------------------------------------
        /// <summary>
        /// Default constructor
        /// </summary>
        // ------------------------------------------------------------------
        public Model()
        {
            //here I'll have to work on the scene graph
            //this.mShapes = new CollectionBase<IShape>();
            //the default page

            //the page collection
            mPages = new CollectionBase <IPage>();
            Page p = new Page("Default Page", this);

            p.Ambience.PageColor = ArtPalette.DefaultPageColor;
            mPages.Add(p);

            Init();
        }
Example #16
0
 /// <summary>
 /// Attaches the given connector to this connector.
 /// <remarks>The method will remove a previous binding, if any, before creating the attachment. This method prohibits mutliple identical connections;
 /// you can attach a connector only once.
 /// </remarks>
 /// </summary>
 /// <param name="connector"></param>
 public void AttachConnector(IConnector connector)
 {
     if (connector == null || !Enabled)
     {
         return;
     }
     //only attach'm if not already present and not the parent
     if (!attachedConnectors.Contains(connector) && connector != attachedTo)
     {
         connector.DetachFromParent();
         attachedConnectors.Add(connector);
         //make sure the attached connector is centered at this connector
         connector.Point      = this.mPoint;
         connector.AttachedTo = this;
     }
 }
Example #17
0
        /// <summary>
        /// Creates a new bundle using a given collection of diagram entities.
        /// </summary>
        /// <param name="collection"></param>
        public Bundle(CollectionBase <IDiagramEntity> collection)
        {
            mEntities = new CollectionBase <IDiagramEntity>();
            //we could assign it directly but let's make sure the collection does not
            //contain unwanted elements
            foreach (IDiagramEntity entity in collection)
            {
                if ((entity is IShape) || (entity is IConnection) || (entity is IGroup))
                {
                    mEntities.Add(entity);
                }
            }

            //the following line would give problem. The event handler attached to the Selection would be triggered when
            //the mEntities collection is changed!
            //mEntities = collection;
        }
Example #18
0
 internal void SelectEntity(IDiagramEntity entity, Point surfacePoint)
 {
     // Groups are treated specially because we can drill-down
     // into the group.  The process of drilling is the first
     // mouse hit will select the group.  The second mouse hit
     // will select a child, if there's a child at that point.
     if (entity is IGroup)
     {
         if (entity.IsSelected == false)
         {
             entity.IsSelected = true;
             mSelection.Add(entity);
         }
         else
         {
             IGroup group = entity as IGroup;
             for (int j = group.Entities.Count - 1; j >= 0; j--)
             {
                 IDiagramEntity child = group.Entities[j];
                 if (child.Hit(surfacePoint))
                 {
                     // Repeat the process because what if this
                     // child is too a group!
                     SelectEntity(child, surfacePoint);
                     group.IsSelected = false;
                     if (mSelection.Contains(group))
                     {
                         mSelection.Remove(group);
                     }
                     break;
                 }
             }
         }
     }
     //else if (entity.Group != null)
     //{
     //    //entity.Group.IsSelected = true;
     //    //mSelection.Add(entity.Group);
     //}
     else
     {
         entity.IsSelected = true;
         mSelection.Add(entity);
     }
 }
Example #19
0
 /// <summary>
 /// Adds the given activity to the controller.
 /// </summary>
 /// <param name="activity">The activity.</param>
 public void AddActivity(IActivity activity)
 {
     registeredActivity.Add(activity);
 }
Example #20
0
        // ------------------------------------------------------------------
        /// <summary>
        /// Initialize of the bundle
        /// </summary>
        // ------------------------------------------------------------------
        protected override void Initialize()
        {
            base.Initialize();
            Name           = "Class Shape";
            mTitle         = "Class shape";
            mSubTitle      = "by The Netron Project";
            this.Resizable = false;
            sf.Trimming    = StringTrimming.EllipsisCharacter;
            //the initial size
            Transform(0, 0, 200, 50);


            //mList.OnItemAdded += new EventHandler<CollectionEventArgs<ClassShapeItem>>(mList_OnItemAdded);

            #region The icon material
            CreateShapeIcon();
            #endregion

            #region The xpand icon material
            CreateXpansionIcon();
            #endregion

            #region The free text
            textMaterial = new LabelMaterial();
            textMaterial.Transform(new Rectangle(Rectangle.X + 5, Rectangle.Y + 18, Rectangle.Width - 10, bodyHeight));
            textMaterial.Text    = GetQuotation();
            textMaterial.Visible = false;
            Children.Add(textMaterial);

            #endregion

            #region The folders

            /* The following code is only an example of what is possible.
             * You can add any shape material here but I guess the properties/methods nodes
             * are quite useful for many purposes.
             */

            string[]       props   = new string[] { "Rectangle", "Size", "Visible" };
            FolderMaterial folder1 = new FolderMaterial("Properties", props, "Resources.PublicProperty.ico");
            folder1.Transform(new Rectangle(Rectangle.X + 5, Rectangle.Y + 55, Rectangle.Width - 10, FolderMaterial.HeaderHeight));
            folder1.Visible   = false;
            folder1.ShowLines = true;
            mFolders.Add(folder1);
            folder1.OnFolderChanged += new EventHandler <RectangleEventArgs>(folders_OnFolderChanged);
            Children.Add(folder1);
            mPropertiesNode = folder1;

            string[]       methds  = new string[] { "Invalidate", "Transform", "Update", "Reset", "Delete" };
            FolderMaterial folder2 = new FolderMaterial("Methods", methds, "Resources.PublicMethod.ico");
            folder2.Transform(new Rectangle(Rectangle.X + 5, Rectangle.Y + 55 + FolderMaterial.HeaderHeight + 10, Rectangle.Width - 10, FolderMaterial.HeaderHeight));
            folder2.Visible   = false;
            folder2.ShowLines = true;
            mFolders.Add(folder2);
            folder2.OnFolderChanged += new EventHandler <RectangleEventArgs>(folders_OnFolderChanged);
            Children.Add(folder2);
            mMethodsNode = folder2;

            #region this calculates the initial body height


            foreach (FolderMaterial folder in mFolders)
            {
                bodyHeight += folder.Rectangle.Height + 3;
            }

            //UpdateBody();
            #endregion

            #endregion

            #region Connectors
            cTop        = new Connector(new Point((int)(Rectangle.Left + Rectangle.Width / 2), Rectangle.Top), Model);
            cTop.Name   = "Top connector";
            cTop.Parent = this;
            Connectors.Add(cTop);

            cRight        = new Connector(new Point(Rectangle.Right, (int)(Rectangle.Top + Rectangle.Height / 2)), Model);
            cRight.Name   = "Right connector";
            cRight.Parent = this;
            Connectors.Add(cRight);

            cBottom        = new Connector(new Point((int)(Rectangle.Left + Rectangle.Width / 2), Rectangle.Bottom), Model);
            cBottom.Name   = "Bottom connector";
            cBottom.Parent = this;
            Connectors.Add(cBottom);

            cLeft        = new Connector(new Point(Rectangle.Left, (int)(Rectangle.Top + Rectangle.Height / 2)), Model);
            cLeft.Name   = "Left connector";
            cLeft.Parent = this;
            Connectors.Add(cLeft);
            #endregion
        }
        private CollectionBase <INode> sortedChildren(INode n)
        {
            double basevalue = 0;
            // update basevalue angle for node ordering
            INode p = n.ParentNode;

            if (p != null)
            {
                basevalue = normalize(Math.Atan2(p.Y - n.Y, p.X - n.X));
            }
            int cc = n.ChildCount;

            if (cc == 0)
            {
                return(null);
            }

            INode c = (INode)n.FirstChild;

            // TODO: this is hacky and will break when filtering
            // how to know that a branch is newly expanded?
            // is there an alternative property we should check?
            //if ( !c.isStartVisible() )
            //{
            //    // use natural ordering for previously invisible nodes
            //    return n.Children;
            //}



            double[] angle = new double[cc];
            int[]    idx   = new int[cc];
            for (int i = 0; i < cc; ++i, c = c.NextSibling)
            {
                idx[i]   = i;
                angle[i] = normalize(-basevalue + Math.Atan2(c.Y - n.Y, c.X - n.X));
            }

            Array.Sort(angle, idx);//or is it the other way around
            CollectionBase <INode> col      = new CollectionBase <INode>();
            CollectionBase <INode> children = n.Children;

            for (int i = 0; i < cc; ++i)
            {
                col.Add(children[idx[i]]);
            }
            return(col);

            // return iterator over sorted children
            //return new Iterator() {
            //    int cur = 0;
            //    public Object next() {
            //        return n.getChild(idx[cur++]);
            //    }
            //    public bool hasNext() {
            //        return cur < idx.Length;
            //    }
            //    public void remove() {
            //        throw new UnsupportedOperationException();
            //    }
            //};
        }
Example #22
0
        /// <summary>
        /// Collects the shapes at the given (transformed surface) location.
        /// The shapes selected in this way are available
        /// </summary>
        /// <param name="surfacePoint">The surface point.</param>
        public static void CollectEntitiesAt(Point surfacePoint)
        {
            if (surfacePoint == Point.Empty)
            {
                return;
            }
            if (Selection.mController == null)
            {
                return;
            }

            //only change the current selection if the mouse did not hit an already selected element
            if (mSelection.Count > 0)
            {
                foreach (IDiagramEntity entity in mSelection)
                {
                    if (entity.Rectangle.Contains(surfacePoint))
                    {
                        return;
                    }
                }
            }

            //here the scene-graph will play a role in the future,
            //for now we'll keep is simple
            Selection.Clear();

            IConnection con;
            IShape      sh;

            //we use the paintables here rather than traversing the scene-graph because only
            //visible things can be collected
            //We traverse the paintables from top to bottom since the highest z-order
            //is at the top of the stack.

            for (int k = Model.Paintables.Count - 1; k >= 0; k--)
            {
                IDiagramEntity entity = Model.Paintables[k];

                #region we give priority to the connector selection
                if (typeof(IConnection).IsInstanceOfType(entity))
                {
                    con = entity as IConnection;
                    if (con.From.Hit(surfacePoint))
                    {
                        connector            = con.From;
                        connector.IsSelected = true;
                        Invalidate();
                        return;
                    }
                    if (con.To.Hit(surfacePoint))
                    {
                        connector            = con.To;
                        connector.IsSelected = true;
                        Invalidate();
                        return;
                    }
                }
                else if (entity is IGroup)
                {
                    //should I care about the connectors at this point...?
                }
                else if (entity is IShape)
                {
                    sh = entity as IShape;
                    foreach (IConnector cn in sh.Connectors)
                    {
                        //if there are connectors attached to the shape connector, the attached ones should be picked up and not the one of the shape
                        if (cn.Hit(surfacePoint) && cn.AttachedConnectors.Count == 0)
                        {
                            connector            = cn;
                            connector.IsSelected = true;
                            Invalidate(); //this will invalidate only the selected connector
                            return;       //we hit a connector and quit the selection. If the user intended to select the entity it had to be away from the connector!
                        }
                    }
                }

                #endregion

                #region no connector was hit, maybe the entity itself
                if (entity.Hit(surfacePoint))
                {
                    //if the entity is part of an IGroup, the IGroup should be selected
                    //rather than the entity itself
                    //Note that the Group property returns the top group parent and not
                    //just the immediate parent of an entity
                    if (entity.Group != null)
                    {
                        entity.Group.IsSelected = true;
                        mSelection.Add(entity.Group);
                    }
                    else
                    {
                        entity.IsSelected = true;
                        mSelection.Add(entity);
                    }


                    break;
                }
                #endregion
            }
            RaiseOnNewSelection();
            Invalidate();

            //Using a full invalidate is rather expensive, so we'll only refresh the current selection
            //Controller.View.Invalidate();
        }
Example #23
0
 // ------------------------------------------------------------------
 /// <summary>
 /// Adds a page.  This should be used when adding pages rather than
 /// though the Pages property so the page gets attached to the Model.
 /// </summary>
 /// <param name="page">IPage: The page to add.</param>
 /// <returns>IPage</returns>
 // ------------------------------------------------------------------
 public IPage AddPage(IPage page)
 {
     mPages.Add(page);
     AttachToPage(page);
     return(page);
 }