557 lines
16 KiB
C
557 lines
16 KiB
C
#include "pebble_os.h"
|
||
#include "pebble_app.h"
|
||
#include "pebble_fonts.h"
|
||
|
||
#define DEBUG 0
|
||
|
||
#define MY_UUID { 0x42, 0x35, 0x46, 0xE7, 0x54, 0x18, 0x4F, 0x47, 0x96, 0x63, 0xF0, 0xDB, 0x98, 0x7C, 0x04, 0x40 }
|
||
PBL_APP_INFO(MY_UUID,
|
||
"Filmplakat", "lastfuture",
|
||
2, 2, /* App version */
|
||
RESOURCE_ID_IMAGE_MENU_ICON,
|
||
#if DEBUG
|
||
APP_INFO_STANDARD_APP
|
||
#else
|
||
APP_INFO_WATCH_FACE
|
||
#endif
|
||
);
|
||
|
||
void itoa(int num, char* buffer) {
|
||
const char digits[11] = "0123456789";
|
||
if(num > 9) {
|
||
buffer[0] = digits[num / 10];
|
||
buffer[1] = digits[num % 10];
|
||
} else {
|
||
buffer[0] = digits[num % 10];
|
||
buffer[1] = '\0';
|
||
}
|
||
}
|
||
|
||
Window window;
|
||
TextLayer row_1, row_1b, row_2, row_3, row_3b, row_4, row_4b, row_5, row_5b;
|
||
PropertyAnimation anim_1, anim_1b, anim_2, anim_3, anim_3b, anim_4, anim_4b, anim_5, anim_5b;
|
||
static char row_1_buffer[20], row_3_buffer[20], row_4_buffer[20], row_5_buffer[20], row_1_oldbuf[20], row_3_oldbuf[20], row_4_oldbuf[20], row_5_oldbuf[20];
|
||
static int row_1_x, row_2_x, row_3_x, row_4_x, row_5_x, row_1_y, row_2_y, row_3_y, row_4_y, row_5_y, row_1_oldx, row_2_oldx, row_3_oldx, row_4_oldx, row_5_oldx, row_1_oldy, row_2_oldy, row_3_oldy, row_4_oldy, row_5_oldy;
|
||
static bool row_3_asc, row_4_asc, has_row_3, has_row_4, firstblood, tenplusone;
|
||
GFont fontHour, fontUhr, fontMinutes, fontDate;
|
||
|
||
PblTm t;
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////
|
||
|
||
#include "string.h"
|
||
static const char* MONTHS[] = {
|
||
"Januar",
|
||
"Februar",
|
||
"März",
|
||
"April",
|
||
"Mai",
|
||
"Juni",
|
||
"Juli",
|
||
"August",
|
||
"September",
|
||
"Oktober",
|
||
"November",
|
||
"Dezember",
|
||
};
|
||
static const char* WEEKDAYS[] = {
|
||
"So",
|
||
"Mo",
|
||
"Di",
|
||
"Mi",
|
||
"Do",
|
||
"Fr",
|
||
"Sa",
|
||
};
|
||
static const char* TEENS[] = {
|
||
"null",
|
||
"ein",
|
||
"zwei",
|
||
"drei",
|
||
"vier",
|
||
"fünf",
|
||
"sechs",
|
||
"sieben",
|
||
"acht",
|
||
"neun",
|
||
"zehn",
|
||
"elf",
|
||
"zwölf",
|
||
"dreizehn",
|
||
"vierzehn",
|
||
"fünfzehn",
|
||
"sechzehn",
|
||
"siebzehn",
|
||
"achtzehn",
|
||
"neunzehn",
|
||
};
|
||
static const char* TEENS_DOTLESS[] = {
|
||
"null",
|
||
"eın",
|
||
"zwei",
|
||
"drei",
|
||
"vıer",
|
||
"fünf",
|
||
"sechs",
|
||
"sıeben",
|
||
"acht",
|
||
"neun",
|
||
"zehn",
|
||
"elf",
|
||
"zwölf",
|
||
"dreizehn",
|
||
"vıerzehn",
|
||
"fünfzehn",
|
||
"sechzehn",
|
||
"sıebzehn",
|
||
"achtzehn",
|
||
"neunzehn",
|
||
};
|
||
static const char* TENS[] = {
|
||
"zwanzig",
|
||
"dreißig",
|
||
"vierzig",
|
||
"fünfzig",
|
||
"sechzig",
|
||
};
|
||
static const char* TENS_DOTLESS[] = {
|
||
"zwanzıg",
|
||
"dreißig",
|
||
"vıerzıg",
|
||
"fünfzig",
|
||
"sechzig",
|
||
};
|
||
static const bool TEENS_ASC[] = {
|
||
true,
|
||
false,
|
||
false,
|
||
true,
|
||
false,
|
||
true,
|
||
false,
|
||
false,
|
||
true,
|
||
false,
|
||
true,
|
||
true,
|
||
false,
|
||
true,
|
||
false,
|
||
true,
|
||
false,
|
||
false,
|
||
true,
|
||
false,
|
||
};
|
||
static const bool TENS_ASC[] = {
|
||
false,
|
||
true,
|
||
false,
|
||
true,
|
||
true,
|
||
};
|
||
|
||
static const char* STR_UND = "und";
|
||
static const char* STR_SPACE = " ";
|
||
static const char* STR_DOT = ".";
|
||
static const char* STR_S = "s";
|
||
|
||
static const char* ROW_2_BUFFER = "uhr";
|
||
|
||
static const int UHR_ASC = 28;
|
||
static const int MINUTES_ASC = 25;
|
||
static const int MINUTES2_ASC = 28;
|
||
static const int DATE_ASC = 36;
|
||
|
||
static const int MINUTES_X = 5;
|
||
static const int MINUTES2_X = 5;
|
||
|
||
void setup_text_layer(TextLayer* row, PropertyAnimation *this_anim, int x, int y, int oldx, int oldy, GFont font, int magic, bool delayed, bool black){
|
||
int rectheight = 50;
|
||
text_layer_set_text_color(row, GColorWhite);
|
||
if (black) {
|
||
text_layer_set_background_color(row, GColorBlack);
|
||
rectheight = 37;
|
||
} else {
|
||
text_layer_set_background_color(row, GColorClear);
|
||
}
|
||
layer_add_child(&window.layer, &row->layer);
|
||
text_layer_set_font(row,font);
|
||
|
||
int speed = 1000;
|
||
int distance = oldy - y;
|
||
|
||
if (distance < 0) { distance *= -1; }
|
||
|
||
if (firstblood) {
|
||
speed = 600;
|
||
} else if (x == -144) {
|
||
speed = 1400;
|
||
} else if (oldx == 144) {
|
||
speed = 1000;
|
||
} else {
|
||
speed = 500;
|
||
}
|
||
|
||
GRect start_rect = GRect(oldx,oldy,144-oldx-1,rectheight);
|
||
GRect target_rect = GRect(x,y,144-x-1,rectheight);
|
||
|
||
if (magic == 1) { // disappear
|
||
start_rect = GRect(oldx,oldy,144-oldx-1,rectheight);
|
||
target_rect = GRect(-114,oldy,144-oldx-1,rectheight);
|
||
} else if (magic == 2) { // reappear
|
||
start_rect = GRect(144,y,144-x-1,rectheight);
|
||
target_rect = GRect(x,y,144-x-1,rectheight);
|
||
} else if (magic == 3) { // and stay down
|
||
start_rect = GRect(0,0,0,0);
|
||
target_rect = GRect(0,0,0,0);
|
||
speed = 1;
|
||
} else {
|
||
}
|
||
|
||
if (magic != 3) {
|
||
layer_set_frame(&row->layer, start_rect);
|
||
property_animation_init_layer_frame(this_anim, &row->layer, NULL, &target_rect);
|
||
|
||
animation_set_duration(&this_anim->animation, speed);
|
||
animation_set_curve(&this_anim->animation, AnimationCurveEaseInOut);
|
||
if (delayed) {
|
||
animation_set_delay(&this_anim->animation, 100);
|
||
}
|
||
animation_schedule(&this_anim->animation);
|
||
}
|
||
}
|
||
|
||
void GetTime(int hours, int minutes, int day, int month, int weekday){
|
||
|
||
has_row_3 = false;
|
||
has_row_4 = false;
|
||
|
||
int hours12h = hours % 12;
|
||
if (hours == 12) { hours12h = 12; }
|
||
strcat(row_1_buffer, TEENS[hours12h]);
|
||
|
||
tenplusone = false;
|
||
|
||
if (minutes == 0) {
|
||
} else if (minutes < 20) {
|
||
row_3_asc = TEENS_ASC[minutes];
|
||
if (row_3_asc == false) {
|
||
strcat(row_3_buffer, TEENS_DOTLESS[minutes]);
|
||
} else {
|
||
strcat(row_3_buffer, TEENS[minutes]);
|
||
}
|
||
if (minutes == 1) {
|
||
strcat(row_3_buffer, STR_S);
|
||
}
|
||
has_row_3 = true;
|
||
} else {
|
||
int tenner = minutes/10;
|
||
int oner = minutes % 10;
|
||
if (oner == 0) {
|
||
row_3_asc = TENS_ASC[tenner-2];
|
||
if (row_3_asc == false && tenner!=2) {
|
||
strcat(row_3_buffer, TENS_DOTLESS[tenner-2]);
|
||
} else {
|
||
strcat(row_3_buffer, TENS[tenner-2]);
|
||
}
|
||
has_row_3 = true;
|
||
} else {
|
||
if (oner == 1) {
|
||
tenplusone = true;
|
||
}
|
||
row_3_asc = TEENS_ASC[oner];
|
||
if (row_3_asc == false) {
|
||
strcat(row_3_buffer, TEENS_DOTLESS[oner]);
|
||
} else {
|
||
strcat(row_3_buffer, TEENS[oner]);
|
||
}
|
||
strcat(row_3_buffer, STR_UND);
|
||
has_row_3 = true;
|
||
row_4_asc = TENS_ASC[tenner-2];
|
||
if (row_4_asc == false) {
|
||
strcat(row_4_buffer, TENS_DOTLESS[tenner-2]);
|
||
} else {
|
||
strcat(row_4_buffer, TENS[tenner-2]);
|
||
}
|
||
has_row_4 = true;
|
||
}
|
||
}
|
||
|
||
char daynum[] = "xx";
|
||
itoa(day,daynum);
|
||
strcat(row_5_buffer, WEEKDAYS[weekday]);
|
||
strcat(row_5_buffer, STR_SPACE);
|
||
strcat(row_5_buffer, daynum);
|
||
strcat(row_5_buffer, STR_DOT);
|
||
strcat(row_5_buffer, STR_SPACE);
|
||
strcat(row_5_buffer, MONTHS[month]);
|
||
}
|
||
|
||
void update_time(PblTm* t){
|
||
|
||
memset(row_1_oldbuf,0,20);
|
||
memset(row_3_oldbuf,0,20);
|
||
memset(row_4_oldbuf,0,20);
|
||
memset(row_5_oldbuf,0,20);
|
||
|
||
strcat(row_1_oldbuf,row_1_buffer);
|
||
strcat(row_3_oldbuf,row_3_buffer);
|
||
strcat(row_4_oldbuf,row_4_buffer);
|
||
strcat(row_5_oldbuf,row_5_buffer);
|
||
|
||
memset(row_1_buffer,0,20);
|
||
memset(row_3_buffer,0,20);
|
||
memset(row_4_buffer,0,20);
|
||
memset(row_5_buffer,0,20);
|
||
|
||
bool has_row_3_old = has_row_3;
|
||
bool has_row_4_old = has_row_4;
|
||
|
||
strcat(row_1_buffer, STR_SPACE); // workaround for weird "z" bug
|
||
|
||
GetTime(t->tm_hour,t->tm_min,t->tm_mday,t->tm_mon,t->tm_wday);
|
||
//GetTime(7,57,2,8,0); // longest strings?
|
||
//GetTime(t->tm_hour,t->tm_sec,t->tm_mday,t->tm_mon,t->tm_wday);
|
||
|
||
int spacing = 0;
|
||
|
||
row_1_oldx = row_1_x;
|
||
row_2_oldx = row_2_x;
|
||
row_3_oldx = row_3_x;
|
||
row_4_oldx = row_4_x;
|
||
row_5_oldx = row_5_x;
|
||
|
||
row_1_oldy = row_1_y;
|
||
row_2_oldy = row_2_y;
|
||
row_3_oldy = row_3_y;
|
||
row_4_oldy = row_4_y;
|
||
row_5_oldy = row_5_y;
|
||
|
||
row_1_x = row_2_x = row_3_x = row_4_x = row_5_x = 20;
|
||
|
||
row_1_y = spacing;
|
||
spacing += UHR_ASC;
|
||
row_2_y = spacing;
|
||
if (has_row_3) {
|
||
if (row_3_asc) { spacing += MINUTES_ASC; } else { spacing += MINUTES_ASC-MINUTES_X; }
|
||
}
|
||
row_3_y = spacing;
|
||
if (has_row_4) {
|
||
if (row_4_asc) { spacing += MINUTES2_ASC; } else { spacing += MINUTES2_ASC-MINUTES2_X; }
|
||
}
|
||
row_4_y = spacing;
|
||
spacing += DATE_ASC;
|
||
row_5_y = spacing;
|
||
|
||
row_1_x -= row_1_y/5;
|
||
row_2_x -= row_2_y/5;
|
||
row_3_x -= row_3_y/5;
|
||
row_4_x -= row_4_y/5;
|
||
row_5_x -= row_5_y/5;
|
||
row_1_x -= 7;
|
||
row_5_x += 4;
|
||
|
||
spacing += 22;
|
||
|
||
int y_offset = (168-spacing)/2;
|
||
|
||
row_1_y += y_offset;
|
||
row_2_y += y_offset;
|
||
row_3_y += y_offset;
|
||
row_4_y += y_offset;
|
||
row_5_y += y_offset;
|
||
|
||
if (firstblood) {
|
||
has_row_3_old = has_row_3;
|
||
has_row_4_old = has_row_4;
|
||
memset(row_3_oldbuf,0,20);
|
||
memset(row_4_oldbuf,0,20);
|
||
strcat(row_3_oldbuf,row_3_buffer);
|
||
strcat(row_4_oldbuf,row_4_buffer);
|
||
|
||
int sidestoggle = -144;
|
||
|
||
row_1_oldx = sidestoggle;
|
||
sidestoggle *= -1;
|
||
row_2_oldx = sidestoggle;
|
||
if (has_row_3) { sidestoggle *= -1; };
|
||
row_3_oldx = sidestoggle;
|
||
if (has_row_4) { sidestoggle *= -1; };
|
||
row_4_oldx = sidestoggle;
|
||
sidestoggle *= -1;
|
||
row_5_oldx = sidestoggle;
|
||
|
||
row_1_oldy = row_1_y;
|
||
row_2_oldy = row_2_y;
|
||
row_3_oldy = row_3_y;
|
||
row_4_oldy = row_4_y;
|
||
row_5_oldy = row_5_y;
|
||
|
||
tenplusone = false;
|
||
}
|
||
|
||
|
||
int magic = 0;
|
||
bool haschanged = false;
|
||
|
||
setup_text_layer(&row_2,&anim_2,row_2_x,row_2_y,row_2_oldx,row_2_oldy,fontUhr,0,false,false);
|
||
text_layer_set_text(&row_2,ROW_2_BUFFER);
|
||
|
||
if (strcmp(row_1_oldbuf,row_1_buffer)) { haschanged = true; } else { haschanged = false; }
|
||
|
||
if (haschanged && firstblood != true) {
|
||
setup_text_layer(&row_1,&anim_1,-144,row_1_oldy,row_1_oldx,row_1_oldy,fontHour,0,false,true);
|
||
text_layer_set_text(&row_1,row_1_oldbuf);
|
||
setup_text_layer(&row_1b,&anim_1b,row_1_x,row_1_y,144,row_1_y,fontHour,magic,true,true);
|
||
text_layer_set_text(&row_1b,row_1_buffer);
|
||
} else {
|
||
setup_text_layer(&row_1,&anim_1,row_1_x,row_1_y,row_1_oldx,row_1_oldy,fontHour,0,true,true);
|
||
text_layer_set_text(&row_1,row_1_buffer);
|
||
text_layer_set_text(&row_1b,STR_SPACE);
|
||
}
|
||
|
||
if (strcmp(row_3_oldbuf,row_3_buffer)) { haschanged = true; } else { haschanged = false; }
|
||
|
||
if (has_row_3 == has_row_3_old && has_row_3 == true) {
|
||
magic = 0;
|
||
} else if (has_row_3 == has_row_3_old && has_row_3 == false) {
|
||
magic = 3; // stay down
|
||
} else if (has_row_3 != has_row_3_old && has_row_3 == false) {
|
||
magic = 1; // disappear
|
||
} else if (has_row_3 != has_row_3_old && has_row_3 == true) {
|
||
magic = 2; // reappear
|
||
}
|
||
if (magic == 0) {
|
||
if (haschanged) {
|
||
if (tenplusone) {
|
||
setup_text_layer(&row_3,&anim_3,row_3_x,row_3_y,144,row_3_y,fontMinutes,magic,true,false);
|
||
text_layer_set_text(&row_3,row_3_buffer);
|
||
text_layer_set_text(&row_3b,STR_SPACE);
|
||
} else {
|
||
setup_text_layer(&row_3,&anim_3,-144,row_3_oldy,row_3_oldx,row_3_oldy,fontMinutes,magic,false,false);
|
||
text_layer_set_text(&row_3,row_3_oldbuf);
|
||
setup_text_layer(&row_3b,&anim_3b,row_3_x,row_3_y,144,row_3_y,fontMinutes,magic,true,false);
|
||
text_layer_set_text(&row_3b,row_3_buffer);
|
||
}
|
||
} else {
|
||
setup_text_layer(&row_3,&anim_3,row_3_x,row_3_y,row_3_oldx,row_3_oldy,fontMinutes,magic,false,false);
|
||
text_layer_set_text(&row_3,row_3_buffer);
|
||
text_layer_set_text(&row_3b,STR_SPACE);
|
||
}
|
||
} else {
|
||
setup_text_layer(&row_3,&anim_3,row_3_x,row_3_y,row_3_oldx,row_3_oldy,fontMinutes,magic,false,false);
|
||
if (magic == 1) {
|
||
text_layer_set_text(&row_3,row_3_oldbuf);
|
||
} else {
|
||
text_layer_set_text(&row_3,row_3_buffer);
|
||
}
|
||
text_layer_set_text(&row_3b,STR_SPACE);
|
||
}
|
||
|
||
if (strcmp(row_4_oldbuf,row_4_buffer)) { haschanged = true; } else { haschanged = false; }
|
||
|
||
if (has_row_4 == has_row_4_old && has_row_4 == true) {
|
||
magic = 0;
|
||
} else if (has_row_4 == has_row_4_old && has_row_4 == false) {
|
||
magic = 3; // stay down
|
||
} else if (has_row_4 != has_row_4_old && has_row_4 == false) {
|
||
magic = 1; // disappear
|
||
} else if (has_row_4 != has_row_4_old && has_row_4 == true) {
|
||
magic = 2; // reappear
|
||
}
|
||
if (tenplusone) {
|
||
setup_text_layer(&row_4,&anim_4,row_4_x,row_4_y,row_3_oldx,row_3_oldy,fontMinutes,0,false,false);
|
||
text_layer_set_text(&row_4,row_4_buffer);
|
||
text_layer_set_text(&row_4b,STR_SPACE);
|
||
} else if (magic == 0) {
|
||
if (haschanged) {
|
||
setup_text_layer(&row_4,&anim_4,-144,row_4_oldy,row_4_oldx,row_4_oldy,fontMinutes,magic,false,false);
|
||
text_layer_set_text(&row_4,row_4_oldbuf);
|
||
setup_text_layer(&row_4b,&anim_4b,row_4_x,row_4_y,144,row_4_y,fontMinutes,magic,true,false);
|
||
text_layer_set_text(&row_4b,row_4_buffer);
|
||
} else {
|
||
setup_text_layer(&row_4,&anim_4,row_4_x,row_4_y,row_4_oldx,row_4_oldy,fontMinutes,magic,false,false);
|
||
text_layer_set_text(&row_4,row_4_buffer);
|
||
text_layer_set_text(&row_4b,STR_SPACE);
|
||
}
|
||
} else {
|
||
setup_text_layer(&row_4,&anim_4,row_4_x,row_4_y,row_4_oldx,row_4_oldy,fontMinutes,magic,false,false);
|
||
if (magic == 1) {
|
||
text_layer_set_text(&row_4,row_4_oldbuf);
|
||
} else {
|
||
text_layer_set_text(&row_4,row_4_buffer);
|
||
}
|
||
text_layer_set_text(&row_4b,STR_SPACE);
|
||
}
|
||
|
||
if (strcmp(row_5_oldbuf,row_5_buffer)) { haschanged = true; } else { haschanged = false; }
|
||
|
||
if (haschanged && firstblood != true) {
|
||
setup_text_layer(&row_5,&anim_5,-144,row_5_oldy,row_5_oldx,row_5_oldy,fontDate,0,false,false);
|
||
text_layer_set_text(&row_5,row_5_oldbuf);
|
||
setup_text_layer(&row_5b,&anim_5b,row_5_x,row_5_y,144,row_5_y,fontDate,magic,true,false);
|
||
text_layer_set_text(&row_5b,row_5_buffer);
|
||
} else {
|
||
setup_text_layer(&row_5,&anim_5,row_5_x,row_5_y,row_5_oldx,row_5_oldy,fontDate,0,true,false);
|
||
text_layer_set_text(&row_5,row_5_buffer);
|
||
text_layer_set_text(&row_5b,STR_SPACE);
|
||
}
|
||
|
||
if (firstblood) {
|
||
firstblood = false;
|
||
}
|
||
}
|
||
|
||
|
||
static void handle_minute_tick(AppContextRef app_ctx, PebbleTickEvent* e) {
|
||
update_time(e->tick_time);
|
||
}
|
||
|
||
void handle_init(AppContextRef ctx) {
|
||
(void)ctx;
|
||
|
||
firstblood = true;
|
||
|
||
window_init(&window, "Clock_Window");
|
||
window_stack_push(&window, true /* Animated */);
|
||
window_set_background_color(&window, GColorBlack);
|
||
resource_init_current_app(&APP_RESOURCES);
|
||
|
||
fontHour = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_ROBOTO_BOLDITALIC_35));
|
||
fontUhr = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_ROBOTO_LIGHTITALIC_30));
|
||
fontMinutes = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_ROBOTO_ITALIC_33));
|
||
fontDate = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_ROBOTO_ITALIC_13));
|
||
|
||
memset(row_1_buffer,0,20);
|
||
memset(row_3_buffer,0,20);
|
||
memset(row_4_buffer,0,20);
|
||
memset(row_5_buffer,0,20);
|
||
|
||
text_layer_init(&row_2, window.layer.frame);
|
||
text_layer_init(&row_3, window.layer.frame);
|
||
text_layer_init(&row_4, window.layer.frame);
|
||
text_layer_init(&row_5, window.layer.frame);
|
||
text_layer_init(&row_3b, window.layer.frame);
|
||
text_layer_init(&row_4b, window.layer.frame);
|
||
text_layer_init(&row_5b, window.layer.frame);
|
||
|
||
text_layer_init(&row_1, window.layer.frame);
|
||
text_layer_init(&row_1b, window.layer.frame);
|
||
|
||
get_time(&t);
|
||
}
|
||
|
||
|
||
void pbl_main(void *params) {
|
||
PebbleAppHandlers handlers = {
|
||
.init_handler = &handle_init,
|
||
.tick_info = {
|
||
.tick_handler = &handle_minute_tick,
|
||
.tick_units = MINUTE_UNIT
|
||
}
|
||
};
|
||
app_event_loop(params, &handlers);
|
||
}
|