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
|
gameboy := gameboy
|
||||||
profile := accuracy
|
profile := accuracy
|
||||||
ui := ui
|
ui := ui
|
||||||
|
# phoenix := gtk
|
||||||
|
|
||||||
# debugger
|
|
||||||
options :=
|
options :=
|
||||||
|
# debugger
|
||||||
|
|
||||||
# compiler
|
# compiler
|
||||||
c := $(compiler) -std=gnu99
|
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>
|
#include <nall/string.hpp>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include <nall/utf8.hpp>
|
#include <nall/windows/utf8.hpp>
|
||||||
#else
|
#else
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
#include <nall/platform.hpp>
|
#include <nall/platform.hpp>
|
||||||
#include <nall/stdint.hpp>
|
#include <nall/stdint.hpp>
|
||||||
#include <nall/string.hpp>
|
#include <nall/string.hpp>
|
||||||
#include <nall/utf8.hpp>
|
|
||||||
#include <nall/utility.hpp>
|
#include <nall/utility.hpp>
|
||||||
|
#include <nall/windows/utf8.hpp>
|
||||||
|
|
||||||
namespace nall {
|
namespace nall {
|
||||||
inline FILE* fopen_utf8(const string &utf8_filename, const char *mode) {
|
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 index : unsigned { absolute, relative };
|
||||||
enum class time : unsigned { create, modify, access };
|
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() {
|
uint8_t read() {
|
||||||
if(!fp) return 0xff; //file not open
|
if(!fp) return 0xff; //file not open
|
||||||
if(file_mode == mode::write) return 0xff; //reads not permitted
|
if(file_mode == mode::write) return 0xff; //reads not permitted
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define NALL_FILEMAP_HPP
|
#define NALL_FILEMAP_HPP
|
||||||
|
|
||||||
#include <nall/stdint.hpp>
|
#include <nall/stdint.hpp>
|
||||||
#include <nall/utf8.hpp>
|
#include <nall/windows/utf8.hpp>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.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;
|
size = 0;
|
||||||
|
|
||||||
send({
|
send({
|
||||||
"GET ", path, " HTTP/1.1\n"
|
"GET ", path, " HTTP/1.1\r\n"
|
||||||
"Host: ", hostname, "\n"
|
"Host: ", hostname, "\r\n"
|
||||||
"\n"
|
"Connection: close\r\n"
|
||||||
|
"\r\n"
|
||||||
});
|
});
|
||||||
|
|
||||||
header = downloadHeader();
|
header = downloadHeader();
|
||||||
|
@ -99,7 +100,7 @@ struct http {
|
||||||
inline void downloadContent(uint8_t *&data, unsigned &size) {
|
inline void downloadContent(uint8_t *&data, unsigned &size) {
|
||||||
unsigned capacity = 0;
|
unsigned capacity = 0;
|
||||||
|
|
||||||
if(header.position("Transfer-Encoding: chunked")) {
|
if(header.iposition("\r\nTransfer-Encoding: chunked\r\n")) {
|
||||||
while(true) {
|
while(true) {
|
||||||
unsigned length = hex(downloadChunkLength());
|
unsigned length = hex(downloadChunkLength());
|
||||||
if(length == 0) break;
|
if(length == 0) break;
|
||||||
|
@ -115,7 +116,7 @@ struct http {
|
||||||
length -= packetlength;
|
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);
|
unsigned length = decimal((const char*)header + position() + 16);
|
||||||
while(length) {
|
while(length) {
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
|
@ -150,8 +151,12 @@ struct http {
|
||||||
serversocket = -1;
|
serversocket = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
inline int close(int sock) {
|
||||||
|
return closesocket(sock);
|
||||||
|
}
|
||||||
|
|
||||||
inline http() {
|
inline http() {
|
||||||
#ifdef _WIN32
|
|
||||||
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
if(sock == INVALID_SOCKET && WSAGetLastError() == WSANOTINITIALISED) {
|
if(sock == INVALID_SOCKET && WSAGetLastError() == WSANOTINITIALISED) {
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
|
@ -159,9 +164,11 @@ struct http {
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else close(sock);
|
} else {
|
||||||
#endif
|
close(sock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,8 @@ inline bool inflate(
|
||||||
const uint8_t *source, unsigned sourceLength
|
const uint8_t *source, unsigned sourceLength
|
||||||
) {
|
) {
|
||||||
unsigned long tl = targetLength, sl = 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 {
|
namespace puff {
|
||||||
|
|
|
@ -5,10 +5,9 @@
|
||||||
//minimum version needed for _wstat64, etc
|
//minimum version needed for _wstat64, etc
|
||||||
#undef __MSVCRT_VERSION__
|
#undef __MSVCRT_VERSION__
|
||||||
#define __MSVCRT_VERSION__ 0x0601
|
#define __MSVCRT_VERSION__ 0x0601
|
||||||
|
#include <nall/windows/utf8.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <nall/utf8.hpp>
|
|
||||||
|
|
||||||
//=========================
|
//=========================
|
||||||
//standard platform headers
|
//standard platform headers
|
||||||
//=========================
|
//=========================
|
||||||
|
@ -67,7 +66,6 @@
|
||||||
#define rmdir _rmdir
|
#define rmdir _rmdir
|
||||||
#define usleep(n) Sleep(n / 1000)
|
#define usleep(n) Sleep(n / 1000)
|
||||||
#define vsnprintf _vsnprintf
|
#define vsnprintf _vsnprintf
|
||||||
static int close(int sock) { return closesocket(sock); }
|
|
||||||
#endif
|
#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
|
#define NALL_RESOURCE_HPP
|
||||||
|
|
||||||
#include <nall/file.hpp>
|
#include <nall/file.hpp>
|
||||||
#include <nall/unzip.hpp>
|
#include <nall/zip.hpp>
|
||||||
|
|
||||||
namespace nall {
|
namespace nall {
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ struct resource {
|
||||||
bool decode(const uint8_t *cdata, unsigned csize) {
|
bool decode(const uint8_t *cdata, unsigned csize) {
|
||||||
if(data) delete[] data;
|
if(data) delete[] data;
|
||||||
|
|
||||||
unzip archive;
|
zip archive;
|
||||||
if(archive.open(cdata, csize) == false) return false;
|
if(archive.open(cdata, csize) == false) return false;
|
||||||
if(archive.file.size() == 0) return false;
|
if(archive.file.size() == 0) return false;
|
||||||
bool result = archive.extract(archive.file[0], data, size);
|
bool result = archive.extract(archive.file[0], data, size);
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
#include <nall/concept.hpp>
|
#include <nall/concept.hpp>
|
||||||
#include <nall/function.hpp>
|
#include <nall/function.hpp>
|
||||||
#include <nall/stdint.hpp>
|
#include <nall/stdint.hpp>
|
||||||
#include <nall/utf8.hpp>
|
|
||||||
#include <nall/vector.hpp>
|
#include <nall/vector.hpp>
|
||||||
|
#include <nall/windows/utf8.hpp>
|
||||||
|
|
||||||
namespace nall {
|
namespace nall {
|
||||||
class string;
|
class string;
|
||||||
|
@ -22,13 +22,13 @@ namespace nall {
|
||||||
|
|
||||||
template<typename... Args> inline string& assign(Args&&... args);
|
template<typename... Args> inline string& assign(Args&&... args);
|
||||||
template<typename... Args> inline string& append(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 bool readfile(const string&);
|
||||||
|
|
||||||
inline string& replace (const char*, const char*);
|
template<unsigned Limit = 0> inline string& replace(const char*, const char*);
|
||||||
inline string& qreplace(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;
|
inline unsigned length() const;
|
||||||
|
|
||||||
|
@ -37,7 +37,6 @@ namespace nall {
|
||||||
|
|
||||||
inline bool wildcard(const char*) const;
|
inline bool wildcard(const char*) const;
|
||||||
inline bool iwildcard(const char*) const;
|
inline bool iwildcard(const char*) const;
|
||||||
inline lstring lwildcard(const char*) const;
|
|
||||||
|
|
||||||
inline bool beginswith(const char*) const;
|
inline bool beginswith(const char*) const;
|
||||||
inline bool ibeginswith(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& ltrim(const char *key = " ");
|
||||||
template<unsigned limit = 0> inline string& rtrim(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> position(const char *key) const;
|
||||||
|
inline optional<unsigned> iposition(const char *key) const;
|
||||||
inline optional<unsigned> qposition(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 operator const char*() const;
|
||||||
inline char* operator()();
|
inline char* operator()();
|
||||||
|
@ -76,10 +77,16 @@ namespace nall {
|
||||||
inline string(string&&);
|
inline string(string&&);
|
||||||
inline ~string();
|
inline ~string();
|
||||||
|
|
||||||
|
//internal functions
|
||||||
|
inline string& assign_(const char*);
|
||||||
|
inline string& append_(const char*);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
char *data;
|
char *data;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
|
|
||||||
|
template<unsigned Limit, bool Insensitive, bool Quoted> inline string& ureplace(const char*, const char*);
|
||||||
|
|
||||||
#if defined(QSTRING_H)
|
#if defined(QSTRING_H)
|
||||||
public:
|
public:
|
||||||
inline operator QString() const;
|
inline operator QString() const;
|
||||||
|
@ -91,24 +98,28 @@ namespace nall {
|
||||||
template<typename T> inline lstring& operator<<(T value);
|
template<typename T> inline lstring& operator<<(T value);
|
||||||
|
|
||||||
inline optional<unsigned> find(const char*) const;
|
inline optional<unsigned> find(const char*) const;
|
||||||
template<unsigned limit = 0> inline void split (const char*, const char*);
|
template<unsigned Limit = 0> inline lstring& split(const char*, const char*);
|
||||||
template<unsigned limit = 0> inline void qsplit(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();
|
||||||
lstring(std::initializer_list<string>);
|
lstring(std::initializer_list<string>);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
template<unsigned Limit, bool Insensitive, bool Quoted> inline lstring& usplit(const char*, const char*);
|
||||||
};
|
};
|
||||||
|
|
||||||
//compare.hpp
|
//compare.hpp
|
||||||
inline char chrlower(char c);
|
inline char chrlower(char c);
|
||||||
inline char chrupper(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 wildcard(const char *str, const char *pattern);
|
||||||
inline bool iwildcard(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 strbegin (const char *str, const char *key);
|
inline bool istrbegin(const char *str, const char *key);
|
||||||
inline bool stribegin(const char *str, const char *key);
|
inline bool strend(const char *str, const char *key);
|
||||||
inline bool strend (const char *str, const char *key);
|
inline bool istrend(const char *str, const char *key);
|
||||||
inline bool striend(const char *str, const char *key);
|
|
||||||
|
|
||||||
//convert.hpp
|
//convert.hpp
|
||||||
inline char* strlower(char *str);
|
inline char* strlower(char *str);
|
||||||
|
@ -116,14 +127,14 @@ namespace nall {
|
||||||
inline char* qstrlower(char *str);
|
inline char* qstrlower(char *str);
|
||||||
inline char* qstrupper(char *str);
|
inline char* qstrupper(char *str);
|
||||||
inline char* strtr(char *dest, const char *before, const char *after);
|
inline char* strtr(char *dest, const char *before, const char *after);
|
||||||
inline uintmax_t hex (const char *str);
|
inline uintmax_t hex(const char *str);
|
||||||
inline intmax_t integer(const char *str);
|
inline intmax_t integer(const char *str);
|
||||||
inline uintmax_t decimal(const char *str);
|
inline uintmax_t decimal(const char *str);
|
||||||
inline uintmax_t binary (const char *str);
|
inline uintmax_t binary(const char *str);
|
||||||
inline double fp (const char *str);
|
inline double fp(const char *str);
|
||||||
|
|
||||||
//math.hpp
|
//math.hpp
|
||||||
inline bool strint (const char *str, int &result);
|
inline bool strint(const char *str, int &result);
|
||||||
inline bool strmath(const char *str, int &result);
|
inline bool strmath(const char *str, int &result);
|
||||||
|
|
||||||
//platform.hpp
|
//platform.hpp
|
||||||
|
@ -137,27 +148,31 @@ namespace nall {
|
||||||
|
|
||||||
//strpos.hpp
|
//strpos.hpp
|
||||||
inline optional<unsigned> strpos(const char *str, const char *key);
|
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> 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
|
//trim.hpp
|
||||||
template<unsigned limit = 0> inline char* ltrim(char *str, const char *key = " ");
|
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* 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
|
//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 strlcpy(string &dest, const char *src, unsigned length);
|
||||||
inline unsigned strlcat(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 substr(const char *src, unsigned start = 0, unsigned length = ~0u);
|
||||||
inline string sha256(const uint8_t *data, unsigned size);
|
inline string sha256(const uint8_t *data, unsigned size);
|
||||||
|
|
||||||
inline string integer(intmax_t value);
|
template<unsigned length = 0, char padding = ' '> inline string integer(intmax_t value);
|
||||||
template<unsigned length = 0> inline string linteger(intmax_t value);
|
template<unsigned length = 0, char padding = ' '> inline string linteger(intmax_t value);
|
||||||
template<unsigned length = 0> inline string rinteger(intmax_t value);
|
template<unsigned length = 0, char padding = ' '> inline string decimal(uintmax_t value);
|
||||||
inline string decimal(uintmax_t value);
|
template<unsigned length = 0, char padding = ' '> inline string ldecimal(uintmax_t value);
|
||||||
template<unsigned length = 0> inline string ldecimal(uintmax_t value);
|
template<unsigned length = 0, char padding = '0'> inline string hex(uintmax_t value);
|
||||||
template<unsigned length = 0> inline string rdecimal(uintmax_t value);
|
template<unsigned length = 0, char padding = '0'> inline string binary(uintmax_t value);
|
||||||
template<unsigned length = 0> inline string hex(uintmax_t value);
|
|
||||||
template<unsigned length = 0> inline string binary(uintmax_t value);
|
|
||||||
inline unsigned fp(char *str, double value);
|
inline unsigned fp(char *str, double value);
|
||||||
inline string fp(double value);
|
inline string fp(double value);
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ char chrupper(char c) {
|
||||||
return (c >= 'a' && c <= 'z') ? c - ('a' - 'A') : 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) {
|
while(*str1) {
|
||||||
if(chrlower(*str1) != chrlower(*str2)) break;
|
if(chrlower(*str1) != chrlower(*str2)) break;
|
||||||
str1++, str2++;
|
str1++, str2++;
|
||||||
|
@ -59,39 +59,6 @@ bool iwildcard(const char *s, const char *p) {
|
||||||
return !*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) {
|
bool strbegin(const char *str, const char *key) {
|
||||||
int i, ssl = strlen(str), ksl = strlen(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));
|
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);
|
int ssl = strlen(str), ksl = strlen(key);
|
||||||
|
|
||||||
if(ksl > ssl) return false;
|
if(ksl > ssl) return false;
|
||||||
|
@ -122,7 +89,7 @@ bool strend(const char *str, const char *key) {
|
||||||
return (!memcmp(str + ssl - ksl, key, ksl));
|
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);
|
int ssl = strlen(str), ksl = strlen(key);
|
||||||
|
|
||||||
if(ksl > ssl) return false;
|
if(ksl > ssl) return false;
|
||||||
|
|
|
@ -3,100 +3,49 @@
|
||||||
|
|
||||||
namespace nall {
|
namespace nall {
|
||||||
|
|
||||||
string& string::replace(const char *key, const char *token) {
|
template<unsigned Limit, bool Insensitive, bool Quoted>
|
||||||
int i, z, ksl = strlen(key), tsl = strlen(token), ssl = length();
|
string& string::ureplace(const char *key, const char *token) {
|
||||||
unsigned int replace_count = 0, size = ssl;
|
if(!key || !*key) return *this;
|
||||||
char *buffer;
|
enum : unsigned { limit = Limit ? Limit : ~0u };
|
||||||
|
|
||||||
if(ksl <= ssl) {
|
const char *p = data;
|
||||||
if(tsl > ksl) { //the new string may be longer than the old string...
|
unsigned counter = 0, keyLength = 0;
|
||||||
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)) {
|
while(*p) {
|
||||||
replace_count++;
|
if(quoteskip<Quoted>(p)) continue;
|
||||||
i += ksl;
|
for(unsigned n = 0;; n++) {
|
||||||
} else i++;
|
if(key[n] == 0) { counter++; p += n; keyLength = n; break; }
|
||||||
}
|
if(!chrequal<Insensitive>(key[n], p[n])) { p++; break; }
|
||||||
size = ssl + ((tsl - ksl) * replace_count);
|
|
||||||
reserve(size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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++];
|
|
||||||
}
|
|
||||||
buffer[z] = 0;
|
|
||||||
|
|
||||||
assign(buffer);
|
|
||||||
delete[] buffer;
|
|
||||||
}
|
}
|
||||||
|
if(counter == 0) return *this;
|
||||||
|
if(Limit) counter = min(counter, Limit);
|
||||||
|
|
||||||
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
string& string::qreplace(const char *key, const char *token) {
|
template<unsigned Limit> string &string::replace(const char *key, const char *token) { return ureplace<Limit, false, false>(key, token); }
|
||||||
int i, l, z, ksl = strlen(key), tsl = strlen(token), ssl = length();
|
template<unsigned Limit> string &string::ireplace(const char *key, const char *token) { return ureplace<Limit, true, false>(key, token); }
|
||||||
unsigned int replace_count = 0, size = ssl;
|
template<unsigned Limit> string &string::qreplace(const char *key, const char *token) { return ureplace<Limit, false, true>(key, token); }
|
||||||
uint8_t x;
|
template<unsigned Limit> string &string::iqreplace(const char *key, const char *token) { return ureplace<Limit, true, true>(key, token); }
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,56 +3,36 @@
|
||||||
|
|
||||||
namespace nall {
|
namespace nall {
|
||||||
|
|
||||||
template<unsigned Limit> void lstring::split(const char *key, const char *src) {
|
template<unsigned Limit, bool Insensitive, bool Quoted> lstring& lstring::usplit(const char *key, const char *base) {
|
||||||
unsigned limit = Limit;
|
|
||||||
reset();
|
reset();
|
||||||
|
if(!key || !*key) return *this;
|
||||||
|
|
||||||
int ssl = strlen(src), ksl = strlen(key);
|
const char *p = base;
|
||||||
int lp = 0, split_count = 0;
|
unsigned counter = 0;
|
||||||
|
|
||||||
for(int i = 0; i <= ssl - ksl;) {
|
while(*p) {
|
||||||
if(!memcmp(src + i, key, ksl)) {
|
if(Limit) if(counter >= Limit) break;
|
||||||
strlcpy(operator[](split_count++), src + lp, i - lp + 1);
|
if(quoteskip<Quoted>(p)) continue;
|
||||||
i += ksl;
|
for(unsigned n = 0;; n++) {
|
||||||
lp = i;
|
if(key[n] == 0) {
|
||||||
if(!--limit) break;
|
strlcpy(operator[](counter++), base, (unsigned)(p - base + 1));
|
||||||
} else i++;
|
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[](split_count++) = src + lp;
|
operator[](counter) = base;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,40 +2,33 @@
|
||||||
#define NALL_STRING_STRPOS_HPP
|
#define NALL_STRING_STRPOS_HPP
|
||||||
|
|
||||||
//usage example:
|
//usage example:
|
||||||
//if(auto pos = strpos(str, key)) print(pos(), "\n");
|
//if(auto position = strpos(str, key)) print(position(), "\n");
|
||||||
//prints position of key within str, only if it is found
|
//prints position of key within str; but only if it is found
|
||||||
|
|
||||||
namespace nall {
|
namespace nall {
|
||||||
|
|
||||||
optional<unsigned> strpos(const char *str, const char *key) {
|
template<bool Insensitive, bool Quoted>
|
||||||
unsigned ssl = strlen(str), ksl = strlen(key);
|
optional<unsigned> ustrpos(const char *str, const char *key) {
|
||||||
if(ksl > ssl) return { false, 0 };
|
const char *base = str;
|
||||||
|
|
||||||
for(unsigned i = 0; i <= ssl - ksl; i++) {
|
while(*str) {
|
||||||
if(!memcmp(str + i, key, ksl)) return { true, i };
|
if(quoteskip<Quoted>(str)) continue;
|
||||||
}
|
for(unsigned n = 0;; n++) {
|
||||||
|
if(key[n] == 0) return { true, (unsigned)(str - base) };
|
||||||
return { false, 0 };
|
if(str[n] == 0) return { false, 0 };
|
||||||
}
|
if(!chrequal<Insensitive>(str[n], key[n])) break;
|
||||||
|
|
||||||
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 };
|
str++;
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return { false, 0 };
|
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); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,7 +29,8 @@ template<unsigned Limit> char* rtrim(char *str, const char *key) {
|
||||||
return str;
|
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);
|
return ltrim<limit>(rtrim<limit>(str, key), key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,38 @@
|
||||||
|
|
||||||
namespace nall {
|
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) {
|
unsigned strlcpy(string &dest, const char *src, unsigned length) {
|
||||||
dest.reserve(length);
|
dest.reserve(length);
|
||||||
return strlcpy(dest(), src, length);
|
return strlcpy(dest(), src, length);
|
||||||
|
@ -39,33 +71,7 @@ string sha256(const uint8_t *data, unsigned size) {
|
||||||
|
|
||||||
/* arithmetic <> string */
|
/* arithmetic <> string */
|
||||||
|
|
||||||
string integer(intmax_t value) {
|
template<unsigned length_, char padding> 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) {
|
|
||||||
bool negative = value < 0;
|
bool negative = value < 0;
|
||||||
if(negative) value = abs(value);
|
if(negative) value = abs(value);
|
||||||
|
|
||||||
|
@ -82,34 +88,7 @@ template<unsigned length_> string linteger(intmax_t value) {
|
||||||
|
|
||||||
unsigned length = (length_ == 0 ? size : length_);
|
unsigned length = (length_ == 0 ? size : length_);
|
||||||
char result[length + 1];
|
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--) {
|
|
||||||
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);
|
|
||||||
result[length] = 0;
|
result[length] = 0;
|
||||||
|
|
||||||
for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) {
|
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;
|
return (const char*)result;
|
||||||
}
|
}
|
||||||
|
|
||||||
string decimal(uintmax_t value) {
|
template<unsigned length_, char padding> string linteger(intmax_t value) {
|
||||||
char buffer[64];
|
bool negative = value < 0;
|
||||||
unsigned size = 0;
|
if(negative) value = abs(value);
|
||||||
|
|
||||||
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) {
|
|
||||||
char buffer[64];
|
char buffer[64];
|
||||||
unsigned size = 0;
|
unsigned size = 0;
|
||||||
|
|
||||||
|
@ -150,11 +110,12 @@ template<unsigned length_> string ldecimal(uintmax_t value) {
|
||||||
buffer[size++] = '0' + n;
|
buffer[size++] = '0' + n;
|
||||||
value /= 10;
|
value /= 10;
|
||||||
} while(value);
|
} while(value);
|
||||||
|
buffer[size++] = negative ? '-' : '+';
|
||||||
buffer[size] = 0;
|
buffer[size] = 0;
|
||||||
|
|
||||||
unsigned length = (length_ == 0 ? size : length_);
|
unsigned length = (length_ == 0 ? size : length_);
|
||||||
char result[length + 1];
|
char result[length + 1];
|
||||||
memset(result, ' ', length);
|
memset(result, padding, length);
|
||||||
result[length] = 0;
|
result[length] = 0;
|
||||||
|
|
||||||
for(signed x = 0, y = size - 1; x < length && y >= 0; x++, y--) {
|
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;
|
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];
|
char buffer[64];
|
||||||
unsigned size = 0;
|
unsigned size = 0;
|
||||||
|
|
||||||
|
@ -177,7 +138,7 @@ template<unsigned length_> string rdecimal(uintmax_t value) {
|
||||||
|
|
||||||
unsigned length = (length_ == 0 ? size : length_);
|
unsigned length = (length_ == 0 ? size : length_);
|
||||||
char result[length + 1];
|
char result[length + 1];
|
||||||
memset(result, ' ', length);
|
memset(result, padding, length);
|
||||||
result[length] = 0;
|
result[length] = 0;
|
||||||
|
|
||||||
for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) {
|
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;
|
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];
|
char buffer[64];
|
||||||
unsigned size = 0;
|
unsigned size = 0;
|
||||||
|
|
||||||
|
@ -199,7 +183,7 @@ template<unsigned length_> string hex(uintmax_t value) {
|
||||||
|
|
||||||
unsigned length = (length_ == 0 ? size : length_);
|
unsigned length = (length_ == 0 ? size : length_);
|
||||||
char result[length + 1];
|
char result[length + 1];
|
||||||
memset(result, '0', length);
|
memset(result, padding, length);
|
||||||
result[length] = 0;
|
result[length] = 0;
|
||||||
|
|
||||||
for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) {
|
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;
|
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];
|
char buffer[256];
|
||||||
unsigned size = 0;
|
unsigned size = 0;
|
||||||
|
|
||||||
|
@ -221,7 +205,7 @@ template<unsigned length_> string binary(uintmax_t value) {
|
||||||
|
|
||||||
unsigned length = (length_ == 0 ? size : length_);
|
unsigned length = (length_ == 0 ? size : length_);
|
||||||
char result[length + 1];
|
char result[length + 1];
|
||||||
memset(result, '0', length);
|
memset(result, padding, length);
|
||||||
result[length] = 0;
|
result[length] = 0;
|
||||||
|
|
||||||
for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) {
|
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); }
|
unsigned string::length() const { return strlen(data); }
|
||||||
|
|
||||||
bool string::equals(const char *str) const { return !strcmp(data, str); }
|
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::wildcard(const char *str) const { return nall::wildcard(data, str); }
|
||||||
bool string::iwildcard(const char *str) const { return nall::iwildcard(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::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::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::lower() { nall::strlower(data); return *this; }
|
||||||
string& string::upper() { nall::strupper(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::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::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::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::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 {
|
namespace nall {
|
||||||
|
|
||||||
struct unzip {
|
struct zip {
|
||||||
struct File {
|
struct File {
|
||||||
string name;
|
string name;
|
||||||
const uint8_t *data;
|
const uint8_t *data;
|
||||||
|
@ -18,7 +18,7 @@ struct unzip {
|
||||||
unsigned crc32;
|
unsigned crc32;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool open(const char *filename) {
|
inline bool open(const string &filename) {
|
||||||
close();
|
close();
|
||||||
if(fm.open(filename, filemap::mode::read) == false) return false;
|
if(fm.open(filename, filemap::mode::read) == false) return false;
|
||||||
if(open(fm.data(), fm.size()) == false) {
|
if(open(fm.data(), fm.size()) == false) {
|
||||||
|
@ -100,7 +100,7 @@ struct unzip {
|
||||||
if(fm.open()) fm.close();
|
if(fm.open()) fm.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
~unzip() {
|
~zip() {
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,11 +47,12 @@ Window Window::None;
|
||||||
void Window::append(Layout &layout) { state.layout.append(layout); return p.append(layout); }
|
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(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); }
|
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::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(); }
|
Geometry Window::frameMargin() { return p.frameMargin(); }
|
||||||
bool Window::focused() { return p.focused(); }
|
bool Window::focused() { return p.focused(); }
|
||||||
Geometry Window::geometry() { return p.geometry(); }
|
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::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::setFocused() { return p.setFocused(); }
|
||||||
void Window::setFullScreen(bool fullScreen) { state.fullScreen = fullScreen; return p.setFullScreen(fullScreen); }
|
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; }
|
bool Widget::enabled() { return state.enabled; }
|
||||||
Font& Widget::font() { return p.font(); }
|
Font& Widget::font() { return p.font(); }
|
||||||
|
Geometry Widget::geometry() { return state.geometry; }
|
||||||
Geometry Widget::minimumGeometry() { return p.minimumGeometry(); }
|
Geometry Widget::minimumGeometry() { return p.minimumGeometry(); }
|
||||||
void Widget::setEnabled(bool enabled) { state.enabled = enabled; return p.setEnabled(enabled); }
|
void Widget::setEnabled(bool enabled) { state.enabled = enabled; return p.setEnabled(enabled); }
|
||||||
void Widget::setFocused() { return p.setFocused(); }
|
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(); }
|
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(); }
|
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(); }
|
unsigned HorizontalSlider::position() { return p.position(); }
|
||||||
void HorizontalSlider::setLength(unsigned length) { state.length = length; return p.setLength(length); }
|
void HorizontalSlider::setLength(unsigned length) { state.length = length; return p.setLength(length); }
|
||||||
void HorizontalSlider::setPosition(unsigned position) { state.position = position; return p.setPosition(position); }
|
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(); }
|
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(); }
|
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(); }
|
unsigned VerticalSlider::position() { return p.position(); }
|
||||||
void VerticalSlider::setLength(unsigned length) { state.length = length; return p.setLength(length); }
|
void VerticalSlider::setLength(unsigned length) { state.length = length; return p.setLength(length); }
|
||||||
void VerticalSlider::setPosition(unsigned position) { state.position = position; return p.setPosition(position); }
|
void VerticalSlider::setPosition(unsigned position) { state.position = position; return p.setPosition(position); }
|
||||||
|
|
|
@ -21,6 +21,7 @@ struct pCanvas;
|
||||||
struct pCheckBox;
|
struct pCheckBox;
|
||||||
struct pComboBox;
|
struct pComboBox;
|
||||||
struct pHexEdit;
|
struct pHexEdit;
|
||||||
|
struct pHorizontalScrollBar;
|
||||||
struct pHorizontalSlider;
|
struct pHorizontalSlider;
|
||||||
struct pLabel;
|
struct pLabel;
|
||||||
struct pLineEdit;
|
struct pLineEdit;
|
||||||
|
@ -28,6 +29,7 @@ struct pListView;
|
||||||
struct pProgressBar;
|
struct pProgressBar;
|
||||||
struct pRadioBox;
|
struct pRadioBox;
|
||||||
struct pTextEdit;
|
struct pTextEdit;
|
||||||
|
struct pVerticalScrollBar;
|
||||||
struct pVerticalSlider;
|
struct pVerticalSlider;
|
||||||
struct pViewport;
|
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) {}
|
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 {
|
struct Object {
|
||||||
Object();
|
Object();
|
||||||
Object& operator=(const Object&) = delete;
|
Object& operator=(const Object&) = delete;
|
||||||
|
@ -124,11 +132,12 @@ struct Window : Object {
|
||||||
void append(Layout &layout);
|
void append(Layout &layout);
|
||||||
void append(Menu &menu);
|
void append(Menu &menu);
|
||||||
void append(Widget &widget);
|
void append(Widget &widget);
|
||||||
|
Color backgroundColor();
|
||||||
Geometry frameGeometry();
|
Geometry frameGeometry();
|
||||||
Geometry frameMargin();
|
Geometry frameMargin();
|
||||||
bool focused();
|
bool focused();
|
||||||
Geometry geometry();
|
Geometry geometry();
|
||||||
void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue);
|
void setBackgroundColor(const Color &color);
|
||||||
void setFrameGeometry(const Geometry &geometry);
|
void setFrameGeometry(const Geometry &geometry);
|
||||||
void setFocused();
|
void setFocused();
|
||||||
void setFullScreen(bool fullScreen = true);
|
void setFullScreen(bool fullScreen = true);
|
||||||
|
@ -223,6 +232,7 @@ struct Layout : Object {
|
||||||
struct Widget : Object {
|
struct Widget : Object {
|
||||||
bool enabled();
|
bool enabled();
|
||||||
Font& font();
|
Font& font();
|
||||||
|
Geometry geometry();
|
||||||
Geometry minimumGeometry();
|
Geometry minimumGeometry();
|
||||||
void setEnabled(bool enabled = true);
|
void setEnabled(bool enabled = true);
|
||||||
void setFocused();
|
void setFocused();
|
||||||
|
@ -300,6 +310,19 @@ struct HexEdit : private nall::base_from_member<pHexEdit&>, Widget {
|
||||||
pHexEdit &p;
|
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 {
|
struct HorizontalSlider : private nall::base_from_member<pHorizontalSlider&>, Widget {
|
||||||
nall::function<void ()> onChange;
|
nall::function<void ()> onChange;
|
||||||
|
|
||||||
|
@ -406,6 +429,19 @@ struct TextEdit : private nall::base_from_member<pTextEdit&>, Widget {
|
||||||
pTextEdit &p;
|
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 {
|
struct VerticalSlider : private nall::base_from_member<pVerticalSlider&>, Widget {
|
||||||
nall::function<void ()> onChange;
|
nall::function<void ()> onChange;
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,8 @@ struct Timer::State {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Window::State {
|
struct Window::State {
|
||||||
bool backgroundColor;
|
bool backgroundColorOverride;
|
||||||
unsigned backgroundColorRed, backgroundColorGreen, backgroundColorBlue;
|
Color backgroundColor;
|
||||||
bool fullScreen;
|
bool fullScreen;
|
||||||
Geometry geometry;
|
Geometry geometry;
|
||||||
reference_array<Layout&> layout;
|
reference_array<Layout&> layout;
|
||||||
|
@ -42,10 +42,8 @@ struct Window::State {
|
||||||
Font *widgetFont;
|
Font *widgetFont;
|
||||||
|
|
||||||
State() {
|
State() {
|
||||||
backgroundColor = false;
|
backgroundColorOverride = false;
|
||||||
backgroundColorRed = 0;
|
backgroundColor = { 0, 0, 0, 255 };
|
||||||
backgroundColorGreen = 0;
|
|
||||||
backgroundColorBlue = 0;
|
|
||||||
fullScreen = false;
|
fullScreen = false;
|
||||||
geometry = { 128, 128, 256, 256 };
|
geometry = { 128, 128, 256, 256 };
|
||||||
menuFont = 0;
|
menuFont = 0;
|
||||||
|
@ -152,6 +150,16 @@ struct HexEdit::State {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct HorizontalScrollBar::State {
|
||||||
|
unsigned length;
|
||||||
|
unsigned position;
|
||||||
|
|
||||||
|
State() {
|
||||||
|
length = 101;
|
||||||
|
position = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct HorizontalSlider::State {
|
struct HorizontalSlider::State {
|
||||||
unsigned length;
|
unsigned length;
|
||||||
unsigned position;
|
unsigned position;
|
||||||
|
@ -223,6 +231,16 @@ struct TextEdit::State {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VerticalScrollBar::State {
|
||||||
|
unsigned length;
|
||||||
|
unsigned position;
|
||||||
|
|
||||||
|
State() {
|
||||||
|
length = 101;
|
||||||
|
position = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct VerticalSlider::State {
|
struct VerticalSlider::State {
|
||||||
unsigned length;
|
unsigned length;
|
||||||
unsigned position;
|
unsigned position;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "widget/check-box.cpp"
|
#include "widget/check-box.cpp"
|
||||||
#include "widget/combo-box.cpp"
|
#include "widget/combo-box.cpp"
|
||||||
#include "widget/hex-edit.cpp"
|
#include "widget/hex-edit.cpp"
|
||||||
|
#include "widget/horizontal-scroll-bar.cpp"
|
||||||
#include "widget/horizontal-slider.cpp"
|
#include "widget/horizontal-slider.cpp"
|
||||||
#include "widget/label.cpp"
|
#include "widget/label.cpp"
|
||||||
#include "widget/line-edit.cpp"
|
#include "widget/line-edit.cpp"
|
||||||
|
@ -26,6 +27,7 @@
|
||||||
#include "widget/progress-bar.cpp"
|
#include "widget/progress-bar.cpp"
|
||||||
#include "widget/radio-box.cpp"
|
#include "widget/radio-box.cpp"
|
||||||
#include "widget/text-edit.cpp"
|
#include "widget/text-edit.cpp"
|
||||||
|
#include "widget/vertical-scroll-bar.cpp"
|
||||||
#include "widget/vertical-slider.cpp"
|
#include "widget/vertical-slider.cpp"
|
||||||
#include "widget/viewport.cpp"
|
#include "widget/viewport.cpp"
|
||||||
|
|
||||||
|
|
|
@ -82,14 +82,16 @@ struct pWindow : public pObject {
|
||||||
GtkWidget *statusContainer;
|
GtkWidget *statusContainer;
|
||||||
GtkWidget *menu;
|
GtkWidget *menu;
|
||||||
GtkWidget *status;
|
GtkWidget *status;
|
||||||
|
GdkEventConfigure lastConfigure;
|
||||||
|
|
||||||
void append(Layout &layout);
|
void append(Layout &layout);
|
||||||
void append(Menu &menu);
|
void append(Menu &menu);
|
||||||
void append(Widget &widget);
|
void append(Widget &widget);
|
||||||
|
Color backgroundColor();
|
||||||
bool focused();
|
bool focused();
|
||||||
Geometry frameMargin();
|
Geometry frameMargin();
|
||||||
Geometry geometry();
|
Geometry geometry();
|
||||||
void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue);
|
void setBackgroundColor(const Color &color);
|
||||||
void setFocused();
|
void setFocused();
|
||||||
void setFullScreen(bool fullScreen);
|
void setFullScreen(bool fullScreen);
|
||||||
void setGeometry(const Geometry &geometry);
|
void setGeometry(const Geometry &geometry);
|
||||||
|
@ -202,8 +204,7 @@ struct pButton : public pWidget {
|
||||||
|
|
||||||
struct pCanvas : public pWidget {
|
struct pCanvas : public pWidget {
|
||||||
Canvas &canvas;
|
Canvas &canvas;
|
||||||
uint32_t *bufferRGB;
|
cairo_surface_t *surface;
|
||||||
uint32_t *bufferBGR;
|
|
||||||
|
|
||||||
uint32_t* buffer();
|
uint32_t* buffer();
|
||||||
void setGeometry(const Geometry &geometry);
|
void setGeometry(const Geometry &geometry);
|
||||||
|
@ -211,7 +212,6 @@ struct pCanvas : public pWidget {
|
||||||
|
|
||||||
pCanvas(Canvas &canvas) : pWidget(canvas), canvas(canvas) {}
|
pCanvas(Canvas &canvas) : pWidget(canvas), canvas(canvas) {}
|
||||||
void constructor();
|
void constructor();
|
||||||
void redraw();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pCheckBox : public pWidget {
|
struct pCheckBox : public pWidget {
|
||||||
|
@ -264,6 +264,18 @@ struct pHexEdit : public pWidget {
|
||||||
void updateScroll();
|
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 {
|
struct pHorizontalSlider : public pWidget {
|
||||||
HorizontalSlider &horizontalSlider;
|
HorizontalSlider &horizontalSlider;
|
||||||
|
|
||||||
|
@ -368,6 +380,18 @@ struct pTextEdit : public pWidget {
|
||||||
void constructor();
|
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 {
|
struct pVerticalSlider : public pWidget {
|
||||||
VerticalSlider &verticalSlider;
|
VerticalSlider &verticalSlider;
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
static void Canvas_expose(pCanvas *self) {
|
static gboolean Canvas_expose(GtkWidget *widget, GdkEvent *event, pCanvas *self) {
|
||||||
self->redraw();
|
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() {
|
uint32_t* pCanvas::buffer() {
|
||||||
return bufferRGB;
|
return (uint32_t*)cairo_image_surface_get_data(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pCanvas::setGeometry(const Geometry &geometry) {
|
void pCanvas::setGeometry(const Geometry &geometry) {
|
||||||
delete[] bufferRGB;
|
if(geometry.width == cairo_image_surface_get_width(surface)
|
||||||
delete[] bufferBGR;
|
&& geometry.height == cairo_image_surface_get_height(surface)) return;
|
||||||
|
|
||||||
bufferRGB = new uint32_t[geometry.width * geometry.height]();
|
cairo_surface_destroy(surface);
|
||||||
bufferBGR = new uint32_t[geometry.width * geometry.height]();
|
surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, geometry.width, geometry.height);
|
||||||
|
|
||||||
pWidget::setGeometry(geometry);
|
pWidget::setGeometry(geometry);
|
||||||
update();
|
update();
|
||||||
|
@ -19,41 +23,16 @@ void pCanvas::setGeometry(const Geometry &geometry) {
|
||||||
|
|
||||||
void pCanvas::update() {
|
void pCanvas::update() {
|
||||||
if(gtk_widget_get_realized(gtkWidget) == false) return;
|
if(gtk_widget_get_realized(gtkWidget) == false) return;
|
||||||
GdkRectangle rect;
|
gdk_window_invalidate_rect(gtk_widget_get_window(gtkWidget), 0, true);
|
||||||
rect.x = 0;
|
|
||||||
rect.y = 0;
|
|
||||||
rect.width = gtkWidget->allocation.width;
|
|
||||||
rect.height = gtkWidget->allocation.height;
|
|
||||||
gdk_window_invalidate_rect(gtkWidget->window, &rect, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pCanvas::constructor() {
|
void pCanvas::constructor() {
|
||||||
bufferRGB = new uint32_t[256 * 256]();
|
surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 256, 256);
|
||||||
bufferBGR = new uint32_t[256 * 256]();
|
|
||||||
|
|
||||||
gtkWidget = gtk_drawing_area_new();
|
gtkWidget = gtk_drawing_area_new();
|
||||||
GdkColor color;
|
GdkColor color;
|
||||||
color.pixel = color.red = color.green = color.blue = 0;
|
color.pixel = color.red = color.green = color.blue = 0;
|
||||||
gtk_widget_modify_bg(gtkWidget, GTK_STATE_NORMAL, &color);
|
gtk_widget_modify_bg(gtkWidget, GTK_STATE_NORMAL, &color);
|
||||||
gtk_widget_set_double_buffered(gtkWidget, false);
|
gtk_widget_set_double_buffered(gtkWidget, false);
|
||||||
gtk_widget_add_events(gtkWidget, GDK_EXPOSURE_MASK);
|
gtk_widget_add_events(gtkWidget, GDK_EXPOSURE_MASK);
|
||||||
g_signal_connect_swapped(G_OBJECT(gtkWidget), "expose_event", G_CALLBACK(Canvas_expose), (gpointer)this);
|
g_signal_connect(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
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,7 @@ Geometry pComboBox::minimumGeometry() {
|
||||||
|
|
||||||
void pComboBox::reset() {
|
void pComboBox::reset() {
|
||||||
locked = true;
|
locked = true;
|
||||||
for(signed n = itemCounter - 1; n >= 0; n--) {
|
gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(gtkWidget))));
|
||||||
gtk_combo_box_remove_text(GTK_COMBO_BOX(gtkWidget), n);
|
|
||||||
}
|
|
||||||
itemCounter = 0;
|
itemCounter = 0;
|
||||||
locked = false;
|
locked = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,17 +112,17 @@ bool pHexEdit::keyPress(unsigned scancode) {
|
||||||
unsigned cursorY = position / lineWidth;
|
unsigned cursorY = position / lineWidth;
|
||||||
unsigned cursorX = position % lineWidth;
|
unsigned cursorX = position % lineWidth;
|
||||||
|
|
||||||
if(scancode == GDK_Home) {
|
if(scancode == GDK_KEY_Home) {
|
||||||
setCursorPosition(cursorY * lineWidth + 10);
|
setCursorPosition(cursorY * lineWidth + 10);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(scancode == GDK_End) {
|
if(scancode == GDK_KEY_End) {
|
||||||
setCursorPosition(cursorY * lineWidth + 10 + (hexEdit.state.columns * 3 - 1));
|
setCursorPosition(cursorY * lineWidth + 10 + (hexEdit.state.columns * 3 - 1));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(scancode == GDK_Up) {
|
if(scancode == GDK_KEY_Up) {
|
||||||
if(cursorY != 0) return false;
|
if(cursorY != 0) return false;
|
||||||
|
|
||||||
signed newOffset = hexEdit.state.offset - hexEdit.state.columns;
|
signed newOffset = hexEdit.state.offset - hexEdit.state.columns;
|
||||||
|
@ -133,7 +133,7 @@ bool pHexEdit::keyPress(unsigned scancode) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(scancode == GDK_Down) {
|
if(scancode == GDK_KEY_Down) {
|
||||||
if(cursorY != hexEdit.state.rows - 1) return false;
|
if(cursorY != hexEdit.state.rows - 1) return false;
|
||||||
|
|
||||||
signed newOffset = hexEdit.state.offset + hexEdit.state.columns;
|
signed newOffset = hexEdit.state.offset + hexEdit.state.columns;
|
||||||
|
@ -144,7 +144,7 @@ bool pHexEdit::keyPress(unsigned scancode) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(scancode == GDK_Page_Up) {
|
if(scancode == GDK_KEY_Page_Up) {
|
||||||
signed newOffset = hexEdit.state.offset - hexEdit.state.columns * hexEdit.state.rows;
|
signed newOffset = hexEdit.state.offset - hexEdit.state.columns * hexEdit.state.rows;
|
||||||
if(newOffset >= 0) {
|
if(newOffset >= 0) {
|
||||||
hexEdit.setOffset(newOffset);
|
hexEdit.setOffset(newOffset);
|
||||||
|
@ -155,7 +155,7 @@ bool pHexEdit::keyPress(unsigned scancode) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(scancode == GDK_Page_Down) {
|
if(scancode == GDK_KEY_Page_Down) {
|
||||||
signed newOffset = hexEdit.state.offset + hexEdit.state.columns * hexEdit.state.rows;
|
signed newOffset = hexEdit.state.offset + hexEdit.state.columns * hexEdit.state.rows;
|
||||||
for(unsigned n = 0; n < hexEdit.state.rows; n++) {
|
for(unsigned n = 0; n < hexEdit.state.rows; n++) {
|
||||||
if(newOffset + hexEdit.state.columns * hexEdit.state.rows - (hexEdit.state.columns - 1) <= hexEdit.state.length) {
|
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) {
|
void pHorizontalSlider::setLength(unsigned length) {
|
||||||
length += length == 0;
|
length += length == 0;
|
||||||
gtk_range_set_range(GTK_RANGE(gtkWidget), 0, length - 1);
|
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) {
|
void pHorizontalSlider::setPosition(unsigned position) {
|
||||||
|
@ -24,5 +25,6 @@ void pHorizontalSlider::setPosition(unsigned position) {
|
||||||
void pHorizontalSlider::constructor() {
|
void pHorizontalSlider::constructor() {
|
||||||
gtkWidget = gtk_hscale_new_with_range(0, 100, 1);
|
gtkWidget = gtk_hscale_new_with_range(0, 100, 1);
|
||||||
gtk_scale_set_draw_value(GTK_SCALE(gtkWidget), false);
|
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);
|
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) {
|
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) {
|
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) {
|
void pVerticalSlider::setLength(unsigned length) {
|
||||||
length += length == 0;
|
length += length == 0;
|
||||||
gtk_range_set_range(GTK_RANGE(gtkWidget), 0, length - 1);
|
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) {
|
void pVerticalSlider::setPosition(unsigned position) {
|
||||||
|
@ -24,5 +25,6 @@ void pVerticalSlider::setPosition(unsigned position) {
|
||||||
void pVerticalSlider::constructor() {
|
void pVerticalSlider::constructor() {
|
||||||
gtkWidget = gtk_vscale_new_with_range(0, 100, 1);
|
gtkWidget = gtk_vscale_new_with_range(0, 100, 1);
|
||||||
gtk_scale_set_draw_value(GTK_SCALE(gtkWidget), false);
|
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);
|
g_signal_connect_swapped(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(VerticalSlider_change), (gpointer)&verticalSlider);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
uintptr_t pViewport::handle() {
|
uintptr_t pViewport::handle() {
|
||||||
return GDK_WINDOW_XID(gtkWidget->window);
|
return GDK_WINDOW_XID(gtk_widget_get_window(gtkWidget));
|
||||||
}
|
}
|
||||||
|
|
||||||
void pViewport::constructor() {
|
void pViewport::constructor() {
|
||||||
|
|
|
@ -1,70 +1,57 @@
|
||||||
static void Action_setFont(GtkWidget *widget, gpointer font);
|
static void Action_setFont(GtkWidget *widget, gpointer font);
|
||||||
static void Widget_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();
|
if(window->onClose) window->onClose();
|
||||||
window->setVisible(false);
|
window->setVisible(false);
|
||||||
return true;
|
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;
|
if(gtk_widget_get_realized(window->p.widget) == false) return false;
|
||||||
|
GdkWindow *gdkWindow = gtk_widget_get_window(widget);
|
||||||
|
|
||||||
//update geometry settings
|
//update geometry settings
|
||||||
Display *display = XOpenDisplay(0);
|
GdkRectangle border, client;
|
||||||
XWindowAttributes attributes, parentAttributes;
|
gdk_window_get_frame_extents(gdkWindow, &border);
|
||||||
XGetWindowAttributes(display, GDK_WINDOW_XID(window->p.widget->window), &attributes);
|
gdk_window_get_geometry(gdkWindow, 0, 0, &client.width, &client.height, 0);
|
||||||
X11Window rootWindow, parentWindow, *childWindow = 0;
|
gdk_window_get_origin(gdkWindow, &client.x, &client.y);
|
||||||
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);
|
|
||||||
|
|
||||||
settings.frameGeometryX = attributes.x;
|
settings.frameGeometryX = client.x - border.x;
|
||||||
settings.frameGeometryY = attributes.y;
|
settings.frameGeometryY = client.y - border.y;
|
||||||
settings.frameGeometryWidth = parentAttributes.width - attributes.width;
|
settings.frameGeometryWidth = border.width - client.width;
|
||||||
settings.frameGeometryHeight = parentAttributes.height - attributes.height;
|
settings.frameGeometryHeight = border.height - client.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();
|
|
||||||
|
|
||||||
//move
|
//move
|
||||||
if(window->p.locked == false && window->state.fullScreen == false) {
|
if(event->configure.x != window->p.lastConfigure.x
|
||||||
if(window->state.geometry.x != eventX || window->state.geometry.y != eventY) {
|
|| event->configure.y != window->p.lastConfigure.y
|
||||||
window->state.geometry.x = eventX;
|
) {
|
||||||
window->state.geometry.y = eventY;
|
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
|
//size
|
||||||
if(window->p.locked == false && window->state.fullScreen == false) {
|
if(event->configure.width != window->p.lastConfigure.width
|
||||||
if(window->state.geometry.width != eventWidth || window->state.geometry.height != eventHeight) {
|
|| event->configure.height != window->p.lastConfigure.height
|
||||||
window->state.geometry.width = eventWidth;
|
) {
|
||||||
window->state.geometry.height = eventHeight;
|
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) {
|
||||||
|
Geometry geometry = window->geometry();
|
||||||
|
geometry.x = geometry.y = 0;
|
||||||
|
layout.setGeometry(geometry);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(window->p.locked == false && window->onSize) window->onSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(layout, window->state.layout) {
|
window->p.lastConfigure = event->configure;
|
||||||
Geometry geometry = window->geometry();
|
|
||||||
geometry.x = geometry.y = 0;
|
|
||||||
layout.setGeometry(geometry);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(window->onSize) window->onSize();
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +64,7 @@ void pWindow::append(Layout &layout) {
|
||||||
|
|
||||||
void pWindow::append(Menu &subMenu) {
|
void pWindow::append(Menu &subMenu) {
|
||||||
if(window.state.menuFont) subMenu.p.setFont(*window.state.menuFont);
|
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);
|
gtk_widget_show(subMenu.p.widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +77,12 @@ void pWindow::append(Widget &widget) {
|
||||||
widget.setVisible();
|
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() {
|
Geometry pWindow::frameMargin() {
|
||||||
if(window.state.fullScreen) return { 0, menuHeight(), 0, menuHeight() + statusHeight() };
|
if(window.state.fullScreen) return { 0, menuHeight(), 0, menuHeight() + statusHeight() };
|
||||||
return {
|
return {
|
||||||
|
@ -111,13 +104,13 @@ Geometry pWindow::geometry() {
|
||||||
return window.state.geometry;
|
return window.state.geometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pWindow::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) {
|
void pWindow::setBackgroundColor(const Color &color) {
|
||||||
GdkColor color;
|
GdkColor gdkColor;
|
||||||
color.pixel = (red << 16) | (green << 8) | (blue << 0);
|
gdkColor.pixel = (color.red << 16) | (color.green << 8) | (color.blue << 0);
|
||||||
color.red = (red << 8) | (red << 0);
|
gdkColor.red = (color.red << 8) | (color.red << 0);
|
||||||
color.green = (green << 8) | (green << 0);
|
gdkColor.green = (color.green << 8) | (color.green << 0);
|
||||||
color.blue = (blue << 8) | (blue << 0);
|
gdkColor.blue = (color.blue << 8) | (color.blue << 0);
|
||||||
gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &color);
|
gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &gdkColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pWindow::setFocused() {
|
void pWindow::setFocused() {
|
||||||
|
@ -129,14 +122,12 @@ void pWindow::setFullScreen(bool fullScreen) {
|
||||||
gtk_window_unfullscreen(GTK_WINDOW(widget));
|
gtk_window_unfullscreen(GTK_WINDOW(widget));
|
||||||
gtk_window_set_resizable(GTK_WINDOW(widget), window.state.resizable);
|
gtk_window_set_resizable(GTK_WINDOW(widget), window.state.resizable);
|
||||||
gtk_window_set_decorated(GTK_WINDOW(widget), true);
|
gtk_window_set_decorated(GTK_WINDOW(widget), true);
|
||||||
locked = true;
|
|
||||||
for(unsigned n = 0; n < 4; n++) {
|
for(unsigned n = 0; n < 4; n++) {
|
||||||
setGeometry(window.state.geometry);
|
setGeometry(window.state.geometry);
|
||||||
gtk_widget_set_size_request(widget, -1, -1);
|
gtk_widget_set_size_request(widget, -1, -1);
|
||||||
OS::processEvents();
|
OS::processEvents();
|
||||||
usleep(2000);
|
usleep(2000);
|
||||||
}
|
}
|
||||||
locked = false;
|
|
||||||
} else {
|
} else {
|
||||||
gtk_window_fullscreen(GTK_WINDOW(widget));
|
gtk_window_fullscreen(GTK_WINDOW(widget));
|
||||||
gtk_window_set_decorated(GTK_WINDOW(widget), false);
|
gtk_window_set_decorated(GTK_WINDOW(widget), false);
|
||||||
|
@ -224,8 +215,8 @@ void pWindow::constructor() {
|
||||||
setTitle("");
|
setTitle("");
|
||||||
setGeometry(window.state.geometry);
|
setGeometry(window.state.geometry);
|
||||||
|
|
||||||
g_signal_connect_swapped(G_OBJECT(widget), "delete-event", G_CALLBACK(Window_close), (gpointer)&window);
|
g_signal_connect(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), "configure-event", G_CALLBACK(Window_configure), (gpointer)&window);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned pWindow::menuHeight() {
|
unsigned pWindow::menuHeight() {
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define X11None 0L
|
#define X11None 0L
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
#include <gdk/gdk.h>
|
||||||
#include <gdk/gdkx.h>
|
#include <gdk/gdkx.h>
|
||||||
#include <cairo.h>
|
#include <cairo.h>
|
||||||
#include <gdk/gdkkeysyms.h>
|
#include <gdk/gdkkeysyms.h>
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "widget/check-box.cpp"
|
#include "widget/check-box.cpp"
|
||||||
#include "widget/combo-box.cpp"
|
#include "widget/combo-box.cpp"
|
||||||
#include "widget/hex-edit.cpp"
|
#include "widget/hex-edit.cpp"
|
||||||
|
#include "widget/horizontal-scroll-bar.cpp"
|
||||||
#include "widget/horizontal-slider.cpp"
|
#include "widget/horizontal-slider.cpp"
|
||||||
#include "widget/label.cpp"
|
#include "widget/label.cpp"
|
||||||
#include "widget/line-edit.cpp"
|
#include "widget/line-edit.cpp"
|
||||||
|
@ -27,6 +28,7 @@
|
||||||
#include "widget/progress-bar.cpp"
|
#include "widget/progress-bar.cpp"
|
||||||
#include "widget/radio-box.cpp"
|
#include "widget/radio-box.cpp"
|
||||||
#include "widget/text-edit.cpp"
|
#include "widget/text-edit.cpp"
|
||||||
|
#include "widget/vertical-scroll-bar.cpp"
|
||||||
#include "widget/vertical-slider.cpp"
|
#include "widget/vertical-slider.cpp"
|
||||||
#include "widget/viewport.cpp"
|
#include "widget/viewport.cpp"
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
** Meta object code from reading C++ file 'qt.moc.hpp'
|
** 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)
|
** by: The Qt Meta Object Compiler version 62 (Qt 4.7.0)
|
||||||
**
|
**
|
||||||
** WARNING! All changes made in this file will be lost!
|
** 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;
|
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[] = {
|
static const uint qt_meta_data_pHorizontalSlider[] = {
|
||||||
|
|
||||||
// content:
|
// content:
|
||||||
|
@ -918,6 +979,67 @@ int pTextEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
|
||||||
}
|
}
|
||||||
return _id;
|
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[] = {
|
static const uint qt_meta_data_pVerticalSlider[] = {
|
||||||
|
|
||||||
// content:
|
// content:
|
||||||
|
|
|
@ -101,10 +101,11 @@ public:
|
||||||
void append(Layout &layout);
|
void append(Layout &layout);
|
||||||
void append(Menu &menu);
|
void append(Menu &menu);
|
||||||
void append(Widget &widget);
|
void append(Widget &widget);
|
||||||
|
Color backgroundColor();
|
||||||
Geometry frameMargin();
|
Geometry frameMargin();
|
||||||
bool focused();
|
bool focused();
|
||||||
Geometry geometry();
|
Geometry geometry();
|
||||||
void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue);
|
void setBackgroundColor(const Color &color);
|
||||||
void setFocused();
|
void setFocused();
|
||||||
void setFullScreen(bool fullScreen);
|
void setFullScreen(bool fullScreen);
|
||||||
void setGeometry(const Geometry &geometry);
|
void setGeometry(const Geometry &geometry);
|
||||||
|
@ -330,6 +331,25 @@ public slots:
|
||||||
void onScroll();
|
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 {
|
struct pHorizontalSlider : public QObject, public pWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -462,6 +482,25 @@ public slots:
|
||||||
void onChange();
|
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 {
|
struct pVerticalSlider : public QObject, public pWidget {
|
||||||
Q_OBJECT
|
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);
|
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() {
|
Geometry pWindow::frameMargin() {
|
||||||
unsigned menuHeight = window.state.menuVisible ? qtMenu->height() : 0;
|
unsigned menuHeight = window.state.menuVisible ? qtMenu->height() : 0;
|
||||||
unsigned statusHeight = window.state.statusVisible ? qtStatus->height() : 0;
|
unsigned statusHeight = window.state.statusVisible ? qtStatus->height() : 0;
|
||||||
|
@ -43,9 +49,9 @@ Geometry pWindow::geometry() {
|
||||||
return window.state.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;
|
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->setPalette(palette);
|
||||||
qtContainer->setAutoFillBackground(true);
|
qtContainer->setAutoFillBackground(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "widget/check-box.cpp"
|
#include "widget/check-box.cpp"
|
||||||
#include "widget/combo-box.cpp"
|
#include "widget/combo-box.cpp"
|
||||||
#include "widget/hex-edit.cpp"
|
#include "widget/hex-edit.cpp"
|
||||||
|
#include "widget/horizontal-scroll-bar.cpp"
|
||||||
#include "widget/horizontal-slider.cpp"
|
#include "widget/horizontal-slider.cpp"
|
||||||
#include "widget/label.cpp"
|
#include "widget/label.cpp"
|
||||||
#include "widget/line-edit.cpp"
|
#include "widget/line-edit.cpp"
|
||||||
|
@ -25,6 +26,7 @@
|
||||||
#include "widget/progress-bar.cpp"
|
#include "widget/progress-bar.cpp"
|
||||||
#include "widget/radio-box.cpp"
|
#include "widget/radio-box.cpp"
|
||||||
#include "widget/text-edit.cpp"
|
#include "widget/text-edit.cpp"
|
||||||
|
#include "widget/vertical-scroll-bar.cpp"
|
||||||
#include "widget/vertical-slider.cpp"
|
#include "widget/vertical-slider.cpp"
|
||||||
#include "widget/viewport.cpp"
|
#include "widget/viewport.cpp"
|
||||||
|
|
||||||
|
|
|
@ -63,10 +63,11 @@ struct pWindow : public pObject {
|
||||||
void append(Layout &layout);
|
void append(Layout &layout);
|
||||||
void append(Menu &menu);
|
void append(Menu &menu);
|
||||||
void append(Widget &widget);
|
void append(Widget &widget);
|
||||||
|
Color backgroundColor();
|
||||||
bool focused();
|
bool focused();
|
||||||
Geometry frameMargin();
|
Geometry frameMargin();
|
||||||
Geometry geometry();
|
Geometry geometry();
|
||||||
void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue);
|
void setBackgroundColor(const Color &color);
|
||||||
void setFocused();
|
void setFocused();
|
||||||
void setFullScreen(bool fullScreen);
|
void setFullScreen(bool fullScreen);
|
||||||
void setGeometry(const Geometry &geometry);
|
void setGeometry(const Geometry &geometry);
|
||||||
|
@ -214,6 +215,17 @@ struct pHexEdit : public pWidget {
|
||||||
void constructor();
|
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 {
|
struct pHorizontalSlider : public pWidget {
|
||||||
HorizontalSlider &horizontalSlider;
|
HorizontalSlider &horizontalSlider;
|
||||||
|
|
||||||
|
@ -300,6 +312,17 @@ struct pTextEdit : public pWidget {
|
||||||
void constructor();
|
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 {
|
struct pVerticalSlider : public pWidget {
|
||||||
VerticalSlider &verticalSlider;
|
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) {
|
void pWindow::append(Widget &widget) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Color pWindow::backgroundColor() {
|
||||||
|
return { 0, 0, 0, 255 };
|
||||||
|
}
|
||||||
|
|
||||||
bool pWindow::focused() {
|
bool pWindow::focused() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +23,7 @@ Geometry pWindow::geometry() {
|
||||||
return { 0, 0, 0, 0 };
|
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() {
|
void pWindow::setFocused() {
|
||||||
|
|
|
@ -6,3 +6,4 @@ synchronize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronize "nall"
|
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() {
|
Geometry pVerticalSlider::minimumGeometry() {
|
||||||
return { 0, 0, 25, 0 };
|
return { 0, 0, 0, 25 };
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned pVerticalSlider::position() {
|
unsigned pVerticalSlider::position() {
|
||||||
|
|
|
@ -16,6 +16,12 @@ void pWindow::append(Widget &widget) {
|
||||||
widget.p.setParent(window);
|
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() {
|
bool pWindow::focused() {
|
||||||
return (GetForegroundWindow() == hwnd);
|
return (GetForegroundWindow() == hwnd);
|
||||||
}
|
}
|
||||||
|
@ -37,10 +43,15 @@ Geometry pWindow::frameMargin() {
|
||||||
Geometry pWindow::geometry() {
|
Geometry pWindow::geometry() {
|
||||||
Geometry margin = frameMargin();
|
Geometry margin = frameMargin();
|
||||||
|
|
||||||
//note: GetWindowRect returns -32000(x),-32000(y) when window is minimized
|
RECT rc;
|
||||||
WINDOWPLACEMENT wp;
|
if(IsIconic(hwnd)) {
|
||||||
GetWindowPlacement(hwnd, &wp);
|
//GetWindowRect returns -32000(x),-32000(y) when window is minimized
|
||||||
RECT rc = wp.rcNormalPosition;
|
WINDOWPLACEMENT wp;
|
||||||
|
GetWindowPlacement(hwnd, &wp);
|
||||||
|
rc = wp.rcNormalPosition;
|
||||||
|
} else {
|
||||||
|
GetWindowRect(hwnd, &rc);
|
||||||
|
}
|
||||||
|
|
||||||
signed x = rc.left + margin.x;
|
signed x = rc.left + margin.x;
|
||||||
signed y = rc.top + margin.y;
|
signed y = rc.top + margin.y;
|
||||||
|
@ -50,9 +61,9 @@ Geometry pWindow::geometry() {
|
||||||
return { x, y, width, height };
|
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);
|
if(brush) DeleteObject(brush);
|
||||||
brushColor = RGB(red, green, blue);
|
brushColor = RGB(color.red, color.green, color.blue);
|
||||||
brush = CreateSolidBrush(brushColor);
|
brush = CreateSolidBrush(brushColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "widget/check-box.cpp"
|
#include "widget/check-box.cpp"
|
||||||
#include "widget/combo-box.cpp"
|
#include "widget/combo-box.cpp"
|
||||||
#include "widget/hex-edit.cpp"
|
#include "widget/hex-edit.cpp"
|
||||||
|
#include "widget/horizontal-scroll-bar.cpp"
|
||||||
#include "widget/horizontal-slider.cpp"
|
#include "widget/horizontal-slider.cpp"
|
||||||
#include "widget/label.cpp"
|
#include "widget/label.cpp"
|
||||||
#include "widget/line-edit.cpp"
|
#include "widget/line-edit.cpp"
|
||||||
|
@ -26,6 +27,7 @@
|
||||||
#include "widget/progress-bar.cpp"
|
#include "widget/progress-bar.cpp"
|
||||||
#include "widget/radio-box.cpp"
|
#include "widget/radio-box.cpp"
|
||||||
#include "widget/text-edit.cpp"
|
#include "widget/text-edit.cpp"
|
||||||
|
#include "widget/vertical-scroll-bar.cpp"
|
||||||
#include "widget/vertical-slider.cpp"
|
#include "widget/vertical-slider.cpp"
|
||||||
#include "widget/viewport.cpp"
|
#include "widget/viewport.cpp"
|
||||||
|
|
||||||
|
@ -175,7 +177,7 @@ void pOS::initialize() {
|
||||||
WNDCLASS wc;
|
WNDCLASS wc;
|
||||||
wc.cbClsExtra = 0;
|
wc.cbClsExtra = 0;
|
||||||
wc.cbWndExtra = 0;
|
wc.cbWndExtra = 0;
|
||||||
wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
|
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
|
||||||
wc.hCursor = LoadCursor(0, IDC_ARROW);
|
wc.hCursor = LoadCursor(0, IDC_ARROW);
|
||||||
wc.hIcon = LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(2));
|
wc.hIcon = LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(2));
|
||||||
wc.hInstance = GetModuleHandle(0);
|
wc.hInstance = GetModuleHandle(0);
|
||||||
|
@ -199,7 +201,7 @@ void pOS::initialize() {
|
||||||
|
|
||||||
wc.cbClsExtra = 0;
|
wc.cbClsExtra = 0;
|
||||||
wc.cbWndExtra = 0;
|
wc.cbWndExtra = 0;
|
||||||
wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
|
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
|
||||||
wc.hCursor = LoadCursor(0, IDC_ARROW);
|
wc.hCursor = LoadCursor(0, IDC_ARROW);
|
||||||
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
|
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
|
||||||
wc.hInstance = GetModuleHandle(0);
|
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_HSCROLL:
|
||||||
case WM_VSCROLL: {
|
case WM_VSCROLL: {
|
||||||
unsigned id = LOWORD(wparam);
|
Object *object = 0;
|
||||||
HWND control = GetDlgItem(window.p.hwnd, id);
|
if(lparam) {
|
||||||
if(control == 0) break;
|
object = (Object*)GetWindowLongPtr((HWND)lparam, GWLP_USERDATA);
|
||||||
Object *object = (Object*)GetWindowLongPtr(control, GWLP_USERDATA);
|
} else {
|
||||||
|
unsigned id = LOWORD(wparam);
|
||||||
|
HWND control = GetDlgItem(window.p.hwnd, id);
|
||||||
|
if(control == 0) break;
|
||||||
|
object = (Object*)GetWindowLongPtr(control, GWLP_USERDATA);
|
||||||
|
}
|
||||||
if(object == 0) break;
|
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)) {
|
if(dynamic_cast<HorizontalSlider*>(object)) {
|
||||||
HorizontalSlider &horizontalSlider = (HorizontalSlider&)*object;
|
HorizontalSlider &horizontalSlider = (HorizontalSlider&)*object;
|
||||||
if(horizontalSlider.state.position != horizontalSlider.position()) {
|
if(horizontalSlider.state.position != horizontalSlider.position()) {
|
||||||
|
|
|
@ -78,10 +78,11 @@ struct pWindow : public pObject {
|
||||||
void append(Layout &layout);
|
void append(Layout &layout);
|
||||||
void append(Menu &menu);
|
void append(Menu &menu);
|
||||||
void append(Widget &widget);
|
void append(Widget &widget);
|
||||||
|
Color backgroundColor();
|
||||||
bool focused();
|
bool focused();
|
||||||
Geometry frameMargin();
|
Geometry frameMargin();
|
||||||
Geometry geometry();
|
Geometry geometry();
|
||||||
void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue);
|
void setBackgroundColor(const Color &color);
|
||||||
void setFocused();
|
void setFocused();
|
||||||
void setFullScreen(bool fullScreen);
|
void setFullScreen(bool fullScreen);
|
||||||
void setGeometry(const Geometry &geometry);
|
void setGeometry(const Geometry &geometry);
|
||||||
|
@ -250,6 +251,19 @@ struct pHexEdit : public pWidget {
|
||||||
void setParent(Window &parent);
|
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 {
|
struct pHorizontalSlider : public pWidget {
|
||||||
HorizontalSlider &horizontalSlider;
|
HorizontalSlider &horizontalSlider;
|
||||||
|
|
||||||
|
@ -350,6 +364,19 @@ struct pTextEdit : public pWidget {
|
||||||
void setParent(Window &parent);
|
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 {
|
struct pVerticalSlider : public pWidget {
|
||||||
VerticalSlider &verticalSlider;
|
VerticalSlider &verticalSlider;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
namespace SNES {
|
namespace SNES {
|
||||||
namespace Info {
|
namespace Info {
|
||||||
static const char Name[] = "bsnes";
|
static const char Name[] = "bsnes";
|
||||||
static const char Version[] = "080.04";
|
static const char Version[] = "080.05";
|
||||||
static const unsigned SerializerVersion = 21;
|
static const unsigned SerializerVersion = 21;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,13 @@ ui_objects += ruby phoenix
|
||||||
|
|
||||||
# platform
|
# platform
|
||||||
ifeq ($(platform),x)
|
ifeq ($(platform),x)
|
||||||
# phoenix_compile = $(call compile,-DPHOENIX_GTK `pkg-config --cflags gtk+-2.0`)
|
ifeq ($(phoenix),gtk)
|
||||||
# link += `pkg-config --libs gtk+-2.0`
|
phoenix_compile = $(call compile,-DPHOENIX_GTK `pkg-config --cflags gtk+-2.0`)
|
||||||
|
link += `pkg-config --libs gtk+-2.0`
|
||||||
phoenix_compile = $(call compile,-DPHOENIX_QT `pkg-config --cflags QtCore QtGui`)
|
else
|
||||||
link += `pkg-config --libs QtCore QtGui`
|
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 := video.glx video.xv video.sdl
|
||||||
ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.pulseaudiosimple audio.ao
|
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) {
|
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::Up: return inputState[keyboard(0)[Keyboard::Up]];
|
||||||
case GameBoy::Input::Down: return inputState[keyboard(0)[Keyboard::Down]];
|
case GameBoy::Input::Down: return inputState[keyboard(0)[Keyboard::Down]];
|
||||||
case GameBoy::Input::Left: return inputState[keyboard(0)[Keyboard::Left]];
|
case GameBoy::Input::Left: return inputState[keyboard(0)[Keyboard::Left]];
|
||||||
|
|
|
@ -7,11 +7,13 @@ ui_objects += $(if $(call streq,$(platform),win),resource)
|
||||||
|
|
||||||
# platform
|
# platform
|
||||||
ifeq ($(platform),x)
|
ifeq ($(platform),x)
|
||||||
# phoenix_compile = $(call compile,-DPHOENIX_GTK `pkg-config --cflags gtk+-2.0`)
|
ifeq ($(phoenix),gtk)
|
||||||
# link += `pkg-config --libs gtk+-2.0`
|
phoenix_compile = $(call compile,-DPHOENIX_GTK `pkg-config --cflags gtk+-2.0`)
|
||||||
|
link += `pkg-config --libs gtk+-2.0`
|
||||||
phoenix_compile = $(call compile,-DPHOENIX_QT `pkg-config --cflags QtCore QtGui`)
|
else
|
||||||
link += `pkg-config --libs QtCore QtGui`
|
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 := video.glx video.xv video.sdl
|
||||||
ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.pulseaudiosimple audio.ao
|
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(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(settings.focusPolicy = 0, "settings.focusPolicy");
|
||||||
|
|
||||||
attach(controller.port1 = 1, "controller.port1");
|
attach(controller.port1 = 1, "controller.port1");
|
||||||
|
|
|
@ -30,6 +30,7 @@ struct Configuration : public configuration {
|
||||||
} input;
|
} input;
|
||||||
|
|
||||||
struct Settings {
|
struct Settings {
|
||||||
|
bool startFullScreen;
|
||||||
unsigned focusPolicy;
|
unsigned focusPolicy;
|
||||||
} settings;
|
} settings;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ void AboutWindow::create() {
|
||||||
application.addWindow(this, "AboutWindow", "160,160");
|
application.addWindow(this, "AboutWindow", "160,160");
|
||||||
setTitle("About bsnes ...");
|
setTitle("About bsnes ...");
|
||||||
setResizable(false);
|
setResizable(false);
|
||||||
setBackgroundColor(255, 255, 255);
|
setBackgroundColor({ 255, 255, 255 });
|
||||||
|
|
||||||
information.setText({
|
information.setText({
|
||||||
"bsnes v", SNES::Info::Version, " ~ Profile: ", SNES::Info::Profile,
|
"bsnes v", SNES::Info::Version, " ~ Profile: ", SNES::Info::Profile,
|
||||||
|
|
|
@ -7,7 +7,7 @@ void MainWindow::create() {
|
||||||
application.addWindow(this, "MainWindow", "128,128");
|
application.addWindow(this, "MainWindow", "128,128");
|
||||||
setMenuFont(application.proportionalFont);
|
setMenuFont(application.proportionalFont);
|
||||||
setStatusFont(application.proportionalFontBold);
|
setStatusFont(application.proportionalFontBold);
|
||||||
setBackgroundColor(0, 0, 0);
|
setBackgroundColor({ 0, 0, 0 });
|
||||||
|
|
||||||
system.setText("System");
|
system.setText("System");
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ void InputMapper::poll_hotkeys(unsigned scancode, int16_t value) {
|
||||||
|
|
||||||
//fullscreen
|
//fullscreen
|
||||||
if(scancode == hotkeysGeneral.fullscreenToggle.scancode) {
|
if(scancode == hotkeysGeneral.fullscreenToggle.scancode) {
|
||||||
utility.setFullscreen(!utility.fullscreen);
|
utility.setFullScreen(!utility.fullScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
//mouse capture
|
//mouse capture
|
||||||
|
|
|
@ -109,6 +109,7 @@ void Application::main(int argc, char **argv) {
|
||||||
utility.setControllers();
|
utility.setControllers();
|
||||||
utility.setFilter();
|
utility.setFilter();
|
||||||
utility.setShader();
|
utility.setShader();
|
||||||
|
if(config.settings.startFullScreen) utility.setFullScreen();
|
||||||
|
|
||||||
if(argc == 2) cartridge.loadNormal(argv[1]);
|
if(argc == 2) cartridge.loadNormal(argv[1]);
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ void CheatEditor::load() {
|
||||||
cheatList.reset();
|
cheatList.reset();
|
||||||
for(unsigned i = 0; i < 128; i++) {
|
for(unsigned i = 0; i < 128; i++) {
|
||||||
cheatList.append("");
|
cheatList.append("");
|
||||||
cheatText[i][CheatSlot] = rdecimal<3>(i + 1);
|
cheatText[i][CheatSlot] = decimal<3>(i + 1);
|
||||||
cheatText[i][CheatCode] = "";
|
cheatText[i][CheatCode] = "";
|
||||||
cheatText[i][CheatDesc] = "";
|
cheatText[i][CheatDesc] = "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ void StateManager::synchronize() {
|
||||||
|
|
||||||
void StateManager::refresh() {
|
void StateManager::refresh() {
|
||||||
for(unsigned i = 0; i < 32; i++) {
|
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();
|
stateList.autoSizeColumns();
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,13 +82,13 @@ void Utility::setScale(unsigned scale) {
|
||||||
mainWindow.setGeometry({ geom.x, geom.y, width, height });
|
mainWindow.setGeometry({ geom.x, geom.y, width, height });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Utility::setFullscreen(bool fullscreen) {
|
void Utility::setFullScreen(bool fullScreen) {
|
||||||
this->fullscreen = fullscreen;
|
this->fullScreen = fullScreen;
|
||||||
|
|
||||||
mainWindow.setMenuVisible(!fullscreen);
|
mainWindow.setMenuVisible(!fullScreen);
|
||||||
mainWindow.setStatusVisible(!fullscreen);
|
mainWindow.setStatusVisible(!fullScreen);
|
||||||
mainWindow.setFullScreen(fullscreen);
|
mainWindow.setFullScreen(fullScreen);
|
||||||
if(fullscreen == false) {
|
if(fullScreen == false) {
|
||||||
input.unacquire();
|
input.unacquire();
|
||||||
setScale();
|
setScale();
|
||||||
} else {
|
} else {
|
||||||
|
@ -215,6 +215,6 @@ void Utility::loadState(unsigned slot) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Utility::Utility() {
|
Utility::Utility() {
|
||||||
fullscreen = false;
|
fullScreen = false;
|
||||||
statusTime = 0;
|
statusTime = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ struct Utility : property<Utility> {
|
||||||
void setControllers();
|
void setControllers();
|
||||||
|
|
||||||
void setScale(unsigned scale = 0);
|
void setScale(unsigned scale = 0);
|
||||||
void setFullscreen(bool fullscreen = true);
|
void setFullScreen(bool fullScreen = true);
|
||||||
|
|
||||||
void setFilter();
|
void setFilter();
|
||||||
void setShader();
|
void setShader();
|
||||||
|
@ -21,7 +21,7 @@ struct Utility : property<Utility> {
|
||||||
|
|
||||||
Utility();
|
Utility();
|
||||||
|
|
||||||
bool fullscreen;
|
bool fullScreen;
|
||||||
unsigned viewportX, viewportY;
|
unsigned viewportX, viewportY;
|
||||||
unsigned viewportWidth, viewportHeight;
|
unsigned viewportWidth, viewportHeight;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue