Существует множество библиотек графического интерфейса для микроконтроллеров и встраиваемых систем, но многие из них имеют ограниченный функционал, сложность в использовании и интеграции, необходимость обязательного использования внешней оперативной памяти, а некоторые стоят больше, чем ваш проект целиком. Из-за этих причин и многих других было решено писать свою библиотеку.


Назвал я её MakiseGui.





Перед началом разработки я поставил себе цели:


  • Простота конечной разработки. Писать интерфейс не должно быть сложнее, чем используя WindowsForms и тп
  • Простота интеграции. Встроить и запустить интерфейс в приложении должно быть максимально просто на любом железе или ПО.
  • Чистый Си. Был использован только gnu-c99 и из библиотек только stdlib
  • Минимальное потребление RAM. Возможность использования на средних микроконтроллерах без внешней памяти(примерно 40kb с цветным дисплеем 320х240).
  • Достаточное количество графических элементов для комфортной разработки. Простое добавление новых.
  • opensource лицензия и бесплатное использование даже в коммерческих проектах

Пример без объяснений.


В качестве демонстрации возможностей библиотеки и примеров использования может быть использован проект созданный специально для этих целей: https://github.com/SL-RU/MakiseSDLTest


Он использует SDL2 для отрисовки и ввода и имеет примеры использования всех элементов и почти всех функций системы. Может быть скомпиллирован и запущен на любом linux дистрибутиве. На windows тоже, но лишь теоретически — сам не пробовал.


Видео работы:



Структура


image


Библиотека состоит из трёх чётко разделённых частей:


1) Ядро. Ядро состоит из интерфейса к драйверу, функций отрисовки в драйвер и функций отрисовки примитивов в буфер.


2) Драйвер. Драйвер обеспечивает всё общение с железом и с ПО, поэтому под каждую задачу придётся писать обычно свой, чтобы учесть все моменты(DMA, прерывания и тд). Драйвер лишь обеспечивает передачу изображения из буфера на железо и очищает буфер изображения. Как примеры, в проекте есть драйверы для дисплея на ili9340, а так же SDL2 для отладки библиотеки на компьютере. Ядро и драйвер могут работать отдельно, без GUI.


3) Сам GUI. Занимает бОльшую часть системы, тут воплощены все необходимые функции для работы интерфейса: контейнеры, элементы, системы отрисовки, фокуса, ввода, обработки событий и прочего.


GUI


Разработка графического интерфейса максимально приближена к объектно-ориентированному для максимальной простоты конечного программирования. Благодаря этому она имеет некоторые приятные особенности


Простейший пример, создающий кнопку на экране:


MHost host; //базовая структура системы, root-контейнер, содержащий все другие контейнеры и элементы.

//метод будет вызыван при нажатии на кнопку
void click(MButton *b)
{
    printf("Button was clicked"); //выводим сообщение в стандартный поток
    b->text = "Clicked!"; //меняем текст кнопки

}
MButton button; //структура, содержащая всю информацию о кнопке
void create_gui()
{
    //создаём кнопку
    m_create_button(&button, //указатель на структуру кнопки
        host->host, //контейнер, в который будет добавлена кнопка после создания. В данном случае это контейнер MHost'a
        mp_rel(20, 20, //координаты элемента относительно левого верхнего угла
               90, 30), //ширина, высота
        "Click me",   //текст кнопки
        //События
        &click, //Вызывается при нажатии на кнопку
        0, //Вызывается до обработки нажатия, может прервать обработку нажатия
        0, //Вызывается при действиях с фокусом кнопки
        &ts_button //стиль кнопки
    );
}

void main()
{
    //тут была инициализация MakiseGui, драйвера, MakiseBuffer и MHost. Запуск драйвера.
    create_gui();
    while(1)
    {
        //драйвер вызывает функции рисовки
        //совершается ввод
        //и логика
    }
}

Итого, этот пример создаёт на экране кнопку при нажатии на которую в стандартном потоке вывода появится надпись "Button was clicked" и текст кнопки изменится.


Инициализация


Инициализация предполагает только лишь запуск драйвера, задание размеров и выделение памяти для структур и буферов элементов. Чисто формальная операция. Как инициализировать систему можно поглядеть тут: https://github.com/SL-RU/MakiseSDLTest/blob/master/src/main.c в методе start_m();


Для начала использования GUI нужно создать makise_config.h и сконфигурировать его. В этом файле задаются системные дефайны и выбираются нужные драйверы дисплея. https://github.com/SL-RU/MakiseSDLTest/blob/master/makise_config.h


Ввод


Ввод приспособлен для работы в мультипоточных приложениях — он имеет очередь событий, которые посылаются интерфейсу при вызове makise_gui_input_perform(host);


Любое событие ввода представлено структурой MInputData.


Возможен ввод кнопок(список стандартных в makise_gui_input.h MInputKeyEnum), символов(пока нигде не используется) и ввод курсора(сенсорный экран или мышь). В примере с SDL используется ввод с клавиатуры и ввод мышью.


Контейнеры.


MContainer — структура контейнера.


Контейнеры содержат связанный список элементов. Из контейнеров можно удалять или добавлять элементы, перемещать их и совершать другие операции.


Позиция элемента в контейнере прямо влияет на очередь отрисовки и ввода.


Линкованый список осуществляется при помощи указателей на первый и последний элемент списка MElement и в структуре MElement имеются указатели на следующий и предыдущий элемент.


Элементы.


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


На данный момент существуют следующие элементы:


  • MButton — кнопка. Которая отображает текст посылает события при нажатии
  • MCanvas — простейший контейнер, который просто содержит элементы.
  • MLable — простейшее текстовое поле
  • MTextField — текстовое поле, поддерживающее перенос слов и переносы
  • MSlider — слайдер
  • MToggle — кнопка имеющая два состояния.
  • MSList — список. Может быть как просто списком, так и radio-кнопками, так и чекбосками. Поддерживает обычные списки и динамические линкованные.
  • MTabs — вкладки. Несколько переключаемых контейнеров.

Лучшей документацией являются примеры, поэтому для каждого элемента есть свои примеры использования. Как сложные, так и простые.


Количество элементов будет пополняться со временем. Да, тут нет многих необходимых функций — графики, изображения и тд. Но для моих целей они пока не нужны, но если вскоре понадобятся, то буду добавлять и публиковать в библиотеку. Так же не стесняйтесь добавлять свои или править существующие! Пулл-реквесты приветствуются.


Стили


Стиль элемента определяет его внешний вид. Cтиль задаёт цвета элемента в определённом состоянии. За это отвечают структуры MakiseStyle и MakiseStyleTheme. MakiseStyle содержит несколько MakiseStyleTheme для определённых состояний, а так же параметры шрифта.


Для кнопки стиль может выглядеть так:


MakiseStyle ts_button =
{
    MC_White,  //основной цвет. Не несёт никакого значения
    &F_Arial24,//Шрифт стиля
    0, //межстрочное расстояние
    //цвет заднего фона | шрифта   бортик    есть ли двойной бортик
    {MC_Black,           MC_Gray,  MC_Gray,  0     }, //когда кнопка не активна
    {MC_Black,           MC_White, MC_White, 0     }, //нормальное состояние
    {MC_White,           MC_Green, MC_White, 0     }, //в фокусе
    {MC_Green,           MC_White, MC_White, 0     }, //когда была кликнута
};

Фокус


Фокус определяет к какому элементу пойдёт ввод. Для управления фокусом существуют следующие функции:


MFocusEnum makise_g_focus(MElement *el, MFocusEnum event); //фокусирует или расфокусирует нужный элемент
MFocusEnum makise_g_host_focus_next(MHost *host);//переведёт фокус на следующий по очереди элемент
MFocusEnum makise_g_host_focus_prev(MHost *host);//на предыдущий

Пример работы на микроконтроллере


Так же был написан пример библиотеки для STM32 микроконтроллеров. Был использован МК STM32f437VGT6 с тактовой частотой 180МГц и 2.2" дисплей 230х320 пикселей на контроллере ILI9341. Управления с компьютерной клавиатуры по UART.


Код примера: https://github.com/SL-RU/MakiseILI9341Test


Видео примера:



Немножко документации есть в репозитории. Но вся основная документация находиться в комментариях к функциям и в примерах. Задавайте вопросы! На основе них я буду дописывать документацию. Много моментов не было затронуто в статье или затронуто мимоходом. Если статья найдёт популярность, то с удовольствием напишу ещё несколько, например про создание драйвера для STM32 + tft дисплей, подключенный по FSMC для данного GUI.


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


Лицензия проекта — MIT. Вы можете использовать библиотеку и исходный код как хотите и где хотите, даже использовать без проблем в коммерческих проектах, но в то же время я не даю никаких гарантий по работе библиотеки — всё как есть.


Если вы что-то хотите поменять в коде, исправить найденный баг или ошибку, то пишите в issue в репозитории или даже кидайте пуллреквесты.


Буду рад вопросам и пожеланиям!

Поделиться с друзьями
-->

Комментарии (57)


  1. krocos
    16.04.2017 00:03
    +7

    ЭльПсиКонгру!


    1. perfect_genius
      16.04.2017 17:57

      «Укрепляй разум»


  1. inoxcrom
    16.04.2017 00:19
    +1

    Спасибо!


    1. SL_RU
      16.04.2017 00:20

      Рад, если она поможет вам! ^^


  1. Taciturn
    16.04.2017 00:27
    +6

    Жаль что пример выполнен не на микроконтроллере микроволновки.


  1. SL_RU
    16.04.2017 00:41

    Можете подсказать, на какие зарубежные ресурсы можно выложить эту статью?


    1. Sirikid
      16.04.2017 01:10
      +1

      reddit


      1. KonstantinSpb
        16.04.2017 18:34

        +1 и на форумы ST, Arduino, Hackerday
        GUI хорошо было бы иметь в GRUB2


    1. cybersonner
      16.04.2017 19:48

      hackaday.com
      dangerousprototypes.com


  1. artyfarty
    16.04.2017 01:49
    +1

    Жаль что не про AI, тут бы название ироничнее было (речь о линии сюжета S;G 0)


  1. golf2109
    16.04.2017 03:14
    +1

    Спасибо, очень интерестная работа.
    Очень не хватает возможности вывода картинок и графиков.


  1. ryo_oh_ki
    16.04.2017 08:24
    -6

    а некоторые стоят больше, чем ваш проект целиком

    Интересно, а сколько стоила разработка вашего проекта (взяв среднюю цену работы системного программиста в час по отрасли)?


    1. SL_RU
      16.04.2017 13:21

      Именно этой библиотеки? Ноль — я её писал для будущих своих коммерческих проектов в свободное от работы и учёбы время.


      1. Revertis
        16.04.2017 15:27
        -5

        Плохо, что цена вашего свободного времени ноль :-/


        1. SL_RU
          16.04.2017 15:49

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


        1. veydlin
          16.04.2017 17:13
          +4

          Цена свободного времени — полученный опыт


        1. AllexIn
          16.04.2017 23:10
          +1

          Цена этого потраченного времени заложена в стоимость будущих работ.
          Например, нейрохирург получает тысячи долларов за одну операцию, потому, что обучить его было очень дорого. И стоимость этого обучения заложена в стоимость операций им проводимых.
          Здесь тоже самое.
          Обучение делается «в кредит» будущей работы.


        1. Juralis
          16.04.2017 23:17
          +3

          Боюсь себе представить, сколько стоило написание вашего комментария.


          1. ryo_oh_ki
            17.04.2017 06:40
            -1

            :) 57 руб (потратил примерно 10 минут). И странно, что вопросы про рабочее время вызывают такую реакцию… Знать, чего ты стоишь ведь очень полезно в профессиональном плане.


            1. Siemargl
              17.04.2017 09:27
              +2

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

              Если ты не банкир или «менеджер», фу.

              И сильно противоречит духу опенсорса.


              1. ryo_oh_ki
                17.04.2017 18:15

                Наоборот, считать деньги очень полезно. В любом проекте есть экономическая составляющая (см. свой диплом), и трезвая оценка своих сил поможет даже с «бесплатными» проектами.

                Ты же не будешь кодером до пенсии, рано или поздно будешь руководить (официально или нет) группой/отделом/компанией и будешь совмещать свои профессиональные обязанности с обязанностями «менеджера».

                Опенсорс не мешает зарабатывать, скорее наоборот. :-)


                1. Siemargl
                  17.04.2017 18:37

                  Ты же не будешь кодером до пенсии, рано или поздно будешь руководить (официально или нет) группой/отделом/компанией и будешь совмещать свои профессиональные обязанности с обязанностями «менеджера».
                  А если дальше пойти?

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

                  И бросить мыслить категориями — сколько стоит погладить жену =)


            1. Juralis
              17.04.2017 10:40
              +3

              А как вы это подсчитали? Если вы как программист оцениваете стоимость своих 10 минут в 57 рублей (что-то около 60 тысяч в месяц?), то это же вовсе не значит, что кто-то вам заплатил бы эти же деньги за написание комментариев на хабре. Почему вы думаете, что рыночная стоимость комментария тут 57 рублей?
              Да и чёрт с ним. Вы с друзьями общаетесь с такими же мыслями? Не завидую им. И вообще, вашим близким.
              Строго говоря, ваше время бесценно на столько же, насколько бесценна сама ваша жизнь. А если рассуждать вашей логикой, то можно просто взять, умножить вашу цену на потенциальный максимальный трудовой стаж. Судя по профилю, вам 42 года. До пенсии вам осталось что-то около 23 лет. За это время работая 8 часов по будням вы заработаете около 17 мруб. После этого будете получать ещё пенсию. В зависимости от того, сколько вы проживёте и сколько будете работать после выхода на пенсию, вы сможете получить ещё примерно столько же. И так, получается, что стоимость оставшейся вашей жизни будет составлять примерно 35 мруб. Теперь вы знаете «чего вы стоите в профессиональном плане». Наверное это действительно полезно. Да вот какая странность. Эта стоимость совершенно не учитывает, ни то, какой вы муж, ни то, какой вы отец, ни то, как любит вас собака, если она у вас есть. Хотя, с таким подходом, наверное у вас её нет. Ведь почесать её за ухом будет стоить для неё десять рублей. Вы же профессионал.
              Ладно. К чему бы это я? К тому, что человек сделал нечто хорошее (библиотеку) и поделился этим со всеми. У него наверное просто есть какие-то другие меры своей ценности. В комментариях была указана стоимость его работы. И как мне кажется, она на несколько порядков выше вашей.


              1. ryo_oh_ki
                17.04.2017 18:22

                Какое витиеватое оскорбление. :-) Спасибо!


      1. KislyFan
        16.04.2017 15:47
        +1

        посчитать то можно, проблема в том, что часто «в свободное от работы и учёбы время» посчитать затруднительно. Сегодня я работаю над проектом три часа, завтра один час, послезавтра ни одного. А в субботу пошел дождь, поэтому я остался дома и писал код весь день с перерывами на еду. В итоге трудозатраты можно оценить лишь косвенно по количеству строк.


      1. ryo_oh_ki
        16.04.2017 16:12
        -1

        Я спрашивал про метрики, про кол-во кода помноженную на среднюю ставку программиста способного написать такое системное ПО.


        1. SL_RU
          16.04.2017 16:16
          +1

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


          1. ryo_oh_ki
            16.04.2017 16:27
            -1

            Я сам прикинул :-) Получается примерно 22 000 строк (если считать весь код оригинальным), ~ 5 чел/лет, и если оценивать по скромным зарплатам в РФ, то около 5 млн. руб. Если за рубежом, то ~ $256 000.


            1. Quiensabe
              16.04.2017 22:28
              -1

              При рабочем дне 6 часов, это получается одна строка в 24 минуты… Вдумчивое программирование :)


              1. ryo_oh_ki
                17.04.2017 06:33
                +2

                Эх, если б программирование заключалось только в механической печати строк текста на клавиатуре… :)


            1. grossws
              17.04.2017 01:51

              А откуда вы пять человеко-лет взяли? 22k строк при нормальной производительности в 100 строк в день (в предположении, что количество бойлерплейта там более-менее среднее, что для библиотеки такого рода на Си вполне вероятно) вполне укладывается в ~11-12 человеко-месяцев.


              1. ryo_oh_ki
                17.04.2017 06:36

                Не всё так просто, чем больше проект тем труднее идёт дописывание нового кода, медленнее тестирование, больше отладки. Программа же должна не только быть напечатана, но и заработать.


                1. grossws
                  17.04.2017 12:44

                  Судя по https://www.openhub.net/p/MakiseGUI основной объём был добавлен в интервале последних 3-4 месяцев. Ну и оценка в 100 строк на Си в день — это с учётом отладки.


                  Естественно производительность может быть меньше на порядок в более низкоуровневых кусках: со сложным flow на прерываниях, dma и прочими радостями, разбором сложных протоколов взаимодействия со сторонней аппаратурой (настройка того же fsmc).


                  Но такого рода библиотека (основная её часть) — обычная аппаратно-независимая работа с данными и простым буфером в памяти, так что оценка была сделана такая.


                  Не подумайте, что я обесцениваю работу SL_RU. Если дойдут руки попробовать, то я не поленюсь дополнить документацией и багфиксами.


              1. APaMazur
                17.04.2017 06:58

                Все зависит от стадии проекта
                На начальной показатель высокий, потом низкий
                Если весь проект 22к строк, то дорасти до 22 от 20 может быть те самые оставшиеся 4 года


  1. Error1024
    16.04.2017 10:00
    +2

    Как происходит отрисовка? Каждый раз перерисовываеться все или библиотека умеет определять необходимый регион перерисовки?


    1. SL_RU
      16.04.2017 13:07

      Каждый раз всё с нуля, да. Можно вручную поменять регион перерисовки.
      Но в планах сделать автоматическое определение. Но это в планах — пока не особо нужно.


      1. Error1024
        16.04.2017 13:12
        +2

        Имхо это должно быть фичей с самым высоким приоритетом, иначе сколько-нибудь сложный интерфейс будет отнимать много времени у CPU(а это и быстрая разрядка батарей) и даже подтормаживать.
        Насколько я понимаю поддержки полупрозрачных контролов нет пока, это сильно упрощает задачу по отрисовке только необходимых контролов.


        1. SL_RU
          16.04.2017 13:17

          Да, это важная штука, но для моей задачки она пока не сильно требовалась, а времени на разработку ушло бы много.
          Прозрачные цвет есть, а полупрозрачных нет. В стиле можно задать в любом месте MC_Transparent и тогда эта деталь(бэкграунд, обводка, шрифт и тп) просто не будет рисоваться — не будет тратить ресурсы.


  1. ValdikSS
    16.04.2017 13:30

    Что за дискач на 3:20 последнего видео? Железная проблема?


    1. SL_RU
      16.04.2017 13:33

      Просто дисплей так рисует серый цвет и другие — эмулирует 16битную палитру. На глаз не заметно — только на камеру.


      1. ValdikSS
        16.04.2017 13:44
        +1

        Больше похоже на плохо настроенный Vcom, а не на dithering.


        1. SL_RU
          16.04.2017 13:48

          Не, питание чистейшее и в жизни не заметны ни моргания подсветки, ни пикселей — к тому же на видео пиксели не мерцают, а дёргаются.


          1. ValdikSS
            16.04.2017 13:50
            +5

            Неправильно настроенный Vcom выглядит так:
            image
            Это похоже на то, что в вашем видео.


            1. SL_RU
              16.04.2017 13:55

              Хм, хорошо. Я покапаюсь регистрах на эту тему. Спасибки за замечание.


  1. Alex_ME
    16.04.2017 14:42
    +1

    Очень заинтересовался вашим проектом. В одном разрабатываемом устройстве нужен дисплей и делаем какое-то подобие GUI библиотеки, но пока там просто куча говнокода и из контроллов — кнопка. Правда, дисплей (как раз ili9340) подключен по SPI (увы) и полное обновление занимает кучу времени.


    1. SL_RU
      16.04.2017 15:00

      А кучу — это сколько? Для гуи ведь не нужны 24фпс, достаточно лишь чтобы действия были отзывчивыми. Но даже на stm32f103c8t6 на тактовой частоте 72мгц гуй работал очень даже прилично — был совершенно юзабелен.

      Так-то есть лишь одно решение — обновлять лишь необходимые части. Но механизма для этого в библиотеке нет — только если делать вручную…


      1. Alex_ME
        16.04.2017 22:44

        У Вас как реализована работа с дисплеем? FSMC?


        Я ошибся, у нас не SPI, а 8-битный 8080 интерфейс. Очистка экрана занимает… ну секунду и невооруженным взглядом видно, как он стирается строчка-за строчкой. Понятное дело, что каждый раз при переключении кнопки такое делать — неприемлимо.


        1. SL_RU
          16.04.2017 22:56
          +1

          DMA + SPI

          Что-то жестоко — секунда 0_0
          Вы на каком МК это делаете? Не эмулируете ли случаем 8080 на GPIO? На 8080 можно обновлять хоть на всех 60фпс дисплей, если использовать хардварный интерфейс с DMA…


          1. Alex_ME
            16.04.2017 23:36

            STM32 F107VCT6. Была непонятная noname библиотека, в которой даже работа с GPIO была через странную абстракцию и было еще дольше. Переписал на чистый GPIO — стало несколько быстрее, но не сильно вникал в детали. Почему-то казалось, что у дисплея ограничение на тайминги при передаче.
            Спасибо за наводку, попробую ускорить.


            1. SL_RU
              16.04.2017 23:41

              Вот, нашёл статью об этом: https://habrahabr.ru/post/278967/ 11мс на заливку. Так же рекомендую почитать официальные APPNOTE на тему подключения дисплеев по 8080


              1. Alex_ME
                16.04.2017 23:51

                Большое спасибо! Я правильно понимаю, что Вы сначала отрисовываете в буфер в памяти, а потом сгружаете на экран?


                1. SL_RU
                  16.04.2017 23:54

                  Агась, MakiseBuffer->buffer — это первичный буфер, в который рисует гуй. Так же ещё есть опциональный второй буфер MakiseDriver->buffer для драйвера — он не обязателен.


      1. Dima_Sharihin
        18.04.2017 11:55
        +1

        Чтобы делать полноценную сверхбыструю (средствами SPI DMA) перерисовку экрана для ILI9341, то нужно хранить кусок результата (самое простое — весь экран) в оперативной памяти.
        У STM32F103C8T6 оперативки аж 20 килобайт, из которых нужно оставить для бизнес-логики и RTOS. На весь экран нужно куда больше ОЗУ.
        Таким образом экранчик ILI9341 придется перерисовывать в 6-7 проходов. И код рендеринга изначально писать под фреймбуфер произвольного размера, меньшего размеру экрана


  1. Vadimatorikda
    16.04.2017 20:37
    +1

    Одного лишь названия библиотеки хватило, чтобы я обратил на нее свое внимание… Ну это все лирика. Временами на хабре появляются подобные статьи, где люди показывают нечто подобное. Но ваш уровень мне понравился больше. Честно, на код пока не смотрел, но демо понравилось, а так же стиль работы с GUI, похожий на библиотеку QT. Задам вам сейчас несколько «вопросов от новичка»:
    1.1 Рассчитана ли библиотека на монохромные экраны? Например, часто применяемые 128x64.
    1.2 Имеется ли возможность рисования без буфера для монохромных экранов (в случае их поддержки)?
    1.3 Имеется ли возможность выбора между отрисовкой с использование буфера и без него для монохромных экранов (в случае их поддержки)?
    2.1 Какого рода требуется драйвер для цветного дисплея? Имеется ввиду, библиотеке рисования просто требуется поставить указатель на нужный пиксель строки/столбца LCD и после передать N пакетов, содержащих в себе цвета пикселей (массив цветов пикселей) из буфера, или будет требоваться по пиксельное обращение к буферу экрана?
    2.2 В дополнение к предыдущему вопросу: отрисовка идет сразу готовой сформированной (или формирующийся динамически между передачами) картинки (драйвер просто копирует из буфера мк в буфер LCD) или же отрисовка идет по-элементно: сначала прямоугольник кнопки, потом внутри него текст и т.д.
    2.3 Есть ли возможность создать const связанный список на этапе компиляции, а потом просто подставлять нужный список для отрисовки? Например, у меня 3 меню, все положения и т.д. заранее известны. Меняются только значения и такст. Я могу сделать const связанный список, который будет содержать указатели на изменяемые данные (которые будут динамически обновляться при каждой перерисовке)?
    Чтобы было более понятно: очень много модулей мк в моих проектах (на CPP), работают на constexpr. Например. При условии, что GPIO никогда не меняют своих настроек в процессе работы (1 линия — 1 режим работы), я использую constexpr функции, которым скармливаю конфигурации каждого вывода, а на выходе получаю просто массив uint32_t переменных, которые в реальном времени (времени выполнения) копирую в выбранные GPIO.
    Возможно ли нечто подобное в вашей библиотеке? Например, создаю объект (или структуру) описания одного окна, потом, если нужно, добавляю в него ссылки на другие окна, все это во время компиляции вычисляется и создается const структуры, которыми потом будет оперировать библиотека в реальном времени.


    1. SL_RU
      16.04.2017 21:11
      +1

      1.1) Да, рассчитана. На самом деле библиотека и произошла, хоть и пройдя долгий путь развития, от прошлой библиотеки для 128х64 дислея. (кусок работы запечатлён тут. Там тоже были кнопочки и прочие элементы, ноо работа была с ними на совсем примитивном уровне.)
      1.2) Да, отрисовка происходит за раз, поэтому можно сразу из системного буфера гнать данные на экран.
      1.3) Не совсем понял этот вопрос… Первый буфер, в который рисуют всё методы отрисовки примитивов обязателен, а второй, используемый только драйвером — не. Например драйвер SDL его и не использует.
      2.1) Драйвер лишь должен инициализировать дисплей и отправлять данные из первичного буфера на экран. Единственное дополнительное, что может потребоваться — преобразовывать цвета, если битность первичного буфера не совпадает с той, что необходима дисплею(например для экономии РАМы и тп). А так да, достаточно скормить дисплею данные с указателя.
      2.2) ГУЙ рисует в свой буфер(в первичный) за один проход, который просто потом использует драйвер. Драйвер может скопировать его, а может и нет.
      2.3) Конечно можно — всё сделано через структуры в которые можно тупо скопировать необходимые данные по указателю, но это будет значительно сложнее, чем написать просто функцию инициализации.


  1. Vadimatorikda
    17.04.2017 08:54

    Планируете ли вы добавить в библиотеку такие объекты как: график (по точкам из массива), диаграммы (так же из массива), эквалайзер. Просто я планирую использовать последний в своем проекте. Посмотрев демо-видео конечно пришла очень страшная идея: сделать на каждую «палку» эквалайзера по вертикальному статус-бару, но 100 статус баров (для простого эквалайзера на OLED дисплее) — это очень страшно)))


    1. SL_RU
      17.04.2017 09:33

      Планирую, но вы можете сделать это и сами)
      Процесс создания новых элементов достаточно прост — посмотрите на существующие — единственное что нужно — в методе draw элемента написать код отрисовки. =)