summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-12-31 16:35:40 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-12-31 16:35:40 -0500
commit3f22228a220d065af3f99ba6a538ff80517ecaa2 (patch)
tree918e0254e63eb63ad9311491022ee55be2f312ac
parente26bc35d04c136a142da37a87f6ba47940399879 (diff)
configurable colors
-rw-r--r--buffer.c16
-rw-r--r--colors.c36
-rw-r--r--config.c19
-rw-r--r--main.c14
-rw-r--r--math.c7
-rw-r--r--ted-base.c5
-rw-r--r--ted.cfg7
7 files changed, 80 insertions, 24 deletions
diff --git a/buffer.c b/buffer.c
index 1c41f92..7d4827d 100644
--- a/buffer.c
+++ b/buffer.c
@@ -23,6 +23,7 @@ typedef struct BufferEdit {
typedef struct {
char const *filename;
+ Settings *settings;
double scroll_x, scroll_y; // number of characters scrolled in the x/y direction
Font *font;
BufferPos cursor_pos;
@@ -40,11 +41,12 @@ typedef struct {
} TextBuffer;
-void buffer_create(TextBuffer *buffer, Font *font) {
+void buffer_create(TextBuffer *buffer, Font *font, Settings *settings) {
util_zero_memory(buffer, sizeof *buffer);
buffer->font = font;
buffer->tab_width = 4;
buffer->store_undo_events = true;
+ buffer->settings = settings;
}
// this is a macro so we get -Wformat warnings
@@ -1583,13 +1585,15 @@ void buffer_render(TextBuffer *buffer, float x1, float y1, float x2, float y2) {
float char_width = text_font_char_width(font),
char_height = text_font_char_height(font);
float header_height = char_height;
+ Settings *settings = buffer->settings;
+ u32 *colors = settings->colors;
// get screen coordinates of cursor
v2 cursor_display_pos = buffer_pos_to_pixels(buffer, buffer->cursor_pos);
// the rectangle that the cursor is rendered as
Rect cursor_rect = rect(cursor_display_pos, V2(1.0f, char_height)); // @SETTINGS: cursor width
- u32 border_color = 0x7f7f7fff; // color of border around buffer
+ u32 border_color = colors[COLOR_BORDER]; // color of border around buffer
// bounding box around buffer & header
gl_color_rgba(border_color);
@@ -1637,7 +1641,7 @@ void buffer_render(TextBuffer *buffer, float x1, float y1, float x2, float y2) {
// highlight line cursor is on
{
- gl_color1f(0.15f); // @SETTINGS
+ gl_color_rgba(colors[COLOR_CURSOR_LINE_BG]);
glBegin(GL_QUADS);
Rect hl_rect = rect(V2(x1, cursor_display_pos.y), V2(x2-x1-1, char_height));
buffer_clip_rect(buffer, &hl_rect);
@@ -1655,7 +1659,7 @@ void buffer_render(TextBuffer *buffer, float x1, float y1, float x2, float y2) {
if (buffer->selection) { // draw selection
glBegin(GL_QUADS);
- gl_color_rgba(0x3366aa88); // @SETTINGS
+ gl_color_rgba(colors[COLOR_SELECTION_BG]);
BufferPos sel_start = {0}, sel_end = {0};
int cmp = buffer_pos_cmp(buffer->cursor_pos, buffer->selection_pos);
if (cmp < 0) {
@@ -1699,7 +1703,6 @@ void buffer_render(TextBuffer *buffer, float x1, float y1, float x2, float y2) {
text_chars_begin(font);
- glColor3f(1,1,1);
text_state = (TextRenderState){
.x = render_start_x, .y = y1 + text_font_char_height(font),
@@ -1709,6 +1712,7 @@ void buffer_render(TextBuffer *buffer, float x1, float y1, float x2, float y2) {
text_state.y -= (float)(buffer->scroll_y - start_line) * char_height;
+ gl_color_rgba(colors[COLOR_TEXT]);
for (u32 line_idx = start_line; line_idx < nlines; ++line_idx) {
Line *line = &lines[line_idx];
@@ -1747,7 +1751,7 @@ void buffer_render(TextBuffer *buffer, float x1, float y1, float x2, float y2) {
{ // render cursor
if (buffer_clip_rect(buffer, &cursor_rect)) {
- glColor3f(0,1,1);
+ gl_color_rgba(colors[COLOR_CURSOR]);
glBegin(GL_QUADS);
rect_render(cursor_rect);
glEnd();
diff --git a/colors.c b/colors.c
index d3952c3..297e6d2 100644
--- a/colors.c
+++ b/colors.c
@@ -7,7 +7,6 @@ ENUM_U16 {
COLOR_BORDER,
COLOR_TEXT,
COLOR_SELECTION_BG,
- COLOR_SELECTION_TEXT,
COLOR_COUNT
} ENUM_U16_END(ColorSetting);
@@ -24,8 +23,7 @@ static ColorName const color_names[COLOR_COUNT] = {
{COLOR_CURSOR_LINE_BG, "cursor-line-bg"},
{COLOR_BORDER, "border"},
{COLOR_TEXT, "text"},
- {COLOR_SELECTION_BG, "selection-bg"},
- {COLOR_SELECTION_TEXT, "selection-text"}
+ {COLOR_SELECTION_BG, "selection-bg"}
};
static ColorSetting color_setting_from_str(char const *str) {
@@ -50,15 +48,31 @@ static char const *color_setting_to_str(ColorSetting s) {
// converts #rrggbb/#rrggbbaa to a color. returns false if it's not in the right format.
static Status color_from_str(char const *str, u32 *color) {
uint r = 0, g = 0, b = 0, a = 0xff;
- size_t len = strlen(str);
- if (len == 7) {
- sscanf(str, "#%02x%02x%02x", &r, &g, &b);
- } else if (len == 9) {
- sscanf(str, "#%02x%02x%02x%02x", &r, &g, &b, &a);
- } else {
- return false;
+ bool success = false;
+ switch (strlen(str)) {
+ case 4:
+ success = sscanf(str, "#%01x%01x%01x", &r, &g, &b) == 3;
+ // extend single hex digit to double hex digit
+ r |= r << 4;
+ g |= g << 4;
+ b |= b << 4;
+ break;
+ case 5:
+ success = sscanf(str, "#%01x%01x%01x%01x", &r, &g, &b, &a) == 4;
+ r |= r << 4;
+ g |= g << 4;
+ b |= b << 4;
+ a |= a << 4;
+ break;
+ case 7:
+ success = sscanf(str, "#%02x%02x%02x", &r, &g, &b) == 3;
+ break;
+ case 9:
+ success = sscanf(str, "#%02x%02x%02x%02x", &r, &g, &b, &a) == 4;
+ break;
}
- if (r > 0xff || g > 0xff || b > 0xff) return false;
+ if (!success || r > 0xff || g > 0xff || b > 0xff || a > 0xff)
+ return false;
if (color)
*color = (u32)r << 24 | (u32)g << 16 | (u32)b << 8 | (u32)a;
return true;
diff --git a/config.c b/config.c
index 259c85e..eb38cfd 100644
--- a/config.c
+++ b/config.c
@@ -9,7 +9,8 @@
typedef enum {
SECTION_NONE,
- SECTION_KEYBOARD
+ SECTION_KEYBOARD,
+ SECTION_COLORS
} Section;
// all worth it for the -Wformat warnings
@@ -146,6 +147,7 @@ void config_read(Ted *ted, char const *filename) {
.error = false
};
ConfigReader *cfg = &cfg_reader;
+ Settings *settings = &ted->settings;
FILE *fp = fopen(filename, "rb");
if (fp) {
int line_cap = 4096;
@@ -175,6 +177,8 @@ void config_read(Ted *ted, char const *filename) {
char *section_name = line + 1;
if (streq(section_name, "keyboard")) {
section = SECTION_KEYBOARD;
+ } else if (streq(section_name, "colors")) {
+ section = SECTION_COLORS;
} else {
config_err(cfg, "Unrecognized section: [%s].", section_name);
}
@@ -203,6 +207,19 @@ void config_read(Ted *ted, char const *filename) {
config_err(cfg, "Line outside of any section."
"Try putting a section header, e.g. [keyboard] before this line?");
break;
+ case SECTION_COLORS: {
+ ColorSetting setting = color_setting_from_str(key);
+ if (setting != COLOR_UNKNOWN) {
+ u32 color = 0;
+ if (color_from_str(value, &color)) {
+ settings->colors[setting] = color;
+ } else {
+ config_err(cfg, "'%s' is not a valid color. Colors should look like #rgb, #rgba, #rrggbb, or #rrggbbaa.", value);
+ }
+ } else {
+ config_err(cfg, "No such color option: %s", key);
+ }
+ } break;
case SECTION_KEYBOARD: {
// lines like Ctrl+Down = 10 :down
u32 key_combo = config_parse_key_combo(cfg, key);
diff --git a/main.c b/main.c
index de4f262..dfd78fa 100644
--- a/main.c
+++ b/main.c
@@ -14,6 +14,9 @@ no_warn_end
#include "command.h"
#include "util.c"
#include "colors.c"
+typedef struct {
+ u32 colors[COLOR_COUNT];
+} Settings;
#include "time.c"
#include "unicode.h"
#define MATH_GL
@@ -84,6 +87,8 @@ int main(void) {
die("Not enough memory available to run ted.");
}
+ Settings *settings = &ted->settings;
+
config_read(ted, "ted.cfg");
if (ted_haserr(ted)) {
die("Error reading config: %s", ted_geterr(ted));
@@ -91,7 +96,7 @@ int main(void) {
TextBuffer text_buffer;
TextBuffer *buffer = &text_buffer;
- buffer_create(buffer, font);
+ buffer_create(buffer, font, settings);
ted->active_buffer = buffer;
if (!buffer_load_file(buffer, "buffer.c"))
@@ -198,7 +203,11 @@ int main(void) {
glLoadIdentity();
// pixel coordinates; down is positive y
glOrtho(0, window_width, window_height, 0, -1, +1);
- glClearColor(0, 0, 0, 1);
+ { // clear (background)
+ float bg_color[4];
+ rgba_u32_to_floats(settings->colors[COLOR_BG], bg_color);
+ glClearColor(bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
+ }
glClear(GL_COLOR_BUFFER_BIT);
{
@@ -224,6 +233,7 @@ int main(void) {
SDL_Quit();
buffer_free(buffer);
text_font_free(font);
+ free(ted);
return 0;
}
diff --git a/math.c b/math.c
index 2909c66..d4adf73 100644
--- a/math.c
+++ b/math.c
@@ -700,6 +700,13 @@ static void gl_color2f(float v, float a) {
glColor4f(v,v,v,a);
}
+static void rgba_u32_to_floats(u32 rgba, float floats[static 4]) {
+ floats[0] = (float)(rgba >> 24) / 255.f;
+ floats[1] = (float)(rgba >> 16) / 255.f;
+ floats[2] = (float)(rgba >> 8) / 255.f;
+ floats[3] = (float)(rgba >> 0) / 255.f;
+}
+
// color is 0xRRGGBBAA
static void gl_color_rgba(u32 color) {
glColor4ub((u8)(color >> 24), (u8)(color >> 16), (u8)(color >> 8), (u8)color);
diff --git a/ted-base.c b/ted-base.c
index 8771f02..784bbe9 100644
--- a/ted-base.c
+++ b/ted-base.c
@@ -4,10 +4,6 @@ typedef struct {
i64 argument;
} KeyAction;
-typedef struct {
- u32 colors[COLOR_COUNT];
-} Settings;
-
#define SCANCODE_COUNT 0x120 // SDL scancodes should be less than this value.
// a "key combo" is some subset of {control, shift, alt} + some key.
#define KEY_COMBO_COUNT (SCANCODE_COUNT << 3)
@@ -21,6 +17,7 @@ typedef struct {
typedef struct {
TextBuffer *active_buffer;
+ Settings settings;
KeyAction key_actions[KEY_COMBO_COUNT];
char error[256];
} Ted;
diff --git a/ted.cfg b/ted.cfg
index ba0ffb5..c8b6099 100644
--- a/ted.cfg
+++ b/ted.cfg
@@ -41,3 +41,10 @@ Ctrl+s = :save
Ctrl+z = :undo
Ctrl+Shift+z = :redo
+[colors]
+border = #a77
+cursor-line-bg = #222
+cursor = #3ff
+selection-bg = #36a8
+text = #fff
+bg = #001