A barberpole spinner - bbjimmy - 05-05-2016
There are times when a process will take a liong time, but a status bar is not usable for feedback as there is no feedback from the process. A barberpole slinner will give the user some idea that the process is still running.
The following is a library and example program
example program
Code: #!yab
import spinner
// set DEBUG = 1 to print out all messages on the console
DEBUG = 0
OpenWindow()
// Main Message Loop
dim msg$(1)
while(not leavingLoop)
nCommands = token(message$, msg$(), "|")
for everyCommand = 1 to nCommands
if(DEBUG and msg$(everyCommand)<>"") print msg$(everyCommand)
switch(msg$(everyCommand))
case "_QuitRequested"
case "MainWindow:_QuitRequested"
leavingLoop = true
break
case "start"
display_spinner("horizontal")
display_spinner("virtictal")
countdown=1
break
case "stop"
hide_spinner("horizontal")
hide_spinner("virtictal")
countdown = 0
break
default
end switch
next everyCommand
if countdown >0 then
countdown=countdown+1
if countdown=400 countdown=0
endif
if countdown then
spin("horizontal")
spin("virtictal")
endif
wend
CloseWindow()
end
sub OpenWindow()
window open 100,100 to 600,500, "MainWindow", "Main Window"
button 80,30 to 150,60, "start", "start", "MainWindow"
button 180,30 to 250,60, "stop", "stop", "MainWindow"
new_spinner(100,100,100,0,"horizontal", "MainWindow")
new_spinner(10,10,50,1,"virtictal", "MainWindow")
return
end sub
// Close down the main window
sub CloseWindow()
window close "MainWindow"
return
end sub
new_spinner( x,y,length,virtical,name$)
x and y are the top left co-ordinates of the spinner.
length is the number of pixels right or down from the x,y origin
if virtical is true, the spinner is virtical otherwise it is horizontal
name$ is the name of the new slinner.
display_spinner(name$) and hide_spinner(name$) show/hide the spinner.
spin(name$) rotates the barber poel one step. This should be in your main program loop. one cannot spin a hidden spinner ( the view for the spinner is removed on hide, and added on show)
the library ( save as spinner.yab and place in the library search path)
Code: export sub new_spinner(hz,vt,htln,orentationn, name$, view$)
static mumber
number = number+1
dim spinner(number,4)
dim spinnername$(number,2)
spinner(number,1)=hz
spinner(number,2)=vt
spinner(number,3)=htln
if spinner(number,3)=0 spinner(number,3)=1
spinner(number,4)=orentationn
spinnername$(number,1)=name$
spinnername$(number,2)=view$
end sub
export sub display_spinner(name$)
local x,i.number,view$, length
x=arraysize(spinnername$(),1)
for i=1 to x
if (spinnername$(i,1)=name$) number = i
next
view$=spinnername$(number,2)
length=spinner(number,3)
if spinner(number,4) = 0 then
view spinner(number,1),spinner(number,2) to spinner(number,2)+length,spinner(number,1)+15, name$+"_view", view$
draw set 0,"HighSolidFill"
draw set "highcolor",180,180,180, name$+"_view"
draw rect 0,0 to length,15, name$+"_view"
draw set "highcolor",225,225,235, name$+"_view"
draw line 0,15 to length,15, name$+"_view"
draw line length,0 to length,15 , name$+"_view"
draw set "highcolor",150,150,150, name$+"_view"
draw line 0,0 to 0,15 , name$+"_view"
draw line 1,0 to length-1,0 , name$+"_view"
CANVAS 2,2 to length-2,13, name$, name$+"_view"
draw set "highcolor", 0,80,225, name$
draw set "lowcolor", 245,245,245, name$
else
view spinner(number,1),spinner(number,2) to spinner(number,2)+15,spinner(number,1)+length, name$+"_view", view$
draw set 0,"HighSolidFill"
draw set "highcolor",180,180,180, name$+"_view"
draw rect 0,0 to 15,length, name$+"_view"
draw set "highcolor",225,225,235, name$+"_view"
draw line 0,length to 15,length, name$+"_view"
draw line 15,0 to 15,length, name$+"_view"
draw set "highcolor",150,150,150, name$+"_view"
draw line 0,0 to 14,0 , name$+"_view"
draw line 0,0 to 0,length , name$+"_view"
CANVAS 2,2 to 13, length-2, name$, name$+"_view"
draw set "highcolor", 0,80,225, name$
draw set "lowcolor", 245,245,245, name$
endif
end sub
export sub hide_spinner(name$)
view remove name$+"_view"
end sub
export sub spin(name$)
local i,length,x
x=arraysize(spinnername$(),1)
for i=1 to x
if (spinnername$(i,1)=name$) number = i
next
length=spinner(number,3)
p = spinner(number,0)
switch p
case 0
pattern$= "030060120240225195135015"
break
case 1
pattern$ = "060120240225195135015030"
break
case 2
pattern$ = "120240225195135015030060"
break
case 3
pattern$ = "240225195135015030060120"
break
case 4
pattern$ = "225195135015030060120240"
break
case 5
pattern$ = "195135015030060120240225"
break
case 6
pattern$ = "135015030060120240225195"
break
case 7
pattern$ = "015030060120240225195135"
break
end switch
draw set 0, pattern$
if spinner(number,4) = 0 then // spin to the right or up
draw rect 0,0 to length-4, 13, name$
p=p-1
if p<0 p=7
spinner(number,0)=p
else
draw rect 0,0 to 13 ,length, name$
p=p+1
if p=8 p=0
spinner(number,0)=p
endif
end sub
RE: A barberpole spinner - clasqm - 05-07-2016
Not trying to be snarky, but should "static mumber" be "static number"? You never use the static "mumber" again.
Also, perhaps just for readability:
orentationn => orientation
virtical =>vertical (in fact in the demo you have it as "virtictal")
But, a very interesting approach, and a new tool in the yab toolbox! Thank you.
RE: A barberpole spinner - bbjimmy - 05-07-2016
A typo, but yes. I am still changing this library to make it more uesful. I will post here when I am really happy with it.
RE: A barberpole spinner - clasqm - 05-08-2016
OK, I'm looking to incorporate this in my app TinyTim (what a useful little test mule that is turning out to be). The first confusing bit was that I got "XXX is not of type View" errors. Turns out that I was trying to create the spinner and immediately hide it.
Code: new_spinner(70,140,0,210, "DuringCurl", "MainWindow")
hide_spinner("DuringCurl")
That's not how it works, apparently. new_spinner just sets up the variables. The spinner doesn't exist and therefore cannot be hidden until you've run display_spinner. Just mentioning that for the sake of the documentation.
Right, that out of the way, I am now getting segmentation fault errors, i.e. the OS itself does not like what yab is doing. I suspect that is because I'm trying to be all clever and artistic and superimposing the spinner on top of a button. Will keep on experimenting and reporting here.
RE: A barberpole spinner - clasqm - 05-08-2016
OK, I'm missing something here. The code below should display a 50-pixel horizontal spinner in the bottom left corner. But it doesn't. It does not crash, it just does not display anything.
Code: import spinner
window open 100,100 to 500,280, "MainWindow", ProgramName$
window set "MainWindow", "look", "floating"
window set "MainWindow", "feel", "modal-app"
window set "MainWindow", "flags","not-zoomable"
window set "MainWindow", "flags","not-resizable"
text 10,25 to 49,40, "URLlabel", "URL:", "MainWindow"
text 10,68 to 52,88, "Submitlabel", "Submit", "MainWindow"
text 10,105 to 59,125, "Resultslabel", "Result:", "MainWindow"
draw rect 70,10 to 390,50, "MainWindow"
Textedit 71,11 to 389,49, "URLField", 0,"MainWindow"
Button 70, 60 to 390, 90, "tinyurlButton", "Submit this URL to tinyurl.com", "MainWindow"
View 70, 100 to 390, 130, "ShortURLView", "MainWindow"
new_spinner(10,147,50,0, "DuringCurl", "MainWindow")
display_spinner("DuringCurl")
spin("DuringCurl")
Button 70, 140 to 280, 170, "copyButton", "Copy to clipboard", "MainWindow"
option set "copyButton", "enabled", 0 //don't need this until we have a short URL
Button 290, 140 to 390, 170, "aboutButton", "About", "MainWindow"
There's something here that I am not seeing/understanding.
RE: A barberpole spinner - bbjimmy - 05-08-2016
I added an updated version of spinner.yab at https://github.com/bbjimmy/yab-lib one can see the documentation at https://github.com/bbjimmy/yab-lib/blob/master/spinner/spinner.md
RE: A barberpole spinner - clasqm - 05-09-2016
I can display the spinner now, thanks. Not getting it to spin yet, but it's late at night. Will try again tomorrow.
You say in the documentation
Code: When your process starts, set a flag variable to and display the spinner:
display_spinner("MySpinner")
spin=true
my_cool_process()
spin=false
hide_spinner("MySpinner")
Then in the main message loop of your program add:
if spin spinall()
Now while my_cool_process() is running, the spinner will show on the bottom of MyView.
But while my program is in my_cool_process(), it is not checking the main loop. It only returns to the main loop when my_cool_process() completes. You'd have to spawn the spinner into a separate thread to do that. Hmm, now if we spun it off to a separate program ... I think I see a way. TTYL
RE: A barberpole spinner - bbjimmy - 05-09-2016
yes, launch a separate program and have it send a message when the process is done. Then the main loop can spin the spinner until it receives the done message.
RE: A barberpole spinner - clasqm - 05-10-2016
(05-09-2016, 09:46 PM)bbjimmy Wrote: yes, launch a separate program and have it send a message when the process is done. Then the main loop can spin the spinner until it receives the done message.
OK, here's one approach:
Code: #!/bin/env yab
DEBUG = 0
displaymessage$ = "Please Wait ..."
import spinner
OpenWindow()
//Main Message Loop
dim msg$(1)
while(not leavingLoop)
nCommands = token(message$, msg$(), "|")
for everyCommand = 1 to nCommands
if(DEBUG and msg$(everyCommand)<>"") print msg$(everyCommand)
switch(msg$(everyCommand))
case "_QuitRequested":
leavingLoop = true
break
default:
break
end switch
next everyCommand
spin("Barber")
wend
CloseWindow()
end
sub CloseWindow()
window close "MainWindow"
end sub
sub OpenWindow()
window open 100,100 to 600,150, "MainWindow", "barberpole"
window set "MainWindow", "look", "bordered"
view 1,3 to 500,28, "SpinView", "MainWindow"
new_spinner(1,1,25,497, "Barber", "SpinView")
display_spinner("Barber")
view 3,31 to 497,50, "MsgView", "MainWindow"
text 1,4 to 494, 19,"themessage", displaymessage$, "MsgView"
text set "themessage", "align-center"
end sub
compile that as the executable "barberpole" (actually, I call dibs on that name - name yours something related to your app like "barberpole_MyGreatApp")
Now call it in yab with
system("barberpole")
When you no longer need it, there are two ways to get rid of it. The elegant way:
system("hey barberpole quit")
The brute force way:
system("kill barberpole")
Of course if there were two barberpoles active they would both be killed, which is why you should name your version appropriately.
This is just a quick mockup. A proper CLI app would put itself in the screen centre, have parameters to change colours and direction, a custom message and so on. I think I will develop that further.
RE: A barberpole spinner - bbjimmy - 05-10-2016
You are forgetting about inter application messaging in yab.
Change the main loop:
Code: while(not leavingLoop)
nCommands = token(message$, msg$(), "|")
for everyCommand = 1 to nCommands
if(DEBUG and msg$(everyCommand)<>"") print msg$(everyCommand)
switch(msg$(everyCommand))
case "_QuitRequested"
case "_Scripting:done"
leavingLoop = true
break
default:
break
end switch
next everyCommand
spin("Barber")
wend
have your application send the_Scripting:done message:
arived = message send "application/x-vnd.barberpole", "done"
|