void a3d_sprite_delete(a3d_sprite_t** _self) { assert(_self); a3d_sprite_t* self = *_self; if(self) { LOGD("debug"); int i; a3d_widget_t* widget = (a3d_widget_t*) self; a3d_screen_t* screen = widget->screen; for(i = 0; i < self->count; ++i) { a3d_screen_spriteTexUnmap(screen, &(self->id_tex[i])); } free(self->id_tex); glBindBuffer(GL_ARRAY_BUFFER, 0); glDeleteBuffers(1, &self->id_coords); glDeleteBuffers(1, &self->id_vertex); a3d_widget_delete((a3d_widget_t**) _self); } }
void a3d_listbox_delete(a3d_listbox_t** _self) { assert(_self); a3d_listbox_t* self = *_self; if(self) { LOGD("debug"); a3d_list_delete(&self->list); a3d_widget_delete((a3d_widget_t**) _self); } }
a3d_bulletbox_t* a3d_bulletbox_new(a3d_screen_t* screen, int wsize, int anchor, int style_border, int style_line, int style_text, a3d_vec4f_t* color_fill, a3d_vec4f_t* color_line, a3d_vec4f_t* color_text, a3d_vec4f_t* color_icon, int max_len, int count, a3d_widget_click_fn click_fn, a3d_widget_refresh_fn refresh_fn) { assert(screen); assert(color_fill); assert(color_line); assert(color_text); assert(color_icon); if(wsize == 0) { wsize = sizeof(a3d_bulletbox_t); } a3d_bulletbox_t* self; self = (a3d_bulletbox_t*) a3d_widget_new(screen, wsize, anchor, A3D_WIDGET_WRAP_SHRINK, A3D_WIDGET_WRAP_SHRINK, A3D_WIDGET_STRETCH_NA, 1.0f, style_border, style_line, color_line, color_fill, NULL, a3d_bulletbox_size, click_fn, a3d_bulletbox_layout, a3d_bulletbox_drag, a3d_bulletbox_draw, a3d_bulletbox_fade, refresh_fn); if(self == NULL) { return NULL; } a3d_vec4f_t clear = { .r = 0.0f, .g = 0.0f, .b = 0.0f, .a = 0.0f }; int wrap = A3D_WIDGET_WRAP_STRETCH_TEXT_MEDIUM; if(style_text == A3D_TEXT_STYLE_LARGE) { wrap = A3D_WIDGET_WRAP_STRETCH_TEXT_LARGE; } else if(style_text == A3D_TEXT_STYLE_SMALL) { wrap = A3D_WIDGET_WRAP_STRETCH_TEXT_SMALL; } self->icon = a3d_sprite_new(screen, 0, anchor, wrap, wrap, A3D_WIDGET_STRETCH_SQUARE, 1.0f, A3D_WIDGET_BORDER_NONE, A3D_WIDGET_LINE_NONE, &clear, &clear, color_icon, NULL, NULL, count); if(self->icon == NULL) { goto fail_icon; } self->text = a3d_text_new(screen, 0, anchor, A3D_WIDGET_BORDER_NONE, A3D_WIDGET_LINE_NONE, style_text, &clear, &clear, color_text, max_len, NULL, NULL); if(self->text == NULL) { goto fail_text; } // success return self; // failure fail_text: a3d_sprite_delete(&self->icon); fail_icon: a3d_widget_delete((a3d_widget_t**) &self); return NULL; } void a3d_bulletbox_delete(a3d_bulletbox_t** _self) { assert(_self); a3d_bulletbox_t* self = *_self; if(self) { LOGD("debug"); a3d_text_delete(&self->text); a3d_sprite_delete(&self->icon); a3d_widget_delete((a3d_widget_t**) _self); } }
a3d_listbox_t* a3d_listbox_new(a3d_screen_t* screen, int wsize, int orientation, int anchor, int wrapx, int wrapy, int stretch_mode, float stretch_factor, int style_border, int style_line, a3d_vec4f_t* color_fill, a3d_vec4f_t* color_line, a3d_widget_reflow_fn reflow_fn, a3d_widget_refresh_fn refresh_fn) { // reflow_fn, refresh_fn may be NULL assert(screen); assert(color_fill); assert(color_line); LOGD("debug wsize=%i, orientation=%i, anchor=%i, wrapx=%i, wrapy=%i", wsize, orientation, anchor, wrapx, wrapy); LOGD("debug stretch_mode=%i, stretch_factor=%f, style_border=%i, style_line=%i", stretch_mode, stretch_factor, style_border, style_line); LOGD("debug color_fill: r=%f, g=%f, b=%f, a=%f", color_fill->r, color_fill->g, color_fill->b, color_fill->a); LOGD("debug color_line: r=%f, g=%f, b=%f, a=%f", color_line->r, color_line->g, color_line->b, color_line->a); if(wsize == 0) { wsize = sizeof(a3d_listbox_t); } // optionally overide refresh_fn if(refresh_fn == NULL) { refresh_fn = a3d_listbox_refresh; } a3d_listbox_t* self = (a3d_listbox_t*) a3d_widget_new(screen, wsize, anchor, wrapx, wrapy, stretch_mode, stretch_factor, style_border, style_line, color_line, color_fill, reflow_fn, a3d_listbox_size, a3d_listbox_click, a3d_listbox_layout, a3d_listbox_drag, a3d_listbox_draw, a3d_listbox_fade, refresh_fn); if(self == NULL) { return NULL; } a3d_widget_soundFx((a3d_widget_t*) self, 0); self->list = a3d_list_new(); if(self->list == NULL) { goto fail_list; } a3d_list_notify(self->list, (void*) self, a3d_listbox_notify, a3d_listbox_notify, a3d_listbox_notify); self->orientation = orientation; // success return self; // failure fail_list: a3d_widget_delete((a3d_widget_t**) &self); return NULL; }
a3d_layer_t* a3d_layer_new(a3d_screen_t* screen, int wsize, int anchor, int wrapx, int wrapy, int stretch_mode, float stretch_factor, int style_border, int style_line, a3d_vec4f_t* color_fill, a3d_vec4f_t* color_line, int mode) { assert(screen); assert(color_fill); assert(color_line); LOGD("debug wsize=%i, anchor=%i, wrapx=%i, wrapy=%i", wsize, anchor, wrapx, wrapy); LOGD("debug stretch_mode=%i, stretch_factor=%f, style_border=%i, style_line=%i", stretch_mode, stretch_factor, style_border, style_line); LOGD("debug color_fill: r=%f, g=%f, b=%f, a=%f", color_fill->r, color_fill->g, color_fill->b, color_fill->a); LOGD("debug color_line: r=%f, g=%f, b=%f, a=%f", color_line->r, color_line->g, color_line->b, color_line->a); if(wsize == 0) { wsize = sizeof(a3d_layer_t); } a3d_layer_t* self = (a3d_layer_t*) a3d_widget_new(screen, wsize, anchor, wrapx, wrapy, stretch_mode, stretch_factor, style_border, style_line, color_line, color_fill, NULL, a3d_layer_size, a3d_layer_click, a3d_layer_layout, a3d_layer_drag, a3d_layer_draw, a3d_layer_fade, a3d_layer_refresh); if(self == NULL) { return NULL; } a3d_widget_soundFx((a3d_widget_t*) self, 0); self->list = a3d_list_new(); if(self->list == NULL) { goto fail_list; } self->mode = mode; a3d_list_notify(self->list, (void*) self, a3d_layer_notify, a3d_layer_notify, a3d_layer_notify); // success return self; // failure fail_list: a3d_widget_delete((a3d_widget_t**) &self); return NULL; }
static void a3d_hline_draw(a3d_widget_t* widget) { assert(widget); a3d_hline_t* self = (a3d_hline_t*) widget; // clip separator to border a3d_rect4f_t rect_border_clip; if(a3d_rect4f_intersect(&widget->rect_border, &widget->rect_clip, &rect_border_clip) == 0) { return; } // clip separator float top = widget->rect_clip.t; float h2 = widget->rect_clip.h/2.0f; a3d_rect4f_t line = { .t = top + h2, .l = rect_border_clip.l, .w = rect_border_clip.w, .h = 0.0f }; // draw the separator a3d_screen_t* screen = widget->screen; a3d_vec4f_t* c = &self->color; float alpha = widget->fade*c->a; if(alpha > 0.0f) { glDisable(GL_SCISSOR_TEST); if(alpha < 1.0f) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } glUseProgram(screen->prog); glEnableVertexAttribArray(screen->attr_coords); int line_style = A3D_WIDGET_LINE_MEDIUM; if(self->style == A3D_HLINE_STYLE_SMALL) { line_style = A3D_WIDGET_LINE_SMALL; } else if(self->style == A3D_HLINE_STYLE_LARGE) { line_style = A3D_WIDGET_LINE_LARGE; } float lw = a3d_screen_layoutLine(screen, line_style); glLineWidth(lw); a3d_rect4f_t* r = &line; glBindBuffer(GL_ARRAY_BUFFER, screen->id_coords2); glVertexAttribPointer(screen->attr_coords, 2, GL_FLOAT, GL_FALSE, 0, 0); a3d_mat4f_t mvp; a3d_mat4f_ortho(&mvp, 1, 0.0f, screen->w, screen->h, 0.0f, 0.0f, 2.0f); glUniformMatrix4fv(screen->unif_mvp, 1, GL_FALSE, (GLfloat*) &mvp); glUniform4f(screen->unif_rect, r->t, r->l, r->w, r->h); glUniform4f(screen->unif_color, c->r, c->g, c->b, alpha); glDrawArrays(GL_LINES, 0, 2); glLineWidth(1.0f); glBindBuffer(GL_ARRAY_BUFFER, 0); glDisableVertexAttribArray(screen->attr_coords); glUseProgram(0); if(alpha < 1.0f) { glDisable(GL_BLEND); } glEnable(GL_SCISSOR_TEST); } } /*********************************************************** * public * ***********************************************************/ a3d_hline_t* a3d_hline_new(a3d_screen_t* screen, int wsize, int anchor, int style_line, a3d_vec4f_t* color_line, int max_len) { assert(screen); assert(color_line); a3d_vec4f_t clear = { .r = 0.0f, .g = 0.0f, .b = 0.0f, .a = 0.0f }; if(wsize == 0) { wsize = sizeof(a3d_hline_t); } a3d_hline_t* self = (a3d_hline_t*) a3d_widget_new(screen, wsize, anchor, A3D_WIDGET_WRAP_SHRINK, A3D_WIDGET_WRAP_SHRINK, A3D_WIDGET_STRETCH_NA, 1.0f, A3D_WIDGET_BORDER_NONE, A3D_WIDGET_LINE_NONE, &clear, &clear, NULL, a3d_hline_size, NULL, NULL, NULL, a3d_hline_draw, NULL, NULL); if(self == NULL) { return NULL; } self->wrapx = A3D_HLINE_WRAP_SHRINK; self->max_len = max_len; self->style = style_line; a3d_vec4f_copy(color_line, &self->color); return self; } void a3d_hline_delete(a3d_hline_t** _self) { assert(_self); a3d_hline_t* self = *_self; if(self) { a3d_widget_delete((a3d_widget_t**) _self); } }
a3d_sprite_t* a3d_sprite_new(a3d_screen_t* screen, int wsize, int anchor, int wrapx, int wrapy, int stretch_mode, float stretch_factor, int style_border, int style_line, a3d_vec4f_t* color_fill, a3d_vec4f_t* color_line, a3d_vec4f_t* color_sprite, a3d_widget_click_fn click_fn, a3d_widget_refresh_fn refresh_fn, int count) { // click_fn and refresh_fn may be NULL assert(screen); assert(color_fill); assert(color_line); assert(color_sprite); LOGD("debug wsize=%i, anchor=%i, wrapx=%i, wrapy=%i", wsize, anchor, wrapx, wrapy); LOGD("debug stretch_mode=%i, stretch_factor=%f, style_border=%i, style_line=%i", stretch_mode, stretch_factor, style_border, style_line); LOGD("debug color_fill: r=%f, g=%f, b=%f, a=%f", color_fill->r, color_fill->g, color_fill->b, color_fill->a); LOGD("debug color_line: r=%f, g=%f, b=%f, a=%f", color_line->r, color_line->g, color_line->b, color_line->a); LOGD("debug color_sprite: r=%f, g=%f, b=%f, a=%f", color_sprite->r, color_sprite->g, color_sprite->b, color_sprite->a); LOGD("debug count=%i", count); if(count <= 0) { LOGE("invalid count=%i", count); return NULL; } if((wrapx == A3D_WIDGET_WRAP_SHRINK) || (wrapy == A3D_WIDGET_WRAP_SHRINK)) { LOGE("invalid wrapx=%i, wrapy=%i", wrapx, wrapy); return NULL; } if(wsize == 0) { wsize = sizeof(a3d_sprite_t); } a3d_sprite_t* self = (a3d_sprite_t*) a3d_widget_new(screen, wsize, anchor, wrapx, wrapy, stretch_mode, stretch_factor, style_border, style_line, color_line, color_fill, NULL, NULL, click_fn, NULL, NULL, a3d_sprite_draw, NULL, refresh_fn); if(self == NULL) { return NULL; } self->id_tex = (GLuint*) calloc(count, sizeof(GLuint)); if(self->id_tex == NULL) { LOGE("malloc failed"); goto fail_tex; } self->index = 0; self->count = count; self->theta = 0.0f; a3d_vec4f_copy(color_sprite, &self->color); glGenBuffers(1, &self->id_vertex); glGenBuffers(1, &self->id_coords); int vertex_size = 24; // 2*3*xyzw int coords_size = 12; // 2*3*uv glBindBuffer(GL_ARRAY_BUFFER, self->id_vertex); glBufferData(GL_ARRAY_BUFFER, vertex_size*sizeof(GLfloat), VERTEX, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, self->id_coords); glBufferData(GL_ARRAY_BUFFER, coords_size*sizeof(GLfloat), COORDS, GL_STATIC_DRAW); // success return self; // failure fail_tex: a3d_widget_delete((a3d_widget_t**) &self); return NULL; }