1# draw.rb -- draw.scm --> draw.rb
2
3# Translator: Michael Scholz <mi-scholz@users.sourceforge.net>
4# Created: 2005/04/05 00:17:04
5# Changed: 2018/04/15 22:49:29
6
7# examples of extensions to Snd's graphics
8#
9# module Draw
10#  display_colored_samples(color, beg, dur, snd = false, chn = false)
11#  display_samples_in_color(snd, chn)
12#  color_samples(color, beg = 0, dur = false, snd = Snd.snd, chn = Snd.chn)
13#  uncolor_samples(snd = Snd.snd, chn = Snd.chn)
14#  display_previous_edits(snd, chn)
15#  overlay_sounds(*rest)
16#  samples_via_colormap(snd, chn)
17#  click_for_listener_help(pos)
18
19require "extensions"
20
21module Draw
22  add_help(:display_colored_samples,
23           "display_colored_samples(color, beg, dur, snd=false, chn=false)  \
24Displays samples from beg for dur in color \
25whenever they're in the current view.")
26  def display_colored_samples(color, beg, dur, snd = false, chn = false)
27    unless array?(color) and number?(beg) and number?(dur)
28      return
29    end
30    left = left_sample(snd, chn)
31    right = right_sample(snd, chn)
32    len = beg + dur
33    old_color = foreground_color(snd, chn)
34    if left < len and right > beg
35      cr = channel_widgets(snd, chn)[17]
36      if vct?(data = make_graph_data(snd, chn))
37        samps = [right, len].min - [left, beg].max
38        offset = [0, beg - left].max
39        new_data = data.subseq(offset, offset + samps)
40        set_foreground_color(color, snd, chn)
41        graph_data(new_data,
42                   snd, chn,
43                   Copy_context,
44                   [beg, left].max,
45                   [len, right].min, Graph_lines, cr)
46        set_foreground_color(old_color, snd, chn)
47      else
48        low_data, high_data = data[0, 2]
49        size = low_data.length
50        samps = right - left
51        left_offset = [0, beg - left].max
52        left_bin = ((size.to_f * left_offset) / samps).floor
53        right_offset = [len, right].min - left
54        right_bin = ((size.to_f * right_offset) / samps).floor
55        new_low_data = low_data.subseq(left_bin, right_bin)
56        new_high_data = high_data.subseq(left_bin, right_bin)
57        set_foreground_color(color, snd, chn)
58        graph_data([new_low_data, new_high_data],
59                   snd, chn, Copy_context, left_bin, right_bin, Graph_lines, cr)
60        set_foreground_color(old_color, snd, chn)
61      end
62    end
63  end
64
65  def display_samples_in_color(snd, chn)
66    col, beg, dur = channel_property(:colored_samples, snd, chn)
67    display_colored_samples(col, beg, dur, snd, chn)
68  end
69
70  add_help(:color_samples,
71           "color_samples(color, beg=0, dur=false, snd=false, chn=false)  \
72Causes samples from BEG to BEG+DUR to be displayed in COLOR.")
73  def color_samples(color, beg = 0, dur = false, snd = Snd.snd, chn = Snd.chn)
74    unless $after_graph_hook.member?("display-samples-in-color")
75      $after_graph_hook.add_hook!("display-samples-in-color") do |s, c|
76        display_samples_in_color(s, c)
77      end
78    end
79    unless dur then dur = framples(snd, chn) - beg end
80    set_channel_property(:colored_samples, [color, beg, dur], snd, chn)
81    update_time_graph(snd, chn)
82  end
83
84  add_help(:uncolor_samples,
85           "uncolor_samples(snd=false, chn=false)  \
86Cancels sample coloring in the given channel.")
87  def uncolor_samples(snd = Snd.snd, chn = Snd.chn)
88    set_channel_property(:colored_samples, [], snd, chn)
89    update_time_graph(snd, chn)
90  end
91
92  add_help(:display_previous_edits,
93           "display_previous_edits(snd, chn)  \
94Displays all edits of the current sound, \
95with older versions gradually fading away.")
96  def display_previous_edits(snd, chn)
97    edits = edit_position(snd, chn)
98    if edits > 0
99      old_color = foreground_color(snd, chn)
100      clist = color2list(old_color)
101      r = clist[0]
102      g = clist[1]
103      b = clist[2]
104      rinc = (1.0 - r) / (edits + 1)
105      ginc = (1.0 - g) / (edits + 1)
106      binc = (1.0 - b) / (edits + 1)
107      cr = channel_widgets(snd, chn)[17]
108      re = 1.0 - rinc
109      ge = 1.0 - ginc
110      be = 1.0 - binc
111      0.upto(edits) do |pos|
112        data = make_graph_data(snd, chn, pos)
113        set_foreground_color(make_color(re, ge, be), snd, chn)
114        graph_data(data,
115                   snd, chn, Copy_context,
116                   false, false, time_graph_style(snd, chn), cr)
117        re -= rinc
118        ge -= ginc
119        be -= binc
120      end
121      set_foreground_color(old_color, snd, chn)
122    end
123  end
124
125  add_help(:overlay_sounds,
126           "overlay_sounds(*rest)  \
127Overlays onto its first argument all \
128subsequent arguments: overlay_sounds(1, 0, 3)")
129  def overlay_sounds(*rest)
130    base = rest.shift
131    if integer?(base)
132      base = integer2sound(base)
133    end
134    $after_graph_hook.add_hook!(get_func_name) do |snd, chn|
135      if snd == base
136        cr = channel_widgets(snd, chn)[17]
137        rest.each do |s|
138          graph_data(make_graph_data(s, chn),
139                     base, chn, Copy_context, false, false, Graph_dots, cr)
140        end
141      end
142    end
143  end
144
145  add_help(:samples_via_colormap,
146           "samples_via_colormap(snd, chn)  \
147Displays time domain graph using current \
148colormap (just an example of colormap_ref).")
149  def samples_via_colormap(snd, chn)
150    left = left_sample(snd, chn)
151    old_color = foreground_color(snd, chn)
152    if data = make_graph_data(snd, chn)
153      cr = channel_widgets(snd, chn)[17]
154      if vct?(data)
155        data = [data]
156      end
157      data.each do |cur_data|
158        x0 = x2position(left / srate(snd))
159        y0 = y2position(cur_data[0])
160        colors = make_array(colormap_size)
161        j = 1
162        (left + 1).upto(left + cur_data.length - 1) do |i|
163          x1 = x2position(i / srate(snd))
164          y1 = y2position(cur_data[j])
165          x = cur_data[j].abs
166          ref = (colormap_size * x).floor
167          unless colors[ref]
168            colors[ref] = make_color(*colormap_ref(colormap, x))
169          end
170          set_foreground_color(colors[ref], snd, chn)
171          draw_line(x0, y0, x1, y1, snd, chn, Time_graph, cr)
172          x0, y0 = x1, y1
173          j += 1
174        end
175      end
176      set_foreground_color(old_color, snd, chn)
177    end
178  end
179
180  # click-for-listener-help
181
182  $last_click_time = 0.0
183
184  def click_for_listener_help(pos)
185    time = Time.now.to_f
186    if time - $last_click_time < 0.2
187      $last_click_time = 0.0
188      text = widget_text(main_widgets[4])
189      if string?(text)
190        subject = text.slice(text.rindex(/\b/m, pos)...text.index(/\b/m, pos))
191        if string?(subject)
192          help = snd_help(subject, false)
193          if string?(help)
194            help_dialog(subject, help)
195          end
196        end
197      end
198    else
199      $last_click_time = time
200    end
201  end
202  # $listener_click_hook.add_hook!("listener-help",
203  #   &method(:click_for_listener_help).to_proc)
204end
205
206include Draw
207
208# draw.rb ends here
209