Made the Debugger dialog use a TabWidget again, instead of it being another

Dialog.  This was necessary since it seems Dialogs can't contain other
dialogs in the GUI core.

Added keyboard navigation to the TabWidget class.  For now, it's only
enabled for the Debugger.  Ctrl-Tab/Shift-Ctrl-Tab switches to the
next/previous tab (respectively), and Tab/Shift-Tab switches to the
next/previous widget in the current tab.

There's still a bit of work to do, but the infrastructure is there.
That's it, I'm taking the night off, because this deceptively simple
concept has taken about a day to implement ...


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@479 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2005-06-10 17:46:07 +00:00
parent c988604949
commit 4ee8ee8cd7
18 changed files with 519 additions and 287 deletions

View File

@ -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

View File

@ -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 <cassert>
@ -88,6 +88,9 @@ OSystem::OSystem()
#ifdef DEVELOPER_SUPPORT
myFeatures += "Debugger";
#endif
// When we first start Stella, no GUI widget is active
GuiObject::resetActiveWidget();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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);
}

View File

@ -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

View File

@ -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)
{

View File

@ -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);

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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 <stdarg.h>
#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];

View File

@ -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)
{

View File

@ -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:

View File

@ -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;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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<Tab> 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

View File

@ -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)

View File

@ -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);
};