Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGonzalo Odiard <godiard@gmail.com>2012-04-16 19:00:09 (GMT)
committer Gonzalo Odiard <godiard@gmail.com>2012-04-17 18:11:36 (GMT)
commit7ed15ed98ee5f2a53a5dac8a75381bac6196c19e (patch)
treeef01c2e006c97cd6ae4daac6004239aa1a6e7a6d
parent862171dbe24dbf6e877a672b22c14ac493bb096a (diff)
Add combos to enable the user to change the font used in the cards. v2
This work is based in the contributions of Flavio Danesse <fdanesse@activitycentral.com> and Ariel Calzada <ariel.calzada@gmail.com> The fonts are saved in the game file. v2: Solve error in add-pair, and initialization of card font in the CardEditor Signed-of-by: Gonzalo Odiard <gonzalo@laptop.org>
-rw-r--r--activity.py4
-rw-r--r--cardlist.py31
-rw-r--r--cardtable.py7
-rw-r--r--createcardpanel.py67
-rw-r--r--fontcombobox.py65
-rw-r--r--memorize.dtd4
-rw-r--r--model.py13
-rw-r--r--svgcard.py17
8 files changed, 187 insertions, 21 deletions
diff --git a/activity.py b/activity.py
index 8a472d6..1fdf8ac 100644
--- a/activity.py
+++ b/activity.py
@@ -116,6 +116,8 @@ class MemorizeActivity(Activity):
self.cardlist.add_pair)
self.createcardpanel.connect('update-pair',
self.cardlist.update_selected)
+ self.createcardpanel.connect('change-font',
+ self.cardlist.change_font)
self._createToolbarBuilder.connect('create_new_game',
self.cardlist.clean_list)
self._createToolbarBuilder.connect('create_new_game',
@@ -155,6 +157,8 @@ class MemorizeActivity(Activity):
self._memorizeToolbarBuilder.update_toolbar)
self.game.connect('change_game',
self._memorizeToolbarBuilder.update_toolbar)
+ self.game.connect('change_game',
+ self.createcardpanel.update_font_combos)
self._memorizeToolbarBuilder.connect('game_changed',
self.change_game)
diff --git a/cardlist.py b/cardlist.py
index 66e5f56..6bc781c 100644
--- a/cardlist.py
+++ b/cardlist.py
@@ -71,6 +71,8 @@ class CardList(gtk.EventBox):
self.get_window().freeze_updates()
self.model = game.model
self.current_game_key = self.model.data['game_file']
+ font_name1 = self.model.data['font_name1']
+ font_name2 = self.model.data['font_name2']
game_pairs = self.model.pairs
game_data = self.model.data
self.clean_list(load=True)
@@ -104,7 +106,7 @@ class CardList(gtk.EventBox):
self.add_pair(None, game_pairs[key].props.achar,
game_pairs[key].props.bchar, aimg, bimg, asnd, bsnd,
game_pairs[key].props.aspeak, game_pairs[key].props.bspeak,
- False, load=True)
+ font_name1, font_name2, False, load=True)
self.get_window().thaw_updates()
self.emit('update-create-toolbar', self.model.data['name'],
self.model.data['equal_pairs'],
@@ -184,8 +186,9 @@ class CardList(gtk.EventBox):
self.model.mark_modified()
def add_pair(self, widget, achar, bchar, aimg, bimg, asnd, bsnd,
- aspeak, bspeak, show=True, load=False):
- pair = CardPair(achar, bchar, aimg, bimg, asnd, bsnd, aspeak, bspeak)
+ aspeak, bspeak, font_name1, font_name2, show=True, load=False):
+ pair = CardPair(achar, bchar, aimg, bimg, asnd, bsnd, aspeak, bspeak,
+ font_name1, font_name2)
self.vbox.pack_end(pair, False, True)
self.pairs.append(pair)
pair.connect('pair-selected', self.set_selected)
@@ -196,6 +199,15 @@ class CardList(gtk.EventBox):
if show:
self.show_all()
+ def change_font(self, widget, group, font_name):
+ for pair in self.pairs:
+ pair.change_font(group, font_name)
+ if group == 1:
+ self.model.data['font_name1'] = font_name
+ if group == 2:
+ self.model.data['font_name2'] = font_name
+ self.model.mark_modified()
+
def rem_pair(self, widget, event):
self.vbox.remove(widget)
self.pairs.remove(widget)
@@ -238,7 +250,8 @@ class CardPair(gtk.EventBox):
}
def __init__(self, text1, text2=None, aimg=None, bimg=None,
- asnd=None, bsnd=None, aspeak=None, bspeak=None):
+ asnd=None, bsnd=None, aspeak=None, bspeak=None,
+ font_name1=None, font_name2=None):
gtk.EventBox.__init__(self)
self.bg_color = '#000000'
@@ -258,7 +271,7 @@ class CardPair(gtk.EventBox):
'front': {'fill_color': '#4c4d4f',
'stroke_color': '#ffffff',
'opacity': '1'}},
- None, theme.PAIR_SIZE, 1, self.bg_color)
+ None, theme.PAIR_SIZE, 1, self.bg_color, font_name1)
self.bcard1.flip()
self.bcard1.set_pixbuf(aimg)
align = gtk.Alignment(.5, .5, 0, 0)
@@ -272,7 +285,7 @@ class CardPair(gtk.EventBox):
'front': {'fill_color': '#4c4d4f',
'stroke_color': '#ffffff',
'opacity': '1'}},
- None, theme.PAIR_SIZE, 1, self.bg_color)
+ None, theme.PAIR_SIZE, 1, self.bg_color, font_name2)
self.bcard2.flip()
self.bcard2.set_pixbuf(bimg)
align = gtk.Alignment(.5, .5, 0, 0)
@@ -326,6 +339,12 @@ class CardPair(gtk.EventBox):
self.asnd = asnd
self.bsnd = bsnd
+ def change_font(self, card, font_name):
+ if card == 1:
+ self.bcard1.change_font(font_name)
+ else:
+ self.bcard2.change_font(font_name)
+
def get_text(self, card):
if card == 1:
return self.bcard1.get_text()
diff --git a/cardtable.py b/cardtable.py
index b9ab29f..97428cc 100644
--- a/cardtable.py
+++ b/cardtable.py
@@ -88,7 +88,8 @@ class CardTable(gtk.EventBox):
def load_game(self, widget, data, grid):
self.data = data
self.cards_data = grid
-
+ font_name1 = data['font_name1']
+ font_name2 = data['font_name2']
if self._workspace_size == 0:
# widow is not allocated, thus postpone loading
return
@@ -129,12 +130,14 @@ class CardTable(gtk.EventBox):
if card['ab'] == 'a':
props['back_text'] = {'card_text': text1}
+ font_name = font_name1
elif card['ab'] == 'b':
props['back_text'] = {'card_text': text2}
+ font_name = font_name2
align = self.data.get('align', '1')
card = svgcard.SvgCard(identifier, props, jpg,
- self.card_size, align)
+ self.card_size, align, '#000000', font_name)
card.connect('enter-notify-event', self.mouse_event, [x, y])
card.connect('button-press-event',
self.flip_card_mouse, identifier)
diff --git a/createcardpanel.py b/createcardpanel.py
index e654b1c..1da561f 100644
--- a/createcardpanel.py
+++ b/createcardpanel.py
@@ -31,6 +31,7 @@ from sugar.graphics.icon import Icon
from sugar.graphics.palette import Palette
from sugar.graphics.toggletoolbutton import ToggleToolButton
from sugar.graphics.toolcombobox import ToolComboBox
+from fontcombobox import FontComboBox
from port import chooser
import theme
@@ -38,14 +39,16 @@ import speak.espeak
import speak.widgets
import speak.face
from port.roundbox import RoundBox
+import model
_logger = logging.getLogger('memorize-activity')
class CreateCardPanel(gtk.EventBox):
__gsignals__ = {
- 'add-pair': (SIGNAL_RUN_FIRST, None, 8 * [TYPE_PYOBJECT]),
+ 'add-pair': (SIGNAL_RUN_FIRST, None, 10 * [TYPE_PYOBJECT]),
'update-pair': (SIGNAL_RUN_FIRST, None, 8 * [TYPE_PYOBJECT]),
+ 'change-font': (SIGNAL_RUN_FIRST, None, 2 * [TYPE_PYOBJECT]),
}
def __init__(self):
@@ -92,8 +95,8 @@ class CreateCardPanel(gtk.EventBox):
# Set card editors
- self.cardeditor1 = CardEditor()
- self.cardeditor2 = CardEditor()
+ self.cardeditor1 = CardEditor(1)
+ self.cardeditor2 = CardEditor(2)
self.clean(None)
self.cardeditor1.connect('has-text', self.receive_text_signals)
self.cardeditor2.connect('has-text', self.receive_text_signals)
@@ -101,6 +104,8 @@ class CreateCardPanel(gtk.EventBox):
self.cardeditor2.connect('has-picture', self.receive_picture_signals)
self.cardeditor1.connect('has-sound', self.receive_sound_signals)
self.cardeditor2.connect('has-sound', self.receive_sound_signals)
+ self.cardeditor1.connect('change-font', self.receive_font_signals)
+ self.cardeditor2.connect('change-font', self.receive_font_signals)
# edit panel
@@ -115,6 +120,15 @@ class CreateCardPanel(gtk.EventBox):
self.show_all()
+ def update_font_combos(self, widget, data, grid):
+ logging.error('update font %s', data)
+ if 'font_name1' in data:
+ self.cardeditor1.set_font_name(data['font_name1'])
+ self.cardeditor1.card.change_font(data['font_name1'])
+ if 'font_name2' in data:
+ self.cardeditor2.set_font_name(data['font_name2'])
+ self.cardeditor2.card.change_font(data['font_name2'])
+
def emit_add_pair(self, widget):
self._addbutton.set_sensitive(False)
if self.equal_pairs:
@@ -125,7 +139,9 @@ class CreateCardPanel(gtk.EventBox):
self.cardeditor1.get_snd(),
self.cardeditor1.get_snd(),
self.cardeditor1.get_speak(),
- self.cardeditor1.get_speak())
+ self.cardeditor1.get_speak(),
+ self.cardeditor1.get_font_name(),
+ self.cardeditor1.get_font_name())
else:
self.emit('add-pair', self.cardeditor1.get_text(),
self.cardeditor2.get_text(),
@@ -134,7 +150,9 @@ class CreateCardPanel(gtk.EventBox):
self.cardeditor1.get_snd(),
self.cardeditor2.get_snd(),
self.cardeditor1.get_speak(),
- self.cardeditor2.get_speak())
+ self.cardeditor2.get_speak(),
+ self.cardeditor1.get_font_name(),
+ self.cardeditor2.get_font_name())
self.clean(None)
def emit_update_pair(self, widget):
@@ -215,6 +233,16 @@ class CreateCardPanel(gtk.EventBox):
self._card2_has_sound = has_sound
self._update_buttom_status()
+ def receive_font_signals(self, widget, font_name):
+ if self.equal_pairs:
+ self.emit('change-font', 1, font_name)
+ self.emit('change-font', 2, font_name)
+ else:
+ if widget == self.cardeditor1:
+ self.emit('change-font', 1, font_name)
+ if widget == self.cardeditor2:
+ self.emit('change-font', 2, font_name)
+
def _update_buttom_status(self):
if not self.equal_pairs:
if (self._card1_has_text or self._card1_has_picture \
@@ -246,13 +274,14 @@ class CardEditor(gtk.EventBox):
'has-text': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]),
'has-picture': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]),
'has-sound': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]),
+ 'change-font': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]),
}
- def __init__(self):
+ def __init__(self, editor_index):
gtk.EventBox.__init__(self)
self.snd = None
-
+ self.editor_index = editor_index
self.temp_folder = None
box = gtk.VBox()
@@ -307,10 +336,27 @@ class CardEditor(gtk.EventBox):
else:
self.usespeak = None
- box.pack_start(toolbar, False)
+ self.font_combo = FontComboBox()
+ self.id_font_changed = self.font_combo.connect("changed",
+ self.__font_changed_cb)
+ self.font_combo.set_font_name(model.DEFAULT_FONT)
+
+ box.pack_start(self.font_combo, True, True, 0)
self.add(box)
+ def __font_changed_cb(self, widget):
+ font = widget.get_font_name()
+ logging.error('Selected font %s', font)
+ if font:
+ self.card.change_font(font)
+ self.emit('change-font', font)
+
+ def set_font_name(self, font_name):
+ self.font_combo.handler_block(self.id_font_changed)
+ self.font_combo.set_font_name(font_name)
+ self.font_combo.handler_unblock(self.id_font_changed)
+
def update_text(self, entry):
self.card.change_text(entry.get_text())
if len(entry.get_text()) == 0:
@@ -416,6 +462,9 @@ class CardEditor(gtk.EventBox):
def get_snd(self):
return self.snd
+ def get_font_name(self):
+ return self.font_combo.get_font_name()
+
def clean(self):
self.textentry.set_text('')
self.card.set_pixbuf(None)
@@ -423,7 +472,7 @@ class CardEditor(gtk.EventBox):
self.emit('has-text', False)
self.emit('has-picture', False)
self.emit('has-sound', False)
- if self.usespeak is not None:
+ if self.usespeak is not None and self.usespeak.palette is not None:
self.usespeak.props.active = False
self.usespeak.palette.face.shut_up()
diff --git a/fontcombobox.py b/fontcombobox.py
new file mode 100644
index 0000000..58f9140
--- /dev/null
+++ b/fontcombobox.py
@@ -0,0 +1,65 @@
+# Copyright (C) 2012 Gonzalo Odiard <gonzalo@laptop.org>
+# Based in code form Flavio Danesse <fdanesse@activitycentral.com>
+# and Ariel Calzada <ariel.calzada@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+import gtk
+
+FONT_BLACKLIST = ['cmex10', 'cmmi10', 'cmr10', 'cmsy10', 'esint10', 'eufm10',
+ 'msam10', 'msbm10', 'rsfs10', 'wasy10']
+
+
+class FontComboBox(gtk.ComboBox):
+
+ def __init__(self):
+ gtk.ComboBox.__init__(self)
+ font_renderer = gtk.CellRendererText()
+ self.pack_start(font_renderer)
+ self.add_attribute(font_renderer, 'text', 0)
+ self.add_attribute(font_renderer, 'font', 0)
+ font_model = gtk.ListStore(str)
+
+ context = self.get_pango_context()
+ font_index = 0
+ self.faces = {}
+
+ for family in context.list_families():
+ name = family.get_name()
+ if name not in FONT_BLACKLIST:
+ font_model.append([name])
+ font_faces = []
+ for face in family.list_faces():
+ face_name = face.get_face_name()
+ font_faces.append(face_name)
+ self.faces[name] = font_faces
+
+ sorter = gtk.TreeModelSort(font_model)
+ sorter.set_sort_column_id(0, gtk.SORT_ASCENDING)
+ self.set_model(sorter)
+ self.show()
+
+ def set_font_name(self, font_name):
+ count = 0
+ tree_iter = self.get_model().get_iter_first()
+ while tree_iter is not None:
+ value = self.get_model().get_value(tree_iter, 0)
+ if value == font_name:
+ self.set_active(count)
+ count = count + 1
+ tree_iter = self.get_model().iter_next(tree_iter)
+
+ def get_font_name(self):
+ tree_iter = self.get_active_iter()
+ return self.get_model().get_value(tree_iter, 0)
diff --git a/memorize.dtd b/memorize.dtd
index 3c1fc15..d361d47 100644
--- a/memorize.dtd
+++ b/memorize.dtd
@@ -10,7 +10,9 @@
face1 CDATA #IMPLIED
face2 CDATA #IMPLIED
align CDATA #IMPLIED
- equal_pairs CDATA #IMPLIED
+ equal_pairs CDATA #IMPLIED
+ font_name1 CDATA #IMPLIED
+ font_name2 CDATA #IMPLIED
>
<!ELEMENT pair (#PCDATA)* >
diff --git a/model.py b/model.py
index cc0e608..2567ed2 100644
--- a/model.py
+++ b/model.py
@@ -28,6 +28,8 @@ from sugar.activity.activity import get_bundle_path, get_activity_root
_logger = logging.getLogger('model')
+DEFAULT_FONT = 'Sans'
+
class Pair(gobject.GObject):
__gproperties__ = {
@@ -118,6 +120,8 @@ class Model(object):
self.data['align'] = '1'
self.data['divided'] = '0'
self.data['equal_pairs'] = '0'
+ self.data['font_name1'] = DEFAULT_FONT
+ self.data['font_name2'] = DEFAULT_FONT
try:
self.dtd = libxml2.parseDTD(None, join(get_bundle_path(),
@@ -218,6 +222,10 @@ class Model(object):
self.data['align'] = attribute.content
elif(attribute.name == 'equal_pairs'):
self.data['equal_pairs'] = attribute.content
+ elif(attribute.name == 'font_name1'):
+ self.data['font_name1'] = attribute.content
+ elif(attribute.name == 'font_name2'):
+ self.data['font_name2'] = attribute.content
xpa.xpathFreeContext()
else:
_logger.error('Read: Error in validation of the file')
@@ -246,7 +254,10 @@ class Model(object):
if(self.data.get('equal_pairs', None) != None):
root.setProp('equal_pairs', self.data['equal_pairs'])
-
+ if(self.data.get('font_name1', None) != None):
+ root.setProp('font_name1', self.data['font_name1'])
+ if(self.data.get('font_name2', None) != None):
+ root.setProp('font_name2', self.data['font_name2'])
if(self.data.get('scoresnd', None) != None):
root.setProp("scoresnd", self.data['scoresnd'])
if(self.data.get('winsnd', None) != None):
diff --git a/svgcard.py b/svgcard.py
index 7500f3f..631640e 100644
--- a/svgcard.py
+++ b/svgcard.py
@@ -29,6 +29,7 @@ from sugar.util import LRU
import theme
import face
import speak.voice
+import model
_logger = logging.getLogger('memorize-activity')
@@ -57,7 +58,7 @@ class SvgCard(gtk.EventBox):
cache = {}
def __init__(self, identifier, pprops, jpeg, size,
- align, bg_color='#000000'):
+ align, bg_color='#000000', font_name=model.DEFAULT_FONT):
gtk.EventBox.__init__(self)
self.bg_color = bg_color
@@ -70,6 +71,7 @@ class SvgCard(gtk.EventBox):
self.size = size
self.align = align
self.text_layouts = [None, None]
+ self.font_name = font_name
self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bg_color))
self.set_size_request(size, size)
@@ -300,7 +302,7 @@ class SvgCard(gtk.EventBox):
layout = self.create_pango_layout(text)
layout.set_width(PIXELS_PANGO(card_size))
layout.set_wrap(pango.WRAP_WORD)
- desc = pango.FontDescription('Deja Vu Sans bold ' + str(size))
+ desc = pango.FontDescription(self.font_name + " " + str(size))
layout.set_font_description(desc)
if layout.get_line_count() <= max_lines_count and \
@@ -317,6 +319,17 @@ class SvgCard(gtk.EventBox):
return layout
+ def change_font(self, font_name):
+ # remove from local cache
+ self.text_layouts[self.flipped] = False
+ text = self.props['front_text']['card_text']
+ key = (self.size, text)
+ if key in _text_layout_cache:
+ del _text_layout_cache[key]
+
+ self.font_name = font_name
+ self.queue_draw()
+
def set_background(self, color):
self.bg_color = color
self.draw.modify_bg(gtk.STATE_NORMAL,