SpeedMaster wrote: ↑24 Apr 2020, 08:13
Is it also possible to add an option for the direction ?
SKAN wrote: ↑24 Apr 2020, 08:52
I had thought of that. Too costly (codewise) to implement.
You're right, but it's worth it.
I managed to make one that can go backwards.
I also added a few extra options like the possiblity to disable wrapping around the end ...
CycleStr(Value, unique fields, [ Delimiter, direction, wrapping around ])
here is the function:
Code: Select all
/*
CycleStr v.1.2 by Speedmaster
function to cycles to the next or previous value in a set of values ex. "A|B|C|D"
CycleStr(s:="", Z:="", D:="|", dir:=1, cycle:=true)
S = a value in the set Z.
Z = set of values, a string of delimited values. for ex. "red|green|blue"
you can also auto build a range for numbers syntax is "R:Min:Max:PaddingZeros" for ex. "R:25:99:3" ==> 025|026...099
D = Delimiters can be either a single string or an array of strings. (default is "|")
dir = 0 go to home, 1 cycle forward, -1 cycle backward, 2 go to end
Cycle = false/true allow wrapping around the end.
examples:
CycleStr("B", "A|B|C") returns "C" next value
CycleStr("B", "A|B|C",,-1) returns "A" previous value
CycleStr("C", "A|B|C") returns "A" (wrap around to right)
CycleStr("A", "A|B|C",,-1) returns "C" (wrap around to left)
CycleStr("C", "A|B|C",,1,false) returns "C" (wrapping around disabled)
CycleStr("33", "R:55:100:3") returns "034" (build a range of values from 055 to 100) "055|056...100"
CycleStr("A", "A B/C",[" ", "/"]) returns "B" (mixed delimiters are supported in an array of strings)
CycleStr("r", "abcdefghijklmnopqrstuv","") returns "s" (if there is no delimiter values are split by chars)
;---------------------------------
;script example :
item:="cherry"
right::tooltip, % item:=CycleStr(item,"Apple|Banana|Cherry|Durian|Fig",,1) ; start at "cherry" show next value and wrap around at end
left::tooltip, % item:=CycleStr(item,"Apple|Banana|Cherry|Durian|Fig",,-1,false) ; start at "cherry" show previous value and stop at first value
home::tooltip, % item:=CycleStr(item, "Apple|Banana|Cherry|Durian|Fig",,0) ; jump to home of list
end::tooltip, % item:=CycleStr(item, "Apple|Banana|Cherry|Durian|Fig",,2) ; jump to end of list
*/
CycleStr(S:="", Z:="", D:="|", dir:=1, cycle:=true) {
if (regexmatch(z, "i)R:? ?(-?\d+):(-?\d+):?(\d\d?)?", num)) {
--num1
while (num1++ < num2) {
if (num3!="")
numrange .= Format("{:0" num3 "}", num1) (D?D:D:="|")
else
numrange .= num1 (D?D:D:="|")
}
z:=rtrim(numrange, (D?D:D:="|"))
}
oz:=strsplit(z, d), ozb:=[]
for k, v in oz
ozb[v,1]:=oz[(K+1)<=oz.length()?(k+1):1], ozb[v,2]:=oz[(k-1)>0?(k-1):oz.length()]
if (dir=0)
return ozb[oz[oz.length()],1] ; start of list dir=0
if (dir=2)
return ozb[oz.1,2] ; end of list dir=2
if (!cycle && (dir>0) && (s=oz[oz.length()]))
return s
if (!cycle && (dir=-1) && (s=oz[1]) && oz.length()) ;&& msgbox("") ; cycle disabled
return s
return, ozb[ozb[s].length()?s:(oz[(dir>0)?(oz.length()):1])][(dir>0)?1:2]
}
Demo script for strings:
Code: Select all
#SingleInstance force
gui, font, s12
wraparound:=true
fruits:="Apple|Banana|Cherry|Durian|Fig|Grape|Kumquat|Lychee|Mango|Nectarine|Orange|Papaya|Quince|Yuzu"
gui, add, text, w800 , % "CycleStr() demo`n`n" fruits
gui, add, text, , Press cursors to show values `n(up=home, down=end, right=next, left=previous)
gui, add, text, x80 center border w200 vtxt,
gui, add, checkbox, checked X+10 vwraparound gckb, wrap around
gui, show,
left::
item:=CycleStr(item, fruits,,-1,wraparound)
goto print
return
right::
item:=CycleStr(item, fruits,,1,wraparound)
goto print
return
up::
item:=CycleStr(item, fruits,,0)
goto print
return
down::
item:=CycleStr(item, fruits,,2)
goto print
return
ckb:
gui, submit, nohide
return
print:
guicontrol,,txt, % item
return
esc::
guiclose:
exitapp
Demo script for a range of numbers
Code: Select all
#SingleInstance force
gui, font, s12
wraparound:=true
values:="CycleStr( "" R:Min:Max:Padding "" ) ex. num:=cyclestr(num, "" r:1:1000:5 "" )"
gui, add, text, w550 , % "CycleStr() demo cycling numbers with zero padding`n`n" . values
gui, add, text, , Press cursors to show values `n(up=home, down=end, right=next, left=previous)
gui, add, text, x80 center border w200 vtxt,
gui, add, checkbox, checked X+10 vwraparound gckb, wrap around
gui, show,
left::
item:=CycleStr(item, "r0:1000:5",,-1,wraparound)
goto print
return
right::
item:=CycleStr(item, "r0:1000:5",,1,wraparound)
goto print
return
up::
item:=CycleStr(item, "r0:1000:5",,0)
goto print
return
down::
item:=CycleStr(item, "r0:1000:5",,2)
goto print
return
ckb:
gui, submit, nohide
return
print:
guicontrol,,txt, % item
return
esc::
guiclose:
exitapp
Cheers