diff --git a/appinfo.json b/appinfo.json new file mode 100644 index 0000000..01d7a74 --- /dev/null +++ b/appinfo.json @@ -0,0 +1,40 @@ +{ + "resources": { + "media": [ + { + "type": "png-trans", + "file": "images/action_icon_minus.png", + "name": "MINUS" + }, + { + "type": "png-trans", + "file": "images/action_icon_plus.png", + "name": "PLUS" + }, + { + "type": "png-trans", + "file": "images/reset.png", + "name": "RESET" + }, + { + "type": "png", + "file": "images/icon.png", + "name": "ICON", + "menuIcon": true + } + ] + }, + "versionCode": 1, + "shortName": "counter", + "capabilities": [ + "" + ], + "versionLabel": "1.0", + "longName": "Counter is a multipurpose counting app with applications ranging from lap tracking to card counting.", + "uuid": "36bab645-70c5-472b-b99f-afc9f8656c70", + "appKeys": {}, + "companyName": "matthewbauer", + "watchapp": { + "watchface": false + } +} diff --git a/resources/images/action_icon_minus.png b/resources/images/action_icon_minus.png new file mode 100644 index 0000000..7bb4f73 Binary files /dev/null and b/resources/images/action_icon_minus.png differ diff --git a/resources/images/action_icon_plus.png b/resources/images/action_icon_plus.png new file mode 100644 index 0000000..1ba4c9a Binary files /dev/null and b/resources/images/action_icon_plus.png differ diff --git a/resources/images/icon.png b/resources/images/icon.png new file mode 100644 index 0000000..b9362e5 Binary files /dev/null and b/resources/images/icon.png differ diff --git a/resources/images/reset.png b/resources/images/reset.png new file mode 100644 index 0000000..63434c1 Binary files /dev/null and b/resources/images/reset.png differ diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..b3019ab --- /dev/null +++ b/src/main.c @@ -0,0 +1,112 @@ +#include + +#define COUNT_PKEY 1 +#define COUNT_DEFAULT 0 +#define REPEAT_INTERVAL 50 + +Window *window; +TextLayer *text_layer; + +GBitmap *action_icon_plus; +GBitmap *action_icon_minus; +GBitmap *action_icon_reset; + +ActionBarLayer *action_bar; + +static int count = COUNT_DEFAULT; + +void update() { + static char buffer[10]; + snprintf(buffer, sizeof(buffer), "%i", count); + text_layer_set_text(text_layer, buffer); +} + +void increment() { + count++; +} + +void decrement() { + count--; +} + +void reset() { + count = 0; +} + +void select_click_handler(ClickRecognizerRef recognizer, void *context) { + increment(); + update(); +} + +void down_click_handler(ClickRecognizerRef recognizer, void *context) { + decrement(); + update(); +} + +void up_click_handler(ClickRecognizerRef recognizer, void *context) { + reset(); + update(); +} + +void click_config_provider(void *context) { + window_single_repeating_click_subscribe(BUTTON_ID_SELECT, REPEAT_INTERVAL, (ClickHandler) select_click_handler); + window_single_repeating_click_subscribe(BUTTON_ID_UP, REPEAT_INTERVAL, (ClickHandler) up_click_handler); + window_single_repeating_click_subscribe(BUTTON_ID_DOWN, REPEAT_INTERVAL, (ClickHandler) down_click_handler); +} + +void window_load(Window *window) { + action_bar = action_bar_layer_create(); + action_bar_layer_add_to_window(action_bar, window); + action_bar_layer_set_click_config_provider(action_bar, click_config_provider); + + action_bar_layer_set_icon(action_bar, BUTTON_ID_UP, action_icon_reset); + action_bar_layer_set_icon(action_bar, BUTTON_ID_SELECT, action_icon_plus); + action_bar_layer_set_icon(action_bar, BUTTON_ID_DOWN, action_icon_minus); + + Layer *layer = window_get_root_layer(window); + GRect bounds = layer_get_frame(layer); + const int16_t width = layer_get_frame(layer).size.w - ACTION_BAR_WIDTH - 3; + + text_layer = text_layer_create(GRect(0, 44, width, bounds.size.h)); + text_layer_set_font(text_layer, fonts_get_system_font(FONT_KEY_BITHAM_42_BOLD)); + text_layer_set_background_color(text_layer, GColorClear); + update(); + text_layer_set_text_alignment(text_layer, GTextAlignmentCenter); + layer_add_child(layer, text_layer_get_layer(text_layer)); +} + +void window_unload(Window *window) { + text_layer_destroy(text_layer); + action_bar_layer_destroy(action_bar); +} + +void init() { + action_icon_plus = gbitmap_create_with_resource(RESOURCE_ID_PLUS_WHITE); + action_icon_minus = gbitmap_create_with_resource(RESOURCE_ID_MINUS_WHITE); + action_icon_reset = gbitmap_create_with_resource(RESOURCE_ID_RESET_WHITE); + + window = window_create(); + + window_set_window_handlers(window, (WindowHandlers) { + .load = window_load, + .unload = window_unload, + }); + + count = persist_exists(COUNT_PKEY) ? persist_read_int(COUNT_PKEY) : COUNT_DEFAULT; + + window_stack_push(window, true); +} + +void deinit() { + persist_write_int(COUNT_PKEY, count); + window_destroy(window); + gbitmap_destroy(action_icon_plus); + gbitmap_destroy(action_icon_minus); + gbitmap_destroy(action_icon_reset); +} + +int main() { + init(); + app_event_loop(); + deinit(); +} diff --git a/wscript b/wscript new file mode 100644 index 0000000..15d208f --- /dev/null +++ b/wscript @@ -0,0 +1,46 @@ + +# +# This file is the default set of rules to compile a Pebble project. +# +# Feel free to customize this to your needs. +# + +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') + global hint + if hint is not None: + hint = hint.bake(['--config', 'pebble-jshintrc']) + +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 = [node.abspath() for node in ctx.path.ant_glob("src/*.js")] + if js_paths: + ctx.exec_command(['cat'] + js_paths, stdout=open('src/js/pebble-js-app.js', 'a')) + + ctx.load('pebble_sdk') + + ctx.pbl_program(source=ctx.path.ant_glob('src/**/*.c'), + target='pebble-app.elf') + + ctx.pbl_bundle(elf='pebble-app.elf', + js=ctx.path.ant_glob('src/js/**/*.js')) +