Drag&drop fixes
This commit is contained in:
Родитель
238e7ce116
Коммит
6f929d4b9e
|
@ -1,10 +1,12 @@
|
|||
using System;
|
||||
using Xwt;
|
||||
using Xwt.Drawing;
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
public class DragDrop: VBox
|
||||
{
|
||||
Button b2;
|
||||
public DragDrop ()
|
||||
{
|
||||
HBox box = new HBox ();
|
||||
|
@ -12,12 +14,15 @@ namespace Samples
|
|||
SimpleBox b1 = new SimpleBox (30);
|
||||
box.PackStart (b1, BoxMode.None);
|
||||
|
||||
Button b2 = new Button ("Drop here");
|
||||
b2 = new Button ("Drop here");
|
||||
box.PackEnd (b2, BoxMode.None);
|
||||
|
||||
b1.ButtonPressed += delegate {
|
||||
var d = b1.CreateDragOperation ();
|
||||
d.Data.AddValue ("Hola");
|
||||
var img = Image.FromResource (GetType(), "class.png");
|
||||
d.SetDragImage (img, (int)img.Size.Width, (int)img.Size.Height);
|
||||
d.AllowedActions = DragDropAction.All;
|
||||
d.Start ();
|
||||
};
|
||||
|
||||
|
@ -25,13 +30,12 @@ namespace Samples
|
|||
PackStart (box);
|
||||
|
||||
b2.DragDrop += HandleB2DragDrop;
|
||||
// b2.DragOver += HandleB2DragOver;
|
||||
b2.DragOver += HandleB2DragOver;
|
||||
}
|
||||
|
||||
void HandleB2DragOver (object sender, DragOverEventArgs e)
|
||||
{
|
||||
Console.WriteLine ("Drag over");
|
||||
e.AllowedAction = DragDropAction.Copy | DragDropAction.Move | DragDropAction.Link;
|
||||
e.AllowedAction = e.Action;
|
||||
}
|
||||
|
||||
void HandleB2DragDrop (object sender, DragEventArgs e)
|
||||
|
@ -42,6 +46,7 @@ namespace Samples
|
|||
foreach (var u in e.Data.Uris)
|
||||
Console.WriteLine ("u:" + u);
|
||||
e.Success = true;
|
||||
b2.Label = "Dropped!";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,6 +71,39 @@ namespace Xwt.GtkBackend
|
|||
var pix = (Gdk.Pixbuf)handle;
|
||||
return pix.ScaleSimple ((int)width, (int)height, Gdk.InterpType.Bilinear);
|
||||
}
|
||||
|
||||
public override object Copy (object handle)
|
||||
{
|
||||
var pix = (Gdk.Pixbuf)handle;
|
||||
return pix.Copy ();
|
||||
}
|
||||
|
||||
public override void CopyArea (object srcHandle, int srcX, int srcY, int width, int height, object destHandle, int destX, int destY)
|
||||
{
|
||||
var pixSrc = (Gdk.Pixbuf)srcHandle;
|
||||
var pixDst = (Gdk.Pixbuf)destHandle;
|
||||
pixSrc.CopyArea (srcX, srcY, width, height, pixDst, destX, destY);
|
||||
}
|
||||
|
||||
public override object Crop (object handle, int srcX, int srcY, int width, int height)
|
||||
{
|
||||
var pix = (Gdk.Pixbuf)handle;
|
||||
Gdk.Pixbuf res = new Gdk.Pixbuf (pix.Colorspace, pix.HasAlpha, pix.BitsPerSample, width, height);
|
||||
res.Fill (0);
|
||||
Console.WriteLine ("pp:" + srcX + " " + srcY + " " + width + " " + height);
|
||||
pix.CopyArea (srcX, srcY, width, height, res, 0, 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
public override object ChangeOpacity (object backend, double opacity)
|
||||
{
|
||||
Gdk.Pixbuf image = (Gdk.Pixbuf) backend;
|
||||
Gdk.Pixbuf result = image.Copy ();
|
||||
result.Fill (0);
|
||||
result = result.AddAlpha (true, 0, 0, 0);
|
||||
image.Composite (result, 0, 0, image.Width, image.Height, 0, 0, 1, 1, Gdk.InterpType.Bilinear, (int)(255 * opacity));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -299,11 +299,13 @@ namespace Xwt.GtkBackend
|
|||
res = DragDropResult.Canceled;
|
||||
}
|
||||
if (res == DragDropResult.Canceled) {
|
||||
args.RetVal = false;
|
||||
args.RetVal = true;
|
||||
Gtk.Drag.Finish (args.Context, false, false, args.Time);
|
||||
}
|
||||
else if (res == DragDropResult.Success) {
|
||||
args.RetVal = true;
|
||||
Gtk.Drag.Finish (args.Context, true, false, args.Time);
|
||||
var cda = ConvertDragAction (args.Context.Actions);
|
||||
Gtk.Drag.Finish (args.Context, true, cda == DragDropAction.Move, args.Time);
|
||||
}
|
||||
else {
|
||||
// Undefined, we need more data
|
||||
|
@ -360,21 +362,53 @@ namespace Xwt.GtkBackend
|
|||
Gdk.Drag.Status (args.Context, ConvertDragAction (da.AllowedAction), args.Time);
|
||||
}
|
||||
else {
|
||||
DragEventArgs da = new DragEventArgs (lastDragPosition, dragData, ConvertDragAction (args.Context.Actions));
|
||||
var cda = ConvertDragAction (args.Context.Actions);
|
||||
DragEventArgs da = new DragEventArgs (lastDragPosition, dragData, cda);
|
||||
EventSink.OnDragDrop (da);
|
||||
Gtk.Drag.Finish (args.Context, da.Success, false, args.Time);
|
||||
Gtk.Drag.Finish (args.Context, da.Success, cda == DragDropAction.Move, args.Time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DragStart (TransferDataSource data, DragDropAction dragAction, object imageBackend, int hotX, int hotY)
|
||||
class IconInitializer
|
||||
{
|
||||
public Gdk.Pixbuf Image;
|
||||
public double HotX, HotY;
|
||||
public Gtk.Widget Widget;
|
||||
|
||||
public static void Init (Gtk.Widget w, Gdk.Pixbuf image, double hotX, double hotY)
|
||||
{
|
||||
IconInitializer ii = new WidgetBackend.IconInitializer ();
|
||||
ii.Image = image;
|
||||
ii.HotX = hotX;
|
||||
ii.HotY = hotY;
|
||||
ii.Widget = w;
|
||||
w.DragBegin += ii.Begin;
|
||||
}
|
||||
|
||||
void Begin (object o, Gtk.DragBeginArgs args)
|
||||
{
|
||||
Gtk.Drag.SetIconPixbuf (args.Context, Image, (int)HotX, (int)HotY);
|
||||
Widget.DragBegin -= Begin;
|
||||
}
|
||||
}
|
||||
|
||||
public void DragStart (TransferDataSource data, DragDropAction dragAction, object imageBackend, double hotX, double hotY)
|
||||
{
|
||||
Gdk.DragAction action = ConvertDragAction (dragAction);
|
||||
currentDragData = data;
|
||||
Widget.DragBegin += HandleDragBegin;
|
||||
IconInitializer.Init (Widget, (Gdk.Pixbuf) imageBackend, hotX, hotY);
|
||||
Gtk.Drag.Begin (Widget, Util.BuildTargetTable (data.DataTypes), action, 1, Gtk.Global.CurrentEvent);
|
||||
}
|
||||
|
||||
void HandleDragBegin (object o, Gtk.DragBeginArgs args)
|
||||
{
|
||||
Console.WriteLine ("Begin drag");
|
||||
Widget.DragEnd += HandleWidgetDragEnd;
|
||||
Widget.DragFailed += HandleDragFailed;
|
||||
Widget.DragDataDelete += HandleDragDataDelete;
|
||||
Widget.DragDataGet += HandleWidgetDragDataGet;
|
||||
var ctx = Gtk.Drag.Begin (Widget, Util.BuildTargetTable (data.DataTypes), action, 0, Gtk.Global.CurrentEvent);
|
||||
Gtk.Drag.SetIconPixbuf (ctx, (Gdk.Pixbuf)imageBackend, hotX, hotY);
|
||||
}
|
||||
|
||||
void HandleWidgetDragDataGet (object o, Gtk.DragDataGetArgs args)
|
||||
|
@ -382,10 +416,29 @@ namespace Xwt.GtkBackend
|
|||
Util.SetDragData (currentDragData, args);
|
||||
}
|
||||
|
||||
void HandleDragFailed (object o, Gtk.DragFailedArgs args)
|
||||
{
|
||||
Console.WriteLine ("FAILED");
|
||||
}
|
||||
|
||||
void HandleDragDataDelete (object o, Gtk.DragDataDeleteArgs args)
|
||||
{
|
||||
FinishDrag (true);
|
||||
}
|
||||
|
||||
void HandleWidgetDragEnd (object o, Gtk.DragEndArgs args)
|
||||
{
|
||||
FinishDrag (false);
|
||||
}
|
||||
|
||||
void FinishDrag (bool delete)
|
||||
{
|
||||
Widget.DragEnd -= HandleWidgetDragEnd;
|
||||
Widget.DragDataGet -= HandleWidgetDragDataGet;
|
||||
Widget.DragFailed -= HandleDragFailed;
|
||||
Widget.DragDataDelete -= HandleDragDataDelete;
|
||||
Widget.DragBegin -= HandleDragBegin;
|
||||
eventSink.OnDragFinished (new DragFinishedEventArgs (delete));
|
||||
}
|
||||
|
||||
public void SetDragTarget (string[] types, DragDropAction dragAction)
|
||||
|
|
|
@ -61,6 +61,26 @@ namespace Xwt.Mac
|
|||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public override object Copy (object handle)
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public override void CopyArea (object backend, int srcX, int srcY, int width, int height, object dest, int destX, int destY)
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public override object Crop (object backend, int srcX, int srcY, int width, int height)
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public override object ChangeOpacity (object backend, double opacity)
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -234,13 +234,21 @@ namespace Xwt.Mac
|
|||
}
|
||||
}
|
||||
|
||||
public void DragStart (TransferDataSource data, DragDropAction dragAction, object image, int xhot, int yhot)
|
||||
public void DragStart (TransferDataSource data, DragDropAction dragAction, object image, double xhot, double yhot)
|
||||
{
|
||||
var lo = RootWidget.ConvertPointToBase (new PointF (Widget.Bounds.X, Widget.Bounds.Y));
|
||||
lo = RootWidget.Window.ConvertBaseToScreen (lo);
|
||||
var ml = NSEvent.CurrentMouseLocation;
|
||||
var pb = NSPasteboard.FromName (NSPasteboard.NSDragPasteboardName);
|
||||
if (pb == null)
|
||||
throw new InvalidOperationException ("Could not get pasteboard");
|
||||
if (data == null)
|
||||
throw new ArgumentNullException ("data");
|
||||
InitPasteboard (pb, data);
|
||||
var pos = new PointF (Widget.Bounds.X + Widget.Bounds.Width/2, Widget.Bounds.Y + Widget.Bounds.Height / 2);
|
||||
var img = new NSImage ("/Users/lluis/prog/work/Xwt/MacTest/class.png");
|
||||
Widget.DragImage (img, pos, new SizeF (0,0), NSApplication.SharedApplication.CurrentEvent, pb, Widget, true);
|
||||
var img = (NSImage)image;
|
||||
var pos = new PointF (ml.X - lo.X - (float)xhot, lo.Y - ml.Y - (float)yhot + img.Size.Height);
|
||||
Console.WriteLine ("P:" + NSApplication.SharedApplication.CurrentEvent);
|
||||
Widget.DragImage (img, pos, new SizeF (0, 0), NSApplication.SharedApplication.CurrentEvent, pb, Widget, true);
|
||||
}
|
||||
|
||||
public void SetDragSource (string[] types, DragDropAction dragAction)
|
||||
|
|
|
@ -221,7 +221,7 @@ namespace Xwt.Mac
|
|||
|
||||
}
|
||||
|
||||
public void DragStart (TransferDataSource data, DragDropAction dragAction, object dragImage, int xhot, int yhot)
|
||||
public void DragStart (TransferDataSource data, DragDropAction dragAction, object dragImage, double xhot, double yhot)
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
|
2
Xwt.sln
2
Xwt.sln
|
@ -45,7 +45,7 @@ Global
|
|||
{C3887A93-B2BD-4097-8E2F-3A063EFF32FD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
StartupItem = MacTest\MacTest.csproj
|
||||
StartupItem = GtkTest\GtkTest.csproj
|
||||
Policies = $0
|
||||
$0.DotNetNamingPolicy = $1
|
||||
$1.DirectoryNamespaceAssociation = None
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace Xwt.Backends
|
|||
|
||||
object NativeWidget { get; }
|
||||
|
||||
void DragStart (TransferDataSource data, DragDropAction dragAction, object imageBackend, int hotX, int hotY);
|
||||
void DragStart (TransferDataSource data, DragDropAction allowedDragActions, object imageBackend, double hotX, double hotY);
|
||||
void SetDragSource (string[] types, DragDropAction dragAction);
|
||||
void SetDragTarget (string[] types, DragDropAction dragAction);
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ namespace Xwt.Backends
|
|||
void OnDragDropCheck (DragCheckEventArgs args);
|
||||
void OnDragDrop (DragEventArgs args);
|
||||
void OnDragLeave (EventArgs args);
|
||||
void OnDragFinished (DragFinishedEventArgs args);
|
||||
|
||||
/// <summary>
|
||||
/// Notifies the frontend that the preferred size of this widget has changed
|
||||
|
|
|
@ -63,6 +63,14 @@ namespace Xwt.Backends
|
|||
public abstract Size GetSize (object handle);
|
||||
|
||||
public abstract object Resize (object handle, double width, double height);
|
||||
|
||||
public abstract object Copy (object handle);
|
||||
|
||||
public abstract void CopyArea (object srcHandle, int srcX, int srcY, int width, int height, object destHandle, int destX, int destY);
|
||||
|
||||
public abstract object Crop (object handle, int srcX, int srcY, int width, int height);
|
||||
|
||||
public abstract object ChangeOpacity (object backend, double opacity);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,14 +51,24 @@ namespace Xwt.Drawing
|
|||
{
|
||||
}
|
||||
|
||||
public Image (Image image): base (handler.Copy (image.Backend))
|
||||
{
|
||||
}
|
||||
|
||||
public static Image FromResource (Type type, string resource)
|
||||
{
|
||||
return new Image (handler.LoadFromResource (type.Assembly, resource));
|
||||
var img = handler.LoadFromResource (type.Assembly, resource);
|
||||
if (img == null)
|
||||
throw new InvalidOperationException ("Resource not found: " + resource);
|
||||
return new Image (img);
|
||||
}
|
||||
|
||||
public static Image FromResource (Assembly asm, string resource)
|
||||
{
|
||||
return new Image (handler.LoadFromResource (asm, resource));
|
||||
var img = handler.LoadFromResource (asm, resource);
|
||||
if (img == null)
|
||||
throw new InvalidOperationException ("Resource not found: " + resource);
|
||||
return new Image (img);
|
||||
}
|
||||
|
||||
public static Image FromFile (string file)
|
||||
|
@ -110,9 +120,19 @@ namespace Xwt.Drawing
|
|||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public Image SetOpacity (double opacity)
|
||||
public Image ChangeOpacity (double opacity)
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
return new Image (handler.ChangeOpacity (Backend, opacity));
|
||||
}
|
||||
|
||||
public void CopyArea (int srcX, int srcY, int width, int height, Image dest, int destX, int destY)
|
||||
{
|
||||
handler.CopyArea (Backend, srcX, srcY, width, height, dest.Backend, destX, destY);
|
||||
}
|
||||
|
||||
public Image Crop (int srcX, int srcY, int width, int height)
|
||||
{
|
||||
return new Image (handler.Crop (Backend, srcX, srcY, width, height));
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
|
|
|
@ -80,8 +80,18 @@ namespace Xwt
|
|||
|
||||
public Point Position { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Proposed drop action, which depends on the control keys being pressed
|
||||
/// </summary>
|
||||
public DragDropAction Action { get; private set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Allowed action
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// To be set by the handler of the event. Specifies the action that will be performed if the item is dropped.
|
||||
/// If not specified or set to Default, the action will be determined by the handler of DragOver.
|
||||
/// </remarks>
|
||||
public DragDropAction AllowedAction { get; set; }
|
||||
}
|
||||
|
||||
|
@ -104,6 +114,16 @@ namespace Xwt
|
|||
public DragDropAction AllowedAction { get; set; }
|
||||
}
|
||||
|
||||
public class DragFinishedEventArgs: EventArgs
|
||||
{
|
||||
public DragFinishedEventArgs (bool deleteSource)
|
||||
{
|
||||
DeleteSource = deleteSource;
|
||||
}
|
||||
|
||||
public bool DeleteSource { get; private set; }
|
||||
}
|
||||
|
||||
public enum DragDropResult
|
||||
{
|
||||
Success,
|
||||
|
|
|
@ -40,16 +40,21 @@ namespace Xwt
|
|||
DragDropAction action;
|
||||
bool started;
|
||||
Image image;
|
||||
int hotX;
|
||||
int hotY;
|
||||
double hotX;
|
||||
double hotY;
|
||||
|
||||
public event EventHandler<DragFinishedEventArgs> Finished;
|
||||
|
||||
internal DragOperation (Widget w)
|
||||
{
|
||||
source = w;
|
||||
Action = DragDropAction.Copy;
|
||||
AllowedActions = DragDropAction.All;
|
||||
}
|
||||
|
||||
public DragDropAction Action {
|
||||
/// <summary>
|
||||
/// A bitmask of the allowed drag actions for this drag.
|
||||
/// </summary>
|
||||
public DragDropAction AllowedActions {
|
||||
get { return action; }
|
||||
set {
|
||||
if (started)
|
||||
|
@ -62,7 +67,7 @@ namespace Xwt
|
|||
get { return data; }
|
||||
}
|
||||
|
||||
public void SetDragImage (Image image, int hotX, int hotY)
|
||||
public void SetDragImage (Image image, double hotX, double hotY)
|
||||
{
|
||||
if (started)
|
||||
throw new InvalidOperationException ("The drag image must be set before starting the drag operation");
|
||||
|
@ -76,6 +81,14 @@ namespace Xwt
|
|||
started = true;
|
||||
source.DragStart (data, action, XwtObject.GetBackend (image), hotX, hotY);
|
||||
}
|
||||
|
||||
internal void NotifyFinished (DragFinishedEventArgs args)
|
||||
{
|
||||
Console.WriteLine ("Notify finished " + args.DeleteSource);
|
||||
if (Finished != null)
|
||||
Finished (this, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class TransferDataSource
|
||||
|
|
|
@ -47,6 +47,7 @@ namespace Xwt
|
|||
bool heightCached;
|
||||
static HashSet<Widget> resizeRequestQueue = new HashSet<Widget> ();
|
||||
EventSink eventSink;
|
||||
DragOperation currentDragOperation;
|
||||
|
||||
protected class EventSink: IWidgetEventSink
|
||||
{
|
||||
|
@ -81,6 +82,11 @@ namespace Xwt
|
|||
{
|
||||
Parent.OnPreferredSizeChanged ();
|
||||
}
|
||||
|
||||
public void OnDragFinished (DragFinishedEventArgs args)
|
||||
{
|
||||
Parent.OnDragFinished (args);
|
||||
}
|
||||
}
|
||||
|
||||
public Widget ()
|
||||
|
@ -162,12 +168,13 @@ namespace Xwt
|
|||
|
||||
public DragOperation CreateDragOperation ()
|
||||
{
|
||||
return new DragOperation (this);
|
||||
currentDragOperation = new DragOperation (this);
|
||||
return currentDragOperation;
|
||||
}
|
||||
|
||||
internal void DragStart (TransferDataSource data, DragDropAction dragAction, object image, int hotX, int hotY)
|
||||
internal void DragStart (TransferDataSource data, DragDropAction allowedDragActions, object image, double hotX, double hotY)
|
||||
{
|
||||
Backend.DragStart (data, dragAction, image, hotX, hotY);
|
||||
Backend.DragStart (data, allowedDragActions, image, hotX, hotY);
|
||||
}
|
||||
|
||||
public void SetDragDropTarget (params string[] types)
|
||||
|
@ -246,6 +253,15 @@ namespace Xwt
|
|||
dragLeave (this, args);
|
||||
}
|
||||
|
||||
internal protected virtual void OnDragFinished (DragFinishedEventArgs args)
|
||||
{
|
||||
if (currentDragOperation != null) {
|
||||
var dop = currentDragOperation;
|
||||
currentDragOperation = null;
|
||||
dop.NotifyFinished (args);
|
||||
}
|
||||
}
|
||||
|
||||
protected static IWidgetBackend GetWidgetBackend (Widget w)
|
||||
{
|
||||
return (IWidgetBackend) GetBackend (w);
|
||||
|
|
Загрузка…
Ссылка в новой задаче