Path: blob/main/internal/sidebar/guilds/folderbutton.go
366 views
package guilds12import (3"context"4"fmt"56"github.com/diamondburned/arikawa/v3/discord"7"github.com/diamondburned/gotk4/pkg/gtk/v4"8"github.com/diamondburned/gotkit/components/onlineimage"9"github.com/diamondburned/gotkit/gtkutil/cssutil"10"github.com/diamondburned/gotkit/gtkutil/imgutil"11"libdb.so/dissent/internal/gtkcord"12"libdb.so/dissent/internal/sidebar/sidebutton"13)1415// FolderButton is the folder icon containing the four guild icons.16type FolderButton struct {17*gtk.Button18// Main stack, switches between "guilds" and "folder"19MainStack *gtk.Stack20GuildGrid *gtk.Grid // contains 4 images always.21FolderIcon *gtk.Image22Images [4]*onlineimage.Avatar // first 4 of folder.Guilds23Mentions *sidebutton.MentionsIndicator2425prov *gtk.CSSProvider26ctx context.Context27}2829// [0] [1]30// [2] [3]31var folderIconMatrix = [4][2]int{32{0, 0},33{1, 0},34{0, 1},35{1, 1},36}3738var folderButtonCSS = cssutil.Applier("guild-folderbutton", `39.guild-folderbutton {40padding: 0 12px; /* reset styling */41padding-top: 8px;42border: none;43border-radius: 0;44min-width: 0;45min-height: 0;46background: none;47}48.guild-foldericons {49transition: 200ms ease;50padding: 4px 0;51/* Super quirky hack to give bottom margin control to the Stack52* instead of the button. We make up for the negative margin in53* the button.54*/55margin-top: -4px;56margin-bottom: 4px;57border-radius: calc({$guild_icon_size} / 4);58}59.guild-foldericons:not(.guild-foldericons-collapsed) {60background-color: @theme_bg_color;61padding-bottom: 8px;62margin-bottom: 0px;63border-radius:64calc({$guild_icon_size} / 4)65calc({$guild_icon_size} / 4)660 0;67}68.guild-foldericons > image {69color: rgb(88, 101, 242);70}71.guild-foldericons-collapsed {72background-color: rgba(88, 101, 242, 0.35);73}74.guild-foldericons image {75background: none;76}77.guild-folderbutton .guild-foldericons {78transition-property: all;79outline: 0px solid transparent;80}81.guild-folderbutton:hover .guild-foldericons.guild-foldericons-collapsed {82outline: 2px solid @theme_selected_bg_color;83}84`)8586// NewFolderButton creates a new FolderButton.87func NewFolderButton(ctx context.Context) *FolderButton {88b := FolderButton{ctx: ctx}89b.FolderIcon = gtk.NewImageFromIconName("folder-visiting-symbolic")90b.FolderIcon.SetPixelSize(FolderSize)9192b.GuildGrid = gtk.NewGrid()93b.GuildGrid.SetHAlign(gtk.AlignCenter)94b.GuildGrid.SetVAlign(gtk.AlignCenter)95b.GuildGrid.SetRowSpacing(4) // calculated from Discord96b.GuildGrid.SetRowHomogeneous(true)97b.GuildGrid.SetColumnSpacing(4)98b.GuildGrid.SetColumnHomogeneous(true)99100for ix := range b.Images {101b.Images[ix] = onlineimage.NewAvatar(ctx, imgutil.HTTPProvider, FolderMiniSize)102b.Images[ix].SetText("#")103104pos := folderIconMatrix[ix]105b.GuildGrid.Attach(b.Images[ix], pos[0], pos[1], 1, 1)106}107108b.MainStack = gtk.NewStack()109b.MainStack.SetTransitionType(gtk.StackTransitionTypeSlideUp) // unsure110b.MainStack.SetSizeRequest(gtkcord.GuildIconSize, gtkcord.GuildIconSize)111b.MainStack.SetHAlign(gtk.AlignCenter)112b.MainStack.AddCSSClass("guild-foldericons")113b.MainStack.AddCSSClass("guild-foldericons-collapsed")114b.MainStack.AddChild(b.GuildGrid)115b.MainStack.AddChild(b.FolderIcon)116117b.Mentions = sidebutton.NewMentionsIndicator()118b.Mentions.SetVAlign(gtk.AlignEnd)119b.Mentions.SetHAlign(gtk.AlignEnd)120121overlay := gtk.NewOverlay()122overlay.SetChild(b.MainStack)123overlay.AddOverlay(b.Mentions)124125b.Button = gtk.NewButton()126b.Button.SetHasFrame(false)127b.Button.SetChild(overlay)128129folderButtonCSS(b)130return &b131}132133// SetIcons sets the guild icons to be shown.134func (b *FolderButton) SetIcons(guildIDs []discord.GuildID) {135state := gtkcord.FromContext(b.ctx)136137for ix, image := range b.Images {138if ix >= len(guildIDs) {139image.Hide()140continue141}142143image.Show()144145g, err := state.Cabinet.Guild(guildIDs[ix])146if err != nil {147image.SetText("?")148continue149}150151image.SetText(g.Name)152image.SetFromURL(gtkcord.InjectSize(g.IconURL(), 64))153}154}155156// SetRevealed sets what the FolderButton should show depending on if the folder157// is revealed/opened or not.158func (b *FolderButton) SetRevealed(revealed bool) {159if revealed {160b.MainStack.SetTransitionType(gtk.StackTransitionTypeSlideDown)161b.MainStack.SetVisibleChild(b.FolderIcon)162b.MainStack.RemoveCSSClass("guild-foldericons-collapsed")163} else {164b.MainStack.SetTransitionType(gtk.StackTransitionTypeSlideUp)165b.MainStack.SetVisibleChild(b.GuildGrid)166b.MainStack.AddCSSClass("guild-foldericons-collapsed")167}168}169170const colorCSSf = `171image {172color: rgb(%[1]d, %[2]d, %[3]d);173}174stack.guild-foldericons-collapsed {175background-color: rgba(%[1]d, %[2]d, %[3]d, 0.4);176}177`178179func (b *FolderButton) colorWidgets() []gtk.Widgetter {180return []gtk.Widgetter{181b.Button,182b.FolderIcon,183b.MainStack,184}185}186187// SetColor sets the color of the folder.188func (b *FolderButton) SetColor(color discord.Color) {189rr, gg, bb := color.RGB()190191p := gtk.NewCSSProvider()192p.LoadFromData(fmt.Sprintf(colorCSSf, rr, gg, bb))193194for _, w := range b.colorWidgets() {195s := gtk.BaseWidget(w).StyleContext()196if b.prov != nil {197s.RemoveProvider(b.prov)198}199s.AddProvider(p, gtk.STYLE_PROVIDER_PRIORITY_APPLICATION+10)200}201202b.prov = p203}204205206