Update to v080r05 release.

byuu says:

Includes updated versions of nall and phoenix, which mostly improves the
GTK+ version. However, it appears to be crashing at the moment after
loading a game. Unfortunately it works when gdb is used, so I can't
easily debug it :/

You can now build with make phoenix=gtk if you want the GTK+ version on
Linux (the Qt version is leagues better even on Gnome, please use it if
at all possible.)

There's also settings.startFullScreen, config-file only, to allow for
front-end use. Forgot to add the reset/power hotkeys.

I also fixed compilation of ui-gameboy on GCC 4.6. I hope that's the
last switch(enum) error, those are damn annoying. Can't wait to switch
to GCC 4.6 on Windows.
This commit is contained in:
Tim Allen 2011-08-07 00:03:52 +10:00
parent f38af85e0a
commit 0c3f0834ab
69 changed files with 1579 additions and 491 deletions

View File

@ -3,9 +3,10 @@ snes := snes
gameboy := gameboy
profile := accuracy
ui := ui
# phoenix := gtk
# debugger
options :=
# debugger
# compiler
c := $(compiler) -std=gnu99

101
bsnes/nall/bmp.hpp Executable file
View File

@ -0,0 +1,101 @@
#ifndef NALL_BMP_HPP
#define NALL_BMP_HPP
#include <nall/file.hpp>
//BMP reader / writer
//author: byuu
//note: only 24-bit RGB and 32-bit ARGB uncompressed images supported
namespace nall {
struct bmp {
static bool read(const string &filename, uint32_t *&data, unsigned &width, unsigned &height);
static bool write(const string &filename, const uint32_t *data, unsigned width, unsigned height, bool alpha = false);
};
bool bmp::read(const string &filename, uint32_t *&data, unsigned &width, unsigned &height) {
file fp;
if(fp.open(filename, file::mode::read) == false) return false;
if(fp.size() < 0x36) return false;
if(fp.readm(2) != 0x424d) return false;
fp.seek(0x000a);
unsigned offset = fp.readl(4);
unsigned dibsize = fp.readl(4);
if(dibsize != 40) return false;
signed headerWidth = fp.readl(4);
if(headerWidth < 0) return false;
signed headerHeight = fp.readl(4);
fp.readl(2);
unsigned bitsPerPixel = fp.readl(2);
if(bitsPerPixel != 24 && bitsPerPixel != 32) return false;
unsigned compression = fp.readl(4);
if(compression != 0) return false;
fp.seek(offset);
bool noFlip = headerHeight < 0;
width = headerWidth, height = abs(headerHeight);
data = new uint32_t[width * height];
unsigned bytesPerPixel = bitsPerPixel / 8;
unsigned alignedWidth = width * bytesPerPixel;
unsigned paddingLength = 0;
while(alignedWidth % 4) alignedWidth++, paddingLength++;
for(unsigned y = 0; y < height; y++) {
uint32_t *p = noFlip ? data + y * width : data + (height - 1 - y) * width;
for(unsigned x = 0; x < width; x++, p++) {
*p = fp.readl(bytesPerPixel);
if(bytesPerPixel == 3) *p |= 255 << 24;
}
if(paddingLength) fp.readl(paddingLength);
}
fp.close();
return true;
}
bool bmp::write(const string &filename, const uint32_t *data, unsigned width, unsigned height, bool alpha) {
file fp;
if(fp.open(filename, file::mode::write) == false) return false;
unsigned bitsPerPixel = alpha ? 32 : 24;
unsigned bytesPerPixel = bitsPerPixel / 8;
unsigned alignedWidth = width * bytesPerPixel;
unsigned paddingLength = 0;
unsigned imageSize = alignedWidth * height;
unsigned fileSize = 0x36 + imageSize;
while(alignedWidth % 4) alignedWidth++, paddingLength++;
fp.writem(0x424d, 2); //signature
fp.writel(fileSize, 4); //file size
fp.writel(0, 2); //reserved
fp.writel(0, 2); //reserved
fp.writel(0x36, 4); //offset
fp.writel(40, 4); //DIB size
fp.writel(width, 4); //width
fp.writel(-height, 4); //height
fp.writel(1, 2); //color planes
fp.writel(bitsPerPixel, 2); //bits per pixel
fp.writel(0, 4); //compression method (BI_RGB)
fp.writel(imageSize, 4); //image data size
fp.writel(3780, 4); //horizontal resolution
fp.writel(3780, 4); //vertical resolution
fp.writel(0, 4); //palette size
fp.writel(0, 4); //important color count
for(unsigned y = 0; y < height; y++) {
const uint32_t *p = data + y * width;
for(unsigned x = 0; x < width; x++) fp.writel(*p++, bytesPerPixel);
if(paddingLength) fp.writel(0, paddingLength);
}
fp.close();
return true;
}
}
#endif

View File

@ -6,7 +6,7 @@
#include <nall/string.hpp>
#if defined(_WIN32)
#include <nall/utf8.hpp>
#include <nall/windows/utf8.hpp>
#else
#include <dirent.h>
#include <stdio.h>

View File

@ -4,8 +4,8 @@
#include <nall/platform.hpp>
#include <nall/stdint.hpp>
#include <nall/string.hpp>
#include <nall/utf8.hpp>
#include <nall/utility.hpp>
#include <nall/windows/utf8.hpp>
namespace nall {
inline FILE* fopen_utf8(const string &utf8_filename, const char *mode) {
@ -22,6 +22,24 @@ namespace nall {
enum class index : unsigned { absolute, relative };
enum class time : unsigned { create, modify, access };
static bool read(const string &filename, uint8_t *&data, unsigned &size) {
file fp;
if(fp.open(filename, mode::read) == false) return false;
size = fp.size();
data = new uint8_t[size];
fp.read(data, size);
fp.close();
return true;
}
static bool write(const string &filename, const uint8_t *data, unsigned size) {
file fp;
if(fp.open(filename, mode::write) == false) return false;
fp.write(data, size);
fp.close();
return true;
}
uint8_t read() {
if(!fp) return 0xff; //file not open
if(file_mode == mode::write) return 0xff; //reads not permitted

View File

@ -2,7 +2,7 @@
#define NALL_FILEMAP_HPP
#include <nall/stdint.hpp>
#include <nall/utf8.hpp>
#include <nall/windows/utf8.hpp>
#include <stdio.h>
#include <stdlib.h>

87
bsnes/nall/gzip.hpp Executable file
View File

@ -0,0 +1,87 @@
#ifndef NALL_GZIP_HPP
#define NALL_GZIP_HPP
#include <nall/file.hpp>
#include <nall/inflate.hpp>
namespace nall {
struct gzip {
string filename;
uint8_t *data;
unsigned size;
bool decompress(const string &filename);
bool decompress(const uint8_t *data, unsigned size);
gzip();
~gzip();
};
bool gzip::decompress(const string &filename) {
uint8_t *data;
unsigned size;
if(file::read(filename, data, size) == false) return false;
bool result = decompress(data, size);
delete[] data;
return result;
}
bool gzip::decompress(const uint8_t *data, unsigned size) {
if(size < 18) return false;
if(data[0] != 0x1f) return false;
if(data[1] != 0x8b) return false;
unsigned cm = data[2];
unsigned flg = data[3];
unsigned mtime = data[4];
mtime |= data[5] << 8;
mtime |= data[6] << 16;
mtime |= data[7] << 24;
unsigned xfl = data[8];
unsigned os = data[9];
unsigned p = 10;
unsigned isize = data[size - 4];
isize |= data[size - 3] << 8;
isize |= data[size - 2] << 16;
isize |= data[size - 1] << 24;
filename = "";
if(flg & 0x04) { //FEXTRA
unsigned xlen = data[p + 0];
xlen |= data[p + 1] << 8;
p += 2 + xlen;
}
if(flg & 0x08) { //FNAME
char buffer[PATH_MAX];
for(unsigned n = 0; n < PATH_MAX; n++, p++) {
buffer[n] = data[p];
if(data[p] == 0) break;
}
if(data[p++]) return false;
filename = buffer;
}
if(flg & 0x10) { //FCOMMENT
while(data[p++]);
}
if(flg & 0x02) { //FHCRC
p += 2;
}
this->size = isize;
this->data = new uint8_t[this->size];
return inflate(this->data, this->size, data + p, size - p - 8);
}
gzip::gzip() : data(0) {
}
gzip::~gzip() {
if(data) delete[] data;
}
}
#endif

View File

@ -28,9 +28,10 @@ struct http {
size = 0;
send({
"GET ", path, " HTTP/1.1\n"
"Host: ", hostname, "\n"
"\n"
"GET ", path, " HTTP/1.1\r\n"
"Host: ", hostname, "\r\n"
"Connection: close\r\n"
"\r\n"
});
header = downloadHeader();
@ -99,7 +100,7 @@ struct http {
inline void downloadContent(uint8_t *&data, unsigned &size) {
unsigned capacity = 0;
if(header.position("Transfer-Encoding: chunked")) {
if(header.iposition("\r\nTransfer-Encoding: chunked\r\n")) {
while(true) {
unsigned length = hex(downloadChunkLength());
if(length == 0) break;
@ -115,7 +116,7 @@ struct http {
length -= packetlength;
}
}
} else if(auto position = header.position("Content-Length: ")) {
} else if(auto position = header.iposition("\r\nContent-Length: ")) {
unsigned length = decimal((const char*)header + position() + 16);
while(length) {
char buffer[256];
@ -150,8 +151,12 @@ struct http {
serversocket = -1;
}
inline http() {
#ifdef _WIN32
inline int close(int sock) {
return closesocket(sock);
}
inline http() {
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sock == INVALID_SOCKET && WSAGetLastError() == WSANOTINITIALISED) {
WSADATA wsaData;
@ -159,9 +164,11 @@ struct http {
WSACleanup();
return;
}
} else close(sock);
#endif
} else {
close(sock);
}
}
#endif
};
}

View File

@ -17,7 +17,8 @@ inline bool inflate(
const uint8_t *source, unsigned sourceLength
) {
unsigned long tl = targetLength, sl = sourceLength;
return puff::puff((unsigned char*)target, &tl, (unsigned char*)source, &sl) == 0;
int result = puff::puff((unsigned char*)target, &tl, (unsigned char*)source, &sl);
return result == 0;
}
namespace puff {

View File

@ -5,10 +5,9 @@
//minimum version needed for _wstat64, etc
#undef __MSVCRT_VERSION__
#define __MSVCRT_VERSION__ 0x0601
#include <nall/windows/utf8.hpp>
#endif
#include <nall/utf8.hpp>
//=========================
//standard platform headers
//=========================
@ -67,7 +66,6 @@
#define rmdir _rmdir
#define usleep(n) Sleep(n / 1000)
#define vsnprintf _vsnprintf
static int close(int sock) { return closesocket(sock); }
#endif
//================

423
bsnes/nall/png.hpp Executable file
View File

@ -0,0 +1,423 @@
#ifndef NALL_PNG_HPP
#define NALL_PNG_HPP
//PNG image decoder
//author: byuu
#include <nall/inflate.hpp>
#include <nall/string.hpp>
namespace nall {
struct png {
uint32_t *data;
unsigned size;
struct Info {
unsigned width;
unsigned height;
unsigned bitDepth;
unsigned colorType;
unsigned compressionMethod;
unsigned filterType;
unsigned interlaceMethod;
unsigned bytesPerPixel;
unsigned pitch;
uint8_t palette[256][3];
} info;
uint8_t *rawData;
unsigned rawSize;
inline bool decode(const string &filename);
inline bool decode(const uint8_t *sourceData, unsigned sourceSize);
inline void transform();
inline void alphaTransform(uint32_t rgb = 0xffffff);
png();
~png();
protected:
enum class FourCC : unsigned {
IHDR = 0x49484452,
PLTE = 0x504c5445,
IDAT = 0x49444154,
IEND = 0x49454e44,
};
static const unsigned interlace[7][4];
unsigned bitpos;
inline unsigned inflateSize();
inline bool deinterlace(const uint8_t *&inputData, unsigned pass);
inline bool filter(uint8_t *outputData, const uint8_t *inputData, unsigned width, unsigned height);
inline unsigned read(const uint8_t *data, unsigned length);
inline unsigned decode(const uint8_t *&data);
inline unsigned readbits(const uint8_t *&data);
inline unsigned scale(unsigned n);
};
bool png::decode(const string &filename) {
uint8_t *data;
unsigned size;
if(file::read(filename, data, size) == false) return false;
bool result = decode(data, size);
delete[] data;
return result;
}
bool png::decode(const uint8_t *sourceData, unsigned sourceSize) {
if(sourceSize < 8) return false;
if(read(sourceData + 0, 4) != 0x89504e47) return false;
if(read(sourceData + 4, 4) != 0x0d0a1a0a) return false;
uint8_t *compressedData = 0;
unsigned compressedSize = 0;
unsigned offset = 8;
while(offset < sourceSize) {
unsigned length = read(sourceData + offset + 0, 4);
unsigned fourCC = read(sourceData + offset + 4, 4);
unsigned checksum = read(sourceData + offset + 8 + length, 4);
if(fourCC == (unsigned)FourCC::IHDR) {
info.width = read(sourceData + offset + 8, 4);
info.height = read(sourceData + offset + 12, 4);
info.bitDepth = read(sourceData + offset + 16, 1);
info.colorType = read(sourceData + offset + 17, 1);
info.compressionMethod = read(sourceData + offset + 18, 1);
info.filterType = read(sourceData + offset + 19, 1);
info.interlaceMethod = read(sourceData + offset + 20, 1);
if(info.bitDepth == 0 || info.bitDepth > 16) return false;
if(info.bitDepth & (info.bitDepth - 1)) return false; //not a power of two
if(info.compressionMethod != 0) return false;
if(info.filterType != 0) return false;
if(info.interlaceMethod != 0 && info.interlaceMethod != 1) return false;
switch(info.colorType) {
case 0: info.bytesPerPixel = info.bitDepth * 1; break; //L
case 2: info.bytesPerPixel = info.bitDepth * 3; break; //R,G,B
case 3: info.bytesPerPixel = info.bitDepth * 1; break; //P
case 4: info.bytesPerPixel = info.bitDepth * 2; break; //L,A
case 6: info.bytesPerPixel = info.bitDepth * 4; break; //R,G,B,A
default: return false;
}
if(info.colorType == 2 || info.colorType == 4 || info.colorType == 6)
if(info.bitDepth != 8 && info.bitDepth != 16) return false;
if(info.colorType == 3 && info.bitDepth == 16) return false;
info.bytesPerPixel = (info.bytesPerPixel + 7) / 8;
info.pitch = (int)info.width * info.bytesPerPixel;
}
if(fourCC == (unsigned)FourCC::PLTE) {
if(length % 3) return false;
for(unsigned n = 0, p = offset + 8; n < length / 3; n++) {
info.palette[n][0] = sourceData[p++];
info.palette[n][1] = sourceData[p++];
info.palette[n][2] = sourceData[p++];
}
}
if(fourCC == (unsigned)FourCC::IDAT) {
compressedData = (uint8_t*)realloc(compressedData, compressedSize + length);
memcpy(compressedData + compressedSize, sourceData + offset + 8, length);
compressedSize += length;
}
if(fourCC == (unsigned)FourCC::IEND) {
break;
}
offset += 4 + 4 + length + 4;
}
unsigned interlacedSize = inflateSize();
uint8_t *interlacedData = new uint8_t[interlacedSize];
bool result = inflate(interlacedData, interlacedSize, compressedData + 2, compressedSize - 6);
delete[] compressedData;
if(result == false) {
delete[] interlacedData;
return false;
}
rawSize = info.width * info.height * info.bytesPerPixel;
rawData = new uint8_t[rawSize];
if(info.interlaceMethod == 0) {
if(filter(rawData, interlacedData, info.width, info.height) == false) {
delete[] interlacedData;
delete[] rawData;
rawData = 0;
return false;
}
} else {
const uint8_t *passData = interlacedData;
for(unsigned pass = 0; pass < 7; pass++) {
if(deinterlace(passData, pass) == false) {
delete[] interlacedData;
delete[] rawData;
rawData = 0;
return false;
}
}
}
delete[] interlacedData;
return true;
}
const unsigned png::interlace[7][4] = {
//x-distance, y-distance, x-origin, y-origin
{ 8, 8, 0, 0 },
{ 8, 8, 4, 0 },
{ 4, 8, 0, 4 },
{ 4, 4, 2, 0 },
{ 2, 4, 0, 2 },
{ 2, 2, 1, 0 },
{ 1, 2, 0, 1 },
};
unsigned png::inflateSize() {
if(info.interlaceMethod == 0) {
return info.width * info.height * info.bytesPerPixel + info.height;
}
unsigned size = 0;
for(unsigned pass = 0; pass < 7; pass++) {
unsigned xd = interlace[pass][0], yd = interlace[pass][1];
unsigned xo = interlace[pass][2], yo = interlace[pass][3];
unsigned width = (info.width + (xd - xo - 1)) / xd;
unsigned height = (info.height + (yd - yo - 1)) / yd;
if(width == 0 || height == 0) continue;
size += width * height * info.bytesPerPixel + height;
}
return size;
}
bool png::deinterlace(const uint8_t *&inputData, unsigned pass) {
unsigned xd = interlace[pass][0], yd = interlace[pass][1];
unsigned xo = interlace[pass][2], yo = interlace[pass][3];
unsigned width = (info.width + (xd - xo - 1)) / xd;
unsigned height = (info.height + (yd - yo - 1)) / yd;
if(width == 0 || height == 0) return true;
unsigned outputSize = width * height * info.bytesPerPixel;
uint8_t *outputData = new uint8_t[outputSize];
bool result = filter(outputData, inputData, width, height);
const uint8_t *rd = outputData;
for(unsigned y = yo; y < info.height; y += yd) {
uint8_t *wr = rawData + y * info.pitch;
for(unsigned x = xo; x < info.width; x += xd) {
for(unsigned b = 0; b < info.bytesPerPixel; b++) {
wr[x * info.bytesPerPixel + b] = *rd++;
}
}
}
inputData += outputSize + height;
delete[] outputData;
return result;
}
bool png::filter(uint8_t *outputData, const uint8_t *inputData, unsigned width, unsigned height) {
uint8_t *wr = outputData;
const uint8_t *rd = inputData;
int bpp = info.bytesPerPixel, pitch = width * bpp;
for(int y = 0; y < height; y++) {
uint8_t filter = *rd++;
switch(filter) {
case 0x00: //None
for(int x = 0; x < pitch; x++) {
wr[x] = rd[x];
}
break;
case 0x01: //Subtract
for(int x = 0; x < pitch; x++) {
wr[x] = rd[x] + (x - bpp < 0 ? 0 : wr[x - bpp]);
}
break;
case 0x02: //Above
for(int x = 0; x < pitch; x++) {
wr[x] = rd[x] + (y - 1 < 0 ? 0 : wr[x - pitch]);
}
break;
case 0x03: //Average
for(int x = 0; x < pitch; x++) {
short a = x - bpp < 0 ? 0 : wr[x - bpp];
short b = y - 1 < 0 ? 0 : wr[x - pitch];
wr[x] = rd[x] + (uint8_t)((a + b) / 2);
}
break;
case 0x04: //Paeth
for(int x = 0; x < pitch; x++) {
short a = x - bpp < 0 ? 0 : wr[x - bpp];
short b = y - 1 < 0 ? 0 : wr[x - pitch];
short c = x - bpp < 0 || y - 1 < 0 ? 0 : wr[x - pitch - bpp];
short p = a + b - c;
short pa = p > a ? p - a : a - p;
short pb = p > b ? p - b : b - p;
short pc = p > c ? p - c : c - p;
uint8_t paeth = (uint8_t)((pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c);
wr[x] = rd[x] + paeth;
}
break;
default: //Invalid
return false;
}
rd += pitch;
wr += pitch;
}
return true;
}
unsigned png::read(const uint8_t *data, unsigned length) {
unsigned result = 0;
while(length--) result = (result << 8) | (*data++);
return result;
}
unsigned png::decode(const uint8_t *&data) {
unsigned p, r, g, b, a;
switch(info.colorType) {
case 0: //L
r = g = b = scale(readbits(data));
a = 0xff;
break;
case 2: //R,G,B
r = scale(readbits(data));
g = scale(readbits(data));
b = scale(readbits(data));
a = 0xff;
break;
case 3: //P
p = readbits(data);
r = info.palette[p][0];
g = info.palette[p][1];
b = info.palette[p][2];
a = 0xff;
break;
case 4: //L,A
r = g = b = scale(readbits(data));
a = scale(readbits(data));
break;
case 6: //R,G,B,A
r = scale(readbits(data));
g = scale(readbits(data));
b = scale(readbits(data));
a = scale(readbits(data));
break;
}
return (a << 24) | (r << 16) | (g << 8) | (b << 0);
}
unsigned png::readbits(const uint8_t *&data) {
unsigned result = 0;
switch(info.bitDepth) {
case 1:
result = (*data >> bitpos) & 1;
bitpos++;
if(bitpos == 8) { data++; bitpos = 0; }
break;
case 2:
result = (*data >> bitpos) & 3;
bitpos += 2;
if(bitpos == 8) { data++; bitpos = 0; }
break;
case 4:
result = (*data >> bitpos) & 15;
bitpos += 4;
if(bitpos == 8) { data++; bitpos = 0; }
break;
case 8:
result = *data++;
break;
case 16:
result = (data[0] << 8) | (data[1] << 0);
data += 2;
break;
}
return result;
}
unsigned png::scale(unsigned n) {
switch(info.bitDepth) {
case 1: return n ? 0xff : 0x00;
case 2: return n * 0x55;
case 4: return n * 0x11;
case 8: return n;
case 16: return n >> 8;
}
return 0;
}
void png::transform() {
if(data) delete[] data;
data = new uint32_t[info.width * info.height];
bitpos = 0;
const uint8_t *rd = rawData;
for(unsigned y = 0; y < info.height; y++) {
uint32_t *wr = data + y * info.width;
for(unsigned x = 0; x < info.width; x++) {
wr[x] = decode(rd);
}
}
}
void png::alphaTransform(uint32_t rgb) {
transform();
uint8_t ir = rgb >> 16;
uint8_t ig = rgb >> 8;
uint8_t ib = rgb >> 0;
uint32_t *p = data;
for(unsigned y = 0; y < info.height; y++) {
for(unsigned x = 0; x < info.width; x++) {
uint32_t pixel = *p;
uint8_t a = pixel >> 24;
uint8_t r = pixel >> 16;
uint8_t g = pixel >> 8;
uint8_t b = pixel >> 0;
r = (r * a) + (ir * (255 - a)) >> 8;
g = (g * a) + (ig * (255 - a)) >> 8;
b = (b * a) + (ib * (255 - a)) >> 8;
*p++ = (255 << 24) | (r << 16) | (g << 8) | (b << 0);
}
}
}
png::png() : data(0), rawData(0) {
}
png::~png() {
if(data) delete[] data;
if(rawData) delete[] rawData;
}
}
#endif

View File

@ -2,7 +2,7 @@
#define NALL_RESOURCE_HPP
#include <nall/file.hpp>
#include <nall/unzip.hpp>
#include <nall/zip.hpp>
namespace nall {
@ -39,7 +39,7 @@ struct resource {
bool decode(const uint8_t *cdata, unsigned csize) {
if(data) delete[] data;
unzip archive;
zip archive;
if(archive.open(cdata, csize) == false) return false;
if(archive.file.size() == 0) return false;
bool result = archive.extract(archive.file[0], data, size);

View File

@ -8,8 +8,8 @@
#include <nall/concept.hpp>
#include <nall/function.hpp>
#include <nall/stdint.hpp>
#include <nall/utf8.hpp>
#include <nall/vector.hpp>
#include <nall/windows/utf8.hpp>
namespace nall {
class string;
@ -22,13 +22,13 @@ namespace nall {
template<typename... Args> inline string& assign(Args&&... args);
template<typename... Args> inline string& append(Args&&... args);
inline string& assign_(const char*);
inline string& append_(const char*);
inline bool readfile(const string&);
inline string& replace (const char*, const char*);
inline string& qreplace(const char*, const char*);
template<unsigned Limit = 0> inline string& replace(const char*, const char*);
template<unsigned Limit = 0> inline string& ireplace(const char*, const char*);
template<unsigned Limit = 0> inline string& qreplace(const char*, const char*);
template<unsigned Limit = 0> inline string& iqreplace(const char*, const char*);
inline unsigned length() const;
@ -37,7 +37,6 @@ namespace nall {
inline bool wildcard(const char*) const;
inline bool iwildcard(const char*) const;
inline lstring lwildcard(const char*) const;
inline bool beginswith(const char*) const;
inline bool ibeginswith(const char*) const;
@ -52,10 +51,12 @@ namespace nall {
template<unsigned limit = 0> inline string& ltrim(const char *key = " ");
template<unsigned limit = 0> inline string& rtrim(const char *key = " ");
template<unsigned limit = 0> inline string& trim (const char *key = " ");
template<unsigned limit = 0> inline string& trim(const char *key = " ", const char *rkey = 0);
inline optional<unsigned> position(const char *key) const;
inline optional<unsigned> iposition(const char *key) const;
inline optional<unsigned> qposition(const char *key) const;
inline optional<unsigned> iqposition(const char *key) const;
inline operator const char*() const;
inline char* operator()();
@ -76,10 +77,16 @@ namespace nall {
inline string(string&&);
inline ~string();
//internal functions
inline string& assign_(const char*);
inline string& append_(const char*);
protected:
char *data;
unsigned size;
template<unsigned Limit, bool Insensitive, bool Quoted> inline string& ureplace(const char*, const char*);
#if defined(QSTRING_H)
public:
inline operator QString() const;
@ -91,24 +98,28 @@ namespace nall {
template<typename T> inline lstring& operator<<(T value);
inline optional<unsigned> find(const char*) const;
template<unsigned limit = 0> inline void split (const char*, const char*);
template<unsigned limit = 0> inline void qsplit(const char*, const char*);
template<unsigned Limit = 0> inline lstring& split(const char*, const char*);
template<unsigned Limit = 0> inline lstring& isplit(const char*, const char*);
template<unsigned Limit = 0> inline lstring& qsplit(const char*, const char*);
template<unsigned Limit = 0> inline lstring& iqsplit(const char*, const char*);
lstring();
lstring(std::initializer_list<string>);
protected:
template<unsigned Limit, bool Insensitive, bool Quoted> inline lstring& usplit(const char*, const char*);
};
//compare.hpp
inline char chrlower(char c);
inline char chrupper(char c);
inline int stricmp(const char *str1, const char *str2);
inline int istrcmp(const char *str1, const char *str2);
inline bool wildcard(const char *str, const char *pattern);
inline bool iwildcard(const char *str, const char *pattern);
inline lstring lwildcard(const char *str, const char *pattern);
inline bool strbegin(const char *str, const char *key);
inline bool stribegin(const char *str, const char *key);
inline bool istrbegin(const char *str, const char *key);
inline bool strend(const char *str, const char *key);
inline bool striend(const char *str, const char *key);
inline bool istrend(const char *str, const char *key);
//convert.hpp
inline char* strlower(char *str);
@ -137,27 +148,31 @@ namespace nall {
//strpos.hpp
inline optional<unsigned> strpos(const char *str, const char *key);
inline optional<unsigned> istrpos(const char *str, const char *key);
inline optional<unsigned> qstrpos(const char *str, const char *key);
inline optional<unsigned> iqstrpos(const char *str, const char *key);
template<bool Insensitive = false, bool Quoted = false> inline optional<unsigned> ustrpos(const char *str, const char *key);
//trim.hpp
template<unsigned limit = 0> inline char* ltrim(char *str, const char *key = " ");
template<unsigned limit = 0> inline char* rtrim(char *str, const char *key = " ");
template<unsigned limit = 0> inline char* trim (char *str, const char *key = " ");
template<unsigned limit = 0> inline char* trim(char *str, const char *key = " ", const char *rkey = 0);
//utility.hpp
template<bool Insensitive> alwaysinline bool chrequal(char x, char y);
template<bool Quoted, typename T> alwaysinline bool quoteskip(T *&p);
template<bool Quoted, typename T> alwaysinline bool quotecopy(char *&t, T *&p);
inline unsigned strlcpy(string &dest, const char *src, unsigned length);
inline unsigned strlcat(string &dest, const char *src, unsigned length);
inline string substr(const char *src, unsigned start = 0, unsigned length = ~0u);
inline string sha256(const uint8_t *data, unsigned size);
inline string integer(intmax_t value);
template<unsigned length = 0> inline string linteger(intmax_t value);
template<unsigned length = 0> inline string rinteger(intmax_t value);
inline string decimal(uintmax_t value);
template<unsigned length = 0> inline string ldecimal(uintmax_t value);
template<unsigned length = 0> inline string rdecimal(uintmax_t value);
template<unsigned length = 0> inline string hex(uintmax_t value);
template<unsigned length = 0> inline string binary(uintmax_t value);
template<unsigned length = 0, char padding = ' '> inline string integer(intmax_t value);
template<unsigned length = 0, char padding = ' '> inline string linteger(intmax_t value);
template<unsigned length = 0, char padding = ' '> inline string decimal(uintmax_t value);
template<unsigned length = 0, char padding = ' '> inline string ldecimal(uintmax_t value);
template<unsigned length = 0, char padding = '0'> inline string hex(uintmax_t value);
template<unsigned length = 0, char padding = '0'> inline string binary(uintmax_t value);
inline unsigned fp(char *str, double value);
inline string fp(double value);

View File

@ -11,7 +11,7 @@ char chrupper(char c) {
return (c >= 'a' && c <= 'z') ? c - ('a' - 'A') : c;
}
int stricmp(const char *str1, const char *str2) {
int istrcmp(const char *str1, const char *str2) {
while(*str1) {
if(chrlower(*str1) != chrlower(*str2)) break;
str1++, str2++;
@ -59,39 +59,6 @@ bool iwildcard(const char *s, const char *p) {
return !*p;
}
lstring lwildcard(const char *s, const char *p) {
lstring output;
array<const char*> sp, ep;
const char *cp = 0, *mp = 0;
while(*s && *p != '*') {
if(*p != '?' && *s != *p) return output;
p++, s++;
}
while(*s) {
if(*p == '*') {
sp.append(s), ep.append(s);
if(!*++p) {
while(*s) s++;
ep[ep.size() - 1] = s;
break;
}
mp = p, cp = s + 1;
} else if(*p == '?' || *p == *s) {
p++, s++;
} else {
ep[ep.size() - 1] = cp;
p = mp, s = cp++;
}
}
while(*p == '*') p++;
if(*p) return output;
for(unsigned n = 0; n < sp.size(); n++) {
output.append(substr(sp[n], 0, ep[n] - sp[n]));
}
return output;
}
bool strbegin(const char *str, const char *key) {
int i, ssl = strlen(str), ksl = strlen(key);
@ -99,7 +66,7 @@ bool strbegin(const char *str, const char *key) {
return (!memcmp(str, key, ksl));
}
bool stribegin(const char *str, const char *key) {
bool istrbegin(const char *str, const char *key) {
int ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl) return false;
@ -122,7 +89,7 @@ bool strend(const char *str, const char *key) {
return (!memcmp(str + ssl - ksl, key, ksl));
}
bool striend(const char *str, const char *key) {
bool istrend(const char *str, const char *key) {
int ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl) return false;

View File

@ -3,100 +3,49 @@
namespace nall {
string& string::replace(const char *key, const char *token) {
int i, z, ksl = strlen(key), tsl = strlen(token), ssl = length();
unsigned int replace_count = 0, size = ssl;
char *buffer;
template<unsigned Limit, bool Insensitive, bool Quoted>
string& string::ureplace(const char *key, const char *token) {
if(!key || !*key) return *this;
enum : unsigned { limit = Limit ? Limit : ~0u };
if(ksl <= ssl) {
if(tsl > ksl) { //the new string may be longer than the old string...
for(i = 0; i <= ssl - ksl;) { //so let's find out how big of a string we'll need...
if(!memcmp(data + i, key, ksl)) {
replace_count++;
i += ksl;
} else i++;
}
size = ssl + ((tsl - ksl) * replace_count);
reserve(size);
}
const char *p = data;
unsigned counter = 0, keyLength = 0;
buffer = new char[size + 1];
for(i = z = 0; i < ssl;) {
if(i <= ssl - ksl) {
if(!memcmp(data + i, key, ksl)) {
memcpy(buffer + z, token, tsl);
z += tsl;
i += ksl;
} else buffer[z++] = data[i++];
} else buffer[z++] = data[i++];
while(*p) {
if(quoteskip<Quoted>(p)) continue;
for(unsigned n = 0;; n++) {
if(key[n] == 0) { counter++; p += n; keyLength = n; break; }
if(!chrequal<Insensitive>(key[n], p[n])) { p++; break; }
}
buffer[z] = 0;
}
if(counter == 0) return *this;
if(Limit) counter = min(counter, Limit);
assign(buffer);
delete[] buffer;
char *t = data, *base;
unsigned tokenLength = strlen(token);
if(tokenLength > keyLength) {
t = base = strdup(data);
reserve((unsigned)(p - data) + ((tokenLength - keyLength) * counter));
}
char *o = data;
while(*t && counter) {
if(quotecopy<Quoted>(o, t)) continue;
for(unsigned n = 0;; n++) {
if(key[n] == 0) { counter--; memcpy(o, token, tokenLength); t += keyLength; o += tokenLength; break; }
if(!chrequal<Insensitive>(key[n], t[n])) { *o++ = *t++; break; }
}
}
do *o++ = *t; while(*t++);
if(tokenLength > keyLength) free(base);
return *this;
}
string& string::qreplace(const char *key, const char *token) {
int i, l, z, ksl = strlen(key), tsl = strlen(token), ssl = length();
unsigned int replace_count = 0, size = ssl;
uint8_t x;
char *buffer;
if(ksl <= ssl) {
if(tsl > ksl) {
for(i = 0; i <= ssl - ksl;) {
x = data[i];
if(x == '\"' || x == '\'') {
l = i;
i++;
while(data[i++] != x) {
if(i == ssl) {
i = l;
break;
}
}
}
if(!memcmp(data + i, key, ksl)) {
replace_count++;
i += ksl;
} else i++;
}
size = ssl + ((tsl - ksl) * replace_count);
reserve(size);
}
buffer = new char[size + 1];
for(i = z = 0; i < ssl;) {
x = data[i];
if(x == '\"' || x == '\'') {
l = i++;
while(data[i] != x && i < ssl)i++;
if(i >= ssl)i = l;
else {
memcpy(buffer + z, data + l, i - l);
z += i - l;
}
}
if(i <= ssl - ksl) {
if(!memcmp(data + i, key, ksl)) {
memcpy(buffer + z, token, tsl);
z += tsl;
i += ksl;
replace_count++;
} else buffer[z++] = data[i++];
} else buffer[z++] = data[i++];
}
buffer[z] = 0;
assign(buffer);
delete[] buffer;
}
return *this;
}
template<unsigned Limit> string &string::replace(const char *key, const char *token) { return ureplace<Limit, false, false>(key, token); }
template<unsigned Limit> string &string::ireplace(const char *key, const char *token) { return ureplace<Limit, true, false>(key, token); }
template<unsigned Limit> string &string::qreplace(const char *key, const char *token) { return ureplace<Limit, false, true>(key, token); }
template<unsigned Limit> string &string::iqreplace(const char *key, const char *token) { return ureplace<Limit, true, true>(key, token); }
};

View File

@ -3,55 +3,35 @@
namespace nall {
template<unsigned Limit> void lstring::split(const char *key, const char *src) {
unsigned limit = Limit;
template<unsigned Limit, bool Insensitive, bool Quoted> lstring& lstring::usplit(const char *key, const char *base) {
reset();
if(!key || !*key) return *this;
int ssl = strlen(src), ksl = strlen(key);
int lp = 0, split_count = 0;
const char *p = base;
unsigned counter = 0;
for(int i = 0; i <= ssl - ksl;) {
if(!memcmp(src + i, key, ksl)) {
strlcpy(operator[](split_count++), src + lp, i - lp + 1);
i += ksl;
lp = i;
if(!--limit) break;
} else i++;
while(*p) {
if(Limit) if(counter >= Limit) break;
if(quoteskip<Quoted>(p)) continue;
for(unsigned n = 0;; n++) {
if(key[n] == 0) {
strlcpy(operator[](counter++), base, (unsigned)(p - base + 1));
p += n;
base = p;
break;
}
operator[](split_count++) = src + lp;
}
template<unsigned Limit> void lstring::qsplit(const char *key, const char *src) {
unsigned limit = Limit;
reset();
int ssl = strlen(src), ksl = strlen(key);
int lp = 0, split_count = 0;
for(int i = 0; i <= ssl - ksl;) {
uint8_t x = src[i];
if(x == '\"' || x == '\'') {
int z = i++; //skip opening quote
while(i < ssl && src[i] != x) i++;
if(i >= ssl) i = z; //failed match, rewind i
else {
i++; //skip closing quote
continue; //restart in case next char is also a quote
if(!chrequal<Insensitive>(key[n], p[n])) { p++; break; }
}
}
if(!memcmp(src + i, key, ksl)) {
strlcpy(operator[](split_count++), src + lp, i - lp + 1);
i += ksl;
lp = i;
if(!--limit) break;
} else i++;
operator[](counter) = base;
return *this;
}
operator[](split_count++) = src + lp;
}
template<unsigned Limit> lstring& lstring::split(const char *key, const char *src) { return usplit<Limit, false, false>(key, src); }
template<unsigned Limit> lstring& lstring::isplit(const char *key, const char *src) { return usplit<Limit, true, false>(key, src); }
template<unsigned Limit> lstring& lstring::qsplit(const char *key, const char *src) { return usplit<Limit, false, true>(key, src); }
template<unsigned Limit> lstring& lstring::iqsplit(const char *key, const char *src) { return usplit<Limit, true, true>(key, src); }
};

View File

@ -2,39 +2,32 @@
#define NALL_STRING_STRPOS_HPP
//usage example:
//if(auto pos = strpos(str, key)) print(pos(), "\n");
//prints position of key within str, only if it is found
//if(auto position = strpos(str, key)) print(position(), "\n");
//prints position of key within str; but only if it is found
namespace nall {
optional<unsigned> strpos(const char *str, const char *key) {
unsigned ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl) return { false, 0 };
template<bool Insensitive, bool Quoted>
optional<unsigned> ustrpos(const char *str, const char *key) {
const char *base = str;
for(unsigned i = 0; i <= ssl - ksl; i++) {
if(!memcmp(str + i, key, ksl)) return { true, i };
while(*str) {
if(quoteskip<Quoted>(str)) continue;
for(unsigned n = 0;; n++) {
if(key[n] == 0) return { true, (unsigned)(str - base) };
if(str[n] == 0) return { false, 0 };
if(!chrequal<Insensitive>(str[n], key[n])) break;
}
str++;
}
return { false, 0 };
}
optional<unsigned> qstrpos(const char *str, const char *key) {
unsigned ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl) return { false, 0 };
for(unsigned i = 0; i <= ssl - ksl;) {
uint8_t x = str[i];
if(x == '\"' || x == '\'') {
uint8_t z = i++;
while(str[i] != x && i < ssl) i++;
if(i >= ssl) i = z;
}
if(!memcmp(str + i, key, ksl)) return { true, i };
i++;
}
return { false, 0 };
}
optional<unsigned> strpos(const char *str, const char *key) { return ustrpos<false, false>(str, key); }
optional<unsigned> istrpos(const char *str, const char *key) { return ustrpos<true, false>(str, key); }
optional<unsigned> qstrpos(const char *str, const char *key) { return ustrpos<false, true>(str, key); }
optional<unsigned> iqstrpos(const char *str, const char *key) { return ustrpos<true, true>(str, key); }
}

View File

@ -29,7 +29,8 @@ template<unsigned Limit> char* rtrim(char *str, const char *key) {
return str;
}
template<unsigned limit> char* trim(char *str, const char *key) {
template<unsigned limit> char* trim(char *str, const char *key, const char *rkey) {
if(rkey) return ltrim<limit>(rtrim<limit>(str, rkey), key);
return ltrim<limit>(rtrim<limit>(str, key), key);
}

View File

@ -3,6 +3,38 @@
namespace nall {
template<bool Insensitive>
bool chrequal(char x, char y) {
if(Insensitive) return chrlower(x) == chrlower(y);
return x == y;
}
template<bool Quoted, typename T>
bool quoteskip(T *&p) {
if(Quoted == false) return false;
if(*p != '\'' && *p != '\"') return false;
while(*p == '\'' || *p == '\"') {
char x = *p++;
while(*p && *p++ != x);
}
return true;
}
template<bool Quoted, typename T>
bool quotecopy(char *&t, T *&p) {
if(Quoted == false) return false;
if(*p != '\'' && *p != '\"') return false;
while(*p == '\'' || *p == '\"') {
char x = *p++;
*t++ = x;
while(*p && *p != x) *t++ = *p++;
*t++ = *p++;
}
return true;
}
unsigned strlcpy(string &dest, const char *src, unsigned length) {
dest.reserve(length);
return strlcpy(dest(), src, length);
@ -39,33 +71,7 @@ string sha256(const uint8_t *data, unsigned size) {
/* arithmetic <> string */
string integer(intmax_t value) {
bool negative = value < 0;
if(negative) value = abs(value);
char buffer[64];
unsigned size = 0;
do {
unsigned n = value % 10;
buffer[size++] = '0' + n;
value /= 10;
} while(value);
buffer[size++] = negative ? '-' : '+';
buffer[size] = 0;
char result[size + 1];
memset(result, '0', size);
result[size] = 0;
for(signed x = size - 1, y = 0; x >= 0 && y < size; x--, y++) {
result[x] = buffer[y];
}
return (const char*)result;
}
template<unsigned length_> string linteger(intmax_t value) {
template<unsigned length_, char padding> string integer(intmax_t value) {
bool negative = value < 0;
if(negative) value = abs(value);
@ -82,34 +88,7 @@ template<unsigned length_> string linteger(intmax_t value) {
unsigned length = (length_ == 0 ? size : length_);
char result[length + 1];
memset(result, ' ', length);
result[length] = 0;
for(signed x = 0, y = size - 1; x < length && y >= 0; x++, y--) {
result[x] = buffer[y];
}
return (const char*)result;
}
template<unsigned length_> string rinteger(intmax_t value) {
bool negative = value < 0;
if(negative) value = abs(value);
char buffer[64];
unsigned size = 0;
do {
unsigned n = value % 10;
buffer[size++] = '0' + n;
value /= 10;
} while(value);
buffer[size++] = negative ? '-' : '+';
buffer[size] = 0;
unsigned length = (length_ == 0 ? size : length_);
char result[length + 1];
memset(result, ' ', length);
memset(result, padding, length);
result[length] = 0;
for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) {
@ -119,29 +98,10 @@ template<unsigned length_> string rinteger(intmax_t value) {
return (const char*)result;
}
string decimal(uintmax_t value) {
char buffer[64];
unsigned size = 0;
do {
unsigned n = value % 10;
buffer[size++] = '0' + n;
value /= 10;
} while(value);
buffer[size] = 0;
char result[size + 1];
memset(result, '0', size);
result[size] = 0;
for(signed x = size - 1, y = 0; x >= 0 && y < size; x--, y++) {
result[x] = buffer[y];
}
return (const char*)result;
}
template<unsigned length_> string ldecimal(uintmax_t value) {
template<unsigned length_, char padding> string linteger(intmax_t value) {
bool negative = value < 0;
if(negative) value = abs(value);
char buffer[64];
unsigned size = 0;
@ -150,11 +110,12 @@ template<unsigned length_> string ldecimal(uintmax_t value) {
buffer[size++] = '0' + n;
value /= 10;
} while(value);
buffer[size++] = negative ? '-' : '+';
buffer[size] = 0;
unsigned length = (length_ == 0 ? size : length_);
char result[length + 1];
memset(result, ' ', length);
memset(result, padding, length);
result[length] = 0;
for(signed x = 0, y = size - 1; x < length && y >= 0; x++, y--) {
@ -164,7 +125,7 @@ template<unsigned length_> string ldecimal(uintmax_t value) {
return (const char*)result;
}
template<unsigned length_> string rdecimal(uintmax_t value) {
template<unsigned length_, char padding> string decimal(uintmax_t value) {
char buffer[64];
unsigned size = 0;
@ -177,7 +138,7 @@ template<unsigned length_> string rdecimal(uintmax_t value) {
unsigned length = (length_ == 0 ? size : length_);
char result[length + 1];
memset(result, ' ', length);
memset(result, padding, length);
result[length] = 0;
for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) {
@ -187,7 +148,30 @@ template<unsigned length_> string rdecimal(uintmax_t value) {
return (const char*)result;
}
template<unsigned length_> string hex(uintmax_t value) {
template<unsigned length_, char padding> string ldecimal(uintmax_t value) {
char buffer[64];
unsigned size = 0;
do {
unsigned n = value % 10;
buffer[size++] = '0' + n;
value /= 10;
} while(value);
buffer[size] = 0;
unsigned length = (length_ == 0 ? size : length_);
char result[length + 1];
memset(result, padding, length);
result[length] = 0;
for(signed x = 0, y = size - 1; x < length && y >= 0; x++, y--) {
result[x] = buffer[y];
}
return (const char*)result;
}
template<unsigned length_, char padding> string hex(uintmax_t value) {
char buffer[64];
unsigned size = 0;
@ -199,7 +183,7 @@ template<unsigned length_> string hex(uintmax_t value) {
unsigned length = (length_ == 0 ? size : length_);
char result[length + 1];
memset(result, '0', length);
memset(result, padding, length);
result[length] = 0;
for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) {
@ -209,7 +193,7 @@ template<unsigned length_> string hex(uintmax_t value) {
return (const char*)result;
}
template<unsigned length_> string binary(uintmax_t value) {
template<unsigned length_, char padding> string binary(uintmax_t value) {
char buffer[256];
unsigned size = 0;
@ -221,7 +205,7 @@ template<unsigned length_> string binary(uintmax_t value) {
unsigned length = (length_ == 0 ? size : length_);
char result[length + 1];
memset(result, '0', length);
memset(result, padding, length);
result[length] = 0;
for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) {

View File

@ -6,17 +6,16 @@ namespace nall {
unsigned string::length() const { return strlen(data); }
bool string::equals(const char *str) const { return !strcmp(data, str); }
bool string::iequals(const char *str) const { return !stricmp(data, str); }
bool string::iequals(const char *str) const { return !istrcmp(data, str); }
bool string::wildcard(const char *str) const { return nall::wildcard(data, str); }
bool string::iwildcard(const char *str) const { return nall::iwildcard(data, str); }
lstring string::lwildcard(const char *str) const { return nall::lwildcard(data, str); }
bool string::beginswith(const char *str) const { return strbegin(data, str); }
bool string::ibeginswith(const char *str) const { return stribegin(data, str); }
bool string::ibeginswith(const char *str) const { return istrbegin(data, str); }
bool string::endswith(const char *str) const { return strend(data, str); }
bool string::iendswith(const char *str) const { return striend(data, str); }
bool string::iendswith(const char *str) const { return istrend(data, str); }
string& string::lower() { nall::strlower(data); return *this; }
string& string::upper() { nall::strupper(data); return *this; }
@ -26,10 +25,12 @@ string& string::transform(const char *before, const char *after) { nall::strtr(d
template<unsigned limit> string& string::ltrim(const char *key) { nall::ltrim<limit>(data, key); return *this; }
template<unsigned limit> string& string::rtrim(const char *key) { nall::rtrim<limit>(data, key); return *this; }
template<unsigned limit> string& string::trim (const char *key) { nall::trim <limit>(data, key); return *this; }
template<unsigned limit> string& string::trim(const char *key, const char *rkey) { nall::trim <limit>(data, key, rkey); return *this; }
optional<unsigned> string::position(const char *key) const { return strpos(data, key); }
optional<unsigned> string::iposition(const char *key) const { return istrpos(data, key); }
optional<unsigned> string::qposition(const char *key) const { return qstrpos(data, key); }
optional<unsigned> string::iqposition(const char *key) const { return iqstrpos(data, key); }
}

View File

@ -8,7 +8,7 @@
namespace nall {
struct unzip {
struct zip {
struct File {
string name;
const uint8_t *data;
@ -18,7 +18,7 @@ struct unzip {
unsigned crc32;
};
inline bool open(const char *filename) {
inline bool open(const string &filename) {
close();
if(fm.open(filename, filemap::mode::read) == false) return false;
if(open(fm.data(), fm.size()) == false) {
@ -100,7 +100,7 @@ struct unzip {
if(fm.open()) fm.close();
}
~unzip() {
~zip() {
close();
}

View File

@ -47,11 +47,12 @@ Window Window::None;
void Window::append(Layout &layout) { state.layout.append(layout); return p.append(layout); }
void Window::append(Menu &menu) { state.menu.append(menu); ((Action&)menu).state.parent = this; return p.append(menu); }
void Window::append(Widget &widget) { state.widget.append(widget); return p.append(widget); }
Color Window::backgroundColor() { return p.backgroundColor(); }
Geometry Window::frameGeometry() { Geometry geometry = p.geometry(), margin = p.frameMargin(); return { geometry.x - margin.x, geometry.y - margin.y, geometry.width + margin.width, geometry.height + margin.height }; }
Geometry Window::frameMargin() { return p.frameMargin(); }
bool Window::focused() { return p.focused(); }
Geometry Window::geometry() { return p.geometry(); }
void Window::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) { state.backgroundColor = true; state.backgroundColorRed = red; state.backgroundColorGreen = green; state.backgroundColorBlue = blue; return p.setBackgroundColor(red, green, blue); }
void Window::setBackgroundColor(const Color &color) { state.backgroundColorOverride = true; state.backgroundColor = color; return p.setBackgroundColor(color); }
void Window::setFrameGeometry(const Geometry &geometry) { Geometry margin = p.frameMargin(); return setGeometry({ geometry.x + margin.x, geometry.y + margin.y, geometry.width - margin.width, geometry.height - margin.height }); }
void Window::setFocused() { return p.setFocused(); }
void Window::setFullScreen(bool fullScreen) { state.fullScreen = fullScreen; return p.setFullScreen(fullScreen); }
@ -93,6 +94,7 @@ RadioItem::RadioItem() : state(*new State), base_from_member<pRadioItem&>(*new p
bool Widget::enabled() { return state.enabled; }
Font& Widget::font() { return p.font(); }
Geometry Widget::geometry() { return state.geometry; }
Geometry Widget::minimumGeometry() { return p.minimumGeometry(); }
void Widget::setEnabled(bool enabled) { state.enabled = enabled; return p.setEnabled(enabled); }
void Widget::setFocused() { return p.setFocused(); }
@ -128,6 +130,11 @@ void HexEdit::setRows(unsigned rows) { state.rows = rows; return p.setRows(rows)
void HexEdit::update() { return p.update(); }
HexEdit::HexEdit() : state(*new State), base_from_member<pHexEdit&>(*new pHexEdit(*this)), Widget(base_from_member<pHexEdit&>::value), p(base_from_member<pHexEdit&>::value) { p.constructor(); }
unsigned HorizontalScrollBar::position() { return p.position(); }
void HorizontalScrollBar::setLength(unsigned length) { state.length = length; return p.setLength(length); }
void HorizontalScrollBar::setPosition(unsigned position) { state.position = position; return p.setPosition(position); }
HorizontalScrollBar::HorizontalScrollBar() : state(*new State), base_from_member<pHorizontalScrollBar&>(*new pHorizontalScrollBar(*this)), Widget(base_from_member<pHorizontalScrollBar&>::value), p(base_from_member<pHorizontalScrollBar&>::value) { p.constructor(); }
unsigned HorizontalSlider::position() { return p.position(); }
void HorizontalSlider::setLength(unsigned length) { state.length = length; return p.setLength(length); }
void HorizontalSlider::setPosition(unsigned position) { state.position = position; return p.setPosition(position); }
@ -172,6 +179,11 @@ void TextEdit::setWordWrap(bool wordWrap) { state.wordWrap = wordWrap; return p.
string TextEdit::text() { return p.text(); }
TextEdit::TextEdit() : state(*new State), base_from_member<pTextEdit&>(*new pTextEdit(*this)), Widget(base_from_member<pTextEdit&>::value), p(base_from_member<pTextEdit&>::value) { p.constructor(); }
unsigned VerticalScrollBar::position() { return p.position(); }
void VerticalScrollBar::setLength(unsigned length) { state.length = length; return p.setLength(length); }
void VerticalScrollBar::setPosition(unsigned position) { state.position = position; return p.setPosition(position); }
VerticalScrollBar::VerticalScrollBar() : state(*new State), base_from_member<pVerticalScrollBar&>(*new pVerticalScrollBar(*this)), Widget(base_from_member<pVerticalScrollBar&>::value), p(base_from_member<pVerticalScrollBar&>::value) { p.constructor(); }
unsigned VerticalSlider::position() { return p.position(); }
void VerticalSlider::setLength(unsigned length) { state.length = length; return p.setLength(length); }
void VerticalSlider::setPosition(unsigned position) { state.position = position; return p.setPosition(position); }

View File

@ -21,6 +21,7 @@ struct pCanvas;
struct pCheckBox;
struct pComboBox;
struct pHexEdit;
struct pHorizontalScrollBar;
struct pHorizontalSlider;
struct pLabel;
struct pLineEdit;
@ -28,6 +29,7 @@ struct pListView;
struct pProgressBar;
struct pRadioBox;
struct pTextEdit;
struct pVerticalScrollBar;
struct pVerticalSlider;
struct pViewport;
@ -43,6 +45,12 @@ struct Geometry {
inline Geometry(signed x, signed y, unsigned width, unsigned height) : x(x), y(y), width(width), height(height) {}
};
struct Color {
uint8_t red, green, blue, alpha;
inline Color() : red(0), green(0), blue(0), alpha(255) {}
inline Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha = 255) : red(red), green(green), blue(blue), alpha(alpha) {}
};
struct Object {
Object();
Object& operator=(const Object&) = delete;
@ -124,11 +132,12 @@ struct Window : Object {
void append(Layout &layout);
void append(Menu &menu);
void append(Widget &widget);
Color backgroundColor();
Geometry frameGeometry();
Geometry frameMargin();
bool focused();
Geometry geometry();
void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue);
void setBackgroundColor(const Color &color);
void setFrameGeometry(const Geometry &geometry);
void setFocused();
void setFullScreen(bool fullScreen = true);
@ -223,6 +232,7 @@ struct Layout : Object {
struct Widget : Object {
bool enabled();
Font& font();
Geometry geometry();
Geometry minimumGeometry();
void setEnabled(bool enabled = true);
void setFocused();
@ -300,6 +310,19 @@ struct HexEdit : private nall::base_from_member<pHexEdit&>, Widget {
pHexEdit &p;
};
struct HorizontalScrollBar : private nall::base_from_member<pHorizontalScrollBar&>, Widget {
nall::function<void ()> onChange;
unsigned position();
void setLength(unsigned length);
void setPosition(unsigned position);
HorizontalScrollBar();
struct State;
State &state;
pHorizontalScrollBar &p;
};
struct HorizontalSlider : private nall::base_from_member<pHorizontalSlider&>, Widget {
nall::function<void ()> onChange;
@ -406,6 +429,19 @@ struct TextEdit : private nall::base_from_member<pTextEdit&>, Widget {
pTextEdit &p;
};
struct VerticalScrollBar : private nall::base_from_member<pVerticalScrollBar&>, Widget {
nall::function<void ()> onChange;
unsigned position();
void setLength(unsigned length);
void setPosition(unsigned position);
VerticalScrollBar();
struct State;
State &state;
pVerticalScrollBar &p;
};
struct VerticalSlider : private nall::base_from_member<pVerticalSlider&>, Widget {
nall::function<void ()> onChange;

View File

@ -24,8 +24,8 @@ struct Timer::State {
};
struct Window::State {
bool backgroundColor;
unsigned backgroundColorRed, backgroundColorGreen, backgroundColorBlue;
bool backgroundColorOverride;
Color backgroundColor;
bool fullScreen;
Geometry geometry;
reference_array<Layout&> layout;
@ -42,10 +42,8 @@ struct Window::State {
Font *widgetFont;
State() {
backgroundColor = false;
backgroundColorRed = 0;
backgroundColorGreen = 0;
backgroundColorBlue = 0;
backgroundColorOverride = false;
backgroundColor = { 0, 0, 0, 255 };
fullScreen = false;
geometry = { 128, 128, 256, 256 };
menuFont = 0;
@ -152,6 +150,16 @@ struct HexEdit::State {
}
};
struct HorizontalScrollBar::State {
unsigned length;
unsigned position;
State() {
length = 101;
position = 0;
}
};
struct HorizontalSlider::State {
unsigned length;
unsigned position;
@ -223,6 +231,16 @@ struct TextEdit::State {
}
};
struct VerticalScrollBar::State {
unsigned length;
unsigned position;
State() {
length = 101;
position = 0;
}
};
struct VerticalSlider::State {
unsigned length;
unsigned position;

View File

@ -19,6 +19,7 @@
#include "widget/check-box.cpp"
#include "widget/combo-box.cpp"
#include "widget/hex-edit.cpp"
#include "widget/horizontal-scroll-bar.cpp"
#include "widget/horizontal-slider.cpp"
#include "widget/label.cpp"
#include "widget/line-edit.cpp"
@ -26,6 +27,7 @@
#include "widget/progress-bar.cpp"
#include "widget/radio-box.cpp"
#include "widget/text-edit.cpp"
#include "widget/vertical-scroll-bar.cpp"
#include "widget/vertical-slider.cpp"
#include "widget/viewport.cpp"

View File

@ -82,14 +82,16 @@ struct pWindow : public pObject {
GtkWidget *statusContainer;
GtkWidget *menu;
GtkWidget *status;
GdkEventConfigure lastConfigure;
void append(Layout &layout);
void append(Menu &menu);
void append(Widget &widget);
Color backgroundColor();
bool focused();
Geometry frameMargin();
Geometry geometry();
void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue);
void setBackgroundColor(const Color &color);
void setFocused();
void setFullScreen(bool fullScreen);
void setGeometry(const Geometry &geometry);
@ -202,8 +204,7 @@ struct pButton : public pWidget {
struct pCanvas : public pWidget {
Canvas &canvas;
uint32_t *bufferRGB;
uint32_t *bufferBGR;
cairo_surface_t *surface;
uint32_t* buffer();
void setGeometry(const Geometry &geometry);
@ -211,7 +212,6 @@ struct pCanvas : public pWidget {
pCanvas(Canvas &canvas) : pWidget(canvas), canvas(canvas) {}
void constructor();
void redraw();
};
struct pCheckBox : public pWidget {
@ -264,6 +264,18 @@ struct pHexEdit : public pWidget {
void updateScroll();
};
struct pHorizontalScrollBar : public pWidget {
HorizontalScrollBar &horizontalScrollBar;
Geometry minimumGeometry();
unsigned position();
void setLength(unsigned length);
void setPosition(unsigned position);
pHorizontalScrollBar(HorizontalScrollBar &horizontalScrollBar) : pWidget(horizontalScrollBar), horizontalScrollBar(horizontalScrollBar) {}
void constructor();
};
struct pHorizontalSlider : public pWidget {
HorizontalSlider &horizontalSlider;
@ -368,6 +380,18 @@ struct pTextEdit : public pWidget {
void constructor();
};
struct pVerticalScrollBar : public pWidget {
VerticalScrollBar &verticalScrollBar;
Geometry minimumGeometry();
unsigned position();
void setLength(unsigned length);
void setPosition(unsigned position);
pVerticalScrollBar(VerticalScrollBar &verticalScrollBar) : pWidget(verticalScrollBar), verticalScrollBar(verticalScrollBar) {}
void constructor();
};
struct pVerticalSlider : public pWidget {
VerticalSlider &verticalSlider;

View File

@ -1,17 +1,21 @@
static void Canvas_expose(pCanvas *self) {
self->redraw();
static gboolean Canvas_expose(GtkWidget *widget, GdkEvent *event, pCanvas *self) {
cairo_t *context = gdk_cairo_create(gtk_widget_get_window(widget));
cairo_set_source_surface(context, self->surface, 0, 0);
cairo_paint(context);
cairo_destroy(context);
return true;
}
uint32_t* pCanvas::buffer() {
return bufferRGB;
return (uint32_t*)cairo_image_surface_get_data(surface);
}
void pCanvas::setGeometry(const Geometry &geometry) {
delete[] bufferRGB;
delete[] bufferBGR;
if(geometry.width == cairo_image_surface_get_width(surface)
&& geometry.height == cairo_image_surface_get_height(surface)) return;
bufferRGB = new uint32_t[geometry.width * geometry.height]();
bufferBGR = new uint32_t[geometry.width * geometry.height]();
cairo_surface_destroy(surface);
surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, geometry.width, geometry.height);
pWidget::setGeometry(geometry);
update();
@ -19,41 +23,16 @@ void pCanvas::setGeometry(const Geometry &geometry) {
void pCanvas::update() {
if(gtk_widget_get_realized(gtkWidget) == false) return;
GdkRectangle rect;
rect.x = 0;
rect.y = 0;
rect.width = gtkWidget->allocation.width;
rect.height = gtkWidget->allocation.height;
gdk_window_invalidate_rect(gtkWidget->window, &rect, true);
gdk_window_invalidate_rect(gtk_widget_get_window(gtkWidget), 0, true);
}
void pCanvas::constructor() {
bufferRGB = new uint32_t[256 * 256]();
bufferBGR = new uint32_t[256 * 256]();
surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 256, 256);
gtkWidget = gtk_drawing_area_new();
GdkColor color;
color.pixel = color.red = color.green = color.blue = 0;
gtk_widget_modify_bg(gtkWidget, GTK_STATE_NORMAL, &color);
gtk_widget_set_double_buffered(gtkWidget, false);
gtk_widget_add_events(gtkWidget, GDK_EXPOSURE_MASK);
g_signal_connect_swapped(G_OBJECT(gtkWidget), "expose_event", G_CALLBACK(Canvas_expose), (gpointer)this);
}
void pCanvas::redraw() {
if(gtk_widget_get_realized(gtkWidget) == false) return;
uint32_t *rgb = bufferRGB, *bgr = bufferBGR;
for(unsigned y = gtkWidget->allocation.height; y; y--) {
for(unsigned x = gtkWidget->allocation.width; x; x--) {
uint32_t pixel = *rgb++;
*bgr++ = ((pixel << 16) & 0xff0000) | (pixel & 0x00ff00) | ((pixel >> 16) & 0x0000ff);
}
}
gdk_draw_rgb_32_image(
gtkWidget->window,
gtkWidget->style->fg_gc[GTK_WIDGET_STATE(gtkWidget)],
0, 0, gtkWidget->allocation.width, gtkWidget->allocation.height,
GDK_RGB_DITHER_NONE, (guchar*)bufferBGR, sizeof(uint32_t) * gtkWidget->allocation.width
);
g_signal_connect(G_OBJECT(gtkWidget), "expose_event", G_CALLBACK(Canvas_expose), (gpointer)this);
}

View File

@ -18,9 +18,7 @@ Geometry pComboBox::minimumGeometry() {
void pComboBox::reset() {
locked = true;
for(signed n = itemCounter - 1; n >= 0; n--) {
gtk_combo_box_remove_text(GTK_COMBO_BOX(gtkWidget), n);
}
gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(gtkWidget))));
itemCounter = 0;
locked = false;
}

View File

@ -112,17 +112,17 @@ bool pHexEdit::keyPress(unsigned scancode) {
unsigned cursorY = position / lineWidth;
unsigned cursorX = position % lineWidth;
if(scancode == GDK_Home) {
if(scancode == GDK_KEY_Home) {
setCursorPosition(cursorY * lineWidth + 10);
return true;
}
if(scancode == GDK_End) {
if(scancode == GDK_KEY_End) {
setCursorPosition(cursorY * lineWidth + 10 + (hexEdit.state.columns * 3 - 1));
return true;
}
if(scancode == GDK_Up) {
if(scancode == GDK_KEY_Up) {
if(cursorY != 0) return false;
signed newOffset = hexEdit.state.offset - hexEdit.state.columns;
@ -133,7 +133,7 @@ bool pHexEdit::keyPress(unsigned scancode) {
return true;
}
if(scancode == GDK_Down) {
if(scancode == GDK_KEY_Down) {
if(cursorY != hexEdit.state.rows - 1) return false;
signed newOffset = hexEdit.state.offset + hexEdit.state.columns;
@ -144,7 +144,7 @@ bool pHexEdit::keyPress(unsigned scancode) {
return true;
}
if(scancode == GDK_Page_Up) {
if(scancode == GDK_KEY_Page_Up) {
signed newOffset = hexEdit.state.offset - hexEdit.state.columns * hexEdit.state.rows;
if(newOffset >= 0) {
hexEdit.setOffset(newOffset);
@ -155,7 +155,7 @@ bool pHexEdit::keyPress(unsigned scancode) {
return true;
}
if(scancode == GDK_Page_Down) {
if(scancode == GDK_KEY_Page_Down) {
signed newOffset = hexEdit.state.offset + hexEdit.state.columns * hexEdit.state.rows;
for(unsigned n = 0; n < hexEdit.state.rows; n++) {
if(newOffset + hexEdit.state.columns * hexEdit.state.rows - (hexEdit.state.columns - 1) <= hexEdit.state.length) {

View File

@ -0,0 +1,29 @@
static void HorizontalScrollBar_change(HorizontalScrollBar *self) {
if(self->state.position == self->position()) return;
self->state.position = self->position();
if(self->onChange) self->onChange();
}
Geometry pHorizontalScrollBar::minimumGeometry() {
return { 0, 0, 0, 20 };
}
unsigned pHorizontalScrollBar::position() {
return (unsigned)gtk_range_get_value(GTK_RANGE(gtkWidget));
}
void pHorizontalScrollBar::setLength(unsigned length) {
length += length == 0;
gtk_range_set_range(GTK_RANGE(gtkWidget), 0, length - 1);
gtk_range_set_increments(GTK_RANGE(gtkWidget), 1, length >> 3);
}
void pHorizontalScrollBar::setPosition(unsigned position) {
gtk_range_set_value(GTK_RANGE(gtkWidget), position);
}
void pHorizontalScrollBar::constructor() {
gtkWidget = gtk_hscrollbar_new(0);
setLength(101);
g_signal_connect_swapped(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(HorizontalScrollBar_change), (gpointer)&horizontalScrollBar);
}

View File

@ -15,6 +15,7 @@ unsigned pHorizontalSlider::position() {
void pHorizontalSlider::setLength(unsigned length) {
length += length == 0;
gtk_range_set_range(GTK_RANGE(gtkWidget), 0, length - 1);
gtk_range_set_increments(GTK_RANGE(gtkWidget), 1, length >> 3);
}
void pHorizontalSlider::setPosition(unsigned position) {
@ -24,5 +25,6 @@ void pHorizontalSlider::setPosition(unsigned position) {
void pHorizontalSlider::constructor() {
gtkWidget = gtk_hscale_new_with_range(0, 100, 1);
gtk_scale_set_draw_value(GTK_SCALE(gtkWidget), false);
setLength(101);
g_signal_connect_swapped(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(HorizontalSlider_change), (gpointer)&horizontalSlider);
}

View File

@ -13,7 +13,7 @@ Geometry pLineEdit::minimumGeometry() {
}
void pLineEdit::setEditable(bool editable) {
gtk_entry_set_editable(GTK_ENTRY(gtkWidget), editable);
gtk_editable_set_editable(GTK_EDITABLE(gtkWidget), editable);
}
void pLineEdit::setText(const string &text) {

View File

@ -0,0 +1,29 @@
static void VerticalScrollBar_change(VerticalScrollBar *self) {
if(self->state.position == self->position()) return;
self->state.position = self->position();
if(self->onChange) self->onChange();
}
Geometry pVerticalScrollBar::minimumGeometry() {
return { 0, 0, 20, 0 };
}
unsigned pVerticalScrollBar::position() {
return (unsigned)gtk_range_get_value(GTK_RANGE(gtkWidget));
}
void pVerticalScrollBar::setLength(unsigned length) {
length += length == 0;
gtk_range_set_range(GTK_RANGE(gtkWidget), 0, length - 1);
gtk_range_set_increments(GTK_RANGE(gtkWidget), 1, length >> 3);
}
void pVerticalScrollBar::setPosition(unsigned position) {
gtk_range_set_value(GTK_RANGE(gtkWidget), position);
}
void pVerticalScrollBar::constructor() {
gtkWidget = gtk_vscrollbar_new(0);
setLength(101);
g_signal_connect_swapped(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(VerticalScrollBar_change), (gpointer)&verticalScrollBar);
}

View File

@ -15,6 +15,7 @@ unsigned pVerticalSlider::position() {
void pVerticalSlider::setLength(unsigned length) {
length += length == 0;
gtk_range_set_range(GTK_RANGE(gtkWidget), 0, length - 1);
gtk_range_set_increments(GTK_RANGE(gtkWidget), 1, length >> 3);
}
void pVerticalSlider::setPosition(unsigned position) {
@ -24,5 +25,6 @@ void pVerticalSlider::setPosition(unsigned position) {
void pVerticalSlider::constructor() {
gtkWidget = gtk_vscale_new_with_range(0, 100, 1);
gtk_scale_set_draw_value(GTK_SCALE(gtkWidget), false);
setLength(101);
g_signal_connect_swapped(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(VerticalSlider_change), (gpointer)&verticalSlider);
}

View File

@ -1,5 +1,5 @@
uintptr_t pViewport::handle() {
return GDK_WINDOW_XID(gtkWidget->window);
return GDK_WINDOW_XID(gtk_widget_get_window(gtkWidget));
}
void pViewport::constructor() {

View File

@ -1,60 +1,45 @@
static void Action_setFont(GtkWidget *widget, gpointer font);
static void Widget_setFont(GtkWidget *widget, gpointer font);
static gint Window_close(Window *window) {
static gint Window_close(GtkWidget *widget, GdkEvent *event, Window *window) {
if(window->onClose) window->onClose();
window->setVisible(false);
return true;
}
static gboolean Window_configure(Window *window) {
static gboolean Window_configure(GtkWidget *widget, GdkEvent *event, Window *window) {
if(gtk_widget_get_realized(window->p.widget) == false) return false;
GdkWindow *gdkWindow = gtk_widget_get_window(widget);
//update geometry settings
Display *display = XOpenDisplay(0);
XWindowAttributes attributes, parentAttributes;
XGetWindowAttributes(display, GDK_WINDOW_XID(window->p.widget->window), &attributes);
X11Window rootWindow, parentWindow, *childWindow = 0;
unsigned int childCount;
XQueryTree(display, GDK_WINDOW_XID(window->p.widget->window), &rootWindow, &parentWindow, &childWindow, &childCount);
XGetWindowAttributes(display, parentWindow, &parentAttributes);
if(childWindow) XFree(childWindow);
XCloseDisplay(display);
GdkRectangle border, client;
gdk_window_get_frame_extents(gdkWindow, &border);
gdk_window_get_geometry(gdkWindow, 0, 0, &client.width, &client.height, 0);
gdk_window_get_origin(gdkWindow, &client.x, &client.y);
settings.frameGeometryX = attributes.x;
settings.frameGeometryY = attributes.y;
settings.frameGeometryWidth = parentAttributes.width - attributes.width;
settings.frameGeometryHeight = parentAttributes.height - attributes.height;
GtkAllocation menuAllocation, statusAllocation;
gtk_widget_get_allocation(window->p.menu, &menuAllocation);
gtk_widget_get_allocation(window->p.status, &statusAllocation);
if(menuAllocation.height > 1) settings.menuGeometryHeight = menuAllocation.height;
if(statusAllocation.height > 1) settings.statusGeometryHeight = statusAllocation.height;
//calculate current window position
signed eventX = parentAttributes.x + attributes.x;
signed eventY = parentAttributes.y + attributes.y + window->p.menuHeight();
unsigned eventWidth = attributes.width;
unsigned eventHeight = attributes.height - window->p.menuHeight() - window->p.statusHeight();
settings.frameGeometryX = client.x - border.x;
settings.frameGeometryY = client.y - border.y;
settings.frameGeometryWidth = border.width - client.width;
settings.frameGeometryHeight = border.height - client.height;
//move
if(window->p.locked == false && window->state.fullScreen == false) {
if(window->state.geometry.x != eventX || window->state.geometry.y != eventY) {
window->state.geometry.x = eventX;
window->state.geometry.y = eventY;
if(event->configure.x != window->p.lastConfigure.x
|| event->configure.y != window->p.lastConfigure.y
) {
if(window->state.fullScreen == false) {
window->state.geometry.x = client.x;
window->state.geometry.y = client.y + window->p.menuHeight();
}
if(window->p.locked == false && window->onMove) window->onMove();
}
if(window->onMove) window->onMove();
//size
if(window->p.locked == false && window->state.fullScreen == false) {
if(window->state.geometry.width != eventWidth || window->state.geometry.height != eventHeight) {
window->state.geometry.width = eventWidth;
window->state.geometry.height = eventHeight;
}
if(event->configure.width != window->p.lastConfigure.width
|| event->configure.height != window->p.lastConfigure.height
) {
if(window->state.fullScreen == false) {
window->state.geometry.width = client.width;
window->state.geometry.height = client.height - window->p.menuHeight() - window->p.statusHeight();
}
foreach(layout, window->state.layout) {
@ -63,8 +48,10 @@ static gboolean Window_configure(Window *window) {
layout.setGeometry(geometry);
}
if(window->onSize) window->onSize();
if(window->p.locked == false && window->onSize) window->onSize();
}
window->p.lastConfigure = event->configure;
return false;
}
@ -77,7 +64,7 @@ void pWindow::append(Layout &layout) {
void pWindow::append(Menu &subMenu) {
if(window.state.menuFont) subMenu.p.setFont(*window.state.menuFont);
gtk_menu_bar_append(menu, subMenu.p.widget);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), subMenu.p.widget);
gtk_widget_show(subMenu.p.widget);
}
@ -90,6 +77,12 @@ void pWindow::append(Widget &widget) {
widget.setVisible();
}
Color pWindow::backgroundColor() {
if(window.state.backgroundColorOverride) return window.state.backgroundColor;
GdkColor color = widget->style->bg[GTK_STATE_NORMAL];
return { (uint8_t)(color.red >> 8), (uint8_t)(color.green >> 8), (uint8_t)(color.blue >> 8), 255 };
}
Geometry pWindow::frameMargin() {
if(window.state.fullScreen) return { 0, menuHeight(), 0, menuHeight() + statusHeight() };
return {
@ -111,13 +104,13 @@ Geometry pWindow::geometry() {
return window.state.geometry;
}
void pWindow::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) {
GdkColor color;
color.pixel = (red << 16) | (green << 8) | (blue << 0);
color.red = (red << 8) | (red << 0);
color.green = (green << 8) | (green << 0);
color.blue = (blue << 8) | (blue << 0);
gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &color);
void pWindow::setBackgroundColor(const Color &color) {
GdkColor gdkColor;
gdkColor.pixel = (color.red << 16) | (color.green << 8) | (color.blue << 0);
gdkColor.red = (color.red << 8) | (color.red << 0);
gdkColor.green = (color.green << 8) | (color.green << 0);
gdkColor.blue = (color.blue << 8) | (color.blue << 0);
gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &gdkColor);
}
void pWindow::setFocused() {
@ -129,14 +122,12 @@ void pWindow::setFullScreen(bool fullScreen) {
gtk_window_unfullscreen(GTK_WINDOW(widget));
gtk_window_set_resizable(GTK_WINDOW(widget), window.state.resizable);
gtk_window_set_decorated(GTK_WINDOW(widget), true);
locked = true;
for(unsigned n = 0; n < 4; n++) {
setGeometry(window.state.geometry);
gtk_widget_set_size_request(widget, -1, -1);
OS::processEvents();
usleep(2000);
}
locked = false;
} else {
gtk_window_fullscreen(GTK_WINDOW(widget));
gtk_window_set_decorated(GTK_WINDOW(widget), false);
@ -224,8 +215,8 @@ void pWindow::constructor() {
setTitle("");
setGeometry(window.state.geometry);
g_signal_connect_swapped(G_OBJECT(widget), "delete-event", G_CALLBACK(Window_close), (gpointer)&window);
g_signal_connect_swapped(G_OBJECT(widget), "configure-event", G_CALLBACK(Window_configure), (gpointer)&window);
g_signal_connect(G_OBJECT(widget), "delete-event", G_CALLBACK(Window_close), (gpointer)&window);
g_signal_connect(G_OBJECT(widget), "configure-event", G_CALLBACK(Window_configure), (gpointer)&window);
}
unsigned pWindow::menuHeight() {

View File

@ -22,6 +22,7 @@
#define X11None 0L
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <cairo.h>
#include <gdk/gdkkeysyms.h>

View File

@ -20,6 +20,7 @@
#include "widget/check-box.cpp"
#include "widget/combo-box.cpp"
#include "widget/hex-edit.cpp"
#include "widget/horizontal-scroll-bar.cpp"
#include "widget/horizontal-slider.cpp"
#include "widget/label.cpp"
#include "widget/line-edit.cpp"
@ -27,6 +28,7 @@
#include "widget/progress-bar.cpp"
#include "widget/radio-box.cpp"
#include "widget/text-edit.cpp"
#include "widget/vertical-scroll-bar.cpp"
#include "widget/vertical-slider.cpp"
#include "widget/viewport.cpp"

View File

@ -1,7 +1,7 @@
/****************************************************************************
** Meta object code from reading C++ file 'qt.moc.hpp'
**
** Created: Tue May 24 19:33:16 2011
** Created: Fri Aug 5 17:51:21 2011
** by: The Qt Meta Object Compiler version 62 (Qt 4.7.0)
**
** WARNING! All changes made in this file will be lost!
@ -606,6 +606,67 @@ int pHexEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
}
return _id;
}
static const uint qt_meta_data_pHorizontalScrollBar[] = {
// content:
5, // revision
0, // classname
0, 0, // classinfo
1, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
// slots: signature, parameters, type, tag, flags
22, 21, 21, 21, 0x0a,
0 // eod
};
static const char qt_meta_stringdata_pHorizontalScrollBar[] = {
"pHorizontalScrollBar\0\0onChange()\0"
};
const QMetaObject pHorizontalScrollBar::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_pHorizontalScrollBar,
qt_meta_data_pHorizontalScrollBar, 0 }
};
#ifdef Q_NO_DATA_RELOCATION
const QMetaObject &pHorizontalScrollBar::getStaticMetaObject() { return staticMetaObject; }
#endif //Q_NO_DATA_RELOCATION
const QMetaObject *pHorizontalScrollBar::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
}
void *pHorizontalScrollBar::qt_metacast(const char *_clname)
{
if (!_clname) return 0;
if (!strcmp(_clname, qt_meta_stringdata_pHorizontalScrollBar))
return static_cast<void*>(const_cast< pHorizontalScrollBar*>(this));
if (!strcmp(_clname, "pWidget"))
return static_cast< pWidget*>(const_cast< pHorizontalScrollBar*>(this));
return QObject::qt_metacast(_clname);
}
int pHorizontalScrollBar::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QObject::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) {
case 0: onChange(); break;
default: ;
}
_id -= 1;
}
return _id;
}
static const uint qt_meta_data_pHorizontalSlider[] = {
// content:
@ -918,6 +979,67 @@ int pTextEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
}
return _id;
}
static const uint qt_meta_data_pVerticalScrollBar[] = {
// content:
5, // revision
0, // classname
0, 0, // classinfo
1, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
// slots: signature, parameters, type, tag, flags
20, 19, 19, 19, 0x0a,
0 // eod
};
static const char qt_meta_stringdata_pVerticalScrollBar[] = {
"pVerticalScrollBar\0\0onChange()\0"
};
const QMetaObject pVerticalScrollBar::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_pVerticalScrollBar,
qt_meta_data_pVerticalScrollBar, 0 }
};
#ifdef Q_NO_DATA_RELOCATION
const QMetaObject &pVerticalScrollBar::getStaticMetaObject() { return staticMetaObject; }
#endif //Q_NO_DATA_RELOCATION
const QMetaObject *pVerticalScrollBar::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
}
void *pVerticalScrollBar::qt_metacast(const char *_clname)
{
if (!_clname) return 0;
if (!strcmp(_clname, qt_meta_stringdata_pVerticalScrollBar))
return static_cast<void*>(const_cast< pVerticalScrollBar*>(this));
if (!strcmp(_clname, "pWidget"))
return static_cast< pWidget*>(const_cast< pVerticalScrollBar*>(this));
return QObject::qt_metacast(_clname);
}
int pVerticalScrollBar::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QObject::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) {
case 0: onChange(); break;
default: ;
}
_id -= 1;
}
return _id;
}
static const uint qt_meta_data_pVerticalSlider[] = {
// content:

View File

@ -101,10 +101,11 @@ public:
void append(Layout &layout);
void append(Menu &menu);
void append(Widget &widget);
Color backgroundColor();
Geometry frameMargin();
bool focused();
Geometry geometry();
void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue);
void setBackgroundColor(const Color &color);
void setFocused();
void setFullScreen(bool fullScreen);
void setGeometry(const Geometry &geometry);
@ -330,6 +331,25 @@ public slots:
void onScroll();
};
struct pHorizontalScrollBar : public QObject, public pWidget {
Q_OBJECT
public:
HorizontalScrollBar &horizontalScrollBar;
QScrollBar *qtScrollBar;
Geometry minimumGeometry();
unsigned position();
void setLength(unsigned length);
void setPosition(unsigned position);
pHorizontalScrollBar(HorizontalScrollBar &horizontalScrollBar) : pWidget(horizontalScrollBar), horizontalScrollBar(horizontalScrollBar) {}
void constructor();
public slots:
void onChange();
};
struct pHorizontalSlider : public QObject, public pWidget {
Q_OBJECT
@ -462,6 +482,25 @@ public slots:
void onChange();
};
struct pVerticalScrollBar : public QObject, public pWidget {
Q_OBJECT
public:
VerticalScrollBar &verticalScrollBar;
QScrollBar *qtScrollBar;
Geometry minimumGeometry();
unsigned position();
void setLength(unsigned length);
void setPosition(unsigned position);
pVerticalScrollBar(VerticalScrollBar &verticalScrollBar) : pWidget(verticalScrollBar), verticalScrollBar(verticalScrollBar) {}
void constructor();
public slots:
void onChange();
};
struct pVerticalSlider : public QObject, public pWidget {
Q_OBJECT

View File

@ -0,0 +1,29 @@
Geometry pHorizontalScrollBar::minimumGeometry() {
return { 0, 0, 0, 15 };
}
unsigned pHorizontalScrollBar::position() {
return qtScrollBar->value();
}
void pHorizontalScrollBar::setLength(unsigned length) {
length += length == 0;
qtScrollBar->setRange(0, length - 1);
qtScrollBar->setPageStep(length >> 3);
}
void pHorizontalScrollBar::setPosition(unsigned position) {
qtScrollBar->setValue(position);
}
void pHorizontalScrollBar::constructor() {
qtWidget = qtScrollBar = new QScrollBar(Qt::Horizontal);
qtScrollBar->setRange(0, 100);
qtScrollBar->setPageStep(101 >> 3);
connect(qtScrollBar, SIGNAL(valueChanged(int)), SLOT(onChange()));
}
void pHorizontalScrollBar::onChange() {
horizontalScrollBar.state.position = position();
if(horizontalScrollBar.onChange) horizontalScrollBar.onChange();
}

View File

@ -0,0 +1,29 @@
Geometry pVerticalScrollBar::minimumGeometry() {
return { 0, 0, 15, 0 };
}
unsigned pVerticalScrollBar::position() {
return qtScrollBar->value();
}
void pVerticalScrollBar::setLength(unsigned length) {
length += length == 0;
qtScrollBar->setRange(0, length - 1);
qtScrollBar->setPageStep(length >> 3);
}
void pVerticalScrollBar::setPosition(unsigned position) {
qtScrollBar->setValue(position);
}
void pVerticalScrollBar::constructor() {
qtWidget = qtScrollBar = new QScrollBar(Qt::Vertical);
qtScrollBar->setRange(0, 100);
qtScrollBar->setPageStep(101 >> 3);
connect(qtScrollBar, SIGNAL(valueChanged(int)), SLOT(onChange()));
}
void pVerticalScrollBar::onChange() {
verticalScrollBar.state.position = position();
if(verticalScrollBar.onChange) verticalScrollBar.onChange();
}

View File

@ -18,6 +18,12 @@ void pWindow::append(Widget &widget) {
widget.setVisible(widget.state.visible);
}
Color pWindow::backgroundColor() {
if(window.state.backgroundColorOverride) return window.state.backgroundColor;
QColor color = qtWindow->palette().color(QPalette::ColorRole::Window);
return { (uint8_t)color.red(), (uint8_t)color.green(), (uint8_t)color.blue(), (uint8_t)color.alpha() };
}
Geometry pWindow::frameMargin() {
unsigned menuHeight = window.state.menuVisible ? qtMenu->height() : 0;
unsigned statusHeight = window.state.statusVisible ? qtStatus->height() : 0;
@ -43,9 +49,9 @@ Geometry pWindow::geometry() {
return window.state.geometry;
}
void pWindow::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) {
void pWindow::setBackgroundColor(const Color &color) {
QPalette palette;
palette.setColor(QPalette::Window, QColor(red, green, blue));
palette.setColor(QPalette::Window, QColor(color.red, color.green, color.blue));
qtContainer->setPalette(palette);
qtContainer->setAutoFillBackground(true);
}

View File

@ -18,6 +18,7 @@
#include "widget/check-box.cpp"
#include "widget/combo-box.cpp"
#include "widget/hex-edit.cpp"
#include "widget/horizontal-scroll-bar.cpp"
#include "widget/horizontal-slider.cpp"
#include "widget/label.cpp"
#include "widget/line-edit.cpp"
@ -25,6 +26,7 @@
#include "widget/progress-bar.cpp"
#include "widget/radio-box.cpp"
#include "widget/text-edit.cpp"
#include "widget/vertical-scroll-bar.cpp"
#include "widget/vertical-slider.cpp"
#include "widget/viewport.cpp"

View File

@ -63,10 +63,11 @@ struct pWindow : public pObject {
void append(Layout &layout);
void append(Menu &menu);
void append(Widget &widget);
Color backgroundColor();
bool focused();
Geometry frameMargin();
Geometry geometry();
void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue);
void setBackgroundColor(const Color &color);
void setFocused();
void setFullScreen(bool fullScreen);
void setGeometry(const Geometry &geometry);
@ -214,6 +215,17 @@ struct pHexEdit : public pWidget {
void constructor();
};
struct pHorizontalScrollBar : public pWidget {
HorizontalScrollBar &horizontalScrollBar;
unsigned position();
void setLength(unsigned length);
void setPosition(unsigned position);
pHorizontalScrollBar(HorizontalScrollBar &horizontalScrollBar) : pWidget(horizontalScrollBar), horizontalScrollBar(horizontalScrollBar) {}
void constructor();
};
struct pHorizontalSlider : public pWidget {
HorizontalSlider &horizontalSlider;
@ -300,6 +312,17 @@ struct pTextEdit : public pWidget {
void constructor();
};
struct pVerticalScrollBar : public pWidget {
VerticalScrollBar &verticalScrollBar;
unsigned position();
void setLength(unsigned length);
void setPosition(unsigned position);
pVerticalScrollBar(VerticalScrollBar &verticalScrollBar) : pWidget(verticalScrollBar), verticalScrollBar(verticalScrollBar) {}
void constructor();
};
struct pVerticalSlider : public pWidget {
VerticalSlider &verticalSlider;

View File

@ -0,0 +1,12 @@
unsigned pHorizontalScrollBar::position() {
return 0;
}
void pHorizontalScrollBar::setLength(unsigned length) {
}
void pHorizontalScrollBar::setPosition(unsigned position) {
}
void pHorizontalScrollBar::constructor() {
}

View File

@ -0,0 +1,12 @@
unsigned pVerticalScrollBar::position() {
return 0;
}
void pVerticalScrollBar::setLength(unsigned length) {
}
void pVerticalScrollBar::setPosition(unsigned position) {
}
void pVerticalScrollBar::constructor() {
}

View File

@ -7,6 +7,10 @@ void pWindow::append(Menu &menu) {
void pWindow::append(Widget &widget) {
}
Color pWindow::backgroundColor() {
return { 0, 0, 0, 255 };
}
bool pWindow::focused() {
return false;
}
@ -19,7 +23,7 @@ Geometry pWindow::geometry() {
return { 0, 0, 0, 0 };
}
void pWindow::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) {
void pWindow::setBackgroundColor(const Color &color) {
}
void pWindow::setFocused() {

View File

@ -6,3 +6,4 @@ synchronize() {
}
synchronize "nall"
rm -r nall/test

View File

@ -0,0 +1,32 @@
Geometry pHorizontalScrollBar::minimumGeometry() {
return { 0, 0, 0, 18 };
}
unsigned pHorizontalScrollBar::position() {
return GetScrollPos(hwnd, SB_CTL);
}
void pHorizontalScrollBar::setLength(unsigned length) {
length += (length == 0);
SetScrollRange(hwnd, SB_CTL, 0, length - 1, TRUE);
horizontalScrollBar.setPosition(0);
}
void pHorizontalScrollBar::setPosition(unsigned position) { return;
SetScrollPos(hwnd, SB_CTL, position, TRUE);
}
void pHorizontalScrollBar::constructor() {
setParent(Window::None);
}
void pHorizontalScrollBar::setParent(Window &parent) {
if(hwnd) DestroyWindow(hwnd);
hwnd = CreateWindow(
L"SCROLLBAR", L"", WS_CHILD | WS_VISIBLE | WS_TABSTOP | SBS_HORZ,
0, 0, 0, 0, parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0
);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&horizontalScrollBar);
setLength(horizontalScrollBar.state.length);
setPosition(horizontalScrollBar.state.position);
}

View File

@ -0,0 +1,32 @@
Geometry pVerticalScrollBar::minimumGeometry() {
return { 0, 0, 18, 0 };
}
unsigned pVerticalScrollBar::position() {
return GetScrollPos(hwnd, SB_CTL);
}
void pVerticalScrollBar::setLength(unsigned length) {
length += (length == 0);
SetScrollRange(hwnd, SB_CTL, 0, length - 1, TRUE);
verticalScrollBar.setPosition(0);
}
void pVerticalScrollBar::setPosition(unsigned position) {
SetScrollPos(hwnd, SB_CTL, position, TRUE);
}
void pVerticalScrollBar::constructor() {
setParent(Window::None);
}
void pVerticalScrollBar::setParent(Window &parent) {
if(hwnd) DestroyWindow(hwnd);
hwnd = CreateWindow(
L"SCROLLBAR", L"", WS_CHILD | WS_VISIBLE | SBS_VERT,
0, 0, 0, 0, parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0
);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&verticalScrollBar);
setLength(verticalScrollBar.state.length);
setPosition(verticalScrollBar.state.position);
}

View File

@ -1,5 +1,5 @@
Geometry pVerticalSlider::minimumGeometry() {
return { 0, 0, 25, 0 };
return { 0, 0, 0, 25 };
}
unsigned pVerticalSlider::position() {

View File

@ -16,6 +16,12 @@ void pWindow::append(Widget &widget) {
widget.p.setParent(window);
}
Color pWindow::backgroundColor() {
if(window.state.backgroundColorOverride) return window.state.backgroundColor;
DWORD color = GetSysColor(COLOR_3DFACE);
return { (uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color >> 0), 255 };
}
bool pWindow::focused() {
return (GetForegroundWindow() == hwnd);
}
@ -37,10 +43,15 @@ Geometry pWindow::frameMargin() {
Geometry pWindow::geometry() {
Geometry margin = frameMargin();
//note: GetWindowRect returns -32000(x),-32000(y) when window is minimized
RECT rc;
if(IsIconic(hwnd)) {
//GetWindowRect returns -32000(x),-32000(y) when window is minimized
WINDOWPLACEMENT wp;
GetWindowPlacement(hwnd, &wp);
RECT rc = wp.rcNormalPosition;
rc = wp.rcNormalPosition;
} else {
GetWindowRect(hwnd, &rc);
}
signed x = rc.left + margin.x;
signed y = rc.top + margin.y;
@ -50,9 +61,9 @@ Geometry pWindow::geometry() {
return { x, y, width, height };
}
void pWindow::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) {
void pWindow::setBackgroundColor(const Color &color) {
if(brush) DeleteObject(brush);
brushColor = RGB(red, green, blue);
brushColor = RGB(color.red, color.green, color.blue);
brush = CreateSolidBrush(brushColor);
}

View File

@ -19,6 +19,7 @@
#include "widget/check-box.cpp"
#include "widget/combo-box.cpp"
#include "widget/hex-edit.cpp"
#include "widget/horizontal-scroll-bar.cpp"
#include "widget/horizontal-slider.cpp"
#include "widget/label.cpp"
#include "widget/line-edit.cpp"
@ -26,6 +27,7 @@
#include "widget/progress-bar.cpp"
#include "widget/radio-box.cpp"
#include "widget/text-edit.cpp"
#include "widget/vertical-scroll-bar.cpp"
#include "widget/vertical-slider.cpp"
#include "widget/viewport.cpp"
@ -175,7 +177,7 @@ void pOS::initialize() {
WNDCLASS wc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hIcon = LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(2));
wc.hInstance = GetModuleHandle(0);
@ -199,7 +201,7 @@ void pOS::initialize() {
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hInstance = GetModuleHandle(0);
@ -408,11 +410,58 @@ static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
case WM_HSCROLL:
case WM_VSCROLL: {
Object *object = 0;
if(lparam) {
object = (Object*)GetWindowLongPtr((HWND)lparam, GWLP_USERDATA);
} else {
unsigned id = LOWORD(wparam);
HWND control = GetDlgItem(window.p.hwnd, id);
if(control == 0) break;
Object *object = (Object*)GetWindowLongPtr(control, GWLP_USERDATA);
object = (Object*)GetWindowLongPtr(control, GWLP_USERDATA);
}
if(object == 0) break;
if(dynamic_cast<HorizontalScrollBar*>(object)
|| dynamic_cast<VerticalScrollBar*>(object)) {
SCROLLINFO info;
memset(&info, 0, sizeof(SCROLLINFO));
info.cbSize = sizeof(SCROLLINFO);
info.fMask = SIF_ALL;
GetScrollInfo((HWND)lparam, SB_CTL, &info);
switch(LOWORD(wparam)) {
case SB_LEFT: info.nPos = info.nMin; break;
case SB_RIGHT: info.nPos = info.nMax; break;
case SB_LINELEFT: info.nPos--; break;
case SB_LINERIGHT: info.nPos++; break;
case SB_PAGELEFT: info.nPos -= info.nMax >> 3; break;
case SB_PAGERIGHT: info.nPos += info.nMax >> 3; break;
case SB_THUMBTRACK: info.nPos = info.nTrackPos; break;
}
info.fMask = SIF_POS;
SetScrollInfo((HWND)lparam, SB_CTL, &info, TRUE);
//Windows may clamp position to scrollbar range
GetScrollInfo((HWND)lparam, SB_CTL, &info);
if(dynamic_cast<HorizontalScrollBar*>(object)) {
HorizontalScrollBar &horizontalScrollBar = (HorizontalScrollBar&)*object;
if(horizontalScrollBar.state.position != info.nPos) {
horizontalScrollBar.state.position = info.nPos;
horizontalScrollBar.onChange();
}
} else {
VerticalScrollBar &verticalScrollBar = (VerticalScrollBar&)*object;
if(verticalScrollBar.state.position != info.nPos) {
verticalScrollBar.state.position = info.nPos;
verticalScrollBar.onChange();
}
}
return TRUE;
}
if(dynamic_cast<HorizontalSlider*>(object)) {
HorizontalSlider &horizontalSlider = (HorizontalSlider&)*object;
if(horizontalSlider.state.position != horizontalSlider.position()) {

View File

@ -78,10 +78,11 @@ struct pWindow : public pObject {
void append(Layout &layout);
void append(Menu &menu);
void append(Widget &widget);
Color backgroundColor();
bool focused();
Geometry frameMargin();
Geometry geometry();
void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue);
void setBackgroundColor(const Color &color);
void setFocused();
void setFullScreen(bool fullScreen);
void setGeometry(const Geometry &geometry);
@ -250,6 +251,19 @@ struct pHexEdit : public pWidget {
void setParent(Window &parent);
};
struct pHorizontalScrollBar : public pWidget {
HorizontalScrollBar &horizontalScrollBar;
Geometry minimumGeometry();
unsigned position();
void setLength(unsigned length);
void setPosition(unsigned position);
pHorizontalScrollBar(HorizontalScrollBar &horizontalScrollBar) : pWidget(horizontalScrollBar), horizontalScrollBar(horizontalScrollBar) {}
void constructor();
void setParent(Window &parent);
};
struct pHorizontalSlider : public pWidget {
HorizontalSlider &horizontalSlider;
@ -350,6 +364,19 @@ struct pTextEdit : public pWidget {
void setParent(Window &parent);
};
struct pVerticalScrollBar : public pWidget {
VerticalScrollBar &verticalScrollBar;
Geometry minimumGeometry();
unsigned position();
void setLength(unsigned length);
void setPosition(unsigned position);
pVerticalScrollBar(VerticalScrollBar &verticalScrollBar) : pWidget(verticalScrollBar), verticalScrollBar(verticalScrollBar) {}
void constructor();
void setParent(Window &parent);
};
struct pVerticalSlider : public pWidget {
VerticalSlider &verticalSlider;

View File

@ -1,7 +1,7 @@
namespace SNES {
namespace Info {
static const char Name[] = "bsnes";
static const char Version[] = "080.04";
static const char Version[] = "080.05";
static const unsigned SerializerVersion = 21;
}
}

View File

@ -5,11 +5,13 @@ ui_objects += ruby phoenix
# platform
ifeq ($(platform),x)
# phoenix_compile = $(call compile,-DPHOENIX_GTK `pkg-config --cflags gtk+-2.0`)
# link += `pkg-config --libs gtk+-2.0`
ifeq ($(phoenix),gtk)
phoenix_compile = $(call compile,-DPHOENIX_GTK `pkg-config --cflags gtk+-2.0`)
link += `pkg-config --libs gtk+-2.0`
else
phoenix_compile = $(call compile,-DPHOENIX_QT `pkg-config --cflags QtCore QtGui`)
link += `pkg-config --libs QtCore QtGui`
endif
ruby := video.glx video.xv video.sdl
ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.pulseaudiosimple audio.ao

View File

@ -37,7 +37,7 @@ void Interface::input_poll() {
}
bool Interface::input_poll(unsigned id) {
switch(id) {
switch((GameBoy::Input)id) {
case GameBoy::Input::Up: return inputState[keyboard(0)[Keyboard::Up]];
case GameBoy::Input::Down: return inputState[keyboard(0)[Keyboard::Down]];
case GameBoy::Input::Left: return inputState[keyboard(0)[Keyboard::Left]];

View File

@ -7,11 +7,13 @@ ui_objects += $(if $(call streq,$(platform),win),resource)
# platform
ifeq ($(platform),x)
# phoenix_compile = $(call compile,-DPHOENIX_GTK `pkg-config --cflags gtk+-2.0`)
# link += `pkg-config --libs gtk+-2.0`
ifeq ($(phoenix),gtk)
phoenix_compile = $(call compile,-DPHOENIX_GTK `pkg-config --cflags gtk+-2.0`)
link += `pkg-config --libs gtk+-2.0`
else
phoenix_compile = $(call compile,-DPHOENIX_QT `pkg-config --cflags QtCore QtGui`)
link += `pkg-config --libs QtCore QtGui`
endif
ruby := video.glx video.xv video.sdl
ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.pulseaudiosimple audio.ao

View File

@ -43,6 +43,7 @@ void Configuration::create() {
attach(input.driver = "", "input.driver");
attach(settings.startFullScreen = false, "settings.startFullScreen", "Start in full screen mode for front-end use");
attach(settings.focusPolicy = 0, "settings.focusPolicy");
attach(controller.port1 = 1, "controller.port1");

View File

@ -30,6 +30,7 @@ struct Configuration : public configuration {
} input;
struct Settings {
bool startFullScreen;
unsigned focusPolicy;
} settings;

View File

@ -6,7 +6,7 @@ void AboutWindow::create() {
application.addWindow(this, "AboutWindow", "160,160");
setTitle("About bsnes ...");
setResizable(false);
setBackgroundColor(255, 255, 255);
setBackgroundColor({ 255, 255, 255 });
information.setText({
"bsnes v", SNES::Info::Version, " ~ Profile: ", SNES::Info::Profile,

View File

@ -7,7 +7,7 @@ void MainWindow::create() {
application.addWindow(this, "MainWindow", "128,128");
setMenuFont(application.proportionalFont);
setStatusFont(application.proportionalFontBold);
setBackgroundColor(0, 0, 0);
setBackgroundColor({ 0, 0, 0 });
system.setText("System");

View File

@ -29,7 +29,7 @@ void InputMapper::poll_hotkeys(unsigned scancode, int16_t value) {
//fullscreen
if(scancode == hotkeysGeneral.fullscreenToggle.scancode) {
utility.setFullscreen(!utility.fullscreen);
utility.setFullScreen(!utility.fullScreen);
}
//mouse capture

View File

@ -109,6 +109,7 @@ void Application::main(int argc, char **argv) {
utility.setControllers();
utility.setFilter();
utility.setShader();
if(config.settings.startFullScreen) utility.setFullScreen();
if(argc == 2) cartridge.loadNormal(argv[1]);

View File

@ -5,7 +5,7 @@ void CheatEditor::load() {
cheatList.reset();
for(unsigned i = 0; i < 128; i++) {
cheatList.append("");
cheatText[i][CheatSlot] = rdecimal<3>(i + 1);
cheatText[i][CheatSlot] = decimal<3>(i + 1);
cheatText[i][CheatCode] = "";
cheatText[i][CheatDesc] = "";
}

View File

@ -46,7 +46,7 @@ void StateManager::synchronize() {
void StateManager::refresh() {
for(unsigned i = 0; i < 32; i++) {
stateList.modify(i, rdecimal<2>(i + 1), slotLoadDescription(i));
stateList.modify(i, decimal<2>(i + 1), slotLoadDescription(i));
}
stateList.autoSizeColumns();
}

View File

@ -82,13 +82,13 @@ void Utility::setScale(unsigned scale) {
mainWindow.setGeometry({ geom.x, geom.y, width, height });
}
void Utility::setFullscreen(bool fullscreen) {
this->fullscreen = fullscreen;
void Utility::setFullScreen(bool fullScreen) {
this->fullScreen = fullScreen;
mainWindow.setMenuVisible(!fullscreen);
mainWindow.setStatusVisible(!fullscreen);
mainWindow.setFullScreen(fullscreen);
if(fullscreen == false) {
mainWindow.setMenuVisible(!fullScreen);
mainWindow.setStatusVisible(!fullScreen);
mainWindow.setFullScreen(fullScreen);
if(fullScreen == false) {
input.unacquire();
setScale();
} else {
@ -215,6 +215,6 @@ void Utility::loadState(unsigned slot) {
}
Utility::Utility() {
fullscreen = false;
fullScreen = false;
statusTime = 0;
}

View File

@ -7,7 +7,7 @@ struct Utility : property<Utility> {
void setControllers();
void setScale(unsigned scale = 0);
void setFullscreen(bool fullscreen = true);
void setFullScreen(bool fullScreen = true);
void setFilter();
void setShader();
@ -21,7 +21,7 @@ struct Utility : property<Utility> {
Utility();
bool fullscreen;
bool fullScreen;
unsigned viewportX, viewportY;
unsigned viewportWidth, viewportHeight;