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