Created
February 23, 2010 17:45
-
-
Save rkumar/312468 to your computer and use it in GitHub Desktop.
ncurses common io routines
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #*******************************************************# | |
| # Note: all method here require the presence of a footer_win | |
| # and header_win to have been created, | |
| # with the exception of print_help_page. | |
| # | |
| # Arunachalesha | |
| # $Id$ # | |
| #*******************************************************# | |
| module Commons1 | |
| # from which line to print in footer_win | |
| LINEONE = 1 | |
| FOOTER_COLOR_PAIR = 6 | |
| MAIN_WINDOW_COLOR_PAIR = 5 | |
| ERROR_COLOR_PAIR = 7 | |
| # @table_width is a constant in caller based on which we decide where to show | |
| # key_labels and error messages. | |
| # WHEN WE CREATE A PANEL BWLOW we can do away wit that. FIXME XXX | |
| # return true for y, false for n | |
| # e.g. | |
| # <code> | |
| # ret = @main.askyesno(nil, "Are you sure you wish to proceed?") | |
| # </code> | |
| # 2008-10-09 18:27 added call to print_footer_help | |
| def askyesno(win, askstr, default = "N", helptext="Helptext for this question") | |
| win ||= @footer_win | |
| askstr = "#{askstr} [#{default}]: " | |
| len = askstr.length | |
| clear_error # 2008-10-13 20:26 | |
| print_this(win, askstr, 4, LINEONE, 0) | |
| labels=["?~Help "," ~ ", "N~No ", "Y~Yes "] | |
| print_key_labels( 0, 0, labels) | |
| win.refresh | |
| #Ncurses.echo(); | |
| yn='' | |
| #win.mvwgetnstr(Ncurses.LINES-3,askstr.length,yn,maxlen) | |
| while true | |
| ch=win.mvwgetch(LINEONE,askstr.length) | |
| if ch < 0 || ch > 255 | |
| next | |
| end | |
| yn = ch.chr | |
| yn = default if yn == '' or ch == 10 # KEY_ENTER | |
| yn.downcase! | |
| break if yn =~/[yn]/ | |
| if yn == '?' | |
| print_footer_help(helptext) | |
| print_key_labels( 0, 0, labels) | |
| next | |
| end | |
| Ncurses.beep | |
| end | |
| #Ncurses.noecho(); | |
| clear_error # 2008-11-06 19:27 | |
| restore_application_key_labels # must be done after using print_key_labels | |
| win.refresh | |
| return yn == 'y' | |
| end | |
| # return y or n or c | |
| def askyesnocancel(win, askstr, default = "N") | |
| win ||= @footer_win | |
| askstr = "#{askstr} [#{default}]: " | |
| len = askstr.length | |
| clear_error # 2008-10-13 20:26 | |
| print_this(win, askstr, 4, LINEONE, 0) | |
| labels=["N~No ", "Y~Yes ","C~Cancel"," ~ "] | |
| print_key_labels( 0, 0, labels) | |
| win.refresh | |
| #Ncurses.echo(); | |
| yn='' | |
| #win.mvwgetnstr(LINEONE,askstr.length,yn,maxlen) | |
| while true | |
| ch=win.mvwgetch(LINEONE,askstr.length) | |
| yn = ch.chr | |
| yn = default if yn == '' or ch == 10 # KEY_ENTER | |
| yn.downcase! | |
| break if yn =~/[ync]/ | |
| Ncurses.beep | |
| end | |
| #Ncurses.noecho(); | |
| restore_application_key_labels # must be done after using print_key_labels | |
| return yn | |
| end | |
| # return single digit from given choices | |
| # e.g. | |
| # <code> | |
| # labels=["N~No ", "Y~Yes ","C~Cancel"," ~ ","S~SurpiseMe","G~GoAway! "] | |
| # ret = @main.askchoice(nil, "Are you sure you wish to proceed?","N",labels,"NYCSG") | |
| # @main.clear_error | |
| # </code> | |
| def askchoice(win, askstr, default, labels, validchars, config={}) | |
| win ||= @footer_win | |
| askstr = "#{askstr} [#{default}]: " | |
| len = askstr.length | |
| helptext = config.fetch("helptext", "No helptext provided for this action") | |
| clear_error # 2008-10-13 20:26 | |
| print_this(win, askstr, 4, LINEONE, 0) | |
| #labels=["N~No ", "Y~Yes ","C~Cancel"," ~ "] | |
| print_key_labels( 0, 0, labels) | |
| #Ncurses.echo(); | |
| yn='' | |
| validchars.downcase! | |
| #win.mvwgetnstr(LINEONE-3,askstr.length,yn,maxlen) | |
| while true | |
| ch=win.mvwgetch(LINEONE,askstr.length) | |
| yn = ch.chr | |
| # 2008-10-31 18:08 | |
| if ch == ?\C-g or yn == '?' | |
| print_footer_help(helptext) | |
| print_key_labels( 0, 0, labels) | |
| next | |
| end | |
| yn = default if yn == '' or ch == 10 # KEY_ENTER | |
| yn.downcase! | |
| break if validchars.include?yn | |
| Ncurses.beep | |
| end | |
| #Ncurses.noecho(); | |
| restore_application_key_labels # must be done after using print_key_labels | |
| return yn | |
| end | |
| # complex version of get_string that allows for trappng of control character | |
| # such as C-c and C-h and TAB for completion | |
| # validints contains int codes not chars. | |
| # TODO We should put a field there, make it visible and mv it to after the prompt | |
| # and handle all editing events on it. | |
| def ask_string(win, askstr, maxlen, default, labels, validints=[], helptext="") | |
| win ||= @footer_win | |
| askstr = "#{askstr} [#{default}]: " | |
| len = askstr.length | |
| clear_error # 2008-10-13 20:26 | |
| print_this(win, askstr, 4, LINEONE, 0) | |
| mylabels=["^G~Help ", "^C~Cancel"] | |
| mylabels += labels if !labels.nil? | |
| begin | |
| print_key_labels( 0, 0, mylabels) | |
| Ncurses.echo(); | |
| yn="" | |
| #win.mvwgetnstr(LINEONE-3,askstr.length,yn,maxlen) | |
| while true | |
| ch=win.mvwgetch(LINEONE,len) | |
| case ch | |
| when 3 # -1 # C-c | |
| return -1, nil | |
| when 10 | |
| break | |
| when ?\C-h, ?\C-? | |
| len -= 1 | |
| yn.chop! | |
| when ?\C-g | |
| print_footer_help(helptext) | |
| return 7, nil | |
| else | |
| if validints.include?ch | |
| print_status("Found in validints") | |
| return ch, nil | |
| else | |
| # if in allowed character allow entry, otherwise beep | |
| if ch.chr =~ /[[:cntrl:]]/ | |
| Ncurses.beep | |
| next | |
| end | |
| end | |
| yn << ch.chr | |
| len += 1 | |
| end | |
| end | |
| yn = default if yn == "" | |
| ensure | |
| Ncurses.noecho(); | |
| restore_application_key_labels # must be done after using print_key_labels | |
| end | |
| return 0, yn | |
| end | |
| def get_string(win, askstr, maxlen=20, default="", labels=nil ) | |
| win ||= @footer_win | |
| askstr = "#{askstr} [#{default}]: " | |
| len = askstr.length | |
| clear_error # 2008-11-06 19:25 | |
| print_this(win, askstr, 4, LINEONE, 0) | |
| #labels=["N~No ", "Y~Yes ","C~Cancel"," ~ "] | |
| mylabels = ["^G~Help ", "^C~Cancel"] | |
| mylabels = (mylabels + labels) if !labels.nil? | |
| print_key_labels( 0, 0, mylabels) | |
| Ncurses.echo(); | |
| yn='' | |
| begin | |
| Signal.trap("INT"){ return nil } | |
| win.mvwgetnstr(LINEONE,askstr.length,yn,maxlen) | |
| rescue | |
| yn='' | |
| ensure | |
| Ncurses.noecho(); | |
| clear_error # 2008-11-02 11:51 | |
| restore_application_key_labels # must be done after using print_key_labels | |
| end | |
| yn = default if yn == "" # 2008-10-31 18:59 | |
| return yn | |
| end | |
| def print_this(win, text, color, x, y) | |
| if(win == nil) | |
| raise "win nil in printthis" | |
| end | |
| color=Ncurses.COLOR_PAIR(color); | |
| win.attron(color); | |
| #win.mvprintw(x, y, "%-40s" % text); | |
| win.mvprintw(x, y, "%s" % text); | |
| win.attroff(color); | |
| win.refresh | |
| end | |
| # prints error in footer_win only | |
| def print_error(text) | |
| clear_error | |
| print_in_middle(@footer_win, LINEONE, 10, 80, text, Ncurses.COLOR_PAIR(ERROR_COLOR_PAIR)) | |
| end | |
| # prints status in footer_win only | |
| def print_status(text) | |
| text = text[text.length-80..-1] if text.length > 80 | |
| print_error(text) | |
| end | |
| # clear previous error, call inside getch loop after each ch. | |
| def clear_error | |
| print_this(@footer_win, "%-*s" % [Ncurses.COLS," "], 5, LINEONE, 0) | |
| end | |
| # This is only for the menu program, in which we print current action/menu string in the | |
| # key labels below. | |
| # Its a dirty hack edpending on: | |
| # * String CurRow present in key labels | |
| # * field_init_proc called this method to set it. | |
| def print_action(text) | |
| print_this(@footer_win, " %-10s" % ("["+text+"]"), FOOTER_COLOR_PAIR, @action_posy, @action_posx) | |
| end | |
| # the old historical program which prints a string in middle of whereever | |
| # thanks to this i was using stdscr which must never be used | |
| def print_in_middle(win, starty, startx, width, string, color) | |
| if(win == nil) | |
| raise "window is nil" | |
| end | |
| x = Array.new | |
| y = Array.new | |
| Ncurses.getyx(win, y, x); | |
| if(startx != 0) | |
| x[0] = startx; | |
| end | |
| if(starty != 0) | |
| y[0] = starty; | |
| end | |
| if(width == 0) | |
| width = 80; | |
| end | |
| length = string.length; | |
| temp = (width - length)/ 2; | |
| x[0] = startx + temp.floor; | |
| win.attron(color); | |
| win.mvprintw(y[0], x[0], "%s", string); | |
| win.attroff(color); | |
| win.refresh(); | |
| end | |
| # splits that bad hack array into even and odd arrays | |
| # and prints on last 2 lines | |
| def print_key_labels(posy, posx, arr) | |
| ## paint so-called key bindings from key_labels | |
| posx = 0 | |
| even = [] | |
| odd = [] | |
| arr.each_index { |i| | |
| if i % 2 == 0 | |
| even << arr[i] | |
| else | |
| odd << arr[i] | |
| end | |
| } | |
| posy = LINEONE+1 | |
| print_key_labels_row(posy, posx, even) | |
| posy = LINEONE+2 | |
| print_key_labels_row(posy, posx, odd) | |
| # 2008-09-29 21:58 | |
| @footer_win.wrefresh # needed else secod row not shown after askchoice XXX | |
| end | |
| def print_key_labels_row(posy, posx, arr) | |
| #clear first | |
| my_form_win = @footer_win | |
| # first clear the line | |
| print_this(my_form_win, "%-*s" % [Ncurses.COLS," "], FOOTER_COLOR_PAIR, posy, 0) | |
| padding = 8 | |
| padding = 4 if arr.length > 5 | |
| padding = 0 if arr.length > 7 | |
| arr.each_index { |i| | |
| kl = arr[i].split('~') | |
| if kl[0].strip !="" # don't print that white blank space for fillers | |
| color_pair=2 | |
| my_form_win.attron(Ncurses.COLOR_PAIR(color_pair)) | |
| my_form_win.mvprintw(posy, posx, "%s" % kl[0] ); | |
| my_form_win.attroff(Ncurses.COLOR_PAIR(color_pair)) | |
| end | |
| color_pair=FOOTER_COLOR_PAIR | |
| posx = posx + kl[0].length | |
| my_form_win.attron(Ncurses.COLOR_PAIR(color_pair)) | |
| lab = sprintf(" %s %*s" , kl[1], padding, " "); | |
| # hack | |
| if kl[1].strip == "CurRow" | |
| @action_posx = posx | |
| @action_posy = posy | |
| end | |
| my_form_win.mvprintw(posy, posx, lab) | |
| my_form_win.attroff(Ncurses.COLOR_PAIR(color_pair)) | |
| posx = posx + lab.length | |
| } | |
| end | |
| # since it must always be @header_win, we should remove the first param | |
| # why should user have any direct access to those 2 windows. | |
| def old_print_header(win, htext, posy = 0, posx = 0) | |
| win.attron(Ncurses.COLOR_PAIR(6)) | |
| win.mvprintw(posy, posx, "%-*s" % [Ncurses.COLS, htext] ); | |
| win.attroff(Ncurses.COLOR_PAIR(6)) | |
| end | |
| def print_header(htext, posy = 0, posx = 0) | |
| win = @header_win | |
| win.attron(Ncurses.COLOR_PAIR(6)) | |
| win.mvprintw(posy, posx, "%-*s" % [Ncurses.COLS, htext] ); | |
| win.attroff(Ncurses.COLOR_PAIR(6)) | |
| end | |
| # since it must always be @header_win, we should remove the first param | |
| # why should user have any direct access to those 2 windows. | |
| def old_print_top_right(win, htext) | |
| hlen = htext.length | |
| win.attron(Ncurses.COLOR_PAIR(6)) | |
| win.mvprintw(0, Ncurses.COLS-hlen, htext ); | |
| win.attroff(Ncurses.COLOR_PAIR(6)) | |
| #win.refresh | |
| end | |
| def print_top_right(htext) | |
| hlen = htext.length | |
| win = @header_win | |
| win.attron(Ncurses.COLOR_PAIR(6)) | |
| win.mvprintw(0, Ncurses.COLS-hlen, htext ); | |
| win.attroff(Ncurses.COLOR_PAIR(6)) | |
| #win.refresh | |
| end | |
| # prints labels defined by user in the DSL. | |
| # | |
| # Array of labels with: | |
| # | |
| # * position = [y,x] i.e, row, column | |
| # * text = "label text" | |
| # * color_pair = 6 (optional, default 6) | |
| def print_screen_labels(my_form_win, labelarr) | |
| table_width = @table_width || Ncurses.LINES-1 | |
| return if labelarr.nil? | |
| labelarr.each{ |lhash| | |
| posy, posx = lhash["position"] | |
| posy = table_width + posy if posy < 0 | |
| posx = Ncurses.COLS + posy if posx < 0 | |
| text = lhash["text"] | |
| color_pair = lhash["color_pair"] || 6 | |
| my_form_win.attron(Ncurses.COLOR_PAIR(color_pair)) | |
| my_form_win.mvprintw(posy, posx, "%-s" % text ); | |
| my_form_win.attroff(Ncurses.COLOR_PAIR(color_pair)) | |
| } | |
| end | |
| def print_headers(form_hash) | |
| header = form_hash["header"] | |
| header_top_left = form_hash["header_top_left"] || "" | |
| header_top_center = form_hash["header_top_center"] || "" | |
| header_top_right = form_hash["header_top_right"] || "" | |
| posy = 0 | |
| posx = 0 | |
| htext = " <APP NAME> <VERSION> MAIN MENU" | |
| posy, posx, htext = header if !header.nil? | |
| print_header(htext + " %15s " % header_top_left + " %20s" % header_top_center , posy, posx) | |
| print_top_right(header_top_right) | |
| @header_win.wrefresh(); | |
| end | |
| # 2008-10-09 18:27 askyesno and ask_string can be passed some text | |
| # to be popped up when a user enters ? | |
| def print_footer_help(helptext) | |
| print_this(@footer_win, "%-*s" % [Ncurses.COLS," "], 6, LINEONE+1, 0) | |
| print_this(@footer_win, "%-*s" % [Ncurses.COLS," "], 6, LINEONE+2, 0) | |
| print_this(@footer_win, "%s" % helptext, 6, LINEONE+1, 0) | |
| sleep(5) | |
| end | |
| def print_help_page(filename = "TODO") | |
| #require 'transactionviewer' | |
| #tp = TransactionViewer.new(nil) | |
| #tp.run | |
| require 'panelreader' | |
| tp = PanelReader.new() | |
| tp.view_file(filename) | |
| #require 'padreader' | |
| #tp = PadReader.new() | |
| #tp.view_file(filename) | |
| end | |
| #def newaskyesno(win, askstr, default = "N", helptext="Helptext for this question") | |
| ## | |
| # user may pass in actions for each key along with other config values in config hash. | |
| # config can contain default, helptext, labels and 'y', 'n' | |
| def newaskyesno(win, askstr, config = {}) | |
| win ||= @footer_win | |
| default = config.fetch("default", "N") | |
| helptext = config.fetch("helptext", "This is helptext for this action") | |
| askstr = "#{askstr} [#{default}]: " | |
| len = askstr.length | |
| clear_error # 2008-10-13 20:26 | |
| print_this(win, askstr, 4, LINEONE, 0) | |
| labels=config.fetch("labels", ["?~Help "," ~ ", "N~No ", "Y~Yes "]) | |
| print_key_labels( 0, 0, labels) | |
| win.refresh | |
| #Ncurses.echo(); | |
| yn='' | |
| #win.mvwgetnstr(Ncurses.LINES-3,askstr.length,yn,maxlen) | |
| while true | |
| ch=win.mvwgetch(LINEONE,askstr.length) | |
| if ch < 0 || ch > 255 | |
| next | |
| end | |
| yn = ch.chr | |
| yn = default if yn == '' or ch == 10 # KEY_ENTER | |
| yn.downcase! | |
| break if yn =~/[yn]/ | |
| if yn == '?' | |
| print_footer_help(helptext) | |
| print_key_labels( 0, 0, labels) | |
| next | |
| end | |
| Ncurses.beep | |
| end # while | |
| #Ncurses.noecho(); | |
| begin | |
| config[yn].call if config.include? yn | |
| ensure | |
| restore_application_key_labels # must be done after using print_key_labels | |
| win.refresh | |
| end | |
| return yn == 'y' | |
| end | |
| ### ADD HERE ### | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment