Skip to content

Commit 211ea35

Browse files
committed
add custom avatars
1 parent 20e05bc commit 211ea35

File tree

8 files changed

+197
-12
lines changed

8 files changed

+197
-12
lines changed

GraphView/avatars.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Gramps - a GTK+/GNOME based genealogy program
4+
#
5+
# Copyright (C) 2020- Ivan Komaritsyn
6+
#
7+
# This program is free software; you can redistribute it and/or modify
8+
# it under the terms of the GNU General Public License as published by
9+
# the Free Software Foundation; either version 2 of the License, or
10+
# (at your option) any later version.
11+
#
12+
# This program is distributed in the hope that it will be useful,
13+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
# GNU General Public License for more details.
16+
#
17+
# You should have received a copy of the GNU General Public License
18+
# along with this program; if not, write to the Free Software
19+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20+
21+
#-------------------------------------------------------------------------
22+
#
23+
# Python modules
24+
#
25+
#-------------------------------------------------------------------------
26+
import os
27+
28+
#-------------------------------------------------------------------------
29+
#
30+
# Gramps Modules
31+
#
32+
#-------------------------------------------------------------------------
33+
from gramps.gen.lib import Person
34+
35+
from gramps.gen.const import GRAMPS_LOCALE as glocale
36+
try:
37+
_trans = glocale.get_addon_translator(__file__)
38+
except ValueError:
39+
_trans = glocale.translation
40+
_ = _trans.gettext
41+
42+
43+
class Avatars():
44+
"""
45+
Avatar support for GraphView.
46+
"""
47+
def __init__(self, config):
48+
"""
49+
config param - gramps.gen.config.
50+
"""
51+
self.config = config
52+
53+
# set avatars path '<...<GraphView_addon_path>/avatars>'
54+
self.path, _filename = os.path.split(__file__)
55+
self.path = os.path.join(self.path, 'avatars')
56+
57+
# define styles dictionary
58+
# dic item: (id: name, directory)
59+
self.styles = {0: (_('Custom'), None),
60+
1: (_('Dark (default)'), 'dark'),
61+
2: (_('Light'), 'light'),
62+
3: (_('Cartoon'), 'cartoon'),
63+
}
64+
65+
self.style = 1
66+
self.custom = False
67+
self.update_current_style()
68+
69+
def update_current_style(self):
70+
"""
71+
Update and check current style.
72+
"""
73+
self.style = self.config.get('interface.graphview-avatars-style')
74+
if self.styles.get(self.style) is None:
75+
self.style = 1
76+
77+
# set custom style mark
78+
self.custom = self.style == 0
79+
80+
def get_avatar(self, gender):
81+
"""
82+
Return person gender avatar or None.
83+
"""
84+
if self.custom:
85+
avatar = ''
86+
if gender == Person.MALE:
87+
avatar = self.config.get('interface.graphview-avatars-male')
88+
elif gender == Person.FEMALE:
89+
avatar = self.config.get('interface.graphview-avatars-female')
90+
if avatar:
91+
return avatar
92+
else:
93+
return None
94+
95+
style = self.styles.get(self.style)[1] # get style directory
96+
97+
if gender == Person.MALE:
98+
return os.path.join(self.path, style, 'person_male.png')
99+
if gender == Person.FEMALE:
100+
return os.path.join(self.path, style, 'person_female.png')
101+
102+
def get_styles_list(self):
103+
"""
104+
List of styles.
105+
List item: (id, name)
106+
"""
107+
styles_list = []
108+
for key, item in self.styles.items():
109+
styles_list.append((key, item[0]))
110+
return styles_list
111+
File renamed without changes.
File renamed without changes.
5.59 KB
Loading
6.64 KB
Loading
12.2 KB
Loading
14.4 KB
Loading

GraphView/graphview.py

Lines changed: 86 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,13 @@
121121

122122
#-------------------------------------------------------------------------
123123
#
124-
# Search widget module
124+
# GraphView modules
125125
#
126126
#-------------------------------------------------------------------------
127127
import sys
128128
sys.path.append(os.path.abspath(os.path.dirname(__file__)))
129129
from search_widget import SearchWidget, Popover, ListBoxRow, get_person_tooltip
130+
from avatars import Avatars
130131

131132

132133
#-------------------------------------------------------------------------
@@ -143,6 +144,9 @@ class GraphView(NavigationView):
143144
CONFIGSETTINGS = (
144145
('interface.graphview-show-images', True),
145146
('interface.graphview-show-avatars', True),
147+
('interface.graphview-avatars-style', 1),
148+
('interface.graphview-avatars-male', ''), # custom avatar
149+
('interface.graphview-avatars-female', ''), # custom avatar
146150
('interface.graphview-show-full-dates', False),
147151
('interface.graphview-show-places', False),
148152
('interface.graphview-place-format', 0),
@@ -191,6 +195,8 @@ def __init__(self, pdata, dbstate, uistate, nav_group=0):
191195

192196
# for disable animation options in config dialog
193197
self.ani_widgets = []
198+
# for disable custom avatar options in config dialog
199+
self.avatar_widgets = []
194200

195201
self.additional_uis.append(self.additional_ui)
196202
self.define_print_actions()
@@ -397,6 +403,38 @@ def cb_update_show_avatars(self, _client, _cnxn_id, entry, _data):
397403
self.show_avatars = entry == 'True'
398404
self.graph_widget.populate(self.get_active())
399405

406+
def cb_update_avatars_style(self, _client, _cnxn_id, entry, _data):
407+
"""
408+
Called when the configuration menu changes the avatars setting.
409+
"""
410+
for widget in self.avatar_widgets:
411+
widget.set_visible(entry == '0')
412+
self.graph_widget.populate(self.get_active())
413+
414+
def cb_on_combo_show(self, combobox):
415+
"""
416+
Called when the configuration menu show combobox widget for avatars.
417+
Used to hide custom avatars settings.
418+
"""
419+
for widget in self.avatar_widgets:
420+
widget.set_visible(combobox.get_active() == 0)
421+
422+
def cb_male_avatar_set(self, file_chooser_button):
423+
"""
424+
Called when the configuration menu changes the male avatar.
425+
"""
426+
self._config.set('interface.graphview-avatars-male',
427+
file_chooser_button.get_filename())
428+
self.graph_widget.populate(self.get_active())
429+
430+
def cb_female_avatar_set(self, file_chooser_button):
431+
"""
432+
Called when the configuration menu changes the female avatar.
433+
"""
434+
self._config.set('interface.graphview-avatars-female',
435+
file_chooser_button.get_filename())
436+
self.graph_widget.populate(self.get_active())
437+
400438
def cb_update_show_full_dates(self, _client, _cnxn_id, entry, _data):
401439
"""
402440
Called when the configuration menu changes the date setting.
@@ -550,6 +588,8 @@ def config_connect(self):
550588
self.cb_update_show_images)
551589
self._config.connect('interface.graphview-show-avatars',
552590
self.cb_update_show_avatars)
591+
self._config.connect('interface.graphview-avatars-style',
592+
self.cb_update_avatars_style)
553593
self._config.connect('interface.graphview-show-full-dates',
554594
self.cb_update_show_full_dates)
555595
self._config.connect('interface.graphview-show-places',
@@ -678,6 +718,47 @@ def theme_config_panel(self, configdialog):
678718
font_btn.connect('font-set', self.config_change_font)
679719
font_btn.set_filter_func(self.font_filter_func)
680720

721+
# Avatars options
722+
# ===================================================================
723+
row += 1
724+
avatars = Avatars(self._config)
725+
combo = configdialog.add_combo(grid, _('Avatars style'), row,
726+
'interface.graphview-avatars-style',
727+
avatars.get_styles_list())
728+
combo.connect('show', self.cb_on_combo_show)
729+
730+
file_filter = Gtk.FileFilter()
731+
file_filter.set_name(_('PNG files'))
732+
file_filter.add_pattern("*.png")
733+
734+
self.avatar_widgets.clear()
735+
row += 1
736+
lbl = Gtk.Label(label=_('Male avatar:'), halign=Gtk.Align.END)
737+
FCB_male = Gtk.FileChooserButton.new(_('Choose male avatar'),
738+
Gtk.FileChooserAction.OPEN)
739+
FCB_male.add_filter(file_filter)
740+
FCB_male.set_filename(
741+
self._config.get('interface.graphview-avatars-male'))
742+
FCB_male.connect('file-set', self.cb_male_avatar_set)
743+
grid.attach(lbl, 1, row, 1, 1)
744+
grid.attach(FCB_male, 2, row, 1, 1)
745+
self.avatar_widgets.append(lbl)
746+
self.avatar_widgets.append(FCB_male)
747+
748+
row += 1
749+
lbl = Gtk.Label(label=_('Female avatar:'), halign=Gtk.Align.END)
750+
FCB_female = Gtk.FileChooserButton.new(_('Choose female avatar'),
751+
Gtk.FileChooserAction.OPEN)
752+
FCB_female.connect('file-set', self.cb_female_avatar_set)
753+
FCB_female.add_filter(file_filter)
754+
FCB_female.set_filename(
755+
self._config.get('interface.graphview-avatars-female'))
756+
grid.attach(lbl, 1, row, 1, 1)
757+
grid.attach(FCB_female, 2, row, 1, 1)
758+
self.avatar_widgets.append(lbl)
759+
self.avatar_widgets.append(FCB_female)
760+
# ===================================================================
761+
681762
return _('Themes'), grid
682763

683764
def animation_config_panel(self, configdialog):
@@ -2101,6 +2182,8 @@ def __init__(self, dbstate, view, bold_size=0, norm_size=0):
21012182
# font if we use genealogical symbols
21022183
self.sym_font = None
21032184

2185+
self.avatars = Avatars(self.view._config)
2186+
21042187
def __del__(self):
21052188
"""
21062189
Free stream file on destroy.
@@ -2144,6 +2227,7 @@ def init_dot(self):
21442227
ranksep = ranksep * 0.1
21452228
nodesep = self.view._config.get('interface.graphview-nodesep')
21462229
nodesep = nodesep * 0.1
2230+
self.avatars.update_current_style()
21472231
# get background color from gtk theme and convert it to hex
21482232
# else use white background
21492233
bg_color = self.context.lookup_color('theme_bg_color')
@@ -2757,16 +2841,6 @@ def get_person_themes(self, index=-1):
27572841
else:
27582842
return person_themes[0]
27592843

2760-
def get_avatar(self, gender):
2761-
"""
2762-
Return person gender avatar.
2763-
"""
2764-
path, _filename = os.path.split(__file__)
2765-
if gender == Person.MALE:
2766-
return os.path.join(path, 'person_male.png')
2767-
if gender == Person.FEMALE:
2768-
return os.path.join(path, 'person_female.png')
2769-
27702844
def get_person_label(self, person):
27712845
"""
27722846
Return person label string (with tags).
@@ -2790,7 +2864,7 @@ def get_person_label(self, person):
27902864
image = self.view.graph_widget.get_person_image(person,
27912865
kind='path')
27922866
if not image and self.show_avatars:
2793-
image = self.get_avatar(gender=person.gender)
2867+
image = self.avatars.get_avatar(gender=person.gender)
27942868

27952869
if image is not None:
27962870
image = '<IMG SRC="%s"/>' % image

0 commit comments

Comments
 (0)