Drag and Drop (for "Cards")

Just starting out? Need help? Post your questions and find answers here.
bembulak
Posts: 71
Joined: Wed Feb 26, 2014 9:53 am

Drag and Drop (for "Cards")

Post by bembulak »

Hi,

I've been playing around with Windows and Gadgets for a few days now. I'd like to drag and drop Gadgets around, but just can't bring anything to work.

My Idea was to have a window with some containers (FrameGadget or ContainerGadget?) and to move child-objects (canvas?) from on Frame to another.
Alternative would be to have windows and make them snappy according to their pos on the available space.

There is no drag and drop section in the help (current full version of SB, 2.40).

Is there no support for it, or is it so obvious and easy (and I don't see the solution for it)?

Thanks!
User avatar
useful
Posts: 116
Joined: Tue Feb 25, 2014 1:15 pm

Re: Drag and Drop (for "Cards")

Post by useful »

2B or not 2B = FF
bembulak
Posts: 71
Joined: Wed Feb 26, 2014 9:53 am

Re: Drag and Drop (for "Cards")

Post by bembulak »

useful wrote: Fri Jan 06, 2023 3:28 pm Drag & Drop Yes! https://www.purebasic.com/documentation/
Drag & Drop No! https://www.spiderbasic.com/documentation/
Thank you.
User avatar
Peter
Posts: 1086
Joined: Mon Feb 24, 2014 10:17 pm
Location: 127.0.0.1:9080
Contact:

Re: Drag and Drop (for "Cards")

Post by Peter »

With some knowledge of JavaScript, D&D is relatively easy to implement:

Code: Select all

If OpenWindow(0, 0, 0, 800, 800, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ContainerGadget(0, 200, 200, 400, 400, #PB_Container_Single) : CloseGadgetList()
EndIf

GID = GadgetID(0)

! $(v_gid.div).draggable();
See: https://jqueryui.com/draggable/ and https://jqueryui.com/droppable/
Dirk Geppert
Posts: 282
Joined: Fri Sep 22, 2017 7:02 am

Re: Drag and Drop (for "Cards")

Post by Dirk Geppert »

@Peter: good to know! That opens up new horizons! :D

Code: Select all

Procedure Events()
  
  SetGadgetText(1, "Dragged to: " + Str(GadgetX(1)) + ", " + Str(GadgetY(1)))
  
EndProcedure

If OpenWindow(0, 0, 0, 800, 800, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ContainerGadget(0, 200, 200, 400, 400, #PB_Container_Single) : CloseGadgetList()
  SetGadgetColor(0, #PB_Gadget_BackColor, #Red)
  ButtonGadget(1, 200, 700, 300, 50, "Drag me around")
EndIf

GID = GadgetID(0)

! $(v_gid.div).draggable();

GID = GadgetID(1)

! $(v_gid.div).draggable();

BindGadgetEvent(1, @Events())
bembulak
Posts: 71
Joined: Wed Feb 26, 2014 9:53 am

Re: Drag and Drop (for "Cards")

Post by bembulak »

That's really interesting!

The frame gets the "dropped Gadget" as parameter, right? Is there a way to get from the jQuery 'ui' object back to the SB Gadget-ID?

Example:

Code: Select all

; https://jqueryui.com/draggable/
; 

Enumeration
  #window
  #frame
  #button
EndEnumeration

Procedure ButtonHandler()
  Debug "Button click event on gadget #" + EventGadget()
EndProcedure
  
OpenWindow(#window, 10, 10, 460, 480, "Click test", #PB_Window_SystemMenu)
FrameGadget(#frame, 5, 5, 450, 200, "Drop on me!")
FRM = GadgetID(#frame)
! $(v_frm.div).droppable({
! drop: function(event, ui) {
  Debug "You dropped something onto me!"
  ; How to Get the GadgetID from function param "ui"?
  ! console.log(ui);
  Debug("the Frame: " + Str(#frame))
  Debug("the Gadget: " + Str(EventGadget()))
!}
!});

ButtonGadget(#button, 10, 220, 180, 30, "Click me")
GID2 = GadgetID(#Button)
! $(v_gid2.div).draggable();  
! $(v_gid2.div).on( "dragstop", function( event, ui ) { console.log("I was dropped");console.log(ui)} );
BindGadgetEvent(#button, @ButtonHandler())

In the browser's Dev-Tools, I see that the 'ui' is something like:

Code: Select all

// a lot more lines and not expanded:
Object { draggable: {…}, helper: {…}, position: {…}, offset: {…} }
draggable: Object { 0: div.ui-draggable
, length: 1 }
helper: Object { 0: div.ui-draggable
, length: 1 }
offset: Object { top: 83.79998779296875, left: 115.80000305175781 }
position: Object { top: 44.99998474121094, left: 105 }
<prototype>: Object { … }
If I had multiple objects, how would I determine, which was dropped onto the Frame? Any ideas?
User avatar
Peter
Posts: 1086
Joined: Mon Feb 24, 2014 10:17 pm
Location: 127.0.0.1:9080
Contact:

Re: Drag and Drop (for "Cards")

Post by Peter »

For example, you can use callbacks to find out which target was dropped on:

Code: Select all

Enumeration
  #window
  #card1
  #card2
  #card3
  #target1
  #target2
EndEnumeration

Procedure DroppedOnTarget1Callback()
  MessageRequester("Dropped on #target1")
EndProcedure

Procedure DroppedOnTarget2Callback()
  MessageRequester("Dropped on #target2")
EndProcedure

Procedure MakeDraggable(Gadget)
  
  Protected GID = GadgetID(Gadget)
  ! $(v_gid.div).draggable();
  
EndProcedure

Procedure MakeDroppable(Gadget, Callback)
  
  Protected GID = GadgetID(Gadget)
  ! $(v_gid.div).droppable({
  !   drop: function( event, ui ) {
  !     v_callback();
  !   }
  ! });  
  
EndProcedure

Procedure SetCanvasBackgroundColor(CanvasGadget, Color)
  If GadgetType(CanvasGadget) <> #PB_GadgetType_Canvas : ProcedureReturn : EndIf
  If StartDrawing(CanvasOutput(CanvasGadget))
    Box(0, 0, GadgetWidth(CanvasGadget), GadgetHeight(CanvasGadget), Color)
    StopDrawing()
  EndIf
EndProcedure



OpenWindow(#window, #PB_Ignore, #PB_Ignore, 800, 600, "", #PB_Window_ScreenCentered)

; Targets

CanvasGadget(#target1, 300, 10, 200, 200, #PB_Canvas_Border)
MakeDroppable(#target1, @DroppedOnTarget1Callback())

CanvasGadget(#target2, 300, 300, 200, 200, #PB_Canvas_Border)
MakeDroppable(#target2, @DroppedOnTarget2Callback())

; Cards

CanvasGadget(#card1, 10, 10, 100, 150, #PB_Canvas_Border)
SetCanvasBackgroundColor(#card1, #Red)
MakeDraggable(#card1)

CanvasGadget(#card2, 15, 15, 100, 150, #PB_Canvas_Border)
SetCanvasBackgroundColor(#card2, #Blue)
MakeDraggable(#card2)

CanvasGadget(#card3, 20, 20, 100, 150, #PB_Canvas_Border)
SetCanvasBackgroundColor(#card3, #Green)
MakeDraggable(#card3)
bembulak
Posts: 71
Joined: Wed Feb 26, 2014 9:53 am

Re: Drag and Drop (for "Cards")

Post by bembulak »

Peter wrote: Wed Jan 11, 2023 6:26 pm For example, you can use callbacks to find out which target was dropped on:

Code: Select all

Enumeration
  #window
  #card1
  #card2
  #card3
  #target1
  #target2
EndEnumeration

Procedure DroppedOnTarget1Callback()
  MessageRequester("Dropped on #target1")
EndProcedure

Procedure DroppedOnTarget2Callback()
  MessageRequester("Dropped on #target2")
EndProcedure

Procedure MakeDraggable(Gadget)
  
  Protected GID = GadgetID(Gadget)
  ! $(v_gid.div).draggable();
  
EndProcedure

Procedure MakeDroppable(Gadget, Callback)
  
  Protected GID = GadgetID(Gadget)
  ! $(v_gid.div).droppable({
  !   drop: function( event, ui ) {
  !     v_callback();
  !   }
  ! });  
  
EndProcedure

Procedure SetCanvasBackgroundColor(CanvasGadget, Color)
  If GadgetType(CanvasGadget) <> #PB_GadgetType_Canvas : ProcedureReturn : EndIf
  If StartDrawing(CanvasOutput(CanvasGadget))
    Box(0, 0, GadgetWidth(CanvasGadget), GadgetHeight(CanvasGadget), Color)
    StopDrawing()
  EndIf
EndProcedure



OpenWindow(#window, #PB_Ignore, #PB_Ignore, 800, 600, "", #PB_Window_ScreenCentered)

; Targets

CanvasGadget(#target1, 300, 10, 200, 200, #PB_Canvas_Border)
MakeDroppable(#target1, @DroppedOnTarget1Callback())

CanvasGadget(#target2, 300, 300, 200, 200, #PB_Canvas_Border)
MakeDroppable(#target2, @DroppedOnTarget2Callback())

; Cards

CanvasGadget(#card1, 10, 10, 100, 150, #PB_Canvas_Border)
SetCanvasBackgroundColor(#card1, #Red)
MakeDraggable(#card1)

CanvasGadget(#card2, 15, 15, 100, 150, #PB_Canvas_Border)
SetCanvasBackgroundColor(#card2, #Blue)
MakeDraggable(#card2)

CanvasGadget(#card3, 20, 20, 100, 150, #PB_Canvas_Border)
SetCanvasBackgroundColor(#card3, #Green)
MakeDraggable(#card3)
Wow, that's fantastic! Thank you.

Your contributions to this community are priceless.
munfraid
Posts: 104
Joined: Sat Mar 24, 2018 1:33 pm

Re: Drag and Drop (for "Cards")

Post by munfraid »

Yes, this is really awesome, thanks for this!
Unfortunately it just works with the mouse. On touch devices it's not working. Is there a way to make this possible?
Post Reply