diff --git a/src/st/st-theme-node-drawing.c b/src/st/st-theme-node-drawing.c index 4a17ac2da..6e71c9881 100644 --- a/src/st/st-theme-node-drawing.c +++ b/src/st/st-theme-node-drawing.c @@ -49,6 +49,22 @@ typedef struct { guint border_width_2; } StCornerSpec; +static void +elliptical_arc (cairo_t *cr, + double x_center, + double y_center, + double x_radius, + double y_radius, + double angle1, + double angle2) +{ + cairo_save (cr); + cairo_translate (cr, x_center, y_center); + cairo_scale (cr, x_radius, y_radius); + cairo_arc (cr, 0, 0, 1.0, angle1, angle2); + cairo_restore (cr); +} + static CoglHandle create_corner_material (StCornerSpec *corner) { @@ -73,13 +89,11 @@ create_corner_material (StCornerSpec *corner) cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_scale (cr, size, size); - /* TODO support nonuniform border widths */ - - if (corner->border_width_1 < corner->radius) + if (max_border_width <= corner->radius) { - double internal_radius = 0.5 * (1.0 - (double) corner->border_width_1 / corner->radius); + double x_radius, y_radius; - if (corner->border_width_1 != 0) + if (max_border_width != 0) { cairo_set_source_rgba (cr, corner->border_color_1.red / 255., @@ -96,14 +110,41 @@ create_corner_material (StCornerSpec *corner) corner->color.green / 255., corner->color.blue / 255., corner->color.alpha / 255.); - cairo_arc (cr, 0.5, 0.5, internal_radius, 0, 2 * M_PI); + + x_radius = 0.5 * (1.0 - (double) corner->border_width_2 / corner->radius); + y_radius = 0.5 * (1.0 - (double) corner->border_width_1 / corner->radius); + + /* TOPRIGHT */ + elliptical_arc (cr, + 0.5, 0.5, + x_radius, y_radius, + 3 * M_PI / 2, 2 * M_PI); + + /* BOTTOMRIGHT */ + elliptical_arc (cr, + 0.5, 0.5, + x_radius, y_radius, + 0, M_PI / 2); + + /* TOPLEFT */ + elliptical_arc (cr, + 0.5, 0.5, + x_radius, y_radius, + M_PI, 3 * M_PI / 2); + + /* BOTTOMLEFT */ + elliptical_arc (cr, + 0.5, 0.5, + x_radius, y_radius, + M_PI / 2, M_PI); + cairo_fill (cr); } else { double radius; - radius = (gdouble)corner->radius / corner->border_width_1; + radius = (gdouble)corner->radius / max_border_width; cairo_set_source_rgba (cr, corner->border_color_1.red / 255., @@ -216,6 +257,41 @@ over (const ClutterColor *source, unpremultiply (result); } +static void +st_theme_node_get_corner_border_widths (StThemeNode *node, + StCorner corner_id, + guint *border_width_1, + guint *border_width_2) +{ + switch (corner_id) + { + case ST_CORNER_TOPLEFT: + if (border_width_1) + *border_width_1 = node->border_width[ST_SIDE_TOP]; + if (border_width_2) + *border_width_2 = node->border_width[ST_SIDE_LEFT]; + break; + case ST_CORNER_TOPRIGHT: + if (border_width_1) + *border_width_1 = node->border_width[ST_SIDE_TOP]; + if (border_width_2) + *border_width_2 = node->border_width[ST_SIDE_RIGHT]; + break; + case ST_CORNER_BOTTOMRIGHT: + if (border_width_1) + *border_width_1 = node->border_width[ST_SIDE_BOTTOM]; + if (border_width_2) + *border_width_2 = node->border_width[ST_SIDE_RIGHT]; + break; + case ST_CORNER_BOTTOMLEFT: + if (border_width_1) + *border_width_1 = node->border_width[ST_SIDE_BOTTOM]; + if (border_width_2) + *border_width_2 = node->border_width[ST_SIDE_LEFT]; + break; + } +} + static CoglHandle st_theme_node_lookup_corner (StThemeNode *node, StCorner corner_id) @@ -233,30 +309,25 @@ st_theme_node_lookup_corner (StThemeNode *node, corner.radius = node->border_radius[corner_id]; corner.color = node->background_color; + st_theme_node_get_corner_border_widths (node, corner_id, + &corner.border_width_1, + &corner.border_width_2); switch (corner_id) { case ST_CORNER_TOPLEFT: - corner.border_width_1 = node->border_width[ST_SIDE_TOP]; - corner.border_width_2 = node->border_width[ST_SIDE_LEFT]; over (&node->border_color[ST_SIDE_TOP], &corner.color, &corner.border_color_1); over (&node->border_color[ST_SIDE_LEFT], &corner.color, &corner.border_color_2); break; case ST_CORNER_TOPRIGHT: - corner.border_width_1 = node->border_width[ST_SIDE_TOP]; - corner.border_width_2 = node->border_width[ST_SIDE_RIGHT]; over (&node->border_color[ST_SIDE_TOP], &corner.color, &corner.border_color_1); over (&node->border_color[ST_SIDE_RIGHT], &corner.color, &corner.border_color_2); break; case ST_CORNER_BOTTOMRIGHT: - corner.border_width_1 = node->border_width[ST_SIDE_BOTTOM]; - corner.border_width_2 = node->border_width[ST_SIDE_RIGHT]; over (&node->border_color[ST_SIDE_BOTTOM], &corner.color, &corner.border_color_1); over (&node->border_color[ST_SIDE_RIGHT], &corner.color, &corner.border_color_2); break; case ST_CORNER_BOTTOMLEFT: - corner.border_width_1 = node->border_width[ST_SIDE_BOTTOM]; - corner.border_width_2 = node->border_width[ST_SIDE_LEFT]; over (&node->border_color[ST_SIDE_BOTTOM], &corner.color, &corner.border_color_1); over (&node->border_color[ST_SIDE_LEFT], &corner.color, &corner.border_color_2); break; @@ -346,28 +417,14 @@ get_background_position (StThemeNode *self, } /* Use of this function marks code which doesn't support - * non-uniform widths and/or colors. + * non-uniform colors. */ -static gboolean -get_arbitrary_border (StThemeNode *node, - int *width, - ClutterColor *color) +static void +get_arbitrary_border_color (StThemeNode *node, + ClutterColor *color) { - int w; - - w = st_theme_node_get_border_width (node, ST_SIDE_TOP); - if (w > 0) - { - if (width) - *width = w; - if (color) - st_theme_node_get_border_color (node, ST_SIDE_TOP, color); - return TRUE; - } - - if (width) - *width = 0; - return FALSE; + if (color) + st_theme_node_get_border_color (node, ST_SIDE_TOP, color); } static CoglHandle @@ -379,7 +436,7 @@ st_theme_node_render_gradient (StThemeNode *node) cairo_surface_t *surface; cairo_pattern_t *pattern; ClutterColor border_color; - int border_width; + int border_width[4]; guint rowstride; guchar *data; @@ -392,11 +449,15 @@ st_theme_node_render_gradient (StThemeNode *node) rowstride); cr = cairo_create (surface); - /* TODO - support non-uniform border colors and widths */ - get_arbitrary_border (node, &border_width, &border_color); + /* TODO - support non-uniform border colors */ + get_arbitrary_border_color (node, &border_color); for (i = 0; i < 4; i++) - radius[i] = st_theme_node_get_border_radius (node, i); + { + border_width[i] = st_theme_node_get_border_width (node, i); + + radius[i] = st_theme_node_get_border_radius (node, i); + } if (node->background_gradient_type == ST_GRADIENT_VERTICAL) pattern = cairo_pattern_create_linear (0, 0, 0, node->alloc_height); @@ -437,13 +498,13 @@ st_theme_node_render_gradient (StThemeNode *node) radius[ST_CORNER_TOPRIGHT], radius[ST_CORNER_TOPRIGHT], 3 * M_PI / 2, 2 * M_PI); cairo_line_to (cr, node->alloc_width, node->alloc_height - radius[ST_CORNER_BOTTOMRIGHT]); - if (radius[ST_CORNER_BOTTOMRIGHT]) + if (radius[ST_CORNER_BOTTOMRIGHT] > 0) cairo_arc (cr, node->alloc_width - radius[ST_CORNER_BOTTOMRIGHT], node->alloc_height - radius[ST_CORNER_BOTTOMRIGHT], radius[ST_CORNER_BOTTOMRIGHT], 0, M_PI / 2); cairo_line_to (cr, radius[ST_CORNER_BOTTOMLEFT], node->alloc_height); - if (radius[ST_CORNER_BOTTOMLEFT]) + if (radius[ST_CORNER_BOTTOMLEFT] > 0) cairo_arc (cr, radius[ST_CORNER_BOTTOMLEFT], node->alloc_height - radius[ST_CORNER_BOTTOMLEFT], @@ -456,7 +517,10 @@ st_theme_node_render_gradient (StThemeNode *node) * otherwise the outline shape is filled with the background * gradient directly */ - if (border_width > 0) + if (border_width[ST_SIDE_TOP] > 0 || + border_width[ST_SIDE_RIGHT] > 0 || + border_width[ST_SIDE_BOTTOM] > 0 || + border_width[ST_SIDE_LEFT] > 0) { cairo_set_source_rgba (cr, border_color.red / 255., @@ -465,47 +529,70 @@ st_theme_node_render_gradient (StThemeNode *node) border_color.alpha / 255.); cairo_fill (cr); - if (radius[ST_CORNER_TOPLEFT] > border_width) - cairo_arc (cr, - radius[ST_CORNER_TOPLEFT], - radius[ST_CORNER_TOPLEFT], - radius[ST_CORNER_TOPLEFT] - border_width, - M_PI, 3 * M_PI / 2); + if (radius[ST_CORNER_TOPLEFT] > MAX(border_width[ST_SIDE_TOP], + border_width[ST_SIDE_LEFT])) + elliptical_arc (cr, + radius[ST_CORNER_TOPLEFT], + radius[ST_CORNER_TOPLEFT], + radius[ST_CORNER_TOPLEFT] - border_width[ST_SIDE_LEFT], + radius[ST_CORNER_TOPLEFT] - border_width[ST_SIDE_TOP], + M_PI, 3 * M_PI / 2); else - cairo_move_to (cr, border_width, border_width); + cairo_move_to (cr, + border_width[ST_SIDE_LEFT], + border_width[ST_SIDE_TOP]); cairo_line_to (cr, - node->alloc_width - MAX(radius[ST_CORNER_TOPRIGHT], border_width), - border_width); + node->alloc_width - MAX(radius[ST_CORNER_TOPRIGHT], border_width[ST_SIDE_RIGHT]), + border_width[ST_SIDE_TOP]); - if (radius[ST_CORNER_TOPRIGHT] > border_width) - cairo_arc (cr, - node->alloc_width - radius[ST_CORNER_TOPRIGHT], - radius[ST_CORNER_TOPRIGHT], - radius[ST_CORNER_TOPRIGHT] - border_width, - 3 * M_PI / 2, 2 * M_PI); + if (radius[ST_CORNER_TOPRIGHT] > MAX(border_width[ST_SIDE_TOP], + border_width[ST_SIDE_RIGHT])) + elliptical_arc (cr, + node->alloc_width - radius[ST_CORNER_TOPRIGHT], + radius[ST_CORNER_TOPRIGHT], + radius[ST_CORNER_TOPRIGHT] - border_width[ST_SIDE_RIGHT], + radius[ST_CORNER_TOPRIGHT] - border_width[ST_SIDE_TOP], + 3 * M_PI / 2, 2 * M_PI); + else + cairo_line_to (cr, + node->alloc_width - border_width[ST_SIDE_RIGHT], + border_width[ST_SIDE_TOP]); cairo_line_to (cr, - node->alloc_width - border_width, - node->alloc_height - MAX(radius[ST_CORNER_BOTTOMRIGHT], border_width)); + node->alloc_width - border_width[ST_SIDE_RIGHT], + node->alloc_height - MAX(radius[ST_CORNER_BOTTOMRIGHT], border_width[ST_SIDE_BOTTOM])); - if (radius[ST_CORNER_BOTTOMRIGHT] > border_width) - cairo_arc (cr, - node->alloc_width - radius[ST_CORNER_BOTTOMRIGHT], - node->alloc_height - radius[ST_CORNER_BOTTOMRIGHT], - radius[ST_CORNER_BOTTOMRIGHT] - border_width, - 0, M_PI / 2); + if (radius[ST_CORNER_BOTTOMRIGHT] > MAX(border_width[ST_SIDE_BOTTOM], + border_width[ST_SIDE_RIGHT])) + elliptical_arc (cr, + node->alloc_width - radius[ST_CORNER_BOTTOMRIGHT], + node->alloc_height - radius[ST_CORNER_BOTTOMRIGHT], + radius[ST_CORNER_BOTTOMRIGHT] - border_width[ST_SIDE_RIGHT], + radius[ST_CORNER_BOTTOMRIGHT] - border_width[ST_SIDE_BOTTOM], + 0, M_PI / 2); + else + cairo_line_to (cr, + node->alloc_width - border_width[ST_SIDE_RIGHT], + node->alloc_height - border_width[ST_SIDE_BOTTOM]); cairo_line_to (cr, - MAX(radius[ST_CORNER_BOTTOMLEFT], border_width), - node->alloc_height - border_width); + MAX(radius[ST_CORNER_BOTTOMLEFT], border_width[ST_SIDE_LEFT]), + node->alloc_height - border_width[ST_SIDE_BOTTOM]); + + if (radius[ST_CORNER_BOTTOMLEFT] > MAX(border_width[ST_SIDE_BOTTOM], + border_width[ST_SIDE_LEFT])) + elliptical_arc (cr, + radius[ST_CORNER_BOTTOMLEFT], + node->alloc_height - radius[ST_CORNER_BOTTOMLEFT], + radius[ST_CORNER_BOTTOMLEFT] - border_width[ST_SIDE_LEFT], + radius[ST_CORNER_BOTTOMLEFT] - border_width[ST_SIDE_BOTTOM], + M_PI / 2, M_PI); + else + cairo_line_to (cr, + border_width[ST_SIDE_LEFT], + node->alloc_height - border_width[ST_SIDE_BOTTOM]); - if (radius[ST_CORNER_BOTTOMLEFT] > border_width) - cairo_arc (cr, - radius[ST_CORNER_BOTTOMLEFT], - node->alloc_height - radius[ST_CORNER_BOTTOMLEFT], - radius[ST_CORNER_BOTTOMLEFT] - border_width, - M_PI / 2, M_PI); cairo_close_path (cr); } @@ -706,27 +793,40 @@ st_theme_node_paint_borders (StThemeNode *node, { float width, height; - int border_width; + int border_width[4]; int max_border_radius = 0; int max_width_radius[4]; - int corner_id; + int corner_id, side_id; ClutterColor border_color; guint8 alpha; width = box->x2 - box->x1; height = box->y2 - box->y1; - get_arbitrary_border (node, &border_width, &border_color); + /* TODO - support non-uniform border colors */ + get_arbitrary_border_color (node, &border_color); + + for (side_id = 0; side_id < 4; side_id++) + border_width[side_id] = st_theme_node_get_border_width(node, side_id); + for (corner_id = 0; corner_id < 4; corner_id++) { + guint border_width_1, border_width_2; + + st_theme_node_get_corner_border_widths (node, corner_id, + &border_width_1, &border_width_2); + if (node->border_radius[corner_id] > max_border_radius) max_border_radius = node->border_radius[corner_id]; - max_width_radius[corner_id] = MAX(border_width, + max_width_radius[corner_id] = MAX(MAX(border_width_1, border_width_2), node->border_radius[corner_id]); } /* borders */ - if (border_width > 0) + if (border_width[ST_SIDE_TOP] > 0 || + border_width[ST_SIDE_RIGHT] > 0 || + border_width[ST_SIDE_BOTTOM] > 0 || + border_width[ST_SIDE_LEFT] > 0) { ClutterColor effective_border; gboolean skip_corner_1, skip_corner_2; @@ -749,18 +849,19 @@ st_theme_node_paint_borders (StThemeNode *node, x1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT] : 0; y1 = 0; x2 = skip_corner_2 ? width - max_width_radius[ST_CORNER_TOPRIGHT] : width; - y2 = border_width; + y2 = border_width[ST_SIDE_TOP]; cogl_rectangle (x1, y1, x2, y2); /* EAST */ skip_corner_1 = node->border_radius[ST_CORNER_TOPRIGHT] > 0; skip_corner_2 = node->border_radius[ST_CORNER_BOTTOMRIGHT] > 0; - x1 = width - border_width; - y1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPRIGHT] : border_width; + x1 = width - border_width[ST_SIDE_RIGHT]; + y1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPRIGHT] + : border_width[ST_SIDE_TOP]; x2 = width; y2 = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMRIGHT] - : height - border_width; + : height - border_width[ST_SIDE_BOTTOM]; cogl_rectangle (x1, y1, x2, y2); /* SOUTH */ @@ -768,7 +869,7 @@ st_theme_node_paint_borders (StThemeNode *node, skip_corner_2 = node->border_radius[ST_CORNER_BOTTOMRIGHT] > 0; x1 = skip_corner_1 ? max_width_radius[ST_CORNER_BOTTOMLEFT] : 0; - y1 = height - border_width; + y1 = height - border_width[ST_SIDE_BOTTOM]; x2 = skip_corner_2 ? width - max_width_radius[ST_CORNER_BOTTOMRIGHT] : width; y2 = height; @@ -779,10 +880,11 @@ st_theme_node_paint_borders (StThemeNode *node, skip_corner_2 = node->border_radius[ST_CORNER_BOTTOMLEFT] > 0; x1 = 0; - y1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT] : border_width; - x2 = border_width; + y1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT] + : border_width[ST_SIDE_TOP]; + x2 = border_width[ST_SIDE_LEFT]; y2 = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMLEFT] - : height - border_width; + : height - border_width[ST_SIDE_BOTTOM]; cogl_rectangle (x1, y1, x2, y2); } } @@ -853,82 +955,99 @@ st_theme_node_paint_borders (StThemeNode *node, switch (corner_id) { case ST_CORNER_TOPLEFT: - verts[0] = border_width; - verts[1] = max_width_radius[ST_CORNER_TOPLEFT]; + verts[0] = border_width[ST_SIDE_LEFT]; + verts[1] = MAX(node->border_radius[corner_id], + border_width[ST_SIDE_TOP]); verts[2] = max_border_radius; verts[3] = max_border_radius; if (n_rects == 2) { - verts[4] = max_width_radius[ST_CORNER_TOPLEFT]; - verts[5] = border_width; + verts[4] = MAX(node->border_radius[corner_id], + border_width[ST_SIDE_LEFT]); + verts[5] = border_width[ST_SIDE_TOP]; verts[6] = max_border_radius; - verts[7] = max_width_radius[ST_CORNER_TOPLEFT]; + verts[7] = MAX(node->border_radius[corner_id], + border_width[ST_SIDE_TOP]); } break; case ST_CORNER_TOPRIGHT: verts[0] = width - max_border_radius; - verts[1] = max_width_radius[ST_CORNER_TOPRIGHT]; - verts[2] = width - border_width; + verts[1] = MAX(node->border_radius[corner_id], + border_width[ST_SIDE_TOP]); + verts[2] = width - border_width[ST_SIDE_RIGHT]; verts[3] = max_border_radius; if (n_rects == 2) { verts[4] = width - max_border_radius; - verts[5] = border_width; - verts[6] = width - max_width_radius[ST_CORNER_TOPRIGHT]; - verts[7] = max_width_radius[ST_CORNER_TOPRIGHT]; + verts[5] = border_width[ST_SIDE_TOP]; + verts[6] = width - MAX(node->border_radius[corner_id], + border_width[ST_SIDE_RIGHT]); + verts[7] = MAX(node->border_radius[corner_id], + border_width[ST_SIDE_TOP]); } break; case ST_CORNER_BOTTOMRIGHT: verts[0] = width - max_border_radius; verts[1] = height - max_border_radius; - verts[2] = width - border_width; - verts[3] = height - max_width_radius[ST_CORNER_BOTTOMRIGHT]; + verts[2] = width - border_width[ST_SIDE_RIGHT]; + verts[3] = height - MAX(node->border_radius[corner_id], + border_width[ST_SIDE_BOTTOM]); if (n_rects == 2) { verts[4] = width - max_border_radius; - verts[5] = height - max_width_radius[ST_CORNER_BOTTOMRIGHT]; - verts[6] = width - max_width_radius[ST_CORNER_BOTTOMRIGHT]; - verts[7] = height - border_width; + verts[5] = height - MAX(node->border_radius[corner_id], + border_width[ST_SIDE_BOTTOM]); + verts[6] = width - MAX(node->border_radius[corner_id], + border_width[ST_SIDE_RIGHT]); + verts[7] = height - border_width[ST_SIDE_BOTTOM]; } break; case ST_CORNER_BOTTOMLEFT: - verts[0] = border_width; + verts[0] = border_width[ST_SIDE_LEFT]; verts[1] = height - max_border_radius; verts[2] = max_border_radius; - verts[3] = height - max_width_radius[ST_CORNER_BOTTOMLEFT]; + verts[3] = height - MAX(node->border_radius[corner_id], + border_width[ST_SIDE_BOTTOM]); if (n_rects == 2) { - verts[4] = max_width_radius[ST_CORNER_BOTTOMLEFT]; - verts[5] = height - max_width_radius[ST_CORNER_BOTTOMLEFT]; + verts[4] = MAX(node->border_radius[corner_id], + border_width[ST_SIDE_LEFT]); + verts[5] = height - MAX(node->border_radius[corner_id], + border_width[ST_SIDE_BOTTOM]); verts[6] = max_border_radius; - verts[7] = height - border_width; + verts[7] = height - border_width[ST_SIDE_BOTTOM]; } break; } cogl_rectangles (verts, n_rects); } - if (max_border_radius > border_width) - { - /* Once we've drawn the borders and corners, if the corners are bigger - * the the border width, the remaining area is shaped like - * - * ######## - * ########## - * ########## - * ######## - * - * We draw it in 3 pieces - first the top and bottom, then the main - * rectangle - */ - cogl_rectangle (max_border_radius, border_width, - width - max_border_radius, max_border_radius); - cogl_rectangle (max_border_radius, height - max_border_radius, - width - max_border_radius, height - border_width); - } + /* Once we've drawn the borders and corners, if the corners are bigger + * then the border width, the remaining area is shaped like + * + * ######## + * ########## + * ########## + * ######## + * + * We draw it in at most 3 pieces - first the top and bottom if + * necessary, then the main rectangle + */ + if (max_border_radius > border_width[ST_SIDE_TOP]) + cogl_rectangle (MAX(max_border_radius, border_width[ST_SIDE_LEFT]), + border_width[ST_SIDE_TOP], + width - MAX(max_border_radius, border_width[ST_SIDE_RIGHT]), + max_border_radius); + if (max_border_radius > border_width[ST_SIDE_BOTTOM]) + cogl_rectangle (MAX(max_border_radius, border_width[ST_SIDE_LEFT]), + height - max_border_radius, + width - MAX(max_border_radius, border_width[ST_SIDE_RIGHT]), + height - border_width[ST_SIDE_BOTTOM]); - cogl_rectangle (border_width, MAX(border_width, max_border_radius), - width - border_width, height - MAX(border_width, max_border_radius)); + cogl_rectangle (border_width[ST_SIDE_LEFT], + MAX(border_width[ST_SIDE_TOP], max_border_radius), + width - border_width[ST_SIDE_RIGHT], + height - MAX(border_width[ST_SIDE_BOTTOM], max_border_radius)); } } @@ -1108,8 +1227,6 @@ st_theme_node_paint (StThemeNode *node, * zero width or a border image is being used. * * Deviations from the above as implemented here: - * - Nonuniform border widths combined with a non-zero border radius result - * in the border radius being ignored * - The combination of border image and a non-zero border radius is * not supported; the background color will be drawn with square * corners. diff --git a/tests/Makefile.am b/tests/Makefile.am index 4c6b92188..9fb38a294 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -4,6 +4,7 @@ EXTRA_DIST = run-test.sh.in TEST_JS = \ interactive/borders.js \ interactive/border-radius.js \ + interactive/border-width.js \ interactive/box-layout.js \ interactive/calendar.js \ interactive/css-fonts.js \ diff --git a/tests/interactive/border-width.js b/tests/interactive/border-width.js new file mode 100644 index 000000000..60f760619 --- /dev/null +++ b/tests/interactive/border-width.js @@ -0,0 +1,60 @@ +/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ + +const Clutter = imports.gi.Clutter; +const St = imports.gi.St; + +const UI = imports.testcommon.ui; + +UI.init(); +let stage = Clutter.Stage.get_default(); +stage.width = 640; +stage.height = 480; + +let vbox = new St.BoxLayout({ width: stage.width, + height: stage.height, + style: 'padding: 10px; background: #ffee88;' + }); +stage.add_actor(vbox); + +let scroll = new St.ScrollView(); +vbox.add(scroll, { expand: true }); + +let box = new St.BoxLayout({ vertical: true, + style: 'spacing: 20px;' }); +scroll.add_actor(box); + +function addTestCase(borders, useGradient) { + let background; + if (useGradient) + background = 'background-gradient-direction: vertical;' + + 'background-gradient-start: white;' + + 'background-gradient-end: gray;'; + else + background = 'background: white;'; + + let border_style = "border-top: " + borders[St.Side.TOP] + " solid black;\n" + + "border-right: " + borders[St.Side.RIGHT] + " solid black;\n" + + "border-bottom: " + borders[St.Side.BOTTOM] + " solid black;\n" + + "border-left: " + borders[St.Side.LEFT] + " solid black;"; + box.add(new St.Label({ text: border_style, + style: border_style + + 'border-radius: 0px 5px 15px 25px;' + + 'padding: 5px;' + background }), + { x_fill: false }); +} + +// uniform backgrounds +addTestCase([" 0px", " 5px", "10px", "15px"], false); +addTestCase([" 5px", "10px", "15px", " 0px"], false); +addTestCase(["10px", "15px", " 0px", " 5px"], false); +addTestCase(["15px", " 0px", " 5px", "10px"], false); + +// gradient backgrounds +addTestCase([" 0px", " 5px", "10px", "15px"], true); +addTestCase([" 5px", "10px", "15px", " 0px"], true); +addTestCase(["10px", "15px", " 0px", " 5px"], true); +addTestCase(["15px", " 0px", " 5px", "10px"], true); + +stage.show(); +Clutter.main(); +stage.destroy();