From 8461f5dec71f5d63d8ffba2ae1bb73ce2e74a000 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Wed, 25 Nov 2020 19:50:58 -0500 Subject: scrolling --- buffer.c | 17 ++++++++++++++++- main.c | 44 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/buffer.c b/buffer.c index 7fea0d3..cd6c353 100644 --- a/buffer.c +++ b/buffer.c @@ -22,6 +22,7 @@ typedef struct { typedef struct { u32 nblocks; // number of text blocks + double scroll_x, scroll_y; // number of characters scrolled in the x/y direction TextBlock *blocks; } TextBuffer; @@ -117,18 +118,27 @@ void text_buffer_free(TextBuffer *buffer) { free(blocks); } +void text_buffer_scroll(TextBuffer *buffer, double dx, double dy) { + buffer->scroll_x += dx; + buffer->scroll_y += dy; +} + // Render the text buffer in the given rectangle void text_buffer_render(TextBuffer *buffer, Font *font, float x1, float y1, float x2, float y2) { mbstate_t mbstate = {0}; uint nblocks = buffer->nblocks; TextBlock *blocks = buffer->blocks; - glBegin(GL_LINE_LOOP); + float char_height = text_font_char_height(font); + glColor3f(0.5f,0.5f,0.5f); + glBegin(GL_LINE_STRIP); glVertex2f(x1,y1); glVertex2f(x1,y2); glVertex2f(x2,y2); glVertex2f(x2,y1); + glVertex2f(x1-1,y1); glEnd(); + glColor3f(1,1,1); text_chars_begin(font); TextRenderState text_state = { .x = x1, .y = y1 + text_font_char_height(font), @@ -136,6 +146,10 @@ void text_buffer_render(TextBuffer *buffer, Font *font, float x1, float y1, floa .max_x = x2, .max_y = y2 }; + // @TODO: make this better (we should figure out where to start rendering, etc.) + text_state.x -= (float)buffer->scroll_x * char_height; + text_state.y -= (float)buffer->scroll_y * char_height; + for (uint block_idx = 0; block_idx < nblocks; ++block_idx) { TextBlock *block = &blocks[block_idx]; char *p = block->contents, *end = p + block->len; @@ -177,3 +191,4 @@ void text_buffer_render(TextBuffer *buffer, Font *font, float x1, float y1, floa } text_chars_end(font); } + diff --git a/main.c b/main.c index c655d42..feb526a 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,3 @@ - #include "base.h" no_warn_start #if _WIN32 @@ -36,6 +35,7 @@ INT WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, int main(void) { #endif setlocale(LC_ALL, ""); // allow unicode + SDL_SetHint(SDL_HINT_NO_SIGNAL_HANDLERS, "1"); // if this program is sent a SIGTERM/SIGINT, don't turn it into a quit event if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0) die("%s", SDL_GetError()); @@ -43,7 +43,7 @@ int main(void) { SDL_WINDOWPOS_UNDEFINED, 1280, 720, SDL_WINDOW_SHOWN|SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); if (!window) die("%s", SDL_GetError()); - + { // set icon SDL_Surface *icon = SDL_LoadBMP("assets/icon.bmp"); SDL_SetWindowIcon(window, icon); @@ -77,16 +77,54 @@ int main(void) { } + Uint32 time_at_last_frame = SDL_GetTicks(); + while (!quit) { SDL_Event event; + + while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: quit = true; break; + case SDL_MOUSEWHEEL: { + // scroll with mouse wheel + Sint32 dx = event.wheel.x, dy = -event.wheel.y; + double scroll_speed = 2.5; + text_buffer_scroll(&text_buffer, dx * scroll_speed, dy * scroll_speed); + } break; } } + Uint8 const *keyboard_state = SDL_GetKeyboardState(NULL); + bool control_key_down = keyboard_state[SDL_SCANCODE_LCTRL] || keyboard_state[SDL_SCANCODE_RCTRL]; + + double frame_dt; + { + Uint32 time_this_frame = SDL_GetTicks(); + frame_dt = 0.001 * (time_this_frame - time_at_last_frame); + time_at_last_frame = time_this_frame; + } + + if (control_key_down) { + // control + arrow keys to scroll + double scroll_speed = 20.0; + double scroll_amount = scroll_speed * frame_dt; + if (keyboard_state[SDL_SCANCODE_UP]) + text_buffer_scroll(&text_buffer, 0, -scroll_amount); + if (keyboard_state[SDL_SCANCODE_DOWN]) + text_buffer_scroll(&text_buffer, 0, +scroll_amount); + // @TODO: get this to work + #if 0 + if (keyboard_state[SDL_SCANCODE_LEFT]) + text_buffer_scroll(&text_buffer, -scroll_amount, 0); + if (keyboard_state[SDL_SCANCODE_RIGHT]) + text_buffer_scroll(&text_buffer, +scroll_amount, 0); + #endif + } + + int window_width = 0, window_height = 0; SDL_GetWindowSize(window, &window_width, &window_height); float window_widthf = (float)window_width, window_heightf = (float)window_height; @@ -102,8 +140,6 @@ int main(void) { glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); - glColor3f(1,1,1); - { float x1 = 50, y1 = 50, x2 = window_widthf-50, y2 = window_heightf-50; text_buffer_render(&text_buffer, font, x1, y1, x2, y2); -- cgit v1.2.3