mirror of https://github.com/stella-emu/stella.git
Starting to add GUI code from ScummVM.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@377 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
f3b4648eac
commit
5489ca7248
|
@ -12,12 +12,15 @@
|
||||||
Release History
|
Release History
|
||||||
===============================================================================
|
===============================================================================
|
||||||
1.4.2a to 1.4.2b: MacOSX version only (February 27, 2005)
|
1.4.2a to 1.4.2b: MacOSX version only (February 27, 2005)
|
||||||
|
|
||||||
* Added fix to mute sound while user is loading a new cartridge, or using
|
* Added fix to mute sound while user is loading a new cartridge, or using
|
||||||
the Preferences window.
|
the Preferences window.
|
||||||
|
|
||||||
1.4.2 to 1.4.2a: MacOSX version only (February 21, 2005)
|
1.4.2 to 1.4.2a: MacOSX version only (February 21, 2005)
|
||||||
|
|
||||||
* Fixed problem in timing loop which was causing crashes after 15-30
|
* Fixed problem in timing loop which was causing crashes after 15-30
|
||||||
minutes.
|
minutes.
|
||||||
|
|
||||||
* Turned optimization on in compiler settings, which had somehow gotten
|
* Turned optimization on in compiler settings, which had somehow gotten
|
||||||
turned off.
|
turned off.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
Please distribute this file with the SDL runtime environment:
|
Please distribute this file with the SDL runtime environment:
|
||||||
|
|
||||||
The Simple DirectMedia Layer (SDL for short) is a cross-platfrom library
|
The Simple DirectMedia Layer (SDL for short) is a cross-platfrom library
|
||||||
|
@ -10,4 +9,3 @@ http://www.libsdl.org/
|
||||||
|
|
||||||
This library is distributed under the terms of the GNU LGPL license:
|
This library is distributed under the terms of the GNU LGPL license:
|
||||||
http://www.gnu.org/copyleft/lesser.html
|
http://www.gnu.org/copyleft/lesser.html
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
## See the file "license" for information on usage and redistribution of
|
## See the file "license" for information on usage and redistribution of
|
||||||
## this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
## this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
##
|
##
|
||||||
## $Id: makefile,v 1.61 2005-02-22 02:59:52 stephena Exp $
|
## $Id: makefile,v 1.62 2005-02-27 23:41:17 stephena Exp $
|
||||||
##============================================================================
|
##============================================================================
|
||||||
|
|
||||||
##============================================================================
|
##============================================================================
|
||||||
|
@ -32,7 +32,7 @@ OPTIMIZATIONS =
|
||||||
|
|
||||||
### to include support for saving snapshots in png format
|
### to include support for saving snapshots in png format
|
||||||
### (requires PNG library)
|
### (requires PNG library)
|
||||||
SNAPSHOT_SUPPORT = 1
|
# SNAPSHOT_SUPPORT = 1
|
||||||
|
|
||||||
### to include support for game developers
|
### to include support for game developers
|
||||||
### enables some extra commandline options that allow the user
|
### enables some extra commandline options that allow the user
|
||||||
|
@ -41,7 +41,7 @@ OPTIMIZATIONS =
|
||||||
|
|
||||||
### to build on SMP (or distcc-based) machines
|
### to build on SMP (or distcc-based) machines
|
||||||
### change to number of CPU's you have
|
### change to number of CPU's you have
|
||||||
NUMBER_CPU = 1
|
NUMBER_CPU = 3
|
||||||
|
|
||||||
##============================================================================
|
##============================================================================
|
||||||
## All done, type make to get a list of frontends
|
## All done, type make to get a list of frontends
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
//
|
||||||
// $Id: mainSDL.cxx,v 1.26 2005-02-25 02:29:37 stephena Exp $
|
// $Id: mainSDL.cxx,v 1.27 2005-02-27 23:41:17 stephena Exp $
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -876,7 +876,7 @@ int main(int argc, char* argv[])
|
||||||
theShowInfoFlag = theSettings->getBool("showinfo");
|
theShowInfoFlag = theSettings->getBool("showinfo");
|
||||||
theGrabMouseIndicator = theSettings->getBool("grabmouse");
|
theGrabMouseIndicator = theSettings->getBool("grabmouse");
|
||||||
theHideCursorIndicator = theSettings->getBool("hidecursor");
|
theHideCursorIndicator = theSettings->getBool("hidecursor");
|
||||||
bool theRomLauncherFlag = true;//theSettings->getBool("romlauncher");
|
bool theRomLauncherFlag = false;//true;//FIXMEtheSettings->getBool("romlauncher");
|
||||||
|
|
||||||
// Create a properties set for us to use and set it up
|
// Create a properties set for us to use and set it up
|
||||||
PropertiesSet propertiesSet;
|
PropertiesSet propertiesSet;
|
||||||
|
@ -971,9 +971,10 @@ int main(int argc, char* argv[])
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cerr << "Attempting to open " << romfile << endl;
|
if((theConsole = CreateConsole(romfile)) != NULL)
|
||||||
theConsole = CreateConsole(romfile);
|
|
||||||
mainGameLoop();
|
mainGameLoop();
|
||||||
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
//
|
||||||
// $Id: EventHandler.cxx,v 1.34 2005-02-25 02:29:38 stephena Exp $
|
// $Id: EventHandler.cxx,v 1.35 2005-02-27 23:41:18 stephena Exp $
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -127,10 +127,6 @@ void EventHandler::handleKeyEvent(SDLKey key, SDLMod mod, uInt8 state)
|
||||||
// Determine which mode we're in, then send the event to the appropriate place
|
// Determine which mode we're in, then send the event to the appropriate place
|
||||||
switch(myState)
|
switch(myState)
|
||||||
{
|
{
|
||||||
case S_NONE:
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case S_EMULATE:
|
case S_EMULATE:
|
||||||
// if(mod & KMOD_ALT && state)
|
// if(mod & KMOD_ALT && state)
|
||||||
// handleEvent(myAltKeyTable[key], state);
|
// handleEvent(myAltKeyTable[key], state);
|
||||||
|
@ -140,17 +136,21 @@ void EventHandler::handleKeyEvent(SDLKey key, SDLMod mod, uInt8 state)
|
||||||
handleEvent(myKeyTable[key], state);
|
handleEvent(myKeyTable[key], state);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_BROWSER:
|
|
||||||
//FIXME myOSystem->gui().browser().handleKeyEvent(key, mod, state);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case S_MENU:
|
case S_MENU:
|
||||||
//FIXME myOSystem->gui().menu().handleKeyEvent(key, mod, state);
|
//FIXME myOSystem->gui().menu().handleKeyEvent(key, mod, state);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case S_BROWSER:
|
||||||
|
//FIXME myOSystem->gui().browser().handleKeyEvent(key, mod, state);
|
||||||
|
break;
|
||||||
|
|
||||||
case S_DEBUGGER:
|
case S_DEBUGGER:
|
||||||
// Not yet implemented
|
// Not yet implemented
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case S_NONE:
|
||||||
|
return;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
//
|
||||||
// $Id: EventHandler.hxx,v 1.17 2005-02-25 02:29:38 stephena Exp $
|
// $Id: EventHandler.hxx,v 1.18 2005-02-27 23:41:19 stephena Exp $
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#ifndef EVENTHANDLER_HXX
|
#ifndef EVENTHANDLER_HXX
|
||||||
|
@ -32,17 +32,16 @@ class OSystem;
|
||||||
This class takes care of event remapping and dispatching for the
|
This class takes care of event remapping and dispatching for the
|
||||||
Stella core, as well as keeping track of the current 'mode'.
|
Stella core, as well as keeping track of the current 'mode'.
|
||||||
|
|
||||||
The frontends will send translated events here, and the handler will
|
The frontend will send translated events here, and the handler will
|
||||||
check to see what the current 'mode' is. For now, the modes can be
|
check to see what the current 'mode' is.
|
||||||
normal and menu mode.
|
|
||||||
|
|
||||||
If in normal mode, events received from the frontends are remapped and
|
If in emulation mode, events received from the frontend are remapped and
|
||||||
sent to the emulation core. If in menu mode, the events are sent
|
sent to the emulation core. If in menu mode, the events are sent
|
||||||
unchanged to the user interface, where (among other things) changing key
|
unchanged to the menu class, where (among other things) changing key
|
||||||
mapping can take place.
|
mapping can take place.
|
||||||
|
|
||||||
@author Stephen Anthony
|
@author Stephen Anthony
|
||||||
@version $Id: EventHandler.hxx,v 1.17 2005-02-25 02:29:38 stephena Exp $
|
@version $Id: EventHandler.hxx,v 1.18 2005-02-27 23:41:19 stephena Exp $
|
||||||
*/
|
*/
|
||||||
class EventHandler
|
class EventHandler
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
//
|
||||||
// $Id: FrameBuffer.cxx,v 1.16 2005-02-22 18:40:59 stephena Exp $
|
// $Id: FrameBuffer.cxx,v 1.17 2005-02-27 23:41:19 stephena Exp $
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -192,12 +192,12 @@ void FrameBuffer::update()
|
||||||
// Do any pre-frame stuff
|
// Do any pre-frame stuff
|
||||||
preFrameUpdate();
|
preFrameUpdate();
|
||||||
|
|
||||||
// Determine which mode we are in (normal or menu mode)
|
// Determine which mode we are in (from the EventHandler)
|
||||||
// In normal mode, only the mediasource or messages are shown,
|
// Take care of S_EMULATE mode here, otherwise let the GUI
|
||||||
// and they are shown per-frame
|
// figure out what to draw
|
||||||
// In menu mode, any of the menus are shown, but the mediasource
|
switch(myOSystem->eventHandler().state())
|
||||||
// is not updated, and all updates depend on whether the screen is dirty
|
{
|
||||||
if(!myMenuMode)
|
case EventHandler::S_EMULATE:
|
||||||
{
|
{
|
||||||
// Draw changes to the mediasource
|
// Draw changes to the mediasource
|
||||||
if(!myPauseStatus)
|
if(!myPauseStatus)
|
||||||
|
@ -226,8 +226,10 @@ void FrameBuffer::update()
|
||||||
theRedrawEntireFrameIndicator = true;
|
theRedrawEntireFrameIndicator = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break; // S_EMULATE
|
||||||
}
|
}
|
||||||
else // we are in MENU_MODE
|
|
||||||
|
case EventHandler::S_MENU: // FIXME - this whole thing will disappear into the gui().menu class
|
||||||
{
|
{
|
||||||
// Only update the screen if it's been invalidated
|
// Only update the screen if it's been invalidated
|
||||||
// or the menus have changed
|
// or the menus have changed
|
||||||
|
@ -236,23 +238,21 @@ void FrameBuffer::update()
|
||||||
drawMediaSource();
|
drawMediaSource();
|
||||||
|
|
||||||
// Then overlay any menu items
|
// Then overlay any menu items
|
||||||
|
// FIXME myOSystem->gui().menu().draw();
|
||||||
|
|
||||||
switch(myCurrentWidget)
|
switch(myCurrentWidget)
|
||||||
{
|
{
|
||||||
case W_NONE:
|
case W_NONE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MAIN_MENU:
|
case MAIN_MENU:
|
||||||
drawMainMenu();
|
drawMainMenu();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REMAP_MENU:
|
case REMAP_MENU:
|
||||||
drawRemapMenu();
|
drawRemapMenu();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INFO_MENU:
|
case INFO_MENU:
|
||||||
drawInfoMenu();
|
drawInfoMenu();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -268,6 +268,20 @@ void FrameBuffer::update()
|
||||||
myMenuRedraws--;
|
myMenuRedraws--;
|
||||||
theMenuChangedIndicator = (myMenuRedraws != 0);
|
theMenuChangedIndicator = (myMenuRedraws != 0);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EventHandler::S_BROWSER:
|
||||||
|
// FIXME myOSystem->gui().browser().draw();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EventHandler::S_DEBUGGER:
|
||||||
|
// Not yet implemented
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EventHandler::S_NONE:
|
||||||
|
return;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do any post-frame stuff
|
// Do any post-frame stuff
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
//
|
||||||
// $Id: FrameBuffer.hxx,v 1.16 2005-02-22 18:41:11 stephena Exp $
|
// $Id: FrameBuffer.hxx,v 1.17 2005-02-27 23:41:19 stephena Exp $
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#ifndef FRAMEBUFFER_HXX
|
#ifndef FRAMEBUFFER_HXX
|
||||||
|
@ -39,7 +39,7 @@ FIXME This class also implements a MAME-like user interface where Stella settin
|
||||||
can be changed.
|
can be changed.
|
||||||
|
|
||||||
@author Stephen Anthony
|
@author Stephen Anthony
|
||||||
@version $Id: FrameBuffer.hxx,v 1.16 2005-02-22 18:41:11 stephena Exp $
|
@version $Id: FrameBuffer.hxx,v 1.17 2005-02-27 23:41:19 stephena Exp $
|
||||||
*/
|
*/
|
||||||
class FrameBuffer
|
class FrameBuffer
|
||||||
{
|
{
|
||||||
|
@ -160,8 +160,8 @@ FIXME
|
||||||
void refresh(bool now = false)
|
void refresh(bool now = false)
|
||||||
{
|
{
|
||||||
theRedrawEntireFrameIndicator = true;
|
theRedrawEntireFrameIndicator = true;
|
||||||
if(now)
|
myMenuRedraws = 2;
|
||||||
drawMediaSource();
|
if(now) drawMediaSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,277 @@
|
||||||
|
/* ScummVM - Scumm Interpreter
|
||||||
|
* Copyright (C) 2002-2004 The ScummVM project
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* $Header: /home/stephena/STELLA_CVS-to-SVN/stella/src/gui/Dialog.cxx,v 1.1 2005-02-27 23:41:19 stephena Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "newgui.h"
|
||||||
|
#include "dialog.h"
|
||||||
|
#include "widget.h"
|
||||||
|
|
||||||
|
namespace GUI {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO list
|
||||||
|
* - add some sense of the window being "active" (i.e. in front) or not. If it
|
||||||
|
* was inactive and just became active, reset certain vars (like who is focused).
|
||||||
|
* Maybe we should just add lostFocus and receivedFocus methods to Dialog, just
|
||||||
|
* like we have for class Widget?
|
||||||
|
* ...
|
||||||
|
*/
|
||||||
|
|
||||||
|
Dialog::~Dialog() {
|
||||||
|
delete _firstWidget;
|
||||||
|
_firstWidget = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Dialog::runModal() {
|
||||||
|
// Open up
|
||||||
|
open();
|
||||||
|
|
||||||
|
// Start processing events
|
||||||
|
g_gui.runLoop();
|
||||||
|
|
||||||
|
// Return the result code
|
||||||
|
return _result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dialog::open() {
|
||||||
|
Widget *w = _firstWidget;
|
||||||
|
|
||||||
|
_result = 0;
|
||||||
|
_visible = true;
|
||||||
|
g_gui.openDialog(this);
|
||||||
|
|
||||||
|
// Search for the first objects that wantsFocus() (if any) and give it the focus
|
||||||
|
while (w && !w->wantsFocus()) {
|
||||||
|
w = w->_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w) {
|
||||||
|
w->receivedFocus();
|
||||||
|
_focusedWidget = w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dialog::close() {
|
||||||
|
_visible = false;
|
||||||
|
g_gui.closeTopDialog();
|
||||||
|
|
||||||
|
if (_mouseWidget) {
|
||||||
|
_mouseWidget->handleMouseLeft(0);
|
||||||
|
_mouseWidget = 0;
|
||||||
|
}
|
||||||
|
releaseFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dialog::releaseFocus() {
|
||||||
|
if (_focusedWidget) {
|
||||||
|
_focusedWidget->lostFocus();
|
||||||
|
_focusedWidget = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dialog::draw() {
|
||||||
|
g_gui._needRedraw = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dialog::drawDialog() {
|
||||||
|
|
||||||
|
if (!isVisible())
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_gui.blendRect(_x, _y, _w, _h, g_gui._bgcolor);
|
||||||
|
g_gui.box(_x, _y, _w, _h, g_gui._color, g_gui._shadowcolor);
|
||||||
|
|
||||||
|
// Draw all children
|
||||||
|
Widget *w = _firstWidget;
|
||||||
|
while (w) {
|
||||||
|
w->draw();
|
||||||
|
w = w->_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flag the draw area as dirty
|
||||||
|
g_gui.addDirtyRect(_x, _y, _w, _h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dialog::handleMouseDown(int x, int y, int button, int clickCount) {
|
||||||
|
Widget *w;
|
||||||
|
w = findWidget(x, y);
|
||||||
|
|
||||||
|
// If the click occured inside a widget which is not the currently
|
||||||
|
// focused one, change the focus to that widget.
|
||||||
|
// TODO: use the wantsFocus() method to objects, so that only fields
|
||||||
|
// that want it get the focus (like edit fields, list field...)
|
||||||
|
// However, right now we "abuse" the focus also for the click&drag
|
||||||
|
// behaviour of buttons. This should probably be changed by adding
|
||||||
|
// a nother field, e.g. _clickedWidget or _dragWidget.
|
||||||
|
if (w && w != _focusedWidget) {
|
||||||
|
// The focus will change. Tell the old focused widget (if any)
|
||||||
|
// that it lost the focus.
|
||||||
|
releaseFocus();
|
||||||
|
|
||||||
|
// Tell the new focused widget (if any) that it just gained the focus.
|
||||||
|
if (w)
|
||||||
|
w->receivedFocus();
|
||||||
|
|
||||||
|
_focusedWidget = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w && w == _focusedWidget)
|
||||||
|
_focusedWidget->handleMouseDown(x - (_focusedWidget->getAbsX() - _x), y - (_focusedWidget->getAbsY() - _y), button, clickCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dialog::handleMouseUp(int x, int y, int button, int clickCount) {
|
||||||
|
Widget *w;
|
||||||
|
|
||||||
|
if (_focusedWidget) {
|
||||||
|
w = _focusedWidget;
|
||||||
|
|
||||||
|
// Lose focus on mouseup unless the widget requested to retain the focus
|
||||||
|
if (! (_focusedWidget->getFlags() & WIDGET_RETAIN_FOCUS )) {
|
||||||
|
releaseFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
w = findWidget(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w)
|
||||||
|
w->handleMouseUp(x - (w->getAbsX() - _x), y - (w->getAbsY() - _y), button, 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);
|
||||||
|
if (!w)
|
||||||
|
w = _focusedWidget;
|
||||||
|
if (w)
|
||||||
|
w->handleMouseWheel(x, y, direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) {
|
||||||
|
if (_focusedWidget) {
|
||||||
|
if (_focusedWidget->handleKeyDown(ascii, keycode, modifiers))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hotkey handling
|
||||||
|
if (ascii != 0) {
|
||||||
|
Widget *w = _firstWidget;
|
||||||
|
ascii = toupper(ascii);
|
||||||
|
while (w) {
|
||||||
|
if (w->_type == kButtonWidget && ascii == toupper(((ButtonWidget *)w)->_hotkey)) {
|
||||||
|
// The hotkey for widget w was pressed. We fake a mouse click into the
|
||||||
|
// button by invoking the appropriate methods.
|
||||||
|
w->handleMouseDown(0, 0, 1, 1);
|
||||||
|
w->handleMouseUp(0, 0, 1, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
w = w->_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ESC closes all dialogs by default
|
||||||
|
if (keycode == 27) {
|
||||||
|
setResult(-1);
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: tab/shift-tab should focus the next/previous focusable widget
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dialog::handleKeyUp(uint16 ascii, int keycode, int modifiers) {
|
||||||
|
// Focused widget receives keyup events
|
||||||
|
if (_focusedWidget)
|
||||||
|
_focusedWidget->handleKeyUp(ascii, keycode, modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dialog::handleMouseMoved(int x, int y, int button) {
|
||||||
|
Widget *w;
|
||||||
|
|
||||||
|
if (_focusedWidget) {
|
||||||
|
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);
|
||||||
|
if (mouseInFocusedWidget && _mouseWidget != w) {
|
||||||
|
_mouseWidget = w;
|
||||||
|
w->handleMouseEntered(button);
|
||||||
|
} else if (!mouseInFocusedWidget && _mouseWidget == w) {
|
||||||
|
_mouseWidget = 0;
|
||||||
|
w->handleMouseLeft(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
w->handleMouseMoved(x - wx, y - wy, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
w = findWidget(x, y);
|
||||||
|
|
||||||
|
if (_mouseWidget != w) {
|
||||||
|
if (_mouseWidget)
|
||||||
|
_mouseWidget->handleMouseLeft(button);
|
||||||
|
if (w)
|
||||||
|
w->handleMouseEntered(button);
|
||||||
|
_mouseWidget = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!w || !(w->getFlags() & WIDGET_TRACK_MOUSE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
w->handleMouseMoved(x - (w->getAbsX() - _x), y - (w->getAbsY() - _y), button);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dialog::handleTickle() {
|
||||||
|
// Focused widget receives tickle notifications
|
||||||
|
if (_focusedWidget && _focusedWidget->getFlags() & WIDGET_WANT_TICKLE) {
|
||||||
|
_focusedWidget->handleTickle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
|
||||||
|
switch (cmd) {
|
||||||
|
case kCloseCmd:
|
||||||
|
close();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine the widget at location (x,y) if any. Assumes the coordinates are
|
||||||
|
* in the local coordinate system, i.e. relative to the top left of the dialog.
|
||||||
|
*/
|
||||||
|
Widget *Dialog::findWidget(int x, int y) {
|
||||||
|
return Widget::findWidgetInChain(_firstWidget, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonWidget *Dialog::addButton(int x, int y, const Common::String &label, uint32 cmd, char hotkey) {
|
||||||
|
return new ButtonWidget(this, x, y, kButtonWidth, 16, label, cmd, hotkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace GUI
|
|
@ -0,0 +1,87 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
// Copyright (c) 1995-2005 by Bradford W. Mott
|
||||||
|
//
|
||||||
|
// 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.1 2005-02-27 23:41:19 stephena Exp $
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#ifndef DIALOG_HXX
|
||||||
|
#define DIALOG_HXX
|
||||||
|
|
||||||
|
#include "bspf.hxx"
|
||||||
|
|
||||||
|
#include "common/scummsys.h"
|
||||||
|
#include "common/str.h"
|
||||||
|
|
||||||
|
#include "gui/object.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
This is the base class for all dialog boxes.
|
||||||
|
|
||||||
|
@author Stephen Anthony
|
||||||
|
@version $Id: Dialog.hxx,v 1.1 2005-02-27 23:41:19 stephena Exp $
|
||||||
|
*/
|
||||||
|
class Dialog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Dialog(uInt16 x, uInt16 y, uInt16 w, uInt16 h)
|
||||||
|
: GuiObject(x, y, w, h),
|
||||||
|
_mouseWidget(0), _focusedWidget(0), _visible(false) {
|
||||||
|
}
|
||||||
|
virtual ~Dialog();
|
||||||
|
|
||||||
|
virtual int runModal();
|
||||||
|
|
||||||
|
bool isVisible() const { return _visible; }
|
||||||
|
|
||||||
|
void releaseFocus();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void open();
|
||||||
|
virtual void close();
|
||||||
|
|
||||||
|
virtual void draw();
|
||||||
|
virtual void drawDialog();
|
||||||
|
|
||||||
|
virtual void handleTickle(); // Called periodically (in every guiloop() )
|
||||||
|
virtual void handleMouseDown(int x, int y, int button, int clickCount);
|
||||||
|
virtual void handleMouseUp(int x, int y, int button, int clickCount);
|
||||||
|
virtual void handleMouseWheel(int x, int y, int direction);
|
||||||
|
virtual void handleKeyDown(uint16 ascii, int keycode, int modifiers);
|
||||||
|
virtual void handleKeyUp(uint16 ascii, int keycode, int modifiers);
|
||||||
|
virtual void handleMouseMoved(int x, int y, int button);
|
||||||
|
virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
|
||||||
|
virtual void handleScreenChanged() {}
|
||||||
|
|
||||||
|
Widget *findWidget(int x, int y); // Find the widget at pos x,y if any
|
||||||
|
|
||||||
|
ButtonWidget *addButton(int x, int y, const Common::String &label, uint32 cmd, char hotkey);
|
||||||
|
|
||||||
|
void setResult(int result) { _result = result; }
|
||||||
|
int getResult() const { return _result; }
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Widget *_mouseWidget;
|
||||||
|
Widget *_focusedWidget;
|
||||||
|
bool _visible;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _result;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // End of namespace GUI
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,60 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
// Copyright (c) 1995-2005 by Bradford W. Mott
|
||||||
|
//
|
||||||
|
// 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.1 2005-02-27 23:41:19 stephena Exp $
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#ifndef GUI_OBJECT_HXX
|
||||||
|
#define GUI_OBJECT_HXX
|
||||||
|
|
||||||
|
class Widget;
|
||||||
|
|
||||||
|
#include "bspf.hxx"
|
||||||
|
|
||||||
|
/**
|
||||||
|
This is the base class for all GUI objects/widgets.
|
||||||
|
|
||||||
|
@author Stephen Anthony
|
||||||
|
@version $Id: GuiObject.hxx,v 1.1 2005-02-27 23:41:19 stephena Exp $
|
||||||
|
*/
|
||||||
|
class GuiObject
|
||||||
|
{
|
||||||
|
//friend class Widget;
|
||||||
|
|
||||||
|
public:
|
||||||
|
GuiObject(int x, int y, int w, int h) : _x(x), _y(y), _w(w), _h(h), _firstWidget(0) { }
|
||||||
|
|
||||||
|
virtual Int16 getAbsX() const { return _x; }
|
||||||
|
virtual Int16 getAbsY() const { return _y; }
|
||||||
|
virtual Int16 getChildX() const { return getAbsX(); }
|
||||||
|
virtual Int16 getChildY() const { return getAbsY(); }
|
||||||
|
virtual uInt16 getWidth() const { return _w; }
|
||||||
|
virtual uInt16 getHeight() const { return _h; }
|
||||||
|
|
||||||
|
virtual bool isVisible() const = 0;
|
||||||
|
|
||||||
|
virtual void draw() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Int16 _x, _y;
|
||||||
|
uInt16 _w, _h;
|
||||||
|
|
||||||
|
Widget* _firstWidget;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void releaseFocus() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,47 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
// Copyright (c) 1995-2005 by Bradford W. Mott
|
||||||
|
//
|
||||||
|
// See the file "license" for information on usage and redistribution of
|
||||||
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
|
//
|
||||||
|
// $Id: Menu.cxx,v 1.1 2005-02-27 23:41:19 stephena Exp $
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#include "bspf.hxx"
|
||||||
|
|
||||||
|
#include "Menu.hxx"
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Menu::Menu()
|
||||||
|
{
|
||||||
|
cerr << "Menu::Menu()\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Menu::~Menu()
|
||||||
|
{
|
||||||
|
cerr << "Menu::~Menu()\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Menu::handleKeyEvent(SDLKey key, SDLMod mod, uInt8 state)
|
||||||
|
{
|
||||||
|
cerr << "Menu::handleKeyEvent()\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Menu::draw()
|
||||||
|
{
|
||||||
|
cerr << "Menu::draw()\n";
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
// Copyright (c) 1995-2005 by Bradford W. Mott
|
||||||
|
//
|
||||||
|
// See the file "license" for information on usage and redistribution of
|
||||||
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
|
//
|
||||||
|
// $Id: Menu.hxx,v 1.1 2005-02-27 23:41:19 stephena Exp $
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#ifndef MENU_HXX
|
||||||
|
#define MENU_HXX
|
||||||
|
|
||||||
|
#include "bspf.hxx"
|
||||||
|
|
||||||
|
/**
|
||||||
|
The base class for all menus in Stella.
|
||||||
|
|
||||||
|
This class keeps track of all configuration menus. organizes them into
|
||||||
|
a stack, and handles their events.
|
||||||
|
|
||||||
|
@author Stephen Anthony
|
||||||
|
@version $Id: Menu.hxx,v 1.1 2005-02-27 23:41:19 stephena Exp $
|
||||||
|
*/
|
||||||
|
class Menu
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
Create a new menu stack
|
||||||
|
*/
|
||||||
|
Menu();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Destructor
|
||||||
|
*/
|
||||||
|
virtual ~Menu();
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
Handle a keyboard event.
|
||||||
|
|
||||||
|
@param key keysym
|
||||||
|
@param mod modifiers
|
||||||
|
@param state state of key
|
||||||
|
*/
|
||||||
|
void handleKeyEvent(SDLKey key, SDLMod mod, uInt8 state);
|
||||||
|
|
||||||
|
// FIXME - add mouse and joystick handlers
|
||||||
|
|
||||||
|
/**
|
||||||
|
Draw the stack of menus.
|
||||||
|
*/
|
||||||
|
void draw();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,267 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
// Copyright (c) 1995-2005 by Bradford W. Mott
|
||||||
|
//
|
||||||
|
// 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.1 2005-02-27 23:41:19 stephena Exp $
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#include "Dialog.hxx"
|
||||||
|
#include "GuiObject.hxx"
|
||||||
|
#include "bspf.hxx"
|
||||||
|
|
||||||
|
#include "Widget.hxx"
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Widget::Widget(GuiObject* boss, uInt32 x, uInt32 y, uInt32 w, uInt32 h)
|
||||||
|
: GuiObject(x, y, w, h), _type(0), _boss(boss),
|
||||||
|
_id(0), _flags(0), _hasFocus(false)
|
||||||
|
{
|
||||||
|
// Insert into the widget list of the boss
|
||||||
|
_next = _boss->_firstWidget;
|
||||||
|
_boss->_firstWidget = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Widget::~Widget()
|
||||||
|
{
|
||||||
|
delete _next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Widget::draw()
|
||||||
|
{
|
||||||
|
NewGui *gui = &g_gui;
|
||||||
|
|
||||||
|
if (!isVisible() || !_boss->isVisible())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int oldX = _x, oldY = _y;
|
||||||
|
|
||||||
|
// Account for our relative position in the dialog
|
||||||
|
_x = getAbsX();
|
||||||
|
_y = getAbsY();
|
||||||
|
|
||||||
|
// Clear background (unless alpha blending is enabled)
|
||||||
|
if (_flags & WIDGET_CLEARBG)
|
||||||
|
gui->fillRect(_x, _y, _w, _h, gui->_bgcolor);
|
||||||
|
|
||||||
|
// Draw border
|
||||||
|
if (_flags & WIDGET_BORDER) {
|
||||||
|
OverlayColor colorA = gui->_color;
|
||||||
|
OverlayColor colorB = gui->_shadowcolor;
|
||||||
|
if ((_flags & WIDGET_INV_BORDER) == WIDGET_INV_BORDER)
|
||||||
|
SWAP(colorA, colorB);
|
||||||
|
gui->box(_x, _y, _w, _h, colorA, colorB);
|
||||||
|
_x += 4;
|
||||||
|
_y += 4;
|
||||||
|
_w -= 8;
|
||||||
|
_h -= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now perform the actual widget draw
|
||||||
|
drawWidget((_flags & WIDGET_HILITED) ? true : false);
|
||||||
|
|
||||||
|
// Restore x/y
|
||||||
|
if (_flags & WIDGET_BORDER) {
|
||||||
|
_x -= 4;
|
||||||
|
_y -= 4;
|
||||||
|
_w += 8;
|
||||||
|
_h += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flag the draw area as dirty
|
||||||
|
gui->addDirtyRect(_x, _y, _w, _h);
|
||||||
|
|
||||||
|
_x = oldX;
|
||||||
|
_y = oldY;
|
||||||
|
|
||||||
|
// Draw all children
|
||||||
|
Widget *w = _firstWidget;
|
||||||
|
while (w) {
|
||||||
|
w->draw();
|
||||||
|
w = w->_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget *Widget::findWidgetInChain(Widget *w, int x, int y) {
|
||||||
|
while (w) {
|
||||||
|
// Stop as soon as we find a widget that contains the point (x,y)
|
||||||
|
if (x >= w->_x && x < w->_x + w->_w && y >= w->_y && y < w->_y + w->_h)
|
||||||
|
break;
|
||||||
|
w = w->_next;
|
||||||
|
}
|
||||||
|
if (w)
|
||||||
|
w = w->findWidget(x - w->_x, y - w->_y);
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
|
||||||
|
StaticTextWidget::StaticTextWidget(GuiObject *boss, int x, int y, int w, int h, const String &text, TextAlignment align)
|
||||||
|
: Widget(boss, x, y, w, h), _align(align) {
|
||||||
|
_flags = WIDGET_ENABLED;
|
||||||
|
_type = kStaticTextWidget;
|
||||||
|
setLabel(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StaticTextWidget::setValue(int value) {
|
||||||
|
char buf[256];
|
||||||
|
sprintf(buf, "%d", value);
|
||||||
|
_label = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StaticTextWidget::drawWidget(bool hilite) {
|
||||||
|
NewGui *gui = &g_gui;
|
||||||
|
gui->drawString(_label, _x, _y, _w, isEnabled() ? gui->_textcolor : gui->_color, _align);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
|
||||||
|
ButtonWidget::ButtonWidget(GuiObject *boss, int x, int y, int w, int h, const String &label, uint32 cmd, uint8 hotkey)
|
||||||
|
: StaticTextWidget(boss, x, y, w, h, label, kTextAlignCenter), CommandSender(boss),
|
||||||
|
_cmd(cmd), _hotkey(hotkey) {
|
||||||
|
_flags = WIDGET_ENABLED | WIDGET_BORDER | WIDGET_CLEARBG;
|
||||||
|
_type = kButtonWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ButtonWidget::handleMouseUp(int x, int y, int button, int clickCount) {
|
||||||
|
if (isEnabled() && x >= 0 && x < _w && y >= 0 && y < _h)
|
||||||
|
sendCommand(_cmd, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ButtonWidget::drawWidget(bool hilite) {
|
||||||
|
NewGui *gui = &g_gui;
|
||||||
|
gui->drawString(_label, _x, _y + (_h - kLineHeight)/2 + 1, _w,
|
||||||
|
!isEnabled() ? gui->_color :
|
||||||
|
hilite ? gui->_textcolorhi : gui->_textcolor, _align);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
|
||||||
|
/* 8x8 checkbox bitmap */
|
||||||
|
static uint32 checked_img[8] = {
|
||||||
|
0x00000000,
|
||||||
|
0x01000010,
|
||||||
|
0x00100100,
|
||||||
|
0x00011000,
|
||||||
|
0x00011000,
|
||||||
|
0x00100100,
|
||||||
|
0x01000010,
|
||||||
|
0x00000000,
|
||||||
|
};
|
||||||
|
|
||||||
|
CheckboxWidget::CheckboxWidget(GuiObject *boss, int x, int y, int w, int h, const String &label, uint32 cmd, uint8 hotkey)
|
||||||
|
: ButtonWidget(boss, x, y, w, h, label, cmd, hotkey), _state(false) {
|
||||||
|
_flags = WIDGET_ENABLED;
|
||||||
|
_type = kCheckboxWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckboxWidget::handleMouseUp(int x, int y, int button, int clickCount) {
|
||||||
|
if (isEnabled() && x >= 0 && x < _w && y >= 0 && y < _h) {
|
||||||
|
toggleState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckboxWidget::setState(bool state) {
|
||||||
|
if (_state != state) {
|
||||||
|
_state = state;
|
||||||
|
_flags ^= WIDGET_INV_BORDER;
|
||||||
|
draw();
|
||||||
|
}
|
||||||
|
sendCommand(_cmd, _state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckboxWidget::drawWidget(bool hilite) {
|
||||||
|
NewGui *gui = &g_gui;
|
||||||
|
|
||||||
|
// Draw the box
|
||||||
|
gui->box(_x, _y, 14, 14, gui->_color, gui->_shadowcolor);
|
||||||
|
|
||||||
|
// If checked, draw cross inside the box
|
||||||
|
if (_state)
|
||||||
|
gui->drawBitmap(checked_img, _x + 3, _y + 3, isEnabled() ? gui->_textcolor : gui->_color);
|
||||||
|
else
|
||||||
|
gui->fillRect(_x + 2, _y + 2, 10, 10, gui->_bgcolor);
|
||||||
|
|
||||||
|
// Finally draw the label
|
||||||
|
gui->drawString(_label, _x + 20, _y + 3, _w, isEnabled() ? gui->_textcolor : gui->_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
|
||||||
|
SliderWidget::SliderWidget(GuiObject *boss, int x, int y, int w, int h, const String &label, uint labelWidth, uint32 cmd, uint8 hotkey)
|
||||||
|
: ButtonWidget(boss, x, y, w, h, label, cmd, hotkey),
|
||||||
|
_value(0), _oldValue(0),_valueMin(0), _valueMax(100), _isDragging(false),
|
||||||
|
_labelWidth(labelWidth) {
|
||||||
|
_flags = WIDGET_ENABLED | WIDGET_TRACK_MOUSE | WIDGET_CLEARBG;
|
||||||
|
_type = kSliderWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SliderWidget::handleMouseMoved(int x, int y, int button) {
|
||||||
|
// TODO: when the mouse is dragged outside the widget, the slider should
|
||||||
|
// snap back to the old value.
|
||||||
|
if (isEnabled() && _isDragging && x >= (int)_labelWidth) {
|
||||||
|
int newValue = posToValue(x - _labelWidth);
|
||||||
|
if (newValue < _valueMin)
|
||||||
|
newValue = _valueMin;
|
||||||
|
else if (newValue > _valueMax)
|
||||||
|
newValue = _valueMax;
|
||||||
|
|
||||||
|
if (newValue != _value) {
|
||||||
|
_value = newValue;
|
||||||
|
draw();
|
||||||
|
sendCommand(_cmd, _value); // FIXME - hack to allow for "live update" in sound dialog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SliderWidget::handleMouseDown(int x, int y, int button, int clickCount) {
|
||||||
|
if (isEnabled()) {
|
||||||
|
_isDragging = true;
|
||||||
|
handleMouseMoved(x, y, button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SliderWidget::handleMouseUp(int x, int y, int button, int clickCount) {
|
||||||
|
if (isEnabled() && _isDragging) {
|
||||||
|
sendCommand(_cmd, _value);
|
||||||
|
}
|
||||||
|
_isDragging = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SliderWidget::drawWidget(bool hilite) {
|
||||||
|
NewGui *gui = &g_gui;
|
||||||
|
|
||||||
|
// Draw the label, if any
|
||||||
|
if (_labelWidth > 0)
|
||||||
|
gui->drawString(_label, _x, _y + 2, _labelWidth, isEnabled() ? gui->_textcolor : gui->_color, kTextAlignRight);
|
||||||
|
|
||||||
|
// Draw the box
|
||||||
|
gui->box(_x + _labelWidth, _y, _w - _labelWidth, _h, gui->_color, gui->_shadowcolor);
|
||||||
|
|
||||||
|
// Draw the 'bar'
|
||||||
|
gui->fillRect(_x + _labelWidth + 2, _y + 2, valueToPos(_value), _h - 4,
|
||||||
|
!isEnabled() ? gui->_color :
|
||||||
|
hilite ? gui->_textcolorhi : gui->_textcolor);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SliderWidget::valueToPos(int value) {
|
||||||
|
return ((_w - _labelWidth - 4) * (value - _valueMin) / (_valueMax - _valueMin));
|
||||||
|
}
|
||||||
|
|
||||||
|
int SliderWidget::posToValue(int pos) {
|
||||||
|
return (pos) * (_valueMax - _valueMin) / (_w - _labelWidth - 4) + _valueMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace GUI
|
|
@ -0,0 +1,196 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
// Copyright (c) 1995-2005 by Bradford W. Mott
|
||||||
|
//
|
||||||
|
// 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.1 2005-02-27 23:41:19 stephena Exp $
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#ifndef WIDGET_HXX
|
||||||
|
#define WIDGET_HXX
|
||||||
|
|
||||||
|
class Dialog;
|
||||||
|
|
||||||
|
#include "GuiObject.hxx"
|
||||||
|
#include "bspf.hxx"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
This is the base class for all widgets.
|
||||||
|
|
||||||
|
@author Stephen Anthony
|
||||||
|
@version $Id: Widget.hxx,v 1.1 2005-02-27 23:41:19 stephena Exp $
|
||||||
|
*/
|
||||||
|
class Widget : public GuiObject
|
||||||
|
{
|
||||||
|
friend class Dialog;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Widget(GuiObject* boss, uInt32 x, uInt32 y, uInt32 w, uInt32 h);
|
||||||
|
virtual ~Widget();
|
||||||
|
|
||||||
|
virtual Int16 getAbsX() const { return _x + _boss->getChildX(); }
|
||||||
|
virtual Int16 getAbsY() const { return _y + _boss->getChildY(); }
|
||||||
|
|
||||||
|
virtual void handleMouseDown(uInt32 x, uInt32 y, uInt32 button, uInt32 clickCount) {}
|
||||||
|
virtual void handleMouseUp(uInt32 x, uInt32 y, uInt32 button, uInt32 clickCount) {}
|
||||||
|
virtual void handleMouseEntered(uInt32 button) {}
|
||||||
|
virtual void handleMouseLeft(uInt32 button) {}
|
||||||
|
virtual void handleMouseMoved(uInt32 x, uInt32 y, uInt32 button) {}
|
||||||
|
virtual void handleMouseWheel(uInt32 x, uInt32 y, uInt32 direction) {}
|
||||||
|
//FIXME virtual bool handleKeyDown(uint16 ascii, int keycode, int modifiers) { return false; } // Return true if the event was handled
|
||||||
|
//FIXME virtual bool handleKeyUp(uint16 ascii, int keycode, int modifiers) { return false; } // Return true if the event was handled
|
||||||
|
virtual void handleTickle() {}
|
||||||
|
|
||||||
|
void draw();
|
||||||
|
void receivedFocus() { _hasFocus = true; receivedFocusWidget(); }
|
||||||
|
void lostFocus() { _hasFocus = false; lostFocusWidget(); }
|
||||||
|
virtual bool wantsFocus() { return false; };
|
||||||
|
|
||||||
|
void setFlags(int flags) { _flags |= flags; }
|
||||||
|
void clearFlags(int flags) { _flags &= ~flags; }
|
||||||
|
uInt32 getFlags() const { return _flags; }
|
||||||
|
|
||||||
|
void setEnabled(bool e) { if (e) setFlags(WIDGET_ENABLED); else clearFlags(WIDGET_ENABLED); }
|
||||||
|
bool isEnabled() const { return _flags & WIDGET_ENABLED; }
|
||||||
|
bool isVisible() const { return !(_flags & WIDGET_INVISIBLE); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void drawWidget(bool hilite) {}
|
||||||
|
|
||||||
|
virtual void receivedFocusWidget() {}
|
||||||
|
virtual void lostFocusWidget() {}
|
||||||
|
|
||||||
|
virtual Widget *findWidget(uInt32 x, uInt32 y) { return this; }
|
||||||
|
|
||||||
|
void releaseFocus() { assert(_boss); _boss->releaseFocus(); }
|
||||||
|
|
||||||
|
// By default, delegate unhandled commands to the boss
|
||||||
|
void handleCommand(CommandSender *sender, uint32 cmd, uint32 data)
|
||||||
|
{ assert(_boss); _boss->handleCommand(sender, cmd, data); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uInt32 _type;
|
||||||
|
GuiObject* _boss;
|
||||||
|
Widget* _next;
|
||||||
|
uInt16 _id;
|
||||||
|
uInt16 _flags;
|
||||||
|
bool _hasFocus;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static Widget *findWidgetInChain(Widget *start, uInt32 x, uInt32 y);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* StaticTextWidget */
|
||||||
|
class StaticTextWidget : public Widget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StaticTextWidget(GuiObject* boss, uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
||||||
|
const String &text, TextAlignment align);
|
||||||
|
void setValue(uInt32 value);
|
||||||
|
void setLabel(const string& label) { _label = label; }
|
||||||
|
const string& getLabel() const { return _label; }
|
||||||
|
void setAlign(TextAlignment align) { _align = align; }
|
||||||
|
TextAlignment getAlign() const { return _align; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void drawWidget(bool hilite);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// typedef Graphics::TextAlignment TextAlignment;
|
||||||
|
|
||||||
|
string _label;
|
||||||
|
// TextAlignment _align;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* ButtonWidget */
|
||||||
|
class ButtonWidget : public StaticTextWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ButtonWidget(GuiObject* boss, uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
||||||
|
const string& label, uInt32 cmd = 0, uInt8 hotkey = 0);
|
||||||
|
|
||||||
|
void setCmd(uint32 cmd) { _cmd = cmd; }
|
||||||
|
uint32 getCmd() const { return _cmd; }
|
||||||
|
|
||||||
|
void handleMouseUp(uInt32 x, uInt32 y, uInt32 button, uInt32 clickCount);
|
||||||
|
void handleMouseEntered(uInt32 button) { setFlags(WIDGET_HILITED); draw(); }
|
||||||
|
void handleMouseLeft(uInt32 button) { clearFlags(WIDGET_HILITED); draw(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void drawWidget(bool hilite);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uInt32 _cmd;
|
||||||
|
uInt8 _hotkey;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* CheckboxWidget */
|
||||||
|
class CheckboxWidget : public ButtonWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CheckboxWidget(GuiObject* boss, uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
||||||
|
const string& label, uInt32 cmd = 0, uInt8 hotkey = 0);
|
||||||
|
|
||||||
|
void handleMouseUp(uInt32 x, uInt32 y, uInt32 button, uInt32 clickCount);
|
||||||
|
virtual void handleMouseEntered(uInt32 button) {}
|
||||||
|
virtual void handleMouseLeft(uInt32 button) {}
|
||||||
|
|
||||||
|
void setState(bool state);
|
||||||
|
void toggleState() { setState(!_state); }
|
||||||
|
bool getState() const { return _state; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void drawWidget(bool hilite);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool _state;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* SliderWidget */
|
||||||
|
class SliderWidget : public ButtonWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SliderWidget(GuiObject *boss, int x, int y, int w, int h, const string& label = "",
|
||||||
|
uInt32 labelWidth = 0, uInt32 cmd = 0, uInt8 hotkey = 0);
|
||||||
|
|
||||||
|
void setValue(uInt32 value) { _value = value; }
|
||||||
|
uInt32 getValue() const { return _value; }
|
||||||
|
|
||||||
|
void setMinValue(uInt32 value) { _valueMin = value; }
|
||||||
|
uInt32 getMinValue() const { return _valueMin; }
|
||||||
|
void setMaxValue(uInt32 value) { _valueMax = value; }
|
||||||
|
uInt32 getMaxValue() const { return _valueMax; }
|
||||||
|
|
||||||
|
void handleMouseMoved(uInt32 x, uInt32 y, uInt32 button);
|
||||||
|
void handleMouseDown(uInt32 x, uInt32 y, uInt32 button, uInt32 clickCount);
|
||||||
|
void handleMouseUp(uInt32 x, uInt32 y, uInt32 button, uInt32 clickCount);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void drawWidget(bool hilite);
|
||||||
|
|
||||||
|
uInt32 valueToPos(uInt32 value);
|
||||||
|
uInt32 posToValue(uInt32 pos);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uInt32 _value, _oldValue;
|
||||||
|
uInt32 _valueMin, _valueMax;
|
||||||
|
bool _isDragging;
|
||||||
|
uInt32 _labelWidth;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue