X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=share%2Fgui.c;h=e7d58aa51358423aeaca27930291bf77e5164694;hb=c02ae9f8fce350c74e6ac7d281f03857c44964a7;hp=2b68f9cfa39aa7e80d71264a7bcf19c254dfdad9;hpb=eb47a9d407d86a2b939746eabdc63f6bfec1df00;p=neverball diff --git a/share/gui.c b/share/gui.c index 2b68f9c..e7d58aa 100644 --- a/share/gui.c +++ b/share/gui.c @@ -20,6 +20,7 @@ #include "glext.h" #include "image.h" #include "vec3.h" +#include "text.h" #include "gui.h" /*---------------------------------------------------------------------------*/ @@ -80,7 +81,6 @@ static struct widget widget[MAXWIDGET]; static int active; static int radius; static TTF_Font *font[3] = { NULL, NULL, NULL }; -static int scale[3] = { 1, 1, 1 }; static GLuint digit_text[3][11]; static GLuint digit_list[3][11]; @@ -228,19 +228,6 @@ void gui_init(void) int s0 = s / 26; int s1 = s / 13; int s2 = s / 7; - int m; - - /* Make sure text size doesn't exceed the maximum texture size. */ - - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m); - - scale[0] = 1; - scale[1] = 1; - scale[2] = 1; - - while (s0 > m) { s0 /= 2; scale[0] *= 2; } - while (s1 > m) { s1 /= 2; scale[1] *= 2; } - while (s2 > m) { s2 /= 2; scale[2] *= 2; } memset(widget, 0, sizeof (struct widget) * MAXWIDGET); @@ -267,7 +254,7 @@ void gui_init(void) digit_text[i][j] = make_image_from_font(NULL, NULL, &digit_w[i][j], &digit_h[i][j], - text, font[i], scale[i]); + text, font[i]); digit_list[i][j] = gui_list(-digit_w[i][j] / 2, -digit_h[i][j] / 2, +digit_w[i][j], @@ -279,7 +266,7 @@ void gui_init(void) digit_text[i][j] = make_image_from_font(NULL, NULL, &digit_w[i][10], &digit_h[i][10], - ":", font[i], scale[i]); + ":", font[i]); digit_list[i][j] = gui_list(-digit_w[i][10] / 2, -digit_h[i][10] / 2, +digit_w[i][10], @@ -379,7 +366,7 @@ static int gui_widget(int pd, int type) return id; } - fprintf(stderr, _("Out of widget IDs\n")); + fprintf(stderr, "Out of widget IDs\n"); return 0; } @@ -397,7 +384,7 @@ void gui_set_image(int id, const char *file) if (glIsTexture(widget[id].text_img)) glDeleteTextures(1, &widget[id].text_img); - widget[id].text_img = make_image_from_file(NULL, NULL, NULL, NULL, file); + widget[id].text_img = make_image_from_file(file); } void gui_set_label(int id, const char *text) @@ -410,8 +397,7 @@ void gui_set_label(int id, const char *text) glDeleteLists(widget[id].text_obj, 1); widget[id].text_img = make_image_from_font(NULL, NULL, &w, &h, - text, font[widget[id].size], - scale[widget[id].size]); + text, font[widget[id].size]); widget[id].text_obj = gui_list(-w / 2, -h / 2, w, h, widget[id].color0, widget[id].color1); } @@ -466,10 +452,9 @@ int gui_image(int pd, const char *file, int w, int h) if ((id = gui_widget(pd, GUI_IMAGE))) { - widget[id].text_img = make_image_from_file(NULL, NULL, - NULL, NULL, file); - widget[id].w = w; - widget[id].h = h; + widget[id].text_img = make_image_from_file(file); + widget[id].w = w; + widget[id].h = h; } return id; } @@ -493,8 +478,7 @@ int gui_state(int pd, const char *text, int size, int token, int value) widget[id].text_img = make_image_from_font(NULL, NULL, &widget[id].w, &widget[id].h, - text, font[size], - scale[size]); + text, font[size]); widget[id].size = size; widget[id].token = token; widget[id].value = value; @@ -512,8 +496,7 @@ int gui_label(int pd, const char *text, int size, int rect, const float *c0, widget[id].text_img = make_image_from_font(NULL, NULL, &widget[id].w, &widget[id].h, - text, font[size], - scale[size]); + text, font[size]); widget[id].size = size; widget[id].color0 = c0 ? c0 : gui_yel; widget[id].color1 = c1 ? c1 : gui_red; @@ -1414,122 +1397,174 @@ void gui_toggle(int id) /*---------------------------------------------------------------------------*/ -static int gui_vert_test(int id, int jd) +static int gui_vert_offset(int id, int jd) { - /* Determine whether widget id is in vertical contact with widget jd. */ + /* Vertical offset between bottom of id and top of jd */ - if (id && gui_hot(id) && jd && gui_hot(jd)) - { - int i0 = widget[id].x; - int i1 = widget[id].x + widget[id].w; - int j0 = widget[jd].x; - int j1 = widget[jd].x + widget[jd].w; - - /* Is widget id's top edge is in contact with jd's bottom edge? */ + return widget[id].y - (widget[jd].y + widget[jd].h); +} - if (widget[id].y + widget[id].h == widget[jd].y) - { - /* Do widgets id and jd overlap horizontally? */ +static int gui_horz_offset(int id, int jd) +{ + /* Horizontal offset between left of id and right of jd */ - if (j0 <= i0 && i0 < j1) return 1; - if (j0 < i1 && i1 <= j1) return 1; - if (i0 <= j0 && j0 < i1) return 1; - if (i0 < j1 && j1 <= i1) return 1; - } - } - return 0; + return widget[id].x - (widget[jd].x + widget[jd].w); } -static int gui_horz_test(int id, int jd) +static int gui_vert_dist(int id, int jd) { - /* Determine whether widget id is in horizontal contact with widget jd. */ - - if (id && gui_hot(id) && jd && gui_hot(jd)) - { - int i0 = widget[id].y; - int i1 = widget[id].y + widget[id].h; - int j0 = widget[jd].y; - int j1 = widget[jd].y + widget[jd].h; + /* Vertical distance between the tops of id and jd */ - /* Is widget id's right edge in contact with jd's left edge? */ + return abs((widget[id].y + widget[id].h) - (widget[jd].y + widget[jd].h)); +} - if (widget[id].x + widget[id].w == widget[jd].x) - { - /* Do widgets id and jd overlap vertically? */ +static int gui_horz_dist(int id, int jd) +{ + /* Horizontal distance between the left sides of id and jd */ - if (j0 <= i0 && i0 < j1) return 1; - if (j0 < i1 && i1 <= j1) return 1; - if (i0 <= j0 && j0 < i1) return 1; - if (i0 < j1 && j1 <= i1) return 1; - } - } - return 0; + return abs(widget[id].x - widget[jd].x); } /*---------------------------------------------------------------------------*/ static int gui_stick_L(int id, int dd) { - int jd, kd; + int jd, kd, hd; + int o, omin, d, dmin; - /* Find a widget to the left of widget dd. */ + /* Find the closest "hot" widget to the left of dd (and inside id) */ - if (gui_horz_test(id, dd)) + if (id && gui_hot(id)) return id; + hd = 0; + omin = widget[dd].x - widget[id].x + 1; + dmin = widget[dd].y + widget[dd].h + widget[id].y + widget[id].h; + for (jd = widget[id].car; jd; jd = widget[jd].cdr) - if ((kd = gui_stick_L(jd, dd))) - return kd; + { + kd = gui_stick_L(jd, dd); - return 0; + if (kd && kd != dd) + { + o = gui_horz_offset(dd, kd); + d = gui_vert_dist(dd, kd); + + if (0 <= o && o <= omin && d <= dmin) + { + hd = kd; + omin = o; + dmin = d; + } + } + } + + return hd; } static int gui_stick_R(int id, int dd) { - int jd, kd; + int jd, kd, hd; + int o, omin, d, dmin; - /* Find a widget to the right of widget dd. */ + /* Find the closest "hot" widget to the right of dd (and inside id) */ - if (gui_horz_test(dd, id)) + if (id && gui_hot(id)) return id; + hd = 0; + omin = (widget[id].x + widget[id].w) - (widget[dd].x + widget[dd].w) + 1; + dmin = widget[dd].y + widget[dd].h + widget[id].y + widget[id].h; + for (jd = widget[id].car; jd; jd = widget[jd].cdr) - if ((kd = gui_stick_R(jd, dd))) - return kd; + { + kd = gui_stick_R(jd, dd); - return 0; + if (kd && kd != dd) + { + o = gui_horz_offset(kd, dd); + d = gui_vert_dist(dd, kd); + + if (0 <= o && o <= omin && d <= dmin) + { + hd = kd; + omin = o; + dmin = d; + } + } + } + + return hd; } static int gui_stick_D(int id, int dd) { - int jd, kd; + int jd, kd, hd; + int o, omin, d, dmin; - /* Find a widget below widget dd. */ + /* Find the closest "hot" widget below dd (and inside id) */ - if (gui_vert_test(id, dd)) + if (id && gui_hot(id)) return id; + hd = 0; + omin = widget[dd].y - widget[id].y + 1; + dmin = widget[dd].x + widget[dd].w + widget[id].x + widget[id].w; + for (jd = widget[id].car; jd; jd = widget[jd].cdr) - if ((kd = gui_stick_D(jd, dd))) - return kd; + { + kd = gui_stick_D(jd, dd); - return 0; + if (kd && kd != dd) + { + o = gui_vert_offset(dd, kd); + d = gui_horz_dist(dd, kd); + + if (0 <= o && o <= omin && d <= dmin) + { + hd = kd; + omin = o; + dmin = d; + } + } + } + + return hd; } static int gui_stick_U(int id, int dd) { - int jd, kd; + int jd, kd, hd; + int o, omin, d, dmin; - /* Find a widget above widget dd. */ + /* Find the closest "hot" widget above dd (and inside id) */ - if (gui_vert_test(dd, id)) + if (id && gui_hot(id)) return id; + hd = 0; + omin = (widget[id].y + widget[id].h) - (widget[dd].y + widget[dd].h) + 1; + dmin = widget[dd].x + widget[dd].w + widget[id].x + widget[id].w; + for (jd = widget[id].car; jd; jd = widget[jd].cdr) - if ((kd = gui_stick_U(jd, dd))) - return kd; + { + kd = gui_stick_U(jd, dd); - return 0; + if (kd && kd != dd) + { + o = gui_vert_offset(kd, dd); + d = gui_horz_dist(dd, kd); + + if (0 <= o && o <= omin && d <= dmin) + { + hd = kd; + omin = o; + dmin = d; + } + } + } + + return hd; } /*---------------------------------------------------------------------------*/ @@ -1580,13 +1615,21 @@ static int gui_wrap_D(int id, int dd) /*---------------------------------------------------------------------------*/ -int gui_stick(int id, int x, int y) +/* Flag the axes to prevent uncontrolled scrolling. */ + +static int xflag = 1; +static int yflag = 1; + +void gui_stuck() { - /* Flag the axes to prevent uncontrolled scrolling. */ + /* Force the user to recenter the joystick before the next GUI action. */ - static int xflag = 1; - static int yflag = 1; + xflag = 0; + yflag = 0; +} +int gui_stick(int id, int x, int y) +{ int jd = 0; /* Find a new active widget in the direction of joystick motion. */