mirror of https://github.com/bsnes-emu/bsnes.git
Update to v093r03 release.
byuu says: Updated to support latest phoenix changes. Converted Settings and Tools to TabFrame views. Errata: - phoenix/Windows ComboButton wasn't calling parent pWidget::setGeometry() [fixed locally] - TRACKBAR_CLASS draws COLOR_3DFACE for the background even when its parent is a WC_TABCONTROL
This commit is contained in:
parent
8c0b0fa4ad
commit
68eaf53691
|
@ -3,7 +3,7 @@
|
|||
|
||||
namespace Emulator {
|
||||
static const char Name[] = "higan";
|
||||
static const char Version[] = "093.02";
|
||||
static const char Version[] = "093.03";
|
||||
static const char Author[] = "byuu";
|
||||
static const char License[] = "GPLv3";
|
||||
static const char Website[] = "http://byuu.org/";
|
||||
|
|
|
@ -41,7 +41,7 @@ ifeq ($(compiler),)
|
|||
flags :=
|
||||
link :=
|
||||
else ifeq ($(platform),macosx)
|
||||
compiler := clang
|
||||
compiler := clang++
|
||||
flags := -w -stdlib=libc++
|
||||
link := -lc++ -lobjc
|
||||
else ifeq ($(platform),bsd)
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include <nall/string.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
#if defined(PLATFORM_X) || defined(PLATFORM_OSX)
|
||||
#if defined(PLATFORM_X) || defined(PLATFORM_MACOSX)
|
||||
#include <dlfcn.h>
|
||||
#elif defined(PLATFORM_WINDOWS)
|
||||
#include <windows.h>
|
||||
|
@ -59,7 +59,7 @@ inline void library::close() {
|
|||
dlclose((void*)handle);
|
||||
handle = 0;
|
||||
}
|
||||
#elif defined(PLATFORM_OSX)
|
||||
#elif defined(PLATFORM_MACOSX)
|
||||
inline bool library::open(const string& name, const string& path) {
|
||||
if(handle) close();
|
||||
handle = (uintptr_t)dlopen(string(path, !path.empty() && !path.endswith("/") ? "/" : "", "lib", name, ".dylib"), RTLD_LAZY);
|
||||
|
|
432
nall/image.hpp
432
nall/image.hpp
|
@ -11,13 +11,14 @@
|
|||
namespace nall {
|
||||
|
||||
struct image {
|
||||
uint8_t* data = nullptr;
|
||||
unsigned width = 0;
|
||||
uint8_t* data = nullptr;
|
||||
unsigned width = 0;
|
||||
unsigned height = 0;
|
||||
unsigned pitch = 0;
|
||||
unsigned pitch = 0;
|
||||
unsigned size = 0;
|
||||
|
||||
bool endian = 0;
|
||||
unsigned depth = 32;
|
||||
bool endian = 0; //0 = lsb, 1 = msb
|
||||
unsigned depth = 32;
|
||||
unsigned stride = 4;
|
||||
|
||||
struct Channel {
|
||||
|
@ -34,10 +35,18 @@ struct image {
|
|||
}
|
||||
};
|
||||
|
||||
Channel alpha = {255u << 24, 8u, 24};
|
||||
Channel red = {255u << 16, 8u, 16};
|
||||
Channel green = {255u << 8, 8u, 8};
|
||||
Channel blue = {255u << 0, 8u, 0};
|
||||
enum class blend : unsigned {
|
||||
add,
|
||||
sourceAlpha, //color = sourceColor * sourceAlpha + targetColor * (1 - sourceAlpha)
|
||||
sourceColor, //color = sourceColor
|
||||
targetAlpha, //color = targetColor * targetAlpha + sourceColor * (1 - targetAlpha)
|
||||
targetColor, //color = targetColor
|
||||
};
|
||||
|
||||
Channel alpha = {255u << 24, 8u, 24u};
|
||||
Channel red = {255u << 16, 8u, 16u};
|
||||
Channel green = {255u << 8, 8u, 8u};
|
||||
Channel blue = {255u << 0, 8u, 0u};
|
||||
|
||||
typedef double (*interpolation)(double, double, double, double, double);
|
||||
static inline unsigned bitDepth(uint64_t color);
|
||||
|
@ -63,18 +72,27 @@ struct image {
|
|||
inline void free();
|
||||
inline bool empty() const;
|
||||
inline void allocate(unsigned width, unsigned height);
|
||||
inline void clear(uint64_t color);
|
||||
inline bool crop(unsigned x, unsigned y, unsigned width, unsigned height);
|
||||
inline void impose(blend mode, unsigned targetX, unsigned targetY, image source, unsigned x, unsigned y, unsigned width, unsigned height);
|
||||
inline void fill(uint64_t color = 0);
|
||||
inline void gradient(uint64_t a, uint64_t b, uint64_t c, uint64_t d);
|
||||
inline void horizontalGradient(uint64_t a, uint64_t b);
|
||||
inline void verticalGradient(uint64_t a, uint64_t b);
|
||||
inline bool load(const string& filename);
|
||||
//inline bool loadBMP(const uint8_t* data, unsigned size);
|
||||
inline bool loadPNG(const uint8_t* data, unsigned size);
|
||||
inline void scale(unsigned width, unsigned height, interpolation op);
|
||||
inline void scale(unsigned width, unsigned height, bool linear = true);
|
||||
inline void transform(bool endian, unsigned depth, uint64_t alphaMask, uint64_t redMask, uint64_t greenMask, uint64_t blueMask);
|
||||
inline void alphaBlend(uint64_t alphaColor);
|
||||
|
||||
protected:
|
||||
inline uint64_t interpolate(double mu, const uint64_t* s, interpolation op);
|
||||
inline void scaleX(unsigned width, interpolation op);
|
||||
inline void scaleY(unsigned height, interpolation op);
|
||||
inline uint8_t* allocate(unsigned width, unsigned height, unsigned stride);
|
||||
alwaysinline uint64_t interpolate1D(int64_t a, int64_t b, uint32_t x);
|
||||
alwaysinline uint64_t interpolate2D(int64_t a, int64_t b, int64_t c, int64_t d, uint32_t x, uint32_t y);
|
||||
inline void scaleLinearWidth(unsigned width);
|
||||
inline void scaleLinearHeight(unsigned height);
|
||||
inline void scaleLinear(unsigned width, unsigned height);
|
||||
inline void scaleNearest(unsigned width, unsigned height);
|
||||
inline bool loadBMP(const string& filename);
|
||||
inline bool loadPNG(const string& filename);
|
||||
};
|
||||
|
@ -131,6 +149,7 @@ image& image::operator=(const image& source) {
|
|||
width = source.width;
|
||||
height = source.height;
|
||||
pitch = source.pitch;
|
||||
size = source.size;
|
||||
|
||||
endian = source.endian;
|
||||
stride = source.stride;
|
||||
|
@ -140,8 +159,8 @@ image& image::operator=(const image& source) {
|
|||
green = source.green;
|
||||
blue = source.blue;
|
||||
|
||||
data = new uint8_t[width * height * stride];
|
||||
memcpy(data, source.data, width * height * stride);
|
||||
data = allocate(width, height, stride);
|
||||
memcpy(data, source.data, source.size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -151,6 +170,7 @@ image& image::operator=(image&& source) {
|
|||
width = source.width;
|
||||
height = source.height;
|
||||
pitch = source.pitch;
|
||||
size = source.size;
|
||||
|
||||
endian = source.endian;
|
||||
stride = source.stride;
|
||||
|
@ -175,13 +195,13 @@ image::image(image&& source) {
|
|||
|
||||
image::image(bool endian, unsigned depth, uint64_t alphaMask, uint64_t redMask, uint64_t greenMask, uint64_t blueMask) {
|
||||
this->endian = endian;
|
||||
this->depth = depth;
|
||||
this->depth = depth;
|
||||
this->stride = (depth / 8) + ((depth & 7) > 0);
|
||||
|
||||
alpha = {alphaMask, bitDepth(alphaMask), bitShift(alphaMask)};
|
||||
red = {redMask, bitDepth(redMask), bitShift(redMask)};
|
||||
red = {redMask, bitDepth(redMask), bitShift(redMask )};
|
||||
green = {greenMask, bitDepth(greenMask), bitShift(greenMask)};
|
||||
blue = {blueMask, bitDepth(blueMask), bitShift(blueMask)};
|
||||
blue = {blueMask, bitDepth(blueMask), bitShift(blueMask )};
|
||||
}
|
||||
|
||||
image::image(const string& filename) {
|
||||
|
@ -231,39 +251,175 @@ bool image::empty() const {
|
|||
void image::allocate(unsigned width, unsigned height) {
|
||||
if(data != nullptr && this->width == width && this->height == height) return;
|
||||
free();
|
||||
data = new uint8_t[width * height * stride]();
|
||||
data = allocate(width, height, stride);
|
||||
pitch = width * stride;
|
||||
size = height * pitch;
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
}
|
||||
|
||||
void image::clear(uint64_t color) {
|
||||
uint8_t *dp = data;
|
||||
void image::fill(uint64_t color) {
|
||||
uint8_t* dp = data;
|
||||
for(unsigned n = 0; n < width * height; n++) {
|
||||
write(dp, color);
|
||||
dp += stride;
|
||||
}
|
||||
}
|
||||
|
||||
void image::gradient(uint64_t a, uint64_t b, uint64_t c, uint64_t d) {
|
||||
//create gradient by scaling 2x2 image using linear interpolation
|
||||
//replace data with gradient data to prevent extra copy
|
||||
delete[] data;
|
||||
nall::image gradient;
|
||||
gradient.endian = endian, gradient.depth = depth, gradient.stride = stride;
|
||||
gradient.alpha = alpha, gradient.red = red, gradient.green = green, gradient.blue = blue;
|
||||
gradient.allocate(2, 2);
|
||||
uint8_t* dp = gradient.data;
|
||||
gradient.write(dp, a); dp += stride;
|
||||
gradient.write(dp, b); dp += stride;
|
||||
gradient.write(dp, c); dp += stride;
|
||||
gradient.write(dp, d); dp += stride;
|
||||
gradient.scale(width, height);
|
||||
data = gradient.data;
|
||||
gradient.data = nullptr;
|
||||
}
|
||||
|
||||
void image::horizontalGradient(uint64_t a, uint64_t b) {
|
||||
gradient(a, b, a, b);
|
||||
}
|
||||
|
||||
void image::verticalGradient(uint64_t a, uint64_t b) {
|
||||
gradient(a, a, b, b);
|
||||
}
|
||||
|
||||
bool image::load(const string& filename) {
|
||||
if(loadBMP(filename) == true) return true;
|
||||
if(loadPNG(filename) == true) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void image::scale(unsigned outputWidth, unsigned outputHeight, interpolation op) {
|
||||
if(width != outputWidth) scaleX(outputWidth, op);
|
||||
if(height != outputHeight) scaleY(outputHeight, op);
|
||||
bool image::crop(unsigned outputX, unsigned outputY, unsigned outputWidth, unsigned outputHeight) {
|
||||
if(outputX + outputWidth > width) return false;
|
||||
if(outputY + outputHeight > height) return false;
|
||||
|
||||
uint8_t* outputData = allocate(outputWidth, outputHeight, stride);
|
||||
unsigned outputPitch = outputWidth * stride;
|
||||
|
||||
#pragma omp parallel for
|
||||
for(unsigned y = 0; y < outputHeight; y++) {
|
||||
const uint8_t* sp = data + pitch * (outputY + y) + stride * outputX;
|
||||
uint8_t* dp = outputData + outputPitch * y;
|
||||
for(unsigned x = 0; x < outputWidth; x++) {
|
||||
write(dp, read(sp));
|
||||
sp += stride;
|
||||
dp += stride;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] data;
|
||||
data = outputData;
|
||||
width = outputWidth;
|
||||
height = outputHeight;
|
||||
pitch = outputPitch;
|
||||
size = width * pitch;
|
||||
return true;
|
||||
}
|
||||
|
||||
void image::impose(blend mode, unsigned targetX, unsigned targetY, image source, unsigned sourceX, unsigned sourceY, unsigned sourceWidth, unsigned sourceHeight) {
|
||||
source.transform(endian, depth, alpha.mask, red.mask, green.mask, blue.mask);
|
||||
|
||||
for(unsigned y = 0; y < sourceHeight; y++) {
|
||||
const uint8_t* sp = source.data + source.pitch * (sourceY + y) + source.stride * sourceX;
|
||||
uint8_t* dp = data + pitch * (targetY + y) + stride * targetX;
|
||||
for(unsigned x = 0; x < sourceWidth; x++) {
|
||||
uint64_t sourceColor = source.read(sp);
|
||||
uint64_t targetColor = read(dp);
|
||||
|
||||
int64_t sa = (sourceColor & alpha.mask) >> alpha.shift;
|
||||
int64_t sr = (sourceColor & red.mask ) >> red.shift;
|
||||
int64_t sg = (sourceColor & green.mask) >> green.shift;
|
||||
int64_t sb = (sourceColor & blue.mask ) >> blue.shift;
|
||||
|
||||
int64_t da = (targetColor & alpha.mask) >> alpha.shift;
|
||||
int64_t dr = (targetColor & red.mask ) >> red.shift;
|
||||
int64_t dg = (targetColor & green.mask) >> green.shift;
|
||||
int64_t db = (targetColor & blue.mask ) >> blue.shift;
|
||||
|
||||
uint64_t a, r, g, b;
|
||||
|
||||
switch(mode) {
|
||||
case blend::add:
|
||||
a = max(sa, da);
|
||||
r = min(red.mask >> red.shift, ((sr * sa) >> alpha.depth) + ((dr * da) >> alpha.depth));
|
||||
g = min(green.mask >> green.shift, ((sg * sa) >> alpha.depth) + ((dg * da) >> alpha.depth));
|
||||
b = min(blue.mask >> blue.shift, ((sb * sa) >> alpha.depth) + ((db * da) >> alpha.depth));
|
||||
break;
|
||||
|
||||
case blend::sourceAlpha:
|
||||
a = max(sa, da);
|
||||
r = dr + (((sr - dr) * sa) >> alpha.depth);
|
||||
g = dg + (((sg - dg) * sa) >> alpha.depth);
|
||||
b = db + (((sb - db) * sa) >> alpha.depth);
|
||||
break;
|
||||
|
||||
case blend::sourceColor:
|
||||
a = sa;
|
||||
r = sr;
|
||||
g = sg;
|
||||
b = sb;
|
||||
break;
|
||||
|
||||
case blend::targetAlpha:
|
||||
a = max(sa, da);
|
||||
r = sr + (((dr - sr) * da) >> alpha.depth);
|
||||
g = sg + (((dg - sg) * da) >> alpha.depth);
|
||||
b = sb + (((db - sb) * da) >> alpha.depth);
|
||||
break;
|
||||
|
||||
case blend::targetColor:
|
||||
a = da;
|
||||
r = dr;
|
||||
g = dg;
|
||||
b = db;
|
||||
break;
|
||||
}
|
||||
|
||||
write(dp, (a << alpha.shift) | (r << red.shift) | (g << green.shift) | (b << blue.shift));
|
||||
sp += source.stride;
|
||||
dp += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void image::scale(unsigned outputWidth, unsigned outputHeight, bool linear) {
|
||||
if(width == outputWidth && height == outputHeight) return; //no scaling necessary
|
||||
if(linear == false) return scaleNearest(outputWidth, outputHeight);
|
||||
|
||||
if(width == outputWidth ) return scaleLinearHeight(outputHeight);
|
||||
if(height == outputHeight) return scaleLinearWidth(outputWidth);
|
||||
|
||||
//find fastest scaling method, based on number of interpolation operations required
|
||||
//magnification usually benefits from two-pass linear interpolation
|
||||
//minification usually benefits from one-pass bilinear interpolation
|
||||
unsigned d1wh = ((width * outputWidth ) + (outputWidth * outputHeight)) * 1;
|
||||
unsigned d1hw = ((height * outputHeight) + (outputWidth * outputHeight)) * 1;
|
||||
unsigned d2wh = (outputWidth * outputHeight) * 3;
|
||||
|
||||
if(d1wh <= d1hw && d1wh <= d2wh) return scaleLinearWidth(outputWidth), scaleLinearHeight(outputHeight);
|
||||
if(d1hw <= d2wh) return scaleLinearHeight(outputHeight), scaleLinearWidth(outputWidth);
|
||||
return scaleLinear(outputWidth, outputHeight);
|
||||
}
|
||||
|
||||
void image::transform(bool outputEndian, unsigned outputDepth, uint64_t outputAlphaMask, uint64_t outputRedMask, uint64_t outputGreenMask, uint64_t outputBlueMask) {
|
||||
if(endian == outputEndian && depth == outputDepth && alpha.mask == outputAlphaMask && red.mask == outputRedMask && green.mask == outputGreenMask && blue.mask == outputBlueMask) return;
|
||||
|
||||
image output(outputEndian, outputDepth, outputAlphaMask, outputRedMask, outputGreenMask, outputBlueMask);
|
||||
output.allocate(width, height);
|
||||
|
||||
#pragma omp parallel for
|
||||
for(unsigned y = 0; y < height; y++) {
|
||||
const uint8_t* sp = data + pitch * y;
|
||||
uint8_t* dp = output.data + output.pitch * y;
|
||||
uint8_t* sp = data + pitch * y;
|
||||
for(unsigned x = 0; x < width; x++) {
|
||||
uint64_t color = read(sp);
|
||||
sp += stride;
|
||||
|
@ -287,9 +443,9 @@ void image::transform(bool outputEndian, unsigned outputDepth, uint64_t outputAl
|
|||
}
|
||||
|
||||
void image::alphaBlend(uint64_t alphaColor) {
|
||||
uint64_t alphaR = (alphaColor & red.mask) >> red.shift;
|
||||
uint64_t alphaR = (alphaColor & red.mask ) >> red.shift;
|
||||
uint64_t alphaG = (alphaColor & green.mask) >> green.shift;
|
||||
uint64_t alphaB = (alphaColor & blue.mask) >> blue.shift;
|
||||
uint64_t alphaB = (alphaColor & blue.mask ) >> blue.shift;
|
||||
|
||||
#pragma omp parallel for
|
||||
for(unsigned y = 0; y < height; y++) {
|
||||
|
@ -298,9 +454,9 @@ void image::alphaBlend(uint64_t alphaColor) {
|
|||
uint64_t color = read(dp);
|
||||
|
||||
uint64_t colorA = (color & alpha.mask) >> alpha.shift;
|
||||
uint64_t colorR = (color & red.mask) >> red.shift;
|
||||
uint64_t colorR = (color & red.mask ) >> red.shift;
|
||||
uint64_t colorG = (color & green.mask) >> green.shift;
|
||||
uint64_t colorB = (color & blue.mask) >> blue.shift;
|
||||
uint64_t colorB = (color & blue.mask ) >> blue.shift;
|
||||
double alphaScale = (double)colorA / (double)((1 << alpha.depth) - 1);
|
||||
|
||||
colorA = (1 << alpha.depth) - 1;
|
||||
|
@ -316,99 +472,199 @@ void image::alphaBlend(uint64_t alphaColor) {
|
|||
|
||||
//protected
|
||||
|
||||
uint64_t image::interpolate(double mu, const uint64_t* s, double (*op)(double, double, double, double, double)) {
|
||||
uint64_t aa = (s[0] & alpha.mask) >> alpha.shift, ar = (s[0] & red.mask) >> red.shift,
|
||||
ag = (s[0] & green.mask) >> green.shift, ab = (s[0] & blue.mask) >> blue.shift;
|
||||
uint64_t ba = (s[1] & alpha.mask) >> alpha.shift, br = (s[1] & red.mask) >> red.shift,
|
||||
bg = (s[1] & green.mask) >> green.shift, bb = (s[1] & blue.mask) >> blue.shift;
|
||||
uint64_t ca = (s[2] & alpha.mask) >> alpha.shift, cr = (s[2] & red.mask) >> red.shift,
|
||||
cg = (s[2] & green.mask) >> green.shift, cb = (s[2] & blue.mask) >> blue.shift;
|
||||
uint64_t da = (s[3] & alpha.mask) >> alpha.shift, dr = (s[3] & red.mask) >> red.shift,
|
||||
dg = (s[3] & green.mask) >> green.shift, db = (s[3] & blue.mask) >> blue.shift;
|
||||
|
||||
int64_t A = op(mu, aa, ba, ca, da);
|
||||
int64_t R = op(mu, ar, br, cr, dr);
|
||||
int64_t G = op(mu, ag, bg, cg, dg);
|
||||
int64_t B = op(mu, ab, bb, cb, db);
|
||||
|
||||
A = max(0, min(A, (1 << alpha.depth) - 1));
|
||||
R = max(0, min(R, (1 << red.depth) - 1));
|
||||
G = max(0, min(G, (1 << green.depth) - 1));
|
||||
B = max(0, min(B, (1 << blue.depth) - 1));
|
||||
|
||||
return (A << alpha.shift) | (R << red.shift) | (G << green.shift) | (B << blue.shift);
|
||||
uint8_t* image::allocate(unsigned width, unsigned height, unsigned stride) {
|
||||
//allocate 1x1 larger than requested; so that linear interpolation does not require bounds-checking
|
||||
unsigned size = width * height * stride;
|
||||
unsigned padding = width * stride + stride;
|
||||
uint8_t* data = new uint8_t[size + padding];
|
||||
memset(data + size, 0x00, padding);
|
||||
return data;
|
||||
}
|
||||
|
||||
void image::scaleX(unsigned outputWidth, interpolation op) {
|
||||
uint8_t* outputData = new uint8_t[outputWidth * height * stride];
|
||||
//fixed-point reduction of: a * (1 - x) + b * x
|
||||
uint64_t image::interpolate1D(int64_t a, int64_t b, uint32_t x) {
|
||||
return a + (((b - a) * x) >> 32); //a + (b - a) * x
|
||||
}
|
||||
|
||||
//fixed-point reduction of: a * (1 - x) * (1 - y) + b * x * (1 - y) + c * (1 - x) * y + d * x * y
|
||||
uint64_t image::interpolate2D(int64_t a, int64_t b, int64_t c, int64_t d, uint32_t x, uint32_t y) {
|
||||
a = a + (((b - a) * x) >> 32); //a + (b - a) * x
|
||||
c = c + (((d - c) * x) >> 32); //c + (d - c) * x
|
||||
return a + (((c - a) * y) >> 32); //a + (c - a) * y
|
||||
}
|
||||
|
||||
void image::scaleLinearWidth(unsigned outputWidth) {
|
||||
uint8_t* outputData = allocate(outputWidth, height, stride);
|
||||
unsigned outputPitch = outputWidth * stride;
|
||||
double step = (double)width / (double)outputWidth;
|
||||
const uint8_t* terminal = data + pitch * height;
|
||||
uint64_t xstride = ((uint64_t)(width - 1) << 32) / max(1u, outputWidth - 1);
|
||||
|
||||
#pragma omp parallel for
|
||||
for(unsigned y = 0; y < height; y++) {
|
||||
uint64_t xfraction = 0;
|
||||
|
||||
const uint8_t* sp = data + pitch * y;
|
||||
uint8_t* dp = outputData + outputPitch * y;
|
||||
uint8_t* sp = data + pitch * y;
|
||||
|
||||
double fraction = 0.0;
|
||||
uint64_t s[4] = {sp < terminal ? read(sp) : 0}; //B,C (0,1) = center of kernel { 0, 0, 1, 2 }
|
||||
s[1] = s[0];
|
||||
s[2] = sp + stride < terminal ? read(sp += stride) : s[1];
|
||||
s[3] = sp + stride < terminal ? read(sp += stride) : s[2];
|
||||
uint64_t a = read(sp);
|
||||
uint64_t b = read(sp + stride);
|
||||
sp += stride;
|
||||
|
||||
for(unsigned x = 0; x < width; x++) {
|
||||
while(fraction <= 1.0) {
|
||||
if(dp >= outputData + outputPitch * height) break;
|
||||
write(dp, interpolate(fraction, (const uint64_t*)&s, op));
|
||||
unsigned x = 0;
|
||||
while(x < outputWidth) {
|
||||
while(xfraction < 0x100000000 && x++ < outputWidth) {
|
||||
uint64_t A = interpolate1D((a & alpha.mask) >> alpha.shift, (b & alpha.mask) >> alpha.shift, xfraction);
|
||||
uint64_t R = interpolate1D((a & red.mask ) >> red.shift , (b & red.mask ) >> red.shift, xfraction);
|
||||
uint64_t G = interpolate1D((a & green.mask) >> green.shift, (b & green.mask) >> green.shift, xfraction);
|
||||
uint64_t B = interpolate1D((a & blue.mask ) >> blue.shift , (b & blue.mask ) >> blue.shift, xfraction);
|
||||
|
||||
write(dp, (A << alpha.shift) | (R << red.shift) | (G << green.shift) | (B << blue.shift));
|
||||
dp += stride;
|
||||
fraction += step;
|
||||
xfraction += xstride;
|
||||
}
|
||||
|
||||
s[0] = s[1]; s[1] = s[2]; s[2] = s[3];
|
||||
if(sp + stride < terminal) s[3] = read(sp += stride);
|
||||
fraction -= 1.0;
|
||||
sp += stride;
|
||||
a = b;
|
||||
b = read(sp);
|
||||
xfraction -= 0x100000000;
|
||||
}
|
||||
}
|
||||
|
||||
free();
|
||||
data = outputData;
|
||||
width = outputWidth;
|
||||
pitch = width * stride;
|
||||
pitch = outputPitch;
|
||||
size = height * pitch;
|
||||
}
|
||||
|
||||
void image::scaleY(unsigned outputHeight, interpolation op) {
|
||||
uint8_t* outputData = new uint8_t[width * outputHeight * stride];
|
||||
double step = (double)height / (double)outputHeight;
|
||||
const uint8_t* terminal = data + pitch * height;
|
||||
void image::scaleLinearHeight(unsigned outputHeight) {
|
||||
uint8_t* outputData = allocate(width, outputHeight, stride);
|
||||
uint64_t ystride = ((uint64_t)(height - 1) << 32) / max(1u, outputHeight - 1);
|
||||
|
||||
#pragma omp parallel for
|
||||
for(unsigned x = 0; x < width; x++) {
|
||||
uint64_t yfraction = 0;
|
||||
|
||||
const uint8_t* sp = data + stride * x;
|
||||
uint8_t* dp = outputData + stride * x;
|
||||
uint8_t* sp = data + stride * x;
|
||||
|
||||
double fraction = 0.0;
|
||||
uint64_t s[4] = {sp < terminal ? read(sp) : 0};
|
||||
s[1] = s[0];
|
||||
s[2] = sp + pitch < terminal ? read(sp += pitch) : s[1];
|
||||
s[3] = sp + pitch < terminal ? read(sp += pitch) : s[2];
|
||||
uint64_t a = read(sp);
|
||||
uint64_t b = read(sp + pitch);
|
||||
sp += pitch;
|
||||
|
||||
for(unsigned y = 0; y < height; y++) {
|
||||
while(fraction <= 1.0) {
|
||||
if(dp >= outputData + pitch * outputHeight) break;
|
||||
write(dp, interpolate(fraction, (const uint64_t*)&s, op));
|
||||
unsigned y = 0;
|
||||
while(y < outputHeight) {
|
||||
while(yfraction < 0x100000000 && y++ < outputHeight) {
|
||||
uint64_t A = interpolate1D((a & alpha.mask) >> alpha.shift, (b & alpha.mask) >> alpha.shift, yfraction);
|
||||
uint64_t R = interpolate1D((a & red.mask ) >> red.shift, (b & red.mask ) >> red.shift, yfraction);
|
||||
uint64_t G = interpolate1D((a & green.mask) >> green.shift, (b & green.mask) >> green.shift, yfraction);
|
||||
uint64_t B = interpolate1D((a & blue.mask ) >> blue.shift, (b & blue.mask ) >> blue.shift, yfraction);
|
||||
|
||||
write(dp, (A << alpha.shift) | (R << red.shift) | (G << green.shift) | (B << blue.shift));
|
||||
dp += pitch;
|
||||
fraction += step;
|
||||
yfraction += ystride;
|
||||
}
|
||||
|
||||
s[0] = s[1]; s[1] = s[2]; s[2] = s[3];
|
||||
if(sp + pitch < terminal) s[3] = read(sp += pitch);
|
||||
fraction -= 1.0;
|
||||
sp += pitch;
|
||||
a = b;
|
||||
b = read(sp);
|
||||
yfraction -= 0x100000000;
|
||||
}
|
||||
}
|
||||
|
||||
free();
|
||||
data = outputData;
|
||||
height = outputHeight;
|
||||
size = height * pitch;
|
||||
}
|
||||
|
||||
void image::scaleLinear(unsigned outputWidth, unsigned outputHeight) {
|
||||
uint8_t* outputData = allocate(outputWidth, outputHeight, stride);
|
||||
unsigned outputPitch = outputWidth * stride;
|
||||
|
||||
uint64_t xstride = ((uint64_t)(width - 1) << 32) / max(1u, outputWidth - 1);
|
||||
uint64_t ystride = ((uint64_t)(height - 1) << 32) / max(1u, outputHeight - 1);
|
||||
|
||||
#pragma omp parallel for
|
||||
for(unsigned y = 0; y < outputHeight; y++) {
|
||||
uint64_t yfraction = ystride * y;
|
||||
uint64_t xfraction = 0;
|
||||
|
||||
const uint8_t* sp = data + pitch * (yfraction >> 32);
|
||||
uint8_t* dp = outputData + outputPitch * y;
|
||||
|
||||
uint64_t a = read(sp);
|
||||
uint64_t b = read(sp + stride);
|
||||
uint64_t c = read(sp + pitch);
|
||||
uint64_t d = read(sp + pitch + stride);
|
||||
sp += stride;
|
||||
|
||||
unsigned x = 0;
|
||||
while(x < outputWidth) {
|
||||
while(xfraction < 0x100000000 && x++ < outputWidth) {
|
||||
uint64_t A = interpolate2D((a & alpha.mask) >> alpha.shift, (b & alpha.mask) >> alpha.shift, (c & alpha.mask) >> alpha.shift, (d & alpha.mask) >> alpha.shift, xfraction, yfraction);
|
||||
uint64_t R = interpolate2D((a & red.mask ) >> red.shift, (b & red.mask ) >> red.shift, (c & red.mask ) >> red.shift, (d & red.mask ) >> red.shift, xfraction, yfraction);
|
||||
uint64_t G = interpolate2D((a & green.mask) >> green.shift, (b & green.mask) >> green.shift, (c & green.mask) >> green.shift, (d & green.mask) >> green.shift, xfraction, yfraction);
|
||||
uint64_t B = interpolate2D((a & blue.mask ) >> blue.shift, (b & blue.mask ) >> blue.shift, (c & blue.mask ) >> blue.shift, (d & blue.mask ) >> blue.shift, xfraction, yfraction);
|
||||
|
||||
write(dp, (A << alpha.shift) | (R << red.shift) | (G << green.shift) | (B << blue.shift));
|
||||
dp += stride;
|
||||
xfraction += xstride;
|
||||
}
|
||||
|
||||
sp += stride;
|
||||
a = b;
|
||||
c = d;
|
||||
b = read(sp);
|
||||
d = read(sp + pitch);
|
||||
xfraction -= 0x100000000;
|
||||
}
|
||||
}
|
||||
|
||||
free();
|
||||
data = outputData;
|
||||
width = outputWidth;
|
||||
height = outputHeight;
|
||||
pitch = outputPitch;
|
||||
size = height * pitch;
|
||||
}
|
||||
|
||||
void image::scaleNearest(unsigned outputWidth, unsigned outputHeight) {
|
||||
uint8_t* outputData = allocate(outputWidth, outputHeight, stride);
|
||||
unsigned outputPitch = outputWidth * stride;
|
||||
|
||||
uint64_t xstride = ((uint64_t)width << 32) / outputWidth;
|
||||
uint64_t ystride = ((uint64_t)height << 32) / outputHeight;
|
||||
|
||||
#pragma omp parallel for
|
||||
for(unsigned y = 0; y < outputHeight; y++) {
|
||||
uint64_t yfraction = ystride * y;
|
||||
uint64_t xfraction = 0;
|
||||
|
||||
const uint8_t* sp = data + pitch * (yfraction >> 32);
|
||||
uint8_t* dp = outputData + outputPitch * y;
|
||||
|
||||
uint64_t a = read(sp);
|
||||
|
||||
unsigned x = 0;
|
||||
while(x < outputWidth) {
|
||||
while(xfraction < 0x100000000 && x++ < outputWidth) {
|
||||
write(dp, a);
|
||||
dp += stride;
|
||||
xfraction += xstride;
|
||||
}
|
||||
|
||||
sp += stride;
|
||||
a = read(sp);
|
||||
xfraction -= 0x100000000;
|
||||
}
|
||||
}
|
||||
|
||||
free();
|
||||
data = outputData;
|
||||
width = outputWidth;
|
||||
height = outputHeight;
|
||||
pitch = outputPitch;
|
||||
size = height * pitch;
|
||||
}
|
||||
|
||||
bool image::loadBMP(const string& filename) {
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace Math {
|
|||
#include <utility>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <nall/stdint.hpp>
|
||||
#include <nall/string.hpp>
|
||||
|
||||
#if !defined(PLATFORM_X) && !defined(PLATFORM_OSX)
|
||||
#if !defined(PLATFORM_X) && !defined(PLATFORM_MACOSX)
|
||||
#error "nall/serial: unsupported platform"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ string configpath() {
|
|||
SHGetFolderPathW(nullptr, CSIDL_APPDATA | CSIDL_FLAG_CREATE, nullptr, 0, path);
|
||||
result = (const char*)utf8_t(path);
|
||||
result.transform("\\", "/");
|
||||
#elif defined(PLATFORM_OSX)
|
||||
#elif defined(PLATFORM_MACOSX)
|
||||
result = {userpath(), "Library/Application Support/"};
|
||||
#else
|
||||
result = {userpath(), ".config/"};
|
||||
|
@ -66,7 +66,7 @@ string sharedpath() {
|
|||
SHGetFolderPathW(nullptr, CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE, nullptr, 0, path);
|
||||
result = (const char*)utf8_t(path);
|
||||
result.transform("\\", "/");
|
||||
#elif defined(PLATFORM_OSX)
|
||||
#elif defined(PLATFORM_MACOSX)
|
||||
result = "/Library/Application Support/";
|
||||
#else
|
||||
result = "/usr/share/";
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <nall/function.hpp>
|
||||
#include <nall/intrinsics.hpp>
|
||||
|
||||
#if defined(PLATFORM_X) || defined(PLATFORM_OSX)
|
||||
#if defined(PLATFORM_X) || defined(PLATFORM_MACOSX)
|
||||
#include <pthread.h>
|
||||
|
||||
namespace nall {
|
||||
|
@ -64,7 +64,7 @@ void* thread_entry_point(void* parameter) {
|
|||
}
|
||||
|
||||
}
|
||||
#elif defined(PLATFORM_WIN)
|
||||
#elif defined(PLATFORM_WINDOWS)
|
||||
namespace nall {
|
||||
|
||||
inline DWORD WINAPI thread_entry_point(LPVOID);
|
||||
|
|
|
@ -3,7 +3,7 @@ ifeq ($(platform),)
|
|||
phoenixlink =
|
||||
else ifeq ($(platform),windows)
|
||||
phoenixflags = $(cppflags) $(flags) -DPHOENIX_WINDOWS
|
||||
phoenixlink = -lkernel32 -luser32 -lgdi32 -ladvapi32 -lole32 -lcomctl32 -lcomdlg32 -lshlwapi
|
||||
phoenixlink = -lkernel32 -luser32 -lgdi32 -ladvapi32 -lole32 -lcomctl32 -lcomdlg32 -luxtheme -lmsimg32 -lshlwapi
|
||||
else ifeq ($(platform),macosx)
|
||||
phoenixflags = $(objcppflags) $(flags) -DPHOENIX_COCOA
|
||||
phoenixlink = -framework Cocoa -framework Carbon
|
||||
|
|
|
@ -20,12 +20,6 @@
|
|||
|
||||
namespace phoenix {
|
||||
|
||||
bool pCheckItem::checked() {
|
||||
@autoreleasepool {
|
||||
return [cocoaAction state] != NSOffState;
|
||||
}
|
||||
}
|
||||
|
||||
void pCheckItem::setChecked(bool checked) {
|
||||
@autoreleasepool {
|
||||
auto state = checked ? NSOnState : NSOffState;
|
||||
|
|
|
@ -12,7 +12,6 @@ struct pCheckItem : public pAction {
|
|||
CheckItem& checkItem;
|
||||
CocoaCheckItem* cocoaCheckItem = nullptr;
|
||||
|
||||
bool checked();
|
||||
void setChecked(bool checked);
|
||||
void setText(string text);
|
||||
|
||||
|
|
|
@ -19,12 +19,6 @@
|
|||
|
||||
namespace phoenix {
|
||||
|
||||
bool pRadioItem::checked() {
|
||||
@autoreleasepool {
|
||||
return [cocoaAction state] != NSOffState;
|
||||
}
|
||||
}
|
||||
|
||||
void pRadioItem::setChecked() {
|
||||
@autoreleasepool {
|
||||
for(auto& item : radioItem.state.group) {
|
||||
|
|
|
@ -12,7 +12,6 @@ struct pRadioItem : public pAction {
|
|||
RadioItem& radioItem;
|
||||
CocoaRadioItem* cocoaRadioItem = nullptr;
|
||||
|
||||
bool checked();
|
||||
void setChecked();
|
||||
void setGroup(const group<RadioItem>& group);
|
||||
void setText(string text);
|
||||
|
|
|
@ -84,7 +84,7 @@ void pApplication::initialize() {
|
|||
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]];
|
||||
[NSApp setMainMenu:[pWindow::none().p.cocoaWindow menu]];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
namespace phoenix {
|
||||
|
||||
string pFont::serif(unsigned size, string style) {
|
||||
if(size == 0) size = 12;
|
||||
if(size == 0) size = 8;
|
||||
if(style == "") style = "Normal";
|
||||
return {"Georgia, ", size, ", ", style};
|
||||
}
|
||||
|
||||
string pFont::sans(unsigned size, string style) {
|
||||
if(size == 0) size = 12;
|
||||
if(size == 0) size = 8;
|
||||
if(style == "") style = "Normal";
|
||||
return {"Lucida Grande, ", size, ", ", style};
|
||||
}
|
||||
|
||||
string pFont::monospace(unsigned size, string style) {
|
||||
if(size == 0) size = 12;
|
||||
if(size == 0) size = 8;
|
||||
if(style == "") style = "Normal";
|
||||
return {"Menlo, ", size, ", ", style};
|
||||
}
|
||||
|
@ -32,10 +32,10 @@ NSFont* pFont::cocoaFont(string description) {
|
|||
|
||||
NSString* family = @"Lucida Grande";
|
||||
NSFontTraitMask traits = 0;
|
||||
CGFloat size = 12;
|
||||
CGFloat size = 8.0;
|
||||
|
||||
if(!part(0).empty()) family = [NSString stringWithUTF8String:part(0)];
|
||||
if(!part(1).empty()) size = real(part(1));
|
||||
if(!part(1).empty()) size = decimal(part(1));
|
||||
if(part(2).ifind("bold")) traits |= NSBoldFontMask;
|
||||
if(part(2).ifind("italic")) traits |= NSItalicFontMask;
|
||||
if(part(2).ifind("narrow")) traits |= NSNarrowFontMask;
|
||||
|
@ -43,6 +43,7 @@ NSFont* pFont::cocoaFont(string description) {
|
|||
if(part(2).ifind("condensed")) traits |= NSCondensedFontMask;
|
||||
if(part(2).ifind("smallcaps")) traits |= NSSmallCapsFontMask;
|
||||
|
||||
size *= 1.5; //scale to point sizes (for consistency with other operating systems)
|
||||
return [[NSFontManager sharedFontManager] fontWithFamily:family traits:traits weight:5 size:size];
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,10 @@
|
|||
#include "widget/button.cpp"
|
||||
#include "widget/canvas.cpp"
|
||||
#include "widget/check-button.cpp"
|
||||
#include "widget/check-label.cpp"
|
||||
#include "widget/combo-button.cpp"
|
||||
#include "widget/console.cpp"
|
||||
#include "widget/frame.cpp"
|
||||
#include "widget/hex-edit.cpp"
|
||||
#include "widget/horizontal-scroller.cpp"
|
||||
#include "widget/horizontal-slider.cpp"
|
||||
|
@ -32,6 +34,8 @@
|
|||
#include "widget/list-view.cpp"
|
||||
#include "widget/progress-bar.cpp"
|
||||
#include "widget/radio-button.cpp"
|
||||
#include "widget/radio-label.cpp"
|
||||
#include "widget/tab-frame.cpp"
|
||||
#include "widget/text-edit.cpp"
|
||||
#include "widget/vertical-scroller.cpp"
|
||||
#include "widget/vertical-slider.cpp"
|
||||
|
|
|
@ -29,8 +29,10 @@ namespace phoenix {
|
|||
#include "widget/button.hpp"
|
||||
#include "widget/canvas.hpp"
|
||||
#include "widget/check-button.hpp"
|
||||
#include "widget/check-label.hpp"
|
||||
#include "widget/combo-button.hpp"
|
||||
#include "widget/console.hpp"
|
||||
#include "widget/frame.hpp"
|
||||
#include "widget/hex-edit.hpp"
|
||||
#include "widget/horizontal-scroller.hpp"
|
||||
#include "widget/horizontal-slider.hpp"
|
||||
|
@ -39,6 +41,8 @@ namespace phoenix {
|
|||
#include "widget/list-view.hpp"
|
||||
#include "widget/progress-bar.hpp"
|
||||
#include "widget/radio-button.hpp"
|
||||
#include "widget/radio-label.hpp"
|
||||
#include "widget/tab-frame.hpp"
|
||||
#include "widget/text-edit.hpp"
|
||||
#include "widget/vertical-scroller.hpp"
|
||||
#include "widget/vertical-slider.hpp"
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
}
|
||||
if(timer->state.enabled == false) return;
|
||||
instance = [NSTimer
|
||||
scheduledTimerWithTimeInterval:timer->state.milliseconds / 1000.0
|
||||
scheduledTimerWithTimeInterval:timer->state.interval / 1000.0
|
||||
target:self selector:@selector(run:) userInfo:nil repeats:YES
|
||||
];
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ void pTimer::setEnabled(bool enabled) {
|
|||
}
|
||||
}
|
||||
|
||||
void pTimer::setInterval(unsigned milliseconds) {
|
||||
void pTimer::setInterval(unsigned interval) {
|
||||
@autoreleasepool {
|
||||
[cocoaTimer update];
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ struct pTimer : public pObject {
|
|||
CocoaTimer* cocoaTimer = nullptr;
|
||||
|
||||
void setEnabled(bool enabled);
|
||||
void setInterval(unsigned milliseconds);
|
||||
void setInterval(unsigned interval);
|
||||
|
||||
pTimer(Timer& timer) : pObject(timer), timer(timer) {}
|
||||
void constructor();
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
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]
|
||||
NSTrackingArea* area = [[[NSTrackingArea alloc] initWithRect:[self frame]
|
||||
options:NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow | NSTrackingInVisibleRect
|
||||
owner:self userInfo:nil
|
||||
] autorelease];
|
||||
|
@ -25,7 +25,7 @@
|
|||
}
|
||||
|
||||
-(void) mouseButton:(NSEvent*)event down:(BOOL)isDown {
|
||||
if(auto &callback = isDown ? canvas->onMousePress : canvas->onMouseRelease) {
|
||||
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);
|
||||
|
@ -94,47 +94,40 @@ void pCanvas::setDroppable(bool droppable) {
|
|||
}
|
||||
}
|
||||
|
||||
void pCanvas::setSize(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];
|
||||
void pCanvas::setGeometry(Geometry geometry) {
|
||||
if(canvas.state.width == 0 || canvas.state.height == 0) rasterize();
|
||||
|
||||
[image addRepresentation:bitmap];
|
||||
[cocoaView setImage:image];
|
||||
unsigned width = canvas.state.width;
|
||||
unsigned height = canvas.state.height;
|
||||
if(width == 0) width = widget.state.geometry.width;
|
||||
if(height == 0) height = widget.state.geometry.height;
|
||||
|
||||
if(width < geometry.width) {
|
||||
geometry.x += (geometry.width - width) / 2;
|
||||
geometry.width = width;
|
||||
}
|
||||
|
||||
if(height < geometry.height) {
|
||||
geometry.y += (geometry.height - height) / 2;
|
||||
geometry.height = height;
|
||||
}
|
||||
|
||||
pWidget::setGeometry(geometry);
|
||||
}
|
||||
|
||||
void pCanvas::update() {
|
||||
@autoreleasepool {
|
||||
if(NSBitmapImageRep* bitmap = [[[cocoaView image] representations] objectAtIndex:0]) {
|
||||
uint8_t* target = [bitmap bitmapData];
|
||||
uint32_t* source = canvas.state.data;
|
||||
void pCanvas::setMode(Canvas::Mode mode) {
|
||||
rasterize(), redraw();
|
||||
}
|
||||
|
||||
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::setSize(Size size) {
|
||||
rasterize(), redraw();
|
||||
}
|
||||
|
||||
void pCanvas::constructor() {
|
||||
@autoreleasepool {
|
||||
cocoaView = cocoaCanvas = [[CocoaCanvas alloc] initWith:canvas];
|
||||
setSize(canvas.size());
|
||||
}
|
||||
setSize(canvas.size());
|
||||
}
|
||||
|
||||
void pCanvas::destructor() {
|
||||
|
@ -143,4 +136,79 @@ void pCanvas::destructor() {
|
|||
}
|
||||
}
|
||||
|
||||
void pCanvas::rasterize() {
|
||||
@autoreleasepool {
|
||||
unsigned width = canvas.state.width;
|
||||
unsigned height = canvas.state.height;
|
||||
if(width == 0) width = widget.state.geometry.width;
|
||||
if(height == 0) height = widget.state.geometry.height;
|
||||
|
||||
if(width != surfaceWidth || height != surfaceHeight) {
|
||||
NSImage* image = [[[NSImage alloc] initWithSize:NSMakeSize(width, height)] autorelease];
|
||||
NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc]
|
||||
initWithBitmapDataPlanes:nil
|
||||
pixelsWide:width pixelsHigh:height
|
||||
bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES
|
||||
isPlanar:NO colorSpaceName:NSCalibratedRGBColorSpace
|
||||
bitmapFormat:NSAlphaNonpremultipliedBitmapFormat
|
||||
bytesPerRow:width * 4 bitsPerPixel:32
|
||||
] autorelease];
|
||||
|
||||
[image addRepresentation:bitmap];
|
||||
[cocoaView setImage:image];
|
||||
|
||||
surfaceWidth = width;
|
||||
surfaceHeight = height;
|
||||
}
|
||||
|
||||
if(NSBitmapImageRep* bitmap = [[[cocoaView image] representations] objectAtIndex:0]) {
|
||||
uint32_t* target = (uint32_t*)[bitmap bitmapData];
|
||||
|
||||
if(canvas.state.mode == Canvas::Mode::Color) {
|
||||
nall::image image;
|
||||
image.allocate(width, height);
|
||||
image.fill(canvas.state.color.argb());
|
||||
memcpy(target, image.data, image.size);
|
||||
}
|
||||
|
||||
if(canvas.state.mode == Canvas::Mode::Gradient) {
|
||||
nall::image image;
|
||||
image.allocate(width, height);
|
||||
image.gradient(
|
||||
canvas.state.gradient[0].argb(), canvas.state.gradient[1].argb(), canvas.state.gradient[2].argb(), canvas.state.gradient[3].argb()
|
||||
);
|
||||
memcpy(target, image.data, image.size);
|
||||
}
|
||||
|
||||
if(canvas.state.mode == Canvas::Mode::Image) {
|
||||
nall::image image = canvas.state.image;
|
||||
image.scale(width, height);
|
||||
image.transform(0, 32, 255u << 24, 255u << 16, 255u << 8, 255u << 0);
|
||||
memcpy(target, image.data, image.size);
|
||||
}
|
||||
|
||||
if(canvas.state.mode == Canvas::Mode::Data) {
|
||||
if(width == canvas.state.width && height == canvas.state.height) {
|
||||
memcpy(target, canvas.state.data, width * height * sizeof(uint32_t));
|
||||
} else {
|
||||
memset(target, 0x00, width * height * sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
|
||||
//ARGB -> ABGR transformation
|
||||
for(unsigned n = 0; n < width * height; n++) {
|
||||
uint32_t color = *target;
|
||||
color = (color & 0xff00ff00) | ((color & 0xff0000) >> 16) | ((color & 0x0000ff) << 16);
|
||||
*target++ = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pCanvas::redraw() {
|
||||
@autoreleasepool {
|
||||
[cocoaView setNeedsDisplay:YES];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,14 +24,19 @@ namespace phoenix {
|
|||
struct pCanvas : public pWidget {
|
||||
Canvas& canvas;
|
||||
CocoaCanvas* cocoaCanvas = nullptr;
|
||||
unsigned surfaceWidth = 0;
|
||||
unsigned surfaceHeight = 0;
|
||||
|
||||
void setDroppable(bool droppable);
|
||||
void setGeometry(Geometry geometry);
|
||||
void setMode(Canvas::Mode mode);
|
||||
void setSize(Size size);
|
||||
void update();
|
||||
|
||||
pCanvas(Canvas& canvas) : pWidget(canvas), canvas(canvas) {}
|
||||
void constructor();
|
||||
void destructor();
|
||||
void rasterize();
|
||||
void redraw();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
|
||||
[self setTarget:self];
|
||||
[self setAction:@selector(activate:)];
|
||||
[self setButtonType:NSSwitchButton];
|
||||
[self setBezelStyle:NSRegularSquareBezelStyle];
|
||||
[self setButtonType:NSOnOffButton];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
@ -20,15 +21,20 @@
|
|||
|
||||
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 + 20, size.height};
|
||||
|
||||
if(checkButton.state.orientation == Orientation::Horizontal) {
|
||||
size.width += checkButton.state.image.width;
|
||||
size.height = max(checkButton.state.image.height, size.height);
|
||||
}
|
||||
|
||||
if(checkButton.state.orientation == Orientation::Vertical) {
|
||||
size.width = max(checkButton.state.image.width, size.width);
|
||||
size.height += checkButton.state.image.height;
|
||||
}
|
||||
|
||||
return {size.width + 20, size.height + 4};
|
||||
}
|
||||
|
||||
void pCheckButton::setChecked(bool checked) {
|
||||
|
@ -39,11 +45,25 @@ void pCheckButton::setChecked(bool checked) {
|
|||
|
||||
void pCheckButton::setGeometry(Geometry geometry) {
|
||||
pWidget::setGeometry({
|
||||
geometry.x - 2, geometry.y,
|
||||
geometry.width + 4, geometry.height
|
||||
geometry.x - 2, geometry.y - 2,
|
||||
geometry.width + 4, geometry.height + 4
|
||||
});
|
||||
}
|
||||
|
||||
void pCheckButton::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 pCheckButton::setText(string text) {
|
||||
@autoreleasepool {
|
||||
[cocoaView setTitle:[NSString stringWithUTF8String:text]];
|
||||
|
@ -53,8 +73,6 @@ void pCheckButton::setText(string text) {
|
|||
void pCheckButton::constructor() {
|
||||
@autoreleasepool {
|
||||
cocoaView = cocoaCheckButton = [[CocoaCheckButton alloc] initWith:checkButton];
|
||||
setChecked(checkButton.state.checked);
|
||||
setText(checkButton.state.text);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,10 +12,10 @@ struct pCheckButton : public pWidget {
|
|||
CheckButton& checkButton;
|
||||
CocoaCheckButton* cocoaCheckButton = nullptr;
|
||||
|
||||
bool checked();
|
||||
Size minimumSize();
|
||||
void setChecked(bool checked);
|
||||
void setGeometry(Geometry geometry);
|
||||
void setImage(const image& image, Orientation orientation);
|
||||
void setText(string text);
|
||||
|
||||
pCheckButton(CheckButton& checkButton) : pWidget(checkButton), checkButton(checkButton) {}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
@implementation CocoaCheckLabel : NSButton
|
||||
|
||||
-(id) initWith:(phoenix::CheckLabel&)checkLabelReference {
|
||||
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
|
||||
checkLabel = &checkLabelReference;
|
||||
|
||||
[self setTarget:self];
|
||||
[self setAction:@selector(activate:)];
|
||||
[self setButtonType:NSSwitchButton];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(IBAction) activate:(id)sender {
|
||||
checkLabel->state.checked = [self state] != NSOffState;
|
||||
if(checkLabel->onToggle) checkLabel->onToggle();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
Size pCheckLabel::minimumSize() {
|
||||
Size size = Font::size(checkLabel.font(), checkLabel.state.text);
|
||||
return {size.width + 20, size.height};
|
||||
}
|
||||
|
||||
void pCheckLabel::setChecked(bool checked) {
|
||||
@autoreleasepool {
|
||||
[cocoaView setState:checked ? NSOnState : NSOffState];
|
||||
}
|
||||
}
|
||||
|
||||
void pCheckLabel::setGeometry(Geometry geometry) {
|
||||
pWidget::setGeometry({
|
||||
geometry.x - 2, geometry.y,
|
||||
geometry.width + 4, geometry.height
|
||||
});
|
||||
}
|
||||
|
||||
void pCheckLabel::setText(string text) {
|
||||
@autoreleasepool {
|
||||
[cocoaView setTitle:[NSString stringWithUTF8String:text]];
|
||||
}
|
||||
}
|
||||
|
||||
void pCheckLabel::constructor() {
|
||||
@autoreleasepool {
|
||||
cocoaView = cocoaCheckLabel = [[CocoaCheckLabel alloc] initWith:checkLabel];
|
||||
setChecked(checkLabel.state.checked);
|
||||
setText(checkLabel.state.text);
|
||||
}
|
||||
}
|
||||
|
||||
void pCheckLabel::destructor() {
|
||||
@autoreleasepool {
|
||||
[cocoaView release];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
@interface CocoaCheckLabel : NSButton {
|
||||
@public
|
||||
phoenix::CheckLabel* checkLabel;
|
||||
}
|
||||
-(id) initWith:(phoenix::CheckLabel&)checkLabel;
|
||||
-(IBAction) activate:(id)sender;
|
||||
@end
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
struct pCheckLabel : public pWidget {
|
||||
CheckLabel& checkLabel;
|
||||
CocoaCheckLabel* cocoaCheckLabel = nullptr;
|
||||
|
||||
Size minimumSize();
|
||||
void setChecked(bool checked);
|
||||
void setGeometry(Geometry geometry);
|
||||
void setText(string text);
|
||||
|
||||
pCheckLabel(CheckLabel& checkLabel) : pWidget(checkLabel), checkLabel(checkLabel) {}
|
||||
void constructor();
|
||||
void destructor();
|
||||
};
|
||||
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
}
|
||||
|
||||
-(IBAction) activate:(id)sender {
|
||||
comboButton->state.selection = [self indexOfSelectedItem];
|
||||
if(comboButton->onChange) comboButton->onChange();
|
||||
}
|
||||
|
||||
|
@ -31,15 +32,9 @@ Size pComboButton::minimumSize() {
|
|||
return {maximumWidth + 36, size.height + 6};
|
||||
}
|
||||
|
||||
void pComboButton::modify(unsigned row, string text) {
|
||||
void pComboButton::remove(unsigned selection) {
|
||||
@autoreleasepool {
|
||||
[[cocoaView itemAtIndex:row] setTitle:[NSString stringWithUTF8String:text]];
|
||||
}
|
||||
}
|
||||
|
||||
void pComboButton::remove(unsigned row) {
|
||||
@autoreleasepool {
|
||||
[cocoaView removeItemAtIndex:row];
|
||||
[cocoaView removeItemAtIndex:selection];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,12 +44,6 @@ void pComboButton::reset() {
|
|||
}
|
||||
}
|
||||
|
||||
unsigned pComboButton::selection() {
|
||||
@autoreleasepool {
|
||||
return [cocoaView indexOfSelectedItem];
|
||||
}
|
||||
}
|
||||
|
||||
void pComboButton::setGeometry(Geometry geometry) {
|
||||
pWidget::setGeometry({
|
||||
geometry.x - 2, geometry.y,
|
||||
|
@ -62,9 +51,15 @@ void pComboButton::setGeometry(Geometry geometry) {
|
|||
});
|
||||
}
|
||||
|
||||
void pComboButton::setSelection(unsigned row) {
|
||||
void pComboButton::setSelection(unsigned selection) {
|
||||
@autoreleasepool {
|
||||
[cocoaView selectItemAtIndex:row];
|
||||
[cocoaView selectItemAtIndex:selection];
|
||||
}
|
||||
}
|
||||
|
||||
void pComboButton::setText(unsigned selection, string text) {
|
||||
@autoreleasepool {
|
||||
[[cocoaView itemAtIndex:selection] setTitle:[NSString stringWithUTF8String:text]];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,12 +14,11 @@ struct pComboButton : public pWidget {
|
|||
|
||||
void append(string text);
|
||||
Size minimumSize();
|
||||
void modify(unsigned row, string text);
|
||||
void remove(unsigned row);
|
||||
void remove(unsigned selection);
|
||||
void reset();
|
||||
unsigned selection();
|
||||
void setGeometry(Geometry geometry);
|
||||
void setSelection(unsigned row);
|
||||
void setSelection(unsigned selection);
|
||||
void setText(unsigned selection, string text);
|
||||
|
||||
pComboButton(ComboButton& comboButton) : pWidget(comboButton), comboButton(comboButton) {}
|
||||
void constructor();
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
@implementation CocoaFrame : NSBox
|
||||
|
||||
-(id) initWith:(phoenix::Frame&)frameReference {
|
||||
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
|
||||
frame = &frameReference;
|
||||
|
||||
[self setTitle:@""];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
void pFrame::setEnabled(bool enabled) {
|
||||
if(frame.state.layout) frame.state.layout->setEnabled(frame.state.layout->enabled());
|
||||
pWidget::setEnabled(enabled);
|
||||
}
|
||||
|
||||
void pFrame::setFont(string font) {
|
||||
@autoreleasepool {
|
||||
[cocoaView setTitleFont:pFont::cocoaFont(font)];
|
||||
}
|
||||
}
|
||||
|
||||
void pFrame::setGeometry(Geometry geometry) {
|
||||
bool empty = frame.state.text.empty();
|
||||
Size size = Font::size(frame.font(), frame.state.text);
|
||||
pWidget::setGeometry({
|
||||
geometry.x - 3, geometry.y - (empty ? size.height - 2 : 1),
|
||||
geometry.width + 6, geometry.height + (empty ? size.height + 2 : 5)
|
||||
});
|
||||
if(frame.state.layout == nullptr) return;
|
||||
geometry.x += 1, geometry.y += (empty ? 1 : size.height - 2);
|
||||
geometry.width -= 2, geometry.height -= (empty ? 1 : size.height - 1);
|
||||
frame.state.layout->setGeometry(geometry);
|
||||
}
|
||||
|
||||
void pFrame::setText(string text) {
|
||||
@autoreleasepool {
|
||||
[cocoaView setTitle:[NSString stringWithUTF8String:text]];
|
||||
}
|
||||
}
|
||||
|
||||
void pFrame::setVisible(bool visible) {
|
||||
if(frame.state.layout) frame.state.layout->setVisible(frame.state.layout->visible());
|
||||
pWidget::setVisible(visible);
|
||||
}
|
||||
|
||||
void pFrame::constructor() {
|
||||
@autoreleasepool {
|
||||
cocoaView = cocoaFrame = [[CocoaFrame alloc] initWith:frame];
|
||||
}
|
||||
}
|
||||
|
||||
void pFrame::destructor() {
|
||||
@autoreleasepool {
|
||||
[cocoaView release];
|
||||
}
|
||||
}
|
||||
|
||||
void pFrame::orphan() {
|
||||
destructor();
|
||||
constructor();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
@interface CocoaFrame : NSBox {
|
||||
@public
|
||||
phoenix::Frame* frame;
|
||||
}
|
||||
-(id) initWith:(phoenix::Frame&)frame;
|
||||
@end
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
struct pFrame : public pWidget {
|
||||
Frame& frame;
|
||||
CocoaFrame* cocoaFrame = nullptr;
|
||||
|
||||
void setEnabled(bool enabled);
|
||||
void setFont(string font);
|
||||
void setGeometry(Geometry geometry);
|
||||
void setText(string text);
|
||||
void setVisible(bool visible);
|
||||
|
||||
pFrame(Frame& frame) : pWidget(frame), frame(frame) {}
|
||||
void constructor();
|
||||
void destructor();
|
||||
void orphan();
|
||||
};
|
||||
|
||||
}
|
|
@ -58,12 +58,6 @@ Size pHorizontalScroller::minimumSize() {
|
|||
}
|
||||
}
|
||||
|
||||
unsigned pHorizontalScroller::position() {
|
||||
@autoreleasepool {
|
||||
return [cocoaView doubleValue] * horizontalScroller.state.length;
|
||||
}
|
||||
}
|
||||
|
||||
void pHorizontalScroller::setLength(unsigned length) {
|
||||
@autoreleasepool {
|
||||
[cocoaView update];
|
||||
|
|
|
@ -14,7 +14,6 @@ struct pHorizontalScroller : public pWidget {
|
|||
CocoaHorizontalScroller* cocoaHorizontalScroller = nullptr;
|
||||
|
||||
Size minimumSize();
|
||||
unsigned position();
|
||||
void setLength(unsigned length);
|
||||
void setPosition(unsigned position);
|
||||
|
||||
|
|
|
@ -24,12 +24,6 @@ Size pHorizontalSlider::minimumSize() {
|
|||
return {48, 20};
|
||||
}
|
||||
|
||||
unsigned pHorizontalSlider::position() {
|
||||
@autoreleasepool {
|
||||
return [cocoaView doubleValue];
|
||||
}
|
||||
}
|
||||
|
||||
void pHorizontalSlider::setGeometry(Geometry geometry) {
|
||||
pWidget::setGeometry({
|
||||
geometry.x - 2, geometry.y,
|
||||
|
|
|
@ -13,7 +13,6 @@ struct pHorizontalSlider : public pWidget {
|
|||
CocoaHorizontalSlider* cocoaHorizontalSlider = nullptr;
|
||||
|
||||
Size minimumSize();
|
||||
unsigned position();
|
||||
void setGeometry(Geometry geometry);
|
||||
void setLength(unsigned length);
|
||||
void setPosition(unsigned position);
|
||||
|
|
|
@ -134,6 +134,8 @@
|
|||
}
|
||||
|
||||
-(void) tableViewSelectionDidChange:(NSNotification*)notification {
|
||||
listView->state.selected = true;
|
||||
listView->state.selection = [content selectedRow];
|
||||
if(listView->onChange) listView->onChange();
|
||||
}
|
||||
|
||||
|
@ -178,14 +180,13 @@
|
|||
unsigned textDisplacement = 0;
|
||||
|
||||
if(image) {
|
||||
NSGraphicsContext* context = [NSGraphicsContext currentContext];
|
||||
[context saveGraphicsState];
|
||||
[[NSGraphicsContext currentContext] 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];
|
||||
[[NSGraphicsContext currentContext] restoreGraphicsState];
|
||||
textDisplacement = frame.size.height + 2;
|
||||
}
|
||||
|
||||
|
@ -237,17 +238,7 @@ void pListView::autoSizeColumns() {
|
|||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
void pListView::remove(unsigned selection) {
|
||||
@autoreleasepool {
|
||||
[[cocoaView content] reloadData];
|
||||
}
|
||||
|
@ -259,27 +250,13 @@ void pListView::reset() {
|
|||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
void pListView::setChecked(unsigned selection, bool checked) {
|
||||
@autoreleasepool {
|
||||
[[cocoaView content] reloadData];
|
||||
}
|
||||
|
@ -307,7 +284,7 @@ void pListView::setHeaderVisible(bool visible) {
|
|||
}
|
||||
}
|
||||
|
||||
void pListView::setImage(unsigned row, unsigned column, const image& image) {
|
||||
void pListView::setImage(unsigned selection, unsigned position, const image& image) {
|
||||
@autoreleasepool {
|
||||
[[cocoaView content] reloadData];
|
||||
}
|
||||
|
@ -321,9 +298,15 @@ void pListView::setSelected(bool selected) {
|
|||
}
|
||||
}
|
||||
|
||||
void pListView::setSelection(unsigned row) {
|
||||
void pListView::setSelection(unsigned selection) {
|
||||
@autoreleasepool {
|
||||
[[cocoaView content] selectRowIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(row, 1)] byExtendingSelection:NO];
|
||||
[[cocoaView content] selectRowIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(selection, 1)] byExtendingSelection:NO];
|
||||
}
|
||||
}
|
||||
|
||||
void pListView::setText(unsigned selection, unsigned position, const string text) {
|
||||
@autoreleasepool {
|
||||
[[cocoaView content] reloadData];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,20 +42,17 @@ struct pListView : public pWidget {
|
|||
|
||||
void append(const lstring& text);
|
||||
void autoSizeColumns();
|
||||
bool checked(unsigned row);
|
||||
void modify(unsigned row, const lstring& text);
|
||||
void remove(unsigned row);
|
||||
void remove(unsigned selection);
|
||||
void reset();
|
||||
bool selected();
|
||||
unsigned selection();
|
||||
void setCheckable(bool checkable);
|
||||
void setChecked(unsigned row, bool checked);
|
||||
void setChecked(unsigned selection, bool checked);
|
||||
void setFont(string font);
|
||||
void setHeaderText(const lstring& text);
|
||||
void setHeaderVisible(bool visible);
|
||||
void setImage(unsigned row, unsigned column, const image& image);
|
||||
void setImage(unsigned selection, unsigned position, const image& image);
|
||||
void setSelected(bool selected);
|
||||
void setSelection(unsigned row);
|
||||
void setSelection(unsigned selection);
|
||||
void setText(unsigned selection, unsigned position, string text);
|
||||
|
||||
pListView(ListView& listView) : pWidget(listView), listView(listView) {}
|
||||
void constructor();
|
||||
|
|
|
@ -6,29 +6,38 @@
|
|||
|
||||
[self setTarget:self];
|
||||
[self setAction:@selector(activate:)];
|
||||
[self setButtonType:NSRadioButton];
|
||||
[self setBezelStyle:NSRegularSquareBezelStyle];
|
||||
[self setButtonType:NSOnOffButton];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(IBAction) activate:(id)sender {
|
||||
bool wasChecked = radioButton->state.checked;
|
||||
radioButton->setChecked();
|
||||
if(radioButton->onActivate) radioButton->onActivate();
|
||||
if(wasChecked == false) {
|
||||
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 + 22, size.height};
|
||||
|
||||
if(radioButton.state.orientation == Orientation::Horizontal) {
|
||||
size.width += radioButton.state.image.width;
|
||||
size.height = max(radioButton.state.image.height, size.height);
|
||||
}
|
||||
|
||||
if(radioButton.state.orientation == Orientation::Vertical) {
|
||||
size.width = max(radioButton.state.image.width, size.width);
|
||||
size.height += radioButton.state.image.height;
|
||||
}
|
||||
|
||||
return {size.width + 20, size.height + 4};
|
||||
}
|
||||
|
||||
void pRadioButton::setChecked() {
|
||||
|
@ -42,14 +51,28 @@ void pRadioButton::setChecked() {
|
|||
|
||||
void pRadioButton::setGeometry(Geometry geometry) {
|
||||
pWidget::setGeometry({
|
||||
geometry.x - 1, geometry.y,
|
||||
geometry.width + 2, geometry.height
|
||||
geometry.x - 2, geometry.y - 2,
|
||||
geometry.width + 4, geometry.height + 4
|
||||
});
|
||||
}
|
||||
|
||||
void pRadioButton::setGroup(const group<RadioButton>& group) {
|
||||
}
|
||||
|
||||
void pRadioButton::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 pRadioButton::setText(string text) {
|
||||
@autoreleasepool {
|
||||
[cocoaView setTitle:[NSString stringWithUTF8String:text]];
|
||||
|
|
|
@ -12,11 +12,11 @@ struct pRadioButton : public pWidget {
|
|||
RadioButton& radioButton;
|
||||
CocoaRadioButton* cocoaRadioButton = nullptr;
|
||||
|
||||
bool checked();
|
||||
Size minimumSize();
|
||||
void setChecked();
|
||||
void setGeometry(Geometry geometry);
|
||||
void setGroup(const group<RadioButton>& group);
|
||||
void setImage(const image& image, Orientation orientation);
|
||||
void setText(string text);
|
||||
|
||||
pRadioButton(RadioButton& radioButton) : pWidget(radioButton), radioButton(radioButton) {}
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
@implementation CocoaRadioLabel : NSButton
|
||||
|
||||
-(id) initWith:(phoenix::RadioLabel&)radioLabelReference {
|
||||
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
|
||||
radioLabel = &radioLabelReference;
|
||||
|
||||
[self setTarget:self];
|
||||
[self setAction:@selector(activate:)];
|
||||
[self setButtonType:NSRadioButton];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(IBAction) activate:(id)sender {
|
||||
radioLabel->setChecked();
|
||||
if(radioLabel->onActivate) radioLabel->onActivate();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
Size pRadioLabel::minimumSize() {
|
||||
Size size = Font::size(radioLabel.font(), radioLabel.state.text);
|
||||
return {size.width + 22, size.height};
|
||||
}
|
||||
|
||||
void pRadioLabel::setChecked() {
|
||||
@autoreleasepool {
|
||||
for(auto& item : radioLabel.state.group) {
|
||||
auto state = (&item == &radioLabel) ? NSOnState : NSOffState;
|
||||
[item.p.cocoaView setState:state];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pRadioLabel::setGeometry(Geometry geometry) {
|
||||
pWidget::setGeometry({
|
||||
geometry.x - 1, geometry.y,
|
||||
geometry.width + 2, geometry.height
|
||||
});
|
||||
}
|
||||
|
||||
void pRadioLabel::setGroup(const group<RadioLabel>& group) {
|
||||
}
|
||||
|
||||
void pRadioLabel::setText(string text) {
|
||||
@autoreleasepool {
|
||||
[cocoaView setTitle:[NSString stringWithUTF8String:text]];
|
||||
}
|
||||
}
|
||||
|
||||
void pRadioLabel::constructor() {
|
||||
@autoreleasepool {
|
||||
cocoaView = cocoaRadioLabel = [[CocoaRadioLabel alloc] initWith:radioLabel];
|
||||
}
|
||||
}
|
||||
|
||||
void pRadioLabel::destructor() {
|
||||
@autoreleasepool {
|
||||
[cocoaView release];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
@interface CocoaRadioLabel : NSButton {
|
||||
@public
|
||||
phoenix::RadioLabel* radioLabel;
|
||||
}
|
||||
-(id) initWith:(phoenix::RadioLabel&)radioLabel;
|
||||
-(IBAction) activate:(id)sender;
|
||||
@end
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
struct pRadioLabel : public pWidget {
|
||||
RadioLabel& radioLabel;
|
||||
CocoaRadioLabel* cocoaRadioLabel = nullptr;
|
||||
|
||||
Size minimumSize();
|
||||
void setChecked();
|
||||
void setGeometry(Geometry geometry);
|
||||
void setGroup(const group<RadioLabel>& group);
|
||||
void setText(string text);
|
||||
|
||||
pRadioLabel(RadioLabel& radioLabel) : pWidget(radioLabel), radioLabel(radioLabel) {}
|
||||
void constructor();
|
||||
void destructor();
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
@implementation CocoaTabFrame : NSTabView
|
||||
|
||||
-(id) initWith:(phoenix::TabFrame&)tabFrameReference {
|
||||
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
|
||||
tabFrame = &tabFrameReference;
|
||||
|
||||
[self setDelegate:self];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) tabView:(NSTabView*)tabView didSelectTabViewItem:(NSTabViewItem*)tabViewItem {
|
||||
tabFrame->state.selection = [tabView indexOfTabViewItem:tabViewItem];
|
||||
tabFrame->p.synchronizeLayout();
|
||||
if(tabFrame->onChange) tabFrame->onChange();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CocoaTabFrameItem : NSTabViewItem
|
||||
|
||||
-(id) initWith:(phoenix::TabFrame&)tabFrameReference {
|
||||
if(self = [super initWithIdentifier:nil]) {
|
||||
tabFrame = &tabFrameReference;
|
||||
cocoaTabFrame = tabFrame->p.cocoaTabFrame;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(NSSize) sizeOfLabel:(BOOL)shouldTruncateLabel {
|
||||
NSSize sizeOfLabel = [super sizeOfLabel:shouldTruncateLabel];
|
||||
signed selection = [cocoaTabFrame indexOfTabViewItem:self];
|
||||
if(selection < 0) return sizeOfLabel; //should never happen
|
||||
if(tabFrame->state.image[selection].empty() == false) {
|
||||
unsigned iconSize = phoenix::Font::size(tabFrame->font(), " ").height;
|
||||
sizeOfLabel.width += iconSize + 2;
|
||||
}
|
||||
return sizeOfLabel;
|
||||
}
|
||||
|
||||
-(void) drawLabel:(BOOL)shouldTruncateLabel inRect:(NSRect)tabRect {
|
||||
signed selection = [cocoaTabFrame indexOfTabViewItem:self];
|
||||
if(selection >= 0 && tabFrame->state.image[selection].empty() == false) {
|
||||
unsigned iconSize = phoenix::Font::size(tabFrame->font(), " ").height;
|
||||
NSImage* image = NSMakeImage(tabFrame->state.image[selection]);
|
||||
|
||||
[[NSGraphicsContext currentContext] saveGraphicsState];
|
||||
NSRect targetRect = NSMakeRect(tabRect.origin.x, tabRect.origin.y + 2, iconSize, iconSize);
|
||||
[image drawInRect:targetRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil];
|
||||
[[NSGraphicsContext currentContext] restoreGraphicsState];
|
||||
|
||||
tabRect.origin.x += iconSize + 2;
|
||||
tabRect.size.width -= iconSize + 2;
|
||||
}
|
||||
[super drawLabel:shouldTruncateLabel inRect:tabRect];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
void pTabFrame::append(string text, const image& image) {
|
||||
@autoreleasepool {
|
||||
CocoaTabFrameItem* item = [[CocoaTabFrameItem alloc] initWith:tabFrame];
|
||||
[item setLabel:[NSString stringWithUTF8String:text]];
|
||||
[cocoaView addTabViewItem:item];
|
||||
tabs.append(item);
|
||||
}
|
||||
}
|
||||
|
||||
void pTabFrame::remove(unsigned selection) {
|
||||
@autoreleasepool {
|
||||
CocoaTabFrameItem* item = tabs[selection];
|
||||
[cocoaView removeTabViewItem:item];
|
||||
tabs.remove(selection);
|
||||
}
|
||||
}
|
||||
|
||||
void pTabFrame::setEnabled(bool enabled) {
|
||||
for(auto& layout : tabFrame.state.layout) {
|
||||
if(layout) layout->setEnabled(layout->enabled());
|
||||
}
|
||||
pWidget::setEnabled(enabled);
|
||||
}
|
||||
|
||||
void pTabFrame::setGeometry(Geometry geometry) {
|
||||
pWidget::setGeometry({
|
||||
geometry.x - 7, geometry.y - 5,
|
||||
geometry.width + 14, geometry.height + 6
|
||||
});
|
||||
geometry.x += 1, geometry.width -= 2;
|
||||
geometry.y += 22, geometry.height -= 32;
|
||||
for(auto& layout : tabFrame.state.layout) {
|
||||
if(layout == nullptr) continue;
|
||||
layout->setGeometry(geometry);
|
||||
}
|
||||
synchronizeLayout();
|
||||
}
|
||||
|
||||
void pTabFrame::setImage(unsigned selection, const image& image) {
|
||||
}
|
||||
|
||||
void pTabFrame::setSelection(unsigned selection) {
|
||||
@autoreleasepool {
|
||||
CocoaTabFrameItem* item = tabs[selection];
|
||||
[cocoaView selectTabViewItem:item];
|
||||
}
|
||||
synchronizeLayout();
|
||||
}
|
||||
|
||||
void pTabFrame::setText(unsigned selection, string text) {
|
||||
@autoreleasepool {
|
||||
CocoaTabFrameItem* item = tabs[selection];
|
||||
[item setLabel:[NSString stringWithUTF8String:text]];
|
||||
}
|
||||
}
|
||||
|
||||
void pTabFrame::setVisible(bool visible) {
|
||||
for(auto& layout : tabFrame.state.layout) {
|
||||
if(layout) layout->setVisible(layout->visible());
|
||||
}
|
||||
pWidget::setVisible(visible);
|
||||
}
|
||||
|
||||
void pTabFrame::constructor() {
|
||||
@autoreleasepool {
|
||||
cocoaView = cocoaTabFrame = [[CocoaTabFrame alloc] initWith:tabFrame];
|
||||
}
|
||||
}
|
||||
|
||||
void pTabFrame::destructor() {
|
||||
@autoreleasepool {
|
||||
[cocoaView release];
|
||||
}
|
||||
}
|
||||
|
||||
void pTabFrame::synchronizeLayout() {
|
||||
unsigned selection = 0;
|
||||
for(auto& layout : tabFrame.state.layout) {
|
||||
if(layout) layout->setVisible(selection == tabFrame.state.selection);
|
||||
selection++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
@interface CocoaTabFrame : NSTabView <NSTabViewDelegate> {
|
||||
@public
|
||||
phoenix::TabFrame* tabFrame;
|
||||
}
|
||||
-(id) initWith:(phoenix::TabFrame&)tabFrame;
|
||||
-(void) tabView:(NSTabView*)tabView didSelectTabViewItem:(NSTabViewItem*)tabViewItem;
|
||||
@end
|
||||
|
||||
@interface CocoaTabFrameItem : NSTabViewItem {
|
||||
@public
|
||||
phoenix::TabFrame* tabFrame;
|
||||
CocoaTabFrame* cocoaTabFrame;
|
||||
}
|
||||
-(id) initWith:(phoenix::TabFrame&)tabFrame;
|
||||
-(NSSize) sizeOfLabel:(BOOL)shouldTruncateLabel;
|
||||
-(void) drawLabel:(BOOL)shouldTruncateLabel inRect:(NSRect)tabRect;
|
||||
@end
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
struct pTabFrame : public pWidget {
|
||||
TabFrame& tabFrame;
|
||||
CocoaTabFrame* cocoaTabFrame = nullptr;
|
||||
vector<CocoaTabFrameItem*> tabs;
|
||||
|
||||
void append(string text, const image& image);
|
||||
void remove(unsigned selection);
|
||||
void setEnabled(bool enabled);
|
||||
void setGeometry(Geometry geometry);
|
||||
void setImage(unsigned selection, const image& image);
|
||||
void setSelection(unsigned selection);
|
||||
void setText(unsigned selection, string text);
|
||||
void setVisible(bool visible);
|
||||
|
||||
pTabFrame(TabFrame& tabFrame) : pWidget(tabFrame), tabFrame(tabFrame) {}
|
||||
void constructor();
|
||||
void destructor();
|
||||
void synchronizeLayout();
|
||||
};
|
||||
|
||||
}
|
|
@ -58,12 +58,6 @@ Size pVerticalScroller::minimumSize() {
|
|||
}
|
||||
}
|
||||
|
||||
unsigned pVerticalScroller::position() {
|
||||
@autoreleasepool {
|
||||
return [cocoaView doubleValue] * verticalScroller.state.length;
|
||||
}
|
||||
}
|
||||
|
||||
void pVerticalScroller::setLength(unsigned length) {
|
||||
@autoreleasepool {
|
||||
[cocoaView update];
|
||||
|
|
|
@ -14,7 +14,6 @@ struct pVerticalScroller : public pWidget {
|
|||
CocoaVerticalScroller* cocoaVerticalScroller = nullptr;
|
||||
|
||||
Size minimumSize();
|
||||
unsigned position();
|
||||
void setLength(unsigned length);
|
||||
void setPosition(unsigned position);
|
||||
|
||||
|
|
|
@ -24,12 +24,6 @@ Size pVerticalSlider::minimumSize() {
|
|||
return {20, 48};
|
||||
}
|
||||
|
||||
unsigned pVerticalSlider::position() {
|
||||
@autoreleasepool {
|
||||
return [cocoaView doubleValue];
|
||||
}
|
||||
}
|
||||
|
||||
void pVerticalSlider::setGeometry(Geometry geometry) {
|
||||
pWidget::setGeometry({
|
||||
geometry.x, geometry.y - 2,
|
||||
|
|
|
@ -13,7 +13,6 @@ struct pVerticalSlider : public pWidget {
|
|||
CocoaVerticalSlider* cocoaVerticalSlider = nullptr;
|
||||
|
||||
Size minimumSize();
|
||||
unsigned position();
|
||||
void setGeometry(Geometry geometry);
|
||||
void setLength(unsigned length);
|
||||
void setPosition(unsigned position);
|
||||
|
|
|
@ -17,8 +17,9 @@ Size pWidget::minimumSize() {
|
|||
}
|
||||
|
||||
void pWidget::setEnabled(bool enabled) {
|
||||
if(!widget.parent()) enabled = false;
|
||||
if(widget.state.abstract) enabled = false;
|
||||
if(sizable.state.layout && sizable.state.layout->enabled() == false) enabled = false;
|
||||
if(!widget.enabledToAll()) enabled = false;
|
||||
|
||||
@autoreleasepool {
|
||||
if([cocoaView respondsToSelector:@selector(setEnabled:)]) {
|
||||
|
@ -47,11 +48,13 @@ void pWidget::setGeometry(Geometry geometry) {
|
|||
[cocoaView setFrame:NSMakeRect(geometry.x, windowHeight - geometry.y - geometry.height, geometry.width, geometry.height)];
|
||||
[[cocoaView superview] setNeedsDisplay:YES];
|
||||
}
|
||||
if(widget.onSize) widget.onSize();
|
||||
}
|
||||
|
||||
void pWidget::setVisible(bool visible) {
|
||||
if(!widget.parent()) visible = false;
|
||||
if(widget.state.abstract) visible = false;
|
||||
if(sizable.state.layout && sizable.state.layout->visible() == false) visible = false;
|
||||
if(!widget.visibleToAll()) visible = false;
|
||||
|
||||
@autoreleasepool {
|
||||
[cocoaView setHidden:!visible];
|
||||
|
|
|
@ -7,11 +7,11 @@ struct pWidget : public pSizable {
|
|||
bool enabled();
|
||||
bool focused();
|
||||
virtual Size minimumSize();
|
||||
void setEnabled(bool enabled);
|
||||
virtual void setEnabled(bool enabled);
|
||||
void setFocused();
|
||||
virtual void setFont(string font);
|
||||
virtual void setGeometry(Geometry geometry);
|
||||
void setVisible(bool visible);
|
||||
virtual void setVisible(bool visible);
|
||||
|
||||
pWidget(Widget& widget) : pSizable(widget), widget(widget) {}
|
||||
void constructor();
|
||||
|
|
|
@ -170,24 +170,12 @@ void pWindow::append(Widget& widget) {
|
|||
|
||||
@autoreleasepool {
|
||||
[widget.p.cocoaView removeFromSuperview];
|
||||
[[cocoaWindow contentView] addSubview:widget.p.cocoaView positioned:NSWindowBelow relativeTo:nil];
|
||||
[[cocoaWindow contentView] addSubview:widget.p.cocoaView positioned:NSWindowAbove relativeTo:nil];
|
||||
widget.p.setGeometry(widget.geometry());
|
||||
[[cocoaWindow contentView] setNeedsDisplay:YES];
|
||||
}
|
||||
}
|
||||
|
||||
Color pWindow::backgroundColor() {
|
||||
@autoreleasepool {
|
||||
NSColor* color = [[cocoaWindow backgroundColor] colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
|
||||
return {
|
||||
uint8_t(255 * [color redComponent]),
|
||||
uint8_t(255 * [color greenComponent]),
|
||||
uint8_t(255 * [color blueComponent]),
|
||||
uint8_t(255 * [color alphaComponent])
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
bool pWindow::focused() {
|
||||
@autoreleasepool {
|
||||
return [cocoaWindow isMainWindow] == YES;
|
||||
|
@ -362,6 +350,14 @@ void pWindow::setWidgetFont(string font) {
|
|||
void pWindow::constructor() {
|
||||
@autoreleasepool {
|
||||
cocoaWindow = [[CocoaWindow alloc] initWith:window];
|
||||
|
||||
NSColor* color = [[cocoaWindow backgroundColor] colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
|
||||
window.state.backgroundColor = Color(
|
||||
(uint8_t)(255 * [color redComponent]),
|
||||
(uint8_t)(255 * [color greenComponent]),
|
||||
(uint8_t)(255 * [color blueComponent]),
|
||||
(uint8_t)(255 * [color alphaComponent])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@ struct pWindow : public pObject {
|
|||
void append(Layout& layout);
|
||||
void append(Menu& menu);
|
||||
void append(Widget& widget);
|
||||
Color backgroundColor();
|
||||
bool focused();
|
||||
Geometry frameMargin();
|
||||
Geometry geometry();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -37,8 +37,10 @@ struct pWidget;
|
|||
struct pButton;
|
||||
struct pCanvas;
|
||||
struct pCheckButton;
|
||||
struct pCheckLabel;
|
||||
struct pComboButton;
|
||||
struct pConsole;
|
||||
struct pFrame;
|
||||
struct pHexEdit;
|
||||
struct pHorizontalScroller;
|
||||
struct pHorizontalSlider;
|
||||
|
@ -47,6 +49,8 @@ struct pLineEdit;
|
|||
struct pListView;
|
||||
struct pProgressBar;
|
||||
struct pRadioButton;
|
||||
struct pRadioLabel;
|
||||
struct pTabFrame;
|
||||
struct pTextEdit;
|
||||
struct pVerticalScroller;
|
||||
struct pVerticalSlider;
|
||||
|
@ -59,7 +63,7 @@ struct Application {
|
|||
static bool pendingEvents();
|
||||
static void processEvents();
|
||||
static void quit();
|
||||
static void setName(nall::string name);
|
||||
static void setName(const nall::string& name);
|
||||
|
||||
Application() = delete;
|
||||
struct State;
|
||||
|
@ -78,17 +82,13 @@ struct Application {
|
|||
};
|
||||
};
|
||||
|
||||
enum : unsigned {
|
||||
MaximumSize = ~0u,
|
||||
MinimumSize = 0u,
|
||||
};
|
||||
|
||||
struct Color {
|
||||
uint8_t red, green, blue, alpha;
|
||||
uint32_t rgb() const;
|
||||
uint32_t rgba() const;
|
||||
inline Color() : red(0), green(0), blue(0), alpha(255) {}
|
||||
inline Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha = 255) : red(red), green(green), blue(blue), alpha(alpha) {}
|
||||
uint32_t argb() const;
|
||||
inline Color() : alpha(255), red(0), green(0), blue(0) {}
|
||||
inline Color(uint8_t red, uint8_t green, uint8_t blue) : alpha(255), red(red), green(green), blue(blue) {}
|
||||
inline Color(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue) : alpha(alpha), red(red), green(green), blue(blue) {}
|
||||
};
|
||||
|
||||
struct Position {
|
||||
|
@ -98,6 +98,9 @@ struct Position {
|
|||
};
|
||||
|
||||
struct Size {
|
||||
static const unsigned Maximum = ~0u;
|
||||
static const unsigned Minimum = 0u;
|
||||
|
||||
unsigned width, height;
|
||||
inline Size() : width(0), height(0) {}
|
||||
template<typename W, typename H> inline Size(W width, H height) : width(width), height(height) {}
|
||||
|
@ -112,16 +115,16 @@ struct Geometry {
|
|||
inline Geometry() : x(0), y(0), width(0), height(0) {}
|
||||
inline Geometry(Position position, Size size) : x(position.x), y(position.y), width(size.width), height(size.height) {}
|
||||
template<typename X, typename Y, typename W, typename H> inline Geometry(X x, Y y, W width, H height) : x(x), y(y), width(width), height(height) {}
|
||||
Geometry(nall::string text);
|
||||
Geometry(const nall::string& text);
|
||||
};
|
||||
|
||||
enum class Orientation : unsigned { Horizontal, Vertical };
|
||||
|
||||
struct Font {
|
||||
static nall::string serif(unsigned size = 0, nall::string style = "");
|
||||
static nall::string sans(unsigned size = 0, nall::string style = "");
|
||||
static nall::string monospace(unsigned size = 0, nall::string style = "");
|
||||
static Size size(nall::string font, nall::string text);
|
||||
static nall::string serif(unsigned size = 0, const nall::string& style = "");
|
||||
static nall::string sans(unsigned size = 0, const nall::string& style = "");
|
||||
static nall::string monospace(unsigned size = 0, const nall::string& style = "");
|
||||
static Size size(const nall::string& font, const nall::string& text);
|
||||
Font() = delete;
|
||||
};
|
||||
|
||||
|
@ -148,15 +151,13 @@ struct Mouse {
|
|||
};
|
||||
|
||||
struct BrowserWindow {
|
||||
template<typename... Args> BrowserWindow& setFilters(Args&&... args) { return setFilters_({args...}); }
|
||||
|
||||
nall::string directory();
|
||||
nall::string open();
|
||||
nall::string save();
|
||||
BrowserWindow& setFilters_(const nall::lstring& filters);
|
||||
BrowserWindow& setFilters(const nall::lstring& filters);
|
||||
BrowserWindow& setParent(Window& parent);
|
||||
BrowserWindow& setPath(nall::string path);
|
||||
BrowserWindow& setTitle(nall::string title);
|
||||
BrowserWindow& setPath(const nall::string& path);
|
||||
BrowserWindow& setTitle(const nall::string& title);
|
||||
|
||||
BrowserWindow();
|
||||
~BrowserWindow();
|
||||
|
@ -183,11 +184,11 @@ struct MessageWindow {
|
|||
Response information(Buttons = Buttons::Ok);
|
||||
Response question(Buttons = Buttons::YesNo);
|
||||
MessageWindow& setParent(Window& parent);
|
||||
MessageWindow& setText(nall::string text);
|
||||
MessageWindow& setTitle(nall::string title);
|
||||
MessageWindow& setText(const nall::string& text);
|
||||
MessageWindow& setTitle(const nall::string& title);
|
||||
Response warning(Buttons = Buttons::Ok);
|
||||
|
||||
MessageWindow(nall::string text = "");
|
||||
MessageWindow(const nall::string& text = "");
|
||||
~MessageWindow();
|
||||
struct State;
|
||||
State& state;
|
||||
|
@ -204,8 +205,10 @@ struct Object {
|
|||
struct Timer : private nall::base_from_member<pTimer&>, Object {
|
||||
nall::function<void ()> onActivate;
|
||||
|
||||
bool enabled() const;
|
||||
unsigned interval() const;
|
||||
void setEnabled(bool enabled = true);
|
||||
void setInterval(unsigned milliseconds);
|
||||
void setInterval(unsigned interval); //in milliseconds
|
||||
|
||||
Timer();
|
||||
~Timer();
|
||||
|
@ -222,45 +225,47 @@ struct Window : private nall::base_from_member<pWindow&>, Object {
|
|||
nall::function<void ()> onMove;
|
||||
nall::function<void ()> onSize;
|
||||
|
||||
static Window& none();
|
||||
|
||||
inline void append() {}
|
||||
inline void remove() {}
|
||||
template<typename T, typename... Args> void append(T& arg, Args&&... args) { append_(arg); append(args...); }
|
||||
template<typename T, typename... Args> void remove(T& arg, Args&&... args) { remove_(arg); remove(args...); }
|
||||
|
||||
void append_(Layout& layout);
|
||||
void append_(Menu& menu);
|
||||
void append_(Widget& widget);
|
||||
Color backgroundColor();
|
||||
void append(Layout& layout);
|
||||
void append(Menu& menu);
|
||||
void append(Widget& widget);
|
||||
Color backgroundColor() const;
|
||||
bool droppable() const;
|
||||
Geometry frameGeometry();
|
||||
Geometry frameMargin();
|
||||
bool focused();
|
||||
bool fullScreen();
|
||||
bool fullScreen() const;
|
||||
Geometry geometry();
|
||||
void remove_(Layout& layout);
|
||||
void remove_(Menu& menu);
|
||||
void remove_(Widget& widget);
|
||||
nall::string menuFont() const;
|
||||
bool menuVisible() const;
|
||||
bool modal() const;
|
||||
void remove(Layout& layout);
|
||||
void remove(Menu& menu);
|
||||
void remove(Widget& widget);
|
||||
bool resizable() const;
|
||||
void setBackgroundColor(Color color);
|
||||
void setDroppable(bool droppable = true);
|
||||
void setFrameGeometry(Geometry geometry);
|
||||
void setFocused();
|
||||
void setFullScreen(bool fullScreen = true);
|
||||
void setGeometry(Geometry geometry);
|
||||
void setMenuFont(nall::string font);
|
||||
void setMenuFont(const nall::string& font);
|
||||
void setMenuVisible(bool visible = true);
|
||||
void setModal(bool modal = true);
|
||||
void setResizable(bool resizable = true);
|
||||
void setSmartGeometry(Geometry geometry);
|
||||
void setStatusFont(nall::string font);
|
||||
void setStatusText(nall::string text);
|
||||
void setStatusFont(const nall::string& font);
|
||||
void setStatusText(const nall::string& text);
|
||||
void setStatusVisible(bool visible = true);
|
||||
void setTitle(nall::string text);
|
||||
void setTitle(const nall::string& text);
|
||||
void setVisible(bool visible = true);
|
||||
void setWidgetFont(nall::string font);
|
||||
nall::string statusText();
|
||||
void setWidgetFont(const nall::string& font);
|
||||
void setWindowGeometry(Geometry geometry);
|
||||
nall::string statusFont() const;
|
||||
nall::string statusText() const;
|
||||
bool statusVisible() const;
|
||||
void synchronizeLayout();
|
||||
bool visible();
|
||||
nall::string title() const;
|
||||
bool visible() const;
|
||||
nall::string widgetFont() const;
|
||||
|
||||
Window();
|
||||
~Window();
|
||||
|
@ -270,10 +275,10 @@ struct Window : private nall::base_from_member<pWindow&>, Object {
|
|||
};
|
||||
|
||||
struct Action : Object {
|
||||
bool enabled();
|
||||
bool enabled() const;
|
||||
void setEnabled(bool enabled = true);
|
||||
void setVisible(bool visible = true);
|
||||
bool visible();
|
||||
bool visible() const;
|
||||
|
||||
Action(pAction& p);
|
||||
~Action();
|
||||
|
@ -283,13 +288,12 @@ struct Action : Object {
|
|||
};
|
||||
|
||||
struct Menu : private nall::base_from_member<pMenu&>, Action {
|
||||
template<typename... Args> void append(Args&&... args) { append({std::forward<Args>(args)...}); }
|
||||
template<typename... Args> void remove(Args&&... args) { remove({std::forward<Args>(args)...}); }
|
||||
|
||||
void append(const nall::group<Action>& list);
|
||||
nall::image image() const;
|
||||
void remove(const nall::group<Action>& list);
|
||||
void setImage(const nall::image& image = nall::image{});
|
||||
void setText(nall::string text);
|
||||
void setText(const nall::string& text);
|
||||
nall::string text() const;
|
||||
|
||||
Menu();
|
||||
~Menu();
|
||||
|
@ -307,8 +311,10 @@ struct Separator : private nall::base_from_member<pSeparator&>, Action {
|
|||
struct Item : private nall::base_from_member<pItem&>, Action {
|
||||
nall::function<void ()> onActivate;
|
||||
|
||||
nall::image image() const;
|
||||
void setImage(const nall::image& image = nall::image{});
|
||||
void setText(nall::string text);
|
||||
void setText(const nall::string& text);
|
||||
nall::string text() const;
|
||||
|
||||
Item();
|
||||
~Item();
|
||||
|
@ -320,9 +326,10 @@ struct Item : private nall::base_from_member<pItem&>, Action {
|
|||
struct CheckItem : private nall::base_from_member<pCheckItem&>, Action {
|
||||
nall::function<void ()> onToggle;
|
||||
|
||||
bool checked();
|
||||
bool checked() const;
|
||||
void setChecked(bool checked = true);
|
||||
void setText(nall::string text);
|
||||
void setText(const nall::string& text);
|
||||
nall::string text() const;
|
||||
|
||||
CheckItem();
|
||||
~CheckItem();
|
||||
|
@ -337,10 +344,10 @@ struct RadioItem : private nall::base_from_member<pRadioItem&>, Action {
|
|||
|
||||
nall::function<void ()> onActivate;
|
||||
|
||||
bool checked();
|
||||
bool checked() const;
|
||||
void setChecked();
|
||||
void setText(nall::string text);
|
||||
nall::string text();
|
||||
void setText(const nall::string& text);
|
||||
nall::string text() const;
|
||||
|
||||
RadioItem();
|
||||
~RadioItem();
|
||||
|
@ -350,14 +357,18 @@ struct RadioItem : private nall::base_from_member<pRadioItem&>, Action {
|
|||
};
|
||||
|
||||
struct Sizable : Object {
|
||||
virtual bool enabled() = 0;
|
||||
Layout* layout();
|
||||
bool enabled() const;
|
||||
bool enabledToAll() const;
|
||||
Layout* layout() const;
|
||||
virtual Size minimumSize() = 0;
|
||||
Sizable* parent() const;
|
||||
virtual void setEnabled(bool enabled = true) = 0;
|
||||
virtual void setGeometry(Geometry geometry) = 0;
|
||||
virtual void setVisible(bool visible = true) = 0;
|
||||
virtual bool visible() = 0;
|
||||
Window* window();
|
||||
virtual void synchronizeLayout() = 0;
|
||||
bool visible() const;
|
||||
bool visibleToAll() const;
|
||||
Window* window() const;
|
||||
|
||||
Sizable(pSizable& p);
|
||||
~Sizable();
|
||||
|
@ -369,8 +380,7 @@ struct Sizable : Object {
|
|||
struct Layout : private nall::base_from_member<pLayout&>, Sizable {
|
||||
virtual void append(Sizable& sizable);
|
||||
virtual void remove(Sizable& sizable);
|
||||
virtual void reset() {}
|
||||
virtual void synchronizeLayout() = 0;
|
||||
virtual void reset();
|
||||
|
||||
Layout();
|
||||
Layout(pLayout& p);
|
||||
|
@ -381,17 +391,18 @@ struct Layout : private nall::base_from_member<pLayout&>, Sizable {
|
|||
};
|
||||
|
||||
struct Widget : private nall::base_from_member<pWidget&>, Sizable {
|
||||
bool enabled();
|
||||
nall::function<void ()> onSize;
|
||||
|
||||
bool focused();
|
||||
nall::string font();
|
||||
Geometry geometry();
|
||||
nall::string font() const;
|
||||
Geometry geometry() const;
|
||||
Size minimumSize();
|
||||
void setEnabled(bool enabled = true);
|
||||
void setFocused();
|
||||
void setFont(nall::string font);
|
||||
void setFont(const nall::string& font);
|
||||
void setGeometry(Geometry geometry);
|
||||
void setVisible(bool visible = true);
|
||||
bool visible();
|
||||
void synchronizeLayout();
|
||||
|
||||
Widget();
|
||||
Widget(pWidget& p);
|
||||
|
@ -404,8 +415,11 @@ struct Widget : private nall::base_from_member<pWidget&>, Sizable {
|
|||
struct Button : private nall::base_from_member<pButton&>, Widget {
|
||||
nall::function<void ()> onActivate;
|
||||
|
||||
void setImage(const nall::image& image = nall::image{}, Orientation = Orientation::Horizontal);
|
||||
void setText(nall::string text);
|
||||
nall::image image() const;
|
||||
Orientation orientation() const;
|
||||
void setImage(const nall::image& image = nall::image{}, Orientation orientation = Orientation::Horizontal);
|
||||
void setText(const nall::string& text);
|
||||
nall::string text() const;
|
||||
|
||||
Button();
|
||||
~Button();
|
||||
|
@ -415,18 +429,30 @@ struct Button : private nall::base_from_member<pButton&>, Widget {
|
|||
};
|
||||
|
||||
struct Canvas : private nall::base_from_member<pCanvas&>, Widget {
|
||||
enum class Mode : unsigned { Color, Gradient, Image, Data };
|
||||
|
||||
nall::function<void (nall::lstring)> onDrop;
|
||||
nall::function<void ()> onMouseLeave;
|
||||
nall::function<void (Position)> onMouseMove;
|
||||
nall::function<void (Mouse::Button)> onMousePress;
|
||||
nall::function<void (Mouse::Button)> onMouseRelease;
|
||||
|
||||
uint32_t* data();
|
||||
Color color() const;
|
||||
uint32_t* data() const;
|
||||
bool droppable() const;
|
||||
nall::vector<Color> gradient() const;
|
||||
nall::image image() const;
|
||||
Mode mode() const;
|
||||
void setColor(Color color);
|
||||
void setData();
|
||||
void setDroppable(bool droppable = true);
|
||||
bool setImage(const nall::image& image);
|
||||
void setHorizontalGradient(Color left, Color right);
|
||||
void setGradient(Color topLeft, Color topRight, Color bottomLeft, Color bottomRight);
|
||||
void setImage(const nall::image& image);
|
||||
void setMode(Mode mode);
|
||||
void setSize(Size size);
|
||||
Size size();
|
||||
void update();
|
||||
void setVerticalGradient(Color top, Color bottom);
|
||||
Size size() const;
|
||||
|
||||
Canvas();
|
||||
~Canvas();
|
||||
|
@ -438,9 +464,12 @@ struct Canvas : private nall::base_from_member<pCanvas&>, Widget {
|
|||
struct CheckButton : private nall::base_from_member<pCheckButton&>, Widget {
|
||||
nall::function<void ()> onToggle;
|
||||
|
||||
bool checked();
|
||||
bool checked() const;
|
||||
nall::image image() const;
|
||||
void setChecked(bool checked = true);
|
||||
void setText(nall::string text);
|
||||
void setImage(const nall::image& image = nall::image{}, Orientation orientation = Orientation::Horizontal);
|
||||
void setText(const nall::string& text);
|
||||
nall::string text() const;
|
||||
|
||||
CheckButton();
|
||||
~CheckButton();
|
||||
|
@ -449,19 +478,33 @@ struct CheckButton : private nall::base_from_member<pCheckButton&>, Widget {
|
|||
pCheckButton& p;
|
||||
};
|
||||
|
||||
struct CheckLabel : private nall::base_from_member<pCheckLabel&>, Widget {
|
||||
nall::function<void ()> onToggle;
|
||||
|
||||
bool checked() const;
|
||||
void setChecked(bool checked = true);
|
||||
void setText(const nall::string& text);
|
||||
nall::string text() const;
|
||||
|
||||
CheckLabel();
|
||||
~CheckLabel();
|
||||
struct State;
|
||||
State& state;
|
||||
pCheckLabel& p;
|
||||
};
|
||||
|
||||
struct ComboButton : private nall::base_from_member<pComboButton&>, Widget {
|
||||
nall::function<void ()> onChange;
|
||||
|
||||
template<typename... Args> void append(Args&&... args) { append_({args...}); }
|
||||
|
||||
void append_(const nall::lstring& list);
|
||||
void modify(unsigned row, nall::string text);
|
||||
void remove(unsigned row);
|
||||
void append(const nall::string& text = "");
|
||||
void remove(unsigned selection);
|
||||
void reset();
|
||||
unsigned selection();
|
||||
void setSelection(unsigned row);
|
||||
nall::string text();
|
||||
nall::string text(unsigned row);
|
||||
unsigned rows() const;
|
||||
unsigned selection() const;
|
||||
void setSelection(unsigned selection);
|
||||
void setText(unsigned selection, const nall::string& text);
|
||||
nall::string text() const;
|
||||
nall::string text(unsigned selection) const;
|
||||
|
||||
ComboButton();
|
||||
~ComboButton();
|
||||
|
@ -473,9 +516,9 @@ struct ComboButton : private nall::base_from_member<pComboButton&>, Widget {
|
|||
struct Console : private nall::base_from_member<pConsole&>, Widget {
|
||||
nall::function<void (nall::string)> onActivate;
|
||||
|
||||
template<typename... Args> void print(Args&&... args) { print_({args...}); }
|
||||
template<typename... Args> void print(Args&&... args) { print({args...}); }
|
||||
|
||||
void print_(nall::string text);
|
||||
void print(const nall::string& text);
|
||||
void reset();
|
||||
|
||||
Console();
|
||||
|
@ -485,10 +528,27 @@ struct Console : private nall::base_from_member<pConsole&>, Widget {
|
|||
pConsole& p;
|
||||
};
|
||||
|
||||
struct Frame : private nall::base_from_member<pFrame&>, Widget {
|
||||
void setLayout(Layout& layout);
|
||||
void setText(const nall::string& text);
|
||||
void synchronizeLayout();
|
||||
nall::string text() const;
|
||||
|
||||
Frame();
|
||||
~Frame();
|
||||
struct State;
|
||||
State& state;
|
||||
pFrame& p;
|
||||
};
|
||||
|
||||
struct HexEdit : private nall::base_from_member<pHexEdit&>, Widget {
|
||||
nall::function<uint8_t (unsigned)> onRead;
|
||||
nall::function<void (unsigned, uint8_t)> onWrite;
|
||||
|
||||
unsigned columns() const;
|
||||
unsigned length() const;
|
||||
unsigned offset() const;
|
||||
unsigned rows() const;
|
||||
void setColumns(unsigned columns);
|
||||
void setLength(unsigned length);
|
||||
void setOffset(unsigned offset);
|
||||
|
@ -505,8 +565,8 @@ struct HexEdit : private nall::base_from_member<pHexEdit&>, Widget {
|
|||
struct HorizontalScroller : private nall::base_from_member<pHorizontalScroller&>, Widget {
|
||||
nall::function<void ()> onChange;
|
||||
|
||||
unsigned length();
|
||||
unsigned position();
|
||||
unsigned length() const;
|
||||
unsigned position() const;
|
||||
void setLength(unsigned length);
|
||||
void setPosition(unsigned position);
|
||||
|
||||
|
@ -520,8 +580,8 @@ struct HorizontalScroller : private nall::base_from_member<pHorizontalScroller&>
|
|||
struct HorizontalSlider : private nall::base_from_member<pHorizontalSlider&>, Widget {
|
||||
nall::function<void ()> onChange;
|
||||
|
||||
unsigned length();
|
||||
unsigned position();
|
||||
unsigned length() const;
|
||||
unsigned position() const;
|
||||
void setLength(unsigned length);
|
||||
void setPosition(unsigned position);
|
||||
|
||||
|
@ -533,7 +593,8 @@ struct HorizontalSlider : private nall::base_from_member<pHorizontalSlider&>, Wi
|
|||
};
|
||||
|
||||
struct Label : private nall::base_from_member<pLabel&>, Widget {
|
||||
void setText(nall::string text);
|
||||
void setText(const nall::string& text);
|
||||
nall::string text() const;
|
||||
|
||||
Label();
|
||||
~Label();
|
||||
|
@ -546,8 +607,9 @@ struct LineEdit : private nall::base_from_member<pLineEdit&>, Widget {
|
|||
nall::function<void ()> onActivate;
|
||||
nall::function<void ()> onChange;
|
||||
|
||||
bool editable() const;
|
||||
void setEditable(bool editable = true);
|
||||
void setText(nall::string text);
|
||||
void setText(const nall::string& text);
|
||||
nall::string text();
|
||||
|
||||
LineEdit();
|
||||
|
@ -562,25 +624,28 @@ struct ListView : private nall::base_from_member<pListView&>, Widget {
|
|||
nall::function<void ()> onChange;
|
||||
nall::function<void (unsigned)> onToggle;
|
||||
|
||||
template<typename... Args> void append(Args&&... args) { append_({args...}); }
|
||||
template<typename... Args> void modify(unsigned row, Args&&... args) { modify_(row, {args...}); }
|
||||
template<typename... Args> void setHeaderText(Args&&... args) { setHeaderText_({args...}); }
|
||||
|
||||
void append_(const nall::lstring& list);
|
||||
void append(const nall::lstring& text);
|
||||
void autoSizeColumns();
|
||||
bool checked(unsigned row);
|
||||
void modify_(unsigned row, const nall::lstring& list);
|
||||
void remove(unsigned row);
|
||||
bool checkable() const;
|
||||
bool checked(unsigned selection) const;
|
||||
unsigned columns() const;
|
||||
bool headerVisible() const;
|
||||
nall::image image(unsigned selection, unsigned position) const;
|
||||
void remove(unsigned selection);
|
||||
void reset();
|
||||
bool selected();
|
||||
unsigned selection();
|
||||
unsigned rows() const;
|
||||
bool selected() const;
|
||||
unsigned selection() const;
|
||||
void setCheckable(bool checkable = true);
|
||||
void setChecked(unsigned row, bool checked = true);
|
||||
void setHeaderText_(const nall::lstring& list);
|
||||
void setChecked(unsigned selection, bool checked = true);
|
||||
void setHeaderText(const nall::lstring& text);
|
||||
void setHeaderVisible(bool visible = true);
|
||||
void setImage(unsigned row, unsigned column, const nall::image& image = nall::image{});
|
||||
void setImage(unsigned selection, unsigned position, const nall::image& image = nall::image{});
|
||||
void setSelected(bool selected = true);
|
||||
void setSelection(unsigned row);
|
||||
void setSelection(unsigned selection);
|
||||
void setText(unsigned selection, const nall::lstring& text);
|
||||
void setText(unsigned selection, unsigned position, const nall::string& text);
|
||||
nall::string text(unsigned selection, unsigned position) const;
|
||||
|
||||
ListView();
|
||||
~ListView();
|
||||
|
@ -590,6 +655,7 @@ struct ListView : private nall::base_from_member<pListView&>, Widget {
|
|||
};
|
||||
|
||||
struct ProgressBar : private nall::base_from_member<pProgressBar&>, Widget {
|
||||
unsigned position() const;
|
||||
void setPosition(unsigned position);
|
||||
|
||||
ProgressBar();
|
||||
|
@ -605,9 +671,12 @@ struct RadioButton : private nall::base_from_member<pRadioButton&>, Widget {
|
|||
|
||||
nall::function<void ()> onActivate;
|
||||
|
||||
bool checked();
|
||||
bool checked() const;
|
||||
nall::image image() const;
|
||||
void setChecked();
|
||||
void setText(nall::string text);
|
||||
void setImage(const nall::image& image = nall::image{}, Orientation orientation = Orientation::Horizontal);
|
||||
void setText(const nall::string& text);
|
||||
nall::string text() const;
|
||||
|
||||
RadioButton();
|
||||
~RadioButton();
|
||||
|
@ -616,15 +685,56 @@ struct RadioButton : private nall::base_from_member<pRadioButton&>, Widget {
|
|||
pRadioButton& p;
|
||||
};
|
||||
|
||||
struct RadioLabel : private nall::base_from_member<pRadioLabel&>, Widget {
|
||||
template<typename... Args> static void group(Args&&... args) { group({std::forward<Args>(args)...}); }
|
||||
static void group(const nall::group<RadioLabel>& list);
|
||||
|
||||
nall::function<void ()> onActivate;
|
||||
|
||||
bool checked() const;
|
||||
void setChecked();
|
||||
void setText(const nall::string& text);
|
||||
nall::string text() const;
|
||||
|
||||
RadioLabel();
|
||||
~RadioLabel();
|
||||
struct State;
|
||||
State& state;
|
||||
pRadioLabel& p;
|
||||
};
|
||||
|
||||
struct TabFrame : private nall::base_from_member<pTabFrame&>, Widget {
|
||||
nall::function<void ()> onChange;
|
||||
|
||||
void append(const nall::string& text = "", const nall::image& image = nall::image{});
|
||||
nall::image image(unsigned selection) const;
|
||||
void remove(unsigned selection);
|
||||
unsigned selection() const;
|
||||
void setImage(unsigned selection, const nall::image& image = nall::image{});
|
||||
void setLayout(unsigned selection, Layout& layout);
|
||||
void setSelection(unsigned selection);
|
||||
void setText(unsigned selection, const nall::string& text);
|
||||
void synchronizeLayout();
|
||||
unsigned tabs() const;
|
||||
nall::string text(unsigned selection) const;
|
||||
|
||||
TabFrame();
|
||||
~TabFrame();
|
||||
struct State;
|
||||
State& state;
|
||||
pTabFrame& p;
|
||||
};
|
||||
|
||||
struct TextEdit : private nall::base_from_member<pTextEdit&>, Widget {
|
||||
nall::function<void ()> onChange;
|
||||
|
||||
bool editable() const;
|
||||
void setCursorPosition(unsigned position);
|
||||
void setEditable(bool editable = true);
|
||||
void setText(nall::string text);
|
||||
void setText(const nall::string& text);
|
||||
void setWordWrap(bool wordWrap = true);
|
||||
nall::string text();
|
||||
bool wordWrap();
|
||||
bool wordWrap() const;
|
||||
|
||||
TextEdit();
|
||||
~TextEdit();
|
||||
|
@ -636,8 +746,8 @@ struct TextEdit : private nall::base_from_member<pTextEdit&>, Widget {
|
|||
struct VerticalScroller : private nall::base_from_member<pVerticalScroller&>, Widget {
|
||||
nall::function<void ()> onChange;
|
||||
|
||||
unsigned length();
|
||||
unsigned position();
|
||||
unsigned length() const;
|
||||
unsigned position() const;
|
||||
void setLength(unsigned length);
|
||||
void setPosition(unsigned position);
|
||||
|
||||
|
@ -651,8 +761,8 @@ struct VerticalScroller : private nall::base_from_member<pVerticalScroller&>, Wi
|
|||
struct VerticalSlider : private nall::base_from_member<pVerticalSlider&>, Widget {
|
||||
nall::function<void ()> onChange;
|
||||
|
||||
unsigned length();
|
||||
unsigned position();
|
||||
unsigned length() const;
|
||||
unsigned position() const;
|
||||
void setLength(unsigned length);
|
||||
void setPosition(unsigned position);
|
||||
|
||||
|
@ -670,6 +780,7 @@ struct Viewport : private nall::base_from_member<pViewport&>, Widget {
|
|||
nall::function<void (Mouse::Button)> onMousePress;
|
||||
nall::function<void (Mouse::Button)> onMouseRelease;
|
||||
|
||||
bool droppable() const;
|
||||
uintptr_t handle();
|
||||
void setDroppable(bool droppable = true);
|
||||
|
||||
|
|
|
@ -10,13 +10,8 @@ void FixedLayout::append(Sizable& sizable) {
|
|||
if(window()) window()->synchronizeLayout();
|
||||
}
|
||||
|
||||
bool FixedLayout::enabled() {
|
||||
if(layout()) return state.enabled && layout()->enabled();
|
||||
return state.enabled;
|
||||
}
|
||||
|
||||
Size FixedLayout::minimumSize() {
|
||||
unsigned width = MinimumSize, height = MinimumSize;
|
||||
unsigned width = Size::Minimum, height = Size::Minimum;
|
||||
for(auto& child : children) {
|
||||
width = max(width, child.sizable->minimumSize().width);
|
||||
height = max(height, child.sizable->minimumSize().height);
|
||||
|
@ -42,9 +37,9 @@ void FixedLayout::reset() {
|
|||
}
|
||||
|
||||
void FixedLayout::setEnabled(bool enabled) {
|
||||
state.enabled = enabled;
|
||||
Sizable::state.enabled = enabled;
|
||||
for(auto& child : children) {
|
||||
child.sizable->setVisible(dynamic_cast<Widget*>(child.sizable) ? child.sizable->enabled() : enabled);
|
||||
child.sizable->setEnabled(child.sizable->enabled());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,29 +47,22 @@ void FixedLayout::setGeometry(Geometry geometry) {
|
|||
}
|
||||
|
||||
void FixedLayout::setVisible(bool visible) {
|
||||
state.visible = visible;
|
||||
Sizable::state.visible = visible;
|
||||
for(auto& child : children) {
|
||||
child.sizable->setVisible(dynamic_cast<Widget*>(child.sizable) ? child.sizable->visible() : visible);
|
||||
child.sizable->setVisible(child.sizable->visible());
|
||||
}
|
||||
}
|
||||
|
||||
void FixedLayout::synchronizeLayout() {
|
||||
for(auto& child : children) {
|
||||
Layout::append(*child.sizable);
|
||||
child.sizable->setGeometry(child.geometry);
|
||||
Geometry childGeometry = child.geometry;
|
||||
if((signed)childGeometry.width < 1) childGeometry.width = 1;
|
||||
if((signed)childGeometry.height < 1) childGeometry.height = 1;
|
||||
child.sizable->setGeometry(childGeometry);
|
||||
}
|
||||
}
|
||||
|
||||
bool FixedLayout::visible() {
|
||||
if(layout()) return state.visible && layout()->visible();
|
||||
return state.visible;
|
||||
}
|
||||
|
||||
FixedLayout::FixedLayout() {
|
||||
state.enabled = true;
|
||||
state.visible = true;
|
||||
}
|
||||
|
||||
FixedLayout::~FixedLayout() {
|
||||
while(children.size()) remove(*children[0].sizable);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
struct FixedLayout : Layout {
|
||||
void append(Sizable& sizable, Geometry geometry);
|
||||
void append(Sizable& sizable);
|
||||
bool enabled();
|
||||
Size minimumSize();
|
||||
void remove(Sizable& sizable);
|
||||
void reset();
|
||||
|
@ -9,16 +8,9 @@ struct FixedLayout : Layout {
|
|||
void setGeometry(Geometry geometry);
|
||||
void setVisible(bool visible = true);
|
||||
void synchronizeLayout();
|
||||
bool visible();
|
||||
FixedLayout();
|
||||
~FixedLayout();
|
||||
|
||||
//private:
|
||||
struct State {
|
||||
bool enabled;
|
||||
bool visible;
|
||||
} state;
|
||||
|
||||
struct Children {
|
||||
Sizable* sizable;
|
||||
Geometry geometry;
|
||||
|
|
|
@ -11,17 +11,12 @@ void HorizontalLayout::append(Sizable& sizable) {
|
|||
if(window()) window()->synchronizeLayout();
|
||||
}
|
||||
|
||||
bool HorizontalLayout::enabled() {
|
||||
if(layout()) return state.enabled && layout()->enabled();
|
||||
return state.enabled;
|
||||
}
|
||||
|
||||
Size HorizontalLayout::minimumSize() {
|
||||
unsigned width = 0, height = 0;
|
||||
|
||||
for(auto& child : children) {
|
||||
width += child.spacing;
|
||||
if(child.width == MinimumSize || child.width == MaximumSize) {
|
||||
if(child.width == Size::Minimum || child.width == Size::Maximum) {
|
||||
width += child.sizable->minimumSize().width;
|
||||
continue;
|
||||
}
|
||||
|
@ -29,7 +24,7 @@ Size HorizontalLayout::minimumSize() {
|
|||
}
|
||||
|
||||
for(auto& child : children) {
|
||||
if(child.height == MinimumSize || child.height == MaximumSize) {
|
||||
if(child.height == Size::Minimum || child.height == Size::Maximum) {
|
||||
height = max(height, child.sizable->minimumSize().height);
|
||||
continue;
|
||||
}
|
||||
|
@ -43,7 +38,7 @@ void HorizontalLayout::remove(Sizable& sizable) {
|
|||
for(unsigned n = 0; n < children.size(); n++) {
|
||||
if(children[n].sizable == &sizable) {
|
||||
if(dynamic_cast<Layout*>(children[n].sizable)) {
|
||||
Layout *layout = (Layout*)children[n].sizable;
|
||||
Layout* layout = (Layout*)children[n].sizable;
|
||||
layout->reset();
|
||||
}
|
||||
children.remove(n);
|
||||
|
@ -66,17 +61,17 @@ void HorizontalLayout::setAlignment(double alignment) {
|
|||
}
|
||||
|
||||
void HorizontalLayout::setEnabled(bool enabled) {
|
||||
state.enabled = enabled;
|
||||
Sizable::state.enabled = enabled;
|
||||
for(auto& child : children) {
|
||||
child.sizable->setEnabled(dynamic_cast<Widget*>(child.sizable) ? child.sizable->enabled() : enabled);
|
||||
child.sizable->setEnabled(child.sizable->enabled());
|
||||
}
|
||||
}
|
||||
|
||||
void HorizontalLayout::setGeometry(Geometry containerGeometry) {
|
||||
auto children = this->children;
|
||||
for(auto& child : children) {
|
||||
if(child.width == MinimumSize) child.width = child.sizable->minimumSize().width;
|
||||
if(child.height == MinimumSize) child.height = child.sizable->minimumSize().height;
|
||||
if(child.width == Size::Minimum) child.width = child.sizable->minimumSize().width;
|
||||
if(child.height == Size::Minimum) child.height = child.sizable->minimumSize().height;
|
||||
}
|
||||
|
||||
Geometry geometry = containerGeometry;
|
||||
|
@ -87,14 +82,14 @@ void HorizontalLayout::setGeometry(Geometry containerGeometry) {
|
|||
|
||||
unsigned minimumWidth = 0, maximumWidthCounter = 0;
|
||||
for(auto& child : children) {
|
||||
if(child.width == MaximumSize) maximumWidthCounter++;
|
||||
if(child.width != MaximumSize) minimumWidth += child.width;
|
||||
if(child.width == Size::Maximum) maximumWidthCounter++;
|
||||
if(child.width != Size::Maximum) minimumWidth += child.width;
|
||||
minimumWidth += child.spacing;
|
||||
}
|
||||
|
||||
for(auto& child : children) {
|
||||
if(child.width == MaximumSize) child.width = (geometry.width - minimumWidth) / maximumWidthCounter;
|
||||
if(child.height == MaximumSize) child.height = geometry.height;
|
||||
if(child.width == Size::Maximum) child.width = (geometry.width - minimumWidth) / maximumWidthCounter;
|
||||
if(child.height == Size::Maximum) child.height = geometry.height;
|
||||
}
|
||||
|
||||
unsigned maximumHeight = 0;
|
||||
|
@ -103,6 +98,8 @@ void HorizontalLayout::setGeometry(Geometry containerGeometry) {
|
|||
for(auto& child : children) {
|
||||
unsigned pivot = (maximumHeight - child.height) * state.alignment;
|
||||
Geometry childGeometry = {geometry.x, geometry.y + pivot, child.width, child.height};
|
||||
if((signed)childGeometry.width < 1) childGeometry.width = 1;
|
||||
if((signed)childGeometry.height < 1) childGeometry.height = 1;
|
||||
child.sizable->setGeometry(childGeometry);
|
||||
|
||||
geometry.x += child.width + child.spacing;
|
||||
|
@ -115,9 +112,9 @@ void HorizontalLayout::setMargin(unsigned margin) {
|
|||
}
|
||||
|
||||
void HorizontalLayout::setVisible(bool visible) {
|
||||
state.visible = visible;
|
||||
Sizable::state.visible = visible;
|
||||
for(auto& child : children) {
|
||||
child.sizable->setVisible(dynamic_cast<Widget*>(child.sizable) ? child.sizable->visible() : visible);
|
||||
child.sizable->setVisible(child.sizable->visible());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,18 +122,6 @@ void HorizontalLayout::synchronizeLayout() {
|
|||
for(auto& child : children) Layout::append(*child.sizable);
|
||||
}
|
||||
|
||||
bool HorizontalLayout::visible() {
|
||||
if(layout()) return state.visible && layout()->visible();
|
||||
return state.visible;
|
||||
}
|
||||
|
||||
HorizontalLayout::HorizontalLayout() {
|
||||
state.alignment = 0.5;
|
||||
state.enabled = true;
|
||||
state.margin = 0;
|
||||
state.visible = true;
|
||||
}
|
||||
|
||||
HorizontalLayout::~HorizontalLayout() {
|
||||
while(children.size()) remove(*children[0].sizable);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
struct HorizontalLayout : public Layout {
|
||||
void append(Sizable& sizable, Size size, unsigned spacing = 0);
|
||||
void append(Sizable& sizable);
|
||||
bool enabled();
|
||||
Size minimumSize();
|
||||
void remove(Sizable& sizable);
|
||||
void reset();
|
||||
|
@ -11,16 +10,12 @@ struct HorizontalLayout : public Layout {
|
|||
void setMargin(unsigned margin);
|
||||
void setVisible(bool visible = true);
|
||||
void synchronizeLayout();
|
||||
bool visible();
|
||||
HorizontalLayout();
|
||||
~HorizontalLayout();
|
||||
|
||||
//private:
|
||||
struct State {
|
||||
double alignment;
|
||||
bool enabled;
|
||||
unsigned margin;
|
||||
bool visible;
|
||||
double alignment = 0.5;
|
||||
unsigned margin = 0;
|
||||
} state;
|
||||
|
||||
struct Children {
|
||||
|
|
|
@ -11,16 +11,11 @@ void VerticalLayout::append(Sizable& sizable) {
|
|||
if(window()) window()->synchronizeLayout();
|
||||
}
|
||||
|
||||
bool VerticalLayout::enabled() {
|
||||
if(layout()) return state.enabled && layout()->enabled();
|
||||
return state.enabled;
|
||||
}
|
||||
|
||||
Size VerticalLayout::minimumSize() {
|
||||
unsigned width = 0, height = 0;
|
||||
|
||||
for(auto& child : children) {
|
||||
if(child.width == MinimumSize || child.width == MaximumSize) {
|
||||
if(child.width == Size::Minimum || child.width == Size::Maximum) {
|
||||
width = max(width, child.sizable->minimumSize().width);
|
||||
continue;
|
||||
}
|
||||
|
@ -29,7 +24,7 @@ Size VerticalLayout::minimumSize() {
|
|||
|
||||
for(auto& child : children) {
|
||||
height += child.spacing;
|
||||
if(child.height == MinimumSize || child.height == MaximumSize) {
|
||||
if(child.height == Size::Minimum || child.height == Size::Maximum) {
|
||||
height += child.sizable->minimumSize().height;
|
||||
continue;
|
||||
}
|
||||
|
@ -43,7 +38,7 @@ void VerticalLayout::remove(Sizable& sizable) {
|
|||
for(unsigned n = 0; n < children.size(); n++) {
|
||||
if(children[n].sizable == &sizable) {
|
||||
if(dynamic_cast<Layout*>(children[n].sizable)) {
|
||||
Layout *layout = (Layout*)children[n].sizable;
|
||||
Layout* layout = (Layout*)children[n].sizable;
|
||||
layout->reset();
|
||||
}
|
||||
children.remove(n);
|
||||
|
@ -66,17 +61,17 @@ void VerticalLayout::setAlignment(double alignment) {
|
|||
}
|
||||
|
||||
void VerticalLayout::setEnabled(bool enabled) {
|
||||
state.enabled = enabled;
|
||||
Sizable::state.enabled = enabled;
|
||||
for(auto& child : children) {
|
||||
child.sizable->setEnabled(dynamic_cast<Widget*>(child.sizable) ? child.sizable->enabled() : enabled);
|
||||
child.sizable->setEnabled(child.sizable->enabled());
|
||||
}
|
||||
}
|
||||
|
||||
void VerticalLayout::setGeometry(Geometry containerGeometry) {
|
||||
auto children = this->children;
|
||||
for(auto& child : children) {
|
||||
if(child.width == MinimumSize) child.width = child.sizable->minimumSize().width;
|
||||
if(child.height == MinimumSize) child.height = child.sizable->minimumSize().height;
|
||||
if(child.width == Size::Minimum) child.width = child.sizable->minimumSize().width;
|
||||
if(child.height == Size::Minimum) child.height = child.sizable->minimumSize().height;
|
||||
}
|
||||
|
||||
Geometry geometry = containerGeometry;
|
||||
|
@ -87,14 +82,14 @@ void VerticalLayout::setGeometry(Geometry containerGeometry) {
|
|||
|
||||
unsigned minimumHeight = 0, maximumHeightCounter = 0;
|
||||
for(auto& child : children) {
|
||||
if(child.height == MaximumSize) maximumHeightCounter++;
|
||||
if(child.height != MaximumSize) minimumHeight += child.height;
|
||||
if(child.height == Size::Maximum) maximumHeightCounter++;
|
||||
if(child.height != Size::Maximum) minimumHeight += child.height;
|
||||
minimumHeight += child.spacing;
|
||||
}
|
||||
|
||||
for(auto& child : children) {
|
||||
if(child.width == MaximumSize) child.width = geometry.width;
|
||||
if(child.height == MaximumSize) child.height = (geometry.height - minimumHeight) / maximumHeightCounter;
|
||||
if(child.width == Size::Maximum) child.width = geometry.width;
|
||||
if(child.height == Size::Maximum) child.height = (geometry.height - minimumHeight) / maximumHeightCounter;
|
||||
}
|
||||
|
||||
unsigned maximumWidth = 0;
|
||||
|
@ -103,6 +98,8 @@ void VerticalLayout::setGeometry(Geometry containerGeometry) {
|
|||
for(auto& child : children) {
|
||||
unsigned pivot = (maximumWidth - child.width) * state.alignment;
|
||||
Geometry childGeometry = {geometry.x + pivot, geometry.y, child.width, child.height};
|
||||
if((signed)childGeometry.width < 1) childGeometry.width = 1;
|
||||
if((signed)childGeometry.height < 1) childGeometry.height = 1;
|
||||
child.sizable->setGeometry(childGeometry);
|
||||
|
||||
geometry.y += child.height + child.spacing;
|
||||
|
@ -115,9 +112,9 @@ void VerticalLayout::setMargin(unsigned margin) {
|
|||
}
|
||||
|
||||
void VerticalLayout::setVisible(bool visible) {
|
||||
state.visible = visible;
|
||||
Sizable::state.visible = visible;
|
||||
for(auto& child : children) {
|
||||
child.sizable->setVisible(dynamic_cast<Widget*>(child.sizable) ? child.sizable->visible() : visible);
|
||||
child.sizable->setVisible(child.sizable->visible());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,18 +122,6 @@ void VerticalLayout::synchronizeLayout() {
|
|||
for(auto& child : children) Layout::append(*child.sizable);
|
||||
}
|
||||
|
||||
bool VerticalLayout::visible() {
|
||||
if(layout()) return state.visible && layout()->visible();
|
||||
return state.visible;
|
||||
}
|
||||
|
||||
VerticalLayout::VerticalLayout() {
|
||||
state.alignment = 0.0;
|
||||
state.enabled = true;
|
||||
state.margin = 0;
|
||||
state.visible = true;
|
||||
}
|
||||
|
||||
VerticalLayout::~VerticalLayout() {
|
||||
while(children.size()) remove(*children[0].sizable);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
struct VerticalLayout : public Layout {
|
||||
void append(Sizable& sizable, Size size, unsigned spacing = 0);
|
||||
void append(Sizable& sizable);
|
||||
bool enabled();
|
||||
Size minimumSize();
|
||||
void remove(Sizable& sizable);
|
||||
void reset();
|
||||
|
@ -11,16 +10,12 @@ struct VerticalLayout : public Layout {
|
|||
void setMargin(unsigned margin);
|
||||
void setVisible(bool visible = true);
|
||||
void synchronizeLayout();
|
||||
bool visible();
|
||||
VerticalLayout();
|
||||
~VerticalLayout();
|
||||
|
||||
//private:
|
||||
struct State {
|
||||
double alignment;
|
||||
bool enabled;
|
||||
unsigned margin;
|
||||
bool visible;
|
||||
double alignment = 0.0;
|
||||
unsigned margin = 0;
|
||||
} state;
|
||||
|
||||
struct Children {
|
||||
|
|
|
@ -5,7 +5,7 @@ struct Application::State {
|
|||
|
||||
struct Timer::State {
|
||||
bool enabled = false;
|
||||
unsigned milliseconds = 0;
|
||||
unsigned interval = 0;
|
||||
};
|
||||
|
||||
struct BrowserWindow::State {
|
||||
|
@ -52,12 +52,12 @@ struct Action::State {
|
|||
|
||||
struct Menu::State {
|
||||
group<Action> action;
|
||||
nall::image image = {0, 32, 255u << 24, 255u << 16, 255u << 8, 255u << 0};
|
||||
nall::image image;
|
||||
string text;
|
||||
};
|
||||
|
||||
struct Item::State {
|
||||
nall::image image = {0, 32, 255u << 24, 255u << 16, 255u << 8, 255u << 0};
|
||||
nall::image image;
|
||||
string text;
|
||||
};
|
||||
|
||||
|
@ -73,35 +73,48 @@ struct RadioItem::State {
|
|||
};
|
||||
|
||||
struct Sizable::State {
|
||||
Layout* layout = nullptr;
|
||||
bool enabled = true;
|
||||
Sizable* parent = nullptr;
|
||||
bool visible = true;
|
||||
Window* window = nullptr;
|
||||
};
|
||||
|
||||
struct Layout::State {
|
||||
Widget* widget = nullptr;
|
||||
unsigned widgetSelection = 0;
|
||||
};
|
||||
|
||||
struct Widget::State {
|
||||
bool abstract = false;
|
||||
bool enabled = true;
|
||||
string font;
|
||||
Geometry geometry = {0, 0, 0, 0};
|
||||
bool visible = true;
|
||||
};
|
||||
|
||||
struct Button::State {
|
||||
nall::image image = {0, 32, 255u << 24, 255u << 16, 255u << 8, 255u << 0};
|
||||
nall::image image;
|
||||
Orientation orientation = Orientation::Horizontal;
|
||||
string text;
|
||||
};
|
||||
|
||||
struct Canvas::State {
|
||||
Color color;
|
||||
uint32_t* data = nullptr;
|
||||
bool droppable = false;
|
||||
unsigned width = 256;
|
||||
unsigned height = 256;
|
||||
vector<Color> gradient = {{}, {}, {}, {}};
|
||||
nall::image image;
|
||||
Canvas::Mode mode = Canvas::Mode::Color;
|
||||
unsigned width = 0;
|
||||
unsigned height = 0;
|
||||
};
|
||||
|
||||
struct CheckButton::State {
|
||||
bool checked = false;
|
||||
nall::image image;
|
||||
Orientation orientation = Orientation::Horizontal;
|
||||
string text;
|
||||
};
|
||||
|
||||
struct CheckLabel::State {
|
||||
bool checked = false;
|
||||
string text;
|
||||
};
|
||||
|
@ -114,6 +127,11 @@ struct ComboButton::State {
|
|||
struct Console::State {
|
||||
};
|
||||
|
||||
struct Frame::State {
|
||||
Layout* layout = nullptr;
|
||||
string text;
|
||||
};
|
||||
|
||||
struct HexEdit::State {
|
||||
unsigned columns = 16;
|
||||
unsigned length = 0;
|
||||
|
@ -158,9 +176,24 @@ struct ProgressBar::State {
|
|||
struct RadioButton::State {
|
||||
bool checked = true;
|
||||
nall::group<RadioButton> group;
|
||||
nall::image image;
|
||||
Orientation orientation = Orientation::Horizontal;
|
||||
string text;
|
||||
};
|
||||
|
||||
struct RadioLabel::State {
|
||||
bool checked = true;
|
||||
nall::group<RadioLabel> group;
|
||||
string text;
|
||||
};
|
||||
|
||||
struct TabFrame::State {
|
||||
vector<nall::image> image;
|
||||
vector<Layout*> layout;
|
||||
unsigned selection = 0;
|
||||
lstring text;
|
||||
};
|
||||
|
||||
struct TextEdit::State {
|
||||
unsigned cursorPosition = 0;
|
||||
bool editable = true;
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
namespace phoenix {
|
||||
|
||||
static void CheckItem_toggle(CheckItem* self) {
|
||||
if(self->p.locked == false && self->onToggle) self->onToggle();
|
||||
}
|
||||
|
||||
bool pCheckItem::checked() {
|
||||
return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
|
||||
static void CheckItem_toggle(GtkCheckMenuItem* gtkCheckMenuItem, CheckItem* self) {
|
||||
self->state.checked = gtk_check_menu_item_get_active(gtkCheckMenuItem);
|
||||
if(!self->p.locked && self->onToggle) self->onToggle();
|
||||
}
|
||||
|
||||
void pCheckItem::setChecked(bool checked) {
|
||||
|
@ -22,7 +19,7 @@ void pCheckItem::constructor() {
|
|||
widget = gtk_check_menu_item_new_with_mnemonic("");
|
||||
setChecked(checkItem.state.checked);
|
||||
setText(checkItem.state.text);
|
||||
g_signal_connect_swapped(G_OBJECT(widget), "toggled", G_CALLBACK(CheckItem_toggle), (gpointer)&checkItem);
|
||||
g_signal_connect(G_OBJECT(widget), "toggled", G_CALLBACK(CheckItem_toggle), (gpointer)&checkItem);
|
||||
}
|
||||
|
||||
void pCheckItem::destructor() {
|
||||
|
|
|
@ -1,22 +1,18 @@
|
|||
namespace phoenix {
|
||||
|
||||
static void RadioItem_activate(RadioItem* self) {
|
||||
for(auto& item : self->state.group) item.state.checked = (&item == self);
|
||||
if(self->p.locked == false && self->checked() && self->onActivate) self->onActivate();
|
||||
}
|
||||
|
||||
bool pRadioItem::checked() {
|
||||
return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
|
||||
static void RadioItem_activate(GtkCheckMenuItem* gtkCheckMenuItem, RadioItem* self) {
|
||||
self->p.onActivate();
|
||||
}
|
||||
|
||||
void pRadioItem::setChecked() {
|
||||
locked = true;
|
||||
parent().locked = true;
|
||||
for(auto& item : radioItem.state.group) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item.p.widget), false);
|
||||
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), true);
|
||||
locked = false;
|
||||
parent().locked = false;
|
||||
}
|
||||
|
||||
void pRadioItem::setGroup(const group<RadioItem>& group) {
|
||||
parent().locked = true;
|
||||
for(auto& item : group) {
|
||||
if(&item == &group.first()) continue;
|
||||
GSList* currentGroup = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(group.first().p.widget));
|
||||
|
@ -24,6 +20,7 @@ void pRadioItem::setGroup(const group<RadioItem>& group) {
|
|||
gtk_radio_menu_item_set_group(GTK_RADIO_MENU_ITEM(item.p.widget), currentGroup);
|
||||
}
|
||||
}
|
||||
parent().locked = false;
|
||||
}
|
||||
|
||||
void pRadioItem::setText(string text) {
|
||||
|
@ -37,7 +34,7 @@ void pRadioItem::constructor() {
|
|||
for(auto& item : radioItem.state.group) {
|
||||
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item.p.widget), item.state.checked);
|
||||
}
|
||||
g_signal_connect_swapped(G_OBJECT(widget), "toggled", G_CALLBACK(RadioItem_activate), (gpointer)&radioItem);
|
||||
g_signal_connect(G_OBJECT(widget), "toggled", G_CALLBACK(RadioItem_activate), (gpointer)&radioItem);
|
||||
}
|
||||
|
||||
void pRadioItem::destructor() {
|
||||
|
@ -49,4 +46,17 @@ void pRadioItem::orphan() {
|
|||
constructor();
|
||||
}
|
||||
|
||||
void pRadioItem::onActivate() {
|
||||
if(parent().locked) return;
|
||||
bool wasChecked = radioItem.state.checked;
|
||||
radioItem.setChecked();
|
||||
if(wasChecked) return;
|
||||
if(radioItem.onActivate) radioItem.onActivate();
|
||||
}
|
||||
|
||||
pRadioItem& pRadioItem::parent() {
|
||||
if(radioItem.state.group.size()) return radioItem.state.group.first().p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,8 +23,10 @@
|
|||
#include "widget/button.cpp"
|
||||
#include "widget/canvas.cpp"
|
||||
#include "widget/check-button.cpp"
|
||||
#include "widget/check-label.cpp"
|
||||
#include "widget/combo-button.cpp"
|
||||
#include "widget/console.cpp"
|
||||
#include "widget/frame.cpp"
|
||||
#include "widget/hex-edit.cpp"
|
||||
#include "widget/horizontal-scroller.cpp"
|
||||
#include "widget/horizontal-slider.cpp"
|
||||
|
@ -33,6 +35,8 @@
|
|||
#include "widget/list-view.cpp"
|
||||
#include "widget/progress-bar.cpp"
|
||||
#include "widget/radio-button.cpp"
|
||||
#include "widget/radio-label.cpp"
|
||||
#include "widget/tab-frame.cpp"
|
||||
#include "widget/text-edit.cpp"
|
||||
#include "widget/vertical-scroller.cpp"
|
||||
#include "widget/vertical-slider.cpp"
|
||||
|
|
|
@ -95,7 +95,7 @@ struct pTimer : public pObject {
|
|||
Timer& timer;
|
||||
|
||||
void setEnabled(bool enabled);
|
||||
void setInterval(unsigned milliseconds);
|
||||
void setInterval(unsigned interval);
|
||||
|
||||
pTimer(Timer& timer) : pObject(timer), timer(timer) {}
|
||||
void constructor();
|
||||
|
@ -117,7 +117,6 @@ struct pWindow : public pObject {
|
|||
void append(Layout& layout);
|
||||
void append(Menu& menu);
|
||||
void append(Widget& widget);
|
||||
Color backgroundColor();
|
||||
bool focused();
|
||||
Geometry frameMargin();
|
||||
Geometry geometry();
|
||||
|
@ -200,7 +199,6 @@ struct pItem : public pAction {
|
|||
struct pCheckItem : public pAction {
|
||||
CheckItem& checkItem;
|
||||
|
||||
bool checked();
|
||||
void setChecked(bool checked);
|
||||
void setText(string text);
|
||||
|
||||
|
@ -213,7 +211,6 @@ struct pCheckItem : public pAction {
|
|||
struct pRadioItem : public pAction {
|
||||
RadioItem& radioItem;
|
||||
|
||||
bool checked();
|
||||
void setChecked();
|
||||
void setGroup(const group<RadioItem>& group);
|
||||
void setText(string text);
|
||||
|
@ -222,11 +219,15 @@ struct pRadioItem : public pAction {
|
|||
void constructor();
|
||||
void destructor();
|
||||
void orphan();
|
||||
void onActivate();
|
||||
pRadioItem& parent();
|
||||
};
|
||||
|
||||
struct pSizable : public pObject {
|
||||
Sizable& sizable;
|
||||
|
||||
virtual Position displacement() { return {0, 0}; }
|
||||
|
||||
pSizable(Sizable &sizable) : pObject(sizable), sizable(sizable) {}
|
||||
};
|
||||
|
||||
|
@ -238,16 +239,18 @@ struct pLayout : public pSizable {
|
|||
|
||||
struct pWidget : public pSizable {
|
||||
Widget& widget;
|
||||
GtkWidget* gtkWidget;
|
||||
GtkWidget* gtkWidget = nullptr;
|
||||
GtkWidget* gtkParent = nullptr;
|
||||
|
||||
bool enabled();
|
||||
virtual GtkWidget* container(Widget& widget);
|
||||
virtual Position containerOffset();
|
||||
virtual bool focused();
|
||||
virtual Size minimumSize();
|
||||
void setEnabled(bool enabled);
|
||||
virtual void setEnabled(bool enabled);
|
||||
virtual void setFocused();
|
||||
virtual void setFont(string font);
|
||||
virtual void setGeometry(Geometry geometry);
|
||||
void setVisible(bool visible);
|
||||
virtual void setVisible(bool visible);
|
||||
|
||||
pWidget(Widget& widget) : pSizable(widget), widget(widget) {}
|
||||
void constructor();
|
||||
|
@ -270,27 +273,49 @@ struct pButton : public pWidget {
|
|||
|
||||
struct pCanvas : public pWidget {
|
||||
Canvas& canvas;
|
||||
cairo_surface_t* surface;
|
||||
GdkPixbuf* surface = nullptr;
|
||||
unsigned surfaceWidth = 0;
|
||||
unsigned surfaceHeight = 0;
|
||||
|
||||
Size minimumSize();
|
||||
void setDroppable(bool droppable);
|
||||
void setGeometry(Geometry geometry);
|
||||
void setMode(Canvas::Mode mode);
|
||||
void setSize(Size size);
|
||||
void update();
|
||||
|
||||
pCanvas(Canvas& canvas) : pWidget(canvas), canvas(canvas) {}
|
||||
void constructor();
|
||||
void destructor();
|
||||
void orphan();
|
||||
void onExpose(GdkEventExpose* event);
|
||||
void rasterize();
|
||||
void redraw();
|
||||
void release();
|
||||
};
|
||||
|
||||
struct pCheckButton : public pWidget {
|
||||
CheckButton& checkButton;
|
||||
|
||||
bool checked();
|
||||
Size minimumSize();
|
||||
void setChecked(bool checked);
|
||||
void setImage(const image& image, Orientation orientation);
|
||||
void setText(string text);
|
||||
|
||||
pCheckButton(CheckButton& checkButton) : pWidget(checkButton), checkButton(checkButton) {}
|
||||
void constructor();
|
||||
void destructor();
|
||||
void orphan();
|
||||
void onToggle();
|
||||
};
|
||||
|
||||
struct pCheckLabel : public pWidget {
|
||||
CheckLabel& checkLabel;
|
||||
|
||||
Size minimumSize();
|
||||
void setChecked(bool checked);
|
||||
void setText(string text);
|
||||
|
||||
pCheckButton(CheckButton& checkButton) : pWidget(checkButton), checkButton(checkButton) {}
|
||||
pCheckLabel(CheckLabel& checkLabel) : pWidget(checkLabel), checkLabel(checkLabel) {}
|
||||
void constructor();
|
||||
void destructor();
|
||||
void orphan();
|
||||
|
@ -301,12 +326,11 @@ struct pComboButton : public pWidget {
|
|||
unsigned itemCounter;
|
||||
|
||||
void append(string text);
|
||||
void modify(unsigned row, string text);
|
||||
void remove(unsigned row);
|
||||
Size minimumSize();
|
||||
void remove(unsigned selection);
|
||||
void reset();
|
||||
unsigned selection();
|
||||
void setSelection(unsigned row);
|
||||
void setSelection(unsigned selection);
|
||||
void setText(unsigned selection, string text);
|
||||
|
||||
pComboButton(ComboButton& comboButton) : pWidget(comboButton), comboButton(comboButton) {}
|
||||
void constructor();
|
||||
|
@ -331,6 +355,22 @@ struct pConsole : public pWidget {
|
|||
void seekCursorToEnd();
|
||||
};
|
||||
|
||||
struct pFrame : public pWidget {
|
||||
Frame& frame;
|
||||
|
||||
GtkWidget* container(Widget& widget);
|
||||
Position containerOffset();
|
||||
void setEnabled(bool enabled);
|
||||
void setGeometry(Geometry geometry);
|
||||
void setText(string text);
|
||||
void setVisible(bool visible);
|
||||
|
||||
pFrame(Frame& frame) : pWidget(frame), frame(frame) {}
|
||||
void constructor();
|
||||
void destructor();
|
||||
void orphan();
|
||||
};
|
||||
|
||||
struct pHexEdit : public pWidget {
|
||||
HexEdit& hexEdit;
|
||||
GtkWidget* container;
|
||||
|
@ -364,7 +404,6 @@ struct pHorizontalScroller : public pWidget {
|
|||
HorizontalScroller& horizontalScroller;
|
||||
|
||||
Size minimumSize();
|
||||
unsigned position();
|
||||
void setLength(unsigned length);
|
||||
void setPosition(unsigned position);
|
||||
|
||||
|
@ -378,7 +417,6 @@ struct pHorizontalSlider : public pWidget {
|
|||
HorizontalSlider& horizontalSlider;
|
||||
|
||||
Size minimumSize();
|
||||
unsigned position();
|
||||
void setLength(unsigned length);
|
||||
void setPosition(unsigned position);
|
||||
|
||||
|
@ -429,20 +467,17 @@ struct pListView : public pWidget {
|
|||
|
||||
void append(const lstring& text);
|
||||
void autoSizeColumns();
|
||||
bool checked(unsigned row);
|
||||
bool focused();
|
||||
void modify(unsigned row, const lstring& text);
|
||||
void remove(unsigned row);
|
||||
void remove(unsigned selection);
|
||||
void reset();
|
||||
bool selected();
|
||||
unsigned selection();
|
||||
void setCheckable(bool checkable);
|
||||
void setChecked(unsigned row, bool checked);
|
||||
void setChecked(unsigned selection, bool checked);
|
||||
void setHeaderText(const lstring& text);
|
||||
void setHeaderVisible(bool visible);
|
||||
void setImage(unsigned row, unsigned column, const nall::image& image);
|
||||
void setImage(unsigned selection, unsigned position, const image& image);
|
||||
void setSelected(bool selected);
|
||||
void setSelection(unsigned row);
|
||||
void setText(unsigned selection, unsigned position, string text);
|
||||
|
||||
pListView(ListView& listView) : pWidget(listView), listView(listView) {}
|
||||
void constructor();
|
||||
|
@ -467,18 +502,65 @@ struct pProgressBar : public pWidget {
|
|||
struct pRadioButton : public pWidget {
|
||||
RadioButton& radioButton;
|
||||
|
||||
bool checked();
|
||||
Size minimumSize();
|
||||
void setChecked();
|
||||
void setGroup(const group<RadioButton>& group);
|
||||
void setImage(const image& image, Orientation orientation);
|
||||
void setText(string text);
|
||||
|
||||
pRadioButton(RadioButton& radioButton) : pWidget(radioButton), radioButton(radioButton) {}
|
||||
void onActivate();
|
||||
pRadioButton& parent();
|
||||
void constructor();
|
||||
void destructor();
|
||||
void orphan();
|
||||
void onActivate();
|
||||
pRadioButton& parent();
|
||||
};
|
||||
|
||||
struct pRadioLabel : public pWidget {
|
||||
RadioLabel& radioLabel;
|
||||
|
||||
Size minimumSize();
|
||||
void setChecked();
|
||||
void setGroup(const group<RadioLabel>& group);
|
||||
void setText(string text);
|
||||
|
||||
pRadioLabel(RadioLabel& radioLabel) : pWidget(radioLabel), radioLabel(radioLabel) {}
|
||||
void onActivate();
|
||||
pRadioLabel& parent();
|
||||
void constructor();
|
||||
void destructor();
|
||||
void orphan();
|
||||
};
|
||||
|
||||
struct pTabFrame : public pWidget {
|
||||
TabFrame& tabFrame;
|
||||
struct Tab {
|
||||
GtkWidget* child;
|
||||
GtkWidget* container;
|
||||
GtkWidget* layout;
|
||||
GtkWidget* image;
|
||||
GtkWidget* title;
|
||||
};
|
||||
vector<Tab> tabs;
|
||||
|
||||
void append(string text, const image& image);
|
||||
GtkWidget* container(Widget& widget);
|
||||
Position containerOffset();
|
||||
Position displacement();
|
||||
void remove(unsigned selection);
|
||||
void setEnabled(bool enabled);
|
||||
void setGeometry(Geometry geometry);
|
||||
void setImage(unsigned selection, const image& image);
|
||||
void setSelection(unsigned selection);
|
||||
void setText(unsigned selection, string text);
|
||||
void setVisible(bool visible);
|
||||
|
||||
pTabFrame(TabFrame& tabFrame) : pWidget(tabFrame), tabFrame(tabFrame) {}
|
||||
void constructor();
|
||||
void destructor();
|
||||
void orphan();
|
||||
void setFont(string font);
|
||||
void synchronizeLayout();
|
||||
};
|
||||
|
||||
struct pTextEdit : public pWidget {
|
||||
|
@ -503,7 +585,6 @@ struct pVerticalScroller : public pWidget {
|
|||
VerticalScroller& verticalScroller;
|
||||
|
||||
Size minimumSize();
|
||||
unsigned position();
|
||||
void setLength(unsigned length);
|
||||
void setPosition(unsigned position);
|
||||
|
||||
|
@ -517,7 +598,6 @@ struct pVerticalSlider : public pWidget {
|
|||
VerticalSlider& verticalSlider;
|
||||
|
||||
Size minimumSize();
|
||||
unsigned position();
|
||||
void setLength(unsigned length);
|
||||
void setPosition(unsigned position);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ static guint Timer_trigger(pTimer* self) {
|
|||
}
|
||||
//callback may have disabled timer, so check state again
|
||||
if(self->timer.state.enabled) {
|
||||
g_timeout_add(self->timer.state.milliseconds, (GSourceFunc)Timer_trigger, (gpointer)self);
|
||||
g_timeout_add(self->timer.state.interval, (GSourceFunc)Timer_trigger, (gpointer)self);
|
||||
}
|
||||
//kill this timer instance (it is spawned above if needed again)
|
||||
return false;
|
||||
|
@ -15,11 +15,11 @@ static guint Timer_trigger(pTimer* self) {
|
|||
|
||||
void pTimer::setEnabled(bool enabled) {
|
||||
if(enabled) {
|
||||
g_timeout_add(timer.state.milliseconds, (GSourceFunc)Timer_trigger, (gpointer)this);
|
||||
g_timeout_add(timer.state.interval, (GSourceFunc)Timer_trigger, (gpointer)this);
|
||||
}
|
||||
}
|
||||
|
||||
void pTimer::setInterval(unsigned milliseconds) {
|
||||
void pTimer::setInterval(unsigned interval) {
|
||||
}
|
||||
|
||||
void pTimer::constructor() {
|
||||
|
|
|
@ -12,7 +12,7 @@ static GdkColor CreateColor(uint8_t r, uint8_t g, uint8_t b) {
|
|||
static GdkPixbuf* CreatePixbuf(const nall::image& image, bool scale = false) {
|
||||
nall::image gdkImage = image;
|
||||
gdkImage.transform(0, 32, 255u << 24, 255u << 0, 255u << 8, 255u << 16);
|
||||
if(scale) gdkImage.scale(15, 15, Interpolation::Linear);
|
||||
if(scale) gdkImage.scale(15, 15);
|
||||
|
||||
GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, gdkImage.width, gdkImage.height);
|
||||
memcpy(gdk_pixbuf_get_pixels(pixbuf), gdkImage.data, gdkImage.width * gdkImage.height * 4);
|
||||
|
@ -46,6 +46,37 @@ static lstring DropPaths(GtkSelectionData* data) {
|
|||
return paths;
|
||||
}
|
||||
|
||||
static Position GetDisplacement(Sizable* sizable) {
|
||||
Position position;
|
||||
while(sizable->state.parent) {
|
||||
Position displacement = sizable->state.parent->p.displacement();
|
||||
position.x += displacement.x;
|
||||
position.y += displacement.y;
|
||||
sizable = sizable->state.parent;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
static Layout* GetParentWidgetLayout(Sizable* sizable) {
|
||||
while(sizable) {
|
||||
if(sizable->state.parent && dynamic_cast<TabFrame*>(sizable->state.parent)) return (Layout*)sizable;
|
||||
sizable = sizable->state.parent;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static Widget* GetParentWidget(Sizable* sizable) {
|
||||
while(sizable) {
|
||||
if(sizable->state.parent && dynamic_cast<TabFrame*>(sizable->state.parent)) return (Widget*)sizable->state.parent;
|
||||
sizable = sizable->state.parent;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static bool HasParentWidget(Sizable* sizable) {
|
||||
return GetParentWidget(sizable) != nullptr;
|
||||
}
|
||||
|
||||
static Keyboard::Keycode Keysym(unsigned keysym) {
|
||||
switch(keysym) {
|
||||
case GDK_Escape: return Keyboard::Keycode::Escape;
|
||||
|
|
|
@ -1,83 +1,102 @@
|
|||
namespace phoenix {
|
||||
|
||||
static gboolean Canvas_expose(GtkWidget* widget, GdkEvent* event, pCanvas* self) {
|
||||
cairo_t* context = gdk_cairo_create(gtk_widget_get_window(widget));
|
||||
cairo_set_source_surface(context, self->surface, 0, 0);
|
||||
cairo_paint(context);
|
||||
cairo_destroy(context);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void Canvas_dropEvent(GtkWidget* widget, GdkDragContext* context, gint x, gint y,
|
||||
GtkSelectionData* data, guint type, guint timestamp, Canvas* canvas) {
|
||||
if(canvas->state.droppable == false) return;
|
||||
static void Canvas_drop(GtkWidget* widget, GdkDragContext* context, signed x, signed y,
|
||||
GtkSelectionData* data, unsigned type, unsigned timestamp, Canvas* canvas) {
|
||||
if(!canvas->state.droppable) return;
|
||||
lstring paths = DropPaths(data);
|
||||
if(paths.empty()) return;
|
||||
if(canvas->onDrop) canvas->onDrop(paths);
|
||||
}
|
||||
|
||||
static gboolean Canvas_mouseLeave(GtkWidget* widget, GdkEventButton* event, pCanvas* self) {
|
||||
if(self->canvas.onMouseLeave) self->canvas.onMouseLeave();
|
||||
static signed Canvas_expose(GtkWidget* widget, GdkEventExpose* event, Canvas* self) {
|
||||
self->p.onExpose(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
static gboolean Canvas_mouseMove(GtkWidget* widget, GdkEventButton* event, pCanvas* self) {
|
||||
if(self->canvas.onMouseMove) self->canvas.onMouseMove({(signed)event->x, (signed)event->y});
|
||||
static signed Canvas_mouseLeave(GtkWidget* widget, GdkEventButton* event, Canvas* self) {
|
||||
if(self->onMouseLeave) self->onMouseLeave();
|
||||
return true;
|
||||
}
|
||||
|
||||
static gboolean Canvas_mousePress(GtkWidget* widget, GdkEventButton* event, pCanvas* self) {
|
||||
if(self->canvas.onMousePress) switch(event->button) {
|
||||
case 1: self->canvas.onMousePress(Mouse::Button::Left); break;
|
||||
case 2: self->canvas.onMousePress(Mouse::Button::Middle); break;
|
||||
case 3: self->canvas.onMousePress(Mouse::Button::Right); break;
|
||||
static signed Canvas_mouseMove(GtkWidget* widget, GdkEventButton* event, Canvas* self) {
|
||||
if(self->onMouseMove) self->onMouseMove({(signed)event->x, (signed)event->y});
|
||||
return true;
|
||||
}
|
||||
|
||||
static signed Canvas_mousePress(GtkWidget* widget, GdkEventButton* event, Canvas* self) {
|
||||
if(self->onMousePress) switch(event->button) {
|
||||
case 1: self->onMousePress(Mouse::Button::Left); break;
|
||||
case 2: self->onMousePress(Mouse::Button::Middle); break;
|
||||
case 3: self->onMousePress(Mouse::Button::Right); break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static gboolean Canvas_mouseRelease(GtkWidget* widget, GdkEventButton* event, pCanvas* self) {
|
||||
if(self->canvas.onMouseRelease) switch(event->button) {
|
||||
case 1: self->canvas.onMouseRelease(Mouse::Button::Left); break;
|
||||
case 2: self->canvas.onMouseRelease(Mouse::Button::Middle); break;
|
||||
case 3: self->canvas.onMouseRelease(Mouse::Button::Right); break;
|
||||
static signed Canvas_mouseRelease(GtkWidget* widget, GdkEventButton* event, Canvas* self) {
|
||||
if(self->onMouseRelease) switch(event->button) {
|
||||
case 1: self->onMouseRelease(Mouse::Button::Left); break;
|
||||
case 2: self->onMouseRelease(Mouse::Button::Middle); break;
|
||||
case 3: self->onMouseRelease(Mouse::Button::Right); break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Size pCanvas::minimumSize() {
|
||||
return {canvas.state.width, canvas.state.height};
|
||||
}
|
||||
|
||||
void pCanvas::setDroppable(bool droppable) {
|
||||
gtk_drag_dest_set(gtkWidget, GTK_DEST_DEFAULT_ALL, nullptr, 0, GDK_ACTION_COPY);
|
||||
if(droppable) gtk_drag_dest_add_uri_targets(gtkWidget);
|
||||
}
|
||||
|
||||
void pCanvas::setSize(Size size) {
|
||||
cairo_surface_destroy(surface);
|
||||
surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, canvas.state.width, canvas.state.height);
|
||||
void pCanvas::setGeometry(Geometry geometry) {
|
||||
if(canvas.state.width == 0 || canvas.state.height == 0) rasterize();
|
||||
unsigned width = canvas.state.width;
|
||||
unsigned height = canvas.state.height;
|
||||
if(width == 0) width = widget.state.geometry.width;
|
||||
if(height == 0) height = widget.state.geometry.height;
|
||||
|
||||
if(width < geometry.width) {
|
||||
geometry.x += (geometry.width - width) / 2;
|
||||
geometry.width = width;
|
||||
}
|
||||
|
||||
if(height < geometry.height) {
|
||||
geometry.y += (geometry.height - height) / 2;
|
||||
geometry.height = height;
|
||||
}
|
||||
|
||||
pWidget::setGeometry(geometry);
|
||||
}
|
||||
|
||||
void pCanvas::update() {
|
||||
memcpy(cairo_image_surface_get_data(surface), canvas.state.data, canvas.state.width * canvas.state.height * sizeof(uint32_t));
|
||||
if(gtk_widget_get_realized(gtkWidget) == false) return;
|
||||
gdk_window_invalidate_rect(gtk_widget_get_window(gtkWidget), nullptr, true);
|
||||
void pCanvas::setMode(Canvas::Mode mode) {
|
||||
rasterize(), redraw();
|
||||
}
|
||||
|
||||
void pCanvas::setSize(Size size) {
|
||||
rasterize(), redraw();
|
||||
}
|
||||
|
||||
void pCanvas::constructor() {
|
||||
surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, canvas.state.width, canvas.state.height);
|
||||
memcpy(cairo_image_surface_get_data(surface), canvas.state.data, canvas.state.width * canvas.state.height * sizeof(uint32_t));
|
||||
gtkWidget = gtk_drawing_area_new();
|
||||
gtk_widget_set_double_buffered(gtkWidget, false);
|
||||
//gtk_widget_set_double_buffered(gtkWidget, false);
|
||||
gtk_widget_add_events(gtkWidget,
|
||||
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_EXPOSURE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "drag-data-received", G_CALLBACK(Canvas_dropEvent), (gpointer)&canvas);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "button_press_event", G_CALLBACK(Canvas_mousePress), (gpointer)this);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "button_release_event", G_CALLBACK(Canvas_mouseRelease), (gpointer)this);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "expose_event", G_CALLBACK(Canvas_expose), (gpointer)this);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "leave_notify_event", G_CALLBACK(Canvas_mouseLeave), (gpointer)this);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "motion_notify_event", G_CALLBACK(Canvas_mouseMove), (gpointer)this);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "button-press-event", G_CALLBACK(Canvas_mousePress), (gpointer)&canvas);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "button-release-event", G_CALLBACK(Canvas_mouseRelease), (gpointer)&canvas);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "drag-data-received", G_CALLBACK(Canvas_drop), (gpointer)&canvas);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "expose-event", G_CALLBACK(Canvas_expose), (gpointer)&canvas);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "leave-notify-event", G_CALLBACK(Canvas_mouseLeave), (gpointer)&canvas);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "motion-notify-event", G_CALLBACK(Canvas_mouseMove), (gpointer)&canvas);
|
||||
|
||||
setDroppable(canvas.state.droppable);
|
||||
rasterize(), redraw();
|
||||
}
|
||||
|
||||
void pCanvas::destructor() {
|
||||
release();
|
||||
gtk_widget_destroy(gtkWidget);
|
||||
cairo_surface_destroy(surface);
|
||||
}
|
||||
|
||||
void pCanvas::orphan() {
|
||||
|
@ -85,4 +104,74 @@ void pCanvas::orphan() {
|
|||
constructor();
|
||||
}
|
||||
|
||||
void pCanvas::onExpose(GdkEventExpose* expose) {
|
||||
if(surface) gdk_draw_pixbuf(gtk_widget_get_window(gtkWidget), nullptr, surface, 0, 0, 0, 0, -1, -1, GDK_RGB_DITHER_NONE, 0, 0);
|
||||
}
|
||||
|
||||
void pCanvas::rasterize() {
|
||||
unsigned width = canvas.state.width;
|
||||
unsigned height = canvas.state.height;
|
||||
if(width == 0) width = widget.state.geometry.width;
|
||||
if(height == 0) height = widget.state.geometry.height;
|
||||
|
||||
if(width != surfaceWidth || height != surfaceHeight) release();
|
||||
surfaceWidth = width;
|
||||
surfaceHeight = height;
|
||||
|
||||
if(width == 0 || height == 0) return;
|
||||
|
||||
if(!surface) surface = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, width, height);
|
||||
uint32_t* buffer = (uint32_t*)gdk_pixbuf_get_pixels(surface);
|
||||
|
||||
if(canvas.state.mode == Canvas::Mode::Color) {
|
||||
uint32_t color = canvas.state.color.argb();
|
||||
for(unsigned n = 0; n < width * height; n++) buffer[n] = color;
|
||||
}
|
||||
|
||||
if(canvas.state.mode == Canvas::Mode::Gradient) {
|
||||
nall::image image;
|
||||
image.allocate(width, height);
|
||||
image.gradient(
|
||||
canvas.state.gradient[0].argb(), canvas.state.gradient[1].argb(), canvas.state.gradient[2].argb(), canvas.state.gradient[3].argb()
|
||||
);
|
||||
memcpy(buffer, image.data, image.size);
|
||||
}
|
||||
|
||||
if(canvas.state.mode == Canvas::Mode::Image) {
|
||||
nall::image image = canvas.state.image;
|
||||
image.scale(width, height);
|
||||
image.transform(0, 32, 255u << 24, 255u << 16, 255u << 8, 255u << 0);
|
||||
memcpy(buffer, image.data, image.size);
|
||||
}
|
||||
|
||||
if(canvas.state.mode == Canvas::Mode::Data) {
|
||||
if(width == canvas.state.width && height == canvas.state.height) {
|
||||
memcpy(buffer, canvas.state.data, width * height * sizeof(uint32_t));
|
||||
} else {
|
||||
memset(buffer, 0x00, width * height * sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
|
||||
//ARGB -> ABGR conversion
|
||||
for(unsigned n = 0; n < width * height; n++) {
|
||||
uint32_t color = *buffer;
|
||||
color = (color & 0xff00ff00) | ((color & 0xff0000) >> 16) | ((color & 0x0000ff) << 16);
|
||||
*buffer++ = color;
|
||||
}
|
||||
}
|
||||
|
||||
void pCanvas::redraw() {
|
||||
if(gtk_widget_get_realized(gtkWidget)) {
|
||||
gdk_window_invalidate_rect(gtk_widget_get_window(gtkWidget), nullptr, true);
|
||||
}
|
||||
}
|
||||
|
||||
void pCanvas::release() {
|
||||
if(surface == nullptr) return;
|
||||
g_object_unref(surface);
|
||||
surface = nullptr;
|
||||
surfaceWidth = 0;
|
||||
surfaceHeight = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,17 +1,23 @@
|
|||
namespace phoenix {
|
||||
|
||||
static void CheckButton_toggle(CheckButton* self) {
|
||||
self->state.checked = self->checked();
|
||||
if(self->p.locked == false && self->onToggle) self->onToggle();
|
||||
}
|
||||
|
||||
bool pCheckButton::checked() {
|
||||
return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtkWidget));
|
||||
static void CheckButton_toggle(GtkToggleButton* toggleButton, CheckButton* self) {
|
||||
self->p.onToggle();
|
||||
}
|
||||
|
||||
Size pCheckButton::minimumSize() {
|
||||
Size size = pFont::size(widget.state.font, checkButton.state.text);
|
||||
return {size.width + 28, size.height + 4};
|
||||
|
||||
if(checkButton.state.orientation == Orientation::Horizontal) {
|
||||
size.width += checkButton.state.image.width;
|
||||
size.height = max(checkButton.state.image.height, size.height);
|
||||
}
|
||||
|
||||
if(checkButton.state.orientation == Orientation::Vertical) {
|
||||
size.width = max(checkButton.state.image.width, size.width);
|
||||
size.height += checkButton.state.image.height;
|
||||
}
|
||||
|
||||
return {size.width + 24, size.height + 12};
|
||||
}
|
||||
|
||||
void pCheckButton::setChecked(bool checked) {
|
||||
|
@ -20,13 +26,27 @@ void pCheckButton::setChecked(bool checked) {
|
|||
locked = false;
|
||||
}
|
||||
|
||||
void pCheckButton::setImage(const image& image, Orientation orientation) {
|
||||
if(image.empty() == false) {
|
||||
GtkImage* gtkImage = CreateImage(image);
|
||||
gtk_button_set_image(GTK_BUTTON(gtkWidget), (GtkWidget*)gtkImage);
|
||||
} else {
|
||||
gtk_button_set_image(GTK_BUTTON(gtkWidget), nullptr);
|
||||
}
|
||||
switch(orientation) {
|
||||
case Orientation::Horizontal: gtk_button_set_image_position(GTK_BUTTON(gtkWidget), GTK_POS_LEFT); break;
|
||||
case Orientation::Vertical: gtk_button_set_image_position(GTK_BUTTON(gtkWidget), GTK_POS_TOP); break;
|
||||
}
|
||||
}
|
||||
|
||||
void pCheckButton::setText(string text) {
|
||||
gtk_button_set_label(GTK_BUTTON(gtkWidget), text);
|
||||
setFont(widget.state.font);
|
||||
}
|
||||
|
||||
void pCheckButton::constructor() {
|
||||
gtkWidget = gtk_check_button_new_with_label("");
|
||||
g_signal_connect_swapped(G_OBJECT(gtkWidget), "toggled", G_CALLBACK(CheckButton_toggle), (gpointer)&checkButton);
|
||||
gtkWidget = gtk_toggle_button_new();
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "toggled", G_CALLBACK(CheckButton_toggle), (gpointer)&checkButton);
|
||||
|
||||
setChecked(checkButton.state.checked);
|
||||
setText(checkButton.state.text);
|
||||
|
@ -41,4 +61,10 @@ void pCheckButton::orphan() {
|
|||
constructor();
|
||||
}
|
||||
|
||||
void pCheckButton::onToggle() {
|
||||
if(locked) return;
|
||||
checkButton.state.checked = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtkWidget));
|
||||
if(checkButton.onToggle) checkButton.onToggle();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
namespace phoenix {
|
||||
|
||||
static void CheckLabel_toggle(GtkToggleButton* toggleButton, CheckLabel* self) {
|
||||
self->state.checked = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(self->p.gtkWidget));
|
||||
if(!self->p.locked && self->onToggle) self->onToggle();
|
||||
}
|
||||
|
||||
Size pCheckLabel::minimumSize() {
|
||||
Size size = pFont::size(widget.state.font, checkLabel.state.text);
|
||||
return {size.width + 28, size.height + 4};
|
||||
}
|
||||
|
||||
void pCheckLabel::setChecked(bool checked) {
|
||||
locked = true;
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtkWidget), checked);
|
||||
locked = false;
|
||||
}
|
||||
|
||||
void pCheckLabel::setText(string text) {
|
||||
gtk_button_set_label(GTK_BUTTON(gtkWidget), text);
|
||||
}
|
||||
|
||||
void pCheckLabel::constructor() {
|
||||
gtkWidget = gtk_check_button_new_with_label("");
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "toggled", G_CALLBACK(CheckLabel_toggle), (gpointer)&checkLabel);
|
||||
|
||||
setChecked(checkLabel.state.checked);
|
||||
setText(checkLabel.state.text);
|
||||
}
|
||||
|
||||
void pCheckLabel::destructor() {
|
||||
gtk_widget_destroy(gtkWidget);
|
||||
}
|
||||
|
||||
void pCheckLabel::orphan() {
|
||||
destructor();
|
||||
constructor();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
namespace phoenix {
|
||||
|
||||
static void ComboButton_change(ComboButton* self) {
|
||||
if(self->p.locked == false) {
|
||||
self->state.selection = self->selection();
|
||||
if(!self->p.locked) {
|
||||
self->state.selection = gtk_combo_box_get_active(GTK_COMBO_BOX(self->p.gtkWidget));
|
||||
if(self->onChange) self->onChange();
|
||||
}
|
||||
}
|
||||
|
||||
void pComboButton::append(string text) {
|
||||
gtk_combo_box_append_text(GTK_COMBO_BOX(gtkWidget), text);
|
||||
if(itemCounter++ == 0) setSelection(0);
|
||||
if(itemCounter++ == 0) comboButton.setSelection(0);
|
||||
}
|
||||
|
||||
Size pComboButton::minimumSize() {
|
||||
|
@ -20,21 +20,14 @@ Size pComboButton::minimumSize() {
|
|||
return {maximumWidth + 44, size.height + 12};
|
||||
}
|
||||
|
||||
void pComboButton::modify(unsigned row, string text) {
|
||||
void pComboButton::remove(unsigned selection) {
|
||||
locked = true;
|
||||
unsigned position = selection();
|
||||
gtk_combo_box_remove_text(GTK_COMBO_BOX(gtkWidget), row);
|
||||
gtk_combo_box_insert_text(GTK_COMBO_BOX(gtkWidget), row, text);
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(gtkWidget), position);
|
||||
gtk_combo_box_remove_text(GTK_COMBO_BOX(gtkWidget), selection);
|
||||
itemCounter--;
|
||||
locked = false;
|
||||
}
|
||||
|
||||
void pComboButton::remove(unsigned row) {
|
||||
locked = true;
|
||||
unsigned position = selection();
|
||||
gtk_combo_box_remove_text(GTK_COMBO_BOX(gtkWidget), row);
|
||||
if(position == row) gtk_combo_box_set_active(GTK_COMBO_BOX(gtkWidget), 0);
|
||||
locked = false;
|
||||
//when removing the actively selected item, reset the selection to the first entry
|
||||
if(selection == comboButton.state.selection) comboButton.setSelection(0);
|
||||
}
|
||||
|
||||
void pComboButton::reset() {
|
||||
|
@ -44,13 +37,17 @@ void pComboButton::reset() {
|
|||
locked = false;
|
||||
}
|
||||
|
||||
unsigned pComboButton::selection() {
|
||||
return gtk_combo_box_get_active(GTK_COMBO_BOX(gtkWidget));
|
||||
void pComboButton::setSelection(unsigned selection) {
|
||||
locked = true;
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(gtkWidget), selection);
|
||||
locked = false;
|
||||
}
|
||||
|
||||
void pComboButton::setSelection(unsigned row) {
|
||||
void pComboButton::setText(unsigned selection, string text) {
|
||||
locked = true;
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(gtkWidget), row);
|
||||
gtk_combo_box_remove_text(GTK_COMBO_BOX(gtkWidget), selection);
|
||||
gtk_combo_box_insert_text(GTK_COMBO_BOX(gtkWidget), selection, text);
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(gtkWidget), comboButton.state.selection);
|
||||
locked = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
namespace phoenix {
|
||||
|
||||
GtkWidget* pFrame::container(Widget& widget) {
|
||||
return gtk_widget_get_parent(gtkWidget);
|
||||
}
|
||||
|
||||
Position pFrame::containerOffset() {
|
||||
return {0, 0};
|
||||
}
|
||||
|
||||
void pFrame::setEnabled(bool enabled) {
|
||||
if(frame.state.layout) frame.state.layout->setEnabled(frame.state.layout->enabled());
|
||||
pWidget::setEnabled(enabled);
|
||||
}
|
||||
|
||||
void pFrame::setGeometry(Geometry geometry) {
|
||||
pWidget::setGeometry(geometry);
|
||||
if(frame.state.layout == nullptr) return;
|
||||
Size size = pFont::size(widget.state.font, frame.state.text);
|
||||
if(frame.state.text.empty()) size.height = 8;
|
||||
geometry.x += 2, geometry.width -= 5;
|
||||
geometry.y += size.height - 1, geometry.height -= size.height + 2;
|
||||
frame.state.layout->setGeometry(geometry);
|
||||
}
|
||||
|
||||
void pFrame::setText(string text) {
|
||||
gtk_frame_set_label(GTK_FRAME(gtkWidget), text);
|
||||
}
|
||||
|
||||
void pFrame::setVisible(bool visible) {
|
||||
if(frame.state.layout) frame.state.layout->setVisible(frame.state.layout->visible());
|
||||
pWidget::setVisible(visible);
|
||||
}
|
||||
|
||||
void pFrame::constructor() {
|
||||
gtkWidget = gtk_frame_new("");
|
||||
}
|
||||
|
||||
void pFrame::destructor() {
|
||||
gtk_widget_destroy(gtkWidget);
|
||||
}
|
||||
|
||||
void pFrame::orphan() {
|
||||
destructor();
|
||||
constructor();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,19 +1,16 @@
|
|||
namespace phoenix {
|
||||
|
||||
static void HorizontalScroller_change(HorizontalScroller* self) {
|
||||
if(self->state.position == self->position()) return;
|
||||
self->state.position = self->position();
|
||||
if(self->p.locked == false && self->onChange) self->onChange();
|
||||
static void HorizontalScroller_change(GtkRange* gtkRange, HorizontalScroller* self) {
|
||||
unsigned position = (unsigned)gtk_range_get_value(gtkRange);
|
||||
if(self->state.position == position) return;
|
||||
self->state.position = position;
|
||||
if(!self->p.locked && self->onChange) self->onChange();
|
||||
}
|
||||
|
||||
Size pHorizontalScroller::minimumSize() {
|
||||
return {0, 20};
|
||||
}
|
||||
|
||||
unsigned pHorizontalScroller::position() {
|
||||
return (unsigned)gtk_range_get_value(GTK_RANGE(gtkWidget));
|
||||
}
|
||||
|
||||
void pHorizontalScroller::setLength(unsigned length) {
|
||||
locked = true;
|
||||
length += length == 0;
|
||||
|
@ -28,7 +25,7 @@ void pHorizontalScroller::setPosition(unsigned position) {
|
|||
|
||||
void pHorizontalScroller::constructor() {
|
||||
gtkWidget = gtk_hscrollbar_new(0);
|
||||
g_signal_connect_swapped(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(HorizontalScroller_change), (gpointer)&horizontalScroller);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(HorizontalScroller_change), (gpointer)&horizontalScroller);
|
||||
|
||||
setLength(horizontalScroller.state.length);
|
||||
setPosition(horizontalScroller.state.position);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
namespace phoenix {
|
||||
|
||||
static void HorizontalSlider_change(HorizontalSlider* self) {
|
||||
if(self->state.position == self->position()) return;
|
||||
self->state.position = self->position();
|
||||
static void HorizontalSlider_change(GtkRange* gtkRange, HorizontalSlider* self) {
|
||||
unsigned position = (unsigned)gtk_range_get_value(gtkRange);
|
||||
if(self->state.position == position) return;
|
||||
self->state.position = position;
|
||||
if(self->onChange) self->onChange();
|
||||
}
|
||||
|
||||
|
@ -10,10 +11,6 @@ Size pHorizontalSlider::minimumSize() {
|
|||
return {0, 20};
|
||||
}
|
||||
|
||||
unsigned pHorizontalSlider::position() {
|
||||
return (unsigned)gtk_range_get_value(GTK_RANGE(gtkWidget));
|
||||
}
|
||||
|
||||
void pHorizontalSlider::setLength(unsigned length) {
|
||||
length += length == 0;
|
||||
gtk_range_set_range(GTK_RANGE(gtkWidget), 0, max(1u, length - 1));
|
||||
|
@ -27,7 +24,7 @@ void pHorizontalSlider::setPosition(unsigned position) {
|
|||
void pHorizontalSlider::constructor() {
|
||||
gtkWidget = gtk_hscale_new_with_range(0, 100, 1);
|
||||
gtk_scale_set_draw_value(GTK_SCALE(gtkWidget), false);
|
||||
g_signal_connect_swapped(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(HorizontalSlider_change), (gpointer)&horizontalSlider);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(HorizontalSlider_change), (gpointer)&horizontalSlider);
|
||||
|
||||
setLength(horizontalSlider.state.length);
|
||||
setPosition(horizontalSlider.state.position);
|
||||
|
|
|
@ -1,57 +1,53 @@
|
|||
namespace phoenix {
|
||||
|
||||
static void ListView_activate(ListView* self) {
|
||||
static void ListView_activate(GtkTreeView* treeView, GtkTreePath* path, GtkTreeViewColumn* column, ListView* self) {
|
||||
char* pathname = gtk_tree_path_to_string(path);
|
||||
unsigned selection = decimal(pathname);
|
||||
g_free(pathname);
|
||||
self->state.selection = selection;
|
||||
if(self->onActivate) self->onActivate();
|
||||
}
|
||||
|
||||
static void ListView_change(ListView* self) {
|
||||
if(self->state.selected == false || self->state.selection != self->selection()) {
|
||||
static void ListView_change(GtkTreeView* treeView, ListView* self) {
|
||||
GtkTreeIter iter;
|
||||
if(!gtk_tree_selection_get_selected(gtk_tree_view_get_selection(treeView), 0, &iter)) return; //should not be possible
|
||||
char* path = gtk_tree_model_get_string_from_iter(gtk_tree_view_get_model(treeView), &iter);
|
||||
unsigned selection = decimal(path);
|
||||
g_free(path);
|
||||
|
||||
if(!self->state.selected || self->state.selection != selection) {
|
||||
self->state.selected = true;
|
||||
self->state.selection = self->selection();
|
||||
self->state.selection = selection;
|
||||
if(self->onChange) self->onChange();
|
||||
}
|
||||
}
|
||||
|
||||
static void ListView_toggle(GtkCellRendererToggle* cell, gchar* path, ListView* self) {
|
||||
unsigned row = decimal(path);
|
||||
self->setChecked(row, !self->checked(row));
|
||||
if(self->onToggle) self->onToggle(row);
|
||||
unsigned selection = decimal(path);
|
||||
self->setChecked(selection, !self->checked(selection));
|
||||
if(self->onToggle) self->onToggle(selection);
|
||||
}
|
||||
|
||||
void pListView::append(const lstring& text) {
|
||||
GtkTreeIter iter;
|
||||
gtk_list_store_append(store, &iter);
|
||||
for(unsigned n = 0; n < text.size(); n++) gtk_list_store_set(store, &iter, 1 + n * 2 + 1, (const char*)text[n], -1);
|
||||
for(unsigned n = 0; n < text.size(); n++) {
|
||||
gtk_list_store_set(store, &iter, 1 + n * 2 + 1, (const char*)text[n], -1);
|
||||
}
|
||||
}
|
||||
|
||||
void pListView::autoSizeColumns() {
|
||||
gtk_tree_view_columns_autosize(GTK_TREE_VIEW(subWidget));
|
||||
}
|
||||
|
||||
bool pListView::checked(unsigned row) {
|
||||
GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(subWidget));
|
||||
GtkTreeIter iter;
|
||||
bool state;
|
||||
if(gtk_tree_model_get_iter_from_string(model, &iter, string(row)) == false) return false;
|
||||
gtk_tree_model_get(model, &iter, 0, &state, -1);
|
||||
return state;
|
||||
}
|
||||
|
||||
bool pListView::focused() {
|
||||
return GTK_WIDGET_HAS_FOCUS(subWidget);
|
||||
}
|
||||
|
||||
void pListView::modify(unsigned row, const lstring& text) {
|
||||
void pListView::remove(unsigned selection) {
|
||||
GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(subWidget));
|
||||
GtkTreeIter iter;
|
||||
gtk_tree_model_get_iter_from_string(model, &iter, string(row));
|
||||
for(unsigned n = 0; n < text.size(); n++) gtk_list_store_set(store, &iter, 1 + n * 2 + 1, (const char*)text[n], -1);
|
||||
}
|
||||
|
||||
void pListView::remove(unsigned row) {
|
||||
GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(subWidget));
|
||||
GtkTreeIter iter;
|
||||
gtk_tree_model_get_iter_from_string(model, &iter, string(row));
|
||||
gtk_tree_model_get_iter_from_string(model, &iter, string(selection));
|
||||
gtk_list_store_remove(store, &iter);
|
||||
}
|
||||
|
||||
|
@ -65,30 +61,14 @@ void pListView::reset() {
|
|||
gtk_scrolled_window_set_vadjustment(GTK_SCROLLED_WINDOW(gtkWidget), 0);
|
||||
}
|
||||
|
||||
bool pListView::selected() {
|
||||
GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(subWidget));
|
||||
return gtk_tree_selection_get_selected(selection, 0, 0);
|
||||
}
|
||||
|
||||
unsigned pListView::selection() {
|
||||
GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(subWidget));
|
||||
GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(subWidget));
|
||||
GtkTreeIter iter;
|
||||
if(gtk_tree_selection_get_selected(selection, 0, &iter) == false) return listView.state.selection;
|
||||
char* path = gtk_tree_model_get_string_from_iter(model, &iter);
|
||||
unsigned row = decimal(path);
|
||||
g_free(path);
|
||||
return row;
|
||||
}
|
||||
|
||||
void pListView::setCheckable(bool checkable) {
|
||||
gtk_cell_renderer_set_visible(column(0).checkbutton, checkable);
|
||||
}
|
||||
|
||||
void pListView::setChecked(unsigned row, bool checked) {
|
||||
void pListView::setChecked(unsigned selection, bool checked) {
|
||||
GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(subWidget));
|
||||
GtkTreeIter iter;
|
||||
gtk_tree_model_get_iter_from_string(model, &iter, string(row));
|
||||
gtk_tree_model_get_iter_from_string(model, &iter, string(selection));
|
||||
gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, checked, -1);
|
||||
}
|
||||
|
||||
|
@ -101,15 +81,15 @@ void pListView::setHeaderVisible(bool visible) {
|
|||
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(subWidget), visible);
|
||||
}
|
||||
|
||||
void pListView::setImage(unsigned row, unsigned column, const nall::image& image) {
|
||||
void pListView::setImage(unsigned selection, unsigned position, const image& image) {
|
||||
GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(subWidget));
|
||||
GtkTreeIter iter;
|
||||
gtk_tree_model_get_iter_from_string(model, &iter, string(row));
|
||||
gtk_tree_model_get_iter_from_string(model, &iter, string(selection));
|
||||
if(image.empty() == false) {
|
||||
GdkPixbuf* pixbuf = CreatePixbuf(image, true);
|
||||
gtk_list_store_set(store, &iter, 1 + column * 2, pixbuf, -1);
|
||||
gtk_list_store_set(store, &iter, 1 + position * 2, pixbuf, -1);
|
||||
} else {
|
||||
gtk_list_store_set(store, &iter, 1 + column * 2, nullptr, -1);
|
||||
gtk_list_store_set(store, &iter, 1 + position * 2, nullptr, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,13 +102,13 @@ void pListView::setSelected(bool selected) {
|
|||
}
|
||||
}
|
||||
|
||||
void pListView::setSelection(unsigned row) {
|
||||
GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(subWidget));
|
||||
void pListView::setSelection(unsigned selection) {
|
||||
GtkTreeSelection* treeSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW(subWidget));
|
||||
GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(subWidget));
|
||||
gtk_tree_selection_unselect_all(selection);
|
||||
gtk_tree_selection_unselect_all(treeSelection);
|
||||
GtkTreeIter iter;
|
||||
if(gtk_tree_model_get_iter_from_string(model, &iter, string(row)) == false) return;
|
||||
gtk_tree_selection_select_iter(selection, &iter);
|
||||
if(gtk_tree_model_get_iter_from_string(model, &iter, string(selection)) == false) return;
|
||||
gtk_tree_selection_select_iter(treeSelection, &iter);
|
||||
|
||||
//scroll window to selected item
|
||||
char* path = gtk_tree_model_get_string_from_iter(model, &iter);
|
||||
|
@ -138,6 +118,13 @@ void pListView::setSelection(unsigned row) {
|
|||
g_free(path);
|
||||
}
|
||||
|
||||
void pListView::setText(unsigned selection, unsigned position, string text) {
|
||||
GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(subWidget));
|
||||
GtkTreeIter iter;
|
||||
gtk_tree_model_get_iter_from_string(model, &iter, string(selection));
|
||||
gtk_list_store_set(store, &iter, 1 + position * 2 + 1, (const char*)text, -1);
|
||||
}
|
||||
|
||||
void pListView::constructor() {
|
||||
gtkWidget = gtk_scrolled_window_new(0, 0);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gtkWidget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||
|
@ -190,8 +177,8 @@ void pListView::constructor() {
|
|||
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(subWidget), headerText.size() >= 2); //two or more columns + checkbutton column
|
||||
gtk_tree_view_set_search_column(GTK_TREE_VIEW(subWidget), 2);
|
||||
|
||||
g_signal_connect_swapped(G_OBJECT(subWidget), "cursor-changed", G_CALLBACK(ListView_change), (gpointer)&listView);
|
||||
g_signal_connect_swapped(G_OBJECT(subWidget), "row-activated", G_CALLBACK(ListView_activate), (gpointer)&listView);
|
||||
g_signal_connect(G_OBJECT(subWidget), "cursor-changed", G_CALLBACK(ListView_change), (gpointer)&listView);
|
||||
g_signal_connect(G_OBJECT(subWidget), "row-activated", G_CALLBACK(ListView_activate), (gpointer)&listView);
|
||||
|
||||
gtk_widget_show(subWidget);
|
||||
|
||||
|
|
|
@ -1,63 +1,63 @@
|
|||
namespace phoenix {
|
||||
|
||||
static void RadioButton_activate(RadioButton* self) {
|
||||
static void RadioButton_activate(GtkToggleButton* toggleButton, RadioButton* self) {
|
||||
self->p.onActivate();
|
||||
}
|
||||
|
||||
bool pRadioButton::checked() {
|
||||
return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtkWidget));
|
||||
}
|
||||
|
||||
Size pRadioButton::minimumSize() {
|
||||
Size size = pFont::size(widget.state.font, radioButton.state.text);
|
||||
return {size.width + 28, size.height + 4};
|
||||
|
||||
if(radioButton.state.orientation == Orientation::Horizontal) {
|
||||
size.width += radioButton.state.image.width;
|
||||
size.height = max(radioButton.state.image.height, size.height);
|
||||
}
|
||||
|
||||
if(radioButton.state.orientation == Orientation::Vertical) {
|
||||
size.width = max(radioButton.state.image.width, size.width);
|
||||
size.height += radioButton.state.image.height;
|
||||
}
|
||||
|
||||
return {size.width + 24, size.height + 12};
|
||||
}
|
||||
|
||||
void pRadioButton::setChecked() {
|
||||
parent().locked = true;
|
||||
for(auto& item : radioButton.state.group) item.state.checked = false;
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtkWidget), radioButton.state.checked = true);
|
||||
for(auto& item : radioButton.state.group) {
|
||||
bool checked = &item == &radioButton;
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(item.p.gtkWidget), item.state.checked = checked);
|
||||
}
|
||||
parent().locked = false;
|
||||
}
|
||||
|
||||
void pRadioButton::setGroup(const group<RadioButton>& group) {
|
||||
if(&parent() == this) return;
|
||||
parent().locked = true;
|
||||
gtk_radio_button_set_group(
|
||||
GTK_RADIO_BUTTON(gtkWidget),
|
||||
gtk_radio_button_get_group(GTK_RADIO_BUTTON(parent().gtkWidget))
|
||||
);
|
||||
for(auto& item : radioButton.state.group) {
|
||||
if(item.state.checked) {
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(item.p.gtkWidget), true);
|
||||
break;
|
||||
}
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(item.p.gtkWidget), item.state.checked);
|
||||
}
|
||||
parent().locked = false;
|
||||
}
|
||||
|
||||
void pRadioButton::setText(string text) {
|
||||
gtk_button_set_label(GTK_BUTTON(gtkWidget), text);
|
||||
}
|
||||
|
||||
void pRadioButton::onActivate() {
|
||||
if(parent().locked == false) {
|
||||
bool wasChecked = radioButton.state.checked;
|
||||
setChecked();
|
||||
if(wasChecked == false) {
|
||||
if(radioButton.onActivate) radioButton.onActivate();
|
||||
}
|
||||
void pRadioButton::setImage(const image& image, Orientation orientation) {
|
||||
if(image.empty() == false) {
|
||||
GtkImage* gtkImage = CreateImage(image);
|
||||
gtk_button_set_image(GTK_BUTTON(gtkWidget), (GtkWidget*)gtkImage);
|
||||
} else {
|
||||
gtk_button_set_image(GTK_BUTTON(gtkWidget), nullptr);
|
||||
}
|
||||
switch(orientation) {
|
||||
case Orientation::Horizontal: gtk_button_set_image_position(GTK_BUTTON(gtkWidget), GTK_POS_LEFT); break;
|
||||
case Orientation::Vertical: gtk_button_set_image_position(GTK_BUTTON(gtkWidget), GTK_POS_TOP); break;
|
||||
}
|
||||
}
|
||||
|
||||
pRadioButton& pRadioButton::parent() {
|
||||
if(radioButton.state.group.size()) return radioButton.state.group.first().p;
|
||||
return *this;
|
||||
void pRadioButton::setText(string text) {
|
||||
gtk_button_set_label(GTK_BUTTON(gtkWidget), text);
|
||||
setFont(widget.state.font);
|
||||
}
|
||||
|
||||
void pRadioButton::constructor() {
|
||||
gtkWidget = gtk_radio_button_new_with_label(nullptr, "");
|
||||
g_signal_connect_swapped(G_OBJECT(gtkWidget), "toggled", G_CALLBACK(RadioButton_activate), (gpointer)&radioButton);
|
||||
gtkWidget = gtk_toggle_button_new();
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "toggled", G_CALLBACK(RadioButton_activate), (gpointer)&radioButton);
|
||||
|
||||
setGroup(radioButton.state.group);
|
||||
setText(radioButton.state.text);
|
||||
|
@ -72,4 +72,18 @@ void pRadioButton::orphan() {
|
|||
constructor();
|
||||
}
|
||||
|
||||
void pRadioButton::onActivate() {
|
||||
if(parent().locked) return;
|
||||
bool wasChecked = radioButton.state.checked;
|
||||
setChecked();
|
||||
if(!wasChecked) {
|
||||
if(radioButton.onActivate) radioButton.onActivate();
|
||||
}
|
||||
}
|
||||
|
||||
pRadioButton& pRadioButton::parent() {
|
||||
if(radioButton.state.group.size()) return radioButton.state.group.first().p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
namespace phoenix {
|
||||
|
||||
static void RadioLabel_activate(GtkToggleButton* toggleButton, RadioLabel* self) {
|
||||
self->p.onActivate();
|
||||
}
|
||||
|
||||
Size pRadioLabel::minimumSize() {
|
||||
Size size = pFont::size(widget.state.font, radioLabel.state.text);
|
||||
return {size.width + 28, size.height + 4};
|
||||
}
|
||||
|
||||
void pRadioLabel::setChecked() {
|
||||
parent().locked = true;
|
||||
for(auto& item : radioLabel.state.group) item.state.checked = false;
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtkWidget), radioLabel.state.checked = true);
|
||||
parent().locked = false;
|
||||
}
|
||||
|
||||
void pRadioLabel::setGroup(const group<RadioLabel>& group) {
|
||||
if(&parent() == this) return;
|
||||
parent().locked = true;
|
||||
gtk_radio_button_set_group(
|
||||
GTK_RADIO_BUTTON(gtkWidget),
|
||||
gtk_radio_button_get_group(GTK_RADIO_BUTTON(parent().gtkWidget))
|
||||
);
|
||||
for(auto& item : radioLabel.state.group) {
|
||||
if(item.state.checked) {
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(item.p.gtkWidget), true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
parent().locked = false;
|
||||
}
|
||||
|
||||
void pRadioLabel::setText(string text) {
|
||||
gtk_button_set_label(GTK_BUTTON(gtkWidget), text);
|
||||
}
|
||||
|
||||
void pRadioLabel::constructor() {
|
||||
gtkWidget = gtk_radio_button_new_with_label(nullptr, "");
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "toggled", G_CALLBACK(RadioLabel_activate), (gpointer)&radioLabel);
|
||||
|
||||
setGroup(radioLabel.state.group);
|
||||
setText(radioLabel.state.text);
|
||||
}
|
||||
|
||||
void pRadioLabel::destructor() {
|
||||
gtk_widget_destroy(gtkWidget);
|
||||
}
|
||||
|
||||
void pRadioLabel::orphan() {
|
||||
destructor();
|
||||
constructor();
|
||||
}
|
||||
|
||||
void pRadioLabel::onActivate() {
|
||||
if(parent().locked) return;
|
||||
bool wasChecked = radioLabel.state.checked;
|
||||
setChecked();
|
||||
if(wasChecked) return;
|
||||
if(radioLabel.onActivate) radioLabel.onActivate();
|
||||
}
|
||||
|
||||
pRadioLabel& pRadioLabel::parent() {
|
||||
if(radioLabel.state.group.size()) return radioLabel.state.group.first().p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
namespace phoenix {
|
||||
|
||||
static void TabFrame_change(GtkNotebook* notebook, GtkWidget* page, unsigned selection, TabFrame* self) {
|
||||
self->state.selection = selection;
|
||||
self->p.synchronizeLayout();
|
||||
if(self->onChange) self->onChange();
|
||||
}
|
||||
|
||||
void pTabFrame::append(string text, const image& image) {
|
||||
unsigned selection = tabFrame.state.text.size() - 1;
|
||||
|
||||
Tab tab;
|
||||
tab.child = gtk_fixed_new();
|
||||
tab.container = gtk_hbox_new(false, 0);
|
||||
tab.image = gtk_image_new();
|
||||
tab.title = gtk_label_new(text);
|
||||
tabs.append(tab);
|
||||
|
||||
gtk_widget_show(tab.child);
|
||||
gtk_widget_show(tab.container);
|
||||
gtk_widget_show(tab.image);
|
||||
gtk_widget_show(tab.title);
|
||||
gtk_box_pack_start(GTK_BOX(tab.container), tab.image, false, false, 0);
|
||||
gtk_box_pack_start(GTK_BOX(tab.container), tab.title, false, false, 2);
|
||||
|
||||
gtk_notebook_append_page(GTK_NOTEBOOK(gtkWidget), tab.child, tab.container);
|
||||
setFont(widget.state.font);
|
||||
if(!image.empty()) setImage(selection, image);
|
||||
}
|
||||
|
||||
GtkWidget* pTabFrame::container(Widget& widget) {
|
||||
Layout* widgetLayout = GetParentWidgetLayout(&widget);
|
||||
unsigned selection = 0;
|
||||
for(auto& layout : tabFrame.state.layout) {
|
||||
if(layout == widgetLayout) return tabs[selection].child;
|
||||
selection++;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Position pTabFrame::containerOffset() {
|
||||
return {widget.state.geometry.x + 3, widget.state.geometry.y + 28};
|
||||
}
|
||||
|
||||
Position pTabFrame::displacement() {
|
||||
return {6, 31};
|
||||
}
|
||||
|
||||
void pTabFrame::remove(unsigned selection) {
|
||||
tabs.remove(selection);
|
||||
gtk_notebook_remove_page(GTK_NOTEBOOK(gtkWidget), selection);
|
||||
}
|
||||
|
||||
void pTabFrame::setEnabled(bool enabled) {
|
||||
for(auto& layout : tabFrame.state.layout) {
|
||||
if(layout) layout->setEnabled(layout->enabled());
|
||||
}
|
||||
pWidget::setEnabled(enabled);
|
||||
}
|
||||
|
||||
void pTabFrame::setGeometry(Geometry geometry) {
|
||||
pWidget::setGeometry(geometry);
|
||||
geometry.x += 1, geometry.width -= 5;
|
||||
geometry.y += 26, geometry.height -= 31;
|
||||
for(auto& layout : tabFrame.state.layout) {
|
||||
if(layout == nullptr) continue;
|
||||
layout->setGeometry(geometry);
|
||||
}
|
||||
synchronizeLayout();
|
||||
}
|
||||
|
||||
void pTabFrame::setImage(unsigned selection, const image& image) {
|
||||
nall::image copy = image;
|
||||
unsigned size = pFont::size(widget.state.font, " ").height;
|
||||
copy.scale(size, size);
|
||||
GdkPixbuf* pixbuf = CreatePixbuf(copy);
|
||||
gtk_image_set_from_pixbuf(GTK_IMAGE(tabs[selection].image), pixbuf);
|
||||
}
|
||||
|
||||
void pTabFrame::setSelection(unsigned selection) {
|
||||
gtk_notebook_set_current_page(GTK_NOTEBOOK(gtkWidget), selection);
|
||||
}
|
||||
|
||||
void pTabFrame::setText(unsigned selection, string text) {
|
||||
gtk_label_set_text(GTK_LABEL(tabs[selection].title), text);
|
||||
}
|
||||
|
||||
void pTabFrame::setVisible(bool visible) {
|
||||
for(auto& layout : tabFrame.state.layout) {
|
||||
if(layout) layout->setVisible(layout->visible());
|
||||
}
|
||||
pWidget::setVisible(visible);
|
||||
}
|
||||
|
||||
void pTabFrame::constructor() {
|
||||
gtkWidget = gtk_notebook_new();
|
||||
gtk_notebook_set_show_border(GTK_NOTEBOOK(gtkWidget), false);
|
||||
gtk_notebook_set_tab_pos(GTK_NOTEBOOK(gtkWidget), GTK_POS_TOP);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "switch-page", G_CALLBACK(TabFrame_change), (gpointer)&tabFrame);
|
||||
|
||||
setSelection(tabFrame.state.selection);
|
||||
}
|
||||
|
||||
void pTabFrame::destructor() {
|
||||
gtk_widget_destroy(gtkWidget);
|
||||
}
|
||||
|
||||
void pTabFrame::orphan() {
|
||||
destructor();
|
||||
constructor();
|
||||
}
|
||||
|
||||
void pTabFrame::setFont(string font) {
|
||||
for(auto& tab : tabs) pFont::setFont(tab.title, font);
|
||||
}
|
||||
|
||||
void pTabFrame::synchronizeLayout() {
|
||||
unsigned selection = 0;
|
||||
for(auto& layout : tabFrame.state.layout) {
|
||||
if(layout) layout->setVisible(selection == tabFrame.state.selection);
|
||||
selection++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,19 +1,16 @@
|
|||
namespace phoenix {
|
||||
|
||||
static void VerticalScroller_change(VerticalScroller* self) {
|
||||
if(self->state.position == self->position()) return;
|
||||
self->state.position = self->position();
|
||||
if(self->p.locked == false && self->onChange) self->onChange();
|
||||
static void VerticalScroller_change(GtkRange* gtkRange, VerticalScroller* self) {
|
||||
unsigned position = (unsigned)gtk_range_get_value(gtkRange);
|
||||
if(self->state.position == position) return;
|
||||
self->state.position = position;
|
||||
if(!self->p.locked && self->onChange) self->onChange();
|
||||
}
|
||||
|
||||
Size pVerticalScroller::minimumSize() {
|
||||
return {20, 0};
|
||||
}
|
||||
|
||||
unsigned pVerticalScroller::position() {
|
||||
return (unsigned)gtk_range_get_value(GTK_RANGE(gtkWidget));
|
||||
}
|
||||
|
||||
void pVerticalScroller::setLength(unsigned length) {
|
||||
locked = true;
|
||||
length += length == 0;
|
||||
|
@ -28,7 +25,7 @@ void pVerticalScroller::setPosition(unsigned position) {
|
|||
|
||||
void pVerticalScroller::constructor() {
|
||||
gtkWidget = gtk_vscrollbar_new(0);
|
||||
g_signal_connect_swapped(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(VerticalScroller_change), (gpointer)&verticalScroller);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(VerticalScroller_change), (gpointer)&verticalScroller);
|
||||
|
||||
setLength(verticalScroller.state.length);
|
||||
setPosition(verticalScroller.state.position);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
namespace phoenix {
|
||||
|
||||
static void VerticalSlider_change(VerticalSlider* self) {
|
||||
if(self->state.position == self->position()) return;
|
||||
self->state.position = self->position();
|
||||
static void VerticalSlider_change(GtkRange* gtkRange, VerticalSlider* self) {
|
||||
unsigned position = (unsigned)gtk_range_get_value(gtkRange);
|
||||
if(self->state.position == position) return;
|
||||
self->state.position = position;
|
||||
if(self->onChange) self->onChange();
|
||||
}
|
||||
|
||||
|
@ -10,10 +11,6 @@ Size pVerticalSlider::minimumSize() {
|
|||
return {20, 0};
|
||||
}
|
||||
|
||||
unsigned pVerticalSlider::position() {
|
||||
return (unsigned)gtk_range_get_value(GTK_RANGE(gtkWidget));
|
||||
}
|
||||
|
||||
void pVerticalSlider::setLength(unsigned length) {
|
||||
length += length == 0;
|
||||
gtk_range_set_range(GTK_RANGE(gtkWidget), 0, max(1u, length - 1));
|
||||
|
@ -27,7 +24,7 @@ void pVerticalSlider::setPosition(unsigned position) {
|
|||
void pVerticalSlider::constructor() {
|
||||
gtkWidget = gtk_vscale_new_with_range(0, 100, 1);
|
||||
gtk_scale_set_draw_value(GTK_SCALE(gtkWidget), false);
|
||||
g_signal_connect_swapped(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(VerticalSlider_change), (gpointer)&verticalSlider);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(VerticalSlider_change), (gpointer)&verticalSlider);
|
||||
|
||||
setLength(verticalSlider.state.length);
|
||||
setPosition(verticalSlider.state.position);
|
||||
|
|
|
@ -51,10 +51,10 @@ void pViewport::constructor() {
|
|||
gtk_widget_add_events(gtkWidget,
|
||||
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "drag-data-received", G_CALLBACK(Viewport_dropEvent), (gpointer)&viewport);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "button_press_event", G_CALLBACK(Viewport_mousePress), (gpointer)this);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "button_release_event", G_CALLBACK(Viewport_mouseRelease), (gpointer)this);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "leave_notify_event", G_CALLBACK(Viewport_mouseLeave), (gpointer)this);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "motion_notify_event", G_CALLBACK(Viewport_mouseMove), (gpointer)this);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "button-press-event", G_CALLBACK(Viewport_mousePress), (gpointer)this);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "button-release-event", G_CALLBACK(Viewport_mouseRelease), (gpointer)this);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "leave-notify-event", G_CALLBACK(Viewport_mouseLeave), (gpointer)this);
|
||||
g_signal_connect(G_OBJECT(gtkWidget), "motion-notify-event", G_CALLBACK(Viewport_mouseMove), (gpointer)this);
|
||||
|
||||
GdkColor color;
|
||||
color.pixel = 0;
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
namespace phoenix {
|
||||
|
||||
bool pWidget::enabled() {
|
||||
return gtk_widget_get_sensitive(gtkWidget);
|
||||
GtkWidget* pWidget::container(Widget& widget) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Position pWidget::containerOffset() {
|
||||
return {0, 0};
|
||||
}
|
||||
|
||||
bool pWidget::focused() {
|
||||
|
@ -13,8 +17,9 @@ Size pWidget::minimumSize() {
|
|||
}
|
||||
|
||||
void pWidget::setEnabled(bool enabled) {
|
||||
if(!widget.parent()) enabled = false;
|
||||
if(widget.state.abstract) enabled = false;
|
||||
if(sizable.state.layout && sizable.state.layout->enabled() == false) enabled = false;
|
||||
if(!widget.enabledToAll()) enabled = false;
|
||||
gtk_widget_set_sensitive(gtkWidget, enabled);
|
||||
}
|
||||
|
||||
|
@ -27,20 +32,26 @@ void pWidget::setFont(string font) {
|
|||
}
|
||||
|
||||
void pWidget::setGeometry(Geometry geometry) {
|
||||
if(sizable.window() && sizable.window()->visible()) gtk_fixed_move(GTK_FIXED(sizable.window()->p.formContainer), gtkWidget, geometry.x, geometry.y);
|
||||
unsigned width = (signed)geometry.width <= 0 ? 1U : geometry.width;
|
||||
unsigned height = (signed)geometry.height <= 0 ? 1U : geometry.height;
|
||||
Position displacement = GetDisplacement(&widget);
|
||||
geometry.x -= displacement.x;
|
||||
geometry.y -= displacement.y;
|
||||
|
||||
if(gtkParent) gtk_fixed_move(GTK_FIXED(gtkParent), gtkWidget, geometry.x, geometry.y);
|
||||
unsigned width = (signed)geometry.width <= 0 ? 1u : geometry.width;
|
||||
unsigned height = (signed)geometry.height <= 0 ? 1u : geometry.height;
|
||||
gtk_widget_set_size_request(gtkWidget, width, height);
|
||||
if(widget.onSize) widget.onSize();
|
||||
}
|
||||
|
||||
void pWidget::setVisible(bool visible) {
|
||||
if(!widget.parent()) visible = false;
|
||||
if(widget.state.abstract) visible = false;
|
||||
if(sizable.state.layout && sizable.state.layout->visible() == false) visible = false;
|
||||
if(!widget.visibleToAll()) visible = false;
|
||||
gtk_widget_set_visible(gtkWidget, visible);
|
||||
}
|
||||
|
||||
void pWidget::constructor() {
|
||||
if(widget.state.abstract) gtkWidget = gtk_label_new("");
|
||||
if(widget.state.abstract) gtkWidget = gtk_fixed_new();
|
||||
}
|
||||
|
||||
void pWidget::destructor() {
|
||||
|
|
|
@ -17,7 +17,9 @@ static gboolean Window_expose(GtkWidget* widget, GdkEvent* event, Window* window
|
|||
double blue = (double)color.blue / 255.0;
|
||||
double alpha = (double)color.alpha / 255.0;
|
||||
|
||||
if(gdk_screen_is_composited(gdk_screen_get_default())) {
|
||||
if(gdk_screen_is_composited(gdk_screen_get_default())
|
||||
&& gdk_screen_get_rgba_colormap(gdk_screen_get_default())
|
||||
) {
|
||||
cairo_set_source_rgba(context, red, green, blue, alpha);
|
||||
} else {
|
||||
cairo_set_source_rgb(context, red, green, blue);
|
||||
|
@ -80,7 +82,7 @@ static gboolean Window_configure(GtkWidget* widget, GdkEvent* event, Window* win
|
|||
return false;
|
||||
}
|
||||
|
||||
static void Window_dropEvent(GtkWidget* widget, GdkDragContext* context, gint x, gint y,
|
||||
static void Window_drop(GtkWidget* widget, GdkDragContext* context, gint x, gint y,
|
||||
GtkSelectionData* data, guint type, guint timestamp, Window* window) {
|
||||
if(window->state.droppable == false) return;
|
||||
lstring paths = DropPaths(data);
|
||||
|
@ -88,13 +90,13 @@ GtkSelectionData* data, guint type, guint timestamp, Window* window) {
|
|||
if(window->onDrop) window->onDrop(paths);
|
||||
}
|
||||
|
||||
static gboolean Window_keyPressEvent(GtkWidget* widget, GdkEventKey* event, Window* window) {
|
||||
static gboolean Window_keyPress(GtkWidget* widget, GdkEventKey* event, Window* window) {
|
||||
Keyboard::Keycode key = Keysym(event->keyval);
|
||||
if(key != Keyboard::Keycode::None && window->onKeyPress) window->onKeyPress(key);
|
||||
return false;
|
||||
}
|
||||
|
||||
static gboolean Window_keyReleaseEvent(GtkWidget* widget, GdkEventKey* event, Window* window) {
|
||||
static gboolean Window_keyRelease(GtkWidget* widget, GdkEventKey* event, Window* window) {
|
||||
Keyboard::Keycode key = Keysym(event->keyval);
|
||||
if(key != Keyboard::Keycode::None && window->onKeyRelease) window->onKeyRelease(key);
|
||||
return false;
|
||||
|
@ -140,8 +142,8 @@ void pWindow::append(Layout& layout) {
|
|||
}
|
||||
|
||||
void pWindow::append(Menu& menu) {
|
||||
if(window.state.menuFont != "") menu.p.setFont(window.state.menuFont);
|
||||
else menu.p.setFont("Sans, 8");
|
||||
if(window.state.menuFont) menu.p.setFont(window.state.menuFont);
|
||||
else menu.p.setFont(Font::sans(8));
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(this->menu), menu.p.widget);
|
||||
gtk_widget_show(menu.p.widget);
|
||||
}
|
||||
|
@ -151,22 +153,17 @@ void pWindow::append(Widget& widget) {
|
|||
widget.setFont(window.state.widgetFont);
|
||||
}
|
||||
|
||||
((Sizable&)widget).state.window = &window;
|
||||
gtk_fixed_put(GTK_FIXED(formContainer), widget.p.gtkWidget, 0, 0);
|
||||
if(widget.state.font != "") widget.p.setFont(widget.state.font);
|
||||
else if(window.state.widgetFont != "") widget.p.setFont(window.state.widgetFont);
|
||||
else widget.p.setFont("Sans, 8");
|
||||
widget.setVisible(widget.visible());
|
||||
}
|
||||
if(HasParentWidget(&widget)) {
|
||||
widget.p.gtkParent = GetParentWidget(&widget)->p.container(widget);
|
||||
} else {
|
||||
widget.p.gtkParent = formContainer;
|
||||
}
|
||||
|
||||
Color pWindow::backgroundColor() {
|
||||
if(window.state.backgroundColorOverride) return window.state.backgroundColor;
|
||||
return {
|
||||
(uint8_t)(settings->window.backgroundColor >> 16),
|
||||
(uint8_t)(settings->window.backgroundColor >> 8),
|
||||
(uint8_t)(settings->window.backgroundColor >> 0),
|
||||
255
|
||||
};
|
||||
gtk_fixed_put(GTK_FIXED(widget.p.gtkParent), widget.p.gtkWidget, 0, 0);
|
||||
if(widget.state.font) widget.p.setFont(widget.state.font);
|
||||
else if(window.state.widgetFont) widget.p.setFont(window.state.widgetFont);
|
||||
else widget.p.setFont(Font::sans(8));
|
||||
widget.setVisible(widget.visible());
|
||||
}
|
||||
|
||||
Geometry pWindow::frameMargin() {
|
||||
|
@ -335,11 +332,9 @@ void pWindow::constructor() {
|
|||
}
|
||||
}
|
||||
|
||||
if(gdk_screen_is_composited(gdk_screen_get_default())) {
|
||||
gtk_widget_set_colormap(widget, gdk_screen_get_rgba_colormap(gdk_screen_get_default()));
|
||||
} else {
|
||||
gtk_widget_set_colormap(widget, gdk_screen_get_rgb_colormap(gdk_screen_get_default()));
|
||||
}
|
||||
GdkColormap* colormap = gdk_screen_get_rgba_colormap(gdk_screen_get_default());
|
||||
if(!colormap) colormap = gdk_screen_get_rgb_colormap(gdk_screen_get_default());
|
||||
if(colormap) gtk_widget_set_colormap(widget, colormap);
|
||||
|
||||
gtk_window_set_resizable(GTK_WINDOW(widget), true);
|
||||
#if GTK_MAJOR_VERSION >= 3
|
||||
|
@ -370,18 +365,24 @@ void pWindow::constructor() {
|
|||
setTitle("");
|
||||
setResizable(window.state.resizable);
|
||||
setGeometry(window.state.geometry);
|
||||
setMenuFont("Sans, 8");
|
||||
setStatusFont("Sans, 8");
|
||||
setMenuFont(Font::sans(8));
|
||||
setStatusFont(Font::sans(8));
|
||||
|
||||
g_signal_connect(G_OBJECT(widget), "delete-event", G_CALLBACK(Window_close), (gpointer)&window);
|
||||
g_signal_connect(G_OBJECT(widget), "expose-event", G_CALLBACK(Window_expose), (gpointer)&window);
|
||||
g_signal_connect(G_OBJECT(widget), "configure-event", G_CALLBACK(Window_configure), (gpointer)&window);
|
||||
g_signal_connect(G_OBJECT(widget), "drag-data-received", G_CALLBACK(Window_dropEvent), (gpointer)&window);
|
||||
g_signal_connect(G_OBJECT(widget), "key-press-event", G_CALLBACK(Window_keyPressEvent), (gpointer)&window);
|
||||
g_signal_connect(G_OBJECT(widget), "key-release-event", G_CALLBACK(Window_keyPressEvent), (gpointer)&window);
|
||||
g_signal_connect(G_OBJECT(widget), "drag-data-received", G_CALLBACK(Window_drop), (gpointer)&window);
|
||||
g_signal_connect(G_OBJECT(widget), "key-press-event", G_CALLBACK(Window_keyPress), (gpointer)&window);
|
||||
g_signal_connect(G_OBJECT(widget), "key-release-event", G_CALLBACK(Window_keyPress), (gpointer)&window);
|
||||
|
||||
g_signal_connect(G_OBJECT(formContainer), "size-allocate", G_CALLBACK(Window_sizeAllocate), (gpointer)&window);
|
||||
g_signal_connect(G_OBJECT(formContainer), "size-request", G_CALLBACK(Window_sizeRequest), (gpointer)&window);
|
||||
|
||||
window.state.backgroundColor = Color(
|
||||
(uint8_t)(settings->window.backgroundColor >> 16),
|
||||
(uint8_t)(settings->window.backgroundColor >> 8),
|
||||
(uint8_t)(settings->window.backgroundColor >> 0)
|
||||
);
|
||||
}
|
||||
|
||||
unsigned pWindow::menuHeight() {
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
namespace phoenix {
|
||||
|
||||
bool pCheckItem::checked() {
|
||||
return qtAction->isChecked();
|
||||
}
|
||||
|
||||
void pCheckItem::setChecked(bool checked) {
|
||||
qtAction->setChecked(checked);
|
||||
}
|
||||
|
@ -25,7 +21,7 @@ void pCheckItem::destructor() {
|
|||
}
|
||||
|
||||
void pCheckItem::onToggle() {
|
||||
checkItem.state.checked = checked();
|
||||
checkItem.state.checked = qtAction->isChecked();
|
||||
if(checkItem.onToggle) checkItem.onToggle();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
namespace phoenix {
|
||||
|
||||
bool pRadioItem::checked() {
|
||||
return qtAction->isChecked();
|
||||
}
|
||||
|
||||
void pRadioItem::setChecked() {
|
||||
locked = true;
|
||||
for(auto& item : radioItem.state.group) {
|
||||
|
@ -37,9 +33,9 @@ void pRadioItem::destructor() {
|
|||
}
|
||||
|
||||
void pRadioItem::onActivate() {
|
||||
if(radioItem.state.checked == false) {
|
||||
if(!radioItem.state.checked) {
|
||||
setChecked();
|
||||
if(locked == false && radioItem.onActivate) radioItem.onActivate();
|
||||
if(!locked && radioItem.onActivate) radioItem.onActivate();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,10 @@
|
|||
#include "widget/button.cpp"
|
||||
#include "widget/canvas.cpp"
|
||||
#include "widget/check-button.cpp"
|
||||
#include "widget/check-label.cpp"
|
||||
#include "widget/combo-button.cpp"
|
||||
#include "widget/console.cpp"
|
||||
#include "widget/frame.cpp"
|
||||
#include "widget/hex-edit.cpp"
|
||||
#include "widget/horizontal-scroller.cpp"
|
||||
#include "widget/horizontal-slider.cpp"
|
||||
|
@ -34,6 +36,8 @@
|
|||
#include "widget/list-view.cpp"
|
||||
#include "widget/progress-bar.cpp"
|
||||
#include "widget/radio-button.cpp"
|
||||
#include "widget/radio-label.cpp"
|
||||
#include "widget/tab-frame.cpp"
|
||||
#include "widget/text-edit.cpp"
|
||||
#include "widget/vertical-scroller.cpp"
|
||||
#include "widget/vertical-slider.cpp"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
** Meta object code from reading C++ file 'platform.moc.hpp'
|
||||
**
|
||||
** Created: Tue Nov 5 18:38:24 2013
|
||||
** Created: Fri Nov 22 09:50:07 2013
|
||||
** by: The Qt Meta Object Compiler version 63 (Qt 4.8.2)
|
||||
**
|
||||
** WARNING! All changes made in this file will be lost!
|
||||
|
@ -536,13 +536,14 @@ static const uint qt_meta_data_phoenix__pCheckButton[] = {
|
|||
0, // signalCount
|
||||
|
||||
// slots: signature, parameters, type, tag, flags
|
||||
23, 22, 22, 22, 0x0a,
|
||||
31, 23, 22, 22, 0x0a,
|
||||
|
||||
0 // eod
|
||||
};
|
||||
|
||||
static const char qt_meta_stringdata_phoenix__pCheckButton[] = {
|
||||
"phoenix::pCheckButton\0\0onToggle()\0"
|
||||
"phoenix::pCheckButton\0\0checked\0"
|
||||
"onToggle(bool)\0"
|
||||
};
|
||||
|
||||
void phoenix::pCheckButton::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
|
||||
|
@ -551,11 +552,10 @@ void phoenix::pCheckButton::qt_static_metacall(QObject *_o, QMetaObject::Call _c
|
|||
Q_ASSERT(staticMetaObject.cast(_o));
|
||||
pCheckButton *_t = static_cast<pCheckButton *>(_o);
|
||||
switch (_id) {
|
||||
case 0: _t->onToggle(); break;
|
||||
case 0: _t->onToggle((*reinterpret_cast< bool(*)>(_a[1]))); break;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
Q_UNUSED(_a);
|
||||
}
|
||||
|
||||
const QMetaObjectExtraData phoenix::pCheckButton::staticMetaObjectExtraData = {
|
||||
|
@ -598,6 +598,82 @@ int phoenix::pCheckButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
|
|||
}
|
||||
return _id;
|
||||
}
|
||||
static const uint qt_meta_data_phoenix__pCheckLabel[] = {
|
||||
|
||||
// content:
|
||||
6, // revision
|
||||
0, // classname
|
||||
0, 0, // classinfo
|
||||
1, 14, // methods
|
||||
0, 0, // properties
|
||||
0, 0, // enums/sets
|
||||
0, 0, // constructors
|
||||
0, // flags
|
||||
0, // signalCount
|
||||
|
||||
// slots: signature, parameters, type, tag, flags
|
||||
22, 21, 21, 21, 0x0a,
|
||||
|
||||
0 // eod
|
||||
};
|
||||
|
||||
static const char qt_meta_stringdata_phoenix__pCheckLabel[] = {
|
||||
"phoenix::pCheckLabel\0\0onToggle()\0"
|
||||
};
|
||||
|
||||
void phoenix::pCheckLabel::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
|
||||
{
|
||||
if (_c == QMetaObject::InvokeMetaMethod) {
|
||||
Q_ASSERT(staticMetaObject.cast(_o));
|
||||
pCheckLabel *_t = static_cast<pCheckLabel *>(_o);
|
||||
switch (_id) {
|
||||
case 0: _t->onToggle(); break;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
Q_UNUSED(_a);
|
||||
}
|
||||
|
||||
const QMetaObjectExtraData phoenix::pCheckLabel::staticMetaObjectExtraData = {
|
||||
0, qt_static_metacall
|
||||
};
|
||||
|
||||
const QMetaObject phoenix::pCheckLabel::staticMetaObject = {
|
||||
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pCheckLabel,
|
||||
qt_meta_data_phoenix__pCheckLabel, &staticMetaObjectExtraData }
|
||||
};
|
||||
|
||||
#ifdef Q_NO_DATA_RELOCATION
|
||||
const QMetaObject &phoenix::pCheckLabel::getStaticMetaObject() { return staticMetaObject; }
|
||||
#endif //Q_NO_DATA_RELOCATION
|
||||
|
||||
const QMetaObject *phoenix::pCheckLabel::metaObject() const
|
||||
{
|
||||
return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
|
||||
}
|
||||
|
||||
void *phoenix::pCheckLabel::qt_metacast(const char *_clname)
|
||||
{
|
||||
if (!_clname) return 0;
|
||||
if (!strcmp(_clname, qt_meta_stringdata_phoenix__pCheckLabel))
|
||||
return static_cast<void*>(const_cast< pCheckLabel*>(this));
|
||||
if (!strcmp(_clname, "pWidget"))
|
||||
return static_cast< pWidget*>(const_cast< pCheckLabel*>(this));
|
||||
return QObject::qt_metacast(_clname);
|
||||
}
|
||||
|
||||
int phoenix::pCheckLabel::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
|
||||
{
|
||||
_id = QObject::qt_metacall(_c, _id, _a);
|
||||
if (_id < 0)
|
||||
return _id;
|
||||
if (_c == QMetaObject::InvokeMetaMethod) {
|
||||
if (_id < 1)
|
||||
qt_static_metacall(this, _c, _id, _a);
|
||||
_id -= 1;
|
||||
}
|
||||
return _id;
|
||||
}
|
||||
static const uint qt_meta_data_phoenix__pComboButton[] = {
|
||||
|
||||
// content:
|
||||
|
@ -737,6 +813,69 @@ int phoenix::pConsole::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
|
|||
return _id;
|
||||
return _id;
|
||||
}
|
||||
static const uint qt_meta_data_phoenix__pFrame[] = {
|
||||
|
||||
// content:
|
||||
6, // revision
|
||||
0, // classname
|
||||
0, 0, // classinfo
|
||||
0, 0, // methods
|
||||
0, 0, // properties
|
||||
0, 0, // enums/sets
|
||||
0, 0, // constructors
|
||||
0, // flags
|
||||
0, // signalCount
|
||||
|
||||
0 // eod
|
||||
};
|
||||
|
||||
static const char qt_meta_stringdata_phoenix__pFrame[] = {
|
||||
"phoenix::pFrame\0"
|
||||
};
|
||||
|
||||
void phoenix::pFrame::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
|
||||
{
|
||||
Q_UNUSED(_o);
|
||||
Q_UNUSED(_id);
|
||||
Q_UNUSED(_c);
|
||||
Q_UNUSED(_a);
|
||||
}
|
||||
|
||||
const QMetaObjectExtraData phoenix::pFrame::staticMetaObjectExtraData = {
|
||||
0, qt_static_metacall
|
||||
};
|
||||
|
||||
const QMetaObject phoenix::pFrame::staticMetaObject = {
|
||||
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pFrame,
|
||||
qt_meta_data_phoenix__pFrame, &staticMetaObjectExtraData }
|
||||
};
|
||||
|
||||
#ifdef Q_NO_DATA_RELOCATION
|
||||
const QMetaObject &phoenix::pFrame::getStaticMetaObject() { return staticMetaObject; }
|
||||
#endif //Q_NO_DATA_RELOCATION
|
||||
|
||||
const QMetaObject *phoenix::pFrame::metaObject() const
|
||||
{
|
||||
return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
|
||||
}
|
||||
|
||||
void *phoenix::pFrame::qt_metacast(const char *_clname)
|
||||
{
|
||||
if (!_clname) return 0;
|
||||
if (!strcmp(_clname, qt_meta_stringdata_phoenix__pFrame))
|
||||
return static_cast<void*>(const_cast< pFrame*>(this));
|
||||
if (!strcmp(_clname, "pWidget"))
|
||||
return static_cast< pWidget*>(const_cast< pFrame*>(this));
|
||||
return QObject::qt_metacast(_clname);
|
||||
}
|
||||
|
||||
int phoenix::pFrame::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
|
||||
{
|
||||
_id = QObject::qt_metacall(_c, _id, _a);
|
||||
if (_id < 0)
|
||||
return _id;
|
||||
return _id;
|
||||
}
|
||||
static const uint qt_meta_data_phoenix__pHexEdit[] = {
|
||||
|
||||
// content:
|
||||
|
@ -1125,6 +1264,82 @@ int phoenix::pListView::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
|
|||
}
|
||||
return _id;
|
||||
}
|
||||
static const uint qt_meta_data_phoenix__pRadioLabel[] = {
|
||||
|
||||
// content:
|
||||
6, // revision
|
||||
0, // classname
|
||||
0, 0, // classinfo
|
||||
1, 14, // methods
|
||||
0, 0, // properties
|
||||
0, 0, // enums/sets
|
||||
0, 0, // constructors
|
||||
0, // flags
|
||||
0, // signalCount
|
||||
|
||||
// slots: signature, parameters, type, tag, flags
|
||||
22, 21, 21, 21, 0x0a,
|
||||
|
||||
0 // eod
|
||||
};
|
||||
|
||||
static const char qt_meta_stringdata_phoenix__pRadioLabel[] = {
|
||||
"phoenix::pRadioLabel\0\0onActivate()\0"
|
||||
};
|
||||
|
||||
void phoenix::pRadioLabel::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
|
||||
{
|
||||
if (_c == QMetaObject::InvokeMetaMethod) {
|
||||
Q_ASSERT(staticMetaObject.cast(_o));
|
||||
pRadioLabel *_t = static_cast<pRadioLabel *>(_o);
|
||||
switch (_id) {
|
||||
case 0: _t->onActivate(); break;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
Q_UNUSED(_a);
|
||||
}
|
||||
|
||||
const QMetaObjectExtraData phoenix::pRadioLabel::staticMetaObjectExtraData = {
|
||||
0, qt_static_metacall
|
||||
};
|
||||
|
||||
const QMetaObject phoenix::pRadioLabel::staticMetaObject = {
|
||||
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pRadioLabel,
|
||||
qt_meta_data_phoenix__pRadioLabel, &staticMetaObjectExtraData }
|
||||
};
|
||||
|
||||
#ifdef Q_NO_DATA_RELOCATION
|
||||
const QMetaObject &phoenix::pRadioLabel::getStaticMetaObject() { return staticMetaObject; }
|
||||
#endif //Q_NO_DATA_RELOCATION
|
||||
|
||||
const QMetaObject *phoenix::pRadioLabel::metaObject() const
|
||||
{
|
||||
return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
|
||||
}
|
||||
|
||||
void *phoenix::pRadioLabel::qt_metacast(const char *_clname)
|
||||
{
|
||||
if (!_clname) return 0;
|
||||
if (!strcmp(_clname, qt_meta_stringdata_phoenix__pRadioLabel))
|
||||
return static_cast<void*>(const_cast< pRadioLabel*>(this));
|
||||
if (!strcmp(_clname, "pWidget"))
|
||||
return static_cast< pWidget*>(const_cast< pRadioLabel*>(this));
|
||||
return QObject::qt_metacast(_clname);
|
||||
}
|
||||
|
||||
int phoenix::pRadioLabel::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
|
||||
{
|
||||
_id = QObject::qt_metacall(_c, _id, _a);
|
||||
if (_id < 0)
|
||||
return _id;
|
||||
if (_c == QMetaObject::InvokeMetaMethod) {
|
||||
if (_id < 1)
|
||||
qt_static_metacall(this, _c, _id, _a);
|
||||
_id -= 1;
|
||||
}
|
||||
return _id;
|
||||
}
|
||||
static const uint qt_meta_data_phoenix__pRadioButton[] = {
|
||||
|
||||
// content:
|
||||
|
@ -1201,6 +1416,82 @@ int phoenix::pRadioButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
|
|||
}
|
||||
return _id;
|
||||
}
|
||||
static const uint qt_meta_data_phoenix__pTabFrame[] = {
|
||||
|
||||
// content:
|
||||
6, // revision
|
||||
0, // classname
|
||||
0, 0, // classinfo
|
||||
1, 14, // methods
|
||||
0, 0, // properties
|
||||
0, 0, // enums/sets
|
||||
0, 0, // constructors
|
||||
0, // flags
|
||||
0, // signalCount
|
||||
|
||||
// slots: signature, parameters, type, tag, flags
|
||||
30, 20, 19, 19, 0x0a,
|
||||
|
||||
0 // eod
|
||||
};
|
||||
|
||||
static const char qt_meta_stringdata_phoenix__pTabFrame[] = {
|
||||
"phoenix::pTabFrame\0\0selection\0"
|
||||
"onChange(int)\0"
|
||||
};
|
||||
|
||||
void phoenix::pTabFrame::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
|
||||
{
|
||||
if (_c == QMetaObject::InvokeMetaMethod) {
|
||||
Q_ASSERT(staticMetaObject.cast(_o));
|
||||
pTabFrame *_t = static_cast<pTabFrame *>(_o);
|
||||
switch (_id) {
|
||||
case 0: _t->onChange((*reinterpret_cast< int(*)>(_a[1]))); break;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const QMetaObjectExtraData phoenix::pTabFrame::staticMetaObjectExtraData = {
|
||||
0, qt_static_metacall
|
||||
};
|
||||
|
||||
const QMetaObject phoenix::pTabFrame::staticMetaObject = {
|
||||
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pTabFrame,
|
||||
qt_meta_data_phoenix__pTabFrame, &staticMetaObjectExtraData }
|
||||
};
|
||||
|
||||
#ifdef Q_NO_DATA_RELOCATION
|
||||
const QMetaObject &phoenix::pTabFrame::getStaticMetaObject() { return staticMetaObject; }
|
||||
#endif //Q_NO_DATA_RELOCATION
|
||||
|
||||
const QMetaObject *phoenix::pTabFrame::metaObject() const
|
||||
{
|
||||
return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
|
||||
}
|
||||
|
||||
void *phoenix::pTabFrame::qt_metacast(const char *_clname)
|
||||
{
|
||||
if (!_clname) return 0;
|
||||
if (!strcmp(_clname, qt_meta_stringdata_phoenix__pTabFrame))
|
||||
return static_cast<void*>(const_cast< pTabFrame*>(this));
|
||||
if (!strcmp(_clname, "pWidget"))
|
||||
return static_cast< pWidget*>(const_cast< pTabFrame*>(this));
|
||||
return QObject::qt_metacast(_clname);
|
||||
}
|
||||
|
||||
int phoenix::pTabFrame::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
|
||||
{
|
||||
_id = QObject::qt_metacall(_c, _id, _a);
|
||||
if (_id < 0)
|
||||
return _id;
|
||||
if (_c == QMetaObject::InvokeMetaMethod) {
|
||||
if (_id < 1)
|
||||
qt_static_metacall(this, _c, _id, _a);
|
||||
_id -= 1;
|
||||
}
|
||||
return _id;
|
||||
}
|
||||
static const uint qt_meta_data_phoenix__pTextEdit[] = {
|
||||
|
||||
// content:
|
||||
|
|
|
@ -94,7 +94,7 @@ public:
|
|||
QTimer* qtTimer;
|
||||
|
||||
void setEnabled(bool enabled);
|
||||
void setInterval(unsigned milliseconds);
|
||||
void setInterval(unsigned interval);
|
||||
|
||||
pTimer(Timer& timer) : pObject(timer), timer(timer) {}
|
||||
void constructor();
|
||||
|
@ -132,7 +132,6 @@ public:
|
|||
void append(Layout& layout);
|
||||
void append(Menu& menu);
|
||||
void append(Widget& widget);
|
||||
Color backgroundColor();
|
||||
Geometry frameMargin();
|
||||
bool focused();
|
||||
Geometry geometry();
|
||||
|
@ -222,7 +221,6 @@ public:
|
|||
CheckItem& checkItem;
|
||||
QAction* qtAction;
|
||||
|
||||
bool checked();
|
||||
void setChecked(bool checked);
|
||||
void setText(string text);
|
||||
|
||||
|
@ -242,7 +240,6 @@ public:
|
|||
QAction* qtAction;
|
||||
QActionGroup* qtGroup;
|
||||
|
||||
bool checked();
|
||||
void setChecked();
|
||||
void setGroup(const group<RadioItem>& group);
|
||||
void setText(string text);
|
||||
|
@ -279,11 +276,11 @@ struct pWidget : public pSizable {
|
|||
|
||||
bool focused();
|
||||
virtual Size minimumSize();
|
||||
void setEnabled(bool enabled);
|
||||
virtual void setEnabled(bool enabled);
|
||||
void setFocused();
|
||||
void setFont(string font);
|
||||
void setGeometry(Geometry geometry);
|
||||
void setVisible(bool visible);
|
||||
virtual void setGeometry(Geometry geometry);
|
||||
virtual void setVisible(bool visible);
|
||||
|
||||
pWidget(Widget& widget) : pSizable(widget), widget(widget) {}
|
||||
void constructor();
|
||||
|
@ -317,7 +314,9 @@ struct pCanvas : public QObject, public pWidget {
|
|||
|
||||
public:
|
||||
Canvas& canvas;
|
||||
QImage* qtImage;
|
||||
QImage* surface = nullptr;
|
||||
unsigned surfaceWidth = 0;
|
||||
unsigned surfaceHeight = 0;
|
||||
struct QtCanvas : public QWidget {
|
||||
pCanvas& self;
|
||||
void dragEnterEvent(QDragEnterEvent*);
|
||||
|
@ -332,13 +331,16 @@ public:
|
|||
QtCanvas* qtCanvas;
|
||||
|
||||
void setDroppable(bool droppable);
|
||||
void setGeometry(Geometry geometry);
|
||||
void setMode(Canvas::Mode mode);
|
||||
void setSize(Size size);
|
||||
void update();
|
||||
|
||||
pCanvas(Canvas& canvas) : pWidget(canvas), canvas(canvas) {}
|
||||
void constructor();
|
||||
void destructor();
|
||||
void orphan();
|
||||
void rasterize();
|
||||
void release();
|
||||
|
||||
public slots:
|
||||
};
|
||||
|
@ -348,14 +350,34 @@ struct pCheckButton : public QObject, public pWidget {
|
|||
|
||||
public:
|
||||
CheckButton& checkButton;
|
||||
QCheckBox* qtCheckButton;
|
||||
QToolButton* qtCheckButton;
|
||||
|
||||
Size minimumSize();
|
||||
void setChecked(bool checked);
|
||||
void setImage(const image& image, Orientation orientation);
|
||||
void setText(string text);
|
||||
|
||||
pCheckButton(CheckButton& checkButton) : pWidget(checkButton), checkButton(checkButton) {}
|
||||
void constructor();
|
||||
void destructor();
|
||||
void orphan();
|
||||
|
||||
public slots:
|
||||
void onToggle(bool checked);
|
||||
};
|
||||
|
||||
struct pCheckLabel : public QObject, public pWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CheckLabel& checkLabel;
|
||||
QCheckBox* qtCheckLabel;
|
||||
|
||||
bool checked();
|
||||
Size minimumSize();
|
||||
void setChecked(bool checked);
|
||||
void setText(string text);
|
||||
|
||||
pCheckButton(CheckButton& checkButton) : pWidget(checkButton), checkButton(checkButton) {}
|
||||
pCheckLabel(CheckLabel& checkLabel) : pWidget(checkLabel), checkLabel(checkLabel) {}
|
||||
void constructor();
|
||||
void destructor();
|
||||
void orphan();
|
||||
|
@ -372,12 +394,12 @@ public:
|
|||
QComboBox* qtComboButton;
|
||||
|
||||
void append(string text);
|
||||
void modify(unsigned row, string text);
|
||||
void remove(unsigned row);
|
||||
Size minimumSize();
|
||||
void remove(unsigned selection);
|
||||
void reset();
|
||||
unsigned selection();
|
||||
void setSelection(unsigned row);
|
||||
void setSelection(unsigned selection);
|
||||
void setText(unsigned selection, string text);
|
||||
|
||||
pComboButton(ComboButton& comboButton) : pWidget(comboButton), comboButton(comboButton) {}
|
||||
void constructor();
|
||||
|
@ -411,6 +433,24 @@ public:
|
|||
void keyPressEvent(QKeyEvent*);
|
||||
};
|
||||
|
||||
struct pFrame : public QObject, public pWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Frame& frame;
|
||||
QGroupBox* qtFrame;
|
||||
|
||||
void setEnabled(bool enabled);
|
||||
void setGeometry(Geometry geometry);
|
||||
void setText(string text);
|
||||
void setVisible(bool visible);
|
||||
|
||||
pFrame(Frame& frame) : pWidget(frame), frame(frame) {}
|
||||
void constructor();
|
||||
void destructor();
|
||||
void orphan();
|
||||
};
|
||||
|
||||
struct pHexEdit : public QObject, public pWidget {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -459,7 +499,6 @@ public:
|
|||
QScrollBar* qtScroller;
|
||||
|
||||
Size minimumSize();
|
||||
unsigned position();
|
||||
void setLength(unsigned length);
|
||||
void setPosition(unsigned position);
|
||||
|
||||
|
@ -480,7 +519,6 @@ public:
|
|||
QSlider* qtSlider;
|
||||
|
||||
Size minimumSize();
|
||||
unsigned position();
|
||||
void setLength(unsigned length);
|
||||
void setPosition(unsigned position);
|
||||
|
||||
|
@ -537,19 +575,16 @@ public:
|
|||
|
||||
void append(const lstring& text);
|
||||
void autoSizeColumns();
|
||||
bool checked(unsigned row);
|
||||
void modify(unsigned row, const lstring& text);
|
||||
void remove(unsigned row);
|
||||
void remove(unsigned selection);
|
||||
void reset();
|
||||
bool selected();
|
||||
unsigned selection();
|
||||
void setCheckable(bool checkable);
|
||||
void setChecked(unsigned row, bool checked);
|
||||
void setChecked(unsigned selection, bool checked);
|
||||
void setHeaderText(const lstring& text);
|
||||
void setHeaderVisible(bool visible);
|
||||
void setImage(unsigned row, unsigned column, const nall::image& image);
|
||||
void setImage(unsigned selection, unsigned position, const image& image);
|
||||
void setSelected(bool selected);
|
||||
void setSelection(unsigned row);
|
||||
void setSelection(unsigned selection);
|
||||
void setText(unsigned selection, unsigned position, string text);
|
||||
|
||||
pListView(ListView& listView) : pWidget(listView), listView(listView) {}
|
||||
void constructor();
|
||||
|
@ -575,17 +610,40 @@ struct pProgressBar : public pWidget {
|
|||
void orphan();
|
||||
};
|
||||
|
||||
struct pRadioLabel : public QObject, public pWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RadioLabel& radioLabel;
|
||||
QRadioButton* qtRadioLabel;
|
||||
|
||||
bool checked();
|
||||
Size minimumSize();
|
||||
void setChecked();
|
||||
void setGroup(const group<RadioLabel>& group);
|
||||
void setText(string text);
|
||||
|
||||
pRadioLabel(RadioLabel& radioLabel) : pWidget(radioLabel), radioLabel(radioLabel) {}
|
||||
pRadioLabel& parent();
|
||||
void constructor();
|
||||
void destructor();
|
||||
void orphan();
|
||||
|
||||
public slots:
|
||||
void onActivate();
|
||||
};
|
||||
|
||||
struct pRadioButton : public QObject, public pWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RadioButton& radioButton;
|
||||
QRadioButton* qtRadioButton;
|
||||
QToolButton* qtRadioButton;
|
||||
|
||||
bool checked();
|
||||
Size minimumSize();
|
||||
void setChecked();
|
||||
void setGroup(const group<RadioButton>& group);
|
||||
void setImage(const image& image, Orientation orientation);
|
||||
void setText(string text);
|
||||
|
||||
pRadioButton(RadioButton& radioButton) : pWidget(radioButton), radioButton(radioButton) {}
|
||||
|
@ -598,6 +656,32 @@ public slots:
|
|||
void onActivate();
|
||||
};
|
||||
|
||||
struct pTabFrame : public QObject, public pWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TabFrame& tabFrame;
|
||||
QTabWidget* qtTabFrame;
|
||||
|
||||
void append(string text, const image& image);
|
||||
void remove(unsigned selection);
|
||||
void setEnabled(bool enabled);
|
||||
void setGeometry(Geometry geometry);
|
||||
void setImage(unsigned selection, const image& image);
|
||||
void setSelection(unsigned selection);
|
||||
void setText(unsigned selection, string text);
|
||||
void setVisible(bool visible);
|
||||
|
||||
pTabFrame(TabFrame& tabFrame) : pWidget(tabFrame), tabFrame(tabFrame) {}
|
||||
void constructor();
|
||||
void destructor();
|
||||
void orphan();
|
||||
void synchronizeLayout();
|
||||
|
||||
public slots:
|
||||
void onChange(int selection);
|
||||
};
|
||||
|
||||
struct pTextEdit : public QObject, public pWidget {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -628,7 +712,6 @@ public:
|
|||
QScrollBar* qtScroller;
|
||||
|
||||
Size minimumSize();
|
||||
unsigned position();
|
||||
void setLength(unsigned length);
|
||||
void setPosition(unsigned position);
|
||||
|
||||
|
@ -649,7 +732,6 @@ public:
|
|||
QSlider* qtSlider;
|
||||
|
||||
Size minimumSize();
|
||||
unsigned position();
|
||||
void setLength(unsigned length);
|
||||
void setPosition(unsigned position);
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ void pTimer::setEnabled(bool enabled) {
|
|||
}
|
||||
}
|
||||
|
||||
void pTimer::setInterval(unsigned milliseconds) {
|
||||
qtTimer->setInterval(milliseconds);
|
||||
void pTimer::setInterval(unsigned interval) {
|
||||
qtTimer->setInterval(interval);
|
||||
}
|
||||
|
||||
void pTimer::constructor() {
|
||||
|
|
|
@ -4,32 +4,48 @@ void pCanvas::setDroppable(bool droppable) {
|
|||
qtCanvas->setAcceptDrops(droppable);
|
||||
}
|
||||
|
||||
void pCanvas::setSize(Size size) {
|
||||
delete qtImage;
|
||||
qtImage = new QImage(size.width, size.height, QImage::Format_ARGB32);
|
||||
void pCanvas::setGeometry(Geometry geometry) {
|
||||
if(canvas.state.width == 0 || canvas.state.height == 0) rasterize();
|
||||
unsigned width = canvas.state.width;
|
||||
unsigned height = canvas.state.height;
|
||||
if(width == 0) width = widget.state.geometry.width;
|
||||
if(height == 0) height = widget.state.geometry.height;
|
||||
|
||||
if(width < geometry.width) {
|
||||
geometry.x += (geometry.width - width) / 2;
|
||||
geometry.width = width;
|
||||
}
|
||||
|
||||
if(height < geometry.height) {
|
||||
geometry.y += (geometry.height - height) / 2;
|
||||
geometry.height = height;
|
||||
}
|
||||
|
||||
pWidget::setGeometry(geometry);
|
||||
}
|
||||
|
||||
void pCanvas::update() {
|
||||
uint32_t* dp = (uint32_t*)qtImage->bits(), *sp = (uint32_t*)canvas.state.data;
|
||||
for(unsigned n = 0; n < canvas.state.width * canvas.state.height; n++) *dp++ = 0xff000000 | *sp++;
|
||||
void pCanvas::setMode(Canvas::Mode mode) {
|
||||
rasterize();
|
||||
qtCanvas->update();
|
||||
}
|
||||
|
||||
void pCanvas::setSize(Size size) {
|
||||
rasterize();
|
||||
qtCanvas->update();
|
||||
}
|
||||
|
||||
void pCanvas::constructor() {
|
||||
qtWidget = qtCanvas = new QtCanvas(*this);
|
||||
qtCanvas->setMouseTracking(true);
|
||||
qtImage = new QImage(canvas.state.width, canvas.state.height, QImage::Format_ARGB32);
|
||||
memcpy(qtImage->bits(), canvas.state.data, canvas.state.width * canvas.state.height * sizeof(uint32_t));
|
||||
|
||||
pWidget::synchronizeState();
|
||||
update();
|
||||
rasterize(), qtCanvas->update();
|
||||
}
|
||||
|
||||
void pCanvas::destructor() {
|
||||
release();
|
||||
delete qtCanvas;
|
||||
delete qtImage;
|
||||
qtWidget = qtCanvas = nullptr;
|
||||
qtImage = nullptr;
|
||||
}
|
||||
|
||||
void pCanvas::orphan() {
|
||||
|
@ -37,6 +53,53 @@ void pCanvas::orphan() {
|
|||
constructor();
|
||||
}
|
||||
|
||||
void pCanvas::rasterize() {
|
||||
unsigned width = canvas.state.width;
|
||||
unsigned height = canvas.state.height;
|
||||
if(width == 0) width = widget.state.geometry.width;
|
||||
if(height == 0) height = widget.state.geometry.height;
|
||||
|
||||
if(canvas.state.mode != Canvas::Mode::Color) {
|
||||
if(width != surfaceWidth || height != surfaceHeight) release();
|
||||
if(!surface) surface = new QImage(width, height, QImage::Format_ARGB32);
|
||||
}
|
||||
|
||||
if(canvas.state.mode == Canvas::Mode::Gradient) {
|
||||
nall::image image;
|
||||
image.allocate(width, height);
|
||||
image.gradient(
|
||||
canvas.state.gradient[0].argb(), canvas.state.gradient[1].argb(), canvas.state.gradient[2].argb(), canvas.state.gradient[3].argb()
|
||||
);
|
||||
memcpy(surface->bits(), image.data, image.size);
|
||||
}
|
||||
|
||||
if(canvas.state.mode == Canvas::Mode::Image) {
|
||||
nall::image image = canvas.state.image;
|
||||
image.scale(width, height);
|
||||
image.transform(0, 32, 255u << 24, 255u << 16, 255u << 8, 255u << 0);
|
||||
memcpy(surface->bits(), image.data, image.size);
|
||||
}
|
||||
|
||||
if(canvas.state.mode == Canvas::Mode::Data) {
|
||||
if(width == canvas.state.width && height == canvas.state.height) {
|
||||
memcpy(surface->bits(), canvas.state.data, width * height * sizeof(uint32_t));
|
||||
} else {
|
||||
memset(surface->bits(), 0x00, width * height * sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
|
||||
surfaceWidth = width;
|
||||
surfaceHeight = height;
|
||||
}
|
||||
|
||||
void pCanvas::release() {
|
||||
if(surface == nullptr) return;
|
||||
delete surface;
|
||||
surface = nullptr;
|
||||
surfaceWidth = 0;
|
||||
surfaceHeight = 0;
|
||||
}
|
||||
|
||||
void pCanvas::QtCanvas::dragEnterEvent(QDragEnterEvent* event) {
|
||||
if(event->mimeData()->hasUrls()) {
|
||||
event->acceptProposedAction();
|
||||
|
@ -76,15 +139,14 @@ void pCanvas::QtCanvas::mouseReleaseEvent(QMouseEvent* event) {
|
|||
}
|
||||
|
||||
void pCanvas::QtCanvas::paintEvent(QPaintEvent* event) {
|
||||
Canvas& canvas = self.canvas;
|
||||
QPainter painter(self.qtCanvas);
|
||||
painter.drawImage(0, 0, *self.qtImage);
|
||||
|
||||
//this will scale the source image to fit the target widget size (nearest-neighbor):
|
||||
//painter.drawImage(
|
||||
// QRect(0, 0, geometry().width(), geometry().height()),
|
||||
// *self.qtImage,
|
||||
// QRect(0, 0, self.canvas.state.width, self.canvas.state.height)
|
||||
//);
|
||||
if(canvas.state.mode == Canvas::Mode::Color) {
|
||||
painter.fillRect(event->rect(), QBrush(QColor(canvas.state.color.red, canvas.state.color.green, canvas.state.color.blue, canvas.state.color.alpha)));
|
||||
} else {
|
||||
painter.drawImage(0, 0, *self.surface);
|
||||
}
|
||||
}
|
||||
|
||||
pCanvas::QtCanvas::QtCanvas(pCanvas& self) : self(self) {
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
namespace phoenix {
|
||||
|
||||
bool pCheckButton::checked() {
|
||||
return qtCheckButton->isChecked();
|
||||
}
|
||||
|
||||
Size pCheckButton::minimumSize() {
|
||||
Size size = pFont::size(qtWidget->font(), checkButton.state.text);
|
||||
return {size.width + 26, size.height + 6};
|
||||
|
||||
if(checkButton.state.orientation == Orientation::Horizontal) {
|
||||
size.width += checkButton.state.image.width;
|
||||
size.height = max(checkButton.state.image.height, size.height);
|
||||
}
|
||||
|
||||
if(checkButton.state.orientation == Orientation::Vertical) {
|
||||
size.width = max(checkButton.state.image.width, size.width);
|
||||
size.height += checkButton.state.image.height;
|
||||
}
|
||||
|
||||
return {size.width + 20, size.height + 12};
|
||||
}
|
||||
|
||||
void pCheckButton::setChecked(bool checked) {
|
||||
|
@ -15,13 +22,25 @@ void pCheckButton::setChecked(bool checked) {
|
|||
locked = false;
|
||||
}
|
||||
|
||||
void pCheckButton::setImage(const image& image, Orientation orientation) {
|
||||
qtCheckButton->setIconSize(QSize(image.width, image.height));
|
||||
qtCheckButton->setIcon(CreateIcon(image));
|
||||
qtCheckButton->setStyleSheet("text-align: top;");
|
||||
switch(orientation) {
|
||||
case Orientation::Horizontal: qtCheckButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); break;
|
||||
case Orientation::Vertical: qtCheckButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); break;
|
||||
}
|
||||
}
|
||||
|
||||
void pCheckButton::setText(string text) {
|
||||
qtCheckButton->setText(QString::fromUtf8(text));
|
||||
}
|
||||
|
||||
void pCheckButton::constructor() {
|
||||
qtWidget = qtCheckButton = new QCheckBox;
|
||||
connect(qtCheckButton, SIGNAL(stateChanged(int)), SLOT(onToggle()));
|
||||
qtWidget = qtCheckButton = new QToolButton;
|
||||
qtCheckButton->setCheckable(true);
|
||||
qtCheckButton->setToolButtonStyle(Qt::ToolButtonTextOnly);
|
||||
connect(qtCheckButton, SIGNAL(toggled(bool)), SLOT(onToggle(bool)));
|
||||
|
||||
pWidget::synchronizeState();
|
||||
setChecked(checkButton.state.checked);
|
||||
|
@ -29,8 +48,6 @@ void pCheckButton::constructor() {
|
|||
}
|
||||
|
||||
void pCheckButton::destructor() {
|
||||
delete qtCheckButton;
|
||||
qtWidget = qtCheckButton = nullptr;
|
||||
}
|
||||
|
||||
void pCheckButton::orphan() {
|
||||
|
@ -38,9 +55,9 @@ void pCheckButton::orphan() {
|
|||
constructor();
|
||||
}
|
||||
|
||||
void pCheckButton::onToggle() {
|
||||
checkButton.state.checked = checked();
|
||||
if(locked == false && checkButton.onToggle) checkButton.onToggle();
|
||||
void pCheckButton::onToggle(bool checked) {
|
||||
checkButton.state.checked = checked;
|
||||
if(!locked && checkButton.onToggle) checkButton.onToggle();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
namespace phoenix {
|
||||
|
||||
Size pCheckLabel::minimumSize() {
|
||||
Size size = pFont::size(qtWidget->font(), checkLabel.state.text);
|
||||
return {size.width + 26, size.height + 6};
|
||||
}
|
||||
|
||||
void pCheckLabel::setChecked(bool checked) {
|
||||
locked = true;
|
||||
qtCheckLabel->setChecked(checked);
|
||||
locked = false;
|
||||
}
|
||||
|
||||
void pCheckLabel::setText(string text) {
|
||||
qtCheckLabel->setText(QString::fromUtf8(text));
|
||||
}
|
||||
|
||||
void pCheckLabel::constructor() {
|
||||
qtWidget = qtCheckLabel = new QCheckBox;
|
||||
connect(qtCheckLabel, SIGNAL(stateChanged(int)), SLOT(onToggle()));
|
||||
|
||||
pWidget::synchronizeState();
|
||||
setChecked(checkLabel.state.checked);
|
||||
setText(checkLabel.state.text);
|
||||
}
|
||||
|
||||
void pCheckLabel::destructor() {
|
||||
delete qtCheckLabel;
|
||||
qtWidget = qtCheckLabel = nullptr;
|
||||
}
|
||||
|
||||
void pCheckLabel::orphan() {
|
||||
destructor();
|
||||
constructor();
|
||||
}
|
||||
|
||||
void pCheckLabel::onToggle() {
|
||||
checkLabel.state.checked = qtCheckLabel->isChecked();
|
||||
if(!locked && checkLabel.onToggle) checkLabel.onToggle();
|
||||
}
|
||||
|
||||
}
|
|
@ -13,16 +13,12 @@ Size pComboButton::minimumSize() {
|
|||
return {maximumWidth + 32, size.height + 12};
|
||||
}
|
||||
|
||||
void pComboButton::modify(unsigned row, string text) {
|
||||
qtComboButton->setItemText(row, text);
|
||||
}
|
||||
|
||||
void pComboButton::remove(unsigned row) {
|
||||
void pComboButton::remove(unsigned selection) {
|
||||
locked = true;
|
||||
unsigned position = selection();
|
||||
qtComboButton->removeItem(row);
|
||||
if(position == row) qtComboButton->setCurrentIndex(0);
|
||||
qtComboButton->removeItem(selection);
|
||||
locked = false;
|
||||
|
||||
if(selection == comboButton.state.selection) comboButton.setSelection(0);
|
||||
}
|
||||
|
||||
void pComboButton::reset() {
|
||||
|
@ -31,15 +27,14 @@ void pComboButton::reset() {
|
|||
locked = false;
|
||||
}
|
||||
|
||||
unsigned pComboButton::selection() {
|
||||
signed index = qtComboButton->currentIndex();
|
||||
return index >= 0 ? index : 0;
|
||||
void pComboButton::setSelection(unsigned selection) {
|
||||
locked = true;
|
||||
qtComboButton->setCurrentIndex(selection);
|
||||
locked = false;
|
||||
}
|
||||
|
||||
void pComboButton::setSelection(unsigned row) {
|
||||
locked = true;
|
||||
qtComboButton->setCurrentIndex(row);
|
||||
locked = false;
|
||||
void pComboButton::setText(unsigned selection, string text) {
|
||||
qtComboButton->setItemText(selection, text);
|
||||
}
|
||||
|
||||
void pComboButton::constructor() {
|
||||
|
@ -51,7 +46,7 @@ void pComboButton::constructor() {
|
|||
locked = true;
|
||||
for(auto& text : comboButton.state.text) append(text);
|
||||
locked = false;
|
||||
setSelection(selection);
|
||||
comboButton.setSelection(selection);
|
||||
}
|
||||
|
||||
void pComboButton::destructor() {
|
||||
|
@ -65,8 +60,8 @@ void pComboButton::orphan() {
|
|||
}
|
||||
|
||||
void pComboButton::onChange() {
|
||||
comboButton.state.selection = selection();
|
||||
if(locked == false && comboButton.onChange) comboButton.onChange();
|
||||
comboButton.state.selection = qtComboButton->currentIndex();
|
||||
if(!locked && comboButton.onChange) comboButton.onChange();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
namespace phoenix {
|
||||
|
||||
void pFrame::setEnabled(bool enabled) {
|
||||
if(frame.state.layout) frame.state.layout->setEnabled(frame.state.layout->enabled());
|
||||
pWidget::setEnabled(enabled);
|
||||
}
|
||||
|
||||
void pFrame::setGeometry(Geometry geometry) {
|
||||
pWidget::setGeometry(geometry);
|
||||
if(frame.state.layout == nullptr) return;
|
||||
Size size = pFont::size(widget.state.font, frame.state.text);
|
||||
if(frame.state.text.empty()) size.height = 8;
|
||||
geometry.x += 1, geometry.width -= 3;
|
||||
geometry.y += size.height, geometry.height -= size.height + 1;
|
||||
frame.state.layout->setGeometry(geometry);
|
||||
}
|
||||
|
||||
void pFrame::setText(string text) {
|
||||
qtFrame->setTitle(QString::fromUtf8(text));
|
||||
}
|
||||
|
||||
void pFrame::setVisible(bool visible) {
|
||||
if(frame.state.layout) frame.state.layout->setVisible(frame.state.layout->visible());
|
||||
pWidget::setVisible(visible);
|
||||
}
|
||||
|
||||
void pFrame::constructor() {
|
||||
qtWidget = qtFrame = new QGroupBox;
|
||||
|
||||
pWidget::synchronizeState();
|
||||
setText(frame.state.text);
|
||||
}
|
||||
|
||||
void pFrame::destructor() {
|
||||
delete qtFrame;
|
||||
qtWidget = qtFrame = nullptr;
|
||||
}
|
||||
|
||||
void pFrame::orphan() {
|
||||
destructor();
|
||||
constructor();
|
||||
}
|
||||
|
||||
}
|
|
@ -4,10 +4,6 @@ Size pHorizontalScroller::minimumSize() {
|
|||
return {0, 15};
|
||||
}
|
||||
|
||||
unsigned pHorizontalScroller::position() {
|
||||
return qtScroller->value();
|
||||
}
|
||||
|
||||
void pHorizontalScroller::setLength(unsigned length) {
|
||||
length += length == 0;
|
||||
qtScroller->setRange(0, length - 1);
|
||||
|
@ -40,7 +36,7 @@ void pHorizontalScroller::orphan() {
|
|||
}
|
||||
|
||||
void pHorizontalScroller::onChange() {
|
||||
horizontalScroller.state.position = position();
|
||||
horizontalScroller.state.position = qtScroller->value();
|
||||
if(horizontalScroller.onChange) horizontalScroller.onChange();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,10 +4,6 @@ Size pHorizontalSlider::minimumSize() {
|
|||
return {0, 20};
|
||||
}
|
||||
|
||||
unsigned pHorizontalSlider::position() {
|
||||
return qtSlider->value();
|
||||
}
|
||||
|
||||
void pHorizontalSlider::setLength(unsigned length) {
|
||||
length += length == 0;
|
||||
qtSlider->setRange(0, length - 1);
|
||||
|
@ -40,7 +36,7 @@ void pHorizontalSlider::orphan() {
|
|||
}
|
||||
|
||||
void pHorizontalSlider::onChange() {
|
||||
horizontalSlider.state.position = position();
|
||||
horizontalSlider.state.position = qtSlider->value();
|
||||
if(horizontalSlider.onChange) horizontalSlider.onChange();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ void pListView::append(const lstring& text) {
|
|||
|
||||
item->setData(0, Qt::UserRole, (unsigned)items.size());
|
||||
if(listView.state.checkable) item->setCheckState(0, Qt::Unchecked);
|
||||
for(unsigned n = 0; n < text.size(); n++) {
|
||||
item->setText(n, QString::fromUtf8(text[n]));
|
||||
for(unsigned position = 0; position < text.size(); position++) {
|
||||
item->setText(position, QString::fromUtf8(text[position]));
|
||||
}
|
||||
locked = false;
|
||||
}
|
||||
|
@ -17,24 +17,9 @@ void pListView::autoSizeColumns() {
|
|||
for(unsigned n = 0; n < listView.state.headerText.size(); n++) qtListView->resizeColumnToContents(n);
|
||||
}
|
||||
|
||||
bool pListView::checked(unsigned row) {
|
||||
QTreeWidgetItem* item = qtListView->topLevelItem(row);
|
||||
return item ? item->checkState(0) == Qt::Checked : false;
|
||||
}
|
||||
|
||||
void pListView::modify(unsigned row, const lstring& text) {
|
||||
void pListView::remove(unsigned selection) {
|
||||
locked = true;
|
||||
QTreeWidgetItem* item = qtListView->topLevelItem(row);
|
||||
if(item == nullptr) return;
|
||||
for(unsigned n = 0; n < text.size(); n++) {
|
||||
item->setText(n, QString::fromUtf8(text[n]));
|
||||
}
|
||||
locked = false;
|
||||
}
|
||||
|
||||
void pListView::remove(unsigned row) {
|
||||
locked = true;
|
||||
QTreeWidgetItem* item = qtListView->topLevelItem(row);
|
||||
QTreeWidgetItem* item = qtListView->topLevelItem(selection);
|
||||
if(item == nullptr) return;
|
||||
delete item;
|
||||
locked = false;
|
||||
|
@ -44,17 +29,6 @@ void pListView::reset() {
|
|||
qtListView->clear();
|
||||
}
|
||||
|
||||
bool pListView::selected() {
|
||||
QTreeWidgetItem* item = qtListView->currentItem();
|
||||
return (item && item->isSelected() == true);
|
||||
}
|
||||
|
||||
unsigned pListView::selection() {
|
||||
QTreeWidgetItem* item = qtListView->currentItem();
|
||||
if(item == 0) return 0;
|
||||
return item->data(0, Qt::UserRole).toUInt();
|
||||
}
|
||||
|
||||
void pListView::setCheckable(bool checkable) {
|
||||
if(checkable) {
|
||||
auto items = qtListView->findItems("", Qt::MatchContains);
|
||||
|
@ -62,9 +36,9 @@ void pListView::setCheckable(bool checkable) {
|
|||
}
|
||||
}
|
||||
|
||||
void pListView::setChecked(unsigned row, bool checked) {
|
||||
void pListView::setChecked(unsigned selection, bool checked) {
|
||||
locked = true;
|
||||
QTreeWidgetItem* item = qtListView->topLevelItem(row);
|
||||
QTreeWidgetItem* item = qtListView->topLevelItem(selection);
|
||||
if(item) item->setCheckState(0, checked ? Qt::Checked : Qt::Unchecked);
|
||||
locked = false;
|
||||
}
|
||||
|
@ -84,11 +58,11 @@ void pListView::setHeaderVisible(bool visible) {
|
|||
autoSizeColumns();
|
||||
}
|
||||
|
||||
void pListView::setImage(unsigned row, unsigned column, const nall::image& image) {
|
||||
QTreeWidgetItem* item = qtListView->topLevelItem(row);
|
||||
void pListView::setImage(unsigned selection, unsigned position, const nall::image& image) {
|
||||
QTreeWidgetItem* item = qtListView->topLevelItem(selection);
|
||||
if(item) {
|
||||
if(image.empty() == 0) item->setIcon(column, CreateIcon(image));
|
||||
if(image.empty() == 1) item->setIcon(column, QIcon());
|
||||
if(image.empty() == 0) item->setIcon(position, CreateIcon(image));
|
||||
if(image.empty() == 1) item->setIcon(position, QIcon());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,18 +71,19 @@ void pListView::setSelected(bool selected) {
|
|||
if(item) item->setSelected(selected);
|
||||
}
|
||||
|
||||
void pListView::setSelection(unsigned row) {
|
||||
void pListView::setSelection(unsigned selection) {
|
||||
locked = true;
|
||||
QTreeWidgetItem* item = qtListView->currentItem();
|
||||
if(item) item->setSelected(false);
|
||||
qtListView->setCurrentItem(0);
|
||||
auto items = qtListView->findItems("", Qt::MatchContains);
|
||||
for(unsigned n = 0; n < items.size(); n++) {
|
||||
if(items[n]->data(0, Qt::UserRole).toUInt() == row) {
|
||||
qtListView->setCurrentItem(items[n]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
item = qtListView->topLevelItem(selection);
|
||||
if(item) qtListView->setCurrentItem(item);
|
||||
locked = false;
|
||||
}
|
||||
|
||||
void pListView::setText(unsigned selection, unsigned position, string text) {
|
||||
locked = true;
|
||||
QTreeWidgetItem* item = qtListView->topLevelItem(selection);
|
||||
if(item) item->setText(position, QString::fromUtf8(text));
|
||||
locked = false;
|
||||
}
|
||||
|
||||
|
@ -151,18 +126,25 @@ void pListView::onActivate() {
|
|||
}
|
||||
|
||||
void pListView::onChange(QTreeWidgetItem* item) {
|
||||
//Qt bug workaround: clicking items with mouse does not mark items as selected
|
||||
if(item) item->setSelected(true);
|
||||
listView.state.selected = selected();
|
||||
if(listView.state.selected) listView.state.selection = selection();
|
||||
if(locked == false && listView.onChange) listView.onChange();
|
||||
bool selected = listView.state.selected;
|
||||
unsigned selection = listView.state.selection;
|
||||
if(item) {
|
||||
item->setSelected(true); //Qt bug workaround: clicking items with mouse does not mark items as selected
|
||||
listView.state.selected = true;
|
||||
listView.state.selection = item->data(0, Qt::UserRole).toUInt();
|
||||
} else {
|
||||
listView.state.selected = false;
|
||||
listView.state.selection = 0;
|
||||
}
|
||||
if(selected != listView.state.selected || selection != listView.state.selection) {
|
||||
if(!locked && listView.onChange) listView.onChange();
|
||||
}
|
||||
}
|
||||
|
||||
void pListView::onToggle(QTreeWidgetItem* item) {
|
||||
unsigned row = item->data(0, Qt::UserRole).toUInt();
|
||||
bool checkState = checked(row);
|
||||
listView.state.checked[row] = checkState;
|
||||
if(locked == false && listView.onToggle) listView.onToggle(row);
|
||||
unsigned selection = item->data(0, Qt::UserRole).toUInt();
|
||||
listView.state.checked[selection] = (item->checkState(0) == Qt::Checked);
|
||||
if(!locked && listView.onToggle) listView.onToggle(selection);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,20 +1,27 @@
|
|||
namespace phoenix {
|
||||
|
||||
bool pRadioButton::checked() {
|
||||
return qtRadioButton->isChecked();
|
||||
}
|
||||
|
||||
Size pRadioButton::minimumSize() {
|
||||
Size size = pFont::size(qtWidget->font(), radioButton.state.text);
|
||||
return {size.width + 26, size.height + 6};
|
||||
|
||||
if(radioButton.state.orientation == Orientation::Horizontal) {
|
||||
size.width += radioButton.state.image.width;
|
||||
size.height = max(radioButton.state.image.height, size.height);
|
||||
}
|
||||
|
||||
if(radioButton.state.orientation == Orientation::Vertical) {
|
||||
size.width = max(radioButton.state.image.width, size.width);
|
||||
size.height += radioButton.state.image.height;
|
||||
}
|
||||
|
||||
return {size.width + 20, size.height + 12};
|
||||
}
|
||||
|
||||
void pRadioButton::setChecked() {
|
||||
parent().locked = true;
|
||||
for(auto &item : radioButton.state.group) {
|
||||
item.p.qtRadioButton->setChecked(item.state.checked = false);
|
||||
for(auto& item : radioButton.state.group) {
|
||||
bool checked = &item.p == this;
|
||||
item.p.qtRadioButton->setChecked(item.state.checked = checked);
|
||||
}
|
||||
qtRadioButton->setChecked(radioButton.state.checked = true);
|
||||
parent().locked = false;
|
||||
}
|
||||
|
||||
|
@ -26,6 +33,16 @@ void pRadioButton::setGroup(const group<RadioButton>& group) {
|
|||
parent().locked = false;
|
||||
}
|
||||
|
||||
void pRadioButton::setImage(const image& image, Orientation orientation) {
|
||||
qtRadioButton->setIconSize(QSize(image.width, image.height));
|
||||
qtRadioButton->setIcon(CreateIcon(image));
|
||||
qtRadioButton->setStyleSheet("text-align: top;");
|
||||
switch(orientation) {
|
||||
case Orientation::Horizontal: qtRadioButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); break;
|
||||
case Orientation::Vertical: qtRadioButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); break;
|
||||
}
|
||||
}
|
||||
|
||||
void pRadioButton::setText(string text) {
|
||||
qtRadioButton->setText(QString::fromUtf8(text));
|
||||
}
|
||||
|
@ -36,8 +53,9 @@ pRadioButton& pRadioButton::parent() {
|
|||
}
|
||||
|
||||
void pRadioButton::constructor() {
|
||||
qtWidget = qtRadioButton = new QRadioButton;
|
||||
qtRadioButton->setAutoExclusive(false);
|
||||
qtWidget = qtRadioButton = new QToolButton;
|
||||
qtRadioButton->setCheckable(true);
|
||||
qtRadioButton->setToolButtonStyle(Qt::ToolButtonTextOnly);
|
||||
connect(qtRadioButton, SIGNAL(toggled(bool)), SLOT(onActivate()));
|
||||
|
||||
pWidget::synchronizeState();
|
||||
|
@ -56,12 +74,11 @@ void pRadioButton::orphan() {
|
|||
}
|
||||
|
||||
void pRadioButton::onActivate() {
|
||||
if(parent().locked == false) {
|
||||
bool wasChecked = radioButton.state.checked;
|
||||
setChecked();
|
||||
if(wasChecked == false) {
|
||||
if(radioButton.onActivate) radioButton.onActivate();
|
||||
}
|
||||
if(parent().locked) return;
|
||||
bool wasChecked = radioButton.state.checked;
|
||||
setChecked();
|
||||
if(!wasChecked) {
|
||||
if(radioButton.onActivate) radioButton.onActivate();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
namespace phoenix {
|
||||
|
||||
Size pRadioLabel::minimumSize() {
|
||||
Size size = pFont::size(qtWidget->font(), radioLabel.state.text);
|
||||
return {size.width + 26, size.height + 6};
|
||||
}
|
||||
|
||||
void pRadioLabel::setChecked() {
|
||||
parent().locked = true;
|
||||
for(auto& item : radioLabel.state.group) {
|
||||
bool checked = &item == &radioLabel;
|
||||
item.p.qtRadioLabel->setChecked(item.state.checked = checked);
|
||||
}
|
||||
parent().locked = false;
|
||||
}
|
||||
|
||||
void pRadioLabel::setGroup(const group<RadioLabel>& group) {
|
||||
parent().locked = true;
|
||||
for(auto& item : radioLabel.state.group) {
|
||||
item.p.qtRadioLabel->setChecked(item.state.checked);
|
||||
}
|
||||
parent().locked = false;
|
||||
}
|
||||
|
||||
void pRadioLabel::setText(string text) {
|
||||
qtRadioLabel->setText(QString::fromUtf8(text));
|
||||
}
|
||||
|
||||
pRadioLabel& pRadioLabel::parent() {
|
||||
if(radioLabel.state.group.size()) return radioLabel.state.group.first().p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void pRadioLabel::constructor() {
|
||||
qtWidget = qtRadioLabel = new QRadioButton;
|
||||
qtRadioLabel->setAutoExclusive(false);
|
||||
connect(qtRadioLabel, SIGNAL(toggled(bool)), SLOT(onActivate()));
|
||||
|
||||
pWidget::synchronizeState();
|
||||
setGroup(radioLabel.state.group);
|
||||
setText(radioLabel.state.text);
|
||||
}
|
||||
|
||||
void pRadioLabel::destructor() {
|
||||
if(qtRadioLabel) delete qtRadioLabel;
|
||||
qtWidget = qtRadioLabel = nullptr;
|
||||
}
|
||||
|
||||
void pRadioLabel::orphan() {
|
||||
destructor();
|
||||
constructor();
|
||||
}
|
||||
|
||||
void pRadioLabel::onActivate() {
|
||||
if(parent().locked) return;
|
||||
bool wasChecked = radioLabel.state.checked;
|
||||
setChecked();
|
||||
if(!wasChecked) {
|
||||
if(radioLabel.onActivate) radioLabel.onActivate();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
namespace phoenix {
|
||||
|
||||
void pTabFrame::append(string text, const image& image) {
|
||||
unsigned selection = tabFrame.state.text.size() - 1;
|
||||
QWidget* widget = new QWidget; //addTab() requires a child widget, so give it an empty one
|
||||
qtTabFrame->addTab(widget, QString::fromUtf8(text));
|
||||
if(!image.empty()) setImage(selection, image);
|
||||
}
|
||||
|
||||
void pTabFrame::remove(unsigned selection) {
|
||||
qtTabFrame->removeTab(selection);
|
||||
}
|
||||
|
||||
void pTabFrame::setEnabled(bool enabled) {
|
||||
for(auto& layout : tabFrame.state.layout) {
|
||||
if(layout) layout->setEnabled(layout->enabled());
|
||||
}
|
||||
pWidget::setEnabled(enabled);
|
||||
}
|
||||
|
||||
void pTabFrame::setGeometry(Geometry geometry) {
|
||||
pWidget::setGeometry(geometry);
|
||||
geometry.x += 1, geometry.width -= 2;
|
||||
geometry.y += 29, geometry.height -= 30;
|
||||
for(auto& layout : tabFrame.state.layout) {
|
||||
if(layout == nullptr) continue;
|
||||
layout->setGeometry(geometry);
|
||||
}
|
||||
synchronizeLayout();
|
||||
}
|
||||
|
||||
void pTabFrame::setImage(unsigned selection, const image& image) {
|
||||
qtTabFrame->setTabIcon(selection, CreateIcon(image));
|
||||
}
|
||||
|
||||
void pTabFrame::setSelection(unsigned selection) {
|
||||
qtTabFrame->setCurrentIndex(selection);
|
||||
synchronizeLayout();
|
||||
}
|
||||
|
||||
void pTabFrame::setText(unsigned selection, string text) {
|
||||
qtTabFrame->setTabText(selection, QString::fromUtf8(text));
|
||||
}
|
||||
|
||||
void pTabFrame::setVisible(bool visible) {
|
||||
for(auto& layout : tabFrame.state.layout) {
|
||||
if(layout) layout->setVisible(layout->visible());
|
||||
}
|
||||
pWidget::setVisible(visible);
|
||||
}
|
||||
|
||||
void pTabFrame::constructor() {
|
||||
qtWidget = qtTabFrame = new QTabWidget;
|
||||
connect(qtTabFrame, SIGNAL(currentChanged(int)), SLOT(onChange(int)));
|
||||
|
||||
setSelection(tabFrame.state.selection);
|
||||
}
|
||||
|
||||
void pTabFrame::destructor() {
|
||||
delete qtTabFrame;
|
||||
qtWidget = qtTabFrame = nullptr;
|
||||
}
|
||||
|
||||
void pTabFrame::orphan() {
|
||||
destructor();
|
||||
constructor();
|
||||
}
|
||||
|
||||
void pTabFrame::synchronizeLayout() {
|
||||
unsigned selection = 0;
|
||||
for(auto& layout : tabFrame.state.layout) {
|
||||
if(layout) layout->setVisible(selection == tabFrame.state.selection);
|
||||
selection++;
|
||||
}
|
||||
}
|
||||
|
||||
void pTabFrame::onChange(int selection) {
|
||||
tabFrame.state.selection = selection;
|
||||
synchronizeLayout();
|
||||
if(tabFrame.onChange) tabFrame.onChange();
|
||||
}
|
||||
|
||||
}
|
|
@ -4,10 +4,6 @@ Size pVerticalScroller::minimumSize() {
|
|||
return {15, 0};
|
||||
}
|
||||
|
||||
unsigned pVerticalScroller::position() {
|
||||
return qtScroller->value();
|
||||
}
|
||||
|
||||
void pVerticalScroller::setLength(unsigned length) {
|
||||
length += length == 0;
|
||||
qtScroller->setRange(0, length - 1);
|
||||
|
@ -40,7 +36,7 @@ void pVerticalScroller::orphan() {
|
|||
}
|
||||
|
||||
void pVerticalScroller::onChange() {
|
||||
verticalScroller.state.position = position();
|
||||
verticalScroller.state.position = qtScroller->value();
|
||||
if(verticalScroller.onChange) verticalScroller.onChange();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,10 +4,6 @@ Size pVerticalSlider::minimumSize() {
|
|||
return {20, 0};
|
||||
}
|
||||
|
||||
unsigned pVerticalSlider::position() {
|
||||
return qtSlider->value();
|
||||
}
|
||||
|
||||
void pVerticalSlider::setLength(unsigned length) {
|
||||
length += length == 0;
|
||||
qtSlider->setRange(0, length - 1);
|
||||
|
@ -40,7 +36,7 @@ void pVerticalSlider::orphan() {
|
|||
}
|
||||
|
||||
void pVerticalSlider::onChange() {
|
||||
verticalSlider.state.position = position();
|
||||
verticalSlider.state.position = qtSlider->value();
|
||||
if(verticalSlider.onChange) verticalSlider.onChange();
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue