mirror of https://github.com/bsnes-emu/bsnes.git
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:
parent
d9400084c2
commit
b7c212de7e
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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) {
|
||||
for(unsigned c = 0; c < this->channels; c++) {
|
||||
if(sample[c]) delete[] sample[c];
|
||||
if(sample) {
|
||||
for(unsigned c = 0; c < this->channels; c++) {
|
||||
if(sample[c]) delete[] sample[c];
|
||||
}
|
||||
delete[] sample;
|
||||
}
|
||||
if(sample) delete[] sample;
|
||||
|
||||
this->channels = channels;
|
||||
if(channels == 0) return;
|
||||
|
@ -40,7 +42,6 @@ struct Buffer {
|
|||
}
|
||||
|
||||
Buffer() {
|
||||
channels = 0;
|
||||
}
|
||||
|
||||
~Buffer() {
|
||||
|
|
|
@ -69,7 +69,7 @@ protected:
|
|||
real intensityInverse;
|
||||
} settings;
|
||||
|
||||
Resampler *resampler;
|
||||
Resampler *resampler = nullptr;
|
||||
inline void write(real channel[]);
|
||||
|
||||
#include "buffer.hpp"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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; } }
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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] =
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -172,13 +172,13 @@ bool png::decode(const uint8_t *sourceData, unsigned sourceSize) {
|
|||
unsigned png::interlace(unsigned pass, unsigned index) {
|
||||
static const unsigned data[7][4] = {
|
||||
//x-distance, y-distance, x-origin, y-origin
|
||||
{ 8, 8, 0, 0 },
|
||||
{ 8, 8, 4, 0 },
|
||||
{ 4, 8, 0, 4 },
|
||||
{ 4, 4, 2, 0 },
|
||||
{ 2, 4, 0, 2 },
|
||||
{ 2, 2, 1, 0 },
|
||||
{ 1, 2, 0, 1 },
|
||||
{8, 8, 0, 0},
|
||||
{8, 8, 4, 0},
|
||||
{4, 8, 0, 4},
|
||||
{4, 4, 2, 0},
|
||||
{2, 4, 0, 2},
|
||||
{2, 2, 1, 0},
|
||||
{1, 2, 0, 1},
|
||||
};
|
||||
return data[pass][index];
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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*> {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace nall {
|
||||
|
||||
string string::date() {
|
||||
time_t timestamp = ::time(0);
|
||||
time_t timestamp = ::time(nullptr);
|
||||
tm *info = localtime(×tamp);
|
||||
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(×tamp);
|
||||
return {
|
||||
decimal<2, '0'>(info->tm_hour), ":",
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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(¤tTime);
|
||||
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);
|
||||
|
|
|
@ -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() {
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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]];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace phoenix {
|
||||
|
||||
struct pDesktop {
|
||||
static Size size();
|
||||
static Geometry workspace();
|
||||
};
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
|
@ -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};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
#define decimal CocoaDecimal
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
#undef decimal
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace phoenix {
|
||||
|
||||
struct pKeyboard {
|
||||
static bool pressed(Keyboard::Scancode scancode);
|
||||
static vector<bool> state();
|
||||
};
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
namespace phoenix {
|
||||
|
||||
Position pMouse::position() {
|
||||
return {0, 0};
|
||||
}
|
||||
|
||||
bool pMouse::pressed(Mouse::Button button) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace phoenix {
|
||||
|
||||
struct pMouse {
|
||||
static Position position();
|
||||
static bool pressed(Mouse::Button button);
|
||||
};
|
||||
|
||||
}
|
|
@ -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() {}
|
||||
};
|
||||
|
||||
}
|
|
@ -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"
|
|
@ -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"
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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() {
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
namespace phoenix {
|
||||
|
||||
struct pLayout : public pSizable {
|
||||
Layout &layout;
|
||||
|
||||
pLayout(Layout &layout) : pSizable(layout), layout(layout) {}
|
||||
};
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
namespace phoenix {
|
||||
|
||||
struct pSizable : public pObject {
|
||||
Sizable &sizable;
|
||||
|
||||
pSizable(Sizable &sizable) : pObject(sizable), sizable(sizable) {}
|
||||
};
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace phoenix {
|
||||
|
||||
uintptr_t pViewport::handle() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pViewport::constructor() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace phoenix {
|
||||
|
||||
struct pViewport : public pWidget {
|
||||
Viewport &viewport;
|
||||
|
||||
uintptr_t handle();
|
||||
|
||||
pViewport(Viewport &viewport) : pWidget(viewport), viewport(viewport) {}
|
||||
void constructor();
|
||||
};
|
||||
|
||||
}
|
|
@ -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
Loading…
Reference in New Issue