some code in the exhibit ui, and first stab at laying out the
[laserbrain_demo] / src / ui_exhibit.cc
1 #include "ui_exhibit.h"
2 #include "ui.h"
3 #include "app.h"
4 #include <drawtext.h>
5
6 static void draw_titlebar();
7 static void draw_tabs();
8 static void layout_text(const char *text);
9
10 static Vec3 pos;
11 static Vec2 size;
12 static float text_padding;
13 static Exhibit *ex;
14 static int vis_tab;
15 static float scroll;
16 static std::vector<const char*> text_lines;
17 static AudioStream *voice;
18
19
20 bool exui_init()
21 {
22         size.x = 150;
23         size.y = 180;
24         text_padding = size.x * 0.01;
25
26         return true;
27 }
28
29 void exui_shutdown()
30 {
31 }
32
33 void exui_change_tab(int dir)
34 {
35 }
36
37 void exui_scroll(float delta)
38 {
39 }
40
41 bool exui_raycast(const Ray &ray)
42 {
43         return false;
44 }
45
46 void exui_update(float dt)
47 {
48         if(exsel_active.ex != ex) {
49                 ex = exsel_active.ex;
50                 scroll = 0.0f;
51                 vis_tab = 0;
52                 text_lines.clear();
53                 if(voice) voice->stop();
54
55                 if(ex) {
56                         int num_data = ex->data.size();
57                         for(int i=0; i<num_data; i++) {
58                                 if(ex->data[i].type == EXDATA_INFO) {
59                                         layout_text(ex->data[i].text.c_str());
60                                         voice = ex->data[i].voice;
61                                 }
62                         }
63
64                         if(voice) {
65                                 voice->play(AUDIO_PLAYMODE_ONCE);
66                         }
67                 } else {
68                         voice = 0;
69                 }
70         }
71 }
72
73 void exui_draw()
74 {
75         if(!exsel_active) return;
76
77         draw_titlebar();
78         draw_tabs();
79 }
80
81 static void draw_titlebar()
82 {
83 }
84
85 static void draw_tabs()
86 {
87 }
88
89 static void layout_text(const char *text)
90 {
91         text_lines.clear();
92         if(!text) return;
93         if(!ui_font) return;
94
95         dtx_use_font(ui_font, ui_font_size);
96
97         float pos = text_padding;
98         text_lines.push_back(text);
99         const char *last_break = 0;
100
101         while(*text) {
102                 if(*text == '\n') {     // paragraph break
103                         text_lines.push_back(text);
104                         text_lines.push_back(++text);
105                         pos = text_padding;
106                         last_break = 0;
107                         continue;
108                 }
109
110                 int code = dtx_utf8_char_code(text);
111                 const char *next = dtx_utf8_next_char((char*)text);
112                 pos += dtx_glyph_width(code);
113
114                 if(pos >= size.x - text_padding) {
115                         if(text == text_lines.back()) {
116                                 // not even a single character fits on a line... abort
117                                 warning_log("text layout failed. glyph %d doesn't fit in line (%g)\n", code, size.x - 2.0 * text_padding);
118                                 text_lines.clear();
119                                 return;
120                         }
121                         if(last_break) {
122                                 text_lines.push_back(last_break + 1);
123                                 last_break = 0;
124                         } else {
125                                 // no good point to break, just break here
126                                 text_lines.push_back(text);
127                         }
128                         pos = text_padding;
129                 }
130                 text = next;
131         }
132 }