made it work, more or less, with ruby 1.9
[nyuron.git] / modules / ui.rb
blob3c51d58ffc13b936d06e92814049b31b5148c99a
1 require 'modules/cli'
2 module UserInterface
3         extend CLI
4         extend self
6         attr_accessor :list, :regexp
7         attr_reader :cursor, :start, :marked
9         @keybuffer = ""
10         @regexp = //
11         @cursor = 0
12         @busy_array = %w(/ - \\ |)
13 #       @busy_array = ("!".."~").to_a.shuffle
14         @busy_pos = 0
15         @start = 0
16         @old_start = 0
17         @old_cursor = 0
19         @marked = []
20         @list = []
22         def meta_loop
23                 Cache.opt.sync!
24                 Cache.map.sync!
25                 Cache.cmd.sync!
27                 while true
28                         begin
29                                 $now = Time.now
30                                 do_tasks
31                                 case Info.where
32                                 when :main
33                                         CLI.cursor(Color.terminal_cursor)
34                                         main_loop
35                                 when :console, :search, :searchback
36                                         CLI.cursor(Color.console.terminal_cursor)
37                                         Console.main_loop(Info.where)
38                                 else
39                                         forbid
40                                 end
41                         rescue
42                                 Console.raise $!
43                         end
44                 end
45         end
47         def main_loop
48                 API.busy true
49                 UI.draw
50                 Console.clear
51                 API.busy false
52                 CLI.movi UI.cursor - UI.start, 0
53                 key = UI.get_key
54                 API.busy true
55                 UI.handle_key(key)
56         end
58         def do_tasks
59                 if Info.request_filter
60                         API.refilter!
61                 end
62                 if Info.request_reoccur or
63                                 ((next_reoccur = Opt.next_reoccur.to_i) and 
64                                 next_reoccur > 0 and
65                                 $now.to_i > next_reoccur)
66                         API.reoccur!
67                 end
68                 if Info.request_sort
69                         API.resort!
70                 end
71         end
73         def key_combination?(str)
74 #               log("#{str} =~ #{@regexp} => #{str =~ @regexp}")
75                 str =~ @regexp
76         end
78         ## Returns the line, where the console is drawn.
79         def console_line()
80                 -1
81         end
82         
83         ## Get the key from user input
84         def get_key()
85                 geti
86         end
88         def handle_key(key)
89                 @key = key
90                 return if @key.empty?
92                 # special cases
93                 case @key
94                 when '<'
95                         @key = "<<"
96                 when '<redraw>'
97                         Info.request_draw = true
98                         return
99                 end
101                 @keybuffer << @key
103                 if key_combination?(@keybuffer).nil?
104                         command = Cache.map[@keybuffer]
105                         if command
106                                 Command.run(command, @keybuffer)
107                         end
108                         @keybuffer.clear
109                 end
110         end
112         ## Set or remove the sign at the bottom right that work is in progress.
113         ## Also, each time this method is called with true, that sign is rotated.
114         ## Use this in time-expensive processes to entertain the user :)
115         def busy(bool=true)
116                 return unless Opt.busy
117                 if bool
118                         @busy_pos += 1
119                         if @busy_pos == @busy_array.size
120                                 @busy_pos = 0
121                         end
122                         puti(-1, -1, @busy_array[@busy_pos])
123                         CLI.refresh
124                 else
125 #                       if Info.where == :main
126 #                               puti(-1, -1, "]")
127 #                       else
128                                 puti(-1, -1, " ")
129 #                       end
130                         CLI.refresh
131                 end
132         end
134         def draw
135 #               bm "draw" do
136                         width = API.cols
137                         cursor_color = Opt.cursor_color
138                         cursor_color = [6, 0] unless cursor_color.is_a?(Array) and cursor_color[0].is_a?(Integer) and cursor_color[1].is_a?(Integer)
139                         
140                         Info.request_draw = true ##temporary
141                         if Info.request_draw or @old_start != @start or (@cursor != @old_cursor and !@list[@old_cursor])
142                                 Info.request_draw = false
144                                 expand = Opt.expand
145                                 expand = false unless expand == false or expand == true
146                                 expand_max = Opt.expand_max
147                                 expand_max = 10 unless expand_max.is_a? Integer
148                                 expand = false if expand_max < 1
150                                 draw_blank = false
152                                 line_ix = 0
153                                 list_ix = 0
154                                 while line_ix + 1 < lines
155                                         jump = 1
156                                         if draw_blank
157                                                 attr_set(*Color[:normal].base)
158                                                 puti(line_ix, " " * cols)
160                                         else
161                                                 cell = @list[list_ix+@start]
162                                                 if cell.nil?
163                                                         draw_blank = true
164                                                         redo
165                                                 end
167                                                 if @cursor - @start == line_ix
168                                                         mode = :selected
169                                                 elsif @marked.include? cell
170                                                         mode = :marked
171                                                 elsif cell.tags.include? 'k'
172                                                         mode = :done
173                                                 else
174                                                         mode = :normal
175                                                 end
177                                                 attr_set(*Color[mode].content)
178                                                 puti(line_ix, cell.to_s(width))
179                                                 attr_set(*Color[:normal].content)
180 #                                               log "cell.lines = #{cell.lines}"
181                                                 if expand and mode == :selected and cell.lines > 1
182 #                                                       log("expand and cell.lines > 1")
183                                                         for line in 1..[cell.lines - 1, expand_max].min
184                                                                 puti(line_ix+jump, cell.line(line).rjust(cols))
185 #                                                               attr_at(0, line_ix+jump, -1, *Color[:selected].content)
186                                                                 attr_at(0, line_ix+jump, -1, *Color[:normal].content)
187                                                                 jump += 1
188                                                         end
189                                                         if (cell.lines > expand_max + 1)
190                                                                 stringy = "...."
191                                                         else
192                                                                 stringy = ""
193                                                         end
194                                                         puti(line_ix+jump, stringy.ljust(cols))
195                                                         attr_at(0, line_ix+jump, -1, *Color[:normal].content)
196                                                         jump += 1
197                                                 end
198 #                                               if mode == :selected
199 #                                                       attr_set(-1, -1, 0)
200 #                                               else
201                                                 if true
202                                                         if cell.bold_on_the_left > 0
203 #                                                               logpp Color[mode].map
204                                                                 clr = Color[mode].send(cell.type) #rescue Color.default_color
205                                                                 attr_at(0, line_ix, cell.bold_on_the_left, *clr)
206                                                         end
208                                                         botr = cell.bold_on_the_right
209                                                         if botr > 0
210                                                                 if cell.prio < 0
211                                                                         clr = Color[mode].priority_negative
212                                                                 else
213                                                                         clr = Color[mode].priority_positive
214                                                                 end
215                                                                 attr_at(cols-botr, line_ix, botr, *clr)
216                                                         end
218                                                         if not cell.tags.empty?
219 #                                                               botr += 1 if botr > 0
220                                                                 sz = cell.tagstring.size
221                                                                 clr = Color[mode].tags
222                                                                 attr_at(cols-botr-sz, line_ix, sz, *clr)
223                                                         end
224                                                 end
225                                                 attr_set(-1, -1, 0)
226                                         end
227                                         
228                                         list_ix += 1
229                                         line_ix += jump
230                                 end
231                         else
232                                 if @cursor != @old_cursor
233                                         old = @old_cursor - @start
234                                         cur = @cursor - @start
235                                         attr_at(0, cur, -1, *Color[:selected].content)
236 #                                       color_reverse_at(cur, 0, -1, *cursor_color)
237                                         attr_at(0, old, -1, *Color[:normal].content)
238 #                                       color_at(old, 0, -1, -1, -1)
239                                         cell = @list[@old_cursor]
240 #                                       color_bold_at(old, 0, cell.bold_on_the_left, -1, -1) if cell.bold_on_the_left > 0
241 #                                       color_at(old, cols-cell.bold_on_the_right, -1, 2, -1) if cell.bold_on_the_right > 0
242 ##                                      color_bold_at(old, cols-cell.bold_on_the_right, -1, -1, -1) if cell.bold_on_the_right > 0
243 ##                                              color_at(cur, 0, 13, 4, 6)
244                                         color -1, -1
245                                 end
246 #                       end
248                         @old_start = @start
249                         @old_cursor = @cursor
250                 end
251         end
253         def start=(val)
254                 if @start != val
255                         @start, @old_start = val, @start
256                 end
257         end
259         def cursor=(val)
260                 if @cursor != val
261                         @cursor, @old_cursor = val, @cursor
262                 end
263         end
265         def close
266                 closei
267                 puts Opt.quitmsg
268         end
271 UI = UserInterface