You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
3.6KB

  1. /*
  2. * meli - ui crate.
  3. *
  4. * Copyright 2017-2018 Manos Pitsidianakis
  5. *
  6. * This file is part of meli.
  7. *
  8. * meli is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * meli is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with meli. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. /*!
  22. Simple type definitions and macro helper for a (x,y) position on the terminal and the areas they define.
  23. An `Area` consists of two points: the upper left and bottom right corners.
  24. */
  25. /// A `(x, y)` position on screen.
  26. pub type Pos = (usize, usize);
  27. #[inline(always)]
  28. pub fn get_x(p: Pos) -> usize {
  29. p.0
  30. }
  31. #[inline(always)]
  32. pub fn get_y(p: Pos) -> usize {
  33. p.1
  34. }
  35. #[inline(always)]
  36. pub fn set_x(p: Pos, new_x: usize) -> Pos {
  37. (new_x, p.1)
  38. }
  39. #[inline(always)]
  40. pub fn set_y(p: Pos, new_y: usize) -> Pos {
  41. (p.0, new_y)
  42. }
  43. #[inline(always)]
  44. pub fn pos_inc(p: Pos, inc: (usize, usize)) -> Pos {
  45. (p.0 + inc.0, p.1 + inc.1)
  46. }
  47. #[inline(always)]
  48. pub fn pos_dec(p: Pos, dec: (usize, usize)) -> Pos {
  49. (p.0.saturating_sub(dec.0), p.1.saturating_sub(dec.1))
  50. }
  51. /// An `Area` consists of two points: the upper left and bottom right corners.
  52. ///
  53. /// Example:
  54. /// ```
  55. /// # #[macro_use] extern crate ui; fn main() {
  56. /// use ui::*;
  57. ///
  58. /// let new_area = ((0, 0), (1, 1));
  59. /// # }
  60. /// ```
  61. pub type Area = (Pos, Pos);
  62. /// Get an area's height
  63. ///
  64. /// Example:
  65. /// ```
  66. /// # #[macro_use] extern crate ui; fn main() {
  67. /// use ui::*;
  68. ///
  69. /// let new_area = ((0, 0), (1, 1));
  70. /// assert_eq!(height!(new_area), 1);
  71. /// # }
  72. /// ```
  73. #[macro_export]
  74. macro_rules! height {
  75. ($a:expr) => {
  76. (get_y(bottom_right!($a))).saturating_sub(get_y(upper_left!($a)))
  77. };
  78. }
  79. /// Get an area's width
  80. ///
  81. /// Example:
  82. /// ```
  83. /// # #[macro_use] extern crate ui; fn main() {
  84. /// use ui::*;
  85. ///
  86. /// let new_area = ((0, 0), (1, 1));
  87. /// assert_eq!(width!(new_area), 1);
  88. /// # }
  89. /// ```
  90. #[macro_export]
  91. macro_rules! width {
  92. ($a:expr) => {
  93. (get_x(bottom_right!($a))).saturating_sub(get_x(upper_left!($a)))
  94. };
  95. }
  96. /// Get the upper left Position of an area
  97. ///
  98. /// Example:
  99. /// ```
  100. /// # #[macro_use] extern crate ui; fn main() {
  101. /// use ui::*;
  102. ///
  103. /// let new_area = ((0, 0), (1, 1));
  104. /// assert_eq!(upper_left!(new_area), (0, 0));
  105. /// # }
  106. /// ```
  107. #[macro_export]
  108. macro_rules! upper_left {
  109. ($a:expr) => {
  110. $a.0
  111. };
  112. }
  113. /// Get the bottom right Position of an area
  114. ///
  115. /// Example:
  116. /// ```
  117. /// # #[macro_use] extern crate ui; fn main() {
  118. /// use ui::*;
  119. ///
  120. /// let new_area = ((0, 0), (1, 1));
  121. /// assert_eq!(bottom_right!(new_area), (1, 1));
  122. /// # }
  123. /// ```
  124. #[macro_export]
  125. macro_rules! bottom_right {
  126. ($a:expr) => {
  127. $a.1
  128. };
  129. }
  130. /// Check if area is valid.
  131. ///
  132. /// Example:
  133. /// ```
  134. /// # #[macro_use] extern crate ui; fn main() {
  135. /// use ui::*;
  136. ///
  137. /// let valid_area = ((0, 0), (1, 1));
  138. /// assert!(is_valid_area!(valid_area));
  139. ///
  140. /// let invalid_area = ((2, 2), (1, 1));
  141. /// assert!(!is_valid_area!(invalid_area));
  142. /// # }
  143. ///
  144. #[macro_export]
  145. macro_rules! is_valid_area {
  146. ($a:expr) => {{
  147. let upper_left = upper_left!($a);
  148. let bottom_right = bottom_right!($a);
  149. !(get_y(upper_left) > get_y(bottom_right) || get_x(upper_left) > get_x(bottom_right))
  150. }};
  151. }