Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
The brackets are handy tokens for telling RunRev where a string of words starts and finishes. The $HOME token is a RunRev variable and is not enclosed in quotes as if it were part of a Linux shell path name. The single & token concatenates two strings together without any spaces. The && token does the same with a space. Because RunRev interprets the " token itself, to add a space separated string as one Linux shell variable, the quote token is used.
The second command makes sure that RunRev hasn't split a long string with a carriage return.
The third command runs the shell command and put the result into DUNWORK. Even if there is no output from the shell script, it is a good idea to do it this way as you can see if there are any shell script errors with the variable watcher when you set the RunRev script debug mode.
The other way RunRev scripts in this application call shell commands is like this.
put the shell of ("ls" && MYFLDR && "|wc -l") into FLDRLINES
replace return with empty in FLDRLINES
In this case the Linux shell command returned a value to RunRev. Because the Linux shell adds a carriage return, we have to get rid of it otherwise RunRev sees it as two lines, one containing the value and one a blank.
These simple constructions allow you to seamlessly integrate Runtime Revolution GUI interfaces with Linux shell scripts and commands.
Now it is time to write the script for the image "Im1". We will use the button "button 1" to copy this script to the other 48 images on the story board.
I've added some extra functionality to the images which we shall implement as the story board is developed. The two extra areas are Sound and Zoom. Sound lets you create a sound or add a sound which is associated with the chosen image. Zoom lets you zoom a picture a large as all the thumbnail pictures. To make this work you will have to add a new image starting at the top left of thumbnail "Im1" and ending at the bottom right of thumbnail "Im49". The name of this image is "ZOOM". Here is the size and position property inspector. Make sure its size and position are locked.
Picture of Property Inspector for Image ZOOM:
[img=640x480]http://images.linuxquestions.org/articles/zoom.jpg[/img]
RunRev scripts take actions designated by action handlers. In the Button 1 script the handler we used was "on mouseUp" which performed the actions when the mouse button was released. In the next script we are using the handler "on mouseDown" which performs the actions when a mouse button is pressed down.
Here is the script for image "Im1" which lots of explanatory comments. Right click on the thumbnail "Im1" in Pointer Mode to bring up the object menu and select "edit script" to enter the following.
Code:
on mouseDown
#set a global variable that can be used in other scripts or contain
#values set by other scripts
global PPROG
#me is a special RunRev variable in this case containing the object name of
#the clicked object i.e. The image name
put me into CPIC
put the filename of image me into CIMAGE
#Check that this image field contains a source image
#<> means "not equal to"
if CIMAGE <> empty
then
#Ask the user what they want to do.
#The order of options after the with statement is the reverse of the order
#of the button placement in to answer pop up window. The first item "Move"
#will be highlighted and activated by the Enter key. You can change this
#order to suit your preferences.
answer "Move, Zoom, Edit, Remove Picture or Add Sound" with "Cancel" or "Sound" or "Remove" or "Edit" or "Zoom" or "Move"
#The special RunRev variable "it" contains the last value input.
put it into MANSWER
#Take action based on the input value
switch MANSWER
case "Cancel"
#Break out of the switch
break
case "Move"
#Set some variables
global MUVIT
global MUVPIC
global MUVFILE
#Give a message to click an empty thumbnail
put "Click OK, then click on an empty picture square" into MASK
answer MASK
put "YES" into MUVIT
put CPIC into MUVPIC
put CIMAGE into MUVFILE
break
case "Zoom"
#load the ZOOM image with the clicked picture
set the filename of image "ZOOM" to CIMAGE
#Move this image in front of all the other images
set the layer of image "ZOOM" to top
#Hopefully the user will read the howto and click this image
#to unzoom it
break
case "Edit"
global PDIR
global PPROG
answer "Edit with TUX or the GIMP" with "Cancel" or "GIMP" or"TUX"
put it into PPROG
if PPROG <> "Cancel"
then
#Call a shell command script
put ($HOME & "/SB/bin/editpic.sh" && CIMAGE && PPROG) into DUEDIT
replace return with empty in DUEDIT
put the shell of DUEDIT into DUNEDIT
#Refresh the image
set the filename of image CPIC to empty
set the filename of image CPIC to CIMAGE
end if
break
case "Remove"
set the filename of image CPIC to empty
break
case "Sound"
#Add a sound for this picture and rename it to the
#picture name and save it in its folder where it will
#be loaded with the picture next time
answer file "Select a sound to go with this picture" with ($HOME & "/SB/work/sounds")
put it into NEWSND
#Run some Linux shell commands
#basename cuts of the preceding path.
put the shell of ("basename" && CIMAGE) into IMNAME
put the shell of ("dirname" && CIMAGE) into IMDIR
#Do not have to get rid of return as it is done next
put ("cp" && NEWSND && IMDIR & "/" & IMNAME) into CPSND
replace return with empty in CPSND
put the shell of CPSND into DUNCPSND
break
end switch
else
#This is an empty thumbnail so check if it is a square to move
#a picture to
if MUVIT = "YES"
then
#CPIC is the empty image field
set the filename of image CPIC to MUVFILE
#MUVPIC is a global variable containing the image name to be moved
set the filename of image MUVPIC to empty
#Clear the moving variable
put "NO" into MUVIT
end if
end if
end mouseDown
Save the script with the "Apply" button and replace and apply the script in "Button 1" with this one.
Code:
on mouseUp
put 2 into PCOUNT
put the script of image "Im1" into MSCRIPT
repeat for 48 times
put ("Im" & PCOUNT) into PIC
set the script of image PIC to MSCRIPT
add 1 to PCOUNT
end repeat
end mouseUp
Select "Browse Mode" from the menu or tool box and click "Button 1". Return to "Pointer Mode" and right click thumbnail "Im49" to check edit script happened as planned and the script was copied successfully to all of them.
You can right click and cut Button 1 as you shouldn't need it any more.
IMPORTANT MESSAGE
Save the stack after every big change, to help negate Murphy's Law.
The CLICK ME menu button is developed next so that you can load some pictures and at least move them around. This is the script. It is the longest one in the project. If you think of each menu item as another button, it doesn't seem so big.
The object action handler is called "on menuPick", "theMenuItem" can be any meaningful name not already used by RunRev. Since I added some more choices to the menu here is a new picture.
Picture of CLICK ME menu:
[img=640x480]http://images.linuxquestions.org/articles/click2.jpg)[/img]
Add SOUNDS and Manage Files to the objects Property Inspector. Both these items will eventually be used to create some new sub stacks, although sounds will be used from the existing stack.
Here is the CLICK ME menu script
Code:
on menuPick theMenuItem
global NUMPICS
global PDIR
global MYPICDIR
put ($HOME & "/SB/work/pics/") into MYPICDIR
#The default folder is where RunRev goes to open folders
set the defaultFolder to MYPICDIR
#Turn off animation if going
set the filename of image "ANIM" to $HOME & "/SB/sclblue.gif"
#The visible property is used to hide or show objects
set the visible of button "ANIMCTRL" to false
set the visible of button "PSOUND" to false
#Perform actions for each menu item
switch theMenuItem
case "NEW PROJECT"
#Make directory
ask "Enter one word project Name"
put it into NDIR
put ($HOME & "/SB/work/pics/" & NDIR) into PDIR
put the shell of ("mkdir" && PDIR) into DUNDIR
#Test there is room for more pictures
if NUMPICS < 49
then
set the visible of button "NEWPIC" to true
else
put "Cannot add any more pictures" after field "MESG"
end if
break
case "LOAD PROJECT"
#Load all picture files in a folder
#Get name from list
global MYPICDIR
global NUMPICS
answer folder "Select Project Folder" with MYPICDIR
put it into PDIR
#Fill the pics. The second set of brackets inside the quotes
#make the shell commands run in a sub shell, first changing to
#the folder PDIR, then running the file command on this folder
#which outputs the file path name followed by a colon followed
#by the file type. This output is piped into the grep command
#to select only those of type "image". Finally the output from
#grep is piped into the cut command with the field delimiter set
#to the colon, returning a list of file path names.
put ("(cd" && PDIR && "; file * | grep image | cut -d: -f1 )" ) into DUIFILES
replace return with empty in DUIFILES
put the shell of DUIFILES into IFILES
#IFILES is a list of image file path names, one per line.
if IFILES <> empty
then
#This is a repeat loop inside a repeat loop
put 0 into ALLPICS
#Loop round each file name
repeat for each line thisLine in IFILES
put "NO" into PSAVED
#put each picture thisLine into empty thumbnail by looping round
#thumbnails until the flag PSAVED is not equal to NO
repeat while ALLPICS < 49 and PSAVED = "NO"
add 1 to ALLPICS
put "Im" & ALLPICS into THISPIC
if the filename of image THISPIC <> empty
then
#Skip it
else
put the filename of image THISPIC into THISPFILE
set the filename of image THISPIC to (PDIR & "/" & thisLine)
add 1 to NUMPICS
#Set inner repeat loop exit flag
put "YES" into PSAVED
#Put a message into MESG
put return & "Added pic" && NUMPICS && "as" && thisLine after field "MESG"
end if
#In case we have run out of empty thumbnails
if ALLPICS > 49
then
put NUMPICS && "Is more than 49 pics" after field "MESG"
exit repeat
end if
#End of inner repeat loop
end repeat
#End of outer repeat loop
end repeat
put return & "Pic Count" && NUMPICS after field "MESG"
#Make sure number of pics is not more than 49
if NUMPICS > 49
then
put 49 into NUMPICS
end if
#Show add pic button if there are empty thumbnails
if NUMPICS < 49
then
set the visible of button "NEWPIC" to true
end if
#Put the project directory path into PMESG
put PDIR & return after field "PMESG"
#Allow the user to make an animation of loaded pictures
set the visible of button "ANIMTEST" to true
else
put return & "No image files in" && PDIR after field "MESG"
put empty into PDIR
end if
break
case "LOAD PICTURE"
#Load a single picture. This can also be a repeat picture from a
#loaded project folder
#Get name from list
global MYPICDIR
global NUMPICS
put "NO" into TSAVED
#The with statement sets the folder to start looking for files
answer file "Select Project Picture" with MYPICDIR
put it into PFILE
if PFILE <> empty
then
#This is the same inner loop and if conditions
#as in the load project case item
#with the variable names changed
repeat while ALLPICS < 49 and TSAVED = "NO"
add 1 to ALLPICS
put "Im" & ALLPICS into THISPIC
if the filename of image THISPIC <> empty
then
#Skip it
else
put the filename of image THISPIC into THISPFILE
set the filename of image THISPIC to PFILE
add 1 to NUMPICS
put "YES" into TSAVED
put return & "Added pic" && NUMPICS && "as" && PFILE after field "MESG"
end if
if ALLPICS > 49
then
put NUMPICS && "Is more than 49 pics" after field "MESG"
exit repeat
end if
end repeat
end if
if NUMPICS > 49
then
put 49 into NUMPICS
end if
if NUMPICS < 49
then
set the visible of button "NEWPIC" to true
end if
if NUMPICS > 2
then
set the visible of button "ANIMTEST" to true
end if
break
case "CLEAR BOARD"
global NUMPICS
answer "Clear the Story Board of all current pictures" with "Cancel" or "WIPE"
put it into CRACT
if CRACT = "Cancel"
then
break
end if
if CRACT = "WIPE"
then
put 1 into CLPICS
#A repeat until loop just to show you how it is done
#We need to have one more than the number of pictures
#To make the loop stop at this point
repeat until CLPICS = 50
put "Im" & CLPICS into CLRPIC
set the filename of image CLRPIC to empty
add 1 to CLPICS
end repeat
#Clear out picture count, project path names, and hide
#action buttons
put 0 into NUMPICS
put empty into field "PMESG"
set the visible of button "NEWPIC" to false
set the visible of button "ANIMTEST" to false
set the visible of button "ANIMCTRL" to false
end if
break
case "SOUNDS"
answer "Create New Sound or Add Existing Sound to Layout" with "Cancel" or "Create" or "Add"
put it into SANS
if SANS <> "Cancel"
then
switch SANS
case "Create"
#This is an easy case as we just choose a tool for creating
answer "Use Audacity or Simple Recorder" with "Audacity" or "Recorder"
put it into RECS
global NEWSND
ask "Enter a one word name for your new sound"
put it into NSND
put ($HOME & "/SB/work/sounds/" & NSND & ".wav") into NEWSND
if RECS = "Audacity"
then
put ($HOME & "/SB/bin/donewsnd.sh" && NEWSND) into DUNEW
replace return with empty in DUNEW
put the shell of DUNEW into DUNNEW
else
#Use the new recorder stack.
go card "SOUND" of stack "SB"
end if
break
case "Add"
#A more difficult case as the sound needs to be identified
#as belonging to an animation so that it can be played back
#when the animation is being displayed.
answer file "Choose a wav sound for the whole layout" with ( $HOME & "/SB/work/sounds/")
global LAYSND
put it into LAYSND
#To be more general sound formats other than "wav" should be
#allowed or converted, but at this point of development it
#doesn't happen, (Maybe later) so we had better test the name
#to make sure it is a wav format file.
put the shell of ("basename" && LAYSND && "|cut -d. -f2") into STYPE
if STYPE <> "wav"
then
#Give the user a message
put "Sound not wav format" into field "MESG"
#Break out of the case
break
end if
#Create a layout folder, save the pictures and rename the sound to the folder name
#Make sure layout folder exists
put ($HOME & "/SB/work/layouts") into LAYDIR
put the shell of ("mkdir" && LAYDIR) into DUNMK
#Check the layout folder doesn't exist or overwrite it
put "NO" into GOTFLDR
#This loop will keep asking for a name until GOTFLDR = YES
#Or it breaks out of the case
repeat until GOTFLDR = "YES"
ask "Enter a one word name for your layout"
put it into LAYNAME
if LAYNAME = "Cancel"
then
break
end if
put (LAYDIR & "/" & LAYNAME) into LAYFLDR
#This tests for the existence of a folder
if there is a folder LAYFLDR
then
answer "Overwrite existing layout" with "Yes" or "No"
put it into OLAY
if OLAY = "Yes"
then
put "YES" into GOTFLDR
else
break
end if
else
put "YES" into GOTFLDR
end if
end repeat
#Even if there is an existing folder, existing files can't
#be removed in case the current story board layout is
#using files from this layout folder which will be the case
#when trying out more new sounds, or if pictures have been modified
#after trying out a sound. With this scenario, copy (cp) won't
#copy a file to itself, but will leave existing or modified files
#in place and return an error message.
#
#Create the layout folder whether it exists or not
put the shell of ("mkdir" && LAYFLDR) into DUFLDR
#Copy the layout files into new folder
#Collect non empty image filenames and their image numbers
#The lists are used to restore the original storyboard if the
#user requests this option. This is so that a layout that
#contains spaces which the user may want to fill after the
#sound has be tested, can be restored.
global LAYPICS
put empty into LAYPICS
global NOLAY
put empty into NOLAY
put 1 into PICCOUNT
repeat for NUMPICS times
put "Im" & PICCOUNT into LPIC
put the filename of image LPIC into TPIC
if TPIC <> empty
then
put TPIC & space after LAYPICS
put PICCOUNT & space after NOLAY
end if
add 1 to PICCOUNT
end repeat
#Load them into LAYFLDR
put the shell of ("cp" && LAYPICS && LAYFLDR) into CPLAY
#Rename and copy the sound.
put (LAYNAME & ".wav") into LAYBASE
put ("cp" && LAYSND && LAYFLDR & "/" & LAYBASE) into CPSND
replace return with empty in CPSND
put the shell of CPSND into DUNCPSND
#Replace the current layout with the newly saved layout
#Clear board, pic count and hide buttons
put 1 into CLPICS
repeat until CLPICS = 50
put "Im" & CLPICS into CLRPIC
set the filename of image CLRPIC to empty
add 1 to CLPICS
end repeat
put 0 into NUMPICS
put empty into field "PMESG"
set the visible of button "NEWPIC" to false
set the visible of button "ANIMTEST" to false
set the visible of button "ANIMCTRL" to false
#Load the layout
put ("(cd" && LAYFLDR && "; file * | grep image | cut -d: -f1 )" ) into DULFILES
replace return with empty in DULFILES
put the shell of DULFILES into LFILES
if LFILES <> empty
then
put 0 into ALLPICS
repeat for each line thisLine in LFILES
add 1 to ALLPICS
put "Im" & ALLPICS into THISPIC
set the filename of image THISPIC to (LAYFLDR & "/" & thisLine)
add 1 to NUMPICS
end repeat
end if
#Put new layout folder name into PMESG
put LAYFLDR into field "PMESG"
#Ask whether to replace or keep new layout and save the answer
#into a global to be used by the end animation action object
answer "Keep or Replace new layout when finished Animation testing" with "Replace" or "Keep"
global REPLAYOUT
put it into REPLAYOUT
set the visible of button "ANIMTEST" to true
break
end switch
end if
break
case "Refresh Project List"
#Replaces multiple occurrences of the same project path with one.
global NUMPICS
put empty into field "PMESG"
put empty into RLDIR
put 1 into RLCOUNT
repeat until RLCOUNT >= NUMPICS
put "Im" & RLCOUNT into RLPIC
put the filename of image RLPIC into RLPICFILE
put return & RLPICFILE after field "MESG"
if RLPICFILE <> empty
then
#Cut off the folder path part
put the shell of ("dirname" && RLPICFILE) into RLDIR
#Check its not in the lines of PMESG
put "NO" into RLMATCH
if field "PMESG" <> empty
then
put field "PMESG" into ALLPDIRS
repeat for each line RLLINE in ALLPDIRS
if RLLINE <> empty
then
#This RunRev test checks for a text match just like the shell
#command grep does.
if matchText ( RLDIR, RLLINE)
then
put "YES" into RLMATCH
#exit the repeat loop
exit repeat
else
put "NO" into RLMATCH
end if
end if
end repeat
end if # PMESG This comment is to see which if this end if belongs.
if RLMATCH = "NO"
then
put RLDIR after field "PMESG"
end if
end if # <> RLPICFILE
add 1 to RLCOUNT
end repeat # NUMPICS
break
end switch
end menuPick
Although this is a big long script, nearly all the constructs are repeated over and over again, some nested inside others to achieve the desired actions, but mostly all are very simple, which is what programming and scripting are all about. They mainly consist of mundane testing and looping constructs, but the end result lets you create exciting programs like this one.
Apply this script and save the stack.
The last script to enter for this week is the one for the ZOOM image, so that you can click a thumbnail to zoom and click ZOOM to unzoom.
Code:
on mouseDown
set the filename of image "ZOOM" to empty
set the layer of image "ZOOM" to bottom
end mouseDown
Apply this script, save the stack, enter Browse Mode, load some picture files and click on the thumbnails to move them around, zoom and unzoom and clear the board. You won't be able to test functions which use Linux shell scripts in $HOME/SB/bin until they have been written. So you'll just have to wait until the next article won't ya.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.