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) 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() _, model := m.MenuModel()
p, _ := gtk.PopoverNewFromModel(relative, model) p, _ := gtk.PopoverNewFromModel(relative, model)

View File

@ -30,6 +30,11 @@ func (s *Stateful) Reset() {
s.labels = nil 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()) { func (s *Stateful) AddAction(label string, call func()) {
sa := glib.SimpleActionNew(ActionName(label), nil) sa := glib.SimpleActionNew(ActionName(label), nil)
sa.Connect("activate", call) sa.Connect("activate", call)

View File

@ -4,7 +4,6 @@ import (
"github.com/diamondburned/cchat" "github.com/diamondburned/cchat"
"github.com/diamondburned/cchat-gtk/internal/gts" "github.com/diamondburned/cchat-gtk/internal/gts"
"github.com/diamondburned/cchat-gtk/internal/ui/primitives" "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-gtk/internal/ui/rich"
"github.com/diamondburned/cchat/text" "github.com/diamondburned/cchat/text"
) )
@ -16,9 +15,6 @@ const UnreadColorDefs = `
type ToggleButtonImage struct { type ToggleButtonImage struct {
*rich.ToggleButtonImage *rich.ToggleButtonImage
extraMenu []menu.Item
menu *menu.LazyMenu
clicked func(bool) clicked func(bool)
readcss primitives.ClassEnum readcss primitives.ClassEnum
@ -67,7 +63,6 @@ func WrapToggleButtonImage(b *rich.ToggleButtonImage) *ToggleButtonImage {
ToggleButtonImage: b, ToggleButtonImage: b,
clicked: func(bool) {}, clicked: func(bool) {},
menu: menu.NewLazyMenu(b.ToggleButton),
} }
tb.Connect("clicked", func() { tb.clicked(tb.GetActive()) }) tb.Connect("clicked", func() { tb.clicked(tb.GetActive()) })
serverButtonCSS(tb) 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() { func (b *ToggleButtonImage) SetNormal() {
b.SetLabelUnsafe(b.GetLabel()) b.SetLabelUnsafe(b.GetLabel())
b.menu.SetItems(b.extraMenu) // b.menu.SetItems(b.extraMenu)
if b.icon != "" { if b.icon != "" {
b.Image.SetPlaceholderIcon(b.icon, b.Image.Size()) b.Image.SetPlaceholderIcon(b.icon, b.Image.Size())
@ -121,9 +111,6 @@ func (b *ToggleButtonImage) SetNormal() {
func (b *ToggleButtonImage) SetLoading() { func (b *ToggleButtonImage) SetLoading() {
b.SetLabelUnsafe(b.GetLabel()) b.SetLabelUnsafe(b.GetLabel())
// Reset the menu.
b.menu.SetItems(b.extraMenu)
if b.icon != "" { if b.icon != "" {
b.Image.SetPlaceholderIcon("content-loading-symbolic", b.Image.Size()) 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()) { func (b *ToggleButtonImage) SetFailed(err error, retry func()) {
b.Label.SetMarkup(rich.MakeRed(b.GetLabel())) 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 we have an icon set, then we can use the failed icon.
if b.icon != "" { if b.icon != "" {
b.Image.SetPlaceholderIcon("computer-fail-symbolic", b.Image.Size()) 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/log"
"github.com/diamondburned/cchat-gtk/internal/ui/primitives" "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/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/primitives/roundimage"
"github.com/diamondburned/cchat-gtk/internal/ui/rich" "github.com/diamondburned/cchat-gtk/internal/ui/rich"
"github.com/diamondburned/cchat-gtk/internal/ui/service/savepath" "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) r.Box.PackStart(r.Button, false, false, 0)
serverCSS(r.Box) serverCSS(r.Box)
// Make the Actions menu.
r.ActionsMenu = actions.NewMenu("server")
r.ActionsMenu.InsertActionGroup(r)
// Ensure errors are displayed. // Ensure errors are displayed.
r.childrenSetErr(r.childrenErr) r.childrenSetErr(r.childrenErr)
@ -137,10 +140,6 @@ func (r *ServerRow) Init() {
// Restore the read state. // Restore the read state.
r.Button.SetUnreadUnsafe(r.unread, r.mentioned) // update with 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 { if cmder := r.Server.AsCommander(); cmder != nil {
r.cmder = commander.NewBuffer(r.Server.Name().String(), cmder) r.cmder = commander.NewBuffer(r.Server.Name().String(), cmder)
r.ActionsMenu.AddAction("Command Prompt", r.cmder.ShowDialog) 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. // Bind right clicks and show a popover menu on such event.
r.Button.Connect("button-press-event", func(_ gtk.IWidget, ev *gdk.Event) { r.Button.Connect("button-press-event", func(_ gtk.IWidget, ev *gdk.Event) {
if gts.EventIsRightClick(ev) { if gts.EventIsRightClick(ev) {
r.ActionsMenu.Popover(r).Popup() r.ActionsMenu.Popup(r)
} }
}) })
@ -223,12 +222,28 @@ func (r *ServerRow) IsHollow() bool {
// recursively create // recursively create
func (r *ServerRow) SetHollowServerList(list cchat.Lister, ctrl Controller) { func (r *ServerRow) SetHollowServerList(list cchat.Lister, ctrl Controller) {
r.serverList = list r.serverList = list
r.children = NewHollowChildren(r, ctrl) 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() { go func() {
var err = list.Servers(r.children) var err = list.Servers(children)
if err != nil { if err != nil {
log.Error(errors.Wrap(err, "Failed to get servers")) 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 // Use the childrenX method instead of SetX. We can wrap nil
// errors. // errors.
r.childrenSetErr(errors.Wrap(err, "Failed to get servers")) 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.SetTooltipText(err.Error())
r.Button.SetFailed(err, retry) r.Button.SetFailed(err, retry)
r.Button.Label.SetMarkup(rich.MakeRed(r.Button.GetLabel())) 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 // SetDone is shared between the parent struct and the children list. This is
@ -356,13 +375,13 @@ func (r *ServerRow) SetDone() {
r.SetTooltipText("") r.SetTooltipText("")
} }
func (r *ServerRow) SetNormalExtraMenu(items []menu.Item) { // func (r *ServerRow) SetNormalExtraMenu(items []menu.Item) {
AssertUnhollow(r) // AssertUnhollow(r)
r.Button.SetNormalExtraMenu(items) // r.Button.SetNormalExtraMenu(items)
r.SetSensitive(true) // r.SetSensitive(true)
r.SetTooltipText("") // r.SetTooltipText("")
} // }
// SetSelected is used for highlighting the current message server. // SetSelected is used for highlighting the current message server.
func (r *ServerRow) SetSelected(selected bool) { func (r *ServerRow) SetSelected(selected bool) {
@ -400,10 +419,15 @@ func (r *ServerRow) SetRevealChild(reveal bool) {
return return
} }
// Load the list of servers if we're still in loading mode. Before, we have // Ensure that we have successfully loaded the server.
// to call Servers on this. Now, we already know that there are hollow r.load(func(err error) {
// servers in the children container. if err == nil {
r.children.LoadAll() // 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 // 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) rowIconCSS(row.icon.Icon)
row.ListBoxRow, _ = gtk.ListBoxRowNew() row.ListBoxRow, _ = gtk.ListBoxRowNew()
row.ListBoxRow.Show()
rowCSS(row.ListBoxRow) rowCSS(row.ListBoxRow)
// TODO: commander button // 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. // Bind right clicks and show a popover menu on such event.
row.icon.Connect("button-press-event", func(_ gtk.IWidget, ev *gdk.Event) { row.icon.Connect("button-press-event", func(_ gtk.IWidget, ev *gdk.Event) {
if gts.EventIsRightClick(ev) { 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 // method will reconnect. If the row is already loaded, then SessionSelected
// will be called. // will be called.
func (r *Row) Activate() { 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 // If session is nil, then we've probably failed to load it. The row is
// deactivated while loading, so this wouldn't have happened. // deactivated while loading, so this wouldn't have happened.
if r.Session == nil { if r.Session == nil {
@ -248,6 +246,9 @@ func (r *Row) Activate() {
// method. // method.
r.Servers.Children.LoadAll() 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 // SetLoading sets the session button to have a spinner circle. DO NOT CONFUSE