tabscroll 0.0.1 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,89 +0,0 @@
1
- # A simple timer that counts in seconds.
2
- #
3
- # Usage:
4
- # timer = Timer.new
5
- # timer.start
6
- # ...
7
- # if timer.delta > 0.5 # half a second
8
- # ...
9
- #
10
- class Timer
11
-
12
- def initialize
13
- @is_running = false
14
- @is_paused = false
15
- end
16
-
17
- # Starts counting.
18
- def start
19
- return if @is_running
20
-
21
- @start_time = Time.now
22
- @stop_time = 0.0
23
- @paused_time = 0.0
24
- @is_running = true
25
- @is_paused = false
26
- end
27
-
28
- # Stops counting.
29
- def stop
30
- return if not @is_running
31
-
32
- @stop_time = Time.now
33
- @is_running = false
34
- @is_paused = false
35
- end
36
-
37
- def restart
38
- self.stop
39
- self.start
40
- end
41
-
42
- def pause
43
- return if not @is_running or @is_paused
44
-
45
- @paused_time = (Time.now - @start_time)
46
- @is_running = false
47
- @is_paused = true
48
- end
49
-
50
- def unpause
51
- return if not @is_paused or @is_running
52
-
53
- @start_time = (Time.now - @paused_time)
54
- @is_running = true
55
- @is_paused = false
56
- end
57
-
58
- def running?
59
- @is_running
60
- end
61
-
62
- def paused?
63
- @is_paused
64
- end
65
-
66
- # Returns the current delta in seconds (float).
67
- def delta
68
- if @is_running
69
- return (Time.now.to_f - @start_time.to_f)
70
- end
71
-
72
- return @paused_time.to_f if @is_paused
73
-
74
- return @start_time if @start_time == 0 # Something's wrong
75
-
76
- return (@stop_time.to_f - @start_time.to_f)
77
- end
78
-
79
- # Converts the timer's delta to a formatted string.
80
- def to_s
81
- min = (self.delta / 60).to_i
82
- sec = (self.delta).to_i
83
- msec = (self.delta * 100).to_i
84
-
85
- "#{min}:#{sec}:#{msec}"
86
- end
87
-
88
- end
89
-
@@ -1,203 +0,0 @@
1
-
2
- require_relative 'screen.rb'
3
- require_relative 'timer.rb'
4
-
5
- # A full guitar tab, as shown on the screen.
6
- # Note that it depends on an already-existing window to exist.
7
- #
8
- class Track
9
- COMMENT_CHAR = '#'
10
- attr_reader :screen, :percent_completed
11
- attr_accessor :speed
12
-
13
- # Creates a Track that will be shown on `screen`.
14
- # See Screen.
15
- def initialize(screen)
16
- @offset = 0
17
- @timer = Timer.new
18
- @timer.start
19
- @speed = 0
20
- @screen = screen
21
- @percent_completed = 0
22
-
23
- @raw_track = []
24
- @raw_track[0] = ""
25
- @raw_track[1] = ""
26
- @raw_track[2] = ""
27
- @raw_track[3] = ""
28
- @raw_track[4] = ""
29
- @raw_track[5] = ""
30
- @raw_track[6] = ""
31
- end
32
-
33
- # Loads and parses +filename+'s contents into Track.
34
- def load filename
35
- if not File.exist? filename
36
- raise "Error: File '#{filename}' doesn't exist!"
37
- end
38
- if not File.file? filename
39
- raise "Error: '#{filename}' is not a file!"
40
- end
41
-
42
- file = File.new filename
43
-
44
- # The thing here is there's no way I can know in
45
- # advance how many lines the tab track will have.
46
- #
47
- # People put lots of strange things on them like
48
- # timing, comments, etecetera.
49
- #
50
- # So I will read all non-blank lines, creating a
51
- # counter. Then I will use it to display the track
52
- # onscreen.
53
- #
54
- # I will also make every line have the same width
55
- # as of the biggest one.
56
-
57
- # Any tab line MUST have EITHER ---1---9--| OR |---3----0
58
- tab_line = /[-[:alnum:]]\||\|[-[:alnum:]]/
59
-
60
- # Duration of each note only has those chars.
61
- # So we look for anything BUT these chars.
62
- not_duration_line = /[^WHQESTX \.]/
63
-
64
- count = 0
65
- max_width = 0
66
-
67
- file.readlines.each do |line|
68
- next if line[0] == COMMENT_CHAR
69
-
70
- line.chomp!
71
- if line.empty?
72
-
73
- # Making sure everything will have the same width
74
- @raw_track.each_with_index do |t, i|
75
- if t.length < max_width
76
- @raw_track[i] += (' ' * (max_width - t.length))
77
- end
78
- end
79
-
80
- count = 0
81
- max_width = 0
82
-
83
- # Lines must be EITHER a tab_line OR a duration_line.
84
- # not not duration line means that
85
- # (I should find a better way of expressing myself on regexes)
86
- elsif (line =~ tab_line) or (not line =~ not_duration_line)
87
- @raw_track[count] += line
88
-
89
- if @raw_track[count].length > max_width
90
- max_width = @raw_track[count].length
91
- end
92
-
93
- count += 1
94
-
95
- end # Ignoring any other kind of line
96
-
97
- if count > 7
98
- raise "Error: Invalid format on '#{filename}'"
99
- end
100
-
101
- end
102
- end
103
-
104
- # Prints the track on the screen, along with string indicators
105
- # on the left.
106
- #
107
- # It is shown at the vertical center of the provided Screen,
108
- # spanning it's whole width.
109
- def show
110
- x = 1
111
- y = (@screen.height/2) - (@raw_track.size/2)
112
-
113
- # This both prints EADGBE and clears the whole screen,
114
- # printing spaces where the track was.
115
- #
116
- # Also, if we have only 5 tracks, we leave the sixth
117
- # indicator out of the screen.
118
- if not @raw_track[6] =~ /[:blank:]/
119
- @screen.mvaddstr(0, y, "E" + (' ' * (@screen.width - 1)))
120
- @screen.mvaddstr(0, y + 1, "B" + (' ' * (@screen.width - 1)))
121
- @screen.mvaddstr(0, y + 2, "G" + (' ' * (@screen.width - 1)))
122
- @screen.mvaddstr(0, y + 3, "D" + (' ' * (@screen.width - 1)))
123
- @screen.mvaddstr(0, y + 4, "A" + (' ' * (@screen.width - 1)))
124
- @screen.mvaddstr(0, y + 5, "E" + (' ' * (@screen.width - 1)))
125
- else
126
- @screen.mvaddstr(0, y, ' ' * @screen.width)
127
- @screen.mvaddstr(0, y + 1, "E" + (' ' * (@screen.width - 1)))
128
- @screen.mvaddstr(0, y + 2, "B" + (' ' * (@screen.width - 1)))
129
- @screen.mvaddstr(0, y + 3, "G" + (' ' * (@screen.width - 1)))
130
- @screen.mvaddstr(0, y + 4, "D" + (' ' * (@screen.width - 1)))
131
- @screen.mvaddstr(0, y + 5, "A" + (' ' * (@screen.width - 1)))
132
- @screen.mvaddstr(0, y + 6, "E" + (' ' * (@screen.width - 1)))
133
- end
134
-
135
- (0...@raw_track.size).each do |i|
136
- str = @raw_track[i]
137
- str = str[@offset..(@offset + @screen.width - 2)]
138
- @screen.mvaddstr(x, y + i, str)
139
- end
140
- end
141
-
142
- # Scrolls the guitar tab by `n`.
143
- #
144
- # * If `n` is positive, scroll forward.
145
- # * If `n` is negative, scroll backward.
146
- def scroll n
147
- @offset += n
148
-
149
- left_limit = 0
150
- right_limit = (@raw_track[0].length - @screen.width + 1).abs
151
-
152
- if @offset < left_limit then @offset = left_limit end
153
- if @offset > right_limit then @offset = right_limit end
154
- end
155
-
156
- # Goes to the beginning of the Track.
157
- def begin
158
- @offset = 0
159
- @speed = 0
160
- end
161
-
162
- # Goes to the end of the Track.
163
- def end
164
- @offset = (@raw_track[0].length - @screen.width + 1).abs
165
- @speed = 0
166
- end
167
-
168
- # Turns on/off Track's auto scroll functionality.
169
- #
170
- # Note that it won't work anyways if you don't keep calling
171
- # +update+ method.
172
- def auto_scroll option
173
- if option == true
174
- @timer.start if not @timer.running?
175
- else
176
- @timer.stop
177
- end
178
- end
179
-
180
- # Updates Track's auto scroll functionality.
181
- def update
182
- return if not @timer.running?
183
-
184
- current_completed = @offset + @screen.width - 1
185
- @percent_completed = ((100.0 * current_completed)/@raw_track[0].length).ceil
186
-
187
- if @timer.running? and @speed != 0
188
- if @timer.delta > (1/(@speed*0.5)).abs
189
- if @speed > 0
190
- self.scroll 1
191
- self.show
192
- else
193
- self.scroll -1
194
- self.show
195
- end
196
-
197
- @timer.restart
198
- end
199
- end
200
- end
201
-
202
- end
203
-