Search code examples
rubycurses

Creating a menu with curses


I'm trying to follow this tutorial: http://www.tldp.org/HOWTO/NCURSES-Programming-HOWTO/keys.html

But I'm afraid I'm not getting on well with it at all.

This isn't the best code in the world, but it illustrates what I want to do:

        require "curses"
        include Curses

        init_screen #initialize first screen
        start_color #
        noecho

    close = false


        t1 = Thread.new{
        four = Window.new(5,60,2,2)
        four.box('|', '-')


            t2 = Thread.new{

                menu = Window.new(7,40,7,2)
                menu.box('|', '-')
                menu.setpos 1,1
                menu.addstr "item_one"
                menu.setpos 2,1

                menu.attrset(A_STANDOUT)

                menu.addstr "item_two"
                menu.setpos 3,1

                menu.attrset(A_NORMAL)

                menu.addstr "item_three"
                menu.setpos 4,1
                menu.addstr "item_four"

                menu.getch
            }
            t2.join

        while close == false
            ch = four.getch
            case ch
                when 'w'
                    four.setpos 2,1
                    four.addstr 'move up'
                    four.refresh
                when 's'
                    four.setpos 2,1
                    four.addstr 'move down'
                    four.refresh
                when 'x'
                    close = true
            end
        end


        }
        t1.join

By pressing W and D keys, I want to move the highlight up and down the menu items in the menu window. Literally no idea how I can move that highlight. It would mean moving the attribute setter in the code. I really don't know. There's not many resources out there in way of Curses.


Solution

  • there is no need for threads in your example.

    you can see how this can be done here: https://gist.github.com/phoet/6988038

    require "curses"
    include Curses
    
    init_screen
    start_color
    noecho
    
    def draw_menu(menu, active_index=nil)
      4.times do |i|
        menu.setpos(i + 1, 1)
        menu.attrset(i == active_index ? A_STANDOUT : A_NORMAL)
        menu.addstr "item_#{i}"
      end
    end
    
    def draw_info(menu, text)
      menu.setpos(1, 10)
      menu.attrset(A_NORMAL)
      menu.addstr text
    end
    
    position = 0
    
    menu = Window.new(7,40,7,2)
    menu.box('|', '-')
    draw_menu(menu, position)
    while ch = menu.getch
      case ch
      when 'w'
        draw_info menu, 'move up'
        position -= 1
      when 's'
        draw_info menu, 'move down'
        position += 1
      when 'x'
        exit
      end
      position = 3 if position < 0
      position = 0 if position > 3
      draw_menu(menu, position)
    end