Update to v092r03 release.

byuu says:

This release adds the phoenix/Cocoa port, and rewrites a lot of the
higan user interface to work with all of the new changes (like blocking
in the main run loop and in modal windows.)

It doesn't yet modify the compilation flags to actually build on OS
X yet, and even then, we don't really have ruby drivers, so there'd be
no video, audio or input.

Two months between a single WIP point release ... for the first six
years, I never went more than a month without a full official release.
I guess I should be happy that it's become so refined, but I sure do
miss those halcyon days of exciting progress.
This commit is contained in:
Tim Allen 2013-03-16 00:11:33 +11:00
parent d9400084c2
commit b7c212de7e
342 changed files with 7651 additions and 3659 deletions

View File

@ -3,7 +3,7 @@
namespace Emulator {
static const char Name[] = "higan";
static const char Version[] = "092.02";
static const char Version[] = "092.03";
static const char Author[] = "byuu";
static const char License[] = "GPLv3";
}

View File

@ -38,7 +38,7 @@ ifeq ($(compiler),)
ifeq ($(platform),win)
compiler := g++
else ifeq ($(platform),osx)
compiler := g++-mp-4.7
compiler := clang
else
compiler := g++-4.7
endif

View File

@ -97,7 +97,7 @@ bool bpsdelta::create(const string &filename, const string &metadata) {
for(unsigned n = 0; n < markupSize; n++) write(metadata[n]);
Node *sourceTree[65536], *targetTree[65536];
for(unsigned n = 0; n < 65536; n++) sourceTree[n] = 0, targetTree[n] = 0;
for(unsigned n = 0; n < 65536; n++) sourceTree[n] = nullptr, targetTree[n] = nullptr;
//source tree creation
for(unsigned offset = 0; offset < sourceSize; offset++) {

View File

@ -27,10 +27,10 @@ struct compositor {
bool compositor::enabled_metacity() {
FILE *fp = popen("gconftool-2 --get /apps/metacity/general/compositing_manager", "r");
if(fp == 0) return false;
if(!fp) return false;
char buffer[512];
if(fgets(buffer, sizeof buffer, fp) == 0) return false;
if(!fgets(buffer, sizeof buffer, fp)) return false;
if(!memcmp(buffer, "true", 4)) return true;
return false;
@ -43,7 +43,7 @@ bool compositor::enable_metacity(bool status) {
} else {
fp = popen("gconftool-2 --set --type bool /apps/metacity/general/compositing_manager false", "r");
}
if(fp == 0) return false;
if(!fp) return false;
pclose(fp);
return true;
}
@ -52,10 +52,10 @@ bool compositor::enable_metacity(bool status) {
bool compositor::enabled_xfwm4() {
FILE *fp = popen("xfconf-query -c xfwm4 -p '/general/use_compositing'", "r");
if(fp == 0) return false;
if(!fp) return false;
char buffer[512];
if(fgets(buffer, sizeof buffer, fp) == 0) return false;
if(!fgets(buffer, sizeof buffer, fp)) return false;
if(!memcmp(buffer, "true", 4)) return true;
return false;
@ -68,7 +68,7 @@ bool compositor::enable_xfwm4(bool status) {
} else {
fp = popen("xfconf-query -c xfwm4 -p '/general/use_compositing' -t 'bool' -s 'false'", "r");
}
if(fp == 0) return false;
if(!fp) return false;
pclose(fp);
return true;
}
@ -112,11 +112,11 @@ bool compositor::enable(bool status) {
bool compositor::enabled() {
HMODULE module = GetModuleHandleW(L"dwmapi");
if(module == 0) module = LoadLibraryW(L"dwmapi");
if(module == 0) return false;
if(module == nullptr) module = LoadLibraryW(L"dwmapi");
if(module == nullptr) return false;
auto pDwmIsCompositionEnabled = (HRESULT (WINAPI*)(BOOL*))GetProcAddress(module, "DwmIsCompositionEnabled");
if(pDwmIsCompositionEnabled == 0) return false;
if(pDwmIsCompositionEnabled == nullptr) return false;
BOOL result;
if(pDwmIsCompositionEnabled(&result) != S_OK) return false;
@ -125,11 +125,11 @@ bool compositor::enabled() {
bool compositor::enable(bool status) {
HMODULE module = GetModuleHandleW(L"dwmapi");
if(module == 0) module = LoadLibraryW(L"dwmapi");
if(module == 0) return false;
if(module == nullptr) module = LoadLibraryW(L"dwmapi");
if(module == nullptr) return false;
auto pDwmEnableComposition = (HRESULT (WINAPI*)(UINT))GetProcAddress(module, "DwmEnableComposition");
if(pDwmEnableComposition == 0) return false;
if(pDwmEnableComposition == nullptr) return false;
if(pDwmEnableComposition(status) != S_OK) return false;
return true;

View File

@ -17,7 +17,8 @@
namespace nall {
struct library {
bool opened() const { return handle; }
explicit operator bool() const { return open(); }
bool open() const { return handle; }
bool open(const char*, const char* = "");
bool open_absolute(const char*);
void* sym(const char*);
@ -48,7 +49,7 @@ namespace nall {
}
inline void* library::sym(const char *name) {
if(!handle) return 0;
if(!handle) return nullptr;
return dlsym((void*)handle, name);
}
@ -72,7 +73,7 @@ namespace nall {
}
inline void* library::sym(const char *name) {
if(!handle) return 0;
if(!handle) return nullptr;
return dlsym((void*)handle, name);
}
@ -96,7 +97,7 @@ namespace nall {
}
inline void* library::sym(const char *name) {
if(!handle) return 0;
if(!handle) return nullptr;
return (void*)GetProcAddress((HMODULE)handle, name);
}
@ -107,7 +108,8 @@ namespace nall {
}
#else
inline bool library::open(const char*, const char*) { return false; }
inline void* library::sym(const char*) { return 0; }
inline bool library::open_absolute(const char*) { return false; }
inline void* library::sym(const char*) { return nullptr; }
inline void library::close() {}
#endif
};

View File

@ -1,16 +1,18 @@
#ifdef NALL_DSP_INTERNAL_HPP
struct Buffer {
double **sample;
uint16_t rdoffset;
uint16_t wroffset;
unsigned channels;
double **sample = nullptr;
uint16_t rdoffset = 0;
uint16_t wroffset = 0;
unsigned channels = 0;
void setChannels(unsigned channels) {
if(sample) {
for(unsigned c = 0; c < this->channels; c++) {
if(sample[c]) delete[] sample[c];
}
if(sample) delete[] sample;
delete[] sample;
}
this->channels = channels;
if(channels == 0) return;
@ -40,7 +42,6 @@ struct Buffer {
}
Buffer() {
channels = 0;
}
~Buffer() {

View File

@ -69,7 +69,7 @@ protected:
real intensityInverse;
} settings;
Resampler *resampler;
Resampler *resampler = nullptr;
inline void write(real channel[]);
#include "buffer.hpp"

View File

@ -584,7 +584,7 @@ void ResampleUtility::normalize(double* io, int size, double gain)
void* ResampleUtility::make_aligned(void* ptr, unsigned boundary)
{
unsigned char* null_ptr = (unsigned char *)NULL;
unsigned char* null_ptr = (unsigned char *)nullptr;
unsigned char* uc_ptr = (unsigned char *)ptr;
uc_ptr += (boundary - ((uc_ptr - null_ptr) & (boundary - 1))) & (boundary - 1);

View File

@ -39,7 +39,7 @@ void ResampleSinc::sample() {
}
ResampleSinc::ResampleSinc(DSP &dsp) : Resampler(dsp) {
for(unsigned n = 0; n < 8; n++) sinc_resampler[n] = 0;
for(unsigned n = 0; n < 8; n++) sinc_resampler[n] = nullptr;
}
void ResampleSinc::remakeSinc() {

View File

@ -264,6 +264,10 @@ namespace nall {
return fp;
}
explicit operator bool() const {
return open();
}
bool open(const string &filename, mode mode_) {
if(fp) return false;
@ -293,17 +297,14 @@ namespace nall {
if(!fp) return;
buffer_flush();
fclose(fp);
fp = 0;
fp = nullptr;
}
file() {
memset(buffer, 0, sizeof buffer);
buffer_offset = -1; //invalidate buffer
buffer_dirty = false;
fp = 0;
file_offset = 0;
file_size = 0;
file_mode = mode::read;
}
file(const string &filename, mode mode_) {
open(filename, mode_);
}
~file() {
@ -315,13 +316,13 @@ namespace nall {
private:
enum { buffer_size = 1 << 12, buffer_mask = buffer_size - 1 };
char buffer[buffer_size];
int buffer_offset;
bool buffer_dirty;
FILE *fp;
unsigned file_offset;
unsigned file_size;
mode file_mode;
char buffer[buffer_size] = {0};
int buffer_offset = -1; //invalidate buffer
bool buffer_dirty = false;
FILE *fp = nullptr;
unsigned file_offset = 0;
unsigned file_size = 0;
mode file_mode = mode::read;
void buffer_sync() {
if(!fp) return; //file not open

View File

@ -22,14 +22,15 @@ namespace nall {
public:
enum class mode : unsigned { read, write, readwrite, writeread };
explicit operator bool() const { return open(); }
bool open() const { return p_open(); }
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* 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_size(0), p_handle(nullptr) { p_ctor(); }
filemap(const char *filename, mode mode_) : p_size(0), p_handle(nullptr) { p_ctor(); p_open(filename, mode_); }
~filemap() { p_dtor(); }
private:
@ -49,7 +50,7 @@ namespace nall {
bool p_open(const char *filename, mode mode_) {
if(file::exists(filename) && file::size(filename) == 0) {
p_handle = 0;
p_handle = nullptr;
p_size = 0;
return true;
}
@ -85,13 +86,13 @@ namespace nall {
break;
}
p_filehandle = CreateFileW(utf16_t(filename), desired_access, FILE_SHARE_READ, NULL,
creation_disposition, FILE_ATTRIBUTE_NORMAL, NULL);
p_filehandle = CreateFileW(utf16_t(filename), desired_access, FILE_SHARE_READ, nullptr,
creation_disposition, FILE_ATTRIBUTE_NORMAL, nullptr);
if(p_filehandle == INVALID_HANDLE_VALUE) return false;
p_size = GetFileSize(p_filehandle, NULL);
p_size = GetFileSize(p_filehandle, nullptr);
p_maphandle = CreateFileMapping(p_filehandle, NULL, flprotect, 0, p_size, NULL);
p_maphandle = CreateFileMapping(p_filehandle, nullptr, flprotect, 0, p_size, nullptr);
if(p_maphandle == INVALID_HANDLE_VALUE) {
CloseHandle(p_filehandle);
p_filehandle = INVALID_HANDLE_VALUE;
@ -105,7 +106,7 @@ namespace nall {
void p_close() {
if(p_handle) {
UnmapViewOfFile(p_handle);
p_handle = 0;
p_handle = nullptr;
}
if(p_maphandle != INVALID_HANDLE_VALUE) {
@ -141,7 +142,7 @@ namespace nall {
bool p_open(const char *filename, mode mode_) {
if(file::exists(filename) && file::size(filename) == 0) {
p_handle = 0;
p_handle = nullptr;
p_size = 0;
return true;
}
@ -175,9 +176,9 @@ namespace nall {
fstat(p_fd, &p_stat);
p_size = p_stat.st_size;
p_handle = (uint8_t*)mmap(0, p_size, mmap_flags, MAP_SHARED, p_fd, 0);
p_handle = (uint8_t*)mmap(nullptr, p_size, mmap_flags, MAP_SHARED, p_fd, 0);
if(p_handle == MAP_FAILED) {
p_handle = 0;
p_handle = nullptr;
::close(p_fd);
p_fd = -1;
return false;
@ -189,7 +190,7 @@ namespace nall {
void p_close() {
if(p_handle) {
munmap(p_handle, p_size);
p_handle = 0;
p_handle = nullptr;
}
if(p_fd >= 0) {

View File

@ -34,7 +34,7 @@ namespace nall {
};
public:
operator bool() const { return callback; }
explicit operator bool() const { return callback; }
R operator()(P... p) const { return (*callback)(std::forward<P>(p)...); }
void reset() { if(callback) { delete callback; callback = nullptr; } }

View File

@ -24,7 +24,7 @@ struct http {
string header;
inline void download(const string &path, uint8_t *&data, unsigned &size) {
data = 0;
data = nullptr;
size = 0;
send({
@ -147,7 +147,7 @@ struct http {
inline void disconnect() {
close(serversocket);
freeaddrinfo(serverinfo);
serverinfo = 0;
serverinfo = nullptr;
serversocket = -1;
}

View File

@ -89,7 +89,7 @@ inline int stored(state *s) {
) return 2;
if(s->incnt + len > s->inlen) return 2;
if(s->out != 0) {
if(s->out != nullptr) {
if(s->outcnt + len > s->outlen) return 1;
while(len--) s->out[s->outcnt++] = s->in[s->incnt++];
} else {
@ -186,7 +186,7 @@ inline int codes(state *s, huffman *lencode, huffman *distcode) {
symbol = decode(s, lencode);
if(symbol < 0) return symbol;
if(symbol < 256) {
if(s->out != 0) {
if(s->out != nullptr) {
if(s->outcnt == s->outlen) return 1;
s->out[s->outcnt] = symbol;
}
@ -203,7 +203,7 @@ inline int codes(state *s, huffman *lencode, huffman *distcode) {
if(dist > s->outcnt) return -11;
#endif
if(s->out != 0) {
if(s->out != nullptr) {
if(s->outcnt + len > s->outlen) return 1;
while(len--) {
s->out[s->outcnt] =

View File

@ -61,7 +61,7 @@ bool lzss::compress(const string &filename) {
if(targetFile.open(filename, file::mode::write) == false) return false;
for(unsigned n = 0; n < 32; n += 8) targetFile.write(sourceSize >> n);
for(unsigned n = 0; n < 65536; n++) tree[n] = 0;
for(unsigned n = 0; n < 65536; n++) tree[n] = nullptr;
uint8_t buffer[25];
unsigned sourceOffset = 0;
@ -81,7 +81,7 @@ bool lzss::compress(const string &filename) {
while(node) {
if(node->offset < sourceOffset - 0x80000) {
//out-of-range: all subsequent nodes will also be, so free up their memory
if(node->next) { delete node->next; node->next = 0; }
if(node->next) { delete node->next; node->next = nullptr; }
break;
}

View File

@ -69,7 +69,7 @@ bool png::decode(const uint8_t *sourceData, unsigned sourceSize) {
if(read(sourceData + 0, 4) != 0x89504e47) return false;
if(read(sourceData + 4, 4) != 0x0d0a1a0a) return false;
uint8_t *compressedData = 0;
uint8_t *compressedData = nullptr;
unsigned compressedSize = 0;
unsigned offset = 8;
@ -150,7 +150,7 @@ bool png::decode(const uint8_t *sourceData, unsigned sourceSize) {
if(filter(data, interlacedData, info.width, info.height) == false) {
delete[] interlacedData;
delete[] data;
data = 0;
data = nullptr;
return false;
}
} else {
@ -159,7 +159,7 @@ bool png::decode(const uint8_t *sourceData, unsigned sourceSize) {
if(deinterlace(passData, pass) == false) {
delete[] interlacedData;
delete[] data;
data = 0;
data = nullptr;
return false;
}
}

View File

@ -86,7 +86,7 @@ namespace nall {
return *this;
}
serializer(const serializer &s) : idata(0) {
serializer(const serializer &s) : idata(nullptr) {
operator=(s);
}
@ -99,7 +99,7 @@ namespace nall {
isize = s.isize;
icapacity = s.icapacity;
s.idata = 0;
s.idata = nullptr;
return *this;
}
@ -110,7 +110,7 @@ namespace nall {
//construction
serializer() {
imode = Size;
idata = 0;
idata = nullptr;
isize = 0;
icapacity = 0;
}

View File

@ -22,6 +22,7 @@ namespace nall {
};
struct string {
//deprecated: use string text = file::read(filename);
inline static string read(const string &filename);
inline static string date();
@ -71,7 +72,7 @@ namespace nall {
template<unsigned limit = 0> inline string& ltrim(const char *key = " ");
template<unsigned limit = 0> inline string& rtrim(const char *key = " ");
template<unsigned limit = 0> inline string& trim(const char *key = " ", const char *rkey = 0);
template<unsigned limit = 0> inline string& trim(const char *key = " ", const char *rkey = nullptr);
inline string& strip();
inline optional<unsigned> position(const char *key) const;
@ -79,6 +80,7 @@ namespace nall {
inline optional<unsigned> qposition(const char *key) const;
inline optional<unsigned> iqposition(const char *key) const;
inline explicit operator bool() const;
inline operator const char*() const;
inline char* operator()();
inline char& operator[](int);
@ -197,7 +199,7 @@ namespace nall {
//trim.hpp
template<unsigned limit = 0> inline char* ltrim(char *str, const char *key = " ");
template<unsigned limit = 0> inline char* rtrim(char *str, const char *key = " ");
template<unsigned limit = 0> inline char* trim(char *str, const char *key = " ", const char *rkey = 0);
template<unsigned limit = 0> inline char* trim(char *str, const char *key = " ", const char *rkey = nullptr);
inline char* strip(char *s);
//utility.hpp

View File

@ -116,6 +116,32 @@ template<> struct stringify<long double> {
stringify(long double value) { fp(data, value); }
};
// arrays
template<> struct stringify<vector<uint8_t>> {
char *text;
operator const char*() const { return text; }
stringify(vector<uint8_t> value) {
text = new char[value.size() + 1]();
memcpy(text, value.data(), value.size());
}
~stringify() {
delete[] text;
}
};
template<> struct stringify<const vector<uint8_t>&> {
char *text;
operator const char*() const { return text; }
stringify(const vector<uint8_t> &value) {
text = new char[value.size() + 1]();
memcpy(text, value.data(), value.size());
}
~stringify() {
delete[] text;
}
};
// strings
template<> struct stringify<char*> {

View File

@ -3,7 +3,7 @@
namespace nall {
char* strlower(char *str) {
if(!str) return 0;
if(!str) return nullptr;
int i = 0;
while(str[i]) {
str[i] = chrlower(str[i]);
@ -13,7 +13,7 @@ char* strlower(char *str) {
}
char* strupper(char *str) {
if(!str) return 0;
if(!str) return nullptr;
int i = 0;
while(str[i]) {
str[i] = chrupper(str[i]);
@ -23,7 +23,7 @@ char* strupper(char *str) {
}
char* qstrlower(char *s) {
if(!s) return 0;
if(!s) return nullptr;
bool quoted = false;
while(*s) {
if(*s == '\"' || *s == '\'') quoted ^= 1;
@ -33,7 +33,7 @@ char* qstrlower(char *s) {
}
char* qstrupper(char *s) {
if(!s) return 0;
if(!s) return nullptr;
bool quoted = false;
while(*s) {
if(*s == '\"' || *s == '\'') quoted ^= 1;

View File

@ -55,6 +55,10 @@ string& string::append_(const char *s) {
return *this;
}
string::operator bool() const {
return !empty();
}
string::operator const char*() const {
return data;
}

View File

@ -3,7 +3,7 @@
namespace nall {
string string::date() {
time_t timestamp = ::time(0);
time_t timestamp = ::time(nullptr);
tm *info = localtime(&timestamp);
return {
decimal<4, '0'>(1900 + info->tm_year), "-",
@ -13,7 +13,7 @@ string string::date() {
}
string string::time() {
time_t timestamp = ::time(0);
time_t timestamp = ::time(nullptr);
tm *info = localtime(&timestamp);
return {
decimal<2, '0'>(info->tm_hour), ":",

View File

@ -80,7 +80,7 @@ protected:
parseName(p);
parseData(p);
parseAttributes(p);
if(*p++ != '\n') throw "Missing line feed";
if(*p && *p++ != '\n') throw "Missing line feed";
while(*p) {
if(*p == '\n') { p++; continue; }

View File

@ -39,7 +39,7 @@ string userpath() {
string result;
#ifdef _WIN32
wchar_t path[PATH_MAX] = L"";
SHGetFolderPathW(0, CSIDL_PROFILE | CSIDL_FLAG_CREATE, 0, 0, path);
SHGetFolderPathW(nullptr, CSIDL_PROFILE | CSIDL_FLAG_CREATE, nullptr, 0, path);
result = (const char*)utf8_t(path);
result.transform("\\", "/");
#else
@ -59,7 +59,7 @@ string configpath() {
string result;
#ifdef _WIN32
wchar_t path[PATH_MAX] = L"";
SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, path);
SHGetFolderPathW(nullptr, CSIDL_APPDATA | CSIDL_FLAG_CREATE, nullptr, 0, path);
result = (const char*)utf8_t(path);
result.transform("\\", "/");
#else

View File

@ -232,7 +232,7 @@ unsigned fp(char *str, long double value) {
string fp(long double value) {
string temp;
temp.reserve(fp(0, value));
temp.reserve(fp(nullptr, value));
fp(temp(), value);
return temp;
}

View File

@ -3,7 +3,7 @@
namespace nall {
bool wildcard(const char *s, const char *p) {
const char *cp = 0, *mp = 0;
const char *cp = nullptr, *mp = nullptr;
while(*s && *p != '*') {
if(*p != '?' && *s != *p) return false;
p++, s++;
@ -23,7 +23,7 @@ bool wildcard(const char *s, const char *p) {
}
bool iwildcard(const char *s, const char *p) {
const char *cp = 0, *mp = 0;
const char *cp = nullptr, *mp = nullptr;
while(*s && *p != '*') {
if(*p != '?' && chrlower(*s) != chrlower(*p)) return false;
p++, s++;

View File

@ -14,7 +14,7 @@ namespace nall {
struct thread {
thread(function<void ()> entryPoint) : entryPoint(entryPoint), completed(false), dead(false) {
initialize();
pthread_create(&pthread, NULL, thread_entry_point, (void*)this);
pthread_create(&pthread, nullptr, thread_entry_point, (void*)this);
}
~thread() {
@ -28,7 +28,7 @@ namespace nall {
void join() {
if(dead) return;
dead = true;
pthread_join(pthread, NULL);
pthread_join(pthread, nullptr);
}
static bool primary() {
@ -59,7 +59,7 @@ namespace nall {
thread *context = (thread*)parameter;
context->entryPoint();
context->completed = true;
pthread_exit(0);
pthread_exit(nullptr);
}
}
#elif defined(PLATFORM_WIN)
@ -69,7 +69,7 @@ namespace nall {
struct thread {
thread(function<void ()> entryPoint) : entryPoint(entryPoint), completed(false), dead(false) {
initialize();
hthread = CreateThread(NULL, 0, thread_entry_point, (void*)this, 0, NULL);
hthread = CreateThread(nullptr, 0, thread_entry_point, (void*)this, 0, nullptr);
}
~thread() {

View File

@ -21,7 +21,7 @@ namespace nall {
unsigned objectsize;
public:
operator bool() const { return pool; }
explicit operator bool() const { return pool; }
T* data() { return pool; }
const T* data() const { return pool; }

View File

@ -9,7 +9,7 @@ namespace nall {
//generate unique GUID
inline string guid() {
random_lfsr lfsr;
lfsr.seed(time(0));
lfsr.seed(time(nullptr));
for(unsigned n = 0; n < 256; n++) lfsr();
string output;

View File

@ -31,7 +31,7 @@ struct registry {
if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) {
wchar_t data[NWR_SIZE] = L"";
DWORD size = NWR_SIZE * sizeof(wchar_t);
LONG result = RegQueryValueExW(handle, utf16_t(node), NULL, NULL, (LPBYTE)&data, (LPDWORD)&size);
LONG result = RegQueryValueExW(handle, utf16_t(node), nullptr, nullptr, (LPBYTE)&data, (LPDWORD)&size);
RegCloseKey(handle);
if(result == ERROR_SUCCESS) return true;
}
@ -46,7 +46,7 @@ struct registry {
if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) {
wchar_t data[NWR_SIZE] = L"";
DWORD size = NWR_SIZE * sizeof(wchar_t);
LONG result = RegQueryValueExW(handle, utf16_t(node), NULL, NULL, (LPBYTE)&data, (LPDWORD)&size);
LONG result = RegQueryValueExW(handle, utf16_t(node), nullptr, nullptr, (LPBYTE)&data, (LPDWORD)&size);
RegCloseKey(handle);
if(result == ERROR_SUCCESS) return (const char*)utf8_t(data);
}
@ -60,7 +60,7 @@ struct registry {
DWORD disposition;
for(unsigned n = 0; n < part.size(); n++) {
path.append(part[n]);
if(RegCreateKeyExW(rootKey, utf16_t(path), 0, NULL, 0, NWR_FLAGS | KEY_ALL_ACCESS, NULL, &handle, &disposition) == ERROR_SUCCESS) {
if(RegCreateKeyExW(rootKey, utf16_t(path), 0, nullptr, 0, NWR_FLAGS | KEY_ALL_ACCESS, nullptr, &handle, &disposition) == ERROR_SUCCESS) {
if(n == part.size() - 1) {
RegSetValueExW(handle, utf16_t(node), 0, REG_SZ, (BYTE*)(wchar_t*)utf16_t(data), (data.length() + 1) * sizeof(wchar_t));
}
@ -86,17 +86,17 @@ struct registry {
string path = part.concatenate("\\");
if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) {
DWORD folders, nodes;
RegQueryInfoKey(handle, NULL, NULL, NULL, &folders, NULL, NULL, &nodes, NULL, NULL, NULL, NULL);
RegQueryInfoKey(handle, nullptr, nullptr, nullptr, &folders, nullptr, nullptr, &nodes, nullptr, nullptr, nullptr, nullptr);
for(unsigned n = 0; n < folders; n++) {
wchar_t name[NWR_SIZE] = L"";
DWORD size = NWR_SIZE * sizeof(wchar_t);
RegEnumKeyEx(handle, n, (wchar_t*)&name, &size, NULL, NULL, NULL, NULL);
RegEnumKeyEx(handle, n, (wchar_t*)&name, &size, nullptr, nullptr, nullptr, nullptr);
result.append({(const char*)utf8_t(name), "/"});
}
for(unsigned n = 0; n < nodes; n++) {
wchar_t name[NWR_SIZE] = L"";
DWORD size = NWR_SIZE * sizeof(wchar_t);
RegEnumValueW(handle, n, (wchar_t*)&name, &size, NULL, NULL, NULL, NULL);
RegEnumValueW(handle, n, (wchar_t*)&name, &size, nullptr, nullptr, nullptr, nullptr);
result.append((const char*)utf8_t(name));
}
RegCloseKey(handle);
@ -111,7 +111,7 @@ private:
if(name == "HKCU") return HKEY_CURRENT_USER;
if(name == "HKLM") return HKEY_LOCAL_MACHINE;
if(name == "HKU" ) return HKEY_USERS;
return NULL;
return nullptr;
}
};

View File

@ -30,7 +30,7 @@ namespace nall {
utf16_t(const char *s = "") {
if(!s) s = "";
unsigned length = MultiByteToWideChar(CP_UTF8, 0, s, -1, 0, 0);
unsigned length = MultiByteToWideChar(CP_UTF8, 0, s, -1, nullptr, 0);
buffer = new wchar_t[length + 1]();
MultiByteToWideChar(CP_UTF8, 0, s, -1, buffer, length);
}
@ -56,9 +56,9 @@ namespace nall {
utf8_t(const wchar_t *s = L"") {
if(!s) s = L"";
unsigned length = WideCharToMultiByte(CP_UTF8, 0, s, -1, 0, 0, (const char*)0, (BOOL*)0);
unsigned length = WideCharToMultiByte(CP_UTF8, 0, s, -1, nullptr, 0, nullptr, nullptr);
buffer = new char[length + 1]();
WideCharToMultiByte(CP_UTF8, 0, s, -1, buffer, length, (const char*)0, (BOOL*)0);
WideCharToMultiByte(CP_UTF8, 0, s, -1, buffer, length, nullptr, nullptr);
}
~utf8_t() {

View File

@ -11,7 +11,7 @@ namespace nall {
struct zip {
zip(const string &filename) {
fp.open(filename, file::mode::write);
time_t currentTime = time(0);
time_t currentTime = time(nullptr);
tm *info = localtime(&currentTime);
dosTime = (info->tm_hour << 11) | (info->tm_min << 5) | (info->tm_sec >> 1);
dosDate = ((info->tm_year - 80) << 9) | ((1 + info->tm_mon) << 5) + (info->tm_mday);

View File

@ -0,0 +1,21 @@
namespace phoenix {
void pAction::setEnabled(bool enabled) {
@autoreleasepool {
[cocoaAction setEnabled:enabled];
}
}
void pAction::setVisible(bool visible) {
@autoreleasepool {
[cocoaAction setHidden:!visible];
}
}
void pAction::constructor() {
}
void pAction::destructor() {
}
}

View File

@ -0,0 +1,15 @@
namespace phoenix {
struct pAction : public pObject {
Action &action;
NSMenuItem *cocoaAction;
void setEnabled(bool enabled);
void setVisible(bool visible);
pAction(Action &action) : pObject(action), action(action) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,55 @@
@implementation CocoaCheckItem : NSMenuItem
-(id) initWith :(phoenix::CheckItem&)checkItemReference {
if(self = [super initWithTitle:@"" action:@selector(activate) keyEquivalent:@""]) {
checkItem = &checkItemReference;
[self setTarget:self];
}
return self;
}
-(void) activate {
checkItem->state.checked = !checkItem->state.checked;
auto state = checkItem->state.checked ? NSOnState : NSOffState;
[self setState:state];
if(checkItem->onToggle) checkItem->onToggle();
}
@end
namespace phoenix {
bool pCheckItem::checked() {
@autoreleasepool {
return [cocoaAction state] != NSOffState;
}
}
void pCheckItem::setChecked(bool checked) {
@autoreleasepool {
auto state = checked ? NSOnState : NSOffState;
[cocoaAction setState:state];
}
}
void pCheckItem::setText(const string &text) {
@autoreleasepool {
[cocoaAction setTitle:[NSString stringWithUTF8String:text]];
}
}
void pCheckItem::constructor() {
@autoreleasepool {
cocoaAction = cocoaCheckItem = [[CocoaCheckItem alloc] initWith:checkItem];
setText(checkItem.state.text);
}
}
void pCheckItem::destructor() {
@autoreleasepool {
[cocoaAction release];
}
}
}

View File

@ -0,0 +1,24 @@
@interface CocoaCheckItem : NSMenuItem {
@public
phoenix::CheckItem *checkItem;
}
-(id) initWith :(phoenix::CheckItem&)checkItem;
-(void) activate;
@end
namespace phoenix {
struct pCheckItem : public pAction {
CheckItem &checkItem;
CocoaCheckItem *cocoaCheckItem;
bool checked();
void setChecked(bool checked);
void setText(const string &text);
pCheckItem(CheckItem &checkItem) : pAction(checkItem), checkItem(checkItem) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,45 @@
@implementation CocoaItem : NSMenuItem
-(id) initWith :(phoenix::Item&)itemReference {
if(self = [super initWithTitle:@"" action:@selector(activate) keyEquivalent:@""]) {
item = &itemReference;
[self setTarget:self];
}
return self;
}
-(void) activate {
if(item->onActivate) item->onActivate();
}
@end
namespace phoenix {
void pItem::setImage(const image &image) {
@autoreleasepool {
unsigned size = 15; //there is no API to retrieve the optimal size
[cocoaAction setImage:NSMakeImage(image, size, size)];
}
}
void pItem::setText(const string &text) {
@autoreleasepool {
[cocoaAction setTitle:[NSString stringWithUTF8String:text]];
}
}
void pItem::constructor() {
@autoreleasepool {
cocoaAction = cocoaItem = [[CocoaItem alloc] initWith:item];
}
}
void pItem::destructor() {
@autoreleasepool {
[cocoaAction release];
}
}
}

View File

@ -0,0 +1,23 @@
@interface CocoaItem : NSMenuItem {
@public
phoenix::Item *item;
}
-(id) initWith :(phoenix::Item&)item;
-(void) activate;
@end
namespace phoenix {
struct pItem : public pAction {
Item &item;
CocoaItem *cocoaItem;
void setImage(const image &image);
void setText(const string &text);
pItem(Item &item) : pAction(item), item(item) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,61 @@
@implementation CocoaMenu : NSMenuItem
-(id) initWith :(phoenix::Menu&)menuReference {
if(self = [super initWithTitle:@"" action:nil keyEquivalent:@""]) {
menu = &menuReference;
cocoaMenu = [[NSMenu alloc] initWithTitle:@""];
[self setSubmenu:cocoaMenu];
}
return self;
}
-(NSMenu*) cocoaMenu {
return cocoaMenu;
}
@end
namespace phoenix {
void pMenu::append(Action &action) {
@autoreleasepool {
[[cocoaAction cocoaMenu] addItem:action.p.cocoaAction];
}
}
void pMenu::remove(Action &action) {
@autoreleasepool {
[[cocoaAction cocoaMenu] removeItem:action.p.cocoaAction];
}
}
void pMenu::setImage(const image &image) {
@autoreleasepool {
unsigned size = 15; //there is no API to retrieve the optimal size
[cocoaAction setImage:NSMakeImage(image, size, size)];
}
}
void pMenu::setText(const string &text) {
@autoreleasepool {
[[cocoaAction cocoaMenu] setTitle:[NSString stringWithUTF8String:text]];
[cocoaAction setTitle:[NSString stringWithUTF8String:text]];
}
}
void pMenu::constructor() {
@autoreleasepool {
cocoaAction = cocoaMenu = [[CocoaMenu alloc] initWith:menu];
setText(menu.state.text);
}
}
void pMenu::destructor() {
@autoreleasepool {
[[cocoaAction cocoaMenu] release];
[cocoaAction release];
}
}
}

View File

@ -0,0 +1,26 @@
@interface CocoaMenu : NSMenuItem {
@public
phoenix::Menu *menu;
NSMenu *cocoaMenu;
}
-(id) initWith :(phoenix::Menu&)menu;
-(NSMenu*) cocoaMenu;
@end
namespace phoenix {
struct pMenu : public pAction {
Menu &menu;
CocoaMenu *cocoaMenu;
void append(Action &action);
void remove(Action &action);
void setImage(const image &image);
void setText(const string &text);
pMenu(Menu &menu) : pAction(menu), menu(menu) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,59 @@
@implementation CocoaRadioItem : NSMenuItem
-(id) initWith :(phoenix::RadioItem&)radioItemReference {
if(self = [super initWithTitle:@"" action:@selector(activate) keyEquivalent:@""]) {
radioItem = &radioItemReference;
[self setTarget:self];
[self setOnStateImage:[NSImage imageNamed:@"NSMenuRadio"]];
}
return self;
}
-(void) activate {
radioItem->setChecked();
if(radioItem->onActivate) radioItem->onActivate();
}
@end
namespace phoenix {
bool pRadioItem::checked() {
@autoreleasepool {
return [cocoaAction state] != NSOffState;
}
}
void pRadioItem::setChecked() {
@autoreleasepool {
for(auto &item : radioItem.state.group) {
auto state = (&item == &radioItem) ? NSOnState : NSOffState;
[item.p.cocoaAction setState:state];
}
}
}
void pRadioItem::setGroup(const set<RadioItem&> &group) {
}
void pRadioItem::setText(const string &text) {
@autoreleasepool {
[cocoaAction setTitle:[NSString stringWithUTF8String:text]];
}
}
void pRadioItem::constructor() {
@autoreleasepool {
cocoaAction = cocoaRadioItem = [[CocoaRadioItem alloc] initWith:radioItem];
setText(radioItem.state.text);
}
}
void pRadioItem::destructor() {
@autoreleasepool {
[cocoaAction release];
}
}
}

View File

@ -0,0 +1,25 @@
@interface CocoaRadioItem : NSMenuItem {
@public
phoenix::RadioItem *radioItem;
}
-(id) initWith :(phoenix::RadioItem&)radioItem;
-(void) activate;
@end
namespace phoenix {
struct pRadioItem : public pAction {
RadioItem &radioItem;
CocoaRadioItem *cocoaRadioItem;
bool checked();
void setChecked();
void setGroup(const set<RadioItem&> &group);
void setText(const string &text);
pRadioItem(RadioItem &radioItem) : pAction(radioItem), radioItem(radioItem) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,26 @@
@implementation CocoaSeparator : NSMenuItem
-(id) initWith :(phoenix::Separator&)separatorReference {
if(self = [super separatorItem]) {
separator = &separatorReference;
}
return self;
}
@end
namespace phoenix {
void pSeparator::constructor() {
@autoreleasepool {
cocoaAction = cocoaSeparator = [[CocoaSeparator alloc] initWith:separator];
}
}
void pSeparator::destructor() {
@autoreleasepool {
[cocoaAction release];
}
}
}

View File

@ -0,0 +1,19 @@
@interface CocoaSeparator : NSMenuItem {
@public
phoenix::Separator *separator;
}
-(id) initWith :(phoenix::Separator&)separator;
@end
namespace phoenix {
struct pSeparator : public pAction {
Separator &separator;
CocoaSeparator *cocoaSeparator;
pSeparator(Separator &separator) : pAction(separator), separator(separator) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,69 @@
@implementation CocoaDelegate : NSObject
-(NSApplicationTerminateReply) applicationShouldTerminate :(NSApplication*)sender {
using phoenix::Application;
if(Application::Cocoa::onQuit) Application::Cocoa::onQuit();
else Application::quit();
return NSTerminateCancel;
}
-(void) run :(NSTimer*)timer {
using phoenix::Application;
if(Application::main) Application::main();
}
@end
CocoaDelegate *cocoaDelegate = nullptr;
namespace phoenix {
void pApplication::run() {
if(Application::main) {
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:cocoaDelegate selector:@selector(run:) userInfo:nil repeats:YES];
}
@autoreleasepool {
[NSApp run];
}
}
bool pApplication::pendingEvents() {
bool result = false;
@autoreleasepool {
NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:NO];
if(event != nil) result = true;
}
return result;
}
void pApplication::processEvents() {
@autoreleasepool {
while(applicationState.quit == false) {
NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES];
if(event == nil) break;
[event retain];
[NSApp sendEvent:event];
[event release];
}
}
}
void pApplication::quit() {
@autoreleasepool {
[NSApp stop:nil];
NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined location:NSMakePoint(0, 0) modifierFlags:0 timestamp:0.0 windowNumber:0 context:nil subtype:0 data1:0 data2:0];
[NSApp postEvent:event atStart:true];
}
}
void pApplication::initialize() {
@autoreleasepool {
[NSApplication sharedApplication];
cocoaDelegate = [[CocoaDelegate alloc] init];
[NSApp setDelegate:cocoaDelegate];
//every window has the default application menu; call this so it is displayed at startup
[NSApp setMainMenu:[Window::none().p.cocoaWindow menu]];
}
}
}

View File

@ -0,0 +1,18 @@
@interface CocoaDelegate : NSObject <NSApplicationDelegate> {
}
-(NSApplicationTerminateReply) applicationShouldTerminate :(NSApplication*)sender;
-(void) run :(NSTimer*)timer;
@end
namespace phoenix {
struct pApplication {
static void run();
static bool pendingEvents();
static void processEvents();
static void quit();
static void initialize();
};
}

View File

@ -0,0 +1,18 @@
namespace phoenix {
Size pDesktop::size() {
@autoreleasepool {
NSRect primary = [[[NSScreen screens] objectAtIndex:0] frame];
return {primary.size.width, primary.size.height};
}
}
Geometry pDesktop::workspace() {
@autoreleasepool {
auto screen = Desktop::size();
NSRect area = [[[NSScreen screens] objectAtIndex:0] visibleFrame];
return {area.origin.x, screen.height - area.size.height - area.origin.y, area.size.width, area.size.height};
}
}
}

View File

@ -0,0 +1,8 @@
namespace phoenix {
struct pDesktop {
static Size size();
static Geometry workspace();
};
}

View File

@ -0,0 +1,66 @@
namespace phoenix {
string pDialogWindow::fileOpen(Window &parent, const string &path, const lstring &filter) {
string result;
@autoreleasepool {
NSMutableArray *filters = [[NSMutableArray alloc] init];
for(auto &rule : filter) {
string pattern = rule.split<1>("(")(1).rtrim<1>(")");
if(!pattern.empty()) [filters addObject:[NSString stringWithUTF8String:pattern]];
}
NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setCanChooseDirectories:NO];
[panel setCanChooseFiles:YES];
[panel setAllowedFileTypes:filters];
if([panel runModalForDirectory:[NSString stringWithUTF8String:path] file:nil] == NSOKButton) {
NSArray *filenames = [panel filenames];
const char *filename = [[filenames objectAtIndex:0] UTF8String];
if(filename) result = filename;
}
[filters release];
}
return result;
}
string pDialogWindow::fileSave(Window &parent, const string &path, const lstring &filter) {
string result;
@autoreleasepool {
NSMutableArray *filters = [[NSMutableArray alloc] init];
for(auto &rule : filter) {
string pattern = rule.split<1>("(")(1).rtrim<1>(")");
if(!pattern.empty()) [filters addObjects:[NSString stringWithUTF8String:pattern]];
}
NSSavePanel *panel = [NSSavePanel savePanel];
[panel setAllowedFileTypes:filters];
if([panel runModalForDirectory:[NSString stringWithUTF8String:path] file:nil] == NSOKButton) {
NSArray *filenames = [panel filenames];
const char *filename = [[filenames objectAtIndex:0] UTF8String];
if(filename) result = filename;
}
[filters release];
}
return result;
}
string pDialogWindow::folderSelect(Window &parent, const string &path) {
string result;
@autoreleasepool {
NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setCanChooseDirectories:YES];
[panel setCanChooseFiles:NO];
if([panel runModalForDirectory:[NSString stringWithUTF8String:path] file:nil] == NSOKButton) {
NSArray *filenames = [panel filenames];
const char *filename = [[filenames objectAtIndex:0] UTF8String];
if(filename) result = filename;
}
}
return result;
}
}

View File

@ -0,0 +1,9 @@
namespace phoenix {
struct pDialogWindow {
static string fileOpen(Window &parent, const string &path, const lstring &filter);
static string fileSave(Window &parent, const string &path, const lstring &filter);
static string folderSelect(Window &parent, const string &path);
};
}

View File

@ -0,0 +1,59 @@
namespace phoenix {
string pFont::serif(unsigned size, string style) {
if(size == 0) size = 12;
if(style == "") style = "Normal";
return {"Georgia, ", size, ", ", style};
}
string pFont::sans(unsigned size, string style) {
if(size == 0) size = 12;
if(style == "") style = "Normal";
return {"Lucida Grande, ", size, ", ", style};
}
string pFont::monospace(unsigned size, string style) {
if(size == 0) size = 12;
if(style == "") style = "Normal";
return {"Menlo, ", size, ", ", style};
}
Size pFont::size(const string &font, const string &text) {
@autoreleasepool {
if(NSFont *nsFont = cocoaFont(font)) {
return size(nsFont, text);
}
}
return {0, 0};
}
NSFont* pFont::cocoaFont(const string &description) {
lstring part = description.split<2>(",");
for(auto &item : part) item.strip();
NSString *family = @"Lucida Grande";
NSFontTraitMask traits = 0;
CGFloat size = 12;
if(!part(0).empty()) family = [NSString stringWithUTF8String:part(0)];
if(!part(1).empty()) size = fp(part(1));
if(part(2).iposition("bold")) traits |= NSBoldFontMask;
if(part(2).iposition("italic")) traits |= NSItalicFontMask;
if(part(2).iposition("narrow")) traits |= NSNarrowFontMask;
if(part(2).iposition("expanded")) traits |= NSExpandedFontMask;
if(part(2).iposition("condensed")) traits |= NSCondensedFontMask;
if(part(2).iposition("smallcaps")) traits |= NSSmallCapsFontMask;
return [[NSFontManager sharedFontManager] fontWithFamily:family traits:traits weight:5 size:size];
}
Size pFont::size(NSFont *font, const string &text) {
@autoreleasepool {
NSString *cocoaText = [NSString stringWithUTF8String:text];
NSDictionary *fontAttributes = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil];
NSSize size = [cocoaText sizeWithAttributes:fontAttributes];
return {size.width, size.height};
}
}
}

View File

@ -0,0 +1,13 @@
namespace phoenix {
struct pFont {
static string serif(unsigned size, string style);
static string sans(unsigned size, string style);
static string monospace(unsigned size, string style);
static Size size(const string &font, const string &text);
static NSFont* cocoaFont(const string &description);
static Size size(NSFont *font, const string &text);
};
}

View File

@ -0,0 +1,4 @@
#define decimal CocoaDecimal
#import <Cocoa/Cocoa.h>
#import <Carbon/Carbon.h>
#undef decimal

View File

@ -0,0 +1,14 @@
namespace phoenix {
bool pKeyboard::pressed(Keyboard::Scancode scancode) {
return false;
}
vector<bool> pKeyboard::state() {
vector<bool> output;
output.resize((unsigned)Keyboard::Scancode::Limit);
for(auto &n : output) n = false;
return output;
}
}

View File

@ -0,0 +1,8 @@
namespace phoenix {
struct pKeyboard {
static bool pressed(Keyboard::Scancode scancode);
static vector<bool> state();
};
}

View File

@ -0,0 +1,76 @@
namespace phoenix {
MessageWindow::Response pMessageWindow::information(Window &parent, const string &text, MessageWindow::Buttons buttons) {
return message(parent, text, buttons, Type::Information);
}
MessageWindow::Response pMessageWindow::question(Window &parent, const string &text, MessageWindow::Buttons buttons) {
return message(parent, text, buttons, Type::Question);
}
MessageWindow::Response pMessageWindow::warning(Window &parent, const string &text, MessageWindow::Buttons buttons) {
return message(parent, text, buttons, Type::Warning);
}
MessageWindow::Response pMessageWindow::critical(Window &parent, const string &text, MessageWindow::Buttons buttons) {
return message(parent, text, buttons, Type::Critical);
}
MessageWindow::Response pMessageWindow::message(Window &parent, const string &text, MessageWindow::Buttons buttons, Type type) {
@autoreleasepool {
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
[alert setMessageText:[NSString stringWithUTF8String:text]];
switch(buttons) {
case MessageWindow::Buttons::Ok:
[alert addButtonWithTitle:@"Ok"];
break;
case MessageWindow::Buttons::OkCancel:
[alert addButtonWithTitle:@"Ok"];
[alert addButtonWithTitle:@"Cancel"];
break;
case MessageWindow::Buttons::YesNo:
[alert addButtonWithTitle:@"Yes"];
[alert addButtonWithTitle:@"No"];
break;
case MessageWindow::Buttons::YesNoCancel:
[alert addButtonWithTitle:@"Yes"];
[alert addButtonWithTitle:@"No"];
[alert addButtonWithTitle:@"Cancel"];
break;
}
switch(type) {
case Type::Information: [alert setAlertStyle:NSInformationalAlertStyle]; break;
case Type::Question: [alert setAlertStyle:NSInformationalAlertStyle]; break;
case Type::Warning: [alert setAlertStyle:NSWarningAlertStyle]; break;
case Type::Critical: [alert setAlertStyle:NSCriticalAlertStyle]; break;
}
NSInteger response = [alert runModal];
//[alert beginSheetModalForWindow:parent.p.cocoaWindow modalDelegate:self didEndSelector:@selector(...) contextInfo:nil];
switch(buttons) {
case MessageWindow::Buttons::Ok:
if(response == NSAlertFirstButtonReturn) return MessageWindow::Response::Ok;
break;
case MessageWindow::Buttons::OkCancel:
if(response == NSAlertFirstButtonReturn) return MessageWindow::Response::Ok;
if(response == NSAlertSecondButtonReturn) return MessageWindow::Response::Cancel;
break;
case MessageWindow::Buttons::YesNo:
if(response == NSAlertFirstButtonReturn) return MessageWindow::Response::Yes;
if(response == NSAlertSecondButtonReturn) return MessageWindow::Response::No;
break;
case MessageWindow::Buttons::YesNoCancel:
if(response == NSAlertFirstButtonReturn) return MessageWindow::Response::Yes;
if(response == NSAlertSecondButtonReturn) return MessageWindow::Response::No;
if(response == NSAlertThirdButtonReturn) return MessageWindow::Response::Cancel;
break;
}
}
return MessageWindow::Response::Ok;
}
}

View File

@ -0,0 +1,13 @@
namespace phoenix {
struct pMessageWindow {
static MessageWindow::Response information(Window &parent, const string &text, MessageWindow::Buttons buttons);
static MessageWindow::Response question(Window &parent, const string &text, MessageWindow::Buttons buttons);
static MessageWindow::Response warning(Window &parent, const string &text, MessageWindow::Buttons buttons);
static MessageWindow::Response critical(Window &parent, const string &text, MessageWindow::Buttons buttons);
enum class Type : unsigned { Information, Question, Warning, Critical };
static MessageWindow::Response message(Window &parent, const string &text, MessageWindow::Buttons buttons, Type type);
};
}

View File

@ -0,0 +1,11 @@
namespace phoenix {
Position pMouse::position() {
return {0, 0};
}
bool pMouse::pressed(Mouse::Button button) {
return false;
}
}

View File

@ -0,0 +1,8 @@
namespace phoenix {
struct pMouse {
static Position position();
static bool pressed(Mouse::Button button);
};
}

View File

@ -0,0 +1,14 @@
namespace phoenix {
struct pObject {
Object &object;
bool locked;
pObject(Object &object) : object(object), locked(false) {}
virtual ~pObject() {}
void constructor() {}
void destructor() {}
};
}

View File

@ -0,0 +1,38 @@
#include "platform.hpp"
#include "utility.cpp"
#include "desktop.cpp"
#include "keyboard.cpp"
#include "mouse.cpp"
#include "dialog-window.cpp"
#include "message-window.cpp"
#include "font.cpp"
#include "timer.cpp"
#include "window.cpp"
#include "action/action.cpp"
#include "action/menu.cpp"
#include "action/separator.cpp"
#include "action/item.cpp"
#include "action/check-item.cpp"
#include "action/radio-item.cpp"
#include "widget/widget.cpp"
#include "widget/button.cpp"
#include "widget/canvas.cpp"
#include "widget/check-button.cpp"
#include "widget/combo-button.cpp"
#include "widget/hex-edit.cpp"
#include "widget/horizontal-scroller.cpp"
#include "widget/horizontal-slider.cpp"
#include "widget/label.cpp"
#include "widget/line-edit.cpp"
#include "widget/list-view.cpp"
#include "widget/progress-bar.cpp"
#include "widget/radio-button.cpp"
#include "widget/text-edit.cpp"
#include "widget/vertical-scroller.cpp"
#include "widget/vertical-slider.cpp"
#include "widget/viewport.cpp"
#include "application.cpp"

View File

@ -0,0 +1,46 @@
namespace phoenix {
struct pFont;
struct pWindow;
struct pMenu;
struct pLayout;
struct pWidget;
}
#include "font.hpp"
#include "desktop.hpp"
#include "keyboard.hpp"
#include "mouse.hpp"
#include "dialog-window.hpp"
#include "message-window.hpp"
#include "object.hpp"
#include "timer.hpp"
#include "window.hpp"
#include "action/action.hpp"
#include "action/menu.hpp"
#include "action/separator.hpp"
#include "action/item.hpp"
#include "action/check-item.hpp"
#include "action/radio-item.hpp"
#include "widget/sizable.hpp"
#include "widget/layout.hpp"
#include "widget/widget.hpp"
#include "widget/button.hpp"
#include "widget/canvas.hpp"
#include "widget/check-button.hpp"
#include "widget/combo-button.hpp"
#include "widget/hex-edit.hpp"
#include "widget/horizontal-scroller.hpp"
#include "widget/horizontal-slider.hpp"
#include "widget/label.hpp"
#include "widget/line-edit.hpp"
#include "widget/list-view.hpp"
#include "widget/progress-bar.hpp"
#include "widget/radio-button.hpp"
#include "widget/text-edit.hpp"
#include "widget/vertical-scroller.hpp"
#include "widget/vertical-slider.hpp"
#include "widget/viewport.hpp"
#include "application.hpp"

View File

@ -0,0 +1,60 @@
@implementation CocoaTimer : NSObject
-(id) initWith :(phoenix::Timer&)timerReference {
if(self = [super init]) {
timer = &timerReference;
instance = nil;
}
return self;
}
-(NSTimer*) instance {
return instance;
}
-(void) update {
if(instance) {
[instance invalidate];
instance = nil;
}
if(timer->state.enabled == false) return;
instance = [NSTimer
scheduledTimerWithTimeInterval:timer->state.milliseconds / 1000.0
target:self selector:@selector(run:) userInfo:nil repeats:YES
];
}
-(void) run :(NSTimer*)instance {
if(timer->onActivate) timer->onActivate();
}
@end
namespace phoenix {
void pTimer::setEnabled(bool enabled) {
@autoreleasepool {
[cocoaTimer update];
}
}
void pTimer::setInterval(unsigned milliseconds) {
@autoreleasepool {
[cocoaTimer update];
}
}
void pTimer::constructor() {
@autoreleasepool {
cocoaTimer = [[CocoaTimer alloc] initWith:timer];
}
}
void pTimer::destructor() {
@autoreleasepool {
if([cocoaTimer instance]) [[cocoaTimer instance] invalidate];
[cocoaTimer release];
}
}
}

View File

@ -0,0 +1,26 @@
@interface CocoaTimer : NSObject {
@public
phoenix::Timer *timer;
NSTimer *instance;
}
-(id) initWith :(phoenix::Timer&)timer;
-(NSTimer*) instance;
-(void) update;
-(void) run :(NSTimer*)instance;
@end
namespace phoenix {
struct pTimer : public pObject {
Timer &timer;
CocoaTimer *cocoaTimer;
void setEnabled(bool enabled);
void setInterval(unsigned milliseconds);
pTimer(Timer &timer) : pObject(timer), timer(timer) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,17 @@
NSImage* NSMakeImage(nall::image image, unsigned width = 0, unsigned height = 0) {
if(image.empty()) return nil;
if(width && height) image.scale(width, height, Interpolation::Linear);
image.transform(0, 32, 255u << 24, 255u << 0, 255u << 8, 255u << 16);
NSImage *cocoaImage = [[[NSImage alloc] initWithSize:NSMakeSize(image.width, image.height)] autorelease];
NSBitmapImageRep *bitmap = [[[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:nil
pixelsWide:image.width pixelsHigh:image.height
bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES
isPlanar:NO colorSpaceName:NSCalibratedRGBColorSpace
bitmapFormat:NSAlphaNonpremultipliedBitmapFormat
bytesPerRow:image.pitch bitsPerPixel:32
] autorelease];
memcpy([bitmap bitmapData], image.data, image.height * image.pitch);
[cocoaImage addRepresentation:bitmap];
return cocoaImage;
}

View File

@ -0,0 +1,70 @@
@implementation CocoaButton : NSButton
-(id) initWith :(phoenix::Button&)buttonReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
button = &buttonReference;
[self setTarget:self];
[self setAction:@selector(activate:)];
//NSRoundedBezelStyle has a fixed height; which breaks both icons and larger/smaller text
[self setBezelStyle:NSRegularSquareBezelStyle];
}
return self;
}
-(IBAction) activate :(id)sender {
if(button->onActivate) button->onActivate();
}
@end
namespace phoenix {
Size pButton::minimumSize() {
Size size = Font::size(button.font(), button.state.text);
if(button.state.orientation == Orientation::Horizontal) {
size.width += button.state.image.width;
size.height = max(button.state.image.height, size.height);
}
if(button.state.orientation == Orientation::Vertical) {
size.width = max(button.state.image.width, size.width);
size.height += button.state.image.height;
}
return {size.width + 24, size.height + 8};
}
void pButton::setImage(const image &image, Orientation orientation) {
@autoreleasepool {
if(image.empty()) {
[cocoaView setImage:nil];
return;
}
[cocoaView setImage:NSMakeImage(image)];
if(orientation == Orientation::Horizontal) [cocoaView setImagePosition:NSImageLeft];
if(orientation == Orientation::Vertical ) [cocoaView setImagePosition:NSImageAbove];
}
}
void pButton::setText(const string &text) {
@autoreleasepool {
[cocoaView setTitle:[NSString stringWithUTF8String:text]];
}
}
void pButton::constructor() {
@autoreleasepool {
cocoaView = cocoaButton = [[CocoaButton alloc] initWith:button];
}
}
void pButton::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@ -0,0 +1,24 @@
@interface CocoaButton : NSButton {
@public
phoenix::Button *button;
}
-(id) initWith :(phoenix::Button&)button;
-(IBAction) activate :(id)sender;
@end
namespace phoenix {
struct pButton : public pWidget {
Button &button;
CocoaButton *cocoaButton;
Size minimumSize();
void setImage(const image &image, Orientation orientation);
void setText(const string &text);
pButton(Button &button) : pWidget(button), button(button) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,125 @@
@implementation CocoaCanvas : NSImageView
-(id) initWith :(phoenix::Canvas&)canvasReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
canvas = &canvasReference;
[self setEditable:NO]; //disable image drag-and-drop functionality
NSTrackingArea *area = [[[NSTrackingArea alloc] initWithRect:[self frame]
options:NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow | NSTrackingInVisibleRect
owner:self userInfo:nil
] autorelease];
[self addTrackingArea:area];
}
return self;
}
-(void) mouseButton :(NSEvent*)event down:(BOOL)isDown {
if(auto &callback = isDown ? canvas->onMousePress : canvas->onMouseRelease) {
switch([event buttonNumber]) {
case 0: return callback(phoenix::Mouse::Button::Left);
case 1: return callback(phoenix::Mouse::Button::Right);
case 2: return callback(phoenix::Mouse::Button::Middle);
}
}
}
-(void) mouseExited :(NSEvent*)event {
if(canvas->onMouseLeave) canvas->onMouseLeave();
}
-(void) mouseMove :(NSEvent*)event {
if([event window] == nil) return;
NSPoint location = [self convertPoint:[event locationInWindow] fromView:nil];
if(canvas->onMouseMove) canvas->onMouseMove({location.x, [self frame].size.height - 1 - location.y});
}
-(void) mouseDown :(NSEvent*)event {
[self mouseButton:event down:YES];
}
-(void) mouseUp :(NSEvent*)event {
[self mouseButton:event down:NO];
}
-(void) mouseDragged :(NSEvent*)event {
[self mouseMove:event];
}
-(void) rightMouseDown :(NSEvent*)event {
[self mouseButton:event down:YES];
}
-(void) rightMouseUp :(NSEvent*)event {
[self mouseButton:event down:NO];
}
-(void) rightMouseDragged :(NSEvent*)event {
[self mouseMove:event];
}
-(void) otherMouseDown :(NSEvent*)event {
[self mouseButton:event down:YES];
}
-(void) otherMouseUp :(NSEvent*)event {
[self mouseButton:event down:NO];
}
-(void) otherMouseDragged :(NSEvent*)event {
[self mouseMove:event];
}
@end
namespace phoenix {
void pCanvas::setSize(const Size &size) {
@autoreleasepool {
NSImage *image = [[[NSImage alloc] initWithSize:NSMakeSize(size.width, size.height)] autorelease];
NSBitmapImageRep *bitmap = [[[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:nil
pixelsWide:size.width pixelsHigh:size.height
bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES
isPlanar:NO colorSpaceName:NSCalibratedRGBColorSpace
bitmapFormat:NSAlphaNonpremultipliedBitmapFormat
bytesPerRow:size.width * 4 bitsPerPixel:32
] autorelease];
[image addRepresentation:bitmap];
[cocoaView setImage:image];
}
}
void pCanvas::update() {
@autoreleasepool {
if(NSBitmapImageRep *bitmap = [[[cocoaView image] representations] objectAtIndex:0]) {
uint8_t *target = [bitmap bitmapData];
uint32_t *source = canvas.state.data;
for(unsigned n = 0; n < canvas.state.width * canvas.state.height; n++) {
*target++ = *source >> 16;
*target++ = *source >> 8;
*target++ = *source >> 0;
*target++ = *source >> 24;
source++;
}
[cocoaView setNeedsDisplay:YES];
}
}
}
void pCanvas::constructor() {
@autoreleasepool {
cocoaView = cocoaCanvas = [[CocoaCanvas alloc] initWith:canvas];
setSize(canvas.size());
}
}
void pCanvas::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@ -0,0 +1,34 @@
@interface CocoaCanvas : NSImageView {
@public
phoenix::Canvas *canvas;
}
-(id) initWith:(phoenix::Canvas&)canvas;
-(void) mouseButton :(NSEvent*)event down:(BOOL)isDown;
-(void) mouseExited :(NSEvent*)event;
-(void) mouseMove :(NSEvent*)event;
-(void) mouseDown :(NSEvent*)event;
-(void) mouseUp :(NSEvent*)event;
-(void) mouseDragged :(NSEvent*)event;
-(void) rightMouseDown :(NSEvent*)event;
-(void) rightMouseUp :(NSEvent*)event;
-(void) rightMouseDragged :(NSEvent*)event;
-(void) otherMouseDown :(NSEvent*)event;
-(void) otherMouseUp :(NSEvent*)event;
-(void) otherMouseDragged :(NSEvent*)event;
@end
namespace phoenix {
struct pCanvas : public pWidget {
Canvas &canvas;
CocoaCanvas *cocoaCanvas;
void setSize(const Size &size);
void update();
pCanvas(Canvas &canvas) : pWidget(canvas), canvas(canvas) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,60 @@
@implementation CocoaCheckButton : NSButton
-(id) initWith :(phoenix::CheckButton&)checkButtonReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
checkButton = &checkButtonReference;
[self setTarget:self];
[self setAction:@selector(activate:)];
[self setButtonType:NSSwitchButton];
}
return self;
}
-(IBAction) activate :(id)sender {
checkButton->state.checked = [self state] != NSOffState;
if(checkButton->onToggle) checkButton->onToggle();
}
@end
namespace phoenix {
bool pCheckButton::checked() {
@autoreleasepool {
return [cocoaView state] != NSOffState;
}
}
Size pCheckButton::minimumSize() {
Size size = Font::size(checkButton.font(), checkButton.state.text);
return {size.width + 24, size.height + 8};
}
void pCheckButton::setChecked(bool checked) {
@autoreleasepool {
[cocoaView setState:checked ? NSOnState : NSOffState];
}
}
void pCheckButton::setText(const string &text) {
@autoreleasepool {
[cocoaView setTitle:[NSString stringWithUTF8String:text]];
}
}
void pCheckButton::constructor() {
@autoreleasepool {
cocoaView = cocoaCheckButton = [[CocoaCheckButton alloc] initWith:checkButton];
setChecked(checkButton.state.checked);
setText(checkButton.state.text);
}
}
void pCheckButton::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@ -0,0 +1,25 @@
@interface CocoaCheckButton : NSButton {
@public
phoenix::CheckButton *checkButton;
}
-(id) initWith :(phoenix::CheckButton&)checkButton;
-(IBAction) activate :(id)sender;
@end
namespace phoenix {
struct pCheckButton : public pWidget {
CheckButton &checkButton;
CocoaCheckButton *cocoaCheckButton;
bool checked();
Size minimumSize();
void setChecked(bool checked);
void setText(const string &text);
pCheckButton(CheckButton &checkButton) : pWidget(checkButton), checkButton(checkButton) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,76 @@
@implementation CocoaComboButton : NSPopUpButton
-(id) initWith :(phoenix::ComboButton&)comboButtonReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0) pullsDown:NO]) {
comboButton = &comboButtonReference;
[self setTarget:self];
[self setAction:@selector(activate:)];
}
return self;
}
-(IBAction) activate :(id)sender {
if(comboButton->onChange) comboButton->onChange();
}
@end
namespace phoenix {
void pComboButton::append(const string &text) {
@autoreleasepool {
[cocoaView addItemWithTitle:[NSString stringWithUTF8String:text]];
}
}
Size pComboButton::minimumSize() {
unsigned maximumWidth = 0;
for(auto &text : comboButton.state.text) maximumWidth = max(maximumWidth, Font::size(comboButton.font(), text).width);
Size size = Font::size(comboButton.font(), " ");
return {maximumWidth + 40, size.height + 8};
}
void pComboButton::modify(unsigned row, const string &text) {
@autoreleasepool {
[[cocoaView itemAtIndex:row] setTitle:[NSString stringWithUTF8String:text]];
}
}
void pComboButton::remove(unsigned row) {
@autoreleasepool {
[cocoaView removeItemAtIndex:row];
}
}
void pComboButton::reset() {
@autoreleasepool {
[cocoaView removeAllItems];
}
}
unsigned pComboButton::selection() {
@autoreleasepool {
return [cocoaView indexOfSelectedItem];
}
}
void pComboButton::setSelection(unsigned row) {
@autoreleasepool {
[cocoaView selectItemAtIndex:row];
}
}
void pComboButton::constructor() {
@autoreleasepool {
cocoaView = cocoaComboButton = [[CocoaComboButton alloc] initWith:comboButton];
}
}
void pComboButton::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@ -0,0 +1,28 @@
@interface CocoaComboButton : NSPopUpButton {
@public
phoenix::ComboButton *comboButton;
}
-(id) initWith :(phoenix::ComboButton&)comboButton;
-(IBAction) activate :(id)sender;
@end
namespace phoenix {
struct pComboButton : public pWidget {
ComboButton &comboButton;
CocoaComboButton *cocoaComboButton;
void append(const string &text);
Size minimumSize();
void modify(unsigned row, const string &text);
void remove(unsigned row);
void reset();
unsigned selection();
void setSelection(unsigned row);
pComboButton(ComboButton &comboButton) : pWidget(comboButton), comboButton(comboButton) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,21 @@
namespace phoenix {
void pHexEdit::setColumns(unsigned columns) {
}
void pHexEdit::setLength(unsigned length) {
}
void pHexEdit::setOffset(unsigned offset) {
}
void pHexEdit::setRows(unsigned rows) {
}
void pHexEdit::update() {
}
void pHexEdit::constructor() {
}
}

View File

@ -0,0 +1,16 @@
namespace phoenix {
struct pHexEdit : public pWidget {
HexEdit &hexEdit;
void setColumns(unsigned columns);
void setLength(unsigned length);
void setOffset(unsigned offset);
void setRows(unsigned rows);
void update();
pHexEdit(HexEdit &hexEdit) : pWidget(hexEdit), hexEdit(hexEdit) {}
void constructor();
};
}

View File

@ -0,0 +1,91 @@
@implementation CocoaHorizontalScroller : NSScroller
-(id) initWith :(phoenix::HorizontalScroller&)horizontalScrollerReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 1, 0)]) {
horizontalScroller = &horizontalScrollerReference;
[self setTarget:self];
[self setAction:@selector(scroll:)];
[self setControlSize:NSRegularControlSize];
[self setScrollerStyle:NSScrollerStyleLegacy];
[self setEnabled:YES];
[self update];
}
return self;
}
-(void) update {
double d = 1.0 / horizontalScroller->state.length;
double f = d * horizontalScroller->state.position;
[self setDoubleValue:f];
[self setKnobProportion:d];
}
-(IBAction) scroll :(id)sender {
auto &state = horizontalScroller->state;
switch([self hitPart]) {
case NSScrollerIncrementLine:
case NSScrollerIncrementPage:
if(state.position < state.length - 1) state.position++;
[self update];
break;
case NSScrollerDecrementLine:
case NSScrollerDecrementPage:
if(state.position) state.position--;
[self update];
break;
case NSScrollerKnob:
state.position = [self doubleValue] * state.length;
break;
}
if(horizontalScroller->onChange) horizontalScroller->onChange();
}
@end
namespace phoenix {
Size pHorizontalScroller::minimumSize() {
@autoreleasepool {
return {32, [NSScroller scrollerWidthForControlSize:NSRegularControlSize scrollerStyle:NSScrollerStyleLegacy]};
}
}
unsigned pHorizontalScroller::position() {
@autoreleasepool {
return [cocoaView doubleValue] * horizontalScroller.state.length;
}
}
void pHorizontalScroller::setLength(unsigned length) {
@autoreleasepool {
[cocoaView update];
}
}
void pHorizontalScroller::setPosition(unsigned position) {
@autoreleasepool {
[cocoaView update];
}
}
void pHorizontalScroller::constructor() {
@autoreleasepool {
cocoaView = cocoaHorizontalScroller = [[CocoaHorizontalScroller alloc] initWith:horizontalScroller];
}
}
void pHorizontalScroller::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@ -0,0 +1,26 @@
@interface CocoaHorizontalScroller : NSScroller {
@public
phoenix::HorizontalScroller *horizontalScroller;
}
-(id) initWith :(phoenix::HorizontalScroller&)horizontalScroller;
-(void) update;
-(IBAction) scroll :(id)sender;
@end
namespace phoenix {
struct pHorizontalScroller : public pWidget {
HorizontalScroller &horizontalScroller;
CocoaHorizontalScroller *cocoaHorizontalScroller;
Size minimumSize();
unsigned position();
void setLength(unsigned length);
void setPosition(unsigned position);
pHorizontalScroller(HorizontalScroller &horizontalScroller) : pWidget(horizontalScroller), horizontalScroller(horizontalScroller) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,60 @@
@implementation CocoaHorizontalSlider : NSSlider
-(id) initWith :(phoenix::HorizontalSlider&)horizontalSliderReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 1, 0)]) {
horizontalSlider = &horizontalSliderReference;
[self setTarget:self];
[self setAction:@selector(activate:)];
[self setMinValue:0];
}
return self;
}
-(IBAction) activate :(id)sender {
horizontalSlider->state.position = [self doubleValue];
if(horizontalSlider->onChange) horizontalSlider->onChange();
}
@end
namespace phoenix {
Size pHorizontalSlider::minimumSize() {
return {64, 24};
}
unsigned pHorizontalSlider::position() {
@autoreleasepool {
return [cocoaView doubleValue];
}
}
void pHorizontalSlider::setLength(unsigned length) {
@autoreleasepool {
[cocoaView setMaxValue:length];
}
}
void pHorizontalSlider::setPosition(unsigned position) {
@autoreleasepool {
[cocoaView setDoubleValue:position];
}
}
void pHorizontalSlider::constructor() {
@autoreleasepool {
cocoaView = cocoaHorizontalSlider = [[CocoaHorizontalSlider alloc] initWith:horizontalSlider];
setLength(horizontalSlider.state.length);
setPosition(horizontalSlider.state.position);
}
}
void pHorizontalSlider::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@ -0,0 +1,25 @@
@interface CocoaHorizontalSlider : NSSlider {
@public
phoenix::HorizontalSlider *horizontalSlider;
}
-(id) initWith :(phoenix::HorizontalSlider&)horizontalSlider;
-(IBAction) activate :(id)sender;
@end
namespace phoenix {
struct pHorizontalSlider : public pWidget {
HorizontalSlider &horizontalSlider;
CocoaHorizontalSlider *cocoaHorizontalSlider;
Size minimumSize();
unsigned position();
void setLength(unsigned length);
void setPosition(unsigned position);
pHorizontalSlider(HorizontalSlider &horizontalSlider) : pWidget(horizontalSlider), horizontalSlider(horizontalSlider) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,43 @@
@implementation CocoaLabel : NSTextField
-(id) initWith :(phoenix::Label&)labelReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
label = &labelReference;
[self setAlignment:NSLeftTextAlignment];
[self setBordered:NO];
[self setDrawsBackground:NO];
[self setEditable:NO];
}
return self;
}
@end
namespace phoenix {
Size pLabel::minimumSize() {
Size size = Font::size(label.font(), label.state.text);
return {size.width, size.height};
}
void pLabel::setText(const string &text) {
@autoreleasepool {
[cocoaView setStringValue:[NSString stringWithUTF8String:text]];
}
}
void pLabel::constructor() {
@autoreleasepool {
cocoaView = cocoaLabel = [[CocoaLabel alloc] initWith:label];
setText(label.state.text);
}
}
void pLabel::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@ -0,0 +1,22 @@
@interface CocoaLabel : NSTextField {
@public
phoenix::Label *label;
}
-(id) initWith :(phoenix::Label&)label;
@end
namespace phoenix {
struct pLabel : public pWidget {
Label &label;
CocoaLabel *cocoaLabel;
Size minimumSize();
void setText(const string &text);
pLabel(Label &label) : pWidget(label), label(label) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,9 @@
namespace phoenix {
struct pLayout : public pSizable {
Layout &layout;
pLayout(Layout &layout) : pSizable(layout), layout(layout) {}
};
}

View File

@ -0,0 +1,65 @@
@implementation CocoaLineEdit : NSTextField
-(id) initWith :(phoenix::LineEdit&)lineEditReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
lineEdit = &lineEditReference;
[self setDelegate:self];
[self setTarget:self];
[self setAction:@selector(activate:)];
//prevent focus changes from generating activate event
[[self cell] setSendsActionOnEndEditing:NO];
}
return self;
}
-(void) textDidChange :(NSNotification*)n {
if(lineEdit->onChange) lineEdit->onChange();
}
-(IBAction) activate :(id)sender {
if(lineEdit->onActivate) lineEdit->onActivate();
}
@end
namespace phoenix {
Size pLineEdit::minimumSize() {
Size size = Font::size(lineEdit.font(), lineEdit.state.text);
return {size.width + 10, size.height + 8};
}
void pLineEdit::setEditable(bool editable) {
@autoreleasepool {
[cocoaView setEditable:editable];
}
}
void pLineEdit::setText(const string &text) {
@autoreleasepool {
[cocoaView setStringValue:[NSString stringWithUTF8String:text]];
}
}
string pLineEdit::text() {
@autoreleasepool {
return [[cocoaView stringValue] UTF8String];
}
}
void pLineEdit::constructor() {
@autoreleasepool {
cocoaView = cocoaLineEdit = [[CocoaLineEdit alloc] initWith:lineEdit];
setEditable(lineEdit.state.editable);
}
}
void pLineEdit::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@ -0,0 +1,26 @@
@interface CocoaLineEdit : NSTextField <NSTextFieldDelegate> {
@public
phoenix::LineEdit *lineEdit;
}
-(id) initWith :(phoenix::LineEdit&)lineEdit;
-(void) textDidChange :(NSNotification*)n;
-(IBAction) activate :(id)sender;
@end
namespace phoenix {
struct pLineEdit : public pWidget {
LineEdit &lineEdit;
CocoaLineEdit *cocoaLineEdit;
Size minimumSize();
void setEditable(bool editable);
void setText(const string &text);
string text();
pLineEdit(LineEdit &lineEdit) : pWidget(lineEdit), lineEdit(lineEdit) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,326 @@
@implementation CocoaListView : NSScrollView
-(id) initWith :(phoenix::ListView&)listViewReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
listView = &listViewReference;
content = [[CocoaListViewContent alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)];
[self setDocumentView:content];
[self setBorderType:NSBezelBorder];
[self setHasVerticalScroller:YES];
[content setDataSource:self];
[content setDelegate:self];
[content setTarget:self];
[content setDoubleAction:@selector(activate:)];
[content setAllowsColumnReordering:NO];
[content setAllowsColumnResizing:YES];
[content setAllowsColumnSelection:NO];
[content setAllowsEmptySelection:YES];
[content setAllowsMultipleSelection:NO];
[content setColumnAutoresizingStyle:NSTableViewNoColumnAutoresizing];
font = nil;
[self setFont:nil];
}
return self;
}
-(void) dealloc {
[content release];
[font release];
[super dealloc];
}
-(CocoaListViewContent*) content {
return content;
}
-(NSFont*) font {
return font;
}
-(void) setFont :(NSFont*)fontPointer {
if(!fontPointer) fontPointer = [NSFont systemFontOfSize:12];
[fontPointer retain];
if(font) [font release];
font = fontPointer;
unsigned fontHeight = phoenix::pFont::size(font, " ").height;
[content setFont:font];
[content setRowHeight:fontHeight];
[self reloadColumns];
}
-(void) reloadColumns {
while([[content tableColumns] count]) {
[content removeTableColumn:[[content tableColumns] lastObject]];
}
if(listView->state.checkable) {
NSTableColumn *tableColumn = [[NSTableColumn alloc] initWithIdentifier:@"check"];
NSTableHeaderCell *headerCell = [[NSTableHeaderCell alloc] initTextCell:@""];
NSButtonCell *dataCell = [[NSButtonCell alloc] initTextCell:@""];
[dataCell setButtonType:NSSwitchButton];
[dataCell setControlSize:NSSmallControlSize];
[dataCell setRefusesFirstResponder:YES];
[tableColumn setResizingMask:NSTableColumnNoResizing];
[tableColumn setHeaderCell:headerCell];
[tableColumn setDataCell:dataCell];
[tableColumn setWidth:20.0];
[content addTableColumn:tableColumn];
}
lstring headers = listView->state.headerText;
if(headers.size() == 0) headers.append("");
[content setUsesAlternatingRowBackgroundColors:headers.size() >= 2];
for(unsigned column = 0; column < headers.size(); column++) {
NSTableColumn *tableColumn = [[NSTableColumn alloc] initWithIdentifier:[[NSNumber numberWithInteger:column] stringValue]];
NSTableHeaderCell *headerCell = [[NSTableHeaderCell alloc] initTextCell:[NSString stringWithUTF8String:headers(column)]];
CocoaListViewCell *dataCell = [[CocoaListViewCell alloc] initTextCell:@""];
[dataCell setEditable:NO];
[tableColumn setResizingMask:NSTableColumnAutoresizingMask | NSTableColumnUserResizingMask];
[tableColumn setHeaderCell:headerCell];
[tableColumn setDataCell:dataCell];
[content addTableColumn:tableColumn];
}
}
-(NSInteger) numberOfRowsInTableView :(NSTableView*)table {
return listView->state.text.size();
}
-(id) tableView :(NSTableView*)table objectValueForTableColumn :(NSTableColumn*)tableColumn row:(NSInteger)row {
if([[tableColumn identifier] isEqualToString:@"check"]) {
auto checked = listView->state.checked(row) ? NSOnState : NSOffState;
return [NSNumber numberWithInteger:checked];
}
NSInteger column = [[tableColumn identifier] integerValue];
unsigned height = [table rowHeight];
NSString *text = [NSString stringWithUTF8String:listView->state.text(row)(column)];
NSImage *image = NSMakeImage(listView->state.image(row)(column), height, height);
if(image) return @{ @"text":text, @"image":image };
return @{ @"text":text };
}
-(void) tableView :(NSTableView*)table setObjectValue:(id)object forTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row {
if([[tableColumn identifier] isEqualToString:@"check"]) {
listView->state.checked(row) = [object integerValue] != NSOffState;
if(listView->onToggle) listView->onToggle(row);
}
}
-(void) tableView :(NSTableView*)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row {
[cell setFont:[self font]];
}
-(void) tableViewSelectionDidChange :(NSNotification*)notification {
if(listView->onChange) listView->onChange();
}
-(IBAction) activate :(id)sender {
if([content clickedRow] < 0) return;
if(listView->onActivate) listView->onActivate();
}
@end
@implementation CocoaListViewContent : NSTableView
-(void) keyDown :(NSEvent*)event {
[super keyDown:event];
auto character = [[event characters] characterAtIndex:0];
if(character == NSEnterCharacter || character == NSCarriageReturnCharacter) {
[[self delegate] activate:self];
}
}
@end
@implementation CocoaListViewCell : NSTextFieldCell
//used by type-ahead
-(NSString*) stringValue {
return [[self objectValue] objectForKey:@"text"];
}
-(void) drawWithFrame :(NSRect)frame inView:(NSView*)view {
NSString *text = [[self objectValue] objectForKey:@"text"];
NSImage *image = [[self objectValue] objectForKey:@"image"];
unsigned textDisplacement = 0;
if(image) {
NSGraphicsContext *context = [NSGraphicsContext currentContext];
[context saveGraphicsState];
NSRect targetRect = NSMakeRect(frame.origin.x, frame.origin.y, frame.size.height, frame.size.height);
NSRect sourceRect = NSMakeRect(0, 0, [image size].width, [image size].height);
[image drawInRect:targetRect fromRect:sourceRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil];
[context restoreGraphicsState];
textDisplacement = frame.size.height + 2;
}
NSRect textRect = NSMakeRect(
frame.origin.x + textDisplacement, frame.origin.y,
frame.size.width - textDisplacement, frame.size.height
);
NSColor *textColor = [self isHighlighted]
? [NSColor alternateSelectedControlTextColor]
: [NSColor textColor];
[text drawInRect:textRect withAttributes:@{
NSForegroundColorAttributeName:textColor,
NSFontAttributeName:[self font]
}];
}
@end
namespace phoenix {
void pListView::append(const lstring &text) {
@autoreleasepool {
[[cocoaView content] reloadData];
}
}
void pListView::autoSizeColumns() {
@autoreleasepool {
if(listView.state.checkable) {
NSTableColumn *tableColumn = [[cocoaView content] tableColumnWithIdentifier:@"check"];
[tableColumn setWidth:20.0];
}
unsigned height = [[cocoaView content] rowHeight];
for(unsigned column = 0; column < listView.state.headerText.size(); column++) {
NSTableColumn *tableColumn = [[cocoaView content] tableColumnWithIdentifier:[[NSNumber numberWithInteger:column] stringValue]];
unsigned minimumWidth = pFont::size([[tableColumn headerCell] font], listView.state.headerText(column)).width + 4;
for(unsigned row = 0; row < listView.state.text.size(); row++) {
unsigned width = pFont::size([cocoaView font], listView.state.text(row)(column)).width + 2;
if(listView.state.image(row)(height).empty() == false) width += height + 2;
if(width > minimumWidth) minimumWidth = width;
}
[tableColumn setWidth:minimumWidth];
}
}
}
bool pListView::checked(unsigned row) {
return listView.state.checked(row);
}
void pListView::modify(unsigned row, const lstring &text) {
@autoreleasepool {
[[cocoaView content] reloadData];
}
}
void pListView::remove(unsigned row) {
@autoreleasepool {
[[cocoaView content] reloadData];
}
}
void pListView::reset() {
@autoreleasepool {
[[cocoaView content] reloadData];
}
}
bool pListView::selected() {
@autoreleasepool {
return [[cocoaView content] selectedRow] >= 0;
}
}
unsigned pListView::selection() {
if(selected() == false) return 0;
@autoreleasepool {
return [[cocoaView content] selectedRow];
}
}
void pListView::setCheckable(bool checkable) {
@autoreleasepool {
[cocoaView reloadColumns];
}
}
void pListView::setChecked(unsigned row, bool checked) {
@autoreleasepool {
[[cocoaView content] reloadData];
}
}
void pListView::setFont(const string &font) {
@autoreleasepool {
[cocoaView setFont:pFont::cocoaFont(font)];
}
}
void pListView::setHeaderText(const lstring &text) {
@autoreleasepool {
[cocoaView reloadColumns];
}
}
void pListView::setHeaderVisible(bool visible) {
@autoreleasepool {
if(visible) {
[[cocoaView content] setHeaderView:[[[NSTableHeaderView alloc] init] autorelease]];
} else {
[[cocoaView content] setHeaderView:nil];
}
}
}
void pListView::setImage(unsigned row, unsigned column, const image &image) {
@autoreleasepool {
[[cocoaView content] reloadData];
}
}
void pListView::setSelected(bool selected) {
@autoreleasepool {
if(selected == false) {
[[cocoaView content] deselectAll:nil];
}
}
}
void pListView::setSelection(unsigned row) {
@autoreleasepool {
[[cocoaView content] selectRowIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(row, 1)] byExtendingSelection:NO];
}
}
void pListView::constructor() {
@autoreleasepool {
cocoaView = cocoaListView = [[CocoaListView alloc] initWith:listView];
setHeaderVisible(listView.state.headerVisible);
setHeaderText(listView.state.headerText);
}
}
void pListView::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@ -0,0 +1,62 @@
@class CocoaListViewContent;
@interface CocoaListView : NSScrollView <NSTableViewDelegate, NSTableViewDataSource> {
@public
phoenix::ListView *listView;
CocoaListViewContent *content;
NSFont *font;
}
-(id) initWith :(phoenix::ListView&)listView;
-(void) dealloc;
-(CocoaListViewContent*) content;
-(NSFont*) font;
-(void) setFont :(NSFont*)font;
-(void) reloadColumns;
-(NSInteger) numberOfRowsInTableView :(NSTableView*)table;
-(id) tableView :(NSTableView*)table objectValueForTableColumn :(NSTableColumn*)tableColumn row:(NSInteger)row;
-(void) tableView :(NSTableView*)table setObjectValue:(id)object forTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row;
-(void) tableView :(NSTableView*)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row;
-(void) tableViewSelectionDidChange :(NSNotification*)notification;
-(IBAction) activate :(id)sender;
@end
@interface CocoaListViewContent : NSTableView {
}
-(void) keyDown :(NSEvent*)event;
@end
@interface CocoaListViewCell : NSTextFieldCell {
}
-(NSString*) stringValue;
-(void) drawWithFrame :(NSRect)frame inView:(NSView*)view;
@end
namespace phoenix {
struct pListView : public pWidget {
ListView &listView;
CocoaListView *cocoaListView;
void append(const lstring &text);
void autoSizeColumns();
bool checked(unsigned row);
void modify(unsigned row, const lstring &text);
void remove(unsigned row);
void reset();
bool selected();
unsigned selection();
void setCheckable(bool checkable);
void setChecked(unsigned row, bool checked);
void setFont(const string &font);
void setHeaderText(const lstring &text);
void setHeaderVisible(bool visible);
void setImage(unsigned row, unsigned column, const image &image);
void setSelected(bool selected);
void setSelection(unsigned row);
pListView(ListView &listView) : pWidget(listView), listView(listView) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,37 @@
@implementation CocoaProgressBar : NSProgressIndicator
-(id) initWith :(phoenix::ProgressBar&)progressBarReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
progressBar = &progressBarReference;
[self setIndeterminate:NO];
[self setMinValue:0.0];
[self setMaxValue:100.0];
}
return self;
}
@end
namespace phoenix {
void pProgressBar::setPosition(unsigned position) {
@autoreleasepool {
[cocoaView setDoubleValue:position];
}
}
void pProgressBar::constructor() {
@autoreleasepool {
cocoaView = cocoaProgressBar = [[CocoaProgressBar alloc] initWith:progressBar];
setPosition(progressBar.state.position);
}
}
void pProgressBar::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@ -0,0 +1,21 @@
@interface CocoaProgressBar : NSProgressIndicator {
@public
phoenix::ProgressBar *progressBar;
}
-(id) initWith :(phoenix::ProgressBar&)progressBar;
@end
namespace phoenix {
struct pProgressBar : public pWidget {
ProgressBar &progressBar;
CocoaProgressBar *cocoaProgressBar;
void setPosition(unsigned position);
pProgressBar(ProgressBar &progressBar) : pWidget(progressBar), progressBar(progressBar) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,64 @@
@implementation CocoaRadioButton : NSButton
-(id) initWith :(phoenix::RadioButton&)radioButtonReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
radioButton = &radioButtonReference;
[self setTarget:self];
[self setAction:@selector(activate:)];
[self setButtonType:NSRadioButton];
}
return self;
}
-(IBAction) activate :(id)sender {
radioButton->setChecked();
if(radioButton->onActivate) radioButton->onActivate();
}
@end
namespace phoenix {
bool pRadioButton::checked() {
@autoreleasepool {
return [cocoaView state] != NSOffState;
}
}
Size pRadioButton::minimumSize() {
Size size = Font::size(radioButton.font(), radioButton.state.text);
return {size.width + 24, size.height + 8};
}
void pRadioButton::setChecked() {
@autoreleasepool {
for(auto &button : radioButton.state.group) {
auto state = (&button == &radioButton) ? NSOnState : NSOffState;
[button.p.cocoaView setState:state];
}
}
}
void pRadioButton::setGroup(const set<RadioButton&> &group) {
}
void pRadioButton::setText(const string &text) {
@autoreleasepool {
[cocoaView setTitle:[NSString stringWithUTF8String:text]];
}
}
void pRadioButton::constructor() {
@autoreleasepool {
cocoaView = cocoaRadioButton = [[CocoaRadioButton alloc] initWith:radioButton];
}
}
void pRadioButton::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@ -0,0 +1,25 @@
@interface CocoaRadioButton : NSButton {
@public
phoenix::RadioButton *radioButton;
}
-(id) initWith :(phoenix::RadioButton&)radioButton;
@end
namespace phoenix {
struct pRadioButton : public pWidget {
RadioButton &radioButton;
CocoaRadioButton *cocoaRadioButton;
bool checked();
Size minimumSize();
void setChecked();
void setGroup(const set<RadioButton&> &group);
void setText(const string &text);
pRadioButton(RadioButton &radioButton) : pWidget(radioButton), radioButton(radioButton) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,9 @@
namespace phoenix {
struct pSizable : public pObject {
Sizable &sizable;
pSizable(Sizable &sizable) : pObject(sizable), sizable(sizable) {}
};
}

View File

@ -0,0 +1,101 @@
@implementation CocoaTextEdit : NSScrollView
-(id) initWith :(phoenix::TextEdit&)textEditReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
textEdit = &textEditReference;
content = [[[NSTextView alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)] autorelease];
[content setDelegate:self];
[content setRichText:NO];
[self setBorderType:NSBezelBorder];
[self setDocumentView:content];
[self configure];
}
return self;
}
-(NSTextView*) content {
return content;
}
-(void) configure {
[content setMinSize:NSMakeSize(0, 0)];
[content setMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)];
[[content textContainer] setContainerSize:NSMakeSize(FLT_MAX, FLT_MAX)];
[[content textContainer] setWidthTracksTextView:textEdit->wordWrap()];
[content setHorizontallyResizable:YES];
[content setVerticallyResizable:YES];
[content setAutoresizingMask:NSViewNotSizable];
[self setHasHorizontalScroller:!textEdit->wordWrap()];
[self setHasVerticalScroller:YES];
}
-(void) textDidChange :(NSNotification*)notification {
textEdit->state.text = [[content string] UTF8String];
if(textEdit->onChange) textEdit->onChange();
}
@end
namespace phoenix {
void pTextEdit::setCursorPosition(unsigned position) {
@autoreleasepool {
string text = [[[cocoaView content] string] UTF8String];
position = min(position, text.length());
[[cocoaView content] setSelectedRange:NSMakeRange(position, 0)];
}
}
void pTextEdit::setEditable(bool editable) {
@autoreleasepool {
[[cocoaView content] setEditable:editable];
}
}
void pTextEdit::setFont(const string &font) {
@autoreleasepool {
[[cocoaView content] setFont:pFont::cocoaFont(font)];
}
}
void pTextEdit::setText(const string &text) {
@autoreleasepool {
[[cocoaView content] setString:[NSString stringWithUTF8String:text]];
}
}
void pTextEdit::setWordWrap(bool wordWrap) {
@autoreleasepool {
[cocoaView configure];
}
}
string pTextEdit::text() {
@autoreleasepool {
return [[[cocoaView content] string] UTF8String];
}
}
void pTextEdit::constructor() {
@autoreleasepool {
cocoaView = cocoaTextEdit = [[CocoaTextEdit alloc] initWith:textEdit];
setEditable(textEdit.state.editable);
setWordWrap(textEdit.state.wordWrap);
setFont(textEdit.font());
setText(textEdit.state.text);
setCursorPosition(textEdit.state.cursorPosition);
}
}
void pTextEdit::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@ -0,0 +1,30 @@
@interface CocoaTextEdit : NSScrollView <NSTextViewDelegate> {
@public
phoenix::TextEdit *textEdit;
NSTextView *content;
}
-(id) initWith :(phoenix::TextEdit&)textEdit;
-(NSTextView*) content;
-(void) configure;
-(void) textDidChange :(NSNotification*)notification;
@end
namespace phoenix {
struct pTextEdit : public pWidget {
TextEdit &textEdit;
CocoaTextEdit *cocoaTextEdit;
void setCursorPosition(unsigned position);
void setEditable(bool editable);
void setFont(const string &font);
void setText(const string &text);
void setWordWrap(bool wordWrap);
string text();
pTextEdit(TextEdit &textEdit) : pWidget(textEdit), textEdit(textEdit) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,91 @@
@implementation CocoaVerticalScroller : NSScroller
-(id) initWith :(phoenix::VerticalScroller&)verticalScrollerReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 1)]) {
verticalScroller = &verticalScrollerReference;
[self setTarget:self];
[self setAction:@selector(scroll:)];
[self setControlSize:NSRegularControlSize];
[self setScrollerStyle:NSScrollerStyleLegacy];
[self setEnabled:YES];
[self update];
}
return self;
}
-(void) update {
double d = 1.0 / verticalScroller->state.length;
double f = d * verticalScroller->state.position;
[self setDoubleValue:f];
[self setKnobProportion:d];
}
-(IBAction) scroll :(id)sender {
auto &state = verticalScroller->state;
switch([self hitPart]) {
case NSScrollerIncrementLine:
case NSScrollerIncrementPage:
if(state.position < state.length - 1) state.position++;
[self update];
break;
case NSScrollerDecrementLine:
case NSScrollerDecrementPage:
if(state.position) state.position--;
[self update];
break;
case NSScrollerKnob:
state.position = [self doubleValue] * state.length;
break;
}
if(verticalScroller->onChange) verticalScroller->onChange();
}
@end
namespace phoenix {
Size pVerticalScroller::minimumSize() {
@autoreleasepool {
return {[NSScroller scrollerWidthForControlSize:NSRegularControlSize scrollerStyle:NSScrollerStyleLegacy], 32};
}
}
unsigned pVerticalScroller::position() {
@autoreleasepool {
return [cocoaView doubleValue] * verticalScroller.state.length;
}
}
void pVerticalScroller::setLength(unsigned length) {
@autoreleasepool {
[cocoaView update];
}
}
void pVerticalScroller::setPosition(unsigned position) {
@autoreleasepool {
[cocoaView update];
}
}
void pVerticalScroller::constructor() {
@autoreleasepool {
cocoaView = cocoaVerticalScroller = [[CocoaVerticalScroller alloc] initWith:verticalScroller];
}
}
void pVerticalScroller::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@ -0,0 +1,24 @@
@interface CocoaVerticalScroller : NSScroller {
@public
phoenix::VerticalScroller *verticalScroller;
}
-(id) initWith :(phoenix::VerticalScroller&)verticalScroller;
@end
namespace phoenix {
struct pVerticalScroller : public pWidget {
VerticalScroller &verticalScroller;
CocoaVerticalScroller *cocoaVerticalScroller;
Size minimumSize();
unsigned position();
void setLength(unsigned length);
void setPosition(unsigned position);
pVerticalScroller(VerticalScroller &verticalScroller) : pWidget(verticalScroller), verticalScroller(verticalScroller) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,60 @@
@implementation CocoaVerticalSlider : NSSlider
-(id) initWith :(phoenix::VerticalSlider&)verticalSliderReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 1)]) {
verticalSlider = &verticalSliderReference;
[self setTarget:self];
[self setAction:@selector(activate:)];
[self setMinValue:0];
}
return self;
}
-(IBAction) activate :(id)sender {
verticalSlider->state.position = [self doubleValue];
if(verticalSlider->onChange) verticalSlider->onChange();
}
@end
namespace phoenix {
Size pVerticalSlider::minimumSize() {
return {24, 64};
}
unsigned pVerticalSlider::position() {
@autoreleasepool {
return [cocoaView doubleValue];
}
}
void pVerticalSlider::setLength(unsigned length) {
@autoreleasepool {
[cocoaView setMaxValue:length];
}
}
void pVerticalSlider::setPosition(unsigned position) {
@autoreleasepool {
[cocoaView setDoubleValue:position];
}
}
void pVerticalSlider::constructor() {
@autoreleasepool {
cocoaView = cocoaVerticalSlider = [[CocoaVerticalSlider alloc] initWith:verticalSlider];
setLength(verticalSlider.state.length);
setPosition(verticalSlider.state.position);
}
}
void pVerticalSlider::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@ -0,0 +1,25 @@
@interface CocoaVerticalSlider : NSSlider {
@public
phoenix::VerticalSlider *verticalSlider;
}
-(id) initWith :(phoenix::VerticalSlider&)verticalSlider;
-(IBAction) activate :(id)sender;
@end
namespace phoenix {
struct pVerticalSlider : public pWidget {
VerticalSlider &verticalSlider;
CocoaVerticalSlider *cocoaVerticalSlider;
Size minimumSize();
unsigned position();
void setLength(unsigned length);
void setPosition(unsigned position);
pVerticalSlider(VerticalSlider &verticalSlider) : pWidget(verticalSlider), verticalSlider(verticalSlider) {}
void constructor();
void destructor();
};
}

View File

@ -0,0 +1,10 @@
namespace phoenix {
uintptr_t pViewport::handle() {
return 0;
}
void pViewport::constructor() {
}
}

View File

@ -0,0 +1,12 @@
namespace phoenix {
struct pViewport : public pWidget {
Viewport &viewport;
uintptr_t handle();
pViewport(Viewport &viewport) : pWidget(viewport), viewport(viewport) {}
void constructor();
};
}

View File

@ -0,0 +1,76 @@
namespace phoenix {
bool pWidget::enabled() {
@autoreleasepool {
return [cocoaView respondsToSelector:@selector(enabled)] && [cocoaView enabled];
}
}
bool pWidget::focused() {
@autoreleasepool {
return cocoaView == [[cocoaView window] firstResponder];
}
}
Size pWidget::minimumSize() {
return {0, 0};
}
void pWidget::setEnabled(bool enabled) {
if(widget.state.abstract) enabled = false;
if(sizable.state.layout && sizable.state.layout->enabled() == false) enabled = false;
@autoreleasepool {
if([cocoaView respondsToSelector:@selector(setEnabled:)]) {
[cocoaView setEnabled:enabled];
}
}
}
void pWidget::setFocused() {
@autoreleasepool {
[[cocoaView window] makeFirstResponder:cocoaView];
}
}
void pWidget::setFont(const string &font) {
@autoreleasepool {
if([cocoaView respondsToSelector:@selector(setFont:)]) {
[cocoaView setFont:pFont::cocoaFont(font)];
}
}
}
void pWidget::setGeometry(const Geometry &geometry) {
@autoreleasepool {
CGFloat windowHeight = [[cocoaView superview] frame].size.height;
[cocoaView setFrame:NSMakeRect(geometry.x, windowHeight - geometry.y - geometry.height, geometry.width, geometry.height)];
[[cocoaView superview] setNeedsDisplay:YES];
}
}
void pWidget::setVisible(bool visible) {
if(widget.state.abstract) visible = false;
if(sizable.state.layout && sizable.state.layout->visible() == false) visible = false;
@autoreleasepool {
[cocoaView setHidden:!visible];
}
}
void pWidget::constructor() {
if(!widget.state.abstract) return;
@autoreleasepool {
cocoaView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)];
[cocoaView setHidden:true];
}
}
void pWidget::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

Some files were not shown because too many files have changed in this diff Show More