From f8536ce373216e9e63386b240ff906b13c2bfb71 Mon Sep 17 00:00:00 2001 From: Eric Vandewater Date: Fri, 14 Oct 2016 17:58:17 -0700 Subject: [PATCH 1/3] Shrink menu icon to allow succesful pebble build --- .gitignore | 1 + appinfo.json | 6 +++--- resources/images/menu_icon.png | Bin 15463 -> 6539 bytes 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 574622dd..ba23cb91 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /.lock-* /build/ /out/ +.idea/ diff --git a/appinfo.json b/appinfo.json index 64029118..44ecf8a9 100644 --- a/appinfo.json +++ b/appinfo.json @@ -11,17 +11,17 @@ "file": "images/menu_icon.png", "menuIcon": true, "name": "IMAGE_MENU_ICON", - "type": "bitmap" + "type": "png" }, { "file": "images/logo_splash.png", "name": "IMAGE_LOGO_SPLASH", - "type": "bitmap" + "type": "png" }, { "file": "images/tile_splash.png", "name": "IMAGE_TILE_SPLASH", - "type": "bitmap" + "type": "png" }, { "file": "fonts/UbuntuMono-Regular.ttf", diff --git a/resources/images/menu_icon.png b/resources/images/menu_icon.png index a9ed50333781bac396a4ac094e9bf0ad40b4978b..4c26ed6029461ff8e72accffbd8556ce765d4e98 100644 GIT binary patch delta 3756 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 Date: Sat, 15 Oct 2016 11:20:05 -0700 Subject: [PATCH 2/3] Add 'Path' element type to simply-pebble Fix transform bug in _makeMetaAccessor in struct.js Replace menu_icon.png to avoid loading errors Update app.js to demo new path element --- resources/images/menu_icon.png | Bin 6539 -> 283 bytes src/js/app.js | 36 +++++++++++----- src/js/lib/struct.js | 4 +- src/js/ui/element.js | 1 + src/js/ui/index.js | 1 + src/js/ui/path.js | 29 +++++++++++++ src/js/ui/simply-pebble.js | 33 ++++++++++++++ src/js/ui/stage.js | 12 +++--- src/simply/simply_msg_commands.h | 1 + src/simply/simply_stage.c | 72 +++++++++++++++++++++++++++++++ src/simply/simply_stage.h | 8 ++++ 11 files changed, 180 insertions(+), 17 deletions(-) create mode 100644 src/js/ui/path.js diff --git a/resources/images/menu_icon.png b/resources/images/menu_icon.png index 4c26ed6029461ff8e72accffbd8556ce765d4e98..91fc819f51c660cbcab217c2be3dd63126d8139b 100644 GIT binary patch delta 267 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 diff --git a/src/js/app.js b/src/js/app.js index 9255c293..870d1934 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -7,6 +7,8 @@ var UI = require('ui'); var Vector2 = require('vector2'); +var TRIG_MAX_ANGLE = 0x10000; + var main = new UI.Card({ title: 'Pebble.js', icon: 'images/menu_icon.png', @@ -50,17 +52,11 @@ main.on('click', 'select', function(e) { size: new Vector2(140, 140), angle: 0, angle2: 300, - radius: 20, + radius: 10, backgroundColor: 'cyan', borderColor: 'celeste', borderWidth: 1, }); - var textfield = new UI.Text({ - size: new Vector2(140, 60), - font: 'gothic-24-bold', - text: 'Dynamic\nWindow', - textAlign: 'center' - }); var windSize = wind.size(); // Center the radial in the window var radialPos = radial.position() @@ -68,14 +64,34 @@ main.on('click', 'select', function(e) { .subSelf(radial.size()) .multiplyScalar(0.5); radial.position(radialPos); + var textfield = new UI.Text({ + size: new Vector2(140, 60), + font: 'gothic-18', + text: 'Dynamic\nWindow', + textAlign: 'center' + }); // Center the textfield in the window var textfieldPos = textfield.position() - .addSelf(windSize) - .subSelf(textfield.size()) - .multiplyScalar(0.5); + .addSelf(windSize) + .subSelf(textfield.size()) + .multiplyScalar(0.5) + .addSelf({ x: 0, y: 10 }); textfield.position(textfieldPos); wind.add(radial); wind.add(textfield); + // Add clock ticks inside radial using path fields + var centerPos = wind.size().multiplyScalar(0.5); + var outerSize = radial.size().y / 2 - radial.radius() - 15; + for (var i = 0; i < 12; i++) { + wind.add(new UI.Path({ + p0: { x: -2, y: outerSize - 7 }, + p1: { x: -2, y: outerSize + 7 }, + p2: { x: 2, y: outerSize + 7 }, + p3: { x: 2, y: outerSize - 7 }, + offset: centerPos, + rotation: Math.floor(TRIG_MAX_ANGLE * i / 12) + })); + } wind.show(); }); diff --git a/src/js/lib/struct.js b/src/js/lib/struct.js index 9989b161..192df1c9 100644 --- a/src/js/lib/struct.js +++ b/src/js/lib/struct.js @@ -171,8 +171,8 @@ struct.prototype._makeAccessor = function(field) { }; struct.prototype._makeMetaAccessor = function(name, transform) { - this[name] = function(value, field) { - transform.call(this, value, field); + this[name] = function(value) { + transform.call(this, value, name); return this; }; }; diff --git a/src/js/ui/element.js b/src/js/ui/element.js index c4759f29..4e5a05d5 100644 --- a/src/js/ui/element.js +++ b/src/js/ui/element.js @@ -38,6 +38,7 @@ var Types = [ 'TextType', 'ImageType', 'InverterType', + 'PathType' ]; Types.forEach(function(name, index) { diff --git a/src/js/ui/index.js b/src/js/ui/index.js index 8ba16893..4507fe40 100644 --- a/src/js/ui/index.js +++ b/src/js/ui/index.js @@ -14,5 +14,6 @@ UI.Image = require('ui/image'); UI.Inverter = require('ui/inverter'); UI.Vibe = require('ui/vibe'); UI.Light = require('ui/light'); +UI.Path = require('ui/path'); module.exports = UI; diff --git a/src/js/ui/path.js b/src/js/ui/path.js new file mode 100644 index 00000000..110184f0 --- /dev/null +++ b/src/js/ui/path.js @@ -0,0 +1,29 @@ +var util2 = require('util2'); +var myutil = require('myutil'); +var Propable = require('ui/propable'); +var StageElement = require('ui/element'); + +var pathProps = [ + 'rotation', + 'offset', + 'p0', + 'p1', + 'p2', + 'p3', +]; + +var defaults = { + backgroundColor: 'clear', + borderColor: 'white', +}; + +var Path = function(elementDef) { + StageElement.call(this, myutil.shadow(defaults, elementDef || {})); + this.state.type = StageElement.PathType; +}; + +util2.inherit(Path, StageElement); + +Propable.makeAccessors(pathProps, Path.prototype); + +module.exports = Path; diff --git a/src/js/ui/simply-pebble.js b/src/js/ui/simply-pebble.js index 648dc445..dacb935c 100644 --- a/src/js/ui/simply-pebble.js +++ b/src/js/ui/simply-pebble.js @@ -76,6 +76,11 @@ var SizeType = function(x) { this.sizeH(x.y); }; +var VectorType = function(vector, field) { + this[field + 'X'](vector.x); + this[field + 'Y'](vector.y); +}; + var namedColorMap = { 'clear': 0x00, 'black': 0xC0, @@ -732,6 +737,17 @@ var ElementAnimateDonePacket = new struct([ ['uint32', 'id'], ]); +var ElementPathPacket = new struct([ + [Packet, 'packet'], + ['uint32', 'id'], + ['int32', 'rotation'], + [GPoint, 'offset', VectorType], + [GPoint, 'p0', VectorType], + [GPoint, 'p1', VectorType], + [GPoint, 'p2', VectorType], + [GPoint, 'p3', VectorType], +]); + var VoiceDictationStartPacket = new struct([ [Packet, 'packet'], ['bool', 'enableConfirmation'], @@ -801,6 +817,7 @@ var CommandPackets = [ ElementImagePacket, ElementAnimatePacket, ElementAnimateDonePacket, + ElementPathPacket, VoiceDictationStartPacket, VoiceDictationStopPacket, VoiceDictationDataPacket, @@ -1305,6 +1322,19 @@ SimplyPebble.elementAnimate = function(id, def, animateDef, duration, easing) { SimplyPebble.sendPacket(ElementAnimatePacket); }; +SimplyPebble.elementPath = function(id, def) { + ElementPathPacket + .id(id) + .p0(def.p0) + .p1(def.p1) + .p2(def.p2) + .p3(def.p3) + .rotation(def.rotation) + .offset(def.offset || { x: 0, y: 0 }) + .prop(def); + SimplyPebble.sendPacket(ElementPathPacket); +}; + SimplyPebble.stageClear = function() { SimplyPebble.sendPacket(StageClearPacket); }; @@ -1333,6 +1363,9 @@ SimplyPebble.stageElement = function(id, type, def, index) { SimplyPebble.elementRadius(id, def); SimplyPebble.elementImage(id, def.image, def.compositing); break; + case StageElement.PathType: + SimplyPebble.elementPath(id, def); + break; } }; diff --git a/src/js/ui/stage.js b/src/js/ui/stage.js index f8ec59d0..573a64cb 100644 --- a/src/js/ui/stage.js +++ b/src/js/ui/stage.js @@ -9,11 +9,13 @@ var Stage = function(stageDef) { }; Stage.RectType = 1; -Stage.CircleType = 2; -Stage.RadialType = 6; -Stage.TextType = 3; -Stage.ImageType = 4; -Stage.InverterType = 5; +Stage.LineType = 2; +Stage.CircleType = 3; +Stage.RadialType = 4; +Stage.TextType = 4; +Stage.ImageType = 5; +Stage.InverterType = 6; +Stage.PathType = 7; util2.copy(Emitter.prototype, Stage.prototype); diff --git a/src/simply/simply_msg_commands.h b/src/simply/simply_msg_commands.h index c04f7aaa..8e54cb3d 100644 --- a/src/simply/simply_msg_commands.h +++ b/src/simply/simply_msg_commands.h @@ -55,6 +55,7 @@ enum Command { CommandElementImage, CommandElementAnimate, CommandElementAnimateDone, + CommandElementPath, CommandVoiceStart, CommandVoiceStop, CommandVoiceData, diff --git a/src/simply/simply_stage.c b/src/simply/simply_stage.c index 1b5106ad..ac397d42 100644 --- a/src/simply/simply_stage.c +++ b/src/simply/simply_stage.c @@ -111,6 +111,19 @@ struct __attribute__((__packed__)) ElementAnimateDonePacket { uint32_t id; }; +typedef struct ElementPathPacket ElementPathPacket; + +struct __attribute__((__packed__)) ElementPathPacket { + Packet packet; + uint32_t id; + int32_t rotation; + GPoint offset; + GPoint p0; + GPoint p1; + GPoint p2; + GPoint p3; +}; + static void simply_stage_clear(SimplyStage *self); static void simply_stage_update(SimplyStage *self); @@ -157,6 +170,15 @@ static void destroy_element(SimplyStage *self, SimplyElementCommon *element) { case SimplyElementTypeInverter: inverter_layer_destroy(((SimplyElementInverter*) element)->inverter_layer); break; + case SimplyElementTypePath: + if (((SimplyElementPath*) element)->path) { + if (((SimplyElementPath*) element)->path->points) { + free(((SimplyElementPath*) element)->path->points); + ((SimplyElementPath*) element)->path->points = NULL; + } + gpath_destroy(((SimplyElementPath*) element)->path); + } + break; } free(element); } @@ -289,6 +311,17 @@ static void image_element_draw(GContext *ctx, SimplyStage *self, SimplyElementIm graphics_context_set_compositing_mode(ctx, GCompOpAssign); } +static void path_element_draw(GContext *ctx, SimplyStage *self, SimplyElementPath *element) { + if (element->path && element->common.background_color.a) { + graphics_context_set_fill_color(ctx, gcolor8_get(element->common.background_color)); + gpath_draw_filled(ctx, element->path); + } + if (element->path && element->common.border_color.a) { + graphics_context_set_stroke_color(ctx, gcolor8_get(element->common.border_color)); + gpath_draw_outline(ctx, element->path); + } +} + static void layer_update_callback(Layer *layer, GContext *ctx) { SimplyStage *self = *(void**) layer_get_data(layer); @@ -332,6 +365,9 @@ static void layer_update_callback(Layer *layer, GContext *ctx) { break; case SimplyElementTypeInverter: break; + case SimplyElementTypePath: + path_element_draw(ctx, self, (SimplyElementPath*) element); + break; } element = (SimplyElementCommon*) element->node.next; } @@ -356,6 +392,7 @@ static size_t prv_get_element_size(SimplyElementType type) { case SimplyElementTypeText: return sizeof(SimplyElementText); case SimplyElementTypeImage: return sizeof(SimplyElementImage); case SimplyElementTypeInverter: return sizeof(SimplyElementInverter); + case SimplyElementTypePath: return sizeof(SimplyElementPath); } return 0; } @@ -703,6 +740,38 @@ static void handle_element_animate_packet(Simply *simply, Packet *data) { simply_stage_animate_element(simply->stage, element, animation, packet->frame); } +static void handle_element_path_packet(Simply *simply, Packet *data) { + GPathInfo pathInfo; + GPath *path; + + ElementPathPacket *packet = (ElementPathPacket*) data; + SimplyElementPath *element = (SimplyElementPath*) simply_stage_get_element(simply->stage, packet->id); + if (!element) { + return; + } + pathInfo.num_points = 4; + pathInfo.points = malloc0(4 * sizeof(GPoint)); + if (pathInfo.points) { + memcpy(pathInfo.points, &packet->p0, 4 * sizeof(GPoint)); + path = gpath_create(&pathInfo); + if (path) { + if (element->path) { + if (element->path->points) { + free(element->path->points); + element->path->points = NULL; + } + gpath_destroy(element->path); + } + element->path = path; + gpath_move_to(element->path, packet->offset); + gpath_rotate_to(element->path, packet->rotation); + simply_stage_update(simply->stage); + } else { + free(pathInfo.points); + } + } +} + bool simply_stage_handle_packet(Simply *simply, Packet *packet) { switch (packet->type) { case CommandStageClear: @@ -738,6 +807,9 @@ bool simply_stage_handle_packet(Simply *simply, Packet *packet) { case CommandElementAnimate: handle_element_animate_packet(simply, packet); return true; + case CommandElementPath: + handle_element_path_packet(simply, packet); + return true; } return false; } diff --git a/src/simply/simply_stage.h b/src/simply/simply_stage.h index e9714f51..c00e804f 100644 --- a/src/simply/simply_stage.h +++ b/src/simply/simply_stage.h @@ -31,6 +31,7 @@ enum SimplyElementType { SimplyElementTypeText, SimplyElementTypeImage, SimplyElementTypeInverter, + SimplyElementTypePath, }; struct SimplyStageLayer { @@ -113,6 +114,13 @@ struct SimplyAnimation { AnimationCurve curve; }; +typedef struct SimplyElementPath SimplyElementPath; + +struct SimplyElementPath { + SimplyElementCommon common; + GPath* path; +}; + SimplyStage *simply_stage_create(Simply *simply); void simply_stage_destroy(SimplyStage *self); From 07b2f3f9295372e6fa6ec49a3dcfe57e437c4418 Mon Sep 17 00:00:00 2001 From: Eric Vandewater Date: Sat, 15 Oct 2016 17:31:52 -0700 Subject: [PATCH 3/3] Destroy element when removed in handle_element_remove_packet in simplay_stage.c --- src/simply/simply_stage.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/simply/simply_stage.c b/src/simply/simply_stage.c index ac397d42..f2ec4abb 100644 --- a/src/simply/simply_stage.c +++ b/src/simply/simply_stage.c @@ -633,6 +633,7 @@ static void handle_element_remove_packet(Simply *simply, Packet *data) { return; } simply_stage_remove_element(simply->stage, element); + destroy_element(simply->stage, element); simply_stage_update(simply->stage); }