-
That sounds like a fantastic idea! I don't have ADHD but I'd love to use that app, I could load it with all the things my wife asks me to do and which I almost instantly forget! Thank you for the example of reminding yourself to eat, you reminded me that we don't all think in the same way, personally I never forget to eat, quite the opposite I'm often thinking about my next meal!
The task queue with priority sounds great too, currently I might set an alarm to remind me of something, but that's not easy to add multiple things to, and the alarm by definition only goes off at a set time. An occasionally gentle reminder sounds like a better solution.
Brilliant use of tech to help you out, and nice to see the commercial option you linked, I'm sure you'll be able to make something that works better!
-
It's a fantastic ecosystem, Gordon has done a smashing job with it! And there is a lot of helpful things out there. When I made my first app I laboriously laid it out by hand, only afterwards did I discover the layout library which made it much easier!
If the keyboard you've made is your avatar, I also thought it looked similar to the multi-tap keyboard (you may see a familiar name listed under authors in the readme!)
Using the real device is quite different from the emulator, but please do a comparison when you get your hands on it. If your keyboard works better you can always make changes to the multi-tap keyboard so that everyone can benefit from your improvements, or as you say release a separate keyboard app that suits your needs better. That's one of the joys of open-source, it's up to you.
But that's only the keyboard section, do you mind if I'm nosy and ask what the rest of your app does?
-
Well done for solving your problem! Not sure if you're aware, but there's a whole selection of keyboards available for the JS2: https://banglejs.com/apps/?c=textinput
Details of how to use them in your own app here: https://github.com/espruino/BangleApps/tree/master/apps/kbtouch
You might want to repackage your keyboard as a separate app so others can use it, or give people a choice of which keyboard they use to interact with your app.
-
Great news that the font is available with a 'very permissive' license (having read the license I see why you didn't spell it out here!) Very glad to see that others also think Renaissance would be a suitable font.
I don't know enough about how Espruino works with fonts to comment on a new font renderer, or packaging. Since some of the Renaissance fonts are bold though it would be nice to be able to use that. Since they're already packaged up as PBF files could we use them directly? Would people be able to make new fonts in the same format?
In terms of how we use the fonts, I'd be happy specifying the font and size directly, especially if there was a wiki page or tutorial with examples of the different fonts and sizes. Alternatively listing them as
tiny
,small
,medium
andlarge
would be quite user friendly, but I think having the size in the name is more useful.I really like Gordon's idea of working out the best size of font to fit the text in a space, I agree it would be great for messages. I'm actually less keen on letting the Bangle pick the 'best' font size in other situations though, I already find it slightly odd that menu items can have 2 sizes of font, I can imagine some very strange looking screens with multiple different sized bits of text looking very messy.
-
I just bodged something up
Fabulous, thanks Gordon! Your bodges look like finely honed works of art next to mine!
At first glance these look promising, some of the characters have gone a bit wonky, but very readable in the emulator and on a JS2.
Using an existing font has got to be easier than designing a new one (or multiple for different sizes) from scratch, question is are we happy to do that?
Also, is it possible to adjust the spacing between letters? When I made the mockup above I thought it was much more readable with just an extra pixel of space between each letter.
-
I like the sound of new fonts, particularly a nice range of sizes. typically I use the Vector font, it's easy to use for large sizes though not as good for small text. It would be nice to have the option for Bold text too.
Just for reference, here is the font that the Pebble watches used, and the reason they used it:Raster Gothic Condensed is the font used throughout the Pebble system, largely because it is optimized for monochromatic displays. Pebble selected this font because it allows a relatively large number of characters to be displayed on a single line, also because the font has an excellent readability vs. size ratio.
This is a paid for font, but the Rebble team has had a go at making a similar font and releasing it on Github: https://github.com/pebble-dev/renaissance
Unfortunately the fonts are only in pbf format, which I would try, but can't get to convert using the Espruino Font Converter. Does anyone know how I could get these fonts into the Bangle?
EDIT: Manually pasted the letters as Gordon did above, the bottom 2 rows are Renaissance 24 and Renaissance 18. -
Thanks for your suggestions Gordon, I tried them all, but in the end redrawing the entire screen was too slow to look good. Your
g.scroll
andg.drawImages
solution was the best, but moved the widgets as well which wasn't ideal.
I've abandoned the idea of a general function to wipe to a different screen, and opened https://github.com/espruino/BangleApps/pull/2547 with the much simpler solution of just clearing the screen and redrawing the text for this clock. I'll have to come up with some more imaginative animations for my other clocks! -
I'm going to jump to the BangleJS2 defence :-)
It all depends what you want, and what you expect from a smartwatch. I've had several, and while the Pebble Time Steel was by far the best, the BangleJS2 comes a close second, and thanks to the efforts of Gordon and the community keeps improving.
I won't argue every point, but recent improvements, with fastloading, hiding widgets, speed improvements, etc. have made such a big difference it's now a very usable watch, for me.
One thing that's made a huge difference with the usability of the touchscreen, new in 2v16, is the touchscreen calibration in the settings menu. If you haven't done it yet I highly recommend it! No more stabbing around, it's now precise and reliable.
-
So now I've got colours working correctly (thanks again Hal and Gordon), I need to work on speed. See code below, but in the emulator, doing a full screen wipe takes ~6ms/frame. Exactly the same on the actual B2 takes ~228ms/frame, i.e. very very slow.
Is there anything I can do to speed this up, or is that just how long it takes to draw the whole screen? Doing only part of the screen definitely speeds things up, but not enough to look smooth.
let colormap={ 0: 0, 31: 1, 2016: 2, 2047: 3, 63488: 4, 63519: 5, 65504: 6, 65535: 7 }; let palette = new Uint16Array([ g.toColor("#000"), g.toColor("#00f"), g.toColor("#0f0"), g.toColor("#0ff"), g.toColor("#f00"), g.toColor("#f0f"), g.toColor("#ff0"), g.toColor("#fff"), 0,0,0,0,0,0,0,0 ]); let animInterval; let time_array = [] let animate = function(step) { if (animInterval) clearInterval(animInterval); slideX = -R.w; animInterval = setInterval(function() { let time_start = getTime() slideX += step; let stop = false; if (slideX>=0) { slideX=0; stop = true; } g.drawImage(g2img, slideX, R.y); if (stop) { clearInterval(animInterval); animInterval=undefined; print(time_array) print(time_array.reduce((a, b) => a + b, 0) / time_array.length) } time_array.push(Math.round((getTime() - time_start)*1000)) }, 20); }; Bangle.loadWidgets(); Bangle.drawWidgets(); let R = Bangle.appRect; // R.h = 50 let g2 = Graphics.createArrayBuffer(R.w * 2, R.h, 4, {msb:true}); let g2img = { width:g2.getWidth(), height:g2.getHeight(), bpp:4, buffer:g2.buffer, palette: palette }; g2.setBgColor(colormap[g.theme.bg]); g2.setColor(colormap[g.theme.fg]); g.setBgColor("#F00").clearRect(R); g.setColor("#0F0").setFont('Vector:15').setFontAlign(0, 0).drawString("OLD SCREEN", R.w/2, R.h/2); let screengrab = g.asImage(); g2.drawImage(screengrab, R.w - R.x, -R.y); g2.clearRect(R); g2.setFont('Vector:15').setFontAlign(0, 0).drawString("NEW SCREEN", R.w/2, R.h/2); animate(4);
-
-
Thanks for your help @halemmerich, that does work, but I agree it feels like there could be a simpler solution.
Searching for 'BPP' in the forum (should have done that before I posted, sorry), shows quite a few people have had a similar problem.
It all seems to stem fromg.asImage()
giving a 3 bpp buffer, but if I try tocreateArrayBuffer
with 3 bpp it says:Uncaught Error: Invalid BPP
. -
Hi All,
I'm hoping someone can help me understand BPP better. I'm testing out a simple animation, based on the Slope Clock, to slide the current contents of the screen off, and show a new screen. I've had this running in the emulator, but some of the colours are wrong.It should show BLACK text (wibble) on GREEN, then replace it with WHITE text (flibble) on RED.
When I take a screenshot of the screen withg.asImage
, and put it in the image buffer withdrawImage
, the colour changes from GREEN to BLUE.I'm sure it's a simple fix somewhere, but I'm stuck!
This is the code I've been trying:
let g2 = Graphics.createArrayBuffer(g.getWidth() * 2, g.getHeight(), 8, {msb:true}); let g2img = { width:g2.getWidth(), height:g2.getHeight(), bpp:8, buffer:g2.buffer }; let R = Bangle.appRect; let x = R.w / 2; let y = R.y + R.h / 2; let animInterval; let animate = function(step) { if (animInterval) clearInterval(animInterval); slideX = -g2.getWidth()/2; animInterval = setInterval(function() { slideX += step; let stop = false; if (slideX>=0) { slideX=0; stop = true; } g.drawImage(g2img, slideX, 0); if (stop) { clearInterval(animInterval); animInterval=undefined; } }, 50); }; g.reset().setBgColor("#0f0").clearRect(R); // clear whole background g.setFontAlign(0, 0).setFont("Vector:30").drawString("WIBBLE", g.getWidth()/2, g.getHeight()/2); let screengrab = g.asImage(); // Draw to offscreen buffer g2.setColor("#f00").fillRect(0,0,g2.getWidth(),g2.getHeight()); g2.setColor("#fff").setFontAlign(0, 0).setFont("Vector:30").drawString("FLIBBLE", g2.getWidth()/4, g2.getHeight()/2); g2.drawImage(screengrab, g2.getWidth()/2, 0); animate(3);
-
Thank you Gordon for taking the time to explain that. I think I understand slightly better now. I will try and work with the current system, and if that doesn't work run it from my own app loader. I haven't had time recently to work on this but hope to get back to it soon.
The thing I really want to avoid is going in a different direction that can't be merged in!
-
Yeah, it's a bit complicated :-(
I agree that breaking out the message library functions would be a good idea. My problem with using the message app to pass events on to a custom app, is that the message app still shows as installed, and listed in the launcher. I think this would confuse users.
Thank you @Rarder44, I've been thinking similar things.
Is there anything eslse we could do to make it less complicated? Ignoring for a moment what we already have, what would be the best way to handle communications? Do we even need a message library if we change to firing events rather than importing
message
? -
I'm glad you said that, it sounds like you want similar things to me! You might want to check out my Messages Notification app (you should also install Notifications Overlay.)
They aren't finished yet, I need to get back and finish them off, but should be more like you want.
Features:
- Instant (ish), full text notification in a scrollable message.
- No message storage. You see it when the message arrives, then it's gone.
- Customisable font size!
Snags:
- No notifications for calls yet
- Weird colours, highlight should be blue but is actually green?
- Slow for large notifications, like email
- Needs cutting edge firmware, not previous stable firmware.
- Gets overwritten by standard Messages app if you update the Android app.
- Doesn't block events to app underneath yet.
Looking at that list, you may not want to try it yet, but I'll work on it and announce here when it's ready!
- Instant (ish), full text notification in a scrollable message.
-
Fab, thanks @rigrig! Looks good, I'll give it a go.
-
Would this be a good time to mention the Hidable Widget Bar? I haven't tried it with this fast app switching yet, but I can't see why it wouldn't work.
Would it be helpful to add some settings? Always Show Widgets, Always Hide Widgets, Swipe to show or hide? Or pick a gesture to show and hide? I have no idea how to make it a library though! -
Hello awesome Banglers!
I have a couple of projects on the go, Hiding the widget bar in an overlay, and Pop up notifications in an overlay, both usingBangle.SetLCDOverlay
. I'm having trouble with swipes and drags. I can set a new event handler to move the overlay, but the clock face or app underneath also reacts to the swipe or drag.Is there a way to block or clear existing events, e.g.
Bangle.on('swipe'...)
, use my customswipe
handler, then clear my custom handler and put the previous one back? -
Thank you @Gordon, I think I understand now. I will leave the
Android
andiOS
apps alone, make a new app that replacesmessages
with my own code. This means I won't break anything in the Android app, or anything in the message app, which I was a bit worried about.Changing the
"type":"messages"
sounds useful, if it can be fixed to show up in the launcher.So @rigrig, thanks for looking into it, but don't worry about making any changes to your
smessages
app on my account, since I'll be replacing it anyway.Sorry for causing confusion!
As for speed, in my tests so far I have a bit of boot code that listens for a message and shows a notification. It feels instant, certainly fast enough. I think it's just avoiding launching a whole app and waiting for the 'Loading...' screen to pass that takes the time. I'll avoid tweaks that would reduce battery life, that's one of the best things about the Bangle!
-
I'm confused, let me try and explain more what I'm trying to do.
My use case for notifications on the Bangle is to see if it's something I need to do immediately, or if it will keep. When I hear the bing on the phone, or feel the buzz of the bangle, I can look at the Bangle, read the whole message, ideally as much text as possible without having to touch the screen. Then, I can ignore it, wait for it to time out or manually dismiss it, or if it's something I need to do something about, I go to the phone.
I can see that the new messages app will be great, but I'd like something much, much simpler: no storage, no responses, no widget, just very fast and clear text.
So the idea to put a switch in the Android app (and match it in the iOS app) to emit a signal, check if it's handled in a custom app, launch the Messages app if it is not handled, sounds ideal to me. As a bonus, it creates a way for anyone to make custom apps that tie into messages, or music, or calls, but the standard Messages will still load for everyone by default.
I'll try making the changes to make the Android/ios app emit messages. If I do it correctly, it won't make any difference to anyone else. If it turns out to be a terrible idea I won't submit it to be merged, but I'd like to try.
-
Thanks for your input everyone.
I agree that we shouldn't duplicate code, I only made my own version rather than changed the Android app so I could go back to the standard one if I needed to (i.e. when I mucked it up!).
The Overlay Notification is coming together well, at least well enough for a first version.
I really like the idea of adding something that a custom app can tie into, but would fall back on the default if nothing is there.
Let me see if I understand @rigrig's idea:
- A message is sent from Gadgetbridge to the Bangle
- The Android app receives the Gadgetbridge message
- The Android app emits a signal saying it has a new message.
THEN - A custom app acts on the signal, doing whatever it does.
- The Android app sees that something acted on the signal, and does nothing else.
OR - Nothing receives the signal
- The Android app sees that nothing acted on the signal, and launches the default app.
I'll have a go at incorporating that into the Android app code and trying it!
- A message is sent from Gadgetbridge to the Bangle
-
Thank you Ganblejs!
I've now got a solution, it isn't quite as smooth but does at least work.
Create a temporary image, the size of the display, use drawImage to draw a section of the large image to that, then display the temperoary image with setLCDOverlay:var temp_img = Graphics.createArrayBuffer(g.getWidth(), g.getHeight(), 8); var y_pos = 0; function onDrag(e) { y_pos += e.dy; temp_img.drawImage(img, 0, y_pos); Bangle.setLCDOverlay(temp_img, 0, 0); }
-
Thank you Ganble, you're right it's not an issue with integers! You can probably tell I'm only a very amateur programmer!
In that case,
setLCDOverlay
doesn't work with negative numbers, but this time I have no idea why.An example run in the emulator (same results on watch):
img = Graphics.createArrayBuffer(100, 100, 8).setColor('#f00').fillRect(0, 0, 100, 100); var y = 0; Bangle.setLCDOverlay(img, 0, y);
Draw a 100px square, colour it red, display in on the overlay. Negative number doesn't work, see third screenshot of blank screen.
By contrast,
g.drawImage(img, 0, y);
does work with negative numbers! See screenshot with green square, drawn at y=-90.Sorry, didn't do enough experimenting with the basic
drawImage
call, not I only need to work out whysetLCDOverlay
doesn't work the same. -
Hi All,
How can I position an image so the top-left point is off the screen, i.e. the x and y coordinate are negative? (Bangle.js2, possibly linked to this question which now seems locked?)
OR
How can I display only part of an image? Crop an image in memory and display it?
As part of my Overlay Notifications project, I'm making images and showing them on the overlay using
Bangle.setLCDOverlay(img, x, y);
. But x and y must be integers, so I can't scroll my image up by setting y as negative. Scrolling down works (by setting y to >0), the bottom of the image drops off the bottom of the screen.img.scroll
doesn't work, again x and y must be integers, setting them negative goes bananas and crashes the watch. I also tried 'blit', but that reads screen pixels (I think) so also doesn't work for me. This would also apply tog.drawImage(image, x, y)
andg.drawString(str, x, y)
, x and y must be integers.Thank you!
I nearly got a transition like this to work! Gordon helped me out with some suggestions, I'll see if I can dig out what I tried and make it work.
Edit: It was in this thread, I'll have another crack at it, it nearly worked: https://forum.espruino.com/conversations/383148