|
Collecting User Preferences: Part 2 Hello and welcome to part 2 (of 2) of my newsletter article. You can read part 1 here. Please download the little example stack here, you will find everything discussed below in the stack scripts of the main- and the substack. Additionally to the things we already learned in the first article, we will learn how to manage preferences that are stored on different cards, converting multi line text to one line and converting binary data to one line text. I recommend that you check these terms in the Livecode dictionary for more information (this is a great place to learn more about terms you haven't met before): urlencode To check it out, you should open the example stack, go to the prefs, do some settings, import an image, close the prefs stack and then quit LiveCode without saving. When you open the stack the next time all your input is there as you left it! And as an extra bonus, we will also see how to write a generic script that will work for the current settings as well as for all controls that we might add in the future. The trick is to set a custom property of the controls whose content needs to be saved. In my example stack I named the custom property "saveme" (without the quotes) and set it to TRUE. This way we can simply loop through ALL objects on a card and will only handle controls that have this property set to true. If we try to query a custom property of an object that does not have this custom property at all, we do not get an error fortunately, and that is exactly what we need here. You can check this for yourself in the "Inspector" of the fields, buttons and images I use in my example. And doing so for your preferences is also pretty easy: And here is what's going on in the example stack: There are surely a lot more ways to make this possible but I choose this format:
1. Number of card ## We collect and store the prefs when the user closes the stack on closestack mk_collectprefs end closestack # This handler will collect all necessary prefs and pass them # to the function that will store them on the users HD command mk_collectprefs lock screen put empty into tAllPrefs ## Loop through all cards: repeat with i = 1 to the num of cds put the num of controls of cd i into tNumofcontrols ## Loop through all control on card: repeat with k = 1 to tNumofcontrols ## This work for ALL controls, even if we add more of # them later to our stack! ## As long as they have their custom property "saveme" # set to TRUE! if the saveme of control k of cd i <> true then next repeat end if ## Now we can collect the contents of the control ## Gives -> button "name of button" put the name of control k of cd i into tName put word 1 of tName into tType put word 2 of tName into tShortName ## Important step! replace QUOTE with empty in tShortName ## Now we need to differ: switch tType case "field" put empty into tStyle ## Now we need to URLENCODE the text, so we can store # it in ONE line! put urlencode(the text of fld tShortName of cd i) into \ tContent break ## No scrollbar in this example, but we take this into # account anyway! case "scrollbar" put the thumbpos of sb tShortName of cd i into tContent break case "button" ## Here we need to differ between Menubuttons like # option and combo boxes and radio buttons and checkboxes put the style of btn tShortname of cd i into tStyle switch tStyle case "radiobutton" case "checkbox" put the hilite of btn tShortname of cd i into tContent break case "menu" put the label of btn tShortname of cd i into tContent break end switch break case "image" put empty into tStyle ## Apparently the imagedata of an empty image is NOT # empty, ## so we need this little cumbersome check to see if # the image is REALLY empty: if the filename of img tShortName of cd i = empty AND \ the text of img tShortname of cd i = empty then put empty into tContent else ## Here we get the binary imagedata and convert it to # a ONE line string put the imagedata of img tShortName of cd i into \ tImageData ## Step 1: convert binary data to text data: put base64encode(tImageData) into tImageDataText ## Step 2: convert this string to ONE line: put urlencode(tImageDataText) into tContent end if ## Now we also need to save the rect of the image, # since setting the text of an image ## requires the image to have the SAME dimensions as # the source image! ## Otherwise we get visual GARBAGE :-) put TAB & the rect of img tShortName of cd i after \ tContent break end switch ## NOW we can prepare the list of the prefs to store ## We use this format here: ## Number of card TAB Type of control TAB Name of control # TAB Style of control (only neccessary for buttons!) TAB ## Content of control TAB Rect of control (only # neccessaryfor images!) put i & TAB & tType & TAB & tShortName & TAB & tStyle & \ TAB & tContent & CR after tAllPrefs ## End all controls end repeat ## End all cards end repeat ## Get rid of trailing CR delete char -1 of tAllPrefs ## Now we call the function that will store this to a text file put mk_setprefs(tAllPrefs) into tResult ## Better doublecheck! if tResult <> empty then answer "There was an error when saving the preferences!" & \ CR & tResult end if end mk_collectprefs Checking if the file was written successfully at the end of this script is of course optional, but keep in mind that the developers (WE!) are always blamed if something goes wrong, so its best to take care of everything that might go wrong! ;-) 2. Now we need handlers that collect the users input and pass it to the function mentioned above that will store the preferences to a file, take the stored info and "restore" the users input when the user opens that prefs stack the next time. They are located in the stack script of the substack "Preferences_sub". ## we collect and store the prefs when the user closes the stack on closestack mk_collectprefs end closestack ## This handler will collect all necessary prefs and pass them # to the function that will store them on the users HD command mk_collectprefs lock screen put empty into tAllPrefs ## Loop through all cards: repeat with i = 1 to the num of cds put the num of controls of cd i into tNumofcontrols ## Loop through all control on card: repeat with k = 1 to tNumofcontrols ## This work for ALL controls, even if we add more of # them later to our stack! ## As long as they have their custom property "saveme" # set to TRUE! if the saveme of control k of cd i <> true then next repeat end if ## Now we can collect the contents of the control ## Gives -> button "name of button" put the name of control k of cd i into tName put word 1 of tName into tType put word 2 of tName into tShortName ## Important step! replace QUOTE with empty in tShortName ## Now we need to differ: switch tType case "field" put empty into tStyle ## Now we need to URLENCODE the text, so we can store # it in ONE line! put urlencode(the text of fld tShortName of cd i) into \ tContent break ## No scrollbar in this example, but we take this into # account anyway! case "scrollbar" put the thumbpos of sb tShortName of cd i into tContent break case "button" ## Here we need to differ between menubuttons like # option and combo boxes and radio buttons and checkboxes put the style of btn tShortname of cd i into tStyle switch tStyle case "radiobutton" case "checkbox" put the hilite of btn tShortname of cd i into tContent break case "menu" put the label of btn tShortname of cd i into tContent break end switch break case "image" put empty into tStyle ## Apparently the imagedata of an empty image is NOT # empty, ## so we need this little cumbersome check to see if # the image is REALLY empty: if the filename of img tShortName of cd i = empty AND \ the text of img tShortname of cd i = empty then put empty into tContent else ## Here we get the binary imagedata and convert it to # a ONE line string put the imagedata of img tShortName of cd i into \ tImageData ## Step 1: convert binary data to text data: put base64encode(tImageData) into tImageDataText ## Step2: convert this string to ONE line: put urlencode(tImageDataText) into tContent end if ## Now we also need to save the rect of the image, # since setting the text of an image ## requires the image to have the SAME dimensions as # the source image! ## Otherwise we get GARBAGE :-) put TAB & the rect of img tShortName of cd i after \ tContent break end switch ## NOW we can prepare the list of the prefs to store ## We use this format here: ## Number of card TAB Type of control TAB Name of control # TAB Style of control (only neccessary for buttons!) TAB ## Content of control TAB Rect of control (only # neccessaryfor images!) put i & TAB & tType & TAB & tShortName & TAB & tStyle & \ TAB & tContent & CR after tAllPrefs ## End all controls end repeat ## End all cards end repeat ## Get rid of trailing CR delete char -1 of tAllPrefs ## Now we call the function that will store this to a text file put mk_setprefs(tAllPrefs) into tResult ## Better doublecheck! if tResult <> empty then answer "There was an error when saving the preferences!" & \ CR & tResult end if end mk_collectprefs Hint: Well, that's it basically. Have fun!
|
|