static void glw_freefloat_layout(glw_freefloat_t *ff, glw_rctx_t *rc) { glw_t *w = &ff->w; glw_t *c; int i, candpos = -1; float vmin = 1; for(i = 0; i < ff->num_visible; i++) { if(ff->visible[i] == NULL) { candpos = i; } else { vmin = GLW_MIN(ff->visible[i]->glw_parent_v, vmin); } } if(vmin > 1.0 / (float)ff->num_visible && candpos != -1) { /* Insert new entry */ if(ff->pick != NULL) ff->pick = glw_next_widget(ff->pick); if(ff->pick == NULL) ff->pick = glw_first_widget(w); if(ff->pick != NULL && !is_visible(ff, ff->pick)) { ff->visible[candpos] = ff->pick; setup_floater(ff, ff->pick); } } for(i = 0; i < ff->num_visible; i++) { if((c = ff->visible[i]) == NULL) continue; if(c->glw_parent_v >= 1) { ff->visible[i] = NULL; } else { glw_layout0(c, rc); } if(c->glw_class->gc_ready ? c->glw_class->gc_ready(c) : 1) c->glw_parent_v += c->glw_parent_s; c->glw_parent_s += c->glw_parent_s2; } qsort(ff->visible, ff->num_visible, sizeof(void *), zsort); c = ff->pick; // Layout next few items to pick, to preload textures, etc for(i = 0; i < 3 && c != NULL; i++, c = glw_next_widget(c)) { if(!is_visible(ff, c)) glw_layout0(c, rc); } }
static int glw_displacement_callback(glw_t *w, void *opaque, glw_signal_t signal, void *extra) { glw_displacement_t *gd = (glw_displacement_t *)w; glw_t *c; glw_rctx_t *rc, rc0; switch(signal) { default: break; case GLW_SIGNAL_LAYOUT: if((c = TAILQ_FIRST(&w->glw_childs)) == NULL) break; rc = extra; int width = rc->rc_width - gd->gd_padding_left - gd->gd_padding_right; int height = rc->rc_height - gd->gd_padding_top - gd->gd_padding_bottom; rc0 = *rc; rc0.rc_width = width; rc0.rc_height = height; glw_layout0(c, &rc0); break; case GLW_SIGNAL_CHILD_CONSTRAINTS_CHANGED: glw_copy_constraints(w, extra); return 1; } return 0; }
static void drawFrame(glw_ps3_t *gp, int buffer) { gcmContextData *ctx = gp->gr.gr_be.be_ctx; realityViewportTranslate(ctx, gp->res.width/2, gp->res.height/2, 0.0, 0.0); realityViewportScale(ctx, gp->res.width/2, -gp->res.height/2, 1.0, 0.0); realityZControl(ctx, 0, 1, 1); // disable viewport culling // Enable alpha blending. realityBlendFunc(ctx, NV30_3D_BLEND_FUNC_SRC_RGB_SRC_ALPHA | NV30_3D_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA, NV30_3D_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_ALPHA | NV30_3D_BLEND_FUNC_DST_ALPHA_ZERO); realityBlendEquation(ctx, NV40_3D_BLEND_EQUATION_RGB_FUNC_ADD | NV40_3D_BLEND_EQUATION_ALPHA_FUNC_ADD); realityBlendEnable(ctx, 1); realityViewport(ctx, gp->res.width, gp->res.height); setupRenderTarget(gp, buffer); // set the clear color realitySetClearColor(ctx, 0x00000000); realitySetClearDepthValue(ctx, 0xffff); // Clear the buffers realityClearBuffers(ctx, REALITY_CLEAR_BUFFERS_COLOR_R | REALITY_CLEAR_BUFFERS_COLOR_G | REALITY_CLEAR_BUFFERS_COLOR_B | NV30_3D_CLEAR_BUFFERS_COLOR_A | REALITY_CLEAR_BUFFERS_DEPTH); // XMB may overwrite currently loaded shaders, so clear them out gp->gr.gr_be.be_vp_current = NULL; gp->gr.gr_be.be_fp_current = NULL; realityCullEnable(ctx, 1); realityFrontFace(ctx, REALITY_FRONT_FACE_CCW); realityCullFace(ctx, REALITY_CULL_FACE_BACK); glw_lock(&gp->gr); glw_prepare_frame(&gp->gr, 0); gp->gr.gr_width = gp->res.width; gp->gr.gr_height = gp->res.height; glw_rctx_t rc; glw_rctx_init(&rc, gp->gr.gr_width, gp->gr.gr_height); glw_layout0(gp->gr.gr_universe, &rc); glw_render0(gp->gr.gr_universe, &rc); glw_unlock(&gp->gr); }
static void popup_layout(glw_t *w, const glw_rctx_t *rc) { glw_rctx_t rc0; glw_popup_t *p = (glw_popup_t *)w; glw_t *c = TAILQ_FIRST(&w->glw_childs); if(c == NULL || c->glw_flags & GLW_HIDDEN) return; int f = glw_filter_constraints(c); if(f & GLW_CONSTRAINT_X) p->width = MIN(c->glw_req_size_x, rc->rc_width); else p->width = rc->rc_width / 2; if(f & GLW_CONSTRAINT_Y) p->height = MIN(c->glw_req_size_y, rc->rc_height); else p->height = rc->rc_height / 2; rc0 = *rc; rc0.rc_width = p->width; rc0.rc_height = p->height; glw_layout0(c, &rc0); }
static void glw_cursor_layout(glw_t *w, const glw_rctx_t *rc) { glw_t *c = TAILQ_FIRST(&w->glw_childs); if(c != NULL) glw_layout0(c, rc); }
static int glw_keyintercept_callback(glw_t *w, void *opaque, glw_signal_t signal, void *extra) { glw_t *c; switch(signal) { default: break; case GLW_SIGNAL_DESTROY: ki_unbind((glw_keyintercept_t *)w); break; case GLW_SIGNAL_LAYOUT: c = TAILQ_FIRST(&w->glw_childs); if(c != NULL) glw_layout0(c, extra); break; case GLW_SIGNAL_CHILD_CONSTRAINTS_CHANGED: glw_copy_constraints(w, extra); return 1; case GLW_SIGNAL_EVENT_BUBBLE: if(w->glw_flags2 & GLW2_ENABLED) return ki_handle_event((glw_keyintercept_t *)w, extra); else return 0; } return 0; }
static void glw_slider_layout(glw_t *w, const glw_rctx_t *rc) { glw_slider_t *s = (glw_slider_t *)w; glw_t *c; glw_rctx_t rc0; int f; if((c = TAILQ_FIRST(&w->glw_childs)) == NULL || rc->rc_width == 0 || rc->rc_height == 0) return; f = glw_filter_constraints(c); if(s->fixed_knob_size) { if(w->glw_class == &glw_slider_x) { s->knob_size_px = s->knob_size_fixed * rc->rc_width; } else { s->knob_size_px = s->knob_size_fixed * rc->rc_height; } } else if(f & GLW_CONSTRAINT_X && w->glw_class == &glw_slider_x) { s->knob_size_px = c->glw_req_size_x; } else if(f & GLW_CONSTRAINT_Y && w->glw_class == &glw_slider_y) { s->knob_size_px = c->glw_req_size_y; } else if(w->glw_class == &glw_slider_x) { s->knob_size_px = rc->rc_height; } else { s->knob_size_px = rc->rc_width; } int p; rc0 = *rc; if(w->glw_class == &glw_slider_x) { p = s->value * (rc->rc_width - s->knob_size_px) + s->knob_size_px / 2; rc0.rc_width = s->knob_size_px; s->slider_size_px = rc->rc_width; } else { p = (1 - s->value) * (rc->rc_height - s->knob_size_px) + s->knob_size_px / 2; rc0.rc_height = s->knob_size_px; s->slider_size_px = rc->rc_height; } if(s->interpolate) glw_lp(&s->knob_pos_px, w->glw_root, p, 0.25); else s->knob_pos_px = p; glw_layout0(c, &rc0); }
static int glw_mirror_callback(glw_t *w, void *opaque, glw_signal_t signal, void *extra) { glw_t *c; switch(signal) { default: break; case GLW_SIGNAL_LAYOUT: c = TAILQ_FIRST(&w->glw_childs); if(c != NULL) glw_layout0(c, extra); break; } return 0; }
static int glw_expander_callback(glw_t *w, void *opaque, glw_signal_t signal, void *extra) { glw_expander_t *exp = (glw_expander_t *)w; glw_rctx_t *rc = extra; glw_t *c; glw_rctx_t rc0; switch(signal) { default: break; case GLW_SIGNAL_CHILD_CONSTRAINTS_CHANGED: update_constraints(exp); return 1; case GLW_SIGNAL_LAYOUT: if((c = TAILQ_FIRST(&w->glw_childs)) == NULL) break; rc0 = *rc; if(exp->w.glw_class == &glw_expander_x) { rc0.rc_width = c->glw_req_size_x; if(rc0.rc_width == 0) rc0.rc_width = exp->last; else exp->last = rc0.rc_width; } else { rc0.rc_height = c->glw_req_size_y; if(rc0.rc_height == 0) rc0.rc_height = exp->last; else exp->last = rc0.rc_height; } glw_layout0(c, &rc0); break; } return 0; }
static int glw_rotator_callback(glw_t *w, void *opaque, glw_signal_t signal, void *extra) { glw_rotator_t *gr = (glw_rotator_t *)w; glw_t *c; glw_rctx_t *rc; switch(signal) { default: break; case GLW_SIGNAL_LAYOUT: rc = extra; gr->theta -= 5; c = TAILQ_FIRST(&w->glw_childs); if(c != NULL) glw_layout0(c, rc); break; } return 0; }
static void render_hover_widget(glw_t *w, glw_cursor_t *gc, glw_rctx_t *rc0, const glw_rctx_t *rc, int *zmax) { // glw_root_t *gr = w->glw_root; if(!(gc->w.glw_flags & GLW_IN_HOVER_PATH)) return; gc->gc_hover_rctx.rc_alpha = 1.0f; gc->gc_hover_rctx.rc_sharpness = 1.0f; glw_layout0(w, &gc->gc_hover_rctx); rc0->rc_zindex = MAX(*zmax, rc->rc_zindex); gc->gc_hover_rctx.rc_zmax = rc0->rc_zmax; gc->gc_hover_rctx.rc_zindex = rc0->rc_zindex; glw_render0(w, &gc->gc_hover_rctx); }
static void glw_segway_layout(glw_t *w, const glw_rctx_t *rc) { glw_segway_t *s = (glw_segway_t *)w; glw_t *c; if((c = TAILQ_FIRST(&w->glw_childs)) == NULL) return; s->req_width = 0; int f = glw_filter_constraints(c); if(f & GLW_CONSTRAINT_X) { s->req_width = glw_req_width(c); } else if(f & GLW_CONSTRAINT_W && c->glw_req_weight < 0) { s->req_width = rc->rc_height * -c->glw_req_weight; } glw_rctx_t rc0 = *rc; float alpha; if(s->req_width == 0 || !s->direction) { rc0.rc_width = w->glw_root->gr_width; rc0.rc_segwayed = 1; alpha = 0; } else { rc0.rc_width = s->req_width; alpha = 1; } glw_lp(&s->alpha, w->glw_root, alpha, 0.25); glw_lp(&s->actual_width, w->glw_root, s->req_width, 0.25); s->actual_width_rounded = rintf(s->actual_width); rc0.rc_alpha *= s->alpha; glw_layout0(c, &rc0); glw_set_constraints(w, s->actual_width_rounded, 0, 0, GLW_CONSTRAINT_X); }
JNIEXPORT void JNICALL Java_com_showtimemediacenter_showtime_STCore_glwStep(JNIEnv *env, jobject obj, jint id) { android_glw_root_t *agr = (android_glw_root_t *)id; glw_root_t *gr = &agr->gr; glw_lock(gr); gr->gr_can_externalize = 1; gr->gr_externalize_cnt = 0; glViewport(0, 0, gr->gr_width, gr->gr_height); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glw_prepare_frame(gr, 0); glw_rctx_t rc; glw_rctx_init(&rc, gr->gr_width, gr->gr_height, 1); glw_layout0(gr->gr_universe, &rc); glw_render0(gr->gr_universe, &rc); glw_unlock(gr); glw_post_scene(gr); }
static void glw_bloom_layout(glw_t *w, glw_rctx_t *rc) { glw_bloom_t *b = (void *)w; glw_root_t *gr = w->glw_root; glw_rctx_t rc0; glw_t *c; int x, y, i, sizx, sizy; TAILQ_FOREACH(c, &w->glw_childs, glw_parent_link) glw_layout0(c, rc); if(b->b_glow < 0.01) { if(b->b_width || b->b_height) bloom_destroy_rtt(gr, b); return; } sizx = rc->rc_width + EDGE_SIZE; sizy = rc->rc_height + EDGE_SIZE; if(b->b_width != sizx || b->b_height != sizy) { if(b->b_width || b->b_height) bloom_destroy_rtt(gr, b); b->b_width = sizx; b->b_height = sizy; if(b->b_width || b->b_height) { for(i = 0; i < BLOOM_COUNT; i++) { x = b->b_width / (2 << i); y = b->b_height / (2 << i); glw_rtt_init(gr, &b->b_rtt[i], x, y, 1); } } } // Initialize output texture if(!b->b_render_initialized) { float xs = gr->gr_normalized_texture_coords ? 1.0 : b->b_width; float ys = gr->gr_normalized_texture_coords ? 1.0 : b->b_height; glw_renderer_init_quad(&b->b_render); glw_renderer_vtx_pos(&b->b_render, 0, -1.0, -1.0, 0.0); glw_renderer_vtx_st (&b->b_render, 0, 0.0, 0); glw_renderer_vtx_pos(&b->b_render, 1, 1.0, -1.0, 0.0); glw_renderer_vtx_st (&b->b_render, 1, xs, 0); glw_renderer_vtx_pos(&b->b_render, 2, 1.0, 1.0, 0.0); glw_renderer_vtx_st (&b->b_render, 2, xs, ys); glw_renderer_vtx_pos(&b->b_render, 3, -1.0, 1.0, 0.0); glw_renderer_vtx_st (&b->b_render, 3, 0.0, ys); } memset(&rc0, 0, sizeof(glw_rctx_t)); rc0.rc_alpha = 1; rc0.rc_width = b->b_width - EDGE_SIZE; rc0.rc_height = b->b_height - EDGE_SIZE; rc0.rc_inhibit_shadows = 1; if(!b->b_need_render) return; for(i = 0; i < BLOOM_COUNT; i++) { glw_rtt_enter(gr, &b->b_rtt[i], &rc0); rc0.rc_width = b->b_width - EDGE_SIZE; rc0.rc_height = b->b_height - EDGE_SIZE; glw_Scalef(&rc0, 1.0 - EDGE_SIZE / b->b_width, 1.0 - EDGE_SIZE / b->b_height, 1.0); TAILQ_FOREACH(c, &w->glw_childs, glw_parent_link) glw_render0(c, &rc0); glw_rtt_restore(gr, &b->b_rtt[i]); } }
static void render_focus_widget(glw_t *w, glw_cursor_t *gc, const Mtx *saved, glw_rctx_t *rc0, const glw_rctx_t *rc, int *zmax) { glw_root_t *gr = w->glw_root; if(!(gc->w.glw_flags & GLW_IN_FOCUS_PATH)) return; glw_t *f = gr->gr_current_focus; if(f->glw_matrix != NULL) { Mtx a_inv; glw_mtx_invert(&a_inv, saved); Mtx *b = f->glw_matrix; if(0) { glw_rect_t focus_rect; glw_project_matrix(&focus_rect, b, gr); printf("Current focus: %d,%d - %d,%d\n", focus_rect.x1, focus_rect.y1, focus_rect.x2, focus_rect.y2); } Mtx x; glw_mtx_mul(&x, &a_inv, b); if (!gc->gc_initialized) { gc->gc_mtx = x; gc->gc_initialized = 1; } else { for(int r = 0; r < 4; r++) { for(int c = 0; c < 4; c++) { glw_lp(&gc->gc_mtx.r[r][c], gr, x.r[r][c], 0.75); /* printf("%2.3f%c", gc->gc_mtx[i], (i+1) & 3 ? '\t' : '\n'); */ } } } glw_mtx_mul(&gc->gc_cursor_rctx.rc_mtx, saved, &gc->gc_mtx); } glw_rect_t cursor_rect; glw_project(&cursor_rect, &gc->gc_cursor_rctx, gr); gc->gc_cursor_rctx.rc_width = cursor_rect.x2 - cursor_rect.x1; gc->gc_cursor_rctx.rc_height = cursor_rect.y2 - cursor_rect.y1; if(gc->gc_cursor_rctx.rc_width <= 0) return; if(gc->gc_cursor_rctx.rc_height <= 0) return; gc->gc_cursor_rctx.rc_alpha = 1.0f; gc->gc_cursor_rctx.rc_sharpness = 1.0f; glw_layout0(w, &gc->gc_cursor_rctx); rc0->rc_zindex = MAX(*zmax, rc->rc_zindex); gc->gc_cursor_rctx.rc_zmax = rc0->rc_zmax; gc->gc_cursor_rctx.rc_zindex = rc0->rc_zindex; glw_render0(w, &gc->gc_cursor_rctx); }
static void glw_slideshow_layout(glw_t *w, const glw_rctx_t *rc) { glw_root_t *gr = w->glw_root; glw_slideshow_t *s = (glw_slideshow_t *)w; glw_t *c, *p, *n; float delta; int r = 0; glw_reset_screensaver(w->glw_root); delta = s->w.glw_root->gr_frameduration / (float)s->transition_time; if((c = s->w.glw_focused) == NULL) { c = s->w.glw_focused = glw_first_widget(&s->w); if(c) glw_copy_constraints(&s->w, c); } if(c == NULL) return; glw_schedule_refresh(gr, s->deadline); if(s->deadline <= gr->gr_frame_start) { s->deadline = gr->gr_frame_start + s->display_time; c = glw_next_widget(c); if(c == NULL) c = glw_first_widget(&s->w); if(c != NULL) { glw_focus_open_path_close_all_other(c); glw_copy_constraints(&s->w, c); } } glw_layout0(c, rc); r |= update_parent_alpha(c, GLW_MIN(c->glw_parent_alpha + delta, 1.0f)); /** * Keep previous and next images 'hot' (ie, loaded into texture memory) */ p = glw_prev_widget(c); if(p == NULL) p = glw_last_widget(&s->w, 0); if(p != NULL && p != c) { r |= update_parent_alpha(p, GLW_MAX(p->glw_parent_alpha - delta, 0.0f)); glw_layout0(p, rc); } n = glw_next_widget(c); if(n == NULL) n = glw_first_widget(&s->w); if(n != NULL && n != c) { r |= update_parent_alpha(n, GLW_MAX(n->glw_parent_alpha - delta, 0.0f)); glw_layout0(n, rc); } if(r) glw_need_refresh(w->glw_root, 0); }
static void glw_image_layout(glw_t *w, glw_rctx_t *rc) { glw_image_t *gi = (void *)w; glw_root_t *gr = w->glw_root; glw_loadable_texture_t *glt; glw_rctx_t rc0; glw_t *c; if(gi->gi_pending_filename != NULL) { // Request to load int xs = -1, ys = -1; int flags = 0; if(gi->gi_pending != NULL) glw_tex_deref(w->glw_root, gi->gi_pending); if(gi->gi_pending_filename[0] == 0) { gi->gi_pending = NULL; if(gi->gi_current != NULL) { glw_tex_deref(w->glw_root, gi->gi_current); gi->gi_current = NULL; } gi->gi_update = 1; } else { if(w->glw_class == &glw_repeatedimage) flags |= GLW_TEX_REPEAT; if(gi->gi_bitmap_flags & GLW_IMAGE_HQ_SCALING) { if(rc->rc_width < rc->rc_height) { xs = rc->rc_width; } else { ys = rc->rc_height; } } if(xs && ys) { gi->gi_pending = glw_tex_create(w->glw_root, gi->gi_pending_filename, flags, xs, ys); free(gi->gi_pending_filename); gi->gi_pending_filename = NULL; } else { gi->gi_pending = NULL; } } } if((glt = gi->gi_pending) != NULL) { glw_tex_layout(gr, glt); if(glt->glt_state == GLT_STATE_VALID || glt->glt_state == GLT_STATE_ERROR) { // Pending texture completed, ok or error: transfer to current if(gi->gi_current != NULL) glw_tex_deref(w->glw_root, gi->gi_current); gi->gi_current = gi->gi_pending; gi->gi_pending = NULL; gi->gi_update = 1; } } if((glt = gi->gi_current) == NULL) return; glw_tex_layout(gr, glt); if(glt->glt_state == GLT_STATE_ERROR) { if(!gi->gi_was_valid) { glw_signal0(w, GLW_SIGNAL_READY, NULL); gi->gi_was_valid = 1; } } else if(glt->glt_state == GLT_STATE_VALID) { if(!gi->gi_was_valid) { glw_signal0(w, GLW_SIGNAL_READY, NULL); gi->gi_was_valid = 1; } if(gi->gi_update) { gi->gi_update = 0; glw_renderer_free(&gi->gi_gr); switch(gi->gi_mode) { case GI_MODE_NORMAL: glw_renderer_init_quad(&gi->gi_gr); glw_image_layout_normal(gr, rc, gi, glt); break; case GI_MODE_BORDER_SCALING: glw_renderer_init(&gi->gi_gr, 16, 18, borderobject); glw_image_layout_tesselated(gr, rc, gi, glt); break; case GI_MODE_REPEATED_TEXTURE: glw_renderer_init_quad(&gi->gi_gr); glw_image_layout_repeated(gr, rc, gi, glt); break; case GI_MODE_ALPHA_EDGES: glw_renderer_init(&gi->gi_gr, 16, 18, borderobject); glw_image_layout_alpha_edges(gr, rc, gi, glt); break; case GI_MODE_BORDER_ONLY_SCALING: glw_renderer_init(&gi->gi_gr, 16, 16, borderonlyobject); glw_image_layout_tesselated(gr, rc, gi, glt); break; default: abort(); } } else if(gi->gi_last_width != rc->rc_width || gi->gi_last_height != rc->rc_height) { gi->gi_last_width = rc->rc_width; gi->gi_last_height = rc->rc_height; switch(gi->gi_mode) { case GI_MODE_NORMAL: break; case GI_MODE_BORDER_SCALING: case GI_MODE_BORDER_ONLY_SCALING: glw_image_layout_tesselated(gr, rc, gi, glt); break; case GI_MODE_REPEATED_TEXTURE: glw_image_layout_repeated(gr, rc, gi, glt); break; case GI_MODE_ALPHA_EDGES: glw_image_layout_alpha_edges(gr, rc, gi, glt); break; } if(gi->gi_bitmap_flags & GLW_IMAGE_HQ_SCALING && gi->gi_pending == NULL && gi->gi_pending_filename == NULL && rc->rc_width && rc->rc_height) { int xs = -1, ys = -1, rescale; if(rc->rc_width < rc->rc_height) { rescale = abs(rc->rc_width - glt->glt_xs) > glt->glt_xs / 10; xs = rc->rc_width; } else { rescale = abs(rc->rc_height - glt->glt_ys) > glt->glt_ys / 10; ys = rc->rc_height; } if(rescale) { int flags = 0; if(w->glw_class == &glw_repeatedimage) flags |= GLW_TEX_REPEAT; gi->gi_pending = glw_tex_create(w->glw_root, glt->glt_filename, flags, xs, ys); } } } } glw_image_update_constraints(gi); if((c = TAILQ_FIRST(&w->glw_childs)) != NULL) { rc0 = *rc; rc0.rc_width -= gi->gi_box_left + gi->gi_box_right; rc0.rc_height -= gi->gi_box_top + gi->gi_box_bottom; if(rc0.rc_height >= 0 && rc0.rc_width >= 0) glw_layout0(c, &rc0); } }
static void glw_slideshow_layout(glw_t *w, const glw_rctx_t *rc) { glw_slideshow_t *s = (glw_slideshow_t *)w; glw_t *c, *p, *n; float delta; glw_reset_screensaver(w->glw_root); delta = s->w.glw_root->gr_frameduration / (1000000.0 * s->transition_time); if(s->time == 0) { s->displaytime = INT32_MAX; } else { s->displaytime = 1000000 * s->time / s->w.glw_root->gr_frameduration; } if((c = s->w.glw_focused) == NULL) { c = s->w.glw_focused = glw_first_widget(&s->w); if(c) glw_copy_constraints(&s->w, c); } if(c == NULL) return; if(s->timer >= s->displaytime) { c = glw_next_widget(c); if(c == NULL) c = glw_first_widget(&s->w); s->timer = 0; if(c != NULL) { glw_focus_open_path_close_all_other(c); glw_copy_constraints(&s->w, c); } } if(!s->hold) s->timer++; glw_layout0(c, rc); c->glw_parent_alpha = GLW_MIN(c->glw_parent_alpha + delta, 1.0f); /** * Keep previous and next images 'hot' (ie, loaded into texture memory) */ p = glw_prev_widget(c); if(p == NULL) p = glw_last_widget(&s->w); if(p != NULL && p != c) { p->glw_parent_alpha = GLW_MAX(p->glw_parent_alpha - delta, 0.0f); glw_layout0(p, rc); } n = glw_next_widget(c); if(n == NULL) n = glw_first_widget(&s->w); if(n != NULL && n != c) { n->glw_parent_alpha = GLW_MAX(n->glw_parent_alpha - delta, 0.0f); glw_layout0(n, rc); } }
static void glw_image_layout(glw_t *w, glw_rctx_t *rc) { glw_image_t *gi = (void *)w; glw_root_t *gr = w->glw_root; glw_loadable_texture_t *glt; glw_rctx_t rc0; glw_t *c; int hq = (w->glw_class == &glw_icon || w->glw_class == &glw_image); if(gi->gi_pending_url != NULL) { // Request to load int xs = -1, ys = -1; int flags = 0; gi->gi_loading_new_url = 1; if(gi->gi_pending != NULL) { glw_tex_deref(w->glw_root, gi->gi_pending); gi->gi_pending = NULL; } if(rstr_get(gi->gi_pending_url)[0] == 0) { // Empty string, unload all if(gi->gi_current != NULL) { glw_tex_deref(w->glw_root, gi->gi_current); gi->gi_current = NULL; } gi->gi_update = 1; } else { if(w->glw_class == &glw_repeatedimage) flags |= GLW_TEX_REPEAT; if(hq) { if(rc->rc_width < rc->rc_height) { xs = rc->rc_width; } else { ys = rc->rc_height; } } if(xs && ys) { if(w->glw_flags & GLW_DEBUG) TRACE(TRACE_DEBUG, "IMG", "Loading texture: %s", rstr_get(gi->gi_pending_url)); gi->gi_pending = glw_tex_create(w->glw_root, gi->gi_pending_url, flags, xs, ys); rstr_release(gi->gi_pending_url); gi->gi_pending_url = NULL; } } } if((glt = gi->gi_pending) != NULL) { glw_tex_layout(gr, glt); if(glw_is_tex_inited(&glt->glt_texture) || glt->glt_state == GLT_STATE_ERROR) { // Pending texture completed, ok or error: transfer to current if(gi->gi_current != NULL) glw_tex_deref(w->glw_root, gi->gi_current); gi->gi_current = gi->gi_pending; gi->gi_pending = NULL; gi->gi_update = 1; gi->gi_loading_new_url = 0; } } if((glt = gi->gi_current) == NULL) return; if(gi->gi_loading_new_url) { gi->gi_autofade = GLW_LP(8, gi->gi_autofade, 0); } else { gi->gi_autofade = GLW_LP(8, gi->gi_autofade, 1); } glw_tex_layout(gr, glt); if(glt->glt_state == GLT_STATE_ERROR) { if(!gi->gi_is_ready) { gi->gi_is_ready = 1; glw_signal0(w, GLW_SIGNAL_READINESS, NULL); } } else if(glw_is_tex_inited(&glt->glt_texture)) { int r = !gi->gi_loading_new_url; if(gi->gi_is_ready != r) { gi->gi_is_ready = r; glw_signal0(w, GLW_SIGNAL_READINESS, NULL); } if(gi->gi_update) { gi->gi_update = 0; glw_renderer_free(&gi->gi_gr); switch(gi->gi_mode) { case GI_MODE_NORMAL: glw_renderer_init_quad(&gi->gi_gr); glw_image_layout_normal(gr, rc, gi, glt); break; case GI_MODE_BORDER_SCALING: glw_renderer_init(&gi->gi_gr, 16, 18, borderobject); glw_image_layout_tesselated(gr, rc, gi, glt); break; case GI_MODE_REPEATED_TEXTURE: glw_renderer_init_quad(&gi->gi_gr); glw_image_layout_repeated(gr, rc, gi, glt); break; case GI_MODE_ALPHA_EDGES: glw_renderer_init(&gi->gi_gr, 16, 18, borderobject); glw_image_layout_alpha_edges(gr, rc, gi, glt); break; case GI_MODE_BORDER_ONLY_SCALING: glw_renderer_init(&gi->gi_gr, 16, 16, borderonlyobject); glw_image_layout_tesselated(gr, rc, gi, glt); break; default: abort(); } } else if(gi->gi_last_width != rc->rc_width || gi->gi_last_height != rc->rc_height) { gi->gi_last_width = rc->rc_width; gi->gi_last_height = rc->rc_height; switch(gi->gi_mode) { case GI_MODE_NORMAL: break; case GI_MODE_BORDER_SCALING: case GI_MODE_BORDER_ONLY_SCALING: glw_image_layout_tesselated(gr, rc, gi, glt); break; case GI_MODE_REPEATED_TEXTURE: glw_image_layout_repeated(gr, rc, gi, glt); break; case GI_MODE_ALPHA_EDGES: glw_image_layout_alpha_edges(gr, rc, gi, glt); break; } gi->gi_need_reload = hq; } if(gi->gi_need_reload && gi->gi_pending == NULL && gi->gi_pending_url == NULL && rc->rc_width && rc->rc_height) { gi->gi_need_reload = 0; int xs = -1, ys = -1, rescale; if(rc->rc_width < rc->rc_height) { rescale = rc->rc_width != glt->glt_xs; xs = rc->rc_width; } else { rescale = rc->rc_height != glt->glt_ys; ys = rc->rc_height; } if(rescale) { int flags = 0; if(w->glw_class == &glw_repeatedimage) flags |= GLW_TEX_REPEAT; gi->gi_pending = glw_tex_create(w->glw_root, glt->glt_url, flags, xs, ys); } } } else { if(gi->gi_is_ready) { gi->gi_is_ready = 0; glw_signal0(w, GLW_SIGNAL_READINESS, NULL); } } glw_image_update_constraints(gi); if((c = TAILQ_FIRST(&w->glw_childs)) != NULL) { rc0 = *rc; rc0.rc_width -= gi->gi_box_left + gi->gi_box_right; rc0.rc_height -= gi->gi_box_top + gi->gi_box_bottom; if(rc0.rc_height >= 0 && rc0.rc_width >= 0) glw_layout0(c, &rc0); } }