Browse Source

Create controls immediately when dragging from the toolbox

TODO: cursor should be in the center of the control

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@3528 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Ivan Shumilin 17 years ago
parent
commit
110e3d9954
  1. 5
      samples/XamlDesigner/Document.cs
  2. 9
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfViewContent.cs
  3. 126
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/CreateComponentTool.cs
  4. 107
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/DragMoveMouseGesture.cs
  5. 140
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/MoveLogic.cs
  6. 1
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj

5
samples/XamlDesigner/Document.cs

@ -146,7 +146,10 @@ namespace ICSharpCode.XamlDesigner @@ -146,7 +146,10 @@ namespace ICSharpCode.XamlDesigner
public XamlErrorService XamlErrorService {
get {
return DesignContext.Services.GetService<XamlErrorService>();
if (DesignContext != null) {
return DesignContext.Services.GetService<XamlErrorService>();
}
return null;
}
}

9
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/WpfViewContent.cs

@ -152,16 +152,9 @@ namespace ICSharpCode.WpfDesign.AddIn @@ -152,16 +152,9 @@ namespace ICSharpCode.WpfDesign.AddIn
propertyContainer.PropertyGridReplacementControl = propertyEditorHost;
}
ICollection<DesignItem> oldItems = new DesignItem[0];
void OnSelectionChanged(object sender, DesignItemCollectionEventArgs e)
{
ISelectionService selectionService = designer.DesignContext.Services.Selection;
ICollection<DesignItem> items = selectionService.SelectedItems;
if (!IsCollectionWithSameElements(items, oldItems)) {
propertyGridView.PropertyGrid.SelectedItems = items;
oldItems = items;
}
propertyGridView.PropertyGrid.SelectedItems = DesignContext.Services.Selection.SelectedItems;
}
static bool IsCollectionWithSameElements(ICollection<DesignItem> a, ICollection<DesignItem> b)

126
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/CreateComponentTool.cs

@ -20,6 +20,9 @@ namespace ICSharpCode.WpfDesign.Designer.Services @@ -20,6 +20,9 @@ namespace ICSharpCode.WpfDesign.Designer.Services
public class CreateComponentTool : ITool
{
readonly Type componentType;
MoveLogic moveLogic;
ChangeGroup changeGroup;
Point createPoint;
/// <summary>
/// Creates a new CreateComponentTool instance.
@ -45,16 +48,89 @@ namespace ICSharpCode.WpfDesign.Designer.Services @@ -45,16 +48,89 @@ namespace ICSharpCode.WpfDesign.Designer.Services
public void Activate(IDesignPanel designPanel)
{
designPanel.MouseDown += OnMouseDown;
designPanel.DragOver += OnDragOver;
designPanel.Drop += OnDrop;
//designPanel.DragEnter += designPanel_DragOver;
designPanel.DragOver += designPanel_DragOver;
designPanel.Drop += designPanel_Drop;
designPanel.DragLeave += designPanel_DragLeave;
}
public void Deactivate(IDesignPanel designPanel)
{
designPanel.MouseDown -= OnMouseDown;
designPanel.DragOver -= OnDragOver;
designPanel.Drop -= OnDrop;
//designPanel.DragEnter -= designPanel_DragOver;
designPanel.DragOver -= designPanel_DragOver;
designPanel.Drop -= designPanel_Drop;
designPanel.DragLeave -= designPanel_DragLeave;
}
void designPanel_DragOver(object sender, DragEventArgs e)
{
try {
IDesignPanel designPanel = (IDesignPanel)sender;
e.Effects = DragDropEffects.Copy;
e.Handled = true;
Point p = e.GetPosition(designPanel);
if (moveLogic == null) {
if (e.Data.GetData(typeof(CreateComponentTool)) != this) return;
// TODO: dropLayer in designPanel
designPanel.IsAdornerLayerHitTestVisible = false;
DesignPanelHitTestResult result = designPanel.HitTest(p, false, true);
if (result.ModelHit != null) {
designPanel.Focus();
DesignItem createdItem = CreateItem(designPanel.Context);
if (AddItemWithDefaultSize(result.ModelHit, createdItem, e.GetPosition(result.ModelHit.View))) {
moveLogic = new MoveLogic(createdItem);
createPoint = p;
} else {
changeGroup.Abort();
}
}
} else if ((moveLogic.ClickedOn.View as FrameworkElement).IsLoaded) {
if (moveLogic.Operation == null) {
moveLogic.Start(createPoint);
} else {
moveLogic.Move(p);
}
}
} catch (Exception x) {
DragDropExceptionHandler.HandleException(x);
}
}
void designPanel_Drop(object sender, DragEventArgs e)
{
try {
if (moveLogic != null) {
moveLogic.Stop();
if (moveLogic.ClickedOn.Services.Tool.CurrentTool is CreateComponentTool) {
moveLogic.ClickedOn.Services.Tool.CurrentTool = moveLogic.ClickedOn.Services.Tool.PointerTool;
}
moveLogic.DesignPanel.IsAdornerLayerHitTestVisible = true;
moveLogic = null;
changeGroup.Commit();
}
} catch (Exception x) {
DragDropExceptionHandler.HandleException(x);
}
}
void designPanel_DragLeave(object sender, DragEventArgs e)
{
try {
if (moveLogic != null) {
moveLogic.Cancel();
moveLogic.ClickedOn.Services.Selection.SetSelectedComponents(null);
moveLogic.DesignPanel.IsAdornerLayerHitTestVisible = true;
moveLogic = null;
changeGroup.Abort();
}
} catch (Exception x) {
DragDropExceptionHandler.HandleException(x);
}
}
/// <summary>
/// Is called to create the item used by the CreateComponentTool.
@ -63,54 +139,18 @@ namespace ICSharpCode.WpfDesign.Designer.Services @@ -63,54 +139,18 @@ namespace ICSharpCode.WpfDesign.Designer.Services
{
object newInstance = context.Services.ExtensionManager.CreateInstanceWithCustomInstanceFactory(componentType, null);
DesignItem item = context.Services.Component.RegisterComponentForDesigner(newInstance);
changeGroup = item.OpenGroup("Drop Control");
context.Services.ExtensionManager.ApplyDefaultInitializers(item);
return item;
}
void OnDragOver(object sender, DragEventArgs e)
{
try {
if (e.Data.GetData(typeof(CreateComponentTool)) == this) {
e.Effects = DragDropEffects.Copy;
e.Handled = true;
} else {
e.Effects = DragDropEffects.None;
}
} catch (Exception ex) {
DragDropExceptionHandler.HandleException(ex);
}
}
void OnDrop(object sender, DragEventArgs e)
{
try {
if (e.Data.GetData(typeof(CreateComponentTool)) != this)
return;
e.Handled = true;
IDesignPanel designPanel = (IDesignPanel)sender;
DesignPanelHitTestResult result = designPanel.HitTest(e.GetPosition(designPanel), false, true);
if (result.ModelHit != null) {
designPanel.Focus();
DesignItem createdItem = CreateItem(designPanel.Context);
AddItemWithDefaultSize(result.ModelHit, createdItem, e.GetPosition(result.ModelHit.View));
}
if (designPanel.Context.Services.Tool.CurrentTool is CreateComponentTool) {
designPanel.Context.Services.Tool.CurrentTool = designPanel.Context.Services.Tool.PointerTool;
}
} catch (Exception ex) {
DragDropExceptionHandler.HandleException(ex);
}
}
internal static bool AddItemWithDefaultSize(DesignItem container, DesignItem createdItem, Point position)
{
var size = ModelTools.GetDefaultSize(createdItem);
PlacementOperation operation = PlacementOperation.TryStartInsertNewComponents(
container,
new DesignItem[] { createdItem },
new Rect[] { new Rect(position, ModelTools.GetDefaultSize(createdItem)) },
new Rect[] { new Rect(position, size) },
PlacementType.AddItem
);
if (operation != null) {

107
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/DragMoveMouseGesture.cs

@ -19,137 +19,48 @@ namespace ICSharpCode.WpfDesign.Designer.Services @@ -19,137 +19,48 @@ namespace ICSharpCode.WpfDesign.Designer.Services
/// </summary>
sealed class DragMoveMouseGesture : ClickOrDragMouseGesture
{
readonly DesignItem clickedOn;
PlacementOperation operation;
ICollection<DesignItem> selectedItems;
bool isDoubleClick;
MoveLogic moveLogic;
internal DragMoveMouseGesture(DesignItem clickedOn, bool isDoubleClick)
{
Debug.Assert(clickedOn != null);
this.clickedOn = clickedOn;
this.isDoubleClick = isDoubleClick;
if (clickedOn.Parent != null)
this.positionRelativeTo = clickedOn.Parent.View;
else
this.positionRelativeTo = clickedOn.View;
selectedItems = clickedOn.Services.Selection.SelectedItems;
if (!selectedItems.Contains(clickedOn))
selectedItems = SharedInstances.EmptyDesignItemArray;
moveLogic = new MoveLogic(clickedOn);
}
protected override void OnDragStarted(MouseEventArgs e)
{
IPlacementBehavior b = PlacementOperation.GetPlacementBehavior(selectedItems);
if (b != null && b.CanPlace(selectedItems, PlacementType.Move, PlacementAlignment.TopLeft)) {
List<DesignItem> sortedSelectedItems = new List<DesignItem>(selectedItems);
sortedSelectedItems.Sort(ModelTools.ComparePositionInModelFile);
selectedItems = sortedSelectedItems;
operation = PlacementOperation.Start(selectedItems, PlacementType.Move);
}
moveLogic.Start(startPoint);
}
protected override void OnMouseMove(object sender, MouseEventArgs e)
{
base.OnMouseMove(sender, e); // call OnDragStarted if min. drag distace is reached
if (operation != null) {
UIElement currentContainer = operation.CurrentContainer.View;
Point p = e.GetPosition(currentContainer);
// try to switch the container
if (operation.CurrentContainerBehavior.CanLeaveContainer(operation)) {
ChangeContainerIfPossible(e);
}
Vector v = e.GetPosition(positionRelativeTo) - startPoint;
foreach (PlacementInformation info in operation.PlacedItems) {
info.Bounds = new Rect(info.OriginalBounds.Left + v.X,
info.OriginalBounds.Top + v.Y,
info.OriginalBounds.Width,
info.OriginalBounds.Height);
}
operation.CurrentContainerBehavior.BeforeSetPosition(operation);
foreach (PlacementInformation info in operation.PlacedItems) {
operation.CurrentContainerBehavior.SetPosition(info);
}
}
}
// Perform hit testing on the design panel and return the first model that is not selected
DesignPanelHitTestResult HitTestUnselectedModel(MouseEventArgs e)
{
DesignPanelHitTestResult result = DesignPanelHitTestResult.NoHit;
ISelectionService selection = services.Selection;
designPanel.HitTest(
e.GetPosition(designPanel), false, true,
delegate(DesignPanelHitTestResult r) {
if (r.ModelHit == null)
return true; // continue hit testing
if (selection.IsComponentSelected(r.ModelHit))
return true; // continue hit testing
result = r;
return false; // finish hit testing
});
return result;
}
bool ChangeContainerIfPossible(MouseEventArgs e)
{
DesignPanelHitTestResult result = HitTestUnselectedModel(e);
if (result.ModelHit == null) return false;
if (result.ModelHit == operation.CurrentContainer) return false;
// check that we don't move an item into itself:
DesignItem tmp = result.ModelHit;
while (tmp != null) {
if (tmp == clickedOn) return false;
tmp = tmp.Parent;
}
IPlacementBehavior b = result.ModelHit.GetBehavior<IPlacementBehavior>();
if (b != null && b.CanEnterContainer(operation)) {
operation.ChangeContainer(result.ModelHit);
return true;
}
return false;
moveLogic.Move(e.GetPosition(positionRelativeTo));
}
protected override void OnMouseUp(object sender, MouseButtonEventArgs e)
{
if (!hasDragStarted && isDoubleClick) {
// user made a double-click
Debug.Assert(operation == null);
HandleDoubleClick();
}
if (operation != null) {
operation.Commit();
operation = null;
Debug.Assert(moveLogic.Operation == null);
moveLogic.HandleDoubleClick();
}
moveLogic.Stop();
Stop();
}
protected override void OnStopped()
{
if (operation != null) {
operation.Abort();
operation = null;
}
}
void HandleDoubleClick()
{
if (selectedItems.Count == 1) {
IEventHandlerService ehs = services.GetService<IEventHandlerService>();
if (ehs != null) {
DesignItemProperty defaultEvent = ehs.GetDefaultEvent(clickedOn);
if (defaultEvent != null) {
ehs.CreateEventHandler(defaultEvent);
}
}
}
moveLogic.Cancel();
}
}
}

140
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/MoveLogic.cs

@ -0,0 +1,140 @@ @@ -0,0 +1,140 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
namespace ICSharpCode.WpfDesign.Designer.Services
{
class MoveLogic
{
public MoveLogic(DesignItem clickedOn)
{
this.clickedOn = clickedOn;
selectedItems = clickedOn.Services.Selection.SelectedItems;
if (!selectedItems.Contains(clickedOn))
selectedItems = SharedInstances.EmptyDesignItemArray;
}
DesignItem clickedOn;
PlacementOperation operation;
ICollection<DesignItem> selectedItems;
Point startPoint;
public DesignItem ClickedOn {
get { return clickedOn; }
}
public PlacementOperation Operation {
get { return operation; }
}
public IDesignPanel DesignPanel {
get { return clickedOn.Services.DesignPanel; }
}
public void Start(Point p)
{
startPoint = p;
IPlacementBehavior b = PlacementOperation.GetPlacementBehavior(selectedItems);
if (b != null && b.CanPlace(selectedItems, PlacementType.Move, PlacementAlignment.TopLeft)) {
List<DesignItem> sortedSelectedItems = new List<DesignItem>(selectedItems);
sortedSelectedItems.Sort(ModelTools.ComparePositionInModelFile);
selectedItems = sortedSelectedItems;
operation = PlacementOperation.Start(selectedItems, PlacementType.Move);
}
}
public void Move(Point p)
{
if (operation != null) {
// try to switch the container
if (operation.CurrentContainerBehavior.CanLeaveContainer(operation)) {
ChangeContainerIfPossible(p);
}
Vector v = p - startPoint;
foreach (PlacementInformation info in operation.PlacedItems) {
info.Bounds = new Rect(info.OriginalBounds.Left + v.X,
info.OriginalBounds.Top + v.Y,
info.OriginalBounds.Width,
info.OriginalBounds.Height);
}
operation.CurrentContainerBehavior.BeforeSetPosition(operation);
foreach (PlacementInformation info in operation.PlacedItems) {
operation.CurrentContainerBehavior.SetPosition(info);
}
}
}
public void Stop()
{
if (operation != null) {
operation.Commit();
operation = null;
}
}
public void Cancel()
{
if (operation != null) {
operation.Abort();
operation = null;
}
}
// Perform hit testing on the design panel and return the first model that is not selected
DesignPanelHitTestResult HitTestUnselectedModel(Point p)
{
DesignPanelHitTestResult result = DesignPanelHitTestResult.NoHit;
ISelectionService selection = clickedOn.Services.Selection;
DesignPanel.HitTest(p, false, true, delegate(DesignPanelHitTestResult r) {
if (r.ModelHit == null)
return true; // continue hit testing
if (selection.IsComponentSelected(r.ModelHit))
return true; // continue hit testing
result = r;
return false; // finish hit testing
});
return result;
}
bool ChangeContainerIfPossible(Point p)
{
DesignPanelHitTestResult result = HitTestUnselectedModel(p);
if (result.ModelHit == null) return false;
if (result.ModelHit == operation.CurrentContainer) return false;
// check that we don't move an item into itself:
DesignItem tmp = result.ModelHit;
while (tmp != null) {
if (tmp == clickedOn) return false;
tmp = tmp.Parent;
}
IPlacementBehavior b = result.ModelHit.GetBehavior<IPlacementBehavior>();
if (b != null && b.CanEnterContainer(operation)) {
operation.ChangeContainer(result.ModelHit);
return true;
}
return false;
}
public void HandleDoubleClick()
{
if (selectedItems.Count == 1) {
IEventHandlerService ehs = clickedOn.Services.GetService<IEventHandlerService>();
if (ehs != null) {
DesignItemProperty defaultEvent = ehs.GetDefaultEvent(clickedOn);
if (defaultEvent != null) {
ehs.CreateEventHandler(defaultEvent);
}
}
}
}
}
}

1
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj

@ -180,6 +180,7 @@ @@ -180,6 +180,7 @@
<Compile Include="Services\DragMoveMouseGesture.cs" />
<Compile Include="Services\ErrorService.cs" />
<Compile Include="Services\MouseGestureBase.cs" />
<Compile Include="Services\MoveLogic.cs" />
<Compile Include="Services\OptionService.cs">
<SubType>Code</SubType>
</Compile>

Loading…
Cancel
Save