mirror of https://github.com/stella-emu/stella.git
First pass at adding a cart-specific bankswitch/info tab to the
debugger. In the process, I had to spend several days extending the UI/dialog class to actually contain multiple tabs. This was harder than expected, and it still isn't quite finished. In many ways, we're beginning to reach the limits of the current code; it was never designed for a full-fledged, graphically rich UI. For now the tab is empty, but eventually it will contain general info about the ROM bankswitch type (size, virtual layout, etc), but also cart-specific info, including the ability to change banks, which can be vary greatly among the different schemes. Eventually, it may even allow to see/modify very cart-specific info (like display RAM in DPC, etc). Better handle errors in opening the serial port (AtariVox support) for Windows and OSX. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2678 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
fbf239798d
commit
ac1bccf454
|
@ -33,8 +33,8 @@ template <class T>
|
|||
class Array
|
||||
{
|
||||
protected:
|
||||
int _capacity;
|
||||
int _size;
|
||||
uInt32 _capacity;
|
||||
uInt32 _size;
|
||||
T *_data;
|
||||
|
||||
public:
|
||||
|
@ -48,7 +48,7 @@ class Array
|
|||
_size = array._size;
|
||||
_capacity = _size + 128;
|
||||
_data = new T[_capacity];
|
||||
for(int i = 0; i < _size; i++)
|
||||
for(uInt32 i = 0; i < _size; i++)
|
||||
_data[i] = array._data[i];
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ class Array
|
|||
delete [] _data;
|
||||
}
|
||||
|
||||
void reserve(int capacity)
|
||||
void reserve(uInt32 capacity)
|
||||
{
|
||||
if(capacity <= _capacity)
|
||||
return;
|
||||
|
@ -74,11 +74,11 @@ class Array
|
|||
void push_back(const Array<T>& array)
|
||||
{
|
||||
ensureCapacity(_size + array._size);
|
||||
for(int i = 0; i < array._size; i++)
|
||||
for(uInt32 i = 0; i < array._size; i++)
|
||||
_data[_size++] = array._data[i];
|
||||
}
|
||||
|
||||
void insert_at(int idx, const T& element)
|
||||
void insert_at(uInt32 idx, const T& element)
|
||||
{
|
||||
assert(idx >= 0 && idx <= _size);
|
||||
ensureCapacity(_size + 1);
|
||||
|
@ -87,30 +87,30 @@ class Array
|
|||
// usually isn't correct (specifically, for any class which has a non-default
|
||||
// copy behaviour. E.g. the String class uses a refCounter which has to be
|
||||
// updated whenever a String is copied.
|
||||
for(int i = _size; i > idx; i--)
|
||||
for(uInt32 i = _size; i > idx; i--)
|
||||
_data[i] = _data[i-1];
|
||||
|
||||
_data[idx] = element;
|
||||
_size++;
|
||||
}
|
||||
|
||||
T remove_at(int idx)
|
||||
T remove_at(uInt32 idx)
|
||||
{
|
||||
assert(idx >= 0 && idx < _size);
|
||||
T tmp = _data[idx];
|
||||
for(int i = idx; i < _size - 1; i++)
|
||||
for(uInt32 i = idx; i < _size - 1; i++)
|
||||
_data[i] = _data[i+1];
|
||||
_size--;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
T& operator [](int idx)
|
||||
T& operator [](uInt32 idx)
|
||||
{
|
||||
assert(idx >= 0 && idx < _size);
|
||||
return _data[idx];
|
||||
}
|
||||
|
||||
const T& operator [](int idx) const
|
||||
const T& operator [](uInt32 idx) const
|
||||
{
|
||||
assert(idx >= 0 && idx < _size);
|
||||
return _data[idx];
|
||||
|
@ -123,14 +123,14 @@ class Array
|
|||
_size = array._size;
|
||||
_capacity = _size + 128;
|
||||
_data = new T[_capacity];
|
||||
for(int i = 0; i < _size; i++)
|
||||
for(uInt32 i = 0; i < _size; i++)
|
||||
_data[i] = array._data[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
unsigned int size() const { return _size; }
|
||||
unsigned int capacity() const { return _capacity; }
|
||||
uInt32 size() const { return _size; }
|
||||
uInt32 capacity() const { return _capacity; }
|
||||
|
||||
void clear(bool fullerase = true)
|
||||
{
|
||||
|
@ -172,7 +172,7 @@ class Array
|
|||
}
|
||||
|
||||
protected:
|
||||
void ensureCapacity(int new_len)
|
||||
void ensureCapacity(uInt32 new_len)
|
||||
{
|
||||
if (new_len <= _capacity)
|
||||
return;
|
||||
|
@ -184,7 +184,7 @@ class Array
|
|||
if (old_data)
|
||||
{
|
||||
// Copy old data
|
||||
for (int i = 0; i < _size; i++)
|
||||
for (uInt32 i = 0; i < _size; i++)
|
||||
_data[i] = old_data[i];
|
||||
delete [] old_data;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ DebuggerDialog::DebuggerDialog(OSystem* osystem, DialogContainer* parent,
|
|||
int x, int y, int w, int h)
|
||||
: Dialog(osystem, parent, x, y, w, h, true), // use base surface
|
||||
myTab(NULL),
|
||||
myRomTab(NULL),
|
||||
myFatalError(NULL)
|
||||
{
|
||||
addTiaArea();
|
||||
|
@ -72,7 +73,9 @@ void DebuggerDialog::loadConfig()
|
|||
myTiaZoom->loadConfig();
|
||||
myCpu->loadConfig();
|
||||
myRam->loadConfig();
|
||||
myRom->loadConfig();
|
||||
|
||||
myRomTab->loadConfig();
|
||||
// myRom->loadConfig();
|
||||
|
||||
myMessageBox->setEditString("");
|
||||
}
|
||||
|
@ -176,12 +179,14 @@ void DebuggerDialog::addTiaArea()
|
|||
void DebuggerDialog::addTabArea()
|
||||
{
|
||||
const GUI::Rect& r = instance().debugger().getTabBounds();
|
||||
|
||||
const int vBorder = 4;
|
||||
|
||||
// The tab widget
|
||||
// Since there are two tab widgets in this dialog, we specifically
|
||||
// assign an ID of 0
|
||||
myTab = new TabWidget(this, instance().consoleFont(), r.left, r.top + vBorder,
|
||||
r.width(), r.height() - vBorder);
|
||||
myTab->setID(0);
|
||||
addTabWidget(myTab);
|
||||
|
||||
const int widWidth = r.width() - vBorder;
|
||||
|
@ -193,28 +198,28 @@ void DebuggerDialog::addTabArea()
|
|||
myPrompt = new PromptWidget(myTab, instance().consoleFont(),
|
||||
2, 2, widWidth, widHeight);
|
||||
myTab->setParentWidget(tabID, myPrompt);
|
||||
addToFocusList(myPrompt->getFocusList(), tabID);
|
||||
addToFocusList(myPrompt->getFocusList(), myTab, tabID);
|
||||
|
||||
// The TIA tab
|
||||
tabID = myTab->addTab("TIA");
|
||||
TiaWidget* tia = new TiaWidget(myTab, instance().consoleFont(),
|
||||
2, 2, widWidth, widHeight);
|
||||
myTab->setParentWidget(tabID, tia);
|
||||
addToFocusList(tia->getFocusList(), tabID);
|
||||
addToFocusList(tia->getFocusList(), myTab, tabID);
|
||||
|
||||
// The input/output tab (includes RIOT and INPTx from TIA)
|
||||
tabID = myTab->addTab("I/O");
|
||||
RiotWidget* riot = new RiotWidget(myTab, instance().consoleFont(),
|
||||
2, 2, widWidth, widHeight);
|
||||
myTab->setParentWidget(tabID, riot);
|
||||
addToFocusList(riot->getFocusList(), tabID);
|
||||
addToFocusList(riot->getFocusList(), myTab, tabID);
|
||||
|
||||
// The Audio tab
|
||||
tabID = myTab->addTab("Audio");
|
||||
AudioWidget* aud = new AudioWidget(myTab, instance().consoleFont(),
|
||||
2, 2, widWidth, widHeight);
|
||||
myTab->setParentWidget(tabID, aud);
|
||||
addToFocusList(aud->getFocusList(), tabID);
|
||||
addToFocusList(aud->getFocusList(), myTab, tabID);
|
||||
|
||||
myTab->setActiveTab(0);
|
||||
}
|
||||
|
@ -248,6 +253,8 @@ void DebuggerDialog::addStatusArea()
|
|||
void DebuggerDialog::addRomArea()
|
||||
{
|
||||
const GUI::Rect& r = instance().debugger().getRomBounds();
|
||||
const int vBorder = 4;
|
||||
|
||||
int xpos, ypos;
|
||||
|
||||
xpos = r.left + 10; ypos = 10;
|
||||
|
@ -289,14 +296,45 @@ void DebuggerDialog::addRomArea()
|
|||
bwidth, bheight, "<", kDDRewindCmd);
|
||||
myRewindButton->clearFlags(WIDGET_ENABLED);
|
||||
|
||||
xpos = r.left + 10; ypos += myRam->getHeight() + 5;
|
||||
myRom = new RomWidget(this, instance().consoleFont(), xpos, ypos);
|
||||
addToFocusList(myRom->getFocusList());
|
||||
|
||||
// Add the DataGridOpsWidget to any widgets which contain a
|
||||
// DataGridWidget which we want controlled
|
||||
myCpu->setOpsWidget(ops);
|
||||
myRam->setOpsWidget(ops);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Disassembly area
|
||||
|
||||
xpos = r.left + vBorder; ypos += myRam->getHeight() + 5;
|
||||
const int tabWidth = r.width() - vBorder;
|
||||
const int tabHeight = r.height() - ypos;
|
||||
int tabID;
|
||||
|
||||
// Since there are two tab widgets in this dialog, we specifically
|
||||
// assign an ID of 1
|
||||
myRomTab = new TabWidget(
|
||||
this, instance().consoleFont(), xpos, ypos, tabWidth, tabHeight);
|
||||
myRomTab->setID(1);
|
||||
addTabWidget(myRomTab);
|
||||
|
||||
// The main disassembly tab
|
||||
tabID = myRomTab->addTab(" Disassembly ");
|
||||
myRom = new RomWidget(myRomTab, instance().consoleFont(),
|
||||
2, 2, tabWidth - 1,
|
||||
tabHeight - myRomTab->getTabHeight() - 2);
|
||||
myRomTab->setParentWidget(tabID, myRom);
|
||||
addToFocusList(myRom->getFocusList(), myRomTab, tabID);
|
||||
|
||||
// The 'cart-specific' information tab
|
||||
tabID = myRomTab->addTab(instance().console().cartridge().name());
|
||||
#if 0
|
||||
myRom = new RomWidget(myRomTab, instance().consoleFont(),
|
||||
2, 2, tabWidth - 1,
|
||||
tabHeight - myRomTab->getTabHeight() - 2);
|
||||
myRomTab->setParentWidget(tabID, myRom);
|
||||
addToFocusList(myRom->getFocusList(), myRomTab, tabID);
|
||||
#endif
|
||||
|
||||
myRomTab->setActiveTab(0);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -72,7 +72,7 @@ class DebuggerDialog : public Dialog
|
|||
kDDExitFatalCmd = 'DDer'
|
||||
};
|
||||
|
||||
TabWidget* myTab;
|
||||
TabWidget *myTab, *myRomTab;
|
||||
|
||||
PromptWidget* myPrompt;
|
||||
TiaInfoWidget* myTiaInfo;
|
||||
|
|
|
@ -38,8 +38,9 @@
|
|||
#include "RomWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
RomWidget::RomWidget(GuiObject* boss, const GUI::Font& font, int x, int y)
|
||||
: Widget(boss, font, x, y, 16, 16),
|
||||
RomWidget::RomWidget(GuiObject* boss, const GUI::Font& font,
|
||||
int x, int y, int w, int h)
|
||||
: Widget(boss, font, x, y, w, h),
|
||||
CommandSender(boss),
|
||||
myListIsDirty(true),
|
||||
myCurrentBank(-1)
|
||||
|
@ -85,18 +86,12 @@ RomWidget::RomWidget(GuiObject* boss, const GUI::Font& font, int x, int y)
|
|||
|
||||
// Create rom listing
|
||||
xpos = x; ypos += myBank->getHeight() + 4;
|
||||
const GUI::Rect& dialog = instance().debugger().getDialogBounds();
|
||||
int w = dialog.width() - x - 5, h = dialog.height() - ypos - 3;
|
||||
|
||||
myRomList = new RomListWidget(boss, font, xpos, ypos, w, h);
|
||||
myRomList = new RomListWidget(boss, font, xpos, ypos, _w - 4, _h - ypos - 2);
|
||||
myRomList->setTarget(this);
|
||||
myRomList->myMenu->setTarget(this);
|
||||
addFocusWidget(myRomList);
|
||||
|
||||
// Calculate real dimensions
|
||||
_w = myRomList->getWidth();
|
||||
_h = myRomList->getHeight();
|
||||
|
||||
// Create dialog box for save ROM (get name)
|
||||
StringList label;
|
||||
label.push_back("Filename: ");
|
||||
|
|
|
@ -39,7 +39,7 @@ class StringList;
|
|||
class RomWidget : public Widget, public CommandSender
|
||||
{
|
||||
public:
|
||||
RomWidget(GuiObject* boss, const GUI::Font& font, int x, int y);
|
||||
RomWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h);
|
||||
virtual ~RomWidget();
|
||||
|
||||
void invalidate(bool forcereload = true)
|
||||
|
|
|
@ -163,11 +163,6 @@ Console::Console(OSystem* osystem, Cartridge* cart, const Properties& props)
|
|||
// Reset the system to its power-on state
|
||||
mySystem->reset();
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
myOSystem->createDebugger(*this);
|
||||
m6502->attach(myOSystem->debugger());
|
||||
#endif
|
||||
|
||||
// Finally, add remaining info about the console
|
||||
myConsoleInfo.CartName = myProperties.get(Cartridge_Name);
|
||||
myConsoleInfo.CartMD5 = myProperties.get(Cartridge_MD5);
|
||||
|
@ -920,6 +915,15 @@ void Console::toggleFixedColors() const
|
|||
myOSystem->frameBuffer().showMessage("Fixed debug colors disabled");
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Console::addDebugger()
|
||||
{
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
myOSystem->createDebugger(*this);
|
||||
mySystem->m6502().attach(myOSystem->debugger());
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 Console::ourNTSCPalette[256] = {
|
||||
0x000000, 0, 0x4a4a4a, 0, 0x6f6f6f, 0, 0x8e8e8e, 0,
|
||||
|
|
|
@ -170,6 +170,11 @@ class Console : public Serializable
|
|||
*/
|
||||
const ConsoleInfo& about() const { return myConsoleInfo; }
|
||||
|
||||
/**
|
||||
Set up the console to use the debugger.
|
||||
*/
|
||||
void addDebugger();
|
||||
|
||||
public:
|
||||
/**
|
||||
Overloaded assignment operator
|
||||
|
|
|
@ -50,9 +50,8 @@ FrameBuffer::FrameBuffer(OSystem* osystem)
|
|||
myInitializedCount(0),
|
||||
myPausedCount(0)
|
||||
{
|
||||
myMsg.surface = myStatsMsg.surface = NULL;
|
||||
myMsg.surfaceID = myStatsMsg.surfaceID = -1;
|
||||
myMsg.enabled = myStatsMsg.enabled = false;
|
||||
myMsg.surface = myStatsMsg.surface = NULL;
|
||||
myMsg.enabled = myStatsMsg.enabled = false;
|
||||
|
||||
// Load NTSC filter settings
|
||||
myNTSCFilter.loadConfig(myOSystem->settings());
|
||||
|
@ -175,13 +174,13 @@ FBInitStatus FrameBuffer::initialize(const string& title,
|
|||
|
||||
if(myStatsMsg.surface == NULL)
|
||||
{
|
||||
myStatsMsg.surfaceID = allocateSurface(myStatsMsg.w, myStatsMsg.h);
|
||||
myStatsMsg.surface = surface(myStatsMsg.surfaceID);
|
||||
uInt32 surfaceID = allocateSurface(myStatsMsg.w, myStatsMsg.h);
|
||||
myStatsMsg.surface = surface(surfaceID);
|
||||
}
|
||||
if(myMsg.surface == NULL)
|
||||
{
|
||||
myMsg.surfaceID = allocateSurface(640, myOSystem->font().getFontHeight()+10);
|
||||
myMsg.surface = surface(myMsg.surfaceID);
|
||||
uInt32 surfaceID = allocateSurface(640, myOSystem->font().getFontHeight()+10);
|
||||
myMsg.surface = surface(surfaceID);
|
||||
}
|
||||
|
||||
// Finally, show some information about the framebuffer,
|
||||
|
@ -586,22 +585,22 @@ void FrameBuffer::toggleScanlineInterpolation()
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int FrameBuffer::allocateSurface(int w, int h, bool useBase)
|
||||
uInt32 FrameBuffer::allocateSurface(int w, int h, bool useBase)
|
||||
{
|
||||
// Create a new surface
|
||||
FBSurface* surface = createSurface(w, h, useBase);
|
||||
|
||||
// Add it to the list
|
||||
mySurfaceList.insert(make_pair(int(mySurfaceList.size()), surface));
|
||||
mySurfaceList.insert(make_pair(mySurfaceList.size(), surface));
|
||||
|
||||
// Return a reference to it
|
||||
return mySurfaceList.size() - 1;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FBSurface* FrameBuffer::surface(int id) const
|
||||
FBSurface* FrameBuffer::surface(uInt32 id) const
|
||||
{
|
||||
map<int,FBSurface*>::const_iterator iter = mySurfaceList.find(id);
|
||||
map<uInt32,FBSurface*>::const_iterator iter = mySurfaceList.find(id);
|
||||
return iter != mySurfaceList.end() ? iter->second : NULL;
|
||||
}
|
||||
|
||||
|
@ -614,7 +613,7 @@ void FrameBuffer::resetSurfaces(FBSurface* tiasurface)
|
|||
// Any derived FrameBuffer classes that call this method should be
|
||||
// aware of these restrictions, and act accordingly
|
||||
|
||||
map<int,FBSurface*>::iterator iter;
|
||||
map<uInt32,FBSurface*>::iterator iter;
|
||||
for(iter = mySurfaceList.begin(); iter != mySurfaceList.end(); ++iter)
|
||||
iter->second->free();
|
||||
if(tiasurface)
|
||||
|
|
|
@ -173,7 +173,7 @@ class FrameBuffer
|
|||
|
||||
@return A unique ID used to identify this surface
|
||||
*/
|
||||
int allocateSurface(int w, int h, bool useBase = false);
|
||||
uInt32 allocateSurface(int w, int h, bool useBase = false);
|
||||
|
||||
/**
|
||||
Retrieve the surface associated with the given ID.
|
||||
|
@ -181,7 +181,7 @@ class FrameBuffer
|
|||
@param id The ID for the surface to retrieve.
|
||||
@return A pointer to a valid surface object, or NULL.
|
||||
*/
|
||||
FBSurface* surface(int id) const;
|
||||
FBSurface* surface(uInt32 id) const;
|
||||
|
||||
/**
|
||||
Returns the current dimensions of the framebuffer image.
|
||||
|
@ -633,7 +633,6 @@ class FrameBuffer
|
|||
MessagePosition position;
|
||||
uInt32 color;
|
||||
FBSurface* surface;
|
||||
int surfaceID;
|
||||
bool enabled;
|
||||
};
|
||||
Message myMsg;
|
||||
|
@ -645,7 +644,7 @@ class FrameBuffer
|
|||
VideoModeList* myCurrentModeList;
|
||||
|
||||
// Holds a reference to all the surfaces that have been created
|
||||
map<int,FBSurface*> mySurfaceList;
|
||||
map<uInt32,FBSurface*> mySurfaceList;
|
||||
|
||||
// Holds static strings for the remap menu (emulation and menu events)
|
||||
static GraphicsMode ourGraphicsModes[GFX_NumModes];
|
||||
|
|
|
@ -531,6 +531,9 @@ bool OSystem::createConsole(const FilesystemNode& rom, const string& md5sum,
|
|||
myConsole = openConsole(myRomFile, myRomMD5, type, id);
|
||||
if(myConsole)
|
||||
{
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
myConsole->addDebugger();
|
||||
#endif
|
||||
#ifdef CHEATCODE_SUPPORT
|
||||
myCheatManager->loadCheats(myRomMD5);
|
||||
#endif
|
||||
|
|
|
@ -46,31 +46,26 @@ Dialog::Dialog(OSystem* instance, DialogContainer* parent,
|
|||
_cancelWidget(0),
|
||||
_visible(false),
|
||||
_isBase(isBase),
|
||||
_ourTab(NULL),
|
||||
_surface(NULL),
|
||||
_focusID(0),
|
||||
_surfaceID(-1)
|
||||
_surface(0),
|
||||
_tabID(0)
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Dialog::~Dialog()
|
||||
{
|
||||
for(unsigned int i = 0; i < _ourFocusList.size(); ++i)
|
||||
_ourFocusList[i].focusList.clear();
|
||||
_myFocus.list.clear();
|
||||
_myTabList.clear();
|
||||
|
||||
delete _firstWidget;
|
||||
_firstWidget = NULL;
|
||||
|
||||
_ourButtonGroup.clear();
|
||||
_buttonGroup.clear();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::open()
|
||||
{
|
||||
_result = 0;
|
||||
_visible = true;
|
||||
|
||||
// Make sure we have a valid surface to draw into
|
||||
// Technically, this shouldn't be needed until drawDialog(), but some
|
||||
// dialogs cause drawing to occur within loadConfig()
|
||||
|
@ -80,11 +75,10 @@ void Dialog::open()
|
|||
// However, this policy is left entirely to the framebuffer
|
||||
// We suggest the hint here, but specific framebuffers are free to
|
||||
// ignore it
|
||||
_surface = instance().frameBuffer().surface(_surfaceID);
|
||||
if(_surface == NULL)
|
||||
{
|
||||
_surfaceID = instance().frameBuffer().allocateSurface(_w, _h, _isBase);
|
||||
_surface = instance().frameBuffer().surface(_surfaceID);
|
||||
uInt32 surfaceID = instance().frameBuffer().allocateSurface(_w, _h, _isBase);
|
||||
_surface = instance().frameBuffer().surface(surfaceID);
|
||||
}
|
||||
|
||||
center();
|
||||
|
@ -92,7 +86,9 @@ void Dialog::open()
|
|||
|
||||
// (Re)-build the focus list to use for the widgets which are currently
|
||||
// onscreen
|
||||
buildFocusWidgetList(_focusID);
|
||||
buildCurrentFocusList();
|
||||
|
||||
_visible = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -135,43 +131,75 @@ void Dialog::releaseFocus()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::addFocusWidget(Widget* w)
|
||||
{
|
||||
// All focusable widgets should retain focus
|
||||
if(w)
|
||||
w->setFlags(WIDGET_RETAIN_FOCUS);
|
||||
if(!w)
|
||||
return;
|
||||
|
||||
if(_ourFocusList.size() == 0)
|
||||
{
|
||||
Focus f;
|
||||
f.focusedWidget = 0;
|
||||
_ourFocusList.push_back(f);
|
||||
}
|
||||
_ourFocusList[0].focusedWidget = w;
|
||||
_ourFocusList[0].focusList.push_back(w);
|
||||
// All focusable widgets should retain focus
|
||||
w->setFlags(WIDGET_RETAIN_FOCUS);
|
||||
|
||||
_myFocus.widget = w;
|
||||
_myFocus.list.push_back(w);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::addToFocusList(WidgetArray& list, int id)
|
||||
void Dialog::addToFocusList(WidgetArray& list)
|
||||
{
|
||||
// All focusable widgets should retain focus
|
||||
for(unsigned int i = 0; i < list.size(); ++i)
|
||||
for(uInt32 i = 0; i < list.size(); ++i)
|
||||
list[i]->setFlags(WIDGET_RETAIN_FOCUS);
|
||||
|
||||
id++; // Arrays start at 0, not -1.
|
||||
|
||||
// Make sure the array is large enough
|
||||
while((int)_ourFocusList.size() <= id)
|
||||
{
|
||||
Focus f;
|
||||
f.focusedWidget = NULL;
|
||||
_ourFocusList.push_back(f);
|
||||
}
|
||||
|
||||
_ourFocusList[id].focusList.push_back(list);
|
||||
if(id == 0 && _ourFocusList.size() > 0)
|
||||
_focusList = _ourFocusList[0].focusList;
|
||||
_myFocus.list.push_back(list);
|
||||
_focusList = _myFocus.list;
|
||||
|
||||
if(list.size() > 0)
|
||||
_ourFocusList[id].focusedWidget = list[0];
|
||||
_myFocus.widget = list[0];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::addToFocusList(WidgetArray& list, TabWidget* w, int tabId)
|
||||
{
|
||||
// Only add the list if the tab actually exists
|
||||
if(!w || w->getID() < 0 || (uInt32)w->getID() >= _myTabList.size())
|
||||
return;
|
||||
|
||||
assert(w == _myTabList[w->getID()].widget);
|
||||
|
||||
// All focusable widgets should retain focus
|
||||
for(uInt32 i = 0; i < list.size(); ++i)
|
||||
list[i]->setFlags(WIDGET_RETAIN_FOCUS);
|
||||
|
||||
// First get the appropriate focus list
|
||||
FocusList& focus = _myTabList[w->getID()].focus;
|
||||
|
||||
// Now insert in the correct place in that focus list
|
||||
uInt32 id = tabId;
|
||||
if(id < focus.size())
|
||||
focus[id].list.push_back(list);
|
||||
else
|
||||
{
|
||||
// Make sure the array is large enough
|
||||
while(focus.size() <= id)
|
||||
focus.push_back(Focus());
|
||||
|
||||
focus[id].list.push_back(list);
|
||||
}
|
||||
|
||||
if(list.size() > 0)
|
||||
focus[id].widget = list[0];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::addTabWidget(TabWidget* w)
|
||||
{
|
||||
if(!w || w->getID() < 0)
|
||||
return;
|
||||
|
||||
// Make sure the array is large enough
|
||||
uInt32 id = w->getID();
|
||||
while(_myTabList.size() < id)
|
||||
_myTabList.push_back(TabFocus());
|
||||
|
||||
_myTabList.push_back(TabFocus(w));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -183,51 +211,66 @@ void Dialog::setFocus(Widget* w)
|
|||
{
|
||||
// Redraw widgets for new focus
|
||||
_focusedWidget = Widget::setFocusForChain(this, getFocusList(), w, 0);
|
||||
|
||||
cerr << "set focus for " << _focusedWidget << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::buildFocusWidgetList(int id)
|
||||
void Dialog::buildCurrentFocusList(int tabID)
|
||||
{
|
||||
// Yes, this is hideously complex. That's the price we pay for
|
||||
// tab navigation ...
|
||||
_focusList.clear();
|
||||
|
||||
// Remember which item previously had focus, but only if it belongs
|
||||
// to this focus list
|
||||
if(_focusID < (int)_ourFocusList.size() &&
|
||||
Widget::isWidgetInChain(_ourFocusList[_focusID].focusList, _focusedWidget))
|
||||
_ourFocusList[_focusID].focusedWidget = _focusedWidget;
|
||||
|
||||
_focusID = id;
|
||||
|
||||
// Create a focuslist for items currently onscreen
|
||||
// We do this by starting with any dialog focus list (at index 0 in the
|
||||
// focus lists, then appending the list indicated by 'id'.
|
||||
if(_focusID < (int)_ourFocusList.size())
|
||||
// Remember which tab item previously had focus, if applicable
|
||||
// This only applies if this method was called for a tab change
|
||||
Widget* tabFocusWidget = 0;
|
||||
if(tabID >= 0 && tabID < (int)_myTabList.size())
|
||||
{
|
||||
_focusList.clear();
|
||||
_focusList.push_back(_ourFocusList[0].focusList);
|
||||
cerr << "save tab, move to next\n";
|
||||
// Save focus in previously selected tab column,
|
||||
// and get focus for new tab column
|
||||
TabFocus& tabfocus = _myTabList[tabID];
|
||||
tabfocus.saveCurrentFocus(_focusedWidget);
|
||||
tabFocusWidget = tabfocus.getNewFocus();
|
||||
|
||||
// Append extra focus list
|
||||
if(_focusID > 0)
|
||||
_focusList.push_back(_ourFocusList[_focusID].focusList);
|
||||
|
||||
// Add button group at end of current focus list
|
||||
// We do it this way for TabWidget, so that buttons are scanned
|
||||
// *after* the widgets in the current tab
|
||||
if(_ourButtonGroup.size() > 0)
|
||||
_focusList.push_back(_ourButtonGroup);
|
||||
|
||||
// Only update _focusedWidget if it doesn't belong to the main focus list
|
||||
// HACK - figure out how to properly deal with only one focus-able widget
|
||||
// in a tab -- TabWidget is the spawn of the devil
|
||||
if(_focusList.size() == 1)
|
||||
_focusedWidget = _focusList[0];
|
||||
else if(!Widget::isWidgetInChain(_ourFocusList[0].focusList, _focusedWidget))
|
||||
_focusedWidget = _ourFocusList[_focusID].focusedWidget;
|
||||
_tabID = tabID;
|
||||
}
|
||||
else
|
||||
_focusedWidget = 0;
|
||||
|
||||
// Special case for dialogs containing only one tab widget, with all items
|
||||
// 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)
|
||||
_myTabList[id].appendFocusList(_focusList);
|
||||
|
||||
// Add remaining items from main focus list
|
||||
if(!containsSingleTab)
|
||||
_focusList.push_back(_myFocus.list);
|
||||
|
||||
// Add button group at end of current focus list
|
||||
// We do it this way for TabWidget, so that buttons are scanned
|
||||
// *after* the widgets in the current tab
|
||||
if(_buttonGroup.size() > 0)
|
||||
_focusList.push_back(_buttonGroup);
|
||||
|
||||
// Finally, the moment we've all been waiting for :)
|
||||
// Set the actual focus widget
|
||||
if(tabFocusWidget)
|
||||
{cerr << "tab focus changed\n";
|
||||
_focusedWidget = tabFocusWidget;
|
||||
}
|
||||
else if(!_focusedWidget && _focusList.size() > 0)
|
||||
_focusedWidget = _focusList[0];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -295,20 +338,14 @@ void Dialog::handleKeyDown(StellaKey key, StellaMod mod, char ascii)
|
|||
// not ascii??
|
||||
if(instance().eventHandler().kbdShift(mod))
|
||||
{
|
||||
if(key == KBDK_LEFT && _ourTab) // left arrow
|
||||
{
|
||||
_ourTab->cycleTab(-1);
|
||||
if(key == KBDK_LEFT && cycleTab(-1))
|
||||
return;
|
||||
}
|
||||
else if(key == KBDK_RIGHT && _ourTab) // right arrow
|
||||
{
|
||||
_ourTab->cycleTab(+1);
|
||||
else if(key == KBDK_RIGHT && cycleTab(+1))
|
||||
return;
|
||||
}
|
||||
else if(key == KBDK_TAB) // tab
|
||||
else if(key == KBDK_TAB)
|
||||
e = Event::UINavPrev;
|
||||
}
|
||||
else if(key == KBDK_TAB) // tab
|
||||
else if(key == KBDK_TAB)
|
||||
e = Event::UINavNext;
|
||||
|
||||
// Check the keytable now, since we might get one of the above events,
|
||||
|
@ -338,22 +375,19 @@ void Dialog::handleKeyUp(StellaKey key, StellaMod mod, char ascii)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::handleMouseDown(int x, int y, int button, int clickCount)
|
||||
{
|
||||
Widget* w;
|
||||
w = findWidget(x, y);
|
||||
Widget* w = findWidget(x, y);
|
||||
|
||||
_dragWidget = w;
|
||||
|
||||
setFocus(w);
|
||||
|
||||
if(w)
|
||||
w->handleMouseDown(x - (w->getAbsX() - _x), y - (w->getAbsY() - _y), button, clickCount);
|
||||
w->handleMouseDown(x - (w->getAbsX() - _x), y - (w->getAbsY() - _y),
|
||||
button, clickCount);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::handleMouseUp(int x, int y, int button, int clickCount)
|
||||
{
|
||||
Widget* w;
|
||||
|
||||
if(_focusedWidget)
|
||||
{
|
||||
// Lose focus on mouseup unless the widget requested to retain the focus
|
||||
|
@ -361,10 +395,10 @@ void Dialog::handleMouseUp(int x, int y, int button, int clickCount)
|
|||
releaseFocus();
|
||||
}
|
||||
|
||||
w = _dragWidget;
|
||||
|
||||
Widget* w = _dragWidget;
|
||||
if(w)
|
||||
w->handleMouseUp(x - (w->getAbsX() - _x), y - (w->getAbsY() - _y), button, clickCount);
|
||||
w->handleMouseUp(x - (w->getAbsX() - _x), y - (w->getAbsY() - _y),
|
||||
button, clickCount);
|
||||
|
||||
_dragWidget = 0;
|
||||
}
|
||||
|
@ -372,16 +406,14 @@ void Dialog::handleMouseUp(int x, int y, int button, int clickCount)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::handleMouseWheel(int x, int y, int direction)
|
||||
{
|
||||
Widget* w;
|
||||
|
||||
// This may look a bit backwards, but I think it makes more sense for
|
||||
// the mouse wheel to primarily affect the widget the mouse is at than
|
||||
// the widget that happens to be focused.
|
||||
|
||||
w = findWidget(x, y);
|
||||
Widget* w = findWidget(x, y);
|
||||
if(!w)
|
||||
w = _focusedWidget;
|
||||
if (w)
|
||||
if(w)
|
||||
w->handleMouseWheel(x, y, direction);
|
||||
}
|
||||
|
||||
|
@ -389,13 +421,13 @@ void Dialog::handleMouseWheel(int x, int y, int direction)
|
|||
void Dialog::handleMouseMoved(int x, int y, int button)
|
||||
{
|
||||
Widget* w;
|
||||
|
||||
|
||||
if(_focusedWidget && !_dragWidget)
|
||||
{
|
||||
w = _focusedWidget;
|
||||
int wx = w->getAbsX() - _x;
|
||||
int wy = w->getAbsY() - _y;
|
||||
|
||||
|
||||
// We still send mouseEntered/Left messages to the focused item
|
||||
// (but to no other items).
|
||||
bool mouseInFocusedWidget = (x >= wx && x < wx + w->_w && y >= wy && y < wy + w->_h);
|
||||
|
@ -441,7 +473,8 @@ bool Dialog::handleMouseClicks(int x, int y, int button)
|
|||
Widget* w = findWidget(x, y);
|
||||
|
||||
if(w)
|
||||
return w->handleMouseClicks(x - (w->getAbsX() - _x), y - (w->getAbsY() - _y), button);
|
||||
return w->handleMouseClicks(x - (w->getAbsX() - _x),
|
||||
y - (w->getAbsY() - _y), button);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
@ -554,14 +587,40 @@ bool Dialog::handleNavEvent(Event::Type e)
|
|||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Dialog::cycleTab(int direction)
|
||||
{
|
||||
cerr << "cycle " << (direction < 0 ? "left" : "right") << ", tabID = " << _tabID << endl;
|
||||
|
||||
if(_tabID >= 0 && _tabID < (int)_myTabList.size())
|
||||
{
|
||||
_myTabList[_tabID].widget->cycleTab(direction);
|
||||
return true;
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
||||
{
|
||||
switch(cmd)
|
||||
{
|
||||
case kTabChangedCmd:
|
||||
// Add this focus list for the given tab to the global focus list
|
||||
buildFocusWidgetList(++data);
|
||||
if(_visible)
|
||||
buildCurrentFocusList(id);
|
||||
break;
|
||||
|
||||
case kCloseCmd:
|
||||
|
@ -580,7 +639,7 @@ Widget* Dialog::findWidget(int x, int y)
|
|||
return Widget::findWidgetInChain(_firstWidget, x, y);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::addOKCancelBGroup(WidgetArray& wid, const GUI::Font& font,
|
||||
const string& okText, const string& cancelText)
|
||||
{
|
||||
|
@ -614,3 +673,72 @@ void Dialog::addOKCancelBGroup(WidgetArray& wid, const GUI::Font& font,
|
|||
addOKWidget(b);
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Dialog::Focus::Focus(Widget* w)
|
||||
: widget(w)
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Dialog::Focus::~Focus()
|
||||
{
|
||||
list.clear();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Dialog::TabFocus::TabFocus(TabWidget* w)
|
||||
: widget(w),
|
||||
currentTab(0)
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Dialog::TabFocus::~TabFocus()
|
||||
{
|
||||
focus.clear();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::TabFocus::appendFocusList(WidgetArray& list)
|
||||
{
|
||||
uInt32 active = widget->getActiveTab();
|
||||
|
||||
if(active >= 0 && active < focus.size())
|
||||
list.push_back(focus[active].list);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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() &&
|
||||
Widget::isWidgetInChain(focus[currentTab].list, w))
|
||||
{cerr << "saving widget\n";
|
||||
focus[currentTab].widget = w;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Widget* Dialog::TabFocus::getNewFocus()
|
||||
{
|
||||
currentTab = widget->getActiveTab();
|
||||
|
||||
return (currentTab >= 0 && currentTab < focus.size()) ?
|
||||
focus[currentTab].widget : 0;
|
||||
}
|
||||
|
|
|
@ -45,12 +45,6 @@ class Dialog : public GuiObject
|
|||
{
|
||||
friend class DialogContainer;
|
||||
|
||||
struct Focus {
|
||||
Widget* focusedWidget;
|
||||
WidgetArray focusList;
|
||||
};
|
||||
typedef Common::Array<Focus> FocusList;
|
||||
|
||||
public:
|
||||
Dialog(OSystem* instance, DialogContainer* parent,
|
||||
int x, int y, int w, int h, bool isBase = false);
|
||||
|
@ -69,10 +63,11 @@ class Dialog : public GuiObject
|
|||
virtual void setDefaults() {}
|
||||
|
||||
void addFocusWidget(Widget* w);
|
||||
void addToFocusList(WidgetArray& list, int id = -1);
|
||||
void addBGroupToFocusList(WidgetArray& list) { _ourButtonGroup = list; }
|
||||
void addToFocusList(WidgetArray& list);
|
||||
void addToFocusList(WidgetArray& list, TabWidget* w, int tabId);
|
||||
void addBGroupToFocusList(WidgetArray& list) { _buttonGroup = list; }
|
||||
void redrawFocus();
|
||||
void addTabWidget(TabWidget* w) { _ourTab = w; }
|
||||
void addTabWidget(TabWidget* w);
|
||||
void addOKWidget(Widget* w) { _okWidget = w; }
|
||||
void addCancelWidget(Widget* w) { _cancelWidget = w; }
|
||||
void setFocus(Widget* w);
|
||||
|
@ -102,12 +97,10 @@ class Dialog : public GuiObject
|
|||
const string& okText = "",
|
||||
const string& cancelText = "");
|
||||
|
||||
void setResult(int result) { _result = result; }
|
||||
int getResult() const { return _result; }
|
||||
|
||||
private:
|
||||
void buildFocusWidgetList(int id);
|
||||
void buildCurrentFocusList(int tabID = -1);
|
||||
bool handleNavEvent(Event::Type e);
|
||||
bool cycleTab(int direction);
|
||||
|
||||
protected:
|
||||
Widget* _mouseWidget;
|
||||
|
@ -119,14 +112,36 @@ class Dialog : public GuiObject
|
|||
bool _isBase;
|
||||
|
||||
private:
|
||||
FocusList _ourFocusList;
|
||||
TabWidget* _ourTab;
|
||||
WidgetArray _ourButtonGroup;
|
||||
struct Focus {
|
||||
Widget* widget;
|
||||
WidgetArray list;
|
||||
|
||||
Focus(Widget* w = 0);
|
||||
virtual ~Focus();
|
||||
};
|
||||
typedef Common::Array<Focus> FocusList;
|
||||
|
||||
struct TabFocus {
|
||||
TabWidget* widget;
|
||||
FocusList focus;
|
||||
uInt32 currentTab;
|
||||
|
||||
TabFocus(TabWidget* w = 0);
|
||||
virtual ~TabFocus();
|
||||
|
||||
void appendFocusList(WidgetArray& list);
|
||||
void saveCurrentFocus(Widget* w);
|
||||
Widget* getNewFocus();
|
||||
};
|
||||
typedef Common::Array<TabFocus> TabFocusList;
|
||||
|
||||
Focus _myFocus; // focus for base dialog
|
||||
TabFocusList _myTabList; // focus for each tab (if any)
|
||||
|
||||
WidgetArray _buttonGroup;
|
||||
FBSurface* _surface;
|
||||
|
||||
int _result;
|
||||
int _focusID;
|
||||
int _surfaceID;
|
||||
int _tabID;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -178,7 +178,7 @@ GameInfoDialog::GameInfoDialog(
|
|||
wid.push_back(myType);
|
||||
|
||||
// Add items for tab 0
|
||||
addToFocusList(wid, tabID);
|
||||
addToFocusList(wid, myTab, tabID);
|
||||
|
||||
|
||||
// 2) Console properties
|
||||
|
@ -216,7 +216,7 @@ GameInfoDialog::GameInfoDialog(
|
|||
wid.push_back(myTVType);
|
||||
|
||||
// Add items for tab 1
|
||||
addToFocusList(wid, tabID);
|
||||
addToFocusList(wid, myTab, tabID);
|
||||
|
||||
|
||||
// 3) Controller properties
|
||||
|
@ -326,7 +326,7 @@ GameInfoDialog::GameInfoDialog(
|
|||
wid.push_back(myMouseY);
|
||||
|
||||
// Add items for tab 2
|
||||
addToFocusList(wid, tabID);
|
||||
addToFocusList(wid, myTab, tabID);
|
||||
|
||||
|
||||
// 4) Display properties
|
||||
|
@ -389,7 +389,7 @@ GameInfoDialog::GameInfoDialog(
|
|||
myPPBlendLabel->setFlags(WIDGET_CLEARBG);
|
||||
|
||||
// Add items for tab 3
|
||||
addToFocusList(wid, tabID);
|
||||
addToFocusList(wid, myTab, tabID);
|
||||
|
||||
|
||||
// Activate the first tab
|
||||
|
|
|
@ -67,7 +67,7 @@ InputDialog::InputDialog(OSystem* osystem, DialogContainer* parent,
|
|||
myTab->getHeight() - ypos,
|
||||
actions, kEmulationMode);
|
||||
myTab->setParentWidget(tabID, myEmulEventMapper);
|
||||
addToFocusList(myEmulEventMapper->getFocusList(), tabID);
|
||||
addToFocusList(myEmulEventMapper->getFocusList(), myTab, tabID);
|
||||
|
||||
// 2) Event mapper for UI actions
|
||||
tabID = myTab->addTab("UI Events");
|
||||
|
@ -78,7 +78,7 @@ InputDialog::InputDialog(OSystem* osystem, DialogContainer* parent,
|
|||
myTab->getHeight() - ypos,
|
||||
actions, kMenuMode);
|
||||
myTab->setParentWidget(tabID, myMenuEventMapper);
|
||||
addToFocusList(myMenuEventMapper->getFocusList(), tabID);
|
||||
addToFocusList(myMenuEventMapper->getFocusList(), myTab, tabID);
|
||||
|
||||
// 3) Devices & ports
|
||||
addDevicePortTab(font);
|
||||
|
@ -197,7 +197,7 @@ void InputDialog::addDevicePortTab(const GUI::Font& font)
|
|||
wid.push_back(myMouseControl);
|
||||
|
||||
// Add items for virtual device ports
|
||||
addToFocusList(wid, tabID);
|
||||
addToFocusList(wid, myTab, tabID);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -164,6 +164,12 @@ struct Rect
|
|||
void moveTo(const Point & p) {
|
||||
moveTo(p.x, p.y);
|
||||
}
|
||||
|
||||
friend ostream& operator<<(ostream& os, const Rect& r) {
|
||||
os << "x=" << r.x() << ", y=" << r.y()
|
||||
<< ", w=" << r.width() << ", h=" << r.height();
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
} // End of namespace GUI
|
||||
|
|
|
@ -39,6 +39,8 @@ TabWidget::TabWidget(GuiObject* boss, const GUI::Font& font,
|
|||
_activeTab(-1),
|
||||
_firstTime(true)
|
||||
{
|
||||
_id = 0; // For dialogs with multiple tab widgets, they should specifically
|
||||
// call ::setID to differentiate among them
|
||||
_flags = WIDGET_ENABLED | WIDGET_CLEARBG;
|
||||
_type = kTabWidget;
|
||||
_bgcolor = kDlgColor;
|
||||
|
@ -112,7 +114,7 @@ void TabWidget::setActiveTab(int tabID, bool show)
|
|||
|
||||
// Let parent know about the tab change
|
||||
if(show)
|
||||
sendCommand(kTabChangedCmd, _activeTab, -1);
|
||||
sendCommand(kTabChangedCmd, _activeTab, _id);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -156,7 +156,7 @@ UIDialog::UIDialog(OSystem* osystem, DialogContainer* parent,
|
|||
kTextAlignLeft);
|
||||
|
||||
// Add items for tab 0
|
||||
addToFocusList(wid, tabID);
|
||||
addToFocusList(wid, myTab, tabID);
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// 2) Debugger options
|
||||
|
@ -211,7 +211,7 @@ UIDialog::UIDialog(OSystem* osystem, DialogContainer* parent,
|
|||
}
|
||||
|
||||
// Add items for tab 1
|
||||
addToFocusList(wid, tabID);
|
||||
addToFocusList(wid, myTab, tabID);
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// 3) Misc. options
|
||||
|
@ -263,7 +263,7 @@ UIDialog::UIDialog(OSystem* osystem, DialogContainer* parent,
|
|||
ypos += lineHeight + 4;
|
||||
|
||||
// Add items for tab 2
|
||||
addToFocusList(wid, tabID);
|
||||
addToFocusList(wid, myTab, tabID);
|
||||
|
||||
// Activate the first tab
|
||||
myTab->setActiveTab(0);
|
||||
|
|
|
@ -236,7 +236,7 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent,
|
|||
ypos += lineHeight + 4;
|
||||
|
||||
// Add items for tab 0
|
||||
addToFocusList(wid, tabID);
|
||||
addToFocusList(wid, myTab, tabID);
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// 2) TV effects options
|
||||
|
@ -326,7 +326,7 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent,
|
|||
CREATE_CLONE_BUTTON(Custom, "Revert");
|
||||
|
||||
// Add items for tab 2
|
||||
addToFocusList(wid, tabID);
|
||||
addToFocusList(wid, myTab, tabID);
|
||||
|
||||
// Activate the first tab
|
||||
myTab->setActiveTab(0);
|
||||
|
|
|
@ -39,6 +39,7 @@ SerialPortMACOSX::SerialPortMACOSX()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
SerialPortMACOSX::~SerialPortMACOSX()
|
||||
{
|
||||
closePort();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -65,7 +66,10 @@ bool SerialPortMACOSX::openPort(const string& device)
|
|||
void SerialPortMACOSX::closePort()
|
||||
{
|
||||
if(myHandle)
|
||||
{
|
||||
close(myHandle);
|
||||
myHandle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -49,7 +49,10 @@ bool SerialPortWin32::openPort(const string& device)
|
|||
FillMemory(&dcb, sizeof(dcb), 0);
|
||||
dcb.DCBlength = sizeof(dcb);
|
||||
if(!BuildCommDCB("19200,n,8,1", &dcb))
|
||||
{
|
||||
closePort()
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(&dcb, 0, sizeof(DCB));
|
||||
dcb.BaudRate = CBR_19200;
|
||||
|
|
Loading…
Reference in New Issue