4 poin oleh GN⁺ 2024-05-26 | 1 komentar | Bagikan ke WhatsApp
  • Spot adalah toolkit reaktif sederhana untuk membuat GUI desktop lintas platform di Go; ia menggunakan widget native jika memungkinkan dan menyediakan API yang konsisten untuk tiap platform
  • Saat status aplikasi berubah, Spot membangun ulang pohon komponen immutable lalu membandingkannya dengan status sebelumnya untuk menentukan kontrol UI mana yang perlu diperbarui
  • Backend saat ini berbasis Cocoa untuk macOS dan FLTK untuk platform lain; di macOS, FLTK juga bisa digunakan secara opsional
  • spot adalah paket inti yang tidak bergantung pada backend, menyediakan model reaktif dan rendering, sedangkan spot/ui adalah kumpulan kontrol GUI lintas platform siap pakai
  • Tata letak otomatis, banyak jendela, dialog modal, jendela yang dapat diubah ukurannya, menu bar, widget kustom, akses ke widget native, drag-and-drop, dan internasionalisasi belum tersedia

Tujuan dan model dasar Spot

  • Spot adalah toolkit GUI reaktif untuk Go, dirancang untuk menggunakan widget native jika memungkinkan sekaligus menyediakan API yang konsisten di berbagai platform
  • Dengan menambahkannya sebagai dependensi sederhana ke proyek dan hanya menulis kode Go, Anda dapat membuat binary GUI native yang self-contained tanpa alat tambahan atau code generation
  • Contohnya membuat jendela dan tombol dengan alur ui.Init(), spot.MountFn(...), ui.Run(), serta mengelola status jumlah klik dengan spot.UseState[int](<https://github.com/roblillack/ctx, 0>)
  • Handler klik tombol memanggil setCounter(counter + 1), dan ketika status berubah, judul tombol berubah dalam format "Clicked %d times!"

Cara pembaruan reaktif

  • Di Spot, reactive berarti UI diperbarui secara otomatis saat status aplikasi berubah
  • Saat status berubah, Spot membangun ulang pohon komponen immutable, lalu membandingkannya dengan cepat terhadap status sebelumnya untuk menentukan kontrol UI mana yang akan diperbarui
  • Di web, gagasan ini sering disebut virtual DOM, dan Spot bermula dari eksperimen membawa konsep ini ke lingkungan desktop Go untuk mengimplementasikan library GUI yang mirip React
  • Alih-alih memperbarui UI secara manual, developer mengelola logika dan status aplikasi dengan fungsi rendering tanpa efek samping serta hook seperti UseState

Backend dan struktur paket

  • Spot secara otomatis memilih backend yang sesuai dengan platform eksekusi saat kompilasi
  • Saat ini tersedia dua backend
  • Di macOS, Spot menggunakan backend Cocoa, sedangkan di platform lain menggunakan backend berbasis FLTK
  • Di macOS, FLTK juga bisa digunakan secara opsional, dan peningkatan dukungan Windows masih menjadi rencana ke depan
  • spot adalah paket inti yang menyediakan model reaktif dan kemampuan rendering, serta dapat digunakan dengan kumpulan kontrol apa pun yang mengimplementasikan antarmuka spot.Control
  • spot/ui adalah paket kontrol GUI lintas platform siap pakai yang dapat digunakan bersama Spot

Komponen, kontrol, dan hook

  • Seperti React, Anda dapat membuat hook kustom
    • Buat fungsi yang menerima *spot.RenderContext sebagai argumen pertama, lalu panggil spot.UseState, spot.UseEffect, dan lainnya untuk menghubungkannya ke lifecycle Spot
    • Secara konvensi, nama fungsi diberi prefiks Use…
  • Komponen kustom dapat dibuat sebagai struct yang mengimplementasikan antarmuka spot.Component
    • Antarmuka ini memiliki satu metode, Render(ctx *spot.RenderContext) spot.Component
    • Komponen yang dibuat dengan cara ini dapat digunakan dengan cara yang sama seperti komponen bawaan
  • Di Spot, component adalah unit logis yang memuat logika bisnis dan status
    • Komponen tersusun dari komponen lain, dan pada akhirnya dirender menjadi satu atau lebih kontrol
  • control adalah komponen khusus yang di-mount ke pohon UI dan merepresentasikan elemen visual di layar
    • Umumnya berbasis implementasi native dari backend GUI, seperti tombol, label, atau input teks
  • Library widget yang sepenuhnya berbeda dari library widget yang disediakan juga dapat digunakan
    • Cukup buat struct yang mengimplementasikan antarmuka spot.Component dan mengelola widget native
  • Penggunaan spot/ui dengan backend selain Cocoa atau FLTK saat ini belum didukung

Istilah lifecycle rendering

  • Make: proses membuat instance struct yang mengimplementasikan antarmuka spot.Component, atau memanggil spot.Make bersama fungsi render untuk membuat instance komponen baru
  • Render: proses menerapkan status komponen ke elemen penyusunnya dan mengembalikan instance komponen lain
  • Build: proses merender komponen secara rekursif untuk membuat pohon kontrol
    • Dilakukan dengan meneruskan instance komponen ke spot.Build, atau meneruskan fungsi render ke spot.BuildFn
  • Mount: proses membuat kontrol UI nyata dari pohon kontrol virtual
    • Dapat dilakukan dengan memanggil Mount pada node pohon, atau menggunakan spot.Mount, spot.MountFn
  • Update: proses memperbarui pohon kontrol yang sudah di-mount
    • Dilakukan dengan memanggil Update pada node pohon

Fitur yang saat ini belum disediakan

  • Spot saat ini belum menyediakan fitur berikut
    • Tata letak otomatis

      • Banyak jendela
      • Dialog modal
      • Jendela yang dapat diubah ukurannya
      • Menu bar
      • Widget kustom
      • Akses ke widget native
      • Drag-and-drop
      • Internasionalisasi

Kontrol UI yang didukung

  • Spot menyediakan beberapa kontrol UI secara default, seperti tombol, label, input teks, slider, dan dropdown
  • Penanda status dukungan dibagi menjadi ❓ belum diimplementasikan, 🚧 sedang dikerjakan, ⚠️ implementasi parsial, dan ✅ selesai
  • Kontrol utama yang sudah selesai adalah sebagai berikut
    • Button: tombol untuk menjalankan aksi sederhana, menggunakan Fl_Button dan NSButton
    • Checkbox: kontrol untuk memilih salah satu dari dua opsi, menggunakan Fl_Check_Button dan NSButton
    • Dropdown: dropdown untuk memilih salah satu dari beberapa item, menggunakan Fl_Choice dan NSComboBox
    • Image: kontrol untuk menampilkan gambar bitmap, menggunakan Fl_Box dan NSButton kustom
    • Label: label teks yang tidak dapat diedit, menggunakan Fl_Box dan NSTextField
    • ListBox: kontrol daftar dengan pilihan tunggal atau ganda, menggunakan Fl_Select_Browser/Fl_Multi_Browser dan NSTableView
    • ProgressBar: penampil progres untuk pekerjaan jangka panjang, menggunakan Fl_Progress dan NSProgressIndicator
    • Slider: input slider horizontal, menggunakan Fl_Slider dan NSSlider
    • Spinner: input angka dengan tombol naik/turun, menggunakan Fl_Spinner dan NSTextField+NSStepper
    • TextField: input teks satu baris, menggunakan Fl_Input dan NSTextField
    • TextEditor: editor teks multi-baris, menggunakan Fl_Text_Editor dan NSTextView
    • Window: kontrol jendela tingkat atas, menggunakan Fl_Window dan NSWindow
  • Ada juga kontrol dengan implementasi parsial atau belum diimplementasikan
    • Dial: kontrol status melingkar dan berstatus ⚠️ implementasi parsial
    • ComboBox: menu dropdown yang digabungkan dengan input teks dan belum dimulai
  • Library kontrol Windows native https://github.com/rodrigocfd/windigo disebut sebagai kandidat backend potensial di masa depan

1 komentar

 
GN⁺ 2024-05-26
Opini Hacker News
  • Ini wajib saya lihat. Saya sedang mencari cara sederhana untuk membuat tool pengembangan internal dengan Go, yang pada dasarnya hanya setingkat form dengan tombol dan field teks.
    Saya juga pernah mencoba Gio, tetapi sulit dipahami, dan sekarang saya memakai wails yang jauh lebih saya sukai. Proyek ini juga menarik dan tampaknya layak ditelusuri.

  • Saya sangat menyarankan untuk benar-benar mengurangi arah “Lintas platform: Dengan memanfaatkan FLTK[1] dan Cocoa[2], Spot berjalan di Mac, Linux, BSD, dengan rencana dukungan Windows native di masa depan.”
    Simpan saja pelajarannya agar fleksibilitas di masa depan tetap ada, tetapi sebaiknya kuasai dulu satu toolkit. GUI toolkit, binding GUI, dan GUI itu sendiri memang mudah sekali tenggelam dalam detail, dan kalau Anda dengan sukarela menanggung detail dari beberapa toolkit dasar sekaligus, besar kemungkinan akhirnya tidak ada satu toolkit pun yang benar-benar dikuasai.
    Ada ungkapan “90% pertama adalah 90% pekerjaan, dan 10% sisanya adalah 90% lagi,” tetapi untuk GUI, itu pun terasa terlalu optimistis. 10% pertama adalah 90% pekerjaan, 10% berikutnya 10 kali lipatnya, dan 10% setelah itu juga 10 kali lipat lagi. Mencoba lintas platform bisa membuat Anda tercekik.
    Saya tidak berharap Anda langsung setuju dengan pendapat ini sekarang, tetapi nanti ketika Anda menghadapi situasi di mana tiga toolkit memaksakan tiga cara yang saling bertentangan untuk menangani hal seperti rich text, semoga Anda mengizinkan diri sendiri untuk menyisakan hanya toolkit dasar yang paling baik didukung atau paling populer, dan membuang sisanya.

  • Saya sudah cukup lama mencari hal seperti ini di Go. Menurut saya Go punya peluang besar untuk memberikan developer experience yang bagus pada UI lintas platform karena proses build-nya sederhana.
    Berdasarkan pengalaman, setengah dari penderitaan pengembangan lintas platform adalah mengelola kompleksitas build, dan Go hampir menghilangkan itu.
    Namun ukuran default kontrol native berbeda-beda di tiap platform, jadi saya penasaran bagaimana layout lintas platform akan diselesaikan. Saya belum pernah melihat bagian ini diselesaikan dengan sangat baik di toolkit lintas platform lain. Bagaimanapun, semoga sukses.

  • Beberapa tahun lalu saya mencari hal seperti ini. Namun saya juga butuh dukungan Windows. Akhirnya saya beralih ke C++ untuk memakai wxWidgets, dan bisa mendapatkan binary kecil yang self-contained.

    • go-fltk juga bisa dibuild dan dijalankan di Windows, dan sebenarnya bekerja cukup baik.
      Saya terkesan melihat FLTK, meski merupakan toolkit native, mendukung zoom in/out seluruh aplikasi dengan Ctrl-+ dan Ctrl+- seperti browser. Dan berkat https://github.com/fltk-rs/fltk-theme?tab=readme-ov-file#wid..., kesan saya membaik tentang seberapa “native” tampilan FLTK bisa dibuat.
      Terkait itu, baru-baru ini saya juga menemukan GoVCL https://z-kit.cc/en/ dan ingin mencobanya.
    • Saya sangat menyukai WxWindows, tetapi sekarang saya sudah terlalu dalam memakai Go.
      Spot “Hello World” yang self-contained berukuran 2.3MiB di Mac saya. Tidak cantik, tetapi cukup berfungsi bagi saya.
    • Memang ada wxGo, tetapi sayangnya proyeknya tidak lagi dipelihara.
  • Saya penasaran apa keunggulan pendekatan pohon kontrol virtual dibandingkan cara memperbarui langsung kontrol yang ditampilkan kepada pengguna.

    • Dalam situasi kompleks, misalnya ketika pengguna berinteraksi dengan UI sementara pekerjaan yang berjalan lama di background juga mengubah state UI, manajemen state bisa cepat menjadi tidak terkendali.
      Anda harus menulis kode callback di mana-mana, dan setiap callback mungkin perlu memeriksa dengan hati-hati status terkini dari semua aktivitas lain sebelum memperbarui puluhan widget.
      Dalam pendekatan reaktif, Anda menulis satu fungsi render yang mendeskripsikan antarmuka untuk state tertentu, lalu framework menangani kapan fungsi itu dipanggil dan input apa yang diberikan. Ini jauh lebih mudah dipahami, dan setelah memakai React, sulit untuk kembali, sehingga saya bereksperimen apakah hal serupa bisa dilakukan di Go.
  • Terlihat bagus. Saya penasaran apakah README bisa mencantumkan platform yang didukung.
    Informasi seperti Windows, Linux, macOS, *BSD, Android, iOS, Web, Tizen rasanya cukup menarik.
    Mungkin bisa ditulis seperti dokumentasi Flutter: https://docs.flutter.dev/reference/supported-platforms

  • Usahanya patut diapresiasi, tetapi lintas platform tanpa dukungan Windows?

    • Sepertinya di Windows mereka memakai FLTK, hanya saja dukungan native belum ada.
    • Pakai saja WSL.
  • Andai saya tahu ini 3 minggu lalu, atau andai dari riwayat commit proyek ini sudah ada saat itu. Sejak lama saya mengatakan bahwa React yang dip port ke Go atau framework mirip React untuk Go akan memberikan pengalaman pengembangan yang luar biasa, dan ini tampaknya sangat pas.
    Saya dulu cukup tidak suka React.js sampai akhirnya tersadar lewat React.lua.

    • Saya juga punya masalah yang sama. Saya sangat menyukai cara komposisi komponen di React, dan sulit kembali.
      Akhirnya saya menemukan cara melakukan hal serupa hanya dengan html/template standar Go, dan menulis detail implementasinya di sini: https://www.sheshbabu.com/posts/react-like-composition-using...
    • Saya penasaran apa yang Anda pakai sebagai gantinya 3 minggu lalu.
  • Masalah besarnya adalah, kalau merilis untuk desktop, biasanya orang juga menginginkan versi web. Terutama jika itu bukan aplikasi yang sangat niche dan banyak berinteraksi dengan sistem operasi.
    Atau Anda membutuhkan sesuatu yang menargetkan banyak platform, termasuk mobile.
    Saya sudah cukup lama mencari, tetapi yang paling mendekati adalah Qt dan React Native, dan keduanya merupakan pilihan yang menyakitkan karena berbagai alasan.

  • FLTK mendukung Windows. Saya penasaran apakah mereka belum mendukung Windows karena berencana memakai solusi lain.

    • Jika lingkungan seperti compiler C yang sesuai sudah tersedia, Spot seharusnya berjalan tanpa perubahan di Windows dan memilih backend FLTK.
      Namun tujuan saya, meski prioritasnya rendah, adalah mengimplementasikan backend berbasis Win32, dan langkah pertamanya sudah selesai: https://github.com/roblillack/spot/pull/4