أوّلُ نافذةٍ وزرٌّ يستجيب
هذا الدرسُ مسارٌ واحدٌ مضمون: من ملفٍّ فارغٍ إلى نافذةٍ تُفتَحُ على سطحِ مكتبِك فيها عنوانٌ وعدّادٌ وزرٌّ مربوطٌ بمعالِج. لا خياراتٍ ولا تفريعات — الخياراتُ في كيف تبني شجرةَ الواجهة والأحداثُ والحالة.
ما يلزمُك قبلَه
مترجِمُ sad-build مبنيًّا — البناءُ والتشغيل. ولا يلزمُك استيرادُ وحدة: مدمَجاتُ الواجهةِ مُعلَنةٌ في مصدرِ الحقيقةِ بـrequire_import: false، فهي متاحةٌ بلا استورد.
١ · اكتُبِ الملفّ
احفَظْ هذا في مرحبا.ص:
# أوّلُ نافذةٍ في لغة ص
متغير العدد = 0
متغير عرض_العدد = نص_عنصر("النقرات: 0")
.حجم_خط(28)
.لون("#FFFFFF")
دالة عند_النقر_على_الزر()
العدد = العدد + 1
عين_النص(عرض_العدد، "النقرات: " + العدد)
تحديث_حالة()
نهاية
متغير الجذر = عمود(
نص_عنصر("مرحبًا من لغة ص").حجم_خط(34).لون("#FFFFFF")،
عرض_العدد،
زر("انقرني").عند_النقر(عند_النقر_على_الزر)
)
.لون_خلفية("#0B1A2E")
.حشوة(40)
.تباعد(20)
طباعة_شجرة(الجذر)
تشغيل_تطبيق(الجذر)أربعةُ أشياءَ تجري ههنا، ولا خامسَ:
| السطر | ما يفعل |
|---|---|
نص_عنصر · زر · عمود | مصانعُ عُقَد — كلٌّ يُنشئُ عقدةً في شجرةِ الواجهة |
.حجم_خط(…) · .لون(…) | معدّلاتٌ انسيابيّة — تضبطُ خاصّيّةً وتُرجِعُ العنصرَ نفسَه فتتسلسل |
.عند_النقر(دالّة) | يُسجّلُ معالِجَ حدثٍ على العقدة — البادئةُ عند_ مُعلَنةٌ معدّلًا في ui_modifiers.yaml |
تشغيل_تطبيق(الجذر) | نقطةُ الدخولِ الوحيدة إلى حلقةِ الأحداث: تفتحُ النافذةَ وترسمُ وتُرسِلُ الأحداث |
اكتُبِ الملفَّ بمحرِّرٍ يحفظُ UTF-8
ولا تُنشِئْه بإعادةِ توجيهٍ من صدفةٍ لا تُحسِنُ العربيّة، فيصلُ المترجِمَ نصٌّ مشوَّه.
٢ · ترجِمْ
sad-build مرحبا.ص -o مرحبا.exeالمترجِمُ يضعُ SDL2.dll بجوارِ الثنائيِّ من تلقاءِ نفسِه — مقيسٌ: مجلَّدٌ فارغٌ فيه الملفُّ المصدريُّ وحدَه صارَ بعدَ الترجمةِ يحملُ مرحبا.exe وSDL2.dll. فلا خطوةَ نسخٍ يدويّة.
٣ · شغِّلْ
./مرحبا.exeفيُطبَعُ أوّلًا نصُّ الشجرةِ الذي طلبتَه بـطباعة_شجرة:
عمود(لون_خلفية: "#0B1A2E", حشوة: 40, تباعد: 20)
نص_عنصر(محتوى: "مرحبًا من لغة ص", حجم_خط: 34, لون: "#FFFFFF")
نص_عنصر(محتوى: "النقرات: 0", حجم_خط: 28, لون: "#FFFFFF")
زر(عنوان: "انقرني") [عند_النقر]ثمّ تُفتَحُ النافذة، ويُطبَعُ سطرُ التأكيد:
✓ تم إنشاء النافذة: تطبيق ص [800x600]هذا هو النجاحُ الأوّل. والوسمُ [عند_النقر] في مخرَجِ الشجرةِ برهانٌ نصّيٌّ على أنّ المعالِجَ سُجِّلَ فعلًا على العقدة لا أنّه كُتِبَ فحسب.
لماذا طباعة_شجرة في درسِ نافذة؟
لأنّها نقطةُ الارتساءِ الوحيدةُ التي تُقاسُ بلا عين. النافذةُ تُرى ولا تُقارَن؛ ونصُّ الشجرةِ يُقارَنُ حرفًا بحرف. فمتى شككتَ أنّ عنصرًا لم يُضَفْ أو خاصّيّةً لم تُضبَط، اطبعِ الشجرةَ قبلَ أن تفتحَ النافذة.
ما بعدَ ذلك
- شجرةٌ أكبرُ وحاوياتٌ متداخلة ⟵ كيف تبني شجرةَ الواجهةِ وتُعدِّلُها
- أحداثٌ وحالةٌ وتنقّلٌ بين صفحات ⟵ الأحداثُ والحالةُ والتنقّل
- ولماذا «يدعمُ خمسَ منصّات» دعوى لا بنية ⟵ شجرةٌ واحدةٌ ومخارجُ كثيرة
حدٌّ مُعلَنٌ يخصُّ هذا الدرس
النافذةُ تُفتَحُ ويُسجَّلُ المعالِج — وهذا مقيس. أمّا أثرُ النقرةِ المرئيُّ فلم يُقَسْ ههنا: التحقّقُ منه يلزمُه نقرةٌ بشريّةٌ على جهازٍ ذي شاشة، ولا بذرةَ واحدةً في tests/behavior تستدعي تشغيل_تطبيق فتحرسَه. فاعتبِرْه سلوكًا تُجرّبُه بيدِك لا وعدًا محروسًا.
⚠️ وقياسٌ يخصُّ عين_النص بعينِها: مخرَجُ طباعة_شجرة بعدَ ندائها يُظهِرُ خاصّيّةً جديدةً باسمِ text بجوارِ محتوى لا بدلًا منها — مقيسٌ في شجرةُ الواجهة. وأيُّ القيمتَينِ تفوزُ عندَ الرسمِ لم يُقَسْ. فلا تبنِ على هذه الصيغةِ منطقَ عرضٍ قبلَ أن تراه بعينِك.