ImRAD - เครื่องมือสร้าง GUI สำหรับไลบรารี ImGui
(github.com/tpecholt)- ImRAD เป็นเครื่องมือสร้าง GUI สำหรับ ImGui ที่สร้าง โค้ด C++ ซึ่งนำไปใช้ในแอปพลิเคชันได้ทันที และสามารถพาร์สกลับมาเพื่อแก้ไข UI ที่สร้างไว้ต่อไปได้
- รองรับ data binding, event และการเพิ่มโค้ด UI ด้วยตนเอง โดยโค้ดที่สร้างขึ้นจะแยกด้วย comment marker ทำให้ผู้ใช้ยังใช้งานดีไซเนอร์ต่อได้แม้ใส่โค้ดของตนเองเข้าไป
- ทำงานบน Windows, Linux, MacOS และโค้ดที่สร้างขึ้นทำงานได้บน Windows, Linux, MacOS, Android
- เลย์เอาต์ใช้
SameLine,Spacing,NextColumnและ box layout แทนตำแหน่งแบบ absolute พร้อมรักษาความสัมพันธ์ parent-child และลำดับระหว่างวิดเจ็ต - ซอร์สของ ImRAD เป็น GPL แต่โค้ดที่เครื่องมือสร้างขึ้นและ
imrad.hที่โค้ดนั้นใช้งานได้รับการยกเว้นจาก GPL จึงรวมเข้าในโปรเจกต์โอเพนซอร์สหรือเชิงพาณิชย์ได้
บทบาทของ ImRAD และวิธีสร้างโค้ด
- ImRAD เป็นเครื่องมือสร้าง GUI สำหรับไลบรารี ImGui
- สร้างและพาร์ส โค้ด C++ ที่ใช้โดยตรงในแอปพลิเคชันได้
- ต่างจากเครื่องมืออื่น ๆ ตรงที่รองรับเวิร์กโฟลว์ในการแก้ไข UI ที่สร้างขึ้นต่อเนื่อง
-
Data binding
- Event
- การเพิ่มโค้ด UI ด้วยตนเอง
- โค้ดที่สร้างขึ้นจะถูกบันทึกเป็นไฟล์
.hและ.cppและสามารถตรวจสอบได้รวดเร็วผ่าน code preview
-
แพลตฟอร์มที่รองรับและประเภทหน้าต่าง
- ตัว ImRAD เองทำงานบน Windows, Linux, MacOS
- โค้ดที่สร้างขึ้นทำงานบน Windows, Linux, MacOS, Android
- รองรับการออกแบบหน้าต่างหลากหลายรูปแบบ
- หน้าต่างแบบ floating, popup, modal popup
MainWindowที่รวมการทำงานกับ GLFW- ImRAD สร้างการเรียก GLFW เพื่อซิงก์หน้าต่าง ImGui กับ title bar ของหน้าต่าง OS, แฟล็กการปรับขนาด, auto size ฯลฯ
Activity- หน้าต่างแบบไม่มีการตกแต่งที่เติมเต็มพื้นที่ viewport ทั้งหมด
- แสดง activity ได้ครั้งละหนึ่งรายการเท่านั้น
- ใช้กับแอป Android เป็นหลัก
- มีเทมเพลตรวมอยู่ด้วย
main.cppทั่วไปบนฐาน GLFWMainActivity.java,AndroidManifest.xml,main.cpp,CMakeLists.txtสำหรับ Android
วิดเจ็ตและฟังก์ชันเลย์เอาต์
- รองรับวิดเจ็ต ImGui หลากหลาย
- วิดเจ็ตพื้นฐาน เช่น
Text,Checkbox,Combo,Button,Slider,ColorEdit - วิดเจ็ตคอนเทนเนอร์ เช่น
Child,Table,CollapsingHeader,TreeNode,TabBar - วิดเจ็ต เช่น
Splitter,DockSpace - การแก้ไข
MenuBarและ context menu CustomWidgetที่เรียกโค้ดวิดเจ็ตภายนอกได้
- วิดเจ็ตพื้นฐาน เช่น
- เลย์เอาต์ถูกสร้างโดยใช้
SameLine,Spacing,NextColumnแทน ตำแหน่งแบบ absolute- ทำให้วิดเจ็ตปฏิบัติตาม item spacing และ frame padding อย่างสม่ำเสมอ
- ความสัมพันธ์ parent-child และลำดับของ child ที่สำคัญต่อวิดเจ็ตคอนเทนเนอร์อย่าง
Tableจะชัดเจน - รองรับการกำหนดตำแหน่งทางเลือกที่รักษาระยะสัมพันธ์จากมุมของ parent ที่เลือกไว้ ใช้กับวิดเจ็ต overlay ได้
- รองรับ box layout
- กลไกเลย์เอาต์ที่สร้างอยู่บนฟีเจอร์ของ ImGui
- สามารถยืดวิดเจ็ตที่ปรับขนาดได้ในแนวนอนหรือแนวตั้ง
- ใส่ spacer เพื่อสร้างการจัดแนวได้
- ใช้ Table Layout Helper ที่สร้างเลย์เอาต์แนวนอนด้วย
Tableที่มองไม่เห็นได้ด้วย
Binding, event และโค้ดผู้ใช้
- เนื่องจาก ImGui เป็นไลบรารี GUI แบบ immediate mode สถานะของวิดเจ็ต เช่น input text หรือรายการใน combo box ต้องถูกตั้งค่าในโค้ดที่สร้างขึ้น ณ ตอนวาด และ ImRAD จัดการเรื่องนี้ด้วย property binding
- ตัวแปรของคลาสสามารถจัดการได้ด้วย class wizard แบบง่าย หรือผ่านกล่องโต้ตอบ binding
- เมื่อใช้ property binding UI ที่สร้างขึ้นจะทำงานแบบไดนามิกได้ ในขณะที่ยังออกแบบต่อได้
- รองรับการสร้าง event handler และโค้ดสนับสนุน
- ตัวอย่างเช่น modal dialog จะสร้างฟังก์ชันสมาชิก
OpenPopupให้อัตโนมัติ โดยมี lambda callback ที่ถูกเรียกเมื่อปิด - event handler แยกโค้ดประมวลผล event ของผู้ใช้ออกจากส่วนที่สร้างขึ้น เพื่อให้ดีไซเนอร์ยังทำงานต่อได้
- ตัวอย่างเช่น modal dialog จะสร้างฟังก์ชันสมาชิก
- โค้ดที่สร้างขึ้นถูกแยกด้วย comment marker
- ผู้ใช้สามารถใส่โค้ดเพิ่มเติมรอบ ๆ โค้ดที่สร้างขึ้นได้
- ใช้กับการเรียก popup ที่ขึ้นกับ draw หรือการคำนวณตัวแปรบางส่วนได้
- สามารถใช้
CustomWidgetเพื่อมอบหมายงานให้ callback ของผู้ใช้ได้ด้วย
การตั้งค่า สไตล์ และรูปแบบ runtime
- Window configuration คือรูปแบบแปรผันของ UI ที่เปิดใช้งานได้ตอน runtime
- มีประโยชน์กับแพลตฟอร์มที่ต่างกันหรือการหมุนหน้าจอ เป็นต้น
- สไตล์คือการตั้งค่าที่รวมสี ตัวแปรสไตล์ และฟอนต์ไว้ด้วยกัน
- นอกจากสไตล์พื้นฐานของ ImGui แล้ว ผู้ใช้สามารถกำหนดสไตล์ใหม่ได้
- สไตล์สามารถบันทึกเป็นไฟล์ INI ใต้โฟลเดอร์
styleได้
- dialog unit สามารถตั้งเป็นพิกเซลแบบไม่ขึ้นกับอุปกรณ์ได้
- มีประโยชน์กับ Android และแอปที่รองรับ DPI
- ImRAD ติดตามการเปลี่ยนแปลงของไฟล์ที่เปิดอยู่
- ระหว่างออกแบบใน ImRAD ผู้ใช้สามารถแก้ไขไฟล์เดียวกันใน IDE ที่เลือกได้ด้วย
- การเปลี่ยนแปลงสไตล์ INI จะแสดงผลทันทีเช่นกัน
Dependency และตัวเลือกของโค้ดที่สร้างขึ้น
- โค้ดที่สร้างขึ้นสามารถใช้ในโปรเจกต์ได้ทันที และโดยพื้นฐานพึ่งพาเพียงไลบรารี ImGui กับเฮดเดอร์ประกอบ
imrad.hเท่านั้น - ปัจจุบัน
imrad.hมีทั้ง interface และ implementation- หากต้องการสร้าง implementation ใน
main.cppให้ defineIMRAD_H_IMPLEMENTATIONก่อน include
- หากต้องการสร้าง implementation ใน
- โค้ดที่สร้างขึ้นใช้ routine จัดรูปแบบ
ImRad::Format- ใน C++20 โดยพื้นฐานจะ delegate ไปยัง
std::format - หาก define
IMRAD_WITH_FMTจะใช้ไลบรารีfmtได้ - หากไม่มีทั้งสองอย่าง จะใช้ routine จัดรูปแบบแบบง่ายที่ข้ามแฟล็ก formatting
- ใน C++20 โดยพื้นฐานจะ delegate ไปยัง
- ฟีเจอร์บางส่วนต้องการ dependency เพิ่มและการเปิดใช้งานอย่างชัดเจน
- วิดเจ็ต
MainWindowหรือImageต้องการไลบรารีเพิ่มเติม เช่น GLFW, STB - ต้อง define
IMRAD_WITH_LOAD_TEXTURE
- วิดเจ็ต
imrad.hสามารถใช้ไลบรารี zlib เพื่อโหลด asset จากไฟล์ zip ได้- เปิดใช้งานด้วย
IMRAD_WITH_MINIZIP
- เปิดใช้งานด้วย
- สามารถสร้างโค้ดที่มีสตริงแปลภาษาได้
- เมื่อคอมไพล์
imrad.hด้วยIMRAD_WITH_GETTEXTจะสามารถแปลด้วย gettext/libintl ได้ - สามารถใช้ libintl-lite ที่ไม่มี dependency ได้เช่นกัน
- เมื่อคอมไพล์
ไลเซนส์และการเผยแพร่
- ซอร์สโค้ดของ ImRAD ใช้ ไลเซนส์ GPL
- โค้ดที่เครื่องมือสร้างขึ้นได้รับการยกเว้นจาก GPL
- สามารถรวมไว้ในโปรเจกต์โอเพนซอร์สหรือเชิงพาณิชย์ได้
- ผู้ใช้เป็นผู้กำหนดไลเซนส์ของโค้ดที่สร้างขึ้น
imrad.hที่โค้ดที่สร้างขึ้นใช้งานก็ได้รับการยกเว้นจาก GPL เช่นกัน- เวอร์ชันล่าสุดให้ clone repository แล้ว build ด้วย CMake
- ต้องดึง submodule ในไดเรกทอรี
3rdpartyมาด้วย
- ต้องดึง submodule ในไดเรกทอรี
- เวอร์ชันที่ค่อนข้างเก่าสามารถดาวน์โหลดได้จาก Releases
- ดู tutorial และเอกสารโดยละเอียดได้ที่ wiki
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
หนึ่งในส่วนที่น่าทึ่งที่สุดของโปรเจกต์นี้คือ มันมี parser ที่ทำเอง สำหรับอ่าน subset ของ C++ ที่ตัวมันเองสร้างได้
ทั้งหมดทำเป็น header เดียว น่าประทับใจแต่ก็ดูบ้าบิ่นเหมือนกัน
https://github.com/tpecholt/imrad/blob/main/src/cpp_parser.h
ผมไม่ค่อยคุ้นกับการเขียนโปรแกรม เลยเข้าใจแค่ว่าโปรเจกต์นี้มีบางอย่างที่อ่านข้อมูลได้
ช่วยอธิบายได้ไหมว่าทำไมเครื่องมือที่อ่าน C++ ได้ถึงยอดเยี่ยมขนาดนั้น
เจ๋งมาก อาจเป็นเพราะ ความคิดถึง Visual Basic ก็ได้ แต่สำหรับผมโปรเจกต์นี้เหมือนเชอร์รีบนหน้าเค้กของ imgui เลย
ถ้าทำเป็น แอป wasm HTML5 เพื่อให้สร้าง GUI ในเบราว์เซอร์ได้เร็ว ๆ แล้วคัดลอกผลลัพธ์ไปวางใน editor ได้ ก็น่าจะเจ๋ง
เห็นบอกว่า “สร้างและ parse โค้ด C++ และโค้ดนี้สามารถนำไปใช้ในแอปพลิเคชันได้ทันที” เลยสงสัยว่า parse ในที่นี้คือการอ่านโค้ดที่ตัวเองสร้างขึ้นกลับเข้าไปใหม่หรือเปล่า
ดูเหมือนว่าจะเอาไว้อ่านโค้ดที่ตัวเองสร้างขึ้นจริง ๆ parser ที่ทำเองนี้ไม่ได้รองรับทั้งภาษา แต่รองรับแค่ subset เท่านั้น
เช่น มีการ hardcode การรู้จำ STL container ไว้ และน่าจะจัดการเฉพาะสิ่งที่อาจปรากฏในโค้ดที่สร้างขึ้นเท่านั้น
ในขั้นตอนนี้ไม่ได้สร้าง abstract syntax tree (AST) ดูเหมือนจะทำ tokenization กับ lexical analysis แล้วปล่อยให้ฝั่งผู้เรียกต้องเข้าใจเองว่าจะขับเคลื่อน “state machine” ของการ parse ต่ออย่างไร
ส่วนการสร้าง AST และ code generation น่าจะอยู่ในไฟล์นี้ที่ยาวกว่า 9,000 บรรทัด: https://github.com/tpecholt/imrad/blob/main/src/node.cpp
เขียนไว้ว่า “ImRAD รันได้บน Windows, Linux, MacOS”
ยอดเยี่ยม ช่วงหลายปีที่ผ่านมาผมกำลังทำแอป ImGui C++ อยู่ ถ้ามีสิ่งนี้ตอนนั้นคงประหยัดเวลาได้มาก
ถ้าผู้สร้าง dear-imgui บอกว่าชื่อคือ “dear” งั้นควรพูดว่า “for the Dear library” ไม่ใช่หรือ?
IMGUI หมายถึง immediate mode GUI และ ocornut เคยบอกว่าได้รับแรงบันดาลใจจาก IMGUI อีกตัวที่ชื่อ “simgui”
“หลังจากนั้นประมาณ 15 เดือนก็เปลี่ยนชื่อเป็น ‘dear imgui’ เพราะ ‘imgui’ ไปครอบครองตัวย่อทั้งหมดอยู่ ขอโทษที่ยังทำให้สับสนมาจนถึงตอนนี้”
https://github.com/ocornut/imgui/issues/7892
ชื่อ namespace ก็เป็น ImGui และไม่ใช่แค่ “Dear” อย่างเดียวแน่นอน
คิดว่าไม่ควรใส่ sudo ลงไปเยอะเกินไป นอกนั้นดูเจ๋งจริง ๆ
สงสัยว่า โค้ด C++ ที่สร้างขึ้นจะนำไปใช้ในที่อย่าง Python ตอนใช้ binding ของ pyimgui ได้ไหม
สงสัยว่าทำไม GUI builder สำหรับ ImGui ถึงไม่ได้สร้างด้วย ตัว ImGui เอง
เจ๋ง กำลังทำโปรเจกต์ด้วย ImGui อยู่ และคิดมาตลอดว่าน่าจะมีอะไรแบบนี้ จะลองใช้ดู
Steam เป็นระบบข้ามแพลตฟอร์มยอดนิยม ใช้กับแอปพลิเคชันที่ไม่ใช่เกมได้ไหม? หรือแม้แต่กับ แอปพลิเคชันระดับองค์กร ได้ไหม?
เช่น หลายบรรทัด ฟอนต์ และบางกรณีฟีเจอร์อย่าง RTL แต่ ImGUI ยังขาดด้านนี้อยู่