1#!/usr/bin/env python 2# -*- mode: python; coding: utf-8; -*- 3# --------------------------------------------------------------------------- 4# 5# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer 6# Copyright (C) 2003 Mt. Hood Playing Card Co. 7# Copyright (C) 2005-2009 Skomoroh 8# 9# This program is free software: you can redistribute it and/or modify 10# it under the terms of the GNU General Public License as published by 11# the Free Software Foundation, either version 3 of the License, or 12# (at your option) any later version. 13# 14# This program is distributed in the hope that it will be useful, 15# but WITHOUT ANY WARRANTY; without even the implied warranty of 16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17# GNU General Public License for more details. 18# 19# You should have received a copy of the GNU General Public License 20# along with this program. If not, see <http://www.gnu.org/licenses/>. 21# 22# --------------------------------------------------------------------------- 23 24from pysollib.mfxutil import KwStruct 25from pysollib.mygettext import _ 26from pysollib.ui.tktile.tkutil import bind 27 28from six.moves import tkinter 29from six.moves import tkinter_font 30from six.moves import tkinter_ttk as ttk 31 32from .tkwidget import MfxDialog 33from .tkwidget import PysolScale 34 35 36# ************************************************************************ 37# * 38# ************************************************************************ 39 40class FontChooserDialog(MfxDialog): 41 def __init__(self, parent, title, init_font, **kw): 42 # print init_font 43 kw = self.initKw(kw) 44 MfxDialog.__init__(self, parent, title, kw.resizable, kw.default) 45 top_frame, bottom_frame = self.createFrames(kw) 46 self.createBitmaps(top_frame, kw) 47 48 self.font_family = 'Helvetica' 49 self.font_size = 12 50 self.font_weight = 'normal' 51 self.font_slant = 'roman' 52 53 if init_font is not None: 54 assert 2 <= len(init_font) <= 4 55 assert isinstance(init_font[1], int) 56 self.font_family, self.font_size = init_font[:2] 57 if len(init_font) > 2: 58 if init_font[2] in ['bold', 'normal']: 59 self.font_weight = init_font[2] 60 elif init_font[2] in ['italic', 'roman']: 61 self.font_slant = init_font[2] 62 else: 63 raise ValueError('invalid font style: '+init_font[2]) 64 if len(init_font) > 3: 65 if init_font[3] in ['bold', 'normal']: 66 self.font_weight = init_font[3] 67 elif init_font[2] in ['italic', 'roman']: 68 self.font_slant = init_font[3] 69 else: 70 raise ValueError('invalid font style: '+init_font[3]) 71 72 # self.family_var = tkinter.StringVar() 73 self.weight_var = tkinter.BooleanVar() 74 self.weight_var.set(self.font_weight == 'bold') 75 self.slant_var = tkinter.BooleanVar() 76 self.slant_var.set(self.font_slant == 'italic') 77 self.size_var = tkinter.IntVar() 78 self.size_var.set(self.font_size) 79 # 80 frame = ttk.Frame(top_frame) 81 frame.pack(expand=True, fill='both', padx=5, pady=10) 82 frame.columnconfigure(0, weight=1) 83 # frame.rowconfigure(1, weight=1) 84 self.entry = ttk.Entry(frame) 85 self.entry.grid(row=0, column=0, columnspan=2, sticky='news') 86 self.entry.insert('end', _('abcdefghABCDEFGH')) 87 self.list_box = tkinter.Listbox(frame, width=36, exportselection=False) 88 sb = ttk.Scrollbar(frame) 89 self.list_box.configure(yscrollcommand=sb.set) 90 sb.configure(command=self.list_box.yview) 91 self.list_box.grid(row=1, column=0, sticky='news') # rowspan=4 92 sb.grid(row=1, column=1, sticky='ns') 93 bind(self.list_box, '<<ListboxSelect>>', self.fontupdate) 94 # self.list_box.focus() 95 cb1 = ttk.Checkbutton(frame, text=_('Bold'), 96 command=self.fontupdate, 97 variable=self.weight_var) 98 cb1.grid(row=2, column=0, columnspan=2, sticky='we') 99 cb2 = ttk.Checkbutton(frame, text=_('Italic'), 100 command=self.fontupdate, 101 variable=self.slant_var) 102 cb2.grid(row=3, column=0, columnspan=2, sticky='we') 103 104 sc = PysolScale(frame, from_=6, to=40, resolution=1, 105 label=_('Size:'), orient='horizontal', 106 command=self.fontupdate, variable=self.size_var) 107 sc.grid(row=4, column=0, columnspan=2, sticky='news') 108 # 109 font_families = list(tkinter_font.families()) 110 font_families.sort() 111 selected = -1 112 n = 0 113 self.list_box.insert('end', *font_families) 114 for font in font_families: 115 if font.lower() == self.font_family.lower(): 116 selected = n 117 break 118 n += 1 119 if selected >= 0: 120 self.list_box.select_set(selected) 121 self.list_box.see(selected) 122 # 123 focus = self.createButtons(bottom_frame, kw) 124 self.mainloop(focus, kw.timeout) 125 126 self.font = (self.font_family, self.font_size, 127 self.font_slant, self.font_weight) 128 129 def fontupdate(self, *args): 130 if self.list_box.curselection(): 131 self.font_family = self.list_box.get(self.list_box.curselection()) 132 self.font_weight = self.weight_var.get() and 'bold' or 'normal' 133 self.font_slant = self.slant_var.get() and 'italic' or 'roman' 134 self.font_size = self.size_var.get() 135 self.entry.configure(font=(self.font_family, self.font_size, 136 self.font_slant, self.font_weight)) 137 138 def initKw(self, kw): 139 kw = KwStruct(kw, 140 strings=(_("&OK"), _("&Cancel")), 141 default=0, 142 ) 143 return MfxDialog.initKw(self, kw) 144 145# ************************************************************************ 146# * 147# ************************************************************************ 148 149 150class FontsDialog(MfxDialog): 151 def __init__(self, parent, title, app, **kw): 152 kw = self.initKw(kw) 153 MfxDialog.__init__(self, parent, title, kw.resizable, kw.default) 154 top_frame, bottom_frame = self.createFrames(kw) 155 self.createBitmaps(top_frame, kw) 156 157 frame = ttk.Frame(top_frame) 158 frame.pack(expand=True, fill='both', padx=5, pady=10) 159 frame.columnconfigure(0, weight=1) 160 161 self.fonts = {} 162 row = 0 163 for fn, title in ( # ('default', _('Default')), 164 ('sans', _('HTML: ')), 165 ('small', _('Small: ')), 166 ('fixed', _('Fixed: ')), 167 ('canvas_default', _('Tableau default: ')), 168 ('canvas_fixed', _('Tableau fixed: ')), 169 ('canvas_large', _('Tableau large: ')), 170 ('canvas_small', _('Tableau small: ')), 171 ): 172 font = app.opt.fonts[fn] 173 self.fonts[fn] = font 174 ttk.Label(frame, text=title, anchor='w' 175 ).grid(row=row, column=0, sticky='we') 176 if font: 177 title = ' '.join( 178 [str(i) for i in font if i not in ('roman', 'normal')]) 179 elif font is None: 180 title = 'Default' 181 label = ttk.Label(frame, font=font, text=title) 182 label.grid(row=row, column=1, padx=8) 183 b = ttk.Button(frame, text=_('Change...'), width=10, 184 command=lambda label=label, 185 fn=fn: self.selectFont(label, fn)) 186 b.grid(row=row, column=2) 187 row += 1 188 # 189 focus = self.createButtons(bottom_frame, kw) 190 self.mainloop(focus, kw.timeout) 191 192 def selectFont(self, label, fn): 193 d = FontChooserDialog(self.top, _('Select font'), self.fonts[fn]) 194 if d.status == 0 and d.button == 0: 195 self.fonts[fn] = d.font 196 title = ' '.join( 197 [str(i) for i in d.font if i not in ('roman', 'normal')]) 198 label.configure(font=d.font, text=title) 199 200 def initKw(self, kw): 201 kw = KwStruct(kw, 202 strings=(_('&OK'), _('&Cancel')), 203 default=0, 204 ) 205 return MfxDialog.initKw(self, kw) 206