pancurses_result/window.rs
1use general::*;
2use point::*;
3use std::time::Duration;
4
5pub enum EndOfLineOrNumber {
6 EndOfLine,
7 Number(i32),
8}
9
10impl EndOfLineOrNumber {
11 pub fn unwrap_number_or(self, eol: i32) -> i32 {
12 match self {
13 EndOfLineOrNumber::EndOfLine => eol,
14 EndOfLineOrNumber::Number(n) => n,
15 }
16 }
17}
18
19impl From<i32> for EndOfLineOrNumber {
20 fn from(n: i32) -> Self {
21 EndOfLineOrNumber::Number(n)
22 }
23}
24
25/// A curses window.
26///
27/// It will clean up itself on destruction.
28///
29/// Many curses functions have been renamed for one reason or another. All
30/// renamed functions state the curses function they corollate to.
31pub struct Window {
32 w: pancurses::Window,
33}
34
35impl Window {
36 pub(crate) fn new(w: pancurses::Window) -> Self {
37 Window { w }
38 }
39
40 /// Put a character at the point.
41 ///
42 /// This corresponds to `addch`.
43 pub fn put_char<T: Into<Chtype>>(&mut self, ch: T) -> Result<(), ()> {
44 check(self.w.addch(ch.into()))
45 }
46 /// Put a string at the point.
47 ///
48 /// This corresponds to `addch`.
49 pub fn put_str<T: AsRef<str>>(&mut self, string: T) -> Result<(), ()> {
50 check(self.w.addstr(string))
51 }
52 /// Print a formatted string at the point.
53 ///
54 /// This corresponds to `printw`. It does not use `printw`
55 /// under the hood because that function cannot be safe to use
56 /// within rust code because rust does not allow for variadic
57 /// arguments.
58 pub fn printw(&mut self, args: std::fmt::Arguments) -> Result<(), ()> {
59 self.put_str(args.to_string())
60 }
61 /// Put the contents of `source` that overlap with this `Window`.
62 ///
63 /// The two `Window`s are not required to be the same size;
64 /// overlapping portions are copied.
65 ///
66 /// This corresponds to `overwrite` but *with the arguments flipped*.
67 pub fn put_window(&mut self, source: &Window) -> Result<(), ()> {
68 source.overwrite_onto(self)
69 }
70 /// Put the contents of `source` in a region at a region of this `Window`.
71 ///
72 /// The two regions are not required to be the same size; overlapping
73 /// portions are copied.
74 ///
75 /// This corresponds to `copywin` but *with the arguments flipped* and a
76 /// final argument of `true`.
77 pub fn put_window_region<P1: Into<Point>, P2: Into<Point>, P3: Into<Point>>(
78 &mut self,
79 destination_start: P1,
80 destination_end: P2,
81 source: &Window,
82 source_start: P3,
83 ) -> Result<(), ()> {
84 source.overwrite_region_onto(source_start, self, destination_start, destination_end)
85 }
86 /// Put the non-blank contents of `source` that overlap with this
87 /// `Window`.
88 ///
89 /// The two `Window`s are not required to be the same size;
90 /// overlapping portions are copied.
91 ///
92 /// This corresponds to `overlay` but *with the arguments flipped*.
93 pub fn put_window_text(&mut self, source: &Window) -> Result<(), ()> {
94 source.overlay_onto(self)
95 }
96 /// Put the non-blank contents of `source` in a region at a region of this `Window`.
97 ///
98 /// The two regions are not required to be the same size; overlapping
99 /// portions are copied.
100 ///
101 /// This corresponds to `copywin` but *with the arguments flipped* and a
102 /// final argument of `true`.
103 pub fn put_window_text_region<P1: Into<Point>, P2: Into<Point>, P3: Into<Point>>(
104 &mut self,
105 destination_start: P1,
106 destination_end: P2,
107 source: &Window,
108 source_start: P3,
109 ) -> Result<(), ()> {
110 source.overlay_region_onto(source_start, self, destination_start, destination_end)
111 }
112
113 /// Put the contents of this `Window` onto `destination` where they overlap.
114 ///
115 /// This corresponds to `overwrite`.
116 pub fn overwrite_onto(&self, destination: &mut Self) -> Result<(), ()> {
117 check(self.w.overwrite(&destination.w))
118 }
119 /// Put the non-blank contents of this `Window` onto `destination` where they overlap.
120 ///
121 /// This corresponds to `overlay`.
122 pub fn overlay_onto(&self, destination: &mut Self) -> Result<(), ()> {
123 check(self.w.overlay(&destination.w))
124 }
125
126 /// Overwrite this `Window` on top of the `destination`.
127 ///
128 /// For more information on how this works, see [`put_window`].
129 ///
130 /// This corresponds to `copywin` with a final argument of `true`.
131 ///
132 /// [`put_window`]: struct.Window.html#method.put_window
133 pub fn overwrite_region_onto<P1: Into<Point>, P2: Into<Point>, P3: Into<Point>>(
134 &self,
135 source_start: P1,
136 destination: &mut Window,
137 destination_start: P2,
138 destination_end: P3,
139 ) -> Result<(), ()> {
140 let source_start = source_start.into();
141 let destination_start = destination_start.into();
142 let destination_end = destination_end.into();
143 check(self.w.copywin(
144 &destination.w,
145 source_start.y,
146 source_start.x,
147 destination_start.y,
148 destination_start.x,
149 destination_end.y,
150 destination_end.x,
151 true,
152 ))
153 }
154 /// Overlay this `Window`'s text on top of the `destination`.
155 ///
156 /// For more information on how this works, see [`put_window_text`].
157 ///
158 /// This corresponds to `copywin` with a final argument of `true`.
159 ///
160 /// [`put_window_text`]: struct.Window.html#method.put_window_text
161 pub fn overlay_region_onto<P1: Into<Point>, P2: Into<Point>, P3: Into<Point>>(
162 &self,
163 source_start: P1,
164 destination: &mut Window,
165 destination_start: P2,
166 destination_end: P3,
167 ) -> Result<(), ()> {
168 let source_start = source_start.into();
169 let destination_start = destination_start.into();
170 let destination_end = destination_end.into();
171 check(self.w.copywin(
172 &destination.w,
173 source_start.y,
174 source_start.x,
175 destination_start.y,
176 destination_start.x,
177 destination_end.y,
178 destination_end.x,
179 true,
180 ))
181 }
182
183 /// Get the attributes of the character at the point.
184 ///
185 /// This corresponds to `attrget`.
186 pub fn attributes(&self) -> (Chtype, i16) {
187 self.w.attrget()
188 }
189 /// Turn off the following attributes of the character at the point.
190 ///
191 /// This corresponds to `attroff`.
192 pub fn turn_off_attributes<T: Into<Chtype>>(&mut self, attributes: T) -> Result<(), ()> {
193 check(self.w.attroff(attributes))
194 }
195 /// Turn on the following attributes of the character at the point.
196 ///
197 /// This corresponds to `attron`.
198 pub fn turn_on_attributes<T: Into<Chtype>>(&mut self, attributes: T) -> Result<(), ()> {
199 check(self.w.attron(attributes))
200 }
201 /// Set the attributes of the character at the point.
202 ///
203 /// This corresponds to `attrset`.
204 pub fn set_attributes<T: Into<Chtype>>(&mut self, attributes: T) -> Result<(), ()> {
205 check(self.w.attrset(attributes))
206 }
207 /// Turn off the following attributes of the character at the point.
208 ///
209 /// This corresponds to `chgat`.
210 pub fn change_attributes<T: Into<Chtype>, N: Into<EndOfLineOrNumber>>(
211 &mut self,
212 n: N,
213 attributes: T,
214 color_pair: i16,
215 ) -> Result<(), ()> {
216 check(
217 self.w
218 .chgat(n.into().unwrap_number_or(-1), attributes.into(), color_pair),
219 )
220 }
221
222 /// Set the background of the `Window`.
223 ///
224 /// This corresponds to `bkgdset`.
225 pub fn set_background<T: Into<Chtype>>(&mut self, ch: T) {
226 self.w.bkgdset(ch)
227 }
228 /// Set the background of the `Window` and apply it.
229 ///
230 /// This sets the attributes of every character to the attributes
231 /// of `background` and replaces old background characters with
232 /// `background`.
233 ///
234 /// This corresponds to `bkgd`.
235 pub fn set_background_and_apply<T: Into<Chtype>>(&mut self, background: T) -> Result<(), ()> {
236 check(self.w.bkgd(background))
237 }
238
239 /// Clear the screen.
240 ///
241 /// This fills the screen with background characters. This can be
242 /// customized via [`set_background`].
243 ///
244 /// Unlike [`erase`], `clear` will also invoke force a the next call to
245 /// [`refresh`] to clear the screen (as if by [`refresh_force_clear`]).
246 ///
247 /// [`set_background`]: struct.Window.html#method.set_background
248 /// [`erase`]: struct.Window.html#method.erase
249 /// [`refresh`]: struct.Window.html#method.refresh
250 /// [`refresh_force_clear`]: struct.Window.html#method.refresh_force_clear
251 pub fn clear(&mut self) -> Result<(), ()> {
252 check(self.w.clear())
253 }
254 /// Clear the virtual screen.
255 ///
256 /// See [`clear`] for a comparison of these two methods.
257 ///
258 /// [`clear`]: struct.Window.html#method.clear
259 pub fn erase(&mut self) -> Result<(), ()> {
260 check(self.w.erase())
261 }
262 /// Erase all characters after the point.
263 ///
264 /// This will clear to the end of the line, then clear each line
265 /// after the one the point is on.
266 ///
267 /// This corresponds to `clrtobot`.
268 pub fn clear_to_bottom(&mut self) -> Result<(), ()> {
269 check(self.w.clrtobot())
270 }
271 /// Erase all characters to the right of the point on this line.
272 ///
273 /// This corresponds to `clrtobot`.
274 pub fn clear_to_end_of_line(&mut self) -> Result<(), ()> {
275 check(self.w.clrtoeol())
276 }
277
278 /// Set the current color of the given window to the
279 /// foregrond/background pair `color_pair`.
280 ///
281 /// This corresponds to `color_set`.
282 pub fn set_color(&mut self, color_pair: i16) -> Result<(), ()> {
283 check(self.w.color_set(color_pair))
284 }
285
286 /// Delete the character at the point.
287 ///
288 /// This will shift left the characters on the rest of the line.
289 ///
290 /// This corresponds to `delch`.
291 pub fn delete_char(&mut self) -> Result<(), ()> {
292 check(self.w.delch())
293 }
294 /// Delete the line the point is on.
295 ///
296 /// This will shift left the characters on the rest of the line.
297 ///
298 /// This corresponds to `delch`.
299 pub fn delete_line(&mut self) -> Result<(), ()> {
300 check(self.w.deleteln())
301 }
302 /// Delete this `Window`, allowing for error handling outside of
303 /// panicking.
304 pub fn delete_window(self) -> Result<(), ()> {
305 check(self.w.delwin())
306 }
307
308 /// Draw a border around the edges of the `Window`.
309 ///
310 /// This corresponds to `border`.
311 pub fn draw_border<
312 LS: Into<Chtype>,
313 RS: Into<Chtype>,
314 TS: Into<Chtype>,
315 BS: Into<Chtype>,
316 TLC: Into<Chtype>,
317 TRC: Into<Chtype>,
318 BLC: Into<Chtype>,
319 BRC: Into<Chtype>,
320 >(
321 &mut self,
322 left_side: LS,
323 right_side: RS,
324 top_side: TS,
325 bottom_side: BS,
326 top_left_corner: TLC,
327 top_right_corner: TRC,
328 bottom_left_corner: BLC,
329 bottom_right_corner: BRC,
330 ) -> Result<(), ()> {
331 check(self.w.border(
332 left_side.into(),
333 right_side.into(),
334 top_side.into(),
335 bottom_side.into(),
336 top_left_corner.into(),
337 top_right_corner.into(),
338 bottom_left_corner.into(),
339 bottom_right_corner.into(),
340 ))
341 }
342 /// Drow a box around the edges of the `Window`.
343 ///
344 /// This is shorthand for [`draw_border`] with default corners.
345 ///
346 /// This corresponds to `border`.
347 ///
348 /// [`draw_border`]: struct.Window.html#method.draw_border
349 pub fn draw_box<VT: Into<Chtype>, HT: Into<Chtype>>(
350 &mut self,
351 vertical: VT,
352 horizontal: HT,
353 ) -> Result<(), ()> {
354 check(self.w.draw_box(vertical.into(), horizontal.into()))
355 }
356 /// Draw a horizontal line starting at the point.
357 ///
358 /// This corresponds to `hline`.
359 pub fn draw_horizontal_line<T: Into<Chtype>>(
360 &mut self,
361 ch: T,
362 max_length: i32,
363 ) -> Result<(), ()> {
364 check(self.w.hline(ch.into(), max_length))
365 }
366 /// Draw a vertical line starting at the point.
367 ///
368 /// This corresponds to `vline`.
369 pub fn draw_vertical_line<T: Into<Chtype>>(
370 &mut self,
371 ch: T,
372 max_length: i32,
373 ) -> Result<(), ()> {
374 check(self.w.vline(ch.into(), max_length))
375 }
376
377 /// Test if `p` is enclosed in this `Window`.
378 pub fn encloses<P: Into<Point>>(&self, p: P) -> bool {
379 let p = p.into();
380 self.w.enclose(p.y, p.x)
381 }
382
383 /// Get the start of the `Window` on the physical screen.
384 ///
385 /// This corresponds to `get_beg_yx`.
386 pub fn beginning(&self) -> Point {
387 self.w.get_beg_yx().into()
388 }
389 /// Get the ending of the `Window` on the physical screen.
390 pub fn ending(&self) -> Point {
391 let (y, x) = self.beginning().into();
392 let (h, w) = self.size().into();
393 Point { y: y + h, x: x + w }
394 }
395
396 /// Get the position of the point.
397 ///
398 /// This corresponds to `get_cur_yx`.
399 pub fn point(&self) -> Point {
400 self.w.get_cur_yx().into()
401 }
402
403 /// Get the size of the `Window`.
404 ///
405 /// This corresponds to `get_max_yx`.
406 pub fn size(&self) -> Dimension {
407 self.w.get_max_yx().into()
408 }
409
410 /// Insert `n` blank lines above the cursor.
411 ///
412 /// If `n > 0`, then `n` blank lines are inserted above the
413 /// cursor. The last `n` lines of the screen are lost.
414 ///
415 /// If `n < 0`, then `n` lines below the cursor are deleted and
416 /// the rest are shifted up. This clears the bottom `n` lines of
417 /// the screen.
418 ///
419 /// The point remains the same after this operation.
420 ///
421 /// This corresponds to `insdelln`.
422 pub fn insert_lines(&mut self, n: i32) -> Result<(), ()> {
423 check(self.w.insdelln(n))
424 }
425 /// Insert a blank line above the current line.
426 ///
427 /// This effectively erases the last line on the screen.
428 ///
429 /// The point remains the same after this operation.
430 ///
431 /// This corresponds to `insertln`.
432 pub fn insert_line(&mut self) -> Result<(), ()> {
433 check(self.w.insertln())
434 }
435 /// Insert a character into the current line.
436 ///
437 /// This shifts to the right characters after the cursor. The
438 /// rightmost character will thus be lost.
439 ///
440 /// The point remains the same after this operation.
441 ///
442 /// This corresponds to `insch`.
443 pub fn insert_char<T: Into<Chtype>>(&self, ch: T) -> Result<(), ()> {
444 check(self.w.insch(ch.into()))
445 }
446
447 /// Transform the point `p` from `Window`-relative to screen-relative.
448 ///
449 /// This corresponds to `mouse_trafo`.
450 pub fn window_to_screen<P: Into<Point>>(&self, p: P) -> Point {
451 let p = p.into();
452 self.w.mouse_trafo(p.y, p.x, true).into()
453 }
454 /// Transform the point `p` from screen-relative to `Window`-relative.
455 ///
456 /// This corresponds to `mouse_trafo`.
457 pub fn screen_to_window<P: Into<Point>>(&self, p: P) -> Point {
458 let p = p.into();
459 self.w.mouse_trafo(p.y, p.x, false).into()
460 }
461
462 /// Move to the point to `p`.
463 ///
464 /// This corresponds to `mv`.
465 pub fn move_to<P: Into<Point>>(&mut self, p: P) -> Result<(), ()> {
466 let p = p.into();
467 check(self.w.mv(p.y, p.x))
468 }
469 /// Move to the point `p` then put `ch` at that point.
470 ///
471 /// This corresponds to `mvaddch`.
472 pub fn move_put_char<P: Into<Point>, T: Into<Chtype>>(
473 &mut self,
474 p: P,
475 ch: T,
476 ) -> Result<(), ()> {
477 let p = p.into();
478 check(self.w.mvaddch(p.y, p.x, ch.into()))
479 }
480 /// Move to the point `p` then put `string` at that point.
481 ///
482 /// This corresponds to `mvaddstr`.
483 pub fn move_put_str<P: Into<Point>, T: AsRef<str>>(
484 &mut self,
485 p: P,
486 string: T,
487 ) -> Result<(), ()> {
488 let p = p.into();
489 check(self.w.mvaddstr(p.y, p.x, string))
490 }
491 /// Move to the point `p` then change the attributes of `n` characters after that point.
492 ///
493 /// This corresponds to `mvchgat`.
494 pub fn move_change_attributes<P: Into<Point>, N: Into<EndOfLineOrNumber>, T: Into<Chtype>>(
495 &mut self,
496 p: P,
497 n: N,
498 attributes: T,
499 color_pair: i16,
500 ) -> Result<(), ()> {
501 let p = p.into();
502 check(self.w.mvchgat(
503 p.y,
504 p.x,
505 n.into().unwrap_number_or(-1),
506 attributes.into(),
507 color_pair,
508 ))
509 }
510 /// Move to `p` then get the character at the point.
511 ///
512 /// This corresponds to `mvinch`.
513 pub fn move_get_char<P: Into<Point>>(&mut self, p: P) -> Chtype {
514 let p = p.into();
515 self.w.mvinch(p.y, p.x)
516 }
517 /// Move to `p` then insert the character at the point.
518 ///
519 /// This corresponds to `mvinsch`.
520 pub fn move_insert_char<P: Into<Point>, T: Into<Chtype>>(
521 &mut self,
522 p: P,
523 ch: T,
524 ) -> Result<(), ()> {
525 let p = p.into();
526 check(self.w.mvinsch(p.y, p.x, ch.into()))
527 }
528 // /// Move to `p` then insert the character at the point.
529 // ///
530 // /// This corresponds to `mvinsch`.
531 // pub fn move_derived_window<P: Into<Point>>(&mut self, p: P) -> Result<(), ()> {
532 // let p = p.into();
533 // check(self.w.mvderwin(p.y, p.x))
534 // }
535 /// Move the `Window` such that it starts at `p` on the screen.
536 ///
537 /// This corresponds to `mvwin`.
538 pub fn move_window<P: Into<Point>>(&mut self, p: P) -> Result<(), ()> {
539 let p = p.into();
540 check(self.w.mvwin(p.y, p.x))
541 }
542
543 /// Read a key event from the `Window`.
544 ///
545 /// The exact behavior of this procedure depends on other configuration
546 /// procedures.
547 ///
548 /// * To set how we handle a lack of input (with regard to
549 /// blocking/unblocking) [`set_block_on_read`], [`set_timeout`], and
550 /// [`Curses::set_timeout`].
551 ///
552 /// * To set how function keys are handled, see
553 /// [`read_interpolate_function_keys`].
554 ///
555 /// * To set how new lines are handled, see
556 /// [`Curses::set_translate_new_lines`].
557 ///
558 /// * To set how input is buffered, see [`Curses::set_input_buffering_mode`].
559 ///
560 /// * To control whether curses will automatically echo characters see
561 /// [`Curses::set_echo_input`].
562 ///
563 /// This corresponds to `getch`.
564 ///
565 /// [`set_block_on_read`]: struct.Window.html#method.set_block_on_read
566 /// [`set_timeout`]: struct.Window.html#method.set_timeout
567 /// [`Curses::set_timeout`]: struct.Curses.html#method.set_timeout
568 /// [`read_interpolate_function_keys`]: struct.Window.html#method.read_interpolate_function_keys
569 /// [`Curses::set_translate_new_lines`]: struct.Curses.html#method.set_translate_new_lines
570 /// [`Curses::set_input_buffering_mode`]: struct.Curses.html#method.set_input_buffering_mode
571 /// [`Curses::set_echo_input`]: struct.Curses.html#method.set_echo_input
572 pub fn read_char(&mut self) -> Option<Input> {
573 self.w.getch()
574 }
575 /// Place `input` into the front of the input queue.
576 ///
577 /// Thus the next call to [`read_char`] will return `input`.
578 ///
579 /// This corresponds to `ungetch`.
580 ///
581 /// [`read_char`]: struct.Window.html#method.read_char
582 pub fn unread_char(&mut self, input: &Input) -> Result<(), ()> {
583 check(self.w.ungetch(input))
584 }
585 /// Set whether [`read_char`] will block until an input is ready.
586 ///
587 /// With an argument `true`, [`read_char`] will block until it receives an
588 /// input to yield.
589 ///
590 /// With an argument `false`, [`read_char`] will immediately return `None`
591 /// if there is no input to yield.
592 ///
593 /// This corresponds to `nodelay(!block)`.
594 pub fn set_block_on_read(&mut self, block: bool) -> Result<(), ()> {
595 check(self.w.nodelay(!block))
596 }
597 /// [`read_char`] will block for at most `duration` and wait for input.
598 ///
599 /// `duration` is rounded down to the nearest millisecond. This will only
600 /// change the way input is read in this `Window`. To set it for *all*
601 /// `Window`s, see [`Curses::set_timeout`].
602 ///
603 /// From reading the ncurses source code, I have deduced that this is overriden
604 /// by the global [`Curses`]'s timeout (see [`Curses::set_timeout`]).
605 ///
606 /// Use `None` as the timeout to stop this.
607 ///
608 /// This corresponds to `timeout`.
609 ///
610 /// [`Curses::read_char`]: struct.Curses.html#method.read_char
611 /// [`Curses::set_timeout`]: struct.Curses.html#method.set_timeout
612 /// [`Curses`]: struct.Curses.html
613 pub fn set_timeout(&self, duration: Option<Duration>) {
614 self.w.timeout(duration.map(as_millis).unwrap_or(-1))
615 }
616 /// Enable or disable function key interpolation.
617 ///
618 /// When enabled and a function key is pressed, [`read_char`] will
619 /// return a single value representing the function key instead of
620 /// a series of escape sequences.
621 ///
622 /// When disabled and a function key is pressed, [`read_char`]
623 /// will return a series of escape sequences instead of a single
624 /// value representing the function key.
625 ///
626 /// It is disabled by default.
627 ///
628 /// This corresponds to `keypad`.
629 ///
630 /// [`read_char`]: struct.Window.html#method.read_char
631 pub fn read_interpolate_function_keys(&mut self, interpolate: bool) -> Result<(), ()> {
632 check(self.w.keypad(interpolate))
633 }
634
635 /// Copy this `Window` to the physical screen.
636 ///
637 /// This corresponds to `wrefresh`.
638 pub fn refresh(&mut self) -> Result<(), ()> {
639 check(self.w.refresh())
640 }
641 /// Refresh the virtual screen.
642 ///
643 /// This is much faster if multiple `Window`s have to be refreshed.
644 ///
645 /// To push the virtual screen changes to the physical screen, use
646 /// [`Curses::update`].
647 ///
648 /// This corresponds to `wnoutrefresh`.
649 ///
650 /// [`Curses::update`]: struct.Curses.html#method.update
651 pub fn refresh_virtual_screen(&mut self) -> Result<(), ()> {
652 check(self.w.noutrefresh())
653 }
654 /// Make the next call to [`refresh`] clear and then rerender.
655 ///
656 /// This corresponds to `clearok`.
657 ///
658 /// [`refresh`]: struct.Window.html#method.refresh
659 pub fn refresh_force_clear(&mut self, force_clear: bool) -> Result<(), ()> {
660 check(self.w.clearok(force_clear))
661 }
662
663 /// Enable or disable scrolling.
664 ///
665 /// This corresponds to `scrollok`.
666 pub fn set_scroll_enabled(&mut self, scroll: bool) -> Result<(), ()> {
667 check(self.w.scrollok(scroll))
668 }
669 /// Set a software scrolling region.
670 ///
671 /// This will do nothing unless scrolling has been enabled (see
672 /// [`set_scroll_enabled`]).
673 ///
674 /// This corresponds to `setscrreg`.
675 ///
676 /// [`set_scroll_enabled`]: struct.Window.html#method.set_scroll_enabled
677 pub fn set_scroll_region(&mut self, start: i32, end: i32) -> Result<(), ()> {
678 check(self.w.setscrreg(start, end))
679 }
680
681 /// Create a new window
682 ///
683 /// This corresponds to `subwin`. Note that the arguments have been
684 /// reordered to be more consistent with other functions.
685 pub fn create_sub_window<P: Into<Point>, D: Into<Dimension>>(
686 &self,
687 point: P,
688 size: D,
689 ) -> Result<Window, ()> {
690 let p = point.into();
691 let d = size.into();
692 match self.w.subwin(d.rows, d.columns, p.y, p.x) {
693 Ok(w) => Ok(Window { w }),
694 Err(_) => Err(()),
695 }
696 }
697
698 /// Test if this `Window` has been modified since the last call to
699 /// [`refresh`].
700 ///
701 /// This corresponds to `is_wintouched`.
702 ///
703 /// [`refresh`]: struct.Window.html#method.refresh
704 pub fn touched(&self) -> bool {
705 self.w.is_touched()
706 }
707 /// Test if the specified line has been modified since the last call to
708 /// [`refresh`].
709 ///
710 /// This corresponds to `is_linetouched`.
711 ///
712 /// [`refresh`]: struct.Window.html#method.refresh
713 pub fn line_touched(&self, line: i32) -> bool {
714 self.w.is_linetouched(line)
715 }
716 /// Force the entire `Window` to be redrawn upon the next call to
717 /// [`refresh`].
718 ///
719 /// This corresponds to `touchwin`.
720 ///
721 /// [`refresh`]: struct.Window.html#method.refresh
722 pub fn touch(&mut self) -> Result<(), ()> {
723 check(self.w.touch())
724 }
725 /// Force the specified lines to be redrawn upon the next call to
726 /// [`refresh`].
727 ///
728 /// This corresponds to `touchline`.
729 ///
730 /// [`refresh`]: struct.Window.html#method.refresh
731 pub fn touch_lines(&mut self, start: i32, count: i32) -> Result<(), ()> {
732 check(self.w.touchline(start, count))
733 }
734 /// Pretend this `Window` hasn't changed and thus won't redraw it upon the
735 /// next call to [`refresh`].
736 ///
737 /// This corresponds to `touchline`.
738 ///
739 /// [`refresh`]: struct.Window.html#method.refresh
740 pub fn untouch(&mut self) -> Result<(), ()> {
741 check(self.w.untouch())
742 }
743 /// Pretend the specified lines haven't changed and thus won't redraw it
744 /// upon the next call to [`refresh`].
745 ///
746 /// This corresponds to `touchline`.
747 ///
748 /// [`refresh`]: struct.Window.html#method.refresh
749 pub fn untouch_lines(&mut self, start: i32, count: i32) -> Result<(), ()> {
750 check(self.w.touchln(start, count, false))
751 }
752}
753
754/// Duplicate this `Window`.
755///
756/// This corresponds to `dupwin`.
757impl Clone for Window {
758 fn clone(&self) -> Self {
759 Window { w: self.w.dupwin() }
760 }
761}
762
763unsafe impl Send for Window {}
764unsafe impl Sync for Window {}