From 3f563905393e04aee15a9ba984f9a192ee90af17 Mon Sep 17 00:00:00 2001 From: Steveice10 Date: Mon, 19 Dec 2016 18:18:25 -0800 Subject: [PATCH] Optimize list UI. --- source/core/screen.c | 4 + source/core/screen.h | 1 + source/ui/list.c | 147 +++++++++++--------------------- source/ui/section/extsavedata.c | 2 +- source/ui/section/qrinstall.c | 4 +- source/ui/section/titles.c | 2 +- 6 files changed, 57 insertions(+), 103 deletions(-) diff --git a/source/core/screen.c b/source/core/screen.c index 445aa62..e2d20fd 100644 --- a/source/core/screen.c +++ b/source/core/screen.c @@ -592,6 +592,10 @@ void screen_draw_texture_crop(u32 id, float x, float y, float width, float heigh screen_draw_quad(x, y, x + width, y + height, 0, 0, width / (float) textures[id].pow2Width, height / (float) textures[id].pow2Height); } +float screen_get_font_height(float scaleY) { + return scaleY * fontGetInfo()->lineFeed; +} + static void screen_get_string_size_internal(float* width, float* height, const char* text, float scaleX, float scaleY, bool oneLine, bool wrap, float wrapX) { float w = 0; float h = 0; diff --git a/source/core/screen.h b/source/core/screen.h index 0ea9ff6..2293f15 100644 --- a/source/core/screen.h +++ b/source/core/screen.h @@ -72,6 +72,7 @@ void screen_select(gfxScreen_t screen); void screen_set_scissor(bool enabled, u32 x, u32 y, u32 width, u32 height); void screen_draw_texture(u32 id, float x, float y, float width, float height); void screen_draw_texture_crop(u32 id, float x, float y, float width, float height); +float screen_get_font_height(float scaleY); void screen_get_string_size(float* width, float* height, const char* text, float scaleX, float scaleY); void screen_get_string_size_wrap(float* width, float* height, const char* text, float scaleX, float scaleY, float wrapX); void screen_draw_string(const char* text, float x, float y, float scaleX, float scaleY, u32 colorId, bool centerLines); diff --git a/source/ui/list.c b/source/ui/list.c index 975b0c2..06085b7 100644 --- a/source/ui/list.c +++ b/source/ui/list.c @@ -22,56 +22,7 @@ typedef struct { void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2, list_item* selected); } list_data; -static float list_get_item_screen_y(list_data* listData, list_item* item) { - if(item == NULL) { - return 0; - } - - float y = -listData->scrollPos; - - linked_list_iter iter; - linked_list_iterate(&listData->items, &iter); - - while(linked_list_iter_has_next(&iter)) { - list_item* currItem = (list_item*) linked_list_iter_next(&iter); - if(currItem == item) { - break; - } - - float stringHeight; - screen_get_string_size(NULL, &stringHeight, currItem->name, 0.5f, 0.5f); - y += stringHeight; - } - - return y; -} - -static int list_get_item_index_at(list_data* listData, float screenY) { - float y = -listData->scrollPos; - - linked_list_iter iter; - linked_list_iterate(&listData->items, &iter); - - int i = 0; - while(linked_list_iter_has_next(&iter)) { - list_item* item = (list_item*) linked_list_iter_next(&iter); - - float stringHeight; - screen_get_string_size(NULL, &stringHeight, item->name, 0.5f, 0.5f); - - if(screenY >= y && screenY < y + stringHeight) { - return i; - } - - y += stringHeight; - - i++; - } - - return -1; -} - -static void list_validate_pos(list_data* listData, float by1, float by2) { +static void list_validate(list_data* listData, float by1, float by2) { u32 size = linked_list_size(&listData->items); if(size == 0 || listData->selectedIndex < 0) { @@ -87,39 +38,45 @@ static void list_validate_pos(list_data* listData, float by1, float by2) { listData->scrollPos = 0; } + float viewSize = by2 - by1; + float fontHeight = screen_get_font_height(0.5f); + bool found = false; if(listData->selectedItem != NULL) { + u32 oldIndex = listData->selectedIndex; + int index = linked_list_index_of(&listData->items, listData->selectedItem); if(index != -1) { found = true; listData->selectedIndex = (u32) index; + + if(listData->selectedIndex != oldIndex) { + listData->scrollPos += (listData->selectedIndex * fontHeight) - (oldIndex * fontHeight); + } } } if(!found) { listData->selectedItem = linked_list_get(&listData->items, listData->selectedIndex); + + listData->selectionScroll = 0; + listData->nextSelectionScrollResetTime = 0; } - float itemHeight; - screen_get_string_size(NULL, &itemHeight, listData->selectedItem->name, 0.5f, 0.5f); + float itemY = listData->selectedIndex * fontHeight; - float itemY = list_get_item_screen_y(listData, listData->selectedItem); - if(itemY + itemHeight > by2 - by1) { - listData->scrollPos -= (by2 - by1) - itemY - itemHeight; + float minItemScrollPos = itemY - (viewSize - fontHeight); + if(listData->scrollPos < minItemScrollPos) { + listData->scrollPos = minItemScrollPos; } - if(itemY < 0) { - listData->scrollPos += itemY; + if(listData->scrollPos > itemY) { + listData->scrollPos = itemY; } - list_item* lastItem = (list_item*) linked_list_get(&listData->items, size - 1); - - float lastItemHeight; - screen_get_string_size(NULL, &lastItemHeight, lastItem->name, 0.5f, 0.5f); - - float lastPageEnd = list_get_item_screen_y(listData, lastItem); - if(lastPageEnd < by2 - by1 - lastItemHeight) { - listData->scrollPos -= (by2 - by1 - lastItemHeight) - lastPageEnd; + float maxScrollPos = (size * fontHeight) - viewSize; + if(listData->scrollPos > maxScrollPos) { + listData->scrollPos = maxScrollPos; } if(listData->scrollPos < 0) { @@ -135,7 +92,7 @@ static void list_update(ui_view* view, void* data, float bx1, float by1, float b bool selectedTouched = false; if(size > 0) { - list_validate_pos(listData, by1, by2); + list_validate(listData, by1, by2); float itemWidth; screen_get_string_size(&itemWidth, NULL, listData->selectedItem->name, 0.5f, 0.5f); @@ -157,7 +114,7 @@ static void list_update(ui_view* view, void* data, float bx1, float by1, float b u32 lastSelectedIndex = listData->selectedIndex; - if(((hidKeysDown() & KEY_DOWN) || ((hidKeysHeld() & KEY_DOWN) && osGetTime() >= listData->nextActionTime))) { + if((hidKeysDown() & KEY_DOWN) || ((hidKeysHeld() & KEY_DOWN) && osGetTime() >= listData->nextActionTime)) { if(listData->selectedIndex < size - 1) { listData->selectedIndex++; } else { @@ -167,7 +124,7 @@ static void list_update(ui_view* view, void* data, float bx1, float by1, float b listData->nextActionTime = osGetTime() + ((hidKeysDown() & KEY_DOWN) ? 500 : 100); } - if(((hidKeysDown() & KEY_UP) || ((hidKeysHeld() & KEY_UP) && osGetTime() >= listData->nextActionTime))) { + if((hidKeysDown() & KEY_UP) || ((hidKeysHeld() & KEY_UP) && osGetTime() >= listData->nextActionTime)) { if(listData->selectedIndex > 0) { listData->selectedIndex--; } else { @@ -177,7 +134,7 @@ static void list_update(ui_view* view, void* data, float bx1, float by1, float b listData->nextActionTime = osGetTime() + ((hidKeysDown() & KEY_UP) ? 500 : 100); } - if(((hidKeysDown() & KEY_RIGHT) || ((hidKeysHeld() & KEY_RIGHT) && osGetTime() >= listData->nextActionTime))) { + if((hidKeysDown() & KEY_RIGHT) || ((hidKeysHeld() & KEY_RIGHT) && osGetTime() >= listData->nextActionTime)) { if(listData->selectedIndex < size - 1) { u32 remaining = size - 1 - listData->selectedIndex; listData->selectedIndex += remaining < 13 ? remaining : 13; @@ -188,7 +145,7 @@ static void list_update(ui_view* view, void* data, float bx1, float by1, float b listData->nextActionTime = osGetTime() + ((hidKeysDown() & KEY_RIGHT) ? 500 : 100); } - if(((hidKeysDown() & KEY_LEFT) || ((hidKeysHeld() & KEY_LEFT) && osGetTime() >= listData->nextActionTime))) { + if((hidKeysDown() & KEY_LEFT) || ((hidKeysHeld() & KEY_LEFT) && osGetTime() >= listData->nextActionTime)) { if(listData->selectedIndex > 0) { u32 remaining = listData->selectedIndex; listData->selectedIndex -= remaining < 13 ? remaining : 13; @@ -199,25 +156,23 @@ static void list_update(ui_view* view, void* data, float bx1, float by1, float b listData->nextActionTime = osGetTime() + ((hidKeysDown() & KEY_LEFT) ? 500 : 100); } - if(hidKeysDown() & KEY_TOUCH) { + if((hidKeysDown() | hidKeysHeld()) & KEY_TOUCH) { touchPosition pos; hidTouchRead(&pos); - listData->lastScrollTouchY = pos.py; - - int index = list_get_item_index_at(listData, pos.py - by1); - if(index >= 0) { - if(listData->selectedIndex == index) { - selectedTouched = true; - } else { - listData->selectedIndex = (u32) index; + if(hidKeysDown() & KEY_TOUCH) { + u32 index = (u32) ((listData->scrollPos + (pos.py - by1)) / screen_get_font_height(0.5f)); + if(index >= 0) { + if(listData->selectedIndex == index) { + selectedTouched = true; + } else { + listData->selectedIndex = (u32) index; + } } + } else if(hidKeysHeld() & KEY_TOUCH) { + listData->scrollPos += -((int) pos.py - (int) listData->lastScrollTouchY); } - } else if(hidKeysHeld() & KEY_TOUCH) { - touchPosition pos; - hidTouchRead(&pos); - listData->scrollPos += -((int) pos.py - (int) listData->lastScrollTouchY); listData->lastScrollTouchY = pos.py; } @@ -228,13 +183,13 @@ static void list_update(ui_view* view, void* data, float bx1, float by1, float b listData->nextSelectionScrollResetTime = 0; } - list_validate_pos(listData, by1, by2); + list_validate(listData, by1, by2); } if(listData->update != NULL) { listData->update(view, listData->data, &listData->items, listData->selectedItem, selectedTouched); - list_validate_pos(listData, by1, by2); + list_validate(listData, by1, by2); } } @@ -242,6 +197,8 @@ static void list_draw_top(ui_view* view, void* data, float x1, float y1, float x list_data* listData = (list_data*) data; if(listData->drawTop != NULL) { + list_validate(listData, y1, y2); + listData->drawTop(view, listData->data, x1, y1, x2, y2, listData->selectedItem); } } @@ -249,8 +206,9 @@ static void list_draw_top(ui_view* view, void* data, float x1, float y1, float x static void list_draw_bottom(ui_view* view, void* data, float x1, float y1, float x2, float y2) { list_data* listData = (list_data*) data; - list_validate_pos(listData, y1, y2); + list_validate(listData, y1, y2); + float fontHeight = screen_get_font_height(0.5f); float y = y1 - listData->scrollPos; linked_list_iter iter; @@ -263,10 +221,7 @@ static void list_draw_bottom(ui_view* view, void* data, float x1, float y1, floa list_item* item = linked_list_iter_next(&iter); - float stringHeight; - screen_get_string_size(NULL, &stringHeight, item->name, 0.5f, 0.5f); - - if(y > y1 - stringHeight) { + if(y > y1 - fontHeight) { float x = x1 + 2; if(item == listData->selectedItem) { x -= listData->selectionScroll; @@ -278,22 +233,16 @@ static void list_draw_bottom(ui_view* view, void* data, float x1, float y1, floa u32 selectionOverlayWidth = 0; u32 selectionOverlayHeight = 0; screen_get_texture_size(&selectionOverlayWidth, &selectionOverlayHeight, TEXTURE_SELECTION_OVERLAY); - screen_draw_texture(TEXTURE_SELECTION_OVERLAY, (x1 + x2 - selectionOverlayWidth) / 2, y, selectionOverlayWidth, stringHeight); + screen_draw_texture(TEXTURE_SELECTION_OVERLAY, (x1 + x2 - selectionOverlayWidth) / 2, y, selectionOverlayWidth, fontHeight); } } - y += stringHeight; + y += fontHeight; } u32 size = linked_list_size(&listData->items); if(size > 0) { - list_item* lastItem = (list_item*) linked_list_get(&listData->items, size - 1); - - float lastItemHeight; - screen_get_string_size(NULL, &lastItemHeight, lastItem->name, 0.5f, 0.5f); - - float totalHeight = list_get_item_screen_y(listData, lastItem) + listData->scrollPos + lastItemHeight; - + float totalHeight = size * fontHeight; float viewHeight = y2 - y1; if(totalHeight > viewHeight) { diff --git a/source/ui/section/extsavedata.c b/source/ui/section/extsavedata.c index 104e00a..4141501 100644 --- a/source/ui/section/extsavedata.c +++ b/source/ui/section/extsavedata.c @@ -252,7 +252,7 @@ void extsavedata_open() { data->showSD = true; data->showNAND = true; - data->sortByName = true; + data->sortByName = false; list_display("Ext Save Data", "A: Select, B: Return, X: Refresh, Select: Options", data, extsavedata_update, extsavedata_draw_top); } \ No newline at end of file diff --git a/source/ui/section/qrinstall.c b/source/ui/section/qrinstall.c index a385b02..54f2b3f 100644 --- a/source/ui/section/qrinstall.c +++ b/source/ui/section/qrinstall.c @@ -154,7 +154,7 @@ static void qrinstall_wait_update(ui_view* view, void* data, float* progress, ch return; } - if(hidKeysDown() & KEY_A) { + if(hidKeysDown() & KEY_SELECT) { SwkbdState swkbd; swkbdInit(&swkbd, SWKBD_TYPE_NORMAL, 2, -1); swkbdSetValidation(&swkbd, SWKBD_NOTEMPTY, 0, 0); @@ -295,5 +295,5 @@ void qrinstall_open() { return; } - info_display("QR Code Install", "B: Return, A: Enter URL(s), X: Repeat, Y: Forget", false, data, qrinstall_wait_update, qrinstall_wait_draw_top); + info_display("QR Code Install", "B: Return, X: Repeat, Y: Forget, SELECT: URL(s)", false, data, qrinstall_wait_update, qrinstall_wait_draw_top); } diff --git a/source/ui/section/titles.c b/source/ui/section/titles.c index 43e53ef..372b8cc 100644 --- a/source/ui/section/titles.c +++ b/source/ui/section/titles.c @@ -297,7 +297,7 @@ void titles_open() { data->showGameCard = true; data->showSD = true; data->showNAND = true; - data->sortByName = true; + data->sortByName = false; list_display("Titles", "A: Select, B: Return, X: Refresh, Select: Options", data, titles_update, titles_draw_top); } \ No newline at end of file