| OLD | NEW |
| (Empty) |
| 1 /** | |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | |
| 3 * (C) 2000 Simon Hausmann <hausmann@kde.org> | |
| 4 * (C) 2000 Stefan Schimanski (1Stein@gmx.de) | |
| 5 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. | |
| 6 * | |
| 7 * This library is free software; you can redistribute it and/or | |
| 8 * modify it under the terms of the GNU Library General Public | |
| 9 * License as published by the Free Software Foundation; either | |
| 10 * version 2 of the License, or (at your option) any later version. | |
| 11 * | |
| 12 * This library is distributed in the hope that it will be useful, | |
| 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 15 * Library General Public License for more details. | |
| 16 * | |
| 17 * You should have received a copy of the GNU Library General Public License | |
| 18 * along with this library; see the file COPYING.LIB. If not, write to | |
| 19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
| 20 * Boston, MA 02110-1301, USA. | |
| 21 * | |
| 22 */ | |
| 23 | |
| 24 #include "config.h" | |
| 25 #include "core/rendering/RenderFrameSet.h" | |
| 26 | |
| 27 #include "core/dom/Document.h" | |
| 28 #include "core/events/MouseEvent.h" | |
| 29 #include "core/frame/LocalFrame.h" | |
| 30 #include "core/html/HTMLDimension.h" | |
| 31 #include "core/html/HTMLFrameSetElement.h" | |
| 32 #include "core/layout/PaintInfo.h" | |
| 33 #include "core/page/EventHandler.h" | |
| 34 #include "core/paint/FrameSetPainter.h" | |
| 35 #include "core/rendering/RenderFrame.h" | |
| 36 #include "core/rendering/RenderView.h" | |
| 37 #include "platform/Cursor.h" | |
| 38 #include "platform/graphics/GraphicsContext.h" | |
| 39 | |
| 40 namespace blink { | |
| 41 | |
| 42 RenderFrameSet::RenderFrameSet(HTMLFrameSetElement* frameSet) | |
| 43 : RenderBox(frameSet) | |
| 44 , m_isResizing(false) | |
| 45 , m_isChildResizing(false) | |
| 46 { | |
| 47 setInline(false); | |
| 48 } | |
| 49 | |
| 50 RenderFrameSet::~RenderFrameSet() | |
| 51 { | |
| 52 } | |
| 53 | |
| 54 RenderFrameSet::GridAxis::GridAxis() | |
| 55 : m_splitBeingResized(noSplit) | |
| 56 { | |
| 57 } | |
| 58 | |
| 59 HTMLFrameSetElement* RenderFrameSet::frameSet() const | |
| 60 { | |
| 61 return toHTMLFrameSetElement(node()); | |
| 62 } | |
| 63 | |
| 64 void RenderFrameSet::paint(const PaintInfo& paintInfo, const LayoutPoint& paintO
ffset) | |
| 65 { | |
| 66 FrameSetPainter(*this).paint(paintInfo, paintOffset); | |
| 67 } | |
| 68 | |
| 69 void RenderFrameSet::computePreferredLogicalWidths() | |
| 70 { | |
| 71 m_minPreferredLogicalWidth = 0; | |
| 72 m_maxPreferredLogicalWidth = 0; | |
| 73 clearPreferredLogicalWidthsDirty(); | |
| 74 } | |
| 75 | |
| 76 void RenderFrameSet::GridAxis::resize(int size) | |
| 77 { | |
| 78 m_sizes.resize(size); | |
| 79 m_deltas.resize(size); | |
| 80 m_deltas.fill(0); | |
| 81 | |
| 82 // To track edges for resizability and borders, we need to be (size + 1). Th
is is because a parent frameset | |
| 83 // may ask us for information about our left/top/right/bottom edges in order
to make its own decisions about | |
| 84 // what to do. We are capable of tainting that parent frameset's borders, so
we have to cache this info. | |
| 85 m_preventResize.resize(size + 1); | |
| 86 m_allowBorder.resize(size + 1); | |
| 87 } | |
| 88 | |
| 89 void RenderFrameSet::layOutAxis(GridAxis& axis, const Vector<HTMLDimension>& gri
d, int availableLen) | |
| 90 { | |
| 91 availableLen = max(availableLen, 0); | |
| 92 | |
| 93 int* gridLayout = axis.m_sizes.data(); | |
| 94 | |
| 95 if (grid.isEmpty()) { | |
| 96 gridLayout[0] = availableLen; | |
| 97 return; | |
| 98 } | |
| 99 | |
| 100 int gridLen = axis.m_sizes.size(); | |
| 101 ASSERT(gridLen); | |
| 102 | |
| 103 int totalRelative = 0; | |
| 104 int totalFixed = 0; | |
| 105 int totalPercent = 0; | |
| 106 int countRelative = 0; | |
| 107 int countFixed = 0; | |
| 108 int countPercent = 0; | |
| 109 | |
| 110 // First we need to investigate how many columns of each type we have and | |
| 111 // how much space these columns are going to require. | |
| 112 for (int i = 0; i < gridLen; ++i) { | |
| 113 // Count the total length of all of the fixed columns/rows -> totalFixed | |
| 114 // Count the number of columns/rows which are fixed -> countFixed | |
| 115 if (grid[i].isAbsolute()) { | |
| 116 gridLayout[i] = max<int>(grid[i].value(), 0); | |
| 117 totalFixed += gridLayout[i]; | |
| 118 countFixed++; | |
| 119 } | |
| 120 | |
| 121 // Count the total percentage of all of the percentage columns/rows -> t
otalPercent | |
| 122 // Count the number of columns/rows which are percentages -> countPercen
t | |
| 123 if (grid[i].isPercentage()) { | |
| 124 gridLayout[i] = max<int>(grid[i].value() * availableLen / 100., 0); | |
| 125 totalPercent += gridLayout[i]; | |
| 126 countPercent++; | |
| 127 } | |
| 128 | |
| 129 // Count the total relative of all the relative columns/rows -> totalRel
ative | |
| 130 // Count the number of columns/rows which are relative -> countRelative | |
| 131 if (grid[i].isRelative()) { | |
| 132 totalRelative += max<int>(grid[i].value(), 1); | |
| 133 countRelative++; | |
| 134 } | |
| 135 } | |
| 136 | |
| 137 int remainingLen = availableLen; | |
| 138 | |
| 139 // Fixed columns/rows are our first priority. If there is not enough space t
o fit all fixed | |
| 140 // columns/rows we need to proportionally adjust their size. | |
| 141 if (totalFixed > remainingLen) { | |
| 142 int remainingFixed = remainingLen; | |
| 143 | |
| 144 for (int i = 0; i < gridLen; ++i) { | |
| 145 if (grid[i].isAbsolute()) { | |
| 146 gridLayout[i] = (gridLayout[i] * remainingFixed) / totalFixed; | |
| 147 remainingLen -= gridLayout[i]; | |
| 148 } | |
| 149 } | |
| 150 } else | |
| 151 remainingLen -= totalFixed; | |
| 152 | |
| 153 // Percentage columns/rows are our second priority. Divide the remaining spa
ce proportionally | |
| 154 // over all percentage columns/rows. IMPORTANT: the size of each column/row
is not relative | |
| 155 // to 100%, but to the total percentage. For example, if there are three col
umns, each of 75%, | |
| 156 // and the available space is 300px, each column will become 100px in width. | |
| 157 if (totalPercent > remainingLen) { | |
| 158 int remainingPercent = remainingLen; | |
| 159 | |
| 160 for (int i = 0; i < gridLen; ++i) { | |
| 161 if (grid[i].isPercentage()) { | |
| 162 gridLayout[i] = (gridLayout[i] * remainingPercent) / totalPercen
t; | |
| 163 remainingLen -= gridLayout[i]; | |
| 164 } | |
| 165 } | |
| 166 } else | |
| 167 remainingLen -= totalPercent; | |
| 168 | |
| 169 // Relative columns/rows are our last priority. Divide the remaining space p
roportionally | |
| 170 // over all relative columns/rows. IMPORTANT: the relative value of 0* is tr
eated as 1*. | |
| 171 if (countRelative) { | |
| 172 int lastRelative = 0; | |
| 173 int remainingRelative = remainingLen; | |
| 174 | |
| 175 for (int i = 0; i < gridLen; ++i) { | |
| 176 if (grid[i].isRelative()) { | |
| 177 gridLayout[i] = (max(grid[i].value(), 1.) * remainingRelative) /
totalRelative; | |
| 178 remainingLen -= gridLayout[i]; | |
| 179 lastRelative = i; | |
| 180 } | |
| 181 } | |
| 182 | |
| 183 // If we could not evenly distribute the available space of all of the r
elative | |
| 184 // columns/rows, the remainder will be added to the last column/row. | |
| 185 // For example: if we have a space of 100px and three columns (*,*,*), t
he remainder will | |
| 186 // be 1px and will be added to the last column: 33px, 33px, 34px. | |
| 187 if (remainingLen) { | |
| 188 gridLayout[lastRelative] += remainingLen; | |
| 189 remainingLen = 0; | |
| 190 } | |
| 191 } | |
| 192 | |
| 193 // If we still have some left over space we need to divide it over the alrea
dy existing | |
| 194 // columns/rows | |
| 195 if (remainingLen) { | |
| 196 // Our first priority is to spread if over the percentage columns. The r
emaining | |
| 197 // space is spread evenly, for example: if we have a space of 100px, the
columns | |
| 198 // definition of 25%,25% used to result in two columns of 25px. After th
is the | |
| 199 // columns will each be 50px in width. | |
| 200 if (countPercent && totalPercent) { | |
| 201 int remainingPercent = remainingLen; | |
| 202 int changePercent = 0; | |
| 203 | |
| 204 for (int i = 0; i < gridLen; ++i) { | |
| 205 if (grid[i].isPercentage()) { | |
| 206 changePercent = (remainingPercent * gridLayout[i]) / totalPe
rcent; | |
| 207 gridLayout[i] += changePercent; | |
| 208 remainingLen -= changePercent; | |
| 209 } | |
| 210 } | |
| 211 } else if (totalFixed) { | |
| 212 // Our last priority is to spread the remaining space over the fixed
columns. | |
| 213 // For example if we have 100px of space and two column of each 40px
, both | |
| 214 // columns will become exactly 50px. | |
| 215 int remainingFixed = remainingLen; | |
| 216 int changeFixed = 0; | |
| 217 | |
| 218 for (int i = 0; i < gridLen; ++i) { | |
| 219 if (grid[i].isAbsolute()) { | |
| 220 changeFixed = (remainingFixed * gridLayout[i]) / totalFixed; | |
| 221 gridLayout[i] += changeFixed; | |
| 222 remainingLen -= changeFixed; | |
| 223 } | |
| 224 } | |
| 225 } | |
| 226 } | |
| 227 | |
| 228 // If we still have some left over space we probably ended up with a remaind
er of | |
| 229 // a division. We cannot spread it evenly anymore. If we have any percentage | |
| 230 // columns/rows simply spread the remainder equally over all available perce
ntage columns, | |
| 231 // regardless of their size. | |
| 232 if (remainingLen && countPercent) { | |
| 233 int remainingPercent = remainingLen; | |
| 234 int changePercent = 0; | |
| 235 | |
| 236 for (int i = 0; i < gridLen; ++i) { | |
| 237 if (grid[i].isPercentage()) { | |
| 238 changePercent = remainingPercent / countPercent; | |
| 239 gridLayout[i] += changePercent; | |
| 240 remainingLen -= changePercent; | |
| 241 } | |
| 242 } | |
| 243 } else if (remainingLen && countFixed) { | |
| 244 // If we don't have any percentage columns/rows we only have | |
| 245 // fixed columns. Spread the remainder equally over all fixed | |
| 246 // columns/rows. | |
| 247 int remainingFixed = remainingLen; | |
| 248 int changeFixed = 0; | |
| 249 | |
| 250 for (int i = 0; i < gridLen; ++i) { | |
| 251 if (grid[i].isAbsolute()) { | |
| 252 changeFixed = remainingFixed / countFixed; | |
| 253 gridLayout[i] += changeFixed; | |
| 254 remainingLen -= changeFixed; | |
| 255 } | |
| 256 } | |
| 257 } | |
| 258 | |
| 259 // Still some left over. Add it to the last column, because it is impossible | |
| 260 // spread it evenly or equally. | |
| 261 if (remainingLen) | |
| 262 gridLayout[gridLen - 1] += remainingLen; | |
| 263 | |
| 264 // now we have the final layout, distribute the delta over it | |
| 265 bool worked = true; | |
| 266 int* gridDelta = axis.m_deltas.data(); | |
| 267 for (int i = 0; i < gridLen; ++i) { | |
| 268 if (gridLayout[i] && gridLayout[i] + gridDelta[i] <= 0) | |
| 269 worked = false; | |
| 270 gridLayout[i] += gridDelta[i]; | |
| 271 } | |
| 272 // if the deltas broke something, undo them | |
| 273 if (!worked) { | |
| 274 for (int i = 0; i < gridLen; ++i) | |
| 275 gridLayout[i] -= gridDelta[i]; | |
| 276 axis.m_deltas.fill(0); | |
| 277 } | |
| 278 } | |
| 279 | |
| 280 void RenderFrameSet::notifyFrameEdgeInfoChanged() | |
| 281 { | |
| 282 if (needsLayout()) | |
| 283 return; | |
| 284 // FIXME: We should only recompute the edge info with respect to the frame t
hat changed | |
| 285 // and its adjacent frame(s) instead of recomputing the edge info for the en
tire frameset. | |
| 286 computeEdgeInfo(); | |
| 287 } | |
| 288 | |
| 289 void RenderFrameSet::fillFromEdgeInfo(const FrameEdgeInfo& edgeInfo, int r, int
c) | |
| 290 { | |
| 291 if (edgeInfo.allowBorder(LeftFrameEdge)) | |
| 292 m_cols.m_allowBorder[c] = true; | |
| 293 if (edgeInfo.allowBorder(RightFrameEdge)) | |
| 294 m_cols.m_allowBorder[c + 1] = true; | |
| 295 if (edgeInfo.preventResize(LeftFrameEdge)) | |
| 296 m_cols.m_preventResize[c] = true; | |
| 297 if (edgeInfo.preventResize(RightFrameEdge)) | |
| 298 m_cols.m_preventResize[c + 1] = true; | |
| 299 | |
| 300 if (edgeInfo.allowBorder(TopFrameEdge)) | |
| 301 m_rows.m_allowBorder[r] = true; | |
| 302 if (edgeInfo.allowBorder(BottomFrameEdge)) | |
| 303 m_rows.m_allowBorder[r + 1] = true; | |
| 304 if (edgeInfo.preventResize(TopFrameEdge)) | |
| 305 m_rows.m_preventResize[r] = true; | |
| 306 if (edgeInfo.preventResize(BottomFrameEdge)) | |
| 307 m_rows.m_preventResize[r + 1] = true; | |
| 308 } | |
| 309 | |
| 310 void RenderFrameSet::computeEdgeInfo() | |
| 311 { | |
| 312 m_rows.m_preventResize.fill(frameSet()->noResize()); | |
| 313 m_rows.m_allowBorder.fill(false); | |
| 314 m_cols.m_preventResize.fill(frameSet()->noResize()); | |
| 315 m_cols.m_allowBorder.fill(false); | |
| 316 | |
| 317 LayoutObject* child = firstChild(); | |
| 318 if (!child) | |
| 319 return; | |
| 320 | |
| 321 size_t rows = m_rows.m_sizes.size(); | |
| 322 size_t cols = m_cols.m_sizes.size(); | |
| 323 for (size_t r = 0; r < rows; ++r) { | |
| 324 for (size_t c = 0; c < cols; ++c) { | |
| 325 FrameEdgeInfo edgeInfo; | |
| 326 if (child->isFrameSet()) | |
| 327 edgeInfo = toRenderFrameSet(child)->edgeInfo(); | |
| 328 else | |
| 329 edgeInfo = toRenderFrame(child)->edgeInfo(); | |
| 330 fillFromEdgeInfo(edgeInfo, r, c); | |
| 331 child = child->nextSibling(); | |
| 332 if (!child) | |
| 333 return; | |
| 334 } | |
| 335 } | |
| 336 } | |
| 337 | |
| 338 FrameEdgeInfo RenderFrameSet::edgeInfo() const | |
| 339 { | |
| 340 FrameEdgeInfo result(frameSet()->noResize(), true); | |
| 341 | |
| 342 int rows = frameSet()->totalRows(); | |
| 343 int cols = frameSet()->totalCols(); | |
| 344 if (rows && cols) { | |
| 345 result.setPreventResize(LeftFrameEdge, m_cols.m_preventResize[0]); | |
| 346 result.setAllowBorder(LeftFrameEdge, m_cols.m_allowBorder[0]); | |
| 347 result.setPreventResize(RightFrameEdge, m_cols.m_preventResize[cols]); | |
| 348 result.setAllowBorder(RightFrameEdge, m_cols.m_allowBorder[cols]); | |
| 349 result.setPreventResize(TopFrameEdge, m_rows.m_preventResize[0]); | |
| 350 result.setAllowBorder(TopFrameEdge, m_rows.m_allowBorder[0]); | |
| 351 result.setPreventResize(BottomFrameEdge, m_rows.m_preventResize[rows]); | |
| 352 result.setAllowBorder(BottomFrameEdge, m_rows.m_allowBorder[rows]); | |
| 353 } | |
| 354 | |
| 355 return result; | |
| 356 } | |
| 357 | |
| 358 void RenderFrameSet::layout() | |
| 359 { | |
| 360 ASSERT(needsLayout()); | |
| 361 | |
| 362 if (!parent()->isFrameSet() && !document().printing()) { | |
| 363 setWidth(view()->viewWidth()); | |
| 364 setHeight(view()->viewHeight()); | |
| 365 } | |
| 366 | |
| 367 unsigned cols = frameSet()->totalCols(); | |
| 368 unsigned rows = frameSet()->totalRows(); | |
| 369 | |
| 370 if (m_rows.m_sizes.size() != rows || m_cols.m_sizes.size() != cols) { | |
| 371 m_rows.resize(rows); | |
| 372 m_cols.resize(cols); | |
| 373 } | |
| 374 | |
| 375 LayoutUnit borderThickness = frameSet()->border(); | |
| 376 layOutAxis(m_rows, frameSet()->rowLengths(), size().height() - (rows - 1) *
borderThickness); | |
| 377 layOutAxis(m_cols, frameSet()->colLengths(), size().width() - (cols - 1) * b
orderThickness); | |
| 378 | |
| 379 positionFrames(); | |
| 380 | |
| 381 RenderBox::layout(); | |
| 382 | |
| 383 computeEdgeInfo(); | |
| 384 | |
| 385 updateLayerTransformAfterLayout(); | |
| 386 | |
| 387 clearNeedsLayout(); | |
| 388 } | |
| 389 | |
| 390 static void clearNeedsLayoutOnHiddenFrames(RenderBox* frame) | |
| 391 { | |
| 392 for (; frame; frame = frame->nextSiblingBox()) { | |
| 393 frame->setWidth(0); | |
| 394 frame->setHeight(0); | |
| 395 frame->clearNeedsLayout(); | |
| 396 clearNeedsLayoutOnHiddenFrames(frame->firstChildBox()); | |
| 397 } | |
| 398 } | |
| 399 | |
| 400 void RenderFrameSet::positionFrames() | |
| 401 { | |
| 402 RenderBox* child = firstChildBox(); | |
| 403 if (!child) | |
| 404 return; | |
| 405 | |
| 406 int rows = frameSet()->totalRows(); | |
| 407 int cols = frameSet()->totalCols(); | |
| 408 | |
| 409 int borderThickness = frameSet()->border(); | |
| 410 LayoutSize size; | |
| 411 LayoutPoint position; | |
| 412 for (int r = 0; r < rows; r++) { | |
| 413 position.setX(0); | |
| 414 size.setHeight(m_rows.m_sizes[r]); | |
| 415 for (int c = 0; c < cols; c++) { | |
| 416 child->setLocation(position); | |
| 417 size.setWidth(m_cols.m_sizes[c]); | |
| 418 | |
| 419 // has to be resized and itself resize its contents | |
| 420 if (size != child->size()) { | |
| 421 child->setSize(size); | |
| 422 child->setNeedsLayoutAndFullPaintInvalidation(); | |
| 423 child->layout(); | |
| 424 } | |
| 425 | |
| 426 position.setX(position.x() + size.width() + borderThickness); | |
| 427 | |
| 428 child = child->nextSiblingBox(); | |
| 429 if (!child) | |
| 430 return; | |
| 431 } | |
| 432 position.setY(position.y() + size.height() + borderThickness); | |
| 433 } | |
| 434 | |
| 435 // All the remaining frames are hidden to avoid ugly spurious unflowed frame
s. | |
| 436 clearNeedsLayoutOnHiddenFrames(child); | |
| 437 } | |
| 438 | |
| 439 void RenderFrameSet::startResizing(GridAxis& axis, int position) | |
| 440 { | |
| 441 int split = hitTestSplit(axis, position); | |
| 442 if (split == noSplit || axis.m_preventResize[split]) { | |
| 443 axis.m_splitBeingResized = noSplit; | |
| 444 return; | |
| 445 } | |
| 446 axis.m_splitBeingResized = split; | |
| 447 axis.m_splitResizeOffset = position - splitPosition(axis, split); | |
| 448 } | |
| 449 | |
| 450 void RenderFrameSet::continueResizing(GridAxis& axis, int position) | |
| 451 { | |
| 452 if (needsLayout()) | |
| 453 return; | |
| 454 if (axis.m_splitBeingResized == noSplit) | |
| 455 return; | |
| 456 int currentSplitPosition = splitPosition(axis, axis.m_splitBeingResized); | |
| 457 int delta = (position - currentSplitPosition) - axis.m_splitResizeOffset; | |
| 458 if (!delta) | |
| 459 return; | |
| 460 axis.m_deltas[axis.m_splitBeingResized - 1] += delta; | |
| 461 axis.m_deltas[axis.m_splitBeingResized] -= delta; | |
| 462 setNeedsLayoutAndFullPaintInvalidation(); | |
| 463 } | |
| 464 | |
| 465 bool RenderFrameSet::userResize(MouseEvent* evt) | |
| 466 { | |
| 467 if (!m_isResizing) { | |
| 468 if (needsLayout()) | |
| 469 return false; | |
| 470 if (evt->type() == EventTypeNames::mousedown && evt->button() == LeftBut
ton) { | |
| 471 FloatPoint localPos = absoluteToLocal(FloatPoint(evt->absoluteLocati
on()), UseTransforms); | |
| 472 startResizing(m_cols, localPos.x()); | |
| 473 startResizing(m_rows, localPos.y()); | |
| 474 if (m_cols.m_splitBeingResized != noSplit || m_rows.m_splitBeingResi
zed != noSplit) { | |
| 475 setIsResizing(true); | |
| 476 return true; | |
| 477 } | |
| 478 } | |
| 479 } else { | |
| 480 if (evt->type() == EventTypeNames::mousemove || (evt->type() == EventTyp
eNames::mouseup && evt->button() == LeftButton)) { | |
| 481 FloatPoint localPos = absoluteToLocal(FloatPoint(evt->absoluteLocati
on()), UseTransforms); | |
| 482 continueResizing(m_cols, localPos.x()); | |
| 483 continueResizing(m_rows, localPos.y()); | |
| 484 if (evt->type() == EventTypeNames::mouseup && evt->button() == LeftB
utton) { | |
| 485 setIsResizing(false); | |
| 486 return true; | |
| 487 } | |
| 488 } | |
| 489 } | |
| 490 | |
| 491 return false; | |
| 492 } | |
| 493 | |
| 494 void RenderFrameSet::setIsResizing(bool isResizing) | |
| 495 { | |
| 496 m_isResizing = isResizing; | |
| 497 for (LayoutObject* ancestor = parent(); ancestor; ancestor = ancestor->paren
t()) { | |
| 498 if (ancestor->isFrameSet()) | |
| 499 toRenderFrameSet(ancestor)->m_isChildResizing = isResizing; | |
| 500 } | |
| 501 if (LocalFrame* frame = this->frame()) | |
| 502 frame->eventHandler().setResizingFrameSet(isResizing ? frameSet() : 0); | |
| 503 } | |
| 504 | |
| 505 bool RenderFrameSet::canResizeRow(const IntPoint& p) const | |
| 506 { | |
| 507 int r = hitTestSplit(m_rows, p.y()); | |
| 508 return r != noSplit && !m_rows.m_preventResize[r]; | |
| 509 } | |
| 510 | |
| 511 bool RenderFrameSet::canResizeColumn(const IntPoint& p) const | |
| 512 { | |
| 513 int c = hitTestSplit(m_cols, p.x()); | |
| 514 return c != noSplit && !m_cols.m_preventResize[c]; | |
| 515 } | |
| 516 | |
| 517 int RenderFrameSet::splitPosition(const GridAxis& axis, int split) const | |
| 518 { | |
| 519 if (needsLayout()) | |
| 520 return 0; | |
| 521 | |
| 522 int borderThickness = frameSet()->border(); | |
| 523 | |
| 524 int size = axis.m_sizes.size(); | |
| 525 if (!size) | |
| 526 return 0; | |
| 527 | |
| 528 int position = 0; | |
| 529 for (int i = 0; i < split && i < size; ++i) | |
| 530 position += axis.m_sizes[i] + borderThickness; | |
| 531 return position - borderThickness; | |
| 532 } | |
| 533 | |
| 534 int RenderFrameSet::hitTestSplit(const GridAxis& axis, int position) const | |
| 535 { | |
| 536 if (needsLayout()) | |
| 537 return noSplit; | |
| 538 | |
| 539 int borderThickness = frameSet()->border(); | |
| 540 if (borderThickness <= 0) | |
| 541 return noSplit; | |
| 542 | |
| 543 size_t size = axis.m_sizes.size(); | |
| 544 if (!size) | |
| 545 return noSplit; | |
| 546 | |
| 547 int splitPosition = axis.m_sizes[0]; | |
| 548 for (size_t i = 1; i < size; ++i) { | |
| 549 if (position >= splitPosition && position < splitPosition + borderThickn
ess) | |
| 550 return i; | |
| 551 splitPosition += borderThickness + axis.m_sizes[i]; | |
| 552 } | |
| 553 return noSplit; | |
| 554 } | |
| 555 | |
| 556 bool RenderFrameSet::isChildAllowed(LayoutObject* child, const LayoutStyle&) con
st | |
| 557 { | |
| 558 return child->isFrame() || child->isFrameSet(); | |
| 559 } | |
| 560 | |
| 561 CursorDirective RenderFrameSet::getCursor(const LayoutPoint& point, Cursor& curs
or) const | |
| 562 { | |
| 563 IntPoint roundedPoint = roundedIntPoint(point); | |
| 564 if (canResizeRow(roundedPoint)) { | |
| 565 cursor = rowResizeCursor(); | |
| 566 return SetCursor; | |
| 567 } | |
| 568 if (canResizeColumn(roundedPoint)) { | |
| 569 cursor = columnResizeCursor(); | |
| 570 return SetCursor; | |
| 571 } | |
| 572 return RenderBox::getCursor(point, cursor); | |
| 573 } | |
| 574 | |
| 575 } // namespace blink | |
| OLD | NEW |