jurarsr
🧩 Syntax:
local InputService = game:GetService('UserInputService');
local TextService = game:GetService('TextService');
local CoreGui = game:GetService('CoreGui');
local Teams = game:GetService('Teams');
local Players = game:GetService('Players');
local RunService = game:GetService('RunService')
local TweenService = game:GetService('TweenService');
local RenderStepped = RunService.RenderStepped;
local LocalPlayer = Players.LocalPlayer;
local Mouse = LocalPlayer:GetMouse();
local ProtectGui = protectgui or (syn and syn.protect_gui) or (function() end);
local ScreenGui = Instance.new('ScreenGui');
ProtectGui(ScreenGui);
ScreenGui.ZIndexBehavior = Enum.ZIndexBehavior.Global;
ScreenGui.Parent = CoreGui;
local Toggles = {};
local Options = {};
getgenv().Toggles = Toggles;
getgenv().Options = Options;
local Library = {
Registry = {};
RegistryMap = {};
HudRegistry = {};
FontColor = Color3.fromRGB(255, 255, 255);
MainColor = Color3.fromRGB(28, 28, 28);
BackgroundColor = Color3.fromRGB(20, 20, 20);
AccentColor = Color3.fromRGB(0, 85, 255);
OutlineColor = Color3.fromRGB(50, 50, 50);
RiskColor = Color3.fromRGB(255, 50, 50),
Black = Color3.new(0, 0, 0);
Font = Enum.Font.Jura,
OpenedFrames = {};
DependencyBoxes = {};
Signals = {};
ScreenGui = ScreenGui;
};
local RainbowStep = 0
local Hue = 0
table.insert(Library.Signals, RenderStepped:Connect(function(Delta)
RainbowStep = RainbowStep + Delta
if RainbowStep >= (1 / 60) then
RainbowStep = 0
Hue = Hue + (1 / 400);
if Hue > 1 then
Hue = 0;
end;
Library.CurrentRainbowHue = Hue;
Library.CurrentRainbowColor = Color3.fromHSV(Hue, 0.8, 1);
end
end))
local function GetPlayersString()
local PlayerList = Players:GetPlayers();
for i = 1, #PlayerList do
PlayerList[i] = PlayerList[i].Name;
end;
table.sort(PlayerList, function(str1, str2) return str1 < str2 end);
return PlayerList;
end;
local function GetTeamsString()
local TeamList = Teams:GetTeams();
for i = 1, #TeamList do
TeamList[i] = TeamList[i].Name;
end;
table.sort(TeamList, function(str1, str2) return str1 < str2 end);
return TeamList;
end;
function Library:SafeCallback(f, ...)
if (not f) then
return;
end;
if not Library.NotifyOnError then
return f(...);
end;
local success, event = pcall(f, ...);
if not success then
local _, i = event:find(":%d+: ");
if not i then
return Library:Notify(event);
end;
return Library:Notify(event:sub(i + 1), 3);
end;
end;
function Library:AttemptSave()
if Library.SaveManager then
Library.SaveManager:Save();
end;
end;
function Library:Create(Class, Properties)
local _Instance = Class;
if type(Class) == 'string' then
_Instance = Instance.new(Class);
end;
for Property, Value in next, Properties do
_Instance[Property] = Value;
end;
return _Instance;
end;
function Library:ApplyTextStroke(Inst)
Inst.TextStrokeTransparency = 1;
Library:Create('UIStroke', {
Color = Color3.new(0, 0, 0);
Thickness = 1;
LineJoinMode = Enum.LineJoinMode.Miter;
Parent = Inst;
});
end;
function Library:CreateLabel(Properties, IsHud)
local _Instance = Library:Create('TextLabel', {
BackgroundTransparency = 1;
Font = Library.Font;
TextColor3 = Library.FontColor;
TextSize = 16;
TextStrokeTransparency = 0;
});
Library:ApplyTextStroke(_Instance);
Library:AddToRegistry(_Instance, {
TextColor3 = 'FontColor';
}, IsHud);
return Library:Create(_Instance, Properties);
end;
function Library:MakeDraggable(Instance, Cutoff)
Instance.Active = true;
Instance.InputBegan:Connect(function(Input)
if Input.UserInputType == Enum.UserInputType.MouseButton1 then
local ObjPos = Vector2.new(
Mouse.X - Instance.AbsolutePosition.X,
Mouse.Y - Instance.AbsolutePosition.Y
);
if ObjPos.Y > (Cutoff or 40) then
return;
end;
while InputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) do
Instance.Position = UDim2.new(
0,
Mouse.X - ObjPos.X + (Instance.Size.X.Offset * Instance.AnchorPoint.X),
0,
Mouse.Y - ObjPos.Y + (Instance.Size.Y.Offset * Instance.AnchorPoint.Y)
);
RenderStepped:Wait();
end;
end;
end)
end;
function Library:AddToolTip(InfoStr, HoverInstance)
local X, Y = Library:GetTextBounds(InfoStr, Library.Font, 14);
local Tooltip = Library:Create('Frame', {
BackgroundColor3 = Library.MainColor,
BorderColor3 = Library.OutlineColor,
Size = UDim2.fromOffset(X + 5, Y + 4),
ZIndex = 100,
Parent = Library.ScreenGui,
Visible = false,
})
local Label = Library:CreateLabel({
Position = UDim2.fromOffset(3, 1),
Size = UDim2.fromOffset(X, Y);
TextSize = 14;
Text = InfoStr,
TextColor3 = Library.FontColor,
TextXAlignment = Enum.TextXAlignment.Left;
ZIndex = Tooltip.ZIndex + 1,
Parent = Tooltip;
});
Library:AddToRegistry(Tooltip, {
BackgroundColor3 = 'MainColor';
BorderColor3 = 'OutlineColor';
});
Library:AddToRegistry(Label, {
TextColor3 = 'FontColor',
});
local IsHovering = false
HoverInstance.MouseEnter:Connect(function()
if Library:MouseIsOverOpenedFrame() then
return
end
IsHovering = true
Tooltip.Position = UDim2.fromOffset(Mouse.X + 15, Mouse.Y + 12)
Tooltip.Visible = true
while IsHovering do
RunService.Heartbeat:Wait()
Tooltip.Position = UDim2.fromOffset(Mouse.X + 15, Mouse.Y + 12)
end
end)
HoverInstance.MouseLeave:Connect(function()
IsHovering = false
Tooltip.Visible = false
end)
end
function Library:OnHighlight(HighlightInstance, Instance, Properties, PropertiesDefault)
HighlightInstance.MouseEnter:Connect(function()
local Reg = Library.RegistryMap[Instance];
for Property, ColorIdx in next, Properties do
Instance[Property] = Library[ColorIdx] or ColorIdx;
if Reg and Reg.Properties[Property] then
Reg.Properties[Property] = ColorIdx;
end;
end;
end)
HighlightInstance.MouseLeave:Connect(function()
local Reg = Library.RegistryMap[Instance];
for Property, ColorIdx in next, PropertiesDefault do
Instance[Property] = Library[ColorIdx] or ColorIdx;
if Reg and Reg.Properties[Property] then
Reg.Properties[Property] = ColorIdx;
end;
end;
end)
end;
function Library:MouseIsOverOpenedFrame()
for Frame, _ in next, Library.OpenedFrames do
local AbsPos, AbsSize = Frame.AbsolutePosition, Frame.AbsoluteSize;
if Mouse.X >= AbsPos.X and Mouse.X <= AbsPos.X + AbsSize.X
and Mouse.Y >= AbsPos.Y and Mouse.Y <= AbsPos.Y + AbsSize.Y then
return true;
end;
end;
end;
function Library:IsMouseOverFrame(Frame)
local AbsPos, AbsSize = Frame.AbsolutePosition, Frame.AbsoluteSize;
if Mouse.X >= AbsPos.X and Mouse.X <= AbsPos.X + AbsSize.X
and Mouse.Y >= AbsPos.Y and Mouse.Y <= AbsPos.Y + AbsSize.Y then
return true;
end;
end;
function Library:UpdateDependencyBoxes()
for _, Depbox in next, Library.DependencyBoxes do
Depbox:Update();
end;
end;
function Library:MapValue(Value, MinA, MaxA, MinB, MaxB)
return (1 - ((Value - MinA) / (MaxA - MinA))) * MinB + ((Value - MinA) / (MaxA - MinA)) * MaxB;
end;
function Library:GetTextBounds(Text, Font, Size, Resolution)
local Bounds = TextService:GetTextSize(Text, Size, Font, Resolution or Vector2.new(1920, 1080))
return Bounds.X, Bounds.Y
end;
function Library:GetDarkerColor(Color)
local H, S, V = Color3.toHSV(Color);
return Color3.fromHSV(H, S, V / 1.5);
end;
Library.AccentColorDark = Library:GetDarkerColor(Library.AccentColor);
function Library:AddToRegistry(Instance, Properties, IsHud)
local Idx = #Library.Registry + 1;
local Data = {
Instance = Instance;
Properties = Properties;
Idx = Idx;
};
table.insert(Library.Registry, Data);
Library.RegistryMap[Instance] = Data;
if IsHud then
table.insert(Library.HudRegistry, Data);
end;
end;
function Library:RemoveFromRegistry(Instance)
local Data = Library.RegistryMap[Instance];
if Data then
for Idx = #Library.Registry, 1, -1 do
if Library.Registry[Idx] == Data then
table.remove(Library.Registry, Idx);
end;
end;
for Idx = #Library.HudRegistry, 1, -1 do
if Library.HudRegistry[Idx] == Data then
table.remove(Library.HudRegistry, Idx);
end;
end;
Library.RegistryMap[Instance] = nil;
end;
end;
function Library:UpdateColorsUsingRegistry()
-- TODO: Could have an 'active' list of objects
-- where the active list only contains Visible objects.
-- IMPL: Could setup .Changed events on the AddToRegistry function
-- that listens for the 'Visible' propert being changed.
-- Visible: true => Add to active list, and call UpdateColors function
-- Visible: false => Remove from active list.
-- The above would be especially efficient for a rainbow menu color or live color-changing.
for Idx, Object in next, Library.Registry do
for Property, ColorIdx in next, Object.Properties do
if type(ColorIdx) == 'string' then
Object.Instance[Property] = Library[ColorIdx];
elseif type(ColorIdx) == 'function' then
Object.Instance[Property] = ColorIdx()
end
end;
end;
end;
function Library:GiveSignal(Signal)
-- Only used for signals not attached to library instances, as those should be cleaned up on object destruction by Roblox
table.insert(Library.Signals, Signal)
end
function Library:Unload()
-- Unload all of the signals
for Idx = #Library.Signals, 1, -1 do
local Connection = table.remove(Library.Signals, Idx)
Connection:Disconnect()
end
-- Call our unload callback, maybe to undo some hooks etc
if Library.OnUnload then
Library.OnUnload()
end
ScreenGui:Destroy()
end
function Library:OnUnload(Callback)
Library.OnUnload = Callback
end
Library:GiveSignal(ScreenGui.DescendantRemoving:Connect(function(Instance)
if Library.RegistryMap[Instance] then
Library:RemoveFromRegistry(Instance);
end;
end))
local BaseAddons = {};
do
local Funcs = {};
function Funcs:AddColorPicker(Idx, Info)
local ToggleLabel = self.TextLabel;
-- local Container = self.Container;
assert(Info.Default, 'AddColorPicker: Missing default value.');
local ColorPicker = {
Value = Info.Default;
Transparency = Info.Transparency or 0;
Type = 'ColorPicker';
Title = type(Info.Title) == 'string' and Info.Title or 'Color picker',
Callback = Info.Callback or function(Color) end;
};
function ColorPicker:SetHSVFromRGB(Color)
local H, S, V = Color3.toHSV(Color);
ColorPicker.Hue = H;
ColorPicker.Sat = S;
ColorPicker.Vib = V;
end;
ColorPicker:SetHSVFromRGB(ColorPicker.Value);
local DisplayFrame = Library:Create('Frame', {
BackgroundColor3 = ColorPicker.Value;
BorderColor3 = Library:GetDarkerColor(ColorPicker.Value);
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(0, 28, 0, 14);
ZIndex = 6;
Parent = ToggleLabel;
});
-- Transparency image taken from https://github.com/matas3535/SplixPrivateDrawingLibrary/blob/main/Library.lua cus i'm lazy
local CheckerFrame = Library:Create('ImageLabel', {
BorderSizePixel = 0;
Size = UDim2.new(0, 27, 0, 13);
ZIndex = 5;
Image = 'http://www.roblox.com/asset/?id=12977615774';
Visible = not not Info.Transparency;
Parent = DisplayFrame;
});
-- 1/16/23
-- Rewrote this to be placed inside the Library ScreenGui
-- There was some issue which caused RelativeOffset to be way off
-- Thus the color picker would never show
local PickerFrameOuter = Library:Create('Frame', {
Name = 'Color';
BackgroundColor3 = Color3.new(1, 1, 1);
BorderColor3 = Color3.new(0, 0, 0);
Position = UDim2.fromOffset(DisplayFrame.AbsolutePosition.X, DisplayFrame.AbsolutePosition.Y + 18),
Size = UDim2.fromOffset(230, Info.Transparency and 271 or 253);
Visible = false;
ZIndex = 15;
Parent = ScreenGui,
});
DisplayFrame:GetPropertyChangedSignal('AbsolutePosition'):Connect(function()
PickerFrameOuter.Position = UDim2.fromOffset(DisplayFrame.AbsolutePosition.X, DisplayFrame.AbsolutePosition.Y + 18);
end)
local PickerFrameInner = Library:Create('Frame', {
BackgroundColor3 = Library.BackgroundColor;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 16;
Parent = PickerFrameOuter;
});
local Highlight = Library:Create('Frame', {
BackgroundColor3 = Library.AccentColor;
BorderSizePixel = 0;
Size = UDim2.new(1, 0, 0, 2);
ZIndex = 17;
Parent = PickerFrameInner;
});
local SatVibMapOuter = Library:Create('Frame', {
BorderColor3 = Color3.new(0, 0, 0);
Position = UDim2.new(0, 4, 0, 25);
Size = UDim2.new(0, 200, 0, 200);
ZIndex = 17;
Parent = PickerFrameInner;
});
local SatVibMapInner = Library:Create('Frame', {
BackgroundColor3 = Library.BackgroundColor;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 18;
Parent = SatVibMapOuter;
});
local SatVibMap = Library:Create('ImageLabel', {
BorderSizePixel = 0;
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 18;
Image = 'rbxassetid://4155801252';
Parent = SatVibMapInner;
});
local CursorOuter = Library:Create('ImageLabel', {
AnchorPoint = Vector2.new(0.5, 0.5);
Size = UDim2.new(0, 6, 0, 6);
BackgroundTransparency = 1;
Image = 'http://www.roblox.com/asset/?id=9619665977';
ImageColor3 = Color3.new(0, 0, 0);
ZIndex = 19;
Parent = SatVibMap;
});
local CursorInner = Library:Create('ImageLabel', {
Size = UDim2.new(0, CursorOuter.Size.X.Offset - 2, 0, CursorOuter.Size.Y.Offset - 2);
Position = UDim2.new(0, 1, 0, 1);
BackgroundTransparency = 1;
Image = 'http://www.roblox.com/asset/?id=9619665977';
ZIndex = 20;
Parent = CursorOuter;
})
local HueSelectorOuter = Library:Create('Frame', {
BorderColor3 = Color3.new(0, 0, 0);
Position = UDim2.new(0, 208, 0, 25);
Size = UDim2.new(0, 15, 0, 200);
ZIndex = 17;
Parent = PickerFrameInner;
});
local HueSelectorInner = Library:Create('Frame', {
BackgroundColor3 = Color3.new(1, 1, 1);
BorderSizePixel = 0;
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 18;
Parent = HueSelectorOuter;
});
local HueCursor = Library:Create('Frame', {
BackgroundColor3 = Color3.new(1, 1, 1);
AnchorPoint = Vector2.new(0, 0.5);
BorderColor3 = Color3.new(0, 0, 0);
Size = UDim2.new(1, 0, 0, 1);
ZIndex = 18;
Parent = HueSelectorInner;
});
local HueBoxOuter = Library:Create('Frame', {
BorderColor3 = Color3.new(0, 0, 0);
Position = UDim2.fromOffset(4, 228),
Size = UDim2.new(0.5, -6, 0, 20),
ZIndex = 18,
Parent = PickerFrameInner;
});
local HueBoxInner = Library:Create('Frame', {
BackgroundColor3 = Library.MainColor;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 18,
Parent = HueBoxOuter;
});
Library:Create('UIGradient', {
Color = ColorSequence.new({
ColorSequenceKeypoint.new(0, Color3.new(1, 1, 1)),
ColorSequenceKeypoint.new(1, Color3.fromRGB(212, 212, 212))
});
Rotation = 90;
Parent = HueBoxInner;
});
local HueBox = Library:Create('TextBox', {
BackgroundTransparency = 1;
Position = UDim2.new(0, 5, 0, 0);
Size = UDim2.new(1, -5, 1, 0);
Font = Library.Font;
PlaceholderColor3 = Color3.fromRGB(190, 190, 190);
PlaceholderText = 'Hex color',
Text = '#FFFFFF',
TextColor3 = Library.FontColor;
TextSize = 14;
TextStrokeTransparency = 0;
TextXAlignment = Enum.TextXAlignment.Left;
ZIndex = 20,
Parent = HueBoxInner;
});
Library:ApplyTextStroke(HueBox);
local RgbBoxBase = Library:Create(HueBoxOuter:Clone(), {
Position = UDim2.new(0.5, 2, 0, 228),
Size = UDim2.new(0.5, -6, 0, 20),
Parent = PickerFrameInner
});
local RgbBox = Library:Create(RgbBoxBase.Frame:FindFirstChild('TextBox'), {
Text = '255, 255, 255',
PlaceholderText = 'RGB color',
TextColor3 = Library.FontColor
});
local TransparencyBoxOuter, TransparencyBoxInner, TransparencyCursor;
if Info.Transparency then
TransparencyBoxOuter = Library:Create('Frame', {
BorderColor3 = Color3.new(0, 0, 0);
Position = UDim2.fromOffset(4, 251);
Size = UDim2.new(1, -8, 0, 15);
ZIndex = 19;
Parent = PickerFrameInner;
});
TransparencyBoxInner = Library:Create('Frame', {
BackgroundColor3 = ColorPicker.Value;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 19;
Parent = TransparencyBoxOuter;
});
Library:AddToRegistry(TransparencyBoxInner, { BorderColor3 = 'OutlineColor' });
Library:Create('ImageLabel', {
BackgroundTransparency = 1;
Size = UDim2.new(1, 0, 1, 0);
Image = 'http://www.roblox.com/asset/?id=12978095818';
ZIndex = 20;
Parent = TransparencyBoxInner;
});
TransparencyCursor = Library:Create('Frame', {
BackgroundColor3 = Color3.new(1, 1, 1);
AnchorPoint = Vector2.new(0.5, 0);
BorderColor3 = Color3.new(0, 0, 0);
Size = UDim2.new(0, 1, 1, 0);
ZIndex = 21;
Parent = TransparencyBoxInner;
});
end;
local DisplayLabel = Library:CreateLabel({
Size = UDim2.new(1, 0, 0, 14);
Position = UDim2.fromOffset(5, 5);
TextXAlignment = Enum.TextXAlignment.Left;
TextSize = 14;
Text = ColorPicker.Title,--Info.Default;
TextWrapped = false;
ZIndex = 16;
Parent = PickerFrameInner;
});
local ContextMenu = {}
do
ContextMenu.Options = {}
ContextMenu.Container = Library:Create('Frame', {
BorderColor3 = Color3.new(),
ZIndex = 14,
Visible = false,
Parent = ScreenGui
})
ContextMenu.Inner = Library:Create('Frame', {
BackgroundColor3 = Library.BackgroundColor;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.fromScale(1, 1);
ZIndex = 15;
Parent = ContextMenu.Container;
});
Library:Create('UIListLayout', {
Name = 'Layout',
FillDirection = Enum.FillDirection.Vertical;
SortOrder = Enum.SortOrder.LayoutOrder;
Parent = ContextMenu.Inner;
});
Library:Create('UIPadding', {
Name = 'Padding',
PaddingLeft = UDim.new(0, 4),
Parent = ContextMenu.Inner,
});
local function updateMenuPosition()
ContextMenu.Container.Position = UDim2.fromOffset(
(DisplayFrame.AbsolutePosition.X + DisplayFrame.AbsoluteSize.X) + 4,
DisplayFrame.AbsolutePosition.Y + 1
)
end
local function updateMenuSize()
local menuWidth = 60
for i, label in next, ContextMenu.Inner:GetChildren() do
if label:IsA('TextLabel') then
menuWidth = math.max(menuWidth, label.TextBounds.X)
end
end
ContextMenu.Container.Size = UDim2.fromOffset(
menuWidth + 8,
ContextMenu.Inner.Layout.AbsoluteContentSize.Y + 4
)
end
DisplayFrame:GetPropertyChangedSignal('AbsolutePosition'):Connect(updateMenuPosition)
ContextMenu.Inner.Layout:GetPropertyChangedSignal('AbsoluteContentSize'):Connect(updateMenuSize)
task.spawn(updateMenuPosition)
task.spawn(updateMenuSize)
Library:AddToRegistry(ContextMenu.Inner, {
BackgroundColor3 = 'BackgroundColor';
BorderColor3 = 'OutlineColor';
});
function ContextMenu:Show()
self.Container.Visible = true
end
function ContextMenu:Hide()
self.Container.Visible = false
end
function ContextMenu:AddOption(Str, Callback)
if type(Callback) ~= 'function' then
Callback = function() end
end
local Button = Library:CreateLabel({
Active = false;
Size = UDim2.new(1, 0, 0, 15);
TextSize = 13;
Text = Str;
ZIndex = 16;
Parent = self.Inner;
TextXAlignment = Enum.TextXAlignment.Left,
});
Library:OnHighlight(Button, Button,
{ TextColor3 = 'AccentColor' },
{ TextColor3 = 'FontColor' }
);
Button.InputBegan:Connect(function(Input)
if Input.UserInputType ~= Enum.UserInputType.MouseButton1 then
return
end
Callback()
end)
end
ContextMenu:AddOption('Copy color', function()
Library.ColorClipboard = ColorPicker.Value
Library:Notify('Copied color!', 2)
end)
ContextMenu:AddOption('Paste color', function()
if not Library.ColorClipboard then
return Library:Notify('You have not copied a color!', 2)
end
ColorPicker:SetValueRGB(Library.ColorClipboard)
end)
ContextMenu:AddOption('Copy HEX', function()
pcall(setclipboard, ColorPicker.Value:ToHex())
Library:Notify('Copied hex code to clipboard!', 2)
end)
ContextMenu:AddOption('Copy RGB', function()
pcall(setclipboard, table.concat({ math.floor(ColorPicker.Value.R * 255), math.floor(ColorPicker.Value.G * 255), math.floor(ColorPicker.Value.B * 255) }, ', '))
Library:Notify('Copied RGB values to clipboard!', 2)
end)
end
Library:AddToRegistry(PickerFrameInner, { BackgroundColor3 = 'BackgroundColor'; BorderColor3 = 'OutlineColor'; });
Library:AddToRegistry(Highlight, { BackgroundColor3 = 'AccentColor'; });
Library:AddToRegistry(SatVibMapInner, { BackgroundColor3 = 'BackgroundColor'; BorderColor3 = 'OutlineColor'; });
Library:AddToRegistry(HueBoxInner, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; });
Library:AddToRegistry(RgbBoxBase.Frame, { BackgroundColor3 = 'MainColor'; BorderColor3 = 'OutlineColor'; });
Library:AddToRegistry(RgbBox, { TextColor3 = 'FontColor', });
Library:AddToRegistry(HueBox, { TextColor3 = 'FontColor', });
local SequenceTable = {};
for Hue = 0, 1, 0.1 do
table.insert(SequenceTable, ColorSequenceKeypoint.new(Hue, Color3.fromHSV(Hue, 1, 1)));
end;
local HueSelectorGradient = Library:Create('UIGradient', {
Color = ColorSequence.new(SequenceTable);
Rotation = 90;
Parent = HueSelectorInner;
});
HueBox.FocusLost:Connect(function(enter)
if enter then
local success, result = pcall(Color3.fromHex, HueBox.Text)
if success and typeof(result) == 'Color3' then
ColorPicker.Hue, ColorPicker.Sat, ColorPicker.Vib = Color3.toHSV(result)
end
end
ColorPicker:Display()
end)
RgbBox.FocusLost:Connect(function(enter)
if enter then
local r, g, b = RgbBox.Text:match('(%d+),%s*(%d+),%s*(%d+)')
if r and g and b then
ColorPicker.Hue, ColorPicker.Sat, ColorPicker.Vib = Color3.toHSV(Color3.fromRGB(r, g, b))
end
end
ColorPicker:Display()
end)
function ColorPicker:Display()
ColorPicker.Value = Color3.fromHSV(ColorPicker.Hue, ColorPicker.Sat, ColorPicker.Vib);
SatVibMap.BackgroundColor3 = Color3.fromHSV(ColorPicker.Hue, 1, 1);
Library:Create(DisplayFrame, {
BackgroundColor3 = ColorPicker.Value;
BackgroundTransparency = ColorPicker.Transparency;
BorderColor3 = Library:GetDarkerColor(ColorPicker.Value);
});
if TransparencyBoxInner then
TransparencyBoxInner.BackgroundColor3 = ColorPicker.Value;
TransparencyCursor.Position = UDim2.new(1 - ColorPicker.Transparency, 0, 0, 0);
end;
CursorOuter.Position = UDim2.new(ColorPicker.Sat, 0, 1 - ColorPicker.Vib, 0);
HueCursor.Position = UDim2.new(0, 0, ColorPicker.Hue, 0);
HueBox.Text = '#' .. ColorPicker.Value:ToHex()
RgbBox.Text = table.concat({ math.floor(ColorPicker.Value.R * 255), math.floor(ColorPicker.Value.G * 255), math.floor(ColorPicker.Value.B * 255) }, ', ')
Library:SafeCallback(ColorPicker.Callback, ColorPicker.Value);
Library:SafeCallback(ColorPicker.Changed, ColorPicker.Value);
end;
function ColorPicker:OnChanged(Func)
ColorPicker.Changed = Func;
Func(ColorPicker.Value)
end;
function ColorPicker:Show()
for Frame, Val in next, Library.OpenedFrames do
if Frame.Name == 'Color' then
Frame.Visible = false;
Library.OpenedFrames[Frame] = nil;
end;
end;
PickerFrameOuter.Visible = true;
Library.OpenedFrames[PickerFrameOuter] = true;
end;
function ColorPicker:Hide()
PickerFrameOuter.Visible = false;
Library.OpenedFrames[PickerFrameOuter] = nil;
end;
function ColorPicker:SetValue(HSV, Transparency)
local Color = Color3.fromHSV(HSV[1], HSV[2], HSV[3]);
ColorPicker.Transparency = Transparency or 0;
ColorPicker:SetHSVFromRGB(Color);
ColorPicker:Display();
end;
function ColorPicker:SetValueRGB(Color, Transparency)
ColorPicker.Transparency = Transparency or 0;
ColorPicker:SetHSVFromRGB(Color);
ColorPicker:Display();
end;
SatVibMap.InputBegan:Connect(function(Input)
if Input.UserInputType == Enum.UserInputType.MouseButton1 then
while InputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) do
local MinX = SatVibMap.AbsolutePosition.X;
local MaxX = MinX + SatVibMap.AbsoluteSize.X;
local MouseX = math.clamp(Mouse.X, MinX, MaxX);
local MinY = SatVibMap.AbsolutePosition.Y;
local MaxY = MinY + SatVibMap.AbsoluteSize.Y;
local MouseY = math.clamp(Mouse.Y, MinY, MaxY);
ColorPicker.Sat = (MouseX - MinX) / (MaxX - MinX);
ColorPicker.Vib = 1 - ((MouseY - MinY) / (MaxY - MinY));
ColorPicker:Display();
RenderStepped:Wait();
end;
Library:AttemptSave();
end;
end);
HueSelectorInner.InputBegan:Connect(function(Input)
if Input.UserInputType == Enum.UserInputType.MouseButton1 then
while InputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) do
local MinY = HueSelectorInner.AbsolutePosition.Y;
local MaxY = MinY + HueSelectorInner.AbsoluteSize.Y;
local MouseY = math.clamp(Mouse.Y, MinY, MaxY);
ColorPicker.Hue = ((MouseY - MinY) / (MaxY - MinY));
ColorPicker:Display();
RenderStepped:Wait();
end;
Library:AttemptSave();
end;
end);
DisplayFrame.InputBegan:Connect(function(Input)
if Input.UserInputType == Enum.UserInputType.MouseButton1 and not Library:MouseIsOverOpenedFrame() then
if PickerFrameOuter.Visible then
ColorPicker:Hide()
else
ContextMenu:Hide()
ColorPicker:Show()
end;
elseif Input.UserInputType == Enum.UserInputType.MouseButton2 and not Library:MouseIsOverOpenedFrame() then
ContextMenu:Show()
ColorPicker:Hide()
end
end);
if TransparencyBoxInner then
TransparencyBoxInner.InputBegan:Connect(function(Input)
if Input.UserInputType == Enum.UserInputType.MouseButton1 then
while InputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) do
local MinX = TransparencyBoxInner.AbsolutePosition.X;
local MaxX = MinX + TransparencyBoxInner.AbsoluteSize.X;
local MouseX = math.clamp(Mouse.X, MinX, MaxX);
ColorPicker.Transparency = 1 - ((MouseX - MinX) / (MaxX - MinX));
ColorPicker:Display();
RenderStepped:Wait();
end;
Library:AttemptSave();
end;
end);
end;
Library:GiveSignal(InputService.InputBegan:Connect(function(Input)
if Input.UserInputType == Enum.UserInputType.MouseButton1 then
local AbsPos, AbsSize = PickerFrameOuter.AbsolutePosition, PickerFrameOuter.AbsoluteSize;
if Mouse.X < AbsPos.X or Mouse.X > AbsPos.X + AbsSize.X
or Mouse.Y < (AbsPos.Y - 20 - 1) or Mouse.Y > AbsPos.Y + AbsSize.Y then
ColorPicker:Hide();
end;
if not Library:IsMouseOverFrame(ContextMenu.Container) then
ContextMenu:Hide()
end
end;
if Input.UserInputType == Enum.UserInputType.MouseButton2 and ContextMenu.Container.Visible then
if not Library:IsMouseOverFrame(ContextMenu.Container) and not Library:IsMouseOverFrame(DisplayFrame) then
ContextMenu:Hide()
end
end
end))
ColorPicker:Display();
ColorPicker.DisplayFrame = DisplayFrame
Options[Idx] = ColorPicker;
return self;
end;
function Funcs:AddKeyPicker(Idx, Info)
local ParentObj = self;
local ToggleLabel = self.TextLabel;
local Container = self.Container;
assert(Info.Default, 'AddKeyPicker: Missing default value.');
local KeyPicker = {
Value = Info.Default;
Toggled = false;
Mode = Info.Mode or 'Toggle'; -- Always, Toggle, Hold
Type = 'KeyPicker';
Callback = Info.Callback or function(Value) end;
ChangedCallback = Info.ChangedCallback or function(New) end;
SyncToggleState = Info.SyncToggleState or false;
};
if KeyPicker.SyncToggleState then
Info.Modes = { 'Toggle' }
Info.Mode = 'Toggle'
end
local PickOuter = Library:Create('Frame', {
BackgroundColor3 = Color3.new(0, 0, 0);
BorderColor3 = Color3.new(0, 0, 0);
Size = UDim2.new(0, 28, 0, 15);
ZIndex = 6;
Parent = ToggleLabel;
});
local PickInner = Library:Create('Frame', {
BackgroundColor3 = Library.BackgroundColor;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 7;
Parent = PickOuter;
});
Library:AddToRegistry(PickInner, {
BackgroundColor3 = 'BackgroundColor';
BorderColor3 = 'OutlineColor';
});
local DisplayLabel = Library:CreateLabel({
Size = UDim2.new(1, 0, 1, 0);
TextSize = 13;
Text = Info.Default;
TextWrapped = true;
ZIndex = 8;
Parent = PickInner;
});
local ModeSelectOuter = Library:Create('Frame', {
BorderColor3 = Color3.new(0, 0, 0);
Position = UDim2.fromOffset(ToggleLabel.AbsolutePosition.X + ToggleLabel.AbsoluteSize.X + 4, ToggleLabel.AbsolutePosition.Y + 1);
Size = UDim2.new(0, 60, 0, 45 + 2);
Visible = false;
ZIndex = 14;
Parent = ScreenGui;
});
ToggleLabel:GetPropertyChangedSignal('AbsolutePosition'):Connect(function()
ModeSelectOuter.Position = UDim2.fromOffset(ToggleLabel.AbsolutePosition.X + ToggleLabel.AbsoluteSize.X + 4, ToggleLabel.AbsolutePosition.Y + 1);
end);
local ModeSelectInner = Library:Create('Frame', {
BackgroundColor3 = Library.BackgroundColor;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 15;
Parent = ModeSelectOuter;
});
Library:AddToRegistry(ModeSelectInner, {
BackgroundColor3 = 'BackgroundColor';
BorderColor3 = 'OutlineColor';
});
Library:Create('UIListLayout', {
FillDirection = Enum.FillDirection.Vertical;
SortOrder = Enum.SortOrder.LayoutOrder;
Parent = ModeSelectInner;
});
local ContainerLabel = Library:CreateLabel({
TextXAlignment = Enum.TextXAlignment.Left;
Size = UDim2.new(1, 0, 0, 18);
TextSize = 13;
Visible = false;
ZIndex = 110;
Parent = Library.KeybindContainer;
}, true);
local Modes = Info.Modes or { 'Always', 'Toggle', 'Hold' };
local ModeButtons = {};
for Idx, Mode in next, Modes do
local ModeButton = {};
local Label = Library:CreateLabel({
Active = false;
Size = UDim2.new(1, 0, 0, 15);
TextSize = 13;
Text = Mode;
ZIndex = 16;
Parent = ModeSelectInner;
});
function ModeButton:Select()
for _, Button in next, ModeButtons do
Button:Deselect();
end;
KeyPicker.Mode = Mode;
Label.TextColor3 = Library.AccentColor;
Library.RegistryMap[Label].Properties.TextColor3 = 'AccentColor';
ModeSelectOuter.Visible = false;
end;
function ModeButton:Deselect()
KeyPicker.Mode = nil;
Label.TextColor3 = Library.FontColor;
Library.RegistryMap[Label].Properties.TextColor3 = 'FontColor';
end;
Label.InputBegan:Connect(function(Input)
if Input.UserInputType == Enum.UserInputType.MouseButton1 then
ModeButton:Select();
Library:AttemptSave();
end;
end);
if Mode == KeyPicker.Mode then
ModeButton:Select();
end;
ModeButtons[Mode] = ModeButton;
end;
function KeyPicker:Update()
if Info.NoUI then
return;
end;
local State = KeyPicker:GetState();
ContainerLabel.Text = string.format('[%s] %s (%s)', KeyPicker.Value, Info.Text, KeyPicker.Mode);
ContainerLabel.Visible = true;
ContainerLabel.TextColor3 = State and Library.AccentColor or Library.FontColor;
Library.RegistryMap[ContainerLabel].Properties.TextColor3 = State and 'AccentColor' or 'FontColor';
local YSize = 0
local XSize = 0
for _, Label in next, Library.KeybindContainer:GetChildren() do
if Label:IsA('TextLabel') and Label.Visible then
YSize = YSize + 18;
if (Label.TextBounds.X > XSize) then
XSize = Label.TextBounds.X
end
end;
end;
Library.KeybindFrame.Size = UDim2.new(0, math.max(XSize + 10, 210), 0, YSize + 23)
end;
function KeyPicker:GetState()
if KeyPicker.Mode == 'Always' then
return true;
elseif KeyPicker.Mode == 'Hold' then
if KeyPicker.Value == 'None' then
return false;
end
local Key = KeyPicker.Value;
if Key == 'MB1' or Key == 'MB2' then
return Key == 'MB1' and InputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)
or Key == 'MB2' and InputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton2);
else
return InputService:IsKeyDown(Enum.KeyCode[KeyPicker.Value]);
end;
else
return KeyPicker.Toggled;
end;
end;
function KeyPicker:SetValue(Data)
local Key, Mode = Data[1], Data[2];
DisplayLabel.Text = Key;
KeyPicker.Value = Key;
ModeButtons[Mode]:Select();
KeyPicker:Update();
end;
function KeyPicker:OnClick(Callback)
KeyPicker.Clicked = Callback
end
function KeyPicker:OnChanged(Callback)
KeyPicker.Changed = Callback
Callback(KeyPicker.Value)
end
if ParentObj.Addons then
table.insert(ParentObj.Addons, KeyPicker)
end
function KeyPicker:DoClick()
if ParentObj.Type == 'Toggle' and KeyPicker.SyncToggleState then
ParentObj:SetValue(not ParentObj.Value)
end
Library:SafeCallback(KeyPicker.Callback, KeyPicker.Toggled)
Library:SafeCallback(KeyPicker.Clicked, KeyPicker.Toggled)
end
local Picking = false;
PickOuter.InputBegan:Connect(function(Input)
if Input.UserInputType == Enum.UserInputType.MouseButton1 and not Library:MouseIsOverOpenedFrame() then
Picking = true;
DisplayLabel.Text = '';
local Break;
local Text = '';
task.spawn(function()
while (not Break) do
if Text == '...' then
Text = '';
end;
Text = Text .. '.';
DisplayLabel.Text = Text;
wait(0.4);
end;
end);
wait(0.2);
local Event;
Event = InputService.InputBegan:Connect(function(Input)
local Key;
if Input.UserInputType == Enum.UserInputType.Keyboard then
Key = Input.KeyCode.Name;
elseif Input.UserInputType == Enum.UserInputType.MouseButton1 then
Key = 'MB1';
elseif Input.UserInputType == Enum.UserInputType.MouseButton2 then
Key = 'MB2';
end;
Break = true;
Picking = false;
DisplayLabel.Text = Key;
KeyPicker.Value = Key;
Library:SafeCallback(KeyPicker.ChangedCallback, Input.KeyCode or Input.UserInputType)
Library:SafeCallback(KeyPicker.Changed, Input.KeyCode or Input.UserInputType)
Library:AttemptSave();
Event:Disconnect();
end);
elseif Input.UserInputType == Enum.UserInputType.MouseButton2 and not Library:MouseIsOverOpenedFrame() then
ModeSelectOuter.Visible = true;
end;
end);
Library:GiveSignal(InputService.InputBegan:Connect(function(Input)
if (not Picking) then
if KeyPicker.Mode == 'Toggle' then
local Key = KeyPicker.Value;
if Key == 'MB1' or Key == 'MB2' then
if Key == 'MB1' and Input.UserInputType == Enum.UserInputType.MouseButton1
or Key == 'MB2' and Input.UserInputType == Enum.UserInputType.MouseButton2 then
KeyPicker.Toggled = not KeyPicker.Toggled
KeyPicker:DoClick()
end;
elseif Input.UserInputType == Enum.UserInputType.Keyboard then
if Input.KeyCode.Name == Key then
KeyPicker.Toggled = not KeyPicker.Toggled;
KeyPicker:DoClick()
end;
end;
end;
KeyPicker:Update();
end;
if Input.UserInputType == Enum.UserInputType.MouseButton1 then
local AbsPos, AbsSize = ModeSelectOuter.AbsolutePosition, ModeSelectOuter.AbsoluteSize;
if Mouse.X < AbsPos.X or Mouse.X > AbsPos.X + AbsSize.X
or Mouse.Y < (AbsPos.Y - 20 - 1) or Mouse.Y > AbsPos.Y + AbsSize.Y then
ModeSelectOuter.Visible = false;
end;
end;
end))
Library:GiveSignal(InputService.InputEnded:Connect(function(Input)
if (not Picking) then
KeyPicker:Update();
end;
end))
KeyPicker:Update();
Options[Idx] = KeyPicker;
return self;
end;
BaseAddons.__index = Funcs;
BaseAddons.__namecall = function(Table, Key, ...)
return Funcs[Key](...);
end;
end;
local BaseGroupbox = {};
do
local Funcs = {};
function Funcs:AddBlank(Size)
local Groupbox = self;
local Container = Groupbox.Container;
Library:Create('Frame', {
BackgroundTransparency = 1;
Size = UDim2.new(1, 0, 0, Size);
ZIndex = 1;
Parent = Container;
});
end;
function Funcs:AddLabel(Text, DoesWrap)
local Label = {};
local Groupbox = self;
local Container = Groupbox.Container;
local TextLabel = Library:CreateLabel({
Size = UDim2.new(1, -4, 0, 15);
TextSize = 14;
Text = Text;
TextWrapped = DoesWrap or false,
TextXAlignment = Enum.TextXAlignment.Left;
ZIndex = 5;
Parent = Container;
});
if DoesWrap then
local Y = select(2, Library:GetTextBounds(Text, Library.Font, 14, Vector2.new(TextLabel.AbsoluteSize.X, math.huge)))
TextLabel.Size = UDim2.new(1, -4, 0, Y)
else
Library:Create('UIListLayout', {
Padding = UDim.new(0, 4);
FillDirection = Enum.FillDirection.Horizontal;
HorizontalAlignment = Enum.HorizontalAlignment.Right;
SortOrder = Enum.SortOrder.LayoutOrder;
Parent = TextLabel;
});
end
Label.TextLabel = TextLabel;
Label.Container = Container;
function Label:SetText(Text)
TextLabel.Text = Text
if DoesWrap then
local Y = select(2, Library:GetTextBounds(Text, Library.Font, 14, Vector2.new(TextLabel.AbsoluteSize.X, math.huge)))
TextLabel.Size = UDim2.new(1, -4, 0, Y)
end
Groupbox:Resize();
end
if (not DoesWrap) then
setmetatable(Label, BaseAddons);
end
Groupbox:AddBlank(5);
Groupbox:Resize();
return Label;
end;
function Funcs:AddButton(...)
-- TODO: Eventually redo this
local Button = {};
local function ProcessButtonParams(Class, Obj, ...)
local Props = select(1, ...)
if type(Props) == 'table' then
Obj.Text = Props.Text
Obj.Func = Props.Func
Obj.DoubleClick = Props.DoubleClick
Obj.Tooltip = Props.Tooltip
else
Obj.Text = select(1, ...)
Obj.Func = select(2, ...)
end
assert(type(Obj.Func) == 'function', 'AddButton: `Func` callback is missing.');
end
ProcessButtonParams('Button', Button, ...)
local Groupbox = self;
local Container = Groupbox.Container;
local function CreateBaseButton(Button)
local Outer = Library:Create('Frame', {
BackgroundColor3 = Color3.new(0, 0, 0);
BorderColor3 = Color3.new(0, 0, 0);
Size = UDim2.new(1, -4, 0, 20);
ZIndex = 5;
});
local Inner = Library:Create('Frame', {
BackgroundColor3 = Library.MainColor;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 6;
Parent = Outer;
});
local Label = Library:CreateLabel({
Size = UDim2.new(1, 0, 1, 0);
TextSize = 14;
Text = Button.Text;
ZIndex = 6;
Parent = Inner;
});
Library:Create('UIGradient', {
Color = ColorSequence.new({
ColorSequenceKeypoint.new(0, Color3.new(1, 1, 1)),
ColorSequenceKeypoint.new(1, Color3.fromRGB(212, 212, 212))
});
Rotation = 90;
Parent = Inner;
});
Library:AddToRegistry(Outer, {
BorderColor3 = 'Black';
});
Library:AddToRegistry(Inner, {
BackgroundColor3 = 'MainColor';
BorderColor3 = 'OutlineColor';
});
Library:OnHighlight(Outer, Outer,
{ BorderColor3 = 'AccentColor' },
{ BorderColor3 = 'Black' }
);
return Outer, Inner, Label
end
local function InitEvents(Button)
local function WaitForEvent(event, timeout, validator)
local bindable = Instance.new('BindableEvent')
local connection = event:Once(function(...)
if type(validator) == 'function' and validator(...) then
bindable:Fire(true)
else
bindable:Fire(false)
end
end)
task.delay(timeout, function()
connection:disconnect()
bindable:Fire(false)
end)
return bindable.Event:Wait()
end
local function ValidateClick(Input)
if Library:MouseIsOverOpenedFrame() then
return false
end
if Input.UserInputType ~= Enum.UserInputType.MouseButton1 then
return false
end
return true
end
Button.Outer.InputBegan:Connect(function(Input)
if not ValidateClick(Input) then return end
if Button.Locked then return end
if Button.DoubleClick then
Library:RemoveFromRegistry(Button.Label)
Library:AddToRegistry(Button.Label, { TextColor3 = 'AccentColor' })
Button.Label.TextColor3 = Library.AccentColor
Button.Label.Text = 'Are you sure?'
Button.Locked = true
local clicked = WaitForEvent(Button.Outer.InputBegan, 0.5, ValidateClick)
Library:RemoveFromRegistry(Button.Label)
Library:AddToRegistry(Button.Label, { TextColor3 = 'FontColor' })
Button.Label.TextColor3 = Library.FontColor
Button.Label.Text = Button.Text
task.defer(rawset, Button, 'Locked', false)
if clicked then
Library:SafeCallback(Button.Func)
end
return
end
Library:SafeCallback(Button.Func);
end)
end
Button.Outer, Button.Inner, Button.Label = CreateBaseButton(Button)
Button.Outer.Parent = Container
InitEvents(Button)
function Button:AddTooltip(tooltip)
if type(tooltip) == 'string' then
Library:AddToolTip(tooltip, self.Outer)
end
return self
end
function Button:AddButton(...)
local SubButton = {}
ProcessButtonParams('SubButton', SubButton, ...)
self.Outer.Size = UDim2.new(0.5, -2, 0, 20)
SubButton.Outer, SubButton.Inner, SubButton.Label = CreateBaseButton(SubButton)
SubButton.Outer.Position = UDim2.new(1, 3, 0, 0)
SubButton.Outer.Size = UDim2.fromOffset(self.Outer.AbsoluteSize.X - 2, self.Outer.AbsoluteSize.Y)
SubButton.Outer.Parent = self.Outer
function SubButton:AddTooltip(tooltip)
if type(tooltip) == 'string' then
Library:AddToolTip(tooltip, self.Outer)
end
return SubButton
end
if type(SubButton.Tooltip) == 'string' then
SubButton:AddTooltip(SubButton.Tooltip)
end
InitEvents(SubButton)
return SubButton
end
if type(Button.Tooltip) == 'string' then
Button:AddTooltip(Button.Tooltip)
end
Groupbox:AddBlank(5);
Groupbox:Resize();
return Button;
end;
function Funcs:AddDivider()
local Groupbox = self;
local Container = self.Container
local Divider = {
Type = 'Divider',
}
Groupbox:AddBlank(2);
local DividerOuter = Library:Create('Frame', {
BackgroundColor3 = Color3.new(0, 0, 0);
BorderColor3 = Color3.new(0, 0, 0);
Size = UDim2.new(1, -4, 0, 5);
ZIndex = 5;
Parent = Container;
});
local DividerInner = Library:Create('Frame', {
BackgroundColor3 = Library.MainColor;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 6;
Parent = DividerOuter;
});
Library:AddToRegistry(DividerOuter, {
BorderColor3 = 'Black';
});
Library:AddToRegistry(DividerInner, {
BackgroundColor3 = 'MainColor';
BorderColor3 = 'OutlineColor';
});
Groupbox:AddBlank(9);
Groupbox:Resize();
end
function Funcs:AddInput(Idx, Info)
assert(Info.Text, 'AddInput: Missing `Text` string.')
local Textbox = {
Value = Info.Default or '';
Numeric = Info.Numeric or false;
Finished = Info.Finished or false;
Type = 'Input';
Callback = Info.Callback or function(Value) end;
};
local Groupbox = self;
local Container = Groupbox.Container;
local InputLabel = Library:CreateLabel({
Size = UDim2.new(1, 0, 0, 15);
TextSize = 14;
Text = Info.Text;
TextXAlignment = Enum.TextXAlignment.Left;
ZIndex = 5;
Parent = Container;
});
Groupbox:AddBlank(1);
local TextBoxOuter = Library:Create('Frame', {
BackgroundColor3 = Color3.new(0, 0, 0);
BorderColor3 = Color3.new(0, 0, 0);
Size = UDim2.new(1, -4, 0, 20);
ZIndex = 5;
Parent = Container;
});
local TextBoxInner = Library:Create('Frame', {
BackgroundColor3 = Library.MainColor;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 6;
Parent = TextBoxOuter;
});
Library:AddToRegistry(TextBoxInner, {
BackgroundColor3 = 'MainColor';
BorderColor3 = 'OutlineColor';
});
Library:OnHighlight(TextBoxOuter, TextBoxOuter,
{ BorderColor3 = 'AccentColor' },
{ BorderColor3 = 'Black' }
);
if type(Info.Tooltip) == 'string' then
Library:AddToolTip(Info.Tooltip, TextBoxOuter)
end
Library:Create('UIGradient', {
Color = ColorSequence.new({
ColorSequenceKeypoint.new(0, Color3.new(1, 1, 1)),
ColorSequenceKeypoint.new(1, Color3.fromRGB(212, 212, 212))
});
Rotation = 90;
Parent = TextBoxInner;
});
local Container = Library:Create('Frame', {
BackgroundTransparency = 1;
ClipsDescendants = true;
Position = UDim2.new(0, 5, 0, 0);
Size = UDim2.new(1, -5, 1, 0);
ZIndex = 7;
Parent = TextBoxInner;
})
local Box = Library:Create('TextBox', {
BackgroundTransparency = 1;
Position = UDim2.fromOffset(0, 0),
Size = UDim2.fromScale(5, 1),
Font = Library.Font;
PlaceholderColor3 = Color3.fromRGB(190, 190, 190);
PlaceholderText = Info.Placeholder or '';
Text = Info.Default or '';
TextColor3 = Library.FontColor;
TextSize = 14;
TextStrokeTransparency = 0;
TextXAlignment = Enum.TextXAlignment.Left;
ZIndex = 7;
Parent = Container;
});
Library:ApplyTextStroke(Box);
function Textbox:SetValue(Text)
if Info.MaxLength and #Text > Info.MaxLength then
Text = Text:sub(1, Info.MaxLength);
end;
if Textbox.Numeric then
if (not tonumber(Text)) and Text:len() > 0 then
Text = Textbox.Value
end
end
Textbox.Value = Text;
Box.Text = Text;
Library:SafeCallback(Textbox.Callback, Textbox.Value);
Library:SafeCallback(Textbox.Changed, Textbox.Value);
end;
if Textbox.Finished then
Box.FocusLost:Connect(function(enter)
if not enter then return end
Textbox:SetValue(Box.Text);
Library:AttemptSave();
end)
else
Box:GetPropertyChangedSignal('Text'):Connect(function()
Textbox:SetValue(Box.Text);
Library:AttemptSave();
end);
end
-- https://devforum.roblox.com/t/how-to-make-textboxes-follow-current-cursor-position/1368429/6
-- thank you nicemike40 :)
local function Update()
local PADDING = 2
local reveal = Container.AbsoluteSize.X
if not Box:IsFocused() or Box.TextBounds.X <= reveal - 2 * PADDING then
-- we aren't focused, or we fit so be normal
Box.Position = UDim2.new(0, PADDING, 0, 0)
else
-- we are focused and don't fit, so adjust position
local cursor = Box.CursorPosition
if cursor ~= -1 then
-- calculate pixel width of text from start to cursor
local subtext = string.sub(Box.Text, 1, cursor-1)
local width = TextService:GetTextSize(subtext, Box.TextSize, Box.Font, Vector2.new(math.huge, math.huge)).X
-- check if we're inside the box with the cursor
local currentCursorPos = Box.Position.X.Offset + width
-- adjust if necessary
if currentCursorPos < PADDING then
Box.Position = UDim2.fromOffset(PADDING-width, 0)
elseif currentCursorPos > reveal - PADDING - 1 then
Box.Position = UDim2.fromOffset(reveal-width-PADDING-1, 0)
end
end
end
end
task.spawn(Update)
Box:GetPropertyChangedSignal('Text'):Connect(Update)
Box:GetPropertyChangedSignal('CursorPosition'):Connect(Update)
Box.FocusLost:Connect(Update)
Box.Focused:Connect(Update)
Library:AddToRegistry(Box, {
TextColor3 = 'FontColor';
});
function Textbox:OnChanged(Func)
Textbox.Changed = Func;
Func(Textbox.Value);
end;
Groupbox:AddBlank(5);
Groupbox:Resize();
Options[Idx] = Textbox;
return Textbox;
end;
function Funcs:AddToggle(Idx, Info)
assert(Info.Text, 'AddInput: Missing `Text` string.')
local Toggle = {
Value = Info.Default or false;
Type = 'Toggle';
Callback = Info.Callback or function(Value) end;
Addons = {},
Risky = Info.Risky,
};
local Groupbox = self;
local Container = Groupbox.Container;
local ToggleOuter = Library:Create('Frame', {
BackgroundColor3 = Color3.new(0, 0, 0);
BorderColor3 = Color3.new(0, 0, 0);
Size = UDim2.new(0, 13, 0, 13);
ZIndex = 5;
Parent = Container;
});
Library:AddToRegistry(ToggleOuter, {
BorderColor3 = 'Black';
});
local ToggleInner = Library:Create('Frame', {
BackgroundColor3 = Library.MainColor;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 6;
Parent = ToggleOuter;
});
Library:AddToRegistry(ToggleInner, {
BackgroundColor3 = 'MainColor';
BorderColor3 = 'OutlineColor';
});
local ToggleLabel = Library:CreateLabel({
Size = UDim2.new(0, 216, 1, 0);
Position = UDim2.new(1, 6, 0, 0);
TextSize = 14;
Text = Info.Text;
TextXAlignment = Enum.TextXAlignment.Left;
ZIndex = 6;
Parent = ToggleInner;
});
Library:Create('UIListLayout', {
Padding = UDim.new(0, 4);
FillDirection = Enum.FillDirection.Horizontal;
HorizontalAlignment = Enum.HorizontalAlignment.Right;
SortOrder = Enum.SortOrder.LayoutOrder;
Parent = ToggleLabel;
});
local ToggleRegion = Library:Create('Frame', {
BackgroundTransparency = 1;
Size = UDim2.new(0, 170, 1, 0);
ZIndex = 8;
Parent = ToggleOuter;
});
Library:OnHighlight(ToggleRegion, ToggleOuter,
{ BorderColor3 = 'AccentColor' },
{ BorderColor3 = 'Black' }
);
function Toggle:UpdateColors()
Toggle:Display();
end;
if type(Info.Tooltip) == 'string' then
Library:AddToolTip(Info.Tooltip, ToggleRegion)
end
function Toggle:Display()
ToggleInner.BackgroundColor3 = Toggle.Value and Library.AccentColor or Library.MainColor;
ToggleInner.BorderColor3 = Toggle.Value and Library.AccentColorDark or Library.OutlineColor;
Library.RegistryMap[ToggleInner].Properties.BackgroundColor3 = Toggle.Value and 'AccentColor' or 'MainColor';
Library.RegistryMap[ToggleInner].Properties.BorderColor3 = Toggle.Value and 'AccentColorDark' or 'OutlineColor';
end;
function Toggle:OnChanged(Func)
Toggle.Changed = Func;
Func(Toggle.Value);
end;
function Toggle:SetValue(Bool)
Bool = (not not Bool);
Toggle.Value = Bool;
Toggle:Display();
for _, Addon in next, Toggle.Addons do
if Addon.Type == 'KeyPicker' and Addon.SyncToggleState then
Addon.Toggled = Bool
Addon:Update()
end
end
Library:SafeCallback(Toggle.Callback, Toggle.Value);
Library:SafeCallback(Toggle.Changed, Toggle.Value);
Library:UpdateDependencyBoxes();
end;
ToggleRegion.InputBegan:Connect(function(Input)
if Input.UserInputType == Enum.UserInputType.MouseButton1 and not Library:MouseIsOverOpenedFrame() then
Toggle:SetValue(not Toggle.Value) -- Why was it not like this from the start?
Library:AttemptSave();
end;
end);
if Toggle.Risky then
Library:RemoveFromRegistry(ToggleLabel)
ToggleLabel.TextColor3 = Library.RiskColor
Library:AddToRegistry(ToggleLabel, { TextColor3 = 'RiskColor' })
end
Toggle:Display();
Groupbox:AddBlank(Info.BlankSize or 5 + 2);
Groupbox:Resize();
Toggle.TextLabel = ToggleLabel;
Toggle.Container = Container;
setmetatable(Toggle, BaseAddons);
Toggles[Idx] = Toggle;
Library:UpdateDependencyBoxes();
return Toggle;
end;
function Funcs:AddSlider(Idx, Info)
assert(Info.Default, 'AddSlider: Missing default value.');
assert(Info.Text, 'AddSlider: Missing slider text.');
assert(Info.Min, 'AddSlider: Missing minimum value.');
assert(Info.Max, 'AddSlider: Missing maximum value.');
assert(Info.Rounding, 'AddSlider: Missing rounding value.');
local Slider = {
Value = Info.Default;
Min = Info.Min;
Max = Info.Max;
Rounding = Info.Rounding;
MaxSize = 232;
Type = 'Slider';
Callback = Info.Callback or function(Value) end;
};
local Groupbox = self;
local Container = Groupbox.Container;
if not Info.Compact then
Library:CreateLabel({
Size = UDim2.new(1, 0, 0, 10);
TextSize = 14;
Text = Info.Text;
TextXAlignment = Enum.TextXAlignment.Left;
TextYAlignment = Enum.TextYAlignment.Bottom;
ZIndex = 5;
Parent = Container;
});
Groupbox:AddBlank(3);
end
local SliderOuter = Library:Create('Frame', {
BackgroundColor3 = Color3.new(0, 0, 0);
BorderColor3 = Color3.new(0, 0, 0);
Size = UDim2.new(1, -4, 0, 13);
ZIndex = 5;
Parent = Container;
});
Library:AddToRegistry(SliderOuter, {
BorderColor3 = 'Black';
});
local SliderInner = Library:Create('Frame', {
BackgroundColor3 = Library.MainColor;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 6;
Parent = SliderOuter;
});
Library:AddToRegistry(SliderInner, {
BackgroundColor3 = 'MainColor';
BorderColor3 = 'OutlineColor';
});
local Fill = Library:Create('Frame', {
BackgroundColor3 = Library.AccentColor;
BorderColor3 = Library.AccentColorDark;
Size = UDim2.new(0, 0, 1, 0);
ZIndex = 7;
Parent = SliderInner;
});
Library:AddToRegistry(Fill, {
BackgroundColor3 = 'AccentColor';
BorderColor3 = 'AccentColorDark';
});
local HideBorderRight = Library:Create('Frame', {
BackgroundColor3 = Library.AccentColor;
BorderSizePixel = 0;
Position = UDim2.new(1, 0, 0, 0);
Size = UDim2.new(0, 1, 1, 0);
ZIndex = 8;
Parent = Fill;
});
Library:AddToRegistry(HideBorderRight, {
BackgroundColor3 = 'AccentColor';
});
local DisplayLabel = Library:CreateLabel({
Size = UDim2.new(1, 0, 1, 0);
TextSize = 14;
Text = 'Infinite';
ZIndex = 9;
Parent = SliderInner;
});
Library:OnHighlight(SliderOuter, SliderOuter,
{ BorderColor3 = 'AccentColor' },
{ BorderColor3 = 'Black' }
);
if type(Info.Tooltip) == 'string' then
Library:AddToolTip(Info.Tooltip, SliderOuter)
end
function Slider:UpdateColors()
Fill.BackgroundColor3 = Library.AccentColor;
Fill.BorderColor3 = Library.AccentColorDark;
end;
function Slider:Display()
local Suffix = Info.Suffix or '';
if Info.Compact then
DisplayLabel.Text = Info.Text .. ': ' .. Slider.Value .. Suffix
elseif Info.HideMax then
DisplayLabel.Text = string.format('%s', Slider.Value .. Suffix)
else
DisplayLabel.Text = string.format('%s/%s', Slider.Value .. Suffix, Slider.Max .. Suffix);
end
local X = math.ceil(Library:MapValue(Slider.Value, Slider.Min, Slider.Max, 0, Slider.MaxSize));
Fill.Size = UDim2.new(0, X, 1, 0);
HideBorderRight.Visible = not (X == Slider.MaxSize or X == 0);
end;
function Slider:OnChanged(Func)
Slider.Changed = Func;
Func(Slider.Value);
end;
local function Round(Value)
if Slider.Rounding == 0 then
return math.floor(Value);
end;
return tonumber(string.format('%.' .. Slider.Rounding .. 'f', Value))
end;
function Slider:GetValueFromXOffset(X)
return Round(Library:MapValue(X, 0, Slider.MaxSize, Slider.Min, Slider.Max));
end;
function Slider:SetValue(Str)
local Num = tonumber(Str);
if (not Num) then
return;
end;
Num = math.clamp(Num, Slider.Min, Slider.Max);
Slider.Value = Num;
Slider:Display();
Library:SafeCallback(Slider.Callback, Slider.Value);
Library:SafeCallback(Slider.Changed, Slider.Value);
end;
SliderInner.InputBegan:Connect(function(Input)
if Input.UserInputType == Enum.UserInputType.MouseButton1 and not Library:MouseIsOverOpenedFrame() then
local mPos = Mouse.X;
local gPos = Fill.Size.X.Offset;
local Diff = mPos - (Fill.AbsolutePosition.X + gPos);
while InputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) do
local nMPos = Mouse.X;
local nX = math.clamp(gPos + (nMPos - mPos) + Diff, 0, Slider.MaxSize);
local nValue = Slider:GetValueFromXOffset(nX);
local OldValue = Slider.Value;
Slider.Value = nValue;
Slider:Display();
if nValue ~= OldValue then
Library:SafeCallback(Slider.Callback, Slider.Value);
Library:SafeCallback(Slider.Changed, Slider.Value);
end;
RenderStepped:Wait();
end;
Library:AttemptSave();
end;
end);
Slider:Display();
Groupbox:AddBlank(Info.BlankSize or 6);
Groupbox:Resize();
Options[Idx] = Slider;
return Slider;
end;
function Funcs:AddDropdown(Idx, Info)
if Info.SpecialType == 'Player' then
Info.Values = GetPlayersString();
Info.AllowNull = true;
elseif Info.SpecialType == 'Team' then
Info.Values = GetTeamsString();
Info.AllowNull = true;
end;
assert(Info.Values, 'AddDropdown: Missing dropdown value list.');
assert(Info.AllowNull or Info.Default, 'AddDropdown: Missing default value. Pass `AllowNull` as true if this was intentional.')
if (not Info.Text) then
Info.Compact = true;
end;
local Dropdown = {
Values = Info.Values;
Value = Info.Multi and {};
Multi = Info.Multi;
Type = 'Dropdown';
SpecialType = Info.SpecialType; -- can be either 'Player' or 'Team'
Callback = Info.Callback or function(Value) end;
};
local Groupbox = self;
local Container = Groupbox.Container;
local RelativeOffset = 0;
if not Info.Compact then
local DropdownLabel = Library:CreateLabel({
Size = UDim2.new(1, 0, 0, 10);
TextSize = 14;
Text = Info.Text;
TextXAlignment = Enum.TextXAlignment.Left;
TextYAlignment = Enum.TextYAlignment.Bottom;
ZIndex = 5;
Parent = Container;
});
Groupbox:AddBlank(3);
end
for _, Element in next, Container:GetChildren() do
if not Element:IsA('UIListLayout') then
RelativeOffset = RelativeOffset + Element.Size.Y.Offset;
end;
end;
local DropdownOuter = Library:Create('Frame', {
BackgroundColor3 = Color3.new(0, 0, 0);
BorderColor3 = Color3.new(0, 0, 0);
Size = UDim2.new(1, -4, 0, 20);
ZIndex = 5;
Parent = Container;
});
Library:AddToRegistry(DropdownOuter, {
BorderColor3 = 'Black';
});
local DropdownInner = Library:Create('Frame', {
BackgroundColor3 = Library.MainColor;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 6;
Parent = DropdownOuter;
});
Library:AddToRegistry(DropdownInner, {
BackgroundColor3 = 'MainColor';
BorderColor3 = 'OutlineColor';
});
Library:Create('UIGradient', {
Color = ColorSequence.new({
ColorSequenceKeypoint.new(0, Color3.new(1, 1, 1)),
ColorSequenceKeypoint.new(1, Color3.fromRGB(212, 212, 212))
});
Rotation = 90;
Parent = DropdownInner;
});
local DropdownArrow = Library:Create('ImageLabel', {
AnchorPoint = Vector2.new(0, 0.5);
BackgroundTransparency = 1;
Position = UDim2.new(1, -16, 0.5, 0);
Size = UDim2.new(0, 12, 0, 12);
Image = 'http://www.roblox.com/asset/?id=6282522798';
ZIndex = 8;
Parent = DropdownInner;
});
local ItemList = Library:CreateLabel({
Position = UDim2.new(0, 5, 0, 0);
Size = UDim2.new(1, -5, 1, 0);
TextSize = 14;
Text = '--';
TextXAlignment = Enum.TextXAlignment.Left;
TextWrapped = true;
ZIndex = 7;
Parent = DropdownInner;
});
Library:OnHighlight(DropdownOuter, DropdownOuter,
{ BorderColor3 = 'AccentColor' },
{ BorderColor3 = 'Black' }
);
if type(Info.Tooltip) == 'string' then
Library:AddToolTip(Info.Tooltip, DropdownOuter)
end
local MAX_DROPDOWN_ITEMS = 8;
local ListOuter = Library:Create('Frame', {
BackgroundColor3 = Color3.new(0, 0, 0);
BorderColor3 = Color3.new(0, 0, 0);
ZIndex = 20;
Visible = false;
Parent = ScreenGui;
});
local function RecalculateListPosition()
ListOuter.Position = UDim2.fromOffset(DropdownOuter.AbsolutePosition.X, DropdownOuter.AbsolutePosition.Y + DropdownOuter.Size.Y.Offset + 1);
end;
local function RecalculateListSize(YSize)
ListOuter.Size = UDim2.fromOffset(DropdownOuter.AbsoluteSize.X, YSize or (MAX_DROPDOWN_ITEMS * 20 + 2))
end;
RecalculateListPosition();
RecalculateListSize();
DropdownOuter:GetPropertyChangedSignal('AbsolutePosition'):Connect(RecalculateListPosition);
local ListInner = Library:Create('Frame', {
BackgroundColor3 = Library.MainColor;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Inset;
BorderSizePixel = 0;
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 21;
Parent = ListOuter;
});
Library:AddToRegistry(ListInner, {
BackgroundColor3 = 'MainColor';
BorderColor3 = 'OutlineColor';
});
local Scrolling = Library:Create('ScrollingFrame', {
BackgroundTransparency = 1;
BorderSizePixel = 0;
CanvasSize = UDim2.new(0, 0, 0, 0);
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 21;
Parent = ListInner;
TopImage = 'rbxasset://textures/ui/Scroll/scroll-middle.png',
BottomImage = 'rbxasset://textures/ui/Scroll/scroll-middle.png',
ScrollBarThickness = 3,
ScrollBarImageColor3 = Library.AccentColor,
});
Library:AddToRegistry(Scrolling, {
ScrollBarImageColor3 = 'AccentColor'
})
Library:Create('UIListLayout', {
Padding = UDim.new(0, 0);
FillDirection = Enum.FillDirection.Vertical;
SortOrder = Enum.SortOrder.LayoutOrder;
Parent = Scrolling;
});
function Dropdown:Display()
local Values = Dropdown.Values;
local Str = '';
if Info.Multi then
for Idx, Value in next, Values do
if Dropdown.Value[Value] then
Str = Str .. Value .. ', ';
end;
end;
Str = Str:sub(1, #Str - 2);
else
Str = Dropdown.Value or '';
end;
ItemList.Text = (Str == '' and '--' or Str);
end;
function Dropdown:GetActiveValues()
if Info.Multi then
local T = {};
for Value, Bool in next, Dropdown.Value do
table.insert(T, Value);
end;
return T;
else
return Dropdown.Value and 1 or 0;
end;
end;
function Dropdown:BuildDropdownList()
local Values = Dropdown.Values;
local Buttons = {};
for _, Element in next, Scrolling:GetChildren() do
if not Element:IsA('UIListLayout') then
Element:Destroy();
end;
end;
local Count = 0;
for Idx, Value in next, Values do
local Table = {};
Count = Count + 1;
local Button = Library:Create('Frame', {
BackgroundColor3 = Library.MainColor;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Middle;
Size = UDim2.new(1, -1, 0, 20);
ZIndex = 23;
Active = true,
Parent = Scrolling;
});
Library:AddToRegistry(Button, {
BackgroundColor3 = 'MainColor';
BorderColor3 = 'OutlineColor';
});
local ButtonLabel = Library:CreateLabel({
Active = false;
Size = UDim2.new(1, -6, 1, 0);
Position = UDim2.new(0, 6, 0, 0);
TextSize = 14;
Text = Value;
TextXAlignment = Enum.TextXAlignment.Left;
ZIndex = 25;
Parent = Button;
});
Library:OnHighlight(Button, Button,
{ BorderColor3 = 'AccentColor', ZIndex = 24 },
{ BorderColor3 = 'OutlineColor', ZIndex = 23 }
);
local Selected;
if Info.Multi then
Selected = Dropdown.Value[Value];
else
Selected = Dropdown.Value == Value;
end;
function Table:UpdateButton()
if Info.Multi then
Selected = Dropdown.Value[Value];
else
Selected = Dropdown.Value == Value;
end;
ButtonLabel.TextColor3 = Selected and Library.AccentColor or Library.FontColor;
Library.RegistryMap[ButtonLabel].Properties.TextColor3 = Selected and 'AccentColor' or 'FontColor';
end;
ButtonLabel.InputBegan:Connect(function(Input)
if Input.UserInputType == Enum.UserInputType.MouseButton1 then
local Try = not Selected;
if Dropdown:GetActiveValues() == 1 and (not Try) and (not Info.AllowNull) then
else
if Info.Multi then
Selected = Try;
if Selected then
Dropdown.Value[Value] = true;
else
Dropdown.Value[Value] = nil;
end;
else
Selected = Try;
if Selected then
Dropdown.Value = Value;
else
Dropdown.Value = nil;
end;
for _, OtherButton in next, Buttons do
OtherButton:UpdateButton();
end;
end;
Table:UpdateButton();
Dropdown:Display();
Library:SafeCallback(Dropdown.Callback, Dropdown.Value);
Library:SafeCallback(Dropdown.Changed, Dropdown.Value);
Library:AttemptSave();
end;
end;
end);
Table:UpdateButton();
Dropdown:Display();
Buttons[Button] = Table;
end;
Scrolling.CanvasSize = UDim2.fromOffset(0, (Count * 20) + 1);
local Y = math.clamp(Count * 20, 0, MAX_DROPDOWN_ITEMS * 20) + 1;
RecalculateListSize(Y);
end;
function Dropdown:SetValues(NewValues)
if NewValues then
Dropdown.Values = NewValues;
end;
Dropdown:BuildDropdownList();
end;
function Dropdown:OpenDropdown()
ListOuter.Visible = true;
Library.OpenedFrames[ListOuter] = true;
DropdownArrow.Rotation = 180;
end;
function Dropdown:CloseDropdown()
ListOuter.Visible = false;
Library.OpenedFrames[ListOuter] = nil;
DropdownArrow.Rotation = 0;
end;
function Dropdown:OnChanged(Func)
Dropdown.Changed = Func;
Func(Dropdown.Value);
end;
function Dropdown:SetValue(Val)
if Dropdown.Multi then
local nTable = {};
for Value, Bool in next, Val do
if table.find(Dropdown.Values, Value) then
nTable[Value] = true
end;
end;
Dropdown.Value = nTable;
else
if (not Val) then
Dropdown.Value = nil;
elseif table.find(Dropdown.Values, Val) then
Dropdown.Value = Val;
end;
end;
Dropdown:BuildDropdownList();
Library:SafeCallback(Dropdown.Callback, Dropdown.Value);
Library:SafeCallback(Dropdown.Changed, Dropdown.Value);
end;
DropdownOuter.InputBegan:Connect(function(Input)
if Input.UserInputType == Enum.UserInputType.MouseButton1 and not Library:MouseIsOverOpenedFrame() then
if ListOuter.Visible then
Dropdown:CloseDropdown();
else
Dropdown:OpenDropdown();
end;
end;
end);
InputService.InputBegan:Connect(function(Input)
if Input.UserInputType == Enum.UserInputType.MouseButton1 then
local AbsPos, AbsSize = ListOuter.AbsolutePosition, ListOuter.AbsoluteSize;
if Mouse.X < AbsPos.X or Mouse.X > AbsPos.X + AbsSize.X
or Mouse.Y < (AbsPos.Y - 20 - 1) or Mouse.Y > AbsPos.Y + AbsSize.Y then
Dropdown:CloseDropdown();
end;
end;
end);
Dropdown:BuildDropdownList();
Dropdown:Display();
local Defaults = {}
if type(Info.Default) == 'string' then
local Idx = table.find(Dropdown.Values, Info.Default)
if Idx then
table.insert(Defaults, Idx)
end
elseif type(Info.Default) == 'table' then
for _, Value in next, Info.Default do
local Idx = table.find(Dropdown.Values, Value)
if Idx then
table.insert(Defaults, Idx)
end
end
elseif type(Info.Default) == 'number' and Dropdown.Values[Info.Default] ~= nil then
table.insert(Defaults, Info.Default)
end
if next(Defaults) then
for i = 1, #Defaults do
local Index = Defaults[i]
if Info.Multi then
Dropdown.Value[Dropdown.Values[Index]] = true
else
Dropdown.Value = Dropdown.Values[Index];
end
if (not Info.Multi) then break end
end
Dropdown:BuildDropdownList();
Dropdown:Display();
end
Groupbox:AddBlank(Info.BlankSize or 5);
Groupbox:Resize();
Options[Idx] = Dropdown;
return Dropdown;
end;
function Funcs:AddDependencyBox()
local Depbox = {
Dependencies = {};
};
local Groupbox = self;
local Container = Groupbox.Container;
local Holder = Library:Create('Frame', {
BackgroundTransparency = 1;
Size = UDim2.new(1, 0, 0, 0);
Visible = false;
Parent = Container;
});
local Frame = Library:Create('Frame', {
BackgroundTransparency = 1;
Size = UDim2.new(1, 0, 1, 0);
Visible = true;
Parent = Holder;
});
local Layout = Library:Create('UIListLayout', {
FillDirection = Enum.FillDirection.Vertical;
SortOrder = Enum.SortOrder.LayoutOrder;
Parent = Frame;
});
function Depbox:Resize()
Holder.Size = UDim2.new(1, 0, 0, Layout.AbsoluteContentSize.Y);
Groupbox:Resize();
end;
Layout:GetPropertyChangedSignal('AbsoluteContentSize'):Connect(function()
Depbox:Resize();
end);
Holder:GetPropertyChangedSignal('Visible'):Connect(function()
Depbox:Resize();
end);
function Depbox:Update()
for _, Dependency in next, Depbox.Dependencies do
local Elem = Dependency[1];
local Value = Dependency[2];
if Elem.Type == 'Toggle' and Elem.Value ~= Value then
Holder.Visible = false;
Depbox:Resize();
return;
end;
end;
Holder.Visible = true;
Depbox:Resize();
end;
function Depbox:SetupDependencies(Dependencies)
for _, Dependency in next, Dependencies do
assert(type(Dependency) == 'table', 'SetupDependencies: Dependency is not of type `table`.');
assert(Dependency[1], 'SetupDependencies: Dependency is missing element argument.');
assert(Dependency[2] ~= nil, 'SetupDependencies: Dependency is missing value argument.');
end;
Depbox.Dependencies = Dependencies;
Depbox:Update();
end;
Depbox.Container = Frame;
setmetatable(Depbox, BaseGroupbox);
table.insert(Library.DependencyBoxes, Depbox);
return Depbox;
end;
BaseGroupbox.__index = Funcs;
BaseGroupbox.__namecall = function(Table, Key, ...)
return Funcs[Key](...);
end;
end;
-- < Create other UI elements >
do
Library.NotificationArea = Library:Create('Frame', {
BackgroundTransparency = 1;
Position = UDim2.new(0, 0, 0, 40);
Size = UDim2.new(0, 300, 0, 200);
ZIndex = 100;
Parent = ScreenGui;
});
Library:Create('UIListLayout', {
Padding = UDim.new(0, 4);
FillDirection = Enum.FillDirection.Vertical;
SortOrder = Enum.SortOrder.LayoutOrder;
Parent = Library.NotificationArea;
});
local WatermarkOuter = Library:Create('Frame', {
BorderColor3 = Color3.new(0, 0, 0);
Position = UDim2.new(0, 100, 0, -25);
Size = UDim2.new(0, 213, 0, 20);
ZIndex = 200;
Visible = false;
Parent = ScreenGui;
});
local WatermarkInner = Library:Create('Frame', {
BackgroundColor3 = Library.MainColor;
BorderColor3 = Library.AccentColor;
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 201;
Parent = WatermarkOuter;
});
Library:AddToRegistry(WatermarkInner, {
BorderColor3 = 'AccentColor';
});
local InnerFrame = Library:Create('Frame', {
BackgroundColor3 = Color3.new(1, 1, 1);
BorderSizePixel = 0;
Position = UDim2.new(0, 1, 0, 1);
Size = UDim2.new(1, -2, 1, -2);
ZIndex = 202;
Parent = WatermarkInner;
});
local Gradient = Library:Create('UIGradient', {
Color = ColorSequence.new({
ColorSequenceKeypoint.new(0, Library:GetDarkerColor(Library.MainColor)),
ColorSequenceKeypoint.new(1, Library.MainColor),
});
Rotation = -90;
Parent = InnerFrame;
});
Library:AddToRegistry(Gradient, {
Color = function()
return ColorSequence.new({
ColorSequenceKeypoint.new(0, Library:GetDarkerColor(Library.MainColor)),
ColorSequenceKeypoint.new(1, Library.MainColor),
});
end
});
local WatermarkLabel = Library:CreateLabel({
Position = UDim2.new(0, 5, 0, 0);
Size = UDim2.new(1, -4, 1, 0);
TextSize = 14;
TextXAlignment = Enum.TextXAlignment.Left;
ZIndex = 203;
Parent = InnerFrame;
});
Library.Watermark = WatermarkOuter;
Library.WatermarkText = WatermarkLabel;
Library:MakeDraggable(Library.Watermark);
local KeybindOuter = Library:Create('Frame', {
AnchorPoint = Vector2.new(0, 0.5);
BorderColor3 = Color3.new(0, 0, 0);
Position = UDim2.new(0, 10, 0.5, 0);
Size = UDim2.new(0, 210, 0, 20);
Visible = false;
ZIndex = 100;
Parent = ScreenGui;
});
local KeybindInner = Library:Create('Frame', {
BackgroundColor3 = Library.MainColor;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 101;
Parent = KeybindOuter;
});
Library:AddToRegistry(KeybindInner, {
BackgroundColor3 = 'MainColor';
BorderColor3 = 'OutlineColor';
}, true);
local ColorFrame = Library:Create('Frame', {
BackgroundColor3 = Library.AccentColor;
BorderSizePixel = 0;
Size = UDim2.new(1, 0, 0, 2);
ZIndex = 102;
Parent = KeybindInner;
});
Library:AddToRegistry(ColorFrame, {
BackgroundColor3 = 'AccentColor';
}, true);
local KeybindLabel = Library:CreateLabel({
Size = UDim2.new(1, 0, 0, 20);
Position = UDim2.fromOffset(5, 2),
TextXAlignment = Enum.TextXAlignment.Left,
Text = 'Keybinds';
ZIndex = 104;
Parent = KeybindInner;
});
local KeybindContainer = Library:Create('Frame', {
BackgroundTransparency = 1;
Size = UDim2.new(1, 0, 1, -20);
Position = UDim2.new(0, 0, 0, 20);
ZIndex = 1;
Parent = KeybindInner;
});
Library:Create('UIListLayout', {
FillDirection = Enum.FillDirection.Vertical;
SortOrder = Enum.SortOrder.LayoutOrder;
Parent = KeybindContainer;
});
Library:Create('UIPadding', {
PaddingLeft = UDim.new(0, 5),
Parent = KeybindContainer,
})
Library.KeybindFrame = KeybindOuter;
Library.KeybindContainer = KeybindContainer;
Library:MakeDraggable(KeybindOuter);
end;
function Library:SetWatermarkVisibility(Bool)
Library.Watermark.Visible = Bool;
end;
function Library:SetWatermark(Text)
local X, Y = Library:GetTextBounds(Text, Library.Font, 14);
Library.Watermark.Size = UDim2.new(0, X + 15, 0, (Y * 1.5) + 3);
Library:SetWatermarkVisibility(true)
Library.WatermarkText.Text = Text;
end;
function Library:Notify(Text, Time)
local XSize, YSize = Library:GetTextBounds(Text, Library.Font, 14);
YSize = YSize + 7
local NotifyOuter = Library:Create('Frame', {
BorderColor3 = Color3.new(0, 0, 0);
Position = UDim2.new(0, 100, 0, 10);
Size = UDim2.new(0, 0, 0, YSize);
ClipsDescendants = true;
ZIndex = 100;
Parent = Library.NotificationArea;
});
local NotifyInner = Library:Create('Frame', {
BackgroundColor3 = Library.MainColor;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 101;
Parent = NotifyOuter;
});
Library:AddToRegistry(NotifyInner, {
BackgroundColor3 = 'MainColor';
BorderColor3 = 'OutlineColor';
}, true);
local InnerFrame = Library:Create('Frame', {
BackgroundColor3 = Color3.new(1, 1, 1);
BorderSizePixel = 0;
Position = UDim2.new(0, 1, 0, 1);
Size = UDim2.new(1, -2, 1, -2);
ZIndex = 102;
Parent = NotifyInner;
});
local Gradient = Library:Create('UIGradient', {
Color = ColorSequence.new({
ColorSequenceKeypoint.new(0, Library:GetDarkerColor(Library.MainColor)),
ColorSequenceKeypoint.new(1, Library.MainColor),
});
Rotation = -90;
Parent = InnerFrame;
});
Library:AddToRegistry(Gradient, {
Color = function()
return ColorSequence.new({
ColorSequenceKeypoint.new(0, Library:GetDarkerColor(Library.MainColor)),
ColorSequenceKeypoint.new(1, Library.MainColor),
});
end
});
local NotifyLabel = Library:CreateLabel({
Position = UDim2.new(0, 4, 0, 0);
Size = UDim2.new(1, -4, 1, 0);
Text = Text;
TextXAlignment = Enum.TextXAlignment.Left;
TextSize = 14;
ZIndex = 103;
Parent = InnerFrame;
});
local LeftColor = Library:Create('Frame', {
BackgroundColor3 = Library.AccentColor;
BorderSizePixel = 0;
Position = UDim2.new(0, -1, 0, -1);
Size = UDim2.new(0, 3, 1, 2);
ZIndex = 104;
Parent = NotifyOuter;
});
Library:AddToRegistry(LeftColor, {
BackgroundColor3 = 'AccentColor';
}, true);
pcall(NotifyOuter.TweenSize, NotifyOuter, UDim2.new(0, XSize + 8 + 4, 0, YSize), 'Out', 'Quad', 0.4, true);
task.spawn(function()
wait(Time or 5);
pcall(NotifyOuter.TweenSize, NotifyOuter, UDim2.new(0, 0, 0, YSize), 'Out', 'Quad', 0.4, true);
wait(0.4);
NotifyOuter:Destroy();
end);
end;
function Library:CreateWindow(...)
local Arguments = { ... }
local Config = { AnchorPoint = Vector2.zero }
if type(...) == 'table' then
Config = ...;
else
Config.Title = Arguments[1]
Config.AutoShow = Arguments[2] or false;
end
if type(Config.Title) ~= 'string' then Config.Title = 'No title' end
if type(Config.TabPadding) ~= 'number' then Config.TabPadding = 0 end
if type(Config.MenuFadeTime) ~= 'number' then Config.MenuFadeTime = 0.2 end
if typeof(Config.Position) ~= 'UDim2' then Config.Position = UDim2.fromOffset(175, 50) end
if typeof(Config.Size) ~= 'UDim2' then Config.Size = UDim2.fromOffset(550, 600) end
if Config.Center then
Config.AnchorPoint = Vector2.new(0.5, 0.5)
Config.Position = UDim2.fromScale(0.5, 0.5)
end
local Window = {
Tabs = {};
};
local Outer = Library:Create('Frame', {
AnchorPoint = Config.AnchorPoint,
BackgroundColor3 = Color3.new(0, 0, 0);
BorderSizePixel = 0;
Position = Config.Position,
Size = Config.Size,
Visible = false;
ZIndex = 1;
Parent = ScreenGui;
});
Library:MakeDraggable(Outer, 25);
local Inner = Library:Create('Frame', {
BackgroundColor3 = Library.MainColor;
BorderColor3 = Library.AccentColor;
BorderMode = Enum.BorderMode.Inset;
Position = UDim2.new(0, 1, 0, 1);
Size = UDim2.new(1, -2, 1, -2);
ZIndex = 1;
Parent = Outer;
});
Library:AddToRegistry(Inner, {
BackgroundColor3 = 'MainColor';
BorderColor3 = 'AccentColor';
});
local WindowLabel = Library:CreateLabel({
Position = UDim2.new(0, 7, 0, 0);
Size = UDim2.new(0, 0, 0, 25);
Text = Config.Title or '';
TextXAlignment = Enum.TextXAlignment.Left;
ZIndex = 1;
Parent = Inner;
});
local MainSectionOuter = Library:Create('Frame', {
BackgroundColor3 = Library.BackgroundColor;
BorderColor3 = Library.OutlineColor;
Position = UDim2.new(0, 8, 0, 25);
Size = UDim2.new(1, -16, 1, -33);
ZIndex = 1;
Parent = Inner;
});
Library:AddToRegistry(MainSectionOuter, {
BackgroundColor3 = 'BackgroundColor';
BorderColor3 = 'OutlineColor';
});
local MainSectionInner = Library:Create('Frame', {
BackgroundColor3 = Library.BackgroundColor;
BorderColor3 = Color3.new(0, 0, 0);
BorderMode = Enum.BorderMode.Inset;
Position = UDim2.new(0, 0, 0, 0);
Size = UDim2.new(1, 0, 1, 0);
ZIndex = 1;
Parent = MainSectionOuter;
});
Library:AddToRegistry(MainSectionInner, {
BackgroundColor3 = 'BackgroundColor';
});
local TabArea = Library:Create('Frame', {
BackgroundTransparency = 1;
Position = UDim2.new(0, 8, 0, 8);
Size = UDim2.new(1, -16, 0, 21);
ZIndex = 1;
Parent = MainSectionInner;
});
local TabListLayout = Library:Create('UIListLayout', {
Padding = UDim.new(0, Config.TabPadding);
FillDirection = Enum.FillDirection.Horizontal;
SortOrder = Enum.SortOrder.LayoutOrder;
Parent = TabArea;
});
local TabContainer = Library:Create('Frame', {
BackgroundColor3 = Library.MainColor;
BorderColor3 = Library.OutlineColor;
Position = UDim2.new(0, 8, 0, 30);
Size = UDim2.new(1, -16, 1, -38);
ZIndex = 2;
Parent = MainSectionInner;
});
Library:AddToRegistry(TabContainer, {
BackgroundColor3 = 'MainColor';
BorderColor3 = 'OutlineColor';
});
function Window:SetWindowTitle(Title)
WindowLabel.Text = Title;
end;
function Window:AddTab(Name)
local Tab = {
Groupboxes = {};
Tabboxes = {};
};
local TabButtonWidth = Library:GetTextBounds(Name, Library.Font, 16);
local TabButton = Library:Create('Frame', {
BackgroundColor3 = Library.BackgroundColor;
BorderColor3 = Library.OutlineColor;
Size = UDim2.new(0, TabButtonWidth + 8 + 4, 1, 0);
ZIndex = 1;
Parent = TabArea;
});
Library:AddToRegistry(TabButton, {
BackgroundColor3 = 'BackgroundColor';
BorderColor3 = 'OutlineColor';
});
local TabButtonLabel = Library:CreateLabel({
Position = UDim2.new(0, 0, 0, 0);
Size = UDim2.new(1, 0, 1, -1);
Text = Name;
ZIndex = 1;
Parent = TabButton;
});
local Blocker = Library:Create('Frame', {
BackgroundColor3 = Library.MainColor;
BorderSizePixel = 0;
Position = UDim2.new(0, 0, 1, 0);
Size = UDim2.new(1, 0, 0, 1);
BackgroundTransparency = 1;
ZIndex = 3;
Parent = TabButton;
});
Library:AddToRegistry(Blocker, {
BackgroundColor3 = 'MainColor';
});
local TabFrame = Library:Create('Frame', {
Name = 'TabFrame',
BackgroundTransparency = 1;
Position = UDim2.new(0, 0, 0, 0);
Size = UDim2.new(1, 0, 1, 0);
Visible = false;
ZIndex = 2;
Parent = TabContainer;
});
local LeftSide = Library:Create('ScrollingFrame', {
BackgroundTransparency = 1;
BorderSizePixel = 0;
Position = UDim2.new(0, 8 - 1, 0, 8 - 1);
Size = UDim2.new(0.5, -12 + 2, 0, 507 + 2);
CanvasSize = UDim2.new(0, 0, 0, 0);
BottomImage = '';
TopImage = '';
ScrollBarThickness = 0;
ZIndex = 2;
Parent = TabFrame;
});
local RightSide = Library:Create('ScrollingFrame', {
BackgroundTransparency = 1;
BorderSizePixel = 0;
Position = UDim2.new(0.5, 4 + 1, 0, 8 - 1);
Size = UDim2.new(0.5, -12 + 2, 0, 507 + 2);
CanvasSize = UDim2.new(0, 0, 0, 0);
BottomImage = '';
TopImage = '';
ScrollBarThickness = 0;
ZIndex = 2;
Parent = TabFrame;
});
Library:Create('UIListLayout', {
Padding = UDim.new(0, 8);
FillDirection = Enum.FillDirection.Vertical;
SortOrder = Enum.SortOrder.LayoutOrder;
HorizontalAlignment = Enum.HorizontalAlignment.Center;
Parent = LeftSide;
});
Library:Create('UIListLayout', {
Padding = UDim.new(0, 8);
FillDirection = Enum.FillDirection.Vertical;
SortOrder = Enum.SortOrder.LayoutOrder;
HorizontalAlignment = Enum.HorizontalAlignment.Center;
Parent = RightSide;
});
for _, Side in next, { LeftSide, RightSide } do
Side:WaitForChild('UIListLayout'):GetPropertyChangedSignal('AbsoluteContentSize'):Connect(function()
Side.CanvasSize = UDim2.fromOffset(0, Side.UIListLayout.AbsoluteContentSize.Y);
end);
end;
function Tab:ShowTab()
for _, Tab in next, Window.Tabs do
Tab:HideTab();
end;
Blocker.BackgroundTransparency = 0;
TabButton.BackgroundColor3 = Library.MainColor;
Library.RegistryMap[TabButton].Properties.BackgroundColor3 = 'MainColor';
TabFrame.Visible = true;
end;
function Tab:HideTab()
Blocker.BackgroundTransparency = 1;
TabButton.BackgroundColor3 = Library.BackgroundColor;
Library.RegistryMap[TabButton].Properties.BackgroundColor3 = 'BackgroundColor';
TabFrame.Visible = false;
end;
function Tab:SetLayoutOrder(Position)
TabButton.LayoutOrder = Position;
TabListLayout:ApplyLayout();
end;
function Tab:AddGroupbox(Info)
local Groupbox = {};
local BoxOuter = Library:Create('Frame', {
BackgroundColor3 = Library.BackgroundColor;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, 0, 0, 507 + 2);
ZIndex = 2;
Parent = Info.Side == 1 and LeftSide or RightSide;
});
Library:AddToRegistry(BoxOuter, {
BackgroundColor3 = 'BackgroundColor';
BorderColor3 = 'OutlineColor';
});
local BoxInner = Library:Create('Frame', {
BackgroundColor3 = Library.BackgroundColor;
BorderColor3 = Color3.new(0, 0, 0);
-- BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, -2, 1, -2);
Position = UDim2.new(0, 1, 0, 1);
ZIndex = 4;
Parent = BoxOuter;
});
Library:AddToRegistry(BoxInner, {
BackgroundColor3 = 'BackgroundColor';
});
local Highlight = Library:Create('Frame', {
BackgroundColor3 = Library.AccentColor;
BorderSizePixel = 0;
Size = UDim2.new(1, 0, 0, 2);
ZIndex = 5;
Parent = BoxInner;
});
Library:AddToRegistry(Highlight, {
BackgroundColor3 = 'AccentColor';
});
local GroupboxLabel = Library:CreateLabel({
Size = UDim2.new(1, 0, 0, 18);
Position = UDim2.new(0, 4, 0, 2);
TextSize = 14;
Text = Info.Name;
TextXAlignment = Enum.TextXAlignment.Left;
ZIndex = 5;
Parent = BoxInner;
});
local Container = Library:Create('Frame', {
BackgroundTransparency = 1;
Position = UDim2.new(0, 4, 0, 20);
Size = UDim2.new(1, -4, 1, -20);
ZIndex = 1;
Parent = BoxInner;
});
Library:Create('UIListLayout', {
FillDirection = Enum.FillDirection.Vertical;
SortOrder = Enum.SortOrder.LayoutOrder;
Parent = Container;
});
function Groupbox:Resize()
local Size = 0;
for _, Element in next, Groupbox.Container:GetChildren() do
if (not Element:IsA('UIListLayout')) and Element.Visible then
Size = Size + Element.Size.Y.Offset;
end;
end;
BoxOuter.Size = UDim2.new(1, 0, 0, 20 + Size + 2 + 2);
end;
Groupbox.Container = Container;
setmetatable(Groupbox, BaseGroupbox);
Groupbox:AddBlank(3);
Groupbox:Resize();
Tab.Groupboxes[Info.Name] = Groupbox;
return Groupbox;
end;
function Tab:AddLeftGroupbox(Name)
return Tab:AddGroupbox({ Side = 1; Name = Name; });
end;
function Tab:AddRightGroupbox(Name)
return Tab:AddGroupbox({ Side = 2; Name = Name; });
end;
function Tab:AddTabbox(Info)
local Tabbox = {
Tabs = {};
};
local BoxOuter = Library:Create('Frame', {
BackgroundColor3 = Library.BackgroundColor;
BorderColor3 = Library.OutlineColor;
BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, 0, 0, 0);
ZIndex = 2;
Parent = Info.Side == 1 and LeftSide or RightSide;
});
Library:AddToRegistry(BoxOuter, {
BackgroundColor3 = 'BackgroundColor';
BorderColor3 = 'OutlineColor';
});
local BoxInner = Library:Create('Frame', {
BackgroundColor3 = Library.BackgroundColor;
BorderColor3 = Color3.new(0, 0, 0);
-- BorderMode = Enum.BorderMode.Inset;
Size = UDim2.new(1, -2, 1, -2);
Position = UDim2.new(0, 1, 0, 1);
ZIndex = 4;
Parent = BoxOuter;
});
Library:AddToRegistry(BoxInner, {
BackgroundColor3 = 'BackgroundColor';
});
local Highlight = Library:Create('Frame', {
BackgroundColor3 = Library.AccentColor;
BorderSizePixel = 0;
Size = UDim2.new(1, 0, 0, 2);
ZIndex = 10;
Parent = BoxInner;
});
Library:AddToRegistry(Highlight, {
BackgroundColor3 = 'AccentColor';
});
local TabboxButtons = Library:Create('Frame', {
BackgroundTransparency = 1;
Position = UDim2.new(0, 0, 0, 1);
Size = UDim2.new(1, 0, 0, 18);
ZIndex = 5;
Parent = BoxInner;
});
Library:Create('UIListLayout', {
FillDirection = Enum.FillDirection.Horizontal;
HorizontalAlignment = Enum.HorizontalAlignment.Left;
SortOrder = Enum.SortOrder.LayoutOrder;
Parent = TabboxButtons;
});
function Tabbox:AddTab(Name)
local Tab = {};
local Button = Library:Create('Frame', {
BackgroundColor3 = Library.MainColor;
BorderColor3 = Color3.new(0, 0, 0);
Size = UDim2.new(0.5, 0, 1, 0);
ZIndex = 6;
Parent = TabboxButtons;
});
Library:AddToRegistry(Button, {
BackgroundColor3 = 'MainColor';
});
local ButtonLabel = Library:CreateLabel({
Size = UDim2.new(1, 0, 1, 0);
TextSize = 14;
Text = Name;
TextXAlignment = Enum.TextXAlignment.Center;
ZIndex = 7;
Parent = Button;
});
local Block = Library:Create('Frame', {
BackgroundColor3 = Library.BackgroundColor;
BorderSizePixel = 0;
Position = UDim2.new(0, 0, 1, 0);
Size = UDim2.new(1, 0, 0, 1);
Visible = false;
ZIndex = 9;
Parent = Button;
});
Library:AddToRegistry(Block, {
BackgroundColor3 = 'BackgroundColor';
});
local Container = Library:Create('Frame', {
BackgroundTransparency = 1;
Position = UDim2.new(0, 4, 0, 20);
Size = UDim2.new(1, -4, 1, -20);
ZIndex = 1;
Visible = false;
Parent = BoxInner;
});
Library:Create('UIListLayout', {
FillDirection = Enum.FillDirection.Vertical;
SortOrder = Enum.SortOrder.LayoutOrder;
Parent = Container;
});
function Tab:Show()
for _, Tab in next, Tabbox.Tabs do
Tab:Hide();
end;
Container.Visible = true;
Block.Visible = true;
Button.BackgroundColor3 = Library.BackgroundColor;
Library.RegistryMap[Button].Properties.BackgroundColor3 = 'BackgroundColor';
Tab:Resize();
end;
function Tab:Hide()
Container.Visible = false;
Block.Visible = false;
Button.BackgroundColor3 = Library.MainColor;
Library.RegistryMap[Button].Properties.BackgroundColor3 = 'MainColor';
end;
function Tab:Resize()
local TabCount = 0;
for _, Tab in next, Tabbox.Tabs do
TabCount = TabCount + 1;
end;
for _, Button in next, TabboxButtons:GetChildren() do
if not Button:IsA('UIListLayout') then
Button.Size = UDim2.new(1 / TabCount, 0, 1, 0);
end;
end;
if (not Container.Visible) then
return;
end;
local Size = 0;
for _, Element in next, Tab.Container:GetChildren() do
if (not Element:IsA('UIListLayout')) and Element.Visible then
Size = Size + Element.Size.Y.Offset;
end;
end;
BoxOuter.Size = UDim2.new(1, 0, 0, 20 + Size + 2 + 2);
end;
Button.InputBegan:Connect(function(Input)
if Input.UserInputType == Enum.UserInputType.MouseButton1 and not Library:MouseIsOverOpenedFrame() then
Tab:Show();
Tab:Resize();
end;
end);
Tab.Container = Container;
Tabbox.Tabs[Name] = Tab;
setmetatable(Tab, BaseGroupbox);
Tab:AddBlank(3);
Tab:Resize();
-- Show first tab (number is 2 cus of the UIListLayout that also sits in that instance)
if #TabboxButtons:GetChildren() == 2 then
Tab:Show();
end;
return Tab;
end;
Tab.Tabboxes[Info.Name or ''] = Tabbox;
return Tabbox;
end;
function Tab:AddLeftTabbox(Name)
return Tab:AddTabbox({ Name = Name, Side = 1; });
end;
function Tab:AddRightTabbox(Name)
return Tab:AddTabbox({ Name = Name, Side = 2; });
end;
TabButton.InputBegan:Connect(function(Input)
if Input.UserInputType == Enum.UserInputType.MouseButton1 then
Tab:ShowTab();
end;
end);
-- This was the first tab added, so we show it by default.
if #TabContainer:GetChildren() == 1 then
Tab:ShowTab();
end;
Window.Tabs[Name] = Tab;
return Tab;
end;
local ModalElement = Library:Create('TextButton', {
BackgroundTransparency = 1;
Size = UDim2.new(0, 0, 0, 0);
Visible = true;
Text = '';
Modal = false;
Parent = ScreenGui;
});
local TransparencyCache = {};
local Toggled = false;
local Fading = false;
function Library:Toggle()
if Fading then
return;
end;
local FadeTime = Config.MenuFadeTime;
Fading = true;
Toggled = (not Toggled);
ModalElement.Modal = Toggled;
if Toggled then
-- A bit scuffed, but if we're going from not toggled -> toggled we want to show the frame immediately so that the fade is visible.
Outer.Visible = true;
task.spawn(function()
-- TODO: add cursor fade?
local State = InputService.MouseIconEnabled;
local Cursor = Drawing.new('Triangle');
Cursor.Thickness = 1;
Cursor.Filled = true;
Cursor.Visible = true;
local CursorOutline = Drawing.new('Triangle');
CursorOutline.Thickness = 1;
CursorOutline.Filled = false;
CursorOutline.Color = Color3.new(0, 0, 0);
CursorOutline.Visible = true;
while Toggled and ScreenGui.Parent do
InputService.MouseIconEnabled = false;
local mPos = InputService:GetMouseLocation();
Cursor.Color = Library.AccentColor;
Cursor.PointA = Vector2.new(mPos.X, mPos.Y);
Cursor.PointB = Vector2.new(mPos.X + 16, mPos.Y + 6);
Cursor.PointC = Vector2.new(mPos.X + 6, mPos.Y + 16);
CursorOutline.PointA = Cursor.PointA;
CursorOutline.PointB = Cursor.PointB;
CursorOutline.PointC = Cursor.PointC;
RenderStepped:Wait();
end;
InputService.MouseIconEnabled = State;
Cursor:Remove();
CursorOutline:Remove();
end);
end;
for _, Desc in next, Outer:GetDescendants() do
local Properties = {};
if Desc:IsA('ImageLabel') then
table.insert(Properties, 'ImageTransparency');
table.insert(Properties, 'BackgroundTransparency');
elseif Desc:IsA('TextLabel') or Desc:IsA('TextBox') then
table.insert(Properties, 'TextTransparency');
elseif Desc:IsA('Frame') or Desc:IsA('ScrollingFrame') then
table.insert(Properties, 'BackgroundTransparency');
elseif Desc:IsA('UIStroke') then
table.insert(Properties, 'Transparency');
end;
local Cache = TransparencyCache[Desc];
if (not Cache) then
Cache = {};
TransparencyCache[Desc] = Cache;
end;
for _, Prop in next, Properties do
if not Cache[Prop] then
Cache[Prop] = Desc[Prop];
end;
if Cache[Prop] == 1 then
continue;
end;
TweenService:Create(Desc, TweenInfo.new(FadeTime, Enum.EasingStyle.Linear), { [Prop] = Toggled and Cache[Prop] or 1 }):Play();
end;
end;
task.wait(FadeTime);
Outer.Visible = Toggled;
Fading = false;
end
Library:GiveSignal(InputService.InputBegan:Connect(function(Input, Processed)
if type(Library.ToggleKeybind) == 'table' and Library.ToggleKeybind.Type == 'KeyPicker' then
if Input.UserInputType == Enum.UserInputType.Keyboard and Input.KeyCode.Name == Library.ToggleKeybind.Value then
task.spawn(Library.Toggle)
end
elseif Input.KeyCode == Enum.KeyCode.RightControl or (Input.KeyCode == Enum.KeyCode.RightShift and (not Processed)) then
task.spawn(Library.Toggle)
end
end))
if Config.AutoShow then task.spawn(Library.Toggle) end
Window.Holder = Outer;
return Window;
end;
local function OnPlayerChange()
local PlayerList = GetPlayersString();
for _, Value in next, Options do
if Value.Type == 'Dropdown' and Value.SpecialType == 'Player' then
Value:SetValues(PlayerList);
end;
end;
end;
Players.PlayerAdded:Connect(OnPlayerChange);
Players.PlayerRemoving:Connect(OnPlayerChange);
getgenv().Library = Library
return Library