| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // require: list_selection_model.js | 5 // require: list_selection_model.js |
| 6 // require: list_selection_controller.js | 6 // require: list_selection_controller.js |
| 7 // require: list.js | 7 // require: list.js |
| 8 | 8 |
| 9 /** | 9 /** |
| 10 * @fileoverview This implements a grid control. Grid contains a bunch of | 10 * @fileoverview This implements a grid control. Grid contains a bunch of |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 * @type {function(new:cr.ui.GridItem, *)} | 66 * @type {function(new:cr.ui.GridItem, *)} |
| 67 * @override | 67 * @override |
| 68 */ | 68 */ |
| 69 itemConstructor_: GridItem, | 69 itemConstructor_: GridItem, |
| 70 | 70 |
| 71 /** | 71 /** |
| 72 * Whether or not the rows on list have various heights. | 72 * Whether or not the rows on list have various heights. |
| 73 * Shows a warning at the setter because cr.ui.Grid does not support this. | 73 * Shows a warning at the setter because cr.ui.Grid does not support this. |
| 74 * @type {boolean} | 74 * @type {boolean} |
| 75 */ | 75 */ |
| 76 get fixedHeight() { | 76 get fixedHeight() { return true; }, |
| 77 return true; | |
| 78 }, | |
| 79 set fixedHeight(fixedHeight) { | 77 set fixedHeight(fixedHeight) { |
| 80 if (!fixedHeight) | 78 if (!fixedHeight) |
| 81 console.warn('cr.ui.Grid does not support fixedHeight = false'); | 79 console.warn('cr.ui.Grid does not support fixedHeight = false'); |
| 82 }, | 80 }, |
| 83 | 81 |
| 84 /** | 82 /** |
| 85 * @return {number} The number of columns determined by width of the grid | 83 * @return {number} The number of columns determined by width of the grid |
| 86 * and width of the items. | 84 * and width of the items. |
| 87 * @private | 85 * @private |
| 88 */ | 86 */ |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 getItemTop: function(index) { | 199 getItemTop: function(index) { |
| 202 return Math.floor(index / this.columns) * this.getDefaultItemHeight_(); | 200 return Math.floor(index / this.columns) * this.getDefaultItemHeight_(); |
| 203 }, | 201 }, |
| 204 | 202 |
| 205 /** | 203 /** |
| 206 * @param {number} index The index of the item. | 204 * @param {number} index The index of the item. |
| 207 * @return {number} The row of the item. May vary in the case | 205 * @return {number} The row of the item. May vary in the case |
| 208 * of multiple columns. | 206 * of multiple columns. |
| 209 * @override | 207 * @override |
| 210 */ | 208 */ |
| 211 getItemRow: function(index) { | 209 getItemRow: function(index) { return Math.floor(index / this.columns); }, |
| 212 return Math.floor(index / this.columns); | |
| 213 }, | |
| 214 | 210 |
| 215 /** | 211 /** |
| 216 * @param {number} row The row. | 212 * @param {number} row The row. |
| 217 * @return {number} The index of the first item in the row. | 213 * @return {number} The index of the first item in the row. |
| 218 * @override | 214 * @override |
| 219 */ | 215 */ |
| 220 getFirstItemInRow: function(row) { | 216 getFirstItemInRow: function(row) { return row * this.columns; }, |
| 221 return row * this.columns; | |
| 222 }, | |
| 223 | 217 |
| 224 /** | 218 /** |
| 225 * Creates the selection controller to use internally. | 219 * Creates the selection controller to use internally. |
| 226 * @param {cr.ui.ListSelectionModel} sm The underlying selection model. | 220 * @param {cr.ui.ListSelectionModel} sm The underlying selection model. |
| 227 * @return {!cr.ui.ListSelectionController} The newly created selection | 221 * @return {!cr.ui.ListSelectionController} The newly created selection |
| 228 * controller. | 222 * controller. |
| 229 * @override | 223 * @override |
| 230 */ | 224 */ |
| 231 createSelectionController: function(sm) { | 225 createSelectionController: function(sm) { |
| 232 return new GridSelectionController(sm, this); | 226 return new GridSelectionController(sm, this); |
| 233 }, | 227 }, |
| 234 | 228 |
| 235 /** | 229 /** |
| 236 * Calculates the number of items fitting in the given viewport. | 230 * Calculates the number of items fitting in the given viewport. |
| 237 * @param {number} scrollTop The scroll top position. | 231 * @param {number} scrollTop The scroll top position. |
| 238 * @param {number} clientHeight The height of viewport. | 232 * @param {number} clientHeight The height of viewport. |
| 239 * @return {{first: number, length: number, last: number}} The index of | 233 * @return {{first: number, length: number, last: number}} The index of |
| 240 * first item in view port, The number of items, The item past the last. | 234 * first item in view port, The number of items, The item past the last. |
| 241 * @override | 235 * @override |
| 242 */ | 236 */ |
| 243 getItemsInViewPort: function(scrollTop, clientHeight) { | 237 getItemsInViewPort: function(scrollTop, clientHeight) { |
| 244 var itemHeight = this.getDefaultItemHeight_(); | 238 var itemHeight = this.getDefaultItemHeight_(); |
| 245 var firstIndex = | 239 var firstIndex = |
| 246 this.autoExpands ? 0 : this.getIndexForListOffset_(scrollTop); | 240 this.autoExpands ? 0 : this.getIndexForListOffset_(scrollTop); |
| 247 var columns = this.columns; | 241 var columns = this.columns; |
| 248 var count = this.autoExpands_ ? this.dataModel.length : Math.max( | 242 var count = this.autoExpands_ ? |
| 249 columns * (Math.ceil(clientHeight / itemHeight) + 1), | 243 this.dataModel.length : |
| 250 this.countItemsInRange_(firstIndex, scrollTop + clientHeight)); | 244 Math.max( |
| 245 columns * (Math.ceil(clientHeight / itemHeight) + 1), |
| 246 this.countItemsInRange_(firstIndex, scrollTop + clientHeight)); |
| 251 count = columns * Math.ceil(count / columns); | 247 count = columns * Math.ceil(count / columns); |
| 252 count = Math.min(count, this.dataModel.length - firstIndex); | 248 count = Math.min(count, this.dataModel.length - firstIndex); |
| 253 return { | 249 return {first: firstIndex, length: count, last: firstIndex + count - 1}; |
| 254 first: firstIndex, | |
| 255 length: count, | |
| 256 last: firstIndex + count - 1 | |
| 257 }; | |
| 258 }, | 250 }, |
| 259 | 251 |
| 260 /** | 252 /** |
| 261 * Merges list items. Calls the base class implementation and then | 253 * Merges list items. Calls the base class implementation and then |
| 262 * puts spacers on the right places. | 254 * puts spacers on the right places. |
| 263 * @param {number} firstIndex The index of first item, inclusively. | 255 * @param {number} firstIndex The index of first item, inclusively. |
| 264 * @param {number} lastIndex The index of last item, exclusively. | 256 * @param {number} lastIndex The index of last item, exclusively. |
| 265 * @override | 257 * @override |
| 266 */ | 258 */ |
| 267 mergeItems: function(firstIndex, lastIndex) { | 259 mergeItems: function(firstIndex, lastIndex) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 294 spacer.className = 'spacer'; | 286 spacer.className = 'spacer'; |
| 295 this.insertBefore(spacer, next); | 287 this.insertBefore(spacer, next); |
| 296 item = next; | 288 item = next; |
| 297 } | 289 } |
| 298 } else | 290 } else |
| 299 item = next; | 291 item = next; |
| 300 } | 292 } |
| 301 | 293 |
| 302 function isSpacer(child) { | 294 function isSpacer(child) { |
| 303 return child.classList.contains('spacer') && | 295 return child.classList.contains('spacer') && |
| 304 child != afterFiller; // Must not be removed. | 296 child != afterFiller; // Must not be removed. |
| 305 } | 297 } |
| 306 }, | 298 }, |
| 307 | 299 |
| 308 /** | 300 /** |
| 309 * Returns the height of after filler in the list. | 301 * Returns the height of after filler in the list. |
| 310 * @param {number} lastIndex The index of item past the last in viewport. | 302 * @param {number} lastIndex The index of item past the last in viewport. |
| 311 * @return {number} The height of after filler. | 303 * @return {number} The height of after filler. |
| 312 * @override | 304 * @override |
| 313 */ | 305 */ |
| 314 getAfterFillerHeight: function(lastIndex) { | 306 getAfterFillerHeight: function(lastIndex) { |
| 315 var columns = this.columns; | 307 var columns = this.columns; |
| 316 var itemHeight = this.getDefaultItemHeight_(); | 308 var itemHeight = this.getDefaultItemHeight_(); |
| 317 // We calculate the row of last item, and the row of last shown item. | 309 // We calculate the row of last item, and the row of last shown item. |
| 318 // The difference is the number of rows not shown. | 310 // The difference is the number of rows not shown. |
| 319 var afterRows = Math.floor((this.dataModel.length - 1) / columns) - | 311 var afterRows = Math.floor((this.dataModel.length - 1) / columns) - |
| 320 Math.floor((lastIndex - 1) / columns); | 312 Math.floor((lastIndex - 1) / columns); |
| 321 return afterRows * itemHeight; | 313 return afterRows * itemHeight; |
| 322 }, | 314 }, |
| 323 | 315 |
| 324 /** | 316 /** |
| 325 * Returns true if the child is a list item. | 317 * Returns true if the child is a list item. |
| 326 * @param {Node} child Child of the list. | 318 * @param {Node} child Child of the list. |
| 327 * @return {boolean} True if a list item. | 319 * @return {boolean} True if a list item. |
| 328 */ | 320 */ |
| 329 isItem: function(child) { | 321 isItem: function(child) { |
| 330 // Non-items are before-, afterFiller and spacers added in mergeItems. | 322 // Non-items are before-, afterFiller and spacers added in mergeItems. |
| 331 return child.nodeType == Node.ELEMENT_NODE && | 323 return child.nodeType == Node.ELEMENT_NODE && |
| 332 !child.classList.contains('spacer'); | 324 !child.classList.contains('spacer'); |
| 333 }, | 325 }, |
| 334 | 326 |
| 335 redraw: function() { | 327 redraw: function() { |
| 336 this.updateMetrics_(); | 328 this.updateMetrics_(); |
| 337 var itemCount = this.dataModel ? this.dataModel.length : 0; | 329 var itemCount = this.dataModel ? this.dataModel.length : 0; |
| 338 if (this.lastItemCount_ != itemCount) { | 330 if (this.lastItemCount_ != itemCount) { |
| 339 this.lastItemCount_ = itemCount; | 331 this.lastItemCount_ = itemCount; |
| 340 // Force recalculation. | 332 // Force recalculation. |
| 341 this.columns_ = 0; | 333 this.columns_ = 0; |
| 342 } | 334 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 364 /** | 356 /** |
| 365 * Check if accessibility is enabled: if ChromeVox is running | 357 * Check if accessibility is enabled: if ChromeVox is running |
| 366 * (which provides spoken feedback for accessibility), make up/down | 358 * (which provides spoken feedback for accessibility), make up/down |
| 367 * behave the same as left/right. That's because the 2-dimensional | 359 * behave the same as left/right. That's because the 2-dimensional |
| 368 * structure of the grid isn't exposed, so it makes more sense to a | 360 * structure of the grid isn't exposed, so it makes more sense to a |
| 369 * user who is relying on spoken feedback to flatten it. | 361 * user who is relying on spoken feedback to flatten it. |
| 370 * @return {boolean} True if accessibility is enabled. | 362 * @return {boolean} True if accessibility is enabled. |
| 371 */ | 363 */ |
| 372 isAccessibilityEnabled: function() { | 364 isAccessibilityEnabled: function() { |
| 373 return window.cvox && window.cvox.Api && | 365 return window.cvox && window.cvox.Api && |
| 374 window.cvox.Api.isChromeVoxActive && | 366 window.cvox.Api.isChromeVoxActive && |
| 375 window.cvox.Api.isChromeVoxActive(); | 367 window.cvox.Api.isChromeVoxActive(); |
| 376 }, | 368 }, |
| 377 | 369 |
| 378 /** | 370 /** |
| 379 * Returns the index below (y axis) the given element. | 371 * Returns the index below (y axis) the given element. |
| 380 * @param {number} index The index to get the index below. | 372 * @param {number} index The index to get the index below. |
| 381 * @return {number} The index below or -1 if not found. | 373 * @return {number} The index below or -1 if not found. |
| 382 * @override | 374 * @override |
| 383 */ | 375 */ |
| 384 getIndexBelow: function(index) { | 376 getIndexBelow: function(index) { |
| 385 if (this.isAccessibilityEnabled()) | 377 if (this.isAccessibilityEnabled()) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 405 index -= this.grid_.columns; | 397 index -= this.grid_.columns; |
| 406 return Math.max(index, 0); | 398 return Math.max(index, 0); |
| 407 }, | 399 }, |
| 408 | 400 |
| 409 /** | 401 /** |
| 410 * Returns the index before (x axis) the given element. | 402 * Returns the index before (x axis) the given element. |
| 411 * @param {number} index The index to get the index before. | 403 * @param {number} index The index to get the index before. |
| 412 * @return {number} The index before or -1 if not found. | 404 * @return {number} The index before or -1 if not found. |
| 413 * @override | 405 * @override |
| 414 */ | 406 */ |
| 415 getIndexBefore: function(index) { | 407 getIndexBefore: function(index) { return index - 1; }, |
| 416 return index - 1; | |
| 417 }, | |
| 418 | 408 |
| 419 /** | 409 /** |
| 420 * Returns the index after (x axis) the given element. | 410 * Returns the index after (x axis) the given element. |
| 421 * @param {number} index The index to get the index after. | 411 * @param {number} index The index to get the index after. |
| 422 * @return {number} The index after or -1 if not found. | 412 * @return {number} The index after or -1 if not found. |
| 423 * @override | 413 * @override |
| 424 */ | 414 */ |
| 425 getIndexAfter: function(index) { | 415 getIndexAfter: function(index) { |
| 426 if (index == this.getLastIndex()) { | 416 if (index == this.getLastIndex()) { |
| 427 return -1; | 417 return -1; |
| 428 } | 418 } |
| 429 return index + 1; | 419 return index + 1; |
| 430 } | 420 } |
| 431 }; | 421 }; |
| 432 | 422 |
| 433 return { | 423 return { |
| 434 Grid: Grid, | 424 Grid: Grid, |
| 435 GridItem: GridItem, | 425 GridItem: GridItem, |
| 436 GridSelectionController: GridSelectionController | 426 GridSelectionController: GridSelectionController |
| 437 }; | 427 }; |
| 438 }); | 428 }); |
| OLD | NEW |