|
MythTV
0.26-pre
|
00001 /* TokenGroup.cpp 00002 00003 Copyright (C) David C. J. Matthews 2004 dm at prolingua.co.uk 00004 00005 This program is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU General Public License 00007 as published by the Free Software Foundation; either version 2 00008 of the License, or (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 Or, point your browser to http://www.gnu.org/copyleft/gpl.html 00019 00020 */ 00021 00022 00023 #include "TokenGroup.h" 00024 #include "Presentable.h" 00025 #include "Ingredients.h" 00026 #include "Root.h" 00027 #include "BaseClasses.h" 00028 #include "ParseNode.h" 00029 #include "ASN1Codes.h" 00030 #include "Engine.h" 00031 00032 void MHTokenGroupItem::Initialise(MHParseNode *p, MHEngine *engine) 00033 { 00034 // A pair consisting of an object reference and an optional action slot sequence. 00035 m_Object.Initialise(p->GetSeqN(0), engine); 00036 00037 if (p->GetSeqCount() > 1) 00038 { 00039 MHParseNode *pSlots = p->GetSeqN(1); 00040 00041 for (int i = 0; i < pSlots->GetSeqCount(); i++) 00042 { 00043 MHParseNode *pAct = pSlots->GetSeqN(i); 00044 MHActionSequence *pActions = new MHActionSequence; 00045 m_ActionSlots.Append(pActions); 00046 00047 // The action slot entry may be NULL. 00048 if (pAct->m_nNodeType != MHParseNode::PNNull) 00049 { 00050 pActions->Initialise(pAct, engine); 00051 } 00052 } 00053 } 00054 } 00055 00056 void MHTokenGroupItem::PrintMe(FILE *fd, int nTabs) const 00057 { 00058 PrintTabs(fd, nTabs); 00059 fprintf(fd, "( "); 00060 m_Object.PrintMe(fd, nTabs + 1); 00061 fprintf(fd, "\n"); 00062 00063 if (m_ActionSlots.Size() != 0) 00064 { 00065 PrintTabs(fd, nTabs + 1); 00066 fprintf(fd, ":ActionSlots (\n"); 00067 00068 for (int i = 0; i < m_ActionSlots.Size(); i++) 00069 { 00070 PrintTabs(fd, nTabs + 2); 00071 fprintf(fd, "(\n"); 00072 MHActionSequence *pActions = m_ActionSlots.GetAt(i); 00073 00074 if (pActions->Size() == 0) 00075 { 00076 PrintTabs(fd, nTabs + 2); 00077 fprintf(fd, "NULL\n"); 00078 } 00079 else 00080 { 00081 pActions->PrintMe(fd, nTabs + 2); 00082 } 00083 00084 PrintTabs(fd, nTabs + 2); 00085 fprintf(fd, ")\n"); 00086 } 00087 00088 PrintTabs(fd, nTabs + 1); 00089 fprintf(fd, ")\n"); 00090 } 00091 00092 PrintTabs(fd, nTabs); 00093 fprintf(fd, ")\n"); 00094 } 00095 00096 void MHMovement::Initialise(MHParseNode *p, MHEngine * /*engine*/) 00097 { 00098 for (int i = 0; i < p->GetSeqCount(); i++) 00099 { 00100 m_Movement.Append(p->GetSeqN(i)->GetIntValue()); 00101 } 00102 } 00103 00104 void MHMovement::PrintMe(FILE *fd, int nTabs) const 00105 { 00106 PrintTabs(fd, nTabs); 00107 fprintf(fd, "( "); 00108 00109 for (int i = 0; i < m_Movement.Size(); i++) 00110 { 00111 fprintf(fd, "%d ", m_Movement.GetAt(i)); 00112 } 00113 00114 fprintf(fd, ")\n"); 00115 } 00116 00117 MHTokenGroup::MHTokenGroup() 00118 { 00119 m_nTokenPosition = 1; // Initial value 00120 } 00121 00122 void MHTokenGroup::Initialise(MHParseNode *p, MHEngine *engine) 00123 { 00124 MHPresentable::Initialise(p, engine); 00125 MHParseNode *pMovements = p->GetNamedArg(C_MOVEMENT_TABLE); 00126 00127 if (pMovements) 00128 { 00129 for (int i = 0; i < pMovements->GetArgCount(); i++) 00130 { 00131 MHMovement *pMove = new MHMovement; 00132 m_MovementTable.Append(pMove); 00133 pMove->Initialise(pMovements->GetArgN(i), engine); 00134 } 00135 } 00136 00137 MHParseNode *pTokenGrp = p->GetNamedArg(C_TOKEN_GROUP_ITEMS); 00138 00139 if (pTokenGrp) 00140 { 00141 for (int i = 0; i < pTokenGrp->GetArgCount(); i++) 00142 { 00143 MHTokenGroupItem *pToken = new MHTokenGroupItem; 00144 m_TokenGrpItems.Append(pToken); 00145 pToken->Initialise(pTokenGrp->GetArgN(i), engine); 00146 } 00147 } 00148 00149 MHParseNode *pNoToken = p->GetNamedArg(C_NO_TOKEN_ACTION_SLOTS); 00150 00151 if (pNoToken) 00152 { 00153 for (int i = 0; i < pNoToken->GetArgCount(); i++) 00154 { 00155 MHParseNode *pAct = pNoToken->GetArgN(i); 00156 MHActionSequence *pActions = new MHActionSequence; 00157 m_NoTokenActionSlots.Append(pActions); 00158 00159 // The action slot entry may be NULL. 00160 if (pAct->m_nNodeType != MHParseNode::PNNull) 00161 { 00162 pActions->Initialise(pAct, engine); 00163 } 00164 } 00165 } 00166 } 00167 00168 // This is used to print the contents of the token group. 00169 void MHTokenGroup::PrintContents(FILE *fd, int nTabs) const 00170 { 00171 MHPresentable::PrintMe(fd, nTabs + 1); 00172 00173 if (m_MovementTable.Size() != 0) 00174 { 00175 PrintTabs(fd, nTabs + 1); 00176 fprintf(fd, ":MovementTable (\n"); 00177 00178 for (int i = 0; i < m_MovementTable.Size(); i++) 00179 { 00180 m_MovementTable.GetAt(i)->PrintMe(fd, nTabs + 2); 00181 } 00182 00183 PrintTabs(fd, nTabs + 1); 00184 fprintf(fd, ")\n"); 00185 } 00186 00187 if (m_TokenGrpItems.Size() != 0) 00188 { 00189 PrintTabs(fd, nTabs + 1); 00190 fprintf(fd, ":TokenGroupItems (\n"); 00191 00192 for (int i = 0; i < m_TokenGrpItems.Size(); i++) 00193 { 00194 m_TokenGrpItems.GetAt(i)->PrintMe(fd, nTabs + 2); 00195 } 00196 00197 PrintTabs(fd, nTabs + 1); 00198 fprintf(fd, ")\n"); 00199 } 00200 00201 if (m_NoTokenActionSlots.Size() != 0) 00202 { 00203 PrintTabs(fd, nTabs + 1); 00204 fprintf(fd, ":NoTokenActionSlots (\n"); 00205 00206 for (int i = 0; i < m_NoTokenActionSlots.Size(); i++) 00207 { 00208 MHActionSequence *pActions = m_NoTokenActionSlots.GetAt(i); 00209 00210 if (pActions->Size() == 0) 00211 { 00212 PrintTabs(fd, nTabs + 2); 00213 fprintf(fd, "NULL "); 00214 } 00215 else 00216 { 00217 pActions->PrintMe(fd, nTabs + 2); 00218 } 00219 } 00220 00221 PrintTabs(fd, nTabs + 1); 00222 fprintf(fd, ")\n"); 00223 } 00224 00225 } 00226 00227 void MHTokenGroup::PrintMe(FILE *fd, int nTabs) const 00228 { 00229 PrintTabs(fd, nTabs); 00230 fprintf(fd, "{:TokenGroup "); 00231 PrintContents(fd, nTabs); 00232 PrintTabs(fd, nTabs); 00233 fprintf(fd, "}\n"); 00234 } 00235 00236 // Activate the token group following the standard. 00237 void MHTokenGroup::Activation(MHEngine *engine) 00238 { 00239 if (m_fRunning) 00240 { 00241 return; 00242 } 00243 00244 MHPresentable::Activation(engine); 00245 00246 // We're supposed to apply Activation to each of the "items" but it isn't clear 00247 // exactly what that means. Assume it means each of the visibles. 00248 for (int i = 0; i < m_TokenGrpItems.Size(); i++) 00249 { 00250 MHObjectRef *pObject = &m_TokenGrpItems.GetAt(i)->m_Object; 00251 00252 // The object reference may be the null reference. 00253 // Worse: it seems that sometimes in BBC's MHEG the reference simply doesn't exist. 00254 if (pObject->IsSet()) 00255 { 00256 try 00257 { 00258 engine->FindObject(m_TokenGrpItems.GetAt(i)->m_Object)->Activation(engine); 00259 } 00260 catch (char const *) {} 00261 } 00262 } 00263 00264 engine->EventTriggered(this, EventTokenMovedTo, m_nTokenPosition); 00265 m_fRunning = true; 00266 engine->EventTriggered(this, EventIsRunning); 00267 } 00268 00269 void MHTokenGroup::Deactivation(MHEngine *engine) 00270 { 00271 if (! m_fRunning) 00272 { 00273 return; 00274 } 00275 00276 engine->EventTriggered(this, EventTokenMovedFrom, m_nTokenPosition); 00277 MHPresentable::Deactivation(engine); 00278 } 00279 00280 // Internal function to generate the appropriate events. 00281 void MHTokenGroup::TransferToken(int newPos, MHEngine *engine) 00282 { 00283 if (newPos != m_nTokenPosition) 00284 { 00285 engine->EventTriggered(this, EventTokenMovedFrom, m_nTokenPosition); 00286 m_nTokenPosition = newPos; 00287 engine->EventTriggered(this, EventTokenMovedTo, m_nTokenPosition); 00288 } 00289 } 00290 00291 // Perform the actions depending on where the token is. 00292 void MHTokenGroup::CallActionSlot(int n, MHEngine *engine) 00293 { 00294 if (m_nTokenPosition == 0) // No slot has the token. 00295 { 00296 if (n > 0 && n <= m_NoTokenActionSlots.Size()) 00297 { 00298 engine->AddActions(*(m_NoTokenActionSlots.GetAt(n - 1))); 00299 } 00300 } 00301 else 00302 { 00303 if (m_nTokenPosition > 0 && m_nTokenPosition <= m_TokenGrpItems.Size()) 00304 { 00305 MHTokenGroupItem *pGroup = m_TokenGrpItems.GetAt(m_nTokenPosition - 1); 00306 00307 if (n > 0 && n <= pGroup->m_ActionSlots.Size()) 00308 { 00309 engine->AddActions(*(pGroup->m_ActionSlots.GetAt(n - 1))); 00310 } 00311 } 00312 } 00313 } 00314 00315 void MHTokenGroup::Move(int n, MHEngine *engine) 00316 { 00317 if (m_nTokenPosition == 0 || n < 1 || n > m_MovementTable.Size()) 00318 { 00319 TransferToken(0, engine); // Not in the standard 00320 } 00321 else 00322 { 00323 TransferToken(m_MovementTable.GetAt(n - 1)->m_Movement.GetAt(m_nTokenPosition - 1), engine); 00324 } 00325 } 00326 00327 // ListGroup. This is a complex class and the description was extensively revised in the MHEG corrigendum. 00328 // It doesn't seem to be used a great deal in practice and quite a few of the actions haven't been tested. 00329 00330 MHListGroup::MHListGroup() 00331 { 00332 m_fWrapAround = false; 00333 m_fMultipleSelection = false; 00334 m_nFirstItem = 1; 00335 m_nLastFirstItem = m_nFirstItem; 00336 m_nLastCount = 0; 00337 } 00338 MHListGroup::~MHListGroup() 00339 { 00340 while (!m_ItemList.isEmpty()) 00341 { 00342 delete m_ItemList.takeFirst(); 00343 } 00344 } 00345 00346 void MHListGroup::Initialise(MHParseNode *p, MHEngine *engine) 00347 { 00348 MHTokenGroup::Initialise(p, engine); 00349 MHParseNode *pPositions = p->GetNamedArg(C_POSITIONS); 00350 00351 if (pPositions) 00352 { 00353 for (int i = 0; i < pPositions->GetArgCount(); i++) 00354 { 00355 MHParseNode *pPos = pPositions->GetArgN(i); 00356 QPoint pos(pPos->GetSeqN(0)->GetIntValue(), pPos->GetSeqN(1)->GetIntValue()); 00357 m_Positions.Append(pos); 00358 } 00359 } 00360 00361 MHParseNode *pWrap = p->GetNamedArg(C_WRAP_AROUND); 00362 00363 if (pWrap) 00364 { 00365 m_fWrapAround = pWrap->GetArgN(0)->GetBoolValue(); 00366 } 00367 00368 MHParseNode *pMultiple = p->GetNamedArg(C_WRAP_AROUND); 00369 00370 if (pMultiple) 00371 { 00372 m_fMultipleSelection = pMultiple->GetArgN(0)->GetBoolValue(); 00373 } 00374 } 00375 00376 void MHListGroup::PrintMe(FILE *fd, int nTabs) const 00377 { 00378 PrintTabs(fd, nTabs); 00379 fprintf(fd, "{:ListGroup "); 00380 MHTokenGroup::PrintContents(fd, nTabs); 00381 PrintTabs(fd, nTabs + 1); 00382 fprintf(fd, ":Positions ("); 00383 00384 for (int i = 0; i < m_Positions.Size(); i++) 00385 { 00386 fprintf(fd, " ( %d %d )", m_Positions.GetAt(i).x(), m_Positions.GetAt(i).y()); 00387 } 00388 00389 fprintf(fd, ")\n"); 00390 00391 if (m_fWrapAround) 00392 { 00393 PrintTabs(fd, nTabs + 1); 00394 fprintf(fd, ":WrapAround true\n"); 00395 } 00396 00397 if (m_fMultipleSelection) 00398 { 00399 PrintTabs(fd, nTabs + 1); 00400 fprintf(fd, ":MultipleSelection true\n"); 00401 } 00402 00403 PrintTabs(fd, nTabs); 00404 fprintf(fd, "}\n"); 00405 } 00406 00407 void MHListGroup::Preparation(MHEngine *engine) 00408 { 00409 MHTokenGroup::Preparation(engine); 00410 00411 for (int i = 0; i < m_TokenGrpItems.Size(); i++) 00412 { 00413 // Find the item and add it to the list if it isn't already there. 00414 try 00415 { 00416 MHRoot *pItem = (MHRoot *)engine->FindObject(m_TokenGrpItems.GetAt(i)->m_Object); 00417 MHListItem *p = 0; 00418 QList<MHListItem *>::iterator it = m_ItemList.begin(); 00419 00420 for (; it != m_ItemList.end(); ++it) 00421 { 00422 p = *it; 00423 00424 if (p->m_pVisible == pItem) 00425 { 00426 break; 00427 } 00428 } 00429 00430 if (!p) 00431 { 00432 m_ItemList.append(new MHListItem(pItem)); 00433 } 00434 } 00435 catch (...) // Ignore invalid or null objects. 00436 { 00437 } 00438 } 00439 } 00440 00441 void MHListGroup::Destruction(MHEngine *engine) 00442 { 00443 // Reset the positions of the visibles. 00444 for (int j = 0; j < m_ItemList.size(); j++) 00445 { 00446 m_ItemList.at(j)->m_pVisible->ResetPosition(); 00447 } 00448 00449 MHTokenGroup::Destruction(engine); 00450 } 00451 00452 void MHListGroup::Activation(MHEngine *engine) 00453 { 00454 m_fFirstItemDisplayed = m_fLastItemDisplayed = false; 00455 MHTokenGroup::Activation(engine); 00456 Update(engine); 00457 } 00458 00459 00460 void MHListGroup::Deactivation(MHEngine *engine) 00461 { 00462 // Deactivate the visibles. 00463 for (int j = 0; j < m_ItemList.size(); j++) 00464 { 00465 m_ItemList.at(j)->m_pVisible->Deactivation(engine); 00466 } 00467 00468 MHTokenGroup::Deactivation(engine); 00469 } 00470 00471 // Update action - set the position of the cells to be displayed and deactivate those 00472 // which aren't. 00473 void MHListGroup::Update(MHEngine *engine) 00474 { 00475 if (!m_ItemList.size()) // Special cases when the list becomes empty 00476 { 00477 if (m_fFirstItemDisplayed) 00478 { 00479 m_fFirstItemDisplayed = false; 00480 engine->EventTriggered(this, EventFirstItemPresented, false); 00481 } 00482 00483 if (m_fLastItemDisplayed) 00484 { 00485 m_fLastItemDisplayed = false; 00486 engine->EventTriggered(this, EventLastItemPresented, false); 00487 } 00488 } 00489 else // Usual case. 00490 { 00491 for (int i = 0; i < m_ItemList.size(); i++) 00492 { 00493 MHRoot *pVis = m_ItemList.at(i)->m_pVisible; 00494 int nCell = i + 1 - m_nFirstItem; // Which cell does this item map onto? 00495 00496 if (nCell >= 0 && nCell < m_Positions.Size()) 00497 { 00498 if (i == 0 && ! m_fFirstItemDisplayed) 00499 { 00500 m_fFirstItemDisplayed = true; 00501 engine->EventTriggered(this, EventFirstItemPresented, true); 00502 } 00503 00504 if (i == m_ItemList.size() - 1 && ! m_fLastItemDisplayed) 00505 { 00506 m_fLastItemDisplayed = true; 00507 engine->EventTriggered(this, EventLastItemPresented, true); 00508 } 00509 00510 try 00511 { 00512 pVis->SetPosition(m_Positions.GetAt(i - m_nFirstItem + 1).x(), m_Positions.GetAt(i - m_nFirstItem + 1).y(), engine); 00513 } 00514 catch (...) {} 00515 00516 if (! pVis->GetRunningStatus()) 00517 { 00518 pVis->Activation(engine); 00519 } 00520 } 00521 else 00522 { 00523 if (i == 0 && m_fFirstItemDisplayed) 00524 { 00525 m_fFirstItemDisplayed = false; 00526 engine->EventTriggered(this, EventFirstItemPresented, false); 00527 } 00528 00529 if (i == m_ItemList.size() - 1 && m_fLastItemDisplayed) 00530 { 00531 m_fLastItemDisplayed = false; 00532 engine->EventTriggered(this, EventLastItemPresented, false); 00533 } 00534 00535 if (pVis->GetRunningStatus()) 00536 { 00537 pVis->Deactivation(engine); 00538 pVis->ResetPosition(); 00539 } 00540 } 00541 } 00542 } 00543 00544 // Generate the HeadItems and TailItems events. Even in the MHEG corrigendum this is unclear. 00545 // I'm not at all sure this is right. 00546 if (m_nLastFirstItem != m_nFirstItem) 00547 { 00548 engine->EventTriggered(this, EventHeadItems, m_nFirstItem); 00549 } 00550 00551 if (m_nLastCount - m_nLastFirstItem != m_ItemList.size() - m_nFirstItem) 00552 { 00553 engine->EventTriggered(this, EventTailItems, m_ItemList.size() - m_nFirstItem); 00554 } 00555 00556 m_nLastCount = m_ItemList.size(); 00557 m_nLastFirstItem = m_nFirstItem; 00558 } 00559 00560 // Add an item to the list 00561 void MHListGroup::AddItem(int nIndex, MHRoot *pItem, MHEngine *engine) 00562 { 00563 // See if the item is already there and ignore this if it is. 00564 QList<MHListItem *>::iterator it = m_ItemList.begin(); 00565 00566 for (; it != m_ItemList.end(); ++it) 00567 { 00568 if ((*it)->m_pVisible == pItem) 00569 { 00570 return; 00571 } 00572 } 00573 00574 // Ignore this if the index is out of range 00575 if (nIndex < 1 || nIndex > m_ItemList.size() + 1) 00576 { 00577 return; 00578 } 00579 00580 // Insert it at the appropriate position (MHEG indexes count from 1). 00581 m_ItemList.insert(nIndex - 1, new MHListItem(pItem)); 00582 00583 if (nIndex <= m_nFirstItem && m_nFirstItem < m_ItemList.size()) 00584 { 00585 m_nFirstItem++; 00586 } 00587 00588 Update(engine); // Apply the update behaviour 00589 } 00590 00591 // Remove an item from the list 00592 void MHListGroup::DelItem(MHRoot *pItem, MHEngine *) 00593 { 00594 // See if the item is already there and ignore this if it is. 00595 for (int i = 0; i < m_ItemList.size(); i++) 00596 { 00597 if (m_ItemList.at(i)->m_pVisible == pItem) // Found it - remove it from the list and reset the posn. 00598 { 00599 delete m_ItemList.takeAt(i); 00600 pItem->ResetPosition(); 00601 00602 if (i + 1 < m_nFirstItem && m_nFirstItem > 1) 00603 { 00604 m_nFirstItem--; 00605 } 00606 00607 return; 00608 } 00609 } 00610 } 00611 00612 // Set the selection status of the item to true 00613 void MHListGroup::Select(int nIndex, MHEngine *engine) 00614 { 00615 MHListItem *pListItem = m_ItemList.at(nIndex - 1); 00616 00617 if (pListItem == 0 || pListItem->m_fSelected) 00618 { 00619 return; // Ignore if already selected. 00620 } 00621 00622 if (! m_fMultipleSelection) 00623 { 00624 // Deselect any existing selections. 00625 for (int i = 0; i < m_ItemList.size(); i++) 00626 if (m_ItemList.at(i)->m_fSelected) 00627 { 00628 Deselect(i + 1, engine); 00629 } 00630 } 00631 00632 pListItem->m_fSelected = true; 00633 engine->EventTriggered(this, EventItemSelected, nIndex); 00634 } 00635 00636 // Set the selection status of the item to false 00637 void MHListGroup::Deselect(int nIndex, MHEngine *engine) 00638 { 00639 MHListItem *pListItem = m_ItemList.at(nIndex - 1); 00640 00641 if (pListItem == 0 || ! pListItem->m_fSelected) 00642 { 00643 return; // Ignore if not selected. 00644 } 00645 00646 pListItem->m_fSelected = false; 00647 engine->EventTriggered(this, EventItemDeselected, nIndex); 00648 } 00649 00650 // Return the reference to the visible at the particular position. 00651 void MHListGroup::GetCellItem(int nCell, const MHObjectRef &itemDest, MHEngine *engine) 00652 { 00653 if (nCell < 1) 00654 { 00655 nCell = 1; // First cell 00656 } 00657 00658 if (nCell > m_Positions.Size()) 00659 { 00660 nCell = m_Positions.Size(); // Last cell. 00661 } 00662 00663 int nVisIndex = nCell + m_nFirstItem - 2; 00664 00665 if (nVisIndex >= 0 && nVisIndex < m_ItemList.size()) 00666 { 00667 MHRoot *pVis = m_ItemList.at(nVisIndex)->m_pVisible; 00668 engine->FindObject(itemDest)->SetVariableValue(pVis->m_ObjectReference); 00669 } 00670 else 00671 { 00672 engine->FindObject(itemDest)->SetVariableValue(MHObjectRef::Null); 00673 } 00674 } 00675 00676 int MHListGroup::AdjustIndex(int nIndex) // Added in the MHEG corrigendum 00677 { 00678 int nItems = m_ItemList.size(); 00679 00680 if (nItems == 0) 00681 { 00682 return 1; 00683 } 00684 00685 if (nIndex > nItems) 00686 { 00687 return ((nIndex - 1) % nItems) + 1; 00688 } 00689 else if (nIndex < 0) 00690 { 00691 return nItems - ((-nIndex) % nItems); 00692 } 00693 else 00694 { 00695 return nIndex; 00696 } 00697 } 00698 00699 void MHListGroup::GetListItem(int nCell, const MHObjectRef &itemDest, MHEngine *engine) 00700 { 00701 if (m_fWrapAround) 00702 { 00703 nCell = AdjustIndex(nCell); 00704 } 00705 00706 if (nCell < 1 || nCell > m_ItemList.size()) 00707 { 00708 return; // Ignore it if it's out of range and not wrapping 00709 } 00710 00711 engine->FindObject(itemDest)->SetVariableValue(m_ItemList.at(nCell - 1)->m_pVisible->m_ObjectReference); 00712 } 00713 00714 void MHListGroup::GetItemStatus(int nCell, const MHObjectRef &itemDest, MHEngine *engine) 00715 { 00716 if (m_fWrapAround) 00717 { 00718 nCell = AdjustIndex(nCell); 00719 } 00720 00721 if (nCell < 1 || nCell > m_ItemList.size()) 00722 { 00723 return; 00724 } 00725 00726 engine->FindObject(itemDest)->SetVariableValue(m_ItemList.at(nCell - 1)->m_fSelected); 00727 } 00728 00729 void MHListGroup::SelectItem(int nCell, MHEngine *engine) 00730 { 00731 if (m_fWrapAround) 00732 { 00733 nCell = AdjustIndex(nCell); 00734 } 00735 00736 if (nCell < 1 || nCell > m_ItemList.size()) 00737 { 00738 return; 00739 } 00740 00741 Select(nCell, engine); 00742 } 00743 00744 void MHListGroup::DeselectItem(int nCell, MHEngine *engine) 00745 { 00746 if (m_fWrapAround) 00747 { 00748 nCell = AdjustIndex(nCell); 00749 } 00750 00751 if (nCell < 1 || nCell > m_ItemList.size()) 00752 { 00753 return; 00754 } 00755 00756 Deselect(nCell, engine); 00757 } 00758 00759 void MHListGroup::ToggleItem(int nCell, MHEngine *engine) 00760 { 00761 if (m_fWrapAround) 00762 { 00763 nCell = AdjustIndex(nCell); 00764 } 00765 00766 if (nCell < 1 || nCell > m_ItemList.size()) 00767 { 00768 return; 00769 } 00770 00771 if (m_ItemList.at(nCell - 1)->m_fSelected) 00772 { 00773 Deselect(nCell, engine); 00774 } 00775 else 00776 { 00777 Select(nCell, engine); 00778 } 00779 } 00780 00781 void MHListGroup::ScrollItems(int nCell, MHEngine *engine) 00782 { 00783 nCell += m_nFirstItem; 00784 00785 if (m_fWrapAround) 00786 { 00787 nCell = AdjustIndex(nCell); 00788 } 00789 00790 if (nCell < 1 || nCell > m_ItemList.size()) 00791 { 00792 return; 00793 } 00794 00795 m_nFirstItem = nCell; 00796 Update(engine); 00797 } 00798 00799 void MHListGroup::SetFirstItem(int nCell, MHEngine *engine) 00800 { 00801 if (m_fWrapAround) 00802 { 00803 nCell = AdjustIndex(nCell); 00804 } 00805 00806 if (nCell < 1 || nCell > m_ItemList.size()) 00807 { 00808 return; 00809 } 00810 00811 m_nFirstItem = nCell; 00812 Update(engine); 00813 } 00814 00815 00816 00817 // Actions 00818 void MHAddItem::Initialise(MHParseNode *p, MHEngine *engine) 00819 { 00820 MHElemAction::Initialise(p, engine); 00821 m_Index.Initialise(p->GetArgN(1), engine); 00822 m_Item.Initialise(p->GetArgN(2), engine); 00823 } 00824 00825 void MHAddItem::PrintArgs(FILE *fd, int) const 00826 { 00827 m_Index.PrintMe(fd, 0); 00828 m_Item.PrintMe(fd, 0); 00829 } 00830 00831 void MHAddItem::Perform(MHEngine *engine) 00832 { 00833 MHObjectRef item; 00834 m_Item.GetValue(item, engine); 00835 Target(engine)->AddItem(m_Index.GetValue(engine), engine->FindObject(item), engine); 00836 } 00837 00838 void MHGetListActionData::Initialise(MHParseNode *p, MHEngine *engine) 00839 { 00840 MHElemAction::Initialise(p, engine); 00841 m_Index.Initialise(p->GetArgN(1), engine); 00842 m_Result.Initialise(p->GetArgN(2), engine); 00843 } 00844 00845 void MHGetListActionData::PrintArgs(FILE *fd, int) const 00846 { 00847 m_Index.PrintMe(fd, 0); 00848 m_Result.PrintMe(fd, 0); 00849 }
1.7.6.1