2 #include "ui_exhibit.h"
12 static void draw_frame(const Rect &rect);
13 static void draw_titlebar(const Rect &rect);
14 static void draw_tabs(const Rect &rect);
15 static void draw_text(const Rect &rect);
16 static void layout_text(const char *text);
18 static const SceneNode *parent;
21 static float text_padding;
22 static float text_scale = 0.05f;
26 static std::vector<const char*> text_lines;
27 static AudioStream *voice;
29 enum {COL_BG, COL_FG, COL_FRM};
30 static float color[][3] = {
31 {0.09, 0.14, 0.2}, // COL_BG
32 {0.31, 0.58, 0.9}, // COL_FG
33 {0.19, 0.23, 0.46} // COL_FRM
41 text_padding = size.x * 0.01;
50 void exui_setnode(const SceneNode *node)
55 void exui_change_tab(int dir)
59 void exui_scroll(float delta)
63 bool exui_raycast(const Ray &ray)
68 void exui_update(float dt)
70 if(exsel_active.ex != ex) {
75 if(voice) voice->stop();
78 int num_data = ex->data.size();
79 for(int i=0; i<num_data; i++) {
80 if(ex->data[i].type == EXDATA_INFO) {
81 layout_text(ex->data[i].text.c_str());
82 voice = ex->data[i].voice;
87 voice->play(AUDIO_PLAYMODE_ONCE);
97 if(!exsel_active) return;
100 dtx_use_font(ui_font, ui_font_size);
101 float rowspc = dtx_line_height() * text_scale;
103 Rect rect = {-size.x / 2.0f, -size.y / 2.0f, size.x, size.y};
105 glMatrixMode(GL_MODELVIEW);
108 glMultMatrixf(parent->get_matrix()[0]);
110 glTranslatef(pos.x, pos.y, pos.z);
115 glPushAttrib(GL_ENABLE_BIT);
116 glDisable(GL_TEXTURE_2D);
117 glDisable(GL_LIGHTING);
119 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
123 Rect tbar_rect = {rect.x, rect.y, rect.w, rowspc};
124 draw_titlebar(tbar_rect);
125 Rect tabs_rect = {tbar_rect.x, tbar_rect.y + rowspc, tbar_rect.w, tbar_rect.h};
126 draw_tabs(tabs_rect);
127 Rect text_rect = {rect.x, tabs_rect.y + rowspc, rect.w, rect.h - tabs_rect.y - rowspc};
128 draw_text(text_rect);
136 static inline float *vrect(const Rect &rect, int i)
139 v[0] = ((i + 1) & 2) ? rect.x + rect.w : rect.x;
140 v[1] = (i & 2) ? rect.y : rect.y + rect.h;
144 static inline void draw_rect(const Rect &rect, int col)
147 glColor3fv(color[col]);
148 for(int i=0; i<4; i++)
149 glVertex2fv(vrect(rect, i));
153 static void draw_frame(const Rect &rect)
155 draw_rect(rect, COL_BG);
157 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
158 draw_rect(rect, COL_FRM);
159 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
162 static void draw_titlebar(const Rect &rect)
164 draw_rect(rect, COL_FRM);
166 const char *title = ex->get_name();
169 glTranslatef(rect.x + text_padding, rect.y + rect.h - text_padding, 0);
170 glScalef(text_scale, -text_scale, text_scale);
172 glColor3fv(color[COL_BG]);
173 dtx_string(ex->get_name());
178 static void draw_tabs(const Rect &rect)
182 static void draw_text(const Rect &rect)
186 static void layout_text(const char *text)
192 dtx_use_font(ui_font, ui_font_size);
194 float pos = text_padding;
195 text_lines.push_back(text);
196 const char *last_break = 0;
199 if(*text == '\n') { // paragraph break
200 text_lines.push_back(text);
201 text_lines.push_back(++text);
207 int code = dtx_utf8_char_code(text);
208 const char *next = dtx_utf8_next_char((char*)text);
209 pos += dtx_glyph_width(code) * text_scale;
211 if(code < 256 && isspace(code)) {
215 if(pos >= size.x - text_padding) {
216 if(text == text_lines.back()) {
217 // not even a single character fits on a line... abort
218 warning_log("text layout failed. glyph %d doesn't fit in line (%g)\n", code, size.x - 2.0 * text_padding);
223 text_lines.push_back(last_break + 1);
226 // no good point to break, just break here
227 text_lines.push_back(text);
233 text_lines.push_back(0);
236 debug_log("text layout:\n");
237 for(size_t i=0; i<text_lines.size() - 1; i++) {
238 const char *p = text_lines[i];
239 while(*p && p != text_lines[i + 1]) {