Rockbox.org home
Downloads
Release release
Dev builds dev builds
Extras extras
themes themes
Documentation
Manual manual
Wiki wiki
Device Status device status
Support
Forums forums
Mailing lists mailing lists
IRC IRC
Development
Bugs bugs
Patches patches
Dev Guide dev guide
Search



Donate

Rockbox Technical Forums


Login with username, password and session length
Home Help Search Staff List Login Register
News:

Thank You for your continued support and contributions!

+  Rockbox Technical Forums
|-+  Rockbox Development
| |-+  Starting Development and Compiling
| | |-+  Dynamic text in menu items (was: something related to rb->snprintf and menus)
« previous next »
  • Print
Pages: [1]

Author Topic: Dynamic text in menu items (was: something related to rb->snprintf and menus)  (Read 1534 times)

Offline gbl08ma

  • Member
  • *
  • Posts: 249
    • My blog
Dynamic text in menu items (was: something related to rb->snprintf and menus)
« on: January 31, 2011, 02:41:56 PM »
I'm developing a ID3 tag editor for Rockbox (in the future it might support other tags), and to display the file and tag information I'm trying to use the menu API.

The idea is: The tag is displayed in a menu item, and when a user selects that menu item, the vkeyboard opens so user can modify the tag. For now, as my plugin is still a stub, it only has code for showing the ID3v1 info of an opened file (the plugin is a viewer). Taking into account my C coding (in)ability, it's obvious the result would not be something that compiles with errors. :)

Here's the part of the code of the plugin which is causing the build to fail:
Code: [Select]
    /* get tag info from new_id3v1 and display it*/
    char* title_display;
    rb->snprintf(title_display, 37, "Title: %s", new_id3v1.title);
    char* artist_display;
    rb->snprintf(artist_display, 38, "Artist: %s", new_id3v1.artist);
    char* album_display;
    rb->snprintf(album_display, 37, "Album: %s", new_id3v1.album);
    char* year_display;
    rb->snprintf(year_display, 10, "Year: %s", new_id3v1.year);
    char* comment_display;
    rb->snprintf(comment_display, 37, "Comment: %s", new_id3v1.comment);
    MENUITEM_STRINGLIST(edittags_menu, "Select a tag to edit", NULL,         /* this is the line 229 */
                        title_display, artist_display, album_display,
                        year_display, comment_display, "Save", "Return",);
    switch (rb->do_menu(&edittags_menu, NULL, NULL, false))
    {
        default: /* no matter what the user selects, we will always return back */
            return true;
    }
and, on another subroutine
Code: [Select]
    char* filename_display;
    rb->snprintf(filename_display, MAX_PATH, "Filename: %s", opened_file);
    char* tagtype_display;
    tagtype_display = "Tag type: ID3v1"; /*in the future this will show the real
                                        tag type; for now it's a placeholder. */
    MENUITEM_STRINGLIST(fileinfo_menu, "File information", NULL,              /* this is the line 197 */
                        filename_display, tagtype_display, "Return",);
    switch (rb->do_menu(&fileinfo_menu, NULL, NULL, false))
    {
        default: /* no matter what the user selects, we will always return back */
        return true;
    }

(the whole file is attached)

This is the output of make:
Code: [Select]
gabriel@somePC:~/rockbox/build$ make
CC apps/plugins/id3_editor.c
/home/gabriel/rockbox/apps/plugins/id3_editor.c: In function ‘show_file_info’:
/home/gabriel/rockbox/apps/plugins/id3_editor.c:197: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:197: error: (near initialization for ‘fileinfo_menu_[0]’)
/home/gabriel/rockbox/apps/plugins/id3_editor.c:197: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:197: error: (near initialization for ‘fileinfo_menu_[1]’)
/home/gabriel/rockbox/apps/plugins/id3_editor.c: In function ‘show_edittags_menu’:
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: (near initialization for ‘edittags_menu_[0]’)
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: (near initialization for ‘edittags_menu_[1]’)
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: (near initialization for ‘edittags_menu_[2]’)
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: (near initialization for ‘edittags_menu_[3]’)
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: (near initialization for ‘edittags_menu_[4]’)
make: ** [/home/gabriel/rockbox/build/apps/plugins/id3_editor.o] Erro 1
gabriel@somePC:~/rockbox/build$
gabriel@GabrielUbuntuDesktop:~/rockbox/build$ make
CC apps/plugins/id3_editor.c
/home/gabriel/rockbox/apps/plugins/id3_editor.c: In function ‘show_file_info’:
/home/gabriel/rockbox/apps/plugins/id3_editor.c:197: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:197: error: (near initialization for ‘fileinfo_menu_[0]’)
/home/gabriel/rockbox/apps/plugins/id3_editor.c:197: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:197: error: (near initialization for ‘fileinfo_menu_[1]’)
/home/gabriel/rockbox/apps/plugins/id3_editor.c: In function ‘show_edittags_menu’:
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: (near initialization for ‘edittags_menu_[0]’)
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: (near initialization for ‘edittags_menu_[1]’)
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: (near initialization for ‘edittags_menu_[2]’)
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: (near initialization for ‘edittags_menu_[3]’)
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:229: error: (near initialization for ‘edittags_menu_[4]’)
make: ** [/home/gabriel/rockbox/build/apps/plugins/id3_editor.o] Erro 1
gabriel@GabrielUbuntuDesktop:~/rockbox/build$

I think that this errors are because I'm trying to use not-constant variables on MENUITEM_STRINGLIST, at least it's what it seems, because on another menu I'm using only strings and no variables, this way:
Code: [Select]
MENUITEM_STRINGLIST(main_menu, "Tag editor", NULL, "File information",
                        "Edit tags", "Exit",);
...and it doesn't show any error on the compiler.

If, like I think, it's because I'm trying to make menu items out of char* variables that were mixed with others using rb->snprintf, then how can I achieve the same effect ("Title: One Song", "Artist: Some Artist", etc.) using menus, or if menus can't be used, some other way to display data where user can scroll to the tag s/he wants to edit.

Anticipated thanks
Gabriel

PS: about the uploaded file, most likely the code is ugly, I didn't check if it follows the coding guidelines (I think so), and certainly contains more errors than what the compiler reports; I played a bit with C and C++ two years ago for curiosity, but in the meantime I forgot most of the few things I learned... I hope that with Rockbox I can definitely learn C again.
PS2: I'll create a patch in the tracker when I think it's worth, that is, when I get something that compiles.
* id3_editor.c (9.37 kB - downloaded 86 times.)
« Last Edit: February 02, 2011, 01:37:36 PM by gbl08ma »
Logged
http://gbl08ma.com | http://i.tny.im

Offline bluebrother

  • Developer
  • Member
  • *
  • Posts: 3421
  • creature
Re: rb->snprintf Mixed variables in menu items
« Reply #1 on: January 31, 2011, 04:15:19 PM »
Code: [Select]
    /* get tag info from new_id3v1 and display it*/
    char* title_display;
    rb->snprintf(title_display, 37, "Title: %s", new_id3v1.title);

This is wrong -- snprint() doesn't allocate the buffer it writes the output data to. You need to allocate the memory yourself you're pointing snprintf() to.

Haven't looked into other issues yet.
Logged
Rockbox Utility development binaries (updated infrequently) · How to ask questions the smart way · We do not estimate timeframes.

Offline gbl08ma

  • Member
  • *
  • Posts: 249
    • My blog
Re: rb->snprintf Mixed variables in menu items
« Reply #2 on: January 31, 2011, 04:49:51 PM »
Thanks for your help...
I changed the variables from char* to char[10], where 10 is the size of the buffer. Also, replaced
Code: [Select]
tagtype_display = "Tag type: ID3v1"
for
Code: [Select]
rb->snprintf(tagtype_display, 15, "Tag type: ID3v1");
and the build result is...
Code: [Select]
gabriel@somePC:~/rockbox/build$ make
CC apps/plugins/id3_editor.c
/home/gabriel/rockbox/apps/plugins/id3_editor.c: In function ‘show_file_info’:
/home/gabriel/rockbox/apps/plugins/id3_editor.c:207: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:207: error: (near initialization for ‘fileinfo_menu_[0]’)
/home/gabriel/rockbox/apps/plugins/id3_editor.c:207: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:207: error: (near initialization for ‘fileinfo_menu_[1]’)
/home/gabriel/rockbox/apps/plugins/id3_editor.c: In function ‘show_edittags_menu’:
/home/gabriel/rockbox/apps/plugins/id3_editor.c:239: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:239: error: (near initialization for ‘edittags_menu_[0]’)
/home/gabriel/rockbox/apps/plugins/id3_editor.c:239: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:239: error: (near initialization for ‘edittags_menu_[1]’)
/home/gabriel/rockbox/apps/plugins/id3_editor.c:239: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:239: error: (near initialization for ‘edittags_menu_[2]’)
/home/gabriel/rockbox/apps/plugins/id3_editor.c:239: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:239: error: (near initialization for ‘edittags_menu_[3]’)
/home/gabriel/rockbox/apps/plugins/id3_editor.c:239: error: initializer element is not constant
/home/gabriel/rockbox/apps/plugins/id3_editor.c:239: error: (near initialization for ‘edittags_menu_[4]’)
make: ** [/home/gabriel/rockbox/build/apps/plugins/id3_editor.o] Erro 1

The line numbers of the error are different because I added some extra documentation comments at the start of the file.

Attached goes my modified id3_editor.c.
* id3_editor.c (10.01 kB - downloaded 97 times.)
Logged
http://gbl08ma.com | http://i.tny.im

Offline bluebrother

  • Developer
  • Member
  • *
  • Posts: 3421
  • creature
Re: rb->snprintf Mixed variables in menu items
« Reply #3 on: January 31, 2011, 06:01:45 PM »
From a quick look into menu.h it doesn't look like you're using the correct macro -- MENUITEM_RETURNVALUE_DYNTEXT sounds like a better match to me. But I'm not familiar with that code and haven't checked right now so I might also be wrong. However, I suggest checking menu.h :)
Logged
Rockbox Utility development binaries (updated infrequently) · How to ask questions the smart way · We do not estimate timeframes.

Offline gbl08ma

  • Member
  • *
  • Posts: 249
    • My blog
Re: rb->snprintf Mixed variables in menu items
« Reply #4 on: February 01, 2011, 07:05:05 AM »
I used the code that was on the wiki page about how to use the menu API, perhaps it is wrong or I modified it in some wrong way.
Logged
http://gbl08ma.com | http://i.tny.im

Offline torne

  • Developer
  • Member
  • *
  • Posts: 994
  • arf arf
Re: rb->snprintf Mixed variables in menu items
« Reply #5 on: February 01, 2011, 07:58:58 AM »
The menu macros are not function calls that happen at runtime, they are datastructure creation macros which happen at compile time. You can only pass constant, known-at-compile-time values into them. To have dynamic menus you need to do it differently, by providing a function which can be called at runtime to return the appropriate string. See MENUITEM_RETURNVALUE_DYNTEXT and similar as bluebrother suggested.
Logged
some kind of ARM guy. ipodvideo/gigabeat-s/h120/clipv2. to save time let's assume i know everything.

Offline gbl08ma

  • Member
  • *
  • Posts: 249
    • My blog
Re: rb->snprintf Mixed variables in menu items
« Reply #6 on: February 01, 2011, 04:01:42 PM »
So, if I my conclusions I took from looking at the MENUITEM_RETURNVALUE_DYNTEXT definition on menu.h, and from observing the only practical example of using this macro existent in SVN (I did a recursive grep), located at root_menu.c (it's the resume playback/go to WPS item menu), I'm under the impression that to use this macro I need to do like this:

(kind of C-pseudo-code, "coded" directly on the reply textbox)
Code: [Select]
bool show_test_menu(void)
{
    char[14] item1text = "Item 1 example";
    char[14] item2text = "Item 2 example";
    MENUITEM_RETURNVALUE_DYNTEXT(dyn_item1, CALL1, NULL, item1text,
            NULL, NULL, ICON_NOICON);
    MENUITEM_RETURNVALUE_DYNTEXT(dyn_item2, CALL2, NULL, item2text,
            NULL, NULL, ICON_NOICON);
    /* I don't know if ICON_NOICON exists... */

    /*and then tell to draw the menu... */

    MAKE_MENU(test_menu, "Test menu",
            item_callback, Icon_Rockbox,
            &dyn_item1, &dyn_item2);
}

/*have a function that handles item selection... */
static int item_callback(int action, const struct menu_item_ex *this_item)
{
    /* a switch would be in here... just not sure what to switch between...? between CALL1 and  CALL2? */
}


So, am I correct and this is the way I should create a menu with dynamic items, or what is wrong or missing? Also please answer my questions on the "code"... I plan to "wikify" this once I get it working, so it is easier for other people to show dynamic information on the menu items.

--Edit--

Well, from another, deeper looking it seems that the function that I should use is MENUITEM_FUNCTION_DYNTEXT, which is the "same" as MENUITEM_FUNCTION, but for dynamic text. Just what I want, except that I don't seem to need a so complex thing:

Code: [Select]
/* As above, except the text is dynamic */
#define MENUITEM_FUNCTION_DYNTEXT(name, flags, func, param,                 \
                                  text_callback, voice_callback,            \
                                  text_cb_data, callback, icon)             \
    static const struct menu_get_name_and_icon name##_                      \
        = {callback,text_callback,voice_callback,text_cb_data,icon};        \
    static const struct menu_func name##__ = {{(void*)func}, param};           \
    static const struct menu_item_ex name   =                                  \
        { MT_FUNCTION_CALL|MENU_DYNAMIC_DESC|flags,                            \
         { .function = & name##__}, {.menu_get_name_and_icon = & name##_}};
What exactly should I put on the parameters name, flags, func, param, text_callback, voice_callback, text_cb_data, callback and icon? I know some of them seem pretty obvious on what they are, but what kind of data (char, int, some specific struct, pointer to a function or macro, etc.) should I pass to them, and are they all the parameters required (can't I just put NULL)? For example, I don't have a voice_callback as plugins don't have lang files.

From looking at an "example" at /apps/audio_eq_menu.c (a pretty complex example, by the way, but it was one of the few available on the code), it seems I should setup a function and various structures for each menu item...

Isn't there a simpler way to do this? Using MENUITEM_FUNCTION seems to be waaay simpler, but it doesn't support dynamic content, does it?
How does the system uptime menu under the System menu show these dynamic menu items with a time counter (that is updated on real-time)? Or isn't that a menu (but something that looks like one)? I can't find the file where that menu is coded, I'll keep on searching the files...

Thanks for all the help (I know that, actually, it seems it'd be less work for you guys, that are trying to help me, if I didn't try code when I can't...)
« Last Edit: February 02, 2011, 01:35:39 PM by gbl08ma »
Logged
http://gbl08ma.com | http://i.tny.im

  • Print
Pages: [1]
« previous next »
+  Rockbox Technical Forums
|-+  Rockbox Development
| |-+  Starting Development and Compiling
| | |-+  Dynamic text in menu items (was: something related to rb->snprintf and menus)
 

  • SMF 2.0.17 | SMF © 2019, Simple Machines
  • Rockbox Privacy Policy
  • XHTML
  • RSS
  • WAP2

Page created in 0.079 seconds with 16 queries.