1
0
mirror of https://github.com/gryf/wmaker.git synced 2026-02-15 13:35:53 +01:00

0.51.1 pre snapshot. Be careful, it may be buggy. It fixes some bugs though.

This commit is contained in:
dan
1999-02-17 11:06:40 +00:00
parent 931a37b124
commit e7495baff7
189 changed files with 16952 additions and 9682 deletions

View File

@@ -22,8 +22,10 @@ typedef struct W_TextField {
W_Class widgetClass;
W_View *view;
#if 0
struct W_TextField *nextField; /* next textfield in the chain */
struct W_TextField *prevField;
#endif
char *text;
int textLen; /* size of text */
@@ -39,6 +41,8 @@ typedef struct W_TextField {
WMRange selection;
WMRange prevselection;
WMFont *font;
#if 0
WMHandlerID timerID; /* for cursor blinking */
#endif
@@ -46,13 +50,15 @@ typedef struct W_TextField {
WMAlignment alignment:2;
unsigned int bordered:1;
unsigned int beveled:1;
unsigned int enabled:1;
unsigned int focused:1;
unsigned int cursorOn:1;
unsigned int secure:1; /* password entry style */
/**/
@@ -97,11 +103,11 @@ struct W_ViewProcedureTable _TextFieldViewProcedures = {
};
#define TEXT_WIDTH(tPtr, start) (WMWidthOfString((tPtr)->view->screen->normalFont, \
&((tPtr)->text[(start)]), (tPtr)->textLen - (start) + 1))
#define TEXT_WIDTH(tPtr, start) (WMWidthOfString((tPtr)->font, \
&((tPtr)->text[(start)]), (tPtr)->textLen - (start) + 1))
#define TEXT_WIDTH2(tPtr, start, end) (WMWidthOfString((tPtr)->view->screen->normalFont, \
&((tPtr)->text[(start)]), (end) - (start) + 1))
#define TEXT_WIDTH2(tPtr, start, end) (WMWidthOfString((tPtr)->font, \
&((tPtr)->text[(start)]), (end) - (start) + 1))
static void
@@ -163,7 +169,6 @@ WMCreateTextField(WMWidget *parent)
{
TextField *tPtr;
tPtr = wmalloc(sizeof(TextField));
memset(tPtr, 0, sizeof(TextField));
@@ -185,24 +190,28 @@ WMCreateTextField(WMWidget *parent)
tPtr->text[0] = 0;
tPtr->textLen = 0;
tPtr->bufferSize = MIN_TEXT_BUFFER;
tPtr->flags.enabled = 1;
WMCreateEventHandler(tPtr->view, ExposureMask|StructureNotifyMask
|FocusChangeMask, handleEvents, tPtr);
W_ResizeView(tPtr->view, DEFAULT_WIDTH, DEFAULT_HEIGHT);
WMSetTextFieldBordered(tPtr, DEFAULT_BORDERED);
tPtr->font = WMRetainFont(tPtr->view->screen->normalFont);
tPtr->flags.bordered = DEFAULT_BORDERED;
tPtr->flags.beveled = True;
tPtr->flags.alignment = DEFAULT_ALIGNMENT;
tPtr->offsetWidth = (tPtr->view->size.height
- WMFontHeight(tPtr->view->screen->normalFont))/2;
tPtr->offsetWidth =
WMAX((tPtr->view->size.height - WMFontHeight(tPtr->font))/2, 1);
WMCreateEventHandler(tPtr->view, EnterWindowMask|LeaveWindowMask
|ButtonPressMask|KeyPressMask|Button1MotionMask,
handleTextFieldActionEvents, tPtr);
tPtr->flags.cursorOn = 1;
return tPtr;
}
@@ -311,10 +320,6 @@ WMGetTextFieldText(WMTextField *tPtr)
void
WMSetTextFieldText(WMTextField *tPtr, char *text)
{
/* We do not set text if it's the same. This will also help
* to avoid some infinite loops if this function is called from
* a function called by a notification observer. -Dan
*/
if ((text && strcmp(tPtr->text, text) == 0) ||
(!text && tPtr->textLen == 0))
return;
@@ -347,6 +352,14 @@ WMSetTextFieldText(WMTextField *tPtr, char *text)
}
void
WMSetTextFieldFont(WMTextField *tPtr, WMFont *font)
{
/* TODO: update font change after field is mapped */
WMReleaseFont(tPtr->font);
tPtr->font = WMRetainFont(font);
}
void
WMSetTextFieldAlignment(WMTextField *tPtr, WMAlignment alignment)
{
@@ -373,6 +386,17 @@ WMSetTextFieldBordered(WMTextField *tPtr, Bool bordered)
}
void
WMSetTextFieldBeveled(WMTextField *tPtr, Bool flag)
{
tPtr->flags.beveled = flag;
if (tPtr->view->flags.realized) {
paintTextField(tPtr);
}
}
void
WMSetTextFieldSecure(WMTextField *tPtr, Bool flag)
@@ -385,6 +409,13 @@ WMSetTextFieldSecure(WMTextField *tPtr, Bool flag)
}
Bool
WMGetTextFieldEnabled(WMTextField *tPtr)
{
return tPtr->flags.enabled;
}
void
WMSetTextFieldEnabled(WMTextField *tPtr, Bool flag)
{
@@ -438,15 +469,61 @@ WMSetTextFieldCursorPosition(WMTextField *tPtr, unsigned int position)
}
void
WMSetTextFieldNextTextField(WMTextField *tPtr, WMTextField *next)
{
CHECK_CLASS(tPtr, WC_TextField);
if (next == NULL) {
if (tPtr->view->nextFocusChain)
tPtr->view->nextFocusChain->prevFocusChain = NULL;
tPtr->view->nextFocusChain = NULL;
return;
}
CHECK_CLASS(next, WC_TextField);
if (tPtr->view->nextFocusChain)
tPtr->view->nextFocusChain->prevFocusChain = NULL;
if (next->view->prevFocusChain)
next->view->prevFocusChain->nextFocusChain = NULL;
tPtr->view->nextFocusChain = next->view;
next->view->prevFocusChain = tPtr->view;
}
void
WMSetTextFieldPrevTextField(WMTextField *tPtr, WMTextField *prev)
{
CHECK_CLASS(tPtr, WC_TextField);
if (prev == NULL) {
if (tPtr->view->prevFocusChain)
tPtr->view->prevFocusChain->nextFocusChain = NULL;
tPtr->view->prevFocusChain = NULL;
return;
}
CHECK_CLASS(prev, WC_TextField);
if (tPtr->view->prevFocusChain)
tPtr->view->prevFocusChain->nextFocusChain = NULL;
if (prev->view->nextFocusChain)
prev->view->nextFocusChain->prevFocusChain = NULL;
tPtr->view->prevFocusChain = prev->view;
prev->view->nextFocusChain = tPtr->view;
}
static void
resizeTextField(WMTextField *tPtr, unsigned int width, unsigned int height)
{
W_ResizeView(tPtr->view, width, height);
tPtr->offsetWidth = (tPtr->view->size.height
- WMFontHeight(tPtr->view->screen->normalFont))/2;
tPtr->usableWidth = tPtr->view->size.width - 2*tPtr->offsetWidth;
tPtr->offsetWidth =
WMAX((tPtr->view->size.height - WMFontHeight(tPtr->font))/2, 1);
tPtr->usableWidth = tPtr->view->size.width - 2*tPtr->offsetWidth + 2;
}
@@ -457,27 +534,24 @@ paintCursor(TextField *tPtr)
WMScreen *screen = tPtr->view->screen;
int textWidth;
cx = WMWidthOfString(screen->normalFont,
&(tPtr->text[tPtr->viewPosition]),
cx = WMWidthOfString(tPtr->font, &(tPtr->text[tPtr->viewPosition]),
tPtr->cursorPosition-tPtr->viewPosition);
switch (tPtr->flags.alignment) {
case WARight:
textWidth = WMWidthOfString(screen->normalFont, tPtr->text,
tPtr->textLen);
textWidth = WMWidthOfString(tPtr->font, tPtr->text, tPtr->textLen);
if (textWidth < tPtr->usableWidth)
cx += tPtr->offsetWidth + tPtr->usableWidth - textWidth;
cx += tPtr->offsetWidth + tPtr->usableWidth - textWidth + 1;
else
cx += tPtr->offsetWidth;
cx += tPtr->offsetWidth + 1;
break;
case WALeft:
cx += tPtr->offsetWidth;
cx += tPtr->offsetWidth + 1;
break;
case WAJustified:
/* not supported */
case WACenter:
textWidth = WMWidthOfString(screen->normalFont, tPtr->text,
tPtr->textLen);
textWidth = WMWidthOfString(tPtr->font, tPtr->text, tPtr->textLen);
if (textWidth < tPtr->usableWidth)
cx += tPtr->offsetWidth + (tPtr->usableWidth-textWidth)/2;
else
@@ -497,7 +571,7 @@ paintCursor(TextField *tPtr)
static void
drawRelief(WMView *view)
drawRelief(WMView *view, Bool beveled)
{
WMScreen *scr = view->screen;
Display *dpy = scr->display;
@@ -507,8 +581,14 @@ drawRelief(WMView *view)
int width = view->size.width;
int height = view->size.height;
wgc = W_GC(scr->white);
dgc = W_GC(scr->darkGray);
if (!beveled) {
XDrawRectangle(dpy, view->window, dgc, 0, 0, width-1, height-1);
return;
}
wgc = W_GC(scr->white);
lgc = W_GC(scr->gray);
/* top left */
@@ -550,16 +630,15 @@ paintTextField(TextField *tPtr)
totalWidth = tPtr->view->size.width - 2*bd;
if (tPtr->textLen > 0) {
tw = WMWidthOfString(screen->normalFont,
&(tPtr->text[tPtr->viewPosition]),
tw = WMWidthOfString(tPtr->font, &(tPtr->text[tPtr->viewPosition]),
tPtr->textLen - tPtr->viewPosition);
th = WMFontHeight(screen->normalFont);
th = WMFontHeight(tPtr->font);
ty = tPtr->offsetWidth;
switch (tPtr->flags.alignment) {
case WALeft:
tx = tPtr->offsetWidth;
tx = tPtr->offsetWidth + 1;
if (tw < tPtr->usableWidth)
XClearArea(screen->display, view->window, bd+tw, bd,
totalWidth-tw, view->size.height-2*bd,
@@ -575,7 +654,7 @@ paintTextField(TextField *tPtr)
default:
case WARight:
tx = tPtr->offsetWidth + tPtr->usableWidth - tw;
tx = tPtr->offsetWidth + tPtr->usableWidth - tw - 1;
if (tw < tPtr->usableWidth)
XClearArea(screen->display, view->window, bd, bd,
totalWidth-tw, view->size.height-2*bd, False);
@@ -587,7 +666,7 @@ paintTextField(TextField *tPtr)
WMSetColorInGC(screen->darkGray, screen->textFieldGC);
WMDrawImageString(screen, view->window, screen->textFieldGC,
screen->normalFont, tx, ty,
tPtr->font, tx, ty,
&(tPtr->text[tPtr->viewPosition]),
tPtr->textLen - tPtr->viewPosition);
@@ -598,7 +677,7 @@ paintTextField(TextField *tPtr)
? tPtr->selection.position + tPtr->selection.count
: tPtr->selection.position;
rx = tx + WMWidthOfString(screen->normalFont,
rx = tx + WMWidthOfString(tPtr->font,
&(tPtr->text[tPtr->viewPosition]),
count);
@@ -606,8 +685,7 @@ paintTextField(TextField *tPtr)
screen->gray->color.pixel);
WMDrawImageString(screen, view->window, screen->textFieldGC,
screen->normalFont, rx, ty,
&(tPtr->text[count]),
tPtr->font, rx, ty, &(tPtr->text[count]),
abs(tPtr->selection.count));
XSetBackground(screen->display, screen->textFieldGC,
@@ -630,7 +708,7 @@ paintTextField(TextField *tPtr)
/* draw relief */
if (tPtr->flags.bordered) {
drawRelief(view);
drawRelief(view, tPtr->flags.beveled);
}
}
@@ -715,7 +793,6 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
KeySym ksym;
int count, refresh = 0;
int control_pressed = 0;
WMScreen *scr = tPtr->view->screen;
if (((XKeyEvent *) event)->state & WM_EMACSKEYMASK) {
control_pressed = 1;
@@ -733,9 +810,9 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
}
/* Be careful in any case in this switch statement, never to call
* to more than 2 functions at the same time, that can generate text
* change notifications. Only one text change notification should be sent
* in any case. Else hazardous things can happen.
* to more than a function that can generate text change notifications.
* Only one text change notification should be sent in any case.
* Else hazardous things can happen.
* Maybe we need a better solution than the function wrapper to inform
* functions that change text in text fields, if they need to send a
* change notification or not. -Dan
@@ -811,7 +888,7 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
} else {
tPtr->cursorPosition++;
}
while (WMWidthOfString(scr->normalFont,
while (WMWidthOfString(tPtr->font,
&(tPtr->text[tPtr->viewPosition]),
tPtr->cursorPosition-tPtr->viewPosition)
> tPtr->usableWidth) {
@@ -851,7 +928,7 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
paintCursor(tPtr);
tPtr->cursorPosition = tPtr->textLen;
tPtr->viewPosition = 0;
while (WMWidthOfString(scr->normalFont,
while (WMWidthOfString(tPtr->font,
&(tPtr->text[tPtr->viewPosition]),
tPtr->textLen-tPtr->viewPosition)
> tPtr->usableWidth) {
@@ -870,6 +947,7 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
case XK_BackSpace:
if (tPtr->cursorPosition > 0) {
WMRange range;
if (tPtr->prevselection.count) {
range.position = tPtr->prevselection.count < 0
? tPtr->prevselection.position + tPtr->prevselection.count
@@ -892,6 +970,7 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
case XK_Delete:
if (tPtr->cursorPosition < tPtr->textLen || tPtr->prevselection.count) {
WMRange range;
if (tPtr->prevselection.count) {
range.position = tPtr->prevselection.count < 0
? tPtr->prevselection.position + tPtr->prevselection.count
@@ -910,6 +989,7 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
default:
if (count > 0 && !iscntrl(buffer[0])) {
WMRange range;
if (tPtr->prevselection.count) {
range.position = tPtr->prevselection.count < 0
? tPtr->prevselection.position + tPtr->prevselection.count
@@ -944,7 +1024,6 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
static int
pointToCursorPosition(TextField *tPtr, int x)
{
WMFont *font = tPtr->view->screen->normalFont;
int a, b, mid;
int tw;
@@ -953,13 +1032,13 @@ pointToCursorPosition(TextField *tPtr, int x)
a = tPtr->viewPosition;
b = tPtr->viewPosition + tPtr->textLen;
if (WMWidthOfString(font, &(tPtr->text[tPtr->viewPosition]),
if (WMWidthOfString(tPtr->font, &(tPtr->text[tPtr->viewPosition]),
tPtr->textLen-tPtr->viewPosition) < x)
return tPtr->textLen;
while (a < b && b-a>1) {
mid = (a+b)/2;
tw = WMWidthOfString(font, &(tPtr->text[tPtr->viewPosition]),
tw = WMWidthOfString(tPtr->font, &(tPtr->text[tPtr->viewPosition]),
mid - tPtr->viewPosition);
if (tw > x)
b = mid;
@@ -981,7 +1060,7 @@ handleTextFieldActionEvents(XEvent *event, void *data)
switch (event->type) {
case KeyPress:
if (tPtr->flags.enabled)
if (tPtr->flags.enabled && tPtr->flags.focused)
handleTextFieldKeyPress(tPtr, event);
break;
@@ -1045,7 +1124,9 @@ destroyTextField(TextField *tPtr)
if (tPtr->timerID)
WMDeleteTimerHandler(tPtr->timerID);
#endif
WMReleaseFont(tPtr->font);
if (tPtr->text)
free(tPtr->text);