Studio 给你创建自定义 widgets 的能力,并将它们用作 Studio 工具和扩展。这些 widget 在 Studio 中行为为自定义窗口/面板,您可以将它们靠近界面或将它们作为独立窗口漂浮。
创建 widget 用户界面
所有工作室 widget 都以 DockWidgetPluginGui 个对象开始,可以用 GuiObjects 填充,例如文本标签和按钮。要创建一个空的 widget GUI,请调用 CreateDockWidgetPluginGui() 函数,传递一个 ID 和一个 DockWidgetPluginGuiInfo 对象。
注意 DockWidgetPluginGuiInfo.new() 建造者期望其参数在 特定顺序 中按以下顺序:
# | 属性 | 类型 | 描述 |
---|---|---|---|
1 | Enum.InitialDockState | 枚列 | 其中一个 Enum.InitialDockState 枚列。 |
2 | InitialEnabled | Boolean 值 | widget GUI的初始启用(可见)状态。 |
3 | InitialEnabledShouldOverrideRestore | Boolean 值 | 如果真实,那么 初始启用 的值将覆盖之前保存的启用状态。 |
4 | FloatingXSize | 整数 | 当 InitialDockState 设置为 Enum.InitialDockState.Float 时,图形用户界面的初始宽度。 |
5 | FloatingYSize | 整数 | 当 InitialDockState 设置为 Enum.InitialDockState.Float 时,图形用户界面的初始高度。 |
6 | MinWidth | 整数 | 最小 GUI 宽度,带有一些平台特有的变化。 |
7 | MinHeight | 整数 | 最低GUI高度,带有一些平台特有的变化。 |
-- 创建新的“DockWidgetPluginGuiInfo”对象local widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, -- widget将在漂浮面板中初始化true, -- widget 将初始化启用false, -- 不要覆盖以前启用的状态200, -- 漂浮窗口的默认宽度300, -- 浮动窗口的默认高度150, -- 悬浮窗口的最小宽度150 -- 悬浮窗口的最低高度)-- 创建新的 widget 图形用户界面local testWidget = plugin:CreateDockWidgetPluginGui("TestWidget", widgetInfo)testWidget.Title = "Test Widget" -- Optional widget title
自定义 widget 界面
一旦您创建了一控件 widget,您可以通过 GuiObjects 例如说明性 TextLabels 或互动 ImageButtons 来自定义其用户界面。例如,以下代码添加了基本的 TextButton 到 GUI 窗口:
-- 创建新的 widget 图形用户界面local testWidget = plugin:CreateDockWidgetPluginGui("TestWidget", widgetInfo)testWidget.Title = "Test Widget" -- 可选 widget 标题local testButton = Instance.new("TextButton")testButton.BorderSizePixel = 0testButton.TextSize = 20testButton.TextColor3 = Color3.new(1,0.2,0.4)testButton.AnchorPoint = Vector2.new(0.5,0.5)testButton.Size = UDim2.new(1,0,1,0)testButton.Position = UDim2.new(0.5,0,0.5,0)testButton.SizeConstraint = Enum.SizeConstraint.RelativeYYtestButton.Text = "Click Me"testButton.Parent = testWidget
更改工作室颜色主题
有效的工作室 widgets 理想地匹配 Studio 主题设置 ,并在主题更改时动态调整。例实例,如果开发者正在使用黑暗主题,那么 widge控件的背景颜色、图像和文本标签应与 Studio 的默认主题颜色一起看起来很漂亮。
以下代码添加使用了一个 syncGuiColors() 函数,该函数最初与同步的 GUI 对象表一起调用。在函数内,嵌套的 setColors() 函数循环通过对象并使用 GetColor() 与 Enum.StudioStyleGuideColor 枚数同步特定方面的它们。这个 setColors() 函数会立即运行以同步工作室主题,然后连接到 ThemeChanged 事件以检测未来主题变更。
testButton.Parent = testWidget
local function syncGuiColors(objects)
local function setColors()
for _, guiObject in objects do
-- 同步背景颜色
guiObject.BackgroundColor3 = settings().Studio.Theme:GetColor(Enum.StudioStyleGuideColor.MainBackground)
-- 同步文本颜色
guiObject.TextColor3 = settings().Studio.Theme:GetColor(Enum.StudioStyleGuideColor.MainText)
end
end
-- 运行“setColors()”函数以初始同步颜色
setColors()
-- 将“主题更改”事件连接到“setColors()”函数
settings().Studio.ThemeChanged:Connect(setColors)
end
-- 运行“syncGuiColors()”函数以同步提供的对象的颜色
syncGuiColors({testButton})
自定义鼠标指针
为了提高与 widget 元素的预期互动,您可以将系统特定 鼠标指针 设置为 GUI 事件,例如 MouseEnter 和 MouseLeave。以下代码展示了如何连接函数到 MouseEnter 和 MouseLeave 事件的 testButton 以更改鼠标指针:
local function setCursor(cursorAsset)
plugin:GetMouse().Icon = cursorAsset
end
testButton.MouseEnter:Connect(function()
setCursor("rbxasset://SystemCursors/PointingHand")
end)
testButton.MouseLeave:Connect(function()
setCursor("")
end)
参考下表列出鼠标指针和其潜在使用案例的列表:
鼠标滚动图标 | 资产 | 使用案例 |
---|---|---|
![]() | rbxasset://SystemCursors/Arrow | 默认单击和选择。 |
![]() | rbxasset://SystemCursors/PointingHand | 悬停在激活链接/按钮上。 |
![]() | rbxasset://SystemCursors/OpenHand | 悬停在可拖动物品目上。 |
![]() | rbxasset://SystemCursors/ClosedHand | 拖动一个项物品。 |
![]() | rbxasset://SystemCursors/IBeam | 在文本字段中悬停。 |
![]() | rbxasset://SystemCursors/SizeNS | 悬停在垂直缩放手柄上。 |
![]() | rbxasset://SystemCursors/SizeEW | 悬停在水平缩放手柄上。 |
![]() | rbxasset://SystemCursors/SizeNESW | 悬停在角落上的缩放手柄。 |
![]() | rbxasset://SystemCursors/SizeNWSE | 悬停在角落上的缩放手柄。 |
![]() | rbxasset://SystemCursors/SizeAll | 悬停在多向调整手柄上。 |
![]() | rbxasset://SystemCursors/SplitNS | 悬停在垂直"分割"手柄上。 |
![]() | rbxasset://SystemCursors/SplitEW | 悬停在水平“分割”手柄上。 |
![]() | rbxasset://SystemCursors/Forbidden | 悬停在锁定/禁用的物品上。 |
![]() | rbxasset://SystemCursors/Wait | 表示正在进行的行动。 |
![]() | rbxasset://SystemCursors/Busy | 表示系统正忙。 |
![]() | rbxasset://SystemCursors/Cross | 悬停在精确选择区域上。 |
收集用户输入
用户界面元素,例如 TextBox 和 TextButton 在 Studio widget 中正常工作,您可以像通常在 Roblox 上构建界面一样进行构建。然而,UserInputService 和 ContextActionService 不能工作,因为这些服务期望主游戏窗口处于焦点。
通用输入事件的一个解决方案是创建透明的 Frame 并将其覆盖在整个屏幕上。以下代码示例创建了一个框架,当用户单击框架时,GuiObject.InputBegan事件会在用户单击框架之前捕获框架上的键盘输入:
local frame = Instance.new("Frame")
frame.BackgroundTransparency = 1 -- 隐藏框架
frame.Size = UDim2.new(1, 0, 1, 0) -- 覆盖屏幕
frame.Position = UDim2.new(0, 0, 0, 0)
frame.Parent = testWidget
local function onInputBegan(inputObject)
-- 在这里处理输入对象,例如检测按键操作
end
frame.InputBegan:Connect(onInputBegan)
拖动和丢弃互动
使用拖放互动为您的 widget 提高数据流量是一种简单的方法。要创建这种互动,您必须定义要拖动的元素,启动拖动,创建一个掉落目标,并处理掉落动作动。
创建拖动源
当用户按下鼠标按钮在某些 UI 元素上时,您可以通过调用 Plugin:StartDrag() 启动拖动操作,通常在 widge控件 内的 TextButton 或 ImageButton 中。以下代码示例创建了一个带有文本按钮的单窗口 widget。
-- 首先创建 widgetlocal widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, true, true, 300, 200)local dragSourceWidget = plugin:CreateDockWidgetPluginGui("Drag Source", widgetInfo)dragSourceWidget.Title = "Drag Source"-- 创建一个启动拖动的文本按钮local dragButton = Instance.new("TextButton")dragButton.Size = UDim2.new(1, 0, 1, 0)dragButton.Text = "Drag me!"dragButton.Parent = dragSourceWidget
启动拖动
当用户单击 TextButton 时,您可以通过启动 MouseButton1Down() 事件来启动拖动,该事件会在用户按下鼠标按钮后立即发生。
在连接的函数中,确定要拖动的数据。数据的类型应反映在键中,拖动的内容应反映在键中,发送者的应在键中描述自己。请参阅Plugin:StartDrag()页面了解更多详情。
local function onButton1Down()
local dragInfo = {
Data = "Hello, world", -- 正在拖动的数据
MimeType = "text/plain", -- 描述数据的 MIME 类型
Sender = "SomeDragSource", -- 描述数据来自哪里
MouseIcon = "", -- 用于鼠标的图像内容
DragIcon = "", -- 在拖动时在鼠标下渲染图像内容
HotSpot = Vector2.zero -- 在拖动图标上中心化鼠标的位置
}
plugin:StartDrag(dragInfo)
end
dragButton.MouseButton1Down:Connect(onButton1Down)
创建掉落目标
当用户在拖动期间在窗口上释放鼠标时,事件 PluginGui.PluginDragDropped 发生。当发生这种情况时,您需要定义一个 掉落目标 例如第二个 widget 具有 TextLabel 检测掉落。
local dragTargetWidget = plugin:CreateDockWidgetPluginGui("Drop Target", widgetInfo)dragTargetWidget.Title = "Drop Target"-- 此文本标签将显示已丢弃的内容local textLabel = Instance.new("TextLabel")textLabel.Size = UDim2.new(1, 0, 1, 0)textLabel.Text = "Drop here..."textLabel.Parent = dragTargetWidget
处理掉落行动作
创建了一个掉落目标后,连接掉落目标 widget 上的 PluginGui.PluginDragDropped 事件:
local function onDragDrop(dragData)
print("PluginDragDropped")
if dragData.MimeType == "text/plain" then
textLabel.Text = dragData.Data
else
textLabel.Text = dragData.MimeType
end
end
dragTargetWidget.PluginDragDropped:Connect(onDragDrop)
当拖动仍在进行时,这三个事件在用户将鼠控件移动到一个 widget 上时发生:
- PluginDragEntered – 用户将鼠标悬停在窗口上时发射
- PluginDragMoved – 在用户移动鼠标到窗口上时反复发射,用于显示“在此处放置!”消信息。
- PluginDragLeft – 用户的鼠标离开窗口时发生火焰。这有助于隐藏“在此处放置”消信息。