/** * clutter_color_shade: * @color: a #ClutterColor * @factor: the shade factor to apply * @result: (out): return location for the shaded color * * Shades @color by @factor and saves the modified color into @result. */ void clutter_color_shade (const ClutterColor *color, gdouble factor, ClutterColor *result) { float h, l, s; g_return_if_fail (color != NULL); g_return_if_fail (result != NULL); clutter_color_to_hls (color, &h, &l, &s); l *= factor; if (l > 1.0) l = 1.0; else if (l < 0) l = 0; s *= factor; if (s > 1.0) s = 1.0; else if (s < 0) s = 0; clutter_color_from_hls (result, h, l, s); result->alpha = color->alpha; }
//doc ClutterColor fromHLS(h, l, s) IO_METHOD(IoClutterColor, fromHLS) { ClutterColor color; float h = CNUMBER(IoMessage_locals_numberArgAt_(m, locals, 0)), l = CNUMBER(IoMessage_locals_numberArgAt_(m, locals, 1)), s = CNUMBER(IoMessage_locals_numberArgAt_(m, locals, 2)); clutter_color_from_hls(&color, h, l, s); return IoClutterColor_newWithColor(IOSTATE, color); }
/** * clutter_color_shade: * @color: a #ClutterColor * @factor: the shade factor to apply * @result: (out caller-allocates): return location for the shaded color * * Shades @color by @factor and saves the modified color into @result. */ void clutter_color_shade (const ClutterColor *color, gdouble factor, ClutterColor *result) { float h, l, s; g_return_if_fail (color != NULL); g_return_if_fail (result != NULL); clutter_color_to_hls (color, &h, &l, &s); l = CLAMP (l * factor, 0.0, 1.0); s = CLAMP (s * factor, 0.0, 1.0); clutter_color_from_hls (result, h, l, s); result->alpha = color->alpha; }
static void add_actor (ClutterContainer *container) { ClutterActor *rect; ClutterColor color = { 0xff, 0xff, 0xff, 255 }; static gboolean expand = TRUE; clutter_color_from_hls (&color, g_random_double_range (0.0, 360.0), 0.5, 0.5); rect = clutter_rectangle_new_with_color (&color); clutter_actor_set_size (rect, 32, 64); clutter_container_add_actor (container, rect); clutter_actor_set_reactive (rect, TRUE); g_signal_connect (rect, "enter-event", G_CALLBACK (enter_event), NULL); g_signal_connect (rect, "leave-event", G_CALLBACK (leave_event), NULL); g_signal_connect (rect, "button-release-event", G_CALLBACK (button_release_event), container); clutter_container_child_set (container, rect, "expand", expand, NULL); expand = !expand; }
static void frame_cb (ClutterTimeline *timeline, gint elapsed_msecs, TestState *state) { guint x, y; float period_progress = clutter_timeline_get_progress (timeline); float period_progress_sin = sinf (period_progress); float wave_shift = period_progress * WAVE_SPEED; float ripple_shift = period_progress * RIPPLE_SPEED; for (y = 0; y <= MESH_HEIGHT; y++) for (x = 0; x <= MESH_WIDTH; x++) { guint vert_index = (MESH_WIDTH + 1) * y + x; float *vert = &state->quad_mesh_verts[3 * vert_index]; float real_x = x * QUAD_WIDTH; float real_y = y * QUAD_HEIGHT; float wave_offset = (float)x / (MESH_WIDTH + 1); float wave_angle = (WAVE_PERIODS * 2 * G_PI * wave_offset) + wave_shift; float wave_sin = sinf (wave_angle); float a_sqr = (RIPPLE_CENTER_X - real_x) * (RIPPLE_CENTER_X - real_x); float b_sqr = (RIPPLE_CENTER_Y - real_y) * (RIPPLE_CENTER_Y - real_y); float ripple_offset = sqrtf (a_sqr + b_sqr) / RIPPLE_RADIUS; float ripple_angle = (RIPPLE_PERIODS * 2 * G_PI * ripple_offset) + ripple_shift; float ripple_sin = sinf (ripple_angle); float h, s, l; guint8 *color; vert[2] = (wave_sin * WAVE_DEPTH) + (ripple_sin * RIPPLE_DEPTH); /* Burn some CPU time picking a pretty color... */ h = (HSL_OFFSET + wave_sin + ripple_sin + period_progress_sin) * HSL_SCALE; s = 0.5; l = 0.25 + (period_progress_sin + 1.0) / 4.0; color = &state->quad_mesh_colors[4 * vert_index]; /* A bit of a sneaky cast, but it seems safe to assume the ClutterColor * typedef is set in stone... */ clutter_color_from_hls ((ClutterColor *)color, h * 360.0, l, s); color[0] = (color[0] * color[3] + 128) / 255; color[1] = (color[1] * color[3] + 128) / 255; color[2] = (color[2] * color[3] + 128) / 255; } cogl_vertex_buffer_add (state->buffer, "gl_Vertex", 3, /* n components */ COGL_ATTRIBUTE_TYPE_FLOAT, FALSE, /* normalized */ 0, /* stride */ state->quad_mesh_verts); cogl_vertex_buffer_add (state->buffer, "gl_Color", 4, /* n components */ COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE, FALSE, /* normalized */ 0, /* stride */ state->quad_mesh_colors); cogl_vertex_buffer_submit (state->buffer); clutter_actor_set_rotation (state->dummy, CLUTTER_Z_AXIS, 360 * period_progress, (MESH_WIDTH * QUAD_WIDTH) / 2, (MESH_HEIGHT * QUAD_HEIGHT) / 2, 0); clutter_actor_set_rotation (state->dummy, CLUTTER_X_AXIS, 360 * period_progress, (MESH_WIDTH * QUAD_WIDTH) / 2, (MESH_HEIGHT * QUAD_HEIGHT) / 2, 0); }
static gboolean parse_hsla (ClutterColor *color, gchar *str, gboolean has_alpha) { gdouble number; gdouble h, l, s; skip_whitespace (&str); if (*str != '(') return FALSE; str += 1; /* hue */ skip_whitespace (&str); /* we don't do any angle normalization here because * clutter_color_from_hls() will do it for us */ number = g_ascii_strtod (str, &str); skip_whitespace (&str); if (*str != ',') return FALSE; h = number; str += 1; /* saturation */ skip_whitespace (&str); number = g_ascii_strtod (str, &str); skip_whitespace (&str); if (*str != '%') return FALSE; str += 1; s = CLAMP (number / 100.0, 0.0, 1.0); skip_whitespace (&str); if (*str != ',') return FALSE; str += 1; /* luminance */ skip_whitespace (&str); number = g_ascii_strtod (str, &str); skip_whitespace (&str); if (*str != '%') return FALSE; str += 1; l = CLAMP (number / 100.0, 0.0, 1.0); skip_whitespace (&str); /* alpha (optional); since the alpha channel value can only * be between 0 and 1 we don't use the parse_rgb_value() * function */ if (has_alpha) { if (*str != ',') return FALSE; str += 1; skip_whitespace (&str); number = g_ascii_strtod (str, &str); color->alpha = CLAMP (number * 255.0, 0, 255); } else color->alpha = 255; skip_whitespace (&str); if (*str != ')') return FALSE; clutter_color_from_hls (color, h, l, s); return TRUE; }
static void add_actor (ClutterActor *box, gint left, gint top, gint width, gint height) { ClutterLayoutManager *layout; ClutterActor *rect, *text; ClutterColor color; clutter_color_from_hls (&color, g_random_double_range (0.0, 360.0), 0.5, 0.5); color.alpha = 255; rect = clutter_actor_new (); clutter_actor_set_layout_manager (rect, clutter_bin_layout_new ()); clutter_actor_set_background_color (rect, &color); clutter_actor_set_reactive (rect, TRUE); if (random_size) clutter_actor_set_size (rect, g_random_int_range (40, 80), g_random_int_range (40, 80)); else clutter_actor_set_size (rect, 60, 60); clutter_actor_set_x_expand (rect, default_expand); clutter_actor_set_y_expand (rect, default_expand); if (!default_expand) { clutter_actor_set_x_align (rect, CLUTTER_ACTOR_ALIGN_CENTER); clutter_actor_set_y_align (rect, CLUTTER_ACTOR_ALIGN_CENTER); } if (random_align) { clutter_actor_set_x_align (rect, g_random_int_range (0, 3)); clutter_actor_set_y_align (rect, g_random_int_range (0, 3)); } text = clutter_text_new_with_text ("Sans 8px", NULL); clutter_text_set_line_alignment (CLUTTER_TEXT (text), PANGO_ALIGN_CENTER); clutter_actor_add_child (rect, text); g_signal_connect (rect, "button-release-event", G_CALLBACK (button_release_cb), NULL); g_signal_connect (rect, "notify::x-expand", G_CALLBACK (changed_cb), text); g_signal_connect (rect, "notify::y-expand", G_CALLBACK (changed_cb), text); g_signal_connect (rect, "notify::x-align", G_CALLBACK (changed_cb), text); g_signal_connect (rect, "notify::y-align", G_CALLBACK (changed_cb), text); layout = clutter_actor_get_layout_manager (box); if (use_box) clutter_actor_add_child (box, rect); else clutter_grid_layout_attach (CLUTTER_GRID_LAYOUT (layout), rect, left, top, width, height); changed_cb (rect, NULL, text); }
int main (int argc, char *argv[]) { ClutterActor *stage, *box; ClutterLayoutManager *layout; GError *error; gint i; error = NULL; if (clutter_init_with_args (&argc, &argv, NULL, entries, NULL, &error) != CLUTTER_INIT_SUCCESS) { g_print ("Unable to run flow-layout: %s", error->message); g_error_free (error); return EXIT_FAILURE; } stage = clutter_stage_new (); clutter_actor_set_background_color (stage, CLUTTER_COLOR_LightSkyBlue); clutter_stage_set_title (CLUTTER_STAGE (stage), "Flow Layout"); clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); layout = clutter_flow_layout_new (vertical ? CLUTTER_FLOW_VERTICAL : CLUTTER_FLOW_HORIZONTAL); clutter_flow_layout_set_homogeneous (CLUTTER_FLOW_LAYOUT (layout), is_homogeneous); clutter_flow_layout_set_column_spacing (CLUTTER_FLOW_LAYOUT (layout), x_spacing); clutter_flow_layout_set_row_spacing (CLUTTER_FLOW_LAYOUT (layout), y_spacing); box = clutter_actor_new (); clutter_actor_set_layout_manager (box, layout); clutter_actor_set_background_color (box, CLUTTER_COLOR_Aluminium2); clutter_actor_add_child (stage, box); if (!fixed_size) clutter_actor_add_constraint (box, clutter_bind_constraint_new (stage, CLUTTER_BIND_SIZE, 0.0)); clutter_actor_set_position (box, 0, 0); clutter_actor_set_name (box, "box"); for (i = 0; i < n_rects; i++) { ClutterColor color = CLUTTER_COLOR_INIT (255, 255, 255, 255); gfloat width, height; ClutterActor *rect; gchar *name; name = g_strdup_printf ("rect%02d", i); clutter_color_from_hls (&color, 360.0 / n_rects * i, 0.5, 0.8); rect = clutter_actor_new (); clutter_actor_set_background_color (rect, &color); if (random_size) { width = g_random_int_range (50, 100); height = g_random_int_range (50, 100); } else width = height = 50.f; clutter_actor_set_size (rect, width, height); clutter_actor_set_name (rect, name); clutter_actor_add_child (box, rect); g_free (name); } clutter_actor_show (stage); clutter_main (); return EXIT_SUCCESS; }