Image Objects Update

I had previously discussed the use of Image Objects in 3d Web Pages

This posts has several updates:

An app to generate the pages is included.
I have included animated gif images in as both background and objects.
The objects can be rotated.

Here is an example of a page created with the app

Click Image for larger view

XCountry

Notice that the object is used twice, each time at a different rotation.

Here is the code for the app:

<!DOCTYPE html PUBLIC ‘-//W3C//DTD XHTML 1.0 Transitional//EN’ ‘http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd’&gt;
<html xmlns=’http://www.w3.org/1999/xhtml’&gt;
<head profile=’http://gmpg.org/xfn/11′&gt;
<title>Enter Title Here</title>
<style type=’text/css’>
body {margin-left:0;margin-right:0;font:normal normal normal 12px Arial; }
a{ text-decoration: }
:link { color: rgb(0, 0, 255) }
:visited {color :rgb(100, 0,100) }
:hover { }
:active { }
#i2,#i3,#i4{position: absolute}
#i1{position: relative}
input{width: 60px}
#files{width: 200px}
#sav{position: absolute; width: 100%; height: 100%; top: 0; visibility: hidden; background: #EEEEEE; padding: 5px}
</style>
</head>
<body>
<center>Choose Image <input type=”file” id=”files” name=”files” /> <button name=”b1″ value=”” onclick=’rot();’>Load</button> <input type=”text” id=”t1″ name=”t1″ value=”Left” ondblclick=’clearInterval(si);’/> <input type=”text” id=”t2″ name=”t2″ value=”Height” /> <input type=”text” id=”t3″ name=”t3″ value=”Top” /> <input type=”text” id=”t4″ name=”t4″ value=”Rotate” /> Folder<select id = “s1″ name=”s1″><option></option><option>file://D:/My Pictures/</option><option>file://D:/My Pictures/threed/</option><option>file://D:/My Pictures/Animated GIF/</option></select> <input type=”button” id=”b2″ name=”b2″ value=”Redo” onclick=’clearInterval(si); redo();’ /> <input type=”button” id=”b3″ name=”b3″ value=”Save” onclick=’save();’ /><br />
<di id=”frame” style=”width: 1100px; height: 570px; background: black”></di></center><textarea id=”sav”name=”sav” rows=”rows” cols=”columns”></textarea>

var j = -1; var cnt = 0; var img; var img2; var si; var ratio; var img3; var img4; var done = false; var fl = “”; var im1; var im2; var im3; var im4; var si; var r2 = 0; var r3 = 0; var r4 = 0; var rt2 = false; var rt3 = false; var rt4 = false; var si;function save() {
var r2b = r2 – 5; var r3b = r3 – 7; var r4b = r4 – 9; var r2c = r2 – 10; var r3c = r3 – 12; var r4c = r4 – 14;
var ta = document.getElementById(“sav”);
ta.value = ‘3dImage\n\nbody {margin-left:0;margin-right:0;font:normal normal normal 12px Arial; }\n#i2,#i3,#i4{position: absolute}\n#i1{position:relative}\n\n\n\n
\n\n\n ‘;
ta.value += ‘var imga; var j = -1; var imgb; var imgc; var imgd; var cnt2 =’ + cnt + ‘;\n’;
ta.value += ‘document.getElementById(“frame2″).innerHTML = \” + im1 + ‘\’;\n’;
ta.value += ‘imga = document.getElementById(“i1”);\n’;
if (img.style.width > img.style.height) {
ta.value += ‘imga.style.width = “‘ + img.style.width + ‘”;\n’;
} else {
ta.value += ‘imga.style.height = “‘ + img.style.height + ‘”;\n’;
}
ta.value += ‘document.getElementById(“frame2″).innerHTML += \” + im2 + ‘\’;\n’;
ta.value += ‘imgb = document.getElementById(“i2”);\n’;
ta.value += ‘imgb.style.left = “‘ + img2.style.left + ‘”;\nimgb.style.height = “‘ + img2.style.height + ‘”;\nimgb.style.top = “‘ + img2.style.top + ‘”;\n ‘;
if (cnt > 2) {
ta.value += ‘document.getElementById(“frame2″).innerHTML += \” + im3 + ‘\’;\n’;
ta.value += ‘imgc = document.getElementById(“i3”);\n’;
ta.value += ‘imgc.style.left = “‘ + img3.style.left + ‘”;\nimgc.style.height = “‘ + img3.style.height + ‘”;\nimgc.style.top = “‘ + img3.style.top + ‘”;\n ‘;
}
if (cnt == 4) {
ta.value += ‘document.getElementById(“frame2″).innerHTML += \” + im4 + ‘\’;\n’;
ta.value += ‘imgd = document.getElementById(“i4”);\n’;
ta.value += ‘imgd.style.left = “‘ + img4.style.left + ‘”;\nimgd.style.height = “‘ + img4.style.height + ‘”;\nimgd.style.top = “‘ + img4.style.top + ‘”;\n ‘;
}
ta.value += ‘si = setInterval(“rot2()”, 40);\n’;ta.value += ‘function rot2() {\nj++;\nimga = document.getElementById(“i1”);\nimgb = document.getElementById(“i2”);\n’;
if (cnt == 3 || cnt == 4) ta.value += ‘imgc = document.getElementById(“i3”);\n’;
if (cnt == 4) ta.value += ‘imgd = document.getElementById(“i4″);\n’;
ta.value += ‘if (j==0) {\nimga.style.transform=”rotateY(4deg)”;\nimgb.style.transform=”rotateY(‘ + r2 + ‘deg)”;\nif (cnt2 == 3 || cnt2 == 4) imgc.style.transform=”rotateY(‘ + r3 + ‘deg)”;\nif (cnt2 == 4) imgd.style.transform=”rotateY(‘ + r4 + ‘deg)”;\n}\nif (j==1) {\nimga.style.transform=”rotateY(7deg)”;\nimgb.style.transform=”rotateY(‘ + r2b + ‘deg)”;\nif (cnt2 == 3 || cnt2 == 4) imgc.style.transform=”rotateY(‘ + r3b + ‘deg)”;\nif (cnt2 == 4)\nimgd.style.transform=”rotateY(‘ + r4b + ‘deg)”;\n}\nif (j==2) {\nimga.style.transform=”rotateY(10deg)”;\nimgb.style.transform=”rotateY(‘ + r2c + ‘deg)”;\nif (cnt2 == 3 || cnt2 == 4) imgc.style.transform=”rotateY(‘ + r3c + ‘deg)”;\nif (cnt2 == 4)\nimgd.style.transform=”rotateY(‘ + r4c + ‘deg)”;\n}\nif (j==3) {\nimga.style.transform=”rotateY(7deg)”;\nimgb.style.transform=”rotateY(‘ + r2b + ‘deg)”;\nif (cnt2 == 3 || cnt2 == 4) imgc.style.transform=”rotateY(‘ + r3b + ‘deg)”;\nif (cnt2 == 4)\nimgd.style.transform=”rotateY(‘ + r4b + ‘deg)”;\nj = -1;\n}\n\n}\n’;ta.value += ”;
ta.style.visibility=”visible”;
}

function redo() {
clearInterval(si);
cnt –;
alert(“Make Change”);
done = true;
if (cnt == 1) rt2 = false;
if (cnt == 2 || cnt == 3) rt3 = false;
if (cnt == 4) rt4 = false;
j = -1;
}

function rot() {
if (document.getElementById(“s1”).value != “”) {
document.getElementById(“s1″).style.backgroundColor=”yellow”;
} else {
document.getElementById(“s1″).style.backgroundColor=”white”;
}
cnt++;
var fil = document.getElementById(“files”).value;
if (fil == fl && cnt == 2 && ! done) {
alert(“choose an Object”);
cnt –;
}
fl = fil;
if (fil.indexOf(“fake”) > -1) fil = fil.substr(12, fl.length – 12);
if (cnt == 1) {
document.getElementById(“frame”).innerHTML = ‘‘;
im1= ‘‘;
img = document.getElementById(“i1”);
alert(“loading”);
if (i1.clientWidth/i1.clientHeight ‘;
im2 = ‘‘;
}
img = document.getElementById(“i1”);
img2 = document.getElementById(“i2”);
alert(“loading”);
img2.style.left = document.getElementById(“t1”).value + “%”;
img2.style.height = ((document.getElementById(“t2”).value/85) * img.clientHeight) + “px”;
if (document.getElementById(“t3”).value != “Top”) {
img2.style.top = document.getElementById(“t3”).value + “%”;
document.getElementById(“t3”).style.backgroundColor = “yellow”;
} else {
img2.style.top = ((img.clientHeight – img2.clientHeight) / 2 + 50 ) + “px”;
}
} else if (cnt == 3) {
if (! done) {
document.getElementById(“frame”).innerHTML += ‘‘;
im3 = ‘‘;
}
img = document.getElementById(“i1”);
img2 = document.getElementById(“i2”);
img3 = document.getElementById(“i3”);
alert(“loading”);
img3.style.left = document.getElementById(“t1”).value + “%”;
img3.style.height = ((document.getElementById(“t2”).value/85) * img.clientHeight) + “px”;
if (document.getElementById(“t3”).value != “Top”) {
img3.style.top = document.getElementById(“t3”).value + “%”;
document.getElementById(“t3”).style.backgroundColor = “yellow”;
} else {
img3.style.top = ((img.clientHeight – img3.clientHeight) / 2 + 50 ) + “px”;
}
} else if (cnt == 4) {
if (! done) {
document.getElementById(“frame”).innerHTML += ‘‘;
im4 = ‘‘;
}
img = document.getElementById(“i1”);
img2 = document.getElementById(“i2”);
img3 = document.getElementById(“i3”);
img4 = document.getElementById(“i4”);
alert(“loading”);
img4.style.left = document.getElementById(“t1”).value + “%”;
img4.style.height = ((document.getElementById(“t2”).value/85) * img.clientHeight) + “px”;
if (document.getElementById(“t3”).value != “Top”) {
img4.style.top = document.getElementById(“t3”).value + “%”;
document.getElementById(“t3”).style.backgroundColor = “yellow”;
} else {
img4.style.top = ((img.clientHeight – img4.clientHeight) / 2 + 50 ) + “px”;
}
}
if (cnt > 1) si = setInterval(“rot2()”, 40);
done = false;
if (document.getElementById(“t4”).value != “Rotate”) document.getElementById(“t4”).style.backgroundColor = “yellow”;
}

function rot2() {
j++;

if (j==-0) {
img.style.transform=”rotateY(4deg)”;
if (document.getElementById(“t4”).value != “Rotate” && ! rt2) {
r2 = parseInt(document.getElementById(“t4″).value);
img2.style.transform=”rotateY(” + r2 + “deg)”;
rt2 = true;
}
if (cnt == 3 || cnt == 4) {
if (document.getElementById(“t4”).value != “Rotate” && ! rt3) {
r3 = parseInt(document.getElementById(“t4″).value);
img3.style.transform=”rotateY(” + r3 + “deg)”;
rt3 = true;
}
}
if (cnt == 4) {
if (document.getElementById(“t4”).value != “Rotate” && ! rt4) {
r4 = parseInt(document.getElementById(“t4″).value);
img4.style.transform=”rotateY(” + r4 + “deg)”;
rt4 = true;
}
}
}

if (j==-1) {
img.style.transform=”rotateY(4deg)”;
if (document.getElementById(“t4”).value != “Rotate” && ! rt2) {
r2 = parseInt(document.getElementById(“t4″).value) – 5;
img2.style.transform=”rotateY(” + r2 + “deg)”;
}
if (cnt == 3|| cnt == 4) {
alert(rt2);
if (document.getElementById(“t4”).value != “Rotate” && ! rt3) {
r3 = parseInt(document.getElementById(“t4″).value – 7);
img3.style.transform=”rotateY(” + r3 + “deg)”;
}
}
if (cnt == 4) {
if (document.getElementById(“t4”).value != “Rotate” && ! rt4) {
r4 = parseInt(document.getElementById(“t4″).value – 9);
img4.style.transform=”rotateY(” + r4 + “deg)”;
}
}
}

if (j==2) {
img.style.transform=”rotateY(9deg)”;
if (document.getElementById(“t4”).value != “Rotate” && ! rt2) {
r2 = parseInt(document.getElementById(“t4″).value) – 10;
img2.style.transform=”rotateY(” + r2 + “deg)”;
}

if (cnt == 3 || cnt == 3) {
if (document.getElementById(“t4”).value != “Rotate” && ! rt3) {
r3 = parseInt(document.getElementById(“t4″).value) – 12;
img3.style.transform=”rotateY(” + r3 + “deg)”;
}
}

if (cnt == 4) {
if (document.getElementById(“t4”).value != “Rotate” && ! rt4) {
r4= parseInt(document.getElementById(“t4″).value) – 14;
img4.style.transform=”rotateY(” + r4 + “deg)”;
}
}
}

if (j==3) {
img.style.transform=”rotateY(7deg)”;
if (document.getElementById(“t4”).value != “Rotate” && ! rt2) {
r2 = parseInt(document.getElementById(“t4″).value) – 5;
img2.style.transform=”rotateY(” + r2 + “deg)”;
}
if (cnt == 3|| cnt == 4) {
if (document.getElementById(“t4”).value != “Rotate” && ! rt3) {
r3 = parseInt(document.getElementById(“t4″).value) – 7;
img3.style.transform=”rotateY(” + r3 + “deg)”;
}
}
if (cnt == 4) {
if (document.getElementById(“t4”).value != “Rotate” && ! rt4) {
r4 = parseInt(document.getElementById(“t4″).value) – 9;
img4.style.transform=”rotateY(” + r4 + “deg)”;
}
}
j = -1;
}

}

</body></html>

To use, first load the background image by choosing it with the File box  and  clicking Load.

It is best to have all images in the same folder as the app, as no path is required in that case. I you want to use a file from another folder, the path must be added to the select box and chosen before using the File box.

Next, the first object must be chosen. Before loading, the left and height must be entered in the text boxes; top and rotation are optional. There is a default top which approximately centers the object vertically, and the default rotation is 0.

If not satisfied click Redo.

With each of the Load button, a variable named cnt is incremented. The background and each object correspond to a value of cnt.

When Redo is clicked, the value  of cnt is deceased, so on clicking Load after making changes,  it is increased to its previous value so the changes are made to the current object.

After clicking Load, the effect is immediately apparent.

After being satisfied with the first object, up to two more objects can be added, using either the same or different images.

Here is how the interface appears:

Click Image for larger view

wob3-interface

When satisfied with the scene, click save and a hidden textarea is made visible, with generated code.

A couple of changes must be made before the code can be saved. The two script tags required a space after the opening bracket. These spaces must be removed. Once that is done, the text can be copied, pasted into a text editor and saved as a html file.

Here is the code generated for the viewed example:

<html><head><title>3dImage</title>
<style>
body {margin-left:0;margin-right:0;font:normal normal normal 12px Arial; }
#i2,#i3,#i4{position: absolute}
#i1{position:relative}
</style>
</head>
<body>
<br />
<center>

</center>var imga; var j = -1; var imgb; var imgc; var imgd; var cnt2 =3;
document.getElementById(“frame2”).innerHTML = ‘‘;
imga = document.getElementById(“i1”);
imga.style.width = “1060px”;
document.getElementById(“frame2”).innerHTML += ‘‘;
imgb = document.getElementById(“i2”);
imgb.style.left = “55%”;
imgb.style.height = “217.059px”;
imgb.style.top = “15%”;
document.getElementById(“frame2”).innerHTML += ‘‘;
imgc = document.getElementById(“i3”);
imgc.style.left = “38%”;
imgc.style.height = “337.647px”;
imgc.style.top = “15%”;
si = setInterval(“rot2()”, 40);
function rot2() {
j++;
imga = document.getElementById(“i1”);
imgb = document.getElementById(“i2”);
imgc = document.getElementById(“i3″);
if (j==0) {
imga.style.transform=”rotateY(4deg)”;
imgb.style.transform=”rotateY(35deg)”;
if (cnt2 == 3 || cnt2 == 4) imgc.style.transform=”rotateY(160deg)”;
if (cnt2 == 4) imgd.style.transform=”rotateY(0deg)”;
}
if (j==1) {
imga.style.transform=”rotateY(7deg)”;
imgb.style.transform=”rotateY(30deg)”;
if (cnt2 == 3 || cnt2 == 4) imgc.style.transform=”rotateY(153deg)”;
if (cnt2 == 4)
imgd.style.transform=”rotateY(-9deg)”;
}
if (j==2) {
imga.style.transform=”rotateY(10deg)”;
imgb.style.transform=”rotateY(25deg)”;
if (cnt2 == 3 || cnt2 == 4) imgc.style.transform=”rotateY(148deg)”;
if (cnt2 == 4)
imgd.style.transform=”rotateY(-14deg)”;
}
if (j==3) {
imga.style.transform=”rotateY(7deg)”;
imgb.style.transform=”rotateY(30deg)”;
if (cnt2 == 3 || cnt2 == 4) imgc.style.transform=”rotateY(153deg)”;
if (cnt2 == 4)
imgd.style.transform=”rotateY(-9deg)”;
j = -1;
}}
</body></html>
 

To get this page to appear properly, I had to change div to di, so add the v if you want to use the code.

A HTML Pulse Measuring App

This is a simple app that provides an accurate method for determining one’s pulse rate, and can be run either on a computer or mobile device, although I think it is better on a mobile device, particularly a phone.

The interface consists of a button and a text box.

Clicking the “Start” button initiates a timer and changres the label to “Stop”.

You then count 10 heartbeats and click the button again.

The text box will give you a reading of your pulse. I tried this app on my phone and then manually counted heartbeats for sixty seconds and got the same value. It is better than counting for 10 seconds and multiplying by 6, as the latter method only gives values to the nearest multiple of 6.

After clicking the button a second time, it is ready for another reading, as another click resets everything.

Here is how a reading looks in an image captured from a phone screen:

Click Image for larger view

pulse

Here is the code:

<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'&gt;
<html xmlns='http://www.w3.org/1999/xhtml'&gt;
<head profile='http://gmpg.org/xfn/11'&gt;
<title>Pulse</title>
<style>
body {margin-left:0;margin-right:0;font:normal normal normal 15pt Arial; background: #FFDD99}a{ text-decoration: }:link { color: rgb(0, 0, 255) }:visited {color :rgb(100, 0,100) }:hover { }:active { } #b1{position: relative; width: 300px; height: 200px; background: #22AA22; text-shadow: 5px 5px 5px #000000; color : white; font: normal normal 800 64pt Arial} #t1{font: normal normal 800 15pt Arial}
</style>
</head>
<body>
<center><input type=”button” id=”b1″ name=”b1″ value=”Start” onclick=’run();’ /></center><br />
<center><input type=”text” id=”t1″ name=”t1″ value=”0″ /></center>
var then; var now;
function run() {
document.getElementById(“t1”).value = “0”;
if (document.getElementById(“b1”).value == “Start”) {
then = new Date();
document.getElementById(“b1”).value = “Stop”;
} else {
now = new Date();
var pulse = Math.floor(600000/(now – then));
document.getElementById(“t1”).value = pulse;
document.getElementById(“b1”).value = “Start”;
}
}

</body>
</html>

 

Clicking the button a first time calls the Date() function and places the output in the then variable.

The second click places the new Date() in the now variable.

The equation Math.floor(600000/(now – then)) calculates the pulse rate and places it in the pulse variable, which is displayed in the text box.

An Android Finance App

I generally prefer writing apps to be run in a browser, making them more cross-platform; my Javascript Calculator runs fine on my phone as well as my laptops. However, for the fun of it, I wrote a few android apps, using Eclipse. This is one of them.

It is a finance app, calculating compond interest, mortgages, annuities and depreciation.

Here is how the interface looks, in an image captured from the screen of my phone:

Click Image for larger view

android-interface

Here is how an interest calculation looks:

Click Image for larger view:

calc

Here is the java source:

package android.finance;

import android.finance.R;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.Toast;

public class finance extends Activity {
public EditText text;
public EditText text2;
public EditText text3;
public EditText text4;
public RadioButton mortgageButton;
public RadioButton annuityButton;
public RadioButton interestButton;
public RadioButton depreciationButton;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (EditText) findViewById(R.id.editText1);
text2 = (EditText) findViewById(R.id.editText2);
text3 = (EditText) findViewById(R.id.editText3);
text4 = (EditText) findViewById(R.id.editText4);
mortgageButton = (RadioButton) findViewById(R.id.radio0);
annuityButton = (RadioButton) findViewById(R.id.radio1);
interestButton = (RadioButton) findViewById(R.id.radio2);
depreciationButton = (RadioButton) findViewById(R.id.radio3);

}
public void clear(View view) {
switch (view.getId()) {
case R.id.button2:
text.setText(“”);
text2.setText(“Principal”);

if (depreciationButton.isChecked()) {
text3.setText(“Years”);
} else {
text3.setText(“Interest”);
}

if (depreciationButton.isChecked()) {
text4.setText(“Current Year”);
} else {
text4.setText(“Time in Months”);
}
break;
case R.id.radio3:
text.setText(“”);
text2.setText(“Principal”);
text3.setText(“Years”);
text4.setText(“Current Year”);
break;
case R.id.radio0:
text.setText(“”);
text2.setText(“Principal”);
text3.setText(“Interest”);
text4.setText(“Time in Months”);
break;
case R.id.radio1:
text.setText(“”);
text2.setText(“Principal”);
text3.setText(“Interest”);
text4.setText(“Time in Months”);
break;
case R.id.radio2:
text.setText(“”);
text2.setText(“Principal”);
text3.setText(“Interest”);
text4.setText(“Time in Months”);
break;
}
}

// This method is called at button click because we assigned the name to the
// “On Click property” of the button
public void calc(View view) {
switch (view.getId()) {
case R.id.button1:
if (text2.getText().length() == 0 || text3.getText().length() == 0 || text4.getText().length() == 0) {
Toast.makeText(this, “Please enter a valid number”,
Toast.LENGTH_LONG).show();
return;
}
double inputValue1 = Double.parseDouble(text2.getText().toString());
double inputValue2 = Double.parseDouble(text3.getText().toString());
double inputValue3 = Double.parseDouble(text4.getText().toString());
if (mortgageButton.isChecked()) {
text.setText(String.valueOf(calcMortgage(inputValue1, inputValue2, inputValue3)));
} else if (annuityButton.isChecked()) {
text.setText(String.valueOf(calcAnnuity(inputValue1, inputValue2, inputValue3)));
} else if (interestButton.isChecked()){
text.setText(String.valueOf(calcInterest(inputValue1, inputValue2, inputValue3)));
}
else if (depreciationButton.isChecked()){
text3.setText(“Years”);
text4.setText(“Current Year”);
text.setText(String.valueOf(calcDepreciation(inputValue1, inputValue2, inputValue3)));
}
break;
}
}
private double calcMortgage(double principal, double interest, double months) {
interest = interest / 1200;
double myNum = principal / (( Math.pow((1 + interest) , -months) – 1) / interest);
int precision = 100; //keep 4 digits
myNum= Math.floor(myNum * precision +.5)/precision;
return (myNum);
}

private double calcAnnuity(double principal, double interest, double months) {
interest = interest / 1200;
double myNum = ((Math.pow(1+interest, months) -1) /interest) * principal;
int precision = 100; //keep 4 digits
myNum= Math.floor(myNum * precision +.5)/precision;
return (myNum);
}

private double calcInterest(double principal, double interest, double months) {
interest = interest / 1200;
for (int i = 1; i <= months; i ++) {
double in = interest * principal;
principal += in;
}

double myNum = principal;
int precision = 100; //keep 4 digits
myNum= Math.floor(myNum * precision +.5)/precision;
return (myNum);
}

private double calcDepreciation(double principal, double years, double year) {

double intrate = 0; double interest = 0;
double prin = principal;
while (prin > 0.1 * principal) {
intrate += 0.000001;

for (int i = 1;i <=years;i++) {
interest = intrate * prin;
prin -= interest;
if (prin <= 0.1 * principal) break;
}

if (prin > 0.1 * principal) {
prin = principal;
interest = 0;
}

}
prin = principal;
for (int j = 1; j <=year; j++) {
interest = intrate * prin;
prin -= interest;

}
double myNum = interest;
int precision = 100;
myNum= Math.floor(myNum * precision +.5)/precision;
return (myNum);
}

}

and here is the resource java file:

/* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/package android.finance;

public final class R {
public static final class attr {
}
public static final class color {
public static final int background=0x7f050000;
}
public static final class drawable {
public static final int icon=0x7f020000;
}
public static final class id {
public static final int button1=0x7f060009;
public static final int button2=0x7f06000a;
public static final int editText1=0x7f060000;
public static final int editText2=0x7f060001;
public static final int editText3=0x7f060002;
public static final int editText4=0x7f060003;
public static final int radio0=0x7f060005;
public static final int radio1=0x7f060006;
public static final int radio2=0x7f060007;
public static final int radio3=0x7f060008;
public static final int radioGroup1=0x7f060004;
}
public static final class layout {
public static final int main=0x7f030000;
}
public static final class string {
public static final int annuity=0x7f040004;
public static final int app_name=0x7f040001;
public static final int depreciation=0x7f040006;
public static final int hello=0x7f040000;
public static final int interest=0x7f040005;
public static final int mortgage=0x7f040003;
public static final int myClickEvent=0x7f040002;
}
}

An Interactive Celestia Planetarium Script

Celestia has two kinds of scripts. cel files give a fixed automation, such as a tour of the solar system. celx files can do that plus allow interaction. This post will discuss a celx file that I wrote. Here is how the screen looks on opening the script:

Click image for larger view

Celes1

A menu appears to allow choosing functions by means of typing a letter or number. In this example I chose to view Earth from a specific location. Hitting enter showed a new menu where I could choose from a number of cities;

Click Image for larger view

Celes-loc

I chose Nairobi, #16. There is then a choice to view the Earth looking at Nairobi, or view the sky from Nairobi. This is how Earth looks from space, pointing toward Nairobi:

Click Image for larger view

Celes-Nairobi

This is how the night sky looks from Nairobi:

Nairobi-sky

Click image for larger view

Clicking q and hitting Enter will bring back the main menu.

By choosing Object from the main menu you get a prompt to enter the object name. Entering Jupiter and resetting the distance to 100000 km above the surface gives the following image:

Click image for larger view

Celes-Jup

Other options in the main menu include changing the position of the object, looking at the night shy from the object position, changing the time rate, changing the date and changing the field of view.

Here is the code:

celestia:show(“orbits”)
celestia:show(“planets”)
celestia:show(“stars”)
celestia:show(“galaxies”)
celestia:showlabel(“planets”)
celestia:showlabel(“moons”)
celestia:show(“moons”)
celestia:show(“constellations”)
celestia:showlabel(“constellations”)
celestia:setfaintestvisible(6)
Sol = celestia:find(“Sol”)
Mercury = celestia:find(“Sol/Mercury”)
Venus = celestia:find(“Sol/Venus”)
Moon = celestia:find(“Sol/Earth/Moon”)
Mars = celestia:find(“Sol/Mars”)
Jupiter = celestia:find(“Sol/Jupiter”)
Saturn = celestia:find(“Sol/Saturn”)
Uranus = celestia:find(“Sol/Uranus”)
Neptune = celestia:find(“Sol/Neptune”)
Pluto = celestia:find(“Sol/Pluto”)
Hubble = celestia:find(“Hubble”)
Earth = celestia:find(“Sol/Earth”)
celestia:select(Earth)
celestia:getobserver():setfov(math.rad(27))
fov = 27
celestia:settimescale(10)
obj  = Earth
lt = 0
lng = 0
dist2 = 31000function getChar(char)
userKeypress = char
return true  — Tell Celestia we will handle this keypress
endfunction getUserInput(prompt)
local inputLine = “”

userKeypress = “”                        — Clear the userKeypress var
celestia:requestkeyboard(true)           — Enable keyboard input

while true do                            — Loop until we get Enter key
— Display the prompt…
if prompt ~= nil then
celestia:print(prompt .. inputLine, 100, -1, -1, 1, 22)
else
celestia:print(inputLine, 100, -1, -1, 1, 22)
end
wait(0.01)

— What key did the user press…
if userKeypress == “\013” then      — Enter key, we’re done
break

elseif userKeypress == “\008” then  — Backspace key, remove last char
local strlen = string.len(inputLine)
if strlen <= 1 then
inputLine = “”
else
inputLine = string.sub(inputLine, 1, strlen – 1)
end

else  — Add the character to inputLine…
inputLine = inputLine .. userKeypress

end
userKeypress = “”

end

celestia:requestkeyboard(false)       — Disable keyboard input
return inputLine
end

function viewSky(sky, obj, lt, lng)
ob = celestia:getobserver()
rate2 = celestia:gettimescale()
lat = math.rad(lt)
dist = dist2
long = math.rad(lng)
if lat == 0 then
long = getUserInput(” Observer LONGITUDE (-180 – +180 degrees): “)
long = math.rad(long)
lat = getUserInput(”  Observer LATITUDE (-90 – +90 degrees): “)
lat = math.rad(lat)
dist = getUserInput(”  DISTANCE in Kilometers\n Earth 31000\nMoon 8000\nSol 500000\nMercury 12000\nVenus 27000\nMars 18000\nJupiter 400000\nSaturn 600000\nUranus 14000\nNeptune  14000\nPluto 60000\nHubble 1\nSky 1): “)
end
if sky == “y” then
if fov == 27 then
fov = 120
end
celestia:getobserver():setfov(math.rad(fov))
if obj == Earth then
dist = 6450
end
if obj == Moon then
dist = 1800
end
if obj == Sol then
dist = 800000
end
if obj == Mercury then
dist = 2800
end
if obj == Venus then
dist = 6200
end
if obj ==Mars then
dist = 3800
end
if obj ==Jupiter then
dist = 80000
end
if obj ==Saturn then
dist = 80000
end
if obj ==Uranus then
dist = 30000
end
if obj ==Neptune then
dist = 30000
end
if obj ==Pluto then
dist = 2000
end
if obj ==Hubble then
dist = .1
end
end
celestia:settimescale(rate2)
ob:gotolonglat(obj, long, lat, dist, 5)
wait(6)
if sky == “y” then
obs = celestia:getobserver()
y_axis = celestia:newvector(0,1,0)
flip_rot = celestia:newrotation(y_axis,math.rad(180))
obs:rotate(flip_rot)
celestia:getobserver():synchronous(obj)
wait(1)
else
celestia:getobserver():follow(obj)
end
wait(1)
getAction()

end

function setnewTime()
lt = 0
rate2 = celestia:gettimescale()
celestia:settimescale(0)
year = getUserInput(” Enter a year: “)
month = getUserInput(” Enter a month: “)
day = getUserInput(” Enter a day: “)
celestia:settime(celestia:tojulianday(year,month,day,23,00,0))
celestia:settimescale(rate2)
wait(1)
getAction()
end

function setTimeRate()
lt = 0
rate = 1
rate = getUserInput(” Enter TimeRate: “)
celestia:settimescale(rate)
wait(1)
getAction()
end

function changeDist(obj)
lt = 0
rate2 = celestia:gettimescale()
celestia:settimescale(0)
d = getUserInput(“Set new distance: “)
celestia:getobserver():gotodistance(obj, d, 10)
celestia:settimescale(rate2)
wait(5)
getAction()
end

function motion(obj)
lt = 0
rate2 = celestia:gettimescale()
celestia:settimescale(0)
m = getUserInput(“s – sync, f – follow, c – chase: “)
if m == “s” then
celestia:getobserver():synchronous(obj)
end
if m == “f” then
celestia:getobserver():follow(obj)
end
if m == “c” then
celestia:getobserver():chase(obj)
end
celestia:settimescale(rate2)
wait(1)
getAction()
end

function gotoObject()
lt = 0
fov = 27
celestia:getobserver():setfov(math.rad(27))
rate2 = celestia:gettimescale()
celestia:settimescale(0)
ob = celestia:getobserver()
dur = 10
dist = 1
o = getUserInput(“Earth        – 1\nMoon        – 2\nSol            – 3\nMercury    – 4\nVenus       – 5\nMars         – 6\nJupiter     – 7\nSaturn      – 8\nUranus     – 9\nNeptune  – 10\nPluto        – 11\nHubble    – 1\nChoose(1-12): “)
if o == “1” then
ob:gotolonglat(Earth, -161, 0, 31000, dur)
ob:follow(Earth)
obj = Earth
end
if o == “2” then
ob:gotolonglat(Moon, -3.7, 5.3, 8000, dur)
ob:follow(Moon)
obj = Moo4
end
if o == “3” then
ob:gotolonglat(Sol, 0, -.1, 5000000, dur)
ob:follow(Sol)
obj = Sol
end
if o == “4” then
ob:gotolonglat(Mercury, -91, 6, 12000, dur)
ob:follow(Mercury)
obj = Mercury
end
if o == “5” then
ob:gotolonglat(Venus, -125, 1, 27000, dur)
ob:follow(Venus)
obj = Venus
end
if o == “6” then
ob:gotolonglat(Mars, 62, 5, 18000, dur)
ob:follow(Mars)
obj = Mars
end
if o == “7” then
ob:gotolonglat(Jupiter, 7.8, 60, 400000, dur)
ob:follow(Jupiter)
obj = Jupiter
end
if o == “8” then
ob:follow(Saturn)
ob:gotolonglat(Saturn,-113, 28, 600000, 2)
obj = Saturn
end
if o == “9” then
ob:gotolonglat(Uranus,-64, -.2, 140000, 2)
ob:follow(Uranus)
obj = Uranus
end
if o == “10” then
ob:gotolonglat(Neptune,-123, -.25, 140000, 2)
ob:follow(Neptune)
obj = Neptune
end
if o == “11” then
ob:gotolonglat(Pluto,-112, -.50, 60000, 2)
ob:follow(Pluto)
obj = Pluto
end
if o == “12” then
ob:gotolonglat(Hubble, -156 ,14, 1, 2)
ob:follow(Hubble)
obj = Hubble
end
celestia:settimescale(rate2)
wait(5)
getAction()
end

function changeFOV()
lt = 0
rate2 = celestia:gettimescale()
fov = getUserInput(“new FOV: “)
celestia:getobserver():setfov(math.rad(fov))
celestia:settimescale(rate2)
wait(1)
getAction()
end

function setLocation()
fov = 27
celestia:getobserver():setfov(math.rad(27))
rate2 = celestia:gettimescale()
celestia:settimescale(0)
ob = celestia:getobserver()
ob:chase(Earth)
dur = 10
dist = 1
loc = getUserInput(“1 New York 2 Miami 3 Chicago 4 Houston 5 Minneapolis 6 Denver 7 Seattle 8 San Diego\n9 London 10 Paris 11 Rio De Janeiro 12 Santiago 13 Rome 14 Moscow 15 Berlin 16 Nairobi\n17 Calcutta 18 Tokyo 19 Beijing 20 Bangkok 21 Sydney 22 Perth \nchoose: “)
sky =  getUserInput(“\View Location – n \ View Sky – y\nchoose: “)
if loc == “1” then
lng = -74
lt = 41
end
if loc == “2” then
lng = -80
lt = 26
end
if loc == “3” then
lng = -87
lt = 42
end
if loc == “4” then
lng = -95
lt = 30
end
if loc == “5” then
lng = -93
lt = 45
end
if loc == “6” then
lng = -105
lt = 40
end
if loc == “7” then
lng = -122
lt = 48
end
if loc == “8” then
lng = -117
lt = 32.3
end
if loc == “9” then
lng = .1
lt = 51.5
end
if loc == “10” then
lng = 2.3
lt = 48.8
end
if loc == “11” then
lng = -43.2
lt = -23
end
if loc == “12” then
lng = -70.8
lt = -33.5
end
if loc == “13” then
lng = 12.5
lt = 42
end
if loc == “14” then
lng = 37.5
lt = 55.8
end
if loc == “15” then
lng = 13.4
lt = 52.5
end
if loc == “16” then
lng = 37
lt = -1
end
if loc == “17” then
lng = 88.5
lt = 22.5
end
if loc == “18” then
lng = 139.8
lt = 35.7
end
if loc == “19” then
lng = -116.4
lt = 40
end
if loc == “20” then
lng = 100.5
lt = 13.8
end
if loc == “21” then
lng = 151
lt = -34
end
if loc == “22” then
lng = 116
lt = -32
end
obj = Earth
viewSky(sky, obj, lt, lng)
end

function otherObject(oobj)
obj = celestia:find(oobj)
celestia:getobserver():goto(obj)
celestia:getobserver():follow(obj)
wait(1)
getAction()
end

function getChoice()
lt = 0
rate2 = celestia:gettimescale()
celestia:settimescale(0)
celestia_keyboard_callback = getChar
ch = getUserInput(“Select Operation:\n1- lat & long\n2 view sky\n3 setTimeRate\n4 set time\n5 change distance\n6 synchronize,follow,chase\n7 go to object\n8 change FOV\n9 Location\n10 Other Object\nPress q for this menu\nchoose(1-10): “)
celestia:settimescale(rate2)
if ch == “1” then
viewSky(“n”, obj, 0, 0)
end
if ch == “2” then
viewSky(“y”, obj, 0, 0)
end
if ch == “3” then
setTimeRate()
end
if ch == “4” then
setnewTime()
end
if ch == “5” then
changeDist(obj)
end
if ch == “6” then
motion(obj)
end
if ch == “7” then
gotoObject()
end
if ch == “8” then
changeFOV()
end
if ch == “9” then
setLocation()
end
if ch == “10” then
oobj  =  getUserInput(“object name: “)
otherObject(oobj)
end
end

function getAction()
lt = 0
celestia_keyboard_callback = getChar
ac = getUserInput()
if ac == “q” then
getChoice()
end
end
getChoice()

celestia_keyboard_callback = getChar is a callback function that allows for keyboard input
The getUserInput() function creates the prompt menus.

The normal procedure is to run Celestia and use a menu to choose a script to run. To speed it up I have written a batch file to start Celestia or scripts directly from a command line:

@echo off
D:
cd \Programs\Celestia
:CHOOSE
ECHO ON
REM 1. Viewer
REM 2: Doc
REM 3. Celestia
REM 4. End
ECHO OFF
CHOICE /C 1234  /N  /M “Please choose a menu option”
IF ERRORLEVEL == 4 GOTO END
IF ERRORLEVEL == 3 GOTO Celestia
IF ERRORLEVEL == 2 GOTO Doc
IF ERRORLEVEL ==  1 GOTO Viewer
:Viewer
.\celestia –url Viewer.celx
GOTO CHOOSE
:Doc
.\celestia –url Celx_Visual_Guide_v1.132.1.celx
GOTO CHOOSE
:Celestia
celestia
GOTO CHOOSE
:END

A HTML Python IDE

I had previously discussed a Python app to create Python and Java Interfaces.

This app ports it to HTML and has features to make it even more convnient.

I have only finished the Python part, but I think it is complex enough to merit a discussion. I will post an update when the Java part is complete.

There is a help section, but I think the interface is descriptive enough that the help may never be needed.

Once again the first thing is to choose the language, for this post Python.

Next, the Control must be chosen.
When this is done, some changes will be noticed in that the background color of certain boxes will change. Boxes highlighted yellow are required, while light green highlighted boxes are optional. Here is how it looks on choosing to add a frame:

Click Image for larger view

AddingFrame

Also notice the change in color of the background box, indicating the background color has been changed. This is a warning that all future widgets will have the new color unless it is changed again.

To set values for the widgets, first doubleclick the box and it will change to gray. Then insert the new value. The graying is an indication that the value has already been set. When all yellow boxes have been converted to gray, click the red button and that code will be added. Here is how it now looks:

Click Image for larger view

FrameAdded

Next we are going to add a button to the frame.

On selecting button, notice a couple of new things; the Parent box has turned yellow, as well as the Function box. For a button it is required to Subclass and a choice must be made between the window and frame as to the parent.

Here is how that looks:

Click Image for larger view

AddButtonFrameOption

This is the appearance after adding the button information and clicking the red button:

Click Image for larger view

ButtonAdded

Notice that a function has been created.

Here is how the created interface looks:

Click Image for larger view

PythonResult

Here is the code:

><!DOCTYPE html PUBLIC ‘-//W3C//DTD XHTML 1.0 Transitional//EN’ ‘http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd’&gt;
<html xmlns=’http://www.w3.org/1999/xhtml’&gt;
<head profile=’http://gmpg.org/xfn/11′&gt;
<title>Python-Java-IDE</title>
<style type=’text/css’>
body {margin-left:0;margin-right:0;font:normal normal normal 12px Arial; }
a{ text-decoration: }
:link { color: rgb(0, 0, 255) }
:visited {color :rgb(100, 0,100) }
:hover { }
:active { }
#widget{background: #0000AA; color: white}
#go{background: #FF0033; color: white}
table{position: relative; width: 90%; left: 5%; empty-cells: show; background: #EEEEEE}
#ta{width: 100%; height:1000px}
input{font-size:10pt; width:90px}
#deffont{width: 150px}
#langu{background: #000000; color: white}
#fnd,#cse,#rplace,#rall,#bold,#ital,#under,#selected,#nbook{width: 20px}
#sze{width: 50px}
#file, #edit, #java, #help{background: #EEEEEE}
select{font-size: 10pt}
</style>
</head>
<body>
<table>
<tr>
<td><input type=”text” id=”width” name=”width” value=”width” ondblclick=’rset(“width”);’/></td>
<td><input type=”button” id=”go” name=”go” value=”Go” onclick=’wrt();’ /></td>
<td></td>
<td colspan=”4″><select id=”file” name=”file” onchange=’fileop();’>
<option>File</option>
<option>New</option>
<option>Local Storage</option>
<option>Open LS</option>
</select>
<select id=”edit” name=”edit” onchange=’undo();’>
<option>Edit</option>
<option>Undo</option>
<option>Redo</option>
<option>BgColor</option>
<option>FgColor</option>
</select>
<select id=”java” name = “java”>
<option>Java</option>
<option>Compile</option>
<option>Run</option>
<option>Make Jar</option>
</select>
<select id=”help” name=”help” onchange=’hlp();’>
<option>Help</option>
<option>View Help</option>
<option>Return</option>
</select>
</td>
<td></td>
<td></td>
<td><input type=”checkbox” id=”fnd” name=”fnd” value=”find” onmousedown=’f_r(“find”);’ />find<td>
</tr>
<tr>
<td><input type=”text” id=”height” name=”height” value=”height” ondblclick=’rset(“height”);’ /></td>
<td><select id=”widget” name=”widget” onchange= ‘hilite();’>
<option>Control</option>
<option>Python</option>
<option></option>
<option>Window</option>
<option>Entry</option>
<option>Button</option>
<option>Label</option>
<option>Text</option>
<option>ScrolledText</option>
<option>Listbox</option>
<option>Combobox</option>
<option>Checkbutton</option>
<option>Radiobutton</option>
<option>Frame</option>
<option>Canvas</option>
<option>Scrollbar</option>
<option>Menu</option>
<option>Progressbar</option>
<option>Notebook</option>
<option></option>
<option>Java</option>
</select></td>
<td><input type=”text” id=”Text” name=”Text” value=”” ondblclick=’rset(“Text”);’ /></td>
<td><input type=”text” id=”name” name=”name” value=”” ondblclick=’rset(“name”);’ /></td>
<td><select id=”langu” name=”langu” onchange= ‘lng();’>
<option>Language</option>
<option>Python</option>
<option>Java</option>
</select>
</td>
<td></td>
<td><input type=’color’ id=’color’ value= simple color /></td>
<td><input type=”text” id=”find” name=”find” value=”find” /></td>
<td><input type=”text” id=”replace” name=”replace” value=”replace” /></td>
<td><input type=”checkbox” id=”cse” name=”cse” value=”case” checked />case<td>
</tr>
<tr>
<td><input type=”text” id=”left” name=”left” value=”left” ondblclick=’rset(“left”);’ /></td>
<td><input type=”text” id=”strvar” name=”strvr” value=”” ondblclick=’rset(“strvar”);’ /></td>
<td id=”slct”></td>
<td><input type=”text” id=”func” name=”func” value=”” ondblclick=’rset(“func”);’ /></td>
<td>

Selected

</td>
<td><select id=”parent” name=”parent” onmousedown=’rset(“parent”);’><option>window</option></select></td>
<td><input type=”checkbox” id=”nbook” name=”nbook” value=”nbook” />Notebook</td>
<td></td>
<td></td>
<td><input type=”checkbox” id=”rplace” name=”rplace” value=”replace” onmousedown=’f_r(“replace”);’ />replace</td>
</tr>
<tr>
<td><input type=”text” id=”top” name=”top” value=”top” ondblclick=’rset(“top”);’ /></td>
<td><input type=”text” id=”deffont” name=”deffont” value=”” ‘ onmousedown=’document.getElementById(“deffont”),style.backgroundColor=”#FFDDAA”;’ /></td>
<td><input type=”text” id=”fg” name=”fg” value=’fg=”#000000″‘ onmousedown=’document.getElementById(“fg”),style.backgroundColor=”#FFDDAA”;’/></td>
<td><input type=”text” id=”bg” name=”bg” value=’bg=”#EEEEEE”” onmousedown=’document.getElementById(“bg”),style.backgroundColor=”#FFDDAA”;’ /></td>
<td><input type=”checkbox” id=”bold” name=”bold” value=”bold” checked />bold</td>
<td><input type=”checkbox” id=”ital” name=”ital” value=”italic” />italic</td>
<td><input type=”checkbox” id=”under” name=”under” value=”underline” />underline</td>
<td><input type=”text” id=”sze” name=”sze” value=’fontsize’ ondblclick=’rset(“sze”);’/></td>
<td id=”fontselect”>
<select id=”font” name=”font” onchange=’getFont();’>
<option>Font</option>
<option>Arial</option>
<option>Times New Roman</option>
<option>Courier</option>
<option>Georgia</option>
<option>Cancun</option>
<option>Verbana</option>
<option>Impact</option>
<option>Comic Sans MS</option>
</select>
</td>
<td><input type=”checkbox” id=”rall” name=”rall” value=”replace all” onmousedown=’f_r(“rall”);’ />replace all<td>
</tr>
<tr>
<td colspan=”12″><textarea id=”ta” name=”ta” rows=”rows” cols=”columns”>
</textarea></td>
</tr>
</table>

var strt; var ta; var fn; var selectionText; var repl; var strt2 = 0; var beginText; var endText; var width; var height; var titl; var width2; var height2; var wdth; var hgt; var lft; var tp; var strbind = “”; var fntstr= “”; var txt2 = “”; var oldstr=””; var newstr = “”; var slcted = “”; var parnt2; var mnucnt = false; var width3; var height3;

function fileop() {
var op = document.getElementById(“file”).value;
if (op == “New”) document.getElementById(“ta”).value = “”;
if (op == “Local Storage”) {
var savestr = prompt(“Save Key”, “”);
localStorage.setItem(savestr, document.getElementById(“ta”).value);
}
if (op == “Open LS”) {
var opnstr = prompt(“Open Key”, “”);
var recovstr = localStorage.getItem(opnstr);
document.getElementById(“ta”).value = recovstr;
}
}

function hlp() {
if (document.getElementById(“help”).value == “View Help”) {
document.getElementById(“ta”).value = ‘General\nStart by choosing Python or Java from the Language black box.\nif Python select Window from the blue box.\nThe values to be entered will be highlighted in yellow. Double click a yellow box and it will turn gray.\nEnter the value and go to the next yellow box.\nWhen no yellow boxes remain, click the red box.\nRepeat the procedure with any controls to be added. Control dimensions are entered as a percentage of the parent.\nClick Undo to remove the last change and Redo to reverse the Undo.\nClick View Help to see this file and Return to go back to the workspace.\n\nPython\nIf you plan to create a Notebook, check Notebook. With a few exceptions entry is very straightforward. If the input is text, doubleclick and enter the value. If the input is select, choose a value from the list. Yellow boxes are compulsory and values must be entered. Light blue-green boxes are optional. If a Frame or Canvas has been added, it can serve as a parent. Therefore the parent box will turn yellow and a parent must be chosen for any subsequent widget. The WidgetText holds any caption or text that will be displayed. The WidgetName box holds the widget id.\nThe differences:\nButton:\nButtons are bound to a function, which must be given a name.\nCheckbox, Radiobox and Progressbar:\nThese need a variable whose name must be added. Additionally, to work properly, a determinate Progressbar must be tied to some function, although it is not itself bound. Therefore, give the function a name, use the same name for a function created by a bound widget and transfer the code to the new function\nListbox & Combobox:\nIt is bound to a function, which must be given a name. . To populate the list fill the WidgetText box in the following manner: \’item1\’,\’item2\’, \’item3\’ etc. Combobox is similar, only there is an option for the type of binding.\nScrollbar:\nThe widget to which the scrollbar is attached may not be the same as its parent. Therefore in the WidgetName box, the scrollbar id is entered followed by a comma and the id of the widget to which it is attached.\nMenus:\nNo position entries are needed. A Title such as Edit goes in the mnutitle box. The menu items are entered in the WidgetText as an item name followed by a comma, including a comma after the last item name. After the red box is clicked, repeat for the next menu, if needed.\nNotebook:\nCreate the Frames or ScrolledText boxes or other widgets that will populate the Notebook and fill them in the normal manner. Do not bother with Frame or ScrolledText dimensions. Click on Notebook and put in a width. Then make a comma separated list of the widgets to go in the notebook, followed by a comma after the last one. As with everything else, finish by clicking the red button’;
} else {
document.getElementById(“ta”).value = newstr;
}
}

function rset(layr) {
document.getElementById(layr).style.backgroundColor = “#CCCCCC”;
}

function getFont() {
if (document.getElementById(“langu”).value == “Python”) {
fntstr = ‘font= (“‘ + document.getElementById(“font”).value + ‘”,’;
fntstr += ‘ ‘ + document.getElementById(“sze”).value + ‘,’;
if (document.getElementById(“bold”).checked) fntstr += ‘ “bold”,’;
if (document.getElementById(“ital”).checked) fntstr += ‘ “italic”,’;
if (document.getElementById(“under”).checked) fntstr += ‘ “underline”‘;
fntstr += ‘)’;
document.getElementById(“deffont”).value = fntstr;
}
document.getElementById(“deffont”).style.backgroundColor=”#FFDDAA”;
}

function f_r(op) {
document.getElementById(“ta”).focus();
ta = document.getElementById(“ta”).value;

if (op == “rall”) {
document.getElementById(“ta”).focus();
ta = document.getElementById(“ta”).value;
fn = document.getElementById(“find”).value;
repl = document.getElementById(“replace”).value;
document.getElementById(“ta”).value = ta.replace(new RegExp(fn, ‘g’), repl);
}

if (op == “find”) {
fn = document.getElementById(“find”).value;
if (document.getElementById(“cse”).checked) {
strt = ta.indexOf(fn, strt2);
} else {
strt = ta.toLowerCase().indexOf(fn.toLowerCase(), strt2);
}
beginText = ta.substr(0, strt);
endText = ta.substr(beginText.length + fn.length, ta.length – beginText.length – fn.length );
selectionText = ta.substr(strt, fn.length);
strt2 = strt + fn.length + 1;
}
if (op == “replace”) {
document.getElementById(“ta”).focus();
repl = document.getElementById(“replace”).value;
if (strt != -1)document.getElementById(“ta”).value = beginText + repl + endText;
}
}

function lng() {
if (document.getElementById(“langu”).value == “Python”) {
document.getElementById(“fontselect”).innerHTML = ‘FontArialTimes New RomanCalibriCourier NewCancunGeorgiaImpactVerbanaSnell Blk BTComic Sans MSPrincetownDWeddingText BTManorlyEngrvrsOldEng Bd BT’;
document.getElementById(“Text”).value = “WidgetText”;
document.getElementById(“name”).value = “WidgetName”;
document.getElementById(“strvar”).value = “Variable”;
document.getElementById(“slct”).innerHTML = ‘Bind ActionButtonRelease-1ButtonRelease-2Return’;
document.getElementById(“func”).value = “Function”;
document.getElementById(“deffont”).value = ‘font= (“Arial”, 10, “bold”)’;
} else {
document.getElementById(“Text”).value = “Caption”;
document.getElementById(“name”).value = “Control Name”;
document.getElementById(“strvar”).value = “Panel”;
document.getElementById(“slct”).innerHTML = ”;
document.getElementById(“func”).value = “*,jar”;
document.getElementById(“deffont”).value = ‘”Arial”, Font.BOLD | Font.ITALIC, 15)’;
}
}

function hilite() {
if (document.getElementById(“ta”).value.indexOf(“Frame”) != -1 || document.getElementById(“ta”).value.indexOf(“Canvas”) != -1 ) document.getElementById(“parent”).style.backgroundColor = “yellow”;
var el = document.getElementById(“widget”).value;
document.getElementById(“sze”).value = “fontsize”;
document.getElementById(“d1”).style.backgroundColor = “#EEEEEE”;
if (el != “Scrollbar” && el != “Menu” && el != “Progressbar” && el != “Notebook”) {
document.getElementById(“width”).style.backgroundColor = “yellow”;
document.getElementById(“height”).style.backgroundColor = “yellow”;
}
document.getElementById(“left”).style.backgroundColor = “white”;
document.getElementById(“top”).style.backgroundColor = “white”;
document.getElementById(“name”).style.backgroundColor = “white”;
document.getElementById(“Text”).style.backgroundColor = “white”;
document.getElementById(“strvar”).style.backgroundColor = “white”;
document.getElementById(“func”).style.backgroundColor = “white”;
document.getElementById(“bnd”).style.backgroundColor = “white”;
document.getElementById(“sze”).style.backgroundColor = “white”;
if (el != “Window” && el != “Scrollbar” && el != “Menu” && el != “Progressbar” && el != “Notebook”) {
document.getElementById(“left”).style.backgroundColor = “yellow”;
document.getElementById(“top”).style.backgroundColor = “yellow”;
document.getElementById(“name”).style.backgroundColor = “yellow”;
if (el != “Frame” && el != “Canvas” && el != “Text” && el != “ScrolledText”) document.getElementById(“Text”).style.backgroundColor = “yellow”;
}
if (el == “Checkbutton” || el == “Radiobutton”) document.getElementById(“strvar”).style.backgroundColor = “yellow”;
if (el == “Button” || el == “Listbox” || el == “Combobox”) document.getElementById(“func”).style.backgroundColor = “yellow”;
if (el == “Entry” || el == “Radiobutton” || el == “Frame” || el == “Canvas”) {
document.getElementById(“func”).style.backgroundColor = “#CCFFF5”;
document.getElementById(“bnd”).style.backgroundColor = “#CCFFF5”;
}
if (el == “Combobox”) document.getElementById(“bnd”).style.backgroundColor = “yellow”;
if (el == “Radiobutton”) document.getElementById(“d1”).style.backgroundColor = “#CCFFF5”;
if (document.getElementById(“widget”).value == “Scrollbar” && (document.getElementById(“ta”).value.indexOf(“Frame”) != -1 || document.getElementById(“ta”).value.indexOf(“Canvas”) != -1 || document.getElementById(“ta”).value.indexOf(“Listbox”) != -1)) document.getElementById(“parent”).style.backgroundColor = “yellow”;
if (el == “Scrollbar”) document.getElementById(“name”).style.backgroundColor = “yellow”;

if (el == “Menu”) {
document.getElementById(“sze”).value = “mnutitle”;
document.getElementById(“sze”).style.backgroundColor = “yellow”;
document.getElementById(“name”).style.backgroundColor = “yellow”;
document.getElementById(“Text”).style.backgroundColor = “yellow”;
document.getElementById(“func”).style.backgroundColor = “yellow”;
document.getElementById(“width”).style.backgroundColor = “white”;
document.getElementById(“height”).style.backgroundColor = “white”;
}
if (el == “Progressbar”) {
document.getElementById(“width”).value = “length”;
document.getElementById(“left”).value = “value”;
document.getElementById(“width”).style.backgroundColor = “yellow”;
document.getElementById(“left”).style.backgroundColor = “yellow”;
document.getElementById(“name”).style.backgroundColor = “yellow”;
document.getElementById(“strvar”).style.backgroundColor = “yellow”;
document.getElementById(“func”).style.backgroundColor = “yellow”;
}

if (el == “Notebook”) {
document.getElementById(“width”).style.backgroundColor = “yellow”;
document.getElementById(“height”).style.backgroundColor = “white”;
document.getElementById(“name”).style.backgroundColor = “yellow”;
document.getElementById(“parent”).style.backgroundColor = “white”;
}

if (el == “Control”) {
oldstr = document.getElementById(“ta”).value;
document.getElementById(“width”).style.backgroundColor = “white”;
document.getElementById(“height”).style.backgroundColor = “white”;
document.getElementById(“top”).style.backgroundColor = “white”;
document.getElementById(“top”).style.backgroundColor = “white”;
document.getElementById(“left”).style.backgroundColor = “white”;
document.getElementById(“top”).style.backgroundColor = “white”;
document.getElementById(“name”).style.backgroundColor = “white”;
document.getElementById(“Text”).style.backgroundColor = “white”;
document.getElementById(“strvar”).style.backgroundColor = “white”;
document.getElementById(“func”).style.backgroundColor = “white”;
document.getElementById(“bnd”).style.backgroundColor = “white”;
document.getElementById(“sze”).style.backgroundColor = “white”;
}

}

function undo() {
if (document.getElementById(“edit”).value == “Undo”) {
document.getElementById(“ta”).value = oldstr;
} else if (document.getElementById(“edit”).value == “Redo”) {
document.getElementById(“ta”).value = newstr;
}
if (document.getElementById(“edit”).value == “BgColor”) {
document.getElementById(“bg”).value = ‘bg=”‘ + document.getElementById(“color”).value + ‘”‘;
document.getElementById(“bg”).style.backgroundColor = “#FFDDAA”;
}
if (document.getElementById(“edit”).value == “FgColor”) {
document.getElementById(“fg”).value = ‘fg=”‘ + document.getElementById(“color”).value + ‘”‘;
document.getElementById(“fg”).style.backgroundColor = “#FFDDAA”;
}
}

function wrt() {
parnt2 = document.getElementById(“parent”).value;
oldstr = document.getElementById(“ta”).value;
if (document.getElementById(“langu”).value == “Python”) {
pthon();
}
newstr = document.getElementById(“ta”).value;
}

function pthon() {
if (document.getElementById(“selected”).checked) {
slcted = document.getElementById(“name”).value + ‘.select()’;
} else {
slcted = “”;
}
if (document.getElementById(“bnd”).value != “Bind Action”) {
strbind = ‘\n’ + document.getElementById(“name”).value +’.bind(“”, ‘ + document.getElementById(“func”).value + ‘)’ ;
} else {
strbind = “”;
}
width = document.getElementById(“width”).value;
height = document.getElementById(“height”).value;
titl= document.getElementById(“Text”).value;

if ( document.getElementById(“widget”).value == “Window”) {
width2 = width;
height2 = height;
document.getElementById(“ta”).value += “import os\nimport tkinter\nfrom tkinter import *\nfrom tkinter import ttk\nfrom tkinter import scrolledtext\nfrom tkinter import filedialog\n\nwindow = tkinter.Tk()\nwindow.title(‘” + titl + “‘)\nwindow.maxsize(” + width + “,” + height + “)\nwindow.configure(” + document.getElementById(‘bg’).value + “)\n# notebook\n\n\n\nwindow.mainloop()”;
}

if ( document.getElementById(“widget”).value != “Window” && document.getElementById(“parent”).value == “window”) {
wdth = Math.round(parseFloat(document.getElementById(“width”).value)/100 * .97 * width2);
lft = Math.round(parseFloat(document.getElementById(“left”).value)/100 * .97 * width2);
hgt = Math.round(parseFloat(document.getElementById(“height”).value)/100 * .94 * height2);
tp = Math.round(parseFloat(document.getElementById(“top”).value)/100 * .94 * height2);
} else {
wdth = Math.round(parseFloat(document.getElementById(“width”).value)/100 * .97 * width3);
lft = Math.round(parseFloat(document.getElementById(“left”).value)/100 * .97 * width3);
hgt = Math.round(parseFloat(document.getElementById(“height”).value)/100 * .94 * height3);
tp = Math.round(parseFloat(document.getElementById(“top”).value)/100 * .94 * height3);
}

if ( document.getElementById(“widget”).value == “Entry” || document.getElementById(“widget”).value == “Frame” || document.getElementById(“widget”).value == “Canvas” ) {
ta = document.getElementById(“ta”).value;
var pos = ta.indexOf(“\n\n\n”);
beginText = ta.substr(0, pos);
if (document.getElementById(“Text”).value != “” && document.getElementById(“widget”).value == “Entry” ) {
titl = document.getElementById(“name”).value + ‘.insert(0, “‘ + document.getElementById(“Text”).value + ‘”);’;
var fn = ‘,’ + document.getElementById(“fg”).value + ‘,’ + document.getElementById(“bg”).value + ‘,’ + document.getElementById(“deffont”).value;
} else {
titl = “”;
fn = ‘, ‘ + document.getElementById(“bg”).value;
}
if ( document.getElementById(“widget”).value == “Frame” || document.getElementById(“widget”).value == “Canvas” || document.getElementById(“widget”).value == “Listbox” ) {
document.getElementById(“parent”).innerHTML += “” + document.getElementById(“name”).value + “”;
width3 = wdth;
height3 = hgt;
}

if (document.getElementById(“nbook”).checked && document.getElementById(“widget”).value == “Frame”) {
document.getElementById(“ta”).value = beginText + ‘\n\n’ + document.getElementById(“name”).value + ‘ = tkinter.Frame(nb, ‘ + document.getElementById(“bg”).value + ‘)\n\n\nwindow.mainloop()\n’;
} else {
document.getElementById(“ta”).value = beginText + ‘\n\n’ + document.getElementById(“name”).value + ‘ = tkinter.’ + document.getElementById(“widget”).value + ‘(‘ + parnt2 + fn + ‘ )\n’ + document.getElementById(“name”).value + ‘.place(x= “‘ + lft + ‘”, y=”‘ + tp + ‘”, width=”‘ + wdth + ‘”, height=”‘ + hgt + ‘”)’ + strbind +’\n’ + titl + ‘\n\n\nwindow.mainloop()\n’;
}

if (strbind !=””) {
ta = document.getElementById(“ta”).value;
pos = ta.indexOf(“\n\n”);
beginText = ta.substr(0, pos);
var endText = ta.substr(beginText.length, ta.length – beginText.length);
document.getElementById(“ta”).value = beginText + ‘\ndef ‘ + document.getElementById(“func”).value + ‘(event):\n code = “your code goes here”‘ + endText;
}
}

if ( document.getElementById(“widget”).value == “Label” || document.getElementById(“widget”).value == “Text” || document.getElementById(“widget”).value == “ScrolledText”) {
if ( document.getElementById(“widget”).value == “Label”) {
txt2 = ‘, text=”‘ + titl + ‘”‘;
} else {
txt2 = “”;
}

if (document.getElementById(“widget”).value == “ScrolledText”) {
var parnt =”scrolledtext” ;
} else {
parnt = “tkinter”;
}

ta = document.getElementById(“ta”).value;
var pos = ta.indexOf(“\n\n\n”);
beginText = ta.substr(0, pos);
if (document.getElementById(“nbook”).checked && document.getElementById(“widget”).value == “ScrolledText”) {
document.getElementById(“ta”).value = beginText + ‘\n\n’ + document.getElementById(“name”).value + ‘ = scrolledtext.ScrolledText(nb, ‘ + document.getElementById(“bg”).value + ‘)\n\n\nwindow.mainloop()\n’;
} else {
document.getElementById(“ta”).value = beginText + ‘\n\n’ + document.getElementById(“name”).value + ‘ = ‘ + parnt + ‘.’ + document.getElementById(“widget”).value + ‘(‘ + parnt2 + ‘, ‘ + document.getElementById(“fg”).value + ‘,’ + document.getElementById(“bg”).value + ‘,’ + document.getElementById(“deffont”).value + txt2 + ‘)\n’ + document.getElementById(“name”).value + ‘.place(x= “‘ + lft + ‘”, y=”‘ + tp + ‘”, width=”‘ + wdth + ‘”, height=”‘ + hgt + ‘”)\n\n\nwindow.mainloop()\n’;
}
}

if ( document.getElementById(“widget”).value == “Button”) {
ta = document.getElementById(“ta”).value;
var pos = ta.indexOf(“\n\n\n”);
beginText = ta.substr(0, pos);
document.getElementById(“ta”).value = beginText + ‘\n\n’ + document.getElementById(“name”).value + ‘ = tkinter.Button(‘ + parnt2 + ‘, ‘ + document.getElementById(“fg”).value + ‘,’ + document.getElementById(“bg”).value + ‘,’ + document.getElementById(“deffont”).value + ‘, text=”‘ + titl + ‘”, command=’ + document.getElementById(“func”).value + ‘)\n’ + document.getElementById(“name”).value + ‘.place(x= “‘ + lft + ‘”, y=”‘ + tp + ‘”, width=”‘ + wdth + ‘”, height=”‘ + hgt + ‘”)\n\n\nwindow.mainloop()\n’;
ta = document.getElementById(“ta”).value;
pos = ta.indexOf(“\n\n”);
beginText = ta.substr(0, pos);
var endText = ta.substr(beginText.length, ta.length – beginText.length);
document.getElementById(“ta”).value = beginText + ‘\ndef ‘ + document.getElementById(“func”).value + ‘():\n a = “put code here”‘ + endText;
}

if ( document.getElementById(“widget”).value == “Combobox”) {
ta = document.getElementById(“ta”).value;
var pos = ta.indexOf(“\n\n\n”);
beginText = ta.substr(0, pos);
document.getElementById(“ta”).value = beginText + ‘\n\nvallist = [‘ + document.getElementById(“Text”).value + ‘]\n’ + document.getElementById(“name”).value + ‘ = ttk.Combobox(window,’ + document.getElementById(“deffont”).value + ‘, values=vallist)\n’ + document.getElementById(“name”).value + ‘.place(x=”‘ + lft + ‘”, y=”‘ + tp + ‘”, width=”‘ + wdth + ‘”, height=”‘ + hgt + ‘”)\n’ + document.getElementById(“name”).value + ‘.insert(0,”Choose”)’ + strbind + ‘\n\n\nwindow.mainloop()\n’ ;
ta = document.getElementById(“ta”).value;
pos = ta.indexOf(“\n\n”);
beginText = ta.substr(0, pos);
var endText = ta.substr(beginText.length, ta.length – beginText.length);
document.getElementById(“ta”).value = beginText + ‘\ndef ‘ + document.getElementById(“func”).value + ‘(event):\n a = “enter your code”‘ + endText;
}

if ( document.getElementById(“widget”).value == “Listbox”) {
document.getElementById(“parent”).innerHTML += “” + document.getElementById(“name”).value + “”;
ta = document.getElementById(“ta”).value;
var pos = ta.indexOf(“\n\n\n”);
beginText = ta.substr(0, pos);
document.getElementById(“ta”).value = beginText + ‘\n\n’ + document.getElementById(“name”).value + ‘ = tkinter.Listbox(window,’ + document.getElementById(“deffont”).value + ‘)\n’ + document.getElementById(“name”).value + ‘.place(x=”‘ + lft + ‘”, y=”‘ + tp + ‘”, width=”‘ + wdth + ‘”, height=”‘ + hgt + ‘”)\nfor item in ([‘ + document.getElementById(“Text”).value + ‘]):\n ‘ + document.getElementById(“name”).value + ‘.insert(0, item)\n’ + document.getElementById(“name”).value + ‘.bind(“”,’ + document.getElementById(“func”).value + ‘)\n\n\nwindow.mainloop()\n’ ;
ta = document.getElementById(“ta”).value;
pos = ta.indexOf(“\n\n”);
beginText = ta.substr(0, pos);
var endText = ta.substr(beginText.length, ta.length – beginText.length);
document.getElementById(“ta”).value = beginText + ‘\ndef ‘ + document.getElementById(“func”).value + ‘(event):\n index =’ + document.getElementById(“name”).value + ‘.curselection()[0]\n seltext = ‘ + document.getElementById(“name”).value + ‘.get(index)’ + endText;
}

if ( document.getElementById(“widget”).value == “Checkbutton”) {
txt2 = ‘, text=”‘ + titl + ‘”‘;
ta = document.getElementById(“ta”).value;
var pos = ta.indexOf(“\n\n\n”);
beginText = ta.substr(0, pos);
document.getElementById(“ta”).value = beginText + ‘\n\n’ + document.getElementById(“strvar”).value + ‘ = StringVar()\n’ + document.getElementById(“name”).value + ‘ = tkinter.’ + document.getElementById(“widget”).value + ‘(‘ + parnt2 + ‘, ‘ + document.getElementById(“fg”).value + ‘,’ + document.getElementById(“bg”).value + ‘,’ + document.getElementById(“deffont”).value + txt2 + ‘, variable=’ + document.getElementById(“strvar”).value + ‘, onvalue=”yes”, offvalue=”no”)\n’ + document.getElementById(“name”).value + ‘.place(x= “‘ + lft + ‘”, y=”‘ + tp + ‘”, width=”‘ + wdth + ‘”, height=”‘ + hgt + ‘”)\n\n\nwindow.mainloop()\n ‘;
}

if ( document.getElementById(“widget”).value == “Radiobutton”) {
txt2 = ‘, text=”‘ + titl + ‘”‘;
ta = document.getElementById(“ta”).value;
var pos = ta.indexOf(“\n\n\n”);
beginText = ta.substr(0, pos);
document.getElementById(“ta”).value = beginText + ‘\n\n’ + document.getElementById(“strvar”).value + ‘ = StringVar()\n’ + document.getElementById(“name”).value + ‘ = tkinter.’ + document.getElementById(“widget”).value + ‘(‘ + parnt2 + ‘, ‘ + document.getElementById(“fg”).value + ‘,’ + document.getElementById(“bg”).value + ‘,’ + document.getElementById(“deffont”).value + txt2 + ‘, variable=’ + document.getElementById(“strvar”).value + ‘, value = “‘ + document.getElementById(“Text”).value + ‘”)\n’ + document.getElementById(“name”).value + ‘.place(x= “‘ + lft + ‘”, y=”‘ + tp + ‘”, width=”‘ + wdth + ‘”, height=”‘ + hgt + ‘”)’ + strbind + ‘\n’ + slcted + ‘\n\n\nwindow.mainloop()\n ‘;
if (strbind != “”) {
ta = document.getElementById(“ta”).value;
pos = ta.indexOf(“\n\n”);
beginText = ta.substr(0, pos);
var endText = ta.substr(beginText.length, ta.length – beginText.length);
document.getElementById(“ta”).value = beginText + ‘\ndef ‘ + document.getElementById(“func”).value + ‘(event):\n a = “enter code here”‘ + endText;
}
}

if ( document.getElementById(“widget”).value == “Scrollbar” ) {
var pos2 = document.getElementById(“name”).value.indexOf(“,”);
var id = document.getElementById(“name”).value.substr(0,pos2);
var attach = document.getElementById(“name”).value.substr(pos2 + 1, document.getElementById(“name”).value.length – pos2);
ta = document.getElementById(“ta”).value;
var pos = ta.indexOf(“\n\n\n”);
beginText = ta.substr(0, pos);
document.getElementById(“ta”).value = beginText + ‘\n\n’ + id + ‘ = tkinter.Scrollbar(‘ + parnt2 + ‘, orient=”vertical”, command=’+ attach + ‘.yview)\n’ + attach + ‘.configure(yscrollcommand=’ + id + ‘.set)\n’ + id + ‘.pack(side=RIGHT, fill=Y)\n\n\nwindow.mainloop()\n ‘;
}

if ( document.getElementById(“widget”).value == “Progressbar” ) {
var vr = document.getElementById(“strvar”).value;
ta = document.getElementById(“ta”).value;
var pos = ta.indexOf(“\n\n\n”);
beginText = ta.substr(0, pos);
document.getElementById(“ta”).value = beginText + ‘\n\nglobal ‘ + vr + ‘\n’ + vr + ‘ = ‘ + document.getElementById(“left”).value + ‘\n’ + document.getElementById(“name”).value + ‘ = ttk.Progressbar(‘ + parnt2 + ‘, orient=”horizontal”, mode=”determinate”, length=’ + document.getElementById(“width”).value + ‘, value=’ + vr + ‘)\n’ + document.getElementById(“name”).value + ‘.pack(side=”bottom”, fill=Y)\n\n\nwindow.mainloop()\n ‘;
ta = document.getElementById(“ta”).value;
pos = ta.indexOf(“\n\n”);
beginText = ta.substr(0, pos);
var endText = ta.substr(beginText.length, ta.length – beginText.length);
document.getElementById(“ta”).value = beginText + ‘\ndef ‘ + document.getElementById(“func”).value + ‘(event):\n global ‘ + document.getElementById(“strvar”).value + ‘\n\n ‘ + document.getElementById(“name”).value + ‘.step(‘ + document.getElementById(“strvar”).value + ‘)\n’ + endText;
}

if ( document.getElementById(“widget”).value == “Menu” ) {
var a = 0;
var b=0;
var txt2 = document.getElementById(“Text”);
var c = 0;
var d=0;
strmenu = “”;
var txt1 = document.getElementById(“func”);
ta = document.getElementById(“ta”).value;
var pos = ta.indexOf(“\n\n\n”);
beginText = ta.substr(0, pos);
if (! mnucnt) var strmenu = ‘menubar = ‘ + document.getElementById(“widget”).value + ‘(‘ + document.getElementById(“parent”).value + ‘)\n’
strmenu += document.getElementById(“name”).value + ‘ = Menu(menubar, tearoff=0)\n’;
for (var i=0; i

</body></html>

Since javascript is unable to save files, I have used Local Storage for saving in the functions fileop() and OpenLS().

There is a find and replace, text and background colors can be changed either by clicking a color dialog or manually entering the text and the font can be changed either by choosing from a list or entering manually;

I will eventually convert to PHP which will allow both saving and testing, but right now, to save and test, the text has to be copied and pasted into another application.