Тэээк-с, ну допустим. Вот один из вариантов реализации. Оно было скорее как эксперимент, но тем не менее.
Итак. Во-первых, надо объявить тип, который будет отвечать за один элемент меню.
Код:
typedef struct menuitem { char name[17]; //выводимое имя пункта int32_t min; //минимальное значение параметра, который настраивается в меню int32_t max; //максимальное значение int32_t value; //текущее значение, Меняется кнопками "вверх" и "вниз" int32_t oldvalue; //значение до сохранения int32_t step; //шаг изменения значения struct menuitem *left; //соседнее меню слева struct menuitem *right; //соседнее меню справа int32_t (* action)(); //действие пункта меню. Может быть как просто применение текущего значения параметра, так и целая подпрограмма. uint8_t id; //просто номер } menuitem;
Далее описываются конкретные пункты. Для каждого пункта прописываются все эти поля. То есть громкость, допустим, регулируется от 5 условных единиц до 100 с шагом 5. Тогда переменная volume типа menuitem должна иметь volume.min=5, volume.max=100, volume.step=5. Ну и так далее со всеми элементами.
Curritem это, собственно, текущий активный элемент меню. Далее описываем необходимые функции для каждого пункта меню. У меня эти функции вызывается по нажатию на кнопку ОК. Например
Вот эта функция выполняет сохранения выбранного значения во внешнюю энергонезависимую память и зажигает красный светодиод на секунду. И так любые функции, которые надо выполнять по нажатию кнопки ОК. Дальше начинается само формирования структуры меню. Само меню не древовидное, а в виде двусвязного списка. А можно и ещё связей добавить, сколько хватит кнопок и фантазии. То есть, для, так сказать, главного экрана присваиваем соответствующим полям ссылки на прочие элементы меню. Остальные поля не назначаются, поскольку прочих функций там не предусмотрено.
И так далее для всех прочих пунктов. На этом же этапе происходит загрузка ранее сохранённых значений. Проверки нет, но было бы неплохо это предусмотреть. Ну да ладно, это дело завтрашнего дня. Ну и собственно, антидребезг и реакция на каждую кнопку. Можно это дело хоть в прерывания засунуть. Для кнопок влево и вправо предусмотрено просто переключение пунктов, вверх и вниз изменяют параметры, ОК чаще всего просто сохраняет и применяет параметры, ВЫХ не делает ничего, просто возвращает в главное меню.
Ну и ещё раз повторюсь, что можно увеличить количество связей, можно назначить на каждую кнопку не жёсткую функцию, а тоже вызов заранее определённой функции, можно придумать ещё много всего. Это лишь моя такая небольшая попытка переизобрести меню заново, не обязательно линейное или древовидное.
Зарегистрирован: Вт сен 19, 2023 07:07:05 Сообщений: 72
Рейтинг сообщения:0
Меня заинтересовал 1 код и 2 код.Вопрос 1 структура есть а в структуре есть две структуры .А что в этих структурах?.2 код Это пункты меню? В скопках что указано код для регулировки ? Или что А где же вывод на экран?
struct menuitem *left; //соседнее меню слева struct menuitem *right; //соседнее меню справа
Вот это? Это не сами структуры, это лишь поле, содержащее ссылку на другой элемент того же типа. Указатель. По факту просто адрес другого экземпляра структуры. Собственно, в этом и заключается
А в шестнадцатеричном виде потому что это номера кириллических символов в знакосинтезирующем экранчике 1602. А сам вывод это совершенно отдельная независимая функция. Она берёт значения из curitem и выводит уже их. А вот сам *curitem это ссылка на текущий пункт меню. И эта ссылка подменяется по мере надобности.
Справа это фактически указатель на пункт меню (структура) blanktime. То есть даже и не переменная как таковая, а адрес в памяти. Чтобы такое присвоение получалось элемент right структуры menuitem объявлен как
Код:
struct menuitem *right;
То есть мы сразу говорим, что это ссылка на структуру типа menuitem. Потом берём blanktime, который имеет тип menuitem, и присваиваем его адрес полю right.
Зарегистрирован: Вт сен 19, 2023 07:07:05 Сообщений: 72
Рейтинг сообщения:0
Код:
char name[17];
Так это у вас буфер Для LCD?. А то пункты меню?.Но я не увидел Какие кнопки какие уменьшают или увеличивают параметры в меню?Покажите.Если это буфер то как он выводит пункты меню?
Функция вывода на экран это совершенно отдельная независимая функция. К организации меню она не относится. name это по сути просто строка с выводимым названием меню.
Если каким-либо способом пришла команда на увеличение параметра (кнопка, ДУ, генератор случайных чисел, не столь важно), то происходит увеличение value в указанных пределах с указанным шагом. Конкретно в данном случае функция UP проверяет состояние ножки. Так что кнопки одновременно нажимать в таком алгоритме нельзя. Но правильный опрос кнопок это опять-таки отдельная задача.
Зарегистрирован: Вт сен 19, 2023 07:07:05 Сообщений: 72
Рейтинг сообщения:0
Код:
UP - верх .Doun- вниз
Это шагаете вниз и вверх? А допустим есть какой то параметр G в меню как бы вы записали G++; G--?.А эти символы .Покажите как вы выводите на LCD?Много вопросов.
Объявил бы ещё одну переменную menuitem Gtune и уже внутри неё Gtune.value и устанавливал. И в любом месте программы где надо было бы использовать это значение уже брал бы Gtune.value .
Вначале преобразование числа в десятичную строку, потом что-то про выравнивание строк или вроде того. Не помню уже. А потом вывод библиотечной функцией. Первой строкой название пункта меню (то самое поле name), а второй строкой текущее значение параметра.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 15
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения