2013-05-30 4 views
0

이것은 특정 질문이지만 어쨌든 게시 ...런타임시 정적 변수 변경

런타임에 정적 변수를 변경할 수 없습니다. 내 문제는 내가 런타임에 목록보기에서 행 수를 변경할 수 없다는 것입니다. 그것은 아래 코드와 함께 작동하지만이 목록은 이제 정적입니다. 사용자가 하나의 항목을 추가하거나 제거하려는 경우이 예제의 목록에는 여전히 5 개의 행이 있습니다.

는 섹션의 항목에 관련된 스크립트의 라인이다 :

#include "pebble_os.h" 
#include "pebble_app.h" 
#include "pebble_fonts.h" 
#include "settings.h" 

static Window window; 
static SimpleMenuLayer menu_layer; 
static SimpleMenuSection menu_sections[1]; 
static SimpleMenuItem menu_section0_items[5]; 

[...]

void init_settings_window() 

[...]

menu_sections[0] = (SimpleMenuSection) { 
     .title = "Things to buy...", 
     .items = menu_section0_items, 
     .num_items = ARRAY_LENGTH(menu_section0_items) 
    }; 

의 정의 SimpleMenuSection (API 참조) :

struct SimpleMenuSection 
Data structure containing the information of a menu section. 

Data Fields 
const SimpleMenuItem * items Array of items in the section. 
uint32_t  num_items Number of items in the .items array. 
const char *  title Title of the section. Optional, leave NULL if unused. 
+0

나는 런타임에 변경하고자하는 것이 무엇인지 이해하지 못합니다. –

+0

나에게 쉽게 설명되지 않았다, 미안. 그러나 나는 그것을 (잘하면) 풀었다. 정적 SimpleMenuItem에서 menu_section0_items [5]; 섹션의 최대 항목을 설정할 수 있습니다. 이 줄에서 .items = menu_section0_items 나는 menu_section0_items를 uint32_t 변수와 교환했다. 이제 작동합니다. 아마도이 질문을 삭제하는 것이 좋습니다 :( – Peter

답변

0

가변 길이 배열을 사용하여 런타임에 배열 크기를 결정해야 할 수 있습니다. Varialble 길이 배열은 c99 std의 일부이며 gcc 컴파일러에서 사용할 수 있습니다.

1

더 좋은 해결책은 (내가 생각하기에) 함수에 대한 모든 MenuLayer 콜백을 설정하고 항목이 변경되면 menu_layer_reload_data()으로 호출하는 것입니다. 런타임 중에 행 수가 변경 될 경우 각 섹션에 대한 명시 적 콜백을 설정하는 것이 최적의 솔루션이 아니며, 특히 동일한 콜백 동작이있는 여러 섹션이나 행으로 끝나는 경우가 아닙니다. 게다가 행이나 섹션이 많으면 코드가 엉망이 될 수 있습니다. 적용하려는 콜백이 각 행이나 섹션마다 다른 경우가 아니라면 모든 행에 대해 한 번에 콜백을 한 번 설정해야합니다.

SimpleMenu 예제는 주로 비 동적 메뉴를 위해 설계되었습니다. 의도 한대로 동적 메뉴를 제거하는 방법 대신 demos/feature_menu_layer에서 데모를 살펴보아야합니다. 이 방법을 가지고가는 경우에

MenuLayer menu_layer; 
uint16_t menu_get_num_sections_callback(MenuLayer *me, void *data) 
{ 
    return 1; // for now, there is only ever 1 section 
} 

uint16_t menu_get_num_rows_callback(MenuLayer *me, uint16_t section_index, void *data) 
{ 
    return my_var_that_holds_current_row_count; 
} 

int16_t menu_get_header_height_callback(MenuLayer *me, uint16_t section_index, void *data) 
{ 
    return MENU_CELL_BASIC_HEADER_HEIGHT; 
} 

void menu_draw_header_callback(GContext* ctx, const Layer *cell_layer, uint16_t section_index, void *data) 
{ 
    menu_cell_basic_header_draw(ctx, cell_layer, "Things to buy..."); 
} 

void menu_draw_row_callback(GContext* ctx, const Layer *cell_layer, MenuIndex *cell_index, void *data) 
{ 
    switch(cell_index->row) 
    { 
     // Fill in row content here 
    } 
} 

void window_load(Window *me) 
{ 
    // ... other window code here 
    // Set all the callbacks for the menu layer 
    menu_layer_set_callbacks(&menu_layer, NULL, (MenuLayerCallbacks) 
    { 
     .get_num_sections = menu_get_num_sections_callback, 
     .get_num_rows = menu_get_num_rows_callback, 
     .get_header_height = menu_get_header_height_callback, 
     .get_cell_height = menu_get_cell_height_callback, 
     .draw_header = menu_draw_header_callback, 
     .draw_row = menu_draw_row_callback, 

    }); 
} 

은 모두 당신이 할 필요가 : 더 나은 솔루션 (IMO)는 (그리고 SimpleMenuLayer를 사용하지 않음)

좀 더 같은 것을 할 것입니다 전체 MenuLayer에 대한 설정 콜백이다 메뉴를 새로 것은 : 행

  • 업데이트 행/셀의 컨텐츠를 보유하고있는 변수의 수를 보유하고

    1. 업데이트하여 변수
    2. 전화 menu_layer_reload_data(menu_layer)

    이 방법은 SimpleMenuLayer 접근 방식보다 설치가 필요 메뉴를 통해 (오류가 발생하기 쉬운 응용 프로그램이 성장함에 따라 될) 유사/동일한 기능을 반복 호출을 제거, 쉽게 코드를 읽고 이해할 수 있습니다, 다른 APIs/SDKs가 동일한 목표를 달성하는 방법에 더 근접합니다.

    페블 (Pebble)의 동적 메뉴를 구현하는 방법을 생각하면이 점을 feature_simple_menu_layer 예제와 비교하면 훨씬 더 명확하고 이해하기 쉽습니다. 동적 메뉴.