Spot - Go भाषा के लिए React-जैसा डेस्कटॉप GUI टूलकिट
(github.com/roblillack)- Spot, Go में cross-platform desktop GUI बनाने के लिए एक सरल reactive toolkit है, जो जहाँ संभव हो native widgets का उपयोग करता है और platform-specific APIs को एक consistent रूप में प्रदान करता है
- एप्लिकेशन state बदलने पर यह immutable component tree को फिर से बनाता है और पिछली state से तुलना करके तय करता है कि किन UI controls को अपडेट करना है
- वर्तमान backend, macOS पर Cocoa और अन्य platforms पर FLTK आधारित implementation है, और macOS पर भी वैकल्पिक रूप से FLTK का उपयोग किया जा सकता है
spotएक backend-independent core package है जो reactive model और rendering देता है, जबकिspot/uiपहले से बने cross-platform GUI controls का संग्रह है- automatic layout, multiple windows, modal dialogs, resizable windows, menu bar, custom widgets, native widget access, drag and drop, internationalization अभी उपलब्ध नहीं हैं
Spot का उद्देश्य और बुनियादी मॉडल
- Spot, Go के लिए एक reactive GUI toolkit है, जिसे इस तरह डिजाइन किया गया है कि जहाँ संभव हो native widgets का उपयोग करते हुए कई platforms पर consistent API दी जा सके
- इसे project में एक simple dependency के रूप में जोड़कर सिर्फ Go code लिखना होता है, और किसी अतिरिक्त tool या code generation के बिना self-contained native GUI binaries बनाई जा सकती हैं
- उदाहरण
ui.Init(),spot.MountFn(...),ui.Run()flow के साथ window और button बनाता है, औरspot.UseState[int](<https://github.com/roblillack/ctx, 0>)से click count state को manage करता है - button click handler,
setCounter(counter + 1)को call करता है, और state बदलने पर button title"Clicked %d times!"फॉर्मेट में बदल जाता है
Reactive update का तरीका
- Spot में reactive का मतलब है कि application state बदलने पर UI अपने-आप update होती है
- state change होने पर immutable component tree को फिर से बनाया जाता है, और पुरानी state से तेज़ी से तुलना करके तय किया जाता है कि कौन से UI controls update करने हैं
- वेब में इस विचार को आमतौर पर virtual DOM कहा जाता है, और Spot इस concept को Go desktop environment में लाता है; इसकी शुरुआत React-जैसी GUI library बनाने के एक experiment से हुई थी
- developer, UI को manually update करने के बजाय side-effect-free rendering functions और
UseStateजैसे hooks से application logic और state को manage करता है
Backend और package संरचना
- Spot compile समय पर चल रहे platform के अनुसार backend को अपने-आप चुनता है
- अभी दो backend उपलब्ध हैं
- FLTK आधारित implementation: go-fltk का उपयोग
- Cocoa आधारित implementation: gocoa के modified version का उपयोग
- macOS पर Cocoa backend उपयोग होता है, और अन्य platforms पर FLTK आधारित backend उपयोग होता है
- macOS पर वैकल्पिक रूप से FLTK भी इस्तेमाल किया जा सकता है, जबकि Windows support में सुधार भविष्य की योजना में है
spotएक core package है जो reactive model और rendering functionality देता है, औरspot.Controlinterface को implement करने वाले किसी भी control set के साथ इस्तेमाल किया जा सकता हैspot/ui, Spot के साथ उपयोग के लिए तैयार cross-platform GUI controls package है
Components, controls और hooks
- React की तरह custom hooks बनाए जा सकते हैं
- पहला argument
*spot.RenderContextलेने वाला function बनाकरspot.UseState,spot.UseEffectआदि call किए जाते हैं, जिससे वे Spot lifecycle से जुड़ जाते हैं - convention के अनुसार function name में
Use…prefix लगाया जाता है
- पहला argument
- custom components को
spot.Componentinterface implement करने वाले struct के रूप में बनाया जा सकता है- इस interface में एक single method
Render(ctx *spot.RenderContext) spot.Componentहोता है - इस तरह बने components को built-in components की तरह ही उपयोग किया जा सकता है
- इस interface में एक single method
- Spot में component business logic और state रखने वाली logical unit है
- components, दूसरे components से मिलकर बनते हैं, और अंत में एक या अधिक controls के रूप में render होते हैं
- control एक special component है जो UI tree में mount होता है और स्क्रीन के visual element को दर्शाता है
- आमतौर पर यह button, label, text input जैसे GUI backend के native implementations पर आधारित होता है
- दिए गए widget library के अलावा पूरी तरह अलग widget library भी इस्तेमाल की जा सकती है
- इसके लिए
spot.Componentinterface implement करने वाला और native widgets को manage करने वाला struct बनाना होगा
- इसके लिए
spot/uiको Cocoa या FLTK के अलावा किसी और backend के साथ इस्तेमाल करना अभी supported नहीं है
Rendering lifecycle की शब्दावली
- Make:
spot.Componentinterface implement करने वाले struct instance को बनाना, या render function के साथspot.Makecall करके नया component instance बनाना - Render: component state को उसके elements पर लागू करना और दूसरा component instance लौटाना
- Build: components को recursively render करके control tree बनाना
- इसके लिए
spot.Buildमें component instance पास किया जाता है, याspot.BuildFnमें render function देकर चलाया जाता है
- इसके लिए
- Mount: virtual control tree से actual UI controls बनाना
- tree node के
Mountको call करके, याspot.Mount,spot.MountFnका उपयोग करके यह किया जा सकता है
- tree node के
- Update: mounted control tree को update करना
- यह tree node के
Updateको call करके किया जाता है
- यह tree node के
वे सुविधाएँ जो अभी उपलब्ध नहीं हैं
- Spot फिलहाल ये सुविधाएँ प्रदान नहीं करता
-
automatic layout
- multiple windows
- modal dialogs
- resizable windows
- menu bar
- custom widgets
- native widget access
- drag and drop
- internationalization
-
समर्थित UI controls
- Spot, button, label, text input, slider, dropdown आदि कई UI controls मूल रूप से प्रदान करता है
- support status को ❓ not implemented, 🚧 in progress, ⚠️ partially implemented, ✅ complete के रूप में दिखाया जाता है
- मुख्य पूर्ण controls ये हैं
- Button: simple action button,
Fl_ButtonऔरNSButtonका उपयोग - Checkbox: दो विकल्पों में से एक चुनने वाला control,
Fl_Check_ButtonऔरNSButtonका उपयोग - Dropdown: कई items में से एक चुनने वाला dropdown,
Fl_ChoiceऔरNSComboBoxका उपयोग - Image: bitmap image दिखाने वाला control,
Fl_Boxऔर customNSButtonका उपयोग - Label: non-editable text label,
Fl_BoxऔरNSTextFieldका उपयोग - ListBox: single या multi-selection list control,
Fl_Select_Browser/Fl_Multi_BrowserऔरNSTableViewका उपयोग - ProgressBar: long-running task progress दिखाने वाला control,
Fl_ProgressऔरNSProgressIndicatorका उपयोग - Slider: horizontal slider input,
Fl_SliderऔरNSSliderका उपयोग - Spinner: ऊपर/नीचे buttons वाला numeric input,
Fl_SpinnerऔरNSTextField+NSStepperका उपयोग - TextField: single-line text input,
Fl_InputऔरNSTextFieldका उपयोग - TextEditor: multi-line text editing,
Fl_Text_EditorऔरNSTextViewका उपयोग - Window: top-level window control,
Fl_WindowऔरNSWindowका उपयोग
- Button: simple action button,
- कुछ controls partially implemented या not implemented भी हैं
- Dial: circular state control, और ⚠️ partially implemented स्थिति में है
- ComboBox: text input के साथ जुड़ा dropdown menu, जिस पर अभी काम शुरू नहीं हुआ है
- संभावित भविष्य backend उम्मीदवार के रूप में native Windows controls library
https://github.com/rodrigocfd/windigoका उल्लेख किया गया है
1 टिप्पणियां
Hacker News की राय
इसे ज़रूर देखना पड़ेगा। मैं Go में internal development tools बनाने का कोई आसान तरीका ढूँढ रहा था, जो असल में buttons और text fields वाले forms जितना ही है
Gio भी आज़माया था, लेकिन समझना मुश्किल लगा, और अभी मैं wails इस्तेमाल कर रहा हूँ, जो मुझे काफ़ी ज़्यादा पसंद है। यह project भी दिलचस्प है और देखने लायक लगता है
“Cross platform: FLTK[1] और Cocoa[2] का उपयोग करके Spot Mac, Linux, BSD पर चलता है, और आगे native Windows support की योजना है” वाली दिशा को गंभीरता से घटाने की सलाह दूँगा
सीखी गई बातें संभालकर रखिए ताकि बाद में flexibility बनी रहे, लेकिन पहले एक toolkit में अच्छा करना बेहतर है। GUI toolkit, GUI bindings और GUI खुद वैसे भी details में फँसकर डूब जाने वाली चीज़ें हैं; अगर आप कई underlying toolkits की details भी खुद उठाने लगेंगे, तो अंत में किसी भी toolkit को ठीक से न कर पाने की संभावना बड़ी है
कहा जाता है, “पहले 90% में काम का 90% होता है, और बचा 10% एक और 90% होता है,” लेकिन GUI में यह भी कुछ ज़्यादा ही optimistic लगता है। पहला 10% काम का 90% है, अगला 10% उसका 10 गुना है, और उसके बाद वाला 10% फिर 10 गुना। Cross platform की कोशिश गले में फंदा कस सकती है
मुझे उम्मीद नहीं कि आप अभी इस बात से सहमत होंगे, लेकिन जब बाद में आपको ऐसी स्थिति मिले कि तीन toolkits rich text handling जैसी चीज़ों को तीन परस्पर विरोधी तरीकों से मजबूर कर रहे हैं, तो खुद को यह अनुमति दें कि सबसे अच्छी तरह supported या सबसे लोकप्रिय underlying toolkit को रखकर बाकी छोड़ सकते हैं
Go में मैं काफ़ी समय से ऐसी चीज़ ढूँढ रहा था। Go का build process सरल है, इसलिए cross-platform UI में बेहतरीन developer experience देने का बड़ा मौका दिखता है
मेरे अनुभव में cross-platform development की आधी परेशानी build complexity manage करने में होती है, और Go उसे लगभग हटा देता है
हालांकि native controls के default sizes हर platform पर अलग होते हैं, तो उत्सुक हूँ कि cross-platform layout को कैसे हल किया जाएगा। यह हिस्सा दूसरे cross-platform toolkits में भी बहुत अच्छी तरह सुलझा हुआ नहीं देखा। फिर भी शुभकामनाएँ
कुछ साल पहले मैं ऐसी चीज़ खोज रहा था। लेकिन Windows support भी चाहिए था। आखिरकार wxWidgets इस्तेमाल करने के लिए C++ पर चला गया, और छोटा self-contained binary मिल गया
यह देखकर प्रभावित हुआ कि native toolkit होते हुए भी FLTK browser की तरह Ctrl-+ और Ctrl+- से पूरे app का zoom in/out support करता है। और https://github.com/fltk-rs/fltk-theme?tab=readme-ov-file#wid... की वजह से FLTK को कितना “native” जैसा दिखाया जा सकता है, इस बारे में मेरी धारणा बेहतर हुई
इसी संदर्भ में हाल ही में GoVCL https://z-kit.cc/en/ भी मिला और इसे आज़माना चाहता हूँ
self-contained Spot “Hello World” मेरे Mac पर 2.3MiB है। सुंदर नहीं है, लेकिन मेरे लिए पर्याप्त काम करता है
यूज़र को दिखने वाले controls को सीधे update करने की तुलना में, virtual control tree approach का फायदा क्या है, यह जानना चाहता हूँ
जगह-जगह callback code लिखना पड़ता है, और हर callback को बाकी सभी activities की current state सावधानी से check करके दर्जनों widgets update करने पड़ सकते हैं
Reactive approach में आप किसी दिए गए state के लिए interface describe करने वाला एक single rendering function लिखते हैं, और framework संभालता है कि उसे कब call करना है और कौन-सा input देना है। इसे समझना कहीं आसान है, और React इस्तेमाल करने के बाद पीछे लौटना मुश्किल होता है, इसलिए Go में भी ऐसा कुछ संभव है या नहीं, इसे experiment करने लगा
अच्छा लग रहा है। क्या README में supported platforms लिख सकते हैं?
Windows, Linux, macOS, *BSD, Android, iOS, Web, Tizen जैसी जानकारी काफ़ी दिलचस्प होगी
Flutter docs की तरह लिखना भी ठीक रहेगा: https://docs.flutter.dev/reference/supported-platforms
कोशिश काबिले-तारीफ़ है, लेकिन Windows support के बिना cross platform?
काश मुझे इसके बारे में 3 हफ्ते पहले पता होता, या commit history के हिसाब से यह तब पहले से मौजूद होता। मैं बहुत समय से कहता आया हूँ कि Go में port किया गया React या Go के लिए React जैसा framework हो तो development experience जबरदस्त होगा, और यह बिल्कुल वैसा ही लगता है
React.lua से समझ आने तक मुझे React.js काफ़ी नापसंद था
आखिरकार मुझे Go standard
html/templateसे ही वैसा कुछ करने का तरीका मिला, और implementation details यहाँ लिखीं: https://www.sheshbabu.com/posts/react-like-composition-using...Desktop के लिए release करने पर आम तौर पर web version भी चाहिए होता है, यह बड़ी समस्या है। खासकर अगर वह ऐसा बहुत niche app न हो जो operating system के साथ बहुत interact करता हो
या फिर mobile समेत कई platforms को target करने वाली कोई चीज़ चाहिए होती है
काफ़ी लंबे समय तक खोजा, लेकिन सबसे करीब Qt और React Native थे, और दोनों ही कई कारणों से तकलीफ़देह विकल्प थे
FLTK Windows support करता है। क्या किसी दूसरे solution को इस्तेमाल करने की योजना की वजह से अभी Windows support नहीं है?
हालांकि मेरा लक्ष्य, भले ही priority कम है, Win32-based backend implement करना है, और पहला step पूरा हो गया है: https://github.com/roblillack/spot/pull/4