new render target class while working on the exhibit UI
[laserbrain_demo] / src / ui_exhibit.cc
index 355d078..eda39c6 100644 (file)
@@ -1,26 +1,43 @@
+#include <drawtext.h>
 #include "ui_exhibit.h"
 #include "ui.h"
 #include "app.h"
 #include "ui_exhibit.h"
 #include "ui.h"
 #include "app.h"
-#include <drawtext.h>
+#include "snode.h"
+#include "shader.h"
 
 
-static void draw_titlebar();
-static void draw_tabs();
+struct Rect {
+       float x, y, w, h;
+};
+
+static void draw_frame(const Rect &rect);
+static void draw_titlebar(const Rect &rect);
+static void draw_tabs(const Rect &rect);
+static void draw_text(const Rect &rect);
 static void layout_text(const char *text);
 
 static void layout_text(const char *text);
 
+static const SceneNode *parent;
 static Vec3 pos;
 static Vec2 size;
 static float text_padding;
 static Vec3 pos;
 static Vec2 size;
 static float text_padding;
+static float text_scale = 0.05f;
 static Exhibit *ex;
 static int vis_tab;
 static float scroll;
 static std::vector<const char*> text_lines;
 static AudioStream *voice;
 
 static Exhibit *ex;
 static int vis_tab;
 static float scroll;
 static std::vector<const char*> text_lines;
 static AudioStream *voice;
 
+enum {COL_BG, COL_FG, COL_FRM};
+static float color[][3] = {
+       {0.09, 0.14, 0.2},      // COL_BG
+       {0.31, 0.58, 0.9},      // COL_FG
+       {0.19, 0.23, 0.46}      // COL_FRM
+};
+
 
 bool exui_init()
 {
 
 bool exui_init()
 {
-       size.x = 150;
-       size.y = 180;
+       size.x = 15;
+       size.y = 18;
        text_padding = size.x * 0.01;
 
        return true;
        text_padding = size.x * 0.01;
 
        return true;
@@ -30,6 +47,11 @@ void exui_shutdown()
 {
 }
 
 {
 }
 
+void exui_setnode(const SceneNode *node)
+{
+       parent = node;
+}
+
 void exui_change_tab(int dir)
 {
 }
 void exui_change_tab(int dir)
 {
 }
@@ -73,16 +95,91 @@ void exui_update(float dt)
 void exui_draw()
 {
        if(!exsel_active) return;
 void exui_draw()
 {
        if(!exsel_active) return;
+       if(!ui_font) return;
 
 
-       draw_titlebar();
-       draw_tabs();
+       dtx_use_font(ui_font, ui_font_size);
+       float rowspc = dtx_line_height() * text_scale;
+
+       Rect rect = {-size.x / 2.0f, -size.y / 2.0f, size.x, size.y};
+
+       glMatrixMode(GL_MODELVIEW);
+       glPushMatrix();
+       if(parent) {
+               glMultMatrixf(parent->get_matrix()[0]);
+       }
+       glTranslatef(pos.x, pos.y, pos.z);
+       glScalef(1, -1, 1);
+
+       bind_shader(0);
+
+       glPushAttrib(GL_ENABLE_BIT);
+       glDisable(GL_TEXTURE_2D);
+       glDisable(GL_LIGHTING);
+       glEnable(GL_BLEND);
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+       glDepthMask(0);
+
+       draw_frame(rect);
+       Rect tbar_rect = {rect.x, rect.y, rect.w, rowspc};
+       draw_titlebar(tbar_rect);
+       Rect tabs_rect = {tbar_rect.x, tbar_rect.y + rowspc, tbar_rect.w, tbar_rect.h};
+       draw_tabs(tabs_rect);
+       Rect text_rect = {rect.x, tabs_rect.y + rowspc, rect.w, rect.h - tabs_rect.y - rowspc};
+       draw_text(text_rect);
+
+       glDepthMask(1);
+       glPopAttrib();
+
+       glPopMatrix();
 }
 
 }
 
-static void draw_titlebar()
+static inline float *vrect(const Rect &rect, int i)
 {
 {
+       static float v[2];
+       v[0] = ((i + 1) & 2) ? rect.x + rect.w : rect.x;
+       v[1] = (i & 2) ? rect.y : rect.y + rect.h;
+       return v;
 }
 
 }
 
-static void draw_tabs()
+static inline void draw_rect(const Rect &rect, int col)
+{
+       glBegin(GL_QUADS);
+       glColor3fv(color[col]);
+       for(int i=0; i<4; i++)
+               glVertex2fv(vrect(rect, i));
+       glEnd();
+}
+
+static void draw_frame(const Rect &rect)
+{
+       draw_rect(rect, COL_BG);
+       glLineWidth(2.0);
+       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+       draw_rect(rect, COL_FRM);
+       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+}
+
+static void draw_titlebar(const Rect &rect)
+{
+       draw_rect(rect, COL_FRM);
+
+       const char *title = ex->get_name();
+       if(title) {
+               glPushMatrix();
+               glTranslatef(rect.x + text_padding, rect.y + rect.h - text_padding, 0);
+               glScalef(text_scale, -text_scale, text_scale);
+
+               glColor3fv(color[COL_BG]);
+               dtx_string(ex->get_name());
+               glPopMatrix();
+       }
+}
+
+static void draw_tabs(const Rect &rect)
+{
+}
+
+static void draw_text(const Rect &rect)
 {
 }
 
 {
 }
 
@@ -109,7 +206,11 @@ static void layout_text(const char *text)
 
                int code = dtx_utf8_char_code(text);
                const char *next = dtx_utf8_next_char((char*)text);
 
                int code = dtx_utf8_char_code(text);
                const char *next = dtx_utf8_next_char((char*)text);
-               pos += dtx_glyph_width(code);
+               pos += dtx_glyph_width(code) * text_scale;
+
+               if(code < 256 && isspace(code)) {
+                       last_break = text;
+               }
 
                if(pos >= size.x - text_padding) {
                        if(text == text_lines.back()) {
 
                if(pos >= size.x - text_padding) {
                        if(text == text_lines.back()) {
@@ -129,4 +230,18 @@ static void layout_text(const char *text)
                }
                text = next;
        }
                }
                text = next;
        }
+       text_lines.push_back(0);
+
+       /*
+       debug_log("text layout:\n");
+       for(size_t i=0; i<text_lines.size() - 1; i++) {
+               const char *p = text_lines[i];
+               while(*p && p != text_lines[i + 1]) {
+                       putchar(*p);
+                       ++p;
+               }
+               putchar('\n');
+       }
+       debug_log("---\n");
+       */
 }
 }