From 4324cbd4c1af70c59b844eb1de7d8d7b556f2dcc Mon Sep 17 00:00:00 2001 From: dapgo Date: Tue, 28 Feb 2023 12:04:00 +0100 Subject: [PATCH] helloworld compat improvements minor improvements and bjs2 --- apps/helloworld/README.md | 38 ++++-- apps/helloworld/helloworld.app.js | 219 ++++++++++++++++++++++++++++++ apps/helloworld/metadata.json | 7 +- apps/helloworld/screenshot.png | Bin 0 -> 5193 bytes apps/helloworld/ss_emul_BJS1.png | Bin 0 -> 5193 bytes apps/helloworld/ss_emul_BJS2.png | Bin 0 -> 3422 bytes 6 files changed, 253 insertions(+), 11 deletions(-) create mode 100644 apps/helloworld/helloworld.app.js create mode 100644 apps/helloworld/screenshot.png create mode 100644 apps/helloworld/ss_emul_BJS1.png create mode 100644 apps/helloworld/ss_emul_BJS2.png diff --git a/apps/helloworld/README.md b/apps/helloworld/README.md index 370ec349b..0617a9450 100644 --- a/apps/helloworld/README.md +++ b/apps/helloworld/README.md @@ -3,7 +3,6 @@ A cross cultural hello world!/hola mundo! app The most common testing sentence in several languages ;) - ## Pictures: Launcher icon @@ -14,6 +13,10 @@ Screen - Spanish ![](helloworld_es.png) +Screenshot BJS2 emul + +![](ss_emul_BJS2.png) + Screen - English ![](helloworld_en.png) @@ -22,6 +25,10 @@ Screen - Japanese ![](helloworld_jp.png) +Screenshot BJS1 emul + +![](ss_emul_BJS1.png) + ## Usage @@ -31,17 +38,32 @@ interact to change language, color or quit. ## Features -Colours, all inputs , graph, widgets loaded -Counter for Times Display + - Compatible Bangle.js1 Bangle.js2 + - Bottom Widget compatible + - Change FG/BG colors, + - Usage of many input events -## Controls +## Pending/future Features +- replace UI hardcoded colors for dynamic based on theme +- BJS2 change BTN1 from quit to Change FG Color (conflict wit setUI?) -finger swipe -button 1,2 and 3 -touch screen left, center or right + +## Controls/UI + - Left area: Back/Exit/launcher + - BTN3 (long press)(BJS1): default Exit/kill app + + - BTN1 (BJS2): Back/Exit/launcher + - BTN1 (BJS1): Change Language + - BTN2 (BJS1): Change FG Color + - BTN3 (BJS1): Quit + + - Right area: Change BG Color + - Swipe left: Change Language + - Swipe right: Change Language ## Creator -Daniel Perez \ No newline at end of file +This app is so basic that probably the easiest is to just edit the code +Otherwise you can contact me [here](https://github.com/dapgo/my_espruino_smartwatch_things) \ No newline at end of file diff --git a/apps/helloworld/helloworld.app.js b/apps/helloworld/helloworld.app.js new file mode 100644 index 000000000..1b6684f3f --- /dev/null +++ b/apps/helloworld/helloworld.app.js @@ -0,0 +1,219 @@ +//HolaMundo v202212 +// place your const, vars, functions or classes here +{ + var contador=1; + var v_mode_debug=0; + var v_model=process.env.BOARD; + + var v_color_statictxt='#b30000'; + //var v_color_b_area='#111111'; + //orange RGB format rrggbb //white,Orange,DarkGreen,Yellow,Maroon,Blue,green,Purple,cyan,olive,DarkCyan,pink + var a_colors= Array(0xFFFF,0xFD20,0x03E0,0xFFE0,0x7800,0x001F,0x07E0,0x780F,0x07FF,0x7BE0,0x03EF,0xF81F); + + var x_max_screen=g.getWidth(); + var y_max_screen=g.getHeight(); + var y_wg_bottom=g.getHeight()-25; + var y_wg_top=25; + + //EMSCRIPTEN,EMSCRIPTEN2 +if (v_model=='BANGLEJS'||v_model=='EMSCRIPTEN') { + var v_color_lines=0xFFFF; //White hex format + var v_color_text=0x07E0; + var v_font1size=10; //out of quotes + var v_font2size=12; + var v_font_banner_size=30; + var v_font3size=12; + var x_btn_area=215; + var x_max_usable_area=x_btn_area;//Pend! only for bangle.js + var y_btn2=124; //harcoded for bangle.js cuz it is not the half of display height + var graph_y=120; + var box_x2=195; + var box_y2=150; + }else{ //BJS2 + //176x176 + var v_color_lines="#000"; //White hex format + var v_color_text="#000"; + var v_font1size=9; //out of quotes + var v_font2size=9; + var v_font_banner_size=16; + var v_font3size=8; + //g.setColor("#000"); //black or dark + x_max_usable_area=176; + var graph_y=60; + var box_x2=128; + var box_y2=104; + } + if (v_mode_debug>0) console.log("device="+v_model); + var v_arraypos=0; + var v_acolorpos=0; //for fg + var v_aBGcolorPos=5; //for bg + var a_string1 = Array('hola', 'hello', 'saluton', 'ola','ciao', 'salut','czesc','konnichiwa'); + var a_string2 = Array('mundo!', 'world!', 'mondo!','mundo!','mondo!','monde!','swiat!','sekai!'); + + +} + if (v_mode_debug>0) { + console.log("*** UI dimensions***"); + console.log("x="+x_max_screen); + console.log("y_wg_bottom="+y_wg_bottom); + } + + // special function to handle display switch on + Bangle.on('lcdPower', (on) => { + if (on) { + contador=contador+1; + PrintHelloWorld(); + // call your app function here + // If you clear the screen, do Bangle.drawWidgets(); + } + }); + + //Clear/fill dynamic area except widget area, right and bottom status line + function ClearActiveArea(){ + g.setColor(a_colors[v_aBGcolorPos]); //dynamic color + g.fillRect(0,y_wg_top,box_x2,box_y2); + g.flip(); + } + + function DrawBangleButtons(){ + g.setFontVector(v_font1size); + g.setColor(v_color_lines);//White + + g.drawString("Lang", x_max_screen-g.stringWidth("Lang"),y_wg_top+v_font1size+1); + //above Btn2 + //g.setFontVector(v_font1size).drawString("Off", x_max_screen-g.stringWidth("Off"),y_btn2-(2*v_font1size)); + g.drawString("Color", x_max_screen-g.stringWidth("Color"),y_btn2-v_font1size); + //above Btn3 + g.drawString("Quit", x_max_screen-g.stringWidth("Quit"),y_wg_bottom-(2*v_font1size)); + g.flip(); + g.setColor(v_color_text); //green + g.setFontVector(v_font1size); + g.drawString("B1", x_max_screen-g.stringWidth("B1"),y_wg_top); + g.drawString("B2", x_max_screen-g.stringWidth("B2"),y_btn2); + g.drawString("B3",x_max_screen-g.stringWidth("B3"),y_wg_bottom-v_font1size); + g.flip(); +} + +function DrawBottomInfoBanner(){ +/* External Vars:v_color_text,v_font2size,x_max_usable_area,y_wg_bottom +*/ + g.setColor(v_color_text); + var info_text1="Swipe <- -> (Lang)"; + //var info_text2="Touch: Left=Up Right=Down"; + //aligned left of max usable area + g.setFontVector(v_font2size); + //g.drawString(info_text2, x_max_usable_area-g.stringWidth(info_text2)-2 ,y_wg_bottom-(2*v_font2size)); + g.drawString(info_text1, x_max_usable_area-g.stringWidth(info_text1)-2 ,y_wg_bottom-v_font2size); + g.flip(); +} + + //function Graphics.setColor(r, g, b) binary + // banglejs.com/reference#l_Graphics_setColor + + function PrintHelloWorld(){ + ClearActiveArea(); //except widgets and bottom + + if (v_mode_debug>0) console.log("drawing a "+a_string1[v_arraypos]+" "+a_string2[v_arraypos]); + + g.setColor(a_colors[v_acolorpos]); //dynamic color + g.setFont("Vector",v_font_banner_size); + g.drawString(a_string1[v_arraypos],2,55); + //line below 2nd string + g.drawLine(10, 149, 150, 149); + g.flip(); + + g.setColor(a_colors[v_acolorpos+1]); //dynamic color + g.drawString(a_string2[v_arraypos],5,85); + g.flip(); + + g.setFont("Vector",v_font3size); + g.setColor(v_color_statictxt); + g.drawString("Display on/off: "+contador ,10,box_y2+7); + //var mem=process.memory(); + //if (v_mode_debug>0) console.log("Mem free/total: "+mem.free+"/"+mem.total); + g.flip(); + } + + function PrintMainStaticArea(){ + g.setColor(v_color_statictxt); + g.setFont("Vector",v_font3size); + g.drawString("#by DPG #bangle.js",10,box_y2+5+(v_font3size*2)); + g.drawString("#javascript #espruino",10,box_y2+5+(v_font3size*3)); + + var img_obj_RedHi = { + width : 40, height : 40, bpp : 4, + transparent : 0, + buffer : require("heatshrink").decompress(atob("AFkM7vd4EAhoTNhvQhvcgHdAQIAL5oWCFIPdExo+CEoIZCABI0DhvADIZhJL4IXDHRkMEAQmOCYgmOAAIOBHwImNRQgmPHgYmCUIIXMJobfB3jgCWZJNDEga1JYQQQCMYZoJJAJNDBwgTICQPdCY7lDRQx4DVIwTIHYZzEHZATFBwblDCZRKEO5ITFWAbIJCYrHBAAImICYwEB5raKCYwAMCYXc5gADE5hLDAAgTIBJLkBBJAyKHw5hKBRJJKKJSuII5Q0IhqPKCbjRKCc4AgA==")) + } + g.drawImage(img_obj_RedHi,box_x2+2,graph_y); + g.flip(); + } + + + //inc var postion for text array + function ChangeLang(dir){ + if (v_mode_debug>0) console.log("ChangeLang, dir, Prev pos: "+dir+" , "+v_arraypos); + + if ((dir==1) && (v_arraypos0)) v_arraypos--; + else if ((dir== -1) && (v_arraypos==0)) v_arraypos=a_string1.length-1; + PrintHelloWorld(); + } + + //inc var postion for color array + function ChangeColor(){ + //if (v_mode_debug>0) console.log("ChangeColor, colpos: "+v_acolorpos); + if (v_acolorpos { + if(dir == 1) ChangeLang(1); //right + else ChangeLang(-1); //left + }); + } + + if (v_mode_debug>0) console.log("**************************"); + if (v_mode_debug>0) console.log("Log: *** hola mundo app"); + g.clear(); + Bangle.loadWidgets(); + Bangle.drawWidgets(); + Bangle.setUI({ + mode : "custom", + back : function() {load();} + }); + if (v_model=='BANGLEJS'||v_model=='EMSCRIPTEN') DrawBangleButtons(); + DrawBottomInfoBanner(); + UserInput(); + PrintMainStaticArea(); + PrintHelloWorld(); + \ No newline at end of file diff --git a/apps/helloworld/metadata.json b/apps/helloworld/metadata.json index b8fe1b1e3..b9dec6b52 100644 --- a/apps/helloworld/metadata.json +++ b/apps/helloworld/metadata.json @@ -2,14 +2,15 @@ "id": "helloworld", "name": "hello, world!", "shortName": "hello world", - "version": "0.02", + "version": "0.03", "description": "A cross cultural hello world!/hola mundo! app with colors and languages", "icon": "app.png", "tags": "input,interface,buttons,touch", - "supports": ["BANGLEJS"], + "screenshots": [{"url":"screenshot.png"}], + "supports": ["BANGLEJS","BANGLEJS2"], "readme": "README.md", "storage": [ - {"name":"helloworld.app.js","url":"app.js"}, + {"name":"helloworld.app.js","url":"helloworld.app.js"}, {"name":"helloworld.img","url":"app-icon.js","evaluate":true} ] } diff --git a/apps/helloworld/screenshot.png b/apps/helloworld/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..32cbd4ff37148d772cff92ea25ea5646aabab4d2 GIT binary patch literal 5193 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