Turbo Vision 2.0 - การคืนชีพ Text UI ยุค 90s
(github.com/magiblot)- โอเพนซอร์สพอร์ตที่นำเฟรมเวิร์ก Text UI ของ Borland จากยุค 90 มาปรับให้ทันสมัยด้วยการรองรับข้ามแพลตฟอร์ม + Unicode
- เวลาสร้างแอปเทอร์มินัล ไม่ต้องจัดการเรื่องความเข้ากันได้ของเทอร์มินัลเอง - โค้ดเดียวกันทำงานได้บน Linux, Windows และ DOS
- มี วิดเจ็ต TUI อย่าง หน้าต่างซ้อนทับที่ปรับขนาดได้, เมนูแบบดรอปดาวน์, ไดอะล็อก, ปุ่ม, แถบเลื่อน, ช่องกรอกข้อมูล, เช็กบ็อกซ์, ปุ่มตัวเลือก ติดตั้งมาให้แล้ว จึงหยิบไปใช้ได้เลยโดยไม่ต้องสร้างเอง
- รองรับ UTF-8 Unicode เต็มรูปแบบ — แม้ยังคงใช้ API แบบ
charเดิม ก็ยังจัดการอักขระ CJK แบบเต็มความกว้าง, อักขระผสม และอีโมจิได้ และใช้เพียงmoveStr()บรรทัดเดียวก็จัดการการเลื่อนและการตัดข้อความแบบหลายไบต์ให้อัตโนมัติ - ใช้ประโยชน์จากการรองรับ UTF-8
setlocaleของ Microsoft RTL ทำให้โค้ดอย่างstd::ifstream f("コンピュータ.txt")ทำงานบน Windows ได้เหมือนเดิม - รองรับ True Color 24 บิต — ขยายจาก 16 สีเดิมไปสู่ RGB, xterm-256 และสีพื้นฐานของเทอร์มินัล และถ้าเทอร์มินัลไม่รองรับก็จะทำการ quantize ไปเป็นสีที่ใกล้ที่สุดโดยอัตโนมัติ
- รองรับอินพุต/เอาต์พุตสมัยใหม่ทั้งหมด เช่น ล้อเมาส์, ปุ่มกลาง, การคลิกสามครั้ง, ขนาดหน้าจอสูงสุด 32767 แถว/คอลัมน์, และอีเวนต์การปรับขนาดหน้าต่าง
- มีการเชื่อมต่อกับคลิปบอร์ดของระบบในตัว: Windows/macOS ใช้งานได้ทันที และแม้ในสภาพแวดล้อมรีโมตผ่าน SSH ก็ยังคัดลอก/วางได้ผ่าน X11 forwarding หรือ escape code แบบ OSC 52
- ซอร์สโค้ด Turbo Vision ยุค Borland C++ เดิมสามารถ นำมาคอมไพล์ได้แทบจะทันทีโดยแก้ไขเพียงเล็กน้อย
- รองรับระบบบิลด์ CMake และ ติดตั้งผ่าน vcpkg ได้ด้วย
./vcpkg install tvisionเพียงบรรทัดเดียว, หากเพิ่มเป็น CMake submodule ด้วยadd_subdirectoryก็ลิงก์ dependency ให้อัตโนมัติ - ต้องการ C++14 ขึ้นไป และ libncursesw / ไลเซนส์ MIT
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ดีใจมากที่เห็นรีโพซิทอรีนี้ขึ้นหน้า front page และตอนนี้ก็กำลังทำ wrapper สำหรับรีโพนี้เองอยู่
ตอนนี้กำลังรัน Turbo Vision บน macOS ผ่าน .Net ซึ่งให้ความรู้สึกเหมือนเวทมนตร์พอสมควร
กำลังทำ API ระดับสูงขึ้น พร้อมทั้งครอบหรือปรับปรุง palette API ที่ค่อนข้างล้าสมัย และเพิ่มระบบ layout เข้าไปด้วย
ตอนนี้ยังทำอยู่แบบหนักมากในรีโพส่วนตัว โดยวันนี้ก็ยังไล่ปรับ palette ตาม surface ที่วางคอนโทรลไว้ แล้วพรุ่งนี้ก็ไปเก็บรายละเอียดส่วนอื่นต่อแบบนี้เรื่อย ๆ
ยังเหลืองานอย่างจัดระเบียบ layout และเพิ่มคอนโทรลพื้นฐานที่มาตรฐานยุคนี้ควรมี
ก่อนหน้านี้เคยใช้ Terminal.Gui เหมือนกัน แต่เพราะมันกำลังเปลี่ยนผ่านไป v2 เลยใช้งานให้ไม่มีบั๊กได้ค่อนข้างยาก และ Claude ก็แสดงให้เห็นชัดดีว่าถ้าสร้างไลบรารี TUI โดยไม่คำนึงถึงเทอร์มินัลจริง ๆ ไม่ควรทำอะไรบ้าง
เลยคิดมาตลอดว่าอยากได้ Turbo Vision เวอร์ชันทันสมัย แล้วก็มาพบรีโพนี้เข้า พอเห็นว่ารองรับ Unicode ด้วยก็รู้สึกขอบคุณมากจริง ๆ
https://www.remobjects.com/elements/oxygene/
https://www.remobjects.com/elements/
ฉันเองก็กำลังทำ .NET wrapper อยู่เหมือนกัน อาจจะไปได้ไม่ไกลเท่าไร แต่ตั้งใจจะเลียนแบบ Windows Forms API ให้ใกล้ที่สุด และอยากใส่ตัวออกแบบ TUI แบบ drag-and-drop เข้าไปด้วย
ตัวอย่างอยู่ที่นี่: https://github.com/brianluft/terminalforms/tree/main/src/TerminalFormsDemo
งานเชื่อมต่อยาก ๆ ฝั่ง C++ ส่วนใหญ่จัดการไว้ตรงนี้: https://github.com/brianluft/terminalforms/tree/main/src/tfcore
ผม export ฟังก์ชัน C แบบเรียบง่ายไว้เพื่อให้เรียกผ่าน P/Invoke ได้ แล้วให้ฝั่ง C# เน้นไปที่การจัดโครงสร้างคลาสเป็นหลัก
ตอนแรกผมพยายามยืนกรานว่าสิ่งที่ทำได้ใน C++ จะต้องทำได้ใน C# ทั้งหมด แต่สุดท้ายมันซับซ้อนเกินไป ถึงขั้นเอา placement new มาใส่อ็อบเจ็กต์ C++ ลงในบัฟเฟอร์ของ C# จนเกือบกลายเป็นว่าฝั่ง C# สืบทอดคลาส C++ ได้จริง ๆ แล้วการออกแบบก็พังไปเลย
สุดท้ายก็เปลี่ยนมาใช้แนวทางที่ตรงไปตรงมามากกว่า ยืดหยุ่นน้อยลงแต่เรียบง่ายกว่ามาก และเก็บความยืดหยุ่นไว้ที่ฝั่ง C# แทน
อยากรู้ว่าคุณจัดระบบ P/Invoke system ของคุณยังไง
คงช่วยไม่ให้ผมไปพยายามเปล่าประโยชน์แบบทำแอปให้ GEOS หรือไปเข้าทีม Hurd แบบคนเดียวได้ดี
เคยลองใช้ Terminal.Gui แต่รู้สึกถูกใจฝั่ง TV มากกว่าเลยเคยคิดจะทำ wrapper เหมือนกัน ถ้าเปิดเผยเมื่อไรอยากดูมากจริง ๆ
เส้นทางการเขียนโปรแกรมของผมเริ่มต้นแบบตรงตัวจาก ถังขยะ ในยุค 90
ผมไปเจอ หนังสือ Turbo Vision ที่มีคนทิ้งไว้ และตกหลุมรัก TUI สีน้ำเงินที่ใคร ๆ ก็สร้างได้ทันที
เวอร์ชันดั้งเดิมอยู่ใน Turbo Pascal 6 และพอร์ต C++ ออกมาทีหลัง
เพราะงั้นนี่ก็คือพอร์ตแบบทันสมัยของพอร์ตอีกที
Borland ก็มีเฟรมเวิร์กอื่นที่คล้ายกัน โดย OWL เดิมทีเริ่มจากฝั่ง Turbo Pascal for Windows 1.5 ก่อน และเครื่องมือหลายส่วนของ C++ Builder ก็จริง ๆ เขียนด้วย Delphi
Object Pascal ใน Turbo Pascal 5.5 และ Turbo Vision ในเวอร์ชัน 6 คือจุดเริ่มต้น OOP ของผม และรู้สึกว่าโชคดีมากที่ได้เริ่มเส้นทางนั้นแบบนั้น
แม้อยู่ในสภาพแวดล้อมอย่าง MS-DOS ก็ยังเรียนรู้ข้อดีของ OOP และเฟรมเวิร์กแบบ Turbo Vision ได้อย่างเต็มที่
ตอนที่ Borland ออก Turbo Pascal, Turbo C++, TurboVision มานั้น เหมือนจักรวาลแห่งความเป็นไปได้เปิดกว้างออกมาตรงหน้า
คอมไพเลอร์ก็ยอดเยี่ยม คู่มือก็เหมือนงานศิลปะ เสียดายที่ไม่ได้เก็บหนังสือพวกนั้นไว้จนถึงตอนนี้
มันคือสมบัติทางวัฒนธรรมชัด ๆ
ช่วงต้นยุค 90 ผมเรียน C/C++ ด้วยตัวเองแทบจะจากการอ่านแต่กองหนังสือ Borland ที่มากับ Turbo C++ อย่างเดียว ทุกวันนี้แทบจินตนาการไม่ออกเลยว่าจะมีใครเรียนจากแค่อ่านคู่มืออ้างอิงแบบนั้น
เฟรมเวิร์ก TUI ใหม่ ๆ มักให้ความรู้สึกว่าขาดอะไรบางอย่างอยู่เสมอ ตอนนี้เลยจะลองกลับมาใช้ตัวนี้อีกครั้งเพื่อดูว่าที่คิดนั้นเป็นแค่ความคิดถึงหรือเปล่า
ผมจะเอามันไปใส่ในเครื่องมือตัวถัดไป และอยากปรบมือดัง ๆ ให้คนที่สร้างมันขึ้นมา
นอกจาก GW-BASIC กับ MS-DOS แล้ว ทุกอย่างเป็น Borland หมด ทั้ง Turbo BASIC, Turbo Pascal, Turbo C++ for MS-DOS and Windows 3.x, Turbo Vision, OWL
ผมมาใช้ VC++ ก็ราว ๆ เวอร์ชัน 5 ซึ่ง MFC ดูจืดชืดไปเลยเมื่อเทียบกับของ Borland
ทุกวันนี้ก็ยังมีไม่กี่อย่างที่ตาม ความสามารถด้าน RAD ของ C++ Builder ได้ทัน และ .NET เองก็ใช้เวลานานพอควรกว่าจะจัดการเรื่องการเขียนโค้ดระดับล่างแบบ Delphi และเรื่อง AOT ได้ลงตัว
ผมว่าเราควรยื่น Turbo Pascal 7 สำหรับ MS-DOS กับ Delphi รุ่นล่าสุดให้คนที่พัฒนา Go, C++, Rust ไปคนละหลายชุด
Turbo Vision 2.0 ยังใช้งานได้จริงค่อนข้างมากจนผมเคยใช้ทำงานต้นแบบเมื่อปีก่อน
ผมพยายามทำฟรอนต์เอนด์ Turbo Vision ให้ดีบักเกอร์ LLDB เพื่อให้ทำงานเหมือน Turbo Debugger ของ Borland และส่วนใหญ่ก็ออกมาตามที่หวัง
มันน่าทึ่งมากที่เหมือนรับช่วงต่อจากจุดที่ค้างไว้ในปี 199x ได้ตรง ๆ และยังคอมไพล์กับรันโค้ดจากปี 1993 ได้โดยแทบไม่มีปัญหา
ตัวแก้ไขภายในก็มีเวอร์ชันที่ดีกว่าซึ่งใช้ Scintilla เป็นฐานและมีฟีเจอร์อย่าง syntax highlighting ด้วย แต่สิ่งที่ผมอยากดัดแปลงกลับทำได้ไม่ค่อยดี เลยคงต้องไปขอความช่วยเหลือจากผู้เขียน
อย่างไรก็ตาม ถ้ามองในความหมายของ documentation แบบองค์ความรู้สาธารณะสมัยใหม่ มันยังมีน้อยอยู่ เลยถาม Stack Overflow หรือ AI ได้ยาก ต้องเรียนรู้จากโค้ดตัวอย่างและกลับไปอ่านหนังสือ Turbo Vision อยู่ซ้ำ ๆ แบบสมัยก่อน
การจัด layout ด้วยมือค่อนข้างน่าเบื่อ ถ้ามี auto layout แบบ Qt ก็น่าจะดี และก็คิดถึง splitter อยู่บ้าง แต่ดูแล้วคงทำเองไม่ยาก
อีกอย่างที่ทำให้แปลกใจคือ TV จริง ๆ แล้วเล็กและกะทัดรัดมาก ตอนยุค 90 มันดูยิ่งใหญ่มหาศาลกว่านี้ในความทรงจำ
โดยรวมแล้วงานปรับให้ทันสมัยทำออกมาได้ดีมาก และผมชอบมันมาก
Turbo Vision เดิมมีเอกสารคุณภาพสูงจำนวนมากอยู่แล้ว
กลับกัน ผมว่าของฝั่งสมัยใหม่นี่แหละที่เอกสารไม่ค่อยพอ
https://archive.org/details/bitsavers_borlandTurrogrammingGuide1992_25707423
แค่เห็น cmake directive เต็มไปหมดก็ชวนให้อยากย้อนเวลากลับไป
สมัย Turbo C หรือ Pascal แค่กด F9 ก็รันได้แล้ว
ในอีกมุมหนึ่งมันก็สะท้อนความไร้ประสิทธิภาพของ toolchain พวกเราเหมือนกัน
ยุคนี้มันควรจะแค่ชี้ไปที่คอมไพเลอร์ออนไลน์แล้วรันได้เลย หรือดาวน์โหลดมา เปิดโฟลเดอร์เดียวแล้วรันได้ จบ ไม่ควรกลายเป็นพิธีกรรมมากกว่าเป็นเครื่องมือ
./configure && make && make install นี่แหละควรยังเป็น gold standard อยู่
นี่เป็นแค่หนึ่งใน พอร์ต/โคลนของ Turbo Vision เท่านั้น
ฝั่ง C++ ยังมีตัวนี้ด้วย: https://github.com/kloczek/tvision
เวอร์ชันที่รวมอยู่ใน FreePascal/Lazarus เขียนด้วย Pascal และก็มีเวอร์ชัน Rust อยู่ตัวหนึ่งที่ดูเหมือนจะ vibe-coded อยู่บ้าง: https://github.com/aovestdipaperino/turbo-vision-4-rust
พอเอาไปรันในเทอร์มินัล มันจะหายไปนิดหน่อยจากความรู้สึกหลักที่ เมาส์บนหน้าจอโหมดข้อความ เคยให้ไว้
บนหน้าจอโหมดข้อความจริง ๆ มันไม่ได้เป็นตัวชี้เมาส์ แต่จะดูเหมือนบล็อกสีเหลืองที่ขยับได้ด้วยเมาส์มากกว่า
สงสัยว่ามีใครเคยลองรันมันบนโหมดข้อความความละเอียดสูงของ Linux พร้อม GPM บ้างไหม
มันแค่กลับสีของเซลล์ที่อยู่ใต้ตัวชี้ และเพราะหน้าต่างหลักที่กินพื้นที่เกือบทั้งจอส่วนใหญ่มักเป็นสีน้ำเงินเข้ม ผลเลยออกมาคล้ายบล็อกสีเหลืองสว่างอยู่บ่อย ๆ
ขอแนะนำตอนล่าสุดของ Wookash podcast ที่พูดถึง Chuck Jazdzewski
เขาเป็นหนึ่งในทีมที่สร้าง Turbo Vision ดั้งเดิม และยังเล่าเรื่องระบบนิเวศโดยรอบไว้เยอะมากด้วย
ผมยังอยากได้ Turbo Vision ของจริง คือเวอร์ชัน Pascal มากกว่าเวอร์ชัน C++ อยู่ดี
เวอร์ชัน C++ ให้ความรู้สึกเหมือนเป็นการย้าย Pascal เวอร์ชันหนึ่งมาอีกที
ตัวอย่างเช่น ใน Pascal นั้น
usesเป็นคีย์เวิร์ด แต่การ include โมดูลด้วย#defineยังไงก็ให้ความรู้สึกเหมือนเป็นการแฮ็กถึงตอนนี้ความต่างพวกนี้อาจไม่ใช่เรื่องใหญ่แล้วก็เถอะ
IDE โหมดข้อความก็ใช้ Free Vision
https://wiki.lazarus.freepascal.org/images/1/19/Userscreen.png
แต่ความต่างสำคัญคือ Free Vision กับ Turbo Vision ใช้ชนิด
objectจากยุค Turbo Pascal 5.5 ไม่ใช่classแบบ Delphiclassทำให้ทำพวกการทำซีเรียลไลซ์อัตโนมัติได้ง่ายกว่าด้วย RTTI แต่objectไม่มีสิ่งนั้น ถ้าจะจำแนกชนิดต่าง ๆ ตอนรันไทม์ก็ต้องทำซีเรียลไลซ์แบบแมนนวล โดยอาศัยการลงทะเบียน VMT pointer ที่อยู่ ณ offset คงที่ของ object pointerแม้ Free Pascal จะเพิ่มความสะดวกอย่าง private/protected/public และ property ให้กับ
objectบ้าง แต่ Free Vision ก็ไม่ใช้ส่วนขยายนั้น เพราะต้องคง API ดั้งเดิมของ Turbo Vision ไว้