Программерские приёмчики: организация меню.
- Войдите на сайт для отправки комментариев
Втр, 13/04/2021 - 13:15
Опять вопрос по приёмам. Например: нужна древовидная многоуровневая менюшка. Каждый пункт меню может (но не обязан) иметь один или несколько подпунктов. Вид примерно такой:
Пункт 1
Пункт 1.1
Пункт 1.2
Пункт 2
Пункт 2.1
Пункт 2.1.1
Пункт 2.1.2
Пункт 2.1.2.1
Пункт 2.1.3
Пункт 2.2
Пункт 2.3
Пункт 2.3.1
Пункт 2.4
Пункт 3
Пункт 4
Пункт 4.1
Пункт 4.2
Пункт 4.3
Как наиболее грамотно организовать подобное в коде? Многомерный массив? Одна переменная, как понимаю, должна описывать текущую позицию меню, нужна ли ещё одна, описывающая родительский пункт? Что менее затратно - выделять память под такую переменную (теряем память), или же динамически вычислять родителя (теряем время)?
Связные списки, например.
Связные списки, например.
дополню - связный список обьектов. Для описания пунктов меню создается структура или класс, поля которого хранят текст пункта, указатели на предыдущий, последующий. вышестоящий и нижестоящий пункт и прочую необходимую информацию.
Примеров в сети довольно много. но должен предупредить, что организация меню - один из довольно сложных разделов ООП программирования. Мне кажется. что для вас пока будет сложно его освоить...для человека. не понимающего даже. как посчитать число элементов обычного одномерного массива.
Мне кажется. что для вас пока будет сложно его освоить...для человека. не понимающего даже. как посчитать число элементов обычного одномерного массива.
если опустить выпад насчёт массива - спасибо. :-) То, что я не знаком с конкретной реализацией С++, не означает, что не работаю с ООП в целом. ;-)
Связные списки, например.
Единственное причина использовать эту структуру - быстрая вставка. Которая тут совершенно не нужна.
То, что я не знаком с конкретной реализацией С++
Ты ни с какой не знаком.
вот вам ссылочка на обсуждение организации многомерного меню на этом форуме. там и примеры есть. Только не советую брать первые два - там как раз пример того, как это делать НЕ НАДО
http://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/sozdanie-mnogourovnevogo-graficheskogo-menyu
Единственное причина использовать эту структуру - быстрая вставка. Которая тут совершенно не нужна.
я бы сказал не "быстрая", а скорее простая и легкая. Меню на связанном списке позволяет играючи добавлять и убирать элементы при разработке программы. Считаю это этого более чем достаточно. чтобы выбрать именно этот вариант
Меню на связанном списке позволяет играючи добавлять и убирать элементы при разработке программы. Считаю это этого более чем достаточно. чтобы выбрать именно этот вариант
ИНтересно, как это так выбор структуры изменит скорость редактирования кода.
Связные списки, например.
Единственное причина использовать эту структуру - быстрая вставка. Которая тут совершенно не нужна.
С чего ты решил, что знаешь какая цель преследуется и как будет использоваться структура меню?
В Вашем прошлом вопросе, Вам ответили сразу два человека, а вместо благодарности огребли наезд с топаньем ногами и истерическим капсом. Так что ЛЕСОМ!
Так что ЛЕСОМ!
да, если нечего высказать по вопросу - лесом, пожалуйста. С капсом и без.
Связные списки, например.
Единственное причина использовать эту структуру - быстрая вставка. Которая тут совершенно не нужна.
С чего ты решил, что знаешь какая цель преследуется и как будет использоваться структура меню?
Понятия не имею, какая цель преследуется. Я рассуждаю с точки зрения рациональности решения. А какая нмркоманская логика привела к рекомендации связанных списков в такой задаче - это для меня темный лес.
да, если нечего высказать по вопросу - лесом, пожалуйста. С капсом и без
Уважаемый, вы прямым ходом движетесь к указателю и последующему бану. Или начинайте вести себя как взрослый человек, или никто не станет тратить на вас время - нет смысла, если вас не сегодня-завтра забанят...
Во-всяком случае, я пока от ответа на ваши вопросы воздержусь.
Понятия не имею, какая цель преследуется. Я рассуждаю с точки зрения рациональности решения.
Ты просто хочешь всегда казаться истиной в последней инстанции. Вот и всё. Это в каждом твоем выступлении (по теме и без) сквозит.
Я просто молчу, когда чего-то не знаю, а не выдумываю чушь, как любят делать многие тут.
Согласен, списки для меню не в тему. Я обычно использую массив структур. В структуре есть поля для глубины вложения, указателей на текст данного пункта и функцию отвечающую за динамику - видимость пункта, дополнительный текст и пр. Чисто статические меню почти что не встречаются. Они не удобны.Например в меню настройки параметров куда приятней видеть название параметра и его текущее значение, чем только название.
Согласен, списки для меню не в тему. Я обычно использую массив структур. В структуре есть поля для глубины вложения, указателей на текст данного пункта и функцию отвечающую за динамику - видимость пункта, дополнительный текст и пр. Чисто статические меню почти что не встречаются. Они не удобны.Например в меню настройки параметров куда приятней видеть название параметра и его текущее значение, чем только название.
Эту прелесть еще бы и в PROGMEM запхать какнить. :)
В микроменю вполне себе уживаются и связные списки и PROGMEM без загонов насчёт быстрых вставок.
https://github.com/abcminiuser/micromenu-v2/blob/master/MicroMenu.h
В микроменю вполне себе уживаются и связные списки и PROGMEM без загонов насчёт быстрых вставок.
https://github.com/abcminiuser/micromenu-v2/blob/master/MicroMenu.h
Спасибо. Я то себе сделал, сначала строки в прогмем загоняю, потом список структур с указателями на них, но дюже неудобно и нечитабельно, а в макросы я играть не умею.
Согласен, списки для меню не в тему. Я обычно использую массив структур.
массив структур списку не противоречит. Вот мой простенький вариант - с точки зрения синтаксиса - массив структур в ПРОГМЕМ, с точки зрения логики - связанный список.
http://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/sozdanie-mnogourovnevogo-graficheskogo-menyu#comment-530028
сначала строки в прогмем загоняю, потом список структур с указателями на них, но дюже неудобно и нечитабельно
мне тоже не понравилось микроменю тем что громоздко и нечитабельно, я его переделал нагляднее и проще :)
Согласен, списки для меню не в тему. Я обычно использую массив структур. В структуре есть поля для глубины вложения, указателей на текст данного пункта и функцию отвечающую за динамику - видимость пункта, дополнительный текст и пр. Чисто статические меню почти что не встречаются. Они не удобны.Например в меню настройки параметров куда приятней видеть название параметра и его текущее значение, чем только название.
Эту прелесть еще бы и в PROGMEM запхать какнить. :)
Запихуется. Но не всегда запихиваю. Там жеж самих строк нет, занимают не так и много. А вот строки - те да, те PROGMEM
Запихуется. Но не всегда запихиваю. Там жеж самих строк нет,
я в структуру разом положил все - и строчки, и указатели, и номера пунктов. И все в ПРОГМЕМ
мне тоже не понравилось микроменю тем что громоздко и нечитабельно
Вот-вот. Поэтому я тоже лисапед изобрёл, но выкладывать никуда не стал, ибо за код мучительно стыдно, хоть и менее громоздко, но тоже нечитабельно. :) А я люблю "академический" код, который говорит сам за себя даже с минимумом комментариев :)
я в структуру разом положил все - и строчки, и указатели, и номера пунктов. И все в ПРОГМЕМ
Огорчу тебя, в ПРОГМЕМ у тебя указатели на строчки, а сами строчки -> в ОЗУ.
Если код остался этот http://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/sozdanie-mnogourovnevogo-graficheskogo-menyu#comment-530028
Огорчу тебя, в ПРОГМЕМ у тебя указатели на строчки, а сами строчки -> в ОЗУ.
Если код остался этот
код, этот, да.
А чего строчки не в ПРОГМЕМ - посмотри внимательно. там выше сама структура описана - она вся в ПРОГМЕМ, разве нет? строчки не ссылками, а константы с заранее описанным размером. Или надо на строку отдельно еще один квалификатор ПРОГМЕМ ставить?
НЕТ
const char[] сам по себе строки в прогмем не пхает. Структура да, она у тебя вся в прогмем, со всеми указателями, только указатели эти указывают на ОЗУ, там где сопсно строки и лежат.
Для другого надо сначала строки в прогмем запхать
const char txt_MenuItem1[] PROGMEM = "Menu Item1 Text";
а потом уже в структуре с ними указатель связывать.
struct TMenuItem {
__FlashStringHelper__ ItemText;
.
.
}
const TMenuItem Item1 PROGMEM = {txt_MenuItem1,...};
Для другого надо сначала строки в прогмем запхать
const char txt_MenuItem1[] PROGMEM = "Menu Item1 Text";
а потом уже в структуре с ними указатель связывать.
это мерзко и разрушает всю идею. Мне это не подходит. Надо придумать что-то другое :)
это мерзко и разрушает всю идею. Мне это не подходит. Надо придумать что-то другое :)
Почему я и говорю, что получается некрасиво. :) Я - за красивый ко(д/т).
это мерзко и разрушает всю идею. Мне это не подходит. Надо придумать что-то другое :)
Мои опыты вроде как показывали, что поведение массива, описанного в PGM-структуре ничем не отличается от поведения массива описанного отдельно с квалификатором PROGMEM.
Дед просто думает, что в структуре указатель, но это не так. Я тоже постоянно забываю, как правильно надо объявлять, когда месяца три этот прогмем не трогаю.
Дед просто думает, что в структуре указатель, но это не так.
если в структуре стоит строка, то это и есть указатель. Возможно, я крепко ашыбаюсь, пусь взрослые подскажут. :)
А можно мне на код глянуть?
А давайте, как настоящие анжинеры, просто палкой по прогмему хрястнем и посмотрим, что выйдет:
//#define ASCIIZ_AS_ARRAY
#define ASCIIZ_AS_ARRAY
А можно мне на код глянуть?
код по ссылке из #25
Гри, дело в том, что const char[12] и const char[] это разные типы данных, первый - известной длины и относится к типам-значениям, он может храниться в PROGMEM вместе со структурой, а второй тип данных, для компилятора - неизвестной длины, а неоднозначности он не терпит, поэтому второй тип ни что иное как const char * известной длины, что ничему не противоречит. Поэтому в первом случае структура хранит в себе весь массив как набор байт, а во втором - только указатель. Можешь распечатать sizeof(listUsr_t) в первом и во втором случае.
Но, согласись, для меню фиксированный массив это оверхэд.
Гри, дело в том, что const char[12] и const char[] это разные типы данных, первый - известной длины и относится к типам-значениям, он может храниться в PROGMEM вместе со структурой, а второй тип данных, для компилятора - неизвестной длины, а неоднозначности он не терпит, поэтому второй тип ни что иное как const char * известной длины, что ничему не противоречит.
Деда, если мы обсуждаем код по моей ссылке - там-то как раз массив известной длины:
И я не случайно его так описал - а именно с целью того, чтобы он весь упихался в прогмем.
Если он в ПРОГМЕМ и флеша хватает - какая разница? - зато код проще и нагляднее
А давайте, как настоящие анжинеры, просто палкой по прогмему хрястнем и посмотрим, что выйдет:
и это правильно :) сам собирался проверить, но вечером. на работе ардуины нет.
Спасибо
Деда, если мы обсуждаем код по моей ссылке - там-то как раз массив известной длины:
И я не случайно его так описал - а именно с целью того, чтобы он весь упихался в прогмем.
Ну так я ж слепой, прошу пардону. Паду, полью лысину воткой.
Но, согласись, для меню фиксированный массив это оверхэд.
А я не спорю с этим. Мое замечание касалось реализации с интегрированным в структуру массивом. А рационально это или нет - решать тому, кто пользуется. К примеру для менюшек на LSD - это очень даже и плюс. Сразу определил 17 (или 21) символ в массиве и лепишь туда строки с пробелами. При выводе они ещё и почистят весь мусор на экранчике.
..а если этот текст в массив засунуть, и вынести в отдельный файл .h , то можно в кирилице от гребаного юникода избавится. Но редактировать в ИДЕ не получится. Вот где экономия :-) Ещё в вывод текста на экран дописал функцию вывода из progmem из массива по заданному индексу... Ляпота.
А я не спорю с этим. Мое замечание касалось реализации с интегрированным в структуру массивом. А рационально это или нет - решать тому, кто пользуется. К примеру для менюшек на LSD - это очень даже и плюс. Сразу определил 17 (или 21) символ в массиве и лепишь туда строки с пробелами. При выводе они ещё и почистят весь мусор на экранчике.
Ну всё, извините, парни, это я идиот, ляпнул не разобравшись. Буду внимательней впредь.
Огорчу тебя, в ПРОГМЕМ у тебя указатели на строчки, а сами строчки -> в ОЗУ.
Если код остался этот http://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/sozdanie-mnogourovnevogo-graficheskogo-menyu#comment-530028
Да, нет, всё там в прогмем. Проверить легко. Компилируем вот так:
Теперь компилируем вот так:
Как видишь, расход ОЗУ не изменился, а расход прогмем изменился на 3160 - 2548 = 612 байтов, т.е. в точности на 18 * sizeof(menuItem)
Ох, сорри, пока писал, тут уже всё и без меня разрулилось. Сорри.