00001
00002
00003 #include "mythuitype.h"
00004
00005
00006 #include <QEvent>
00007 #include <QKeyEvent>
00008 #include <QDomDocument>
00009
00010
00011 #include "mythlogging.h"
00012
00013
00014 #include "mythgesture.h"
00015 #include "mythimage.h"
00016 #include "mythpainter.h"
00017 #include "mythmainwindow.h"
00018 #include "mythfontproperties.h"
00019 #include "mythuitext.h"
00020 #include "mythuiimage.h"
00021 #include "mythuibutton.h"
00022 #include "mythuicheckbox.h"
00023 #include "mythuibuttonlist.h"
00024 #include "mythuitextedit.h"
00025 #include "mythuiprogressbar.h"
00026 #include "mythuispinbox.h"
00027 #include "mythuiwebbrowser.h"
00028
00029 MythUIType::MythUIType(QObject *parent, const QString &name)
00030 : QObject(parent)
00031 {
00032 setObjectName(name);
00033
00034 m_Visible = true;
00035 m_Enabled = true;
00036 m_EnableInitiator = false;
00037 m_Initiator = false;
00038 m_Vanish = false;
00039 m_Vanished = false;
00040 m_CanHaveFocus = m_HasFocus = false;
00041 m_Area = MythRect(0, 0, 0, 0);
00042 m_MinArea = MythRect(0, 0, 0, 0);
00043 m_NeedsRedraw = false;
00044 m_AlphaChangeMode = m_AlphaChange = m_AlphaMin = 0;
00045 m_AlphaMax = 255;
00046 m_Moving = false;
00047 m_XYDestination = QPoint(0, 0);
00048 m_XYSpeed = QPoint(0, 0);
00049 m_deferload = false;
00050 m_IsDependDefault = false;
00051 m_ReverseDepend = false;
00052
00053 m_Parent = NULL;
00054
00055 if (parent)
00056 {
00057 m_Parent = dynamic_cast<MythUIType *>(parent);
00058
00059 if (m_Parent)
00060 m_Parent->AddChild(this);
00061 }
00062
00063 m_DirtyRegion = QRegion(QRect(0, 0, 0, 0));
00064
00065 m_Fonts = new FontMap();
00066 m_focusOrder = 0;
00067 m_Painter = NULL;
00068
00069 m_BorderColor = QColor(random() % 255, random() % 255, random() % 255);
00070 }
00071
00072 MythUIType::~MythUIType()
00073 {
00074 delete m_Fonts;
00075 qDeleteAll(m_animations);
00076 }
00077
00082 void MythUIType::Reset()
00083 {
00084
00085 QMutableListIterator<MythUIType *> it(m_ChildrenList);
00086
00087 while (it.hasNext())
00088 {
00089 it.next();
00090 MythUIType *type = it.value();
00091 type->Reset();
00092 }
00093 }
00094
00098 void MythUIType::AddChild(MythUIType *child)
00099 {
00100 if (!child)
00101 return;
00102
00103 m_ChildrenList.push_back(child);
00104 }
00105
00106 static QObject *qChildHelper(const char *objName, const char *inheritsClass,
00107 bool recursiveSearch, const QObjectList &children)
00108 {
00109 if (children.isEmpty())
00110 return 0;
00111
00112 bool onlyWidgets = (inheritsClass
00113 && qstrcmp(inheritsClass, "QWidget") == 0);
00114 const QLatin1String oName(objName);
00115
00116 for (int i = 0; i < children.size(); ++i)
00117 {
00118 QObject *obj = children.at(i);
00119
00120 if (onlyWidgets)
00121 {
00122 if (obj->isWidgetType() && (!objName || obj->objectName() == oName))
00123 return obj;
00124 }
00125 else if ((!inheritsClass || obj->inherits(inheritsClass))
00126 && (!objName || obj->objectName() == oName))
00127 return obj;
00128
00129 if (recursiveSearch && (dynamic_cast<MythUIGroup *>(obj) != NULL)
00130 && (obj = qChildHelper(objName, inheritsClass,
00131 recursiveSearch,
00132 obj->children())))
00133 return obj;
00134 }
00135
00136 return 0;
00137 }
00138
00145 MythUIType *MythUIType::GetChild(const QString &name) const
00146 {
00147 QObject *ret = qChildHelper(name.toAscii().constData(), NULL, true, children());
00148
00149 if (ret)
00150 return dynamic_cast<MythUIType *>(ret);
00151
00152 return NULL;
00153 }
00154
00160 void MythUIType::DeleteChild(const QString &name)
00161 {
00162 QMutableListIterator<MythUIType *> it(m_ChildrenList);
00163
00164 while (it.hasNext())
00165 {
00166 it.next();
00167 MythUIType *type = it.value();
00168
00169 if (type->objectName() == name)
00170 {
00171 delete type;
00172 it.remove();
00173 return;
00174 }
00175 }
00176 }
00177
00184 void MythUIType::DeleteChild(MythUIType *child)
00185 {
00186 QMutableListIterator<MythUIType *> it(m_ChildrenList);
00187
00188 while (it.hasNext())
00189 {
00190 it.next();
00191 MythUIType *type = it.value();
00192
00193 if (type == child)
00194 {
00195 delete type;
00196 it.remove();
00197 child = NULL;
00198 return;
00199 }
00200 }
00201 }
00202
00206 QList<MythUIType *> *MythUIType::GetAllChildren(void)
00207 {
00208 return &m_ChildrenList;
00209 }
00210
00214 void MythUIType::DeleteAllChildren(void)
00215 {
00216 QList<MythUIType *>::iterator it;
00217
00218 for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
00219 if (*it)
00220 delete *it;
00221
00222 m_ChildrenList.clear();
00223 }
00224
00233 MythUIType *MythUIType::GetChildAt(const QPoint &p, bool recursive,
00234 bool focusable) const
00235 {
00236 if (GetArea().contains(p))
00237 {
00238 if (!IsVisible() || !IsEnabled())
00239 return NULL;
00240
00241 if (m_ChildrenList.isEmpty())
00242 return NULL;
00243
00244
00245 QList<MythUIType *>::const_iterator it;
00246
00247 for (it = m_ChildrenList.end() - 1; it != m_ChildrenList.begin() - 1; --it)
00248 {
00249 if (!(*it))
00250 continue;
00251
00252
00253
00254
00255 if (!(*it)->GetArea().contains(p - GetArea().topLeft()))
00256 continue;
00257
00258
00259 MythUIType *child = *it;
00260
00261 if (recursive && (focusable && !child->CanTakeFocus()))
00262 child = child->GetChildAt(p - GetArea().topLeft(), recursive,
00263 focusable);
00264
00265 if (child)
00266 {
00267
00268
00269 if (focusable && !child->CanTakeFocus())
00270 continue;
00271
00272 return child;
00273 }
00274 }
00275 }
00276
00277 return NULL;
00278 }
00279
00280 void MythUIType::ActivateAnimations(MythUIAnimation::Trigger trigger)
00281 {
00282 foreach (MythUIAnimation* animation, m_animations)
00283 if (animation->GetTrigger() == trigger)
00284 animation->Activate();
00285
00286 foreach (MythUIType* uiType, m_ChildrenList)
00287 uiType->ActivateAnimations(trigger);
00288 }
00289
00290 bool MythUIType::NeedsRedraw(void) const
00291 {
00292 return m_NeedsRedraw;
00293 }
00294
00295 void MythUIType::ResetNeedsRedraw(void)
00296 {
00297 m_NeedsRedraw = false;
00298
00299 QList<MythUIType *>::Iterator it;
00300
00301 for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
00302 (*it)->ResetNeedsRedraw();
00303 }
00304
00305 void MythUIType::SetRedraw(void)
00306 {
00307 if (m_Area.width() == 0 || m_Area.height() == 0)
00308 return;
00309
00310 m_NeedsRedraw = true;
00311
00312 if (m_DirtyRegion.isEmpty())
00313 m_DirtyRegion = QRegion(m_Area.toQRect());
00314 else
00315 m_DirtyRegion = m_DirtyRegion.unite(QRegion(m_Area.toQRect()));
00316
00317 if (m_Parent)
00318 m_Parent->SetChildNeedsRedraw(this);
00319 }
00320
00321 void MythUIType::SetChildNeedsRedraw(MythUIType *child)
00322 {
00323 QRegion childRegion = child->GetDirtyArea();
00324
00325 if (childRegion.isEmpty())
00326 return;
00327
00328 childRegion.translate(m_Area.x(), m_Area.y());
00329
00330 childRegion = childRegion.intersect(m_Area.toQRect());
00331
00332 m_NeedsRedraw = true;
00333
00334 if (m_DirtyRegion.isEmpty())
00335 m_DirtyRegion = childRegion;
00336 else
00337 m_DirtyRegion = m_DirtyRegion.unite(childRegion);
00338
00339 if (m_Parent)
00340 m_Parent->SetChildNeedsRedraw(this);
00341 }
00342
00346 bool MythUIType::CanTakeFocus(void) const
00347 {
00348 return m_CanHaveFocus;
00349 }
00350
00354 void MythUIType::SetCanTakeFocus(bool set)
00355 {
00356 m_CanHaveFocus = set;
00357 }
00358
00364 void MythUIType::HandleMovementPulse(void)
00365 {
00366 if (!GetPainter()->SupportsAnimation())
00367 return;
00368
00369 if (!m_Moving)
00370 return;
00371
00372 QPoint curXY = m_Area.topLeft().toQPoint();
00373 m_DirtyRegion = m_Area.toQRect();
00374
00375 int xdir = m_XYDestination.x() - curXY.x();
00376 int ydir = m_XYDestination.y() - curXY.y();
00377
00378 curXY.setX(curXY.x() + m_XYSpeed.x());
00379 curXY.setY(curXY.y() + m_XYSpeed.y());
00380
00381 if ((xdir > 0 && curXY.x() >= m_XYDestination.x()) ||
00382 (xdir < 0 && curXY.x() <= m_XYDestination.x()) ||
00383 (xdir == 0))
00384 {
00385 m_XYSpeed.setX(0);
00386 }
00387
00388 if ((ydir > 0 && curXY.y() >= m_XYDestination.y()) ||
00389 (ydir <= 0 && curXY.y() <= m_XYDestination.y()) ||
00390 (ydir == 0))
00391 {
00392 m_XYSpeed.setY(0);
00393 }
00394
00395 SetRedraw();
00396
00397 if (m_XYSpeed.x() == 0 && m_XYSpeed.y() == 0)
00398 {
00399 m_Moving = false;
00400 emit FinishedMoving();
00401 }
00402
00403 m_Area.moveTopLeft(curXY);
00404 }
00405
00411 void MythUIType::HandleAlphaPulse(void)
00412 {
00413 if (!GetPainter()->SupportsAlpha() ||
00414 !GetPainter()->SupportsAnimation())
00415 return;
00416
00417 if (m_AlphaChangeMode == 0)
00418 return;
00419
00420 m_Effects.alpha += m_AlphaChange;
00421
00422 if (m_Effects.alpha > m_AlphaMax)
00423 m_Effects.alpha = m_AlphaMax;
00424
00425 if (m_Effects.alpha < m_AlphaMin)
00426 m_Effects.alpha = m_AlphaMin;
00427
00428
00429 if (m_Effects.alpha == m_AlphaMax || m_Effects.alpha == m_AlphaMin)
00430 {
00431 if (m_AlphaChangeMode == 2)
00432 {
00433 m_AlphaChange *= -1;
00434 }
00435 else
00436 {
00437 m_AlphaChangeMode = 0;
00438 m_AlphaChange = 0;
00439 }
00440 }
00441
00442 SetRedraw();
00443 }
00444
00451 void MythUIType::Pulse(void)
00452 {
00453 if (!m_Visible || m_Vanished)
00454 return;
00455
00456 HandleMovementPulse();
00457 HandleAlphaPulse();
00458
00459 QList<MythUIAnimation*>::Iterator i;
00460 for (i = m_animations.begin(); i != m_animations.end(); ++i)
00461 (*i)->IncrementCurrentTime();
00462
00463 QList<MythUIType *>::Iterator it;
00464
00465 for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
00466 (*it)->Pulse();
00467 }
00468
00469 int MythUIType::CalcAlpha(int alphamod)
00470 {
00471 return (int)(m_Effects.alpha * (alphamod / 255.0));
00472 }
00473
00474 void MythUIType::DrawSelf(MythPainter *, int, int, int, QRect)
00475 {
00476 }
00477
00478 void MythUIType::Draw(MythPainter *p, int xoffset, int yoffset, int alphaMod,
00479 QRect clipRect)
00480 {
00481 m_DirtyRegion = QRegion(QRect(0, 0, 0, 0));
00482
00483 if (!m_Visible || m_Vanished)
00484 return;
00485
00486 QRect realArea = m_Area.toQRect();
00487 realArea.translate(xoffset, yoffset);
00488
00489 if (!realArea.intersects(clipRect))
00490 return;
00491
00492 p->PushTransformation(m_Effects, m_Effects.GetCentre(m_Area, xoffset, yoffset));
00493
00494 DrawSelf(p, xoffset, yoffset, alphaMod, clipRect);
00495
00496 QList<MythUIType *>::Iterator it;
00497
00498 for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
00499 {
00500 (*it)->Draw(p, xoffset + m_Area.x(), yoffset + m_Area.y(),
00501 CalcAlpha(alphaMod), clipRect);
00502 }
00503
00504 if (p->ShowBorders())
00505 {
00506 static const QBrush nullbrush(Qt::NoBrush);
00507 p->DrawRect(realArea, nullbrush, QPen(m_BorderColor), 255);
00508
00509 if (p->ShowTypeNames())
00510 {
00511 MythFontProperties font;
00512 font.SetFace(QFont("Droid Sans"));
00513 font.SetColor(m_BorderColor);
00514 font.SetPointSize(8);
00515 p->DrawText(realArea, objectName(), 0, font, 255, realArea);
00516 }
00517 }
00518
00519 p->PopTransformation();
00520 }
00521
00522 void MythUIType::SetPosition(int x, int y)
00523 {
00524 SetPosition(MythPoint(x, y));
00525 }
00526
00527 void MythUIType::SetPosition(const MythPoint &point)
00528 {
00529 MythPoint pos(point);
00530
00531 if (m_Parent)
00532 pos.CalculatePoint(m_Parent->GetFullArea());
00533 else
00534 pos.CalculatePoint(GetMythMainWindow()->GetUIScreenRect());
00535
00536 if (m_Area.topLeft() == pos)
00537 return;
00538
00539 m_DirtyRegion = QRegion(m_Area.toQRect());
00540
00541 m_Area.moveTopLeft(pos);
00542
00543 RecalculateArea(false);
00544
00545 SetRedraw();
00546 }
00547
00548 MythPoint MythUIType::GetPosition(void) const
00549 {
00550 return m_Area.topLeft();
00551 }
00552
00553 void MythUIType::SetSize(const QSize &size)
00554 {
00555 if (size == m_Area.size())
00556 return;
00557
00558 m_DirtyRegion = QRegion(m_Area.toQRect());
00559
00560 m_Area.setSize(size);
00561 RecalculateArea();
00562
00563 if (m_Parent)
00564 m_Parent->ExpandArea(m_Area.toQRect());
00565
00566 SetRedraw();
00567 }
00568
00574 void MythUIType::SetMinSize(const MythPoint &minsize)
00575 {
00576 MythPoint point(minsize);
00577
00578 if (m_Parent)
00579 point.CalculatePoint(m_Parent->GetFullArea());
00580
00581 m_MinSize = point;
00582
00583 SetRedraw();
00584 }
00585
00586 QSize MythUIType::GetMinSize(void) const
00587 {
00588 if (!m_MinSize.isValid())
00589 return m_Area.size();
00590
00591 return QSize(m_MinSize.x(), m_MinSize.y());
00592 }
00593
00594 void MythUIType::SetArea(const MythRect &rect)
00595 {
00596 if (rect == m_Area)
00597 return;
00598
00599 m_DirtyRegion = QRegion(m_Area.toQRect());
00600
00601 m_Area = rect;
00602 RecalculateArea();
00603
00604 if (m_Parent)
00605 m_Parent->ExpandArea(m_Area.toQRect());
00606
00607 SetRedraw();
00608 }
00609
00613 void MythUIType::AdjustMinArea(int delta_x, int delta_y,
00614 int delta_w, int delta_h)
00615 {
00616
00617 if (!m_MinSize.isValid())
00618 return;
00619
00620
00621 QRect bounded(m_Area.x() - delta_x,
00622 m_Area.y() - delta_y,
00623 m_Area.width() + delta_w,
00624 m_Area.height() + delta_h);
00625
00626
00627 if (!bounded.isNull() || !m_Vanish)
00628 {
00629 QPoint center = bounded.center();
00630
00631 if (bounded.isNull())
00632 bounded.setSize(GetMinSize());
00633 else
00634 bounded.setSize(bounded.size().expandedTo(GetMinSize()));
00635
00636 bounded.moveCenter(center);
00637 }
00638
00639 if (bounded.x() + bounded.width() > m_Area.x() + m_Area.width())
00640 bounded.moveRight(m_Area.x() + m_Area.width());
00641 if (bounded.y() + bounded.height() > m_Area.y() + m_Area.height())
00642 bounded.moveBottom(m_Area.x() + m_Area.height());
00643 if (bounded.x() < m_Area.x())
00644 {
00645 bounded.moveLeft(m_Area.x());
00646 if (bounded.width() > m_Area.width())
00647 bounded.setWidth(m_Area.width());
00648 }
00649 if (bounded.y() < m_Area.y())
00650 {
00651 bounded.moveTop(m_Area.y());
00652 if (bounded.height() > m_Area.height())
00653 bounded.setHeight(m_Area.height());
00654 }
00655
00656 m_MinArea = bounded;
00657 m_Vanished = false;
00658
00659 QList<MythUIType *>::iterator it;
00660
00661 for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
00662 {
00663 if (!(*it)->m_Initiator)
00664 (*it)->AdjustMinArea(delta_x, delta_y, delta_w, delta_h);
00665 }
00666 }
00667
00668 void MythUIType::VanishSibling(void)
00669 {
00670 if (!m_MinSize.isValid() || !m_Vanish)
00671 return;
00672
00673 m_MinArea.moveLeft(0);
00674 m_MinArea.moveTop(0);
00675 m_MinArea.setWidth(0);
00676 m_MinArea.setHeight(0);
00677 m_Vanished = true;
00678
00679 QList<MythUIType *>::iterator it;
00680
00681 for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
00682 {
00683 if (!(*it)->m_Initiator)
00684 (*it)->VanishSibling();
00685 }
00686 }
00687
00691 void MythUIType::SetMinAreaParent(MythRect actual_area, MythRect allowed_area,
00692 MythUIType *calling_child)
00693 {
00694 int delta_x = 0, delta_y = 0, delta_w = 0, delta_h = 0;
00695 MythRect area;
00696
00697
00698 if (!m_MinSize.isValid())
00699 return;
00700
00701 if (calling_child->m_Vanished)
00702 {
00703 actual_area.moveLeft(0);
00704 actual_area.moveTop(0);
00705 allowed_area.moveLeft(0);
00706 allowed_area.moveTop(0);
00707 }
00708
00709 actual_area.translate(m_Area.x(), m_Area.y());
00710 allowed_area.translate(m_Area.x(), m_Area.y());
00711
00712 QList<MythUIType *>::iterator it;
00713
00714 for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
00715 {
00716 if (*it == calling_child || !(*it)->m_Initiator)
00717 continue;
00718
00719 if (!(*it)->m_Vanished)
00720 {
00721
00722 area = (*it)->GetArea();
00723 area.translate(m_Area.x(), m_Area.y());
00724 actual_area = actual_area.united(area);
00725
00726 area = (*it)->m_Area;
00727 area.translate(m_Area.x(), m_Area.y());
00728 allowed_area = allowed_area.united(area);
00729 }
00730 }
00731
00732
00733 actual_area = actual_area.intersected(m_Area);
00734 allowed_area = allowed_area.intersected(m_Area);
00735
00736 if (m_Vanish && actual_area.size().isNull())
00737 {
00738 m_Vanished = true;
00739 }
00740 else
00741 {
00742 if (calling_child->m_Vanished)
00743 {
00744 delta_x = m_Area.x() - actual_area.x();
00745 delta_y = m_Area.y() - actual_area.y();
00746 delta_w = actual_area.width() - m_Area.width();
00747 delta_h = actual_area.height() - m_Area.height();
00748 }
00749 else
00750 {
00751 delta_x = allowed_area.x() - actual_area.x();
00752 delta_y = allowed_area.y() - actual_area.y();
00753 delta_w = actual_area.width() - allowed_area.width();
00754 delta_h = actual_area.height() - allowed_area.height();
00755 }
00756
00757 m_Vanished = false;
00758 }
00759
00760 for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
00761 {
00762 if (*it == calling_child)
00763 continue;
00764
00765 if (!(*it)->m_Initiator)
00766 {
00767 if (m_Vanished)
00768 (*it)->VanishSibling();
00769 else
00770 (*it)->AdjustMinArea(delta_x, delta_y, delta_w, delta_h);
00771 }
00772
00773 area = (*it)->GetArea();
00774 area.translate(m_Area.topLeft());
00775 actual_area = actual_area.united(area);
00776 }
00777
00778 if (m_Vanished)
00779 {
00780 m_MinArea.setRect(0, 0, 0, 0);
00781 actual_area.setRect(0, 0, 0, 0);
00782 }
00783 else
00784 {
00785 QSize bound(actual_area.width(), actual_area.height());
00786
00787 bound = bound.expandedTo(GetMinSize());
00788 m_MinArea.setRect(actual_area.x(),
00789 actual_area.y(),
00790 actual_area.x() + bound.width(),
00791 actual_area.y() + bound.height());
00792 }
00793
00794 if (m_Parent)
00795 m_Parent->SetMinAreaParent(actual_area, m_Area, this);
00796 }
00797
00801 void MythUIType::SetMinArea(const MythRect &rect)
00802 {
00803
00804 if (!m_Initiator || !m_MinSize.isValid())
00805 return;
00806
00807 QRect bounded(rect);
00808 bool vanish = (m_Vanish && rect.isNull());
00809
00810 if (vanish)
00811 {
00812 bounded.moveLeft(0);
00813 bounded.moveTop(0);
00814 }
00815 else
00816 {
00817 QPoint center = bounded.center();
00818
00819 if (bounded.isNull())
00820 bounded.setSize(GetMinSize());
00821 else
00822 bounded.setSize(bounded.size().expandedTo(GetMinSize()));
00823
00824 bounded.moveCenter(center);
00825 if (bounded.x() + bounded.width() > m_Area.x() + m_Area.width())
00826 bounded.moveRight(m_Area.x() + m_Area.width());
00827 if (bounded.y() + bounded.height() > m_Area.y() + m_Area.height())
00828 bounded.moveBottom(m_Area.x() + m_Area.height());
00829 if (bounded.x() < m_Area.x())
00830 {
00831 bounded.moveLeft(m_Area.x());
00832 if (bounded.width() > m_Area.width())
00833 bounded.setWidth(m_Area.width());
00834 }
00835 if (bounded.y() < m_Area.y())
00836 {
00837 bounded.moveTop(m_Area.y());
00838 if (bounded.height() > m_Area.height())
00839 bounded.setHeight(m_Area.height());
00840 }
00841 }
00842
00843 m_MinArea = bounded;
00844 m_Vanished = vanish;
00845
00846 if (m_Parent)
00847 m_Parent->SetMinAreaParent(m_MinArea, m_Area, this);
00848 }
00849
00850 void MythUIType::ExpandArea(const MythRect &rect)
00851 {
00852 QSize childSize = rect.size();
00853 QSize size = m_Area.size();
00854
00855 if (childSize == size)
00856 return;
00857
00858 SetSize(size.expandedTo(childSize));
00859 SetRedraw();
00860 }
00861
00866 MythRect MythUIType::GetArea(void) const
00867 {
00868 if (m_Vanished || m_MinArea.isValid())
00869 return m_MinArea;
00870
00871 return m_Area;
00872 }
00873
00874 MythRect MythUIType::GetFullArea(void) const
00875 {
00876 return m_Area;
00877 }
00878
00879 QRegion MythUIType::GetDirtyArea(void) const
00880 {
00881 return m_DirtyRegion;
00882 }
00883
00884 bool MythUIType::IsVisible(bool recurse) const
00885 {
00886 if (recurse)
00887 {
00888 if (m_Parent && !m_Parent->IsVisible(recurse))
00889 return false;
00890 }
00891
00892 return m_Visible;
00893 }
00894
00895 void MythUIType::MoveTo(QPoint destXY, QPoint speedXY)
00896 {
00897 if (!GetPainter()->SupportsAnimation())
00898 return;
00899
00900 if (destXY.x() == m_Area.x() && destXY.y() == m_Area.y())
00901 return;
00902
00903 m_Moving = true;
00904
00905 m_XYDestination = destXY;
00906 m_XYSpeed = speedXY;
00907 }
00908
00909 void MythUIType::AdjustAlpha(int mode, int alphachange, int minalpha,
00910 int maxalpha)
00911 {
00912 if (!GetPainter()->SupportsAlpha())
00913 return;
00914
00915 m_AlphaChangeMode = mode;
00916 m_AlphaChange = alphachange;
00917 m_AlphaMin = minalpha;
00918 m_AlphaMax = maxalpha;
00919
00920 if (m_Effects.alpha > m_AlphaMax)
00921 m_Effects.alpha = m_AlphaMax;
00922
00923 if (m_Effects.alpha < m_AlphaMin)
00924 m_Effects.alpha = m_AlphaMin;
00925 }
00926
00927 void MythUIType::SetAlpha(int newalpha)
00928 {
00929 if (m_Effects.alpha == newalpha)
00930 return;
00931
00932 m_Effects.alpha = newalpha;
00933 SetRedraw();
00934 }
00935
00936 int MythUIType::GetAlpha(void) const
00937 {
00938 return m_Effects.alpha;
00939 }
00940
00941 void MythUIType::SetCentre(UIEffects::Centre centre)
00942 {
00943 m_Effects.centre = centre;
00944 }
00945
00946 void MythUIType::SetZoom(float zoom)
00947 {
00948 SetHorizontalZoom(zoom);
00949 SetVerticalZoom(zoom);
00950 }
00951
00952 void MythUIType::SetHorizontalZoom(float zoom)
00953 {
00954 m_Effects.hzoom = zoom;
00955 SetRedraw();
00956 }
00957
00958 void MythUIType::SetVerticalZoom(float zoom)
00959 {
00960 m_Effects.vzoom = zoom;
00961 SetRedraw();
00962 }
00963
00964 void MythUIType::SetAngle(float angle)
00965 {
00966 m_Effects.angle = angle;
00967 SetRedraw();
00968 }
00969
00974 bool MythUIType::keyPressEvent(QKeyEvent *)
00975 {
00976 return false;
00977 }
00978
00979
00980 void MythUIType::customEvent(QEvent *)
00981 {
00982 return;
00983 }
00984
00990 bool MythUIType::gestureEvent(MythGestureEvent *)
00991 {
00992 return false;
00993 }
00994
00999 void MythUIType::mediaEvent(MythMediaEvent *)
01000 {
01001 return;
01002 }
01003
01004 void MythUIType::LoseFocus(void)
01005 {
01006 if (!m_CanHaveFocus || !m_HasFocus)
01007 return;
01008
01009 emit LosingFocus();
01010 m_HasFocus = false;
01011 Refresh();
01012 }
01013
01014 bool MythUIType::TakeFocus(void)
01015 {
01016 if (!m_CanHaveFocus || m_HasFocus)
01017 return false;
01018
01019 m_HasFocus = true;
01020 Refresh();
01021 emit TakingFocus();
01022 return true;
01023 }
01024
01025 void MythUIType::Activate(void)
01026 {
01027 }
01028
01029 void MythUIType::Refresh(void)
01030 {
01031 SetRedraw();
01032 }
01033
01034 void MythUIType::UpdateDependState(bool isDefault)
01035 {
01036 m_IsDependDefault = m_ReverseDepend ? !isDefault : isDefault;
01037
01038 SetVisible(!m_IsDependDefault);
01039 }
01040
01041 void MythUIType::SetVisible(bool visible)
01042 {
01043 if (visible == m_Visible)
01044 return;
01045
01046 if (visible && m_IsDependDefault)
01047 return;
01048
01049 m_Visible = visible;
01050 SetRedraw();
01051
01052 if (m_Visible)
01053 emit Showing();
01054 else
01055 emit Hiding();
01056 }
01057
01058 void MythUIType::SetDependIsDefault(bool isDefault)
01059 {
01060 m_IsDependDefault = isDefault;
01061 }
01062
01063 void MythUIType::SetEnabled(bool enable)
01064 {
01065 if (m_Enabled != enable)
01066 m_Enabled = enable;
01067
01068 if (enable)
01069 emit Enabling();
01070 else
01071 emit Disabling();
01072 }
01073
01074 void MythUIType::Hide(void)
01075 {
01076 SetVisible(false);
01077 }
01078
01079 void MythUIType::Show(void)
01080 {
01081 SetVisible(true);
01082 }
01083
01084 void MythUIType::AddFocusableChildrenToList(QMap<int, MythUIType *> &focusList)
01085 {
01086 if (m_CanHaveFocus)
01087 focusList.insertMulti(m_focusOrder, this);
01088
01089 QList<MythUIType *>::Iterator it;
01090
01091 for (it = m_ChildrenList.end() - 1; it != m_ChildrenList.begin() - 1; --it)
01092 (*it)->AddFocusableChildrenToList(focusList);
01093 }
01094
01095 int MythUIType::NormX(const int x)
01096 {
01097 return GetMythMainWindow()->NormX(x);
01098 }
01099
01100 int MythUIType::NormY(const int y)
01101 {
01102 return GetMythMainWindow()->NormY(y);
01103 }
01104
01108 void MythUIType::CopyFrom(MythUIType *base)
01109 {
01110 m_xmlLocation = base->m_xmlLocation;
01111 m_Visible = base->m_Visible;
01112 m_Enabled = base->m_Enabled;
01113 m_CanHaveFocus = base->m_CanHaveFocus;
01114 m_focusOrder = base->m_focusOrder;
01115
01116 m_Area = base->m_Area;
01117 RecalculateArea();
01118
01119 m_EnableInitiator = base->m_EnableInitiator;
01120 m_MinSize = base->m_MinSize;
01121 m_Vanish = base->m_Vanish;
01122 m_Vanished = false;
01123 m_Effects = base->m_Effects;
01124 m_AlphaChangeMode = base->m_AlphaChangeMode;
01125 m_AlphaChange = base->m_AlphaChange;
01126 m_AlphaMin = base->m_AlphaMin;
01127 m_AlphaMax = base->m_AlphaMax;
01128
01129 m_Moving = base->m_Moving;
01130 m_XYDestination = base->m_XYDestination;
01131 m_XYSpeed = base->m_XYSpeed;
01132 m_deferload = base->m_deferload;
01133
01134 QList<MythUIAnimation*>::Iterator i;
01135 for (i = base->m_animations.begin(); i != base->m_animations.end(); ++i)
01136 {
01137 MythUIAnimation* animation = new MythUIAnimation(this);
01138 animation->CopyFrom(*i);
01139 m_animations.push_back(animation);
01140 }
01141
01142 QList<MythUIType *>::Iterator it;
01143
01144 for (it = base->m_ChildrenList.begin(); it != base->m_ChildrenList.end();
01145 ++it)
01146 {
01147 MythUIType *child = GetChild((*it)->objectName());
01148
01149 if (child)
01150 child->CopyFrom(*it);
01151 else
01152 (*it)->CreateCopy(this);
01153 }
01154
01155 m_dependsMap = base->m_dependsMap;
01156 m_ReverseDepend = base->m_ReverseDepend;
01157
01158 SetMinArea(base->m_MinArea);
01159 }
01160
01165 void MythUIType::CreateCopy(MythUIType *)
01166 {
01167
01168 }
01169
01174 bool MythUIType::ParseElement(
01175 const QString &filename, QDomElement &element, bool showWarnings)
01176 {
01177
01178
01179 if (element.tagName() == "position")
01180 SetPosition(parsePoint(element));
01181 else if (element.tagName() == "area")
01182 {
01183 SetArea(parseRect(element));
01184 }
01185 else if (element.tagName() == "minsize")
01186 {
01187
01188 if (element.hasAttribute("initiator"))
01189 m_EnableInitiator = parseBool(element.attribute("initiator"));
01190
01191 if (element.hasAttribute("vanish"))
01192 m_Vanish = parseBool(element.attribute("vanish"));
01193
01194 SetMinSize(parsePoint(element));
01195 }
01196 else if (element.tagName() == "alpha")
01197 {
01198 m_Effects.alpha = getFirstText(element).toInt();
01199 m_AlphaChangeMode = 0;
01200 }
01201 else if (element.tagName() == "alphapulse")
01202 {
01203 m_AlphaChangeMode = 2;
01204 m_AlphaMin = element.attribute("min", "0").toInt();
01205 m_Effects.alpha = m_AlphaMax = element.attribute("max", "255").toInt();
01206
01207 if (m_AlphaMax > 255)
01208 m_Effects.alpha = m_AlphaMax = 255;
01209
01210 if (m_AlphaMin < 0)
01211 m_AlphaMin = 0;
01212
01213 m_AlphaChange = element.attribute("change", "5").toInt();
01214 }
01215 else if (element.tagName() == "focusorder")
01216 {
01217 int order = getFirstText(element).toInt();
01218 SetFocusOrder(order);
01219 }
01220 else if (element.tagName() == "loadondemand")
01221 {
01222 SetDeferLoad(parseBool(element));
01223 }
01224 else if (element.tagName() == "helptext")
01225 {
01226 m_helptext = getFirstText(element);
01227 }
01228 else if (element.tagName() == "animation")
01229 {
01230 MythUIAnimation::ParseElement(element, this);
01231 }
01232 else
01233 return false;
01234
01235 return true;
01236 }
01237
01245 void MythUIType::Finalize(void)
01246 {
01247 }
01248
01249 MythFontProperties *MythUIType::GetFont(const QString &text) const
01250 {
01251 MythFontProperties *ret = m_Fonts->GetFont(text);
01252
01253 if (!ret && m_Parent)
01254 return m_Parent->GetFont(text);
01255
01256 return ret;
01257 }
01258
01259 bool MythUIType::AddFont(const QString &text, MythFontProperties *fontProp)
01260 {
01261 return m_Fonts->AddFont(text, fontProp);
01262 }
01263
01264 void MythUIType::RecalculateArea(bool recurse)
01265 {
01266 if (m_Parent)
01267 m_Area.CalculateArea(m_Parent->GetFullArea());
01268 else
01269 m_Area.CalculateArea(GetMythMainWindow()->GetUIScreenRect());
01270
01271 if (recurse)
01272 {
01273 QList<MythUIType *>::iterator it;
01274
01275 for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
01276 {
01277 (*it)->RecalculateArea(recurse);
01278 }
01279 }
01280 }
01281
01282 void MythUIType::SetFocusOrder(int order)
01283 {
01284 m_focusOrder = order;
01285 }
01286
01287 bool MythUIType::MoveChildToTop(MythUIType *child)
01288 {
01289 if (!child)
01290 return false;
01291
01292 int i = m_ChildrenList.indexOf(child);
01293
01294 if (i != -1 || i != m_ChildrenList.size() - 1)
01295 {
01296 m_ChildrenList.removeAt(i);
01297 m_ChildrenList.append(child);
01298 child->SetRedraw();
01299 return true;
01300 }
01301
01302 return false;
01303 }
01304
01305
01306 bool MythUIType::MoveToTop(void)
01307 {
01308 if (m_Parent)
01309 {
01310 return m_Parent->MoveChildToTop(this);
01311 }
01312
01313 return false;
01314 }
01315
01316 bool MythUIType::IsDeferredLoading(bool recurse) const
01317 {
01318 if (m_deferload)
01319 return true;
01320
01321 if (recurse && m_Parent)
01322 return m_Parent->IsDeferredLoading(recurse);
01323
01324 return false;
01325 }
01326
01332 void MythUIType::LoadNow(void)
01333 {
01334 QList<MythUIType *>::Iterator it;
01335
01336 for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
01337 (*it)->LoadNow();
01338 }
01339
01345 bool MythUIType::ContainsPoint(const QPoint &point) const
01346 {
01347 if (m_Area.contains(point))
01348 return true;
01349
01350 return false;
01351 }
01352
01353 MythPainter *MythUIType::GetPainter(void)
01354 {
01355 if (m_Painter)
01356 return m_Painter;
01357
01358 if (m_Parent)
01359 return m_Parent->GetPainter();
01360
01361 return GetMythPainter();
01362 }
01363
01364 void MythUIType::SetDependsMap(QMap<QString, QString> dependsMap)
01365 {
01366 m_dependsMap = dependsMap;
01367 }
01368
01369 void MythUIType::SetReverseDependence(bool reverse)
01370 {
01371 m_ReverseDepend = reverse;
01372 }
01373
01374 void MythUIType::ConnectDependants(bool recurse)
01375 {
01376
01377 QMapIterator<QString, QString> i(m_dependsMap);
01378 while(i.hasNext())
01379 {
01380 i.next();
01381 QString dependeeName = i.value();
01382 bool reverse = false;
01383 if (dependeeName.startsWith('!'))
01384 {
01385 reverse = true;
01386 dependeeName.remove(0,1);
01387 }
01388 MythUIType *dependee = GetChild(dependeeName);
01389 MythUIType *dependant = GetChild(i.key());
01390
01391 if (dependee && dependant)
01392 {
01393 QObject::connect(dependee, SIGNAL(DependChanged(bool)),
01394 dependant, SLOT(UpdateDependState(bool)));
01395 dependant->SetReverseDependence(reverse);
01396 dependant->UpdateDependState(true);
01397 }
01398 }
01399
01400 if (recurse)
01401 {
01402 QList<MythUIType *>::iterator it;
01403 for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
01404 {
01405 if (*it)
01406 (*it)->ConnectDependants(recurse);
01407 }
01408 }
01409 }