http://www.gambas-es.org/viewtopic.php?f=1&t=125
-----------------------------------
JaM0N
14 Octubre 2009, 06:25

Drag &amp; Drop
-----------------------------------
Hola, soy nuevo en esto y estoy inetentando hacer algo simple pero bonito para comenzar... Estoy modificando el Reproductor de sonido que viene como ejemplo y quiero agregarle la opción de Drop...
el problema es que no se muy bien como hacerlo (hace tiempo no programo otra cosa que javascript o php :( ) y la documentación que encuentro por todos lados solo dice

[code linenumbers=false syntax=gambas]
EVENT Drop ( )

'This event is raised when a drag is dropped in the control. 

PROPERTY Drop AS Boolean

'Returns or sets if a control accepts drops. 

SUB Drag ( Data AS Variant [ , Format AS String ] )

'Starts a drag & drop process.

'    * Data is the data to be dragged. It can be a String or an Image.
'    * If Data is a text, then you can specify in Format the MIME type of this text. For example, "text/html". 

EVENT Drag ( )

'This event is raised when the mouse enters the control during a drag & drop process.

'Event Cancellation
'If you stop the event with STOP EVENT, then the drop will be rejected.

EVENT DragMove ( )

'This event is raised while the mouse moves inside the control during a drag & drop process.

'Event Cancellation
'If you stop the event with STOP EVENT, you indicate that the part of the control where the mouse cursor is does not accept the drop.  [/code]

Y no tengo ni idea como usarlo. Estaría muy ineteresante que junto a esa información pusieran al menos 5 lineas de código a modo de ejemplo para gente como yo  :oops: 

Bueno, saludos


-----------------------------------
jguardon
16 Octubre 2009, 20:59

Re: Drag &amp; Drop
-----------------------------------
Nunca he usado D&D, pero mira en los ejemplos que vienen con Gambas, hay un ejemplo llamado precisamente "DragNDrop".

Es un proyecto muy simple, pero que muestra su uso básico.

Saludos


-----------------------------------
soplo
27 Octubre 2009, 21:25

Re: Drag &amp; Drop
-----------------------------------
Es muy simple.

1. En el control del que vas a hacer drop pones la propiedad DROP a TRUE.

2. En el control del que quieres hacer drag escribes el evento mousedrag (para hacer drag con el ratón)
[code linenumbers=false syntax=gambas]PUBLIC SUB textbox_MouseDrag()

IF Mouse.left THEN 
  textbox.Drag(textbox.text)
ENDIF 
END[/code]

Con eso ya has programado que cuando hagas drag en un textbox te lleves el contenido. Igual podrías llevarte cualquier otra cosa naturalmente. El método drag inicia el proceso drag y te llevas lo que hayas metido como argumento.

Así que ahora ya puedes arrastrar desde un textbox a otro por ejemplo. Te queda por programar lo que ocurrirá cuando hagas el drop. para eso está el evento drop
[code linenumbers=false syntax=gambas]sub textbox2_drop
textbox2.text=textbox1.drop
end sub[/code]

Hay algún otro método para programar lo que ocurre mientras mueves el ratón y tal, pero lo fundamental es eso.

 :mryellow:


-----------------------------------
jsbsan
01 Noviembre 2009, 11:05

Re: Drag &amp; Drop
-----------------------------------
He intentado ejecutar tu cogido en dos textbox ( textbox1 (parga hacer drag) y textbox2 (para hacer el drop) ).

Pero cuando lo ejecuto me da el siguiente error a la hora de pulsar el boton left del raton en el textbox1:

 [img]http://www.gambas-es.org/files/posted_images/6/error_drag_and_drop.jpg[/img] 

Y se queda bloqueado el raton, teniendo que salir del  Gambas2, con el teclado.

¿que he hecho mal?


[codeblock]
 PUBLIC SUB TextBox1_MouseDrag()
  IF Mouse.Left THEN 
    TextBox1.Drag(TextBox1.text)
    ENDIF 
 END

PUBLIC SUB TextBox2_Drop()
  TextBox2.text = TextBox1.Drop
END
[/codeblock]

He utilizado UBUNTU 9.10 y Gambas2-2.17


-----------------------------------
maikl
01 Noviembre 2009, 11:48

Re: Drag &amp; Drop
-----------------------------------
Hola, he hecho pruebas y faltaria usar el objeto drop que no depende de quien envia, ya que no debes saber quien envia el dato sino solo el dato que llega al control.

PUBLIC SUB TextBox1_MouseDrag()

  TextBox1.Drag("hola") 'El valor que sea, por defecto texto, si es otra cosa lo cambias por parámetro.

END

PUBLIC SUB TextBox2_Drop()

  TextBox2.Text = Drag.Data

END

Y quieres algo chulo? con el mismo código que te he puesto prueba a arrastrar un archivo de una ventana del explorador de archivos al textbox2, se pondrá el nombre del archivo arrastrado en el textobox.
El objeto Drag contiene los datos del arrastre actual, junto con el tipo de datos.
En tu prueba podrias hacer que si el archivo es extension mp3 pues que suene.
Saludos y suerte!


-----------------------------------
maikl
01 Noviembre 2009, 11:49

Re: Drag &amp; Drop
-----------------------------------
ep ep ep que falta poner en las propiedades del textbox2 el valor true a la propiedad Drop, en el diseño.


-----------------------------------
soplo
01 Noviembre 2009, 17:00

Re: Drag &amp; Drop
-----------------------------------
Cierto cierto.

La propiedad DROP lo que hace es indicar que objetos pueden recibir un drag.

Cuando sueltas en ese control se genera el evento textbox2_drop y allí 
[code linenumbers=false syntax=gambas]sub textbox2_drop
textbox2.text=textbox1.drop
end sub[/code]

No conocía al objeto DRAG. Todos los días se aprende algo 

 :mryellow:

Una cosa mas. El método drag (textbox1.drag(textbox1.text) admite un parámetro. Si no se pone se asume que lo que se copia es texto plano o imagen, pero si se pone el parámetro se puede especificar que es otro tipo de dato (como por ejemplo XML). El parámetro que se pone es el tipo MIME que se quiere usar y que por defecto es "text/html"

[code linenumbers=false syntax=gambas]Control.drag("video.avi","video/x-msvideo")[/code]

Esta es la lista de los mimetypes (aunque por lo visto gambas no funciona con todos)

[url=http://www.mimetype.org/]Mime Types


-----------------------------------
jsbsan
01 Noviembre 2009, 19:31

Re: Drag &amp; Drop
-----------------------------------
Ok, ahora me funciona perfectamente.

He hecho una pequeña aplicación a modo de ejemplo.
 [img]http://www.gambas-es.org/files/posted_images/6/cogerysoltar.jpg[/img] 
Este es el codigo del formulario principal :

[code linenumbers=false syntax=gambas]
' Gambas class file

'propiedades drog:
'TextBox2.Drop debes declararlas  desde el editor de propiedades TRUE
'ListBox1.Drop debes declararlas  desde el editor de propiedades TRUE
'listbox2.Drop debes declararlas  desde el editor de propiedades TRUE


PUBLIC SUB Form_Open()
ListBox1.Add("Andalucia")
ListBox1.Add("Canarias")
listbox1.add("Murcia")
END


'coger
PUBLIC SUB TextBox1_MouseDrag()
  IF Mouse.Left THEN
     TextBox1.Drag(TextBox1.Text) 
    ENDIF
 END

PUBLIC SUB ListBox1_MouseDrag()
  IF Mouse.Left THEN 
   listbox1.Drag(ListBox1[ListBox1.index].text)
  ENDIF 
END

PUBLIC SUB ListBox2_MouseDrag()
  IF Mouse.Left THEN 
   listbox2.Drag(ListBox2[ListBox2.index].text)
  ENDIF 
END



'soltar
PUBLIC SUB TextBox2_Drop()
  TextBox2.text = Drag.Data
END


PUBLIC SUB ListBox1_Drop()
  ListBox1.Add(Drag.data)
  END
PUBLIC SUB listbox2_Drop()
  ListBox2.Add(Drag.data)
END

[/code]

La publicare en mi blog, gracias a todos por vuestras respuestas


-----------------------------------
angelnu
11 Noviembre 2009, 20:42

Re: Drag &amp; Drop
-----------------------------------
Estoy haciendo pruebas con el Drag and Drop  y me repite los datos al hacer Drop . 
El codigo es el siguiente:

[code linenumbers=false syntax=gambas]
PUBLIC SUB ListBox1_MouseDrag()

    IF Mouse.Left THEN
    ' inicio el drag 
     ListBox1.Drag(ListBox1[ListBox1.Index].Text, "text/plain")
    ENDIF

END

PUBLIC SUB TxaDespues_Drop()
     ' suelto el texto en un texarea
  TxaDespues.Text = Drag.Data ' al parar aqui observo Drag.Data y los datos son correctos 

END
[/code]


-----------------------------------
soplo
11 Noviembre 2009, 20:54

Re: Drag &amp; Drop
-----------------------------------
si, a mi también me pasó eso y no recuerdo bien pero creo que lo que hice fue hacer un drag.hide porque lo que pasa es que el drag sigue activo por si quieres pastear en otro sitio.

La verdad es que no lo recuerdo porque lo hice hace tiempo y tuve que darle bastantes vueltas hasta conseguirlo. Como no tengo el código aquí no lo puedo mirar, pero creo que fue eso.


-----------------------------------
jguardon
11 Noviembre 2009, 21:14

Re: Drag &amp; Drop
-----------------------------------
Al comienzo del procedimiento _MouseDrag() ¿vale con poner drag.Data=NULL ?


-----------------------------------
angelnu
11 Noviembre 2009, 21:15

Re: Drag &amp; Drop
-----------------------------------
Gracias soplo por responder he puesto el Drag.Hide y sigue igual..


-----------------------------------
angelnu
11 Noviembre 2009, 21:21

Re: Drag &amp; Drop
-----------------------------------
Gracias Jesús pero Drag.Data es una propiedad de solo lectura 
drag.Data = NULL da error.


-----------------------------------
soplo
11 Noviembre 2009, 23:51

Re: Drag &amp; Drop
-----------------------------------
Acabo de ver esto en la documentacion[quote]
EVENT Drag ( )

This event is raised when the mouse enters the control during a drag & drop process.

Event Cancellation
If you stop the event with STOP EVENT, then the drop will be rejected. [/quote]
[url=http://www.gambasdoc.org/help/comp/gb.qt/control/.drag]Cancelación DRAG

De donde deduzco que hay que meter un stop event en el evento drag. Este evento se ejecuta siempre al iniciar una operación drag así que entiendo que hace falta alguna variable que valga si o no según se quiera o no se quiera cancelar el drag. En caso de que sea SI debería ejecutarse stop event.


-----------------------------------
fabianfv
12 Noviembre 2009, 01:01

Re: Drag &amp; Drop
-----------------------------------
[quote]
Cuando sueltas en ese control se genera el evento textbox2_drop y allí
[code linenumbers=false syntax=gambas]
sub textbox2_drop
textbox2.text=textbox1.drop
end sub
[/code]
[/quote]

El problema de usar la propiedad Drop de un control es que te fuerzas a escribir código para saber desde que control se recibe el Drag&Drop. Si sólo se puede recibir el Drag&Drop de un único control lo anterior funcionará sin problemas, si hay más de un control, al arrastrar desde cualquier otro control estaría siempre colocando los datos de un único control que no es el que se está arrastrando (en este caso los datos de textbox1).

Se puede identificar el control que inició el arrastre de este modo:

[code linenumbers=false syntax=gambas]
PUBLIC SUB TxtRecibeDrop_Drop()
SELECT CASE Drag.Source
  CASE ListBox1
    TxtRecibeDrop.Text = ListBox1.drop
  CASE ListBox2
    TxtRecibeDrop.Text = ListBox2.drop
END SELECT 
END
[/code]

Sin embargo, se usa la clase Drag para identificar el control que originó el D&D, cuando se puede usar directamente para asignar el dato que se está arrastrando.

-------------------------------------

[quote]
Al comienzo del procedimiento _MouseDrag() ¿vale con poner drag.Data=NULL ?
[/quote]

La sintaxis debería ser:

[code linenumbers=false syntax=gambas]
  Drag.Data(NULL)
[/code]

Sin embargo, esto da un error a pesar que Drag.Data es de tipo Variant. Aquí parece haber otro bug.

-------------------------------------

[quote]
Gracias Jesús pero Drag.Data es una propiedad de solo lectura
drag.Data = NULL da error.
[/quote]

La definición de Drag.Data es:

[code linenumbers=false syntax=gambas]
STATIC PROPERTY READ Data AS Variant
[/code]

Si no me equivoco aquí hay una inconsistencia en el diseño de la clase, ya que por una lado usa Property Read y por otro lado permite establecer el valor de la propiedad Data. Tal vez esté hecho así intencionalmente pero no lo comprendo, más allá de que esté documentado:

[quote]
 This class is static.
 This class can be used as a function.
[/quote]

-------------------------------------

[quote]
De donde deduzco que hay que meter un stop event en el evento drag. Este evento se ejecuta siempre al iniciar una operación drag así que entiendo que hace falta alguna variable que valga si o no según se quiera o no se quiera cancelar el drag. En caso de que sea SI debería ejecutarse stop event.
[/quote]

El problema es que no quieres cancelar el D&D porque si no nada ocurriría. En todo caso puede pensarse de colocar STOP EVENT en el código del evento DROP:

[code linenumbers=false syntax=gambas]
PUBLIC SUB TxtRecibeDrop_Drop()
   TxtRecibeDrop.Text = Drag.Data
   STOP EVENT
END
[/code]

Pensando que el evento se repite dos veces. Pero no es esto lo que ocurre en realidad, sino un bug en la clase Drag o bien en la clase TextBox.


-------------------------------------


[quote]
Estoy haciendo pruebas con el Drag and Drop  y me repite los datos al hacer Drop .
El codigo es el siguiente: 
[/quote]

El problema de la repetición del texto que se arrastra sólo se da cuando se usa gb.qt y el control destino es un TextBox (o un control que hereda de TextBox como TextArea). Claramente hay un bug, lo que no me queda claro si es en la clase Drag o en la clase TextBox.

La solución:

[code linenumbers=false syntax=gambas]
PUBLIC SUB TxaDespues_Drop()
  TxaDespues.Text = Drag.Paste("")
END
[/code]

-------------------------------------

Finalmente, decir que si se usa D&D con gb.gtk aparecen numerosos bugs, desde el bloqueo del uso del ratón para el servidor X, hasta la aparición de diversos errores N° 11 (SIGSEGV).


-----------------------------------
angelnu
12 Noviembre 2009, 15:47

Re: Drag &amp; Drop
-----------------------------------
Gracias Fabianfv por tu extensa respuesta, efectivamente Drag.Paste("") no provoca duplicar el texto, pero si parece que hay un o varios bugs
el codigo:

[code linenumbers=false syntax=gambas]PUBLIC SUB ListBox1_MouseDrag()

    IF Mouse.Left THEN
    ' inicio el drag 
   
     ListBox1.Drag(ListBox1[ListBox1.Index].Text, "text/plain")
   
    ENDIF

END

PUBLIC SUB TxaDespues_Drop()

     ' suelto el texto en un texarea
  TxaDespues.Pos = TxaDespues.Length  ' posicionamos al final del texto
  TxaDespues.Text &= Drag.Paste("") & "," ' añadimos una coma 
  
END[/code]

El ultimo texto pegado siempre se pone al inicio no al final, y el texto que tuviera el control se pone detrás del texto pegado.

Efectivamente utilizo gb.qt 

otra curiosidad el codigo:
[code linenumbers=false syntax=gambas]PUBLIC SUB TextBox1_Drop()

  TextBox1.Text &= ListBox1.Drop
   STOP EVENT
END[/code]

Pone siempre una T delante del texto a pegar

Un saludo Angel


-----------------------------------
fabianfv
12 Noviembre 2009, 20:21

Re: Drag &amp; Drop
-----------------------------------
[quote]
[code linenumbers=false syntax=gambas]
PUBLIC SUB TxaDespues_Drop()

    ' suelto el texto en un texarea
 TxaDespues.Pos = TxaDespues.Length  ' posicionamos al final del texto
 TxaDespues.Text &= Drag.Paste("") & "," ' añadimos una coma
 
END
[/code]

El ultimo texto pegado siempre se pone al inicio no al final, y el texto que tuviera el control se pone detrás del texto pegado. 
[/quote]

No pude reproducir el comportamiento que describes. Lo que observé es que el cursor de texto se ubica en la posición del puntero del ratón al momento en que sueltas el botón izquierdo y que no es posible ubicar el texto que se arrastra a un posición distinta.

¿Tienes una necesidad real de controlar que el texto se agregue al final? (ocurrirá de todos modos si el usuario lo hace así). ¿Podrías usar otro control en lugar de un TextBox?

[quote]
[code linenumbers=false syntax=gambas]
PUBLIC SUB TextBox1_Drop()

 TextBox1.Text &= ListBox1.Drop
  STOP EVENT
END
[/code]

Pone siempre una T delante del texto a pegar 
[/quote]

Tampoco hubo forma de que pudiera reproducir este comportamiento. ¿Podría ser que el TextBox tuviera el texto predefinido "TextBox1) y la "T" que mencionas fuera el primer caracter de ese texto?

Nota: Colocar STOP EVENT al final del evento DROP no tiene ningún efecto, puedes borrar esa línea.


