PowerPoint like grouping

Our customer wants to group objects as PowerPoint does. After grouping several objects<?:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

· Click one object, the group box is selected

· With the group box selected

o Click the object inside the group, the object is selected also

o Click another object, this one is selected and the previous one is de-selected

· The object inside the group is selected

o Move it, the group box is resized automatically

o Resize it, the group box is resized automatically

What is the best approach to implement this requirement? Could you give me some code samples? Any suggestions are helpful also. This is for GoDiagram Win 4.0.

Thank you.

Sure, shouldn’t be too hard. Give me some time to play with it…

Do you see any difference between shift-click and ctrl-click in PowerPoint? If there is, I’m not seeing it.



Is multiple selection of objects with a group a requirement?

Do you see any difference between shift-click and ctrl-click in PowerPoint? If there is, I’m not seeing it.

No, I did not see the differences either.

Is multiple selection of objects with a group a requirement?
Yes, it is.

well, that was interesting.



this works pretty well. When combined with DragsRealTime = false, it looks pretty similar, except GoDiagram will hide the selection handles during a drag.



There are some cases with multiple groups selected that this doesn’t handle the same as PowerPoint. (this code doesn’t prevent an object within a group being selected when another group elsewhere is selected.)



select these tools with:



view.ReplaceMouseTool(typeof(GoToolSelecting), new PowerPointSelectingTool(view));

view.ReplaceMouseTool(typeof(GoToolDragging), new PowerPointDraggingTool(view));





<br /> <br /> // Powerpoint will allow you to select an object within a Group and leave the <br /> // group itself selected. move and resize the object will resize group to fit (which is what GoDiagram does by default) <br /> // see: http://www.nwoods.com/forum/forum_posts.asp?TID=3412 <br /> [Serializable] <br /> public class PowerPointSelectingTool : GoToolSelecting { <br /> public PowerPointSelectingTool(GoView v) : base(v) { } <br /> <br /> public override void DoSelect(GoInputEventArgs evt) { <br /> <br /> GoObject picked = this.View.PickObject(true, false, evt.DocPoint, true); // only selectable document objects <br /> <br /> if (picked != null && picked is GoShape && picked.Parent != null) { <br /> if (this.View.Selection.Contains(picked.Parent)) { <br /> // click on object within Group, and that group is already selected. <br /> // first, deselect any other object within group (unless shift-click) <br /> if (!evt.Shift) { <br /> // deselect any other object within this group that is selected. <br /> foreach (GoObject child in picked.Parent) { <br /> if (this.View.Selection.Contains(child)) this.Selection.Remove(child); <br /> } <br /> } <br /> // now select object within group (and leave group selected) <br /> this.CurrentObject = picked; <br /> this.Selection.Add(picked); <br /> } <br /> else { <br /> // click on object within group, but group not selected yet. ... select group <br /> this.CurrentObject = picked.Parent; <br /> //this.CurrentObjectWasSelected = this.View.Selection.Contains(this.CurrentObject); <br /> if (this.CurrentObject != null) { <br /> if (evt.Control) { <br /> this.Selection.Toggle(this.CurrentObject); <br /> } <br /> else if (evt.Shift) { <br /> this.Selection.Add(this.CurrentObject); <br /> } <br /> else { <br /> this.Selection.Select(this.CurrentObject); <br /> } <br /> } <br /> } <br /> } <br /> else { <br /> // not a shape within a group ... do the default GoDiagram thing. <br /> base.DoSelect(evt); <br /> } <br /> } <br /> } <br /> <br /> [Serializable] <br /> public class PowerPointDraggingTool : GoToolDragging { <br /> <br /> public PowerPointDraggingTool(GoView v) : base(v) { <br /> } <br /> <br /> public override void Start() { <br /> <br /> if (this.SelectsWhenStarts) { <br /> this.CurrentObject = this.View.PickObject(true, false, this.FirstInput.DocPoint, true); <br /> if (this.CurrentObject == null) <br /> return; <br /> <br /> // if the group was selected, but no objects within group, we want to drag group. <br /> <br /> bool childSelected = false; <br /> if (this.CurrentObject is GoShape && this.CurrentObject.Parent != null) { <br /> foreach (GoObject child in this.CurrentObject.Parent) { <br /> if (this.Selection.Contains(child)) { <br /> childSelected = true; <br /> if (!(this.FirstInput.Shift || this.FirstInput.Control)) this.Selection.Remove(child); <br /> } <br /> } <br /> if (childSelected) { <br /> this.Selection.Add(this.CurrentObject); // add mouse-downed shape to selection <br /> <br /> //?? should make sure no other separate groups are selected here? <br /> } <br /> else { <br /> // no child selected, drag group <br /> this.CurrentObject = this.CurrentObject.Parent; <br /> } <br /> } <br /> // remember the offset within the current object <br /> this.MoveOffset = SubtractPoints(this.FirstInput.DocPoint, this.CurrentObject.Position); <br /> } <br /> StartTransaction(); <br /> <br /> if (this.SelectsWhenStarts) { <br /> // we don't call DoSelect because we don't want the Control modifier to unselect <br /> // an already selected object <br /> if (!this.Selection.Contains(this.CurrentObject)) { <br /> if (this.FirstInput.Shift || this.FirstInput.Control) <br /> this.Selection.Add(this.CurrentObject); <br /> else <br /> this.Selection.Select(this.CurrentObject); <br /> } <br /> } <br /> this.SelectsWhenStarts = false; <br /> base.Start(); <br /> } <br /> <br /> public override GoSelection ComputeEffectiveSelection(IGoCollection coll, bool move) { <br /> <br /> // if both a GoGroup and a GoObject within that group are selected, remove the GoGroup from <br /> // the effective selection. (ComputeEffectiveSelection does the opposite... it removes the child) <br /> <br /> GoCollection groups = new GoCollection(); <br /> GoCollection safecoll = new GoCollection(); <br /> <br /> foreach (GoObject obj in coll) { <br /> safecoll.Add(obj); <br /> if (obj is GoShape && obj.Parent != null && coll.Contains(obj.Parent)) { <br /> groups.Add(obj.Parent); <br /> } <br /> } <br /> foreach (GoObject group in groups) { <br /> safecoll.Remove(group); <br /> } <br /> <br /> return base.ComputeEffectiveSelection(safecoll, move); <br /> } <br /> } <br />

Jake,

I will start from your code and make it suitable to our application.
I am really appreciating your help.