Spot - Go dili için, React’e benzer masaüstü GUI araç takımı
(github.com/roblillack)- Spot, Go’da çapraz platform masaüstü GUI oluşturmak için basit, reaktif bir araç takımıdır; mümkün olduğunda yerel widget’ları kullanır ve platforma özgü API’leri tutarlı biçimde sunar
- Uygulama durumu değiştiğinde değişmez bir bileşen ağacını yeniden oluşturup önceki durumla karşılaştırarak hangi UI kontrollerinin güncelleneceğini belirleyen bir yaklaşımla çalışır
- Mevcut backend’ler macOS’te Cocoa ve diğer platformlarda FLTK tabanlı uygulamadır; macOS’te isteğe bağlı olarak FLTK de kullanılabilir
spot, reaktif modeli ve render etmeyi sağlayan backend’den bağımsız çekirdek pakettir;spot/uiise hazır çapraz platform GUI kontrolleri koleksiyonudur- Otomatik layout, birden çok pencere, modal iletişim kutuları, yeniden boyutlandırılabilir pencereler, menü çubuğu, özel widget’lar, yerel widget erişimi, sürükle-bırak ve uluslararasılaştırma henüz sunulmamaktadır
Spot’un amacı ve temel modeli
- Spot, Go için reaktif bir GUI araç takımıdır; mümkün olan yerlerde yerel widget’ları kullanırken birden fazla platformda tutarlı bir API sunmak üzere tasarlanmıştır
- Projeye basit bir bağımlılık olarak ekleyip yalnızca Go kodu yazarak, ek araçlar veya kod üretimi olmadan kendi kendine yeten yerel GUI ikilileri oluşturabilirsiniz
- Örnekte
ui.Init(),spot.MountFn(...),ui.Run()akışıyla pencere ve düğme oluşturulur;spot.UseState[int](<https://github.com/roblillack/ctx, 0>)ile tıklama sayısı durumu yönetilir - Düğme tıklama handler’ı
setCounter(counter + 1)çağırır; durum değiştiğinde düğme başlığı"Clicked %d times!"biçiminde değişir
Reaktif güncelleme yöntemi
- Spot’ta reactive, uygulama durumu değiştiğinde UI’ın otomatik olarak yenilenmesi anlamına gelir
- Durum değiştiğinde değişmez bileşen ağacı yeniden oluşturulur ve önceki durumla hızlıca karşılaştırılarak hangi UI kontrollerinin güncelleneceği belirlenir
- Web’de bu fikir genellikle virtual DOM olarak adlandırılır; Spot, bu kavramı Go masaüstü ortamına taşıyıp React’e benzer bir GUI kütüphanesi uygulamayı amaçlayan bir deney olarak başlamıştır
- Geliştirici, UI’ı elle güncellemek yerine yan etkisiz render fonksiyonları ve
UseStategibi hook’larla uygulama mantığını ve durumu yönetir
Backend ve paket yapısı
- Spot, derleme sırasında çalışacağı platforma uygun backend’i otomatik seçer
- Şu anda sunulan iki backend vardır
- FLTK tabanlı uygulama: go-fltk kullanır
- Cocoa tabanlı uygulama: gocoa’nın değiştirilmiş bir sürümünü kullanır
- macOS’te Cocoa backend’i, diğer platformlarda ise FLTK tabanlı backend kullanılır
- macOS’te isteğe bağlı olarak FLTK de kullanılabilir; Windows desteğinin iyileştirilmesi geleceğe dönük planlar arasında kalmaktadır
spot, reaktif model ve render işlevlerini sağlayan çekirdek pakettir;spot.Controlarayüzünü uygulayan herhangi bir kontrol kümesiyle kullanılabilirspot/ui, Spot ile birlikte kullanılabilen hazır çapraz platform GUI kontrolleri paketidir
Bileşenler, kontroller ve hook’lar
- React’te olduğu gibi özel hook’lar oluşturulabilir
- İlk argüman olarak
*spot.RenderContextalan bir fonksiyon oluşturupspot.UseState,spot.UseEffectvb. çağırarak Spot yaşam döngüsüne bağlanılır - Geleneksel olarak fonksiyon adları
Use…önekiyle başlar
- İlk argüman olarak
- Özel bileşenler,
spot.Componentarayüzünü uygulayan struct’lar olarak oluşturulabilir- Bu arayüz,
Render(ctx *spot.RenderContext) spot.Componentadlı tek bir metoda sahiptir - Bu şekilde oluşturulan bileşenler yerleşik bileşenlerle aynı biçimde kullanılabilir
- Bu arayüz,
- Spot’ta component, iş mantığını ve durumu taşıyan mantıksal bir birimdir
- Bileşenler başka bileşenlerden oluşur ve en sonunda bir veya daha fazla kontrole render edilir
- control, UI ağacına mount edilen özel bir bileşendir ve ekrandaki görsel öğeyi temsil eder
- Genellikle düğme, etiket, metin girişi gibi GUI backend’inin yerel uygulamasına dayanır
- Sağlanan widget kütüphanesinden tamamen farklı bir widget kütüphanesi de kullanılabilir
spot.Componentarayüzünü uygulayan ve yerel widget’ları yöneten struct’lar oluşturmak yeterlidir
spot/ui’ın Cocoa veya FLTK dışındaki backend’lerle birlikte kullanımı şu anda desteklenmemektedir
Render yaşam döngüsü terimleri
- Make:
spot.Componentarayüzünü uygulayan bir struct örneği oluşturma veya bir render fonksiyonuyla birliktespot.Makeçağırarak yeni bir bileşen örneği oluşturma süreci - Render: Bileşen durumunu alt öğelere uygulayıp başka bileşen örnekleri döndürme süreci
- Build: Bileşenleri özyinelemeli olarak render edip kontrol ağacını oluşturma süreci
spot.Build’e bir bileşen örneği verilerek veyaspot.BuildFn’e bir render fonksiyonu verilerek çalıştırılır
- Mount: Sanal kontrol ağacından gerçek UI kontrolleri oluşturma süreci
- Ağaç düğümünün
Mountmetodu çağrılarak veyaspot.Mount,spot.MountFnkullanılarak yapılabilir
- Ağaç düğümünün
- Update: Mount edilmiş kontrol ağacını güncelleme süreci
- Ağaç düğümünün
Updatemetodu çağrılarak gerçekleştirilir
- Ağaç düğümünün
Şu anda sunulmayan özellikler
- Spot şu anda aşağıdaki özellikleri sunmamaktadır
-
Otomatik layout
- Birden çok pencere
- Modal iletişim kutuları
- Yeniden boyutlandırılabilir pencereler
- Menü çubuğu
- Özel widget’lar
- Yerel widget erişimi
- Sürükle-bırak
- Uluslararasılaştırma
-
Desteklenen UI kontrolleri
- Spot, düğme, etiket, metin girişi, slider, dropdown gibi çeşitli UI kontrollerini yerleşik olarak sunar
- Destek durumu işaretleri ❓ uygulanmadı, 🚧 üzerinde çalışılıyor, ⚠️ kısmen uygulandı, ✅ tamamlandı olarak ayrılır
- Tamamlanmış başlıca kontroller şunlardır
- Button: Basit eylem çalıştırma düğmesi;
Fl_ButtonveNSButtonkullanır - Checkbox: İki seçenekten birini seçmeye yarayan kontrol;
Fl_Check_ButtonveNSButtonkullanır - Dropdown: Birden çok öğeden birini seçmeye yarayan dropdown;
Fl_ChoiceveNSComboBoxkullanır - Image: Bitmap görüntü gösterme kontrolü;
Fl_Boxve özelNSButtonkullanır - Label: Düzenlenemeyen metin etiketi;
Fl_BoxveNSTextFieldkullanır - ListBox: Tekli veya çoklu seçim liste kontrolü;
Fl_Select_Browser/Fl_Multi_BrowserveNSTableViewkullanır - ProgressBar: Uzun süren işlerin ilerlemesini gösterir;
Fl_ProgressveNSProgressIndicatorkullanır - Slider: Yatay slider girişi;
Fl_SliderveNSSliderkullanır - Spinner: Yukarı/aşağı düğmeleri olan sayısal giriş;
Fl_SpinnerveNSTextField+NSStepperkullanır - TextField: Tek satırlık metin girişi;
Fl_InputveNSTextFieldkullanır - TextEditor: Çok satırlı metin düzenleme;
Fl_Text_EditorveNSTextViewkullanır - Window: Üst düzey pencere kontrolü;
Fl_WindowveNSWindowkullanır
- Button: Basit eylem çalıştırma düğmesi;
- Kısmen uygulanmış veya uygulanmamış kontroller de vardır
- Dial: Dairesel durum kontrolüdür ve ⚠️ kısmen uygulanmış durumdadır
- ComboBox: Metin girişiyle birleştirilmiş dropdown menüdür ve henüz başlanmamıştır
- Gelecekteki olası backend adaylarından biri olarak yerel Windows kontrol kütüphanesi
https://github.com/rodrigocfd/windigogösterilmektedir
1 yorum
Hacker News yorumları
Buna mutlaka bakmam lazım. Go ile dahili geliştirme araçları yapmanın basit bir yolunu arıyordum; aslında düğmeler ve metin alanları olan bir form düzeyinde bir şey
Gio'yu da denedim ama anlaması zordu; şu anda wails kullanıyorum ve çok daha hoşuma gidiyor. Bu proje de ilginç ve incelemeye değer görünüyor
“Çapraz platform: FLTK[1] ve Cocoa[2] kullanarak Spot, Mac, Linux ve BSD'de çalışır; gelecekte yerel Windows desteği planlanıyor” yönünü ciddi biçimde daraltmanızı öneririm
Öğrendiklerinizi saklayıp ileride esneklik sağlayın ama önce tek bir toolkit üzerinde iyi olmak daha iyi. GUI toolkit'leri, GUI binding'leri ve GUI'nin kendisi zaten ayrıntılarda boğulmaya çok yatkın; bir de birden fazla temel toolkit'in ayrıntılarını gönüllü olarak üstlenirseniz, sonunda hiçbir toolkit'i düzgün yapamama ihtimaliniz yüksek
“İlk %90 işin %90'ıdır, kalan %10 da bir başka %90'dır” diye bir söz var; ama GUI'de bu bile iyimser kalıyor. İlk %10 işin %90'ı, sonraki %10 bunun 10 katı, ondan sonraki %10 da yine 10 katı oluyor. Çapraz platform denemek boğazınızı sıkabilir
Şu anda bu görüşe katılmanızı beklemiyorum; ama ileride üç toolkit'in zengin metin işleme gibi şeyleri birbiriyle çelişen üç farklı yolla dayattığı bir durumla karşılaşırsanız, en iyi desteklenen ya da en popüler temel toolkit dışındakileri bırakmaya kendinize izin vermenizi umarım
Go'da bir süredir böyle bir şey arıyordum. Go'nun derleme süreci basit olduğu için çapraz platform UI'da harika bir geliştirici deneyimi sunma fırsatı büyük bence
Deneyimlerime göre çapraz platform geliştirmenin acısının yarısı derleme karmaşıklığını yönetmek; Go bunu neredeyse ortadan kaldırıyor
Yine de yerel kontrollerin varsayılan boyutları platformdan platforma değişiyor; çapraz platform layout işini nasıl çözeceklerini merak ediyorum. Bu kısmın başka çapraz platform toolkit'lerde de çok iyi çözüldüğünü görmedim. Yine de bol şans
Birkaç yıl önce böyle bir şey arıyordum. Ancak Windows desteğine de ihtiyacım vardı. Sonunda wxWidgets kullanmak için C++'a geçtim ve küçük, kendi kendine yeten bir ikili dosya elde edebildim
Yerel bir toolkit olmasına rağmen FLTK'nin, tarayıcılar gibi Ctrl-+ ve Ctrl+- ile tüm uygulamada yakınlaştırma/uzaklaştırma desteklemesini görünce etkilendim. Ayrıca https://github.com/fltk-rs/fltk-theme?tab=readme-ov-file#wid... sayesinde FLTK'yi ne kadar “yerel” görünümlü yapabileceğime dair izlenimim iyileşti
Bununla bağlantılı olarak yakın zamanda GoVCL'yi https://z-kit.cc/en/ de keşfettim ve bir denemek istiyorum
Kendi kendine yeten Spot “Hello World” benim Mac'imde 2.3MiB. Güzel değil ama benim için yeterince çalışıyor
Kullanıcıya gösterilen kontrolleri doğrudan güncelleme yöntemiyle karşılaştırıldığında sanal kontrol ağacı yaklaşımının avantajının ne olduğunu merak ediyorum
Her yere callback kodu yazmak gerekiyor ve her callback, diğer tüm etkinliklerin mevcut durumunu dikkatle kontrol ettikten sonra onlarca widget'ı güncellemek zorunda kalabiliyor
Reaktif yaklaşımda, verilen bir durum için arayüzü tanımlayan tek bir render fonksiyonu yazıyorsunuz; framework bunun ne zaman çağrılacağını ve hangi girdilerin verileceğini hallediyor. Bunu anlamak çok daha kolay ve React'i kullandıktan sonra geri dönmek zor olduğu için Go'da da benzer bir şeyin mümkün olup olmadığını denemeye başladım
Güzel görünüyor. README'ye desteklenen platformları yazabilir misiniz diye merak ediyorum
Windows, Linux, macOS, *BSD, Android, iOS, Web, Tizen gibi bilgiler oldukça ilginç olurdu
Flutter belgelerindeki gibi yazılsa da iyi olabilir: https://docs.flutter.dev/reference/supported-platforms
Çaba takdire değer ama Windows desteği olmayan çapraz platform mu?
Keşke bunu 3 hafta önce bilseydim; ya da commit geçmişine bakılırsa o zaman zaten var idiyse keşke fark etseydim. Uzun zamandır Go'ya port edilmiş React ya da Go için React benzeri bir framework olursa geliştirme deneyiminin muazzam olacağını söylüyordum ve bu tam isabet görünüyor
React.lua ile fark edene kadar React.js'den epey nefret ediyordum
Sonunda yalnızca Go standart
html/templateile benzer bir şey yapmanın yolunu buldum ve uygulama ayrıntılarını burada yazdım: https://www.sheshbabu.com/posts/react-like-composition-using...Masaüstü olarak yayımladığınızda genellikle web sürümünü de istemeniz büyük sorun. İşletim sistemiyle çok etkileşen çok niş bir uygulama değilse özellikle böyle
Ya da mobil dahil birden fazla platformu hedefleyen bir şeye ihtiyaç oluyor
Epey uzun süre aradım ama en yakın seçenekler Qt ve React Native idi; ikisi de çeşitli nedenlerle acı veren seçeneklerdi
FLTK Windows'u destekliyor. Başka bir çözüm kullanma planı olduğu için mi Windows'u henüz desteklemiyor merak ediyorum
Ancak benim hedefim, önceliği düşük olsa da Win32 tabanlı bir backend uygulamak; ilk aşama tamamlandı: https://github.com/roblillack/spot/pull/4