هناك العديد من الطرق التي يمكنك من خلالها تخصيص الطرق التي تبدو بها عمليات الربط، ولكل طريقة منها زيادة الصعوبة. تتطلب جميعها إنشاء عارض مخصّص
السمات الأساسية
يمكنك تخصيص الاتصالات عن طريق تغيير عرضها أو ارتفاعها، مع الحفاظ على نفس الشكل الأساسي. للقيام بذلك، تحتاج إلى إنشاء المكوِّن الثابت المخصص، وإلغاء بعض الثوابت.
وتعمل برامج العرض المختلفة على تحديد ثوابت مختلفة واستخدامها، لذا يُرجى مراجعة الوثائق المرجعية للصف المتميز:
بالنسبة إلى العارض الأساسي، يمكنك إلغاء NOTCH_WIDTH
NOTCH_HEIGHT
لعمليات الربط التالية والسابقة
TAB_WIDTH
وTAB_HEIGHT
للإدخال والمخرجات
الاتصالات.
class CustomConstantProvider extends Blockly.blockRendering.ConstantProvider {
constructor() {
super();
this.NOTCH_WIDTH = 20;
this.NOTCH_HEIGHT = 10;
this.TAB_HEIGHT = 8;
}
}
الأشكال الأساسية
يمكنك تخصيص الاتصالات عن طريق تجاوز شكلها الأساسي. الأشكال الأساسية لها ارتفاع وعرض ومسارين.
يرسم كل مسار نفس الشكل، ولكن من نهايات عكسية!
وهذا أمر ضروري لأنه عندما يرسم الدرج مخطط فإنها ترسم كل نوع من أنواع الاتصال في كلا الاتجاهين. على سبيل المثال: الروابط السابقة يتم رسمها من اليسار إلى اليمين، لكن الاتصالات التالية مرسومة من اليمين إلى اليسار. لذلك تحتاج إلى توفير مسارات لكلا تلك الحالات.
يمكنك إلغاء الطريقة makeNotch
في الطريقة التالية والسابقة.
والاتصالات، وطريقة makePuzzleTab
للإدخال
واتصالات الإخراج.
class CustomConstantProvider extends Blockly.blockRendering.ConstantProvider {
makePuzzleTab() {
const width = this.TAB_WIDTH;
const height = this.TAB_HEIGHT;
return {
type: this.SHAPES.PUZZLE,
width,
height,
pathUp: Blockly.utils.svgPaths.line([
Blockly.utils.svgPaths.point(-width, -height / 2),
Blockly.utils.svgPaths.point(width, -height / 2)]),
pathDown: Blockly.utils.svgPaths.line([
Blockly.utils.svgPaths.point(-width, height / 2),
Blockly.utils.svgPaths.point(width, height / 2)]),
};
}
}
يمكنك مراجعة مستندات مسار MDN SVG للحصول على معلومات حول كيفية
لتحديد سلاسل المسار. تم توفير مساحة الاسم Blockly.utils.svgPaths
كغلاف رفيع حول هذه السلاسل لتسهيل قراءتها.
أشكال لعمليات التحقق من الاتصال
يمكنك تخصيص الاتصالات من خلال تغيير الشكل بناءً على روابط التحقق من الاتصال.
يتيح لك هذا إنشاء أشكال مختلفة لتمثيل أنواع بيانات مختلفة. على سبيل المثال، يمكن تمثيل السلاسل باتصالات مثلثية، بينما يتم تمثيل القيم المنطقية بواسطة الاتصالات الدائرية.
لتوفير أشكال مختلفة لعمليات التحقق المختلفة من الاتصال، يجب إلغاء
الطريقة shapeFor
. يجب تهيئة الأشكال المعروضة
في init
.
راجع الأشكال الأساسية للحصول على معلومات حول أنواع والأشكال المتوافقة.
export class ConstantProvider extends Blockly.blockRendering.BaseConstantProvider {
shapeFor(connection) {
let check = connection.getCheck();
// For connections with no check, match any child block.
if (!check && connection.targetConnection) {
check = connection.targetConnection.getCheck();
}
if (check && check.includes('String')) return this.TRIANGULAR_TAB;
if (check && check.includes('Boolean')) return this.ROUND_TAB;
return super.shapeFor(connection);
}
}
مصادر الإدخال المخصّصة
يمكنك تخصيص أشكال الربط من خلال إنشاء إدخال مخصّص بالكامل. هذا النمط يتم فقط إذا كنت تريد أن تبدو بعض الاتصالات مختلفة عن غيرها، لكنك ولا تريدها أن تستند إلى التحقق من الاتصال.
على سبيل المثال، إذا أردت وضع مسافة بادئة لبعض إدخالات القيمة مثل مدخلات العبارة، يمكنك إنشاء إدخال مخصّص لدعم ذلك
إنشاء فئة إدخال مخصّصة
اتّبِع خطوات إنشاء إدخال مخصّص.
إنشاء خطة قابلة للقياس
يجب إنشاء عنصر قابل للقياس لتمثيل مدخلاتك المخصّصة.
يجب أن تُكتسب البيانات المخصّصة القابلة للقياس من
Blockly.blockRendering.InputConnection
يمكن أن تتضمن أيضًا
أي بيانات قياس إضافية تحتاجها لرسم شكل المدخلات.
export class CustomInputMeasurable extends Blockly.blockRendering.InputConnection {
constructor(constants, input) {
super(constants, input);
// Any extra measurement data...
}
}
إضفاء مثيل قابل للقياس
يجب إنشاء مثيل مخصص لمعلومات العرض
وقابلة للقياس. ولإجراء ذلك، عليك إلغاء الطريقة addInput_
.
export class RenderInfo extends Blockly.blockRendering.RenderInfo {
addInput_(input, activeRow) {
if (input instanceof CustomInput) {
activeRow.elements.push(new CustomInputMeasurable(this.constants_, input));
}
super.addInput_(input, activeRow);
}
}
يمكنك إنشاء صف.
بشكلٍ تلقائي، لا تنشئ الإدخالات صفوفًا جديدة. إذا أردت الحصول على مشاركتك
لعرض نهاية الصف، يجب إلغاء
shouldStartNewRow_
من
معلومات العرض
export class RenderInfo extends Blockly.blockRendering.RenderInfo {
shouldStartNewRow_(currInput, prevInput) {
if (prevInput instanceof CustomInput) return true;
return super.shouldStartNewRow_(currInput, prevInput);
}
}
يمكنك بشكل اختياري إنشاء شكل لإدخالك
إنها لفكرة جيدة أن يتم تخزين شكل مدخلاتك في ثابت، تمامًا مثل بالنسبة إلى علامات تبويب الألغاز وعلامات التبويب هذا يحافظ على تنظيم التعليمات البرمجية ويجعل يسهل تعديلها لاحقًا.
رسم الإدخال
أخيرًا، يجب تعديل الدرج لرسم الشكل.
يمكن للإدخالات المخصّصة تنفيذ أحد الإجراءَين التاليَين:
التأثير في مخطط القسم، مثل إدخالات العبارات
أو التأثير في العناصر الداخلية للكتلة، مثل إدخالات القيمة المضمّنة
إذا كان الإدخال يؤثر في مخطط القالب، يمكنك تجاوز
drawOutline_
، في الحالات الأخرى، إلغاء
drawInternals_
export class Drawer extends Blockly.blockRendering.Drawer {
drawOutline_() {
this.drawTop_();
for (let r = 1; r < this.info_.rows.length - 1; r++) {
const row = this.info_.rows[r];
// Insert checks for your input here!
if (row.getLastInput() instanceof CustomInputMeasurable) {
this.drawCustomInput(row);
} else if (row.hasJaggedEdge) {
this.drawJaggedEdge_(row);
} else if (row.hasStatement) {
this.drawStatementInput_(row);
} else if (row.hasExternalInput) {
this.drawValueInput_(row);
} else {
this.drawRightSideRow_(row);
}
}
this.drawBottom_();
this.drawLeft_();
}
protected drawInternals_() {
for (const row of rows) {
for (const elem of row) {
// Insert checks for your input here!
if (elem instanceof CustomInputMeasurable) {
this.drawCustomInput(elem);
}
if (Types.isInlineInput(elem)) {
this.drawInlineInput_(elem as InlineInput);
} else if (Types.isIcon(elem) || Types.isField(elem)) {
this.layoutField_(elem as Field | Icon);
}
}
}
}
}