about summary refs log blame commit diff stats
path: root/code/cli.rb
blob: 3c0f506ecae2f817cb2b4dd3c66965167d4dd131 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12

                 
          


                   





                                  
                                                     
                              







                                       

                               


                                      
                               


                                             
                               


                                        
                    
                          


                   








                                        



                                




                                          
                                 
                  
                                




                                          

                                  
                                      


                                 


                                                                                  

                                                 
                                                      


                      
                                                       

           



                               
                             
                  
                                 
                            
                                



                                  

                                    



                                                            
                
                                           


                        
                                     



























                                                                        



                                                                                     
                    
                                                                 


                   








                                                                        










                                                                        






                                                                         

                                                               
                                                                         



                                                                                  




                                                                            
                                                                            




                                                                         
                                                                         




                                                                                      
                                                                                      




                                                                                      
                                                                                      



                                                                     






















                                                                                      
                 
   
require 'ncurses'

module CLI
	@@mev = nil
	extend self

	def self.keytable(key)
		case key
		when 12
			'<redraw>'
		when ?\n
			'<cr>'
		when ?\b, Ncurses::KEY_BACKSPACE, 127
			'<bs>'
		when Ncurses::KEY_RIGHT
			'<right>'
		when Ncurses::KEY_LEFT
			'<left>'
		when Ncurses::KEY_UP
			'<up>'
		when Ncurses::KEY_DOWN
			'<down>'
		when ?\e
			'<esc>'
		when Ncurses::KEY_BTAB
			'<s-tab>'
		when 9
			'<tab>'
		when 1..26 # CTRL + ...
			"<c-#{(key+96).chr}>"
		when 32..127
			key.chr
		when Ncurses::KEY_MOUSE
			fetch_mouse_data
			'<mouse>'
		else
			''
		end
	end

	def fetch_mouse_data
		@@mev = MouseEvent.new
		Ncurses::getmouse(@@mev)
	end

	def mouse
		@@mev
	end

	def clear_keybuffer
		Ncurses.flushinp
	end

	def self.included(this)
		@@window = Ncurses.initscr
		starti
	end

	# (Re)Start the Interface
	def starti
		@@running = true
		@@screen = Ncurses.stdscr
		@@screen.keypad(true)
		Ncurses.start_color
		Ncurses.use_default_colors

		Ncurses.noecho
		Ncurses.curs_set 0
		Ncurses.halfdelay(200)
		@@colortable = []
	end

	MOUSE_MASK_ON = Ncurses::ALL_MOUSE_EVENTS | Ncurses::REPORT_MOUSE_POSITION
	MOUSE_MASK_OFF = 0

	def init_mouse( interval )
		Ncurses.mouseinterval( interval )
		Ncurses.mousemask( MOUSE_MASK_ON, [] )
	end

	def stop_mouse
		Ncurses.mousemask( MOUSE_MASK_OFF, [] )
	end

	def self.refresh
		Ncurses.refresh
	end

	# Close the Interface
	def closei
		@@running = false
		Ncurses.echo
		Ncurses.nocbreak
		Ncurses.curs_set 1
		Ncurses.endwin
	end

	def running?() @@running end

	def cleari
		Ncurses.mvaddstr(0, 0, ' ' * (lines * cols))
	end

	def geti
		CLI.keytable(Ncurses.getch)
	end

	def set_title(x)
		print "\e]2;#{x}\007"
	end

	def lines
		Ncurses.LINES
	end

	def cols
		Ncurses.COLS
	end

	def movi(y=0, x=0)
		y < 0 and y += lines
		Ncurses.move(y, x)
	end

	def puti *args
		case args.size
		when 1
			Ncurses.addstr(args[0].to_s)
		when 2
			if (y = args[0]) < 0 then y += Ncurses.LINES end
			Ncurses.mvaddstr(y, 0, args[1].to_s)
		when 3
			if (y = args[0]) < 0 then y += Ncurses.LINES end
			Ncurses.mvaddstr(y, args[1], args[2].to_s)
		end
	end

	def attr_set(fg=-1, bg=-1, attr = nil)
		fg, bg, attr = fg if fg.is_a? Array
		if attr
			Ncurses.attrset(attr | Ncurses.COLOR_PAIR(get_color(fg, bg)))
		else
			Ncurses.color_set(get_color(fg, bg), nil)
		end
	end

	def attr_at(y=0, x=0, len=-1, fg=-1, bg=-1, attr=0)
		fg, bg, attr = fg if fg.is_a? Array
		y += lines if y < 0
		x += cols if x < 0
		attr ||= 0

		Ncurses.mvchgat(y, x, len, attr, get_color(fg, bg), nil)
	end

	def get_color(fg, bg)
		n = bg+2 + 9*(fg+2)
		color = @@colortable[n]
		unless color
			# create a new pair
			size = @@colortable.reject{|x| x.nil? }.size + 1
			Ncurses::init_pair(size, fg, bg)
			color = @@colortable[n] = size
		end
		return color
	end

	class MouseEvent # {{{
		attr_accessor :id, :x,:y,:z, :bstate
		def press1?() 0 != @bstate & Ncurses::BUTTON1_PRESSED end
		def press2?() 0 != @bstate & Ncurses::BUTTON2_PRESSED end
		def press3?() 0 != @bstate & Ncurses::BUTTON3_PRESSED end
		def press4?() 0 != @bstate & Ncurses::BUTTON4_PRESSED end

		## this does not work. BUTTON5_* is not defined
		def press5?() 0 != @bstate & Ncurses::BUTTON5_PRESSED end

		## this is an EVIL fix but I don't know better
		def press5?() 0 != ( @bstate & 128 ) + ( @bstate & 134217728 ) end


		def release1?() 0 != @bstate & Ncurses::BUTTON1_RELEASED end
		def release2?() 0 != @bstate & Ncurses::BUTTON2_RELEASED end
		def release3?() 0 != @bstate & Ncurses::BUTTON3_RELEASED end
		def release4?() 0 != @bstate & Ncurses::BUTTON4_RELEASED end
#		def release5?() 0 != @bstate & Ncurses::BUTTON5_RELEASED end

		def click1?() 0 != @bstate & Ncurses::BUTTON1_CLICKED end
		def click2?() 0 != @bstate & Ncurses::BUTTON2_CLICKED end
		def click3?() 0 != @bstate & Ncurses::BUTTON3_CLICKED end
		def click4?() 0 != @bstate & Ncurses::BUTTON4_CLICKED end
#		def click5?() 0 != @bstate & Ncurses::BUTTON5_CLICKED end

		def doubleclick1?() 0 != @bstate & Ncurses::BUTTON1_DOUBLE_CLICKED end
		def doubleclick2?() 0 != @bstate & Ncurses::BUTTON2_DOUBLE_CLICKED end
		def doubleclick3?() 0 != @bstate & Ncurses::BUTTON3_DOUBLE_CLICKED end
		def doubleclick4?() 0 != @bstate & Ncurses::BUTTON4_DOUBLE_CLICKED end
#		def doubleclick5?() 0 != @bstate & Ncurses::BUTTON5_DOUBLE_CLICKED end

		def tripleclick1?() 0 != @bstate & Ncurses::BUTTON1_TRIPLE_CLICKED end
		def tripleclick2?() 0 != @bstate & Ncurses::BUTTON2_TRIPLE_CLICKED end
		def tripleclick3?() 0 != @bstate & Ncurses::BUTTON3_TRIPLE_CLICKED end
		def tripleclick4?() 0 != @bstate & Ncurses::BUTTON4_TRIPLE_CLICKED end
#		def tripleclick5?() 0 != @bstate & Ncurses::BUTTON5_TRIPLE_CLICKED end

		def alt?() 0 != @bstate & Ncurses::BUTTON_ALT end
		def shift?() 0 != @bstate & Ncurses::BUTTON_SHIFT end
		def ctrl?() 0 != @bstate & Ncurses::BUTTON_CTRL end

		## too many keys {{{
#		def press6?() 0 != @bstate & Ncurses::BUTTON6_PRESSED end
#		def press7?() 0 != @bstate & Ncurses::BUTTON7_PRESSED end
#		def press8?() 0 != @bstate & Ncurses::BUTTON8_PRESSED end
#		def press9?() 0 != @bstate & Ncurses::BUTTON9_PRESSED end
#		def release6?() 0 != @bstate & Ncurses::BUTTON6_RELEASED end
#		def release7?() 0 != @bstate & Ncurses::BUTTON7_RELEASED end
#		def release8?() 0 != @bstate & Ncurses::BUTTON8_RELEASED end
#		def release9?() 0 != @bstate & Ncurses::BUTTON9_RELEASED end
#		def click6?() 0 != @bstate & Ncurses::BUTTON6_CLICKED end
#		def click7?() 0 != @bstate & Ncurses::BUTTON7_CLICKED end
#		def click8?() 0 != @bstate & Ncurses::BUTTON8_CLICKED end
#		def click9?() 0 != @bstate & Ncurses::BUTTON9_CLICKED end
#		def doubleclick6?() 0 != @bstate & Ncurses::BUTTON6_DOUBLE_CLICKED end
#		def doubleclick7?() 0 != @bstate & Ncurses::BUTTON7_DOUBLE_CLICKED end
#		def doubleclick8?() 0 != @bstate & Ncurses::BUTTON8_DOUBLE_CLICKED end
#		def doubleclick9?() 0 != @bstate & Ncurses::BUTTON9_DOUBLE_CLICKED end
#		def tripleclick6?() 0 != @bstate & Ncurses::BUTTON6_TRIPLE_CLICKED end
#		def tripleclick7?() 0 != @bstate & Ncurses::BUTTON7_TRIPLE_CLICKED end
#		def tripleclick8?() 0 != @bstate & Ncurses::BUTTON8_TRIPLE_CLICKED end
#		def tripleclick9?() 0 != @bstate & Ncurses::BUTTON9_TRIPLE_CLICKED end
		# }}}
	end # }}}
end