You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
2.8 KiB
106 lines
2.8 KiB
|
|
#include <string> |
|
#include <deque> |
|
#include "draw.h" |
|
#include "colours.h" |
|
|
|
struct chat_line_shape { |
|
SDL_Surface* surf; |
|
SDL_Texture* tex; |
|
SDL_Rect rect; |
|
|
|
void destroy() { |
|
SDL_FreeSurface(surf); |
|
SDL_DestroyTexture(tex); |
|
} |
|
}; |
|
|
|
struct chat_line_shape draw_text(struct sdl_context c, TTF_Font* f, SDL_Color col, int width, const std::string &text, bool wrapped = true) { |
|
SDL_Surface* surf; |
|
if (wrapped) { |
|
surf = TTF_RenderUTF8_Solid_Wrapped(f, text.c_str(), col, width); |
|
} else { |
|
surf = TTF_RenderUTF8_Solid(f, text.c_str(), col); |
|
|
|
} |
|
SDL_Texture* tex = SDL_CreateTextureFromSurface(c.ren, surf); |
|
SDL_Rect msgrect = {}; |
|
SDL_QueryTexture(tex, NULL, NULL, &msgrect.w, &msgrect.h); |
|
return { surf, tex, msgrect }; |
|
} |
|
|
|
void render_text(struct sdl_context c, TTF_Font* f, SDL_Color col, int x, int y, int width, const std::string &text) { |
|
auto t = draw_text(c, f, col, width, text); |
|
t.rect.x = x; |
|
t.rect.y = y; |
|
SDL_RenderCopy(c.ren, t.tex, NULL, &t.rect); |
|
t.destroy(); |
|
} |
|
|
|
|
|
void draw_messages(struct drawinfo d, std::deque<msg> &message_display_queue) { |
|
|
|
int height = d.drawcontext.height - 20; |
|
int linesep = 0; |
|
int i = message_display_queue.size() - 1; |
|
|
|
unsigned int now = SDL_GetTicks(); |
|
|
|
int name_margin = 150; |
|
for (; i >= 0 && height > 20; i--) { |
|
msg m = message_display_queue.at(i); |
|
|
|
if (now - m.received_at > d.max_age) { |
|
continue; |
|
} |
|
|
|
struct chat_line_shape s = draw_text(d.drawcontext, d.fonts.messages, d.colours.messages, d.drawcontext.width - 20 - name_margin, m.message); |
|
height -= s.rect.h + linesep; |
|
|
|
s.rect.x = 20 + name_margin; |
|
s.rect.y = height; |
|
|
|
SDL_Color uname_col = get_uname_colour(m.user); |
|
|
|
|
|
struct chat_line_shape userline = draw_text(d.drawcontext, d.fonts.usernames, uname_col, name_margin - 20, m.user, false); |
|
userline.rect.y = height; |
|
if (userline.rect.w > name_margin - 20) { |
|
userline.rect.w = name_margin - 20; |
|
} |
|
userline.rect.x = name_margin - userline.rect.w; |
|
|
|
SDL_RenderCopy(d.drawcontext.ren, userline.tex, NULL, &userline.rect); |
|
SDL_RenderCopy(d.drawcontext.ren, s.tex, NULL, &s.rect); |
|
userline.destroy(); |
|
s.destroy(); |
|
|
|
} |
|
|
|
for (; i > 0; i--) { |
|
// remove offscreen messages from queue |
|
message_display_queue.pop_front(); |
|
} |
|
|
|
} |
|
|
|
void draw(struct drawinfo d, std::deque<msg> &messages) { |
|
|
|
auto col = d.colours.background; |
|
SDL_SetRenderDrawColor(d.drawcontext.ren, col.r, col.g, col.b, 255); |
|
SDL_RenderClear(d.drawcontext.ren); |
|
|
|
|
|
// background |
|
int wmargin, hmargin; |
|
wmargin = 10; |
|
hmargin = 10; |
|
SDL_Rect bg{ wmargin, hmargin, d.drawcontext.width - wmargin * 2, d.drawcontext.height - hmargin * 2 }; |
|
auto bc = d.colours.background; |
|
// SDL_SetRenderDrawColor(d.drawcontext.ren, bc.r, bc.g, bc.b, 0); |
|
// SDL_RenderFillRect(d.drawcontext.ren, &bg); |
|
|
|
draw_messages(d, messages); |
|
|
|
SDL_RenderPresent(d.drawcontext.ren); |
|
}
|
|
|