4 पॉइंट द्वारा GN⁺ 2024-05-26 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • 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.Control interface को 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 लगाया जाता है
  • custom components को spot.Component interface implement करने वाले struct के रूप में बनाया जा सकता है
    • इस interface में एक single method Render(ctx *spot.RenderContext) spot.Component होता है
    • इस तरह बने components को built-in components की तरह ही उपयोग किया जा सकता है
  • 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.Component interface implement करने वाला और native widgets को manage करने वाला struct बनाना होगा
  • spot/ui को Cocoa या FLTK के अलावा किसी और backend के साथ इस्तेमाल करना अभी supported नहीं है

Rendering lifecycle की शब्दावली

  • Make: spot.Component interface implement करने वाले struct instance को बनाना, या render function के साथ spot.Make call करके नया 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 का उपयोग करके यह किया जा सकता है
  • Update: mounted control tree को update करना
    • यह tree node के Update को call करके किया जाता है

वे सुविधाएँ जो अभी उपलब्ध नहीं हैं

  • 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 और custom NSButton का उपयोग
    • 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 का उपयोग
  • कुछ 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 टिप्पणियां

 
GN⁺ 2024-05-26
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 मिल गया

    • go-fltk Windows पर भी build और run होता है, और सच में काफ़ी अच्छे से काम करता है
      यह देखकर प्रभावित हुआ कि 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/ भी मिला और इसे आज़माना चाहता हूँ
    • WxWindows मुझे बहुत पसंद है, लेकिन इन दिनों मैं Go में बहुत गहराई तक जा चुका हूँ
      self-contained Spot “Hello World” मेरे Mac पर 2.3MiB है। सुंदर नहीं है, लेकिन मेरे लिए पर्याप्त काम करता है
    • wxGo मौजूद है, लेकिन अफ़सोस कि project maintained नहीं है
  • यूज़र को दिखने वाले controls को सीधे update करने की तुलना में, virtual control tree approach का फायदा क्या है, यह जानना चाहता हूँ

    • जटिल हालात में, जैसे user UI से interact कर रहा हो और साथ ही background में लंबा चलने वाला काम भी UI state बदल रहा हो, state management जल्दी ही संभालना मुश्किल हो जाता है
      जगह-जगह 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?

    • Windows पर शायद FLTK इस्तेमाल करता है, बस native support अभी नहीं लगता
    • WSL इस्तेमाल कर लो
  • काश मुझे इसके बारे में 3 हफ्ते पहले पता होता, या commit history के हिसाब से यह तब पहले से मौजूद होता। मैं बहुत समय से कहता आया हूँ कि Go में port किया गया React या Go के लिए React जैसा framework हो तो development experience जबरदस्त होगा, और यह बिल्कुल वैसा ही लगता है
    React.lua से समझ आने तक मुझे React.js काफ़ी नापसंद था

    • मेरी भी यही समस्या थी। React में वाला component composition तरीका मुझे सच में बहुत पसंद था, और उससे वापस जाना मुश्किल था
      आखिरकार मुझे Go standard html/template से ही वैसा कुछ करने का तरीका मिला, और implementation details यहाँ लिखीं: https://www.sheshbabu.com/posts/react-like-composition-using...
    • उत्सुक हूँ कि 3 हफ्ते पहले आप इसके बजाय क्या इस्तेमाल कर रहे थे
  • Desktop के लिए release करने पर आम तौर पर web version भी चाहिए होता है, यह बड़ी समस्या है। खासकर अगर वह ऐसा बहुत niche app न हो जो operating system के साथ बहुत interact करता हो
    या फिर mobile समेत कई platforms को target करने वाली कोई चीज़ चाहिए होती है
    काफ़ी लंबे समय तक खोजा, लेकिन सबसे करीब Qt और React Native थे, और दोनों ही कई कारणों से तकलीफ़देह विकल्प थे

  • FLTK Windows support करता है। क्या किसी दूसरे solution को इस्तेमाल करने की योजना की वजह से अभी Windows support नहीं है?

    • अगर सही C compiler वगैरह environment मौजूद हो, तो Spot Windows पर भी बिना बदलाव के चलता है और FLTK backend चुनना चाहिए
      हालांकि मेरा लक्ष्य, भले ही priority कम है, Win32-based backend implement करना है, और पहला step पूरा हो गया है: https://github.com/roblillack/spot/pull/4