diff options
author | Philipp Hörist <philipp@hoerist.com> | 2022-10-09 22:50:11 +0300 |
---|---|---|
committer | Philipp Hörist <philipp@hoerist.com> | 2022-10-09 22:50:11 +0300 |
commit | fdc424f5a1d46111a7e914f3350f80a5bdb3ecda (patch) | |
tree | 7b3c9c5fb4a729d8b8cf1cab16455f58c069b9c7 | |
parent | 48f4884936cb580e110804b79ee1b69b6fb5f0be (diff) |
refactor: Add AvatarBox
Move code related to the avatar image into its own widget
-rw-r--r-- | gajim/gtk/conversation/rows/message.py | 68 | ||||
-rw-r--r-- | gajim/gtk/conversation/rows/widgets.py | 78 |
2 files changed, 86 insertions, 60 deletions
diff --git a/gajim/gtk/conversation/rows/message.py b/gajim/gtk/conversation/rows/message.py index 122dc63cf..d2dd56ecf 100644 --- a/gajim/gtk/conversation/rows/message.py +++ b/gajim/gtk/conversation/rows/message.py @@ -48,6 +48,7 @@ from gajim.common.modules.contacts import GroupchatContact from gajim.common.types import ChatContactT from .base import BaseRow +from .widgets import AvatarBox from .widgets import DateTimeLabel from .widgets import NicknameLabel from .widgets import MessageIcons @@ -55,11 +56,9 @@ from .widgets import MoreMenuButton from ..message_widget import MessageWidget from ...dialogs import InputDialog from ...dialogs import DialogButton -from ...menus import get_groupchat_participant_menu from ...preview import PreviewWidget -from ...util import GajimPopover from ...util import format_fingerprint -from ...util import get_cursor + MERGE_TIMEFRAME = timedelta(seconds=120) @@ -179,19 +178,9 @@ class MessageRow(BaseRow): self.set_receipt() self._meta_box.pack_start(self._message_icons, False, True, 0) - avatar = self._get_avatar(kind, name) - self._avatar_image = Gtk.Image.new_from_surface(avatar) - if self._is_groupchat: - avatar_placeholder = Gtk.EventBox() - avatar_placeholder.connect( - 'button-press-event', self._on_avatar_clicked, name) - avatar_placeholder.connect('realize', self._on_realize) - else: - avatar_placeholder = Gtk.Box() - avatar_placeholder.set_size_request(AvatarSize.ROSTER, -1) - avatar_placeholder.set_valign(Gtk.Align.START) - avatar_placeholder.add(self._avatar_image) + avatar = self._get_avatar(kind, name) + self._avatar_box = AvatarBox(self._contact, name, avatar) self._bottom_box = Gtk.Box(spacing=6) self._bottom_box.add(self._message_widget) @@ -203,7 +192,7 @@ class MessageRow(BaseRow): more_menu_button = MoreMenuButton(self, self._contact, name) self._bottom_box.pack_end(more_menu_button, False, True, 0) - self.grid.attach(avatar_placeholder, 0, 0, 1, 2) + self.grid.attach(self._avatar_box, 0, 0, 1, 2) self.grid.attach(self._meta_box, 1, 0, 1, 1) self.grid.attach(self._bottom_box, 1, 1, 1, 1) @@ -266,45 +255,6 @@ class MessageRow(BaseRow): assert not isinstance(avatar, GdkPixbuf.Pixbuf) return avatar - def _on_avatar_clicked(self, - _widget: Gtk.Widget, - event: Gdk.EventButton, - name: str - ) -> int: - if event.type == Gdk.EventType.BUTTON_PRESS: - if event.button == 1: - app.window.activate_action('mention', GLib.Variant('s', name)) - elif event.button == 3: - self._show_participant_menu(name, event) - - return Gdk.EVENT_STOP - - def _show_participant_menu(self, nick: str, event: Gdk.EventButton) -> None: - assert isinstance(self._contact, GroupchatContact) - if not self._contact.is_joined: - return - - self_contact = self._contact.get_self() - assert self_contact is not None - - if nick == self_contact.name: - # Don’t show menu for us - return - - contact = self._contact.get_resource(nick) - menu = get_groupchat_participant_menu(self._contact.account, - self_contact, - contact) - - popover = GajimPopover(menu, relative_to=self, event=event) - popover.popup() - - @staticmethod - def _on_realize(event_box: Gtk.EventBox) -> None: - window = event_box.get_window() - if window is not None: - window.set_cursor(get_cursor('pointer')) - def is_same_sender(self, message: MessageRow) -> bool: return message.name == self.name @@ -485,19 +435,17 @@ class MessageRow(BaseRow): def update_avatar(self) -> None: avatar = self._get_avatar(self.kind, self.name) - self._avatar_image.set_from_surface(avatar) + self._avatar_box.set_from_surface(avatar) def set_merged(self, merged: bool) -> None: self._merged = merged if merged: self.get_style_context().add_class('merged') - self._avatar_image.set_no_show_all(True) - self._avatar_image.hide() self._meta_box.set_no_show_all(True) self._meta_box.hide() else: self.get_style_context().remove_class('merged') - self._avatar_image.set_no_show_all(False) - self._avatar_image.show() self._meta_box.set_no_show_all(False) self._meta_box.show() + + self._avatar_box.set_merged(merged) diff --git a/gajim/gtk/conversation/rows/widgets.py b/gajim/gtk/conversation/rows/widgets.py index aaed1ea94..668370d5f 100644 --- a/gajim/gtk/conversation/rows/widgets.py +++ b/gajim/gtk/conversation/rows/widgets.py @@ -15,14 +15,18 @@ from __future__ import annotations from typing import TYPE_CHECKING +from typing import Optional from datetime import datetime from gi.repository import Gtk +from gi.repository import Gdk from gi.repository import Pango from gi.repository import GLib +import cairo from gajim.common import app +from gajim.common.const import AvatarSize from gajim.common.i18n import Q_ from gajim.common.helpers import is_retraction_allowed from gajim.common.modules.contacts import GroupchatContact @@ -31,7 +35,10 @@ from gajim.common.types import ChatContactT if TYPE_CHECKING: from .message import MessageRow +from ...menus import get_groupchat_participant_menu from ...util import wrap_with_event_box +from ...util import get_cursor +from ...util import GajimPopover class SimpleLabel(Gtk.Label): @@ -241,3 +248,74 @@ class MessageIcons(Gtk.Box): def set_error_tooltip(self, text: str) -> None: self._error_image.set_tooltip_markup(text) + + +class AvatarBox(Gtk.EventBox): + def __init__(self, + contact: ChatContactT, + name: str, + avatar: Optional[cairo.ImageSurface], + ) -> None: + + Gtk.EventBox.__init__(self) + + self.set_size_request(AvatarSize.ROSTER, -1) + self.set_valign(Gtk.Align.START) + + self._contact = contact + + self._image = Gtk.Image.new_from_surface(avatar) + self.add(self._image) + + if self._contact.is_groupchat: + self.connect('realize', self._on_realize) + + self.connect('button-press-event', + self._on_avatar_clicked, name) + + def set_from_surface(self, surface: Optional[cairo.ImageSurface]) -> None: + self._image.set_from_surface(surface) + + def set_merged(self, merged: bool) -> None: + self._image.set_no_show_all(merged) + self._image.set_visible(not merged) + + @staticmethod + def _on_realize(event_box: Gtk.EventBox) -> None: + window = event_box.get_window() + if window is not None: + window.set_cursor(get_cursor('pointer')) + + def _on_avatar_clicked(self, + _widget: Gtk.Widget, + event: Gdk.EventButton, + name: str + ) -> int: + + if event.type == Gdk.EventType.BUTTON_PRESS: + if event.button == 1: + app.window.activate_action('mention', GLib.Variant('s', name)) + elif event.button == 3: + self._show_participant_menu(name, event) + + return Gdk.EVENT_STOP + + def _show_participant_menu(self, nick: str, event: Gdk.EventButton) -> None: + assert isinstance(self._contact, GroupchatContact) + if not self._contact.is_joined: + return + + self_contact = self._contact.get_self() + assert self_contact is not None + + if nick == self_contact.name: + # Don’t show menu for us + return + + contact = self._contact.get_resource(nick) + menu = get_groupchat_participant_menu(self._contact.account, + self_contact, + contact) + + popover = GajimPopover(menu, relative_to=self, event=event) + popover.popup() |