package server import ( "github.com/diamondburned/cchat" "github.com/diamondburned/cchat-gtk/internal/gts" "github.com/diamondburned/cchat-gtk/internal/ui/primitives" "github.com/diamondburned/cchat-gtk/internal/ui/service/breadcrumb" "github.com/diamondburned/cchat-gtk/internal/ui/service/loading" "github.com/gotk3/gotk3/gtk" ) type Controller interface { RowSelected(*ServerRow, cchat.ServerMessage) } // Children is a children server with a reference to the parent. type Children struct { *gtk.Box load *loading.Button // only not nil while loading Rows []*ServerRow Parent breadcrumb.Breadcrumber rowctrl Controller } // reserved var childrenCSS = primitives.PrepareClassCSS("server-children", ` .server-children { margin: 0; margin-top: 3px; border-radius: 0; } `) func NewChildren(p breadcrumb.Breadcrumber, ctrl Controller) *Children { main, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0) main.SetMarginStart(ChildrenMargin) childrenCSS(main) return &Children{ Box: main, Parent: p, rowctrl: ctrl, } } // setLoading shows the loading circle as a list child. func (c *Children) setLoading() { // Exit if we're already loading. if c.load != nil { return } // Clear everything. c.Reset() // Set the loading circle and stuff. c.load = loading.NewButton() c.load.Show() c.Box.Add(c.load) } func (c *Children) Reset() { // Remove old servers from the list. for _, row := range c.Rows { c.Box.Remove(row) } // Wipe the list empty. c.Rows = nil } // setNotLoading removes the loading circle, if any. This is not in Reset() // anymore, since the backend may not necessarily call SetServers. func (c *Children) setNotLoading() { // Do we have the spinning circle button? If yes, remove it. if c.load != nil { // Stop the loading mode. The reset function should do everything for us. c.Box.Remove(c.load) c.load = nil } } // SetServers is reserved for cchat.ServersContainer. func (c *Children) SetServers(servers []cchat.Server) { gts.ExecAsync(func() { // Save the current state. var oldID string for _, row := range c.Rows { if row.GetActive() { oldID = row.Server.ID() break } } // Reset before inserting new servers. c.Reset() c.Rows = make([]*ServerRow, len(servers)) for i, server := range servers { row := NewServerRow(c, server, c.rowctrl) row.Show() // row.SetFocusHAdjustment(c.GetFocusHAdjustment()) // inherit // row.SetFocusVAdjustment(c.GetFocusVAdjustment()) c.Rows[i] = row c.Box.Add(row) } // Update parent reference? Only if it's activated. if oldID != "" { for _, row := range c.Rows { if row.Server.ID() == oldID { row.Button.SetActive(true) } } } }) } func (c *Children) Breadcrumb() breadcrumb.Breadcrumb { return breadcrumb.Try(c.Parent) }