diff options
author | Gonzalo Odiard <godiard@gmail.com> | 2012-04-16 19:00:09 (GMT) |
---|---|---|
committer | Gonzalo Odiard <godiard@gmail.com> | 2012-04-17 18:11:36 (GMT) |
commit | 7ed15ed98ee5f2a53a5dac8a75381bac6196c19e (patch) | |
tree | ef01c2e006c97cd6ae4daac6004239aa1a6e7a6d | |
parent | 862171dbe24dbf6e877a672b22c14ac493bb096a (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.py | 4 | ||||
-rw-r--r-- | cardlist.py | 31 | ||||
-rw-r--r-- | cardtable.py | 7 | ||||
-rw-r--r-- | createcardpanel.py | 67 | ||||
-rw-r--r-- | fontcombobox.py | 65 | ||||
-rw-r--r-- | memorize.dtd | 4 | ||||
-rw-r--r-- | model.py | 13 | ||||
-rw-r--r-- | svgcard.py | 17 |
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)* > @@ -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): @@ -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, |