MythTV  master
Groups.cpp
Go to the documentation of this file.
1 /* Groups.cpp
2 
3  Copyright (C) David C. J. Matthews 2004 dm at prolingua.co.uk
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU General Public License
7  as published by the Free Software Foundation; either version 2
8  of the License, or (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18  Or, point your browser to http://www.gnu.org/copyleft/gpl.html
19 
20 */
21 
22 #include "Root.h"
23 #include "Groups.h"
24 #include "ASN1Codes.h"
25 #include "ParseNode.h"
26 #include "Ingredients.h"
27 #include "Programs.h"
28 #include "Variables.h"
29 #include "Presentable.h"
30 #include "Visible.h"
31 #include "Engine.h"
32 #include "Text.h"
33 #include "Bitmap.h"
34 #include "Stream.h"
35 #include "DynamicLineArt.h"
36 #include "Link.h"
37 #include "TokenGroup.h"
38 #include "Logging.h"
39 
41 {
42  while (!m_Timers.isEmpty())
43  {
44  delete m_Timers.takeFirst();
45  }
46 }
47 
49 {
50  engine->GetGroupId().Copy(""); // Set to empty before we start (just in case).
51  MHRoot::Initialise(p, engine);
52 
53  // Must be an external reference with an object number of zero.
55  {
56  MHERROR("Object reference for a group object must be zero and external");
57  }
58 
59  // Set the group id for the rest of the group to this.
61  // Some of the information is irrelevant.
62  // MHParseNode *pStdId = p->GetNamedArg(C_STANDARD_IDENTIFIER);
63  // MHParseNode *pStdVersion = p->GetNamedArg(C_STANDARD_VERSION);
64  // MHParseNode *pObjectInfo = p->GetNamedArg(C_OBJECT_INFORMATION);
65 
66  MHParseNode *pOnStartUp = p->GetNamedArg(C_ON_START_UP);
67 
68  if (pOnStartUp)
69  {
70  m_StartUp.Initialise(pOnStartUp, engine);
71  }
72 
73  MHParseNode *pOnCloseDown = p->GetNamedArg(C_ON_CLOSE_DOWN);
74 
75  if (pOnCloseDown)
76  {
77  m_CloseDown.Initialise(pOnCloseDown, engine);
78  }
79 
80  MHParseNode *pOriginalGCPrio = p->GetNamedArg(C_ORIGINAL_GC_PRIORITY);
81 
82  if (pOriginalGCPrio)
83  {
84  m_nOrigGCPriority = pOriginalGCPrio->GetArgN(0)->GetIntValue();
85  }
86 
87  // Ignore the other stuff at the moment.
88  MHParseNode *pItems = p->GetNamedArg(C_ITEMS);
89 
90  if (pItems == nullptr)
91  {
92  MHParseNode::Failure("Missing :Items block");
93  return;
94  }
95 
96  for (int i = 0; i < pItems->GetArgCount(); i++)
97  {
98  MHParseNode *pItem = pItems->GetArgN(i);
99  MHIngredient *pIngredient = nullptr;
100 
101  try
102  {
103  // Generate the particular kind of ingredient.
104  switch (pItem->GetTagNo())
105  {
106  case C_RESIDENT_PROGRAM:
107  pIngredient = new MHResidentProgram;
108  break;
109  case C_REMOTE_PROGRAM:
110  pIngredient = new MHRemoteProgram;
111  break;
113  pIngredient = new MHInterChgProgram;
114  break;
115  case C_PALETTE:
116  pIngredient = new MHPalette;
117  break;
118  case C_FONT:
119  pIngredient = new MHFont;
120  break;
121  case C_CURSOR_SHAPE:
122  pIngredient = new MHCursorShape;
123  break;
124  case C_BOOLEAN_VARIABLE:
125  pIngredient = new MHBooleanVar;
126  break;
127  case C_INTEGER_VARIABLE:
128  pIngredient = new MHIntegerVar;
129  break;
131  pIngredient = new MHOctetStrVar;
132  break;
134  pIngredient = new MHObjectRefVar;
135  break;
137  pIngredient = new MHContentRefVar;
138  break;
139  case C_LINK:
140  pIngredient = new MHLink;
141  break;
142  case C_STREAM:
143  pIngredient = new MHStream;
144  break;
145  case C_BITMAP:
146  pIngredient = new MHBitmap;
147  break;
148  case C_LINE_ART:
149  pIngredient = new MHLineArt;
150  break;
151  case C_DYNAMIC_LINE_ART:
152  pIngredient = new MHDynamicLineArt;
153  break;
154  case C_RECTANGLE:
155  pIngredient = new MHRectangle;
156  break;
157  case C_HOTSPOT:
158  pIngredient = new MHHotSpot;
159  break;
160  case C_SWITCH_BUTTON:
161  pIngredient = new MHSwitchButton;
162  break;
163  case C_PUSH_BUTTON:
164  pIngredient = new MHPushButton;
165  break;
166  case C_TEXT:
167  pIngredient = new MHText;
168  break;
169  case C_ENTRY_FIELD:
170  pIngredient = new MHEntryField;
171  break;
172  case C_HYPER_TEXT:
173  pIngredient = new MHHyperText;
174  break;
175  case C_SLIDER:
176  pIngredient = new MHSlider;
177  break;
178  case C_TOKEN_GROUP:
179  pIngredient = new MHTokenGroup;
180  break;
181  case C_LIST_GROUP:
182  pIngredient = new MHListGroup;
183  break;
184  default:
185  MHLOG(MHLogWarning, QString("Unknown ingredient %1").arg(pItem->GetTagNo()));
186  // Future proofing: ignore any ingredients that we don't know about.
187  // Obviously these can only arise in the binary coding.
188  }
189 
190  if (pIngredient)
191  {
192  // Initialise it from its argments.
193  pIngredient->Initialise(pItem, engine);
194 
195  // Remember the highest numbered ingredient
196  if (pIngredient->m_ObjectReference.m_nObjectNo > m_nLastId)
197  {
198  m_nLastId = pIngredient->m_ObjectReference.m_nObjectNo;
199  }
200 
201  // Add it to the ingedients of this group.
202  m_Items.Append(pIngredient);
203  }
204  }
205  catch (...)
206  {
207  MHLOG(MHLogError, "ERROR in MHGroup::Initialise ingredient");
208  if (pIngredient && __mhlogStream)
209  pIngredient->PrintMe(__mhlogStream, 0);
210 
211  delete(pIngredient);
212  throw;
213  }
214  }
215 }
216 
217 void MHGroup::PrintMe(FILE *fd, int nTabs) const
218 {
219  MHRoot::PrintMe(fd, nTabs);
220 
221  if (m_StartUp.Size() != 0)
222  {
223  PrintTabs(fd, nTabs + 1);
224  fprintf(fd, ":OnStartUp (\n");
225  m_StartUp.PrintMe(fd, nTabs + 2);
226  PrintTabs(fd, nTabs + 2);
227  fprintf(fd, ")\n");
228  }
229 
230  if (m_CloseDown.Size() != 0)
231  {
232  PrintTabs(fd, nTabs + 1);
233  fprintf(fd, ":OnCloseDown (\n");
234  m_CloseDown.PrintMe(fd, nTabs + 2);
235  PrintTabs(fd, nTabs + 2);
236  fprintf(fd, ")\n");
237  }
238 
239  if (m_nOrigGCPriority != 127)
240  {
241  PrintTabs(fd, nTabs + 1);
242  fprintf(fd, ":OrigGCPriority %d\n", m_nOrigGCPriority);
243  }
244 
245  PrintTabs(fd, nTabs + 1);
246  fprintf(fd, ":Items ( \n");
247 
248  for (int i = 0; i < m_Items.Size(); i++)
249  {
250  m_Items.GetAt(i)->PrintMe(fd, nTabs + 2);
251  }
252 
253  PrintTabs(fd, nTabs + 1);
254  fprintf(fd, ")\n");
255 }
256 
257 // Preparation - sets up the run-time representation. Sets m_fAvailable and generates IsAvailable event.
259 {
260  // Prepare the ingredients first if they are initially active or are initially available programs.
261  for (int i = 0; i < m_Items.Size(); i++)
262  {
263  MHIngredient *pIngredient = m_Items.GetAt(i);
264 
265  if (pIngredient->InitiallyActive() || pIngredient->InitiallyAvailable())
266  {
267  pIngredient->Preparation(engine);
268  }
269  }
270 
271  MHRoot::Preparation(engine); // Prepare the root object and send the IsAvailable event.
272 }
273 
274 // Activation - starts running the object. Sets m_fRunning and generates IsRunning event.
276 {
277  if (m_fRunning)
278  {
279  return;
280  }
281 
282  MHRoot::Activation(engine);
283  // Run any start-up actions.
284  engine->AddActions(m_StartUp);
285  engine->RunActions();
286 
287  // Activate the ingredients in order.
288  for (int i = 0; i < m_Items.Size(); i++)
289  {
290  MHIngredient *pIngredient = m_Items.GetAt(i);
291 
292  if (pIngredient->InitiallyActive())
293  {
294  pIngredient->Activation(engine);
295  }
296  }
297 
298  m_fRunning = true;
299  // Record the time here. This is the basis for absolute times.
300  m_StartTime.start();
301  // Don't generate IsRunning here - that's done by the sub-classes.
302 }
303 
304 // Deactivation - stops running the object. Clears m_fRunning
306 {
307  if (! m_fRunning)
308  {
309  return;
310  }
311 
312  // Run any close-down actions.
313  engine->AddActions(m_CloseDown);
314  engine->RunActions();
315  MHRoot::Deactivation(engine);
316 }
317 
318 // Destruction - deletes the run-time representation. Clears m_fAvailable.
320 {
321  for (int i = m_Items.Size(); i > 0; i--)
322  {
323  m_Items.GetAt(i - 1)->Destruction(engine);
324  }
325 
326  MHRoot::Destruction(engine);
327 }
328 
329 // Return an object if its object ID matches (or if it's a stream, if it has a matching component).
331 {
333  {
334  return this;
335  }
336 
337  for (int i = m_Items.Size(); i > 0; i--)
338  {
339  MHRoot *pResult = m_Items.GetAt(i - 1)->FindByObjectNo(n);
340 
341  if (pResult)
342  {
343  return pResult;
344  }
345  }
346 
347  return nullptr;
348 }
349 
350 // Set up a timer or cancel a timer.
351 void MHGroup::SetTimer(int nTimerId, bool fAbsolute, int nMilliSecs, MHEngine * /*engine*/)
352 {
353  // First remove any existing timer with the same Id.
354  for (int i = 0; i < m_Timers.size(); i++)
355  {
356  MHTimer *pTimer = m_Timers.at(i);
357 
358  if (pTimer->m_nTimerId == nTimerId)
359  {
360  delete m_Timers.takeAt(i);
361  break;
362  }
363  }
364 
365  // If the time has passed we don't set up a timer.
366  QTime currentTime;
367  currentTime.start(); // Set current time
368 
369  if (nMilliSecs < 0 || (fAbsolute && m_StartTime.addMSecs(nMilliSecs) < currentTime))
370  {
371  return;
372  }
373 
374  auto *pTimer = new MHTimer;
375  m_Timers.append(pTimer);
376  pTimer->m_nTimerId = nTimerId;
377 
378  if (fAbsolute)
379  {
380  pTimer->m_Time = m_StartTime.addMSecs(nMilliSecs);
381  }
382  else
383  {
384  pTimer->m_Time = currentTime.addMSecs(nMilliSecs);
385  }
386 }
387 
388 // Fire any timers that have passed.
390 {
391  QTime currentTime = QTime::currentTime(); // Get current time
392  QList<MHTimer *>::iterator it = m_Timers.begin();
393  int nMSecs = 0;
394 
395  while (it != m_Timers.end())
396  {
397  MHTimer *pTimer = *it;
398 
399  if (pTimer->m_Time <= currentTime) // Use <= rather than < here so we fire timers with zero time immediately.
400  {
401  // If the time has passed trigger the event and remove the timer from the queue.
402  engine->EventTriggered(this, EventTimerFired, pTimer->m_nTimerId);
403  delete pTimer;
404  it = m_Timers.erase(it);
405  }
406  else
407  {
408  // This has not yet expired. Set "nMSecs" to the earliest time we have.
409  int nMSecsToGo = currentTime.msecsTo(pTimer->m_Time);
410 
411  if (nMSecs == 0 || nMSecsToGo < nMSecs)
412  {
413  nMSecs = nMSecsToGo;
414  }
415 
416  ++it;
417  }
418  }
419 
420  return nMSecs;
421 }
422 
423 // Create a clone of the target and add it to the ingredients.
424 void MHGroup::MakeClone(MHRoot *pTarget, MHRoot *pRef, MHEngine *engine)
425 {
426  MHIngredient *pClone = pTarget->Clone(engine); // Clone it.
427  pClone->m_ObjectReference.m_GroupId.Copy(m_ObjectReference.m_GroupId); // Group id is the same as this.
428  pClone->m_ObjectReference.m_nObjectNo = ++m_nLastId; // Create a new object id.
429  m_Items.Append(pClone);
430  // Set the object reference result to the newly constructed ref.
431  pRef->SetVariableValue(pClone->m_ObjectReference);
432  pClone->Preparation(engine); // Prepare the clone.
433 }
434 
436 {
437  delete(m_pCurrentScene);
438 }
439 
441 {
442  MHGroup::Initialise(p, engine);
443  // OnSpawnCloseDown
444  MHParseNode *pOnSpawn = p->GetNamedArg(C_ON_SPAWN_CLOSE_DOWN);
445 
446  if (pOnSpawn)
447  {
448  m_OnSpawnCloseDown.Initialise(pOnSpawn, engine);
449  }
450 
451  // OnRestart
452  MHParseNode *pOnRestart = p->GetNamedArg(C_ON_RESTART);
453 
454  if (pOnRestart)
455  {
456  m_OnRestart.Initialise(pOnRestart, engine);
457  }
458 
459  // Default attributes. These are encoded in a group in binary.
460  MHParseNode *pDefattrs = p->GetNamedArg(C_DEFAULT_ATTRIBUTES);
461 
462  // but in the text form they're encoded in the Application block.
463  if (pDefattrs == nullptr)
464  {
465  pDefattrs = p;
466  }
467 
468  MHParseNode *pCharSet = pDefattrs->GetNamedArg(C_CHARACTER_SET);
469 
470  if (pCharSet)
471  {
472  m_nCharSet = pCharSet->GetArgN(0)->GetIntValue();
473  }
474 
475  // Colours
476  MHParseNode *pBGColour = pDefattrs->GetNamedArg(C_BACKGROUND_COLOUR);
477 
478  if (pBGColour)
479  {
480  m_BGColour.Initialise(pBGColour->GetArgN(0), engine);
481  }
482 
483  MHParseNode *pTextColour = pDefattrs->GetNamedArg(C_TEXT_COLOUR);
484 
485  if (pTextColour)
486  {
487  m_TextColour.Initialise(pTextColour->GetArgN(0), engine);
488  }
489 
490  MHParseNode *pButtonRefColour = pDefattrs->GetNamedArg(C_BUTTON_REF_COLOUR);
491 
492  if (pButtonRefColour)
493  {
494  m_ButtonRefColour.Initialise(pButtonRefColour->GetArgN(0), engine);
495  }
496 
497  MHParseNode *pHighlightRefColour = pDefattrs->GetNamedArg(C_HIGHLIGHT_REF_COLOUR);
498 
499  if (pHighlightRefColour)
500  {
501  m_HighlightRefColour.Initialise(pHighlightRefColour->GetArgN(0), engine);
502  }
503 
504  MHParseNode *pSliderRefColour = pDefattrs->GetNamedArg(C_SLIDER_REF_COLOUR);
505 
506  if (pSliderRefColour)
507  {
508  m_SliderRefColour.Initialise(pSliderRefColour->GetArgN(0), engine);
509  }
510 
511  // Content hooks
512  MHParseNode *pTextCHook = pDefattrs->GetNamedArg(C_TEXT_CONTENT_HOOK);
513 
514  if (pTextCHook)
515  {
516  m_nTextCHook = pTextCHook->GetArgN(0)->GetIntValue();
517  }
518 
519  MHParseNode *pIPCHook = pDefattrs->GetNamedArg(C_IP_CONTENT_HOOK);
520 
521  if (pIPCHook)
522  {
523  m_nIPCHook = pIPCHook->GetArgN(0)->GetIntValue();
524  }
525 
526  MHParseNode *pStrCHook = pDefattrs->GetNamedArg(C_STREAM_CONTENT_HOOK);
527 
528  if (pStrCHook)
529  {
530  m_nStrCHook = pStrCHook->GetArgN(0)->GetIntValue();
531  }
532 
533  MHParseNode *pBitmapCHook = pDefattrs->GetNamedArg(C_BITMAP_CONTENT_HOOK);
534 
535  if (pBitmapCHook)
536  {
537  m_nBitmapCHook = pBitmapCHook->GetArgN(0)->GetIntValue();
538  }
539 
540  MHParseNode *pLineArtCHook = pDefattrs->GetNamedArg(C_LINE_ART_CONTENT_HOOK);
541 
542  if (pLineArtCHook)
543  {
544  m_nLineArtCHook = pLineArtCHook->GetArgN(0)->GetIntValue();
545  }
546 
547  // Font. This is a little tricky. There are two attributes both called Font.
548  // In the binary notation the font here is encoded as 42 whereas the text form
549  // finds the first occurrence of :Font in the table and returns 13.
550  MHParseNode *pFont = pDefattrs->GetNamedArg(C_FONT2);
551 
552  if (pFont == nullptr)
553  {
554  pFont = pDefattrs->GetNamedArg(C_FONT);
555  }
556 
557  if (pFont)
558  {
559  m_Font.Initialise(pFont->GetArgN(0), engine);
560  }
561 
562  // Font attributes.
563  MHParseNode *pFontAttrs = pDefattrs->GetNamedArg(C_FONT_ATTRIBUTES);
564 
565  if (pFontAttrs)
566  {
567  pFontAttrs->GetArgN(0)->GetStringValue(m_FontAttrs);
568  }
569 }
570 
571 void MHApplication::PrintMe(FILE *fd, int nTabs) const
572 {
573  PrintTabs(fd, nTabs);
574  fprintf(fd, "{:Application ");
575  MHGroup::PrintMe(fd, nTabs);
576 
577  if (m_OnSpawnCloseDown.Size() != 0)
578  {
579  PrintTabs(fd, nTabs + 1);
580  fprintf(fd, ":OnSpawnCloseDown");
581  m_OnSpawnCloseDown.PrintMe(fd, nTabs + 1);
582  fprintf(fd, "\n");
583  }
584 
585  if (m_OnRestart.Size() != 0)
586  {
587  PrintTabs(fd, nTabs + 1);
588  fprintf(fd, ":OnRestart");
589  m_OnRestart.PrintMe(fd, nTabs + 1);
590  fprintf(fd, "\n");
591  }
592 
593  if (m_nCharSet > 0)
594  {
595  PrintTabs(fd, nTabs + 1);
596  fprintf(fd, ":CharacterSet %d\n", m_nCharSet);
597  }
598 
599  if (m_BGColour.IsSet())
600  {
601  PrintTabs(fd, nTabs + 1);
602  fprintf(fd, ":BackgroundColour ");
603  m_BGColour.PrintMe(fd, nTabs + 1);
604  fprintf(fd, "\n");
605  }
606 
607  if (m_nTextCHook > 0)
608  {
609  PrintTabs(fd, nTabs + 1);
610  fprintf(fd, ":TextCHook %d\n", m_nTextCHook);
611  }
612 
613  if (m_TextColour.IsSet())
614  {
615  PrintTabs(fd, nTabs + 1);
616  fprintf(fd, ":TextColour");
617  m_TextColour.PrintMe(fd, nTabs + 1);
618  fprintf(fd, "\n");
619  }
620 
621  if (m_Font.IsSet())
622  {
623  PrintTabs(fd, nTabs + 1);
624  fprintf(fd, ":Font ");
625  m_Font.PrintMe(fd, nTabs + 1);
626  fprintf(fd, "\n");
627  }
628 
629  if (m_FontAttrs.Size() > 0)
630  {
631  PrintTabs(fd, nTabs + 1);
632  fprintf(fd, ":FontAttributes ");
633  m_FontAttrs.PrintMe(fd, nTabs + 1);
634  fprintf(fd, "\n");
635  }
636 
637  if (m_nIPCHook > 0)
638  {
639  PrintTabs(fd, nTabs + 1);
640  fprintf(fd, ":InterchgPrgCHook %d\n", m_nIPCHook);
641  }
642 
643  if (m_nStrCHook > 0)
644  {
645  PrintTabs(fd, nTabs + 1);
646  fprintf(fd, ":StreamCHook %d\n", m_nStrCHook);
647  }
648 
649  if (m_nBitmapCHook > 0)
650  {
651  PrintTabs(fd, nTabs + 1);
652  fprintf(fd, ":BitmapCHook %d\n", m_nBitmapCHook);
653  }
654 
655  if (m_nLineArtCHook > 0)
656  {
657  PrintTabs(fd, nTabs + 1);
658  fprintf(fd, ":LineArtCHook %d\n", m_nLineArtCHook);
659  }
660 
661  if (m_ButtonRefColour.IsSet())
662  {
663  PrintTabs(fd, nTabs + 1);
664  fprintf(fd, ":ButtonRefColour ");
665  m_ButtonRefColour.PrintMe(fd, nTabs + 1);
666  fprintf(fd, "\n");
667  }
668 
670  {
671  PrintTabs(fd, nTabs + 1);
672  fprintf(fd, ":HighlightRefColour ");
673  m_HighlightRefColour.PrintMe(fd, nTabs + 1);
674  fprintf(fd, "\n");
675  }
676 
677  if (m_SliderRefColour.IsSet())
678  {
679  PrintTabs(fd, nTabs + 1);
680  fprintf(fd, ":SliderRefColour ");
681  m_SliderRefColour.PrintMe(fd, nTabs + 1);
682  fprintf(fd, "\n");
683  }
684 
685  fprintf(fd, "}\n");
686 }
687 
688 // This is a bit messy. The MHEG corrigendum says that we need to process OnRestart actions
689 // BEFORE generating IsRunning. That's important because TransitionTo etc are ignored during
690 // OnRestart but allowed in events triggered by IsRunning.
692 {
693  if (m_fRunning)
694  {
695  return;
696  }
697 
698  MHGroup::Activation(engine);
699 
700  if (m_fRestarting) // Set by Quit
701  {
702  engine->AddActions(m_OnRestart);
703  engine->RunActions();
704  }
705 
706  engine->EventTriggered(this, EventIsRunning);
707 }
708 
709 int MHApplication::FindOnStack(const MHRoot *pVis) // Returns the index on the stack or -1 if it's not there.
710 {
711  for (int i = 0; i < m_DisplayStack.Size(); i++)
712  {
713  if (m_DisplayStack.GetAt(i) == pVis)
714  {
715  return i;
716  }
717  }
718 
719  return -1; // Not there
720 }
721 
723 {
724  MHGroup::Initialise(p, engine);
725  // Event register.
726  MHParseNode *pInputEventReg = p->GetNamedArg(C_INPUT_EVENT_REGISTER);
727 
728  if (pInputEventReg)
729  {
730  m_nEventReg = pInputEventReg->GetArgN(0)->GetIntValue();
731  }
732 
733  // Co-ordinate system
734  MHParseNode *pSceneCoords = p->GetNamedArg(C_SCENE_COORDINATE_SYSTEM);
735 
736  if (pSceneCoords)
737  {
738  m_nSceneCoordX = pSceneCoords->GetArgN(0)->GetIntValue();
739  m_nSceneCoordY = pSceneCoords->GetArgN(1)->GetIntValue();
740  }
741 
742  // Aspect ratio
743  MHParseNode *pAspectRatio = p->GetNamedArg(C_ASPECT_RATIO);
744 
745  if (pAspectRatio)
746  {
747  // Is the binary encoded as a sequence or a pair of arguments?
748  m_nAspectRatioW = pAspectRatio->GetArgN(0)->GetIntValue();
749  m_nAspectRatioH = pAspectRatio->GetArgN(1)->GetIntValue();
750  }
751 
752  // Moving cursor
753  MHParseNode *pMovingCursor = p->GetNamedArg(C_MOVING_CURSOR);
754 
755  if (pMovingCursor)
756  {
757  pMovingCursor->GetArgN(0)->GetBoolValue();
758  }
759 
760  // Next scene sequence: this is just a hint and isn't implemented
761 }
762 
763 void MHScene::PrintMe(FILE *fd, int nTabs) const
764 {
765  PrintTabs(fd, nTabs);
766  fprintf(fd, "{:Scene ");
767  MHGroup::PrintMe(fd, nTabs);
768  PrintTabs(fd, nTabs + 1);
769  fprintf(fd, ":InputEventReg %d\n", m_nEventReg);
770  PrintTabs(fd, nTabs + 1);
771  fprintf(fd, ":SceneCS %d %d\n", m_nSceneCoordX, m_nSceneCoordY);
772 
773  if (m_nAspectRatioW != 4 || m_nAspectRatioH != 3)
774  {
775  PrintTabs(fd, nTabs + 1);
776  fprintf(fd, ":AspectRatio %d %d\n", m_nAspectRatioW, m_nAspectRatioH);
777  }
778 
779  if (m_fMovingCursor)
780  {
781  PrintTabs(fd, nTabs + 1);
782  fprintf(fd, ":MovingCursor true\n");
783  }
784 
785  fprintf(fd, "}\n");
786 }
787 
789 {
790  if (m_fRunning)
791  {
792  return;
793  }
794 
795  MHGroup::Activation(engine);
796  engine->EventTriggered(this, EventIsRunning);
797 }
798 
799 // Action added in UK MHEG profile. It doesn't define a new internal attribute for this.
800 void MHScene::SetInputRegister(int nReg, MHEngine *engine)
801 {
802  m_nEventReg = nReg;
803  engine->SetInputRegister(nReg);
804 }
805 
806 
808 {
809  MHElemAction::Initialise(p, engine); // Target
810  m_EventSource.Initialise(p->GetArgN(1), engine);
811  m_EventType = (enum EventType)p->GetArgN(2)->GetEnumValue();
812 
813  if (p->GetArgCount() >= 4)
814  {
815  // TODO: We could check here that we only have bool, int or string and not object ref or content ref.
816  m_EventData.Initialise(p->GetArgN(3), engine);
817  }
818 }
819 
820 void MHSendEvent::PrintArgs(FILE *fd, int /*nTabs*/) const
821 {
822  m_EventSource.PrintMe(fd, 0);
823  QByteArray tmp = MHLink::EventTypeToString(m_EventType).toLatin1();
824  fprintf(fd, "%s", tmp.constData());
825  fprintf(fd, " ");
826 
827  if (m_EventData.m_Type != MHParameter::P_Null)
828  {
829  m_EventData.PrintMe(fd, 0);
830  }
831 }
832 
834 {
835  // The target is always the current scene so we ignore it here.
836  MHObjectRef target;
837  MHObjectRef source;
838  m_Target.GetValue(target, engine); // TODO: Check this is the scene?
839  m_EventSource.GetValue(source, engine);
840 
841  // Generate the event.
842  if (m_EventData.m_Type == MHParameter::P_Null)
843  {
844  engine->EventTriggered(engine->FindObject(source), m_EventType);
845  }
846  else
847  {
848  MHUnion data;
849  data.GetValueFrom(m_EventData, engine);
850  engine->EventTriggered(engine->FindObject(source), m_EventType, data);
851  }
852 }
853 
855 {
856  MHElemAction::Initialise(p, engine);
857  m_TimerId.Initialise(p->GetArgN(1), engine); // The timer id
858 
859  if (p->GetArgCount() > 2)
860  {
861  MHParseNode *pNewTimer = p->GetArgN(2);
862  m_TimerValue.Initialise(pNewTimer->GetSeqN(0), engine);
863 
864  if (pNewTimer->GetSeqCount() > 1)
865  {
866  m_TimerType = ST_TimerAbsolute; // May be absolute - depends on the value.
867  m_AbsFlag.Initialise(pNewTimer->GetSeqN(1), engine);
868  }
869  else
870  {
871  m_TimerType = ST_TimerRelative;
872  }
873  }
874 }
875 
876 void MHSetTimer::PrintArgs(FILE *fd, int /*nTabs*/) const
877 {
878  m_TimerId.PrintMe(fd, 0);
879 
880  if (m_TimerType != ST_NoNewTimer)
881  {
882  fprintf(fd, "( ");
883  m_TimerValue.PrintMe(fd, 0);
884 
885  if (m_TimerType == ST_TimerAbsolute)
886  {
887  m_AbsFlag.PrintMe(fd, 0);
888  }
889 
890  fprintf(fd, ") ");
891  }
892 }
893 
895 {
896  int nTimerId = m_TimerId.GetValue(engine);
897  bool fAbsolute = false; // Defaults to relative time.
898  int newTime = -1;
899 
900  switch (m_TimerType)
901  {
902  case ST_NoNewTimer:
903  fAbsolute = true;
904  newTime = -1;
905  break; // We treat an absolute time of -1 as "cancel"
906  case ST_TimerAbsolute:
907  fAbsolute = m_AbsFlag.GetValue(engine);
908  [[clang::fallthrough]];
909  case ST_TimerRelative:
910  newTime = m_TimerValue.GetValue(engine);
911  }
912 
913  Target(engine)->SetTimer(nTimerId, fAbsolute, newTime, engine);
914 }
915 
917 {
918  MHElemAction::Initialise(p, engine); // Target
919  m_Succeeded.Initialise(p->GetArgN(1), engine);
920  MHParseNode *pVarSeq = p->GetArgN(2);
921 
922  for (int i = 0; i < pVarSeq->GetSeqCount(); i++)
923  {
924  auto *pVar = new MHObjectRef;
925  m_Variables.Append(pVar);
926  pVar->Initialise(pVarSeq->GetSeqN(i), engine);
927  }
928 
929  m_FileName.Initialise(p->GetArgN(3), engine);
930 }
931 
932 void MHPersistent::PrintArgs(FILE *fd, int nTabs) const
933 {
934  m_Succeeded.PrintMe(fd, nTabs);
935  fprintf(fd, " ( ");
936 
937  for (int i = 0; i < m_Variables.Size(); i++)
938  {
939  m_Variables.GetAt(i)->PrintMe(fd, 0);
940  }
941 
942  fprintf(fd, " ) ");
943  m_FileName.PrintMe(fd, nTabs);
944 }
945 
947 {
948  MHObjectRef target;
949  m_Target.GetValue(target, engine); // Get the target - this should always be the application
950  MHOctetString fileName;
951  m_FileName.GetValue(fileName, engine);
952  bool fResult = engine->LoadStorePersistent(m_fIsLoad, fileName, m_Variables);
953  engine->FindObject(m_Succeeded)->SetVariableValue(fResult);
954 }
955 
957 {
958  m_fIsTagged = false;
959  m_nConnectionTag = 0;
960  m_nTransitionEffect = -1;
961 }
962 
964 {
965  MHElemAction::Initialise(p, engine); // Target
966  // The next one may be present but NULL in binary.
967  if (p->GetArgCount() > 1)
968  {
969  MHParseNode *pCtag = p->GetArgN(1);
970 
971  if (pCtag->m_nNodeType == MHParseNode::PNInt)
972  {
973  m_fIsTagged = true;
974  m_nConnectionTag = pCtag->GetIntValue();
975  }
976  }
977 
978  if (p->GetArgCount() > 2)
979  {
980  MHParseNode *pTrEff = p->GetArgN(2);
981  m_nTransitionEffect = pTrEff->GetIntValue();
982  }
983 }
984 
985 void MHTransitionTo::PrintArgs(FILE *fd, int /*nTabs*/) const
986 {
987  if (m_fIsTagged)
988  {
989  fprintf(fd, " %d ", m_nConnectionTag);
990  }
991  else if (m_nTransitionEffect >= 0)
992  {
993  fprintf(fd, " NULL ");
994  }
995 
996  if (m_nTransitionEffect >= 0)
997  {
998  fprintf(fd, " %d", m_nTransitionEffect);
999  }
1000 }
1001 
1002 // Do the action - Transition to a new scene.
1004 {
1005  MHObjectRef target;
1006  m_Target.GetValue(target, engine); // Get the target
1007  engine->TransitionToScene(target);
1008 }
1009 
1011 {
1012  MHObjectRef target;
1013  m_Target.GetValue(target, engine);
1014  engine->Launch(target);
1015 }
1017 {
1018  engine->Quit();
1019 }
1021 {
1022  MHObjectRef target;
1023  m_Target.GetValue(target, engine);
1024  engine->Spawn(target);
1025 }
1027 {
1028  engine->LockScreen();
1029 }
1031 {
1032  engine->UnlockScreen();
1033 }
1034 
1036 {
1037  MHElemAction::Initialise(p, engine);
1038  m_Feature.Initialise(p->GetArgN(1), engine);
1039  m_Answer.Initialise(p->GetArgN(2), engine);
1040 }
1041 
1043 {
1044  // Ignore the target which isn't used.
1045  MHOctetString feature;
1046  m_Feature.GetValue(feature, engine);
1047  engine->FindObject(m_Answer)->SetVariableValue(engine->GetEngineSupport(feature));
1048 }
void Initialise(MHParseNode *p, MHEngine *engine)
#define C_DYNAMIC_LINE_ART
Definition: ASN1Codes.h:57
int m_nTransitionEffect
Definition: Groups.h:240
static void Failure(const char *p)
Definition: ParseNode.cpp:43
void Activation(MHEngine *engine) override
Definition: Groups.cpp:788
void Preparation(MHEngine *engine) override
virtual void Destruction(MHEngine *engine)
Definition: Root.cpp:97
void Initialise(MHParseNode *p, MHEngine *engine)
Definition: Groups.h:39
#define C_HYPER_TEXT
Definition: ASN1Codes.h:64
#define C_FONT2
Definition: ASN1Codes.h:75
QTime m_Time
Definition: Groups.h:42
void Deactivation(MHEngine *engine) override
Definition: Groups.cpp:305
#define C_LIST_GROUP
Definition: ASN1Codes.h:67
QList< MHTimer * > m_Timers
Definition: Groups.h:78
#define C_SWITCH_BUTTON
Definition: ASN1Codes.h:60
void PrintMe(FILE *fd, int nTabs) const override
#define MHERROR(__text)
Definition: Logging.h:42
bool GetValue(MHEngine *engine) const
MHObjectRef m_Answer
Definition: Groups.h:268
#define C_ON_CLOSE_DOWN
Definition: ASN1Codes.h:39
void PrintMe(FILE *fd, int nTabs) const
MHParameter m_EventData
Definition: Groups.h:183
MHOwnPtrSequence< MHObjectRef > m_Variables
Definition: Groups.h:224
void Perform(MHEngine *engine) override
Definition: Groups.cpp:1042
void RunActions()
Definition: Engine.cpp:614
void Perform(MHEngine *engine) override
Definition: Groups.cpp:1003
void Perform(MHEngine *engine) override
Definition: Groups.cpp:1030
void PrintMe(FILE *fd, int nTabs) const
#define C_INPUT_EVENT_REGISTER
Definition: ASN1Codes.h:84
MHColour m_BGColour
Definition: Groups.h:132
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Groups.cpp:722
virtual void SetVariableValue(const MHUnion &)
Definition: Root.h:108
MHGenericObjectRef m_Target
Definition: BaseActions.h:46
virtual bool InitiallyAvailable()
Definition: Ingredients.h:43
virtual MHRoot * FindByObjectNo(int n)
Definition: Root.cpp:115
#define C_CONTENT_REF_VARIABLE
Definition: ASN1Codes.h:52
virtual void PrintMe(FILE *fd, int nTabs) const
Definition: Root.cpp:38
MHRoot * Target(MHEngine *engine)
Definition: BaseActions.cpp:46
BASE GetAt(int i) const
Definition: BaseClasses.h:48
enum NodeType m_nNodeType
Definition: ParseNode.h:46
bool IsSet() const
Definition: BaseClasses.h:142
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Groups.cpp:963
#define C_TEXT
Definition: ASN1Codes.h:62
void Initialise(MHParseNode *p, MHEngine *engine)
void Perform(MHEngine *engine) override
Definition: Groups.cpp:833
virtual void Activation(MHEngine *engine)
Definition: Root.cpp:69
int m_nBitmapCHook
Definition: Groups.h:136
virtual bool InitiallyActive()
Definition: Ingredients.h:42
MHColour m_TextColour
Definition: Groups.h:132
MHScene * m_pCurrentScene
Definition: Groups.h:149
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Groups.cpp:440
MHGenericObjectRef m_EventSource
Definition: Groups.h:181
MHOctetString m_FontAttrs
Definition: Groups.h:139
int CheckTimers(MHEngine *engine)
Definition: Groups.cpp:389
#define C_PALETTE
Definition: ASN1Codes.h:45
#define C_ASPECT_RATIO
Definition: ASN1Codes.h:86
MHOwnPtrSequence< MHIngredient > m_Items
Definition: Groups.h:70
virtual void Deactivation(MHEngine *engine)
Definition: Root.cpp:85
void MakeClone(MHRoot *pTarget, MHRoot *pRef, MHEngine *engine) override
Definition: Groups.cpp:424
#define C_BITMAP_CONTENT_HOOK
Definition: ASN1Codes.h:79
#define C_ITEMS
Definition: ASN1Codes.h:41
int GetValue(MHEngine *engine) const
void GetValue(MHOctetString &str, MHEngine *engine) const
void Perform(MHEngine *engine) override
Definition: Groups.cpp:946
#define C_RECTANGLE
Definition: ASN1Codes.h:58
void PrintMe(FILE *fd, int nTabs) const override
Definition: Groups.cpp:763
#define C_STREAM_CONTENT_HOOK
Definition: ASN1Codes.h:78
bool Launch(const MHObjectRef &target, bool fIsSpawn=false)
Definition: Engine.cpp:274
int m_nCharSet
Definition: Groups.h:131
void PrintMe(FILE *fd, int nTabs) const
void SetTimer(int nTimerId, bool fAbsolute, int nMilliSecs, MHEngine *engine) override
Definition: Groups.cpp:351
MHGenericInteger m_TimerValue
Definition: Groups.h:202
static guint32 * tmp
Definition: goom_core.c:35
void Initialise(MHParseNode *p, MHEngine *engine)
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Groups.cpp:854
virtual void Initialise(MHParseNode *p, MHEngine *engine)
Definition: Actions.cpp:67
#define C_SCENE_COORDINATE_SYSTEM
Definition: ASN1Codes.h:85
void GetValueFrom(const MHParameter &value, MHEngine *engine)
void Perform(MHEngine *engine) override
Definition: Groups.cpp:1026
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Groups.cpp:48
void GetValue(MHObjectRef &ref, MHEngine *engine) const
#define C_OCTET_STRING_VARIABLE
Definition: ASN1Codes.h:50
int FindOnStack(const MHRoot *pVis)
Definition: Groups.cpp:709
void Initialise(MHParseNode *p, MHEngine *engine)
virtual MHIngredient * Clone(MHEngine *)
Definition: Root.h:96
void PrintTabs(FILE *fd, int n)
Definition: ParseNode.cpp:34
MHFontBody m_Font
Definition: Groups.h:138
MHRoot * FindByObjectNo(int n) override
Definition: Groups.cpp:330
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Groups.cpp:1035
int m_nLastId
Definition: Groups.h:81
void PrintMe(FILE *fd, int nTabs) const override
Definition: Groups.cpp:571
MHParseNode * GetSeqN(int n)
Definition: ParseNode.cpp:152
void Copy(const MHOctetString &str)
#define C_BOOLEAN_VARIABLE
Definition: ASN1Codes.h:48
int Size() const
Definition: BaseClasses.h:118
int m_nIPCHook
Definition: Groups.h:134
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Ingredients.cpp:49
void PrintArgs(FILE *fd, int nTabs) const override
Definition: Groups.cpp:876
void PrintArgs(FILE *fd, int nTabs) const override
Definition: Groups.cpp:985
MHGenericInteger m_TimerId
Definition: Groups.h:194
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Groups.cpp:916
void Perform(MHEngine *engine) override
Definition: Groups.cpp:894
void Preparation(MHEngine *engine) override
Definition: Groups.cpp:258
int GetIntValue()
Definition: ParseNode.cpp:170
#define C_REMOTE_PROGRAM
Definition: ASN1Codes.h:43
FILE * __mhlogStream
Definition: Engine.cpp:1478
bool m_fMovingCursor
Definition: Groups.h:108
#define C_BUTTON_REF_COLOUR
Definition: ASN1Codes.h:81
#define C_INTERCHANGED_PROGRAM
Definition: ASN1Codes.h:44
void EventTriggered(MHRoot *pSource, enum EventType ev)
Definition: Engine.h:93
int m_nStrCHook
Definition: Groups.h:135
bool LoadStorePersistent(bool fIsLoad, const MHOctetString &fileName, const MHSequence< MHObjectRef * > &variables)
Definition: Engine.cpp:1110
void PrintArgs(FILE *fd, int nTabs) const override
Definition: Groups.cpp:820
MHGenericOctetString m_Feature
Definition: Groups.h:267
void GetStringValue(MHOctetString &str)
Definition: ParseNode.cpp:203
MHParseNode * GetNamedArg(int nTag)
Definition: ParseNode.cpp:110
#define C_LINE_ART_CONTENT_HOOK
Definition: ASN1Codes.h:80
void PrintMe(FILE *fd, int nTabs) const
#define C_TEXT_COLOUR
Definition: ASN1Codes.h:74
QTime m_StartTime
Definition: Groups.h:77
int m_nTextCHook
Definition: Groups.h:133
enum MHParameter::ParamTypes P_Null
#define C_FONT
Definition: ASN1Codes.h:46
void Initialise(MHParseNode *p, MHEngine *engine)
#define C_TEXT_CONTENT_HOOK
Definition: ASN1Codes.h:73
Definition: Root.h:43
void PrintMe(FILE *fd, int nTabs) const
void PrintMe(FILE *fd, int nTabs) const
void TransitionToScene(const MHObjectRef &target)
Definition: Engine.cpp:419
MHObjectRef m_Succeeded
Definition: Groups.h:223
bool m_fRunning
Definition: Root.h:252
MHObjectRef m_ObjectReference
Definition: Root.h:247
#define C_BACKGROUND_COLOUR
Definition: ASN1Codes.h:72
int FILE
Definition: mythburn.py:110
MHActionSequence m_OnRestart
Definition: Groups.h:129
#define C_TOKEN_GROUP
Definition: ASN1Codes.h:66
int m_nTimerId
Definition: Groups.h:41
virtual void SetTimer(int, bool, int, MHEngine *)
Definition: Root.h:79
void Destruction(MHEngine *engine) override
void Perform(MHEngine *engine) override
Definition: Groups.cpp:1010
int m_nEventReg
Definition: Groups.h:100
void Perform(MHEngine *engine) override
Definition: Groups.cpp:1020
bool IsSet() const
Definition: BaseClasses.h:313
bool m_fIsLoad
Definition: Groups.h:222
MHActionSequence m_StartUp
Definition: Groups.h:69
MHColour m_ButtonRefColour
Definition: Groups.h:132
MHActionSequence m_OnSpawnCloseDown
Definition: Groups.h:129
#define C_LINK
Definition: ASN1Codes.h:53
void PrintArgs(FILE *fd, int nTabs) const override
Definition: Groups.cpp:932
int m_nSceneCoordX
Definition: Groups.h:101
virtual void Initialise(MHParseNode *p, MHEngine *engine)
Definition: Root.cpp:30
void Destruction(MHEngine *engine) override
Definition: Groups.cpp:319
#define C_MOVING_CURSOR
Definition: ASN1Codes.h:87
void UnlockScreen()
Definition: Engine.cpp:905
void Initialise(MHParseNode *p, MHEngine *engine)
MHRoot * FindObject(const MHObjectRef &oRef, bool failOnNotFound=true)
Definition: Engine.cpp:574
#define C_PUSH_BUTTON
Definition: ASN1Codes.h:61
bool m_fIsTagged
Definition: Groups.h:238
#define C_ON_START_UP
Definition: ASN1Codes.h:38
void SetInputRegister(int nReg, MHEngine *engine) override
Definition: Groups.cpp:800
#define C_DEFAULT_ATTRIBUTES
Definition: ASN1Codes.h:70
void PrintMe(FILE *fd, int nTabs) const
#define MHLOG(__level, __text)
Definition: Logging.h:36
virtual void Initialise(MHParseNode *p, MHEngine *engine)
Definition: BaseActions.cpp:31
#define C_INTEGER_VARIABLE
Definition: ASN1Codes.h:49
int GetSeqCount()
Definition: ParseNode.cpp:141
int GetArgCount()
Definition: ParseNode.cpp:60
Definition: Text.h:37
MHOctetString & GetGroupId()
Definition: Engine.h:152
#define C_ON_SPAWN_CLOSE_DOWN
Definition: ASN1Codes.h:68
bool GetBoolValue()
Definition: ParseNode.cpp:192
void Perform(MHEngine *engine) override
Definition: Groups.cpp:1016
~MHGroup() override
Definition: Groups.cpp:40
#define C_FONT_ATTRIBUTES
Definition: ASN1Codes.h:76
MHActionSequence m_CloseDown
Definition: Groups.h:69
void Initialise(MHParseNode *p, MHEngine *engine)
MHOctetString m_GroupId
Definition: BaseClasses.h:168
void Activation(MHEngine *engine) override
Definition: Groups.cpp:691
virtual void PrintMe(FILE *fd, int nTabs) const
Definition: Actions.cpp:456
void Quit()
Definition: Engine.cpp:378
MHParseNode * GetArgN(int n)
Definition: ParseNode.cpp:78
void Spawn(const MHObjectRef &target)
Definition: Engine.h:84
#define C_LINE_ART
Definition: ASN1Codes.h:56
MHSequence< MHVisible * > m_DisplayStack
Definition: Groups.h:146
int GetTagNo()
Definition: ParseNode.cpp:49
MHGenericBoolean m_AbsFlag
Definition: Groups.h:203
MHColour m_HighlightRefColour
Definition: Groups.h:132
void SetInputRegister(int nReg)
Definition: Engine.cpp:518
void PrintMe(FILE *fd, int nTabs) const override
Definition: Groups.cpp:217
EventType
Definition: Root.h:33
void LockScreen()
Definition: Engine.h:109
#define C_SLIDER_REF_COLOUR
Definition: ASN1Codes.h:83
void Append(BASE b)
Definition: BaseClasses.h:63
int m_nAspectRatioW
Definition: Groups.h:106
#define C_ENTRY_FIELD
Definition: ASN1Codes.h:63
#define C_ORIGINAL_GC_PRIORITY
Definition: ASN1Codes.h:40
#define C_STREAM
Definition: ASN1Codes.h:54
int m_nLineArtCHook
Definition: Groups.h:137
bool m_fRestarting
Definition: Groups.h:150
#define C_BITMAP
Definition: ASN1Codes.h:55
int Size() const
Definition: BaseClasses.h:46
#define C_CURSOR_SHAPE
Definition: ASN1Codes.h:47
MHGenericOctetString m_FileName
Definition: Groups.h:225
int m_nSceneCoordY
Definition: Groups.h:102
#define C_HIGHLIGHT_REF_COLOUR
Definition: ASN1Codes.h:82
void AddActions(const MHActionSequence &actions)
Definition: Engine.cpp:724
void PrintMe(FILE *fd, int nTabs) const
#define C_CHARACTER_SET
Definition: ASN1Codes.h:71
void PrintMe(FILE *fd, int nTabs) const
#define C_HOTSPOT
Definition: ASN1Codes.h:59
#define C_OBJECT_REF_VARIABLE
Definition: ASN1Codes.h:51
#define C_SLIDER
Definition: ASN1Codes.h:65
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Groups.cpp:807
#define C_ON_RESTART
Definition: ASN1Codes.h:69
int m_nConnectionTag
Definition: Groups.h:239
virtual void Preparation(MHEngine *engine)
Definition: Root.cpp:52
int m_nOrigGCPriority
Definition: Groups.h:68
void Activation(MHEngine *engine) override
Definition: Groups.cpp:275
#define C_RESIDENT_PROGRAM
Definition: ASN1Codes.h:42
bool GetEngineSupport(const MHOctetString &feature)
Definition: Engine.cpp:1188
enum MHSetTimer::@9 ST_NoNewTimer
#define C_IP_CONTENT_HOOK
Definition: ASN1Codes.h:77
int m_nAspectRatioH
Definition: Groups.h:107
MHColour m_SliderRefColour
Definition: Groups.h:132
~MHApplication() override
Definition: Groups.cpp:435