mirror of
https://github.com/diamondburned/cchat-gtk.git
synced 2025-03-21 01:19:19 +00:00
Minor appearance tweaks
This commit is contained in:
parent
e35837ee2b
commit
f5093a690b
|
@ -26,34 +26,21 @@ type ImageContainerSizer interface {
|
|||
|
||||
// AsyncImage loads an image. This method uses the cache.
|
||||
func AsyncImage(img ImageContainer, url string, procs ...imgutil.Processor) {
|
||||
if url == "" {
|
||||
return
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
connectDestroyer(img, cancel)
|
||||
|
||||
gif := strings.Contains(url, ".gif")
|
||||
|
||||
l, err := gdk.PixbufLoaderNew()
|
||||
if err != nil {
|
||||
log.Error(errors.Wrap(err, "Failed to make pixbuf loader"))
|
||||
return
|
||||
}
|
||||
|
||||
l.Connect("area-prepared", areaPreparedFn(ctx, img, gif))
|
||||
|
||||
go syncImage(ctx, l, url, procs, gif)
|
||||
asyncImage(img, url, 0, 0, procs)
|
||||
}
|
||||
|
||||
// AsyncImageSized resizes using GdkPixbuf. This method uses the cache.
|
||||
func AsyncImageSized(img ImageContainerSizer, url string, w, h int, procs ...imgutil.Processor) {
|
||||
asyncImage(img, url, w, h, procs)
|
||||
}
|
||||
|
||||
func asyncImage(img ImageContainer, url string, w, h int, procs []imgutil.Processor) {
|
||||
if url == "" {
|
||||
return
|
||||
}
|
||||
|
||||
// Add a processor to resize.
|
||||
procs = append(procs, imgutil.Resize(w, h))
|
||||
// // Add a processor to resize.
|
||||
// procs = append(procs, imgutil.Resize(w, h))
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
connectDestroyer(img, cancel)
|
||||
|
@ -66,13 +53,17 @@ func AsyncImageSized(img ImageContainerSizer, url string, w, h int, procs ...img
|
|||
return
|
||||
}
|
||||
|
||||
l.Connect("size-prepared", func(l *gdk.PixbufLoader, imgW, imgH int) {
|
||||
w, h = imgutil.MaxSize(imgW, imgH, w, h)
|
||||
if w != imgW || h != imgH {
|
||||
l.SetSize(w, h)
|
||||
execIfCtx(ctx, func() { img.SetSizeRequest(w, h) })
|
||||
}
|
||||
})
|
||||
if w > 0 && h > 0 {
|
||||
l.Connect("size-prepared", func(l *gdk.PixbufLoader, imgW, imgH int) {
|
||||
w, h = imgutil.MaxSize(imgW, imgH, w, h)
|
||||
if w != imgW || h != imgH {
|
||||
l.SetSize(w, h)
|
||||
execIfCtx(ctx, func() {
|
||||
img.(ImageContainerSizer).SetSizeRequest(w, h)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
l.Connect("area-prepared", areaPreparedFn(ctx, img, gif))
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@ import (
|
|||
"github.com/diamondburned/cchat-gtk/internal/ui/messages/input"
|
||||
"github.com/diamondburned/cchat-gtk/internal/ui/messages/message"
|
||||
"github.com/diamondburned/cchat-gtk/internal/ui/primitives"
|
||||
"github.com/diamondburned/cchat-gtk/internal/ui/primitives/roundimage"
|
||||
"github.com/diamondburned/cchat-gtk/internal/ui/service/menu"
|
||||
"github.com/diamondburned/imgutil"
|
||||
"github.com/gotk3/gotk3/gtk"
|
||||
)
|
||||
|
||||
|
@ -165,17 +165,17 @@ func NewFullSendingMessage(msg input.PresendMessage) *FullSendingMessage {
|
|||
}
|
||||
|
||||
type Avatar struct {
|
||||
gtk.Image
|
||||
roundimage.Image
|
||||
url string
|
||||
}
|
||||
|
||||
func NewAvatar() *Avatar {
|
||||
avatar, _ := gtk.ImageNew()
|
||||
avatar, _ := roundimage.NewImage(0)
|
||||
avatar.SetSizeRequest(AvatarSize, AvatarSize)
|
||||
avatar.SetVAlign(gtk.ALIGN_START)
|
||||
|
||||
// Default icon.
|
||||
primitives.SetImageIcon(avatar, "user-available-symbolic", AvatarSize)
|
||||
primitives.SetImageIcon(avatar.Image, "user-available-symbolic", AvatarSize)
|
||||
|
||||
return &Avatar{*avatar, ""}
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ func (a *Avatar) SetURL(url string) {
|
|||
}
|
||||
|
||||
a.url = url
|
||||
httputil.AsyncImageSized(a, url, AvatarSize, AvatarSize, imgutil.Round(true))
|
||||
httputil.AsyncImageSized(a, url, AvatarSize, AvatarSize)
|
||||
}
|
||||
|
||||
// ManuallySetURL sets the URL without downloading the image. It assumes the
|
||||
|
|
|
@ -7,13 +7,16 @@ import (
|
|||
"image/png"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-gtk/internal/gts"
|
||||
"github.com/diamondburned/cchat-gtk/internal/log"
|
||||
"github.com/diamondburned/cchat-gtk/internal/ui/primitives"
|
||||
"github.com/diamondburned/cchat-gtk/internal/ui/primitives/roundimage"
|
||||
"github.com/disintegration/imaging"
|
||||
"github.com/gotk3/gotk3/gdk"
|
||||
"github.com/gotk3/gotk3/gtk"
|
||||
|
@ -24,7 +27,10 @@ var pngEncoder = png.Encoder{
|
|||
CompressionLevel: png.BestCompression,
|
||||
}
|
||||
|
||||
const FileIconSize = 72
|
||||
const (
|
||||
ThumbSize = 72
|
||||
IconSize = 56
|
||||
)
|
||||
|
||||
// File represents a middle format that can be used to create a
|
||||
// MessageAttachment.
|
||||
|
@ -264,8 +270,11 @@ func (c *Container) remove(name string) {
|
|||
|
||||
var previewCSS = primitives.PrepareCSS(`
|
||||
.attachment-preview {
|
||||
background-color: alpha(@theme_fg_color, 0.2);
|
||||
border-radius: 4px;
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
|
||||
background-color: alpha(@theme_fg_color, 0.15);
|
||||
border-radius: 5px;
|
||||
}
|
||||
`)
|
||||
|
||||
|
@ -278,7 +287,7 @@ var deleteAttBtnCSS = primitives.PrepareCSS(`
|
|||
/* Add our own styling */
|
||||
border-radius: 999px 999px;
|
||||
transition: linear 100ms all;
|
||||
background-color: alpha(@theme_bg_color, 0.50);
|
||||
background-color: alpha(@theme_bg_color, 0.75);
|
||||
}
|
||||
.delete-attachment:hover {
|
||||
background-color: alpha(red, 0.5);
|
||||
|
@ -287,9 +296,9 @@ var deleteAttBtnCSS = primitives.PrepareCSS(`
|
|||
|
||||
func (c *Container) addPreview(name string, src image.Image) {
|
||||
// Make a fallback image first.
|
||||
gimg, _ := gtk.ImageNew()
|
||||
primitives.SetImageIcon(gimg, "image-x-generic-symbolic", FileIconSize/3)
|
||||
gimg.SetSizeRequest(FileIconSize, FileIconSize)
|
||||
gimg, _ := roundimage.NewImage(4) // border-radius: 4px
|
||||
primitives.SetImageIcon(gimg.Image, iconFromName(name), IconSize)
|
||||
gimg.SetSizeRequest(ThumbSize, ThumbSize)
|
||||
gimg.SetVAlign(gtk.ALIGN_CENTER)
|
||||
gimg.SetHAlign(gtk.ALIGN_CENTER)
|
||||
gimg.SetTooltipText(name)
|
||||
|
@ -300,14 +309,14 @@ func (c *Container) addPreview(name string, src image.Image) {
|
|||
// Determine if we could generate an image preview.
|
||||
if src != nil {
|
||||
// Get the minimum dimension.
|
||||
var w, h = minsize(src.Bounds().Dx(), src.Bounds().Dy(), FileIconSize)
|
||||
var w, h = minsize(src.Bounds().Dx(), src.Bounds().Dy(), ThumbSize)
|
||||
|
||||
var img *image.NRGBA
|
||||
// Downscale the image.
|
||||
img = imaging.Resize(src, w, h, imaging.Lanczos)
|
||||
|
||||
// Crop to a square.
|
||||
img = imaging.CropCenter(img, FileIconSize, FileIconSize)
|
||||
img = imaging.CropCenter(img, ThumbSize, ThumbSize)
|
||||
|
||||
// Copy the image to a pixbuf.
|
||||
gimg.SetFromPixbuf(gts.RenderPixbuf(img))
|
||||
|
@ -315,7 +324,7 @@ func (c *Container) addPreview(name string, src image.Image) {
|
|||
|
||||
// BLOAT!!! Make an overlay of an event box that, when hovered, will show
|
||||
// something that allows closing the image.
|
||||
del, _ := gtk.ButtonNewFromIconName("window-close", gtk.ICON_SIZE_DIALOG)
|
||||
del, _ := gtk.ButtonNewFromIconName("window-close-symbolic", gtk.ICON_SIZE_DIALOG)
|
||||
del.SetVAlign(gtk.ALIGN_CENTER)
|
||||
del.SetHAlign(gtk.ALIGN_CENTER)
|
||||
del.SetTooltipText("Remove " + name)
|
||||
|
@ -325,7 +334,7 @@ func (c *Container) addPreview(name string, src image.Image) {
|
|||
primitives.AttachCSS(del, deleteAttBtnCSS)
|
||||
|
||||
ovl, _ := gtk.OverlayNew()
|
||||
ovl.SetSizeRequest(FileIconSize, FileIconSize)
|
||||
ovl.SetSizeRequest(ThumbSize, ThumbSize)
|
||||
ovl.Add(gimg)
|
||||
ovl.AddOverlay(del)
|
||||
ovl.Show()
|
||||
|
@ -334,6 +343,24 @@ func (c *Container) addPreview(name string, src image.Image) {
|
|||
c.Box.PackStart(ovl, false, false, 0)
|
||||
}
|
||||
|
||||
func iconFromName(filename string) string {
|
||||
switch t := mime.TypeByExtension(filepath.Ext(filename)); {
|
||||
case strings.HasPrefix(t, "image"):
|
||||
return "image-x-generic-symbolic"
|
||||
|
||||
case strings.HasPrefix(t, "audio"):
|
||||
return "audio-x-generic-symbolic"
|
||||
|
||||
case strings.HasPrefix(t, "application"):
|
||||
return "application-x-appliance-symbolic"
|
||||
|
||||
case strings.HasPrefix(t, "text"):
|
||||
fallthrough
|
||||
default:
|
||||
return "text-x-generic-symbolic"
|
||||
}
|
||||
}
|
||||
|
||||
func minsize(w, h, maxsz int) (int, int) {
|
||||
if w < h {
|
||||
// return the scaled width as max
|
||||
|
|
|
@ -35,25 +35,13 @@ var textCSS = primitives.PrepareCSS(`
|
|||
}
|
||||
|
||||
.message-input * {
|
||||
background-color: @theme_base_color;
|
||||
transition: linear 50ms background-color;
|
||||
|
||||
/* Legacy styling
|
||||
border: 1px solid alpha(@theme_fg_color, 0.2);
|
||||
border-radius: 4px;
|
||||
*/
|
||||
}
|
||||
|
||||
.message-input:focus * {
|
||||
background-color: mix(
|
||||
@theme_base_color,
|
||||
@theme_selected_bg_color,
|
||||
0.15
|
||||
);
|
||||
|
||||
/* Legacy styling
|
||||
border-color: @theme_selected_bg_color;
|
||||
*/
|
||||
}
|
||||
`)
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"github.com/diamondburned/cchat-gtk/internal/ui/primitives"
|
||||
"github.com/diamondburned/cchat-gtk/internal/ui/rich"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/diamondburned/imgutil"
|
||||
"github.com/gotk3/gotk3/gtk"
|
||||
)
|
||||
|
||||
|
@ -41,7 +40,7 @@ var usernameCSS = primitives.PrepareCSS(`
|
|||
`)
|
||||
|
||||
func NewContainer() *Container {
|
||||
avatar := rich.NewIcon(AvatarSize, imgutil.Round(true))
|
||||
avatar := rich.NewIcon(AvatarSize)
|
||||
avatar.SetPlaceholderIcon("user-available-symbolic", AvatarSize)
|
||||
avatar.Show()
|
||||
|
||||
|
|
105
internal/ui/primitives/roundimage/roundimage.go
Normal file
105
internal/ui/primitives/roundimage/roundimage.go
Normal file
|
@ -0,0 +1,105 @@
|
|||
package roundimage
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/gotk3/gotk3/cairo"
|
||||
"github.com/gotk3/gotk3/gtk"
|
||||
)
|
||||
|
||||
const (
|
||||
pi = math.Pi
|
||||
circle = 2 * math.Pi
|
||||
)
|
||||
|
||||
type Image struct {
|
||||
*gtk.Image
|
||||
Radius float64
|
||||
}
|
||||
|
||||
// NewImage creates a new round image. If radius is 0, then it will be half the
|
||||
// dimensions. If the radius is less than 0, then nothing is rounded.
|
||||
func NewImage(radius float64) (*Image, error) {
|
||||
i, err := gtk.ImageNew()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
image := &Image{Image: i, Radius: radius}
|
||||
|
||||
// Connect to the draw callback and clip the context.
|
||||
i.Connect("draw", func(i *gtk.Image, cc *cairo.Context) bool {
|
||||
var w = float64(i.GetAllocatedWidth())
|
||||
var h = float64(i.GetAllocatedHeight())
|
||||
|
||||
var min = w
|
||||
// Use the smallest side for radius calculation.
|
||||
if h < w {
|
||||
min = h
|
||||
}
|
||||
|
||||
// Copy the variables in case we need to change them.
|
||||
var r = image.Radius
|
||||
|
||||
// We have to do this so the arc paint doesn't leave back a black
|
||||
// background instead of the usual alpha.
|
||||
// cc.SetSourceRGBA(255, 255, 255, 0)
|
||||
|
||||
switch {
|
||||
// If radius is less than 0, then don't round.
|
||||
case r < 0:
|
||||
break
|
||||
|
||||
// If radius is 0, then we have to calculate our own radius.:This only
|
||||
// works if the image is a square.
|
||||
case r == 0:
|
||||
// Calculate the radius by dividing a side by 2.
|
||||
r = (min / 2)
|
||||
|
||||
// Draw an arc from 0deg to 360deg.
|
||||
cc.Arc(w/2, h/2, r, 0, circle)
|
||||
cc.SetSourceRGBA(255, 255, 255, 0)
|
||||
|
||||
// Clip the image with the arc we drew.
|
||||
cc.Clip()
|
||||
|
||||
// If radius is more than 0, then we have to calculate the radius from
|
||||
// the edges.
|
||||
case r > 0:
|
||||
// StackOverflow is godly.
|
||||
// https://stackoverflow.com/a/6959843.
|
||||
|
||||
// Account for the offset.
|
||||
// r += o
|
||||
|
||||
// Radius should be largest a single side divided by 2.
|
||||
if max := min / 2; r > max {
|
||||
r = max
|
||||
}
|
||||
|
||||
// Draw 4 arcs at 4 corners.
|
||||
cc.Arc(0+r, 0+r, r, 2*(pi/2), 3*(pi/2)) // top left
|
||||
cc.Arc(w-r, 0+r, r, 3*(pi/2), 4*(pi/2)) // top right
|
||||
cc.Arc(w-r, h-r, r, 0*(pi/2), 1*(pi/2)) // bottom right
|
||||
cc.Arc(0+r, h-r, r, 1*(pi/2), 2*(pi/2)) // bottom left
|
||||
|
||||
// Close the created path.
|
||||
cc.ClosePath()
|
||||
cc.SetSourceRGBA(255, 255, 255, 0)
|
||||
|
||||
// Clip the image with the arc we drew.
|
||||
cc.Clip()
|
||||
}
|
||||
|
||||
// Paint the changes.
|
||||
cc.Paint()
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
return image, nil
|
||||
}
|
||||
|
||||
func (i *Image) SetRadius(r float64) {
|
||||
i.Radius = r
|
||||
}
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/diamondburned/cchat-gtk/internal/gts"
|
||||
"github.com/diamondburned/cchat-gtk/internal/gts/httputil"
|
||||
"github.com/diamondburned/cchat-gtk/internal/ui/primitives"
|
||||
"github.com/diamondburned/cchat-gtk/internal/ui/primitives/roundimage"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/diamondburned/imgutil"
|
||||
"github.com/gotk3/gotk3/gtk"
|
||||
|
@ -14,9 +15,10 @@ import (
|
|||
|
||||
type IconerFn = func(context.Context, cchat.IconContainer) (func(), error)
|
||||
|
||||
// Icon represents a rounded image container.
|
||||
type Icon struct {
|
||||
*gtk.Revealer
|
||||
Image *gtk.Image
|
||||
Image *roundimage.Image
|
||||
procs []imgutil.Processor
|
||||
size int
|
||||
|
||||
|
@ -35,7 +37,7 @@ func NewIcon(sizepx int, procs ...imgutil.Processor) *Icon {
|
|||
sizepx = DefaultIconSize
|
||||
}
|
||||
|
||||
img, _ := gtk.ImageNew()
|
||||
img, _ := roundimage.NewImage(0)
|
||||
img.Show()
|
||||
img.SetSizeRequest(sizepx, sizepx)
|
||||
|
||||
|
@ -92,7 +94,7 @@ func (i *Icon) SetPlaceholderIcon(iconName string, iconSzPx int) {
|
|||
i.SetSize(iconSzPx)
|
||||
|
||||
if iconName != "" {
|
||||
primitives.SetImageIcon(i.Image, iconName, iconSzPx)
|
||||
primitives.SetImageIcon(i.Image.Image, iconName, iconSzPx)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,11 +130,7 @@ func (i *Icon) SetIconUnsafe(url string) {
|
|||
}
|
||||
|
||||
func (i *Icon) updateAsync() {
|
||||
if i.size > 0 {
|
||||
httputil.AsyncImageSized(i.Image, i.url, i.size, i.size, i.procs...)
|
||||
} else {
|
||||
httputil.AsyncImage(i.Image, i.url, i.procs...)
|
||||
}
|
||||
httputil.AsyncImageSized(i.Image, i.url, i.size, i.size, i.procs...)
|
||||
}
|
||||
|
||||
type ToggleButtonImage struct {
|
||||
|
|
|
@ -17,7 +17,7 @@ type ToggleButtonImage struct {
|
|||
clicked func(bool)
|
||||
|
||||
err error
|
||||
icon bool // whether or not the button has an icon
|
||||
icon string // whether or not the button has an icon
|
||||
iconSz int
|
||||
}
|
||||
|
||||
|
@ -62,8 +62,8 @@ func (b *ToggleButtonImage) SetNormal() {
|
|||
b.SetLabelUnsafe(b.GetLabel())
|
||||
b.menu.SetItems(b.extraMenu)
|
||||
|
||||
if b.icon {
|
||||
b.Image.SetPlaceholderIcon("user-available-symbolic", b.Image.Size())
|
||||
if b.icon != "" {
|
||||
b.Image.SetPlaceholderIcon(b.icon, b.Image.Size())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ func (b *ToggleButtonImage) SetLoading() {
|
|||
// Reset the menu.
|
||||
b.menu.SetItems(b.extraMenu)
|
||||
|
||||
if b.icon {
|
||||
if b.icon != "" {
|
||||
b.Image.SetPlaceholderIcon("content-loading-symbolic", b.Image.Size())
|
||||
}
|
||||
}
|
||||
|
@ -87,13 +87,13 @@ func (b *ToggleButtonImage) SetFailed(err error, retry func()) {
|
|||
b.menu.AddItems(b.extraMenu...)
|
||||
|
||||
// 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())
|
||||
}
|
||||
}
|
||||
|
||||
func (b *ToggleButtonImage) SetPlaceholderIcon(iconName string, iconSzPx int) {
|
||||
b.icon = true
|
||||
b.icon = iconName
|
||||
b.Image.SetPlaceholderIcon(iconName, iconSzPx)
|
||||
}
|
||||
|
||||
|
@ -102,12 +102,6 @@ func (b *ToggleButtonImage) SetIcon(url string) {
|
|||
}
|
||||
|
||||
func (b *ToggleButtonImage) SetIconUnsafe(url string) {
|
||||
b.icon = true
|
||||
b.icon = ""
|
||||
b.Image.SetIconUnsafe(url)
|
||||
}
|
||||
|
||||
// type Row struct {
|
||||
// gtk.Box
|
||||
// Button *ToggleButtonImage
|
||||
// Children *gtk.Box
|
||||
// }
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"github.com/diamondburned/cchat-gtk/internal/ui/rich"
|
||||
"github.com/diamondburned/cchat-gtk/internal/ui/service/config"
|
||||
"github.com/diamondburned/cchat-gtk/internal/ui/service/menu"
|
||||
"github.com/diamondburned/imgutil"
|
||||
"github.com/gotk3/gotk3/gtk"
|
||||
)
|
||||
|
||||
|
@ -21,7 +20,6 @@ type header struct {
|
|||
|
||||
func newHeader(svc cchat.Service) *header {
|
||||
b := rich.NewToggleButtonImage(svc.Name())
|
||||
b.Image.AddProcessors(imgutil.Round(true))
|
||||
b.Image.SetPlaceholderIcon("folder-remote-symbolic", IconSize)
|
||||
b.SetRelief(gtk.RELIEF_NONE)
|
||||
b.SetMode(true)
|
||||
|
|
|
@ -10,13 +10,12 @@ import (
|
|||
"github.com/diamondburned/cchat-gtk/internal/ui/service/loading"
|
||||
"github.com/diamondburned/cchat-gtk/internal/ui/service/menu"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/diamondburned/imgutil"
|
||||
"github.com/gotk3/gotk3/gtk"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const ChildrenMargin = 24
|
||||
const IconSize = 20
|
||||
const IconSize = 32
|
||||
|
||||
type Controller interface {
|
||||
RowSelected(*ServerRow, cchat.ServerMessage)
|
||||
|
@ -36,8 +35,6 @@ type Row struct {
|
|||
func NewRow(parent breadcrumb.Breadcrumber, name text.Rich) *Row {
|
||||
button := button.NewToggleButtonImage(name)
|
||||
button.Box.SetHAlign(gtk.ALIGN_START)
|
||||
button.Image.AddProcessors(imgutil.Round(true))
|
||||
button.Image.SetSize(IconSize)
|
||||
button.SetRelief(gtk.RELIEF_NONE)
|
||||
button.Show()
|
||||
|
||||
|
@ -64,6 +61,7 @@ func (r *Row) SetLabelUnsafe(name text.Rich) {
|
|||
|
||||
func (r *Row) SetIconer(v interface{}) {
|
||||
if iconer, ok := v.(cchat.Icon); ok {
|
||||
r.Button.Image.SetSize(IconSize)
|
||||
r.Button.Image.AsyncSetIconer(iconer, "Error getting server icon URL")
|
||||
}
|
||||
}
|
||||
|
@ -134,7 +132,9 @@ func (r *Row) childrenFailed(err error) {
|
|||
|
||||
func (r *Row) childrenDone() {
|
||||
r.loaded = true
|
||||
r.SetDone()
|
||||
|
||||
// I don't think this is supposed to be called here...
|
||||
// r.SetDone()
|
||||
}
|
||||
|
||||
// SetSelected is used for highlighting the current message server.
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
)
|
||||
|
||||
const IconSize = 32
|
||||
const IconName = "face-plain-symbolic"
|
||||
|
||||
// Controller extends server.RowController to add session.
|
||||
type Controller interface {
|
||||
|
@ -67,7 +68,7 @@ func NewLoading(parent breadcrumb.Breadcrumber, id, name string, ctrl Controller
|
|||
|
||||
func newRow(parent breadcrumb.Breadcrumber, name text.Rich, ctrl Controller) *Row {
|
||||
srow := server.NewRow(parent, name)
|
||||
srow.Button.SetPlaceholderIcon("user-invisible-symbolic", IconSize)
|
||||
srow.Button.SetPlaceholderIcon(IconName, IconSize)
|
||||
srow.Show()
|
||||
|
||||
// Bind the row to .session in CSS.
|
||||
|
@ -142,7 +143,7 @@ func (r *Row) DisconnectSession() {
|
|||
r.Reset()
|
||||
|
||||
// Set the offline icon to the button.
|
||||
r.Button.Image.SetPlaceholderIcon("user-invisible-symbolic", IconSize)
|
||||
r.Button.Image.SetPlaceholderIcon(IconName, IconSize)
|
||||
// Also unselect the button.
|
||||
r.Button.SetActive(false)
|
||||
|
||||
|
|
Loading…
Reference in a new issue