/*
* re_ui.c
*
* A programmers editor
*
* Simple UI in SDL2
*
* Author: Dario Rodriguez dario@softhome.net
* This program is licensed under the terms of GNU GPL v2.1+
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include "re_ui.h"
#include "hack_regular.h"
#define DEFAULTFONTSIZE 16
#define DEFAULTTITLEPREFIX "re - "
#define DEFAULTWINDOWWIDTH 80
#define DEFAULTWINDOWHEIGHT 66
#define RECTFILL(r,rx,ry,rw,rh) (r).x=(rx),(r).y=(ry),(r).w=(rw),(r).h=(rh)
reui_t *
reui_init()
{
reui_t *ui;
SDL_Rect screenrect;
if((ui=malloc(sizeof(reui_t)))==NULL)
return(NULL);
memset(ui,0,sizeof(reui_t));
/* video */
if(SDL_Init(SDL_INIT_VIDEO)<0
|| SDL_GetDisplayBounds(0,&screenrect)!=0) {
reui_free(ui),ui=NULL;
return(NULL);
}
ui->screenw=screenrect.w;
ui->screenh=screenrect.h;
/* font */
ui->fontheight=DEFAULTFONTSIZE;
ui->fontdata=SDL_RWFromConstMem(hack_regular,SIZE_HACK_REGULAR);
SDL_RWseek(ui->fontdata,0,RW_SEEK_SET);
if(ui->fontdata==NULL
|| TTF_Init()==-1
|| (ui->font=TTF_OpenFontRW(ui->fontdata,0,ui->fontheight))==NULL) {
reui_free(ui),ui=NULL;
return(NULL);
}
/* font width */
{
SDL_Surface *s;
SDL_Color c={0,0,0,0};
if((s=TTF_RenderUTF8_Blended(ui->font,"m",c))==NULL) {
reui_free(ui),ui=NULL;
return(NULL);
}
ui->fontwidth=s->w;
SDL_FreeSurface(s),s=NULL;
}
/* main window */
ui->w=ui->fontwidth*DEFAULTWINDOWWIDTH;
ui->w=(ui->w>ui->screenw)?ui->screenw:ui->w;
ui->h=ui->fontheight*DEFAULTWINDOWHEIGHT;
ui->h=(ui->h>ui->screenh)?ui->screenw:ui->h;
if((ui->win=SDL_CreateWindow(
DEFAULTTITLEPREFIX,
SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,
ui->w,ui->h,0))==NULL
|| (ui->renderer=SDL_CreateRenderer(ui->win,-1,
SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC))==NULL
|| (ui->scr=SDL_CreateTexture(ui->renderer,SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING,ui->w,ui->h))==NULL) {
reui_free(ui),ui=NULL;
return(NULL);
}
/* finished */
ui->scrdirty=1;
ui->rendererdirty=1;
return(ui);
}
void
reui_free(reui_t *ui)
{
if(ui==NULL)
return;
if(ui->font!=NULL)
TTF_CloseFont(ui->font),ui->fontdata=NULL;
if(TTF_WasInit())
TTF_Quit();
if(ui->fontdata!=NULL)
SDL_FreeRW(ui->fontdata),ui->fontdata=NULL;
if(ui->scr!=NULL)
SDL_DestroyTexture(ui->scr),ui->scr=NULL;
if(ui->renderer!=NULL)
SDL_DestroyRenderer(ui->renderer),ui->renderer=NULL;
if(ui->win!=NULL)
SDL_DestroyWindow(ui->win),ui->win=NULL;
SDL_Quit();
free(ui),ui=NULL;
}
int
reui_title(reui_t *ui, char *titlefilename)
{
char buf[1024];
if(ui==NULL || titlefilename==NULL)
return(-1);
snprintf(buf,sizeof(buf),"%s%s",DEFAULTTITLEPREFIX,titlefilename);
buf[sizeof(buf)-1]='\0';
SDL_SetWindowTitle(ui->win,buf);
return(0);
}
int
reui_fill(reui_t *ui, int x, int y, int w, int h, char *rgba)
{
SDL_Rect dstrect;
if(ui==NULL || rgba==NULL)
return(-1);
RECTFILL(dstrect,x,y,w,h);
SDL_SetRenderDrawColor(ui->renderer,
((unsigned char *)rgba)[0],
((unsigned char *)rgba)[1],
((unsigned char *)rgba)[2],
((unsigned char *)rgba)[3]);
SDL_RenderFillRect(ui->renderer, &dstrect);
ui->rendererdirty=1;
return(0);
}
int
reui_scr2renderer(reui_t *ui, int x, int y, int w, int h)
{
SDL_Rect srcrect,dstrect;
if(ui==NULL)
return(-1);
RECTFILL(srcrect,x,y,w,h);
RECTFILL(dstrect,x,y,w,h);
SDL_RenderCopy(ui->renderer,ui->scr,&srcrect,&dstrect);
ui->rendererdirty=1;
return(0);
}
int
reui_present(reui_t *ui)
{
if(ui==NULL)
return(-1);
SDL_RenderPresent(ui->renderer);
ui->rendererdirty=0;
return(0);
}
int
reui_write(reui_t *ui, int x, int y, char *rgba, char *str, int nchar)
{
char buf[1024];
SDL_Surface *fgsurface;
SDL_Texture *fg;
SDL_Color c={((unsigned char *)rgba)[0],
((unsigned char *)rgba)[1],
((unsigned char *)rgba)[2],
((unsigned char *)rgba)[3]};
SDL_Rect dstrect;
if(nchar<sizeof(buf)) {
memcpy(buf,str,nchar);
buf[nchar]='\0';
} else {
memcpy(buf,str,sizeof(buf)-1);
buf[sizeof(buf)-1]='\0';
}
if((fgsurface=TTF_RenderUTF8_Blended(ui->font,buf,c))==NULL
|| (fg=SDL_CreateTextureFromSurface(ui->renderer,fgsurface))==NULL) {
if(fgsurface!=NULL)
SDL_FreeSurface(fgsurface),fgsurface=NULL;
return(-1);
}
RECTFILL(dstrect,x,y,fgsurface->w,fgsurface->h);
SDL_RenderCopy(ui->renderer,fg,NULL,&dstrect);
ui->rendererdirty=1;
SDL_FreeSurface(fgsurface),fgsurface=NULL;
SDL_DestroyTexture(fg),fg=NULL;
return(0);
}
int
reui_printf(reui_t *ui, int x, int y, char *rgba, char *format, ...)
{
char buf[1024];
va_list l;
va_start(l,format);
vsnprintf(buf,sizeof(buf),format,l);
va_end(l);
buf[sizeof(buf)-1]='\0';
if(reui_write(ui,x,y,rgba,buf,strlen(buf))!=0)
return(-1);
return(0);
}