action menu fix; server list retry fix

This commit is contained in:
diamondburned 2020-10-25 19:28:29 -07:00
parent 46ec8c66ac
commit 8a8423d33f
5 changed files with 66 additions and 43 deletions

View File

@ -39,7 +39,18 @@ func (m *Menu) InsertActionGroup(w ActionGroupInserter) {
w.InsertActionGroup(m.prefix, m)
}
func (m *Menu) Popover(relative gtk.IWidget) *gtk.Popover {
// Popup pops up the menu popover. It does not pop up anything if there are no
// menu items.
func (m *Menu) Popup(relative gtk.IWidget) {
p := m.popover(relative)
if p == nil || m.Len() == 0 {
return
}
p.Popup()
}
func (m *Menu) popover(relative gtk.IWidget) *gtk.Popover {
_, model := m.MenuModel()
p, _ := gtk.PopoverNewFromModel(relative, model)

View File

@ -30,6 +30,11 @@ func (s *Stateful) Reset() {
s.labels = nil
}
// Len returns the number of menu entries.
func (s *Stateful) Len() int {
return len(s.labels)
}
func (s *Stateful) AddAction(label string, call func()) {
sa := glib.SimpleActionNew(ActionName(label), nil)
sa.Connect("activate", call)

View File

@ -4,7 +4,6 @@ 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/primitives/menu"
"github.com/diamondburned/cchat-gtk/internal/ui/rich"
"github.com/diamondburned/cchat/text"
)
@ -16,9 +15,6 @@ const UnreadColorDefs = `
type ToggleButtonImage struct {
*rich.ToggleButtonImage
extraMenu []menu.Item
menu *menu.LazyMenu
clicked func(bool)
readcss primitives.ClassEnum
@ -67,7 +63,6 @@ func WrapToggleButtonImage(b *rich.ToggleButtonImage) *ToggleButtonImage {
ToggleButtonImage: b,
clicked: func(bool) {},
menu: menu.NewLazyMenu(b.ToggleButton),
}
tb.Connect("clicked", func() { tb.clicked(tb.GetActive()) })
serverButtonCSS(tb)
@ -104,14 +99,9 @@ func (b *ToggleButtonImage) SetClickedIfTrue(clickedIfTrue func()) {
}
}
func (b *ToggleButtonImage) SetNormalExtraMenu(items []menu.Item) {
b.extraMenu = items
b.SetNormal()
}
func (b *ToggleButtonImage) SetNormal() {
b.SetLabelUnsafe(b.GetLabel())
b.menu.SetItems(b.extraMenu)
// b.menu.SetItems(b.extraMenu)
if b.icon != "" {
b.Image.SetPlaceholderIcon(b.icon, b.Image.Size())
@ -121,9 +111,6 @@ func (b *ToggleButtonImage) SetNormal() {
func (b *ToggleButtonImage) SetLoading() {
b.SetLabelUnsafe(b.GetLabel())
// Reset the menu.
b.menu.SetItems(b.extraMenu)
if b.icon != "" {
b.Image.SetPlaceholderIcon("content-loading-symbolic", b.Image.Size())
}
@ -132,11 +119,6 @@ func (b *ToggleButtonImage) SetLoading() {
func (b *ToggleButtonImage) SetFailed(err error, retry func()) {
b.Label.SetMarkup(rich.MakeRed(b.GetLabel()))
// Add a retry button, if any.
b.menu.Reset()
b.menu.AddItems(menu.SimpleItem("Retry", retry))
b.menu.AddItems(b.extraMenu...)
// If we have an icon set, then we can use the failed icon.
if b.icon != "" {
b.Image.SetPlaceholderIcon("computer-fail-symbolic", b.Image.Size())

View File

@ -6,7 +6,6 @@ import (
"github.com/diamondburned/cchat-gtk/internal/log"
"github.com/diamondburned/cchat-gtk/internal/ui/primitives"
"github.com/diamondburned/cchat-gtk/internal/ui/primitives/actions"
"github.com/diamondburned/cchat-gtk/internal/ui/primitives/menu"
"github.com/diamondburned/cchat-gtk/internal/ui/primitives/roundimage"
"github.com/diamondburned/cchat-gtk/internal/ui/rich"
"github.com/diamondburned/cchat-gtk/internal/ui/service/savepath"
@ -125,6 +124,10 @@ func (r *ServerRow) Init() {
r.Box.PackStart(r.Button, false, false, 0)
serverCSS(r.Box)
// Make the Actions menu.
r.ActionsMenu = actions.NewMenu("server")
r.ActionsMenu.InsertActionGroup(r)
// Ensure errors are displayed.
r.childrenSetErr(r.childrenErr)
@ -137,10 +140,6 @@ func (r *ServerRow) Init() {
// Restore the read state.
r.Button.SetUnreadUnsafe(r.unread, r.mentioned) // update with state
// Make the Actions menu.
r.ActionsMenu = actions.NewMenu("server")
r.ActionsMenu.InsertActionGroup(r)
if cmder := r.Server.AsCommander(); cmder != nil {
r.cmder = commander.NewBuffer(r.Server.Name().String(), cmder)
r.ActionsMenu.AddAction("Command Prompt", r.cmder.ShowDialog)
@ -149,7 +148,7 @@ func (r *ServerRow) Init() {
// Bind right clicks and show a popover menu on such event.
r.Button.Connect("button-press-event", func(_ gtk.IWidget, ev *gdk.Event) {
if gts.EventIsRightClick(ev) {
r.ActionsMenu.Popover(r).Popup()
r.ActionsMenu.Popup(r)
}
})
@ -223,12 +222,28 @@ func (r *ServerRow) IsHollow() bool {
// recursively create
func (r *ServerRow) SetHollowServerList(list cchat.Lister, ctrl Controller) {
r.serverList = list
r.children = NewHollowChildren(r, ctrl)
r.children.setLoading()
r.load(func(error) {})
}
// load calls finish if the server list is not loaded. If it is, finish is
// called with a nil immediately.
func (r *ServerRow) load(finish func(error)) {
if r.children.Rows != nil {
finish(nil)
return
}
list := r.serverList
children := r.children
children.setLoading()
if !r.IsHollow() {
r.SetSensitive(false)
}
go func() {
var err = list.Servers(r.children)
var err = list.Servers(children)
if err != nil {
log.Error(errors.Wrap(err, "Failed to get servers"))
}
@ -245,6 +260,8 @@ func (r *ServerRow) SetHollowServerList(list cchat.Lister, ctrl Controller) {
// Use the childrenX method instead of SetX. We can wrap nil
// errors.
r.childrenSetErr(errors.Wrap(err, "Failed to get servers"))
finish(err)
})
}()
}
@ -344,6 +361,8 @@ func (r *ServerRow) SetFailed(err error, retry func()) {
r.SetTooltipText(err.Error())
r.Button.SetFailed(err, retry)
r.Button.Label.SetMarkup(rich.MakeRed(r.Button.GetLabel()))
r.ActionsMenu.Reset()
r.ActionsMenu.AddAction("Retry", retry)
}
// SetDone is shared between the parent struct and the children list. This is
@ -356,13 +375,13 @@ func (r *ServerRow) SetDone() {
r.SetTooltipText("")
}
func (r *ServerRow) SetNormalExtraMenu(items []menu.Item) {
AssertUnhollow(r)
// func (r *ServerRow) SetNormalExtraMenu(items []menu.Item) {
// AssertUnhollow(r)
r.Button.SetNormalExtraMenu(items)
r.SetSensitive(true)
r.SetTooltipText("")
}
// r.Button.SetNormalExtraMenu(items)
// r.SetSensitive(true)
// r.SetTooltipText("")
// }
// SetSelected is used for highlighting the current message server.
func (r *ServerRow) SetSelected(selected bool) {
@ -400,10 +419,15 @@ func (r *ServerRow) SetRevealChild(reveal bool) {
return
}
// Load the list of servers if we're still in loading mode. Before, we have
// to call Servers on this. Now, we already know that there are hollow
// servers in the children container.
r.children.LoadAll()
// Ensure that we have successfully loaded the server.
r.load(func(err error) {
if err == nil {
// Load the list of servers if we're still in loading mode. Before,
// we have to call Servers on this. Now, we already know that there
// are hollow servers in the children container.
r.children.LoadAll()
}
})
}
// GetRevealChild returns whether or not the server list is expanded, or always

View File

@ -152,6 +152,7 @@ func newRow(parent traverse.Breadcrumber, name text.Rich, ctrl Servicer) *Row {
rowIconCSS(row.icon.Icon)
row.ListBoxRow, _ = gtk.ListBoxRowNew()
row.ListBoxRow.Show()
rowCSS(row.ListBoxRow)
// TODO: commander button
@ -166,7 +167,7 @@ func newRow(parent traverse.Breadcrumber, name text.Rich, ctrl Servicer) *Row {
// Bind right clicks and show a popover menu on such event.
row.icon.Connect("button-press-event", func(_ gtk.IWidget, ev *gdk.Event) {
if gts.EventIsRightClick(ev) {
row.ActionsMenu.Popover(row).Popup()
row.ActionsMenu.Popup(row)
}
})
@ -236,9 +237,6 @@ func (r *Row) Breadcrumb() string {
// method will reconnect. If the row is already loaded, then SessionSelected
// will be called.
func (r *Row) Activate() {
// Display the empty server list first, then try and reconnect.
r.svcctrl.SessionSelected(r)
// If session is nil, then we've probably failed to load it. The row is
// deactivated while loading, so this wouldn't have happened.
if r.Session == nil {
@ -248,6 +246,9 @@ func (r *Row) Activate() {
// method.
r.Servers.Children.LoadAll()
}
// Display the empty server list first, then try and reconnect.
r.svcctrl.SessionSelected(r)
}
// SetLoading sets the session button to have a spinner circle. DO NOT CONFUSE