Class: Track

Inherits:
Object
  • Object
show all
Defined in:
lib/tabscroll/track.rb

Overview

A full guitar tab, as shown on the screen. Note that it depends on an already-existing window to exist.

Constant Summary collapse

COMMENT_CHAR =

Any line on the file that starts with this char is completely ignored when processed. Useful for making use of tabs we currently can’t parse.

'#'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(screen) ⇒ Track

Creates a Track that will be shown on screen. See Screen.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/tabscroll/track.rb', line 20

def initialize(screen)
  @offset = 0
  @timer  = Timer.new
  @timer.start
  @speed  = 0
  @screen = screen
  @percent_completed = 0

  @raw_track = []
  @raw_track[0] = ""
  @raw_track[1] = ""
  @raw_track[2] = ""
  @raw_track[3] = ""
  @raw_track[4] = ""
  @raw_track[5] = ""
  @raw_track[6] = ""
end

Instance Attribute Details

#percent_completedObject (readonly)

Returns the value of attribute percent_completed.



15
16
17
# File 'lib/tabscroll/track.rb', line 15

def percent_completed
  @percent_completed
end

#screenObject (readonly)

Returns the value of attribute screen.



15
16
17
# File 'lib/tabscroll/track.rb', line 15

def screen
  @screen
end

#speedObject

Returns the value of attribute speed.



16
17
18
# File 'lib/tabscroll/track.rb', line 16

def speed
  @speed
end

Instance Method Details

#auto_scroll(option) ⇒ Object

Turns on/off Track’s auto scroll functionality.

Note that it won’t work anyways if you don’t keep calling update method.



180
181
182
183
184
185
186
# File 'lib/tabscroll/track.rb', line 180

def auto_scroll option
  if option == true
    @timer.start if not @timer.running?
  else
    @timer.stop
  end
end

#beginObject

Goes to the beginning of the Track.



165
166
167
168
# File 'lib/tabscroll/track.rb', line 165

def begin
  @offset = 0
  @speed  = 0
end

#endObject

Goes to the end of the Track.



171
172
173
174
# File 'lib/tabscroll/track.rb', line 171

def end
  @offset = (@raw_track[0].length - @screen.width + 1).abs
  @speed  = 0
end

#load(filename) ⇒ Object

Loads and parses filename‘s contents into Track.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/tabscroll/track.rb', line 39

def load filename
  if not File.exist? filename
    raise "Error: File '#{filename}' doesn't exist!"
  end
  if not File.file? filename
    raise "Error: '#{filename}' is not a file!"
  end

  file = File.new filename

  # The thing here is there's no way I can know in
  # advance how many lines the tab track will have.
  #
  # People put lots of strange things on them like
  # timing, comments, etecetera.
  #
  # So I will read all non-blank lines, creating a
  # counter. Then I will use it to display the track
  # onscreen.
  #
  # I will also make every line have the same width
  # as of the biggest one.

  # Any tab line MUST have EITHER:
  # ---1---9--|
  # or
  # |---3----0
  tab_line = /[-[:alnum:]*]\||\|[-[:alnum:]*]/

  # Duration of each note only has those chars.
  # So we look for anything BUT these chars.
  not_duration_line = /[^WHQESTX \.]/

  count = 0
  max_width = 0

  file.readlines.each do |line|
    next if line[0] == COMMENT_CHAR

    line.chomp!
    if line.empty?

      # Making sure everything will have the same width
      @raw_track.each_with_index do |t, i|
        if t.length < max_width
          @raw_track[i] += (' ' * (max_width - t.length))
        end
      end

      count = 0
      max_width = 0

    # Lines must be EITHER a tab_line OR a duration_line.
    # not not duration line means that
    # (I should find a better way of expressing myself on regexes)
    elsif (line =~ tab_line) or (not line =~ not_duration_line)
      @raw_track[count] += line

      if @raw_track[count].length > max_width
        max_width = @raw_track[count].length
      end

      count += 1

    end # Ignoring any other kind of line

    if count > 7
      raise "Error: Invalid format on '#{filename}'"
    end

  end
end

#scroll(n) ⇒ Object

Scrolls the guitar tab by n.

  • If n is positive, scroll forward.

  • If n is negative, scroll backward.



154
155
156
157
158
159
160
161
162
# File 'lib/tabscroll/track.rb', line 154

def scroll n
  @offset += n

  left_limit  = 0
  right_limit = (@raw_track[0].length - @screen.width + 1).abs

  if @offset < left_limit  then @offset = left_limit  end
  if @offset > right_limit then @offset = right_limit end
end

#showObject

Prints the track on the screen, along with string indicators on the left.

It is shown at the vertical center of the provided Screen, spanning it’s whole width.



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/tabscroll/track.rb', line 117

def show
  x = 1
  y = (@screen.height/2) - (@raw_track.size/2)

  # This both prints EADGBE and clears the whole screen,
  # printing spaces where the track was.
  #
  # Also, if we have only 5 tracks, we leave the sixth
  # indicator out of the screen.
  if @raw_track.last =~ /^ *$/
    @screen.mvaddstr(0, y,     "E" + (' ' * (@screen.width - 1)))
    @screen.mvaddstr(0, y + 1, "B" + (' ' * (@screen.width - 1)))
    @screen.mvaddstr(0, y + 2, "G" + (' ' * (@screen.width - 1)))
    @screen.mvaddstr(0, y + 3, "D" + (' ' * (@screen.width - 1)))
    @screen.mvaddstr(0, y + 4, "A" + (' ' * (@screen.width - 1)))
    @screen.mvaddstr(0, y + 5, "E" + (' ' * (@screen.width - 1)))
  else
    @screen.mvaddstr(0, y,     ' ' * @screen.width)
    @screen.mvaddstr(0, y + 1, "E" + (' ' * (@screen.width - 1)))
    @screen.mvaddstr(0, y + 2, "B" + (' ' * (@screen.width - 1)))
    @screen.mvaddstr(0, y + 3, "G" + (' ' * (@screen.width - 1)))
    @screen.mvaddstr(0, y + 4, "D" + (' ' * (@screen.width - 1)))
    @screen.mvaddstr(0, y + 5, "A" + (' ' * (@screen.width - 1)))
    @screen.mvaddstr(0, y + 6, "E" + (' ' * (@screen.width - 1)))
  end

  (0...@raw_track.size).each do |i|
    str = @raw_track[i]
    str = str[@offset..(@offset + @screen.width - 2)]
    @screen.mvaddstr(x, y + i, str)
  end
end

#updateObject

Updates Track’s auto scroll functionality.



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/tabscroll/track.rb', line 189

def update
  return if not @timer.running?

  current_completed = @offset + @screen.width - 1
  @percent_completed = ((100.0 * current_completed)/@raw_track[0].length).ceil

  if @timer.running? and @speed != 0
    if @timer.delta > (1/(@speed*0.5)).abs
      if @speed > 0
        self.scroll 1
        self.show
      else
        self.scroll -1
        self.show
      end

      @timer.restart
    end
  end
end