Page 1 of 1
Drag and Drop (for "Cards")
Posted: Fri Jan 06, 2023 3:23 pm
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!
Re: Drag and Drop (for "Cards")
Posted: Fri Jan 06, 2023 3:28 pm
by useful
Re: Drag and Drop (for "Cards")
Posted: Fri Jan 06, 2023 4:20 pm
by bembulak
Re: Drag and Drop (for "Cards")
Posted: Fri Jan 06, 2023 9:31 pm
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/
Re: Drag and Drop (for "Cards")
Posted: Sat Jan 07, 2023 5:22 pm
by Dirk Geppert
@Peter: good to know! That opens up new horizons!
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())
Re: Drag and Drop (for "Cards")
Posted: Wed Jan 11, 2023 5:30 pm
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?
Re: Drag and Drop (for "Cards")
Posted: Wed Jan 11, 2023 6:26 pm
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)
Re: Drag and Drop (for "Cards")
Posted: Wed Jan 11, 2023 8:10 pm
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.
Re: Drag and Drop (for "Cards")
Posted: Wed Mar 06, 2024 9:04 pm
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?