MythTV  0.27pre
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
mythuitype.cpp
Go to the documentation of this file.
1 
2 // Own header
3 #include "mythuitype.h"
4 
5 // QT headers
6 #include <QEvent>
7 #include <QKeyEvent>
8 #include <QDomDocument>
9 
10 // Mythdb headers
11 #include "mythlogging.h"
12 
13 // MythUI headers
14 #include "mythgesture.h"
15 #include "mythimage.h"
16 #include "mythpainter.h"
17 #include "mythmainwindow.h"
18 #include "mythfontproperties.h"
19 #include "mythuitext.h"
20 #include "mythuiimage.h"
21 #include "mythuibutton.h"
22 #include "mythuicheckbox.h"
23 #include "mythuibuttonlist.h"
24 #include "mythuitextedit.h"
25 #include "mythuiprogressbar.h"
26 #include "mythuispinbox.h"
27 
28 MythUIType::MythUIType(QObject *parent, const QString &name)
29  : QObject(parent)
30 {
31  setObjectName(name);
32 
33  m_Visible = true;
34  m_Enabled = true;
35  m_EnableInitiator = false;
36  m_Initiator = false;
37  m_Vanish = false;
38  m_Vanished = false;
39  m_CanHaveFocus = m_HasFocus = false;
40  m_Area = MythRect(0, 0, 0, 0);
41  m_MinArea = MythRect(0, 0, 0, 0);
42  m_NeedsRedraw = false;
44  m_AlphaMax = 255;
45  m_Moving = false;
46  m_XYDestination = QPoint(0, 0);
47  m_XYSpeed = QPoint(0, 0);
48  m_deferload = false;
49  m_IsDependDefault = false;
50  m_ReverseDepend = false;
51 
52  m_Parent = NULL;
53 
54  if (parent)
55  {
56  m_Parent = dynamic_cast<MythUIType *>(parent);
57 
58  if (m_Parent)
59  m_Parent->AddChild(this);
60  }
61 
62  m_DirtyRegion = QRegion(QRect(0, 0, 0, 0));
63 
64  m_Fonts = new FontMap();
65  m_focusOrder = 0;
66  m_Painter = NULL;
67 
68  m_BorderColor = QColor(random() % 255, random() % 255, random() % 255);
69 }
70 
72 {
73  delete m_Fonts;
74  qDeleteAll(m_animations);
75 }
76 
82 {
83  // Reset all children
84  QMutableListIterator<MythUIType *> it(m_ChildrenList);
85 
86  while (it.hasNext())
87  {
88  it.next();
89  MythUIType *type = it.value();
90  type->Reset();
91  }
92 }
93 
98 {
99  if (!child)
100  return;
101 
102  m_ChildrenList.push_back(child);
103 }
104 
105 static QObject *qChildHelper(const char *objName, const char *inheritsClass,
106  bool recursiveSearch, const QObjectList &children)
107 {
108  if (children.isEmpty())
109  return 0;
110 
111  bool onlyWidgets = (inheritsClass
112  && qstrcmp(inheritsClass, "QWidget") == 0);
113  const QLatin1String oName(objName);
114 
115  for (int i = 0; i < children.size(); ++i)
116  {
117  QObject *obj = children.at(i);
118 
119  if (onlyWidgets)
120  {
121  if (obj->isWidgetType() && (!objName || obj->objectName() == oName))
122  return obj;
123  }
124  else if ((!inheritsClass || obj->inherits(inheritsClass))
125  && (!objName || obj->objectName() == oName))
126  return obj;
127 
128  if (recursiveSearch && (dynamic_cast<MythUIGroup *>(obj) != NULL)
129  && (obj = qChildHelper(objName, inheritsClass,
130  recursiveSearch,
131  obj->children())))
132  return obj;
133  }
134 
135  return 0;
136 }
137 
144 MythUIType *MythUIType::GetChild(const QString &name) const
145 {
146  QObject *ret = qChildHelper(name.toLatin1().constData(), NULL, true, children());
147 
148  if (ret)
149  return dynamic_cast<MythUIType *>(ret);
150 
151  return NULL;
152 }
153 
159 void MythUIType::DeleteChild(const QString &name)
160 {
161  QMutableListIterator<MythUIType *> it(m_ChildrenList);
162 
163  while (it.hasNext())
164  {
165  it.next();
166  MythUIType *type = it.value();
167 
168  if (type->objectName() == name)
169  {
170  delete type;
171  it.remove();
172  return;
173  }
174  }
175 }
176 
184 {
185  QMutableListIterator<MythUIType *> it(m_ChildrenList);
186 
187  while (it.hasNext())
188  {
189  it.next();
190  MythUIType *type = it.value();
191 
192  if (type == child)
193  {
194  delete type;
195  it.remove();
196  child = NULL;
197  return;
198  }
199  }
200 }
201 
205 QList<MythUIType *> *MythUIType::GetAllChildren(void)
206 {
207  return &m_ChildrenList;
208 }
209 
214 {
215  QList<MythUIType *>::iterator it;
216 
217  for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
218  if (*it)
219  delete *it;
220 
221  m_ChildrenList.clear();
222 }
223 
232 MythUIType *MythUIType::GetChildAt(const QPoint &p, bool recursive,
233  bool focusable) const
234 {
235  if (GetArea().contains(p))
236  {
237  if (!IsVisible() || !IsEnabled())
238  return NULL;
239 
240  if (m_ChildrenList.isEmpty())
241  return NULL;
242 
243  /* check all children */
244  QList<MythUIType *>::const_iterator it;
245 
246  for (it = m_ChildrenList.end() - 1; it != m_ChildrenList.begin() - 1; --it)
247  {
248  if (!(*it))
249  continue;
250 
251  // If this point doesn't fall within the child's area then move on
252  // This requires that the area is actually accurate and in some
253  // cases this still isn't true
254  if (!(*it)->GetArea().contains(p - GetArea().topLeft()))
255  continue;
256 
257 
258  MythUIType *child = *it;
259 
260  if (recursive && (focusable && !child->CanTakeFocus()))
261  child = child->GetChildAt(p - GetArea().topLeft(), recursive,
262  focusable);
263 
264  if (child)
265  {
266  // NOTE: Assumes no selectible ui type will contain another
267  // selectible ui type.
268  if (focusable && !child->CanTakeFocus())
269  continue;
270 
271  return child;
272  }
273  }
274  }
275 
276  return NULL;
277 }
278 
280 {
281  foreach (MythUIAnimation* animation, m_animations)
282  if (animation->GetTrigger() == trigger)
283  animation->Activate();
284 
285  foreach (MythUIType* uiType, m_ChildrenList)
286  uiType->ActivateAnimations(trigger);
287 }
288 
289 bool MythUIType::NeedsRedraw(void) const
290 {
291  return m_NeedsRedraw;
292 }
293 
295 {
296  m_NeedsRedraw = false;
297 
298  QList<MythUIType *>::Iterator it;
299 
300  for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
301  (*it)->ResetNeedsRedraw();
302 }
303 
305 {
306  if (m_Area.width() == 0 || m_Area.height() == 0)
307  return;
308 
309  m_NeedsRedraw = true;
310 
311  if (m_DirtyRegion.isEmpty())
312  m_DirtyRegion = QRegion(m_Area.toQRect());
313  else
314  m_DirtyRegion = m_DirtyRegion.unite(QRegion(m_Area.toQRect()));
315 
316  if (m_Parent)
318 }
319 
321 {
322  QRegion childRegion = child->GetDirtyArea();
323 
324  if (childRegion.isEmpty())
325  return;
326 
327  childRegion.translate(m_Area.x(), m_Area.y());
328 
329  childRegion = childRegion.intersect(m_Area.toQRect());
330 
331  m_NeedsRedraw = true;
332 
333  if (m_DirtyRegion.isEmpty())
334  m_DirtyRegion = childRegion;
335  else
336  m_DirtyRegion = m_DirtyRegion.unite(childRegion);
337 
338  if (m_Parent)
340 }
341 
345 bool MythUIType::CanTakeFocus(void) const
346 {
347  return m_CanHaveFocus;
348 }
349 
354 {
355  m_CanHaveFocus = set;
356 }
357 
364 {
365  if (!GetPainter()->SupportsAnimation())
366  return;
367 
368  if (!m_Moving)
369  return;
370 
371  QPoint curXY = m_Area.topLeft().toQPoint();
373 
374  int xdir = m_XYDestination.x() - curXY.x();
375  int ydir = m_XYDestination.y() - curXY.y();
376 
377  curXY.setX(curXY.x() + m_XYSpeed.x());
378  curXY.setY(curXY.y() + m_XYSpeed.y());
379 
380  if ((xdir > 0 && curXY.x() >= m_XYDestination.x()) ||
381  (xdir < 0 && curXY.x() <= m_XYDestination.x()) ||
382  (xdir == 0))
383  {
384  m_XYSpeed.setX(0);
385  }
386 
387  if ((ydir > 0 && curXY.y() >= m_XYDestination.y()) ||
388  (ydir <= 0 && curXY.y() <= m_XYDestination.y()) ||
389  (ydir == 0))
390  {
391  m_XYSpeed.setY(0);
392  }
393 
394  SetRedraw();
395 
396  if (m_XYSpeed.x() == 0 && m_XYSpeed.y() == 0)
397  {
398  m_Moving = false;
399  emit FinishedMoving();
400  }
401 
402  m_Area.moveTopLeft(curXY);
403 }
404 
411 {
412  if (!GetPainter()->SupportsAlpha() ||
413  !GetPainter()->SupportsAnimation())
414  return;
415 
416  if (m_AlphaChangeMode == 0)
417  return;
418 
420 
421  if (m_Effects.alpha > m_AlphaMax)
423 
424  if (m_Effects.alpha < m_AlphaMin)
426 
427  // Reached limits so change direction
429  {
430  if (m_AlphaChangeMode == 2)
431  {
432  m_AlphaChange *= -1;
433  }
434  else
435  {
436  m_AlphaChangeMode = 0;
437  m_AlphaChange = 0;
438  emit FinishedFading();
439  }
440  }
441 
442  SetRedraw();
443 }
444 
452 {
453  if (!m_Visible || m_Vanished)
454  return;
455 
458 
459  QList<MythUIAnimation*>::Iterator i;
460  for (i = m_animations.begin(); i != m_animations.end(); ++i)
461  (*i)->IncrementCurrentTime();
462 
463  QList<MythUIType *>::Iterator it;
464 
465  for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
466  (*it)->Pulse();
467 }
468 
469 int MythUIType::CalcAlpha(int alphamod)
470 {
471  return (int)(m_Effects.alpha * (alphamod / 255.0));
472 }
473 
474 void MythUIType::DrawSelf(MythPainter *, int, int, int, QRect)
475 {
476 }
477 
478 void MythUIType::Draw(MythPainter *p, int xoffset, int yoffset, int alphaMod,
479  QRect clipRect)
480 {
481  // NB m_DirtyRegion may be extended by HandleMovementPulse, SetRedraw
482  // or SetChildNeedsRedraw etc _AFTER_ GetDirtyArea is called.
483  // So clipRect may not include the whole of m_DirtyRegion
484  m_DirtyRegion -= QRegion(clipRect); // NB Qt >= 4.2
485 
486  if (!m_Visible || m_Vanished)
487  return;
488 
489  QRect realArea = m_Area.toQRect();
490  realArea.translate(xoffset, yoffset);
491 
492  if (!realArea.intersects(clipRect))
493  return;
494 
495  p->PushTransformation(m_Effects, m_Effects.GetCentre(m_Area, xoffset, yoffset));
496 
497  DrawSelf(p, xoffset, yoffset, alphaMod, clipRect);
498 
499  QList<MythUIType *>::Iterator it;
500 
501  for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
502  {
503  (*it)->Draw(p, xoffset + m_Area.x(), yoffset + m_Area.y(),
504  CalcAlpha(alphaMod), clipRect);
505  }
506 
507  if (p->ShowBorders())
508  {
509  static const QBrush nullbrush(Qt::NoBrush);
510  p->DrawRect(realArea, nullbrush, QPen(m_BorderColor), 255);
511 
512  if (p->ShowTypeNames())
513  {
514  MythFontProperties font;
515  font.SetFace(QFont("Droid Sans"));
516  font.SetColor(m_BorderColor);
517  font.SetPointSize(8);
518  p->DrawText(realArea, objectName(), 0, font, 255, realArea);
519  }
520  }
521 
522  p->PopTransformation();
523 }
524 
526 {
527  SetPosition(MythPoint(x, y));
528 }
529 
531 {
532  MythPoint pos(point);
533 
534  if (m_Parent)
536  else
537  pos.CalculatePoint(GetMythMainWindow()->GetUIScreenRect());
538 
539  if (m_Area.topLeft() == pos)
540  return;
541 
542  m_DirtyRegion = QRegion(m_Area.toQRect());
543 
544  m_Area.moveTopLeft(pos);
545 
546  RecalculateArea(false);
547 
548  SetRedraw();
549 }
550 
552 {
553  return m_Area.topLeft();
554 }
555 
556 void MythUIType::SetSize(const QSize &size)
557 {
558  if (size == m_Area.size())
559  return;
560 
561  m_DirtyRegion = QRegion(m_Area.toQRect());
562 
563  m_Area.setSize(size);
564  RecalculateArea();
565 
566  if (m_Parent)
568 
569  SetRedraw();
570 }
571 
577 void MythUIType::SetMinSize(const MythPoint &minsize)
578 {
579  MythPoint point(minsize);
580 
581  if (m_Parent)
583 
584  m_MinSize = point;
585 
586  SetRedraw();
587 }
588 
589 QSize MythUIType::GetMinSize(void) const
590 {
591  if (!m_MinSize.isValid())
592  return m_Area.size();
593 
594  return QSize(m_MinSize.x(), m_MinSize.y());
595 }
596 
597 void MythUIType::SetArea(const MythRect &rect)
598 {
599  if (rect == m_Area)
600  return;
601 
602  m_DirtyRegion = QRegion(m_Area.toQRect());
603 
604  m_Area = rect;
605  RecalculateArea();
606 
607  if (m_Parent)
608  m_Parent->ExpandArea(m_Area.toQRect());
609 
610  SetRedraw();
611 }
612 
616 void MythUIType::AdjustMinArea(int delta_x, int delta_y,
617  int delta_w, int delta_h)
618 {
619  // If a minsize is not set, don't use MinArea
620  if (!m_MinSize.isValid())
621  return;
622 
623  // Delta's are negative values; knock down the area
624  QRect bounded(m_Area.x() - delta_x,
625  m_Area.y() - delta_y,
626  m_Area.width() + delta_w,
627  m_Area.height() + delta_h);
628 
629  // Make sure we have not violated the min size
630  if (!bounded.isNull() || !m_Vanish)
631  {
632  QPoint center = bounded.center();
633 
634  if (bounded.isNull())
635  bounded.setSize(GetMinSize());
636  else
637  bounded.setSize(bounded.size().expandedTo(GetMinSize()));
638 
639  bounded.moveCenter(center);
640  }
641 
642  if (bounded.x() + bounded.width() > m_Area.x() + m_Area.width())
643  bounded.moveRight(m_Area.x() + m_Area.width());
644  if (bounded.y() + bounded.height() > m_Area.y() + m_Area.height())
645  bounded.moveBottom(m_Area.y() + m_Area.height());
646  if (bounded.x() < m_Area.x())
647  {
648  bounded.moveLeft(m_Area.x());
649  if (bounded.width() > m_Area.width())
650  bounded.setWidth(m_Area.width());
651  }
652  if (bounded.y() < m_Area.y())
653  {
654  bounded.moveTop(m_Area.y());
655  if (bounded.height() > m_Area.height())
656  bounded.setHeight(m_Area.height());
657  }
658 
659  m_MinArea = bounded;
660  m_Vanished = false;
661 
662  QList<MythUIType *>::iterator it;
663 
664  for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
665  {
666  if (!(*it)->m_Initiator)
667  (*it)->AdjustMinArea(delta_x, delta_y, delta_w, delta_h);
668  }
669 }
670 
672 {
673  if (!m_MinSize.isValid() || !m_Vanish)
674  return;
675 
676  m_MinArea.moveLeft(0);
677  m_MinArea.moveTop(0);
678  m_MinArea.setWidth(0);
679  m_MinArea.setHeight(0);
680  m_Vanished = true;
681 
682  QList<MythUIType *>::iterator it;
683 
684  for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
685  {
686  if (!(*it)->m_Initiator)
687  (*it)->VanishSibling();
688  }
689 }
690 
694 void MythUIType::SetMinAreaParent(MythRect actual_area, MythRect allowed_area,
695  MythUIType *calling_child)
696 {
697  int delta_x = 0, delta_y = 0, delta_w = 0, delta_h = 0;
698  MythRect area;
699 
700  // If a minsize is not set, don't use MinArea
701  if (!m_MinSize.isValid())
702  return;
703 
704  if (calling_child->m_Vanished)
705  {
706  actual_area.moveLeft(0);
707  actual_area.moveTop(0);
708  allowed_area.moveLeft(0);
709  allowed_area.moveTop(0);
710  }
711 
712  actual_area.translate(m_Area.x(), m_Area.y());
713  allowed_area.translate(m_Area.x(), m_Area.y());
714 
715  QList<MythUIType *>::iterator it;
716 
717  for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
718  {
719  if (*it == calling_child || !(*it)->m_Initiator)
720  continue;
721 
722  if (!(*it)->m_Vanished)
723  {
724  // Find union of area(s)
725  area = (*it)->GetArea();
726  area.translate(m_Area.x(), m_Area.y());
727  actual_area = actual_area.united(area);
728 
729  area = (*it)->m_Area;
730  area.translate(m_Area.x(), m_Area.y());
731  allowed_area = allowed_area.united(area);
732  }
733  }
734 
735  // Make sure it is not larger than the area allowed
736  actual_area = actual_area.intersected(m_Area);
737  allowed_area = allowed_area.intersected(m_Area);
738 
739  if (m_Vanish && actual_area.size().isNull())
740  {
741  m_Vanished = true;
742  }
743  else
744  {
745  if (calling_child->m_Vanished)
746  {
747  delta_x = m_Area.x() - actual_area.x();
748  delta_y = m_Area.y() - actual_area.y();
749  delta_w = actual_area.width() - m_Area.width();
750  delta_h = actual_area.height() - m_Area.height();
751  }
752  else
753  {
754  delta_x = allowed_area.x() - actual_area.x();
755  delta_y = allowed_area.y() - actual_area.y();
756  delta_w = actual_area.width() - allowed_area.width();
757  delta_h = actual_area.height() - allowed_area.height();
758  }
759 
760  m_Vanished = false;
761  }
762 
763  for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
764  {
765  if (*it == calling_child)
766  continue;
767 
768  if (!(*it)->m_Initiator)
769  {
770  if (m_Vanished)
771  (*it)->VanishSibling();
772  else
773  (*it)->AdjustMinArea(delta_x, delta_y, delta_w, delta_h);
774  }
775 
776  area = (*it)->GetArea();
777  area.translate(m_Area.topLeft());
778  actual_area = actual_area.united(area);
779  }
780 
781  if (m_Vanished)
782  {
783  m_MinArea.setRect(0, 0, 0, 0);
784  actual_area.setRect(0, 0, 0, 0);
785  }
786  else
787  {
788  QSize bound(actual_area.width(), actual_area.height());
789 
790  bound = bound.expandedTo(GetMinSize());
791  m_MinArea.setRect(actual_area.x(),
792  actual_area.y(),
793  actual_area.x() + bound.width(),
794  actual_area.y() + bound.height());
795  }
796 
797  if (m_Parent)
798  m_Parent->SetMinAreaParent(actual_area, m_Area, this);
799 }
800 
805 {
806  // If a minsize is not set, don't use MinArea
807  if (!m_Initiator || !m_MinSize.isValid())
808  return;
809 
810  QRect bounded(rect);
811  bool vanish = (m_Vanish && rect.isNull());
812 
813  if (vanish)
814  {
815  bounded.moveLeft(0);
816  bounded.moveTop(0);
817  }
818  else
819  {
820  QPoint center = bounded.center();
821 
822  if (bounded.isNull())
823  bounded.setSize(GetMinSize());
824  else
825  bounded.setSize(bounded.size().expandedTo(GetMinSize()));
826 
827  bounded.moveCenter(center);
828  if (bounded.x() + bounded.width() > m_Area.x() + m_Area.width())
829  bounded.moveRight(m_Area.x() + m_Area.width());
830  if (bounded.y() + bounded.height() > m_Area.y() + m_Area.height())
831  bounded.moveBottom(m_Area.y() + m_Area.height());
832  if (bounded.x() < m_Area.x())
833  {
834  bounded.moveLeft(m_Area.x());
835  if (bounded.width() > m_Area.width())
836  bounded.setWidth(m_Area.width());
837  }
838  if (bounded.y() < m_Area.y())
839  {
840  bounded.moveTop(m_Area.y());
841  if (bounded.height() > m_Area.height())
842  bounded.setHeight(m_Area.height());
843  }
844  }
845 
846  m_MinArea = bounded;
847  m_Vanished = vanish;
848 
849  if (m_Parent)
851 }
852 
854 {
855  QSize childSize = rect.size();
856  QSize size = m_Area.size();
857 
858  if (childSize == size)
859  return;
860 
861  SetSize(size.expandedTo(childSize));
862  SetRedraw();
863 }
864 
870 {
871  if (m_Vanished || m_MinArea.isValid())
872  return m_MinArea;
873 
874  return m_Area;
875 }
876 
878 {
879  return m_Area;
880 }
881 
882 QRegion MythUIType::GetDirtyArea(void) const
883 {
884  return m_DirtyRegion;
885 }
886 
887 bool MythUIType::IsVisible(bool recurse) const
888 {
889  if (recurse)
890  {
891  if (m_Parent && !m_Parent->IsVisible(recurse))
892  return false;
893  }
894 
895  return m_Visible;
896 }
897 
898 void MythUIType::MoveTo(QPoint destXY, QPoint speedXY)
899 {
900  if (!GetPainter()->SupportsAnimation())
901  return;
902 
903  if (destXY.x() == m_Area.x() && destXY.y() == m_Area.y())
904  return;
905 
906  m_Moving = true;
907 
908  m_XYDestination = destXY;
909  m_XYSpeed = speedXY;
910 }
911 
912 void MythUIType::AdjustAlpha(int mode, int alphachange, int minalpha,
913  int maxalpha)
914 {
915  if (!GetPainter()->SupportsAlpha())
916  return;
917 
919  m_AlphaChange = alphachange;
920  m_AlphaMin = minalpha;
921  m_AlphaMax = maxalpha;
922 
923  if (m_Effects.alpha > m_AlphaMax)
925 
926  if (m_Effects.alpha < m_AlphaMin)
928 }
929 
930 void MythUIType::SetAlpha(int newalpha)
931 {
932  if (m_Effects.alpha == newalpha)
933  return;
934 
935  m_Effects.alpha = newalpha;
936  SetRedraw();
937 }
938 
939 int MythUIType::GetAlpha(void) const
940 {
941  return m_Effects.alpha;
942 }
943 
945 {
946  m_Effects.centre = centre;
947 }
948 
949 void MythUIType::SetZoom(float zoom)
950 {
951  SetHorizontalZoom(zoom);
952  SetVerticalZoom(zoom);
953 }
954 
956 {
957  m_Effects.hzoom = zoom;
958  SetRedraw();
959 }
960 
962 {
963  m_Effects.vzoom = zoom;
964  SetRedraw();
965 }
966 
967 void MythUIType::SetAngle(float angle)
968 {
969  m_Effects.angle = angle;
970  SetRedraw();
971 }
972 
977 bool MythUIType::keyPressEvent(QKeyEvent *)
978 {
979  return false;
980 }
981 
982 
984 {
985  return;
986 }
987 
994 {
995  return false;
996 }
997 
1003 {
1004  return;
1005 }
1006 
1008 {
1009  if (!m_CanHaveFocus || !m_HasFocus)
1010  return;
1011 
1012  emit LosingFocus();
1013  m_HasFocus = false;
1014  Refresh();
1015 }
1016 
1018 {
1019  if (!m_CanHaveFocus || m_HasFocus)
1020  return false;
1021 
1022  m_HasFocus = true;
1023  Refresh();
1024  emit TakingFocus();
1025  return true;
1026 }
1027 
1029 {
1030 }
1031 
1033 {
1034  SetRedraw();
1035 }
1036 
1037 void MythUIType::UpdateDependState(bool isDefault)
1038 {
1039  m_IsDependDefault = m_ReverseDepend ? !isDefault : isDefault;
1040 
1042 }
1043 
1044 void MythUIType::SetVisible(bool visible)
1045 {
1046  if (visible == m_Visible)
1047  return;
1048 
1049  if (visible && m_IsDependDefault)
1050  return;
1051 
1052  m_Visible = visible;
1053  SetRedraw();
1054 
1055  if (m_Visible)
1056  emit Showing();
1057  else
1058  emit Hiding();
1059 }
1060 
1062 {
1063  m_IsDependDefault = isDefault;
1064 }
1065 
1066 void MythUIType::SetEnabled(bool enable)
1067 {
1068  if (m_Enabled != enable)
1069  m_Enabled = enable;
1070 
1071  if (enable)
1072  emit Enabling();
1073  else
1074  emit Disabling();
1075 }
1076 
1078 {
1079  SetVisible(false);
1080 }
1081 
1083 {
1084  SetVisible(true);
1085 }
1086 
1087 void MythUIType::AddFocusableChildrenToList(QMap<int, MythUIType *> &focusList)
1088 {
1089  if (m_CanHaveFocus)
1090  focusList.insertMulti(m_focusOrder, this);
1091 
1092  QList<MythUIType *>::Iterator it;
1093 
1094  for (it = m_ChildrenList.end() - 1; it != m_ChildrenList.begin() - 1; --it)
1095  (*it)->AddFocusableChildrenToList(focusList);
1096 }
1097 
1098 int MythUIType::NormX(const int x)
1099 {
1100  return GetMythMainWindow()->NormX(x);
1101 }
1102 
1103 int MythUIType::NormY(const int y)
1104 {
1105  return GetMythMainWindow()->NormY(y);
1106 }
1107 
1112 {
1113  m_xmlLocation = base->m_xmlLocation;
1114  m_Visible = base->m_Visible;
1115  m_Enabled = base->m_Enabled;
1117  m_focusOrder = base->m_focusOrder;
1118 
1119  m_Area = base->m_Area;
1120  RecalculateArea();
1121 
1123  m_MinSize = base->m_MinSize;
1124  m_Vanish = base->m_Vanish;
1125  m_Vanished = false;
1126  m_Effects = base->m_Effects;
1128  m_AlphaChange = base->m_AlphaChange;
1129  m_AlphaMin = base->m_AlphaMin;
1130  m_AlphaMax = base->m_AlphaMax;
1131 
1132  m_Moving = base->m_Moving;
1134  m_XYSpeed = base->m_XYSpeed;
1135  m_deferload = base->m_deferload;
1136 
1137  QList<MythUIAnimation*>::Iterator i;
1138  for (i = base->m_animations.begin(); i != base->m_animations.end(); ++i)
1139  {
1140  MythUIAnimation* animation = new MythUIAnimation(this);
1141  animation->CopyFrom(*i);
1142  m_animations.push_back(animation);
1143  }
1144 
1145  QList<MythUIType *>::Iterator it;
1146 
1147  for (it = base->m_ChildrenList.begin(); it != base->m_ChildrenList.end();
1148  ++it)
1149  {
1150  MythUIType *child = GetChild((*it)->objectName());
1151 
1152  if (child)
1153  child->CopyFrom(*it);
1154  else
1155  (*it)->CreateCopy(this);
1156  }
1157 
1158  m_dependsMap = base->m_dependsMap;
1160 
1161  SetMinArea(base->m_MinArea);
1162 }
1163 
1169 {
1170  // Calling CreateCopy on base type is not valid
1171 }
1172 
1178  const QString &filename, QDomElement &element, bool showWarnings)
1179 {
1180  //FIXME add movement etc.
1181 
1182  if (element.tagName() == "position")
1183  SetPosition(parsePoint(element));
1184  else if (element.tagName() == "area")
1185  {
1186  SetArea(parseRect(element));
1187  }
1188  else if (element.tagName() == "minsize")
1189  {
1190  // Use parsePoint so percentages can be used
1191  if (element.hasAttribute("initiator"))
1192  m_EnableInitiator = parseBool(element.attribute("initiator"));
1193 
1194  if (element.hasAttribute("vanish"))
1195  m_Vanish = parseBool(element.attribute("vanish"));
1196 
1197  SetMinSize(parsePoint(element));
1198  }
1199  else if (element.tagName() == "alpha")
1200  {
1201  m_Effects.alpha = getFirstText(element).toInt();
1202  m_AlphaChangeMode = 0;
1203  }
1204  else if (element.tagName() == "alphapulse")
1205  {
1206  m_AlphaChangeMode = 2;
1207  m_AlphaMin = element.attribute("min", "0").toInt();
1208  m_Effects.alpha = m_AlphaMax = element.attribute("max", "255").toInt();
1209 
1210  if (m_AlphaMax > 255)
1211  m_Effects.alpha = m_AlphaMax = 255;
1212 
1213  if (m_AlphaMin < 0)
1214  m_AlphaMin = 0;
1215 
1216  m_AlphaChange = element.attribute("change", "5").toInt();
1217  }
1218  else if (element.tagName() == "focusorder")
1219  {
1220  int order = getFirstText(element).toInt();
1221  SetFocusOrder(order);
1222  }
1223  else if (element.tagName() == "loadondemand")
1224  {
1225  SetDeferLoad(parseBool(element));
1226  }
1227  else if (element.tagName() == "helptext")
1228  {
1229  m_helptext = getFirstText(element);
1230  }
1231  else if (element.tagName() == "animation")
1232  {
1233  MythUIAnimation::ParseElement(element, this);
1234  }
1235  else
1236  return false;
1237 
1238  return true;
1239 }
1240 
1249 {
1250 }
1251 
1252 MythFontProperties *MythUIType::GetFont(const QString &text) const
1253 {
1254  MythFontProperties *ret = m_Fonts->GetFont(text);
1255 
1256  if (!ret && m_Parent)
1257  return m_Parent->GetFont(text);
1258 
1259  return ret;
1260 }
1261 
1263 {
1264  return m_Fonts->AddFont(text, fontProp);
1265 }
1266 
1268 {
1269  if (m_Parent)
1271  else
1272  m_Area.CalculateArea(GetMythMainWindow()->GetUIScreenRect());
1273 
1274  if (recurse)
1275  {
1276  QList<MythUIType *>::iterator it;
1277 
1278  for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
1279  {
1280  (*it)->RecalculateArea(recurse);
1281  }
1282  }
1283 }
1284 
1286 {
1287  m_focusOrder = order;
1288 }
1289 
1291 {
1292  if (!child)
1293  return false;
1294 
1295  int i = m_ChildrenList.indexOf(child);
1296 
1297  if (i != -1 || i != m_ChildrenList.size() - 1)
1298  {
1299  m_ChildrenList.removeAt(i);
1300  m_ChildrenList.append(child);
1301  child->SetRedraw();
1302  return true;
1303  }
1304 
1305  return false;
1306 }
1307 
1308 
1310 {
1311  if (m_Parent)
1312  {
1313  return m_Parent->MoveChildToTop(this);
1314  }
1315 
1316  return false;
1317 }
1318 
1319 bool MythUIType::IsDeferredLoading(bool recurse) const
1320 {
1321  if (m_deferload)
1322  return true;
1323 
1324  if (recurse && m_Parent)
1325  return m_Parent->IsDeferredLoading(recurse);
1326 
1327  return false;
1328 }
1329 
1336 {
1337  QList<MythUIType *>::Iterator it;
1338 
1339  for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
1340  (*it)->LoadNow();
1341 }
1342 
1348 bool MythUIType::ContainsPoint(const QPoint &point) const
1349 {
1350  if (m_Area.contains(point))
1351  return true;
1352 
1353  return false;
1354 }
1355 
1357 {
1358  if (m_Painter)
1359  return m_Painter;
1360 
1361  if (m_Parent)
1362  return m_Parent->GetPainter();
1363 
1364  return GetMythPainter();
1365 }
1366 
1367 void MythUIType::SetDependsMap(QMap<QString, QString> dependsMap)
1368 {
1369  m_dependsMap = dependsMap;
1370 }
1371 
1373 {
1374  m_ReverseDepend = reverse;
1375 }
1376 
1378 {
1379 
1380  QMapIterator<QString, QString> i(m_dependsMap);
1381  while(i.hasNext())
1382  {
1383  i.next();
1384  QString dependeeName = i.value();
1385  bool reverse = false;
1386  if (dependeeName.startsWith('!'))
1387  {
1388  reverse = true;
1389  dependeeName.remove(0,1);
1390  }
1391  MythUIType *dependee = GetChild(dependeeName);
1392  MythUIType *dependant = GetChild(i.key());
1393 
1394  if (dependee && dependant)
1395  {
1396  QObject::connect(dependee, SIGNAL(DependChanged(bool)),
1397  dependant, SLOT(UpdateDependState(bool)));
1398  dependant->SetReverseDependence(reverse);
1399  dependant->UpdateDependState(true);
1400  }
1401  }
1402 
1403  if (recurse)
1404  {
1405  QList<MythUIType *>::iterator it;
1406  for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
1407  {
1408  if (*it)
1409  (*it)->ConnectDependants(recurse);
1410  }
1411  }
1412 }