为atp_select添加了默认选中项目的功能,先build一下试试

This commit is contained in:
anod 2022-10-15 17:12:57 +08:00
parent c1e79ef7a8
commit 7b66f6a82e
5 changed files with 108 additions and 24 deletions

View File

@ -41,6 +41,15 @@ extern acf_error_t acf_initialize(
INPUT(acf_text_t) filename_of_acf_font
);
extern acf_error_t acf_calculate(
INPUT(acf_rectedge_t) width_in_pixel_of_canvas,
INPUT(acf_text_t) text_painting_in_utf8,
OUTPUT(acf_rectedge_t) using_width_in_pixel_of_canvas,
OUTPUT(acf_counter_t) rendered_char_counting,
OUTPUT(acf_text_t) text_not_rendered_in_utf8
);
extern acf_canvas_t acf_get_canvas(
INPUT(acf_rectedge_t) width_in_pixel_of_canvas,
INPUT(acf_text_t) text_painting_in_utf8,

View File

@ -60,12 +60,14 @@ typedef struct {
typedef atp_error_t (*atp_lineprovider_t)(
INPUT(atp_callerdata_t) some_data_provided_by_caller,
INPUT(atp_counter_t) line_index_of_this_page,
OUTPUT(atp_linecfg_t) configuration_of_this_line
);
typedef atp_error_t (*atp_itemprovider_t)(
INPUT(atp_callerdata_t) some_data_provided_by_caller,
INPUT(atp_counter_t) index_of_current_option_item,
OUTPUT(atp_itemcfg_t) configuration_of_current_option_item
);
@ -91,6 +93,8 @@ extern atp_error_t atp_select(
INPUT(atp_itemprovider_t) item_information_provider,
INPUT(atp_keyhandler_t) extra_key_handler,
INPUT(atp_callerdata_t) some_data_from_caller,
INPUT(atp_counter_t) index_of_default_selected_item,
OUTPUT(atp_itemval_t) value_of_select_item
);

View File

@ -279,7 +279,7 @@ static int render_unicode(FHandle fd, int *x, unsigned width, unsigned height, u
// render
// 从上往下(y从大到小x从小到大)进行绘制
int px = *x, py = -1-gblfont.offsety; // px/py不参与计算位置
int px = *x, py = -1-gblfont.offsety; // px/py不参与计算位置
int cx = px + bbx[2], cy = py + bbx[1] + bbx[3]; // cx/cy计算位置进行绘制
// 先检查宽度
@ -287,17 +287,20 @@ static int render_unicode(FHandle fd, int *x, unsigned width, unsigned height, u
return 1;
// 绘制
for (int i = 0; i < bbx[1]; ++i)
if ( ram != NULL )
{
for (int j = 0; j < bbx[0]; ++j)
for (int i = 0; i < bbx[1]; ++i)
{
int tx = cx+j, ty = cy-i;
// see: https://www.zhihu.com/question/264505093/answer/281849883
if( ( tx | ((int)width-tx) | ty | ((int)height-ty) ) > 0 ) // 0 <= tx && tx < width && 0 <= ty && ty <= height
for (int j = 0; j < bbx[0]; ++j)
{
if( BIT_AT_POS(glyph, bbx[0] * i + j) )
int tx = cx+j, ty = cy-i;
// see: https://www.zhihu.com/question/264505093/answer/281849883
if( ( tx | ((int)width-tx) | ty | ((int)height-ty) ) > 0 ) // 0 <= tx && tx < width && 0 <= ty && ty <= height
{
SET_AT_POS( ram, PIX_IN_LINE(tx, ty, width) );
if( BIT_AT_POS(glyph, bbx[0] * i + j) )
{
SET_AT_POS( ram, PIX_IN_LINE(tx, ty, width) );
}
}
}
}
@ -387,3 +390,43 @@ acf_canvas_t acf_get_canvas(acf_rectedge_t width, acf_text_t text, acf_rectedge_
fClose(font);
return canvas;
}
acf_canvas_t acf_calculate(acf_rectedge_t width, acf_text_t text, acf_rectedge_t *realwidth, acf_counter_t *renderedcnt, acf_text_t *rest)
{
FHandle font;
if( gblfont.filename == NULL || RES_OK != fOpen(&font, gblfont.filename, FA_OPEN_EXISTING | FA_READ) )
{
// log
return ACFONT_NOT_FOUND;
}
uint32_t unicode;
int linex = 0;
int rendered_count = 0;
const char *utf8_line = text;
for (const char *next = next_unicode(utf8_line, &unicode);
next != NULL;
next = next_unicode(utf8_line, &unicode))
{
int error = render_unicode(font, &linex, width, gblfont.height, unicode, NULL);
if( error > 0 ) break;
else if( error < 0 ) error = render_unicode(font, &linex, width, gblfont.height, '?', NULL);
if( error )
{
fClose(font);
return error;
}
utf8_line = next;
++rendered_count;
}
if( realwidth != NULL ) *realwidth = linex;
if( renderedcnt != NULL ) *renderedcnt = rendered_count;
if( rest != NULL ) *rest = utf8_line;
fClose(font);
return 0;
}

View File

@ -223,11 +223,11 @@ static void draw_options( int start_row, int start_idx, int option_cnt, int sele
else draw_options( 0, idx_top - title_len, cnt, item_sel, provider, data ); \
}
atp_error_t atp_select( atp_text_t title, atp_counter_t cnt, atp_itemprovider_t provider, atp_keyhandler_t handler, atp_callerdata_t data, atp_itemval_t *res )
atp_error_t atp_select( atp_text_t title, atp_counter_t cnt, atp_itemprovider_t provider, atp_keyhandler_t handler, atp_callerdata_t data, atp_counter_t index, atp_itemval_t *res )
{
uint8_t title_offset[TITLE_MAX];
int idx_top = 0, title_len = 1;
int item_sel = 0;
int item_sel = index < cnt ? index : 0;
int title_len = 1;
atp_itemcfg_t config;
screen_clean();
@ -236,17 +236,22 @@ atp_error_t atp_select( atp_text_t title, atp_counter_t cnt, atp_itemprovider_t
const char *cursor = title;
for( int i=0; i < TITLE_MAX; ++i )
{
const char *next = easy_put( cursor, ATP_PLACEMENT_LEFT, ATP_COLOR_LIGHT, i );
if( *next == '\0' ) break;
const char *next;
if( 0 == acf_calculate( CONTAINER_RECT_WIDTH, cursor, NULL, NULL, &next ) )
{
if( *next == '\0' ) break;
title_offset[i] = next - cursor;
++title_len;
cursor = next;
title_offset[i] = next - cursor;
++title_len;
cursor = next;
}
}
for( int i=title_len; i < TITLE_MAX; ++i ) title_offset[i] = 0;
// draw item
draw_options( title_len, 0, cnt, item_sel, provider, data );
int idx_top = item_sel + title_len;
idx_top = idx_top - idx_top%CONTAINER_MAX_LINES;
REFRESH_PAGE;
while( 1 )
{
@ -338,7 +343,9 @@ atp_error_t atp_select( atp_text_t title, atp_counter_t cnt, atp_itemprovider_t
// 更新item_sel
item_sel = idx_top + item_sel % CONTAINER_MAX_LINES;
if( item_sel >= (int)cnt ) item_sel = cnt-1;
if( idx_top == 0 && item_sel >= CONTAINER_MAX_LINES-title_len )
item_sel = 0;
else if( item_sel >= (int)cnt ) item_sel = cnt-1;
// 更新view
REFRESH_PAGE;

View File

@ -76,7 +76,7 @@ int dlistCompare(const void *a, const void *b)
return res;
}
static Result scanDir(const char *const path, DirList *const dList, const char *const filter)
static Result scanDir(const char *const path, DirList *const dList, const char *const filter, const char *match, int *index)
{
FILINFO *const fis = (FILINFO*)malloc(sizeof(FILINFO) * DIR_READ_BLOCKS);
if(fis == NULL) return RES_OUT_OF_MEM;
@ -127,6 +127,18 @@ scanEnd:
qsort(dList->ptrs, dList->num, sizeof(char*), dlistCompare);
if( match != NULL )
{
for( int i=0; i < dList->num; ++i )
{
if( strcmp(match, &dList->ptrs[i][1]) == 0 )
{
*index = i;
break;
}
}
}
return res;
}
@ -156,6 +168,7 @@ atp_error_t display_empty( atp_callerdata_t, atp_counter_t, atp_linecfg_t *confi
if(*(tmpPathPtr - 1) == ':') tmpPathPtr++; \
*tmpPathPtr = '\0'; \
scan = 1; \
upFrom = tmpPathPtr + 1; \
}
Result browseFiles(const char *const basePath, char selected[512])
{
@ -170,15 +183,18 @@ Result browseFiles(const char *const basePath, char selected[512])
if(dList == NULL) return RES_OUT_OF_MEM;
Result res;
if((res = scanDir(curDir, dList, ".gba")) != RES_OK) goto end;
if((res = scanDir(curDir, dList, ".gba", NULL, NULL)) != RES_OK) goto end;
while( 1 ){
const char *upFrom = NULL;
int selecting = 0;
while( 1 )
{
atp_itemval_t value;
atp_boolean_t scan = 0;
atp_error_t error;
const u32 count = dList->num;
if( count > 0 )
error = atp_select( curDir, count, display_folder, NULL, (atp_callerdata_t)dList, &value );
error = atp_select( curDir, count, display_folder, NULL, (atp_callerdata_t)dList, selecting, &value );
else error = atp_show( 1, display_empty, NULL );
u32 pathLen = strlen(curDir);
@ -210,7 +226,12 @@ Result browseFiles(const char *const basePath, char selected[512])
safeStrcpy( selected, curDir, 512 );
break;
}
else scan = 1;
else
{
scan = 1;
selecting = 0;
upFrom = NULL;
}
}
}
else if( error == ATP_NO_ACTION )
@ -220,7 +241,7 @@ Result browseFiles(const char *const basePath, char selected[512])
if( scan )
{
if(RES_OK != (res = scanDir(curDir, dList, ".gba")) )
if(RES_OK != (res = scanDir(curDir, dList, ".gba", upFrom, &selecting)) )
break;
}
}