Page 1 of 1

FrameGadget() can defeat Drag and Drop

Posted: Sat Oct 03, 2020 4:33 am
by Little John
In the Help of PB 5.72 concerning FrameGadget(), it reads
This kind of gadget is decorative only.
This is currently not quite true.

Calling the FrameGadget() function can defeat Drag and Drop, depending on the exact place in the source code where it is used (tested on Windows). This is demonstrated by the following examples:
  • In the first example, FrameGadget() comes before StringGadget()
    --> Drag and Drop does not work with StringGadget().
    //edit: As BarryG pointed out, this example would work without the flag #PB_Frame_Flat.
  • In the second example, FrameGadget() comes after StringGadget()
    --> Drag and Drop does work with StringGadget().

Code: Select all

; PB 5.72

EnableExplicit

; Windows
#WinMain = 0

; Gadgets
Enumeration
   #Frame1
   #Text1
   #String1
   #Frame2
   #Text2
   #String2
   #BtnQuit
EndEnumeration

#WinWidth  = 400
#WinHeight = 280
#Frame1X   =  10
#Frame1Y   =  20
#Frame2X   =  10
#Frame2Y   = 120


Define event.i, dropped$

If OpenWindow(#WinMain, 0,0, #WinWidth,#WinHeight, "Drag and Drop files",
              #PB_Window_ScreenCentered|#PB_Window_MinimizeGadget) = 0
   MessageRequester("Fatal error",
                    "Can't open main window.",
                    #PB_MessageRequester_Error)
   End
EndIf

FrameGadget(#Frame1,   #Frame1X,    #Frame1Y,    #WinWidth-20,75, "", #PB_Frame_Flat)
TextGadget(#Text1,     #Frame1X+10, #Frame1Y+15, 260,20, "Does not work")
StringGadget(#String1, #Frame1X+10, #Frame1Y+35, #WinWidth-40,20, "")

TextGadget(#Text2,     #Frame2X+10,#Frame2Y+15, 100,20, "Works")
StringGadget(#String2, #Frame2X+10,#Frame2Y+35, #WinWidth-40,20, "")
FrameGadget(#Frame2,   #Frame2X,   #Frame2Y,    #WinWidth-20,75, "", #PB_Frame_Flat)

ButtonGadget(#BtnQuit, #WinWidth-90,#WinHeight-50, 80,25, "Quit")

EnableGadgetDrop(#String1, #PB_Drop_Files, #PB_Drag_Copy)
EnableGadgetDrop(#String2, #PB_Drop_Files, #PB_Drag_Copy)

SetActiveGadget(#String1)

Repeat
   event = WaitWindowEvent()

   Select event
      Case #PB_Event_Gadget
         If EventGadget() = #BtnQuit
            Break
         EndIf

      Case #PB_Event_GadgetDrop
         dropped$ = StringField(EventDropFiles(), 1, #LF$)
         SetGadgetText(EventGadget(), dropped$)
         SetActiveGadget(EventGadget())
   EndSelect
Until event = #PB_Event_CloseWindow

CloseWindow(#WinMain)
This is either a bug in PureBasic itself or in the documentation.

Re: FrameGadget() can defeat Drag and Drop

Posted: Sat Oct 03, 2020 6:03 am
by BarryG
Confirmed, but remove #PB_Frame_Flat and it works for the first example. So #PB_Frame_Flat is causing the problem.

Re: FrameGadget() can defeat Drag and Drop

Posted: Sat Oct 03, 2020 6:27 am
by chi
Not a bug! Windows draws its controls from top to bottom. When you create the Frame first and then the Stringgadget, the Frame is on top of the Stringgadget... Thus, the Frame is blocking Drag/Drop.
If you have a Framegadget with other Gadget "in it", always create the Frame last! (like in your second example).

quick test

Code: Select all

;replace
  EnableGadgetDrop(#String1, #PB_Drop_Files, #PB_Drag_Copy)
;with
  EnableGadgetDrop(#Frame1, #PB_Drop_Files, #PB_Drag_Copy)
;and the frame will respond to DnD
you could also use

Code: Select all

BringWindowToTop_(GadgetID(#String1))
afterwards, if you don't want to restructure your code.

If you remove #PB_Frame_Flat from the Frame, Windows will create the Frame as a Button Control instead of a Static Control and it will also work...

Re: FrameGadget() can defeat Drag and Drop

Posted: Sat Oct 03, 2020 6:34 am
by BarryG
chi wrote:Not a bug!
You missed my #PB_Frame_Flat comment. It is a bug because the command should work the same whether the #PB_Frame_Flat is used or not.

Re: FrameGadget() can defeat Drag and Drop

Posted: Sat Oct 03, 2020 6:49 am
by chi
BarryG wrote:
chi wrote:Not a bug!
You missed my #PB_Frame_Flat comment. It is a bug because the command should work the same whether the #PB_Frame_Flat is used or not.
Yeah, I missed it... But PB creates two different controls depending on whether you have specified #PB_Frame_Flat or not. Without you get a Button Control that doesn't block the underlying controls, with #PB_Frame_Flat you get a Static Control that blocks.

Re: FrameGadget() can defeat Drag and Drop

Posted: Sat Oct 03, 2020 7:49 am
by Little John
chi wrote:quick test

Code: Select all

;replace
  EnableGadgetDrop(#String1, #PB_Drop_Files, #PB_Drag_Copy)
;with
  EnableGadgetDrop(#Frame1, #PB_Drop_Files, #PB_Drag_Copy)
;and the frame will respond to DnD
I know that this is technically possible, but that's not how I want my program to work.
And using the FrameGadget() as target for Drag and Drop would also be a contradiction to the statement in the Help:
This kind of gadget is decorative only.
As I already wrote: If all this is the intended behaviour, then it should be documented properly.

Re: FrameGadget() can defeat Drag and Drop

Posted: Sat Oct 03, 2020 7:49 am
by Little John
BarryG wrote:Confirmed, but remove #PB_Frame_Flat and it works for the first example. So #PB_Frame_Flat is causing the problem.
Good catch, thank you!