rect.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /* Rectangular class for Midnight Commander widgets
  2. Copyright (C) 2020-2024
  3. The Free Software Foundation, Inc.
  4. Written by:
  5. Andrew Borodin <aborodin@vmail.ru>, 2020-2022
  6. This file is part of the Midnight Commander.
  7. The Midnight Commander is free software: you can redistribute it
  8. and/or modify it under the terms of the GNU General Public License as
  9. published by the Free Software Foundation, either version 3 of the License,
  10. or (at your option) any later version.
  11. The Midnight Commander is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /** \file widget-common.c
  19. * \brief Source: shared stuff of widgets
  20. */
  21. #include <config.h>
  22. #include <stdlib.h>
  23. #include "lib/global.h"
  24. #include "rect.h"
  25. /*** global variables ****************************************************************************/
  26. /*** file scope macro definitions ****************************************************************/
  27. /*** file scope type declarations ****************************************************************/
  28. /*** file scope variables ************************************************************************/
  29. /*** file scope functions ************************************************************************/
  30. /* --------------------------------------------------------------------------------------------- */
  31. /*** public functions ****************************************************************************/
  32. /* --------------------------------------------------------------------------------------------- */
  33. /**
  34. * Create new WRect object.
  35. *
  36. * @param y y-coordinate of left-up corner
  37. * @param x x-coordinate of left-up corner
  38. * @param lines height
  39. * @param cols width
  40. *
  41. * @return newly allocated WRect object.
  42. */
  43. WRect *
  44. rect_new (int y, int x, int lines, int cols)
  45. {
  46. WRect *r;
  47. r = g_try_new (WRect, 1);
  48. if (r != NULL)
  49. rect_init (r, y, x, lines, cols);
  50. return r;
  51. }
  52. /* --------------------------------------------------------------------------------------------- */
  53. /**
  54. * Initialize WRect object.
  55. *
  56. * @param r WRect object
  57. * @param y y-coordinate of left-up corner
  58. * @param x x-coordinate of left-up corner
  59. * @param lines height
  60. * @param cols width
  61. */
  62. void
  63. rect_init (WRect *r, int y, int x, int lines, int cols)
  64. {
  65. r->y = y;
  66. r->x = x;
  67. r->lines = lines;
  68. r->cols = cols;
  69. }
  70. /* --------------------------------------------------------------------------------------------- */
  71. /**
  72. * Change position of rectangle area.
  73. *
  74. * @param r WRect object
  75. * @param dy y-shift of left-up corner
  76. * @param dx x-shift of left-up corner
  77. */
  78. void
  79. rect_move (WRect *r, int dy, int dx)
  80. {
  81. r->y += dy;
  82. r->x += dx;
  83. }
  84. /* --------------------------------------------------------------------------------------------- */
  85. /**
  86. * Change size of rectangle area keeping it's position.
  87. *
  88. * @param r WRect object
  89. * @param dl change size value of height
  90. * @param dc change size value of width
  91. */
  92. void
  93. rect_resize (WRect *r, int dl, int dc)
  94. {
  95. r->lines += dl;
  96. r->cols += dc;
  97. }
  98. /* --------------------------------------------------------------------------------------------- */
  99. /**
  100. * Change size of rectangle area keeping it's center.
  101. *
  102. * @param r WRect object
  103. * @param dl change size value of y-coordinate and height
  104. * Positive value means move up and increase height.
  105. * Negative value means move down and decrease height.
  106. * @param dc change size value of x-coordinate and width
  107. * Positive value means move left and increase width.
  108. * Negative value means move right and decrease width.
  109. */
  110. void
  111. rect_grow (WRect *r, int dl, int dc)
  112. {
  113. r->y -= dl;
  114. r->x -= dc;
  115. r->lines += dl * 2;
  116. r->cols += dc * 2;
  117. }
  118. /* --------------------------------------------------------------------------------------------- */
  119. /**
  120. * Calculates the intersection of two rectangle areas.
  121. * The resulting rectangle is the largest rectangle which contains intersection of rectangle areas.
  122. *
  123. * @param r first WRect object
  124. * @param r1 second WRect object
  125. *
  126. * The resulting rectangle is stored in r.
  127. */
  128. void
  129. rect_intersect (WRect *r, const WRect *r1)
  130. {
  131. int y, x;
  132. int y1, x1;
  133. /* right-down corners */
  134. y = r->y + r->lines;
  135. x = r->x + r->cols;
  136. y1 = r1->y + r1->lines;
  137. x1 = r1->x + r1->cols;
  138. /* right-down corner of intersection */
  139. y = MIN (y, y1);
  140. x = MIN (x, x1);
  141. /* left-up corner of intersection */
  142. r->y = MAX (r->y, r1->y);
  143. r->x = MAX (r->x, r1->x);
  144. /* intersection sizes */
  145. r->lines = y - r->y;
  146. r->cols = x - r->x;
  147. }
  148. /* --------------------------------------------------------------------------------------------- */
  149. /**
  150. * Calculates the union of two rectangle areas.
  151. * The resulting rectangle is the largest rectangle which contains both rectangle areas.
  152. *
  153. * @param r first WRect object
  154. * @param r1 second WRect object
  155. *
  156. * The resulting rectangle is stored in r.
  157. */
  158. void
  159. rect_union (WRect *r, const WRect *r1)
  160. {
  161. int x, y;
  162. int x1, y1;
  163. /* right-down corners */
  164. y = r->y + r->lines;
  165. x = r->x + r->cols;
  166. y1 = r1->y + r1->lines;
  167. x1 = r1->x + r1->cols;
  168. /* right-down corner of union */
  169. y = MAX (y, y1);
  170. x = MAX (x, x1);
  171. /* left-up corner of union */
  172. r->y = MIN (r->y, r1->y);
  173. r->x = MIN (r->x, r1->x);
  174. /* union sizes */
  175. r->lines = y - r->y;
  176. r->cols = x - r->x;
  177. }
  178. /* --------------------------------------------------------------------------------------------- */
  179. /**
  180. * Check whether two rectangle areas are overlapped or not.
  181. *
  182. * @param r1 WRect object
  183. * @param r2 WRect object
  184. *
  185. * @return TRUE if rectangle areas are overlapped, FALSE otherwise.
  186. */
  187. gboolean
  188. rects_are_overlapped (const WRect *r1, const WRect *r2)
  189. {
  190. return !((r2->x >= r1->x + r1->cols) || (r1->x >= r2->x + r2->cols)
  191. || (r2->y >= r1->y + r1->lines) || (r1->y >= r2->y + r2->lines));
  192. }
  193. /* --------------------------------------------------------------------------------------------- */
  194. /**
  195. * Check whether two rectangle areas are equal or not.
  196. *
  197. * @param r1 WRect object
  198. * @param r2 WRect object
  199. *
  200. * @return TRUE if rectangle areas are equal, FALSE otherwise.
  201. */
  202. gboolean
  203. rects_are_equal (const WRect *r1, const WRect *r2)
  204. {
  205. return (r1->y == r2->y && r1->x == r2->x && r1->lines == r2->lines && r1->cols == r2->cols);
  206. }
  207. /* --------------------------------------------------------------------------------------------- */