* src/PedView.py: Now using cairo :-) Changed menu handling

svn: r5714
This commit is contained in:
Martin Hawlisch 2006-01-11 14:41:07 +00:00
parent 130fea4a89
commit 312696477f
2 changed files with 235 additions and 80 deletions

View File

@ -1,3 +1,7 @@
2006-01-11 Martin Hawlisch <Martin.Hawlisch@gmx.de>
* src/PedView.py: Now using cairo :-)
Changed menu handling
2006-01-10 Don Allingham <don@gramps-project.org> 2006-01-10 Don Allingham <don@gramps-project.org>
* src/FamilyView.py: fix title * src/FamilyView.py: fix title
* src/MapView.py: fix title * src/MapView.py: fix title

View File

@ -36,6 +36,11 @@ from cgi import escape
import gobject import gobject
import gtk import gtk
import gtk.gdk import gtk.gdk
try:
import cairo
cairo_available = True
except:
cairo_available = False
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -86,6 +91,143 @@ class PersonBoxWidget_old( gtk.Button):
self.modify_bg( gtk.STATE_PRELIGHT, white) self.modify_bg( gtk.STATE_PRELIGHT, white)
self.modify_bg( gtk.STATE_SELECTED, white) self.modify_bg( gtk.STATE_SELECTED, white)
class PersonBoxWidget_cairo( gtk.DrawingArea):
def __init__(self,fh,person,maxlines,image=None):
gtk.DrawingArea.__init__(self)
self.add_events(gtk.gdk.BUTTON_PRESS_MASK) # Required for popup menu
self.add_events(gtk.gdk.ENTER_NOTIFY_MASK) # Required for tooltip and mouse-over
self.add_events(gtk.gdk.LEAVE_NOTIFY_MASK) # Required for tooltip and mouse-over
self.fh = fh
self.person = person
self.maxlines = maxlines
self.hightlight = False
self.connect("expose_event", self.expose)
self.connect("realize", self.realize)
self.text = "Cairo"
if self.person:
self.text = self.fh.format_person(self.person,self.maxlines)
alive = Utils.probably_alive(self.person,self.fh.db)
if alive and self.person.get_gender() == RelLib.Person.MALE:
self.bgcolor = (0.9,0.9,1)
self.bordercolor = (0.5,0.5,0.8)
elif alive and self.person.get_gender() == RelLib.Person.FEMALE:
self.bgcolor = (1,0.9,0.9)
self.bordercolor = (0.8,0.5,0.5)
elif alive:
self.bgcolor = (1,0.9,1)
self.bordercolor = (0.8,0.5,0.8)
elif self.person.get_gender() == RelLib.Person.MALE:
self.bgcolor = (0.8,0.8,1)
self.bordercolor = (0,0,0)
elif self.person.get_gender() == RelLib.Person.FEMALE:
self.bgcolor = (1,0.8,0.8)
self.bordercolor = (0,0,0)
else:
self.bgcolor = (1,0.8,1)
self.bordercolor = (0,0,0)
else:
self.bgcolor = (0.9,0.9,0.9)
self.bordercolor = (0,0,0)
self.lines = self.text.split("\n")
self.image = image
try:
self.img_surf = cairo.ImageSurface.create_from_png(image)
except:
self.image = False
self.connect("enter-notify-event", self.on_enter_cb) # enable mouse-over
self.connect("leave-notify-event", self.on_leave_cb)
self.set_size_request(120,25)
def on_enter_cb(self,widget,event):
self.hightlight = True
self.queue_draw()
def on_leave_cb(self,widget,event):
self.hightlight = False
self.queue_draw()
def realize(self,widget):
self.context = self.window.cairo_create()
e = self.context.font_extents()
textheight = len(self.lines) * e[2]
textwidth = 1
for txt in self.lines:
le = self.context.text_extents(txt)
textwidth = max(textwidth,le[4])
xmin = textwidth + 12
ymin = textheight + 11
if self.image:
xmin += self.img_surf.get_width()
ymin = max( ymin,self.img_surf.get_height()+4)
self.set_size_request(max(xmin,120),max(ymin,25))
self.text_gc = self.window.new_gc()
def expose(self,widget,event):
alloc = self.get_allocation()
self.context = self.window.cairo_create()
# widget area for debugging
#self.context.rectangle(0,0,alloc.width,alloc.height)
#self.context.set_source_rgb( 1,0,1)
#self.context.fill_preserve()
#self.context.stroke()
# Create box shape and store path
self.context.move_to(0,5)
self.context.curve_to(0,2,2,0, 5,0)
self.context.line_to(alloc.width-8,0)
self.context.curve_to(alloc.width-5,0,alloc.width-3,2, alloc.width-3,5)
self.context.line_to(alloc.width-3,alloc.height-8)
self.context.curve_to(alloc.width-3,alloc.height-5, alloc.width-5,alloc.height-3, alloc.width-8,alloc.height-3)
self.context.line_to(5,alloc.height-3)
self.context.curve_to(2,alloc.height-3,0,alloc.height-5,0,alloc.height-8)
self.context.close_path()
path = self.context.copy_path()
# shadow
self.context.save()
self.context.translate(3,3)
self.context.new_path()
self.context.append_path( path)
self.context.set_source_rgba( self.bordercolor[0], self.bordercolor[1], self.bordercolor[2],0.4)
self.context.fill_preserve()
self.context.set_line_width(0)
self.context.stroke()
self.context.restore()
# box shape used for clipping
self.context.append_path( path)
self.context.clip()
# background
self.context.append_path( path)
self.context.set_source_rgb( self.bgcolor[0], self.bgcolor[1], self.bgcolor[2])
self.context.fill_preserve()
self.context.stroke()
# image
if self.image:
self.context.set_source_surface( self.img_surf,alloc.width-4-self.img_surf.get_width(),1)
self.context.paint()
#border
if self.hightlight:
self.context.set_line_width(5)
else:
self.context.set_line_width(2)
self.context.append_path( path)
self.context.set_source_rgb( self.bordercolor[0], self.bordercolor[1], self.bordercolor[2])
self.context.stroke()
e = self.context.font_extents()
ypos = 5+e[0]
for txt in self.lines:
self.context.move_to(5,ypos)
self.context.set_source_rgb( 0,0,0)
self.context.show_text(txt)
ypos = ypos + e[2]
class PersonBoxWidget( gtk.DrawingArea): class PersonBoxWidget( gtk.DrawingArea):
def __init__(self,fh,person,maxlines,image=None): def __init__(self,fh,person,maxlines,image=None):
gtk.DrawingArea.__init__(self) gtk.DrawingArea.__init__(self)
@ -95,9 +237,12 @@ class PersonBoxWidget( gtk.DrawingArea):
self.fh = fh self.fh = fh
self.person = person self.person = person
self.maxlines = maxlines self.maxlines = maxlines
self.image = image try:
self.init_done = False self.image = gtk.gdk.pixbuf_new_from_file( image)
except:
self.image = None
self.connect("expose_event", self.expose) self.connect("expose_event", self.expose)
self.connect("realize", self.realize)
text = "" text = ""
if self.person: if self.person:
text = self.fh.format_person(self.person,self.maxlines) text = self.fh.format_person(self.person,self.maxlines)
@ -107,61 +252,56 @@ class PersonBoxWidget( gtk.DrawingArea):
s = self.textlayout.get_pixel_size() s = self.textlayout.get_pixel_size()
xmin = s[0] + 12 xmin = s[0] + 12
ymin = s[1] + 11 ymin = s[1] + 11
if image: if self.image:
xmin += image.get_width() xmin += self.image.get_width()
ymin = max( ymin,image.get_height()+4) ymin = max( ymin,self.image.get_height()+4)
self.set_size_request(max(xmin,120),max(ymin,25)) self.set_size_request(max(xmin,120),max(ymin,25))
def on_enter_cb(self,widget,event): def on_enter_cb(self,widget,event):
'''' On mouse-over hightlight border''' '''' On mouse-over hightlight border'''
try: self.border_gc.line_width = 3
self.border_gc.line_width = 3 self.queue_draw()
self.queue_draw()
except AttributeError:
pass # ignore missing self.border_gc because we are not yet exposed
def on_leave_cb(self,widget,event): def on_leave_cb(self,widget,event):
try: self.border_gc.line_width = 1
self.border_gc.line_width = 1 self.queue_draw()
self.queue_draw()
except AttributeError:
pass # ignore missing self.border_gc because we are not yet exposed
def expose(self,widget,event): def realize(self,widget):
if not self.init_done: self.bg_gc = self.window.new_gc()
self.bg_gc = self.window.new_gc() self.text_gc = self.window.new_gc()
self.text_gc = self.window.new_gc() self.border_gc = self.window.new_gc()
self.border_gc = self.window.new_gc() self.border_gc.line_style = gtk.gdk.LINE_SOLID
self.border_gc.line_style = gtk.gdk.LINE_SOLID self.border_gc.line_width = 1
self.border_gc.line_width = 1 self.shadow_gc = self.window.new_gc()
self.shadow_gc = self.window.new_gc() self.shadow_gc.line_style = gtk.gdk.LINE_SOLID
self.shadow_gc.line_style = gtk.gdk.LINE_SOLID self.shadow_gc.line_width = 4
self.shadow_gc.line_width = 4 if self.person:
if self.person: alive = Utils.probably_alive(self.person,self.fh.db)
alive = Utils.probably_alive(self.person,self.fh.db) if alive and self.person.get_gender() == RelLib.Person.MALE:
if alive and self.person.get_gender() == RelLib.Person.MALE: self.bg_gc.set_foreground( self.get_colormap().alloc_color("#F5FFFF"))
self.bg_gc.set_foreground( self.get_colormap().alloc_color("#F5FFFF")) self.border_gc.set_foreground( self.get_colormap().alloc_color("#009999"))
self.border_gc.set_foreground( self.get_colormap().alloc_color("#009999")) elif self.person.get_gender() == RelLib.Person.MALE:
elif self.person.get_gender() == RelLib.Person.MALE: self.bg_gc.set_foreground( self.get_colormap().alloc_color("#F5FFFF"))
self.bg_gc.set_foreground( self.get_colormap().alloc_color("#F5FFFF")) self.border_gc.set_foreground( self.get_colormap().alloc_color("#000000"))
self.border_gc.set_foreground( self.get_colormap().alloc_color("#000000")) elif alive and self.person.get_gender() == RelLib.Person.FEMALE:
elif alive and self.person.get_gender() == RelLib.Person.FEMALE: self.bg_gc.set_foreground( self.get_colormap().alloc_color("#FFF5FF"))
self.bg_gc.set_foreground( self.get_colormap().alloc_color("#FFF5FF")) self.border_gc.set_foreground( self.get_colormap().alloc_color("#990099"))
self.border_gc.set_foreground( self.get_colormap().alloc_color("#990099")) elif self.person.get_gender() == RelLib.Person.FEMALE:
elif self.person.get_gender() == RelLib.Person.FEMALE: self.bg_gc.set_foreground( self.get_colormap().alloc_color("#FFF5FF"))
self.bg_gc.set_foreground( self.get_colormap().alloc_color("#FFF5FF")) self.border_gc.set_foreground( self.get_colormap().alloc_color("#000000"))
self.border_gc.set_foreground( self.get_colormap().alloc_color("#000000")) elif alive:
elif alive: self.bg_gc.set_foreground( self.get_colormap().alloc_color("#FFFFF5"))
self.bg_gc.set_foreground( self.get_colormap().alloc_color("#FFFFF5")) self.border_gc.set_foreground( self.get_colormap().alloc_color("#999900"))
self.border_gc.set_foreground( self.get_colormap().alloc_color("#999900"))
else:
self.bg_gc.set_foreground( self.get_colormap().alloc_color("#FFFFF5"))
self.border_gc.set_foreground( self.get_colormap().alloc_color("#000000"))
else: else:
self.bg_gc.set_foreground( self.get_colormap().alloc_color("#eeeeee")) self.bg_gc.set_foreground( self.get_colormap().alloc_color("#FFFFF5"))
self.border_gc.set_foreground( self.get_colormap().alloc_color("#777777")) self.border_gc.set_foreground( self.get_colormap().alloc_color("#000000"))
self.shadow_gc.set_foreground( self.get_colormap().alloc_color("#999999")) else:
self.init_done = True self.bg_gc.set_foreground( self.get_colormap().alloc_color("#eeeeee"))
self.border_gc.set_foreground( self.get_colormap().alloc_color("#777777"))
self.shadow_gc.set_foreground( self.get_colormap().alloc_color("#999999"))
def expose(self,widget,event):
alloc = self.get_allocation() alloc = self.get_allocation()
# shadow # shadow
self.window.draw_line(self.shadow_gc, 3, alloc.height-1, alloc.width, alloc.height-1) self.window.draw_line(self.shadow_gc, 3, alloc.height-1, alloc.width, alloc.height-1)
@ -191,11 +331,11 @@ class FormattingHelper:
text = "" text = ""
for event_ref in family.get_event_ref_list(): for event_ref in family.get_event_ref_list():
event = self.db.get_event_from_handle(event_ref.ref) event = self.db.get_event_from_handle(event_ref.ref)
if event: if event and event.get_type()[0] == RelLib.Event.MARRIAGE:
if line_count < 3: if line_count < 3:
return DateHandler.get_date(event) return DateHandler.get_date(event)
i,s = event.get_type() (i,s) = event.get_type()
name = Utils.family_relations[i] name = Utils.family_events.get(i)
text += name text += name
text += "\n" text += "\n"
text += DateHandler.get_date(event) text += DateHandler.get_date(event)
@ -204,6 +344,8 @@ class FormattingHelper:
if line_count < 5: if line_count < 5:
return text; return text;
break break
if not text:
text = ReportUtils.relationship_name(family.get_relationship())
return text return text
def get_place_name( self, place_handle): def get_place_name( self, place_handle):
@ -557,7 +699,10 @@ class PedView(PageView.PersonNavView):
continue continue
if not lst[i]: if not lst[i]:
# No person -> show empty box # No person -> show empty box
pw = PersonBoxWidget( self.format_helper, None, 0, None); if cairo_available:
pw = PersonBoxWidget_cairo( self.format_helper, None, 0, None);
else:
pw = PersonBoxWidget( self.format_helper, None, 0, None);
if positions[i][0][2] > 1: if positions[i][0][2] > 1:
table_widget.attach(pw,x,x+w,y,y+h,gtk.FILL,gtk.FILL,0,0) table_widget.attach(pw,x,x+w,y,y+h,gtk.FILL,gtk.FILL,0,0)
else: else:
@ -578,13 +723,15 @@ class PedView(PageView.PersonNavView):
if obj: if obj:
mtype = obj.get_mime_type() mtype = obj.get_mime_type()
if mtype[0:5] == "image": if mtype[0:5] == "image":
image = ImgManip.get_thumbnail_image(obj.get_path()) image = ImgManip.get_thumbnail_path(obj.get_path())
pw = PersonBoxWidget( self.format_helper, lst[i][0], positions[i][0][3], image); if cairo_available:
pw = PersonBoxWidget_cairo( self.format_helper, lst[i][0], positions[i][0][3], image);
else:
pw = PersonBoxWidget( self.format_helper, lst[i][0], positions[i][0][3], image);
if positions[i][0][3] < 7: if positions[i][0][3] < 7:
self.tooltips.set_tip(pw, self.format_helper.format_person(lst[i][0], 11)) self.tooltips.set_tip(pw, self.format_helper.format_person(lst[i][0], 11))
pw.set_data(_PERSON,lst[i][0].get_handle()) pw.connect("button-press-event", self.person_button_press_cb,lst[i][0].get_handle())
pw.connect("button-press-event", self.build_full_nav_menu_cb)
if positions[i][0][2] > 1: if positions[i][0][2] > 1:
table_widget.attach(pw,x,x+w,y,y+h,gtk.EXPAND|gtk.FILL,gtk.EXPAND|gtk.FILL,0,0) table_widget.attach(pw,x,x+w,y,y+h,gtk.EXPAND|gtk.FILL,gtk.EXPAND|gtk.FILL,0,0)
else: else:
@ -771,10 +918,22 @@ class PedView(PageView.PersonNavView):
def on_show_option_menu_cb(self,obj,data=None): def on_show_option_menu_cb(self,obj,data=None):
myMenu = gtk.Menu() myMenu = gtk.Menu()
self.add_nav_portion_to_menu(myMenu)
self.add_settings_to_menu(myMenu) self.add_settings_to_menu(myMenu)
myMenu.popup(None,None,None,0,0) myMenu.popup(None,None,None,0,0)
return(True); return(True);
def person_button_press_cb(self,obj,event,person_handle):
if event.button==1:
defperson = self.dbstate.active
if defperson and defperson.get_handle() != person_handle:
self.dbstate.change_active_handle(person_handle)
else:
self.build_full_nav_menu_cb(obj,event,person_handle)
else:
self.build_full_nav_menu_cb(obj,event,person_handle)
return True
def on_show_child_menu(self,obj): def on_show_child_menu(self,obj):
"""User clicked button to move to child of active person""" """User clicked button to move to child of active person"""
@ -810,15 +969,11 @@ class PedView(PageView.PersonNavView):
return 1 return 1
return 0 return 0
def on_childmenu_changed(self,obj): def on_childmenu_changed(self,obj,person_handle):
"""Callback for the pulldown menu selection, changing to the person """Callback for the pulldown menu selection, changing to the person
attached with menu item.""" attached with menu item."""
self.dbstate.change_active_handle(person_handle)
person_handle = obj.get_data(_PERSON) return True
if person_handle:
self.dbstate.change_active_handle(person_handle)
return True
return False
def change_force_size_cb(self,event,data): def change_force_size_cb(self,event,data):
if data in [0,2,3,4,5]: if data in [0,2,3,4,5]:
@ -893,9 +1048,12 @@ class PedView(PageView.PersonNavView):
im = gtk.image_new_from_stock(gtk.STOCK_HOME,gtk.ICON_SIZE_MENU) im = gtk.image_new_from_stock(gtk.STOCK_HOME,gtk.ICON_SIZE_MENU)
im.show() im.show()
item.set_image(im) item.set_image(im)
if not self.dbstate.db.get_default_person():
item.set_sensitive(False)
else:
item.set_sensitive(sensitivity)
if callback: if callback:
item.connect("activate",callback) item.connect("activate",callback)
item.set_sensitive(sensitivity)
item.show() item.show()
menu.append(item) menu.append(item)
@ -971,7 +1129,7 @@ class PedView(PageView.PersonNavView):
menu.append(item) menu.append(item)
def build_full_nav_menu_cb(self,obj,event): def build_full_nav_menu_cb(self,obj,event,person_handle):
""" """
Builds the full menu (including Siblings, Spouses, Children, Builds the full menu (including Siblings, Spouses, Children,
and Parents) with navigation. and Parents) with navigation.
@ -980,7 +1138,6 @@ class PedView(PageView.PersonNavView):
menu = gtk.Menu() menu = gtk.Menu()
menu.set_title(_('People Menu')) menu.set_title(_('People Menu'))
person_handle = obj.get_data(_PERSON)
person = self.db.get_person_from_handle(person_handle) person = self.db.get_person_from_handle(person_handle)
if not person: if not person:
return 0 return 0
@ -989,8 +1146,7 @@ class PedView(PageView.PersonNavView):
go_image.show() go_image.show()
go_item = gtk.ImageMenuItem(NameDisplay.displayer.display(person)) go_item = gtk.ImageMenuItem(NameDisplay.displayer.display(person))
go_item.set_image(go_image) go_item.set_image(go_image)
go_item.set_data(_PERSON,person_handle) go_item.connect("activate",self.on_childmenu_changed,person_handle)
go_item.connect("activate",self.on_childmenu_changed)
go_item.show() go_item.show()
menu.append(go_item) menu.append(go_item)
@ -1029,9 +1185,8 @@ class PedView(PageView.PersonNavView):
go_image.show() go_image.show()
sp_item = gtk.ImageMenuItem(NameDisplay.displayer.display(spouse)) sp_item = gtk.ImageMenuItem(NameDisplay.displayer.display(spouse))
sp_item.set_image(go_image) sp_item.set_image(go_image)
sp_item.set_data(_PERSON,sp_id)
linked_persons.append(sp_id) linked_persons.append(sp_id)
sp_item.connect("activate",self.on_childmenu_changed) sp_item.connect("activate",self.on_childmenu_changed,sp_id)
sp_item.show() sp_item.show()
sp_menu.append(sp_item) sp_menu.append(sp_item)
@ -1073,9 +1228,8 @@ class PedView(PageView.PersonNavView):
label.show() label.show()
label.set_alignment(0,0) label.set_alignment(0,0)
sib_item.add(label) sib_item.add(label)
sib_item.set_data(_PERSON,sib_id)
linked_persons.append(sib_id) linked_persons.append(sib_id)
sib_item.connect("activate",self.on_childmenu_changed) sib_item.connect("activate",self.on_childmenu_changed,sib_id)
sib_item.show() sib_item.show()
sib_menu.append(sib_item) sib_menu.append(sib_item)
@ -1111,9 +1265,8 @@ class PedView(PageView.PersonNavView):
label.show() label.show()
label.set_alignment(0,0) label.set_alignment(0,0)
child_item.add(label) child_item.add(label)
child_item.set_data(_PERSON,child_handle)
linked_persons.append(child_handle) linked_persons.append(child_handle)
child_item.connect("activate",self.on_childmenu_changed) child_item.connect("activate",self.on_childmenu_changed,child_handle)
child_item.show() child_item.show()
child_menu.append(child_item) child_menu.append(child_item)
@ -1149,9 +1302,8 @@ class PedView(PageView.PersonNavView):
label.show() label.show()
label.set_alignment(0,0) label.set_alignment(0,0)
par_item.add(label) par_item.add(label)
par_item.set_data(_PERSON,par_id)
linked_persons.append(par_id) linked_persons.append(par_id)
par_item.connect("activate",self.on_childmenu_changed) par_item.connect("activate",self.on_childmenu_changed,par_id)
par_item.show() par_item.show()
par_menu.append(par_item) par_menu.append(par_item)
@ -1186,8 +1338,7 @@ class PedView(PageView.PersonNavView):
label.show() label.show()
label.set_alignment(0,0) label.set_alignment(0,0)
per_item.add(label) per_item.add(label)
per_item.set_data(_PERSON,p_id) per_item.connect("activate",self.on_childmenu_changed,p_id)
per_item.connect("activate",self.on_childmenu_changed)
per_item.show() per_item.show()
per_menu.append(per_item) per_menu.append(per_item)