Fetch list from phone
This commit is contained in:
@@ -9,6 +9,7 @@ INCLUDE_DIRECTORIES("build/${PEBBLE_FLAVOUR}/src")
|
||||
INCLUDE_DIRECTORIES("build/include")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
add_definitions(-DCLION)
|
||||
|
||||
set(SOURCE_FILES
|
||||
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_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,
|
||||
|
||||
15
src/main.c
15
src/main.c
@@ -19,13 +19,26 @@
|
||||
|
||||
#include <pebble.h>
|
||||
#include "screens/list/list_window.h"
|
||||
#include "network.h"
|
||||
#include "util.h"
|
||||
|
||||
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);
|
||||
|
||||
app_event_loop();
|
||||
|
||||
CLEANUP:
|
||||
LIST_WINDOW_destroy(window);
|
||||
NETWORK_cleanup();
|
||||
return rval;
|
||||
}
|
||||
|
||||
184
src/network.c
184
src/network.c
@@ -22,17 +22,38 @@
|
||||
#include "util.h"
|
||||
|
||||
#define MAX_HABIT_COUNT 50
|
||||
static int HABIT_COUNT;
|
||||
static int HABIT_CURRENT;
|
||||
|
||||
// LIST WINDOW
|
||||
//------------------------------------------------------------------------------
|
||||
struct NetworkState
|
||||
{
|
||||
int habit_count;
|
||||
|
||||
static int request_next_habit()
|
||||
int habit_current;
|
||||
|
||||
struct NetworkCallbacks *callbacks;
|
||||
};
|
||||
|
||||
static int process_ok(struct NetworkState *state)
|
||||
{
|
||||
int rval = 0;
|
||||
abort_if(!state, "state is null");
|
||||
|
||||
if(HABIT_CURRENT >= HABIT_COUNT)
|
||||
struct NetworkCallbacks *callbacks = state->callbacks;
|
||||
abort_if(!callbacks, "callbacks is null");
|
||||
|
||||
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;
|
||||
|
||||
DictionaryIterator *dict;
|
||||
@@ -42,83 +63,72 @@ static int request_next_habit()
|
||||
rval = dict_write_cstring(dict, 0, "FETCH");
|
||||
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");
|
||||
|
||||
rval = app_message_outbox_send();
|
||||
abort_if(rval, "app_message_outbox_send failed");
|
||||
|
||||
HABIT_CURRENT++;
|
||||
state->habit_current++;
|
||||
|
||||
CLEANUP:
|
||||
return rval;
|
||||
}
|
||||
|
||||
static int process_count(DictionaryIterator *iter)
|
||||
static int process_count(DictionaryIterator *iter, struct NetworkState *state)
|
||||
{
|
||||
int rval = 0;
|
||||
abort_if(!state, "state is null");
|
||||
struct NetworkCallbacks *callbacks = state->callbacks;
|
||||
|
||||
Tuple *tuple = dict_find(iter, 1);
|
||||
abort_if(!tuple, "tuple is null");
|
||||
|
||||
int count = tuple->value->int32;
|
||||
|
||||
// rval = LIST_WINDOW_allocate(count);
|
||||
// abort_if(rval, "LIST_WINDOW_allocate failed");
|
||||
if(callbacks->on_count)
|
||||
{
|
||||
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;
|
||||
HABIT_COUNT = count;
|
||||
HABIT_CURRENT = 0;
|
||||
state->habit_count = count;
|
||||
state->habit_current = 0;
|
||||
|
||||
rval = request_next_habit();
|
||||
abort_if(rval, "request_next_habit failed");
|
||||
|
||||
CLEANUP:
|
||||
return rval;
|
||||
}
|
||||
|
||||
static int process_habit(DictionaryIterator *iter)
|
||||
{
|
||||
int rval = 0;
|
||||
|
||||
// // id
|
||||
// Tuple *tuple = dict_find(iter, 1);
|
||||
// abort_if(!tuple, "tuple is null");
|
||||
// int id = tuple->value->int32;
|
||||
//
|
||||
// // name
|
||||
// tuple = dict_find(iter, 2);
|
||||
// abort_if(!tuple, "tuple is null");
|
||||
// char *name = tuple->value->cstring;
|
||||
//
|
||||
// // checkmark value
|
||||
// tuple = dict_find(iter, 3);
|
||||
// abort_if(!tuple, "tuple is null");
|
||||
// int checkmark = tuple->value->int32;
|
||||
|
||||
// rval = LIST_WINDOW_add_habit(id, name, checkmark);
|
||||
// abort_if(rval, "LIST_WINDOW_add_habit failed");
|
||||
|
||||
rval = request_next_habit();
|
||||
rval = request_next_habit(state);
|
||||
abort_if(rval, "request_next_habit failed");
|
||||
|
||||
CLEANUP:
|
||||
return rval;
|
||||
}
|
||||
|
||||
int NETWORK_request_list()
|
||||
static int process_habit(DictionaryIterator *iter, struct NetworkState *state)
|
||||
{
|
||||
int rval = 0;
|
||||
struct NetworkCallbacks *callbacks = state->callbacks;
|
||||
|
||||
DictionaryIterator *dict;
|
||||
rval = app_message_outbox_begin(&dict);
|
||||
abort_if(rval, "app_message_outbox_begin failed");
|
||||
Tuple *tuple = dict_find(iter, 1);
|
||||
abort_if(!tuple, "tuple is null");
|
||||
int id = tuple->value->int32;
|
||||
|
||||
rval = dict_write_cstring(dict, 0, "COUNT");
|
||||
abort_if(rval, "dict_write_cstring failed");
|
||||
tuple = dict_find(iter, 2);
|
||||
abort_if(!tuple, "tuple is null");
|
||||
char *name = tuple->value->cstring;
|
||||
|
||||
rval = app_message_outbox_send();
|
||||
abort_if(rval, "app_message_outbox_send failed");
|
||||
tuple = dict_find(iter, 3);
|
||||
abort_if(!tuple, "tuple is null");
|
||||
int checkmark = tuple->value->int32;
|
||||
|
||||
if(callbacks->on_habit)
|
||||
{
|
||||
void *ctx = callbacks->on_habit_context;
|
||||
rval = callbacks->on_habit(id, name, checkmark, ctx);
|
||||
abort_if(rval, "state->on_habit failed");
|
||||
|
||||
rval = request_next_habit(state);
|
||||
abort_if(rval, "request_next_habit failed");
|
||||
}
|
||||
|
||||
CLEANUP:
|
||||
return rval;
|
||||
@@ -141,44 +151,102 @@ int NETWORK_request_toggle(int id)
|
||||
rval = app_message_outbox_send();
|
||||
abort_if(rval, "app_message_outbox_send failed");
|
||||
|
||||
CLEANUP:
|
||||
log_debug("--> %s", "COUNT");
|
||||
|
||||
CLEANUP:
|
||||
return rval;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int NETWORK_request_list()
|
||||
{
|
||||
int rval = 0;
|
||||
|
||||
DictionaryIterator *dict;
|
||||
rval = app_message_outbox_begin(&dict);
|
||||
abort_if(rval, "app_message_outbox_begin failed");
|
||||
|
||||
rval = dict_write_cstring(dict, 0, "COUNT");
|
||||
abort_if(rval, "dict_write_cstring failed");
|
||||
|
||||
rval = app_message_outbox_send();
|
||||
abort_if(rval, "app_message_outbox_send failed");
|
||||
|
||||
log_debug("--> %s", "COUNT");
|
||||
|
||||
CLEANUP:
|
||||
return rval;
|
||||
}
|
||||
|
||||
static void NETWORK_on_received(DictionaryIterator *iter, void *context)
|
||||
{
|
||||
int rval = 0;
|
||||
struct NetworkState *state = context;
|
||||
abort_if(!state, "state is null");
|
||||
|
||||
Tuple *tuple = dict_find(iter, 0);
|
||||
abort_if(!tuple, "tuple is null");
|
||||
|
||||
char *action = tuple->value->cstring;
|
||||
log_debug("<-- %s", action);
|
||||
|
||||
if(strcmp(action, "COUNT") == 0)
|
||||
{
|
||||
rval = process_count(iter);
|
||||
rval = process_count(iter, state);
|
||||
abort_if(rval, "process_count failed");
|
||||
}
|
||||
else if(strcmp(action, "HABIT") == 0)
|
||||
{
|
||||
rval = process_habit(iter);
|
||||
rval = process_habit(iter, state);
|
||||
abort_if(rval, "process_habit failed");
|
||||
}
|
||||
else if(strcmp(action, "OK") == 0)
|
||||
{
|
||||
rval = NETWORK_request_list();
|
||||
abort_if(rval, "NETWORK_request_list failed");
|
||||
rval = process_ok(state);
|
||||
abort_if(rval, "process_ok failed");
|
||||
}
|
||||
|
||||
CLEANUP:
|
||||
return;
|
||||
}
|
||||
|
||||
struct NetworkCallbacks * NETWORK_get_callbacks()
|
||||
{
|
||||
struct NetworkState *state = app_message_get_context();
|
||||
return state->callbacks;
|
||||
}
|
||||
|
||||
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_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
|
||||
|
||||
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_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"
|
||||
|
||||
const char *ACTIONS[] = {
|
||||
" Check",
|
||||
" View stats"
|
||||
" Check",
|
||||
" More Info"
|
||||
};
|
||||
|
||||
// MENU LAYER CALLBACKS
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// callback: MenuLayerSelectCallback
|
||||
static void on_click(struct MenuLayer *menu_layer,
|
||||
MenuIndex *cell_index,
|
||||
@@ -62,6 +65,8 @@ static int16_t on_get_cell_height(struct MenuLayer *menu_layer,
|
||||
return CELL_HEIGHT;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static void set_menu_layer_callbacks(struct ActionMenuLayer *action_menu,
|
||||
struct MenuLayer *menu)
|
||||
{
|
||||
|
||||
@@ -21,13 +21,12 @@
|
||||
|
||||
struct ActionMenuLayerCallbacks
|
||||
{
|
||||
void (*on_select)(void *callback_context);
|
||||
int (*on_select)(void *callback_context);
|
||||
};
|
||||
|
||||
struct ActionMenuLayer
|
||||
{
|
||||
struct MenuLayer *menu_layer;
|
||||
|
||||
void *callback_context;
|
||||
struct ActionMenuLayerCallbacks callbacks;
|
||||
};
|
||||
|
||||
@@ -24,18 +24,47 @@
|
||||
#include "action_menu_layer.h"
|
||||
#include "style.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 ActionWindow *window = callback_context;
|
||||
|
||||
ANIMATION_WINDOW_destroy(window->animation_window);
|
||||
window->animation_window = ANIMATION_WINDOW_create(
|
||||
struct AnimationWindow *window = ANIMATION_WINDOW_create(
|
||||
RESOURCE_ID_CONFIRM_SEQUENCE);
|
||||
|
||||
window_stack_push(window->animation_window->raw_window, true);
|
||||
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;
|
||||
|
||||
rval = NETWORK_request_toggle(window->habit_id);
|
||||
abort_if(rval, "NETWORK_request_toggle failed");
|
||||
|
||||
struct NetworkCallbacks *net_callbacks = NETWORK_get_callbacks();
|
||||
abort_if(!net_callbacks, "NETWORK_get_callbacks failed");
|
||||
|
||||
net_callbacks->on_ok = on_ok;
|
||||
|
||||
CLEANUP:
|
||||
return rval;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static int add_menu_layer(struct ActionWindow *window,
|
||||
struct Layer *root_layer,
|
||||
struct GRect bounds)
|
||||
@@ -109,13 +138,15 @@ static void set_raw_window_handlers(Window *raw_window)
|
||||
window_set_window_handlers(raw_window, handlers);
|
||||
}
|
||||
|
||||
struct ActionWindow *ACTION_WINDOW_create()
|
||||
struct ActionWindow *ACTION_WINDOW_create(int habit_id)
|
||||
{
|
||||
struct ActionWindow *window = 0;
|
||||
|
||||
window = (struct ActionWindow*) malloc(sizeof(struct ActionWindow));
|
||||
if(!window) return NULL;
|
||||
|
||||
window->habit_id = habit_id;
|
||||
|
||||
Window *raw_window = window_create();
|
||||
if(!raw_window) return NULL;
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
struct ActionWindow
|
||||
{
|
||||
int habit_id;
|
||||
|
||||
struct Window *raw_window;
|
||||
|
||||
struct ActionMenuLayer *menu_layer;
|
||||
@@ -30,6 +32,6 @@ struct ActionWindow
|
||||
struct AnimationWindow *animation_window;
|
||||
};
|
||||
|
||||
struct ActionWindow* ACTION_WINDOW_create();
|
||||
struct ActionWindow* ACTION_WINDOW_create(int habit_id);
|
||||
|
||||
void ACTION_WINDOW_destroy(struct ActionWindow *window);
|
||||
@@ -31,6 +31,6 @@
|
||||
|
||||
#define BORDER_COLOR GColorFolly
|
||||
|
||||
#define BORDER_WIDTH 6
|
||||
#define BORDER_WIDTH 14
|
||||
|
||||
#define CELL_HEIGHT 36
|
||||
@@ -23,22 +23,31 @@
|
||||
|
||||
#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]);
|
||||
free(layer->habit_names);
|
||||
free(layer->habit_checkmarks);
|
||||
free(layer->habit_ids);
|
||||
|
||||
layer->habit_names = 0;
|
||||
layer->habit_checkmarks = 0;
|
||||
layer->habit_ids = 0;
|
||||
layer->habit_count = 0;
|
||||
|
||||
return 0;
|
||||
CLEANUP:
|
||||
return rval;
|
||||
}
|
||||
|
||||
int LIST_LAYER_allocate(struct ListLayer *layer, int count)
|
||||
{
|
||||
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 *));
|
||||
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,
|
||||
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];
|
||||
strncpy(name, new_name, MAX_NAME_LENGTH);
|
||||
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_count++;
|
||||
|
||||
return 0;
|
||||
CLEANUP:
|
||||
return rval;
|
||||
}
|
||||
|
||||
static uint16_t get_num_rows(MenuLayer *menu_layer,
|
||||
@@ -90,11 +106,20 @@ static void on_draw_row(GContext *ctx,
|
||||
MenuIndex *cell_index,
|
||||
void *callback_context)
|
||||
{
|
||||
int rval = 0;
|
||||
abort_if(!cell_index, "cell_index is null");
|
||||
|
||||
int n = cell_index->row;
|
||||
|
||||
struct ListLayer *list_layer = callback_context;
|
||||
abort_if(!list_layer, "list_layer is null");
|
||||
|
||||
char *name = list_layer->habit_names[n];
|
||||
|
||||
menu_cell_basic_draw(ctx, cell_layer, name, NULL, NULL);
|
||||
|
||||
CLEANUP:
|
||||
if(rval) CRASH();
|
||||
}
|
||||
|
||||
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,
|
||||
void *callback_context)
|
||||
{
|
||||
int rval = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
struct ListLayer *layer = context;
|
||||
int n = index->row;
|
||||
int habit_id = list_layer->habit_ids[n];
|
||||
|
||||
LIST_LAYER_allocate(layer, 4);
|
||||
LIST_LAYER_add_habit(layer, 0, "Wake up early", 0);
|
||||
LIST_LAYER_add_habit(layer, 1, "Meditate", 1);
|
||||
LIST_LAYER_add_habit(layer, 2, "Exercise", 1);
|
||||
LIST_LAYER_add_habit(layer, 3, "Go to school", 0);
|
||||
if(!callbacks->on_select) return;
|
||||
rval = callbacks->on_select(habit_id, callbacks->on_select_context);
|
||||
abort_if(rval, "callbacks->on_select failed");
|
||||
|
||||
CLEANUP:
|
||||
if(rval) CRASH();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
@@ -178,7 +204,7 @@ struct ListLayer* LIST_LAYER_create(struct GRect bounds)
|
||||
void LIST_LAYER_destroy(struct ListLayer *list_layer)
|
||||
{
|
||||
if(!list_layer) return;
|
||||
free_habits(list_layer);
|
||||
LIST_LAYER_clear(list_layer);
|
||||
menu_layer_destroy(list_layer->menu_layer);
|
||||
free(list_layer);
|
||||
}
|
||||
@@ -22,7 +22,9 @@
|
||||
|
||||
struct ListLayerCallbacks
|
||||
{
|
||||
void (*on_select)(void *callback_context);
|
||||
void *on_select_context;
|
||||
|
||||
int (*on_select)(int habit_id, void *callback_context);
|
||||
};
|
||||
|
||||
struct ListLayer
|
||||
@@ -35,14 +37,22 @@ struct ListLayer
|
||||
struct MenuLayer *menu_layer;
|
||||
struct ActionWindow *action_window;
|
||||
|
||||
void *callback_context;
|
||||
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_add_to_layer(struct ListLayer *layer, struct Layer *root_layer);
|
||||
|
||||
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 "../action/action_window.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;
|
||||
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;
|
||||
}
|
||||
|
||||
// callback: WindowHandler
|
||||
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;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
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_add_to_layer(window->list_layer, root_layer);
|
||||
|
||||
window->list_layer->callback_context = window;
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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();
|
||||
if(!window->action_window) return;
|
||||
LIST_LAYER_clear(window->list_layer);
|
||||
|
||||
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()
|
||||
{
|
||||
WindowHandlers handlers = {
|
||||
.load = on_load,
|
||||
.unload = on_unload
|
||||
.unload = on_unload,
|
||||
.appear = on_appear,
|
||||
.disappear = on_disappear,
|
||||
};
|
||||
|
||||
struct ListWindow *list_window = 0;
|
||||
|
||||
@@ -26,8 +26,6 @@ struct ListWindow
|
||||
struct ActionWindow *action_window;
|
||||
};
|
||||
|
||||
void LIST_WINDOW_show_action_window(struct ListWindow *window);
|
||||
|
||||
struct ListWindow *LIST_WINDOW_create();
|
||||
|
||||
void LIST_WINDOW_destroy(struct ListWindow *window);
|
||||
|
||||
14
src/util.h
14
src/util.h
@@ -22,10 +22,18 @@
|
||||
#include <pebble.h>
|
||||
|
||||
#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; }
|
||||
|
||||
#define abort_iff(cond, msg, ...) if(cond) { \
|
||||
APP_LOG(APP_LOG_LEVEL_ERROR, msg " (%d) (%s:%d)", __VA_ARGS__, rval, __FILE__, \
|
||||
__LINE__); \
|
||||
APP_LOG(APP_LOG_LEVEL_ERROR, msg " (%d)", __VA_ARGS__, rval); \
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user