-
Notifications
You must be signed in to change notification settings - Fork 1
/
tab_chatbox.go
164 lines (150 loc) · 3.96 KB
/
tab_chatbox.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package main
import (
"fmt"
"log"
"time"
"unsafe"
"github.com/lxn/win"
)
type tabChatbox struct {
tabCommon
unread int
unreadSpaced bool
disconnected bool
error bool
notify bool
textBuffer *RichEdit
textInput *MyLineEdit
chatlogger func(string)
nickQueue *nickQueue
}
func (t *tabChatbox) Padlen(nick string) int {
if t.nickQueue == nil {
t.nickQueue = &nickQueue{}
}
t.nickQueue.Push(stripFmtChars(nick))
return t.nickQueue.Mode()
}
func (t *tabChatbox) Clear() {
t.nickQueue = &nickQueue{}
mw.Synchronize(func() {
t.textBuffer.SetText("")
})
}
func (t *tabChatbox) Title() string {
title := t.tabTitle
if t.unread > 0 && !t.HasFocus() {
title = fmt.Sprintf("%s %d", title, t.unread)
}
if t.notify {
title = "* " + title
}
if t.error {
title = "! " + title
}
if t.disconnected {
title = "(" + title + ")"
}
return title
}
// TODO(tso): think of a better name than UpdateMessageCounterAndPossiblyNickFlashSlashHighlight
func (t *tabChatbox) Notify(asterisk bool) {
if !t.HasFocus() {
if asterisk {
t.notify = true
}
t.unread++
mw.WindowBase.Synchronize(func() {
t.tabPage.SetTitle(t.Title())
SetSystrayContextMenu()
})
}
}
func (t *tabChatbox) Focus() {
t.unread = 0
t.unreadSpaced = false
t.error = false
t.notify = false
mw.WindowBase.Synchronize(func() {
t.tabPage.SetTitle(t.Title())
SetStatusBarIcon(t.statusIcon)
SetStatusBarText(t.statusText)
t.textInput.SetFocus()
t.textBuffer.SendMessage(win.WM_VSCROLL, win.SB_BOTTOM, 0)
SetSystrayContextMenu()
})
}
func (t *tabChatbox) Logln(text string) {
t.chatlogger(text)
}
func (t *tabChatbox) Errorln(text string, styles [][]int) {
if !t.HasFocus() {
t.error = true
}
mw.WindowBase.Synchronize(func() {
SetStatusBarIcon("res/msg_error.ico")
SetStatusBarText(text)
})
// TODO(tso): set status bar icon
t.Println(text, styles)
}
func (t *tabChatbox) Println(text string, styles [][]int) {
mw.Synchronize(func() {
// HACK(tso): synchronization issue
// - goirc is firing off handlers in goroutines as fast as it can
// - tab creation has to be wrapped in a mw.Synchronize so that's
// happening in another thread as well
// - that mutex in clientState is doing nothing and we can't put
// it in the Synchronize callbacks because they could happen in
// some arbitrary order
// so whatever hopefully this won't block the mainthread or be an
// infinite loop...
// -tso 7/16/2018 4:06:27 PM
for t.textBuffer == nil {
<-time.After(time.Millisecond * 500)
for i := 0; i < 100; i++ {
log.Println("textBuffer is nil! <- THIS IS STILL HAPPENING AAAAAaaaaaaaaaaaaaaaa")
}
}
lpsi := win.SCROLLINFO{}
lpsi.FMask = win.SIF_ALL
lpsi.CbSize = uint32(unsafe.Sizeof(lpsi))
shouldScroll := false
if win.GetScrollInfo(t.textBuffer.Handle(), win.SB_VERT, &lpsi) {
// min := int(lpsi.NMin)
max := int(lpsi.NMax)
pos := int(int32(lpsi.NPage) + lpsi.NPos)
// log.Printf("lpsi: %+v min: %v max: %v pos: %v", lpsi, min, max, pos)
if lpsi.NPage == 0 {
shouldScroll = true
} else {
shouldScroll = pos >= max
}
} else {
// log.Println("failed to GetScrollInfo()!")
}
// log.Printf("shouldScroll: %v", shouldScroll)
if t.unread > 0 && !t.unreadSpaced {
// TODO(tso): think of something better than a bunch of whitespace
// because apparently I have a tendency to focus and unfocus
// the window without thinking about it
//
// and chat
//
// ends up
//
// looking
//
// like this
//
// maybe put an arrow instead of the timestamp where the first new message begins
// -tso 7/15/2018 1:07:16 PM
t.unreadSpaced = true
}
t.textBuffer.AppendText("\n")
t.textBuffer.AppendText(text, styles...)
if shouldScroll {
t.textBuffer.SendMessage(win.WM_VSCROLL, win.SB_BOTTOM, 0)
}
})
}