chatMessages "fl-gui.name/twitchchat/twitch/core/messages"
"fl-gui.name/twitchchat/twitch/core/privmsg"
"fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/theme"
"go.openfl.eu/chat-scroller/messages"
)
type ChatWindow struct {
content *scrollCanvas
messagesSync sync.Mutex
+ textSize float32
}
func (c *ChatWindow) OnMessage(m chatMessages.Message) {
defer c.messagesSync.Unlock()
text := privmsg.Privmsg{m}
- co := newWrappingTextLine(text)
+ co := newWrappingTextLine(text, c.textSize)
c.content.Add(co)
}
w := app.NewWindow("chat")
content := newScrollingCanvas()
- cw := ChatWindow{content, sync.Mutex{}}
+ cw := ChatWindow{content, sync.Mutex{}, app.Settings().Theme().Size(theme.SizeNameText)}
messages.Listen(&cw)
w.SetContent(content)
)
type TextLineRenderer struct {
- objects []fyne.CanvasObject
+ objects []fyne.CanvasObject
+ textHeight float32
}
-func newTextLineRenderer(objects []fyne.CanvasObject) *TextLineRenderer {
- return &TextLineRenderer{objects}
+func newTextLineRenderer(objects []fyne.CanvasObject, textHeight float32) *TextLineRenderer {
+ return &TextLineRenderer{objects, textHeight}
}
func (t *TextLineRenderer) Destroy() {
lineHeight := float32(0)
for _, o := range t.objects {
if currentPos.X+o.MinSize().Width > size.Width {
- currentPos = fyne.Position{0, currentPos.Y + lineHeight}
+ currentPos = fyne.Position{0, currentPos.Y + lineHeight + 3}
lineHeight = 0
} else {
if o.MinSize().Height > lineHeight {
lineHeight = o.MinSize().Height
}
}
- o.Move(currentPos)
+ o.Move(currentPos.Add(fyne.Position{0, (t.textHeight - o.MinSize().Height) / 2}))
currentPos = currentPos.Add(fyne.Position{o.MinSize().Width, 0})
}
}
type WrappingTextLine struct {
widget.BaseWidget
- message privmsg.Privmsg
+ message privmsg.Privmsg
+ textSize float32
}
-func newWrappingTextLine(message privmsg.Privmsg) *WrappingTextLine {
+func newWrappingTextLine(message privmsg.Privmsg, textSize float32) *WrappingTextLine {
item := &WrappingTextLine{
- message: message,
+ message: message,
+ textSize: textSize,
}
item.ExtendBaseWidget(item)
return item
objects := make([]fyne.CanvasObject, 0, 3)
// badges
- appendBadges(&objects, w.message)
+ w.appendBadges(&objects, w.message)
// username
userColor, ok := hexColorToColor(w.message.Color())
objects = append(objects, sepObject)
// message
- appendMessages(&objects, w.message)
- return newTextLineRenderer(objects)
+ w.appendMessages(&objects, w.message)
+ return newTextLineRenderer(objects, w.textSize)
}
-func appendBadges(objects *[]fyne.CanvasObject, message privmsg.Privmsg) {
+func (w *WrappingTextLine) appendBadges(objects *[]fyne.CanvasObject, message privmsg.Privmsg) {
for _, b := range strings.Split(message.Badges(), ",") {
i := decorations.GetBadge(b)
if i == nil {
continue
}
img := canvas.NewImageFromImage(*i)
- img.SetMinSize(fyne.Size{18, 18})
- img.Resize(fyne.Size{18, 18})
+ size := w.textSize
+ img.SetMinSize(fyne.Size{size, size})
+ img.Resize(fyne.Size{size, size})
*objects = append(*objects, img)
}
}
-func appendMessages(objects *[]fyne.CanvasObject, message privmsg.Privmsg) {
+func (w *WrappingTextLine) appendMessages(objects *[]fyne.CanvasObject, message privmsg.Privmsg) {
emotes := parseEmotesTag(message)
text := message.UserMessage()
textCol := color.RGBA{10, 10, 10, 255}
return
}
img := canvas.NewImageFromImage(*i)
- img.SetMinSize(fyne.Size{18, 18})
- img.Resize(fyne.Size{18, 18})
+ size := w.textSize * 1.2 // should be configurable, but also fix emotes overlapping outside of a text line
+ img.Resize(fyne.Size{img.Aspect() * size, size})
+ img.SetMinSize(img.Size())
*objects = append(*objects, img)
}
"os"
"runtime/pprof"
+ "fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/data/binding"
"fyne.io/fyne/v2/theme"
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
var memprofile = flag.String("memprofile", "", "write memory profile to `file`")
+type chattheme struct {
+ fyne.Theme
+}
+
+func (c chattheme) Size(name fyne.ThemeSizeName) float32 {
+ if name == theme.SizeNameText {
+ return 24
+ }
+ return c.Theme.Size(name)
+}
+
func main() {
flag.Parse()
if *cpuprofile != "" {
// this listener will trigger on initialization
model.Application.Twitch.TokenState.AddListener(binding.NewDataListener(func() { token.Authenticate(&scroller) }))
- scroller.Settings().SetTheme(theme.LightTheme())
+ scroller.Settings().SetTheme(chattheme{theme.LightTheme()})
go status.CreateSetupWindow(scroller)