Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/pebble-dembel.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey 'Cluster' Avdyukhin <ClusterM@users.noreply.github.com>2015-04-13 12:22:52 +0300
committerAlexey 'Cluster' Avdyukhin <ClusterM@users.noreply.github.com>2015-04-13 12:22:52 +0300
commit9af3f7156238af9659ed75c072860205ba5af5bd (patch)
tree9a9a688291050270b82354ea403f91f77ec91efd
parentcdea20addbe93b3414904fd47e682999f6e065f3 (diff)
First commit
-rw-r--r--appinfo.json26
-rw-r--r--src/dembel.c218
-rw-r--r--src/pebble-js-app.js62
-rw-r--r--wscript62
4 files changed, 368 insertions, 0 deletions
diff --git a/appinfo.json b/appinfo.json
new file mode 100644
index 0000000..c80a825
--- /dev/null
+++ b/appinfo.json
@@ -0,0 +1,26 @@
+{
+ "appKeys": {
+ "end_time": 1,
+ "start_time": 0
+ },
+ "capabilities": [
+ "configurable"
+ ],
+ "companyName": "Cluster",
+ "longName": "DEMBEL WATCHFACE",
+ "projectType": "native",
+ "resources": {
+ "media": []
+ },
+ "sdkVersion": "3",
+ "shortName": "DEMBEL WATCHFACE",
+ "targetPlatforms": [
+ "aplite"
+ ],
+ "uuid": "3ac71f3b-063c-470a-b94b-cb09154adc78",
+ "versionCode": 1,
+ "versionLabel": "1.0",
+ "watchapp": {
+ "watchface": true
+ }
+}
diff --git a/src/dembel.c b/src/dembel.c
new file mode 100644
index 0000000..4e11246
--- /dev/null
+++ b/src/dembel.c
@@ -0,0 +1,218 @@
+#include <pebble.h>
+
+static time_t start_time;
+static time_t end_time;
+
+static Window *window;
+static TextLayer *time_layer;
+static TextLayer *left_time_layer;
+static TextLayer *left_time_layer2;
+static TextLayer *percent_layer;
+static Layer *progress_layer;
+
+static float percent = 0;
+
+#define MSG_START_TIME 0
+#define MSG_END_TIME 1
+
+static void fucking_russian(int number, char* text, char* def, char* ending1, char* ending234)
+{
+ if (number >= 10 && number <= 19)
+ strcat(text, def);
+ else
+ switch (number % 10)
+ {
+ case 0:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ strcat(text, def);
+ break;
+ case 1:
+ strcat(text, ending1);
+ break;
+ case 2:
+ case 3:
+ case 4:
+ strcat(text, ending234);
+ break;
+ }
+}
+
+static void handle_tick(struct tm *tick_time, TimeUnits units_changed)
+{
+ time_t now = time(NULL);
+
+ long int left_total = end_time - now;
+ if (left_total < 0) left_total *= -1;
+ int left_mins = (left_total / 60) % 60;
+ int left_hours = (left_total / (60*60)) % 24;
+ int left_days = left_total / (60*60*24);
+
+ static char left_time_str[200];
+ char minut[15];
+ char chas[15];
+ char den[15];
+
+ strcpy(minut, "минут");
+ strcpy(chas, "час");
+ strcpy(den, "д");
+ if (end_time > now)
+ fucking_russian(left_mins, minut, "", "а", "ы");
+ else
+ fucking_russian(left_mins, minut, "", "у", "ы");
+ fucking_russian(left_hours, chas, "ов", "", "а");
+ fucking_russian(left_days, den, "ней", "ень", "ня");
+
+ if (end_time > now)
+ text_layer_set_text(left_time_layer, "До дембеля осталось");
+ else
+ text_layer_set_text(left_time_layer, "Ты дембель уже");
+ snprintf(left_time_str, sizeof(left_time_str), "%d %s,\n%d %s\nи %d %s",
+ left_days, den, left_hours, chas, left_mins, minut);
+ text_layer_set_text(left_time_layer2, left_time_str);
+
+ percent = 100.0 * (now - start_time) / (end_time - start_time);
+ if (percent > 100) percent = 100;
+ if (percent < 0) percent = 0;
+ static char percent_str[200];
+ snprintf(percent_str, sizeof(percent_str), "Ты отслужил %d.%02d%%", (int)percent, (int)(percent*100)%100);
+ text_layer_set_text(percent_layer, percent_str);
+ layer_mark_dirty(progress_layer);
+
+ static char time_str[20];
+ if (clock_is_24h_style())
+ strftime(time_str, sizeof(time_str), "%H:%M", tick_time);
+ else
+ strftime(time_str, sizeof(time_str), "%I:%M", tick_time);
+ text_layer_set_text(time_layer, time_str);
+}
+
+static void progress_layer_update_callback(Layer *layer, GContext *ctx)
+{
+ graphics_context_set_stroke_color(ctx, GColorBlack);
+ graphics_context_set_fill_color(ctx, GColorBlack);
+ GRect rect = layer_get_bounds(layer);
+ graphics_draw_round_rect(ctx, rect, 0);
+ rect.origin.x += 2;
+ rect.origin.y += 2;
+ rect.size.h -= 4;
+ rect.size.w = (rect.size.w-4)*percent / 100;
+ graphics_fill_rect(ctx, rect, 0, GCornerNone);
+}
+
+static void in_received_handler(DictionaryIterator *received, void *context) {
+ APP_LOG(APP_LOG_LEVEL_DEBUG, "Received config");
+ Tuple *tuple = dict_find(received, MSG_START_TIME);
+ if (tuple) {
+ start_time = tuple->value->int32;
+ persist_write_int(MSG_START_TIME, start_time);
+ }
+ tuple = dict_find(received, MSG_END_TIME);
+ if (tuple) {
+ end_time = tuple->value->int32;
+ persist_write_int(MSG_END_TIME, end_time);
+ }
+ time_t now = time(NULL);
+ handle_tick(localtime(&now), 0);
+}
+
+static void handle_init(void) {
+ struct tm tick_time;
+ tick_time.tm_year = 2014 - 1900;
+ tick_time.tm_mon = 12 - 1;
+ tick_time.tm_mday = 9;
+ tick_time.tm_hour = 12 - 1;
+ tick_time.tm_min = 0;
+ tick_time.tm_sec = 0;
+ start_time = mktime(&tick_time);
+ tick_time.tm_year = 2015 - 1900;
+ end_time = mktime(&tick_time);
+
+ // Read stored settings
+ if (persist_exists(MSG_START_TIME))
+ start_time = persist_read_int(MSG_START_TIME);
+ if (persist_exists(MSG_END_TIME))
+ end_time = persist_read_int(MSG_END_TIME);
+
+ // Open communication channel
+ app_message_register_inbox_received(in_received_handler);
+ app_message_open(64, 64);
+
+ // Create a window and text layer
+ window = window_create();
+
+ // Current time layer
+ time_layer = text_layer_create(GRect(0, 0, 144, 50));
+ // Set the text, font, and text alignment
+ text_layer_set_font(time_layer, fonts_get_system_font(FONT_KEY_BITHAM_42_BOLD));
+ text_layer_set_background_color(time_layer, GColorClear);
+ text_layer_set_text_alignment(time_layer, GTextAlignmentCenter);
+ // Add the text layer to the window
+ layer_add_child(window_get_root_layer(window), text_layer_get_layer(time_layer));
+
+ // Left time layer
+ left_time_layer = text_layer_create(GRect(0, 47, 144, 80));
+ // Set the text, font, and text alignment
+ text_layer_set_font(left_time_layer, fonts_get_system_font(FONT_KEY_GOTHIC_18));
+ text_layer_set_background_color(left_time_layer, GColorClear);
+ text_layer_set_text_alignment(left_time_layer, GTextAlignmentCenter);
+ // Add the text layer to the window
+ layer_add_child(window_get_root_layer(window), text_layer_get_layer(left_time_layer));
+
+ // Another Left time layer
+ left_time_layer2 = text_layer_create(GRect(0, 67, 144, 80));
+ // Set the text, font, and text alignment
+ text_layer_set_font(left_time_layer2, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD));
+ text_layer_set_background_color(left_time_layer2, GColorClear);
+ text_layer_set_text_alignment(left_time_layer2, GTextAlignmentCenter);
+ // Add the text layer to the window
+ layer_add_child(window_get_root_layer(window), text_layer_get_layer(left_time_layer2));
+
+ // Percent layer
+ percent_layer = text_layer_create(GRect(0, 130, 144, 80));
+ // Set the text, font, and text alignment
+ text_layer_set_font(percent_layer, fonts_get_system_font(FONT_KEY_GOTHIC_14_BOLD));
+ text_layer_set_background_color(percent_layer, GColorClear);
+ text_layer_set_text_alignment(percent_layer, GTextAlignmentCenter);
+ // Add the text layer to the window
+ layer_add_child(window_get_root_layer(window), text_layer_get_layer(percent_layer));
+
+ // Create progress bar
+ progress_layer = layer_create(GRect(2, 150, 140, 15));
+ layer_set_update_proc(progress_layer, &progress_layer_update_callback);
+ layer_add_child(window_get_root_layer(window), progress_layer);
+
+ time_t now = time(NULL);
+ handle_tick(localtime(&now), 0);
+
+ // Push the window
+ window_stack_push(window, true);
+
+ // Subscribe to time updates
+ tick_timer_service_subscribe(MINUTE_UNIT, handle_tick);
+
+ //light_enable(true); // For taking photos only!
+}
+
+static void handle_deinit(void) {
+ tick_timer_service_unsubscribe();
+
+ // Destroy layers
+ text_layer_destroy(time_layer);
+ text_layer_destroy(left_time_layer);
+ text_layer_destroy(left_time_layer2);
+ text_layer_destroy(percent_layer);
+ layer_destroy(progress_layer);
+
+ // Destroy the window
+ window_destroy(window);
+}
+
+int main(void) {
+ handle_init();
+ app_event_loop();
+ handle_deinit();
+}
diff --git a/src/pebble-js-app.js b/src/pebble-js-app.js
new file mode 100644
index 0000000..e5d12db
--- /dev/null
+++ b/src/pebble-js-app.js
@@ -0,0 +1,62 @@
+var initialized = false;
+var options = {
+ "config_start_year": 2014,
+ "config_start_month": 12,
+ "config_start_day": 9,
+ "config_start_hour": 12,
+ "config_start_min": 0,
+ "config_end_year": 2015,
+ "config_end_month": 12,
+ "config_end_day": 9,
+ "config_end_hour": 12,
+ "config_end_min": 0
+};
+
+function java_mktime(hour,minute,day,month,year)
+{
+ var localOffset = new Date().getTimezoneOffset() * 60;
+ return new Date(year, month - 1, day, hour, minute).getTime() / 1000 - localOffset;
+}
+
+function send_config()
+{
+ var config = {
+ "start_time": java_mktime(options["config_start_hour"], options["config_start_min"], options["config_start_day"], options["config_start_month"], options["config_start_year"]),
+ "end_time": java_mktime(options["config_end_hour"], options["config_end_min"], options["config_end_day"], options["config_end_month"], options["config_end_year"])
+ };
+ Pebble.sendAppMessage(config);
+}
+
+Pebble.addEventListener("ready", function() {
+ initialized = true;
+ var json = window.localStorage.getItem('dembel-config');
+ if (typeof json === 'string') {
+ try {
+ options = JSON.parse(json);
+ send_config();
+ console.log("Loaded stored config: " + json);
+ } catch(e) {
+ console.log("stored config json parse error: " + json + ' - ' + e);
+ }
+ }
+});
+
+Pebble.addEventListener("showConfiguration", function() {
+ console.log("showing configuration");
+ var cfg = '?config=' + encodeURI(JSON.stringify(options));
+ Pebble.openURL("http://clusterrr.com/pebble_configs/dembel.php" + cfg);
+});
+
+Pebble.addEventListener("webviewclosed", function(e) {
+ var response = decodeURIComponent(e.response);
+ if (response.charAt(0) == "{" && response.slice(-1) == "}" && response.length > 5) {
+ try {
+ options = JSON.parse(response);
+ send_config();
+ window.localStorage.setItem('dembel-config', response);
+ } catch(e) {
+ console.log("Response config json parse error: " + response + ' - ' + e);
+ }
+ console.log("Options = " + response);
+ }
+});
diff --git a/wscript b/wscript
new file mode 100644
index 0000000..b20f58f
--- /dev/null
+++ b/wscript
@@ -0,0 +1,62 @@
+
+ #
+# This file is the default set of rules to compile a Pebble project.
+#
+# Feel free to customize this to your needs.
+#
+
+import os.path
+try:
+ from sh import CommandNotFound, jshint, cat, ErrorReturnCode_2
+ hint = jshint
+except (ImportError, CommandNotFound):
+ hint = None
+
+top = '.'
+out = 'build'
+
+def options(ctx):
+ ctx.load('pebble_sdk')
+
+def configure(ctx):
+ ctx.load('pebble_sdk')
+
+def build(ctx):
+ if False and hint is not None:
+ try:
+ hint([node.abspath() for node in ctx.path.ant_glob("src/**/*.js")], _tty_out=False) # no tty because there are none in the cloudpebble sandbox.
+ except ErrorReturnCode_2 as e:
+ ctx.fatal("\nJavaScript linting failed (you can disable this in Project Settings):\n" + e.stdout)
+
+ # Concatenate all our JS files (but not recursively), and only if any JS exists in the first place.
+ ctx.path.make_node('src/js/').mkdir()
+ js_paths = ctx.path.ant_glob(['src/*.js', 'src/**/*.js'])
+ if js_paths:
+ ctx(rule='cat ${SRC} > ${TGT}', source=js_paths, target='pebble-js-app.js')
+ has_js = True
+ else:
+ has_js = False
+
+ ctx.load('pebble_sdk')
+
+ build_worker = os.path.exists('worker_src')
+ binaries = []
+
+ for p in ctx.env.TARGET_PLATFORMS:
+ ctx.set_env(ctx.all_envs[p])
+ ctx.set_group(ctx.env.PLATFORM_NAME)
+ app_elf='{}/pebble-app.elf'.format(p)
+ ctx.pbl_program(source=ctx.path.ant_glob('src/**/*.c'),
+ target=app_elf)
+
+ if build_worker:
+ worker_elf='{}/pebble-worker.elf'.format(p)
+ binaries.append({'platform': p, 'app_elf': app_elf, 'worker_elf': worker_elf})
+ ctx.pbl_worker(source=ctx.path.ant_glob('worker_src/**/*.c'),
+ target=worker_elf)
+ else:
+ binaries.append({'platform': p, 'app_elf': app_elf})
+
+ ctx.set_group('bundle')
+ ctx.pbl_bundle(binaries=binaries, js='pebble-js-app.js' if has_js else [])
+ \ No newline at end of file