O Estúdio oferece a você o poder de criar widgets personalizados e usá-los como ferramentas e extensões. Esses widgets se comportam como janelas/painéis personalizados no Estúdio, e você pode fixá-los dentro da sua interface ou deixá-los flutuar como janelas separadas.
Criar UIs de widget
Todos os widgets do Estúdio começam como objetos DockWidgetPluginGui, que você pode preencher com GuiObjects, como rótulos de texto e botões. Para criar uma GUI de widget vazia, chame a função CreateDockWidgetPluginGui(), passando um ID e um objeto DockWidgetPluginGuiInfo.
Observe que o construtor DockWidgetPluginGuiInfo.new() espera seus parâmetros em uma ordem específica, conforme segue:
| # | Propriedade | Tipo | Descrição |
|---|---|---|---|
| 1 | Enum.InitialDockState | Enum | Um dos enums Enum.InitialDockState. |
| 2 | InitialEnabled | Booleano | O estado inicial habilitado (visível) da GUI do widget. |
| 3 | InitialEnabledShouldOverrideRestore | Booleano | Se verdadeiro, o valor de InitialEnabled substitui o estado habilitado salvo anteriormente. |
| 4 | FloatingXSize | Inteiro | A largura inicial da GUI quando InitialDockState está definido como Enum.InitialDockState.Float. |
| 5 | FloatingYSize | Inteiro | A altura inicial da GUI quando InitialDockState está definido como Enum.InitialDockState.Float. |
| 6 | MinWidth | Inteiro | A largura mínima da GUI, com algumas variações específicas da plataforma. |
| 7 | MinHeight | Inteiro | A altura mínima da GUI, com algumas variações específicas da plataforma. |
-- Criar novo objeto "DockWidgetPluginGuiInfo"local widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, -- O widget será inicializado em um painel flutuantetrue, -- O widget será inicialmente habilitadofalse, -- Não sobrescrever o estado habilitado anterior200, -- Largura padrão da janela flutuante300, -- Altura padrão da janela flutuante150, -- Largura mínima da janela flutuante150 -- Altura mínima da janela flutuante)-- Criar nova GUI de widgetlocal testWidget = plugin:CreateDockWidgetPluginGui("TestWidget", widgetInfo)testWidget.Title = "Widget de Teste" -- Título opcional do widget
Personalizar a UI do widget
Depois de criar um widget, você pode personalizar sua interface com GuiObjects, como TextLabels informativos ou ImageButtons interativos. Por exemplo, o código a seguir adiciona um TextButton básico à janela GUI:
-- Criar nova GUI de widgetlocal testWidget = plugin:CreateDockWidgetPluginGui("TestWidget", widgetInfo)testWidget.Title = "Widget de Teste" -- Título opcional do widgetlocal 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 = "Clique em Mim"testButton.Parent = testWidget
Alterar temas de cores do Estúdio
Widgets eficazes do Estúdio, idealmente, correspondem à configuração do tema do Estúdio e se ajustam dinamicamente quando o tema muda. Por exemplo, se um desenvolvedor estiver usando o tema escuro, a cor de fundo do widget, imagens e rótulos de texto devem ficar bonitos ao lado das cores nativas do tema do Estúdio.
A seguinte adição de código usa uma função syncGuiColors() que é chamada inicialmente junto com uma tabela de objetos de GUI para sincronizar. Dentro da função, uma função aninhada setColors() percorre os objetos e sincroniza aspectos específicos deles usando GetColor() com enums Enum.StudioStyleGuideColor. Esta função setColors() é executada imediatamente para sincronizar o tema do Estúdio, e em seguida, é conectada ao evento ThemeChanged para detectar futuras mudanças de tema.
testButton.Parent = testWidget
local function syncGuiColors(objects)
local function setColors()
for _, guiObject in objects do
-- Sincronizar a cor de fundo
guiObject.BackgroundColor3 = settings().Studio.Theme:GetColor(Enum.StudioStyleGuideColor.MainBackground)
-- Sincronizar a cor do texto
guiObject.TextColor3 = settings().Studio.Theme:GetColor(Enum.StudioStyleGuideColor.MainText)
end
end
-- Executar a função 'setColors()' para sincronizar cores inicialmente
setColors()
-- Conectar o evento 'ThemeChanged' à função 'setColors()'
settings().Studio.ThemeChanged:Connect(setColors)
end
-- Executar a função 'syncGuiColors()' para sincronizar as cores dos objetos fornecidos
syncGuiColors({testButton})
Personalizar os cursores do mouse
Para melhorar a interação esperada com os elementos do widget, você pode definir cursores do mouse específicos do sistema para eventos de GUI, como MouseEnter e MouseLeave. O código a seguir demonstra como conectar uma função aos eventos MouseEnter e MouseLeave do testButton para alterar o cursor do mouse:
local function setCursor(cursorAsset)
plugin:GetMouse().Icon = cursorAsset
end
testButton.MouseEnter:Connect(function()
setCursor("rbxasset://SystemCursors/PointingHand")
end)
testButton.MouseLeave:Connect(function()
setCursor("")
end)
Consulte a tabela a seguir para uma lista de cursores do mouse e seus possíveis casos de uso:
| Ícone do Cursor do Mouse | Asset | Caso de Uso |
|---|---|---|
| rbxasset://SystemCursors/Arrow | Clique e seleção padrão. | |
| rbxasset://SystemCursors/PointingHand | Pairando sobre um link/botão ativo. | |
| rbxasset://SystemCursors/OpenHand | Pairando sobre um item arrastável. | |
| rbxasset://SystemCursors/ClosedHand | Arrastando um item. | |
| rbxasset://SystemCursors/IBeam | Pairando em um campo de texto. | |
| rbxasset://SystemCursors/SizeNS | Pairando sobre um manipulador de redimensionamento vertical. | |
| rbxasset://SystemCursors/SizeEW | Pairando sobre um manipulador de redimensionamento horizontal. | |
| rbxasset://SystemCursors/SizeNESW | Pairando sobre um manipulador de redimensionamento de canto. | |
| rbxasset://SystemCursors/SizeNWSE | Pairando sobre um manipulador de redimensionamento de canto. | |
| rbxasset://SystemCursors/SizeAll | Pairando sobre um manipulador de redimensionamento multidirecional. | |
| rbxasset://SystemCursors/SplitNS | Pairando sobre um manipulador "divisão" vertical. | |
| rbxasset://SystemCursors/SplitEW | Pairando sobre um manipulador "divisão" horizontal. | |
| rbxasset://SystemCursors/Forbidden | Pairando sobre um item bloqueado/proibido. | |
| rbxasset://SystemCursors/Wait | Indicando que uma ação está em progresso. | |
| rbxasset://SystemCursors/Busy | Indicando que o sistema está ocupado. | |
| rbxasset://SystemCursors/Cross | Pairando sobre uma área de seleção precisa. |
Coletar entrada do usuário
Elementos da UI, como TextBox e TextButton, funcionam normalmente em widgets do Estúdio, e você pode construir interfaces como normalmente faria no Roblox. No entanto, UserInputService não funciona, pois esses serviços esperam que a janela principal da experiência esteja em foco.
Uma solução alternativa para eventos de entrada genéricos é criar um Frame transparente e sobrepor ele em toda a tela. O seguinte exemplo de código cria um quadro, e quando o usuário clica no quadro, o evento GuiObject.InputBegan captura a entrada do teclado no quadro até que o usuário clique fora:
local frame = Instance.new("Frame")
frame.BackgroundTransparency = 1 -- Ocultar o quadro
frame.Size = UDim2.new(1, 0, 1, 0) -- Cobrir a tela
frame.Position = UDim2.new(0, 0, 0, 0)
frame.Parent = testWidget
local function onInputBegan(inputObject)
-- Processar o objeto de entrada aqui, por exemplo detectar pressionamentos de tecla
end
frame.InputBegan:Connect(onInputBegan)
Interação de arrastar e soltar
Usar interações de arrastar e soltar para seus widgets é uma maneira simples de melhorar o fluxo de dados. Para criar essa interação, você deve definir o elemento a ser arrastado, iniciar o arrasto, criar um alvo de soltura e processar a ação de soltura.
Criar fonte de arrasto
Você pode iniciar uma ação de arrastar chamando Plugin:StartDrag() quando o usuário pressiona um botão do mouse em algum elemento de UI, tipicamente um TextButton ou ImageButton dentro de um widget. O seguinte exemplo de código cria um widget de janela única com um botão de texto dentro dele.
-- Criar o widget primeirolocal widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, true, true, 300, 200)local dragSourceWidget = plugin:CreateDockWidgetPluginGui("Fonte de Arrasto", widgetInfo)dragSourceWidget.Title = "Fonte de Arrasto"-- Criar um TextButton que iniciará o arrastolocal dragButton = Instance.new("TextButton")dragButton.Size = UDim2.new(1, 0, 1, 0)dragButton.Text = "Arraste-me!"dragButton.Parent = dragSourceWidget
Iniciar o arrasto
Quando o usuário clica no TextButton, você pode iniciar o arrasto através do evento MouseButton1Down(), que é ativado assim que o usuário pressiona o botão do mouse.
Dentro da função conectada, determine os dados a serem arrastados. O tipo dos dados deve ser refletido na chave MimeType, o conteúdo do arrasto deve ser refletido na chave Data, e o remetente deve descrever a si mesmo na chave Sender. Consulte a página Plugin:StartDrag() para mais detalhes.
local function onButton1Down()
local dragInfo = {
Data = "Olá, mundo", -- Os dados sendo arrastados
MimeType = "text/plain", -- Descreve o tipo MIME dos dados
Sender = "SomeDragSource", -- Descreve de onde os dados se originaram
MouseIcon = "", -- Conteúdo da imagem a ser usado para o cursor
DragIcon = "", -- Conteúdo da imagem a ser renderizado sob o cursor durante o arrasto
HotSpot = Vector2.zero -- Onde no DragIcon centralizar o cursor
}
plugin:StartDrag(dragInfo)
end
dragButton.MouseButton1Down:Connect(onButton1Down)
Criar alvo de soltura
O evento PluginGui.PluginDragDropped é ativado quando o usuário solta o mouse em uma janela durante um arrasto. Quando isso ocorre, você precisa definir um alvo de soltura, como um segundo widget com um TextLabel para detectar as soltas.
local dragTargetWidget = plugin:CreateDockWidgetPluginGui("Alvo de Soltura", widgetInfo)dragTargetWidget.Title = "Alvo de Soltura"-- Este TextLabel irá exibir o que foi soltolocal textLabel = Instance.new("TextLabel")textLabel.Size = UDim2.new(1, 0, 1, 0)textLabel.Text = "Solte aqui..."textLabel.Parent = dragTargetWidget
Processar a ação de soltura
Depois de criar um alvo de soltura, conecte o evento PluginGui.PluginDragDropped no widget de alvo de soltura:
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)
Enquanto um arrasto ainda estiver em progresso, esses três eventos serão ativados à medida que o usuário mover o mouse sobre um widget:
- PluginDragEntered – é ativado quando o usuário paira o mouse sobre uma janela
- PluginDragMoved – é ativado repetidamente à medida que o usuário move o mouse sobre uma janela. Isso é útil para mostrar uma mensagem "Solte aqui!".
- PluginDragLeft – é ativado quando o cursor do usuário sai de uma janela. Isso é útil para esconder uma mensagem "Solte aqui!".















