Drag, drop and go

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Message
Author
User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#31 Post by MochiMoppel »

Something like this?

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
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:

Code: Select all

<action condition="command_is_true([[ $(</tmp/test) == $(</tmp/testbackup) ]] && { do_something & echo true ;} || echo false )">break:</action> 
Better performance, worse readability :lol:

User avatar
zigbert
Posts: 6621
Joined: Wed 29 Mar 2006, 18:13
Location: Valåmoen, Norway
Contact:

#32 Post by zigbert »

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 :D
Thanks a lot
Sigmund

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#33 Post by MochiMoppel »

zigbert wrote:Keep it coming :D
OK, here we go:

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 :wink:

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
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...
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.

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> 
with

Code: Select all

<action>do_something &</action>
<action signal="button-release-event" condition="command_is_true( echo $PTR_Y )">break:</action>
I think there is no need to specify the mouse button. Dragging works only with the left button, and so does doubleclick. Middle or right mouse button clicks are not affected by the code.

User avatar
zigbert
Posts: 6621
Joined: Wed 29 Mar 2006, 18:13
Location: Valåmoen, Norway
Contact:

#34 Post by zigbert »

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 :lol:

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

User avatar
don570
Posts: 5528
Joined: Wed 10 Mar 2010, 19:58
Location: Ontario

#35 Post by don570 »

sorting a list alphabetically can sometimes be helpful if test file is
created haphazardly

Code: Select all

# sort alphabetically
LIST=$(sort -f /tmp/test)
echo "$LIST" > /tmp/test 
I used script in puppy help system

http://murga-linux.com/puppy/viewtopic. ... 003#964003
____________________________________________________

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#36 Post by MochiMoppel »

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...

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

User avatar
zigbert
Posts: 6621
Joined: Wed 29 Mar 2006, 18:13
Location: Valåmoen, Norway
Contact:

#37 Post by zigbert »

MochiMoppel wrote:Works perfectly here for at least 3 drops, but then...
:lol:

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#38 Post by MochiMoppel »

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.

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

User avatar
misko_2083
Posts: 114
Joined: Tue 08 Nov 2016, 13:42

#39 Post by misko_2083 »

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 ):

Code: Select all

	/* Remove the default indentation in column 0 */
	gtk_tree_view_set_show_expanders(GTK_TREE_VIEW(tree_view), FALSE);
If this is enabled, it is possible to see the children and move them back:

Code: Select all

	/* Show the expander */
	gtk_tree_view_set_show_expanders(GTK_TREE_VIEW(tree_view), TRUE);
Image
This is not the solution, but now we know where the row goes when it is dropped on another row. :D

arivas_2005
Posts: 212
Joined: Sun 25 Feb 2007, 14:39

#40 Post by arivas_2005 »

Hi
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
-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!

Wognath
Posts: 423
Joined: Sun 19 Apr 2009, 17:23

Unidentified flying objects

#41 Post by Wognath »

Drag and drop scripts, based on Zigbert's on 1st page of this topic, have been useful for me:

Code: Select all

<window title="title"><vbox>
		<entry width-request="400" height-request="60"> 
			<variable>X</variable> 
			<default>"Drag a file here or click the button"</default> 
			<action signal="changed">EXIT:1</action> 
		</entry> 
		<button><label>"button label"</label></button>
</vbox></window>
After the script exits, icons occasionally fly across the screen, from nowhere to nowhere, as though replaying a drag and drop action. The UFOs do not appear to be hostile, but :?: why do they appear :?:
Fatdog 720 frugal, HP AMD streambook

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#42 Post by MochiMoppel »

This is an enhanced version of my last posted version.

I needed a "drop zone" for a toolbar which combines the advantages of Wognath's and my own approach
- contains a default text in the entry field. No need to keep the field empty and no need for a frame.
- can be used multiple times without the need to close the dialog

A bit tricky but interesting. I learned that the entry widget does not trigger an "enter-notify-event" signal when the mouse enters the widget with a dragged text but that this signal is emitted - somewhat belatedly - when the text is finally dropped. I also learned that the "enter-notify-event" and "leave-notify-event" signals are always emitted twice, only heaven knows why.

The real challenge was to keep the default text always visible without mixing with the dropped text. I almost succeeded. Now the entry field is only cleared during simple mouse movements and only while the cursor hovers over the field. The default text remains visible while dragging text onto the widget and the dropped text never appears in the field. Good enough for me.

Code: Select all

#!/bin/sh
function drop_action { 
	 Xdialog -left -backtitle "You dropped:" -msg "${DROP_ZONE// \//\n/}" x &
}; export -f drop_action 

export MSG="Drop files/folders"
echo ' 
<entry xalign="0.5" can-focus="false" overwrite-mode="true"> 
	<variable>DROP_ZONE</variable> 
	<input>echo "$MSG"</input>
	<action signal="enter-notify-event">clear:DROP_ZONE</action>
	<action signal="leave-notify-event">refresh:DROP_ZONE</action>
	<action>[[ -z $DROP_ZONE || $DROP_ZONE == $MSG ]] || drop_action</action> 
	<action condition="command_is_true( [[ $DROP_ZONE ]] && echo true )">refresh:DROP_ZONE</action> 
</entry>'| gtkdialog -s
Attachments
Enhanced_drag_and_drop.png
(52.91 KiB) Downloaded 130 times

Post Reply