diff --git a/src/LBackend.c b/src/LBackend.c index d18daf6c0..cac3cf69e 100644 --- a/src/LBackend.c +++ b/src/LBackend.c @@ -102,6 +102,36 @@ void LBackend_DrawTitle(struct Context2D* ctx, const char* title) { Launcher_DrawTitle(&logoFont, title, ctx); } +/* Scales up flag bitmap if necessary */ +static void LBackend_ScaleFlag(struct Bitmap* bmp) { + struct Bitmap scaled; + int width = Display_ScaleX(bmp->width); + int height = Display_ScaleY(bmp->height); + /* at default DPI don't need to rescale it */ + if (width == bmp->width && height == bmp->height) return; + + Bitmap_TryAllocate(&scaled, width, height); + if (!scaled.scan0) { + Logger_SysWarn(ERR_OUT_OF_MEMORY, "resizing flags bitmap"); return; + } + + Bitmap_Scale(&scaled, bmp, 0, 0, bmp->width, bmp->height); + Mem_Free(bmp->scan0); + *bmp = scaled; +} + +void LBackend_DecodeFlag(struct Flag* flag, cc_uint8* data, cc_uint32 len) { + struct Stream s; + cc_result res; + + Stream_ReadonlyMemory(&s, data, len); + res = Png_Decode(&flag->bmp, &s); + if (res) Logger_SysWarn(res, "decoding flag"); + flag->meta = NULL; + + LBackend_ScaleFlag(&flag->bmp); +} + static void OnPointerMove(void* obj, int idx); void LBackend_SetScreen(struct LScreen* s) { int i; diff --git a/src/LBackend.h b/src/LBackend.h index 3162b9d96..2ebb8ab82 100644 --- a/src/LBackend.h +++ b/src/LBackend.h @@ -15,6 +15,7 @@ struct LLabel; struct LLine; struct LSlider; struct LTable; +struct Flag; void LBackend_Init(void); void LBackend_Free(void); @@ -24,6 +25,8 @@ void LBackend_CloseScreen(struct LScreen* s); void LBackend_UpdateTitleFont(void); void LBackend_DrawTitle(struct Context2D* ctx, const char* title); +void LBackend_DecodeFlag(struct Flag* flag, cc_uint8* data, cc_uint32 len); + /* Resets pixels to default, then draws widgets of current screen over it */ void LBackend_Redraw(void); void LBackend_ThemeChanged(void); @@ -65,7 +68,6 @@ void LBackend_TableInit(struct LTable* w); void LBackend_TableUpdate(struct LTable* w); /* Adjusts Y position of rows and number of visible rows */ void LBackend_TableReposition(struct LTable* w); -void LBackend_TableFlagAdded(struct LTable* w); void LBackend_TableDraw(struct LTable* w); void LBackend_TableMouseDown(struct LTable* w, int idx); diff --git a/src/LScreens.c b/src/LScreens.c index f8ce21d57..676ccb8ac 100644 --- a/src/LScreens.c +++ b/src/LScreens.c @@ -1367,12 +1367,8 @@ static void ServersScreen_Activated(struct LScreen* s_) { static void ServersScreen_Tick(struct LScreen* s_) { struct ServersScreen* s = (struct ServersScreen*)s_; - int count; LScreen_Tick(s_); - - count = FetchFlagsTask.count; LWebTask_Tick(&FetchFlagsTask.Base, NULL); - if (count != FetchFlagsTask.count) LBackend_TableFlagAdded(&s->table); if (!FetchServersTask.Base.working) return; LWebTask_Tick(&FetchServersTask.Base, NULL); diff --git a/src/LWeb.c b/src/LWeb.c index d623abe13..95bd05d4c 100644 --- a/src/LWeb.c +++ b/src/LWeb.c @@ -11,6 +11,7 @@ #include "Errors.h" #include "Utils.h" #include "Http.h" +#include "LBackend.h" /*########################################################################################################################* *----------------------------------------------------------JSON-----------------------------------------------------------* @@ -580,39 +581,13 @@ void FetchUpdateTask_Run(cc_bool release, int buildIndex) { *#########################################################################################################################*/ struct FetchFlagsData FetchFlagsTask; static int flagsCount, flagsCapacity; - static struct Flag* flags; -/* Scales up flag bitmap if necessary */ -static void FetchFlagsTask_Scale(struct Bitmap* bmp) { - struct Bitmap scaled; - int width = Display_ScaleX(bmp->width); - int height = Display_ScaleY(bmp->height); - /* at default DPI don't need to rescale it */ - if (width == bmp->width && height == bmp->height) return; - - Bitmap_TryAllocate(&scaled, width, height); - if (!scaled.scan0) { - Logger_SysWarn(ERR_OUT_OF_MEMORY, "resizing flags bitmap"); return; - } - - Bitmap_Scale(&scaled, bmp, 0, 0, bmp->width, bmp->height); - Mem_Free(bmp->scan0); - *bmp = scaled; -} - static void FetchFlagsTask_DownloadNext(void); static void FetchFlagsTask_Handle(cc_uint8* data, cc_uint32 len) { struct Flag* flag = &flags[FetchFlagsTask.count]; - struct Stream s; - cc_result res; - - Stream_ReadonlyMemory(&s, data, len); - res = Png_Decode(&flag->bmp, &s); - if (res) Logger_SysWarn(res, "decoding flag"); - flag->meta = NULL; - - FetchFlagsTask_Scale(&flag->bmp); + LBackend_DecodeFlag(flag, data, len); + FetchFlagsTask.count++; FetchFlagsTask_DownloadNext(); } @@ -645,7 +620,8 @@ static void FetchFlagsTask_Ensure(void) { void FetchFlagsTask_Add(const struct ServerInfo* server) { int i; - for (i = 0; i < flagsCount; i++) { + for (i = 0; i < flagsCount; i++) + { if (flags[i].country[0] != server->country[0]) continue; if (flags[i].country[1] != server->country[1]) continue; /* flag is already or will be downloaded */ @@ -656,6 +632,7 @@ void FetchFlagsTask_Add(const struct ServerInfo* server) { Bitmap_Init(flags[flagsCount].bmp, 0, 0, NULL); flags[flagsCount].country[0] = server->country[0]; flags[flagsCount].country[1] = server->country[1]; + flags[flagsCount].meta = NULL; flagsCount++; FetchFlagsTask_DownloadNext(); @@ -663,7 +640,8 @@ void FetchFlagsTask_Add(const struct ServerInfo* server) { struct Flag* Flags_Get(const struct ServerInfo* server) { int i; - for (i = 0; i < FetchFlagsTask.count; i++) { + for (i = 0; i < FetchFlagsTask.count; i++) + { if (flags[i].country[0] != server->country[0]) continue; if (flags[i].country[1] != server->country[1]) continue; return &flags[i]; diff --git a/src/interop_ios.m b/src/interop_ios.m index 7826d7ba8..25c95d718 100644 --- a/src/interop_ios.m +++ b/src/interop_ios.m @@ -1678,17 +1678,6 @@ void LBackend_TableUpdate(struct LTable* w) { [tbl reloadData]; } -// TODO only redraw flags -void LBackend_TableFlagAdded(struct LTable* w) { - UITableView* tbl = (__bridge UITableView*)w->meta; - - // trying to update cell.imageView.image doesn't seem to work, - // so pointlessly reload entire table data instead - NSIndexPath* selected = [tbl indexPathForSelectedRow]; - [tbl reloadData]; - [tbl selectRowAtIndexPath:selected animated:NO scrollPosition:UITableViewScrollPositionNone]; -} - void LBackend_TableDraw(struct LTable* w) { } void LBackend_TableReposition(struct LTable* w) { } void LBackend_TableMouseDown(struct LTable* w, int idx) { } @@ -1716,10 +1705,6 @@ static void LTable_UpdateCell(UITableView* table, UITableViewCell* cell, int row LTable_FormatUptime(&desc, server->uptime); if (server->software.length) String_Format1(&desc, " | %s", &server->software); - if (flag && !flag->meta && flag->bmp.scan0) { - UIImage* img = ToUIImage(&flag->bmp); - flag->meta = CFBridgingRetain(img); - } if (flag && flag->meta) cell.imageView.image = (__bridge UIImage*)flag->meta; @@ -1734,9 +1719,33 @@ static void LTable_UpdateCell(UITableView* table, UITableViewCell* cell, int row LTable_UpdateCellColor(cell, server, row, selected); } +// TODO only redraw flags +static void OnFlagsChanged(void) { + struct LScreen* s = Launcher_Active; + for (int i = 0; i < s->numWidgets; i++) + { + if (s->widgets[i]->type != LWIDGET_TABLE) continue; + UITableView* tbl = (__bridge UITableView*)s->widgets[i]->meta; + + // trying to update cell.imageView.image doesn't seem to work, + // so pointlessly reload entire table data instead + NSIndexPath* selected = [tbl indexPathForSelectedRow]; + [tbl reloadData]; + [tbl selectRowAtIndexPath:selected animated:NO scrollPosition:UITableViewScrollPositionNone]; + } +} + /*########################################################################################################################* *------------------------------------------------------UI Backend--------------------------------------------------------* *#########################################################################################################################*/ +void LBackend_DecodeFlag(struct Flag* flag, cc_uint8* data, cc_uint32 len) { + NSData* ns_data = [NSData dataWithBytes:data length:len]; + UIImage* img = [UIImage imageWithData:ns_data]; + if (!img) return; + + flag->meta = CFBridgingRetain(img); + OnFlagsChanged(); +} static void LBackend_LayoutDimensions(struct LWidget* w, CGRect* r) { const struct LLayout* l = w->layouts + 2;