Drag and Drop en un Browse.

Drag and Drop en un Browse.

Postby miarcod » Mon Feb 21, 2022 7:44 am

Hola, tengo un dialogo en el que se muestra un TCBrowse con datos de un array y he programado una función que permite intercambiar las filas de ese browse.
Esto lo hago con el teclado, pero me interesaría poder arrastrar una fila de una posición a otra mediante drag and drop
He estado buscando pero no encuentro nada al respecto, tambien he estado probando con bDragBegin y bDropOver pero no lo consigo.
Algún ejemplo de como mover una fila de un browse a otra posición del mismo browse (si se puede claro).

Gracias
Un saludo
Last edited by miarcod on Mon Feb 28, 2022 7:22 pm, edited 2 times in total.
miarcod
 
Posts: 197
Joined: Tue Oct 11, 2005 2:17 pm

Re: Drag and Drop en un Browse.

Postby FranciscoA » Wed Feb 23, 2022 2:24 am

Intenta con esto:
Code: Select all  Expand view
  WITH OBJECT oBrw
      :oDragCursor      := oCur
      :bDragBegin       := { |r,c,f,o| SetDropInfo( { oBrw:nArrayAt, oBrw:aRow } ) }
      :bDropOver        := { |u,r,c,f| oBrw:LButtonDown( r,c ), ;
                                       oBrw:LButtonUp(r,c), ;
                                       aData[u[1]] := oBrw:aRow, ;
                                       aData[oBrw:nArrayAt] := u[2], ;
                                       oBrw:Refresh() }

      :CreateFromCode()
   END
 

Saludos.
Francisco J. Alegría P.
Chinandega, Nicaragua.

Fwxh-MySql-TMySql
User avatar
FranciscoA
 
Posts: 2110
Joined: Fri Jul 18, 2008 1:24 am
Location: Chinandega, Nicaragua, C.A.

Re: Drag and Drop en un Browse.

Postby miarcod » Mon Feb 28, 2022 5:54 pm

Gracias,

He conseguido arrastras de un listbox a otro, pero ahora no consigo arrastrar desde un xbrowse a un listbox

Si recibo el evento dropover desde un listbox a otro listbox, de un lisbrox a un xbrowse, o de un xbrowse dentro del mismo xbrowse pero no recibo el evento dropover desde un xbrowse a un listbox

Se queda el curso en modo arrastrar hasta que hago la operación de arrastrar dentro del mismo xbrowse

Un saludo

Pongo un ejemplo de lo que me pasa. En este ejemplo se puede arastrar entre los listbox pero no me deja arrastras del browse al listbox

Code: Select all  Expand view

//------------------------------------------------------------------------//
STATIC FUNCTION Test()
    Local oDlg
    Local oLbx1, oLbx2, oLbx3, cValue, aItems
    Local oBrw1
    Local oCursor, oOrigen, oDestino

    DEFINE CURSOR oCursor drag

    aItems := { "UNO", "DOS", "TRES", "CUATRO", "CINCO", "SEIS", "SIETE" }
    DEFINE DIALOG oDlg SIZE 640,480


    @  10,  10 LISTBOX oLbx1 VAR cValue ITEMS aItems ;
               SIZE 80, 100 PIXEL OF oDlg

    @  10, 100 LISTBOX oLbx2 VAR cValue ITEMS {} ;
               SIZE 80, 100 PIXEL OF oDlg

    @  10, 190 LISTBOX oLbx3 VAR cValue ITEMS {} ;
               SIZE 80, 100 PIXEL OF oDlg

    @ 120,  10 XBROWSE oBrw1 OF oDlg COLUMNS 1 ;
               ARRAY { "Item 1","Item 2","Item 3","Item 4" } ;
               SIZE 100, 100 PIXEL

    oBrw1:CreateFromCode()

    oLbx1:Cargo := "LBX1"
    oLbx2:Cargo := "LBX2"
    oLbx3:Cargo := "LBX3"
    oBrw1:Cargo := "BRW1"


    // DEFINIR DRAG AND DROP


    oLbx1:oDragCursor := oCursor
    oLbx1:bDragBegin  := { |            nRow, nCol, nKeyFlags | ;
                                        oOrigen := oLbx1,       ;
                                        SetBegin(oOrigen) }
    oLbx1:bDropOver   := { | uDropInfo, nRow, nCol, nKeyFlags | ;
                                        oDestino := oLbx1,      ;
                                        SetOver(uDropInfo, nRow, nCol, nKeyFlags, oOrigen, oDestino) }

    oLbx2:oDragCursor := oCursor
    oLbx2:bDragBegin  := { |            nRow, nCol, nKeyFlags | ;
                                        oOrigen := oLbx2,       ;
                                        SetBegin(oOrigen) }
    oLbx2:bDropOver   := { | uDropInfo, nRow, nCol, nKeyFlags | ;
                                        oDestino := oLbx2,      ;
                                        SetOver(uDropInfo, nRow, nCol, nKeyFlags, oOrigen, oDestino) }

    oLbx3:oDragCursor := oCursor
    oLbx3:bDragBegin  := { |            nRow, nCol, nKeyFlags | ;
                                        oOrigen := oLbx3,       ;
                                        SetBegin(oOrigen) }
    oLbx3:bDropOver   := { | uDropInfo, nRow, nCol, nKeyFlags | ;
                                        oDestino := oLbx3,      ;
                                        SetOver(uDropInfo, nRow, nCol, nKeyFlags, oOrigen, oDestino) }

    oBrw1:oDragCursor := oCursor
    oBrw1:bDragBegin  := { |            nRow, nCol, nKeyFlags | ;
                                        oOrigen := oBrw1,       ;
                                        SetBegin(oOrigen) }
    oBrw1:bDropOver   := { | uDropInfo, nRow, nCol, nKeyFlags | ;
                                        oDestino := oBrw1,      ;
                                        SetOver(uDropInfo, nRow, nCol, nKeyFlags, oOrigen, oDestino) }


    ACTIVATE DIALOG oDlg CENTER



RETURN .F.

//-----------------------**-----------------------------------------------//
STATIC FUNCTION SetBegin(oOrigen)
Local cOrigen := Left(oOrigen:Cargo, 3)

If cOrigen == "LBX"
   If len(oOrigen:aItems) >0
      SetDropInfo( oOrigen:getSelText() )
   EndIf
   RETURN NIL
EndIf

If cOrigen == "BRW"
   SetDropInfo( oOrigen:aArrayData[oOrigen:nArrayAt] )
EndIf


RETURN NIL

//-----------------------**-----------------------------------------------//
STATIC FUNCTION SetOver( uDropInfo, nRow, nCol, nKeyFlags,;
                         oOrigen, oDestino)
Local cOrigen  := Left( oOrigen:Cargo, 3)
Local cDestino := Left(oDestino:Cargo, 3)

If cOrigen == "LBX" .and. cDestino == "LBX"
   oOrigen:del( )
   oDestino:Add( uDropInfo)
   RETURN NIL
EndIf

If cOrigen == "BRW" .and. cDestino == "BRW"
   MsgInfo("Operación no permitida")
   RETURN NIL

EndIf

If cOrigen == "BRW" .and. cDestino == "LBX"
   oDestino:Add( uDropInfo)
EndIf


RETURN NIL


 
miarcod
 
Posts: 197
Joined: Tue Oct 11, 2005 2:17 pm

Re: Drag and Drop en un Browse.

Postby FranciscoA » Tue Mar 01, 2022 3:45 pm

miarcod wrote:Gracias,

He conseguido arrastras de un listbox a otro, pero ahora no consigo arrastrar desde un xbrowse a un listbox

Si recibo el evento dropover desde un listbox a otro listbox, de un lisbrox a un xbrowse, o de un xbrowse dentro del mismo xbrowse pero no recibo el evento dropover desde un xbrowse a un listbox

Se queda el curso en modo arrastrar hasta que hago la operación de arrastrar dentro del mismo xbrowse

Un saludo

Pongo un ejemplo de lo que me pasa. En este ejemplo se puede arastrar entre los listbox pero no me deja arrastras del browse al listbox



He probado tu codigo con los siguientes resultados:
Drag/Drop entre list boxes OK
Drag/Drop de Browse a list boxes OK ( pero no elimina el item del browse. Probablemente es el comportamiento que deseas )
Drag/Drop de list boxes a Browse NO FUNCIONA ( no veo el codigo para esto: If cOrigen == "LBX" .and. cDestino == "BRW" )

Saludos
Francisco J. Alegría P.
Chinandega, Nicaragua.

Fwxh-MySql-TMySql
User avatar
FranciscoA
 
Posts: 2110
Joined: Fri Jul 18, 2008 1:24 am
Location: Chinandega, Nicaragua, C.A.

Re: Drag and Drop en un Browse.

Postby miarcod » Wed Mar 02, 2022 2:48 pm

Francisco
Gracias por responder

No se si será mi versión de pero, a mi el arrastre desde el browxe a cualquiera de los listbox no me lo deja hacer

Al hacer click en una celda aparece el cursor se arrastrar pero al soltarlo en el listbox no se ejecuta el evento dropOver y no pasa nada no se agrega el elemento al listbox, de hecho si hago click para soltar en un listbox el cursor permance en modo arrastre aunque no mantenga el botón pulsado hasta que vuelvo a hacer clic en el browxe, que es cuando se ejcuta el evento dropOver.

Por si fuera algún cambio de alguna clase que estuviera modificada por mi he probado a crear este ejemplo directamente como una muestra mas de los ejemplos de fw pero el problema sigue siendo el mismo lo que me indica que no es ninguna modificación realizado por mi.

He probado a agregar un segundo browse y en este caso si funciona y se genera el evento en el browse correspondiente, por lo que supondo que tiene que haber algo en la clase Listbox que no se está ejecutando correctamente al soltar desde el browse

Un saludo

Utilizo FWH 20.08
Habour 3.2.0dev (r2004201301)

Pongo el ejemplo rectificado

Code: Select all  Expand view

//------------------------------------------------------------------------//
STATIC FUNCTION Test()
    Local oDlg
    Local oLbx1, oLbx2, oLbx3, cValue, aItems
    Local oBrw1, oBrw2
    Local oCursor, oOrigen, oDestino

    DEFINE CURSOR oCursor drag

    aItems := { "UNO", "DOS", "TRES", "CUATRO", "CINCO", "SEIS", "SIETE" }
    DEFINE DIALOG oDlg SIZE 640,480


    @  10,  10 LISTBOX oLbx1 VAR cValue ITEMS aItems ;
               SIZE 80, 100 PIXEL OF oDlg

    @  10, 100 LISTBOX oLbx2 VAR cValue ITEMS {} ;
               SIZE 80, 100 PIXEL OF oDlg

    @  10, 190 LISTBOX oLbx3 VAR cValue ITEMS {} ;
               SIZE 80, 100 PIXEL OF oDlg

    @ 120,  10 XBROWSE oBrw1 OF oDlg COLUMNS 1 ;
               ARRAY { "Item 1","Item 2","Item 3","Item 4" } ;
               SIZE 100, 100 PIXEL

    @ 120, 120 XBROWSE oBrw2 OF oDlg COLUMNS 1 ;
               ARRAY { "Item 11","Item 12","Item 13","Item 14" } ;
               SIZE 100, 100 PIXEL

    oBrw1:CreateFromCode()
    oBrw2:CreateFromCode()

    oLbx1:Cargo := "LBX1"
    oLbx2:Cargo := "LBX2"
    oLbx3:Cargo := "LBX3"
    oBrw1:Cargo := "BRW1"
    oBrw2:Cargo := "BRW2"


    // DEFINIR DRAG AND DROP


    oLbx1:oDragCursor := oCursor
    oLbx1:bDragBegin  := { |            nRow, nCol, nKeyFlags | ;
                                        oOrigen := oLbx1,       ;
                                        SetBegin(oOrigen) }
    oLbx1:bDropOver   := { | uDropInfo, nRow, nCol, nKeyFlags | ;
                                        oDestino := oLbx1,      ;
                                        SetOver(uDropInfo, nRow, nCol, nKeyFlags, oOrigen, oDestino) }

    oLbx2:oDragCursor := oCursor
    oLbx2:bDragBegin  := { |            nRow, nCol, nKeyFlags | ;
                                        oOrigen := oLbx2,       ;
                                        SetBegin(oOrigen) }
    oLbx2:bDropOver   := { | uDropInfo, nRow, nCol, nKeyFlags | ;
                                        oDestino := oLbx2,      ;
                                        SetOver(uDropInfo, nRow, nCol, nKeyFlags, oOrigen, oDestino) }

    oLbx3:oDragCursor := oCursor
    oLbx3:bDragBegin  := { |            nRow, nCol, nKeyFlags | ;
                                        oOrigen := oLbx3,       ;
                                        SetBegin(oOrigen) }
    oLbx3:bDropOver   := { | uDropInfo, nRow, nCol, nKeyFlags | ;
                                        oDestino := oLbx3,      ;
                                        SetOver(uDropInfo, nRow, nCol, nKeyFlags, oOrigen, oDestino) }

    oBrw1:oDragCursor := oCursor
    oBrw1:bDragBegin  := { |            nRow, nCol, nKeyFlags | ;
                                        oOrigen := oBrw1,       ;
                                        SetBegin(oOrigen) }
    oBrw1:bDropOver   := { | uDropInfo, nRow, nCol, nKeyFlags | ;
                                        oDestino := oBrw1,      ;
                                        SetOver(uDropInfo, nRow, nCol, nKeyFlags, oOrigen, oDestino) }

    oBrw2:oDragCursor := oCursor
    oBrw2:bDragBegin  := { |            nRow, nCol, nKeyFlags | ;
                                        oOrigen := oBrw2,       ;
                                        SetBegin(oOrigen) }
    oBrw2:bDropOver   := { | uDropInfo, nRow, nCol, nKeyFlags | ;
                                        oDestino := oBrw2,      ;
                                        SetOver(uDropInfo, nRow, nCol, nKeyFlags, oOrigen, oDestino) }


    ACTIVATE DIALOG oDlg CENTER



RETURN .F.

//-----------------------**-----------------------------------------------//
STATIC FUNCTION SetBegin(oOrigen)
Local cOrigen := Left(oOrigen:Cargo, 3)

If cOrigen == "LBX"
   If len(oOrigen:aItems) >0
      SetDropInfo( oOrigen:getSelText() )
   EndIf
   RETURN NIL
EndIf

If cOrigen == "BRW"
   SetDropInfo( oOrigen:aArrayData[oOrigen:nArrayAt] )
EndIf
RETURN NIL

//-----------------------**-----------------------------------------------//
STATIC FUNCTION SetOver( uDropInfo, nRow, nCol, nKeyFlags,;
                         oOrigen, oDestino)
Local cOrigen  := Left( oOrigen:Cargo, 3)
Local cDestino := Left(oDestino:Cargo, 3)

If cOrigen == "LBX" .and. cDestino == "LBX"
   oOrigen:del( )
   oDestino:Add( uDropInfo)
   RETURN NIL
EndIf

If cOrigen == "BRW" .and. cDestino == "BRW"
   If oOrigen:Cargo == oDestino:Cargo
      MsgInfo("No se puede arrastrar dentro del mismo browse")
      RETURN NIL
   EndIf
   MsgInfo("Borrar elemento " + uDropInfo + " del " +  oOrigen:Cargo + CRLF +;
           "y agregarlo al " +  oDestino:Cargo )
   RETURN NIL

EndIf

If cOrigen == "BRW" .and. cDestino == "LBX"
   oDestino:Add( uDropInfo)
EndIf
RETURN NIL
 
miarcod
 
Posts: 197
Joined: Tue Oct 11, 2005 2:17 pm

Re: Drag and Drop en un Browse.

Postby miarcod » Sat May 07, 2022 10:48 am

Hola de nuevo

Bueno he retomado este tema y como pensé que el problema era que no se podia arrastra de un listbox a un xbrowxe lo probe con xbrowse solo y me doy cuenta que el problema no está en arrastrar de un control a otro sino la posición que ocupan en el dialogo

Si el se arrastra de un xbrowse a la derecha, a la izquierda o abajo no hay problema pero si se arrastra de un xbrowse otro control que está arriba no se ejecuta bDropOver. Supongo que el xBrowse origen está esperando algo ya que no se libera el arrastre hasta que se hace un nuevo click en el browse origen

Alguna idea de que tengo que cambiar para poder arrastra de abajo arriba desde un xbrowse
Gracias

Este es el ejemplo con el que estoy probando

Code: Select all  Expand view
#include "Fivewin.ch"

function Main()
    Local oDlg
    Local oLbx1, oLbx2, oLbx3, cValue, aItems
    Local oBrw1, oBrw2, oBrw3
    Local oCursor, oOrigen, oDestino

    DEFINE CURSOR oCursor drag

    aItems := { "UNO", "DOS", "TRES", "CUATRO", "CINCO", "SEIS", "SIETE" }
    DEFINE DIALOG oDlg SIZE 800,600

    @  10,  10 LISTBOX oLbx1 VAR cValue ITEMS aItems ;
               SIZE 80, 100 PIXEL OF oDlg

    @  10, 100 LISTBOX oLbx2 VAR cValue ITEMS {} ;
               SIZE 80, 100 PIXEL OF oDlg

    @  10, 300 XBROWSE oBrw1 OF oDlg COLUMNS 1 ;
               ARRAY { "Item 1","Item 2","Item 3","Item 4" } ;
               SIZE 100, 100 PIXEL

    @ 120,  10 XBROWSE oBrw2 OF oDlg COLUMNS 1 ;
               ARRAY { "Item 1","Item 2","Item 3","Item 4" } ;
               SIZE 100, 100 PIXEL

    @ 120, 120 XBROWSE oBrw3 OF oDlg COLUMNS 1 ;
               ARRAY { "Item 11","Item 12","Item 13","Item 14" } ;
               SIZE 100, 100 PIXEL

    @ 120, 300 LISTBOX oLbx3 VAR cValue ITEMS {} ;
               SIZE 80, 100 PIXEL OF oDlg

    oBrw1:CreateFromCode()
    oBrw2:CreateFromCode()
    oBrw3:CreateFromCode()

    oLbx1:Cargo := "LBX1"
    oLbx2:Cargo := "LBX2"
    oLbx3:Cargo := "LBX3"

    oBrw1:Cargo := "BRW1"
    oBrw2:Cargo := "BRW2"
    oBrw3:Cargo := "BRW3"


    // DEFINIR DRAG AND DROP


    oLbx1:oDragCursor := oCursor
    oLbx1:bDragBegin  := { |            nRow, nCol, nKeyFlags | ;
                                        oOrigen := oLbx1,       ;
                                        SetBegin(oOrigen) }
    oLbx1:bDropOver   := { | uDropInfo, nRow, nCol, nKeyFlags | ;
                                        oDestino := oLbx1,      ;
                                        SetOver(uDropInfo, nRow, nCol, nKeyFlags, oOrigen, oDestino) }

    oLbx2:oDragCursor := oCursor
    oLbx2:bDragBegin  := { |            nRow, nCol, nKeyFlags | ;
                                        oOrigen := oLbx2,       ;
                                        SetBegin(oOrigen) }
    oLbx2:bDropOver   := { | uDropInfo, nRow, nCol, nKeyFlags | ;
                                        oDestino := oLbx2,      ;
                                        SetOver(uDropInfo, nRow, nCol, nKeyFlags, oOrigen, oDestino) }

    oLbx3:oDragCursor := oCursor
    oLbx3:bDragBegin  := { |            nRow, nCol, nKeyFlags | ;
                                        oOrigen := oLbx3,       ;
                                        SetBegin(oOrigen) }
    oLbx3:bDropOver   := { | uDropInfo, nRow, nCol, nKeyFlags | ;
                                        oDestino := oLbx3,      ;
                                        SetOver(uDropInfo, nRow, nCol, nKeyFlags, oOrigen, oDestino) }

    oBrw1:oDragCursor := oCursor
    oBrw1:bDragBegin  := { |            nRow, nCol, nKeyFlags | ;
                                        oOrigen := oBrw1,       ;
                                        SetBegin(oOrigen) }
    oBrw1:bDropOver   := { | uDropInfo, nRow, nCol, nKeyFlags | ;
                                        oDestino := oBrw1,      ;
                                        SetOver(uDropInfo, nRow, nCol, nKeyFlags, oOrigen, oDestino) }

    oBrw2:oDragCursor := oCursor
    oBrw2:bDragBegin  := { |            nRow, nCol, nKeyFlags | ;
                                        oOrigen := oBrw2,       ;
                                        SetBegin(oOrigen) }
    oBrw2:bDropOver   := { | uDropInfo, nRow, nCol, nKeyFlags | ;
                                        oDestino := oBrw2,      ;
                                        SetOver(uDropInfo, nRow, nCol, nKeyFlags, oOrigen, oDestino) }

    oBrw3:oDragCursor := oCursor
    oBrw3:bDragBegin  := { |            nRow, nCol, nKeyFlags | ;
                                        oOrigen := oBrw3,       ;
                                        SetBegin(oOrigen) }
    oBrw3:bDropOver   := { | uDropInfo, nRow, nCol, nKeyFlags | ;
                                        oDestino := oBrw3,      ;
                                        SetOver(uDropInfo, nRow, nCol, nKeyFlags, oOrigen, oDestino) }



    ACTIVATE DIALOG oDlg CENTER



RETURN .F.

//-----------------------**-----------------------------------------------//
STATIC FUNCTION SetBegin(oOrigen)
/*
Local cOrigen := Left(oOrigen:Cargo, 3)

If cOrigen == "LBX"
   If len(oOrigen:aItems) >0
      SetDropInfo( oOrigen:getSelText() )
   EndIf
   RETURN NIL
EndIf

If cOrigen == "BRW"
   SetDropInfo( oOrigen:aArrayData[oOrigen:nArrayAt] )
EndIf
*/


RETURN NIL

//-----------------------**-----------------------------------------------//
STATIC FUNCTION SetOver( uDropInfo, nRow, nCol, nKeyFlags,;
                         oOrigen, oDestino)
Msginfo("Arratrando " + oOrigen:Cargo + " a " + oDestino:Cargo)
RETURN NIL



return nil

 
miarcod
 
Posts: 197
Joined: Tue Oct 11, 2005 2:17 pm

Re: Drag and Drop en un Browse.

Postby miarcod » Mon May 09, 2022 3:30 pm

Bueno,
Investigando he llegado a la conclusión de que el problema se encuentra en la clase XBROWSE, concretamente en el método

Code: Select all  Expand view
METHOD LButtonUp( nRow, nCol, nFlags ) CLASS TXBrowse
   local nCaptured
   local nRowAdvanced, nTimeScrolled, nVelocity, nRowToAdvance
   local nRatio, n, cMsg := ""

   if ::lDrag
      return ::Super:LButtonUp( nRow, nCol, nFlags )
   endif

   If nRow <= ::nTopBarHeight
      return 0
   endif

...

 


La solución que se ma ha ocurrido es agregar

Code: Select all  Expand view

   If nRow <= ::nTopBarHeight .and. ::nTopBarHeight != 0.00
      return 0
   endif
 

Con esto obtengo el comportamiento desaado, aunque no tengo del todo claro para que se utiliza la variable nTopBarHeight , por lo cual no se si esto me afectará en otra parte, creo que esto es un BUG de esta clase

Agradecería algún comentario al respecto.

Gracias y un saludo
miarcod
 
Posts: 197
Joined: Tue Oct 11, 2005 2:17 pm


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 96 guests