diff --git a/stella/src/build/makefile b/stella/src/build/makefile index bf0090300..668f688aa 100644 --- a/stella/src/build/makefile +++ b/stella/src/build/makefile @@ -13,7 +13,7 @@ ## See the file "license" for information on usage and redistribution of ## this file, and for a DISCLAIMER OF ALL WARRANTIES. ## -## $Id: makefile,v 1.89 2005-06-09 04:31:44 urchlay Exp $ +## $Id: makefile,v 1.90 2005-06-10 17:46:05 stephena Exp $ ##============================================================================ ##============================================================================ @@ -160,7 +160,7 @@ GUI_OBJS = Font.o Menu.o Launcher.o Debugger.o \ EventMappingDialog.o GameInfoDialog.o HelpDialog.o AboutDialog.o \ LauncherDialog.o LauncherOptionsDialog.o BrowserDialog.o GameList.o \ ProgressDialog.o \ - DebuggerDialog.o PromptDialog.o + DebuggerDialog.o PromptWidget.o CORE_OBJS = Booster.o Cart.o Cart2K.o Cart3F.o Cart4K.o CartAR.o CartDPC.o \ CartE0.o CartE7.o CartF4.o CartF4SC.o CartF6.o CartF6SC.o \ @@ -453,8 +453,8 @@ ProgressDialog.o: $(GUI)/ProgressDialog.cxx $(GUI)/ProgressDialog.hxx DebuggerDialog.o: $(GUI)/DebuggerDialog.cxx $(GUI)/DebuggerDialog.hxx $(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(GUI)/DebuggerDialog.cxx -PromptDialog.o: $(GUI)/PromptDialog.cxx $(GUI)/PromptDialog.hxx - $(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(GUI)/PromptDialog.cxx +PromptWidget.o: $(GUI)/PromptWidget.cxx $(GUI)/PromptWidget.hxx + $(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(GUI)/PromptWidget.cxx DebuggerParser.o: $(COMMON)/DebuggerParser.cxx $(COMMON)/DebuggerParser.hxx $(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(COMMON)/DebuggerParser.cxx diff --git a/stella/src/emucore/OSystem.cxx b/stella/src/emucore/OSystem.cxx index 5221b657a..b2dcda4fc 100644 --- a/stella/src/emucore/OSystem.cxx +++ b/stella/src/emucore/OSystem.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: OSystem.cxx,v 1.23 2005-06-08 18:45:08 stephena Exp $ +// $Id: OSystem.cxx,v 1.24 2005-06-10 17:46:06 stephena Exp $ //============================================================================ #include @@ -88,6 +88,9 @@ OSystem::OSystem() #ifdef DEVELOPER_SUPPORT myFeatures += "Debugger"; #endif + + // When we first start Stella, no GUI widget is active + GuiObject::resetActiveWidget(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/gui/DebuggerDialog.cxx b/stella/src/gui/DebuggerDialog.cxx index 6bd9371db..1f05f6e67 100644 --- a/stella/src/gui/DebuggerDialog.cxx +++ b/stella/src/gui/DebuggerDialog.cxx @@ -13,149 +13,110 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: DebuggerDialog.cxx,v 1.6 2005-06-09 20:09:22 stephena Exp $ +// $Id: DebuggerDialog.cxx,v 1.7 2005-06-10 17:46:06 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project //============================================================================ -#include "DialogContainer.hxx" -#include "PromptDialog.hxx" +#include "TabWidget.hxx" +#include "ListWidget.hxx" +#include "PromptWidget.hxx" #include "DebuggerDialog.hxx" -enum { - kPromptCmd = 'PRMT', - kCpuCmd = 'CPU ', - kRamCmd = 'RAM ', - kRomCmd = 'ROM ', - kTiaCmd = 'TIA ', - kCodeCmd = 'CODE' -}; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DebuggerDialog::DebuggerDialog(OSystem* osystem, DialogContainer* parent, int x, int y, int w, int h) : Dialog(osystem, parent, x, y, w, h), - myPromptDialog(NULL), - myCpuDialog(NULL), - myRamDialog(NULL), - myRomDialog(NULL), - myTiaDialog(NULL), - myCodeDialog(NULL) + myTab(NULL) { - const int border = 5; - const int space = 5; - const int width = 40; - int xpos = border; + const int vBorder = 4; + int yoffset; - // Add a row of buttons for the various debugger operations - new ButtonWidget(this, xpos, border, width, 16, "Prompt", kPromptCmd, 0); - xpos += space + width; - new ButtonWidget(this, xpos, border, width, 16, "CPU", kCpuCmd, 0); - xpos += space + width; - new ButtonWidget(this, xpos, border, width, 16, "RAM", kRamCmd, 0); - xpos += space + width; - new ButtonWidget(this, xpos, border, width, 16, "ROM", kRomCmd, 0); - xpos += space + width; - new ButtonWidget(this, xpos, border, width, 16, "TIA", kTiaCmd, 0); - xpos += space + width; - new ButtonWidget(this, xpos, border, width, 16, "Code", kCodeCmd, 0); - xpos += space + width; + // The tab widget + myTab = new TabWidget(this, 0, vBorder, _w, _h - vBorder - 1); - const int xoff = border; - const int yoff = border + 16 + 2; + // 1) The Prompt/console tab + myTab->addTab("Prompt"); + yoffset = vBorder; - // Create the debugger dialog boxes - myPromptDialog = new PromptDialog(osystem, parent, x + xoff, y + yoff, - w - xoff - 2, h - yoff - 3); + PromptWidget* prompt = new PromptWidget(myTab, 2, 2, + _w - vBorder, _h - 25); + myTab->setActiveWidget(0, prompt); + + // 2) The CPU tab + myTab->addTab("CPU"); + yoffset = vBorder; + +///////////////////// FIXME - just testing, will be removed + ListWidget* myList = new ListWidget(myTab, 10, 24, 100, _h - 24 - 26 - 10 - 10); + myList->setEditable(false); + myList->setNumberingMode(kListNumberingOff); + + StringList l; + for (int i = 0; i < 10; ++i) + l.push_back("TESTING!!!"); + myList->setList(l); + + ListWidget* myList2 = new ListWidget(myTab, 150, 24, 100, _h - 24 - 26 - 10 - 10); + myList2->setEditable(false); + myList2->setNumberingMode(kListNumberingOff); + + StringList l2; + for (int i = 0; i < 10; ++i) + l2.push_back("TESTING AGAIN!!!"); + myList2->setList(l2); + + ListWidget* myList3 = new ListWidget(myTab, 300, 24, 100, _h - 24 - 26 - 10 - 10); + myList3->setEditable(false); + myList3->setNumberingMode(kListNumberingOff); + + StringList l3; + for (int i = 0; i < 10; ++i) + l3.push_back("CPU_TESTING!!!"); + myList3->setList(l3); + + myTab->setActiveWidget(1, myList); +///////////////////////////// + + // 3) The RAM tab + myTab->addTab("RAM"); + yoffset = vBorder; + + + // 4) The ROM tab + myTab->addTab("ROM"); + yoffset = vBorder; + + + // 5) The TIA tab + myTab->addTab("TIA"); + yoffset = vBorder; + + + // 6) The RAM tab + myTab->addTab("Code"); + yoffset = vBorder; + + + + + // Set active tab to prompt + myTab->setActiveTab(0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DebuggerDialog::~DebuggerDialog() { - delete myPromptDialog; -/* - delete myCpuDialog; - delete myRamDialog; - delete myRomDialog; - delete myTiaDialog; - delete myCodeDialog; -*/ -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void DebuggerDialog::addButtons(GuiObject* boss) -{ - // This is a terrible hack, but it does seem to work ... - const int border = 5; - const int space = 5; - const int width = 40; - int xpos = border; - - // Add a row of buttons for the various debugger operations - new ButtonWidget(boss, xpos, border, width, 16, "Prompt", kPromptCmd, 0); - xpos += space + width; - new ButtonWidget(boss, xpos, border, width, 16, "CPU", kCpuCmd, 0); - xpos += space + width; - new ButtonWidget(boss, xpos, border, width, 16, "RAM", kRamCmd, 0); - xpos += space + width; - new ButtonWidget(boss, xpos, border, width, 16, "ROM", kRomCmd, 0); - xpos += space + width; - new ButtonWidget(boss, xpos, border, width, 16, "TIA", kTiaCmd, 0); - xpos += space + width; - new ButtonWidget(boss, xpos, border, width, 16, "Code", kCodeCmd, 0); - xpos += space + width; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DebuggerDialog::loadConfig() { - // Auto-select the command prompt - parent()->addDialog(myPromptDialog); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void DebuggerDialog::handleCommand(CommandSender* sender, int cmd, int data) +void DebuggerDialog::handleKeyDown(int ascii, int keycode, int modifiers) { - switch (cmd) - { - case kPromptCmd: - parent()->reStack(); - parent()->addDialog(myPromptDialog); - break; - - case kCpuCmd: - parent()->reStack(); -// parent()->addDialog(myCpuDialog); - cerr << "kCpuCmd\n"; - break; - - case kRamCmd: - parent()->reStack(); -// parent()->addDialog(myRamDialog); - cerr << "kRamCmd\n"; - break; - - case kRomCmd: - parent()->reStack(); -// parent()->addDialog(myRomDialog); - cerr << "kRomCmd\n"; - break; - - case kTiaCmd: - parent()->reStack(); -// parent()->addDialog(myTiaDialog); - cerr << "kTiaCmd\n"; - break; - - case kCodeCmd: - parent()->reStack(); -// parent()->addDialog(myCodeDialog); - cerr << "kCodeCmd\n"; - break; - - default: - Dialog::handleCommand(sender, cmd, data); - break; - } + myTab->handleKeyDown(ascii, keycode, modifiers); } diff --git a/stella/src/gui/DebuggerDialog.hxx b/stella/src/gui/DebuggerDialog.hxx index 3c856d3bb..71d18aa3e 100644 --- a/stella/src/gui/DebuggerDialog.hxx +++ b/stella/src/gui/DebuggerDialog.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: DebuggerDialog.hxx,v 1.4 2005-06-09 19:04:59 stephena Exp $ +// $Id: DebuggerDialog.hxx,v 1.5 2005-06-10 17:46:06 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -24,12 +24,7 @@ class OSystem; class DialogContainer; -class PromptDialog; -class CpuDialog; -class RamDialog; -class RomDialog; -class TiaDialog; -class CodeDialog; +class TabWidget; #include "Dialog.hxx" @@ -41,18 +36,10 @@ class DebuggerDialog : public Dialog ~DebuggerDialog(); virtual void loadConfig(); - virtual void handleCommand(CommandSender* sender, int cmd, int data); - - void addButtons(GuiObject* boss); + virtual void handleKeyDown(int ascii, int keycode, int modifiers); protected: - // The debugger dialogs - PromptDialog* myPromptDialog; - CpuDialog* myCpuDialog; - RamDialog* myRamDialog; - RomDialog* myRomDialog; - TiaDialog* myTiaDialog; - CodeDialog* myCodeDialog; + TabWidget* myTab; }; #endif diff --git a/stella/src/gui/Dialog.cxx b/stella/src/gui/Dialog.cxx index 338ec0554..806b93555 100644 --- a/stella/src/gui/Dialog.cxx +++ b/stella/src/gui/Dialog.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Dialog.cxx,v 1.18 2005-05-26 18:56:58 stephena Exp $ +// $Id: Dialog.cxx,v 1.19 2005-06-10 17:46:06 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -280,14 +280,6 @@ void Dialog::handleJoyUp(int stick, int button) _focusedWidget->handleJoyUp(stick, button); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Dialog::handleTickle() -{ - // Focused widget receives tickle notifications - if(_focusedWidget && _focusedWidget->getFlags() & WIDGET_WANT_TICKLE) - _focusedWidget->handleTickle(); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Dialog::handleCommand(CommandSender* sender, int cmd, int data) { diff --git a/stella/src/gui/Dialog.hxx b/stella/src/gui/Dialog.hxx index 34ea28b78..59a421d90 100644 --- a/stella/src/gui/Dialog.hxx +++ b/stella/src/gui/Dialog.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Dialog.hxx,v 1.15 2005-05-26 15:43:44 stephena Exp $ +// $Id: Dialog.hxx,v 1.16 2005-06-10 17:46:06 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -35,7 +35,7 @@ class DialogContainer; This is the base class for all dialog boxes. @author Stephen Anthony - @version $Id: Dialog.hxx,v 1.15 2005-05-26 15:43:44 stephena Exp $ + @version $Id: Dialog.hxx,v 1.16 2005-06-10 17:46:06 stephena Exp $ */ class Dialog : public GuiObject { @@ -61,7 +61,6 @@ class Dialog : public GuiObject virtual void draw(); void releaseFocus(); - virtual void handleTickle(); // Called periodically (in every guiloop() ) virtual void handleKeyDown(int ascii, int keycode, int modifiers); virtual void handleKeyUp(int ascii, int keycode, int modifiers); virtual void handleMouseDown(int x, int y, int button, int clickCount); diff --git a/stella/src/gui/GuiObject.hxx b/stella/src/gui/GuiObject.hxx index 53a369511..2cd86d8b9 100644 --- a/stella/src/gui/GuiObject.hxx +++ b/stella/src/gui/GuiObject.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: GuiObject.hxx,v 1.9 2005-05-21 16:12:13 stephena Exp $ +// $Id: GuiObject.hxx,v 1.10 2005-06-10 17:46:06 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -33,7 +33,7 @@ class Widget; This is the base class for all GUI objects/widgets. @author Stephen Anthony - @version $Id: GuiObject.hxx,v 1.9 2005-05-21 16:12:13 stephena Exp $ + @version $Id: GuiObject.hxx,v 1.10 2005-06-10 17:46:06 stephena Exp $ */ class GuiObject : public CommandReceiver { @@ -68,6 +68,8 @@ class GuiObject : public CommandReceiver virtual bool isVisible() const = 0; virtual void draw() = 0; + static void resetActiveWidget() { _activeWidget = NULL; } + protected: OSystem* myOSystem; DialogContainer* myParent; @@ -76,6 +78,7 @@ class GuiObject : public CommandReceiver int _w, _h; Widget* _firstWidget; + static Widget* _activeWidget; protected: virtual void releaseFocus() = 0; diff --git a/stella/src/gui/GuiUtils.hxx b/stella/src/gui/GuiUtils.hxx index 375e89390..3f85e7e4e 100644 --- a/stella/src/gui/GuiUtils.hxx +++ b/stella/src/gui/GuiUtils.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: GuiUtils.hxx,v 1.9 2005-06-07 01:14:39 stephena Exp $ +// $Id: GuiUtils.hxx,v 1.10 2005-06-10 17:46:06 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -29,7 +29,7 @@ Probably not very neat, but at least it works ... @author Stephen Anthony - @version $Id: GuiUtils.hxx,v 1.9 2005-06-07 01:14:39 stephena Exp $ + @version $Id: GuiUtils.hxx,v 1.10 2005-06-10 17:46:06 stephena Exp $ */ #define kLineHeight 12 @@ -48,12 +48,13 @@ enum OverlayColor { // The commands generated by various widgets enum { - kOKCmd = 'OK ', - kCloseCmd = 'CLOS', - kNextCmd = 'NEXT', - kPrevCmd = 'PREV', - kDefaultsCmd = 'DEFA', - kSetPositionCmd = 'SETP', + kOKCmd = 'OK ', + kCloseCmd = 'CLOS', + kNextCmd = 'NEXT', + kPrevCmd = 'PREV', + kDefaultsCmd = 'DEFA', + kSetPositionCmd = 'SETP', + kActiveWidgetCmd = 'ACTW', kRendererChanged, kAspectRatioChanged, kFrameRateChanged, diff --git a/stella/src/gui/LauncherDialog.cxx b/stella/src/gui/LauncherDialog.cxx index 64e7326e2..5cb93dbfc 100644 --- a/stella/src/gui/LauncherDialog.cxx +++ b/stella/src/gui/LauncherDialog.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: LauncherDialog.cxx,v 1.20 2005-06-08 18:45:09 stephena Exp $ +// $Id: LauncherDialog.cxx,v 1.21 2005-06-10 17:46:06 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -97,6 +97,7 @@ LauncherDialog::LauncherDialog(OSystem* osystem, DialogContainer* parent, myList = new ListWidget(this, 10, 24, _w - 20, _h - 24 - 26 - 10 - 10); myList->setEditable(false); myList->setNumberingMode(kListNumberingOff); + myList->clearFlags(WIDGET_TAB_NAVIGATE); // Add note textwidget to show any notes for the currently selected ROM new StaticTextWidget(this, 20, _h - 43, 30, 16, "Note:", kTextAlignLeft); diff --git a/stella/src/gui/ListWidget.cxx b/stella/src/gui/ListWidget.cxx index 69ba76e81..bd5b55f9a 100644 --- a/stella/src/gui/ListWidget.cxx +++ b/stella/src/gui/ListWidget.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: ListWidget.cxx,v 1.13 2005-06-09 20:09:23 stephena Exp $ +// $Id: ListWidget.cxx,v 1.14 2005-06-10 17:46:06 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -36,7 +36,8 @@ ListWidget::ListWidget(GuiObject* boss, int x, int y, int w, int h) : Widget(boss, x, y, w - kScrollBarWidth, h), CommandSender(boss) { - _flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS; + _flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS | + WIDGET_TAB_NAVIGATE; _type = kListWidget; _numberingMode = kListNumberingOne; _entriesPerPage = (_h - 2) / kLineHeight; @@ -138,6 +139,10 @@ void ListWidget::handleMouseDown(int x, int y, int button, int clickCount) { if (isEnabled()) { + // A click indicated this widget has been selected + // It should receive focus (because it has the WIDGET_TAB_NAVIGATE property) + receivedFocus(); + int oldSelectedItem = _selectedItem; _selectedItem = (y - 1) / kLineHeight + _currentPos; if (_selectedItem > (int)_list.size() - 1) diff --git a/stella/src/gui/PromptDialog.cxx b/stella/src/gui/PromptWidget.cxx similarity index 86% rename from stella/src/gui/PromptDialog.cxx rename to stella/src/gui/PromptWidget.cxx index c4f45d127..cbd1f00ca 100644 --- a/stella/src/gui/PromptDialog.cxx +++ b/stella/src/gui/PromptWidget.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: PromptDialog.cxx,v 1.9 2005-06-09 20:09:23 stephena Exp $ +// $Id: PromptWidget.cxx,v 1.1 2005-06-10 17:46:06 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -26,7 +26,7 @@ #include "Debugger.hxx" #include "DebuggerDialog.hxx" -#include "PromptDialog.hxx" +#include "PromptWidget.hxx" #define PROMPT "> " @@ -39,10 +39,14 @@ */ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -PromptDialog::PromptDialog(OSystem* osystem, DialogContainer* parent, - int x, int y, int w, int h) - : Dialog(osystem, parent, x, y, w, h) +PromptWidget::PromptWidget(GuiObject* boss, int x, int y, int w, int h) + : Widget(boss, x, y, w - kScrollBarWidth, h), + CommandSender(boss) { + _flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS | + WIDGET_TAB_NAVIGATE; + _type = kPromptWidget; + _kConsoleCharWidth = instance()->consoleFont().getMaxCharWidth(); _kConsoleLineHeight = instance()->consoleFont().getFontHeight() + 2; @@ -58,7 +62,8 @@ PromptDialog::PromptDialog(OSystem* osystem, DialogContainer* parent, _firstLineInBuffer = 0; // Add scrollbar - _scrollBar = new ScrollBarWidget(this, _w - kScrollBarWidth - 1, 0, kScrollBarWidth, _h); + _scrollBar = new ScrollBarWidget(boss, _x + _w, _y, kScrollBarWidth, _h); + _scrollBar->setTarget(this); // Init History @@ -74,27 +79,19 @@ PromptDialog::PromptDialog(OSystem* osystem, DialogContainer* parent, string version = string("Stella version ") + STELLA_VERSION + "\n"; print(version.c_str()); print("Debugger is ready\n"); + print(PROMPT); + _promptStartPos = _promptEndPos = _currentPos; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -PromptDialog::~PromptDialog() +PromptWidget::~PromptWidget() { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::loadConfig() +void PromptWidget::drawWidget(bool hilite) { - if (_promptStartPos == -1) - { - print(PROMPT); - _promptStartPos = _promptEndPos = _currentPos; - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::drawDialog() -{ - FrameBuffer& fb = instance()->frameBuffer(); + FrameBuffer& fb = _boss->instance()->frameBuffer(); // Fill the background fb.fillRect(_x, _y, _w, _h, kBGColor); @@ -127,15 +124,24 @@ void PromptDialog::drawDialog() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::handleMouseWheel(int x, int y, int direction) +void PromptWidget::handleMouseDown(int x, int y, int button, int clickCount) +{ +return; + _scrollBar->handleMouseDown(x, y, button, clickCount); +cerr << "PromptWidget::handleMouseDown\n"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void PromptWidget::handleMouseWheel(int x, int y, int direction) { _scrollBar->handleMouseWheel(x, y, direction); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::handleKeyDown(int ascii, int keycode, int modifiers) +bool PromptWidget::handleKeyDown(int ascii, int keycode, int modifiers) { int i; + bool handled = true; switch (keycode) { @@ -185,34 +191,6 @@ void PromptDialog::handleKeyDown(int ascii, int keycode, int modifiers) instance()->frameBuffer().refresh(); break; -#if 0 // FIXME - this may not be included in the 2.0 release - case 9: // tab - { - if (_completionCallbackProc) - { - int len = _currentPos - _promptStartPos; - assert(len >= 0); - char *str = new char[len + 1]; - - // Copy the user input to str - for (i = 0; i < len; i++) - str[i] = buffer(_promptStartPos + i); - str[len] = '\0'; - - char *completion = 0; - if ((*_completionCallbackProc)(this, str, completion, _callbackRefCon)) - { - insertIntoPrompt(completion); - scrollToCurrent(); - draw(); - instance()->frameBuffer().refresh(); - delete[] completion; - } - delete[] str; - } - break; - } -#endif case 127: killChar(+1); draw(); @@ -317,12 +295,16 @@ void PromptDialog::handleKeyDown(int ascii, int keycode, int modifiers) putchar(ascii); scrollToCurrent(); } + else + handled = false; break; } + + return handled; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::insertIntoPrompt(const char* str) +void PromptWidget::insertIntoPrompt(const char* str) { unsigned int l = strlen(str); @@ -337,7 +319,7 @@ void PromptDialog::insertIntoPrompt(const char* str) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::handleCommand(CommandSender* sender, int cmd, int data) +void PromptWidget::handleCommand(CommandSender* sender, int cmd, int data) { switch (cmd) { @@ -354,7 +336,7 @@ void PromptDialog::handleCommand(CommandSender* sender, int cmd, int data) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::specialKeys(int keycode) +void PromptWidget::specialKeys(int keycode) { bool handled = false; @@ -399,7 +381,7 @@ void PromptDialog::specialKeys(int keycode) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::killChar(int direction) +void PromptWidget::killChar(int direction) { if(direction == -1) // Delete previous character (backspace) { @@ -431,7 +413,7 @@ void PromptDialog::killChar(int direction) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::killLine(int direction) +void PromptWidget::killLine(int direction) { if(direction == -1) // erase from current position to beginning of line { @@ -450,7 +432,7 @@ void PromptDialog::killLine(int direction) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::killLastWord() +void PromptWidget::killLastWord() { int cnt = 0; bool space = true; @@ -476,7 +458,7 @@ void PromptDialog::killLastWord() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::addToHistory(const char *str) +void PromptWidget::addToHistory(const char *str) { strcpy(_history[_historyIndex], str); _historyIndex = (_historyIndex + 1) % kHistorySize; @@ -487,7 +469,7 @@ void PromptDialog::addToHistory(const char *str) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::historyScroll(int direction) +void PromptWidget::historyScroll(int direction) { if (_historySize == 0) return; @@ -534,7 +516,7 @@ void PromptDialog::historyScroll(int direction) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::nextLine() +void PromptWidget::nextLine() { int line = _currentPos / _lineWidth; if (line == _scrollLine) @@ -548,7 +530,7 @@ void PromptDialog::nextLine() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Call this (at least) when the current line changes or when a new line is added -void PromptDialog::updateScrollBuffer() +void PromptWidget::updateScrollBuffer() { int lastchar = MAX(_promptEndPos, _currentPos); int line = lastchar / _lineWidth; @@ -571,7 +553,7 @@ void PromptDialog::updateScrollBuffer() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int PromptDialog::printf(const char *format, ...) +int PromptWidget::printf(const char *format, ...) { va_list argptr; @@ -582,7 +564,7 @@ int PromptDialog::printf(const char *format, ...) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int PromptDialog::vprintf(const char *format, va_list argptr) +int PromptWidget::vprintf(const char *format, va_list argptr) { char buf[2048]; @@ -596,7 +578,7 @@ int PromptDialog::vprintf(const char *format, va_list argptr) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::putchar(int c) +void PromptWidget::putchar(int c) { putcharIntern(c); @@ -605,7 +587,7 @@ void PromptDialog::putchar(int c) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::putcharIntern(int c) +void PromptWidget::putcharIntern(int c) { if (c == '\n') nextLine(); @@ -622,13 +604,13 @@ void PromptDialog::putcharIntern(int c) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::print(string str) // laziness/convenience method +void PromptWidget::print(string str) // laziness/convenience method { print(str.c_str()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::print(const char *str) +void PromptWidget::print(const char *str) { while (*str) putcharIntern(*str++); @@ -638,9 +620,9 @@ void PromptDialog::print(const char *str) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::drawCaret() +void PromptWidget::drawCaret() { - FrameBuffer& fb = instance()->frameBuffer(); + FrameBuffer& fb = _boss->instance()->frameBuffer(); int line = _currentPos / _lineWidth; @@ -654,11 +636,11 @@ void PromptDialog::drawCaret() char c = buffer(_currentPos); fb.fillRect(x, y, _kConsoleCharWidth, _kConsoleLineHeight, kTextColor); - fb.drawChar(instance()->consoleFont(), c, x, y + 2, kBGColor); + fb.drawChar(_boss->instance()->consoleFont(), c, x, y + 2, kBGColor); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PromptDialog::scrollToCurrent() +void PromptWidget::scrollToCurrent() { int line = _promptEndPos / _lineWidth; diff --git a/stella/src/gui/PromptDialog.hxx b/stella/src/gui/PromptWidget.hxx similarity index 80% rename from stella/src/gui/PromptDialog.hxx rename to stella/src/gui/PromptWidget.hxx index a72143c90..871513f9c 100644 --- a/stella/src/gui/PromptDialog.hxx +++ b/stella/src/gui/PromptWidget.hxx @@ -13,21 +13,23 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: PromptDialog.hxx,v 1.7 2005-06-09 20:09:23 stephena Exp $ +// $Id: PromptWidget.hxx,v 1.1 2005-06-10 17:46:06 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project //============================================================================ -#ifndef PROMPT_DIALOG_HXX -#define PROMPT_DIALOG_HXX +#ifndef PROMPT_WIDGET_HXX +#define PROMPT_WIDGET_HXX -class CommandSender; -class DialogContainer; class ScrollBarWidget; #include -#include "Dialog.hxx" + +#include "GuiObject.hxx" +#include "Widget.hxx" +#include "Command.hxx" +#include "bspf.hxx" enum { kBufferSize = 32768, @@ -36,12 +38,11 @@ enum { kHistorySize = 20 }; -class PromptDialog : public Dialog +class PromptWidget : public Widget, public CommandSender { public: - PromptDialog(OSystem* osystem, DialogContainer* parent, - int x, int y, int w, int h); - virtual ~PromptDialog(); + PromptWidget(GuiObject* boss, int x, int y, int w, int h); + virtual ~PromptWidget(); public: int printf(const char *format, ...); @@ -52,7 +53,7 @@ class PromptDialog : public Dialog protected: inline char &buffer(int idx) { return _buffer[idx % kBufferSize]; } - void drawDialog(); + void drawWidget(bool hilite); void drawCaret(); void putcharIntern(int c); void insertIntoPrompt(const char *str); @@ -72,11 +73,10 @@ class PromptDialog : public Dialog void addToHistory(const char *str); void historyScroll(int direction); - private: + void handleMouseDown(int x, int y, int button, int clickCount); void handleMouseWheel(int x, int y, int direction); - void handleKeyDown(int ascii, int keycode, int modifiers); + bool handleKeyDown(int ascii, int keycode, int modifiers); void handleCommand(CommandSender* sender, int cmd, int data); - void loadConfig(); protected: char _buffer[kBufferSize]; diff --git a/stella/src/gui/ScrollBarWidget.cxx b/stella/src/gui/ScrollBarWidget.cxx index d5c1d4671..3c86e9b8c 100644 --- a/stella/src/gui/ScrollBarWidget.cxx +++ b/stella/src/gui/ScrollBarWidget.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: ScrollBarWidget.cxx,v 1.5 2005-05-21 16:12:13 stephena Exp $ +// $Id: ScrollBarWidget.cxx,v 1.6 2005-06-10 17:46:06 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -192,27 +192,6 @@ void ScrollBarWidget::handleMouseMoved(int x, int y, int button) } } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ScrollBarWidget::handleTickle() { -/* - // FIXME/TODO - this code is supposed to allow for "click-repeat" (like key repeat), - // i.e. if you click on one of the arrows and keep clicked, it will scroll - // continuously. However, just like key repeat, this requires two delays: - // First an "initial" delay that has to pass before repeating starts (otherwise - // it is near to impossible to achieve single clicks). Secondly, a repeat delay - // that determines how often per second a click is simulated. - int old_pos = _currentPos; - - if (_draggingPart == kUpArrowPart) - _currentPos--; - else if (_draggingPart == kDownArrowPart) - _currentPos++; - - // Make sure that _currentPos is still inside the bounds - checkBounds(old_pos); -*/ -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ScrollBarWidget::checkBounds(int old_pos) { diff --git a/stella/src/gui/ScrollBarWidget.hxx b/stella/src/gui/ScrollBarWidget.hxx index e7b20c0d5..f36cfde3d 100644 --- a/stella/src/gui/ScrollBarWidget.hxx +++ b/stella/src/gui/ScrollBarWidget.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: ScrollBarWidget.hxx,v 1.2 2005-05-13 18:28:06 stephena Exp $ +// $Id: ScrollBarWidget.hxx,v 1.3 2005-06-10 17:46:06 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -49,7 +49,6 @@ class ScrollBarWidget : public Widget, public CommandSender virtual void handleMouseMoved(int x, int y, int button); virtual void handleMouseEntered(int button) { setFlags(WIDGET_HILITED); } virtual void handleMouseLeft(int button) { clearFlags(WIDGET_HILITED); _part = kNoPart; draw(); } - virtual void handleTickle(); // FIXME - this should be private, but then we also have to add accessors // for _numEntries, _entriesPerPage and _currentPos. This again leads to the question: diff --git a/stella/src/gui/TabWidget.cxx b/stella/src/gui/TabWidget.cxx index 0e89a4207..9ce0d9bc6 100644 --- a/stella/src/gui/TabWidget.cxx +++ b/stella/src/gui/TabWidget.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: TabWidget.cxx,v 1.3 2005-06-08 18:45:09 stephena Exp $ +// $Id: TabWidget.cxx,v 1.4 2005-06-10 17:46:06 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -35,6 +35,9 @@ enum { kTabPadding = 3 }; +// +Widget* GuiObject::_activeWidget; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TabWidget::TabWidget(GuiObject *boss, int x, int y, int w, int h) : Widget(boss, x, y, w, h), @@ -54,6 +57,7 @@ TabWidget::~TabWidget() { delete _tabs[i].firstWidget; _tabs[i].firstWidget = 0; + // _tabs[i].activeWidget is deleted elsewhere } _tabs.clear(); } @@ -71,6 +75,7 @@ int TabWidget::addTab(const string& title) Tab newTab; newTab.title = title; newTab.firstWidget = NULL; + newTab.activeWidget = NULL; _tabs.push_back(newTab); @@ -102,13 +107,74 @@ void TabWidget::setActiveTab(int tabID) _tabs[_activeTab].firstWidget = _firstWidget; _activeTab = tabID; - _firstWidget = _tabs[tabID].firstWidget; - _boss->draw(); + _firstWidget = _tabs[tabID].firstWidget; + // If a widget has been activated elsewhere and it belongs to the + // current view, use it. Otherwise use the default. + if(_activeWidget && isWidgetInChain(_firstWidget, _activeWidget)) + _tabs[tabID].activeWidget = _activeWidget; + else + _activeWidget = _tabs[tabID].activeWidget; + + // Make sure this widget receives focus, and that the other widgets + // in the tabview lose focus + if(_activeWidget) + _activeWidget->receivedFocus(); + + _boss->draw(); _boss->instance()->frameBuffer().refresh(); } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void TabWidget::cycleTab(int direction) +{ + int tabID = _activeTab; + + // Don't do anything if no tabs have been defined + if(tabID == -1) + return; + + if(direction == -1) // Go to the previous tab, wrap around at beginning + { + tabID--; + if(tabID == -1) + tabID = (int)_tabs.size() - 1; + } + else if(direction == 1) // Go to the next tab, wrap around at end + { + tabID++; + if(tabID == (int)_tabs.size()) + tabID = 0; + } + + // Finally, select the active tab + setActiveTab(tabID); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void TabWidget::cycleWidget(int direction) +{ + // Don't do anything if no tabs have been defined + if(_activeTab == -1) + return; + + if(direction == -1) + Widget::setPrevInChain(_tabs[_activeTab].firstWidget, + _tabs[_activeTab].activeWidget); + else if(direction == +1) + Widget::setNextInChain(_tabs[_activeTab].firstWidget, + _tabs[_activeTab].activeWidget); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void TabWidget::setActiveWidget(int tabID, Widget* widID) +{ + assert(0 <= tabID && tabID < (int)_tabs.size()); + _tabs[tabID].activeWidget = widID; + widID->receivedFocus(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void TabWidget::handleMouseDown(int x, int y, int button, int clickCount) { @@ -132,10 +198,53 @@ void TabWidget::handleMouseDown(int x, int y, int button, int clickCount) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool TabWidget::handleKeyDown(int ascii, int keycode, int modifiers) { - // TODO: maybe there should be a way to switch between tabs - // using the keyboard? E.g. Alt-Shift-Left/Right-Arrow or something - // like that. - return Widget::handleKeyDown(ascii, keycode, modifiers); + // Test for TAB character + // Ctrl-Tab selects next tab + // Shift-Ctrl-Tab selects previous tab + // Tab sets next widget in current tab + // Shift-Tab sets previous widget in current tab + if(keycode == 9) // tab key + { + if(_boss->instance()->eventHandler().kbdControl(modifiers)) + { + if(_boss->instance()->eventHandler().kbdShift(modifiers)) + cycleTab(-1); + else + cycleTab(+1); + } + else if(_boss->instance()->eventHandler().kbdShift(modifiers)) + cycleWidget(-1); + else + cycleWidget(+1); + + return true; + } + else if (_activeWidget) + return _activeWidget->handleKeyDown(ascii, keycode, modifiers); + else + return Widget::handleKeyDown(ascii, keycode, modifiers); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void TabWidget::handleCommand(CommandSender* sender, int cmd, int data) +{ + switch(cmd) + { + case kActiveWidgetCmd: + if(_activeWidget && isWidgetInChain(_firstWidget, _activeWidget)) + { + _tabs[_activeTab].activeWidget = _activeWidget; + Widget::setFocusForChain(_firstWidget, _activeWidget); + + // Make sure the changes are shown onscreen + _boss->instance()->frameBuffer().refresh(); + } + break; + + default: + sendCommand(cmd, data); + break; + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/gui/TabWidget.hxx b/stella/src/gui/TabWidget.hxx index ca3d9141a..12a659dd6 100644 --- a/stella/src/gui/TabWidget.hxx +++ b/stella/src/gui/TabWidget.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: TabWidget.hxx,v 1.3 2005-06-02 21:37:33 stephena Exp $ +// $Id: TabWidget.hxx,v 1.4 2005-06-10 17:46:07 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -33,6 +33,7 @@ class TabWidget : public Widget, public CommandSender struct Tab { string title; Widget* firstWidget; + Widget* activeWidget; }; typedef GUI::Array TabList; @@ -53,15 +54,18 @@ class TabWidget : public Widget, public CommandSender //void removeTab(int tabID); // Setting the active tab: void setActiveTab(int tabID); + void cycleTab(int direction); + void cycleWidget(int direction); // setActiveTab changes the value of _firstWidget. This means Widgets added afterwards // will be added to the active tab. + void setActiveWidget(int tabID, Widget* widID); virtual void handleMouseDown(int x, int y, int button, int clickCount); virtual bool handleKeyDown(int ascii, int keycode, int modifiers); + virtual void handleCommand(CommandSender* sender, int cmd, int data); protected: virtual void drawWidget(bool hilite); - virtual Widget *findWidget(int x, int y); protected: @@ -72,7 +76,6 @@ class TabWidget : public Widget, public CommandSender private: void box(int x, int y, int width, int height, OverlayColor colorA, OverlayColor colorB, bool omitBottom); - }; #endif diff --git a/stella/src/gui/Widget.cxx b/stella/src/gui/Widget.cxx index f3910646c..c484a3ac0 100644 --- a/stella/src/gui/Widget.cxx +++ b/stella/src/gui/Widget.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Widget.cxx,v 1.12 2005-06-08 18:45:09 stephena Exp $ +// $Id: Widget.cxx,v 1.13 2005-06-10 17:46:07 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -29,6 +29,8 @@ #include "GuiUtils.hxx" #include "Widget.hxx" +//FIXMEstatic int COUNT = 0; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Widget::Widget(GuiObject* boss, int x, int y, int w, int h) : GuiObject(boss->instance(), boss->parent(), x, y, w, h), @@ -106,6 +108,33 @@ void Widget::draw() } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Widget::receivedFocus() +{ + if(_hasFocus) + return; + + _hasFocus = true; + receivedFocusWidget(); + + // Only signal a new active widget if the widget has defined that capability + // We only care about widgets with WIDGET_TAB_NAVIGATE property + if(getFlags() & WIDGET_TAB_NAVIGATE) + { + _activeWidget = this; + _boss->handleCommand(NULL, kActiveWidgetCmd, 0); + } +} +/* FIXME +void Widget::lostFocus() +{ + _hasFocus = false; + lostFocusWidget(); + +if(getFlags() & WIDGET_TAB_NAVIGATE) + cerr << "lost focus: " << this << endl; +} +*/ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Widget* Widget::findWidgetInChain(Widget *w, int x, int y) { @@ -123,6 +152,169 @@ Widget* Widget::findWidgetInChain(Widget *w, int x, int y) return w; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool Widget::isWidgetInChain(Widget* w, Widget* find) +{ + bool found = false; + + while(w) + { + // Stop as soon as we find the widget + if(w == find) + { + found = true; + break; + } + w = w->_next; + } + + return found; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Widget::setFocusForChain(Widget* w, Widget* hasFocus) +{ + if(!hasFocus) + return; + + while(w) + { + if(w != hasFocus) + w->lostFocus(); + + w = w->_next; + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Widget::setPrevInChain(Widget* start, Widget* hasFocus) +{ + if(!start) + return; + + // We search the array in circular fashion until the 'end' is reached + Widget* w = hasFocus; + Widget* active = NULL; + + if(w) // start from 'hasFocus' + { + w = w->_next; + while(w) + { + if(w->getFlags() & WIDGET_TAB_NAVIGATE) + { + active = w; + break; + } + w = w->_next; + } + + // If we haven't found an active widget by now, start searching from + // the beginning of the list + if(!active) + { + w = start; + while(w != hasFocus) + { + if(w->getFlags() & WIDGET_TAB_NAVIGATE) + { + active = w; + break; + } + w = w->_next; + } + } + } + else // start from the beginning, since no widget currently has focus + { + w = start; + while(w) + { + if(w->getFlags() & WIDGET_TAB_NAVIGATE) + { + active = w; + break; + } + w = w->_next; + } + } + + // At this point, we *should* have an active widget + if(active) + active->receivedFocus(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Widget::setNextInChain(Widget* start, Widget* hasFocus) +{ + if(!start) + return; +// FIXME - get this working +cerr << "--------------------------------\nWidget list:\n"; + Widget* w1 = start; + while(w1) + { + if(w1->getFlags() & WIDGET_TAB_NAVIGATE) + { + cerr << w1 << endl; + } + w1 = w1->_next; + } +cerr << "\n--------------------------------\n"; + + + // We search the array in circular fashion until the 'end' is reached + Widget* w = hasFocus; + Widget* active = NULL; + + if(w) // start from 'hasFocus' + { + w = w->_next; + while(w) + { + if(w->getFlags() & WIDGET_TAB_NAVIGATE) + { + active = w; + break; + } + w = w->_next; + } + + // If we haven't found an active widget by now, start searching from + // the beginning of the list + if(!active) + { + w = start; + while(w != hasFocus) + { + if(w->getFlags() & WIDGET_TAB_NAVIGATE) + { + active = w; + break; + } + w = w->_next; + } + } + } + else // start from the beginning, since no widget currently has focus + { + w = start; + while(w) + { + if(w->getFlags() & WIDGET_TAB_NAVIGATE) + { + active = w; + break; + } + w = w->_next; + } + } + + // At this point, we *should* have an active widget + if(active) + active->receivedFocus(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - StaticTextWidget::StaticTextWidget(GuiObject *boss, int x, int y, int w, int h, const string& text, TextAlignment align) diff --git a/stella/src/gui/Widget.hxx b/stella/src/gui/Widget.hxx index bfbb64c79..378e63a8a 100644 --- a/stella/src/gui/Widget.hxx +++ b/stella/src/gui/Widget.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Widget.hxx,v 1.14 2005-06-08 18:45:09 stephena Exp $ +// $Id: Widget.hxx,v 1.15 2005-06-10 17:46:07 stephena Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -29,6 +29,7 @@ class Dialog; #include "OSystem.hxx" #include "FrameBuffer.hxx" #include "GuiObject.hxx" +#include "GuiUtils.hxx" #include "bspf.hxx" enum { @@ -38,7 +39,7 @@ enum { WIDGET_BORDER = 1 << 3, WIDGET_INV_BORDER = 1 << 4, WIDGET_CLEARBG = 1 << 5, - WIDGET_WANT_TICKLE = 1 << 7, + WIDGET_TAB_NAVIGATE = 1 << 7, WIDGET_TRACK_MOUSE = 1 << 8, WIDGET_RETAIN_FOCUS = 1 << 9 }; @@ -52,7 +53,8 @@ enum { kListWidget = 'LIST', kScrollBarWidget = 'SCRB', kPopUpWidget = 'POPU', - kTabWidget = 'TABW' + kTabWidget = 'TABW', + kPromptWidget = 'PROM' }; enum { @@ -64,7 +66,7 @@ enum { This is the base class for all widgets. @author Stephen Anthony - @version $Id: Widget.hxx,v 1.14 2005-06-08 18:45:09 stephena Exp $ + @version $Id: Widget.hxx,v 1.15 2005-06-10 17:46:07 stephena Exp $ */ class Widget : public GuiObject { @@ -87,11 +89,11 @@ class Widget : public GuiObject virtual bool handleKeyUp(int ascii, int keycode, int modifiers) { return false; } virtual void handleJoyDown(int stick, int button) {} virtual void handleJoyUp(int stick, int button) {} - virtual void handleTickle() {} void draw(); - void receivedFocus() { _hasFocus = true; receivedFocusWidget(); } + void receivedFocus(); void lostFocus() { _hasFocus = false; lostFocusWidget(); } + virtual bool wantsFocus() { return false; }; void setFlags(int flags) { _flags |= flags; @@ -136,6 +138,20 @@ class Widget : public GuiObject public: static Widget* findWidgetInChain(Widget* start, int x, int y); + + /** Determine if 'find' is in the chain pointed to by 'start' */ + static bool isWidgetInChain(Widget* start, Widget* find); + + /** Widget 'hasFocus' has focus, make all other widgets in chain lose focus */ + static void setFocusForChain(Widget* start, Widget* hasFocus); + + /** Select previous widget in chain with WIDGET_TAB_NOTIFY property to have + focus, starting from 'hasFocus' */ + static void setPrevInChain(Widget* start, Widget* hasFocus); + + /** Select next widget in chain with WIDGET_TAB_NOTIFY property to have + focus, starting from 'hasFocus' */ + static void setNextInChain(Widget* start, Widget* hasFocus); };