 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
freakkk as guest Guest
|
Posted: Sat Jul 15, 2006 4:29 am Post subject: TreeView: Drag and Drop items |
|
|
| Quote: | | The user has attempted to start dragging an item (there is currently no built-in support for this). | Using v1.0.44 there isn't currently any built in support for this-- so here is an attempt I made. As it currently stands- it only keeps 1 level deep worth of child items.. and since it uses a timer to detect how far your dragging the item-- it seems to act a little buggy at times. I would love to see feedback on improving (I'm sure theres probably a much better more efficeint way of doing this!!)
Anyways- here it is:
--Corey
| Code: | #singleinstance force
SetTimer, TREEVIEWdragTIMER, 10
SetTimer, TREEVIEWdragTIMER, Off
Gui, Add, TreeView, gMySubroutine h195 0x200 AltSubmit 0x400
Gui, Add, Button, gMOVEdown, MOVEdown
Gui, Add, Button, gMOVEup, MOVEup
P1 := TV_Add("First parent")
P1C1 := TV_Add("Parent 1's first child", P1) ; Specify P1 to be this item's parent.
P2 := TV_Add("Second parent")
P2C1 := TV_Add("Parent 2's first child", P2)
P2C2 := TV_Add("Parent 2's second child", P2)
P2C2C1 := TV_Add("Child 2's first child", P2C2)
P3 := TV_Add("3rd parent")
P4 := TV_Add("4th parent")
Gui, Show, ,Drag and drop experiment.. ; Show the window and its TreeView.
return
GuiEscape:
GuiClose: ; Exit the script when the user closes the TreeView's GUI window.
ExitApp
;------------------------------------------------------------------------------
MOVEup:
TREEVIEWmoveup()
return
;------------------------------------------------------------------------------
MOVEdown:
TREEVIEWmovedown()
return
;------------------------------------------------------------------------------
MySubroutine:
If A_GuiEvent=D
{
MouseGetPos, , OutputVarY
SetTimer, TREEVIEWdragTIMER, On
}
return
;------------------------------------------------------------------------------
TREEVIEWdragTIMER:
OLDvalue=
;TV_Modify(A_EventInfo , "Select")
GetKeyState, state, LButton, P
If state=U
{
;TV_Modify(A_EventInfo , "Select")
SetTimer, TREEVIEWdragTIMER, Off
OutputVarY=
OLDvalue=
NEWOutputVarY=
return
}
MouseGetPos, , NEWOutputVarY
If NEWOutputVarY=%OutputVarY%
return
OLDvalue:=Sub(OutputVarY, 11)
If NEWOutputVarY<%OLDvalue%
{
MouseGetPos, , OutputVarY
TREEVIEWmoveup()
return
}
OLDvalue:=Add(OutputVarY, 11)
If NEWOutputVarY>%OLDvalue%
{
MouseGetPos, , OutputVarY
TREEVIEWmovedown()
return
}
return
;////////////////////////// FUNCTIONS //////////////////////////
TREEVIEWmoveup()
{
TV_GetText(PREVitem, TV_GetPrev(TV_GetSelection()))
TV_GetText(THISitem, TV_GetSelection())
If PREVitem=
return
; LOOPS THROUGH ITEM.. STORING THE TEXT OF CHILD ITEMS IN A STRING.. (there's gotta be a better way!!)
Loop
{
If TV_GetChild(TV_GetSelection())=0 ; CURRENT ITEM HAS CHILD ITEMS..
break
TV_GetText(CHILDitem, TV_GetChild(TV_GetSelection()))
TV_Delete(TV_GetChild(TV_GetSelection()))
If THISitemARRAY=
THISitemARRAY=%CHILDitem%
Else
THISitemARRAY=%THISitemARRAY%|%CHILDitem%
}
Loop
{
If TV_GetChild(TV_GetPrev(TV_GetSelection()))=0 ; CURRENT ITEM HAS CHILD ITEMS..
break
TV_GetText(CHILDitem, TV_GetChild(TV_GetPrev(TV_GetSelection())))
TV_Delete(TV_GetChild(TV_GetPrev(TV_GetSelection())))
If PREVitemARRAY=
PREVitemARRAY=%CHILDitem%
Else
PREVitemARRAY=%PREVitemARRAY%|%CHILDitem%
}
If THISitemARRAY<>
{
Loop, Parse, THISitemARRAY, |
TV_Add(A_LoopField, TV_GetPrev(TV_GetSelection()))
}
If PREVitemARRAY<>
{
Loop, Parse, PREVitemARRAY, |
TV_Add(A_LoopField, TV_GetSelection())
}
TV_Modify(TV_GetSelection() , "", PREVitem)
TV_Modify(TV_GetPrev(TV_GetSelection()) , "Select", THISitem)
PREVitemARRAY=
THISitemARRAY=
return
}
;------------------------------------------------------------------------------
TREEVIEWmovedown()
{
TV_GetText(NEXTitem, TV_GetNext(TV_GetSelection()))
TV_GetText(THISitem, TV_GetSelection())
If NEXTitem=
return
Loop
{
If TV_GetChild(TV_GetSelection())=0
break
TV_GetText(CHILDitem, TV_GetChild(TV_GetSelection()))
TV_Delete(TV_GetChild(TV_GetSelection()))
If THISitemARRAY=
THISitemARRAY=%CHILDitem%
Else
THISitemARRAY=%THISitemARRAY%|%CHILDitem%
}
Loop
{
If TV_GetChild(TV_GetNext(TV_GetSelection()))=0
break
TV_GetText(CHILDitem, TV_GetChild(TV_GetNext(TV_GetSelection())))
TV_Delete(TV_GetChild(TV_GetNext(TV_GetSelection())))
If NEXTitemARRAY=
NEXTitemARRAY=%CHILDitem%
Else
NEXTitemARRAY=%NEXTitemARRAY%|%CHILDitem%
}
If THISitemARRAY<>
{
Loop, Parse, THISitemARRAY, |
TV_Add(A_LoopField, TV_GetNext(TV_GetSelection()))
}
If NEXTitemARRAY<>
{
Loop, Parse, NEXTitemARRAY, |
TV_Add(A_LoopField, TV_GetSelection())
}
TV_Modify(TV_GetSelection() , "", NEXTitem)
TV_Modify(TV_GetNext(TV_GetSelection()) , "Select", THISitem)
NEXTitemARRAY=
THISitemARRAY=
return
}
;------------------------------------------------------------------------------
Add(x, y)
{
return x + y ; "Return" expects an expression.
}
;------------------------------------------------------------------------------
Sub(x, y)
{
return x - y ; "Return" expects an expression.
} |
|
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10465
|
Posted: Sat Jul 15, 2006 1:57 pm Post subject: |
|
|
| Nice-looking script (maybe a similar approach can be applied to ListViews). I'm glad you've created a means of drag-and-drop because it might be a while before built-in support is added. |
|
| Back to top |
|
 |
Terrapin
Joined: 15 Aug 2005 Posts: 107 Location: North Carolina
|
Posted: Mon Jul 17, 2006 9:36 am Post subject: |
|
|
Corey, it works very well as far as I can see. I had thought to try to do something similar with ListView, but it seems like it would take a great deal of brain-power I don't have. I join Chris in asking whether this is possible with ListView? It seems it would be simpler than doing TreeView?
Thanks,
Bob |
|
| Back to top |
|
 |
MisterW
Joined: 20 Jul 2005 Posts: 65
|
Posted: Mon Jul 17, 2006 3:01 pm Post subject: Tree Functions |
|
|
Here are some functions I wrote to convert trees to strings and back. They can be used to handle cutting/copying/pasting/moving of brances or loading or saving trees to a file. They could be more robust in their handling of delimiters but they seem to work ok.
Below the functions is some sample code that uses them. The listview does nothing at the moment.
| Code: | Tree2Str(id,byref str)
{
TV_GetText(name,id)
str=%str%%name%
first_child := TV_GetChild(id)
if first_child
{
str=%str%(
Tree2Str(first_child,str)
this_child := first_child
Loop {
next_child := TV_GetNext(this_child)
if next_child {
str=%str%,
Tree2str(next_child,str)
this_child := next_child
} else
break
}
str=%str%)
}
return
}
; This function will destroy the string passed to it.
; If you need it make a copy
Str2Tree(byref str, parent_id=0 , relative=0)
{
Loop {
name=
maybe=
size := StrLen(str)
at_start=1
count = 0
Loop, parse, str
{
count := a_index
c := a_loopfield
if c = ,
{
r=0
break
} else if c = (
{
r=1
break
} else if c = )
{
r = -1
break
} else {
a := Asc(c)
if (a = 32) {
if !at_start
maybe=%maybe%%c%
; else skip
} else if (a > 8 and a < 14) { ; tabs, newlines, linefeeds and anything in between
; skip
} else {
at_start = 0
if maybe {
name=%name%%maybe%%c%
maybe=
} else
name=%name%%c%
}
}
}
if (count = size) ; string end
r = -1
StringTrimLeft,str,str,%count%
if r < 0 ; Found ) or end of string
{
if name
TV_add(name,parent_id)
break
} else if name {
if relative
new_id := TV_Add(name,parent_id,relative)
else
new_id := TV_Add(name,parent_id)
if r > 0 ; Found (
Str2Tree(str,new_id)
}
}
return
}
|
Sample Code
Right Click on a node to get a context menu.
| Code: |
#SingleInstance Force
ThingString=
(
Things{
Animals{
Farm{Sheep,Goat,Cow,Horse,Chicken},
Home{Dog,Cat,Hamster,Budgie,Goldfish}
},
Colors{
Primary{Red,Green,Blue},
Others{Yellow,Magenta,Cyan},
Shades{Black,White}
},
Vehicles{
Land{
Motor{
Car{Holden,Ford,Subaru,Mitsubishi,Toyota},
Truck,Motorbike,Train},
Other{Bike,Skateboard}
},
Sea{Boat,Submarine,Hydrofoil,Hovercraft},
Air{Plane,Helicopter,Glider}
}
}
)
StringReplace,ThingString,ThingString,{,(,A
StringReplace,ThingString,ThingString,},),A
Menu,ContextMenu,Add,Add,CMHandler
Menu,ContextMenu,Add,Add,CMHandler
Menu,ContextMenu,Add,Delete,CMHandler
Menu,ContextMenu,Add,
Menu,ContextMenu,Add,Cut,CMHandler
Menu,ContextMenu,Add,Copy,CMHandler
Menu,ContextMenu,Add,Paste,CMHandler
Menu,ContextMenu,Add,Insert Above,CMHandler
Menu,ContextMenu,Add,Insert Below,CMHandler
Gui,Font,s10 w1000,Arial
Gui,Add,TreeView, +Buttons cGreen vTVC AltSubmit gTVEvent,
Gui,Add,ListView, vLVC
copy=%ThingString%
Str2Tree(copy)
copy=%ThingString%
Str2Tree(copy)
Gui,+Resize
Gui,Show,w600 h450,Hello There
Gui,Add,StatusBar,,
return
GuiClose:
ExitApp
GuiSize:
tw := A_GuiWidth / 3
SB_SetParts(tw,tw)
th := A_GuiHeight - 35
GuiControl,Move,TVC,x5 y5 w%tw% h%th%
lw := 2 * (A_GuiWidth / 3) - 15
lh := th
lx := tw +10
GuiControl,Move,LVC,x%lx% y5 w%lw% h%lh%
return
TVEvent:
MouseGetPos,x,y
SB_SetText(A_GuiEvent,1)
SB_SetText(A_EventInfo,2)
SB_SetText(x . " , " . y,3)
if A_GuiEvent = RightClick
{
TVSelected := A_EventInfo
Menu,ContextMenu,Show,%x%,%y%
}
return
CMHandler:
op := A_ThisMenuItem
SB_SetText(op,1)
if op = Add
{
InputBox,NewNode
TV_Add(NewNode,TVSelected)
}
else if op = Delete
{
TV_Delete(TVSelected)
}
else if op = Cut
{
TreeBuffer=
Tree2Str(TVSelected,TreeBuffer)
TV_Delete(TVSelected)
}
else if op = Copy
{
TreeBuffer=
Tree2Str(TVSelected,TreeBuffer)
}
else if op = Paste
{
Branch=%TreeBuffer%
Str2Tree(Branch,TVSelected)
}
else if op = Insert Above
{
Branch=%TreeBuffer%
Sibling := TV_GetPrev(TVSelected)
NewParent := TV_GetParent(TVSelected)
if !Sibling
Sibling=First
Str2Tree(Branch,NewParent,Sibling)
}
else if op = Insert Below
{
Branch=%TreeBuffer%
NewParent := TV_GetParent(TVSelected)
Str2Tree(Branch,NewParent,TVSelected)
}
return
|
|
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6721 Location: France (near Paris)
|
Posted: Mon Jul 17, 2006 3:33 pm Post subject: Re: Tree Functions |
|
|
| MisterW wrote: | | Here are some functions I wrote to convert trees to strings and back. | Interesting. Perhaps using a more "standard" syntax like JSON, YAML or the like could be useful. Or not...
http://www.autohotkey.com/forum/viewtopic.php?t=10898&p=67614#67614 _________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2") |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|