Added icons library for easy in-app icons

pull/3186/head
Gordon Williams 2024-02-06 15:57:55 +00:00
parent 12412bde88
commit b97ee0a056
22 changed files with 172 additions and 0 deletions

1
apps/icons/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.01: New library

21
apps/icons/README.md Normal file
View File

@ -0,0 +1,21 @@
# Icons Library
This library contains a set of icons that might be useful in your application, as well as a chooser for those icons:
```JS
// get a list of available icons
require("icons").getIconNames()
// draw an icon
g.drawImage(require("icons").getIcon("light"),0,0);
// Allow the user to request an icon
require("icons").showIconChooser().then(function(iconName) {
console.log("User chose "+iconName);
}, function() {
console.log("User Cancelled");
});
```
To ensure the app loader auto-installs this module along with your app, just add the line
```"dependencies" : { "messageicons":"module" },``` to your `metadata.json` file.

BIN
apps/icons/app.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
apps/icons/gen/bike.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

BIN
apps/icons/gen/car.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

BIN
apps/icons/gen/close.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

BIN
apps/icons/gen/down.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

BIN
apps/icons/gen/fan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

92
apps/icons/gen/generate.js Executable file
View File

@ -0,0 +1,92 @@
#!/usr/bin/node
// Creates lib.js from icons
// npm install png-js
// Icons from https://fonts.google.com/icons
var imageconverter = require("../../../webtools/imageconverter.js").imageconverter;
var icons = JSON.parse(require("fs").readFileSync(__dirname+"/icon_names.json"));
const imgOptions = {
mode : "1bit",
inverted : true,
transparent : true,
output: "raw"
};
var PNG = require('png-js');
var IMAGE_BYTES = 76;
var iconTests = [];
var promises = [];
icons.forEach((icon,iconIndex) => {
// create image
console.log("Loading "+icon.name);
var fn = __dirname+"/"+icon.name+".png";
console.log(fn);
var png = new PNG(require("fs").readFileSync(fn));
if (png.width!=24 || png.height!=24) {
console.warn(icon.name+" should be 24x24px");
}
promises.push(new Promise(r => {
png.decode(function (pixels) {
var rgba = new Uint8Array(pixels);
var isTransparent = false;
for (var i=0;i<rgba.length;i+=4)
if (rgba[i+3]<255) isTransparent=true;
if (!isTransparent) { // make it transparent
for (var i=0;i<rgba.length;i+=4)
rgba[i+3] = 255-rgba[i];
}
imgOptions.width = png.width;
imgOptions.height = png.height;
var img = imageconverter.RGBAtoString(rgba, imgOptions);
icon.index = iconIndex;
icon.img = img;
console.log("Loaded "+icon.name);
if (img.length != IMAGE_BYTES) throw new Error("Image size should be 76 bytes");
r(); // done
});
}));
});
Promise.all(promises).then(function() {
// Allocate a big array of icons
var iconData = new Uint8Array(IMAGE_BYTES * icons.length);
icons.forEach((icon,idx) => {
iconData.set(Array.prototype.slice.call(Buffer.from(icon.img,"binary")), idx*IMAGE_BYTES)
});
console.log("Saving images");
require("fs").writeFileSync(__dirname+"/../icons.img", Buffer.from(iconData,"binary"));
console.log("Saving library");
require("fs").writeFileSync(__dirname+"/../lib.js", `
// Auto-generated by apps/icons/gen/generate.js
/// Get an icon based on a name from getIconNames that can be drawn with g.drawImage
exports.getIcon = function(name) {
let match = ${JSON.stringify(","+icons.map(icon=>icon.name+"|"+icon.index).join(",")+",")}.match(new RegExp(\`,\${name.toLowerCase()}\\\\|(\\\\d+)\`))
return require("Storage").read("icons.img", (match===null)?0:match[1]*${IMAGE_BYTES}, ${IMAGE_BYTES});
};
/// Get a list of available icon names
exports.getIconNames = function() {
return ${JSON.stringify(icons.map(i=>i.name))};
};
/// Show a menu to allow an icon to be chosen - its name is returned
exports.showIconChooser = function() {
return new Promise((resolve,reject) => {
var menu = { "" : { title : /*LANG*/"Icons", back : ()=>{E.showMenu();reject();}}}
exports.getIconNames().forEach(name => {
menu[\`\\0\${exports.getIcon(name)} \${name}\`] = ()=>{E.showMenu();resolve(name);};
});
E.showMenu(menu);
});
};
`);
});

BIN
apps/icons/gen/home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

View File

@ -0,0 +1,16 @@
[
{"name":"home"},
{"name":"bike"},
{"name":"car"},
{"name":"fan"},
{"name":"light"},
{"name":"plug"},
{"name":"rocket"},
{"name":"switch"},
{"name":"sync"},
{"name":"up"},
{"name":"down"},
{"name":"left"},
{"name":"right"},
{"name":"close"}
]

BIN
apps/icons/gen/left.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 B

BIN
apps/icons/gen/light.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 B

BIN
apps/icons/gen/plug.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

BIN
apps/icons/gen/right.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

BIN
apps/icons/gen/rocket.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 B

BIN
apps/icons/gen/switch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

BIN
apps/icons/gen/sync.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

BIN
apps/icons/gen/up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

BIN
apps/icons/icons.img Normal file

Binary file not shown.

25
apps/icons/lib.js Normal file
View File

@ -0,0 +1,25 @@
// Auto-generated by apps/icons/gen/generate.js
/// Get an icon based on a name from getIconNames that can be drawn with g.drawImage
exports.getIcon = function(name) {
let match = ",home|0,bike|1,car|2,fan|3,light|4,plug|5,rocket|6,switch|7,sync|8,up|9,down|10,left|11,right|12,close|13,".match(new RegExp(`,${name.toLowerCase()}\\|(\\d+)`))
return require("Storage").read("icons.img", (match===null)?0:match[1]*76, 76);
};
/// Get a list of available icon names
exports.getIconNames = function() {
return ["home","bike","car","fan","light","plug","rocket","switch","sync","up","down","left","right","close"];
};
/// Show a menu to allow an icon to be chosen - its name is returned
exports.showIconChooser = function() {
return new Promise((resolve,reject) => {
var menu = { "" : { title : /*LANG*/"Icons", back : ()=>{E.showMenu();reject();}}}
exports.getIconNames().forEach(name => {
menu[`\0${exports.getIcon(name)} ${name}`] = ()=>{E.showMenu();resolve(name);};
});
E.showMenu(menu);
});
};

17
apps/icons/metadata.json Normal file
View File

@ -0,0 +1,17 @@
{
"id": "icons",
"name": "Icons",
"version": "0.01",
"description": "Library containing useful icons for apps",
"icon": "app.png",
"type": "module",
"tags": "tool,system",
"supports": ["BANGLEJS","BANGLEJS2"],
"provides_modules" : ["icons"],
"default": true,
"readme": "README.md",
"storage": [
{"name":"icons","url":"lib.js"},
{"name":"icons.img","url":"icons.img"}
]
}