编辑“界面

警告:您没有登录。如果您做出任意编辑,您的IP地址将会公开可见。如果您登录创建一个账户,您的编辑将归属于您的用户名,且将享受其他好处。

该编辑可以被撤销。 请检查下面的对比以核实您想要撤销的内容,然后发布下面的更改以完成撤销。

最后版本 您的文本
第1行: 第1行:
{{Version|timeless}}
{{Version|timeless}}{{需要翻译}}
CK3的用户界面(UI)是高度可修改的,但由于这个原因,UI修改器会禁用成就,因为玩家可能会用它们作弊。
CK3的用户界面(UI)是高度可修改的,但由于这个原因,UI修改器会禁用成就,因为玩家可能会用它们作弊。


第115行: 第115行:


 这可以帮助你更好地看到代码的结构,注意到任何缺失的或额外的括号,对于一些编辑器来说,这也是正确折叠代码块所需要的。
 这可以帮助你更好地看到代码的结构,注意到任何缺失的或额外的括号,对于一些编辑器来说,这也是正确折叠代码块所需要的。
=== 提升和功能 ===
每个窗口都有一个预定义的命令集合-提升和功能(promotes and functions) -可供使用。这些命令可以在使用 <code>DumpDataTypes</code> 控制台命令后,在 <code>Documents/Paradox Interactive/Crusader Kings III/logs/</code> 目录下的 <code>data_types.log</code> 文件中找到。
它们用于显示游戏中的所有数据,例如您的姓名、金币、子女,并且可以设置按钮操作。
一个“promote”返回一个作用域(scope),即一个游戏对象,如角色或省份,而一个 "function" 返回一个数字、一个字符串或一个布尔值(true/false)等等。
全局命令可以在任何地方使用,比如 <code>GetPlayer</code> (返回玩家角色)或 <code>GetCurrentDate</code> (获取当前日期)。
其他命令只能在它们所属的窗口/对象中使用,例如,GetParents 只能在角色窗口中使用,并且必须以 <code>CharacterWindow.GetParents</code> 开始。
命令可以像这样链接起来:
<code>CharacterWindow.GetCharacter.GetPrimaryTitle.GetHeir.GetPrimarySpouse.GetFather</code>
对象可以继承其父对象的范围,这意味着我们不需要重新键入上面的行来显示关于此角色的信息。相反,我们可以将小部件的数据上下文设置为此行,然后其中的每个文本框都将使用 <code>"[Character.GetNameNoTooltip]"</code> ,  <code>"[Character.GetGold]"</code> 等等。
同样的规定也适用于gridboxes的条目


=== UI组件 ===
=== UI组件 ===
第177行: 第157行:
* 在另一个hbox中的hbox将有0个大小,并且不会展开其子代。使用<code>layoutpolicy_horizontal = expanding</code>来调整它的大小(或者在vbox中使用<code>layoutpolicy_vertical = expanding</code>)。
* 在另一个hbox中的hbox将有0个大小,并且不会展开其子代。使用<code>layoutpolicy_horizontal = expanding</code>来调整它的大小(或者在vbox中使用<code>layoutpolicy_vertical = expanding</code>)。
* 接受数据模型(从游戏数据中创建列表)。
* 接受数据模型(从游戏数据中创建列表)。
<code>dynamicgridbox</code>
<code>dynamicgridbox</code>


* 仅用于数据模型。
* Is only used with datamodels.
* 将所有条目垂直排列。使用<code>flipdirection = yes</code> 可以使其水平排列。
* Arranges all the items vertically. Use <code>flipdirection = yes</code> to make it horizontal.
* 默认情况下不忽略不可见项目。使用 <code>ignoreinvisible = yes</code> 来进行更改。
* Doesn't ignore invisible items by default. Use <code>ignoreinvisible = yes</code> to change it.
* 根据内容的调整大小,并受到最小尺寸和最大尺寸的限制。
* Can be fixed size, resized by the content and limited by minimumsize and maximumsize.
* 条目可以有不同的尺寸。
* Items can be of different size.
* 有时候在处理非常长的列表时可能会出现卡顿的情况。
* Can become laggy with very long lists.


<code>fixedgridbox</code>
<code>fixedgridbox</code>


* 类似于动态框,但其所有项目都是固定尺寸的(本质上是一个表格)。
* Similar to a dynamic box but all its itmes are of fixed size (it's essentially a table).
* 仅用于数据模型。
* Is only used with datamodels.
* 将所有项目垂直排列。使用 <code>flipdirection = yes</code> 可以使其水平排列。
* Arranges all its items vertically. Use <code>flipdirection = yes</code> to make it horizontal.
* 无法忽视不可见的条目。
* Cannot ignore invisible items.
* 可以固定大小,根据内容进行调整,并受最小尺寸和最大尺寸的限制。
* Can be fixed size, resized by the content and limited by minimumsize and maximumsize.
* 处理长列表性能更好。
* Much better for performance with long lists.


<code>overlappingitembox</code>
<code>overlappingitembox</code>


* 仅用于数据模型。
* Is only used with datamodels.
* 将所有项目水平排列,并在列表长度超过盒子大小时重叠显示。使用 <code>flipdirection = yes</code> 使其水平排列。
* Arranges all its items horizontally and overlaps them if the list is longer that the size of the box. Use <code>flipdirection = yes</code> to make it horizontal.
* 可以是固定尺寸或自动调整大小。
* Can be fixed size or autoresized.


<code>scrollarea</code>
<code>scrollarea</code>


* 一个带有滚动条的小部件,如果内容超过其大小,滚动条将出现。
* A widget with scrollbars that appear if the content is bigger than its size.
* 滚动条可以通过 <code>scrollbarpolicy_horizontal = always_off</code> <code>scrollbarpolicy_vertical = always_off</code> 来禁用。
* Scrollbars can be disabled with <code>scrollbarpolicy_horizontal = always_off</code> and <code>scrollbarpolicy_vertical = always_off</code>.
** 可以使用没有滚动条的滚动区域来裁剪列表或图片。
** A scrollarea with no scrollbars can be used to crop lists or images.
* 可以固定大小,根据内容进行调整,并受最小尺寸和最大尺寸的限制。
* Can be fixed size, resized by the content and limited by minimumsize and maximumsize.


<code>button</code>
<code>button</code>


* 一个可点击的对象。 接受 <code>onclick</code> <code>onrightclick</code>.
* A clickable object. Accepts <code>onclick</code> and <code>onrightclick</code>.
** 在添加右键功能时,请包括 <code>button_ignore = none</code>.
** When adding a right click function, include <code>button_ignore = none</code>.
* 无默认材质
* Doesn't have a texture by default.
* 可以根据其子代进行固定大小或调整大小。
* Can be fixed size or resized by its children.
** 一个0x0按钮可以用来添加不可见的快捷键。
** A 0x0 button can be used to add invisible hotkeys.


<code>icon</code>
<code>icon</code>


* 显示一个材质
* Displays a texture.
* 可用作小部件来存储子代。
* Can be used as a widget to store children.
* 可以通过 <code>mirror = horizontal</code> <code>mirror = vertical</code> 进行翻转.
* Can be flipped with <code>mirror = horizontal</code> or <code>mirror = vertical</code>.


<code>textbox</code>
<code>textbox</code>


* 显示文字内容。
* Shows text.
* 可以是固定尺寸或自动调整大小。
* Can be fixed size or autoresized.
* 使用 <code>elide = right</code> <code>elide = left</code> 来截断过长的文本。
* Use <code>elide = right</code> or <code>elide = left</code> to cut off text that is too long
* 可以是单行或多行,当 <code>multiline = yes</code> 时为多行。
* Can be a single line or multiple, with <code>multiline = yes</code>.
* 游戏文件通常使用在gui/shared/text.gui 中设置的模板,比如 <code>text_single</code> 。使用它们可以保持视觉一致性,并减少每次编写代码的工作量。
* Game files often use templates set in gui/shared/text.gui, like <code>text_single</code>. Use them to keep visual consistency and to type less code every time.
 
==== hbox/vbox ====
 
Hboxes和vboxes是可调整大小的容器,它们对其子代进行排序、调整大小或展开。hbox水平排序子代,vbox垂直排序子代,除此之外它们的工作方式相同,所以这里的所有示例都适用于两者。
 
以下是屏幕截图,hboxes 带有黑色背景。所有示例都可以在 [https://steamcommunity.com/sharedfiles/filedetails/?id=2579010074 UI Library mod] 中找到。
 
{| class="wikitable"
|默认情况下,hbox 的工作方式类似于流容器(flowcontainer):它以水平方向排列子项,并调整大小以适应它们。
<pre>
hbox = {
   button_round = {}
   button_round = {}
}
</pre>
|[[File:simple_hbox_wide.jpg]]
|-
|使用 <code>layoutpolicy_horizontal = expanding</code> 时,它会扩展到其父级的宽度,并展开其子元素。
<pre>
hbox = {
   layoutpolicy_horizontal = expanding
   button_round = {}
   button_round = {}
}
</pre>
|[[File:Expanded_hbox.jpg]]
|-
|要将其子项分组,我们可以使用 <code>expand = {}</code> ,这是一个模板部件,其布局策略设置为"增长(growing)"(在gui/shared/windows.gui中定义)。
<pre>
hbox = {
   layoutpolicy_horizontal = expanding
   button_round = {}
   button_round = {}
   expand = {}
}
</pre>
|[[File:Ordered_hbox.jpg]]
|-
|"扩大(expanding)"策略涉及到子代的规模调整。


这对于创建标签页非常有用,无需手动设置它们的大小。
=== Promotes and Functions ===
<pre>
hbox = {
   layoutpolicy_horizontal = expanding
   button_standard = { layoutpolicy_horizontal = expanding }
   button_standard = { layoutpolicy_horizontal = expanding }
}
</pre>
|[[File:tabs hbox 2.jpg]]
|-
|随着水平和垂直方向的“扩展(expanding)”策略,hbox 及其子代将在两个方向上进行调整大小。
<pre>
hbox = {
   layoutpolicy_horizontal = expanding  layoutpolicy_vertical = expanding
   button_standard = {
     layoutpolicy_horizontal = expanding  layoutpolicy_vertical = expanding
   }
   button_standard = {
     layoutpolicy_horizontal = expanding  layoutpolicy_vertical = expanding
   }
}
</pre>
|[[File:big hbox.png]]
|}
如果放置在固定大小的父级容器中,默认情况下,它会水平和垂直方向上扩展到整个父级容器的大小。但如果放置在其他垂直盒子或水平盒子中,它们将不会扩展到父级容器的大小。


Each window has a predefined set of commands - promotes and functions - available for it. These can be found in the data_types.log file in <code>Documents/Paradox Interactive/Crusader Kings III/logs/</code> after you use the <code>DumpDataTypes</code> console command.


==== 布局策略 ====
They are used to display all data from the game, like your name, gold, children, and to set button actions.


布局策略控制着hboxes和vboxes中子元素的调整大小方式。这同样适用于嵌套boxes中的boxes。
A promote returns a scope, i.e a game object, like Character or Province, while a function returns a number, a string or a boolean (true/false) value, etc.


有两种类型,<code>layoutpolicy_horizontal</code> 和 <code>layoutpolicy_vertical</code> ,分别控制水平和垂直行为。
Global commands can be used anywhere, like GetPlayer (returns the player character) or GetCurrentDate.


默认情况下有五项固定的策略:
Other commands can only be used in their window/object, for example, GetParents can only be used in the character window and must be started with <code>CharacterWindow.GetParents</code>.


#'''fixed'''(固定的) - 组件保持原始大小,无法放大或缩小。设置"fixed"属性的hboxes/vboxes将根据子代的大小进行调整,就像一个容器。
Commands can be chained like this:
#'''expanding'''(扩展的) - 根据父代的宽度/高度自动调整大小,但不会缩小到原始尺寸以下。优先级高于其他策略的子代。如果多个子代设置为 "expanding" ,它们将平均分配可用空间。
#'''growing''' (增长的)- 与"expanding"相似,但优先级较低。如果存在带有"expanding"属性的子代,"growing"将不会发生。这还意味着 <code>expand = {}</code> 部件将调整大小为0,因此如果想要与"expanding"策略的组件一起使用,需要更改其策略。
#'''preferred''' (偏好的)- 随着可用空间的变化,它会随之放大或缩小。
#'''shrinking''' (缩水的)- 可以缩小至原始大小以下,但无法放大超过原始大小。


布局策略还会遵循最小尺寸 (minimumsize) 、最大尺寸 (maximumsize) 、最小宽度 (min_width)和最大宽度 (max_width) 。
<code>CharacterWindow.GetCharacter.GetPrimaryTitle.GetHeir.GetPrimarySpouse.GetFather</code>


{|class="wikitable"
Children can inherit the scope from their parent, meaning we wouldn't need to retype the line above to show information about this character. Instead we can set <code>datacontext</code> of a widget to this line and then every textbox in it will use <code>"[Character.GetNameNoTooltip]"</code>, <code>"[Character.GetGold]"</code>, etc.
| "Expanding" 优先于 "growing" ,但不会使其缩小到小于原始(固定)尺寸。
<pre>
hbox = {
max_width = 400
layoutpolicy_horizontal = expanding


button_standard_small = { layoutpolicy_horizontal = expanding }
The same applies to items in gridboxes.
button_standard_small = { layoutpolicy_horizontal = growing }
}
</pre>
|[[File:growing hbox 2.png]]
|-
| "preferred" 和 "shrinking" 在空间不足时都可以收缩。为了看到这种效果,可能需要通过 <code>max_width</code> 或 "shrinking" 策略来限制 hbox 的宽度。
<pre>
hbox = {
layoutpolicy_horizontal = shrinking


button_standard_small = { layoutpolicy_horizontal = growing }
=== Templates ===
button_standard_small = { layoutpolicy_horizontal = preferred }
button_standard_small = { layoutpolicy_horizontal = shrinking }
}
</pre>
|[[File:shrinking hbox 2.png]]
|}


请注意,具有较大尺寸的物块 (objects) 可能会拉伸 hbox/vbox,即使看起来适合。设置 <code>max_width</code> ,并测试所有文本字段是否能够容纳很长的字符串,以确保窗口不会改变。
Templates are named blocks of code which can be used multiple times throughout the code, which helps maintain the same style and reduce the amount of code we write. Editing the template will edit all instances of it!


=== 模板 ===
Templates are global and can be defined in any file. Most of the game templates are stored in gui/shared. A local version, local_template, has to be defined within the same file.


'''模板''' (Templates) 和类型是代码的命名代码块,可以在代码中多次使用,例如按钮、窗口背景和文本样式。这有助于保持相同的样式,并减少我们编写的代码量。编辑模板将同时编辑所有的实例!
Templates can store the contents of an entire window or just one line, like this one:


模板可以存储整个窗口的内容或仅存储一行,就像这个例子:
<pre>
<pre>
template Window_Size_Sidebar
template Window_Size_Sidebar
第353行: 第245行:
</pre>
</pre>


这个模板可以与"using = Window_Size_Sidebar" 一起使用,基本上会用模板的内容替换 "using" 行。
This template can be used inside another element with "using = Window_Size_Sidebar", which will, essentially, replace the "using" line with the contents of the template.
 
模板是全局的,可以在任何.gui文件中定义。大部分游戏模板存储在 <code>gui/shared</code> 目录下。本地版本 <code>local_template</code> 必须在同一文件中定义。
 
常用的模板和类型可以在UI库中找到。要访问它,打开控制台,切换到发布模式(Release mode),然后会出现一个名为 "UI Library" 的新按钮。


==== 类型 ====
==== Types ====


虽然模板可以只包含一个属性,但'''类型'''(Types)始终是完整的部件,比如按钮或小部件。
If templates can contain just a few properties, types are always whole elements, like a button or a widget.


<code>text_single</code> 和 <code>text_multi</code> 是具有许多预定义属性的文本框类型,因此我们不需要每次重新输入它们,只需简单地写:
text_single and text_multi are types of a textbox with many properties already defined for them, so we don't need to retype them every time and instead simply write:


<pre>
<pre>
第371行: 第259行:
</pre>
</pre>


类型的定义方式略有不同,首先要创建一个命名的组:
Types are defined in a slightly different way, by creating a named group of types first:


<pre>
<pre>
第382行: 第270行:
</pre>
</pre>


==== 块覆写 ====
==== Blockoverride ====


模板和类型可以具有命名的'''覆写块'''(blockoverride),这使我们能够在不更改整个模板的情况下编辑实例的一部分。例如,一个模板可以有一个默认的文本块:
Templates and types can have named override blocks, which allow us to edit a part of an instance without changing the whole template. For example, a template may have a default block of text:


<pre>
<pre>
第393行: 第281行:
</pre>
</pre>


为了覆盖其中的内容,我们可以在我们的实例中添加一个具有相同名称的覆盖代码块:
To replace it, we add a blockoverride with the same name in our instance:


<pre>
<pre>
第402行: 第290行:
</pre>
</pre>


我们也可以像这样从我们的实例中移除它:
We can also remove it from our instance like this:
<code>blockoverride "text" {}</code>
<code>blockoverride "text" {}</code>


==== 增加模组兼容性 ====
== Scripted GUIs ==
 
在制作一个涉及gui的mod时,所写的gui代码会与其他mod的代码覆盖同一个文件而无法同时运行。
 
模组开发者可以通过使用模板并为另一个模组创建一个“钩子(hook)”来实现兼容性。
 
为了做到这一点,每个模组开发者在已修改的窗口中包含其他模组的模板,而模板本身则在单独的文件中定义。
 
例如,全屏理发店模组包括了来自社区风味包(Community Flavor Pack)的“using = cfp_bg_buttons”模板,该模板添加了额外的背景。如果用户未订阅社区风味包,则无法找到该模板,也不会对游戏产生任何影响。如果用户同时订阅了这两个模组,则模板会被应用。
 
当然,这需要模组开发者合作,为彼此的模组设置模板。
 
== 脚本化的图形用户界面 ==


'''脚本化的GUI''' (Scripted guis) 实质上是从用户界面触发的隐藏事件。
Scripted guis are, essentially, hidden events triggered from the UI.


它们以 <code>.txt</code> 文件的形式存储在游戏 <code>/common/scripted_guis</code> 目录下,与 <code>.gui</code> 文件不同,无法直接从游戏中重新加载。
The are stored as .txt files in game/common/scripted_guis and cannot be reloaded from the game, unlike the .gui files.


脚本化GUI的基本结构如下:
The basic structure of a scripted gui is:


<pre>
<pre>
gui_name = { 
gui_name = { 
scope = character # 根作用域, 即:影响的目标
scope = character # the root scope, i.e. the target of the effects
saved_scopes = {} # 其他额外的目标
saved_scopes = {} # any additional targets


is_shown = {} # 在用户界面可见吗?
is_shown = {} # is it visible on the UI?


ai_is_valid = {} # AI 可用吗? 默认不可用.
ai_is_valid = {} # is the AI allowed to use it? Disabled by default.


is_valid = {} # 玩家可用吗?
is_valid = {} # can the player use it?


effect = { # 它做什么
effect = { # what it does
custom_tooltip = "" # 添加提示
custom_tooltip = "" # adds a tooltip
}
}
}
}
</pre>
</pre>
  
  
不是所有代码块都是必须的。 有时一个脚本gui文件中可能只有一个作用域 (scope) 、一个是否显示 (is_shown) 、一个效果 (effect) 。
Not all of the blocks are necessary. Sometimes a scripted gui may only contain the scope and is_shown or effect.


在 <code>.gui</code> 文件中我们用如下的代码:
In the .gui file we use the following:


<pre>
<pre>
第458行: 第334行:
</pre>
</pre>


没有''' 数据内容''' (datacontext) 是无法将脚本GUI与元素联系起来的。
datacontext is necessary to link the element to the scripted gui. Other commands won't work without it.


在这个例子中,脚本GUI 是通过全局函数 <code>GetPlayer.MakeScope</code> 来为玩家设定范围的。它可以更改为角色窗口中的某个人,例如 <code>CharacterWindow.GetCharacter.MakeScope</code> ,或者如果范围是一个省份,则使用 <code>HoldingView.GetProvince.MakeScope</code>
In this example the scripted gui is scoped to the player with a global function <code>GetPlayer.MakeScope</code>. It can be changed to someone in the character window, e.g. <code>CharacterWindow.GetCharacter.MakeScope</code>, or if the scope was a province, <code>HoldingView.GetProvince.MakeScope</code>.


'''ScriptedGui.Execute''' 用于按钮,它将执行脚本界面中 <code>effect</code> 块中列出的所有内容。
ScriptedGui.Execute is used with buttons and will execute everything listed in the <code>effect</code> block in the scripted gui.


is_shown is_valid 块中,'''IsShown''' 和 '''IsValid''' 用于检查条件。
IsShown and IsValid check for conditions in is_shown and is_valid blocks.


'''BuildTooltip''' 可以与文本框一起使用,在用户界面中显示自定义文本。
BuildTooltip can also be used with a textbox to display custom text in the UI.


为了将另一个作用域保存到我们的脚本化图形用户界面中,我们使用 '''AddScope''' :
To save another scope to our scripted gui, we use AddScope like this:


<pre>
  "[ScriptedGui.Execute( GuiScope.SetRoot( GetPlayer.MakeScope ).AddScope('target', CharacterWindow.GetCharacter.MakeScope ).End )]"
  "[ScriptedGui.Execute( GuiScope.SetRoot( GetPlayer.MakeScope ).AddScope('target', CharacterWindow.GetCharacter.MakeScope ).End )]"
</pre>


然后我们在脚本化GUI中使用相同的名称:
And then we use the same name in the scripted gui:


<pre>
  saved_scope = {
  saved_scope = {
   target
   target
  }
  }
</pre>


通过这种方式可以保存多个作用域。
Multiple scopes can be saved this way.


在点号或左括号之前不要加空格!<code>Execute(</code> 是正确的写法,<code>Execute (</code> 是错误的写法。其他空格可以省略,但它们有助于提高可读性。
It is important to not put any spaces before the dots or opening parentheses! <code>Execute(</code> is correct, <code>Execute (</code> is not. Other spaces can be omitted, but they help with readability.


=== 显示变量或脚本值 ===
=== Displaying a variable or script value ===


变量或脚本值可以在用户界面显示,就像这样:
Variables and script values can be shown on the UI like this:


变量:
variable:


<code>
<code>
第496行: 第368行:
</code>
</code>


脚本值:
svalue:


<code>
<code>
第502行: 第374行:
</code>
</code>


在这个例子中,变量存储在玩家角色中,名为 <code>test_var</code> 。可以触及任何其他作用域,只需记得添加  <code>MakeScope</code> 即可。
In this example the variable is stored in the player character and is called <code>test_var</code>. Any other scope can be used, just remember to add <code>MakeScope</code>.
 
|1 at the end is optional and will cut off all decimals save for one, so instead of 1.573 you will see 1.5. Note that it does not round the value. You can set this at any number, add % to convert to a percentage, add = or + to color the value if it's positive or negative.
 
When using localization to display values in events, we use this:


结尾的 "|1" 是可选的,它会截取所有小数位,只保留一个小数位,所以不论是 1.573 还是 1.5,您都将看到 1.5。请注意,这不会对数值进行四舍五入。您可以将其设置为任意数字,并添加 % 以将其转换为百分比,如果数值为正或负,还可以添加 = 或 + 以给数值上色。
<code>event_var: "[ROOT.GetCharacter.MakeScope.Var('test_var').GetValue|0]"</code>


在事件中使用本地化显示值时,我们使用以下方法:
<code>event_value: "[SCOPE.ScriptValue('test_value')|0]"</code>


<pre>
If you have a saved scope (named "target" here), it changes to this:
  event_var: "[ROOT.GetCharacter.MakeScope.Var('test_var').GetValue|0]"
 
  event_value: "[SCOPE.ScriptValue('test_value')|0]"
</pre>


如果你有一个保存的作用域(这里命名为"target" ),它会变成这样:
<code>event_var: "[target.MakeScope.Var('test_var').GetValue|0]"</code>


<pre>
<code>event_value: "[GuiScope.SetRoot( target.MakeScope ).ScriptValue('test_value')|0]"</code>
  event_var: "[target.MakeScope.Var('test_var').GetValue|0]"


  event_value: "[GuiScope.SetRoot( target.MakeScope ).ScriptValue('test_value')|0]"
=== Displaying data lists ===
</pre>


=== 展示数据列表 ===
We can create custom lists of characters, for example, to make societies.
我们可以创建自定义字符列表,例如用于构建社交网络(societies)。


要实现这一点,首先需要将它们添加到一个变量列表(list)中。可以通过事件或脚本GUI来完成,就像这样:
To do this, first, we need to add them to a variable list. This can be done though an event or a scripted gui, like this:


<pre>
<pre>
第544行: 第413行:
</pre>
</pre>


如果我们将此效果应用于玩家,他们将成为<code>root</code> ,因此列表将存储在他们身上。
If we fire this effect for the player, they will be the <code>root</code>, so the list will be stored in them.
 
Then we use any list box (vbox, dynamicgridbox, fixedgridbox) with the datamodel set to our list:


然后,我们使用任何列表框(vbox、dynamicgridbox、fixedgridbox),将数据模型设置为我们的列表:
<pre>
<pre>
dynamicgridbox = {
dynamicgridbox = {
第565行: 第435行:
</pre>
</pre>


== 新窗口和开关 ==
== New windows and toggles ==
没有简单的方法来创建一个新窗口并使您的模组与其他模组兼容。我们必须要么覆盖hud或其他窗口,要么使用事件来打开窗口。
 
通常的方法是将新窗口添加到<code>ingame_topbar</code>部件的hud.gui文件中,然后添加一个按钮来显示/隐藏它。


另一种方法是重写一个未使用的窗口,比如test_gui,并添加一个带有显示该窗口的控制台命令的按钮。
There isn't a simple way to create a new window and make your mod compatible with others. We have to either overwrite the hud or other windows.


有几种方法可以添加切换功能,以下三种方法在游戏会话之间不保持持久性,但可以在.gui 文件本身中轻松设置:
The usual way is to add the new window to hud.gui inside of ingame_topbar widget and then add a button to show/hide it.


*[[界面#P社GUI组件的开关|P社GUI组件]](PdxGuiWidget) - 直接简单,但在有多个切换功能时会变得复杂
The alternative is to rewrite one of the unused windows, like test_gui and add a button with the console command that shows it.
*[[界面#动画开关|动画]](Animations) - 长一些,但更容易触发多个操作
*[[界面#系统变量|系统变量]](System variables) - 有些复杂,但非常灵活和方便


脚本GUI允许我们将切换功能保存到保存文件中作为变量,并触发多个操作,但它们更复杂,并且必须在单独的文件夹中进行设置。
=== Toggles with PdxGuiWidget ===
=== P社GUI组件的开关 ===


'''PdxGuiWidget''' 是一个简单的功能,用于隐藏或显示指定的元素。
PdxGuiWidget is a simple function used to hide or reveal named elements.


在这个示例中,我们有一个包含隐藏子菜单的容器,一个按钮用于显示子菜单,另一个按钮用于隐藏子菜单。
In this example we have a container with a hidden submenu, one button that shows it and another that hides it.
# 当点击第一个按钮时,它会返回到其父代,在父代中搜索子菜单和另一个按钮,然后显示它们并隐藏自身。
# when clicked, the first button goes back to its parent, searches in it for the submenu and the other button, reveals them and hides itself
# 第二个按钮会搜索元素和按钮,并显示它们并隐藏自身。
# the second button searches for the element and the button, reveals them and hides itself


<pre>
<pre>
第613行: 第477行:
</pre>
</pre>


  如果元素之间有更多的父/子级别分隔,我们可以像这样重复使用 '''AccessParent''' :
If the elements are separated by more parents/children, we can repeat AccessParent like this:
  onclick = "[PdxGuiWidget.AccessParent.AccessParent.AccessParent.AccessParent.FindChild('submnenu').Show]"


<pre>
Each button can hide or reveal multiple elements of any type. You only need to provide the name.
onclick = "[PdxGuiWidget.AccessParent.AccessParent.AccessParent.AccessParent.FindChild('submnenu').Show]"
</pre>


每个按钮都可以隐藏或显示多个任意类型的元素。您只需要提供名称。
Pros:
* easy to edit on the fly as any changes can be reloaded with the "reload gui" command


优点:
Cons:
* 对于简单的切换设置很容易。
* the toggles will reset any time the game is restarted
* If you want to hide multiple things or toggles, the code will get very bloated and hard to manage
* trying to hide entries in a data list (like a dynamicgridbox) will only hide the first instance


缺点:
=== Toggles with animation ===
*切换将在每次重新启动游戏时重置。
*如果您想要隐藏多个事物或切换,代码会变得非常冗长和难以管理。
*尝试隐藏数据列表中的条目(如动态网格框)将只隐藏第一个实例。


=== 动画开关 ===
We can set up animations that are triggered by buttons (or conditions) to hide/show elements or to even move them. This way we don't need to count how many parents separate the button and the window and we can trigger many things at once with just one onclick.


我们可以设置通过按钮(或条件)触发的动画来隐藏/显示元素,甚至移动它们。这样一来,我们就不需要计算按钮和窗口之间有多少个父级,而且可以通过一个 <code>onclick</code> 同时触发多个动作。
The previous example would look like this and work the same way. The first button triggers "show_submenu", which hides the button and shows the rest, while the second button triggers "hide_submenu", which hides this button and the widget and shows the first button.


前面的示例将如下所示,并且以相同的方式工作。第一个按钮触发 "show_submenu",隐藏该按钮并显示其他内容,而第二个按钮触发 "hide_submenu",隐藏此按钮和小部件,并显示第一个按钮。
<pre>
<pre>
container = {
container = {
第680行: 第542行:
</pre>
</pre>


虽然较长,但动画可以保存为模板并以一行代码的方式重复使用,就像 <code>using = hide_animation</code> 。全屏理发器使用很多动画,如果你需要更好的例子。
it is longer, but animations can be saved as templates and reused with one line, like <code>using = hide_animation</code>. Fullscreen Barbershop uses animations extensively, if you want a better example.


优点:
Pros:
* 更容易将许多事物链接在一起,甚至打开一个不同的窗口并触发其中的动画
* can also be edited on the fly, with "reload gui" command
* easier to link many things together, and even open a different window and trigger an animation in it


缺点:
Cons:
* 动画块可能相当冗长
* animation blocks can be quite lengthy
* 当游戏重新启动时,所有开关都会重置
* all toggles will reset when the game is restarted


=== 脚本GUI开关 ===
=== Toggles with Scripted GUIs ===


脚本化的GUI允许我们使用脚本来切换可见性。它们使得管理多个项目更加容易,但在大量使用时可能会影响性能。
Scripted guis allows us to use script to toggle visibility. They make it easier to manage multiple things but can impact performance when used in big numbers.


对于一个脚本化的切换,我们需要在common/scripted_guis/ 目录下创建一个.txt文件。文件的名称可以任意取。
For a scripted toggle we need to create a .txt file in common/scripted_guis/. The name of the file can be anything.


这个文件中的基本切换看起来像这样:
A basic toggle in this file would looks like this:


<pre>
<pre>
第719行: 第582行:
</pre>
</pre>


单击时,它会向作用域角色添加一个变量,并在再次单击时将其删除。
When clicked, it adds a variable to the scoped character and removes it when clicked again.


然后,如果该变量存在,我们的窗口将可见。如果不存在,则隐藏。
Then, if the variable is present, our window will be visible. If it's not, it's hidden.


这就是 GUI 文件的外观。我们可以只使用一个按钮,因为其功能会随着每次点击而改变。
This is how the gui file would look like. We can use just one button as its function will change with each click.


<pre>
<pre>
第739行: 第602行:
</pre>
</pre>


<code>"GetPlayer"</code> 是一个全局[[界面#提升和功能|Promote]]函数,返回玩家角色。
"GetPlayer" is a global promote and returns the player character.
 
"Player.MakeScope" makes our player the scope of the scripted gui, meaning this is where we store the variable in.


<code>"Player.MakeScope"</code> 将我们的玩家设定为脚本化图形界面的作用域,这意味着我们将变量存储在这里。
Two buttons can be used if you want different tooltips for them. In this case, copy the 'visible' property to both buttons, but add 'Not' to one of them, so it's hidden by default:
visible = "[Not(ScriptedGui.IsShown( GuiScope.SetRoot( GetPlayer.MakeScope ).End ))]"


如果你想要为两个按钮设置不同的工具提示,可以使用两个按钮。在这种情况下,将 <code>'visible'</code> 属性复制到两个按钮上,但是在其中一个上添加 <code>'Not'</code> ,这样它就会默认隐藏起来。
Pros:
* the toggles are saved in the character and won't reset unless they die or you start a new game
* easier to link many things, even in different windows


<pre>
The downsides:
visible = "[Not(ScriptedGui.IsShown( GuiScope.SetRoot( GetPlayer.MakeScope ).End ))]"
* you need to restart the game to update scripted guis
</pre>
* it's a little harder to remember the syntax (copy the code from here to reduce the chance of mistakes)


优点:
=== System Variables ===
*切换设置会保存在角色中,除非角色死亡或开始新游戏,否则不会重置。
*更容易链接多个对象,甚至在不同的窗口中。


缺点:
System variables are used internally by the game, they are not save persistent and cannot be directly accessed through scripts.
*更难记住语法(从这里复制代码以减少错误的机会)。


=== 系统变量 ===
No setup is needed for them as they can be directly created in the .gui file.


系统变量是游戏内部使用的,它们不会被保存,也不能通过脚本直接访问。
The syntax for using system variables is:
对于它们不需要进行设置,因为可以直接在.gui文件中创建。
使用系统变量的语法为:


<code>onclick = "[GetVariableSystem.Toggle( 'var_name' )]"</code>
<code>onclick = "[GetVariableSystem.Toggle( 'var_name' )]"</code>


或者:
or:


<pre>datacontext = "[GetVariableSystem]"
<pre>datacontext = "[GetVariableSystem]"
onclick = "[VariableSystem.Toggle( 'var_name' )]"</pre>
onclick = "[VariableSystem.Toggle( 'var_name' )]"</pre>


可用的函数如下:
The available functions are:
*Clear - <code>Clear( 'var_name' )</code> 清除变量
* Clear - <code>Clear( 'var_name' )</code> clears the variable
*ClearIf - <code>ClearIf( 'var_name', Condition )</code> 如果条件为真,则清除变量
* ClearIf - <code>ClearIf( 'var_name', Condition )</code> clears the variable if Condition is true
*Exists - <code>Exists( 'var_name' )</code> 布尔型,如果变量存在则返回true
* Exists - <code>Exists( 'var_name' )</code> Boolean, returns true if the variable exists
*Get - <code>Get( 'var_name' )</code> 字符串型,返回存储在变量中的值
* Get - <code>Get( 'var_name' )</code> CString, returns the value stored in the variable
*HasValue - <code>HasValue( 'var_name', 'string' )</code> 布尔型,如果存储的值与提供的值匹配则返回true
* HasValue - <code>HasValue( 'var_name', 'string' )</code> Boolean, returns true if the stored value matches the provided value
*Set - <code>Set( 'var_name', 'string' )</code> 将存储的值设置为提供的值
* Set - <code>Set( 'var_name', 'string' )</code> sets the stored value to the provided value
*Toggle - <code>Toggle( 'var_name' )</code> 如果变量存在则清除它,如果不存在则创建它
* Toggle - <code>Toggle( 'var_name' )</code> clears the variable if it exists, creates it if it does not
 
==== Toggles with System Variables ====


==== 系统变量开关 ====
A basic toggle using system variables in this file would looks like this:


一个使用此文件中的系统变量的基本切换如下所示:
<pre>
<pre>
container = {
container = {
第793行: 第657行:
</pre>
</pre>


点击时,系统变量根据其存在与否切换,然后用于显示/ 隐藏部件。
When clicked, the system variable is toggled depending on whether it exists, this is then used to show/hide the widget.


==== 带有系统变量的选项 ====
==== Tabs with System Variables ====


一个包含三个选项的基本设置如下:
A basic setup for three tabs would look like this:


<pre>
<pre>
第823行: 第687行:
</pre>
</pre>


注意,变量最初没有值,因此没有任何小部件会显示。
Note that the variable initially has no value and none of the widgets would show.


要设置默认选项卡,需要由打开窗口的按钮设置变量的值。
To set a default tab the variable needs to be set by the button opening the window:


<pre>
<pre>
第834行: 第698行:
</pre>
</pre>


或在窗口显示时使用状态块:
or using a state block when the window is shown:


<pre>
<pre>
第843行: 第707行:
</pre>
</pre>


或者,可以将其中一个小部件设置为在变量不存在时显示,避免初始值的需求。
Alternatively one of the widgets can be set to appear when the variable doesn't exist, avoiding the need for an initial value:


<pre>
<pre>
第869行: 第733行:
</pre>
</pre>


这相当于第一个示例,其中之一是设置默认值的方法。
This is the equivalent of the first example with one of the methods to set a default value.


优点:
Pros:
* 简单且易于记忆的语法
* simple and easy to remember syntax
* 更容易连接许多事物,甚至在不同的窗口中
* easier to link many things, even in different windows
* 可以通过附加命令进行扩展(见下文)以显示全新的窗口,避免在hud.gui 中使用小部件的需要
* can be extended with additional commands (see below) to show entirely new windows, avoiding the need to have the widget in hud.gui


缺点:
The downsides:
* 无法直接与脚本交互,必须使用GUI进行设置和清除
* no direct interaction with scripts, they must be set & cleared using the gui
* 可能更难跟踪
* can be harder to keep track of
* 游戏重新启动时,所有切换将重置
* all toggles will reset when the game is restarted


=== 添加新的UI元素 ===
=== 添加新的UI元素 ===
请注意您对十字军之王3百科的所有贡献都被认为是在知识共享署名-非商业性使用-相同方式共享下发布,请查看在十字军之王3百科:版权的细节。如果您不希望您的文字被任意修改和再散布,请不要提交。
您同时也要向我们保证您所提交的内容是您自己所作,或得自一个不受版权保护或相似自由的来源。 未经许可,请勿提交受版权保护的作品!

为防止机器编辑,请完成下方验证

取消 编辑帮助(在新窗口中打开)