10#include <QDomDocument>
13#include <QInputMethodEvent>
42#define LOC QString("MythUIType: ")
51 m_parent = qobject_cast<MythUIType *>(parent);
97static QObject *
qChildHelper(
const char *objName,
const char *inheritsClass,
98 bool recursiveSearch,
const QObjectList &children)
100 if (children.isEmpty())
103 bool onlyWidgets = (inheritsClass
104 && qstrcmp(inheritsClass,
"QWidget") == 0);
105 const QLatin1String oName(objName);
107 for (
auto *obj : std::as_const(children))
111 if (obj->isWidgetType() && (!objName || obj->objectName() == oName))
114 else if ((!inheritsClass || obj->inherits(inheritsClass))
115 && (!objName || obj->objectName() == oName))
120 if (recursiveSearch && (qobject_cast<MythUIGroup *>(obj) !=
nullptr))
122 obj =
qChildHelper(objName, inheritsClass, recursiveSearch,
140 QObject *ret =
qChildHelper(name.toLatin1().constData(),
nullptr,
true, children());
143 return qobject_cast<MythUIType *>(ret);
162 if (
type->objectName() == name)
209 QList<MythUIType *> descendants {};
214 descendants += item->GetAllDescendants();
224 QList<MythUIType *>::iterator it;
242 bool focusable)
const
253 QList<MythUIType *>::const_reverse_iterator it;
263 if (!(*it)->GetArea().contains(
p -
GetArea().topLeft()))
291 if (animation->GetTrigger() == trigger)
292 animation->Activate();
295 uiType->ActivateAnimations(trigger);
307 QList<MythUIType *>::Iterator it;
310 (*it)->ResetNeedsRedraw();
333 if (childRegion.isEmpty())
464 QList<MythUIAnimation*>::Iterator i;
466 (*i)->IncrementCurrentTime();
468 QList<MythUIType *>::Iterator it;
496 realArea.translate(xoffset, yoffset);
498 if (!realArea.intersects(clipRect))
503 DrawSelf(
p, xoffset, yoffset, alphaMod, clipRect);
505 QList<MythUIType *>::Iterator it;
513 if (
p->ShowBorders())
515 static const QBrush kNullBrush(Qt::NoBrush);
518 p->DrawRect(realArea, kNullBrush, pen, 255);
520 if (
p->ShowTypeNames())
523 font.
SetFace(QFont(
"Droid Sans"));
526 p->DrawText(realArea, objectName(), 0, font, 255, realArea);
530 p->PopTransformation();
571 if (size ==
m_area.size())
630 int delta_w,
int delta_h)
637 QRect bounded(
m_area.x() - delta_x,
640 m_area.height() + delta_h);
645 QPoint center = bounded.center();
647 if (bounded.isNull())
650 bounded.setSize(bounded.size().expandedTo(
GetMinSize()));
652 bounded.moveCenter(center);
655 if (bounded.x() + bounded.width() >
m_area.x() +
m_area.width())
657 if (bounded.y() + bounded.height() >
m_area.y() +
m_area.height())
659 if (bounded.x() <
m_area.x())
661 bounded.moveLeft(
m_area.x());
662 if (bounded.width() >
m_area.width())
663 bounded.setWidth(
m_area.width());
665 if (bounded.y() <
m_area.y())
667 bounded.moveTop(
m_area.y());
668 if (bounded.height() >
m_area.height())
669 bounded.setHeight(
m_area.height());
675 QList<MythUIType *>::iterator it;
679 if (!(*it)->m_initiator)
680 (*it)->AdjustMinArea(delta_x, delta_y, delta_w, delta_h);
695 QList<MythUIType *>::iterator it;
699 if (!(*it)->m_initiator)
700 (*it)->VanishSibling();
731 QList<MythUIType *>::iterator it;
738 if (!(*it)->m_vanished)
741 area = (*it)->GetArea();
743 actual_area = actual_area.united(area);
745 area = (*it)->m_area;
747 allowed_area = allowed_area.united(area);
752 actual_area = actual_area.intersected(
m_area);
753 allowed_area = allowed_area.intersected(
m_area);
755 if (
m_vanish && actual_area.size().isNull())
763 delta_x =
m_area.x() - actual_area.x();
764 delta_y =
m_area.y() - actual_area.y();
765 delta_w = actual_area.width() -
m_area.width();
766 delta_h = actual_area.height() -
m_area.height();
770 delta_x = allowed_area.x() - actual_area.x();
771 delta_y = allowed_area.y() - actual_area.y();
772 delta_w = actual_area.width() - allowed_area.width();
773 delta_h = actual_area.height() - allowed_area.height();
781 if (*it == calling_child)
784 if (!(*it)->m_initiator)
787 (*it)->VanishSibling();
789 (*it)->AdjustMinArea(delta_x, delta_y, delta_w, delta_h);
792 area = (*it)->GetArea();
794 actual_area = actual_area.united(area);
800 actual_area.
setRect(0, 0, 0, 0);
804 QSize bound(actual_area.width(), actual_area.height());
809 actual_area.x() + bound.width(),
810 actual_area.y() + bound.height());
827 bool vanish = (
m_vanish && rect.isNull());
836 QPoint center = bounded.center();
838 if (bounded.isNull())
841 bounded.setSize(bounded.size().expandedTo(
GetMinSize()));
843 bounded.moveCenter(center);
844 if (bounded.x() + bounded.width() >
m_area.x() +
m_area.width())
846 if (bounded.y() + bounded.height() >
m_area.y() +
m_area.height())
848 if (bounded.x() <
m_area.x())
850 bounded.moveLeft(
m_area.x());
851 if (bounded.width() >
m_area.width())
852 bounded.setWidth(
m_area.width());
854 if (bounded.y() <
m_area.y())
856 bounded.moveTop(
m_area.y());
857 if (bounded.height() >
m_area.height())
858 bounded.setHeight(
m_area.height());
871 QSize childSize = rect.size();
872 QSize size =
m_area.size();
874 if (childSize == size)
877 SetSize(size.expandedTo(childSize));
919 if (destXY.x() ==
m_area.x() && destXY.y() ==
m_area.y())
1005 QObject::customEvent(event);
1064 bool visible =
false;
1069 visible = reverse ? !isDefault : isDefault;
1090 visible = visible && v;
1095 visible = visible || v;
1106 auto *dependee = qobject_cast<MythUIType*>(sender());
1161 (*it)->AddFocusableChildrenToList(focusList);
1204 QList<MythUIAnimation*>::Iterator i;
1208 animation->CopyFrom(*i);
1212 QList<MythUIType *>::Iterator it;
1222 (*it)->CreateCopy(
this);
1244 const QString &
filename, QDomElement &element,
bool showWarnings)
1248 if (element.tagName() ==
"position")
1250 else if (element.tagName() ==
"area")
1254 else if (element.tagName() ==
"minsize")
1257 if (element.hasAttribute(
"initiator"))
1260 if (element.hasAttribute(
"vanish"))
1265 else if (element.tagName() ==
"alpha")
1270 else if (element.tagName() ==
"alphapulse")
1273 m_alphaMin = element.attribute(
"min",
"0").toInt();
1283 else if (element.tagName() ==
"focusorder")
1288 else if (element.tagName() ==
"loadondemand")
1292 else if (element.tagName() ==
"helptext")
1296 else if (element.tagName() ==
"animation")
1303 QString(
"Unknown widget type '%1'").arg(element.tagName()));
1346 QList<MythUIType *>::iterator it;
1350 (*it)->RecalculateArea(recurse);
1407 QList<MythUIType *>::Iterator it;
1420 return m_area.contains(point);
1447 QStringList dependees;
1448 QList<int> operators;
1456 QString name = it.value();
1457 QStringList tmp1 = name.split(
"&");
1458 for (
const QString& t1 : std::as_const(tmp1))
1460 QStringList tmp2 = t1.split(
"|");
1462 dependees.append(tmp2[0]);
1463 for (
int j = 1; j < tmp2.size(); j++)
1465 dependees.append(tmp2[j]);
1466 operators.append(1);
1468 operators.append(2);
1475 for (QString dependeeName : std::as_const(dependees))
1477 bool reverse =
false;
1478 if (dependeeName.startsWith(
'!'))
1481 dependeeName.remove(0,1);
1490 dependant->
m_dependsValue.append(QPair<MythUIType *, bool>(dependee,
false));
1495 dependant->
m_dependsValue.append(QPair<MythUIType *, bool>(dependee, !reverse));
1504 QList<MythUIType *>::iterator child;
1508 (*child)->ConnectDependants(recurse);
bool AddFont(const QString &text, MythFontProperties *fontProp)
MythFontProperties * GetFont(const QString &text)
void SetFace(const QFont &face)
void SetColor(const QColor &color)
void SetPointSize(uint points)
A custom event that represents a mouse gesture.
Wrapper around QPoint allowing us to handle percentage and other relative values for positioning in m...
void CalculatePoint(QRect parentArea)
QPoint toQPoint(void) const
Wrapper around QRect allowing us to handle percentage and other relative values for areas in mythui.
void setRect(const QString &sX, const QString &sY, const QString &sWidth, const QString &sHeight, const QString &baseRes=QString())
MythPoint topLeft(void) const
void moveTop(const QString &sY)
void moveLeft(const QString &sX)
void setWidth(const QString &sWidth)
void setHeight(const QString &sHeight)
void CalculateArea(QRect parentArea)
void moveTopLeft(QPoint point)
QRect toQRect(void) const
static void ParseElement(const QDomElement &element, MythUIType *parent)
The base class on which all widgets and screens are based.
bool IsEnabled(void) const
void AddFocusableChildrenToList(FocusInfoType &focusList)
bool AddFont(const QString &text, MythFontProperties *fontProp)
QList< MythUIType * > * GetAllChildren(void)
Return a list of all child widgets.
bool ContainsPoint(QPoint point) const
Check if the given point falls within this widgets area.
virtual void RecalculateArea(bool recurse=true)
void SetCanTakeFocus(bool set=true)
Set whether this widget can take focus.
void SetDependsMap(QMap< QString, QString > dependsMap)
virtual QRegion GetDirtyArea(void) const
bool IsVisible(bool recurse=false) const
virtual void SetSize(QSize size)
void VisibilityChanged(bool Visible)
void HandleMovementPulse()
Handle one frame of a movement animation.
void AddChild(MythUIType *child)
Add a child UIType.
void ActivateAnimations(MythUIAnimation::Trigger trigger)
void SetFocusOrder(int order)
virtual void mediaEvent(MythMediaEvent *event)
Media/Device status event handler, received from MythMediaMonitor.
void customEvent(QEvent *event) override
virtual void DrawSelf(MythPainter *p, int xoffset, int yoffset, int alphaMod, QRect clipRect)
virtual void VanishSibling(void)
void Draw(MythPainter *p, int xoffset, int yoffset, int alphaMod=255, QRect clipRect=QRect())
bool CanTakeFocus(void) const
Return if this widget can accept input focus.
virtual void SetVisible(bool visible)
virtual MythPainter * GetPainter(void)
void AdjustAlpha(int mode, int alphachange, int minalpha=0, int maxalpha=255)
virtual void SetArea(const MythRect &rect)
virtual void LoadNow(void)
Cause images in this and child widgets to be loaded.
virtual bool gestureEvent(MythGestureEvent *event)
Mouse click/movement handler, receives mouse gesture events from the QCoreApplication event loop.
void ExpandArea(QRect rect)
virtual QSize GetMinSize(void) const
MythUIType(QObject *parent, const QString &name)
virtual void AdjustMinArea(int delta_x, int delta_y, int delta_w, int delta_h)
Adjust the size of a sibling.
QList< int > m_dependOperator
QMap< MythUIType *, bool > m_reverseDepend
void SetEnabled(bool enable)
void SetAngle(float angle)
virtual void CopyFrom(MythUIType *base)
Copy this widgets state from another.
virtual void Finalize(void)
Perform any post-xml parsing initialisation tasks.
bool NeedsRedraw(void) const
MythUIType * GetChildAt(QPoint p, bool recursive=true, bool focusable=true) const
Return the first MythUIType at the given coordinates.
void ResetNeedsRedraw(void)
void SetFocusedName(const QString &widgetname)
void ConnectDependants(bool recurse=false)
void SetVerticalZoom(float zoom)
virtual void SetMinArea(const MythRect &rect)
Set the minimum area based on the given size.
virtual void Pulse(void)
Pulse is called 70 times a second to trigger a single frame of an animation.
void SetChildNeedsRedraw(MythUIType *child)
static int NormY(int height)
MythFontProperties * GetFont(const QString &text) const
void SetReverseDependence(MythUIType *dependee, bool reverse)
virtual MythRect GetArea(void) const
If the object has a minimum area defined, return it, other wise return the default area.
bool IsDeferredLoading(bool recurse=false) const
virtual void CreateCopy(MythUIType *parent)
Copy the state of this widget to the one given, it must be of the same type.
void SetDependIsDefault(bool isDefault)
QMap< QString, QString > m_dependsMap
virtual MythRect GetFullArea(void) const
void DeleteAllChildren(void)
Delete all child widgets.
int CalcAlpha(int alphamod) const
virtual void SetMinAreaParent(MythRect actual_area, MythRect allowed_area, MythUIType *child)
Adjust the size of sibling objects within the button.
void SetPosition(int x, int y)
Convenience method, calls SetPosition(const MythPoint&) Override that instead to change functionality...
QList< MythUIAnimation * > m_animations
void UpdateDependState(bool isDefault)
void HandleAlphaPulse()
Handle one frame of an alpha (transparency) change animation.
MythUIType * GetChild(const QString &name) const
Get a named child of this UIType.
void SetAlpha(int newalpha)
void SetCentre(UIEffects::Centre centre)
void MoveTo(QPoint destXY, QPoint speedXY)
virtual bool inputMethodEvent(QInputMethodEvent *event)
Input Method event handler.
void DeleteChild(const QString &name)
Delete a named child of this UIType.
void SetHorizontalZoom(float zoom)
void DependChanged(bool isDefault)
virtual void Reset(void)
Reset the widget to it's original state, should not reset changes made by the theme.
virtual bool ParseElement(const QString &filename, QDomElement &element, bool showWarnings)
Parse the xml definition of this widget setting the state of the object accordingly.
void FinishedMoving(void)
QList< MythUIType * > m_childrenList
void FinishedFading(void)
static int NormX(int width)
void SetDeferLoad(bool defer)
virtual void SetMinSize(const MythPoint &size)
Set the minimum size of this widget, for widgets which can be rescaled.
virtual bool keyPressEvent(QKeyEvent *event)
Key event handler.
QList< MythUIType * > GetAllDescendants(void)
virtual MythPoint GetPosition(void) const
QList< QPair< MythUIType *, bool > > m_dependsValue
bool MoveChildToTop(MythUIType *child)
QPointF GetCentre(const QRect rect, int xoff, int yoff) const
static MythRect parseRect(const QString &text, bool normalize=true)
static MythPoint parsePoint(const QString &text, bool normalize=true)
static QString getFirstText(QDomElement &element)
static bool parseBool(const QString &text)
A C++ ripoff of the stroke library for MythTV.
MythPainter * GetMythPainter(void)
MythMainWindow * GetMythMainWindow(void)
Convenience inline random number generator functions.
static QObject * qChildHelper(const char *objName, const char *inheritsClass, bool recursiveSearch, const QObjectList &children)
QMultiMap< int, MythUIType * > FocusInfoType
uint32_t MythRandom()
generate 32 random bits
static eu8 clamp(eu8 value, eu8 low, eu8 high)
#define VERBOSE_XML(type, level, filename, element, msg)