sync fwk
parent
4cf144a0dd
commit
48ecfdef3a
20
bind/v4k.lua
20
bind/v4k.lua
|
@ -2128,6 +2128,7 @@ typedef union json_t { char* s; double f; int64_t i; uintptr_t p; union json_t*
|
|||
int* engine_geti(const char *key);
|
||||
char** engine_gets(const char *key);
|
||||
int engine_send(const char *cmd, const char *optional_value);
|
||||
int ui_debug();
|
||||
char* dialog_load();
|
||||
char* dialog_save();
|
||||
int gizmo(vec3 *pos, vec3 *rot, vec3 *sca);
|
||||
|
@ -2493,8 +2494,8 @@ enum { NETWORK_USERID = 7, NETWORK_COUNT , NETWORK_CAPACITY };
|
|||
void server_send_bin(int64_t handle, const void *ptr, int len);
|
||||
void server_drop(int64_t handle);
|
||||
int64_t client_join(const char *ip, int port);
|
||||
typedef struct obj { struct { union { uintptr_t objheader; struct { uintptr_t objtype:8; uintptr_t objsizew:8; uintptr_t objrefs:8; uintptr_t objheap:1; uintptr_t objcomps:1; uintptr_t objunused:64-8-8-8-1-1-16-3; uintptr_t objid:16+3; }; }; ifdef(debug,const char *objname;) }; } obj;
|
||||
typedef struct entity { struct { union { uintptr_t objheader; struct { uintptr_t objtype:8; uintptr_t objsizew:8; uintptr_t objrefs:8; uintptr_t objheap:1; uintptr_t objcomps:1; uintptr_t objunused:64-8-8-8-1-1-16-3; uintptr_t objid:16+3; }; }; union { struct { uintptr_t objenabled:32, objflagged:32; }; uintptr_t cflags; }; void *c[32]; }; } entity;
|
||||
typedef struct obj { struct { ifdef(debug, const char *objname;) union { uintptr_t objheader; struct { uintptr_t objtype:8; uintptr_t objsizew:8; uintptr_t objrefs:8; uintptr_t objheap:1; uintptr_t objcomps:1; uintptr_t objunused:64-8-8-8-1-1-16-3; uintptr_t objid:16+3; }; }; struct obj** objchildren; }; } obj;
|
||||
typedef struct entity { struct { struct { ifdef(debug, const char *objname;) union { uintptr_t objheader; struct { uintptr_t objtype:8; uintptr_t objsizew:8; uintptr_t objrefs:8; uintptr_t objheap:1; uintptr_t objcomps:1; uintptr_t objunused:64-8-8-8-1-1-16-3; uintptr_t objid:16+3; }; }; struct obj** objchildren; }; union { struct { uintptr_t objenabled:32, objflagged:32; }; uintptr_t cflags; }; void *c[32]; }; } entity;
|
||||
obj *objtmp;
|
||||
void* obj_malloc(unsigned sz);
|
||||
void* obj_free(void *o);
|
||||
|
@ -2559,16 +2560,16 @@ void* obj_free(void *o);
|
|||
obj* obj_loadmpack(void *o, const char *sav);
|
||||
int obj_push(const void *o);
|
||||
int obj_pop(void *o);
|
||||
bool obj_addcomponent(void *object, unsigned c, void *ptr);
|
||||
bool obj_hascomponent(void *object, unsigned c);
|
||||
void* obj_getcomponent(void *object, unsigned c);
|
||||
bool obj_delcomponent(void *object, unsigned c);
|
||||
bool obj_usecomponent(void *object, unsigned c);
|
||||
bool obj_offcomponent(void *object, unsigned c);
|
||||
bool obj_addcomponent(entity *e, unsigned c, void *ptr);
|
||||
bool obj_hascomponent(entity *e, unsigned c);
|
||||
void* obj_getcomponent(entity *e, unsigned c);
|
||||
bool obj_delcomponent(entity *e, unsigned c);
|
||||
bool obj_usecomponent(entity *e, unsigned c);
|
||||
bool obj_offcomponent(entity *e, unsigned c);
|
||||
char* entity_save(entity *self);
|
||||
void* obj_clone(const void *src);
|
||||
void* obj_merge(void *dst, const void *src);
|
||||
void* obj_mutate(void **dst, const void *src);
|
||||
void* obj_mutate(void *dst, const void *src);
|
||||
void* obj_make(const char *str);
|
||||
typedef enum OBJTYPE_BUILTINS {
|
||||
OBJTYPE_obj = 0,
|
||||
|
@ -3324,6 +3325,7 @@ PANEL_OPEN = 1,
|
|||
int ui_hover();
|
||||
int ui_active();
|
||||
int ui_demo(int do_windows);
|
||||
void *ui_handle();
|
||||
enum VIDEO_FLAGS {
|
||||
VIDEO_YCBCR = 0,
|
||||
VIDEO_RGB = 2,
|
||||
|
|
1058
engine/joint/v4k.h
1058
engine/joint/v4k.h
File diff suppressed because it is too large
Load Diff
|
@ -20995,6 +20995,9 @@ nk_nonblock_begin(struct nk_context *ctx,
|
|||
nk_flags flags, struct nk_rect body, struct nk_rect header,
|
||||
enum nk_panel_type panel_type)
|
||||
{
|
||||
if(body.x < 10) body.x = 0; //< @r-lyeh: popup snapping to the left
|
||||
if((body.x+body.w)>window_width()) body.x-=body.w-(window_width()-body.x); //< @r-lyeh: prevent popups to be printed outside of window client / right border
|
||||
|
||||
struct nk_window *popup;
|
||||
struct nk_window *win;
|
||||
struct nk_panel *panel;
|
||||
|
@ -21476,7 +21479,7 @@ nk_menu_begin(struct nk_context *ctx, struct nk_window *win,
|
|||
is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_MENU);
|
||||
if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
|
||||
(!is_open && !is_active && !is_clicked)) return 0;
|
||||
if (!nk_nonblock_begin(ctx, NK_WINDOW_NO_SCROLLBAR, body, header, NK_PANEL_MENU))
|
||||
if (!nk_nonblock_begin(ctx, NK_WINDOW_NO_SCROLLBAR_X/*|NK_WINDOW_NO_SCROLLBAR*/, body, header, NK_PANEL_MENU)) //< @r-lyeh: our popups are huge. enable Y scrollbars
|
||||
return 0;
|
||||
|
||||
win->popup.type = NK_PANEL_MENU;
|
||||
|
@ -22710,6 +22713,7 @@ nk_tree_state_base_(struct nk_context *ctx, enum nk_tree_type type,
|
|||
NK_INTERN int
|
||||
nk_tree_base_(struct nk_context *ctx, enum nk_tree_type type,
|
||||
struct nk_image *img, const char *title, enum nk_collapse_states initial_state,
|
||||
enum nk_collapse_states *forced_state, //< @r-lyeh
|
||||
const char *hash, int len, int line)
|
||||
{
|
||||
struct nk_window *win = ctx->current;
|
||||
|
@ -22727,7 +22731,8 @@ nk_tree_base_(struct nk_context *ctx, enum nk_tree_type type,
|
|||
state = nk_add_value(ctx, win, tree_hash, 0);
|
||||
*state = initial_state;
|
||||
}
|
||||
return nk_tree_state_base_(ctx, type, img, title, (enum nk_collapse_states*)state);
|
||||
return nk_tree_state_base_(ctx, type, img, title,
|
||||
forced_state ? forced_state : (enum nk_collapse_states*)state); //< @r-lyeh
|
||||
}
|
||||
#endif
|
||||
NK_API nk_bool
|
||||
|
|
|
@ -16,8 +16,56 @@
|
|||
#else
|
||||
#include <unistd.h> // getcwd()
|
||||
#include <pwd.h> // getpwuid()
|
||||
#define _popen popen
|
||||
#define _pclose pclose
|
||||
#endif
|
||||
|
||||
const char** old_file_list(const char *cwd, const char *masks) {
|
||||
ASSERT(strend(cwd, "/"), "Error: dirs like '%s' must end with slash", cwd);
|
||||
|
||||
static __thread array(char*) list = 0;
|
||||
const char *arg0 = cwd; // app_path();
|
||||
int larg0 = strlen(arg0);
|
||||
|
||||
for( int i = 0; i < array_count(list); ++i ) {
|
||||
FREE(list[i]);
|
||||
}
|
||||
array_resize(list, 0);//array_free(list);
|
||||
|
||||
for each_substring(masks,";",it) {
|
||||
int recurse = !!strstr(it, "**");
|
||||
#if is(win32)
|
||||
char *glob = va("dir %s/b/o:n \"%s\\%s\" 2> NUL", recurse ? "/s":"", cwd, it);
|
||||
#else // linux, osx
|
||||
char *glob = va("find %s %s -name \"%s\" | sort", cwd, !recurse ? "-maxdepth 1":"-type f", it);
|
||||
#endif
|
||||
for( FILE *in = _popen(glob, "r"); in; _pclose(in), in = 0) {
|
||||
char buf[1024], *line = buf;
|
||||
while( fgets(buf, sizeof(buf), in) ) {
|
||||
// clean up
|
||||
if( strstr(line, arg0) ) line = buf + larg0;
|
||||
if( !memcmp(line, "./", 2) ) line += 2;
|
||||
int len = strlen(line); while( len > 0 && line[len-1] < 32 ) line[--len] = 0;
|
||||
if( line[0] == '\0' ) continue;
|
||||
// do not insert system folders/files
|
||||
for(int i = 0; i < len; ++i ) if(line[i] == '\\') line[i] = '/';
|
||||
if( line[0] == '.' ) if( !strcmp(line,".git") || !strcmp(line,".vs") || !strcmp(line,".") || !strcmp(line,"..") ) continue;
|
||||
if( strstr(line, "/.") ) continue;
|
||||
// insert copy
|
||||
#if is(win32)
|
||||
char *copy = STRDUP(line); // full path already provided
|
||||
#else
|
||||
// while(line[0] == '/') ++line;
|
||||
char *copy = STRDUP(va("%s%s", cwd, line)); // need to prepend path
|
||||
#endif
|
||||
array_push(list, copy);
|
||||
}
|
||||
}
|
||||
}
|
||||
array_push(list, 0); // terminator
|
||||
return (const char**)list;
|
||||
}
|
||||
|
||||
#if 1
|
||||
#define BROWSER_PRINTF(...) do {} while(0)
|
||||
#else
|
||||
|
@ -81,6 +129,10 @@ struct browser {
|
|||
size_t file_count;
|
||||
size_t dir_count;
|
||||
|
||||
/* filtered directory content */
|
||||
array(char*) ffiles;
|
||||
array(char*) fdirectories;
|
||||
|
||||
/* view mode */
|
||||
bool listing;
|
||||
float zooming;
|
||||
|
@ -117,8 +169,8 @@ static void browser_reload_directory_content(struct browser *browser, const char
|
|||
|
||||
BROWSER_PRINTF("searching at %s\n", path);
|
||||
|
||||
array(char*) list = file_list(path);
|
||||
for( int i = 0, end = array_count(list); i < end; ++i ) {
|
||||
const char** list = old_file_list(path, "*");
|
||||
for( int i = 0; list[i]; ++i ) {
|
||||
|
||||
char *absolute = file_pathabs(ifndef(win32, list[i], va("%s/%s", path, list[i]))); // ../dir/./file.ext -> c:/prj/dir/file.ext
|
||||
BROWSER_PRINTF("%s->%s %d->", list[i], absolute, file_directory(absolute) );
|
||||
|
@ -183,6 +235,9 @@ static void browser_free(struct browser *browser) {
|
|||
for(int i = 0; i < array_count(browser->directories); ++i) FREE(browser->directories[i]);
|
||||
array_free(browser->files);
|
||||
array_free(browser->directories);
|
||||
array_free(browser->ffiles);
|
||||
array_free(browser->fdirectories);
|
||||
|
||||
memset(browser, 0, sizeof(*browser));
|
||||
}
|
||||
|
||||
|
@ -263,10 +318,33 @@ if( cols < 1 ) cols=1;
|
|||
|
||||
/* output directory content window */
|
||||
if(nk_group_begin(ctx, "Content", windowed ? NK_WINDOW_NO_SCROLLBAR : 0)) {
|
||||
|
||||
array(char*) *directories = &browser->directories;
|
||||
array(char*) *files = &browser->files;
|
||||
|
||||
if( ui_filter && ui_filter[0] ) {
|
||||
array_resize(browser->fdirectories, 0);
|
||||
array_resize(browser->ffiles, 0);
|
||||
|
||||
for each_array(browser->directories,char*,k)
|
||||
if( strstri(k, ui_filter) )
|
||||
array_push(browser->fdirectories, k);
|
||||
|
||||
for each_array(browser->files,char*,k)
|
||||
if( strstri(k, ui_filter) )
|
||||
array_push(browser->ffiles, k);
|
||||
|
||||
directories = &browser->fdirectories;
|
||||
files = &browser->ffiles;
|
||||
}
|
||||
|
||||
int dir_count = array_count(*directories);
|
||||
int file_count = array_count(*files);
|
||||
|
||||
int index = -1;
|
||||
size_t i = 0, j = 0, k = 0;
|
||||
size_t rows = 0;
|
||||
size_t count = browser->dir_count + browser->file_count;
|
||||
size_t count = dir_count + file_count;
|
||||
|
||||
rows = count / cols;
|
||||
for (i = 0; i <= rows; i += 1) {
|
||||
|
@ -274,16 +352,18 @@ if( cols < 1 ) cols=1;
|
|||
{size_t n = j + cols;
|
||||
nk_layout_row_dynamic(ctx, icon_height, (int)cols);
|
||||
for (; j < count && j < n; ++j) {
|
||||
size_t t = j-dir_count;
|
||||
|
||||
/* draw one row of icons */
|
||||
if (j < browser->dir_count) {
|
||||
if (j < dir_count) {
|
||||
/* draw and execute directory buttons */
|
||||
if (nk_button_image(ctx,media.custom_folders[BROWSER_FOLDER]))
|
||||
index = (int)j;
|
||||
} else {
|
||||
/* draw and execute files buttons */
|
||||
struct nk_image *icon;
|
||||
size_t fileIndex = ((size_t)j - browser->dir_count);
|
||||
icon = media_icon_for_file(browser->files[fileIndex]);
|
||||
size_t fileIndex = ((size_t)j - dir_count);
|
||||
icon = media_icon_for_file((*files)[fileIndex]);
|
||||
if (nk_button_image(ctx, *icon)) {
|
||||
snprintf(browser->file, BROWSER_MAX_PATH, "%s%s", browser->directory, browser->files[fileIndex]);
|
||||
clicked = 1;
|
||||
|
@ -294,30 +374,32 @@ if( cols < 1 ) cols=1;
|
|||
{size_t n = k + cols;
|
||||
nk_layout_row_dynamic(ctx, 20, (int)cols);
|
||||
for (; k < count && k < n; k++) {
|
||||
size_t t = k-dir_count;
|
||||
|
||||
/* draw one row of labels */
|
||||
if (k < browser->dir_count) {
|
||||
nk_label(ctx, browser->directories[k], NK_TEXT_CENTERED);
|
||||
if (k < dir_count) {
|
||||
nk_label(ctx, (*directories)[k], NK_TEXT_CENTERED);
|
||||
} else {
|
||||
size_t t = k-browser->dir_count;
|
||||
nk_label(ctx,browser->files[t],NK_TEXT_CENTERED);
|
||||
nk_label(ctx, (*files)[t], NK_TEXT_CENTERED);
|
||||
}
|
||||
}}
|
||||
if(tiny)
|
||||
{size_t n = j + cols;
|
||||
nk_layout_row_dynamic(ctx, icon_height, (int)cols);
|
||||
for (; j < count && j < n; ++j) {
|
||||
size_t t = j-dir_count;
|
||||
|
||||
/* draw one row of icons */
|
||||
if (j < browser->dir_count) {
|
||||
if (j < dir_count) {
|
||||
/* draw and execute directory buttons */
|
||||
if (nk_button_image_label(ctx,media.custom_folders[BROWSER_FOLDER], browser->directories[j],NK_TEXT_RIGHT))
|
||||
if (nk_button_image_label(ctx,media.custom_folders[BROWSER_FOLDER], (*directories)[j], NK_TEXT_RIGHT))
|
||||
index = (int)j;
|
||||
} else {
|
||||
/* draw and execute files buttons */
|
||||
struct nk_image *icon;
|
||||
size_t fileIndex = ((size_t)j - browser->dir_count);
|
||||
icon = media_icon_for_file(browser->files[fileIndex]);
|
||||
size_t t = j-browser->dir_count;
|
||||
if (nk_button_image_label(ctx, *icon, browser->files[t],NK_TEXT_RIGHT)) {
|
||||
size_t fileIndex = ((size_t)j - dir_count);
|
||||
icon = media_icon_for_file((*files)[fileIndex]);
|
||||
if (nk_button_image_label(ctx, *icon, (*files)[t],NK_TEXT_RIGHT)) {
|
||||
snprintf(browser->file, BROWSER_MAX_PATH, "%s%s", browser->directory, browser->files[fileIndex]);
|
||||
clicked = 1;
|
||||
}
|
||||
|
@ -329,7 +411,7 @@ if( cols < 1 ) cols=1;
|
|||
struct nk_rect bounds = nk_widget_bounds(ctx);
|
||||
if (nk_input_is_mouse_hovering_rect(&ctx->input, bounds) ) {
|
||||
|
||||
char *name = j < browser->dir_count ? browser->directories[j] : browser->files[j-browser->dir_count];
|
||||
char *name = j < dir_count ? (*directories)[j] : (*files)[j-dir_count];
|
||||
|
||||
char fullpath[PATH_MAX];
|
||||
snprintf(fullpath, PATH_MAX, "%s%s", browser->directory, name);
|
||||
|
|
|
@ -27,7 +27,20 @@
|
|||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* ------------------------------------------------------------------------------
|
||||
* ALTERNATIVE B - MIT-0 (No Attribution clause)
|
||||
* ALTERNATIVE B - 0-BSD License (https://opensource.org/licenses/FPL-1.0.0)
|
||||
* ------------------------------------------------------------------------------
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
* ------------------------------------------------------------------------------
|
||||
* ALTERNATIVE C - MIT-0 (No Attribution clause)
|
||||
* ------------------------------------------------------------------------------
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
* software and associated documentation files (the "Software"), to deal in the Software
|
||||
|
@ -41,19 +54,6 @@
|
|||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* ------------------------------------------------------------------------------
|
||||
* ALTERNATIVE C - Zero BSD License (https://opensource.org/licenses/FPL-1.0.0)
|
||||
* ------------------------------------------------------------------------------
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ## License: Contributed Code ------------------------------------------------
|
||||
*
|
||||
|
@ -73,7 +73,7 @@
|
|||
* --
|
||||
*
|
||||
* "I dedicate any and all copyright interest in this software to the three
|
||||
* license terms listed above. I make this dedication for the benefit of the
|
||||
* licensing terms listed above. I make this dedication for the benefit of the
|
||||
* public at large and to the detriment of my heirs and successors. I intend
|
||||
* this dedication to be an overt act of relinquishment in perpetuity of all
|
||||
* present and future rights to this software under copyright law."
|
||||
|
@ -113,6 +113,8 @@ API void *ui_handle();
|
|||
//-----------------------------------------------------------------------------
|
||||
// C files
|
||||
|
||||
{{FILE:v4k_begin.c}}
|
||||
|
||||
{{FILE:v4k_ds.c}}
|
||||
|
||||
{{FILE:v4k_string.c}}
|
||||
|
|
|
@ -27,7 +27,20 @@
|
|||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* ------------------------------------------------------------------------------
|
||||
* ALTERNATIVE B - MIT-0 (No Attribution clause)
|
||||
* ALTERNATIVE B - 0-BSD License (https://opensource.org/licenses/FPL-1.0.0)
|
||||
* ------------------------------------------------------------------------------
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
* ------------------------------------------------------------------------------
|
||||
* ALTERNATIVE C - MIT-0 (No Attribution clause)
|
||||
* ------------------------------------------------------------------------------
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
* software and associated documentation files (the "Software"), to deal in the Software
|
||||
|
@ -41,19 +54,6 @@
|
|||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* ------------------------------------------------------------------------------
|
||||
* ALTERNATIVE C - Zero BSD License (https://opensource.org/licenses/FPL-1.0.0)
|
||||
* ------------------------------------------------------------------------------
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ## License: Contributed Code ------------------------------------------------
|
||||
*
|
||||
|
@ -73,7 +73,7 @@
|
|||
* --
|
||||
*
|
||||
* "I dedicate any and all copyright interest in this software to the three
|
||||
* license terms listed above. I make this dedication for the benefit of the
|
||||
* licensing terms listed above. I make this dedication for the benefit of the
|
||||
* public at large and to the detriment of my heirs and successors. I intend
|
||||
* this dedication to be an overt act of relinquishment in perpetuity of all
|
||||
* present and future rights to this software under copyright law."
|
||||
|
|
|
@ -136,6 +136,7 @@ errno_t fopen_s(
|
|||
#define NK_DTOA(s,n) strcpy(s, va("%f", n)) // override cos built-in nk_dtoa() will freeze while parsing UINT_MAX otherwise
|
||||
{{FILE:3rd_nuklear.h}}
|
||||
{{FILE:3rd_nuklear_glfw_gl3.h}}
|
||||
static char *ui_filter = 0;
|
||||
{{FILE:3rd_nuklear_filebrowser.h}}
|
||||
//---
|
||||
#ifdef ENABLE_ASSIMP
|
||||
|
|
|
@ -15,7 +15,7 @@ vec3 rnd3() { // random uniform
|
|||
int less3(vec3 *lhs, vec3 *rhs) {
|
||||
if(lhs->x != rhs->x) return lhs->x - rhs->x;
|
||||
if(lhs->y != rhs->y) return lhs->y - rhs->y;
|
||||
if(lhs->z != rhs->z) return lhs->z - rhs->z;
|
||||
if(lhs->z != rhs->z) return lhs->z - rhs->z; // @testme: remove superfluous if check
|
||||
return 0;
|
||||
}
|
||||
uint64_t hash3(vec3 *v) {
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
#define do_threadlock(mutexptr) \
|
||||
for( int init_ = !!(mutexptr) || (thread_mutex_init( (mutexptr) = CALLOC(1, sizeof(thread_mutex_t)) ), 1); init_; init_ = 0) \
|
||||
for( int lock_ = (thread_mutex_lock( mutexptr ), 1); lock_; lock_ = (thread_mutex_unlock( mutexptr ), 0) )
|
|
@ -227,6 +227,8 @@
|
|||
#define VA_SELECT_10TH(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, ...) A10
|
||||
// VA_SPLIT() expands to A) 1 item OR B) 1 item + ',' + va_args[1..N]
|
||||
#define VA_SPLIT(...) VA_FIRST(__VA_ARGS__) VA_REST(__VA_ARGS__)
|
||||
// VA_COUNT() counts number of va args
|
||||
#define VA_COUNT(...) (int)(sizeof((int[]){0, ##__VA_ARGS__})/sizeof(int)-1)
|
||||
|
||||
#if is(cl) && !is(cpp)
|
||||
#define INLINE __inline
|
||||
|
|
|
@ -191,6 +191,235 @@ int engine_tick() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ui_debug() {
|
||||
static int time_factor = 0;
|
||||
static int playing = 0;
|
||||
static int paused = 0;
|
||||
int advance_frame = 0;
|
||||
|
||||
#if 0
|
||||
static int do_filter = 0;
|
||||
static int do_profile = 0;
|
||||
static int do_extra = 0;
|
||||
|
||||
char *EDITOR_TOOLBAR_ICONS = va("%s;%s;%s;%s;%s;%s;%s;%s",
|
||||
do_filter ? ICON_MD_CLOSE : ICON_MD_SEARCH,
|
||||
ICON_MD_PLAY_ARROW,
|
||||
paused ? ICON_MD_SKIP_NEXT : ICON_MD_PAUSE,
|
||||
ICON_MD_FAST_FORWARD,
|
||||
ICON_MD_STOP,
|
||||
ICON_MD_REPLAY,
|
||||
ICON_MD_FACE,
|
||||
ICON_MD_MENU
|
||||
);
|
||||
|
||||
if( input_down(KEY_F) ) if( input(KEY_LCTRL) || input(KEY_RCTRL) ) do_filter ^= 1;
|
||||
int choice = ui_toolbar(EDITOR_TOOLBAR_ICONS);
|
||||
if( choice == 1 ) do_filter ^= 1, do_profile = 0, do_extra = 0;
|
||||
if( choice == 2 ) playing = 1, paused = 0;
|
||||
if( choice == 3 ) advance_frame = !!paused, paused = 1;
|
||||
if( choice == 4 ) paused = 0, time_factor = (++time_factor) % 4;
|
||||
if( choice == 5 ) playing = 0, paused = 0, advance_frame = 0, time_factor = 0;
|
||||
if( choice == 6 ) window_reload();
|
||||
if( choice == 7 ) do_filter = 0, do_profile ^= 1, do_extra = 0;
|
||||
if( choice == 8 ) do_filter = 0, do_profile = 0, do_extra ^= 1;
|
||||
|
||||
if( do_filter ) {
|
||||
char *bak = ui_filter; ui_filter = 0;
|
||||
ui_string(ICON_MD_CLOSE " Filter " ICON_MD_SEARCH, &bak);
|
||||
ui_filter = bak;
|
||||
if( ui_label_icon_clicked_L.x > 0 && ui_label_icon_clicked_L.x <= 24 ) { // if clicked on CANCEL icon (1st icon)
|
||||
do_filter = 0;
|
||||
}
|
||||
} else {
|
||||
if( ui_filter ) ui_filter[0] = '\0';
|
||||
}
|
||||
char *filter_mask = ui_filter && ui_filter[0] ? va("*%s*", ui_filter) : "*";
|
||||
|
||||
static char *username = 0;
|
||||
static char *userpass = 0;
|
||||
if( do_profile ) {
|
||||
ui_string(ICON_MD_FACE " Username", &username);
|
||||
ui_string(ICON_MD_FACE " Password", &userpass);
|
||||
}
|
||||
|
||||
if( do_extra ) {
|
||||
int choice2 = ui_label2_toolbar(NULL,
|
||||
ICON_MD_VIEW_IN_AR
|
||||
ICON_MD_MESSAGE
|
||||
ICON_MD_TIPS_AND_UPDATES ICON_MD_LIGHTBULB ICON_MD_LIGHTBULB_OUTLINE
|
||||
ICON_MD_IMAGE_SEARCH ICON_MD_INSERT_PHOTO
|
||||
ICON_MD_VIDEOGAME_ASSET ICON_MD_VIDEOGAME_ASSET_OFF
|
||||
|
||||
ICON_MD_VOLUME_UP ICON_MD_VOLUME_OFF // audio_volume_master(-1) > 0
|
||||
|
||||
ICON_MD_TROUBLESHOOT ICON_MD_SCHEMA ICON_MD_MENU
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
int open = 0, clicked_or_toggled = 0;
|
||||
|
||||
|
||||
#define EDITOR_UI_COLLAPSE(f,...) \
|
||||
for( int macro(p) = (open = ui_collapse(f,__VA_ARGS__)), macro(dummy) = (clicked_or_toggled = ui_collapse_clicked()); macro(p); ui_collapse_end(), macro(p) = 0)
|
||||
|
||||
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_BUG_REPORT " Bugs 0", "Debug.Bugs") {
|
||||
// @todo. parse /bugs.ini, includes saved screenshots & videos.
|
||||
// @todo. screenshot include parseable level, position screen markers (same info as /bugs.ini)
|
||||
}
|
||||
|
||||
|
||||
// Art and bookmarks
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_FOLDER_SPECIAL " Art", "Debug.Art") {
|
||||
bool inlined = true;
|
||||
const char *file = 0;
|
||||
if( ui_browse(&file, &inlined) ) {
|
||||
const char *sep = ifdef(win32, "\"", "'");
|
||||
app_exec(va("%s %s%s%s", ifdef(win32, "start \"\"", ifdef(osx, "open", "xdg-open")), sep, file, sep));
|
||||
}
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_BOOKMARK " Bookmarks", "Debug.Bookmarks") { /* @todo */ }
|
||||
|
||||
|
||||
// E,C,S,W
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_ACCOUNT_TREE " Scene", "Debug.Scene") {
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_BUBBLE_CHART/*ICON_MD_SCATTER_PLOT*/ " Entities", "Debug.Entities") { /* @todo */ }
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_TUNE " Components", "Debug.Components") { /* @todo */ }
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_PRECISION_MANUFACTURING " Systems", "Debug.Systems") { /* @todo */ }
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_PUBLIC " Levels", "Debug.Levels") {
|
||||
//node_edit(editor.edit.down,&editor.edit);
|
||||
}
|
||||
|
||||
//EDITOR_UI_COLLAPSE(ICON_MD_ACCOUNT_TREE " Init", "Debug.HierarchyInit") { /* @todo */ }
|
||||
//EDITOR_UI_COLLAPSE(ICON_MD_ACCOUNT_TREE " Draw", "Debug.HierarchyDraw") { /* @todo */ }
|
||||
//EDITOR_UI_COLLAPSE(ICON_MD_ACCOUNT_TREE " Tick", "Debug.HierarchyTick") { /* @todo */ }
|
||||
//EDITOR_UI_COLLAPSE(ICON_MD_ACCOUNT_TREE " Edit", "Debug.HierarchyEdit") { /* @todo */ }
|
||||
//EDITOR_UI_COLLAPSE(ICON_MD_ACCOUNT_TREE " Quit", "Debug.HierarchyQuit") { /* @todo */ }
|
||||
|
||||
// node_edit(&editor.init,&editor.init);
|
||||
// node_edit(&editor.draw,&editor.draw);
|
||||
// node_edit(&editor.tick,&editor.tick);
|
||||
// node_edit(&editor.edit,&editor.edit);
|
||||
// node_edit(&editor.quit,&editor.quit);
|
||||
}
|
||||
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_ROCKET_LAUNCH " AI", "Debug.AI") {
|
||||
// @todo
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_VOLUME_UP " Audio", "Debug.Audio") {
|
||||
ui_audio();
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_VIDEOCAM " Camera", "Debug.Camera") {
|
||||
ui_camera( camera_get_active() );
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_MONITOR " Display", "Debug.Display") {
|
||||
// @todo: fps lock, fps target, aspect ratio, fullscreen
|
||||
char *text = va("%s;%s;%s",
|
||||
window_has_fullscreen() ? ICON_MD_FULLSCREEN_EXIT : ICON_MD_FULLSCREEN,
|
||||
ICON_MD_PHOTO_CAMERA,
|
||||
record_active() ? ICON_MD_VIDEOCAM_OFF : ICON_MD_VIDEOCAM
|
||||
);
|
||||
|
||||
int choice = ui_toolbar(text);
|
||||
if( choice == 1 ) engine_send("key_fullscreen",0);
|
||||
if( choice == 2 ) engine_send("key_screenshot",0);
|
||||
if( choice == 3 ) engine_send("key_record",0);
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_KEYBOARD " Keyboard", "Debug.Keyboard") {
|
||||
ui_keyboard();
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_MOUSE " Mouse", "Debug.Mouse") {
|
||||
ui_mouse();
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_GAMEPAD " Gamepads", "Debug.Gamepads") {
|
||||
for( int q = 0; q < 4; ++q ) {
|
||||
for( int r = (open = ui_collapse(va("Gamepad #%d",q+1), va("Debug.Gamepads%d",q))), dummy = (clicked_or_toggled = ui_collapse_clicked()); r; ui_collapse_end(), r = 0) {
|
||||
ui_gamepad(q);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_CONTENT_PASTE " Scripts", "Debug.Scripts") {
|
||||
// @todo
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_STAR_HALF " Shaders", "Debug.Shaders") {
|
||||
ui_shaders();
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_MOVIE " FXs", "Debug.FXs") {
|
||||
ui_fxs();
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_VIEW_QUILT " UI", "Debug.UI") {
|
||||
int choice = ui_toolbar(ICON_MD_RECYCLING " Reset layout;" ICON_MD_SAVE_AS " Save layout");
|
||||
if( choice == 1 ) ui_layout_all_reset("*");
|
||||
if( choice == 2 ) file_delete(WINDOWS_INI), ui_layout_all_save_disk("*");
|
||||
|
||||
for each_map_ptr_sorted(ui_windows, char*, k, unsigned, v) {
|
||||
bool visible = ui_visible(*k);
|
||||
if( ui_bool( *k, &visible ) ) {
|
||||
ui_show( *k, ui_visible(*k) ^ true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_SAVINGS " Budgets", "Debug.Budgets") {
|
||||
// @todo. // mem,fps,gfx,net,hdd,... also logging
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_WIFI/*ICON_MD_SIGNAL_CELLULAR_ALT*/ " Network 0/0 KiB", "Debug.Network") {
|
||||
// @todo
|
||||
// SIGNAL_CELLULAR_1_BAR SIGNAL_CELLULAR_2_BAR
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(va(ICON_MD_SPEED " Profiler %5.2f/%dfps", window_fps(), (int)window_fps_target()), "Debug.Profiler") {
|
||||
ui_profiler();
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(va(ICON_MD_STORAGE " Storage %s", xstats()), "Debug.Storage") {
|
||||
// @todo
|
||||
}
|
||||
|
||||
|
||||
|
||||
// logic: either plug icon (power saving off) or one of the following ones (power saving on):
|
||||
// if 0% batt (no batt): battery alert
|
||||
// if discharging: battery levels [alert,0..6,full]
|
||||
// if charging: battery charging
|
||||
int battery_read = app_battery();
|
||||
int battery_level = abs(battery_read);
|
||||
int battery_discharging = battery_read < 0 && battery_level < 100;
|
||||
const char *power_icon_label = ICON_MD_POWER " Power";
|
||||
if( battery_level ) {
|
||||
const char *battery_levels[9] = { // @todo: remap [7%..100%] -> [0..1] ?
|
||||
ICON_MD_BATTERY_ALERT,ICON_MD_BATTERY_0_BAR,ICON_MD_BATTERY_1_BAR,
|
||||
ICON_MD_BATTERY_2_BAR,ICON_MD_BATTERY_3_BAR,ICON_MD_BATTERY_4_BAR,
|
||||
ICON_MD_BATTERY_5_BAR,ICON_MD_BATTERY_6_BAR,ICON_MD_BATTERY_FULL,
|
||||
};
|
||||
power_icon_label = (const char*)va("%s Power %d%%",
|
||||
battery_discharging ? battery_levels[(int)((9-1)*clampf(battery_level/100.f,0,1))] : ICON_MD_BATTERY_CHARGING_FULL,
|
||||
battery_level);
|
||||
}
|
||||
|
||||
EDITOR_UI_COLLAPSE(power_icon_label, "Debug.Power") {
|
||||
int choice = ui_toolbar( ICON_MD_POWER ";" ICON_MD_BOLT );
|
||||
if( choice == 1 ) engine_send("key_battery","0");
|
||||
if( choice == 2 ) engine_send("key_battery","1");
|
||||
}
|
||||
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_WATER " Reflection", "Debug.Reflect") {
|
||||
ui_reflect("*");
|
||||
}
|
||||
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_EXTENSION " Plugins", "Debug.Plugins") {
|
||||
// @todo. include VCS
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_BUILD " Cook", "Debug.Cook") {
|
||||
// @todo
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gizmo__mode;
|
||||
static int gizmo__active;
|
||||
static int gizmo__hover;
|
||||
|
|
|
@ -14,6 +14,8 @@ API int* engine_geti(const char *key);
|
|||
API char** engine_gets(const char *key);
|
||||
API int engine_send(const char *cmd, const char *optional_value);
|
||||
|
||||
API int ui_debug();
|
||||
|
||||
// open file dialog
|
||||
|
||||
API char* dialog_load();
|
||||
|
|
|
@ -159,13 +159,13 @@ void *obj_unref(void *oo) {
|
|||
// scene tree
|
||||
|
||||
array(obj*)* obj_children(const void *o) {
|
||||
array(obj*) *c = obj_payload(o);
|
||||
array(obj*) *c = &((obj*)o)->objchildren;
|
||||
if(!(*c)) array_push((*c), NULL); // default parenting: none. @todo: optimize & move this at construction time
|
||||
return c;
|
||||
}
|
||||
obj* obj_parent(const void *o) {
|
||||
array(obj*) *c = obj_children(o);
|
||||
return (*c) ? 0[*c] : NULL;
|
||||
return 0[*c]; // (*c) ? 0[*c] : NULL;
|
||||
}
|
||||
obj* obj_root(const void *o) {
|
||||
while( obj_parent(o) ) o = obj_parent(o);
|
||||
|
@ -697,33 +697,27 @@ void test_obj_serialization(void *o1, void *o2) {
|
|||
// ----------------------------------------------------------------------------
|
||||
// components
|
||||
|
||||
bool obj_addcomponent(void *object, unsigned c, void *ptr) {
|
||||
entity *e = (entity*)object;
|
||||
bool obj_addcomponent(entity *e, unsigned c, void *ptr) {
|
||||
e->cflags |= (3ULL << c);
|
||||
e->c[c & (OBJCOMPONENTS_MAX-1)] = ptr;
|
||||
return 1;
|
||||
}
|
||||
bool obj_hascomponent(void *object, unsigned c) {
|
||||
entity *e = (entity*)object;
|
||||
bool obj_hascomponent(entity *e, unsigned c) {
|
||||
return !!(e->cflags & (3ULL << c));
|
||||
}
|
||||
void* obj_getcomponent(void *object, unsigned c) {
|
||||
entity *e = (entity*)object;
|
||||
void* obj_getcomponent(entity *e, unsigned c) {
|
||||
return e->c[c & (OBJCOMPONENTS_MAX-1)];
|
||||
}
|
||||
bool obj_delcomponent(void *object, unsigned c) {
|
||||
entity *e = (entity*)object;
|
||||
bool obj_delcomponent(entity *e, unsigned c) {
|
||||
e->cflags &= ~(3ULL << c);
|
||||
e->c[c & (OBJCOMPONENTS_MAX-1)] = NULL;
|
||||
return 1;
|
||||
}
|
||||
bool obj_usecomponent(void *object, unsigned c) {
|
||||
entity *e = (entity*)object;
|
||||
bool obj_usecomponent(entity *e, unsigned c) {
|
||||
e->cflags |= (1ULL << c);
|
||||
return 1;
|
||||
}
|
||||
bool obj_offcomponent(void *object, unsigned c) {
|
||||
entity *e = (entity*)object;
|
||||
bool obj_offcomponent(entity *e, unsigned c) {
|
||||
e->cflags &= ~(1ULL << c);
|
||||
return 0;
|
||||
}
|
||||
|
@ -733,17 +727,23 @@ char *entity_save(entity *self) {
|
|||
return sav;
|
||||
}
|
||||
|
||||
AUTORUN {
|
||||
static
|
||||
void entity_register() {
|
||||
do_once {
|
||||
STRUCT(entity, uintptr_t, cflags);
|
||||
|
||||
// struct { OBJHEADER union { struct { uintptr_t objenabled : 32, objflagged : 32; }; uintptr_t cflags; }; void* c[32]; };
|
||||
|
||||
obj_extend(entity, save);
|
||||
}
|
||||
}
|
||||
|
||||
AUTORUN{
|
||||
entity_register();
|
||||
}
|
||||
|
||||
static
|
||||
void test_obj_ecs() {
|
||||
entity *e = obj_new(entity);
|
||||
entity_register(); // why is this required here? autorun init fiasco?
|
||||
|
||||
entity *e = entity_new(entity);
|
||||
puts(obj_save(e));
|
||||
|
||||
for( int i = 0; i < 32; ++i) test(0 == obj_hascomponent(e, i));
|
||||
|
@ -756,27 +756,14 @@ void test_obj_ecs() {
|
|||
// ----------------------------------------------------------------------------
|
||||
// reflection
|
||||
|
||||
void *obj_clone(const void *src) {
|
||||
obj *ptr = obj_malloc( sizeof(obj) + obj_size(src) + sizeof(array(obj*)) );
|
||||
ptr->objheader = ((const obj *)src)->objheader;
|
||||
obj_loadini(ptr, obj_saveini(src));
|
||||
return ptr;
|
||||
}
|
||||
void* obj_mutate(void *dst, const void *src) {
|
||||
((obj*)dst)->objheader = ((const obj *)src)->objheader;
|
||||
|
||||
void* obj_merge(void *dst, const void *src) { // @testme
|
||||
char *bin = obj_savebin(src);
|
||||
return obj_mergebin(dst, bin);
|
||||
}
|
||||
|
||||
void* obj_mutate(void **dst, const void *src) {
|
||||
#if 0
|
||||
// mutate a class. ie, convert a given object class into a different one,
|
||||
// while preserving the original metas, components and references as much as possible.
|
||||
// @todo iterate per field
|
||||
|
||||
if(!*dst_) return *dst_ = obj_clone(src);
|
||||
|
||||
void *dst = *dst_;
|
||||
dtor(dst);
|
||||
|
||||
unsigned src_sz = obj_sizeof(src);
|
||||
|
@ -798,6 +785,20 @@ void* obj_mutate(void **dst, const void *src) {
|
|||
return dst;
|
||||
}
|
||||
|
||||
void *obj_clone(const void *src) {
|
||||
int sz = sizeof(obj) + obj_size(src) + sizeof(array(obj*));
|
||||
enum { N = 8 }; sz = ((sz + (N - 1)) & -N); // Round up to N-byte boundary
|
||||
obj *ptr = obj_malloc( sz );
|
||||
obj_mutate(ptr, src); // ptr->objheader = ((const obj *)src)->objheader;
|
||||
obj_loadini(ptr, obj_saveini(src));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* obj_merge(void *dst, const void *src) { // @testme
|
||||
char *bin = obj_savebin(src);
|
||||
return obj_mergebin(dst, bin);
|
||||
}
|
||||
|
||||
void *obj_make(const char *str) {
|
||||
const char *T;
|
||||
const char *I = strchr(str, '['); // is_ini
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#endif
|
||||
|
||||
#define OBJHEADER \
|
||||
struct { \
|
||||
ifdef(debug, const char *objname;) \
|
||||
union { \
|
||||
uintptr_t objheader; \
|
||||
struct { \
|
||||
|
@ -31,10 +33,12 @@
|
|||
uintptr_t objunused:64-8-8-8-1-1-ID_INDEX_BITS-ID_COUNT_BITS; /*19*/ \
|
||||
uintptr_t objid:ID_INDEX_BITS+ID_COUNT_BITS; /*16+3*/ \
|
||||
}; \
|
||||
}; \
|
||||
array(struct obj*) objchildren; \
|
||||
};
|
||||
|
||||
#define OBJ \
|
||||
struct { OBJHEADER ifdef(debug,const char *objname;) };
|
||||
OBJHEADER
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// syntax sugars
|
||||
|
@ -83,6 +87,9 @@
|
|||
// OBJTYPEDEF(entity,1)
|
||||
typedef struct entity { ENTITY } entity;
|
||||
|
||||
#define entity_new(TYPE, ...) OBJ_CTOR(TYPE, #TYPE, 1, 0, __VA_ARGS__)
|
||||
#define entity_new_ext(TYPE, NAME, ...) OBJ_CTOR(TYPE, NAME, 1, 0, __VA_ARGS__)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// heap/stack ctor/dtor
|
||||
|
||||
|
@ -97,16 +104,16 @@ static __thread obj *objtmp;
|
|||
obj_ctor(PTR))
|
||||
#define OBJ_CTOR(TYPE, NAME, HEAP, PAYLOAD_SIZE, ...) (TYPE*)( \
|
||||
objtmp = (HEAP ? MALLOC(sizeof(TYPE)+(PAYLOAD_SIZE)) : ALLOCA(sizeof(TYPE)+(PAYLOAD_SIZE))), \
|
||||
*(TYPE*)objtmp = ((TYPE){ {0}, __VA_ARGS__}), \
|
||||
*(TYPE*)objtmp = ((TYPE){ {0,}, __VA_ARGS__}), \
|
||||
((PAYLOAD_SIZE) ? memset((char*)objtmp + sizeof(TYPE), 0, (PAYLOAD_SIZE)) : objtmp), \
|
||||
( OBJTYPES[ OBJTYPE(TYPE) ] = #TYPE ), \
|
||||
OBJ_CTOR_PTR(objtmp, HEAP,sizeof(TYPE),OBJTYPE(TYPE)), \
|
||||
ifdef(debug, (obj_printf)(objtmp, va("%s", callstack(+16))), 0), \
|
||||
obj_setname(objtmp, NAME))
|
||||
|
||||
#define obj(TYPE, ...) *OBJ_CTOR(TYPE, #TYPE, 0, sizeof(array(obj*)), __VA_ARGS__)
|
||||
#define obj_new(TYPE, ...) OBJ_CTOR(TYPE, #TYPE, 1, sizeof(array(obj*)), __VA_ARGS__)
|
||||
#define obj_new_ext(TYPE, NAME, ...) OBJ_CTOR(TYPE, NAME, 1, sizeof(array(obj*)), __VA_ARGS__)
|
||||
#define obj(TYPE, ...) *OBJ_CTOR(TYPE, #TYPE, 0, 0, __VA_ARGS__)
|
||||
#define obj_new(TYPE, ...) OBJ_CTOR(TYPE, #TYPE, 1, 0, __VA_ARGS__)
|
||||
#define obj_new_ext(TYPE, NAME, ...) OBJ_CTOR(TYPE, NAME, 1, 0, __VA_ARGS__)
|
||||
|
||||
void* obj_malloc(unsigned sz);
|
||||
void* obj_free(void *o);
|
||||
|
@ -261,12 +268,12 @@ API int obj_pop(void *o);
|
|||
// ----------------------------------------------------------------------------
|
||||
// components
|
||||
|
||||
API bool obj_addcomponent(void *object, unsigned c, void *ptr);
|
||||
API bool obj_hascomponent(void *object, unsigned c);
|
||||
API void* obj_getcomponent(void *object, unsigned c);
|
||||
API bool obj_delcomponent(void *object, unsigned c);
|
||||
API bool obj_usecomponent(void *object, unsigned c);
|
||||
API bool obj_offcomponent(void *object, unsigned c);
|
||||
API bool obj_addcomponent(entity *e, unsigned c, void *ptr);
|
||||
API bool obj_hascomponent(entity *e, unsigned c);
|
||||
API void* obj_getcomponent(entity *e, unsigned c);
|
||||
API bool obj_delcomponent(entity *e, unsigned c);
|
||||
API bool obj_usecomponent(entity *e, unsigned c);
|
||||
API bool obj_offcomponent(entity *e, unsigned c);
|
||||
|
||||
API char* entity_save(entity *self);
|
||||
|
||||
|
@ -282,7 +289,7 @@ API char* entity_save(entity *self);
|
|||
|
||||
API void* obj_clone(const void *src);
|
||||
API void* obj_merge(void *dst, const void *src); // @testme
|
||||
API void* obj_mutate(void **dst, const void *src);
|
||||
API void* obj_mutate(void *dst, const void *src);
|
||||
API void* obj_make(const char *str);
|
||||
|
||||
// built-ins
|
||||
|
|
|
@ -9,6 +9,7 @@ static map(unsigned, array(reflect_t)) members;
|
|||
|
||||
void reflect_init() {
|
||||
if(!reflects) map_init_int(reflects);
|
||||
if(!members) map_init_int(members);
|
||||
}
|
||||
AUTORUN {
|
||||
reflect_init();
|
||||
|
@ -96,7 +97,7 @@ void ui_reflect_(const reflect_t *R, const char *filter, int mask) {
|
|||
if( buf ) *buf = '\0';
|
||||
|
||||
struct nk_context *ui_ctx = (struct nk_context *)ui_handle();
|
||||
for ui_push_hspace(16) {
|
||||
/*for ui_push_hspace(16)*/ {
|
||||
array(reflect_t) *T = map_find(members, intern(R->name));
|
||||
/**/ if( T ) {ui_label(strcatf(&buf,"S struct %s@%s", R->name, R->info+1)); for each_array_ptr(*T, reflect_t, it) if(strmatchi(it->name,filter)) ui_reflect_(it,filter,'M'); }
|
||||
else if( R->addr ) ui_label(strcatf(&buf,"F func %s()@%s", R->name, R->info+1));
|
||||
|
|
|
@ -1,3 +1,121 @@
|
|||
// ----------------------------------------------------------------------------------------
|
||||
// ui extensions first
|
||||
|
||||
static float
|
||||
nk_text_width(struct nk_context *ctx, const char *str, unsigned len) {
|
||||
const struct nk_style *style = &ctx->style;
|
||||
const struct nk_user_font *f = style->font;
|
||||
float pixels_width = f->width(f->userdata, f->height, str, len ? (int)len : (int)strlen(str));
|
||||
return pixels_width;
|
||||
}
|
||||
|
||||
static nk_bool
|
||||
nk_hovered_text(struct nk_context *ctx, const char *str, int len,
|
||||
nk_flags align, nk_bool value)
|
||||
{
|
||||
struct nk_window *win;
|
||||
struct nk_panel *layout;
|
||||
const struct nk_input *in;
|
||||
const struct nk_style *style;
|
||||
|
||||
enum nk_widget_layout_states state;
|
||||
struct nk_rect bounds;
|
||||
|
||||
NK_ASSERT(ctx);
|
||||
NK_ASSERT(ctx->current);
|
||||
NK_ASSERT(ctx->current->layout);
|
||||
if (!ctx || !ctx->current || !ctx->current->layout)
|
||||
return 0;
|
||||
|
||||
win = ctx->current;
|
||||
layout = win->layout;
|
||||
style = &ctx->style;
|
||||
|
||||
state = nk_widget(&bounds, ctx);
|
||||
if (!state) return 0;
|
||||
in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
|
||||
|
||||
#if 1 //< @r-lyeh: sim button logic
|
||||
struct nk_rect touch;
|
||||
touch.x = bounds.x - style->selectable.touch_padding.x;
|
||||
touch.y = bounds.y - style->selectable.touch_padding.y;
|
||||
touch.w = bounds.w + style->selectable.touch_padding.x * 2;
|
||||
touch.h = bounds.h + style->selectable.touch_padding.y * 2;
|
||||
int clicked = !!nk_button_behavior(&ctx->last_widget_state, touch, in, NK_BUTTON_DEFAULT);
|
||||
in = 0; //< @r-lyeh: do not pass any input
|
||||
#endif
|
||||
|
||||
nk_do_selectable(&ctx->last_widget_state, &win->buffer, bounds,
|
||||
str, len, align, &value, &style->selectable, in, style->font);
|
||||
|
||||
return clicked; //< @r-lyeh: return sim button logic instead of prev function call
|
||||
}
|
||||
|
||||
#define ui_push_hspace(px) \
|
||||
(int xx = px; xx; xx = 0) \
|
||||
for(struct nk_context *ctx = (struct nk_context*)ui_handle(); ctx; ctx = 0 ) \
|
||||
for(struct nk_panel *layout = ui_ctx->current->layout; layout; ) \
|
||||
for( xx = (layout->at_x += px, layout->bounds.w -= px, 0); layout; layout->at_x -= px, layout->bounds.w += px, layout = 0 )
|
||||
|
||||
// helper macros to instance an overlayed toolbar within the regions of an existing widget
|
||||
#define UI_TOOLBAR_OVERLAY_DECLARE(...) \
|
||||
__VA_ARGS__; \
|
||||
struct nk_rect toolbar_bounds; nk_layout_peek(&toolbar_bounds, ui_ctx); \
|
||||
struct nk_vec2 item_padding = ui_ctx->style.text.padding; \
|
||||
struct nk_text text; \
|
||||
text.padding.x = item_padding.x; \
|
||||
text.padding.y = item_padding.y; \
|
||||
text.background = ui_ctx->style.window.background;
|
||||
#define UI_TOOLBAR_OVERLAY(CHOICE,TEXT,COLOR,ALIGNMENT) \
|
||||
do { \
|
||||
text.text = COLOR; \
|
||||
nk_widget_text(&ui_ctx->current->buffer, toolbar_bounds, TEXT, strlen(TEXT), &text, ALIGNMENT, ui_ctx->style.font); \
|
||||
int clicked_x = input_down(MOUSE_L) && nk_input_is_mouse_hovering_rect(&ui_ctx->input, toolbar_bounds); \
|
||||
if( clicked_x ) clicked_x = (int)((ui_ctx->input.mouse.pos.x - toolbar_bounds.x) - (ALIGNMENT == NK_TEXT_RIGHT ? bounds.w : 0) ); \
|
||||
CHOICE = 1 + (ALIGNMENT == NK_TEXT_RIGHT ? -1 : +1) * clicked_x / (UI_ICON_FONTSIZE + UI_ICON_SPACING_X); /* divided by px per ICON_MD_ glyph approximately */ \
|
||||
int glyphs = strlen(TEXT) / 4 /*3:MD,4:MDI*/; CHOICE *= !!clicked_x * (CHOICE <= glyphs); } while(0)
|
||||
|
||||
// menu macros that work not only standalone but also contained within a panel or window
|
||||
#define UI_MENU(N, ...) do { \
|
||||
enum { MENUROW_HEIGHT = 25 }; \
|
||||
int embedded = !!ui_ctx->current; \
|
||||
struct nk_rect total_space = {0,0,window_width(),window_height()}; \
|
||||
if( embedded ) total_space = nk_window_get_bounds(ui_ctx), total_space.w -= 10; \
|
||||
vec2 popup_space = { total_space.w * 0.33, total_space.h * 0.85 }; \
|
||||
int created = !embedded && nk_begin(ui_ctx, "MENU_" STRINGIZE(__COUNTER__), nk_rect(0, 0, window_width(), UI_MENUROW_HEIGHT), NK_WINDOW_NO_SCROLLBAR); \
|
||||
if ( embedded || created ) { \
|
||||
int align = NK_TEXT_LEFT, Nth = (N), ITEM_WIDTH = 30, span = 0; \
|
||||
nk_menubar_begin(ui_ctx); \
|
||||
nk_layout_row_begin(ui_ctx, NK_STATIC, MENUROW_HEIGHT, Nth); \
|
||||
__VA_ARGS__; \
|
||||
nk_menubar_end(ui_ctx); \
|
||||
if( created ) nk_end(ui_ctx); \
|
||||
} } while(0)
|
||||
#define UI_MENU_POPUP(title, ...) { \
|
||||
int hspace = maxi(ITEM_WIDTH, nk_text_width(ui_ctx,(title),0)); \
|
||||
nk_layout_row_push(ui_ctx, hspace); span += hspace; \
|
||||
if (nk_menu_begin_label(ui_ctx, (title), align, nk_vec2(popup_space.w,popup_space.h))) { \
|
||||
__VA_ARGS__; \
|
||||
nk_menu_end(ui_ctx); \
|
||||
}}
|
||||
#define UI_MENU_ITEM(title, ...) { \
|
||||
int hspace = maxi(ITEM_WIDTH, nk_text_width(ui_ctx,(title),0)); \
|
||||
nk_layout_row_push(ui_ctx, hspace); span += hspace; \
|
||||
if (nk_menu_begin_label(ui_ctx, (title), align, nk_vec2(1,1))) { \
|
||||
__VA_ARGS__; \
|
||||
nk_menu_close(ui_ctx); \
|
||||
nk_menu_end(ui_ctx); \
|
||||
}}
|
||||
#define UI_MENU_ALIGN_RIGHT(px) { \
|
||||
int hspace = total_space.w - span - (px) - 1.5 * ITEM_WIDTH; \
|
||||
nk_layout_row_push(ui_ctx, hspace); span += hspace; \
|
||||
if (nk_menu_begin_label(ui_ctx, (title), align = NK_TEXT_RIGHT, nk_vec2(1,1))) { \
|
||||
nk_menu_close(ui_ctx); \
|
||||
nk_menu_end(ui_ctx); \
|
||||
}}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ui
|
||||
|
||||
#ifndef UI_ICONS_SMALL
|
||||
//#define UI_ICONS_SMALL 1
|
||||
|
@ -316,7 +434,6 @@ vec2 ui_toolbar_(array(ui_item_t) ui_items, vec2 ui_results) {
|
|||
// old method: nk_layout_row_dynamic(ui_ctx, UI_MENUBAR_ICON_HEIGHT/*h*/, array_count(ui_items));
|
||||
{
|
||||
const struct nk_style *style = &ui_ctx->style;
|
||||
const struct nk_user_font *f = style->font;
|
||||
|
||||
nk_layout_row_template_begin(ui_ctx, UI_MENUBAR_ICON_HEIGHT/*h*/);
|
||||
for(int i = 0; i < array_count(ui_items); ++i) {
|
||||
|
@ -326,7 +443,7 @@ vec2 ui_toolbar_(array(ui_item_t) ui_items, vec2 ui_results) {
|
|||
char *tooltip = strchr(first_token, '@');
|
||||
int len = tooltip ? (int)(tooltip - first_token /*- 1*/) : strlen(first_token);
|
||||
|
||||
float pixels_width = f->width(f->userdata, f->height, first_token, len);
|
||||
float pixels_width = nk_text_width(ui_ctx, first_token, len);
|
||||
pixels_width += style->window.header.label_padding.x * 2 + style->window.header.padding.x * 2;
|
||||
if( pixels_width < 5 ) pixels_width = 5;
|
||||
nk_layout_row_template_push_static(ui_ctx, pixels_width);
|
||||
|
@ -1404,20 +1521,19 @@ int ui_panel_end() {
|
|||
}
|
||||
|
||||
static unsigned ui_collapse_state = 0;
|
||||
static bool ui_collapse_next_open = 0;
|
||||
int ui_collapse(const char *label, const char *id) { // mask: 0(closed),1(open),2(created)
|
||||
int open = label[0] == '!'; label += open;
|
||||
int start_open = label[0] == '!'; label += start_open;
|
||||
|
||||
uint64_t hash = 14695981039346656037ULL, mult = 0x100000001b3ULL;
|
||||
for(int i = 0; id[i]; ++i) hash = (hash ^ id[i]) * mult;
|
||||
ui_hue = (hash & 0x3F) / (float)0x3F; ui_hue += !ui_hue;
|
||||
|
||||
ui_collapse_state = nk_tree_base_(ui_ctx, NK_TREE_NODE, 0, label, ui_collapse_next_open ? NK_MAXIMIZED : NK_MINIMIZED, id, strlen(id), 0);
|
||||
return ui_collapse_next_open = 0, ui_collapse_state & 1; // |1 open, |2 clicked, |4 toggled
|
||||
}
|
||||
int ui_collapseo(const char *label, const char *id) { // mask: 0(closed),1(open),2(created)
|
||||
ui_collapse_next_open = true;
|
||||
return ui_collapse(label, id);
|
||||
int forced = ui_filter && ui_filter[0];
|
||||
enum nk_collapse_states forced_open = NK_MAXIMIZED;
|
||||
|
||||
ui_collapse_state = nk_tree_base_(ui_ctx, NK_TREE_NODE, 0, label, start_open ? NK_MAXIMIZED : NK_MINIMIZED, forced ? &forced_open : NULL, id, strlen(id), 0);
|
||||
|
||||
return ui_collapse_state & 1; // |1 open, |2 clicked, |4 toggled
|
||||
}
|
||||
int ui_collapse_clicked() {
|
||||
return ui_collapse_state >> 1; // |1 clicked, |2 toggled
|
||||
|
@ -1574,10 +1690,12 @@ if( font ) nk_style_pop_font(ui_ctx);
|
|||
return ui_label_icon_clicked_L.x;
|
||||
}
|
||||
|
||||
int ui_label(const char *text) {
|
||||
int align = text[0] == '>' ? (text++, NK_TEXT_RIGHT) : text[0] == '=' ? (text++, NK_TEXT_CENTERED) : text[0] == '<' ? (text++, NK_TEXT_LEFT) : NK_TEXT_LEFT;
|
||||
int ui_label(const char *label) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
int align = label[0] == '>' ? (label++, NK_TEXT_RIGHT) : label[0] == '=' ? (label++, NK_TEXT_CENTERED) : label[0] == '<' ? (label++, NK_TEXT_LEFT) : NK_TEXT_LEFT;
|
||||
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
||||
return ui_label_(text, align);
|
||||
return ui_label_(label, align);
|
||||
}
|
||||
|
||||
static int nk_label_(struct nk_context *ui_ctx, const char *text_, int align2 ) {
|
||||
|
@ -1601,6 +1719,8 @@ ui_label_icon_clicked_R.x = is_hovering ? ( (int)((input->mouse.pos.x - bounds.x
|
|||
|
||||
|
||||
int ui_label2(const char *label, const char *text_) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||
|
||||
int align1 = NK_TEXT_LEFT;
|
||||
|
@ -1655,7 +1775,9 @@ int ui_button_transparent(const char *text) {
|
|||
#endif
|
||||
|
||||
static
|
||||
int ui_button_(const char *text) {
|
||||
int ui_button_(const char *label) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
if( 1 ) {
|
||||
#if UI_BUTTON_MONOCHROME
|
||||
nk_style_push_color(ui_ctx, &ui_ctx->style.button.text_normal, nk_rgba(0,0,0,ui_alpha));
|
||||
|
@ -1686,8 +1808,8 @@ int ui_button_(const char *text) {
|
|||
|
||||
struct nk_rect bounds = nk_widget_bounds(ui_ctx);
|
||||
|
||||
const char *split = strchr(text, '@'), *tooltip = split + 1;
|
||||
int ret = nk_button_text(ui_ctx, text, split ? (int)(split - text) : strlen(text) );
|
||||
const char *split = strchr(label, '@'), *tooltip = split + 1;
|
||||
int ret = nk_button_text(ui_ctx, label, split ? (int)(split - label) : strlen(label) );
|
||||
|
||||
const struct nk_input *in = &ui_ctx->input;
|
||||
if (split && nk_input_is_mouse_hovering_rect(in, bounds) && !ui_has_active_popups && nk_window_has_focus(ui_ctx)) {
|
||||
|
@ -1708,6 +1830,23 @@ int ui_button_(const char *text) {
|
|||
}
|
||||
|
||||
int ui_buttons(int buttons, ...) {
|
||||
static array(char*) args = 0;
|
||||
array_resize(args, 0);
|
||||
|
||||
int num_skips = 0;
|
||||
va_list list;
|
||||
va_start(list, buttons);
|
||||
for( int i = 0; i < buttons; ++i ) {
|
||||
const char *label = va_arg(list, const char*);
|
||||
int skip = ui_filter && ui_filter[0] && !strstri(label, ui_filter);
|
||||
array_push(args, skip ? NULL : (char*)label);
|
||||
num_skips += skip;
|
||||
}
|
||||
va_end(list);
|
||||
|
||||
if( num_skips == array_count(args) ) return 0;
|
||||
buttons = array_count(args) - num_skips;
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, 0, buttons);
|
||||
|
||||
float ui_hue_old = ui_hue;
|
||||
|
@ -1722,10 +1861,8 @@ int ui_buttons(int buttons, ...) {
|
|||
layout->bounds.w -= indent;
|
||||
|
||||
int rc = 0;
|
||||
va_list list;
|
||||
va_start(list, buttons);
|
||||
for( int i = 0; i < buttons; ++i ) {
|
||||
if( ui_button_( va_arg(list, const char*) ) ) rc = i+1;
|
||||
for( int i = 0, end = array_count(args); i < end; ++i ) {
|
||||
if( args[i] && ui_button_( args[i] ) ) rc = i+1;
|
||||
ui_hue_cycle( 3 );
|
||||
}
|
||||
va_end(list);
|
||||
|
@ -1742,6 +1879,8 @@ int ui_button(const char *s) {
|
|||
}
|
||||
|
||||
int ui_toggle(const char *label, bool *value) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||
ui_label_(label, NK_TEXT_LEFT);
|
||||
|
||||
|
@ -1751,6 +1890,8 @@ int ui_toggle(const char *label, bool *value) {
|
|||
}
|
||||
|
||||
int ui_color4f(const char *label, float *color4) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
float c[4] = { color4[0]*255, color4[1]*255, color4[2]*255, color4[3]*255 };
|
||||
int ret = ui_color4(label, c);
|
||||
for( int i = 0; i < 4; ++i ) color4[i] = c[i] / 255.0f;
|
||||
|
@ -1760,6 +1901,8 @@ int ui_color4f(const char *label, float *color4) {
|
|||
static enum color_mode {COL_RGB, COL_HSV} ui_color_mode = COL_RGB;
|
||||
|
||||
int ui_color4(const char *label, float *color4) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||
ui_label_(label, NK_TEXT_LEFT);
|
||||
|
||||
|
@ -1806,6 +1949,8 @@ int ui_color3f(const char *label, float *color3) {
|
|||
}
|
||||
|
||||
int ui_color3(const char *label, float *color3) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||
ui_label_(label, NK_TEXT_LEFT);
|
||||
|
||||
|
@ -1842,6 +1987,8 @@ int ui_color3(const char *label, float *color3) {
|
|||
}
|
||||
|
||||
int ui_list(const char *label, const char **items, int num_items, int *selector) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||
ui_label_(label, NK_TEXT_LEFT);
|
||||
|
||||
|
@ -1852,6 +1999,8 @@ int ui_list(const char *label, const char **items, int num_items, int *selector)
|
|||
}
|
||||
|
||||
int ui_slider(const char *label, float *slider) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
// return ui_slider2(label, slider, va("%.2f ", *slider));
|
||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||
ui_label_(label, NK_TEXT_LEFT);
|
||||
|
@ -1862,6 +2011,8 @@ int ui_slider(const char *label, float *slider) {
|
|||
return chg;
|
||||
}
|
||||
int ui_slider2(const char *label, float *slider, const char *caption) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||
ui_label_(label, NK_TEXT_LEFT);
|
||||
|
||||
|
@ -1886,6 +2037,8 @@ int ui_slider2(const char *label, float *slider, const char *caption) {
|
|||
}
|
||||
|
||||
int ui_bool(const char *label, bool *enabled ) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||
ui_label_(label, NK_TEXT_LEFT);
|
||||
|
||||
|
@ -1900,6 +2053,8 @@ int ui_bool(const char *label, bool *enabled ) {
|
|||
}
|
||||
|
||||
int ui_int(const char *label, int *v) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||
ui_label_(label, NK_TEXT_LEFT);
|
||||
|
||||
|
@ -1909,6 +2064,8 @@ int ui_int(const char *label, int *v) {
|
|||
}
|
||||
|
||||
int ui_unsigned(const char *label, unsigned *v) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||
ui_label_(label, NK_TEXT_LEFT);
|
||||
|
||||
|
@ -1918,11 +2075,15 @@ int ui_unsigned(const char *label, unsigned *v) {
|
|||
}
|
||||
|
||||
int ui_short(const char *label, short *v) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
int i = *v, ret = ui_int( label, &i );
|
||||
return *v = (short)i, ret;
|
||||
}
|
||||
|
||||
int ui_float(const char *label, float *v) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||
ui_label_(label, NK_TEXT_LEFT);
|
||||
|
||||
|
@ -1931,6 +2092,8 @@ int ui_float(const char *label, float *v) {
|
|||
}
|
||||
|
||||
int ui_double(const char *label, double *v) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||
ui_label_(label, NK_TEXT_LEFT);
|
||||
|
||||
|
@ -1939,6 +2102,8 @@ int ui_double(const char *label, double *v) {
|
|||
}
|
||||
|
||||
int ui_clampf(const char *label, float *v, float minf, float maxf) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
if( minf > maxf ) return ui_clampf(label, v, maxf, minf);
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||
|
@ -1951,6 +2116,8 @@ int ui_clampf(const char *label, float *v, float minf, float maxf) {
|
|||
static bool ui_float_sign = 0;
|
||||
|
||||
int ui_float2(const char *label, float *v) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||
ui_label_(label, NK_TEXT_LEFT);
|
||||
|
||||
|
@ -1969,6 +2136,8 @@ int ui_float2(const char *label, float *v) {
|
|||
}
|
||||
|
||||
int ui_float3(const char *label, float *v) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||
ui_label_(label, NK_TEXT_LEFT);
|
||||
|
||||
|
@ -1988,6 +2157,8 @@ int ui_float3(const char *label, float *v) {
|
|||
}
|
||||
|
||||
int ui_float4(const char *label, float *v) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||
ui_label_(label, NK_TEXT_LEFT);
|
||||
|
||||
|
@ -2009,6 +2180,8 @@ int ui_float4(const char *label, float *v) {
|
|||
}
|
||||
|
||||
int ui_mat33(const char *label, float M[9]) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
ui_float_sign = 3;
|
||||
int changed = 0;
|
||||
changed |= ui_label(label);
|
||||
|
@ -2018,6 +2191,8 @@ int ui_mat33(const char *label, float M[9]) {
|
|||
return changed;
|
||||
}
|
||||
int ui_mat34(const char *label, float M[12]) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
ui_float_sign = 3;
|
||||
int changed = 0;
|
||||
changed |= ui_label(label);
|
||||
|
@ -2027,6 +2202,8 @@ int ui_mat34(const char *label, float M[12]) {
|
|||
return changed;
|
||||
}
|
||||
int ui_mat44(const char *label, float M[16]) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
ui_float_sign = 4;
|
||||
int changed = 0;
|
||||
changed |= ui_label(label);
|
||||
|
@ -2038,6 +2215,8 @@ int ui_mat44(const char *label, float M[16]) {
|
|||
}
|
||||
|
||||
int ui_buffer(const char *label, char *buffer, int buflen) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, 0, 1 + (label && label[0]));
|
||||
if(label && label[0]) ui_label_(label, NK_TEXT_LEFT);
|
||||
|
||||
|
@ -2046,6 +2225,8 @@ int ui_buffer(const char *label, char *buffer, int buflen) {
|
|||
}
|
||||
|
||||
int ui_string(const char *label, char **str) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
char *bak = va("%s%c", *str ? *str : "", '\0');
|
||||
int rc = ui_buffer(label, bak, strlen(bak)+2);
|
||||
if( *str ) 0[*str] = '\0';
|
||||
|
@ -2054,6 +2235,8 @@ int ui_string(const char *label, char **str) {
|
|||
}
|
||||
|
||||
int ui_separator() {
|
||||
if( /*label &&*/ ui_filter && ui_filter[0] ) return 0; // if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, UI_SEPARATOR_HEIGHT, 1);
|
||||
|
||||
ui_hue_cycle( 1 );
|
||||
|
@ -2070,6 +2253,8 @@ int ui_separator() {
|
|||
}
|
||||
|
||||
int ui_subimage(const char *label, handle id, unsigned iw, unsigned ih, unsigned sx, unsigned sy, unsigned sw, unsigned sh) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
nk_layout_row_dynamic(ui_ctx, sh < 30 || id == texture_checker().id ? 0 : sh, 1 + (label && label[0]));
|
||||
if( label && label[0] ) ui_label_(label, NK_TEXT_LEFT);
|
||||
|
||||
|
@ -2099,31 +2284,35 @@ int ui_subtexture(const char *label, texture_t t, unsigned x, unsigned y, unsign
|
|||
return ui_subimage(label, t.id, t.w,t.h, x,y,w,h);
|
||||
}
|
||||
|
||||
int ui_colormap( const char *map_name, colormap_t *cm ) {
|
||||
int ui_colormap( const char *label, colormap_t *cm ) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
int ret = 0;
|
||||
if( !cm->texture ) {
|
||||
const char *title = va("%s (no image)", map_name);
|
||||
const char *title = va("%s (no image)", label);
|
||||
if( ui_image( title, texture_checker().id, 0,0 ) ) {
|
||||
ret = 2;
|
||||
}
|
||||
} else {
|
||||
unsigned w = cm->texture->w, h = cm->texture->h;
|
||||
ui_label(va("%s (%s)", map_name, cm->texture->filename) ); // @fixme: labelf would crash?
|
||||
ui_label(va("%s (%s)", label, cm->texture->filename) ); // @fixme: labelf would crash?
|
||||
|
||||
const char *fmt[] = { "", "R", "RG", "RGB", "RGBA" };
|
||||
const char *title = va("%s %dx%d %s", map_name, w, h, fmt[cm->texture->n]);
|
||||
const char *title = va("%s %dx%d %s", label, w, h, fmt[cm->texture->n]);
|
||||
if( ui_image( title, cm->texture->id, 128, 128 ) ) {
|
||||
ret = 2;
|
||||
}
|
||||
}
|
||||
|
||||
if( ui_color4f( va("%s Color", map_name), (float *) &cm->color ) ) {
|
||||
if( ui_color4f( va("%s Color", label), (float *) &cm->color ) ) {
|
||||
ret = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ui_radio(const char *label, const char **items, int num_items, int *selector) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
int ret = 0;
|
||||
if( label && label[0] ) ui_label(label);
|
||||
for( int i = 0; i < num_items; i++ ) {
|
||||
|
@ -2136,20 +2325,24 @@ int ui_radio(const char *label, const char **items, int num_items, int *selector
|
|||
return ret;
|
||||
}
|
||||
|
||||
int ui_section(const char *section) {
|
||||
int ui_section(const char *label) {
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
//ui_separator();
|
||||
return ui_label(va("*%s", section));
|
||||
return ui_label(va("*%s", label));
|
||||
}
|
||||
|
||||
int ui_dialog(const char *title, const char *text, int choices, bool *show) { // @fixme: return
|
||||
int ui_dialog(const char *label, const char *text, int choices, bool *show) { // @fixme: return
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||
|
||||
ui_has_active_popups = 0;
|
||||
if(*show) {
|
||||
static struct nk_rect s = {0, 0, 300, 190};
|
||||
if (nk_popup_begin(ui_ctx, NK_POPUP_STATIC, title, NK_WINDOW_BORDER|NK_WINDOW_CLOSABLE, s)) {
|
||||
if (nk_popup_begin(ui_ctx, NK_POPUP_STATIC, label, NK_WINDOW_BORDER|NK_WINDOW_CLOSABLE, s)) {
|
||||
nk_layout_row_dynamic(ui_ctx, 20, 1);
|
||||
for( char label[1024]; *text && sscanf(text, "%[^\r\n]", label); ) {
|
||||
nk_label(ui_ctx, label, NK_TEXT_LEFT);
|
||||
text += strlen(label); while(*text && *text < 32) text++;
|
||||
for( char t[1024]; *text && sscanf(text, "%[^\r\n]", t); ) {
|
||||
nk_label(ui_ctx, t, NK_TEXT_LEFT);
|
||||
text += strlen(t); while(*text && *text < 32) text++;
|
||||
}
|
||||
|
||||
if( choices ) {
|
||||
|
@ -2170,6 +2363,8 @@ int ui_dialog(const char *title, const char *text, int choices, bool *show) { //
|
|||
|
||||
#define ui_bitmask_template(X) \
|
||||
int ui_bitmask##X(const char *label, uint##X##_t *enabled) { \
|
||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0; \
|
||||
\
|
||||
/* @fixme: better way to retrieve widget width? nk_layout_row_dynamic() seems excessive */ \
|
||||
nk_layout_row_dynamic(ui_ctx, 1, 1); \
|
||||
struct nk_rect bounds = nk_widget_bounds(ui_ctx); \
|
||||
|
@ -2297,9 +2492,46 @@ int ui_browse(const char **output, bool *inlined) {
|
|||
struct browser *browser = browsers + windowed; // select instance
|
||||
char **result = results + windowed; // select instance
|
||||
|
||||
struct nk_rect bounds = {0,0,400,300}; // @fixme: how to retrieve inlined region below? (inlined)
|
||||
if( windowed || (!windowed && *inlined) ) bounds = nk_window_get_content_region(ui_ctx);
|
||||
else { struct nk_rect b; nk_layout_peek(&b, ui_ctx); bounds.w = b.w; }
|
||||
struct nk_rect bounds = {0}; // // {0,0,400,300};
|
||||
// #define P(b) printf(FILELINE " (%3d,%3d) %3d,%3d\n", (int)b.x,(int)b.y, (int)b.w,(int)b.h)
|
||||
// if(ui_ctx->current) bounds = nk_layout_space_bounds(ui_ctx), P(bounds);
|
||||
// if(ui_ctx->current) bounds = nk_layout_widget_bounds(ui_ctx), P(bounds);
|
||||
// if(ui_ctx->current) bounds = nk_widget_bounds(ui_ctx), P(bounds);
|
||||
// if(ui_ctx->current) bounds = nk_window_get_bounds(ui_ctx), P(bounds);
|
||||
// if(ui_ctx->current) bounds = nk_window_get_content_region(ui_ctx), P(bounds);
|
||||
// if(ui_ctx->current) nk_layout_peek(&bounds, ui_ctx), P(bounds);
|
||||
// // if(ui_ctx->current) nk_layout_widget_space(&bounds, ui_ctx, ui_ctx->current, nk_false), P(bounds); // note: cant be used within a panel
|
||||
// #undef P
|
||||
|
||||
// panel
|
||||
// v4k_ui.c:2497 ( 6, 34) 310, 24
|
||||
// v4k_ui.c:2498 ( 16, 62) 286, 24
|
||||
// v4k_ui.c:2499 ( 16, 86) 296, 24
|
||||
// v4k_ui.c:2500 ( 0, 0) 327,613
|
||||
// v4k_ui.c:2501 ( 6, 34) 310,572 << ok
|
||||
// v4k_ui.c:2502 ( 16, 86) 296, 24
|
||||
// v4k_ui.c:2503 (316, 62) 297, 24
|
||||
|
||||
// window
|
||||
// v4k_ui.c:2497 (188,152) 711, 4
|
||||
// v4k_ui.c:2498 (188,152) 711, 4
|
||||
// v4k_ui.c:2499 (-2147483648,156) -2147483648, 4
|
||||
// v4k_ui.c:2500 (182,118) 728,409
|
||||
// v4k_ui.c:2501 (188,152) 711,368 << ok
|
||||
// v4k_ui.c:2502 (-2147483648,156) -2147483648, 4
|
||||
// v4k_ui.c:2503 (-2147483648,152) -2147483648, 4
|
||||
|
||||
// popup
|
||||
// v4k_ui.c:2497 ( 9, 30) 350, 24
|
||||
// v4k_ui.c:2498 ( 19, 58) 326, 24
|
||||
// v4k_ui.c:2499 ( 19, 82) 336, 24
|
||||
// v4k_ui.c:2500 ( 4, 29) 360,460
|
||||
// v4k_ui.c:2501 ( 9, 30) 350,458 << ok
|
||||
// v4k_ui.c:2502 ( 19, 82) 336, 24
|
||||
// v4k_ui.c:2503 (359, 58) 336, 24
|
||||
|
||||
bounds = nk_window_get_content_region(ui_ctx);
|
||||
if( !windowed && *inlined ) bounds.h *= 0.80;
|
||||
|
||||
clicked = browser_run(ui_ctx, browser, windowed, bounds);
|
||||
if( clicked ) {
|
||||
|
|
|
@ -86,3 +86,4 @@ API int ui_hover(); // ui_is_hover()?
|
|||
API int ui_active(); // ui_is_active()?
|
||||
|
||||
API int ui_demo(int do_windows);
|
||||
API void *ui_handle();
|
||||
|
|
|
@ -536,229 +536,8 @@ int window_frame_begin() {
|
|||
// generate Debug panel contents
|
||||
if( may_render_debug_panel ) {
|
||||
if( has_menu ? ui_window("Debug " ICON_MD_SETTINGS, 0) : ui_panel("Debug " ICON_MD_SETTINGS, 0) ) {
|
||||
|
||||
static int time_factor = 0;
|
||||
static int playing = 0;
|
||||
static int paused = 0;
|
||||
int advance_frame = 0;
|
||||
|
||||
static int do_filter = 0;
|
||||
static int do_profile = 0;
|
||||
static int do_extra = 0;
|
||||
|
||||
char *EDITOR_TOOLBAR_ICONS = va("%s;%s;%s;%s;%s;%s;%s;%s",
|
||||
do_filter ? ICON_MD_CLOSE : ICON_MD_SEARCH,
|
||||
ICON_MD_PLAY_ARROW,
|
||||
paused ? ICON_MD_SKIP_NEXT : ICON_MD_PAUSE,
|
||||
ICON_MD_FAST_FORWARD,
|
||||
ICON_MD_STOP,
|
||||
ICON_MD_REPLAY,
|
||||
ICON_MD_FACE,
|
||||
ICON_MD_MENU
|
||||
);
|
||||
|
||||
if( input_down(KEY_F) ) if( input(KEY_LCTRL) || input(KEY_RCTRL) ) do_filter ^= 1;
|
||||
int choice = ui_toolbar(EDITOR_TOOLBAR_ICONS);
|
||||
if( choice == 1 ) do_filter ^= 1, do_profile = 0, do_extra = 0;
|
||||
if( choice == 2 ) playing = 1, paused = 0;
|
||||
if( choice == 3 ) advance_frame = !!paused, paused = 1;
|
||||
if( choice == 4 ) paused = 0, time_factor = (++time_factor) % 4;
|
||||
if( choice == 5 ) playing = 0, paused = 0, advance_frame = 0, time_factor = 0;
|
||||
if( choice == 6 ) window_reload();
|
||||
if( choice == 7 ) do_filter = 0, do_profile ^= 1, do_extra = 0;
|
||||
if( choice == 8 ) do_filter = 0, do_profile = 0, do_extra ^= 1;
|
||||
|
||||
static char *filter = 0;
|
||||
if( do_filter ) {
|
||||
ui_string(ICON_MD_CLOSE " Filter " ICON_MD_SEARCH, &filter);
|
||||
if( ui_label_icon_clicked_L.x > 0 && ui_label_icon_clicked_L.x <= 24 ) { // if clicked on CANCEL icon (1st icon)
|
||||
do_filter = 0;
|
||||
}
|
||||
} else {
|
||||
if( filter ) filter[0] = '\0';
|
||||
}
|
||||
char *filter_mask = filter && filter[0] ? va("*%s*", filter) : "*";
|
||||
|
||||
static char *username = 0;
|
||||
static char *userpass = 0;
|
||||
if( do_profile ) {
|
||||
ui_string(ICON_MD_FACE " Username", &username);
|
||||
ui_string(ICON_MD_FACE " Password", &userpass);
|
||||
}
|
||||
|
||||
if( do_extra ) {
|
||||
int choice2 = ui_label2_toolbar(NULL,
|
||||
ICON_MD_VIEW_IN_AR
|
||||
ICON_MD_MESSAGE
|
||||
ICON_MD_TIPS_AND_UPDATES ICON_MD_LIGHTBULB ICON_MD_LIGHTBULB_OUTLINE
|
||||
ICON_MD_IMAGE_SEARCH ICON_MD_INSERT_PHOTO
|
||||
ICON_MD_VIDEOGAME_ASSET ICON_MD_VIDEOGAME_ASSET_OFF
|
||||
|
||||
ICON_MD_VOLUME_UP ICON_MD_VOLUME_OFF // audio_volume_master(-1) > 0
|
||||
|
||||
ICON_MD_TROUBLESHOOT ICON_MD_SCHEMA ICON_MD_MENU
|
||||
);
|
||||
}
|
||||
|
||||
int open = 0, clicked_or_toggled = 0;
|
||||
|
||||
#define ui_collapse_filtered(lbl,id) (strmatchi(lbl,filter_mask) && ui_collapse(lbl,id))
|
||||
|
||||
#define EDITOR_UI_COLLAPSE(f,...) \
|
||||
for( int macro(p) = (open = ui_collapse_filtered(f,__VA_ARGS__)), macro(dummy) = (clicked_or_toggled = ui_collapse_clicked()); macro(p); ui_collapse_end(), macro(p) = 0)
|
||||
|
||||
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_BUG_REPORT " Bugs 0", "Debug.Bugs") {
|
||||
// @todo. parse /bugs.ini, includes saved screenshots & videos.
|
||||
// @todo. screenshot include parseable level, position screen markers (same info as /bugs.ini)
|
||||
}
|
||||
|
||||
|
||||
// Art and bookmarks
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_FOLDER_SPECIAL " Art", "Debug.Art") {
|
||||
bool inlined = true;
|
||||
const char *file = 0;
|
||||
if( ui_browse(&file, &inlined) ) {
|
||||
const char *sep = ifdef(win32, "\"", "'");
|
||||
app_exec(va("%s %s%s%s", ifdef(win32, "start \"\"", ifdef(osx, "open", "xdg-open")), sep, file, sep));
|
||||
}
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_BOOKMARK " Bookmarks", "Debug.Bookmarks") { /* @todo */ }
|
||||
|
||||
|
||||
// E,C,S,W
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_ACCOUNT_TREE " Scene", "Debug.Scene") {
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_BUBBLE_CHART/*ICON_MD_SCATTER_PLOT*/ " Entities", "Debug.Entities") { /* @todo */ }
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_TUNE " Components", "Debug.Components") { /* @todo */ }
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_PRECISION_MANUFACTURING " Systems", "Debug.Systems") { /* @todo */ }
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_PUBLIC " Levels", "Debug.Levels") {
|
||||
//node_edit(editor.edit.down,&editor.edit);
|
||||
}
|
||||
|
||||
//EDITOR_UI_COLLAPSE(ICON_MD_ACCOUNT_TREE " Init", "Debug.HierarchyInit") { /* @todo */ }
|
||||
//EDITOR_UI_COLLAPSE(ICON_MD_ACCOUNT_TREE " Draw", "Debug.HierarchyDraw") { /* @todo */ }
|
||||
//EDITOR_UI_COLLAPSE(ICON_MD_ACCOUNT_TREE " Tick", "Debug.HierarchyTick") { /* @todo */ }
|
||||
//EDITOR_UI_COLLAPSE(ICON_MD_ACCOUNT_TREE " Edit", "Debug.HierarchyEdit") { /* @todo */ }
|
||||
//EDITOR_UI_COLLAPSE(ICON_MD_ACCOUNT_TREE " Quit", "Debug.HierarchyQuit") { /* @todo */ }
|
||||
|
||||
// node_edit(&editor.init,&editor.init);
|
||||
// node_edit(&editor.draw,&editor.draw);
|
||||
// node_edit(&editor.tick,&editor.tick);
|
||||
// node_edit(&editor.edit,&editor.edit);
|
||||
// node_edit(&editor.quit,&editor.quit);
|
||||
}
|
||||
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_ROCKET_LAUNCH " AI", "Debug.AI") {
|
||||
// @todo
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_VOLUME_UP " Audio", "Debug.Audio") {
|
||||
ui_audio();
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_VIDEOCAM " Camera", "Debug.Camera") {
|
||||
ui_camera( camera_get_active() );
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_MONITOR " Display", "Debug.Display") {
|
||||
// @todo: fps lock, fps target, aspect ratio, fullscreen
|
||||
char *text = va("%s;%s;%s",
|
||||
window_has_fullscreen() ? ICON_MD_FULLSCREEN_EXIT : ICON_MD_FULLSCREEN,
|
||||
ICON_MD_PHOTO_CAMERA,
|
||||
record_active() ? ICON_MD_VIDEOCAM_OFF : ICON_MD_VIDEOCAM
|
||||
);
|
||||
|
||||
int choice = ui_toolbar(text);
|
||||
if( choice == 1 ) engine_send("key_fullscreen",0);
|
||||
if( choice == 2 ) engine_send("key_screenshot",0);
|
||||
if( choice == 3 ) engine_send("key_record",0);
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_KEYBOARD " Keyboard", "Debug.Keyboard") {
|
||||
ui_keyboard();
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_MOUSE " Mouse", "Debug.Mouse") {
|
||||
ui_mouse();
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_GAMEPAD " Gamepads", "Debug.Gamepads") {
|
||||
for( int q = 0; q < 4; ++q ) {
|
||||
for( int r = (open = ui_collapse(va("Gamepad #%d",q+1), va("Debug.Gamepads%d",q))), dummy = (clicked_or_toggled = ui_collapse_clicked()); r; ui_collapse_end(), r = 0) {
|
||||
ui_gamepad(q);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_CONTENT_PASTE " Scripts", "Debug.Scripts") {
|
||||
// @todo
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_STAR_HALF " Shaders", "Debug.Shaders") {
|
||||
ui_shaders();
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_MOVIE " FXs", "Debug.FXs") {
|
||||
ui_fxs();
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_VIEW_QUILT " UI", "Debug.UI") {
|
||||
int choice = ui_toolbar(ICON_MD_RECYCLING " Reset layout;" ICON_MD_SAVE_AS " Save layout");
|
||||
if( choice == 1 ) ui_layout_all_reset("*");
|
||||
if( choice == 2 ) file_delete(WINDOWS_INI), ui_layout_all_save_disk("*");
|
||||
|
||||
for each_map_ptr_sorted(ui_windows, char*, k, unsigned, v) {
|
||||
bool visible = ui_visible(*k);
|
||||
if( ui_bool( *k, &visible ) ) {
|
||||
ui_show( *k, ui_visible(*k) ^ true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_SAVINGS " Budgets", "Debug.Budgets") {
|
||||
// @todo. // mem,fps,gfx,net,hdd,... also logging
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_WIFI/*ICON_MD_SIGNAL_CELLULAR_ALT*/ " Network 0/0 KiB", "Debug.Network") {
|
||||
// @todo
|
||||
// SIGNAL_CELLULAR_1_BAR SIGNAL_CELLULAR_2_BAR
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(va(ICON_MD_SPEED " Profiler %5.2f/%dfps", window_fps(), (int)window_fps_target()), "Debug.Profiler") {
|
||||
ui_profiler();
|
||||
}
|
||||
EDITOR_UI_COLLAPSE(va(ICON_MD_STORAGE " Storage %s", xstats()), "Debug.Storage") {
|
||||
// @todo
|
||||
}
|
||||
|
||||
|
||||
|
||||
// logic: either plug icon (power saving off) or one of the following ones (power saving on):
|
||||
// if 0% batt (no batt): battery alert
|
||||
// if discharging: battery levels [alert,0..6,full]
|
||||
// if charging: battery charging
|
||||
int battery_read = app_battery();
|
||||
int battery_level = abs(battery_read);
|
||||
int battery_discharging = battery_read < 0 && battery_level < 100;
|
||||
const char *power_icon_label = ICON_MD_POWER " Power";
|
||||
if( battery_level ) {
|
||||
const char *battery_levels[9] = { // @todo: remap [7%..100%] -> [0..1] ?
|
||||
ICON_MD_BATTERY_ALERT,ICON_MD_BATTERY_0_BAR,ICON_MD_BATTERY_1_BAR,
|
||||
ICON_MD_BATTERY_2_BAR,ICON_MD_BATTERY_3_BAR,ICON_MD_BATTERY_4_BAR,
|
||||
ICON_MD_BATTERY_5_BAR,ICON_MD_BATTERY_6_BAR,ICON_MD_BATTERY_FULL,
|
||||
};
|
||||
power_icon_label = (const char*)va("%s Power %d%%",
|
||||
battery_discharging ? battery_levels[(int)((9-1)*clampf(battery_level/100.f,0,1))] : ICON_MD_BATTERY_CHARGING_FULL,
|
||||
battery_level);
|
||||
}
|
||||
|
||||
EDITOR_UI_COLLAPSE(power_icon_label, "Debug.Power") {
|
||||
int choice = ui_toolbar( ICON_MD_POWER ";" ICON_MD_BOLT );
|
||||
if( choice == 1 ) engine_send("key_battery","0");
|
||||
if( choice == 2 ) engine_send("key_battery","1");
|
||||
}
|
||||
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_WATER " Reflection", "Debug.Reflect") {
|
||||
ui_reflect("*");
|
||||
}
|
||||
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_EXTENSION " Plugins", "Debug.Plugins") {
|
||||
// @todo. include VCS
|
||||
EDITOR_UI_COLLAPSE(ICON_MD_BUILD " Cook", "Debug.Cook") {
|
||||
// @todo
|
||||
}
|
||||
}
|
||||
API int ui_debug();
|
||||
ui_debug();
|
||||
|
||||
(has_menu ? ui_window_end : ui_panel_end)();
|
||||
}
|
||||
|
|
126
engine/v4k
126
engine/v4k
|
@ -211989,6 +211989,9 @@ nk_nonblock_begin(struct nk_context *ctx,
|
|||
nk_flags flags, struct nk_rect body, struct nk_rect header,
|
||||
enum nk_panel_type panel_type)
|
||||
{
|
||||
if(body.x < 10) body.x = 0; //< @r-lyeh: popup snapping to the left
|
||||
if((body.x+body.w)>window_width()) body.x-=body.w-(window_width()-body.x); //< @r-lyeh: prevent popups to be printed outside of window client / right border
|
||||
|
||||
struct nk_window *popup;
|
||||
struct nk_window *win;
|
||||
struct nk_panel *panel;
|
||||
|
@ -212470,7 +212473,7 @@ nk_menu_begin(struct nk_context *ctx, struct nk_window *win,
|
|||
is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_MENU);
|
||||
if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
|
||||
(!is_open && !is_active && !is_clicked)) return 0;
|
||||
if (!nk_nonblock_begin(ctx, NK_WINDOW_NO_SCROLLBAR, body, header, NK_PANEL_MENU))
|
||||
if (!nk_nonblock_begin(ctx, NK_WINDOW_NO_SCROLLBAR_X/*|NK_WINDOW_NO_SCROLLBAR*/, body, header, NK_PANEL_MENU)) //< @r-lyeh: our popups are huge. enable Y scrollbars
|
||||
return 0;
|
||||
|
||||
win->popup.type = NK_PANEL_MENU;
|
||||
|
@ -213704,6 +213707,7 @@ nk_tree_state_base_(struct nk_context *ctx, enum nk_tree_type type,
|
|||
NK_INTERN int
|
||||
nk_tree_base_(struct nk_context *ctx, enum nk_tree_type type,
|
||||
struct nk_image *img, const char *title, enum nk_collapse_states initial_state,
|
||||
enum nk_collapse_states *forced_state, //< @r-lyeh
|
||||
const char *hash, int len, int line)
|
||||
{
|
||||
struct nk_window *win = ctx->current;
|
||||
|
@ -213721,7 +213725,8 @@ nk_tree_base_(struct nk_context *ctx, enum nk_tree_type type,
|
|||
state = nk_add_value(ctx, win, tree_hash, 0);
|
||||
*state = initial_state;
|
||||
}
|
||||
return nk_tree_state_base_(ctx, type, img, title, (enum nk_collapse_states*)state);
|
||||
return nk_tree_state_base_(ctx, type, img, title,
|
||||
forced_state ? forced_state : (enum nk_collapse_states*)state); //< @r-lyeh
|
||||
}
|
||||
#endif
|
||||
NK_API nk_bool
|
||||
|
@ -221909,6 +221914,7 @@ void nk_glfw3_shutdown(struct nk_glfw* glfw)
|
|||
#endif
|
||||
#endif
|
||||
#line 0
|
||||
static char *ui_filter = 0;
|
||||
#line 1 "engine/split/3rd_nuklear_filebrowser.h"
|
||||
// file browser for nuklear, based on https://github.com/vurtun/nuklear/blob/master/example/file_browser.c (public domain)
|
||||
// - rlyeh, public domain
|
||||
|
@ -221928,8 +221934,56 @@ void nk_glfw3_shutdown(struct nk_glfw* glfw)
|
|||
#else
|
||||
#include <unistd.h> // getcwd()
|
||||
#include <pwd.h> // getpwuid()
|
||||
#define _popen popen
|
||||
#define _pclose pclose
|
||||
#endif
|
||||
|
||||
const char** old_file_list(const char *cwd, const char *masks) {
|
||||
ASSERT(strend(cwd, "/"), "Error: dirs like '%s' must end with slash", cwd);
|
||||
|
||||
static __thread array(char*) list = 0;
|
||||
const char *arg0 = cwd; // app_path();
|
||||
int larg0 = strlen(arg0);
|
||||
|
||||
for( int i = 0; i < array_count(list); ++i ) {
|
||||
FREE(list[i]);
|
||||
}
|
||||
array_resize(list, 0);//array_free(list);
|
||||
|
||||
for each_substring(masks,";",it) {
|
||||
int recurse = !!strstr(it, "**");
|
||||
#if is(win32)
|
||||
char *glob = va("dir %s/b/o:n \"%s\\%s\" 2> NUL", recurse ? "/s":"", cwd, it);
|
||||
#else // linux, osx
|
||||
char *glob = va("find %s %s -name \"%s\" | sort", cwd, !recurse ? "-maxdepth 1":"-type f", it);
|
||||
#endif
|
||||
for( FILE *in = _popen(glob, "r"); in; _pclose(in), in = 0) {
|
||||
char buf[1024], *line = buf;
|
||||
while( fgets(buf, sizeof(buf), in) ) {
|
||||
// clean up
|
||||
if( strstr(line, arg0) ) line = buf + larg0;
|
||||
if( !memcmp(line, "./", 2) ) line += 2;
|
||||
int len = strlen(line); while( len > 0 && line[len-1] < 32 ) line[--len] = 0;
|
||||
if( line[0] == '\0' ) continue;
|
||||
// do not insert system folders/files
|
||||
for(int i = 0; i < len; ++i ) if(line[i] == '\\') line[i] = '/';
|
||||
if( line[0] == '.' ) if( !strcmp(line,".git") || !strcmp(line,".vs") || !strcmp(line,".") || !strcmp(line,"..") ) continue;
|
||||
if( strstr(line, "/.") ) continue;
|
||||
// insert copy
|
||||
#if is(win32)
|
||||
char *copy = STRDUP(line); // full path already provided
|
||||
#else
|
||||
// while(line[0] == '/') ++line;
|
||||
char *copy = STRDUP(va("%s%s", cwd, line)); // need to prepend path
|
||||
#endif
|
||||
array_push(list, copy);
|
||||
}
|
||||
}
|
||||
}
|
||||
array_push(list, 0); // terminator
|
||||
return (const char**)list;
|
||||
}
|
||||
|
||||
#if 1
|
||||
#define BROWSER_PRINTF(...) do {} while(0)
|
||||
#else
|
||||
|
@ -221993,6 +222047,10 @@ struct browser {
|
|||
size_t file_count;
|
||||
size_t dir_count;
|
||||
|
||||
/* filtered directory content */
|
||||
array(char*) ffiles;
|
||||
array(char*) fdirectories;
|
||||
|
||||
/* view mode */
|
||||
bool listing;
|
||||
float zooming;
|
||||
|
@ -222029,8 +222087,8 @@ static void browser_reload_directory_content(struct browser *browser, const char
|
|||
|
||||
BROWSER_PRINTF("searching at %s\n", path);
|
||||
|
||||
array(char*) list = file_list(path);
|
||||
for( int i = 0, end = array_count(list); i < end; ++i ) {
|
||||
const char** list = old_file_list(path, "*");
|
||||
for( int i = 0; list[i]; ++i ) {
|
||||
|
||||
char *absolute = file_pathabs(ifndef(win32, list[i], va("%s/%s", path, list[i]))); // ../dir/./file.ext -> c:/prj/dir/file.ext
|
||||
BROWSER_PRINTF("%s->%s %d->", list[i], absolute, file_directory(absolute) );
|
||||
|
@ -222095,6 +222153,9 @@ static void browser_free(struct browser *browser) {
|
|||
for(int i = 0; i < array_count(browser->directories); ++i) FREE(browser->directories[i]);
|
||||
array_free(browser->files);
|
||||
array_free(browser->directories);
|
||||
array_free(browser->ffiles);
|
||||
array_free(browser->fdirectories);
|
||||
|
||||
memset(browser, 0, sizeof(*browser));
|
||||
}
|
||||
|
||||
|
@ -222175,10 +222236,33 @@ if( cols < 1 ) cols=1;
|
|||
|
||||
/* output directory content window */
|
||||
if(nk_group_begin(ctx, "Content", windowed ? NK_WINDOW_NO_SCROLLBAR : 0)) {
|
||||
|
||||
array(char*) *directories = &browser->directories;
|
||||
array(char*) *files = &browser->files;
|
||||
|
||||
if( ui_filter && ui_filter[0] ) {
|
||||
array_resize(browser->fdirectories, 0);
|
||||
array_resize(browser->ffiles, 0);
|
||||
|
||||
for each_array(browser->directories,char*,k)
|
||||
if( strstri(k, ui_filter) )
|
||||
array_push(browser->fdirectories, k);
|
||||
|
||||
for each_array(browser->files,char*,k)
|
||||
if( strstri(k, ui_filter) )
|
||||
array_push(browser->ffiles, k);
|
||||
|
||||
directories = &browser->fdirectories;
|
||||
files = &browser->ffiles;
|
||||
}
|
||||
|
||||
int dir_count = array_count(*directories);
|
||||
int file_count = array_count(*files);
|
||||
|
||||
int index = -1;
|
||||
size_t i = 0, j = 0, k = 0;
|
||||
size_t rows = 0;
|
||||
size_t count = browser->dir_count + browser->file_count;
|
||||
size_t count = dir_count + file_count;
|
||||
|
||||
rows = count / cols;
|
||||
for (i = 0; i <= rows; i += 1) {
|
||||
|
@ -222186,16 +222270,18 @@ if( cols < 1 ) cols=1;
|
|||
{size_t n = j + cols;
|
||||
nk_layout_row_dynamic(ctx, icon_height, (int)cols);
|
||||
for (; j < count && j < n; ++j) {
|
||||
size_t t = j-dir_count;
|
||||
|
||||
/* draw one row of icons */
|
||||
if (j < browser->dir_count) {
|
||||
if (j < dir_count) {
|
||||
/* draw and execute directory buttons */
|
||||
if (nk_button_image(ctx,media.custom_folders[BROWSER_FOLDER]))
|
||||
index = (int)j;
|
||||
} else {
|
||||
/* draw and execute files buttons */
|
||||
struct nk_image *icon;
|
||||
size_t fileIndex = ((size_t)j - browser->dir_count);
|
||||
icon = media_icon_for_file(browser->files[fileIndex]);
|
||||
size_t fileIndex = ((size_t)j - dir_count);
|
||||
icon = media_icon_for_file((*files)[fileIndex]);
|
||||
if (nk_button_image(ctx, *icon)) {
|
||||
snprintf(browser->file, BROWSER_MAX_PATH, "%s%s", browser->directory, browser->files[fileIndex]);
|
||||
clicked = 1;
|
||||
|
@ -222206,30 +222292,32 @@ if( cols < 1 ) cols=1;
|
|||
{size_t n = k + cols;
|
||||
nk_layout_row_dynamic(ctx, 20, (int)cols);
|
||||
for (; k < count && k < n; k++) {
|
||||
size_t t = k-dir_count;
|
||||
|
||||
/* draw one row of labels */
|
||||
if (k < browser->dir_count) {
|
||||
nk_label(ctx, browser->directories[k], NK_TEXT_CENTERED);
|
||||
if (k < dir_count) {
|
||||
nk_label(ctx, (*directories)[k], NK_TEXT_CENTERED);
|
||||
} else {
|
||||
size_t t = k-browser->dir_count;
|
||||
nk_label(ctx,browser->files[t],NK_TEXT_CENTERED);
|
||||
nk_label(ctx, (*files)[t], NK_TEXT_CENTERED);
|
||||
}
|
||||
}}
|
||||
if(tiny)
|
||||
{size_t n = j + cols;
|
||||
nk_layout_row_dynamic(ctx, icon_height, (int)cols);
|
||||
for (; j < count && j < n; ++j) {
|
||||
size_t t = j-dir_count;
|
||||
|
||||
/* draw one row of icons */
|
||||
if (j < browser->dir_count) {
|
||||
if (j < dir_count) {
|
||||
/* draw and execute directory buttons */
|
||||
if (nk_button_image_label(ctx,media.custom_folders[BROWSER_FOLDER], browser->directories[j],NK_TEXT_RIGHT))
|
||||
if (nk_button_image_label(ctx,media.custom_folders[BROWSER_FOLDER], (*directories)[j], NK_TEXT_RIGHT))
|
||||
index = (int)j;
|
||||
} else {
|
||||
/* draw and execute files buttons */
|
||||
struct nk_image *icon;
|
||||
size_t fileIndex = ((size_t)j - browser->dir_count);
|
||||
icon = media_icon_for_file(browser->files[fileIndex]);
|
||||
size_t t = j-browser->dir_count;
|
||||
if (nk_button_image_label(ctx, *icon, browser->files[t],NK_TEXT_RIGHT)) {
|
||||
size_t fileIndex = ((size_t)j - dir_count);
|
||||
icon = media_icon_for_file((*files)[fileIndex]);
|
||||
if (nk_button_image_label(ctx, *icon, (*files)[t],NK_TEXT_RIGHT)) {
|
||||
snprintf(browser->file, BROWSER_MAX_PATH, "%s%s", browser->directory, browser->files[fileIndex]);
|
||||
clicked = 1;
|
||||
}
|
||||
|
@ -222241,7 +222329,7 @@ if( cols < 1 ) cols=1;
|
|||
struct nk_rect bounds = nk_widget_bounds(ctx);
|
||||
if (nk_input_is_mouse_hovering_rect(&ctx->input, bounds) ) {
|
||||
|
||||
char *name = j < browser->dir_count ? browser->directories[j] : browser->files[j-browser->dir_count];
|
||||
char *name = j < dir_count ? (*directories)[j] : (*files)[j-dir_count];
|
||||
|
||||
char fullpath[PATH_MAX];
|
||||
snprintf(fullpath, PATH_MAX, "%s%s", browser->directory, name);
|
||||
|
|
866
engine/v4k.c
866
engine/v4k.c
File diff suppressed because it is too large
Load Diff
66
engine/v4k.h
66
engine/v4k.h
|
@ -27,7 +27,20 @@
|
|||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* ------------------------------------------------------------------------------
|
||||
* ALTERNATIVE B - MIT-0 (No Attribution clause)
|
||||
* ALTERNATIVE B - 0-BSD License (https://opensource.org/licenses/FPL-1.0.0)
|
||||
* ------------------------------------------------------------------------------
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
* ------------------------------------------------------------------------------
|
||||
* ALTERNATIVE C - MIT-0 (No Attribution clause)
|
||||
* ------------------------------------------------------------------------------
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
* software and associated documentation files (the "Software"), to deal in the Software
|
||||
|
@ -41,19 +54,6 @@
|
|||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* ------------------------------------------------------------------------------
|
||||
* ALTERNATIVE C - Zero BSD License (https://opensource.org/licenses/FPL-1.0.0)
|
||||
* ------------------------------------------------------------------------------
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* ## License: Contributed Code ------------------------------------------------
|
||||
*
|
||||
|
@ -73,7 +73,7 @@
|
|||
* --
|
||||
*
|
||||
* "I dedicate any and all copyright interest in this software to the three
|
||||
* license terms listed above. I make this dedication for the benefit of the
|
||||
* licensing terms listed above. I make this dedication for the benefit of the
|
||||
* public at large and to the detriment of my heirs and successors. I intend
|
||||
* this dedication to be an overt act of relinquishment in perpetuity of all
|
||||
* present and future rights to this software under copyright law."
|
||||
|
@ -325,6 +325,8 @@ extern "C" {
|
|||
#define VA_SELECT_10TH(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, ...) A10
|
||||
// VA_SPLIT() expands to A) 1 item OR B) 1 item + ',' + va_args[1..N]
|
||||
#define VA_SPLIT(...) VA_FIRST(__VA_ARGS__) VA_REST(__VA_ARGS__)
|
||||
// VA_COUNT() counts number of va args
|
||||
#define VA_COUNT(...) (int)(sizeof((int[]){0, ##__VA_ARGS__})/sizeof(int)-1)
|
||||
|
||||
#if is(cl) && !is(cpp)
|
||||
#define INLINE __inline
|
||||
|
@ -1820,6 +1822,8 @@ API int* engine_geti(const char *key);
|
|||
API char** engine_gets(const char *key);
|
||||
API int engine_send(const char *cmd, const char *optional_value);
|
||||
|
||||
API int ui_debug();
|
||||
|
||||
// open file dialog
|
||||
|
||||
API char* dialog_load();
|
||||
|
@ -2760,6 +2764,8 @@ API int64_t client_join(const char *ip, int port);
|
|||
#endif
|
||||
|
||||
#define OBJHEADER \
|
||||
struct { \
|
||||
ifdef(debug, const char *objname;) \
|
||||
union { \
|
||||
uintptr_t objheader; \
|
||||
struct { \
|
||||
|
@ -2771,10 +2777,12 @@ API int64_t client_join(const char *ip, int port);
|
|||
uintptr_t objunused:64-8-8-8-1-1-ID_INDEX_BITS-ID_COUNT_BITS; /*19*/ \
|
||||
uintptr_t objid:ID_INDEX_BITS+ID_COUNT_BITS; /*16+3*/ \
|
||||
}; \
|
||||
}; \
|
||||
array(struct obj*) objchildren; \
|
||||
};
|
||||
|
||||
#define OBJ \
|
||||
struct { OBJHEADER ifdef(debug,const char *objname;) };
|
||||
OBJHEADER
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// syntax sugars
|
||||
|
@ -2823,6 +2831,9 @@ API int64_t client_join(const char *ip, int port);
|
|||
// OBJTYPEDEF(entity,1)
|
||||
typedef struct entity { ENTITY } entity;
|
||||
|
||||
#define entity_new(TYPE, ...) OBJ_CTOR(TYPE, #TYPE, 1, 0, __VA_ARGS__)
|
||||
#define entity_new_ext(TYPE, NAME, ...) OBJ_CTOR(TYPE, NAME, 1, 0, __VA_ARGS__)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// heap/stack ctor/dtor
|
||||
|
||||
|
@ -2837,16 +2848,16 @@ static __thread obj *objtmp;
|
|||
obj_ctor(PTR))
|
||||
#define OBJ_CTOR(TYPE, NAME, HEAP, PAYLOAD_SIZE, ...) (TYPE*)( \
|
||||
objtmp = (HEAP ? MALLOC(sizeof(TYPE)+(PAYLOAD_SIZE)) : ALLOCA(sizeof(TYPE)+(PAYLOAD_SIZE))), \
|
||||
*(TYPE*)objtmp = ((TYPE){ {0}, __VA_ARGS__}), \
|
||||
*(TYPE*)objtmp = ((TYPE){ {0,}, __VA_ARGS__}), \
|
||||
((PAYLOAD_SIZE) ? memset((char*)objtmp + sizeof(TYPE), 0, (PAYLOAD_SIZE)) : objtmp), \
|
||||
( OBJTYPES[ OBJTYPE(TYPE) ] = #TYPE ), \
|
||||
OBJ_CTOR_PTR(objtmp, HEAP,sizeof(TYPE),OBJTYPE(TYPE)), \
|
||||
ifdef(debug, (obj_printf)(objtmp, va("%s", callstack(+16))), 0), \
|
||||
obj_setname(objtmp, NAME))
|
||||
|
||||
#define obj(TYPE, ...) *OBJ_CTOR(TYPE, #TYPE, 0, sizeof(array(obj*)), __VA_ARGS__)
|
||||
#define obj_new(TYPE, ...) OBJ_CTOR(TYPE, #TYPE, 1, sizeof(array(obj*)), __VA_ARGS__)
|
||||
#define obj_new_ext(TYPE, NAME, ...) OBJ_CTOR(TYPE, NAME, 1, sizeof(array(obj*)), __VA_ARGS__)
|
||||
#define obj(TYPE, ...) *OBJ_CTOR(TYPE, #TYPE, 0, 0, __VA_ARGS__)
|
||||
#define obj_new(TYPE, ...) OBJ_CTOR(TYPE, #TYPE, 1, 0, __VA_ARGS__)
|
||||
#define obj_new_ext(TYPE, NAME, ...) OBJ_CTOR(TYPE, NAME, 1, 0, __VA_ARGS__)
|
||||
|
||||
void* obj_malloc(unsigned sz);
|
||||
void* obj_free(void *o);
|
||||
|
@ -3001,12 +3012,12 @@ API int obj_pop(void *o);
|
|||
// ----------------------------------------------------------------------------
|
||||
// components
|
||||
|
||||
API bool obj_addcomponent(void *object, unsigned c, void *ptr);
|
||||
API bool obj_hascomponent(void *object, unsigned c);
|
||||
API void* obj_getcomponent(void *object, unsigned c);
|
||||
API bool obj_delcomponent(void *object, unsigned c);
|
||||
API bool obj_usecomponent(void *object, unsigned c);
|
||||
API bool obj_offcomponent(void *object, unsigned c);
|
||||
API bool obj_addcomponent(entity *e, unsigned c, void *ptr);
|
||||
API bool obj_hascomponent(entity *e, unsigned c);
|
||||
API void* obj_getcomponent(entity *e, unsigned c);
|
||||
API bool obj_delcomponent(entity *e, unsigned c);
|
||||
API bool obj_usecomponent(entity *e, unsigned c);
|
||||
API bool obj_offcomponent(entity *e, unsigned c);
|
||||
|
||||
API char* entity_save(entity *self);
|
||||
|
||||
|
@ -3022,7 +3033,7 @@ API char* entity_save(entity *self);
|
|||
|
||||
API void* obj_clone(const void *src);
|
||||
API void* obj_merge(void *dst, const void *src); // @testme
|
||||
API void* obj_mutate(void **dst, const void *src);
|
||||
API void* obj_mutate(void *dst, const void *src);
|
||||
API void* obj_make(const char *str);
|
||||
|
||||
// built-ins
|
||||
|
@ -4380,6 +4391,7 @@ API int ui_hover(); // ui_is_hover()?
|
|||
API int ui_active(); // ui_is_active()?
|
||||
|
||||
API int ui_demo(int do_windows);
|
||||
API void *ui_handle();
|
||||
#line 0
|
||||
|
||||
#line 1 "engine/split/v4k_video.h"
|
||||
|
|
Loading…
Reference in New Issue