1
0
Fork 0
mirror of https://github.com/diamondburned/cchat-gtk.git synced 2024-10-31 19:44:23 +00:00
cchat-gtk/internal/ui/ui.go

150 lines
3.9 KiB
Go
Raw Normal View History

2020-05-26 06:51:06 +00:00
package ui
import (
"github.com/diamondburned/cchat"
"github.com/diamondburned/cchat-gtk/internal/gts"
2020-06-20 07:28:47 +00:00
"github.com/diamondburned/cchat-gtk/internal/log"
2020-06-20 04:40:34 +00:00
"github.com/diamondburned/cchat-gtk/internal/ui/config/preferences"
"github.com/diamondburned/cchat-gtk/internal/ui/messages"
2020-06-04 23:00:41 +00:00
"github.com/diamondburned/cchat-gtk/internal/ui/service"
"github.com/diamondburned/cchat-gtk/internal/ui/service/auth"
"github.com/diamondburned/cchat-gtk/internal/ui/service/session"
2020-05-28 19:26:55 +00:00
"github.com/diamondburned/cchat-gtk/internal/ui/service/session/server"
2020-05-26 06:51:06 +00:00
"github.com/gotk3/gotk3/gtk"
2020-06-06 00:47:28 +00:00
"github.com/markbates/pkger"
2020-06-20 07:28:47 +00:00
"github.com/pkg/errors"
2020-05-26 06:51:06 +00:00
)
2020-06-06 00:47:28 +00:00
func init() {
// Load the local CSS.
gts.LoadCSS(pkger.Include("/internal/ui/style.css"))
}
// constraints for the left panel
const (
leftMinWidth = 200
leftCurrentWidth = 250
leftMaxWidth = 400
)
func clamp(n, min, max int) int {
switch {
case n > max:
return max
case n < min:
return min
default:
return n
}
}
2020-05-26 06:51:06 +00:00
2020-06-04 23:00:41 +00:00
type App struct {
2020-05-26 06:51:06 +00:00
window *window
header *header
2020-06-04 23:00:41 +00:00
// used to keep track of what row to disconnect before switching
lastSelector func(bool)
2020-05-26 06:51:06 +00:00
}
var (
2020-06-20 04:40:34 +00:00
_ gts.WindowHeaderer = (*App)(nil)
2020-06-04 23:00:41 +00:00
_ service.Controller = (*App)(nil)
2020-05-26 06:51:06 +00:00
)
2020-06-04 23:00:41 +00:00
func NewApplication() *App {
app := &App{
2020-05-26 06:51:06 +00:00
window: newWindow(),
header: newHeader(),
}
// Resize the left-side header w/ the left-side pane.
app.window.Services.Connect("size-allocate", func(wv gtk.IWidget) {
// Get the current width of the left sidebar.
var width = app.window.GetPosition()
// Set the left-side header's size.
app.header.left.SetSizeRequest(width, -1)
})
2020-06-20 04:40:34 +00:00
// Bind the preferences action for our GAction button in the header popover.
// The action name for this is "app.preferences".
gts.AddAppAction("preferences", preferences.SpawnPreferenceDialog)
2020-05-26 06:51:06 +00:00
return app
}
2020-06-04 23:00:41 +00:00
func (app *App) AddService(svc cchat.Service) {
2020-06-07 07:06:13 +00:00
app.window.Services.AddService(svc, app)
2020-06-07 04:27:28 +00:00
}
// OnSessionRemove resets things before the session is removed.
func (app *App) OnSessionRemove(id string) {
// Reset the message view if it's what we're showing.
if app.window.MessageView.SessionID() == id {
app.window.MessageView.Reset()
app.header.SetBreadcrumb(nil)
}
2020-05-28 19:26:55 +00:00
}
func (app *App) OnSessionDisconnect(id string) {
// We're basically doing the same thing as removing a session. Check
// OnSessionRemove above.
app.OnSessionRemove(id)
}
func (app *App) RowSelected(ses *session.Row, srv *server.ServerRow, smsg cchat.ServerMessage) {
// Is there an old row that we should deactivate?
if app.lastSelector != nil {
app.lastSelector(false)
2020-06-04 23:00:41 +00:00
}
// Set the new row.
app.lastSelector = srv.SetSelected
app.lastSelector(true)
2020-06-04 23:00:41 +00:00
2020-06-06 00:47:28 +00:00
app.header.SetBreadcrumb(srv.Breadcrumb())
2020-06-04 23:00:41 +00:00
// Disable the server list because we don't want the user to switch around
// while we're loading.
app.window.Services.SetSensitive(false)
// Assert that server is also a list, then join the server.
app.window.MessageView.JoinServer(ses.Session, smsg.(messages.ServerMessage), func() {
// Re-enable the server list.
app.window.Services.SetSensitive(true)
})
2020-06-04 23:00:41 +00:00
}
func (app *App) AuthenticateSession(container *service.Container, svc cchat.Service) {
auth.NewDialog(svc.Name(), svc.Authenticate(), func(ses cchat.Session) {
container.AddSession(ses)
})
2020-05-26 06:51:06 +00:00
}
2020-06-20 07:28:47 +00:00
// Close is called when the application finishes gracefully.
func (app *App) Close() {
// Disconnect everything. This blocks the main thread, so by the time we're
// done, the application would exit immediately. There's no need to update
// the GUI.
for _, s := range app.window.Services.Services {
for _, session := range s.Sessions() {
if session.Session == nil {
continue
}
log.Printlnf("Disconnecting %s session %s", s.Service.Name(), session.ID())
if err := session.Session.Disconnect(); err != nil {
log.Error(errors.Wrap(err, "Failed to disconnect "+session.ID()))
}
2020-06-20 04:40:34 +00:00
}
}
}
2020-06-04 23:00:41 +00:00
func (app *App) Header() gtk.IWidget {
2020-05-26 06:51:06 +00:00
return app.header
}
2020-06-04 23:00:41 +00:00
func (app *App) Window() gtk.IWidget {
2020-05-26 06:51:06 +00:00
return app.window
}