mirror of https://github.com/bsnes-emu/bsnes.git
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:
parent
f38af85e0a
commit
0c3f0834ab
|
@ -3,9 +3,10 @@ snes := snes
|
|||
gameboy := gameboy
|
||||
profile := accuracy
|
||||
ui := ui
|
||||
# phoenix := gtk
|
||||
|
||||
# debugger
|
||||
options :=
|
||||
# debugger
|
||||
|
||||
# compiler
|
||||
c := $(compiler) -std=gnu99
|
||||
|
|
|
@ -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
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
||||
//================
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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); }
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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); }
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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); }
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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); }
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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); }
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
unsigned pHorizontalScrollBar::position() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pHorizontalScrollBar::setLength(unsigned length) {
|
||||
}
|
||||
|
||||
void pHorizontalScrollBar::setPosition(unsigned position) {
|
||||
}
|
||||
|
||||
void pHorizontalScrollBar::constructor() {
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
unsigned pVerticalScrollBar::position() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pVerticalScrollBar::setLength(unsigned length) {
|
||||
}
|
||||
|
||||
void pVerticalScrollBar::setPosition(unsigned position) {
|
||||
}
|
||||
|
||||
void pVerticalScrollBar::constructor() {
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -6,3 +6,4 @@ synchronize() {
|
|||
}
|
||||
|
||||
synchronize "nall"
|
||||
rm -r nall/test
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
Geometry pVerticalSlider::minimumGeometry() {
|
||||
return { 0, 0, 25, 0 };
|
||||
return { 0, 0, 0, 25 };
|
||||
}
|
||||
|
||||
unsigned pVerticalSlider::position() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -30,6 +30,7 @@ struct Configuration : public configuration {
|
|||
} input;
|
||||
|
||||
struct Settings {
|
||||
bool startFullScreen;
|
||||
unsigned focusPolicy;
|
||||
} settings;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]);
|
||||
|
||||
|
|
|
@ -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] = "";
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue