Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/activity.py
diff options
context:
space:
mode:
Diffstat (limited to 'activity.py')
-rw-r--r--activity.py266
1 files changed, 192 insertions, 74 deletions
diff --git a/activity.py b/activity.py
index 5573f58..91d2e24 100644
--- a/activity.py
+++ b/activity.py
@@ -5,8 +5,9 @@ from gettext import gettext as _
# Local import
from src.person import Person
-from src.person import persons
from src.union import Union
+from src.tree import Tree
+from src.tree import sample_family1, sample_family2
import src.const as const
@@ -49,15 +50,10 @@ class RootsActivity(activity.Activity):
self.set_toolbox(toolbox)
toolbox.show()
- # Create sample data
- (self.initx, self.inity, self.initzoom) = (500, 50, 0)
- self.tree = self.init_family()
- self.tree.compute_draw(self.initx, self.inity)
-
# Create drawing area
- self.zoomlevel = 1
+ self.zoomlevel = 0
self.area = gtk.DrawingArea()
- self.area.set_size_request(600, 300)
+ self.area.set_size_request(750, 600)
self.area.set_events(gtk.gdk.BUTTON_PRESS_MASK|gtk.gdk.BUTTON_RELEASE_MASK|gtk.gdk.BUTTON_MOTION_MASK|gtk.gdk.POINTER_MOTION_MASK)
self.area.connect("expose_event", self.area_expose_cb)
self.area.connect("button_press_event", self.press_button)
@@ -65,104 +61,162 @@ class RootsActivity(activity.Activity):
self.area.connect("motion_notify_event", self.mouse_move)
self.moving = False
- # Draw
- self.box = gtk.VBox(False)
+ # Create detail view
+ self.fixed = gtk.VBox()
+ self.fixed.set_size_request(200, 300)
+ self.fixed.pack_start(gtk.Label("Name:"), False, False, 0)
+ self.detail_name = gtk.TextView()
+ self.detail_name.set_cursor_visible(True)
+ self.detail_name.get_buffer().connect("changed", self.detail_changed)
+ self.fixed.pack_start(self.detail_name, False, False, 0)
+ self.detail_chkmale = gtk.RadioButton(None, "Male")
+ self.detail_chkmale.connect("toggled", self.sexradio_checked, 'M')
+ self.fixed.pack_start(self.detail_chkmale, False, False, 0)
+ self.detail_chkfemale = gtk.RadioButton(self.detail_chkmale, "Female")
+ self.detail_chkfemale.connect("toggled", self.sexradio_checked, 'F')
+ self.fixed.pack_start(self.detail_chkfemale, False, False, 0)
+ self.detail_btnaddunion = gtk.Button("Add union")
+ self.detail_btnaddunion.connect("clicked", self.addunion_clicked)
+ self.detail_btnaddchild = gtk.Button("Add child")
+ self.detail_btnaddchild.connect("clicked", self.addchild_clicked)
+ self.detail_btndelete = gtk.Button("Delete")
+ self.detail_btndelete.connect("clicked", self.delete_clicked)
+ self.fixed.pack_start(self.detail_btnaddunion, False, False, 0)
+ self.fixed.pack_start(self.detail_btnaddchild, False, False, 0)
+ self.fixed.pack_start(self.detail_btndelete, False, False, 0)
+ self.box = gtk.HBox(False)
+ self.box.pack_start(self.fixed, True, True, 0)
self.box.pack_start(self.area, True, True, 0)
self.set_canvas(self.box)
+
+ # Create sample data
+ (self.initx, self.inity) = (500, 50)
+ self.tree = sample_family2()
+ self.tree.root.compute_draw(self.initx, self.inity)
+ self.show_detail(None)
+
+ # Show all
self.show_all()
self.area.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.ARROW))
-
- def init_family(self):
- "Init a sample tree"
- l = Person("Lucien", "M")
- a = Person("Annick", "F")
- u = Union(l, a)
-
- d = Person("Dominique", "M")
- u.append_child(d)
- au = Person("Anne", "F")
- u.append_child(au)
- m = Person("Madeleine", "F")
- u.append_child(m)
-
- jp = Person("Jean-Pierre", "M")
- j = Person("Julie", "F")
- up = Union(jp, j)
- up.append_child(l)
- c = Person("Christian", "M")
- up.append_child(c)
-
- ub = Union(Person("Jonathan", "M"), j)
- ub.append_child(Person("Charlie", "F"))
-
- rs = Person("Renee", "F")
- vm = Person("Vivien", "M")
- urv = Union(vm, rs)
- urv.append_child(j)
-
- jr = Person("Jean-Rene", "M")
- ua = Union(jr, Person("Micheline", "F"))
- ua.append_child(a)
- i = Person("Irene", "F")
- ua.append_child(i)
- ui = Union(Person("Nathan", "M"), i)
- ui.append_child(Person("Marie", "F"))
- ui.append_child(Person("Noel", "M"))
- ui.append_child(Person("Thierry", "M"))
-
- uc = Union(c, Person("Clarah", "F"))
- uc.append_child(Person("Sandrine", "F"))
- uc2 = Union(c, Person("Vivianne", "F"))
- uc2.append_child(Person("Pierre", "M"))
- uc2.append_child(Person("Camille", "F"))
-
- return vm
-
+
+ def set_center(self, person):
+ "Set the center of the draw on a person"
+ rect = self.area.allocation
+ dx = (rect.width/2) - self.tree.root.x0 - (person.x0 - self.tree.root.x0) - (person.x1 - person.x0)/2
+ dy = (rect.height/2) - self.tree.root.y0 - (person.y0 - self.tree.root.y0) - (person.y1 - person.y0)/2
+ self.translate(dx, dy)
+
+
+ def show_detail(self, person):
+ "Show detail information for a person"
+
+ # Change selection
+ self.selected = person
+
+ # No selection
+ if person == None:
+ self.detail_name.set_sensitive(False)
+ self.detail_name.get_buffer().set_text("Click one a node to select it")
+ self.detail_chkmale.set_active(True)
+ self.detail_chkmale.set_sensitive(False)
+ self.detail_chkfemale.set_sensitive(False)
+ self.detail_btnaddunion.set_sensitive(False)
+ self.detail_btnaddchild.set_sensitive(False)
+ self.detail_btndelete.set_sensitive(False)
+ return
+
+ # A node is selected
+ self.detail_name.set_sensitive(True)
+ self.detail_name.grab_focus()
+ self.detail_name.get_buffer().set_text(person.name)
+ if person.sex == 'M':
+ self.detail_chkmale.set_active(True)
+ else:
+ self.detail_chkfemale.set_active(True)
+
+ # Compute button status
+ checkable = (len(person.unions) == 0)
+ self.detail_chkmale.set_sensitive(checkable)
+ self.detail_chkfemale.set_sensitive(checkable)
+ self.detail_btnaddchild.set_sensitive(len(person.unions) > 0)
+ unionscount = len(person.unions)
+ childcount = person.child_count()
+ isdescendant = self.tree.is_descendant(person)
+ if person == self.tree.root:
+ deletable = False
+ elif unionscount == 0:
+ deletable = True
+ elif unionscount > 1:
+ deletable = False
+ elif unionscount == 1 and isdescendant:
+ deletable = False
+ elif childcount > 0:
+ deletable = False
+ else:
+ deletable = True
+ self.detail_btndelete.set_sensitive(deletable)
+ self.detail_btnaddunion.set_sensitive(isdescendant)
+
def area_expose_cb(self, area, event):
"Draw tree event"
+
+ # Create context then draw tree inside
gc = self.area.window.cairo_create()
pc = self.create_pango_context()
- self.tree.draw(gc, pc)
+ self.tree.root.draw(gc, pc)
gc.stroke()
+
+ # Draw cross in middle to debug position
+ rect = self.area.allocation
+ gc.move_to((rect.width/2)-10, (rect.height/2))
+ gc.line_to((rect.width/2)+10, (rect.height/2))
+ gc.move_to((rect.width/2), (rect.height/2)-10)
+ gc.line_to((rect.width/2), (rect.height/2)+10)
+ gc.set_source_rgb(255, 255, 255)
+ gc.stroke()
def press_button(self, widget, event):
"Mouse button clicked, detail a person or start the moving mode"
# Look if click in a person
- for p in persons:
+ for p in self.tree.persons:
# Found one, show detail
if p.point_inside(event.x, event.y):
- print p.name
+ self.set_center(p)
+ self.show_detail(p)
self.moving = False
return
# Not found, pass in moving mode
+ self.show_detail(None)
self.movingStart = (event.x, event.y)
self.moving = True
self.area.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR))
-
+
+ def translate(self, dx, dy):
+ # Translate all the tree from deltax, deltay
+ (self.initx, self.inity) = (self.initx+dx, self.inity+dy)
+ for p in self.tree.persons:
+ p.translate(dx, dy)
+ self.redraw()
+
+
def mouse_move(self, widget, event):
"Mouse move event, in moving mode translate draw if in moving mode else change cursor on person"
# In moving mode ?
if self.moving:
# Compute translation
- (dx, dy) = (event.x-self.movingStart[0], event.y-self.movingStart[1])
- (self.initx, self.inity) = (self.initx+dx, self.inity+dy)
- for p in persons:
- p.translate(dx, dy)
+ self.translate(event.x-self.movingStart[0], event.y-self.movingStart[1])
self.movingStart = (event.x, event.y)
-
- # Redraw
- self.redraw()
else:
# Look if a person is under the cursor
- for p in persons:
+ for p in self.tree.persons:
# Found one, change cursor
if p.point_inside(event.x, event.y):
self.area.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND1))
@@ -181,21 +235,85 @@ class RootsActivity(activity.Activity):
def zoom_in(self, event):
"ToolBar button zoom in clicked"
- self.initzoom = self.initzoom + 20
+ self.zoomlevel = self.zoomlevel + 1
+ for p in self.tree.persons:
+ p.scale(20)
self.redraw()
def zoom_out(self, event):
"ToolBar button zoom out clicked"
- self.initzoom = self.initzoom - 20
+ if self.zoomlevel == -3:
+ return
+ self.zoomlevel = self.zoomlevel - 1
+ for p in self.tree.persons:
+ p.scale(-20)
+ self.redraw()
+
+
+ def detail_changed(self, event):
+ "Textfield for the detail has changed, change the matching person name"
+ if self.selected == None:
+ self.redraw()
+ return
+ buffer = self.detail_name.get_buffer()
+ self.selected.name = buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter())
+ self.redraw()
+
+
+ def sexradio_checked(self, widget, data):
+ "Radio button for sex checked, change sex for the selected person"
+ if self.selected is not None:
+ self.selected.sex = data
self.redraw()
+
+ def addchild_clicked(self, event):
+ "Add child clicked"
+ # TODO: Child add to the first union
+ newchild = self.tree.Person("", "M")
+ self.selected.unions[0].append_child(newchild)
+ self.tree.root.compute_draw(self.tree.root.x0, self.tree.root.y0)
+ self.show_detail(newchild)
+
+
+ def addunion_clicked(self, event):
+ "Add union clicked"
+ if self.selected.sex == "M":
+ male = self.selected
+ female = newunion = self.tree.Person("", "F")
+ else:
+ male = newunion = self.tree.Person("", "M")
+ female = self.selected
+ self.tree.Union(male, female)
+ self.tree.root.compute_draw(self.tree.root.x0, self.tree.root.y0)
+ self.show_detail(newunion)
+
+
+ def delete_clicked(self, event):
+ "Delete button clicked"
+ # Remove from union
+ for u in self.selected.unions:
+ self.tree.unions.remove(u)
+ if u.dad == self.selected:
+ u.mum.unions.remove(u)
+ else:
+ u.dad.unions.remove(u)
+
+ # Remove from parent child
+ if self.selected.parents is not None:
+ self.selected.parents.childs.remove(self.selected)
+ # Remove from tree
+ self.tree.persons.remove(self.selected)
+
+ # Recompute and redraw
+ self.tree.root.compute_draw(self.tree.root.x0, self.tree.root.y0)
+ self.show_detail(None)
+
+
def redraw(self):
"Redraw area"
- self.tree.compute_draw(self.initx, self.inity)
- for p in persons:
- p.scale(self.initzoom)
self.area.queue_draw_area(0, 0, self.area.allocation.width, self.area.allocation.height)