... | ... |
@@ -24,6 +24,23 @@ |
24 | 24 |
|
25 | 25 |
#define RECTFILL(r,rx,ry,rw,rh) (r).x=(rx),(r).y=(ry),(r).w=(rw),(r).h=(rh) |
26 | 26 |
|
27 |
+#if SDL_BYTEORDER==SDL_BIG_ENDIAN |
|
28 |
+#define CHARRGBA2UINT(rgba) ((((Uint32)(((unsigned char *)rgba)[0]))<<24) \ |
|
29 |
+ |(((Uint32)(((unsigned char *)rgba)[1]))<<16) \ |
|
30 |
+ |(((Uint32)(((unsigned char *)rgba)[2]))<<8) \ |
|
31 |
+ |((Uint32)(((unsigned char *)rgba)[3]))) |
|
32 |
+#else |
|
33 |
+#define CHARRGBA2UINT(rgba) ((((Uint32)(((unsigned char *)rgba)[3]))<<24) \ |
|
34 |
+ |(((Uint32)(((unsigned char *)rgba)[2]))<<16) \ |
|
35 |
+ |(((Uint32)(((unsigned char *)rgba)[1]))<<8) \ |
|
36 |
+ |((Uint32)(((unsigned char *)rgba)[0]))) |
|
37 |
+#endif |
|
38 |
+ |
|
39 |
+ |
|
40 |
+static int reui_fillrounded(SDL_Surface *dst, int xo, int yo, int w, int h, int r, char *rgba); |
|
41 |
+static int reui_triangle(SDL_Surface *dst, int x, int y, int w, int h, char direction, char *rgba); |
|
42 |
+ |
|
43 |
+ |
|
27 | 44 |
reui_t * |
28 | 45 |
reui_init() |
29 | 46 |
{ |
... | ... |
@@ -223,4 +240,239 @@ reui_printf(reui_t *ui, int x, int y, char *rgba, char *format, ...) |
223 | 240 |
return(0); |
224 | 241 |
} |
225 | 242 |
|
243 |
+int |
|
244 |
+reui_balloon(reui_t *ui, char direction, int x, int y, char *rgbafg, char *rgbabg, char *str, int nchar) |
|
245 |
+{ |
|
246 |
+ char buf[1024]; |
|
247 |
+ SDL_Surface *bgsurface; |
|
248 |
+ SDL_Surface *fgsurface; |
|
249 |
+ SDL_Texture *tex; |
|
250 |
+ SDL_Color c={((unsigned char *)rgbafg)[0], |
|
251 |
+ ((unsigned char *)rgbafg)[1], |
|
252 |
+ ((unsigned char *)rgbafg)[2], |
|
253 |
+ ((unsigned char *)rgbafg)[3]}; |
|
254 |
+ SDL_Rect dstrect; |
|
255 |
+ Uint32 rmask, gmask, bmask, amask; |
|
256 |
+ int trianglew,triangleh; |
|
257 |
+ int marginw,marginh; |
|
258 |
+ int marginoffx,marginoffy; |
|
259 |
+ int radius; |
|
260 |
+ int offx,offy; |
|
261 |
+ if(ui==NULL || rgbafg==NULL || rgbabg==NULL || (str==NULL && nchar!=0)) |
|
262 |
+ return(-1); |
|
263 |
+#if SDL_BYTEORDER==SDL_BIG_ENDIAN |
|
264 |
+ rmask=0xff000000; |
|
265 |
+ gmask=0x00ff0000; |
|
266 |
+ bmask=0x0000ff00; |
|
267 |
+ amask=0x000000ff; |
|
268 |
+#else |
|
269 |
+ rmask=0x000000ff; |
|
270 |
+ gmask=0x0000ff00; |
|
271 |
+ bmask=0x00ff0000; |
|
272 |
+ amask=0xff000000; |
|
273 |
+#endif |
|
274 |
+ if(nchar<sizeof(buf)) { |
|
275 |
+ memcpy(buf,str,nchar); |
|
276 |
+ buf[nchar]='\0'; |
|
277 |
+ } else { |
|
278 |
+ memcpy(buf,str,sizeof(buf)-1); |
|
279 |
+ buf[sizeof(buf)-1]='\0'; |
|
280 |
+ } |
|
281 |
+ if((fgsurface=TTF_RenderUTF8_Blended(ui->font,buf,c))==NULL) |
|
282 |
+ return(-1); |
|
283 |
+ trianglew=ui->fontwidth; |
|
284 |
+ triangleh=ui->fontheight/2; |
|
285 |
+ marginw=ui->fontwidth*4/3; |
|
286 |
+ marginh=ui->fontheight/3; |
|
287 |
+ marginoffx=0; |
|
288 |
+ marginoffy=-ui->fontheight/18; |
|
289 |
+ radius=ui->fontheight/2; |
|
290 |
+ if((bgsurface=SDL_CreateRGBSurface(0 |
|
291 |
+ ,(fgsurface->w+marginw*2)+((direction=='w' || direction=='e')?trianglew:0) |
|
292 |
+ ,(fgsurface->h+marginh*2)+((direction=='n' || direction=='s')?triangleh:0) |
|
293 |
+ ,32, rmask, gmask, bmask, amask))==NULL) { |
|
294 |
+ if(fgsurface!=NULL) |
|
295 |
+ SDL_FreeSurface(fgsurface),fgsurface=NULL; |
|
296 |
+ return(-1); |
|
297 |
+ } |
|
298 |
+ if(direction=='n') { |
|
299 |
+ reui_fillrounded(bgsurface,0,triangleh-1,bgsurface->w,bgsurface->h-triangleh,radius,rgbabg); |
|
300 |
+ reui_triangle(bgsurface,(bgsurface->w-trianglew)/2,0,trianglew,triangleh,direction,rgbabg); |
|
301 |
+ RECTFILL(dstrect,marginw+marginoffx,triangleh+marginh+marginoffy,fgsurface->w,fgsurface->h); |
|
302 |
+ SDL_BlitSurface(fgsurface,NULL,bgsurface,&dstrect); |
|
303 |
+ offx=-bgsurface->w/2; |
|
304 |
+ offy=0; |
|
305 |
+ } else if(direction=='e') { |
|
306 |
+ reui_fillrounded(bgsurface,0,0,bgsurface->w-trianglew,bgsurface->h,radius,rgbabg); |
|
307 |
+ reui_triangle(bgsurface,bgsurface->w-trianglew,(bgsurface->h-triangleh)/2,trianglew,triangleh,direction,rgbabg); |
|
308 |
+ RECTFILL(dstrect,marginw+marginoffx,marginh+marginoffy,fgsurface->w,fgsurface->h); |
|
309 |
+ SDL_BlitSurface(fgsurface,NULL,bgsurface,&dstrect); |
|
310 |
+ offx=-bgsurface->w; |
|
311 |
+ offy=-bgsurface->h/2; |
|
312 |
+ } else if(direction=='s') { |
|
313 |
+ reui_fillrounded(bgsurface,0,0,bgsurface->w,bgsurface->h-triangleh,radius,rgbabg); |
|
314 |
+ reui_triangle(bgsurface,(bgsurface->w-trianglew)/2,bgsurface->h-triangleh,trianglew,triangleh,direction,rgbabg); |
|
315 |
+ RECTFILL(dstrect,marginw+marginoffx,marginh+marginoffy,fgsurface->w,fgsurface->h); |
|
316 |
+ SDL_BlitSurface(fgsurface,NULL,bgsurface,&dstrect); |
|
317 |
+ offx=-bgsurface->w/2; |
|
318 |
+ offy=-bgsurface->h; |
|
319 |
+ } else if(direction=='w') { |
|
320 |
+ reui_fillrounded(bgsurface,trianglew,0,bgsurface->w-trianglew,bgsurface->h,radius,rgbabg); |
|
321 |
+ reui_triangle(bgsurface,0,(bgsurface->h-triangleh)/2,trianglew,triangleh,direction,rgbabg); |
|
322 |
+ RECTFILL(dstrect,trianglew+marginw+marginoffx,marginh+marginoffy,fgsurface->w,fgsurface->h); |
|
323 |
+ SDL_BlitSurface(fgsurface,NULL,bgsurface,&dstrect); |
|
324 |
+ offx=0; |
|
325 |
+ offy=-bgsurface->h/2; |
|
326 |
+ } else { /* default: center */ |
|
327 |
+ reui_fillrounded(bgsurface,0,0,bgsurface->w,bgsurface->h,radius,rgbabg); |
|
328 |
+ RECTFILL(dstrect,marginw+marginoffx,marginh+marginoffy,fgsurface->w,fgsurface->h); |
|
329 |
+ SDL_BlitSurface(fgsurface,NULL,bgsurface,&dstrect); |
|
330 |
+ offx=-bgsurface->w/2; |
|
331 |
+ offy=-bgsurface->h/2; |
|
332 |
+ } |
|
333 |
+ if((tex=SDL_CreateTextureFromSurface(ui->renderer,bgsurface))==NULL) { |
|
334 |
+ SDL_FreeSurface(fgsurface),fgsurface=NULL; |
|
335 |
+ SDL_FreeSurface(bgsurface),bgsurface=NULL; |
|
336 |
+ return(-1); |
|
337 |
+ } |
|
338 |
+ RECTFILL(dstrect,x+offx,y+offy,bgsurface->w,bgsurface->h); |
|
339 |
+ SDL_RenderCopy(ui->renderer,tex,NULL,&dstrect); |
|
340 |
+ ui->rendererdirty=1; |
|
341 |
+ SDL_FreeSurface(fgsurface),fgsurface=NULL; |
|
342 |
+ SDL_FreeSurface(bgsurface),bgsurface=NULL; |
|
343 |
+ SDL_DestroyTexture(tex),tex=NULL; |
|
344 |
+ return(0); |
|
345 |
+ |
|
346 |
+} |
|
347 |
+ |
|
348 |
+ |
|
349 |
+ |
|
350 |
+/* |
|
351 |
+ * https://sdl.libsdl.narkive.com/rX3aNgKp/rectangle-with-round-corners-in-sdl |
|
352 |
+ * |
|
353 |
+ * static int fill_rounded_box_b(SDL_Surface* dst, int xo, int yo, |
|
354 |
+ * int w, int h, int r, Uint32 color); |
|
355 |
+ * |
|
356 |
+ * by "Sami N��t�nen" (s***@bayminer.com) |
|
357 |
+ * (lightly edited to conform to this file code style and semantics) |
|
358 |
+ * |
|
359 |
+ * draws a rounded box with... |
|
360 |
+ * corner radius of 'r' |
|
361 |
+ * width of 'w' |
|
362 |
+ * and height of 'h' |
|
363 |
+ * |
|
364 |
+ * draws the box right and down of... |
|
365 |
+ * x-offset xo |
|
366 |
+ * y-offset yo |
|
367 |
+ * |
|
368 |
+ * returns -1 if 2*r is bigger than w or h |
|
369 |
+ * and draws nothing |
|
370 |
+ * returns 0 on success |
|
371 |
+ */ |
|
372 |
+static int |
|
373 |
+reui_fillrounded(SDL_Surface *dst, int xo, int yo, int w, int h, int r, char *rgba) |
|
374 |
+{ |
|
375 |
+ int yd=(dst->pitch)/(dst->format->BytesPerPixel); |
|
376 |
+ Uint32 *pixels=NULL; |
|
377 |
+ int x,y,i,j; |
|
378 |
+ int rpsqrt2= (int) (r/sqrt(2)); |
|
379 |
+ int sy,ey,sx,ex; |
|
380 |
+ int d,x2m1; |
|
381 |
+ Uint32 color; |
|
382 |
+ if(dst==NULL || rgba==NULL || xo<0 || y0<0 || (xo+w)>dst->w || (yo+h)>dst->h) |
|
383 |
+ return(-1); /* sanity check failed */ |
|
384 |
+ color=CHARRGBA2UINT(rgba); |
|
385 |
+ w/=2; |
|
386 |
+ h/=2; |
|
387 |
+ xo+=w; |
|
388 |
+ yo+=h; |
|
389 |
+ w-=r; |
|
390 |
+ h-=r; |
|
391 |
+ if(w<0||h<0) |
|
392 |
+ return(-1); |
|
393 |
+ SDL_LockSurface(dst); |
|
394 |
+ pixels=(Uint32*)(dst->pixels); |
|
395 |
+ sy=(yo-h)*yd; |
|
396 |
+ ey=(yo+h)*yd; |
|
397 |
+ sx=(xo-w); |
|
398 |
+ ex=(xo+w); |
|
399 |
+ for(i=sy;i<=ey;i+=yd) { |
|
400 |
+ for(j=sx-r;j<=ex+r;j++) { |
|
401 |
+ pixels[i+j]=color; |
|
402 |
+ } |
|
403 |
+ } |
|
404 |
+ d=-r; |
|
405 |
+ x2m1=-1; |
|
406 |
+ y=r; |
|
407 |
+ for(x=0;x<=rpsqrt2;x++) { |
|
408 |
+ x2m1+=2; |
|
409 |
+ d+=x2m1; |
|
410 |
+ if(d>=0) { |
|
411 |
+ y--; |
|
412 |
+ d-=(y*2); |
|
413 |
+ } |
|
414 |
+ for(i=sx-x;i<=ex+x;i++) |
|
415 |
+ pixels[sy-y*yd+i]=color; |
|
416 |
+ |
|
417 |
+ for(i=sx-y;i<=ex+y;i++) |
|
418 |
+ pixels[sy-x*yd+i]=color; |
|
419 |
+ |
|
420 |
+ for(i=sx-y;i<=ex+y;i++) |
|
421 |
+ pixels[ey+x*yd+i]=color; |
|
422 |
+ |
|
423 |
+ for(i=sx-x;i<=ex+x;i++) |
|
424 |
+ pixels[ey+y*yd+i]=color; |
|
425 |
+ } |
|
426 |
+ SDL_UnlockSurface(dst); |
|
427 |
+ return(0); |
|
428 |
+} |
|
429 |
+ |
|
430 |
+/* end of external code */ |
|
431 |
+ |
|
432 |
+static int |
|
433 |
+reui_triangle(SDL_Surface *dst, int x, int y, int w, int h, char direction, char *rgba) |
|
434 |
+{ |
|
435 |
+ Uint32 color; |
|
436 |
+ SDL_Rect dstrect; |
|
437 |
+ int i; |
|
438 |
+ int myw,myh; |
|
439 |
+ if(dst==NULL || rgba==NULL) |
|
440 |
+ return(-1); |
|
441 |
+ color=CHARRGBA2UINT(rgba); |
|
442 |
+ SDL_LockSurface(dst); |
|
443 |
+ if(direction=='n') { |
|
444 |
+ for(i=0;i<h;i++) { |
|
445 |
+ myw=(i*w*2)/(3*h); |
|
446 |
+ myw=(myw<0)?1:(myw>w)?w:myw; |
|
447 |
+ RECTFILL(dstrect,x+(w-myw)/2,y+i,myw,1); |
|
448 |
+ SDL_FillRect(dst,&dstrect,color); |
|
449 |
+ } |
|
450 |
+ } else if(direction=='e') { |
|
451 |
+ for(i=0;i<w;i++) { |
|
452 |
+ myh=(i*h*2)/(3*w); |
|
453 |
+ myh=(myh<0)?1:(myh>h)?h:myh; |
|
454 |
+ RECTFILL(dstrect,x+w-1-i,y+(h-myh)/2,1,myh); |
|
455 |
+ SDL_FillRect(dst,&dstrect,color); |
|
456 |
+ } |
|
457 |
+ } else if(direction=='s') { |
|
458 |
+ for(i=0;i<h;i++) { |
|
459 |
+ myw=(i*w*2)/(3*h); |
|
460 |
+ myw=(myw<0)?1:(myw>w)?w:myw; |
|
461 |
+ RECTFILL(dstrect,x+(w-myw)/2,y+h-1-i,myw,1); |
|
462 |
+ SDL_FillRect(dst,&dstrect,color); |
|
463 |
+ } |
|
464 |
+ } else if(direction=='w') { |
|
465 |
+ for(i=0;i<w;i++) { |
|
466 |
+ myh=(i*h*2)/(3*w); |
|
467 |
+ myh=(myh<0)?1:(myh>h)?h:myh; |
|
468 |
+ RECTFILL(dstrect,x+i,y+(h-myh)/2,1,myh); |
|
469 |
+ SDL_FillRect(dst,&dstrect,color); |
|
470 |
+ } |
|
471 |
+ } else { /* default: center */ |
|
472 |
+ RECTFILL(dstrect,x,y,w,h); |
|
473 |
+ SDL_FillRect(dst,&dstrect,color); |
|
474 |
+ } |
|
475 |
+ SDL_UnlockSurface(dst); |
|
476 |
+ return(0); |
|
477 |
+} |
|
226 | 478 |
|
... | ... |
@@ -48,3 +48,5 @@ int reui_printf(reui_t *ui, int x, int y, char *rgba, char *format, ...) __attri |
48 | 48 |
int reui_printf(reui_t *ui, int x, int y, char *rgba, char *format, ...); |
49 | 49 |
#endif |
50 | 50 |
|
51 |
+int reui_balloon(reui_t *ui, char direction, int x, int y, char *rgbafg, char *rgbabg, char *str, int nchar); |
|
52 |
+ |
... | ... |
@@ -1040,6 +1040,7 @@ re_drawcontents(re_t *re) |
1040 | 1040 |
reui_write(re->ui,re->x+re->ui->fontwidth*(re->curcol-re->origincol),y,"\xff\xff\xff\xff",curptr,redata_generic_utf8charlen(curptr,curptrlen)); |
1041 | 1041 |
} |
1042 | 1042 |
#warning TODO: if it is one of '[','{','<','>','}',']', highlight the matching bracket/parens/anglebracket. |
1043 |
+#warning When searching for matching backet/..., count only the ones in the same highlighting color. |
|
1043 | 1044 |
#warning If it is ourside of the visible part of the code, put a comic baloon (with some transparency) in that dir. (up, down or right) at the correct height/position to mark the direction of where it is. |
1044 | 1045 |
#warning TODO: Select(control+k+b/control+k+k/...) |
1045 | 1046 |
} |
... | ... |
@@ -1053,6 +1054,20 @@ re_drawcontents(re_t *re) |
1053 | 1054 |
} |
1054 | 1055 |
re->contentsdirty=0; |
1055 | 1056 |
re->ui->rendererdirty=1; |
1057 |
+#if 1 |
|
1058 |
+{ |
|
1059 |
+char sampletext[]={"Here is the top"}; |
|
1060 |
+char sampletextlarge[]={"void *memcpy(void *dest, const void *src, size_t n)"}; |
|
1061 |
+reui_balloon(re->ui, 'n', re->x+re->w/2, re->y, "\xff\x00\x00\xff", "\x00\x00\xff\x80",sampletext,strlen(sampletext)); |
|
1062 |
+reui_balloon(re->ui, 's', re->x+re->w/2, re->y+re->h-1, "\xff\x00\x00\x80", "\xff\xff\xff\xaf", "}",1); |
|
1063 |
+reui_balloon(re->ui, 'e', re->x+re->w-1,re->y+re->h/2, "\xff\x00\x00\x80", "\xff\xff\xff\xaf", "[",1); |
|
1064 |
+reui_balloon(re->ui, 'w', re->x, re->y+re->h/2, "\xff\x00\x00\x80", "\xff\xff\xff\xaf", "]",1); |
|
1065 |
+if((re->curline-re->originline)>=(re->maxrow/2)) |
|
1066 |
+ reui_balloon(re->ui, '\0', re->x+re->w/2, re->y+re->ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",sampletextlarge,strlen(sampletextlarge)); |
|
1067 |
+else |
|
1068 |
+ reui_balloon(re->ui, '\0', re->x+re->w/2, re->y+re->h-re->ui->fontheight*3/2, "\x80\x80\x80\xff", "\xff\xff\xff\xcf",sampletextlarge,strlen(sampletextlarge)); |
|
1069 |
+} |
|
1070 |
+#endif |
|
1056 | 1071 |
return(0); |
1057 | 1072 |
} |
1058 | 1073 |
|