Philipp Hörist pushed to branch mainwindow at gajim / gajim
Commits: c4b42214 by lovetox at 2021-04-04T17:16:05+02:00 Add ScrolledView
- - - - -
8 changed files:
- gajim/chat_control.py - gajim/chat_control_base.py - gajim/data/gui/chat_control.ui - gajim/data/gui/groupchat_control.ui - gajim/gtk/conversation/rows/date.py - gajim/gtk/conversation/rows/scroll_hint.py - + gajim/gtk/conversation/scrolled.py - gajim/gtk/conversation/view.py
Changes:
===================================== gajim/chat_control.py ===================================== @@ -180,8 +180,8 @@ def __init__(self, parent_win, jid, acct, session, resource=None): content_area.add(self.info_bar_label) self.info_bar.set_no_show_all(True)
- self.xml.vbox2.pack_start(self.info_bar, False, True, 5) - self.xml.vbox2.reorder_child(self.info_bar, 1) + self.xml.textview_box.pack_start(self.info_bar, False, True, 5) + self.xml.textview_box.reorder_child(self.info_bar, 1)
# List of waiting infobar messages self.info_bar_queue = []
===================================== gajim/chat_control_base.py ===================================== @@ -49,6 +49,7 @@ from gajim import gtkgui_helpers
from gajim.gui.conversation.view import ConversationView +from gajim.gui.conversation.scrolled import ScrolledView from gajim.gui.dialogs import DialogButton from gajim.gui.dialogs import ConfirmationDialog from gajim.gui.dialogs import PastePreviewDialog @@ -166,38 +167,18 @@ def __init__(self, parent_win, widget_name, jid, acct,
# Create ConversationView and connect signals self.conversation_view = ConversationView(self.account, self.contact) - id_ = self.conversation_view.connect('quote', self.on_quote) - self.handlers[id_] = self.conversation_view - id_ = self.conversation_view.connect( - 'load-history', self._on_load_history) - self.handlers[id_] = self.conversation_view + self.conversation_view.connect('quote', self.on_quote) + id_ = self.conversation_view.connect( 'key-press-event', self._on_conversation_view_key_press) self.handlers[id_] = self.conversation_view
- # This is a workaround: as soon as a line break occurs in Gtk.TextView - # with word-char wrapping enabled, a hyphen character is automatically - # inserted before the line break. This triggers the hscrollbar to show, - # see: https://gitlab.gnome.org/GNOME/gtk/-/issues/2384 - # Using set_hscroll_policy(Gtk.Scrollable.Policy.NEVER) would cause bad - # performance during resize, and prevent the window from being shrunk - # horizontally under certain conditions (applies to GroupchatControl) - hscrollbar = self.xml.conversation_scrolledwindow.get_hscrollbar() - hscrollbar.hide() - - self.xml.conversation_scrolledwindow.add(self.conversation_view) - self._scrolled_old_upper = None - self._scrolled_old_value = None - - self._fetch_start_upper = None - self._current_upper = 0 - self._autoscroll = True - self._no_more_messages = False - - vadjustment = self.xml.conversation_scrolledwindow.get_vadjustment() - - vadjustment.connect('notify::upper', self._on_adj_upper_changed) - vadjustment.connect('notify::value', self._on_adj_value_changed) + self._scrolled_view = ScrolledView() + self._scrolled_view.add(self.conversation_view) + self.xml.textview_box.add(self._scrolled_view) + self.xml.textview_box.reorder_child(self._scrolled_view, 2) + self._scrolled_view.connect('request-history', + self.fetch_n_lines_history, 30)
self.msg_textview = MessageInputTextView() self.msg_textview.connect('paste-clipboard', @@ -710,7 +691,11 @@ def shutdown(self): self.handlers[i].disconnect(i) self.handlers.clear()
+ self.conversation_view.destroy() + self._scrolled_view.destroy() + del self.conversation_view + del self._scrolled_view del self.msg_textview del self.msg_scrolledwindow
@@ -1407,10 +1392,7 @@ def set_control_active(self, state): def scroll_to_end(self, force=False): self.conversation_view.scroll_to_end(force)
- def _on_load_history(self, _button, lines): - self.fetch_n_lines_history(lines) - - def fetch_n_lines_history(self, n_lines): + def fetch_n_lines_history(self, _scrolled, n_lines): row = self.conversation_view.get_first_message_row() if row is None: timestamp = time.time() @@ -1431,8 +1413,7 @@ def fetch_n_lines_history(self, n_lines): n_lines)
if not messages: - self._no_more_messages = True - print('SET NO MORE') + self._scrolled_view.set_history_complete() return
for msg in messages: @@ -1471,46 +1452,6 @@ def has_focus(self): return True return False
- def _on_adj_upper_changed(self, adj, *args): - upper = adj.get_upper() - diff = upper - self._current_upper - - if diff != 0: - self._current_upper = upper - if self._autoscroll: - adj.set_value(adj.get_upper() - adj.get_page_size()) - else: - # Workaround: https://gitlab.gnome.org/GNOME/gtk/merge_requests/395 - self.xml.conversation_scrolledwindow.set_kinetic_scrolling(True) - adj.set_value(adj.get_value() + diff) - - if upper == adj.get_page_size(): - # There is no scrollbar, load history until there is - self.fetch_n_lines_history(30) - - def _on_adj_value_changed(self, adj, *args): - bottom = adj.get_upper() - adj.get_page_size() - if (bottom - adj.get_value()) < 1: - self._autoscroll = True - else: - self._autoscroll = False - - if self._no_more_messages: - self._fetch_start_upper = None - return - - if self._fetch_start_upper == adj.get_upper(): - return - - self._fetch_start_upper = None - - # Load messages when we are near the top - if adj.get_value() < adj.get_page_size() * 2: - self._fetch_start_upper = adj.get_upper() - # Workaround: https://gitlab.gnome.org/GNOME/gtk/merge_requests/395 - self.xml.conversation_scrolledwindow.set_kinetic_scrolling(False) - self.fetch_n_lines_history(30) - def scroll_messages(self, direction, msg_buf, msg_type): if msg_type == 'sent': history = self.sent_history
===================================== gajim/data/gui/chat_control.ui ===================================== @@ -403,7 +403,7 @@ <property name="visible">True</property> <property name="can_focus">True</property> <child> - <object class="GtkBox" id="vbox2"> + <object class="GtkBox" id="textview_box"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="orientation">vertical</property> @@ -618,25 +618,7 @@ </packing> </child> <child> - <object class="GtkScrolledWindow" id="conversation_scrolledwindow"> - <property name="height_request">60</property> - <property name="can_focus">True</property> - <property name="shadow_type">in</property> - <property name="overlay_scrolling">False</property> - <child> - <placeholder/> - </child> - <style> - <class name="scrolled-no-border"/> - <class name="no-scroll-indicator"/> - <class name="scrollbar-style"/> - </style> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">2</property> - </packing> + <placeholder/> </child> <child> <object class="GtkSeparator">
===================================== gajim/data/gui/groupchat_control.ui ===================================== @@ -143,7 +143,7 @@ <property name="margin_bottom">7</property> <property name="spacing">3</property> <child> - <object class="GtkBox" id="gc_textviews_vbox"> + <object class="GtkBox" id="textview_box"> <property name="width_request">0</property> <property name="visible">True</property> <property name="can_focus">False</property> @@ -256,27 +256,7 @@ </packing> </child> <child> - <object class="GtkScrolledWindow" id="conversation_scrolledwindow"> - <property name="width_request">200</property> - <property name="height_request">60</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="shadow_type">in</property> - <property name="overlay_scrolling">False</property> - <child> - <placeholder/> - </child> - <style> - <class name="scrolled-no-border"/> - <class name="no-scroll-indicator"/> - <class name="scrollbar-style"/> - </style> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">2</property> - </packing> + <placeholder/> </child> <child> <object class="GtkSeparator">
===================================== gajim/gtk/conversation/rows/date.py ===================================== @@ -21,6 +21,10 @@ class DateRow(BaseRow): def __init__(self, account, date_string, timestamp): BaseRow.__init__(self, account) + + self.set_selectable(False) + self.set_activatable(False) + self.type = 'date' self.timestamp = timestamp self.get_style_context().add_class('conversation-date-row')
===================================== gajim/gtk/conversation/rows/scroll_hint.py ===================================== @@ -24,6 +24,9 @@ class ScrollHintRow(BaseRow): def __init__(self, account, history_mode=False): BaseRow.__init__(self, account) + self.set_selectable(False) + self.set_activatable(False) + self.type = 'system' self.timestamp = datetime.fromtimestamp(0)
@@ -42,11 +45,5 @@ def __init__(self, account, history_mode=False): self.label.set_text(_('Scroll up to load more chat history…')) self.grid.attach(self.label, 0, 1, 1, 1)
- self._button = Gtk.Button.new_from_icon_name( - 'go-up-symbolic', Gtk.IconSize.BUTTON) - self._button.set_tooltip_text(_('Load more messages')) - self._button.connect('clicked', self._on_load_history) - self.grid.attach(self._button, 0, 0, 1, 1) - - def _on_load_history(self, _button): - self.get_parent().emit('load-history', 30) + def set_history_complete(self): + self.label.set_text(_('There is no more history'))
===================================== gajim/gtk/conversation/scrolled.py ===================================== @@ -0,0 +1,109 @@ +# This file is part of Gajim. +# +# Gajim is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation; version 3 only. +# +# Gajim is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Gajim. If not, see http://www.gnu.org/licenses/. + +from gi.repository import Gtk +from gi.repository import GObject + + +class ScrolledView(Gtk.ScrolledWindow): + + __gsignals__ = { + 'request-history': ( + GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, + None, + () + ) + } + + def __init__(self, *args, **kwargs): + Gtk.ScrolledWindow.__init__(self, *args, **kwargs) + + self.set_overlay_scrolling(False) + self.get_style_context().add_class('scrolled-no-border') + self.get_style_context().add_class('no-scroll-indicator') + self.get_style_context().add_class('scrollbar-style') + self.set_shadow_type(Gtk.ShadowType.IN) + self.set_vexpand(True) + + self.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) + + # This is a workaround: as soon as a line break occurs in Gtk.TextView + # with word-char wrapping enabled, a hyphen character is automatically + # inserted before the line break. This triggers the hscrollbar to show, + # see: https://gitlab.gnome.org/GNOME/gtk/-/issues/2384 + # Using set_hscroll_policy(Gtk.Scrollable.Policy.NEVER) would cause bad + # performance during resize, and prevent the window from being shrunk + # horizontally under certain conditions (applies to GroupchatControl) + self.get_hscrollbar().hide() + + self._current_upper = 0 + self._autoscroll = True + self._request_history_at_upper = None + self._complete = False + + vadjustment = self.get_vadjustment() + vadjustment.connect('notify::upper', self._on_adj_upper_changed) + vadjustment.connect('notify::value', self._on_adj_value_changed) + + @property + def autoscroll(self): + return self._autoscroll + + def set_history_complete(self): + self._complete = True + self.get_child().get_child().set_history_complete() + + def _on_adj_upper_changed(self, adj, *args): + upper = adj.get_upper() + diff = upper - self._current_upper + + if diff != 0: + self._current_upper = upper + if self._autoscroll: + adj.set_value(adj.get_upper() - adj.get_page_size()) + else: + # Workaround + # https://gitlab.gnome.org/GNOME/gtk/merge_requests/395 + self.set_kinetic_scrolling(True) + adj.set_value(adj.get_value() + diff) + + if upper == adj.get_page_size(): + # There is no scrollbar, request history until there is + self.emit('request-history') + + def _on_adj_value_changed(self, adj, *args): + bottom = adj.get_upper() - adj.get_page_size() + if (bottom - adj.get_value()) < 1: + self._autoscroll = True + else: + self._autoscroll = False + + if self._complete: + self._request_history_at_upper = None + return + + if self._request_history_at_upper == adj.get_upper(): + # Abort here if we already did a history request and the upper + # did not change. This can happen if we scroll very fast and the + # value changes while the request has not been fullfilled. + return + + self._request_history_at_upper = None + + # Load messages when we are near the top + if adj.get_value() < adj.get_page_size() * 2: + self._request_history_at_upper = adj.get_upper() + # Workaround: https://gitlab.gnome.org/GNOME/gtk/merge_requests/395 + self.set_kinetic_scrolling(False) + self.emit('request-history')
===================================== gajim/gtk/conversation/view.py ===================================== @@ -48,11 +48,6 @@ class ConversationView(Gtk.ListBox): None, (str, ) ), - 'load-history': ( - GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, - None, - (str, ) - ) }
def __init__(self, account, contact, history_mode=False): @@ -95,7 +90,8 @@ def __init__(self, account, contact, history_mode=False): self._last_incoming_timestamp = datetime.fromtimestamp(0)
# Insert the very first row, containing the scroll hint and load button - self.add(ScrollHintRow(self._account, history_mode=self._history_mode)) + self._scroll_hint_row = ScrollHintRow(self._account) + self.add(self._scroll_hint_row) self._timestamps_inserted.append(datetime.fromtimestamp(0))
def clear(self): @@ -111,6 +107,9 @@ def get_first_message_row(self): return row return None
+ def set_history_complete(self): + self._scroll_hint_row.set_history_complete() + def _reset_conversation_view(self): self._first_date = None self._last_date = None
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/commit/c4b42214849d3aeca3b150c0b0a5458b0...