Rename UIString to TString, move ansimage to lib/ and switch to tcell fork

This commit is contained in:
Tulir Asokan
2018-04-11 17:57:15 +03:00
parent c0705b02a0
commit ff7ee333a1
20 changed files with 378 additions and 88 deletions

View File

@ -22,7 +22,8 @@ import (
"math"
"os"
"github.com/gdamore/tcell"
"maunium.net/go/gomuks/ui/messages/tstring"
"maunium.net/go/tcell"
"maunium.net/go/gomuks/debug"
"maunium.net/go/gomuks/interface"
"maunium.net/go/gomuks/ui/messages"
@ -48,7 +49,7 @@ type MessageView struct {
messageIDs map[string]messages.UIMessage
messages []messages.UIMessage
textBuffer []messages.UIString
textBuffer []tstring.TString
metaBuffer []ifc.MessageMeta
}
@ -61,7 +62,7 @@ func NewMessageView() *MessageView {
messages: make([]messages.UIMessage, 0),
messageIDs: make(map[string]messages.UIMessage),
textBuffer: make([]messages.UIString, 0),
textBuffer: make([]tstring.TString, 0),
metaBuffer: make([]ifc.MessageMeta, 0),
widestSender: 5,
@ -183,7 +184,7 @@ func (view *MessageView) appendBuffer(message messages.UIMessage) {
if len(view.metaBuffer) > 0 {
prevMeta := view.metaBuffer[len(view.metaBuffer)-1]
if prevMeta != nil && prevMeta.FormatDate() != message.FormatDate() {
view.textBuffer = append(view.textBuffer, messages.NewColorUIString(
view.textBuffer = append(view.textBuffer, tstring.NewColorTString(
fmt.Sprintf("Date changed to %s", message.FormatDate()),
tcell.ColorGreen))
view.metaBuffer = append(view.metaBuffer, &messages.BasicMeta{
@ -218,7 +219,6 @@ func (view *MessageView) replaceBuffer(message messages.UIMessage) {
view.textBuffer = append(append(view.textBuffer[0:start], message.Buffer()...), view.textBuffer[end:]...)
if len(message.Buffer()) != end-start+1 {
debug.Print(end, "-", start, "!=", len(message.Buffer()))
metaBuffer := view.metaBuffer[0:start]
for range message.Buffer() {
metaBuffer = append(metaBuffer, message)
@ -233,7 +233,7 @@ func (view *MessageView) recalculateBuffers() {
width -= view.TimestampWidth + TimestampSenderGap + view.widestSender + SenderMessageGap
recalculateMessageBuffers := width != view.prevWidth
if height != view.prevHeight || recalculateMessageBuffers || len(view.messages) != view.prevMsgCount {
view.textBuffer = []messages.UIString{}
view.textBuffer = []tstring.TString{}
view.metaBuffer = []ifc.MessageMeta{}
view.prevMsgCount = 0
for i, message := range view.messages {

View File

@ -23,11 +23,12 @@ import (
"image/color"
"github.com/gdamore/tcell"
"maunium.net/go/gomuks/debug"
"maunium.net/go/gomuks/interface"
"maunium.net/go/gomuks/ui/messages/tstring"
"maunium.net/go/gomuks/ui/widget"
"maunium.net/go/pixterm/ansimage"
"maunium.net/go/gomuks/lib/ansimage"
"maunium.net/go/tcell"
)
func init() {
@ -36,11 +37,12 @@ func init() {
type UIImageMessage struct {
UITextMessage
Path string
data []byte
}
// NewImageMessage creates a new UIImageMessage object with the provided values and the default state.
func NewImageMessage(id, sender, msgtype string, data []byte, timestamp time.Time) UIMessage {
func NewImageMessage(id, sender, msgtype string, path string, data []byte, timestamp time.Time) UIMessage {
return &UIImageMessage{
UITextMessage{
MsgSender: sender,
@ -53,6 +55,7 @@ func NewImageMessage(id, sender, msgtype string, data []byte, timestamp time.Tim
MsgIsHighlight: false,
MsgIsService: false,
},
path,
data,
}
}
@ -90,24 +93,13 @@ func (msg *UIImageMessage) CalculateBuffer(width int) {
return
}
image, err := ansimage.NewScaledFromReader(bytes.NewReader(msg.data), -1, width, color.Black, ansimage.ScaleModeResize, ansimage.NoDithering)
image, err := ansimage.NewScaledFromReader(bytes.NewReader(msg.data), 0, width, color.Black)
if err != nil {
msg.buffer = []UIString{NewColorUIString("Failed to display image", tcell.ColorRed)}
msg.buffer = []tstring.TString{tstring.NewColorTString("Failed to display image", tcell.ColorRed)}
debug.Print("Failed to display image:", err)
return
}
msg.buffer = make([]UIString, image.Height())
pixels := image.Pixmap()
for row, pixelRow := range pixels {
msg.buffer[row] = make(UIString, len(pixelRow))
for column, pixel := range pixelRow {
pixelColor := tcell.NewRGBColor(int32(pixel.R), int32(pixel.G), int32(pixel.B))
msg.buffer[row][column] = Cell{
Char: ' ',
Style: tcell.StyleDefault.Background(pixelColor),
}
}
}
msg.buffer = image.Render()
msg.prevBufferWidth = width
}

View File

@ -18,6 +18,7 @@ package messages
import (
"maunium.net/go/gomuks/interface"
"maunium.net/go/gomuks/ui/messages/tstring"
)
// Message is a wrapper for the content and metadata of a Matrix message intended to be displayed.
@ -26,7 +27,7 @@ type UIMessage interface {
CalculateBuffer(width int)
RecalculateBuffer()
Buffer() []UIString
Buffer() []tstring.TString
Height() int
RealSender() string

View File

@ -19,7 +19,7 @@ package messages
import (
"time"
"github.com/gdamore/tcell"
"maunium.net/go/tcell"
"maunium.net/go/gomuks/interface"
)

View File

@ -20,12 +20,13 @@ import (
"fmt"
"time"
"github.com/gdamore/tcell"
"maunium.net/go/gomatrix"
"maunium.net/go/gomuks/debug"
"maunium.net/go/gomuks/interface"
"maunium.net/go/gomuks/matrix/rooms"
"maunium.net/go/gomuks/ui/messages/tstring"
"maunium.net/go/gomuks/ui/widget"
"maunium.net/go/tcell"
)
func ParseEvent(mx ifc.MatrixContainer, room *rooms.Room, evt *gomatrix.Event) UIMessage {
@ -59,16 +60,16 @@ func ParseMessage(mx ifc.MatrixContainer, evt *gomatrix.Event) UIMessage {
return NewTextMessage(evt.ID, evt.Sender, msgtype, text, ts)
case "m.image":
url, _ := evt.Content["url"].(string)
data, err := mx.Download(url)
data, path, err := mx.Download(url)
if err != nil {
debug.Printf("Failed to download %s: %v", url, err)
}
return NewImageMessage(evt.ID, evt.Sender, msgtype, data, ts)
return NewImageMessage(evt.ID, evt.Sender, msgtype, path, data, ts)
}
return nil
}
func getMembershipEventContent(evt *gomatrix.Event) (sender string, text UIString) {
func getMembershipEventContent(evt *gomatrix.Event) (sender string, text tstring.TString) {
membership, _ := evt.Content["membership"].(string)
displayname, _ := evt.Content["displayname"].(string)
if len(displayname) == 0 {
@ -85,28 +86,28 @@ func getMembershipEventContent(evt *gomatrix.Event) (sender string, text UIStrin
switch membership {
case "invite":
sender = "---"
text = NewColorUIString(fmt.Sprintf("%s invited %s.", evt.Sender, displayname), tcell.ColorYellow)
text = tstring.NewColorTString(fmt.Sprintf("%s invited %s.", evt.Sender, displayname), tcell.ColorYellow)
text.Colorize(0, len(evt.Sender), widget.GetHashColor(evt.Sender))
text.Colorize(len(evt.Sender)+len(" invited "), len(displayname), widget.GetHashColor(displayname))
case "join":
sender = "-->"
text = NewColorUIString(fmt.Sprintf("%s joined the room.", displayname), tcell.ColorGreen)
text = tstring.NewColorTString(fmt.Sprintf("%s joined the room.", displayname), tcell.ColorGreen)
text.Colorize(0, len(displayname), widget.GetHashColor(displayname))
case "leave":
sender = "<--"
if evt.Sender != *evt.StateKey {
reason, _ := evt.Content["reason"].(string)
text = NewColorUIString(fmt.Sprintf("%s kicked %s: %s", evt.Sender, displayname, reason), tcell.ColorRed)
text = tstring.NewColorTString(fmt.Sprintf("%s kicked %s: %s", evt.Sender, displayname, reason), tcell.ColorRed)
text.Colorize(0, len(evt.Sender), widget.GetHashColor(evt.Sender))
text.Colorize(len(evt.Sender)+len(" kicked "), len(displayname), widget.GetHashColor(displayname))
} else {
text = NewColorUIString(fmt.Sprintf("%s left the room.", displayname), tcell.ColorRed)
text = tstring.NewColorTString(fmt.Sprintf("%s left the room.", displayname), tcell.ColorRed)
text.Colorize(0, len(displayname), widget.GetHashColor(displayname))
}
}
} else if displayname != prevDisplayname {
sender = "---"
text = NewColorUIString(fmt.Sprintf("%s changed their display name to %s.", prevDisplayname, displayname), tcell.ColorYellow)
text = tstring.NewColorTString(fmt.Sprintf("%s changed their display name to %s.", prevDisplayname, displayname), tcell.ColorYellow)
text.Colorize(0, len(prevDisplayname), widget.GetHashColor(prevDisplayname))
text.Colorize(len(prevDisplayname)+len(" changed their display name to "), len(displayname), widget.GetHashColor(displayname))
}

View File

@ -22,7 +22,8 @@ import (
"regexp"
"time"
"github.com/gdamore/tcell"
"maunium.net/go/gomuks/ui/messages/tstring"
"maunium.net/go/tcell"
"maunium.net/go/gomuks/interface"
"maunium.net/go/gomuks/ui/widget"
)
@ -34,11 +35,11 @@ func init() {
type UIExpandedTextMessage struct {
UITextMessage
MsgUIStringText UIString
MsgTStringText tstring.TString
}
// NewExpandedTextMessage creates a new UIExpandedTextMessage object with the provided values and the default state.
func NewExpandedTextMessage(id, sender, msgtype string, text UIString, timestamp time.Time) UIMessage {
func NewExpandedTextMessage(id, sender, msgtype string, text tstring.TString, timestamp time.Time) UIMessage {
return &UIExpandedTextMessage{
UITextMessage{
MsgSender: sender,
@ -56,8 +57,8 @@ func NewExpandedTextMessage(id, sender, msgtype string, text UIString, timestamp
}
}
func (msg *UIExpandedTextMessage) GetUIStringText() UIString {
return msg.MsgUIStringText
func (msg *UIExpandedTextMessage) GetTStringText() tstring.TString {
return msg.MsgTStringText
}
// CopyFrom replaces the content of this message object with the content of the given object.
@ -78,9 +79,9 @@ func (msg *UIExpandedTextMessage) CopyFrom(from ifc.MessageMeta) {
fromExpandedMsg, ok := from.(*UIExpandedTextMessage)
if ok {
msg.MsgUIStringText = fromExpandedMsg.MsgUIStringText
msg.MsgTStringText = fromExpandedMsg.MsgTStringText
} else {
msg.MsgUIStringText = NewColorUIString(fromMsg.Text(), from.TextColor())
msg.MsgTStringText = tstring.NewColorTString(fromMsg.Text(), from.TextColor())
}
msg.RecalculateBuffer()
@ -97,7 +98,7 @@ type UITextMessage struct {
MsgState ifc.MessageState
MsgIsHighlight bool
MsgIsService bool
buffer []UIString
buffer []tstring.TString
prevBufferWidth int
}
@ -235,7 +236,7 @@ func (msg *UITextMessage) RecalculateBuffer() {
//
// N.B. This will NOT automatically calculate the buffer if it hasn't been
// calculated already, as that requires the target width.
func (msg *UITextMessage) Buffer() []UIString {
func (msg *UITextMessage) Buffer() []tstring.TString {
return msg.buffer
}
@ -307,8 +308,8 @@ func (msg *UITextMessage) SetIsService(isService bool) {
msg.MsgIsService = isService
}
func (msg *UITextMessage) GetUIStringText() UIString {
return NewColorUIString(msg.Text(), msg.TextColor())
func (msg *UITextMessage) GetTStringText() tstring.TString {
return tstring.NewColorTString(msg.Text(), msg.TextColor())
}
// Regular expressions used to split lines when calculating the buffer.
@ -327,10 +328,10 @@ func (msg *UITextMessage) CalculateBuffer(width int) {
return
}
msg.buffer = []UIString{}
text := msg.GetUIStringText()
msg.buffer = []tstring.TString{}
text := msg.GetTStringText()
if msg.MsgType == "m.emote" {
text = NewColorUIString(fmt.Sprintf("* %s %s", msg.MsgSender, text.String()), msg.TextColor())
text = tstring.NewColorTString(fmt.Sprintf("* %s %s", msg.MsgSender, text.String()), msg.TextColor())
text.Colorize(2, len(msg.MsgSender), msg.SenderColor())
}
@ -338,7 +339,7 @@ func (msg *UITextMessage) CalculateBuffer(width int) {
newlines := 0
for _, str := range forcedLinebreaks {
if len(str) == 0 && newlines < 1 {
msg.buffer = append(msg.buffer, UIString{})
msg.buffer = append(msg.buffer, tstring.TString{})
newlines++
} else {
newlines = 0

View File

@ -14,10 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package messages
package tstring
import (
"github.com/gdamore/tcell"
"maunium.net/go/tcell"
"github.com/mattn/go-runewidth"
)

View File

@ -14,18 +14,18 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package messages
package tstring
import (
"strings"
"github.com/gdamore/tcell"
"maunium.net/go/tcell"
"github.com/mattn/go-runewidth"
)
type UIString []Cell
type TString []Cell
func NewUIString(str string) UIString {
func NewTString(str string) TString {
newStr := make([]Cell, len(str))
for i, char := range str {
newStr[i] = NewCell(char)
@ -33,7 +33,7 @@ func NewUIString(str string) UIString {
return newStr
}
func NewColorUIString(str string, color tcell.Color) UIString {
func NewColorTString(str string, color tcell.Color) TString {
newStr := make([]Cell, len(str))
for i, char := range str {
newStr[i] = NewColorCell(char, color)
@ -41,7 +41,7 @@ func NewColorUIString(str string, color tcell.Color) UIString {
return newStr
}
func NewStyleUIString(str string, style tcell.Style) UIString {
func NewStyleTString(str string, style tcell.Style) TString {
newStr := make([]Cell, len(str))
for i, char := range str {
newStr[i] = NewStyleCell(char, style)
@ -49,27 +49,27 @@ func NewStyleUIString(str string, style tcell.Style) UIString {
return newStr
}
func (str UIString) Colorize(from, length int, color tcell.Color) {
func (str TString) Colorize(from, length int, color tcell.Color) {
for i := from; i < from+length; i++ {
str[i].Style = str[i].Style.Foreground(color)
}
}
func (str UIString) Draw(screen tcell.Screen, x, y int) {
func (str TString) Draw(screen tcell.Screen, x, y int) {
offsetX := 0
for _, cell := range str {
offsetX += cell.Draw(screen, x+offsetX, y)
}
}
func (str UIString) RuneWidth() (width int) {
func (str TString) RuneWidth() (width int) {
for _, cell := range str {
width += runewidth.RuneWidth(cell.Char)
}
return width
}
func (str UIString) String() string {
func (str TString) String() string {
var buf strings.Builder
for _, cell := range str {
buf.WriteRune(cell.Char)
@ -78,7 +78,7 @@ func (str UIString) String() string {
}
// Truncate return string truncated with w cells
func (str UIString) Truncate(w int) UIString {
func (str TString) Truncate(w int) TString {
if str.RuneWidth() <= w {
return str[:]
}
@ -94,7 +94,7 @@ func (str UIString) Truncate(w int) UIString {
return str[0:i]
}
func (str UIString) IndexFrom(r rune, from int) int {
func (str TString) IndexFrom(r rune, from int) int {
for i := from; i < len(str); i++ {
if str[i].Char == r {
return i
@ -103,11 +103,11 @@ func (str UIString) IndexFrom(r rune, from int) int {
return -1
}
func (str UIString) Index(r rune) int {
func (str TString) Index(r rune) int {
return str.IndexFrom(r, 0)
}
func (str UIString) Count(r rune) (counter int) {
func (str TString) Count(r rune) (counter int) {
index := 0
for {
index = str.IndexFrom(r, index)
@ -120,8 +120,8 @@ func (str UIString) Count(r rune) (counter int) {
return
}
func (str UIString) Split(sep rune) []UIString {
a := make([]UIString, str.Count(sep)+1)
func (str TString) Split(sep rune) []TString {
a := make([]TString, str.Count(sep)+1)
i := 0
orig := str
for {

View File

@ -20,7 +20,7 @@ import (
"fmt"
"strconv"
"github.com/gdamore/tcell"
"maunium.net/go/tcell"
"maunium.net/go/gomuks/matrix/rooms"
"maunium.net/go/gomuks/ui/widget"
"maunium.net/go/tview"

View File

@ -23,7 +23,7 @@ import (
"strings"
"time"
"github.com/gdamore/tcell"
"maunium.net/go/tcell"
"maunium.net/go/gomuks/interface"
"maunium.net/go/gomuks/matrix/rooms"
"maunium.net/go/gomuks/ui/messages"

View File

@ -17,7 +17,7 @@
package ui
import (
"github.com/gdamore/tcell"
"maunium.net/go/tcell"
"maunium.net/go/gomuks/interface"
"maunium.net/go/tview"
)

View File

@ -23,7 +23,7 @@ import (
"time"
"unicode"
"github.com/gdamore/tcell"
"maunium.net/go/tcell"
"github.com/mattn/go-runewidth"
"maunium.net/go/gomatrix"
"maunium.net/go/gomuks/config"
@ -230,6 +230,11 @@ func (view *MainView) MouseEventHandler(roomView *RoomView, event *tcell.EventMo
x, y := event.Position()
switch event.Buttons() {
case tcell.Button1:
mx, my, mw, mh := msgView.GetRect()
if x >= mx && y >= my && x < mx+mw && y < my+mh {
debug.Print("Message view clicked")
}
case tcell.WheelUp:
if msgView.IsAtTop() {
go view.LoadHistory(roomView.Room.ID, false)

View File

@ -24,7 +24,7 @@ import (
"strings"
"unicode/utf8"
"github.com/gdamore/tcell"
"maunium.net/go/tcell"
"github.com/mattn/go-runewidth"
"github.com/zyedidia/clipboard"
"maunium.net/go/tview"

View File

@ -17,7 +17,7 @@
package widget
import (
"github.com/gdamore/tcell"
"maunium.net/go/tcell"
"maunium.net/go/tview"
)

View File

@ -21,7 +21,7 @@ import (
"hash/fnv"
"sort"
"github.com/gdamore/tcell"
"maunium.net/go/tcell"
)
var colorNames []string

View File

@ -17,7 +17,7 @@
package widget
import (
"github.com/gdamore/tcell"
"maunium.net/go/tcell"
"github.com/mattn/go-runewidth"
"maunium.net/go/tview"
)