mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-09-19 00:21:43 +02:00
Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6c3aec7dc9 | ||
|
4016ae1d43 | ||
|
9e53c51b58 | ||
|
ce2b543679 | ||
|
1a29b59225 | ||
|
1926561ced | ||
|
e2db2c24fc | ||
|
8a53e9ed22 | ||
|
5286481d8d | ||
|
440a59c879 | ||
|
96e9333ec2 | ||
|
775c111fef | ||
|
3ffa44cef9 | ||
|
f28d70f9e6 | ||
|
73fdbf893f | ||
|
da5263bfc3 | ||
|
449a3ad426 |
@@ -1,7 +1,7 @@
|
||||
include nall/Makefile
|
||||
snes := snes
|
||||
profile := compatibility
|
||||
ui := ui-qt
|
||||
profile := accuracy
|
||||
ui := ui-phoenix
|
||||
|
||||
# compiler
|
||||
c := $(compiler) -std=gnu99
|
||||
@@ -62,9 +62,11 @@ endif
|
||||
install:
|
||||
ifeq ($(platform),x)
|
||||
install -D -m 755 out/bsnes $(DESTDIR)$(prefix)/bin/bsnes
|
||||
install -D -m 644 qt/data/bsnes.png $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png
|
||||
install -D -m 644 qt/data/bsnes.desktop $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
|
||||
gconftool-2 --type bool --set /desktop/gnome/interface/menus_have_icons true
|
||||
install -D -m 644 data/bsnes.png $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png
|
||||
install -D -m 644 data/bsnes.desktop $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
|
||||
test -d ~/.bsnes || mkdir ~/.bsnes
|
||||
cp data/cheats.xml ~/.bsnes/cheats.xml
|
||||
chmod 777 ~/.bsnes ~/.bsnes/cheats.xml
|
||||
endif
|
||||
|
||||
uninstall:
|
||||
@@ -88,6 +90,6 @@ clean: ui_clean
|
||||
-@$(call delete,*.manifest)
|
||||
|
||||
archive-all:
|
||||
tar -cjf bsnes.tar.bz2 launcher libco nall obj out phoenix ruby snes ui-phoenix ui-qt Makefile cc.bat clean.bat sync.sh
|
||||
tar -cjf bsnes.tar.bz2 data launcher libco nall obj out phoenix ruby snes ui-phoenix ui-qt Makefile cc.bat clean.bat sync.sh
|
||||
|
||||
help:;
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<assemblyIdentity type="win32" name="bsnes" version="1.0.0.0" processorArchitecture="x86"/>
|
||||
<assemblyIdentity type="win32" name="bsnes" version="1.0.0.0" processorArchitecture="*"/>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df" language="*"/>
|
||||
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
</assembly>
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
File diff suppressed because it is too large
Load Diff
@@ -16,10 +16,10 @@ int main(int argc, char **argv) {
|
||||
unused = realpath(nall::utf8_t(argw[0]), path);
|
||||
#endif
|
||||
string realPath = dir(path);
|
||||
string basePath = string(dir(path), "bsnes.cfg");
|
||||
string basePath = string(dir(path), "bsnes-qt.cfg");
|
||||
unused = userpath(path);
|
||||
if(!strend(path, "/") && !strend(path, "\\")) strcat(path, "/");
|
||||
string userPath = string(path, ".bsnes/bsnes.cfg");
|
||||
string userPath = string(path, ".bsnes/bsnes-qt.cfg");
|
||||
|
||||
configuration config;
|
||||
string profile;
|
||||
|
@@ -102,7 +102,7 @@ namespace nall {
|
||||
|
||||
virtual bool save(const char *filename) const {
|
||||
file fp;
|
||||
if(fp.open(filename, file::mode_write)) {
|
||||
if(fp.open(filename, file::mode::write)) {
|
||||
for(unsigned i = 0; i < list.size(); i++) {
|
||||
string output;
|
||||
output << list[i].name << " = " << list[i].get();
|
||||
|
@@ -27,7 +27,7 @@ namespace nall {
|
||||
bool import(const char *filename) {
|
||||
string data;
|
||||
if(data.readfile(filename) == false) return false;
|
||||
data.ltrim_once("\xef\xbb\xbf"); //remove UTF-8 marker, if it exists
|
||||
data.ltrim<1>("\xef\xbb\xbf"); //remove UTF-8 marker, if it exists
|
||||
data.replace("\r", "");
|
||||
|
||||
lstring line;
|
||||
@@ -43,8 +43,8 @@ namespace nall {
|
||||
part[1].trim();
|
||||
|
||||
//remove quotes
|
||||
part[0].trim_once("\"");
|
||||
part[1].trim_once("\"");
|
||||
part[0].trim<1>("\"");
|
||||
part[1].trim<1>("\"");
|
||||
|
||||
unsigned n = index_input.size();
|
||||
index_input[n] = part[0];
|
||||
|
@@ -16,13 +16,13 @@
|
||||
namespace nall {
|
||||
|
||||
struct directory {
|
||||
static lstring folders(const char *pathname);
|
||||
static lstring files(const char *pathname);
|
||||
static lstring contents(const char *pathname);
|
||||
static lstring folders(const string &pathname, const string &pattern = "*");
|
||||
static lstring files(const string &pathname, const string &pattern = "*");
|
||||
static lstring contents(const string &pathname, const string &pattern = "*");
|
||||
};
|
||||
|
||||
#if defined(_WIN32)
|
||||
inline lstring directory::folders(const char *pathname) {
|
||||
inline lstring directory::folders(const string &pathname, const string &pattern) {
|
||||
lstring list;
|
||||
string path = pathname;
|
||||
path.transform("/", "\\");
|
||||
@@ -34,23 +34,25 @@ struct directory {
|
||||
if(handle != INVALID_HANDLE_VALUE) {
|
||||
if(wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..")) {
|
||||
if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
list.append(string(utf8_t(data.cFileName), "/"));
|
||||
string name = utf8_t(data.cFileName);
|
||||
if(wildcard(name, pattern)) list.append(string(name, "/"));
|
||||
}
|
||||
}
|
||||
while(FindNextFile(handle, &data) != false) {
|
||||
if(wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..")) {
|
||||
if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
list.append(string(utf8_t(data.cFileName), "/"));
|
||||
string name = utf8_t(data.cFileName);
|
||||
if(wildcard(name, pattern)) list.append(string(name, "/"));
|
||||
}
|
||||
}
|
||||
}
|
||||
FindClose(handle);
|
||||
}
|
||||
sort(&list[0], list.size());
|
||||
if(list.size() > 0) sort(&list[0], list.size());
|
||||
return list;
|
||||
}
|
||||
|
||||
inline lstring directory::files(const char *pathname) {
|
||||
inline lstring directory::files(const string &pathname, const string &pattern) {
|
||||
lstring list;
|
||||
string path = pathname;
|
||||
path.transform("/", "\\");
|
||||
@@ -61,27 +63,29 @@ struct directory {
|
||||
handle = FindFirstFile(utf16_t(path), &data);
|
||||
if(handle != INVALID_HANDLE_VALUE) {
|
||||
if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
|
||||
list.append(utf8_t(data.cFileName));
|
||||
string name = utf8_t(data.cFileName);
|
||||
if(wildcard(name, pattern)) list.append(name);
|
||||
}
|
||||
while(FindNextFile(handle, &data) != false) {
|
||||
if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
|
||||
list.append(utf8_t(data.cFileName));
|
||||
string name = utf8_t(data.cFileName);
|
||||
if(wildcard(name, pattern)) list.append(name);
|
||||
}
|
||||
}
|
||||
FindClose(handle);
|
||||
}
|
||||
sort(&list[0], list.size());
|
||||
if(list.size() > 0) sort(&list[0], list.size());
|
||||
return list;
|
||||
}
|
||||
|
||||
inline lstring directory::contents(const char *pathname) {
|
||||
lstring folders = directory::folders(pathname);
|
||||
lstring files = directory::files(pathname);
|
||||
inline lstring directory::contents(const string &pathname, const string &pattern) {
|
||||
lstring folders = directory::folders(pathname); //pattern search of contents() should only filter files
|
||||
lstring files = directory::files(pathname, pattern);
|
||||
foreach(file, files) folders.append(file);
|
||||
return folders;
|
||||
}
|
||||
#else
|
||||
inline lstring directory::folders(const char *pathname) {
|
||||
inline lstring directory::folders(const string &pathname, const string &pattern) {
|
||||
lstring list;
|
||||
DIR *dp;
|
||||
struct dirent *ep;
|
||||
@@ -90,16 +94,18 @@ struct directory {
|
||||
while(ep = readdir(dp)) {
|
||||
if(!strcmp(ep->d_name, ".")) continue;
|
||||
if(!strcmp(ep->d_name, "..")) continue;
|
||||
if(ep->d_type & DT_DIR) list.append(string(ep->d_name, "/"));
|
||||
if(ep->d_type & DT_DIR) {
|
||||
if(wildcard(ep->d_name, pattern)) list.append(string(ep->d_name, "/"));
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
}
|
||||
sort(&list[0], list.size());
|
||||
if(list.size() > 0) sort(&list[0], list.size());
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
inline lstring directory::files(const char *pathname) {
|
||||
inline lstring directory::files(const string &pathname, const string &pattern) {
|
||||
lstring list;
|
||||
DIR *dp;
|
||||
struct dirent *ep;
|
||||
@@ -108,17 +114,19 @@ struct directory {
|
||||
while(ep = readdir(dp)) {
|
||||
if(!strcmp(ep->d_name, ".")) continue;
|
||||
if(!strcmp(ep->d_name, "..")) continue;
|
||||
if((ep->d_type & DT_DIR) == 0) list.append(ep->d_name);
|
||||
if((ep->d_type & DT_DIR) == 0) {
|
||||
if(wildcard(ep->d_name, pattern)) list.append(ep->d_name);
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
}
|
||||
sort(&list[0], list.size());
|
||||
if(list.size() > 0) sort(&list[0], list.size());
|
||||
return list;
|
||||
}
|
||||
|
||||
inline lstring directory::contents(const char *pathname) {
|
||||
lstring folders = directory::folders(pathname);
|
||||
lstring files = directory::files(pathname);
|
||||
inline lstring directory::contents(const string &pathname, const string &pattern) {
|
||||
lstring folders = directory::folders(pathname); //pattern search of contents() should only filter files
|
||||
lstring files = directory::files(pathname, pattern);
|
||||
foreach(file, files) folders.append(file);
|
||||
return folders;
|
||||
}
|
||||
|
@@ -26,12 +26,12 @@ namespace nall {
|
||||
|
||||
class file {
|
||||
public:
|
||||
enum FileMode { mode_read, mode_write, mode_readwrite, mode_writeread };
|
||||
enum SeekMode { seek_absolute, seek_relative };
|
||||
enum class mode : unsigned { read, write, readwrite, writeread };
|
||||
enum class index : unsigned { absolute, relative };
|
||||
|
||||
uint8_t read() {
|
||||
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
|
||||
if(file_offset >= file_size) return 0xff; //cannot read past end of file
|
||||
buffer_sync();
|
||||
return buffer[(file_offset++) & buffer_mask];
|
||||
@@ -60,7 +60,7 @@ namespace nall {
|
||||
|
||||
void write(uint8_t data) {
|
||||
if(!fp) return; //file not open
|
||||
if(file_mode == mode_read) return; //writes not permitted
|
||||
if(file_mode == mode::read) return; //writes not permitted
|
||||
buffer_sync();
|
||||
buffer[(file_offset++) & buffer_mask] = data;
|
||||
buffer_dirty = true;
|
||||
@@ -95,19 +95,19 @@ namespace nall {
|
||||
fflush(fp);
|
||||
}
|
||||
|
||||
void seek(int offset, SeekMode mode = seek_absolute) {
|
||||
void seek(int offset, index index_ = index::absolute) {
|
||||
if(!fp) return; //file not open
|
||||
buffer_flush();
|
||||
|
||||
uintmax_t req_offset = file_offset;
|
||||
switch(mode) {
|
||||
case seek_absolute: req_offset = offset; break;
|
||||
case seek_relative: req_offset += offset; break;
|
||||
switch(index_) {
|
||||
case index::absolute: req_offset = offset; break;
|
||||
case index::relative: req_offset += offset; break;
|
||||
}
|
||||
|
||||
if(req_offset < 0) req_offset = 0; //cannot seek before start of file
|
||||
if(req_offset > file_size) {
|
||||
if(file_mode == mode_read) { //cannot seek past end of file
|
||||
if(file_mode == mode::read) { //cannot seek past end of file
|
||||
req_offset = file_size;
|
||||
} else { //pad file to requested location
|
||||
file_offset = file_size;
|
||||
@@ -174,20 +174,20 @@ namespace nall {
|
||||
return fp;
|
||||
}
|
||||
|
||||
bool open(const char *fn, FileMode mode) {
|
||||
bool open(const char *fn, mode mode_) {
|
||||
if(fp) return false;
|
||||
|
||||
switch(file_mode = mode) {
|
||||
switch(file_mode = mode_) {
|
||||
#if !defined(_WIN32)
|
||||
case mode_read: fp = fopen(fn, "rb"); break;
|
||||
case mode_write: fp = fopen(fn, "wb+"); break; //need read permission for buffering
|
||||
case mode_readwrite: fp = fopen(fn, "rb+"); break;
|
||||
case mode_writeread: fp = fopen(fn, "wb+"); break;
|
||||
case mode::read: fp = fopen(fn, "rb"); break;
|
||||
case mode::write: fp = fopen(fn, "wb+"); break; //need read permission for buffering
|
||||
case mode::readwrite: fp = fopen(fn, "rb+"); break;
|
||||
case mode::writeread: fp = fopen(fn, "wb+"); break;
|
||||
#else
|
||||
case mode_read: fp = _wfopen(utf16_t(fn), L"rb"); break;
|
||||
case mode_write: fp = _wfopen(utf16_t(fn), L"wb+"); break;
|
||||
case mode_readwrite: fp = _wfopen(utf16_t(fn), L"rb+"); break;
|
||||
case mode_writeread: fp = _wfopen(utf16_t(fn), L"wb+"); break;
|
||||
case mode::read: fp = _wfopen(utf16_t(fn), L"rb"); break;
|
||||
case mode::write: fp = _wfopen(utf16_t(fn), L"wb+"); break;
|
||||
case mode::readwrite: fp = _wfopen(utf16_t(fn), L"rb+"); break;
|
||||
case mode::writeread: fp = _wfopen(utf16_t(fn), L"wb+"); break;
|
||||
#endif
|
||||
}
|
||||
if(!fp) return false;
|
||||
@@ -213,7 +213,7 @@ namespace nall {
|
||||
fp = 0;
|
||||
file_offset = 0;
|
||||
file_size = 0;
|
||||
file_mode = mode_read;
|
||||
file_mode = mode::read;
|
||||
}
|
||||
|
||||
~file() {
|
||||
@@ -231,7 +231,7 @@ namespace nall {
|
||||
FILE *fp;
|
||||
unsigned file_offset;
|
||||
unsigned file_size;
|
||||
FileMode file_mode;
|
||||
mode file_mode;
|
||||
|
||||
void buffer_sync() {
|
||||
if(!fp) return; //file not open
|
||||
@@ -246,7 +246,7 @@ namespace nall {
|
||||
|
||||
void buffer_flush() {
|
||||
if(!fp) return; //file not open
|
||||
if(file_mode == mode_read) return; //buffer cannot be written to
|
||||
if(file_mode == mode::read) return; //buffer cannot be written to
|
||||
if(buffer_offset < 0) return; //buffer unused
|
||||
if(buffer_dirty == false) return; //buffer unmodified since read
|
||||
fseek(fp, buffer_offset, SEEK_SET);
|
||||
|
@@ -19,14 +19,16 @@
|
||||
namespace nall {
|
||||
class filemap {
|
||||
public:
|
||||
enum filemode { mode_read, mode_write, mode_readwrite, mode_writeread };
|
||||
enum class mode : unsigned { read, write, readwrite, writeread };
|
||||
|
||||
bool open(const char *filename, filemode mode) { return p_open(filename, mode); }
|
||||
bool opened() const { return p_opened(); }
|
||||
bool open(const char *filename, mode mode_) { return p_open(filename, mode_); }
|
||||
void close() { return p_close(); }
|
||||
unsigned size() const { return p_size; }
|
||||
uint8_t* handle() { return p_handle; }
|
||||
const uint8_t* handle() const { return p_handle; }
|
||||
uint8_t* data() { return p_handle; }
|
||||
const uint8_t* data() const { return p_handle; }
|
||||
filemap() : p_size(0), p_handle(0) { p_ctor(); }
|
||||
filemap(const char *filename, mode mode_) : p_size(0), p_handle(0) { p_ctor(); p_open(filename, mode_); }
|
||||
~filemap() { p_dtor(); }
|
||||
|
||||
private:
|
||||
@@ -40,31 +42,35 @@ namespace nall {
|
||||
|
||||
HANDLE p_filehandle, p_maphandle;
|
||||
|
||||
bool p_open(const char *filename, filemode mode) {
|
||||
bool p_opened() const {
|
||||
return p_handle;
|
||||
}
|
||||
|
||||
bool p_open(const char *filename, mode mode_) {
|
||||
int desired_access, creation_disposition, flprotect, map_access;
|
||||
|
||||
switch(mode) {
|
||||
switch(mode_) {
|
||||
default: return false;
|
||||
case mode_read:
|
||||
case mode::read:
|
||||
desired_access = GENERIC_READ;
|
||||
creation_disposition = OPEN_EXISTING;
|
||||
flprotect = PAGE_READONLY;
|
||||
map_access = FILE_MAP_READ;
|
||||
break;
|
||||
case mode_write:
|
||||
case mode::write:
|
||||
//write access requires read access
|
||||
desired_access = GENERIC_WRITE;
|
||||
creation_disposition = CREATE_ALWAYS;
|
||||
flprotect = PAGE_READWRITE;
|
||||
map_access = FILE_MAP_ALL_ACCESS;
|
||||
break;
|
||||
case mode_readwrite:
|
||||
case mode::readwrite:
|
||||
desired_access = GENERIC_READ | GENERIC_WRITE;
|
||||
creation_disposition = OPEN_EXISTING;
|
||||
flprotect = PAGE_READWRITE;
|
||||
map_access = FILE_MAP_ALL_ACCESS;
|
||||
break;
|
||||
case mode_writeread:
|
||||
case mode::writeread:
|
||||
desired_access = GENERIC_READ | GENERIC_WRITE;
|
||||
creation_disposition = CREATE_NEW;
|
||||
flprotect = PAGE_READWRITE;
|
||||
@@ -122,30 +128,34 @@ namespace nall {
|
||||
|
||||
int p_fd;
|
||||
|
||||
bool p_open(const char *filename, filemode mode) {
|
||||
bool p_opened() const {
|
||||
return p_handle;
|
||||
}
|
||||
|
||||
bool p_open(const char *filename, mode mode_) {
|
||||
int open_flags, mmap_flags;
|
||||
|
||||
switch(mode) {
|
||||
switch(mode_) {
|
||||
default: return false;
|
||||
case mode_read:
|
||||
case mode::read:
|
||||
open_flags = O_RDONLY;
|
||||
mmap_flags = PROT_READ;
|
||||
break;
|
||||
case mode_write:
|
||||
case mode::write:
|
||||
open_flags = O_RDWR | O_CREAT; //mmap() requires read access
|
||||
mmap_flags = PROT_WRITE;
|
||||
break;
|
||||
case mode_readwrite:
|
||||
case mode::readwrite:
|
||||
open_flags = O_RDWR;
|
||||
mmap_flags = PROT_READ | PROT_WRITE;
|
||||
break;
|
||||
case mode_writeread:
|
||||
case mode::writeread:
|
||||
open_flags = O_RDWR | O_CREAT;
|
||||
mmap_flags = PROT_READ | PROT_WRITE;
|
||||
break;
|
||||
}
|
||||
|
||||
p_fd = ::open(filename, open_flags);
|
||||
p_fd = ::open(filename, open_flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||
if(p_fd < 0) return false;
|
||||
|
||||
struct stat p_stat;
|
||||
|
@@ -1,90 +1,59 @@
|
||||
#ifndef NALL_FUNCTION_HPP
|
||||
#define NALL_FUNCTION_HPP
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> class function;
|
||||
|
||||
template<typename R, typename... P>
|
||||
class function<R (P...)> {
|
||||
private:
|
||||
struct base1 { virtual void func1(P...) {} };
|
||||
struct base2 { virtual void func2(P...) {} };
|
||||
struct derived : base1, virtual base2 {};
|
||||
template<typename R, typename... P> class function<R (P...)> {
|
||||
struct container {
|
||||
virtual R operator()(P... p) const = 0;
|
||||
virtual container* copy() const = 0;
|
||||
virtual ~container() {}
|
||||
} *callback;
|
||||
|
||||
struct data_t {
|
||||
R (*callback)(const data_t&, P...);
|
||||
union {
|
||||
R (*callback_global)(P...);
|
||||
struct {
|
||||
R (derived::*callback_member)(P...);
|
||||
void *object;
|
||||
struct global : container {
|
||||
R (*function)(P...);
|
||||
R operator()(P... p) const { return function(std::forward<P>(p)...); }
|
||||
container* copy() const { return new global(function); }
|
||||
global(R (*function)(P...)) : function(function) {}
|
||||
};
|
||||
|
||||
template<typename C> struct member : container {
|
||||
R (C::*function)(P...);
|
||||
C *object;
|
||||
R operator()(P... p) const { return (object->*function)(std::forward<P>(p)...); }
|
||||
container* copy() const { return new member(function, object); }
|
||||
member(R (C::*function)(P...), C *object) : function(function), object(object) {}
|
||||
};
|
||||
} data;
|
||||
|
||||
static R callback_global(const data_t &data, P... p) {
|
||||
return data.callback_global(p...);
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
static R callback_member(const data_t &data, P... p) {
|
||||
return (((C*)data.object)->*((R (C::*&)(P...))data.callback_member))(p...);
|
||||
}
|
||||
template<typename L> struct lambda : container {
|
||||
L object;
|
||||
R operator()(P... p) const { return object(std::forward<P>(p)...); }
|
||||
container* copy() const { return new lambda(object); }
|
||||
lambda(const L& object) : object(object) {}
|
||||
};
|
||||
|
||||
public:
|
||||
R operator()(P... p) const { return data.callback(data, p...); }
|
||||
operator bool() const { return data.callback; }
|
||||
void reset() { data.callback = 0; }
|
||||
operator bool() const { return callback; }
|
||||
R operator()(P... p) const { return (*callback)(std::forward<P>(p)...); }
|
||||
void reset() { if(callback) { delete callback; callback = 0; } }
|
||||
|
||||
function& operator=(const function &source) {
|
||||
if(this != &source) {
|
||||
if(callback) { delete callback; callback = 0; }
|
||||
if(source.callback) callback = source.callback->copy();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
function& operator=(const function &source) { memcpy(&data, &source.data, sizeof(data_t)); return *this; }
|
||||
function(const function &source) { operator=(source); }
|
||||
|
||||
//no pointer
|
||||
function() {
|
||||
data.callback = 0;
|
||||
}
|
||||
|
||||
//symbolic link pointer (nall/dl.hpp::sym, etc)
|
||||
function(void *callback) {
|
||||
data.callback = callback ? &callback_global : 0;
|
||||
data.callback_global = (R (*)(P...))callback;
|
||||
}
|
||||
|
||||
//global function pointer
|
||||
function(R (*callback)(P...)) {
|
||||
data.callback = &callback_global;
|
||||
data.callback_global = callback;
|
||||
}
|
||||
|
||||
//member function pointer
|
||||
template<typename C>
|
||||
function(R (C::*callback)(P...), C *object) {
|
||||
static_assert(sizeof data.callback_member >= sizeof callback, "callback_member is too small");
|
||||
data.callback = &callback_member<C>;
|
||||
(R (C::*&)(P...))data.callback_member = callback;
|
||||
data.object = object;
|
||||
}
|
||||
|
||||
//const member function pointer
|
||||
template<typename C>
|
||||
function(R (C::*callback)(P...) const, C *object) {
|
||||
static_assert(sizeof data.callback_member >= sizeof callback, "callback_member is too small");
|
||||
data.callback = &callback_member<C>;
|
||||
(R (C::*&)(P...))data.callback_member = (R (C::*&)(P...))callback;
|
||||
data.object = object;
|
||||
}
|
||||
|
||||
//lambda function pointer
|
||||
template<typename T>
|
||||
function(T callback) {
|
||||
static_assert(std::is_same<R, typename std::result_of<T(P...)>::type>::value, "lambda mismatch");
|
||||
data.callback = &callback_global;
|
||||
data.callback_global = (R (*)(P...))callback;
|
||||
}
|
||||
function() : callback(0) {}
|
||||
function(void *function) : callback(0) { if(function) callback = new global((R (*)(P...))function); }
|
||||
function(R (*function)(P...)) { callback = new global(function); }
|
||||
template<typename C> function(R (C::*function)(P...), C *object) { callback = new member<C>(function, object); }
|
||||
template<typename C> function(R (C::*function)(P...) const, C *object) { callback = new member<C>((R (C::*)(P...))function, object); }
|
||||
template<typename L> function(const L& object) { callback = new lambda<L>(object); }
|
||||
~function() { if(callback) delete callback; }
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -112,6 +112,7 @@ namespace nall {
|
||||
imode = Size;
|
||||
idata = 0;
|
||||
isize = 0;
|
||||
icapacity = 0;
|
||||
}
|
||||
|
||||
serializer(unsigned capacity) {
|
||||
|
@@ -9,7 +9,7 @@ public:
|
||||
|
||||
inline snes_information(const uint8_t *data, unsigned size);
|
||||
|
||||
private:
|
||||
//private:
|
||||
inline void read_header(const uint8_t *data, unsigned size);
|
||||
inline unsigned find_header(const uint8_t *data, unsigned size);
|
||||
inline unsigned score_header(const uint8_t *data, unsigned size, unsigned addr);
|
||||
|
@@ -2,6 +2,7 @@
|
||||
#define NALL_STRING_HPP
|
||||
|
||||
#include <initializer_list>
|
||||
#include <nall/platform.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
#include <nall/string/base.hpp>
|
||||
@@ -13,6 +14,7 @@
|
||||
#include <nall/string/filename.hpp>
|
||||
#include <nall/string/match.hpp>
|
||||
#include <nall/string/math.hpp>
|
||||
#include <nall/string/platform.hpp>
|
||||
#include <nall/string/strl.hpp>
|
||||
#include <nall/string/strpos.hpp>
|
||||
#include <nall/string/trim.hpp>
|
||||
@@ -20,6 +22,7 @@
|
||||
#include <nall/string/split.hpp>
|
||||
#include <nall/string/utility.hpp>
|
||||
#include <nall/string/variadic.hpp>
|
||||
#include <nall/string/wrapper.hpp>
|
||||
#include <nall/string/xml.hpp>
|
||||
|
||||
namespace nall {
|
||||
|
@@ -17,7 +17,6 @@ namespace nall {
|
||||
class string {
|
||||
public:
|
||||
inline void reserve(unsigned);
|
||||
inline unsigned length() const;
|
||||
|
||||
inline string& assign(const char*);
|
||||
inline string& append(const char*);
|
||||
@@ -26,6 +25,35 @@ namespace nall {
|
||||
inline string& append(unsigned int value);
|
||||
inline string& append(double value);
|
||||
|
||||
inline bool readfile(const char*);
|
||||
|
||||
inline string& replace (const char*, const char*);
|
||||
inline string& qreplace(const char*, const char*);
|
||||
|
||||
inline unsigned length() const;
|
||||
|
||||
inline bool equals(const char*) const;
|
||||
inline bool iequals(const char*) const;
|
||||
|
||||
inline bool wildcard(const char*) const;
|
||||
inline bool iwildcard(const char*) const;
|
||||
|
||||
inline bool beginswith(const char*) const;
|
||||
inline bool ibeginswith(const char*) const;
|
||||
inline bool endswith(const char*) const;
|
||||
inline bool iendswith(const char*) const;
|
||||
|
||||
inline string& lower();
|
||||
inline string& upper();
|
||||
inline string& transform(const char *before, const char *after);
|
||||
|
||||
template<unsigned limit = 0> inline string& ltrim(const char *key = " ");
|
||||
template<unsigned limit = 0> inline string& rtrim(const char *key = " ");
|
||||
template<unsigned limit = 0> inline string& trim (const char *key = " ");
|
||||
|
||||
inline optional<unsigned> position(const char *key) const;
|
||||
inline optional<unsigned> qposition(const char *key) const;
|
||||
|
||||
template<typename T> inline string& operator= (T value);
|
||||
template<typename T> inline string& operator<<(T value);
|
||||
|
||||
@@ -48,20 +76,6 @@ namespace nall {
|
||||
inline string(string&&);
|
||||
inline ~string();
|
||||
|
||||
inline bool readfile(const char*);
|
||||
inline string& replace (const char*, const char*);
|
||||
inline string& qreplace(const char*, const char*);
|
||||
|
||||
inline string& lower();
|
||||
inline string& upper();
|
||||
inline string& transform(const char *before, const char *after);
|
||||
inline string& ltrim(const char *key = " ");
|
||||
inline string& rtrim(const char *key = " ");
|
||||
inline string& trim (const char *key = " ");
|
||||
inline string& ltrim_once(const char *key = " ");
|
||||
inline string& rtrim_once(const char *key = " ");
|
||||
inline string& trim_once (const char *key = " ");
|
||||
|
||||
protected:
|
||||
char *data;
|
||||
unsigned size;
|
||||
@@ -76,9 +90,9 @@ namespace nall {
|
||||
public:
|
||||
template<typename T> inline lstring& operator<<(T value);
|
||||
|
||||
inline optional<unsigned> find(const char*);
|
||||
inline void split (const char*, const char*, unsigned = 0);
|
||||
inline void qsplit(const char*, const char*, unsigned = 0);
|
||||
inline optional<unsigned> find(const char*) const;
|
||||
template<unsigned limit = 0> inline void split (const char*, const char*);
|
||||
template<unsigned limit = 0> inline void qsplit(const char*, const char*);
|
||||
|
||||
lstring();
|
||||
lstring(std::initializer_list<string>);
|
||||
@@ -87,7 +101,9 @@ namespace nall {
|
||||
//compare.hpp
|
||||
inline char chrlower(char c);
|
||||
inline char chrupper(char c);
|
||||
inline int stricmp(const char *dest, const char *src);
|
||||
inline int stricmp(const char *str1, const char *str2);
|
||||
inline bool wildcard(const char *str, const char *pattern);
|
||||
inline bool iwildcard(const char *str, const char *pattern);
|
||||
inline bool strbegin (const char *str, const char *key);
|
||||
inline bool stribegin(const char *str, const char *key);
|
||||
inline bool strend (const char *str, const char *key);
|
||||
@@ -110,23 +126,28 @@ namespace nall {
|
||||
inline bool strint (const char *str, int &result);
|
||||
inline bool strmath(const char *str, int &result);
|
||||
|
||||
//platform.hpp
|
||||
inline string realpath(const char *name);
|
||||
inline string userpath();
|
||||
inline string currentpath();
|
||||
|
||||
//strl.hpp
|
||||
inline unsigned strlcpy(char *dest, const char *src, unsigned length);
|
||||
inline unsigned strlcat(char *dest, const char *src, unsigned length);
|
||||
|
||||
//strpos.hpp
|
||||
inline optional<unsigned> strpos(const char *str, const char *key);
|
||||
inline optional<unsigned> qstrpos(const char *str, const char *key);
|
||||
|
||||
//trim.hpp
|
||||
inline char* ltrim(char *str, const char *key = " ");
|
||||
inline char* rtrim(char *str, const char *key = " ");
|
||||
inline char* trim (char *str, const char *key = " ");
|
||||
inline char* ltrim_once(char *str, const char *key = " ");
|
||||
inline char* rtrim_once(char *str, const char *key = " ");
|
||||
inline char* trim_once (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* trim (char *str, const char *key = " ");
|
||||
|
||||
//utility.hpp
|
||||
inline unsigned strlcpy(string &dest, const char *src, unsigned length);
|
||||
inline unsigned strlcat(string &dest, const char *src, unsigned length);
|
||||
inline string substr(const char *src, unsigned start = 0, unsigned length = 0);
|
||||
inline string& strtr(string &dest, const char *before, const char *after);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strhex(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strsigned(intmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strunsigned(uintmax_t value);
|
||||
|
@@ -11,14 +11,52 @@ char chrupper(char c) {
|
||||
return (c >= 'a' && c <= 'z') ? c - ('a' - 'A') : c;
|
||||
}
|
||||
|
||||
int stricmp(const char *dest, const char *src) {
|
||||
while(*dest) {
|
||||
if(chrlower(*dest) != chrlower(*src)) break;
|
||||
dest++;
|
||||
src++;
|
||||
int stricmp(const char *str1, const char *str2) {
|
||||
while(*str1) {
|
||||
if(chrlower(*str1) != chrlower(*str2)) break;
|
||||
str1++, str2++;
|
||||
}
|
||||
return (int)chrlower(*str1) - (int)chrlower(*str2);
|
||||
}
|
||||
|
||||
return (int)chrlower(*dest) - (int)chrlower(*src);
|
||||
bool wildcard(const char *s, const char *p) {
|
||||
const char *cp = 0, *mp = 0;
|
||||
while(*s && *p != '*') {
|
||||
if(*p != '?' && *s != *p) return false;
|
||||
p++, s++;
|
||||
}
|
||||
while(*s) {
|
||||
if(*p == '*') {
|
||||
if(!*++p) return true;
|
||||
mp = p, cp = s + 1;
|
||||
} else if(*p == '?' || *p == *s) {
|
||||
p++, s++;
|
||||
} else {
|
||||
p = mp, s = cp++;
|
||||
}
|
||||
}
|
||||
while(*p == '*') p++;
|
||||
return !*p;
|
||||
}
|
||||
|
||||
bool iwildcard(const char *s, const char *p) {
|
||||
const char *cp = 0, *mp = 0;
|
||||
while(*s && *p != '*') {
|
||||
if(*p != '?' && chrlower(*s) != chrlower(*p)) return false;
|
||||
p++, s++;
|
||||
}
|
||||
while(*s) {
|
||||
if(*p == '*') {
|
||||
if(!*++p) return true;
|
||||
mp = p, cp = s + 1;
|
||||
} else if(*p == '?' || chrlower(*p) == chrlower(*s)) {
|
||||
p++, s++;
|
||||
} else {
|
||||
p = mp, s = cp++;
|
||||
}
|
||||
}
|
||||
while(*p == '*') p++;
|
||||
return !*p;
|
||||
}
|
||||
|
||||
bool strbegin(const char *str, const char *key) {
|
||||
|
@@ -40,10 +40,6 @@ char* strtr(char *dest, const char *before, const char *after) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
string& string::lower() { nall::strlower(data); return *this; }
|
||||
string& string::upper() { nall::strupper(data); return *this; }
|
||||
string& string::transform(const char *before, const char *after) { nall::strtr(data, before, after); return *this; }
|
||||
|
||||
uintmax_t strhex(const char *str) {
|
||||
if(!str) return 0;
|
||||
uintmax_t result = 0;
|
||||
|
@@ -11,10 +11,6 @@ void string::reserve(unsigned size_) {
|
||||
}
|
||||
}
|
||||
|
||||
unsigned string::length() const {
|
||||
return strlen(data);
|
||||
}
|
||||
|
||||
string& string::assign(const char *s) {
|
||||
unsigned length = strlen(s);
|
||||
reserve(length);
|
||||
@@ -122,7 +118,7 @@ bool string::readfile(const char *filename) {
|
||||
return true;
|
||||
}
|
||||
|
||||
optional<unsigned> lstring::find(const char *key) {
|
||||
optional<unsigned> lstring::find(const char *key) const {
|
||||
for(unsigned i = 0; i < size(); i++) {
|
||||
if(operator[](i) == key) return { true, i };
|
||||
}
|
||||
|
@@ -3,7 +3,9 @@
|
||||
|
||||
namespace nall {
|
||||
|
||||
// "foo/bar.c" -> "foo/", "bar.c" -> "./"
|
||||
// "foo/bar.c" -> "foo/"
|
||||
// "foo/" -> "foo/"
|
||||
// "bar.c" -> "./"
|
||||
inline string dir(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
|
41
bsnes/nall/string/platform.hpp
Executable file
41
bsnes/nall/string/platform.hpp
Executable file
@@ -0,0 +1,41 @@
|
||||
#ifndef NALL_STRING_PLATFORM_HPP
|
||||
#define NALL_STRING_PLATFORM_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
string realpath(const char *name) {
|
||||
char path[PATH_MAX];
|
||||
if(::realpath(name, path)) {
|
||||
string result(path);
|
||||
result.transform("\\", "/");
|
||||
if(result.endswith("/") == false) result.append("/");
|
||||
return result;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
string userpath() {
|
||||
char path[PATH_MAX];
|
||||
if(::userpath(path)) {
|
||||
string result(path);
|
||||
result.transform("\\", "/");
|
||||
if(result.endswith("/") == false) result.append("/");
|
||||
return result;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
string currentpath() {
|
||||
char path[PATH_MAX];
|
||||
if(::getcwd(path)) {
|
||||
string result(path);
|
||||
result.transform("\\", "/");
|
||||
if(result.endswith("/") == false) result.append("/");
|
||||
return result;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@@ -3,7 +3,8 @@
|
||||
|
||||
namespace nall {
|
||||
|
||||
void lstring::split(const char *key, const char *src, unsigned limit) {
|
||||
template<unsigned Limit> void lstring::split(const char *key, const char *src) {
|
||||
unsigned limit = Limit;
|
||||
reset();
|
||||
|
||||
int ssl = strlen(src), ksl = strlen(key);
|
||||
@@ -21,7 +22,8 @@ void lstring::split(const char *key, const char *src, unsigned limit) {
|
||||
operator[](split_count++) = src + lp;
|
||||
}
|
||||
|
||||
void lstring::qsplit(const char *key, const char *src, unsigned limit) {
|
||||
template<unsigned Limit> void lstring::qsplit(const char *key, const char *src) {
|
||||
unsigned limit = Limit;
|
||||
reset();
|
||||
|
||||
int ssl = strlen(src), ksl = strlen(key);
|
||||
|
@@ -7,7 +7,7 @@
|
||||
|
||||
namespace nall {
|
||||
|
||||
inline optional<unsigned> strpos(const char *str, const char *key) {
|
||||
optional<unsigned> strpos(const char *str, const char *key) {
|
||||
unsigned ssl = strlen(str), ksl = strlen(key);
|
||||
if(ksl > ssl) return { false, 0 };
|
||||
|
||||
@@ -18,7 +18,7 @@ inline optional<unsigned> strpos(const char *str, const char *key) {
|
||||
return { false, 0 };
|
||||
}
|
||||
|
||||
inline optional<unsigned> qstrpos(const char *str, const char *key) {
|
||||
optional<unsigned> qstrpos(const char *str, const char *key) {
|
||||
unsigned ssl = strlen(str), ksl = strlen(key);
|
||||
if(ksl > ssl) return { false, 0 };
|
||||
|
||||
|
@@ -3,7 +3,9 @@
|
||||
|
||||
namespace nall {
|
||||
|
||||
char* ltrim(char *str, const char *key) {
|
||||
//limit defaults to zero, which will underflow on first compare; equivalent to no limit
|
||||
template<unsigned Limit> char* ltrim(char *str, const char *key) {
|
||||
unsigned limit = Limit;
|
||||
if(!key || !*key) return str;
|
||||
while(strbegin(str, key)) {
|
||||
char *dest = str, *src = str + strlen(key);
|
||||
@@ -12,50 +14,25 @@ char* ltrim(char *str, const char *key) {
|
||||
if(!*dest) break;
|
||||
dest++;
|
||||
}
|
||||
if(--limit == 0) break;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
char* rtrim(char *str, const char *key) {
|
||||
template<unsigned Limit> char* rtrim(char *str, const char *key) {
|
||||
unsigned limit = Limit;
|
||||
if(!key || !*key) return str;
|
||||
while(strend(str, key)) str[strlen(str) - strlen(key)] = 0;
|
||||
return str;
|
||||
}
|
||||
|
||||
char* trim(char *str, const char *key) {
|
||||
return ltrim(rtrim(str, key), key);
|
||||
}
|
||||
|
||||
char* ltrim_once(char *str, const char *key) {
|
||||
if(!key || !*key) return str;
|
||||
if(strbegin(str, key)) {
|
||||
char *dest = str, *src = str + strlen(key);
|
||||
while(true) {
|
||||
*dest = *src++;
|
||||
if(!*dest) break;
|
||||
dest++;
|
||||
}
|
||||
while(strend(str, key)) {
|
||||
str[strlen(str) - strlen(key)] = 0;
|
||||
if(--limit == 0) break;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
char* rtrim_once(char *str, const char *key) {
|
||||
if(!key || !*key) return str;
|
||||
if(strend(str, key)) str[strlen(str) - strlen(key)] = 0;
|
||||
return str;
|
||||
template<unsigned limit> char* trim(char *str, const char *key) {
|
||||
return ltrim<limit>(rtrim<limit>(str, key), key);
|
||||
}
|
||||
|
||||
char* trim_once(char *str, const char *key) {
|
||||
return ltrim_once(rtrim_once(str, key), key);
|
||||
}
|
||||
|
||||
string& string::ltrim(const char *key) { nall::ltrim(data, key); return *this; }
|
||||
string& string::rtrim(const char *key) { nall::rtrim(data, key); return *this; }
|
||||
string& string::trim (const char *key) { nall::trim (data, key); return *this; }
|
||||
string& string::ltrim_once(const char *key) { nall::ltrim_once(data, key); return *this; }
|
||||
string& string::rtrim_once(const char *key) { nall::rtrim_once(data, key); return *this; }
|
||||
string& string::trim_once (const char *key) { nall::trim_once (data, key); return *this; }
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
33
bsnes/nall/string/wrapper.hpp
Executable file
33
bsnes/nall/string/wrapper.hpp
Executable file
@@ -0,0 +1,33 @@
|
||||
#ifndef NALL_STRING_WRAPPER_HPP
|
||||
#define NALL_STRING_WRAPPER_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
unsigned string::length() const { return strlen(data); }
|
||||
|
||||
bool string::equals(const char *str) const { return !strcmp(data, str); }
|
||||
bool string::iequals(const char *str) const { return !stricmp(data, str); }
|
||||
|
||||
bool string::wildcard(const char *str) const { return nall::wildcard(data, str); }
|
||||
bool string::iwildcard(const char *str) const { return nall::iwildcard(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::endswith(const char *str) const { return strend(data, str); }
|
||||
bool string::iendswith(const char *str) const { return striend(data, str); }
|
||||
|
||||
string& string::lower() { nall::strlower(data); return *this; }
|
||||
string& string::upper() { nall::strupper(data); return *this; }
|
||||
string& string::transform(const char *before, const char *after) { nall::strtr(data, before, after); 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::trim (const char *key) { nall::trim <limit>(data, key); return *this; }
|
||||
|
||||
optional<unsigned> string::position(const char *key) const { return strpos(data, key); }
|
||||
optional<unsigned> string::qposition(const char *key) const { return qstrpos(data, key); }
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@@ -75,11 +75,12 @@ inline string xml_element::parse() const {
|
||||
|
||||
if(strbegin(source, "<![CDATA[")) {
|
||||
if(auto pos = strpos(source, "]]>")) {
|
||||
if(pos() - 9 > 0) {
|
||||
string cdata = substr(source, 9, pos() - 9);
|
||||
data << cdata;
|
||||
offset += strlen(cdata);
|
||||
|
||||
source += offset + 3;
|
||||
}
|
||||
source += 9 + offset + 3;
|
||||
continue;
|
||||
} else {
|
||||
return "";
|
||||
@@ -138,8 +139,8 @@ inline bool xml_element::parse_head(string data) {
|
||||
xml_attribute attr;
|
||||
attr.name = side[0];
|
||||
attr.content = side[1];
|
||||
if(strbegin(attr.content, "\"") && strend(attr.content, "\"")) attr.content.trim_once("\"");
|
||||
else if(strbegin(attr.content, "'") && strend(attr.content, "'")) attr.content.trim_once("'");
|
||||
if(strbegin(attr.content, "\"") && strend(attr.content, "\"")) attr.content.trim<1>("\"");
|
||||
else if(strbegin(attr.content, "'") && strend(attr.content, "'")) attr.content.trim<1>("'");
|
||||
else throw "...";
|
||||
attribute.append(attr);
|
||||
}
|
||||
@@ -185,10 +186,10 @@ inline bool xml_element::parse_body(const char *&data) {
|
||||
|
||||
if(strend(tag, "?") == true) {
|
||||
self_terminating = true;
|
||||
tag.rtrim_once("?");
|
||||
tag.rtrim<1>("?");
|
||||
} else if(strend(tag, "/") == true) {
|
||||
self_terminating = true;
|
||||
tag.rtrim_once("/");
|
||||
tag.rtrim<1>("/");
|
||||
}
|
||||
|
||||
parse_head(tag);
|
||||
|
@@ -1,182 +1,212 @@
|
||||
#ifndef NALL_UPS_HPP
|
||||
#define NALL_UPS_HPP
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/crc32.hpp>
|
||||
#include <nall/file.hpp>
|
||||
#include <nall/function.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
|
||||
namespace nall {
|
||||
class ups {
|
||||
public:
|
||||
enum result {
|
||||
ok,
|
||||
patch_unreadable,
|
||||
|
||||
struct ups {
|
||||
enum class result : unsigned {
|
||||
unknown,
|
||||
success,
|
||||
patch_unwritable,
|
||||
patch_invalid,
|
||||
input_invalid,
|
||||
output_invalid,
|
||||
patch_crc32_invalid,
|
||||
input_crc32_invalid,
|
||||
output_crc32_invalid,
|
||||
source_invalid,
|
||||
target_invalid,
|
||||
target_too_small,
|
||||
patch_checksum_invalid,
|
||||
source_checksum_invalid,
|
||||
target_checksum_invalid,
|
||||
};
|
||||
|
||||
ups::result create(const char *patch_fn, const uint8_t *x_data, unsigned x_size, const uint8_t *y_data, unsigned y_size) {
|
||||
if(!fp.open(patch_fn, file::mode_write)) return patch_unwritable;
|
||||
function<void (unsigned offset, unsigned length)> progress;
|
||||
|
||||
crc32 = ~0;
|
||||
uint32_t x_crc32 = crc32_calculate(x_data, x_size);
|
||||
uint32_t y_crc32 = crc32_calculate(y_data, y_size);
|
||||
result create(
|
||||
const uint8_t *sourcedata, unsigned sourcelength,
|
||||
const uint8_t *targetdata, unsigned targetlength,
|
||||
const char *patchfilename
|
||||
) {
|
||||
source_data = (uint8_t*)sourcedata, target_data = (uint8_t*)targetdata;
|
||||
source_length = sourcelength, target_length = targetlength;
|
||||
source_offset = target_offset = 0;
|
||||
source_checksum = target_checksum = patch_checksum = ~0;
|
||||
|
||||
//header
|
||||
write('U');
|
||||
write('P');
|
||||
write('S');
|
||||
write('1');
|
||||
encptr(x_size);
|
||||
encptr(y_size);
|
||||
if(patch_file.open(patchfilename, file::mode::write) == false) return result::patch_unwritable;
|
||||
|
||||
//body
|
||||
unsigned max_size = max(x_size, y_size);
|
||||
patch_write('U');
|
||||
patch_write('P');
|
||||
patch_write('S');
|
||||
patch_write('1');
|
||||
encode(source_length);
|
||||
encode(target_length);
|
||||
|
||||
unsigned output_length = source_length > target_length ? source_length : target_length;
|
||||
unsigned relative = 0;
|
||||
for(unsigned i = 0; i < max_size;) {
|
||||
uint8_t x = i < x_size ? x_data[i] : 0x00;
|
||||
uint8_t y = i < y_size ? y_data[i] : 0x00;
|
||||
for(unsigned offset = 0; offset < output_length;) {
|
||||
uint8_t x = source_read();
|
||||
uint8_t y = target_read();
|
||||
|
||||
if(x == y) {
|
||||
i++;
|
||||
offset++;
|
||||
continue;
|
||||
}
|
||||
|
||||
encptr(i++ - relative);
|
||||
write(x ^ y);
|
||||
encode(offset++ - relative);
|
||||
patch_write(x ^ y);
|
||||
|
||||
while(true) {
|
||||
if(i >= max_size) {
|
||||
write(0x00);
|
||||
if(offset >= output_length) {
|
||||
patch_write(0x00);
|
||||
break;
|
||||
}
|
||||
|
||||
x = i < x_size ? x_data[i] : 0x00;
|
||||
y = i < y_size ? y_data[i] : 0x00;
|
||||
i++;
|
||||
write(x ^ y);
|
||||
x = source_read();
|
||||
y = target_read();
|
||||
offset++;
|
||||
patch_write(x ^ y);
|
||||
if(x == y) break;
|
||||
}
|
||||
|
||||
relative = i;
|
||||
relative = offset;
|
||||
}
|
||||
|
||||
//footer
|
||||
for(unsigned i = 0; i < 4; i++) write(x_crc32 >> (i << 3));
|
||||
for(unsigned i = 0; i < 4; i++) write(y_crc32 >> (i << 3));
|
||||
uint32_t p_crc32 = ~crc32;
|
||||
for(unsigned i = 0; i < 4; i++) write(p_crc32 >> (i << 3));
|
||||
source_checksum = ~source_checksum;
|
||||
target_checksum = ~target_checksum;
|
||||
for(unsigned i = 0; i < 4; i++) patch_write(source_checksum >> (i * 8));
|
||||
for(unsigned i = 0; i < 4; i++) patch_write(target_checksum >> (i * 8));
|
||||
uint32_t patch_result_checksum = ~patch_checksum;
|
||||
for(unsigned i = 0; i < 4; i++) patch_write(patch_result_checksum >> (i * 8));
|
||||
|
||||
fp.close();
|
||||
return ok;
|
||||
patch_file.close();
|
||||
return result::success;
|
||||
}
|
||||
|
||||
ups::result apply(const uint8_t *p_data, unsigned p_size, const uint8_t *x_data, unsigned x_size, uint8_t *&y_data, unsigned &y_size) {
|
||||
if(p_size < 18) return patch_invalid;
|
||||
p_buffer = p_data;
|
||||
result apply(
|
||||
const uint8_t *patchdata, unsigned patchlength,
|
||||
const uint8_t *sourcedata, unsigned sourcelength,
|
||||
uint8_t *targetdata, unsigned &targetlength
|
||||
) {
|
||||
patch_data = (uint8_t*)patchdata, source_data = (uint8_t*)sourcedata, target_data = targetdata;
|
||||
patch_length = patchlength, source_length = sourcelength, target_length = targetlength;
|
||||
patch_offset = source_offset = target_offset = 0;
|
||||
patch_checksum = source_checksum = target_checksum = ~0;
|
||||
|
||||
crc32 = ~0;
|
||||
if(patch_length < 18) return result::patch_invalid;
|
||||
if(patch_read() != 'U') return result::patch_invalid;
|
||||
if(patch_read() != 'P') return result::patch_invalid;
|
||||
if(patch_read() != 'S') return result::patch_invalid;
|
||||
if(patch_read() != '1') return result::patch_invalid;
|
||||
|
||||
//header
|
||||
if(read() != 'U') return patch_invalid;
|
||||
if(read() != 'P') return patch_invalid;
|
||||
if(read() != 'S') return patch_invalid;
|
||||
if(read() != '1') return patch_invalid;
|
||||
unsigned source_read_length = decode();
|
||||
unsigned target_read_length = decode();
|
||||
|
||||
unsigned px_size = decptr();
|
||||
unsigned py_size = decptr();
|
||||
|
||||
//mirror
|
||||
if(x_size != px_size && x_size != py_size) return input_invalid;
|
||||
y_size = (x_size == px_size) ? py_size : px_size;
|
||||
y_data = new uint8_t[y_size]();
|
||||
|
||||
for(unsigned i = 0; i < x_size && i < y_size; i++) y_data[i] = x_data[i];
|
||||
for(unsigned i = x_size; i < y_size; i++) y_data[i] = 0x00;
|
||||
|
||||
//body
|
||||
unsigned relative = 0;
|
||||
while(p_buffer < p_data + p_size - 12) {
|
||||
relative += decptr();
|
||||
if(source_length != source_read_length && source_length != target_read_length) return result::source_invalid;
|
||||
targetlength = (source_length == source_read_length ? target_read_length : source_read_length);
|
||||
if(target_length < targetlength) return result::target_too_small;
|
||||
target_length = targetlength;
|
||||
|
||||
while(patch_offset < patch_length - 12) {
|
||||
unsigned length = decode();
|
||||
while(length--) target_write(source_read());
|
||||
while(true) {
|
||||
uint8_t x = read();
|
||||
if(x && relative < y_size) {
|
||||
uint8_t y = relative < x_size ? x_data[relative] : 0x00;
|
||||
y_data[relative] = x ^ y;
|
||||
}
|
||||
relative++;
|
||||
if(!x) break;
|
||||
uint8_t patch_xor = patch_read();
|
||||
target_write(patch_xor ^ source_read());
|
||||
if(patch_xor == 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
//footer
|
||||
unsigned px_crc32 = 0, py_crc32 = 0, pp_crc32 = 0;
|
||||
for(unsigned i = 0; i < 4; i++) px_crc32 |= read() << (i << 3);
|
||||
for(unsigned i = 0; i < 4; i++) py_crc32 |= read() << (i << 3);
|
||||
uint32_t p_crc32 = ~crc32;
|
||||
for(unsigned i = 0; i < 4; i++) pp_crc32 |= read() << (i << 3);
|
||||
uint32_t patch_read_checksum = 0, source_read_checksum = 0, target_read_checksum = 0;
|
||||
for(unsigned i = 0; i < 4; i++) source_read_checksum |= patch_read() << (i * 8);
|
||||
for(unsigned i = 0; i < 4; i++) target_read_checksum |= patch_read() << (i * 8);
|
||||
uint32_t patch_result_checksum = ~patch_checksum;
|
||||
source_checksum = ~source_checksum;
|
||||
target_checksum = ~target_checksum;
|
||||
for(unsigned i = 0; i < 4; i++) patch_read_checksum |= patch_read() << (i * 8);
|
||||
|
||||
uint32_t x_crc32 = crc32_calculate(x_data, x_size);
|
||||
uint32_t y_crc32 = crc32_calculate(y_data, y_size);
|
||||
|
||||
if(px_size != py_size) {
|
||||
if(x_size == px_size && x_crc32 != px_crc32) return input_crc32_invalid;
|
||||
if(x_size == py_size && x_crc32 != py_crc32) return input_crc32_invalid;
|
||||
if(y_size == px_size && y_crc32 != px_crc32) return output_crc32_invalid;
|
||||
if(y_size == py_size && y_crc32 != py_crc32) return output_crc32_invalid;
|
||||
if(patch_result_checksum != patch_read_checksum) return result::patch_invalid;
|
||||
if(source_checksum == source_read_checksum && source_length == source_read_length) {
|
||||
if(target_checksum == target_read_checksum && target_length == target_read_length) return result::success;
|
||||
return result::target_invalid;
|
||||
} else if(source_checksum == target_read_checksum && source_length == target_read_length) {
|
||||
if(target_checksum == source_read_checksum && target_length == source_read_length) return result::success;
|
||||
return result::target_invalid;
|
||||
} else {
|
||||
if(x_crc32 != px_crc32 && x_crc32 != py_crc32) return input_crc32_invalid;
|
||||
if(y_crc32 != px_crc32 && y_crc32 != py_crc32) return output_crc32_invalid;
|
||||
if(x_crc32 == y_crc32 && px_crc32 != py_crc32) return output_crc32_invalid;
|
||||
if(x_crc32 != y_crc32 && px_crc32 == py_crc32) return output_crc32_invalid;
|
||||
return result::source_invalid;
|
||||
}
|
||||
|
||||
if(p_crc32 != pp_crc32) return patch_crc32_invalid;
|
||||
return ok;
|
||||
}
|
||||
|
||||
private:
|
||||
file fp;
|
||||
uint32_t crc32;
|
||||
const uint8_t *p_buffer;
|
||||
uint8_t *patch_data, *source_data, *target_data;
|
||||
unsigned patch_length, source_length, target_length;
|
||||
unsigned patch_offset, source_offset, target_offset;
|
||||
unsigned patch_checksum, source_checksum, target_checksum;
|
||||
file patch_file;
|
||||
|
||||
uint8_t read() {
|
||||
uint8_t n = *p_buffer++;
|
||||
crc32 = crc32_adjust(crc32, n);
|
||||
uint8_t patch_read() {
|
||||
if(patch_offset < patch_length) {
|
||||
uint8_t n = patch_data[patch_offset++];
|
||||
patch_checksum = crc32_adjust(patch_checksum, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
void write(uint8_t n) {
|
||||
fp.write(n);
|
||||
crc32 = crc32_adjust(crc32, n);
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void encptr(uint64_t offset) {
|
||||
uint8_t source_read() {
|
||||
if(source_offset < source_length) {
|
||||
uint8_t n = source_data[source_offset++];
|
||||
source_checksum = crc32_adjust(source_checksum, n);
|
||||
return n;
|
||||
}
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
uint8_t target_read() {
|
||||
uint8_t result = 0x00;
|
||||
if(target_offset < target_length) {
|
||||
result = target_data[target_offset];
|
||||
target_checksum = crc32_adjust(target_checksum, result);
|
||||
}
|
||||
if(((target_offset++ & 255) == 0) && progress) {
|
||||
progress(target_offset, source_length > target_length ? source_length : target_length);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void patch_write(uint8_t n) {
|
||||
patch_file.write(n);
|
||||
patch_checksum = crc32_adjust(patch_checksum, n);
|
||||
}
|
||||
|
||||
void target_write(uint8_t n) {
|
||||
if(target_offset < target_length) {
|
||||
target_data[target_offset] = n;
|
||||
target_checksum = crc32_adjust(target_checksum, n);
|
||||
}
|
||||
if(((target_offset++ & 255) == 0) && progress) {
|
||||
progress(target_offset, source_length > target_length ? source_length : target_length);
|
||||
}
|
||||
}
|
||||
|
||||
void encode(uint64_t offset) {
|
||||
while(true) {
|
||||
uint64_t x = offset & 0x7f;
|
||||
offset >>= 7;
|
||||
if(offset == 0) {
|
||||
write(0x80 | x);
|
||||
patch_write(0x80 | x);
|
||||
break;
|
||||
}
|
||||
write(x);
|
||||
patch_write(x);
|
||||
offset--;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t decptr() {
|
||||
uint64_t decode() {
|
||||
uint64_t offset = 0, shift = 1;
|
||||
while(true) {
|
||||
uint8_t x = read();
|
||||
uint8_t x = patch_read();
|
||||
offset += (x & 0x7f) * shift;
|
||||
if(x & 0x80) break;
|
||||
shift <<= 7;
|
||||
@@ -185,6 +215,7 @@ namespace nall {
|
||||
return offset;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -2,8 +2,9 @@ static void Button_tick(Button *self) {
|
||||
if(self->onTick) self->onTick();
|
||||
}
|
||||
|
||||
void Button::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void Button::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
object->widget = gtk_button_new_with_label(text);
|
||||
widget->parent = &parent;
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "clicked", G_CALLBACK(Button_tick), (gpointer)this);
|
||||
if(parent.window->defaultFont) setFont(*parent.window->defaultFont);
|
||||
|
@@ -22,6 +22,7 @@ void Canvas::create(Window &parent, unsigned x, unsigned y, unsigned width, unsi
|
||||
canvas->pitch = width * sizeof(uint32_t);
|
||||
|
||||
object->widget = gtk_drawing_area_new();
|
||||
widget->parent = &parent;
|
||||
GdkColor color;
|
||||
color.pixel = color.red = color.green = color.blue = 0;
|
||||
gtk_widget_modify_bg(object->widget, GTK_STATE_NORMAL, &color);
|
||||
|
@@ -2,8 +2,9 @@ static void CheckBox_tick(CheckBox *self) {
|
||||
if(self->onTick && self->object->locked == false) self->onTick();
|
||||
}
|
||||
|
||||
void CheckBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void CheckBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
object->widget = gtk_check_button_new_with_label(text);
|
||||
widget->parent = &parent;
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "toggled", G_CALLBACK(CheckBox_tick), (gpointer)this);
|
||||
if(parent.window->defaultFont) setFont(*parent.window->defaultFont);
|
||||
|
@@ -2,8 +2,9 @@ void ComboBox_change(ComboBox *self) {
|
||||
if(self->object->locked == false && self->onChange) self->onChange();
|
||||
}
|
||||
|
||||
void ComboBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void ComboBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
object->widget = gtk_combo_box_new_text();
|
||||
widget->parent = &parent;
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "changed", G_CALLBACK(ComboBox_change), (gpointer)this);
|
||||
|
||||
@@ -27,7 +28,7 @@ void ComboBox::reset() {
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
void ComboBox::addItem(const char *text) {
|
||||
void ComboBox::addItem(const string &text) {
|
||||
gtk_combo_box_append_text(GTK_COMBO_BOX(object->widget), text);
|
||||
if(counter++ == 0) setSelection(0);
|
||||
}
|
||||
|
@@ -2,8 +2,9 @@ static void EditBox_change(EditBox *self) {
|
||||
if(self->object->locked == false && self->onChange) self->onChange();
|
||||
}
|
||||
|
||||
void EditBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void EditBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
object->widget = gtk_scrolled_window_new(0, 0);
|
||||
widget->parent = &parent;
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(object->widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(object->widget), GTK_SHADOW_ETCHED_IN);
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
@@ -41,7 +42,7 @@ string EditBox::text() {
|
||||
return text;
|
||||
}
|
||||
|
||||
void EditBox::setText(const char *text) {
|
||||
void EditBox::setText(const string &text) {
|
||||
object->locked = true;
|
||||
gtk_text_buffer_set_text(object->textBuffer, text, -1);
|
||||
object->locked = false;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
bool Font::create(const char *name, unsigned size, Font::Style style) {
|
||||
bool Font::create(const string &name, unsigned size, Font::Style style) {
|
||||
font->font = pango_font_description_new();
|
||||
pango_font_description_set_family(font->font, name);
|
||||
pango_font_description_set_size(font->font, size * PANGO_SCALE);
|
||||
|
@@ -37,12 +37,30 @@ namespace phoenix {
|
||||
#include "viewport.cpp"
|
||||
#include "messagewindow.cpp"
|
||||
|
||||
OS &os = OS::handle();
|
||||
Window Window::None;
|
||||
|
||||
OS& OS::handle() {
|
||||
static OS os;
|
||||
return os;
|
||||
void OS::initialize() {
|
||||
static bool initialized = false;
|
||||
if(initialized == true) return;
|
||||
initialized = true;
|
||||
|
||||
int argc = 1;
|
||||
char *argv[2];
|
||||
argv[0] = new char[8];
|
||||
argv[1] = 0;
|
||||
strcpy(argv[0], "phoenix");
|
||||
char **argvp = argv;
|
||||
gtk_init(&argc, &argvp);
|
||||
|
||||
gtk_rc_parse_string(
|
||||
"style \"phoenix-gtk\"\n"
|
||||
"{\n"
|
||||
" GtkComboBox::appears-as-list = 1\n"
|
||||
" GtkTreeView::vertical-separator = 0\n"
|
||||
"}\n"
|
||||
"class \"GtkComboBox\" style \"phoenix-gtk\"\n"
|
||||
"class \"GtkTreeView\" style \"phoenix-gtk\"\n"
|
||||
);
|
||||
}
|
||||
|
||||
bool OS::pending() {
|
||||
@@ -69,7 +87,7 @@ unsigned OS::desktopHeight() {
|
||||
return gdk_screen_get_height(gdk_screen_get_default());
|
||||
}
|
||||
|
||||
string OS::folderSelect(Window &parent, const char *path) {
|
||||
string OS::folderSelect(Window &parent, const string &path) {
|
||||
string name;
|
||||
|
||||
GtkWidget *dialog = gtk_file_chooser_dialog_new(
|
||||
@@ -90,10 +108,11 @@ string OS::folderSelect(Window &parent, const char *path) {
|
||||
}
|
||||
|
||||
gtk_widget_destroy(dialog);
|
||||
if(name.endswith("/") == false) name.append("/");
|
||||
return name;
|
||||
}
|
||||
|
||||
string OS::fileOpen(Window &parent, const char *filter, const char *path) {
|
||||
string OS::fileOpen(Window &parent, const string &filter, const string &path) {
|
||||
string name;
|
||||
|
||||
GtkWidget *dialog = gtk_file_chooser_dialog_new(
|
||||
@@ -130,7 +149,7 @@ string OS::fileOpen(Window &parent, const char *filter, const char *path) {
|
||||
return name;
|
||||
}
|
||||
|
||||
string OS::fileSave(Window &parent, const char *filter, const char *path) {
|
||||
string OS::fileSave(Window &parent, const string &filter, const string &path) {
|
||||
string name;
|
||||
|
||||
GtkWidget *dialog = gtk_file_chooser_dialog_new(
|
||||
@@ -167,25 +186,4 @@ string OS::fileSave(Window &parent, const char *filter, const char *path) {
|
||||
return name;
|
||||
}
|
||||
|
||||
OS::OS() {
|
||||
os = new OS::Data;
|
||||
int argc = 1;
|
||||
char *argv[2];
|
||||
argv[0] = new char[8];
|
||||
argv[1] = 0;
|
||||
strcpy(argv[0], "phoenix");
|
||||
char **argvp = argv;
|
||||
gtk_init(&argc, &argvp);
|
||||
|
||||
gtk_rc_parse_string(
|
||||
"style \"phoenix-gtk\"\n"
|
||||
"{\n"
|
||||
" GtkComboBox::appears-as-list = 1\n"
|
||||
" GtkTreeView::vertical-separator = 0\n"
|
||||
"}\n"
|
||||
"class \"GtkComboBox\" style \"phoenix-gtk\"\n"
|
||||
"class \"GtkTreeView\" style \"phoenix-gtk\"\n"
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -12,13 +12,20 @@ struct Object {
|
||||
Data *object;
|
||||
};
|
||||
|
||||
struct Geometry {
|
||||
unsigned x, y;
|
||||
unsigned width, height;
|
||||
inline Geometry() : x(0), y(0), width(0), height(0) {}
|
||||
inline Geometry(unsigned x, unsigned y, unsigned width, unsigned height) : x(x), y(y), width(width), height(height) {}
|
||||
};
|
||||
|
||||
struct Font : Object {
|
||||
enum class Style : unsigned {
|
||||
None = 0,
|
||||
Bold = 1,
|
||||
Italic = 2,
|
||||
};
|
||||
bool create(const char *name, unsigned size, Font::Style style = Style::None);
|
||||
bool create(const nall::string &name, unsigned size, Font::Style style = Style::None);
|
||||
Font();
|
||||
~Font();
|
||||
//private:
|
||||
@@ -30,16 +37,19 @@ inline Font::Style operator|(Font::Style a, Font::Style b) { return (Font::Style
|
||||
inline Font::Style operator&(Font::Style a, Font::Style b) { return (Font::Style)((unsigned)a & (unsigned)b); }
|
||||
|
||||
struct Action : Object {
|
||||
void setFont(Font &font);
|
||||
bool visible();
|
||||
void setVisible(bool visible = true);
|
||||
bool enabled();
|
||||
void setEnabled(bool enabled = true);
|
||||
Action();
|
||||
//private:
|
||||
struct Data;
|
||||
Data *action;
|
||||
};
|
||||
|
||||
struct Menu : Action {
|
||||
void create(Window &parent, const char *text);
|
||||
void create(Menu &parent, const char *text);
|
||||
void create(Window &parent, const nall::string &text);
|
||||
void create(Menu &parent, const nall::string &text);
|
||||
};
|
||||
|
||||
struct MenuSeparator : Action {
|
||||
@@ -48,20 +58,20 @@ struct MenuSeparator : Action {
|
||||
|
||||
struct MenuItem : Action {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Menu &parent, const char *text);
|
||||
void create(Menu &parent, const nall::string &text);
|
||||
};
|
||||
|
||||
struct MenuCheckItem : Action {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Menu &parent, const char *text);
|
||||
void create(Menu &parent, const nall::string &text);
|
||||
bool checked();
|
||||
void setChecked(bool checked = true);
|
||||
};
|
||||
|
||||
struct MenuRadioItem : Action {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Menu &parent, const char *text);
|
||||
void create(MenuRadioItem &parent, const char *text);
|
||||
void create(Menu &parent, const nall::string &text);
|
||||
void create(MenuRadioItem &parent, const nall::string &text);
|
||||
bool checked();
|
||||
void setChecked();
|
||||
private:
|
||||
@@ -76,31 +86,37 @@ struct Widget : Object {
|
||||
void setEnabled(bool enabled = true);
|
||||
virtual bool focused();
|
||||
virtual void setFocused();
|
||||
virtual void setGeometry(unsigned x, unsigned y, unsigned width, unsigned height);
|
||||
Widget();
|
||||
//private:
|
||||
struct Data;
|
||||
Data *widget;
|
||||
};
|
||||
|
||||
struct Window : Widget {
|
||||
static Window None;
|
||||
nall::function<bool ()> onClose;
|
||||
void create(unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
bool focused();
|
||||
void setFocused();
|
||||
Geometry geometry();
|
||||
void setGeometry(unsigned x, unsigned y, unsigned width, unsigned height);
|
||||
void setDefaultFont(Font &font);
|
||||
void setFont(Font &font);
|
||||
void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue);
|
||||
void setTitle(const char *text);
|
||||
void setStatusText(const char *text);
|
||||
void setTitle(const nall::string &text);
|
||||
void setStatusText(const nall::string &text);
|
||||
void setMenuVisible(bool visible = true);
|
||||
void setStatusVisible(bool visible = true);
|
||||
Window();
|
||||
//private:
|
||||
struct Data;
|
||||
Data *window;
|
||||
static Window None;
|
||||
};
|
||||
|
||||
struct Button : Widget {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
};
|
||||
|
||||
struct Canvas : Widget {
|
||||
@@ -116,16 +132,16 @@ struct Canvas : Widget {
|
||||
|
||||
struct CheckBox : Widget {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
bool checked();
|
||||
void setChecked(bool checked = true);
|
||||
};
|
||||
|
||||
struct ComboBox : Widget {
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
void reset();
|
||||
void addItem(const char *text);
|
||||
void addItem(const nall::string &text);
|
||||
unsigned selection();
|
||||
void setSelection(unsigned item);
|
||||
ComboBox();
|
||||
@@ -135,12 +151,12 @@ private:
|
||||
|
||||
struct EditBox : Widget {
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
void setFocused();
|
||||
void setEditable(bool editable = true);
|
||||
void setWordWrap(bool wordWrap = true);
|
||||
nall::string text();
|
||||
void setText(const char *text);
|
||||
void setText(const nall::string &text);
|
||||
};
|
||||
|
||||
struct HorizontalSlider : Widget {
|
||||
@@ -151,21 +167,25 @@ struct HorizontalSlider : Widget {
|
||||
};
|
||||
|
||||
struct Label : Widget {
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void setText(const char *text);
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
void setText(const nall::string &text);
|
||||
};
|
||||
|
||||
struct ListBox : Widget {
|
||||
nall::function<void ()> onActivate;
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
nall::function<void (unsigned)> onTick;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
void setFocused();
|
||||
void setHeaderVisible(bool headerVisible = true);
|
||||
void setCheckable(bool checkable = true);
|
||||
void setFont(Font &font);
|
||||
void reset();
|
||||
void resizeColumnsToContent();
|
||||
void addItem(const char *text);
|
||||
void setItem(unsigned row, const char *text);
|
||||
void addItem(const nall::string &text);
|
||||
void setItem(unsigned row, const nall::string &text);
|
||||
bool checked(unsigned row);
|
||||
void setChecked(unsigned row, bool checked = true);
|
||||
nall::optional<unsigned> selection();
|
||||
void setSelection(unsigned row);
|
||||
ListBox();
|
||||
@@ -176,13 +196,13 @@ struct ListBox : Widget {
|
||||
|
||||
struct ProgressBar : Widget {
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height);
|
||||
void setProgress(unsigned progress);
|
||||
void setPosition(unsigned position);
|
||||
};
|
||||
|
||||
struct RadioBox : Widget {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(RadioBox &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
void create(RadioBox &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
bool checked();
|
||||
void setChecked();
|
||||
private:
|
||||
@@ -190,11 +210,12 @@ private:
|
||||
};
|
||||
|
||||
struct TextBox : Widget {
|
||||
nall::function<void ()> onActivate;
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
void setEditable(bool editable = true);
|
||||
nall::string text();
|
||||
void setText(const char *text);
|
||||
void setText(const nall::string &text);
|
||||
};
|
||||
|
||||
struct VerticalSlider : Widget {
|
||||
@@ -221,30 +242,24 @@ struct MessageWindow : Object {
|
||||
Yes,
|
||||
No,
|
||||
};
|
||||
static Response information(Window &parent, const char *text, Buttons = Buttons::Ok);
|
||||
static Response question(Window &parent, const char *text, Buttons = Buttons::YesNo);
|
||||
static Response warning(Window &parent, const char *text, Buttons = Buttons::Ok);
|
||||
static Response critical(Window &parent, const char *text, Buttons = Buttons::Ok);
|
||||
static Response information(Window &parent, const nall::string &text, Buttons = Buttons::Ok);
|
||||
static Response question(Window &parent, const nall::string &text, Buttons = Buttons::YesNo);
|
||||
static Response warning(Window &parent, const nall::string &text, Buttons = Buttons::Ok);
|
||||
static Response critical(Window &parent, const nall::string &text, Buttons = Buttons::Ok);
|
||||
};
|
||||
|
||||
struct OS : Object {
|
||||
bool pending();
|
||||
void run();
|
||||
void main();
|
||||
void quit();
|
||||
unsigned desktopWidth();
|
||||
unsigned desktopHeight();
|
||||
nall::string folderSelect(Window &parent, const char *path = "");
|
||||
nall::string fileOpen(Window &parent, const char *filter, const char *path = "");
|
||||
nall::string fileSave(Window &parent, const char *filter, const char *path = "");
|
||||
static bool pending();
|
||||
static void run();
|
||||
static void main();
|
||||
static void quit();
|
||||
static unsigned desktopWidth();
|
||||
static unsigned desktopHeight();
|
||||
static nall::string folderSelect(Window &parent, const nall::string &path = "");
|
||||
static nall::string fileOpen(Window &parent, const nall::string &filter, const nall::string &path = "");
|
||||
static nall::string fileSave(Window &parent, const nall::string &filter, const nall::string &path = "");
|
||||
//private:
|
||||
static OS& handle();
|
||||
struct Data;
|
||||
Data *os;
|
||||
private:
|
||||
OS();
|
||||
static void initialize();
|
||||
};
|
||||
|
||||
extern OS &os;
|
||||
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@ void HorizontalSlider::create(Window &parent, unsigned x, unsigned y, unsigned w
|
||||
object->position = 0;
|
||||
length += (length == 0);
|
||||
object->widget = gtk_hscale_new_with_range(0, length - 1, 1);
|
||||
widget->parent = &parent;
|
||||
gtk_scale_set_draw_value(GTK_SCALE(object->widget), false);
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "value-changed", G_CALLBACK(HorizontalSlider_change), (gpointer)this);
|
||||
|
@@ -1,5 +1,6 @@
|
||||
void Label::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void Label::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
object->widget = gtk_label_new(text);
|
||||
widget->parent = &parent;
|
||||
gtk_misc_set_alignment(GTK_MISC(object->widget), 0.0, 0.5);
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
if(parent.window->defaultFont) setFont(*parent.window->defaultFont);
|
||||
@@ -7,6 +8,6 @@ void Label::create(Window &parent, unsigned x, unsigned y, unsigned width, unsig
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
void Label::setText(const char *text) {
|
||||
void Label::setText(const string &text) {
|
||||
gtk_label_set_text(GTK_LABEL(object->widget), text);
|
||||
}
|
||||
|
@@ -1,3 +1,10 @@
|
||||
static void ListBox_activate(ListBox *self) {
|
||||
signed selection = -1;
|
||||
if(auto position = self->selection()) selection = position();
|
||||
self->listBox->selection = selection;
|
||||
if(self->onActivate) self->onActivate();
|
||||
}
|
||||
|
||||
static void ListBox_change(ListBox *self) {
|
||||
signed selection = -1;
|
||||
if(auto position = self->selection()) selection = position();
|
||||
@@ -6,25 +13,25 @@ static void ListBox_change(ListBox *self) {
|
||||
if(self->onChange) self->onChange();
|
||||
}
|
||||
|
||||
static void ListBox_activate(ListBox *self) {
|
||||
signed selection = -1;
|
||||
if(auto position = self->selection()) selection = position();
|
||||
self->listBox->selection = selection;
|
||||
if(self->onActivate) self->onActivate();
|
||||
static void ListBox_tick(GtkCellRendererToggle *cell, gchar *path_string, ListBox *self) {
|
||||
unsigned index = strunsigned(path_string);
|
||||
self->setChecked(index, !self->checked(index));
|
||||
if(self->onTick) self->onTick(index);
|
||||
}
|
||||
|
||||
void ListBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void ListBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
listBox->selection = -1;
|
||||
object->widget = gtk_scrolled_window_new(0, 0);
|
||||
widget->parent = &parent;
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(object->widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(object->widget), GTK_SHADOW_ETCHED_IN);
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
|
||||
lstring list;
|
||||
list.split("\t", text);
|
||||
list.split("\t", string("\t", text));
|
||||
|
||||
GType *v = (GType*)malloc(list.size() * sizeof(GType));
|
||||
for(unsigned i = 0; i < list.size(); i++) v[i] = G_TYPE_STRING;
|
||||
for(unsigned i = 0; i < list.size(); i++) v[i] = (i == 0 ? G_TYPE_BOOLEAN : G_TYPE_STRING);
|
||||
listBox->store = gtk_list_store_newv(list.size(), v);
|
||||
free(v);
|
||||
|
||||
@@ -32,20 +39,30 @@ void ListBox::create(Window &parent, unsigned x, unsigned y, unsigned width, uns
|
||||
gtk_container_add(GTK_CONTAINER(object->widget), object->subWidget);
|
||||
g_object_unref(G_OBJECT(listBox->store));
|
||||
|
||||
//alternate color of each row if there is more than one column
|
||||
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(object->subWidget), list.size() >= 2);
|
||||
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(object->subWidget), false);
|
||||
|
||||
for(unsigned i = 0; i < list.size(); i++) {
|
||||
if(i == 0) {
|
||||
listBox->column[i].renderer = gtk_cell_renderer_toggle_new();
|
||||
listBox->column[i].column = gtk_tree_view_column_new_with_attributes(
|
||||
"", listBox->column[i].renderer, "active", i, (void*)0
|
||||
);
|
||||
gtk_tree_view_column_set_resizable(listBox->column[i].column, false);
|
||||
gtk_tree_view_column_set_visible(listBox->column[i].column, listBox->checkable);
|
||||
g_signal_connect(listBox->column[i].renderer, "toggled", G_CALLBACK(ListBox_tick), (gpointer)this);
|
||||
} else {
|
||||
listBox->column[i].renderer = gtk_cell_renderer_text_new();
|
||||
listBox->column[i].column = gtk_tree_view_column_new_with_attributes(
|
||||
list[i], listBox->column[i].renderer, "text", i, (void*)0
|
||||
"", listBox->column[i].renderer, "text", i, (void*)0
|
||||
);
|
||||
gtk_tree_view_column_set_resizable(listBox->column[i].column, true);
|
||||
}
|
||||
listBox->column[i].label = gtk_label_new(list[i]);
|
||||
gtk_tree_view_column_set_widget(GTK_TREE_VIEW_COLUMN(listBox->column[i].column), listBox->column[i].label);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(object->subWidget), listBox->column[i].column);
|
||||
gtk_widget_show(listBox->column[i].label);
|
||||
}
|
||||
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(object->subWidget), false);
|
||||
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(object->subWidget), list.size() >= 3); //>= 2 + one for the checkbox column
|
||||
gtk_tree_view_set_search_column(GTK_TREE_VIEW(object->subWidget), 1);
|
||||
|
||||
g_signal_connect_swapped(G_OBJECT(object->subWidget), "cursor-changed", G_CALLBACK(ListBox_change), (gpointer)this);
|
||||
g_signal_connect_swapped(G_OBJECT(object->subWidget), "row-activated", G_CALLBACK(ListBox_activate), (gpointer)this);
|
||||
@@ -64,6 +81,11 @@ void ListBox::setHeaderVisible(bool visible) {
|
||||
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(object->subWidget), visible);
|
||||
}
|
||||
|
||||
void ListBox::setCheckable(bool checkable) {
|
||||
listBox->checkable = checkable;
|
||||
if(object->subWidget) gtk_tree_view_column_set_visible(listBox->column[0].column, checkable);
|
||||
}
|
||||
|
||||
void ListBox::setFont(Font &font) {
|
||||
Widget::setFont(font);
|
||||
unsigned columns = 1;
|
||||
@@ -89,17 +111,16 @@ void ListBox::resizeColumnsToContent() {
|
||||
gtk_tree_view_columns_autosize(GTK_TREE_VIEW(object->subWidget));
|
||||
}
|
||||
|
||||
void ListBox::addItem(const char *text) {
|
||||
void ListBox::addItem(const string &text) {
|
||||
lstring list;
|
||||
list.split("\t", text);
|
||||
GtkTreeIter iter;
|
||||
gtk_list_store_append(listBox->store, &iter);
|
||||
for(unsigned i = 0; i < list.size(); i++) {
|
||||
gtk_list_store_set(listBox->store, &iter, i, (const char*)list[i], -1);
|
||||
}
|
||||
unsigned index = 1;
|
||||
foreach(item, list) gtk_list_store_set(listBox->store, &iter, index++, (const char*)item, -1);
|
||||
}
|
||||
|
||||
void ListBox::setItem(unsigned row, const char *text) {
|
||||
void ListBox::setItem(unsigned row, const string &text) {
|
||||
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(object->subWidget));
|
||||
GtkTreeIter iter;
|
||||
for(unsigned i = 0; i <= row; i++) {
|
||||
@@ -109,9 +130,28 @@ void ListBox::setItem(unsigned row, const char *text) {
|
||||
|
||||
lstring list;
|
||||
list.split("\t", text);
|
||||
for(unsigned i = 0; i < list.size(); i++) {
|
||||
gtk_list_store_set(listBox->store, &iter, i, (const char*)list[i], -1);
|
||||
unsigned index = 1;
|
||||
foreach(item, list) gtk_list_store_set(listBox->store, &iter, index++, (const char*)item, -1);
|
||||
}
|
||||
|
||||
bool ListBox::checked(unsigned row) {
|
||||
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(object->subWidget));
|
||||
GtkTreePath *path = gtk_tree_path_new_from_string(string(row));
|
||||
GtkTreeIter iter;
|
||||
bool state;
|
||||
gtk_tree_model_get_iter(model, &iter, path);
|
||||
gtk_tree_model_get(model, &iter, 0, &state, -1);
|
||||
gtk_tree_path_free(path);
|
||||
return state;
|
||||
}
|
||||
|
||||
void ListBox::setChecked(unsigned row, bool checked) {
|
||||
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(object->subWidget));
|
||||
GtkTreePath *path = gtk_tree_path_new_from_string(string(row));
|
||||
GtkTreeIter iter;
|
||||
gtk_tree_model_get_iter(model, &iter, path);
|
||||
gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, checked, -1);
|
||||
gtk_tree_path_free(path);
|
||||
}
|
||||
|
||||
optional<unsigned> ListBox::selection() {
|
||||
@@ -151,4 +191,5 @@ void ListBox::setSelection(unsigned row) {
|
||||
|
||||
ListBox::ListBox() {
|
||||
listBox = new ListBox::Data;
|
||||
listBox->checkable = false;
|
||||
}
|
||||
|
@@ -1,12 +1,10 @@
|
||||
static void Action_setFont(GtkWidget *widget, gpointer font) {
|
||||
if(font) {
|
||||
gtk_widget_modify_font(widget, (PangoFontDescription*)font);
|
||||
if(GTK_IS_CONTAINER(widget)) {
|
||||
gtk_container_foreach(GTK_CONTAINER(widget), (GtkCallback)Action_setFont, font);
|
||||
gtk_container_foreach(GTK_CONTAINER(widget), (GtkCallback)Action_setFont, (PangoFontDescription*)font);
|
||||
}
|
||||
}
|
||||
|
||||
void Action::setFont(Font &font) {
|
||||
Action_setFont(object->widget, font.font->font);
|
||||
}
|
||||
|
||||
bool Action::visible() {
|
||||
@@ -25,25 +23,35 @@ void Action::setEnabled(bool enabled) {
|
||||
gtk_widget_set_sensitive(object->widget, enabled);
|
||||
}
|
||||
|
||||
void Menu::create(Window &parent, const char *text) {
|
||||
Action::Action() {
|
||||
action = new Action::Data;
|
||||
action->font = 0;
|
||||
}
|
||||
|
||||
void Menu::create(Window &parent, const string &text) {
|
||||
action->font = parent.window->defaultFont;
|
||||
object->menu = gtk_menu_new();
|
||||
object->widget = gtk_menu_item_new_with_label(text);
|
||||
gtk_menu_item_set_submenu(GTK_MENU_ITEM(object->widget), object->menu);
|
||||
if(parent.window->defaultFont) setFont(*parent.window->defaultFont);
|
||||
if(action->font) Action_setFont(object->widget, action->font->font->font);
|
||||
gtk_menu_bar_append(parent.object->menu, object->widget);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
void Menu::create(Menu &parent, const char *text) {
|
||||
void Menu::create(Menu &parent, const string &text) {
|
||||
action->font = parent.action->font;
|
||||
object->menu = gtk_menu_new();
|
||||
object->widget = gtk_menu_item_new_with_label(text);
|
||||
gtk_menu_item_set_submenu(GTK_MENU_ITEM(object->widget), object->menu);
|
||||
if(action->font) Action_setFont(object->widget, action->font->font->font);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(parent.object->menu), object->widget);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
void MenuSeparator::create(Menu &parent) {
|
||||
action->font = parent.action->font;
|
||||
object->widget = gtk_separator_menu_item_new();
|
||||
if(action->font) Action_setFont(object->widget, action->font->font->font);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(parent.object->menu), object->widget);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
@@ -52,9 +60,11 @@ static void MenuItem_tick(MenuItem *self) {
|
||||
if(self->onTick) self->onTick();
|
||||
}
|
||||
|
||||
void MenuItem::create(Menu &parent, const char *text) {
|
||||
void MenuItem::create(Menu &parent, const string &text) {
|
||||
action->font = parent.action->font;
|
||||
object->widget = gtk_menu_item_new_with_label(text);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "activate", G_CALLBACK(MenuItem_tick), (gpointer)this);
|
||||
if(action->font) Action_setFont(object->widget, action->font->font->font);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(parent.object->menu), object->widget);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
@@ -63,9 +73,11 @@ static void MenuCheckItem_tick(MenuCheckItem *self) {
|
||||
if(self->onTick && self->object->locked == false) self->onTick();
|
||||
}
|
||||
|
||||
void MenuCheckItem::create(Menu &parent, const char *text) {
|
||||
void MenuCheckItem::create(Menu &parent, const string &text) {
|
||||
action->font = parent.action->font;
|
||||
object->widget = gtk_check_menu_item_new_with_label(text);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "toggled", G_CALLBACK(MenuCheckItem_tick), (gpointer)this);
|
||||
if(action->font) Action_setFont(object->widget, action->font->font->font);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(parent.object->menu), object->widget);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
@@ -84,20 +96,24 @@ static void MenuRadioItem_tick(MenuRadioItem *self) {
|
||||
if(self->onTick && self->checked() && self->object->locked == false) self->onTick();
|
||||
}
|
||||
|
||||
void MenuRadioItem::create(Menu &parent, const char *text) {
|
||||
void MenuRadioItem::create(Menu &parent, const string &text) {
|
||||
first = this;
|
||||
action->font = parent.action->font;
|
||||
object->parentMenu = &parent;
|
||||
object->widget = gtk_radio_menu_item_new_with_label(0, text);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "toggled", G_CALLBACK(MenuRadioItem_tick), (gpointer)this);
|
||||
if(action->font) Action_setFont(object->widget, action->font->font->font);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(parent.object->menu), object->widget);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
void MenuRadioItem::create(MenuRadioItem &parent, const char *text) {
|
||||
void MenuRadioItem::create(MenuRadioItem &parent, const string &text) {
|
||||
first = parent.first;
|
||||
action->font = parent.action->font;
|
||||
object->parentMenu = parent.object->parentMenu;
|
||||
object->widget = gtk_radio_menu_item_new_with_label_from_widget(GTK_RADIO_MENU_ITEM(first->object->widget), text);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "toggled", G_CALLBACK(MenuRadioItem_tick), (gpointer)this);
|
||||
if(action->font) Action_setFont(object->widget, action->font->font->font);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(object->parentMenu->object->menu), object->widget);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
@@ -8,56 +8,56 @@ static MessageWindow::Response MessageWindow_response(MessageWindow::Buttons but
|
||||
return MessageWindow::Response::Ok;
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::information(Window &parent, const char *text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response MessageWindow::information(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
GtkButtonsType buttonsType = GTK_BUTTONS_OK;
|
||||
if(buttons == Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL;
|
||||
if(buttons == Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO;
|
||||
|
||||
GtkWidget *dialog = gtk_message_dialog_new(
|
||||
&parent != &Window::None ? GTK_WINDOW(parent.object->widget) : (GtkWindow*)0,
|
||||
GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, buttonsType, "%s", text
|
||||
GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, buttonsType, "%s", (const char*)text
|
||||
);
|
||||
gint response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
return MessageWindow_response(buttons, response);
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::question(Window &parent, const char *text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response MessageWindow::question(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
GtkButtonsType buttonsType = GTK_BUTTONS_OK;
|
||||
if(buttons == Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL;
|
||||
if(buttons == Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO;
|
||||
|
||||
GtkWidget *dialog = gtk_message_dialog_new(
|
||||
&parent != &Window::None ? GTK_WINDOW(parent.object->widget) : (GtkWindow*)0,
|
||||
GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, buttonsType, "%s", text
|
||||
GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, buttonsType, "%s", (const char*)text
|
||||
);
|
||||
gint response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
return MessageWindow_response(buttons, response);
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::warning(Window &parent, const char *text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response MessageWindow::warning(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
GtkButtonsType buttonsType = GTK_BUTTONS_OK;
|
||||
if(buttons == Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL;
|
||||
if(buttons == Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO;
|
||||
|
||||
GtkWidget *dialog = gtk_message_dialog_new(
|
||||
&parent != &Window::None ? GTK_WINDOW(parent.object->widget) : (GtkWindow*)0,
|
||||
GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, buttonsType, "%s", text
|
||||
GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, buttonsType, "%s", (const char*)text
|
||||
);
|
||||
gint response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
return MessageWindow_response(buttons, response);
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::critical(Window &parent, const char *text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response MessageWindow::critical(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
GtkButtonsType buttonsType = GTK_BUTTONS_OK;
|
||||
if(buttons == Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL;
|
||||
if(buttons == Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO;
|
||||
|
||||
GtkWidget *dialog = gtk_message_dialog_new(
|
||||
&parent != &Window::None ? GTK_WINDOW(parent.object->widget) : (GtkWindow*)0,
|
||||
GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, buttonsType, "%s", text
|
||||
GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, buttonsType, "%s", (const char*)text
|
||||
);
|
||||
gint response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
|
@@ -17,6 +17,14 @@ struct Font::Data {
|
||||
PangoFontDescription *font;
|
||||
};
|
||||
|
||||
struct Action::Data {
|
||||
Font *font;
|
||||
};
|
||||
|
||||
struct Widget::Data {
|
||||
Window *parent;
|
||||
};
|
||||
|
||||
struct Window::Data {
|
||||
Font *defaultFont;
|
||||
};
|
||||
@@ -35,16 +43,15 @@ struct ListBox::Data {
|
||||
GtkWidget *label;
|
||||
};
|
||||
linear_vector<GtkColumn> column;
|
||||
bool checkable;
|
||||
signed selection;
|
||||
};
|
||||
|
||||
struct OS::Data {
|
||||
};
|
||||
|
||||
void Object::unused() {
|
||||
}
|
||||
|
||||
Object::Object() {
|
||||
OS::initialize();
|
||||
object = new Object::Data;
|
||||
object->locked = false;
|
||||
}
|
||||
|
@@ -1,11 +1,12 @@
|
||||
void ProgressBar::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height) {
|
||||
object->widget = gtk_progress_bar_new();
|
||||
widget->parent = &parent;
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
gtk_fixed_put(GTK_FIXED(parent.object->formContainer), object->widget, x, y);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
void ProgressBar::setProgress(unsigned progress) {
|
||||
progress = progress <= 100 ? progress : 0;
|
||||
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(object->widget), (double)progress / 100.0);
|
||||
void ProgressBar::setPosition(unsigned position) {
|
||||
position = position <= 100 ? position : 0;
|
||||
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(object->widget), (double)position / 100.0);
|
||||
}
|
||||
|
@@ -2,10 +2,11 @@ static void RadioBox_tick(RadioBox *self) {
|
||||
if(self->onTick && self->checked() && self->object->locked == false) self->onTick();
|
||||
}
|
||||
|
||||
void RadioBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void RadioBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
first = this;
|
||||
object->parentWindow = &parent;
|
||||
object->widget = gtk_radio_button_new_with_label(0, text);
|
||||
widget->parent = &parent;
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "toggled", G_CALLBACK(RadioBox_tick), (gpointer)this);
|
||||
if(parent.window->defaultFont) setFont(*parent.window->defaultFont);
|
||||
@@ -13,7 +14,7 @@ void RadioBox::create(Window &parent, unsigned x, unsigned y, unsigned width, un
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
void RadioBox::create(RadioBox &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void RadioBox::create(RadioBox &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
first = parent.first;
|
||||
object->parentWindow = parent.object->parentWindow;
|
||||
object->widget = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(parent.object->widget), text);
|
||||
|
@@ -1,11 +1,17 @@
|
||||
static void TextBox_activate(TextBox *self) {
|
||||
if(self->onActivate) self->onActivate();
|
||||
}
|
||||
|
||||
static void TextBox_change(TextBox *self) {
|
||||
if(self->object->locked == false && self->onChange) self->onChange();
|
||||
}
|
||||
|
||||
void TextBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void TextBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
object->widget = gtk_entry_new();
|
||||
widget->parent = &parent;
|
||||
gtk_entry_set_text(GTK_ENTRY(object->widget), text);
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "activate", G_CALLBACK(TextBox_activate), (gpointer)this);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "changed", G_CALLBACK(TextBox_change), (gpointer)this);
|
||||
if(parent.window->defaultFont) setFont(*parent.window->defaultFont);
|
||||
gtk_fixed_put(GTK_FIXED(parent.object->formContainer), object->widget, x, y);
|
||||
@@ -20,7 +26,7 @@ string TextBox::text() {
|
||||
return gtk_entry_get_text(GTK_ENTRY(object->widget));
|
||||
}
|
||||
|
||||
void TextBox::setText(const char *text) {
|
||||
void TextBox::setText(const string &text) {
|
||||
object->locked = true;
|
||||
gtk_entry_set_text(GTK_ENTRY(object->widget), text);
|
||||
object->locked = false;
|
||||
|
@@ -8,6 +8,7 @@ void VerticalSlider::create(Window &parent, unsigned x, unsigned y, unsigned wid
|
||||
object->position = 0;
|
||||
length += (length == 0);
|
||||
object->widget = gtk_vscale_new_with_range(0, length - 1, 1);
|
||||
widget->parent = &parent;
|
||||
gtk_scale_set_draw_value(GTK_SCALE(object->widget), false);
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "value-changed", G_CALLBACK(VerticalSlider_change), (gpointer)this);
|
||||
|
@@ -1,7 +1,16 @@
|
||||
void Viewport::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height) {
|
||||
object->widget = gtk_drawing_area_new();
|
||||
gtk_widget_set_double_buffered(object->widget, false);
|
||||
widget->parent = &parent;
|
||||
//gtk_widget_set_double_buffered(object->widget, false);
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
|
||||
GdkColor color;
|
||||
color.pixel = 0;
|
||||
color.red = 0;
|
||||
color.green = 0;
|
||||
color.blue = 0;
|
||||
gtk_widget_modify_bg(object->widget, GTK_STATE_NORMAL, &color);
|
||||
|
||||
gtk_fixed_put(GTK_FIXED(parent.object->formContainer), object->widget, x, y);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
@@ -34,3 +34,14 @@ void Widget::setFocused() {
|
||||
if(visible() == false) setVisible(true);
|
||||
gtk_widget_grab_focus(object->widget);
|
||||
}
|
||||
|
||||
void Widget::setGeometry(unsigned x, unsigned y, unsigned width, unsigned height) {
|
||||
if(widget->parent == 0) return;
|
||||
gtk_fixed_move(GTK_FIXED(widget->parent->object->formContainer), object->widget, x, y);
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
}
|
||||
|
||||
Widget::Widget() {
|
||||
widget = new Widget::Data;
|
||||
widget->parent = 0;
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@ static gint Window_close(Window *window) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Window::create(unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void Window::create(unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
object->widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_move(GTK_WINDOW(object->widget), x, y);
|
||||
|
||||
@@ -47,6 +47,13 @@ void Window::setFocused() {
|
||||
gtk_window_present(GTK_WINDOW(object->widget));
|
||||
}
|
||||
|
||||
Geometry Window::geometry() {
|
||||
gint x, y, width, height;
|
||||
gtk_window_get_position(GTK_WINDOW(object->widget), &x, &y);
|
||||
gtk_widget_get_size_request(object->formContainer, &width, &height);
|
||||
return Geometry(x, y, width, height);
|
||||
}
|
||||
|
||||
void Window::setGeometry(unsigned x, unsigned y, unsigned width, unsigned height) {
|
||||
gtk_window_move(GTK_WINDOW(object->widget), x, y);
|
||||
gtk_widget_set_size_request(object->formContainer, width, height);
|
||||
@@ -69,11 +76,11 @@ void Window::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) {
|
||||
gtk_widget_modify_bg(object->widget, GTK_STATE_NORMAL, &color);
|
||||
}
|
||||
|
||||
void Window::setTitle(const char *text) {
|
||||
void Window::setTitle(const string &text) {
|
||||
gtk_window_set_title(GTK_WINDOW(object->widget), text);
|
||||
}
|
||||
|
||||
void Window::setStatusText(const char *text) {
|
||||
void Window::setStatusText(const string &text) {
|
||||
gtk_statusbar_pop(GTK_STATUSBAR(object->status), 1);
|
||||
gtk_statusbar_push(GTK_STATUSBAR(object->status), 1, text);
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
void Button::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void Button::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
button->setParent(parent.window->container);
|
||||
button->setGeometry(x, y, width, height);
|
||||
button->setText(text);
|
||||
button->setText(QString::fromUtf8(text));
|
||||
if(parent.window->defaultFont) button->setFont(*parent.window->defaultFont);
|
||||
button->show();
|
||||
button->connect(button, SIGNAL(released()), SLOT(onTick()));
|
||||
|
@@ -1,7 +1,7 @@
|
||||
void CheckBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void CheckBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
checkBox->setParent(parent.window->container);
|
||||
checkBox->setGeometry(x, y, width, height);
|
||||
checkBox->setText(text);
|
||||
checkBox->setText(QString::fromUtf8(text));
|
||||
if(parent.window->defaultFont) checkBox->setFont(*parent.window->defaultFont);
|
||||
checkBox->show();
|
||||
checkBox->connect(checkBox, SIGNAL(stateChanged(int)), SLOT(onTick()));
|
||||
|
@@ -1,11 +1,11 @@
|
||||
void ComboBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void ComboBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
comboBox->setParent(parent.window->container);
|
||||
comboBox->setGeometry(x, y, width, height);
|
||||
|
||||
if(*text) {
|
||||
lstring list;
|
||||
list.split("\n", text);
|
||||
foreach(item, list) addItem((const char*)item);
|
||||
foreach(item, list) addItem(item);
|
||||
}
|
||||
|
||||
comboBox->connect(comboBox, SIGNAL(currentIndexChanged(int)), SLOT(onChange()));
|
||||
@@ -17,8 +17,8 @@ void ComboBox::reset() {
|
||||
while(comboBox->count()) comboBox->removeItem(0);
|
||||
}
|
||||
|
||||
void ComboBox::addItem(const char *text) {
|
||||
comboBox->addItem(text);
|
||||
void ComboBox::addItem(const string &text) {
|
||||
comboBox->addItem(QString::fromUtf8(text));
|
||||
}
|
||||
|
||||
unsigned ComboBox::selection() {
|
||||
@@ -27,7 +27,9 @@ unsigned ComboBox::selection() {
|
||||
}
|
||||
|
||||
void ComboBox::setSelection(unsigned row) {
|
||||
object->locked = true;
|
||||
comboBox->setCurrentIndex(row);
|
||||
object->locked = false;
|
||||
}
|
||||
|
||||
ComboBox::ComboBox() {
|
||||
|
@@ -1,13 +1,14 @@
|
||||
void EditBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void EditBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
editBox->setParent(parent.window->container);
|
||||
editBox->setGeometry(x, y, width, height);
|
||||
editBox->setText(text);
|
||||
editBox->setPlainText(QString::fromUtf8(text));
|
||||
if(parent.window->defaultFont) editBox->setFont(*parent.window->defaultFont);
|
||||
editBox->show();
|
||||
editBox->connect(editBox, SIGNAL(textChanged()), SLOT(onChange()));
|
||||
}
|
||||
|
||||
void EditBox::setEditable(bool editable) {
|
||||
editBox->setReadOnly(editable == false);
|
||||
}
|
||||
|
||||
void EditBox::setWordWrap(bool wordWrap) {
|
||||
@@ -15,9 +16,11 @@ void EditBox::setWordWrap(bool wordWrap) {
|
||||
}
|
||||
|
||||
string EditBox::text() {
|
||||
return editBox->toPlainText().toUtf8().constData();
|
||||
}
|
||||
|
||||
void EditBox::setText(const char *text) {
|
||||
void EditBox::setText(const string &text) {
|
||||
editBox->setPlainText(QString::fromUtf8(text));
|
||||
}
|
||||
|
||||
EditBox::EditBox() {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
bool Font::create(const char *name, unsigned size, Font::Style style) {
|
||||
font->setFamily(name);
|
||||
bool Font::create(const string &name, unsigned size, Font::Style style) {
|
||||
font->setFamily(QString::fromUtf8(name));
|
||||
font->setPointSize(size);
|
||||
font->setBold((style & Style::Bold) == Style::Bold);
|
||||
font->setItalic((style & Style::Italic) == Style::Italic);
|
||||
|
@@ -1,13 +1,13 @@
|
||||
void Label::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void Label::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
label->setParent(parent.window->container);
|
||||
label->setGeometry(x, y, width, height);
|
||||
label->setText(text);
|
||||
label->setText(QString::fromUtf8(text));
|
||||
if(parent.window->defaultFont) label->setFont(*parent.window->defaultFont);
|
||||
label->show();
|
||||
}
|
||||
|
||||
void Label::setText(const char *text) {
|
||||
label->setText(text);
|
||||
void Label::setText(const string &text) {
|
||||
label->setText(QString::fromUtf8(text));
|
||||
}
|
||||
|
||||
Label::Label() {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
void ListBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void ListBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
listBox->setParent(parent.window->container);
|
||||
listBox->setGeometry(x, y, width, height);
|
||||
listBox->setAllColumnsShowFocus(true);
|
||||
@@ -7,7 +7,7 @@ void ListBox::create(Window &parent, unsigned x, unsigned y, unsigned width, uns
|
||||
lstring list;
|
||||
list.split("\t", text);
|
||||
QStringList labels;
|
||||
foreach(item, list) labels << (const char*)item;
|
||||
foreach(item, list) labels << QString::fromUtf8(item);
|
||||
listBox->setColumnCount(list.size());
|
||||
listBox->setHeaderLabels(labels);
|
||||
for(unsigned i = 0; i < list.size(); i++) listBox->resizeColumnToContents(i);
|
||||
@@ -16,6 +16,7 @@ void ListBox::create(Window &parent, unsigned x, unsigned y, unsigned width, uns
|
||||
listBox->setAlternatingRowColors(list.size() >= 2);
|
||||
listBox->connect(listBox, SIGNAL(itemActivated(QTreeWidgetItem*, int)), SLOT(onActivate()));
|
||||
listBox->connect(listBox, SIGNAL(itemSelectionChanged()), SLOT(onChange()));
|
||||
listBox->connect(listBox, SIGNAL(itemChanged(QTreeWidgetItem*, int)), SLOT(onTick(QTreeWidgetItem*)));
|
||||
if(parent.window->defaultFont) listBox->setFont(*parent.window->defaultFont);
|
||||
listBox->show();
|
||||
}
|
||||
@@ -24,6 +25,14 @@ void ListBox::setHeaderVisible(bool headerVisible) {
|
||||
listBox->setHeaderHidden(headerVisible == false);
|
||||
}
|
||||
|
||||
void ListBox::setCheckable(bool checkable) {
|
||||
listBox->checkable = checkable;
|
||||
if(listBox->checkable) {
|
||||
auto items = listBox->findItems("", Qt::MatchContains);
|
||||
for(unsigned i = 0; i < items.size(); i++) items[i]->setCheckState(0, Qt::Unchecked);
|
||||
}
|
||||
}
|
||||
|
||||
void ListBox::reset() {
|
||||
listBox->clear();
|
||||
}
|
||||
@@ -32,20 +41,37 @@ void ListBox::resizeColumnsToContent() {
|
||||
for(unsigned i = 0; i < listBox->columnCount(); i++) listBox->resizeColumnToContents(i);
|
||||
}
|
||||
|
||||
void ListBox::addItem(const char *text) {
|
||||
void ListBox::addItem(const string &text) {
|
||||
object->locked = true;
|
||||
auto items = listBox->findItems("", Qt::MatchContains);
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(listBox);
|
||||
if(listBox->checkable) item->setCheckState(0, Qt::Unchecked);
|
||||
item->setData(0, Qt::UserRole, (unsigned)items.size());
|
||||
lstring list;
|
||||
list.split("\t", text);
|
||||
for(unsigned i = 0; i < list.size(); i++) item->setText(i, (const char*)list[i]);
|
||||
for(unsigned i = 0; i < list.size(); i++) item->setText(i, QString::fromUtf8(list[i]));
|
||||
object->locked = false;
|
||||
}
|
||||
|
||||
void ListBox::setItem(unsigned row, const char *text) {
|
||||
void ListBox::setItem(unsigned row, const string &text) {
|
||||
object->locked = true;
|
||||
QTreeWidgetItem *item = listBox->topLevelItem(row);
|
||||
lstring list;
|
||||
list.split("\t", text);
|
||||
for(unsigned i = 0; i < list.size(); i++) item->setText(i, (const char*)list[i]);
|
||||
for(unsigned i = 0; i < list.size(); i++) item->setText(i, QString::fromUtf8(list[i]));
|
||||
object->locked = false;
|
||||
}
|
||||
|
||||
bool ListBox::checked(unsigned row) {
|
||||
QTreeWidgetItem *item = listBox->topLevelItem(row);
|
||||
return (item ? item->checkState(0) == Qt::Checked : false);
|
||||
}
|
||||
|
||||
void ListBox::setChecked(unsigned row, bool checked) {
|
||||
object->locked = true;
|
||||
QTreeWidgetItem *item = listBox->topLevelItem(row);
|
||||
if(item) item->setCheckState(0, checked ? Qt::Checked : Qt::Unchecked);
|
||||
object->locked = false;
|
||||
}
|
||||
|
||||
optional<unsigned> ListBox::selection() {
|
||||
|
@@ -1,10 +1,14 @@
|
||||
void Menu::create(Window &parent, const char *text) {
|
||||
menu->setTitle(text);
|
||||
void Menu::create(Window &parent, const string &text) {
|
||||
menu->parent = &parent;
|
||||
if(menu->parent->window->defaultFont) menu->setFont(*menu->parent->window->defaultFont);
|
||||
menu->setTitle(QString::fromUtf8(text));
|
||||
parent.window->menuBar->addMenu(menu);
|
||||
}
|
||||
|
||||
void Menu::create(Menu &parent, const char *text) {
|
||||
menu->setTitle(text);
|
||||
void Menu::create(Menu &parent, const string &text) {
|
||||
menu->parent = parent.menu->parent;
|
||||
if(menu->parent->window->defaultFont) menu->setFont(*menu->parent->window->defaultFont);
|
||||
menu->setTitle(QString::fromUtf8(text));
|
||||
parent.menu->addMenu(menu);
|
||||
}
|
||||
|
||||
@@ -52,8 +56,8 @@ MenuSeparator::MenuSeparator() {
|
||||
menuSeparator = new MenuSeparator::Data(*this);
|
||||
}
|
||||
|
||||
void MenuItem::create(Menu &parent, const char *text) {
|
||||
menuItem->setText(text);
|
||||
void MenuItem::create(Menu &parent, const string &text) {
|
||||
menuItem->setText(QString::fromUtf8(text));
|
||||
menuItem->connect(menuItem, SIGNAL(triggered()), SLOT(onTick()));
|
||||
parent.menu->addAction(menuItem);
|
||||
}
|
||||
@@ -78,8 +82,8 @@ MenuItem::MenuItem() {
|
||||
menuItem = new MenuItem::Data(*this);
|
||||
}
|
||||
|
||||
void MenuCheckItem::create(Menu &parent, const char *text) {
|
||||
menuCheckItem->setText(text);
|
||||
void MenuCheckItem::create(Menu &parent, const string &text) {
|
||||
menuCheckItem->setText(QString::fromUtf8(text));
|
||||
menuCheckItem->setCheckable(true);
|
||||
menuCheckItem->connect(menuCheckItem, SIGNAL(triggered()), SLOT(onTick()));
|
||||
parent.menu->addAction(menuCheckItem);
|
||||
@@ -113,22 +117,22 @@ MenuCheckItem::MenuCheckItem() {
|
||||
menuCheckItem = new MenuCheckItem::Data(*this);
|
||||
}
|
||||
|
||||
void MenuRadioItem::create(Menu &parent, const char *text) {
|
||||
void MenuRadioItem::create(Menu &parent, const string &text) {
|
||||
menuRadioItem->parent = &parent;
|
||||
menuRadioItem->actionGroup = new QActionGroup(0);
|
||||
menuRadioItem->actionGroup->addAction(menuRadioItem);
|
||||
menuRadioItem->setText(text);
|
||||
menuRadioItem->setText(QString::fromUtf8(text));
|
||||
menuRadioItem->setCheckable(true);
|
||||
menuRadioItem->setChecked(true);
|
||||
menuRadioItem->connect(menuRadioItem, SIGNAL(changed()), SLOT(onTick()));
|
||||
menuRadioItem->parent->menu->addAction(menuRadioItem);
|
||||
}
|
||||
|
||||
void MenuRadioItem::create(MenuRadioItem &parent, const char *text) {
|
||||
void MenuRadioItem::create(MenuRadioItem &parent, const string &text) {
|
||||
menuRadioItem->parent = parent.menuRadioItem->parent;
|
||||
menuRadioItem->actionGroup = parent.menuRadioItem->actionGroup;
|
||||
menuRadioItem->actionGroup->addAction(menuRadioItem);
|
||||
menuRadioItem->setText(text);
|
||||
menuRadioItem->setText(QString::fromUtf8(text));
|
||||
menuRadioItem->setCheckable(true);
|
||||
menuRadioItem->connect(menuRadioItem, SIGNAL(changed()), SLOT(onTick()));
|
||||
menuRadioItem->parent->menu->addAction(menuRadioItem);
|
||||
|
@@ -16,26 +16,30 @@ static MessageWindow::Response MessageWindow_response(MessageWindow::Buttons but
|
||||
return MessageWindow::Response::Ok;
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::information(Window &parent, const char *text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response MessageWindow::information(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
return MessageWindow_response(
|
||||
buttons, QMessageBox::information(&parent != &Window::None ? parent.window : 0, " ", text, MessageWindow_buttons(buttons))
|
||||
buttons, QMessageBox::information(&parent != &Window::None ? parent.window : 0, " ",
|
||||
QString::fromUtf8(text), MessageWindow_buttons(buttons))
|
||||
);
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::question(Window &parent, const char *text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response MessageWindow::question(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
return MessageWindow_response(
|
||||
buttons, QMessageBox::question(&parent != &Window::None ? parent.window : 0, " ", text, MessageWindow_buttons(buttons))
|
||||
buttons, QMessageBox::question(&parent != &Window::None ? parent.window : 0, " ",
|
||||
QString::fromUtf8(text), MessageWindow_buttons(buttons))
|
||||
);
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::warning(Window &parent, const char *text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response MessageWindow::warning(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
return MessageWindow_response(
|
||||
buttons, QMessageBox::warning(&parent != &Window::None ? parent.window : 0, " ", text, MessageWindow_buttons(buttons))
|
||||
buttons, QMessageBox::warning(&parent != &Window::None ? parent.window : 0, " ",
|
||||
QString::fromUtf8(text), MessageWindow_buttons(buttons))
|
||||
);
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::critical(Window &parent, const char *text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response MessageWindow::critical(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
return MessageWindow_response(
|
||||
buttons, QMessageBox::critical(&parent != &Window::None ? parent.window : 0, " ", text, MessageWindow_buttons(buttons))
|
||||
buttons, QMessageBox::critical(&parent != &Window::None ? parent.window : 0, " ",
|
||||
QString::fromUtf8(text), MessageWindow_buttons(buttons))
|
||||
);
|
||||
}
|
||||
|
@@ -2,5 +2,6 @@ void Object::unused() {
|
||||
}
|
||||
|
||||
Object::Object() {
|
||||
OS::initialize();
|
||||
object = new Object::Data(*this);
|
||||
}
|
||||
|
@@ -6,8 +6,8 @@ void ProgressBar::create(Window &parent, unsigned x, unsigned y, unsigned width,
|
||||
progressBar->show();
|
||||
}
|
||||
|
||||
void ProgressBar::setProgress(unsigned progress) {
|
||||
progressBar->setValue(progress);
|
||||
void ProgressBar::setPosition(unsigned position) {
|
||||
progressBar->setValue(position);
|
||||
}
|
||||
|
||||
ProgressBar::ProgressBar() {
|
||||
|
@@ -27,12 +27,22 @@ namespace phoenix {
|
||||
#include "viewport.cpp"
|
||||
#include "messagewindow.cpp"
|
||||
|
||||
OS &os = OS::handle();
|
||||
OS::Data *OS::os = 0;
|
||||
Window Window::None;
|
||||
|
||||
OS& OS::handle() {
|
||||
static OS os;
|
||||
return os;
|
||||
void OS::initialize() {
|
||||
static bool initialized = false;
|
||||
if(initialized == true) return;
|
||||
initialized = true;
|
||||
|
||||
os = new OS::Data;
|
||||
static int argc = 1;
|
||||
static char *argv[2];
|
||||
argv[0] = new char[8];
|
||||
argv[1] = 0;
|
||||
strcpy(argv[0], "phoenix");
|
||||
char **argvp = argv;
|
||||
os->application = new QApplication(argc, argvp);
|
||||
}
|
||||
|
||||
bool OS::pending() {
|
||||
@@ -59,14 +69,17 @@ unsigned OS::desktopHeight() {
|
||||
return QApplication::desktop()->screenGeometry().height();
|
||||
}
|
||||
|
||||
string OS::folderSelect(Window &parent, const char *path) {
|
||||
string OS::folderSelect(Window &parent, const string &path) {
|
||||
QString directory = QFileDialog::getExistingDirectory(
|
||||
&parent != &Window::None ? parent.window : 0, "Select Directory", path, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
|
||||
&parent != &Window::None ? parent.window : 0, "Select Directory",
|
||||
QString::fromUtf8(path), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
|
||||
);
|
||||
return directory.toUtf8().constData();
|
||||
string name = directory.toUtf8().constData();
|
||||
if(name.endswith("/") == false) name.append("/");
|
||||
return name;
|
||||
}
|
||||
|
||||
string OS::fileOpen(Window &parent, const char *filter, const char *path) {
|
||||
string OS::fileOpen(Window &parent, const string &filter, const string &path) {
|
||||
string filters;
|
||||
lstring list;
|
||||
list.split("\n", filter);
|
||||
@@ -83,12 +96,13 @@ string OS::fileOpen(Window &parent, const char *filter, const char *path) {
|
||||
filters.rtrim(";;");
|
||||
|
||||
QString filename = QFileDialog::getOpenFileName(
|
||||
&parent != &Window::None ? parent.window : 0, "Open File", path, (const char*)filters
|
||||
&parent != &Window::None ? parent.window : 0, "Open File",
|
||||
QString::fromUtf8(path), QString::fromUtf8(filters)
|
||||
);
|
||||
return filename.toUtf8().constData();
|
||||
}
|
||||
|
||||
string OS::fileSave(Window &parent, const char *filter, const char *path) {
|
||||
string OS::fileSave(Window &parent, const string &filter, const string &path) {
|
||||
string filters;
|
||||
lstring list;
|
||||
list.split("\n", filter);
|
||||
@@ -105,20 +119,10 @@ string OS::fileSave(Window &parent, const char *filter, const char *path) {
|
||||
filters.rtrim(";;");
|
||||
|
||||
QString filename = QFileDialog::getSaveFileName(
|
||||
&parent != &Window::None ? parent.window : 0, "Save File", path, (const char*)filters
|
||||
&parent != &Window::None ? parent.window : 0, "Save File",
|
||||
QString::fromUtf8(path), QString::fromUtf8(filters)
|
||||
);
|
||||
return filename.toUtf8().constData();
|
||||
}
|
||||
|
||||
OS::OS() {
|
||||
os = new OS::Data(*this);
|
||||
static int argc = 1;
|
||||
static char *argv[2];
|
||||
argv[0] = new char[8];
|
||||
argv[1] = 0;
|
||||
strcpy(argv[0], "phoenix");
|
||||
char **argvp = argv;
|
||||
os->application = new QApplication(argc, argvp);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -12,13 +12,20 @@ struct Object {
|
||||
Data *object;
|
||||
};
|
||||
|
||||
struct Geometry {
|
||||
unsigned x, y;
|
||||
unsigned width, height;
|
||||
inline Geometry() : x(0), y(0), width(0), height(0) {}
|
||||
inline Geometry(unsigned x, unsigned y, unsigned width, unsigned height) : x(x), y(y), width(width), height(height) {}
|
||||
};
|
||||
|
||||
struct Font : Object {
|
||||
enum class Style : unsigned {
|
||||
None = 0,
|
||||
Bold = 1,
|
||||
Italic = 2,
|
||||
};
|
||||
bool create(const char *name, unsigned size, Font::Style style = Style::None);
|
||||
bool create(const nall::string &name, unsigned size, Font::Style style = Style::None);
|
||||
Font();
|
||||
~Font();
|
||||
//private:
|
||||
@@ -37,8 +44,8 @@ struct Action : Object {
|
||||
};
|
||||
|
||||
struct Menu : Action {
|
||||
void create(Window &parent, const char *text);
|
||||
void create(Menu &parent, const char *text);
|
||||
void create(Window &parent, const nall::string &text);
|
||||
void create(Menu &parent, const nall::string &text);
|
||||
bool visible();
|
||||
void setVisible(bool visible = true);
|
||||
bool enabled();
|
||||
@@ -63,7 +70,7 @@ struct MenuSeparator : Action {
|
||||
|
||||
struct MenuItem : Action {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Menu &parent, const char *text);
|
||||
void create(Menu &parent, const nall::string &text);
|
||||
bool visible();
|
||||
void setVisible(bool visible = true);
|
||||
bool enabled();
|
||||
@@ -76,7 +83,7 @@ struct MenuItem : Action {
|
||||
|
||||
struct MenuCheckItem : Action {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Menu &parent, const char *text);
|
||||
void create(Menu &parent, const nall::string &text);
|
||||
bool visible();
|
||||
void setVisible(bool visible = true);
|
||||
bool enabled();
|
||||
@@ -91,8 +98,8 @@ struct MenuCheckItem : Action {
|
||||
|
||||
struct MenuRadioItem : Action {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Menu &parent, const char *text);
|
||||
void create(MenuRadioItem &parent, const char *text);
|
||||
void create(Menu &parent, const nall::string &text);
|
||||
void create(MenuRadioItem &parent, const nall::string &text);
|
||||
bool visible();
|
||||
void setVisible(bool visible = true);
|
||||
bool enabled();
|
||||
@@ -112,8 +119,8 @@ struct Widget : Object {
|
||||
void setVisible(bool visible = true);
|
||||
bool enabled();
|
||||
void setEnabled(bool enabled = true);
|
||||
bool focused();
|
||||
void setFocused();
|
||||
virtual bool focused();
|
||||
virtual void setFocused();
|
||||
Widget();
|
||||
//private:
|
||||
struct Data;
|
||||
@@ -121,26 +128,28 @@ struct Widget : Object {
|
||||
};
|
||||
|
||||
struct Window : Widget {
|
||||
static Window None;
|
||||
nall::function<bool ()> onClose;
|
||||
void create(unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
Geometry geometry();
|
||||
void setGeometry(unsigned x, unsigned y, unsigned width, unsigned height);
|
||||
void setDefaultFont(Font &font);
|
||||
void setFont(Font &font);
|
||||
void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue);
|
||||
void setTitle(const char *text);
|
||||
void setStatusText(const char *text);
|
||||
void setTitle(const nall::string &text);
|
||||
void setStatusText(const nall::string &text);
|
||||
void setMenuVisible(bool visible = true);
|
||||
void setStatusVisible(bool visible = true);
|
||||
bool focused();
|
||||
Window();
|
||||
//private:
|
||||
struct Data;
|
||||
Data *window;
|
||||
static Window None;
|
||||
};
|
||||
|
||||
struct Button : Widget {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
Button();
|
||||
//private:
|
||||
struct Data;
|
||||
@@ -161,7 +170,7 @@ struct Canvas : Widget {
|
||||
|
||||
struct CheckBox : Widget {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
bool checked();
|
||||
void setChecked(bool checked = true);
|
||||
CheckBox();
|
||||
@@ -172,9 +181,9 @@ struct CheckBox : Widget {
|
||||
|
||||
struct ComboBox : Widget {
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
void reset();
|
||||
void addItem(const char *text);
|
||||
void addItem(const nall::string &text);
|
||||
unsigned selection();
|
||||
void setSelection(unsigned row);
|
||||
ComboBox();
|
||||
@@ -185,11 +194,11 @@ struct ComboBox : Widget {
|
||||
|
||||
struct EditBox : Widget {
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
void setEditable(bool editable = true);
|
||||
void setWordWrap(bool wordWrap = true);
|
||||
nall::string text();
|
||||
void setText(const char *text);
|
||||
void setText(const nall::string &text);
|
||||
EditBox();
|
||||
//private:
|
||||
struct Data;
|
||||
@@ -208,8 +217,8 @@ struct HorizontalSlider : Widget {
|
||||
};
|
||||
|
||||
struct Label : Widget {
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void setText(const char *text);
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
void setText(const nall::string &text);
|
||||
Label();
|
||||
//private:
|
||||
struct Data;
|
||||
@@ -219,12 +228,16 @@ struct Label : Widget {
|
||||
struct ListBox : Widget {
|
||||
nall::function<void ()> onActivate;
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
nall::function<void (unsigned)> onTick;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
void setHeaderVisible(bool headerVisible = true);
|
||||
void setCheckable(bool checkable = true);
|
||||
void reset();
|
||||
void resizeColumnsToContent();
|
||||
void addItem(const char *text);
|
||||
void setItem(unsigned row, const char *text);
|
||||
void addItem(const nall::string &text);
|
||||
void setItem(unsigned row, const nall::string &text);
|
||||
bool checked(unsigned row);
|
||||
void setChecked(unsigned row, bool checked = true);
|
||||
nall::optional<unsigned> selection();
|
||||
void setSelection(unsigned row);
|
||||
ListBox();
|
||||
@@ -235,7 +248,7 @@ struct ListBox : Widget {
|
||||
|
||||
struct ProgressBar : Widget {
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height);
|
||||
void setProgress(unsigned progress);
|
||||
void setPosition(unsigned position);
|
||||
ProgressBar();
|
||||
//private:
|
||||
struct Data;
|
||||
@@ -244,8 +257,8 @@ struct ProgressBar : Widget {
|
||||
|
||||
struct RadioBox : Widget {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(RadioBox &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
void create(RadioBox &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
bool checked();
|
||||
void setChecked();
|
||||
RadioBox();
|
||||
@@ -255,11 +268,12 @@ struct RadioBox : Widget {
|
||||
};
|
||||
|
||||
struct TextBox : Widget {
|
||||
nall::function<void ()> onActivate;
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
void setEditable(bool editable = true);
|
||||
nall::string text();
|
||||
void setText(const char *text);
|
||||
void setText(const nall::string &text);
|
||||
TextBox();
|
||||
//private:
|
||||
struct Data;
|
||||
@@ -298,30 +312,26 @@ struct MessageWindow : Object {
|
||||
Yes,
|
||||
No,
|
||||
};
|
||||
static Response information(Window &parent, const char *text, Buttons = Buttons::Ok);
|
||||
static Response question(Window &parent, const char *text, Buttons = Buttons::YesNo);
|
||||
static Response warning(Window &parent, const char *text, Buttons = Buttons::Ok);
|
||||
static Response critical(Window &parent, const char *text, Buttons = Buttons::Ok);
|
||||
static Response information(Window &parent, const nall::string &text, Buttons = Buttons::Ok);
|
||||
static Response question(Window &parent, const nall::string &text, Buttons = Buttons::YesNo);
|
||||
static Response warning(Window &parent, const nall::string &text, Buttons = Buttons::Ok);
|
||||
static Response critical(Window &parent, const nall::string &text, Buttons = Buttons::Ok);
|
||||
};
|
||||
|
||||
struct OS : Object {
|
||||
bool pending();
|
||||
void run();
|
||||
void main();
|
||||
void quit();
|
||||
unsigned desktopWidth();
|
||||
unsigned desktopHeight();
|
||||
nall::string folderSelect(Window &parent, const char *path = "");
|
||||
nall::string fileOpen(Window &parent, const char *filter, const char *path = "");
|
||||
nall::string fileSave(Window &parent, const char *filter, const char *path = "");
|
||||
static bool pending();
|
||||
static void run();
|
||||
static void main();
|
||||
static void quit();
|
||||
static unsigned desktopWidth();
|
||||
static unsigned desktopHeight();
|
||||
static nall::string folderSelect(Window &parent, const nall::string &path = "");
|
||||
static nall::string fileOpen(Window &parent, const nall::string &filter, const nall::string &path = "");
|
||||
static nall::string fileSave(Window &parent, const nall::string &filter, const nall::string &path = "");
|
||||
//private:
|
||||
static OS& handle();
|
||||
struct Data;
|
||||
Data *os;
|
||||
private:
|
||||
OS();
|
||||
static Data *os;
|
||||
static void initialize();
|
||||
};
|
||||
|
||||
extern OS &os;
|
||||
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
** Meta object code from reading C++ file 'qt.moc.hpp'
|
||||
**
|
||||
** Created: Sat Sep 25 06:31:14 2010
|
||||
** Created: Mon Oct 11 13:03:04 2010
|
||||
** by: The Qt Meta Object Compiler version 62 (Qt 4.6.2)
|
||||
**
|
||||
** WARNING! All changes made in this file will be lost!
|
||||
@@ -641,7 +641,7 @@ static const uint qt_meta_data_ListBox__Data[] = {
|
||||
4, // revision
|
||||
0, // classname
|
||||
0, 0, // classinfo
|
||||
2, 14, // methods
|
||||
3, 14, // methods
|
||||
0, 0, // properties
|
||||
0, 0, // enums/sets
|
||||
0, 0, // constructors
|
||||
@@ -651,12 +651,14 @@ static const uint qt_meta_data_ListBox__Data[] = {
|
||||
// slots: signature, parameters, type, tag, flags
|
||||
15, 14, 14, 14, 0x0a,
|
||||
28, 14, 14, 14, 0x0a,
|
||||
44, 39, 14, 14, 0x0a,
|
||||
|
||||
0 // eod
|
||||
};
|
||||
|
||||
static const char qt_meta_stringdata_ListBox__Data[] = {
|
||||
"ListBox::Data\0\0onActivate()\0onChange()\0"
|
||||
"item\0onTick(QTreeWidgetItem*)\0"
|
||||
};
|
||||
|
||||
const QMetaObject ListBox::Data::staticMetaObject = {
|
||||
@@ -690,9 +692,10 @@ int ListBox::Data::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
|
||||
switch (_id) {
|
||||
case 0: onActivate(); break;
|
||||
case 1: onChange(); break;
|
||||
case 2: onTick((*reinterpret_cast< QTreeWidgetItem*(*)>(_a[1]))); break;
|
||||
default: ;
|
||||
}
|
||||
_id -= 2;
|
||||
_id -= 3;
|
||||
}
|
||||
return _id;
|
||||
}
|
||||
@@ -761,7 +764,7 @@ static const uint qt_meta_data_TextBox__Data[] = {
|
||||
4, // revision
|
||||
0, // classname
|
||||
0, 0, // classinfo
|
||||
1, 14, // methods
|
||||
2, 14, // methods
|
||||
0, 0, // properties
|
||||
0, 0, // enums/sets
|
||||
0, 0, // constructors
|
||||
@@ -770,12 +773,13 @@ static const uint qt_meta_data_TextBox__Data[] = {
|
||||
|
||||
// slots: signature, parameters, type, tag, flags
|
||||
15, 14, 14, 14, 0x0a,
|
||||
28, 14, 14, 14, 0x0a,
|
||||
|
||||
0 // eod
|
||||
};
|
||||
|
||||
static const char qt_meta_stringdata_TextBox__Data[] = {
|
||||
"TextBox::Data\0\0onChange()\0"
|
||||
"TextBox::Data\0\0onActivate()\0onChange()\0"
|
||||
};
|
||||
|
||||
const QMetaObject TextBox::Data::staticMetaObject = {
|
||||
@@ -807,10 +811,11 @@ int TextBox::Data::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
|
||||
return _id;
|
||||
if (_c == QMetaObject::InvokeMetaMethod) {
|
||||
switch (_id) {
|
||||
case 0: onChange(); break;
|
||||
case 0: onActivate(); break;
|
||||
case 1: onChange(); break;
|
||||
default: ;
|
||||
}
|
||||
_id -= 1;
|
||||
_id -= 2;
|
||||
}
|
||||
return _id;
|
||||
}
|
||||
|
@@ -19,8 +19,9 @@ public:
|
||||
struct Menu::Data : public QMenu {
|
||||
public:
|
||||
Menu &self;
|
||||
Window *parent;
|
||||
|
||||
Data(Menu &self) : self(self) {
|
||||
Data(Menu &self) : self(self), parent(0) {
|
||||
}
|
||||
};
|
||||
|
||||
@@ -164,7 +165,7 @@ public:
|
||||
|
||||
public slots:
|
||||
void onChange() {
|
||||
if(self.onChange) self.onChange();
|
||||
if(self.object->locked == false && self.onChange) self.onChange();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -213,8 +214,10 @@ struct ListBox::Data : public QTreeWidget {
|
||||
|
||||
public:
|
||||
ListBox &self;
|
||||
bool checkable;
|
||||
|
||||
Data(ListBox &self) : self(self) {
|
||||
checkable = false;
|
||||
}
|
||||
|
||||
public slots:
|
||||
@@ -225,6 +228,10 @@ public slots:
|
||||
void onChange() {
|
||||
if(self.object->locked == false && self.onChange) self.onChange();
|
||||
}
|
||||
|
||||
void onTick(QTreeWidgetItem *item) {
|
||||
if(self.object->locked == false && self.onTick) self.onTick(item->data(0, Qt::UserRole).toUInt());
|
||||
}
|
||||
};
|
||||
|
||||
struct ProgressBar::Data : public QProgressBar {
|
||||
@@ -262,6 +269,10 @@ public:
|
||||
}
|
||||
|
||||
public slots:
|
||||
void onActivate() {
|
||||
if(self.onActivate) self.onActivate();
|
||||
}
|
||||
|
||||
void onChange() {
|
||||
if(self.onChange) self.onChange();
|
||||
}
|
||||
@@ -294,11 +305,7 @@ struct OS::Data : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
OS &self;
|
||||
QApplication *application;
|
||||
|
||||
Data(OS &self) : self(self) {
|
||||
}
|
||||
|
||||
public slots:
|
||||
};
|
||||
|
@@ -1,23 +1,23 @@
|
||||
void RadioBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void RadioBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
radioBox->parent = &parent;
|
||||
radioBox->buttonGroup = new QButtonGroup;
|
||||
radioBox->buttonGroup->addButton(radioBox);
|
||||
radioBox->setParent(radioBox->parent->window->container);
|
||||
radioBox->setGeometry(x, y, width, height);
|
||||
radioBox->setText(text);
|
||||
radioBox->setText(QString::fromUtf8(text));
|
||||
radioBox->setChecked(true);
|
||||
if(parent.window->defaultFont) radioBox->setFont(*parent.window->defaultFont);
|
||||
radioBox->show();
|
||||
radioBox->connect(radioBox, SIGNAL(toggled(bool)), SLOT(onTick()));
|
||||
}
|
||||
|
||||
void RadioBox::create(RadioBox &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void RadioBox::create(RadioBox &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
radioBox->parent = parent.radioBox->parent;
|
||||
radioBox->buttonGroup = parent.radioBox->buttonGroup;
|
||||
radioBox->buttonGroup->addButton(radioBox);
|
||||
radioBox->setParent(radioBox->parent->window->container);
|
||||
radioBox->setGeometry(x, y, width, height);
|
||||
radioBox->setText(text);
|
||||
radioBox->setText(QString::fromUtf8(text));
|
||||
if(radioBox->parent->window->defaultFont) radioBox->setFont(*radioBox->parent->window->defaultFont);
|
||||
radioBox->show();
|
||||
radioBox->connect(radioBox, SIGNAL(toggled(bool)), SLOT(onTick()));
|
||||
|
@@ -1,9 +1,10 @@
|
||||
void TextBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void TextBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
textBox->setParent(parent.window->container);
|
||||
textBox->setGeometry(x, y, width, height);
|
||||
textBox->setText(text);
|
||||
textBox->setText(QString::fromUtf8(text));
|
||||
if(parent.window->defaultFont) textBox->setFont(*parent.window->defaultFont);
|
||||
textBox->show();
|
||||
textBox->connect(textBox, SIGNAL(returnPressed()), SLOT(onActivate()));
|
||||
textBox->connect(textBox, SIGNAL(textEdited(const QString&)), SLOT(onChange()));
|
||||
}
|
||||
|
||||
@@ -15,8 +16,8 @@ string TextBox::text() {
|
||||
return textBox->text().toUtf8().constData();
|
||||
}
|
||||
|
||||
void TextBox::setText(const char *text) {
|
||||
textBox->setText(text);
|
||||
void TextBox::setText(const string &text) {
|
||||
textBox->setText(QString::fromUtf8(text));
|
||||
}
|
||||
|
||||
TextBox::TextBox() {
|
||||
|
@@ -1,6 +1,8 @@
|
||||
void Viewport::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height) {
|
||||
viewport->setParent(parent.window->container);
|
||||
viewport->setGeometry(x, y, width, height);
|
||||
viewport->setAttribute(Qt::WA_PaintOnScreen, true);
|
||||
viewport->setStyleSheet("background: #000000");
|
||||
viewport->show();
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
void Window::create(unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
window->setWindowTitle(text);
|
||||
void Window::create(unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
window->setWindowTitle(QString::fromUtf8(text));
|
||||
window->move(x, y);
|
||||
|
||||
window->layout = new QVBoxLayout(window);
|
||||
@@ -23,6 +23,10 @@ void Window::create(unsigned x, unsigned y, unsigned width, unsigned height, con
|
||||
window->layout->addWidget(window->statusBar);
|
||||
}
|
||||
|
||||
Geometry Window::geometry() {
|
||||
return Geometry(window->x(), window->y(), window->container->width(), window->container->height());
|
||||
}
|
||||
|
||||
void Window::setGeometry(unsigned x, unsigned y, unsigned width, unsigned height) {
|
||||
window->container->setFixedSize(width, height);
|
||||
window->move(x, y);
|
||||
@@ -44,12 +48,12 @@ void Window::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) {
|
||||
window->setAutoFillBackground(true);
|
||||
}
|
||||
|
||||
void Window::setTitle(const char *text) {
|
||||
window->setWindowTitle(text);
|
||||
void Window::setTitle(const string &text) {
|
||||
window->setWindowTitle(QString::fromUtf8(text));
|
||||
}
|
||||
|
||||
void Window::setStatusText(const char *text) {
|
||||
window->statusBar->showMessage(text, 0);
|
||||
void Window::setStatusText(const string &text) {
|
||||
window->statusBar->showMessage(QString::fromUtf8(text), 0);
|
||||
}
|
||||
|
||||
void Window::setMenuVisible(bool visible) {
|
||||
@@ -62,6 +66,10 @@ void Window::setStatusVisible(bool visible) {
|
||||
else window->statusBar->hide();
|
||||
}
|
||||
|
||||
bool Window::focused() {
|
||||
return window->isActiveWindow() && !window->isMinimized();
|
||||
}
|
||||
|
||||
Window::Window() {
|
||||
window = new Window::Data(*this);
|
||||
window->defaultFont = 0;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
void Button::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void Button::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
widget->window = CreateWindow(
|
||||
L"BUTTON", utf16_t(text),
|
||||
WS_CHILD | WS_TABSTOP | WS_VISIBLE,
|
||||
@@ -6,5 +6,5 @@ void Button::create(Window &parent, unsigned x, unsigned y, unsigned width, unsi
|
||||
parent.widget->window, (HMENU)object->id, GetModuleHandle(0), 0
|
||||
);
|
||||
SetWindowLongPtr(widget->window, GWLP_USERDATA, (LONG_PTR)this);
|
||||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : os.os->proportionalFont), 0);
|
||||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : OS::os->proportionalFont), 0);
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
void CheckBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void CheckBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
widget->window = CreateWindow(
|
||||
L"BUTTON", utf16_t(text),
|
||||
WS_CHILD | WS_TABSTOP | WS_VISIBLE | BS_CHECKBOX,
|
||||
@@ -6,7 +6,7 @@ void CheckBox::create(Window &parent, unsigned x, unsigned y, unsigned width, un
|
||||
parent.widget->window, (HMENU)object->id, GetModuleHandle(0), 0
|
||||
);
|
||||
SetWindowLongPtr(widget->window, GWLP_USERDATA, (LONG_PTR)this);
|
||||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : os.os->proportionalFont), 0);
|
||||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : OS::os->proportionalFont), 0);
|
||||
}
|
||||
|
||||
bool CheckBox::checked() {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
void ComboBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void ComboBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
widget->window = CreateWindowEx(
|
||||
0, L"COMBOBOX", L"",
|
||||
WS_CHILD | WS_TABSTOP | WS_VISIBLE | CBS_DROPDOWNLIST | CBS_HASSTRINGS,
|
||||
@@ -7,7 +7,7 @@ void ComboBox::create(Window &parent, unsigned x, unsigned y, unsigned width, un
|
||||
);
|
||||
|
||||
SetWindowLongPtr(widget->window, GWLP_USERDATA, (LONG_PTR)this);
|
||||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : os.os->proportionalFont), 0);
|
||||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : OS::os->proportionalFont), 0);
|
||||
|
||||
//CreateWindow height parameter is the height of the expanded list box;
|
||||
//need additional code to override default ComboBox control height
|
||||
@@ -27,7 +27,7 @@ void ComboBox::reset() {
|
||||
SendMessage(widget->window, CB_RESETCONTENT, 0, 0);
|
||||
}
|
||||
|
||||
void ComboBox::addItem(const char *text) {
|
||||
void ComboBox::addItem(const string &text) {
|
||||
SendMessage(widget->window, CB_ADDSTRING, 0, (LPARAM)(wchar_t*)utf16_t(text));
|
||||
if(SendMessage(widget->window, CB_GETCOUNT, 0, 0) == 1) setSelection(0);
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
void EditBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void EditBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
widget->window = CreateWindowEx(
|
||||
WS_EX_CLIENTEDGE, L"EDIT", L"",
|
||||
WS_CHILD | WS_VISIBLE | ES_AUTOVSCROLL | ES_MULTILINE | ES_WANTRETURN |
|
||||
@@ -8,7 +8,7 @@ void EditBox::create(Window &parent, unsigned x, unsigned y, unsigned width, uns
|
||||
);
|
||||
setText(text);
|
||||
SetWindowLongPtr(widget->window, GWLP_USERDATA, (LONG_PTR)this);
|
||||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : os.os->proportionalFont), 0);
|
||||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : OS::os->proportionalFont), 0);
|
||||
}
|
||||
|
||||
string EditBox::getText() {
|
||||
@@ -21,7 +21,7 @@ string EditBox::getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
void EditBox::setText(const char *text) {
|
||||
void EditBox::setText(const string &text) {
|
||||
string output = text;
|
||||
output.replace("\r", "");
|
||||
output.replace("\n", "\r\n");
|
||||
|
@@ -1,4 +1,4 @@
|
||||
static HFONT Font_createFont(const char *name, unsigned size, bool bold, bool italic) {
|
||||
static HFONT Font_createFont(const string &name, unsigned size, bool bold, bool italic) {
|
||||
return CreateFont(
|
||||
-(size * 96.0 / 72.0 + 0.5),
|
||||
0, 0, 0, bold == false ? FW_NORMAL : FW_BOLD, italic, 0, 0, 0, 0, 0, 0, 0,
|
||||
@@ -6,7 +6,7 @@ static HFONT Font_createFont(const char *name, unsigned size, bool bold, bool it
|
||||
);
|
||||
}
|
||||
|
||||
bool Font::create(const char *name, unsigned size, Font::Style style) {
|
||||
bool Font::create(const string &name, unsigned size, Font::Style style) {
|
||||
font->font = Font_createFont(
|
||||
name, size,
|
||||
(style & Font::Style::Bold) == Font::Style::Bold,
|
||||
|
@@ -1,4 +1,4 @@
|
||||
void Label::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void Label::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
widget->window = CreateWindow(
|
||||
L"phoenix_label", L"",
|
||||
WS_CHILD | WS_VISIBLE,
|
||||
@@ -6,12 +6,13 @@ void Label::create(Window &parent, unsigned x, unsigned y, unsigned width, unsig
|
||||
parent.widget->window, (HMENU)object->id, GetModuleHandle(0), 0
|
||||
);
|
||||
SetWindowLongPtr(widget->window, GWLP_USERDATA, (LONG_PTR)this);
|
||||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : os.os->proportionalFont), 0);
|
||||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : OS::os->proportionalFont), 0);
|
||||
setText(text);
|
||||
}
|
||||
|
||||
void Label::setText(const char *text) {
|
||||
void Label::setText(const string &text) {
|
||||
SetWindowText(widget->window, utf16_t(text));
|
||||
InvalidateRect(widget->window, 0, false);
|
||||
}
|
||||
|
||||
//all of this for want of a STATIC SS_VCENTER flag ...
|
||||
@@ -24,28 +25,14 @@ LRESULT CALLBACK Label_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa
|
||||
Label &label = *label_ptr;
|
||||
|
||||
switch(msg) {
|
||||
case WM_ERASEBKGND: {
|
||||
if(window.window->brush == 0) break;
|
||||
RECT rc;
|
||||
GetClientRect(window.widget->window, &rc);
|
||||
PAINTSTRUCT ps;
|
||||
BeginPaint(window.widget->window, &ps);
|
||||
FillRect(ps.hdc, &rc, window.window->brush);
|
||||
EndPaint(window.widget->window, &ps);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_PAINT: {
|
||||
PAINTSTRUCT ps;
|
||||
BeginPaint(hwnd, &ps);
|
||||
SelectObject(ps.hdc, label.widget->font);
|
||||
if(window.window->brush) {
|
||||
SetBkColor(ps.hdc, window.window->brushColor);
|
||||
} else {
|
||||
SetBkColor(ps.hdc, GetSysColor(COLOR_3DFACE));
|
||||
}
|
||||
RECT rc;
|
||||
BeginPaint(hwnd, &ps);
|
||||
GetClientRect(hwnd, &rc);
|
||||
FillRect(ps.hdc, &rc, window.window->brush ? window.window->brush : GetSysColorBrush(COLOR_3DFACE));
|
||||
SetBkColor(ps.hdc, window.window->brush ? window.window->brushColor : GetSysColor(COLOR_3DFACE));
|
||||
SelectObject(ps.hdc, label.widget->font);
|
||||
unsigned length = GetWindowTextLength(hwnd);
|
||||
wchar_t text[length + 1];
|
||||
GetWindowText(hwnd, text, length + 1);
|
||||
@@ -57,7 +44,6 @@ LRESULT CALLBACK Label_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa
|
||||
rc.bottom = rc.top + height;
|
||||
DrawText(ps.hdc, text, -1, &rc, DT_LEFT | DT_END_ELLIPSIS);
|
||||
EndPaint(hwnd, &ps);
|
||||
InvalidateRect(hwnd, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
void ListBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void ListBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
widget->window = CreateWindowEx(
|
||||
WS_EX_CLIENTEDGE, WC_LISTVIEW, L"",
|
||||
WS_CHILD | WS_TABSTOP | WS_VISIBLE |
|
||||
@@ -7,7 +7,7 @@ void ListBox::create(Window &parent, unsigned x, unsigned y, unsigned width, uns
|
||||
parent.widget->window, (HMENU)object->id, GetModuleHandle(0), 0
|
||||
);
|
||||
SetWindowLongPtr(widget->window, GWLP_USERDATA, (LONG_PTR)this);
|
||||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : os.os->proportionalFont), 0);
|
||||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : OS::os->proportionalFont), 0);
|
||||
ListView_SetExtendedListViewStyle(widget->window, LVS_EX_FULLROWSELECT);
|
||||
|
||||
lstring list;
|
||||
@@ -34,6 +34,10 @@ void ListBox::setHeaderVisible(bool headerVisible) {
|
||||
);
|
||||
}
|
||||
|
||||
void ListBox::setCheckable(bool checkable) {
|
||||
ListView_SetExtendedListViewStyle(widget->window, LVS_EX_FULLROWSELECT | (checkable ? LVS_EX_CHECKBOXES : 0));
|
||||
}
|
||||
|
||||
void ListBox::reset() {
|
||||
ListView_DeleteAllItems(widget->window);
|
||||
}
|
||||
@@ -44,7 +48,7 @@ void ListBox::resizeColumnsToContent() {
|
||||
}
|
||||
}
|
||||
|
||||
void ListBox::addItem(const char *text) {
|
||||
void ListBox::addItem(const string &text) {
|
||||
lstring list;
|
||||
list.split("\t", text);
|
||||
LVITEM item;
|
||||
@@ -54,20 +58,28 @@ void ListBox::addItem(const char *text) {
|
||||
item.iSubItem = 0;
|
||||
utf16_t wtext(list[0]);
|
||||
item.pszText = wtext;
|
||||
object->locked = true;
|
||||
ListView_InsertItem(widget->window, &item);
|
||||
object->locked = false;
|
||||
for(unsigned i = 1; i < list.size(); i++) {
|
||||
utf16_t wtext(list[i]);
|
||||
ListView_SetItemText(widget->window, row, i, wtext);
|
||||
}
|
||||
|
||||
//workaround: when there is only one column, the horizontal scrollbar will always appear without this
|
||||
if(listBox->columns == 1) ListView_SetColumnWidth(widget->window, 0, LVSCW_AUTOSIZE_USEHEADER);
|
||||
}
|
||||
|
||||
void ListBox::setItem(unsigned row, const char *text) {
|
||||
void ListBox::setItem(unsigned row, const string &text) {
|
||||
lstring list;
|
||||
list.split("\t", text);
|
||||
for(unsigned i = 0; i < list.size(); i++) {
|
||||
utf16_t wtext(list[i]);
|
||||
ListView_SetItemText(widget->window, row, i, wtext);
|
||||
}
|
||||
|
||||
//workaround: when there is only one column, the horizontal scrollbar will always appear without this
|
||||
if(listBox->columns == 1) ListView_SetColumnWidth(widget->window, 0, LVSCW_AUTOSIZE_USEHEADER);
|
||||
}
|
||||
|
||||
optional<unsigned> ListBox::selection() {
|
||||
@@ -86,6 +98,16 @@ void ListBox::setSelection(unsigned row) {
|
||||
}
|
||||
}
|
||||
|
||||
bool ListBox::checked(unsigned row) {
|
||||
return ListView_GetCheckState(widget->window, row);
|
||||
}
|
||||
|
||||
void ListBox::setChecked(unsigned row, bool checked) {
|
||||
object->locked = true;
|
||||
ListView_SetCheckState(widget->window, row, checked);
|
||||
object->locked = false;
|
||||
}
|
||||
|
||||
ListBox::ListBox() {
|
||||
listBox = new ListBox::Data;
|
||||
listBox->lostFocus = false;
|
||||
|
@@ -1,15 +1,15 @@
|
||||
Action::Action() {
|
||||
os.objects.append(this);
|
||||
OS::os->objects.append(this);
|
||||
action = new Action::Data;
|
||||
}
|
||||
|
||||
void Menu::create(Window &parent, const char *text) {
|
||||
void Menu::create(Window &parent, const string &text) {
|
||||
action->parentMenu = parent.window->menu;
|
||||
action->menu = CreatePopupMenu();
|
||||
AppendMenu(parent.window->menu, MF_STRING | MF_POPUP, (UINT_PTR)action->menu, utf16_t(text));
|
||||
}
|
||||
|
||||
void Menu::create(Menu &parent, const char *text) {
|
||||
void Menu::create(Menu &parent, const string &text) {
|
||||
action->parentMenu = parent.action->menu;
|
||||
action->menu = CreatePopupMenu();
|
||||
AppendMenu(parent.action->menu, MF_STRING | MF_POPUP, (UINT_PTR)action->menu, utf16_t(text));
|
||||
@@ -46,7 +46,7 @@ void MenuSeparator::setEnabled(bool enabled) {
|
||||
EnableMenuItem(action->parent->action->menu, object->id, MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_GRAYED));
|
||||
}
|
||||
|
||||
void MenuItem::create(Menu &parent, const char *text) {
|
||||
void MenuItem::create(Menu &parent, const string &text) {
|
||||
action->parent = &parent;
|
||||
AppendMenu(parent.action->menu, MF_STRING, object->id, utf16_t(text));
|
||||
}
|
||||
@@ -64,7 +64,7 @@ void MenuItem::setEnabled(bool enabled) {
|
||||
EnableMenuItem(action->parent->action->menu, object->id, MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_GRAYED));
|
||||
}
|
||||
|
||||
void MenuCheckItem::create(Menu &parent, const char *text) {
|
||||
void MenuCheckItem::create(Menu &parent, const string &text) {
|
||||
action->parent = &parent;
|
||||
AppendMenu(parent.action->menu, MF_STRING, object->id, utf16_t(text));
|
||||
}
|
||||
@@ -95,7 +95,7 @@ void MenuCheckItem::setChecked(bool checked) {
|
||||
CheckMenuItem(action->parent->action->menu, object->id, checked ? MF_CHECKED : MF_UNCHECKED);
|
||||
}
|
||||
|
||||
void MenuRadioItem::create(Menu &parent, const char *text) {
|
||||
void MenuRadioItem::create(Menu &parent, const string &text) {
|
||||
action->parent = &parent;
|
||||
action->radioParent = this;
|
||||
action->items.append(this);
|
||||
@@ -103,7 +103,7 @@ void MenuRadioItem::create(Menu &parent, const char *text) {
|
||||
setChecked();
|
||||
}
|
||||
|
||||
void MenuRadioItem::create(MenuRadioItem &parent, const char *text) {
|
||||
void MenuRadioItem::create(MenuRadioItem &parent, const string &text) {
|
||||
action->parent = parent.action->parent;
|
||||
action->radioParent = parent.action->radioParent;
|
||||
action->radioParent->action->items.append(this);
|
||||
|
@@ -8,7 +8,7 @@ static MessageWindow::Response MessageWindow_response(MessageWindow::Buttons but
|
||||
return MessageWindow::Response::Ok;
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::information(Window &parent, const char *text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response MessageWindow::information(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
UINT flags = MB_ICONINFORMATION;
|
||||
if(buttons == Buttons::Ok) flags |= MB_OK;
|
||||
if(buttons == Buttons::OkCancel) flags |= MB_OKCANCEL;
|
||||
@@ -16,7 +16,7 @@ MessageWindow::Response MessageWindow::information(Window &parent, const char *t
|
||||
return MessageWindow_response(buttons, MessageBox(&parent != &Window::None ? parent.widget->window : 0, utf16_t(text), L"", flags));
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::question(Window &parent, const char *text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response MessageWindow::question(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
UINT flags = MB_ICONQUESTION;
|
||||
if(buttons == Buttons::Ok) flags |= MB_OK;
|
||||
if(buttons == Buttons::OkCancel) flags |= MB_OKCANCEL;
|
||||
@@ -24,7 +24,7 @@ MessageWindow::Response MessageWindow::question(Window &parent, const char *text
|
||||
return MessageWindow_response(buttons, MessageBox(&parent != &Window::None ? parent.widget->window : 0, utf16_t(text), L"", flags));
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::warning(Window &parent, const char *text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response MessageWindow::warning(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
UINT flags = MB_ICONWARNING;
|
||||
if(buttons == Buttons::Ok) flags |= MB_OK;
|
||||
if(buttons == Buttons::OkCancel) flags |= MB_OKCANCEL;
|
||||
@@ -32,7 +32,7 @@ MessageWindow::Response MessageWindow::warning(Window &parent, const char *text,
|
||||
return MessageWindow_response(buttons, MessageBox(&parent != &Window::None ? parent.widget->window : 0, utf16_t(text), L"", flags));
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::critical(Window &parent, const char *text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response MessageWindow::critical(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
UINT flags = MB_ICONERROR;
|
||||
if(buttons == Buttons::Ok) flags |= MB_OK;
|
||||
if(buttons == Buttons::OkCancel) flags |= MB_OKCANCEL;
|
||||
|
@@ -70,6 +70,7 @@ struct VerticalSlider::Data {
|
||||
};
|
||||
|
||||
struct OS::Data {
|
||||
nall::array<Object*> objects;
|
||||
HFONT proportionalFont;
|
||||
HFONT monospaceFont;
|
||||
};
|
||||
@@ -78,6 +79,7 @@ void Object::unused() {
|
||||
}
|
||||
|
||||
Object::Object() {
|
||||
OS::initialize();
|
||||
static unsigned guid = 100;
|
||||
object = new Object::Data;
|
||||
object->id = guid++;
|
||||
|
@@ -9,10 +9,10 @@ void ProgressBar::create(Window &parent, unsigned x, unsigned y, unsigned width,
|
||||
SendMessage(widget->window, PBM_SETSTEP, MAKEWPARAM(1, 0), 0);
|
||||
}
|
||||
|
||||
unsigned ProgressBar::progress() {
|
||||
unsigned ProgressBar::position() {
|
||||
return SendMessage(widget->window, PBM_GETPOS, 0, 0);
|
||||
}
|
||||
|
||||
void ProgressBar::setProgress(unsigned progress) {
|
||||
SendMessage(widget->window, PBM_SETPOS, (WPARAM)progress, 0);
|
||||
void ProgressBar::setPosition(unsigned position) {
|
||||
SendMessage(widget->window, PBM_SETPOS, (WPARAM)position, 0);
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
void RadioBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void RadioBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
radioBox->parentWindow = &parent;
|
||||
radioBox->parent = this;
|
||||
radioBox->parent->radioBox->items.append(this);
|
||||
@@ -9,11 +9,11 @@ void RadioBox::create(Window &parent, unsigned x, unsigned y, unsigned width, un
|
||||
parent.widget->window, (HMENU)object->id, GetModuleHandle(0), 0
|
||||
);
|
||||
SetWindowLongPtr(widget->window, GWLP_USERDATA, (LONG_PTR)this);
|
||||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : os.os->proportionalFont), 0);
|
||||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : OS::os->proportionalFont), 0);
|
||||
setChecked();
|
||||
}
|
||||
|
||||
void RadioBox::create(RadioBox &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void RadioBox::create(RadioBox &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
radioBox->parentWindow = parent.radioBox->parentWindow;
|
||||
radioBox->parent = parent.radioBox->parent;
|
||||
radioBox->parent->radioBox->items.append(this);
|
||||
@@ -24,7 +24,7 @@ void RadioBox::create(RadioBox &parent, unsigned x, unsigned y, unsigned width,
|
||||
GetParent(radioBox->parent->widget->window), (HMENU)object->id, GetModuleHandle(0), 0
|
||||
);
|
||||
SetWindowLongPtr(widget->window, GWLP_USERDATA, (LONG_PTR)this);
|
||||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(radioBox->parentWindow->window->defaultFont ? radioBox->parentWindow->window->defaultFont : os.os->proportionalFont), 0);
|
||||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(radioBox->parentWindow->window->defaultFont ? radioBox->parentWindow->window->defaultFont : OS::os->proportionalFont), 0);
|
||||
}
|
||||
|
||||
bool RadioBox::checked() {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
void TextBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void TextBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
widget->window = CreateWindowEx(
|
||||
WS_EX_CLIENTEDGE, L"EDIT", utf16_t(text),
|
||||
WS_CHILD | WS_TABSTOP | WS_VISIBLE | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
|
||||
@@ -6,7 +6,7 @@ void TextBox::create(Window &parent, unsigned x, unsigned y, unsigned width, uns
|
||||
parent.widget->window, (HMENU)object->id, GetModuleHandle(0), 0
|
||||
);
|
||||
SetWindowLongPtr(widget->window, GWLP_USERDATA, (LONG_PTR)this);
|
||||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : os.os->proportionalFont), 0);
|
||||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : OS::os->proportionalFont), 0);
|
||||
}
|
||||
|
||||
string TextBox::text() {
|
||||
@@ -17,7 +17,7 @@ string TextBox::text() {
|
||||
return utf8_t(text);
|
||||
}
|
||||
|
||||
void TextBox::setText(const char *text) {
|
||||
void TextBox::setText(const string &text) {
|
||||
object->locked = true;
|
||||
SetWindowText(widget->window, utf16_t(text));
|
||||
object->locked = false;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
void Viewport::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height) {
|
||||
widget->window = CreateWindow(
|
||||
L"phoenix_window", L"",
|
||||
L"phoenix_viewport", L"",
|
||||
WS_CHILD | WS_VISIBLE | WS_DISABLED,
|
||||
x, y, width, height,
|
||||
parent.widget->window, (HMENU)object->id, GetModuleHandle(0), 0
|
||||
@@ -11,3 +11,7 @@ void Viewport::create(Window &parent, unsigned x, unsigned y, unsigned width, un
|
||||
uintptr_t Viewport::handle() {
|
||||
return (uintptr_t)widget->window;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK Viewport_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
@@ -28,9 +28,13 @@ void Widget::setFocused() {
|
||||
SetFocus(widget->window);
|
||||
}
|
||||
|
||||
void Widget::setGeometry(unsigned x, unsigned y, unsigned width, unsigned height) {
|
||||
SetWindowPos(widget->window, NULL, x, y, width, height, SWP_NOZORDER);
|
||||
}
|
||||
|
||||
Widget::Widget() {
|
||||
os.objects.append(this);
|
||||
OS::os->objects.append(this);
|
||||
widget = new Widget::Data;
|
||||
widget->window = 0;
|
||||
widget->font = os.os->proportionalFont;
|
||||
widget->font = OS::os->proportionalFont;
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
void Window::create(unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
void Window::create(unsigned x, unsigned y, unsigned width, unsigned height, const string &text) {
|
||||
widget->window = CreateWindowEx(
|
||||
0, L"phoenix_window", utf16_t(text),
|
||||
WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,
|
||||
@@ -26,6 +26,18 @@ void Window::setFont(Font &font) {
|
||||
SendMessage(window->status, WM_SETFONT, (WPARAM)font.font->font, 0);
|
||||
}
|
||||
|
||||
Geometry Window::geometry() {
|
||||
RECT position, size;
|
||||
GetWindowRect(widget->window, &position);
|
||||
GetClientRect(widget->window, &size);
|
||||
if(GetWindowLongPtr(window->status, GWL_STYLE) & WS_VISIBLE) {
|
||||
RECT status;
|
||||
GetClientRect(window->status, &status);
|
||||
size.bottom -= status.bottom - status.top;
|
||||
}
|
||||
return Geometry(position.left, position.top, size.right, size.bottom);
|
||||
}
|
||||
|
||||
void Window::setGeometry(unsigned x, unsigned y, unsigned width, unsigned height) {
|
||||
bool isVisible = visible();
|
||||
if(isVisible) setVisible(false);
|
||||
@@ -40,11 +52,11 @@ void Window::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) {
|
||||
window->brush = CreateSolidBrush(window->brushColor);
|
||||
}
|
||||
|
||||
void Window::setTitle(const char *text) {
|
||||
void Window::setTitle(const string &text) {
|
||||
SetWindowText(widget->window, utf16_t(text));
|
||||
}
|
||||
|
||||
void Window::setStatusText(const char *text) {
|
||||
void Window::setStatusText(const string &text) {
|
||||
SendMessage(window->status, SB_SETTEXT, 0, (LPARAM)(wchar_t*)utf16_t(text));
|
||||
}
|
||||
|
||||
|
@@ -29,14 +29,72 @@ namespace phoenix {
|
||||
#include "viewport.cpp"
|
||||
#include "messagewindow.cpp"
|
||||
|
||||
OS &os = OS::handle();
|
||||
OS::Data *OS::os = 0;
|
||||
Window Window::None;
|
||||
|
||||
static void OS_keyboardProc(HWND, UINT, WPARAM, LPARAM);
|
||||
static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
|
||||
OS& OS::handle() {
|
||||
static OS os;
|
||||
return os;
|
||||
void OS::initialize() {
|
||||
static bool initialized = false;
|
||||
if(initialized == true) return;
|
||||
initialized = true;
|
||||
|
||||
InitCommonControls();
|
||||
CoInitialize(0);
|
||||
|
||||
os = new OS::Data;
|
||||
os->proportionalFont = Font_createFont("Tahoma", 8, false, false);
|
||||
os->monospaceFont = Font_createFont("Courier New", 8, false, false);
|
||||
|
||||
WNDCLASS wc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
|
||||
wc.hCursor = LoadCursor(0, IDC_ARROW);
|
||||
wc.hIcon = LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(2));
|
||||
wc.hInstance = GetModuleHandle(0);
|
||||
wc.lpfnWndProc = OS_windowProc;
|
||||
wc.lpszClassName = L"phoenix_window";
|
||||
wc.lpszMenuName = 0;
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
RegisterClass(&wc);
|
||||
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
|
||||
wc.hCursor = LoadCursor(0, IDC_ARROW);
|
||||
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
|
||||
wc.hInstance = GetModuleHandle(0);
|
||||
wc.lpfnWndProc = Canvas_windowProc;
|
||||
wc.lpszClassName = L"phoenix_canvas";
|
||||
wc.lpszMenuName = 0;
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
RegisterClass(&wc);
|
||||
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
|
||||
wc.hCursor = LoadCursor(0, IDC_ARROW);
|
||||
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
|
||||
wc.hInstance = GetModuleHandle(0);
|
||||
wc.lpfnWndProc = Label_windowProc;
|
||||
wc.lpszClassName = L"phoenix_label";
|
||||
wc.lpszMenuName = 0;
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
RegisterClass(&wc);
|
||||
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
|
||||
wc.hCursor = LoadCursor(0, IDC_ARROW);
|
||||
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
|
||||
wc.hInstance = GetModuleHandle(0);
|
||||
wc.lpfnWndProc = Viewport_windowProc;
|
||||
wc.lpszClassName = L"phoenix_viewport";
|
||||
wc.lpszMenuName = 0;
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
RegisterClass(&wc);
|
||||
}
|
||||
|
||||
bool OS::pending() {
|
||||
@@ -84,7 +142,7 @@ unsigned OS::desktopHeight() {
|
||||
return GetSystemMetrics(SM_CYSCREEN);
|
||||
}
|
||||
|
||||
string OS::folderSelect(Window &parent, const char *path) {
|
||||
string OS::folderSelect(Window &parent, const string &path) {
|
||||
wchar_t wfilename[PATH_MAX + 1] = L"";
|
||||
BROWSEINFO bi;
|
||||
bi.hwndOwner = &parent != &Window::None ? parent.widget->window : 0;
|
||||
@@ -108,10 +166,13 @@ string OS::folderSelect(Window &parent, const char *path) {
|
||||
}
|
||||
}
|
||||
if(result == false) return "";
|
||||
return utf8_t(wfilename);
|
||||
string name = utf8_t(wfilename);
|
||||
name.transform("\\", "/");
|
||||
if(name.endswith("/") == false) name.append("/");
|
||||
return name;
|
||||
}
|
||||
|
||||
string OS::fileOpen(Window &parent, const char *filter, const char *path) {
|
||||
string OS::fileOpen(Window &parent, const string &filter, const string &path) {
|
||||
string dir = path;
|
||||
dir.replace("/", "\\");
|
||||
|
||||
@@ -154,10 +215,12 @@ string OS::fileOpen(Window &parent, const char *filter, const char *path) {
|
||||
|
||||
bool result = GetOpenFileName(&ofn);
|
||||
if(result == false) return "";
|
||||
return utf8_t(wfilename);
|
||||
string name = utf8_t(wfilename);
|
||||
name.transform("\\", "/");
|
||||
return name;
|
||||
}
|
||||
|
||||
string OS::fileSave(Window &parent, const char *filter, const char *path) {
|
||||
string OS::fileSave(Window &parent, const string &filter, const string &path) {
|
||||
string dir = path;
|
||||
dir.replace("/", "\\");
|
||||
|
||||
@@ -200,7 +263,9 @@ string OS::fileSave(Window &parent, const char *filter, const char *path) {
|
||||
|
||||
bool result = GetSaveFileName(&ofn);
|
||||
if(result == false) return "";
|
||||
return utf8_t(wfilename);
|
||||
string name = utf8_t(wfilename);
|
||||
name.transform("\\", "/");
|
||||
return name;
|
||||
}
|
||||
|
||||
static void OS_keyboardProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
@@ -211,11 +276,18 @@ static void OS_keyboardProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
info.cbSize = sizeof(GUITHREADINFO);
|
||||
GetGUIThreadInfo(GetCurrentThreadId(), &info);
|
||||
Object *object_ptr = (Object*)GetWindowLongPtr(info.hwndFocus, GWLP_USERDATA);
|
||||
if(object_ptr && dynamic_cast<ListBox*>(object_ptr)) {
|
||||
if(object_ptr) {
|
||||
if(dynamic_cast<ListBox*>(object_ptr)) {
|
||||
ListBox &listBox = (ListBox&)*object_ptr;
|
||||
if(wparam == VK_RETURN) {
|
||||
if(listBox.onActivate) listBox.onActivate();
|
||||
}
|
||||
} else if(dynamic_cast<TextBox*>(object_ptr)) {
|
||||
TextBox &textBox = (TextBox&)*object_ptr;
|
||||
if(wparam == VK_RETURN) {
|
||||
if(textBox.onActivate) textBox.onActivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -261,7 +333,7 @@ static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
|
||||
unsigned id = LOWORD(wparam);
|
||||
HWND control = GetDlgItem(window.widget->window, id);
|
||||
if(control == 0) {
|
||||
Object *object_ptr = (Object*)os.findObject(id);
|
||||
Object *object_ptr = (Object*)OS::findObject(id);
|
||||
if(object_ptr) {
|
||||
if(dynamic_cast<MenuItem*>(object_ptr)) {
|
||||
MenuItem &menuItem = (MenuItem&)*object_ptr;
|
||||
@@ -327,8 +399,12 @@ static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
|
||||
ListBox &listBox = (ListBox&)*object_ptr;
|
||||
LPNMHDR nmhdr = (LPNMHDR)lparam;
|
||||
LPNMLISTVIEW nmlistview = (LPNMLISTVIEW)lparam;
|
||||
|
||||
if(nmhdr->code == LVN_ITEMCHANGED && (nmlistview->uChanged & LVIF_STATE)) {
|
||||
if((nmlistview->uOldState & LVIS_FOCUSED) && !(nmlistview->uNewState & LVIS_FOCUSED)) {
|
||||
unsigned imagemask = ((nmlistview->uNewState & LVIS_STATEIMAGEMASK) >> 12) - 1;
|
||||
if(imagemask == 0 || imagemask == 1) {
|
||||
if(listBox.object->locked == false && listBox.onTick) listBox.onTick(nmlistview->iItem);
|
||||
} else if((nmlistview->uOldState & LVIS_FOCUSED) && !(nmlistview->uNewState & LVIS_FOCUSED)) {
|
||||
listBox.listBox->lostFocus = true;
|
||||
} else {
|
||||
if(!(nmlistview->uOldState & LVIS_SELECTED) && (nmlistview->uNewState & LVIS_SELECTED)) {
|
||||
@@ -385,54 +461,8 @@ static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
|
||||
}
|
||||
|
||||
Object* OS::findObject(unsigned id) {
|
||||
foreach(object, objects) { if(object->object->id == id) return object; }
|
||||
foreach(object, os->objects) { if(object->object->id == id) return object; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
OS::OS() {
|
||||
InitCommonControls();
|
||||
CoInitialize(0);
|
||||
|
||||
os = new OS::Data;
|
||||
os->proportionalFont = Font_createFont("Tahoma", 8, false, false);
|
||||
os->monospaceFont = Font_createFont("Courier New", 8, false, false);
|
||||
|
||||
WNDCLASS wc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
|
||||
wc.hCursor = LoadCursor(0, IDC_ARROW);
|
||||
wc.hIcon = LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(2));
|
||||
wc.hInstance = GetModuleHandle(0);
|
||||
wc.lpfnWndProc = OS_windowProc;
|
||||
wc.lpszClassName = L"phoenix_window";
|
||||
wc.lpszMenuName = 0;
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
RegisterClass(&wc);
|
||||
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
|
||||
wc.hCursor = LoadCursor(0, IDC_ARROW);
|
||||
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
|
||||
wc.hInstance = GetModuleHandle(0);
|
||||
wc.lpfnWndProc = Canvas_windowProc;
|
||||
wc.lpszClassName = L"phoenix_canvas";
|
||||
wc.lpszMenuName = 0;
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
RegisterClass(&wc);
|
||||
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
|
||||
wc.hCursor = LoadCursor(0, IDC_ARROW);
|
||||
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
|
||||
wc.hInstance = GetModuleHandle(0);
|
||||
wc.lpfnWndProc = Label_windowProc;
|
||||
wc.lpszClassName = L"phoenix_label";
|
||||
wc.lpszMenuName = 0;
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
RegisterClass(&wc);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -4,6 +4,8 @@ struct Window;
|
||||
|
||||
struct Object {
|
||||
Object();
|
||||
Object& operator=(const Object&) = delete;
|
||||
Object(const Object&) = delete;
|
||||
//private:
|
||||
struct Data;
|
||||
Data *object;
|
||||
@@ -11,13 +13,20 @@ private:
|
||||
virtual void unused();
|
||||
};
|
||||
|
||||
struct Geometry {
|
||||
unsigned x, y;
|
||||
unsigned width, height;
|
||||
inline Geometry() : x(0), y(0), width(0), height(0) {}
|
||||
inline Geometry(unsigned x, unsigned y, unsigned width, unsigned height) : x(x), y(y), width(width), height(height) {}
|
||||
};
|
||||
|
||||
struct Font : Object {
|
||||
enum class Style : unsigned {
|
||||
None = 0,
|
||||
Bold = 1,
|
||||
Italic = 2,
|
||||
};
|
||||
bool create(const char *name, unsigned size, Font::Style style = Style::None);
|
||||
bool create(const nall::string &name, unsigned size, Font::Style style = Style::None);
|
||||
Font();
|
||||
~Font();
|
||||
//private:
|
||||
@@ -38,8 +47,8 @@ struct Action : Object {
|
||||
};
|
||||
|
||||
struct Menu : Action {
|
||||
void create(Window &parent, const char *text);
|
||||
void create(Menu &parent, const char *text);
|
||||
void create(Window &parent, const nall::string &text);
|
||||
void create(Menu &parent, const nall::string &text);
|
||||
bool enabled();
|
||||
void setEnabled(bool enabled = true);
|
||||
};
|
||||
@@ -52,14 +61,14 @@ struct MenuSeparator : Action {
|
||||
|
||||
struct MenuItem : Action {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Menu &parent, const char *text);
|
||||
void create(Menu &parent, const nall::string &text);
|
||||
bool enabled();
|
||||
void setEnabled(bool enabled = true);
|
||||
};
|
||||
|
||||
struct MenuCheckItem : Action {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Menu &parent, const char *text);
|
||||
void create(Menu &parent, const nall::string &text);
|
||||
bool enabled();
|
||||
void setEnabled(bool enabled = true);
|
||||
bool checked();
|
||||
@@ -68,8 +77,8 @@ struct MenuCheckItem : Action {
|
||||
|
||||
struct MenuRadioItem : Action {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Menu &parent, const char *text);
|
||||
void create(MenuRadioItem &parent, const char *text);
|
||||
void create(Menu &parent, const nall::string &text);
|
||||
void create(MenuRadioItem &parent, const nall::string &text);
|
||||
bool enabled();
|
||||
void setEnabled(bool enabled = true);
|
||||
bool checked();
|
||||
@@ -84,6 +93,7 @@ struct Widget : Object {
|
||||
void setEnabled(bool enabled = true);
|
||||
bool focused();
|
||||
void setFocused();
|
||||
virtual void setGeometry(unsigned x, unsigned y, unsigned width, unsigned height);
|
||||
Widget();
|
||||
//private:
|
||||
struct Data;
|
||||
@@ -91,28 +101,28 @@ struct Widget : Object {
|
||||
};
|
||||
|
||||
struct Window : Widget {
|
||||
static Window None;
|
||||
nall::function<bool ()> onClose;
|
||||
void create(unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
void setDefaultFont(Font &font);
|
||||
void setFont(Font &font);
|
||||
Geometry geometry();
|
||||
void setGeometry(unsigned x, unsigned y, unsigned width, unsigned height);
|
||||
void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue);
|
||||
void setTitle(const char *text);
|
||||
void setStatusText(const char *text);
|
||||
void setTitle(const nall::string &text);
|
||||
void setStatusText(const nall::string &text);
|
||||
void setMenuVisible(bool visible = true);
|
||||
void setStatusVisible(bool visible = true);
|
||||
Window();
|
||||
//private:
|
||||
struct Data;
|
||||
Data *window;
|
||||
//private:
|
||||
static Window None;
|
||||
void resize(unsigned width, unsigned height);
|
||||
};
|
||||
|
||||
struct Button : Widget {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
};
|
||||
|
||||
struct Canvas : Widget {
|
||||
@@ -128,16 +138,16 @@ struct Canvas : Widget {
|
||||
|
||||
struct CheckBox : Widget {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
bool checked();
|
||||
void setChecked(bool checked = true);
|
||||
};
|
||||
|
||||
struct ComboBox : Widget {
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
void reset();
|
||||
void addItem(const char *text);
|
||||
void addItem(const nall::string &text);
|
||||
unsigned selection();
|
||||
void setSelection(unsigned item);
|
||||
ComboBox();
|
||||
@@ -148,9 +158,9 @@ struct ComboBox : Widget {
|
||||
|
||||
struct EditBox : Widget {
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
nall::string getText();
|
||||
void setText(const char *text);
|
||||
void setText(const nall::string &text);
|
||||
void setEditable(bool editable = true);
|
||||
void setWordWrap(bool wordWrap = true);
|
||||
EditBox();
|
||||
@@ -171,19 +181,23 @@ struct HorizontalSlider : Widget {
|
||||
};
|
||||
|
||||
struct Label : Widget {
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void setText(const char *text);
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
void setText(const nall::string &text);
|
||||
};
|
||||
|
||||
struct ListBox : Widget {
|
||||
nall::function<void ()> onActivate;
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
nall::function<void (unsigned)> onTick;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
void setHeaderVisible(bool headerVisible = true);
|
||||
void setCheckable(bool checkable = true);
|
||||
void reset();
|
||||
void resizeColumnsToContent();
|
||||
void addItem(const char *text);
|
||||
void setItem(unsigned row, const char *text);
|
||||
void addItem(const nall::string &text);
|
||||
void setItem(unsigned row, const nall::string &text);
|
||||
bool checked(unsigned row);
|
||||
void setChecked(unsigned row, bool checked = true);
|
||||
nall::optional<unsigned> selection();
|
||||
void setSelection(unsigned row);
|
||||
ListBox();
|
||||
@@ -194,14 +208,14 @@ struct ListBox : Widget {
|
||||
|
||||
struct ProgressBar : Widget {
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height);
|
||||
unsigned progress();
|
||||
void setProgress(unsigned progress);
|
||||
unsigned position();
|
||||
void setPosition(unsigned position);
|
||||
};
|
||||
|
||||
struct RadioBox : Widget {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(RadioBox &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
void create(RadioBox &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
bool checked();
|
||||
void setChecked();
|
||||
RadioBox();
|
||||
@@ -211,10 +225,11 @@ struct RadioBox : Widget {
|
||||
};
|
||||
|
||||
struct TextBox : Widget {
|
||||
nall::function<void ()> onActivate;
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const nall::string &text = "");
|
||||
nall::string text();
|
||||
void setText(const char *text);
|
||||
void setText(const nall::string &text);
|
||||
void setEditable(bool editable = true);
|
||||
};
|
||||
|
||||
@@ -246,33 +261,28 @@ struct MessageWindow : Object {
|
||||
Yes,
|
||||
No,
|
||||
};
|
||||
static Response information(Window &parent, const char *text, Buttons = Buttons::Ok);
|
||||
static Response question(Window &parent, const char *text, Buttons = Buttons::YesNo);
|
||||
static Response warning(Window &parent, const char *text, Buttons = Buttons::Ok);
|
||||
static Response critical(Window &parent, const char *text, Buttons = Buttons::Ok);
|
||||
static Response information(Window &parent, const nall::string &text, Buttons = Buttons::Ok);
|
||||
static Response question(Window &parent, const nall::string &text, Buttons = Buttons::YesNo);
|
||||
static Response warning(Window &parent, const nall::string &text, Buttons = Buttons::Ok);
|
||||
static Response critical(Window &parent, const nall::string &text, Buttons = Buttons::Ok);
|
||||
};
|
||||
|
||||
struct OS : Object {
|
||||
bool pending();
|
||||
void run();
|
||||
void main();
|
||||
void quit();
|
||||
unsigned desktopWidth();
|
||||
unsigned desktopHeight();
|
||||
nall::string folderSelect(Window &parent, const char *path = "");
|
||||
nall::string fileOpen(Window &parent, const char *filter, const char *path = "");
|
||||
nall::string fileSave(Window &parent, const char *filter, const char *path = "");
|
||||
static bool pending();
|
||||
static void run();
|
||||
static void main();
|
||||
static void quit();
|
||||
static unsigned desktopWidth();
|
||||
static unsigned desktopHeight();
|
||||
static nall::string folderSelect(Window &parent, const nall::string &path = "");
|
||||
static nall::string fileOpen(Window &parent, const nall::string &filter, const nall::string &path = "");
|
||||
static nall::string fileSave(Window &parent, const nall::string &filter, const nall::string &path = "");
|
||||
//private:
|
||||
static OS& handle();
|
||||
static void initialize();
|
||||
struct Data;
|
||||
Data *os;
|
||||
Object* findObject(unsigned id);
|
||||
nall::array<Object*> objects;
|
||||
private:
|
||||
OS();
|
||||
static Data *os;
|
||||
static Object* findObject(unsigned id);
|
||||
friend class Object;
|
||||
};
|
||||
|
||||
extern OS &os;
|
||||
|
||||
};
|
||||
|
@@ -277,8 +277,8 @@ public:
|
||||
//this is used to sort device IDs
|
||||
struct DevicePool {
|
||||
HANDLE handle;
|
||||
char name[4096];
|
||||
bool operator<(const DevicePool &pool) const { return strcmp(name, pool.name) < 0; }
|
||||
wchar_t name[4096];
|
||||
bool operator<(const DevicePool &pool) const { return wcscmp(name, pool.name) < 0; }
|
||||
};
|
||||
|
||||
int main() {
|
||||
@@ -342,8 +342,12 @@ public:
|
||||
|
||||
//per MSDN: XInput devices have "IG_" in their device strings,
|
||||
//which is how they should be identified.
|
||||
const char *p = strstr(pool[i].name, "IG_");
|
||||
lgamepad[n].isXInputDevice = (bool)p;
|
||||
string p = utf8_t(pool[i].name);
|
||||
if(auto position = strpos(p, "IG_")) {
|
||||
lgamepad[n].isXInputDevice = true;
|
||||
} else {
|
||||
lgamepad[n].isXInputDevice = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -693,7 +697,9 @@ public:
|
||||
//=========
|
||||
for(unsigned i = 0; i < min(rawinput.lkeyboard.size(), (unsigned)Keyboard::Count); i++) {
|
||||
for(unsigned n = 0; n < nall::Keyboard::Size; n++) {
|
||||
table[keyboard(i).key(n)] = rawinput.lkeyboard[i].state[n];
|
||||
//using keyboard(0)|= instead of keyboard(i)= merges all keyboards to KB0
|
||||
//this is done to favor ease of mapping over flexibility (eg share laptop+USB keyboard mapping)
|
||||
table[keyboard(0).key(n)] |= rawinput.lkeyboard[i].state[n];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -723,15 +729,17 @@ public:
|
||||
for(unsigned i = 0; i < xinput.lgamepad.size(); i++) {
|
||||
if(joy >= Joypad::Count) break;
|
||||
|
||||
table[joypad(i).hat(0)] = xinput.lgamepad[i].hat;
|
||||
table[joypad(joy).hat(0)] = xinput.lgamepad[i].hat;
|
||||
|
||||
for(unsigned axis = 0; axis < min(6U, (unsigned)Joypad::Axes); axis++) {
|
||||
table[joypad(i).axis(axis)] = xinput.lgamepad[i].axis[axis];
|
||||
table[joypad(joy).axis(axis)] = xinput.lgamepad[i].axis[axis];
|
||||
}
|
||||
|
||||
for(unsigned button = 0; button < min(10U, (unsigned)Joypad::Buttons); button++) {
|
||||
table[joypad(i).button(button)] = xinput.lgamepad[i].button[button];
|
||||
table[joypad(joy).button(button)] = xinput.lgamepad[i].button[button];
|
||||
}
|
||||
|
||||
joy++;
|
||||
}
|
||||
|
||||
//=======================
|
||||
@@ -742,16 +750,18 @@ public:
|
||||
if(joy >= Joypad::Count) break;
|
||||
|
||||
for(unsigned hat = 0; hat < min(4U, (unsigned)Joypad::Hats); hat++) {
|
||||
table[joypad(i).hat(hat)] = dinput.lgamepad[i].hat[hat];
|
||||
table[joypad(joy).hat(hat)] = dinput.lgamepad[i].hat[hat];
|
||||
}
|
||||
|
||||
for(unsigned axis = 0; axis < min(6U, (unsigned)Joypad::Axes); axis++) {
|
||||
table[joypad(i).axis(axis)] = dinput.lgamepad[i].axis[axis];
|
||||
table[joypad(joy).axis(axis)] = dinput.lgamepad[i].axis[axis];
|
||||
}
|
||||
|
||||
for(unsigned button = 0; button < min(128U, (unsigned)Joypad::Buttons); button++) {
|
||||
table[joypad(i).button(button)] = dinput.lgamepad[i].button[button];
|
||||
table[joypad(joy).button(button)] = dinput.lgamepad[i].button[button];
|
||||
}
|
||||
|
||||
joy++;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@@ -14,6 +14,7 @@ InputInterface input;
|
||||
const char *Video::Handle = "Handle";
|
||||
const char *Video::Synchronize = "Synchronize";
|
||||
const char *Video::Filter = "Filter";
|
||||
const char *Video::Shader = "Shader";
|
||||
const char *Video::FragmentShader = "FragmentShader";
|
||||
const char *Video::VertexShader = "VertexShader";
|
||||
|
||||
|
@@ -3,6 +3,7 @@ public:
|
||||
static const char *Handle;
|
||||
static const char *Synchronize;
|
||||
static const char *Filter;
|
||||
static const char *Shader;
|
||||
static const char *FragmentShader;
|
||||
static const char *VertexShader;
|
||||
|
||||
|
@@ -24,7 +24,7 @@ public:
|
||||
LPDIRECT3DTEXTURE9 texture;
|
||||
LPDIRECT3DSURFACE9 surface;
|
||||
LPD3DXEFFECT effect;
|
||||
string shaderSource;
|
||||
string shader_source_xml;
|
||||
|
||||
bool lost;
|
||||
unsigned iwidth, iheight;
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
if(name == Video::Handle) return true;
|
||||
if(name == Video::Synchronize) return true;
|
||||
if(name == Video::Filter) return true;
|
||||
if(name == Video::FragmentShader) return true;
|
||||
if(name == Video::Shader) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -92,8 +92,8 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
if(name == Video::FragmentShader) {
|
||||
set_fragment_shader(any_cast<const char*>(value));
|
||||
if(name == Video::Shader) {
|
||||
set_shader(any_cast<const char*>(value));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ public:
|
||||
//failure to do so causes scaling issues on some video drivers.
|
||||
if(state.width != rd.right || state.height != rd.bottom) {
|
||||
init();
|
||||
set_fragment_shader(shaderSource);
|
||||
set_shader(shader_source_xml);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -327,7 +327,7 @@ public:
|
||||
if(device->Present(0, 0, 0, 0) == D3DERR_DEVICELOST) lost = true;
|
||||
}
|
||||
|
||||
void set_fragment_shader(const char *source) {
|
||||
void set_shader(const char *source) {
|
||||
if(!caps.shader) return;
|
||||
|
||||
if(effect) {
|
||||
@@ -336,11 +336,27 @@ public:
|
||||
}
|
||||
|
||||
if(!source || !*source) {
|
||||
shaderSource = "";
|
||||
shader_source_xml = "";
|
||||
return;
|
||||
}
|
||||
shader_source_xml = source;
|
||||
|
||||
shaderSource = source;
|
||||
bool is_hlsl = false;
|
||||
string shader_source;
|
||||
xml_element document = xml_parse(shader_source_xml);
|
||||
foreach(head, document.element) {
|
||||
if(head.name == "shader") {
|
||||
foreach(attribute, head.attribute) {
|
||||
if(attribute.name == "language" && attribute.content == "HLSL") is_hlsl = true;
|
||||
}
|
||||
foreach(element, head.element) {
|
||||
if(element.name == "source") {
|
||||
if(is_hlsl) shader_source = element.parse();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(shader_source == "") return;
|
||||
|
||||
HMODULE d3dx;
|
||||
for(unsigned i = 0; i < 256; i++) {
|
||||
@@ -349,14 +365,14 @@ public:
|
||||
d3dx = LoadLibraryW(utf16_t(t));
|
||||
if(d3dx) break;
|
||||
}
|
||||
if(!d3dx) d3dx = LoadLibrary(L"d3dx9.dll");
|
||||
if(!d3dx) d3dx = LoadLibraryW(L"d3dx9.dll");
|
||||
if(!d3dx) return;
|
||||
|
||||
EffectProc effectProc = (EffectProc)GetProcAddress(d3dx, "D3DXCreateEffect");
|
||||
TextureProc textureProc = (TextureProc)GetProcAddress(d3dx, "D3DXCreateTextureFromFileA");
|
||||
|
||||
LPD3DXBUFFER pBufferErrors = NULL;
|
||||
effectProc(device, utf16_t(shaderSource), lstrlen(utf16_t(source)), NULL, NULL, 0, NULL, &effect, &pBufferErrors);
|
||||
effectProc(device, shader_source, lstrlenA(shader_source), NULL, NULL, 0, NULL, &effect, &pBufferErrors);
|
||||
|
||||
D3DXHANDLE hTech;
|
||||
effect->FindNextValidTechnique(NULL, &hTech);
|
||||
|
@@ -2,7 +2,7 @@
|
||||
video.glx
|
||||
author: byuu
|
||||
license: public domain
|
||||
last updated: 2010-01-05
|
||||
last updated: 2010-09-28
|
||||
|
||||
Design notes:
|
||||
SGI's GLX is the X11/Xlib interface to OpenGL.
|
||||
@@ -62,6 +62,7 @@ public:
|
||||
if(name == Video::Handle) return true;
|
||||
if(name == Video::Synchronize) return true;
|
||||
if(name == Video::Filter) return true;
|
||||
if(name == Video::Shader) return true;
|
||||
if(name == Video::FragmentShader) return true;
|
||||
if(name == Video::VertexShader) return true;
|
||||
return false;
|
||||
@@ -93,6 +94,11 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
if(name == Video::Shader) {
|
||||
OpenGL::set_shader(any_cast<const char*>(value));
|
||||
return true;
|
||||
}
|
||||
|
||||
if(name == Video::FragmentShader) {
|
||||
OpenGL::set_fragment_shader(any_cast<const char*>(value));
|
||||
return true;
|
||||
|
@@ -122,7 +122,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void set_fragment_shader(const char *source) {
|
||||
void set_shader(const char *source) {
|
||||
if(!shader_support) return;
|
||||
|
||||
if(fragmentshader) {
|
||||
@@ -131,19 +131,6 @@ public:
|
||||
fragmentshader = 0;
|
||||
}
|
||||
|
||||
if(source) {
|
||||
fragmentshader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragmentshader, 1, &source, 0);
|
||||
glCompileShader(fragmentshader);
|
||||
glAttachShader(glprogram, fragmentshader);
|
||||
}
|
||||
|
||||
glLinkProgram(glprogram);
|
||||
}
|
||||
|
||||
void set_vertex_shader(const char *source) {
|
||||
if(!shader_support) return;
|
||||
|
||||
if(vertexshader) {
|
||||
glDetachShader(glprogram, vertexshader);
|
||||
glDeleteShader(vertexshader);
|
||||
@@ -151,15 +138,49 @@ public:
|
||||
}
|
||||
|
||||
if(source) {
|
||||
bool is_glsl = false;
|
||||
string fragment_source;
|
||||
string vertex_source;
|
||||
|
||||
xml_element document = xml_parse(source);
|
||||
foreach(head, document.element) {
|
||||
if(head.name == "shader") {
|
||||
foreach(attribute, head.attribute) {
|
||||
if(attribute.name == "language" && attribute.content == "GLSL") is_glsl = true;
|
||||
}
|
||||
foreach(element, head.element) {
|
||||
if(element.name == "fragment") {
|
||||
fragment_source = element.parse();
|
||||
} else if(element.name == "vertex") {
|
||||
vertex_source = element.parse();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(is_glsl) {
|
||||
if(fragment_source != "") set_fragment_shader(fragment_source);
|
||||
if(vertex_source != "") set_vertex_shader(vertex_source);
|
||||
}
|
||||
}
|
||||
|
||||
glLinkProgram(glprogram);
|
||||
}
|
||||
|
||||
void set_fragment_shader(const char *source) {
|
||||
fragmentshader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragmentshader, 1, &source, 0);
|
||||
glCompileShader(fragmentshader);
|
||||
glAttachShader(glprogram, fragmentshader);
|
||||
}
|
||||
|
||||
void set_vertex_shader(const char *source) {
|
||||
vertexshader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertexshader, 1, &source, 0);
|
||||
glCompileShader(vertexshader);
|
||||
glAttachShader(glprogram, vertexshader);
|
||||
}
|
||||
|
||||
glLinkProgram(glprogram);
|
||||
}
|
||||
|
||||
void init() {
|
||||
//disable unused features
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
|
@@ -29,8 +29,7 @@ public:
|
||||
if(name == Video::Handle) return true;
|
||||
if(name == Video::Synchronize) return true;
|
||||
if(name == Video::Filter) return true;
|
||||
if(name == Video::FragmentShader) return true;
|
||||
if(name == Video::VertexShader) return true;
|
||||
if(name == Video::Shader) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -59,13 +58,8 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
if(name == Video::FragmentShader) {
|
||||
OpenGL::set_fragment_shader(any_cast<const char*>(value));
|
||||
return true;
|
||||
}
|
||||
|
||||
if(name == Video::VertexShader) {
|
||||
OpenGL::set_vertex_shader(any_cast<const char*>(value));
|
||||
if(name == Video::Shader) {
|
||||
OpenGL::set_shader(any_cast<const char*>(value));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -5,7 +5,7 @@ uint8 CPU::pio() {
|
||||
}
|
||||
|
||||
bool CPU::joylatch() {
|
||||
return 0;
|
||||
return status.joypad_strobe_latch;
|
||||
}
|
||||
|
||||
bool CPU::interrupt_pending() {
|
||||
|
@@ -75,7 +75,7 @@ void PPU::render_line_mode7(uint8 pri0_pos, uint8 pri1_pos) {
|
||||
palette = memory::vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];
|
||||
} break;
|
||||
case 2: { //palette color 0 outside of screen area
|
||||
if(px < 0 || px > 1023 || py < 0 || py > 1023) {
|
||||
if((px | py) & ~1023) {
|
||||
palette = 0;
|
||||
} else {
|
||||
px &= 1023;
|
||||
@@ -87,7 +87,7 @@ void PPU::render_line_mode7(uint8 pri0_pos, uint8 pri1_pos) {
|
||||
}
|
||||
} break;
|
||||
case 3: { //character 0 repetition outside of screen area
|
||||
if(px < 0 || px > 1023 || py < 0 || py > 1023) {
|
||||
if((px | py) & ~1023) {
|
||||
tile = 0;
|
||||
} else {
|
||||
px &= 1023;
|
||||
|
@@ -43,10 +43,10 @@ void PPU::Background::offset_per_tile(unsigned x, unsigned y, unsigned &hoffset,
|
||||
void PPU::Background::scanline() {
|
||||
if(self.vcounter() == 1) {
|
||||
mosaic_vcounter = regs.mosaic + 1;
|
||||
y = 1;
|
||||
mosaic_voffset = 1;
|
||||
} else if(--mosaic_vcounter == 0) {
|
||||
mosaic_vcounter = regs.mosaic + 1;
|
||||
y += regs.mosaic + 1;
|
||||
mosaic_voffset += regs.mosaic + 1;
|
||||
}
|
||||
if(self.regs.display_disable) return;
|
||||
|
||||
@@ -93,7 +93,7 @@ void PPU::Background::render() {
|
||||
hscroll = regs.hoffset;
|
||||
vscroll = regs.voffset;
|
||||
|
||||
unsigned y = Background::y;
|
||||
unsigned y = (regs.mosaic == 0 ? self.vcounter() : mosaic_voffset);
|
||||
if(hires) {
|
||||
hscroll <<= 1;
|
||||
if(self.regs.interlace) y = (y << 1) + self.field();
|
||||
|
@@ -31,7 +31,6 @@ class Background {
|
||||
const unsigned id;
|
||||
unsigned opt_valid_bit;
|
||||
|
||||
unsigned y;
|
||||
bool hires;
|
||||
signed width;
|
||||
|
||||
@@ -48,6 +47,7 @@ class Background {
|
||||
unsigned vscroll;
|
||||
|
||||
unsigned mosaic_vcounter;
|
||||
unsigned mosaic_voffset;
|
||||
|
||||
LayerWindow window;
|
||||
|
||||
|
@@ -49,7 +49,7 @@ void PPU::Background::render_mode7() {
|
||||
}
|
||||
|
||||
case 2: {
|
||||
if(px < 0 || px > 1023 || py < 0 || py > 1023) {
|
||||
if((px | py) & ~1023) {
|
||||
palette = 0;
|
||||
} else {
|
||||
px &= 1023;
|
||||
@@ -63,7 +63,7 @@ void PPU::Background::render_mode7() {
|
||||
}
|
||||
|
||||
case 3: {
|
||||
if(px < 0 || px > 1023 || py < 0 || py > 1023) {
|
||||
if((px | py) & ~1023) {
|
||||
tile = 0;
|
||||
} else {
|
||||
px &= 1023;
|
||||
|
@@ -283,7 +283,7 @@ void PPU::mmio_write(unsigned addr, uint8 data) {
|
||||
|
||||
switch(addr & 0xffff) {
|
||||
case 0x2100: { //INIDISP
|
||||
if(regs.display_disable && vcounter() == display.height) oam.address_reset();
|
||||
if(regs.display_disable && cpu.vcounter() == display.height) oam.address_reset();
|
||||
regs.display_disable = data & 0x80;
|
||||
regs.display_brightness = data & 0x0f;
|
||||
return;
|
||||
|
@@ -115,7 +115,6 @@ void PPU::Background::serialize(serializer &s) {
|
||||
s.integer(regs.main_enable);
|
||||
s.integer(regs.sub_enable);
|
||||
|
||||
s.integer(y);
|
||||
s.integer(hires);
|
||||
s.integer(width);
|
||||
|
||||
@@ -132,6 +131,7 @@ void PPU::Background::serialize(serializer &s) {
|
||||
s.integer(vscroll);
|
||||
|
||||
s.integer(mosaic_vcounter);
|
||||
s.integer(mosaic_voffset);
|
||||
|
||||
window.serialize(s);
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user