diff options
author | Daniel Francis <francis@sugarlabs.org> | 2012-11-26 00:10:49 (GMT) |
---|---|---|
committer | Daniel Francis <francis@sugarlabs.org> | 2012-11-26 00:10:49 (GMT) |
commit | bf48971a2ac991a6562c3558542c092ab2f9d56b (patch) | |
tree | fb296212c9ddfbbfbb10575ea3fa931fad7ca860 |
Initial commit
Signed-off-by: Daniel Francis <francis@sugarlabs.org>
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | __init__.py | 52 | ||||
-rw-r--r-- | clef.py | 53 | ||||
-rw-r--r-- | instrument.py | 66 | ||||
-rw-r--r-- | piano.py | 44 | ||||
-rw-r--r-- | staff.py | 63 | ||||
-rw-r--r-- | track.py | 81 |
7 files changed, 362 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..95401e0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.pyc +*.pyo +*~ diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..14eb76d --- /dev/null +++ b/__init__.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 S. Daniel Francis <francis@sugarlabs.org> +# +# 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 3 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 Street, Fifth Floor, Boston, +# MA 02110-1301, USA. + +# This code is from an abandoned musical editor + +from gi.repository import Gtk +from gi.repository import Gdk + +from track import Track + + +class StaffArea(Gtk.DrawingArea): + height = 0 + width = 0 + tracks = [] + + def __init__(self): + Gtk.DrawingArea.__init__(self) + self.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse('#FFF')) + self.connect('draw', self._draw_cb) + self.connect('size-allocate', self.__allocate_cb) + self.tracks.append(Track()) + + def __allocate_cb(self, widget, rect): + self.width = rect.width + self.height = rect.height + + def _draw_cb(self, widget, ctx): + window = widget.get_window() + context = widget.create_pango_context() + width = self.width + height = self.height + for track in self.tracks: + track.linespacing = height * 0.05 + track.draw(window, width, context) @@ -0,0 +1,53 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2012 S. Daniel Francis <francis@sugarlabs.org> +# +# 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 3 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 os + +import cairo +from gi.repository import Rsvg + +CLEF_C3 = 0 +CLEF_C4 = 1 +CLEF_F = 2 +CLEF_G = 3 + + +class Clef: + clef_type = CLEF_G + clefs = [Rsvg.Handle.new_from_file(os.path.join(os.environ['SUGAR_BUNDLE_PATH'], + 'symbols/Cclef3.svg')), + Rsvg.Handle.new_from_file(os.path.join(os.environ['SUGAR_BUNDLE_PATH'], + 'symbols/Cclef4.svg')), + Rsvg.Handle.new_from_file(os.path.join(os.environ['SUGAR_BUNDLE_PATH'], + 'symbols/Fclef.svg')), + Rsvg.Handle.new_from_file(os.path.join(os.environ['SUGAR_BUNDLE_PATH'], + 'symbols/Gclef.svg'))] + + def __init__(self): + pass + + def draw(self, context, xcorner, ytop, width, height): + svg = self.clefs[self.clef_type] + matrix = cairo.Matrix(xx=width / svg.props.width, + yy=height / svg.props.height, + x0=xcorner, + y0=ytop) + context.transform(matrix) + svg.render_cairo(context) + context.clip() diff --git a/instrument.py b/instrument.py new file mode 100644 index 0000000..b1d3cfd --- /dev/null +++ b/instrument.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 S. Daniel Francis <francis@sugarlabs.org> +# +# 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 3 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 Street, Fifth Floor, Boston, +# MA 02110-1301, USA. + +import os + +import logging +logger = logging.getLogger('instrument') + +import cairo +from gi.repository import Rsvg + + +class Instrument: + staves = [] + name = '' + ymin = 0 + ymax = 0 + show_bracket = False + staffx = 0 + + def __init__(self): + self.svg = Rsvg.Handle.new_from_file(os.path.join( + os.environ['SUGAR_BUNDLE_PATH'], 'symbols/accolade.svg')) + + def draw(self, window, width, lmarg, rmarg, linespacing): + accolade_cr = window.cairo_create() + + xx = lmarg * 0.03 + x0 = lmarg * 0.20 + y0 = linespacing * 1.5 + self.staffx = lmarg + lmarg * 0.20 + for staff in self.staves: + staff.lmarg = self.staffx + staff.rmarg = rmarg + staff.spacing = linespacing + staff.y = self.ymax + staff.draw(window, width) + self.ymax = staff.ymax + yy = (self.ymax - self.ymin - linespacing) / self.svg.props.height + matrix = cairo.Matrix(xx=xx, + yy=yy, + x0=x0, + y0=y0) + accolade_cr.transform(matrix) + self.svg.render_cairo(accolade_cr) + accolade_cr.clip() + + def guess_height(self, linespace): + return len(self.staves) * linespace * 8 diff --git a/piano.py b/piano.py new file mode 100644 index 0000000..1be56fd --- /dev/null +++ b/piano.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 S. Daniel Francis <francis@sugarlabs.org> +# +# 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 3 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 Street, Fifth Floor, Boston, +# MA 02110-1301, USA. + +from gettext import gettext as _ + +from staff import Beat +from staff import Staff +from instrument import Instrument +import clef + + +class Piano(Instrument): + name = _('Piano') + + def __init__(self): + Instrument.__init__(self) + top_beat = Beat() + top_beat.clef = clef.Clef() + top_staff = Staff(top_beat) + + bottom_beat = Beat() + bottom_beat.clef = clef.Clef() + bottom_beat.clef.clef_type = clef.CLEF_F + bottom_staff = Staff(bottom_beat) + + self.staves.append(top_staff) + self.staves.append(bottom_staff) diff --git a/staff.py b/staff.py new file mode 100644 index 0000000..152e97d --- /dev/null +++ b/staff.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 S. Daniel Francis <francis@sugarlabs.org> +# +# 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 3 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 Street, Fifth Floor, Boston, +# MA 02110-1301, USA. + +import logging +logger = logging.getLogger('staff') + + +class Beat: + clef = None + + +class Staff: + y = 0 + lmarg = 0 + rmarg = 0 + spacing = 0 + ymax = 0 + + def __init__(self, beat): + self.beats = [] + self.beats.append(beat) + logger.debug(self.beats) + + def draw(self, window, width): + context = window.cairo_create() + context.set_source_rgb(0, 0, 0) + context.set_line_width(2) + line_y = self.y + for i in range(5): + x = self.lmarg + context.move_to(x, line_y) + context.line_to(width - self.rmarg, line_y) + line_y += self.spacing + self.ymax = line_y + self.spacing + context.stroke() + context.clip() + self.draw_beats(window) + + def draw_beats(self, window): + for beat in self.beats: + if beat.clef != None: + beat.clef.draw(window.cairo_create(), + self.lmarg * 1.1, + self.y - self.spacing, + self.spacing * 2, + self.ymax - self.y) diff --git a/track.py b/track.py new file mode 100644 index 0000000..4927f1b --- /dev/null +++ b/track.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 S. Daniel Francis <francis@sugarlabs.org> +# +# 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 3 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 Street, Fifth Floor, Boston, +# MA 02110-1301, USA. + +from gi.repository import Pango +from gi.repository import PangoCairo + +from piano import Piano + + +class Track: + + def __init__(self): + self._y = 0 + self._linespacing = 10 + self.piano = Piano() + + def create_instrument_layout(self, name, pango_context): + layout = Pango.Layout(pango_context) + layout.set_font_description(Pango.FontDescription( + 'Century Schoolbook L Roman 20')) + layout.set_text(name, -1) + return layout + + def draw(self, window, width, pango_context): + lmarg = width * 0.03 + rmarg = width * 0.01 + self.piano.ymax = self.piano.ymin = self.linespacing * 2 + context = window.cairo_create() + layout = self.create_instrument_layout(self.piano.name, pango_context) + text_width, height = layout.get_pixel_size() + context.move_to(5, + self.linespacing * 10 * len(self.piano.staves) / 2 - height / 2) + #context.show_layout(layout) + self.piano.draw(window, width, lmarg, + rmarg, self.linespacing) + + #start and end line + context.set_line_width(2) + context.set_source_rgb(0, 0, 0) + context.move_to(self.piano.staffx, + self.piano.ymin) + context.line_to(self.piano.staffx, + self.piano.ymax - self.linespacing * 2) + context.stroke() + context.move_to(width - rmarg, self.piano.ymin) + context.line_to(width - rmarg, self.piano.ymax - self.linespacing * 2) + context.stroke() + context.clip() + + def set_y(self, y): + self._y = y + + def get_y(self): + return self.y + + y = property(get_y, set_y) + + def set_linespacing(self, value): + self._linespacing = value + + def get_linespacing(self): + return self._linespacing + + linespacing = property(get_linespacing, set_linespacing) |