Skip to content

Commit

Permalink
MythDialogBox: Allow an hierarchical menu to be passed to the menu di…
Browse files Browse the repository at this point in the history
…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
Paul Harrison committed Sep 28, 2011
1 parent ac5b20c commit 94f6bb5
Show file tree
Hide file tree
Showing 3 changed files with 240 additions and 13 deletions.
195 changes: 184 additions & 11 deletions mythtv/libs/libmythui/mythdialogbox.cpp
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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");
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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")
{
Expand Down Expand Up @@ -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);
}
}

/////////////////////////////////////////////////////////////////
Expand Down
56 changes: 56 additions & 0 deletions mythtv/libs/libmythui/mythdialogbox.h
Expand Up @@ -17,6 +17,8 @@ class MythUIButton;
class MythUITextEdit;
class MythUIImage;
class MythUIStateType;
class MythMenu;


/**
* \class DialogCompletionEvent
Expand Down Expand Up @@ -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
*
Expand All @@ -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);
Expand All @@ -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;
Expand All @@ -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
*
Expand Down Expand Up @@ -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)

Expand Down
2 changes: 0 additions & 2 deletions mythtv/themes/MythCenter-wide/base.xml
Expand Up @@ -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">
Expand Down

0 comments on commit 94f6bb5

Please sign in to comment.