static int glw_slideshow_event(glw_t *w, event_t *e) { glw_root_t *gr = w->glw_root; glw_slideshow_t *s = (glw_slideshow_t *)w; glw_t *c; event_int_t *eu = (event_int_t *)e; if(event_is_action(e, ACTION_SKIP_FORWARD) || event_is_action(e, ACTION_RIGHT)) { c = w->glw_focused ? glw_next_widget(w->glw_focused) : NULL; if(c == NULL) c = glw_first_widget(w); w->glw_focused = c; s->deadline = 0; glw_need_refresh(gr, 0); } else if(event_is_action(e, ACTION_SKIP_BACKWARD) || event_is_action(e, ACTION_LEFT)) { c = w->glw_focused ? glw_prev_widget(w->glw_focused) : NULL; if(c == NULL) c = glw_last_widget(w, 0); w->glw_focused = c; s->deadline = 0; glw_need_refresh(gr, 0); } else if(event_is_type(e, EVENT_UNICODE) && eu->val == 32) { s->hold = !s->hold; glw_slideshow_update_playstatus(s); } else if(event_is_action(e, ACTION_PLAYPAUSE) || event_is_action(e, ACTION_PLAY) || event_is_action(e, ACTION_PAUSE)) { s->hold = action_update_hold_by_event(s->hold, e); glw_slideshow_update_playstatus(s); } else if(event_is_action(e, ACTION_STOP)) { prop_set_string(s->playstatus, "stop"); } else return 0; return 1; }
static void mod_video_flags(glw_t *w, int set, int clr) { if(w->glw_class->gc_mod_video_flags != NULL) w->glw_class->gc_mod_video_flags(w, set, clr); glw_need_refresh(w->glw_root, 0); }
static int mod_hidden(glw_view_eval_context_t *ec, const token_attrib_t *a, struct token *t) { int v = 0; if(t->type == TOKEN_INT) v = t->t_int; else if(t->type == TOKEN_FLOAT) v = t->t_float > 0.5; else if(t->type == TOKEN_VOID) v = 0; else return glw_view_seterr(ec->ei, t, "Invalid assignment for attribute %s", a->name); glw_t *w = ec->w; if(v) { if(w->glw_flags & GLW_HIDDEN) return 0; glw_hide(w); } else { if(!(w->glw_flags & GLW_HIDDEN)) return 0; glw_unhide(w); } glw_need_refresh(w->glw_root, 0); return 0; }
static void glw_slideshow_update_playstatus(glw_slideshow_t *s) { s->deadline = s->hold ? INT64_MAX : 0; glw_need_refresh(s->w.glw_root, 0); prop_set_string(s->playstatus, s->hold ? "pause" : "play"); }
static void set_alpha(glw_t *w, float v) { if(w->glw_alpha == v) return; w->glw_alpha = v; glw_need_refresh(w->glw_root, 0); }
static void set_blur(glw_t *w, float v) { v = GLW_CLAMP(1 - v, 0, 1); if(w->glw_sharpness == v) return; w->glw_sharpness = v; glw_need_refresh(w->glw_root, 0); }
static int set_align(glw_view_eval_context_t *ec, const token_attrib_t *a, struct token *t) { int v; if(t->type != TOKEN_IDENTIFIER || (v = str2val(rstr_get(t->t_rstring), aligntab)) < 0) return glw_view_seterr(ec->ei, t, "Invalid assignment for attribute %s", a->name); ec->w->glw_alignment = v; glw_need_refresh(ec->w->glw_root, 0); return 0; }
static void mod_flags2(glw_t *w, int set, int clr) { set &= ~w->glw_flags2; w->glw_flags2 |= set; clr &= w->glw_flags2; w->glw_flags2 &= ~clr; if((set | clr) && w->glw_class->gc_mod_flags2 != NULL) w->glw_class->gc_mod_flags2(w, set, clr); glw_need_refresh(w->glw_root, 0); }
void glw_scroll_layout(glw_scroll_control_t *gsc, glw_t *w, int height) { const int max_value = MAX(0, gsc->total_size - gsc->page_size + gsc->scroll_threshold_post); if(w->glw_root->gr_pointer_grab_scroll == w) { gsc->filtered_pos = gsc->target_pos; gsc->filtered_pos = GLW_CLAMP(gsc->filtered_pos, 0, max_value); } else if(fabsf(gsc->kinetic_scroll) > 0.5) { gsc->filtered_pos += gsc->kinetic_scroll; if(gsc->target_pos != gsc->filtered_pos) { gsc->target_pos = gsc->filtered_pos; glw_need_refresh(w->glw_root, 0); } gsc->kinetic_scroll *= 0.95; gsc->bottom_anchored = 0; gsc->filtered_pos = GLW_CLAMP(gsc->filtered_pos, 0, max_value); } else { gsc->kinetic_scroll = 0; if(gsc->bottom_gravity) { if(gsc->target_pos == max_value) { gsc->bottom_anchored = 1; } if(gsc->bottom_anchored) { if(gsc->target_pos != max_value) { w->glw_flags |= GLW_UPDATE_METRICS; } gsc->target_pos = max_value; } } gsc->target_pos = GLW_CLAMP(gsc->target_pos, 0, max_value); if(fabsf(gsc->target_pos - gsc->filtered_pos) > height * 2) { gsc->filtered_pos = gsc->target_pos; } else { glw_lp(&gsc->filtered_pos, w->glw_root, gsc->target_pos, 0.25); } } gsc->rounded_pos = rintf(gsc->filtered_pos * 5.0f) / 5.0f; }
static int set_transition_effect(glw_view_eval_context_t *ec, const token_attrib_t *a, struct token *t) { int v; if(t->type != TOKEN_IDENTIFIER || (v = str2val(rstr_get(t->t_rstring), transitiontab)) < 0) return glw_view_seterr(ec->ei, t, "Invalid assignment for attribute %s", a->name); if(ec->w->glw_class->gc_set_int != NULL) ec->w->glw_class->gc_set_int(ec->w, GLW_ATTRIB_TRANSITION_EFFECT, v); glw_need_refresh(ec->w->glw_root, 0); return 0; }
static void glw_bar_layout(glw_t *w, const glw_rctx_t *rc) { glw_bar_t *gb = (void *)w; float r, g, b, x; if(w->glw_alpha < GLW_ALPHA_EPSILON) return; if(!glw_renderer_initialized(&gb->gb_gr)) { glw_renderer_init_quad(&gb->gb_gr); gb->gb_update = 1; } if(gb->gb_update) { gb->gb_update = 0; r = GLW_LERP(gb->gb_fill, gb->gb_col1[0], gb->gb_col2[0]); g = GLW_LERP(gb->gb_fill, gb->gb_col1[1], gb->gb_col2[1]); b = GLW_LERP(gb->gb_fill, gb->gb_col1[2], gb->gb_col2[2]); x = GLW_LERP(gb->gb_fill, -1, 1); glw_renderer_vtx_pos(&gb->gb_gr, 0, -1.0, -1.0, 0.0); glw_renderer_vtx_col(&gb->gb_gr, 0, gb->gb_col1[0], gb->gb_col1[1], gb->gb_col1[2], 1.0); glw_renderer_vtx_pos(&gb->gb_gr, 1, x, -1.0, 0.0); glw_renderer_vtx_col(&gb->gb_gr, 1, r, g, b, 1.0); glw_renderer_vtx_pos(&gb->gb_gr, 2, x, 1.0, 0.0); glw_renderer_vtx_col(&gb->gb_gr, 2, r, g, b, 1.0); glw_renderer_vtx_pos(&gb->gb_gr, 3, -1.0, 1.0, 0.0); glw_renderer_vtx_col(&gb->gb_gr, 3, gb->gb_col1[0], gb->gb_col1[1], gb->gb_col1[2], 1.0); glw_need_refresh(w->glw_root, 0); } }
static void update_value_delta(glw_slider_t *s, float d) { if(s->p != NULL) { s->interpolate = 2; prop_add_float(s->p, d * (s->max - s->min)); } else { s->value = GLW_MAX(s->min, GLW_MIN(s->max, s->value + d)); s->interpolate = 1; if(s->bound_widget != NULL) { glw_scroll_t gs; gs.value = s->value; glw_signal0(s->bound_widget, GLW_SIGNAL_SCROLL, &gs); } glw_need_refresh(s->w.glw_root, 0); } }
static int64_t video_opengl_newframe(glw_video_t *gv, video_decoder_t *vd, int flags) { hts_mutex_assert(&gv->gv_surface_mutex); glw_video_surface_t *gvs; while((gvs = TAILQ_FIRST(&gv->gv_parked_queue)) != NULL) { TAILQ_REMOVE(&gv->gv_parked_queue, gvs, gvs_link); surface_init(gv, gvs); } glw_need_refresh(gv->w.glw_root, 0); gv_color_matrix_update(gv); return glw_video_newframe_blend(gv, vd, flags, &gv_surface_pixmap_release, 1); }
static void gtb_realize(glw_text_bitmap_t *gtb) { glw_root_t *gr = gtb->w.glw_root; int direct = gtb->gtb_maxlines > 1; if(gtb->gtb_state != GTB_IDLE && gtb->gtb_state != GTB_VALID) { gtb->gtb_deferred_realize = 1; return; } if(direct) { gtb->gtb_state = GTB_NEED_RENDER; glw_need_refresh(gr, 0); } else { TAILQ_INSERT_TAIL(&gr->gr_gtb_dim_queue, gtb, gtb_workq_link); gtb->gtb_state = GTB_QUEUED_FOR_DIMENSIONING; hts_cond_signal(&gr->gr_gtb_work_cond); } }
static int64_t gvv_newframe(glw_video_t *gv, video_decoder_t *vd0, int flags) { video_decoder_t *vd = gv->gv_vd; media_pipe_t *mp = gv->gv_mp; gv->gv_cmatrix_cur[0] = (gv->gv_cmatrix_cur[0] * 3.0f + gv->gv_cmatrix_tgt[0]) / 4.0f; if(flags & GLW_REINITIALIZE_VDPAU) { int i; for(i = 0; i < GLW_VIDEO_MAX_SURFACES; i++) gv->gv_surfaces[i].gvs_vdpau_surface = VDP_INVALID_HANDLE; gv->gv_engine = NULL; mp_send_cmd(mp, &mp->mp_video, MB_CTRL_REINITIALIZE); drain(gv, &gv->gv_displaying_queue); drain(gv, &gv->gv_decoded_queue); hts_cond_signal(&gv->gv_avail_queue_cond); return AV_NOPTS_VALUE; } glw_video_surface_t *gvs; while((gvs = TAILQ_FIRST(&gv->gv_parked_queue)) != NULL) { TAILQ_REMOVE(&gv->gv_parked_queue, gvs, gvs_link); surface_init(gv, gvs); } glw_need_refresh(gv->w.glw_root, 0); return glw_video_newframe_blend(gv, vd, flags, &gv_surface_pixmap_release, 1); }
static int set_source(glw_view_eval_context_t *ec, const token_attrib_t *a, struct token *t) { glw_t *w = ec->w; rstr_t *r; switch(t->type) { default: if(w->glw_class->gc_set_source != NULL) w->glw_class->gc_set_source(w, NULL); return 0; case TOKEN_VECTOR: if(w->glw_class->gc_set_sources != NULL) w->glw_class->gc_set_sources(w, build_rstr_vector(t)); return 0; case TOKEN_RSTRING: r = t->t_rstring; break; case TOKEN_LINK: r = t->t_link_rurl; break; } r = fa_absolute_path(r, t->file); if(w->glw_class->gc_set_source != NULL) w->glw_class->gc_set_source(w, r); glw_need_refresh(w->glw_root, 0); rstr_release(r); return 0; }
static void set_divider(glw_t *w, int v) { glw_conf_constraints(w, 0, 0, 0, GLW_CONSTRAINT_CONF_D); glw_need_refresh(w->glw_root, 0); }
static void glw_text_bitmap_layout(glw_t *w, const glw_rctx_t *rc) { glw_text_bitmap_t *gtb = (void *)w; glw_root_t *gr = w->glw_root; gr->gr_can_externalize = 0; // Initialize renderers if(unlikely(!glw_renderer_initialized(>b->gtb_text_renderer))) glw_renderer_init_quad(>b->gtb_text_renderer); if(w->glw_class == &glw_text && unlikely(!glw_renderer_initialized(>b->gtb_cursor_renderer))) glw_renderer_init_quad(>b->gtb_cursor_renderer); if(gtb->gtb_background_alpha > GLW_ALPHA_EPSILON && unlikely(!glw_renderer_initialized(>b->gtb_cursor_renderer))) { glw_renderer_init_quad(>b->gtb_background_renderer); glw_renderer_vtx_pos(>b->gtb_background_renderer, 0, -1, -1, 0); glw_renderer_vtx_pos(>b->gtb_background_renderer, 1, 1, -1, 0); glw_renderer_vtx_pos(>b->gtb_background_renderer, 2, 1, 1, 0); glw_renderer_vtx_pos(>b->gtb_background_renderer, 3, -1, 1, 0); } // Upload texture image_component_t *ic = image_find_component(gtb->gtb_image, IMAGE_PIXMAP); if(ic != NULL) { glw_tex_upload(gr, >b->gtb_texture, ic->pm, 0); gtb->gtb_margin = ic->pm->pm_margin; image_clear_component(ic); gtb->gtb_need_layout = 1; } const int tex_width = glw_tex_width(>b->gtb_texture); const int tex_height = glw_tex_height(>b->gtb_texture); ic = image_find_component(gtb->gtb_image, IMAGE_TEXT_INFO); image_component_text_info_t *ti = ic ? &ic->text_info : NULL; // Check if we need to repaint if(gtb->gtb_saved_width != rc->rc_width || gtb->gtb_saved_height != rc->rc_height) { if(ti != NULL && gtb->gtb_state == GTB_VALID) { if(ti->ti_flags & IMAGE_TEXT_WRAPPED) gtb->gtb_state = GTB_NEED_RENDER; if(rc->rc_width > gtb->gtb_saved_width && ti->ti_flags & IMAGE_TEXT_TRUNCATED) gtb->gtb_state = GTB_NEED_RENDER; if(gtb->gtb_flags & GTB_ELLIPSIZE) { if(ti->ti_flags & IMAGE_TEXT_TRUNCATED) { gtb->gtb_state = GTB_NEED_RENDER; } else { if(rc->rc_width - gtb->gtb_padding[2] - gtb->gtb_padding[0] < tex_width - gtb->gtb_margin * 2) gtb->gtb_state = GTB_NEED_RENDER; if(rc->rc_height - gtb->gtb_padding[1] - gtb->gtb_padding[3] < tex_height - gtb->gtb_margin * 2) gtb->gtb_state = GTB_NEED_RENDER; } } } gtb->gtb_saved_width = rc->rc_width; gtb->gtb_saved_height = rc->rc_height; gtb->gtb_update_cursor = 1; gtb->gtb_need_layout = 1; if(gtb->w.glw_flags2 & GLW2_DEBUG) printf(" textbitmap: Parent widget gives us :%d x %d ti=%p\n", rc->rc_width, rc->rc_height, ti); } if(ti != NULL && gtb->gtb_need_layout) { const int margin = gtb->gtb_margin; int left = gtb->gtb_padding[0] - margin; int top = rc->rc_height - gtb->gtb_padding[1] + margin; int right = rc->rc_width - gtb->gtb_padding[2] + margin; int bottom = gtb->gtb_padding[3] - margin; int text_width = tex_width; int text_height = tex_height; float x1, y1, x2, y2; if(gtb->w.glw_flags2 & GLW2_DEBUG) printf(" textbitmap: text_width:%d left:%d right:%d margin:%d\n", text_width, left, right, margin); // Vertical if(text_height > top - bottom) { // Oversized, must cut text_height = top - bottom; } else { switch(w->glw_alignment) { case LAYOUT_ALIGN_CENTER: case LAYOUT_ALIGN_LEFT: case LAYOUT_ALIGN_RIGHT: bottom = (bottom + top - text_height) / 2; top = bottom + text_height; break; case LAYOUT_ALIGN_TOP_LEFT: case LAYOUT_ALIGN_TOP_RIGHT: case LAYOUT_ALIGN_TOP: case LAYOUT_ALIGN_JUSTIFIED: bottom = top - tex_height; break; case LAYOUT_ALIGN_BOTTOM: case LAYOUT_ALIGN_BOTTOM_LEFT: case LAYOUT_ALIGN_BOTTOM_RIGHT: top = bottom + tex_height; break; } } y1 = -1.0f + 2.0f * bottom / (float)rc->rc_height; y2 = -1.0f + 2.0f * top / (float)rc->rc_height; // Horizontal if(text_width > right - left || ti->ti_flags & IMAGE_TEXT_TRUNCATED) { // Oversized, must cut text_width = right - left; if(gtb->w.glw_flags2 & GLW2_DEBUG) printf(" textbitmap: Oversized, must cut. Width is now %d\n", text_width); #if 0 if(!(gtb->gtb_flags & GTB_ELLIPSIZE)) { glw_renderer_vtx_col(>b->gtb_text_renderer, 0, 1,1,1,1+text_width/20); glw_renderer_vtx_col(>b->gtb_text_renderer, 1, 1,1,1,0); glw_renderer_vtx_col(>b->gtb_text_renderer, 2, 1,1,1,0); glw_renderer_vtx_col(>b->gtb_text_renderer, 3, 1,1,1,1+text_width/20); } #endif } else { glw_renderer_vtx_col_reset(>b->gtb_text_renderer); switch(w->glw_alignment) { case LAYOUT_ALIGN_JUSTIFIED: case LAYOUT_ALIGN_CENTER: case LAYOUT_ALIGN_BOTTOM: case LAYOUT_ALIGN_TOP: left = (left + right - text_width) / 2; right = left + text_width; break; case LAYOUT_ALIGN_LEFT: case LAYOUT_ALIGN_TOP_LEFT: case LAYOUT_ALIGN_BOTTOM_LEFT: right = left + tex_width; break; case LAYOUT_ALIGN_RIGHT: case LAYOUT_ALIGN_TOP_RIGHT: case LAYOUT_ALIGN_BOTTOM_RIGHT: left = right - tex_width; break; } } x1 = -1.0f + 2.0f * left / (float)rc->rc_width; x2 = -1.0f + 2.0f * right / (float)rc->rc_width; const float s = text_width / (float)tex_width; const float t = text_height / (float)tex_height; if(gtb->w.glw_flags2 & GLW2_DEBUG) printf(" s=%f t=%f\n", s, t); glw_renderer_vtx_pos(>b->gtb_text_renderer, 0, x1, y1, 0.0); glw_renderer_vtx_st (>b->gtb_text_renderer, 0, 0, t); glw_renderer_vtx_pos(>b->gtb_text_renderer, 1, x2, y1, 0.0); glw_renderer_vtx_st (>b->gtb_text_renderer, 1, s, t); glw_renderer_vtx_pos(>b->gtb_text_renderer, 2, x2, y2, 0.0); glw_renderer_vtx_st (>b->gtb_text_renderer, 2, s, 0); glw_renderer_vtx_pos(>b->gtb_text_renderer, 3, x1, y2, 0.0); glw_renderer_vtx_st (>b->gtb_text_renderer, 3, 0, 0); } if(w->glw_class == &glw_text && gtb->gtb_update_cursor && gtb->gtb_state == GTB_VALID) { int i = gtb->gtb_edit_ptr; int left; float x1, y1, x2, y2; if(ti != NULL && ti->ti_charpos != NULL) { if(i < ti->ti_charposlen) { left = ti->ti_charpos[i*2 ]; } else { left = ti->ti_charpos[2 * ti->ti_charposlen - 1]; } } else { left = 0; } left += gtb->gtb_padding[0]; x1 = -1.0f + 2.0f * (left - 1) / (float)rc->rc_width; x2 = -1.0f + 2.0f * (left ) / (float)rc->rc_width; y1 = -1.0f + 2.0f * gtb->gtb_padding[3] / (float)rc->rc_height; y2 = 1.0f - 2.0f * gtb->gtb_padding[1] / (float)rc->rc_height; glw_renderer_vtx_pos(>b->gtb_cursor_renderer, 0, x1, y1, 0.0); glw_renderer_vtx_pos(>b->gtb_cursor_renderer, 1, x2, y1, 0.0); glw_renderer_vtx_pos(>b->gtb_cursor_renderer, 2, x2, y2, 0.0); glw_renderer_vtx_pos(>b->gtb_cursor_renderer, 3, x1, y2, 0.0); if(w->glw_flags2 & GLW2_DEBUG) { printf("Cursor updated %f %f %f %f rect:%d,%d\n", x1, y1, x2, y2, rc->rc_width, rc->rc_height); } gtb->gtb_update_cursor = 0; } gtb->gtb_paint_cursor = gtb->gtb_flags & GTB_PERMANENT_CURSOR || (w->glw_class == &glw_text && glw_is_focused(w)); if(gtb->gtb_paint_cursor && rc->rc_alpha > GLW_ALPHA_EPSILON) glw_need_refresh(gr, 0); gtb->gtb_need_layout = 0; if(gtb->gtb_state == GTB_VALID && gtb->gtb_deferred_realize) { gtb->gtb_deferred_realize = 0; gtb_realize(gtb); } if(gtb->gtb_state != GTB_NEED_RENDER) return; TAILQ_INSERT_TAIL(&gr->gr_gtb_render_queue, gtb, gtb_workq_link); gtb->gtb_state = GTB_QUEUED_FOR_RENDERING; hts_cond_signal(&gr->gr_gtb_work_cond); }
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 set_weight(glw_t *w, float v) { glw_conf_constraints(w, 0, 0, v, GLW_CONSTRAINT_CONF_W); glw_need_refresh(w->glw_root, 0); }
static void set_width(glw_t *w, int v) { glw_conf_constraints(w, v, 0, 0, GLW_CONSTRAINT_CONF_X); glw_need_refresh(w->glw_root, 0); }
static void set_height(glw_t *w, int v) { glw_conf_constraints(w, 0, v, 0, GLW_CONSTRAINT_CONF_Y); glw_need_refresh(w->glw_root, 0); }