1 use {chtype, curses, platform_specific, ptr, Input, ToChtype, ERR};
2 use std::ffi::CString;
3
4 #[derive(Debug)]
5 pub struct Window {
6 #[cfg(windows)]
7 _window: *mut curses::WINDOW,
8 #[cfg(unix)]
9 _window: curses::WINDOW,
10 _stdscr: bool,
11 _deleted: bool,
12 }
13
14 #[cfg(windows)]
15 type WindowPointer = *mut curses::WINDOW;
16 #[cfg(unix)]
17 type WindowPointer = curses::WINDOW;
18
19 impl Window {
20 /// Adds the chtype ch to the window at the current cursor position, and advances the cursor.
21 ///
22 /// Note that chtypes can convey both text (a single character) and attributes, including a
23 /// color pair.
addch<T: ToChtype>(&self, ch: T) -> i3224 pub fn addch<T: ToChtype>(&self, ch: T) -> i32 {
25 unsafe { curses::waddch(self._window, ch.to_chtype()) }
26 }
27
28 /// Write all the characters of the string to the given window.
29 ///
30 /// The functionality is similar to calling window.addch() once for each character in the
31 /// string.
addstr<T: AsRef<str>>(&self, string: T) -> i3232 pub fn addstr<T: AsRef<str>>(&self, string: T) -> i32 {
33 let s = CString::new(string.as_ref()).unwrap();
34 unsafe { curses::waddstr(self._window, s.as_ptr()) }
35 }
36
37 /// Write at most length characters; if length is negative, then the entire string will be
38 /// added.
addnstr<T: AsRef<str>>(&self, string: T, length: usize) -> i3239 pub fn addnstr<T: AsRef<str>>(&self, string: T, length: usize) -> i32 {
40 let s = CString::new(string.as_ref()).unwrap();
41 unsafe { curses::waddnstr(self._window, s.as_ptr(), length as i32) }
42 }
43
44 /// Retrieve attributes for the given window.
45 ///
46 /// ```rust
47 /// use pancurses::{A_BOLD, initscr, endwin};
48 /// let window = initscr();
49 /// window.attron(A_BOLD);
50 /// let (active_attributes, color_pair) = window.attrget();
51 /// assert_eq!(A_BOLD, active_attributes);
52 /// endwin();
53 /// ```
attrget(&self) -> (chtype, i16)54 pub fn attrget(&self) -> (chtype, i16) {
55 let mut attributes: chtype = 0;
56 let mut color_pair: i16 = 0;
57 unsafe {
58 curses::wattr_get(
59 self._window,
60 &mut attributes,
61 &mut color_pair,
62 ptr::null_mut(),
63 );
64 }
65 (attributes, color_pair)
66 }
67
68 /// Turns off the named attributes without affecting any other attributes.
attroff<T: Into<chtype>>(&self, attributes: T) -> i3269 pub fn attroff<T: Into<chtype>>(&self, attributes: T) -> i32 {
70 platform_specific::_attroff(self._window, attributes.into())
71 }
72
73 /// Turns on the named attributes without affecting any other attributes.
attron<T: Into<chtype>>(&self, attributes: T) -> i3274 pub fn attron<T: Into<chtype>>(&self, attributes: T) -> i32 {
75 platform_specific::_attron(self._window, attributes.into())
76 }
77
78 /// Sets the current attributes of the given window to attributes.
attrset<T: Into<chtype>>(&self, attributes: T) -> i3279 pub fn attrset<T: Into<chtype>>(&self, attributes: T) -> i32 {
80 platform_specific::_attrset(self._window, attributes.into())
81 }
82
83 /// Not only change the background, but apply it immediately to every cell in the window.
bkgd<T: Into<chtype>>(&self, ch: T) -> i3284 pub fn bkgd<T: Into<chtype>>(&self, ch: T) -> i32 {
85 unsafe { curses::wbkgd(self._window, ch.into()) }
86 }
87
88 /// Manipulate the background of a window. The background is a chtype consisting of any
89 /// combination of attributes and a character; it is combined with each chtype added or
90 /// inserted to the window by addch() or insch(). Only the attribute part is used to set
91 /// the background of non-blank characters, while both character and attributes are used
92 /// for blank positions.
bkgdset<T: Into<chtype>>(&self, ch: T)93 pub fn bkgdset<T: Into<chtype>>(&self, ch: T) {
94 unsafe { curses::wbkgdset(self._window, ch.into()) }
95 }
96
97 /// Draw a border around the edges of the window.
border<T: ToChtype>( &self, left_side: T, right_side: T, top_side: T, bottom_side: T, top_left_corner: T, top_right_corner: T, bottom_left_corner: T, bottom_right_corner: T, ) -> i3298 pub fn border<T: ToChtype>(
99 &self,
100 left_side: T,
101 right_side: T,
102 top_side: T,
103 bottom_side: T,
104 top_left_corner: T,
105 top_right_corner: T,
106 bottom_left_corner: T,
107 bottom_right_corner: T,
108 ) -> i32 {
109 unsafe {
110 curses::wborder(
111 self._window,
112 left_side.to_chtype(),
113 right_side.to_chtype(),
114 top_side.to_chtype(),
115 bottom_side.to_chtype(),
116 top_left_corner.to_chtype(),
117 top_right_corner.to_chtype(),
118 bottom_left_corner.to_chtype(),
119 bottom_right_corner.to_chtype(),
120 )
121 }
122 }
123
124 /// Changes the attributes of a given number of characters starting at the current cursor
125 /// location. It does not update the cursor and does not perform wrapping. A character count
126 /// of -1 or greater than the remaining window width means to change attributes all the way
127 /// to the end of the current line.
chgat(&self, n: i32, attributes: chtype, color_pair: i16) -> i32128 pub fn chgat(&self, n: i32, attributes: chtype, color_pair: i16) -> i32 {
129 unsafe { curses::wchgat(self._window, n, attributes, color_pair, ptr::null_mut()) }
130 }
131
132 /// Similar to erase(), but also calls clearok() to ensure that the the window is cleared on
133 /// the next refresh().
clear(&self) -> i32134 pub fn clear(&self) -> i32 {
135 unsafe { curses::wclear(self._window) }
136 }
137
138 /// With clearok(), if bf is TRUE, the next call to refresh() with
139 /// this window will clear the screen completely and redraw the
140 /// entire screen.
clearok(&self, bf: bool) -> i32141 pub fn clearok(&self, bf: bool) -> i32 {
142 unsafe { curses::clearok(self._window, bf as u8) }
143 }
144
145 /// Clear the window from the current cursor position to the end of the window.
clrtobot(&self) -> i32146 pub fn clrtobot(&self) -> i32 {
147 unsafe { curses::wclrtobot(self._window) }
148 }
149
150 /// Clear the window from the current cursor position to the end of the current line.
clrtoeol(&self) -> i32151 pub fn clrtoeol(&self) -> i32 {
152 unsafe { curses::wclrtoeol(self._window) }
153 }
154
155 /// Sets the current color of the given window to the foreground/background combination
156 /// described by the color pair parameter.
color_set(&self, color_pair: i16) -> i32157 pub fn color_set(&self, color_pair: i16) -> i32 {
158 unsafe { curses::wcolor_set(self._window, color_pair, ptr::null_mut()) }
159 }
160
161 /// Copy all text from this window to the destination window. The arguments src_tc and
162 /// src_tr specify the top left corner of the region to be copied. dst_tc, dst_tr, dst_br,
163 /// and dst_bc specify the region within the destination window to copy to. The argument
164 /// "overlay", if TRUE, indicates that the copy is done non-destructively (as in overlay());
165 /// blanks in the source window are not copied to the destination window. When overlay is
166 /// FALSE, blanks are copied.
copywin( &self, destination_window: &Window, src_tr: i32, src_tc: i32, dst_tr: i32, dst_tc: i32, dst_br: i32, dst_bc: i32, overlay: bool, ) -> i32167 pub fn copywin(
168 &self,
169 destination_window: &Window,
170 src_tr: i32,
171 src_tc: i32,
172 dst_tr: i32,
173 dst_tc: i32,
174 dst_br: i32,
175 dst_bc: i32,
176 overlay: bool,
177 ) -> i32 {
178 unsafe {
179 curses::copywin(
180 self._window,
181 destination_window._window,
182 src_tr,
183 src_tc,
184 dst_tr,
185 dst_tc,
186 dst_br,
187 dst_bc,
188 overlay as i32,
189 )
190 }
191 }
192
193 /// Delete the character under the cursor. All characters to the right of the cursor
194 /// on the same line are moved to the left one position and hte last character on the
195 /// line is filled with a blank. The cursor position does not change.
delch(&self) -> i32196 pub fn delch(&self) -> i32 {
197 unsafe { curses::wdelch(self._window) }
198 }
199
200 /// Delete the line under the cursor. All lines below are moved up one line, and the
201 /// bottom line is cleared. The cursor position does not change.
deleteln(&self) -> i32202 pub fn deleteln(&self) -> i32 {
203 unsafe { curses::wdeleteln(self._window) }
204 }
205
206 /// Deletes the window, freeing all associated memory. In the case of overlapping windows,
207 /// subwindows should be deleted before the main window.
delwin(mut self) -> i32208 pub fn delwin(mut self) -> i32 {
209 self._deleted = true;
210 unsafe { curses::delwin(self._window) }
211 }
212
213 /// The same as subwin(), except that begy and begx are relative to the origin of the window
214 /// rather than the screen.
215 ///
216 /// There is no difference between subwindows and derived windows.
derwin(&self, nlines: i32, ncols: i32, begy: i32, begx: i32) -> Result<Window, i32>217 pub fn derwin(&self, nlines: i32, ncols: i32, begy: i32, begx: i32) -> Result<Window, i32> {
218 self.subwin(
219 nlines,
220 ncols,
221 begy + self.get_beg_y(),
222 begx + self.get_beg_x(),
223 )
224 }
225
226 /// Draw a border around the edge of the window. If any argument is zero, an appropriate
227 /// default is used.
draw_box<T: ToChtype>(&self, verch: T, horch: T) -> i32228 pub fn draw_box<T: ToChtype>(&self, verch: T, horch: T) -> i32 {
229 platform_specific::_draw_box(self._window, verch.to_chtype(), horch.to_chtype())
230 }
231
232 /// Creates an exact duplicate of the window.
dupwin(&self) -> Window233 pub fn dupwin(&self) -> Window {
234 let dup_win = unsafe { curses::dupwin(self._window) };
235 Window {
236 _window: dup_win,
237 _stdscr: false,
238 _deleted: false,
239 }
240 }
241
242 /// Reports whether the given screen-relative y, x coordinates fall within the window.
enclose(&self, y: i32, x: i32) -> bool243 pub fn enclose(&self, y: i32, x: i32) -> bool {
244 unsafe { curses::wenclose(self._window, y, x) > 0 }
245 }
246
247 /// Copies blanks (i.e. the background chtype) to every cell of the window.
erase(&self) -> i32248 pub fn erase(&self) -> i32 {
249 unsafe { curses::werase(self._window) }
250 }
251
252 /// Get the upper-left y coordinate of this window
get_beg_y(&self) -> i32253 pub fn get_beg_y(&self) -> i32 {
254 unsafe { curses::getbegy(self._window) }
255 }
256
257 // Get the upper-left x coordinate of this window
get_beg_x(&self) -> i32258 pub fn get_beg_x(&self) -> i32 {
259 unsafe { curses::getbegx(self._window) }
260 }
261
262 /// Get the upper-left y and x coordinates of this window
get_beg_yx(&self) -> (i32, i32)263 pub fn get_beg_yx(&self) -> (i32, i32) {
264 (self.get_beg_y(), self.get_beg_x())
265 }
266
267 /// Returns the given window's current background character and attributes.
getbkgd(&self) -> chtype268 pub fn getbkgd(&self) -> chtype {
269 unsafe { curses::getbkgd(self._window) }
270 }
271
272 /// Read a character from the terminal associated with the window.
273 ///
274 /// In nodelay mode, if there is no input waiting, None is returned. In delay mode,
275 /// the program will hang until the system passes text through to the program. Depending on
276 /// the setting of cbreak(), this will be after one character or after the first newline.
277 /// Unless noecho() has been set, the character will also be echoed into the designated window.
278 ///
279 /// If keypad() is TRUE, and a function key is pressed, the token for that function key will be
280 /// returned instead of the raw characters.
281 /// If nodelay(win, TRUE) has been called on the window and no input is waiting, None is
282 /// returned.
getch(&self) -> Option<Input>283 pub fn getch(&self) -> Option<Input> {
284 platform_specific::_wgetch(self._window)
285 }
286
287 /// Return the current x coordinate of the cursor
get_cur_x(&self) -> i32288 pub fn get_cur_x(&self) -> i32 {
289 unsafe { curses::getcurx(self._window) }
290 }
291
292 /// Return the current y coordinate of the cursor
get_cur_y(&self) -> i32293 pub fn get_cur_y(&self) -> i32 {
294 unsafe { curses::getcury(self._window) }
295 }
296
297 /// Return the current y and x coordinates of the cursor
get_cur_yx(&self) -> (i32, i32)298 pub fn get_cur_yx(&self) -> (i32, i32) {
299 (self.get_cur_y(), self.get_cur_x())
300 }
301
302 /// Return the maximum x value of this Window, in other words the number of columns.
get_max_x(&self) -> i32303 pub fn get_max_x(&self) -> i32 {
304 unsafe { curses::getmaxx(self._window) }
305 }
306
307 /// Return the maximum y value of this Window, in other words the number of rows.
get_max_y(&self) -> i32308 pub fn get_max_y(&self) -> i32 {
309 unsafe { curses::getmaxy(self._window) }
310 }
311
312 /// Return the maximum y and x value of this Window
get_max_yx(&self) -> (i32, i32)313 pub fn get_max_yx(&self) -> (i32, i32) {
314 (self.get_max_y(), self.get_max_x())
315 }
316
317 /// Draw a horizontal line using ch from the current cursor position. The line is at most
318 /// n characters long, or as many as fit into the window.
hline<T: ToChtype>(&self, ch: T, n: i32) -> i32319 pub fn hline<T: ToChtype>(&self, ch: T, n: i32) -> i32 {
320 unsafe { curses::whline(self._window, ch.to_chtype(), n) }
321 }
322
323 /// For positive n, insert n lines into the specified window above the current line.
324 /// The n bottom lines are lost. For negative n, delete n lines (starting with the one under
325 /// the cursor), and move the remaining lines up. The bottom n lines are cleared.
326 /// The current cursor position remains the same.
insdelln(&self, n: i32) -> i32327 pub fn insdelln(&self, n: i32) -> i32 {
328 unsafe { curses::winsdelln(self._window, n) }
329 }
330
331 /// A blank line is inserted above the current line and the bottom line is lost.
insertln(&self) -> i32332 pub fn insertln(&self) -> i32 {
333 unsafe { curses::winsertln(self._window) }
334 }
335
336 /// Returns true if the specified line in the specified window has been changed since the last
337 /// call to refresh().
is_linetouched(&self, line: i32) -> bool338 pub fn is_linetouched(&self, line: i32) -> bool {
339 unsafe { curses::is_linetouched(self._window, line) > 0 }
340 }
341
342 /// Returns true if the specified window has been changed since the last call to refresh().
is_touched(&self) -> bool343 pub fn is_touched(&self) -> bool {
344 unsafe { curses::is_wintouched(self._window) > 0 }
345 }
346
347 /// Controls whether getch() returns function/special keys as single key codes (e.g., the left
348 /// arrow key as KEY_LEFT).
349 ///
350 /// Per X/Open, the default for keypad mode is OFF. You'll probably want it on. With keypad
351 /// mode off, if a special key is pressed, getch() does nothing or returns ERR.
keypad(&self, use_keypad: bool) -> i32352 pub fn keypad(&self, use_keypad: bool) -> i32 {
353 unsafe { curses::keypad(self._window, use_keypad as u8) }
354 }
355
356 /// Insert the character ch before the character under the cursor.
357 ///
358 /// All characters to the right of the cursor are moved one space to the right, with the
359 /// possibility of the rightmost character on the line being lost. The insertion operation does
360 /// not change the cursor position.
insch<T: ToChtype>(&self, ch: T) -> i32361 pub fn insch<T: ToChtype>(&self, ch: T) -> i32 {
362 unsafe { curses::winsch(self._window, ch.to_chtype()) }
363 }
364
365 /// Converts between screen-relative and window-relative coordinates.
366 ///
367 /// A to_screen parameter of true means to convert from window to screen;
368 /// otherwise the reverse.
mouse_trafo(&self, y: i32, x: i32, to_screen: bool) -> (i32, i32)369 pub fn mouse_trafo(&self, y: i32, x: i32, to_screen: bool) -> (i32, i32) {
370 let mut mut_y = y;
371 let mut mut_x = x;
372 unsafe { curses::wmouse_trafo(self._window, &mut mut_y, &mut mut_x, to_screen as u8); }
373 (mut_y, mut_x)
374 }
375
376 /// The cursor associated with the window is moved to the given location.
377 ///
378 /// This does not move the physical cursor of the terminal until refresh() is called. The
379 /// position specified is relative to the upper left corner of the window, which is (0,0).
mv(&self, y: i32, x: i32) -> i32380 pub fn mv(&self, y: i32, x: i32) -> i32 {
381 unsafe { curses::wmove(self._window, y, x) }
382 }
383
384 /// moves the cursor to the specified position and adds ch to the specified window
mvaddch<T: ToChtype>(&self, y: i32, x: i32, ch: T) -> i32385 pub fn mvaddch<T: ToChtype>(&self, y: i32, x: i32, ch: T) -> i32 {
386 unsafe { curses::mvwaddch(self._window, y, x, ch.to_chtype()) }
387 }
388
389 /// Write all the characters of the string str to the given window. The functionality is
390 /// similar to calling waddch() once for each character in the string.
mvaddstr<T: AsRef<str>>(&self, y: i32, x: i32, string: T) -> i32391 pub fn mvaddstr<T: AsRef<str>>(&self, y: i32, x: i32, string: T) -> i32 {
392 let s = CString::new(string.as_ref()).unwrap();
393 unsafe { curses::mvwaddstr(self._window, y, x, s.as_ptr()) }
394 }
395
396 /// Write the first'n' characters of the string str to the given window.
mvaddnstr<T: AsRef<str>>(&self, y: i32, x: i32, string: T, n: i32) -> i32397 pub fn mvaddnstr<T: AsRef<str>>(&self, y: i32, x: i32, string: T, n: i32) -> i32 {
398 let s = CString::new(string.as_ref()).unwrap();
399 unsafe { curses::mvwaddnstr(self._window, y, x, s.as_ptr(), n) }
400 }
401
402 /// Moves the cursor and changes the attributes of a given number of characters starting at the
403 /// cursor location. It does not update the cursor and does not perform wrapping. A character count
404 /// of -1 or greater than the remaining window width means to change attributes all the way
405 /// to the end of the current line.
mvchgat(&self, y: i32, x: i32, n: i32, attributes: chtype, color_pair: i16) -> i32406 pub fn mvchgat(&self, y: i32, x: i32, n: i32, attributes: chtype, color_pair: i16) -> i32 {
407 unsafe {
408 curses::mvwchgat(
409 self._window,
410 y,
411 x,
412 n,
413 attributes,
414 color_pair,
415 ptr::null_mut(),
416 )
417 }
418 }
419
420 /// Moves a derived window (or subwindow) inside its parent window.
421 ///
422 /// The screen-relative parameters of the window are not changed. This routine is used to
423 /// display different parts of the parent window at the same physical position on the screen.
mvderwin(&self, pary: i32, parx: i32) -> i32424 pub fn mvderwin(&self, pary: i32, parx: i32) -> i32 {
425 unsafe { curses::mvderwin(self._window, pary, parx) }
426 }
427
428 /// Retrieves the character and attribute from the specified window position, in the form of a
429 /// chtype.
mvinch(&self, y: i32, x: i32) -> chtype430 pub fn mvinch(&self, y: i32, x: i32) -> chtype {
431 unsafe { curses::mvwinch(self._window, y, x) }
432 }
433
434 /// Move the cursor and then insert the character ch before the character under the cursor.
435 ///
436 /// First performs a cursor movement using wmove, and returns an error if the position is
437 /// outside the window. All characters to the right of the cursor are moved one space to the
438 /// right, with the possibility of the rightmost character on the line being lost. The insertion
439 /// operation does not change the cursor position.
mvinsch<T: ToChtype>(&self, y: i32, x: i32, ch: T) -> i32440 pub fn mvinsch<T: ToChtype>(&self, y: i32, x: i32, ch: T) -> i32 {
441 unsafe { curses::mvwinsch(self._window, y, x, ch.to_chtype()) }
442 }
443
444 /// Add a string to the window at the specified cursor position.
mvprintw<T: AsRef<str>>(&self, y: i32, x: i32, string: T) -> i32445 pub fn mvprintw<T: AsRef<str>>(&self, y: i32, x: i32, string: T) -> i32 {
446 let s = CString::new(string.as_ref()).unwrap();
447 unsafe { curses::mvwprintw(self._window, y, x, s.as_ptr()) }
448 }
449
450 /// Moves the window so that the upper left-hand corner is at position (y,x).
451 ///
452 /// If the move would cause the window to be off the screen, it is an error and the window is
453 /// not moved. Moving subwindows is allowed.
mvwin(&self, y: i32, x: i32) -> i32454 pub fn mvwin(&self, y: i32, x: i32) -> i32 {
455 unsafe { curses::mvwin(self._window, y, x) }
456 }
457
458 /// Controls whether wgetch() is a non-blocking call. If the option is enabled, and
459 /// no input is ready, wgetch() will return ERR. If disabled, wgetch() will hang until input is
460 /// ready.
nodelay(&self, enabled: bool) -> i32461 pub fn nodelay(&self, enabled: bool) -> i32 {
462 unsafe { curses::nodelay(self._window, enabled as u8) as i32 }
463 }
464
465 /// Copies the window to the virtual screen.
noutrefresh(&self) -> i32466 pub fn noutrefresh(&self) -> i32 {
467 unsafe { curses::wnoutrefresh(self._window) }
468 }
469
470 /// Overlays this window on top of destination_window. This window and destination_window are
471 /// not required to be the same size; only text where the two windows overlap is copied.
472 /// overlay() is non-destructive.
overlay(&self, destination_window: &Window) -> i32473 pub fn overlay(&self, destination_window: &Window) -> i32 {
474 unsafe { curses::overlay(self._window, destination_window._window) }
475 }
476
477 /// Overlays this window on top of destination_window. This window and destination_window are
478 /// not required to be the same size; only text where the two windows overlap is copied.
479 /// overwrite() is destructive.
overwrite(&self, destination_window: &Window) -> i32480 pub fn overwrite(&self, destination_window: &Window) -> i32 {
481 unsafe { curses::overwrite(self._window, destination_window._window) }
482 }
483
484 /// Add a string to the window at the current cursor position.
printw<T: AsRef<str>>(&self, string: T) -> i32485 pub fn printw<T: AsRef<str>>(&self, string: T) -> i32 {
486 let s = CString::new(string.as_ref()).unwrap();
487 unsafe { curses::wprintw(self._window, s.as_ptr()) }
488 }
489
490 /// Copies the named window to the physical terminal screen, taking into account what
491 /// is already there in order to optimize cursor movement.
492 ///
493 /// This function must be called to get any output on the terminal, as other routines only
494 /// manipulate data structures. Unless leaveok() has been enabled, the physical cursor of the
495 /// terminal is left at the location of the window's cursor.
refresh(&self) -> i32496 pub fn refresh(&self) -> i32 {
497 unsafe { curses::wrefresh(self._window) }
498 }
499
500 /// If enabled and a scrolling region is set with setscrreg(), any attempt to move off
501 /// the bottom margin will cause all lines in the scrolling region to scroll up one line.
scrollok(&self, bf: bool) -> i32502 pub fn scrollok(&self, bf: bool) -> i32 {
503 unsafe { curses::scrollok(self._window, bf as u8) }
504 }
505
506 /// Sets a scrolling region in a window.
507 ///
508 /// "top" and "bot" are the line numbers for the top and bottom margins.
setscrreg(&self, top: i32, bot: i32) -> i32509 pub fn setscrreg(&self, top: i32, bot: i32) -> i32 {
510 unsafe { curses::wsetscrreg(self._window, top, bot) }
511 }
512
513 /// Creates a new subwindow within a window.
514 ///
515 /// The dimensions of the subwindow are nlines lines and ncols columns. The subwindow is at
516 /// position (begy, begx) on the screen. This position is relative to the screen, and not to
517 /// the window orig. Changes made to either window will affect both. When using this routine,
518 /// you will often need to call touchwin() before calling refresh().
subwin(&self, nlines: i32, ncols: i32, begy: i32, begx: i32) -> Result<Window, i32>519 pub fn subwin(&self, nlines: i32, ncols: i32, begy: i32, begx: i32) -> Result<Window, i32> {
520 let new_window = unsafe { curses::subwin(self._window, nlines, ncols, begy, begx) };
521 if new_window.is_null() {
522 Err(ERR)
523 } else {
524 Ok(Window {
525 _window: new_window,
526 _stdscr: false,
527 _deleted: false,
528 })
529 }
530 }
531
532 /// Set blocking or non-blocking reads for the specified window.
533 ///
534 /// The delay is measured in milliseconds. If it's negative, a blocking read is used; if zero,
535 /// then non-blocking reads are done -- if no input is waiting, ERR is returned immediately.
536 /// If the delay is positive, the read blocks for the delay period; if the period expires,
537 /// ERR is returned.
timeout(&self, milliseconds: i32)538 pub fn timeout(&self, milliseconds: i32) {
539 unsafe { curses::wtimeout(self._window, milliseconds) }
540 }
541
542 /// Throws away all information about which parts of the window have been touched, pretending
543 /// that the entire window has been drawn on.
544 ///
545 /// This is sometimes necessary when using overlapping windows, since a change to one window
546 /// will affect the other window, but the records of which lines have been changed in the other
547 /// window will not reflect the change.
touch(&self) -> i32548 pub fn touch(&self) -> i32 {
549 unsafe { curses::touchwin(self._window) }
550 }
551
552 /// Throws away all information about which parts of the window have been touched, pretending
553 /// that the entire window has been drawn on.
554 ///
555 /// This is sometimes necessary when using overlapping windows, since a change to one window
556 /// will affect the other window, but the records of which lines have been changed in the other
557 /// window will not reflect the change.
touchline(&self, start: i32, count: i32) -> i32558 pub fn touchline(&self, start: i32, count: i32) -> i32 {
559 unsafe { curses::touchline(self._window, start, count) }
560 }
561
562 /// Makes n lines in the window, starting at line y, look as if they have or have not been
563 /// changed since the last call to refresh().
touchln(&self, y: i32, n: i32, changed: bool) -> i32564 pub fn touchln(&self, y: i32, n: i32, changed: bool) -> i32 {
565 unsafe { curses::wtouchln(self._window, y, n, if changed { 1 } else { 0 }) }
566 }
567
568 /// Places ch back onto the input queue to be returned by the next call to getch().
ungetch(&self, input: &Input) -> i32569 pub fn ungetch(&self, input: &Input) -> i32 {
570 platform_specific::_ungetch(input)
571 }
572
573 /// Marks all lines in the window as unchanged since the last call to refresh().
untouch(&self) -> i32574 pub fn untouch(&self) -> i32 {
575 unsafe { curses::untouchwin(self._window) }
576 }
577
578 /// Draw a vertical line using ch from the current cursor position. The line is at most
579 /// n characters long, or as many as fit into the window.
vline<T: ToChtype>(&self, ch: T, n: i32) -> i32580 pub fn vline<T: ToChtype>(&self, ch: T, n: i32) -> i32 {
581 unsafe { curses::wvline(self._window, ch.to_chtype(), n) }
582 }
583 }
584
new_window(window_pointer: WindowPointer, is_stdscr: bool) -> Window585 pub fn new_window(window_pointer: WindowPointer, is_stdscr: bool) -> Window {
586 Window {
587 _window: window_pointer,
588 _stdscr: is_stdscr,
589 _deleted: false,
590 }
591 }
592
593 /// Automatically clean up window resources when dropped
594 impl Drop for Window {
drop(&mut self)595 fn drop(&mut self) {
596 if !self._stdscr && !self._deleted {
597 unsafe {
598 curses::delwin(self._window);
599 }
600 }
601 }
602 }
603