Converted backend demos into single header files
This commit is contained in:
parent
a2aaedbed0
commit
f5dc2906a8
@ -10,9 +10,6 @@
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <allegro5/allegro.h>
|
||||
#include <allegro5/allegro_primitives.h>
|
||||
|
||||
/* macros */
|
||||
#define WINDOW_WIDTH 800
|
||||
#define WINDOW_HEIGHT 600
|
||||
@ -20,17 +17,16 @@
|
||||
#define MAX_VERTEX_MEMORY 512 * 1024
|
||||
#define MAX_ELEMENT_MEMORY 128 * 1024
|
||||
|
||||
/* these defines are both needed for the header
|
||||
* and source file. So if you split them remember
|
||||
* to copy them as well. */
|
||||
#define NK_INCLUDE_FIXED_TYPES
|
||||
#define NK_INCLUDE_STANDARD_IO
|
||||
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
||||
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
|
||||
#define NK_INCLUDE_FONT_BAKING
|
||||
#define NK_INCLUDE_DEFAULT_FONT
|
||||
#define NK_IMPLEMENTATION
|
||||
#define NK_ALLEGRO_IMPLEMENTATION
|
||||
#include "../../nuklear.h"
|
||||
#include "nuklear_allegro.h"
|
||||
#include "nuklear_allegro.c"
|
||||
|
||||
#define UNUSED(a) (void)a
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
@ -1,271 +0,0 @@
|
||||
#define NK_IMPLEMENTATION
|
||||
#include "../../nuklear.h"
|
||||
|
||||
#include <allegro5/allegro.h>
|
||||
#include <allegro5/allegro_primitives.h>
|
||||
|
||||
struct nk_allegro_device {
|
||||
ALLEGRO_BITMAP *texture;
|
||||
ALLEGRO_VERTEX_DECL *vertex_decl;
|
||||
struct nk_draw_null_texture null;
|
||||
struct nk_buffer cmds;
|
||||
void *vertex_buffer;
|
||||
void *element_buffer;
|
||||
int max_vertex_memory;
|
||||
int max_element_memory;
|
||||
};
|
||||
|
||||
struct nk_allegro_vertex {
|
||||
struct nk_vec2 pos;
|
||||
struct nk_vec2 uv;
|
||||
ALLEGRO_COLOR col;
|
||||
};
|
||||
|
||||
static struct {
|
||||
ALLEGRO_DISPLAY *win;
|
||||
struct nk_allegro_device dev;
|
||||
struct nk_context ctx;
|
||||
struct nk_font_atlas atlas;
|
||||
} allegro;
|
||||
|
||||
|
||||
NK_API void
|
||||
nk_allegro_device_create(int max_vertex_memory, int max_element_memory)
|
||||
{
|
||||
struct nk_allegro_device *dev = &allegro.dev;
|
||||
ALLEGRO_VERTEX_ELEMENT elems[] = {
|
||||
{ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, offsetof(struct nk_allegro_vertex, pos)},
|
||||
{ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, offsetof(struct nk_allegro_vertex, uv)},
|
||||
{ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(struct nk_allegro_vertex, col)},
|
||||
{0,0,0}
|
||||
};
|
||||
dev->vertex_decl = al_create_vertex_decl(elems, sizeof(struct nk_allegro_vertex));
|
||||
dev->vertex_buffer = calloc((size_t)max_vertex_memory, 1);
|
||||
dev->element_buffer = calloc((size_t)max_element_memory, 1);
|
||||
dev->max_vertex_memory = max_vertex_memory;
|
||||
dev->max_element_memory = max_element_memory;
|
||||
nk_buffer_init_default(&dev->cmds);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_allegro_device_upload_atlas(const void *image, int width, int height)
|
||||
{
|
||||
/* create allegro font bitmap */
|
||||
ALLEGRO_BITMAP *bitmap = 0;
|
||||
struct nk_allegro_device *dev = &allegro.dev;
|
||||
int flags = al_get_new_bitmap_flags();
|
||||
int fmt = al_get_new_bitmap_format();
|
||||
al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP|ALLEGRO_MIN_LINEAR|ALLEGRO_MAG_LINEAR);
|
||||
al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE);
|
||||
bitmap = al_create_bitmap(width, height);
|
||||
al_set_new_bitmap_flags(flags);
|
||||
al_set_new_bitmap_format(fmt);
|
||||
assert(bitmap);
|
||||
|
||||
{/* copy font texture into bitmap */
|
||||
ALLEGRO_LOCKED_REGION * locked_img;
|
||||
locked_img = al_lock_bitmap(bitmap, al_get_bitmap_format(bitmap), ALLEGRO_LOCK_WRITEONLY);
|
||||
assert(locked_img);
|
||||
memcpy(locked_img->data, image, sizeof(uint32_t)*(size_t)(width*height));
|
||||
al_unlock_bitmap(bitmap);}
|
||||
|
||||
/* convert software texture into hardware texture */
|
||||
dev->texture = al_clone_bitmap(bitmap);
|
||||
al_destroy_bitmap(bitmap);
|
||||
assert(dev->texture);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_allegro_render(enum nk_anti_aliasing AA)
|
||||
{
|
||||
int op, src, dst;
|
||||
struct nk_allegro_device *dev = &allegro.dev;
|
||||
struct nk_context *ctx = &allegro.ctx;
|
||||
al_get_blender(&op, &src, &dst);
|
||||
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
|
||||
|
||||
{
|
||||
const struct nk_draw_command *cmd;
|
||||
struct nk_buffer vbuf, ebuf;
|
||||
int offset = 0;
|
||||
struct nk_allegro_vertex *vertices = 0;
|
||||
int *indices = 0;
|
||||
|
||||
/* fill converting configuration */
|
||||
struct nk_convert_config config;
|
||||
memset(&config, 0, sizeof(config));
|
||||
config.global_alpha = 1.0f;
|
||||
config.shape_AA = AA;
|
||||
config.line_AA = AA;
|
||||
config.circle_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.null = dev->null;
|
||||
|
||||
/* convert from command into hardware format */
|
||||
nk_buffer_init_fixed(&vbuf, dev->vertex_buffer, (nk_size)dev->max_vertex_memory);
|
||||
nk_buffer_init_fixed(&ebuf, dev->element_buffer, (nk_size)dev->max_element_memory);
|
||||
nk_convert(ctx, &dev->cmds, &vbuf, &ebuf, &config);
|
||||
|
||||
{
|
||||
/* <sign> allegro does not support 32-bit packed color */
|
||||
unsigned int i = 0;
|
||||
struct nk_draw_vertex *verts = (struct nk_draw_vertex*)dev->vertex_buffer;
|
||||
vertices = (struct nk_allegro_vertex*)calloc(sizeof(struct nk_allegro_vertex), ctx->draw_list.vertex_count);
|
||||
for (i = 0; i < ctx->draw_list.vertex_count; ++i) {
|
||||
nk_byte *c;
|
||||
vertices[i].pos = verts[i].position;
|
||||
vertices[i].uv = verts[i].uv;
|
||||
c = (nk_byte*)&verts[i].col;
|
||||
vertices[i].col = al_map_rgba(c[0], c[1], c[2], c[3]);
|
||||
}
|
||||
}
|
||||
{
|
||||
/* <massive sign> allegro does not support 16-bit indices:
|
||||
* @OPT: define nk_draw_index as int to fix this issue. */
|
||||
unsigned int i = 0;
|
||||
nk_draw_index *elements = (nk_draw_index*)dev->element_buffer;
|
||||
indices = (int*)calloc(sizeof(int), ctx->draw_list.element_count);
|
||||
for (i = 0; i < ctx->draw_list.element_count; ++i)
|
||||
indices[i] = elements[i];
|
||||
}
|
||||
|
||||
/* iterate over and execute each draw command */
|
||||
nk_draw_foreach(cmd, ctx, &dev->cmds)
|
||||
{
|
||||
ALLEGRO_BITMAP *texture = (ALLEGRO_BITMAP*)cmd->texture.ptr;
|
||||
if (!cmd->elem_count) continue;
|
||||
al_set_clipping_rectangle((int)cmd->clip_rect.x, (int)cmd->clip_rect.y,
|
||||
(int)cmd->clip_rect.w, (int)cmd->clip_rect.h);
|
||||
al_draw_indexed_prim(vertices, dev->vertex_decl, texture, &indices[offset],
|
||||
(int)cmd->elem_count, ALLEGRO_PRIM_TRIANGLE_LIST);
|
||||
offset += cmd->elem_count;
|
||||
}
|
||||
|
||||
free(vertices);
|
||||
free(indices);
|
||||
nk_clear(ctx);
|
||||
}
|
||||
al_set_blender(op, src, dst);
|
||||
al_set_clipping_rectangle(0,0, al_get_display_width(allegro.win),
|
||||
al_get_display_height(allegro.win));
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_allegro_device_destroy(void)
|
||||
{
|
||||
struct nk_allegro_device *dev = &allegro.dev;
|
||||
free(dev->vertex_buffer);
|
||||
free(dev->element_buffer);
|
||||
nk_buffer_free(&dev->cmds);
|
||||
}
|
||||
|
||||
|
||||
NK_API struct nk_context*
|
||||
nk_allegro_init(ALLEGRO_DISPLAY *win, int max_vertex_memory, int max_element_memory)
|
||||
{
|
||||
allegro.win = win;
|
||||
nk_init_default(&allegro.ctx, 0);
|
||||
nk_allegro_device_create(max_vertex_memory, max_element_memory);
|
||||
return &allegro.ctx;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_allegro_font_stash_begin(struct nk_font_atlas **atlas)
|
||||
{
|
||||
nk_font_atlas_init_default(&allegro.atlas);
|
||||
nk_font_atlas_begin(&allegro.atlas);
|
||||
*atlas = &allegro.atlas;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_allegro_font_stash_end(void)
|
||||
{
|
||||
const void *image; int w, h;
|
||||
image = nk_font_atlas_bake(&allegro.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
|
||||
nk_allegro_device_upload_atlas(image, w, h);
|
||||
nk_font_atlas_end(&allegro.atlas, nk_handle_ptr(allegro.dev.texture), &allegro.dev.null);
|
||||
if (allegro.atlas.default_font)
|
||||
nk_style_set_font(&allegro.ctx, &allegro.atlas.default_font->handle);
|
||||
}
|
||||
|
||||
|
||||
NK_API void
|
||||
nk_allegro_handle_event(ALLEGRO_EVENT *evt)
|
||||
{
|
||||
struct nk_context *ctx = &allegro.ctx;
|
||||
if ((evt->type == ALLEGRO_EVENT_KEY_UP ||
|
||||
evt->type == ALLEGRO_EVENT_KEY_DOWN) &&
|
||||
evt->keyboard.display == allegro.win)
|
||||
{
|
||||
/* key handler */
|
||||
int down = (evt->type == ALLEGRO_EVENT_KEY_UP);
|
||||
int sym = evt->keyboard.keycode;
|
||||
if (sym == ALLEGRO_KEY_RSHIFT || sym == ALLEGRO_KEY_LSHIFT)
|
||||
nk_input_key(ctx, NK_KEY_SHIFT, down);
|
||||
else if (sym == ALLEGRO_KEY_DELETE)
|
||||
nk_input_key(ctx, NK_KEY_DEL, down);
|
||||
else if (sym == ALLEGRO_KEY_ENTER)
|
||||
nk_input_key(ctx, NK_KEY_ENTER, down);
|
||||
else if (sym == ALLEGRO_KEY_TAB)
|
||||
nk_input_key(ctx, NK_KEY_TAB, down);
|
||||
else if (sym == ALLEGRO_KEY_BACKSPACE)
|
||||
nk_input_key(ctx, NK_KEY_BACKSPACE, down);
|
||||
else if (sym == ALLEGRO_KEY_LEFT) {
|
||||
if (evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, down);
|
||||
else nk_input_key(ctx, NK_KEY_LEFT, down);
|
||||
} else if (sym == ALLEGRO_KEY_RIGHT) {
|
||||
if (evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, down);
|
||||
else nk_input_key(ctx, NK_KEY_RIGHT, down);
|
||||
} else if (sym == ALLEGRO_KEY_HOME)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_START, down);
|
||||
else if (sym == ALLEGRO_KEY_END)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_END, down);
|
||||
else if (sym == ALLEGRO_KEY_C)
|
||||
nk_input_key(ctx, NK_KEY_COPY, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
else if (sym == ALLEGRO_KEY_V)
|
||||
nk_input_key(ctx, NK_KEY_PASTE, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
else if (sym == ALLEGRO_KEY_X)
|
||||
nk_input_key(ctx, NK_KEY_CUT, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
else if (sym == ALLEGRO_KEY_Z)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_UNDO, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
else if (sym == ALLEGRO_KEY_R)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_REDO, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
else if (sym == ALLEGRO_KEY_X)
|
||||
nk_input_key(ctx, NK_KEY_CUT, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
else if (sym == ALLEGRO_KEY_B)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
else if (sym == ALLEGRO_KEY_E)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
|
||||
} else if (evt->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN ||
|
||||
evt->type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) {
|
||||
/* button handler */
|
||||
int down = evt->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN;
|
||||
const int x = evt->mouse.x, y = evt->mouse.y;
|
||||
if (evt->mouse.button == 1)
|
||||
nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down);
|
||||
if (evt->mouse.button == 2)
|
||||
nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down);
|
||||
} else if (evt->type == ALLEGRO_EVENT_MOUSE_AXES) {
|
||||
/* mouse motion */
|
||||
nk_input_motion(ctx, evt->mouse.x, evt->mouse.y);
|
||||
} else if (evt->type == ALLEGRO_EVENT_KEY_CHAR) {
|
||||
/* text input */
|
||||
if (evt->keyboard.display == allegro.win)
|
||||
if (evt->keyboard.unichar > 0 && evt->keyboard.unichar < 0x10000)
|
||||
nk_input_unicode(ctx, (nk_rune)evt->keyboard.unichar);
|
||||
}
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_allegro_shutdown(void)
|
||||
{
|
||||
if (allegro.dev.texture)
|
||||
al_destroy_bitmap(allegro.dev.texture);
|
||||
free(allegro.dev.vertex_buffer);
|
||||
free(allegro.dev.element_buffer);
|
||||
}
|
||||
|
@ -1,8 +1,19 @@
|
||||
/*
|
||||
* Nuklear - v1.00 - public domain
|
||||
* no warrenty implied; use at your own risk.
|
||||
* authored from 2015-2016 by Micha Mettke
|
||||
*/
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* API
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifndef NK_ALLEGRO_H_
|
||||
#define NK_ALLEGRO_H_
|
||||
|
||||
#include "../../nuklear.h"
|
||||
|
||||
#include <allegro5/allegro.h>
|
||||
NK_API struct nk_context* nk_allegro_init(ALLEGRO_DISPLAY *win, int max_vertex_memory, int max_element_memory);
|
||||
NK_API void nk_allegro_font_stash_begin(struct nk_font_atlas **atlas);
|
||||
NK_API void nk_allegro_font_stash_end(void);
|
||||
@ -15,3 +26,281 @@ NK_API void nk_allegro_device_destroy(void);
|
||||
NK_API void nk_allegro_device_create(int max_vertex_memory, int max_elemnt_memory);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* IMPLEMENTATION
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifdef NK_ALLEGRO_IMPLEMENTATION
|
||||
|
||||
#include <allegro5/allegro_primitives.h>
|
||||
|
||||
struct nk_allegro_device {
|
||||
ALLEGRO_BITMAP *texture;
|
||||
ALLEGRO_VERTEX_DECL *vertex_decl;
|
||||
struct nk_draw_null_texture null;
|
||||
struct nk_buffer cmds;
|
||||
void *vertex_buffer;
|
||||
void *element_buffer;
|
||||
int max_vertex_memory;
|
||||
int max_element_memory;
|
||||
};
|
||||
|
||||
struct nk_allegro_vertex {
|
||||
struct nk_vec2 pos;
|
||||
struct nk_vec2 uv;
|
||||
ALLEGRO_COLOR col;
|
||||
};
|
||||
|
||||
static struct {
|
||||
ALLEGRO_DISPLAY *win;
|
||||
struct nk_allegro_device dev;
|
||||
struct nk_context ctx;
|
||||
struct nk_font_atlas atlas;
|
||||
} allegro;
|
||||
|
||||
|
||||
NK_API void
|
||||
nk_allegro_device_create(int max_vertex_memory, int max_element_memory)
|
||||
{
|
||||
struct nk_allegro_device *dev = &allegro.dev;
|
||||
ALLEGRO_VERTEX_ELEMENT elems[] = {
|
||||
{ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, offsetof(struct nk_allegro_vertex, pos)},
|
||||
{ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, offsetof(struct nk_allegro_vertex, uv)},
|
||||
{ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(struct nk_allegro_vertex, col)},
|
||||
{0,0,0}
|
||||
};
|
||||
dev->vertex_decl = al_create_vertex_decl(elems, sizeof(struct nk_allegro_vertex));
|
||||
dev->vertex_buffer = calloc((size_t)max_vertex_memory, 1);
|
||||
dev->element_buffer = calloc((size_t)max_element_memory, 1);
|
||||
dev->max_vertex_memory = max_vertex_memory;
|
||||
dev->max_element_memory = max_element_memory;
|
||||
nk_buffer_init_default(&dev->cmds);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_allegro_device_upload_atlas(const void *image, int width, int height)
|
||||
{
|
||||
/* create allegro font bitmap */
|
||||
ALLEGRO_BITMAP *bitmap = 0;
|
||||
struct nk_allegro_device *dev = &allegro.dev;
|
||||
int flags = al_get_new_bitmap_flags();
|
||||
int fmt = al_get_new_bitmap_format();
|
||||
al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP|ALLEGRO_MIN_LINEAR|ALLEGRO_MAG_LINEAR);
|
||||
al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE);
|
||||
bitmap = al_create_bitmap(width, height);
|
||||
al_set_new_bitmap_flags(flags);
|
||||
al_set_new_bitmap_format(fmt);
|
||||
assert(bitmap);
|
||||
|
||||
{/* copy font texture into bitmap */
|
||||
ALLEGRO_LOCKED_REGION * locked_img;
|
||||
locked_img = al_lock_bitmap(bitmap, al_get_bitmap_format(bitmap), ALLEGRO_LOCK_WRITEONLY);
|
||||
assert(locked_img);
|
||||
memcpy(locked_img->data, image, sizeof(uint32_t)*(size_t)(width*height));
|
||||
al_unlock_bitmap(bitmap);}
|
||||
|
||||
/* convert software texture into hardware texture */
|
||||
dev->texture = al_clone_bitmap(bitmap);
|
||||
al_destroy_bitmap(bitmap);
|
||||
assert(dev->texture);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_allegro_render(enum nk_anti_aliasing AA)
|
||||
{
|
||||
int op, src, dst;
|
||||
struct nk_allegro_device *dev = &allegro.dev;
|
||||
struct nk_context *ctx = &allegro.ctx;
|
||||
al_get_blender(&op, &src, &dst);
|
||||
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
|
||||
|
||||
{
|
||||
const struct nk_draw_command *cmd;
|
||||
struct nk_buffer vbuf, ebuf;
|
||||
int offset = 0;
|
||||
struct nk_allegro_vertex *vertices = 0;
|
||||
int *indices = 0;
|
||||
|
||||
/* fill converting configuration */
|
||||
struct nk_convert_config config;
|
||||
memset(&config, 0, sizeof(config));
|
||||
config.global_alpha = 1.0f;
|
||||
config.shape_AA = AA;
|
||||
config.line_AA = AA;
|
||||
config.circle_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.null = dev->null;
|
||||
|
||||
/* convert from command into hardware format */
|
||||
nk_buffer_init_fixed(&vbuf, dev->vertex_buffer, (nk_size)dev->max_vertex_memory);
|
||||
nk_buffer_init_fixed(&ebuf, dev->element_buffer, (nk_size)dev->max_element_memory);
|
||||
nk_convert(ctx, &dev->cmds, &vbuf, &ebuf, &config);
|
||||
|
||||
{
|
||||
/* <sign> allegro does not support 32-bit packed color */
|
||||
unsigned int i = 0;
|
||||
struct nk_draw_vertex *verts = (struct nk_draw_vertex*)dev->vertex_buffer;
|
||||
vertices = (struct nk_allegro_vertex*)calloc(sizeof(struct nk_allegro_vertex), ctx->draw_list.vertex_count);
|
||||
for (i = 0; i < ctx->draw_list.vertex_count; ++i) {
|
||||
nk_byte *c;
|
||||
vertices[i].pos = verts[i].position;
|
||||
vertices[i].uv = verts[i].uv;
|
||||
c = (nk_byte*)&verts[i].col;
|
||||
vertices[i].col = al_map_rgba(c[0], c[1], c[2], c[3]);
|
||||
}
|
||||
}
|
||||
{
|
||||
/* <massive sign> allegro does not support 16-bit indices:
|
||||
* @OPT: define nk_draw_index as int to fix this issue. */
|
||||
unsigned int i = 0;
|
||||
nk_draw_index *elements = (nk_draw_index*)dev->element_buffer;
|
||||
indices = (int*)calloc(sizeof(int), ctx->draw_list.element_count);
|
||||
for (i = 0; i < ctx->draw_list.element_count; ++i)
|
||||
indices[i] = elements[i];
|
||||
}
|
||||
|
||||
/* iterate over and execute each draw command */
|
||||
nk_draw_foreach(cmd, ctx, &dev->cmds)
|
||||
{
|
||||
ALLEGRO_BITMAP *texture = (ALLEGRO_BITMAP*)cmd->texture.ptr;
|
||||
if (!cmd->elem_count) continue;
|
||||
al_set_clipping_rectangle((int)cmd->clip_rect.x, (int)cmd->clip_rect.y,
|
||||
(int)cmd->clip_rect.w, (int)cmd->clip_rect.h);
|
||||
al_draw_indexed_prim(vertices, dev->vertex_decl, texture, &indices[offset],
|
||||
(int)cmd->elem_count, ALLEGRO_PRIM_TRIANGLE_LIST);
|
||||
offset += cmd->elem_count;
|
||||
}
|
||||
|
||||
free(vertices);
|
||||
free(indices);
|
||||
nk_clear(ctx);
|
||||
}
|
||||
al_set_blender(op, src, dst);
|
||||
al_set_clipping_rectangle(0,0, al_get_display_width(allegro.win),
|
||||
al_get_display_height(allegro.win));
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_allegro_device_destroy(void)
|
||||
{
|
||||
struct nk_allegro_device *dev = &allegro.dev;
|
||||
free(dev->vertex_buffer);
|
||||
free(dev->element_buffer);
|
||||
nk_buffer_free(&dev->cmds);
|
||||
}
|
||||
|
||||
|
||||
NK_API struct nk_context*
|
||||
nk_allegro_init(ALLEGRO_DISPLAY *win, int max_vertex_memory, int max_element_memory)
|
||||
{
|
||||
allegro.win = win;
|
||||
nk_init_default(&allegro.ctx, 0);
|
||||
nk_allegro_device_create(max_vertex_memory, max_element_memory);
|
||||
return &allegro.ctx;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_allegro_font_stash_begin(struct nk_font_atlas **atlas)
|
||||
{
|
||||
nk_font_atlas_init_default(&allegro.atlas);
|
||||
nk_font_atlas_begin(&allegro.atlas);
|
||||
*atlas = &allegro.atlas;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_allegro_font_stash_end(void)
|
||||
{
|
||||
const void *image; int w, h;
|
||||
image = nk_font_atlas_bake(&allegro.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
|
||||
nk_allegro_device_upload_atlas(image, w, h);
|
||||
nk_font_atlas_end(&allegro.atlas, nk_handle_ptr(allegro.dev.texture), &allegro.dev.null);
|
||||
if (allegro.atlas.default_font)
|
||||
nk_style_set_font(&allegro.ctx, &allegro.atlas.default_font->handle);
|
||||
}
|
||||
|
||||
|
||||
NK_API void
|
||||
nk_allegro_handle_event(ALLEGRO_EVENT *evt)
|
||||
{
|
||||
struct nk_context *ctx = &allegro.ctx;
|
||||
if ((evt->type == ALLEGRO_EVENT_KEY_UP ||
|
||||
evt->type == ALLEGRO_EVENT_KEY_DOWN) &&
|
||||
evt->keyboard.display == allegro.win)
|
||||
{
|
||||
/* key handler */
|
||||
int down = (evt->type == ALLEGRO_EVENT_KEY_UP);
|
||||
int sym = evt->keyboard.keycode;
|
||||
if (sym == ALLEGRO_KEY_RSHIFT || sym == ALLEGRO_KEY_LSHIFT)
|
||||
nk_input_key(ctx, NK_KEY_SHIFT, down);
|
||||
else if (sym == ALLEGRO_KEY_DELETE)
|
||||
nk_input_key(ctx, NK_KEY_DEL, down);
|
||||
else if (sym == ALLEGRO_KEY_ENTER)
|
||||
nk_input_key(ctx, NK_KEY_ENTER, down);
|
||||
else if (sym == ALLEGRO_KEY_TAB)
|
||||
nk_input_key(ctx, NK_KEY_TAB, down);
|
||||
else if (sym == ALLEGRO_KEY_BACKSPACE)
|
||||
nk_input_key(ctx, NK_KEY_BACKSPACE, down);
|
||||
else if (sym == ALLEGRO_KEY_LEFT) {
|
||||
if (evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, down);
|
||||
else nk_input_key(ctx, NK_KEY_LEFT, down);
|
||||
} else if (sym == ALLEGRO_KEY_RIGHT) {
|
||||
if (evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, down);
|
||||
else nk_input_key(ctx, NK_KEY_RIGHT, down);
|
||||
} else if (sym == ALLEGRO_KEY_HOME)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_START, down);
|
||||
else if (sym == ALLEGRO_KEY_END)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_END, down);
|
||||
else if (sym == ALLEGRO_KEY_C)
|
||||
nk_input_key(ctx, NK_KEY_COPY, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
else if (sym == ALLEGRO_KEY_V)
|
||||
nk_input_key(ctx, NK_KEY_PASTE, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
else if (sym == ALLEGRO_KEY_X)
|
||||
nk_input_key(ctx, NK_KEY_CUT, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
else if (sym == ALLEGRO_KEY_Z)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_UNDO, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
else if (sym == ALLEGRO_KEY_R)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_REDO, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
else if (sym == ALLEGRO_KEY_X)
|
||||
nk_input_key(ctx, NK_KEY_CUT, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
else if (sym == ALLEGRO_KEY_B)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
else if (sym == ALLEGRO_KEY_E)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down && evt->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL);
|
||||
|
||||
} else if (evt->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN ||
|
||||
evt->type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) {
|
||||
/* button handler */
|
||||
int down = evt->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN;
|
||||
const int x = evt->mouse.x, y = evt->mouse.y;
|
||||
if (evt->mouse.button == 1)
|
||||
nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down);
|
||||
if (evt->mouse.button == 2)
|
||||
nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down);
|
||||
} else if (evt->type == ALLEGRO_EVENT_MOUSE_AXES) {
|
||||
/* mouse motion */
|
||||
nk_input_motion(ctx, evt->mouse.x, evt->mouse.y);
|
||||
} else if (evt->type == ALLEGRO_EVENT_KEY_CHAR) {
|
||||
/* text input */
|
||||
if (evt->keyboard.display == allegro.win)
|
||||
if (evt->keyboard.unichar > 0 && evt->keyboard.unichar < 0x10000)
|
||||
nk_input_unicode(ctx, (nk_rune)evt->keyboard.unichar);
|
||||
}
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_allegro_shutdown(void)
|
||||
{
|
||||
if (allegro.dev.texture)
|
||||
al_destroy_bitmap(allegro.dev.texture);
|
||||
free(allegro.dev.vertex_buffer);
|
||||
free(allegro.dev.element_buffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -12,17 +12,16 @@
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
/* these defines are both needed for the header
|
||||
* and source file. So if you split them remember
|
||||
* to copy them as well. */
|
||||
#define NK_INCLUDE_FIXED_TYPES
|
||||
#define NK_INCLUDE_STANDARD_IO
|
||||
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
||||
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
|
||||
#define NK_INCLUDE_FONT_BAKING
|
||||
#define NK_INCLUDE_DEFAULT_FONT
|
||||
#include "nuklear_glfw.h"
|
||||
#include "nuklear_glfw.c"
|
||||
#define NK_IMPLEMENTATION
|
||||
#define NK_GLFW_GL2_IMPLEMENTATION
|
||||
#include "../../nuklear.h"
|
||||
#include "nuklear_glfw_gl2.h"
|
||||
|
||||
#define WINDOW_WIDTH 1200
|
||||
#define WINDOW_HEIGHT 800
|
||||
|
@ -1,20 +0,0 @@
|
||||
#ifndef NK_GLFW_H_
|
||||
#define NK_GLFW_H_
|
||||
|
||||
#include "../../nuklear.h"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
enum nk_glfw_init_state{NK_GLFW3_DEFAULT=0, NK_GLFW3_INSTALL_CALLBACKS};
|
||||
NK_API struct nk_context *nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state);
|
||||
NK_API void nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas);
|
||||
NK_API void nk_glfw3_font_stash_end(void);
|
||||
|
||||
NK_API void nk_glfw3_new_frame(void);
|
||||
NK_API void nk_glfw3_render(enum nk_anti_aliasing , int max_vertex_buffer, int max_element_buffer);
|
||||
NK_API void nk_glfw3_shutdown(void);
|
||||
|
||||
NK_API void nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint);
|
||||
NK_API void nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff);
|
||||
|
||||
#endif
|
@ -1,19 +1,50 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <limits.h>
|
||||
/*
|
||||
* Nuklear - v1.00 - public domain
|
||||
* no warrenty implied; use at your own risk.
|
||||
* authored from 2015-2016 by Micha Mettke
|
||||
*/
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* API
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifndef NK_GLFW_GL2_H_
|
||||
#define NK_GLFW_GL2_H_
|
||||
|
||||
#define NK_IMPLEMENTATION
|
||||
#include "nuklear_glfw.h"
|
||||
#include "../../nuklear.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
enum nk_glfw_init_state{
|
||||
NK_GLFW3_DEFAULT = 0,
|
||||
NK_GLFW3_INSTALL_CALLBACKS
|
||||
};
|
||||
NK_API struct nk_context* nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state);
|
||||
NK_API void nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas);
|
||||
NK_API void nk_glfw3_font_stash_end(void);
|
||||
|
||||
NK_API void nk_glfw3_new_frame(void);
|
||||
NK_API void nk_glfw3_render(enum nk_anti_aliasing , int max_vertex_buffer, int max_element_buffer);
|
||||
NK_API void nk_glfw3_shutdown(void);
|
||||
|
||||
NK_API void nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint);
|
||||
NK_API void nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* IMPLEMENTATION
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifdef NK_GLFW_GL2_IMPLEMENTATION
|
||||
|
||||
#ifndef NK_GLFW_TEXT_MAX
|
||||
#define NK_GLFW_TEXT_MAX 256
|
||||
#endif
|
||||
|
||||
struct nk_glfw_device {
|
||||
struct nk_buffer cmds;
|
||||
struct nk_draw_null_texture null;
|
||||
@ -285,3 +316,5 @@ void nk_glfw3_shutdown(void)
|
||||
memset(&glfw, 0, sizeof(glfw));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -13,17 +13,16 @@
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
/* these defines are both needed for the header
|
||||
* and source file. So if you split them remember
|
||||
* to copy them as well. */
|
||||
#define NK_INCLUDE_FIXED_TYPES
|
||||
#define NK_INCLUDE_STANDARD_IO
|
||||
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
||||
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
|
||||
#define NK_INCLUDE_FONT_BAKING
|
||||
#define NK_INCLUDE_DEFAULT_FONT
|
||||
#include "nuklear_glfw.h"
|
||||
#include "nuklear_glfw.c"
|
||||
#define NK_IMPLEMENTATION
|
||||
#define NK_GLFW_GL3_IMPLEMENTATION
|
||||
#include "../../nuklear.h"
|
||||
#include "nuklear_glfw_gl3.h"
|
||||
|
||||
#define WINDOW_WIDTH 1200
|
||||
#define WINDOW_HEIGHT 800
|
||||
|
@ -1,23 +0,0 @@
|
||||
#ifndef NK_GLFW_H_
|
||||
#define NK_GLFW_H_
|
||||
|
||||
#include "../../nuklear.h"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
enum nk_glfw_init_state{NK_GLFW3_DEFAULT=0, NK_GLFW3_INSTALL_CALLBACKS};
|
||||
NK_API struct nk_context *nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state);
|
||||
NK_API void nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas);
|
||||
NK_API void nk_glfw3_font_stash_end(void);
|
||||
|
||||
NK_API void nk_glfw3_new_frame(void);
|
||||
NK_API void nk_glfw3_render(enum nk_anti_aliasing , int max_vertex_buffer, int max_element_buffer);
|
||||
NK_API void nk_glfw3_shutdown(void);
|
||||
|
||||
NK_API void nk_glfw3_device_destroy(void);
|
||||
NK_API void nk_glfw3_device_create(void);
|
||||
|
||||
NK_API void nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint);
|
||||
NK_API void nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff);
|
||||
|
||||
#endif
|
@ -1,19 +1,52 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <limits.h>
|
||||
/*
|
||||
* Nuklear - v1.00 - public domain
|
||||
* no warrenty implied; use at your own risk.
|
||||
* authored from 2015-2016 by Micha Mettke
|
||||
*/
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* API
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifndef NK_GLFW_GL3_H_
|
||||
#define NK_GLFW_GL3_H_
|
||||
|
||||
#define NK_IMPLEMENTATION
|
||||
#include "nuklear_glfw.h"
|
||||
#include "../../nuklear.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
enum nk_glfw_init_state{
|
||||
NK_GLFW3_DEFAULT=0,
|
||||
NK_GLFW3_INSTALL_CALLBACKS
|
||||
};
|
||||
|
||||
NK_API struct nk_context* nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state);
|
||||
NK_API void nk_glfw3_shutdown(void);
|
||||
NK_API void nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas);
|
||||
NK_API void nk_glfw3_font_stash_end(void);
|
||||
NK_API void nk_glfw3_new_frame(void);
|
||||
NK_API void nk_glfw3_render(enum nk_anti_aliasing, int max_vertex_buffer, int max_element_buffer);
|
||||
|
||||
NK_API void nk_glfw3_device_destroy(void);
|
||||
NK_API void nk_glfw3_device_create(void);
|
||||
|
||||
NK_API void nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint);
|
||||
NK_API void nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff);
|
||||
|
||||
#endif
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* IMPLEMENTATION
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifdef NK_GLFW_GL3_IMPLEMENTATION
|
||||
|
||||
#ifndef NK_GLFW_TEXT_MAX
|
||||
#define NK_GLFW_TEXT_MAX 256
|
||||
#endif
|
||||
|
||||
struct nk_glfw_device {
|
||||
struct nk_buffer cmds;
|
||||
struct nk_draw_null_texture null;
|
||||
@ -389,3 +422,4 @@ void nk_glfw3_shutdown(void)
|
||||
memset(&glfw, 0, sizeof(glfw));
|
||||
}
|
||||
|
||||
#endif
|
11
demo/sdl1_2/main.c
Executable file → Normal file
11
demo/sdl1_2/main.c
Executable file → Normal file
@ -10,13 +10,13 @@
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
/* these defines are both needed for the header
|
||||
* and source file. So if you split them remember
|
||||
* to copy them as well. */
|
||||
#define NK_INCLUDE_FIXED_TYPES
|
||||
#define NK_INCLUDE_STANDARD_IO
|
||||
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
||||
#define NK_IMPLEMENTATION
|
||||
#define NK_SDL_IMPLEMENTATION
|
||||
#include "../../nuklear.h"
|
||||
#include "nuklear_sdl.h"
|
||||
#include "nuklear_sdl.c"
|
||||
|
||||
#define WINDOW_WIDTH 800
|
||||
#define WINDOW_HEIGHT 600
|
||||
@ -39,8 +39,7 @@
|
||||
* DEMO
|
||||
*
|
||||
* ===============================================================*/
|
||||
int
|
||||
main(void)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
static SDL_Surface *screen_surface;
|
||||
struct nk_color background;
|
||||
|
@ -1,441 +0,0 @@
|
||||
#include <string.h>
|
||||
#include <SDL/SDL.h>
|
||||
#include <SDL/SDL_gfxPrimitives.h>
|
||||
|
||||
#include "nuklear_sdl.h"
|
||||
#define NK_IMPLEMENTATION
|
||||
#include "../../nuklear.h"
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) ((a) < (b) ? (b) : (a))
|
||||
#endif
|
||||
|
||||
#define NK_SDL_MAX_POINTS 128
|
||||
|
||||
struct nk_sdl_Font {
|
||||
int width;
|
||||
int height;
|
||||
int handle;
|
||||
};
|
||||
|
||||
static struct nk_sdl {
|
||||
SDL_Surface *screen_surface;
|
||||
struct nk_context ctx;
|
||||
} sdl;
|
||||
|
||||
static nk_sdl_Font *sdl_font;
|
||||
static SDL_Rect sdl_clip_rect;
|
||||
|
||||
static void
|
||||
nk_sdl_scissor(SDL_Surface *surface, float x, float y, float w, float h)
|
||||
{
|
||||
sdl_clip_rect.x = x;
|
||||
sdl_clip_rect.y = y;
|
||||
sdl_clip_rect.w = w + 1;
|
||||
sdl_clip_rect.h = h;
|
||||
SDL_SetClipRect(surface, &sdl_clip_rect);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_stroke_line(SDL_Surface *surface, short x0, short y0, short x1,
|
||||
short y1, unsigned int line_thickness, struct nk_color col)
|
||||
{
|
||||
thickLineRGBA(surface, x0, y0, x1, y1, line_thickness, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_stroke_rect(SDL_Surface *surface, short x, short y, unsigned short w,
|
||||
unsigned short h, unsigned short r, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
/* Note: thickness is not used by default */
|
||||
if (r == 0) {
|
||||
rectangleRGBA(surface, x, y, x + w, y + h, col.r, col.g, col.b, col.a);
|
||||
} else {
|
||||
roundedRectangleRGBA(surface, x, y, x + w, y + h, r, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_fill_rect(SDL_Surface *surface, short x, short y, unsigned short w,
|
||||
unsigned short h, unsigned short r, struct nk_color col)
|
||||
{
|
||||
if (r == 0) {
|
||||
boxRGBA(surface, x, y, x + w, y + h, col.r, col.g, col.b, col.a);
|
||||
} else {
|
||||
roundedBoxRGBA(surface, x, y, x + w, y + h, r, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_fill_triangle(SDL_Surface *surface, short x0, short y0, short x1, short y1, short x2, short y2, struct nk_color col)
|
||||
{
|
||||
filledTrigonRGBA(surface, x0, y0, x1, y1, x2, y2, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_stroke_triangle(SDL_Surface *surface, short x0, short y0, short x1,
|
||||
short y1, short x2, short y2, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
/* Note: thickness is not used by default */
|
||||
aatrigonRGBA(surface, x0, y0, x1, y1, x2, y2, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_fill_polygon(SDL_Surface *surface, const struct nk_vec2i *pnts, int count, struct nk_color col)
|
||||
{
|
||||
Sint16 p_x[NK_SDL_MAX_POINTS];
|
||||
Sint16 p_y[NK_SDL_MAX_POINTS];
|
||||
int i;
|
||||
for (i = 0; (i < count) && (i < NK_SDL_MAX_POINTS); ++i) {
|
||||
p_x[i] = pnts[i].x;
|
||||
p_y[i] = pnts[i].y;
|
||||
}
|
||||
filledPolygonRGBA (surface, (Sint16 *)p_x, (Sint16 *)p_y, count, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_stroke_polygon(SDL_Surface *surface, const struct nk_vec2i *pnts, int count,
|
||||
unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
/* Note: thickness is not used by default */
|
||||
Sint16 p_x[NK_SDL_MAX_POINTS];
|
||||
Sint16 p_y[NK_SDL_MAX_POINTS];
|
||||
int i;
|
||||
for (i = 0; (i < count) && (i < NK_SDL_MAX_POINTS); ++i) {
|
||||
p_x[i] = pnts[i].x;
|
||||
p_y[i] = pnts[i].y;
|
||||
}
|
||||
aapolygonRGBA(surface, (Sint16 *)p_x, (Sint16 *)p_y, count, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_stroke_polyline(SDL_Surface *surface, const struct nk_vec2i *pnts,
|
||||
int count, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
int x0, y0, x1, y1;
|
||||
if (count == 1) {
|
||||
x0 = pnts[0].x;
|
||||
y0 = pnts[0].y;
|
||||
x1 = x0;
|
||||
y1 = y0;
|
||||
thickLineRGBA(surface, x0, y0, x1, y1, line_thickness, col.r, col.g, col.b, col.a);
|
||||
} else if (count >= 2) {
|
||||
int i;
|
||||
for (i = 0; i < (count - 1); i++) {
|
||||
x0 = pnts[i].x;
|
||||
y0 = pnts[i].y;
|
||||
x1 = pnts[i + 1].x;
|
||||
y1 = pnts[i + 1].y;
|
||||
thickLineRGBA(surface, x0, y0, x1, y1, line_thickness, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_fill_circle(SDL_Surface *surface, short x, short y, unsigned short w,
|
||||
unsigned short h, struct nk_color col)
|
||||
{
|
||||
filledEllipseRGBA(surface, x + w /2, y + h /2, w / 2, h / 2, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_stroke_circle(SDL_Surface *surface, short x, short y, unsigned short w,
|
||||
unsigned short h, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
/* Note: thickness is not used by default */
|
||||
aaellipseRGBA (surface, x + w /2, y + h /2, w / 2, h / 2, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_stroke_curve(SDL_Surface *surface, struct nk_vec2i p1,
|
||||
struct nk_vec2i p2, struct nk_vec2i p3, struct nk_vec2i p4, unsigned int num_segments,
|
||||
unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
unsigned int i_step;
|
||||
float t_step;
|
||||
struct nk_vec2i last = p1;
|
||||
|
||||
num_segments = MAX(num_segments, 1);
|
||||
t_step = 1.0f/(float)num_segments;
|
||||
for (i_step = 1; i_step <= num_segments; ++i_step) {
|
||||
float t = t_step * (float)i_step;
|
||||
float u = 1.0f - t;
|
||||
float w1 = u*u*u;
|
||||
float w2 = 3*u*u*t;
|
||||
float w3 = 3*u*t*t;
|
||||
float w4 = t * t *t;
|
||||
float x = w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x;
|
||||
float y = w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y;
|
||||
nk_sdl_stroke_line(surface, last.x, last.y, (short)x, (short)y, line_thickness, col);
|
||||
last.x = (short)x; last.y = (short)y;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_draw_text(SDL_Surface *surface, short x, short y, unsigned short w, unsigned short h,
|
||||
const char *text, int len, nk_sdl_Font *font, struct nk_color cbg, struct nk_color cfg)
|
||||
{
|
||||
int i;
|
||||
nk_sdl_fill_rect(surface, x, y, len * font->width, font->height, 0, cbg);
|
||||
for (i = 0; i < len; i++) {
|
||||
characterRGBA(surface, x, y, text[i], cfg.r, cfg.g, cfg.b, cfg.a);
|
||||
x += font->width;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
interpolate_color(struct nk_color c1, struct nk_color c2, struct nk_color *result, float fraction)
|
||||
{
|
||||
float r = c1.r + (c2.r - c1.r) * fraction;
|
||||
float g = c1.g + (c2.g - c1.g) * fraction;
|
||||
float b = c1.b + (c2.b - c1.b) * fraction;
|
||||
float a = c1.a + (c2.a - c1.a) * fraction;
|
||||
|
||||
result->r = (nk_byte)NK_CLAMP(0, r, 255);
|
||||
result->g = (nk_byte)NK_CLAMP(0, g, 255);
|
||||
result->b = (nk_byte)NK_CLAMP(0, b, 255);
|
||||
result->a = (nk_byte)NK_CLAMP(0, a, 255);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_fill_rect_multi_color(SDL_Surface *surface, short x, short y, unsigned short w, unsigned short h,
|
||||
struct nk_color left, struct nk_color top, struct nk_color right, struct nk_color bottom)
|
||||
{
|
||||
struct nk_color X1, X2, Y;
|
||||
float fraction_x, fraction_y;
|
||||
int i,j;
|
||||
|
||||
for (j = 0; j < h; j++) {
|
||||
fraction_y = ((float)j) / h;
|
||||
for (i = 0; i < w; i++) {
|
||||
fraction_x = ((float)i) / w;
|
||||
interpolate_color(left, top, &X1, fraction_x);
|
||||
interpolate_color(right, bottom, &X2, fraction_x);
|
||||
interpolate_color(X1, X2, &Y, fraction_y);
|
||||
pixelRGBA(surface, x + i, y + j, Y.r, Y.g, Y.b, Y.a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_clear(SDL_Surface *surface, struct nk_color col)
|
||||
{
|
||||
nk_sdl_fill_rect(surface, 0, 0, surface->w, surface->h, 0, col);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_blit(SDL_Surface *surface)
|
||||
{
|
||||
SDL_UpdateRect(surface, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_sdl_render(struct nk_color clear)
|
||||
{
|
||||
const struct nk_command *cmd;
|
||||
|
||||
SDL_Surface *screen_surface = sdl.screen_surface;
|
||||
nk_sdl_clear(screen_surface, clear);
|
||||
|
||||
nk_foreach(cmd, &sdl.ctx)
|
||||
{
|
||||
switch (cmd->type) {
|
||||
case NK_COMMAND_NOP: break;
|
||||
case NK_COMMAND_SCISSOR: {
|
||||
const struct nk_command_scissor *s =(const struct nk_command_scissor*)cmd;
|
||||
nk_sdl_scissor(screen_surface, s->x, s->y, s->w, s->h);
|
||||
} break;
|
||||
case NK_COMMAND_LINE: {
|
||||
const struct nk_command_line *l = (const struct nk_command_line *)cmd;
|
||||
nk_sdl_stroke_line(screen_surface, l->begin.x, l->begin.y, l->end.x,
|
||||
l->end.y, l->line_thickness, l->color);
|
||||
} break;
|
||||
case NK_COMMAND_RECT: {
|
||||
const struct nk_command_rect *r = (const struct nk_command_rect *)cmd;
|
||||
nk_sdl_stroke_rect(screen_surface, r->x, r->y, r->w, r->h,
|
||||
(unsigned short)r->rounding, r->line_thickness, r->color);
|
||||
} break;
|
||||
case NK_COMMAND_RECT_FILLED: {
|
||||
const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled *)cmd;
|
||||
nk_sdl_fill_rect(screen_surface, r->x, r->y, r->w, r->h,
|
||||
(unsigned short)r->rounding, r->color);
|
||||
} break;
|
||||
case NK_COMMAND_CIRCLE: {
|
||||
const struct nk_command_circle *c = (const struct nk_command_circle *)cmd;
|
||||
nk_sdl_stroke_circle(screen_surface, c->x, c->y, c->w, c->h, c->line_thickness, c->color);
|
||||
} break;
|
||||
case NK_COMMAND_CIRCLE_FILLED: {
|
||||
const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
|
||||
nk_sdl_fill_circle(screen_surface, c->x, c->y, c->w, c->h, c->color);
|
||||
} break;
|
||||
case NK_COMMAND_TRIANGLE: {
|
||||
const struct nk_command_triangle*t = (const struct nk_command_triangle*)cmd;
|
||||
nk_sdl_stroke_triangle(screen_surface, t->a.x, t->a.y, t->b.x, t->b.y,
|
||||
t->c.x, t->c.y, t->line_thickness, t->color);
|
||||
} break;
|
||||
case NK_COMMAND_TRIANGLE_FILLED: {
|
||||
const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled *)cmd;
|
||||
nk_sdl_fill_triangle(screen_surface, t->a.x, t->a.y, t->b.x, t->b.y, t->c.x, t->c.y, t->color);
|
||||
} break;
|
||||
case NK_COMMAND_POLYGON: {
|
||||
const struct nk_command_polygon *p =(const struct nk_command_polygon*)cmd;
|
||||
nk_sdl_stroke_polygon(screen_surface, p->points, p->point_count, p->line_thickness,p->color);
|
||||
} break;
|
||||
case NK_COMMAND_POLYGON_FILLED: {
|
||||
const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled *)cmd;
|
||||
nk_sdl_fill_polygon(screen_surface, p->points, p->point_count, p->color);
|
||||
} break;
|
||||
case NK_COMMAND_POLYLINE: {
|
||||
const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd;
|
||||
nk_sdl_stroke_polyline(screen_surface, p->points, p->point_count, p->line_thickness, p->color);
|
||||
} break;
|
||||
case NK_COMMAND_TEXT: {
|
||||
const struct nk_command_text *t = (const struct nk_command_text*)cmd;
|
||||
nk_sdl_draw_text(screen_surface, t->x, t->y, t->w, t->h,
|
||||
(const char*)t->string, t->length,
|
||||
(nk_sdl_Font*)t->font->userdata.ptr,
|
||||
t->background, t->foreground);
|
||||
} break;
|
||||
case NK_COMMAND_CURVE: {
|
||||
const struct nk_command_curve *q = (const struct nk_command_curve *)cmd;
|
||||
nk_sdl_stroke_curve(screen_surface, q->begin, q->ctrl[0], q->ctrl[1],
|
||||
q->end, 22, q->line_thickness, q->color);
|
||||
} break;
|
||||
case NK_COMMAND_RECT_MULTI_COLOR: {
|
||||
const struct nk_command_rect_multi_color *r = (const struct nk_command_rect_multi_color *)cmd;
|
||||
nk_sdl_fill_rect_multi_color(screen_surface, r->x, r->y, r->w, r->h, r->left, r->top, r->right, r->bottom);
|
||||
} break;
|
||||
case NK_COMMAND_IMAGE:
|
||||
case NK_COMMAND_ARC:
|
||||
case NK_COMMAND_ARC_FILLED:
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
nk_sdl_blit(sdl.screen_surface);
|
||||
nk_clear(&sdl.ctx);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_clipbard_paste(nk_handle usr, struct nk_text_edit *edit)
|
||||
{
|
||||
/* Not supported in SDL 1.2. Use platform specific code. */
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_clipbard_copy(nk_handle usr, const char *text, int len)
|
||||
{
|
||||
/* Not supported in SDL 1.2. Use platform specific code. */
|
||||
}
|
||||
|
||||
static float
|
||||
nk_sdl_get_text_width(nk_handle handle, float height, const char *text, int len)
|
||||
{
|
||||
return len * sdl_font->width;
|
||||
}
|
||||
|
||||
NK_API struct nk_context*
|
||||
nk_sdl_init(SDL_Surface *screen_surface)
|
||||
{
|
||||
struct nk_user_font font;
|
||||
sdl_font = (nk_sdl_Font*)calloc(1, sizeof(nk_sdl_Font));
|
||||
sdl_font->width = 8; /* Default in the SDL_gfx library */
|
||||
sdl_font->height = 8; /* Default in the SDL_gfx library */
|
||||
if (!sdl_font)
|
||||
return NULL;
|
||||
|
||||
font.userdata = nk_handle_ptr(sdl_font);
|
||||
font.height = (float)sdl_font->height;
|
||||
font.width = nk_sdl_get_text_width;
|
||||
|
||||
sdl.screen_surface = screen_surface;
|
||||
nk_init_default(&sdl.ctx, &font);
|
||||
sdl.ctx.clip.copy = nk_sdl_clipbard_copy;
|
||||
sdl.ctx.clip.paste = nk_sdl_clipbard_paste;
|
||||
sdl.ctx.clip.userdata = nk_handle_ptr(0);
|
||||
return &sdl.ctx;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_sdl_handle_event(SDL_Event *evt)
|
||||
{
|
||||
|
||||
struct nk_context *ctx = &sdl.ctx;
|
||||
if (evt->type == SDL_VIDEORESIZE) {
|
||||
/* Do nothing */
|
||||
} else if (evt->type == SDL_KEYUP || evt->type == SDL_KEYDOWN) {
|
||||
/* key events */
|
||||
int down = evt->type == SDL_KEYDOWN;
|
||||
SDLMod state = SDL_GetModState();
|
||||
SDLKey sym = evt->key.keysym.sym;
|
||||
|
||||
if (sym == SDLK_RSHIFT || sym == SDLK_LSHIFT) nk_input_key(ctx, NK_KEY_SHIFT, down);
|
||||
else if (sym == SDLK_DELETE) nk_input_key(ctx, NK_KEY_DEL, down);
|
||||
else if (sym == SDLK_RETURN) nk_input_key(ctx, NK_KEY_ENTER, down);
|
||||
else if (sym == SDLK_TAB) nk_input_key(ctx, NK_KEY_TAB, down);
|
||||
else if (sym == SDLK_LEFT) nk_input_key(ctx, NK_KEY_LEFT, down);
|
||||
else if (sym == SDLK_RIGHT) nk_input_key(ctx, NK_KEY_RIGHT, down);
|
||||
else if (sym == SDLK_BACKSPACE) nk_input_key(ctx, NK_KEY_BACKSPACE, down);
|
||||
else if (sym == SDLK_HOME) nk_input_key(ctx, NK_KEY_TEXT_START, down);
|
||||
else if (sym == SDLK_END) nk_input_key(ctx, NK_KEY_TEXT_END, down);
|
||||
else if (sym == SDLK_SPACE && !down) nk_input_char(ctx, ' ');
|
||||
else {
|
||||
if (sym == SDLK_c && state == SDLK_LCTRL)
|
||||
nk_input_key(ctx, NK_KEY_COPY, down);
|
||||
else if (sym == SDLK_v && state == SDLK_LCTRL)
|
||||
nk_input_key(ctx, NK_KEY_PASTE, down);
|
||||
else if (sym == SDLK_x && state == SDLK_LCTRL)
|
||||
nk_input_key(ctx, NK_KEY_CUT, down);
|
||||
else if (sym == SDLK_z && state == SDLK_LCTRL)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_UNDO, down);
|
||||
else if (sym == SDLK_r && state == SDLK_LCTRL)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_REDO, down);
|
||||
else if (sym == SDLK_LEFT && state == SDLK_LCTRL)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, down);
|
||||
else if (sym == SDLK_RIGHT && state == SDLK_LCTRL)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, down);
|
||||
else if (sym == SDLK_b && state == SDLK_LCTRL)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down);
|
||||
else if (sym == SDLK_e && state == SDLK_LCTRL)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down);
|
||||
else if (!down) {
|
||||
/* This demo does not provide full unicode support since the default
|
||||
* sdl1.2 font only allows runes in range 0-255. But this demo
|
||||
* already is quite limited and not really meant for full blown Apps
|
||||
* anyway. So I think ASCII support for Debugging Tools should be enough */
|
||||
if (sym >= SDLK_0 && sym <= SDLK_9) {
|
||||
nk_rune rune = '0' + sym - SDLK_0;
|
||||
nk_input_unicode(ctx, rune);
|
||||
} else if (sym >= SDLK_a && sym <= SDLK_z) {
|
||||
nk_rune rune = 'a' + sym - SDLK_a;
|
||||
rune = ((state == KMOD_LSHIFT) ? (nk_rune)nk_to_upper((int)rune):rune);
|
||||
nk_input_unicode(ctx, rune);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (evt->type == SDL_MOUSEBUTTONDOWN || evt->type == SDL_MOUSEBUTTONUP) {
|
||||
/* mouse button */
|
||||
int down = evt->type == SDL_MOUSEBUTTONDOWN;
|
||||
const int x = evt->button.x, y = evt->button.y;
|
||||
if (evt->button.button == SDL_BUTTON_LEFT)
|
||||
nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down);
|
||||
if (evt->button.button == SDL_BUTTON_MIDDLE)
|
||||
nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down);
|
||||
if (evt->button.button == SDL_BUTTON_RIGHT)
|
||||
nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down);
|
||||
if (evt->button.button == SDL_BUTTON_WHEELUP)
|
||||
nk_input_scroll(ctx, 1.0f);
|
||||
if (evt->button.button == SDL_BUTTON_WHEELDOWN)
|
||||
nk_input_scroll(ctx, -1.0f);
|
||||
} else if (evt->type == SDL_MOUSEMOTION) {
|
||||
nk_input_motion(ctx, evt->motion.x, evt->motion.y);
|
||||
}
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_sdl_shutdown(void)
|
||||
{
|
||||
free(sdl_font);
|
||||
nk_free(&sdl.ctx);
|
||||
}
|
||||
|
475
demo/sdl1_2/nuklear_sdl.h
Executable file → Normal file
475
demo/sdl1_2/nuklear_sdl.h
Executable file → Normal file
@ -1,15 +1,474 @@
|
||||
/*
|
||||
* Nuklear - v1.00 - public domain
|
||||
* no warrenty implied; use at your own risk.
|
||||
* authored from 2015-2016 by Micha Mettke
|
||||
*/
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* API
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifndef NK_SDL_H_
|
||||
#define NK_SDL_H_
|
||||
|
||||
#include "../../nuklear.h"
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
typedef struct nk_sdl_Font nk_sdl_Font;
|
||||
|
||||
NK_API struct nk_context *nk_sdl_init(SDL_Surface *screen_surface);
|
||||
NK_API void nk_sdl_handle_event(SDL_Event *evt);
|
||||
NK_API void nk_sdl_render(struct nk_color clear);
|
||||
NK_API void nk_sdl_shutdown(void);
|
||||
NK_API struct nk_context* nk_sdl_init(SDL_Surface *screen_surface);
|
||||
NK_API void nk_sdl_handle_event(SDL_Event *evt);
|
||||
NK_API void nk_sdl_render(struct nk_color clear);
|
||||
NK_API void nk_sdl_shutdown(void);
|
||||
|
||||
#endif
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* IMPLEMENTATION
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifdef NK_SDL_IMPLEMENTATION
|
||||
|
||||
#include <string.h>
|
||||
#include <SDL/SDL.h>
|
||||
#include <SDL/SDL_gfxPrimitives.h>
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) ((a) < (b) ? (b) : (a))
|
||||
#endif
|
||||
|
||||
#ifndef NK_SDL_MAX_POINTS
|
||||
#define NK_SDL_MAX_POINTS 128
|
||||
#endif
|
||||
|
||||
struct nk_sdl_Font {
|
||||
int width;
|
||||
int height;
|
||||
int handle;
|
||||
};
|
||||
|
||||
static struct nk_sdl {
|
||||
SDL_Surface *screen_surface;
|
||||
struct nk_context ctx;
|
||||
} sdl;
|
||||
|
||||
static nk_sdl_Font *sdl_font;
|
||||
static SDL_Rect sdl_clip_rect;
|
||||
|
||||
static void
|
||||
nk_sdl_scissor(SDL_Surface *surface, float x, float y, float w, float h)
|
||||
{
|
||||
sdl_clip_rect.x = x;
|
||||
sdl_clip_rect.y = y;
|
||||
sdl_clip_rect.w = w + 1;
|
||||
sdl_clip_rect.h = h;
|
||||
SDL_SetClipRect(surface, &sdl_clip_rect);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_stroke_line(SDL_Surface *surface, short x0, short y0, short x1,
|
||||
short y1, unsigned int line_thickness, struct nk_color col)
|
||||
{
|
||||
thickLineRGBA(surface, x0, y0, x1, y1, line_thickness, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_stroke_rect(SDL_Surface *surface, short x, short y, unsigned short w,
|
||||
unsigned short h, unsigned short r, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
/* Note: thickness is not used by default */
|
||||
if (r == 0) {
|
||||
rectangleRGBA(surface, x, y, x + w, y + h, col.r, col.g, col.b, col.a);
|
||||
} else {
|
||||
roundedRectangleRGBA(surface, x, y, x + w, y + h, r, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_fill_rect(SDL_Surface *surface, short x, short y, unsigned short w,
|
||||
unsigned short h, unsigned short r, struct nk_color col)
|
||||
{
|
||||
if (r == 0) {
|
||||
boxRGBA(surface, x, y, x + w, y + h, col.r, col.g, col.b, col.a);
|
||||
} else {
|
||||
roundedBoxRGBA(surface, x, y, x + w, y + h, r, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_fill_triangle(SDL_Surface *surface, short x0, short y0, short x1, short y1, short x2, short y2, struct nk_color col)
|
||||
{
|
||||
filledTrigonRGBA(surface, x0, y0, x1, y1, x2, y2, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_stroke_triangle(SDL_Surface *surface, short x0, short y0, short x1,
|
||||
short y1, short x2, short y2, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
/* Note: thickness is not used by default */
|
||||
aatrigonRGBA(surface, x0, y0, x1, y1, x2, y2, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_fill_polygon(SDL_Surface *surface, const struct nk_vec2i *pnts, int count, struct nk_color col)
|
||||
{
|
||||
Sint16 p_x[NK_SDL_MAX_POINTS];
|
||||
Sint16 p_y[NK_SDL_MAX_POINTS];
|
||||
int i;
|
||||
for (i = 0; (i < count) && (i < NK_SDL_MAX_POINTS); ++i) {
|
||||
p_x[i] = pnts[i].x;
|
||||
p_y[i] = pnts[i].y;
|
||||
}
|
||||
filledPolygonRGBA (surface, (Sint16 *)p_x, (Sint16 *)p_y, count, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_stroke_polygon(SDL_Surface *surface, const struct nk_vec2i *pnts, int count,
|
||||
unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
/* Note: thickness is not used by default */
|
||||
Sint16 p_x[NK_SDL_MAX_POINTS];
|
||||
Sint16 p_y[NK_SDL_MAX_POINTS];
|
||||
int i;
|
||||
for (i = 0; (i < count) && (i < NK_SDL_MAX_POINTS); ++i) {
|
||||
p_x[i] = pnts[i].x;
|
||||
p_y[i] = pnts[i].y;
|
||||
}
|
||||
aapolygonRGBA(surface, (Sint16 *)p_x, (Sint16 *)p_y, count, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_stroke_polyline(SDL_Surface *surface, const struct nk_vec2i *pnts,
|
||||
int count, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
int x0, y0, x1, y1;
|
||||
if (count == 1) {
|
||||
x0 = pnts[0].x;
|
||||
y0 = pnts[0].y;
|
||||
x1 = x0;
|
||||
y1 = y0;
|
||||
thickLineRGBA(surface, x0, y0, x1, y1, line_thickness, col.r, col.g, col.b, col.a);
|
||||
} else if (count >= 2) {
|
||||
int i;
|
||||
for (i = 0; i < (count - 1); i++) {
|
||||
x0 = pnts[i].x;
|
||||
y0 = pnts[i].y;
|
||||
x1 = pnts[i + 1].x;
|
||||
y1 = pnts[i + 1].y;
|
||||
thickLineRGBA(surface, x0, y0, x1, y1, line_thickness, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_fill_circle(SDL_Surface *surface, short x, short y, unsigned short w,
|
||||
unsigned short h, struct nk_color col)
|
||||
{
|
||||
filledEllipseRGBA(surface, x + w /2, y + h /2, w / 2, h / 2, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_stroke_circle(SDL_Surface *surface, short x, short y, unsigned short w,
|
||||
unsigned short h, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
/* Note: thickness is not used by default */
|
||||
aaellipseRGBA (surface, x + w /2, y + h /2, w / 2, h / 2, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_stroke_curve(SDL_Surface *surface, struct nk_vec2i p1,
|
||||
struct nk_vec2i p2, struct nk_vec2i p3, struct nk_vec2i p4, unsigned int num_segments,
|
||||
unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
unsigned int i_step;
|
||||
float t_step;
|
||||
struct nk_vec2i last = p1;
|
||||
|
||||
num_segments = MAX(num_segments, 1);
|
||||
t_step = 1.0f/(float)num_segments;
|
||||
for (i_step = 1; i_step <= num_segments; ++i_step) {
|
||||
float t = t_step * (float)i_step;
|
||||
float u = 1.0f - t;
|
||||
float w1 = u*u*u;
|
||||
float w2 = 3*u*u*t;
|
||||
float w3 = 3*u*t*t;
|
||||
float w4 = t * t *t;
|
||||
float x = w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x;
|
||||
float y = w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y;
|
||||
nk_sdl_stroke_line(surface, last.x, last.y, (short)x, (short)y, line_thickness, col);
|
||||
last.x = (short)x; last.y = (short)y;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_draw_text(SDL_Surface *surface, short x, short y, unsigned short w, unsigned short h,
|
||||
const char *text, int len, nk_sdl_Font *font, struct nk_color cbg, struct nk_color cfg)
|
||||
{
|
||||
int i;
|
||||
nk_sdl_fill_rect(surface, x, y, len * font->width, font->height, 0, cbg);
|
||||
for (i = 0; i < len; i++) {
|
||||
characterRGBA(surface, x, y, text[i], cfg.r, cfg.g, cfg.b, cfg.a);
|
||||
x += font->width;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
interpolate_color(struct nk_color c1, struct nk_color c2, struct nk_color *result, float fraction)
|
||||
{
|
||||
float r = c1.r + (c2.r - c1.r) * fraction;
|
||||
float g = c1.g + (c2.g - c1.g) * fraction;
|
||||
float b = c1.b + (c2.b - c1.b) * fraction;
|
||||
float a = c1.a + (c2.a - c1.a) * fraction;
|
||||
|
||||
result->r = (nk_byte)NK_CLAMP(0, r, 255);
|
||||
result->g = (nk_byte)NK_CLAMP(0, g, 255);
|
||||
result->b = (nk_byte)NK_CLAMP(0, b, 255);
|
||||
result->a = (nk_byte)NK_CLAMP(0, a, 255);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_fill_rect_multi_color(SDL_Surface *surface, short x, short y, unsigned short w, unsigned short h,
|
||||
struct nk_color left, struct nk_color top, struct nk_color right, struct nk_color bottom)
|
||||
{
|
||||
struct nk_color X1, X2, Y;
|
||||
float fraction_x, fraction_y;
|
||||
int i,j;
|
||||
|
||||
for (j = 0; j < h; j++) {
|
||||
fraction_y = ((float)j) / h;
|
||||
for (i = 0; i < w; i++) {
|
||||
fraction_x = ((float)i) / w;
|
||||
interpolate_color(left, top, &X1, fraction_x);
|
||||
interpolate_color(right, bottom, &X2, fraction_x);
|
||||
interpolate_color(X1, X2, &Y, fraction_y);
|
||||
pixelRGBA(surface, x + i, y + j, Y.r, Y.g, Y.b, Y.a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_clear(SDL_Surface *surface, struct nk_color col)
|
||||
{
|
||||
nk_sdl_fill_rect(surface, 0, 0, surface->w, surface->h, 0, col);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_blit(SDL_Surface *surface)
|
||||
{
|
||||
SDL_UpdateRect(surface, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_sdl_render(struct nk_color clear)
|
||||
{
|
||||
const struct nk_command *cmd;
|
||||
|
||||
SDL_Surface *screen_surface = sdl.screen_surface;
|
||||
nk_sdl_clear(screen_surface, clear);
|
||||
|
||||
nk_foreach(cmd, &sdl.ctx)
|
||||
{
|
||||
switch (cmd->type) {
|
||||
case NK_COMMAND_NOP: break;
|
||||
case NK_COMMAND_SCISSOR: {
|
||||
const struct nk_command_scissor *s =(const struct nk_command_scissor*)cmd;
|
||||
nk_sdl_scissor(screen_surface, s->x, s->y, s->w, s->h);
|
||||
} break;
|
||||
case NK_COMMAND_LINE: {
|
||||
const struct nk_command_line *l = (const struct nk_command_line *)cmd;
|
||||
nk_sdl_stroke_line(screen_surface, l->begin.x, l->begin.y, l->end.x,
|
||||
l->end.y, l->line_thickness, l->color);
|
||||
} break;
|
||||
case NK_COMMAND_RECT: {
|
||||
const struct nk_command_rect *r = (const struct nk_command_rect *)cmd;
|
||||
nk_sdl_stroke_rect(screen_surface, r->x, r->y, r->w, r->h,
|
||||
(unsigned short)r->rounding, r->line_thickness, r->color);
|
||||
} break;
|
||||
case NK_COMMAND_RECT_FILLED: {
|
||||
const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled *)cmd;
|
||||
nk_sdl_fill_rect(screen_surface, r->x, r->y, r->w, r->h,
|
||||
(unsigned short)r->rounding, r->color);
|
||||
} break;
|
||||
case NK_COMMAND_CIRCLE: {
|
||||
const struct nk_command_circle *c = (const struct nk_command_circle *)cmd;
|
||||
nk_sdl_stroke_circle(screen_surface, c->x, c->y, c->w, c->h, c->line_thickness, c->color);
|
||||
} break;
|
||||
case NK_COMMAND_CIRCLE_FILLED: {
|
||||
const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
|
||||
nk_sdl_fill_circle(screen_surface, c->x, c->y, c->w, c->h, c->color);
|
||||
} break;
|
||||
case NK_COMMAND_TRIANGLE: {
|
||||
const struct nk_command_triangle*t = (const struct nk_command_triangle*)cmd;
|
||||
nk_sdl_stroke_triangle(screen_surface, t->a.x, t->a.y, t->b.x, t->b.y,
|
||||
t->c.x, t->c.y, t->line_thickness, t->color);
|
||||
} break;
|
||||
case NK_COMMAND_TRIANGLE_FILLED: {
|
||||
const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled *)cmd;
|
||||
nk_sdl_fill_triangle(screen_surface, t->a.x, t->a.y, t->b.x, t->b.y, t->c.x, t->c.y, t->color);
|
||||
} break;
|
||||
case NK_COMMAND_POLYGON: {
|
||||
const struct nk_command_polygon *p =(const struct nk_command_polygon*)cmd;
|
||||
nk_sdl_stroke_polygon(screen_surface, p->points, p->point_count, p->line_thickness,p->color);
|
||||
} break;
|
||||
case NK_COMMAND_POLYGON_FILLED: {
|
||||
const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled *)cmd;
|
||||
nk_sdl_fill_polygon(screen_surface, p->points, p->point_count, p->color);
|
||||
} break;
|
||||
case NK_COMMAND_POLYLINE: {
|
||||
const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd;
|
||||
nk_sdl_stroke_polyline(screen_surface, p->points, p->point_count, p->line_thickness, p->color);
|
||||
} break;
|
||||
case NK_COMMAND_TEXT: {
|
||||
const struct nk_command_text *t = (const struct nk_command_text*)cmd;
|
||||
nk_sdl_draw_text(screen_surface, t->x, t->y, t->w, t->h,
|
||||
(const char*)t->string, t->length,
|
||||
(nk_sdl_Font*)t->font->userdata.ptr,
|
||||
t->background, t->foreground);
|
||||
} break;
|
||||
case NK_COMMAND_CURVE: {
|
||||
const struct nk_command_curve *q = (const struct nk_command_curve *)cmd;
|
||||
nk_sdl_stroke_curve(screen_surface, q->begin, q->ctrl[0], q->ctrl[1],
|
||||
q->end, 22, q->line_thickness, q->color);
|
||||
} break;
|
||||
case NK_COMMAND_RECT_MULTI_COLOR: {
|
||||
const struct nk_command_rect_multi_color *r = (const struct nk_command_rect_multi_color *)cmd;
|
||||
nk_sdl_fill_rect_multi_color(screen_surface, r->x, r->y, r->w, r->h, r->left, r->top, r->right, r->bottom);
|
||||
} break;
|
||||
case NK_COMMAND_IMAGE:
|
||||
case NK_COMMAND_ARC:
|
||||
case NK_COMMAND_ARC_FILLED:
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
nk_sdl_blit(sdl.screen_surface);
|
||||
nk_clear(&sdl.ctx);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_clipbard_paste(nk_handle usr, struct nk_text_edit *edit)
|
||||
{
|
||||
/* Not supported in SDL 1.2. Use platform specific code. */
|
||||
}
|
||||
|
||||
static void
|
||||
nk_sdl_clipbard_copy(nk_handle usr, const char *text, int len)
|
||||
{
|
||||
/* Not supported in SDL 1.2. Use platform specific code. */
|
||||
}
|
||||
|
||||
static float
|
||||
nk_sdl_get_text_width(nk_handle handle, float height, const char *text, int len)
|
||||
{
|
||||
return len * sdl_font->width;
|
||||
}
|
||||
|
||||
NK_API struct nk_context*
|
||||
nk_sdl_init(SDL_Surface *screen_surface)
|
||||
{
|
||||
struct nk_user_font font;
|
||||
sdl_font = (nk_sdl_Font*)calloc(1, sizeof(nk_sdl_Font));
|
||||
sdl_font->width = 8; /* Default in the SDL_gfx library */
|
||||
sdl_font->height = 8; /* Default in the SDL_gfx library */
|
||||
if (!sdl_font)
|
||||
return NULL;
|
||||
|
||||
font.userdata = nk_handle_ptr(sdl_font);
|
||||
font.height = (float)sdl_font->height;
|
||||
font.width = nk_sdl_get_text_width;
|
||||
|
||||
sdl.screen_surface = screen_surface;
|
||||
nk_init_default(&sdl.ctx, &font);
|
||||
sdl.ctx.clip.copy = nk_sdl_clipbard_copy;
|
||||
sdl.ctx.clip.paste = nk_sdl_clipbard_paste;
|
||||
sdl.ctx.clip.userdata = nk_handle_ptr(0);
|
||||
return &sdl.ctx;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_sdl_handle_event(SDL_Event *evt)
|
||||
{
|
||||
|
||||
struct nk_context *ctx = &sdl.ctx;
|
||||
if (evt->type == SDL_VIDEORESIZE) {
|
||||
/* Do nothing */
|
||||
} else if (evt->type == SDL_KEYUP || evt->type == SDL_KEYDOWN) {
|
||||
/* key events */
|
||||
int down = evt->type == SDL_KEYDOWN;
|
||||
SDLMod state = SDL_GetModState();
|
||||
SDLKey sym = evt->key.keysym.sym;
|
||||
|
||||
if (sym == SDLK_RSHIFT || sym == SDLK_LSHIFT) nk_input_key(ctx, NK_KEY_SHIFT, down);
|
||||
else if (sym == SDLK_DELETE) nk_input_key(ctx, NK_KEY_DEL, down);
|
||||
else if (sym == SDLK_RETURN) nk_input_key(ctx, NK_KEY_ENTER, down);
|
||||
else if (sym == SDLK_TAB) nk_input_key(ctx, NK_KEY_TAB, down);
|
||||
else if (sym == SDLK_LEFT) nk_input_key(ctx, NK_KEY_LEFT, down);
|
||||
else if (sym == SDLK_RIGHT) nk_input_key(ctx, NK_KEY_RIGHT, down);
|
||||
else if (sym == SDLK_BACKSPACE) nk_input_key(ctx, NK_KEY_BACKSPACE, down);
|
||||
else if (sym == SDLK_HOME) nk_input_key(ctx, NK_KEY_TEXT_START, down);
|
||||
else if (sym == SDLK_END) nk_input_key(ctx, NK_KEY_TEXT_END, down);
|
||||
else if (sym == SDLK_SPACE && !down) nk_input_char(ctx, ' ');
|
||||
else {
|
||||
if (sym == SDLK_c && state == SDLK_LCTRL)
|
||||
nk_input_key(ctx, NK_KEY_COPY, down);
|
||||
else if (sym == SDLK_v && state == SDLK_LCTRL)
|
||||
nk_input_key(ctx, NK_KEY_PASTE, down);
|
||||
else if (sym == SDLK_x && state == SDLK_LCTRL)
|
||||
nk_input_key(ctx, NK_KEY_CUT, down);
|
||||
else if (sym == SDLK_z && state == SDLK_LCTRL)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_UNDO, down);
|
||||
else if (sym == SDLK_r && state == SDLK_LCTRL)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_REDO, down);
|
||||
else if (sym == SDLK_LEFT && state == SDLK_LCTRL)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, down);
|
||||
else if (sym == SDLK_RIGHT && state == SDLK_LCTRL)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, down);
|
||||
else if (sym == SDLK_b && state == SDLK_LCTRL)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down);
|
||||
else if (sym == SDLK_e && state == SDLK_LCTRL)
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down);
|
||||
else if (!down) {
|
||||
/* This demo does not provide full unicode support since the default
|
||||
* sdl1.2 font only allows runes in range 0-255. But this demo
|
||||
* already is quite limited and not really meant for full blown Apps
|
||||
* anyway. So I think ASCII support for Debugging Tools should be enough */
|
||||
if (sym >= SDLK_0 && sym <= SDLK_9) {
|
||||
nk_rune rune = '0' + sym - SDLK_0;
|
||||
nk_input_unicode(ctx, rune);
|
||||
} else if (sym >= SDLK_a && sym <= SDLK_z) {
|
||||
nk_rune rune = 'a' + sym - SDLK_a;
|
||||
rune = ((state == KMOD_LSHIFT) ? (nk_rune)nk_to_upper((int)rune):rune);
|
||||
nk_input_unicode(ctx, rune);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (evt->type == SDL_MOUSEBUTTONDOWN || evt->type == SDL_MOUSEBUTTONUP) {
|
||||
/* mouse button */
|
||||
int down = evt->type == SDL_MOUSEBUTTONDOWN;
|
||||
const int x = evt->button.x, y = evt->button.y;
|
||||
if (evt->button.button == SDL_BUTTON_LEFT)
|
||||
nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down);
|
||||
if (evt->button.button == SDL_BUTTON_MIDDLE)
|
||||
nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down);
|
||||
if (evt->button.button == SDL_BUTTON_RIGHT)
|
||||
nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down);
|
||||
if (evt->button.button == SDL_BUTTON_WHEELUP)
|
||||
nk_input_scroll(ctx, 1.0f);
|
||||
if (evt->button.button == SDL_BUTTON_WHEELDOWN)
|
||||
nk_input_scroll(ctx, -1.0f);
|
||||
} else if (evt->type == SDL_MOUSEMOTION) {
|
||||
nk_input_motion(ctx, evt->motion.x, evt->motion.y);
|
||||
}
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_sdl_shutdown(void)
|
||||
{
|
||||
free(sdl_font);
|
||||
nk_free(&sdl.ctx);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -13,17 +13,16 @@
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_opengl.h>
|
||||
|
||||
/* these defines are both needed for the header
|
||||
* and source file. So if you split them remember
|
||||
* to copy them as well. */
|
||||
#define NK_INCLUDE_FIXED_TYPES
|
||||
#define NK_INCLUDE_STANDARD_IO
|
||||
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
||||
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
|
||||
#define NK_INCLUDE_FONT_BAKING
|
||||
#define NK_INCLUDE_DEFAULT_FONT
|
||||
#include "nuklear_sdl.h"
|
||||
#include "nuklear_sdl.c"
|
||||
#define NK_IMPLEMENTATION
|
||||
#define NK_SDL_GL2_IMPLEMENTATION
|
||||
#include "../../nuklear.h"
|
||||
#include "nuklear_sdl_gl2.h"
|
||||
|
||||
#define WINDOW_WIDTH 800
|
||||
#define WINDOW_HEIGHT 600
|
||||
|
@ -1,15 +0,0 @@
|
||||
#ifndef NK_SDL_H_
|
||||
#define NK_SDL_H_
|
||||
|
||||
#include "../../nuklear.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
NK_API struct nk_context *nk_sdl_init(SDL_Window *win);
|
||||
NK_API void nk_sdl_font_stash_begin(struct nk_font_atlas **atlas);
|
||||
NK_API void nk_sdl_font_stash_end(void);
|
||||
NK_API void nk_sdl_handle_event(SDL_Event *evt);
|
||||
NK_API void nk_sdl_render(enum nk_anti_aliasing , int max_vertex_buffer, int max_element_buffer);
|
||||
NK_API void nk_sdl_shutdown(void);
|
||||
|
||||
#endif
|
@ -1,9 +1,35 @@
|
||||
#include <string.h>
|
||||
#include <SDL2/SDL.h>
|
||||
/*
|
||||
* Nuklear - v1.00 - public domain
|
||||
* no warrenty implied; use at your own risk.
|
||||
* authored from 2015-2016 by Micha Mettke
|
||||
*/
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* API
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifndef NK_SDL_GL2_H_
|
||||
#define NK_SDL_GL2_H_
|
||||
|
||||
#include "nuklear_sdl.h"
|
||||
#define NK_IMPLEMENTATION
|
||||
#include "../../nuklear.h"
|
||||
#include <SDL2/SDL.h>
|
||||
NK_API struct nk_context* nk_sdl_init(SDL_Window *win);
|
||||
NK_API void nk_sdl_font_stash_begin(struct nk_font_atlas **atlas);
|
||||
NK_API void nk_sdl_font_stash_end(void);
|
||||
NK_API void nk_sdl_handle_event(SDL_Event *evt);
|
||||
NK_API void nk_sdl_render(enum nk_anti_aliasing , int max_vertex_buffer, int max_element_buffer);
|
||||
NK_API void nk_sdl_shutdown(void);
|
||||
|
||||
#endif
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* IMPLEMENTATION
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifdef NK_SDL_GL2_IMPLEMENTATION
|
||||
|
||||
struct nk_sdl_device {
|
||||
struct nk_buffer cmds;
|
||||
@ -267,3 +293,4 @@ void nk_sdl_shutdown(void)
|
||||
memset(&sdl, 0, sizeof(sdl));
|
||||
}
|
||||
|
||||
#endif
|
@ -14,17 +14,16 @@
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_opengl.h>
|
||||
|
||||
/* these defines are both needed for the header
|
||||
* and source file. So if you split them remember
|
||||
* to copy them as well. */
|
||||
#define NK_INCLUDE_FIXED_TYPES
|
||||
#define NK_INCLUDE_STANDARD_IO
|
||||
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
||||
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
|
||||
#define NK_INCLUDE_FONT_BAKING
|
||||
#define NK_INCLUDE_DEFAULT_FONT
|
||||
#include "nuklear_sdl.h"
|
||||
#include "nuklear_sdl.c"
|
||||
#define NK_IMPLEMENTATION
|
||||
#define NK_SDL_GL3_IMPLEMENTATION
|
||||
#include "../../nuklear.h"
|
||||
#include "nuklear_sdl_gl3.h"
|
||||
|
||||
#define WINDOW_WIDTH 800
|
||||
#define WINDOW_HEIGHT 600
|
||||
|
@ -1,18 +0,0 @@
|
||||
#ifndef NK_SDL_H_
|
||||
#define NK_SDL_H_
|
||||
|
||||
#include "../../nuklear.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
NK_API struct nk_context *nk_sdl_init(SDL_Window *win);
|
||||
NK_API void nk_sdl_font_stash_begin(struct nk_font_atlas **atlas);
|
||||
NK_API void nk_sdl_font_stash_end(void);
|
||||
NK_API void nk_sdl_handle_event(SDL_Event *evt);
|
||||
NK_API void nk_sdl_render(enum nk_anti_aliasing , int max_vertex_buffer, int max_element_buffer);
|
||||
NK_API void nk_sdl_shutdown(void);
|
||||
|
||||
NK_API void nk_sdl_device_destroy(void);
|
||||
NK_API void nk_sdl_device_create(void);
|
||||
|
||||
#endif
|
@ -1,9 +1,42 @@
|
||||
#include <string.h>
|
||||
#include <SDL2/SDL.h>
|
||||
/*
|
||||
* Nuklear - v1.00 - public domain
|
||||
* no warrenty implied; use at your own risk.
|
||||
* authored from 2015-2016 by Micha Mettke
|
||||
*/
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* API
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifndef NK_SDL_GL3_H_
|
||||
#define NK_SDL_GL3_H_
|
||||
|
||||
#include "nuklear_sdl.h"
|
||||
#define NK_IMPLEMENTATION
|
||||
#include "../../nuklear.h"
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_opengl.h>
|
||||
|
||||
NK_API struct nk_context* nk_sdl_init(SDL_Window *win);
|
||||
NK_API void nk_sdl_font_stash_begin(struct nk_font_atlas **atlas);
|
||||
NK_API void nk_sdl_font_stash_end(void);
|
||||
NK_API void nk_sdl_handle_event(SDL_Event *evt);
|
||||
NK_API void nk_sdl_render(enum nk_anti_aliasing , int max_vertex_buffer, int max_element_buffer);
|
||||
NK_API void nk_sdl_shutdown(void);
|
||||
NK_API void nk_sdl_device_destroy(void);
|
||||
NK_API void nk_sdl_device_create(void);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* IMPLEMENTATION
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifdef NK_SDL_GL3_IMPLEMENTATION
|
||||
|
||||
#include <string.h>
|
||||
|
||||
struct nk_sdl_device {
|
||||
struct nk_buffer cmds;
|
||||
@ -369,3 +402,4 @@ void nk_sdl_shutdown(void)
|
||||
memset(&sdl, 0, sizeof(sdl));
|
||||
}
|
||||
|
||||
#endif
|
@ -5,24 +5,22 @@
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xresource.h>
|
||||
|
||||
#define DTIME 20
|
||||
#define WINDOW_WIDTH 800
|
||||
#define WINDOW_HEIGHT 600
|
||||
#include <time.h>
|
||||
|
||||
#define NK_INCLUDE_FIXED_TYPES
|
||||
#define NK_INCLUDE_STANDARD_IO
|
||||
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
||||
#define NK_IMPLEMENTATION
|
||||
#define NK_XLIB_IMPLEMENTATION
|
||||
#include "../../nuklear.h"
|
||||
#include "nuklear_xlib.h"
|
||||
#include "nuklear_xlib.c"
|
||||
|
||||
#define DTIME 20
|
||||
#define WINDOW_WIDTH 800
|
||||
#define WINDOW_HEIGHT 600
|
||||
|
||||
#define UNUSED(a) (void)a
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
@ -90,6 +88,7 @@ sleep_for(long t)
|
||||
/* 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 include
|
||||
* and the corresponding function. */
|
||||
|
||||
/*#include "../style.c"*/
|
||||
/*#include "../calculator.c"*/
|
||||
/*#include "../overview.c"*/
|
||||
|
@ -1,612 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xresource.h>
|
||||
#include <X11/Xlocale.h>
|
||||
|
||||
#define NK_IMPLEMENTATION
|
||||
#include "nuklear_xlib.h"
|
||||
#include "../../nuklear.h"
|
||||
|
||||
typedef struct XSurface XSurface;
|
||||
struct XFont {
|
||||
int ascent;
|
||||
int descent;
|
||||
int height;
|
||||
XFontSet set;
|
||||
XFontStruct *xfont;
|
||||
};
|
||||
struct XSurface {
|
||||
GC gc;
|
||||
Display *dpy;
|
||||
int screen;
|
||||
Window root;
|
||||
Drawable drawable;
|
||||
unsigned int w, h;
|
||||
};
|
||||
static struct {
|
||||
struct nk_context ctx;
|
||||
struct XSurface *surf;
|
||||
} xlib;
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) ((a) < (b) ? (b) : (a))
|
||||
#endif
|
||||
|
||||
static unsigned long
|
||||
color_from_byte(const nk_byte *c)
|
||||
{
|
||||
unsigned long res = 0;
|
||||
res |= (unsigned long)c[0] << 16;
|
||||
res |= (unsigned long)c[1] << 8;
|
||||
res |= (unsigned long)c[2] << 0;
|
||||
return (res);
|
||||
}
|
||||
|
||||
static XSurface*
|
||||
nk_xsurf_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
|
||||
{
|
||||
XSurface *surface = (XSurface*)calloc(1, sizeof(XSurface));
|
||||
surface->w = w;
|
||||
surface->h = h;
|
||||
surface->dpy = dpy;
|
||||
surface->screen = screen;
|
||||
surface->root = root;
|
||||
surface->gc = XCreateGC(dpy, root, 0, NULL);
|
||||
XSetLineAttributes(dpy, surface->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
surface->drawable = XCreatePixmap(dpy, root, w, h,
|
||||
(unsigned int)DefaultDepth(dpy, screen));
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_resize(XSurface *surf, unsigned int w, unsigned int h)
|
||||
{
|
||||
if(!surf) return;
|
||||
if (surf->w == w && surf->h == h) return;
|
||||
surf->w = w; surf->h = h;
|
||||
if(surf->drawable) XFreePixmap(surf->dpy, surf->drawable);
|
||||
surf->drawable = XCreatePixmap(surf->dpy, surf->root, w, h,
|
||||
(unsigned int)DefaultDepth(surf->dpy, surf->screen));
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_scissor(XSurface *surf, float x, float y, float w, float h)
|
||||
{
|
||||
XRectangle clip_rect;
|
||||
clip_rect.x = (short)(x-1);
|
||||
clip_rect.y = (short)(y-1);
|
||||
clip_rect.width = (unsigned short)(w+2);
|
||||
clip_rect.height = (unsigned short)(h+2);
|
||||
XSetClipRectangles(surf->dpy, surf->gc, 0, 0, &clip_rect, 1, Unsorted);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_stroke_line(XSurface *surf, short x0, short y0, short x1,
|
||||
short y1, unsigned int line_thickness, struct nk_color col)
|
||||
{
|
||||
unsigned long c = color_from_byte(&col.r);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter);
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, (int)x0, (int)y0, (int)x1, (int)y1);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_stroke_rect(XSurface* surf, short x, short y, unsigned short w,
|
||||
unsigned short h, unsigned short r, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
unsigned long c = color_from_byte(&col.r);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter);
|
||||
if (r == 0) {
|
||||
XFillRectangle(surf->dpy, surf->drawable, surf->gc, x, y, w, h);
|
||||
} else {
|
||||
short xc = x + r;
|
||||
short yc = y + r;
|
||||
short wc = (short)(w - 2 * r);
|
||||
short hc = (short)(h - 2 * r);
|
||||
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, xc, y, xc+wc, y);
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, x+w, yc, x+w, yc+wc);
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, xc, y+h, xc+wc, y+h);
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, x, yc, yc+hc, x);
|
||||
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, xc + wc - r, y,
|
||||
(unsigned)r*2, (unsigned)r*2, 0 * 64, 90 * 64);
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, x, y,
|
||||
(unsigned)r*2, (unsigned)r*2, 90 * 64, 90 * 64);
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, x, yc + hc - r,
|
||||
(unsigned)r*2, (unsigned)2*r, 180 * 64, 90 * 64);
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, xc + wc - r, yc + hc - r,
|
||||
(unsigned)r*2, (unsigned)2*r, -90 * 64, 90 * 64);
|
||||
}
|
||||
XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_fill_rect(XSurface* surf, short x, short y, unsigned short w,
|
||||
unsigned short h, unsigned short r, struct nk_color col)
|
||||
{
|
||||
unsigned long c = color_from_byte(&col.r);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
if (r == 0) {
|
||||
XFillRectangle(surf->dpy, surf->drawable, surf->gc, x, y, w, h);
|
||||
} else {
|
||||
short xc = x + r;
|
||||
short yc = y + r;
|
||||
short wc = (short)(w - 2 * r);
|
||||
short hc = (short)(h - 2 * r);
|
||||
|
||||
XPoint pnts[12];
|
||||
pnts[0].x = x;
|
||||
pnts[0].y = yc;
|
||||
pnts[1].x = xc;
|
||||
pnts[1].y = yc;
|
||||
pnts[2].x = xc;
|
||||
pnts[2].y = y;
|
||||
|
||||
pnts[3].x = xc + wc;
|
||||
pnts[3].y = y;
|
||||
pnts[4].x = xc + wc;
|
||||
pnts[4].y = yc;
|
||||
pnts[5].x = x + w;
|
||||
pnts[5].y = yc;
|
||||
|
||||
pnts[6].x = x + w;
|
||||
pnts[6].y = yc + hc;
|
||||
pnts[7].x = xc + wc;
|
||||
pnts[7].y = yc + hc;
|
||||
pnts[8].x = xc + wc;
|
||||
pnts[8].y = y + h;
|
||||
|
||||
pnts[9].x = xc;
|
||||
pnts[9].y = y + h;
|
||||
pnts[10].x = xc;
|
||||
pnts[10].y = yc + hc;
|
||||
pnts[11].x = x;
|
||||
pnts[11].y = yc + hc;
|
||||
|
||||
XFillPolygon(surf->dpy, surf->drawable, surf->gc, pnts, 12, Convex, CoordModeOrigin);
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, xc + wc - r, y,
|
||||
(unsigned)r*2, (unsigned)r*2, 0 * 64, 90 * 64);
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, x, y,
|
||||
(unsigned)r*2, (unsigned)r*2, 90 * 64, 90 * 64);
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, x, yc + hc - r,
|
||||
(unsigned)r*2, (unsigned)2*r, 180 * 64, 90 * 64);
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, xc + wc - r, yc + hc - r,
|
||||
(unsigned)r*2, (unsigned)2*r, -90 * 64, 90 * 64);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_fill_triangle(XSurface *surf, short x0, short y0, short x1,
|
||||
short y1, short x2, short y2, struct nk_color col)
|
||||
{
|
||||
XPoint pnts[3];
|
||||
unsigned long c = color_from_byte(&col.r);
|
||||
pnts[0].x = (short)x0;
|
||||
pnts[0].y = (short)y0;
|
||||
pnts[1].x = (short)x1;
|
||||
pnts[1].y = (short)y1;
|
||||
pnts[2].x = (short)x2;
|
||||
pnts[2].y = (short)y2;
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
XFillPolygon(surf->dpy, surf->drawable, surf->gc, pnts, 3, Convex, CoordModeOrigin);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_stroke_triangle(XSurface *surf, short x0, short y0, short x1,
|
||||
short y1, short x2, short y2, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
XPoint pnts[3];
|
||||
unsigned long c = color_from_byte(&col.r);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter);
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, x0, y0, x1, y1);
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, x1, y1, x2, y2);
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, x2, y2, x0, y0);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_fill_polygon(XSurface *surf, const struct nk_vec2i *pnts, int count,
|
||||
struct nk_color col)
|
||||
{
|
||||
int i = 0;
|
||||
#define MAX_POINTS 64
|
||||
XPoint xpnts[MAX_POINTS];
|
||||
unsigned long c = color_from_byte(&col.r);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
for (i = 0; i < count && i < MAX_POINTS; ++i) {
|
||||
xpnts[i].x = pnts[i].x;
|
||||
xpnts[i].y = pnts[i].y;
|
||||
}
|
||||
XFillPolygon(surf->dpy, surf->drawable, surf->gc, xpnts, count, Convex, CoordModeOrigin);
|
||||
#undef MAX_POINTS
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_stroke_polygon(XSurface *surf, const struct nk_vec2i *pnts, int count,
|
||||
unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned long c = color_from_byte(&col.r);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter);
|
||||
for (i = 1; i < count; ++i)
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, pnts[i-1].x, pnts[i-1].y, pnts[i].x, pnts[i].y);
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, pnts[count-1].x, pnts[count-1].y, pnts[0].x, pnts[0].y);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_stroke_polyline(XSurface *surf, const struct nk_vec2i *pnts,
|
||||
int count, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned long c = color_from_byte(&col.r);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
for (i = 0; i < count-1; ++i)
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, pnts[i].x, pnts[i].y, pnts[i+1].x, pnts[i+1].y);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_fill_circle(XSurface *surf, short x, short y, unsigned short w,
|
||||
unsigned short h, struct nk_color col)
|
||||
{
|
||||
unsigned long c = color_from_byte(&col.r);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, (int)x, (int)y,
|
||||
(unsigned)w, (unsigned)h, 0, 360 * 64);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_stroke_circle(XSurface *surf, short x, short y, unsigned short w,
|
||||
unsigned short h, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
unsigned long c = color_from_byte(&col.r);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
XDrawArc(surf->dpy, surf->drawable, surf->gc, (int)x, (int)y,
|
||||
(unsigned)w, (unsigned)h, 0, 360 * 64);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_stroke_curve(XSurface *surf, struct nk_vec2i p1,
|
||||
struct nk_vec2i p2, struct nk_vec2i p3, struct nk_vec2i p4,
|
||||
unsigned int num_segments, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
unsigned int i_step;
|
||||
float t_step;
|
||||
struct nk_vec2i last = p1;
|
||||
|
||||
XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter);
|
||||
num_segments = MAX(num_segments, 1);
|
||||
t_step = 1.0f/(float)num_segments;
|
||||
for (i_step = 1; i_step <= num_segments; ++i_step) {
|
||||
float t = t_step * (float)i_step;
|
||||
float u = 1.0f - t;
|
||||
float w1 = u*u*u;
|
||||
float w2 = 3*u*u*t;
|
||||
float w3 = 3*u*t*t;
|
||||
float w4 = t * t *t;
|
||||
float x = w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x;
|
||||
float y = w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y;
|
||||
nk_xsurf_stroke_line(surf, last.x, last.y, (short)x, (short)y, line_thickness,col);
|
||||
last.x = (short)x; last.y = (short)y;
|
||||
}
|
||||
XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_draw_text(XSurface *surf, short x, short y, unsigned short w, unsigned short h,
|
||||
const char *text, int len, XFont *font, struct nk_color cbg, struct nk_color cfg)
|
||||
{
|
||||
int tx, ty;
|
||||
unsigned long bg = color_from_byte(&cbg.r);
|
||||
unsigned long fg = color_from_byte(&cfg.r);
|
||||
|
||||
XSetForeground(surf->dpy, surf->gc, bg);
|
||||
XFillRectangle(surf->dpy, surf->drawable, surf->gc, (int)x, (int)y, (unsigned)w, (unsigned)h);
|
||||
if(!text || !font || !len) return;
|
||||
|
||||
tx = (int)x;
|
||||
ty = (int)y + font->ascent;
|
||||
XSetForeground(surf->dpy, surf->gc, fg);
|
||||
if(font->set)
|
||||
XmbDrawString(surf->dpy,surf->drawable,font->set,surf->gc,tx,ty,(const char*)text,(int)len);
|
||||
else
|
||||
XDrawString(surf->dpy, surf->drawable, surf->gc, tx, ty, (const char*)text, (int)len);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_clear(XSurface *surf, unsigned long color)
|
||||
{
|
||||
XSetForeground(surf->dpy, surf->gc, color);
|
||||
XFillRectangle(surf->dpy, surf->drawable, surf->gc, 0, 0, surf->w, surf->h);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_blit(Drawable target, XSurface *surf, unsigned int w, unsigned int h)
|
||||
{
|
||||
XCopyArea(surf->dpy, surf->drawable, target, surf->gc, 0, 0, w, h, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_del(XSurface *surf)
|
||||
{
|
||||
XFreePixmap(surf->dpy, surf->drawable);
|
||||
XFreeGC(surf->dpy, surf->gc);
|
||||
free(surf);
|
||||
}
|
||||
|
||||
XFont*
|
||||
nk_xfont_create(Display *dpy, const char *name)
|
||||
{
|
||||
int n;
|
||||
char *def, **missing;
|
||||
XFont *font = (XFont*)calloc(1, sizeof(XFont));
|
||||
font->set = XCreateFontSet(dpy, name, &missing, &n, &def);
|
||||
if(missing) {
|
||||
while(n--)
|
||||
fprintf(stderr, "missing fontset: %s\n", missing[n]);
|
||||
XFreeStringList(missing);
|
||||
}
|
||||
|
||||
if(font->set) {
|
||||
XFontStruct **xfonts;
|
||||
char **font_names;
|
||||
XExtentsOfFontSet(font->set);
|
||||
n = XFontsOfFontSet(font->set, &xfonts, &font_names);
|
||||
while(n--) {
|
||||
font->ascent = MAX(font->ascent, (*xfonts)->ascent);
|
||||
font->descent = MAX(font->descent,(*xfonts)->descent);
|
||||
xfonts++;
|
||||
}
|
||||
} else {
|
||||
if(!(font->xfont = XLoadQueryFont(dpy, name))
|
||||
&& !(font->xfont = XLoadQueryFont(dpy, "fixed"))) {
|
||||
free(font);
|
||||
return 0;
|
||||
}
|
||||
font->ascent = font->xfont->ascent;
|
||||
font->descent = font->xfont->descent;
|
||||
}
|
||||
font->height = font->ascent + font->descent;
|
||||
return font;
|
||||
}
|
||||
|
||||
static float
|
||||
nk_xfont_get_text_width(nk_handle handle, float height, const char *text, int len)
|
||||
{
|
||||
XFont *font = (XFont*)handle.ptr;
|
||||
XRectangle r;
|
||||
if(!font || !text)
|
||||
return 0;
|
||||
|
||||
if(font->set) {
|
||||
XmbTextExtents(font->set, (const char*)text, len, NULL, &r);
|
||||
return (float)r.width;
|
||||
} else{
|
||||
int w = XTextWidth(font->xfont, (const char*)text, len);
|
||||
return (float)w;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nk_xfont_del(Display *dpy, XFont *font)
|
||||
{
|
||||
if(!font) return;
|
||||
if(font->set)
|
||||
XFreeFontSet(dpy, font->set);
|
||||
else
|
||||
XFreeFont(dpy, font->xfont);
|
||||
free(font);
|
||||
}
|
||||
|
||||
NK_API struct nk_context*
|
||||
nk_xlib_init(XFont *xfont, Display *dpy, int screen, Window root,
|
||||
unsigned int w, unsigned int h)
|
||||
{
|
||||
struct nk_user_font font;
|
||||
font.userdata = nk_handle_ptr(xfont);
|
||||
font.height = (float)xfont->height;
|
||||
font.width = nk_xfont_get_text_width;
|
||||
|
||||
if (!setlocale(LC_ALL,"")) return 0;
|
||||
if (!XSupportsLocale()) return 0;
|
||||
if (!XSetLocaleModifiers("@im=none")) return 0;
|
||||
|
||||
xlib.surf = nk_xsurf_create(dpy, screen, root, w, h);
|
||||
nk_init_default(&xlib.ctx, &font);
|
||||
return &xlib.ctx;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_xlib_set_font(XFont *xfont)
|
||||
{
|
||||
struct nk_user_font font;
|
||||
font.userdata = nk_handle_ptr(xfont);
|
||||
font.height = (float)xfont->height;
|
||||
font.width = nk_xfont_get_text_width;
|
||||
nk_style_set_font(&xlib.ctx, &font);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_xlib_handle_event(Display *dpy, int screen, Window win, XEvent *evt)
|
||||
{
|
||||
struct nk_context *ctx = &xlib.ctx;
|
||||
if (evt->type == KeyPress || evt->type == KeyRelease)
|
||||
{
|
||||
/* Key handler */
|
||||
int ret, down = (evt->type == KeyPress);
|
||||
KeySym *code = XGetKeyboardMapping(xlib.surf->dpy, (KeyCode)evt->xkey.keycode, 1, &ret);
|
||||
if (*code == XK_Shift_L || *code == XK_Shift_R) nk_input_key(ctx, NK_KEY_SHIFT, down);
|
||||
else if (*code == XK_Delete) nk_input_key(ctx, NK_KEY_DEL, down);
|
||||
else if (*code == XK_Return) nk_input_key(ctx, NK_KEY_ENTER, down);
|
||||
else if (*code == XK_Tab) nk_input_key(ctx, NK_KEY_TAB, down);
|
||||
else if (*code == XK_Left) nk_input_key(ctx, NK_KEY_LEFT, down);
|
||||
else if (*code == XK_Right) nk_input_key(ctx, NK_KEY_RIGHT, down);
|
||||
else if (*code == XK_BackSpace) nk_input_key(ctx, NK_KEY_BACKSPACE, down);
|
||||
else if (*code == XK_Home) nk_input_key(ctx, NK_KEY_TEXT_START, down);
|
||||
else if (*code == XK_End) nk_input_key(ctx, NK_KEY_TEXT_END, down);
|
||||
else if (*code == XK_space && !down) nk_input_char(ctx, ' ');
|
||||
else {
|
||||
if (*code == 'c' && (evt->xkey.state & ControlMask))
|
||||
nk_input_key(ctx, NK_KEY_COPY, down);
|
||||
else if (*code == 'v' && (evt->xkey.state & ControlMask))
|
||||
nk_input_key(ctx, NK_KEY_PASTE, down);
|
||||
else if (*code == 'x' && (evt->xkey.state & ControlMask))
|
||||
nk_input_key(ctx, NK_KEY_CUT, down);
|
||||
else if (*code == 'z' && (evt->xkey.state & ControlMask))
|
||||
nk_input_key(ctx, NK_KEY_TEXT_UNDO, down);
|
||||
else if (*code == 'r' && (evt->xkey.state & ControlMask))
|
||||
nk_input_key(ctx, NK_KEY_TEXT_REDO, down);
|
||||
else if (*code == XK_Left && (evt->xkey.state & ControlMask))
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, down);
|
||||
else if (*code == XK_Right && (evt->xkey.state & ControlMask))
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, down);
|
||||
else if (*code == 'b' && (evt->xkey.state & ControlMask))
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down);
|
||||
else if (*code == 'e' && (evt->xkey.state & ControlMask))
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down);
|
||||
else if (!down) {
|
||||
char buf[32];
|
||||
KeySym keysym = 0;
|
||||
if (XLookupString((XKeyEvent*)evt, buf, 32, &keysym, NULL) != NoSymbol)
|
||||
nk_input_glyph(ctx, buf);
|
||||
}
|
||||
}
|
||||
XFree(code);
|
||||
} else if (evt->type == ButtonPress || evt->type == ButtonRelease) {
|
||||
/* Button handler */
|
||||
int down = (evt->type == ButtonPress);
|
||||
const int x = evt->xbutton.x, y = evt->xbutton.y;
|
||||
if (evt->xbutton.button == Button1)
|
||||
nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down);
|
||||
if (evt->xbutton.button == Button2)
|
||||
nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down);
|
||||
else if (evt->xbutton.button == Button3)
|
||||
nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down);
|
||||
else if (evt->xbutton.button == Button4)
|
||||
nk_input_scroll(ctx, 1.0f);
|
||||
else if (evt->xbutton.button == Button5)
|
||||
nk_input_scroll(ctx, -1.0f);
|
||||
|
||||
} else if (evt->type == MotionNotify) {
|
||||
/* Mouse motion handler */
|
||||
const int x = evt->xmotion.x, y = evt->xmotion.y;
|
||||
nk_input_motion(ctx, x, y);
|
||||
} else if (evt->type == Expose || evt->type == ConfigureNotify) {
|
||||
/* Window resize handler */
|
||||
unsigned int width, height;
|
||||
XWindowAttributes attr;
|
||||
XGetWindowAttributes(dpy, win, &attr);
|
||||
width = (unsigned int)attr.width;
|
||||
height = (unsigned int)attr.height;
|
||||
nk_xsurf_resize(xlib.surf, width, height);
|
||||
} else if (evt->type == KeymapNotify)
|
||||
XRefreshKeyboardMapping(&evt->xmapping);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_xlib_shutdown(void)
|
||||
{
|
||||
nk_xsurf_del(xlib.surf);
|
||||
nk_free(&xlib.ctx);
|
||||
memset(&xlib, 0, sizeof(xlib));
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_xlib_render(Drawable screen, struct nk_color clear)
|
||||
{
|
||||
const struct nk_command *cmd;
|
||||
struct nk_context *ctx = &xlib.ctx;
|
||||
XSurface *surf = xlib.surf;
|
||||
|
||||
nk_xsurf_clear(xlib.surf, color_from_byte(&clear.r));
|
||||
nk_foreach(cmd, &xlib.ctx)
|
||||
{
|
||||
switch (cmd->type) {
|
||||
case NK_COMMAND_NOP: break;
|
||||
case NK_COMMAND_SCISSOR: {
|
||||
const struct nk_command_scissor *s =(const struct nk_command_scissor*)cmd;
|
||||
nk_xsurf_scissor(surf, s->x, s->y, s->w, s->h);
|
||||
} break;
|
||||
case NK_COMMAND_LINE: {
|
||||
const struct nk_command_line *l = (const struct nk_command_line *)cmd;
|
||||
nk_xsurf_stroke_line(surf, l->begin.x, l->begin.y, l->end.x,
|
||||
l->end.y, l->line_thickness, l->color);
|
||||
} break;
|
||||
case NK_COMMAND_RECT: {
|
||||
const struct nk_command_rect *r = (const struct nk_command_rect *)cmd;
|
||||
nk_xsurf_stroke_rect(surf, r->x, r->y, r->w, r->h,
|
||||
(unsigned short)r->rounding, r->line_thickness, r->color);
|
||||
} break;
|
||||
case NK_COMMAND_RECT_FILLED: {
|
||||
const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled *)cmd;
|
||||
nk_xsurf_fill_rect(surf, r->x, r->y, r->w, r->h,
|
||||
(unsigned short)r->rounding, r->color);
|
||||
} break;
|
||||
case NK_COMMAND_CIRCLE: {
|
||||
const struct nk_command_circle *c = (const struct nk_command_circle *)cmd;
|
||||
nk_xsurf_stroke_circle(surf, c->x, c->y, c->w, c->h, c->line_thickness, c->color);
|
||||
} break;
|
||||
case NK_COMMAND_CIRCLE_FILLED: {
|
||||
const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
|
||||
nk_xsurf_fill_circle(surf, c->x, c->y, c->w, c->h, c->color);
|
||||
} break;
|
||||
case NK_COMMAND_TRIANGLE: {
|
||||
const struct nk_command_triangle*t = (const struct nk_command_triangle*)cmd;
|
||||
nk_xsurf_stroke_triangle(surf, t->a.x, t->a.y, t->b.x, t->b.y,
|
||||
t->c.x, t->c.y, t->line_thickness, t->color);
|
||||
} break;
|
||||
case NK_COMMAND_TRIANGLE_FILLED: {
|
||||
const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled *)cmd;
|
||||
nk_xsurf_fill_triangle(surf, t->a.x, t->a.y, t->b.x, t->b.y,
|
||||
t->c.x, t->c.y, t->color);
|
||||
} break;
|
||||
case NK_COMMAND_POLYGON: {
|
||||
const struct nk_command_polygon *p =(const struct nk_command_polygon*)cmd;
|
||||
nk_xsurf_stroke_polygon(surf, p->points, p->point_count, p->line_thickness,p->color);
|
||||
} break;
|
||||
case NK_COMMAND_POLYGON_FILLED: {
|
||||
const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled *)cmd;
|
||||
nk_xsurf_fill_polygon(surf, p->points, p->point_count, p->color);
|
||||
} break;
|
||||
case NK_COMMAND_POLYLINE: {
|
||||
const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd;
|
||||
nk_xsurf_stroke_polyline(surf, p->points, p->point_count, p->line_thickness, p->color);
|
||||
} break;
|
||||
case NK_COMMAND_TEXT: {
|
||||
const struct nk_command_text *t = (const struct nk_command_text*)cmd;
|
||||
nk_xsurf_draw_text(surf, t->x, t->y, t->w, t->h,
|
||||
(const char*)t->string, t->length,
|
||||
(XFont*)t->font->userdata.ptr,
|
||||
t->background, t->foreground);
|
||||
} break;
|
||||
case NK_COMMAND_CURVE: {
|
||||
const struct nk_command_curve *q = (const struct nk_command_curve *)cmd;
|
||||
nk_xsurf_stroke_curve(surf, q->begin, q->ctrl[0], q->ctrl[1],
|
||||
q->end, 22, q->line_thickness, q->color);
|
||||
} break;
|
||||
case NK_COMMAND_RECT_MULTI_COLOR:
|
||||
case NK_COMMAND_IMAGE:
|
||||
case NK_COMMAND_ARC:
|
||||
case NK_COMMAND_ARC_FILLED:
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
nk_clear(ctx);
|
||||
nk_xsurf_blit(screen, surf, surf->w, surf->h);
|
||||
}
|
||||
|
@ -1,17 +1,641 @@
|
||||
/*
|
||||
* Nuklear - v1.00 - public domain
|
||||
* no warrenty implied; use at your own risk.
|
||||
* authored from 2015-2016 by Micha Mettke
|
||||
*/
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* API
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifndef NK_XLIB_H_
|
||||
#define NK_XLIB_H_
|
||||
|
||||
#include "../../nuklear.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
/* Font */
|
||||
typedef struct XFont XFont;
|
||||
NK_API struct nk_context* nk_xlib_init(XFont *font, Display *dpy, int screen, Window root, unsigned int w, unsigned int h);
|
||||
NK_API void nk_xlib_set_font(XFont *font);
|
||||
NK_API void nk_xlib_handle_event(Display *dpy, int screen, Window win, XEvent *evt);
|
||||
NK_API void nk_xlib_render(Drawable screen, struct nk_color clear);
|
||||
NK_API void nk_xlib_shutdown(void);
|
||||
NK_API XFont* nk_xfont_create(Display *dpy, const char *name);
|
||||
NK_API void nk_xfont_del(Display *dpy, XFont *font);
|
||||
|
||||
/* font */
|
||||
NK_API XFont* nk_xfont_create(Display *dpy, const char *name);
|
||||
NK_API void nk_xfont_del(Display *dpy, XFont *font);
|
||||
NK_API struct nk_context* nk_xlib_init(XFont *font, Display *dpy, int screen, Window root, unsigned int w, unsigned int h);
|
||||
NK_API void nk_xlib_handle_event(Display *dpy, int screen, Window win, XEvent *evt);
|
||||
NK_API void nk_xlib_render(Drawable screen, struct nk_color clear);
|
||||
NK_API void nk_xlib_shutdown(void);
|
||||
NK_API void nk_xlib_set_font(XFont *font);
|
||||
|
||||
#endif
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* IMPLEMENTATION
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifdef NK_XLIB_IMPLEMENTATION
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xresource.h>
|
||||
#include <X11/Xlocale.h>
|
||||
|
||||
typedef struct XSurface XSurface;
|
||||
struct XFont {
|
||||
int ascent;
|
||||
int descent;
|
||||
int height;
|
||||
XFontSet set;
|
||||
XFontStruct *xfont;
|
||||
};
|
||||
struct XSurface {
|
||||
GC gc;
|
||||
Display *dpy;
|
||||
int screen;
|
||||
Window root;
|
||||
Drawable drawable;
|
||||
unsigned int w, h;
|
||||
};
|
||||
static struct {
|
||||
struct nk_context ctx;
|
||||
struct XSurface *surf;
|
||||
} xlib;
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) ((a) < (b) ? (b) : (a))
|
||||
#endif
|
||||
|
||||
static unsigned long
|
||||
nk_color_from_byte(const nk_byte *c)
|
||||
{
|
||||
unsigned long res = 0;
|
||||
res |= (unsigned long)c[0] << 16;
|
||||
res |= (unsigned long)c[1] << 8;
|
||||
res |= (unsigned long)c[2] << 0;
|
||||
return (res);
|
||||
}
|
||||
|
||||
static XSurface*
|
||||
nk_xsurf_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
|
||||
{
|
||||
XSurface *surface = (XSurface*)calloc(1, sizeof(XSurface));
|
||||
surface->w = w;
|
||||
surface->h = h;
|
||||
surface->dpy = dpy;
|
||||
surface->screen = screen;
|
||||
surface->root = root;
|
||||
surface->gc = XCreateGC(dpy, root, 0, NULL);
|
||||
XSetLineAttributes(dpy, surface->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
surface->drawable = XCreatePixmap(dpy, root, w, h,
|
||||
(unsigned int)DefaultDepth(dpy, screen));
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_resize(XSurface *surf, unsigned int w, unsigned int h)
|
||||
{
|
||||
if(!surf) return;
|
||||
if (surf->w == w && surf->h == h) return;
|
||||
surf->w = w; surf->h = h;
|
||||
if(surf->drawable) XFreePixmap(surf->dpy, surf->drawable);
|
||||
surf->drawable = XCreatePixmap(surf->dpy, surf->root, w, h,
|
||||
(unsigned int)DefaultDepth(surf->dpy, surf->screen));
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_scissor(XSurface *surf, float x, float y, float w, float h)
|
||||
{
|
||||
XRectangle clip_rect;
|
||||
clip_rect.x = (short)(x-1);
|
||||
clip_rect.y = (short)(y-1);
|
||||
clip_rect.width = (unsigned short)(w+2);
|
||||
clip_rect.height = (unsigned short)(h+2);
|
||||
XSetClipRectangles(surf->dpy, surf->gc, 0, 0, &clip_rect, 1, Unsorted);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_stroke_line(XSurface *surf, short x0, short y0, short x1,
|
||||
short y1, unsigned int line_thickness, struct nk_color col)
|
||||
{
|
||||
unsigned long c = nk_color_from_byte(&col.r);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter);
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, (int)x0, (int)y0, (int)x1, (int)y1);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_stroke_rect(XSurface* surf, short x, short y, unsigned short w,
|
||||
unsigned short h, unsigned short r, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
unsigned long c = nk_color_from_byte(&col.r);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter);
|
||||
if (r == 0) {
|
||||
XFillRectangle(surf->dpy, surf->drawable, surf->gc, x, y, w, h);
|
||||
} else {
|
||||
short xc = x + r;
|
||||
short yc = y + r;
|
||||
short wc = (short)(w - 2 * r);
|
||||
short hc = (short)(h - 2 * r);
|
||||
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, xc, y, xc+wc, y);
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, x+w, yc, x+w, yc+wc);
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, xc, y+h, xc+wc, y+h);
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, x, yc, yc+hc, x);
|
||||
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, xc + wc - r, y,
|
||||
(unsigned)r*2, (unsigned)r*2, 0 * 64, 90 * 64);
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, x, y,
|
||||
(unsigned)r*2, (unsigned)r*2, 90 * 64, 90 * 64);
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, x, yc + hc - r,
|
||||
(unsigned)r*2, (unsigned)2*r, 180 * 64, 90 * 64);
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, xc + wc - r, yc + hc - r,
|
||||
(unsigned)r*2, (unsigned)2*r, -90 * 64, 90 * 64);
|
||||
}
|
||||
XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_fill_rect(XSurface* surf, short x, short y, unsigned short w,
|
||||
unsigned short h, unsigned short r, struct nk_color col)
|
||||
{
|
||||
unsigned long c = nk_color_from_byte(&col.r);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
if (r == 0) {
|
||||
XFillRectangle(surf->dpy, surf->drawable, surf->gc, x, y, w, h);
|
||||
} else {
|
||||
short xc = x + r;
|
||||
short yc = y + r;
|
||||
short wc = (short)(w - 2 * r);
|
||||
short hc = (short)(h - 2 * r);
|
||||
|
||||
XPoint pnts[12];
|
||||
pnts[0].x = x;
|
||||
pnts[0].y = yc;
|
||||
pnts[1].x = xc;
|
||||
pnts[1].y = yc;
|
||||
pnts[2].x = xc;
|
||||
pnts[2].y = y;
|
||||
|
||||
pnts[3].x = xc + wc;
|
||||
pnts[3].y = y;
|
||||
pnts[4].x = xc + wc;
|
||||
pnts[4].y = yc;
|
||||
pnts[5].x = x + w;
|
||||
pnts[5].y = yc;
|
||||
|
||||
pnts[6].x = x + w;
|
||||
pnts[6].y = yc + hc;
|
||||
pnts[7].x = xc + wc;
|
||||
pnts[7].y = yc + hc;
|
||||
pnts[8].x = xc + wc;
|
||||
pnts[8].y = y + h;
|
||||
|
||||
pnts[9].x = xc;
|
||||
pnts[9].y = y + h;
|
||||
pnts[10].x = xc;
|
||||
pnts[10].y = yc + hc;
|
||||
pnts[11].x = x;
|
||||
pnts[11].y = yc + hc;
|
||||
|
||||
XFillPolygon(surf->dpy, surf->drawable, surf->gc, pnts, 12, Convex, CoordModeOrigin);
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, xc + wc - r, y,
|
||||
(unsigned)r*2, (unsigned)r*2, 0 * 64, 90 * 64);
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, x, y,
|
||||
(unsigned)r*2, (unsigned)r*2, 90 * 64, 90 * 64);
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, x, yc + hc - r,
|
||||
(unsigned)r*2, (unsigned)2*r, 180 * 64, 90 * 64);
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, xc + wc - r, yc + hc - r,
|
||||
(unsigned)r*2, (unsigned)2*r, -90 * 64, 90 * 64);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_fill_triangle(XSurface *surf, short x0, short y0, short x1,
|
||||
short y1, short x2, short y2, struct nk_color col)
|
||||
{
|
||||
XPoint pnts[3];
|
||||
unsigned long c = nk_color_from_byte(&col.r);
|
||||
pnts[0].x = (short)x0;
|
||||
pnts[0].y = (short)y0;
|
||||
pnts[1].x = (short)x1;
|
||||
pnts[1].y = (short)y1;
|
||||
pnts[2].x = (short)x2;
|
||||
pnts[2].y = (short)y2;
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
XFillPolygon(surf->dpy, surf->drawable, surf->gc, pnts, 3, Convex, CoordModeOrigin);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_stroke_triangle(XSurface *surf, short x0, short y0, short x1,
|
||||
short y1, short x2, short y2, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
XPoint pnts[3];
|
||||
unsigned long c = nk_color_from_byte(&col.r);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter);
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, x0, y0, x1, y1);
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, x1, y1, x2, y2);
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, x2, y2, x0, y0);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_fill_polygon(XSurface *surf, const struct nk_vec2i *pnts, int count,
|
||||
struct nk_color col)
|
||||
{
|
||||
int i = 0;
|
||||
#define MAX_POINTS 64
|
||||
XPoint xpnts[MAX_POINTS];
|
||||
unsigned long c = nk_color_from_byte(&col.r);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
for (i = 0; i < count && i < MAX_POINTS; ++i) {
|
||||
xpnts[i].x = pnts[i].x;
|
||||
xpnts[i].y = pnts[i].y;
|
||||
}
|
||||
XFillPolygon(surf->dpy, surf->drawable, surf->gc, xpnts, count, Convex, CoordModeOrigin);
|
||||
#undef MAX_POINTS
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_stroke_polygon(XSurface *surf, const struct nk_vec2i *pnts, int count,
|
||||
unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned long c = nk_color_from_byte(&col.r);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter);
|
||||
for (i = 1; i < count; ++i)
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, pnts[i-1].x, pnts[i-1].y, pnts[i].x, pnts[i].y);
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, pnts[count-1].x, pnts[count-1].y, pnts[0].x, pnts[0].y);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_stroke_polyline(XSurface *surf, const struct nk_vec2i *pnts,
|
||||
int count, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned long c = nk_color_from_byte(&col.r);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
for (i = 0; i < count-1; ++i)
|
||||
XDrawLine(surf->dpy, surf->drawable, surf->gc, pnts[i].x, pnts[i].y, pnts[i+1].x, pnts[i+1].y);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_fill_circle(XSurface *surf, short x, short y, unsigned short w,
|
||||
unsigned short h, struct nk_color col)
|
||||
{
|
||||
unsigned long c = nk_color_from_byte(&col.r);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
XFillArc(surf->dpy, surf->drawable, surf->gc, (int)x, (int)y,
|
||||
(unsigned)w, (unsigned)h, 0, 360 * 64);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_stroke_circle(XSurface *surf, short x, short y, unsigned short w,
|
||||
unsigned short h, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
unsigned long c = nk_color_from_byte(&col.r);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter);
|
||||
XSetForeground(surf->dpy, surf->gc, c);
|
||||
XDrawArc(surf->dpy, surf->drawable, surf->gc, (int)x, (int)y,
|
||||
(unsigned)w, (unsigned)h, 0, 360 * 64);
|
||||
XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_stroke_curve(XSurface *surf, struct nk_vec2i p1,
|
||||
struct nk_vec2i p2, struct nk_vec2i p3, struct nk_vec2i p4,
|
||||
unsigned int num_segments, unsigned short line_thickness, struct nk_color col)
|
||||
{
|
||||
unsigned int i_step;
|
||||
float t_step;
|
||||
struct nk_vec2i last = p1;
|
||||
|
||||
XSetLineAttributes(surf->dpy, surf->gc, line_thickness, LineSolid, CapButt, JoinMiter);
|
||||
num_segments = MAX(num_segments, 1);
|
||||
t_step = 1.0f/(float)num_segments;
|
||||
for (i_step = 1; i_step <= num_segments; ++i_step) {
|
||||
float t = t_step * (float)i_step;
|
||||
float u = 1.0f - t;
|
||||
float w1 = u*u*u;
|
||||
float w2 = 3*u*u*t;
|
||||
float w3 = 3*u*t*t;
|
||||
float w4 = t * t *t;
|
||||
float x = w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x;
|
||||
float y = w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y;
|
||||
nk_xsurf_stroke_line(surf, last.x, last.y, (short)x, (short)y, line_thickness,col);
|
||||
last.x = (short)x; last.y = (short)y;
|
||||
}
|
||||
XSetLineAttributes(surf->dpy, surf->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_draw_text(XSurface *surf, short x, short y, unsigned short w, unsigned short h,
|
||||
const char *text, int len, XFont *font, struct nk_color cbg, struct nk_color cfg)
|
||||
{
|
||||
int tx, ty;
|
||||
unsigned long bg = nk_color_from_byte(&cbg.r);
|
||||
unsigned long fg = nk_color_from_byte(&cfg.r);
|
||||
|
||||
XSetForeground(surf->dpy, surf->gc, bg);
|
||||
XFillRectangle(surf->dpy, surf->drawable, surf->gc, (int)x, (int)y, (unsigned)w, (unsigned)h);
|
||||
if(!text || !font || !len) return;
|
||||
|
||||
tx = (int)x;
|
||||
ty = (int)y + font->ascent;
|
||||
XSetForeground(surf->dpy, surf->gc, fg);
|
||||
if(font->set)
|
||||
XmbDrawString(surf->dpy,surf->drawable,font->set,surf->gc,tx,ty,(const char*)text,(int)len);
|
||||
else
|
||||
XDrawString(surf->dpy, surf->drawable, surf->gc, tx, ty, (const char*)text, (int)len);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_clear(XSurface *surf, unsigned long color)
|
||||
{
|
||||
XSetForeground(surf->dpy, surf->gc, color);
|
||||
XFillRectangle(surf->dpy, surf->drawable, surf->gc, 0, 0, surf->w, surf->h);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_blit(Drawable target, XSurface *surf, unsigned int w, unsigned int h)
|
||||
{
|
||||
XCopyArea(surf->dpy, surf->drawable, target, surf->gc, 0, 0, w, h, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_xsurf_del(XSurface *surf)
|
||||
{
|
||||
XFreePixmap(surf->dpy, surf->drawable);
|
||||
XFreeGC(surf->dpy, surf->gc);
|
||||
free(surf);
|
||||
}
|
||||
|
||||
XFont*
|
||||
nk_xfont_create(Display *dpy, const char *name)
|
||||
{
|
||||
int n;
|
||||
char *def, **missing;
|
||||
XFont *font = (XFont*)calloc(1, sizeof(XFont));
|
||||
font->set = XCreateFontSet(dpy, name, &missing, &n, &def);
|
||||
if(missing) {
|
||||
while(n--)
|
||||
fprintf(stderr, "missing fontset: %s\n", missing[n]);
|
||||
XFreeStringList(missing);
|
||||
}
|
||||
|
||||
if(font->set) {
|
||||
XFontStruct **xfonts;
|
||||
char **font_names;
|
||||
XExtentsOfFontSet(font->set);
|
||||
n = XFontsOfFontSet(font->set, &xfonts, &font_names);
|
||||
while(n--) {
|
||||
font->ascent = MAX(font->ascent, (*xfonts)->ascent);
|
||||
font->descent = MAX(font->descent,(*xfonts)->descent);
|
||||
xfonts++;
|
||||
}
|
||||
} else {
|
||||
if(!(font->xfont = XLoadQueryFont(dpy, name))
|
||||
&& !(font->xfont = XLoadQueryFont(dpy, "fixed"))) {
|
||||
free(font);
|
||||
return 0;
|
||||
}
|
||||
font->ascent = font->xfont->ascent;
|
||||
font->descent = font->xfont->descent;
|
||||
}
|
||||
font->height = font->ascent + font->descent;
|
||||
return font;
|
||||
}
|
||||
|
||||
static float
|
||||
nk_xfont_get_text_width(nk_handle handle, float height, const char *text, int len)
|
||||
{
|
||||
XFont *font = (XFont*)handle.ptr;
|
||||
XRectangle r;
|
||||
if(!font || !text)
|
||||
return 0;
|
||||
|
||||
if(font->set) {
|
||||
XmbTextExtents(font->set, (const char*)text, len, NULL, &r);
|
||||
return (float)r.width;
|
||||
} else{
|
||||
int w = XTextWidth(font->xfont, (const char*)text, len);
|
||||
return (float)w;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nk_xfont_del(Display *dpy, XFont *font)
|
||||
{
|
||||
if(!font) return;
|
||||
if(font->set)
|
||||
XFreeFontSet(dpy, font->set);
|
||||
else
|
||||
XFreeFont(dpy, font->xfont);
|
||||
free(font);
|
||||
}
|
||||
|
||||
NK_API struct nk_context*
|
||||
nk_xlib_init(XFont *xfont, Display *dpy, int screen, Window root,
|
||||
unsigned int w, unsigned int h)
|
||||
{
|
||||
struct nk_user_font font;
|
||||
font.userdata = nk_handle_ptr(xfont);
|
||||
font.height = (float)xfont->height;
|
||||
font.width = nk_xfont_get_text_width;
|
||||
|
||||
if (!setlocale(LC_ALL,"")) return 0;
|
||||
if (!XSupportsLocale()) return 0;
|
||||
if (!XSetLocaleModifiers("@im=none")) return 0;
|
||||
|
||||
xlib.surf = nk_xsurf_create(dpy, screen, root, w, h);
|
||||
nk_init_default(&xlib.ctx, &font);
|
||||
return &xlib.ctx;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_xlib_set_font(XFont *xfont)
|
||||
{
|
||||
struct nk_user_font font;
|
||||
font.userdata = nk_handle_ptr(xfont);
|
||||
font.height = (float)xfont->height;
|
||||
font.width = nk_xfont_get_text_width;
|
||||
nk_style_set_font(&xlib.ctx, &font);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_xlib_handle_event(Display *dpy, int screen, Window win, XEvent *evt)
|
||||
{
|
||||
struct nk_context *ctx = &xlib.ctx;
|
||||
if (evt->type == KeyPress || evt->type == KeyRelease)
|
||||
{
|
||||
/* Key handler */
|
||||
int ret, down = (evt->type == KeyPress);
|
||||
KeySym *code = XGetKeyboardMapping(xlib.surf->dpy, (KeyCode)evt->xkey.keycode, 1, &ret);
|
||||
if (*code == XK_Shift_L || *code == XK_Shift_R) nk_input_key(ctx, NK_KEY_SHIFT, down);
|
||||
else if (*code == XK_Delete) nk_input_key(ctx, NK_KEY_DEL, down);
|
||||
else if (*code == XK_Return) nk_input_key(ctx, NK_KEY_ENTER, down);
|
||||
else if (*code == XK_Tab) nk_input_key(ctx, NK_KEY_TAB, down);
|
||||
else if (*code == XK_Left) nk_input_key(ctx, NK_KEY_LEFT, down);
|
||||
else if (*code == XK_Right) nk_input_key(ctx, NK_KEY_RIGHT, down);
|
||||
else if (*code == XK_BackSpace) nk_input_key(ctx, NK_KEY_BACKSPACE, down);
|
||||
else if (*code == XK_Home) nk_input_key(ctx, NK_KEY_TEXT_START, down);
|
||||
else if (*code == XK_End) nk_input_key(ctx, NK_KEY_TEXT_END, down);
|
||||
else if (*code == XK_space && !down) nk_input_char(ctx, ' ');
|
||||
else {
|
||||
if (*code == 'c' && (evt->xkey.state & ControlMask))
|
||||
nk_input_key(ctx, NK_KEY_COPY, down);
|
||||
else if (*code == 'v' && (evt->xkey.state & ControlMask))
|
||||
nk_input_key(ctx, NK_KEY_PASTE, down);
|
||||
else if (*code == 'x' && (evt->xkey.state & ControlMask))
|
||||
nk_input_key(ctx, NK_KEY_CUT, down);
|
||||
else if (*code == 'z' && (evt->xkey.state & ControlMask))
|
||||
nk_input_key(ctx, NK_KEY_TEXT_UNDO, down);
|
||||
else if (*code == 'r' && (evt->xkey.state & ControlMask))
|
||||
nk_input_key(ctx, NK_KEY_TEXT_REDO, down);
|
||||
else if (*code == XK_Left && (evt->xkey.state & ControlMask))
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, down);
|
||||
else if (*code == XK_Right && (evt->xkey.state & ControlMask))
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, down);
|
||||
else if (*code == 'b' && (evt->xkey.state & ControlMask))
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_START, down);
|
||||
else if (*code == 'e' && (evt->xkey.state & ControlMask))
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_END, down);
|
||||
else if (!down) {
|
||||
char buf[32];
|
||||
KeySym keysym = 0;
|
||||
if (XLookupString((XKeyEvent*)evt, buf, 32, &keysym, NULL) != NoSymbol)
|
||||
nk_input_glyph(ctx, buf);
|
||||
}
|
||||
}
|
||||
XFree(code);
|
||||
} else if (evt->type == ButtonPress || evt->type == ButtonRelease) {
|
||||
/* Button handler */
|
||||
int down = (evt->type == ButtonPress);
|
||||
const int x = evt->xbutton.x, y = evt->xbutton.y;
|
||||
if (evt->xbutton.button == Button1)
|
||||
nk_input_button(ctx, NK_BUTTON_LEFT, x, y, down);
|
||||
if (evt->xbutton.button == Button2)
|
||||
nk_input_button(ctx, NK_BUTTON_MIDDLE, x, y, down);
|
||||
else if (evt->xbutton.button == Button3)
|
||||
nk_input_button(ctx, NK_BUTTON_RIGHT, x, y, down);
|
||||
else if (evt->xbutton.button == Button4)
|
||||
nk_input_scroll(ctx, 1.0f);
|
||||
else if (evt->xbutton.button == Button5)
|
||||
nk_input_scroll(ctx, -1.0f);
|
||||
|
||||
} else if (evt->type == MotionNotify) {
|
||||
/* Mouse motion handler */
|
||||
const int x = evt->xmotion.x, y = evt->xmotion.y;
|
||||
nk_input_motion(ctx, x, y);
|
||||
} else if (evt->type == Expose || evt->type == ConfigureNotify) {
|
||||
/* Window resize handler */
|
||||
unsigned int width, height;
|
||||
XWindowAttributes attr;
|
||||
XGetWindowAttributes(dpy, win, &attr);
|
||||
width = (unsigned int)attr.width;
|
||||
height = (unsigned int)attr.height;
|
||||
nk_xsurf_resize(xlib.surf, width, height);
|
||||
} else if (evt->type == KeymapNotify)
|
||||
XRefreshKeyboardMapping(&evt->xmapping);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_xlib_shutdown(void)
|
||||
{
|
||||
nk_xsurf_del(xlib.surf);
|
||||
nk_free(&xlib.ctx);
|
||||
nk_memset(&xlib, 0, sizeof(xlib));
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_xlib_render(Drawable screen, struct nk_color clear)
|
||||
{
|
||||
const struct nk_command *cmd;
|
||||
struct nk_context *ctx = &xlib.ctx;
|
||||
XSurface *surf = xlib.surf;
|
||||
|
||||
nk_xsurf_clear(xlib.surf, nk_color_from_byte(&clear.r));
|
||||
nk_foreach(cmd, &xlib.ctx)
|
||||
{
|
||||
switch (cmd->type) {
|
||||
case NK_COMMAND_NOP: break;
|
||||
case NK_COMMAND_SCISSOR: {
|
||||
const struct nk_command_scissor *s =(const struct nk_command_scissor*)cmd;
|
||||
nk_xsurf_scissor(surf, s->x, s->y, s->w, s->h);
|
||||
} break;
|
||||
case NK_COMMAND_LINE: {
|
||||
const struct nk_command_line *l = (const struct nk_command_line *)cmd;
|
||||
nk_xsurf_stroke_line(surf, l->begin.x, l->begin.y, l->end.x,
|
||||
l->end.y, l->line_thickness, l->color);
|
||||
} break;
|
||||
case NK_COMMAND_RECT: {
|
||||
const struct nk_command_rect *r = (const struct nk_command_rect *)cmd;
|
||||
nk_xsurf_stroke_rect(surf, r->x, r->y, r->w, r->h,
|
||||
(unsigned short)r->rounding, r->line_thickness, r->color);
|
||||
} break;
|
||||
case NK_COMMAND_RECT_FILLED: {
|
||||
const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled *)cmd;
|
||||
nk_xsurf_fill_rect(surf, r->x, r->y, r->w, r->h,
|
||||
(unsigned short)r->rounding, r->color);
|
||||
} break;
|
||||
case NK_COMMAND_CIRCLE: {
|
||||
const struct nk_command_circle *c = (const struct nk_command_circle *)cmd;
|
||||
nk_xsurf_stroke_circle(surf, c->x, c->y, c->w, c->h, c->line_thickness, c->color);
|
||||
} break;
|
||||
case NK_COMMAND_CIRCLE_FILLED: {
|
||||
const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
|
||||
nk_xsurf_fill_circle(surf, c->x, c->y, c->w, c->h, c->color);
|
||||
} break;
|
||||
case NK_COMMAND_TRIANGLE: {
|
||||
const struct nk_command_triangle*t = (const struct nk_command_triangle*)cmd;
|
||||
nk_xsurf_stroke_triangle(surf, t->a.x, t->a.y, t->b.x, t->b.y,
|
||||
t->c.x, t->c.y, t->line_thickness, t->color);
|
||||
} break;
|
||||
case NK_COMMAND_TRIANGLE_FILLED: {
|
||||
const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled *)cmd;
|
||||
nk_xsurf_fill_triangle(surf, t->a.x, t->a.y, t->b.x, t->b.y,
|
||||
t->c.x, t->c.y, t->color);
|
||||
} break;
|
||||
case NK_COMMAND_POLYGON: {
|
||||
const struct nk_command_polygon *p =(const struct nk_command_polygon*)cmd;
|
||||
nk_xsurf_stroke_polygon(surf, p->points, p->point_count, p->line_thickness,p->color);
|
||||
} break;
|
||||
case NK_COMMAND_POLYGON_FILLED: {
|
||||
const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled *)cmd;
|
||||
nk_xsurf_fill_polygon(surf, p->points, p->point_count, p->color);
|
||||
} break;
|
||||
case NK_COMMAND_POLYLINE: {
|
||||
const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd;
|
||||
nk_xsurf_stroke_polyline(surf, p->points, p->point_count, p->line_thickness, p->color);
|
||||
} break;
|
||||
case NK_COMMAND_TEXT: {
|
||||
const struct nk_command_text *t = (const struct nk_command_text*)cmd;
|
||||
nk_xsurf_draw_text(surf, t->x, t->y, t->w, t->h,
|
||||
(const char*)t->string, t->length,
|
||||
(XFont*)t->font->userdata.ptr,
|
||||
t->background, t->foreground);
|
||||
} break;
|
||||
case NK_COMMAND_CURVE: {
|
||||
const struct nk_command_curve *q = (const struct nk_command_curve *)cmd;
|
||||
nk_xsurf_stroke_curve(surf, q->begin, q->ctrl[0], q->ctrl[1],
|
||||
q->end, 22, q->line_thickness, q->color);
|
||||
} break;
|
||||
case NK_COMMAND_RECT_MULTI_COLOR:
|
||||
case NK_COMMAND_IMAGE:
|
||||
case NK_COMMAND_ARC:
|
||||
case NK_COMMAND_ARC_FILLED:
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
nk_clear(ctx);
|
||||
nk_xsurf_blit(screen, surf, surf->w, surf->h);
|
||||
}
|
||||
#endif
|
||||
|
@ -10,17 +10,17 @@
|
||||
#include <time.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* these defines are both needed for the header
|
||||
* and source file. So if you split them remember
|
||||
* to copy them as well. */
|
||||
#define NK_INCLUDE_FIXED_TYPES
|
||||
#define NK_INCLUDE_STANDARD_IO
|
||||
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
||||
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
|
||||
#define NK_INCLUDE_FONT_BAKING
|
||||
#define NK_INCLUDE_DEFAULT_FONT
|
||||
#include "nuklear_x11.h"
|
||||
#include "nuklear_x11.c"
|
||||
#define NK_IMPLEMENTATION
|
||||
#define NK_XLIB_GL3_IMPLEMENTATION
|
||||
#define NK_XLIB_LOAD_OPENGL_EXTENSIONS
|
||||
#include "../../nuklear.h"
|
||||
#include "nuklear_xlib_gl3.h"
|
||||
|
||||
#define WINDOW_WIDTH 800
|
||||
#define WINDOW_HEIGHT 600
|
||||
|
@ -1,25 +0,0 @@
|
||||
#ifndef NK_X11_OPENGL_H_
|
||||
#define NK_X11_OPENGL_H_
|
||||
|
||||
#include "../../nuklear.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xresource.h>
|
||||
|
||||
/* Define this to 0 if you already load all required OpenGL extensions yourself
|
||||
* otherwise define to 1 to let nuklear load its required extensions. */
|
||||
#define NK_X11_LOAD_OPENGL_EXTENSIONS 1
|
||||
|
||||
NK_API struct nk_context *nk_x11_init(Display *dpy, Window win);
|
||||
NK_API void nk_x11_font_stash_begin(struct nk_font_atlas **atlas);
|
||||
NK_API void nk_x11_font_stash_end(void);
|
||||
NK_API void nk_x11_handle_event(XEvent *evt);
|
||||
NK_API void nk_x11_render(enum nk_anti_aliasing, int max_vertex_buffer, int max_element_buffer);
|
||||
NK_API void nk_x11_shutdown(void);
|
||||
|
||||
NK_API int nk_x11_device_create(void);
|
||||
NK_API void nk_x11_device_destroy(void);
|
||||
|
||||
|
||||
#endif
|
@ -1,3 +1,37 @@
|
||||
/*
|
||||
* Nuklear - v1.00 - public domain
|
||||
* no warrenty implied; use at your own risk.
|
||||
* authored from 2015-2016 by Micha Mettke
|
||||
*/
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* API
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifndef NK_XLIB_GL3_H_
|
||||
#define NK_XLIB_GL3_H_
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
NK_API struct nk_context* nk_x11_init(Display *dpy, Window win);
|
||||
NK_API void nk_x11_font_stash_begin(struct nk_font_atlas **atlas);
|
||||
NK_API void nk_x11_font_stash_end(void);
|
||||
NK_API void nk_x11_handle_event(XEvent *evt);
|
||||
NK_API void nk_x11_render(enum nk_anti_aliasing, int max_vertex_buffer, int max_element_buffer);
|
||||
NK_API void nk_x11_shutdown(void);
|
||||
NK_API int nk_x11_device_create(void);
|
||||
NK_API void nk_x11_device_destroy(void);
|
||||
|
||||
#endif
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* IMPLEMENTATION
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifdef NK_XLIB_GL3_IMPLEMENTATION
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -8,13 +42,7 @@
|
||||
#include <X11/Xlocale.h>
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
#include <GL/glext.h>
|
||||
#include <GL/glxext.h>
|
||||
|
||||
#define NK_IMPLEMENTATION
|
||||
#include "nuklear_x11.h"
|
||||
#include "../../nuklear.h"
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
@ -23,81 +51,81 @@
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#if NK_X11_LOAD_OPENGL_EXTENSIONS
|
||||
#ifdef NK_XLIB_LOAD_OPENGL_EXTENSIONS
|
||||
/* GL_ARB_vertex_buffer_object */
|
||||
typedef void(*qglGenBuffers)(GLsizei, GLuint*);
|
||||
typedef void(*qglBindBuffer)(GLenum, GLuint);
|
||||
typedef void(*qglBufferData)(GLenum, GLsizeiptr, const GLvoid*, GLenum);
|
||||
typedef void(*qglBufferSubData)(GLenum, GLintptr, GLsizeiptr, const GLvoid*);
|
||||
typedef void*(*qglMapBuffer)(GLenum, GLenum);
|
||||
typedef GLboolean(*qglUnmapBuffer)(GLenum);
|
||||
typedef void(*qglDeleteBuffers)(GLsizei, GLuint*);
|
||||
typedef void(*nkglGenBuffers)(GLsizei, GLuint*);
|
||||
typedef void(*nkglBindBuffer)(GLenum, GLuint);
|
||||
typedef void(*nkglBufferData)(GLenum, GLsizeiptr, const GLvoid*, GLenum);
|
||||
typedef void(*nkglBufferSubData)(GLenum, GLintptr, GLsizeiptr, const GLvoid*);
|
||||
typedef void*(*nkglMapBuffer)(GLenum, GLenum);
|
||||
typedef GLboolean(*nkglUnmapBuffer)(GLenum);
|
||||
typedef void(*nkglDeleteBuffers)(GLsizei, GLuint*);
|
||||
/* GL_ARB_vertex_array_object */
|
||||
typedef void (*qglGenVertexArrays)(GLsizei, GLuint*);
|
||||
typedef void (*qglBindVertexArray)(GLuint);
|
||||
typedef void (*qglDeleteVertexArrays)(GLsizei, const GLuint*);
|
||||
typedef void (*nkglGenVertexArrays)(GLsizei, GLuint*);
|
||||
typedef void (*nkglBindVertexArray)(GLuint);
|
||||
typedef void (*nkglDeleteVertexArrays)(GLsizei, const GLuint*);
|
||||
/* GL_ARB_vertex_program / GL_ARB_fragment_program */
|
||||
typedef void(*qglVertexAttribPointer)(GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid*);
|
||||
typedef void(*qglEnableVertexAttribArray)(GLuint);
|
||||
typedef void(*qglDisableVertexAttribArray)(GLuint);
|
||||
typedef void(*nkglVertexAttribPointer)(GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid*);
|
||||
typedef void(*nkglEnableVertexAttribArray)(GLuint);
|
||||
typedef void(*nkglDisableVertexAttribArray)(GLuint);
|
||||
/* GL_ARB_framebuffer_object */
|
||||
typedef void(*qglGenerateMipmap)(GLenum target);
|
||||
typedef void(*nkglGenerateMipmap)(GLenum target);
|
||||
/* GLSL/OpenGL 2.0 core */
|
||||
typedef GLuint(*qglCreateShader)(GLenum);
|
||||
typedef void(*qglShaderSource)(GLuint, GLsizei, const GLchar**, const GLint*);
|
||||
typedef void(*qglCompileShader)(GLuint);
|
||||
typedef void(*qglGetShaderiv)(GLuint, GLenum, GLint*);
|
||||
typedef void(*qglGetShaderInfoLog)(GLuint, GLsizei, GLsizei*, GLchar*);
|
||||
typedef void(*qglDeleteShader)(GLuint);
|
||||
typedef GLuint(*qglCreateProgram)(void);
|
||||
typedef void(*qglAttachShader)(GLuint, GLuint);
|
||||
typedef void(*qglDetachShader)(GLuint, GLuint);
|
||||
typedef void(*qglLinkProgram)(GLuint);
|
||||
typedef void(*qglUseProgram)(GLuint);
|
||||
typedef void(*qglGetProgramiv)(GLuint, GLenum, GLint*);
|
||||
typedef void(*qglGetProgramInfoLog)(GLuint, GLsizei, GLsizei*, GLchar*);
|
||||
typedef void(*qglDeleteProgram)(GLuint);
|
||||
typedef GLint(*qglGetUniformLocation)(GLuint, const GLchar*);
|
||||
typedef GLint(*qglGetAttribLocation)(GLuint, const GLchar*);
|
||||
typedef void(*qglUniform1i)(GLint, GLint);
|
||||
typedef void(*qglUniform1f)(GLint, GLfloat);
|
||||
typedef void(*qglUniformMatrix3fv)(GLint, GLsizei, GLboolean, const GLfloat*);
|
||||
typedef void(*qglUniformMatrix4fv)(GLint, GLsizei, GLboolean, const GLfloat*);
|
||||
typedef GLuint(*nkglCreateShader)(GLenum);
|
||||
typedef void(*nkglShaderSource)(GLuint, GLsizei, const GLchar**, const GLint*);
|
||||
typedef void(*nkglCompileShader)(GLuint);
|
||||
typedef void(*nkglGetShaderiv)(GLuint, GLenum, GLint*);
|
||||
typedef void(*nkglGetShaderInfoLog)(GLuint, GLsizei, GLsizei*, GLchar*);
|
||||
typedef void(*nkglDeleteShader)(GLuint);
|
||||
typedef GLuint(*nkglCreateProgram)(void);
|
||||
typedef void(*nkglAttachShader)(GLuint, GLuint);
|
||||
typedef void(*nkglDetachShader)(GLuint, GLuint);
|
||||
typedef void(*nkglLinkProgram)(GLuint);
|
||||
typedef void(*nkglUseProgram)(GLuint);
|
||||
typedef void(*nkglGetProgramiv)(GLuint, GLenum, GLint*);
|
||||
typedef void(*nkglGetProgramInfoLog)(GLuint, GLsizei, GLsizei*, GLchar*);
|
||||
typedef void(*nkglDeleteProgram)(GLuint);
|
||||
typedef GLint(*nkglGetUniformLocation)(GLuint, const GLchar*);
|
||||
typedef GLint(*nkglGetAttribLocation)(GLuint, const GLchar*);
|
||||
typedef void(*nkglUniform1i)(GLint, GLint);
|
||||
typedef void(*nkglUniform1f)(GLint, GLfloat);
|
||||
typedef void(*nkglUniformMatrix3fv)(GLint, GLsizei, GLboolean, const GLfloat*);
|
||||
typedef void(*nkglUniformMatrix4fv)(GLint, GLsizei, GLboolean, const GLfloat*);
|
||||
|
||||
static qglGenBuffers glGenBuffers;
|
||||
static qglBindBuffer glBindBuffer;
|
||||
static qglBufferData glBufferData;
|
||||
static qglBufferSubData glBufferSubData;
|
||||
static qglMapBuffer glMapBuffer;
|
||||
static qglUnmapBuffer glUnmapBuffer;
|
||||
static qglDeleteBuffers glDeleteBuffers;
|
||||
static qglGenVertexArrays glGenVertexArrays;
|
||||
static qglBindVertexArray glBindVertexArray;
|
||||
static qglDeleteVertexArrays glDeleteVertexArrays;
|
||||
static qglVertexAttribPointer glVertexAttribPointer;
|
||||
static qglEnableVertexAttribArray glEnableVertexAttribArray;
|
||||
static qglDisableVertexAttribArray glDisableVertexAttribArray;
|
||||
static qglGenerateMipmap glGenerateMipmap;
|
||||
static qglCreateShader glCreateShader;
|
||||
static qglShaderSource glShaderSource;
|
||||
static qglCompileShader glCompileShader;
|
||||
static qglGetShaderiv glGetShaderiv;
|
||||
static qglGetShaderInfoLog glGetShaderInfoLog;
|
||||
static qglDeleteShader glDeleteShader;
|
||||
static qglCreateProgram glCreateProgram;
|
||||
static qglAttachShader glAttachShader;
|
||||
static qglDetachShader glDetachShader;
|
||||
static qglLinkProgram glLinkProgram;
|
||||
static qglUseProgram glUseProgram;
|
||||
static qglGetProgramiv glGetProgramiv;
|
||||
static qglGetProgramInfoLog glGetProgramInfoLog;
|
||||
static qglDeleteProgram glDeleteProgram;
|
||||
static qglGetUniformLocation glGetUniformLocation;
|
||||
static qglGetAttribLocation glGetAttribLocation;
|
||||
static qglUniform1i glUniform1i;
|
||||
static qglUniform1f glUniform1f;
|
||||
static qglUniformMatrix3fv glUniformMatrix3fv;
|
||||
static qglUniformMatrix4fv glUniformMatrix4fv;
|
||||
static nkglGenBuffers glGenBuffers;
|
||||
static nkglBindBuffer glBindBuffer;
|
||||
static nkglBufferData glBufferData;
|
||||
static nkglBufferSubData glBufferSubData;
|
||||
static nkglMapBuffer glMapBuffer;
|
||||
static nkglUnmapBuffer glUnmapBuffer;
|
||||
static nkglDeleteBuffers glDeleteBuffers;
|
||||
static nkglGenVertexArrays glGenVertexArrays;
|
||||
static nkglBindVertexArray glBindVertexArray;
|
||||
static nkglDeleteVertexArrays glDeleteVertexArrays;
|
||||
static nkglVertexAttribPointer glVertexAttribPointer;
|
||||
static nkglEnableVertexAttribArray glEnableVertexAttribArray;
|
||||
static nkglDisableVertexAttribArray glDisableVertexAttribArray;
|
||||
static nkglGenerateMipmap glGenerateMipmap;
|
||||
static nkglCreateShader glCreateShader;
|
||||
static nkglShaderSource glShaderSource;
|
||||
static nkglCompileShader glCompileShader;
|
||||
static nkglGetShaderiv glGetShaderiv;
|
||||
static nkglGetShaderInfoLog glGetShaderInfoLog;
|
||||
static nkglDeleteShader glDeleteShader;
|
||||
static nkglCreateProgram glCreateProgram;
|
||||
static nkglAttachShader glAttachShader;
|
||||
static nkglDetachShader glDetachShader;
|
||||
static nkglLinkProgram glLinkProgram;
|
||||
static nkglUseProgram glUseProgram;
|
||||
static nkglGetProgramiv glGetProgramiv;
|
||||
static nkglGetProgramInfoLog glGetProgramInfoLog;
|
||||
static nkglDeleteProgram glDeleteProgram;
|
||||
static nkglGetUniformLocation glGetUniformLocation;
|
||||
static nkglGetAttribLocation glGetAttribLocation;
|
||||
static nkglUniform1i glUniform1i;
|
||||
static nkglUniform1f glUniform1f;
|
||||
static nkglUniformMatrix3fv glUniformMatrix3fv;
|
||||
static nkglUniformMatrix4fv glUniformMatrix4fv;
|
||||
|
||||
enum graphics_card_vendors {
|
||||
VENDOR_UNKNOWN,
|
||||
@ -129,7 +157,7 @@ struct opengl_info {
|
||||
#endif
|
||||
|
||||
struct nk_x11_device {
|
||||
#if NK_X11_LOAD_OPENGL_EXTENSIONS
|
||||
#ifdef NK_XLIB_LOAD_OPENGL_EXTENSIONS
|
||||
struct opengl_info info;
|
||||
#endif
|
||||
struct nk_buffer cmds;
|
||||
@ -160,7 +188,10 @@ static struct nk_x11 {
|
||||
#define NK_SHADER_VERSION "#version 300 es\n"
|
||||
#endif
|
||||
|
||||
#if NK_X11_LOAD_OPENGL_EXTENSIONS
|
||||
#ifdef NK_XLIB_LOAD_OPENGL_EXTENSIONS
|
||||
#include <GL/glx.h>
|
||||
#include <GL/glxext.h>
|
||||
|
||||
NK_INTERN int
|
||||
nk_x11_stricmpn(const char *a, const char *b, int len)
|
||||
{
|
||||
@ -192,7 +223,7 @@ nk_x11_check_extension(struct opengl_info *GL, const char *ext)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define GL_EXT(name) (q##name)nk_gl_ext(#name)
|
||||
#define GL_EXT(name) (nk##name)nk_gl_ext(#name)
|
||||
NK_INTERN __GLXextFuncPtr
|
||||
nk_gl_ext(const char *name)
|
||||
{
|
||||
@ -335,7 +366,7 @@ nk_x11_device_create(void)
|
||||
"}\n";
|
||||
|
||||
struct nk_x11_device *dev = &x11.ogl;
|
||||
#if NK_X11_LOAD_OPENGL_EXTENSIONS
|
||||
#ifdef NK_XLIB_LOAD_OPENGL_EXTENSIONS
|
||||
if (!nk_load_opengl(&dev->info)) return 0;
|
||||
#endif
|
||||
nk_buffer_init_default(&dev->cmds);
|
||||
@ -627,3 +658,4 @@ nk_x11_shutdown(void)
|
||||
memset(&x11, 0, sizeof(x11));
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user