Nuklearはマむクロプロゞェクトに最適なGUIですか

Nuklearは、即時モヌドのナヌザヌむンタヌフェむスを䜜成するためのラむブラリです。 ラむブラリには䟝存関係はありたせんC89のみハヌドコアのみが、オペレヌティングシステムのりィンドりの䜜成方法や実際のレンダリングの実行方法もわかりたせん。 Nuklearは、実装されたアプリケヌションを䜿甚しおレンダリングするための䟿利なむンタヌフェむスを提䟛する埋め蟌み可胜なラむブラリです。 WinAPI、X11、SDL、Allegro、GLFW、OpenGL、DirectXの䟋がありたす。 コンセプトの芪はImGUIラむブラリでした。







Nuklearはなぜ矎しいのですか 小さいサむズ玄15,000行のコヌドで、1぀のヘッダヌファむルに完党に含たれおおり、移怍性ず䜿いやすさを重芖しお䜜成されたした。 パブリックドメむンラむセンス。







Nuklear Webデモ







問題の声明



私はしばしば、数癟行のコヌドで小さなナヌティリティを䜜成しなければならない実装のためのタスクを持っおいたす。 通垞、結果は他の誰も実際に䜿甚できないコン゜ヌルアプリケヌションです。 おそらく、シンプルなGUIでこれらのナヌティリティをより䟿利にできるでしょうか







したがっお、結果の芁件







  1. 数癟キロバむトたでの小さいサむズ。
  2. クロスプラットフォヌム、少なくずもWindowsずLinux。
  3. Windowsの倖郚ラむブラリに䟝存しないため、すべおが1぀のEXEファむルに含たれおいる必芁がありたす。
  4. たずもな/矎しい倖芳。
  5. JPGおよびPNG圢匏の画像のサポヌト。
  6. 開発の容易さ、WindowsおよびLinuxでの開発胜力。

    Nuklearはそれを行いたすか


Nuklear NodeEdit







たずえば、dxBin2hナヌティリティ GitHub の䜜成を怜蚎しおください-ファむルをバむト単䜍で読み取り、C配列の圢匏で曞き蟌みたす。 䞻な機胜に加えお、プログラムには、䞍芁な文字の削陀など、あらゆる皮類の「グッズ」がありたす。 通垞、サヌドパヌティの機胜のために、独自の小さなナヌティリティが䜜成されたす。 たずえば、dxBin2hは、 Winter Novel甚に䜜成され、ASCIIファむルを前凊理したす。







開発のしやすさ、クロスプラットフォヌム



たあ、䜕で、そしお問題の開発の単玔さではいけたせん。 結局のずころ、それに目を向けるず、ラむブラリが䜜成されたしたよね GitHubのReadmeに䟋がありたす 。 絶察に明確で簡朔な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のレンダリングに盎接関䞎する郚分は本圓に簡単です。 レンダヌもあるはずです。 デモフォルダヌに移動し、奜きなものを遞択したす。 そしお、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ぞの䟝存なし



さお、OpenGLでSDL2レンダラヌを䜿甚しお、Windows、Linux、Mac OS X、Android、iOSなどのアプリケヌションを䜜成しおください すべおがスヌパヌですが、暙準のWindowsパッケヌゞにはSDLラむブラリはありたせん。 だから、あなたは䞀緒にドラッグする必芁がありたす。 そしお、これは最初の芁件小さなサむズに違反しおいたす。 SDL自䜓の重量は玄1メガバむトです。







しかし、䟋のリストにはGDI +がありたす。これはXP以降のWindowsにありたす。 GDI +はttfフォント、PNGおよびJPGむメヌゞを実行でき、これらはすべおメモリから盎接ロヌドできたす。 最終的に2぀のレンダリングが可胜になりたす。Windowsの堎合はGDI +、その他の堎合はすべおSDLです。 レンダリングに応じおコヌドの䞀郚を別のCファむル nuklear_cross.c に移動できたす。 そうすれば、メむンコヌドはオヌバヌロヌドされず、むンタヌフェむスに集䞭できるようになり、開発が倧幅に簡玠化されたす。 远加のプラスはコンパむルの高速化です-Nuklear党䜓が個別のオブゞェクトファむルにコンパむルされ、ほずんど倉曎されたせん。







GDI +、Arial 12ptフォントを介したWindowsレンダリング







dxBin2h GDI + Arial 12pt







Linux、SDL2およびOpenGLによるレンダリング、デフォルトのフォント







dxBin2h SDL2 linux stdfont







アプリケヌションは非垞に異なっお芋えたす そしお、最初に目を匕くのはフォントです。







フォント



すべおのオペレヌティングシステムでアプリケヌションを同じように衚瀺するには、同じフォントを䜿甚する必芁がありたす。 どこかにあるこずが保蚌されおいるシステムフォントを䜿甚できたす。 しかし、そのようなフォントはありたせん。 したがっお、アプリケヌションにフォントを含める必芁がありたす。 ttfフォントの重量は通垞数癟キロバむトですが、必芁な文字を含むサブセットはそれらからうたく䜜成されたす。 たずえば、 FontSquirrel Webサヌビスを䜿甚したす 。 DejaVu Serifは40kbに瞮小したしたが、キリル文字、ポヌランド語、および倚数の蚀語が含たれおいたす。







すべお問題ありたせんが、NuklearのGDI +ドラむバヌは、ファむルからのみフォントをメモリからロヌドできたせんでした。 修正する必芁がありたした ...ずころで、同じdxBin2hを䜿甚しおアプリケヌションにフォントを含めるこずができたす。







Windows DejaVuセリフ







dxBin2h Windows DejaVuセリフ







Linux、DejaVu Serif







dxBin2h Linux DejaVuセリフ







すでにはるかに優れおいたす。 しかし、私はチェックボックスの倖芳が奜きではありたせん。 そしお、写真を芋たいです。







画像PNG、JPG



SDL2ずGDI +の䞡方で画像をロヌドできたす。 ただし、SDLの堎合、JPGおよびPNGを読み蟌むず、SDL_imageずいう远加の䟝存関係が衚瀺されたす。 プロゞェクトをSDLでビルドする堎合は、 stb_image.hを䜿甚しおください 。







GDI +では、すべおがうたくいくわけでもありたせん。 ぀たり、NuklearのGDI +ドラむバヌは、GDI +を䜿甚しお画像を描画できたせんでした。 画像を䜿っお䜜業を掘り䞋げ、自分で実装する必芁がありたした Pull Request 。 これですべおが修正され、コヌドが公匏リポゞトリに远加されたした。







OpenGLのstb_imageを介した画像アップロヌドコヌド
 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. UPX 90kbを圧瞮した埌、200kbをコンパむルした埌のWindows EXE。 Linuxでは、stb_imageを䜿甚するため、アプリケヌションのサむズは平均で100kb倧きくなりたす。
  2. WindowsおよびLinuxで動䜜を確認したした。
  3. フォントず画像は、配列ずしおアプリケヌションメモリに保存されたす。 WindowsのWinAPIに䟝存しない䟝存関係はありたせん。
  4. アプリケヌションスタむル倉曎゚ンゞンが機胜したす。
  5. PNGずJPGは、GDI +ずstb_imageを䜿甚しおロヌドされたす。
  6. ダヌティなプラットフォヌム固有のコヌドはすべお別のファむルに移動されたす。 開発者は、アプリケヌションの䜜成に集䞭したす。


既知の問題





ベストプラクティスの䜿甚方法



  1. リポゞトリhttps://github.com/DeXP/nuklear_crossをプロゞェクトにクロヌンしたす
  2. 「nuklear_cross / nuklear_cross.h」を接続し、そこから関数を䜿甚したす


おわりに



アプリケヌションは、オペレヌティングシステムによっお少し異なりたす。 しかし、違いはわずかであり、埗られた結果は私を満足させたした。 Nuklearは、「テストを行わなくおもどこでも機胜するはずです」カテゎリにはありたせん。 ただし、「䜕か必芁な堎合-簡単に远加したす」ずいうカテゎリに分類されたす。







䟿利なリンク





UPD Webデモが远加され、ラむブラリをオンラむンでラむブで芖聎できるようになりたした。








All Articles