Compare commits
2 Commits
df4ead9f85
...
8e88adf1df
| Author | SHA1 | Date | |
|---|---|---|---|
| 8e88adf1df | |||
| 3a52a3991c |
1
Makefile
1
Makefile
@ -3,6 +3,7 @@ src_files += sdl_helpers.cpp
|
||||
|
||||
src_files += Widgets/Widget.cpp
|
||||
src_files += Widgets/WidgetText.cpp
|
||||
src_files += Widgets/WidgetRect.cpp
|
||||
|
||||
all:
|
||||
g++ $(src_files) -Wall -lSDL2 -lSDL2_ttf -lSDL2_image -o trmnl_sdl
|
||||
|
||||
@ -4,6 +4,10 @@ Widget::Widget(int x, int y, int width, int height)
|
||||
: m_surface(nullptr), m_rect{.x = x, .y = y, .w = width, .h = height}
|
||||
{
|
||||
m_surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, SDL_PIXELFORMAT_RGBA8888);
|
||||
if (nullptr != m_surface)
|
||||
{
|
||||
SDL_SetSurfaceBlendMode(m_surface, SDL_BLENDMODE_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
Widget::~Widget()
|
||||
@ -39,4 +43,9 @@ void Widget::resize(int width, int height)
|
||||
m_surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, SDL_PIXELFORMAT_RGBA8888);
|
||||
m_rect.w = width;
|
||||
m_rect.h = height;
|
||||
|
||||
if (nullptr != m_surface)
|
||||
{
|
||||
SDL_SetSurfaceBlendMode(m_surface, SDL_BLENDMODE_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define WIDGET_H_
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include "../json.hpp"
|
||||
|
||||
class Widget
|
||||
{
|
||||
|
||||
204
Widgets/WidgetRect.cpp
Normal file
204
Widgets/WidgetRect.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
#include "WidgetRect.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "../sdl_helpers.h"
|
||||
|
||||
using std::vector;
|
||||
|
||||
WidgetRect::WidgetRect(int x, int y, int width, int height,
|
||||
int radius, int stroke_size, SDL_Color color)
|
||||
: Widget(x, y, width, height),
|
||||
m_color(color),
|
||||
m_stroke_size(stroke_size),
|
||||
m_radius(radius)
|
||||
{
|
||||
}
|
||||
|
||||
WidgetRect::WidgetRect(int x, int y, int width, int height,
|
||||
int radius, int stroke_size)
|
||||
: Widget(x, y, width, height),
|
||||
m_color{.r = 0, .g = 0, .b = 0, .a = SDL_ALPHA_OPAQUE},
|
||||
m_stroke_size(stroke_size),
|
||||
m_radius(radius)
|
||||
{
|
||||
}
|
||||
|
||||
void WidgetRect::draw()
|
||||
{
|
||||
// Clear surface
|
||||
SDL_FillRect(m_surface, nullptr, SDL_MapRGBA(m_surface->format, 255, 255, 255, SDL_ALPHA_TRANSPARENT));
|
||||
|
||||
if (m_radius > 0)
|
||||
{
|
||||
// Draw rounded corners here
|
||||
draw_circle_corner(m_rect.w - m_radius, m_radius - 1, 1);
|
||||
draw_circle_corner(m_radius - 1, m_radius - 1, 2);
|
||||
draw_circle_corner(m_radius - 1, m_rect.h - m_radius, 3);
|
||||
draw_circle_corner(m_rect.w - m_radius, m_rect.h - m_radius, 4);
|
||||
|
||||
// Draw X rect
|
||||
if (m_radius * 2 < m_rect.w)
|
||||
{
|
||||
SDL_Rect rect;
|
||||
rect.x = 0;
|
||||
rect.y = m_radius;
|
||||
rect.w = m_rect.w;
|
||||
rect.h = m_rect.h - 2 * m_radius;
|
||||
SDL_FillRect(m_surface, &rect, SDL_MapRGBA(m_surface->format, m_color.r, m_color.g, m_color.b, m_color.a));
|
||||
|
||||
if (m_stroke_size > 0)
|
||||
{
|
||||
rect.x = m_stroke_size;
|
||||
rect.y = m_radius;
|
||||
rect.w = m_rect.w - 2 * m_stroke_size;
|
||||
rect.h = m_rect.h - 2 * m_radius;
|
||||
SDL_FillRect(m_surface, &rect, SDL_MapRGBA(m_surface->format, 255, 255, 255, SDL_ALPHA_TRANSPARENT));
|
||||
}
|
||||
}
|
||||
|
||||
// Draw Y rect
|
||||
if (m_radius * 2 < m_rect.h)
|
||||
{
|
||||
SDL_Rect rect;
|
||||
rect.x = m_radius;
|
||||
rect.y = 0;
|
||||
rect.w = m_rect.w - 2 * m_radius;
|
||||
rect.h = m_rect.h;
|
||||
SDL_FillRect(m_surface, &rect, SDL_MapRGBA(m_surface->format, m_color.r, m_color.g, m_color.b, m_color.a));
|
||||
|
||||
if (m_stroke_size > 0)
|
||||
{
|
||||
rect.x = m_radius;
|
||||
rect.y = m_stroke_size;
|
||||
rect.w = m_rect.w - 2 * m_radius;
|
||||
rect.h = m_rect.h - 2 * m_stroke_size;
|
||||
SDL_FillRect(m_surface, &rect, SDL_MapRGBA(m_surface->format, 255, 255, 255, SDL_ALPHA_TRANSPARENT));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_Rect rect;
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.w = m_rect.w;
|
||||
rect.h = m_rect.h;
|
||||
SDL_FillRect(m_surface, &rect, SDL_MapRGBA(m_surface->format, m_color.r, m_color.g, m_color.b, m_color.a));
|
||||
|
||||
if (m_stroke_size > 0)
|
||||
{
|
||||
rect.x = m_stroke_size;
|
||||
rect.y = m_stroke_size;
|
||||
rect.w = m_rect.w - 2 * m_stroke_size;
|
||||
rect.h = m_rect.h - 2 * m_stroke_size;
|
||||
SDL_FillRect(m_surface, &rect, SDL_MapRGBA(m_surface->format, 255, 255, 255, SDL_ALPHA_TRANSPARENT));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Widget* WidgetRect::builder(const nlohmann::json& j)
|
||||
{
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
int radius = 0;
|
||||
int stroke_size = -1;
|
||||
SDL_Color color = {.r = 0, .g = 0, .b = 0, .a = SDL_ALPHA_OPAQUE};
|
||||
|
||||
json_extract(j, "x", x);
|
||||
json_extract(j, "y", y);
|
||||
json_extract(j, "width", width);
|
||||
json_extract(j, "height", height);
|
||||
json_extract(j, "radius", radius);
|
||||
json_extract(j, "stroke", stroke_size);
|
||||
json_extract(j, "color", color);
|
||||
|
||||
return new WidgetRect(x, y, width, height, radius, stroke_size, color);
|
||||
}
|
||||
|
||||
void WidgetRect::draw_circle_corner(int x, int y, int quadrant)
|
||||
{
|
||||
if (0 == m_radius)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int x_add;
|
||||
int y_add;
|
||||
|
||||
switch (quadrant)
|
||||
{
|
||||
case 1:
|
||||
x_add = 1;
|
||||
y_add = -1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
x_add = -1;
|
||||
y_add = -1;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
x_add = -1;
|
||||
y_add = 1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
x_add = 1;
|
||||
y_add = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
// TODO: Message printing
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
// Create renderer
|
||||
SDL_Renderer* renderer = SDL_CreateSoftwareRenderer(m_surface);
|
||||
if (nullptr == renderer)
|
||||
{
|
||||
// TODO: Message printing
|
||||
return;
|
||||
}
|
||||
SDL_SetRenderDrawColor(renderer, m_color.r, m_color.g, m_color.b, m_color.a);
|
||||
|
||||
vector<SDL_Point> points;
|
||||
|
||||
int max_dist = m_radius * m_radius;
|
||||
int min_dist = 0;
|
||||
if (m_stroke_size > 0)
|
||||
{
|
||||
min_dist = (m_radius - m_stroke_size) * (m_radius - m_stroke_size);
|
||||
}
|
||||
|
||||
for (int i_x = 0; i_x < m_radius; ++i_x)
|
||||
for (int i_y = 0; i_y < m_radius; ++i_y)
|
||||
{
|
||||
bool should_fill = false;
|
||||
|
||||
// a2 + b2 = c2
|
||||
int dist = i_x * i_x + i_y * i_y;
|
||||
|
||||
// <= c2 (max) && > c2 (min)
|
||||
if ((dist <= max_dist) && (dist >= min_dist))
|
||||
{
|
||||
should_fill = true;
|
||||
}
|
||||
|
||||
if (should_fill)
|
||||
{
|
||||
SDL_Point point =
|
||||
{
|
||||
.x = x + x_add * i_x,
|
||||
.y = y + y_add * i_y
|
||||
};
|
||||
|
||||
points.push_back(point);
|
||||
}
|
||||
}
|
||||
SDL_RenderDrawPoints(renderer, points.data(), points.size());
|
||||
SDL_DestroyRenderer(renderer);
|
||||
}
|
||||
39
Widgets/WidgetRect.h
Normal file
39
Widgets/WidgetRect.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef WIDGET_RECT_H_
|
||||
#define WIDGET_RECT_H_
|
||||
|
||||
#include "Widget.h"
|
||||
|
||||
class WidgetRect : public Widget
|
||||
{
|
||||
protected:
|
||||
// The color of the rectangle
|
||||
// Default - Black (0, 0, 0)
|
||||
SDL_Color m_color;
|
||||
|
||||
// Size of the internal stroke
|
||||
// Set to -1 to fill the space
|
||||
// Default - -1
|
||||
int m_stroke_size;
|
||||
|
||||
// Corner rounding radius
|
||||
// Default - 0;
|
||||
int m_radius;
|
||||
|
||||
public:
|
||||
WidgetRect(int x, int y, int width, int height,
|
||||
int radius, int stroke_size, SDL_Color color);
|
||||
|
||||
WidgetRect(int x, int y, int width, int height,
|
||||
int radius = 0, int stroke_size = -1);
|
||||
|
||||
virtual void draw() override;
|
||||
|
||||
static Widget* builder(const nlohmann::json& j);
|
||||
|
||||
private:
|
||||
// x, y - center of circle
|
||||
// quadrant - 1--4
|
||||
void draw_circle_corner(int x, int y, int quadrant);
|
||||
};
|
||||
|
||||
#endif // WIDGET_RECT_H_
|
||||
@ -30,10 +30,6 @@ m_halign(halign),
|
||||
m_valign(valign),
|
||||
m_text_color(text_color)
|
||||
{
|
||||
if (nullptr != m_surface)
|
||||
{
|
||||
SDL_SetSurfaceBlendMode(m_surface, SDL_BLENDMODE_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
WidgetText::WidgetText(int x, int y, int width, int height, string text,
|
||||
@ -49,10 +45,6 @@ m_halign(HALIGN_CENTER),
|
||||
m_valign(VALIGN_CENTER),
|
||||
m_text_color{.r = 0, .g = 0, .b = 0, .a = SDL_ALPHA_OPAQUE}
|
||||
{
|
||||
if (nullptr != m_surface)
|
||||
{
|
||||
SDL_SetSurfaceBlendMode(m_surface, SDL_BLENDMODE_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
WidgetText::WidgetText(int x, int y, int width, int height, string text,
|
||||
@ -66,10 +58,6 @@ m_halign(HALIGN_CENTER),
|
||||
m_valign(VALIGN_CENTER),
|
||||
m_text_color{.r = 0, .g = 0, .b = 0, .a = SDL_ALPHA_OPAQUE}
|
||||
{
|
||||
if (nullptr != m_surface)
|
||||
{
|
||||
SDL_SetSurfaceBlendMode(m_surface, SDL_BLENDMODE_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
void WidgetText::set_text(const string& text)
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
#include <string>
|
||||
|
||||
#include "../sdl_helpers.h"
|
||||
#include "../json.hpp"
|
||||
|
||||
class WidgetText : public Widget
|
||||
{
|
||||
|
||||
2
main.cpp
2
main.cpp
@ -12,6 +12,7 @@
|
||||
#include "sdl_helpers.h"
|
||||
#include "Widgets/Widget.h"
|
||||
#include "Widgets/WidgetText.h"
|
||||
#include "Widgets/WidgetRect.h"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
@ -23,6 +24,7 @@ using nlohmann::json;
|
||||
void init_builders(map<string, Widget*(*)(const json&)>& widget_builders)
|
||||
{
|
||||
widget_builders["text"] = &WidgetText::builder;
|
||||
widget_builders["rect"] = &WidgetRect::builder;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user