import Toybox.Graphics; import Toybox.WatchUi; import Toybox.Lang; class FotoCompanionView extends WatchUi.View { var bitmap = null; var palette = null; function initialize() { View.initialize(); // Initialize 64 color palette matching Android side (00, 55, AA, FF) // R (2 bits), G (2 bits), B (2 bits) palette = new [64]; for (var i = 0; i < 64; i++) { var r = (i >> 4) & 0x03; var g = (i >> 2) & 0x03; var b = i & 0x03; // Map 0..3 to 0..255 (0, 85, 170, 255) palette[i] = (r * 85) << 16 | (g * 85) << 8 | (b * 85); } } function onLayout(dc as Dc) as Void { } function onUpdate(dc as Dc) as Void { dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_BLACK); dc.clear(); if (bitmap != null) { var cx = (dc.getWidth() - bitmap.getWidth()) / 2; var cy = (dc.getHeight() - bitmap.getHeight()) / 2; dc.drawBitmap(cx, cy, bitmap); } else { dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_TRANSPARENT); dc.drawText(dc.getWidth() / 2, dc.getHeight() / 2, Graphics.FONT_MEDIUM, "Waiting for\nCamera...", Graphics.TEXT_JUSTIFY_CENTER | Graphics.TEXT_JUSTIFY_VCENTER); } // Draw Button Hint dc.setColor(Graphics.COLOR_GREEN, Graphics.COLOR_TRANSPARENT); dc.drawText(dc.getWidth() / 2, dc.getHeight() - 30, Graphics.FONT_XTINY, "PRESS START", Graphics.TEXT_JUSTIFY_CENTER); } function updateImage(data) { if (data instanceof Toybox.Lang.Array) { // Create a BufferedBitmap // Width/Height hardcoded to match Android (120x120) var opts = { :width => 120, :height => 120, :palette => palette }; if (Graphics has :createBufferedBitmap) { var bbRef = Graphics.createBufferedBitmap(opts); var bb = bbRef.get(); // Copy data // BufferedBitmap.setPalette is implicit via options // Unfortunately, there is no direct "setBytes" for the whole bitmap in older SDKs easily exposed without a resource. // But Connect IQ 4.0+ helps. // If we can't do bulk set, we iterate? Too slow. // Actually, resource creation from bytes is tricky. // Let's try the most robust way: // If the data is indeed the palette indices, we just need to get it into the bitmap buffer. // Hack for performance if no setBytes: // Use a resource? No dynamic resource creation. // Alternative: Send a custom String/JSON and parse? No. // If the device supports direct palette mapping we might be good. // Let's assume standard behavior: // We CAN iterate 14400 pixels in Monkey C if optimized? Maybe 0.5s. // Let's try to find a bulk setter. // There isn't one publicly documented for raw byte array -> bitmap pixels easily. // Wait! Strings! // If we encode as a string on Android, drawText? No. // Okay, we will iterate. It's 14400 pixels. // To optimize, Android sends RLE? // For now, simple iteration. var dc = bb.getDc(); for (var i = 0; i < 14400; i++) { if (i < data.size()) { var cIndex = data[i]; if (cIndex >= 0 && cIndex < 64) { dc.setColor(palette[cIndex], Graphics.COLOR_TRANSPARENT); // x = i % 120, y = i / 120 dc.drawPoint(i % 120, i / 120); } } } bitmap = bbRef; WatchUi.requestUpdate(); } } } }