2006-06-22 16:26:55 +04:00
|
|
|
/*
|
|
|
|
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
|
|
|
|
* See LICENSE file for license details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <cext.h>
|
|
|
|
#include "blitz.h"
|
|
|
|
|
|
|
|
static void
|
|
|
|
xchangegc(BlitzInput *i, BlitzColor *c, Bool invert)
|
|
|
|
{
|
|
|
|
XGCValues gcv;
|
|
|
|
|
|
|
|
if(invert) {
|
|
|
|
gcv.foreground = c->bg;
|
|
|
|
gcv.background = c->fg;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
gcv.foreground = c->fg;
|
|
|
|
gcv.background = c->bg;
|
|
|
|
}
|
|
|
|
if(i->font->set)
|
|
|
|
XChangeGC(i->blitz->display, i->gc, GCForeground | GCBackground, &gcv);
|
|
|
|
else {
|
|
|
|
gcv.font = i->font->xfont->fid;
|
|
|
|
XChangeGC(i->blitz->display, i->gc, GCForeground | GCBackground | GCFont, &gcv);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2006-06-23 12:47:07 +04:00
|
|
|
xdrawtextpart(BlitzInput *i, char *start, char *end,
|
2006-06-29 17:38:09 +04:00
|
|
|
unsigned int *xoff, unsigned int yoff)
|
2006-06-22 16:26:55 +04:00
|
|
|
{
|
2006-06-29 17:38:09 +04:00
|
|
|
char c;
|
2006-06-22 16:26:55 +04:00
|
|
|
|
2006-06-29 17:38:09 +04:00
|
|
|
if(!start)
|
|
|
|
return;
|
|
|
|
if(end) {
|
|
|
|
c = *end;
|
|
|
|
*end = 0;
|
|
|
|
}
|
|
|
|
if(i->font->set)
|
|
|
|
XmbDrawImageString(i->blitz->display, i->drawable, i->font->set, i->gc,
|
|
|
|
*xoff, yoff, start, strlen(start));
|
|
|
|
else
|
|
|
|
XDrawImageString(i->blitz->display, i->drawable, i->gc, *xoff, yoff,
|
|
|
|
start, strlen(start));
|
2006-06-22 16:26:55 +04:00
|
|
|
|
2006-06-29 17:38:09 +04:00
|
|
|
*xoff += blitz_textwidth(i->font, start);
|
|
|
|
if(end)
|
|
|
|
*end = c;
|
2006-06-22 16:26:55 +04:00
|
|
|
}
|
|
|
|
|
2006-06-29 17:38:09 +04:00
|
|
|
|
2006-06-22 16:26:55 +04:00
|
|
|
void
|
|
|
|
blitz_draw_input(BlitzInput *i)
|
|
|
|
{
|
2006-06-30 14:21:26 +04:00
|
|
|
unsigned int xoff, yoff, xcursor, h;
|
2006-06-29 19:00:29 +04:00
|
|
|
char *start, *end;
|
|
|
|
|
2006-06-22 16:26:55 +04:00
|
|
|
if (!i)
|
|
|
|
return;
|
|
|
|
|
2006-06-23 13:34:10 +04:00
|
|
|
blitz_drawbg(i->blitz->display, i->drawable, i->gc, i->rect, i->color, True);
|
2006-06-29 17:38:09 +04:00
|
|
|
|
2006-06-30 14:21:26 +04:00
|
|
|
h = (i->font->ascent + i->font->descent);
|
|
|
|
yoff = i->rect.y + (i->rect.height - h) / 2 + i->font->ascent;
|
|
|
|
xcursor = xoff = i->rect.x + i->rect.height / 2;
|
2006-06-22 16:26:55 +04:00
|
|
|
|
2006-06-30 14:25:03 +04:00
|
|
|
start = i->curstart;
|
|
|
|
end = i->curend;
|
|
|
|
if(i->curstart && i->curend) {
|
|
|
|
if(i->curstart < i->curend) {
|
|
|
|
start = i->curstart;
|
|
|
|
end = i->curend;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
start = i->curend;
|
|
|
|
end = i->curstart;
|
|
|
|
}
|
2006-06-29 19:00:29 +04:00
|
|
|
}
|
2006-06-30 16:29:49 +04:00
|
|
|
else if(i->curend) { /* && !i->curstart */
|
|
|
|
start = i->curend;
|
|
|
|
end = nil;
|
|
|
|
}
|
2006-06-29 19:00:29 +04:00
|
|
|
|
2006-06-22 16:26:55 +04:00
|
|
|
/* draw normal text */
|
2006-06-23 12:47:07 +04:00
|
|
|
xchangegc(i, &i->color, False);
|
2006-06-29 19:00:29 +04:00
|
|
|
xdrawtextpart(i, i->text, start, &xoff, yoff);
|
2006-06-30 14:21:26 +04:00
|
|
|
xcursor = xoff;
|
2006-06-22 16:26:55 +04:00
|
|
|
/* draw sel text */
|
2006-06-23 12:47:07 +04:00
|
|
|
xchangegc(i, &i->color, True);
|
2006-06-29 19:00:29 +04:00
|
|
|
xdrawtextpart(i, start, end, &xoff, yoff);
|
2006-06-22 16:26:55 +04:00
|
|
|
/* draw remaining normal text */
|
2006-06-23 12:47:07 +04:00
|
|
|
xchangegc(i, &i->color, False);
|
2006-06-29 19:00:29 +04:00
|
|
|
xdrawtextpart(i, end, nil, &xoff, yoff);
|
2006-06-30 14:21:26 +04:00
|
|
|
|
|
|
|
/* draw cursor */
|
|
|
|
if(!start && !end)
|
|
|
|
xcursor = xoff;
|
|
|
|
if(start == end)
|
|
|
|
blitz_drawcursor(i->blitz->display, i->drawable, i->gc,
|
|
|
|
xcursor, yoff - h + 2, h - 1, i->color);
|
2006-06-29 17:38:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
Bool
|
|
|
|
blitz_ispointinrect(int x, int y, XRectangle * r)
|
|
|
|
{
|
|
|
|
return (x >= r->x) && (x <= r->x + r->width)
|
|
|
|
&& (y >= r->y) && (y <= r->y + r->height);
|
2006-06-22 16:26:55 +04:00
|
|
|
}
|
|
|
|
|
2006-06-28 10:30:49 +04:00
|
|
|
static char *
|
2006-06-29 18:47:26 +04:00
|
|
|
xcharof(BlitzInput *i, int x, char *start, unsigned int len)
|
2006-06-22 16:26:55 +04:00
|
|
|
{
|
2006-07-01 14:52:44 +04:00
|
|
|
unsigned int tw;
|
2006-06-29 18:47:26 +04:00
|
|
|
|
2006-07-01 14:52:44 +04:00
|
|
|
while((len /= 2)) {
|
|
|
|
tw = blitz_textwidth_l(i->font, start, len);
|
2006-06-29 18:47:26 +04:00
|
|
|
|
2006-07-01 14:52:44 +04:00
|
|
|
if(x >= tw) {
|
|
|
|
x -= tw;
|
|
|
|
start += len;
|
|
|
|
len = strlen(start);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return start; /* found */
|
2006-06-29 18:47:26 +04:00
|
|
|
}
|
2006-06-22 16:26:55 +04:00
|
|
|
|
2006-06-29 18:47:26 +04:00
|
|
|
static char *
|
|
|
|
charof(BlitzInput *i, int x, int y)
|
|
|
|
{
|
2006-06-30 14:21:26 +04:00
|
|
|
unsigned int len;
|
|
|
|
|
2006-06-29 17:38:09 +04:00
|
|
|
if(!i->text || !blitz_ispointinrect(x, y, &i->rect))
|
2006-06-22 16:26:55 +04:00
|
|
|
return nil;
|
|
|
|
|
2006-06-30 14:21:26 +04:00
|
|
|
len = strlen(i->text);
|
|
|
|
/* normalize and check x */
|
2006-06-29 19:09:17 +04:00
|
|
|
if((x -= (i->rect.x + i->rect.height / 2)) < 0)
|
2006-06-30 14:21:26 +04:00
|
|
|
return i->text;
|
|
|
|
else if(x > blitz_textwidth_l(i->font, i->text, len))
|
2006-06-22 16:26:55 +04:00
|
|
|
return nil;
|
2006-06-29 18:47:26 +04:00
|
|
|
|
2006-06-29 19:09:17 +04:00
|
|
|
return xcharof(i, x, i->text, strlen(i->text));
|
2006-06-28 10:30:49 +04:00
|
|
|
}
|
|
|
|
|
2006-06-30 16:10:03 +04:00
|
|
|
void
|
|
|
|
blitz_focusin_input(BlitzInput *i)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
blitz_focusout_input(BlitzInput *i)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2006-06-28 10:30:49 +04:00
|
|
|
Bool
|
|
|
|
blitz_bpress_input(BlitzInput *i, int x, int y)
|
|
|
|
{
|
|
|
|
char *ostart, *oend;
|
|
|
|
|
2006-06-29 13:53:45 +04:00
|
|
|
if(!(i->drag = blitz_ispointinrect(x, y, &i->rect)))
|
2006-06-28 10:30:49 +04:00
|
|
|
return False;
|
|
|
|
ostart = i->curstart;
|
|
|
|
oend = i->curend;
|
|
|
|
i->curstart = i->curend = charof(i, x, y);
|
2006-06-29 13:53:45 +04:00
|
|
|
return (i->curstart == ostart) && (i->curend == oend);
|
2006-06-28 10:30:49 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
Bool
|
|
|
|
blitz_brelease_input(BlitzInput *i, int x, int y)
|
|
|
|
{
|
|
|
|
char *oend;
|
|
|
|
|
2006-06-30 16:29:49 +04:00
|
|
|
if(!(i->drag = blitz_ispointinrect(x, y, &i->rect)))
|
2006-06-28 10:30:49 +04:00
|
|
|
return False;
|
|
|
|
oend = i->curend;
|
|
|
|
i->curend = charof(i, x, y);
|
|
|
|
i->drag = False;
|
2006-06-29 13:53:45 +04:00
|
|
|
return i->curend == oend;
|
2006-06-28 10:30:49 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
Bool
|
|
|
|
blitz_bmotion_input(BlitzInput *i, int x, int y)
|
|
|
|
{
|
|
|
|
char *oend;
|
|
|
|
|
2006-06-30 16:29:49 +04:00
|
|
|
if(!i->drag || !(i->drag = blitz_ispointinrect(x, y, &i->rect)))
|
2006-06-28 10:30:49 +04:00
|
|
|
return False;
|
|
|
|
|
|
|
|
oend = i->curend;
|
|
|
|
i->curend = charof(i, x, y);
|
2006-06-29 13:53:45 +04:00
|
|
|
return i->curend == oend;
|
2006-06-28 10:30:49 +04:00
|
|
|
}
|