Пример #1
0
void
glw_layout0(glw_t *w, glw_rctx_t *rc)
{
  glw_root_t *gr = w->glw_root;
  LIST_REMOVE(w, glw_active_link);
  LIST_INSERT_HEAD(&gr->gr_active_list, w, glw_active_link);
  if(!(w->glw_flags & GLW_ACTIVE)) {
    w->glw_flags |= GLW_ACTIVE;
    glw_signal0(w, GLW_SIGNAL_ACTIVE, NULL);
  }
  glw_signal0(w, GLW_SIGNAL_LAYOUT, rc);
}
Пример #2
0
static void
mod_flags1(glw_t *w, int set, int clr)
{
  set &= ~w->glw_flags; // Mask out already set flags
  w->glw_flags |= set;

  if(set & GLW_HIDDEN)
    glw_signal0(w->glw_parent, GLW_SIGNAL_CHILD_HIDDEN, w);

  clr &= w->glw_flags;
  w->glw_flags &= ~clr;
  
  if(clr & GLW_HIDDEN)
    glw_signal0(w->glw_parent, GLW_SIGNAL_CHILD_UNHIDDEN, w);
}
Пример #3
0
static int
slider_bound_callback(glw_t *w, void *opaque, glw_signal_t signal, void *extra)
{
  glw_slider_t *s = opaque;
  glw_slider_metrics_t *m = extra;

  switch(signal) {

  case GLW_SIGNAL_DESTROY:
    s->bound_widget = NULL;
    break;

  case GLW_SIGNAL_SLIDER_METRICS:
    s->fixed_knob_size = 1;
    s->value = m->position;
    s->interpolate = 0;
    s->knob_size_fixed = m->knob_size;

    if((s->knob_size_fixed != 1.0) == !(s->w.glw_flags & GLW_CAN_SCROLL)) {
      s->w.glw_flags ^= GLW_CAN_SCROLL;
      glw_signal0(&s->w, GLW_SIGNAL_CAN_SCROLL_CHANGED, NULL);
    }
    break;

  default:
    break;
  }
  return 0;
}
Пример #4
0
static int
glw_image_callback(glw_t *w, void *opaque, glw_signal_t signal,
		    void *extra)
{
  glw_t *c;
  switch(signal) {
  default:
    break;
  case GLW_SIGNAL_LAYOUT:
    glw_image_layout(w, extra);
    break;
  case GLW_SIGNAL_EVENT:
    TAILQ_FOREACH(c, &w->glw_childs, glw_parent_link)
      if(glw_signal0(c, GLW_SIGNAL_EVENT, extra))
	return 1;
    break;

  case GLW_SIGNAL_CHILD_CONSTRAINTS_CHANGED:
  case GLW_SIGNAL_CHILD_CREATED:
    glw_image_update_constraints((glw_image_t *)w);
    return 1;
  case GLW_SIGNAL_CHILD_DESTROYED:
    glw_set_constraints(w, 0, 0, 0, 0);
    return 1;

  }
  return 0;
}
Пример #5
0
int
glw_navigate_move(glw_t *w, int steps)
{
  glw_move_op_t mop = {0};
  mop.steps = steps;
  glw_signal0(w, GLW_SIGNAL_MOVE, &mop);
  return mop.did_move;
}
Пример #6
0
static void
update_value_delta(glw_slider_t *s, float d)
{
  if(s->p != NULL)
    prop_add_float(s->p, d * (s->max - s->min));
  else {
    s->value = GLW_MAX(s->min, GLW_MIN(s->max, s->value + d));
    if(s->bound_widget != NULL) {
      glw_scroll_t gs;
      gs.value = s->value;
      glw_signal0(s->bound_widget, GLW_SIGNAL_SCROLL, &gs);
    }
  }
}
Пример #7
0
int
glw_navigate_may_wrap(glw_t *w)
{
  if(!(w->glw_flags2 & GLW2_NAV_WRAP)) {
    return 0;
  }
  if(!glw_settings.gs_wrap) {
    return 0;
  }
  int may_wrap = 1;
  glw_signal0(w, GLW_SIGNAL_WRAP_CHECK, &may_wrap);
  return may_wrap;

}
Пример #8
0
void
glw_scroll_update_metrics(glw_scroll_control_t *gsc, glw_t *w)
{
  float v;
  int do_update = 0;

  w->glw_flags &= ~GLW_UPDATE_METRICS;

  v = GLW_MIN(1.0f, (float)gsc->page_size / gsc->total_size);

  if(v != gsc->metrics.knob_size) {
    do_update = 1;
    gsc->metrics.knob_size = v;
  }
  
  v = GLW_MAX(0, (float)gsc->target_pos / (gsc->total_size - gsc->page_size + gsc->scroll_threshold_post));

  if(v != gsc->metrics.position) {
    do_update = 1;
    gsc->metrics.position = v;
  }
  
  if(!do_update)
    return;

  if(gsc->total_size > gsc->page_size && !(w->glw_flags & GLW_CAN_SCROLL)) {
    w->glw_flags |= GLW_CAN_SCROLL;
    glw_signal0(w, GLW_SIGNAL_CAN_SCROLL_CHANGED, NULL);
    
  } else if(gsc->total_size <= gsc->page_size &&
	    w->glw_flags & GLW_CAN_SCROLL) {
    w->glw_flags &= ~GLW_CAN_SCROLL;
    glw_signal0(w, GLW_SIGNAL_CAN_SCROLL_CHANGED, NULL);
  }

  glw_signal0(w, GLW_SIGNAL_SLIDER_METRICS, &gsc->metrics);
}
Пример #9
0
static void
update_value(glw_slider_t *s, float v, int how)
{
  v = GLW_MAX(0, GLW_MIN(1.0, v));

  if(s->p != NULL)
    prop_set_float_ex(s->p, NULL, v * (s->max - s->min) + s->min, how);
  else {
    s->value = v;
    if(s->bound_widget != NULL) {
      glw_scroll_t gs;
      gs.value = s->value;
      glw_signal0(s->bound_widget, GLW_SIGNAL_SCROLL, &gs);
    }
  }
}
Пример #10
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);
  }
}
Пример #11
0
void
glw_scroll_suggest_focus(glw_scroll_control_t *gsc, glw_t *w, glw_t *c)
{
  if(!glw_is_focused(w)) {
    w->glw_focused = c;
    glw_signal0(w, GLW_SIGNAL_FOCUS_CHILD_INTERACTIVE, c);
    gsc->scroll_to_me = c;
    return;
  }

  if(gsc->suggested == w->glw_focused || gsc->suggest_cnt > 0) {
    c = glw_focus_by_path(c);
    if(c != NULL)
      glw_focus_set(c->glw_root, c, GLW_FOCUS_SET_SUGGESTED, "Suggested");
    gsc->suggest_cnt = 1;
  }
  gsc->suggested = c;
  gsc->suggest_cnt++;
}
Пример #12
0
void
glw_scroll_handle_scroll(glw_scroll_control_t *gsc, glw_t *w, glw_scroll_t *gs)
{
  int top = GLW_MAX(gs->value * (gsc->total_size - gsc->page_size
                                 + gsc->scroll_threshold_post), 0);
  gsc->target_pos = top;
  glw_schedule_refresh(w->glw_root, 0);

  if(gsc->chase_focus == 0)
    return;

  glw_t *c = w->glw_class->gc_find_visible_child(w);
  if(c == NULL)
    return;

  if(glw_is_focused(w)) {
    glw_focus_set(w->glw_root, c, GLW_FOCUS_SET_SUGGESTED, "Scroll");
  } else {
    w->glw_focused = c;
    glw_signal0(w, GLW_SIGNAL_FOCUS_CHILD_INTERACTIVE, c);
  }
}
Пример #13
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;
  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);
  }
}
Пример #14
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);
  }
}