First
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
#include "battery.h"
|
||||
#include "src/c/colors.h"
|
||||
|
||||
static Layer *s_battery_layer;
|
||||
static int s_battery_percent;
|
||||
|
||||
|
||||
static void battery_draw(Layer * layer, GContext *ctx) {
|
||||
GRect bounds = layer_get_bounds(layer);
|
||||
|
||||
int width = (bounds.size.w - 2) * s_battery_percent / 100;
|
||||
|
||||
if (width == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get color
|
||||
GColor normal;
|
||||
GColor light;
|
||||
GColor dark;
|
||||
|
||||
if (s_battery_percent > 20) {
|
||||
normal = GREEN;
|
||||
light = GREEN_LIGHT;
|
||||
dark = GREEN_DARK;
|
||||
}
|
||||
else if (s_battery_percent > 10) {
|
||||
normal = ORANGE;
|
||||
light = ORANGE_LIGHT;
|
||||
dark = ORANGE_DARK;
|
||||
}
|
||||
else {
|
||||
normal = RED;
|
||||
light = RED_LIGHT;
|
||||
dark = RED_DARK;
|
||||
}
|
||||
|
||||
// Draw infill
|
||||
graphics_context_set_fill_color(ctx, normal);
|
||||
graphics_fill_rect(
|
||||
ctx,
|
||||
GRect(2, 2, width-2, bounds.size.h-4),
|
||||
0,
|
||||
GCornerNone
|
||||
);
|
||||
|
||||
// Draw normal color conrers
|
||||
graphics_fill_rect(
|
||||
ctx,
|
||||
GRect(0, bounds.size.h-2, 2, 2),
|
||||
0,
|
||||
GCornerNone
|
||||
);
|
||||
graphics_fill_rect(
|
||||
ctx,
|
||||
GRect(width, 0, 2, 2),
|
||||
0,
|
||||
GCornerNone
|
||||
);
|
||||
|
||||
// Draw light edges
|
||||
graphics_context_set_stroke_color(ctx, light);
|
||||
graphics_draw_line(ctx, GPoint(0, 0), GPoint(width-1, 0));
|
||||
graphics_draw_line(ctx, GPoint(0, 1), GPoint(width-1, 1));
|
||||
graphics_draw_line(ctx,GPoint(0, 0), GPoint(0, bounds.size.h-3));
|
||||
graphics_draw_line(ctx,GPoint(1, 0), GPoint(1, bounds.size.h-3));
|
||||
|
||||
// Draw dark edges
|
||||
graphics_context_set_stroke_color(ctx, dark);
|
||||
graphics_draw_line(ctx, GPoint(2, bounds.size.h-2), GPoint(width+1, bounds.size.h-2));
|
||||
graphics_draw_line(ctx, GPoint(2, bounds.size.h-1), GPoint(width+1, bounds.size.h-1));
|
||||
graphics_draw_line(ctx,GPoint(width, 2), GPoint(width, bounds.size.h-1));
|
||||
graphics_draw_line(ctx,GPoint(width+1, 2), GPoint(width+1, bounds.size.h-1));
|
||||
}
|
||||
|
||||
static void battery_changed(BatteryChargeState state) {
|
||||
s_battery_percent = state.charge_percent;
|
||||
layer_mark_dirty(s_battery_layer);
|
||||
}
|
||||
|
||||
void battery_init(Layer *parent) {
|
||||
GRect frame = BATTERY_RECT;
|
||||
s_battery_layer = layer_create(frame);
|
||||
|
||||
layer_set_update_proc(s_battery_layer, battery_draw);
|
||||
layer_add_child(parent, s_battery_layer);
|
||||
|
||||
battery_state_service_subscribe(battery_changed);
|
||||
battery_changed(battery_state_service_peek());
|
||||
}
|
||||
|
||||
void battery_deinit() {
|
||||
// Battery unsubscribe
|
||||
battery_state_service_unsubscribe();
|
||||
|
||||
// Destroy battery layer
|
||||
layer_destroy(s_battery_layer);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <pebble.h>
|
||||
|
||||
|
||||
// BATTERY POSITION
|
||||
#define BATTERY_RECT GRect(12, 206, 176, 10)
|
||||
|
||||
|
||||
void battery_init(Layer *parent);
|
||||
void battery_deinit();
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
// BLACK/WHITE
|
||||
#define BLACK GColorFromHEX(0x000000)
|
||||
#define WHITE GColorFromHEX(0xffffff)
|
||||
|
||||
// GREEN
|
||||
#define GREEN GColorFromHEX(0x55aa00)
|
||||
#define GREEN_LIGHT GColorFromHEX(0xaaff00)
|
||||
#define GREEN_DARK GColorFromHEX(0x005500)
|
||||
|
||||
// ORANGE
|
||||
#define ORANGE GColorFromHEX(0xffaa00)
|
||||
#define ORANGE_LIGHT GColorFromHEX(0xffff00)
|
||||
#define ORANGE_DARK GColorFromHEX(0xaa5500)
|
||||
|
||||
// RED
|
||||
#define RED GColorFromHEX(0xaa0000)
|
||||
#define RED_LIGHT GColorFromHEX(0xff0000)
|
||||
#define RED_DARK GColorFromHEX(0x550000)
|
||||
+342
@@ -0,0 +1,342 @@
|
||||
#include <pebble.h>
|
||||
#include "items.h"
|
||||
#include "src/c/scrolllayer.h"
|
||||
|
||||
|
||||
item_list_t s_items;
|
||||
|
||||
|
||||
// ------------ NVM ------------
|
||||
static void items_nvm_load() {
|
||||
if (persist_exists(ITEMS_NVM_KEY)) {
|
||||
persist_read_data(ITEMS_NVM_KEY, s_items.items, sizeof(s_items.items));
|
||||
}
|
||||
else {
|
||||
memset(s_items.items, 0, sizeof(s_items.items));
|
||||
}
|
||||
}
|
||||
|
||||
static void items_nvm_save() {
|
||||
persist_write_data(ITEMS_NVM_KEY, s_items.items, sizeof(s_items.items));
|
||||
}
|
||||
|
||||
// ------------ ITEMS ------------
|
||||
static void items_organize(item_list_t *item_list) {
|
||||
item_list->num_items = 0;
|
||||
|
||||
for (int i = 0; i < MAX_ITEMS; i++) {
|
||||
if (item_list->items[i].name[0] != 0) {
|
||||
if (item_list->num_items != i) {
|
||||
// Copy item up
|
||||
memcpy(&item_list->items[item_list->num_items], &item_list->items[i], sizeof(item_list->items[i]));
|
||||
// Delete item
|
||||
memset(&item_list->items[i], 0, sizeof(item_list->items[i]));
|
||||
}
|
||||
item_list->num_items++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item_list_t *items_get() {
|
||||
return &s_items;
|
||||
}
|
||||
|
||||
// ------------ PHONE ------------
|
||||
static void update_items(item_list_t *items, const item_list_t *buffer) {
|
||||
if (!items || !buffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check existing items
|
||||
for (int i = 0; i < MAX_ITEMS; i++) {
|
||||
if (items->items[i].name[0] == '\0') {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
for (int j = 0; j < MAX_ITEMS; j++) {
|
||||
if (buffer->items[j].name[0] != '\0' && strcmp(items->items[i].name, buffer->items[j].name) == 0) {
|
||||
|
||||
// Item still exists
|
||||
items->items[i].show_percentage = buffer->items[j].show_percentage;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Item no longer exists
|
||||
if (!found) {
|
||||
memset(&items->items[i], 0, sizeof(items->items[i]));
|
||||
}
|
||||
}
|
||||
|
||||
// Add items
|
||||
for (int i = 0; i < MAX_ITEMS; i++) {
|
||||
if (buffer->items[i].name[0] == '\0') {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
for (int j = 0; j < MAX_ITEMS; j++) {
|
||||
if (items->items[j].name[0] != '\0' && strcmp(items->items[j].name, buffer->items[i].name) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
for (int j = 0; j < MAX_ITEMS; j++) {
|
||||
if (items->items[j].name[0] == '\0') {
|
||||
memcpy(&items->items[j], &buffer->items[i], sizeof(items->items[j]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
items_organize(items);
|
||||
}
|
||||
|
||||
static void inbox_received_handler(DictionaryIterator *iter, void *context) {
|
||||
// Remove scroll layer items
|
||||
scroll_layer_remove_items();
|
||||
|
||||
Tuple *tuple;
|
||||
item_list_t item_buffer;
|
||||
|
||||
// Get the item 1
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_1);
|
||||
if (tuple) {
|
||||
strncpy(item_buffer.items[0].name, tuple->value->cstring, MAX_CHARACTERS);
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_1_SUCCESS);
|
||||
if (tuple) {
|
||||
int success = atoi(tuple->value->cstring);
|
||||
if (success < 0) { success = 0; }
|
||||
item_buffer.items[0].successes = success;
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_1_FAIL);
|
||||
if (tuple) {
|
||||
int fail = atoi(tuple->value->cstring);
|
||||
if (fail < 0) { fail = 0; }
|
||||
item_buffer.items[0].fails = fail;
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_1_PERCENTAGE);
|
||||
if (tuple) {
|
||||
bool show_percentage = tuple->value->int32 != 0;
|
||||
item_buffer.items[0].show_percentage = show_percentage;
|
||||
}
|
||||
|
||||
// Get the item 2
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_2);
|
||||
if (tuple) {
|
||||
strncpy(item_buffer.items[1].name, tuple->value->cstring, MAX_CHARACTERS);
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_2_SUCCESS);
|
||||
if (tuple) {
|
||||
int success = atoi(tuple->value->cstring);
|
||||
if (success < 0) { success = 0; }
|
||||
item_buffer.items[1].successes = success;
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_2_FAIL);
|
||||
if (tuple) {
|
||||
int fail = atoi(tuple->value->cstring);
|
||||
if (fail < 0) { fail = 0; }
|
||||
item_buffer.items[1].fails = fail;
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_2_PERCENTAGE);
|
||||
if (tuple) {
|
||||
bool show_percentage = tuple->value->int32 != 0;
|
||||
item_buffer.items[1].show_percentage = show_percentage;
|
||||
}
|
||||
|
||||
// Get the item 3
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_3);
|
||||
if (tuple) {
|
||||
strncpy(item_buffer.items[2].name, tuple->value->cstring, MAX_CHARACTERS);
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_3_SUCCESS);
|
||||
if (tuple) {
|
||||
int success = atoi(tuple->value->cstring);
|
||||
if (success < 0) { success = 0; }
|
||||
item_buffer.items[2].successes = success;
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_3_FAIL);
|
||||
if (tuple) {
|
||||
int fail = atoi(tuple->value->cstring);
|
||||
if (fail < 0) { fail = 0; }
|
||||
item_buffer.items[2].fails = fail;
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_3_PERCENTAGE);
|
||||
if (tuple) {
|
||||
bool show_percentage = tuple->value->int32 != 0;
|
||||
item_buffer.items[2].show_percentage = show_percentage;
|
||||
}
|
||||
|
||||
// Get the item 4
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_4);
|
||||
if (tuple) {
|
||||
strncpy(item_buffer.items[3].name, tuple->value->cstring, MAX_CHARACTERS);
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_4_SUCCESS);
|
||||
if (tuple) {
|
||||
int success = atoi(tuple->value->cstring);
|
||||
if (success < 0) { success = 0; }
|
||||
item_buffer.items[3].successes = success;
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_4_FAIL);
|
||||
if (tuple) {
|
||||
int fail = atoi(tuple->value->cstring);
|
||||
if (fail < 0) { fail = 0; }
|
||||
item_buffer.items[3].fails = fail;
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_4_PERCENTAGE);
|
||||
if (tuple) {
|
||||
bool show_percentage = tuple->value->int32 != 0;
|
||||
item_buffer.items[3].show_percentage = show_percentage;
|
||||
}
|
||||
|
||||
// Get the item 5
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_5);
|
||||
if (tuple) {
|
||||
strncpy(item_buffer.items[4].name, tuple->value->cstring, MAX_CHARACTERS);
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_5_SUCCESS);
|
||||
if (tuple) {
|
||||
int success = atoi(tuple->value->cstring);
|
||||
if (success < 0) { success = 0; }
|
||||
item_buffer.items[4].successes = success;
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_5_FAIL);
|
||||
if (tuple) {
|
||||
int fail = atoi(tuple->value->cstring);
|
||||
if (fail < 0) { fail = 0; }
|
||||
item_buffer.items[4].fails = fail;
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_5_PERCENTAGE);
|
||||
if (tuple) {
|
||||
bool show_percentage = tuple->value->int32 != 0;
|
||||
item_buffer.items[4].show_percentage = show_percentage;
|
||||
}
|
||||
|
||||
// Get the item 6
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_6);
|
||||
if (tuple) {
|
||||
strncpy(item_buffer.items[5].name, tuple->value->cstring, MAX_CHARACTERS);
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_6_SUCCESS);
|
||||
if (tuple) {
|
||||
int success = atoi(tuple->value->cstring);
|
||||
if (success < 0) { success = 0; }
|
||||
item_buffer.items[5].successes = success;
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_6_FAIL);
|
||||
if (tuple) {
|
||||
int fail = atoi(tuple->value->cstring);
|
||||
if (fail < 0) { fail = 0; }
|
||||
item_buffer.items[5].fails = fail;
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_6_PERCENTAGE);
|
||||
if (tuple) {
|
||||
bool show_percentage = tuple->value->int32 != 0;
|
||||
item_buffer.items[5].show_percentage = show_percentage;
|
||||
}
|
||||
|
||||
// Get the item 7
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_7);
|
||||
if (tuple) {
|
||||
strncpy(item_buffer.items[6].name, tuple->value->cstring, MAX_CHARACTERS);
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_7_SUCCESS);
|
||||
if (tuple) {
|
||||
int success = atoi(tuple->value->cstring);
|
||||
if (success < 0) { success = 0; }
|
||||
item_buffer.items[6].successes = success;
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_7_FAIL);
|
||||
if (tuple) {
|
||||
int fail = atoi(tuple->value->cstring);
|
||||
if (fail < 0) { fail = 0; }
|
||||
item_buffer.items[6].fails = fail;
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_7_PERCENTAGE);
|
||||
if (tuple) {
|
||||
bool show_percentage = tuple->value->int32 != 0;
|
||||
item_buffer.items[6].show_percentage = show_percentage;
|
||||
}
|
||||
|
||||
// Get the item 8
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_8);
|
||||
if (tuple) {
|
||||
strncpy(item_buffer.items[7].name, tuple->value->cstring, MAX_CHARACTERS);
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_8_SUCCESS);
|
||||
if (tuple) {
|
||||
int success = atoi(tuple->value->cstring);
|
||||
if (success < 0) { success = 0; }
|
||||
item_buffer.items[7].successes = success;
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_8_FAIL);
|
||||
if (tuple) {
|
||||
int fail = atoi(tuple->value->cstring);
|
||||
if (fail < 0) { fail = 0; }
|
||||
item_buffer.items[7].fails = fail;
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_8_PERCENTAGE);
|
||||
if (tuple) {
|
||||
bool show_percentage = tuple->value->int32 != 0;
|
||||
item_buffer.items[7].show_percentage = show_percentage;
|
||||
}
|
||||
|
||||
// Get the item 9
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_9);
|
||||
if (tuple) {
|
||||
strncpy(item_buffer.items[8].name, tuple->value->cstring, MAX_CHARACTERS);
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_9_SUCCESS);
|
||||
if (tuple) {
|
||||
int success = atoi(tuple->value->cstring);
|
||||
if (success < 0) { success = 0; }
|
||||
item_buffer.items[8].successes = success;
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_9_FAIL);
|
||||
if (tuple) {
|
||||
int fail = atoi(tuple->value->cstring);
|
||||
if (fail < 0) { fail = 0; }
|
||||
item_buffer.items[8].fails = fail;
|
||||
}
|
||||
tuple = dict_find(iter, MESSAGE_KEY_ITEM_9_PERCENTAGE);
|
||||
if (tuple) {
|
||||
bool show_percentage = tuple->value->int32 != 0;
|
||||
item_buffer.items[8].show_percentage = show_percentage;
|
||||
}
|
||||
|
||||
// Organize buffer
|
||||
items_organize(&item_buffer);
|
||||
|
||||
// Update list from buffer
|
||||
update_items(&s_items, &item_buffer);
|
||||
|
||||
// Save the items to NVM
|
||||
items_organize(&s_items);
|
||||
items_nvm_save();
|
||||
|
||||
// Update the ScrollLayer
|
||||
scroll_layer_add_items();
|
||||
scroll_layer_update_scrollbar();
|
||||
}
|
||||
|
||||
// ------------ INITS ------------
|
||||
void items_init() {
|
||||
// Read items from NVM
|
||||
items_nvm_load();
|
||||
items_organize(&s_items);
|
||||
|
||||
// Register received handler
|
||||
app_message_register_inbox_received(inbox_received_handler);
|
||||
app_message_open(app_message_inbox_size_maximum(), app_message_outbox_size_maximum());
|
||||
}
|
||||
|
||||
void items_deinit() {
|
||||
items_nvm_save();
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
// NVM
|
||||
#define ITEMS_NVM_KEY 1
|
||||
#define MAX_ITEMS 9
|
||||
#define MAX_CHARACTERS 10
|
||||
|
||||
|
||||
typedef struct {
|
||||
char name[MAX_CHARACTERS+1];
|
||||
int successes;
|
||||
int fails;
|
||||
bool show_percentage;
|
||||
} item_t;
|
||||
|
||||
typedef struct {
|
||||
int num_items;
|
||||
item_t items[MAX_ITEMS];
|
||||
} item_list_t;
|
||||
|
||||
|
||||
item_list_t *items_get();
|
||||
void items_init();
|
||||
void items_deinit();
|
||||
@@ -0,0 +1,81 @@
|
||||
#include <pebble.h>
|
||||
|
||||
#include "src/c/battery.h"
|
||||
#include "src/c/time.h"
|
||||
#include "src/c/scrolllayer.h"
|
||||
|
||||
|
||||
static Window *s_main_window;
|
||||
static Layer *s_background_layer;
|
||||
static GBitmap *s_background_bitmap;
|
||||
|
||||
|
||||
static void update_background(Layer *layer, GContext *ctx) {
|
||||
GRect bounds = gbitmap_get_bounds(s_background_bitmap);
|
||||
graphics_draw_bitmap_in_rect(
|
||||
ctx,
|
||||
s_background_bitmap,
|
||||
GRect(0, 0, bounds.size.w, bounds.size.h)
|
||||
);
|
||||
}
|
||||
|
||||
static void main_window_load(Window *window) {
|
||||
Layer *window_layer = window_get_root_layer(window);
|
||||
GRect bounds = layer_get_bounds(window_layer);
|
||||
|
||||
// Create background layer
|
||||
s_background_layer = layer_create(bounds);
|
||||
layer_set_update_proc(s_background_layer, update_background);
|
||||
layer_add_child(window_layer, s_background_layer);
|
||||
|
||||
// Load background bitmap
|
||||
s_background_bitmap = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_BACKGROUND);
|
||||
|
||||
// Init items
|
||||
items_init();
|
||||
|
||||
// Init and draw the battery
|
||||
battery_init(window_layer);
|
||||
|
||||
// Init and draw the time
|
||||
time_init(window_layer);
|
||||
|
||||
// Init and draw the ScrollLayer
|
||||
scrolllayer_init(window_layer, window);
|
||||
}
|
||||
|
||||
static void main_window_unload(Window *window) {
|
||||
// Deinit the items
|
||||
items_deinit();
|
||||
|
||||
// Deinit the battery
|
||||
battery_deinit();
|
||||
|
||||
// Deinit the time
|
||||
time_deinit();
|
||||
|
||||
// Deinit the ScrollLayer
|
||||
scrolllayer_deinit();
|
||||
}
|
||||
|
||||
static void init() {
|
||||
// MAIN WINDOW CREATE
|
||||
s_main_window = window_create();
|
||||
window_set_background_color(s_main_window, GColorBlack);
|
||||
window_set_window_handlers(s_main_window, (WindowHandlers) {
|
||||
.load = main_window_load,
|
||||
.unload = main_window_unload
|
||||
});
|
||||
window_stack_push(s_main_window, true);
|
||||
}
|
||||
|
||||
static void deinit() {
|
||||
// MAIN WINDOW DESTROY
|
||||
window_destroy(s_main_window);
|
||||
}
|
||||
|
||||
int main() {
|
||||
init();
|
||||
app_event_loop();
|
||||
deinit();
|
||||
}
|
||||
@@ -0,0 +1,560 @@
|
||||
#include <pebble.h>
|
||||
#include "scrolllayer.h"
|
||||
|
||||
#include "src/c/colors.h"
|
||||
|
||||
static ScrollLayer *s_scroll_layer;
|
||||
static Layer *s_scroll_bar_layer;
|
||||
static GFont s_scrolllayer_font;
|
||||
static GBitmap *s_background_bitmap;
|
||||
static GBitmap *s_plus_bitmap;
|
||||
static GBitmap *s_minus_bitmap;
|
||||
static GBitmap *s_background_plus_pressed_bitmap;
|
||||
static GBitmap *s_background_minus_pressed_bitmap;
|
||||
static GBitmap *s_scroll_bar_current_bitmap;
|
||||
static GBitmap *s_scroll_bar_full_bitmap;
|
||||
static GBitmap *s_scroll_bar_half_bitmap;
|
||||
static GBitmap *s_scroll_bar_third_bitmap;
|
||||
|
||||
// TOUCH BUTTONS
|
||||
static GRect item_1_plus_button;
|
||||
static GRect item_1_minus_button;
|
||||
static GRect item_2_plus_button;
|
||||
static GRect item_2_minus_button;
|
||||
static GRect item_3_plus_button;
|
||||
static GRect item_3_minus_button;
|
||||
|
||||
// SCROLL
|
||||
static int s_scroll_y;
|
||||
static int s_scroll_page;
|
||||
static scroll_items_t s_scroll_items;
|
||||
|
||||
|
||||
// ------------ SCROLL ------------
|
||||
static void scroll_up(ClickRecognizerRef recognizer, void *context) {
|
||||
s_scroll_y -= MAX_UI_ITEMS * ITEM_UI_HEIGHT;
|
||||
s_scroll_page -= 1;
|
||||
|
||||
if (s_scroll_y < 0) {
|
||||
s_scroll_y = 0;
|
||||
}
|
||||
|
||||
if (s_scroll_page < 0) {
|
||||
s_scroll_page = 0;
|
||||
}
|
||||
|
||||
// Move scroll bar
|
||||
GRect scroll_frame = layer_get_frame(s_scroll_bar_layer);
|
||||
int scroll_frame_y = scroll_frame.origin.y - scroll_frame.size.h;
|
||||
if (scroll_frame_y < SCROLL_BAR_ORIGIN_HEIGHT) {
|
||||
scroll_frame_y = SCROLL_BAR_ORIGIN_HEIGHT;
|
||||
}
|
||||
scroll_frame.origin.y = scroll_frame_y;
|
||||
layer_set_frame(s_scroll_bar_layer, scroll_frame);
|
||||
layer_mark_dirty(s_scroll_bar_layer);
|
||||
|
||||
scroll_layer_set_content_offset(
|
||||
s_scroll_layer,
|
||||
GPoint(0, -s_scroll_y),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
static void scroll_down(ClickRecognizerRef recognizer, void *context) {
|
||||
s_scroll_y += MAX_UI_ITEMS * ITEM_UI_HEIGHT;
|
||||
s_scroll_page += 1;
|
||||
int max_scroll = MAX_UI_ITEMS * ITEM_UI_HEIGHT * (s_scroll_items.page_count - 1);
|
||||
|
||||
if (s_scroll_y > max_scroll) {
|
||||
s_scroll_y = max_scroll;
|
||||
}
|
||||
|
||||
if (s_scroll_page > ((MAX_ITEMS / MAX_UI_ITEMS) - 1)) {
|
||||
s_scroll_page = ((MAX_ITEMS / MAX_UI_ITEMS) - 1);
|
||||
}
|
||||
|
||||
// Move scroll bar
|
||||
GRect scroll_frame = layer_get_frame(s_scroll_bar_layer);
|
||||
int scroll_frame_y = scroll_frame.origin.y + scroll_frame.size.h;
|
||||
if (scroll_frame_y > (SCROLL_BAR_ORIGIN_HEIGHT_END - scroll_frame.size.h)) {
|
||||
scroll_frame_y = (SCROLL_BAR_ORIGIN_HEIGHT_END - scroll_frame.size.h);
|
||||
}
|
||||
scroll_frame.origin.y = scroll_frame_y;
|
||||
layer_set_frame(s_scroll_bar_layer, scroll_frame);
|
||||
layer_mark_dirty(s_scroll_bar_layer);
|
||||
|
||||
scroll_layer_set_content_offset(
|
||||
s_scroll_layer,
|
||||
GPoint(0, -s_scroll_y),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// ------------ BUTTONS ------------
|
||||
static void click_config_provider(void *context) {
|
||||
window_single_click_subscribe(BUTTON_ID_UP, scroll_up);
|
||||
window_single_click_subscribe(BUTTON_ID_DOWN, scroll_down);
|
||||
}
|
||||
|
||||
// ------------ HELPERS ------------
|
||||
static GColor get_color_float(float val) {
|
||||
GColor color;
|
||||
|
||||
if (val < RED_LIMIT) {
|
||||
color = RED;
|
||||
}
|
||||
else if (val < ORANGE_LIMIT) {
|
||||
color = ORANGE;
|
||||
}
|
||||
else {
|
||||
color = GREEN;
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
static void bar_draw(Layer *layer, GContext *ctx) {
|
||||
GColor *color = layer_get_data(layer);
|
||||
|
||||
graphics_context_set_fill_color(ctx, *color);
|
||||
graphics_fill_rect(ctx, layer_get_bounds(layer), 0, GCornerNone);
|
||||
}
|
||||
|
||||
static void scroll_bar_draw(Layer *layer, GContext *ctx) {
|
||||
GRect bounds = gbitmap_get_bounds(s_scroll_bar_current_bitmap);
|
||||
graphics_draw_bitmap_in_rect(ctx, s_scroll_bar_current_bitmap, GRect(0, 0, bounds.size.w, bounds.size.h));
|
||||
}
|
||||
|
||||
static void fill_percentage_buffer(scroll_items_t *items, int element, int total, float percentage) {
|
||||
if (total > 1000) { items->items->items[element].show_percentage = true; }
|
||||
|
||||
if (items->items->items[element].show_percentage) {
|
||||
int percentage_int = (percentage * 100);
|
||||
snprintf(
|
||||
items->numbers_buffer[element],
|
||||
sizeof(items->numbers_buffer[element]),
|
||||
"%d%%",
|
||||
percentage_int
|
||||
);
|
||||
}
|
||||
else {
|
||||
snprintf(
|
||||
items->numbers_buffer[element],
|
||||
sizeof(items->numbers_buffer[element]),
|
||||
"%d/%d",
|
||||
items->items->items[element].successes,
|
||||
total
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_layer_add_items() {
|
||||
GRect bounds = SCROLLLAYER_FRAME_RECT;
|
||||
int n_items = s_scroll_items.items->num_items-1;
|
||||
if (n_items < 0) { n_items = 0; }
|
||||
s_scroll_items.page_count = (n_items / MAX_UI_ITEMS) + 1;
|
||||
|
||||
// Add entries
|
||||
for (int i = 0; i < s_scroll_items.items->num_items; i++) {
|
||||
// Add background
|
||||
s_scroll_items.backgrounds[i] = bitmap_layer_create(GRect(0, i * ITEM_UI_HEIGHT, bounds.size.w, ITEM_UI_HEIGHT));
|
||||
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[i], s_background_bitmap);
|
||||
bitmap_layer_set_compositing_mode(s_scroll_items.backgrounds[i], GCompOpSet); // Set transparency
|
||||
scroll_layer_add_child(s_scroll_layer, bitmap_layer_get_layer(s_scroll_items.backgrounds[i]));
|
||||
|
||||
// Add text
|
||||
s_scroll_items.texts[i] = text_layer_create(GRect(26, (i * ITEM_UI_HEIGHT) + 4, 124, 16));
|
||||
text_layer_set_text(s_scroll_items.texts[i], s_scroll_items.items->items[i].name);
|
||||
text_layer_set_font(s_scroll_items.texts[i], s_scrolllayer_font);
|
||||
text_layer_set_text_alignment(s_scroll_items.texts[i], GTextAlignmentCenter);
|
||||
text_layer_set_background_color(s_scroll_items.texts[i], GColorClear);
|
||||
text_layer_set_text_color(s_scroll_items.texts[i], WHITE);
|
||||
scroll_layer_add_child(s_scroll_layer, text_layer_get_layer(s_scroll_items.texts[i]));
|
||||
|
||||
// Add percentage
|
||||
int total = s_scroll_items.items->items[i].successes + s_scroll_items.items->items[i].fails;
|
||||
float percentage = (float)s_scroll_items.items->items[i].successes / total;
|
||||
GColor color = get_color_float(percentage);
|
||||
s_scroll_items.numbers[i] = text_layer_create(GRect(26, (i * ITEM_UI_HEIGHT) + 18, 124, 16));
|
||||
fill_percentage_buffer(&s_scroll_items, i, total, percentage);
|
||||
text_layer_set_text(s_scroll_items.numbers[i], s_scroll_items.numbers_buffer[i]);
|
||||
text_layer_set_font(s_scroll_items.numbers[i], s_scrolllayer_font);
|
||||
text_layer_set_text_alignment(s_scroll_items.numbers[i], GTextAlignmentCenter);
|
||||
text_layer_set_background_color(s_scroll_items.numbers[i], GColorClear);
|
||||
text_layer_set_text_color(s_scroll_items.numbers[i], color);
|
||||
scroll_layer_add_child(s_scroll_layer, text_layer_get_layer(s_scroll_items.numbers[i]));
|
||||
|
||||
// Add plus button
|
||||
s_scroll_items.plus_buttons[i] = bitmap_layer_create(GRect(146, (i * ITEM_UI_HEIGHT) + 18, 20, 20));
|
||||
bitmap_layer_set_bitmap(s_scroll_items.plus_buttons[i], s_plus_bitmap);
|
||||
bitmap_layer_set_compositing_mode(s_scroll_items.plus_buttons[i], GCompOpSet); // Set transparency
|
||||
scroll_layer_add_child(s_scroll_layer, bitmap_layer_get_layer(s_scroll_items.plus_buttons[i]));
|
||||
|
||||
// Add minus button
|
||||
s_scroll_items.minus_buttons[i] = bitmap_layer_create(GRect(7, (i * ITEM_UI_HEIGHT) + 18, 20, 20));
|
||||
bitmap_layer_set_bitmap(s_scroll_items.minus_buttons[i], s_minus_bitmap);
|
||||
bitmap_layer_set_compositing_mode(s_scroll_items.minus_buttons[i], GCompOpSet); // Set transparency
|
||||
scroll_layer_add_child(s_scroll_layer, bitmap_layer_get_layer(s_scroll_items.minus_buttons[i]));
|
||||
|
||||
// Add bar
|
||||
int width = (PERCENTAGE_BAR_WIDTH) * percentage;
|
||||
GRect bar = GRect(31, (i * ITEM_UI_HEIGHT) + 40, width, 4);
|
||||
s_scroll_items.success_bars[i] = layer_create_with_data(bar, sizeof(GColor));
|
||||
GColor *color_ptr = layer_get_data(s_scroll_items.success_bars[i]);
|
||||
*color_ptr = color;
|
||||
layer_set_update_proc(s_scroll_items.success_bars[i], bar_draw);
|
||||
scroll_layer_add_child(s_scroll_layer, s_scroll_items.success_bars[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_layer_remove_items() {
|
||||
// Destroy items
|
||||
for (int i = 0; i < MAX_ITEMS; i++) {
|
||||
// TextLayers
|
||||
text_layer_destroy(s_scroll_items.texts[i]);
|
||||
text_layer_destroy(s_scroll_items.numbers[i]);
|
||||
|
||||
// BitmapLayers
|
||||
bitmap_layer_destroy(s_scroll_items.backgrounds[i]);
|
||||
bitmap_layer_destroy(s_scroll_items.plus_buttons[i]);
|
||||
bitmap_layer_destroy(s_scroll_items.minus_buttons[i]);
|
||||
|
||||
// Layers
|
||||
layer_destroy(s_scroll_items.success_bars[i]);
|
||||
|
||||
// Destroy the pointers
|
||||
s_scroll_items.texts[i] = NULL;
|
||||
s_scroll_items.numbers[i] = NULL;
|
||||
s_scroll_items.backgrounds[i] = NULL;
|
||||
s_scroll_items.plus_buttons[i] = NULL;
|
||||
s_scroll_items.minus_buttons[i] = NULL;
|
||||
s_scroll_items.success_bars[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void scroll_layer_update_scrollbar() {
|
||||
GRect scroll_box = layer_get_bounds(s_scroll_bar_layer);
|
||||
GRect scroll_frame = layer_get_frame(s_scroll_bar_layer);
|
||||
|
||||
if (s_scroll_items.page_count == 2) {
|
||||
scroll_box.size.h = 82;
|
||||
scroll_frame.size.h = 82;
|
||||
s_scroll_bar_current_bitmap = s_scroll_bar_half_bitmap;
|
||||
}
|
||||
else if (s_scroll_items.page_count == 3) {
|
||||
scroll_box.size.h = 52;
|
||||
scroll_frame.size.h = 52;
|
||||
s_scroll_bar_current_bitmap = s_scroll_bar_third_bitmap;
|
||||
}
|
||||
else {
|
||||
scroll_box.size.h = 160;
|
||||
scroll_frame.size.h = 160;
|
||||
s_scroll_bar_current_bitmap = s_scroll_bar_full_bitmap;
|
||||
}
|
||||
|
||||
layer_set_bounds(s_scroll_bar_layer, scroll_box);
|
||||
layer_set_frame(s_scroll_bar_layer, scroll_frame);
|
||||
layer_mark_dirty(s_scroll_bar_layer);
|
||||
}
|
||||
|
||||
// ------------ TOUCH ------------
|
||||
static void touch_handler(const TouchEvent *event, void *context) {
|
||||
// Get touch point
|
||||
GPoint point = GPoint(event->x, event->y);
|
||||
|
||||
// First item buttons
|
||||
if (grect_contains_point(&item_1_plus_button, &point)) {
|
||||
int element = 0 + (s_scroll_page * MAX_UI_ITEMS);
|
||||
|
||||
if (element >= s_scroll_items.items->num_items) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->type == TouchEvent_Touchdown) {
|
||||
// Change background to pressed
|
||||
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[element], s_background_plus_pressed_bitmap);
|
||||
|
||||
// Update numbers
|
||||
s_scroll_items.items->items[element].successes++;
|
||||
int total = s_scroll_items.items->items[element].successes + s_scroll_items.items->items[element].fails;
|
||||
float percentage = (float)s_scroll_items.items->items[element].successes / total;
|
||||
GColor color = get_color_float(percentage);
|
||||
fill_percentage_buffer(&s_scroll_items, element, total, percentage);
|
||||
text_layer_set_text_color(s_scroll_items.numbers[element], color);
|
||||
text_layer_set_text(s_scroll_items.numbers[element], s_scroll_items.numbers_buffer[element]);
|
||||
|
||||
// Update the percentage bar
|
||||
int width = (PERCENTAGE_BAR_WIDTH) * percentage;
|
||||
GRect bar = GRect(31, (element * ITEM_UI_HEIGHT) + 40, width, 4);
|
||||
GColor *color_ptr = layer_get_data(s_scroll_items.success_bars[element]);
|
||||
*color_ptr = color;
|
||||
layer_set_frame(s_scroll_items.success_bars[element], bar);
|
||||
}
|
||||
else if (event->type == TouchEvent_Liftoff) {
|
||||
// Reset the background
|
||||
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[element], s_background_bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
if (grect_contains_point(&item_1_minus_button, &point)) {
|
||||
int element = 0 + (s_scroll_page * MAX_UI_ITEMS);
|
||||
|
||||
if (element >= s_scroll_items.items->num_items) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->type == TouchEvent_Touchdown) {
|
||||
// Change background to pressed
|
||||
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[element], s_background_minus_pressed_bitmap);
|
||||
|
||||
s_scroll_items.items->items[element].fails++;
|
||||
int total = s_scroll_items.items->items[element].successes + s_scroll_items.items->items[element].fails;
|
||||
float percentage = (float)s_scroll_items.items->items[element].successes / total;
|
||||
GColor color = get_color_float(percentage);
|
||||
fill_percentage_buffer(&s_scroll_items, element, total, percentage);
|
||||
text_layer_set_text_color(s_scroll_items.numbers[element], color);
|
||||
text_layer_set_text(s_scroll_items.numbers[element], s_scroll_items.numbers_buffer[element]);
|
||||
|
||||
// Update the percentage bar
|
||||
int width = (PERCENTAGE_BAR_WIDTH) * percentage;
|
||||
GRect bar = GRect(31, (element * ITEM_UI_HEIGHT) + 40, width, 4);
|
||||
GColor *color_ptr = layer_get_data(s_scroll_items.success_bars[element]);
|
||||
*color_ptr = color;
|
||||
layer_set_frame(s_scroll_items.success_bars[element], bar);
|
||||
}
|
||||
else if (event->type == TouchEvent_Liftoff) {
|
||||
// Reset the background
|
||||
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[element], s_background_bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
// Second item buttons
|
||||
if (grect_contains_point(&item_2_plus_button, &point)) {
|
||||
int element = 1 + (s_scroll_page * MAX_UI_ITEMS);
|
||||
|
||||
if (element >= s_scroll_items.items->num_items) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->type == TouchEvent_Touchdown) {
|
||||
// Change background to pressed
|
||||
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[element], s_background_plus_pressed_bitmap);
|
||||
|
||||
s_scroll_items.items->items[element].successes++;
|
||||
int total = s_scroll_items.items->items[element].successes + s_scroll_items.items->items[element].fails;
|
||||
float percentage = (float)s_scroll_items.items->items[element].successes / total;
|
||||
GColor color = get_color_float(percentage);
|
||||
fill_percentage_buffer(&s_scroll_items, element, total, percentage);
|
||||
text_layer_set_text_color(s_scroll_items.numbers[element], color);
|
||||
text_layer_set_text(s_scroll_items.numbers[element], s_scroll_items.numbers_buffer[element]);
|
||||
|
||||
// Update the percentage bar
|
||||
int width = (PERCENTAGE_BAR_WIDTH) * percentage;
|
||||
GRect bar = GRect(31, (element * ITEM_UI_HEIGHT) + 40, width, 4);
|
||||
GColor *color_ptr = layer_get_data(s_scroll_items.success_bars[element]);
|
||||
*color_ptr = color;
|
||||
layer_set_frame(s_scroll_items.success_bars[element], bar);
|
||||
}
|
||||
else if (event->type == TouchEvent_Liftoff) {
|
||||
// Reset the background
|
||||
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[element], s_background_bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
if (grect_contains_point(&item_2_minus_button, &point)) {
|
||||
int element = 1 + (s_scroll_page * MAX_UI_ITEMS);
|
||||
|
||||
if (element >= s_scroll_items.items->num_items) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->type == TouchEvent_Touchdown) {
|
||||
// Change background to pressed
|
||||
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[element], s_background_minus_pressed_bitmap);
|
||||
|
||||
s_scroll_items.items->items[element].fails++;
|
||||
int total = s_scroll_items.items->items[element].successes + s_scroll_items.items->items[element].fails;
|
||||
float percentage = (float)s_scroll_items.items->items[element].successes / total;
|
||||
GColor color = get_color_float(percentage);
|
||||
fill_percentage_buffer(&s_scroll_items, element, total, percentage);
|
||||
text_layer_set_text_color(s_scroll_items.numbers[element], color);
|
||||
text_layer_set_text(s_scroll_items.numbers[element], s_scroll_items.numbers_buffer[element]);
|
||||
|
||||
// Update the percentage bar
|
||||
int width = (PERCENTAGE_BAR_WIDTH) * percentage;
|
||||
GRect bar = GRect(31, (element * ITEM_UI_HEIGHT) + 40, width, 4);
|
||||
GColor *color_ptr = layer_get_data(s_scroll_items.success_bars[element]);
|
||||
*color_ptr = color;
|
||||
layer_set_frame(s_scroll_items.success_bars[element], bar);
|
||||
}
|
||||
else if (event->type == TouchEvent_Liftoff) {
|
||||
// Reset the background
|
||||
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[element], s_background_bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
// Thisrd item buttons
|
||||
if (grect_contains_point(&item_3_plus_button, &point)) {
|
||||
int element = 2 + (s_scroll_page * MAX_UI_ITEMS);
|
||||
|
||||
if (element >= s_scroll_items.items->num_items) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->type == TouchEvent_Touchdown) {
|
||||
// Change background to pressed
|
||||
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[element], s_background_plus_pressed_bitmap);
|
||||
|
||||
s_scroll_items.items->items[element].successes++;
|
||||
int total = s_scroll_items.items->items[element].successes + s_scroll_items.items->items[element].fails;
|
||||
float percentage = (float)s_scroll_items.items->items[element].successes / total;
|
||||
GColor color = get_color_float(percentage);
|
||||
fill_percentage_buffer(&s_scroll_items, element, total, percentage);
|
||||
text_layer_set_text_color(s_scroll_items.numbers[element], color);
|
||||
text_layer_set_text(s_scroll_items.numbers[element], s_scroll_items.numbers_buffer[element]);
|
||||
|
||||
// Update the percentage bar
|
||||
int width = (PERCENTAGE_BAR_WIDTH) * percentage;
|
||||
GRect bar = GRect(31, (element * ITEM_UI_HEIGHT) + 40, width, 4);
|
||||
GColor *color_ptr = layer_get_data(s_scroll_items.success_bars[element]);
|
||||
*color_ptr = color;
|
||||
layer_set_frame(s_scroll_items.success_bars[element], bar);
|
||||
}
|
||||
else if (event->type == TouchEvent_Liftoff) {
|
||||
// Reset the background
|
||||
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[element], s_background_bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
if (grect_contains_point(&item_3_minus_button, &point)) {
|
||||
int element = 2 + (s_scroll_page * MAX_UI_ITEMS);
|
||||
|
||||
if (element >= s_scroll_items.items->num_items) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->type == TouchEvent_Touchdown) {
|
||||
// Change background to pressed
|
||||
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[element], s_background_minus_pressed_bitmap);
|
||||
|
||||
s_scroll_items.items->items[element].fails++;
|
||||
int total = s_scroll_items.items->items[element].successes + s_scroll_items.items->items[element].fails;
|
||||
float percentage = (float)s_scroll_items.items->items[element].successes / total;
|
||||
GColor color = get_color_float(percentage);
|
||||
fill_percentage_buffer(&s_scroll_items, element, total, percentage);
|
||||
text_layer_set_text_color(s_scroll_items.numbers[element], color);
|
||||
text_layer_set_text(s_scroll_items.numbers[element], s_scroll_items.numbers_buffer[element]);
|
||||
|
||||
// Update the percentage bar
|
||||
int width = (PERCENTAGE_BAR_WIDTH) * percentage;
|
||||
GRect bar = GRect(31, (element * ITEM_UI_HEIGHT) + 40, width, 4);
|
||||
GColor *color_ptr = layer_get_data(s_scroll_items.success_bars[element]);
|
||||
*color_ptr = color;
|
||||
layer_set_frame(s_scroll_items.success_bars[element], bar);
|
||||
}
|
||||
else if (event->type == TouchEvent_Liftoff) {
|
||||
// Reset the background
|
||||
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[element], s_background_bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------ INITS ------------
|
||||
void scrolllayer_init(Layer *parent, Window *window) {
|
||||
s_scroll_y = 0;
|
||||
s_scroll_page = 0;
|
||||
GRect bounds = SCROLLLAYER_FRAME_RECT;
|
||||
|
||||
// Load custom font
|
||||
s_scrolllayer_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_SLKSCR_16));
|
||||
|
||||
// Add touch areas
|
||||
item_1_plus_button = ITEM_1_PLUS_BUTTON_RECT;
|
||||
item_1_minus_button = ITEM_1_MINUS_BUTTON_RECT;
|
||||
item_2_plus_button = ITEM_2_PLUS_BUTTON_RECT;
|
||||
item_2_minus_button = ITEM_2_MINUS_BUTTON_RECT;
|
||||
item_3_plus_button = ITEM_3_PLUS_BUTTON_RECT;
|
||||
item_3_minus_button = ITEM_3_MINUS_BUTTON_RECT;
|
||||
|
||||
// Load bitmaps
|
||||
s_background_bitmap = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_ITEM_BACKGROUND);
|
||||
s_plus_bitmap = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_PLUS_BUTTON);
|
||||
s_minus_bitmap = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_MINUS_BUTTON);
|
||||
s_background_plus_pressed_bitmap = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_BACKGROUND_PLUS_PRESSED);
|
||||
s_background_minus_pressed_bitmap = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_BACKGROUND_MINUS_PRESSED);
|
||||
s_scroll_bar_full_bitmap = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_SCROLL_BAR_FULL);
|
||||
s_scroll_bar_half_bitmap = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_SCROLL_BAR_HALF);
|
||||
s_scroll_bar_third_bitmap = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_SCROLL_BAR_THIRD);
|
||||
|
||||
// Create ScrollLayer
|
||||
s_scroll_layer = scroll_layer_create(bounds);
|
||||
scroll_layer_set_content_size(
|
||||
s_scroll_layer,
|
||||
GSize(bounds.size.w, MAX_ITEMS * ITEM_UI_HEIGHT)
|
||||
);
|
||||
|
||||
// Remove shadow
|
||||
scroll_layer_set_shadow_hidden(s_scroll_layer, true);
|
||||
// Button scroll
|
||||
window_set_click_config_provider(window, click_config_provider);
|
||||
|
||||
// Get entries
|
||||
s_scroll_items.items = items_get();
|
||||
|
||||
// Add items
|
||||
scroll_layer_add_items();
|
||||
|
||||
// Add ScrollLayer
|
||||
layer_add_child(parent, scroll_layer_get_layer(s_scroll_layer));
|
||||
|
||||
// Add scroll bar
|
||||
GRect scroll_box = SCROLL_BAR_FRAME_RECT;
|
||||
if (s_scroll_items.page_count == 2) {
|
||||
scroll_box.size.h = 82;
|
||||
s_scroll_bar_layer = layer_create(scroll_box);
|
||||
s_scroll_bar_current_bitmap = s_scroll_bar_half_bitmap;
|
||||
|
||||
}
|
||||
else if (s_scroll_items.page_count == 3) {
|
||||
scroll_box.size.h = 52;
|
||||
s_scroll_bar_layer = layer_create(scroll_box);
|
||||
s_scroll_bar_current_bitmap = s_scroll_bar_third_bitmap;
|
||||
}
|
||||
else {
|
||||
scroll_box.size.h = 160;
|
||||
s_scroll_bar_layer = layer_create(scroll_box);
|
||||
s_scroll_bar_current_bitmap = s_scroll_bar_full_bitmap;
|
||||
}
|
||||
layer_set_update_proc(s_scroll_bar_layer, scroll_bar_draw);
|
||||
layer_add_child(parent, s_scroll_bar_layer);
|
||||
|
||||
// Register touch handler
|
||||
touch_service_subscribe(touch_handler, NULL);
|
||||
}
|
||||
|
||||
void scrolllayer_deinit() {
|
||||
// Unload font
|
||||
fonts_unload_custom_font(s_scrolllayer_font);
|
||||
|
||||
// Unsubscribe touch
|
||||
touch_service_unsubscribe();
|
||||
|
||||
// Destroy ScrollLayer
|
||||
scroll_layer_destroy(s_scroll_layer);
|
||||
|
||||
// Destroy bitmaps
|
||||
gbitmap_destroy(s_background_bitmap);
|
||||
gbitmap_destroy(s_plus_bitmap);
|
||||
gbitmap_destroy(s_minus_bitmap);
|
||||
gbitmap_destroy(s_background_plus_pressed_bitmap);
|
||||
gbitmap_destroy(s_background_minus_pressed_bitmap);
|
||||
gbitmap_destroy(s_scroll_bar_full_bitmap);
|
||||
gbitmap_destroy(s_scroll_bar_half_bitmap);
|
||||
gbitmap_destroy(s_scroll_bar_third_bitmap);
|
||||
|
||||
// Destroy scroll bar
|
||||
layer_destroy(s_scroll_bar_layer);
|
||||
|
||||
// Destroy items
|
||||
scroll_layer_remove_items();
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <pebble.h>
|
||||
|
||||
#include "src/c/items.h"
|
||||
|
||||
|
||||
// SCROLLLAYER POSITION
|
||||
#define SCROLLLAYER_FRAME_RECT GRect(5, 30, 174, 168)
|
||||
#define SCROLL_BAR_FRAME_RECT GRect(180, 34, 10, 160)
|
||||
#define SCROLL_BAR_ORIGIN_HEIGHT 34
|
||||
#define SCROLL_BAR_ORIGIN_HEIGHT_END 34 + 160
|
||||
#define PERCENTAGE_BAR_WIDTH 112
|
||||
|
||||
// TOUCH BUTTON RECTS
|
||||
#define ITEM_1_PLUS_BUTTON_RECT GRect(110, 32, 70, 56)
|
||||
#define ITEM_1_MINUS_BUTTON_RECT GRect(8, 32, 70, 56)
|
||||
#define ITEM_2_PLUS_BUTTON_RECT GRect(110, 88, 70, 56)
|
||||
#define ITEM_2_MINUS_BUTTON_RECT GRect(8, 88, 70, 56)
|
||||
#define ITEM_3_PLUS_BUTTON_RECT GRect(110, 144, 70, 56)
|
||||
#define ITEM_3_MINUS_BUTTON_RECT GRect(8, 144, 70, 56)
|
||||
|
||||
// UI
|
||||
#define MAX_UI_ITEMS 3
|
||||
#define MAX_UI_PAGES (MAX_ITEMS / MAX_UI_ITEMS)
|
||||
#define ITEM_UI_HEIGHT 56
|
||||
|
||||
// LIMITS
|
||||
#define RED_LIMIT 0.1
|
||||
#define ORANGE_LIMIT 0.4
|
||||
|
||||
typedef struct {
|
||||
item_list_t *items;
|
||||
int page_count;
|
||||
TextLayer *texts[MAX_ITEMS];
|
||||
TextLayer *numbers[MAX_ITEMS];
|
||||
char numbers_buffer[MAX_ITEMS][MAX_CHARACTERS];
|
||||
BitmapLayer *backgrounds[MAX_ITEMS];
|
||||
BitmapLayer *plus_buttons[MAX_ITEMS];
|
||||
BitmapLayer *minus_buttons[MAX_ITEMS];
|
||||
Layer *success_bars[MAX_ITEMS];
|
||||
} scroll_items_t;
|
||||
|
||||
void scroll_layer_add_items();
|
||||
void scroll_layer_remove_items();
|
||||
void scroll_layer_update_scrollbar();
|
||||
void scrolllayer_init(Layer *parent, Window *window);
|
||||
void scrolllayer_deinit();
|
||||
@@ -0,0 +1,58 @@
|
||||
#include "time.h"
|
||||
|
||||
#include "src/c/colors.h"
|
||||
|
||||
static TextLayer *s_time_layer;
|
||||
static GFont s_time_font;
|
||||
|
||||
|
||||
static void update_time() {
|
||||
// Get tm structure
|
||||
time_t temp = time(NULL);
|
||||
struct tm *tick_time = localtime(&temp);
|
||||
|
||||
// Write the current time
|
||||
static char s_time_buffer[8];
|
||||
strftime(s_time_buffer, sizeof(s_time_buffer),
|
||||
clock_is_24h_style() ? "%H:%M" : "%I:%M",
|
||||
tick_time);
|
||||
|
||||
// Display the time
|
||||
text_layer_set_text(s_time_layer, s_time_buffer);
|
||||
}
|
||||
|
||||
static void tick_handler(struct tm *tick_time, TimeUnits units_changed) {
|
||||
update_time();
|
||||
}
|
||||
|
||||
void time_init(Layer *parent) {
|
||||
// Load custom font
|
||||
s_time_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_SLKSCR_16));
|
||||
|
||||
// Create the time TextLayer
|
||||
s_time_layer = text_layer_create(TIME_RECT);
|
||||
text_layer_set_background_color(s_time_layer, GColorClear);
|
||||
text_layer_set_text_color(s_time_layer, WHITE);
|
||||
text_layer_set_font(s_time_layer, s_time_font);
|
||||
text_layer_set_text_alignment(s_time_layer, GTextAlignmentCenter);
|
||||
|
||||
// Add child
|
||||
layer_add_child(parent, text_layer_get_layer(s_time_layer));
|
||||
|
||||
// Display the time on start
|
||||
update_time();
|
||||
|
||||
// Register with TickTimerService
|
||||
tick_timer_service_subscribe(MINUTE_UNIT, tick_handler);
|
||||
}
|
||||
|
||||
void time_deinit() {
|
||||
// Destroy time layer
|
||||
text_layer_destroy(s_time_layer);
|
||||
|
||||
// Unload font
|
||||
fonts_unload_custom_font(s_time_font);
|
||||
|
||||
// Unsubscribe timer
|
||||
tick_timer_service_unsubscribe();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <pebble.h>
|
||||
|
||||
|
||||
// TIME POSITION
|
||||
#define TIME_RECT GRect(8, 6, 186, 20)
|
||||
|
||||
|
||||
void time_init(Layer *parent);
|
||||
void time_deinit();
|
||||
Reference in New Issue
Block a user