Speed ups: cache names---don't re-lookup name; added outer edge to indicate parents; removed simple access
svn: r11714
This commit is contained in:
parent
2018064fe1
commit
d2b481b1a3
@ -58,10 +58,13 @@ if gtk.pygtk_version < (2,3,93):
|
|||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
from BasicUtils import name_displayer
|
from BasicUtils import name_displayer
|
||||||
from Simple import SimpleAccess
|
|
||||||
from gettext import gettext as _
|
from gettext import gettext as _
|
||||||
from DataViews import Gramplet, register
|
from DataViews import Gramplet, register
|
||||||
from gen.lib import Person
|
import gen.lib
|
||||||
|
|
||||||
|
def gender_code(is_male):
|
||||||
|
if is_male: return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
@ -127,7 +130,7 @@ class FanChartWidget(gtk.Widget):
|
|||||||
self.angle = {}
|
self.angle = {}
|
||||||
self.data = {}
|
self.data = {}
|
||||||
for i in range(self.generations):
|
for i in range(self.generations):
|
||||||
self.data[i] = [None for j in range(2 ** i)]
|
self.data[i] = [(None, None, None) for j in range(2 ** i)]
|
||||||
self.angle[i] = []
|
self.angle[i] = []
|
||||||
angle = 0
|
angle = 0
|
||||||
slice = 360.0 / (2 ** i)
|
slice = 360.0 / (2 ** i)
|
||||||
@ -205,14 +208,13 @@ class FanChartWidget(gtk.Widget):
|
|||||||
cr.rotate(self.rotate_value * math.pi/180)
|
cr.rotate(self.rotate_value * math.pi/180)
|
||||||
for generation in range(self.generations - 1, 0, -1):
|
for generation in range(self.generations - 1, 0, -1):
|
||||||
for p in range(len(self.data[generation])):
|
for p in range(len(self.data[generation])):
|
||||||
person = self.data[generation][p]
|
(text, person, parents) = self.data[generation][p]
|
||||||
if person:
|
if person:
|
||||||
start, stop, male, state = self.angle[generation][p]
|
start, stop, male, state = self.angle[generation][p]
|
||||||
name = name_displayer.display(person)
|
|
||||||
gender = person.get_gender()
|
|
||||||
if state in [self.NORMAL, self.EXPANDED]:
|
if state in [self.NORMAL, self.EXPANDED]:
|
||||||
self.draw_person(cr, gender, name, start, stop,
|
self.draw_person(cr, gender_code(male),
|
||||||
generation, state)
|
text, start, stop,
|
||||||
|
generation, state, parents)
|
||||||
cr.set_source_rgb(1, 1, 1) # white
|
cr.set_source_rgb(1, 1, 1) # white
|
||||||
cr.move_to(0,0)
|
cr.move_to(0,0)
|
||||||
cr.arc(0, 0, self.center, 0, 2 * math.pi)
|
cr.arc(0, 0, self.center, 0, 2 * math.pi)
|
||||||
@ -222,7 +224,7 @@ class FanChartWidget(gtk.Widget):
|
|||||||
cr.arc(0, 0, self.center, 0, 2 * math.pi)
|
cr.arc(0, 0, self.center, 0, 2 * math.pi)
|
||||||
cr.stroke()
|
cr.stroke()
|
||||||
# Draw center person:
|
# Draw center person:
|
||||||
person = self.data[0][0]
|
(text, person, parents) = self.data[0][0]
|
||||||
cr.restore()
|
cr.restore()
|
||||||
if person:
|
if person:
|
||||||
cr.save()
|
cr.save()
|
||||||
@ -234,7 +236,8 @@ class FanChartWidget(gtk.Widget):
|
|||||||
cr.update_layout(self.layout)
|
cr.update_layout(self.layout)
|
||||||
cr.show_layout(self.layout)
|
cr.show_layout(self.layout)
|
||||||
|
|
||||||
def draw_person(self, cr, gender, name, start, stop, generation, state):
|
def draw_person(self, cr, gender, name, start, stop, generation,
|
||||||
|
state, parents):
|
||||||
"""
|
"""
|
||||||
Display the piece of pie for a given person. start and stop
|
Display the piece of pie for a given person. start and stop
|
||||||
are in degrees.
|
are in degrees.
|
||||||
@ -243,12 +246,25 @@ class FanChartWidget(gtk.Widget):
|
|||||||
start_rad = start * math.pi/180
|
start_rad = start * math.pi/180
|
||||||
stop_rad = stop * math.pi/180
|
stop_rad = stop * math.pi/180
|
||||||
r,g,b = self.GENCOLOR[generation % len(self.GENCOLOR)]
|
r,g,b = self.GENCOLOR[generation % len(self.GENCOLOR)]
|
||||||
if gender == Person.MALE:
|
if gender == gen.lib.Person.MALE:
|
||||||
r -= r * .10
|
r -= r * .10
|
||||||
g -= g * .10
|
g -= g * .10
|
||||||
b -= b * .10
|
b -= b * .10
|
||||||
cr.set_source_rgb(r/255., g/255., b/255.)
|
|
||||||
radius = generation * self.pixels_per_generation + self.center
|
radius = generation * self.pixels_per_generation + self.center
|
||||||
|
# If max generation, and they have parents:
|
||||||
|
if generation == self.generations - 1 and parents:
|
||||||
|
# draw an indicator
|
||||||
|
cr.move_to(0, 0)
|
||||||
|
#cr.set_source_rgba(1, 0.2, 0.2, 0.6) # pink
|
||||||
|
cr.set_source_rgb(255, 255, 255) # white
|
||||||
|
cr.arc(0, 0, radius + 5, start_rad, stop_rad)
|
||||||
|
cr.fill()
|
||||||
|
cr.move_to(0, 0)
|
||||||
|
cr.set_source_rgb(0, 0, 0) # black
|
||||||
|
cr.arc(0, 0, radius + 5, start_rad, stop_rad)
|
||||||
|
cr.line_to(0, 0)
|
||||||
|
cr.stroke()
|
||||||
|
cr.set_source_rgb(r/255., g/255., b/255.)
|
||||||
cr.move_to(0, 0)
|
cr.move_to(0, 0)
|
||||||
cr.arc(0, 0, radius, start_rad, stop_rad)
|
cr.arc(0, 0, radius, start_rad, stop_rad)
|
||||||
cr.move_to(0, 0)
|
cr.move_to(0, 0)
|
||||||
@ -263,6 +279,7 @@ class FanChartWidget(gtk.Widget):
|
|||||||
else: # EXPANDED
|
else: # EXPANDED
|
||||||
cr.set_line_width(3)
|
cr.set_line_width(3)
|
||||||
cr.stroke()
|
cr.stroke()
|
||||||
|
cr.set_line_width(1)
|
||||||
if self.last_x == None or self.last_y == None:
|
if self.last_x == None or self.last_y == None:
|
||||||
self.draw_text(cr, name, radius - self.pixels_per_generation/2,
|
self.draw_text(cr, name, radius - self.pixels_per_generation/2,
|
||||||
start, stop)
|
start, stop)
|
||||||
@ -461,25 +478,27 @@ class FanChartWidget(gtk.Widget):
|
|||||||
selected = None
|
selected = None
|
||||||
if (0 < generation < self.generations):
|
if (0 < generation < self.generations):
|
||||||
for p in range(len(self.angle[generation])):
|
for p in range(len(self.angle[generation])):
|
||||||
start, stop, male, state = self.angle[generation][p]
|
if self.data[generation][p][1]: # there is a person there
|
||||||
if state == self.COLLAPSED: continue
|
start, stop, male, state = self.angle[generation][p]
|
||||||
if start <= pos <= stop:
|
if state == self.COLLAPSED: continue
|
||||||
selected = p
|
if start <= pos <= stop:
|
||||||
break
|
selected = p
|
||||||
if selected == None: # click in open area
|
break
|
||||||
# save the mouse location for movements
|
# Handle the click:
|
||||||
|
if selected == None: # clicked in open area
|
||||||
if radius < self.center:
|
if radius < self.center:
|
||||||
print "TODO: select children"
|
print "TODO: select child, spouse"
|
||||||
self.queue_draw()
|
self.queue_draw()
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
|
# save the mouse location for movements
|
||||||
self.last_x, self.last_y = event.x, event.y
|
self.last_x, self.last_y = event.x, event.y
|
||||||
return True
|
return True
|
||||||
# Do things based on state, event.state, or button, event.button
|
# Do things based on state, event.state, or button, event.button
|
||||||
if event.button == 1: # left mouse
|
if event.button == 1: # left mouse
|
||||||
self.change_slice(generation, selected)
|
self.change_slice(generation, selected)
|
||||||
elif event.button == 3: # right mouse
|
elif event.button == 3: # right mouse
|
||||||
person = self.data[generation][selected]
|
text, person, parents = self.data[generation][selected]
|
||||||
if person and self.right_click_callback:
|
if person and self.right_click_callback:
|
||||||
self.right_click_callback(person)
|
self.right_click_callback(person)
|
||||||
self.queue_draw()
|
self.queue_draw()
|
||||||
@ -490,7 +509,6 @@ class FanChartGramplet(Gramplet):
|
|||||||
The Gramplet code that realizes the FanChartWidget.
|
The Gramplet code that realizes the FanChartWidget.
|
||||||
"""
|
"""
|
||||||
def init(self):
|
def init(self):
|
||||||
self.sa = SimpleAccess(self.dbstate.db)
|
|
||||||
self.set_tooltip("Click to expand/contract person\nRight-click to make person active")
|
self.set_tooltip("Click to expand/contract person\nRight-click to make person active")
|
||||||
self.generations = 6
|
self.generations = 6
|
||||||
self.gui.fan = FanChartWidget(self.generations,
|
self.gui.fan = FanChartWidget(self.generations,
|
||||||
@ -501,42 +519,88 @@ class FanChartGramplet(Gramplet):
|
|||||||
# Make sure it is visible:
|
# Make sure it is visible:
|
||||||
self.gui.fan.show()
|
self.gui.fan.show()
|
||||||
|
|
||||||
def db_changed(self):
|
|
||||||
"""
|
|
||||||
Method called when database changes.
|
|
||||||
"""
|
|
||||||
# reset the db connection
|
|
||||||
self.sa = SimpleAccess(self.dbstate.db)
|
|
||||||
|
|
||||||
def active_changed(self, handle):
|
def active_changed(self, handle):
|
||||||
"""
|
"""
|
||||||
Method called when active person changes.
|
Method called when active person changes.
|
||||||
"""
|
"""
|
||||||
# Reset everything but rotation angle (leave it as is)
|
# Reset everything but rotation angle (leave it as is)
|
||||||
self.gui.fan.reset_generations()
|
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
def have_parents(self, person):
|
||||||
|
"""
|
||||||
|
Returns True if a person has parents.
|
||||||
|
"""
|
||||||
|
if person:
|
||||||
|
m = self.get_parent(person, "female")
|
||||||
|
f = self.get_parent(person, "male")
|
||||||
|
return m != None or f != None
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_parent(self, person, gender):
|
||||||
|
"""
|
||||||
|
Get the father if gender == "male", or get mother otherwise.
|
||||||
|
"""
|
||||||
|
if person:
|
||||||
|
parent_handle_list = person.get_parent_family_handle_list()
|
||||||
|
if parent_handle_list:
|
||||||
|
family_id = parent_handle_list[0]
|
||||||
|
family = self.dbstate.db.get_family_from_handle(family_id)
|
||||||
|
if family:
|
||||||
|
if gender == "male":
|
||||||
|
person_handle = gen.lib.Family.get_father_handle(family)
|
||||||
|
else:
|
||||||
|
person_handle = gen.lib.Family.get_mother_handle(family)
|
||||||
|
if person_handle:
|
||||||
|
return self.dbstate.db.get_person_from_handle(person_handle)
|
||||||
|
return None
|
||||||
|
|
||||||
def main(self):
|
def main(self):
|
||||||
"""
|
"""
|
||||||
Fill the data structures with the active data. This initializes all
|
Fill the data structures with the active data. This initializes all
|
||||||
data.
|
data.
|
||||||
"""
|
"""
|
||||||
self.gui.fan.data[0][0] = self.dbstate.get_active_person()
|
self.gui.fan.reset_generations()
|
||||||
|
person = self.dbstate.get_active_person()
|
||||||
|
if not person:
|
||||||
|
name = None
|
||||||
|
else:
|
||||||
|
name = name_displayer.display(person)
|
||||||
|
parents = self.have_parents(person)
|
||||||
|
self.gui.fan.data[0][0] = (name, person, parents)
|
||||||
for current in range(1, self.generations):
|
for current in range(1, self.generations):
|
||||||
parent = 0
|
parent = 0
|
||||||
for p in self.gui.fan.data[current - 1]:
|
# name, person, parents
|
||||||
self.gui.fan.data[current][parent] = self.sa.father(p)
|
for (n,p,q) in self.gui.fan.data[current - 1]:
|
||||||
if self.gui.fan.data[current][parent] is None:
|
# Get father's details:
|
||||||
|
person = self.get_parent(p, "male")
|
||||||
|
if person:
|
||||||
|
name = name_displayer.display(person)
|
||||||
|
else:
|
||||||
|
name = None
|
||||||
|
if current == self.generations - 1:
|
||||||
|
parents = self.have_parents(person)
|
||||||
|
else:
|
||||||
|
parents = None
|
||||||
|
self.gui.fan.data[current][parent] = (name, person, parents)
|
||||||
|
if person is None:
|
||||||
# start,stop,male/right,state
|
# start,stop,male/right,state
|
||||||
self.gui.fan.angle[current][parent][3] = self.gui.fan.COLLAPSED
|
self.gui.fan.angle[current][parent][3] = self.gui.fan.COLLAPSED
|
||||||
parent += 1
|
parent += 1
|
||||||
self.gui.fan.data[current][parent] = self.sa.mother(p)
|
# Get mother's details:
|
||||||
if self.gui.fan.data[current][parent] is None:
|
person = self.get_parent(p, "female")
|
||||||
# start,stop,male/left,state
|
if person:
|
||||||
|
name = name_displayer.display(person)
|
||||||
|
else:
|
||||||
|
name = None
|
||||||
|
parents = self.have_parents(person)
|
||||||
|
self.gui.fan.data[current][parent] = (name, person, parents)
|
||||||
|
if person is None:
|
||||||
|
# start,stop,male/right,state
|
||||||
self.gui.fan.angle[current][parent][3] = self.gui.fan.COLLAPSED
|
self.gui.fan.angle[current][parent][3] = self.gui.fan.COLLAPSED
|
||||||
parent += 1
|
parent += 1
|
||||||
self.gui.fan.queue_draw()
|
self.gui.fan.queue_draw()
|
||||||
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# Register the Gramplet
|
# Register the Gramplet
|
||||||
|
Loading…
Reference in New Issue
Block a user