Compare commits
2 Commits
matthiasc/
...
rounded-re
Author | SHA1 | Date | |
---|---|---|---|
|
f2e45bbc87 | ||
|
9965cfbc3b |
@@ -689,6 +689,230 @@ gsk_rounded_rect_intersect_with_rect (const GskRoundedRect *self,
|
|||||||
return GSK_INTERSECTION_NONEMPTY;
|
return GSK_INTERSECTION_NONEMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
rect_corner (const graphene_rect_t *r,
|
||||||
|
unsigned int i,
|
||||||
|
graphene_point_t *p)
|
||||||
|
{
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case GSK_CORNER_TOP_LEFT:
|
||||||
|
graphene_rect_get_top_left (r, p);
|
||||||
|
break;
|
||||||
|
case GSK_CORNER_TOP_RIGHT:
|
||||||
|
graphene_rect_get_top_right (r, p);
|
||||||
|
break;
|
||||||
|
case GSK_CORNER_BOTTOM_RIGHT:
|
||||||
|
graphene_rect_get_bottom_right (r, p);
|
||||||
|
break;
|
||||||
|
case GSK_CORNER_BOTTOM_LEFT:
|
||||||
|
graphene_rect_get_bottom_left (r, p);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
corner_rect (const GskRoundedRect *s,
|
||||||
|
unsigned int i,
|
||||||
|
graphene_rect_t *r)
|
||||||
|
{
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case GSK_CORNER_TOP_LEFT:
|
||||||
|
graphene_rect_init (r,
|
||||||
|
s->bounds.origin.x,
|
||||||
|
s->bounds.origin.y,
|
||||||
|
s->corner[i].width,
|
||||||
|
s->corner[i].height);
|
||||||
|
break;
|
||||||
|
case GSK_CORNER_TOP_RIGHT:
|
||||||
|
graphene_rect_init (r,
|
||||||
|
s->bounds.origin.x + s->bounds.size.width - s->corner[i].width,
|
||||||
|
s->bounds.origin.y,
|
||||||
|
s->corner[i].width,
|
||||||
|
s->corner[i].height);
|
||||||
|
break;
|
||||||
|
case GSK_CORNER_BOTTOM_RIGHT:
|
||||||
|
graphene_rect_init (r,
|
||||||
|
s->bounds.origin.x + s->bounds.size.width - s->corner[i].width,
|
||||||
|
s->bounds.origin.y + s->bounds.size.height - s->corner[i].height,
|
||||||
|
s->corner[i].width,
|
||||||
|
s->corner[i].height);
|
||||||
|
break;
|
||||||
|
case GSK_CORNER_BOTTOM_LEFT:
|
||||||
|
graphene_rect_init (r,
|
||||||
|
s->bounds.origin.x,
|
||||||
|
s->bounds.origin.y + s->bounds.size.height - s->corner[i].height,
|
||||||
|
s->corner[i].width,
|
||||||
|
s->corner[i].height);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
point_in_interior (const graphene_point_t *p,
|
||||||
|
const graphene_rect_t *r)
|
||||||
|
{
|
||||||
|
if (graphene_rect_contains_point (r, p))
|
||||||
|
{
|
||||||
|
if (p->x > r->origin.x && p->x < r->origin.x + r->size.width)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (p->y > r->origin.y && p->y < r->origin.y + r->size.height)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GskRoundedRectIntersection
|
||||||
|
gsk_rounded_rect_intersect (const GskRoundedRect *self,
|
||||||
|
const GskRoundedRect *other,
|
||||||
|
GskRoundedRect *result)
|
||||||
|
{
|
||||||
|
if (!graphene_rect_intersection (&self->bounds, &other->bounds, &result->bounds))
|
||||||
|
return GSK_INTERSECTION_EMPTY;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
graphene_point_t p, p1, p2;
|
||||||
|
|
||||||
|
rect_corner (&self->bounds, i, &p1);
|
||||||
|
rect_corner (&other->bounds, i, &p2);
|
||||||
|
rect_corner (&result->bounds, i, &p);
|
||||||
|
|
||||||
|
if (graphene_point_equal (&p, &p1))
|
||||||
|
{
|
||||||
|
if (graphene_point_equal (&p, &p2))
|
||||||
|
{
|
||||||
|
graphene_rect_t c;
|
||||||
|
graphene_rect_t d;
|
||||||
|
|
||||||
|
corner_rect (self, i, &c);
|
||||||
|
corner_rect (other, i, &d);
|
||||||
|
|
||||||
|
/* corners coincide */
|
||||||
|
if (graphene_rect_contains_rect (&c, &d))
|
||||||
|
{
|
||||||
|
graphene_point_t q1, q2;
|
||||||
|
|
||||||
|
rect_corner (&c, (i + 1) % 4, &q1);
|
||||||
|
rect_corner (&c, (i + 3) % 4, &q2);
|
||||||
|
|
||||||
|
if (gsk_rounded_rect_contains_point (other, &q1) &&
|
||||||
|
gsk_rounded_rect_contains_point (other, &q2))
|
||||||
|
result->corner[i] = self->corner[i];
|
||||||
|
else
|
||||||
|
return GSK_INTERSECTION_NOT_REPRESENTABLE;
|
||||||
|
}
|
||||||
|
else if (graphene_rect_contains_rect (&d, &c))
|
||||||
|
{
|
||||||
|
graphene_point_t q1, q2;
|
||||||
|
|
||||||
|
rect_corner (&d, (i + 1) % 4, &q1);
|
||||||
|
rect_corner (&d, (i + 3) % 4, &q2);
|
||||||
|
|
||||||
|
if (gsk_rounded_rect_contains_point (self, &q1) &&
|
||||||
|
gsk_rounded_rect_contains_point (self, &q2))
|
||||||
|
result->corner[i] = other->corner[i];
|
||||||
|
else
|
||||||
|
return GSK_INTERSECTION_NOT_REPRESENTABLE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return GSK_INTERSECTION_NOT_REPRESENTABLE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
graphene_rect_t c;
|
||||||
|
graphene_point_t q1, q2;
|
||||||
|
|
||||||
|
corner_rect (self, i, &c);
|
||||||
|
|
||||||
|
rect_corner (&c, (i + 1) % 4, &q1);
|
||||||
|
rect_corner (&c, (i + 3) % 4, &q2);
|
||||||
|
|
||||||
|
if (gsk_rounded_rect_contains_point (other, &q1) &&
|
||||||
|
gsk_rounded_rect_contains_point (other, &q2))
|
||||||
|
{
|
||||||
|
if (gsk_rounded_rect_contains_point (other, &p))
|
||||||
|
result->corner[i] = self->corner[i];
|
||||||
|
else
|
||||||
|
#if 1
|
||||||
|
return GSK_INTERSECTION_NEEDS_QUARTIC;
|
||||||
|
#else
|
||||||
|
if (/* no intersection for i */)
|
||||||
|
result->corner[i] = self->corner[i];
|
||||||
|
else
|
||||||
|
return GSK_INTERSECTION_NOT_REPRESENTABLE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return GSK_INTERSECTION_NOT_REPRESENTABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (graphene_point_equal (&p, &p2))
|
||||||
|
{
|
||||||
|
graphene_rect_t d;
|
||||||
|
graphene_point_t q1, q2;
|
||||||
|
|
||||||
|
corner_rect (other, i, &d);
|
||||||
|
|
||||||
|
rect_corner (&d, (i + 1) % 4, &q1);
|
||||||
|
rect_corner (&d, (i + 3) % 4, &q2);
|
||||||
|
|
||||||
|
if (gsk_rounded_rect_contains_point (self, &q1) &&
|
||||||
|
gsk_rounded_rect_contains_point (self, &q2))
|
||||||
|
{
|
||||||
|
if (gsk_rounded_rect_contains_point (self, &p))
|
||||||
|
result->corner[i] = other->corner[i];
|
||||||
|
else
|
||||||
|
#if 1
|
||||||
|
return GSK_INTERSECTION_NEEDS_QUARTIC;
|
||||||
|
#else
|
||||||
|
if (/* no intersection for i */
|
||||||
|
result->corner[i] = other->corner[i];
|
||||||
|
else
|
||||||
|
return GSK_INTERSECTION_NOT_REPRESENTABLE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return GSK_INTERSECTION_NOT_REPRESENTABLE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
graphene_rect_t c, d;
|
||||||
|
|
||||||
|
corner_rect (self, (i + 2) % 4, &c);
|
||||||
|
if (graphene_rect_contains_point (&c, &p) &&
|
||||||
|
!gsk_rounded_rect_contains_point (self, &p))
|
||||||
|
return GSK_INTERSECTION_EMPTY;
|
||||||
|
|
||||||
|
corner_rect (other, (i + 2) % 4, &d);
|
||||||
|
if (graphene_rect_contains_point (&d, &p) &&
|
||||||
|
!gsk_rounded_rect_contains_point (other, &p))
|
||||||
|
return GSK_INTERSECTION_EMPTY;
|
||||||
|
|
||||||
|
for (unsigned int j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
corner_rect (self, j, &c);
|
||||||
|
corner_rect (other, j, &d);
|
||||||
|
|
||||||
|
if (point_in_interior (&p, &c) ||
|
||||||
|
point_in_interior (&p, &d))
|
||||||
|
return GSK_INTERSECTION_NOT_REPRESENTABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
result->corner[i] = (graphene_size_t) { 0, 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GSK_INTERSECTION_NONEMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
append_arc (cairo_t *cr, double angle1, double angle2, gboolean negative)
|
append_arc (cairo_t *cr, double angle1, double angle2, gboolean negative)
|
||||||
{
|
{
|
||||||
|
@@ -37,13 +37,17 @@ char * gsk_rounded_rect_to_string (const GskRounde
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
GSK_INTERSECTION_EMPTY,
|
GSK_INTERSECTION_EMPTY,
|
||||||
GSK_INTERSECTION_NONEMPTY,
|
GSK_INTERSECTION_NONEMPTY,
|
||||||
GSK_INTERSECTION_NOT_REPRESENTABLE
|
GSK_INTERSECTION_NOT_REPRESENTABLE,
|
||||||
|
GSK_INTERSECTION_NEEDS_QUARTIC
|
||||||
} GskRoundedRectIntersection;
|
} GskRoundedRectIntersection;
|
||||||
|
|
||||||
GskRoundedRectIntersection gsk_rounded_rect_intersect_with_rect (const GskRoundedRect *self,
|
GskRoundedRectIntersection gsk_rounded_rect_intersect_with_rect (const GskRoundedRect *self,
|
||||||
const graphene_rect_t *rect,
|
const graphene_rect_t *rect,
|
||||||
GskRoundedRect *result) G_GNUC_PURE;
|
GskRoundedRect *result) G_GNUC_PURE;
|
||||||
|
|
||||||
|
GskRoundedRectIntersection gsk_rounded_rect_intersect (const GskRoundedRect *self,
|
||||||
|
const GskRoundedRect *other,
|
||||||
|
GskRoundedRect *result) G_GNUC_PURE;
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@@ -146,6 +146,13 @@ foreach t: gtk_tests
|
|||||||
)
|
)
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
|
executable('testroundedrect',
|
||||||
|
sources: [ 'testroundedrect.c' ],
|
||||||
|
include_directories: [confinc, gdkinc],
|
||||||
|
c_args: test_args + common_cflags,
|
||||||
|
dependencies: [libgtk_static_dep, libm],
|
||||||
|
)
|
||||||
|
|
||||||
if libsysprof_dep.found()
|
if libsysprof_dep.found()
|
||||||
executable('testperf',
|
executable('testperf',
|
||||||
sources: 'testperf.c',
|
sources: 'testperf.c',
|
||||||
|
312
tests/testroundedrect.c
Normal file
312
tests/testroundedrect.c
Normal file
@@ -0,0 +1,312 @@
|
|||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <gtk/css/gtkcssparserprivate.h>
|
||||||
|
#include <gsk/gskroundedrectprivate.h>
|
||||||
|
|
||||||
|
#define TEST_TYPE_WIDGET (test_widget_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (TestWidget, test_widget, TEST, WIDGET, GtkWidget)
|
||||||
|
|
||||||
|
struct _TestWidget
|
||||||
|
{
|
||||||
|
GtkWidget parent_instance;
|
||||||
|
|
||||||
|
GskRoundedRect rect1;
|
||||||
|
GskRoundedRect rect2;
|
||||||
|
GskRoundedRect rect3;
|
||||||
|
GskRoundedRectIntersection result;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _TestWidgetClass
|
||||||
|
{
|
||||||
|
GtkWidgetClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (TestWidget, test_widget, GTK_TYPE_WIDGET)
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_widget_init (TestWidget *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_widget_measure (GtkWidget *widget,
|
||||||
|
GtkOrientation orientation,
|
||||||
|
int for_size,
|
||||||
|
int *minimum,
|
||||||
|
int *natural,
|
||||||
|
int *minimum_baseline,
|
||||||
|
int *natural_baseline)
|
||||||
|
{
|
||||||
|
TestWidget *self = TEST_WIDGET (widget);
|
||||||
|
|
||||||
|
if (orientation == GTK_ORIENTATION_VERTICAL)
|
||||||
|
*minimum = *natural = MAX (self->rect1.bounds.origin.x + self->rect1.bounds.size.width,
|
||||||
|
self->rect2.bounds.origin.x + self->rect2.bounds.size.width);
|
||||||
|
else
|
||||||
|
*minimum = *natural = MAX (self->rect1.bounds.origin.y + self->rect1.bounds.size.height,
|
||||||
|
self->rect2.bounds.origin.y + self->rect2.bounds.size.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_widget_snapshot (GtkWidget *widget,
|
||||||
|
GtkSnapshot *snapshot)
|
||||||
|
{
|
||||||
|
TestWidget *self = TEST_WIDGET (widget);
|
||||||
|
float widths[4] = { 1, 1, 1, 1 };
|
||||||
|
GdkRGBA colors1[4];
|
||||||
|
GdkRGBA colors2[4];
|
||||||
|
GdkRGBA colors3[4];
|
||||||
|
GskRoundedRect rect3;
|
||||||
|
|
||||||
|
gdk_rgba_parse (&colors1[0], "red");
|
||||||
|
colors1[1] = colors1[2] = colors1[3] = colors1[0];
|
||||||
|
|
||||||
|
gdk_rgba_parse (&colors2[0], "blue");
|
||||||
|
colors2[1] = colors2[2] = colors2[3] = colors2[0];
|
||||||
|
|
||||||
|
gdk_rgba_parse (&colors3[0], "magenta");
|
||||||
|
colors3[1] = colors3[2] = colors3[3] = colors3[0];
|
||||||
|
|
||||||
|
gtk_snapshot_append_border (snapshot, &self->rect1, widths, colors1);
|
||||||
|
gtk_snapshot_append_border (snapshot, &self->rect2, widths, colors2);
|
||||||
|
|
||||||
|
switch (gsk_rounded_rect_intersect (&self->rect1, &self->rect2, &rect3))
|
||||||
|
{
|
||||||
|
case GSK_INTERSECTION_NONEMPTY:
|
||||||
|
gtk_snapshot_append_border (snapshot, &rect3, widths, colors3);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_widget_class_init (TestWidgetClass *class)
|
||||||
|
{
|
||||||
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||||
|
|
||||||
|
widget_class->snapshot = test_widget_snapshot;
|
||||||
|
widget_class->measure = test_widget_measure;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GtkWidget *
|
||||||
|
test_widget_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (TEST_TYPE_WIDGET, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_intersection (TestWidget *self)
|
||||||
|
{
|
||||||
|
self->result = gsk_rounded_rect_intersect (&self->rect1, &self->rect2, &self->rect3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_widget_set_rect1 (TestWidget *self,
|
||||||
|
GskRoundedRect *rect)
|
||||||
|
{
|
||||||
|
self->rect1 = *rect;
|
||||||
|
update_intersection (self);
|
||||||
|
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_widget_set_rect2 (TestWidget *self,
|
||||||
|
GskRoundedRect *rect)
|
||||||
|
{
|
||||||
|
self->rect2 = *rect;
|
||||||
|
update_intersection (self);
|
||||||
|
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
parse_rect (GtkCssParser *parser,
|
||||||
|
graphene_rect_t *out_rect)
|
||||||
|
{
|
||||||
|
double numbers[4];
|
||||||
|
|
||||||
|
if (!gtk_css_parser_consume_number (parser, &numbers[0]) ||
|
||||||
|
!gtk_css_parser_consume_number (parser, &numbers[1]) ||
|
||||||
|
!gtk_css_parser_consume_number (parser, &numbers[2]) ||
|
||||||
|
!gtk_css_parser_consume_number (parser, &numbers[3]))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
graphene_rect_init (out_rect, numbers[0], numbers[1], numbers[2], numbers[3]);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
parse_rounded_rect (GtkCssParser *parser,
|
||||||
|
GskRoundedRect *out_rect)
|
||||||
|
{
|
||||||
|
graphene_rect_t r;
|
||||||
|
graphene_size_t corners[4];
|
||||||
|
double d;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
if (!parse_rect (parser, &r))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!gtk_css_parser_try_delim (parser, '/'))
|
||||||
|
{
|
||||||
|
gsk_rounded_rect_init_from_rect (out_rect, &r, 0);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (!gtk_css_parser_has_number (parser))
|
||||||
|
break;
|
||||||
|
if (!gtk_css_parser_consume_number (parser, &d))
|
||||||
|
return FALSE;
|
||||||
|
corners[i].width = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Expected a number");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The magic (i - 1) >> 1 below makes it take the correct value
|
||||||
|
* according to spec. Feel free to check the 4 cases
|
||||||
|
*/
|
||||||
|
for (; i < 4; i++)
|
||||||
|
corners[i].width = corners[(i - 1) >> 1].width;
|
||||||
|
if (gtk_css_parser_try_delim (parser, '/'))
|
||||||
|
{
|
||||||
|
gtk_css_parser_consume_token (parser);
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (!gtk_css_parser_has_number (parser))
|
||||||
|
break;
|
||||||
|
if (!gtk_css_parser_consume_number (parser, &d))
|
||||||
|
return FALSE;
|
||||||
|
corners[i].height = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
gtk_css_parser_error_syntax (parser, "Expected a number");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i < 4; i++)
|
||||||
|
corners[i].height = corners[(i - 1) >> 1].height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
corners[i].height = corners[i].width;
|
||||||
|
}
|
||||||
|
|
||||||
|
gsk_rounded_rect_init (out_rect, &r, &corners[0], &corners[1], &corners[2], &corners[3]);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GtkWidget *label;
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_label (GtkLabel *label,
|
||||||
|
GskRoundedRectIntersection result)
|
||||||
|
{
|
||||||
|
const char *labels[] = {
|
||||||
|
"Empty", "Not empty", "Not representable", "Who knows"
|
||||||
|
};
|
||||||
|
|
||||||
|
gtk_label_set_label (label, labels[result]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
activate1_cb (GtkEntry *entry, TestWidget *test)
|
||||||
|
{
|
||||||
|
GtkCssParser *parser;
|
||||||
|
const char *text;
|
||||||
|
GBytes *bytes;
|
||||||
|
GskRoundedRect rect;
|
||||||
|
|
||||||
|
text = gtk_editable_get_text (GTK_EDITABLE (entry));
|
||||||
|
bytes = g_bytes_new_static (text, strlen (text) + 1);
|
||||||
|
parser = gtk_css_parser_new_for_bytes (bytes, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
if (parse_rounded_rect (parser, &rect))
|
||||||
|
{
|
||||||
|
test_widget_set_rect1 (test, &rect);
|
||||||
|
update_label (GTK_LABEL (label), test->result);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_css_parser_unref (parser);
|
||||||
|
g_bytes_unref (bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
activate2_cb (GtkEntry *entry, TestWidget *test)
|
||||||
|
{
|
||||||
|
GtkCssParser *parser;
|
||||||
|
const char *text;
|
||||||
|
GBytes *bytes;
|
||||||
|
GskRoundedRect rect;
|
||||||
|
|
||||||
|
text = gtk_editable_get_text (GTK_EDITABLE (entry));
|
||||||
|
bytes = g_bytes_new_static (text, strlen (text) + 1);
|
||||||
|
parser = gtk_css_parser_new_for_bytes (bytes, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
if (parse_rounded_rect (parser, &rect))
|
||||||
|
{
|
||||||
|
test_widget_set_rect2 (test, &rect);
|
||||||
|
update_label (GTK_LABEL (label), test->result);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_css_parser_unref (parser);
|
||||||
|
g_bytes_unref (bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
GtkWidget *window;
|
||||||
|
GtkWidget *box;
|
||||||
|
GtkWidget *grid;
|
||||||
|
GtkWidget *entry1;
|
||||||
|
GtkWidget *entry2;
|
||||||
|
GtkWidget *test;
|
||||||
|
|
||||||
|
gtk_init ();
|
||||||
|
|
||||||
|
window = gtk_window_new ();
|
||||||
|
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||||
|
|
||||||
|
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||||
|
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||||
|
|
||||||
|
grid = gtk_grid_new ();
|
||||||
|
gtk_box_append (GTK_BOX (box), grid);
|
||||||
|
|
||||||
|
test = test_widget_new ();
|
||||||
|
gtk_widget_set_hexpand (test, TRUE);
|
||||||
|
gtk_widget_set_vexpand (test, TRUE);
|
||||||
|
gtk_widget_set_halign (test, GTK_ALIGN_CENTER);
|
||||||
|
gtk_widget_set_valign (test, GTK_ALIGN_CENTER);
|
||||||
|
gtk_box_append (GTK_BOX (box), test);
|
||||||
|
|
||||||
|
entry1 = gtk_entry_new ();
|
||||||
|
g_signal_connect (entry1, "activate", G_CALLBACK (activate1_cb), test);
|
||||||
|
gtk_grid_attach (GTK_GRID (grid), entry1, 0, 0, 1, 1);
|
||||||
|
|
||||||
|
entry2 = gtk_entry_new ();
|
||||||
|
g_signal_connect (entry2, "activate", G_CALLBACK (activate2_cb), test);
|
||||||
|
gtk_grid_attach (GTK_GRID (grid), entry2, 0, 1, 1, 1);
|
||||||
|
|
||||||
|
label = gtk_label_new ("");
|
||||||
|
gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
|
||||||
|
|
||||||
|
gtk_window_present (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
while (g_list_model_get_n_items (gtk_window_get_toplevels ()) > 0)
|
||||||
|
g_main_context_iteration (NULL, FALSE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in New Issue
Block a user