Ticket #3358: smooth_scrolling_patch_5.diff
| File smooth_scrolling_patch_5.diff, 7.0 kB (added by Geobert, 15 months ago) |
|---|
-
src/conversation_textview.py
10 10 ## 11 11 ## This program is distributed in the hope that it will be useful, 12 12 ## but WITHOUT ANY WARRANTY; without even the implied warranty of 13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 ## GNU General Public License for more details. 15 15 ## 16 16 17 17 import random 18 18 from tempfile import gettempdir 19 19 from subprocess import Popen 20 from threading import Timer # for smooth scrolling 20 21 21 22 import gtk 22 23 import pango … … 44 45 path_to_file = os.path.join(gajim.DATA_DIR, 'pixmaps', 'muc_separator.png') 45 46 FOCUS_OUT_LINE_PIXBUF = gtk.gdk.pixbuf_new_from_file(path_to_file) 46 47 48 # smooth scroll constants 49 MAX_SCROLL_TIME = 0.4 # seconds 50 SCROLL_DELAY = 33 # milliseconds 51 47 52 def __init__(self, account, used_in_history_window = False): 48 53 '''if used_in_history_window is True, then we do not show 49 54 Clear menuitem in context menu''' … … 154 159 self.line_tooltip = tooltips.BaseTooltip() 155 160 # use it for hr too 156 161 self.tv.focus_out_line_pixbuf = ConversationTextview.FOCUS_OUT_LINE_PIXBUF 162 self.smooth_id = None 157 163 158 164 def del_handlers(self): 159 165 for i in self.handlers.keys(): … … 181 187 return True 182 188 return False 183 189 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 184 225 def scroll_to_end(self): 185 226 parent = self.tv.get_parent() 186 227 buffer = self.tv.get_buffer() … … 192 233 adjustment.set_value(0) 193 234 return False # when called in an idle_add, just do it once 194 235 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')): 196 239 ''' scrolls to the end of textview if end is not visible ''' 197 240 buffer = self.tv.get_buffer() 198 241 end_iter = buffer.get_end_iter() … … 200 243 visible_rect = self.tv.get_visible_rect() 201 244 # scroll only if expected end is not visible 202 245 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) 204 250 205 251 def scroll_to_end_iter(self): 206 252 buffer = self.tv.get_buffer() … … 407 453 item.set_property('sensitive', False) 408 454 else: 409 455 item = gtk.MenuItem(_('Web _Search for it')) 410 link = search_link % self.selected_phrase456 link = search_link % self.selected_phrase 411 457 id = item.connect('activate', self.visit_url_from_menuitem, link) 412 458 self.handlers[id] = item 413 459 submenu.append(item) … … 632 678 cwd=gettempdir()) 633 679 exitcode = p.wait() 634 680 635 if exitcode == 0: 681 if exitcode == 0: 636 682 p = Popen(['dvips', '-E', '-o', tmpfile + '.ps', tmpfile + '.dvi'], 637 683 cwd=gettempdir()) 638 684 exitcode = p.wait() … … 857 903 if at_the_end or kind == 'outgoing': 858 904 # we are at the end or we are sending something 859 905 # 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) 861 910 862 911 buffer.end_user_action() 863 912 -
src/common/config.py
218 218 'hide_groupchat_occupants_list': [opt_bool, False, _('Hides the group chat occupants list in group chat window.')], 219 219 '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.')], 220 220 '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')], 221 222 '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 ], 222 223 'ctrl_tab_go_to_next_composing': [opt_bool, True, _('Ctrl-Tab go to next composing tab when none is unread.')], 223 224 '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
253 253 # For JEP-0172 254 254 self.user_nick = None 255 255 256 self.smooth = True 257 256 258 def on_msg_textview_populate_popup(self, textview, menu): 257 259 '''we override the default context menu and we prepend an option to switch languages''' 258 260 def _on_select_dictionary(widget, lang): … … 812 814 self.msg_scrolledwindow.set_property('vscrollbar-policy', 813 815 gtk.POLICY_NEVER) 814 816 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 818 821 # enable scrollbar automatic policy for horizontal scrollbar 819 822 # if message we have in message_textview is too big 820 823 if requisition.width > message_width: … … 895 898 if self.sent_history_pos == 0: 896 899 return 897 900 self.sent_history_pos = self.sent_history_pos - 1 901 self.smooth = False 898 902 conv_buf.set_text(self.sent_history[self.sent_history_pos]) 899 903 elif direction == 'down': 900 904 if self.sent_history_pos >= size - 1: … … 904 908 return 905 909 906 910 self.sent_history_pos = self.sent_history_pos + 1 911 self.smooth = False 907 912 conv_buf.set_text(self.sent_history[self.sent_history_pos]) 908 913 909 914 def lighten_color(self, color):
