tooltip feature
parent
31cf65ad50
commit
c8b21e86b5
|
@ -0,0 +1,3 @@
|
||||||
|
@echo off
|
||||||
|
call win\setup_cl_generic.bat amd64
|
||||||
|
cmake --build build && build\eco2d
|
|
@ -3,6 +3,8 @@
|
||||||
#include "world/blocks.h"
|
#include "world/blocks.h"
|
||||||
#include "models/items.h"
|
#include "models/items.h"
|
||||||
|
|
||||||
|
extern void tooltip_show(const char* name, float xpos, float ypos);
|
||||||
|
|
||||||
void ToolAssetInspector(void) {
|
void ToolAssetInspector(void) {
|
||||||
if (nk_begin(dev_ui, "Asset Inspector", nk_rect(400, 100, 240, 800),
|
if (nk_begin(dev_ui, "Asset Inspector", nk_rect(400, 100, 240, 800),
|
||||||
NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE| NK_WINDOW_TITLE))
|
NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE| NK_WINDOW_TITLE))
|
||||||
|
@ -16,6 +18,11 @@ void ToolAssetInspector(void) {
|
||||||
nk_labelf(dev_ui, NK_TEXT_LEFT, "kind: %s", asset_kind_name);
|
nk_labelf(dev_ui, NK_TEXT_LEFT, "kind: %s", asset_kind_name);
|
||||||
nk_labelf(dev_ui, NK_TEXT_LEFT, "spawnable entity: %s", entity_spawn_provided(i) ? "true" : "false");
|
nk_labelf(dev_ui, NK_TEXT_LEFT, "spawnable entity: %s", entity_spawn_provided(i) ? "true" : "false");
|
||||||
|
|
||||||
|
if (nk_button_label(dev_ui, "show tooltip")) {
|
||||||
|
Vector2 mpos = GetMousePosition();
|
||||||
|
tooltip_show(asset_names[i] , mpos.x + 5, mpos.y + 5);
|
||||||
|
}
|
||||||
|
|
||||||
// draw block
|
// draw block
|
||||||
block_id blk_id = blocks_find(i);
|
block_id blk_id = blocks_find(i);
|
||||||
if (blk_id != 0xF) {
|
if (blk_id != 0xF) {
|
||||||
|
|
|
@ -95,8 +95,8 @@ inv_draw_result inventory_draw_crafting_btn(float xpos, float ypos, const char *
|
||||||
recipe rp = craft_get_recipe_data(craft_get_recipe_id_from_product(id));
|
recipe rp = craft_get_recipe_data(craft_get_recipe_id_from_product(id));
|
||||||
int num_reagents = 0;
|
int num_reagents = 0;
|
||||||
for (int i = 0; rp.reagents[i].id; i++) num_reagents++;
|
for (int i = 0; rp.reagents[i].id; i++) num_reagents++;
|
||||||
if (nk_begin(game_ui , name, nk_rect(mpos.x+15, mpos.y+15, name_width+5, 30+30*(float)num_reagents),
|
if (nk_begin(game_ui , name, nk_rect(mpos.x+15, mpos.y+15, name_width+5, 600),
|
||||||
NK_WINDOW_BORDER | NK_WINDOW_NO_INPUT | NK_WINDOW_NO_SCROLLBAR)) {
|
NK_WINDOW_BORDER | NK_WINDOW_NO_INPUT | NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_DYNAMIC)) {
|
||||||
if (nk_tree_push_id(game_ui, NK_TREE_NODE, "Reagents", NK_MAXIMIZED, id)) {
|
if (nk_tree_push_id(game_ui, NK_TREE_NODE, "Reagents", NK_MAXIMIZED, id)) {
|
||||||
for (asset_id i = 0; rp.reagents[i].id; i++) {
|
for (asset_id i = 0; rp.reagents[i].id; i++) {
|
||||||
nk_label(game_ui, asset_names[rp.reagents[i].id], NK_TEXT_LEFT);
|
nk_label(game_ui, asset_names[rp.reagents[i].id], NK_TEXT_LEFT);
|
||||||
|
|
|
@ -0,0 +1,170 @@
|
||||||
|
// Tooltip system with multilevel modal support
|
||||||
|
|
||||||
|
typedef struct _tooltip {
|
||||||
|
const char *name;
|
||||||
|
const char *content;
|
||||||
|
const char **links;
|
||||||
|
} tooltip;
|
||||||
|
|
||||||
|
static tooltip *tooltips = 0;
|
||||||
|
|
||||||
|
//~ registration
|
||||||
|
|
||||||
|
void tooltip_register(tooltip desc) {
|
||||||
|
if (!tooltips) {
|
||||||
|
zpl_array_init(tooltips, zpl_heap());
|
||||||
|
}
|
||||||
|
|
||||||
|
desc.links = 0;
|
||||||
|
zpl_array_append(tooltips, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tooltip_destroy_all(void) {
|
||||||
|
if (!tooltips) return;
|
||||||
|
|
||||||
|
for (zpl_isize i = 0; i < zpl_array_count(tooltips); ++i) {
|
||||||
|
tooltip *tp = (tooltips + i);
|
||||||
|
|
||||||
|
if (tp->links) {
|
||||||
|
zpl_array_free(tp->links);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zpl_array_free(tooltips);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tooltip_build_links(void) {
|
||||||
|
for (zpl_isize i = 0; i < zpl_array_count(tooltips); ++i) {
|
||||||
|
tooltip *tp = (tooltips + i);
|
||||||
|
|
||||||
|
for (zpl_isize j = 0; j < zpl_array_count(tooltips); ++j) {
|
||||||
|
tooltip *linked_tp = (tooltips + j);
|
||||||
|
if (tp == linked_tp)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strstr(tp->content, linked_tp->name)) {
|
||||||
|
if (!tp->links) {
|
||||||
|
zpl_array_init(tp->links, zpl_heap());
|
||||||
|
}
|
||||||
|
|
||||||
|
zpl_array_append(tp->links, linked_tp->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tooltip_register_defaults(void) {
|
||||||
|
// test
|
||||||
|
tooltip_register( (tooltip) { .name = "ASSET_WOOD", .content = "Used as a building material or fuel for the ASSET_FURNACE." } );
|
||||||
|
tooltip_register( (tooltip) { .name = "ASSET_FURNACE", .content = "Producer used to smelt ASSET_IRON_ORE into ASSET_IRON_INGOT." } );
|
||||||
|
tooltip_register( (tooltip) { .name = "ASSET_IRON_ORE", .content = "Natural resource that can be smelted in ASSET_FURNACE." } );
|
||||||
|
tooltip_register( (tooltip) { .name = "ASSET_IRON_INGOT", .content = "Used as a building material. It is smelted from ASSET_IRON_ORE" } );
|
||||||
|
}
|
||||||
|
|
||||||
|
//~ rendering
|
||||||
|
|
||||||
|
#define TOOLTIP_MOUSE_DIST 400.0f
|
||||||
|
|
||||||
|
typedef struct _tooltip_node {
|
||||||
|
float xpos, ypos;
|
||||||
|
tooltip *desc;
|
||||||
|
struct _tooltip_node *next;
|
||||||
|
} tooltip_node;
|
||||||
|
|
||||||
|
static tooltip_node main_tooltip = { 0 };
|
||||||
|
static bool tooltip__should_stay_open = false;
|
||||||
|
|
||||||
|
tooltip *tooltip__find_desc(const char *name) {
|
||||||
|
for (zpl_isize i = 0; i < zpl_array_count(tooltips); ++i) {
|
||||||
|
tooltip *tp = (tooltips + i);
|
||||||
|
|
||||||
|
if (!strcmp(tp->name, name))
|
||||||
|
return tp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tooltip_show(const char* name, float xpos, float ypos) {
|
||||||
|
if (!tooltips) return;
|
||||||
|
|
||||||
|
tooltip *desc = tooltip__find_desc(name);
|
||||||
|
if (!name) return;
|
||||||
|
|
||||||
|
main_tooltip = (tooltip_node) {
|
||||||
|
.xpos = xpos,
|
||||||
|
.ypos = ypos,
|
||||||
|
.desc = desc,
|
||||||
|
.next = 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void tooltip__clear_node(tooltip_node *node) {
|
||||||
|
if (node->next) {
|
||||||
|
tooltip__clear_node(node->next);
|
||||||
|
zpl_mfree(node->next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tooltip_clear(void) {
|
||||||
|
tooltip__clear_node(&main_tooltip);
|
||||||
|
main_tooltip = (tooltip_node) {0};
|
||||||
|
}
|
||||||
|
|
||||||
|
void tooltip__draw_node(tooltip_node *node) {
|
||||||
|
if (!node) return;
|
||||||
|
|
||||||
|
tooltip *desc = node->desc;
|
||||||
|
Vector2 mpos = GetMousePosition();
|
||||||
|
|
||||||
|
if (nk_begin_titled(game_ui, zpl_bprintf("%d%s", (int)node->xpos, desc->name), desc->name, nk_rect(node->xpos, node->ypos, 300, 1200),
|
||||||
|
NK_WINDOW_BORDER | NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_DYNAMIC | NK_WINDOW_TITLE | NK_WINDOW_MOVABLE)) {
|
||||||
|
nk_layout_row_dynamic(game_ui, 30, 1);
|
||||||
|
nk_label_wrap(game_ui, desc->content);
|
||||||
|
|
||||||
|
if (desc->links) {
|
||||||
|
nk_label(game_ui, "See Also:", NK_TEXT_LEFT);
|
||||||
|
nk_layout_row_dynamic(game_ui, 10, 2);
|
||||||
|
|
||||||
|
for (zpl_isize i = 0; i < zpl_array_count(desc->links); ++i) {
|
||||||
|
// todo styling
|
||||||
|
if (nk_button_label(game_ui, desc->links[i])) {
|
||||||
|
if (node->next) tooltip__clear_node(node->next);
|
||||||
|
if (!node->next) node->next = zpl_malloc(sizeof(tooltip_node));
|
||||||
|
*node->next = (tooltip_node) {
|
||||||
|
.xpos = mpos.x+5,
|
||||||
|
.ypos = mpos.y+5,
|
||||||
|
.desc = tooltip__find_desc(desc->links[i]),
|
||||||
|
.next = 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// suggest closing tooltip
|
||||||
|
struct nk_vec2 wpos = nk_window_get_position(game_ui);
|
||||||
|
Vector2 tp_pos = (Vector2) { .x = wpos.x, .y = wpos.y };
|
||||||
|
if (Vector2Distance(mpos, tp_pos) <= TOOLTIP_MOUSE_DIST) {
|
||||||
|
tooltip__should_stay_open = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nk_end(game_ui);
|
||||||
|
|
||||||
|
// draw nested tooltip
|
||||||
|
if (node->next) {
|
||||||
|
tooltip__draw_node(node->next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tooltip_draw(void) {
|
||||||
|
if (!main_tooltip.desc) return;
|
||||||
|
|
||||||
|
tooltip__draw_node(&main_tooltip);
|
||||||
|
|
||||||
|
if (!tooltip__should_stay_open) {
|
||||||
|
tooltip_clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltip__should_stay_open = false;
|
||||||
|
}
|
|
@ -21,6 +21,8 @@ ZPL_DIAGNOSTIC_POP
|
||||||
#define ARCH_IMPL
|
#define ARCH_IMPL
|
||||||
#include "platform/arch.h"
|
#include "platform/arch.h"
|
||||||
|
|
||||||
|
#include "gui/tooltip.c"
|
||||||
|
|
||||||
#include "renderer.c"
|
#include "renderer.c"
|
||||||
|
|
||||||
void platform_init() {
|
void platform_init() {
|
||||||
|
|
|
@ -26,6 +26,7 @@ ZPL_DIAGNOSTIC_POP
|
||||||
#include "renderer.c"
|
#include "renderer.c"
|
||||||
|
|
||||||
// NOTE(zaklaus): add-ins
|
// NOTE(zaklaus): add-ins
|
||||||
|
#include "gui/tooltip.c"
|
||||||
#include "gui/build_mode.c"
|
#include "gui/build_mode.c"
|
||||||
#include "gui/inventory.c"
|
#include "gui/inventory.c"
|
||||||
|
|
||||||
|
@ -34,6 +35,20 @@ void platform_init() {
|
||||||
renderer_init();
|
renderer_init();
|
||||||
|
|
||||||
target_zoom = 2.70f;
|
target_zoom = 2.70f;
|
||||||
|
|
||||||
|
tooltip_register_defaults();
|
||||||
|
|
||||||
|
// room for game-specific tooltips
|
||||||
|
|
||||||
|
tooltip_build_links();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// TEST
|
||||||
|
{
|
||||||
|
Vector2 mpos = GetMousePosition();
|
||||||
|
tooltip_show("ASSET_FURNACE", mpos.x, mpos.y);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static
|
inline static
|
||||||
|
@ -51,6 +66,7 @@ void display_conn_status() {
|
||||||
|
|
||||||
void platform_shutdown() {
|
void platform_shutdown() {
|
||||||
renderer_shutdown();
|
renderer_shutdown();
|
||||||
|
tooltip_destroy_all();
|
||||||
CloseWindow();
|
CloseWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,6 +203,9 @@ void platform_render() {
|
||||||
// NOTE(zaklaus): add-ins
|
// NOTE(zaklaus): add-ins
|
||||||
buildmode_draw();
|
buildmode_draw();
|
||||||
inventory_draw();
|
inventory_draw();
|
||||||
|
|
||||||
|
// goes last
|
||||||
|
tooltip_draw();
|
||||||
}
|
}
|
||||||
display_conn_status();
|
display_conn_status();
|
||||||
debug_draw();
|
debug_draw();
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<RunCommand></RunCommand>
|
<RunCommand></RunCommand>
|
||||||
<DebugCommand></DebugCommand>
|
<DebugCommand></DebugCommand>
|
||||||
<ExePathCommand></ExePathCommand>
|
<ExePathCommand></ExePathCommand>
|
||||||
<DebugSln></DebugSln>
|
<DebugSln>build\eco2d.sln</DebugSln>
|
||||||
<UseVisualStudioEnvBat>false</UseVisualStudioEnvBat>
|
<UseVisualStudioEnvBat>false</UseVisualStudioEnvBat>
|
||||||
<Configurations>
|
<Configurations>
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
|
|
Loading…
Reference in New Issue