Ticket #3358: smooth_scrolling_patch_5.diff

File smooth_scrolling_patch_5.diff, 7.0 kB (added by Geobert, 23 months ago)

more bug fix

  • src/conversation_textview.py

     
    1010## 
    1111## This program is distributed in the hope that it will be useful, 
    1212## but WITHOUT ANY WARRANTY; without even the implied warranty of 
    13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     13## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    1414## GNU General Public License for more details. 
    1515## 
    1616 
    1717import random 
    1818from tempfile import gettempdir 
    1919from subprocess import Popen 
     20from threading import Timer # for smooth scrolling 
    2021 
    2122import gtk 
    2223import pango 
     
    4445        path_to_file = os.path.join(gajim.DATA_DIR, 'pixmaps', 'muc_separator.png') 
    4546        FOCUS_OUT_LINE_PIXBUF = gtk.gdk.pixbuf_new_from_file(path_to_file) 
    4647 
     48        # smooth scroll constants 
     49        MAX_SCROLL_TIME = 0.4 # seconds 
     50        SCROLL_DELAY = 33 # milliseconds 
     51 
    4752        def __init__(self, account, used_in_history_window = False): 
    4853                '''if used_in_history_window is True, then we do not show 
    4954                Clear menuitem in context menu''' 
     
    154159                self.line_tooltip = tooltips.BaseTooltip() 
    155160                # use it for hr too 
    156161                self.tv.focus_out_line_pixbuf = ConversationTextview.FOCUS_OUT_LINE_PIXBUF 
     162                self.smooth_id = None 
    157163 
    158164        def del_handlers(self): 
    159165                for i in self.handlers.keys(): 
     
    181187                        return True 
    182188                return False 
    183189 
     190        # Smooth scrolling inspired by Pidgin code 
     191        def smooth_scroll(self): 
     192                parent = self.tv.get_parent() 
     193                if not parent: 
     194                        return False 
     195                vadj = parent.get_vadjustment() 
     196                max_val = vadj.upper - vadj.page_size + 1 
     197                cur_val = vadj.get_value() 
     198                # scroll by 1/3rd of remaining distance 
     199                onethird = cur_val + ((max_val - cur_val) / 3.0) 
     200                vadj.set_value(onethird) 
     201                if max_val - onethird < 0.01: 
     202                        self.smooth_id = None 
     203                        self.smooth_scroll_timer.cancel() 
     204                        return False 
     205                return True                 
     206 
     207        def smooth_scroll_timeout(self): 
     208                gobject.source_remove(self.smooth_id) 
     209                self.smooth_id = None 
     210                parent = self.tv.get_parent() 
     211                if parent: 
     212                        vadj = parent.get_vadjustment() 
     213                        vadj.set_value(vadj.upper - vadj.page_size + 1) 
     214 
     215        def smooth_scroll_to_end(self): 
     216                if None != self.smooth_id: # already scrolling 
     217                        return False 
     218                self.smooth_id = gobject.timeout_add(self.SCROLL_DELAY, 
     219                                                                                         self.smooth_scroll) 
     220                self.smooth_scroll_timer = Timer(self.MAX_SCROLL_TIME, 
     221                                                                                 self.smooth_scroll_timeout) 
     222                self.smooth_scroll_timer.start() 
     223                return False 
     224 
    184225        def scroll_to_end(self): 
    185226                parent = self.tv.get_parent() 
    186227                buffer = self.tv.get_buffer() 
     
    192233                adjustment.set_value(0) 
    193234                return False # when called in an idle_add, just do it once 
    194235 
    195         def bring_scroll_to_end(self, diff_y = 0): 
     236        def bring_scroll_to_end(self, diff_y = 0,\ 
     237                                                        use_smooth =\ 
     238                                                        gajim.config.get('use_smooth_scrolling')): 
    196239                ''' scrolls to the end of textview if end is not visible ''' 
    197240                buffer = self.tv.get_buffer() 
    198241                end_iter = buffer.get_end_iter() 
     
    200243                visible_rect = self.tv.get_visible_rect() 
    201244                # scroll only if expected end is not visible 
    202245                if end_rect.y >= (visible_rect.y + visible_rect.height + diff_y): 
    203                         gobject.idle_add(self.scroll_to_end_iter) 
     246                        if use_smooth: 
     247                                gobject.idle_add(self.smooth_scroll_to_end) 
     248                        else: 
     249                                gobject.idle_add(self.scroll_to_end_iter) 
    204250 
    205251        def scroll_to_end_iter(self): 
    206252                buffer = self.tv.get_buffer() 
     
    407453                                item.set_property('sensitive', False) 
    408454                        else: 
    409455                                item = gtk.MenuItem(_('Web _Search for it')) 
    410                                 link =  search_link % self.selected_phrase 
     456                                link =  search_link % self.selected_phrase 
    411457                                id = item.connect('activate', self.visit_url_from_menuitem, link) 
    412458                                self.handlers[id] = item 
    413459                        submenu.append(item) 
     
    632678                                cwd=gettempdir()) 
    633679                        exitcode = p.wait() 
    634680 
    635                 if exitcode == 0:            
     681                if exitcode == 0:                
    636682                        p = Popen(['dvips', '-E', '-o', tmpfile + '.ps', tmpfile + '.dvi'], 
    637683                                cwd=gettempdir()) 
    638684                        exitcode = p.wait() 
     
    857903                if at_the_end or kind == 'outgoing': 
    858904                        # we are at the end or we are sending something 
    859905                        # scroll to the end (via idle in case the scrollbar has appeared) 
    860                         gobject.idle_add(self.scroll_to_end) 
     906                        if gajim.config.get('use_smooth_scrolling'): 
     907                                gobject.idle_add(self.smooth_scroll_to_end) 
     908                        else: 
     909                                gobject.idle_add(self.scroll_to_end) 
    861910 
    862911                buffer.end_user_action() 
    863912 
  • src/common/config.py

     
    218218                'hide_groupchat_occupants_list': [opt_bool, False, _('Hides the group chat occupants list in group chat window.')], 
    219219                'chat_merge_consecutive_nickname': [opt_bool, False, _('In a chat, show the nickname at the beginning of a line only when it\'s not the same person talking than in previous message.')], 
    220220                'chat_merge_consecutive_nickname_indent': [opt_str, '  ', _('Indentation when using merge consecutive nickname.')], 
     221        'use_smooth_scrolling': [opt_bool, True, _('Smooth scroll message in conversation window')], 
    221222                'gc_nicknames_colors': [ opt_str, '#a34526:#c000ff:#0012ff:#388a99:#045723:#7c7c7c:#ff8a00:#94452d:#244b5a:#32645a', _('List of colors that will be used to color nicknames in group chats.'), True ], 
    222223                'ctrl_tab_go_to_next_composing': [opt_bool, True, _('Ctrl-Tab go to next composing tab when none is unread.')], 
    223224                'confirm_metacontacts': [ opt_str, '', _('Should we show the confirm metacontacts creation dialog or not? Empty string means we never show the dialog.')], 
  • src/chat_control.py

     
    253253                # For JEP-0172 
    254254                self.user_nick = None 
    255255 
     256                self.smooth = True 
     257 
    256258        def on_msg_textview_populate_popup(self, textview, menu): 
    257259                '''we override the default context menu and we prepend an option to switch languages''' 
    258260                def _on_select_dictionary(widget, lang): 
     
    812814                                self.msg_scrolledwindow.set_property('vscrollbar-policy',  
    813815                                        gtk.POLICY_NEVER) 
    814816                                self.msg_scrolledwindow.set_property('height-request', -1) 
    815  
    816                 self.conv_textview.bring_scroll_to_end(diff_y - 18) 
    817                  
     817                        self.conv_textview.bring_scroll_to_end(diff_y - 18, False) 
     818                else: 
     819                        self.conv_textview.bring_scroll_to_end(diff_y - 18, self.smooth) 
     820                self.smooth = True # reinit the flag 
    818821                # enable scrollbar automatic policy for horizontal scrollbar 
    819822                # if message we have in message_textview is too big 
    820823                if requisition.width > message_width: 
     
    895898                        if self.sent_history_pos == 0: 
    896899                                return 
    897900                        self.sent_history_pos = self.sent_history_pos - 1 
     901                        self.smooth = False 
    898902                        conv_buf.set_text(self.sent_history[self.sent_history_pos]) 
    899903                elif direction == 'down': 
    900904                        if self.sent_history_pos >= size - 1: 
     
    904908                                return 
    905909 
    906910                        self.sent_history_pos = self.sent_history_pos + 1 
     911                        self.smooth = False 
    907912                        conv_buf.set_text(self.sent_history[self.sent_history_pos]) 
    908913 
    909914        def lighten_color(self, color):