Drag, drop and go
This is getting interesting
My original statement is many years old, and I don't remember what lead to it... MochiMoppel has a valid point in the fact that:
When pressing in treeA, it locks the focus, so release in treeB won't get the signal.
But hey, why so pessimistic
I have more than once got impressed of what you guys are able to do to push the limits...
My original statement is many years old, and I don't remember what lead to it... MochiMoppel has a valid point in the fact that:
When pressing in treeA, it locks the focus, so release in treeB won't get the signal.
But hey, why so pessimistic
I have more than once got impressed of what you guys are able to do to push the limits...
Trying to make this drag'n drop widget to work like this :
And the sedscript is:
What I want with these is to "drag'n drop" an windows .exe file over the empty field of this widget ,drop it there and make wine start it.sed is copying it as win.exe(without path) and wine should start it through sfile script. Everything works untill starting /media/SDA/VST/VSTi/sfile.Somehow ,in this file "env WINEPREFIX=\"/home/lns/.wine\" /opt/wine-staging/bin/wine Z:\\\\\\\\media\\\\\\\\SDA\\\\\\\\VST\\\\\\\\VSTi\\\\\\\\win.exe" is corectly copied on one line but without "&" on it's trail ,that's copied on the next line resulting something like this:
Wine can't start win.exe without "&" on it's trail ,so everything stops there.How to put "&" on it's place?I tried almost everything with sed but the result is the same with "&" thrown on the wrong place ,on the next line, not on the same line with win.exe and after win.exe.
Code: Select all
<entry width-request="300">
<variable>X</variable>
<default>Drag an exe</default>
<action>echo $X > /tmp/txt &</action>
<action>'$HERE'/sedscript &</action>
<action signal="changed"> some action on X </action>
</entry>
Code: Select all
#!/bin/bash
sed -i 's/.*\///' /tmp/txt
sed -i 's/ *$//' /tmp/txt
fsg=$( cat /tmp/txt )
echo "#!/bin/bash
env WINEPREFIX=\"/home/lns/.wine\" /opt/wine-staging/bin/wine Z:\\\\\\\\media\\\\\\\\SDA\\\\\\\\VST\\\\\\\\VSTi\\\\\\\\$fsg &" > /media/SDA/VST/VSTi/sfile
./media/SDA/VST/VSTi/sfile
Code: Select all
#!/bin/bash
env WINEPREFIX="/home/lns/.wine" /opt/wine-staging/bin/wine Z:\\\\media\\\\SDA\\\\VST\\\\VSTi\\\\win.exe
&
- MochiMoppel
- Posts: 2084
- Joined: Wed 26 Jan 2011, 09:06
- Location: Japan
I was optimistic when I read your "of course". After reading your disclaimer and no word from some1 I lost my optimism. Let's call this realism, not pessimism. You can't always get what you want ♩ ♪♫zigbert wrote:why so pessimistic
Back to the thread topic. The solution to use a gtkdialog entry widget still has a flaw: While dropping works, editing the text in the entry field does not work anymore. Any attempt to edit the text will trigger a "changed" signal and therefore fire the associated action.
The following version lets the user edit text manually as usual. The action is triggered only after hitting the Enter key. Dropped text triggers the action immediately.
Here is the catch: This version of Drag&Drop&Go works only with window focus model "click". With focus model "sloppy" drag&drop works normally, but triggers action only after hitting the Enter key - just like manual entry.
Code: Select all
#!/bin/sh
export FOCUS_FLAG=/tmp/hasfocus
trap "rm $FOCUS_FLAG" EXIT
function some_action {
[ -f $FOCUS_FLAG ] && METHOD=typed || METHOD=dropped
Xdialog -msg "You $METHOD \n$vENTRY" x
}
export -f some_action
echo '
<window>
<entry>
<variable>vENTRY</variable>
<default>D&D or type&ENTER</default>
<action signal="changed" condition="command_is_true([ -f $FOCUS_FLAG ] || echo true )">some_action &</action>
<action signal="enter-notify-event" condition="command_is_true([ -f $FOCUS_FLAG ] || echo true )">grabfocus:vENTRY</action>
<action signal="key-release-event" condition="command_is_true([ $KEY_SYM = Return ] && echo true )">some_action &</action>
</entry>
<action signal="focus-in-event">touch $FOCUS_FLAG</action>
<action signal="focus-out-event">rm $FOCUS_FLAG</action>
</window>'| gtkdialog -cs
- MochiMoppel
- Posts: 2084
- Joined: Wed 26 Jan 2011, 09:06
- Location: Japan
@zigbert: Now, 9 months later, I regret my 'move'
This is what tips&tricks suggests now:
The reorderable tag attribute is not mentioned in the gtkdialog documentation, but it's included in the main Gtk documentation, used by GtkFileChooserDialog for shuffling bookmarks in the left bookmarks pane and you use it in Pmusic for sorting playlists, so it should have a place somewhere in tips&tricks.
This is what tips&tricks suggests now:
...and this is how IMO moving items could be achieved much easier:But this is not all....The next script shows how to move items in list by drag'n drop. Code:Code: Select all
#!/bin/sh move (){ PRESS_EVENT=$(cat /tmp/PRESS_EVENT) [[ $PRESS_EVENT && $TREE ]] || exit #exit if at least one of the 2 values is empty [[ $PRESS_EVENT == $TREE ]] && exit #exit if both are equal (=single or double click) sed -i "/$PRESS_EVENT/d; /$TREE/ i\\$PRESS_EVENT" /tmp/list #remove PRESS_EVENT, then insert item PRESS_EVENT before item $TREE } export -f move ls -1 /usr/share/backgrounds > /tmp/list export test=" <tree rules_hint=\"true\" hover-selection=\"true\" tooltip-text=\"Drag'n drop items to move them in list\"> <label>Backgrounds</label> <input>cat /tmp/list</input> <variable>TREE</variable> <height>300</height><width>200</width> <action signal=\"button-press-event\">echo \$TREE > /tmp/PRESS_EVENT</action> <action signal=\"button-release-event\">move</action> <action signal=\"button-release-event\">refresh:TREE</action> </tree>" gtkdialog -p test
Code: Select all
#!/bin/sh
export test='
<tree headers-clickable="false" reorderable="true" rules_hint="true" Xhover-selection="true" tooltip-text="Drag'\''n drop items to move them in list">
<label>Backgrounds</label>
<input>ls -1 /usr/share/backgrounds</input>
<variable>TREE</variable>
<height>300</height><width>200</width>
</tree>'
gtkdialog -p test
Like it
Tried to make it more usable with a output file, but the release-event saves the list to <output file> 1 step behind my move. - I have to move twice to update the output file with the first move.
Code: Select all
#!/bin/sh
export test='
<tree headers-clickable="false" reorderable="true" rules_hint="true" Xhover-selection="true" tooltip-text="Drag'\''n drop items to move them in list">
<label>Backgrounds</label>
<input>ls -1 /usr/share/backgrounds</input>
<output file>/tmp/test</output>
<variable>TREE</variable>
<height>300</height><width>200</width>
<action signal="button-release-event">save:TREE</action>
</tree>'
gtkdialog -p test
Any thoughts?
- MochiMoppel
- Posts: 2084
- Joined: Wed 26 Jan 2011, 09:06
- Location: Japan
Yeah, nice, isn't it? A great feature. Saves the status just after you released the button and before gtkdialog shuffles the sort order, updates the display and whatever else has to be done to process the signal. Gives you a last chance to backup your current sort order before you mess up your list with an accidental drop.zigbert wrote:Tried to make it more usable with a output file, but the release-event saves the list to <output file> 1 step behind my move.
It's the same with other signals, e.g. selection-changed. Whatever action you define, user defined actions have precedence and are processed before the built-in actions.
If you want to save the reordered list you can either use the changed signal (which I find too heavy since it fires often) or you can "outsource" the save action. An (invisible) button is fine for that:
Code: Select all
<action signal="button-release-event">activate:BTN_SAVE</action>
.
.
<button visible="false">
<variable>BTN_SAVE</variable>
<action>save:TREE</action>
</button>
...and hovering another item over the item that just ate your deleted item causes the culprit to spit it out again. You can have much fun with this feature ...or is it a bug? Anyway, if you combine your "1 step behind" save and my "outsourced" save, you have all ingredients for a bullet-proof reorder function.Another issue is that moving an item onto another item deletes it.
The following code works for me. It takes a snapshot of the list before and after the reordering. Then it compares the output of the wc command, which should be the same for both files - unless a line is missing (deleted). In this case the tree is refreshed with the first snapshot, which effectively recreates the former sort order.
Code: Select all
#!/bin/sh
ls -1 /usr/share/backgrounds > /tmp/test
export test='
<vbox>
<tree headers-clickable="false" reorderable="true">
<label>Backgrounds</label>
<input>cat /tmp/test</input>
<output file>/tmp/test</output>
<variable>TREE</variable>
<height>300</height><width>200</width>
<action signal="button-release-event">save:TREE</action>
<action signal="button-release-event">activate:BTN_SAVE</action>
</tree>
<button visible="false">
<variable>BTN_SAVE</variable>
<action>cp /tmp/test /tmp/testbackup</action>
<action>save:TREE</action>
<action condition="command_is_true([[ $(wc </tmp/test) != $(wc </tmp/testbackup) ]] && sed "s/^|*//" /tmp/testbackup > /tmp/test && echo true )">refresh:TREE</action>
</button>
</vbox>'
gtkdialog -p test
- MochiMoppel
- Posts: 2084
- Joined: Wed 26 Jan 2011, 09:06
- Location: Japan
In the work of getting this exiting code work in actual usage, I've managed to implement the reorderable feature in the the pMusic playqueue. 2 of the 3 others functions that pMusic use in the queue are ok, but I struggle with the last one...
- The right-click menu is ok.
- The hot-key for removing items in queue by pressing mouse middle-button is ok.
- But activating (play) an item in the list by left-clicking on it seems to be troublesome. Well, it is sure doable with the release-event, but then I play every track I move by the reorderable function. I have tried to instead use doubleclick, but it doesn't seem to work in this combination. And the signal "row-activated" doesn't listen...
So, at this stage, the workaround is a bit hard. It reorders the list gently, but without any option to run actions on a left-click, we miss the last brick in the wall.
Any thoughts?
Sigmund
- The right-click menu is ok.
- The hot-key for removing items in queue by pressing mouse middle-button is ok.
- But activating (play) an item in the list by left-clicking on it seems to be troublesome. Well, it is sure doable with the release-event, but then I play every track I move by the reorderable function. I have tried to instead use doubleclick, but it doesn't seem to work in this combination. And the signal "row-activated" doesn't listen...
So, at this stage, the workaround is a bit hard. It reorders the list gently, but without any option to run actions on a left-click, we miss the last brick in the wall.
Any thoughts?
Sigmund
- MochiMoppel
- Posts: 2084
- Joined: Wed 26 Jan 2011, 09:06
- Location: Japan
Something like this?
Item is activated upon button-release-event, but not after reordering.
If the list hasn't been reordered, the very last action condition doesn't need be tested and you can add a bit of sophistication and break the action chain before it reaches this nonsense test:Better performance, worse readability
Code: Select all
#!/bin/bash
ls -1 /usr/share/backgrounds > /tmp/test
do_something () { [[ $TREE ]] && viewnior "/usr/share/backgrounds/$TREE" ;} ; export -f do_something
export test='
<vbox>
<tree headers-clickable="false" reorderable="true">
<label>Backgrounds</label>
<input>cat /tmp/test</input>
<output file>/tmp/test</output>
<variable>TREE</variable>
<height>300</height><width>200</width>
<action signal="button-release-event">save:TREE</action>
<action signal="button-release-event">activate:BTN_SAVE</action>
</tree>
<button visible="false">
<variable>BTN_SAVE</variable>
<action>cp /tmp/test /tmp/testbackup</action>
<action>save:TREE</action>
<action>"[[ $(</tmp/test) == $(</tmp/testbackup) ]] && do_something &"</action>
<action condition="command_is_true([[ $(wc </tmp/test) != $(wc </tmp/testbackup) ]] && sed \"s/^|*//\" /tmp/testbackup > /tmp/test && echo true )">refresh:TREE</action>
</button>
</vbox>'
gtkdialog -p test
If the list hasn't been reordered, the very last action condition doesn't need be tested and you can add a bit of sophistication and break the action chain before it reaches this nonsense test:
Code: Select all
<action condition="command_is_true([[ $(</tmp/test) == $(</tmp/testbackup) ]] && { do_something & echo true ;} || echo false )">break:</action>
Yeahhh!
Your code works, but it looses the handling of the $BUTTON value for release-event. I made a simple flag to store $BUTTON on press-event for later usage.
The code is too dirty (and complex) atm to show, but I will come back to it with a fresh brain and clean up. I had some other minor issues, so I had to change the approach a bit. I will come back with more feedback.
In the end we need to complete a simple, yet complete, example how to use and understand your code.
Keep it coming
Thanks a lot
Sigmund
Your code works, but it looses the handling of the $BUTTON value for release-event. I made a simple flag to store $BUTTON on press-event for later usage.
The code is too dirty (and complex) atm to show, but I will come back to it with a fresh brain and clean up. I had some other minor issues, so I had to change the approach a bit. I will come back with more feedback.
In the end we need to complete a simple, yet complete, example how to use and understand your code.
Keep it coming
Thanks a lot
Sigmund
- MochiMoppel
- Posts: 2084
- Joined: Wed 26 Jan 2011, 09:06
- Location: Japan
OK, here we go:zigbert wrote:Keep it coming
First let's get rid of [[ $TREE ]] test in the function. The reason for that was a possibly empty $TREE, which occurs when the user drags the item just below itself.
And now the beauty part: Avoid all this (double) saving and copying stuff.
In my previous code all these actions fired with every release event, and of course double with a doubleclick. Made me nervous to think what might happen with speed when the list becomes bigger. Not elegant at all.
Below I attach an improved version that triggers only the main action and nothing else when the user clicks an item. It triggers the saving routine when the user moves an item. Find out why it works
Code: Select all
#!/bin/bash
ls -1 /usr/share/backgrounds > /tmp/test
do_something () { Xdialog -info "Do something with\n$TREE" x 2000 ;} ; export -f do_something
echo '
<vbox>
<tree headers-clickable="false" reorderable="true">
<label>Backgrounds</label>
<input>cat /tmp/test</input>
<output file>/tmp/test</output>
<variable>TREE</variable>
<height>300</height><width>200</width>
<action signal="button-release-event" condition="command_is_true( ((PTR_Y)) && { do_something & echo true ;})">break:</action>
<action signal="button-release-event">save:TREE</action>
<action signal="button-release-event">activate:BTN_SAVE</action>
</tree>
<button visible="false">
<variable>BTN_SAVE</variable>
<action>cp /tmp/test /tmp/testbackup</action>
<action>save:TREE</action>
<action condition="command_is_true([[ $(wc </tmp/test) != $(wc </tmp/testbackup) ]] && sed "s/^|*//" /tmp/testbackup > /tmp/test && echo true )">refresh:TREE</action>
</button>
</vbox>' | gtkdialog -s
Well, "row-activated" , the default action, was listening. At least it listened to the Enter or Space key. It didn't pick up a doubleclick because a simple <action> (= "row-activated") , no matter where it is placed in the code, is always processed after the "button-release-event". With activating BTN_SAVE the action chain of the tree widget comes to an end and actions of the Button widget are processed. The process never returns to the tree widget to continue with the still "pending" row-activated event.zigbert wrote:I have tried to instead use doubleclick, but it doesn't seem to work in this combination. And the signal "row-activated" doesn't listen...
Good news: with above code the default action will now work. Personally I would prefer to use the default action so that the user can use either keyboard (Enter or Space) or mouse (doubleclick).
In above code try to change
Code: Select all
<action signal="button-release-event" condition="command_is_true( ((PTR_Y)) && { do_something & echo true ;})">break:</action>
Code: Select all
<action>do_something &</action>
<action signal="button-release-event" condition="command_is_true( echo $PTR_Y )">break:</action>
I think this is a wonderful workaround...
...But I really wonder what made you notice that $PTR_Y became 0 when moving an item - That is luck
I will wait a couple of days before updating the tips and tricks thread... It could be more.
...But I really wonder what made you notice that $PTR_Y became 0 when moving an item - That is luck
I will wait a couple of days before updating the tips and tricks thread... It could be more.
Code: Select all
#!/bin/bash
#Code below line 15 (break:) is activated when user move item in list
ls -1 /usr/share/backgrounds > /tmp/test
do_something () { Xdialog -info "Do something with\n$TREE" x 2000 ;} ; export -f do_something
echo '
<vbox>
<tree headers-clickable="false" reorderable="true">
<label>Backgrounds</label>
<input>cat /tmp/test</input>
<output file>/tmp/test</output>
<variable>TREE</variable>
<height>300</height><width>200</width>
<action>do_something &</action>
<action signal="button-release-event" condition="command_is_true( echo $PTR_Y )">break:</action>
<action signal="button-release-event">save:TREE</action>
<action signal="button-release-event">activate:BTN_SAVE</action>
</tree>
<button visible="false">
<variable>BTN_SAVE</variable>
<action>cp /tmp/test /tmp/testbackup</action>
<action>save:TREE</action>
<action condition="command_is_true([[ $(wc </tmp/test) != $(wc </tmp/testbackup) ]] && sed \"s/^|*//\" /tmp/testbackup > /tmp/test && echo true )">refresh:TREE</action>
</button>
</vbox>' | gtkdialog -s
sorting a list alphabetically can sometimes be helpful if test file is
created haphazardly
I used script in puppy help system
http://murga-linux.com/puppy/viewtopic. ... 003#964003
____________________________________________________
created haphazardly
Code: Select all
# sort alphabetically
LIST=$(sort -f /tmp/test)
echo "$LIST" > /tmp/test
http://murga-linux.com/puppy/viewtopic. ... 003#964003
____________________________________________________
- MochiMoppel
- Posts: 2084
- Joined: Wed 26 Jan 2011, 09:06
- Location: Japan
Just for the record and everybody's amusement here is what I *thought* would be a solution to the "move onto item" problem.
It uses the deprecated table widget.
It nicely allows drag&drop only between items, eliminating the need for a work around. As a bonus it keeps the dragged item marked and does not fall into instant amnesia like tree.
Works perfectly here for at least 3 drops, but then...
It uses the deprecated table widget.
It nicely allows drag&drop only between items, eliminating the need for a work around. As a bonus it keeps the dragged item marked and does not fall into instant amnesia like tree.
Works perfectly here for at least 3 drops, but then...
Code: Select all
#!/bin/bash
echo '
<table column-header-active="false|false" reorderable="true">
<label>No|Fruit</label>
<item>1|apple</item>
<item>2|banana</item>
<item>3|citron</item>
<item>4|durian</item>
</table>' | gtkdialog -s
- MochiMoppel
- Posts: 2084
- Joined: Wed 26 Jan 2011, 09:06
- Location: Japan
Back to the thread topic and to the OP's question "Is it possible to create an input box in which an action starts immediately when the item is dropped into the box?"
My last attempt worked only for focus model "click", allowed drag only from external windows, required a tmp file and ...OK, let's forget it.
Gtkdialog has no "dropped" signal and so the main problem is to distinguish between manual entry and drag&drop. I'm now convinced that the concept to allow manual entry is bad. Not only does it require very complex code, it also is hardly useful.
Below demo tries to simulate yad's dnd ("drag-and-drop box") widget which accepts only drag&drop text and triggers an action.
The code uses an entry widget with disabled keyboard input (can-focus="false"). Like yad's dnd widget the entry widget remains neatly blank. Unlike yad it supports all of the following features:
- Accepts drag&drop from the active gtkdialog window, not just from external windows
- Accepts middle click paste (select source text, paste with middle click. Not exactly drag&drop, but IMO even better)
- Accepts paste from clipboard (via right-click dialog, Ctrl+V not possible as keyboard input is disabled)
This technique can produce mini windows very similar to desktop icons and may be particularly useful for touchscreens.
My last attempt worked only for focus model "click", allowed drag only from external windows, required a tmp file and ...OK, let's forget it.
Gtkdialog has no "dropped" signal and so the main problem is to distinguish between manual entry and drag&drop. I'm now convinced that the concept to allow manual entry is bad. Not only does it require very complex code, it also is hardly useful.
Below demo tries to simulate yad's dnd ("drag-and-drop box") widget which accepts only drag&drop text and triggers an action.
The code uses an entry widget with disabled keyboard input (can-focus="false"). Like yad's dnd widget the entry widget remains neatly blank. Unlike yad it supports all of the following features:
- Accepts drag&drop from the active gtkdialog window, not just from external windows
- Accepts middle click paste (select source text, paste with middle click. Not exactly drag&drop, but IMO even better)
- Accepts paste from clipboard (via right-click dialog, Ctrl+V not possible as keyboard input is disabled)
This technique can produce mini windows very similar to desktop icons and may be particularly useful for touchscreens.
Code: Select all
#!/bin/bash
function drop_action {
Xdialog -left -backtitle "You dropped:" -msg "${DROP_ZONE// \//\n/}" x &
}; export -f drop_action
echo '
<frame Drop files/folders>
<entry can-focus="false" has-frame="false">
<variable>DROP_ZONE</variable>
<width>110</width>
<height>100</height>
<action>[[ $DROP_ZONE ]] && drop_action</action>
<action>clear:DROP_ZONE</action>
</entry>
</frame>' | gtkdialog -s
- Attachments
-
- drag-and-drop.png
- (53.7 KiB) Downloaded 738 times
- misko_2083
- Posts: 114
- Joined: Tue 08 Nov 2016, 13:42
GtkTreeView creates children when row is DND on another row.
one
^two
three
When you drop row "two" on row "one" this is what happens:
one
\
two
three
In Gtkdialog, the expander that is suppose to expand the children, is disabled. This is probably by design.
In the source ( widget_tree.c ):
If this is enabled, it is possible to see the children and move them back:
This is not the solution, but now we know where the row goes when it is dropped on another row.
one
^two
three
When you drop row "two" on row "one" this is what happens:
one
\
two
three
In Gtkdialog, the expander that is suppose to expand the children, is disabled. This is probably by design.
In the source ( widget_tree.c ):
Code: Select all
/* Remove the default indentation in column 0 */
gtk_tree_view_set_show_expanders(GTK_TREE_VIEW(tree_view), FALSE);
Code: Select all
/* Show the expander */
gtk_tree_view_set_show_expanders(GTK_TREE_VIEW(tree_view), TRUE);
This is not the solution, but now we know where the row goes when it is dropped on another row.
-
- Posts: 212
- Joined: Sun 25 Feb 2007, 14:39
Hi
in
-How export $DROP_ZONE or $fils_sels ?
I want to use it outside the frame and the function,
in more procedures
Ex.
Xdialog -left -backtitle "You dropped:" -msgbox "${DROP_ZONE// \//\n/} " x or
Xdialog -left -backtitle "You dropped:" -msgbox "$fils_sels" x
outside of the function.
( export fils_sels2=$fils_sels not work!)
Thanks you!
in
Code: Select all
#!/bin/bash
function drop_action {
fils_sels=$(echo "$DROP_ZONE" | sed 's, /,\n/,g')
# fil_sels, is modification thanks to @MochiMoppel
Xdialog -left -backtitle "You dropped:" -msg "$fils_sels" x &
}; export -f drop_action
echo '
<frame Drop files/folders>
<entry can-focus="false" has-frame="false">
<variable>DROP_ZONE</variable>
<width>110</width>
<height>100</height>
<action>[[ $DROP_ZONE ]] && drop_action</action>
<action>clear:DROP_ZONE</action>
</entry>
</frame>' | gtkdialog -s
I want to use it outside the frame and the function,
in more procedures
Ex.
Xdialog -left -backtitle "You dropped:" -msgbox "${DROP_ZONE// \//\n/} " x or
Xdialog -left -backtitle "You dropped:" -msgbox "$fils_sels" x
outside of the function.
( export fils_sels2=$fils_sels not work!)
Thanks you!