• Help with a design decision

    From Luc@21:1/5 to All on Mon May 29 15:43:58 2023
    Gentle elders of the village, I come here to ask your wise guidance.

    I am trying to make a file manager kind of application. After a few
    headaches, I finally managed to upgrade tkdnd to the latest version,
    and it's a game changer. Apparently, I can make any widget act as a drop-and-drop source or target, and receive data from the outside
    world too.

    tkdnd::drop_target register $::dropbutton *
    bind $::dropbutton <<Drop>> {tk_messageBox -message "YES"}

    Good.

    The problem is, I need more than "any widget." I have a widget with
    a file list and I want each file in that list to be a source and each
    directory to be both a source and a target.

    I have made and am still working on two prototypes. One uses a text
    widget to produce the file list. The other uses a treeview widget.
    In the first case, each file or directory is in fact a line in a text
    widget. In the second case, each file or directory is an "item" in a
    tree that I don't know how to reference individually. So in either
    case I don't know how to register or bind the individual file name,
    which is a text widget's line or a treeview's item.

    The best I could think of so far is to register the parent (text or
    treeview) and drop the dragged data into whichever directory was
    already selected before anything was ever clicked and dragged, but of
    course that is pretty lame. The user should be able to drag something
    into the application, hover over the directories to select one and
    drop the something into the selected item.

    Also note that I am going to implement an optional "Norton Commander"
    view, which is two independent file listings side by side so you can
    drag from one onto the other. So I really need to be able to drag and
    drop individual items.

    Now, I am beginning to consider using a canvas, which I admit is an
    idea bred out of desperation. I really don't think a canvas is the
    best tool for this job. But at least a canvas will give me full Tk
    paths to reference the items.

    O, gentle elders of the village, what is your wisdom?

    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Christian Gollwitzer@21:1/5 to All on Mon May 29 22:21:17 2023
    Am 29.05.23 um 20:43 schrieb Luc:
    Gentle elders of the village, I come here to ask your wise guidance.

    I am trying to make a file manager kind of application. After a few headaches, I finally managed to upgrade tkdnd to the latest version,
    and it's a game changer. Apparently, I can make any widget act as a drop-and-drop source or target, and receive data from the outside
    world too.

    tkdnd::drop_target register $::dropbutton *
    bind $::dropbutton <<Drop>> {tk_messageBox -message "YES"}

    Good.

    The problem is, I need more than "any widget." I have a widget with
    a file list and I want each file in that list to be a source and each directory to be both a source and a target.


    Use tablelist. There is even a talk about how to use it: https://www.youtube.com/watch?v=rUAfj3Syd_I




    Christian

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Luc on Mon May 29 22:00:09 2023
    Luc <luc@sep.invalid> wrote:
    I am trying to make a file manager kind of application.
    [snip]

    I have made and am still working on two prototypes. One uses a text
    widget to produce the file list. The other uses a treeview widget.
    In the first case, each file or directory is in fact a line in a text
    widget. In the second case, each file or directory is an "item" in a
    tree that I don't know how to reference individually. So in either
    case I don't know how to register or bind the individual file name,
    which is a text widget's line or a treeview's item.

    Beyond Christian's suggestion, you need to read up on two things in the manpages for the treeview and text widgets:

    treeview tags, which are initially referenced in early in the manpage
    this way:

    Each item also has a list of tags, which can be used to associate
    event bindings with individual items and control the appearance of
    the item.

    So, possibly, you can attach drag/drop bindings to treeview items using
    the tags feature.

    As to how to identify a treeview row, that is the "id" of the row.
    This is also again documented in the manpage:

    Each item is identified by a unique name. The widget will generate
    item IDs if they are not supplied by the caller.

    So you can either assign item ID's yourself, or just let the widget
    assign them, and then use them to reference each.

    For text widgets, the system works in a similar manner (via tags) for
    assigning bindings. This is also documented in the text widget
    manpage:

    The second purpose for tags is event bindings. You can associate
    bindings with a tag in much the same way you can associate bindings
    with a widget class: whenever particular X events occur on
    characters with the given tag, a given Tcl command will be executed.

    So much like with the treeview, you'd assign tags to passages of the text widget, and bind to those tags (presumably tkdnd can bind to text
    tags).

    And for the text widget, you have each line identified by "line number"
    in the widget.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et99@21:1/5 to Luc on Mon May 29 17:54:18 2023
    On 5/29/2023 5:29 PM, Luc wrote:
    On Mon, 29 May 2023 22:00:09 -0000 (UTC), Rich wrote:

    So much like with the treeview, you'd assign tags to passages of the text
    widget, and bind to those tags (presumably tkdnd can bind to text
    tags).

    Sadly, no, it can't.

    Remember this:

    tkdnd::drop_target register $::dropbutton *
    bind $::dropbutton <<Drop>> {tk_messageBox -message "YES"}

    I suppose the second line would work if I could run the first one,
    but I don't think I can. Do you?

    I have tried, tkdnd will not accept a text widget tag as a "widget."



    I've only ever played with the demo of treectrl, but it looks like
    a rather complex and powerful gui toolkit. I doubt it would be
    directly compatible with tkdnd, but it appears to have its own
    drag/drop internally.

    It's available with the magicsplat distro which is where I've
    run the demo. Otherwise,

    https://tktreectrl.sourceforge.net/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to Rich on Mon May 29 21:29:36 2023
    On Mon, 29 May 2023 22:00:09 -0000 (UTC), Rich wrote:

    So much like with the treeview, you'd assign tags to passages of the text widget, and bind to those tags (presumably tkdnd can bind to text
    tags).

    Sadly, no, it can't.

    Remember this:

    tkdnd::drop_target register $::dropbutton *
    bind $::dropbutton <<Drop>> {tk_messageBox -message "YES"}

    I suppose the second line would work if I could run the first one,
    but I don't think I can. Do you?

    I have tried, tkdnd will not accept a text widget tag as a "widget."


    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Luc on Tue May 30 02:34:27 2023
    Luc <luc@sep.invalid> wrote:
    On Mon, 29 May 2023 22:00:09 -0000 (UTC), Rich wrote:

    So much like with the treeview, you'd assign tags to passages of the text
    widget, and bind to those tags (presumably tkdnd can bind to text
    tags).

    Sadly, no, it can't.

    Remember this:

    tkdnd::drop_target register $::dropbutton *
    bind $::dropbutton <<Drop>> {tk_messageBox -message "YES"}

    I suppose the second line would work if I could run the first one,
    but I don't think I can. Do you?

    I have tried, tkdnd will not accept a text widget tag as a "widget."

    And was that all you tried? I've never used tkdnd, so the following is
    based on just looking over the tkdnd manpage now, but it seems you
    could, for either a text or a treeview, do:

    First setup the window (the text or the treeview) as the "drop target"
    (this satisifes the need for tkdnd::drop_target to register an actual
    widget).

    Then setup bindings on the tkdnd events, attached to the window itself,
    to trigger procs for each event. For <<DropPosition>> use the %X and
    %Y expansions to obtain the x,y coordinate of the mouse over the
    window. Then using the normal method calls for the widget (be it text
    or treeview) convert the x,y mouse position into a text line number or
    a treeview item id value (and decide if the drop "type" is appropriate
    for this x,y value and return the appropriate return value).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mole Cool@21:1/5 to All on Tue May 30 03:41:56 2023
    I use most of the time (> 95%) tk treectrl, it has a lot of cool features, see the about 30 demos included. There is a explorer demo as well, and a couple with drag and drop.


    But like most of this binary packages, they will probably die with Tcl 9.0 and no longer loadable.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to Mole Cool on Tue May 30 20:13:43 2023
    On Tue, 30 May 2023 03:41:56 -0700 (PDT), Mole Cool wrote:

    But like most of this binary packages, they will probably die with Tcl
    9.0 and no longer loadable.


    Then I will cling to Tcl 8.6 for at least 10 years before I jump to Tcl 9.
    Come and pry it away from my cold stiff dead hands.


    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to Rich on Tue May 30 21:38:32 2023
    On Tue, 30 May 2023 02:34:27 -0000 (UTC), Rich wrote:

    First setup the window (the text or the treeview) as the "drop target"
    (this satisifes the need for tkdnd::drop_target to register an actual widget).

    Then setup bindings on the tkdnd events, attached to the window itself,
    to trigger procs for each event. For <<DropPosition>> use the %X and
    %Y expansions to obtain the x,y coordinate of the mouse over the
    window. Then using the normal method calls for the widget (be it text
    or treeview) convert the x,y mouse position into a text line number or
    a treeview item id value (and decide if the drop "type" is appropriate
    for this x,y value and return the appropriate return value).


    Clever mechanism for targets.

    Now, how would you turn a text line into a drag-and-drop source?

    How would one be able to drag a text widget line onto something else?


    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to Rich on Tue May 30 22:57:34 2023
    On Wed, 31 May 2023 01:38:30 -0000 (UTC), Rich wrote:

    Clever mechanism for targets.
    Now, how would you turn a text line into a drag-and-drop source?

    Presumably the same way you'd otherwise make a text line "active" for mousing, apply a text tag to the characters that should be "active" and
    bind to the appropriate events to be a drag. Which most likely would
    mean detecting the line on a button down event, then beginning the
    "drop source" aspects upon motion (possibly upon sufficient motion
    distance to avoid small mouse jitters of 2-3 pixels initiating a drag).

    How would one be able to drag a text widget line onto something else?

    Same way, apply tags, bind appropriate events to those tags to initiate
    the drag -- then insert into the drag whatever is data appropriate for "dragging" of this text line.


    You bring up tags again, but tags don't work with tkdnd. They don't work
    with the 'register' command that turns a widget into a source (or target) because a "tagged" line of text is not a widget.


    I am having a busy week so I didn't have much time to code today, but
    I have done some more prototyping and now I think that my best bet
    will be labels in place of text lines. They can be fully referenced
    as widgets. They *are* bona fide widgets. I'm just not too sure about
    what parent widget I should use to contain them. Maybe a text widget,
    but I guess I will have to experiment.


    I still don't know how to turn treeview items (the left hand panel)
    into drag-and-drop sources (same problem as with text), but I guess
    that is a lot less likely to be missed or wanted by anyone.

    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Luc on Wed May 31 01:38:30 2023
    Luc <luc@sep.invalid> wrote:
    On Tue, 30 May 2023 02:34:27 -0000 (UTC), Rich wrote:

    First setup the window (the text or the treeview) as the "drop
    target" (this satisifes the need for tkdnd::drop_target to register
    an actual widget).

    Then setup bindings on the tkdnd events, attached to the window
    itself, to trigger procs for each event. For <<DropPosition>> use
    the %X and %Y expansions to obtain the x,y coordinate of the mouse
    over the window. Then using the normal method calls for the widget
    (be it text or treeview) convert the x,y mouse position into a text
    line number or a treeview item id value (and decide if the drop
    "type" is appropriate for this x,y value and return the appropriate
    return value).


    Clever mechanism for targets.

    Now, how would you turn a text line into a drag-and-drop source?

    Presumably the same way you'd otherwise make a text line "active" for
    mousing, apply a text tag to the characters that should be "active" and
    bind to the appropriate events to be a drag. Which most likely would
    mean detecting the line on a button down event, then beginning the
    "drop source" aspects upon motion (possibly upon sufficient motion
    distance to avoid small mouse jitters of 2-3 pixels initiating a drag).

    How would one be able to drag a text widget line onto something else?

    Same way, apply tags, bind appropriate events to those tags to initiate
    the drag -- then insert into the drag whatever is data appropriate for "dragging" of this text line.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et99@21:1/5 to Luc on Tue May 30 19:40:33 2023
    On 5/30/2023 4:13 PM, Luc wrote:
    On Tue, 30 May 2023 03:41:56 -0700 (PDT), Mole Cool wrote:

    But like most of this binary packages, they will probably die with Tcl
    9.0 and no longer loadable.


    Then I will cling to Tcl 8.6 for at least 10 years before I jump to Tcl 9. Come and pry it away from my cold stiff dead hands.



    This is where starpak's come in handy. For example,
    although I run a 64 bit windows 10 system, I have a
    version of BLT that can only run in a 32 bit tcl/tk.

    I installed MagicSplat 32bit 8.6.9 in a 32 bit VM and
    then copied the lib directory packages into the lib
    directory of my starpak folder and built the pak using
    an Ashok 8.6.9 32bit tclkit as the -runtime arg.

    The resulting single file .exe is 24megs - tiny
    considering it has all the 32bit MagicSplat packages
    built in.

    % package require treectrl
    2.4.3
    % package require BLT
    2.4
    % package require twapi
    4.3.5
    % package require tkdnd
    2.9
    % info nameof
    C:/tclf/kits/tcl869-twapi-blt-magic.exe
    % info pa
    8.6.9
    % parray tcl_platform
    ...
    tcl_platform(osVersion) = 10.0
    tcl_platform(platform) = windows
    tcl_platform(pointerSize) = 4
    tcl_platform(threaded) = 1

    Meanwhile, I also have a MagicSplat 64 distro installed
    which runs 8.6.13.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From briang@21:1/5 to Luc on Wed May 31 16:44:44 2023
    On Tuesday, May 30, 2023 at 6:57:40 PM UTC-7, Luc wrote:
    On Wed, 31 May 2023 01:38:30 -0000 (UTC), Rich wrote:

    Clever mechanism for targets.
    Now, how would you turn a text line into a drag-and-drop source?

    Presumably the same way you'd otherwise make a text line "active" for mousing, apply a text tag to the characters that should be "active" and bind to the appropriate events to be a drag. Which most likely would
    mean detecting the line on a button down event, then beginning the
    "drop source" aspects upon motion (possibly upon sufficient motion distance to avoid small mouse jitters of 2-3 pixels initiating a drag).

    How would one be able to drag a text widget line onto something else?

    Same way, apply tags, bind appropriate events to those tags to initiate the drag -- then insert into the drag whatever is data appropriate for "dragging" of this text line.
    You bring up tags again, but tags don't work with tkdnd. They don't work with the 'register' command that turns a widget into a source (or target) because a "tagged" line of text is not a widget.


    I am having a busy week so I didn't have much time to code today, but
    I have done some more prototyping and now I think that my best bet
    will be labels in place of text lines. They can be fully referenced
    as widgets. They *are* bona fide widgets. I'm just not too sure about
    what parent widget I should use to contain them. Maybe a text widget,
    but I guess I will have to experiment.

    Hi Luc. I don't have time to experiment, so I don't know if this will work, but you might give it a try:
    Use the textwidget dlineinfo call to get the size information of the tagged text. Then use the textwidget peer call to create a peer textwidget. Resize the peer widget according to the dlineinfo. Use this peer widget for the dragging. Afterwords,
    destroy the peer widget.

    -Brian

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to briang on Wed May 31 22:41:23 2023
    On Wed, 31 May 2023 16:44:44 -0700 (PDT), briang wrote:

    Hi Luc. I don't have time to experiment, so I don't know if this will
    work, but you might give it a try: Use the textwidget dlineinfo call to
    get the size information of the tagged text. Then use the textwidget peer call to create a peer textwidget. Resize the peer widget according to
    the dlineinfo. Use this peer widget for the dragging. Afterwords,
    destroy the peer widget.

    -Brian


    Very interesting idea. I will certainly look into it on the weekend.

    Thank you.


    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From lamuzzachiodi@gmail.com@21:1/5 to All on Wed May 31 19:39:28 2023
    Maybe something more "simple" can be useful for you.
    For example, take a look to "A simple DnD implementation by SES" (at end of https://wiki.tcl-lang.org/page/Drag+and+Drop).
    Or, in the same line "simplednd" by Kevin Walzer (https://wiki.tcl-lang.org/page/SimpleDND).
    This last isn't available but if you have interest i can paste the code here.

    Saludos,

    Alejandro

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to lamuzz...@gmail.com on Thu Jun 1 13:48:32 2023
    On Wed, 31 May 2023 19:39:28 -0700 (PDT), lamuzz...@gmail.com wrote:

    Maybe something more "simple" can be useful for you.
    For example, take a look to "A simple DnD implementation by SES" (at end
    of https://wiki.tcl-lang.org/page/Drag+and+Drop).


    I have been through that page and probably all links in it.

    "A simple DnD implementation by SES" is bad. Try dragging 'a' down
    towards the bottom then into the other pane, you'll see that 'e'
    gets copied instead of 'a'.


    Or, in the same line
    "simplednd" by Kevin Walzer (https://wiki.tcl-lang.org/page/SimpleDND).
    This last isn't available but if you have interest i can paste the code
    here.


    Yes, I am very interested. Thank you in advance.


    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From lamuzzachiodi@gmail.com@21:1/5 to All on Thu Jun 1 15:01:36 2023
    Well, below i paste the code of simplednd by Kevin Walzer.
    First, you must save this as "simplednd.tcl".

    ##simplednd: implements simple mechanism for drag-and-drop within Tk applications. (c) 2009 WordTech Communications LLC. License: standard Tcl license, http://www.tcl.tk/software/tcltk/license.html.

    package provide simplednd 1.1
    namespace eval simplednd {
    #create the drag icon with empty text and image to initialize; then hide the icon
    proc makeDragIcon {txt img} {
    variable dragicon
    variable dragtext
    variable dragimage
    #create the icon
    set dragicon [toplevel .dnd]
    set dragtext $txt
    set dragimage $img
    wm overrideredirect $dragicon true
    label $dragicon.view -image $dragimage -text $dragtext -compound left
    pack $dragicon.view
    #now hide the icon
    wm withdraw $dragicon
    }
    #register widget to respond to drag events: widget to register, its target widget, callback to associate with this drag event, text for the drag label, and image for the drag label
    proc dragRegister {w target dragcmd dropcmd} {
    variable dragicon
    variable dragtext
    variable dragimage
    variable targetdirection
    catch {simplednd::makeDragIcon {} {}}
    puts "$w registered as dragsite with $target as the drop target"
    #binding for when drag motion begins
    bind $w <B1-Motion> [list [namespace current]::dragMove %W %X %Y $dragcmd $target]
    #binding for when drop event occurs
    bind $w <ButtonRelease-1> [list [namespace current]::dragStop %W %X %Y $target $dropcmd ]
    }
    #drag motion with following args: source widget, cursor x position, cursor y position, drag command, target widget
    proc dragMove {w x y dragcmd target} {
    variable dragicon
    variable dragtext
    variable dragimage
    variable targetdirection
    #the dragcmd properly configures the drag icon
    eval $dragcmd
    #configure drag icon with customized text and image
    $dragicon.view configure -text $dragtext -image $dragimage
    #dragicon appears
    wm deiconify $dragicon
    catch {raise $dragicon}
    #this places the drag icon below the cursor
    set x [expr {$x - ([winfo reqwidth $dragicon] / 2) }]
    set y [expr {$y - [winfo reqheight $dragicon] + 25 }]
    wm geometry $dragicon +$x+$y
    [namespace current]::trackCursor $w $x $y $target
    }
    #track the cursor, change if it is over the drop target; args are source widget (w), x pos (x), y pos (y), target widget (target)
    proc trackCursor {w x y target} {
    #get the coordinates of the drop target
    set targetx [winfo rootx $target]
    set targety [winfo rooty $target]
    set targetwidth [expr [winfo width $target] + $targetx]
    set targetheight [expr [winfo height $target] + $targety]
    #change the icon if over the drop target
    if {($x > $targetx) && ($x < $targetwidth) && ($y > $targety) && ($y < $targetheight)} {
    $w configure -cursor based_arrow_down
    } else {
    $w configure -cursor dot
    }
    }
    #dragstop/drop event with following args: source widget, cursor x position, cursor y position, target widget, dropcommand: if over drop target, execute dropcommand; otherwise simply return
    proc dragStop {w x y target dropcmd} {
    variable dragicon
    variable dragtext
    variable dragimage
    variable targetdirection
    #hide dragicon on drop event
    wm withdraw $dragicon
    #change cursor back to arrow
    $w configure -cursor arrow
    #execute callback or simply return
    if {[winfo containing $x $y] != $target} {
    puts "target $w not reached"
    } else {
    focus -force $target
    eval $dropcmd
    }
    }
    #demo package
    proc demo {} {
    variable dragicon
    variable dragtext
    variable dragimage
    #create image for demo
    image create photo dnd_demo -data {R0lGODlhEAAQALMAAAAAAMbGxv//////////////////////////////////\
    /////////////////////yH5BAEAAAEALAAAAAAQABAAAAQwMMhJ6wQ4YyuB\
    +OBmeeDnAWNpZhWpmu0bxrKAUu57X7VNy7tOLxjIqYiapIjDbDYjADs=}
    listbox .l -selectmode single -activestyle none
    listbox .b -selectmode single -activestyle none
    foreach item {do re mi} {
    .l insert end $item
    }
    foreach item {fa so la} {
    .b insert end $item
    }
    pack .l -side left
    pack .b -side right
    #register drag sources, drag targets, and callbacks
    dragRegister .l .b [namespace current]::drag_l [namespace current]::drop_l
    dragRegister .b .l [namespace current]::drag_b [namespace current]::drop_b
    }
    #dragcommand for demo l widget: configures dragicon
    proc drag_l {} {
    variable dragicon
    variable dragtext
    variable dragimage
    set item [lindex [.l get [.l curselection]]]
    set dragtext $item
    set dragimage dnd_demo
    }
    #dropcommand for demo l widget: callback to execute on drop
    proc drop_l {} {
    variable dragicon
    variable dragtext
    variable dragimage
    .b insert end $dragtext
    .l delete [.l curselection]
    }
    #dragcommand for demo b widget: configures dragicon
    proc drag_b {} {
    variable dragicon
    variable dragtext
    variable dragimage
    set item [lindex [.b get [.b curselection]]]
    set dragtext $item
    set dragimage dnd_demo
    }
    #dropcommand for demo b widget: callback to execute on drop
    proc drop_b {} {
    variable dragicon
    variable dragtext
    variable dragimage
    .l insert end $dragtext
    .b delete [.b curselection]
    }
    namespace export *
    }

    Now, save this as "pkgIndex.tcl"

    # Tcl package index file, version 1.1
    # This file is generated by the "pkg_mkIndex" command
    # and sourced either when an application starts up or
    # by a "package unknown" script. It invokes the
    # "package ifneeded" command to set up package-related
    # information so that packages will be loaded automatically
    # in response to "package require" commands. When this
    # script is sourced, the variable $dir must contain the
    # full path name of this file's directory.

    package ifneeded simplednd 1.1 [list source [file join $dir simplednd.tcl]]

    Finally, the help :

    The simpleDND Package

    The simpleDND package implements a lightweight mechanism for drag-and-drop operations within a single Tcl/Tk application. When used, it provides a visual icon and cursor change to indicate a dragged object, and can execute any Tcl command upon a
    successful drop operation. The package is designed to be easy-to-use, with just a few commands required to add drag-and-drop. Any widget can be registered as a drag source or drop target.

    simpleDND is called via package require simpleDND. It is implemented with the following command:
    * proc dragRegister {w target dragcmd dropcmd}: w is the source widget where the drag is initiated, target is the target widget where the drop is completed, dragcmd is the Tcl command that is executed on the start of the drag operation, and dropcmd is
    the Tcl command that is executed when the drop operation is completed. simplednd::dragRegister must be called for each widget that is set up as a drag source. For instance, if you have a listbox .l and a listbox .b that are both drag sources, the command must be called for each widget. Also, if listbox .l and listbox .b
    have multiple drop targets, then the command must be called for each drop target.

    The dragcmd should be used to configure the drag icon. The variables ::simplednd::dragtext and ::simplednd::dragimg are used for this purpose. At a minimum, you must define a single command setting default values for the dragtext and dragimg variables,
    or you can provide a different command for each drag operation. simpleDND does not provide default values for the text or image in the drag icon; without at least one dragcmd, you will be dragging around an empty label as the drag icon.

    The dropcmd is called on a successful drop, i.e. when the button is released over the drop target registered with the drag source. If the button is released over a widget that is not registered as the drop target, the cursor changes to a standard arrow
    and the drag icon disappears.

    A demonstration of simpleDND is included with the package. Call simplednd::demo after loading the package. You can also inspect the demo source code for ideas on how to implement simpleDND in your own applications.

    Ok, that's all.
    I hope this help you.

    Alejandro

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to lamuzz...@gmail.com on Fri Jun 2 14:22:25 2023
    On Thu, 1 Jun 2023 15:01:36 -0700 (PDT), lamuzz...@gmail.com wrote:

    Well, below i paste the code of simplednd by Kevin Walzer.
    First, you must save this as "simplednd.tcl".


    Thank you for the code.

    Question for everybody: do you think it would be rude or otherwise
    wrong to post this code in its corresponding page on the wiki, that
    is currently empty except for a broken link?

    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From lamuzzachiodi@gmail.com@21:1/5 to All on Mon Jun 5 16:00:56 2023
    I guess if this code is still useful, no one will be bothered by posting it. Just my opinion ... ;-)

    Alejandro

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Schelte@21:1/5 to Luc on Sun Jun 11 14:59:10 2023
    On 31/05/2023 02:38, Luc wrote:
    Now, how would you turn a text line into a drag-and-drop source?

    How would one be able to drag a text widget line onto something else?

    You indicated in a different thread that despite all the tips and hints
    you received, you still haven't managed to get this working. Then let me
    spell it out for you.

    The code below uses a treeview to show a list of files and directories.
    In accordance with your original description, both files and directories
    can be dragged. But dropping is only acceptable for directories.


    # Create a treeview for the list of files
    ttk::treeview .tv1 -yscrollcommand [list .vs1 set] -show tree
    # For simplicity, just give directories a different font color rather
    # than some nice icon
    .tv1 tag configure directory -foreground #008000
    ttk::scrollbar .vs1 -command [list .tv1 yview]
    grid .tv1 .vs1 -sticky nsew
    grid columnconfigure . .tv1 -weight 1
    grid rowconfigure . .tv1 -weight 1

    # Fill the treeview with the files and directories in the current path
    foreach name [lsort [glob -nocomplain -directory [pwd] *]] {
    .tv1 insert {} end -id $name -text [file tail $name] \
    -tags [list [file type $name]]
    }

    # --------------------------------------------------------------------

    # Drag & drop implementation
    package require tkdnd

    # Register the treeview as both a drag source and drop target tkdnd::drag_source register .tv1 {DND_Files}
    tkdnd::drop_target register .tv1 {DND_Files}

    # Set up the minimum bindings
    bind .tv1 <<DragInitCmd>> {dragstart %W %X %Y}
    bind .tv1 <<DropPosition>> {dropcheck %W %X %Y}
    bind .tv1 <<Drop>> {dropfinish %W %X %Y %D}

    # Unfortunately tkdnd doesn't support the %x and %y substitutions.
    # We'll have to calculate them from the %X and %Y values.
    proc tvitem {w x y} {
    set x [expr {$x - [winfo rootx $w]}]
    set y [expr {$y - [winfo rooty $w]}]
    return [$w identify item $x $y]
    }

    # Drag all selected files
    proc dragstart {w x y} {
    set list [$w selection]
    if {[llength $list]} {
    return [list copy DND_Files $list]
    }
    }

    # Only directories are acceptable for dropping
    proc dropcheck {w x y} {
    set item [tvitem $w $x $y]
    if {[$w tag has directory $item]} {
    return copy
    } else {
    return refuse_drop
    }
    }

    # Generate a file copy command when files are dropped
    proc dropfinish {w x y files} {
    # Make sure the drop location is valid
    if {[dropcheck $w $x $y] ne "refuse_drop"} {
    set item [tvitem $w $x $y]
    puts [list file copy {*}$files $item]
    }
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to Schelte on Sun Jun 11 17:47:24 2023
    On Sun, 11 Jun 2023 14:59:10 +0200, Schelte wrote:

    You indicated in a different thread that despite all the tips and hints
    you received, you still haven't managed to get this working. Then let me >spell it out for you.
    **************************

    Thank you for spelling it out. I needed that. It will certainly be useful.

    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)