Another drag-drop example with drag image (PB 4.1)

Share your advanced PureBasic knowledge/code with the community.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Another drag-drop example with drag image (PB 4.1)

Post by srod »

Not as sophisticated as netmaestro's example and it uses a different method to render the image.

Still, we begin to see what an excellent library the drag and drop one is.

Code: Select all

;An example of the new Drag and Drop library for Purebasic 4.1.
;==============================================================
;Uses a DragCallback to display an image whilst an item of text is being dragged between
;two listicons.

;   Example by netmaestro with the image drag added by srod.
;   Created with Purebasic 4.1 (beta 1) for Windows.
;   Date:  May 2007.
;   Platforms:  Windows.


Declare.l DragCallBack(Action)

Structure _drag
  image.l
  hdc.l
  ihdc.l
  oldimage.l
  x.l
  y.l
  width.l
  height.l
EndStructure


Global gDrag._drag


OpenWindow(0,0,0,480,400,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 
CreateGadgetList(WindowID(0)) 
ListIconGadget(0,20,20,200,300,"Gadget 0", 195, #PB_ListIcon_FullRowSelect) 
ListIconGadget(1,250,20,200,300,"Gadget 1", 195, #PB_ListIcon_FullRowSelect) 

AddGadgetItem(0, -1, "Arthur") 
AddGadgetItem(0, -1, "Beryl") 
AddGadgetItem(0, -1, "Charles") 
AddGadgetItem(0, -1, "Daniel") 
AddGadgetItem(0, -1, "Ernest") 
AddGadgetItem(0, -1, "Francis") 
AddGadgetItem(0, -1, "Gordon") 
AddGadgetItem(0, -1, "Harold") 
AddGadgetItem(0, -1, "Ian") 
AddGadgetItem(0, -1, "John") 

EnableGadgetDrop(0,#PB_Drop_Text, #PB_Drag_Copy) 
EnableGadgetDrop(1,#PB_Drop_Text, #PB_Drag_Copy) 

Repeat 
  ev = WaitWindowEvent() 
  Select ev 
    Case #PB_Event_GadgetDrop 
      RemoveGadgetItem(draggadget, dragrow) 
      AddGadgetItem(EventGadget(), GetGadgetState(EventGadget()), EventDropText()) 
    Case #PB_Event_Gadget 
      If EventType() = #PB_EventType_DragStart 
        dragrow = GetGadgetState(EventGadget()) 
        dragtxt.s = GetGadgetItemText(EventGadget(), dragrow) 
        draggadget = EventGadget() 
        ;Create drag image.
          StartDrawing(WindowOutput(0))
            DrawingFont(GetGadgetFont(draggadget))
            gDrag\width = TextWidth(dragtxt) : gDrag\height = TextHeight(dragtxt)
          StopDrawing()
          gDrag\image = CreateImage(#PB_Any, gDrag\width, gDrag\height)
          StartDrawing(ImageOutput(gDrag\image))
            DrawingFont(GetGadgetFont(draggadget))
            DrawingMode(#PB_2DDrawing_Transparent)
            DrawText(0,0,dragtxt,#White)
          StopDrawing()
        gDragx = -1 : gDrag\y = -1
        gDrag\hdc = CreateDC_("DISPLAY",0,0,0)
        gDrag\ihdc = CreateCompatibleDC_(gDrag\hdc)
        gDrag\oldimage=SelectObject_(gDrag\ihdc, ImageID(gDrag\image))
        SetDragCallback(@DragCallBack())
        DragText(dragtxt, #PB_Drag_Copy) 
        ;Now tidy up.
          DragCallBack(#PB_Drag_None) ;This will effectively remove the last drag image.
          SelectObject_(gDrag\ihdc, gDrag\oldimage)
          DeleteDC_(gDrag\ihdc)
          DeleteDC_(gDrag\hdc)
          FreeImage(gDrag\image)
      EndIf 
 EndSelect 
Until ev = #PB_Event_CloseWindow 


Procedure.l DragCallBack(Action)
  If gDrag\x>-1 And gDrag\y>-1
    BitBlt_(gDrag\hdc,gDrag\x,gDrag\y,gDrag\width,gDrag\height,gDrag\ihdc,0,0,#SRCINVERT) 
  EndIf
  RedrawWindow_(WindowID(0), 0, 0, #RDW_UPDATENOW)
  If action<>#PB_Drag_None
    gDrag\x = DesktopMouseX()
    gDrag\y = DesktopMouseY()
    BitBlt_(gDrag\hdc,gDrag\x,gDrag\y,gDrag\width,gDrag\height,gDrag\ihdc,0,0,#SRCINVERT) 
  Else
    gDrag\x = -1 : gDrag\y = -1
  EndIf
  ProcedureReturn 1
EndProcedure
Last edited by srod on Fri Jun 01, 2007 11:12 am, edited 1 time in total.
I may look like a mule, but I'm not a complete ass.
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Post by ts-soft »

nice code, but a small problem :wink:
if i drop 10x John in the same listicongadget, i have only John's :D
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

ts-soft wrote:nice code, but a small problem :wink:
if i drop 10x John in the same listicongadget, i have only John's :D
Doh! :)

Fixed.
I may look like a mule, but I'm not a complete ass.
Derek
Addict
Addict
Posts: 2356
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

A little annoyance, if I start to drag Arthur and then realise I wanted to drag something else instead then I would probably guess that I would need to put Arthur back where it came from, not so. I have to put it back by highlighting Beryl otherwise Arthur gets pushed to the bottom of the list.

It kind of makes sense because it is being pushed out of the top and coming back at the bottom of the list but it does kind of seem wrong that you don't just put back a mis-dragged item in the same place.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

You can easily alter the source to cancel the drag under a myriad of circumstances! This was primarily an example of using the drag callback to show a drag image etc.
I may look like a mule, but I'm not a complete ass.
Derek
Addict
Addict
Posts: 2356
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

I wasn't having a go at the code, just the functionality of it. I didn't know if it was the way the new drag and drop library works in which case it is going to happen in any program that uses drag and drop.

I haven't had time yet to actually lookat the new features myself so I'm just looking at code examples when they come along.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Here's a version which allows you to cancel the drop by releasing the mouse whilst hovering over the original item etc.

Code: Select all

;An example of the new Drag and Drop library for Purebasic 4.1.
;==============================================================
;Uses a DragCallback to display an image whilst an item of text is being dragged between
;two listicons.

;   Example by netmaestro with the image drag added by srod.
;   Created with Purebasic 4.1 (beta 1) for Windows.
;   Date:  May 2007.
;   Platforms:  Windows.


Declare.l DragCallBack(Action)

Structure _drag
  image.l
  hdc.l
  ihdc.l
  oldimage.l
  x.l
  y.l
  width.l
  height.l
EndStructure


Global gDrag._drag


OpenWindow(0,0,0,480,400,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 
CreateGadgetList(WindowID(0)) 
ListIconGadget(0,20,20,200,300,"Gadget 0", 195, #PB_ListIcon_FullRowSelect) 
ListIconGadget(1,250,20,200,300,"Gadget 1", 195, #PB_ListIcon_FullRowSelect) 

AddGadgetItem(0, -1, "Arthur") 
AddGadgetItem(0, -1, "Beryl") 
AddGadgetItem(0, -1, "Charles") 
AddGadgetItem(0, -1, "Daniel") 
AddGadgetItem(0, -1, "Ernest") 
AddGadgetItem(0, -1, "Francis") 
AddGadgetItem(0, -1, "Gordon") 
AddGadgetItem(0, -1, "Harold") 
AddGadgetItem(0, -1, "Ian") 
AddGadgetItem(0, -1, "John") 

EnableGadgetDrop(0,#PB_Drop_Text, #PB_Drag_Copy) 
EnableGadgetDrop(1,#PB_Drop_Text, #PB_Drag_Copy) 

Repeat 
  ev = WaitWindowEvent() 
  Select ev 
    Case #PB_Event_GadgetDrop 
      If draggadget <> EventGadget() Or dragrow <> GetGadgetState(EventGadget())
        RemoveGadgetItem(draggadget, dragrow) 
        AddGadgetItem(EventGadget(), GetGadgetState(EventGadget()), EventDropText()) 
      endif
    Case #PB_Event_Gadget 
      If EventType() = #PB_EventType_DragStart 
        dragrow = GetGadgetState(EventGadget()) 
        dragtxt.s = GetGadgetItemText(EventGadget(), dragrow) 
        draggadget = EventGadget() 
        ;Create drag image.
          StartDrawing(WindowOutput(0))
            DrawingFont(GetGadgetFont(draggadget))
            gDrag\width = TextWidth(dragtxt) : gDrag\height = TextHeight(dragtxt)
          StopDrawing()
          gDrag\image = CreateImage(#PB_Any, gDrag\width, gDrag\height)
          StartDrawing(ImageOutput(gDrag\image))
            DrawingFont(GetGadgetFont(draggadget))
            DrawingMode(#PB_2DDrawing_Transparent)
            DrawText(0,0,dragtxt,#White)
          StopDrawing()
        gDragx = -1 : gDrag\y = -1
        gDrag\hdc = CreateDC_("DISPLAY",0,0,0)
        gDrag\ihdc = CreateCompatibleDC_(gDrag\hdc)
        gDrag\oldimage=SelectObject_(gDrag\ihdc, ImageID(gDrag\image))
        SetDragCallback(@DragCallBack())
        DragText(dragtxt, #PB_Drag_Copy) 
        ;Now tidy up.
          DragCallBack(#PB_Drag_None) ;This will effectively remove the last drag image.
          SelectObject_(gDrag\ihdc, gDrag\oldimage)
          DeleteDC_(gDrag\ihdc)
          DeleteDC_(gDrag\hdc)
          FreeImage(gDrag\image)
      EndIf 
 EndSelect 
Until ev = #PB_Event_CloseWindow 


Procedure.l DragCallBack(Action)
  If gDrag\x>-1 And gDrag\y>-1
    BitBlt_(gDrag\hdc,gDrag\x,gDrag\y,gDrag\width,gDrag\height,gDrag\ihdc,0,0,#SRCINVERT) 
  EndIf
  RedrawWindow_(WindowID(0), 0, 0, #RDW_UPDATENOW)
  If action<>#PB_Drag_None
    gDrag\x = DesktopMouseX()
    gDrag\y = DesktopMouseY()
    BitBlt_(gDrag\hdc,gDrag\x,gDrag\y,gDrag\width,gDrag\height,gDrag\ihdc,0,0,#SRCINVERT) 
  Else
    gDrag\x = -1 : gDrag\y = -1
  EndIf
  ProcedureReturn 1
EndProcedure
I may look like a mule, but I'm not a complete ass.
Derek
Addict
Addict
Posts: 2356
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Brilliant, thanks srod. Will have a good look at these when I find time. :)
freak
PureBasic Team
PureBasic Team
Posts: 5929
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

You can also just press escape to abort the drag... ;)
quidquid Latine dictum sit altum videtur
User avatar
DoubleDutch
Addict
Addict
Posts: 3219
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

On vista (using those examples) dragging reveals the vista desktop.
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

DoubleDutch wrote:On vista (using those examples) dragging reveals the vista desktop.
That way you can see what's going on! :wink:

I don't use Vista so I can't comment, except to say that I am drawing directly to the desktop rather than the underlying application window. I'll try changing this.

Does it do the same with Freak's examples which do not utilise a drag image?
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

DoubleDutch: does the following still display the Vista desktop?

Code: Select all

;An example of the new Drag and Drop library for Purebasic 4.1.
;==============================================================
;Uses a DragCallback to display an image whilst an item of text is being dragged between
;two listicons.

;   Example by netmaestro with the image drag added by srod.
;   Created with Purebasic 4.1 (beta 1) for Windows.
;   Date:  May 2007.
;   Platforms:  Windows.


Declare.l DragCallBack(Action)

Structure _drag
  image.l
  hdc.l
  ihdc.l
  oldimage.l
  x.l
  y.l
  width.l
  height.l
EndStructure


Global gDrag._drag


OpenWindow(0,0,0,480,400,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 
CreateGadgetList(WindowID(0)) 
ListIconGadget(0,20,20,200,300,"Gadget 0", 195, #PB_ListIcon_FullRowSelect) 
ListIconGadget(1,250,20,200,300,"Gadget 1", 195, #PB_ListIcon_FullRowSelect) 

AddGadgetItem(0, -1, "Arthur") 
AddGadgetItem(0, -1, "Beryl") 
AddGadgetItem(0, -1, "Charles") 
AddGadgetItem(0, -1, "Daniel") 
AddGadgetItem(0, -1, "Ernest") 
AddGadgetItem(0, -1, "Francis") 
AddGadgetItem(0, -1, "Gordon") 
AddGadgetItem(0, -1, "Harold") 
AddGadgetItem(0, -1, "Ian") 
AddGadgetItem(0, -1, "John") 

EnableGadgetDrop(0,#PB_Drop_Text, #PB_Drag_Copy) 
EnableGadgetDrop(1,#PB_Drop_Text, #PB_Drag_Copy) 

Repeat 
  ev = WaitWindowEvent() 
  Select ev 
    Case #PB_Event_GadgetDrop 
      If draggadget <> EventGadget() Or dragrow <> GetGadgetState(EventGadget())
        RemoveGadgetItem(draggadget, dragrow) 
        AddGadgetItem(EventGadget(), GetGadgetState(EventGadget()), EventDropText()) 
      EndIf
    Case #PB_Event_Gadget 
      If EventType() = #PB_EventType_DragStart 
        dragrow = GetGadgetState(EventGadget()) 
        dragtxt.s = GetGadgetItemText(EventGadget(), dragrow) 
        draggadget = EventGadget() 
        ;Create drag image.
          StartDrawing(WindowOutput(0))
            DrawingFont(GetGadgetFont(draggadget))
            gDrag\width = TextWidth(dragtxt) : gDrag\height = TextHeight(dragtxt)
          StopDrawing()
          gDrag\image = CreateImage(#PB_Any, gDrag\width, gDrag\height)
          StartDrawing(ImageOutput(gDrag\image))
            DrawingFont(GetGadgetFont(draggadget))
            DrawingMode(#PB_2DDrawing_Transparent)
            DrawText(0,0,dragtxt,#White)
          StopDrawing()
        gDragx = -1 : gDrag\y = -1
        gDrag\hdc = GetDC_(WindowID(0))
        gDrag\ihdc = CreateCompatibleDC_(gDrag\hdc)
        gDrag\oldimage=SelectObject_(gDrag\ihdc, ImageID(gDrag\image))
        SetDragCallback(@DragCallBack())
        DragText(dragtxt, #PB_Drag_Copy) 
        ;Now tidy up.
          DragCallBack(#PB_Drag_None) ;This will effectively remove the last drag image.
          SelectObject_(gDrag\ihdc, gDrag\oldimage)
          DeleteDC_(gDrag\ihdc)
          DeleteDC_(gDrag\hdc)
          FreeImage(gDrag\image)
      EndIf 
 EndSelect 
Until ev = #PB_Event_CloseWindow 


Procedure.l DragCallBack(Action)
  If gDrag\x>-1 And gDrag\y>-1
    BitBlt_(gDrag\hdc,gDrag\x,gDrag\y,gDrag\width,gDrag\height,gDrag\ihdc,0,0,#SRCINVERT) 
  EndIf
  RedrawWindow_(WindowID(0), 0, 0, #RDW_UPDATENOW)
  If action<>#PB_Drag_None
    gDrag\x = WindowMouseX(0)
    gDrag\y = WindowMouseY(0)
    BitBlt_(gDrag\hdc,gDrag\x,gDrag\y,gDrag\width,gDrag\height,gDrag\ihdc,0,0,#SRCINVERT) 
  Else
    gDrag\x = -1 : gDrag\y = -1
  EndIf
  ProcedureReturn 1
EndProcedure
I may look like a mule, but I'm not a complete ass.
User avatar
DoubleDutch
Addict
Addict
Posts: 3219
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

That works fine with vista. :)
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Post by ts-soft »

@srod
have you an example with treegadget? Sort the items per drag & drop,
copying image, gadgetdata , all :wink:

This is for a real project and i have only problems with this.
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Great.

Something to remember about Vista!

Thanks.
I may look like a mule, but I'm not a complete ass.
Post Reply