Here is another stylish switch (a link to the original article is included in the comments).
Also an overview of how to modify html checkbox switches to be functional in Basic:
They will have at least 2 styles, a 'before' and an 'after' the checkbox state is ticked.
You don't interface directly with those styles, you just disable the original web checkbox component then add your own Basic checkbox$ alternative which you can toggle according to the state of your specified variable, so the before and after styles will take care of themselves when your checkbox$ changes state. You just need to branch to change the state of your variable whenever the checkbox state is toggled when clicked.
The top and bottom red coloured code are the functional additions needed,
plus swapping the web checkbox out for a Basic checkbox$ component as shown.
Basic:
pinA = 12 'gpio pin for switch A
stateA = 0 'used to specify the switch state according to the checkbox state pin.mode pinA, output 'configures the pin for output pin(pinA) = stateA 'sets pin to default state onHtmlChange change 'jump when switch is clicked cls a$ = "" a$ = a$ + |<style>| 'a$ = a$ + |/* https://tympanus.net/codrops/2012/09/13/button-switches-with-checkboxes-and-css3-fanciness/ */| a$ = a$ + |body {| a$ = a$ + | background-color: lightblue;| a$ = a$ + |}| a$ = a$ + |.switch input {| a$ = a$ + | /* First, we make it as wide as the container */| a$ = a$ + | position: absolute;| a$ = a$ + | width: 100%;| a$ = a$ + | height: 100%;| a$ = a$ + | /* Then, we put it on top of everything else */| a$ = a$ + | z-index: 100;| a$ = a$ + | /* Last, we make it invisible */| a$ = a$ + | opacity: 0;| a$ = a$ + | /* This one is just for ergonomy */| a$ = a$ + | cursor: pointer;| a$ = a$ + |}| a$ = a$ + |.switch {| a$ = a$ + | width: 50px;| a$ = a$ + | height: 100px;| a$ = a$ + | position: relative;| a$ = a$ + |}| a$ = a$ + |.switch label {| a$ = a$ + | display: block;| a$ = a$ + | width: 100%;| a$ = a$ + | height: 100%;| a$ = a$ + | position: relative;| a$ = a$ + | background: #cbc7bc;| a$ = a$ + | border-radius: 5px;| a$ = a$ + | box-shadow:| a$ = a$ + | inset 0 1px 0 white,| a$ = a$ + | 0 0 0 1px #999,| a$ = a$ + | 0 0 5px 1px rgba(0,0,0,0.2),| a$ = a$ + | 0 2px 0 rgba(255,255,255,0.6),| a$ = a$ + | inset 0 10px 1px #e5e5e5,| a$ = a$ + | inset 0 11px 0 rgba(255,255,255,0.5),| a$ = a$ + | inset 0 -45px 3px #ddd;| a$ = a$ + |}| a$ = a$ + |.switch label:after {| a$ = a$ + | content: "";| a$ = a$ + | position: absolute;| a$ = a$ + | z-index: -1;| a$ = a$ + | top: -20px;| a$ = a$ + | left: -25px;| a$ = a$ + | bottom: -20px;| a$ = a$ + | right: -25px;| a$ = a$ + | background: #ccc; /* Fallback */| a$ = a$ + | background: linear-gradient(#ddd, #bbb);| a$ = a$ + | border-radius: inherit;| a$ = a$ + | border: 1px solid #bbb;| a$ = a$ + | box-shadow:| a$ = a$ + | 0 0 5px 1px rgba(0,0,0,0.15),| a$ = a$ + | 0 3px 3px rgba(0,0,0,0.3),| a$ = a$ + | inset 0 1px 0 rgba(255,255,255,0.5);| a$ = a$ + |}| a$ = a$ + |.switch label:before {| a$ = a$ + | content: "";| a$ = a$ + | position: absolute;| a$ = a$ + | width: 8px;| a$ = a$ + | height: 8px;| a$ = a$ + | top: -13px;| a$ = a$ + | left: 20px;| a$ = a$ + | background: #666;| a$ = a$ + | border-radius: 50%;| a$ = a$ + | box-shadow:| a$ = a$ + | 0 1px 0 white, /* Subtle reflection on the bottom of the hole */| a$ = a$ + | 0 120px 0 #666, /* Faking a second screw hole... */| a$ = a$ + | 0 121px 0 white; /* And its reflection */| a$ = a$ + |}| a$ = a$ + |.switch input:checked ~ label { /* Button */| a$ = a$ + | background: #d2cbc3;| a$ = a$ + | box-shadow:| a$ = a$ + | inset 0 1px 0 white,| a$ = a$ + | 0 0 0 1px #999,| a$ = a$ + | 0 0 5px 1px rgba(0,0,0,0.2),| a$ = a$ + | inset 0 -10px 0 #aaa,| a$ = a$ + | 0 2px 0 rgba(255,255,255,0.1),| a$ = a$ + | inset 0 45px 3px #e0e0E0,| a$ = a$ + | 0 8px 6px rgba(0,0,0,0.18);| a$ = a$ + |}| a$ = a$ + |</style>| a$ = a$ + |<body>| a$ = a$ + |<div class="switch" style="margin-right: auto; margin-left: auto; margin-top:9em;" >| 'a$ = a$ + | <input type="checkbox">| 'disable the original web checkbox component which was set by being ticked a$ = a$ + checkbox$(stateA) 'add our Basic checkbox$ replacement component which gets set according to our stateA variable a$ = a$ + | <label></label>| a$ = a$ + |</div> | a$ = a$ + |</body>| html a$ a$ = "" wait change: print stateA 'for debugging purposes pin(pinA) = stateA 'set pin according to the checkbox$ state refresh return This next version gives a row of 5 functional switches, each with an illuminated panel indicator...
Basic:
cls
pinA = 12 'gpio pin assignment for the 5 switches pinB = 15 pinC = 13 pinD = 16 pinE = 14 indA$ = "Entrance" 'panel indicator indB$ = "Cabin" indC$ = "Galley" indD$ = "Bathroom" indE$ = "Bedroom" indOn$ = "width:47%;height:90%;font-size:20px; margin:auto;border-radius:.3em;text-align:center; background-color:Yellow;color:black;" indOff$ = "width:47%;height:90%;font-size:20px; border-radius:.3em;text-align:center; background-color:AliceBlue ;color:darkgrey;" stateA = 1 'used to specify the switch state according to the checkbox state stateB = 1 stateC = 1 stateD = 1 stateE = 1 pin.mode pinA, output 'configures the pin for output pin.mode pinB, output pin.mode pinC, output pin.mode pinD, output pin.mode pinE, output pin(pinA) = stateA 'sets pin to default state pin(pinB) = stateB pin(pinC) = stateC pin(pinD) = stateD pin(pinE) = stateE onHtmlChange change a$ = "" a$ = a$ + |<style>| a$ = a$ + |body {background-color: lightblue;}| a$ = a$ + |body {background: url("/img/w0.jpg");}| 'Loads a background image if available, else defaults to the above colour a$ = a$ + |.switch input {| a$ = a$ + | position: absolute;| a$ = a$ + | width: 100%;| a$ = a$ + | height: 100%;| a$ = a$ + | z-index: 100;| a$ = a$ + | opacity: 0;| a$ = a$ + | cursor: pointer;| a$ = a$ + |}| a$ = a$ + |.switch {| a$ = a$ + | width: 50px;| a$ = a$ + | height: 100px;| a$ = a$ + | position: relative;| a$ = a$ + |}| a$ = a$ + |.switch label {| a$ = a$ + | display: block;| a$ = a$ + | width: 100%;| a$ = a$ + | height: 100%;| a$ = a$ + | position: relative;| a$ = a$ + | background: #cbc7bc;| a$ = a$ + | border-radius: 5px;| a$ = a$ + | box-shadow:| a$ = a$ + | inset 0 1px 0 white,| a$ = a$ + | 0 0 0 1px #999,| a$ = a$ + | 0 0 5px 1px rgba(0,0,0,0.2),| a$ = a$ + | 0 2px 0 rgba(255,255,255,0.6),| a$ = a$ + | inset 0 10px 1px #e5e5e5,| a$ = a$ + | inset 0 11px 0 rgba(255,255,255,0.5),| a$ = a$ + | inset 0 -45px 3px #ddd;| a$ = a$ + |}| a$ = a$ + |.switch label:after {| a$ = a$ + | content: "";| a$ = a$ + | position: absolute;| a$ = a$ + | z-index: -1;| a$ = a$ + | top: -20px;| a$ = a$ + | left: -25px;| a$ = a$ + | bottom: -20px;| a$ = a$ + | right: -25px;| a$ = a$ + | background: #ccc; /* Fallback */| a$ = a$ + | background: linear-gradient(#ddd, #bbb);| a$ = a$ + | border-radius: inherit;| a$ = a$ + | border: 1px solid #bbb;| a$ = a$ + | box-shadow:| a$ = a$ + | 0 0 5px 1px rgba(0,0,0,0.15),| a$ = a$ + | 0 3px 3px rgba(0,0,0,0.3),| a$ = a$ + | inset 0 1px 0 rgba(255,255,255,0.5);| a$ = a$ + |}| a$ = a$ + |.switch label:before {| a$ = a$ + | content: "";| a$ = a$ + | position: absolute;| a$ = a$ + | width: 8px;| a$ = a$ + | height: 8px;| a$ = a$ + | top: -13px;| a$ = a$ + | left: 20px;| a$ = a$ + | background: #666;| a$ = a$ + | border-radius: 50%;| a$ = a$ + | box-shadow:| a$ = a$ + | 0 1px 0 white, /* Subtle reflection on the bottom of the hole */| a$ = a$ + | 0 120px 0 #666, /* Faking a second screw hole... */| a$ = a$ + | 0 121px 0 white; /* And its reflection */| a$ = a$ + |}| a$ = a$ + |.switch input:checked ~ label { /* Button */| a$ = a$ + | background: #d2cbc3;| a$ = a$ + | box-shadow:| a$ = a$ + | inset 0 1px 0 white,| a$ = a$ + | 0 0 0 1px #999,| a$ = a$ + | 0 0 5px 1px rgba(0,0,0,0.2),| a$ = a$ + | inset 0 -10px 0 #aaa,| a$ = a$ + | 0 2px 0 rgba(255,255,255,0.1),| a$ = a$ + | inset 0 45px 3px #e0e0E0,| a$ = a$ + | 0 8px 6px rgba(0,0,0,0.18);| a$ = a$ + |}| a$ = a$ + |</style>| a$ = a$ + |<body>| a$ = a$ + |<br><br><br><br><br>| a$ = a$ + |<table align="center" height="170"><tr align="center" style="text-align:center;">| a$ = a$ + |<td>| + textbox$(indA$, "indA") + |</td>| a$ = a$ + |<td>| + textbox$(indB$, "indB") + |</td>| a$ = a$ + |<td>| + textbox$(indC$, "indC") + |</td>| a$ = a$ + |<td>| + textbox$(indD$, "indD") + |</td>| a$ = a$ + |<td>| + textbox$(indE$, "indE") + |</td>| a$ = a$ + cssid$("indA", indOff$) a$ = a$ + cssid$("indB", indOff$) a$ = a$ + cssid$("indC", indOff$) a$ = a$ + cssid$("indD", indOff$) a$ = a$ + cssid$("indE", indOff$) a$ = a$ + |</tr>| a$ = a$ + |<tr><td colspan=4 ><br> </td></tr><tr>| a$ = a$ + |<td><div class="switch" style="padding-left:30px; padding-right:30px;margin:auto;">| a$ = a$ + checkbox$(stateA) a$ = a$ + |<label><br><br><br><br><br><br><br>| a$ = a$ + |</label></div></td>| a$ = a$ + |<td><div class="switch" style="padding-left:30px; padding-right:30px;margin:auto;">| a$ = a$ + checkbox$(stateB) a$ = a$ + |<label><br><br><br><br><br><br><br>| a$ = a$ + |</label></div></td>| a$ = a$ + |<td><div class="switch" style="padding-left:30px; padding-right:30px;margin:auto;">| a$ = a$ + checkbox$(stateC) a$ = a$ + |<label><br><br><br><br><br><br><br>| a$ = a$ + |</label></div></td> | a$ = a$ + |<td><div class="switch" style="padding-left:30px; padding-right:30px;margin:auto;">| a$ = a$ + checkbox$(stateD) a$ = a$ + |<label><br><br><br><br><br><br><br>| a$ = a$ + |</label></div></td>| a$ = a$ + |<td><div class="switch" style="padding-left:30px; padding-right:30px;margin:auto;">| a$ = a$ + checkbox$(stateE) a$ = a$ + |<label><br><br><br><br><br><br><br>| a$ = a$ + |</label></div></td>| a$ = a$ + |</tr></table>| a$ = a$ + |</body>| html a$ a$ = "" wait change: print stateA, stateB, stateC, stateD pin(pinA) = stateA pin(pinB) = stateB pin(pinC) = stateC pin(pinD) = stateD pin(pinE) = stateE if stateA <> 0 then css cssid$("indA", indOff$) else css cssid$("indA", indOn$) if stateB <> 0 then css cssid$("indB", indOff$) else css cssid$("indB", indOn$) if stateC <> 0 then css cssid$("indC", indOff$) else css cssid$("indC", indOn$) if stateD <> 0 then css cssid$("indD", indOff$) else css cssid$("indD", indOn$) if stateE <> 0 then css cssid$("indE", indOff$) else css cssid$("indE", indOn$) refresh return '------------- End ----------------- NOTE: Backgrounds There is a line in the script which will load a background image if it is available, else it will default to the colour specified in the line before it: Here is the same line prefixed with HTML and wrapped in style tags to make it easier to include in other scripts: HTML |<style>body {background: url("/img/w0.jpg");}</style>| The above code will tile a smaller image to fill the screen, as shown in the bottom 3 wood panel screenshots. If you wish the image to be enlarged so the shortest side fits the screen as below, insert no-repeat center fixed; background-size: cover as shown: HTML |<style>body {background: url("/img/imagefilename.jpg") no-repeat center fixed; background-size: cover ;}</style>| You can find all 4 of the background images used below attached at the bottom of this page - upload them into the /img/ folder of the device. Any other projects showing a background screenshot will include the image at the page bottom and would have temporarily used the above code.
a$ = a$ + |body {background: url("/img/w0.jpg");}|
a$ = a$ + |body {background: url("/img/w2.jpg");}|
a$ = a$ + |body {background: url("/img/w3.jpg");}| All these free backgrounds were downloaded from: https://pixabay.com/ FEATURE: The firmware has the ability to load a compressed .gz version of a file, as explained here by Ciccio... ...you should refer to the gz file with its regular name, omitting the final .gz. Example: if the original file is named picture.jpg the compressed gz version should be named
picture.jpg.gz BUT it must always be called in the program using its original name without the .gz extension. If the original file is present it will be loaded, but if the original filename is not found then the server will automatically try to send the corresponding compressed .gz version ... so in practice you can replace any file with the correspondeing compressed .gz version without any change in the code. TIP: Search for "7-zip portable" for a free archive utility which does not need to be installed and can even be run from a USB flash drive. |