From 2e8bd12f8bcf9da314d853078ee29f35a381c537 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Thu, 15 Feb 2007 18:48:58 +0100 Subject: [PATCH] Rework color and fonts to be more pytonish. Add units conversions. --- sugar/graphics/Makefile.am | 5 +- sugar/graphics/color.py | 81 +++++++++++++++++++++++++ sugar/graphics/entry.py | 22 +++---- sugar/graphics/font.py | 23 ++++++++ sugar/graphics/frame.py | 4 +- sugar/graphics/label.py | 10 ++-- sugar/graphics/optionmenu.py | 20 +++---- sugar/graphics/roundbox.py | 4 +- sugar/graphics/style.py | 111 ----------------------------------- sugar/graphics/units.py | 12 ++++ tests/test-entry.py | 1 - tests/test-label.py | 1 - tests/test-option-menu.py | 1 - 13 files changed, 150 insertions(+), 145 deletions(-) create mode 100644 sugar/graphics/color.py create mode 100644 sugar/graphics/font.py create mode 100644 sugar/graphics/units.py diff --git a/sugar/graphics/Makefile.am b/sugar/graphics/Makefile.am index 04508325..11c25b5c 100644 --- a/sugar/graphics/Makefile.am +++ b/sugar/graphics/Makefile.am @@ -4,8 +4,10 @@ sugar_PYTHON = \ bubble.py \ button.py \ canvasicon.py \ + color.py \ ClipboardBubble.py \ entry.py \ + font.py \ frame.py \ grid.py \ iconcolor.py \ @@ -20,4 +22,5 @@ sugar_PYTHON = \ style.py \ stylesheet.py \ timeline.py \ - toolbar.py + toolbar.py \ + units.py diff --git a/sugar/graphics/color.py b/sugar/graphics/color.py new file mode 100644 index 00000000..4e3d8856 --- /dev/null +++ b/sugar/graphics/color.py @@ -0,0 +1,81 @@ +import gtk + +_system_colors = { + 'toolbar-background' : '#414141', + 'frame-border' : '#D1D1D2', + 'entry-background-focused' : '#FFFFFF', + 'entry-background-unfocused' : '#414141', + 'entry-selection-focused' : '#D1D1D2', + 'entry-selection-unfocused' : '#00FF00', + 'entry-text-focused' : '#000000', + 'entry-text-unfocused' : '#FFFFFF', + 'entry-border' : '#D1D1D2', + 'label-text' : '#FFFFFF', + 'desktop-background' : '#E2E2E3', + 'menu-background' : '#414141', + 'menu-separator' : '#D1D1D2', + 'menu-border' : '#D1D1D2' +} + +def _html_to_rgb(html_color): + """ #RRGGBB -> (r, g, b) tuple (in float format) """ + + html_color = html_color.strip() + if html_color[0] == '#': + html_color = html_color[1:] + if len(html_color) != 6: + raise ValueError, "input #%s is not in #RRGGBB format" % html_color + + r, g, b = html_color[:2], html_color[2:4], html_color[4:] + r, g, b = [int(n, 16) for n in (r, g, b)] + r, g, b = (r / 255.0, g / 255.0, b / 255.0) + + return (r, g, b) + +def _rgba_to_int(r, g, b, a): + color = int(a * 255) + (int(b * 255) << 8) + \ + (int(g * 255) << 16) + (int(r * 255) << 24) + return color + +class RGBColor(object): + def __init__(self, r, g, b, a=1.0): + self._r = r + self._g = g + self._b = b + self._a = a + + def get_rgba(self): + return (self._r, self._g, self._b, self._a) + + def get_int(self): + return _rgba_to_int(self._r, self._g, self._b, self._a) + + def get_gdk_color(self): + return gtk.gdk.Color(int(self._r * 65535), int(self._g * 65535), + int(self._b * 65535)) + +class SystemColor(RGBColor): + def __init__(self, color_id): + rgb = _html_to_rgb(_system_colors[color_id]) + RGBColor.__init__(self, *rgb) + +RED = RGBColor(1.0, 0.0, 0.0) +GREEN = RGBColor(0.0, 1.0, 0.0) +BLUE = RGBColor(0.0, 0.0, 1.0) +WHITE = RGBColor(1.0, 1.0, 1.0) +BLACK = RGBColor(0.0, 0.0, 0.0) + +TOOLBAR_BACKGROUND = SystemColor('toolbar-background') +FRAME_BORDER = SystemColor('frame-border') +ENTRY_BACKGROUND_FOCUSED = SystemColor('entry-background-focused') +ENTRY_BACKGROUND_UNFOCUSED = SystemColor('entry-background-unfocused') +ENTRY_SELECTION_FOCUSED = SystemColor('entry-selection-focused') +ENTRY_SELECTION_UNFOCUSED = SystemColor('entry-selection-unfocused') +ENTRY_TEXT_FOCUSED = SystemColor('entry-text-focused') +ENTRY_TEXT_UNFOCUSED = SystemColor('entry-text-unfocused') +ENTRY_BORDER = SystemColor('entry-border') +LABEL_TEXT = SystemColor('label-text') +DESKTOP_BACKGROUND = SystemColor('desktop-background') +MENU_BACKGROUND = SystemColor('menu-background') +MENU_SEPARATOR = SystemColor('menu-separator') +MENU_BORDER = SystemColor('menu-border') diff --git a/sugar/graphics/entry.py b/sugar/graphics/entry.py index 0af2f0df..fcaa3c59 100644 --- a/sugar/graphics/entry.py +++ b/sugar/graphics/entry.py @@ -22,8 +22,8 @@ import gtk import hippo from sugar.graphics import style -from sugar.graphics.style import Color -from sugar.graphics.style import Font +from sugar.graphics import color +from sugar.graphics import font from sugar.graphics.button import Button from sugar.graphics.roundbox import RoundBox @@ -57,7 +57,7 @@ class Entry(hippo.CanvasBox, hippo.CanvasItem): self._entry.connect('focus-in-event', self._entry_focus_in_event_cb) self._entry.connect('focus-out-event', self._entry_focus_out_event_cb) self._entry.connect('activate', self._entry_activate_cb) - self._entry.modify_font(Font.DEFAULT.get_pango_desc()) + self._entry.modify_font(font.DEFAULT.get_pango_desc()) self._canvas_widget = hippo.CanvasWidget() self._canvas_widget.props.widget = self._entry @@ -105,21 +105,21 @@ class Entry(hippo.CanvasBox, hippo.CanvasItem): def _update_colors(self, focused): if focused: self._round_box.props.background_color = \ - Color.ENTRY_BACKGROUND_FOCUSED.get_int() + color.ENTRY_BACKGROUND_FOCUSED.get_int() self._entry.modify_base(gtk.STATE_NORMAL, - Color.ENTRY_BACKGROUND_FOCUSED.get_gdk_color()) + color.ENTRY_BACKGROUND_FOCUSED.get_gdk_color()) self._entry.modify_base(gtk.STATE_SELECTED, - Color.ENTRY_SELECTION_FOCUSED.get_gdk_color()) + color.ENTRY_SELECTION_FOCUSED.get_gdk_color()) self._entry.modify_text(gtk.STATE_NORMAL, - Color.ENTRY_TEXT_FOCUSED.get_gdk_color()) + color.ENTRY_TEXT_FOCUSED.get_gdk_color()) else: self._round_box.props.background_color = \ - Color.ENTRY_BACKGROUND_UNFOCUSED.get_int() + color.ENTRY_BACKGROUND_UNFOCUSED.get_int() self._entry.modify_base(gtk.STATE_NORMAL, - Color.ENTRY_BACKGROUND_UNFOCUSED.get_gdk_color()) + color.ENTRY_BACKGROUND_UNFOCUSED.get_gdk_color()) self._entry.modify_base(gtk.STATE_SELECTED, - Color.ENTRY_SELECTION_UNFOCUSED.get_gdk_color()) + color.ENTRY_SELECTION_UNFOCUSED.get_gdk_color()) self._entry.modify_text(gtk.STATE_NORMAL, - Color.ENTRY_TEXT_UNFOCUSED.get_gdk_color()) + color.ENTRY_TEXT_UNFOCUSED.get_gdk_color()) diff --git a/sugar/graphics/font.py b/sugar/graphics/font.py new file mode 100644 index 00000000..023dc372 --- /dev/null +++ b/sugar/graphics/font.py @@ -0,0 +1,23 @@ +import pango + +from sugar.graphics import units + +_system_fonts = { + 'default' : 'Bitstream Vera Sans %d' % units.points_to_pixels(9) +} + +class Font(object): + def __init__(self, desc): + self._desc = desc + + def get_desc(self): + return self._desc + + def get_pango_desc(self): + return pango.FontDescription(self._desc) + +class SystemFont(Font): + def __init__(self, font_id): + Font.__init__(self, _system_fonts[font_id]) + +DEFAULT = SystemFont('default') diff --git a/sugar/graphics/frame.py b/sugar/graphics/frame.py index 16ad76c9..4b800fd6 100644 --- a/sugar/graphics/frame.py +++ b/sugar/graphics/frame.py @@ -15,7 +15,7 @@ # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. -from sugar.graphics.style import Color +from sugar.graphics import color from sugar.graphics.roundbox import RoundBox class Frame(RoundBox): @@ -23,4 +23,4 @@ class Frame(RoundBox): def __init__(self, **kwargs): RoundBox.__init__(self, **kwargs) - self.props.border_color = Color.FRAME_BORDER.get_int() + self.props.border_color = color.FRAME_BORDER.get_int() diff --git a/sugar/graphics/label.py b/sugar/graphics/label.py index 69caa1be..77519f2a 100644 --- a/sugar/graphics/label.py +++ b/sugar/graphics/label.py @@ -24,8 +24,8 @@ import hippo from sugar.graphics import style from sugar.graphics.roundbox import RoundBox from sugar.graphics.button import Button -from sugar.graphics.style import Color -from sugar.graphics.font import Font +from sugar.graphics import color +from sugar.graphics import font class Label(hippo.CanvasBox, hippo.CanvasItem): __gtype_name__ = 'SugarLabel' @@ -42,13 +42,13 @@ class Label(hippo.CanvasBox, hippo.CanvasItem): self._text = text self._round_box = RoundBox() - self._round_box.props.border_color = Color.FRAME_BORDER.get_int() + self._round_box.props.border_color = color.FRAME_BORDER.get_int() self.append(self._round_box, hippo.PACK_EXPAND) self._canvas_text = hippo.CanvasText() self._canvas_text.props.text = self._text - self._canvas_text.props.color = Color.LABEL_TEXT.get_int() - self._canvas_text.props.font_desc = Font.DEFAULT.get_pango_desc() + self._canvas_text.props.color = color.LABEL_TEXT.get_int() + self._canvas_text.props.font_desc = font.DEFAULT.get_pango_desc() self._round_box.append(self._canvas_text, hippo.PACK_EXPAND) def do_set_property(self, pspec, value): diff --git a/sugar/graphics/optionmenu.py b/sugar/graphics/optionmenu.py index a8084388..72ea678c 100644 --- a/sugar/graphics/optionmenu.py +++ b/sugar/graphics/optionmenu.py @@ -25,8 +25,8 @@ import hippo from sugar.graphics import style from sugar.graphics.roundbox import RoundBox from sugar.graphics.button import Button -from sugar.graphics.style import Color -from sugar.graphics.style import Font +from sugar.graphics import color +from sugar.graphics import font from sugar.graphics.canvasicon import CanvasIcon class Menu(hippo.CanvasBox, hippo.CanvasItem): @@ -38,8 +38,8 @@ class Menu(hippo.CanvasBox, hippo.CanvasItem): def __init__(self): hippo.CanvasBox.__init__(self) - self.props.background_color = Color.MENU_BACKGROUND.get_int() - self.props.border_color = Color.MENU_BORDER.get_int() + self.props.background_color = color.MENU_BACKGROUND.get_int() + self.props.border_color = color.MENU_BORDER.get_int() #TODO: how we should specify the border thickness? self.props.border = style.separator_thickness self._window = None @@ -56,8 +56,8 @@ class Menu(hippo.CanvasBox, hippo.CanvasItem): canvas_text = hippo.CanvasText() canvas_text.props.text = label - canvas_text.props.color = Color.LABEL_TEXT.get_int() - canvas_text.props.font_desc = Font.DEFAULT.get_pango_desc() + canvas_text.props.color = color.LABEL_TEXT.get_int() + canvas_text.props.font_desc = font.DEFAULT.get_pango_desc() box.append(canvas_text) box.connect('button-press-event', self._button_press_event_cb, action_id) @@ -65,7 +65,7 @@ class Menu(hippo.CanvasBox, hippo.CanvasItem): def add_separator(self): box = hippo.CanvasBox() - box.props.background_color = Color.MENU_SEPARATOR.get_int() + box.props.background_color = color.MENU_SEPARATOR.get_int() box.props.box_height = style.separator_thickness self.append(box) @@ -105,13 +105,13 @@ class OptionMenu(hippo.CanvasBox, hippo.CanvasItem): self._value = None self._round_box = RoundBox() - self._round_box.props.border_color = Color.FRAME_BORDER.get_int() + self._round_box.props.border_color = color.FRAME_BORDER.get_int() self.append(self._round_box, hippo.PACK_EXPAND) self._canvas_text = hippo.CanvasText() self._canvas_text.props.text = _('No options') - self._canvas_text.props.color = Color.LABEL_TEXT.get_int() - self._canvas_text.props.font_desc = Font.DEFAULT.get_pango_desc() + self._canvas_text.props.color = color.LABEL_TEXT.get_int() + self._canvas_text.props.font_desc = font.DEFAULT.get_pango_desc() self._round_box.append(self._canvas_text, hippo.PACK_EXPAND) # TODO: Substitute for the right icon. diff --git a/sugar/graphics/roundbox.py b/sugar/graphics/roundbox.py index b9580dec..9a2c9f61 100644 --- a/sugar/graphics/roundbox.py +++ b/sugar/graphics/roundbox.py @@ -20,7 +20,7 @@ import math import hippo from sugar.graphics import style -from sugar.graphics.style import Color +from sugar.graphics import color class RoundBox(hippo.CanvasBox, hippo.CanvasItem): __gtype_name__ = 'SugarRoundBox' @@ -38,7 +38,7 @@ class RoundBox(hippo.CanvasBox, hippo.CanvasItem): self.props.border_bottom = self._BORDER_DEFAULT self.props.border_left = self._radius self.props.border_right = self._radius - self.props.border_color = Color.BLACK.get_int() + self.props.border_color = color.BLACK.get_int() def do_paint_background(self, cr, damaged_box): [width, height] = self.get_allocation() diff --git a/sugar/graphics/style.py b/sugar/graphics/style.py index 81f29616..3bfcb4ae 100644 --- a/sugar/graphics/style.py +++ b/sugar/graphics/style.py @@ -16,119 +16,8 @@ # Boston, MA 02111-1307, USA. import logging -import math import gtk -import pango - -import _sugar - -_screen_factor = gtk.gdk.screen_width() / 1200.0 -_dpi_factor = _sugar.get_screen_dpi() / 201.0 -_default_font_size = math.ceil(9 / _dpi_factor * _screen_factor) -print _default_font_size - -_system_colors = { - 'toolbar-background' : '#414141', - 'frame-border' : '#D1D1D2', - 'entry-background-focused' : '#FFFFFF', - 'entry-background-unfocused' : '#414141', - 'entry-selection-focused' : '#D1D1D2', - 'entry-selection-unfocused' : '#00FF00', - 'entry-text-focused' : '#000000', - 'entry-text-unfocused' : '#FFFFFF', - 'entry-border' : '#D1D1D2', - 'label-text' : '#FFFFFF', - 'desktop-background' : '#E2E2E3', - 'menu-background' : '#414141', - 'menu-separator' : '#D1D1D2', - 'menu-border' : '#D1D1D2' -} - -def _html_to_rgb(html_color): - """ #RRGGBB -> (r, g, b) tuple (in float format) """ - - html_color = html_color.strip() - if html_color[0] == '#': - html_color = html_color[1:] - if len(html_color) != 6: - raise ValueError, "input #%s is not in #RRGGBB format" % html_color - - r, g, b = html_color[:2], html_color[2:4], html_color[4:] - r, g, b = [int(n, 16) for n in (r, g, b)] - r, g, b = (r / 255.0, g / 255.0, b / 255.0) - - return (r, g, b) - -def _rgba_to_int(r, g, b, a): - color = int(a * 255) + (int(b * 255) << 8) + \ - (int(g * 255) << 16) + (int(r * 255) << 24) - return color - -class RGBColor(object): - def __init__(self, r, g, b, a=1.0): - self._r = r - self._g = g - self._b = b - self._a = a - - def get_rgba(self): - return (self._r, self._g, self._b, self._a) - - def get_int(self): - return _rgba_to_int(self._r, self._g, self._b, self._a) - - def get_gdk_color(self): - return gtk.gdk.Color(int(self._r * 65535), int(self._g * 65535), - int(self._b * 65535)) - -class SystemColor(RGBColor): - def __init__(self, color_id): - rgb = _html_to_rgb(_system_colors[color_id]) - RGBColor.__init__(self, *rgb) - -class Color(object): - RED = RGBColor(1.0, 0.0, 0.0) - GREEN = RGBColor(0.0, 1.0, 0.0) - BLUE = RGBColor(0.0, 0.0, 1.0) - WHITE = RGBColor(1.0, 1.0, 1.0) - BLACK = RGBColor(0.0, 0.0, 0.0) - - TOOLBAR_BACKGROUND = SystemColor('toolbar-background') - FRAME_BORDER = SystemColor('frame-border') - ENTRY_BACKGROUND_FOCUSED = SystemColor('entry-background-focused') - ENTRY_BACKGROUND_UNFOCUSED = SystemColor('entry-background-unfocused') - ENTRY_SELECTION_FOCUSED = SystemColor('entry-selection-focused') - ENTRY_SELECTION_UNFOCUSED = SystemColor('entry-selection-unfocused') - ENTRY_TEXT_FOCUSED = SystemColor('entry-text-focused') - ENTRY_TEXT_UNFOCUSED = SystemColor('entry-text-unfocused') - ENTRY_BORDER = SystemColor('entry-border') - LABEL_TEXT = SystemColor('label-text') - DESKTOP_BACKGROUND = SystemColor('desktop-background') - MENU_BACKGROUND = SystemColor('menu-background') - MENU_SEPARATOR = SystemColor('menu-separator') - MENU_BORDER = SystemColor('menu-border') - -_system_fonts = { - 'default' : 'Bitstream Vera Sans %d' % _default_font_size -} - -class BaseFont(object): - def __init__(self, desc): - self._desc = desc - - def get_desc(self): - return self._desc - - def get_pango_desc(self): - return pango.FontDescription(self._desc) - -class SystemFont(BaseFont): - def __init__(self, font_id): - BaseFont.__init__(self, _system_fonts[font_id]) - -class Font(object): - DEFAULT = SystemFont('default') ### Deprecated: we should drop this once we removed stylesheets ### diff --git a/sugar/graphics/units.py b/sugar/graphics/units.py new file mode 100644 index 00000000..fe39a9f8 --- /dev/null +++ b/sugar/graphics/units.py @@ -0,0 +1,12 @@ +import gtk + +import _sugar + +def points_to_pixels(points): + return points * _sugar.get_screen_dpi() / 72.0 + +def grid_to_pixels(units): + return units * gtk.gdk.screen_width() / 16 + +def microgrid_to_pixels(units): + return units * gtk.gdk.screen_width() / 80 diff --git a/tests/test-entry.py b/tests/test-entry.py index c87a5ae2..10beaa20 100755 --- a/tests/test-entry.py +++ b/tests/test-entry.py @@ -22,7 +22,6 @@ from sugar.graphics.toolbar import Toolbar from sugar.graphics.frame import Frame from sugar.graphics.button import Button from sugar.graphics.entry import Entry -from sugar.graphics.style import Color def _entry_activated_cb(entry): print "_entry_activated_cb" diff --git a/tests/test-label.py b/tests/test-label.py index 0ddfc176..eaefa4e2 100755 --- a/tests/test-label.py +++ b/tests/test-label.py @@ -21,7 +21,6 @@ import hippo from sugar.graphics.toolbar import Toolbar from sugar.graphics.label import Label from sugar.graphics.button import Button -from sugar.graphics.style import Color import os theme = gtk.icon_theme_get_default() diff --git a/tests/test-option-menu.py b/tests/test-option-menu.py index 856c0f5b..ea627ed8 100755 --- a/tests/test-option-menu.py +++ b/tests/test-option-menu.py @@ -24,7 +24,6 @@ import hippo from sugar.graphics.toolbar import Toolbar from sugar.graphics.optionmenu import OptionMenu -from sugar.graphics.style import Color from sugar.graphics.button import Button def _option_menu_changed_cb(option_menu):