mirror of
https://github.com/Threnklyn/pebble-directions.git
synced 2026-05-18 21:03:27 +02:00
New directions ui
* Beautiful directions list ui * Fixed a bug where the js part would send too long strings * Fixed a bug where the js part would send directions data although there where to many steps
This commit is contained in:
@@ -27,6 +27,7 @@
|
|||||||
"SUCCESS",
|
"SUCCESS",
|
||||||
"DISTANCE",
|
"DISTANCE",
|
||||||
"TIME",
|
"TIME",
|
||||||
|
"INSTRUCTION_ICONS",
|
||||||
"INSTRUCTIONS[20]"
|
"INSTRUCTIONS[20]"
|
||||||
],
|
],
|
||||||
"resources": {
|
"resources": {
|
||||||
@@ -96,6 +97,42 @@
|
|||||||
"name": "ICON_ERROR_OTHER",
|
"name": "ICON_ERROR_OTHER",
|
||||||
"targetPlatforms": null,
|
"targetPlatforms": null,
|
||||||
"type": "bitmap"
|
"type": "bitmap"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "images/step_forward.png",
|
||||||
|
"name": "ICON_STEP_FORWARD",
|
||||||
|
"targetPlatforms": null,
|
||||||
|
"type": "bitmap"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "images/step_left.png",
|
||||||
|
"name": "ICON_STEP_LEFT",
|
||||||
|
"targetPlatforms": null,
|
||||||
|
"type": "bitmap"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "images/step_uleft.png",
|
||||||
|
"name": "ICON_STEP_ULEFT",
|
||||||
|
"targetPlatforms": null,
|
||||||
|
"type": "bitmap"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "images/step_right.png",
|
||||||
|
"name": "ICON_STEP_RIGHT",
|
||||||
|
"targetPlatforms": null,
|
||||||
|
"type": "bitmap"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "images/step_uright.png",
|
||||||
|
"name": "ICON_STEP_URIGHT",
|
||||||
|
"targetPlatforms": null,
|
||||||
|
"type": "bitmap"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "images/step_attr.png",
|
||||||
|
"name": "ICON_STEP_ATTR",
|
||||||
|
"targetPlatforms": null,
|
||||||
|
"type": "bitmap"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 360 B |
Binary file not shown.
|
After Width: | Height: | Size: 147 B |
Binary file not shown.
|
After Width: | Height: | Size: 569 B |
Binary file not shown.
|
After Width: | Height: | Size: 553 B |
Binary file not shown.
|
After Width: | Height: | Size: 587 B |
Binary file not shown.
|
After Width: | Height: | Size: 588 B |
+99
-59
@@ -1,120 +1,160 @@
|
|||||||
#include "directions_draw.h"
|
#include "directions_draw.h"
|
||||||
|
|
||||||
|
|
||||||
#define SQUARE_CELL_HEIGHT_SUMMARY 64
|
// Draw the more indicator and return the new bounds (excluding the space occupied by the more indicator)
|
||||||
#define SQUARE_CELL_HEIGHT_STEP 122
|
GRect directions_draw_more_indicator(GContext *ctx, GRect bounds) {
|
||||||
|
// Set the colors
|
||||||
|
GColor color_bg;
|
||||||
|
GColor color_arrow = GColorBlack;
|
||||||
|
#ifdef PBL_COLOR
|
||||||
|
color_bg = GColorLightGray;
|
||||||
|
#else
|
||||||
|
color_bg = GColorWhite;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Draw the background
|
||||||
|
graphics_context_set_fill_color(ctx, color_bg);
|
||||||
|
graphics_fill_rect(ctx, GRect(0, bounds.size.h - 17, bounds.size.w, 17), 0, GCornerNone);
|
||||||
|
// Draw the arrow (draws a path)
|
||||||
|
struct GPathInfo path_arrow_info = {
|
||||||
|
.num_points = 3,
|
||||||
|
.points = (GPoint []) { {0,0}, {6,5}, {12,0} },
|
||||||
|
};
|
||||||
|
GPath *path_arrow = gpath_create(&path_arrow_info);
|
||||||
|
gpath_move_to(path_arrow, (GPoint) {(bounds.size.w - 12) / 2, bounds.size.h - 10});
|
||||||
|
graphics_context_set_fill_color(ctx, color_arrow);
|
||||||
|
gpath_draw_filled(ctx, path_arrow);
|
||||||
|
gpath_destroy(path_arrow);
|
||||||
|
|
||||||
|
// Return the new bounds
|
||||||
|
bounds.size.h -= 15;
|
||||||
|
return bounds;
|
||||||
|
}
|
||||||
|
|
||||||
// Work out the height of each cell
|
// Work out the height of each cell
|
||||||
int16_t directions_get_cell_height(int16_t window_height, int16_t cell_index) {
|
int16_t directions_get_cell_height(int16_t window_height, int16_t cell_index) {
|
||||||
// Round watches paginate!
|
// Each cell occupies an entire screen!
|
||||||
#ifdef PBL_ROUND
|
return window_height;
|
||||||
return window_height;
|
|
||||||
#endif
|
|
||||||
// Square watches scroll!
|
|
||||||
switch (cell_index) {
|
|
||||||
case 0:
|
|
||||||
return SQUARE_CELL_HEIGHT_SUMMARY;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return SQUARE_CELL_HEIGHT_STEP;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the title card
|
// Draw the title card
|
||||||
void directions_draw_summary(GContext *ctx, GRect bounds, GColor color, int distance, int time) {
|
void directions_draw_summary(GContext *ctx, GRect bounds, GColor color, int distance, int time, char *string_address) {
|
||||||
// Get the strings
|
// Get the strings
|
||||||
char string_distance[10];
|
char string_distance[10];
|
||||||
char string_time[10];
|
char string_time[10];
|
||||||
snprintf(string_distance, sizeof(string_distance), "%i m", distance);
|
snprintf(string_distance, sizeof(string_distance), "%i m", distance);
|
||||||
snprintf(string_time, sizeof(string_time), "%i min", time);
|
snprintf(string_time, sizeof(string_time), "%i min", time);
|
||||||
|
|
||||||
// Get the colors
|
// Get the colors
|
||||||
#ifdef PBL_COLOR
|
#ifdef PBL_COLOR
|
||||||
GColor color_secondary = GColorDarkGray;
|
GColor color_distance = GColorDarkGray;
|
||||||
#else
|
#else
|
||||||
GColor color_secondary = GColorWhite;
|
GColor color_distance = GColorWhite;
|
||||||
color = GColorBlack;
|
color = GColorBlack;
|
||||||
#endif
|
#endif
|
||||||
// Draw the background
|
|
||||||
graphics_context_set_fill_color(ctx, color);
|
// White background
|
||||||
|
graphics_context_set_fill_color(ctx, GColorWhite);
|
||||||
graphics_fill_rect(ctx, bounds, 0, GCornerNone);
|
graphics_fill_rect(ctx, bounds, 0, GCornerNone);
|
||||||
|
|
||||||
|
// Draw the more indicator and get the new bounds size
|
||||||
|
bounds = directions_draw_more_indicator(ctx, bounds);
|
||||||
|
|
||||||
|
// Draw the UI
|
||||||
#ifdef PBL_ROUND
|
#ifdef PBL_ROUND
|
||||||
// ************
|
// ************
|
||||||
// * Round UI *
|
// * Round UI *
|
||||||
// ************
|
// ************
|
||||||
// Outside ring
|
// Header bg (takes 1/2 of screen height)
|
||||||
graphics_context_set_fill_color(ctx, GColorWhite);
|
graphics_context_set_fill_color(ctx, color);
|
||||||
graphics_fill_radial(ctx, bounds, GOvalScaleModeFitCircle, 30, 0, TRIG_MAX_ANGLE);
|
graphics_fill_circle(ctx, (GPoint) {bounds.size.w / 2, bounds.size.h / (-2)}, bounds.size.h);
|
||||||
// Time
|
// Time
|
||||||
GRect time_box = GRect(4, (bounds.size.h - 46) / 2, bounds.size.w - 8, 28);
|
GRect time_box = GRect(0, 23, bounds.size.w, 28);
|
||||||
graphics_context_set_text_color(ctx, GColorWhite);
|
graphics_context_set_text_color(ctx, GColorWhite);
|
||||||
graphics_draw_text(ctx, string_time, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD), time_box, GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL);
|
graphics_draw_text(ctx, string_time, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD), time_box, GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL);
|
||||||
// Distance
|
// Distance
|
||||||
GRect distance_box = GRect(4, (bounds.size.h - 46) / 2 + time_box.size.h, bounds.size.w - 8, 18);
|
GRect distance_box = GRect(0, 23 + time_box.size.h, bounds.size.w, 18);
|
||||||
graphics_context_set_text_color(ctx, color_secondary);
|
graphics_context_set_text_color(ctx, color_distance);
|
||||||
graphics_draw_text(ctx, string_distance, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD), distance_box, GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL);
|
graphics_draw_text(ctx, string_distance, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD), distance_box, GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL);
|
||||||
|
// Address
|
||||||
|
GRect address_box = GRect(0, 7 + bounds.size.h / 2, bounds.size.w, bounds.size.h / 2 - 14);
|
||||||
|
GTextAttributes *text_attributes = graphics_text_attributes_create();
|
||||||
|
graphics_text_attributes_enable_screen_text_flow(text_attributes, 7);
|
||||||
|
graphics_context_set_text_color(ctx, color);
|
||||||
|
graphics_draw_text(ctx, string_address, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD), address_box, GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter, text_attributes);
|
||||||
|
graphics_text_attributes_destroy(text_attributes);
|
||||||
#else
|
#else
|
||||||
// *************
|
// *************
|
||||||
// * Square UI *
|
// * Square UI *
|
||||||
// *************
|
// *************
|
||||||
|
// Header bg
|
||||||
|
GRect header_box = GRect(0, 0, bounds.size.w, 67);
|
||||||
|
graphics_context_set_fill_color(ctx, color);
|
||||||
|
graphics_fill_rect(ctx, header_box, 0, GCornerNone);
|
||||||
// Time
|
// Time
|
||||||
GRect time_box = GRect(7, 5, bounds.size.w - 14, 28);
|
GRect time_box = GRect(7, 7, bounds.size.w - 14, 28);
|
||||||
graphics_context_set_text_color(ctx, GColorWhite);
|
graphics_context_set_text_color(ctx, GColorWhite);
|
||||||
graphics_draw_text(ctx, string_time, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD), time_box, GTextOverflowModeWordWrap, GTextAlignmentLeft, NULL);
|
graphics_draw_text(ctx, string_time, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD), time_box, GTextOverflowModeWordWrap, GTextAlignmentLeft, NULL);
|
||||||
// Distance
|
// Distance
|
||||||
GRect distance_box = GRect(7, time_box.size.h + 5, bounds.size.w - 14, 18);
|
GRect distance_box = GRect(7, 7 + time_box.size.h, bounds.size.w - 14, 18);
|
||||||
graphics_context_set_text_color(ctx, color_secondary);
|
graphics_context_set_text_color(ctx, color_distance);
|
||||||
graphics_draw_text(ctx, string_distance, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD), distance_box, GTextOverflowModeWordWrap, GTextAlignmentLeft, NULL);
|
graphics_draw_text(ctx, string_distance, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD), distance_box, GTextOverflowModeWordWrap, GTextAlignmentLeft, NULL);
|
||||||
|
// Address
|
||||||
|
GRect address_box = GRect(7, 7 + header_box.size.h, bounds.size.w - 14, bounds.size.h - header_box.size.h - 14);
|
||||||
|
graphics_context_set_text_color(ctx, color);
|
||||||
|
graphics_draw_text(ctx, string_address, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD), address_box, GTextOverflowModeTrailingEllipsis, GTextAlignmentLeft, NULL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a step
|
// Draw a step
|
||||||
void directions_draw_step(GContext *ctx, GRect bounds, GColor color, char *text, int16_t data_index, int16_t data_count) {
|
void directions_draw_step(GContext *ctx, GRect bounds, GColor color, char *text, GBitmap *step_icon, int16_t data_index, int16_t data_count) {
|
||||||
// Get the colors
|
// Get the colors
|
||||||
#ifdef PBL_COLOR
|
#ifdef PBL_BW
|
||||||
GColor color_text = GColorDarkGray;
|
color = GColorWhite;
|
||||||
#else
|
|
||||||
GColor color_text = GColorBlack;
|
|
||||||
color = GColorBlack;
|
|
||||||
#endif
|
#endif
|
||||||
// Draw the background
|
GColor color_text = GColorBlack;
|
||||||
|
|
||||||
|
// White background
|
||||||
graphics_context_set_fill_color(ctx, GColorWhite);
|
graphics_context_set_fill_color(ctx, GColorWhite);
|
||||||
graphics_fill_rect(ctx, bounds, 0, GCornerNone);
|
graphics_fill_rect(ctx, bounds, 0, GCornerNone);
|
||||||
|
|
||||||
|
// Draw the more indicator and get the new bounds size (if this is not the last cell)
|
||||||
|
if (data_index + 1 < data_count) {
|
||||||
|
bounds = directions_draw_more_indicator(ctx, bounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the UI
|
||||||
#ifdef PBL_ROUND
|
#ifdef PBL_ROUND
|
||||||
// ************
|
// ************
|
||||||
// * Round UI *
|
// * Round UI *
|
||||||
// ************
|
// ************
|
||||||
// Draw text
|
// Draw header / icon bg (takes 60px of screen height)
|
||||||
GRect text_box = GRect(5, (bounds.size.w - 96) / 2, bounds.size.w - 10, 96);
|
|
||||||
GTextAttributes *text_attributes = graphics_text_attributes_create();
|
|
||||||
graphics_text_attributes_enable_screen_text_flow(text_attributes, 5);
|
|
||||||
graphics_context_set_text_color(ctx, color_text);
|
|
||||||
graphics_draw_text(ctx, text, fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), text_box, GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter, text_attributes);
|
|
||||||
graphics_text_attributes_destroy(text_attributes);
|
|
||||||
// Draw more indicators
|
|
||||||
graphics_context_set_fill_color(ctx, color);
|
graphics_context_set_fill_color(ctx, color);
|
||||||
if (data_index < data_count - 1) {
|
graphics_fill_circle(ctx, GPoint(bounds.size.w / 2, -80), 140);
|
||||||
// Bottom
|
// Draw icon
|
||||||
graphics_fill_circle(ctx, GPoint(bounds.size.w / 2, bounds.size.h), 8);
|
graphics_context_set_compositing_mode(ctx, GCompOpSet);
|
||||||
}
|
graphics_draw_bitmap_in_rect(ctx, step_icon, GRect((bounds.size.w - 24) / 2, 24, 24, 24));
|
||||||
if (data_index > 0) {
|
// Draw text
|
||||||
// Top
|
GRect text_box = GRect(0, 67, bounds.size.w, bounds.size.h - 74);
|
||||||
graphics_fill_circle(ctx, GPoint(bounds.size.w / 2, 0), 8);
|
GTextAttributes *text_attributes = graphics_text_attributes_create();
|
||||||
}
|
graphics_text_attributes_enable_screen_text_flow(text_attributes, 7);
|
||||||
|
graphics_context_set_text_color(ctx, color_text);
|
||||||
|
graphics_draw_text(ctx, text, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD), text_box, GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter, text_attributes);
|
||||||
|
graphics_text_attributes_destroy(text_attributes);
|
||||||
#else
|
#else
|
||||||
// *************
|
// *************
|
||||||
// * Square UI *
|
// * Square UI *
|
||||||
// *************
|
// *************
|
||||||
|
// Draw header/icon bg
|
||||||
|
GRect header_box = GRect(0, 0, bounds.size.w, 52);
|
||||||
|
graphics_context_set_fill_color(ctx, color);
|
||||||
|
graphics_fill_rect(ctx, header_box, 0, GCornerNone);
|
||||||
|
// Draw icon
|
||||||
|
graphics_context_set_compositing_mode(ctx, GCompOpSet);
|
||||||
|
graphics_draw_bitmap_in_rect(ctx, step_icon, GRect((bounds.size.w - 24) / 2, 14, 24, 24));
|
||||||
// Draw text
|
// Draw text
|
||||||
GRect text_box = GRect(7, 3, bounds.size.w - 14, bounds.size.h - 6);
|
GRect text_box = GRect(7, 7 + header_box.size.h, bounds.size.w - 14, bounds.size.h - header_box.size.h - 14);
|
||||||
graphics_context_set_text_color(ctx, color_text);
|
graphics_context_set_text_color(ctx, color_text);
|
||||||
graphics_draw_text(ctx, text, fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), text_box, GTextOverflowModeTrailingEllipsis, GTextAlignmentLeft, NULL);
|
graphics_draw_text(ctx, text, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD), text_box, GTextOverflowModeTrailingEllipsis, GTextAlignmentLeft, NULL);
|
||||||
// Draw block-end indicator (if not last block)
|
|
||||||
if (data_index < data_count - 1) {
|
|
||||||
GRect line_box = GRect(7, text_box.size.h + 1, 40, 4);
|
|
||||||
graphics_context_set_fill_color(ctx, color);
|
|
||||||
graphics_fill_rect(ctx, line_box, 2, GCornersAll);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,5 +4,5 @@
|
|||||||
// Return the height of a cell (this groupes layout functions in one file)
|
// Return the height of a cell (this groupes layout functions in one file)
|
||||||
int16_t directions_get_cell_height(int16_t window_height, int16_t cell_index);
|
int16_t directions_get_cell_height(int16_t window_height, int16_t cell_index);
|
||||||
// Draw cells
|
// Draw cells
|
||||||
void directions_draw_summary(GContext *ctx, GRect bounds, GColor color, int distance, int time);
|
void directions_draw_summary(GContext *ctx, GRect bounds, GColor color, int distance, int time, char *address);
|
||||||
void directions_draw_step(GContext *ctx, GRect bounds, GColor color, char *text, int16_t data_index, int16_t data_count);
|
void directions_draw_step(GContext *ctx, GRect bounds, GColor color, char *text, GBitmap *step_icon, int16_t data_index, int16_t data_count);
|
||||||
|
|||||||
+96
-3
@@ -9,6 +9,7 @@
|
|||||||
#define PROGRESS_SEARCH_SEND 50
|
#define PROGRESS_SEARCH_SEND 50
|
||||||
#define PROGRESS_DISTANCE_RECIVED 80
|
#define PROGRESS_DISTANCE_RECIVED 80
|
||||||
#define PROGRESS_TIME_RECIVED PROGRESS_DISTANCE_RECIVED
|
#define PROGRESS_TIME_RECIVED PROGRESS_DISTANCE_RECIVED
|
||||||
|
#define PROGRESS_ICONS_RECIVED PROGRESS_DISTANCE_RECIVED
|
||||||
#define PROGRESS_STEP_RECIVED 95
|
#define PROGRESS_STEP_RECIVED 95
|
||||||
#define PROGRESS_SUCCESS_RECIVED 100
|
#define PROGRESS_SUCCESS_RECIVED 100
|
||||||
|
|
||||||
@@ -17,6 +18,7 @@ struct RouteData {
|
|||||||
// Data fields
|
// Data fields
|
||||||
int distance;
|
int distance;
|
||||||
int time;
|
int time;
|
||||||
|
char icons[MAX_STEP_COUNT + 1];
|
||||||
char steps[MAX_STEP_COUNT][MAX_STEP_CHARS];
|
char steps[MAX_STEP_COUNT][MAX_STEP_CHARS];
|
||||||
int count;
|
int count;
|
||||||
};
|
};
|
||||||
@@ -28,6 +30,15 @@ static int window_height;
|
|||||||
static MenuLayer *directions_list;
|
static MenuLayer *directions_list;
|
||||||
static GColor selected_type_color;
|
static GColor selected_type_color;
|
||||||
|
|
||||||
|
// Step icons
|
||||||
|
static GBitmap *icon_step_type;
|
||||||
|
static GBitmap *icon_step_forward;
|
||||||
|
static GBitmap *icon_step_right;
|
||||||
|
static GBitmap *icon_step_left;
|
||||||
|
static GBitmap *icon_step_uright;
|
||||||
|
static GBitmap *icon_step_uleft;
|
||||||
|
static GBitmap *icon_step_attr;
|
||||||
|
|
||||||
// Dictation input
|
// Dictation input
|
||||||
static DictationSession *dictation_session;
|
static DictationSession *dictation_session;
|
||||||
static char *address;
|
static char *address;
|
||||||
@@ -58,15 +69,44 @@ static int16_t get_cell_height_callback(struct MenuLayer *menu_layer, MenuIndex
|
|||||||
|
|
||||||
// Draw menu cell callback
|
// Draw menu cell callback
|
||||||
static void draw_row_callback(GContext *ctx, const Layer *cell_layer, MenuIndex *cell_index, void *context) {
|
static void draw_row_callback(GContext *ctx, const Layer *cell_layer, MenuIndex *cell_index, void *context) {
|
||||||
// Determine what row to draw TODO: implement nicer UI
|
// Local vars
|
||||||
|
int data_index = cell_index->row - 1;
|
||||||
|
GBitmap *icon;
|
||||||
|
// Determine what row to draw
|
||||||
switch (cell_index->row) {
|
switch (cell_index->row) {
|
||||||
// Summary
|
// Summary
|
||||||
case 0:
|
case 0:
|
||||||
directions_draw_summary(ctx, layer_get_bounds(cell_layer), selected_type_color, route_data->distance, route_data->time);
|
directions_draw_summary(ctx, layer_get_bounds(cell_layer), selected_type_color, route_data->distance, route_data->time, address);
|
||||||
break;
|
break;
|
||||||
// Step description
|
// Step description
|
||||||
default:
|
default:
|
||||||
directions_draw_step(ctx, layer_get_bounds(cell_layer), selected_type_color, route_data->steps[cell_index->row - 1], cell_index->row - 1, (int16_t)route_data->count);
|
// Select the correct icon
|
||||||
|
switch (route_data->icons[data_index]) {
|
||||||
|
case 'a':
|
||||||
|
icon = icon_step_type;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
icon = icon_step_forward;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
icon = icon_step_right;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
icon = icon_step_left;
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
icon = icon_step_uright;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
icon = icon_step_uleft;
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
icon = icon_step_attr;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
icon = icon_step_type;
|
||||||
|
}
|
||||||
|
directions_draw_step(ctx, layer_get_bounds(cell_layer), selected_type_color, route_data->steps[data_index], icon, data_index, (int16_t)route_data->count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,6 +184,16 @@ static void app_message_inbox_recived_callback(DictionaryIterator *iter, void *c
|
|||||||
route_data->time = (int)message->value->int32;
|
route_data->time = (int)message->value->int32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test if the recived message is fof key INSTRUCTION_ICONS
|
||||||
|
message = dict_find(iter, MESSAGE_KEY_INSTRUCTION_ICONS);
|
||||||
|
if (message) {
|
||||||
|
// Set the progress
|
||||||
|
progress_layer_set_progress(progress_layer, PROGRESS_ICONS_RECIVED, true);
|
||||||
|
// Copy the icon string
|
||||||
|
strcpy(route_data->icons, message->value->cstring);
|
||||||
|
route_data->icons[MAX_STEP_COUNT] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
// Test if the recived message is for key INSTRUCTIONS
|
// Test if the recived message is for key INSTRUCTIONS
|
||||||
for (int i = 0; i < MAX_STEP_COUNT; i++) {
|
for (int i = 0; i < MAX_STEP_COUNT; i++) {
|
||||||
message = dict_find(iter, MESSAGE_KEY_INSTRUCTIONS + i);
|
message = dict_find(iter, MESSAGE_KEY_INSTRUCTIONS + i);
|
||||||
@@ -212,6 +262,11 @@ static void app_message_start() {
|
|||||||
route_data->distance = 0;
|
route_data->distance = 0;
|
||||||
route_data->time = 0;
|
route_data->time = 0;
|
||||||
route_data->count = 0;
|
route_data->count = 0;
|
||||||
|
// Initialise the icons string (has the length of MAX_STEP_COUNT + 1 for correct null termination)
|
||||||
|
for (int i = 0; i < MAX_STEP_COUNT; i ++) {
|
||||||
|
route_data->icons[i] = 'a';
|
||||||
|
}
|
||||||
|
route_data->icons[MAX_STEP_COUNT] = '\0';
|
||||||
// Register all callbacks
|
// Register all callbacks
|
||||||
app_message_register_inbox_received(app_message_inbox_recived_callback);
|
app_message_register_inbox_received(app_message_inbox_recived_callback);
|
||||||
app_message_register_inbox_dropped(app_message_inbox_dropped_callback);
|
app_message_register_inbox_dropped(app_message_inbox_dropped_callback);
|
||||||
@@ -274,6 +329,15 @@ static void window_unload() {
|
|||||||
// Destroy the window
|
// Destroy the window
|
||||||
window_destroy(window);
|
window_destroy(window);
|
||||||
window = NULL;
|
window = NULL;
|
||||||
|
|
||||||
|
// Destroy the step icons
|
||||||
|
gbitmap_destroy(icon_step_type);
|
||||||
|
gbitmap_destroy(icon_step_forward);
|
||||||
|
gbitmap_destroy(icon_step_right);
|
||||||
|
gbitmap_destroy(icon_step_left);
|
||||||
|
gbitmap_destroy(icon_step_uright);
|
||||||
|
gbitmap_destroy(icon_step_uleft);
|
||||||
|
gbitmap_destroy(icon_step_attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void window_disappear() {
|
static void window_disappear() {
|
||||||
@@ -328,6 +392,35 @@ static void window_load() {
|
|||||||
|
|
||||||
// Create the progress layer
|
// Create the progress layer
|
||||||
progress_layer = progress_layer_create(bounds);
|
progress_layer = progress_layer_create(bounds);
|
||||||
|
|
||||||
|
// Create the step icon resources
|
||||||
|
switch (selected_type_enum) {
|
||||||
|
case 0:
|
||||||
|
// Car icon
|
||||||
|
icon_step_type = gbitmap_create_with_resource(RESOURCE_ID_ICON_CAR_BLACK);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
// Bike icon
|
||||||
|
icon_step_type = gbitmap_create_with_resource(RESOURCE_ID_ICON_BIKE_BLACK);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
// Train icon
|
||||||
|
icon_step_type = gbitmap_create_with_resource(RESOURCE_ID_ICON_TRAIN_BLACK);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
// Walk icon
|
||||||
|
icon_step_type = gbitmap_create_with_resource(RESOURCE_ID_ICON_WALK_BLACK);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Forward icon
|
||||||
|
icon_step_type = gbitmap_create_with_resource(RESOURCE_ID_ICON_STEP_FORWARD);
|
||||||
|
}
|
||||||
|
icon_step_forward = gbitmap_create_with_resource(RESOURCE_ID_ICON_STEP_FORWARD);
|
||||||
|
icon_step_right = gbitmap_create_with_resource(RESOURCE_ID_ICON_STEP_RIGHT);
|
||||||
|
icon_step_left = gbitmap_create_with_resource(RESOURCE_ID_ICON_STEP_LEFT);
|
||||||
|
icon_step_uright = gbitmap_create_with_resource(RESOURCE_ID_ICON_STEP_URIGHT);
|
||||||
|
icon_step_uleft = gbitmap_create_with_resource(RESOURCE_ID_ICON_STEP_ULEFT);
|
||||||
|
icon_step_attr = gbitmap_create_with_resource(RESOURCE_ID_ICON_STEP_ATTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push the window to the window stack
|
// Push the window to the window stack
|
||||||
|
|||||||
+19
-11
@@ -4,8 +4,9 @@
|
|||||||
* About the send messages
|
* About the send messages
|
||||||
* –––
|
* –––
|
||||||
* (1) Overview data is send (distance, time needed)
|
* (1) Overview data is send (distance, time needed)
|
||||||
* (2) Step data array is send (each step string, max 20 entrys) -> THE LAST SEND INDEX IS THE LENGTH!
|
* (2) Step icon data is send as a 20 char string (each char encodes one icon!)
|
||||||
* (3) Success value is send (terminates the transmittion; it's true/false
|
* (3) Step data array is send (each step string, max 20 entrys) -> THE LAST SEND INDEX IS THE LENGTH!
|
||||||
|
* (4) Success value is send (terminates the transmittion; it's true/false
|
||||||
* value determines whether the transmition was successfull or not (E.g.
|
* value determines whether the transmition was successfull or not (E.g.
|
||||||
* if false is send as the success first, no route was found)
|
* if false is send as the success first, no route was found)
|
||||||
*
|
*
|
||||||
@@ -21,12 +22,17 @@
|
|||||||
* The first character is always the type selected, the rest
|
* The first character is always the type selected, the rest
|
||||||
* is the written address.
|
* is the written address.
|
||||||
* {selected_type} vals: 0 = Car; 1 = Bike; 2 = Train; 3 = Walk;
|
* {selected_type} vals: 0 = Car; 1 = Bike; 2 = Train; 3 = Walk;
|
||||||
|
*
|
||||||
|
* About the step icon data string
|
||||||
|
* –––
|
||||||
|
* Chars map to the following icons: type: 'a', forward: 'b', right: 'c', left: 'd', uRight: 'e', uLeft: 'f', attr: 'g'
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// Data keys
|
// Data keys
|
||||||
var keys = require('message_keys');
|
var keys = require('message_keys');
|
||||||
var maxStepCount = 20;
|
var maxStepCount = 20;
|
||||||
|
var maxStepStringLength = 128;
|
||||||
var currentMessageNumber = 0;
|
var currentMessageNumber = 0;
|
||||||
var messagePadding = 10;
|
var messagePadding = 10;
|
||||||
|
|
||||||
@@ -55,16 +61,13 @@ function sendStepItem(stepList, index, messageNumber) {
|
|||||||
// Build message
|
// Build message
|
||||||
var key = keys.INSTRUCTIONS + index;
|
var key = keys.INSTRUCTIONS + index;
|
||||||
var dict = {};
|
var dict = {};
|
||||||
dict[key] = stepList[index];
|
dict[key] = stepList[index].substr(0, maxStepStringLength);
|
||||||
|
|
||||||
// Send message to pebble
|
// Send message to pebble
|
||||||
Pebble.sendAppMessage(dict, function() {
|
Pebble.sendAppMessage(dict, function() {
|
||||||
// Success, send next item
|
// Success, send next item
|
||||||
index ++;
|
index ++;
|
||||||
if (maxStepCount > stepList.length) {
|
if (index < stepList.length && index < maxStepCount) {
|
||||||
// Too many steps error
|
|
||||||
sendSuccess(2, messageNumber);
|
|
||||||
} else if (index < stepList.length && index < maxStepCount) {
|
|
||||||
// Recursive callbacks, hell yeah!
|
// Recursive callbacks, hell yeah!
|
||||||
sendStepItem(stepList, index, messageNumber);
|
sendStepItem(stepList, index, messageNumber);
|
||||||
} else {
|
} else {
|
||||||
@@ -77,15 +80,17 @@ function sendStepItem(stepList, index, messageNumber) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendRoute(success, distance, time, stepList, stepIconList, messageNumber) {
|
function sendRoute(success, distance, time, stepList, stepIconsString, messageNumber) {
|
||||||
// Send message to pebble if a route was found
|
// Send message to pebble if a route was found
|
||||||
if (success) {
|
if (success && maxStepCount >= stepList.length) {
|
||||||
// Build message
|
// Build message
|
||||||
var keyDistance = keys.DISTANCE;
|
var keyDistance = keys.DISTANCE;
|
||||||
var keyTime = keys.TIME;
|
var keyTime = keys.TIME;
|
||||||
|
var keyIcons = keys.INSTRUCTION_ICONS;
|
||||||
var dict = {};
|
var dict = {};
|
||||||
dict[keyDistance] = +distance;
|
dict[keyDistance] = +distance;
|
||||||
dict[keyTime] = +time;
|
dict[keyTime] = +time;
|
||||||
|
dict[keyIcons] = ''.concat(stepIconsString);
|
||||||
|
|
||||||
// Transmit
|
// Transmit
|
||||||
Pebble.sendAppMessage(dict, function() {
|
Pebble.sendAppMessage(dict, function() {
|
||||||
@@ -95,6 +100,9 @@ function sendRoute(success, distance, time, stepList, stepIconList, messageNumbe
|
|||||||
// Error
|
// Error
|
||||||
console.log('Transmission failed at [OVERVIEW]');
|
console.log('Transmission failed at [OVERVIEW]');
|
||||||
});
|
});
|
||||||
|
} else if (maxStepCount < stepList.length) {
|
||||||
|
// Too many steps error
|
||||||
|
sendSuccess(2, messageNumber);
|
||||||
} else {
|
} else {
|
||||||
// Send error message (route not found)
|
// Send error message (route not found)
|
||||||
sendSuccess(1, messageNumber);
|
sendSuccess(1, messageNumber);
|
||||||
@@ -106,9 +114,9 @@ function fetchAndSendRoute(routeType, searchText, messageNumber) {
|
|||||||
// Log the recived data
|
// Log the recived data
|
||||||
console.log('Route type:', routeType);
|
console.log('Route type:', routeType);
|
||||||
console.log('Search text:', searchText);
|
console.log('Search text:', searchText);
|
||||||
// Load a route from here api. Data format: { distance, time, stepList[string], stepIconList[int] }
|
// Load a route from here api. Data format: { distance, time, stepList[string], stepIconsString }
|
||||||
locationService.createRoute(routeType, searchText, function(success, data) {
|
locationService.createRoute(routeType, searchText, function(success, data) {
|
||||||
sendRoute(success, data.distance, data.time, data.stepList, data.stepIconList, messageNumber);
|
sendRoute(success, data.distance, data.time, data.stepList, data.stepIconsString, messageNumber);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-9
@@ -82,7 +82,15 @@ function loadRouteData(routeType, fromLat, fromLon, toLat, toLon, callback) {
|
|||||||
// Transport modes, mapped to pebble ids
|
// Transport modes, mapped to pebble ids
|
||||||
var modes = ['car', 'bicycle', 'publicTransport', 'pedestrian'];
|
var modes = ['car', 'bicycle', 'publicTransport', 'pedestrian'];
|
||||||
// Pebble direction icons, mapped to pebble ids (type = show nav type icon, attr = show attribution icon)
|
// Pebble direction icons, mapped to pebble ids (type = show nav type icon, attr = show attribution icon)
|
||||||
var icons = ['type', 'forward', 'right', 'left', 'uRight', 'uLeft', 'attr'];
|
var icons = {
|
||||||
|
type: 'a',
|
||||||
|
forward: 'b',
|
||||||
|
right: 'c',
|
||||||
|
left: 'd',
|
||||||
|
uRight: 'e',
|
||||||
|
uLeft: 'f',
|
||||||
|
attr: 'g',
|
||||||
|
};
|
||||||
// Maps the direction retrived from here api to icon name
|
// Maps the direction retrived from here api to icon name
|
||||||
var directionMap = {
|
var directionMap = {
|
||||||
forward: 'forward',
|
forward: 'forward',
|
||||||
@@ -107,14 +115,14 @@ function loadRouteData(routeType, fromLat, fromLon, toLat, toLon, callback) {
|
|||||||
if (success) {
|
if (success) {
|
||||||
// Success (will fail if expected fields are not available in response)
|
// Success (will fail if expected fields are not available in response)
|
||||||
try {
|
try {
|
||||||
// Our route data will go here. Format: { distance, time, stepList[string], stepIconList[int] }
|
// Our route data will go here. Format: { distance, time, stepList[string], stepIconsString[int] }
|
||||||
var routeData = {};
|
var routeData = {};
|
||||||
// Get the summary
|
// Get the summary
|
||||||
routeData.distance = res.response.route[0].summary.distance; /* in meters */
|
routeData.distance = res.response.route[0].summary.distance; /* in meters */
|
||||||
routeData.time = Math.ceil(res.response.route[0].summary.travelTime / 60); /* in minutes */
|
routeData.time = Math.ceil(res.response.route[0].summary.travelTime / 60); /* in minutes */
|
||||||
// Get the steps
|
// Get the steps
|
||||||
routeData.stepList = [];
|
routeData.stepList = [];
|
||||||
routeData.stepIconList = [];
|
routeData.stepIconsString = '';
|
||||||
res.response.route[0].leg[0].maneuver.forEach(function(step, index) {
|
res.response.route[0].leg[0].maneuver.forEach(function(step, index) {
|
||||||
// Add the text
|
// Add the text
|
||||||
routeData.stepList[index] = step.instruction;
|
routeData.stepList[index] = step.instruction;
|
||||||
@@ -122,21 +130,21 @@ function loadRouteData(routeType, fromLat, fromLon, toLat, toLon, callback) {
|
|||||||
if (step.hasOwnProperty('direction')) {
|
if (step.hasOwnProperty('direction')) {
|
||||||
// Display the specified icon
|
// Display the specified icon
|
||||||
if (directionMap.hasOwnProperty(step.direction)) {
|
if (directionMap.hasOwnProperty(step.direction)) {
|
||||||
routeData.stepIconList[index] = icons.indexOf(directionMap[step.direction]);
|
routeData.stepIconsString = routeData.stepIconsString.concat(icons[directionMap[step.direction]]);
|
||||||
} else {
|
} else {
|
||||||
// Display the travel type icon
|
// Display the travel type icon
|
||||||
routeData.stepIconList[index] = icons.indexOf('type');
|
routeData.stepIconsString = routeData.stepIconsString.concat(icons['type']);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Display the travel type icon
|
// Display the travel type icon
|
||||||
routeData.stepIconList[index] = icons.indexOf('type');
|
routeData.stepIconsString = routeData.stepIconsString.concat(icons['type']);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Test for attribution
|
// Test for attribution
|
||||||
if (res.response.hasOwnProperty('sourceAttribution')) {
|
if (res.response.hasOwnProperty('sourceAttribution')) {
|
||||||
// Add attribution text as last list entry, removing all html markup from it
|
// Add attribution text as last list entry, removing all html markup from it
|
||||||
routeData.stepList.push(res.response.sourceAttribution.attribution.replace(/<.+?>/g, ''));
|
routeData.stepList.push(res.response.sourceAttribution.attribution.replace(/<.+?>/g, ''));
|
||||||
routeData.stepIconList.push(icons.indexOf('attr'));
|
routeData.stepIconsString = routeData.stepIconsString.concat(icons['attr']);
|
||||||
}
|
}
|
||||||
// We are done
|
// We are done
|
||||||
callback(true, routeData);
|
callback(true, routeData);
|
||||||
@@ -147,7 +155,7 @@ function loadRouteData(routeType, fromLat, fromLon, toLat, toLon, callback) {
|
|||||||
// Error
|
// Error
|
||||||
routeErrorCallback(callback);
|
routeErrorCallback(callback);
|
||||||
}
|
}
|
||||||
}, true);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Performs all the steps neccessary to return a complete route (the callback takes: success / route data)
|
// Performs all the steps neccessary to return a complete route (the callback takes: success / route data)
|
||||||
@@ -173,7 +181,7 @@ function createRoute(routeType, searchText, callback) {
|
|||||||
}
|
}
|
||||||
// Helper function to define createRoute error callback all in one place
|
// Helper function to define createRoute error callback all in one place
|
||||||
function routeErrorCallback(callback) {
|
function routeErrorCallback(callback) {
|
||||||
callback(false, { distance: 0, time: 0, stepList: [], stepIconList: [] });
|
callback(false, { distance: 0, time: 0, stepList: [], stepIconsString: '' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user