summaryrefslogtreecommitdiff
path: root/gui/chatlog.py
blob: aca95648ddc79b58936c31d19d88481cf4453527 (plain) (blame)
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
from kivy.event import EventDispatcher
from kivy.uix.abstractview import AbstractView
from kivy.properties import ListProperty, NumericProperty
from kivy.adapters.simplelistadapter import SimpleListAdapter
from kivy.utils import escape_markup
from kivy.clock import Clock
from kivy.uix.label import Label
# from utils import log_method

from textutils import (links_to_markup, replace_emotes, preprocess,
                       remove_formatting)


class ChatLog(AbstractView, EventDispatcher):

    def __init__(self, **kwargs):
        # Check for adapter argument
        if 'adapter' not in kwargs:
            list_adapter = SimpleListAdapter(data=[], cls=Label)
            kwargs['adapter'] = list_adapter

        super(ChatLog, self).__init__(**kwargs)

        self._views = []

        populate = self._trigger_populate = Clock.create_trigger(
            self._populate, -1)

        fbind = self.fbind
        fbind('adapter', populate)
        fbind('size', populate)
        fbind('pos', populate)

    max_lines = NumericProperty(100)
    cut_lines = NumericProperty(10)

    def _populate(self, *args):
        container = self.container
        adapter = self.adapter
        container.clear_widgets()
        self._views = []

        for index in range(adapter.get_count()):
            item_view = adapter.get_view(index)
            self.container.add_widget(item_view)
            self._views.append(item_view)

        container.height = self._container_height()

    def _append(self, msg):
        container = self.container
        adapter = self.adapter
        views = self._views
        cl = self.cut_lines

        if len(views) >= self.max_lines:
            container.clear_widgets(views[:cl])
            self._views = views[cl:]
            adapter.data = adapter.data[cl:]

        adapter.data.append(msg)
        item_view = adapter.get_view(adapter.get_count() - 1)
        item_view.texture_update()

        self._views.append(item_view)
        container.add_widget(item_view)

    def _container_height(self, *args):
        h = 0
        for v in self._views:
            h += v.height
        return h

    def append_message(self, msg):
        msg = preprocess(msg, (replace_emotes,
                               remove_formatting))
        msg = links_to_markup(escape_markup(msg))
        self._append(msg)
        self.container.height = self._container_height()
        self.children[0].scroll_y = 0

    def msg_converter(self, index, msg):
        b = (index % 2) * 0.04
        return {'text': msg,
                'width': self.width,
                'background_color': (0 + b, 0.17 + b, 0.21 + b, 1)}