Nuklear — это библиотека для создания immediate mode пользовательских интерфейсов. Библиотека не имеет никаких зависимостей (только C89! только хардкор!), но и не умеет создавать окна операционной системы или выполнять реальный рендеринг. Nuklear — встраиваемая библиотека, которая предоставляет удобные интерфейсы для отрисовки средствами реализованного приложения. Есть примеры на WinAPI, X11, SDL, Allegro, GLFW, OpenGL, DirectX. Родителем концепции была библиотека ImGUI.


Чем прекрасна именно Nuklear? Она имеет небольшой размер (порядка 15 тысяч строк кода), полностью содержится в одном заголовочном файле, создавалась с упором на портативность и простоту использования. Лицензия Public Domain.


Веб-демо Nuklear


Постановка задачи


У меня часто возникают задачи, для реализации которых приходится писать мелкие утилитки в несколько сотен строк кода. Обычно в результате получается консольное приложение, которое кроме меня никто толком использовать не может. Возможно, простой GUI сможет сделать эти утилиты более удобными?


Итак, требования к результату:


  1. Малый размер, до сотен килобайт.
  2. Кроссплатформенность, для начала хотя бы Windows и Linux.
  3. Отсутствие зависимости от внешних библиотек в Windows, всё должно быть в одном EXE-файле.
  4. Приличный/красивый внешний вид.
  5. Поддержка картинок в форматах JPG и PNG.
  6. Простота разработки, возможность разработки в Windows и Linux.
    Справится ли Nuklear?

Nuklear NodeEdit


Для примера рассмотрим создание утилиты dxBin2h (GitHub) — она считывает файл побайтово и записывает в виде Си-массива. Кроме основного функционала программа имеет всякие "плюшки", типа удаления ненужных символов и т.п. Обычно ради стороннего функционала и создаются свои маленькие утилиты. Например, dxBin2h создавалась для Winter Novel, для предварительной обработки ASCII-файлов.


Простота разработки, кроссплатформенность


Уж с чем, а с простотой разработки проблем быть не должно. Ведь с прицелом на неё библиотека и создавалась, так? Прямо в Readme на GitHub есть пример. Абсолютно понятные и лаконичные 20 строк кода дают красивый и чёткий результат.


Код примера
/* init gui state */
struct nk_context ctx;
nk_init_fixed(&ctx, calloc(1, MAX_MEMORY), MAX_MEMORY, &font);

enum {EASY, HARD};
int op = EASY;
float value = 0.6f;
int i =  20;

if (nk_begin(&ctx, "Show", nk_rect(50, 50, 220, 220),
    NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_CLOSABLE)) {
    /* fixed widget pixel width */
    nk_layout_row_static(&ctx, 30, 80, 1);
    if (nk_button_label(&ctx, "button")) {
        /* event handling */
    }

    /* fixed widget window ratio width */
    nk_layout_row_dynamic(&ctx, 30, 2);
    if (nk_option_label(&ctx, "easy", op == EASY)) op = EASY;
    if (nk_option_label(&ctx, "hard", op == HARD)) op = HARD;

    /* custom widget pixel width */
    nk_layout_row_begin(&ctx, NK_STATIC, 30, 2);
    {
        nk_layout_row_push(&ctx, 50);
        nk_label(&ctx, "Volume:", NK_TEXT_LEFT);
        nk_layout_row_push(&ctx, 110);
        nk_slider_float(&ctx, 0, &value, 1.0f, 0.1f);
    }
    nk_layout_row_end(&ctx);
}
nk_end(&ctx);

Но не всё так просто. Часть, отвечающая непосредственно за просчёт GUI действительно проста. Только должен быть ещё и рендер. Идём в папку demo, выбираем понравившийся. И видим уже далеко не 20 строк. Мало того, хотя примеры и рисуют на экране примерно одинаковый результат, но код значительно отличается именно из-за рендера.


Пример инициализации на WinAPI и SDL

WinAPI:


static LRESULT CALLBACK
WindowProc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    switch (msg) {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    if (nk_gdip_handle_event(wnd, msg, wparam, lparam))
        return 0;
    return DefWindowProcW(wnd, msg, wparam, lparam);
}

int main(void)
{
    GdipFont* font;
    struct nk_context *ctx;

    WNDCLASSW wc;
    RECT rect = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT };
    DWORD style = WS_OVERLAPPEDWINDOW;
    DWORD exstyle = WS_EX_APPWINDOW;
    HWND wnd;
    int running = 1;
    int needs_refresh = 1;

    /* Win32 */
    memset(&wc, 0, sizeof(wc));
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = GetModuleHandleW(0);
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.lpszClassName = L"NuklearWindowClass";
    RegisterClassW(&wc);

    AdjustWindowRectEx(&rect, style, FALSE, exstyle);

    wnd = CreateWindowExW(exstyle, wc.lpszClassName, L"Nuklear Demo",
        style | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,
        rect.right - rect.left, rect.bottom - rect.top,
        NULL, NULL, wc.hInstance, NULL);

SDL:


int
main(int argc, char* argv[])
{
    /* Platform */
    SDL_Window *win;
    SDL_GLContext glContext;
    struct nk_color background;
    int win_width, win_height;
    int running = 1;

    /* GUI */
    struct nk_context *ctx;

    /* SDL setup */
    SDL_SetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED, "0");
    SDL_Init(SDL_INIT_VIDEO);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
    win = SDL_CreateWindow("Demo",
        SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN|SDL_WINDOW_ALLOW_HIGHDPI);
    glContext = SDL_GL_CreateContext(win);
    SDL_GetWindowSize(win, &win_width, &win_height);

Отсутствие зависимостей в Windows


Ну хорошо, берём рендером SDL2 с OpenGL и получаем результирующее приложение под Windows, Linux, Mac OS X, Android, iOS и ещё кучу чего! Всё супер, только вот в стандартной поставке Windows библиотеки SDL нет. Значит, придётся тащить с собой. А это нарушает первое требование (малый размер), т.к. сама SDL весит порядка мегабайта.


Зато в списке примеров виднеется GDI+, которая есть в Windows начиная с XP. GDI+ умеет ttf-шрифты, картинки PNG и JPG, и всё это возможно загружать прямо из памяти. Пускай в итоге будет 2 возможных рендера: GDI+ для Windows и SDL для всех остальных случаев. Можно вынести часть кода, зависящую от рендера, в отдельный Си-файл (nuklear_cross.c). Тогда основной код не будет перегружен, и можно будет сфокусироваться именно на интерфейсе, что значительно упрощает разработку. Дополнительным плюсом получаем ускорение компиляции — весь Nuklear будет компилироваться в отдельный объектный файл, который будет редко изменяться.


Windows, отрисовка через GDI+, шрифт Arial 12pt:


dxBin2h GDI+ Arial 12pt


Linux, отрисовка через SDL2 и OpenGL, шрифт по умолчанию:


dxBin2h SDL2 linux stdfont


Приложение выглядит совсем по-разному! И первое, что бросается в глаза — шрифт.


Шрифт


Чтобы приложение выглядело одинаково во всех операционных системах нужно использовать один и тот же шрифт. Можно было бы взять какой-нибудь системный шрифт, который гарантированно есть везде. Но такого шрифта нет. Поэтому шрифт придётся включать в своё приложение. ttf-шрифты обычно весят сотни килобайт, но из них хорошо создаются подмножества с необходимыми символами. Например, с помощью веб-сервиса FontSquirrel. DejaVu Serif ужался до 40kb, хотя и содержит в себе кириллицу, польский и ещё кучу языков.


Всё было бы отлично, но GDI+ драйвер для Nuklear не умел загружать шрифт из памяти, только из файла. Пришлось исправлять… Кстати, шрифт можно включить в своё приложение с помощью той же dxBin2h.


Windows, DejaVu Serif:


dxBin2h Windows  DejaVu Serif


Linux, DejaVu Serif:


dxBin2h Linux DejaVu Serif


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


Картинки: PNG, JPG


И SDL2 и GDI+ умеют загружать картинки. Но для SDL при загрузке JPG и PNG появляется дополнительная зависимость — SDL_image. Избавиться от неё довольно просто: используем stb_image.h, если проект собирается с SDL.


С GDI+ тоже не всё было хорошо. А именно, GDI+ драйвер для Nuklear не умел отрисовывать изображения средствами GDI+. Пришлось вникать в работу с изображениями и реализовывать самому (Pull Request). Теперь всё исправлено и код в официальном репозитории.


Код загрузки изображения через stb_image для OpenGL
struct nk_image dxNkLoadImageFromMem(const void* buf, int bufSize){
        int x,y,n;
        GLuint tex;
        unsigned char *data = stbi_load_from_memory(buf, bufSize, &x, &y, &n, 0);
        glGenTextures(1, &tex);
        glBindTexture(GL_TEXTURE_2D, tex);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
        return nk_image_id((int)tex);
}

Внешний вид приложения


Чтобы изменить вид чекбоксов в Nuklear есть механизм выставления стилей. Здесь включенный и выключенный чекбокс являются отдельными PNG-картинками. В этом же коде же выставляется красная тема из примеров Nuklear (файл style.c):


    nk_image checked = dxNkLoadImageFromMem( (void*)checked_image, sizeof(checked_image) );
    nk_image unchecked = dxNkLoadImageFromMem( (void*)unchecked_image, sizeof(unchecked_image) );

    set_style(ctx, THEME_RED);
    {struct nk_style_toggle *toggle;
        toggle = &ctx->style.checkbox;
        toggle->border = -2; /* cursor must overlap original image */
        toggle->normal          = nk_style_item_image(unchecked);
        toggle->hover           = nk_style_item_image(unchecked);
        toggle->active          = nk_style_item_image(unchecked);
        toggle->cursor_normal   = nk_style_item_image(checked);
        toggle->cursor_hover    = nk_style_item_image(checked);
    }

Приложение в Windows выглядит так:


dxBin2h Windows


В Linux:


dxBin2h Linux


Что в итоге?


  1. Windows EXE после компиляции 200kb, после ужатия UPX 90kb. В Linux из-за использования stb_image размер приложения в среднем на 100kb больше.
  2. Проверена работа в Windows и Linux.
  3. Шрифт и картинки хранятся как массивы в памяти приложения. Зависимостей не от WinAPI в Windows нет.
  4. Движок изменения стиля приложения работает.
  5. PNG и JPG загружаются средствами GDI+ и stb_image.
  6. Весь "грязный" платформенно-зависимый код вынесен в отдельный файл. Разработчик фокусируется именно на создании приложения.

Известные проблемы


  • Различное сглаживание шрифтов в разных операционных системах
  • Разный размер чекбоксов
  • Разная поддержка изображений (при использовании stb_image нужно избегать проблемных изображений)
  • Не полная поддержка юникода при урезанном шрифте
  • Нет примера на технологиях Mac OS X

Как пользоваться наработками


  1. Склонировать репозиторий https://github.com/DeXP/dxBin2h
  2. Скопировать оттуда папку "GUI" в свой проект
  3. Подключить "GUI/nuklear_cross.h", использовать функции оттуда
  4. При необходимости обновления файлов Nuklear скопировать их из официального репозитория поверх текущих.

Заключение


Приложение выглядит немного по-разному в разных операционных системах. Однако отличия незначительны, полученный результат меня удовлетворил. Nuklear не входит в категорию "я уверен, что будет работать везде и без тестирования". Зато входит в категорию "если что будет нужно — легко допишу".


Полезные ссылки



UPD: Добавил веб-демо, теперь на библиотеку можно посмотреть вживую онлайн.

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

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


  1. ilmarin77
    09.01.2017 18:38
    +2

    Вспоминается FLTK


    1. DeXPeriX
      09.01.2017 18:49
      +1

      FLTK написан на С++, а не на Си. Соответственно, будет занимать значительно больше места (примерно +200kb за stdlibc++). Лицензия у него LGPL, а не Public Domain. Но лично меня оттолкнул внешний вид.
      А вообще я бы хотел Qt, но в 100kb :-)


      1. lieff
        09.01.2017 19:16
        +2

        Благодаря си его еще можно например скриптовать tcc. Я его использую в мини аля-флеш плеере, у которого рантайм около 300кб (размер apk увеличивается на 100кб). Причем работает оно на десктопе, телефонах и веб через emscripten. Вот пример nanovg демки, обернутой в эту штуку (специальо для nuklear демки еще не делал).


        1. DeXPeriX
          09.01.2017 23:21

          Nanovg демка выглядит красиво. Есть ли такая же шкура, но натянутая на FLTK?
          Прикольно. Получается, что за счёт emscripten к списку поддерживаемых Nuklear платформ можно добавить и браузеры?


          1. lieff
            09.01.2017 23:39

            Это псевдо-интерфейс вручную нарисованный nanovg (это почти то же что html5 canvas api, возможности те же). В принципе если код демки использовать — натянуть можно много куда, самому nanovg ничего кроме gl\gles не надо.
            Насчет nuklear — да, собственно это уже делали, правда веб демка жаль уже 404, но я видел как она работала)


          1. pascualle
            09.01.2017 23:42

            так точно. Nuklear поддерживает glfw и sdl, а это означает, что с emscripten проблем не будет. я сам увлекаюсь этой технологией, прям магия с --> llvm --> js


            1. DeXPeriX
              09.01.2017 23:48
              +1

              Ну, судя по комменту выше, проблемки всё-таки есть) И с SDL тоже, но они в процессе решения.
              С другой стороны практической ценности всё-равно вижу мало. У меня утилиты почти всегда файловые, а с этим насколько я в курсе у JavaScript проблемы.


              1. pascualle
                09.01.2017 23:54

                насчет sdl не знаю для меня он слишком громоздкий в разрезе emscripten. А вот пример работы с glfw3, все там отлично рабоатет, как пример моя демка http://casualgum.com/test/mun.html
                зачем это? ну все та же мутиплатформенность, например ты сделал тулзовину или приложение, а в веб версии ее демо-версия… навскид идейка


                1. DeXPeriX
                  10.01.2017 00:12

                  Ну у меня уже есть 2 мелкие тулзовины: одна конвертирует файл из одного 3D-формата в другой, а другая по файлу создаёт Си-массив. И той и той нужно читать файлы с диска. И вроде бы emscripten никак не может дать читать файлы с диска пользователя. Это была бы серьёзная дыра в безопасности.
                  А всякие тулзы типа "нарисуй градиент у нас онлайн и сохрани его как PNG" вроде проще сразу под веб и писать. Они ж будут под это заточены...


                  1. pascualle
                    10.01.2017 00:29

                    https://kripken.github.io/emscripten-site/docs/getting_started/Tutorial.html, раздел «Using files» (fopen)


                    1. DeXPeriX
                      10.01.2017 00:31

                      C сервера — да. С компьютера пользователя никак. Но идея ясна. Так действительно можно делать демки. Хотя бы только со своим ограниченным набором файлов.


              1. lieff
                09.01.2017 23:56
                +1

                Через glfw там были какие то минорные проблемы, но в целом все хорошо работало. Собственно из скрипта аля-флеш мультика моего он тоже работает подо всеми платформами винда\линукс\мак\андройд\ios\веб.


                1. DeXPeriX
                  10.01.2017 00:20

                  Так используется именно Nuklear? А какая библиотека была выбрана драйвером, SDL/glfw?


                  1. lieff
                    10.01.2017 00:30

                    В демо что я кинул — только nanovg, но вообще да, в невыложенных «флешках» я использую и nuklear для интерфейса\кнопочек итд. Использую glfw, но это кухня плеера, для скрипта вшитого во «флешку», эти подробности скрыты.


                    1. DeXPeriX
                      10.01.2017 00:40

                      Очень интересно! Были ли какие-то проблемы с переносом именно в веб? Как много времени было потрачено на решение?


                      1. lieff
                        10.01.2017 00:55
                        +1

                        Были, мне пришлось пропатчить emscripten, добавив loadDynamicLibrarySrc для загрузки скрипта из памяти. Т.к. скрипт грузится не из файла, а распаковывается из zip («флешка» это скрипт+ресурсы). Там еще по мелочи #ifdef EMSCRIPTEN, немного js в html чтобы загрузить флешку по линку в контейнер откуда emscripten файлы берет.
                        В целом ничего сложного, за выходные помоему уложился


                        1. DeXPeriX
                          10.01.2017 19:17
                          +1

                          Спасибо за идею, помощь и подсказки. Для примера собрал свою веб-демку Nuklear:
                          https://dexp.github.io/nuklear-webdemo/
                          Уже добавлена в публикацию.


                          1. lieff
                            10.01.2017 23:45

                            Всегда пожалуйста)


      1. ilmarin77
        09.01.2017 20:02
        +1

        Зато развивается он с 98 года:


        1. DeXPeriX
          09.01.2017 23:31

          Старое не всегда значит хорошее. Мне нравится примеры кода FLTK. Код красивый и лаконичный. По сути претензия к FLTK у меня только одна — ужасный и устаревший внешний вид. Если FLTK имеет хорошую кроссплатформенную поддержку скинов, то я готов пересмотреть своё решение. Иначе увольте. Такие интерфейсы делать в 2017 году считаю моветоном.


          1. MooNDeaR
            10.01.2017 11:38
            +1

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


            1. DeXPeriX
              10.01.2017 11:41

              Возможно. Только вот поддержка скинов в Nuklear полноценна (пруф. на гитхабе, нижние скрины красивее).


  1. SL_RU
    09.01.2017 20:42

    Получается можно её использовать во встраиваемых системах на чистом железе, на микроконтроллерах?


    1. V1RuS
      09.01.2017 21:30

      Угу, только рендер свой написать.


      1. SL_RU
        09.01.2017 21:57

        Миленько :3
        Просто сейчас тоже разрабатываю библиотеку ГУЯ, но ориентируюсь только на МК.


        1. Error1024
          09.01.2017 22:02

          Для рисования на совсем слабых контроллеров могу свою либу посоветовать: https://github.com/errorcalc/ESLowGraphicsLibrary


          1. SL_RU
            09.01.2017 22:07

            Пасибки, возможн когда-нибудь и воспользуюсь. Но сейчас я пишу хай лэвел либу, возможно, с менеджером окон. Аля emWin, только в разы более простую и открытую.


      1. DeXPeriX
        09.01.2017 23:17

        Да, именно так: можно использовать хоть на микроволновке, только нужно будет описать драйвер для рендеринга. И это будет намного проще, чем сделать библиотеку для GUI. Рендер — это буквально пара десятков функций типа: нарисуй прямоугольник, линию, круг, текст, картинку. А Nuklear сама уже на этой базе построит элементы GUI. Библиотека Nuklear занимает порядка 15 000 строк кода, GDI+ драйвер для неё — 1 000, SDL — 300.


        1. LynXzp
          10.01.2017 02:05

          Только обычно библиотеку для GUI на микроконтроллер не нужно делать такой. Там нет мыши (ну можно конечно втулить), и окон, и даже тач редко используется. Обычно пара кнопок и тогда требования к UI совершенно другие. И библиотека рендера часто тоже есть. Остается только воплощать идею заказчика. И 100кб там это сильно больше 16Мб Qt приложения на декстопе.

          Хотя конечно все бесспорно интересно как для PC так и для микроконтроллеров.


          1. DeXPeriX
            10.01.2017 12:19

            Размер уменьшится, если не тащить с собой ttf-шрифт или сильно его урезать. В Readme написано, что можно отказаться даже от stdlib. Наверное, это как раз для каких-нибудь микроконтроллеров и может быть полезно. Только да, интерфейс всё-таки ориентирован на десктопы/мобильники. Ну или как минимум относительно большой экран. Хотя опять же, может быть кто-нибудь попробует, расскажет и поделится своими впечатлениями.


  1. Veliant
    09.01.2017 22:10
    +1

    Скриншот
    image
    напомнил еще одну GUI библиотеку — GWEN (GWork).
    Тоже поддерживаются различные рендереры: GDI, SFML, OpengGL, DirectX, Allegro. Правда она потяжелее и написана на C++


    1. DeXPeriX
      09.01.2017 23:09

      В точку! Скин Gwen и используется:
      https://github.com/vurtun/nuklear/blob/master/example/skins/gwen.png


  1. pascualle
    09.01.2017 22:35

    мне проект понравился, думаю может утащу к себе, я какраз люблю когда никаких зависимостей
    код смотрел, вижу что редактора нет, но может где-то существует и редактор под все это?


    1. DeXPeriX
      09.01.2017 23:27

      Визуального редактора форм под это дело точно нет. Не того масштаба проект. Такие визуальные редакторы нужны в основном для создания сложных интерфейсов. А их: 1) лучше создавать в другом инструментарии (читай Qt); 2) Nuklear скорее всего просто не осилит (за счёт малого количества компонентов).


      1. pascualle
        09.01.2017 23:34

        ну… судя по коду все можно сериализировать, под капотом все пушается в буфер и рисуется. так что потенциально читать лайоут с какого-то редактора сделать не сложно. был бы редактор, кстати, можно попробовать использовать .dfm файлы Borland ide как вариант, редактор там норм


        1. DeXPeriX
          10.01.2017 00:24

          Ну платную проприетарную IDE, да ещё и доступную только под одну ОСь, вряд ли будут прикручивать к Open Source Public Domain проекту.
          С другой стороны, это Open Source. Я больше полугода сидел и хотел от Nuklear именно GDI+. Потом плюнул и реализовал недостающее сам :-)


  1. BIanF
    09.01.2017 22:50
    +4

    Самая неожиданная реклама визуальной новеллы, что я видел.


  1. leshakk
    09.01.2017 23:21
    +1

    А чем не устраивает QT? Да, объёмы больше, но и возможности не ограничиваются только GUI.


    1. DeXPeriX
      09.01.2017 23:24
      +1

      Почему стоит требование малого размера? Потому, что мне жаль из-за утилитки на 20 строчек заставлять пользователя каждый раз тянуть с собой ещё несколько мегабайт Qt. Если проект крупный и серьёзный, то никто не спорит, что инструментарий должен быть соответствующим. Только вот для совсем маленьких проектов я очень долго не мог найти ничего кроссплатформенного...


    1. pascualle
      09.01.2017 23:29
      +4

      думаю, если собрать два самых частых вопроса в информационном поле нашей солнечной системы, они будут такими:
      — а почему не unity
      — а почему не qt


      1. VJean
        10.01.2017 00:04
        -1

        — а почему не Sciter?


      1. icoz
        10.01.2017 00:14
        -1

        — а почему не assembler и framebuffer?


  1. rionekb
    10.01.2017 11:01
    +2

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

    Лучше вложить свои силы создание красивого, правильного и простого установщика Qt runtime на системы где с этим туго. А для проектов побольше можно даже попробовать научить приложение дергать сей установщик, дабы подтянул необходимые компоненты.


    1. lieff
      10.01.2017 11:27
      +1

      Вы не сможете сделать утилиту на 100кб, портабельную и которая заработает под всеми дистрибутивами, которую просто скопировал в фаре и работай. Я пробовал, тут даже libstdc++ приходится линковать статически. Под виндой таскать с такими утилками несколько громадных dll тоже не айс, или копировать их в загрузочные пути чтобы все эти утилки заработали. Доп рантайм это гиблое дело, не заставите вы его никого ставить, все проекты эмбедят Qt внутрь. Под виндой даже С++ рантаймы новых студий ставить отдельно не хотят — эмбедят его установщик вместе с софтом. Причем версий рантайма установленных в системе придется делать 100500 т.к. разные утилки будет слинкованы с разными версиями Qt.
      А так да, Qt конечно рулит.


      1. rionekb
        11.01.2017 21:56

        Так я и говорю, если правильно приложить к этому руки, то к продукту и люди потянутся и со временем превратят его в стандарт. И тогда, конечно, выпуск новой версии скажем раз в год строго с определенным тулчейном и определенной версией Qt — лучше чем клепать 100500 рантаймов. И вопрос портабельости в этом случае вполне решаем до определенной степени.

        Насчет студийных рантаймов, это очень странно что MS не может решить эту проблему по-человечески много лет. Давно могли бы сделать (полу-)автоматическую установку.

        А насчет размера бинарей. Я догадываюсь вряд ли количество подобных утилит дотянет в сумме до внушительных гигабайтов. А если и дотянет, то видимо время задуматься о выпуске пакета утилит с одним набором библиотек.


        1. lieff
          11.01.2017 22:35

          В ваших словах конечно есть истина, как и в моих. Как я уже говорил — я пытался заюзать Qt для данного сценария, проблема не только в размере, официальные сборки не статические, и в винде и в дистрибутивах. В винде приходится прикладывать dll, в лине или делать appimage\snap\flatpak или универсальный бинарь в который все надо линковать статически (из реп может не стоять по дефолту, а если бы стояло — версии разношерстные), на маке тоже придется постараться, в .app формате там приложение — это структура директорий. И универсальная сборка сильно усложняется. Для бльшого софта это норм, для мелкоутилок — ужас, ужас (./util.app/Contents/MacOS/util -f file :3 ).

          Размер тоже может иметь значение. Если это мелкоутилка лично моя — меня не будет сильно парить ее размер, разве что не сотни мегабайт. А вот если я в apk на андройд эту либу заюзаю, как в примере с аля-флешкой выше — меня парить уже будет. Или если я эту «флешку» в сайт какой встрою — тоже размер парить будет. Так же если это вдруг не персональная утилита, а какая-то сверх массовая, типа гнушных утилит, то мелкость по функции и черезмерная толстота тоже начнет вызывать вопросы даже на десктопе, а количество утилит в масштабах дистрибутива очень много.


        1. lieff
          11.01.2017 22:39

          Насчет рантаймов студий — все было хорошо, пока его не вынесли в WinSxS, так что dll из текущей диры уже не подхватываются, и ищутся из недр WinSxS по манифесту. В 2015 студии пошли на попятную и dll можно снова просто прилагать к проге.


  1. VioletGiraffe
    10.01.2017 11:04

    Для этого есть Qt.
    Я лучше скачаю 10-20 МБ приложения, которое нативно выглядит и хорошо работает, чем 200 КБ примитивного GUI. Qt хорош, помимо прочего, большим количеством возможностей из коробки — и в плане GUI, и по взаимодействию с ОС.

    Речь не об embedded, конечно. Речь о том, что для десктопа 20 МБ — не размер, о котором нужно думать. Думать нужно о юзабилити и стоимости разработки хорошего приложения.


    1. bogolt
      10.01.2017 19:50

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


  1. j_wayne
    10.01.2017 11:14

    Вижу на одном из скриншотов «Choose File».
    В readme проекта не нашел ответа на свои вопросы.
    Библиотека сама рисует диалоги choose file и тп? Или использует нативные? Или вообще нет такой фичи?


    1. lieff
      10.01.2017 11:36

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


  1. kx13
    10.01.2017 11:43

    А чем ваша библиотека отличается от уже существующих:
    http://webserver2.tecgraf.puc-rio.br/iup/,
    https://github.com/andlabs/libui?

    Они тоже написаны на С. Тоже весьма компактны. Используют даже нативный вид ОС в которой работают.


    1. DeXPeriX
      10.01.2017 12:49
      +1

      А Nuklear что, уже не существующая библиотека? ;-)
      IUP когда-то пробовал. Претендует на полность — много компонентов, свойств, конфигураций. И жирный исполняемый файл на выходе, несколько мегабайт. С тем же успехом можно wxWidgets взять, только писать код будет приятнее.
      libui значительно лучше, даже называют похудевшим wxWidgets. Только libui написана на С++, а не на Си. Так что как минимум несколько сотен килобайт прибавит. А то и больше, всё-таки компоненов там значительно больше, чем в Nuklear. Но за ссылку спасибо, как-нибудь помучаю эту библиотеку.


      1. monah_tuk
        11.01.2017 12:59

        libui на C++? Где вы его в репозитории увидели? Я только в одном семпле.


        1. lieff
          11.01.2017 13:45

          Наверно имеется ввиду папочка windows. Зачем так сделано не очень понятно, может из-за того что студии не очень дружат с С99.


          1. monah_tuk
            11.01.2017 13:48

            Чёрт, похоже на деформацию, папочку unix посмотрел, а windows даже не открыл :) Кстати, а darwin код вообще на ObjectiveC написан.


  1. NightWind
    10.01.2017 22:05
    -2

    20 mb Qt много? У нас есть простая GUI утилика написанная на node.js + angular.js + electron. Так вот её дистрибутив весит 466 MB, который, конечно для удобства, заботливо положен в GIT репозиторий. (GIT LFS? нет не слышал...)


    1. DeXPeriX
      10.01.2017 22:44
      +1

      Да сейчас и на сотни гигабайт софт можно найти. Только что в этом хорошего?...


      1. NightWind
        10.01.2017 23:01

        Да ничего хорошего, конечно, нет. Каждый раз открываю я эту тулзу и плачу. Только вот писал её один наш co-op student и стоила она компании практически ничего. Другой новый co-op student может её спокойно продолжать пилить, поскольку все они сейчас знают JS.
        Я хочу сказать то, что для постых задач нужна такая технология, которую можно отдать студенту, которая будет минимизирать стоимость разработки и для которой не нужен хардкорный программист который будут реализовывать загрузку изображений через OpenGL — для них и так работы хватает.
        Другое дело, если задача — сложная, но тогда, все рано, придется использовать Qt или что то подобное.
        Вот такие дела.
        А несколько лишних мегабайт никого сейчас не волнует (хотя повторюсь, без слез на нашу тулзу смотреть нельзя, но она работает)


        1. pascualle
          10.01.2017 23:13
          +1

          Проекты разные и требования разные. А также сюда можно добавить бюджет и время. Кому-то 2Гб не проблема в браузере грузить а кому и 640кб хватит на все задачи. Но все замечу, что тема топика «идеальный GUI для микро-проектов», что какбэ должно намекать…


        1. lieff
          10.01.2017 23:38
          +1

          Никто и не говорит что у такого подхота тоже нету жизни, сейчас каждый второй мессенджер — электрон. И кстати в вебе сейчас тоже есть webgl, а инициализировать его через glfw даже проще. И я бы не сказал, что веб сейчас это такая простая технология сильно проще других областей. Я вот с электроном и nodejs тоже возился и проблем хватало, например когда ставится 2000 njs пакетов, у части есть native и бац — один не компилится, приехали.
          Тут все же немного разные области, одно дело одна своя утилита на 400 метров, раз приемлимо и проблем нет — почему бы и нет. Другое дело если каждая такая мелкая системная утилитка типа grep, meld, git gui, kdiff3 итд начнут весить по 400м, жрать по 2 гига и тормозить. Все же во все времена есть какой-то разумный баланс и раз кто-то уже инвестировал свое время в более оптимизированное решение, которым можно воспользоваться — это же хорошо.