def display_menu list, options={}  # --- {{{
      indexing = options[:indexing]
      #indexcolor = options[:indexcolor] || get_color($normalcolor, :yellow, :black)
      indexcolor = $datacolor || 7 # XXX above line crashing on choose()
      indexatt = Ncurses::A_BOLD
      #
      # the index to start from (used when scrolling a long menu such as file list)
      startindex = options[:startindex] || 0

      max_cols = 3 #  maximum no of columns, we will reduce based on data size
      l_succ = "`"
      act_height = @height
      if @box
        act_height = @height - 2
      end
      lh = list.size
      if lh < act_height
        $log.debug "DDD inside one window" if $log.debug? 
        list.each_with_index { |e, i| 
          text = e
          case e
          when Array
            text = e.first + " ..."
          end
          if indexing == :number
            mnem = i+1
            text = "%d. %s" % [i+1, text] 
          elsif indexing == :letter
            mnem = l_succ.succ!
            text = "%s. %s" % [mnem, text] 
          end
          @window.printstring i+@row_offset, 1, text, $normalcolor  
          if indexing
            @window.mvchgat(y=i+@row_offset, x=1, max=1, indexatt, indexcolor, nil)
          end
        }
      else
        $log.debug "DDD inside two window" if $log.debug? 
        row = 0
        h = act_height
        cols = (lh*1.0 / h).ceil
        cols = max_cols if cols > max_cols
        # sometimes elements are large like directory paths, so check size
        datasize = list.first.length
        if datasize > @width/3 # keep safety margin since checking only first row
          cols = 1
        elsif datasize > @width/2
          cols = [2,cols].min
        end
        adv = (@width/cols).to_i
        colct = 0
        col = 1
        $log.debug "DDDcols #{cols}, adv #{adv} size: #{lh} h: #{act_height} w #{@width} " if $log.debug? 
        list.each_with_index { |e, i| 
          text = e
          # signify that there's a deeper level
          case e
          when Array
            text = e.first + "..."
          end
          if indexing == :number
            mnem = i+1
            text = "%d. %s" % [mnem, text] 
          elsif indexing == :letter
            mnem = l_succ.succ!
            text = "%s. %s" % [mnem, text] 
          end
          # print only within range and window height
          #if i >= startindex && row < @window.actual_height
          if i >= startindex && row < @window.height
            $log.debug "XXX: MENU #{i} > #{startindex} row #{row} col #{col} "
            @window.printstring row+@row_offset, col, text, $normalcolor  
            if indexing
              @window.mvchgat(y=row+@row_offset, x=col, max=1, indexatt, indexcolor, nil)
            end
          colct += 1
          if colct == cols
            col = 1
            row += 1
            colct = 0
          else
            col += adv
          end
          end # startindex
        }
      end
      Ncurses::Panel.update_panels();
      Ncurses.doupdate();
      @window.wrefresh
    end
def display_menu list, options={}  # --- {{{
      indexing = options[:indexing]
      #indexcolor = options[:indexcolor] || get_color($normalcolor, :yellow, :black)
      indexcolor = $datacolor || 7 # XXX above line crashing on choose()
      indexatt = Ncurses::A_BOLD
      #
      # the index to start from (used when scrolling a long menu such as file list)
      startindex = options[:startindex] || 0

      max_cols = 3 #  maximum no of columns, we will reduce based on data size
      l_succ = "`"
      act_height = @height
      if @box
        act_height = @height - 2
      end
      lh = list.size
      if lh < act_height
        $log.debug "DDD inside one window" if $log.debug? 
        list.each_with_index { |e, i| 
          text = e
          case e
          when Array
            text = e.first + " ..."
          end
          if indexing == :number
            mnem = i+1
            text = "%d. %s" % [i+1, text] 
          elsif indexing == :letter
            mnem = l_succ.succ!
            text = "%s. %s" % [mnem, text] 
          end
          @window.printstring i+@row_offset, 1, text, $normalcolor  
          if indexing
            @window.mvchgat(y=i+@row_offset, x=1, max=1, indexatt, indexcolor, nil)
          end
        }
      else
        $log.debug "DDD inside two window" if $log.debug? 
        row = 0
        h = act_height
        cols = (lh*1.0 / h).ceil
        cols = max_cols if cols > max_cols
        # sometimes elements are large like directory paths, so check size
        datasize = list.first.length
        if datasize > @width/3 # keep safety margin since checking only first row
          cols = 1
        elsif datasize > @width/2
          cols = [2,cols].min
        end
        adv = (@width/cols).to_i
        colct = 0
        col = 1
        $log.debug "DDDcols #{cols}, adv #{adv} size: #{lh} h: #{act_height} w #{@width} " if $log.debug? 
        list.each_with_index { |e, i| 
          text = e
          # signify that there's a deeper level
          case e
          when Array
            text = e.first + "..."
          end
          if indexing == :number
            mnem = i+1
            text = "%d. %s" % [mnem, text] 
          elsif indexing == :letter
            mnem = l_succ.succ!
            text = "%s. %s" % [mnem, text] 
          end
          # print only within range and window height
          #if i >= startindex && row < @window.actual_height
          if i >= startindex && row < @window.height
            $log.debug "XXX: MENU #{i} > #{startindex} row #{row} col #{col} "
            @window.printstring row+@row_offset, col, text, $normalcolor  
            if indexing
              @window.mvchgat(y=row+@row_offset, x=col, max=1, indexatt, indexcolor, nil)
            end
          colct += 1
          if colct == cols
            col = 1
            row += 1
            colct = 0
          else
            col += adv
          end
          end # startindex
        }
      end
      Ncurses::Panel.update_panels();
      Ncurses.doupdate();
      @window.wrefresh
    end
--- }}}

 Displays list in a window at bottom of screen, if large then 2 or 3 columns.
 @param [Array] list of string to be displayed
 @param [Hash]  configuration options: indexing and indexcolor
 indexing - can be letter or number. Anything else will be ignored, however
  it will result in first letter being highlighted in indexcolor
 indexcolor - color of mnemonic, default green