Как организовать структуру меню и навигацию для LCD.

Тема в разделе "Флудилка", создана пользователем NR55RU, 11 июн 2014.

  1. NR55RU

    NR55RU Гик

    Тема созданию меню для LCD встает чуть реже чем вопрос о том почему что-то не работает, и часто эта тема вызывает множество проблем, и как правило основная проблема именно в создание "структуры" меню и навигации по этому меню.

    На самом деле создать меню любого уровня вложенности и осуществлять по нему навигацию, намного роще чем может показаться.

    И так, ниже я приведу код а потом слегка прокомментирую.
    Внимание: Код не для Ардуина. Это обычный код на С++, который вы можете скопировать и скомпилировать у себя на ПК, запустить и попробовать "походить" по меню спомщью кнопок w.s.a.d и кнопки enter, q - выход из программы.
    Код целенаправленно сделан по возможности понятнее.

    Код (Text):
    #include <iostream>

    typedef struct menuItem
    {
        int id;
        char *name;
        struct menuItem *up;
        struct menuItem *right;
        struct menuItem *left;
        struct menuItem *down;
    } menuItem;

    void showPosition( const menuItem *inputItem );

    int main( void )
    {
        menuItem m = {0, "Menu:", NULL, NULL, NULL};
        menuItem m1 = {1, "Menu 1", NULL, NULL, NULL};
        menuItem m11 = {11, "Menu 1-1", NULL, NULL, NULL};
        menuItem m12 = {12, "Menu 1-2", NULL, NULL, NULL};
        menuItem m13 = {12, "Menu 1-3", NULL, NULL, NULL};
        menuItem m2 = {2, "Menu 2", NULL, NULL, NULL};
        menuItem m21 = {21, "Menu 2-1", NULL, NULL, NULL};

        // Первый уровень меню
        m.down = &m1;
        // Настройка М1
        m1.up = &m;
        m1.down = &m2;
        m1.right = &m11;
        // Настройка М2
        m2.up = &m1;
        m2.right = &m21;

        // Второй уровень меню M1
            // Настройка М11
            m11.left = &m1;
            m11.down = &m12;
            // Настройка М12
            m12.up = &m11;
            m12.down = &m13;
            // Настройка М13
            m13.up = &m12;
       
        // Второй уровень меню M2
            // Настройка М21
            m21.left = &m2;
       
        menuItem *curItem = &m;    // Тут мы будем хранить указатель на текущее меню
        showPosition( curItem );
        char key = 0;
        while ( std::cin >> key )
        {
            switch ( key )
            {
                case 'w':
                    curItem->up ? curItem = curItem->up : NULL;
                    break;
                case 'd':
                    curItem->right ? curItem = curItem->right : NULL;
                    break;
                case 'a':
                    curItem->left ? curItem = curItem->left : NULL;
                    break;
                case 's':
                    curItem->down ? curItem = curItem->down : NULL;
                    break;
            }
            if (key == 'q') break;
            showPosition( curItem );
        }
    }

    void showPosition( const menuItem *inputItem )
    {
        std::cout << "You now at: " << inputItem->name << std::endl;
    }
    Первое что хочу сказать, этот код показывает идеологию создания структуры меню и то как легко организовать по нему навигацию, это не конечный продукт для создания меню, хватит господа копировать готовые куски кода из инета, вставлять их а потом не понимать почему они у вас не работают :)
    Эту идею вам еще потребуется "партировать" на ардуин а значит придется попотеть и вникнуть в идею, именно поэтому я не стал делать готовый код для ардуина и не стал все это запихивать в красивый класс и предоставлять простой и понятный интерфейс.
    Так что данный код это лишь толчок в сторону одного из возможных вариантов.

    Данный код наглядно показывает как мы можем использовать простую идею связанного списка структур что бы создать структур меню любого уровня вложенности.

    Каждая структура menuItem может иметь 4-х соседей, сверху, снизу, слева и справа, это как раз схоже с той идеей как обычно организованно меню на LCD, мы постепенно перемещаемся вниз-вверх нажимаем джойтик право-влево чтобы войти в меню, хотя лево-право можно при желании заменить на нажатие кнопки select, если вы поймете идею представленную выше то сделаете это без особого труда.

    Более того, такая методика позволяет вам хранить в структуре любую нужную вам информацию об этом пункте меню.

    Самое сложное во всем этом коде это аккуратно создать связанную структуру, то что делается в начале,, но это будет весьма просто, если вы нарисуете на бумажке структуру меню а потом по этому рисунку аккуратно создадите структуру, не забывая указывать какое меню находится сверху, сверху, сперва или слева.

    Вот так выглядит визуально меню представленное в данном коде:
    [​IMG]

    В целом как видите все просто, а главное очень хорошо поддается расширению и модификации.
    Так что попробуйте понять саму идею, поняв ее вы сможете создавать какие только пожелаете менюшки для своих LCD.

    P.s. Это далеко не идеальная идея и не идеальная реализация, это лишь базовый пример. :)
     
    acos, dreadfull, Tomasina и ещё 1-му нравится это.
  2. dreadfull

    dreadfull Гик

    интересно,..... красиво,..... НО не понятно как правильно реализовать на ардуине:(.
    хотя автору спасибо за идею (лично я не знал о применении такой возможности на базе ардуино)
     
  3. NR55RU

    NR55RU Гик

    На самом деле это простейшая структура данных, связанный список.
    Одна из разновидностей самых простых структур данных.
    Организовывать пошаговую навигацию по таким спискам без "прыжков" проще простого.
    И применимо это на любом МК или ПК, без разницы.
    Если желаете чуть больше узнать о структурах данных, рекомендую хорошую вводную книгу по этой теме.
    Вот эту.

    А переделать это на ардуин, очень просто, главное понять как это работает хорошо и все :)
     
  4. simark1979

    simark1979 Нуб

    Гениально, спасибо)
    А то в инете полно способов, но ничего проще и гибче не нашел)