2005-05-04 21:32:25 +00:00
|
|
|
//============================================================================
|
|
|
|
//
|
|
|
|
// SSSS tt lll lll
|
|
|
|
// SS SS tt ll ll
|
|
|
|
// SS tttttt eeee ll ll aaaa
|
|
|
|
// SSSS tt ee ee ll ll aa
|
|
|
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
|
|
// SS SS tt ee ll ll aa aa
|
|
|
|
// SSSS ttt eeeee llll llll aaaaa
|
|
|
|
//
|
2005-06-16 00:56:00 +00:00
|
|
|
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
|
2005-05-04 21:32:25 +00:00
|
|
|
//
|
|
|
|
// See the file "license" for information on usage and redistribution of
|
|
|
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
|
|
//
|
2005-08-04 22:59:54 +00:00
|
|
|
// $Id: DialogContainer.cxx,v 1.14 2005-08-04 22:59:54 stephena Exp $
|
2005-05-04 21:32:25 +00:00
|
|
|
//============================================================================
|
|
|
|
|
|
|
|
#include "OSystem.hxx"
|
|
|
|
#include "Dialog.hxx"
|
|
|
|
#include "Stack.hxx"
|
2005-05-26 15:43:44 +00:00
|
|
|
#include "EventHandler.hxx"
|
2005-05-04 21:32:25 +00:00
|
|
|
#include "bspf.hxx"
|
|
|
|
#include "DialogContainer.hxx"
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
DialogContainer::DialogContainer(OSystem* osystem)
|
|
|
|
: myOSystem(osystem),
|
2005-05-26 15:43:44 +00:00
|
|
|
myBaseDialog(NULL),
|
|
|
|
myTime(0)
|
2005-05-04 21:32:25 +00:00
|
|
|
{
|
|
|
|
myCurrentKeyDown.keycode = 0;
|
2005-05-26 15:43:44 +00:00
|
|
|
myCurrentMouseDown.button = -1;
|
2005-05-04 21:32:25 +00:00
|
|
|
myLastClick.x = myLastClick.y = 0;
|
|
|
|
myLastClick.time = 0;
|
|
|
|
myLastClick.count = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
DialogContainer::~DialogContainer()
|
|
|
|
{
|
|
|
|
if(myBaseDialog)
|
|
|
|
delete myBaseDialog;
|
|
|
|
}
|
|
|
|
|
2005-05-26 15:43:44 +00:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void DialogContainer::updateTime(uInt32 time)
|
|
|
|
{
|
|
|
|
// We only need millisecond precision
|
|
|
|
myTime = time / 1000;
|
|
|
|
|
|
|
|
if(myDialogStack.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Check for pending continuous events and send them to the active dialog box
|
|
|
|
Dialog* activeDialog = myDialogStack.top();
|
|
|
|
|
|
|
|
if(myCurrentKeyDown.keycode != 0 && myKeyRepeatTime < myTime)
|
|
|
|
{
|
|
|
|
activeDialog->handleKeyDown(myCurrentKeyDown.ascii, myCurrentKeyDown.keycode,
|
|
|
|
myCurrentKeyDown.flags);
|
|
|
|
myKeyRepeatTime = myTime + kKeyRepeatSustainDelay;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(myCurrentMouseDown.button != -1 && myClickRepeatTime < myTime)
|
|
|
|
{
|
|
|
|
activeDialog->handleMouseDown(myCurrentMouseDown.x - activeDialog->_x,
|
|
|
|
myCurrentMouseDown.y - activeDialog->_y,
|
|
|
|
myCurrentMouseDown.button, 1);
|
|
|
|
myClickRepeatTime = myTime + kClickRepeatSustainDelay;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-05-04 21:32:25 +00:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2005-08-01 22:33:16 +00:00
|
|
|
void DialogContainer::draw(bool fullrefresh)
|
2005-05-04 21:32:25 +00:00
|
|
|
{
|
2005-08-01 22:33:16 +00:00
|
|
|
// Draw all the dialogs on the stack when we want a full refresh
|
|
|
|
if(fullrefresh)
|
2005-05-04 21:32:25 +00:00
|
|
|
{
|
2005-08-01 22:33:16 +00:00
|
|
|
for(int i = 0; i < myDialogStack.size(); i++)
|
|
|
|
{
|
|
|
|
myDialogStack[i]->open();
|
|
|
|
myDialogStack[i]->drawDialog();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(!myDialogStack.empty())
|
|
|
|
{
|
|
|
|
myDialogStack.top()->drawDialog();
|
2005-05-04 21:32:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void DialogContainer::addDialog(Dialog* d)
|
|
|
|
{
|
|
|
|
myDialogStack.push(d);
|
2005-08-04 22:59:54 +00:00
|
|
|
d->open();
|
|
|
|
d->setDirty(); // Next update() will take care of drawing
|
2005-05-04 21:32:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void DialogContainer::removeDialog()
|
|
|
|
{
|
|
|
|
if(!myDialogStack.empty())
|
|
|
|
{
|
|
|
|
myDialogStack.pop();
|
2005-08-04 22:59:54 +00:00
|
|
|
|
|
|
|
// We need to redraw all underlying dialogs, since we don't know
|
|
|
|
// which ones were obscured
|
2005-07-20 15:52:58 +00:00
|
|
|
myOSystem->frameBuffer().refreshTIA();
|
2005-06-23 14:33:12 +00:00
|
|
|
myOSystem->frameBuffer().refreshOverlay();
|
2005-05-04 21:32:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void DialogContainer::reStack()
|
|
|
|
{
|
|
|
|
// Pop all items from the stack, and then add the base menu
|
|
|
|
while(!myDialogStack.empty())
|
2005-05-16 15:37:30 +00:00
|
|
|
myDialogStack.pop();
|
2005-07-20 15:52:58 +00:00
|
|
|
addDialog(myBaseDialog);
|
2005-05-16 15:37:30 +00:00
|
|
|
|
|
|
|
// Now make sure all dialog boxes are in a known (closed) state
|
|
|
|
myBaseDialog->reset();
|
2005-05-26 15:43:44 +00:00
|
|
|
|
|
|
|
// Reset all continuous events
|
|
|
|
myCurrentKeyDown.keycode = 0;
|
|
|
|
myCurrentMouseDown.button = -1;
|
|
|
|
myLastClick.x = myLastClick.y = 0;
|
|
|
|
myLastClick.time = 0;
|
|
|
|
myLastClick.count = 0;
|
2005-05-04 21:32:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2005-06-07 21:22:39 +00:00
|
|
|
void DialogContainer::handleKeyEvent(int unicode, int key, int mod, uInt8 state)
|
2005-05-04 21:32:25 +00:00
|
|
|
{
|
|
|
|
if(myDialogStack.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Send the event to the dialog box on the top of the stack
|
|
|
|
Dialog* activeDialog = myDialogStack.top();
|
|
|
|
if(state == 1)
|
2005-05-26 15:43:44 +00:00
|
|
|
{
|
2005-06-07 21:22:39 +00:00
|
|
|
myCurrentKeyDown.ascii = unicode;
|
2005-05-26 15:43:44 +00:00
|
|
|
myCurrentKeyDown.keycode = key;
|
|
|
|
myCurrentKeyDown.flags = mod;
|
|
|
|
myKeyRepeatTime = myTime + kKeyRepeatInitialDelay;
|
|
|
|
|
2005-06-07 21:22:39 +00:00
|
|
|
activeDialog->handleKeyDown(unicode, key, mod);
|
2005-05-26 15:43:44 +00:00
|
|
|
}
|
2005-05-04 21:32:25 +00:00
|
|
|
else
|
2005-05-26 15:43:44 +00:00
|
|
|
{
|
2005-06-07 21:22:39 +00:00
|
|
|
activeDialog->handleKeyUp(unicode, key, mod);
|
2005-05-26 15:43:44 +00:00
|
|
|
|
|
|
|
// Only stop firing events if it's the current key
|
|
|
|
if (key == myCurrentKeyDown.keycode)
|
|
|
|
myCurrentKeyDown.keycode = 0;
|
|
|
|
}
|
2005-05-04 21:32:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2005-05-13 18:28:06 +00:00
|
|
|
void DialogContainer::handleMouseMotionEvent(int x, int y, int button)
|
2005-05-04 21:32:25 +00:00
|
|
|
{
|
|
|
|
if(myDialogStack.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Send the event to the dialog box on the top of the stack
|
|
|
|
Dialog* activeDialog = myDialogStack.top();
|
|
|
|
activeDialog->handleMouseMoved(x - activeDialog->_x,
|
|
|
|
y - activeDialog->_y,
|
|
|
|
button);
|
2005-06-10 18:46:11 +00:00
|
|
|
|
|
|
|
// Turn off continuous click events as soon as the mouse moves
|
|
|
|
myCurrentMouseDown.button = -1;
|
2005-05-04 21:32:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2005-05-13 18:28:06 +00:00
|
|
|
void DialogContainer::handleMouseButtonEvent(MouseButton b, int x, int y, uInt8 state)
|
2005-05-04 21:32:25 +00:00
|
|
|
{
|
|
|
|
if(myDialogStack.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Send the event to the dialog box on the top of the stack
|
|
|
|
Dialog* activeDialog = myDialogStack.top();
|
|
|
|
|
|
|
|
switch(b)
|
|
|
|
{
|
|
|
|
case EVENT_LBUTTONDOWN:
|
|
|
|
case EVENT_RBUTTONDOWN:
|
|
|
|
// If more than two clicks have been recorded, we start over
|
|
|
|
if(myLastClick.count == 2)
|
|
|
|
{
|
|
|
|
myLastClick.x = myLastClick.y = 0;
|
|
|
|
myLastClick.time = 0;
|
|
|
|
myLastClick.count = 0;
|
|
|
|
}
|
|
|
|
|
2005-05-26 15:43:44 +00:00
|
|
|
if(myLastClick.count && (myTime < myLastClick.time + kDoubleClickDelay)
|
2005-05-04 21:32:25 +00:00
|
|
|
&& ABS(myLastClick.x - x) < 3
|
|
|
|
&& ABS(myLastClick.y - y) < 3)
|
|
|
|
{
|
|
|
|
myLastClick.count++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
myLastClick.x = x;
|
|
|
|
myLastClick.y = y;
|
|
|
|
myLastClick.count = 1;
|
|
|
|
}
|
2005-05-26 15:43:44 +00:00
|
|
|
myLastClick.time = myTime;
|
|
|
|
|
|
|
|
// Now account for repeated mouse events (click and hold)
|
|
|
|
myCurrentMouseDown.x = x;
|
|
|
|
myCurrentMouseDown.y = y;
|
|
|
|
myCurrentMouseDown.button = 1; // in the future, we may differentiate buttons
|
|
|
|
myClickRepeatTime = myTime + kClickRepeatInitialDelay;
|
|
|
|
|
2005-05-04 21:32:25 +00:00
|
|
|
activeDialog->handleMouseDown(x - activeDialog->_x, y - activeDialog->_y,
|
|
|
|
1, myLastClick.count);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EVENT_LBUTTONUP:
|
|
|
|
case EVENT_RBUTTONUP:
|
|
|
|
activeDialog->handleMouseUp(x - activeDialog->_x, y - activeDialog->_y,
|
|
|
|
1, myLastClick.count);
|
2005-05-26 15:43:44 +00:00
|
|
|
// Since all buttons are treated equally, we don't need to check which button
|
|
|
|
//if (button == myCurrentClickDown.button)
|
|
|
|
myCurrentMouseDown.button = -1;
|
2005-05-04 21:32:25 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case EVENT_WHEELUP:
|
|
|
|
activeDialog->handleMouseWheel(x - activeDialog->_x, y - activeDialog->_y, -1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EVENT_WHEELDOWN:
|
|
|
|
activeDialog->handleMouseWheel(x - activeDialog->_x, y - activeDialog->_y, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2005-05-25 23:22:11 +00:00
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2005-05-26 15:43:44 +00:00
|
|
|
void DialogContainer::handleJoyEvent(int stick, int button, uInt8 state)
|
2005-05-25 23:22:11 +00:00
|
|
|
{
|
|
|
|
if(myDialogStack.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Send the event to the dialog box on the top of the stack
|
|
|
|
Dialog* activeDialog = myDialogStack.top();
|
|
|
|
if(state == 1)
|
2005-05-26 15:43:44 +00:00
|
|
|
activeDialog->handleJoyDown(stick, button);
|
2005-05-25 23:22:11 +00:00
|
|
|
else
|
2005-05-26 15:43:44 +00:00
|
|
|
activeDialog->handleJoyUp(stick, button);
|
2005-05-25 23:22:11 +00:00
|
|
|
}
|