/* nuklear - v1.32.0 - public domain */ #include #include #include #include #include #include #include #include #include #include #define NK_INCLUDE_FIXED_TYPES #define NK_INCLUDE_STANDARD_IO #define NK_INCLUDE_STANDARD_VARARGS #define NK_INCLUDE_DEFAULT_ALLOCATOR #define NK_IMPLEMENTATION #define NK_XLIB_IMPLEMENTATION #include "../../nuklear.h" #include "nuklear_xlib.h" #define DTIME 20 #define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 600 typedef struct XWindow XWindow; struct XWindow { Display *dpy; Window root; Visual *vis; Colormap cmap; XWindowAttributes attr; XSetWindowAttributes swa; Window win; int screen; XFont *font; unsigned int width; unsigned int height; Atom wm_delete_window; }; static void die(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); fputs("\n", stderr); exit(EXIT_FAILURE); } static long timestamp(void) { struct timeval tv; if (gettimeofday(&tv, NULL) < 0) return 0; return (long)((long)tv.tv_sec * 1000 + (long)tv.tv_usec/1000); } static void sleep_for(long t) { struct timespec req; const time_t sec = (int)(t/1000); const long ms = t - (sec * 1000); req.tv_sec = sec; req.tv_nsec = ms * 1000000L; while(-1 == nanosleep(&req, &req)); } /* =============================================================== * * EXAMPLE * * ===============================================================*/ /* This are some code examples to provide a small overview of what can be * done with this library. To try out an example uncomment the defines */ /*#define INCLUDE_ALL */ /*#define INCLUDE_STYLE */ /*#define INCLUDE_CALCULATOR */ /*#define INCLUDE_CANVAS */ /*#define INCLUDE_OVERVIEW */ /*#define INCLUDE_NODE_EDITOR */ #ifdef INCLUDE_ALL #define INCLUDE_STYLE #define INCLUDE_CALCULATOR #define INCLUDE_CANVAS #define INCLUDE_OVERVIEW #define INCLUDE_NODE_EDITOR #endif #ifdef INCLUDE_STYLE #include "../../demo/common/style.c" #endif #ifdef INCLUDE_CALCULATOR #include "../../demo/common/calculator.c" #endif #ifdef INCLUDE_CANVAS #include "../../demo/common/canvas.c" #endif #ifdef INCLUDE_OVERVIEW #include "../../demo/common/overview.c" #endif #ifdef INCLUDE_NODE_EDITOR #include "../../demo/common/node_editor.c" #endif /* =============================================================== * * DEMO * * ===============================================================*/ int main(void) { long dt; long started; int running = 1; XWindow xw; struct nk_context *ctx; /* X11 */ memset(&xw, 0, sizeof xw); xw.dpy = XOpenDisplay(NULL); if (!xw.dpy) die("Could not open a display; perhaps $DISPLAY is not set?"); xw.root = DefaultRootWindow(xw.dpy); xw.screen = XDefaultScreen(xw.dpy); xw.vis = XDefaultVisual(xw.dpy, xw.screen); xw.cmap = XCreateColormap(xw.dpy,xw.root,xw.vis,AllocNone); xw.swa.colormap = xw.cmap; xw.swa.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPress | ButtonReleaseMask| ButtonMotionMask | Button1MotionMask | Button3MotionMask | Button4MotionMask | Button5MotionMask| PointerMotionMask | KeymapStateMask; xw.win = XCreateWindow(xw.dpy, xw.root, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, XDefaultDepth(xw.dpy, xw.screen), InputOutput, xw.vis, CWEventMask | CWColormap, &xw.swa); XStoreName(xw.dpy, xw.win, "X11"); XMapWindow(xw.dpy, xw.win); xw.wm_delete_window = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False); XSetWMProtocols(xw.dpy, xw.win, &xw.wm_delete_window, 1); XGetWindowAttributes(xw.dpy, xw.win, &xw.attr); xw.width = (unsigned int)xw.attr.width; xw.height = (unsigned int)xw.attr.height; /* GUI */ xw.font = nk_xfont_create(xw.dpy, "fixed"); ctx = nk_xlib_init(xw.font, xw.dpy, xw.screen, xw.win, xw.width, xw.height); #ifdef INCLUDE_STYLE /* ease regression testing during Nuklear release process; not needed for anything else */ #ifdef STYLE_WHITE set_style(ctx, THEME_WHITE); #elif defined(STYLE_RED) set_style(ctx, THEME_RED); #elif defined(STYLE_BLUE) set_style(ctx, THEME_BLUE); #elif defined(STYLE_DARK) set_style(ctx, THEME_DARK); #endif #endif while (running) { /* Input */ XEvent evt; started = timestamp(); nk_input_begin(ctx); while (XPending(xw.dpy)) { XNextEvent(xw.dpy, &evt); if (evt.type == ClientMessage) goto cleanup; if (XFilterEvent(&evt, xw.win)) continue; nk_xlib_handle_event(xw.dpy, xw.screen, xw.win, &evt); } nk_input_end(ctx); /* GUI */ if (nk_begin(ctx, "Demo", nk_rect(50, 50, 200, 200), NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE| NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE)) { enum {EASY, HARD}; static int op = EASY; static int property = 20; nk_layout_row_static(ctx, 30, 80, 1); if (nk_button_label(ctx, "button")) fprintf(stdout, "button pressed\n"); 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; nk_layout_row_dynamic(ctx, 25, 1); nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1); } nk_end(ctx); if (nk_window_is_hidden(ctx, "Demo")) break; /* -------------- EXAMPLES ---------------- */ #ifdef INCLUDE_CALCULATOR calculator(ctx); #endif #ifdef INCLUDE_CANVAS canvas(ctx); #endif #ifdef INCLUDE_OVERVIEW overview(ctx); #endif #ifdef INCLUDE_NODE_EDITOR node_editor(ctx); #endif /* ----------------------------------------- */ /* Draw */ XClearWindow(xw.dpy, xw.win); nk_xlib_render(xw.win, nk_rgb(30,30,30)); XFlush(xw.dpy); /* Timing */ dt = timestamp() - started; if (dt < DTIME) sleep_for(DTIME - dt); } cleanup: nk_xfont_del(xw.dpy, xw.font); nk_xlib_shutdown(); XUnmapWindow(xw.dpy, xw.win); XFreeColormap(xw.dpy, xw.cmap); XDestroyWindow(xw.dpy, xw.win); XCloseDisplay(xw.dpy); return 0; }