Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(40)

Delta Between Two Patch Sets: scripts/auxiliar/skyline_viewer.py

Issue 5626052: Gets vertical skylines from grob stencils (Closed)
Left Patch Set: Fixes from Janek concerning lyrics and dynamics. Created 13 years ago
Right Patch Set: Run astyle on c++ files Created 12 years, 6 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« lily/skyline.cc ('K') | « scripts/auxiliar/show_skyline_command.py ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 #!/usr/bin/env python
2
3 # This file is part of LilyPond, the GNU music typesetter.
4 #
5 # Copyright (C) 2012 Joe Neeman <joeneeman@gmail.com>
6 #
7 # LilyPond is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # LilyPond is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
19
20 # A GTK+ program for debugging skylines. The program reads a sequence
21 # of line segments from stdin (one line segment per line of stdin, in the format
22 # '(x1, y1) (x2, y2)'). A skyline is terminated by an empty line, which
23 # causes the skyline to be displayed on the screen.
24
25 from threading import Thread
26 from math import isinf
27 import gtk
28 import gobject
29 import goocanvas
30 import sys
31 import re
32
33 class GtkSkylineCanvas (goocanvas.Canvas):
34 """A Canvas for displaying skylines."""
35 def __init__ (self):
36 super (GtkSkylineCanvas, self).__init__ ()
37 self.connect ('size-allocate', GtkSkylineCanvas.rescale)
38 self.x_min = float ('inf')
39 self.x_max = float ('-inf')
40 self.y_min = float ('inf')
41 self.y_max = float ('-inf')
42
43 self.colors = ('black', 'red', 'green', 'blue', 'maroon', 'olive', 'teal ')
44 self.cur_color_index = 0
45
46 def rescale (self, allocation):
47 width = (self.x_max - self.x_min + 1) * 1.1
48 height = (self.y_max - self.y_min + 1) * 1.1
49 if width <= 0 or height <= 0:
50 return
51
52 scale_x = allocation.width / width
53 scale_y = allocation.height / height
54 scale = min (scale_x, scale_y)
55 self.set_scale (scale)
56
57 center_x = (self.x_max + self.x_min) / 2
58 center_y = (self.y_max + self.y_min) / 2
59 actual_width = allocation.width / scale
60 actual_height = allocation.height / scale
61 actual_min_x = center_x - actual_width / 2
62 actual_max_x = center_x + actual_width / 2
63 actual_min_y = center_y - actual_height / 2
64 actual_max_y = center_y + actual_height / 2
65
66 self.set_bounds (actual_min_x, actual_min_y, actual_max_x, actual_max_y)
67 self.scroll_to (actual_min_x, actual_min_y)
68
69 def add_skyline (self, lines):
70 """Adds a skyline to the current canvas, in a new color.
71
72 The canvas will be rescaled, if necessary, to make room for the
73 new skyline."""
74 # Flip vertically, because goocanvas thinks higher numbers are
75 # further down, while lilypond thinks they're further up.
76 lines = [(x1, -y1, x2, -y2) for (x1, y1, x2, y2) in lines]
77
78 color = self.colors[self.cur_color_index]
79 self.cur_color_index = (self.cur_color_index + 1) % len (self.colors)
80
81 # Update the bounding box of the skylines.
82 x_vals = [s[0] for s in lines] + [s[2] for s in lines]
83 y_vals = [s[1] for s in lines] + [s[3] for s in lines]
84 self.x_min = min ([self.x_min] + x_vals)
85 self.x_max = max ([self.x_max] + x_vals)
86 self.y_min = min ([self.y_min] + y_vals)
87 self.y_max = max ([self.y_max] + y_vals)
88
89 # Add the lines to the canvas.
90 root = self.get_root_item ()
91 for (x1, y1, x2, y2) in lines:
92 goocanvas.polyline_new_line (root, x1, y1, x2, y2,
93 stroke_color=color,
94 line_width=0.05)
95 self.rescale (self.get_allocation ())
96
97 # We want to run the gtk main loop in a separate thread so that
98 # the main thread can be responsible for reading stdin.
99 class SkylineWindowThread (Thread):
100 """A thread that runs a Gtk.Window displaying a skyline."""
101
102 def run (self):
103 gtk.gdk.threads_init ()
104 self.window = None
105 self.canvas = None
106 gtk.main ()
107
108 # This should only be called from the Gtk main loop.
109 def _destroy_window (self, window):
110 sys.exit (0)
111
112 # This should only be called from the Gtk main loop.
113 def _setup_window (self):
114 if self.window is None:
115 self.window = gtk.Window ()
116 self.canvas = GtkSkylineCanvas ()
117 self.window.add (self.canvas)
118 self.window.connect ("destroy", self._destroy_window)
119 self.window.show_all ()
120
121 # This should only be called from the Gtk main loop.
122 def _add_skyline (self, lines):
123 self._setup_window ()
124 self.canvas.add_skyline (lines)
125
126 def add_skyline (self, lines):
127 # Copy the lines, just in case someone modifies them.
128 gobject.idle_add (self._add_skyline, list (lines))
129
130 thread = SkylineWindowThread ()
131 thread.setDaemon (True)
132 thread.start ()
133
134 def lines(infile):
135 line = infile.readline()
136 while len(line) > 0:
137 yield line[:-1]
138 line = infile.readline()
139
140 point_re_str = r'\(([a-z.0-9-]*) *,([a-z0-9.-]*)\)'
141 line_re_str = point_re_str + r' +' + point_re_str
142 line_re = re.compile (line_re_str)
143
144 # The main loop just reads lines from stdin and feeds them to the
145 # display.
146 current_skyline = []
147 for line in lines(sys.stdin):
148 if not line:
149 thread.add_skyline(current_skyline)
150 current_skyline = []
151 continue
152
153 m = re.search (line_re, line)
154 if m is None:
155 print('line did not match')
156 else:
157 pts = map(float, m.groups())
158 if not any(map(isinf, pts)):
159 current_skyline.append(pts)
160
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b