Skip to content
Browse files

MythDialogBox: Allow an hierarchical menu to be passed to the menu di…

…alog.

This updates the menu popup dialog to accept a menu tree which the dialog
will allow the user to automatically move up and down the menu tree when
left/up and right/down are pressed. The OSD menu already allows this but in a
much more complicated way. Future commits will update some of the menus that
have submenus to use the new features.
  • Loading branch information...
1 parent ac5b20c commit 94f6bb50987868b0ecaec345476855f9bd42380d Paul Harrison committed Sep 28, 2011
View
195 mythtv/libs/libmythui/mythdialogbox.cpp
@@ -21,11 +21,65 @@
QEvent::Type DialogCompletionEvent::kEventType =
(QEvent::Type) QEvent::registerEventType();
+
+MythMenu::MythMenu(const QString &text, QObject *retobject, const QString &resultid) :
+ m_parentMenu(NULL), m_title(""), m_text(text), m_resultid(resultid), m_retObject(retobject)
+{
+}
+
+MythMenu::MythMenu(const QString &title, const QString &text, QObject *retobject, const QString &resultid) :
+ m_parentMenu(NULL), m_title(title), m_text(text), m_resultid(resultid), m_retObject(retobject)
+{
+}
+
+MythMenu::~MythMenu(void)
+{
+ while (!m_menuItems.isEmpty())
+ {
+ MythMenuItem *item = m_menuItems.takeFirst();
+
+ if (item->SubMenu)
+ delete item->SubMenu;
+
+ delete item;
+ }
+}
+
+void MythMenu::AddItem(const QString& title, const char* slot, MythMenu *subMenu, bool selected, bool checked)
+{
+ MythMenuItem *item = new MythMenuItem(title, slot, checked, subMenu);
+
+ m_menuItems.append(item);
+
+ if (selected)
+ m_selectedItem = m_menuItems.indexOf(item);
+
+ if (subMenu)
+ subMenu->SetParent(this);
+}
+
+void MythMenu::AddItem(const QString &title, QVariant data, MythMenu *subMenu, bool selected, bool checked)
+{
+ MythMenuItem *item = new MythMenuItem(title, data, checked, subMenu);
+
+ m_menuItems.append(item);
+
+ if (selected)
+ m_selectedItem = m_menuItems.indexOf(item);
+
+ if (subMenu)
+ subMenu->SetParent(this);
+}
+
+/////////////////////////////////////////////////////////////////
+
MythDialogBox::MythDialogBox(const QString &text,
MythScreenStack *parent, const char *name,
bool fullscreen, bool osd)
: MythScreenType(parent, name, false)
{
+ m_menu = NULL;
+ m_currentMenu = NULL;
m_retObject = NULL;
m_titlearea = NULL;
m_text = text;
@@ -47,6 +101,8 @@ MythDialogBox::MythDialogBox(const QString &title, const QString &text,
bool fullscreen, bool osd)
: MythScreenType(parent, name, false)
{
+ m_menu = NULL;
+ m_currentMenu = NULL;
m_id = "";
m_retObject = NULL;
m_title = title;
@@ -65,6 +121,35 @@ MythDialogBox::MythDialogBox(const QString &title, const QString &text,
m_exitdata = 0;
}
+MythDialogBox::MythDialogBox(MythMenu *menu, MythScreenStack *parent, const char *name,
+ bool fullscreen, bool osd)
+ : MythScreenType(parent, name, false)
+{
+ m_menu = menu;
+ m_currentMenu = m_menu;
+ m_id = "";
+ m_retObject = NULL;
+ m_title = "";
+ m_titlearea = NULL;
+ m_textarea = NULL;
+ m_buttonList = NULL;
+
+ m_fullscreen = fullscreen;
+ m_osdDialog = osd;
+ m_useSlots = false;
+
+ m_backtext = "";
+ m_backdata = 0;
+ m_exittext = "";
+ m_exitdata = 0;
+}
+
+MythDialogBox::~MythDialogBox(void)
+{
+ if (m_menu)
+ delete m_menu;
+}
+
bool MythDialogBox::Create(void)
{
QString windowName = (m_fullscreen ? "MythDialogBox" : "MythPopupBox");
@@ -92,28 +177,95 @@ bool MythDialogBox::Create(void)
if (m_titlearea)
m_titlearea->SetText(m_title);
m_textarea->SetText(m_text);
+
BuildFocusList();
+ if (m_menu)
+ updateMenu();
+
connect(m_buttonList, SIGNAL(itemClicked(MythUIButtonListItem*)),
SLOT(Select(MythUIButtonListItem*)));
return true;
}
+void MythDialogBox::SetMenuItems(MythMenu* menu)
+{
+ m_menu = menu;
+ m_currentMenu = m_menu;
+ updateMenu();
+}
+
+void MythDialogBox::updateMenu(void)
+{
+ if (!m_buttonList)
+ {
+ LOG(VB_GENERAL, LOG_ERR, "UpdateMenu() called before we have a button list to update!");
+ return;
+ }
+
+ if (!m_currentMenu)
+ return;
+
+ if (m_titlearea)
+ m_titlearea->SetText(m_currentMenu->m_title);
+
+ m_textarea->SetText(m_currentMenu->m_text);
+
+ m_buttonList->Reset();
+
+ for (int x = 0; x < m_currentMenu->m_menuItems.count(); x++)
+ {
+ MythMenuItem *menuItem = m_currentMenu->m_menuItems.at(x);
+ MythUIButtonListItem *button = new MythUIButtonListItem(m_buttonList, menuItem->Text);
+ button->SetData(qVariantFromValue(menuItem));
+ button->setDrawArrow((menuItem->SubMenu != NULL));
+
+ if (m_currentMenu->m_selectedItem == x)
+ m_buttonList->SetItemCurrent(button);
+ }
+}
+
void MythDialogBox::Select(MythUIButtonListItem* item)
{
if (!item)
return;
- const char *slot = qVariantValue<const char *>(item->GetData());
- if (m_useSlots && slot)
+ if (m_currentMenu)
+ {
+ MythMenuItem *menuItem = qVariantValue<MythMenuItem *>(item->GetData());
+
+ if (menuItem->SubMenu)
+ {
+ m_currentMenu->m_selectedItem = m_buttonList->GetCurrentPos();
+ m_currentMenu = menuItem->SubMenu;
+ updateMenu();
+ return;
+ }
+
+ const char *slot = qVariantValue<const char *>(menuItem->Data);
+ if (menuItem->UseSlot && slot)
+ {
+ connect(this, SIGNAL(Selected()), m_currentMenu->m_retObject, slot,
+ Qt::QueuedConnection);
+ emit Selected();
+ }
+
+ SendEvent(m_buttonList->GetItemPos(item), item->GetText(), menuItem->Data);
+ }
+ else
{
- connect(this, SIGNAL(Selected()), m_retObject, slot,
- Qt::QueuedConnection);
- emit Selected();
+ const char *slot = qVariantValue<const char *>(item->GetData());
+ if (m_useSlots && slot)
+ {
+ connect(this, SIGNAL(Selected()), m_retObject, slot,
+ Qt::QueuedConnection);
+ emit Selected();
+ }
+
+ SendEvent(m_buttonList->GetItemPos(item), item->GetText(), item->GetData());
}
- SendEvent(m_buttonList->GetItemPos(item), item->GetText(), item->GetData());
if (m_ScreenStack)
m_ScreenStack->PopScreen(false);
}
@@ -194,7 +346,15 @@ bool MythDialogBox::keyPressEvent(QKeyEvent *event)
(action == "UP" &&
m_buttonList->GetLayout() == MythUIButtonList::LayoutHorizontal))
{
+ if (m_currentMenu && m_currentMenu->m_parentMenu)
+ {
+ m_currentMenu = m_currentMenu->m_parentMenu;
+ updateMenu();
+ return true;
+ }
+
SendEvent(-1, m_backtext, m_backdata);
+ Close();
}
else if (action == "MENU")
{
@@ -243,13 +403,26 @@ bool MythDialogBox::gestureEvent(MythGestureEvent *event)
void MythDialogBox::SendEvent(int res, QString text, QVariant data)
{
- emit Closed(m_id, res);
+ if (m_currentMenu)
+ {
+ emit Closed(m_currentMenu->m_resultid, res);
- if (!m_retObject)
- return;
+ if (!m_currentMenu->m_retObject)
+ return;
- DialogCompletionEvent *dce = new DialogCompletionEvent(m_id, res, text, data);
- QCoreApplication::postEvent(m_retObject, dce);
+ DialogCompletionEvent *dce = new DialogCompletionEvent(m_currentMenu->m_resultid, res, text, data);
+ QCoreApplication::postEvent(m_currentMenu->m_retObject, dce);
+ }
+ else
+ {
+ emit Closed(m_id, res);
+
+ if (!m_retObject)
+ return;
+
+ DialogCompletionEvent *dce = new DialogCompletionEvent(m_id, res, text, data);
+ QCoreApplication::postEvent(m_retObject, dce);
+ }
}
/////////////////////////////////////////////////////////////////
View
56 mythtv/libs/libmythui/mythdialogbox.h
@@ -17,6 +17,8 @@ class MythUIButton;
class MythUITextEdit;
class MythUIImage;
class MythUIStateType;
+class MythMenu;
+
/**
* \class DialogCompletionEvent
@@ -49,6 +51,48 @@ class MUI_PUBLIC DialogCompletionEvent : public QEvent
QVariant m_resultData;
};
+
+class MUI_PUBLIC MythMenuItem
+{
+ public:
+ MythMenuItem(const QString &text, QVariant data = 0, bool checked = false, MythMenu *subMenu = NULL) :
+ Text(text), Data(data), Checked(checked), SubMenu(subMenu), UseSlot(false) {}
+ MythMenuItem(const QString &text, const char *slot, bool checked = false, MythMenu *subMenu = NULL) :
+ Text(text), Data(qVariantFromValue(slot)), Checked(checked), SubMenu(subMenu), UseSlot(true) {}
+
+ QString Text;
+ QVariant Data;
+ bool Checked;
+ MythMenu *SubMenu;
+ bool UseSlot;
+};
+
+class MUI_PUBLIC MythMenu
+{
+ friend class MythDialogBox;
+
+ public:
+ MythMenu(const QString &text, QObject *retobject, const QString &resultid);
+ MythMenu(const QString &title, const QString &text, QObject *retobject, const QString &resultid);
+ ~MythMenu(void);
+
+ void AddItem(const QString &title, QVariant data = 0, MythMenu *subMenu = NULL,
+ bool selected = false, bool checked = false);
+ void AddItem(const QString &title, const char *slot, MythMenu *subMenu = NULL,
+ bool selected = false, bool checked = false);
+
+ void SetParent(MythMenu *parent) { m_parentMenu = parent; }
+
+ private:
+ MythMenu *m_parentMenu;
+ QString m_title;
+ QString m_text;
+ QString m_resultid;
+ QObject *m_retObject;
+ QList<MythMenuItem*> m_menuItems;
+ int m_selectedItem;
+};
+
/**
* \class MythDialogBox
*
@@ -67,9 +111,15 @@ class MUI_PUBLIC MythDialogBox : public MythScreenType
MythDialogBox(const QString &title, const QString &text,
MythScreenStack *parent, const char *name,
bool fullscreen = false, bool osd = false);
+ MythDialogBox(MythMenu* menu, MythScreenStack *parent, const char *name,
+ bool fullscreen = false, bool osd = false);
+
+ ~MythDialogBox(void);
virtual bool Create(void);
+ void SetMenuItems(MythMenu *menu);
+
void SetReturnEvent(QObject *retobject, const QString &resultid);
void SetBackAction(const QString &text, QVariant data);
void SetExitAction(const QString &text, QVariant data);
@@ -92,6 +142,7 @@ class MUI_PUBLIC MythDialogBox : public MythScreenType
protected:
void SendEvent(int res, QString text = "", QVariant data = 0);
+ void updateMenu(void);
MythUIText *m_titlearea;
MythUIText *m_textarea;
@@ -109,8 +160,12 @@ class MUI_PUBLIC MythDialogBox : public MythScreenType
QVariant m_backdata;
QString m_exittext;
QVariant m_exitdata;
+
+ MythMenu *m_menu;
+ MythMenu *m_currentMenu;
};
+
/**
* \class MythConfirmationDialog
*
@@ -240,6 +295,7 @@ class MUI_PUBLIC MythUISearchDialog : public MythScreenType
MUI_PUBLIC MythConfirmationDialog *ShowOkPopup(const QString &message, QObject *parent = NULL,
const char *slot = NULL, bool showCancel = false);
+Q_DECLARE_METATYPE(MythMenuItem*)
Q_DECLARE_METATYPE(const char*)
Q_DECLARE_METATYPE(QFileInfo)
View
2 mythtv/themes/MythCenter-wide/base.xml
@@ -701,8 +701,6 @@
<drawfrombottom>yes</drawfrombottom>
<showarrow>no</showarrow>
<wrapstyle>selection</wrapstyle>
- <triggerevent context="Global" action="ESCAPE">LEFT</triggerevent>
- <triggerevent context="Global" action="SELECT">RIGHT</triggerevent>
<statetype name="buttonitem">
<state name="active">
<textarea name="buttontext">

0 comments on commit 94f6bb5

Please sign in to comment.
Something went wrong with that request. Please try again.