Class: PM::Main

Inherits:
Object
  • Object
show all
Includes:
Curses, Singleton
Defined in:
lib/patchmaster/curses/main.rb

Constant Summary collapse

FUNCTION_KEY_SYMBOLS =
{}

Instance Method Summary collapse

Constructor Details

#initializeMain

Returns a new instance of Main.



19
20
21
# File 'lib/patchmaster/curses/main.rb', line 19

def initialize
  @pm = PatchMaster.instance
end

Instance Method Details

#config_cursesObject



107
108
109
110
111
112
113
# File 'lib/patchmaster/curses/main.rb', line 107

def config_curses
  init_screen
  cbreak                      # unbuffered input
  noecho                      # do not show typed keys
  stdscr.keypad(true)         # enable arrow keys
  curs_set(0)                 # cursor: 0 = invisible, 1 = normal
end

#create_windowsObject



115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/patchmaster/curses/main.rb', line 115

def create_windows
  g = PM::Geometry.new

  @song_lists_win = ListWindow.new(*g.song_lists_rect, nil)
  @song_list_win = ListWindow.new(*g.song_list_rect, 'Song List')
  @song_win = ListWindow.new(*g.song_rect, 'Song')
  @patch_win = PatchWindow.new(*g.patch_rect, 'Patch')
  @message_win = Window.new(*g.message_rect)
  @trigger_win = TriggerWindow.new(*g.trigger_rect)
  @info_win = InfoWindow.new(*g.info_rect)

  @message_win.scrollok(false)
end

#edit(file) ⇒ Object

Opens the most recently loaded/saved file name in an editor. After editing, the file is re-loaded.



154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/patchmaster/curses/main.rb', line 154

def edit(file)
  editor_command = find_editor
  unless editor_command
    message("Can not find $VISUAL, $EDITOR, vim, or vi on your path")
    return
  end

  cmd = "#{editor_command} #{file}"
  @pm.debug(cmd)
  system(cmd)
  load(file)
end

#find_editorObject

Return the first legit command from $VISUAL, $EDITOR, vim, vi, and notepad.exe.



169
170
171
172
173
# File 'lib/patchmaster/curses/main.rb', line 169

def find_editor
  @editor ||= [ENV['VISUAL'], ENV['EDITOR'], 'vim', 'vi', 'notepad.exe'].compact.detect do |cmd|
    system('which', cmd) || File.exist?(cmd)
  end
end

#helpObject



175
176
177
178
179
180
181
# File 'lib/patchmaster/curses/main.rb', line 175

def help
  g = PM::Geometry.new
  win = HelpWindow.new(*g.help_rect)
  win.draw
  win.refresh
  getch                       # wait for key and eat it
end

#load(file) ⇒ Object



144
145
146
# File 'lib/patchmaster/curses/main.rb', line 144

def load(file)
  @pm.load(file)
end

#message(str) ⇒ Object



183
184
185
186
187
188
189
190
191
192
# File 'lib/patchmaster/curses/main.rb', line 183

def message(str)
  if @message_win
    @message_win.clear
    @message_win.addstr(str)
    @message_win.refresh
  else
    $stderr.puts str
  end
  @pm.debug "#{Time.now} #{str}"
end

#refreshObject

Public method callable by triggers



195
196
197
# File 'lib/patchmaster/curses/main.rb', line 195

def refresh
  refresh_all
end

#refresh_allObject



199
200
201
202
203
204
205
# File 'lib/patchmaster/curses/main.rb', line 199

def refresh_all
  set_window_data
  wins = [@song_lists_win, @song_list_win, @song_win, @patch_win, @info_win, @trigger_win]
  wins.map(&:draw)
  ([stdscr] + wins).map(&:noutrefresh)
  Curses.doupdate
end

#resize_windowsObject



129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/patchmaster/curses/main.rb', line 129

def resize_windows
  g = PM::Geometry.new

  @song_lists_win.move_and_resize(g.song_lists_rect)
  @song_list_win.move_and_resize(g.song_list_rect)
  @song_win.move_and_resize(g.song_rect)
  @patch_win.move_and_resize(g.patch_rect)
  @trigger_win.move_and_resize(g.trigger_rect)
  @info_win.move_and_resize(g.info_rect)

  r = g.message_rect
  @message_win.move(r[2], r[3])
  @message_win.resize(r[0], r[1])
end

#runObject



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
# File 'lib/patchmaster/curses/main.rb', line 23

def run
  @pm.start
  begin
    config_curses
    create_windows

    loop do
      begin
        refresh_all
        ch = getch
        message("ch = #{ch}") if $DEBUG
        case ch
        when 'j', Key::DOWN, ' '
          @pm.next_patch
        when 'k', Key::UP
          @pm.prev_patch
        when 'n', Key::RIGHT
          @pm.next_song
        when 'p', Key::LEFT
          @pm.prev_song
        when 'g'
          name = PromptWindow.new('Go To Song', 'Go to song:').gets
          @pm.goto_song(name) if name.length > 0
        when 't'
          name = PromptWindow.new('Go To Song List', 'Go to Song List:').gets
          @pm.goto_song_list(name) if name.length > 0
        when 'e'
          close_screen
          file = @pm.loaded_file || PromptWindow.new('Edit', 'Edit file:').gets
          edit(file) if file.length > 0
        when 'r'
          load(@pm.loaded_file) if @pm.loaded_file && @pm.loaded_file.length > 0
        when 'h', '?'
          help
        when 27        # "\e" doesn't work here
          # Twice in a row sends individual note-off commands
          message('Sending panic note off messages...')
          @pm.panic(@prev_cmd == 27)
          message('Panic sent')
        when 'l'
          file = PromptWindow.new('Load', 'Load file:').gets
          if file.length > 0
            begin
              load(file)
              message("Loaded #{file}")
            rescue => ex
              message(ex.to_s)
            end
          end
        when 's'
          file = PromptWindow.new('Save', 'Save into file:').gets
          if file.length > 0
            begin
              save(file)
              message("Saved #{file}")
            rescue => ex
              message(ex.to_s)
            end
          end
        when 'q'
          break
        when Key::RESIZE
          resize_windows
        end
        @prev_cmd = ch
      rescue => ex
        message(ex.to_s)
        @pm.debug caller.join("\n")
      end

      msg_name = @pm.message_bindings[ch]
      @pm.send_message(msg_name) if msg_name
      code_key = @pm.code_bindings[ch]
      code_key.run if code_key
    end
  ensure
    clear
    refresh
    close_screen
    @pm.stop
    @pm.close_debug_file
  end
end

#save(file) ⇒ Object



148
149
150
# File 'lib/patchmaster/curses/main.rb', line 148

def save(file)
  @pm.save(file)
end

#set_window_dataObject



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/patchmaster/curses/main.rb', line 207

def set_window_data
  @song_lists_win.set_contents('Song Lists', @pm.song_lists, :song_list)

  song_list = @pm.song_list
  @song_list_win.set_contents(song_list.name, song_list.songs, :song)

  song = @pm.song
  if song
    @song_win.set_contents(song.name, song.patches, :patch)
    @info_win.text = song.notes
    patch = @pm.patch
    @patch_win.patch = patch
  else
    @song_win.set_contents(nil, nil, :patch)
    @info_win.text = nil
    @patch_win.patch = nil
  end
end