guiArrayCtrl.cpp
Engine/source/gui/core/guiArrayCtrl.cpp
Public Functions
ConsoleDocClass(GuiArrayCtrl , "@brief Abstract base class <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> controls that store and display multiple elements in <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> single <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">view.\n\n</a>" "You cannot actually instantiate this class. Instead you can use its <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">childre:\n\n</a>" "- <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiConsole\n</a>" "- <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiTextListCtrl\n</a>" "- <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiTreeViewCtrl\n</a>" "- <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">DbgFileView\n</a>" "- <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">CreatorTree\n</a>" "This base class is primarily used by other internal classes or those dedicated <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">editors.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiCore\n</a>" "@internal" )
IMPLEMENT_CALLBACK(GuiArrayCtrl , onCellHighlighted , void , (const Point2I &cell) , (cell) , "Call when <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> cell in the array is highlighted (moused over).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@param @cell Coordinates of the cell" )
IMPLEMENT_CALLBACK(GuiArrayCtrl , onCellSelected , void , (const Point2I &cell) , (cell) , "Call when <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> cell in the array is selected (clicked).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@param @cell Coordinates of the cell" )
Detailed Description
Public Functions
ConsoleDocClass(GuiArrayCtrl , "@brief Abstract base class <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> controls that store and display multiple elements in <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> single <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">view.\n\n</a>" "You cannot actually instantiate this class. Instead you can use its <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">childre:\n\n</a>" "- <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiConsole\n</a>" "- <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiTextListCtrl\n</a>" "- <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiTreeViewCtrl\n</a>" "- <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">DbgFileView\n</a>" "- <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">CreatorTree\n</a>" "This base class is primarily used by other internal classes or those dedicated <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">editors.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiCore\n</a>" "@internal" )
IMPLEMENT_CALLBACK(GuiArrayCtrl , onCellHighlighted , void , (const Point2I &cell) , (cell) , "Call when <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> cell in the array is highlighted (moused over).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@param @cell Coordinates of the cell" )
IMPLEMENT_CALLBACK(GuiArrayCtrl , onCellSelected , void , (const Point2I &cell) , (cell) , "Call when <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> cell in the array is selected (clicked).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@param @cell Coordinates of the cell" )
IMPLEMENT_CONOBJECT(GuiArrayCtrl )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "gui/core/guiArrayCtrl.h" 26 27#include "console/console.h" 28#include "console/engineAPI.h" 29#include "gui/containers/guiScrollCtrl.h" 30#include "gfx/gfxDrawUtil.h" 31#include "gui/core/guiDefaultControlRender.h" 32 33 34IMPLEMENT_CONOBJECT(GuiArrayCtrl); 35 36ConsoleDocClass( GuiArrayCtrl, 37 "@brief Abstract base class for controls that store and display multiple elements in a single view.\n\n" 38 39 "You cannot actually instantiate this class. Instead you can use its childre:\n\n" 40 41 "- GuiConsole\n" 42 "- GuiTextListCtrl\n" 43 "- GuiTreeViewCtrl\n" 44 "- DbgFileView\n" 45 "- CreatorTree\n" 46 47 "This base class is primarily used by other internal classes or those dedicated to editors.\n\n" 48 49 "@ingroup GuiCore\n" 50 51 "@internal" 52); 53 54IMPLEMENT_CALLBACK( GuiArrayCtrl, onCellSelected, void, ( const Point2I& cell ), ( cell ), 55 "Call when a cell in the array is selected (clicked).\n\n" 56 "@param @cell Coordinates of the cell" 57); 58IMPLEMENT_CALLBACK( GuiArrayCtrl, onCellHighlighted, void, ( const Point2I& cell ), ( cell ), 59 "Call when a cell in the array is highlighted (moused over).\n\n" 60 "@param @cell Coordinates of the cell" 61); 62 63//----------------------------------------------------------------------------- 64 65GuiArrayCtrl::GuiArrayCtrl() 66{ 67 mActive = true; 68 69 mCellSize.set(80, 30); 70 mSize = Point2I(5, 30); 71 mSelectedCell.set(-1, -1); 72 mMouseOverCell.set(-1, -1); 73 mHeaderDim.set(0, 0); 74 mIsContainer = true; 75} 76 77//----------------------------------------------------------------------------- 78 79bool GuiArrayCtrl::onWake() 80{ 81 if (! Parent::onWake()) 82 return false; 83 84 //get the font 85 mFont = mProfile->mFont; 86 87 return true; 88} 89 90//----------------------------------------------------------------------------- 91 92void GuiArrayCtrl::onSleep() 93{ 94 Parent::onSleep(); 95 mFont = NULL; 96} 97 98//----------------------------------------------------------------------------- 99 100void GuiArrayCtrl::setSize(Point2I newSize) 101{ 102 mSize = newSize; 103 Point2I newExtent(newSize.x * mCellSize.x + mHeaderDim.x, newSize.y * mCellSize.y + mHeaderDim.y); 104 105 setExtent(newExtent); 106} 107 108//----------------------------------------------------------------------------- 109 110void GuiArrayCtrl::getScrollDimensions(S32 &cell_size, S32 &num_cells) 111{ 112 cell_size = mCellSize.y; 113 num_cells = mSize.y; 114} 115 116//----------------------------------------------------------------------------- 117 118bool GuiArrayCtrl::cellSelected(Point2I cell) 119{ 120 if (cell.x < 0 || cell.x >= mSize.x || cell.y < 0 || cell.y >= mSize.y) 121 { 122 mSelectedCell = Point2I(-1,-1); 123 return false; 124 } 125 126 mSelectedCell = cell; 127 scrollSelectionVisible(); 128 onCellSelected(cell); 129 setUpdate(); 130 return true; 131} 132 133//----------------------------------------------------------------------------- 134 135void GuiArrayCtrl::onCellSelected(Point2I cell) 136{ 137 // [rene, 21-Jan-11 ] clashes with callbacks defined in derived classes 138 Con::executef(this, "onSelect", Con::getFloatArg(cell.x), Con::getFloatArg(cell.y)); 139 140 onCellSelected_callback( cell ); 141 142 //call the console function 143 execConsoleCallback(); 144} 145 146//----------------------------------------------------------------------------- 147 148void GuiArrayCtrl::onCellHighlighted(Point2I cell) 149{ 150 onCellHighlighted_callback( cell ); 151} 152 153//----------------------------------------------------------------------------- 154 155void GuiArrayCtrl::setSelectedCell(Point2I cell) 156{ 157 cellSelected(cell); 158} 159 160//----------------------------------------------------------------------------- 161 162Point2I GuiArrayCtrl::getSelectedCell() 163{ 164 return mSelectedCell; 165} 166 167//----------------------------------------------------------------------------- 168 169void GuiArrayCtrl::scrollSelectionVisible() 170{ 171 scrollCellVisible(mSelectedCell); 172} 173 174//----------------------------------------------------------------------------- 175 176void GuiArrayCtrl::scrollCellVisible(Point2I cell) 177{ 178 //make sure we have a parent 179 //make sure we have a valid cell selected 180 GuiScrollCtrl *parent = dynamic_cast<GuiScrollCtrl*>(getParent()); 181 if(!parent || cell.x < 0 || cell.y < 0) 182 return; 183 184 RectI cellBounds(cell.x * mCellSize.x, cell.y * mCellSize.y, mCellSize.x, mCellSize.y); 185 parent->scrollRectVisible(cellBounds); 186} 187 188//----------------------------------------------------------------------------- 189 190void GuiArrayCtrl::onRenderColumnHeaders(Point2I offset, Point2I parentOffset, Point2I headerDim) 191{ 192 if (mProfile->mBorder) 193 { 194 RectI cellR(offset.x + headerDim.x, parentOffset.y, getWidth() - headerDim.x, headerDim.y); 195 GFX->getDrawUtil()->drawRectFill(cellR, mProfile->mBorderColor); 196 } 197} 198 199//----------------------------------------------------------------------------- 200 201void GuiArrayCtrl::onRenderRowHeader(Point2I offset, Point2I parentOffset, Point2I headerDim, Point2I cell) 202{ 203 ColorI color; 204 RectI cellR; 205 if (cell.x % 2) 206 color.set(255, 0, 0, 255); 207 else 208 color.set(0, 255, 0, 255); 209 210 cellR.point.set(parentOffset.x, offset.y); 211 cellR.extent.set(headerDim.x, mCellSize.y); 212 GFX->getDrawUtil()->drawRectFill(cellR, color); 213} 214 215//----------------------------------------------------------------------------- 216 217void GuiArrayCtrl::onRenderCell(Point2I offset, Point2I cell, bool selected, bool mouseOver) 218{ 219 ColorI color(255 * (cell.x % 2), 255 * (cell.y % 2), 255 * ((cell.x + cell.y) % 2), 255); 220 if (selected) 221 { 222 color.set(255, 0, 0, 255); 223 } 224 else if (mouseOver) 225 { 226 color.set(0, 0, 255, 255); 227 } 228 229 //draw the cell 230 RectI cellR(offset.x, offset.y, mCellSize.x, mCellSize.y); 231 GFX->getDrawUtil()->drawRectFill(cellR, color); 232} 233 234//----------------------------------------------------------------------------- 235 236void GuiArrayCtrl::onRender(Point2I offset, const RectI &updateRect) 237{ 238 // The unmodified offset which was passed into this method. 239 const Point2I inOffset( offset ); 240 241 //Parent::onRender( offset, updateRect ); 242 243 // We render our fill, borders, and child controls ourself. 244 // This allows us to render child controls after we render cells, 245 // so child controls appear on-top, as they should. 246 247 // Render our fill and borders. 248 // This code from GuiControl::onRender(). 249 { 250 RectI ctrlRect(offset, getExtent()); 251 252 //if opaque, fill the update rect with the fill color 253 if ( mProfile->mOpaque ) 254 GFX->getDrawUtil()->drawRectFill(ctrlRect, mProfile->mFillColor); 255 256 //if there's a border, draw the border 257 if ( mProfile->mBorder ) 258 renderBorder(ctrlRect, mProfile); 259 } 260 261 //make sure we have a parent 262 GuiControl *parent = getParent(); 263 if (! parent) 264 return; 265 266 S32 i, j; 267 RectI headerClip; 268 RectI clipRect(updateRect.point, updateRect.extent); 269 270 Point2I parentOffset = parent->localToGlobalCoord(Point2I(0, 0)); 271 272 //if we have column headings 273 if (mHeaderDim.y > 0) 274 { 275 headerClip.point.x = parentOffset.x + mHeaderDim.x; 276 headerClip.point.y = parentOffset.y; 277 headerClip.extent.x = clipRect.extent.x;// - headerClip.point.x; // This seems to fix some strange problems with some Gui's, bug? -pw 278 headerClip.extent.y = mHeaderDim.y; 279 280 if (headerClip.intersect(clipRect)) 281 { 282 GFX->setClipRect(headerClip); 283 284 //now render the header 285 onRenderColumnHeaders(offset, parentOffset, mHeaderDim); 286 287 clipRect.point.y += headerClip.extent.y; 288 clipRect.extent.y -= headerClip.extent.y; 289 } 290 offset.y += mHeaderDim.y; 291 } 292 293 //if we have row headings 294 if (mHeaderDim.x > 0) 295 { 296 clipRect.point.x = getMax(clipRect.point.x, parentOffset.x + mHeaderDim.x); 297 offset.x += mHeaderDim.x; 298 } 299 300 //save the original for clipping the row headers 301 RectI origClipRect = clipRect; 302 303 for (j = 0; j < mSize.y; j++) 304 { 305 //skip until we get to a visible row 306 if ((j + 1) * mCellSize.y + offset.y < updateRect.point.y) 307 continue; 308 309 //break once we've reached the last visible row 310 if(j * mCellSize.y + offset.y >= updateRect.point.y + updateRect.extent.y) 311 break; 312 313 //render the header 314 if (mHeaderDim.x > 0) 315 { 316 headerClip.point.x = parentOffset.x; 317 headerClip.extent.x = mHeaderDim.x; 318 headerClip.point.y = offset.y + j * mCellSize.y; 319 headerClip.extent.y = mCellSize.y; 320 if (headerClip.intersect(origClipRect)) 321 { 322 GFX->setClipRect(headerClip); 323 324 //render the row header 325 onRenderRowHeader(Point2I(0, offset.y + j * mCellSize.y), 326 Point2I(parentOffset.x, offset.y + j * mCellSize.y), 327 mHeaderDim, Point2I(0, j)); 328 } 329 } 330 331 //render the cells for the row 332 for (i = 0; i < mSize.x; i++) 333 { 334 //skip past columns off the left edge 335 if ((i + 1) * mCellSize.x + offset.x < updateRect.point.x) 336 continue; 337 338 //break once past the last visible column 339 if (i * mCellSize.x + offset.x >= updateRect.point.x + updateRect.extent.x) 340 break; 341 342 S32 cellx = offset.x + i * mCellSize.x; 343 S32 celly = offset.y + j * mCellSize.y; 344 345 RectI cellClip(cellx, celly, mCellSize.x, mCellSize.y); 346 347 //make sure the cell is within the update region 348 if (cellClip.intersect(clipRect)) 349 { 350 //set the clip rect 351 GFX->setClipRect(cellClip); 352 353 //render the cell 354 onRenderCell(Point2I(cellx, celly), Point2I(i, j), 355 i == mSelectedCell.x && j == mSelectedCell.y, 356 i == mMouseOverCell.x && j == mMouseOverCell.y); 357 } 358 } 359 } 360 361 // Done rendering cells. 362 // Render child controls, if any, on top. 363 renderChildControls( inOffset, updateRect ); 364} 365 366//----------------------------------------------------------------------------- 367 368void GuiArrayCtrl::onMouseDown( const GuiEvent &event ) 369{ 370 if ( !mActive || !mAwake || !mVisible ) 371 return; 372} 373 374//----------------------------------------------------------------------------- 375 376void GuiArrayCtrl::onMouseUp( const GuiEvent &event ) 377{ 378 if ( !mActive || !mAwake || !mVisible ) 379 return; 380 381 //let the guiControl method take care of the rest 382 Parent::onMouseUp(event); 383 384 Point2I pt = globalToLocalCoord(event.mousePoint); 385 pt.x -= mHeaderDim.x; pt.y -= mHeaderDim.y; 386 Point2I cell( 387 (pt.x < 0 ? -1 : pt.x / mCellSize.x), 388 (pt.y < 0 ? -1 : pt.y / mCellSize.y) 389 ); 390 391 if (cell.x >= 0 && cell.x < mSize.x && cell.y >= 0 && cell.y < mSize.y) 392 { 393 //store the previously selected cell 394 Point2I prevSelected = mSelectedCell; 395 396 //select the new cell 397 cellSelected(Point2I(cell.x, cell.y)); 398 399 //if we double clicked on the *same* cell, evaluate the altConsole Command 400 if ( ( event.mouseClickCount > 1 ) && ( prevSelected == mSelectedCell ) ) 401 execAltConsoleCallback(); 402 } 403} 404 405//----------------------------------------------------------------------------- 406 407void GuiArrayCtrl::onMouseEnter(const GuiEvent &event) 408{ 409 Point2I pt = globalToLocalCoord(event.mousePoint); 410 pt.x -= mHeaderDim.x; pt.y -= mHeaderDim.y; 411 412 //get the cell 413 Point2I cell((pt.x < 0 ? -1 : pt.x / mCellSize.x), (pt.y < 0 ? -1 : pt.y / mCellSize.y)); 414 if (cell.x >= 0 && cell.x < mSize.x && cell.y >= 0 && cell.y < mSize.y) 415 { 416 mMouseOverCell = cell; 417 setUpdateRegion(Point2I(cell.x * mCellSize.x + mHeaderDim.x, 418 cell.y * mCellSize.y + mHeaderDim.y), mCellSize ); 419 onCellHighlighted(mMouseOverCell); 420 } 421} 422 423//----------------------------------------------------------------------------- 424 425void GuiArrayCtrl::onMouseLeave(const GuiEvent & /*event*/) 426{ 427 setUpdateRegion(Point2I(mMouseOverCell.x * mCellSize.x + mHeaderDim.x, 428 mMouseOverCell.y * mCellSize.y + mHeaderDim.y), mCellSize); 429 mMouseOverCell.set(-1,-1); 430 onCellHighlighted(mMouseOverCell); 431} 432 433//----------------------------------------------------------------------------- 434 435void GuiArrayCtrl::onMouseDragged(const GuiEvent &event) 436{ 437 // for the array control, the behavior of onMouseDragged is the same 438 // as on mouse moved - basically just recalc the current mouse over cell 439 // and set the update regions if necessary 440 GuiArrayCtrl::onMouseMove(event); 441} 442 443//----------------------------------------------------------------------------- 444 445void GuiArrayCtrl::onMouseMove(const GuiEvent &event) 446{ 447 Point2I pt = globalToLocalCoord(event.mousePoint); 448 pt.x -= mHeaderDim.x; pt.y -= mHeaderDim.y; 449 Point2I cell((pt.x < 0 ? -1 : pt.x / mCellSize.x), (pt.y < 0 ? -1 : pt.y / mCellSize.y)); 450 if (cell.x != mMouseOverCell.x || cell.y != mMouseOverCell.y) 451 { 452 if (mMouseOverCell.x != -1) 453 { 454 setUpdateRegion(Point2I(mMouseOverCell.x * mCellSize.x + mHeaderDim.x, 455 mMouseOverCell.y * mCellSize.y + mHeaderDim.y), mCellSize); 456 } 457 458 if (cell.x >= 0 && cell.x < mSize.x && cell.y >= 0 && cell.y < mSize.y) 459 { 460 setUpdateRegion(Point2I(cell.x * mCellSize.x + mHeaderDim.x, 461 cell.y * mCellSize.y + mHeaderDim.y), mCellSize); 462 mMouseOverCell = cell; 463 } 464 else 465 mMouseOverCell.set(-1,-1); 466 } 467 onCellHighlighted(mMouseOverCell); 468} 469 470//----------------------------------------------------------------------------- 471 472bool GuiArrayCtrl::onKeyDown(const GuiEvent &event) 473{ 474 //if this control is a dead end, kill the event 475 if ((! mVisible) || (! mActive) || (! mAwake)) return true; 476 477 //get the parent 478 S32 pageSize = 1; 479 GuiControl *parent = getParent(); 480 if (parent && mCellSize.y > 0) 481 { 482 pageSize = getMax(1, (parent->getHeight() / mCellSize.y) - 1); 483 } 484 485 Point2I delta(0,0); 486 switch (event.keyCode) 487 { 488 case KEY_LEFT: 489 delta.set(-1, 0); 490 break; 491 case KEY_RIGHT: 492 delta.set(1, 0); 493 break; 494 case KEY_UP: 495 delta.set(0, -1); 496 break; 497 case KEY_DOWN: 498 delta.set(0, 1); 499 break; 500 case KEY_PAGE_UP: 501 delta.set(0, -pageSize); 502 break; 503 case KEY_PAGE_DOWN: 504 delta.set(0, pageSize); 505 break; 506 case KEY_HOME: 507 cellSelected( Point2I( 0, 0 ) ); 508 return( true ); 509 case KEY_END: 510 cellSelected( Point2I( 0, mSize.y - 1 ) ); 511 return( true ); 512 default: 513 return Parent::onKeyDown(event); 514 } 515 if (mSize.x < 1 || mSize.y < 1) 516 return true; 517 518 //select the first cell if no previous cell was selected 519 if (mSelectedCell.x == -1 || mSelectedCell.y == -1) 520 { 521 cellSelected(Point2I(0,0)); 522 return true; 523 } 524 525 //select the cell 526 Point2I cell = mSelectedCell; 527 cell.x = getMax(0, getMin(mSize.x - 1, cell.x + delta.x)); 528 cell.y = getMax(0, getMin(mSize.y - 1, cell.y + delta.y)); 529 cellSelected(cell); 530 531 return true; 532} 533 534//----------------------------------------------------------------------------- 535 536void GuiArrayCtrl::onRightMouseDown(const GuiEvent &event) 537{ 538 if ( !mActive || !mAwake || !mVisible ) 539 return; 540 541 Parent::onRightMouseDown( event ); 542 543 Point2I cell; 544 if( _findHitCell( event.mousePoint, cell ) ) 545 { 546 char buf[32]; 547 dSprintf( buf, sizeof( buf ), "%d %d", event.mousePoint.x, event.mousePoint.y ); 548 549 // [rene, 21-Jan-11 ] clashes with callbacks defined in derived classes 550 551 // Pass it to the console: 552 Con::executef(this, "onRightMouseDown", Con::getIntArg(cell.x), Con::getIntArg(cell.y), buf); 553 } 554} 555 556//----------------------------------------------------------------------------- 557 558bool GuiArrayCtrl::_findHitCell( const Point2I& pos, Point2I& cellOut ) 559{ 560 Point2I pt = globalToLocalCoord( pos ); 561 pt.x -= mHeaderDim.x; pt.y -= mHeaderDim.y; 562 Point2I cell( ( pt.x < 0 ? -1 : pt.x / mCellSize.x ), ( pt.y < 0 ? -1 : pt.y / mCellSize.y ) ); 563 if( cell.x >= 0 && cell.x < mSize.x && cell.y >= 0 && cell.y < mSize.y ) 564 { 565 cellOut = cell; 566 return true; 567 } 568 569 return false; 570} 571