2007-11-25 19:42:40 +00:00
|
|
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
2007-08-22 07:52:33 +00:00
|
|
|
#include <engine/system.h>
|
2007-05-24 20:54:08 +00:00
|
|
|
#include <engine/interface.h>
|
2007-10-29 18:40:04 +00:00
|
|
|
#include <engine/config.h>
|
2007-05-22 15:03:32 +00:00
|
|
|
#include "ui.h"
|
|
|
|
|
|
|
|
/********************************************************
|
|
|
|
UI
|
|
|
|
*********************************************************/
|
|
|
|
|
|
|
|
struct pretty_font
|
|
|
|
{
|
2007-06-10 20:00:58 +00:00
|
|
|
float m_CharStartTable[256];
|
|
|
|
float m_CharEndTable[256];
|
2007-05-22 15:03:32 +00:00
|
|
|
int font_texture;
|
|
|
|
};
|
|
|
|
|
2007-08-22 07:52:33 +00:00
|
|
|
extern struct pretty_font *current_font;
|
2007-05-22 15:03:32 +00:00
|
|
|
|
2007-11-04 21:36:03 +00:00
|
|
|
static const void *hot_item = 0;
|
|
|
|
static const void *active_item = 0;
|
|
|
|
static const void *last_active_item = 0;
|
|
|
|
static const void *becomming_hot_item = 0;
|
2007-10-06 17:01:06 +00:00
|
|
|
static float mouse_x, mouse_y; /* in gui space */
|
|
|
|
static float mouse_wx, mouse_wy; /* in world space */
|
2007-05-22 15:03:32 +00:00
|
|
|
static unsigned mouse_buttons = 0;
|
|
|
|
|
|
|
|
float ui_mouse_x() { return mouse_x; }
|
|
|
|
float ui_mouse_y() { return mouse_y; }
|
|
|
|
float ui_mouse_world_x() { return mouse_wx; }
|
|
|
|
float ui_mouse_world_y() { return mouse_wy; }
|
|
|
|
int ui_mouse_button(int index) { return (mouse_buttons>>index)&1; }
|
|
|
|
|
2007-11-04 21:36:03 +00:00
|
|
|
void ui_set_hot_item(const void *id) { becomming_hot_item = id; }
|
|
|
|
void ui_set_active_item(const void *id) { active_item = id; if (id) last_active_item = id; }
|
2007-07-21 16:33:01 +00:00
|
|
|
void ui_clear_last_active_item() { last_active_item = 0; }
|
2007-11-04 21:36:03 +00:00
|
|
|
const void *ui_hot_item() { return hot_item; }
|
|
|
|
const void *ui_active_item() { return active_item; }
|
|
|
|
const void *ui_last_active_item() { return last_active_item; }
|
2007-05-22 15:03:32 +00:00
|
|
|
|
|
|
|
int ui_update(float mx, float my, float mwx, float mwy, int buttons)
|
|
|
|
{
|
|
|
|
mouse_x = mx;
|
|
|
|
mouse_y = my;
|
|
|
|
mouse_wx = mwx;
|
|
|
|
mouse_wy = mwy;
|
|
|
|
mouse_buttons = buttons;
|
|
|
|
hot_item = becomming_hot_item;
|
2007-07-20 22:19:40 +00:00
|
|
|
if(active_item)
|
|
|
|
hot_item = active_item;
|
2007-05-22 15:03:32 +00:00
|
|
|
becomming_hot_item = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ui_mouse_inside(float x, float y, float w, float h)
|
|
|
|
{
|
|
|
|
if(mouse_x >= x && mouse_x <= x+w && mouse_y >= y && mouse_y <= y+h)
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ui_do_image(int texture, float x, float y, float w, float h)
|
|
|
|
{
|
|
|
|
gfx_blend_normal();
|
|
|
|
gfx_texture_set(texture);
|
|
|
|
gfx_quads_begin();
|
2007-09-23 18:27:04 +00:00
|
|
|
gfx_setcolor(1,1,1,1);
|
2007-05-22 15:03:32 +00:00
|
|
|
gfx_quads_setsubset(
|
2007-10-06 17:01:06 +00:00
|
|
|
0.0f, /* startx */
|
|
|
|
0.0f, /* starty */
|
|
|
|
1.0f, /* endx */
|
|
|
|
1.0f); /* endy */
|
2007-05-22 15:03:32 +00:00
|
|
|
gfx_quads_drawTL(x,y,w,h);
|
|
|
|
gfx_quads_end();
|
|
|
|
}
|
|
|
|
|
2007-06-01 02:21:46 +00:00
|
|
|
void ui_do_label(float x, float y, const char *text, float size)
|
2007-05-22 15:03:32 +00:00
|
|
|
{
|
|
|
|
gfx_blend_normal();
|
|
|
|
gfx_texture_set(current_font->font_texture);
|
2007-08-22 07:52:33 +00:00
|
|
|
gfx_pretty_text(x, y, size, text, -1);
|
2007-05-22 15:03:32 +00:00
|
|
|
}
|
|
|
|
|
2007-11-04 21:36:03 +00:00
|
|
|
int ui_do_button(const void *id, const char *text, int checked, float x, float y, float w, float h, draw_button_callback draw_func, void *extra)
|
2007-05-22 15:03:32 +00:00
|
|
|
{
|
2007-10-06 17:01:06 +00:00
|
|
|
/* logic */
|
2007-05-22 15:03:32 +00:00
|
|
|
int r = 0;
|
|
|
|
int inside = ui_mouse_inside(x,y,w,h);
|
|
|
|
|
2007-07-20 22:19:40 +00:00
|
|
|
if(ui_active_item() == id)
|
2007-05-22 15:03:32 +00:00
|
|
|
{
|
2007-07-20 22:19:40 +00:00
|
|
|
if(!ui_mouse_button(0))
|
|
|
|
{
|
|
|
|
if(inside)
|
|
|
|
r = 1;
|
|
|
|
ui_set_active_item(0);
|
|
|
|
}
|
2007-05-22 15:03:32 +00:00
|
|
|
}
|
2007-07-20 22:19:40 +00:00
|
|
|
else if(ui_hot_item() == id)
|
2007-05-22 15:03:32 +00:00
|
|
|
{
|
2007-07-20 22:19:40 +00:00
|
|
|
if(ui_mouse_button(0))
|
|
|
|
ui_set_active_item(id);
|
2007-05-22 15:03:32 +00:00
|
|
|
}
|
2007-07-20 22:19:40 +00:00
|
|
|
|
|
|
|
if(inside)
|
|
|
|
ui_set_hot_item(id);
|
2007-05-27 18:14:24 +00:00
|
|
|
|
2007-05-22 15:03:32 +00:00
|
|
|
draw_func(id, text, checked, x, y, w, h, extra);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2007-10-29 18:40:04 +00:00
|
|
|
static float scale = 1.0f;
|
|
|
|
#define MEMORY_SIZE 10*1024
|
|
|
|
static struct rect memory[MEMORY_SIZE];
|
|
|
|
static int memory_used = 0;
|
|
|
|
static struct rect screen = { 0.0f, 0.0f, 800.0f, 600.0f };
|
|
|
|
|
|
|
|
void ui_foreach_rect(rect_fun fun)
|
|
|
|
{
|
|
|
|
int hrm;
|
|
|
|
for (hrm = 0; hrm < memory_used; hrm++)
|
|
|
|
fun(&memory[hrm]);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void add_rect(struct rect *r)
|
|
|
|
{
|
|
|
|
if (memory_used < MEMORY_SIZE)
|
|
|
|
memory[memory_used++] = *r;
|
|
|
|
else
|
|
|
|
dbg_msg("ui", "rect memory full.");
|
|
|
|
}
|
|
|
|
|
|
|
|
struct rect *ui_screen()
|
|
|
|
{
|
|
|
|
if (config.debug)
|
|
|
|
{
|
|
|
|
memory_used = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return &screen;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ui_scale(float s)
|
|
|
|
{
|
|
|
|
scale = s;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ui_hsplit_t(const struct rect *original, int pixels, struct rect *top, struct rect *bottom)
|
|
|
|
{
|
|
|
|
struct rect r = *original;
|
|
|
|
pixels *= scale;
|
|
|
|
|
|
|
|
if (top)
|
|
|
|
{
|
|
|
|
top->x = r.x;
|
|
|
|
top->y = r.y;
|
|
|
|
top->w = r.w;
|
|
|
|
top->h = pixels;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bottom)
|
|
|
|
{
|
|
|
|
bottom->x = r.x;
|
|
|
|
bottom->y = r.y + pixels;
|
|
|
|
bottom->w = r.w;
|
|
|
|
bottom->h = r.h - pixels;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config.debug)
|
|
|
|
{
|
|
|
|
if (top)
|
|
|
|
add_rect(top);
|
|
|
|
if (bottom)
|
|
|
|
add_rect(bottom);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ui_hsplit_b(const struct rect *original, int pixels, struct rect *top, struct rect *bottom)
|
|
|
|
{
|
|
|
|
struct rect r = *original;
|
|
|
|
pixels *= scale;
|
|
|
|
|
|
|
|
if (top)
|
|
|
|
{
|
|
|
|
top->x = r.x;
|
|
|
|
top->y = r.y;
|
|
|
|
top->w = r.w;
|
|
|
|
top->h = r.h - pixels;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bottom)
|
|
|
|
{
|
|
|
|
bottom->x = r.x;
|
|
|
|
bottom->y = r.y + r.h - pixels;
|
|
|
|
bottom->w = r.w;
|
|
|
|
bottom->h = pixels;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config.debug)
|
|
|
|
{
|
|
|
|
if (top)
|
|
|
|
add_rect(top);
|
|
|
|
if (bottom)
|
|
|
|
add_rect(bottom);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ui_vsplit_l(const struct rect *original, int pixels, struct rect *left, struct rect *right)
|
|
|
|
{
|
|
|
|
struct rect r = *original;
|
|
|
|
pixels *= scale;
|
|
|
|
|
|
|
|
if (left)
|
|
|
|
{
|
|
|
|
left->x = r.x;
|
|
|
|
left->y = r.y;
|
|
|
|
left->w = pixels;
|
|
|
|
left->h = r.h;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (right)
|
|
|
|
{
|
|
|
|
right->x = r.x + pixels;
|
|
|
|
right->y = r.y;
|
|
|
|
right->w = r.w - pixels;
|
|
|
|
right->h = r.h;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config.debug)
|
|
|
|
{
|
|
|
|
if (left)
|
|
|
|
add_rect(left);
|
|
|
|
if (right)
|
|
|
|
add_rect(right);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ui_vsplit_r(const struct rect *original, int pixels, struct rect *left, struct rect *right)
|
|
|
|
{
|
|
|
|
struct rect r = *original;
|
|
|
|
pixels *= scale;
|
|
|
|
|
|
|
|
if (left)
|
|
|
|
{
|
|
|
|
left->x = r.x;
|
|
|
|
left->y = r.y;
|
|
|
|
left->w = r.w - pixels;
|
|
|
|
left->h = r.h;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (right)
|
|
|
|
{
|
|
|
|
right->x = r.x + r.w - pixels;
|
|
|
|
right->y = r.y;
|
|
|
|
right->w = pixels;
|
|
|
|
right->h = r.h;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config.debug)
|
|
|
|
{
|
|
|
|
if (left)
|
|
|
|
add_rect(left);
|
|
|
|
if (right)
|
|
|
|
add_rect(right);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ui_margin(const struct rect *original, int pixels, struct rect *other_rect)
|
|
|
|
{
|
|
|
|
struct rect r = *original;
|
|
|
|
pixels *= scale;
|
|
|
|
|
|
|
|
other_rect->x = r.x + pixels;
|
|
|
|
other_rect->y = r.y + pixels;
|
|
|
|
other_rect->w = r.w - 2*pixels;
|
|
|
|
other_rect->h = r.h - 2*pixels;
|
|
|
|
}
|