MythTV  master
Visible.cpp
Go to the documentation of this file.
1 /* Visible.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 #include "compat.h"
22 
23 #include "Visible.h"
24 #include "Presentable.h"
25 #include "Ingredients.h"
26 #include "Root.h"
27 #include "BaseClasses.h"
28 #include "ParseNode.h"
29 #include "ASN1Codes.h"
30 #include "Engine.h"
31 #include "Logging.h"
32 #include "freemheg.h"
33 
34 
35 // Copy constructor for cloning
37 {
44  m_nPosX = ref.m_nPosX;
45  m_nPosY = ref.m_nPosY;
47 }
48 
49 
51 {
52  MHPresentable::Initialise(p, engine);
53  // Original box size - two integer arguments.
54  MHParseNode *pOriginalBox = p->GetNamedArg(C_ORIGINAL_BOX_SIZE);
55 
56  if (! pOriginalBox)
57  {
58  MHParseNode::Failure("OriginalBoxSize missing");
59  }
60  else
61  {
62  m_nOriginalBoxWidth = pOriginalBox->GetArgN(0)->GetIntValue();
63  m_nOriginalBoxHeight = pOriginalBox->GetArgN(1)->GetIntValue();
64  }
65 
66  // Original position - two integer arguments. Optional
67  MHParseNode *pOriginalPos = p->GetNamedArg(C_ORIGINAL_POSITION);
68 
69  if (pOriginalPos)
70  {
71  m_nOriginalPosX = pOriginalPos->GetArgN(0)->GetIntValue();
72  m_nOriginalPosY = pOriginalPos->GetArgN(1)->GetIntValue();
73  }
74 
75  // OriginalPalette ref - optional.
76  MHParseNode *pOriginalPaletteRef = p->GetNamedArg(C_ORIGINAL_PALETTE_REF);
77 
78  if (pOriginalPaletteRef)
79  {
80  m_OriginalPaletteRef.Initialise(pOriginalPaletteRef->GetArgN(0), engine);
81  }
82 }
83 
84 void MHVisible::PrintMe(FILE *fd, int nTabs) const
85 {
86  MHPresentable::PrintMe(fd, nTabs);
87  PrintTabs(fd, nTabs);
88  fprintf(fd, ":OrigBoxSize %d %d\n", m_nOriginalBoxWidth, m_nOriginalBoxHeight);
89 
90  if (m_nOriginalPosX != 0 || m_nOriginalPosY != 0)
91  {
92  PrintTabs(fd, nTabs);
93  fprintf(fd, ":OrigPosition %d %d\n", m_nOriginalPosX, m_nOriginalPosY);
94  }
95 
97  {
98  PrintTabs(fd, nTabs);
99  fprintf(fd, ":OrigPaletteRef");
100  m_OriginalPaletteRef.PrintMe(fd, nTabs + 1);
101  fprintf(fd, "\n");
102  }
103 }
104 
106 {
107  if (m_fAvailable)
108  {
109  return; // Already prepared
110  }
111 
117  // Add a reference to this to the display stack.
118  engine->AddToDisplayStack(this);
120 }
121 
123 {
124  engine->RemoveFromDisplayStack(this);
126 }
127 
129 {
130  if (m_fRunning)
131  {
132  return;
133  }
134 
135  MHIngredient::Activation(engine);
136  m_fRunning = true;
137  engine->Redraw(GetVisibleArea()); // Display the visible.
138  engine->EventTriggered(this, EventIsRunning);
139 }
140 
142 {
143  if (! m_fRunning)
144  {
145  return;
146  }
147 
148  // Stop displaying. We need to save the area before we turn off m_fRunning but
149  // only call Redraw once this is no longer visible so that the area beneath will be drawn.
150  QRegion region = GetVisibleArea();
152  engine->Redraw(region); // Draw underlying object.
153 }
154 
155 // Return the colour, looking up in the palette if necessary. Used by the sub-classes
157 {
158  int red = 0, green = 0, blue = 0, alpha = 0;
159  if (colour.IsSet())
160  {
161  int cSize = colour.m_ColStr.Size();
162 
163  if (cSize != 4)
164  {
165  MHLOG(MHLogWarning, QString("Colour string has length %1 not 4.").arg(cSize));
166  }
167 
168  // Just in case the length is short we handle those properly.
169  if (cSize > 0)
170  {
171  red = colour.m_ColStr.GetAt(0);
172  }
173 
174  if (cSize > 1)
175  {
176  green = colour.m_ColStr.GetAt(1);
177  }
178 
179  if (cSize > 2)
180  {
181  blue = colour.m_ColStr.GetAt(2);
182  }
183 
184  if (cSize > 3)
185  {
186  alpha = 255 - colour.m_ColStr.GetAt(3); // Convert transparency to alpha
187  }
188  }
189 
190  return {red, green, blue, alpha};
191 }
192 
193 // Get the visible region of this visible. This is the area that needs to be drawn.
195 {
196  if (! m_fRunning)
197  {
198  return QRegion(); // Not visible at all.
199  }
200  return QRegion(QRect(m_nPosX, m_nPosY, m_nBoxWidth, m_nBoxHeight));
201 }
202 
203 // MHEG actions.
204 void MHVisible::SetPosition(int nXPosition, int nYPosition, MHEngine *engine)
205 {
206  // When we move a visible we have to redraw both the old area and the new.
207  // In some cases, such as moving an opaque rectangle we might be able to reduce
208  // this if there is some overlap.
209  QRegion drawRegion = GetVisibleArea();
210  m_nPosX = nXPosition;
211  m_nPosY = nYPosition;
212  drawRegion += GetVisibleArea();
213  engine->Redraw(drawRegion);
214 }
215 
216 void MHVisible::GetPosition(MHRoot *pXPosN, MHRoot *pYPosN)
217 {
218  pXPosN->SetVariableValue(m_nPosX);
219  pYPosN->SetVariableValue(m_nPosY);
220 }
221 
222 void MHVisible::SetBoxSize(int nWidth, int nHeight, MHEngine *engine)
223 {
224  QRegion drawRegion = GetVisibleArea();
225  m_nBoxWidth = nWidth;
226  m_nBoxHeight = nHeight;
227  drawRegion += GetVisibleArea();
228  engine->Redraw(drawRegion);
229 }
230 
231 void MHVisible::GetBoxSize(MHRoot *pWidthDest, MHRoot *pHeightDest)
232 {
233  pWidthDest->SetVariableValue(m_nBoxWidth);
234  pHeightDest->SetVariableValue(m_nBoxHeight);
235 }
236 
237 void MHVisible::SetPaletteRef(const MHObjectRef newPalette, MHEngine *engine)
238 {
239  m_PaletteRef.Copy(newPalette);
240  engine->Redraw(GetVisibleArea());
241 }
242 
244 {
245  engine->BringToFront(this);
246 }
247 
249 {
250  engine->SendToBack(this);
251 }
252 
253 void MHVisible::PutBefore(const MHRoot *pRef, MHEngine *engine)
254 {
255  engine->PutBefore(this, pRef);
256 }
257 
258 void MHVisible::PutBehind(const MHRoot *pRef, MHEngine *engine)
259 {
260  engine->PutBehind(this, pRef);
261 }
262 
263 // Copy constructor for cloning
265 {
272  m_LineStyle = ref.m_LineStyle;
273 }
274 
276 {
277  MHVisible::Initialise(p, engine);
278  // Bordered bounding box - optional
280 
281  if (pBBBox)
282  {
283  m_fBorderedBBox = pBBBox->GetArgN(0)->GetBoolValue();
284  }
285 
286  // Original line width
288 
289  if (pOlw)
290  {
292  }
293 
294  // Original line style. This is an integer not an enum.
296 
297  if (pOls)
298  {
300  }
301 
302  // Line colour.
304 
305  if (pOrlc)
306  {
307  m_OrigLineColour.Initialise(pOrlc->GetArgN(0), engine);
308  }
309 
310  // Fill colour
312 
313  if (pOrfc)
314  {
315  m_OrigFillColour.Initialise(pOrfc->GetArgN(0), engine);
316  }
317 }
318 
319 void MHLineArt::PrintMe(FILE *fd, int nTabs) const
320 {
321  MHVisible::PrintMe(fd, nTabs);
322 
323  if (! m_fBorderedBBox)
324  {
325  PrintTabs(fd, nTabs);
326  fprintf(fd, ":BBBox false\n");
327  }
328 
329  if (m_nOriginalLineWidth != 1)
330  {
331  PrintTabs(fd, nTabs);
332  fprintf(fd, ":OrigLineWidth %d\n", m_nOriginalLineWidth);
333  }
334 
336  {
337  PrintTabs(fd, nTabs);
338  fprintf(fd, ":OrigLineStyle %d\n", m_OriginalLineStyle);
339  }
340 
341  if (m_OrigLineColour.IsSet())
342  {
343  PrintTabs(fd, nTabs);
344  fprintf(fd, ":OrigRefLineColour ");
345  m_OrigLineColour.PrintMe(fd, nTabs + 1);
346  fprintf(fd, "\n");
347  }
348 
349  if (m_OrigFillColour.IsSet())
350  {
351  PrintTabs(fd, nTabs);
352  fprintf(fd, ":OrigRefFillColour ");
353  m_OrigFillColour.PrintMe(fd, nTabs + 1);
354  fprintf(fd, "\n");
355  }
356 }
357 
359 {
360  if (m_fAvailable)
361  {
362  return; // Already prepared
363  }
364 
365  // Set up the internal attributes.
368 
369  if (m_OrigLineColour.IsSet())
370  {
372  }
373  else
374  {
375  m_LineColour.SetFromString("\000\000\000\000", 4); // Default is black
376  }
377 
378  if (m_OrigFillColour.IsSet())
379  {
381  }
382  else
383  {
384  m_FillColour.SetFromString("\000\000\000\377", 4); // Default is transparent
385  }
386 
387  MHVisible::Preparation(engine); // Prepare the base class.
388 }
389 
390 // MHEG Actions.
391 // Set the colours
392 void MHLineArt::SetFillColour(const MHColour &colour, MHEngine *engine)
393 {
394  m_FillColour.Copy(colour);
395  engine->Redraw(GetVisibleArea());
396 }
397 
398 void MHLineArt::SetLineColour(const MHColour &colour, MHEngine *engine)
399 {
400  m_LineColour.Copy(colour);
401  engine->Redraw(GetVisibleArea());
402 }
403 
404 void MHLineArt::SetLineWidth(int nWidth, MHEngine *engine)
405 {
406  m_nLineWidth = nWidth;
407  engine->Redraw(GetVisibleArea());
408 }
409 
410 void MHLineArt::SetLineStyle(int nStyle, MHEngine *engine)
411 {
412  m_LineStyle = nStyle;
413  engine->Redraw(GetVisibleArea());
414 }
415 
416 // The rectangle class doesn't add much to the LineArt class
417 void MHRectangle::PrintMe(FILE *fd, int nTabs) const
418 {
419  PrintTabs(fd, nTabs);
420  fprintf(fd, "{:Rectangle ");
421  MHLineArt::PrintMe(fd, nTabs + 1);
422  PrintTabs(fd, nTabs);
423  fprintf(fd, "}\n");
424 }
425 
426 // If this is opaque it obscures the underlying area.
428 {
429  if (! m_fRunning)
430  {
431  return QRegion();
432  }
433 
434  MHRgba lineColour = GetColour(m_LineColour);
435  MHRgba fillColour = GetColour(m_FillColour);
436 
437  // If the fill is transparent or semi-transparent we return an empty region and
438  // ignore the special case where the surrounding box is opaque.
439  if (fillColour.alpha() != 255)
440  {
441  return QRegion();
442  }
443 
444  if (lineColour.alpha() == 255 || m_nLineWidth == 0)
445  {
446  return QRegion(QRect(m_nPosX, m_nPosY, m_nBoxWidth, m_nBoxHeight));
447  }
448 
449  if (m_nBoxWidth <= 2 * m_nLineWidth || m_nBoxHeight <= 2 * m_nLineWidth)
450  {
451  return QRegion();
452  }
453  return QRegion(QRect(m_nPosX + m_nLineWidth, m_nPosY + m_nLineWidth,
455 }
456 
458 {
459  if (! m_fRunning)
460  {
461  return;
462  }
463 
464  if (m_nBoxWidth == 0 || m_nBoxHeight == 0)
465  {
466  return; // Can't draw zero sized boxes.
467  }
468 
469  // The bounding box is assumed always to be True.
470 
471  MHRgba lineColour = GetColour(m_LineColour);
472  MHRgba fillColour = GetColour(m_FillColour);
473  MHContext *d = engine->GetContext();
474 
475  // Fill the centre.
477  {
478  // If the area is very small but non-empty fill it with the line colour
479  d->DrawRect(m_nPosX, m_nPosY, m_nBoxWidth, m_nBoxHeight, lineColour);
480  }
481  else
482  {
483  d->DrawRect(m_nPosX + m_nLineWidth, m_nPosY + m_nLineWidth,
484  m_nBoxWidth - m_nLineWidth * 2, m_nBoxHeight - m_nLineWidth * 2, fillColour);
485  // Draw the lines round the outside. UK MHEG allows us to treat all line styles as solid.
486  // It isn't clear when we draw dashed and dotted lines what colour to put in the spaces.
487  d->DrawRect(m_nPosX, m_nPosY, m_nBoxWidth, m_nLineWidth, lineColour);
488  d->DrawRect(m_nPosX, m_nPosY + m_nBoxHeight - m_nLineWidth, m_nBoxWidth, m_nLineWidth, lineColour);
489  d->DrawRect(m_nPosX, m_nPosY + m_nLineWidth, m_nLineWidth, m_nBoxHeight - m_nLineWidth * 2, lineColour);
491  m_nLineWidth, m_nBoxHeight - m_nLineWidth * 2, lineColour);
492  }
493 }
494 
495 
497 {
498  // Engine Resp - optional
499  MHParseNode *pEngineResp = p->GetNamedArg(C_ENGINE_RESP);
500 
501  if (pEngineResp)
502  {
503  m_fEngineResp = pEngineResp->GetArgN(0)->GetBoolValue();
504  }
505 
506  // Highlight colour.
508 
509  if (phlCol)
510  {
511  m_highlightRefColour.Initialise(phlCol->GetArgN(0), engine);
512  }
513  else
514  {
516  }
517 
518  m_fHighlightStatus = false;
519  m_fInteractionStatus = false;
520 }
521 
522 void MHInteractible::PrintMe(FILE *fd, int nTabs) const
523 {
524  if (! m_fEngineResp)
525  {
526  PrintTabs(fd, nTabs);
527  fprintf(fd, ":EngineResp false\n");
528  }
529 
531  {
532  PrintTabs(fd, nTabs);
533  fprintf(fd, ":HighlightRefColour ");
534  m_highlightRefColour.PrintMe(fd, nTabs + 1);
535  fprintf(fd, "\n");
536  }
537 }
538 
540 {
541  m_fInteractionStatus = true;
542  engine->SetInteraction(this);
543  // The MHEG standard says: "generate visual feedback" here
544  // but it appears that any visual feedback is controlled only
545  // by the highlight status combined with engine-resp.
546 }
547 
549 {
550  if (newStatus) // Turning interaction on.
551  {
552  if (engine->GetInteraction() == nullptr) // No current interactible
553  {
554  Interaction(engine); // virtual function
555  }
556  }
557  else // Turning interaction off.
558  {
560  {
561  m_fInteractionStatus = false;
562  engine->SetInteraction(nullptr);
563  InteractionCompleted(engine); // Interaction is interrupted.
565  }
566  }
567 }
568 
570 {
571  if (newStatus == m_fHighlightStatus)
572  {
573  return;
574  }
575 
576  m_fHighlightStatus = newStatus;
577 
578  // If active redraw to show change of status.
580  {
581  engine->Redraw(m_parent->GetVisibleArea());
582  }
583 
584  // Generate the event for the change of highlight status.
586 }
587 
589 {
590  MHVisible::Initialise(p, engine);
591  MHInteractible::Initialise(p, engine);
592  //
593  MHParseNode *pOrientation = p->GetNamedArg(C_ORIENTATION);
594 
595  if (pOrientation)
596  {
597  m_orientation = (enum SliderOrientation)pOrientation->GetArgN(0)->GetEnumValue();
598  }
599 
600  // This is not optional.
601 
602  MHParseNode *pMin = p->GetNamedArg(C_MIN_VALUE);
603 
604  if (pMin)
605  {
606  m_orig_min_value = pMin->GetArgN(0)->GetIntValue();
607  }
608  else
609  {
610  m_orig_min_value = 1;
611  }
612 
613  MHParseNode *pMax = p->GetNamedArg(C_MAX_VALUE);
614 
615  if (pMax)
616  {
617  m_orig_max_value = pMax->GetArgN(0)->GetIntValue();
618  }
619  else
620  {
621  m_orig_max_value = m_orig_min_value - 1; // Unset
622  }
623 
625 
626  if (pInit)
627  {
628  m_initial_value = pInit->GetArgN(0)->GetIntValue();
629  }
630  else
631  {
632  m_initial_value = m_orig_min_value; // Default is m_min_value
633  }
634 
635  MHParseNode *pPortion = p->GetNamedArg(C_INITIAL_PORTION);
636 
637  if (pPortion)
638  {
639  m_initial_portion = pPortion->GetArgN(0)->GetIntValue();
640  }
641  else
642  {
643  m_initial_portion = m_orig_min_value - 1; // Unset
644  }
645 
646  MHParseNode *pStep = p->GetNamedArg(C_STEP_SIZE);
647 
648  if (pStep)
649  {
650  m_orig_step_size = pStep->GetArgN(0)->GetIntValue();
651  }
652  else
653  {
654  m_orig_step_size = 1; // Unset
655  }
656 
657  MHParseNode *pStyle = p->GetNamedArg(C_SLIDER_STYLE);
658 
659  if (pStyle)
660  {
661  m_style = (enum SliderStyle)pStyle->GetArgN(0)->GetEnumValue();
662  }
663  else
664  {
665  m_style = SliderNormal;
666  }
667 
669 
670  if (pslCol)
671  {
672  m_sliderRefColour.Initialise(pslCol->GetArgN(0), engine);
673  }
674  else
675  {
677  }
678 }
679 
680 static const char *rchOrientation[] =
681 {
682  "left", // 1
683  "right",
684  "up",
685  "down" // 4
686 };
687 
688 // Look up the Orientation. Returns zero if it doesn't match. Used in the text parser only.
689 int MHSlider::GetOrientation(const char *str)
690 {
691  for (int i = 0; i < (int)(sizeof(rchOrientation) / sizeof(rchOrientation[0])); i++)
692  {
693  if (strcasecmp(str, rchOrientation[i]) == 0)
694  {
695  return (i + 1); // Numbered from 1
696  }
697  }
698 
699  return 0;
700 }
701 
702 static const char *rchStyle[] =
703 {
704  "normal", // 1
705  "thermometer",
706  "proportional" // 3
707 };
708 
709 int MHSlider::GetStyle(const char *str)
710 {
711  for (int i = 0; i < (int)(sizeof(rchStyle) / sizeof(rchStyle[0])); i++)
712  {
713  if (strcasecmp(str, rchStyle[i]) == 0)
714  {
715  return (i + 1); // Numbered from 1
716  }
717  }
718 
719  return 0;
720 }
721 
722 void MHSlider::PrintMe(FILE *fd, int nTabs) const
723 {
724  PrintTabs(fd, nTabs);
725  fprintf(fd, "{:Slider ");
726  MHVisible::PrintMe(fd, nTabs + 1);
727  MHInteractible::PrintMe(fd, nTabs + 1);
728 
729  PrintTabs(fd, nTabs);
730  fprintf(fd, ":Orientation %s\n", rchOrientation[m_orientation-1]);
731 
733  {
734  PrintTabs(fd, nTabs + 1);
735  fprintf(fd, ":InitialValue %d\n", m_initial_value);
736  }
737 
738  if (m_orig_min_value != 1)
739  {
740  PrintTabs(fd, nTabs + 1);
741  fprintf(fd, ":MinValue %d\n", m_orig_min_value);
742  }
743 
745  {
746  PrintTabs(fd, nTabs + 1);
747  fprintf(fd, ":MaxValue %d\n", m_orig_max_value);
748  }
749 
751  {
752  PrintTabs(fd, nTabs + 1);
753  fprintf(fd, ":InitialPortion %d\n", m_initial_portion);
754  }
755 
756  if (m_orig_step_size != 1)
757  {
758  PrintTabs(fd, nTabs + 1);
759  fprintf(fd, ":StepSize %d\n", m_orig_step_size);
760  }
761 
762  if (m_style != SliderNormal)
763  {
764  PrintTabs(fd, nTabs + 1);
765  fprintf(fd, ":SliderStyle %s\n", rchStyle[m_style-1]);
766  }
767 
768  if (m_sliderRefColour.IsSet())
769  {
770  PrintTabs(fd, nTabs + 1);
771  fprintf(fd, ":SliderRefColour ");
772  m_sliderRefColour.PrintMe(fd, nTabs + 2);
773  fprintf(fd, "\n");
774  }
775 
776  PrintTabs(fd, nTabs);
777  fprintf(fd, "}\n");
778 }
779 
780 // The MHEG standard doesn't define where the internal values are
781 // initialised. Assume it's during preparation.
783 {
784  MHVisible::Preparation(engine);
790 }
791 
793 {
794  MHContext *d = engine->GetContext();
795  MHRgba colour;
796 
798  {
800  }
801  else
802  {
803  colour = GetColour(m_sliderRefColour);
804  }
805 
806  int major = m_nBoxHeight; // Direction of change.
807  if (m_orientation == SliderLeft || m_orientation == SliderRight)
808  major = m_nBoxWidth;
809 
810  if (m_max_value <= m_min_value)
811  {
812  return; // Avoid divide by zero if error.
813  }
814 
815  if (m_style == SliderNormal)
816  {
817  // This is drawn as a 9 pixel wide "thumb" at the position.
818  major -= 9; // Width of "thumb"
819  int posn = major * (m_slider_value - m_min_value) / (m_max_value - m_min_value);
820 
821  switch (m_orientation)
822  {
823  case SliderLeft:
824  d->DrawRect(m_nPosX + posn, m_nPosY, 9, m_nBoxHeight, colour);
825  break;
826  case SliderRight:
827  d->DrawRect(m_nPosX + m_nBoxWidth - posn - 9, m_nPosY, 9, m_nBoxHeight, colour);
828  break;
829  case SliderUp:
830  d->DrawRect(m_nPosX, m_nPosY + m_nBoxHeight - posn - 9, m_nBoxWidth, 9, colour);
831  break;
832  case SliderDown:
833  d->DrawRect(m_nPosX, m_nPosY + posn, m_nBoxWidth, 9, colour);
834  break;
835  }
836  }
837  else
838  {
839  // Thermometer and proportional sliders are drawn as bars. Thermometers
840  // run from the start to the position, proportional sliders from the
841  // position for the "portion".
842  int start = 0;
843  int end = major * (m_slider_value - m_min_value) / (m_max_value - m_min_value);
844 
845  if (m_style == SliderProp)
846  {
847  start = end;
848  end = major * (m_slider_value + m_portion - m_min_value) / (m_max_value - m_min_value);
849  }
850 
851  switch (m_orientation)
852  {
853  case SliderLeft:
854  d->DrawRect(m_nPosX + start, m_nPosY, end - start, m_nBoxHeight, colour);
855  break;
856  case SliderRight:
857  d->DrawRect(m_nPosX + m_nBoxWidth - end, m_nPosY, end - start, m_nBoxHeight, colour);
858  break;
859  case SliderUp:
860  d->DrawRect(m_nPosX, m_nPosY + m_nBoxHeight - end, m_nBoxWidth, end - start, colour);
861  break;
862  case SliderDown:
863  d->DrawRect(m_nPosX, m_nPosY + start, m_nBoxWidth, end - start, colour);
864  break;
865  }
866 
867  }
868 }
869 
871 {
873  // All the interaction is handled by KeyEvent.
874 }
875 
876 // Called when the interaction has been terminated and we need
877 // to restore the state to non-interacting.
879 {
881  // Redraw with the interaction highlighting turned off
882  engine->Redraw(GetVisibleArea());
883 }
884 
885 // Called when a key is pressed. The only keys that have an effect are
886 // the Select and Cancel keys which both terminate the action and the
887 // arrow keys. The effect of the arrow keys depends on the orientation of
888 // the slider.
889 void MHSlider::KeyEvent(MHEngine *engine, int nCode)
890 {
891  switch (nCode)
892  {
893  case 15: // Select key
894  case 16: // Cancel key
895  m_fInteractionStatus = false;
896  engine->SetInteraction(nullptr);
897  InteractionCompleted(engine); // Interaction is interrupted.
899  break;
900 
901  case 1: // Up
902 
903  if (m_orientation == SliderUp)
904  {
905  Increment(engine);
906  }
907  else if (m_orientation == SliderDown)
908  {
909  Decrement(engine);
910  }
911 
912  break;
913 
914  case 2: // Down
915 
916  if (m_orientation == SliderUp)
917  {
918  Decrement(engine);
919  }
920  else if (m_orientation == SliderDown)
921  {
922  Increment(engine);
923  }
924 
925  break;
926 
927  case 3: // Left
928 
929  if (m_orientation == SliderLeft)
930  {
931  Increment(engine);
932  }
933  else if (m_orientation == SliderRight)
934  {
935  Decrement(engine);
936  }
937 
938  break;
939 
940  case 4: // Right
941 
942  if (m_orientation == SliderLeft)
943  {
944  Decrement(engine);
945  }
946  else if (m_orientation == SliderRight)
947  {
948  Increment(engine);
949  }
950 
951  break;
952 
953  }
954 }
955 
957 {
959  {
961  engine->Redraw(GetVisibleArea());
963  }
964 }
965 
967 {
969  {
971  engine->Redraw(GetVisibleArea());
973  }
974 }
975 
976 void MHSlider::Step(int nbSteps, MHEngine *engine)
977 {
978  m_step_size = nbSteps;
979 
980  if (m_fRunning)
981  {
982  engine->Redraw(GetVisibleArea());
983  }
984 
986 }
987 
988 void MHSlider::SetSliderValue(int newValue, MHEngine *engine)
989 {
990  m_slider_value = newValue;
991 
992  if (m_fRunning)
993  {
994  engine->Redraw(GetVisibleArea());
995  }
996 
998 }
999 
1000 void MHSlider::SetPortion(int newPortion, MHEngine *engine)
1001 {
1002  m_portion = newPortion;
1003 
1004  if (m_fRunning)
1005  {
1006  engine->Redraw(GetVisibleArea());
1007  }
1008 
1009  engine->EventTriggered(this, EventSliderValueChanged);
1010 }
1011 
1012 // Additional action defined in UK MHEG.
1013 void MHSlider::SetSliderParameters(int newMin, int newMax, int newStep, MHEngine *engine)
1014 {
1015  m_min_value = newMin;
1016  m_max_value = newMax;
1017  m_step_size = newStep;
1018  m_slider_value = newMin;
1019 
1020  if (m_fRunning)
1021  {
1022  engine->Redraw(GetVisibleArea());
1023  }
1024 
1025  engine->EventTriggered(this, EventSliderValueChanged);
1026 }
1027 
1028 
1030 {
1031  MHVisible::Initialise(p, engine);
1032  MHInteractible::Initialise(p, engine);
1033  //
1034 }
1035 
1036 void MHEntryField::PrintMe(FILE *fd, int nTabs) const
1037 {
1038  PrintTabs(fd, nTabs);
1039  fprintf(fd, "{:EntryField ");
1040  MHVisible::PrintMe(fd, nTabs + 1);
1041  MHInteractible::PrintMe(fd, nTabs);
1042  fprintf(fd, "****TODO\n");
1043  PrintTabs(fd, nTabs);
1044  fprintf(fd, "}\n");
1045 }
1046 
1048 {
1049  MHVisible::Initialise(p, engine);
1050  //
1051 }
1052 
1053 void MHButton::PrintMe(FILE *fd, int nTabs) const
1054 {
1055  MHVisible::PrintMe(fd, nTabs);
1056  //
1057 }
1058 
1060 {
1061  MHButton::Initialise(p, engine);
1062  //
1063 }
1064 
1065 void MHHotSpot::PrintMe(FILE *fd, int nTabs) const
1066 {
1067  PrintTabs(fd, nTabs);
1068  fprintf(fd, "{:Hotspot ");
1069  MHButton::PrintMe(fd, nTabs + 1);
1070  fprintf(fd, "****TODO\n");
1071  PrintTabs(fd, nTabs);
1072  fprintf(fd, "}\n");
1073 }
1074 
1076 {
1077  MHButton::Initialise(p, engine);
1078  //
1079 }
1080 
1081 void MHPushButton::PrintMe(FILE *fd, int nTabs) const
1082 {
1083  PrintTabs(fd, nTabs);
1084  fprintf(fd, "{:PushButton ");
1085  MHButton::PrintMe(fd, nTabs + 1);
1086  fprintf(fd, "****TODO\n");
1087  PrintTabs(fd, nTabs);
1088  fprintf(fd, "}\n");
1089 }
1090 
1092 {
1093  MHPushButton::Initialise(p, engine);
1094  //
1095 }
1096 
1097 void MHSwitchButton::PrintMe(FILE *fd, int nTabs) const
1098 {
1099  PrintTabs(fd, nTabs);
1100  fprintf(fd, "{:SwitchButton ");
1101  MHPushButton::PrintMe(fd, nTabs + 1);
1102  fprintf(fd, "****TODO\n");
1103  PrintTabs(fd, nTabs);
1104  fprintf(fd, "}\n");
1105 }
1106 
1107 
1109 {
1110  MHElemAction::Initialise(p, engine);
1111 
1112  if (p->GetArgCount() > 1)
1113  {
1114  MHParseNode *pIndexed = p->GetNamedArg(C_NEW_COLOUR_INDEX);
1116 
1117  if (pIndexed)
1118  {
1120  m_Indexed.Initialise(pIndexed->GetArgN(0), engine);
1121  }
1122  else if (pAbsolute)
1123  {
1125  m_Absolute.Initialise(pAbsolute->GetArgN(0), engine);
1126  }
1127  }
1128 }
1129 
1130 void MHSetColour::PrintArgs(FILE *fd, int /*nTabs*/) const
1131 {
1132  if (m_ColourType == CT_Indexed)
1133  {
1134  fprintf(fd, ":NewColourIndex ");
1135  m_Indexed.PrintMe(fd, 0);
1136  }
1137  else if (m_ColourType == CT_Absolute)
1138  {
1139  fprintf(fd, ":NewAbsoluteColour ");
1140  m_Absolute.PrintMe(fd, 0);
1141  }
1142 }
1143 
1145 {
1146  MHObjectRef target;
1147  m_Target.GetValue(target, engine); // Get the item to set.
1148  MHColour newColour;
1149 
1150  switch (m_ColourType)
1151  {
1152  case CT_None:
1153  {
1154  // If the colour is not specified use "transparent".
1155  newColour.SetFromString("\000\000\000\377", 4);
1156  break;
1157  }
1158  case CT_Absolute:
1159  {
1160  MHOctetString colour;
1161  m_Absolute.GetValue(colour, engine);
1162  newColour.m_ColStr.Copy(colour);
1163  break;
1164  }
1165  case CT_Indexed:
1166  newColour.m_nColIndex = m_Indexed.GetValue(engine);
1167  }
1168 
1169  SetColour(newColour, engine); // Set the colour of the appropriate portion of the visible
1170 }
void GetPosition(MHRoot *pXPosN, MHRoot *pYPosN) override
Definition: Visible.cpp:216
#define C_ORIGINAL_PALETTE_REF
Definition: ASN1Codes.h:111
static void Failure(const char *p)
Definition: ParseNode.cpp:43
void Preparation(MHEngine *engine) override
void SetPaletteRef(const MHObjectRef newPalette, MHEngine *engine) override
Definition: Visible.cpp:237
void Initialise(MHParseNode *p, MHEngine *engine)
enum MHSlider::SliderStyle SliderNormal
virtual void InteractionCompleted(MHEngine *)
Definition: Visible.h:152
MHVisible()=default
virtual void Interaction(MHEngine *engine)
Definition: Visible.cpp:539
#define C_INITIAL_PORTION
Definition: ASN1Codes.h:139
void PrintMe(FILE *fd, int nTabs) const override
bool m_fInteractionStatus
Definition: Visible.h:168
void AddToDisplayStack(MHVisible *pVis)
Definition: Engine.cpp:734
void KeyEvent(MHEngine *engine, int nCode) override
Definition: Visible.cpp:889
MHColour m_OrigFillColour
Definition: Visible.h:114
bool IsSet() const
Definition: BaseClasses.h:161
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Visible.cpp:1029
void BringToFront(MHEngine *engine) override
Definition: Visible.cpp:243
void PrintMe(FILE *fd, int nTabs) const
static int GetStyle(const char *str)
Definition: Visible.cpp:709
void SetLineStyle(int nStyle, MHEngine *engine) override
Definition: Visible.cpp:410
void Initialise(MHParseNode *p, MHEngine *engine)
Definition: Visible.cpp:496
int m_orig_max_value
Definition: Visible.h:226
int m_nOriginalPosX
Definition: Visible.h:75
void PrintMe(FILE *fd, int nTabs) const
QRegion GetOpaqueArea() override
Definition: Visible.cpp:427
void SetSliderValue(int newValue, MHEngine *engine) override
Definition: Visible.cpp:988
#define C_MAX_VALUE
Definition: ASN1Codes.h:136
static const char * rchOrientation[]
Definition: Visible.cpp:680
virtual void SetVariableValue(const MHUnion &)
Definition: Root.h:101
MHGenericObjectRef m_Target
Definition: BaseActions.h:46
void RemoveFromDisplayStack(MHVisible *pVis)
Definition: Engine.cpp:746
void Deactivation(MHEngine *engine) override
Definition: Visible.cpp:141
#define C_INITIAL_VALUE
Definition: ASN1Codes.h:138
#define C_ORIGINAL_LINE_STYLE
Definition: ASN1Codes.h:116
bool IsSet() const
Definition: BaseClasses.h:141
void Decrement(MHEngine *engine)
Definition: Visible.cpp:966
void InteractSetInteractionStatus(bool newStatus, MHEngine *engine)
Definition: Visible.cpp:548
void SetPortion(int newPortion, MHEngine *engine) override
Definition: Visible.cpp:1000
void PrintMe(FILE *fd, int nTabs) const override
Definition: Visible.cpp:84
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Visible.cpp:1075
virtual void Activation(MHEngine *engine)
Definition: Root.cpp:69
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Visible.cpp:1047
virtual bool GetRunningStatus()
Definition: Root.h:76
int m_nBoxWidth
Definition: Visible.h:79
void PutBefore(const MHRoot *pVis, const MHRoot *pRef)
Definition: Engine.cpp:790
MHObjectRef m_PaletteRef
Definition: Visible.h:83
virtual QRegion GetVisibleArea()
Definition: Visible.cpp:194
bool m_fAvailable
Definition: Root.h:207
void SetLineWidth(int nWidth, MHEngine *engine) override
Definition: Visible.cpp:404
int m_nPosY
Definition: Visible.h:82
void GetDefaultSliderRefColour(MHColour &colour)
Definition: Engine.cpp:1411
virtual void Deactivation(MHEngine *engine)
Definition: Root.cpp:85
static MHRgba GetColour(const MHColour &colour)
Definition: Visible.cpp:156
int GetValue(MHEngine *engine) const
int m_min_value
Definition: Visible.h:238
void Copy(const MHObjectRef &objr)
void GetValue(MHOctetString &str, MHEngine *engine) const
void PrintMe(FILE *fd, int nTabs) const override
Definition: Visible.cpp:1036
MHColour m_highlightRefColour
Definition: Visible.h:165
#define C_MIN_VALUE
Definition: ASN1Codes.h:137
unsigned char GetAt(int i) const
Definition: BaseClasses.h:121
int m_orig_min_value
Definition: Visible.h:227
virtual void SetColour(const MHColour &colour, MHEngine *engine)=0
void Copy(const MHColour &col)
static int GetOrientation(const char *str)
Definition: Visible.cpp:689
void Display(MHEngine *) override
Definition: Visible.cpp:792
void SetPosition(int nXPosition, int nYPosition, MHEngine *engine) override
Definition: Visible.cpp:204
#define C_ORIGINAL_REF_FILL_COLOUR
Definition: ASN1Codes.h:118
MHLineArt()=default
void PrintMe(FILE *fd, int nTabs) const override
Definition: Visible.cpp:1081
void PrintMe(FILE *fd, int nTabs) const override
Definition: Visible.cpp:1097
bool m_fBorderedBBox
Definition: Visible.h:110
void Preparation(MHEngine *engine) override
Definition: Visible.cpp:782
MHContext * GetContext()
Definition: Engine.h:153
void PrintMe(FILE *fd, int nTabs) const override
Definition: Visible.cpp:1053
#define C_NEW_COLOUR_INDEX
Definition: ASN1Codes.h:263
void GetValue(MHObjectRef &ref, MHEngine *engine) const
void SetBoxSize(int nWidth, int nHeight, MHEngine *engine) override
Definition: Visible.cpp:222
void Perform(MHEngine *engine) override
Definition: Visible.cpp:1144
void Initialise(MHParseNode *p, MHEngine *engine)
void Redraw(const QRegion &region)
Definition: Engine.cpp:899
#define C_ORIENTATION
Definition: ASN1Codes.h:135
int m_LineStyle
Definition: Visible.h:117
int m_nOriginalLineWidth
Definition: Visible.h:111
MHColour m_LineColour
Definition: Visible.h:118
void SetFromString(const char *str, int nLen)
void PrintTabs(FILE *fd, int n)
Definition: ParseNode.cpp:34
SliderStyle
Definition: Visible.h:232
void SetFillColour(const MHColour &colour, MHEngine *engine) override
Definition: Visible.cpp:392
void GetDefaultHighlightRefColour(MHColour &colour)
Definition: Engine.cpp:1397
void Copy(const MHOctetString &str)
int m_orig_step_size
Definition: Visible.h:228
#define C_NEW_ABSOLUTE_COLOUR
Definition: ASN1Codes.h:264
int Size() const
Definition: BaseClasses.h:117
int m_nPosX
Definition: Visible.h:81
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Ingredients.cpp:49
int m_portion
Definition: Visible.h:241
int m_nOriginalBoxWidth
Definition: Visible.h:73
static const uint16_t * d
int GetIntValue()
Definition: ParseNode.cpp:170
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Visible.cpp:275
MHColour m_FillColour
Definition: Visible.h:118
void EventTriggered(MHRoot *pSource, enum EventType ev)
Definition: Engine.h:93
void Increment(MHEngine *engine)
Definition: Visible.cpp:956
#define C_ENGINE_RESP
Definition: ASN1Codes.h:134
void Preparation(MHEngine *engine) override
Definition: Visible.cpp:105
MHParseNode * GetNamedArg(int nTag)
Definition: ParseNode.cpp:110
void SetInteraction(MHInteractible *p)
Definition: Engine.h:161
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Visible.cpp:50
MHColour m_sliderRefColour
Definition: Visible.h:234
enum MHSlider::SliderOrientation SliderLeft
MHVisible * m_parent
Definition: Visible.h:171
void Step(int nbSteps, MHEngine *engine) override
Definition: Visible.cpp:976
void PutBehind(const MHRoot *pVis, const MHRoot *pRef)
Definition: Engine.cpp:821
Definition: Root.h:43
void PrintMe(FILE *fd, int nTabs) const
enum MHSetColour::@13 m_ColourType
bool m_fRunning
Definition: Root.h:208
int m_nOriginalPosY
Definition: Visible.h:76
int m_OriginalLineStyle
Definition: Visible.h:113
int FILE
Definition: mythburn.py:110
void Destruction(MHEngine *engine) override
#define C_ORIGINAL_BOX_SIZE
Definition: ASN1Codes.h:109
void PrintMe(FILE *fd, int nTabs) const override
Definition: Visible.cpp:319
int m_initial_value
Definition: Visible.h:224
void SendToBack(MHEngine *engine) override
Definition: Visible.cpp:248
#define C_ORIGINAL_REF_LINE_COLOUR
Definition: ASN1Codes.h:117
int alpha() const
Definition: freemheg.h:85
void SetLineColour(const MHColour &colour, MHEngine *engine) override
Definition: Visible.cpp:398
int m_max_value
Definition: Visible.h:237
#define C_STEP_SIZE
Definition: ASN1Codes.h:140
int m_initial_portion
Definition: Visible.h:225
int m_nColIndex
Definition: BaseClasses.h:145
void Initialise(MHParseNode *p, MHEngine *engine)
MHObjectRef m_OriginalPaletteRef
Definition: Visible.h:77
int GetEnumValue()
Definition: ParseNode.cpp:181
void GetBoxSize(MHRoot *pWidthDest, MHRoot *pHeightDest) override
Definition: Visible.cpp:231
void Display(MHEngine *engine) override
Definition: Visible.cpp:457
#define MHLOG(__level, __text)
Definition: Logging.h:36
virtual void Initialise(MHParseNode *p, MHEngine *engine)
Definition: BaseActions.cpp:31
#define C_BORDERED_BOUNDING_BOX
Definition: ASN1Codes.h:114
void InteractionCompleted(MHEngine *engine) override
Definition: Visible.cpp:878
int GetArgCount()
Definition: ParseNode.cpp:60
void PrintMe(FILE *fd, int nTabs) const override
Definition: Visible.cpp:722
bool GetBoolValue()
Definition: ParseNode.cpp:192
void BringToFront(const MHRoot *pVis)
Definition: Engine.cpp:760
void PrintMe(FILE *fd, int nTabs) const override
Definition: Visible.cpp:417
void Initialise(MHParseNode *p, MHEngine *engine)
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Visible.cpp:588
SliderOrientation
Definition: Visible.h:222
MHColour m_OrigLineColour
Definition: Visible.h:114
static const char * rchStyle[]
Definition: Visible.cpp:702
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Visible.cpp:1059
void Interaction(MHEngine *engine) override
Definition: Visible.cpp:870
MHParseNode * GetArgN(int n)
Definition: ParseNode.cpp:78
void PrintMe(FILE *fd, int nTabs) const override
Definition: Visible.cpp:1065
void SetSliderParameters(int newMin, int newMax, int newStep, MHEngine *engine) override
Definition: Visible.cpp:1013
int m_step_size
Definition: Visible.h:239
MHInteractible * GetInteraction(void)
Definition: Engine.h:160
void Preparation(MHEngine *engine) override
Definition: Visible.cpp:358
void Destruction(MHEngine *engine) override
Definition: Visible.cpp:122
bool m_fEngineResp
Definition: Visible.h:164
void Activation(MHEngine *engine) override
Definition: Visible.cpp:128
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Visible.cpp:1108
#define C_ORIGINAL_POSITION
Definition: ASN1Codes.h:110
#define C_SLIDER_REF_COLOUR
Definition: ASN1Codes.h:83
bool m_fHighlightStatus
Definition: Visible.h:167
#define C_SLIDER_STYLE
Definition: ASN1Codes.h:141
#define C_ORIGINAL_LINE_WIDTH
Definition: ASN1Codes.h:115
void InteractSetHighlightStatus(bool newStatus, MHEngine *engine)
Definition: Visible.cpp:569
int m_nLineWidth
Definition: Visible.h:116
int m_nBoxHeight
Definition: Visible.h:80
void SendToBack(const MHRoot *pVis)
Definition: Engine.cpp:775
#define C_HIGHLIGHT_REF_COLOUR
Definition: ASN1Codes.h:82
void PutBefore(const MHRoot *pRef, MHEngine *engine) override
Definition: Visible.cpp:253
void PrintMe(FILE *fd, int nTabs) const
void PrintArgs(FILE *fd, int nTabs) const override
Definition: Visible.cpp:1130
MHGenericOctetString m_Absolute
Definition: Visible.h:334
MHGenericInteger m_Indexed
Definition: Visible.h:333
void PrintMe(FILE *fd, int nTabs) const
Definition: Visible.cpp:522
MHOctetString m_ColStr
Definition: BaseClasses.h:144
void PutBehind(const MHRoot *pRef, MHEngine *engine) override
Definition: Visible.cpp:258
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Visible.cpp:1091
int m_slider_value
Definition: Visible.h:240
int m_nOriginalBoxHeight
Definition: Visible.h:74