-
-
I guess you refer to the line
g.setTheme({bg:"#f0f",fg:"#fff",dark:true}).clear();
This is actually an variant I tried before - and it is not working!
If background is globally set to green, f.e., it remains green even after that line!
In order to give you some steps to reproduce the problem (in the REPL):
Try
let customTheme = { fg:g.toColor(0,0,0), fg2:g.toColor(0,0,1), fgH:g.toColor(0,0,0), bg:g.toColor(0,1,0), bg2:g.toColor(0,1,0), bgH:g.toColor(1,1,0) }; let globalSettings = Object.assign( require('Storage').readJSON('setting.json', true) || {}, { theme:customTheme } ); require('Storage').writeJSON('setting.json', globalSettings);
first, then try
g.setTheme({ bg:'#000' }); g.clear(false);
(tested on a real device with firmware 2v11)
-
-
The attached screenshot illustrates what I expected - but I reached that state with a custom renderer only:
/**** Label ****/ function Label (Text, Options) { function renderLabel (Details) { let halfWidth = Details.w/2, xAlignment = Details.halign || 0; let halfHeight = Details.h/2, yAlignment = Details.valign || 0; let Padding = Details.pad || 0; g.setColor(Details.col || g.theme.fg || '#000000'); if (Details.font != null) { g.setFont(Details.font); } g.setFontAlign(xAlignment,yAlignment); g.drawString(Details.label, Details.x + halfWidth + xAlignment*(halfWidth+Padding), Details.y + halfHeight + yAlignment*(halfHeight+Padding) ); } let Result = Object.assign({}, Options || {}, { type:'custom', render:renderLabel, label:Text || '' }); let TextMetrics if (! Options.width || ! Options.height) { if (Options.font != null) { g.setFont(Options.font); } TextMetrics = g.stringMetrics(Result.label); } Result.width = Options.width || TextMetrics.width + 2*(Options.pad || 0); Result.height = Options.height || TextMetrics.height + 2*(Options.pad || 0); return Result; }
Here is a simple "smoke test" for the above "component":
let ScreenWidth = g.getWidth(), ColumnWidth = ScreenWidth/3; // 3 columns let ScreenHeight = g.getHeight(), RowHeight = ScreenHeight/3; // and 3 rows g.clear(true); /**** Label ****/ function Label (Text, Options) { function renderLabel (Details) { let halfWidth = Details.w/2, xAlignment = Details.halign || 0; let halfHeight = Details.h/2, yAlignment = Details.valign || 0; let Padding = Details.pad || 0; g.setColor(Details.col || g.theme.fg || '#000000'); if (Details.font != null) { g.setFont(Details.font); } g.setFontAlign(xAlignment,yAlignment); g.drawString(Details.label, Details.x + halfWidth + xAlignment*(halfWidth+Padding), Details.y + halfHeight + yAlignment*(halfHeight+Padding) ); } let Result = Object.assign({}, Options || {}, { type:'custom', render:renderLabel, label:Text || '' }); let TextMetrics if (! Options.width || ! Options.height) { if (Options.font != null) { g.setFont(Options.font); } TextMetrics = g.stringMetrics(Result.label); } Result.width = Options.width || TextMetrics.width + 2*(Options.pad || 0); Result.height = Options.height || TextMetrics.height + 2*(Options.pad || 0); return Result; } g.setFont12x20(); // does not seem to be respected in layout! let Layout = require('Layout'); let Display = new Layout({ type:'v', c:[ { type:'h', c:[ Label('Test',{ valign:-1, halign:-1, font:'12x20', width:ColumnWidth, height:RowHeight }), Label('Test',{ valign:0, halign:-1, font:'12x20', width:ColumnWidth, height:RowHeight }), Label('Test',{ valign:1, halign:-1, font:'12x20', width:ColumnWidth, height:RowHeight }), ] }, { type:'h', c:[ Label('Test',{ valign:-1, halign:0, font:'12x20', width:ColumnWidth, height:RowHeight }), Label('Test',{ valign:0, halign:0, font:'12x20', width:ColumnWidth, height:RowHeight }), Label('Test',{ valign:1, halign:0, font:'12x20', width:ColumnWidth, height:RowHeight }), ] }, { type:'h', c:[ Label('Test',{ valign:-1, halign:1, font:'12x20', width:ColumnWidth, height:RowHeight }), Label('Test',{ valign:0, halign:1, font:'12x20', width:ColumnWidth, height:RowHeight }), Label('Test',{ valign:1, halign:1, font:'12x20', width:ColumnWidth, height:RowHeight }), ] }, ] }); Display.render();
(the "Label" component is part of my Bangle.js 2 activities as documented on GitHub)
-
While global settings may not include an explicit configuration for a global theme, you may still set one which is from then on respected in any apps (unless they override any theme settings):
let customTheme = { fg:g.toColor(0,0,0), fg2:g.toColor(0,0,1), fgH:g.toColor(0,0,0), bg:g.toColor(0,1,0), bg2:g.toColor(0,1,0), bgH:g.toColor(1,1,0) }; let globalSettings = Object.assign( require('Storage').readJSON('setting.json', true) || {}, { theme:customTheme } ); require('Storage').writeJSON('setting.json', globalSettings);
It is important, however, that you use
g.toColor
in order to get the proper color values for the Bangle.js 2! -
-
Strange,
according to the docs, I should be able to define a (local) theme using
g.setTheme({ bg:'#00FF00' }); g.clear(false); // to test the new theme
but that does not seem to be respected. Indeed, none of the alternatives I tried had any effect:
g.setTheme({ bg:'#0F0' }); // g.setTheme({ bg:'#00FF00' }); // g.setTheme({ bg:0x00FF00 }); // g.setTheme({ bg:g.toColor(0,1,0) }); g.clear(false);
What am I doing wrong?
-
I know that I can find the current general settings using
let Settings = require('Storage').readJSON('setting.json', true) || {}; print('Settings',Settings);
but where do I find details of the currently configured theme?
The documentation tells us to look into a file called
settings.js
which sounds strange on one hand and does not exist on the other... -
Is there any possibility to align some text within its cell when using the layout library?
halign
andvalign
don't seem to be respected as you can see yourself by running the following example:let ScreenWidth = g.getWidth(), ColumnWidth = ScreenWidth/3; // 3 columns let ScreenHeight = g.getHeight(), RowHeight = ScreenHeight/3; // and 3 rows g.clear(true); let Layout = require('Layout'); let Display = new Layout({ type:'v', c:[ { type:'h', c:[ { type:'txt', font:'12x20', label:'Test', valign:-1, halign:-1, width:ColumnWidth, height:RowHeight }, { type:'txt', font:'12x20', label:'Test', valign:0, halign:-1, width:ColumnWidth, height:RowHeight }, { type:'txt', font:'12x20', label:'Test', valign:1, halign:-1, width:ColumnWidth, height:RowHeight }, ] }, { type:'h', c:[ { type:'txt', font:'12x20', label:'Test', valign:-1, halign:0, width:ColumnWidth, height:RowHeight }, { type:'txt', font:'12x20', label:'Test', valign:0, halign:0, width:ColumnWidth, height:RowHeight }, { type:'txt', font:'12x20', label:'Test', valign:1, halign:0, width:ColumnWidth, height:RowHeight }, ] }, { type:'h', c:[ { type:'txt', font:'12x20', label:'Test', valign:-1, halign:1, width:ColumnWidth, height:RowHeight }, { type:'txt', font:'12x20', label:'Test', valign:0, halign:1, width:ColumnWidth, height:RowHeight }, { type:'txt', font:'12x20', label:'Test', valign:1, halign:1, width:ColumnWidth, height:RowHeight }, ] }, ] }); Display.render();
-
For those interested: while playing around with theming, I made the following theme display
let ScreenWidth = g.getWidth(), CenterX = ScreenWidth/2; let ScreenHeight = g.getHeight(); g.reset(); // automatically loads current theme g.clearRect(0,0, ScreenWidth,ScreenHeight); g.setFont12x20(); g.setFontAlign(0,-1); g.drawString('current Theme', CenterX,0); g.setFontAlign(-1,-1); let Theme = g.theme; g.setColor(Theme.fg); g.drawString('fg', 0,35); g.drawString('bg', CenterX,35); g.drawString('fg2', 0,70); g.drawString('bg2', CenterX,70); g.drawString('fgH', 0,105); g.drawString('bgH', CenterX,105); g.drawString('dark', 0,140); g.setColor(Theme.fg); g.fillRect(40,35, 70,55); g.setColor(Theme.fg); g.drawRect(CenterX+39,34, CenterX+71,56); g.setColor(Theme.bg); g.fillRect(CenterX+40,35, CenterX+70,55); g.setColor(Theme.fg2); g.fillRect(40,70, 70,90); g.setColor(Theme.fg); g.drawRect(CenterX+39,69, CenterX+71,91); g.setColor(Theme.bg2); g.fillRect(CenterX+40,70, CenterX+70,90); g.setColor(Theme.fgH); g.fillRect(40,105, 70,125); g.setColor(Theme.fg); g.drawRect(CenterX+39,104, CenterX+71,126); g.setColor(Theme.bgH); g.fillRect(CenterX+40,105, CenterX+70,125); g.setColor(Theme.fg); g.drawString(Theme.dark ? 'yes' : 'no', 50,140);
-
I might have found a solution:
- at first, connect using the Web IDE
- then, in another window, open the App Loader and connect (the Web IDE will show you any responses from the watch)
- upgrade any outdated apps (e.g., Settings, Bootloader etc.) and/or delete an old/install a new application
From then on, everything seems to work fine again - but don't ask me why!
- at first, connect using the Web IDE
-
-
I just updated my Bangle.js 2 to firmware 2v11 - but now, the app loader no longer allows me to do anything. Since the error messages ("toasts") disappear after a few seconds (could that be changed, please!), I had to look into the browser debug console for more information. Here is what I found there:
Chosen device BANGLEJS2 puck.js:406 <BLE> Device Name: Bangle.js 8636 puck.js:406 <BLE> Device ID: C6uV/VXV/s05Mi2CwS5cWw== puck.js:406 <BLE> Connected comms.js:151 <COMMS> Ctrl-C gave "\r\u001b[J let date=new Date();g.reset();g.clearRect(0,24,239,239);g.setColor...\r\n ^\r\ndebug>" comms.js:186 <COMMS> ERROR Parsing JSON SyntaxError: Unexpected token I in JSON at position 0 comms.js:187 <COMMS> Actual response: "In debug mode: Expected a simple ID, type 'help' for more info.\r" ui.js:86 <TOAST>[error] Device connection failed, Invalid JSON puck.js:406 <BLE> Disconnected (gattserverdisconnected) comms.js:260 <COMMS> removeAllApps start puck.js:406 <BLE> Device Name: Bangle.js 8636 puck.js:406 <BLE> Device ID: C6uV/VXV/s05Mi2CwS5cWw== puck.js:406 <BLE> Connected comms.js:265 <COMMS> removeAllApps: received "In debug mode: Expected a simple ID, type 'help' for more info.\r" ui.js:86 <TOAST>[error] App removal failed, Got "In debug mode: Expected a simple ID, type 'help' for more info." 2puck.js:406 <BLE> Disconnected (gattserverdisconnected) puck.js:406 <BLE> Device Name: Bangle.js 8636 puck.js:406 <BLE> Device ID: C6uV/VXV/s05Mi2CwS5cWw== puck.js:406 <BLE> Connected comms.js:151 <COMMS> Ctrl-C gave "" puck.js:406 <BLE> SEND ERROR: NotSupportedError: GATT operation failed for unknown reason. 2puck.js:406 <BLE> Disconnected (gattserverdisconnected) comms.js:265 <COMMS> removeAllApps: received null puck.js:406 <BLE> Disconnected (gattserverdisconnected) ui.js:86 <TOAST>[error] App Install failed,
Basically, the watch claims to be "in debug mode" which is why the App Loader does not get the expected JSON.
If I connect to the watch using the Web IDE and then type "help" into its left side, I get the response
"help" is not defined
:>help Uncaught ReferenceError: "help" is not defined at line 1 col 1 help ^
I already reset my smartwatch several times, without any luck.
-
-
-
I'm currently developing clock faces with a black background.
Since clocks should respect any installed widgets, my clock also draws them - however, most widgets seem to expect a white background and look ugly (if not unrecognizable) on a black one.
Does anybody have an idea how to enhance the look of such widgets?
-
...although it may just be a mistake in the documentation - but it took me surprisingly long to find that out.
From the documentation of E.HSBtoRGB, you might be tempted to write
let Color = E.HSBtoRGB(i/Steps,1,1, true); g.setColor(Color[0],Color[1],Color[2]);
but this is wrong! You have to write
let Color = E.HSBtoRGB(i/Steps,1,1, true); g.setColor(Color[0]/255,Color[1]/255,Color[2]/255);
instead in order to get the expected results!
(Please note: you cannot simply write
let Color = E.HSBtoRGB(i/Steps,1,1); g.setColor(Color);
as the Bangle.js 2 does not support 24-bit color)
(see GitHub for some examples)
-
I've started documenting my Bangle.js 2 "activities" on GitHub - this may be a better place for small code snippets than this forum...
-
-
...now available on my personal App Loader (look for "ColorWheel") and - hopefully - soon on the official one as well.
-
...and here is the same in a touchable version:
//----------------------------------------------------------------------------// //-- ColorWheel - draws a "wheel" of good looking colors --// //----------------------------------------------------------------------------// let ColorList = [ '#0000FF', '#8000FF', '#FF00FF', '#FF0080', '#FF0000', '#FF8000', '#FFFF00', '#80FF00', '#00FF00', '#00FF80', '#00FFFF', '#0080FF' ]; let ScreenWidth = g.getWidth(), CenterX = ScreenWidth/2; let ScreenHeight = g.getHeight(), CenterY = ScreenHeight/2; let outerRadius = Math.min(CenterX,CenterY) * 0.9; let innerRadius = outerRadius*0.5; let sin = Math.sin, cos = Math.cos; let twoPi = 2*Math.PI, halfPi = Math.PI/2; let DeltaPhi = twoPi/72; let Epsilon = 0.001; g.clear(); g.setColor(0,0,0); g.fillRect(0,0, ScreenWidth,ScreenHeight); for (let i = 0; i < 12; i++) { let Phi0 = i * twoPi/12, Phi1 = (i+1) * twoPi/12; let Polygon = []; for (let Phi = Phi0; Phi <= Phi1+Epsilon; Phi += DeltaPhi) { Polygon.push(CenterX + outerRadius * sin(Phi)); Polygon.push(CenterY - outerRadius * cos(Phi)); } for (let Phi = Phi1; Phi >= Phi0-Epsilon; Phi -= DeltaPhi) { Polygon.push(CenterX + innerRadius * sin(Phi)); Polygon.push(CenterY - innerRadius * cos(Phi)); } g.setColor(ColorList[i]); g.fillPoly(Polygon); } g.setColor(1,1,1); g.fillCircle(CenterX,CenterY, innerRadius); g.setFont12x20(); g.setFontAlign(0,0); g.setColor(0,0,0); g.drawString('Tap', CenterX,CenterY-20); g.drawString('on', CenterX,CenterY); g.drawString('Color', CenterX,CenterY+20); Bangle.on('touch', function (Button,Position) { Bangle.buzz(); let dx = Position.x - CenterX; let dy = Position.y - CenterY; let Radius = Math.sqrt(dx*dx + dy*dy); let Color; switch (true) { case (Radius > outerRadius): Color = '#000000'; break; case (Radius < innerRadius): Color = '#FFFFFF'; break; default: let Phi = Math.atan2(dy,dx) + halfPi; if (Phi < 0) { Phi += twoPi; } if (Phi > twoPi) { Phi -= twoPi; } let Index = Math.floor(12*Phi/twoPi); Color = ColorList[Index]; } g.setColor(1,1,1); g.fillCircle(CenterX,CenterY, innerRadius); g.setColor(0,0,0); g.drawString(Color, CenterX,CenterY); });
-
...now available on my personal App Loader (look for "ColorWheel") and - hopefully - soon on the official one as well.
-
...and here is the same in a touchable version:
let ColorList = [ '#0000FF', '#8000FF', '#FF00FF', '#FF0080', '#FF0000', '#FF8000', '#FFFF00', '#80FF00', '#00FF00', '#00FF80', '#00FFFF', '#0080FF' ]; let ScreenWidth = g.getWidth(), CenterX = ScreenWidth/2; let ScreenHeight = g.getHeight(), CenterY = ScreenHeight/2; let outerRadius = Math.min(CenterX,CenterY) * 0.9; let innerRadius = outerRadius*0.5; let sin = Math.sin, cos = Math.cos; let twoPi = 2*Math.PI, halfPi = Math.PI/2; let DeltaPhi = twoPi/72; let Epsilon = 0.001; g.clear(); g.setColor(0,0,0); g.fillRect(0,0, ScreenWidth,ScreenHeight); for (let i = 0; i < 12; i++) { let Phi0 = i * twoPi/12, Phi1 = (i+1) * twoPi/12; let Polygon = []; for (let Phi = Phi0; Phi <= Phi1+Epsilon; Phi += DeltaPhi) { Polygon.push(CenterX + outerRadius * sin(Phi)); Polygon.push(CenterY - outerRadius * cos(Phi)); } for (let Phi = Phi1; Phi >= Phi0-Epsilon; Phi -= DeltaPhi) { Polygon.push(CenterX + innerRadius * sin(Phi)); Polygon.push(CenterY - innerRadius * cos(Phi)); } g.setColor(ColorList[i]); g.fillPoly(Polygon); } g.setColor(1,1,1); g.fillCircle(CenterX,CenterY, innerRadius); g.setFont12x20(); g.setFontAlign(0,0); g.setColor(0,0,0); g.drawString('Tap', CenterX,CenterY-20); g.drawString('on', CenterX,CenterY); g.drawString('Color', CenterX,CenterY+20); Bangle.on('touch', function (Button,Position) { let dx = Position.x - CenterX; let dy = Position.y - CenterY; let Radius = Math.sqrt(dx*dx + dy*dy); let Color; switch (true) { case (Radius > outerRadius): Color = '#000000'; break; case (Radius < innerRadius): Color = '#FFFFFF'; break; default: let Phi = Math.atan2(dy,dx) + halfPi; if (Phi < 0) { Phi += twoPi; } if (Phi > twoPi) { Phi -= twoPi; } let Index = Math.floor(12*Phi/twoPi); Color = ColorList[Index]; } g.setColor(1,1,1); g.fillCircle(CenterX,CenterY, innerRadius); g.setColor(0,0,0); g.drawString(Color, CenterX,CenterY); });
-
In the last few days, the thread Graphics Color questions has been hijacked for several small example programs related to several..."graphics color questions".
In order to simplify finding more specific solutions, I've started a new thread for the following example, namely:
a small color wheel using colors with "full" (0 and 1) and "half" (0.5) values
let ColorList = [ '#0000FF', '#8000FF', '#FF00FF', '#FF0080', '#FF0000', '#FF8000', '#FFFF00', '#80FF00', '#00FF00', '#00FF80', '#00FFFF', '#0080FF' ]; let ScreenWidth = g.getWidth(), CenterX = ScreenWidth/2; let ScreenHeight = g.getHeight(), CenterY = ScreenHeight/2; let outerRadius = Math.min(CenterX,CenterY) * 0.9; let innerRadius = outerRadius*0.5; let sin = Math.sin, cos = Math.cos; let twoPi = 2*Math.PI; let DeltaPhi = twoPi/72; let Epsilon = 0.001; g.clear(); g.setColor(0,0,0); g.fillRect(0,0, ScreenWidth,ScreenHeight); for (let i = 0; i < 12; i++) { let Phi0 = i * twoPi/12, Phi1 = (i+1) * twoPi/12; let Polygon = []; for (let Phi = Phi0; Phi <= Phi1+Epsilon; Phi += DeltaPhi) { Polygon.push(CenterX + outerRadius * sin(Phi)); Polygon.push(CenterY - outerRadius * cos(Phi)); } for (let Phi = Phi1; Phi >= Phi0-Epsilon; Phi -= DeltaPhi) { Polygon.push(CenterX + innerRadius * sin(Phi)); Polygon.push(CenterY - innerRadius * cos(Phi)); } g.setColor(ColorList[i]); g.fillPoly(Polygon); }
Hopefully it will help you finding proper good-looking colors
...I can't find one in the reference - but the layout library draws such rectangles around buttons.