يمنحك استوديو القدرة على إنشاء أدوات مخصصة واستخدامها كأدوات وإضافات. تعمل هذه الأدوات كالنوافذ/الألواح المخصصة في استوديو، ويمكنك تثبيتها داخل واجهتك أو جعلها تطفو كنوافذ منفصلة.
إنشاء واجهات أدوات
تبدأ جميع أدوات الاستوديو ككائنات DockWidgetPluginGui، والتي يمكنك ملؤها بـ GuiObjects مثل تسميات النصوص والأزرار. لإنشاء واجهة أداة فارغة، استدعِ الدالة CreateDockWidgetPluginGui() مع تمرير معرف وكائن DockWidgetPluginGuiInfo.
لاحظ أن مُنشئ DockWidgetPluginGuiInfo.new() يتوقع معلماته بترتيب محدد كما يلي:
| # | الخاصية | النوع | الوصف |
|---|---|---|---|
| 1 | Enum.InitialDockState | التعداد | واحد من إدخالات Enum.InitialDockState. |
| 2 | InitialEnabled | Boolean | الحالة الأولية المفعلة (المرئية) لواجهة الأداة. |
| 3 | InitialEnabledShouldOverrideRestore | Boolean | إذا كانت صحيحة، فإن قيمة InitialEnabled تتجاوز حالة التفعيل المحفوظة مسبقًا. |
| 4 | FloatingXSize | Integer | العرض الأولي للواجهة عندما يتم تعيين InitialDockState إلى Enum.InitialDockState.Float. |
| 5 | FloatingYSize | Integer | الارتفاع الأولي للواجهة عندما يتم تعيين InitialDockState إلى Enum.InitialDockState.Float. |
| 6 | MinWidth | Integer | أقل عرض للواجهة، مع بعض الفروقات حسب النظام الأساسي. |
| 7 | MinHeight | Integer | أقل ارتفاع للواجهة، مع بعض الفروقات حسب النظام الأساسي. |
-- إنشاء كائن جديد "DockWidgetPluginGuiInfo"local widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, -- سيتم تهيئة الأداة في لوحة عائمةtrue, -- سيتم تفعيل الأداة ابتدائيًاfalse, -- لا تتجاوز حالة التفعيل السابقة200, -- العرض الافتراضي للنافذة العائمة300, -- الارتفاع الافتراضي للنافذة العائمة150, -- أقل عرض للنافذة العائمة150 -- أقل ارتفاع للنافذة العائمة)-- إنشاء واجهة أداة جديدةlocal testWidget = plugin:CreateDockWidgetPluginGui("TestWidget", widgetInfo)testWidget.Title = "الأداة التجريبية" -- عنوان الأداة اختياري
تخصيص واجهة الأداة
بمجرد إنشاء أداة، يمكنك تخصيص واجهة المستخدم الخاصة بها باستخدام GuiObjects مثل تسميات النص التوضيحية أو أزرار الصور التفاعلية. على سبيل المثال، الكود التالي يضيف TextButton أساسي إلى نافذة الواجهة:
-- إنشاء واجهة أداة جديدةlocal testWidget = plugin:CreateDockWidgetPluginGui("TestWidget", widgetInfo)testWidget.Title = "الأداة التجريبية" -- عنوان الأداة اختياريlocal testButton = Instance.new("TextButton")testButton.BorderSizePixel = 0testButton.TextSize = 20testButton.TextColor3 = Color3.new(1,0.2,0.4)testButton.AnchorPoint = Vector2.new(0.5,0.5)testButton.Size = UDim2.new(1,0,1,0)testButton.Position = UDim2.new(0.5,0,0.5,0)testButton.SizeConstraint = Enum.SizeConstraint.RelativeYYtestButton.Text = "اضغط علي"testButton.Parent = testWidget
تغيير ثيمات ألوان الاستوديو
تتناسب أدوات استوديو الفعّالة مع إعداد ثيم استوديو وتتكيف ديناميكيًا عند تغيير الثيم. على سبيل المثال، إذا كان المطور يستخدم الثيم الداكن، يجب أن يبدو لون خلفية الأداة، والصور، وتسميات النصوص لطيفًا مع الألوان الأصلية لموضوع الاستوديو.
يستخدم الكود التالي دالة syncGuiColors() التي يتم استدعاؤها في البداية مع جدول من كائنات واجهة المستخدم للمزامنة. داخل الدالة، تقوم دالة setColors() المتداخلة بالتكرار عبر الكائنات وتزامن جوانب معينة منها باستخدام GetColor() مع تعداد Enum.StudioStyleGuideColor. يتم تشغيل دالة setColors() فورًا لمزامنة موضوع الاستوديو، ثم يتم ربطها بحدث ThemeChanged لاكتشاف تغييرات الثيم المستقبلية.
testButton.Parent = testWidget
local function syncGuiColors(objects)
local function setColors()
for _, guiObject in objects do
-- مزامنة لون الخلفية
guiObject.BackgroundColor3 = settings().Studio.Theme:GetColor(Enum.StudioStyleGuideColor.MainBackground)
-- مزامنة لون النص
guiObject.TextColor3 = settings().Studio.Theme:GetColor(Enum.StudioStyleGuideColor.MainText)
end
end
-- قم بتشغيل دالة 'setColors()' لمزامنة الألوان ابتدائيًا
setColors()
-- ربط حدث 'ThemeChanged' بدالة 'setColors()'
settings().Studio.ThemeChanged:Connect(setColors)
end
-- قم بتشغيل دالة 'syncGuiColors()' لمزامنة ألوان الكائنات المقدمة
syncGuiColors({testButton})
تخصيص مؤشرات الماوس
لتحسين التفاعل المتوقع مع عناصر الأداة، يمكنك تعيين مؤشرات الماوس الخاصة بالنظام إلى أحداث واجهة المستخدم، مثل MouseEnter و MouseLeave. يوضح الكود التالي كيفية ربط دالة لأحداث MouseEnter و MouseLeave لـ testButton لتغيير مؤشر الماوس:
local function setCursor(cursorAsset)
plugin:GetMouse().Icon = cursorAsset
end
testButton.MouseEnter:Connect(function()
setCursor("rbxasset://SystemCursors/PointingHand")
end)
testButton.MouseLeave:Connect(function()
setCursor("")
end)
راجع الجدول التالي للحصول على قائمة بمؤشرات الماوس وحالات استخدامها المحتملة:
| رمز مؤشر الماوس | الأصل | حالة الاستخدام |
|---|---|---|
| rbxasset://SystemCursors/Arrow | النقر الافتراضي والتحديد. | |
| rbxasset://SystemCursors/PointingHand | التأشير على رابط/زر نشط. | |
| rbxasset://SystemCursors/OpenHand | التأشير على عنصر قابل للسحب. | |
| rbxasset://SystemCursors/ClosedHand | سحب عنصر. | |
| rbxasset://SystemCursors/IBeam | التأشير في حقل نص. | |
| rbxasset://SystemCursors/SizeNS | التأشير على مقبض تغيير الحجم العمودي. | |
| rbxasset://SystemCursors/SizeEW | التأشير على مقبض تغيير الحجم الأفقي. | |
| rbxasset://SystemCursors/SizeNESW | التأشير على مقبض تغيير الحجم في الزاوية. | |
| rbxasset://SystemCursors/SizeNWSE | التأشير على مقبض تغيير الحجم في الزاوية. | |
| rbxasset://SystemCursors/SizeAll | التأشير على مقبض تغيير الحجم متعدد الاتجاهات. | |
| rbxasset://SystemCursors/SplitNS | التأشير على مقبض "تقسيم" عمودي. | |
| rbxasset://SystemCursors/SplitEW | التأشير على مقبض "تقسيم" أفقي. | |
| rbxasset://SystemCursors/Forbidden | التأشير على عنصر مقفل/ممنوع. | |
| rbxasset://SystemCursors/Wait | الإشارة إلى أن إجراءً قيد التقدم. | |
| rbxasset://SystemCursors/Busy | الإشارة إلى أن النظام مشغول. | |
| rbxasset://SystemCursors/Cross | التأشير فوق منطقة تحديد النقطة. |
جمع مدخلات المستخدم
تعمل عناصر واجهة المستخدم مثل TextBox و TextButton بشكل طبيعي في أدوات استوديو، ويمكنك بناء واجهات كما تفعل عادةً على Roblox. ومع ذلك، فإن UserInputService لا تعمل لأن هذه الخدمات تتوقع أن تكون نافذة التجربة الرئيسية في التركيز.
أحد الحلول البديلة لمدخلات الإدخال العامة هو إنشاء Frame شفافة وتغطيتها على الشاشة بأكملها. ينشئ نموذج الكود التالي إطارًا، وعندما ينقر المستخدم على الإطار، تلتقط حدث GuiObject.InputBegan إدخال لوحة المفاتيح على الإطار حتى ينقر المستخدم بعيدًا:
local frame = Instance.new("Frame")
frame.BackgroundTransparency = 1 -- إخفاء الإطار
frame.Size = UDim2.new(1, 0, 1, 0) -- تغطية الشاشة
frame.Position = UDim2.new(0, 0, 0, 0)
frame.Parent = testWidget
local function onInputBegan(inputObject)
-- معالجة كائن الإدخال هنا، على سبيل المثال اكتشاف ضغطات المفاتيح
end
frame.InputBegan:Connect(onInputBegan)
تفاعل السحب والإفلات
استخدام تفاعلات السحب والإفلات لأدواتك هو طريقة بسيطة لتحسين تدفق البيانات. لإنشاء هذا التفاعل، يجب عليك تحديد العنصر الذي تريد سحبه، بدء السحب، إنشاء هدف للإفلات، ومعالجة إجراء الإفلات.
إنشاء مصدر السحب
يمكنك بدء إجراء السحب من خلال استدعاء Plugin:StartDrag() عندما يضغط المستخدم على زر الماوس على بعض عناصر واجهة المستخدم، عادةً ما تكون TextButton أو ImageButton داخل الأداة. ينشئ نموذج الكود التالي أداة نافذة واحدة مع زر نص داخلها.
-- إنشاء الأداة أولاًlocal widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, true, true, 300, 200)local dragSourceWidget = plugin:CreateDockWidgetPluginGui("مصدر السحب", widgetInfo)dragSourceWidget.Title = "مصدر السحب"-- إنشاء TextButton الذي سيبدأ السحبlocal dragButton = Instance.new("TextButton")dragButton.Size = UDim2.new(1, 0, 1, 0)dragButton.Text = "اسحبني!"dragButton.Parent = dragSourceWidget
بدء السحب
عندما ينقر المستخدم على TextButton، يمكنك بدء السحب من خلال حدث MouseButton1Down() الذي يتم إطلاقه بمجرد ضغط المستخدم على زر الماوس.
داخل الدالة المتصلة، حدد البيانات المراد سحبها. يجب أن يكون نوع البيانات مُعبرًا عنه في مفتاح MimeType، ويجب أن يكون محتوى السحب معبرًا عنه في مفتاح Data، ويجب أن يصف المرسل نفسه في مفتاح Sender. راجع صفحة Plugin:StartDrag() لمزيد من التفاصيل.
local function onButton1Down()
local dragInfo = {
Data = "مرحبًا، العالم", -- البيانات التي يتم سحبها
MimeType = "text/plain", -- تصف نوع MIME للبيانات
Sender = "SomeDragSource", -- تصف من أين نشأت البيانات
MouseIcon = "", -- محتوى الصورة لاستخدامه لمؤشر الماوس
DragIcon = "", -- محتوى الصورة الذي سيتم عرضه تحت المؤشر أثناء السحب
HotSpot = Vector2.zero -- النقطة التي سيتم تركيز المؤشر عليها على DragIcon
}
plugin:StartDrag(dragInfo)
end
dragButton.MouseButton1Down:Connect(onButton1Down)
إنشاء هدف الإفلات
يتم إطلاق حدث PluginGui.PluginDragDropped عندما يرفع المستخدم الماوس على نافذة أثناء سحب. عندما يحدث ذلك، تحتاج إلى تحديد هدف الإفلات مثل أداة ثانية مع TextLabel لاكتشاف عمليات الإسقاط.
local dragTargetWidget = plugin:CreateDockWidgetPluginGui("هدف الإفلات", widgetInfo)dragTargetWidget.Title = "هدف الإفلات"-- ستعرض هذه TextLabel ما تم إسقاطهlocal textLabel = Instance.new("TextLabel")textLabel.Size = UDim2.new(1, 0, 1, 0)textLabel.Text = "أسقط هنا..."textLabel.Parent = dragTargetWidget
معالجة إجراء الإفلات
بعد إنشاء هدف الإفلات، اربط حدث PluginGui.PluginDragDropped على أداة هدف الإفلات:
local function onDragDrop(dragData)
print("تم إسقاط PluginDragDropped")
if dragData.MimeType == "text/plain" then
textLabel.Text = dragData.Data
else
textLabel.Text = dragData.MimeType
end
end
dragTargetWidget.PluginDragDropped:Connect(onDragDrop)
أثناء استمرار السحب، يتم إطلاق هذه الثلاثة أحداث كلما انتقل المستخدم مؤشر الماوس فوق الأداة:
- PluginDragEntered – يتم إطلاقه عندما يقوم المستخدم بالتأشير بالماوس فوق نافذة
- PluginDragMoved – يتم إطلاقه بشكل متكرر مع حركة الماوس فوق نافذة. هذا مفيد لعرض رسالة "أسقط هنا!".
- PluginDragLeft – يتم إطلاقه عندما يترك مؤشر المستخدم نافذة. هذا مفيد لإخفاء رسالة "أسقط هنا!".















