设计 Metacity 主题
1.Metacity主题:
Metacity 主题是基于XML格式的,还有依赖于具体主题的一定数量的图片【通常是便携网络图形格式,PNG】。
2.如何创建主题:
要做的第一步是在下面的位置创建一个目录 -
$PREFIX/share/themes/[theme_name]/metacity-1/
$HOME/.themes/[theme_name]/metacity-1/
按照您的主题名字起名。尽管 Metacity 会检测在上面的任一个位置的主题。但是,当您编写和调试之时,置主题于您的家目录下不失为明智之举。
紧跟着的一步是编辑选定目录中的“metacity-theme-1.xml”文件。此文件包含主题的 XML 描述,该描述依循 DTD描述。当创建新 Metacity 主题时,不要完全从零开始,而是利用已有的主题,这非常有用的。
格式最开始的几行是这样的
<?xml version="1.0"?>
<metacity_theme>
<info>
<name>Atlanta</name>
<author>Havoc Pennington</author>
<copyright>Havoc Pennington, 2002</copyright>
<date>September 2, 2002</date>
<description>Atlanta- a simple theme using Gtk+ default theme</description>
</info>
<!-- 这里就是您要开始定义主题的地方 -->
</metacity_theme>
3.了解主题基础:
1)窗口
有六个 Metacity 认可的不同窗框风格
normal 普通的上层窗口
dialog 对话窗口
modal_dialog 模态(modal state)对话框窗口,比如,要干预之后用户方可与其父窗口交互的窗口
menu 可钉住的菜单窗口,如剥离菜单
utility 小的不变的(persistant)实用工具窗口,如 paletde 或工具箱
border 不显示任何装饰的窗口,如全屏化的窗口
2)风格
对于每一个窗口风格,都需要映射一个“框架风格集合”。每一个“风格设置”就是几个不同“框架状态”的合成物。您需要指定您的风格中每一个框架状态的外观。
框架状态是由下面这些要素决定:
窗口是否已获得焦点或者仍未获得
窗口是否已最大化或者隐藏【或两者】
窗口是否能够垂直地,水平地,垂直水平地调整大小
每一个“框架状态”被映射为一个“框架风格”。框架风格被分成两个不同的部分 ——框架“块” 和窗口“按钮”。
这个分类使构建 Metacity 主题更为容易。
3)框架块
如果您忽略任一个块,那么该块就是空的。Metacity 能够识别下面的挂框架块
entire_background 最先被描画的窗口的整个框架
titlebar 应用程序窗口之上的区域
titlebar_middle 不包括“边缘”块的标题条区域
left_titlebar_edge 标题条左侧区域
right_titlebar_edge 标题条右侧区域
top_titlebar_edge 标题条顶部区域
bottom_titlebar_edge 标题条底部区域
title 标题区域
left_edge 框架左方的边
right_edge 框架右方的边
bottom_edge 框架底部的边
overlay 同entire_background, 但它在最后才被描画
4)窗口按钮
Metacity 认可如下窗口按钮
close 关闭窗口按钮
maximize 最大化窗口按钮
minimize 最小化窗口按钮
menu 菜单按钮
以及下面的按钮位置
left_left_background 指定左边第一个按钮的背景
left_middle_background 指定左边第二个按钮的背景
left_right_background 指定左边第三按钮的背景
right_left_background 指定右边第一个按钮的背景
right_middle_background 指定右边第二个按钮的背景
right_right_background 指定右边第三个按钮的背景
5)Metacity 窗口按钮
对于每一个窗口按钮,都必需指定在给定的按钮状态号码下是如何显现的。
Metacity 认可下面的这些按钮状态
normal 对于给定的框架状态,正常的按钮如何出现
pressed 当点击时【使用鼠标】,按钮应该如何出现
prelight 当获得焦点时,按钮应该如何出现
6)窗口菜单
创建主题的最后一步是指定菜单图标。 他们显示下面这些窗口菜单中的项目 -
close 光标窗口图标
maximize 最大化窗口图标
minimize 最小化窗口图标
unmaximize 取消最大化窗口图标
以及下面这些与 GtkStateType 相对应的状态
normal 菜单中通常的菜单图标如何显示
prelight 菜单项目获得焦点时菜单图标如何显示
active 菜单项目激活时【如,选中】时菜单图标如何显示
selected 菜单项目被选时菜单图标如何显示
insensitive 菜单项目无效时【如,变灰】菜单图标如何显示
4.检测主题
创建Metacity主题时,使用特别为测试主题而设计的应用程序是可取的, Metacity 主题查看器。要使用这一程序, 只需简单的使您的主题作为参数(argument)来加载 。加载的主题将会得到分析,如果有错,它将通过命令行输出错误信息。修复错误直到主题被成功加载。
这个应用程序仅在设计窗口装饰风格时有用,因为它显示出来的窗口上的按钮和窗口菜单无法响应你的操作(鼠标点击或键盘事件)。
切换新主题,需要使用 gconftool-2 或用桌面菜单中的"桌面首选项" > "主题",然后选择“窗口边框主题”标签。如果使用 gconftool2-,则要采用如下的命令 -
gconftool-2 --type=string --set /apps/metacity/general/theme [theme_name]
5.Metacity 框架定义
1)框架的几何图
第一件事是需要创建“框架的几何图”,框架几何图的 name 属性,会在后面给定的“框架风格”中涉及到。
<frame_geometry name="my_frame_geometry">
<!-- 这里就是您要开始定义框架几何图的地方 -->
</frame_geometry>
给定几何图中几个可修改的宽度和高度
Frame geometry specifications
框架几何图规格说明,框架几何图拥有的一些可选属性
has_title 决定在高度计算中是否包含标题文本的高度。缺省值为真。
title_scale 使用 Pangomarkup - xx-small, x-small, small, medium, large, x-large and xx-large。缺省使用桌面字体。
rounded_top_left 定义是否窗口的左上角被圆角化(rounded)。缺省不使用。
rounded_top_right 定义是否窗口的右上角被圆角化(rounded)。缺省不使用。
rounded_bottom_left 定义是否窗口的左下角被圆角化(rounded)。缺省不使用。
rounded_bottom_right 定义是否窗口的右下角被圆角化(rounded)。缺省不使用。
<frame_geometry name="normal_geometry">
<distance name="left_width" value="6"/>
<distance name="right_width" value="6"/>
<distance name="bottom_height" value="7"/>
<distance name="left_titlebar_edge" value="6"/>
<distance name="right_titlebar_edge" value="6"/>
<distance name="button_width" value="17"/>
<distance name="button_height" value="17"/>
<distance name="title_vertical_pad" value="4"/>
<border name="title_border" left="3" right="12" top="4" bottom="3"/>
<border name="button_border" left="0" right="0" top="1" bottom="1"/>
</frame_geometry>
指定框架几何图时,可以使用继承。然后提供新的属性值来替代继承过来的任意值。
<frame_geometry name="borderless_geometry" rounded_top_left="true" rounded_top_right="true" parent="normal_geometry">
<distance name="left_width" value="0"/>
<distance name="right_width" value="0"/>
<distance name="bottom_height" value="0"/>
<distance name="left_titlebar_edge" value="0"/>
<distance name="right_titlebar_edge" value="0"/>
</frame_geometry>
按钮的宽度和高度,可以通过指定某一个比例来替代。
<aspect_ratio name="button" value="1.0"/>
2)描绘运算
“描绘运算”是设计 Metacity 主题的核心部分。为了能够成功描绘框架各部分,需要为“框架块”指定描绘运算。
<draw_ops name="my_drawing_operation">
<!-- 这里就是您要开始定义描绘运算的地方 -->
</draw_ops>
3)运算符
描绘运算通常是forward declared, 但也可放到一行中【参见后面的例子】。下面是在描绘运算中被允许的运算符列表 -
运算符 意 义 示 例
+ 加 2 + 3
- 减 5 - 4
* 乘 3 * 2
/ 除 10 / 2
% 模 34 % 3
`max` 最大值 4 `max` 5
`min` 最小值 7 `min` 3
() 括号 (5 * 3) + 5
应该注意的是常规的 precidence 规则对所有的运算符都有效。
4)常量
在描绘运算中,可以使用预定义变量或常量。常量需要声明且必须以一个大写字母开头。
<constant name="MyConstant" value="3"/>
下面列表是可以使用的预定义变量
width 目标区域的宽度
height 目标区域的高度
object_width 被描绘物的自然宽度
object_height 被描绘物的自然高度
left_width 从左边框架到客户窗口的距离
right_width 从右边框架到客户窗口的距离
top_height 从顶部框架到客户窗口的距离
bottom_height 从底部框架到客户窗口的距离
mini_icon_width 窗口最小图标的宽度
mini_icon_height 窗口最小图标的高度
icon_width 大图标的宽度
icon_height 大图标的高度
title_width 标题文本的宽度
title_height 标题文本的高度
5)运算
Metacity 支持下面的描绘“运算”
line
从起点 (x1, y1) 到终点(x2, y2)用颜色 color 描绘一线段。颜色可以是颜色名如“blue”,十六进制号码如“#FF0099”或者是来自GTK主题的“gtk:base[NORMAL]”形式的【参见后面的更多例子】。它获得附加的属性 width, dash_on_length 和dash_off_length, 它们缺省值都为“0”。
<line color="#00FF00" x1="3" y1="4" x2="0" y2="height" dash_off_length="2" dash_on_length="3"/>
rectangle
从起点 (x,y) 和给定的 width 和 height 描绘一个方形。其有一个可选属性 filled, 缺省值是“false”。
<rectangle color="blend/gtk:fg[NORMAL]/gtk:bg[NORMAL] x="0" y="0" width="width" height="height" filled="true"/>
arc
从起点(x,y)和给定的 width, height, start_angle 以及 extent_angle 描绘一段弧线。其有一个可选属性filled,缺省值是“false”。
<arc color="yellow" x="0" y="0" width="width-1" height="height-1" start_angle="30" extent_angle="180"/>
tint
从起点(x,y)和给定的 width, height,着色,color和alpha.
<tint color="orange" alpha="0.2" x="0" y="0" width="width - mini_icon_width" height="height"/>
gradient
描绘一个渐变从起点(x,y)和给定的width, height, type 【垂直、水平、对角】和一些 color 元素。
<gradient type="vertical" x="10" y="10" width="width - title_width" height="height / 4">
<color value="blue">
<color value="gtk:fg[SELECTED]>
<color value="blend/gtk:light[SELECTED]/gtk:dark[ACTIVE]">
</gradient>
image
映射一幅图像到元素从起点(x,y)和给定的 width, height and filename。它有可选自变量参数alpha 和 colorize, 缺省值是“0” 和无色彩。
<image filename="my_image.png" x="0" y="0" width="width" height="height" alpha="0.5" colorize="#FF3399"/>
gtk_arrow
描绘一个箭头,从起点(x,y)和给定的width, height, GTK state, shadow [无, 内, 外, etched_in 和 etched_out] 和 direction [上, 下, 左或右]。其有可选自变量 filled,缺省值是“false”。
<gtk_arrow state="normal" x="2" y="2" width="width - 4" height="height" shadow="in" arrow="up" filled="true"/>
gtk_box
描绘一个盒子,从起点(x,y)和给定的width, height, GTK state 和 shadow.
<gtk_box state="normal" x="2" y="2" width="width - 4" height="height" shadow="out"/>
gtk_vline
描绘一段垂直线段,从起点(x,y1) 到终点 (x,y2) 和 GTK state.
<gtk_vline state="normal" x="0" y1="0" y2="height"/>
icon
描绘窗口图标,从起点(x,y)和给定的width 和 height。其拥有可选自变量 alpha, 缺省值是“0”。
<icon x="10" y="30" width="width / 3" height="height / 3" alpha="0.3"/>
title
描绘窗口标题文本,从起点(x,y)和给定的color.
<title x="10" y="30" color="gtk:text[NORMAL]"/>
clip
裁剪给定的区域,从起点(x,y) 和给定的 width 和 height.
<clip x="5" y="2" width="width - 10" height="height - SpacerHeight"/>
include
包含其他描绘运算,使用给定的name。 其拥有可选的自变量(x,y), width 和 height, with defaults FIXME.
<include name="other_drawing_operations"/>
tile
覆盖(Tile)其他描绘运算表,使用给定的name, tile_width 和 tile_height。其拥有可选的自变量(x,y), width, height, tile_xoffset 和 tile_yoffset with defaults FIXME.
<tile name="other_drawing_operations" tile_width="10" tile_height="10"/>
6.创建框架风格:
创建“框架风格”时,要扎住(tie)各种不同的“框架块”和“窗口按钮”,形成一个特殊的“框架几何图”。我们通常需要为窗口状态normal, maximized, shaded, maximized_and_shaded 和依赖窗口捕获焦点与否来创建一个风格。
我们首先创建一个模板,他将包括描绘一个给定框架风格所必需的全部信息。
<frame_style name="my_frame_style" geometry="my_frame_geometry">
<!-- 这里就是您要开始定义框架风格的地方 -->
</frame_style>
在给定的框架风格中允许继承。所有的东西都可以重新指定以覆盖(override)父辈风格。
<frame_style name="my_child_frame_style" parent="my_frame_style" geometry="my_frame_geometry">
</frame_style>
1)框架块
为描绘框架的各组成部分,需要为每一个框架块提供描绘运算。如果忽略其中一个块,那么该框架部分将什么也不描绘。
<piece position="entire_background" draw_ops="my_drawing_operation"/>
如早先提到的,作为选择,您可以在一行中提供一个描绘运算
<piece position="left_edge">
<draw_ops>
<rectangle color="#FF0000" x0="0" y0="0" x1="width" y1="height" filled="true"/>
</draw_ops>
</piece>
下面的图例显示可以在一个给定的框架中定义风格的各种块
Non-title frame pieces
非标题框架块
Titlebar frame pieces
标题栏框架块
Title frame piece
标题框架块
2)窗口按钮
如前所述,您需要为给定的一个主题的窗口按钮指定最小化设置。 必须 为close, maximize, minimize 和 menu buttons提供描绘方法 ,该方法为他们定义了两种状态 - normal 和 pressed。 如果 prelight没有被定义,那么该状态将会使用normal。
<button function="close" state="normal" draw_ops="my_drawing_operation"/>
连同指定窗口按钮一起,您可以指定如何描绘窗口的各个组成部分,依赖于其在窗口框架中的不同位置。如果所有按钮拥有相同的背景,您就只需为left_middle_background 和 right_middle_background指定描绘运算。
<button function="left_middle_background" state="pressed" draw_ops="my_background_drawing_operation"/>
把所有这些信息在一起放置入单一的“框架风格”中,就如下面一样 -
<frame_style name="my_frame_style" geometry="my_frame_geometry">
<!-- We first display the title -->
<piece position="title" draw_ops="title_normal"/>
<!-- Let's give the edges some prettiness -->
<piece position="left_edge" draw_ops="draw_left_edge"/>
<piece position="right_edge" draw_ops="draw_right_edge"/>
<piece position="bottom_edge" draw_ops="draw_bottom_edge"/>
<!-- We need to specify the button positions now -->
<button function="left_middle_background" state="pressed" draw_ops="background_button"/>
<button function="right_middle_background" state="pressed" draw_ops="background_button"/>
<!-- We need to specify the buttons now -->
<button function="close" state="normal" draw_ops="close_button"/>
<button function="close" state="pressed" draw_ops="minimize_button"/>
<button function="minimize" state="normal" draw_ops="minimize_button"/>
<button function="minimize" state="pressed" draw_ops="minimize_button_pressed"/>
<button function="maximize" state="normal" draw_ops="maximize_button"/>
<button function="maximize" state="pressed" draw_ops="maximize_button_pressed"/>
<button function="menu" state="normal" draw_ops="menu_button"/>
<button function="menu" state="pressed" draw_ops="menu_button_pressed"/>
</frame_style>
3)菜单图标
在窗口菜单中要为Close, Maximize, UnMaximize 和 Minimize这些菜单项目指定图标。只为normal状态指定描绘运算就够了。您也可为其他状态随意指定它们的描绘运算,就如上面提及的一样。
<window_icon function="close" state="normal" draw_ops="menu_close_icon"/>
<window_icon function="maximize" state="normal" draw_ops="menu_maximize_icon"/>
<window_icon function="minimize" state="normal" draw_ops="menu_minimize_icon"/>
<window_icon function="unmaximize" state="normal" draw_ops="menu_unmaximize_icon"/>
4)框架风格集合
一旦我们有了自己的各式各样的框架风格,我们就要把他们映射到各式各样的窗口状态上去。我们通过创建“框架风格集合” 来实施的这一步骤。这里的 name 属性将在后面通过一个给定的“窗框风格”来引用。
<frame_style_set name="my_style_set">
<frame focus="yes" state="normal" resize="both" style="my_normal_focused_style"/>
<frame focus="no" state="normal" resize="both" style="my_normal_unfocused_style"/>
<frame focus="yes" state="maximized" style="my_maximized_focused_style"/>
<frame focus="no" state="maximized" style="my_maximized_unfocused_style"/>
<frame focus="yes" state="shaded" style="my_shaded_focused_style"/>
<frame focus="no" state="shaded" style="my_shaded_unfocused_style"/>
<frame focus="yes" state="maximized_and_shaded" style="my_maximized_shaded_focused_style"/>
<frame focus="no" state="maximized_and_shaded" style="my_maximized_shaded_unfocused_style"/>
</frame_style_set>
正如您以上所见,您必需为窗口的每种状态提供一个框架,通过窗口焦点yes和 no. 这个 style属性 references 'frame style'。 对任意一个框架您还必需提供一个resize 属性,通过一个normal 状态 'both'. 您可以为其他调整大小的属性none, horizontal and vertical随意指定框架。
5)窗口
最后必需提供的是映射“窗口风格”到给定的“框架风格集合”上。每一个窗口风格需要一个风格集合 normal, dialog, modal_dialog, menu, utility 和 border
<window type="normal" style_set="my_normal_style_set"/>
<window type="dialog" style_set="my_dialog_style_set"/>
<window type="modal_dialog" style_set="my_modal_dialog_style_set"/>
<window type="menu" style_set="my_menu_style_set"/>
<window type="utility" style_set="my_utility_style_set"/>
<window type="border" style_set="my_border_style_set"/> |