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
|
||||
===============================================================================
|
||||
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
|
||||
the Preferences window.
|
||||
|
||||
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
|
||||
minutes.
|
||||
|
||||
* Turned optimization on in compiler settings, which had somehow gotten
|
||||
turned off.
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
Please distribute this file with the SDL runtime environment:
|
||||
|
||||
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:
|
||||
http://www.gnu.org/copyleft/lesser.html
|
||||
|
||||
|
|
|
@ -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.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
|
||||
### (requires PNG library)
|
||||
SNAPSHOT_SUPPORT = 1
|
||||
# SNAPSHOT_SUPPORT = 1
|
||||
|
||||
### to include support for game developers
|
||||
### enables some extra commandline options that allow the user
|
||||
|
@ -41,7 +41,7 @@ OPTIMIZATIONS =
|
|||
|
||||
### to build on SMP (or distcc-based) machines
|
||||
### change to number of CPU's you have
|
||||
NUMBER_CPU = 1
|
||||
NUMBER_CPU = 3
|
||||
|
||||
##============================================================================
|
||||
## 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
|
||||
// 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>
|
||||
|
@ -876,7 +876,7 @@ int main(int argc, char* argv[])
|
|||
theShowInfoFlag = theSettings->getBool("showinfo");
|
||||
theGrabMouseIndicator = theSettings->getBool("grabmouse");
|
||||
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
|
||||
PropertiesSet propertiesSet;
|
||||
|
@ -971,9 +971,10 @@ int main(int argc, char* argv[])
|
|||
break;
|
||||
else
|
||||
{
|
||||
cerr << "Attempting to open " << romfile << endl;
|
||||
theConsole = CreateConsole(romfile);
|
||||
mainGameLoop();
|
||||
if((theConsole = CreateConsole(romfile)) != NULL)
|
||||
mainGameLoop();
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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: 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>
|
||||
|
@ -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
|
||||
switch(myState)
|
||||
{
|
||||
case S_NONE:
|
||||
return;
|
||||
break;
|
||||
|
||||
case S_EMULATE:
|
||||
// if(mod & KMOD_ALT && state)
|
||||
// handleEvent(myAltKeyTable[key], state);
|
||||
|
@ -140,17 +136,21 @@ void EventHandler::handleKeyEvent(SDLKey key, SDLMod mod, uInt8 state)
|
|||
handleEvent(myKeyTable[key], state);
|
||||
break;
|
||||
|
||||
case S_BROWSER:
|
||||
//FIXME myOSystem->gui().browser().handleKeyEvent(key, mod, state);
|
||||
break;
|
||||
|
||||
case S_MENU:
|
||||
//FIXME myOSystem->gui().menu().handleKeyEvent(key, mod, state);
|
||||
break;
|
||||
|
||||
case S_BROWSER:
|
||||
//FIXME myOSystem->gui().browser().handleKeyEvent(key, mod, state);
|
||||
break;
|
||||
|
||||
case S_DEBUGGER:
|
||||
// Not yet implemented
|
||||
break;
|
||||
|
||||
case S_NONE:
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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: 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
|
||||
|
@ -32,17 +32,16 @@ class OSystem;
|
|||
This class takes care of event remapping and dispatching for the
|
||||
Stella core, as well as keeping track of the current 'mode'.
|
||||
|
||||
The frontends will send translated events here, and the handler will
|
||||
check to see what the current 'mode' is. For now, the modes can be
|
||||
normal and menu mode.
|
||||
The frontend will send translated events here, and the handler will
|
||||
check to see what the current 'mode' is.
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
@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
|
||||
{
|
||||
|
|
|
@ -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: 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>
|
||||
|
@ -192,82 +192,96 @@ void FrameBuffer::update()
|
|||
// Do any pre-frame stuff
|
||||
preFrameUpdate();
|
||||
|
||||
// Determine which mode we are in (normal or menu mode)
|
||||
// In normal mode, only the mediasource or messages are shown,
|
||||
// and they are shown per-frame
|
||||
// In menu mode, any of the menus are shown, but the mediasource
|
||||
// is not updated, and all updates depend on whether the screen is dirty
|
||||
if(!myMenuMode)
|
||||
// Determine which mode we are in (from the EventHandler)
|
||||
// Take care of S_EMULATE mode here, otherwise let the GUI
|
||||
// figure out what to draw
|
||||
switch(myOSystem->eventHandler().state())
|
||||
{
|
||||
// Draw changes to the mediasource
|
||||
if(!myPauseStatus)
|
||||
myOSystem->console().mediaSource().update();
|
||||
|
||||
// We always draw the screen, even if the core is paused
|
||||
drawMediaSource();
|
||||
|
||||
if(!myPauseStatus)
|
||||
case EventHandler::S_EMULATE:
|
||||
{
|
||||
// Draw any pending messages
|
||||
if(myMessageTime > 0)
|
||||
{
|
||||
uInt32 width = myMessageText.length()*FONTWIDTH + FONTWIDTH;
|
||||
uInt32 height = LINEOFFSET + FONTHEIGHT;
|
||||
uInt32 x = (myWidth >> 1) - (width >> 1);
|
||||
uInt32 y = myHeight - height - LINEOFFSET/2;
|
||||
// Draw changes to the mediasource
|
||||
if(!myPauseStatus)
|
||||
myOSystem->console().mediaSource().update();
|
||||
|
||||
// Draw the bounded box and text
|
||||
drawBoundedBox(x, y+1, width, height-2);
|
||||
drawText(x + XBOXOFFSET/2, LINEOFFSET/2 + y, myMessageText);
|
||||
myMessageTime--;
|
||||
|
||||
// Erase this message on next update
|
||||
if(myMessageTime == 0)
|
||||
theRedrawEntireFrameIndicator = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // we are in MENU_MODE
|
||||
{
|
||||
// Only update the screen if it's been invalidated
|
||||
// or the menus have changed
|
||||
if(theMenuChangedIndicator || theRedrawEntireFrameIndicator)
|
||||
{
|
||||
// We always draw the screen, even if the core is paused
|
||||
drawMediaSource();
|
||||
|
||||
// Then overlay any menu items
|
||||
switch(myCurrentWidget)
|
||||
if(!myPauseStatus)
|
||||
{
|
||||
case W_NONE:
|
||||
break;
|
||||
// Draw any pending messages
|
||||
if(myMessageTime > 0)
|
||||
{
|
||||
uInt32 width = myMessageText.length()*FONTWIDTH + FONTWIDTH;
|
||||
uInt32 height = LINEOFFSET + FONTHEIGHT;
|
||||
uInt32 x = (myWidth >> 1) - (width >> 1);
|
||||
uInt32 y = myHeight - height - LINEOFFSET/2;
|
||||
|
||||
case MAIN_MENU:
|
||||
drawMainMenu();
|
||||
break;
|
||||
// Draw the bounded box and text
|
||||
drawBoundedBox(x, y+1, width, height-2);
|
||||
drawText(x + XBOXOFFSET/2, LINEOFFSET/2 + y, myMessageText);
|
||||
myMessageTime--;
|
||||
|
||||
case REMAP_MENU:
|
||||
drawRemapMenu();
|
||||
break;
|
||||
|
||||
case INFO_MENU:
|
||||
drawInfoMenu();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
// Erase this message on next update
|
||||
if(myMessageTime == 0)
|
||||
theRedrawEntireFrameIndicator = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Now the screen is up to date
|
||||
theRedrawEntireFrameIndicator = false;
|
||||
|
||||
// This is a performance hack to only draw the menus when necessary
|
||||
// Software mode is single-buffered, so we don't have to worry
|
||||
// However, OpenGL mode is double-buffered, so we need to draw the
|
||||
// menus at least twice (so they'll be in both buffers)
|
||||
// Otherwise, we get horrible flickering
|
||||
myMenuRedraws--;
|
||||
theMenuChangedIndicator = (myMenuRedraws != 0);
|
||||
break; // S_EMULATE
|
||||
}
|
||||
|
||||
case EventHandler::S_MENU: // FIXME - this whole thing will disappear into the gui().menu class
|
||||
{
|
||||
// Only update the screen if it's been invalidated
|
||||
// or the menus have changed
|
||||
if(theMenuChangedIndicator || theRedrawEntireFrameIndicator)
|
||||
{
|
||||
drawMediaSource();
|
||||
|
||||
// Then overlay any menu items
|
||||
// FIXME myOSystem->gui().menu().draw();
|
||||
|
||||
switch(myCurrentWidget)
|
||||
{
|
||||
case W_NONE:
|
||||
break;
|
||||
case MAIN_MENU:
|
||||
drawMainMenu();
|
||||
break;
|
||||
case REMAP_MENU:
|
||||
drawRemapMenu();
|
||||
break;
|
||||
case INFO_MENU:
|
||||
drawInfoMenu();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Now the screen is up to date
|
||||
theRedrawEntireFrameIndicator = false;
|
||||
|
||||
// This is a performance hack to only draw the menus when necessary
|
||||
// Software mode is single-buffered, so we don't have to worry
|
||||
// However, OpenGL mode is double-buffered, so we need to draw the
|
||||
// menus at least twice (so they'll be in both buffers)
|
||||
// Otherwise, we get horrible flickering
|
||||
myMenuRedraws--;
|
||||
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
|
||||
|
|
|
@ -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: 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
|
||||
|
@ -39,7 +39,7 @@ FIXME This class also implements a MAME-like user interface where Stella settin
|
|||
can be changed.
|
||||
|
||||
@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
|
||||
{
|
||||
|
@ -160,8 +160,8 @@ FIXME
|
|||
void refresh(bool now = false)
|
||||
{
|
||||
theRedrawEntireFrameIndicator = true;
|
||||
if(now)
|
||||
drawMediaSource();
|
||||
myMenuRedraws = 2;
|
||||
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