summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHavoc Pennington <hp@pobox.com>2002-02-10 01:10:33 +0000
committerHavoc Pennington <hp@src.gnome.org>2002-02-10 01:10:33 +0000
commit2bad2844f55fe5a241bdb4da7747905798da9a6d (patch)
tree318549e0556708036c97151dc0e7929c1559308d
parent245c9c2d7e27445744eee764ecae6e3914fabd1e (diff)
downloadmetacity-2bad2844f55fe5a241bdb4da7747905798da9a6d.tar.gz
implement wacky "tile" draw op to lose some of the PNG files in Gorilla
2002-02-09 Havoc Pennington <hp@pobox.com> * src/theme.c (meta_draw_op_draw_with_env): implement wacky "tile" draw op to lose some of the PNG files in Gorilla theme * src/theme-parser.c: parse the tile primitive
-rw-r--r--ChangeLog7
-rw-r--r--src/theme-parser.c135
-rw-r--r--src/theme.c81
-rw-r--r--src/theme.h16
-rw-r--r--theme-format.txt5
5 files changed, 240 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 40dacf7a..aae7c1f9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,11 @@
2002-02-09 Havoc Pennington <hp@pobox.com>
+
+ * src/theme.c (meta_draw_op_draw_with_env): implement wacky "tile"
+ draw op to lose some of the PNG files in Gorilla theme
+
+ * src/theme-parser.c: parse the tile primitive
+
+2002-02-09 Havoc Pennington <hp@pobox.com>
* src/window.c (update_icon): port to icon cache
diff --git a/src/theme-parser.c b/src/theme-parser.c
index d857be81..45006157 100644
--- a/src/theme-parser.c
+++ b/src/theme-parser.c
@@ -57,6 +57,7 @@ typedef enum
STATE_ICON,
STATE_TITLE,
STATE_INCLUDE, /* include another draw op list */
+ STATE_TILE, /* tile another draw op list */
/* sub-parts of gradient */
STATE_COLOR,
/* frame style */
@@ -2637,7 +2638,7 @@ parse_draw_op_element (GMarkupParseContext *context,
if (name == NULL)
{
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
- _("No \"name\" attribute on element <%s>"), element_name);
+ _("No \"%s\" attribute on element <%s>"), "name", element_name);
return;
}
@@ -2697,6 +2698,130 @@ parse_draw_op_element (GMarkupParseContext *context,
push_state (info, STATE_INCLUDE);
}
+ else if (ELEMENT_IS ("tile"))
+ {
+ MetaDrawOp *op;
+ const char *name;
+ const char *x;
+ const char *y;
+ const char *width;
+ const char *height;
+ const char *tile_xoffset;
+ const char *tile_yoffset;
+ const char *tile_width;
+ const char *tile_height;
+ MetaDrawOpList *op_list;
+
+ if (!locate_attributes (context, element_name, attribute_names, attribute_values,
+ error,
+ "x", &x, "y", &y,
+ "width", &width, "height", &height,
+ "name", &name,
+ "tile_xoffset", &tile_xoffset,
+ "tile_yoffset", &tile_yoffset,
+ "tile_width", &tile_width,
+ "tile_height", &tile_height,
+ NULL))
+ return;
+
+ if (name == NULL)
+ {
+ set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
+ _("No \"%s\" attribute on element <%s>"), "name", element_name);
+ return;
+ }
+
+ if (tile_width == NULL)
+ {
+ set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
+ _("No \"%s\" attribute on element <%s>"), "tile_width", element_name);
+ return;
+ }
+
+ if (tile_height == NULL)
+ {
+ set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
+ _("No \"%s\" attribute on element <%s>"), "tile_height", element_name);
+ return;
+ }
+
+ /* These default to 0 */
+ if (tile_xoffset && !check_expression (tile_xoffset, FALSE, info->theme, context, error))
+ return;
+
+ if (tile_yoffset && !check_expression (tile_xoffset, FALSE, info->theme, context, error))
+ return;
+
+ /* x/y/width/height default to 0,0,width,height - should
+ * probably do this for all the draw ops
+ */
+
+ if (x && !check_expression (x, FALSE, info->theme, context, error))
+ return;
+
+ if (y && !check_expression (y, FALSE, info->theme, context, error))
+ return;
+
+ if (width && !check_expression (width, FALSE, info->theme, context, error))
+ return;
+
+ if (height && !check_expression (height, FALSE, info->theme, context, error))
+ return;
+
+ if (!check_expression (tile_width, FALSE, info->theme, context, error))
+ return;
+
+ if (!check_expression (tile_height, FALSE, info->theme, context, error))
+ return;
+
+ op_list = meta_theme_lookup_draw_op_list (info->theme,
+ name);
+ if (op_list == NULL)
+ {
+ set_error (error, context, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_PARSE,
+ _("No <draw_ops> called \"%s\" has been defined"),
+ name);
+ return;
+ }
+
+ g_assert (info->op_list);
+
+ if (op_list == info->op_list ||
+ meta_draw_op_list_contains (op_list, info->op_list))
+ {
+ set_error (error, context, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_PARSE,
+ _("Including draw_ops \"%s\" here would create a circular reference"),
+ name);
+ return;
+ }
+
+ op = meta_draw_op_new (META_DRAW_TILE);
+
+ meta_draw_op_list_ref (op_list);
+ op->data.tile.op_list = op_list;
+ op->data.tile.x = x ? optimize_expression (info->theme, x) :
+ g_strdup ("0");
+ op->data.tile.y = y ? optimize_expression (info->theme, y) :
+ g_strdup ("0");
+ op->data.tile.width = width ? optimize_expression (info->theme, width) :
+ g_strdup ("width");
+ op->data.tile.height = height ? optimize_expression (info->theme, height) :
+ g_strdup ("height");
+ op->data.tile.tile_xoffset = tile_xoffset ?
+ optimize_expression (info->theme, tile_xoffset) :
+ g_strdup ("0");
+ op->data.tile.tile_yoffset = tile_yoffset ?
+ optimize_expression (info->theme, tile_yoffset) :
+ g_strdup ("0");
+ op->data.tile.tile_width = optimize_expression (info->theme, tile_width);
+ op->data.tile.tile_height = optimize_expression (info->theme, tile_height);
+
+ meta_draw_op_list_append (info->op_list, op);
+
+ push_state (info, STATE_TILE);
+ }
else
{
set_error (error, context,
@@ -3292,6 +3417,7 @@ start_element_handler (GMarkupParseContext *context,
case STATE_ICON:
case STATE_TITLE:
case STATE_INCLUDE:
+ case STATE_TILE:
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
_("Element <%s> is not allowed inside a draw operation element"),
element_name);
@@ -3525,6 +3651,10 @@ end_element_handler (GMarkupParseContext *context,
pop_state (info);
g_assert (peek_state (info) == STATE_DRAW_OPS);
break;
+ case STATE_TILE:
+ pop_state (info);
+ g_assert (peek_state (info) == STATE_DRAW_OPS);
+ break;
case STATE_COLOR:
pop_state (info);
g_assert (peek_state (info) == STATE_GRADIENT);
@@ -3780,6 +3910,9 @@ text_handler (GMarkupParseContext *context,
case STATE_INCLUDE:
NO_TEXT ("include");
break;
+ case STATE_TILE:
+ NO_TEXT ("tile");
+ break;
case STATE_COLOR:
NO_TEXT ("color");
break;
diff --git a/src/theme.c b/src/theme.c
index 10090bec..a2854926 100644
--- a/src/theme.c
+++ b/src/theme.c
@@ -2285,6 +2285,9 @@ meta_draw_op_new (MetaDrawType type)
case META_DRAW_OP_LIST:
size += sizeof (dummy.data.op_list);
break;
+ case META_DRAW_TILE:
+ size += sizeof (dummy.data.tile);
+ break;
}
op = g_malloc0 (size);
@@ -2400,6 +2403,7 @@ meta_draw_op_free (MetaDrawOp *op)
g_free (op->data.title.x);
g_free (op->data.title.y);
break;
+
case META_DRAW_OP_LIST:
if (op->data.op_list.op_list)
meta_draw_op_list_unref (op->data.op_list.op_list);
@@ -2408,6 +2412,19 @@ meta_draw_op_free (MetaDrawOp *op)
g_free (op->data.op_list.width);
g_free (op->data.op_list.height);
break;
+
+ case META_DRAW_TILE:
+ if (op->data.tile.op_list)
+ meta_draw_op_list_unref (op->data.tile.op_list);
+ g_free (op->data.tile.x);
+ g_free (op->data.tile.y);
+ g_free (op->data.tile.width);
+ g_free (op->data.tile.height);
+ g_free (op->data.tile.tile_xoffset);
+ g_free (op->data.tile.tile_yoffset);
+ g_free (op->data.tile.tile_width);
+ g_free (op->data.tile.tile_height);
+ break;
}
g_free (op);
@@ -2720,7 +2737,10 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
break;
case META_DRAW_OP_LIST:
- break;
+ break;
+
+ case META_DRAW_TILE:
+ break;
}
return pixbuf;
@@ -3052,6 +3072,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
g_object_unref (G_OBJECT (gc));
}
break;
+
case META_DRAW_OP_LIST:
{
int rx, ry, rwidth, rheight;
@@ -3066,6 +3087,55 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
rx, ry, rwidth, rheight);
}
break;
+
+ case META_DRAW_TILE:
+ {
+ int rx, ry, rwidth, rheight;
+ int tile_xoffset, tile_yoffset, tile_width, tile_height;
+ GdkRectangle new_clip;
+ int tile_x, tile_y;
+
+ rx = parse_x_position_unchecked (op->data.tile.x, env);
+ ry = parse_y_position_unchecked (op->data.tile.y, env);
+ rwidth = parse_size_unchecked (op->data.tile.width, env);
+ rheight = parse_size_unchecked (op->data.tile.height, env);
+
+ new_clip.x = rx;
+ new_clip.y = ry;
+ new_clip.width = rwidth;
+ new_clip.height = rheight;
+
+ if (clip == NULL || gdk_rectangle_intersect ((GdkRectangle*)clip, &new_clip,
+ &new_clip))
+ {
+ tile_xoffset = parse_x_position_unchecked (op->data.tile.tile_xoffset, env);
+ tile_yoffset = parse_y_position_unchecked (op->data.tile.tile_yoffset, env);
+ /* tile offset should not include x/y */
+ tile_xoffset -= x;
+ tile_yoffset -= y;
+
+ tile_width = parse_size_unchecked (op->data.tile.tile_width, env);
+ tile_height = parse_size_unchecked (op->data.tile.tile_height, env);
+
+ tile_x = rx - tile_xoffset;
+
+ while (tile_x < (rx + rwidth))
+ {
+ tile_y = ry - tile_yoffset;
+ while (tile_y < (ry + rheight))
+ {
+ meta_draw_op_list_draw (op->data.tile.op_list,
+ widget, drawable, &new_clip, info,
+ tile_x, tile_y, tile_width, tile_height);
+
+ tile_y += tile_height;
+ }
+
+ tile_x += tile_width;
+ }
+ }
+ }
+ break;
}
}
@@ -3260,6 +3330,15 @@ meta_draw_op_list_contains (MetaDrawOpList *op_list,
child))
return TRUE;
}
+ else if (op_list->ops[i]->type == META_DRAW_TILE)
+ {
+ if (op_list->ops[i]->data.tile.op_list == child)
+ return TRUE;
+
+ if (meta_draw_op_list_contains (op_list->ops[i]->data.tile.op_list,
+ child))
+ return TRUE;
+ }
++i;
}
diff --git a/src/theme.h b/src/theme.h
index 5ba1790a..17b2b4af 100644
--- a/src/theme.h
+++ b/src/theme.h
@@ -192,7 +192,9 @@ typedef enum
/* App's window title */
META_DRAW_TITLE,
/* a draw op list */
- META_DRAW_OP_LIST
+ META_DRAW_OP_LIST,
+ /* tiled draw op list */
+ META_DRAW_TILE
} MetaDrawType;
struct _MetaDrawOp
@@ -318,6 +320,18 @@ struct _MetaDrawOp
char *width;
char *height;
} op_list;
+
+ struct {
+ MetaDrawOpList *op_list;
+ char *x;
+ char *y;
+ char *width;
+ char *height;
+ char *tile_xoffset;
+ char *tile_yoffset;
+ char *tile_width;
+ char *tile_height;
+ } tile;
} data;
};
diff --git a/theme-format.txt b/theme-format.txt
index c5403342..9cbc08ea 100644
--- a/theme-format.txt
+++ b/theme-format.txt
@@ -114,8 +114,11 @@ Themes are in a simple XML-subset format.
x="10" y="30" width="width / 3" height="height / 4"/>
<!-- window's title -->
<title color="gtk:text[NORMAL]" x="20" y="30"/>
- <!-- include another draw ops list -->
+ <!-- include another draw ops list; has optional x/y/width/height attrs -->
<include name="some_other_draw_ops"/>
+ <!-- tile another draw ops list; has optional
+ x/y/width/height/tile_xoffset/tile_yoffset -->
+ <tile name="some_other_draw_ops" tile_width="10" tile_height="10"/>
</draw_ops>
<frame_style name="normal" geometry="normal">