Compare commits
12 Commits
wayland-po
...
wip/matthi
Author | SHA1 | Date | |
---|---|---|---|
|
e867944a5a | ||
|
20eaea2b2d | ||
|
79f383ab19 | ||
|
ff9e589402 | ||
|
054e21afae | ||
|
9af17de76b | ||
|
0f95ff74b8 | ||
|
fdd984f55c | ||
|
e13894396d | ||
|
2fc7ecc3df | ||
|
a3aeef3760 | ||
|
1535e22344 |
@@ -1894,6 +1894,8 @@ testsuite/a11y/Makefile
|
||||
testsuite/a11y/state/Makefile
|
||||
testsuite/css/Makefile
|
||||
testsuite/css/parser/Makefile
|
||||
testsuite/css/nodes/Makefile
|
||||
testsuite/css/style/Makefile
|
||||
testsuite/gdk/Makefile
|
||||
testsuite/gtk/Makefile
|
||||
testsuite/reftests/Makefile
|
||||
|
@@ -6244,6 +6244,8 @@ gtk_style_context_set_frame_clock
|
||||
gtk_style_context_set_state
|
||||
gtk_style_context_set_scale
|
||||
gtk_style_context_get_scale
|
||||
GtkStyleContextPrintFlags
|
||||
gtk_style_context_to_string
|
||||
|
||||
<SUBSECTION>
|
||||
GtkBorder
|
||||
|
163
gtk/gtkcssnode.c
163
gtk/gtkcssnode.c
@@ -25,6 +25,8 @@
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtksettingsprivate.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkcsssectionprivate.h"
|
||||
|
||||
/*
|
||||
* CSS nodes are the backbone of the GtkStyleContext implementation and
|
||||
@@ -1510,7 +1512,7 @@ GtkStyleProviderPrivate *
|
||||
gtk_css_node_get_style_provider (GtkCssNode *cssnode)
|
||||
{
|
||||
GtkStyleProviderPrivate *result;
|
||||
|
||||
|
||||
result = gtk_css_node_get_style_provider_or_null (cssnode);
|
||||
if (result)
|
||||
return result;
|
||||
@@ -1520,3 +1522,162 @@ gtk_css_node_get_style_provider (GtkCssNode *cssnode)
|
||||
|
||||
return GTK_STYLE_PROVIDER_PRIVATE (_gtk_settings_get_style_cascade (gtk_settings_get_default (), 1));
|
||||
}
|
||||
|
||||
static void
|
||||
append_id (GtkCssNode *cssnode,
|
||||
GString *string)
|
||||
{
|
||||
const char *id;
|
||||
|
||||
id = gtk_css_node_get_id (cssnode);
|
||||
if (id)
|
||||
{
|
||||
g_string_append (string, " id=");
|
||||
g_string_append (string, id);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
append_visible (GtkCssNode *cssnode,
|
||||
GString *string)
|
||||
{
|
||||
g_string_append_printf (string, " visible=%d", gtk_css_node_get_visible (cssnode));
|
||||
}
|
||||
|
||||
static void
|
||||
append_state (GtkCssNode *cssnode,
|
||||
GString *string)
|
||||
|
||||
{
|
||||
GtkStateFlags state;
|
||||
|
||||
state = gtk_css_node_get_state (cssnode);
|
||||
if (state)
|
||||
{
|
||||
GFlagsClass *fclass;
|
||||
gint i;
|
||||
gboolean first = TRUE;
|
||||
|
||||
g_string_append (string, " state=");
|
||||
fclass = g_type_class_ref (GTK_TYPE_STATE_FLAGS);
|
||||
for (i = 0; i < fclass->n_values; i++)
|
||||
{
|
||||
if (state & fclass->values[i].value)
|
||||
{
|
||||
if (first)
|
||||
first = FALSE;
|
||||
else
|
||||
g_string_append_c (string, '|');
|
||||
g_string_append (string, fclass->values[i].value_nick);
|
||||
}
|
||||
}
|
||||
g_type_class_unref (fclass);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
append_classes (GtkCssNode *cssnode,
|
||||
GString *string)
|
||||
{
|
||||
const GQuark *classes;
|
||||
guint n_classes;
|
||||
|
||||
classes = gtk_css_node_list_classes (cssnode, &n_classes);
|
||||
if (n_classes > 0)
|
||||
{
|
||||
int i;
|
||||
|
||||
g_string_append (string, " classes=");
|
||||
for (i = 0; i < n_classes; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
g_string_append_c (string, ',');
|
||||
g_string_append (string, g_quark_to_string (classes[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
append_style (GtkCssNode *cssnode,
|
||||
GtkStyleContextPrintFlags flags,
|
||||
GString *string,
|
||||
guint indent)
|
||||
{
|
||||
int i;
|
||||
GtkCssStyle *style;
|
||||
|
||||
if (!(flags & GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE))
|
||||
return;
|
||||
|
||||
style = gtk_css_node_get_style (cssnode);
|
||||
|
||||
for (i = 0; i < _gtk_css_style_property_get_n_properties (); i++)
|
||||
{
|
||||
GtkCssStyleProperty *prop;
|
||||
GtkCssValue *value;
|
||||
GtkCssSection *section;
|
||||
const char *name;
|
||||
|
||||
prop = _gtk_css_style_property_lookup_by_id (i);
|
||||
name = _gtk_style_property_get_name (GTK_STYLE_PROPERTY (prop));
|
||||
value = gtk_css_style_get_value (style, i);
|
||||
|
||||
if (!(flags & GTK_STYLE_CONTEXT_PRINT_SHOW_INITIAL))
|
||||
{
|
||||
GtkCssValue *initial, *computed;
|
||||
GtkCssNode *parent_node;
|
||||
GtkCssStyle *parent_style;
|
||||
|
||||
parent_node = gtk_css_node_get_parent (cssnode);
|
||||
parent_style = parent_node ? gtk_css_node_get_style (parent_node) : NULL;
|
||||
initial = _gtk_css_style_property_get_initial_value (prop);
|
||||
computed = _gtk_css_value_compute (initial,
|
||||
i,
|
||||
gtk_css_node_get_style_provider (cssnode),
|
||||
style,
|
||||
parent_style);
|
||||
if (_gtk_css_value_equal (value, computed))
|
||||
continue;
|
||||
}
|
||||
|
||||
g_string_append_printf (string, "%*s%s: ", indent, "", name);
|
||||
_gtk_css_value_print (value, string);
|
||||
|
||||
section = gtk_css_style_get_section (style, i);
|
||||
if (section)
|
||||
{
|
||||
g_string_append (string, " (");
|
||||
_gtk_css_section_print (section, string);
|
||||
g_string_append (string, ")");
|
||||
}
|
||||
g_string_append_c (string, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_node_print (GtkCssNode *cssnode,
|
||||
GtkStyleContextPrintFlags flags,
|
||||
GString *string,
|
||||
guint indent)
|
||||
{
|
||||
GtkCssNode *node;
|
||||
|
||||
g_string_append_printf (string, "%*s", indent, "");
|
||||
if (gtk_css_node_get_name (cssnode))
|
||||
g_string_append (string, gtk_css_node_get_name (cssnode));
|
||||
else
|
||||
g_string_append (string, g_type_name (gtk_css_node_get_widget_type (cssnode)));
|
||||
append_id (cssnode, string);
|
||||
append_visible (cssnode, string);
|
||||
append_state (cssnode, string);
|
||||
append_classes (cssnode, string);
|
||||
g_string_append_c (string, '\n');
|
||||
|
||||
append_style (cssnode, flags, string, indent + 2);
|
||||
|
||||
if (flags & GTK_STYLE_CONTEXT_PRINT_RECURSE)
|
||||
{
|
||||
for (node = gtk_css_node_get_first_child (cssnode); node; node = gtk_css_node_get_next_sibling (node))
|
||||
gtk_css_node_print (node, flags, string, indent + 2);
|
||||
}
|
||||
}
|
||||
|
@@ -171,6 +171,11 @@ GtkWidgetPath * gtk_css_node_create_widget_path (GtkCssNode *
|
||||
const GtkWidgetPath * gtk_css_node_get_widget_path (GtkCssNode *cssnode);
|
||||
GtkStyleProviderPrivate *gtk_css_node_get_style_provider(GtkCssNode *cssnode);
|
||||
|
||||
void gtk_css_node_print (GtkCssNode *cssnode,
|
||||
GtkStyleContextPrintFlags flags,
|
||||
GString *string,
|
||||
guint indent);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_NODE_PRIVATE_H__ */
|
||||
|
@@ -3219,3 +3219,48 @@ _gtk_style_context_is_background_opaque (GtkStyleContext *context)
|
||||
corner_value_is_right_angle (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BORDER_BOTTOM_RIGHT_RADIUS)) &&
|
||||
corner_value_is_right_angle (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BORDER_BOTTOM_LEFT_RADIUS)));
|
||||
}
|
||||
|
||||
/**
|
||||
* GtkStyleContextPrintFlags:
|
||||
* @GTK_STYLE_CONTEXT_PRINT_RECURSE: Print the entire tree of
|
||||
* CSS nodes starting at the style context's node
|
||||
* @GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE: Show the values of the
|
||||
* CSS properties for each node
|
||||
* @GTK_STYLE_CONTEXT_PRINT_SHOW_INITIAL: Show the values of the
|
||||
* CSS properties even if they match the initial value. By default,
|
||||
* values are only shown if they are different from the initial
|
||||
* value.
|
||||
*
|
||||
* Flags that modify the behavior of gtk_style_context_to_string().
|
||||
*/
|
||||
|
||||
/**
|
||||
* gtk_style_context_to_string:
|
||||
* @context: a #GtkStyleContext
|
||||
* @flags: Flags that determine what to print
|
||||
*
|
||||
* Converts the style context into a string representation.
|
||||
*
|
||||
* The string representation always includes information about
|
||||
* the name, state, id, visibility and style classes of the CSS
|
||||
* node that is backing @context. Depending on the flags, more
|
||||
* information may be included.
|
||||
*
|
||||
* Returns: a newly allocated string representing @context
|
||||
*
|
||||
* Since: 3.20
|
||||
*/
|
||||
char *
|
||||
gtk_style_context_to_string (GtkStyleContext *context,
|
||||
GtkStyleContextPrintFlags flags)
|
||||
{
|
||||
GString *string;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
|
||||
|
||||
string = g_string_new ("");
|
||||
|
||||
gtk_css_node_print (context->priv->cssnode, flags, string, 0);
|
||||
|
||||
return g_string_free (string, FALSE);
|
||||
}
|
||||
|
@@ -1208,6 +1208,17 @@ void gtk_draw_insertion_cursor (GtkWidget *widget,
|
||||
GtkTextDirection direction,
|
||||
gboolean draw_arrow);
|
||||
|
||||
typedef enum {
|
||||
GTK_STYLE_CONTEXT_PRINT_NONE = 0,
|
||||
GTK_STYLE_CONTEXT_PRINT_RECURSE = 1 << 0,
|
||||
GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE = 1 << 1,
|
||||
GTK_STYLE_CONTEXT_PRINT_SHOW_INITIAL = 1 << 2
|
||||
} GtkStyleContextPrintFlags;
|
||||
|
||||
GDK_AVAILABLE_IN_3_20
|
||||
char * gtk_style_context_to_string (GtkStyleContext *context,
|
||||
GtkStyleContextPrintFlags flags);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_STYLE_CONTEXT_H__ */
|
||||
|
@@ -2,7 +2,7 @@ include $(top_srcdir)/Makefile.decl
|
||||
|
||||
NULL =
|
||||
|
||||
SUBDIRS = parser
|
||||
SUBDIRS = parser nodes style
|
||||
|
||||
check_PROGRAMS = $(TEST_PROGS)
|
||||
test_in_files =
|
||||
|
60
testsuite/css/nodes/Makefile.am
Normal file
60
testsuite/css/nodes/Makefile.am
Normal file
@@ -0,0 +1,60 @@
|
||||
include $(top_srcdir)/Makefile.decl
|
||||
|
||||
NULL =
|
||||
|
||||
CLEANFILES =
|
||||
|
||||
TEST_PROGS += test-css-nodes
|
||||
test_in_files = test-css-nodes.test.in
|
||||
|
||||
check_PROGRAMS = $(TEST_PROGS)
|
||||
|
||||
test_css_nodes_CFLAGS = \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_builddir)/gdk \
|
||||
-I$(top_srcdir)/gdk \
|
||||
$(GTK_DEBUG_FLAGS) \
|
||||
$(GTK_DEP_CFLAGS)
|
||||
|
||||
test_css_nodes_LDADD = \
|
||||
$(top_builddir)/gdk/libgdk-3.la \
|
||||
$(top_builddir)/gtk/libgtk-3.la \
|
||||
$(GTK_DEP_LIBS)
|
||||
|
||||
test_css_nodes_SOURCES = \
|
||||
test-css-nodes.c
|
||||
|
||||
test_data = \
|
||||
buttons.ui buttons.nodes \
|
||||
entries.ui entries.nodes \
|
||||
levelbar.ui levelbar.nodes \
|
||||
notebook.ui notebook.nodes \
|
||||
progressbar.ui progressbar.nodes \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST += $(test_in_files) $(test_data)
|
||||
|
||||
if BUILDOPT_INSTALL_TESTS
|
||||
insttestdir=$(libexecdir)/installed-tests/$(PACKAGE)/css/nodes
|
||||
insttest_PROGRAMS = $(TEST_PROGS)
|
||||
insttest_DATA = $(test_data)
|
||||
|
||||
substitutions = \
|
||||
-e s,@libexecdir\@,$(libexecdir),g \
|
||||
$(NULL)
|
||||
|
||||
test_files = $(test_in_files:.test.in=.test)
|
||||
|
||||
$(test_files): %.test: %.test.in
|
||||
$(AM_V_GEN) sed $(substitutions) $< > $@.tmp && mv $@.tmp $@
|
||||
|
||||
EXTRA_DIST += $(test_files)
|
||||
|
||||
CLEANFILES += $(test_files)
|
||||
|
||||
testmetadir = $(datadir)/installed-tests/$(PACKAGE)/css/nodes
|
||||
testmeta_DATA = $(test_files)
|
||||
endif
|
||||
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
28
testsuite/css/nodes/buttons.nodes
Normal file
28
testsuite/css/nodes/buttons.nodes
Normal file
@@ -0,0 +1,28 @@
|
||||
window visible=0 state=dir-ltr classes=background
|
||||
decoration visible=1 state=dir-ltr
|
||||
grid visible=1 state=dir-ltr classes=horizontal
|
||||
button visible=1 state=dir-ltr|checked classes=text-button,toggle
|
||||
label visible=1 state=dir-ltr
|
||||
checkbutton visible=1 state=dir-ltr classes=text-button
|
||||
check visible=1 state=dir-ltr
|
||||
label visible=1 state=dir-ltr
|
||||
radiobutton visible=1 state=dir-ltr|checked classes=text-button
|
||||
radio visible=1 state=dir-ltr|checked
|
||||
label visible=1 state=dir-ltr
|
||||
radiobutton visible=1 state=dir-ltr classes=text-button
|
||||
radio visible=1 state=dir-ltr
|
||||
label visible=1 state=dir-ltr
|
||||
switch visible=1 state=active|dir-ltr
|
||||
slider visible=1 classes=slider
|
||||
switch visible=1 state=dir-ltr
|
||||
slider visible=1 classes=slider
|
||||
button visible=1 state=dir-ltr classes=text-button
|
||||
label visible=1 state=dir-ltr
|
||||
button visible=1 state=dir-ltr classes=image-button
|
||||
GtkAlignment visible=1 state=dir-ltr
|
||||
box visible=1 state=dir-ltr classes=horizontal
|
||||
image visible=1 state=dir-ltr
|
||||
button visible=1 state=dir-ltr classes=image-button
|
||||
GtkAlignment visible=1 state=dir-ltr
|
||||
box visible=1 state=dir-ltr classes=horizontal
|
||||
image visible=1 state=dir-ltr
|
147
testsuite/css/nodes/buttons.ui
Normal file
147
testsuite/css/nodes/buttons.ui
Normal file
@@ -0,0 +1,147 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="type">popup</property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="button1">
|
||||
<property name="label" translatable="yes">Hello World!</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="active">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="button2">
|
||||
<property name="label" translatable="yes">Hello World!</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="active">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="button3">
|
||||
<property name="label" translatable="yes">Hello World!</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="active">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="button4">
|
||||
<property name="label" translatable="yes">Hello World!</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="active">True</property>
|
||||
<property name="group">button3</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">3</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="button5">
|
||||
<property name="visible">True</property>
|
||||
<property name="active">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">4</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="button6">
|
||||
<property name="visible">True</property>
|
||||
<property name="active">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="button6-accessible">
|
||||
<property name="accessible-name">Test switch</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">5</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkButton" id="button7">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="label">Text Button</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button8">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="image">image8</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button9">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="image">image9</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkImage" id="image8">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon-name">edit-find-replace</property>
|
||||
<property name="icon-size">1</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="image9">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon-name">window-close-symbolic</property>
|
||||
<property name="use-fallback">True</property>
|
||||
<property name="icon-size">1</property>
|
||||
</object>
|
||||
</interface>
|
16
testsuite/css/nodes/entries.nodes
Normal file
16
testsuite/css/nodes/entries.nodes
Normal file
@@ -0,0 +1,16 @@
|
||||
window visible=0 state=dir-ltr classes=background
|
||||
decoration visible=1 state=dir-ltr
|
||||
box visible=0 state=dir-ltr classes=horizontal
|
||||
label visible=1 state=dir-ltr
|
||||
label visible=1 state=dir-ltr
|
||||
label visible=1 state=dir-ltr
|
||||
entry visible=1 state=dir-ltr
|
||||
progress visible=1 state=dir-ltr
|
||||
entry visible=1 state=dir-ltr
|
||||
entry visible=1 state=dir-ltr
|
||||
image visible=1 state=dir-ltr classes=left
|
||||
image visible=1 state=dir-ltr classes=right
|
||||
spinbutton visible=1 state=dir-ltr classes=horizontal
|
||||
entry visible=1 state=dir-ltr
|
||||
button visible=1 state=dir-ltr classes=down
|
||||
button visible=1 state=dir-ltr classes=up
|
74
testsuite/css/nodes/entries.ui
Normal file
74
testsuite/css/nodes/entries.ui
Normal file
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<object class="GtkAdjustment" id="adjustment1">
|
||||
<property name="lower">0.5</property>
|
||||
<property name="upper">99.5</property>
|
||||
<property name="page-size">0</property>
|
||||
<property name="value">45.5</property>
|
||||
<property name="step-increment">0.5</property>
|
||||
<property name="page-increment">5.0</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="type">popup</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="box1">
|
||||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="label">_entry:</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">entry1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="label">_password entry:</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">entry2</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label3">
|
||||
<property name="label">_spinbutton:</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">spinbutton1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry1">
|
||||
<property name="text" translatable="yes">text</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="progress-fraction">0.3</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry2">
|
||||
<property name="text" translatable="yes">password text</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="visibility">False</property>
|
||||
<property name="invisible_char">*</property>
|
||||
<property name="invisible_char_set">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry3">
|
||||
<property name="text" translatable="yes">icons</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="primary-icon-stock">stock1</property>
|
||||
<property name="secondary-icon-stock">stock2</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="spinbutton1">
|
||||
<property name="adjustment">adjustment1</property>
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
55
testsuite/css/nodes/levelbar.nodes
Normal file
55
testsuite/css/nodes/levelbar.nodes
Normal file
@@ -0,0 +1,55 @@
|
||||
window visible=0 state=dir-ltr classes=background
|
||||
decoration visible=1 state=dir-ltr
|
||||
box visible=1 state=dir-ltr classes=vertical
|
||||
levelbar visible=1 state=dir-ltr classes=horizontal,continuous
|
||||
trough visible=1 state=dir-ltr
|
||||
block visible=1 state=dir-ltr classes=high,filled
|
||||
block visible=1 state=dir-ltr classes=empty
|
||||
levelbar visible=1 state=dir-ltr classes=horizontal,continuous
|
||||
trough visible=1 state=dir-ltr
|
||||
block visible=1 state=dir-ltr classes=empty
|
||||
block visible=1 state=dir-ltr classes=high,filled
|
||||
levelbar visible=1 state=dir-ltr classes=horizontal,continuous
|
||||
trough visible=1 state=dir-ltr
|
||||
block visible=1 state=dir-ltr classes=low,filled
|
||||
block visible=1 state=dir-ltr classes=empty
|
||||
levelbar visible=1 state=dir-ltr classes=horizontal,continuous
|
||||
trough visible=1 state=dir-ltr
|
||||
block visible=1 state=dir-ltr classes=full,filled
|
||||
block visible=1 state=dir-ltr classes=empty
|
||||
levelbar visible=1 state=dir-ltr classes=horizontal,discrete
|
||||
trough visible=1 state=dir-ltr
|
||||
block visible=1 state=dir-ltr classes=full,filled
|
||||
block visible=1 state=dir-ltr classes=full,filled
|
||||
block visible=1 state=dir-ltr classes=full,filled
|
||||
block visible=1 state=dir-ltr classes=full,filled
|
||||
block visible=1 state=dir-ltr classes=full,filled
|
||||
block visible=1 state=dir-ltr classes=empty
|
||||
block visible=1 state=dir-ltr classes=empty
|
||||
block visible=1 state=dir-ltr classes=empty
|
||||
block visible=1 state=dir-ltr classes=empty
|
||||
block visible=1 state=dir-ltr classes=empty
|
||||
levelbar visible=1 state=dir-ltr classes=horizontal,discrete
|
||||
trough visible=1 state=dir-ltr
|
||||
block visible=1 state=dir-ltr classes=full,filled
|
||||
block visible=1 state=dir-ltr classes=full,filled
|
||||
block visible=1 state=dir-ltr classes=empty
|
||||
block visible=1 state=dir-ltr classes=empty
|
||||
block visible=1 state=dir-ltr classes=empty
|
||||
block visible=1 state=dir-ltr classes=empty
|
||||
block visible=1 state=dir-ltr classes=empty
|
||||
block visible=1 state=dir-ltr classes=empty
|
||||
block visible=1 state=dir-ltr classes=empty
|
||||
block visible=1 state=dir-ltr classes=empty
|
||||
levelbar visible=1 state=dir-ltr classes=horizontal,discrete
|
||||
trough visible=1 state=dir-ltr
|
||||
block visible=1 state=dir-ltr classes=full,filled
|
||||
block visible=1 state=dir-ltr classes=full,filled
|
||||
block visible=1 state=dir-ltr classes=full,filled
|
||||
block visible=1 state=dir-ltr classes=full,filled
|
||||
block visible=1 state=dir-ltr classes=full,filled
|
||||
block visible=1 state=dir-ltr classes=full,filled
|
||||
block visible=1 state=dir-ltr classes=full,filled
|
||||
block visible=1 state=dir-ltr classes=full,filled
|
||||
block visible=1 state=dir-ltr classes=empty
|
||||
block visible=1 state=dir-ltr classes=empty
|
66
testsuite/css/nodes/levelbar.ui
Normal file
66
testsuite/css/nodes/levelbar.ui
Normal file
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="type">popup</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLevelBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="value">0.5</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLevelBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="inverted">True</property>
|
||||
<property name="value">0.5</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLevelBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="value">0.2</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLevelBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="value">0.8</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLevelBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="min-value">0</property>
|
||||
<property name="max-value">10</property>
|
||||
<property name="value">5</property>
|
||||
<property name="mode">discrete</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLevelBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="min-value">0</property>
|
||||
<property name="max-value">10</property>
|
||||
<property name="value">2</property>
|
||||
<property name="mode">discrete</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLevelBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="min-value">0</property>
|
||||
<property name="max-value">10</property>
|
||||
<property name="value">8</property>
|
||||
<property name="mode">discrete</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
15
testsuite/css/nodes/notebook.nodes
Normal file
15
testsuite/css/nodes/notebook.nodes
Normal file
@@ -0,0 +1,15 @@
|
||||
window visible=0 state=dir-ltr classes=background
|
||||
decoration visible=1 state=dir-ltr
|
||||
notebook visible=1 state=dir-ltr classes=frame
|
||||
header visible=1 state=dir-ltr classes=top
|
||||
button visible=1 state=dir-ltr classes=text-button
|
||||
label visible=1 state=dir-ltr
|
||||
tabs visible=1 state=dir-ltr
|
||||
tab visible=1 state=active|dir-ltr
|
||||
label visible=1 state=dir-ltr
|
||||
tab visible=1 state=dir-ltr
|
||||
label visible=1 state=dir-ltr
|
||||
button visible=1 state=dir-ltr classes=text-button
|
||||
label visible=1 state=dir-ltr
|
||||
button visible=1 state=dir-ltr classes=text-button
|
||||
label visible=1 state=dir-ltr
|
43
testsuite/css/nodes/notebook.ui
Normal file
43
testsuite/css/nodes/notebook.ui
Normal file
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="type">popup</property>
|
||||
<child>
|
||||
<object class="GtkNotebook" id="notebook1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="page1">
|
||||
<property name="label" translatable="yes">Yes</property>
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="tab">
|
||||
<object class="GtkLabel" id="tab1">
|
||||
<property name="label" translatable="yes">Tab 1</property>
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="page2">
|
||||
<property name="label" translatable="yes">No</property>
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="tab">
|
||||
<object class="GtkLabel" id="tab2">
|
||||
<property name="label" translatable="yes">Tab 2</property>
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="action-start">
|
||||
<object class="GtkButton" id="action">
|
||||
<property name="label" translatable="yes">Action</property>
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
20
testsuite/css/nodes/progressbar.nodes
Normal file
20
testsuite/css/nodes/progressbar.nodes
Normal file
@@ -0,0 +1,20 @@
|
||||
window visible=0 state=dir-ltr classes=background
|
||||
decoration visible=1 state=dir-ltr
|
||||
box id=progressbars visible=1 state=dir-ltr classes=vertical
|
||||
progressbar visible=1 state=dir-ltr classes=horizontal
|
||||
text visible=1 state=dir-ltr
|
||||
trough visible=1 state=dir-ltr
|
||||
progress visible=1 state=dir-ltr classes=left
|
||||
progressbar visible=1 state=dir-ltr classes=horizontal
|
||||
trough visible=1 state=dir-ltr
|
||||
progress visible=1 state=dir-ltr classes=left
|
||||
progressbar visible=1 state=dir-ltr classes=horizontal
|
||||
text visible=1 state=dir-ltr
|
||||
trough visible=1 state=dir-ltr
|
||||
progress visible=1 state=dir-ltr classes=left
|
||||
progressbar visible=1 state=dir-ltr classes=horizontal
|
||||
trough visible=1 state=dir-ltr
|
||||
progress visible=1 state=dir-ltr classes=right
|
||||
progressbar visible=1 state=dir-ltr classes=vertical
|
||||
trough visible=1 state=dir-ltr
|
||||
progress visible=1 state=dir-ltr classes=top
|
49
testsuite/css/nodes/progressbar.ui
Normal file
49
testsuite/css/nodes/progressbar.ui
Normal file
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="type">popup</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="name">progressbars</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkProgressBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="show-text">True</property>
|
||||
<property name="fraction">0</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkProgressBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="fraction">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkProgressBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="show-text">True</property>
|
||||
<property name="fraction">0.4</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkProgressBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="inverted">True</property>
|
||||
<property name="fraction">0.4</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkProgressBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="fraction">0.4</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
265
testsuite/css/nodes/test-css-nodes.c
Normal file
265
testsuite/css/nodes/test-css-nodes.c
Normal file
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat Inc.
|
||||
*
|
||||
* Author:
|
||||
* Matthias Clasen <mclasen@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
static char *
|
||||
test_get_reference_file (const char *ui_file)
|
||||
{
|
||||
GString *file = g_string_new (NULL);
|
||||
|
||||
if (g_str_has_suffix (ui_file, ".ui"))
|
||||
g_string_append_len (file, ui_file, strlen (ui_file) - 3);
|
||||
else
|
||||
g_string_append (file, ui_file);
|
||||
|
||||
g_string_append (file, ".nodes");
|
||||
|
||||
if (!g_file_test (file->str, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_string_free (file, TRUE);
|
||||
return g_strdup (ui_file);
|
||||
}
|
||||
|
||||
return g_string_free (file, FALSE);
|
||||
}
|
||||
|
||||
static char *
|
||||
diff_with_file (const char *file1,
|
||||
char *text,
|
||||
gssize len,
|
||||
GError **error)
|
||||
{
|
||||
const char *command[] = { "diff", "-u", file1, NULL, NULL };
|
||||
char *diff, *tmpfile;
|
||||
int fd;
|
||||
|
||||
diff = NULL;
|
||||
|
||||
if (len < 0)
|
||||
len = strlen (text);
|
||||
|
||||
/* write the text buffer to a temporary file */
|
||||
fd = g_file_open_tmp (NULL, &tmpfile, error);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
if (write (fd, text, len) != (int) len)
|
||||
{
|
||||
close (fd);
|
||||
g_set_error (error,
|
||||
G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||
"Could not write data to temporary file '%s'", tmpfile);
|
||||
goto done;
|
||||
}
|
||||
close (fd);
|
||||
command[3] = tmpfile;
|
||||
|
||||
/* run diff command */
|
||||
g_spawn_sync (NULL,
|
||||
(char **) command,
|
||||
NULL,
|
||||
G_SPAWN_SEARCH_PATH,
|
||||
NULL, NULL,
|
||||
&diff,
|
||||
NULL, NULL,
|
||||
error);
|
||||
|
||||
done:
|
||||
g_unlink (tmpfile);
|
||||
g_free (tmpfile);
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
static void
|
||||
load_ui_file (GFile *file, gboolean generate)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GtkWidget *window;
|
||||
GtkStyleContext *context;
|
||||
char *output, *diff;
|
||||
char *ui_file, *reference_file;
|
||||
GError *error = NULL;
|
||||
|
||||
ui_file = g_file_get_path (file);
|
||||
|
||||
builder = gtk_builder_new_from_file (ui_file);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
|
||||
|
||||
g_assert (window != NULL);
|
||||
|
||||
context = gtk_widget_get_style_context (window);
|
||||
|
||||
output = gtk_style_context_to_string (context, GTK_STYLE_CONTEXT_PRINT_RECURSE);
|
||||
|
||||
if (generate)
|
||||
{
|
||||
g_print ("%s", output);
|
||||
goto out;
|
||||
}
|
||||
|
||||
reference_file = test_get_reference_file (ui_file);
|
||||
|
||||
diff = diff_with_file (reference_file, output, -1, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
if (diff && diff[0])
|
||||
{
|
||||
g_test_message ("Resulting output doesn't match reference:\n%s", diff);
|
||||
g_test_fail ();
|
||||
}
|
||||
g_free (reference_file);
|
||||
g_free (diff);
|
||||
|
||||
out:
|
||||
g_free (output);
|
||||
g_free (ui_file);
|
||||
}
|
||||
|
||||
static void
|
||||
test_ui_file (GFile *file)
|
||||
{
|
||||
load_ui_file (file, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
add_test_for_file (GFile *file)
|
||||
{
|
||||
char *path;
|
||||
|
||||
path = g_file_get_path (file);
|
||||
|
||||
g_test_add_vtable (path,
|
||||
0,
|
||||
g_object_ref (file),
|
||||
NULL,
|
||||
(GTestFixtureFunc) test_ui_file,
|
||||
(GTestFixtureFunc) g_object_unref);
|
||||
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_files (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
GFile *file1 = G_FILE (a);
|
||||
GFile *file2 = G_FILE (b);
|
||||
char *path1, *path2;
|
||||
int result;
|
||||
|
||||
path1 = g_file_get_path (file1);
|
||||
path2 = g_file_get_path (file2);
|
||||
|
||||
result = strcmp (path1, path2);
|
||||
|
||||
g_free (path1);
|
||||
g_free (path2);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
add_tests_for_files_in_directory (GFile *dir)
|
||||
{
|
||||
GFileEnumerator *enumerator;
|
||||
GFileInfo *info;
|
||||
GList *files;
|
||||
GError *error = NULL;
|
||||
|
||||
enumerator = g_file_enumerate_children (dir, G_FILE_ATTRIBUTE_STANDARD_NAME, 0, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
files = NULL;
|
||||
|
||||
while ((info = g_file_enumerator_next_file (enumerator, NULL, &error)))
|
||||
{
|
||||
const char *filename;
|
||||
|
||||
filename = g_file_info_get_name (info);
|
||||
|
||||
if (!g_str_has_suffix (filename, ".ui") ||
|
||||
g_str_has_suffix (filename, ".nodes"))
|
||||
{
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
|
||||
files = g_list_prepend (files, g_file_get_child (dir, filename));
|
||||
|
||||
g_object_unref (info);
|
||||
}
|
||||
|
||||
g_assert_no_error (error);
|
||||
g_object_unref (enumerator);
|
||||
|
||||
files = g_list_sort (files, compare_files);
|
||||
g_list_foreach (files, (GFunc) add_test_for_file, NULL);
|
||||
g_list_free_full (files, g_object_unref);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
g_setenv ("GTK_CSS_DEBUG", "1", TRUE);
|
||||
|
||||
gtk_test_init (&argc, &argv);
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
const char *basedir;
|
||||
GFile *dir;
|
||||
|
||||
basedir = g_test_get_dir (G_TEST_DIST);
|
||||
dir = g_file_new_for_path (basedir);
|
||||
add_tests_for_files_in_directory (dir);
|
||||
|
||||
g_object_unref (dir);
|
||||
}
|
||||
else if (strcmp (argv[1], "--generate") == 0)
|
||||
{
|
||||
if (argc >= 3)
|
||||
{
|
||||
GFile *file = g_file_new_for_commandline_arg (argv[2]);
|
||||
|
||||
load_ui_file (file, TRUE);
|
||||
|
||||
g_object_unref (file);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
GFile *file = g_file_new_for_commandline_arg (argv[i]);
|
||||
|
||||
add_test_for_file (file);
|
||||
|
||||
g_object_unref (file);
|
||||
}
|
||||
}
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
3
testsuite/css/nodes/test-css-nodes.test.in
Normal file
3
testsuite/css/nodes/test-css-nodes.test.in
Normal file
@@ -0,0 +1,3 @@
|
||||
[Test]
|
||||
Exec=/bin/sh -c "cd @libexecdir@/installed-tests/gtk+/css/nodes && @libexecdir@/installed-tests/gtk+/css/nodes/test-css-nodes
|
||||
Type=session
|
59
testsuite/css/style/Makefile.am
Normal file
59
testsuite/css/style/Makefile.am
Normal file
@@ -0,0 +1,59 @@
|
||||
include $(top_srcdir)/Makefile.decl
|
||||
|
||||
NULL =
|
||||
|
||||
CLEANFILES =
|
||||
|
||||
TEST_PROGS += test-css-style
|
||||
test_in_files = test-css-style.test.in
|
||||
|
||||
check_PROGRAMS = $(TEST_PROGS)
|
||||
|
||||
test_css_style_CFLAGS = \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_builddir)/gdk \
|
||||
-I$(top_srcdir)/gdk \
|
||||
$(GTK_DEBUG_FLAGS) \
|
||||
$(GTK_DEP_CFLAGS)
|
||||
|
||||
test_css_style_LDADD = \
|
||||
$(top_builddir)/gdk/libgdk-3.la \
|
||||
$(top_builddir)/gtk/libgtk-3.la \
|
||||
$(GTK_DEP_LIBS)
|
||||
|
||||
test_css_style_SOURCES = \
|
||||
test-css-style.c
|
||||
|
||||
test_data = \
|
||||
currentcolor.ui currentcolor.css currentcolor.nodes \
|
||||
inherit.ui inherit.css inherit.nodes \
|
||||
label.ui label.css label.nodes \
|
||||
nth-child.ui nth-child.css nth-child.nodes \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST += $(test_in_files) $(test_data)
|
||||
|
||||
if BUILDOPT_INSTALL_TESTS
|
||||
insttestdir=$(libexecdir)/installed-tests/$(PACKAGE)/css/style
|
||||
insttest_PROGRAMS = $(TEST_PROGS)
|
||||
insttest_DATA = $(test_data)
|
||||
|
||||
substitutions = \
|
||||
-e s,@libexecdir\@,$(libexecdir),g \
|
||||
$(NULL)
|
||||
|
||||
test_files = $(test_in_files:.test.in=.test)
|
||||
|
||||
$(test_files): %.test: %.test.in
|
||||
$(AM_V_GEN) sed $(substitutions) $< > $@.tmp && mv $@.tmp $@
|
||||
|
||||
EXTRA_DIST += $(test_files)
|
||||
|
||||
CLEANFILES += $(test_files)
|
||||
|
||||
testmetadir = $(datadir)/installed-tests/$(PACKAGE)/css/style
|
||||
testmeta_DATA = $(test_files)
|
||||
endif
|
||||
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
9
testsuite/css/style/currentcolor.css
Normal file
9
testsuite/css/style/currentcolor.css
Normal file
@@ -0,0 +1,9 @@
|
||||
@import "reset-to-defaults.css";
|
||||
|
||||
box {
|
||||
color: red;
|
||||
}
|
||||
|
||||
label {
|
||||
background-color: currentColor;
|
||||
}
|
7
testsuite/css/style/currentcolor.nodes
Normal file
7
testsuite/css/style/currentcolor.nodes
Normal file
@@ -0,0 +1,7 @@
|
||||
window visible=0 state=dir-ltr classes=background
|
||||
decoration visible=1 state=dir-ltr
|
||||
box visible=1 state=dir-ltr classes=horizontal
|
||||
color: rgb(255,0,0) (currentcolor.css:4:12)
|
||||
label visible=1 state=dir-ltr
|
||||
color: rgb(255,0,0) (reset-to-defaults.css:2:12)
|
||||
background-color: rgb(255,0,0) (currentcolor.css:8:32)
|
19
testsuite/css/style/currentcolor.ui
Normal file
19
testsuite/css/style/currentcolor.ui
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="type">popup</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Hello World!</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
11
testsuite/css/style/inherit.css
Normal file
11
testsuite/css/style/inherit.css
Normal file
@@ -0,0 +1,11 @@
|
||||
@import "reset-to-defaults.css";
|
||||
|
||||
box {
|
||||
color: red;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
label#label1 {
|
||||
color: initial;
|
||||
opacity: inherit;
|
||||
}
|
9
testsuite/css/style/inherit.nodes
Normal file
9
testsuite/css/style/inherit.nodes
Normal file
@@ -0,0 +1,9 @@
|
||||
window visible=0 state=dir-ltr classes=background
|
||||
decoration visible=1 state=dir-ltr
|
||||
box visible=1 state=dir-ltr classes=horizontal
|
||||
color: rgb(255,0,0) (inherit.css:4:12)
|
||||
opacity: 0.5 (inherit.css:5:14)
|
||||
label id=label1 visible=1 state=dir-ltr
|
||||
opacity: 0.5 (inherit.css:10:18)
|
||||
label id=label2 visible=1 state=dir-ltr
|
||||
color: rgb(255,0,0) (reset-to-defaults.css:2:12)
|
27
testsuite/css/style/inherit.ui
Normal file
27
testsuite/css/style/inherit.ui
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="type">popup</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="name">label1</property>
|
||||
<property name="label" translatable="yes">Hello World!</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="name">label2</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Hello World!</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
5
testsuite/css/style/label.css
Normal file
5
testsuite/css/style/label.css
Normal file
@@ -0,0 +1,5 @@
|
||||
@import "reset-to-defaults.css";
|
||||
|
||||
box {
|
||||
font: "Comic Sans";
|
||||
}
|
6
testsuite/css/style/label.nodes
Normal file
6
testsuite/css/style/label.nodes
Normal file
@@ -0,0 +1,6 @@
|
||||
window visible=0 state=dir-ltr classes=background
|
||||
decoration visible=1 state=dir-ltr
|
||||
box visible=1 state=dir-ltr classes=horizontal
|
||||
font-family: "\"Comic Sans\"" (label.css:4:20)
|
||||
label visible=1 state=dir-ltr
|
||||
font-family: "\"Comic Sans\"" (reset-to-defaults.css:2:12)
|
19
testsuite/css/style/label.ui
Normal file
19
testsuite/css/style/label.ui
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="type">popup</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Hello World!</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
14
testsuite/css/style/nth-child.css
Normal file
14
testsuite/css/style/nth-child.css
Normal file
@@ -0,0 +1,14 @@
|
||||
@import "reset-to-defaults.css";
|
||||
|
||||
label:first-child {
|
||||
font-size: 20px;
|
||||
}
|
||||
label {
|
||||
font-size: 30px;
|
||||
}
|
||||
label:last-child {
|
||||
font-size: 40px;
|
||||
}
|
||||
label:only-child {
|
||||
font-size: 50px;
|
||||
}
|
13
testsuite/css/style/nth-child.nodes
Normal file
13
testsuite/css/style/nth-child.nodes
Normal file
@@ -0,0 +1,13 @@
|
||||
window visible=0 state=dir-ltr classes=background
|
||||
decoration visible=1 state=dir-ltr
|
||||
box visible=1 state=dir-ltr classes=horizontal
|
||||
box visible=1 state=dir-ltr classes=horizontal
|
||||
label visible=1 state=dir-ltr
|
||||
font-size: 20px (nth-child.css:4:17)
|
||||
label visible=1 state=dir-ltr
|
||||
font-size: 30px (nth-child.css:7:17)
|
||||
label visible=1 state=dir-ltr
|
||||
font-size: 40px (nth-child.css:10:17)
|
||||
box visible=1 state=dir-ltr classes=horizontal
|
||||
label visible=1 state=dir-ltr
|
||||
font-size: 50px (nth-child.css:13:17)
|
48
testsuite/css/style/nth-child.ui
Normal file
48
testsuite/css/style/nth-child.ui
Normal file
@@ -0,0 +1,48 @@
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="type">popup</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Hello World!</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Hello World!</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Hello World!</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Hello World!</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
287
testsuite/css/style/test-css-style.c
Normal file
287
testsuite/css/style/test-css-style.c
Normal file
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat Inc.
|
||||
*
|
||||
* Author:
|
||||
* Matthias Clasen <mclasen@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/* There shall be no other styles */
|
||||
#define GTK_STYLE_PROVIDER_PRIORITY_FORCE G_MAXUINT
|
||||
|
||||
char *
|
||||
test_get_other_file (const char *ui_file, const char *extension)
|
||||
{
|
||||
GString *file = g_string_new (NULL);
|
||||
|
||||
if (g_str_has_suffix (ui_file, ".ui"))
|
||||
g_string_append_len (file, ui_file, strlen (ui_file) - strlen (".ui"));
|
||||
else
|
||||
g_string_append (file, ui_file);
|
||||
|
||||
g_string_append (file, extension);
|
||||
|
||||
if (!g_file_test (file->str, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_string_free (file, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_string_free (file, FALSE);
|
||||
}
|
||||
|
||||
static char *
|
||||
diff_with_file (const char *file1,
|
||||
char *text,
|
||||
gssize len,
|
||||
GError **error)
|
||||
{
|
||||
const char *command[] = { "diff", "-u", file1, NULL, NULL };
|
||||
char *diff, *tmpfile;
|
||||
int fd;
|
||||
|
||||
diff = NULL;
|
||||
|
||||
if (len < 0)
|
||||
len = strlen (text);
|
||||
|
||||
/* write the text buffer to a temporary file */
|
||||
fd = g_file_open_tmp (NULL, &tmpfile, error);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
if (write (fd, text, len) != (int) len)
|
||||
{
|
||||
close (fd);
|
||||
g_set_error (error,
|
||||
G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||
"Could not write data to temporary file '%s'", tmpfile);
|
||||
goto done;
|
||||
}
|
||||
close (fd);
|
||||
command[3] = tmpfile;
|
||||
|
||||
/* run diff command */
|
||||
g_spawn_sync (NULL,
|
||||
(char **) command,
|
||||
NULL,
|
||||
G_SPAWN_SEARCH_PATH,
|
||||
NULL, NULL,
|
||||
&diff,
|
||||
NULL, NULL,
|
||||
error);
|
||||
|
||||
done:
|
||||
g_unlink (tmpfile);
|
||||
g_free (tmpfile);
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
static void
|
||||
load_ui_file (GFile *file, gboolean generate)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GtkWidget *window;
|
||||
GtkStyleContext *context;
|
||||
char *output, *diff;
|
||||
char *ui_file, *css_file, *reference_file;
|
||||
GtkCssProvider *provider;
|
||||
GError *error = NULL;
|
||||
|
||||
ui_file = g_file_get_path (file);
|
||||
|
||||
css_file = test_get_other_file (ui_file, ".css");
|
||||
g_assert (css_file != NULL);
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_path (provider, css_file, &error);
|
||||
g_assert_no_error (error);
|
||||
gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_FORCE);
|
||||
|
||||
builder = gtk_builder_new_from_file (ui_file);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
|
||||
|
||||
g_assert (window != NULL);
|
||||
|
||||
context = gtk_widget_get_style_context (window);
|
||||
|
||||
output = gtk_style_context_to_string (context, GTK_STYLE_CONTEXT_PRINT_RECURSE |
|
||||
GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE);
|
||||
|
||||
if (generate)
|
||||
{
|
||||
g_print ("%s", output);
|
||||
goto out;
|
||||
}
|
||||
|
||||
reference_file = test_get_other_file (ui_file, ".nodes");
|
||||
|
||||
diff = diff_with_file (reference_file, output, -1, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
if (diff && diff[0])
|
||||
{
|
||||
g_test_message ("Resulting output doesn't match reference:\n%s", diff);
|
||||
g_test_fail ();
|
||||
}
|
||||
g_free (reference_file);
|
||||
g_free (diff);
|
||||
|
||||
out:
|
||||
gtk_style_context_remove_provider_for_screen (gdk_screen_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider));
|
||||
g_object_unref (provider);
|
||||
|
||||
g_free (output);
|
||||
g_free (ui_file);
|
||||
g_free (css_file);
|
||||
}
|
||||
|
||||
static void
|
||||
test_ui_file (GFile *file)
|
||||
{
|
||||
load_ui_file (file, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
add_test_for_file (GFile *file)
|
||||
{
|
||||
char *path;
|
||||
|
||||
path = g_file_get_path (file);
|
||||
|
||||
g_test_add_vtable (path,
|
||||
0,
|
||||
g_object_ref (file),
|
||||
NULL,
|
||||
(GTestFixtureFunc) test_ui_file,
|
||||
(GTestFixtureFunc) g_object_unref);
|
||||
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_files (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
GFile *file1 = G_FILE (a);
|
||||
GFile *file2 = G_FILE (b);
|
||||
char *path1, *path2;
|
||||
int result;
|
||||
|
||||
path1 = g_file_get_path (file1);
|
||||
path2 = g_file_get_path (file2);
|
||||
|
||||
result = strcmp (path1, path2);
|
||||
|
||||
g_free (path1);
|
||||
g_free (path2);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
add_tests_for_files_in_directory (GFile *dir)
|
||||
{
|
||||
GFileEnumerator *enumerator;
|
||||
GFileInfo *info;
|
||||
GList *files;
|
||||
GError *error = NULL;
|
||||
|
||||
enumerator = g_file_enumerate_children (dir, G_FILE_ATTRIBUTE_STANDARD_NAME, 0, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
files = NULL;
|
||||
|
||||
while ((info = g_file_enumerator_next_file (enumerator, NULL, &error)))
|
||||
{
|
||||
const char *filename;
|
||||
|
||||
filename = g_file_info_get_name (info);
|
||||
|
||||
if (!g_str_has_suffix (filename, ".ui") ||
|
||||
g_str_has_suffix (filename, ".nodes"))
|
||||
{
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
|
||||
files = g_list_prepend (files, g_file_get_child (dir, filename));
|
||||
|
||||
g_object_unref (info);
|
||||
}
|
||||
|
||||
g_assert_no_error (error);
|
||||
g_object_unref (enumerator);
|
||||
|
||||
files = g_list_sort (files, compare_files);
|
||||
g_list_foreach (files, (GFunc) add_test_for_file, NULL);
|
||||
g_list_free_full (files, g_object_unref);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
g_setenv ("GTK_CSS_DEBUG", "1", TRUE);
|
||||
|
||||
gtk_test_init (&argc, &argv);
|
||||
|
||||
g_object_set (gtk_settings_get_default (),
|
||||
"gtk-font-name", "Sans",
|
||||
NULL);
|
||||
if (argc < 2)
|
||||
{
|
||||
const char *basedir;
|
||||
GFile *dir;
|
||||
|
||||
basedir = g_test_get_dir (G_TEST_DIST);
|
||||
dir = g_file_new_for_path (basedir);
|
||||
add_tests_for_files_in_directory (dir);
|
||||
|
||||
g_object_unref (dir);
|
||||
}
|
||||
else if (strcmp (argv[1], "--generate") == 0)
|
||||
{
|
||||
if (argc >= 3)
|
||||
{
|
||||
GFile *file = g_file_new_for_commandline_arg (argv[2]);
|
||||
|
||||
load_ui_file (file, TRUE);
|
||||
|
||||
g_object_unref (file);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
GFile *file = g_file_new_for_commandline_arg (argv[i]);
|
||||
|
||||
add_test_for_file (file);
|
||||
|
||||
g_object_unref (file);
|
||||
}
|
||||
}
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
3
testsuite/css/style/test-css-style.test.in
Normal file
3
testsuite/css/style/test-css-style.test.in
Normal file
@@ -0,0 +1,3 @@
|
||||
[Test]
|
||||
Exec=/bin/sh -c "cd @libexecdir@/installed-tests/gtk+/css/style && @libexecdir@/installed-tests/gtk+/css/style/test-css-style
|
||||
Type=session
|
Reference in New Issue
Block a user