Removed some unnecessary direct-access instance variables
[nfoiled.git] / lib / nfoiled / window.rb
blob4e02e7b54fd6d767c180afc6088b454c7946e6cb
1 module Nfoiled
2   ##
3   # An `Nfoiled::Window` is a "box" in the terminal to which output can be
4   # printed and from which input can be received. A basic Nfoiled application
5   # will utilize only one of these, a single `Window` covering the entirety
6   # of the `Terminal`'s available area.
7   class Window
8     
9     class <<self
10       # This is simply an accessor for all the windows on the current Terminal.
11       attr_reader :windows
12       def windows; Terminal.current.windows; end
13     end
14     
15     # ==============
16     # = Attributes =
17     # ==============
18     
19     # The Y co-ordinate of the top left corner of this `Window`'s bounding box
20     attr_reader :top
21     # The X co-ordinate of the top left corner of this `Window`'s bounding box
22     attr_reader :left
23     # The height in lines of this `Window`'s bounding box
24     attr_reader :height
25     # The width in columns of this `Window`'s bounding box
26     attr_reader :width
27     
28     # The actual window object as returned by Ncurses
29     attr_reader :wrapee
30     
31     # The `Terminal` that this `Window` pertains to
32     attr_reader :owner
33     
34     # The proc to be run when a character is received
35     attr_accessor :on_key
36     
37     # ====================
38     # = Setup / Teardown =
39     # ====================
40     
41     ##
42     # Responsible for creating a new `Window`, this will also take care of
43     # initializing Ncurses if necessary. See `newwin(3X)`.
44     def initialize opts = Hash.new
45       Nfoiled::initialize
46       
47       @wrapee = ::Ncurses.newwin(
48         opts[:height] ? @height = opts[:height] : ::Ncurses.LINES,
49         opts[:width]  ? @width =  opts[:width]  : ::Ncurses.COLS,
50         opts[:top]    ? @top =    opts[:top]    : 0,
51         opts[:left]   ? @left =   opts[:left]   : 0)
52       
53       ::Ncurses.wtimeout(wrapee, 0) # Prevents ncurses from blocking for input
54       
55       (@owner = Terminal.current).windows << self
56     end
57     
58     ##
59     # Destroys the `wrapee` of this `Window`, and removes this `Window`
60     # from its owning `Terminal`'s `#windows`. See `delwin(3X)`.
61     def destroy!
62       ::Ncurses.delwin(wrapee)
63       @wrapee = nil
64       owner.windows.delete self
65     end
66     
67     # =========
68     # = Input =
69     # =========
70     
71     ##
72     # Gets a single character from the input buffer for this window. Returns
73     # nil if there are no new characters in the buffer. See `wgetch(3X)`.
74     def gets
75       chr = Key.process ::Ncurses.wgetch(wrapee)
76       chr == -1 ? nil : chr
77     end
78     
79     ##
80     # This sets this `Window` as the current `Terminal.acceptor`.
81     def focus!
82       owner.acceptor = self
83       update
84     end
85     
86     ##
87     # Defines a block that controls how the global input loop from
88     # `Nfoiled::read!` handles input when this window has focus.
89     # 
90     # This acts as both a getter & setter, depending on whether a block is
91     # passed in or not.
92     def on_key
93       block_given? ? @on_key = Proc.new : @on_key
94     end
95     
96     # ==========
97     # = Output =
98     # ==========
99     
100     ##
101     # Prints a string to the window
102     def print string
103       wrapee.printw string
104       update
105     end
106     
107     ##
108     # Updates the virtual screen associated with this window. See `wnoutrefresh(3X)`.
109     def update
110       wrapee.wnoutrefresh
111     end
112     
113     ##
114     # Prints a string, followed by a newline, to the window
115     def puts string
116       self.print string.to_s + "\n"
117     end
118   end