- adds the new gui renderer also a new implementation for the classic gui
- adds a ImageMan and ImageDec class for loading and managing image files - adds a loader for zip files which is used by the new theme and the image manager - changes the widgets to use the new gui code - changes the scumm dialogs to use the new gui code - fixes a #include problem in the sky debugger with the new gui code To use the new gui copy gui/themes/default-theme.zip to your extrapath. If the theme zip can not be found the gui will fallback to the classic theme. If you want to change the gui styles use "gui_theme=classic" for the classic theme and "gui_theme=default-theme" for the new theme. Thanks to eriktorbjorn for testing and help with the new theme and to sev for reviewing this patch. svn-id: r20227
This commit is contained in:
parent
901645cb0f
commit
5051b080a2
32 changed files with 3868 additions and 627 deletions
|
@ -13,7 +13,8 @@ MODULE_OBJS := \
|
||||||
common/savefile.o \
|
common/savefile.o \
|
||||||
common/system.o \
|
common/system.o \
|
||||||
common/scaler.o \
|
common/scaler.o \
|
||||||
common/scaler/thumbnail.o
|
common/scaler/thumbnail.o \
|
||||||
|
common/unzip.o
|
||||||
|
|
||||||
ifndef DISABLE_SCALERS
|
ifndef DISABLE_SCALERS
|
||||||
MODULE_OBJS += \
|
MODULE_OBJS += \
|
||||||
|
|
1231
common/unzip.cpp
Normal file
1231
common/unzip.cpp
Normal file
File diff suppressed because it is too large
Load diff
300
common/unzip.h
Normal file
300
common/unzip.h
Normal file
|
@ -0,0 +1,300 @@
|
||||||
|
/* ScummVM - Scumm Interpreter
|
||||||
|
* Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $Header $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* unzip.h -- IO for uncompress .zip files using zlib
|
||||||
|
Version 0.15 beta, Mar 19th, 1998,
|
||||||
|
|
||||||
|
Copyright (C) 1998 Gilles Vollant
|
||||||
|
|
||||||
|
This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
|
||||||
|
WinZip, InfoZip tools and compatible.
|
||||||
|
Encryption and multi volume ZipFile (span) are not supported.
|
||||||
|
Old compressions used by old PKZip 1.x are not supported
|
||||||
|
|
||||||
|
THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE
|
||||||
|
CAN CHANGE IN FUTURE VERSION !!
|
||||||
|
I WAIT FEEDBACK at mail info@winimage.com
|
||||||
|
Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
|
||||||
|
|
||||||
|
Condition of use and distribution are the same than zlib :
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
/* for more info about .ZIP format, see
|
||||||
|
ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
|
||||||
|
PkWare has also a specification at :
|
||||||
|
ftp://ftp.pkware.com/probdesc.zip */
|
||||||
|
|
||||||
|
#ifndef _unz_H
|
||||||
|
#define _unz_H
|
||||||
|
|
||||||
|
#include "common/stdafx.h"
|
||||||
|
#include "common/scummsys.h"
|
||||||
|
|
||||||
|
#ifdef USE_ZLIB
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
|
||||||
|
/* like the STRICT of WIN32, we define a pointer that cannot be converted
|
||||||
|
from (void*) without cast */
|
||||||
|
typedef struct TagunzFile__ { int unused; } unzFile__;
|
||||||
|
typedef unzFile__ *unzFile;
|
||||||
|
#else
|
||||||
|
typedef voidp unzFile;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define UNZ_OK (0)
|
||||||
|
#define UNZ_END_OF_LIST_OF_FILE (-100)
|
||||||
|
#define UNZ_ERRNO (Z_ERRNO)
|
||||||
|
#define UNZ_EOF (0)
|
||||||
|
#define UNZ_PARAMERROR (-102)
|
||||||
|
#define UNZ_BADZIPFILE (-103)
|
||||||
|
#define UNZ_INTERNALERROR (-104)
|
||||||
|
#define UNZ_CRCERROR (-105)
|
||||||
|
|
||||||
|
/* tm_unz contain date/time info */
|
||||||
|
typedef struct tm_unz_s
|
||||||
|
{
|
||||||
|
uInt tm_sec; /* seconds after the minute - [0,59] */
|
||||||
|
uInt tm_min; /* minutes after the hour - [0,59] */
|
||||||
|
uInt tm_hour; /* hours since midnight - [0,23] */
|
||||||
|
uInt tm_mday; /* day of the month - [1,31] */
|
||||||
|
uInt tm_mon; /* months since January - [0,11] */
|
||||||
|
uInt tm_year; /* years - [1980..2044] */
|
||||||
|
} tm_unz;
|
||||||
|
|
||||||
|
/* unz_global_info structure contain global data about the ZIPfile
|
||||||
|
These data comes from the end of central dir */
|
||||||
|
typedef struct unz_global_info_s
|
||||||
|
{
|
||||||
|
uLong number_entry; /* total number of entries in
|
||||||
|
the central dir on this disk */
|
||||||
|
uLong size_comment; /* size of the global comment of the zipfile */
|
||||||
|
} unz_global_info;
|
||||||
|
|
||||||
|
|
||||||
|
/* unz_file_info contain information about a file in the zipfile */
|
||||||
|
typedef struct unz_file_info_s
|
||||||
|
{
|
||||||
|
uLong version; /* version made by 2 bytes */
|
||||||
|
uLong version_needed; /* version needed to extract 2 bytes */
|
||||||
|
uLong flag; /* general purpose bit flag 2 bytes */
|
||||||
|
uLong compression_method; /* compression method 2 bytes */
|
||||||
|
uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
|
||||||
|
uLong crc; /* crc-32 4 bytes */
|
||||||
|
uLong compressed_size; /* compressed size 4 bytes */
|
||||||
|
uLong uncompressed_size; /* uncompressed size 4 bytes */
|
||||||
|
uLong size_filename; /* filename length 2 bytes */
|
||||||
|
uLong size_file_extra; /* extra field length 2 bytes */
|
||||||
|
uLong size_file_comment; /* file comment length 2 bytes */
|
||||||
|
|
||||||
|
uLong disk_num_start; /* disk number start 2 bytes */
|
||||||
|
uLong internal_fa; /* internal file attributes 2 bytes */
|
||||||
|
uLong external_fa; /* external file attributes 4 bytes */
|
||||||
|
|
||||||
|
tm_unz tmu_date;
|
||||||
|
} unz_file_info;
|
||||||
|
|
||||||
|
extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
|
||||||
|
const char* fileName2,
|
||||||
|
int iCaseSensitivity));
|
||||||
|
/*
|
||||||
|
Compare two filename (fileName1,fileName2).
|
||||||
|
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
|
||||||
|
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
|
||||||
|
or strcasecmp)
|
||||||
|
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
|
||||||
|
(like 1 on Unix, 2 on Windows)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
extern unzFile ZEXPORT unzOpen OF((const char *path));
|
||||||
|
/*
|
||||||
|
Open a Zip file. path contain the full pathname (by example,
|
||||||
|
on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer
|
||||||
|
"zlib/zlib111.zip".
|
||||||
|
If the zipfile cannot be opened (file don't exist or in not valid), the
|
||||||
|
return value is NULL.
|
||||||
|
Else, the return value is a unzFile Handle, usable with other function
|
||||||
|
of this unzip package.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int ZEXPORT unzClose OF((unzFile file));
|
||||||
|
/*
|
||||||
|
Close a ZipFile opened with unzipOpen.
|
||||||
|
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
|
||||||
|
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
|
||||||
|
return UNZ_OK if there is no problem. */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
|
||||||
|
unz_global_info *pglobal_info));
|
||||||
|
/*
|
||||||
|
Write info about the ZipFile in the *pglobal_info structure.
|
||||||
|
No preparation of the structure is needed
|
||||||
|
return UNZ_OK if there is no problem. */
|
||||||
|
|
||||||
|
|
||||||
|
extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
|
||||||
|
char *szComment,
|
||||||
|
uLong uSizeBuf));
|
||||||
|
/*
|
||||||
|
Get the global comment string of the ZipFile, in the szComment buffer.
|
||||||
|
uSizeBuf is the size of the szComment buffer.
|
||||||
|
return the number of byte copied or an error code <0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* Unzip package allow you browse the directory of the zipfile */
|
||||||
|
|
||||||
|
extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
|
||||||
|
/*
|
||||||
|
Set the current file of the zipfile to the first file.
|
||||||
|
return UNZ_OK if there is no problem
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int ZEXPORT unzGoToNextFile OF((unzFile file));
|
||||||
|
/*
|
||||||
|
Set the current file of the zipfile to the next file.
|
||||||
|
return UNZ_OK if there is no problem
|
||||||
|
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int ZEXPORT unzLocateFile OF((unzFile file,
|
||||||
|
const char *szFileName,
|
||||||
|
int iCaseSensitivity));
|
||||||
|
/*
|
||||||
|
Try locate the file szFileName in the zipfile.
|
||||||
|
For the iCaseSensitivity signification, see unzStringFileNameCompare
|
||||||
|
|
||||||
|
return value :
|
||||||
|
UNZ_OK if the file is found. It becomes the current file.
|
||||||
|
UNZ_END_OF_LIST_OF_FILE if the file is not found
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
|
||||||
|
unz_file_info *pfile_info,
|
||||||
|
char *szFileName,
|
||||||
|
uLong fileNameBufferSize,
|
||||||
|
void *extraField,
|
||||||
|
uLong extraFieldBufferSize,
|
||||||
|
char *szComment,
|
||||||
|
uLong commentBufferSize));
|
||||||
|
/*
|
||||||
|
Get Info about the current file
|
||||||
|
if pfile_info!=NULL, the *pfile_info structure will contain somes info about
|
||||||
|
the current file
|
||||||
|
if szFileName!=NULL, the filemane string will be copied in szFileName
|
||||||
|
(fileNameBufferSize is the size of the buffer)
|
||||||
|
if extraField!=NULL, the extra field information will be copied in extraField
|
||||||
|
(extraFieldBufferSize is the size of the buffer).
|
||||||
|
This is the Central-header version of the extra field
|
||||||
|
if szComment!=NULL, the comment string of the file will be copied in szComment
|
||||||
|
(commentBufferSize is the size of the buffer)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* for reading the content of the current zipfile, you can open it, read data
|
||||||
|
from it, and close it (you can close it before reading all the file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
|
||||||
|
/*
|
||||||
|
Open for reading data the current file in the zipfile.
|
||||||
|
If there is no error, the return value is UNZ_OK.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
|
||||||
|
/*
|
||||||
|
Close the file in zip opened with unzOpenCurrentFile
|
||||||
|
Return UNZ_CRCERROR if all the file was read but the CRC is not good
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
|
||||||
|
voidp buf,
|
||||||
|
unsigned len));
|
||||||
|
/*
|
||||||
|
Read bytes from the current file (opened by unzOpenCurrentFile)
|
||||||
|
buf contain buffer where data must be copied
|
||||||
|
len the size of buf.
|
||||||
|
|
||||||
|
return the number of byte copied if somes bytes are copied
|
||||||
|
return 0 if the end of file was reached
|
||||||
|
return <0 with error code if there is an error
|
||||||
|
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern z_off_t ZEXPORT unztell OF((unzFile file));
|
||||||
|
/*
|
||||||
|
Give the current position in uncompressed data
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int ZEXPORT unzeof OF((unzFile file));
|
||||||
|
/*
|
||||||
|
return 1 if the end of file was reached, 0 elsewhere
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
|
||||||
|
voidp buf,
|
||||||
|
unsigned len));
|
||||||
|
/*
|
||||||
|
Read extra field from the current file (opened by unzOpenCurrentFile)
|
||||||
|
This is the local-header version of the extra field (sometimes, there is
|
||||||
|
more info in the local-header version than in the central-header)
|
||||||
|
|
||||||
|
if buf==NULL, it return the size of the local extra field
|
||||||
|
|
||||||
|
if buf!=NULL, len is the size of the buffer, the extra header is copied in
|
||||||
|
buf.
|
||||||
|
the return value is the number of bytes copied in buf, or (if <0)
|
||||||
|
the error code
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _unz_H */
|
174
graphics/imagedec.cpp
Normal file
174
graphics/imagedec.cpp
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
/* ScummVM - Scumm Interpreter
|
||||||
|
* Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $Header $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "graphics/imagedec.h"
|
||||||
|
|
||||||
|
#include "common/system.h"
|
||||||
|
#include "common/file.h"
|
||||||
|
|
||||||
|
namespace Graphics {
|
||||||
|
//
|
||||||
|
// BMP Decoder
|
||||||
|
//
|
||||||
|
class BMPDecoder : public ImageDecoder {
|
||||||
|
public:
|
||||||
|
BMPDecoder() {}
|
||||||
|
virtual ~BMPDecoder() {}
|
||||||
|
|
||||||
|
bool decodeable(Common::SeekableReadStream &stream);
|
||||||
|
Surface *decodeImage(Common::SeekableReadStream &stream);
|
||||||
|
|
||||||
|
struct BitmapHeader {
|
||||||
|
uint16 type;
|
||||||
|
uint32 size;
|
||||||
|
uint16 res1;
|
||||||
|
uint16 res2;
|
||||||
|
uint32 imageOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct InfoHeader {
|
||||||
|
uint32 size;
|
||||||
|
uint32 width;
|
||||||
|
uint32 height;
|
||||||
|
uint16 planes;
|
||||||
|
uint16 bitsPerPixel;
|
||||||
|
uint32 compression;
|
||||||
|
uint32 imageSize;
|
||||||
|
uint32 pixelsPerMeterX;
|
||||||
|
uint32 pixelsPerMeterY;
|
||||||
|
uint32 colorsUsed;
|
||||||
|
uint32 colorsImportant;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
bool BMPDecoder::decodeable(Common::SeekableReadStream &stream) {
|
||||||
|
BitmapHeader header;
|
||||||
|
stream.seek(0);
|
||||||
|
header.type = stream.readUint16BE();
|
||||||
|
header.size = stream.readUint32LE();
|
||||||
|
|
||||||
|
// TODO: maybe improve this detection
|
||||||
|
if (header.size == 0 || header.type != 'BM')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Surface *BMPDecoder::decodeImage(Common::SeekableReadStream &stream) {
|
||||||
|
if (!decodeable(stream)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BitmapHeader header;
|
||||||
|
InfoHeader info;
|
||||||
|
|
||||||
|
stream.seek(0);
|
||||||
|
header.type = stream.readUint16BE();
|
||||||
|
header.size = stream.readUint32LE();
|
||||||
|
header.res1 = stream.readUint16LE();
|
||||||
|
header.res2 = stream.readUint16LE();
|
||||||
|
header.imageOffset = stream.readUint32LE();
|
||||||
|
|
||||||
|
if (header.size == 0 || header.type != 'BM') {
|
||||||
|
stream.seek(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.size = stream.readUint32LE();
|
||||||
|
info.width = stream.readUint32LE();
|
||||||
|
info.height = stream.readUint32LE();
|
||||||
|
info.planes = stream.readUint16LE();
|
||||||
|
info.bitsPerPixel = stream.readUint16LE();
|
||||||
|
info.compression = stream.readUint32LE();
|
||||||
|
info.imageSize = stream.readUint32LE();
|
||||||
|
info.pixelsPerMeterX = stream.readUint32LE();
|
||||||
|
info.pixelsPerMeterY = stream.readUint32LE();
|
||||||
|
info.colorsUsed = stream.readUint32LE();
|
||||||
|
info.colorsImportant = stream.readUint32LE();
|
||||||
|
|
||||||
|
stream.seek(header.imageOffset);
|
||||||
|
|
||||||
|
if (info.bitsPerPixel != 24) {
|
||||||
|
stream.seek(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 r = 0, g = 0, b = 0;
|
||||||
|
Surface *newSurf = new Surface;
|
||||||
|
assert(newSurf);
|
||||||
|
newSurf->create(info.width, info.height, sizeof(OverlayColor));
|
||||||
|
assert(newSurf->pixels);
|
||||||
|
OverlayColor *curPixel = (OverlayColor*)newSurf->pixels + (newSurf->h-1) * newSurf->w;
|
||||||
|
int pitchAdd = info.width % 4;
|
||||||
|
for (int i = 0; i < newSurf->h; ++i) {
|
||||||
|
for (int i2 = 0; i2 < newSurf->w; ++i2) {
|
||||||
|
b = stream.readByte();
|
||||||
|
g = stream.readByte();
|
||||||
|
r = stream.readByte();
|
||||||
|
*curPixel = OSystem::instance().RGBToColor(r, g, b);
|
||||||
|
++curPixel;
|
||||||
|
}
|
||||||
|
stream.seek(pitchAdd, SEEK_CUR);
|
||||||
|
curPixel -= newSurf->w*2;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.seek(0);
|
||||||
|
return newSurf;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
|
||||||
|
Surface *ImageDecoder::loadFile(const Common::String &name) {
|
||||||
|
Surface *newSurf = 0;
|
||||||
|
|
||||||
|
Common::File imageFile;
|
||||||
|
if (imageFile.open(name.c_str())) {
|
||||||
|
newSurf = loadFile(imageFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newSurf;
|
||||||
|
}
|
||||||
|
|
||||||
|
Surface *ImageDecoder::loadFile(Common::SeekableReadStream &stream) {
|
||||||
|
// TODO: implement support for bzipped memory
|
||||||
|
|
||||||
|
// FIXME: this is not a very nice solution but it should work
|
||||||
|
// for the moment, we should use a different way to get all
|
||||||
|
// decoders
|
||||||
|
static BMPDecoder bmpDecoder;
|
||||||
|
static ImageDecoder *decoderList[] = {
|
||||||
|
&bmpDecoder, // for uncompressed .BMP files
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
ImageDecoder *decoder = 0;
|
||||||
|
for (int i = 0; decoderList[i] != 0; ++i) {
|
||||||
|
if (decoderList[i]->decodeable(stream)) {
|
||||||
|
decoder = decoderList[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!decoder)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return decoder->decodeImage(stream);
|
||||||
|
}
|
||||||
|
} // end of namespace Graphics
|
61
graphics/imagedec.h
Normal file
61
graphics/imagedec.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/* ScummVM - Scumm Interpreter
|
||||||
|
* Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $Header $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GRAPHICS_IMAGEDEC_H
|
||||||
|
#define GRAPHICS_IMAGEDEC_H
|
||||||
|
|
||||||
|
#include "common/stdafx.h"
|
||||||
|
#include "common/scummsys.h"
|
||||||
|
#include "common/str.h"
|
||||||
|
#include "common/stream.h"
|
||||||
|
|
||||||
|
#include "graphics/surface.h"
|
||||||
|
|
||||||
|
namespace Graphics {
|
||||||
|
class ImageDecoder {
|
||||||
|
public:
|
||||||
|
ImageDecoder() {}
|
||||||
|
virtual ~ImageDecoder() {}
|
||||||
|
|
||||||
|
static Surface *loadFile(const Common::String &name);
|
||||||
|
static Surface *loadFile(Common::SeekableReadStream &stream);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks if the data can be decoded by this decoder
|
||||||
|
*
|
||||||
|
* @param stream memory read stream
|
||||||
|
* @return true if it can be decoded, otherwise false
|
||||||
|
*/
|
||||||
|
virtual bool decodeable(Common::SeekableReadStream &stream) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* decodes the data and returns an pointer to the resulting surface.
|
||||||
|
* Surface::free() must be called by the user also it must be deleted
|
||||||
|
* with delete;
|
||||||
|
*
|
||||||
|
* @param stream the memory stream which should be decoded
|
||||||
|
* @return returns a new surface if the image could be decoded, otherwise 0
|
||||||
|
*/
|
||||||
|
virtual Surface *decodeImage(Common::SeekableReadStream &stream) = 0;
|
||||||
|
};
|
||||||
|
} // end of namespace Graphics
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
146
graphics/imageman.cpp
Normal file
146
graphics/imageman.cpp
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
/* ScummVM - Scumm Interpreter
|
||||||
|
* Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $Header $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "graphics/imagedec.h"
|
||||||
|
#include "graphics/imageman.h"
|
||||||
|
#include "graphics/surface.h"
|
||||||
|
|
||||||
|
DECLARE_SINGLETON(Graphics::ImageManager);
|
||||||
|
|
||||||
|
namespace Graphics {
|
||||||
|
ImageManager::ImageManager() : _surfaces()
|
||||||
|
#ifdef USE_ZLIB
|
||||||
|
, _archives()
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageManager::~ImageManager() {
|
||||||
|
for (Iterator pos = _surfaces.begin(); pos != _surfaces.end(); ++pos) {
|
||||||
|
(*pos)->surface->free();
|
||||||
|
delete (*pos)->surface;
|
||||||
|
delete *pos;
|
||||||
|
*pos = 0;
|
||||||
|
}
|
||||||
|
_surfaces.clear();
|
||||||
|
#ifdef USE_ZLIB
|
||||||
|
for (ZipIterator pos = _archives.begin(); pos != _archives.end(); ++pos) {
|
||||||
|
unzClose(*pos);
|
||||||
|
}
|
||||||
|
_archives.clear();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImageManager::addArchive(const Common::String &name) {
|
||||||
|
#ifdef USE_ZLIB
|
||||||
|
unzFile newFile = unzOpen(name.c_str());
|
||||||
|
if (!newFile)
|
||||||
|
return false;
|
||||||
|
_archives.push_back(newFile);
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImageManager::registerSurface(const Common::String &name, Surface *surf) {
|
||||||
|
if (getSurface(name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry *newHandle = new Entry;
|
||||||
|
if (!newHandle)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!surf) {
|
||||||
|
surf = ImageDecoder::loadFile(name);
|
||||||
|
if (!surf) {
|
||||||
|
#ifdef USE_ZLIB
|
||||||
|
ZipIterator file = _archives.end();
|
||||||
|
for (ZipIterator pos = _archives.begin(); pos != _archives.end(); ++pos) {
|
||||||
|
if (unzLocateFile(*pos, name.c_str(), 2) == UNZ_OK) {
|
||||||
|
file = pos;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file == _archives.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unz_file_info fileInfo;
|
||||||
|
unzOpenCurrentFile(*file);
|
||||||
|
unzGetCurrentFileInfo(*file, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
|
||||||
|
uint8 *buffer = new uint8[fileInfo.uncompressed_size];
|
||||||
|
assert(buffer);
|
||||||
|
unzReadCurrentFile(*file, buffer, fileInfo.uncompressed_size);
|
||||||
|
unzCloseCurrentFile(*file);
|
||||||
|
Common::MemoryReadStream stream(buffer, fileInfo.uncompressed_size);
|
||||||
|
surf = ImageDecoder::loadFile(stream);
|
||||||
|
delete [] buffer;
|
||||||
|
|
||||||
|
if (!surf)
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newHandle->surface = surf;
|
||||||
|
newHandle->name = name;
|
||||||
|
_surfaces.push_back(newHandle);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImageManager::unregisterSurface(const Common::String &name) {
|
||||||
|
Iterator pos = searchHandle(name);
|
||||||
|
if (pos == _surfaces.end()) {
|
||||||
|
// no surface handle it as success
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*pos)->surface->free();
|
||||||
|
delete (*pos)->surface;
|
||||||
|
delete *pos;
|
||||||
|
*pos = 0;
|
||||||
|
|
||||||
|
_surfaces.erase(pos);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Surface * ImageManager::getSurface(const Common::String &name) {
|
||||||
|
Iterator pos = searchHandle(name);
|
||||||
|
if (pos == _surfaces.end()) {
|
||||||
|
// no surface handle it as success
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (*pos)->surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageManager::Iterator ImageManager::searchHandle(const Common::String &name) {
|
||||||
|
Iterator pos = _surfaces.begin();
|
||||||
|
while (pos != _surfaces.end()) {
|
||||||
|
if ((*pos)->name == name)
|
||||||
|
break;
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
} // end of namespace Graphics
|
103
graphics/imageman.h
Normal file
103
graphics/imageman.h
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
/* ScummVM - Scumm Interpreter
|
||||||
|
* Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $Header $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GRAPHICS_IMAGEMAN_H
|
||||||
|
#define GRAPHICS_IMAGEMAN_H
|
||||||
|
|
||||||
|
#include "common/stdafx.h"
|
||||||
|
#include "common/scummsys.h"
|
||||||
|
#include "common/singleton.h"
|
||||||
|
#include "common/str.h"
|
||||||
|
#include "common/list.h"
|
||||||
|
#include "common/unzip.h"
|
||||||
|
|
||||||
|
namespace Graphics {
|
||||||
|
struct Surface;
|
||||||
|
|
||||||
|
class ImageManager : public Common::Singleton<ImageManager> {
|
||||||
|
public:
|
||||||
|
~ImageManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* adds an .zip archive to the pool there the ImagaManager searches
|
||||||
|
* for image files
|
||||||
|
*
|
||||||
|
* @param name the name of the archive
|
||||||
|
* @return true on success and false on failure
|
||||||
|
*/
|
||||||
|
bool addArchive(const Common::String &name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* registers a surface to the ImageManager.
|
||||||
|
* surf->free(), also delete surf, will be called when the ImageManager will
|
||||||
|
* be destroyed or if ImageManager::unregisterSurface is called.
|
||||||
|
* if the parameter 'surf' is 0 the Manger will try to load an image with
|
||||||
|
* the filename 'name'
|
||||||
|
*
|
||||||
|
* @param name the name of the new handle
|
||||||
|
* @param surf the surface which should be associated to the given name
|
||||||
|
* @return returns true on success and false on failure
|
||||||
|
*/
|
||||||
|
bool registerSurface(const Common::String &name, Surface *surf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unregisters a surface, after this the returned surface from
|
||||||
|
* getSurface should NOT be used anymore
|
||||||
|
*
|
||||||
|
* @param name the handle
|
||||||
|
* @return true on success, false on failure
|
||||||
|
*/
|
||||||
|
bool unregisterSurface(const Common::String &name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gets a surface registered to a handle
|
||||||
|
*
|
||||||
|
* @param name the name of the handle
|
||||||
|
* @return returns an pointer to an Surface object or 0 on failure
|
||||||
|
*/
|
||||||
|
Surface *getSurface(const Common::String &name);
|
||||||
|
private:
|
||||||
|
friend class Common::Singleton<SingletonBaseType>;
|
||||||
|
ImageManager();
|
||||||
|
|
||||||
|
struct Entry {
|
||||||
|
Common::String name;
|
||||||
|
Surface *surface;
|
||||||
|
};
|
||||||
|
typedef Common::List<Entry*>::iterator Iterator;
|
||||||
|
#ifdef USE_ZLIB
|
||||||
|
typedef Common::List<unzFile>::iterator ZipIterator;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Iterator searchHandle(const Common::String &name);
|
||||||
|
|
||||||
|
Common::List<Entry*> _surfaces;
|
||||||
|
#ifdef USE_ZLIB
|
||||||
|
Common::List<unzFile> _archives;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end of namespace Graphics
|
||||||
|
|
||||||
|
/** Shortcut for accessing the font manager. */
|
||||||
|
#define ImageMan (Graphics::ImageManager::instance())
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -10,7 +10,9 @@ MODULE_OBJS := \
|
||||||
graphics/newfont_big.o \
|
graphics/newfont_big.o \
|
||||||
graphics/primitives.o \
|
graphics/primitives.o \
|
||||||
graphics/scummfont.o \
|
graphics/scummfont.o \
|
||||||
graphics/surface.o
|
graphics/surface.o \
|
||||||
|
graphics/imageman.o \
|
||||||
|
graphics/imagedec.o
|
||||||
|
|
||||||
MODULE_DIRS += \
|
MODULE_DIRS += \
|
||||||
graphics
|
graphics
|
||||||
|
|
|
@ -59,15 +59,11 @@ void EditTextWidget::handleMouseDown(int x, int y, int button, int clickCount) {
|
||||||
|
|
||||||
|
|
||||||
void EditTextWidget::drawWidget(bool hilite) {
|
void EditTextWidget::drawWidget(bool hilite) {
|
||||||
// Draw a thin frame around us.
|
g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y, _x+_w, _y+_h), _hints, Theme::kWidgetBackgroundBorderSmall);
|
||||||
g_gui.hLine(_x, _y, _x + _w - 1, g_gui._color);
|
|
||||||
g_gui.hLine(_x, _y + _h - 1, _x +_w - 1, g_gui._shadowcolor);
|
|
||||||
g_gui.vLine(_x, _y, _y + _h - 1, g_gui._color);
|
|
||||||
g_gui.vLine(_x + _w - 1, _y, _y + _h - 1, g_gui._shadowcolor);
|
|
||||||
|
|
||||||
// Draw the text
|
// Draw the text
|
||||||
adjustOffset();
|
adjustOffset();
|
||||||
g_gui.drawString(_editString, _x + 2, _y + 2, getEditRect().width(), g_gui._textcolor, kTextAlignLeft, -_editScrollOffset, false);
|
g_gui.theme()->drawText(Common::Rect(_x+2,_y+2, _x+getEditRect().width()-2, _y+_h-2), _editString, Theme::kStateEnabled, Theme::kTextAlignLeft, false, -_editScrollOffset, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Rect EditTextWidget::getEditRect() const {
|
Common::Rect EditTextWidget::getEditRect() const {
|
||||||
|
|
|
@ -37,6 +37,7 @@ ListWidget::ListWidget(GuiObject *boss, int x, int y, int w, int h, WidgetSize w
|
||||||
}
|
}
|
||||||
|
|
||||||
_flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS | WIDGET_WANT_TICKLE;
|
_flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS | WIDGET_WANT_TICKLE;
|
||||||
|
setHints(THEME_HINT_SAVE_BACKGROUND);
|
||||||
_type = kListWidget;
|
_type = kListWidget;
|
||||||
_editMode = false;
|
_editMode = false;
|
||||||
_numberingMode = kListNumberingOne;
|
_numberingMode = kListNumberingOne;
|
||||||
|
@ -297,27 +298,25 @@ void ListWidget::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListWidget::drawWidget(bool hilite) {
|
void ListWidget::drawWidget(bool hilite) {
|
||||||
NewGui *gui = &g_gui;
|
|
||||||
int i, pos, len = _list.size();
|
int i, pos, len = _list.size();
|
||||||
Common::String buffer;
|
Common::String buffer;
|
||||||
int deltax;
|
int deltax;
|
||||||
|
|
||||||
// Draw a thin frame around the list.
|
// Draw a thin frame around the list.
|
||||||
gui->hLine(_x, _y, _x + _w - 1, gui->_color);
|
g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y, _x+_w, _y+_h), _hints, Theme::kWidgetBackgroundBorderSmall);
|
||||||
gui->hLine(_x, _y + _h - 1, _x + _w - 1, gui->_shadowcolor);
|
|
||||||
gui->vLine(_x, _y, _y + _h - 1, gui->_color);
|
|
||||||
|
|
||||||
// Draw the list items
|
// Draw the list items
|
||||||
for (i = 0, pos = _currentPos; i < _entriesPerPage && pos < len; i++, pos++) {
|
for (i = 0, pos = _currentPos; i < _entriesPerPage && pos < len; i++, pos++) {
|
||||||
const OverlayColor textColor = (_selectedItem == pos && _hasFocus) ? gui->_bgcolor : gui->_textcolor;
|
|
||||||
const int y = _y + 2 + kLineHeight * i;
|
const int y = _y + 2 + kLineHeight * i;
|
||||||
|
const int fontHeight = kLineHeight;
|
||||||
|
bool inverted = false;
|
||||||
|
|
||||||
// Draw the selected item inverted, on a highlighted background.
|
// Draw the selected item inverted, on a highlighted background.
|
||||||
if (_selectedItem == pos) {
|
if (_selectedItem == pos) {
|
||||||
if (_hasFocus)
|
if (_hasFocus)
|
||||||
gui->fillRect(_x + 1, _y + 1 + kLineHeight * i, _w - 1, kLineHeight, gui->_textcolorhi);
|
inverted = true;
|
||||||
else
|
else
|
||||||
gui->frameRect(_x + 1, _y + 1 + kLineHeight * i, _w - 1, kLineHeight, gui->_textcolorhi);
|
g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y + 1 + kLineHeight * i, _x+_w-1, y+fontHeight-1), _hints, Theme::kWidgetBackgroundBorderSmall);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If in numbering mode, we first print a number prefix
|
// If in numbering mode, we first print a number prefix
|
||||||
|
@ -325,7 +324,7 @@ void ListWidget::drawWidget(bool hilite) {
|
||||||
char temp[10];
|
char temp[10];
|
||||||
sprintf(temp, "%2d. ", (pos + _numberingMode));
|
sprintf(temp, "%2d. ", (pos + _numberingMode));
|
||||||
buffer = temp;
|
buffer = temp;
|
||||||
gui->drawString(buffer, _x + 2, y, _w - 4, textColor);
|
g_gui.theme()->drawText(Common::Rect(_x+2, y, _x+_w-2, y+fontHeight-1), buffer, Theme::kStateEnabled, Theme::kTextAlignLeft, inverted);
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Rect r(getEditRect());
|
Common::Rect r(getEditRect());
|
||||||
|
@ -335,11 +334,11 @@ void ListWidget::drawWidget(bool hilite) {
|
||||||
adjustOffset();
|
adjustOffset();
|
||||||
deltax = -_editScrollOffset;
|
deltax = -_editScrollOffset;
|
||||||
|
|
||||||
gui->drawString(buffer, _x + r.left, y, r.width(), textColor, kTextAlignLeft, deltax, false);
|
g_gui.theme()->drawText(Common::Rect(_x + r.left - deltax, y, _x+_w-2, y+fontHeight-1), buffer, Theme::kStateEnabled, Theme::kTextAlignLeft, inverted);
|
||||||
} else {
|
} else {
|
||||||
buffer = _list[pos];
|
buffer = _list[pos];
|
||||||
deltax = 0;
|
deltax = 0;
|
||||||
gui->drawString(buffer, _x + r.left, y, r.width(), textColor);
|
g_gui.theme()->drawText(Common::Rect(_x + r.left, y, _x+_w-2, y+fontHeight-1), buffer, Theme::kStateEnabled, Theme::kTextAlignLeft, inverted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,13 +140,10 @@ PopUpDialog::PopUpDialog(PopUpWidget *boss, int clickX, int clickY, WidgetSize w
|
||||||
|
|
||||||
void PopUpDialog::drawDialog() {
|
void PopUpDialog::drawDialog() {
|
||||||
// Draw the menu border
|
// Draw the menu border
|
||||||
g_gui.hLine(_x, _y, _x+_w - 1, g_gui._color);
|
g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y, _x+_w, _y+_h), THEME_HINT_FIRST_DRAW | THEME_HINT_SAVE_BACKGROUND, Theme::kWidgetBackgroundBorderSmall);
|
||||||
g_gui.hLine(_x, _y + _h - 1, _x + _w - 1, g_gui._shadowcolor);
|
|
||||||
g_gui.vLine(_x, _y, _y+_h - 1, g_gui._color);
|
|
||||||
g_gui.vLine(_x + _w - 1, _y, _y + _h - 1, g_gui._shadowcolor);
|
|
||||||
|
|
||||||
if (_twoColumns)
|
/*if (_twoColumns)
|
||||||
g_gui.vLine(_x + _w / 2, _y, _y + _h - 2, g_gui._color);
|
g_gui.vLine(_x + _w / 2, _y, _y + _h - 2, g_gui._color);*/
|
||||||
|
|
||||||
// Draw the entries
|
// Draw the entries
|
||||||
int count = _popUpBoss->_entries.size();
|
int count = _popUpBoss->_entries.size();
|
||||||
|
@ -155,11 +152,9 @@ void PopUpDialog::drawDialog() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The last entry may be empty. Fill it with black.
|
// The last entry may be empty. Fill it with black.
|
||||||
if (_twoColumns && (count & 1)) {
|
/*if (_twoColumns && (count & 1)) {
|
||||||
g_gui.fillRect(_x + 1 + _w / 2, _y + 1 + kLineHeight * (_entriesPerColumn - 1), _w / 2 - 1, kLineHeight, g_gui._bgcolor);
|
g_gui.fillRect(_x + 1 + _w / 2, _y + 1 + kLineHeight * (_entriesPerColumn - 1), _w / 2 - 1, kLineHeight, g_gui._bgcolor);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
g_gui.addDirtyRect(_x, _y, _w, _h);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopUpDialog::handleMouseUp(int x, int y, int button, int clickCount) {
|
void PopUpDialog::handleMouseUp(int x, int y, int button, int clickCount) {
|
||||||
|
@ -322,15 +317,13 @@ void PopUpDialog::drawMenuEntry(int entry, bool hilite) {
|
||||||
|
|
||||||
Common::String &name = _popUpBoss->_entries[entry].name;
|
Common::String &name = _popUpBoss->_entries[entry].name;
|
||||||
|
|
||||||
g_gui.fillRect(x, y, w, kLineHeight, hilite ? g_gui._textcolorhi : g_gui._bgcolor);
|
|
||||||
if (name.size() == 0) {
|
if (name.size() == 0) {
|
||||||
// Draw a separator
|
// Draw a separator
|
||||||
g_gui.hLine(x - 1, y + kLineHeight / 2, x + w, g_gui._shadowcolor);
|
g_gui.theme()->drawLineSeparator(Common::Rect(x, y, x+w, y+kLineHeight));
|
||||||
g_gui.hLine(x, y + 1 + kLineHeight / 2, x + w, g_gui._color);
|
|
||||||
} else {
|
} else {
|
||||||
g_gui.drawString(name, x + 1, y + 2, w - 2, hilite ? g_gui._bgcolor : g_gui._textcolor);
|
g_gui.theme()->drawText(Common::Rect(x+1, y+2, x+w-1, y+kLineHeight), name, hilite ? Theme::kStateHighlight : Theme::kStateEnabled,
|
||||||
|
Theme::kTextAlignLeft);
|
||||||
}
|
}
|
||||||
g_gui.addDirtyRect(x, y, w, kLineHeight);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -343,6 +336,7 @@ void PopUpDialog::drawMenuEntry(int entry, bool hilite) {
|
||||||
PopUpWidget::PopUpWidget(GuiObject *boss, int x, int y, int w, int h, const String &label, uint labelWidth, WidgetSize ws)
|
PopUpWidget::PopUpWidget(GuiObject *boss, int x, int y, int w, int h, const String &label, uint labelWidth, WidgetSize ws)
|
||||||
: Widget(boss, x, y - 1, w, h + 2), CommandSender(boss), _ws(ws), _label(label), _labelWidth(labelWidth) {
|
: Widget(boss, x, y - 1, w, h + 2), CommandSender(boss), _ws(ws), _label(label), _labelWidth(labelWidth) {
|
||||||
_flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS;
|
_flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS;
|
||||||
|
setHints(THEME_HINT_SAVE_BACKGROUND);
|
||||||
_type = kPopUpWidget;
|
_type = kPopUpWidget;
|
||||||
|
|
||||||
_selectedItem = -1;
|
_selectedItem = -1;
|
||||||
|
@ -397,22 +391,19 @@ void PopUpWidget::setSelectedTag(uint32 tag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopUpWidget::drawWidget(bool hilite) {
|
void PopUpWidget::drawWidget(bool hilite) {
|
||||||
NewGui *gui = &g_gui;
|
|
||||||
int x = _x + _labelWidth;
|
int x = _x + _labelWidth;
|
||||||
int w = _w - _labelWidth;
|
int w = _w - _labelWidth;
|
||||||
|
|
||||||
|
// Draw a thin frame around us.
|
||||||
|
g_gui.theme()->drawWidgetBackground(Common::Rect(x, _y, x+w, _y+_h), _hints, Theme::kWidgetBackgroundBorderSmall);
|
||||||
|
|
||||||
// Draw the label, if any
|
// Draw the label, if any
|
||||||
if (_labelWidth > 0)
|
if (_labelWidth > 0)
|
||||||
gui->drawString(_label, _x, _y + 3, _labelWidth, isEnabled() ? gui->_textcolor : gui->_color, kTextAlignRight);
|
g_gui.theme()->drawText(Common::Rect(_x+2,_y+3,_x+_labelWidth, _y+g_gui.theme()->getFontHeight()), _label,
|
||||||
|
isEnabled() ? Theme::kStateEnabled : Theme::kStateDisabled, Theme::kTextAlignRight);
|
||||||
// Draw a thin frame around us.
|
|
||||||
gui->hLine(x, _y, x + w - 1, gui->_color);
|
|
||||||
gui->hLine(x, _y +_h-1, x + w - 1, gui->_shadowcolor);
|
|
||||||
gui->vLine(x, _y, _y+_h-1, gui->_color);
|
|
||||||
gui->vLine(x + w - 1, _y, _y +_h - 1, gui->_shadowcolor);
|
|
||||||
|
|
||||||
// Draw a set of arrows at the right end to signal this is a dropdown/popup
|
// Draw a set of arrows at the right end to signal this is a dropdown/popup
|
||||||
Common::Point p0, p1;
|
/*Common::Point p0, p1;
|
||||||
|
|
||||||
p0 = Common::Point(x + w + 1 - _h / 2, _y + 4);
|
p0 = Common::Point(x + w + 1 - _h / 2, _y + 4);
|
||||||
p1 = Common::Point(x + w + 1 - _h / 2, _y + _h - 4);
|
p1 = Common::Point(x + w + 1 - _h / 2, _y + _h - 4);
|
||||||
|
@ -425,12 +416,13 @@ void PopUpWidget::drawWidget(bool hilite) {
|
||||||
for (; p1.y - p0.y > 1; p0.y++, p0.x--, p1.y--, p1.x++) {
|
for (; p1.y - p0.y > 1; p0.y++, p0.x--, p1.y--, p1.x++) {
|
||||||
surf.drawLine(p0.x, p0.y, p1.x, p0.y, color);
|
surf.drawLine(p0.x, p0.y, p1.x, p0.y, color);
|
||||||
surf.drawLine(p0.x, p1.y, p1.x, p1.y, color);
|
surf.drawLine(p0.x, p1.y, p1.x, p1.y, color);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// Draw the selected entry, if any
|
// Draw the selected entry, if any
|
||||||
if (_selectedItem >= 0) {
|
if (_selectedItem >= 0) {
|
||||||
TextAlignment align = (g_gui.getStringWidth(_entries[_selectedItem].name) > w-6) ? kTextAlignRight : kTextAlignLeft;
|
TextAlignment align = (g_gui.getStringWidth(_entries[_selectedItem].name) > w-6) ? kTextAlignRight : kTextAlignLeft;
|
||||||
gui->drawString(_entries[_selectedItem].name, x+2, _y+3, w-6, !isEnabled() ? gui->_color : gui->_textcolor, align);
|
g_gui.theme()->drawText(Common::Rect(x+2, _y+3, _x+w-6, _y+g_gui.theme()->getFontHeight()), _entries[_selectedItem].name,
|
||||||
|
isEnabled() ? Theme::kStateEnabled : Theme::kStateDisabled, g_gui.theme()->convertAligment(align));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -179,73 +179,22 @@ void ScrollBarWidget::recalc() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScrollBarWidget::drawWidget(bool hilite) {
|
void ScrollBarWidget::drawWidget(bool hilite) {
|
||||||
NewGui *gui = &g_gui;
|
|
||||||
int bottomY = _y + _h - UP_DOWN_BOX_HEIGHT;
|
|
||||||
bool isSinglePage = (_numEntries <= _entriesPerPage);
|
|
||||||
OverlayColor color;
|
|
||||||
Graphics::Surface &surf = g_gui.getScreen();
|
|
||||||
const int B = 3;
|
|
||||||
Common::Point p0, p1, p2;
|
|
||||||
|
|
||||||
gui->frameRect(_x, _y, _w, _h, gui->_shadowcolor);
|
|
||||||
|
|
||||||
if (_draggingPart != kNoPart)
|
if (_draggingPart != kNoPart)
|
||||||
_part = _draggingPart;
|
_part = _draggingPart;
|
||||||
|
|
||||||
const int arrowSize = (_w / 2 - B + 1);
|
Theme::kScrollbarState state = Theme::kScrollbarStateNo;
|
||||||
|
if (_numEntries <= _entriesPerPage) {
|
||||||
//
|
state = Theme::kScrollbarStateSinglePage;
|
||||||
// Up arrow
|
} else if (_part == kUpArrowPart) {
|
||||||
//
|
state = Theme::kScrollbarStateUp;
|
||||||
color = isSinglePage ? gui->_color :
|
} else if (_part == kDownArrowPart) {
|
||||||
(hilite && _part == kUpArrowPart) ? gui->_textcolorhi : gui->_textcolor;
|
state = Theme::kScrollbarStateDown;
|
||||||
gui->frameRect(_x, _y, _w, UP_DOWN_BOX_HEIGHT, gui->_color);
|
} else if (_part == kSliderPart) {
|
||||||
p0 = Common::Point(_x + _w / 2, _y + (UP_DOWN_BOX_HEIGHT - arrowSize - 1) / 2);
|
state = Theme::kScrollbarStateSlider;
|
||||||
p1 = Common::Point(p0.x - arrowSize, p0.y + arrowSize);
|
|
||||||
p2 = Common::Point(p0.x + arrowSize, p0.y + arrowSize);
|
|
||||||
#if 0
|
|
||||||
surf.drawLine(p0.x, p0.y, p1.x, p1.y, color);
|
|
||||||
surf.drawLine(p0.x, p0.y, p2.x, p2.y, color);
|
|
||||||
// surf.drawLine(p1.x, p1.y, p2.x, p2.y, color);
|
|
||||||
#else
|
|
||||||
// Evil HACK to draw filled triangle
|
|
||||||
for (; p1.x <= p2.x; ++p1.x)
|
|
||||||
surf.drawLine(p0.x, p0.y, p1.x, p1.y, color);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
|
||||||
// Down arrow
|
|
||||||
//
|
|
||||||
color = isSinglePage ? gui->_color :
|
|
||||||
(hilite && _part == kDownArrowPart) ? gui->_textcolorhi : gui->_textcolor;
|
|
||||||
gui->frameRect(_x, bottomY, _w, UP_DOWN_BOX_HEIGHT, gui->_color);
|
|
||||||
p0 = Common::Point(_x + _w / 2, bottomY + (UP_DOWN_BOX_HEIGHT + arrowSize + 1) / 2);
|
|
||||||
p1 = Common::Point(p0.x - arrowSize, p0.y - arrowSize);
|
|
||||||
p2 = Common::Point(p0.x + arrowSize, p0.y - arrowSize);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
surf.drawLine(p0.x, p0.y, p1.x, p1.y, color);
|
|
||||||
surf.drawLine(p0.x, p0.y, p2.x, p2.y, color);
|
|
||||||
// surf.drawLine(p1.x, p1.y, p2.x, p2.y, color);
|
|
||||||
#else
|
|
||||||
// Evil HACK to draw filled triangle
|
|
||||||
for (; p1.x <= p2.x; ++p1.x)
|
|
||||||
surf.drawLine(p0.x, p0.y, p1.x, p1.y, color);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
|
||||||
// Slider
|
|
||||||
//
|
|
||||||
if (!isSinglePage) {
|
|
||||||
gui->fillRect(_x, _y + _sliderPos, _w, _sliderHeight,
|
|
||||||
(hilite && _part == kSliderPart) ? gui->_textcolorhi : gui->_textcolor);
|
|
||||||
gui->frameRect(_x, _y + _sliderPos, _w, _sliderHeight, gui->_color);
|
|
||||||
int y = _y + _sliderPos + _sliderHeight / 2;
|
|
||||||
color = (hilite && _part == kSliderPart) ? gui->_color : gui->_shadowcolor;
|
|
||||||
gui->hLine(_x + 2, y - 2, _x + _w - 3, color);
|
|
||||||
gui->hLine(_x + 2, y, _x + _w - 3, color);
|
|
||||||
gui->hLine(_x + 2, y + 2, _x + _w-3, color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_gui.theme()->drawScrollbar(Common::Rect(_x, _y, _x+_w, _y+_h), _sliderPos, _sliderHeight, state,
|
||||||
|
isEnabled() ? (hilite ? Theme::kStateHighlight : Theme::kStateEnabled) : Theme::kStateDisabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace GUI
|
} // End of namespace GUI
|
||||||
|
|
|
@ -127,7 +127,7 @@ bool TabWidget::handleKeyDown(uint16 ascii, int keycode, int modifiers) {
|
||||||
return Widget::handleKeyDown(ascii, keycode, modifiers);
|
return Widget::handleKeyDown(ascii, keycode, modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void box(int x, int y, int width, int height, OverlayColor colorA, OverlayColor colorB, bool omitBottom) {
|
/*static void box(int x, int y, int width, int height, OverlayColor colorA, OverlayColor colorB, bool omitBottom) {
|
||||||
NewGui &gui = g_gui;
|
NewGui &gui = g_gui;
|
||||||
|
|
||||||
gui.hLine(x + 1, y, x + width - 2, colorA);
|
gui.hLine(x + 1, y, x + width - 2, colorA);
|
||||||
|
@ -141,36 +141,18 @@ static void box(int x, int y, int width, int height, OverlayColor colorA, Overla
|
||||||
}
|
}
|
||||||
gui.vLine(x + width - 1, y + 1, y + height - (omitBottom ? 1 : 2), colorB);
|
gui.vLine(x + width - 1, y + 1, y + height - (omitBottom ? 1 : 2), colorB);
|
||||||
gui.vLine(x + width - 2, y + 1, y + height - (omitBottom ? 2 : 1), colorB);
|
gui.vLine(x + width - 2, y + 1, y + height - (omitBottom ? 2 : 1), colorB);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
|
||||||
void TabWidget::drawWidget(bool hilite) {
|
void TabWidget::drawWidget(bool hilite) {
|
||||||
NewGui *gui = &g_gui;
|
|
||||||
|
|
||||||
const int left1 = _x + 1;
|
|
||||||
const int right1 = _x + kTabLeftOffset + _activeTab * (_tabWidth + kTabSpacing);
|
|
||||||
const int left2 = right1 + _tabWidth;
|
|
||||||
const int right2 = _x + _w - 2;
|
|
||||||
|
|
||||||
// Draw horizontal line
|
|
||||||
gui->hLine(left1, _y + _tabHeight - 2, right1, gui->_shadowcolor);
|
|
||||||
gui->hLine(left2, _y + _tabHeight - 2, right2, gui->_shadowcolor);
|
|
||||||
|
|
||||||
// Iterate over all tabs and draw them
|
// Iterate over all tabs and draw them
|
||||||
int i, x = _x + kTabLeftOffset;
|
int i, x = _x + kTabLeftOffset;
|
||||||
for (i = 0; i < (int)_tabs.size(); ++i) {
|
for (i = 0; i < (int)_tabs.size(); ++i) {
|
||||||
OverlayColor color = (i == _activeTab) ? gui->_color : gui->_shadowcolor;
|
|
||||||
int yOffset = (i == _activeTab) ? 0 : 2;
|
int yOffset = (i == _activeTab) ? 0 : 2;
|
||||||
box(x, _y + yOffset, _tabWidth, _tabHeight - yOffset, color, color, (i == _activeTab));
|
g_gui.theme()->drawTab(Common::Rect(x, _y+yOffset, x+_tabWidth, _y+_tabHeight), _tabs[i].title, (i == _activeTab));
|
||||||
gui->drawString(_tabs[i].title, x + kTabPadding, _y + yOffset / 2 + (_tabHeight - gui->getFontHeight() - 3), _tabWidth - 2 * kTabPadding, gui->_textcolor, kTextAlignCenter);
|
|
||||||
x += _tabWidth + kTabSpacing;
|
x += _tabWidth + kTabSpacing;
|
||||||
}
|
}
|
||||||
|
g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y+_tabHeight-2, _x+_w, _y+_h), _hints, Theme::kWidgetBackgroundBorderSmall);
|
||||||
// Draw more horizontal lines
|
|
||||||
gui->hLine(left1, _y + _tabHeight - 1, right1, gui->_color);
|
|
||||||
gui->hLine(left2, _y + _tabHeight - 1, right2, gui->_color);
|
|
||||||
gui->hLine(_x+1, _y + _h - 2, _x + _w - 2, gui->_shadowcolor);
|
|
||||||
gui->hLine(_x+1, _y + _h - 1, _x + _w - 2, gui->_color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget *TabWidget::findWidget(int x, int y) {
|
Widget *TabWidget::findWidget(int x, int y) {
|
||||||
|
|
801
gui/ThemeNew.cpp
Normal file
801
gui/ThemeNew.cpp
Normal file
|
@ -0,0 +1,801 @@
|
||||||
|
/* ScummVM - Scumm Interpreter
|
||||||
|
* Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $Header $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gui/theme.h"
|
||||||
|
|
||||||
|
#include "graphics/imageman.h"
|
||||||
|
#include "graphics/imagedec.h"
|
||||||
|
|
||||||
|
#include "common/config-manager.h"
|
||||||
|
#include "common/file.h"
|
||||||
|
|
||||||
|
#include "common/unzip.h"
|
||||||
|
|
||||||
|
using Graphics::Surface;
|
||||||
|
|
||||||
|
/** Specifies the currently active 16bit pixel format, 555 or 565. */
|
||||||
|
extern int gBitFormat;
|
||||||
|
|
||||||
|
static void getColorFromConfig(const Common::ConfigFile &cfg, const Common::String &value, OverlayColor &color) {
|
||||||
|
Common::String temp;
|
||||||
|
cfg.getKey(value, "colors", temp);
|
||||||
|
int r, g, b;
|
||||||
|
sscanf(temp.c_str(), "%d %d %d", &r, &g, &b);
|
||||||
|
color = OSystem::instance().RGBToColor(r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace GUI {
|
||||||
|
ThemeNew::ThemeNew(OSystem *system, Common::String stylefile) : Theme(), _system(system), _screen(), _initOk(false),
|
||||||
|
_forceRedraw(false), _font(0), _imageHandles(0), _images(0), _colors() {
|
||||||
|
_initOk = false;
|
||||||
|
memset(&_screen, 0, sizeof(_screen));
|
||||||
|
memset(&_dialog, 0, sizeof(_dialog));
|
||||||
|
memset(&_colors, 0, sizeof(_colors));
|
||||||
|
|
||||||
|
_screen.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor));
|
||||||
|
if (_screen.pixels) {
|
||||||
|
_initOk = true;
|
||||||
|
clearAll();
|
||||||
|
if (_screen.w >= 400 && _screen.h >= 300) {
|
||||||
|
_font = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);
|
||||||
|
} else {
|
||||||
|
_font = FontMan.getFontByUsage(Graphics::FontManager::kGUIFont);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConfMan.hasKey("extrapath")) {
|
||||||
|
Common::File::addDefaultDirectory(ConfMan.get("extrapath"));
|
||||||
|
}
|
||||||
|
if (ConfMan.hasKey("themepath")) {
|
||||||
|
Common::File::addDefaultDirectory(ConfMan.get("themepath"));
|
||||||
|
}
|
||||||
|
ImageMan.addArchive(stylefile + ".zip");
|
||||||
|
|
||||||
|
if (!_configFile.loadFromFile(stylefile + ".ini")) {
|
||||||
|
#ifdef USE_ZLIB
|
||||||
|
// Maybe find a nicer solution to this
|
||||||
|
unzFile zipFile = unzOpen((stylefile + ".zip").c_str());
|
||||||
|
if (zipFile == NULL) return;
|
||||||
|
if (unzLocateFile(zipFile, (stylefile + ".ini").c_str(), 2) == UNZ_OK) {
|
||||||
|
unz_file_info fileInfo;
|
||||||
|
unzOpenCurrentFile(zipFile);
|
||||||
|
unzGetCurrentFileInfo(zipFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
|
||||||
|
uint8 *buffer = new uint8[fileInfo.uncompressed_size];
|
||||||
|
assert(buffer);
|
||||||
|
unzReadCurrentFile(zipFile, buffer, fileInfo.uncompressed_size);
|
||||||
|
unzCloseCurrentFile(zipFile);
|
||||||
|
Common::MemoryReadStream stream(buffer, fileInfo.uncompressed_size);
|
||||||
|
if (!_configFile.loadFromStream(stream)) {
|
||||||
|
warning("Can not find theme config file '%s'", (stylefile + ".ini").c_str());
|
||||||
|
unzClose(zipFile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
delete [] buffer;
|
||||||
|
buffer = 0;
|
||||||
|
} else {
|
||||||
|
warning("Can not find theme config file '%s'", (stylefile + ".ini").c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unzClose(zipFile);
|
||||||
|
#else
|
||||||
|
warning("Can not find theme config file '%s'", (stylefile + ".ini").c_str());
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::String temp = "";
|
||||||
|
_configFile.getKey("version", "theme", temp);
|
||||||
|
if (temp != "1") {
|
||||||
|
// TODO: improve this detection and handle it nicer
|
||||||
|
warning("Theme config uses a different version");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Common::String imageHandlesTable[kImageHandlesMax];
|
||||||
|
_configFile.getKey("dialog_corner", "pixmaps", imageHandlesTable[kDialogBkgdCorner]);
|
||||||
|
_configFile.getKey("dialog_top", "pixmaps", imageHandlesTable[kDialogBkgdTop]);
|
||||||
|
_configFile.getKey("dialog_left", "pixmaps", imageHandlesTable[kDialogBkgdLeft]);
|
||||||
|
_configFile.getKey("dialog_bkgd", "pixmaps", imageHandlesTable[kDialogBkgd]);
|
||||||
|
_configFile.getKey("widget_corner", "pixmaps", imageHandlesTable[kWidgetBkgdCorner]);
|
||||||
|
_configFile.getKey("widget_top", "pixmaps", imageHandlesTable[kWidgetBkgdTop]);
|
||||||
|
_configFile.getKey("widget_left", "pixmaps", imageHandlesTable[kWidgetBkgdLeft]);
|
||||||
|
_configFile.getKey("widget_bkgd", "pixmaps", imageHandlesTable[kWidgetBkgd]);
|
||||||
|
_configFile.getKey("checkbox_empty", "pixmaps", imageHandlesTable[kCheckboxEmpty]);
|
||||||
|
_configFile.getKey("checkbox_checked", "pixmaps", imageHandlesTable[kCheckboxChecked]);
|
||||||
|
_configFile.getKey("widget_arrow", "pixmaps", imageHandlesTable[kWidgetArrow]);
|
||||||
|
|
||||||
|
getColorFromConfig(_configFile, "main_dialog_start", _colors[kMainDialogStart]);
|
||||||
|
getColorFromConfig(_configFile, "main_dialog_end", _colors[kMainDialogEnd]);
|
||||||
|
|
||||||
|
getColorFromConfig(_configFile, "dialog_start", _colors[kDialogStart]);
|
||||||
|
getColorFromConfig(_configFile, "dialog_end", _colors[kDialogEnd]);
|
||||||
|
|
||||||
|
getColorFromConfig(_configFile, "color_state_disabled", _colors[kColorStateDisabled]);
|
||||||
|
getColorFromConfig(_configFile, "color_state_highlight", _colors[kColorStateHighlight]);
|
||||||
|
getColorFromConfig(_configFile, "color_state_enabled", _colors[kColorStateEnabled]);
|
||||||
|
getColorFromConfig(_configFile, "color_transparency", _colors[kColorTransparency]);
|
||||||
|
|
||||||
|
getColorFromConfig(_configFile, "text_inverted_background", _colors[kTextInvertedBackground]);
|
||||||
|
getColorFromConfig(_configFile, "text_inverted_color", _colors[kTextInvertedColor]);
|
||||||
|
|
||||||
|
getColorFromConfig(_configFile, "widget_bkgd_start", _colors[kWidgetBackgroundStart]);
|
||||||
|
getColorFromConfig(_configFile, "widget_bkgd_end", _colors[kWidgetBackgroundEnd]);
|
||||||
|
getColorFromConfig(_configFile, "widget_bkgd_small_start", _colors[kWidgetBackgroundSmallStart]);
|
||||||
|
getColorFromConfig(_configFile, "widget_bkgd_small_end", _colors[kWidgetBackgroundSmallEnd]);
|
||||||
|
|
||||||
|
getColorFromConfig(_configFile, "button_bkgd_start", _colors[kButtonBackgroundStart]);
|
||||||
|
getColorFromConfig(_configFile, "button_bkgd_end", _colors[kButtonBackgroundEnd]);
|
||||||
|
getColorFromConfig(_configFile, "button_text_enabled", _colors[kButtonTextEnabled]);
|
||||||
|
getColorFromConfig(_configFile, "button_text_disabled", _colors[kButtonTextDisabled]);
|
||||||
|
getColorFromConfig(_configFile, "button_text_highlight", _colors[kButtonTextHighlight]);
|
||||||
|
|
||||||
|
getColorFromConfig(_configFile, "slider_background_start", _colors[kSliderBackgroundStart]);
|
||||||
|
getColorFromConfig(_configFile, "slider_background_end", _colors[kSliderBackgroundEnd]);
|
||||||
|
getColorFromConfig(_configFile, "slider_start", _colors[kSliderStart]);
|
||||||
|
getColorFromConfig(_configFile, "slider_end", _colors[kSliderEnd]);
|
||||||
|
|
||||||
|
getColorFromConfig(_configFile, "tab_background_start", _colors[kTabBackgroundStart]);
|
||||||
|
getColorFromConfig(_configFile, "tab_background_end", _colors[kTabBackgroundEnd]);
|
||||||
|
|
||||||
|
getColorFromConfig(_configFile, "scrollbar_background_start", _colors[kScrollbarBackgroundStart]);
|
||||||
|
getColorFromConfig(_configFile, "scrollbar_background_end", _colors[kScrollbarBackgroundEnd]);
|
||||||
|
getColorFromConfig(_configFile, "scrollbar_button_start", _colors[kScrollbarButtonStart]);
|
||||||
|
getColorFromConfig(_configFile, "scrollbar_button_end", _colors[kScrollbarButtonEnd]);
|
||||||
|
getColorFromConfig(_configFile, "scrollbar_slider_start", _colors[kScrollbarSliderStart]);
|
||||||
|
getColorFromConfig(_configFile, "scrollbar_slider_end", _colors[kScrollbarSliderEnd]);
|
||||||
|
|
||||||
|
getColorFromConfig(_configFile, "caret_color", _colors[kCaretColor]);
|
||||||
|
|
||||||
|
_imageHandles = imageHandlesTable;
|
||||||
|
|
||||||
|
_images = new const Graphics::Surface*[ARRAYSIZE(imageHandlesTable)];
|
||||||
|
assert(_images);
|
||||||
|
|
||||||
|
for (int i = 0; _imageHandles[i] != "\0"; ++i) {
|
||||||
|
ImageMan.registerSurface(_imageHandles[i], 0);
|
||||||
|
_images[i] = ImageMan.getSurface(_imageHandles[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ThemeNew::~ThemeNew() {
|
||||||
|
deinit();
|
||||||
|
delete [] _images;
|
||||||
|
_images = 0;
|
||||||
|
if (_imageHandles) {
|
||||||
|
for (int i = 0; i < kImageHandlesMax; ++i) {
|
||||||
|
ImageMan.unregisterSurface(_imageHandles[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ThemeNew::init() {
|
||||||
|
if (!_images)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < kImageHandlesMax; ++i) {
|
||||||
|
if (!_images[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit();
|
||||||
|
_screen.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor));
|
||||||
|
if (_screen.pixels) {
|
||||||
|
_initOk = true;
|
||||||
|
clearAll();
|
||||||
|
if (_screen.w >= 400 && _screen.h >= 300) {
|
||||||
|
_font = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);
|
||||||
|
} else {
|
||||||
|
_font = FontMan.getFontByUsage(Graphics::FontManager::kGUIFont);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::deinit() {
|
||||||
|
if (_initOk) {
|
||||||
|
_system->hideOverlay();
|
||||||
|
_screen.free();
|
||||||
|
_initOk = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::refresh() {
|
||||||
|
init();
|
||||||
|
_system->showOverlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::enable() {
|
||||||
|
_system->showOverlay();
|
||||||
|
clearAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::disable() {
|
||||||
|
_system->hideOverlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::openDialog() {
|
||||||
|
if (!_dialog) {
|
||||||
|
_dialog = new DialogState;
|
||||||
|
assert(_dialog);
|
||||||
|
// first dialog
|
||||||
|
_dialog->screen.create(_screen.w, _screen.h, sizeof(OverlayColor));
|
||||||
|
}
|
||||||
|
memcpy(_dialog->screen.pixels, _screen.pixels, _screen.pitch*_screen.h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::closeDialog() {
|
||||||
|
if (_dialog) {
|
||||||
|
_dialog->screen.free();
|
||||||
|
delete _dialog;
|
||||||
|
_dialog = 0;
|
||||||
|
}
|
||||||
|
_forceRedraw = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::clearAll() {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
_system->clearOverlay();
|
||||||
|
// FIXME: problem with the 'pitch'
|
||||||
|
_system->grabOverlay((OverlayColor*)_screen.pixels, _screen.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::drawAll() {
|
||||||
|
// TODO: see ThemeNew::addDirtyRect
|
||||||
|
_forceRedraw = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::resetDrawArea() {
|
||||||
|
if (_initOk) {
|
||||||
|
_drawArea = Common::Rect(0, 0, _screen.w, _screen.h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define surface(x) (_images[x])
|
||||||
|
|
||||||
|
void ThemeNew::drawDialogBackground(const Common::Rect &r, kState state, bool mainDialog) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mainDialog) {
|
||||||
|
colorFade(r, _colors[kMainDialogStart], _colors[kMainDialogEnd]);
|
||||||
|
} else {
|
||||||
|
drawRectMasked(r, surface(kDialogBkgdCorner), surface(kDialogBkgdTop), surface(kDialogBkgdLeft), surface(kDialogBkgd),
|
||||||
|
255, _colors[kDialogStart], _colors[kDialogEnd]);
|
||||||
|
}
|
||||||
|
|
||||||
|
addDirtyRect(r, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::drawText(const Common::Rect &r, const Common::String &str, kState state, kTextAlign align, bool inverted, int deltax, bool useEllipsis) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
Common::Rect r2(r.left, r.top, r.right, r.top+_font->getFontHeight());
|
||||||
|
|
||||||
|
restoreBackground(r2);
|
||||||
|
|
||||||
|
if (inverted) {
|
||||||
|
_screen.fillRect(r, _colors[kTextInvertedBackground]);
|
||||||
|
_font->drawString(&_screen, str, r.left, r.top, r.width(), _colors[kTextInvertedColor], convertAligment(align), deltax, useEllipsis);
|
||||||
|
addDirtyRect(r2);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
_font->drawString(&_screen, str, r.left, r.top, r.width(), getColor(state), convertAligment(align), deltax, useEllipsis);
|
||||||
|
}
|
||||||
|
|
||||||
|
addDirtyRect(r2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
restoreBackground(r);
|
||||||
|
font->drawChar(&_screen, ch, r.left, r.top, getColor(state));
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::drawWidgetBackground(const Common::Rect &r, uint16 hints, kWidgetBackground background, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((hints & THEME_HINT_SAVE_BACKGROUND) && !(hints & THEME_HINT_FIRST_DRAW) && !_forceRedraw) {
|
||||||
|
restoreBackground(r);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (background == kWidgetBackgroundBorderSmall) {
|
||||||
|
drawRectMasked(r, surface(kDialogBkgdCorner), surface(kDialogBkgdTop), surface(kDialogBkgdLeft), surface(kDialogBkgd),
|
||||||
|
(state == kStateDisabled) ? 128 : 256, _colors[kWidgetBackgroundSmallStart], _colors[kWidgetBackgroundSmallEnd]);
|
||||||
|
} else {
|
||||||
|
drawRectMasked(r, surface(kWidgetBkgdCorner), surface(kWidgetBkgdTop), surface(kWidgetBkgdLeft), surface(kWidgetBkgd),
|
||||||
|
(state == kStateDisabled) ? 128 : 256, _colors[kWidgetBackgroundStart], _colors[kWidgetBackgroundEnd], 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
addDirtyRect(r, (hints & THEME_HINT_SAVE_BACKGROUND));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::drawButton(const Common::Rect &r, const Common::String &str, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
|
||||||
|
drawRectMasked(r, surface(kWidgetBkgdCorner), surface(kWidgetBkgdTop), surface(kWidgetBkgdLeft), surface(kWidgetBkgd),
|
||||||
|
255, _colors[kButtonBackgroundStart], _colors[kButtonBackgroundEnd], 2);
|
||||||
|
|
||||||
|
const int off = (r.height() - _font->getFontHeight()) / 2;
|
||||||
|
|
||||||
|
OverlayColor col = 0;
|
||||||
|
switch (state) {
|
||||||
|
case kStateEnabled:
|
||||||
|
col = _colors[kButtonTextEnabled];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kStateHighlight:
|
||||||
|
col = _colors[kButtonTextHighlight];
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
col = _colors[kButtonTextDisabled];
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
_font->drawString(&_screen, str, r.left, r.top + off, r.width(), col, Graphics::kTextAlignCenter, 0, true);
|
||||||
|
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::drawSurface(const Common::Rect &r, const Graphics::Surface &surface, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
Common::Rect rect(r.left, r.top, r.left + surface.w, r.top + surface.h);
|
||||||
|
rect.clip(_screen.w, _screen.h);
|
||||||
|
|
||||||
|
if (!rect.isValidRect())
|
||||||
|
return;
|
||||||
|
|
||||||
|
assert(surface.bytesPerPixel == sizeof(OverlayColor));
|
||||||
|
|
||||||
|
OverlayColor *src = (OverlayColor *)surface.pixels;
|
||||||
|
OverlayColor *dst = (OverlayColor *)_screen.getBasePtr(rect.left, rect.top);
|
||||||
|
|
||||||
|
int w = rect.width();
|
||||||
|
int h = rect.height();
|
||||||
|
|
||||||
|
while (h--) {
|
||||||
|
memcpy(dst, src, surface.pitch);
|
||||||
|
src += w;
|
||||||
|
// FIXME: this should be pitch
|
||||||
|
dst += _screen.w;
|
||||||
|
}
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::drawSlider(const Common::Rect &r, int width, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
|
||||||
|
drawRectMasked(r, surface(kDialogBkgdCorner), surface(kDialogBkgdTop), surface(kDialogBkgdLeft), surface(kDialogBkgd), 255,
|
||||||
|
_colors[kSliderBackgroundStart], _colors[kSliderBackgroundEnd]);
|
||||||
|
|
||||||
|
Common::Rect r2 = r;
|
||||||
|
r2.left = r.left + 2;
|
||||||
|
r2.top = r.top + 2;
|
||||||
|
r2.bottom = r.bottom - 2;
|
||||||
|
r2.right = r2.left + width;
|
||||||
|
if (r2.right > r.right - 2) {
|
||||||
|
r2.right = r.right - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawRectMasked(r2, surface(kWidgetBkgdCorner), surface(kWidgetBkgdTop), surface(kWidgetBkgdLeft), surface(kWidgetBkgd),
|
||||||
|
(state == kStateDisabled) ? 128 : 256, _colors[kSliderStart], _colors[kSliderEnd], 2);
|
||||||
|
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::drawCheckbox(const Common::Rect &r, const Common::String &str, bool checked, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
Common::Rect r2 = r;
|
||||||
|
|
||||||
|
const Graphics::Surface *checkBox = surface(checked ? kCheckboxChecked : kCheckboxEmpty);
|
||||||
|
int checkBoxSize = checkBox->w;
|
||||||
|
|
||||||
|
drawSurface(Common::Rect(r.left, r.top, r.left+checkBox->w, r.top+checkBox->h), checkBox, false, false, (state == kStateDisabled) ? 128 : 256);
|
||||||
|
r2.left += checkBoxSize + 5;
|
||||||
|
_font->drawString(&_screen, str, r2.left, r2.top, r2.width(), getColor(state), Graphics::kTextAlignCenter, 0, false);
|
||||||
|
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::drawTab(const Common::Rect &r, const Common::String &str, bool active, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
if (active) {
|
||||||
|
_font->drawString(&_screen, str, r.left, r.top+2, r.width(), getColor(kStateHighlight), Graphics::kTextAlignCenter, 0, true);
|
||||||
|
} else {
|
||||||
|
drawRectMasked(r, surface(kWidgetBkgdCorner), surface(kWidgetBkgdTop), surface(kWidgetBkgdLeft), surface(kWidgetBkgd),
|
||||||
|
(state == kStateDisabled) ? 128 : 256, _colors[kTabBackgroundStart], _colors[kTabBackgroundEnd], 2);
|
||||||
|
_font->drawString(&_screen, str, r.left, r.top+2, r.width(), getColor(state), Graphics::kTextAlignCenter, 0, true);
|
||||||
|
}
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::drawScrollbar(const Common::Rect &r, int sliderY, int sliderHeight, kScrollbarState, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
const int UP_DOWN_BOX_HEIGHT = r.width() + 1;
|
||||||
|
Common::Rect r2 = r;
|
||||||
|
|
||||||
|
// draws the scrollbar background
|
||||||
|
drawRectMasked(r2, surface(kDialogBkgdCorner), surface(kDialogBkgdTop), surface(kDialogBkgdLeft), surface(kDialogBkgd), 255,
|
||||||
|
_colors[kScrollbarBackgroundStart], _colors[kScrollbarBackgroundEnd]);
|
||||||
|
|
||||||
|
// draws the 'up' button
|
||||||
|
r2.bottom = r2.top + UP_DOWN_BOX_HEIGHT;
|
||||||
|
drawRectMasked(r2, surface(kDialogBkgdCorner), surface(kDialogBkgdTop), surface(kDialogBkgdLeft), surface(kDialogBkgd), 255,
|
||||||
|
_colors[kScrollbarButtonStart], _colors[kScrollbarButtonEnd]);
|
||||||
|
|
||||||
|
const Graphics::Surface *arrow = surface(kWidgetArrow);
|
||||||
|
r2.left += 1 + (r2.width() - arrow->w) / 2;
|
||||||
|
r2.right = r2.left + arrow->w;
|
||||||
|
r2.top += (r2.height() - arrow->h) / 2;
|
||||||
|
r2.bottom = r2.top + arrow->h;
|
||||||
|
drawSurface(r2, arrow, false, false, 255);
|
||||||
|
|
||||||
|
// draws the slider
|
||||||
|
r2 = r;
|
||||||
|
r2.left += 2;
|
||||||
|
r2.right -= 2;
|
||||||
|
r2.top += sliderY;
|
||||||
|
r2.bottom = r2.top + sliderHeight / 2 + surface(kWidgetBkgdCorner)->h + 4;
|
||||||
|
drawRectMasked(r2, surface(kWidgetBkgdCorner), surface(kWidgetBkgdTop), surface(kWidgetBkgdLeft), surface(kWidgetBkgd), 255,
|
||||||
|
_colors[kScrollbarSliderStart], _colors[kScrollbarSliderEnd]);
|
||||||
|
r2.top += sliderHeight / 2;
|
||||||
|
r2.bottom += sliderHeight / 2 - surface(kWidgetBkgdCorner)->h - 4;
|
||||||
|
drawRectMasked(r2, surface(kWidgetBkgdCorner), surface(kWidgetBkgdTop), surface(kWidgetBkgdLeft), surface(kWidgetBkgd), 255,
|
||||||
|
_colors[kScrollbarSliderEnd], _colors[kScrollbarSliderStart]);
|
||||||
|
|
||||||
|
// draws the 'down' button
|
||||||
|
r2 = r;
|
||||||
|
r2.top = r2.bottom - UP_DOWN_BOX_HEIGHT;
|
||||||
|
drawRectMasked(r2, surface(kDialogBkgdCorner), surface(kDialogBkgdTop), surface(kDialogBkgdLeft), surface(kDialogBkgd), 255,
|
||||||
|
_colors[kScrollbarButtonStart], _colors[kScrollbarButtonEnd]);
|
||||||
|
|
||||||
|
r2.left += 1 + (r2.width() - arrow->w) / 2;
|
||||||
|
r2.right = r2.left + arrow->w;
|
||||||
|
r2.top += (r2.height() - arrow->h) / 2;
|
||||||
|
r2.bottom = r2.top + arrow->h;
|
||||||
|
drawSurface(r2, arrow, true, false, 255);
|
||||||
|
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::drawCaret(const Common::Rect &r, bool erase, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
|
||||||
|
restoreBackground(Common::Rect(r.left, r.top, r.left+1, r.bottom));
|
||||||
|
if (!erase) {
|
||||||
|
_screen.vLine(r.left, r.top, r.bottom, _colors[kCaretColor]);
|
||||||
|
} else {
|
||||||
|
// FIXME: hack to restore the caret background correctly
|
||||||
|
const OverlayColor search = _colors[kTextInvertedBackground];
|
||||||
|
const OverlayColor *src = (const OverlayColor*)_screen.getBasePtr(r.left-1, r.top-1);
|
||||||
|
int height = r.height() + 2;
|
||||||
|
if (r.top + height > _screen.h) {
|
||||||
|
height = _screen.h - r.top;
|
||||||
|
}
|
||||||
|
bool drawInvBackground = false;
|
||||||
|
while (height--) {
|
||||||
|
if (src[0] == search || src[1] == search || src[2] == search) {
|
||||||
|
drawInvBackground = true;
|
||||||
|
}
|
||||||
|
src += _screen.w;
|
||||||
|
}
|
||||||
|
if (drawInvBackground) {
|
||||||
|
_screen.vLine(r.left, r.top, r.bottom, search);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::drawLineSeparator(const Common::Rect &r, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
_screen.hLine(r.left - 1, r.top + r.height() / 2, r.right, _system->RGBToColor(0, 0, 0));
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - intern drawing
|
||||||
|
|
||||||
|
void ThemeNew::restoreBackground(Common::Rect r) {
|
||||||
|
r.clip(_screen.w, _screen.h);
|
||||||
|
r.clip(_drawArea);
|
||||||
|
if (_dialog) {
|
||||||
|
if (!_dialog->screen.pixels) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const OverlayColor *src = (const OverlayColor*)_dialog->screen.getBasePtr(r.left, r.top);
|
||||||
|
OverlayColor *dst = (OverlayColor*)_screen.getBasePtr(r.left, r.top);
|
||||||
|
|
||||||
|
int h = r.height();
|
||||||
|
int w = r.width();
|
||||||
|
while (h--) {
|
||||||
|
memcpy(dst, src, w*sizeof(OverlayColor));
|
||||||
|
src += _dialog->screen.w;
|
||||||
|
dst += _screen.w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ThemeNew::addDirtyRect(Common::Rect r, bool backup) {
|
||||||
|
// TODO: implement proper dirty rect handling
|
||||||
|
// FIXME: problem with the 'pitch'
|
||||||
|
r.clip(_screen.w, _screen.h);
|
||||||
|
r.clip(_drawArea);
|
||||||
|
_system->copyRectToOverlay((OverlayColor*)_screen.getBasePtr(r.left, r.top), _screen.w, r.left, r.top, r.width(), r.height());
|
||||||
|
if (_dialog && backup) {
|
||||||
|
if (_dialog->screen.pixels) {
|
||||||
|
OverlayColor *dst = (OverlayColor*)_dialog->screen.getBasePtr(r.left, r.top);
|
||||||
|
const OverlayColor *src = (const OverlayColor*)_screen.getBasePtr(r.left, r.top);
|
||||||
|
int h = r.height();
|
||||||
|
while (h--) {
|
||||||
|
memcpy(dst, src, r.width()*sizeof(OverlayColor));
|
||||||
|
dst += _dialog->screen.w;
|
||||||
|
src += _screen.w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint8 calcColor(uint8 start, uint8 end, int pos, int max) {
|
||||||
|
int diff = ((int)end - (int)start) * pos / max;
|
||||||
|
return start + diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
OverlayColor calcColor(OverlayColor start, OverlayColor end, int pos, int max, uint factor = 1) {
|
||||||
|
pos *= factor;
|
||||||
|
if (pos > max) {
|
||||||
|
pos = max;
|
||||||
|
}
|
||||||
|
OverlayColor result = 0;
|
||||||
|
uint8 sr = 0, sg = 0, sb = 0;
|
||||||
|
uint8 er = 0, eg = 0, eb = 0;
|
||||||
|
if (gBitFormat == 565) {
|
||||||
|
sr = (start >> 11) & 0x1F;
|
||||||
|
sg = (start >> 5) & 0x3F;
|
||||||
|
sb = (start >> 0) & 0x1F;
|
||||||
|
|
||||||
|
er = (end >> 11) & 0x1F;
|
||||||
|
eg = (end >> 5) & 0x3F;
|
||||||
|
eb = (end >> 0) & 0x1F;
|
||||||
|
} else {
|
||||||
|
sr = (start >> 10) & 0x1F;
|
||||||
|
sg = (start >> 5) & 0x1F;
|
||||||
|
sb = (start >> 0) & 0x1F;
|
||||||
|
|
||||||
|
er = (end >> 10) & 0x1F;
|
||||||
|
eg = (end >> 5) & 0x1F;
|
||||||
|
eb = (end >> 0) & 0x1F;
|
||||||
|
}
|
||||||
|
uint8 cr = calcColor(sr, er, pos, max);
|
||||||
|
uint8 cg = calcColor(sg, eg, pos, max);
|
||||||
|
uint8 cb = calcColor(sb, eb, pos, max);
|
||||||
|
if (gBitFormat == 565) {
|
||||||
|
result = ((int)(cr & 0x1F) << 11) | ((int)(cg & 0x3F) << 5) | (int)(cb & 0x1F);
|
||||||
|
} else {
|
||||||
|
result = ((int)(cr & 0x1F) << 10) | ((int)(cg & 0x1F) << 5) | (int)(cb & 0x1F);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::colorFade(const Common::Rect &r, OverlayColor start, OverlayColor end) {
|
||||||
|
OverlayColor *ptr = (OverlayColor*)_screen.getBasePtr(r.left, r.top);
|
||||||
|
int h = r.height();
|
||||||
|
while (h--) {
|
||||||
|
OverlayColor col = calcColor(start, end, r.height()-h, r.height());
|
||||||
|
for (int i = 0; i < r.width(); ++i) {
|
||||||
|
ptr[i] = col;
|
||||||
|
}
|
||||||
|
ptr += _screen.w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::drawRect(const Common::Rect &r, const Surface *corner, const Surface *top, const Surface *left, const Surface *fill, int alpha) {
|
||||||
|
// top left
|
||||||
|
drawRectMasked(r, corner, top, left, fill, alpha, _system->RGBToColor(255, 255, 255), _system->RGBToColor(255, 255, 255));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::drawRectMasked(const Common::Rect &r, const Graphics::Surface *corner, const Graphics::Surface *top,
|
||||||
|
const Graphics::Surface *left, const Graphics::Surface *fill, int alpha,
|
||||||
|
OverlayColor start, OverlayColor end, uint factor) {
|
||||||
|
int drawWidth = MIN(corner->w, MIN(top->w, MIN(left->w, fill->w)));
|
||||||
|
int drawHeight = MIN(corner->h, MIN(top->h, MIN(left->h, fill->h)));
|
||||||
|
int partsH = r.height() / drawHeight;
|
||||||
|
int partsW = r.width() / drawWidth;
|
||||||
|
int yPos = r.top;
|
||||||
|
|
||||||
|
int specialHeight = 0;
|
||||||
|
int specialWidth = 0;
|
||||||
|
|
||||||
|
if (drawHeight*2 > r.height()) {
|
||||||
|
drawHeight = r.height() / 2;
|
||||||
|
partsH = 2;
|
||||||
|
} else {
|
||||||
|
specialHeight = r.height() % drawHeight;
|
||||||
|
if (specialHeight != 0)
|
||||||
|
++partsH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drawWidth*2 > r.width()) {
|
||||||
|
drawWidth = r.width() / 2;
|
||||||
|
partsW = 2;
|
||||||
|
} else {
|
||||||
|
specialWidth = r.width() % drawWidth;
|
||||||
|
if (specialWidth != 0)
|
||||||
|
++partsW;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < partsH; ++y) {
|
||||||
|
int xPos = r.left;
|
||||||
|
bool upDown = false;
|
||||||
|
if (y == partsH - 1)
|
||||||
|
upDown = true;
|
||||||
|
|
||||||
|
// calculate the correct drawing height
|
||||||
|
int usedHeight = drawHeight;
|
||||||
|
if (specialHeight && y == 1) {
|
||||||
|
usedHeight = specialHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
OverlayColor startCol = calcColor(start, end, yPos-r.top, r.height(), factor);
|
||||||
|
OverlayColor endCol = calcColor(start, end, yPos-r.top+usedHeight, r.height(), factor);
|
||||||
|
|
||||||
|
for (int i = 0; i < partsW; ++i) {
|
||||||
|
|
||||||
|
// calculate the correct drawing width
|
||||||
|
int usedWidth = drawWidth;
|
||||||
|
if (specialWidth && i == 1) {
|
||||||
|
usedWidth = specialWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the right surface
|
||||||
|
if (!i) {
|
||||||
|
if (!y || y == partsH - 1) {
|
||||||
|
drawSurfaceMasked(Common::Rect(xPos, yPos, xPos+usedWidth, yPos+usedHeight), corner, upDown, false, alpha, startCol, endCol);
|
||||||
|
} else {
|
||||||
|
drawSurfaceMasked(Common::Rect(xPos, yPos, xPos+usedWidth, yPos+usedHeight), left, upDown, false, alpha, startCol, endCol);
|
||||||
|
}
|
||||||
|
} else if (i == partsW - 1) {
|
||||||
|
if (!y || y == partsH - 1) {
|
||||||
|
drawSurfaceMasked(Common::Rect(xPos, yPos, xPos+usedWidth, yPos+usedHeight), corner, upDown, true, alpha, startCol, endCol);
|
||||||
|
} else {
|
||||||
|
drawSurfaceMasked(Common::Rect(xPos, yPos, xPos+usedWidth, yPos+usedHeight), left, upDown, true, alpha, startCol, endCol);
|
||||||
|
}
|
||||||
|
} else if (!y || y == partsH - 1) {
|
||||||
|
drawSurfaceMasked(Common::Rect(xPos, yPos, xPos+usedWidth, yPos+usedHeight), top, upDown, false, alpha, startCol, endCol);
|
||||||
|
} else {
|
||||||
|
drawSurfaceMasked(Common::Rect(xPos, yPos, xPos+usedWidth, yPos+usedHeight), fill, upDown, false, alpha, startCol, endCol);
|
||||||
|
}
|
||||||
|
xPos += usedWidth;
|
||||||
|
}
|
||||||
|
yPos += usedHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::drawSurface(const Common::Rect &r, const Surface *surf, bool upDown, bool leftRight, int alpha) {
|
||||||
|
drawSurfaceMasked(r, surf, upDown, leftRight, alpha, _system->RGBToColor(255, 255, 255), _system->RGBToColor(255, 255, 255));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline OverlayColor getColorAlpha(OverlayColor col1, OverlayColor col2, int alpha) {
|
||||||
|
if (alpha == 256) {
|
||||||
|
return col1;
|
||||||
|
}
|
||||||
|
uint8 r1, g1, b1;
|
||||||
|
uint8 r2, g2, b2;
|
||||||
|
OSystem::instance().colorToRGB(col1, r1, g1, b1);
|
||||||
|
OSystem::instance().colorToRGB(col2, r2, g2, b2);
|
||||||
|
uint8 r, g, b;
|
||||||
|
r = (alpha * (r1 - r2) >> 8) + r2;
|
||||||
|
g = (alpha * (g1 - g2) >> 8) + g2;
|
||||||
|
b = (alpha * (b1 - b2) >> 8) + b2;
|
||||||
|
return OSystem::instance().RGBToColor(r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeNew::drawSurfaceMasked(const Common::Rect &r, const Graphics::Surface *surf, bool upDown, bool leftRight,
|
||||||
|
int alpha, OverlayColor start, OverlayColor end, uint factor) {
|
||||||
|
OverlayColor *dst = (OverlayColor*)_screen.getBasePtr(r.left, r.top);
|
||||||
|
const OverlayColor *src = 0;
|
||||||
|
|
||||||
|
const OverlayColor transparency = _colors[kColorTransparency];
|
||||||
|
|
||||||
|
if (upDown && !leftRight) { // upsidedown
|
||||||
|
src = (const OverlayColor*)surf->pixels + (surf->h - 1) * surf->w;
|
||||||
|
int drawWidth = (r.width() < surf->w) ? r.width() : surf->w;
|
||||||
|
for (int i = 0; i < r.height(); ++i) {
|
||||||
|
OverlayColor rowColor = calcColor(start, end, i, r.height(), factor);
|
||||||
|
for (int x = 0; x < drawWidth; ++x) {
|
||||||
|
if (src[x] != transparency && dst >= _screen.pixels) {
|
||||||
|
dst[x] = getColorAlpha(src[x], dst[x], alpha) & rowColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst += _screen.w;
|
||||||
|
src -= surf->w;
|
||||||
|
}
|
||||||
|
} else if (upDown && leftRight) { // upsidedown + left right inverse
|
||||||
|
src = (const OverlayColor*)surf->pixels + (surf->h - 1) * surf->w;
|
||||||
|
int drawWidth = (r.width() < surf->w) ? r.width() : surf->w;
|
||||||
|
for (int i = 0; i < r.height(); ++i) {
|
||||||
|
OverlayColor rowColor = calcColor(start, end, i, r.height(), factor);
|
||||||
|
for (int x = 0; x < drawWidth; ++x) {
|
||||||
|
if (src[drawWidth-x-1] != transparency && dst >= _screen.pixels) {
|
||||||
|
dst[x] = getColorAlpha(src[drawWidth-x-1], dst[x], alpha) & rowColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst += _screen.w;
|
||||||
|
src -= surf->w;
|
||||||
|
}
|
||||||
|
} else if (!upDown && leftRight) { // left right inverse
|
||||||
|
src = (const OverlayColor*)surf->pixels;
|
||||||
|
int drawWidth = (r.width() < surf->w) ? r.width() : surf->w;
|
||||||
|
for (int i = 0; i < r.height(); ++i) {
|
||||||
|
OverlayColor rowColor = calcColor(start, end, i, r.height(), factor);
|
||||||
|
for (int x = 0; x < drawWidth; ++x) {
|
||||||
|
if (src[drawWidth-x-1] != transparency && dst >= _screen.pixels) {
|
||||||
|
dst[x] = getColorAlpha(src[drawWidth-x-1], dst[x], alpha) & rowColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst += _screen.w;
|
||||||
|
src += surf->w;
|
||||||
|
}
|
||||||
|
} else { // normal
|
||||||
|
src = (const OverlayColor*)surf->pixels;
|
||||||
|
int drawWidth = (r.width() < surf->w) ? r.width() : surf->w;
|
||||||
|
for (int i = 0; i < r.height(); ++i) {
|
||||||
|
OverlayColor rowColor = calcColor(start, end, i, r.height(), factor);
|
||||||
|
for (int x = 0; x < drawWidth; ++x) {
|
||||||
|
if (src[x] != transparency && dst >= _screen.pixels) {
|
||||||
|
dst[x] = getColorAlpha(src[x], dst[x], alpha) & rowColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst += _screen.w;
|
||||||
|
src += surf->w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OverlayColor ThemeNew::getColor(kState state) {
|
||||||
|
switch (state) {
|
||||||
|
case kStateDisabled:
|
||||||
|
return _colors[kColorStateDisabled];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kStateHighlight:
|
||||||
|
return _colors[kColorStateHighlight];
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
return _colors[kColorStateEnabled];
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end of namespace GUI
|
|
@ -73,7 +73,6 @@ static const char *credits_intro[] = {
|
||||||
|
|
||||||
#include "gui/credits.h"
|
#include "gui/credits.h"
|
||||||
|
|
||||||
|
|
||||||
AboutDialog::AboutDialog()
|
AboutDialog::AboutDialog()
|
||||||
: Dialog(10, 20, 300, 174),
|
: Dialog(10, 20, 300, 174),
|
||||||
_scrollPos(0), _scrollTime(0), _modifiers(0), _willClose(false) {
|
_scrollPos(0), _scrollTime(0), _modifiers(0), _willClose(false) {
|
||||||
|
@ -111,7 +110,6 @@ AboutDialog::AboutDialog()
|
||||||
}
|
}
|
||||||
_w += 2*xOff;
|
_w += 2*xOff;
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < 1; i++)
|
for (i = 0; i < 1; i++)
|
||||||
_lines.push_back("");
|
_lines.push_back("");
|
||||||
|
|
||||||
|
@ -166,7 +164,7 @@ void AboutDialog::addLine(const char *str) {
|
||||||
_lines.push_back(format);
|
_lines.push_back(format);
|
||||||
} else {
|
} else {
|
||||||
Common::StringList wrappedLines;
|
Common::StringList wrappedLines;
|
||||||
g_gui.getFont().wordWrapText(str, _w - 2*xOff, wrappedLines);
|
g_gui.getFont().wordWrapText(str, _w - 2 * xOff, wrappedLines);
|
||||||
|
|
||||||
for (Common::StringList::const_iterator i = wrappedLines.begin(); i != wrappedLines.end(); ++i) {
|
for (Common::StringList::const_iterator i = wrappedLines.begin(); i != wrappedLines.end(); ++i) {
|
||||||
_lines.push_back(format + *i);
|
_lines.push_back(format + *i);
|
||||||
|
@ -180,27 +178,17 @@ void AboutDialog::open() {
|
||||||
_scrollPos = 0;
|
_scrollPos = 0;
|
||||||
_modifiers = 0;
|
_modifiers = 0;
|
||||||
_willClose = false;
|
_willClose = false;
|
||||||
_canvas.pixels = NULL;
|
|
||||||
|
|
||||||
Dialog::open();
|
Dialog::open();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AboutDialog::close() {
|
void AboutDialog::close() {
|
||||||
free(_canvas.pixels);
|
|
||||||
Dialog::close();
|
Dialog::close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AboutDialog::drawDialog() {
|
void AboutDialog::drawDialog() {
|
||||||
if (!_canvas.pixels) {
|
g_gui.theme()->setDrawArea(Common::Rect(_x, _y, _x+_w, _y+_h));
|
||||||
// Blend over the background. Since we can't afford to do that
|
Dialog::drawDialog();
|
||||||
// every time the text is updated (it's horribly CPU intensive)
|
|
||||||
// we do it just once and then use a copy of the result as our
|
|
||||||
// static background for the remainder of the credits.
|
|
||||||
g_gui.blendRect(_x, _y, _w, _h, g_gui._bgcolor);
|
|
||||||
g_gui.copyToSurface(&_canvas, _x, _y, _w, _h);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_gui.drawSurface(_canvas, _x, _y);
|
|
||||||
|
|
||||||
// Draw text
|
// Draw text
|
||||||
// TODO: Add a "fade" effect for the top/bottom text lines
|
// TODO: Add a "fade" effect for the top/bottom text lines
|
||||||
|
@ -213,35 +201,37 @@ void AboutDialog::drawDialog() {
|
||||||
|
|
||||||
for (int line = firstLine; line < lastLine; line++) {
|
for (int line = firstLine; line < lastLine; line++) {
|
||||||
const char *str = _lines[line].c_str();
|
const char *str = _lines[line].c_str();
|
||||||
Graphics::TextAlignment align = Graphics::kTextAlignCenter;
|
Theme::kTextAlign align = Theme::kTextAlignCenter;
|
||||||
OverlayColor color = g_gui._textcolor;
|
Theme::kState state = Theme::kStateEnabled;
|
||||||
while (str[0] == '\\') {
|
while (str[0] == '\\') {
|
||||||
switch (str[1]) {
|
switch (str[1]) {
|
||||||
case 'C':
|
case 'C':
|
||||||
align = Graphics::kTextAlignCenter;
|
align = Theme::kTextAlignCenter;
|
||||||
break;
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
align = Graphics::kTextAlignLeft;
|
align = Theme::kTextAlignLeft;
|
||||||
break;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
align = Graphics::kTextAlignRight;
|
align = Theme::kTextAlignRight;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
switch (str[2]) {
|
switch (str[2]) {
|
||||||
case '0':
|
case '0':
|
||||||
color = g_gui._textcolor;
|
state = Theme::kStateEnabled;
|
||||||
break;
|
break;
|
||||||
case '1':
|
case '1':
|
||||||
color = g_gui._textcolorhi;
|
state = Theme::kStateHighlight;
|
||||||
break;
|
break;
|
||||||
case '2':
|
case '2':
|
||||||
color = g_gui._color;
|
state = Theme::kStateDisabled;
|
||||||
break;
|
break;
|
||||||
case '3':
|
case '3':
|
||||||
color = g_gui._shadowcolor;
|
warning("Need state for color 3");
|
||||||
|
// color = g_gui._shadowcolor;
|
||||||
break;
|
break;
|
||||||
case '4':
|
case '4':
|
||||||
color = g_gui._bgcolor;
|
warning("Need state for color 4");
|
||||||
|
// color = g_gui._bgcolor;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error("Unknown color type '%c'", str[2]);
|
error("Unknown color type '%c'", str[2]);
|
||||||
|
@ -255,31 +245,17 @@ void AboutDialog::drawDialog() {
|
||||||
str += 2;
|
str += 2;
|
||||||
}
|
}
|
||||||
// Trim leading whitespaces if center mode is on
|
// Trim leading whitespaces if center mode is on
|
||||||
if (align == Graphics::kTextAlignCenter)
|
if (align == Theme::kTextAlignCenter)
|
||||||
while (*str && *str == ' ')
|
while (*str && *str == ' ')
|
||||||
str++;
|
str++;
|
||||||
|
|
||||||
g_gui.drawString(str, _x + xOff, y, _w - 2 * xOff, color, align, 0, false);
|
g_gui.theme()->drawText(Common::Rect(_x + xOff, y, _x + _w - xOff, y + g_gui.theme()->getFontHeight() + 4), str, state, align, false, 0, false);
|
||||||
y += _lineHeight;
|
y += _lineHeight;
|
||||||
}
|
}
|
||||||
|
g_gui.theme()->resetDrawArea();
|
||||||
// Draw a border
|
|
||||||
g_gui.box(_x, _y, _w, _h, g_gui._color, g_gui._shadowcolor);
|
|
||||||
|
|
||||||
// Finally blit it all to the screen
|
|
||||||
g_gui.addDirtyRect(_x, _y, _w, _h);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AboutDialog::handleTickle() {
|
void AboutDialog::handleTickle() {
|
||||||
// We're in the process of doing a full redraw to re-create the
|
|
||||||
// background image for the text. That means we need to wait for the
|
|
||||||
// GUI itself to clear the overlay and call drawDialog() in all of the
|
|
||||||
// dialogs, otherwise we'll only redraw this one and it'll still have
|
|
||||||
// the remains of the old image, including the text that was on it.
|
|
||||||
if (!_canvas.pixels)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const uint32 t = getMillis();
|
const uint32 t = getMillis();
|
||||||
int scrollOffset = ((int)t - (int)_scrollTime) / kScrollMillisPerPixel;
|
int scrollOffset = ((int)t - (int)_scrollTime) / kScrollMillisPerPixel;
|
||||||
if (scrollOffset > 0) {
|
if (scrollOffset > 0) {
|
||||||
|
@ -302,16 +278,6 @@ void AboutDialog::handleTickle() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AboutDialog::handleScreenChanged() {
|
|
||||||
// The screen has changed. That means the overlay colors in the canvas
|
|
||||||
// may no longer be correct. Reset it, and issue a full redraw.
|
|
||||||
// TODO: We could check if the bit format has changed, like we do in
|
|
||||||
// the MPEG player.
|
|
||||||
free(_canvas.pixels);
|
|
||||||
_canvas.pixels = NULL;
|
|
||||||
draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AboutDialog::handleMouseUp(int x, int y, int button, int clickCount) {
|
void AboutDialog::handleMouseUp(int x, int y, int button, int clickCount) {
|
||||||
// Close upon any mouse click
|
// Close upon any mouse click
|
||||||
close();
|
close();
|
||||||
|
@ -329,5 +295,4 @@ void AboutDialog::handleKeyUp(uint16 ascii, int keycode, int modifiers) {
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // End of namespace GUI
|
} // End of namespace GUI
|
||||||
|
|
|
@ -36,7 +36,6 @@ protected:
|
||||||
uint32 _lineHeight;
|
uint32 _lineHeight;
|
||||||
byte _modifiers;
|
byte _modifiers;
|
||||||
bool _willClose;
|
bool _willClose;
|
||||||
Graphics::Surface _canvas;
|
|
||||||
|
|
||||||
int xOff, yOff;
|
int xOff, yOff;
|
||||||
|
|
||||||
|
@ -49,7 +48,6 @@ public:
|
||||||
void close();
|
void close();
|
||||||
void drawDialog();
|
void drawDialog();
|
||||||
void handleTickle();
|
void handleTickle();
|
||||||
void handleScreenChanged();
|
|
||||||
void handleMouseUp(int x, int y, int button, int clickCount);
|
void handleMouseUp(int x, int y, int button, int clickCount);
|
||||||
void handleKeyDown(uint16 ascii, int keycode, int modifiers);
|
void handleKeyDown(uint16 ascii, int keycode, int modifiers);
|
||||||
void handleKeyUp(uint16 ascii, int keycode, int modifiers);
|
void handleKeyUp(uint16 ascii, int keycode, int modifiers);
|
||||||
|
|
|
@ -114,10 +114,7 @@ void ConsoleDialog::slideUpAndClose() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleDialog::open() {
|
void ConsoleDialog::open() {
|
||||||
// This dialog will be redrawn a lot, so we store a copy of the blended
|
// TODO: find a new way to do this
|
||||||
// background in a separate "canvas", just like in the About dialog.
|
|
||||||
_canvas.pixels = NULL;
|
|
||||||
|
|
||||||
// Initiate sliding the console down. We do a very simple trick to achieve
|
// Initiate sliding the console down. We do a very simple trick to achieve
|
||||||
// this effect: we simply move the console dialog just above (outside) the
|
// this effect: we simply move the console dialog just above (outside) the
|
||||||
// visible screen area, then shift it down in handleTickle() over a
|
// visible screen area, then shift it down in handleTickle() over a
|
||||||
|
@ -135,36 +132,16 @@ void ConsoleDialog::open() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleDialog::close() {
|
void ConsoleDialog::close() {
|
||||||
free(_canvas.pixels);
|
|
||||||
Dialog::close();
|
Dialog::close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleDialog::drawDialog() {
|
void ConsoleDialog::drawDialog() {
|
||||||
if (!_canvas.pixels) {
|
|
||||||
// Blend over the background. Don't count the time used for
|
|
||||||
// this when timing the slide action.
|
|
||||||
|
|
||||||
uint32 now = g_system->getMillis();
|
|
||||||
uint32 delta;
|
|
||||||
|
|
||||||
g_gui.blendRect(0, 0, _w, _h, g_gui._bgcolor, 2);
|
|
||||||
g_gui.copyToSurface(&_canvas, 0, 0, _w, _h);
|
|
||||||
|
|
||||||
delta = g_system->getMillis() - now;
|
|
||||||
|
|
||||||
if (_slideTime)
|
|
||||||
_slideTime += delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_gui.drawSurface(_canvas, 0, 0);
|
|
||||||
|
|
||||||
// Draw a border
|
|
||||||
g_gui.hLine(_x, _y + _h - 1, _x + _w - 1, g_gui._color);
|
|
||||||
|
|
||||||
// Draw text
|
// Draw text
|
||||||
int start = _scrollLine - _linesPerPage + 1;
|
int start = _scrollLine - _linesPerPage + 1;
|
||||||
int y = _y + 2;
|
int y = _y + 2;
|
||||||
|
|
||||||
|
g_gui.theme()->drawDialogBackground(Common::Rect(_x, _y, _x+_w, _y+_h));
|
||||||
|
|
||||||
for (int line = 0; line < _linesPerPage; line++) {
|
for (int line = 0; line < _linesPerPage; line++) {
|
||||||
int x = _x + 1;
|
int x = _x + 1;
|
||||||
for (int column = 0; column < _lineWidth; column++) {
|
for (int column = 0; column < _lineWidth; column++) {
|
||||||
|
@ -174,7 +151,7 @@ void ConsoleDialog::drawDialog() {
|
||||||
#else
|
#else
|
||||||
byte c = buffer((start + line) * _lineWidth + column);
|
byte c = buffer((start + line) * _lineWidth + column);
|
||||||
#endif
|
#endif
|
||||||
g_gui.drawChar(c, x, y, g_gui._textcolor, _font);
|
g_gui.theme()->drawChar(Common::Rect(x, y, x+kConsoleCharWidth, y+kConsoleLineHeight), c, _font);
|
||||||
x += kConsoleCharWidth;
|
x += kConsoleCharWidth;
|
||||||
}
|
}
|
||||||
y += kConsoleLineHeight;
|
y += kConsoleLineHeight;
|
||||||
|
@ -182,21 +159,14 @@ void ConsoleDialog::drawDialog() {
|
||||||
|
|
||||||
// Draw the scrollbar
|
// Draw the scrollbar
|
||||||
_scrollBar->draw();
|
_scrollBar->draw();
|
||||||
|
|
||||||
// Finally blit it all to the screen
|
|
||||||
g_gui.addDirtyRect(_x, _y, _w, _h);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleDialog::handleScreenChanged() {
|
void ConsoleDialog::handleScreenChanged() {
|
||||||
free(_canvas.pixels);
|
Dialog::handleScreenChanged();
|
||||||
_canvas.pixels = NULL;
|
|
||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleDialog::handleTickle() {
|
void ConsoleDialog::handleTickle() {
|
||||||
if (!_canvas.pixels)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint32 time = g_system->getMillis();
|
uint32 time = g_system->getMillis();
|
||||||
if (_caretTime < time) {
|
if (_caretTime < time) {
|
||||||
_caretTime = time + kCaretBlinkTime;
|
_caretTime = time + kCaretBlinkTime;
|
||||||
|
@ -219,7 +189,7 @@ void ConsoleDialog::handleTickle() {
|
||||||
draw();
|
draw();
|
||||||
} else if (_slideMode == kUpSlideMode && _y <= -_h) {
|
} else if (_slideMode == kUpSlideMode && _y <= -_h) {
|
||||||
// End the slide
|
// End the slide
|
||||||
_slideMode = kNoSlideMode;
|
//_slideMode = kNoSlideMode;
|
||||||
close();
|
close();
|
||||||
} else
|
} else
|
||||||
draw();
|
draw();
|
||||||
|
@ -614,6 +584,7 @@ void ConsoleDialog::print(const char *str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleDialog::drawCaret(bool erase) {
|
void ConsoleDialog::drawCaret(bool erase) {
|
||||||
|
// TODO: use code from EditableWidget::drawCaret here
|
||||||
int line = _currentPos / _lineWidth;
|
int line = _currentPos / _lineWidth;
|
||||||
int displayLine = line - _scrollLine + _linesPerPage - 1;
|
int displayLine = line - _scrollLine + _linesPerPage - 1;
|
||||||
|
|
||||||
|
@ -626,17 +597,8 @@ void ConsoleDialog::drawCaret(bool erase) {
|
||||||
int x = _x + 1 + (_currentPos % _lineWidth) * kConsoleCharWidth;
|
int x = _x + 1 + (_currentPos % _lineWidth) * kConsoleCharWidth;
|
||||||
int y = _y + displayLine * kConsoleLineHeight;
|
int y = _y + displayLine * kConsoleLineHeight;
|
||||||
|
|
||||||
char c = buffer(_currentPos);
|
|
||||||
if (erase) {
|
|
||||||
g_gui.fillRect(x, y, kConsoleCharWidth, kConsoleLineHeight, g_gui._bgcolor);
|
|
||||||
g_gui.drawChar(c, x, y + 2, g_gui._textcolor, _font);
|
|
||||||
} else {
|
|
||||||
g_gui.fillRect(x, y, kConsoleCharWidth, kConsoleLineHeight, g_gui._textcolor);
|
|
||||||
g_gui.drawChar(c, x, y + 2, g_gui._bgcolor, _font);
|
|
||||||
}
|
|
||||||
g_gui.addDirtyRect(x, y, kConsoleCharWidth, kConsoleLineHeight);
|
|
||||||
|
|
||||||
_caretVisible = !erase;
|
_caretVisible = !erase;
|
||||||
|
g_gui.theme()->drawCaret(Common::Rect(x, y, x+kConsoleCharWidth, y+kConsoleLineHeight), erase);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleDialog::scrollToCurrent() {
|
void ConsoleDialog::scrollToCurrent() {
|
||||||
|
|
|
@ -43,7 +43,6 @@ public:
|
||||||
typedef bool (*CompletionCallbackProc)(ConsoleDialog* console, const char *input, char*& completion, void *refCon);
|
typedef bool (*CompletionCallbackProc)(ConsoleDialog* console, const char *input, char*& completion, void *refCon);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Graphics::Surface _canvas;
|
|
||||||
const Graphics::Font *_font;
|
const Graphics::Font *_font;
|
||||||
|
|
||||||
char _buffer[kBufferSize];
|
char _buffer[kBufferSize];
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace GUI {
|
||||||
|
|
||||||
Dialog::Dialog(int x, int y, int w, int h)
|
Dialog::Dialog(int x, int y, int w, int h)
|
||||||
: GuiObject(x, y, w, h),
|
: GuiObject(x, y, w, h),
|
||||||
_mouseWidget(0), _focusedWidget(0), _dragWidget(0), _visible(false) {
|
_mouseWidget(0), _focusedWidget(0), _dragWidget(0), _visible(false), _mainDialog(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Dialog::~Dialog() {
|
Dialog::~Dialog() {
|
||||||
|
@ -88,6 +88,18 @@ void Dialog::close() {
|
||||||
releaseFocus();
|
releaseFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Dialog::handleScreenChanged() {
|
||||||
|
// The screen has changed. That means the screen visual may also have
|
||||||
|
// changed, so any cached image may be invalid. The subsequent redraw
|
||||||
|
// should be treated as the very first draw.
|
||||||
|
|
||||||
|
Widget *w = _firstWidget;
|
||||||
|
while (w) {
|
||||||
|
w->setHints(THEME_HINT_FIRST_DRAW);
|
||||||
|
w = w->_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Dialog::releaseFocus() {
|
void Dialog::releaseFocus() {
|
||||||
if (_focusedWidget) {
|
if (_focusedWidget) {
|
||||||
_focusedWidget->lostFocus();
|
_focusedWidget->lostFocus();
|
||||||
|
@ -104,8 +116,7 @@ void Dialog::drawDialog() {
|
||||||
if (!isVisible())
|
if (!isVisible())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_gui.blendRect(_x, _y, _w, _h, g_gui._bgcolor);
|
g_gui.theme()->drawDialogBackground(Common::Rect(_x, _y, _x+_w, _y+_h), Theme::kStateEnabled, _mainDialog);
|
||||||
g_gui.box(_x, _y, _w, _h, g_gui._color, g_gui._shadowcolor);
|
|
||||||
|
|
||||||
// Draw all children
|
// Draw all children
|
||||||
Widget *w = _firstWidget;
|
Widget *w = _firstWidget;
|
||||||
|
@ -113,9 +124,6 @@ void Dialog::drawDialog() {
|
||||||
w->draw();
|
w->draw();
|
||||||
w = w->_next;
|
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) {
|
void Dialog::handleMouseDown(int x, int y, int button, int clickCount) {
|
||||||
|
|
|
@ -44,6 +44,7 @@ protected:
|
||||||
Widget *_focusedWidget;
|
Widget *_focusedWidget;
|
||||||
Widget *_dragWidget;
|
Widget *_dragWidget;
|
||||||
bool _visible;
|
bool _visible;
|
||||||
|
bool _mainDialog; // FIXME: find a better solution for this and change the Theme class to handle it then
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _result;
|
int _result;
|
||||||
|
@ -73,7 +74,7 @@ protected:
|
||||||
virtual void handleKeyUp(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 handleMouseMoved(int x, int y, int button);
|
||||||
virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
|
virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
|
||||||
virtual void handleScreenChanged() {}
|
void handleScreenChanged();
|
||||||
|
|
||||||
Widget *findWidget(int x, int y); // Find the widget at pos x,y if any
|
Widget *findWidget(int x, int y); // Find the widget at pos x,y if any
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,6 @@ void EditableWidget::drawCaret(bool erase) {
|
||||||
|
|
||||||
Common::Rect editRect = getEditRect();
|
Common::Rect editRect = getEditRect();
|
||||||
|
|
||||||
int16 color = (erase ^ _caretInverse) ? g_gui._bgcolor : g_gui._textcolorhi;
|
|
||||||
int x = editRect.left;
|
int x = editRect.left;
|
||||||
int y = editRect.top + 1;
|
int y = editRect.top + 1;
|
||||||
|
|
||||||
|
@ -155,9 +154,8 @@ void EditableWidget::drawCaret(bool erase) {
|
||||||
x += getAbsX();
|
x += getAbsX();
|
||||||
y += getAbsY();
|
y += getAbsY();
|
||||||
|
|
||||||
g_gui.vLine(x, y, y + editRect.height() - 2, color);
|
g_gui.theme()->drawCaret(Common::Rect(x, y, x+editRect.width(), y+editRect.height()-2), erase);
|
||||||
g_gui.addDirtyRect(x, y, 2, editRect.height() - 2);
|
|
||||||
|
|
||||||
_caretVisible = !erase;
|
_caretVisible = !erase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -490,6 +490,7 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
|
||||||
|
|
||||||
LauncherDialog::LauncherDialog(GameDetector &detector)
|
LauncherDialog::LauncherDialog(GameDetector &detector)
|
||||||
: Dialog(0, 0, 320, 200), _detector(detector) {
|
: Dialog(0, 0, 320, 200), _detector(detector) {
|
||||||
|
_mainDialog = true;
|
||||||
|
|
||||||
const int screenW = g_system->getOverlayWidth();
|
const int screenW = g_system->getOverlayWidth();
|
||||||
const int screenH = g_system->getOverlayHeight();
|
const int screenH = g_system->getOverlayHeight();
|
||||||
|
|
|
@ -16,7 +16,9 @@ MODULE_OBJS := \
|
||||||
gui/PopUpWidget.o \
|
gui/PopUpWidget.o \
|
||||||
gui/ScrollBarWidget.o \
|
gui/ScrollBarWidget.o \
|
||||||
gui/TabWidget.o \
|
gui/TabWidget.o \
|
||||||
gui/widget.o
|
gui/widget.o \
|
||||||
|
gui/theme.o \
|
||||||
|
gui/ThemeNew.o
|
||||||
|
|
||||||
MODULE_DIRS += \
|
MODULE_DIRS += \
|
||||||
gui
|
gui
|
||||||
|
|
285
gui/newgui.cpp
285
gui/newgui.cpp
|
@ -24,6 +24,8 @@
|
||||||
#include "gui/newgui.h"
|
#include "gui/newgui.h"
|
||||||
#include "gui/dialog.h"
|
#include "gui/dialog.h"
|
||||||
|
|
||||||
|
#include "common/config-manager.h"
|
||||||
|
|
||||||
DECLARE_SINGLETON(GUI::NewGui);
|
DECLARE_SINGLETON(GUI::NewGui);
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
@ -55,7 +57,7 @@ enum {
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
NewGui::NewGui() : _needRedraw(false),
|
NewGui::NewGui() : _needRedraw(false),
|
||||||
_stateIsSaved(false), _font(0), _cursorAnimateCounter(0), _cursorAnimateTimer(0) {
|
_stateIsSaved(false), _cursorAnimateCounter(0), _cursorAnimateTimer(0) {
|
||||||
|
|
||||||
_system = &OSystem::instance();
|
_system = &OSystem::instance();
|
||||||
|
|
||||||
|
@ -65,32 +67,26 @@ NewGui::NewGui() : _needRedraw(false),
|
||||||
// Reset key repeat
|
// Reset key repeat
|
||||||
_currentKeyDown.keycode = 0;
|
_currentKeyDown.keycode = 0;
|
||||||
|
|
||||||
// updates the scaling factor
|
ConfMan.registerDefault("gui_theme", "default-theme");
|
||||||
updateScaleFactor();
|
Common::String style = ConfMan.get("gui_theme");
|
||||||
}
|
if (scumm_stricmp(style.c_str(), "classic") == 0) {
|
||||||
|
_theme = new ThemeClassic(_system);
|
||||||
void NewGui::updateColors() {
|
|
||||||
// Setup some default GUI colors.
|
|
||||||
_bgcolor = _system->RGBToColor(0, 0, 0);
|
|
||||||
_color = _system->RGBToColor(104, 104, 104);
|
|
||||||
_shadowcolor = _system->RGBToColor(64, 64, 64);
|
|
||||||
_textcolor = _system->RGBToColor(32, 160, 32);
|
|
||||||
_textcolorhi = _system->RGBToColor(0, 255, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NewGui::updateScaleFactor() {
|
|
||||||
const int screenW = g_system->getOverlayWidth();
|
|
||||||
const int screenH = g_system->getOverlayHeight();
|
|
||||||
|
|
||||||
// TODO: Perhaps we should also set the widget size here. That'd allow
|
|
||||||
// us to remove much of the screen size checking from the individual
|
|
||||||
// widgets.
|
|
||||||
|
|
||||||
if (screenW >= 400 && screenH >= 300) {
|
|
||||||
_font = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);
|
|
||||||
} else {
|
} else {
|
||||||
_font = FontMan.getFontByUsage(Graphics::FontManager::kGUIFont);
|
_theme = new ThemeNew(_system, style.c_str());
|
||||||
}
|
}
|
||||||
|
assert(_theme);
|
||||||
|
|
||||||
|
// Init the theme
|
||||||
|
if (!_theme->init()) {
|
||||||
|
warning("Could not initialize your preferred theme, falling back to classic style");
|
||||||
|
delete _theme;
|
||||||
|
_theme = new ThemeClassic(_system);
|
||||||
|
assert(_theme);
|
||||||
|
if (!_theme->init()) {
|
||||||
|
error("Couldn't initialize classic theme");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_theme->resetDrawArea();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewGui::runLoop() {
|
void NewGui::runLoop() {
|
||||||
|
@ -101,36 +97,34 @@ void NewGui::runLoop() {
|
||||||
if (activeDialog == 0)
|
if (activeDialog == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Setup some default GUI colors. Normally this will be done whenever an
|
|
||||||
// EVENT_SCREEN_CHANGED is received. However, not yet all backends support
|
|
||||||
// that event, so we also do it "manually" whenever a run loop is entered.
|
|
||||||
updateColors();
|
|
||||||
updateScaleFactor();
|
|
||||||
|
|
||||||
if (!_stateIsSaved) {
|
if (!_stateIsSaved) {
|
||||||
saveState();
|
saveState();
|
||||||
|
_theme->enable();
|
||||||
didSaveState = true;
|
didSaveState = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_theme->openDialog();
|
||||||
|
|
||||||
while (!_dialogStack.empty() && activeDialog == _dialogStack.top()) {
|
while (!_dialogStack.empty() && activeDialog == _dialogStack.top()) {
|
||||||
activeDialog->handleTickle();
|
activeDialog->handleTickle();
|
||||||
|
|
||||||
if (_needRedraw) {
|
if (_needRedraw) {
|
||||||
// Restore the overlay to its initial state, then draw all dialogs.
|
// Restore the overlay to its initial state, then draw all dialogs.
|
||||||
// This is necessary to get the blending right.
|
// This is necessary to get the blending right.
|
||||||
_system->clearOverlay();
|
_theme->clearAll();
|
||||||
_system->grabOverlay((OverlayColor *)_screen.pixels, _screenPitch);
|
|
||||||
|
|
||||||
|
for (int i = 0; i < _dialogStack.size(); ++i) {
|
||||||
|
_theme->closeDialog();
|
||||||
|
}
|
||||||
for (int i = 0; i < _dialogStack.size(); i++) {
|
for (int i = 0; i < _dialogStack.size(); i++) {
|
||||||
// For each dialog we draw we have to ensure the correct
|
_theme->openDialog();
|
||||||
// scaling mode is active.
|
|
||||||
updateScaleFactor();
|
|
||||||
_dialogStack[i]->drawDialog();
|
_dialogStack[i]->drawDialog();
|
||||||
}
|
}
|
||||||
_needRedraw = false;
|
_needRedraw = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
animateCursor();
|
animateCursor();
|
||||||
|
_theme->drawAll();
|
||||||
_system->updateScreen();
|
_system->updateScreen();
|
||||||
|
|
||||||
OSystem::Event event;
|
OSystem::Event event;
|
||||||
|
@ -191,8 +185,9 @@ void NewGui::runLoop() {
|
||||||
_system->quit();
|
_system->quit();
|
||||||
return;
|
return;
|
||||||
case OSystem::EVENT_SCREEN_CHANGED:
|
case OSystem::EVENT_SCREEN_CHANGED:
|
||||||
updateColors();
|
// reinit the whole theme
|
||||||
updateScaleFactor();
|
_theme->refresh();
|
||||||
|
_needRedraw = true;
|
||||||
activeDialog->handleScreenChanged();
|
activeDialog->handleScreenChanged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -211,8 +206,12 @@ void NewGui::runLoop() {
|
||||||
_system->delayMillis(10);
|
_system->delayMillis(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (didSaveState)
|
_theme->closeDialog();
|
||||||
|
|
||||||
|
if (didSaveState) {
|
||||||
restoreState();
|
restoreState();
|
||||||
|
_theme->disable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
@ -221,20 +220,6 @@ void NewGui::saveState() {
|
||||||
// Backup old cursor
|
// Backup old cursor
|
||||||
_oldCursorMode = _system->showMouse(true);
|
_oldCursorMode = _system->showMouse(true);
|
||||||
|
|
||||||
// Enable the overlay
|
|
||||||
_system->showOverlay();
|
|
||||||
|
|
||||||
// Create a screen buffer for the overlay data, and fill it with
|
|
||||||
// whatever is visible on the screen rught now.
|
|
||||||
_screen.h = _system->getOverlayHeight();
|
|
||||||
_screen.w = _system->getOverlayWidth();
|
|
||||||
_screen.bytesPerPixel = sizeof(OverlayColor);
|
|
||||||
_screen.pitch = _screen.w * _screen.bytesPerPixel;
|
|
||||||
_screenPitch = _screen.w;
|
|
||||||
_screen.pixels = (OverlayColor*)calloc(_screen.w * _screen.h, sizeof(OverlayColor));
|
|
||||||
|
|
||||||
_system->grabOverlay((OverlayColor *)_screen.pixels, _screenPitch);
|
|
||||||
|
|
||||||
_currentKeyDown.keycode = 0;
|
_currentKeyDown.keycode = 0;
|
||||||
_lastClick.x = _lastClick.y = 0;
|
_lastClick.x = _lastClick.y = 0;
|
||||||
_lastClick.time = 0;
|
_lastClick.time = 0;
|
||||||
|
@ -246,12 +231,6 @@ void NewGui::saveState() {
|
||||||
void NewGui::restoreState() {
|
void NewGui::restoreState() {
|
||||||
_system->showMouse(_oldCursorMode);
|
_system->showMouse(_oldCursorMode);
|
||||||
|
|
||||||
_system->hideOverlay();
|
|
||||||
if (_screen.pixels) {
|
|
||||||
free(_screen.pixels);
|
|
||||||
_screen.pixels = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_system->updateScreen();
|
_system->updateScreen();
|
||||||
|
|
||||||
_stateIsSaved = false;
|
_stateIsSaved = false;
|
||||||
|
@ -272,194 +251,6 @@ void NewGui::closeTopDialog() {
|
||||||
_needRedraw = true;
|
_needRedraw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark -
|
|
||||||
|
|
||||||
const Graphics::Font &NewGui::getFont() const {
|
|
||||||
return *_font;
|
|
||||||
}
|
|
||||||
|
|
||||||
OverlayColor *NewGui::getBasePtr(int x, int y) {
|
|
||||||
return (OverlayColor *)_screen.getBasePtr(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NewGui::box(int x, int y, int width, int height, OverlayColor colorA, OverlayColor colorB) {
|
|
||||||
hLine(x + 1, y, x + width - 2, colorA);
|
|
||||||
hLine(x, y + 1, x + width - 1, colorA);
|
|
||||||
vLine(x, y + 1, y + height - 2, colorA);
|
|
||||||
vLine(x + 1, y, y + height - 1, colorA);
|
|
||||||
|
|
||||||
hLine(x + 1, y + height - 2, x + width - 1, colorB);
|
|
||||||
hLine(x + 1, y + height - 1, x + width - 2, colorB);
|
|
||||||
vLine(x + width - 1, y + 1, y + height - 2, colorB);
|
|
||||||
vLine(x + width - 2, y + 1, y + height - 1, colorB);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NewGui::hLine(int x, int y, int x2, OverlayColor color) {
|
|
||||||
_screen.hLine(x, y, x2, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NewGui::vLine(int x, int y, int y2, OverlayColor color) {
|
|
||||||
_screen.vLine(x, y, y2, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NewGui::copyToSurface(Graphics::Surface *s, int x, int y, int w, int h) {
|
|
||||||
Common::Rect rect(x, y, x + w, y + h);
|
|
||||||
rect.clip(_screen.w, _screen.h);
|
|
||||||
|
|
||||||
if (!rect.isValidRect())
|
|
||||||
return;
|
|
||||||
|
|
||||||
s->w = rect.width();
|
|
||||||
s->h = rect.height();
|
|
||||||
s->bytesPerPixel = sizeof(OverlayColor);
|
|
||||||
s->pitch = s->w * s->bytesPerPixel;
|
|
||||||
s->pixels = (OverlayColor *)malloc(s->pitch * s->h);
|
|
||||||
|
|
||||||
w = s->w;
|
|
||||||
h = s->h;
|
|
||||||
|
|
||||||
OverlayColor *dst = (OverlayColor *)s->pixels;
|
|
||||||
OverlayColor *src = getBasePtr(rect.left, rect.top);
|
|
||||||
|
|
||||||
while (h--) {
|
|
||||||
memcpy(dst, src, s->pitch);
|
|
||||||
src += _screenPitch;
|
|
||||||
dst += s->w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NewGui::drawSurface(const Graphics::Surface &s, int x, int y) {
|
|
||||||
Common::Rect rect(x, y, x + s.w, y + s.h);
|
|
||||||
rect.clip(_screen.w, _screen.h);
|
|
||||||
|
|
||||||
if (!rect.isValidRect())
|
|
||||||
return;
|
|
||||||
|
|
||||||
assert(s.bytesPerPixel == sizeof(OverlayColor));
|
|
||||||
|
|
||||||
OverlayColor *src = (OverlayColor *)s.pixels;
|
|
||||||
OverlayColor *dst = getBasePtr(rect.left, rect.top);
|
|
||||||
|
|
||||||
int w = rect.width();
|
|
||||||
int h = rect.height();
|
|
||||||
|
|
||||||
while (h--) {
|
|
||||||
memcpy(dst, src, s.pitch);
|
|
||||||
src += w;
|
|
||||||
dst += _screenPitch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NewGui::blendRect(int x, int y, int w, int h, OverlayColor color, int level) {
|
|
||||||
#ifdef NEWGUI_256
|
|
||||||
fillRect(x, y, w, h, color);
|
|
||||||
#else
|
|
||||||
Common::Rect rect(x, y, x + w, y + h);
|
|
||||||
rect.clip(_screen.w, _screen.h);
|
|
||||||
|
|
||||||
if (!rect.isValidRect())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (_system->hasFeature(OSystem::kFeatureOverlaySupportsAlpha)) {
|
|
||||||
|
|
||||||
int a, r, g, b;
|
|
||||||
uint8 aa, ar, ag, ab;
|
|
||||||
_system->colorToARGB(color, aa, ar, ag, ab);
|
|
||||||
a = aa*level/(level+1);
|
|
||||||
if (a < 1)
|
|
||||||
return;
|
|
||||||
r = ar * a;
|
|
||||||
g = ag * a;
|
|
||||||
b = ab * a;
|
|
||||||
|
|
||||||
OverlayColor *ptr = getBasePtr(rect.left, rect.top);
|
|
||||||
|
|
||||||
h = rect.height();
|
|
||||||
w = rect.width();
|
|
||||||
while (h--) {
|
|
||||||
for (int i = 0; i < w; i++) {
|
|
||||||
_system->colorToARGB(ptr[i], aa, ar, ag, ab);
|
|
||||||
int a2 = aa + a - (a*aa)/255;
|
|
||||||
ptr[i] = _system->ARGBToColor(a2,
|
|
||||||
((255-a)*aa*ar/255+r)/a2,
|
|
||||||
((255-a)*aa*ag/255+g)/a2,
|
|
||||||
((255-a)*aa*ab/255+b)/a2);
|
|
||||||
}
|
|
||||||
ptr += _screenPitch;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
int r, g, b;
|
|
||||||
uint8 ar, ag, ab;
|
|
||||||
_system->colorToRGB(color, ar, ag, ab);
|
|
||||||
r = ar * level;
|
|
||||||
g = ag * level;
|
|
||||||
b = ab * level;
|
|
||||||
|
|
||||||
OverlayColor *ptr = getBasePtr(rect.left, rect.top);
|
|
||||||
|
|
||||||
h = rect.height();
|
|
||||||
w = rect.width();
|
|
||||||
|
|
||||||
while (h--) {
|
|
||||||
for (int i = 0; i < w; i++) {
|
|
||||||
_system->colorToRGB(ptr[i], ar, ag, ab);
|
|
||||||
ptr[i] = _system->RGBToColor((ar + r) / (level+1),
|
|
||||||
(ag + g) / (level+1),
|
|
||||||
(ab + b) / (level+1));
|
|
||||||
}
|
|
||||||
ptr += _screenPitch;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void NewGui::fillRect(int x, int y, int w, int h, OverlayColor color) {
|
|
||||||
_screen.fillRect(Common::Rect(x, y, x + w, y + h), color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NewGui::frameRect(int x, int y, int w, int h, OverlayColor color) {
|
|
||||||
_screen.frameRect(Common::Rect(x, y, x + w, y + h), color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NewGui::addDirtyRect(int x, int y, int w, int h) {
|
|
||||||
Common::Rect rect(x, y, x + w, y + h);
|
|
||||||
rect.clip(_screen.w, _screen.h);
|
|
||||||
|
|
||||||
if (!rect.isValidRect())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// For now we don't keep yet another list of dirty rects but simply
|
|
||||||
// blit the affected area directly to the overlay. At least for our current
|
|
||||||
// GUI/widget/dialog code that is just fine.
|
|
||||||
OverlayColor *buf = getBasePtr(rect.left, rect.top);
|
|
||||||
_system->copyRectToOverlay(buf, _screenPitch, rect.left, rect.top, rect.width(), rect.height());
|
|
||||||
}
|
|
||||||
|
|
||||||
void NewGui::drawChar(byte chr, int xx, int yy, OverlayColor color, const Graphics::Font *font) {
|
|
||||||
if (font == 0)
|
|
||||||
font = &getFont();
|
|
||||||
font->drawChar(&_screen, chr, xx, yy, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
int NewGui::getStringWidth(const String &str) const {
|
|
||||||
return getFont().getStringWidth(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
int NewGui::getCharWidth(byte c) const {
|
|
||||||
return getFont().getCharWidth(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
int NewGui::getFontHeight() const {
|
|
||||||
return getFont().getFontHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NewGui::drawString(const String &s, int x, int y, int w, OverlayColor color, TextAlignment align, int deltax, bool useEllipsis) {
|
|
||||||
getFont().drawString(&_screen, s, x, y, w, color, align, deltax, useEllipsis);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Draw the mouse cursor (animated). This is mostly ripped from the cursor code in gfx.cpp
|
// Draw the mouse cursor (animated). This is mostly ripped from the cursor code in gfx.cpp
|
||||||
// We could plug in a different cursor here if we like to.
|
// We could plug in a different cursor here if we like to.
|
||||||
|
|
62
gui/newgui.h
62
gui/newgui.h
|
@ -26,6 +26,7 @@
|
||||||
#include "common/stack.h"
|
#include "common/stack.h"
|
||||||
#include "common/str.h"
|
#include "common/str.h"
|
||||||
#include "graphics/fontman.h"
|
#include "graphics/fontman.h"
|
||||||
|
#include "gui/theme.h"
|
||||||
|
|
||||||
class OSystem;
|
class OSystem;
|
||||||
|
|
||||||
|
@ -67,18 +68,23 @@ public:
|
||||||
|
|
||||||
bool isActive() const { return ! _dialogStack.empty(); }
|
bool isActive() const { return ! _dialogStack.empty(); }
|
||||||
|
|
||||||
|
Theme *theme() { return _theme; }
|
||||||
|
|
||||||
|
const Graphics::Font &getFont() const { return *(_theme->getFont()); }
|
||||||
|
int getFontHeight() const { return _theme->getFontHeight(); }
|
||||||
|
int getStringWidth(const Common::String &str) const { return _theme->getStringWidth(str); }
|
||||||
|
int getCharWidth(byte c) const { return _theme->getCharWidth(c); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
OSystem *_system;
|
OSystem *_system;
|
||||||
Graphics::Surface _screen;
|
|
||||||
int _screenPitch;
|
Theme *_theme;
|
||||||
|
|
||||||
bool _needRedraw;
|
bool _needRedraw;
|
||||||
DialogStack _dialogStack;
|
DialogStack _dialogStack;
|
||||||
|
|
||||||
bool _stateIsSaved;
|
bool _stateIsSaved;
|
||||||
|
|
||||||
const Graphics::Font *_font;
|
|
||||||
|
|
||||||
// for continuous events (keyDown)
|
// for continuous events (keyDown)
|
||||||
struct {
|
struct {
|
||||||
uint16 ascii;
|
uint16 ascii;
|
||||||
|
@ -109,54 +115,6 @@ protected:
|
||||||
void loop();
|
void loop();
|
||||||
|
|
||||||
void animateCursor();
|
void animateCursor();
|
||||||
void updateColors();
|
|
||||||
|
|
||||||
void updateScaleFactor();
|
|
||||||
|
|
||||||
OverlayColor *getBasePtr(int x, int y);
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Theme colors
|
|
||||||
OverlayColor _color, _shadowcolor;
|
|
||||||
OverlayColor _bgcolor;
|
|
||||||
OverlayColor _textcolor;
|
|
||||||
OverlayColor _textcolorhi;
|
|
||||||
|
|
||||||
// Font
|
|
||||||
const Graphics::Font &getFont() const;
|
|
||||||
|
|
||||||
// Screen surface
|
|
||||||
Graphics::Surface &getScreen() { return _screen; }
|
|
||||||
|
|
||||||
// Drawing primitives
|
|
||||||
void box(int x, int y, int width, int height, OverlayColor colorA, OverlayColor colorB);
|
|
||||||
void hLine(int x, int y, int x2, OverlayColor color);
|
|
||||||
void vLine(int x, int y, int y2, OverlayColor color);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy the specified screen rectangle into a new graphics surfaces.
|
|
||||||
* New memory for the GFX data is allocated via malloc; it is the
|
|
||||||
* callers responsibilty to free that data.
|
|
||||||
*/
|
|
||||||
void copyToSurface(Graphics::Surface *s, int x, int y, int w, int h);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Draw the graphics contained in the given surface at the specified coordinates.
|
|
||||||
*/
|
|
||||||
void drawSurface(const Graphics::Surface &s, int x, int y);
|
|
||||||
|
|
||||||
void blendRect(int x, int y, int w, int h, OverlayColor color, int level = 3);
|
|
||||||
void fillRect(int x, int y, int w, int h, OverlayColor color);
|
|
||||||
void frameRect(int x, int y, int w, int h, OverlayColor color);
|
|
||||||
|
|
||||||
void drawChar(byte c, int x, int y, OverlayColor color, const Graphics::Font *font = 0);
|
|
||||||
void drawString(const String &str, int x, int y, int w, OverlayColor color, Graphics::TextAlignment align = Graphics::kTextAlignLeft, int deltax = 0, bool useEllipsis = true);
|
|
||||||
|
|
||||||
int getStringWidth(const String &str) const;
|
|
||||||
int getCharWidth(byte c) const;
|
|
||||||
int getFontHeight() const;
|
|
||||||
|
|
||||||
void addDirtyRect(int x, int y, int w, int h);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace GUI
|
} // End of namespace GUI
|
||||||
|
|
516
gui/theme.cpp
Normal file
516
gui/theme.cpp
Normal file
|
@ -0,0 +1,516 @@
|
||||||
|
/* ScummVM - Scumm Interpreter
|
||||||
|
* Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $Header $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gui/theme.h"
|
||||||
|
|
||||||
|
namespace GUI {
|
||||||
|
ThemeClassic::ThemeClassic(OSystem *system) : Theme() {
|
||||||
|
_system = system;
|
||||||
|
_initOk = false;
|
||||||
|
memset(&_screen, 0, sizeof(_screen));
|
||||||
|
#ifdef OLDGUI_TRANSPARENCY
|
||||||
|
memset(&_dialog, 0, sizeof(_dialog));
|
||||||
|
#endif
|
||||||
|
_font = 0;
|
||||||
|
|
||||||
|
// Maybe change this filename
|
||||||
|
_configFile.loadFromFile("classic.ini");
|
||||||
|
}
|
||||||
|
|
||||||
|
ThemeClassic::~ThemeClassic() {
|
||||||
|
deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ThemeClassic::init() {
|
||||||
|
deinit();
|
||||||
|
_screen.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor));
|
||||||
|
if (_screen.pixels) {
|
||||||
|
_initOk = true;
|
||||||
|
clearAll();
|
||||||
|
_bgcolor = _system->RGBToColor(0, 0, 0);
|
||||||
|
_color = _system->RGBToColor(104, 104, 104);
|
||||||
|
_shadowcolor = _system->RGBToColor(64, 64, 64);
|
||||||
|
_textcolor = _system->RGBToColor(32, 160, 32);
|
||||||
|
_textcolorhi = _system->RGBToColor(0, 255, 0);
|
||||||
|
if (_screen.w >= 400 && _screen.h >= 300) {
|
||||||
|
_font = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);
|
||||||
|
} else {
|
||||||
|
_font = FontMan.getFontByUsage(Graphics::FontManager::kGUIFont);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::deinit() {
|
||||||
|
if (_initOk) {
|
||||||
|
_system->hideOverlay();
|
||||||
|
_screen.free();
|
||||||
|
_initOk = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::refresh() {
|
||||||
|
init();
|
||||||
|
_bgcolor = _system->RGBToColor(0, 0, 0);
|
||||||
|
_color = _system->RGBToColor(104, 104, 104);
|
||||||
|
_shadowcolor = _system->RGBToColor(64, 64, 64);
|
||||||
|
_textcolor = _system->RGBToColor(32, 160, 32);
|
||||||
|
_textcolorhi = _system->RGBToColor(0, 255, 0);
|
||||||
|
_system->showOverlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::enable() {
|
||||||
|
_system->showOverlay();
|
||||||
|
clearAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::disable() {
|
||||||
|
_system->hideOverlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::openDialog() {
|
||||||
|
#ifdef OLDGUI_TRANSPARENCY
|
||||||
|
if (!_dialog) {
|
||||||
|
_dialog = new DialogState;
|
||||||
|
assert(_dialog);
|
||||||
|
// first dialog
|
||||||
|
_dialog->screen.create(_screen.w, _screen.h, sizeof(OverlayColor));
|
||||||
|
}
|
||||||
|
memcpy(_dialog->screen.pixels, _screen.pixels, _screen.pitch*_screen.h);
|
||||||
|
blendScreenToDialog();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::closeDialog() {
|
||||||
|
#ifdef OLDGUI_TRANSPARENCY
|
||||||
|
if (_dialog) {
|
||||||
|
_dialog->screen.free();
|
||||||
|
delete _dialog;
|
||||||
|
_dialog = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::clearAll() {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
_system->clearOverlay();
|
||||||
|
// FIXME: problem with the 'pitch'
|
||||||
|
_system->grabOverlay((OverlayColor*)_screen.pixels, _screen.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::drawAll() {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::resetDrawArea() {
|
||||||
|
if (_initOk) {
|
||||||
|
_drawArea = Common::Rect(0, 0, _screen.w, _screen.h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::drawDialogBackground(const Common::Rect &r, kState state, bool mainDialog) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
|
||||||
|
restoreBackground(r);
|
||||||
|
box(r.left, r.top, r.width(), r.height(), _color, _shadowcolor);
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::drawText(const Common::Rect &r, const Common::String &str, kState state, kTextAlign align, bool inverted, int deltax, bool useEllipsis) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!inverted) {
|
||||||
|
restoreBackground(r);
|
||||||
|
_font->drawString(&_screen, str, r.left, r.top, r.width(), getColor(state), convertAligment(align), deltax, useEllipsis);
|
||||||
|
} else {
|
||||||
|
_screen.fillRect(r, getColor(state));
|
||||||
|
_font->drawString(&_screen, str, r.left, r.top, r.width(), _bgcolor, convertAligment(align), deltax, useEllipsis);
|
||||||
|
}
|
||||||
|
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
restoreBackground(r);
|
||||||
|
font->drawChar(&_screen, ch, r.left, r.top, getColor(state));
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::drawWidgetBackground(const Common::Rect &r, uint16 hints, kWidgetBackground background, kState state) {
|
||||||
|
if (!_initOk || background == kWidgetBackgroundNo)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (background) {
|
||||||
|
case kWidgetBackgroundBorder:
|
||||||
|
restoreBackground(r);
|
||||||
|
box(r.left, r.top, r.width(), r.height(), _color, _shadowcolor);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kWidgetBackgroundBorderSmall:
|
||||||
|
restoreBackground(r);
|
||||||
|
box(r.left, r.top, r.width(), r.height());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kWidgetBackgroundPlain:
|
||||||
|
restoreBackground(r);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::drawButton(const Common::Rect &r, const Common::String &str, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
restoreBackground(r);
|
||||||
|
|
||||||
|
drawWidgetBackground(r, 0, kWidgetBackgroundBorder, state);
|
||||||
|
|
||||||
|
const int off = (r.height() - _font->getFontHeight()) / 2;
|
||||||
|
_font->drawString(&_screen, str, r.left, r.top+off, r.width(), getColor(state), Graphics::kTextAlignCenter, 0, false);
|
||||||
|
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::drawSurface(const Common::Rect &r, const Graphics::Surface &surface, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Common::Rect rect(r.left, r.top, r.left + surface.w, r.top + surface.h);
|
||||||
|
rect.clip(_screen.w, _screen.h);
|
||||||
|
|
||||||
|
if (!rect.isValidRect())
|
||||||
|
return;
|
||||||
|
|
||||||
|
assert(surface.bytesPerPixel == sizeof(OverlayColor));
|
||||||
|
|
||||||
|
OverlayColor *src = (OverlayColor *)surface.pixels;
|
||||||
|
OverlayColor *dst = (OverlayColor *)_screen.getBasePtr(rect.left, rect.top);
|
||||||
|
|
||||||
|
int w = rect.width();
|
||||||
|
int h = rect.height();
|
||||||
|
|
||||||
|
while (h--) {
|
||||||
|
memcpy(dst, src, surface.pitch);
|
||||||
|
src += w;
|
||||||
|
// FIXME: this should be pitch
|
||||||
|
dst += _screen.w;
|
||||||
|
}
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::drawSlider(const Common::Rect &r, int width, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
Common::Rect r2 = r;
|
||||||
|
|
||||||
|
restoreBackground(r);
|
||||||
|
|
||||||
|
box(r.left, r.top, r.width(), r.height(), _color, _shadowcolor);
|
||||||
|
r2.left = r.left + 2;
|
||||||
|
r2.top = r.top + 2;
|
||||||
|
r2.bottom = r.bottom - 2;
|
||||||
|
r2.right = r2.left + width;
|
||||||
|
if (r2.right > r.right - 2) {
|
||||||
|
r2.right = r.right - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
_screen.fillRect(r2, getColor(state));
|
||||||
|
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::drawCheckbox(const Common::Rect &r, const Common::String &str, bool checked, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Common::Rect r2 = r;
|
||||||
|
int checkBoxSize = getFontHeight();
|
||||||
|
if (checkBoxSize > r.height()) {
|
||||||
|
checkBoxSize = r.height();
|
||||||
|
}
|
||||||
|
r2.bottom = r2.top + checkBoxSize;
|
||||||
|
|
||||||
|
restoreBackground(r2);
|
||||||
|
|
||||||
|
box(r.left, r.top, checkBoxSize, checkBoxSize, _color, _shadowcolor);
|
||||||
|
|
||||||
|
if (checked) {
|
||||||
|
// TODO: implement old style
|
||||||
|
r2.top += 2;
|
||||||
|
r2.bottom = r.top + checkBoxSize - 2;
|
||||||
|
r2.left += 2;
|
||||||
|
r2.right = r.left + checkBoxSize - 2;
|
||||||
|
_screen.fillRect(r2, getColor(state));
|
||||||
|
r2 = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r2.left += checkBoxSize + 10;
|
||||||
|
_font->drawString(&_screen, str, r2.left, r2.top, r2.width(), getColor(state), Graphics::kTextAlignCenter, 0, true);
|
||||||
|
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::drawTab(const Common::Rect &r, const Common::String &str, bool active, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
restoreBackground(r);
|
||||||
|
box(r.left, r.top, r.width(), r.height(), _color, _shadowcolor);
|
||||||
|
_font->drawString(&_screen, str, r.left, r.top+2, r.width(), getColor(state), Graphics::kTextAlignCenter, 0, true);
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::drawScrollbar(const Common::Rect &r, int sliderY, int sliderHeight, kScrollbarState scroll, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
restoreBackground(r);
|
||||||
|
Common::Rect r2 = r;
|
||||||
|
box(r.left, r.top, r.width(), r.height(), _color, _shadowcolor);
|
||||||
|
|
||||||
|
const int UP_DOWN_BOX_HEIGHT = r.width() + 1;
|
||||||
|
const int B = 3;
|
||||||
|
const int arrowSize = (r.width() / 2 - B + 1);
|
||||||
|
|
||||||
|
OverlayColor color = 0;
|
||||||
|
if (scroll == kScrollbarStateSinglePage) {
|
||||||
|
color = _color;
|
||||||
|
} else if (scroll == kScrollbarStateUp && state == kStateHighlight) {
|
||||||
|
color = _textcolorhi;
|
||||||
|
} else {
|
||||||
|
color = _textcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// draws the 'up' button
|
||||||
|
box(r.left, r.top, r.width(), UP_DOWN_BOX_HEIGHT, _color, _shadowcolor);
|
||||||
|
Common::Point p0 = Common::Point(r.left + r.width() / 2, r.top + (UP_DOWN_BOX_HEIGHT - arrowSize - 1) / 2);
|
||||||
|
Common::Point p1 = Common::Point(p0.x - arrowSize, p0.y + arrowSize);
|
||||||
|
Common::Point p2 = Common::Point(p0.x + arrowSize, p0.y + arrowSize);
|
||||||
|
for (; p1.x <= p2.x; ++p1.x)
|
||||||
|
_screen.drawLine(p0.x, p0.y, p1.x, p1.y, color);
|
||||||
|
|
||||||
|
if (scroll != kScrollbarStateSinglePage) {
|
||||||
|
r2.top += sliderY;
|
||||||
|
r2.left += 2;
|
||||||
|
r2.right -= 2;
|
||||||
|
r2.bottom = r2.top + sliderHeight;
|
||||||
|
_screen.fillRect(r2, (state == kStateHighlight && scroll == kScrollbarStateSlider) ? _textcolorhi : _textcolor);
|
||||||
|
box(r2.left, r2.top, r2.width(), r2.height());
|
||||||
|
int y = r2.top + sliderHeight / 2;
|
||||||
|
color = (state == kStateHighlight && scroll == kScrollbarStateSlider) ? _color : _bgcolor;
|
||||||
|
_screen.hLine(r2.left + 1, y - 2, r2.right - 2, color);
|
||||||
|
_screen.hLine(r2.left + 1, y, r2.right - 2, color);
|
||||||
|
_screen.hLine(r2.left + 1, y + 2, r2.right - 2, color);
|
||||||
|
r2 = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r2.top = r2.bottom - UP_DOWN_BOX_HEIGHT;
|
||||||
|
if (scroll == kScrollbarStateSinglePage) {
|
||||||
|
color = _color;
|
||||||
|
} else if (scroll == kScrollbarStateDown && state == kStateHighlight) {
|
||||||
|
color = _textcolorhi;
|
||||||
|
} else {
|
||||||
|
color = _textcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// draws the 'down' button
|
||||||
|
box(r2.left, r2.top, r2.width(), UP_DOWN_BOX_HEIGHT, _color, _shadowcolor);
|
||||||
|
p0 = Common::Point(r2.left + r2.width() / 2, r2.top + (UP_DOWN_BOX_HEIGHT + arrowSize + 1) / 2);
|
||||||
|
p1 = Common::Point(p0.x - arrowSize, p0.y - arrowSize);
|
||||||
|
p2 = Common::Point(p0.x + arrowSize, p0.y - arrowSize);
|
||||||
|
for (; p1.x <= p2.x; ++p1.x)
|
||||||
|
_screen.drawLine(p0.x, p0.y, p1.x, p1.y, color);
|
||||||
|
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::drawCaret(const Common::Rect &r, bool erase, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
|
||||||
|
OverlayColor color = 0;
|
||||||
|
if (erase) {
|
||||||
|
color = _bgcolor;
|
||||||
|
} else {
|
||||||
|
color = getColor(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
_screen.vLine(r.left, r.top, r.bottom - 2, color);
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::drawLineSeparator(const Common::Rect &r, kState state) {
|
||||||
|
if (!_initOk)
|
||||||
|
return;
|
||||||
|
_screen.hLine(r.left - 1, r.top + r.height() / 2, r.right, _shadowcolor);
|
||||||
|
_screen.hLine(r.left, r.top + 1 + r.height() / 2, r.right, _color);
|
||||||
|
addDirtyRect(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
// intern drawing
|
||||||
|
|
||||||
|
void ThemeClassic::restoreBackground(Common::Rect r) {
|
||||||
|
r.clip(_screen.w, _screen.h);
|
||||||
|
#ifndef OLDGUI_TRANSPARENCY
|
||||||
|
_screen.fillRect(r, _bgcolor);
|
||||||
|
#else
|
||||||
|
if (_dialog) {
|
||||||
|
if (!_dialog->screen.pixels) {
|
||||||
|
_screen.fillRect(r, _bgcolor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const OverlayColor *src = (const OverlayColor*)_dialog->screen.getBasePtr(r.left, r.top);
|
||||||
|
OverlayColor *dst = (OverlayColor*)_screen.getBasePtr(r.left, r.top);
|
||||||
|
|
||||||
|
int h = r.height();
|
||||||
|
int w = r.width();
|
||||||
|
while (h--) {
|
||||||
|
memcpy(dst, src, w*sizeof(OverlayColor));
|
||||||
|
src += _dialog->screen.w;
|
||||||
|
dst += _screen.w;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_screen.fillRect(r, _bgcolor);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ThemeClassic::addDirtyRect(Common::Rect r) {
|
||||||
|
// TODO: implement proper dirty rect handling
|
||||||
|
// FIXME: problem with the 'pitch'
|
||||||
|
r.clip(_screen.w, _screen.h);
|
||||||
|
r.clip(_drawArea);
|
||||||
|
_system->copyRectToOverlay((OverlayColor*)_screen.getBasePtr(r.left, r.top), _screen.w, r.left, r.top, r.width(), r.height());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::box(int x, int y, int width, int height, OverlayColor colorA, OverlayColor colorB) {
|
||||||
|
if (y >= 0) {
|
||||||
|
_screen.hLine(x + 1, y, x + width - 2, colorA);
|
||||||
|
_screen.hLine(x, y + 1, x + width - 1, colorA);
|
||||||
|
}
|
||||||
|
int drawY = y;
|
||||||
|
if (drawY < 0) {
|
||||||
|
height += drawY;
|
||||||
|
drawY = 0;
|
||||||
|
}
|
||||||
|
_screen.vLine(x, drawY + 1, drawY + height - 2, colorA);
|
||||||
|
_screen.vLine(x + 1, drawY, drawY + height - 1, colorA);
|
||||||
|
|
||||||
|
if (y + height >= 0) {
|
||||||
|
_screen.hLine(x + 1, drawY + height - 2, x + width - 1, colorB);
|
||||||
|
_screen.hLine(x + 1, drawY + height - 1, x + width - 2, colorB);
|
||||||
|
_screen.vLine(x + width - 1, drawY + 1, drawY + height - 2, colorB);
|
||||||
|
_screen.vLine(x + width - 2, drawY + 1, drawY + height - 1, colorB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeClassic::box(int x, int y, int w, int h) {
|
||||||
|
_screen.hLine(x, y, x + w - 1, _color);
|
||||||
|
_screen.hLine(x, y + h - 1, x +w - 1, _shadowcolor);
|
||||||
|
_screen.vLine(x, y, y + h - 1, _color);
|
||||||
|
_screen.vLine(x + w - 1, y, y + h - 1, _shadowcolor);
|
||||||
|
}
|
||||||
|
|
||||||
|
OverlayColor ThemeClassic::getColor(kState state) {
|
||||||
|
OverlayColor usedColor = _color;
|
||||||
|
switch (state) {
|
||||||
|
case kStateEnabled:
|
||||||
|
usedColor = _textcolor;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kStateHighlight:
|
||||||
|
usedColor = _textcolorhi;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return usedColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef OLDGUI_TRANSPARENCY
|
||||||
|
void ThemeClassic::blendScreenToDialog() {
|
||||||
|
Common::Rect rect(0, 0, _screen.w, _screen.h);
|
||||||
|
|
||||||
|
if (!rect.isValidRect())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_system->hasFeature(OSystem::kFeatureOverlaySupportsAlpha)) {
|
||||||
|
int a, r, g, b;
|
||||||
|
uint8 aa, ar, ag, ab;
|
||||||
|
_system->colorToARGB(_bgcolor, aa, ar, ag, ab);
|
||||||
|
a = aa*3/(3+1);
|
||||||
|
if (a < 1)
|
||||||
|
return;
|
||||||
|
r = ar * a;
|
||||||
|
g = ag * a;
|
||||||
|
b = ab * a;
|
||||||
|
|
||||||
|
OverlayColor *ptr = (OverlayColor*)_dialog->screen.getBasePtr(rect.left, rect.top);
|
||||||
|
|
||||||
|
int h = rect.height();
|
||||||
|
int w = rect.width();
|
||||||
|
while (h--) {
|
||||||
|
for (int i = 0; i < w; i++) {
|
||||||
|
_system->colorToARGB(ptr[i], aa, ar, ag, ab);
|
||||||
|
int a2 = aa + a - (a*aa)/255;
|
||||||
|
ptr[i] = _system->ARGBToColor(a2,
|
||||||
|
((255-a)*aa*ar/255+r)/a2,
|
||||||
|
((255-a)*aa*ag/255+g)/a2,
|
||||||
|
((255-a)*aa*ab/255+b)/a2);
|
||||||
|
}
|
||||||
|
ptr += _screen.w;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int r, g, b;
|
||||||
|
uint8 ar, ag, ab;
|
||||||
|
_system->colorToRGB(_bgcolor, ar, ag, ab);
|
||||||
|
r = ar * 3;
|
||||||
|
g = ag * 3;
|
||||||
|
b = ab * 3;
|
||||||
|
|
||||||
|
OverlayColor *ptr = (OverlayColor*)_dialog->screen.getBasePtr(rect.left, rect.top);
|
||||||
|
|
||||||
|
int h = rect.height();
|
||||||
|
int w = rect.width();
|
||||||
|
|
||||||
|
while (h--) {
|
||||||
|
for (int i = 0; i < w; i++) {
|
||||||
|
_system->colorToRGB(ptr[i], ar, ag, ab);
|
||||||
|
ptr[i] = _system->RGBToColor((ar + r) / (3+1),
|
||||||
|
(ag + g) / (3+1),
|
||||||
|
(ab + b) / (3+1));
|
||||||
|
}
|
||||||
|
ptr += _screen.w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} // end of namespace GUI
|
||||||
|
|
361
gui/theme.h
Normal file
361
gui/theme.h
Normal file
|
@ -0,0 +1,361 @@
|
||||||
|
/* ScummVM - Scumm Interpreter
|
||||||
|
* Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $Header $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GUI_THEME_H
|
||||||
|
#define GUI_THEME_H
|
||||||
|
|
||||||
|
#include "common/stdafx.h"
|
||||||
|
#include "common/system.h"
|
||||||
|
#include "common/rect.h"
|
||||||
|
#include "common/str.h"
|
||||||
|
#include "common/config-file.h"
|
||||||
|
|
||||||
|
#include "graphics/surface.h"
|
||||||
|
#include "graphics/fontman.h"
|
||||||
|
|
||||||
|
namespace GUI {
|
||||||
|
|
||||||
|
// Hints to the theme engine that the widget is used in a non-standard way.
|
||||||
|
|
||||||
|
enum {
|
||||||
|
// Indicates that this is the first time the widget is drawn.
|
||||||
|
THEME_HINT_FIRST_DRAW = 1 << 0,
|
||||||
|
|
||||||
|
// Indicates that the widget will be redrawn often, e.g. list widgets.
|
||||||
|
// It may therefore be a good idea to save the background so that it
|
||||||
|
// can be redrawn quickly.
|
||||||
|
THEME_HINT_SAVE_BACKGROUND = 1 << 1
|
||||||
|
};
|
||||||
|
|
||||||
|
class Theme {
|
||||||
|
public:
|
||||||
|
Theme() : _drawArea(), _configFile() {}
|
||||||
|
virtual ~Theme() {}
|
||||||
|
|
||||||
|
enum kTextAlign {
|
||||||
|
kTextAlignLeft,
|
||||||
|
kTextAlignCenter,
|
||||||
|
kTextAlignRight
|
||||||
|
};
|
||||||
|
|
||||||
|
enum kWidgetBackground {
|
||||||
|
kWidgetBackgroundNo,
|
||||||
|
kWidgetBackgroundPlain,
|
||||||
|
kWidgetBackgroundBorder,
|
||||||
|
kWidgetBackgroundBorderSmall
|
||||||
|
};
|
||||||
|
|
||||||
|
enum kState {
|
||||||
|
kStateDisabled,
|
||||||
|
kStateEnabled,
|
||||||
|
kStateHighlight
|
||||||
|
};
|
||||||
|
|
||||||
|
enum kScrollbarState {
|
||||||
|
kScrollbarStateNo,
|
||||||
|
kScrollbarStateUp,
|
||||||
|
kScrollbarStateDown,
|
||||||
|
kScrollbarStateSlider,
|
||||||
|
kScrollbarStateSinglePage
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual bool init() = 0;
|
||||||
|
virtual void deinit() = 0;
|
||||||
|
|
||||||
|
virtual void refresh() = 0;
|
||||||
|
|
||||||
|
virtual void enable() = 0;
|
||||||
|
virtual void disable() = 0;
|
||||||
|
|
||||||
|
virtual void openDialog() = 0;
|
||||||
|
virtual void closeDialog() = 0;
|
||||||
|
|
||||||
|
virtual void clearAll() = 0;
|
||||||
|
virtual void drawAll() = 0;
|
||||||
|
|
||||||
|
virtual void setDrawArea(const Common::Rect &r) { _drawArea = r; }
|
||||||
|
// resets the draw area to the screen size
|
||||||
|
virtual void resetDrawArea() = 0;
|
||||||
|
|
||||||
|
virtual const Common::ConfigFile &getConfigFile() { return _configFile; }
|
||||||
|
|
||||||
|
virtual const Graphics::Font *getFont() const = 0;
|
||||||
|
virtual int getFontHeight() const = 0;
|
||||||
|
virtual int getStringWidth(const Common::String &str) const = 0;
|
||||||
|
virtual int getCharWidth(byte c) const = 0;
|
||||||
|
|
||||||
|
virtual void drawDialogBackground(const Common::Rect &r, kState state = kStateEnabled, bool mainDialog = false) = 0;
|
||||||
|
virtual void drawText(const Common::Rect &r, const Common::String &str, kState state = kStateEnabled, kTextAlign align = kTextAlignCenter, bool inverted = false, int deltax = 0, bool useEllipsis = true) = 0;
|
||||||
|
// this should ONLY be used by the debugger until we get a nicer solution
|
||||||
|
virtual void drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, kState state = kStateEnabled) = 0;
|
||||||
|
|
||||||
|
virtual void drawWidgetBackground(const Common::Rect &r, uint16 hints, kWidgetBackground background = kWidgetBackgroundPlain, kState state = kStateEnabled) = 0;
|
||||||
|
virtual void drawButton(const Common::Rect &r, const Common::String &str, kState state = kStateEnabled) = 0;
|
||||||
|
virtual void drawSurface(const Common::Rect &r, const Graphics::Surface &surface, kState state = kStateEnabled) = 0;
|
||||||
|
virtual void drawSlider(const Common::Rect &r, int width, kState state = kStateEnabled) = 0;
|
||||||
|
virtual void drawCheckbox(const Common::Rect &r, const Common::String &str, bool checked, kState state = kStateEnabled) = 0;
|
||||||
|
virtual void drawTab(const Common::Rect &r, const Common::String &str, bool active, kState state = kStateEnabled) = 0;
|
||||||
|
virtual void drawScrollbar(const Common::Rect &r, int sliderY, int sliderHeight, kScrollbarState, kState state = kStateEnabled) = 0;
|
||||||
|
virtual void drawCaret(const Common::Rect &r, bool erase, kState state = kStateEnabled) = 0;
|
||||||
|
virtual void drawLineSeparator(const Common::Rect &r, kState state = kStateEnabled) = 0;
|
||||||
|
|
||||||
|
Graphics::TextAlignment convertAligment(kTextAlign align) const {
|
||||||
|
switch (align) {
|
||||||
|
case kTextAlignLeft:
|
||||||
|
return Graphics::kTextAlignLeft;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kTextAlignRight:
|
||||||
|
return Graphics::kTextAlignRight;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
return Graphics::kTextAlignCenter;
|
||||||
|
};
|
||||||
|
|
||||||
|
kTextAlign convertAligment(Graphics::TextAlignment align) const {
|
||||||
|
switch (align) {
|
||||||
|
case Graphics::kTextAlignLeft:
|
||||||
|
return kTextAlignLeft;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Graphics::kTextAlignRight:
|
||||||
|
return kTextAlignRight;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return kTextAlignCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Common::Rect _drawArea;
|
||||||
|
Common::ConfigFile _configFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define OLDGUI_TRANSPARENCY
|
||||||
|
|
||||||
|
class ThemeClassic : public Theme {
|
||||||
|
public:
|
||||||
|
ThemeClassic(OSystem *system);
|
||||||
|
virtual ~ThemeClassic();
|
||||||
|
|
||||||
|
bool init();
|
||||||
|
void deinit();
|
||||||
|
|
||||||
|
void refresh();
|
||||||
|
|
||||||
|
void enable();
|
||||||
|
void disable();
|
||||||
|
|
||||||
|
void openDialog();
|
||||||
|
void closeDialog();
|
||||||
|
|
||||||
|
void clearAll();
|
||||||
|
void drawAll();
|
||||||
|
|
||||||
|
void resetDrawArea();
|
||||||
|
|
||||||
|
const Graphics::Font *getFont() const { return _font; }
|
||||||
|
int getFontHeight() const { if (_initOk) return _font->getFontHeight(); return 0; }
|
||||||
|
int getStringWidth(const Common::String &str) const { if (_initOk) return _font->getStringWidth(str); return 0; }
|
||||||
|
int getCharWidth(byte c) const { if (_initOk) return _font->getCharWidth(c); return 0; }
|
||||||
|
|
||||||
|
void drawDialogBackground(const Common::Rect &r, kState state, bool mainDialog);
|
||||||
|
void drawText(const Common::Rect &r, const Common::String &str, kState state, kTextAlign align, bool inverted, int deltax, bool useEllipsis);
|
||||||
|
void drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, kState state);
|
||||||
|
|
||||||
|
void drawWidgetBackground(const Common::Rect &r, uint16 hints, kWidgetBackground background, kState state);
|
||||||
|
void drawButton(const Common::Rect &r, const Common::String &str, kState state);
|
||||||
|
void drawSurface(const Common::Rect &r, const Graphics::Surface &surface, kState state);
|
||||||
|
void drawSlider(const Common::Rect &r, int width, kState state);
|
||||||
|
void drawCheckbox(const Common::Rect &r, const Common::String &str, bool checked, kState state);
|
||||||
|
void drawTab(const Common::Rect &r, const Common::String &str, bool active, kState state);
|
||||||
|
void drawScrollbar(const Common::Rect &r, int sliderY, int sliderHeight, kScrollbarState, kState state);
|
||||||
|
void drawCaret(const Common::Rect &r, bool erase, kState state);
|
||||||
|
void drawLineSeparator(const Common::Rect &r, kState state);
|
||||||
|
private:
|
||||||
|
void restoreBackground(Common::Rect r);
|
||||||
|
bool addDirtyRect(Common::Rect r);
|
||||||
|
|
||||||
|
void box(int x, int y, int width, int height, OverlayColor colorA, OverlayColor colorB);
|
||||||
|
void box(int x, int y, int width, int height);
|
||||||
|
|
||||||
|
OverlayColor getColor(kState state);
|
||||||
|
|
||||||
|
OSystem *_system;
|
||||||
|
Graphics::Surface _screen;
|
||||||
|
|
||||||
|
#ifdef OLDGUI_TRANSPARENCY
|
||||||
|
struct DialogState {
|
||||||
|
Graphics::Surface screen;
|
||||||
|
} *_dialog;
|
||||||
|
|
||||||
|
void blendScreenToDialog();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool _initOk;
|
||||||
|
|
||||||
|
const Graphics::Font *_font;
|
||||||
|
OverlayColor _color, _shadowcolor;
|
||||||
|
OverlayColor _bgcolor;
|
||||||
|
OverlayColor _textcolor;
|
||||||
|
OverlayColor _textcolorhi;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ThemeNew : public Theme {
|
||||||
|
public:
|
||||||
|
ThemeNew(OSystem *system, Common::String stylefile);
|
||||||
|
virtual ~ThemeNew();
|
||||||
|
|
||||||
|
bool init();
|
||||||
|
void deinit();
|
||||||
|
|
||||||
|
void refresh();
|
||||||
|
|
||||||
|
void enable();
|
||||||
|
void disable();
|
||||||
|
|
||||||
|
void openDialog();
|
||||||
|
void closeDialog();
|
||||||
|
|
||||||
|
void clearAll();
|
||||||
|
void drawAll();
|
||||||
|
|
||||||
|
void resetDrawArea();
|
||||||
|
|
||||||
|
const Graphics::Font *getFont() const { return _font; }
|
||||||
|
int getFontHeight() const { if (_font) return _font->getFontHeight(); return 0; }
|
||||||
|
int getStringWidth(const Common::String &str) const { if (_font) return _font->getStringWidth(str); return 0; }
|
||||||
|
int getCharWidth(byte c) const { if (_font) return _font->getCharWidth(c); return 0; }
|
||||||
|
|
||||||
|
void drawDialogBackground(const Common::Rect &r, kState state, bool mainDialog);
|
||||||
|
void drawText(const Common::Rect &r, const Common::String &str, kState state, kTextAlign align, bool inverted, int deltax, bool useEllipsis);
|
||||||
|
void drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, kState state);
|
||||||
|
|
||||||
|
void drawWidgetBackground(const Common::Rect &r, uint16 hints, kWidgetBackground background, kState state);
|
||||||
|
void drawButton(const Common::Rect &r, const Common::String &str, kState state);
|
||||||
|
void drawSurface(const Common::Rect &r, const Graphics::Surface &surface, kState state);
|
||||||
|
void drawSlider(const Common::Rect &r, int width, kState state);
|
||||||
|
void drawCheckbox(const Common::Rect &r, const Common::String &str, bool checked, kState state);
|
||||||
|
void drawTab(const Common::Rect &r, const Common::String &str, bool active, kState state);
|
||||||
|
void drawScrollbar(const Common::Rect &r, int sliderY, int sliderHeight, kScrollbarState, kState state);
|
||||||
|
void drawCaret(const Common::Rect &r, bool erase, kState state);
|
||||||
|
void drawLineSeparator(const Common::Rect &r, kState state);
|
||||||
|
private:
|
||||||
|
bool addDirtyRect(Common::Rect r, bool backup = false);
|
||||||
|
|
||||||
|
void colorFade(const Common::Rect &r, OverlayColor start, OverlayColor end);
|
||||||
|
void drawRect(const Common::Rect &r, const Graphics::Surface *corner,
|
||||||
|
const Graphics::Surface *top, const Graphics::Surface *left, const Graphics::Surface *fill, int alpha);
|
||||||
|
void drawRectMasked(const Common::Rect &r, const Graphics::Surface *corner, const Graphics::Surface *top,
|
||||||
|
const Graphics::Surface *left, const Graphics::Surface *fill, int alpha,
|
||||||
|
OverlayColor start, OverlayColor end, uint factor = 1);
|
||||||
|
void drawSurface(const Common::Rect &r, const Graphics::Surface *surf, bool upDown, bool leftRight, int alpha);
|
||||||
|
void drawSurfaceMasked(const Common::Rect &r, const Graphics::Surface *surf, bool upDown, bool leftRight, int alpha,
|
||||||
|
OverlayColor start, OverlayColor end, uint factor = 1);
|
||||||
|
|
||||||
|
OSystem *_system;
|
||||||
|
Graphics::Surface _screen;
|
||||||
|
|
||||||
|
bool _initOk;
|
||||||
|
bool _forceRedraw;
|
||||||
|
|
||||||
|
void restoreBackground(Common::Rect r);
|
||||||
|
OverlayColor getColor(kState state);
|
||||||
|
|
||||||
|
struct DialogState {
|
||||||
|
Graphics::Surface screen;
|
||||||
|
} *_dialog;
|
||||||
|
|
||||||
|
const Graphics::Font *_font;
|
||||||
|
|
||||||
|
enum kImageHandles {
|
||||||
|
kDialogBkgdCorner = 0,
|
||||||
|
kDialogBkgdTop = 1,
|
||||||
|
kDialogBkgdLeft = 2,
|
||||||
|
kDialogBkgd = 3,
|
||||||
|
kWidgetBkgdCorner = 4,
|
||||||
|
kWidgetBkgdTop = 5,
|
||||||
|
kWidgetBkgdLeft = 6,
|
||||||
|
kWidgetBkgd = 7,
|
||||||
|
kCheckboxEmpty = 8,
|
||||||
|
kCheckboxChecked = 9,
|
||||||
|
kWidgetArrow = 10,
|
||||||
|
kImageHandlesMax
|
||||||
|
};
|
||||||
|
|
||||||
|
const Common::String *_imageHandles;
|
||||||
|
const Graphics::Surface **_images;
|
||||||
|
|
||||||
|
enum kColorHandles {
|
||||||
|
kMainDialogStart = 0,
|
||||||
|
kMainDialogEnd = 1,
|
||||||
|
|
||||||
|
kDialogStart = 2,
|
||||||
|
kDialogEnd = 3,
|
||||||
|
|
||||||
|
kColorStateDisabled = 4,
|
||||||
|
kColorStateHighlight = 5,
|
||||||
|
kColorStateEnabled = 6,
|
||||||
|
kColorTransparency = 7,
|
||||||
|
|
||||||
|
kTextInvertedBackground = 8,
|
||||||
|
kTextInvertedColor = 9,
|
||||||
|
|
||||||
|
kWidgetBackgroundStart = 10,
|
||||||
|
kWidgetBackgroundEnd = 11,
|
||||||
|
kWidgetBackgroundSmallStart = 12,
|
||||||
|
kWidgetBackgroundSmallEnd = 13,
|
||||||
|
|
||||||
|
kButtonBackgroundStart = 14,
|
||||||
|
kButtonBackgroundEnd = 15,
|
||||||
|
kButtonTextEnabled = 16,
|
||||||
|
kButtonTextDisabled = 17,
|
||||||
|
kButtonTextHighlight = 18,
|
||||||
|
|
||||||
|
kSliderBackgroundStart = 19,
|
||||||
|
kSliderBackgroundEnd = 20,
|
||||||
|
kSliderStart = 21,
|
||||||
|
kSliderEnd = 22,
|
||||||
|
|
||||||
|
kTabBackgroundStart = 23,
|
||||||
|
kTabBackgroundEnd = 24,
|
||||||
|
|
||||||
|
kScrollbarBackgroundStart = 25,
|
||||||
|
kScrollbarBackgroundEnd = 26,
|
||||||
|
kScrollbarButtonStart = 27,
|
||||||
|
kScrollbarButtonEnd = 28,
|
||||||
|
kScrollbarSliderStart = 29,
|
||||||
|
kScrollbarSliderEnd = 30,
|
||||||
|
|
||||||
|
kCaretColor = 31,
|
||||||
|
|
||||||
|
kColorHandlesMax
|
||||||
|
};
|
||||||
|
|
||||||
|
OverlayColor _colors[kColorHandlesMax];
|
||||||
|
};
|
||||||
|
} // end of namespace GUI
|
||||||
|
|
||||||
|
#endif // GUI_THEME_H
|
BIN
gui/themes/default-theme.zip
Normal file
BIN
gui/themes/default-theme.zip
Normal file
Binary file not shown.
|
@ -29,7 +29,7 @@ namespace GUI {
|
||||||
|
|
||||||
Widget::Widget(GuiObject *boss, int x, int y, int w, int h)
|
Widget::Widget(GuiObject *boss, int x, int y, int w, int h)
|
||||||
: GuiObject(x, y, w, h), _type(0), _boss(boss),
|
: GuiObject(x, y, w, h), _type(0), _boss(boss),
|
||||||
_id(0), _flags(0), _hasFocus(false) {
|
_id(0), _flags(0), _hints(THEME_HINT_FIRST_DRAW), _hasFocus(false) {
|
||||||
// Insert into the widget list of the boss
|
// Insert into the widget list of the boss
|
||||||
_next = _boss->_firstWidget;
|
_next = _boss->_firstWidget;
|
||||||
_boss->_firstWidget = this;
|
_boss->_firstWidget = this;
|
||||||
|
@ -52,16 +52,12 @@ void Widget::draw() {
|
||||||
_y = getAbsY();
|
_y = getAbsY();
|
||||||
|
|
||||||
// Clear background (unless alpha blending is enabled)
|
// Clear background (unless alpha blending is enabled)
|
||||||
if (_flags & WIDGET_CLEARBG)
|
//if (_flags & WIDGET_CLEARBG)
|
||||||
gui->fillRect(_x, _y, _w, _h, gui->_bgcolor);
|
// gui->fillRect(_x, _y, _w, _h, gui->_bgcolor);
|
||||||
|
|
||||||
// Draw border
|
// Draw border
|
||||||
if (_flags & WIDGET_BORDER) {
|
if (_flags & WIDGET_BORDER) {
|
||||||
OverlayColor colorA = gui->_color;
|
gui->theme()->drawWidgetBackground(Common::Rect(_x, _y, _x+_w, _y+_h), _hints, Theme::kWidgetBackgroundBorder);
|
||||||
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;
|
_x += 4;
|
||||||
_y += 4;
|
_y += 4;
|
||||||
_w -= 8;
|
_w -= 8;
|
||||||
|
@ -79,9 +75,6 @@ void Widget::draw() {
|
||||||
_h += 8;
|
_h += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flag the draw area as dirty
|
|
||||||
gui->addDirtyRect(_x, _y, _w, _h);
|
|
||||||
|
|
||||||
_x = oldX;
|
_x = oldX;
|
||||||
_y = oldY;
|
_y = oldY;
|
||||||
|
|
||||||
|
@ -91,6 +84,8 @@ void Widget::draw() {
|
||||||
w->draw();
|
w->draw();
|
||||||
w = w->_next;
|
w = w->_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearHints(THEME_HINT_FIRST_DRAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget *Widget::findWidgetInChain(Widget *w, int x, int y) {
|
Widget *Widget::findWidgetInChain(Widget *w, int x, int y) {
|
||||||
|
@ -137,8 +132,9 @@ void StaticTextWidget::setAlign(TextAlignment align) {
|
||||||
|
|
||||||
|
|
||||||
void StaticTextWidget::drawWidget(bool hilite) {
|
void StaticTextWidget::drawWidget(bool hilite) {
|
||||||
NewGui *gui = &g_gui;
|
g_gui.theme()->drawText(Common::Rect(_x, _y, _x+_w, _y+_h), _label,
|
||||||
gui->drawString(_label, _x, _y, _w, isEnabled() ? gui->_textcolor : gui->_color, _align);
|
isEnabled() ? Theme::kStateEnabled : Theme::kStateDisabled,
|
||||||
|
g_gui.theme()->convertAligment(_align));
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
@ -146,7 +142,7 @@ void StaticTextWidget::drawWidget(bool hilite) {
|
||||||
ButtonWidget::ButtonWidget(GuiObject *boss, int x, int y, int w, int h, const String &label, uint32 cmd, uint8 hotkey, WidgetSize ws)
|
ButtonWidget::ButtonWidget(GuiObject *boss, int x, int y, int w, int h, const String &label, uint32 cmd, uint8 hotkey, WidgetSize ws)
|
||||||
: StaticTextWidget(boss, x, y, w, h, label, kTextAlignCenter, ws), CommandSender(boss),
|
: StaticTextWidget(boss, x, y, w, h, label, kTextAlignCenter, ws), CommandSender(boss),
|
||||||
_cmd(cmd), _hotkey(hotkey) {
|
_cmd(cmd), _hotkey(hotkey) {
|
||||||
_flags = WIDGET_ENABLED | WIDGET_BORDER | WIDGET_CLEARBG;
|
_flags = WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG;
|
||||||
_type = kButtonWidget;
|
_type = kButtonWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,11 +152,7 @@ void ButtonWidget::handleMouseUp(int x, int y, int button, int clickCount) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ButtonWidget::drawWidget(bool hilite) {
|
void ButtonWidget::drawWidget(bool hilite) {
|
||||||
NewGui *gui = &g_gui;
|
g_gui.theme()->drawButton(Common::Rect(_x, _y, _x+_w, _y+_h), _label, isEnabled() ? (hilite ? Theme::kStateHighlight : Theme::kStateEnabled) : Theme::kStateDisabled);
|
||||||
const int off = (_h - g_gui.getFontHeight()) / 2;
|
|
||||||
gui->drawString(_label, _x, _y + off, _w,
|
|
||||||
!isEnabled() ? gui->_color :
|
|
||||||
hilite ? gui->_textcolorhi : gui->_textcolor, _align);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
@ -187,39 +179,8 @@ void CheckboxWidget::setState(bool state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckboxWidget::drawWidget(bool hilite) {
|
void CheckboxWidget::drawWidget(bool hilite) {
|
||||||
NewGui *gui = &g_gui;
|
g_gui.theme()->drawCheckbox(Common::Rect(_x, _y, _x+_w, _y+_h), _label, _state,
|
||||||
int fontHeight = gui->getFontHeight();
|
isEnabled() ? Theme::kStateEnabled : Theme::kStateDisabled);
|
||||||
|
|
||||||
// Draw the box
|
|
||||||
gui->box(_x, _y, fontHeight + 4, fontHeight + 4, gui->_color, gui->_shadowcolor);
|
|
||||||
gui->fillRect(_x + 2, _y + 2, fontHeight, fontHeight, gui->_bgcolor);
|
|
||||||
|
|
||||||
// If checked, draw cross inside the box
|
|
||||||
if (_state) {
|
|
||||||
Graphics::Surface &surf = gui->getScreen();
|
|
||||||
Common::Point p0, p1, p2, p3;
|
|
||||||
OverlayColor color = isEnabled() ? gui->_textcolor : gui->_color;
|
|
||||||
|
|
||||||
p0 = Common::Point(_x + 4, _y + 4);
|
|
||||||
p1 = Common::Point(_x + fontHeight - 1, _y + 4);
|
|
||||||
p2 = Common::Point(_x + 4, _y + fontHeight - 1);
|
|
||||||
p3 = Common::Point(_x + fontHeight - 1, _y + fontHeight - 1);
|
|
||||||
|
|
||||||
if (_ws == kBigWidgetSize) {
|
|
||||||
surf.drawLine(p0.x + 1, p0.y, p3.x, p3.y - 1, color);
|
|
||||||
surf.drawLine(p0.x, p0.y + 1, p3.x - 1, p3.y, color);
|
|
||||||
surf.drawLine(p0.x + 1, p0.y + 1, p3.x - 1, p3.y - 1, color);
|
|
||||||
surf.drawLine(p2.x + 1, p2.y - 1, p1.x - 1, p1.y + 1, color);
|
|
||||||
surf.drawLine(p2.x + 1, p2.y, p1.x, p1.y + 1, color);
|
|
||||||
surf.drawLine(p2.x, p2.y - 1, p1.x - 1, p1.y, color);
|
|
||||||
} else {
|
|
||||||
surf.drawLine(p0.x, p0.y, p3.x, p3.y, color);
|
|
||||||
surf.drawLine(p2.x, p2.y, p1.x, p1.y, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally draw the label
|
|
||||||
gui->drawString(_label, _x + fontHeight + 10, _y + 3, _w, isEnabled() ? gui->_textcolor : gui->_color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
@ -262,15 +223,8 @@ void SliderWidget::handleMouseUp(int x, int y, int button, int clickCount) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SliderWidget::drawWidget(bool hilite) {
|
void SliderWidget::drawWidget(bool hilite) {
|
||||||
NewGui *gui = &g_gui;
|
g_gui.theme()->drawSlider(Common::Rect(_x, _y, _x+_w, _y+_h), valueToPos(_value),
|
||||||
|
isEnabled() ? (hilite ? Theme::kStateHighlight : Theme::kStateEnabled) : Theme::kStateDisabled);
|
||||||
// Draw the box
|
|
||||||
gui->box(_x, _y, _w, _h, gui->_color, gui->_shadowcolor);
|
|
||||||
|
|
||||||
// Draw the 'bar'
|
|
||||||
gui->fillRect(_x + 2, _y + 2, valueToPos(_value), _h - 4,
|
|
||||||
!isEnabled() ? gui->_color :
|
|
||||||
hilite ? gui->_textcolorhi : gui->_textcolor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SliderWidget::valueToPos(int value) {
|
int SliderWidget::valueToPos(int value) {
|
||||||
|
@ -305,13 +259,9 @@ void GraphicsWidget::setGfx(const Graphics::Surface *gfx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsWidget::drawWidget(bool hilite) {
|
void GraphicsWidget::drawWidget(bool hilite) {
|
||||||
if (sizeof(OverlayColor) != _gfx.bytesPerPixel || !_gfx.pixels) {
|
if (sizeof(OverlayColor) == _gfx.bytesPerPixel && _gfx.pixels) {
|
||||||
// FIXME: It doesn't really make sense to render this text here, since
|
g_gui.theme()->drawSurface(Common::Rect(_x, _y, _x+_w, _y+_h), _gfx);
|
||||||
// this widget might be used for other things than rendering savegame
|
}
|
||||||
// graphics/previews...
|
|
||||||
g_gui.drawString("No preview", _x, _y + _h / 2 - g_gui.getFontHeight() / 2, _w, g_gui._textcolor, Graphics::kTextAlignCenter);
|
|
||||||
} else
|
|
||||||
g_gui.drawSurface(_gfx, _x, _y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace GUI
|
} // End of namespace GUI
|
||||||
|
|
|
@ -45,7 +45,6 @@ enum {
|
||||||
WIDGET_WANT_TICKLE = 1 << 7,
|
WIDGET_WANT_TICKLE = 1 << 7,
|
||||||
WIDGET_TRACK_MOUSE = 1 << 8,
|
WIDGET_TRACK_MOUSE = 1 << 8,
|
||||||
WIDGET_RETAIN_FOCUS = 1 << 9 // Retain focus on mouse up. By default widgets lose focus on mouseup, but some widgets might want to retain it - widgets where you enter text, for instance
|
WIDGET_RETAIN_FOCUS = 1 << 9 // Retain focus on mouse up. By default widgets lose focus on mouseup, but some widgets might want to retain it - widgets where you enter text, for instance
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -93,6 +92,7 @@ protected:
|
||||||
Widget *_next;
|
Widget *_next;
|
||||||
uint16 _id;
|
uint16 _id;
|
||||||
uint16 _flags;
|
uint16 _flags;
|
||||||
|
uint16 _hints;
|
||||||
bool _hasFocus;
|
bool _hasFocus;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -127,6 +127,10 @@ public:
|
||||||
void clearFlags(int flags) { _flags &= ~flags; }
|
void clearFlags(int flags) { _flags &= ~flags; }
|
||||||
int getFlags() const { return _flags; }
|
int getFlags() const { return _flags; }
|
||||||
|
|
||||||
|
void setHints(int hints) { _hints |= hints; }
|
||||||
|
void clearHints(int hints) { _hints &= ~hints; }
|
||||||
|
int getHints() const { return _hints; }
|
||||||
|
|
||||||
void setEnabled(bool e) { if (e) setFlags(WIDGET_ENABLED); else clearFlags(WIDGET_ENABLED); }
|
void setEnabled(bool e) { if (e) setFlags(WIDGET_ENABLED); else clearFlags(WIDGET_ENABLED); }
|
||||||
bool isEnabled() const { return _flags & WIDGET_ENABLED; }
|
bool isEnabled() const { return _flags & WIDGET_ENABLED; }
|
||||||
bool isVisible() const { return !(_flags & WIDGET_INVISIBLE); }
|
bool isVisible() const { return !(_flags & WIDGET_INVISIBLE); }
|
||||||
|
|
|
@ -925,20 +925,10 @@ ValueDisplayDialog::ValueDisplayDialog(const Common::String& label, int minVal,
|
||||||
}
|
}
|
||||||
|
|
||||||
void ValueDisplayDialog::drawDialog() {
|
void ValueDisplayDialog::drawDialog() {
|
||||||
g_gui.blendRect(_x, _y, _w, _h, g_gui._bgcolor);
|
|
||||||
g_gui.box(_x, _y, _w, _h, g_gui._color, g_gui._shadowcolor);
|
|
||||||
|
|
||||||
const int labelWidth = _w - 8 - _percentBarWidth;
|
const int labelWidth = _w - 8 - _percentBarWidth;
|
||||||
|
g_gui.theme()->drawDialogBackground(Common::Rect(_x, _y, _x+_w, _y+_h));
|
||||||
// Draw the label
|
g_gui.theme()->drawText(Common::Rect(_x+4, _y+4, _x+labelWidth+4, _y+g_gui.theme()->getFontHeight()+4), _label);
|
||||||
g_gui.drawString(_label, _x + 4, _y + 4, labelWidth, g_gui._textcolor);
|
g_gui.theme()->drawSlider(Common::Rect(_x+4+labelWidth, _y+4, _x+_w-4, _y+_h-4), _percentBarWidth * (_value - _min) / (_max - _min));
|
||||||
|
|
||||||
// Draw the percentage bar
|
|
||||||
g_gui.fillRect(_x + 4 + labelWidth, _y + 4, _percentBarWidth * (_value - _min) / (_max - _min), _h - 8, g_gui._textcolorhi);
|
|
||||||
g_gui.frameRect(_x + 4 + labelWidth, _y + 4, _percentBarWidth, _h - 8, g_gui._textcolor);
|
|
||||||
|
|
||||||
// Flag the draw area as dirty
|
|
||||||
g_gui.addDirtyRect(_x, _y, _w, _h);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ValueDisplayDialog::handleTickle() {
|
void ValueDisplayDialog::handleTickle() {
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
#include "common/stdafx.h"
|
#include "common/stdafx.h"
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
|
#include "common/debugger.cpp"
|
||||||
|
|
||||||
#include "sky/debug.h"
|
#include "sky/debug.h"
|
||||||
#include "sky/grid.h"
|
#include "sky/grid.h"
|
||||||
#include "sky/logic.h"
|
#include "sky/logic.h"
|
||||||
|
@ -30,8 +32,6 @@
|
||||||
#include "sky/struc.h"
|
#include "sky/struc.h"
|
||||||
#include "sky/compact.h"
|
#include "sky/compact.h"
|
||||||
|
|
||||||
#include "common/debugger.cpp"
|
|
||||||
|
|
||||||
namespace Sky {
|
namespace Sky {
|
||||||
|
|
||||||
static const char *section_0_compacts[] = {
|
static const char *section_0_compacts[] = {
|
||||||
|
@ -1278,7 +1278,7 @@ void Debug::mcode(uint32 mcode, uint32 a, uint32 b, uint32 c) {
|
||||||
|
|
||||||
|
|
||||||
Debugger::Debugger(Logic *logic, Mouse *mouse, Screen *screen, SkyCompact *skyCompact)
|
Debugger::Debugger(Logic *logic, Mouse *mouse, Screen *screen, SkyCompact *skyCompact)
|
||||||
: _logic(logic), _mouse(mouse), _screen(screen), _skyCompact(skyCompact), _showGrid(false) {
|
: Common::Debugger<Debugger>(), _logic(logic), _mouse(mouse), _screen(screen), _skyCompact(skyCompact), _showGrid(false) {
|
||||||
DCmd_Register("exit", &Debugger::Cmd_Exit);
|
DCmd_Register("exit", &Debugger::Cmd_Exit);
|
||||||
DCmd_Register("help", &Debugger::Cmd_Help);
|
DCmd_Register("help", &Debugger::Cmd_Help);
|
||||||
DCmd_Register("info", &Debugger::Cmd_Info);
|
DCmd_Register("info", &Debugger::Cmd_Info);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue