# -*- coding: UTF-8 -*-
# toolbars.py, see CalcActivity.py for info
import pygtk
pygtk.require('2.0')
import gtk
from mathlib import MathLib
from sugar.graphics.palette import Palette
from sugar.graphics.menuitem import MenuItem
from sugar.graphics.toolbutton import ToolButton
from sugar.graphics.toggletoolbutton import ToggleToolButton
import logging
_logger = logging.getLogger('calc-activity')
from gettext import gettext as _
def _icon_exists(name):
if name == '':
return False
theme = gtk.icon_theme_get_default()
info = theme.lookup_icon(name, 0, 0)
if info:
return True
return False
class IconToolButton(ToolButton):
def __init__(self, icon_name, text, cb, help_cb=None, alt_html=''):
ToolButton.__init__(self)
if _icon_exists(icon_name):
self.set_icon(icon_name)
else:
if alt_html == '':
alt_html = icon_name
label = gtk.Label()
label.set_markup(alt_html)
label.show()
self.set_label_widget(label)
self.create_palette(text, help_cb)
self.connect('clicked', cb)
def create_palette(self, text, help_cb):
p = Palette(text)
if help_cb is not None:
item = MenuItem(_('Help'), 'action-help')
item.connect('activate', help_cb)
item.show()
p.menu.append(item)
self.set_palette(p)
class IconToggleToolButton(ToggleToolButton):
def __init__(self, items, cb, desc):
ToggleToolButton.__init__(self)
self.items = items
if _icon_exists(items[0]['icon']):
self.set_named_icon(items[0]['icon'])
else:
self.set_label(items[0]['html'])
# self.set_tooltip(items[0][1])
self.set_tooltip(desc)
self.selected = 0
self.connect('clicked', self.toggle_button)
self.callback = cb
def toggle_button(self, w):
self.selected = (self.selected + 1) % len(self.items)
but = self.items[self.selected]
if _icon_exists(but['icon']):
self.set_named_icon(but['icon'])
else:
self.set_label(but['html'])
# self.set_tooltip(but[1])
if self.callback is not None:
self.callback(but)
class TextToggleToolButton(gtk.ToggleToolButton):
def __init__(self, items, cb, index=False):
gtk.ToggleToolButton.__init__(self)
self.items = items
self.set_label(items[0])
self.selected = 0
self.connect('clicked', self.toggle_button)
self.callback = cb
self.index = index
def toggle_button(self, w):
self.selected = (self.selected + 1) % len(self.items)
but = self.items[self.selected]
self.set_label(but)
if self.callback is not None:
if self.index:
self.callback(self.selected)
else:
self.callback(but)
class LineSeparator(gtk.SeparatorToolItem):
def __init__(self):
gtk.SeparatorToolItem.__init__(self)
self.set_draw(True)
class EditToolbar(gtk.Toolbar):
def __init__(self, calc):
gtk.Toolbar.__init__(self)
self.insert(IconToolButton('edit-copy', _('Copy'),
lambda x: calc.text_copy(),
alt_html='Copy'), -1)
self.insert(IconToolButton('edit-paste', _('Paste'),
lambda x: calc.text_paste(),
alt_html='Paste'), -1)
self.insert(IconToolButton('edit-cut', _('Cut'),
lambda x: calc.text_cut(),
alt_html='Cut'), -1)
class AlgebraToolbar(gtk.Toolbar):
def __init__(self, calc):
gtk.Toolbar.__init__(self)
self.insert(IconToolButton('algebra-square', _('Square'),
lambda x: calc.button_pressed(calc.TYPE_OP_POST, '^2'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(square)'),
alt_html='x2'), -1)
self.insert(IconToolButton('algebra-sqrt', _('Square root'),
lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'sqrt'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(sqrt)'),
alt_html='√x'), -1)
self.insert(IconToolButton('algebra-xinv', _('Inverse'),
lambda x: calc.button_pressed(calc.TYPE_OP_POST, '^-1'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(inv)'),
alt_html='x-1'), -1)
self.insert(LineSeparator(), -1)
self.insert(IconToolButton('algebra-exp', _('e to the power x'),
lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'exp'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(exp)'),
alt_html='ex'), -1)
self.insert(IconToolButton('algebra-xpowy', _('x to the power y'),
lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'pow'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(pow)'),
alt_html='xy'), -1)
self.insert(IconToolButton('algebra-ln', _('Natural logarithm'),
lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'ln'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(ln)')), -1)
self.insert(LineSeparator(), -1)
self.insert(IconToolButton('algebra-fac', _('Factorial'),
lambda x: calc.button_pressed(calc.TYPE_OP_POST, '!'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(fac)')), -1)
class TrigonometryToolbar(gtk.Toolbar):
def __init__(self, calc):
gtk.Toolbar.__init__(self)
self.insert(IconToolButton('trigonometry-sin', _('Sine'),
lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'sin'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(sin)')), -1)
self.insert(IconToolButton('trigonometry-cos', _('Cosine'),
lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'cos'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(cos)')), -1)
self.insert(IconToolButton('trigonometry-tan', _('Tangent'),
lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'tan'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(tan)')), -1)
self.insert(LineSeparator(), -1)
self.insert(IconToolButton('trigonometry-asin', _('Arc sine'),
lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'asin'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(asin)')), -1)
self.insert(IconToolButton('trigonometry-acos', _('Arc cosine'),
lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'acos'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(acos)')), -1)
self.insert(IconToolButton('trigonometry-atan', _('Arc tangent'),
lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'atan'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(atan)')), -1)
self.insert(LineSeparator(), -1)
self.insert(IconToolButton('trigonometry-sinh', _('Hyperbolic sine'),
lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'sinh'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(sinh)')), -1)
self.insert(IconToolButton('trigonometry-cosh', _('Hyperbolic cosine'),
lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'cosh'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(cosh)')), -1)
self.insert(IconToolButton('trigonometry-tanh', _('Hyperbolic tangent'),
lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'tanh'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(tanh)')), -1)
class BooleanToolbar(gtk.Toolbar):
def __init__(self, calc):
gtk.Toolbar.__init__(self)
self.insert(IconToolButton('boolean-and', _('Logical and'),
lambda x: calc.button_pressed(calc.TYPE_OP_POST, '&'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(and))')), -1)
self.insert(IconToolButton('boolean-or', _('Logical or'),
lambda x: calc.button_pressed(calc.TYPE_OP_POST, '|'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(or)')), -1)
# self.insert(IconToolButton('boolean-xor', _('Logical xor'),
# lambda x: calc.button_pressed(calc.TYPE_OP_POST, '^'),
# lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(xor)')), -1)
self.insert(LineSeparator(), -1)
self.insert(IconToolButton('boolean-eq', _('Equals'),
lambda x: calc.button_pressed(calc.TYPE_OP_POST, '=')), -1)
self.insert(IconToolButton('boolean-neq', _('Not equals'),
lambda x: calc.button_pressed(calc.TYPE_OP_POST, '!=')), -1)
class MiscToolbar(gtk.Toolbar):
def __init__(self, calc):
gtk.Toolbar.__init__(self)
self.insert(IconToolButton('constants-pi', _('Pi'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'pi'),
alt_html='π'), -1)
self.insert(IconToolButton('constants-e', _('e'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'e')), -1)
self.insert(LineSeparator(), -1)
el = [
{'icon': 'format-deg', 'desc': _('Degrees'), 'html': 'Deg'},
{'icon': 'format-rad', 'desc': _('Radians'), 'html': 'Rad'},
]
self.insert(IconToggleToolButton(el,
lambda x: self.update_angle_type(x, calc),
_('Degrees / radians')), -1)
self.insert(LineSeparator(), -1)
self.insert(IconToolButton('plot', _('Plot'),
lambda x: calc.button_pressed(calc.TYPE_FUNCTION, 'plot'),
lambda x: calc.button_pressed(calc.TYPE_TEXT, 'help(plot)')), -1)
def update_angle_type(self, text, calc):
if text == 'deg':
calc.ml.set_angle_type(MathLib.ANGLE_DEG)
elif text == 'rad':
calc.ml.set_angle_type(MathLib.ANGLE_RAD)
_logger.debug('Angle type: %s', self.ml.angle_scaling)