118 lines
4.5 KiB
C++
118 lines
4.5 KiB
C++
#include <string>
|
|
|
|
using namespace std;
|
|
|
|
#include <SDL3/SDL.h>
|
|
#include <SDL3_ttf/SDL_ttf.h>
|
|
|
|
#include "../SDLHelpers.h"
|
|
|
|
#include "Checkbox.h"
|
|
|
|
bool isBetween(float a, float b, float c) {
|
|
return a >= b && a < c;
|
|
}
|
|
|
|
Checkbox::Checkbox(string text, SDL_Color color, SDL_Rect pos) : Button(text, color, pos) {
|
|
//SDL_Color color;
|
|
//Button::Button(text, color, pos);
|
|
toggle_selected = true;
|
|
// Parent Button doesn't seem to call this but it's own drawButton. So doing it again for here. FIXME how to fix?
|
|
SDL_DestroySurface(button_up);
|
|
SDL_DestroySurface(button_down);
|
|
drawButton();
|
|
selectSurface();
|
|
}
|
|
|
|
Checkbox::~Checkbox() {
|
|
}
|
|
|
|
void Checkbox::drawButton() {
|
|
SDL_Color color_reflection = color;
|
|
SDL_Color color_shadow = color;
|
|
color_reflection.r = (int) color_reflection.r + 50 < 255 ? color_reflection.r + 50 : 255;
|
|
color_reflection.g = (int) color_reflection.g + 50 < 255 ? color_reflection.g + 50 : 255;
|
|
color_reflection.b = (int) color_reflection.b + 50 < 255 ? color_reflection.b + 50 : 255;
|
|
color_shadow.r = (int) color_shadow.r - 50 > 0 ? color_shadow.r - 50 : 0;
|
|
color_shadow.g = (int) color_shadow.g - 50 > 0 ? color_shadow.g - 50 : 0;
|
|
color_shadow.b = (int) color_shadow.b - 50 > 0 ? color_shadow.b - 50 : 0;
|
|
|
|
int w = getPos()->w;
|
|
int h = getPos()->h;
|
|
button_up = SDL_CreateSurface(w, h, SDL_GetPixelFormatForMasks(32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000));
|
|
button_down = SDL_CreateSurface(w, h, SDL_GetPixelFormatForMasks(32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000));
|
|
Uint32 *p_up = (Uint32 *) button_up->pixels;
|
|
Uint32 *p_down = (Uint32 *) button_down->pixels;
|
|
SDL_Color color_up;
|
|
SDL_Color color_down;
|
|
for (int y = 0; y < h; y++) {
|
|
for (int x = 0; x < w; x++) { // checkbox needs to be square so using height
|
|
float u = h / 12.0; // one unit (was 1 pixel in example image)
|
|
color_up.a = 0xff;
|
|
color_down.a = 0xff;
|
|
if (x > h) {
|
|
color_up.a = 0;
|
|
color_down.a = 0;
|
|
} else if (isBetween(y, h - u, h) || isBetween(x, h - u, h)) { // reflection
|
|
color_up.r = 0xd4;
|
|
color_up.g = 0xd0;
|
|
color_up.b = 0xc8;
|
|
color_down = color_up;
|
|
} else if (isBetween(y, 0, u) || isBetween(x, 0, u)) { // lighter shadow
|
|
color_up.r = 0x80;
|
|
color_up.g = 0x80;
|
|
color_up.b = 0x80;
|
|
color_down = color_up;
|
|
} else if (isBetween(y, u, u * 2) || isBetween(x, u, u * 2)) { // darker shadow
|
|
color_up.r = 0x40;
|
|
color_up.g = 0x40;
|
|
color_up.b = 0x40;
|
|
color_down = color_up;
|
|
} else {
|
|
color_up.r = 255;
|
|
color_up.g = 255;
|
|
color_up.b = 255;
|
|
color_down = color_up;
|
|
bool x_cond = isBetween(x, u * 3, 10 * u);
|
|
bool y_cond = isBetween(y, x + u * 1.5, x + u * 4.5);
|
|
float x_change_limit = 5.5 * u;
|
|
if (x >= x_change_limit) {
|
|
unsigned remaining_x = (x - x_change_limit);
|
|
y_cond = isBetween(y, u * 7 - remaining_x, u * 10 - remaining_x);
|
|
}
|
|
if (x_cond && y_cond) {
|
|
color_down.r = 0;
|
|
color_down.g = 0;
|
|
color_down.b = 0;
|
|
}
|
|
}
|
|
*p_up = SDL_MapRGBA(SDL_GetPixelFormatDetails(button_up->format), NULL, color_up.r, color_up.g, color_up.b, color_up.a);
|
|
*p_down = SDL_MapRGBA(SDL_GetPixelFormatDetails(button_down->format), NULL, color_down.r, color_down.g, color_down.b, color_down.a);
|
|
p_up++;
|
|
p_down++;
|
|
}
|
|
}
|
|
|
|
SDL_Color text_color = {0, 0, 0};
|
|
vector<string> fonts;
|
|
fonts.push_back("DejaVuSans.ttf");
|
|
fonts.push_back("ariblk.ttf");
|
|
fonts.push_back("FreeSans.ttf");
|
|
fonts.push_back("arial.ttf");
|
|
TTF_Font *font = openFont(fonts, 10);
|
|
SDL_Surface *text_surface;
|
|
if (!font) {
|
|
SDL_Log("TTF_OpenFont is broken!");
|
|
}
|
|
if(!(text_surface = TTF_RenderText_Blended(font, text.c_str(), text.length(), text_color))) {
|
|
SDL_Log("RenderText failed %s", SDL_GetError());
|
|
}
|
|
SDL_Rect pos;
|
|
pos.x = button_up->h + 8;
|
|
pos.y = button_up->h / 2 - text_surface->h / 2;
|
|
SDL_BlitSurface(text_surface, NULL, button_up, &pos);
|
|
SDL_BlitSurface(text_surface, NULL, button_down, &pos);
|
|
SDL_DestroySurface(text_surface);
|
|
TTF_CloseFont(font);
|
|
}
|