How to drag and drop on ListIconGadget() ?

Mac OSX specific forum
Wolfram
Enthusiast
Enthusiast
Posts: 568
Joined: Thu May 30, 2013 4:39 pm

How to drag and drop on ListIconGadget() ?

Post by Wolfram »

How can I drag and drop AAA to BBB?
And is it possible to get the Column and Row no. on drag and drop?

Code: Select all

Global Window_0, MyList


Procedure OpenWindow_0(x = 0, y = 0, width = 450, height = 160)
  Window_0 = OpenWindow(#PB_Any, x, y, width, height, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  MyList = ListIconGadget(#PB_Any, 25, 40, 408, 100, "L1", 200)
  AddGadgetColumn(MyList, 1, "L2", 200)
  AddGadgetItem(MyList, 1, "AAA"+ Chr(10) +"BBB")
  
  EnableGadgetDrop(MyList, #PB_Drop_Text, #PB_Drag_Move)
  
EndProcedure

Procedure Window_0_Events(event)
  Select event
    Case #PB_Event_CloseWindow
      ProcedureReturn #False
      
    Case #PB_Event_Menu
      Select EventMenu()
        Case -1
          ProcedureReturn #False
      EndSelect
      
    Case #PB_Event_Gadget
      Select EventGadget()
      Case MyList    
          
      EndSelect
    Case #PB_Event_GadgetDrop
      Debug "drop"
      
  EndSelect
  ProcedureReturn #True
EndProcedure

OpenWindow_0()

Repeat
  event = WaitWindowEvent()
Until Window_0_Events(event) = #False

End
macOS Catalina 10.15.7
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: How to drag and drop on ListIconGadget() ?

Post by Shardik »

Unfortunately drag 'n drop is still broken in several functions of PB's MacOS X version using the Cocoa framework whereas it's working much better in the old deprecated Carbon framework (the last PB version with subsystem Carbon was 5.11 x86).

fsw has collected 5 links with drag 'n drop problems in this thread of the "Bugs - MacOS X" subforum where Fred said:
Fred wrote:Cocoa drag'n'drop model is not fully compatiable with PB model, I don't know how to work around it (for now).
Therefore a solution is unneccessary complex and the handling is somewhat different from that on Windows, Linux and even the Carbon framework. I had already found out some time ago that drag 'n drop is only working for the ListIconGadget or ListViewGadget in the Cocoa framework, if the cell content is in edit mode. So my example utilizes this already complicated example from me allowing to edit a cell of a ListIconGadget. This example is enhanced further to allow moving a cell content from one cell to another cell. It also demonstrates how to obtain row and column of the drag start cell and of the drop cell.

But due to the drag 'n drop implementation in the Cocoa framework you have to be patient: :wink:
1. After a left click into a cell its content will be selected.
2. Now you have to wait for about 5 seconds!
3. Then please do a second left click onto the selected cell content and keep the left mouse button depressed!
4. The mouse cursor will change to an arrow. Still keep the left mouse button depressed and drag the cell content to another cell.
5. Release the left mouse button and the text will overwrite the cell under the cursor.
6. The cell content at the start of the dragging operation will be erased.

Code: Select all

EnableExplicit

ImportC ""
  sel_registerName(MethodName.P-UTF8)
  class_addMethod(Class.I, Selector.I, Implementation.I, Types.P-UTF8)
EndImport

ProcedureC EditingFinishedCallback(Object.I, Selector.I, Notification.I)
  Protected EditedCell.I
  Protected EditedColumn.I = CocoaMessage(0, GadgetID(0), "editedColumn")
  Protected EditedRow.I = CocoaMessage(0, GadgetID(0), "editedRow")
  Protected EditedText.S

  EditedCell = CocoaMessage(0, Notification, "object")
  EditedText = PeekS(CocoaMessage(0, CocoaMessage(0, EditedCell, "stringValue"),
    "UTF8String"), -1, #PB_UTF8)
  SetGadgetItemText(0, EditedRow, EditedText, EditedColumn)
EndProcedure

Define CursorLocation.NSPoint
Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
  "NSApplication sharedApplication"), "delegate")
Define DelegateClass.I = CocoaMessage(0, AppDelegate, "class")
Define DragStartColumn.I
Define DragStartRow.I
Define DropColumn.I
Define DropRow.I
Define NotificationCenter.I = CocoaMessage(0, 0,
  "NSNotificationCenter defaultCenter")
Define RowCount.I
Define SelectedColumn.I
Define Selector.I = sel_registerName("textDidEndEditing:")

OpenWindow(0, 200, 100, 430, 150, "Drag 'n Drop of ListIcon cells")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20, "Name",
  110, #PB_ListIcon_GridLines)
EnableGadgetDrop(0, #PB_Drop_Text, #PB_Drag_Move)
AddGadgetColumn(0, 1, "Address", 292)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ + "12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ + "130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(0, -1, "Didi Foundit" + #LF$ + "321 Logo Drive, Mouse House, Downtown")
CocoaMessage(0, GadgetID(0), "setSelectionHighlightStyle:", -1)
class_addMethod(DelegateClass, Selector, @EditingFinishedCallback(), "v@:@")
CocoaMessage(0, NotificationCenter,
  "addObserver:", AppDelegate,
  "selector:", Selector,
  "name:$", @"NSControlTextDidEndEditingNotification",
  "object:", GadgetID(0))

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 0 And EventType() = #PB_EventType_LeftClick
        CursorLocation\x = WindowMouseX(0)
        CursorLocation\y = WindowHeight(0) - WindowMouseY(0)
        CocoaMessage(@CursorLocation, GadgetID(0),
          "convertPoint:@", @CursorLocation, "fromView:", 0)
        DragStartColumn = CocoaMessage(0, GadgetID(0),
          "columnAtPoint:@", @CursorLocation)
        DragStartRow = CocoaMessage(0, GadgetID(0),
          "rowAtPoint:@", @CursorLocation)
        CocoaMessage(0, GadgetID(0),
          "editColumn:", DragStartColumn,
          "row:", DragStartRow,
          "withEvent:", 0,
          "select:", #YES)
      EndIf
    Case #PB_Event_GadgetDrop
      CursorLocation\x = WindowMouseX(0)
      CursorLocation\y = WindowHeight(0) - WindowMouseY(0)
      CocoaMessage(@CursorLocation, GadgetID(0),
        "convertPoint:@", @CursorLocation, "fromView:", 0)
      DropColumn = CocoaMessage(0, GadgetID(0),
        "columnAtPoint:@", @CursorLocation)
      DropRow = CocoaMessage(0, GadgetID(0),
        "rowAtPoint:@", @CursorLocation)
      RowCount = CountGadgetItems(0)

      ; ----- If cursor during dropping is below last row, append new row
      If DropRow = -1
        If DropColumn = 0
          AddGadgetItem(0, RowCount, EventDropText())
        Else
          AddGadgetItem(0, RowCount, "" + #LF$ + EventDropText())
        EndIf
      Else
        ; ----- Insert dragged cell content
        SetGadgetItemText(0, DropRow, EventDropText(), DropColumn)
      EndIf

      ; ----- Clear cell content of drag start
      SetGadgetItemText(0, DragStartRow, "", DragStartColumn)
  EndSelect
ForEver
Wolfram
Enthusiast
Enthusiast
Posts: 568
Joined: Thu May 30, 2013 4:39 pm

Re: How to drag and drop on ListIconGadget() ?

Post by Wolfram »

Thanks!
That is what I'm looking for.
macOS Catalina 10.15.7
WilliamL
Addict
Addict
Posts: 1224
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: How to drag and drop on ListIconGadget() ?

Post by WilliamL »

Hi Shardik,

I wanted to tell you I came across your code and tried to simplify the code (I just took out lines that didn't seem to break the process ;-) ) and changed it to a ListViewGadget and I've worked it into a program. It is a nice way to re-order an array.

Code: Select all

EnableExplicit

Define CursorLocation.NSPoint
Define DragStartRow.I
Define DropRow.I
Define RowCount.I
Define cnt ; for/next counter

OpenWindow(0, 200, 100, 430, 150, "Drag 'n Drop of ListView cells")
ListViewGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20)
EnableGadgetDrop(0, #PB_Drop_Text, #PB_Drag_Move)
AddGadgetItem(0, -1, "0-Harry Rannit - 12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "1-Ginger Brokeit - 130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(0, -1, "2-Didi Foundit - 321 Logo Drive, Mouse House, Downtown")
AddGadgetItem(0, -1, "3-Harry Rannit - 12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "4-Ginger Brokeit - 130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(0, -1, "5-Didi Foundit - 321 Logo Drive, Mouse House, Downtown")
CocoaMessage(0, GadgetID(0), "setSelectionHighlightStyle:", -1)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 0 And EventType() = #PB_EventType_LeftClick
        CursorLocation\x = WindowMouseX(0)
        CursorLocation\y = WindowHeight(0) - WindowMouseY(0)
        CocoaMessage(@CursorLocation, GadgetID(0),"convertPoint:@", @CursorLocation, "fromView:", 0)
        DragStartRow = CocoaMessage(0, GadgetID(0),"rowAtPoint:@", @CursorLocation)
            Debug "DragStartRow="+Str(DragStartRow)
        CocoaMessage(0, GadgetID(0),"editColumn:",0,"row:", DragStartRow,"withEvent:", 0,"select:", #YES)
      EndIf
    Case #PB_Event_GadgetDrop
      CursorLocation\x = WindowMouseX(0)
      CursorLocation\y = WindowHeight(0) - WindowMouseY(0)
      CocoaMessage(@CursorLocation, GadgetID(0),"convertPoint:@", @CursorLocation, "fromView:", 0)
      DropRow = CocoaMessage(0, GadgetID(0),"rowAtPoint:@", @CursorLocation)
          Debug "DropRow="+Str(DropRow)
      RowCount = CountGadgetItems(0)

      If DropRow>-1
          If DropRow>DragStartRow
              For cnt=DragStartRow To DropRow-1
                  ;Debug Str(cnt)+" "+GetGadgetItemText(0,cnt+1)
                  SetGadgetItemText(0,cnt,GetGadgetItemText(0,cnt+1))
              Next
              SetGadgetItemText(0, DropRow, EventDropText())
          Else ; DropRow<DragStartRow
              For cnt=DragStartRow To DropRow+1 Step-1
                  ;Debug Str(cnt)+" "+GetGadgetItemText(0,cnt-1);+" DropRow<DragStartRow"
                  SetGadgetItemText(0,cnt,GetGadgetItemText(0,cnt-1))
              Next
              SetGadgetItemText(0, DropRow,EventDropText())
          EndIf
      EndIf
  EndSelect
ForEver
MacBook Pro-M1 (2021), Sonoma 14.4.1, PB 6.10LTS M1
Post Reply