Fetch list from phone

master
Alinson S. Xavier 9 years ago
parent e60aa7efdf
commit cfe014402c

@ -9,6 +9,7 @@ INCLUDE_DIRECTORIES("build/${PEBBLE_FLAVOUR}/src")
INCLUDE_DIRECTORIES("build/include") INCLUDE_DIRECTORIES("build/include")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
add_definitions(-DCLION)
set(SOURCE_FILES set(SOURCE_FILES
src/main.c src/main.c

@ -38,6 +38,9 @@ static void on_update(struct Layer *layer, GContext *context)
}; };
graphics_context_set_fill_color(context, border->color); graphics_context_set_fill_color(context, border->color);
graphics_fill_rect(context, rect, 0, GCornerNone); graphics_fill_rect(context, rect, 0, GCornerNone);
graphics_context_set_fill_color(context, GColorBlack);
graphics_fill_circle(context, GPoint(7, 10), 2);
} }
static struct Layer* create_raw_layer(struct BorderLayer *border, static struct Layer* create_raw_layer(struct BorderLayer *border,

@ -19,13 +19,26 @@
#include <pebble.h> #include <pebble.h>
#include "screens/list/list_window.h" #include "screens/list/list_window.h"
#include "network.h"
#include "util.h"
int main(void) int main(void)
{ {
struct ListWindow *window = LIST_WINDOW_create(); int rval = 0;
struct ListWindow *window = 0;
rval = NETWORK_register();
abort_if(rval, "NETWORK_register failed");
window = LIST_WINDOW_create();
abort_if(!window, "LIST_WINDOW_create failed");
window_stack_push(window->raw_window, true); window_stack_push(window->raw_window, true);
app_event_loop(); app_event_loop();
CLEANUP:
LIST_WINDOW_destroy(window); LIST_WINDOW_destroy(window);
NETWORK_cleanup();
return rval;
} }

@ -22,17 +22,38 @@
#include "util.h" #include "util.h"
#define MAX_HABIT_COUNT 50 #define MAX_HABIT_COUNT 50
static int HABIT_COUNT;
static int HABIT_CURRENT;
// LIST WINDOW struct NetworkState
//------------------------------------------------------------------------------ {
int habit_count;
int habit_current;
static int request_next_habit() struct NetworkCallbacks *callbacks;
};
static int process_ok(struct NetworkState *state)
{ {
int rval = 0; int rval = 0;
abort_if(!state, "state is null");
struct NetworkCallbacks *callbacks = state->callbacks;
abort_if(!callbacks, "callbacks is null");
if(HABIT_CURRENT >= HABIT_COUNT) if(!callbacks->on_ok) goto CLEANUP;
rval = callbacks->on_ok(callbacks->on_ok_context);
abort_if(rval, "state->on_ok failed");
CLEANUP:
return rval;
}
static int request_next_habit(struct NetworkState *state)
{
int rval = 0;
abort_if(!state, "state is null");
if(state->habit_current >= state->habit_count)
goto CLEANUP; goto CLEANUP;
DictionaryIterator *dict; DictionaryIterator *dict;
@ -42,71 +63,78 @@ static int request_next_habit()
rval = dict_write_cstring(dict, 0, "FETCH"); rval = dict_write_cstring(dict, 0, "FETCH");
abort_if(rval, "dict_write_cstring failed"); abort_if(rval, "dict_write_cstring failed");
rval = dict_write_int32(dict, 1, HABIT_CURRENT); rval = dict_write_int32(dict, 1, state->habit_current);
abort_if(rval, "dict_write_cstring failed"); abort_if(rval, "dict_write_cstring failed");
rval = app_message_outbox_send(); rval = app_message_outbox_send();
abort_if(rval, "app_message_outbox_send failed"); abort_if(rval, "app_message_outbox_send failed");
HABIT_CURRENT++; state->habit_current++;
CLEANUP: CLEANUP:
return rval; return rval;
} }
static int process_count(DictionaryIterator *iter) static int process_count(DictionaryIterator *iter, struct NetworkState *state)
{ {
int rval = 0; int rval = 0;
abort_if(!state, "state is null");
struct NetworkCallbacks *callbacks = state->callbacks;
Tuple *tuple = dict_find(iter, 1); Tuple *tuple = dict_find(iter, 1);
abort_if(!tuple, "tuple is null"); abort_if(!tuple, "tuple is null");
int count = tuple->value->int32; int count = tuple->value->int32;
// rval = LIST_WINDOW_allocate(count); if(callbacks->on_count)
// abort_if(rval, "LIST_WINDOW_allocate failed"); {
rval = callbacks->on_count(count, callbacks->on_count_context);
abort_if(rval, "state->on_count failed");
}
if(count > MAX_HABIT_COUNT) count = MAX_HABIT_COUNT; if(count > MAX_HABIT_COUNT) count = MAX_HABIT_COUNT;
HABIT_COUNT = count; state->habit_count = count;
HABIT_CURRENT = 0; state->habit_current = 0;
rval = request_next_habit(); rval = request_next_habit(state);
abort_if(rval, "request_next_habit failed"); abort_if(rval, "request_next_habit failed");
CLEANUP: CLEANUP:
return rval; return rval;
} }
static int process_habit(DictionaryIterator *iter) static int process_habit(DictionaryIterator *iter, struct NetworkState *state)
{ {
int rval = 0; int rval = 0;
struct NetworkCallbacks *callbacks = state->callbacks;
// // id Tuple *tuple = dict_find(iter, 1);
// Tuple *tuple = dict_find(iter, 1); abort_if(!tuple, "tuple is null");
// abort_if(!tuple, "tuple is null"); int id = tuple->value->int32;
// int id = tuple->value->int32;
// tuple = dict_find(iter, 2);
// // name abort_if(!tuple, "tuple is null");
// tuple = dict_find(iter, 2); char *name = tuple->value->cstring;
// abort_if(!tuple, "tuple is null");
// char *name = tuple->value->cstring; tuple = dict_find(iter, 3);
// abort_if(!tuple, "tuple is null");
// // checkmark value int checkmark = tuple->value->int32;
// tuple = dict_find(iter, 3);
// abort_if(!tuple, "tuple is null"); if(callbacks->on_habit)
// int checkmark = tuple->value->int32; {
void *ctx = callbacks->on_habit_context;
// rval = LIST_WINDOW_add_habit(id, name, checkmark); rval = callbacks->on_habit(id, name, checkmark, ctx);
// abort_if(rval, "LIST_WINDOW_add_habit failed"); abort_if(rval, "state->on_habit failed");
rval = request_next_habit(); rval = request_next_habit(state);
abort_if(rval, "request_next_habit failed"); abort_if(rval, "request_next_habit failed");
}
CLEANUP: CLEANUP:
return rval; return rval;
} }
int NETWORK_request_list() int NETWORK_request_toggle(int id)
{ {
int rval = 0; int rval = 0;
@ -114,17 +142,22 @@ int NETWORK_request_list()
rval = app_message_outbox_begin(&dict); rval = app_message_outbox_begin(&dict);
abort_if(rval, "app_message_outbox_begin failed"); abort_if(rval, "app_message_outbox_begin failed");
rval = dict_write_cstring(dict, 0, "COUNT"); rval = dict_write_cstring(dict, 0, "TOGGLE");
abort_if(rval, "dict_write_cstring failed");
rval = dict_write_int32(dict, 1, id);
abort_if(rval, "dict_write_cstring failed"); abort_if(rval, "dict_write_cstring failed");
rval = app_message_outbox_send(); rval = app_message_outbox_send();
abort_if(rval, "app_message_outbox_send failed"); abort_if(rval, "app_message_outbox_send failed");
log_debug("--> %s", "COUNT");
CLEANUP: CLEANUP:
return rval; return rval;
} }
int NETWORK_request_toggle(int id) int NETWORK_request_list()
{ {
int rval = 0; int rval = 0;
@ -132,53 +165,88 @@ int NETWORK_request_toggle(int id)
rval = app_message_outbox_begin(&dict); rval = app_message_outbox_begin(&dict);
abort_if(rval, "app_message_outbox_begin failed"); abort_if(rval, "app_message_outbox_begin failed");
rval = dict_write_cstring(dict, 0, "TOGGLE"); rval = dict_write_cstring(dict, 0, "COUNT");
abort_if(rval, "dict_write_cstring failed");
rval = dict_write_int32(dict, 1, id);
abort_if(rval, "dict_write_cstring failed"); abort_if(rval, "dict_write_cstring failed");
rval = app_message_outbox_send(); rval = app_message_outbox_send();
abort_if(rval, "app_message_outbox_send failed"); abort_if(rval, "app_message_outbox_send failed");
CLEANUP: log_debug("--> %s", "COUNT");
CLEANUP:
return rval; return rval;
} }
//------------------------------------------------------------------------------
static void NETWORK_on_received(DictionaryIterator *iter, void *context) static void NETWORK_on_received(DictionaryIterator *iter, void *context)
{ {
int rval = 0; int rval = 0;
struct NetworkState *state = context;
abort_if(!state, "state is null");
Tuple *tuple = dict_find(iter, 0); Tuple *tuple = dict_find(iter, 0);
abort_if(!tuple, "tuple is null"); abort_if(!tuple, "tuple is null");
char *action = tuple->value->cstring; char *action = tuple->value->cstring;
log_debug("<-- %s", action);
if(strcmp(action, "COUNT") == 0) if(strcmp(action, "COUNT") == 0)
{ {
rval = process_count(iter); rval = process_count(iter, state);
abort_if(rval, "process_count failed"); abort_if(rval, "process_count failed");
} }
else if(strcmp(action, "HABIT") == 0) else if(strcmp(action, "HABIT") == 0)
{ {
rval = process_habit(iter); rval = process_habit(iter, state);
abort_if(rval, "process_habit failed"); abort_if(rval, "process_habit failed");
} }
else if(strcmp(action, "OK") == 0) else if(strcmp(action, "OK") == 0)
{ {
rval = NETWORK_request_list(); rval = process_ok(state);
abort_if(rval, "NETWORK_request_list failed"); abort_if(rval, "process_ok failed");
} }
CLEANUP: CLEANUP:
return; return;
} }
struct NetworkCallbacks * NETWORK_get_callbacks()
{
struct NetworkState *state = app_message_get_context();
return state->callbacks;
}
int NETWORK_register() int NETWORK_register()
{ {
int rval = 0;
struct NetworkState *state = 0;
state = (struct NetworkState*) malloc(sizeof(struct NetworkState));
abort_if(!state, "could not allocate state");
struct NetworkCallbacks *callbacks = 0;
callbacks = (struct NetworkCallbacks*) malloc(sizeof(struct NetworkCallbacks));
abort_if(!callbacks, "could not allocate callbacks");
state->callbacks = callbacks;
callbacks->on_ok = 0;
callbacks->on_habit = 0;
callbacks->on_count = 0;
callbacks->on_ok_context = 0;
callbacks->on_habit_context = 0;
callbacks->on_count_context = 0;
app_message_register_inbox_received(NETWORK_on_received); app_message_register_inbox_received(NETWORK_on_received);
app_message_open(1024, 1024); app_message_open(1024, 1024);
return 0; app_message_set_context(state);
CLEANUP:
return rval;
}
void NETWORK_cleanup()
{
struct NetworkState *state = app_message_get_context();
free(state->callbacks);
free(state);
app_message_deregister_callbacks();
} }

@ -19,8 +19,30 @@
#pragma once #pragma once
int NETWORK_register(); struct NetworkCallbacks
{
void *on_count_context;
void *on_habit_context;
void *on_ok_context;
int (*on_count)(int count, void *callback_context);
int (*on_habit)(int id,
char *name,
int checkmark,
void *callback_context);
int (*on_ok)(void *callback_context);
};
int NETWORK_request_list(); int NETWORK_request_list();
int NETWORK_request_toggle(int id); int NETWORK_request_toggle(int id);
struct NetworkCallbacks* NETWORK_get_callbacks();
int NETWORK_register();
void NETWORK_cleanup();

@ -22,10 +22,13 @@
#include "style.h" #include "style.h"
const char *ACTIONS[] = { const char *ACTIONS[] = {
" Check", " Check",
" View stats" " More Info"
}; };
// MENU LAYER CALLBACKS
// -----------------------------------------------------------------------------
// callback: MenuLayerSelectCallback // callback: MenuLayerSelectCallback
static void on_click(struct MenuLayer *menu_layer, static void on_click(struct MenuLayer *menu_layer,
MenuIndex *cell_index, MenuIndex *cell_index,
@ -62,6 +65,8 @@ static int16_t on_get_cell_height(struct MenuLayer *menu_layer,
return CELL_HEIGHT; return CELL_HEIGHT;
} }
// -----------------------------------------------------------------------------
static void set_menu_layer_callbacks(struct ActionMenuLayer *action_menu, static void set_menu_layer_callbacks(struct ActionMenuLayer *action_menu,
struct MenuLayer *menu) struct MenuLayer *menu)
{ {

@ -21,13 +21,12 @@
struct ActionMenuLayerCallbacks struct ActionMenuLayerCallbacks
{ {
void (*on_select)(void *callback_context); int (*on_select)(void *callback_context);
}; };
struct ActionMenuLayer struct ActionMenuLayer
{ {
struct MenuLayer *menu_layer; struct MenuLayer *menu_layer;
void *callback_context; void *callback_context;
struct ActionMenuLayerCallbacks callbacks; struct ActionMenuLayerCallbacks callbacks;
}; };

@ -24,18 +24,47 @@
#include "action_menu_layer.h" #include "action_menu_layer.h"
#include "style.h" #include "style.h"
#include "../animation/animation_window.h" #include "../animation/animation_window.h"
#include "../../network.h"
static void on_select(void *callback_context) #ifdef CLION
#include <resource_ids.auto.h>
#endif
// NETWORK CALLBACKS
// -----------------------------------------------------------------------------
static int on_ok(void *callback_context)
{ {
struct AnimationWindow *window = ANIMATION_WINDOW_create(
RESOURCE_ID_CONFIRM_SEQUENCE);
window_stack_push(window->raw_window, true);
return 0;
}
// ACTION MENU LAYER CALLBACKS
// -----------------------------------------------------------------------------
static int on_select(void *callback_context)
{
int rval = 0;
struct ActionWindow *window = callback_context; struct ActionWindow *window = callback_context;
ANIMATION_WINDOW_destroy(window->animation_window); rval = NETWORK_request_toggle(window->habit_id);
window->animation_window = ANIMATION_WINDOW_create( abort_if(rval, "NETWORK_request_toggle failed");
RESOURCE_ID_CONFIRM_SEQUENCE);
struct NetworkCallbacks *net_callbacks = NETWORK_get_callbacks();
abort_if(!net_callbacks, "NETWORK_get_callbacks failed");
net_callbacks->on_ok = on_ok;
window_stack_push(window->animation_window->raw_window, true); CLEANUP:
return rval;
} }
// -----------------------------------------------------------------------------
static int add_menu_layer(struct ActionWindow *window, static int add_menu_layer(struct ActionWindow *window,
struct Layer *root_layer, struct Layer *root_layer,
struct GRect bounds) struct GRect bounds)
@ -109,13 +138,15 @@ static void set_raw_window_handlers(Window *raw_window)
window_set_window_handlers(raw_window, handlers); window_set_window_handlers(raw_window, handlers);
} }
struct ActionWindow *ACTION_WINDOW_create() struct ActionWindow *ACTION_WINDOW_create(int habit_id)
{ {
struct ActionWindow *window = 0; struct ActionWindow *window = 0;
window = (struct ActionWindow*) malloc(sizeof(struct ActionWindow)); window = (struct ActionWindow*) malloc(sizeof(struct ActionWindow));
if(!window) return NULL; if(!window) return NULL;
window->habit_id = habit_id;
Window *raw_window = window_create(); Window *raw_window = window_create();
if(!raw_window) return NULL; if(!raw_window) return NULL;

@ -21,6 +21,8 @@
struct ActionWindow struct ActionWindow
{ {
int habit_id;
struct Window *raw_window; struct Window *raw_window;
struct ActionMenuLayer *menu_layer; struct ActionMenuLayer *menu_layer;
@ -30,6 +32,6 @@ struct ActionWindow
struct AnimationWindow *animation_window; struct AnimationWindow *animation_window;
}; };
struct ActionWindow* ACTION_WINDOW_create(); struct ActionWindow* ACTION_WINDOW_create(int habit_id);
void ACTION_WINDOW_destroy(struct ActionWindow *window); void ACTION_WINDOW_destroy(struct ActionWindow *window);

@ -31,6 +31,6 @@
#define BORDER_COLOR GColorFolly #define BORDER_COLOR GColorFolly
#define BORDER_WIDTH 6 #define BORDER_WIDTH 14
#define CELL_HEIGHT 36 #define CELL_HEIGHT 36

@ -23,22 +23,31 @@
#define MAX_NAME_LENGTH 20 #define MAX_NAME_LENGTH 20
static int free_habits(struct ListLayer *layer) int LIST_LAYER_clear(struct ListLayer *layer)
{ {
int rval = 0;
abort_if(!layer, "layer is null");
for(int i = 0; i < layer->habit_count; i++) free(layer->habit_names[i]); for(int i = 0; i < layer->habit_count; i++) free(layer->habit_names[i]);
free(layer->habit_names); free(layer->habit_names);
free(layer->habit_checkmarks); free(layer->habit_checkmarks);
free(layer->habit_ids); free(layer->habit_ids);
layer->habit_names = 0;
layer->habit_checkmarks = 0;
layer->habit_ids = 0;
layer->habit_count = 0; layer->habit_count = 0;
return 0; CLEANUP:
return rval;
} }
int LIST_LAYER_allocate(struct ListLayer *layer, int count) int LIST_LAYER_allocate(struct ListLayer *layer, int count)
{ {
int rval = 0; int rval = 0;
free_habits(layer); rval = LIST_LAYER_clear(layer);
abort_if(rval, "LIST_LAYER_clear failed");
layer->habit_names = (char **) malloc(count * sizeof(char *)); layer->habit_names = (char **) malloc(count * sizeof(char *));
abort_if(!layer->habit_names, "could not allocate habit_names"); abort_if(!layer->habit_names, "could not allocate habit_names");
@ -64,8 +73,14 @@ int LIST_LAYER_add_habit(struct ListLayer *layer,
char *new_name, char *new_name,
int new_checkmark) int new_checkmark)
{ {
uint16_t count = layer->habit_count; int rval = 0;
abort_if(!layer, "layer is null");
abort_if(!layer->habit_ids, "layer->habit_ids is null");
abort_if(!layer->habit_names, "layer->habits_names is null");
abort_if(!layer->habit_checkmarks, "layer->habit_checkmarks is null");
uint16_t count = layer->habit_count;
char *name = layer->habit_names[count]; char *name = layer->habit_names[count];
strncpy(name, new_name, MAX_NAME_LENGTH); strncpy(name, new_name, MAX_NAME_LENGTH);
menu_layer_reload_data(layer->menu_layer); menu_layer_reload_data(layer->menu_layer);
@ -74,7 +89,8 @@ int LIST_LAYER_add_habit(struct ListLayer *layer,
layer->habit_checkmarks[count] = new_checkmark; layer->habit_checkmarks[count] = new_checkmark;
layer->habit_count++; layer->habit_count++;
return 0; CLEANUP:
return rval;
} }
static uint16_t get_num_rows(MenuLayer *menu_layer, static uint16_t get_num_rows(MenuLayer *menu_layer,
@ -90,11 +106,20 @@ static void on_draw_row(GContext *ctx,
MenuIndex *cell_index, MenuIndex *cell_index,
void *callback_context) void *callback_context)
{ {
int rval = 0;
abort_if(!cell_index, "cell_index is null");
int n = cell_index->row; int n = cell_index->row;
struct ListLayer *list_layer = callback_context; struct ListLayer *list_layer = callback_context;
abort_if(!list_layer, "list_layer is null");
char *name = list_layer->habit_names[n]; char *name = list_layer->habit_names[n];
menu_cell_basic_draw(ctx, cell_layer, name, NULL, NULL); menu_cell_basic_draw(ctx, cell_layer, name, NULL, NULL);
CLEANUP:
if(rval) CRASH();
} }
static int16_t get_cell_height(struct MenuLayer *menu_layer, static int16_t get_cell_height(struct MenuLayer *menu_layer,
@ -108,21 +133,23 @@ static void select_click(struct MenuLayer *menu_layer,
struct MenuIndex *index, struct MenuIndex *index,
void *callback_context) void *callback_context)
{ {
int rval = 0;
struct ListLayer *list_layer = callback_context; struct ListLayer *list_layer = callback_context;
if(!list_layer->callbacks.on_select) return; abort_if(!list_layer, "list_layer is null");
list_layer->callbacks.on_select(list_layer->callback_context); struct ListLayerCallbacks *callbacks = &list_layer->callbacks;
} abort_if(!callbacks, "callbacks is null");
static void request_list(void *context) int n = index->row;
{ int habit_id = list_layer->habit_ids[n];
struct ListLayer *layer = context;
LIST_LAYER_allocate(layer, 4); if(!callbacks->on_select) return;
LIST_LAYER_add_habit(layer, 0, "Wake up early", 0); rval = callbacks->on_select(habit_id, callbacks->on_select_context);
LIST_LAYER_add_habit(layer, 1, "Meditate", 1); abort_if(rval, "callbacks->on_select failed");
LIST_LAYER_add_habit(layer, 2, "Exercise", 1);
LIST_LAYER_add_habit(layer, 3, "Go to school", 0); CLEANUP:
if(rval) CRASH();
} }
static void set_menu_layer_callbacks(struct ListLayer *list_layer, static void set_menu_layer_callbacks(struct ListLayer *list_layer,
@ -149,7 +176,6 @@ static void set_menu_layer_styles(MenuLayer *menu_layer)
void LIST_LAYER_attach_to_window(struct ListLayer *layer, struct Window *window) void LIST_LAYER_attach_to_window(struct ListLayer *layer, struct Window *window)
{ {
menu_layer_set_click_config_onto_window(layer->menu_layer, window); menu_layer_set_click_config_onto_window(layer->menu_layer, window);
app_timer_register(500, request_list, layer);
} }
void LIST_LAYER_add_to_layer(struct ListLayer *layer, struct Layer *root_layer) void LIST_LAYER_add_to_layer(struct ListLayer *layer, struct Layer *root_layer)
@ -178,7 +204,7 @@ struct ListLayer* LIST_LAYER_create(struct GRect bounds)
void LIST_LAYER_destroy(struct ListLayer *list_layer) void LIST_LAYER_destroy(struct ListLayer *list_layer)
{ {
if(!list_layer) return; if(!list_layer) return;
free_habits(list_layer); LIST_LAYER_clear(list_layer);
menu_layer_destroy(list_layer->menu_layer); menu_layer_destroy(list_layer->menu_layer);
free(list_layer); free(list_layer);
} }

@ -22,7 +22,9 @@
struct ListLayerCallbacks struct ListLayerCallbacks
{ {
void (*on_select)(void *callback_context); void *on_select_context;
int (*on_select)(int habit_id, void *callback_context);
}; };
struct ListLayer struct ListLayer
@ -35,14 +37,22 @@ struct ListLayer
struct MenuLayer *menu_layer; struct MenuLayer *menu_layer;
struct ActionWindow *action_window; struct ActionWindow *action_window;
void *callback_context;
struct ListLayerCallbacks callbacks; struct ListLayerCallbacks callbacks;
}; };
int LIST_LAYER_add_habit(struct ListLayer *layer,
int new_id,
char *new_name,
int new_checkmark);
int LIST_LAYER_allocate(struct ListLayer *layer, int count);
void LIST_LAYER_attach_to_window(struct ListLayer *layer, struct Window *window); void LIST_LAYER_attach_to_window(struct ListLayer *layer, struct Window *window);
void LIST_LAYER_add_to_layer(struct ListLayer *layer, struct Layer *root_layer); void LIST_LAYER_add_to_layer(struct ListLayer *layer, struct Layer *root_layer);
struct ListLayer* LIST_LAYER_create(struct GRect bounds); struct ListLayer* LIST_LAYER_create(struct GRect bounds);
void LIST_LAYER_destroy(struct ListLayer *layer); void LIST_LAYER_destroy(struct ListLayer *layer);
int LIST_LAYER_clear(struct ListLayer *layer);

@ -21,15 +21,69 @@
#include "list_window.h" #include "list_window.h"
#include "../action/action_window.h" #include "../action/action_window.h"
#include "list_layer.h" #include "list_layer.h"
#include "../animation/animation_window.h" #include "../../network.h"
#include "../../util.h"
static void on_select(void *callback_context) // NETWORK CALLBACKS
// -----------------------------------------------------------------------------
int on_habit(int id, char *name, int checkmark, void *callback_context)
{ {
int rval = 0;
struct ListWindow *window = callback_context; struct ListWindow *window = callback_context;
LIST_WINDOW_show_action_window(window);
rval = LIST_LAYER_add_habit(window->list_layer, id, name, checkmark);
abort_if(rval, "LIST_LAYER_add_habit failed");
CLEANUP:
return rval;
}
int on_count(int count, void *callback_context)
{
int rval = 0;
struct ListWindow *window = callback_context;
rval = LIST_LAYER_allocate(window->list_layer, count);
abort_if(rval, "LIST_LAYER_allocate failed");
CLEANUP:
return rval;
}
// BUTTON CALLBACKS
// -----------------------------------------------------------------------------
static int on_select(int habit_id, void *callback_context)
{
int rval = 0;
struct ListWindow *window = callback_context;
ACTION_WINDOW_destroy(window->action_window);
window->action_window = ACTION_WINDOW_create(habit_id);
abort_if(!window->action_window, "ACTION_WINDOW_create failed");
window_stack_push(window->action_window->raw_window, true);
CLEANUP:
return rval;
} }
// callback: WindowHandler // TIMER CALLBACKS
// -----------------------------------------------------------------------------
static void request_list(void *callback_context)
{
int rval = 0;
rval = NETWORK_request_list();
abort_if(rval, "NETWORK_request_list failed");
CLEANUP:
if(rval) CRASH();
}
// WINDOW HANDLERS
// -----------------------------------------------------------------------------
static void on_load(Window *raw_window) static void on_load(Window *raw_window)
{ {
Layer *root_layer = window_get_root_layer(raw_window); Layer *root_layer = window_get_root_layer(raw_window);
@ -40,13 +94,12 @@ static void on_load(Window *raw_window)
LIST_LAYER_attach_to_window(window->list_layer, raw_window); LIST_LAYER_attach_to_window(window->list_layer, raw_window);
LIST_LAYER_add_to_layer(window->list_layer, root_layer); LIST_LAYER_add_to_layer(window->list_layer, root_layer);
window->list_layer->callback_context = window;
window->list_layer->callbacks = (struct ListLayerCallbacks) { window->list_layer->callbacks = (struct ListLayerCallbacks) {
.on_select = on_select .on_select = on_select,
.on_select_context = window
}; };
} }
// callback: WindowHandler
static void on_unload(Window *raw_window) static void on_unload(Window *raw_window)
{ {
struct ListWindow *list_window = window_get_user_data(raw_window); struct ListWindow *list_window = window_get_user_data(raw_window);
@ -54,21 +107,48 @@ static void on_unload(Window *raw_window)
ACTION_WINDOW_destroy(list_window->action_window); ACTION_WINDOW_destroy(list_window->action_window);
} }
void LIST_WINDOW_show_action_window(struct ListWindow *window) static void on_appear(Window *raw_window)
{ {
ACTION_WINDOW_destroy(window->action_window); int rval = 0;
struct ListWindow *window = window_get_user_data(raw_window);
window->action_window = ACTION_WINDOW_create(); LIST_LAYER_clear(window->list_layer);
if(!window->action_window) return;
window_stack_push(window->action_window->raw_window, true); struct NetworkCallbacks *callbacks = NETWORK_get_callbacks();
abort_if(!callbacks, "NETWORK_get_callbacks failed");
callbacks->on_count = on_count;
callbacks->on_count_context = window;
callbacks->on_habit = on_habit;
callbacks->on_habit_context = window;
app_timer_register(500, request_list, window);
CLEANUP:
if(rval) CRASH();
}
static void on_disappear(Window *raw_window)
{
int rval = 0;
struct NetworkCallbacks *callbacks = NETWORK_get_callbacks();
abort_if(!callbacks, "NETWORK_get_callbacks failed");
callbacks->on_count = 0;
callbacks->on_habit = 0;
CLEANUP:
if(rval) CRASH();
} }
// -----------------------------------------------------------------------------
struct ListWindow *LIST_WINDOW_create() struct ListWindow *LIST_WINDOW_create()
{ {
WindowHandlers handlers = { WindowHandlers handlers = {
.load = on_load, .load = on_load,
.unload = on_unload .unload = on_unload,
.appear = on_appear,
.disappear = on_disappear,
}; };
struct ListWindow *list_window = 0; struct ListWindow *list_window = 0;

@ -26,8 +26,6 @@ struct ListWindow
struct ActionWindow *action_window; struct ActionWindow *action_window;
}; };
void LIST_WINDOW_show_action_window(struct ListWindow *window);
struct ListWindow *LIST_WINDOW_create(); struct ListWindow *LIST_WINDOW_create();
void LIST_WINDOW_destroy(struct ListWindow *window); void LIST_WINDOW_destroy(struct ListWindow *window);

@ -22,10 +22,18 @@
#include <pebble.h> #include <pebble.h>
#define abort_if(cond, msg) if(cond) { \ #define abort_if(cond, msg) if(cond) { \
APP_LOG(APP_LOG_LEVEL_ERROR, msg " (%d) (%s:%d)", rval, __FILE__, __LINE__); \ APP_LOG(APP_LOG_LEVEL_ERROR, msg " (%d)", rval); \
rval = 1; goto CLEANUP; } rval = 1; goto CLEANUP; }
#define abort_iff(cond, msg, ...) if(cond) { \ #define abort_iff(cond, msg, ...) if(cond) { \
APP_LOG(APP_LOG_LEVEL_ERROR, msg " (%d) (%s:%d)", __VA_ARGS__, rval, __FILE__, \ APP_LOG(APP_LOG_LEVEL_ERROR, msg " (%d)", __VA_ARGS__, rval); \
__LINE__); \
rval = 1; goto CLEANUP; } rval = 1; goto CLEANUP; }
#define log_debug(msg, ...) APP_LOG(APP_LOG_LEVEL_DEBUG, msg, __VA_ARGS__)
static void CRASH()
{
APP_LOG(APP_LOG_LEVEL_ERROR, "%s", "forcing crash");
int *x = NULL;
*x = 42;
}