From cac5d9c3203e23b32d9dc8d233f79576b77487b6 Mon Sep 17 00:00:00 2001 From: dyedgreen Date: Wed, 22 Jun 2016 23:25:57 +0200 Subject: [PATCH] Added loading * Still to do: sending the address in a proper way! --- src/directions_window.c | 8 +- src/js/app.js | 2 +- src/loading_window.c | 172 +++++++++++++++++++++++++++++++++++++++- src/loading_window.h | 8 ++ 4 files changed, 185 insertions(+), 5 deletions(-) diff --git a/src/directions_window.c b/src/directions_window.c index c73917f..43bfafc 100644 --- a/src/directions_window.c +++ b/src/directions_window.c @@ -203,12 +203,12 @@ static void app_message_send_search_data() { dict_write_cstring(iter, MESSAGE_KEY_SEARCH, message); // Send the outbox app_message_outbox_send(); + // Display loading anim window + loading_window_push(); } else { // Display network error window_display_error(Network); } - // Display loading anim window - // TODO: implement this } else { route_data->callback = true; } @@ -247,6 +247,8 @@ static void app_message_destroy_resources() { // Network error callback void window_display_error(enum ErrorType err) { + // Remove the loading window + loading_window_finish(); // Show the error window error_window_push(err); // Remove this window from the window stack @@ -263,7 +265,7 @@ static void window_update_data() { #endif menu_layer_reload_data(directions_list); // Hide the loading view - // TODO: loading will be hidden here + loading_window_finish(); } // Window unload handler diff --git a/src/js/app.js b/src/js/app.js index 06a0014..299f9bb 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -101,7 +101,7 @@ function fetchAndSendRoute(routeType, destination) { setTimeout(function() { // Some dummy loading time sendRoute(true, 560, 16, ['This is the first step', 'This is the second step', 'This is the third step', 'This is the final step']); - }, 2000); + }, 10000); } // Accept data from the pebble watch diff --git a/src/loading_window.c b/src/loading_window.c index 2696c5e..b02826a 100644 --- a/src/loading_window.c +++ b/src/loading_window.c @@ -1,2 +1,172 @@ -#pragma once #include +#include "loading_window.h" + +// TODO: Tidy this! (will do later) +// Some stuff added by me +static bool will_close; + +// The loading window, implementation stolen from pebble UI examples +typedef Layer ProgressLayer; + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +ProgressLayer* progress_layer_create(GRect frame); +void progress_layer_destroy(ProgressLayer* progress_layer); +void progress_layer_increment_progress(ProgressLayer* progress_layer, int16_t progress); +void progress_layer_set_progress(ProgressLayer* progress_layer, int16_t progress_percent); +void progress_layer_set_corner_radius(ProgressLayer* progress_layer, uint16_t corner_radius); +void progress_layer_set_foreground_color(ProgressLayer* progress_layer, GColor color); +void progress_layer_set_background_color(ProgressLayer* progress_layer, GColor color); + +typedef struct { + int16_t progress_percent; + int16_t corner_radius; + GColor foreground_color; + GColor background_color; +} ProgressLayerData; + +static int16_t scale_progress_bar_width_px(unsigned int progress_percent, int16_t rect_width_px) { + return ((progress_percent * (rect_width_px)) / 100); +} + +static void progress_layer_update_proc(ProgressLayer* progress_layer, GContext* ctx) { + ProgressLayerData *data = (ProgressLayerData *)layer_get_data(progress_layer); + GRect bounds = layer_get_bounds(progress_layer); + + int16_t progress_bar_width_px = scale_progress_bar_width_px(data->progress_percent, bounds.size.w); + GRect progress_bar = GRect(bounds.origin.x, bounds.origin.y, progress_bar_width_px, bounds.size.h); + + graphics_context_set_fill_color(ctx, data->background_color); + graphics_fill_rect(ctx, bounds, data->corner_radius, GCornersAll); + + graphics_context_set_fill_color(ctx, data->foreground_color); + graphics_fill_rect(ctx, progress_bar, data->corner_radius, GCornersAll); + +#ifdef PBL_PLATFORM_APLITE + graphics_context_set_stroke_color(ctx, data->background_color); + graphics_draw_rect(ctx, progress_bar); +#endif +} + +ProgressLayer* progress_layer_create(GRect frame) { + ProgressLayer *progress_layer = layer_create_with_data(frame, sizeof(ProgressLayerData)); + layer_set_update_proc(progress_layer, progress_layer_update_proc); + layer_mark_dirty(progress_layer); + + ProgressLayerData *data = (ProgressLayerData *)layer_get_data(progress_layer); + data->progress_percent = 0; + data->corner_radius = 1; + data->foreground_color = GColorBlack; + data->background_color = GColorWhite; + + return progress_layer; +} + +void progress_layer_destroy(ProgressLayer* progress_layer) { + if (progress_layer) { + layer_destroy(progress_layer); + } +} + +void progress_layer_increment_progress(ProgressLayer* progress_layer, int16_t progress) { + ProgressLayerData *data = (ProgressLayerData *)layer_get_data(progress_layer); + data->progress_percent = MIN(100, data->progress_percent + progress); + layer_mark_dirty(progress_layer); +} + +void progress_layer_set_progress(ProgressLayer* progress_layer, int16_t progress_percent) { + ProgressLayerData *data = (ProgressLayerData *)layer_get_data(progress_layer); + data->progress_percent = MIN(100, progress_percent); + layer_mark_dirty(progress_layer); +} + +void progress_layer_set_corner_radius(ProgressLayer* progress_layer, uint16_t corner_radius) { + ProgressLayerData *data = (ProgressLayerData *)layer_get_data(progress_layer); + data->corner_radius = corner_radius; + layer_mark_dirty(progress_layer); +} + +void progress_layer_set_foreground_color(ProgressLayer* progress_layer, GColor color) { + ProgressLayerData *data = (ProgressLayerData *)layer_get_data(progress_layer); + data->foreground_color = color; + layer_mark_dirty(progress_layer); +} + +void progress_layer_set_background_color(ProgressLayer* progress_layer, GColor color) { + ProgressLayerData *data = (ProgressLayerData *)layer_get_data(progress_layer); + data->background_color = color; + layer_mark_dirty(progress_layer); +} + +static Window *s_window; +static ProgressLayer *s_progress_layer; + +static AppTimer *s_timer; +static int s_progress; + +static void progress_callback(void *context); + +static void next_timer() { + s_timer = app_timer_register(PROGRESS_LAYER_WINDOW_DELTA, progress_callback, NULL); +} + +static void progress_callback(void *context) { + s_progress += (s_progress < 85 || will_close) ? 1 : 0; + progress_layer_set_progress(s_progress_layer, s_progress); + next_timer(); + // Close when progress hits 100 + if (s_progress == 100) { + window_stack_remove(s_window, true); + } +} + +static void window_load(Window *window) { + will_close = false; + + Layer *window_layer = window_get_root_layer(window); + GRect bounds = layer_get_bounds(window_layer); + + s_progress_layer = progress_layer_create(GRect((bounds.size.w - PROGRESS_LAYER_WINDOW_WIDTH) / 2, (bounds.size.h - 3) / 2, PROGRESS_LAYER_WINDOW_WIDTH, 6)); + progress_layer_set_progress(s_progress_layer, 0); + progress_layer_set_corner_radius(s_progress_layer, 2); + progress_layer_set_foreground_color(s_progress_layer, GColorWhite); + progress_layer_set_background_color(s_progress_layer, GColorBlack); + layer_add_child(window_layer, s_progress_layer); +} + +static void window_unload(Window *window) { + progress_layer_destroy(s_progress_layer); + + window_destroy(window); + s_window = NULL; +} + +static void window_appear(Window *window) { + s_progress = 0; + next_timer(); +} + +static void window_disappear(Window *window) { + if(s_timer) { + app_timer_cancel(s_timer); + s_timer = NULL; + } +} + +void loading_window_push() { + if(!s_window) { + s_window = window_create(); + window_set_background_color(s_window, PBL_IF_COLOR_ELSE(GColorLightGray, GColorWhite)); + window_set_window_handlers(s_window, (WindowHandlers) { + .load = window_load, + .appear = window_appear, + .disappear = window_disappear, + .unload = window_unload + }); + } + window_stack_push(s_window, true); +} + +void loading_window_finish() { + will_close = true; +} diff --git a/src/loading_window.h b/src/loading_window.h index e69de29..74fccde 100644 --- a/src/loading_window.h +++ b/src/loading_window.h @@ -0,0 +1,8 @@ +#pragma once +#include + +#define PROGRESS_LAYER_WINDOW_DELTA 33 +#define PROGRESS_LAYER_WINDOW_WIDTH 80 + +void loading_window_push(); +void loading_window_finish();