Home AMX User Forum AMX Control Products

Multi-language button

Hi guys, I need to give the user the ability to switch the language of the text on my buttons. For example, the user will have the choice of either French or English for the text displayed on the buttons. What would you recommend as best method for achieving that? I am thinking of using a MSB with 4 states. First two for English text and last two for French text. My question, though, is how I will define that level 3 correspond to the OFF state and level 4 should be the ON state?

Thank you


  • pdabrowskipdabrowski Posts: 184
    AFAIK Multi state buttons are not really designed for this purpose (displaying and holding a state depending on feedback requirements). They are for animating the progress between 2 states (ON & OFF).

    Multi-state bargraphs are more like what you want as you can manipulate the level in code and the multi-state bargraph can be drawn as a button with each state gioving the required feedback. To see a multi-state bargraph like this, open the system page template in TPD4 and look at the properties of the connection status indicator (red circle).

    This can be driven from code as a level, but creating a level for each and every button, then manipulating that level for feedback depending on language selection will be too complicated, especially when you have multiple panels on a system.

    I would look at creating an function that sets the button text based on selected language whenever the user chooses their preferred language, if you have a lot of buttons to send the commands to, create a "loading" page that shows for a couple of seconds while the entire panel is re-written and then periodically update the panel on no activity as well as on the ONLINE event so the panel language is synced in a multiple panel system.

  • ericmedleyericmedley Posts: 4,177
    why not just do the whole thing from code? Make your buttons all variable text and populate them from code. That way you can manage the languages dynamically and even store the settings in a file that can move from master to master/project to project.

    I do this for the most part anyway since I fill things like TP navigation, source selection, lists of stuff, channel favorites, zone names, etc... all dynamically from code. It may sound a bit daunting but honestly, once you write the code for it, it's really easy. (and flexible)
  • GregGGregG Posts: 251
    I did it using the variable text button method, but found a few oddities when I created the code. This is about 7 years ago, so some of these things may have better ways to do them now. (like maybe there's a good way to get a widechar literal constant, since using 'Espa?ol' didn't work for me at the time)

    If you are using this method, make sure you have "Enable _WC Preprocessor (Unicode)" enabled in the netlinx compiler options.

    Then I used code like this to set up the language arrays:
    WC_FORMAT_TP            = 100
    Volatile Char cLanguageSets[2][104][200]
    Include 'UnicodeLib.axi'
    // _WC() turns the given ascii into a widechar string
    //  WC_ENCODE() with the WC_FORMAT_TP option translates the widechar
    //    into a char string for use with the G4 "^UNI-" command.
    cLanguageSets[1][1]    =    WC_ENCODE(_WC('house control'),WC_FORMAT_TP,1)
    cLanguageSets[1][2]    =    WC_ENCODE(_WC('utilities'),WC_FORMAT_TP,1)
    cLanguageSets[1][3]    =    WC_ENCODE(_WC('modules'),WC_FORMAT_TP,1)
    cLanguageSets[1][4]    =    '004500730070006100F1006F006C' //WC_ENCODE(_WC('Espa?ol'),WC_FORMAT_TP,1)
    cLanguageSets[1][5]    =    WC_ENCODE(_WC('Turn off'),WC_FORMAT_TP,1)
    cLanguageSets[1][6]    =    WC_ENCODE(_WC('audio/video ?'),WC_FORMAT_TP,1)
    cLanguageSets[1][7]    =    WC_ENCODE(_WC('Turn off whole house ?'),WC_FORMAT_TP,1)
    cLanguageSets[1][8]    =    WC_ENCODE(_WC('system power'),WC_FORMAT_TP,1)
    cLanguageSets[1][9]    =    WC_ENCODE(_WC('volume'),WC_FORMAT_TP,1)
    cLanguageSets[1][10]    =    WC_ENCODE(_WC('channel'),WC_FORMAT_TP,1)
    cLanguageSets[1][11]    =    WC_ENCODE(_WC('page'),WC_FORMAT_TP,1)
    cLanguageSets[1][12]    =    WC_ENCODE(_WC('audio'),WC_FORMAT_TP,1)
    cLanguageSets[1][13]    =    WC_ENCODE(_WC('video'),WC_FORMAT_TP,1)
    cLanguageSets[1][14]    =    WC_ENCODE(_WC('lighting'),WC_FORMAT_TP,1)
    cLanguageSets[2][1]    =    WC_ENCODE(_WC('control de la casa'),WC_FORMAT_TP,1)    //    house control
    cLanguageSets[2][2]    =    WC_ENCODE(_WC('utilidades'),WC_FORMAT_TP,1)    //    utilities
    cLanguageSets[2][3]    =    '006D00F300640075006C006F0073'  //WC_ENCODE(_WC('m?dulos'),WC_FORMAT_TP,1)    //    modules
    cLanguageSets[2][4]    =    WC_ENCODE(_WC('English'),WC_FORMAT_TP,1)    //    english
    cLanguageSets[2][5]    =    '00BF00440065'  //WC_ENCODE(_WC('?De'),WC_FORMAT_TP,1)    //    Turn off
    cLanguageSets[2][6]    =    '0061007500640069006F002F007600ED00640065006F0020003F'  //WC_ENCODE(_WC('audio/v?deo ?'),WC_FORMAT_TP,1)    //    audio/video ?
    cLanguageSets[2][7]    =    '00BF004400E90020007600750065006C007400610020006100700061006700610064006F002000610020006C006100200063006100730061003F'  //WC_ENCODE(_WC('?D? vuelta apagado a la casa?'),WC_FORMAT_TP,1)    //    Turn off whole house ?
    cLanguageSets[2][8]    =    '0065006E00650072006700ED0061002000640065006C002000730069007300740065006D0061'  //WC_ENCODE(_WC('energ?a del sistema'),WC_FORMAT_TP,1)    //    system|power
    cLanguageSets[2][9]    =    WC_ENCODE(_WC('volumen'),WC_FORMAT_TP,1)    //    volume
    cLanguageSets[2][10]    =    '00650073007400610063006900F3006E'  //WC_ENCODE(_WC('estaci?n'),WC_FORMAT_TP,1)    //    channel
    cLanguageSets[2][11]    =    '007000E100670069006E0061'  //WC_ENCODE(_WC('p?gina'),WC_FORMAT_TP,1)    //    page
    cLanguageSets[2][12]    =    WC_ENCODE(_WC('audio'),WC_FORMAT_TP,1)    //    audio
    cLanguageSets[2][13]    =    '007600ED00640065006F'  //WC_ENCODE(_WC('v?deo'),WC_FORMAT_TP,1)    //    video
    cLanguageSets[2][14]    =    '0069006C0075006D0069006E00610063006900F3006E'  //WC_ENCODE(_WC('iluminaci?n'),WC_FORMAT_TP,1)    //    lighting

    I originally tried using the foreign characters in the netlinx code, but they didn't seem to encode properly all the time, so I would put the strings into TPD4 and copy back out the premade unicode strings that show up in the lower section of the text editing popup.

    Also of note, make sure to do some queuing of the send commands to the touch panels, I had a lot more than just the 14 language resource elements listed here and it becomes easy to flood the interpreter or the panel if you loop around and try to send all those commands from one event.

    And if you resend the strings in an online event, sometimes forcing a ton of commands out the second you see a panel show up can make it drop back off in an endless cycle.
  • RaphayoRaphayo Posts: 111
    I'm reading a file located in the processor.

    All button state are recall from that file.

    The file syntax look like this

    [Channel][tab][inactive text][tab][active text][crlf]


    If you need to correct syntax, update the files in the processor and press language button to load it.
  • The consensus here is to programmatically update the text of each button.
    Thanks everyone for taking the time to share your thought!
Sign In or Register to comment.