A barberpole spinner
#1
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
Reply
#2
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.
Reply
#3
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.
Reply
#4
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.
Reply
#5
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.
Reply
#6
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/...spinner.md
Reply
#7
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
Reply
#8
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.
Reply
#9
(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.
Reply
#10
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"
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)
Free Web Hosting