diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6f15566 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +build +.lock-waf_darwin_build +node_modules +npm-debug.log \ No newline at end of file diff --git a/appinfo.json b/appinfo.json index e9a950d..972fb79 100644 --- a/appinfo.json +++ b/appinfo.json @@ -1,24 +1,25 @@ { "appKeys": { - "COLOR_BACKGROUND": 5, - "COLOR_HOUR_HAND": 9, - "COLOR_HOUR_MARKS": 7, - "COLOR_LABEL": 6, - "COLOR_MINUTE_HAND": 10, - "COLOR_MINUTE_MARKS": 8, - "COLOR_SECOND_HAND": 11, - "SHOW_DATE": 3, - "SHOW_NUMBERS": 1, - "SHOW_SECOND_HAND": 2, - "SHOW_TEMPERATURE": 4, - "TEMPERATURE": 0 + "TEMPERATURE": 0, + "SHOW_NUMBERS": 1, + "SHOW_SECOND_HAND": 2, + "SHOW_DATE": 3, + "SHOW_TEMPERATURE": 4, + "SHOW_STEPS": 5, + "COLOR_BACKGROUND": 6, + "COLOR_LABEL": 7, + "COLOR_HOUR_MARKS": 8, + "COLOR_MINUTE_MARKS": 9, + "COLOR_HOUR_HAND": 10, + "COLOR_MINUTE_HAND": 11, + "COLOR_SECOND_HAND": 12 }, "capabilities": [ "location", "configurable" ], "companyName": "Nicko Guyer", - "longName": "Engineering", + "longName": "Engineering Steps", "projectType": "native", "resources": { "media": [] @@ -31,7 +32,7 @@ "chalk" ], "uuid": "ff541ca4-a444-4513-879a-35ff9ec48a1b", - "versionLabel": "1.6", + "versionLabel": "1.7", "watchapp": { "watchface": true } diff --git a/config/index.html b/config/index.html index d249425..2f1cb43 100644 --- a/config/index.html +++ b/config/index.html @@ -72,6 +72,10 @@

Engineering

Temperature + @@ -97,115 +101,6 @@

Engineering

+ - diff --git a/config/js/main.js b/config/js/main.js new file mode 100644 index 0000000..bc10c49 --- /dev/null +++ b/config/js/main.js @@ -0,0 +1,113 @@ +function getConfigData() { + var backgroundColorPicker = document.getElementById('background_color_picker'); + var labelColorPicker = document.getElementById('label_color_picker'); + var hourMarkColorPicker = document.getElementById('hour_mark_color_picker'); + var minuteMarkColorPicker = document.getElementById('minute_mark_color_picker'); + var hourHandColorPicker = document.getElementById('hour_hand_color_picker'); + var minuteHandColorPicker = document.getElementById('minute_hand_color_picker'); + var secondHandColorPicker = document.getElementById('second_hand_color_picker'); + var numbersCheckbox = document.getElementById('show_numbers_checkbox'); + var secondHandCheckbox = document.getElementById('show_second_hand_checkbox'); + var dateCheckbox = document.getElementById('show_date_checkbox'); + var stepsCheckbox = document.getElementById('show_steps_checkbox'); + var temperatureCheckbox = document.getElementById('show_temperature_checkbox'); + var imperialUnits = document.getElementById('imperial_radio'); + var metricUnits = document.getElementById('metric_radio'); + + var units = 'imperial'; + if (metricUnits.checked) { + units = 'metric'; + } + + var options = { + 'background_color': backgroundColorPicker.value, + 'label_color': labelColorPicker.value, + 'hour_mark_color': hourMarkColorPicker.value, + 'minute_mark_color': minuteMarkColorPicker.value, + 'hour_hand_color': hourHandColorPicker.value, + 'minute_hand_color': minuteHandColorPicker.value, + 'second_hand_color': secondHandColorPicker.value, + 'show_numbers': numbersCheckbox.checked, + 'show_second_hand': secondHandCheckbox.checked, + 'show_date': dateCheckbox.checked, + 'show_steps': stepsCheckbox.checked, + 'show_temperature': temperatureCheckbox.checked, + 'units': units + }; + + // Save for next launch + localStorage.background_color = options.background_color; + localStorage.label_color = options.label_color; + localStorage.hour_mark_color = options.hour_mark_color; + localStorage.minute_mark_color = options.minute_mark_color; + localStorage.hour_hand_color = options.hour_hand_color; + localStorage.minute_hand_color = options.minute_hand_color; + localStorage.second_hand_color = options.second_hand_color; + localStorage.show_numbers = options.show_numbers; + localStorage.show_second_hand = options.show_second_hand; + localStorage.show_date = options.show_date; + localStorage.show_steps = options.show_steps; + localStorage.show_temperature = options.show_temperature; + localStorage.units = options.units; + + console.log('Got options: ' + JSON.stringify(options)); + return options; + } + + function getQueryParam(variable, defaultValue) { + var query = location.search.substring(1); + var vars = query.split('&'); + for (var i = 0; i < vars.length; i++) { + var pair = vars[i].split('='); + if (pair[0] === variable) { + return decodeURIComponent(pair[1]); + } + } + return defaultValue || false; + } + + var submitButton = document.getElementById('submit_button'); + submitButton.addEventListener('click', function() { + console.log('Submit'); + + // Set the return URL depending on the runtime environment + var return_to = getQueryParam('return_to', 'pebblejs://close#'); + document.location = return_to + encodeURIComponent(JSON.stringify(getConfigData())); + }); + + (function() { + var backgroundColorPicker = document.getElementById('background_color_picker'); + var labelColorPicker = document.getElementById('label_color_picker'); + var hourMarkColorPicker = document.getElementById('hour_mark_color_picker'); + var minuteMarkColorPicker = document.getElementById('minute_mark_color_picker'); + var hourHandColorPicker = document.getElementById('hour_hand_color_picker'); + var minuteHandColorPicker = document.getElementById('minute_hand_color_picker'); + var secondHandColorPicker = document.getElementById('second_hand_color_picker'); + var numbersCheckbox = document.getElementById('show_numbers_checkbox'); + var secondHandCheckbox = document.getElementById('show_second_hand_checkbox'); + var dateCheckbox = document.getElementById('show_date_checkbox'); + var stepsCheckbox = document.getElementById('show_steps_checkbox'); + var temperatureCheckbox = document.getElementById('show_temperature_checkbox'); + var imperialUnits = document.getElementById('imperial_radio'); + var metricUnits = document.getElementById('metric_radio'); + + // Load any previously saved configuration, if available + if (localStorage['background_color']) backgroundColorPicker.value = localStorage['background_color']; + if (localStorage['label_color']) labelColorPicker.value = localStorage['label_color']; + if (localStorage['hour_mark_color']) hourMarkColorPicker.value = localStorage['hour_mark_color']; + if (localStorage['minute_mark_color']) minuteMarkColorPicker.value = localStorage['minute_mark_color']; + if (localStorage['hour_hand_color']) hourHandColorPicker.value = localStorage['hour_hand_color']; + if (localStorage['minute_hand_color']) minuteHandColorPicker.value = localStorage['minute_hand_color']; + if (localStorage['second_hand_color']) secondHandColorPicker.value = localStorage['second_hand_color']; + if (localStorage['show_numbers']) numbersCheckbox.checked = JSON.parse(localStorage['show_numbers']); + if (localStorage['show_second_hand']) secondHandCheckbox.checked = JSON.parse(localStorage['show_second_hand']); + if (localStorage['show_date']) dateCheckbox.checked = JSON.parse(localStorage['show_date']); + if (localStorage['show_steps']) stepsCheckbox.checked = JSON.parse(localStorage['show_steps']); + if (localStorage['show_temperature']) temperatureCheckbox.checked = JSON.parse(localStorage['show_temperature']); + if (localStorage['units']) { + if (localStorage['units'] == 'metric') { + metricUnits.checked = true; + imperialUnits.checked = false; + } + } + })(); \ No newline at end of file diff --git a/config/js/main.min.js b/config/js/main.min.js new file mode 100644 index 0000000..b61b5e4 --- /dev/null +++ b/config/js/main.min.js @@ -0,0 +1 @@ +function getConfigData(){var e=document.getElementById("background_color_picker"),o=document.getElementById("label_color_picker"),c=document.getElementById("hour_mark_color_picker"),t=document.getElementById("minute_mark_color_picker"),l=document.getElementById("hour_hand_color_picker"),r=document.getElementById("minute_hand_color_picker"),a=document.getElementById("second_hand_color_picker"),n=document.getElementById("show_numbers_checkbox"),_=document.getElementById("show_second_hand_checkbox"),d=document.getElementById("show_date_checkbox"),m=document.getElementById("show_steps_checkbox"),u=document.getElementById("show_temperature_checkbox"),h=(document.getElementById("imperial_radio"),document.getElementById("metric_radio")),s="imperial";h.checked&&(s="metric");var g={background_color:e.value,label_color:o.value,hour_mark_color:c.value,minute_mark_color:t.value,hour_hand_color:l.value,minute_hand_color:r.value,second_hand_color:a.value,show_numbers:n.checked,show_second_hand:_.checked,show_date:d.checked,show_steps:m.checked,show_temperature:u.checked,units:s};return localStorage.background_color=g.background_color,localStorage.label_color=g.label_color,localStorage.hour_mark_color=g.hour_mark_color,localStorage.minute_mark_color=g.minute_mark_color,localStorage.hour_hand_color=g.hour_hand_color,localStorage.minute_hand_color=g.minute_hand_color,localStorage.second_hand_color=g.second_hand_color,localStorage.show_numbers=g.show_numbers,localStorage.show_second_hand=g.show_second_hand,localStorage.show_date=g.show_date,localStorage.show_steps=g.show_steps,localStorage.show_temperature=g.show_temperature,localStorage.units=g.units,console.log("Got options: "+JSON.stringify(g)),g}function getQueryParam(e,o){for(var c=location.search.substring(1),t=c.split("&"),l=0;l { + console.log('paths.src.scripts', paths.src.scripts); + console.log('paths.dest.scripts.name', paths.dest.scripts.name); + return ()=> { + return gulp.src(paths.src.scripts) + .pipe(plugins.debug()) + .pipe(plugins.jshint()) + .pipe(plugins.jshint.reporter('jshint-stylish')) + .pipe(plugins.concat(paths.dest.scripts.name)) + .pipe(plugins.uglify()) + .pipe(gulp.dest(paths.dest.scripts.dir)); + } +}; \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..d9bf843 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,11 @@ +var gulp = require('gulp'); +var plugins = require('gulp-load-plugins')(); +var paths = require('./gulp/paths.json'); + +gulp.on("error", function (err) { console.log("Oops: %s", err);}); + +// Concat & Minify & Lint Our JS +gulp.task('scripts', require('./gulp/tasks/scripts')(gulp, plugins, paths)); + +gulp.task('default', ['build']); +gulp.task('build', ['scripts']); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..99a2aa6 --- /dev/null +++ b/package.json @@ -0,0 +1,30 @@ +{ + "name": "pebble-engineering-steps", + "version": "1.0.0", + "description": "A fork of pebble-engineering by nguyer that incorporates Pebble Health steps.", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/kencaron/pebble-engineering.git" + }, + "author": "Ken Caron", + "license": "ISC", + "bugs": { + "url": "https://github.com/kencaron/pebble-engineering/issues" + }, + "homepage": "https://github.com/kencaron/pebble-engineering#readme", + "devDependencies": { + "gulp": "^3.9.1", + "gulp-concat": "^2.6.0", + "gulp-debug": "^2.1.2", + "gulp-jshint": "^2.0.0", + "gulp-load-plugins": "^1.2.0", + "gulp-uglify": "^1.5.2", + "jshint": "^2.9.1", + "jshint-stylish": "^2.1.0", + "slate": "https://git@github.com:pebble/slate.git" + } +} diff --git a/src/engineering.c b/src/engineering.c index d0d80f6..aafd7cf 100644 --- a/src/engineering.c +++ b/src/engineering.c @@ -4,16 +4,21 @@ static Window *window; static Layer *s_simple_bg_layer, *s_date_layer, *s_hands_layer; -static TextLayer *s_day_label, *s_num_label; +static TextLayer *s_day_label, *s_num_label, *s_steps_label; static GPath *s_minute_arrow, *s_hour_arrow; -static char s_date_buffer[7], s_temp_buffer[5]; +static char s_date_buffer[7], s_temp_buffer[5], s_steps_buffer[8]; + static AppSync s_sync; static uint8_t s_sync_buffer[64]; static GColor gcolor_background, gcolor_hour_marks, gcolor_minute_marks, gcolor_numbers, gcolor_hour_hand, gcolor_minute_hand, gcolor_second_hand; -static bool b_show_numbers, b_show_temperature, b_show_date, b_show_second_hand; +static bool b_show_numbers, b_show_temperature, b_show_date, b_show_second_hand, b_show_steps; + +static void handle_tick(struct tm *tick_time, TimeUnits units_changed) { + layer_mark_dirty(window_get_root_layer(window)); +} static void load_persisted_values() { // SHOW_NUMBERS @@ -31,6 +36,16 @@ static void load_persisted_values() { b_show_temperature = persist_read_int(KEY_SHOW_TEMPERATURE); } + // SHOW_TEMPERATURE + if (persist_exists(KEY_SHOW_TEMPERATURE)) { + b_show_temperature = persist_read_int(KEY_SHOW_TEMPERATURE); + } + + // SHOW_STEPS + if (persist_exists(KEY_SHOW_STEPS)) { + b_show_steps = persist_read_int(KEY_SHOW_STEPS); + } + // SHOW_DATE if (persist_exists(KEY_SHOW_DATE)) { b_show_date = persist_read_int(KEY_SHOW_DATE); @@ -109,11 +124,25 @@ static void inbox_received_handler(DictionaryIterator *iter, void *context) { persist_write_int(KEY_SHOW_TEMPERATURE, b_show_temperature); } + Tuple *show_steps_t = dict_find(iter, KEY_SHOW_STEPS); + if(show_steps_t) { + APP_LOG(APP_LOG_LEVEL_INFO, "Show steps %d", show_steps_t->value->uint8); + b_show_steps = show_steps_t->value->uint8; + persist_write_int(KEY_SHOW_STEPS, show_steps_t->value->uint8); + } + Tuple *show_second_hand_t = dict_find(iter, KEY_SHOW_SECOND_HAND); if(show_second_hand_t) { APP_LOG(APP_LOG_LEVEL_INFO, "Show second hand %d", show_second_hand_t->value->uint8); b_show_second_hand = show_second_hand_t->value->uint8; persist_write_int(KEY_SHOW_SECOND_HAND, show_second_hand_t->value->uint8); + + if (b_show_second_hand) { + tick_timer_service_subscribe(SECOND_UNIT, handle_tick); + } else { + tick_timer_service_subscribe(MINUTE_UNIT, handle_tick); + } + } Tuple *color_background_t = dict_find(iter, KEY_COLOR_BACKGROUND); @@ -252,6 +281,38 @@ static void bg_update_proc(Layer *layer, GContext *ctx) { } } +static void health_handler(HealthEventType event, void *context) { + + if (b_show_steps) { + if (event == HealthEventMovementUpdate) { + // display the step count + + //Lifted from https://github.com/freakified/TimeStylePebble by freakified + // format step string + int steps = (int)health_service_sum_today(HealthMetricStepCount); + if(steps < 1000) { + snprintf(s_steps_buffer, sizeof(s_steps_buffer), "%i", steps); + } else { + int steps_thousands = steps / 1000; + int steps_hundreds = steps / 100 % 10; + + char decimalSeparator[1] = "."; + + if (steps < 10000) { + snprintf(s_steps_buffer, sizeof(s_steps_buffer), "%i%s%iK", steps_thousands, decimalSeparator, steps_hundreds); + } else { + snprintf(s_steps_buffer, sizeof(s_steps_buffer), "%iK", steps_thousands); + } + } + + text_layer_set_text(s_steps_label, s_steps_buffer); + + } + } + + +} + static void hands_update_proc(Layer *layer, GContext *ctx) { GRect bounds = layer_get_bounds(layer); GPoint center = grect_center_point(&bounds); @@ -283,6 +344,22 @@ static void hands_update_proc(Layer *layer, GContext *ctx) { #endif } + // steps + if (!b_show_steps) { + + health_service_events_unsubscribe(); + text_layer_set_text(s_steps_label, ""); + } else { + text_layer_set_text_color(s_steps_label, gcolor_numbers); + + // subscribe to health events + if(health_service_events_subscribe(health_handler, NULL)) { + health_handler(HealthEventMovementUpdate, NULL); + } else { + APP_LOG(APP_LOG_LEVEL_ERROR, "Health not available!"); + } + } + // temperature if (b_show_temperature) { graphics_context_set_text_color(ctx, gcolor_numbers); @@ -324,10 +401,6 @@ static void date_update_proc(Layer *layer, GContext *ctx) { uppercase(s_date_buffer); } -static void handle_second_tick(struct tm *tick_time, TimeUnits units_changed) { - layer_mark_dirty(window_get_root_layer(window)); -} - static void window_load(Window *window) { Layer *window_layer = window_get_root_layer(window); GRect bounds = layer_get_bounds(window_layer); @@ -347,6 +420,39 @@ static void window_load(Window *window) { layer_add_child(window_layer, s_hands_layer); load_persisted_values(); + + if (b_show_second_hand) { + + tick_timer_service_subscribe(SECOND_UNIT, handle_tick); + } else { + + tick_timer_service_subscribe(MINUTE_UNIT, handle_tick); + } + + // subscribe to health events + if(health_service_events_subscribe(health_handler, NULL)) { + // force initial steps display + + int offset = !b_show_numbers * 10; + + s_steps_label = text_layer_create(PBL_IF_ROUND_ELSE( + GRect(0, 120 + offset, 180, 18), + GRect(0, 100 + offset, 144, 14) + )); + + text_layer_set_background_color(s_steps_label, GColorClear); + text_layer_set_text_color(s_steps_label, gcolor_numbers); + text_layer_set_font(s_steps_label, fonts_get_system_font(PBL_IF_ROUND_ELSE(FONT_KEY_GOTHIC_18, FONT_KEY_GOTHIC_14))); + text_layer_set_text_alignment(s_steps_label, GTextAlignmentCenter); + layer_add_child(s_date_layer, text_layer_get_layer(s_steps_label)); + + if (b_show_steps) { + health_handler(HealthEventMovementUpdate, NULL); + } + + } else { + APP_LOG(APP_LOG_LEVEL_ERROR, "Health not available!"); + } } static void window_unload(Window *window) { @@ -355,6 +461,8 @@ static void window_unload(Window *window) { text_layer_destroy(s_day_label); text_layer_destroy(s_num_label); + text_layer_destroy(s_steps_label); + layer_destroy(s_hands_layer); } @@ -383,6 +491,8 @@ static void init() { b_show_second_hand = true; b_show_date = true; b_show_temperature = true; + b_show_steps = true; + window = window_create(); window_set_window_handlers(window, (WindowHandlers) { @@ -404,7 +514,7 @@ static void init() { gpath_move_to(s_minute_arrow, center); gpath_move_to(s_hour_arrow, center); - tick_timer_service_subscribe(SECOND_UNIT, handle_second_tick); + app_message_register_inbox_received(inbox_received_handler); app_message_open(64, 64); @@ -415,6 +525,8 @@ static void deinit() { gpath_destroy(s_hour_arrow); tick_timer_service_unsubscribe(); + health_service_events_unsubscribe(); + window_destroy(window); } diff --git a/src/engineering.h b/src/engineering.h index 014fb9d..7e93d4c 100644 --- a/src/engineering.h +++ b/src/engineering.h @@ -1,18 +1,19 @@ #pragma once #include -#define KEY_TEMPERATURE 0 -#define KEY_SHOW_NUMBERS 1 -#define KEY_SHOW_SECOND_HAND 2 -#define KEY_SHOW_DATE 3 -#define KEY_SHOW_TEMPERATURE 4 -#define KEY_COLOR_BACKGROUND 5 -#define KEY_COLOR_LABEL 6 -#define KEY_COLOR_HOUR_MARKS 7 -#define KEY_COLOR_MINUTE_MARKS 8 -#define KEY_COLOR_HOUR_HAND 9 -#define KEY_COLOR_MINUTE_HAND 10 -#define KEY_COLOR_SECOND_HAND 11 +#define KEY_TEMPERATURE 0 +#define KEY_SHOW_NUMBERS 1 +#define KEY_SHOW_SECOND_HAND 2 +#define KEY_SHOW_DATE 3 +#define KEY_SHOW_TEMPERATURE 4 +#define KEY_SHOW_STEPS 5 +#define KEY_COLOR_BACKGROUND 6 +#define KEY_COLOR_LABEL 7 +#define KEY_COLOR_HOUR_MARKS 8 +#define KEY_COLOR_MINUTE_MARKS 9 +#define KEY_COLOR_HOUR_HAND 10 +#define KEY_COLOR_MINUTE_HAND 11 +#define KEY_COLOR_SECOND_HAND 12 #define INSET PBL_IF_ROUND_ELSE(1, 0) #define HOURS_RADIUS 3 diff --git a/src/pebble-app-js.js b/src/pebble-app-js.js index 423e43d..45565ed 100644 --- a/src/pebble-app-js.js +++ b/src/pebble-app-js.js @@ -39,7 +39,7 @@ Pebble.addEventListener('ready',function(e) { ); Pebble.addEventListener('showConfiguration', function() { - var url = 'https://rawgit.com/nguyer/pebble-engineering/1.5/config/index.html'; + var url = 'https://rawgit.com/kencaron/pebble-engineering/master/config/index.html'; console.log('Showing configuration page: ' + url); Pebble.openURL(url); @@ -62,6 +62,7 @@ Pebble.addEventListener('webviewclosed', function(e) { toggleDict.SHOW_SECOND_HAND = configData.show_second_hand; toggleDict.SHOW_DATE = configData.show_date; toggleDict.SHOW_TEMPERATURE = configData.show_temperature; + toggleDict.SHOW_STEPS = configData.show_steps; var colorDict = {};