1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-19 12:28:22 +01:00

WMSetTextSeelctionFont/Color

This commit is contained in:
nwanua
2000-07-17 00:12:29 +00:00
parent 6ec980095a
commit ec6dce9c42
2 changed files with 412 additions and 319 deletions

View File

@@ -384,6 +384,8 @@ main(int argc, char **argv)
WMRulerMargins margins;
void *tb = NULL;
printf("copy and paste this string: \n
here is some <b> bold <i>italic <u>underlined</u> </i> </b> text :-) \n");
WMInitializeApplication("WMText", &argc, argv);
dpy = XOpenDisplay(NULL);
@@ -420,6 +422,7 @@ main(int argc, char **argv)
//margins = WMGetTextRulerMargins(text);
#if 1
WMAppendTextStream(text,
@@ -545,6 +548,7 @@ write something like a trivial tic-tac-toe game ");
WMAppendTextStream(text, " without knowing much Xlib. "
"<p><p>(BTW, don't <i>press</i> that button that is <u>screeming</u>"
" to be pressed!");
#endif

View File

@@ -18,12 +18,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* README README README README README README README
* Nwanua: dont use // style comments please!
* It doesnt work in lots of compilers out there :/
* -Alfredo
* README README README README README README README
*/
#include "WINGsP.h"
#include <X11/keysym.h>
@@ -39,9 +33,6 @@ use currentTextBlock and neighbours for fast paint and layout
WMGetTextStreamAll... WMGetTextStream WMGetTextSelection(if (selected) )
the bitfield arrangement in this code assumes a little-endian
machine... might need a __BIG_ENDIAN__ define for arranging
the bitfields efficiently for those big boys.
#endif
@@ -83,6 +74,7 @@ typedef struct _TextBlock {
Section *sections; /* the region for layouts (a growable array) */
/* an _array_! of size _nsections_ */
unsigned short used; /* number of chars in this block */
unsigned short allocated; /* size of allocation (in chars) */
@@ -147,6 +139,7 @@ typedef struct W_Text {
WMBag *gfxItems; /* a nice bag containing graphic items */
WMHandlerID timerID; /* for nice twinky-winky */
WMPoint clicked; /* where in the _document_ was clicked */
unsigned short tpos; /* the character position in the currentTextBlock */
unsigned short RESERVED;/* space taker upper... */
@@ -358,12 +351,13 @@ paintText(Text *tPtr)
} } } }
if(tPtr->cursor.x != -23) {
if (tPtr->flags.cursorShown && tPtr->cursor.x != -23
&& tPtr->flags.focused) {
int y = tPtr->cursor.y - tPtr->vpos;
XDrawLine(dpy, tPtr->db, tPtr->fgGC,
tPtr->cursor.x, y,
tPtr->cursor.x, y + tPtr->cursor.h);
printf("%d %d %d\n", tPtr->cursor.x, tPtr->cursor.y, tPtr->cursor.h);
//printf("%d %d %d\n", tPtr->cursor.x, tPtr->cursor.y, tPtr->cursor.h);
}
_copy_area:
@@ -391,16 +385,34 @@ _copy_area:
}
#define CURSOR_BLINK_ON_DELAY 600
#define CURSOR_BLINK_OFF_DELAY 400
static void
blinkCursor(void *data)
{
Text *tPtr = (Text*)data;
if (tPtr->flags.cursorShown) {
tPtr->timerID = WMAddTimerHandler(CURSOR_BLINK_OFF_DELAY,
blinkCursor, data);
} else {
tPtr->timerID = WMAddTimerHandler(CURSOR_BLINK_ON_DELAY,
blinkCursor, data);
}
paintText(tPtr);
tPtr->flags.cursorShown = !tPtr->flags.cursorShown;
}
static TextBlock *
getFirstNonGraphicBlockFor(TextBlock *tb)
getFirstNonGraphicBlockFor(TextBlock *tb, short dir)
{
if (!tb)
return NULL;
while(tb) {
if (!tb->graphic)
break;
tb = tb->next;
tb = (dir? tb->next : tb->prior);
}
return tb;
@@ -414,7 +426,6 @@ cursorToTextPosition(Text *tPtr, int x, int y)
int done=False, s, pos, len, _w, _y, dir=1; /* 1 == "down" */
char *text;
y += (tPtr->vpos - tPtr->visible.y);
if (y<0)
y = 0;
@@ -427,8 +438,6 @@ cursorToTextPosition(Text *tPtr, int x, int y)
tPtr->clicked.x = x;
tPtr->clicked.y = y;
/* first, which direction? Most likely, newly clicked
position will be close to previous */
if (! (tb = tPtr->currentTextBlock)) {
if (! (tb = tPtr->firstTextBlock)) {
tPtr->tpos = 0;
@@ -436,23 +445,32 @@ cursorToTextPosition(Text *tPtr, int x, int y)
}
}
/* first, which direction? Most likely, newly clicked
position will be close to previous */
dir = !(y < tb->sections[0].y);
tb = tPtr->firstTextBlock;
dir = 1;
dir = 0;
tb = tPtr->lastTextBlock;
printf("%s\n", dir?"down":"up");
if (tPtr->flags.monoFont && tb->graphic) {
tb = getFirstNonGraphicBlockFor(tb);
tb = getFirstNonGraphicBlockFor(tb, 1);
if (!tb) {
tPtr->currentTextBlock = tPtr->firstTextBlock;
tPtr->currentTextBlock =
(dir? tPtr->lastTextBlock : tPtr->firstTextBlock);
tPtr->tpos = 0;
return;
}
}
if(y == tb->sections[0].y)
s = (dir? 0 : tb->nsections-1);
if ( y >= tb->sections[s]._y
&& y <= tb->sections[s]._y + tb->sections[s].h) {
printf("got it\n");
goto _doneV;
}
/* get the first section of the first visible TextBlock */
/* get the first section of the TextBlock that lies about
the vertical click point */
done = False;
while(!done && tb) {
@@ -462,18 +480,14 @@ dir = 1;
}
s = (dir? 0 : tb->nsections-1);
while( (dir? (s<tb->nsections) : (s>=0) )) {
//printf("y:%d top:%d, bot%d :",
//y, tb->sections[s]._y, tb->sections[s].y + tb->sections[s].h);
//output(tb->text, tb->used);
while(!done && (dir? (s<tb->nsections) : (s>=0) )) {
if ( y >= tb->sections[s]._y
&& y <= tb->sections[s].y + tb->sections[s].h) {
&& y <= tb->sections[s]._y + tb->sections[s].h) {
done = True;
break;
} else {
dir? s++ : s--;
}
}
if (!done) {
@@ -481,86 +495,101 @@ dir = 1;
tb = (dir ? tb->next : tb->prior);
} else {
pos = tb->used;
goto _doneH;
break; //goto _doneH;
}
}
}
_doneV:
if (s<0 || s>=tb->nsections) {
s = (dir? tb->nsections-1 : 0);
}
_doneV:
/* we have the line, which TextBlock on that line is it? */
pos = 0;
if (tPtr->flags.monoFont && tb->graphic)
tb = getFirstNonGraphicBlockFor(tb);
tb = getFirstNonGraphicBlockFor(tb, dir);
if (tb) {
if(tb->sections[s].x >= x)
goto _doneH;
if ((dir? tb->sections[s].x >= x : tb->sections[s].x < x))
; //goto _doneH;
_y = tb->sections[s]._y;
}
while(tb) {
if (tPtr->flags.monoFont && tb->graphic) {
tb = tb->next;
tb = (dir ? tb->next : tb->prior);
continue;
}
if (dir) {
if (tb->graphic) {
_w = WMWidgetWidth(tb->d.widget);
} else {
text = &(tb->text[tb->sections[s].begin]);
len = tb->sections[s].end - tb->sections[s].begin;
_w = WMWidthOfString(tb->d.font, text, len);
}
if (tb->sections[s].x + _w >= x)
break;
if(tb->next) {
TextBlock *nxt = tb->next;
}
} else {
if (tb->sections[s].x <= x)
break;
}
#if 0
if ((dir? tb->next : tb->prior)) {
TextBlock *nxt = (dir? tb->next : tb->prior);
if (tPtr->flags.monoFont && nxt->graphic) {
nxt = getFirstNonGraphicBlockFor(nxt);
nxt = getFirstNonGraphicBlockFor(nxt, dir);
if (!nxt) {
pos = 0;
goto _doneH;
}
}
if (_y != nxt->sections[s]._y) {
/* this must be the last on this line. stop */
pos = tb->used;
/* this must be the last/first on this line. stop */
pos = (dir? tb->used : 0);
goto _doneH;
}
}
#endif
s = 0;
tb = tb->next;
tb = (dir ? tb->next : tb->prior);
if (tb)
s = (dir? 0 : tb->nsections-1);
}
/* we have said TextBlock, now where within it? */
if (tb && !tb->graphic) {
WMFont *f = tb->d.font;
len = tb->sections[s].end - tb->sections[s].begin;
text = &(tb->text[tb->sections[s].begin]);
_w = x - tb->sections[s].x;
pos = 0;
while(pos<len && WMWidthOfString(tb->d.font, text, pos+1) < _w)
while(pos<len && WMWidthOfString(f, text, pos+1) < _w)
pos++;
tPtr->cursor.x = tb->sections[s].x +
(pos? WMWidthOfString(f, text, pos) : 0);
pos += tb->sections[s].begin;
_doneH:
tPtr->tpos = (pos<tb->used)? pos : tb->used;
}
tPtr->currentTextBlock = tb;
tPtr->flags.cursorShown;
tPtr->cursor.h = tb->sections[s].h;
tPtr->cursor.y = _y;
tPtr->cursor.x = tPtr->clicked.x; //WMWidthOfString(tb->d.font, text,
tPtr->cursor.y = tb->sections[s]._y;
paintText(tPtr);
if (!tb)
printf("will hang :-)\n");
paintText(tPtr);
}
@@ -778,7 +807,8 @@ output(char *ptr, int len)
char s[len+1];
memcpy(s, ptr, len);
s[len] = 0;
printf(" s is [%s] (%d)\n", s, strlen(s));
//printf(" s is [%s] (%d)\n", s, strlen(s));
printf("[%s]\n", s);
}
@@ -838,6 +868,7 @@ printf("2 prev_y %d \n\n", tb->sections[tb->nsections-1]._y);
}
if (tb->first) {
output(tb->text, tb->used);
y += layOutLine(tPtr, items, nitems, x, y, pwidth, align);
x = 0;//tPtr->visible.x+2;
nitems = 0;
@@ -1007,6 +1038,26 @@ reqBlockSize(unsigned short requested)
return requested + 16 - (requested%16);
}
static void
clearText(Text *tPtr)
{
void *tb;
if (!tPtr->firstTextBlock)
return;
while(tPtr->currentTextBlock)
WMDestroyTextBlock(tPtr, WMRemoveTextBlock(tPtr));
printf("yadda clearText\n");
printf("remove the document\n");
tPtr->firstTextBlock = NULL;
tPtr->currentTextBlock = NULL;
tPtr->lastTextBlock = NULL;
//WMThawText(tPtr);
WMRefreshText(tPtr, 0, 0);
}
static void
deleteTextInteractively(Text *tPtr, KeySym ksym)
{
@@ -1031,11 +1082,15 @@ insertTextInteractively(Text *tPtr, char *text, int len)
}
}
if (*text == 'a')
WMSetTextSelectionColor(tPtr, WMCreateNamedColor(tPtr->view->screen,
"blue", False));
tb = tPtr->currentTextBlock;
if (!tb || tb->graphic) {
WMAppendTextStream(tPtr, text);
if (tPtr->currentTextBlock) {
tPtr->tpos = tPtr->currentTextBlock->used-4;
tPtr->tpos = tPtr->currentTextBlock->used;
}
return;
}
@@ -1230,7 +1285,6 @@ printf("toggle ruler\n");
releaseSelection(tPtr);
}
static void
handleWidgetPress(XEvent *event, void *data)
{
@@ -1247,15 +1301,15 @@ handleWidgetPress(XEvent *event, void *data)
tPtr = (Text*)w;
printf("%p clicked on tb %p wif: (%c)%c", tPtr, tb,
tPtr->firstTextBlock->text[0], tPtr->firstTextBlock->text[1]);
tPtr->currentTextBlock = getFirstNonGraphicBlockFor(tb);
tPtr->currentTextBlock = getFirstNonGraphicBlockFor(tb, 1);
if (!tPtr->currentTextBlock)
tPtr->currentTextBlock = tb;
tPtr->tpos = 0;
output(tPtr->currentTextBlock->text, tPtr->currentTextBlock->used);
if(!tPtr->flags.focused) {
WMSetFocusToWidget(tPtr);
tPtr->flags.focused = True;
}
//if (!tPtr->flags.focused) {
// WMSetFocusToWidget(tPtr);
// tPtr->flags.focused = True;
//}
}
@@ -1274,6 +1328,8 @@ handleActionEvents(XEvent *event, void *data)
case KeyPress:
ksym = XLookupKeysym((XKeyEvent*)event, 0);
if (ksym == XK_Shift_R || ksym == XK_Shift_L) {
WMSetTextSelectionFont(tPtr, WMBoldSystemFontOfSize(
tPtr->view->screen, 18));
tPtr->flags.extendSelection = True;
return;
}
@@ -1288,7 +1344,7 @@ handleActionEvents(XEvent *event, void *data)
XGrabPointer(dpy, W_VIEW(tPtr)->window, False,
PointerMotionMask|ButtonPressMask|ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, None,
W_VIEW(tPtr)->screen->invisibleCursor, CurrentTime);
tPtr->view->screen->invisibleCursor, CurrentTime);
tPtr->flags.pointerGrabbed = True;
handleTextKeyPress(tPtr, event);
@@ -1327,6 +1383,12 @@ handleActionEvents(XEvent *event, void *data)
return;
}
if (event->xbutton.button == Button1) {
if (!tPtr->flags.focused) {
WMSetFocusToWidget(tPtr);
tPtr->flags.focused = True;
}
if (tPtr->flags.ownsSelection)
releaseSelection(tPtr);
cursorToTextPosition(tPtr, event->xmotion.x, event->xmotion.y);
@@ -1336,11 +1398,6 @@ handleActionEvents(XEvent *event, void *data)
break;
}
}
if(!tPtr->flags.focused) {
WMSetFocusToWidget(tPtr);
tPtr->flags.focused = True;
break;
}
if (event->xbutton.button == WINGsConfiguration.mouseWheelDown)
WMScrollText(tPtr, -16);
@@ -1396,13 +1453,24 @@ handleEvents(XEvent *event, void *data)
break;
case FocusIn:
if (W_FocusedViewOfToplevel(W_TopLevelOfView(tPtr->view))!=tPtr->view)
if (W_FocusedViewOfToplevel(W_TopLevelOfView(tPtr->view))
!= tPtr->view)
return;
tPtr->flags.focused = True;
if (!tPtr->timerID) {
tPtr->timerID = WMAddTimerHandler(12+0*CURSOR_BLINK_ON_DELAY,
blinkCursor, tPtr);
}
break;
case FocusOut:
tPtr->flags.focused = False;
paintText(tPtr);
if (tPtr->timerID) {
WMDeleteTimerHandler(tPtr->timerID);
tPtr->timerID = NULL;
}
break;
case DestroyNotify:
@@ -1415,26 +1483,6 @@ handleEvents(XEvent *event, void *data)
static void
clearText(Text *tPtr)
{
void *tb;
if(!tPtr->firstTextBlock)
return;
while(tPtr->currentTextBlock)
WMDestroyTextBlock(tPtr, WMRemoveTextBlock(tPtr));
printf("yadda clearText\n");
printf("remove the document\n");
tPtr->firstTextBlock = NULL;
tPtr->currentTextBlock = NULL;
tPtr->lastTextBlock = NULL;
//WMThawText(tPtr);
WMRefreshText(tPtr, 0, 0);
}
static void
insertPlainText(WMText *tPtr, char *text)
@@ -1490,7 +1538,6 @@ WMCreateText(WMWidget *parent)
#if 0
printf("sizeof:\n");
printf(" TextBlock %d\n", sizeof(TextBlock));
printf(" TextBlock *%d\n", sizeof(TextBlock *));
printf(" Section %d\n", sizeof(Section));
printf(" char * %d\n", sizeof(char *));
printf(" void * %d\n", sizeof(void *));
@@ -1531,6 +1578,8 @@ WMCreateText(WMWidget *parent)
tPtr->view->delegate = &_TextViewDelegate;
tPtr->timerID = NULL;
WMCreateEventHandler(tPtr->view, ExposureMask|StructureNotifyMask
|EnterWindowMask|LeaveWindowMask|FocusChangeMask,
handleEvents, tPtr);
@@ -1815,6 +1864,7 @@ WMAppendTextBlock(WMText *tPtr, void *vtb)
if (tb->graphic) {
WMWidget *w = tb->d.widget;
return;
WMCreateEventHandler(W_VIEW(w), ButtonPressMask,
handleWidgetPress, tb);
if (W_CLASS(w) != WC_TextField && W_CLASS(w) != WC_Text) {
@@ -1893,9 +1943,13 @@ WMDestroyTextBlock(WMText *tPtr, void *vtb)
return;
if (tb->graphic) {
return;
WMDestroyWidget(tb->d.widget);
wfree(tb->d.widget);
/* naturally, there's a danger to destroying
widgets whose action brings us here:
ie. press a button to destroy it... need to
find a safer way. till then... this stays commented out */
//WMDestroyWidget(tb->d.widget);
//wfree(tb->d.widget);
tb->d.widget = NULL;
} else {
WMReleaseFont(tb->d.font);
}
@@ -2125,4 +2179,39 @@ WMGetTextInsertType(WMText *tPtr)
}
void
WMSetTextSelectionColor(WMText *tPtr, WMColor *color)
{
TextBlock *tb;
if (!tPtr || !color)
return;
tb = tPtr->firstTextBlock;
if (!tb || !tPtr->flags.ownsSelection)
return;
while(tb) {
tb->color = WMRetainColor(color);
tb = tb->next;
}
WMRefreshText(tPtr, tPtr->vpos, tPtr->hpos);
}
void
WMSetTextSelectionFont(WMText *tPtr, WMFont *font)
{
TextBlock *tb;
if (!tPtr || !font)
return;
tb = tPtr->firstTextBlock;
if (!tb || !tPtr->flags.ownsSelection)
return;
while(tb) {
if (!tb->graphic)
tb->d.font = WMRetainFont(font);
tb = tb->next;
}
WMRefreshText(tPtr, tPtr->vpos, tPtr->hpos);
}