Hi Jim,
Below are some fixes and improvements.
I hope you find useful.
Below is Color Picker by UglyMike.
Do this: Run/Stop/Run/Stop/Run/Stop and look at the editor window.
For each COMPILE WARNING the editor window is scrolled to the warning line.
Implementation:
In Debug mode: It is useless to follow each warning in editor window because the editor window will go to line 1 after compiling.
In Run mode: Only the first COMPILE WARNING is followed by goToLine() to alow user to follow those in order of appearance.
print "Color Picker - Proof of concept for GUI program by M. Vilain" clg # Load graphical elements spritedim 3 spritepoly 0, {0,0,10,0,10,20,0,20} spritepoly 1, {0,0,10,0,10,20,0,20} spritepoly 2, {0,0,10,0,10,20,0,20} # Color background color grey rect 0,0,299,299 #color mixer # upper-left identation color darkgrey poly {10,10,10,180,210,10} poly {38,193,38,212,72,193} poly {98,193,98,212,132,193} poly {158,193,158,212,192,193} # lower-right identation color 200,200,200 poly {10,179,210,10,210,179} poly {38,213,72,193,72,213} poly {98,213,132,193,132,213} poly {158,213,192,193,192,213} # RGB canvas elements color black rect 13,13,195,164 rect 40,195, 30,15 rect 100,195, 30,15 rect 160,195, 30,15 #slider headers color red rect 218,5,20, 10 color green rect 244,5,20, 10 color blue rect 270,5,20, 10 # Place & show sliders color darkgrey rect 225,20, 4,270 rect 250,20, 4,270 rect 275,20, 4,270 color 200,200,200 rect 229,20, 4,270 rect 254,20, 4,270 rect 279,20, 4,270 color black line 229,20,229,287 line 228,20,228,287 line 254,20,254,287 line 253,20,253,287 line 279,20,279,287 line 278,20,278,287 spriteplace 0,230,27 spriteplace 1,255,27 spriteplace 2,280,27 spriteshow 0 spriteshow 1 spriteshow 2 #define counters for saving 10 colors nextcolor=0 nextrow=0 mclick=0 #draw color slots (2 rows of 5 elements) for i = 0 to 1 for j = 0 to 4 # upper-left identation color darkgrey poly {10+j*24,240+i*24,10+j*24, 264+i*24,34+j*24, 240+i*24} # lower-right identation color 190,190,190 poly {10+j*24,265+i*24,34+j*24, 240+i*24,34+j*24, 265+i*24} # RGB canvas elements color black rect 12+j*24,242+i*24,20,20 next j next i # Show Copy button color 200,200,200 poly {143,248, 143, 282,207 ,248} color darkgrey poly {143, 282,207 ,282,207,248} color grey rect 147, 251, 57,28 color black font "Tahoma",10,100 text 158,255,"Copy" # initialize color values rood=0 blauw=0 groen=0 #here the real work starts.... loop: # is the mouse on the red slider? if mousex > 220 and mousex < 240 then while mouseb=1 if mousey < 27 then place=27 else if mousey > 282 then place=282 else place=mousey rood=mousey-27 end if end if spriteplace 0,230,place pause 0.01 gosub drwcolor end while else # is the mouse on the blue slider? if mousex > 245 and mousex < 265 then while mouseb=1 if mousey < 27 then place=27 else if mousey > 282 then place=282 else place=mousey blauw=mousey-27 end if end if spriteplace 1,255,place pause 0.01 gosub drwcolor end while else # is the mouse on the green slider? if mousex > 270 and mousex < 290 then while mouseb=1 if mousey < 27 then place=27 else if mousey > 282 then place=282 else place=mousey groen=mousey-27 end if end if spriteplace 2,280,place pause 0.01 gosub drwcolor end while endif endif endif #did we click on the Copy button? if clickb=1 then if mousex > 143 and mousex < 208 then if mousey > 248 and mousey < 280 then mclick=1 # Show Copy button pressed color darkgrey poly {143,248, 143, 282,207 ,248} color 200,200,200 poly {143, 282,207 ,282,207,248} color grey rect 147, 251, 57,28 color black font "Tahoma",10,100 text 159,256,"Copy" color rood,blauw,groen rect 12+nextcolor*24,242+nextrow*24,20,20 nextcolor=nextcolor+1 if nextcolor=5 then if nextrow = 1 then nextcolor=0 nextrow=0 else nextcolor=0 nextrow=1 endif endif pause 0.2 end if endif endif clickclear if mclick=1 then # Show Copy button color 200,200,200 poly {143,248, 143, 282,207 ,248} color darkgrey poly {143, 282,207 ,282,207,248} color grey rect 147, 251, 57,28 color black font "Tahoma",10,100 text 158,255,"Copy" mclick=0 endif goto loop drwcolor: if rood > 255 then rood = 255 if groen > 255 then groen = 255 if blauw > 255 then blauw = 255 if rood < 0 then rood = 0 if groen < 0 then groen = 0 if blauw < 0 then blauw = 0 # individual color elements color rood,blauw,groen rect 13,13,195,164 color rood,0,0 rect 40,195, 30,15 color 0,blauw,0 rect 100,195, 30,15 color 0,0,groen rect 160,195, 30,15 #numeric representation color grey rect 39,213, 160,20 color black font "Tahoma",10,100 text 49,213,rood font "Tahoma",10,100 text 106,213,blauw font "Tahoma",10,100 text 166,213,groen return
Go to "Preferences" panel and set debugging speed to Fast (1 ms).
Run program above in debug mode. Now press Run to button.
Let it run for a while and try to stop it.
It will crash.
Implementation: fixed
Open and close preferences window and watch memory allocation. There is a lack of memory.
Implementation: fixed
Open preferences window but do not close it. Open another preferences window. You can open any number of preferences panels.
Implementation: fixed
Open preferences panel and do not close it.
Run a program.
Preferences window is still open...
Implementation: fixed
First: SETSETTING and GETSETTING are some of my favorites statements. Those simple statements allow for example to save the top scores for a game! :)
There was an option in Preferences panel: Allow GETSETTING/SETSETTING statements. If it was not checked the program stops in case of SETSETTING / GETSETTING statemets. So if you did not trust a program you could not even see what it was doing.
Ironically, to see what such a program does, the user had to give it access to these commands.
So I change this option to: Allow programs to use persistent settings (SETSETTING statement)
If it is unchecked then programs will set/get settings from a virtual/fake settings system. This is transparent for programs so no error message will be displayed. This allows programs to run normally, even if user do not want to let tracks or do not trust programs. All volatile settings will be accessible for entire session, so if user runs programs in the same session, then settings will remain accessible for other programs till the end of the BASIC256 session.
Add security levels for SETTINGS in Preference panel GETSETTING/SETSETTING access level
1) Full access (get/set) to settings. Program can set or get settings using different program names.
2) Get any settings / set only owned settings. Program can read any settings from any program but can set only for a single program name (first program name used by SETSETTING).
3) Get / set only owned settings. This is default option. Program can read/write settings for a single program (first program name used by SETSETTING/GETSETTING))
Two error messages have been added:
"The program does not have permission to read settings from other program. Check access level from 'Preferences' panel"
"The program does not have permission to write settings for other program. Check access level from 'Preferences' panel"
Add option Max number of settings for each program so user can limit the number of keys that a program can save (to avoid abuse). The default limit is 100 keys (which is quite enough).
Add a new button Clear all persistent settings to clear all saved pesistent settings.
Add Browse persistent settings button which launches a nice browser to browse/delete persistent settings
1) Program name and key name cannot be empty anymore.
2) The Windows system registry has the following limitations: A subkey may not exceed 255 characters, an entry's value may not exceed 16,383 characters. So, program name and key name for settings may not exceed 255 characters. Also saved value may not exceed 16,383 characters to fit Windows limitations.
3) Slashes ('/' and '\') are forbidden in program name or key names to avoid creating subgroups (On windows '\' are converted by QSettings to '/', which makes them identical).
The only place that slash is allowed is when user read a BASIC256 setting:
print getsetting("SYSTEM", "Main/Font")
4) Program name "SYSTEM" is reserved for getting BASIC256 settings and it is forbidden to be used with SETSETTING.
Because BASIC256 settings are read-only, user cannot use SETSETTING to change those settings. So SETSETTING "SYSTEM", "key", "value" will not work anymore because settings saved in this way could not be read anyway.
If you run program below in previous version you will get empty value every time because SETSETTING is actually save key value for a program named "SYSTEM" and GETSETTING read BASIC256 system key instead of saved key.
setsetting "SYSTEM", "key", "value" print getsetting("SYSTEM", "key")
5) Now it's possible for the user to delete a key by setting value to an empty one.
setsetting "myprog", "mykey", "blabla" print getsetting("myprog", "mykey") setsetting "myprog", "mykey", "" #delete key print getsetting("myprog", "mykey")
6) Safe password
If you run this program you can get the MD5 password
print getsetting("SYSTEM", "Pref/Password/")
But this is wrong because MD5 can be broken. For example, if I set a password even a beginner user can get the hash (202cb962ac59075b964b07152d234b70) and he can find easy the password on web. Try it: https://crackstation.net/
Implementation: User receive a fake password "****" when try to read it and an empty one if there is no password set.
setsetting program_name, setting_key_name, string_expression
setsetting ( program_name, setting_key_name, string_expression )
Save a string_expression to the system registry (or other persistent storage). The program_name and setting_key_name are used to categorize and to make sure that settings accessed when needed and not accidentally changed by another program.
If "Allow programs to use persistent settings (SETSETTING statement)" option from 'Preferences' panel is checked, then the saved value will be available to other BASIC-256 programs and should remain available for an extended period. Otherwise saved values will be avaiable only for current BASIC256 session (till BASIC256 is closed). After this those settings will be lost.
Rules for names:
Program name and key name cannot be empty.
Program name and key name may not exceed 255 characters.
Do not use slashes ('/' and '\') in program name or key names.
Program name "SYSTEM" is reserved for getting BASIC256 settings. BASIC256 settings are read-only so user cannot use SETSETTING to change those settings. This is possible only from 'Preferences' panel.
Failure to comply with any of the above rules will generate an error message: "Invalid program name" or "Invalid key name".
Also string_expression may not exceed 16,383 characters.
If string_expression is empty, the setting_key_name will be removed.
setsetting "thisprogram", "testsetting", "value of setting" print getsetting("thisprogram", "testsetting")
will print
value of setting
getsetting ( program_name, setting_key_name )
returns string_expression
Retrieve a setting from the system registry (or other persistent storage). The program_name and setting_key_name are required by this function to access a previously saved setting. The empty string “” will be returned if the requested setting has not been previously set.
The saved value will be available to other BASIC-256 programs and should remain available for an extended period.
Program name "SYSTEM" is reserved for getting BASIC256 settings. BASIC256 settings are read-only so
setsetting "thisprogram", "testsetting", "value of setting" print getsetting("thisprogram", "testsetting")
will print
value of setting
To retreive a BASIC256 setting "SYSTEM" should be used as a program name. In this case slashes are allowed in key name to acces the desired setting.
print getsetting("SYSTEM", "Main/Font")
Run this program above. It will launch the calculator program.
system "calc"
Now try to stop the program. GUI is not responding.
Implementation: fixed
Run this program above. It will launch the calculator program.
system "calc"
Now wait 30 seconds. Any external program lounched will be closed after 30 seconds.
Implementation: fixed
There are 3 options in Preferences panel for running system commands:
1) Do not allow - program stops and throw error: "You do not have permission to use this statement/function."
2) Ask confirmation from user - program waits for user confirmation
3) Allow - program will run any system commands
Yes - program run external command
No - program stops and throw error: "You do not have permission to use this statement/function."
Ignore - program do not run external command and continue to run without error
Checkbox [ ] Do not ask me again - remembers user choice till the end of program
If command line is too long, the confirmation dialog will show a new button: Show Details... to view the entire command.
system "mshta "+'"'+"javascript:var sh=new ActiveXObject( 'WScript.Shell' ); sh.Popup( 'Message!', 10, 'Title!', 64 );close()"+'"'
There are 3 options in Preferences panel for allowing PORTIN/PORTOUT statements:
1) Do not allow - program stops and throw error: "You do not have permission to use this statement/function." when encounters PORTIN/PORTOUT statements.
2) Ask confirmation from user - program waits for user confirmation
3) Allow - program will execute any PORTIN/PORTOUT statements
Yes - program run statement
No - program stops and throw error: "You do not have permission to use this statement/function."
Ignore - program will ignore PORTIN/PORTOUT statement and continue to run without error. For PORTIN the received value will be 0
Checkbox [ ] Do not ask me again - remembers user choice till the end of program
# this program shows the content of your CMOS - Florin Oprea # check http://www.bioscentral.com/misc/cmosmap.htm loop: s="" for a=0 to 127 portout(0x70, a|0x80) x=portin(0x71) h=tohex(x) if length(h)=1 then h="0";h s=s;h next a cls print s goto loop end
or
# this program shows the time and date of your CMOS - Florin Oprea # check http://www.bioscentral.com/misc/cmosmap.htm loop: cls print "CMOS time (hh:mm:ss): ";getCMOS(4);":";getCMOS(2);":";getCMOS(0) print "CMOS date (dd-mm-yy): ";getCMOS(7);"-";getCMOS(8);"-";getCMOS(9) pause 1 goto loop function getCMOS(reg) portout(0x70, reg|0x80) x=portin(0x71) h=tohex(x) if length(h)=1 then h="0";h return h end function
Run this program:
print 1 print a print 2
Program do not go to line 2 on error.
Implementation: Fixed
Run a program in debug mode as:
loop: goto loop
Press Run to button. Now user cannot return to step by step debug mode if there is no break point.
I find very usefull to let Step button enabled to return to step by step mode any time.
Several settings are read at the beginning of the program run, avoiding reading every time.
imageautocrop will autocrop the specified image to contend by cutting the transparent part around it. You can specify a desired color to be used in which case the image is cut to the content, ignoring the color around it. Remember that imageautocrop(img) is not the same as imageautocrop(img,clear). The first statement will reduce the size of image if full transparent colors are found around it. The second statement imageautocrop(img,clear) will cut ONLY if the pixels are 0. (SEE EXAMPLE BELOW)
This is a quote from https://sourceforge.net/p/kidbasic/patches/45/
So, imageautocrop(img) will cut ANY transparent pixels. Those transparent pixels can have any values but with alpha chanel full transparent (0x00000000, 0x00FFFFFF, 0x007A4E22, so on...)
imageautocrop(img,color) will cut pixels with value EQUAL to color. So, imageautocrop(img,CLEAR) will cut only 0x00000000 pixels and not all transparent pixels.
Respectfully,
Florin Oprea