Finalized tab handling for dialogs containing multiple tabs

(for now, only the debugger, but might as well deal with the problem
in a general way once and for all).  The Shift-Left/Right keys now
work as they did before, and switch between tabs in a tabset.
For dialogs with multiple tabs, it now selects among those tabs
where the focused object is.  Clicking on another tabset then changes
the focus, and allows the same keys to switch among *that* tabset.

Now I can finally start the cart-specific bankswitch UI items.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2679 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2013-03-31 20:54:14 +00:00
parent ac1bccf454
commit 831edca24e
10 changed files with 43 additions and 77 deletions

View File

@ -129,7 +129,7 @@ class CartridgeDPCPlus : public Cartridge
@return The name of the object @return The name of the object
*/ */
string name() const { return "CartridgeDPCPlus"; } string name() const { return "CartridgeDPC+"; }
public: public:
/** /**

View File

@ -212,7 +212,8 @@ void Dialog::setFocus(Widget* w)
// Redraw widgets for new focus // Redraw widgets for new focus
_focusedWidget = Widget::setFocusForChain(this, getFocusList(), w, 0); _focusedWidget = Widget::setFocusForChain(this, getFocusList(), w, 0);
cerr << "set focus for " << _focusedWidget << endl; // Update current tab based on new focused widget
getTabIdForWidget(_focusedWidget);
} }
} }
@ -228,7 +229,6 @@ void Dialog::buildCurrentFocusList(int tabID)
Widget* tabFocusWidget = 0; Widget* tabFocusWidget = 0;
if(tabID >= 0 && tabID < (int)_myTabList.size()) if(tabID >= 0 && tabID < (int)_myTabList.size())
{ {
cerr << "save tab, move to next\n";
// Save focus in previously selected tab column, // Save focus in previously selected tab column,
// and get focus for new tab column // and get focus for new tab column
TabFocus& tabfocus = _myTabList[tabID]; TabFocus& tabfocus = _myTabList[tabID];
@ -238,24 +238,12 @@ cerr << "save tab, move to next\n";
_tabID = tabID; _tabID = tabID;
} }
// Special case for dialogs containing only one tab widget, with all items // Add appropriate items from tablist (if present)
// arranged in separate tabs
bool containsSingleTab = _myFocus.list.size() == 1 && _myTabList.size() == 1;
// A dialog containing only one tabwidget should be added first
if(containsSingleTab)
{
_focusList.push_back(_myFocus.list);
_focusedWidget = _focusList[0];
}
// Now add appropriate items from tablist (if present)
for(uInt32 id = 0; id < _myTabList.size(); ++id) for(uInt32 id = 0; id < _myTabList.size(); ++id)
_myTabList[id].appendFocusList(_focusList); _myTabList[id].appendFocusList(_focusList);
// Add remaining items from main focus list // Add remaining items from main focus list
if(!containsSingleTab) _focusList.push_back(_myFocus.list);
_focusList.push_back(_myFocus.list);
// Add button group at end of current focus list // Add button group at end of current focus list
// We do it this way for TabWidget, so that buttons are scanned // We do it this way for TabWidget, so that buttons are scanned
@ -266,9 +254,7 @@ cerr << "save tab, move to next\n";
// Finally, the moment we've all been waiting for :) // Finally, the moment we've all been waiting for :)
// Set the actual focus widget // Set the actual focus widget
if(tabFocusWidget) if(tabFocusWidget)
{cerr << "tab focus changed\n";
_focusedWidget = tabFocusWidget; _focusedWidget = tabFocusWidget;
}
else if(!_focusedWidget && _focusList.size() > 0) else if(!_focusedWidget && _focusList.size() > 0)
_focusedWidget = _focusList[0]; _focusedWidget = _focusList[0];
} }
@ -549,6 +535,9 @@ bool Dialog::handleNavEvent(Event::Type e)
{ {
_focusedWidget = Widget::setFocusForChain(this, getFocusList(), _focusedWidget = Widget::setFocusForChain(this, getFocusList(),
_focusedWidget, -1); _focusedWidget, -1);
// Update current tab based on new focused widget
getTabIdForWidget(_focusedWidget);
return true; return true;
} }
break; break;
@ -558,6 +547,9 @@ bool Dialog::handleNavEvent(Event::Type e)
{ {
_focusedWidget = Widget::setFocusForChain(this, getFocusList(), _focusedWidget = Widget::setFocusForChain(this, getFocusList(),
_focusedWidget, +1); _focusedWidget, +1);
// Update current tab based on new focused widget
getTabIdForWidget(_focusedWidget);
return true; return true;
} }
break; break;
@ -587,30 +579,31 @@ bool Dialog::handleNavEvent(Event::Type e)
return false; return false;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Dialog::getTabIdForWidget(Widget* w)
{
if(_myTabList.size() == 0)
return;
for(uInt32 id = 0; id < _myTabList.size(); ++id)
{
if(w->_boss == _myTabList[id].widget)
{
_tabID = id;
return;
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Dialog::cycleTab(int direction) bool Dialog::cycleTab(int direction)
{ {
cerr << "cycle " << (direction < 0 ? "left" : "right") << ", tabID = " << _tabID << endl;
if(_tabID >= 0 && _tabID < (int)_myTabList.size()) if(_tabID >= 0 && _tabID < (int)_myTabList.size())
{ {
_myTabList[_tabID].widget->cycleTab(direction); _myTabList[_tabID].widget->cycleTab(direction);
return true; return true;
} }
return false; return false;
#if 0
if(key == KBDK_LEFT && _ourTab) // left arrow
{
_ourTab->cycleTab(-1);
return;
}
else if(key == KBDK_RIGHT && _ourTab) // right arrow
{
_ourTab->cycleTab(+1);
return;
}
#endif
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -711,28 +704,10 @@ void Dialog::TabFocus::appendFocusList(WidgetArray& list)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Dialog::TabFocus::saveCurrentFocus(Widget* w) void Dialog::TabFocus::saveCurrentFocus(Widget* w)
{ {
#if 1
if(currentTab >= 0 && currentTab < focus.size())
{
cerr << "chain len = " << focus[currentTab].list.size() << endl;
if(Widget::isWidgetInChain(focus[currentTab].list, w))
{
cerr << "saving widget\n";
focus[currentTab].widget = w;
}
else
cerr << "not in chain\n";
}
#else
if(currentTab >= 0 && currentTab < focus.size() && if(currentTab >= 0 && currentTab < focus.size() &&
Widget::isWidgetInChain(focus[currentTab].list, w)) Widget::isWidgetInChain(focus[currentTab].list, w))
{cerr << "saving widget\n";
focus[currentTab].widget = w; focus[currentTab].widget = w;
} }
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Widget* Dialog::TabFocus::getNewFocus() Widget* Dialog::TabFocus::getNewFocus()

View File

@ -100,6 +100,7 @@ class Dialog : public GuiObject
private: private:
void buildCurrentFocusList(int tabID = -1); void buildCurrentFocusList(int tabID = -1);
bool handleNavEvent(Event::Type e); bool handleNavEvent(Event::Type e);
void getTabIdForWidget(Widget* w);
bool cycleTab(int direction); bool cycleTab(int direction);
protected: protected:

View File

@ -70,7 +70,6 @@ GameInfoDialog::GameInfoDialog(
myTab = new TabWidget(this, font, xpos, ypos, _w - 2*xpos, myTab = new TabWidget(this, font, xpos, ypos, _w - 2*xpos,
_h - buttonHeight - fontHeight - ifont.getLineHeight() - 20); _h - buttonHeight - fontHeight - ifont.getLineHeight() - 20);
addTabWidget(myTab); addTabWidget(myTab);
addFocusWidget(myTab);
// 1) Cartridge properties // 1) Cartridge properties
wid.clear(); wid.clear();

View File

@ -56,8 +56,6 @@ InputDialog::InputDialog(OSystem* osystem, DialogContainer* parent,
xpos = 2; ypos = vBorder; xpos = 2; ypos = vBorder;
myTab = new TabWidget(this, font, xpos, ypos, _w - 2*xpos, _h - buttonHeight - 20); myTab = new TabWidget(this, font, xpos, ypos, _w - 2*xpos, _h - buttonHeight - 20);
addTabWidget(myTab); addTabWidget(myTab);
wid.push_back(myTab);
addToFocusList(wid);
// 1) Event mapper for emulation actions // 1) Event mapper for emulation actions
tabID = myTab->addTab("Emul. Events"); tabID = myTab->addTab("Emul. Events");

View File

@ -92,7 +92,6 @@ RomAuditDialog::RomAuditDialog(OSystem* osystem, DialogContainer* parent,
kTextAlignLeft); kTextAlignLeft);
// Add OK and Cancel buttons // Add OK and Cancel buttons
wid.clear();
addOKCancelBGroup(wid, font, "Audit", "Done"); addOKCancelBGroup(wid, font, "Audit", "Done");
addBGroupToFocusList(wid); addBGroupToFocusList(wid);

View File

@ -73,14 +73,7 @@ int TabWidget::getChildY() const
int TabWidget::addTab(const string& title) int TabWidget::addTab(const string& title)
{ {
// Add a new tab page // Add a new tab page
Tab newTab; _tabs.push_back(Tab(title));
newTab.title = title;
newTab.firstWidget = NULL;
newTab.parentWidget = NULL;
newTab.enabled = true;
_tabs.push_back(newTab);
int numTabs = _tabs.size(); int numTabs = _tabs.size();
// Determine the new tab width // Determine the new tab width
@ -145,7 +138,7 @@ void TabWidget::updateActiveTab()
void TabWidget::activateTabs() void TabWidget::activateTabs()
{ {
for(unsigned int i = 0; i <_tabs.size(); ++i) for(unsigned int i = 0; i <_tabs.size(); ++i)
sendCommand(kTabChangedCmd, i-1, -1); sendCommand(kTabChangedCmd, i-1, _id);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -315,7 +308,7 @@ void TabWidget::drawWidget(bool hilite)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Widget *TabWidget::findWidget(int x, int y) Widget* TabWidget::findWidget(int x, int y)
{ {
if (y < _tabHeight) if (y < _tabHeight)
{ {

View File

@ -31,14 +31,6 @@
class TabWidget : public Widget, public CommandSender class TabWidget : public Widget, public CommandSender
{ {
struct Tab {
string title;
Widget* firstWidget;
Widget* parentWidget;
bool enabled;
};
typedef Common::Array<Tab> TabList;
public: public:
TabWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h); TabWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h);
~TabWidget(); ~TabWidget();
@ -77,7 +69,18 @@ class TabWidget : public Widget, public CommandSender
virtual void drawWidget(bool hilite); virtual void drawWidget(bool hilite);
virtual Widget* findWidget(int x, int y); virtual Widget* findWidget(int x, int y);
protected: private:
struct Tab {
string title;
Widget* firstWidget;
Widget* parentWidget;
bool enabled;
Tab(const string& t = "", Widget* first = 0, Widget* parent = 0, bool e = true)
: title(t), firstWidget(first), parentWidget(parent), enabled(e) { }
};
typedef Common::Array<Tab> TabList;
TabList _tabs; TabList _tabs;
int _tabWidth; int _tabWidth;
int _tabHeight; int _tabHeight;

View File

@ -61,7 +61,6 @@ UIDialog::UIDialog(OSystem* osystem, DialogContainer* parent,
xpos = ypos = vBorder; xpos = ypos = vBorder;
myTab = new TabWidget(this, font, xpos, ypos, _w - 2*xpos, _h - buttonHeight - 20); myTab = new TabWidget(this, font, xpos, ypos, _w - 2*xpos, _h - buttonHeight - 20);
addTabWidget(myTab); addTabWidget(myTab);
addFocusWidget(myTab);
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
// 1) Launcher options // 1) Launcher options

View File

@ -66,7 +66,6 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent,
xpos = ypos = 5; xpos = ypos = 5;
myTab = new TabWidget(this, font, xpos, ypos, _w - 2*xpos, _h - buttonHeight - 20); myTab = new TabWidget(this, font, xpos, ypos, _w - 2*xpos, _h - buttonHeight - 20);
addTabWidget(myTab); addTabWidget(myTab);
addFocusWidget(myTab);
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
// 1) General options // 1) General options