static void handleEvents(XEvent * event, void *data) { Label *lPtr = (Label *) data; CHECK_CLASS(data, WC_Label); switch (event->type) { case Expose: if (event->xexpose.count != 0) break; paintLabel(lPtr); break; case DestroyNotify: destroyLabel(lPtr); break; } }
void WMRemoveSplitViewSubview(WMSplitView * sPtr, WMView * view) { W_SplitViewSubview *p; int i, count; CHECK_CLASS(sPtr, WC_SplitView); /* TODO: rewrite this. This code with macros is getting more complex than it worths */ count = _GetSubviewsCount(); for (i = 0; i < count; i++) { p = _GetPSubviewStructAt(i); if (p->view == view) { WMDeleteFromArray(sPtr->subviews, i); sPtr->flags.adjustOnPaint = 1; paintSplitView(sPtr); break; } } }
void WMSetScrollerParameters(WMScroller * sPtr, float floatValue, float knobProportion) { /* * This value represents 1 pixel on a 4k wide screen, it makes * a good minimum; this ensure a non-null value to avoid * potential division-by-0. * Please note that there is another size check when drawing * the knob to make sure it will remain selectable. */ static const float min_knob_proportion = 1.0 / 4096.0; CHECK_CLASS(sPtr, WC_Scroller); assert(!isnan(floatValue)); if (floatValue < 0.0) sPtr->floatValue = 0.0; else if (floatValue > 1.0) sPtr->floatValue = 1.0; else sPtr->floatValue = floatValue; if (knobProportion <= min_knob_proportion) { sPtr->knobProportion = min_knob_proportion; sPtr->flags.documentFullyVisible = 0; } else if (knobProportion >= 1.0) { sPtr->knobProportion = 1.0; sPtr->flags.documentFullyVisible = 1; } else { sPtr->knobProportion = knobProportion; sPtr->flags.documentFullyVisible = 0; } if (sPtr->view->flags.realized) paintScroller(sPtr); /* WMPostNotificationName(WMScrollerDidScrollNotification, sPtr, NULL); */ }
void WMInsertTextFieldText(WMTextField * tPtr, const char *text, int position) { int len; CHECK_CLASS(tPtr, WC_TextField); if (!text) return; len = strlen(text); /* check if buffer will hold the text */ if (len + tPtr->textLen >= tPtr->bufferSize) { tPtr->bufferSize = tPtr->textLen + len + TEXT_BUFFER_INCR; tPtr->text = wrealloc(tPtr->text, tPtr->bufferSize); } if (position < 0 || position >= tPtr->textLen) { /* append the text at the end */ wstrlcat(tPtr->text, text, tPtr->bufferSize); tPtr->textLen += len; tPtr->cursorPosition += len; incrToFit(tPtr); } else { /* insert text at position */ memmv(&(tPtr->text[position + len]), &(tPtr->text[position]), tPtr->textLen - position + 1); memcpy(&(tPtr->text[position]), text, len); tPtr->textLen += len; if (position >= tPtr->cursorPosition) { tPtr->cursorPosition += len; incrToFit2(tPtr); } else { incrToFit(tPtr); } } paintTextField(tPtr); }
void WMDeleteTextFieldRange(WMTextField * tPtr, WMRange range) { CHECK_CLASS(tPtr, WC_TextField); normalizeRange(tPtr, &range); if (!range.count) return; memmv(&(tPtr->text[range.position]), &(tPtr->text[range.position + range.count]), tPtr->textLen - (range.position + range.count) + 1); /* better than nothing ;) */ if (tPtr->cursorPosition > range.position) tPtr->viewPosition += oneUTF8CharBackward(&tPtr->text[tPtr->viewPosition], tPtr->viewPosition); tPtr->textLen -= range.count; tPtr->cursorPosition = range.position; decrToFit(tPtr); paintTextField(tPtr); }
static void handleEvents(XEvent *event, void *data) { ScrollView *sPtr = (ScrollView*)data; CHECK_CLASS(data, WC_ScrollView); switch (event->type) { case Expose: if (event->xexpose.count!=0) break; if (event->xexpose.serial == 0) /* means it's artificial */ W_RedisplayView(sPtr->contentView); else paintScrollView(sPtr); break; case DestroyNotify: destroyScrollView(sPtr); break; } }
void WMSetSplitViewConstrainProc(WMSplitView * sPtr, WMSplitViewConstrainProc * proc) { CHECK_CLASS(sPtr, WC_SplitView); sPtr->constrainProc = proc; }
int WMGetSplitViewSubviewsCount(WMSplitView * sPtr) { CHECK_CLASS(sPtr, WC_SplitView); return (_GetSubviewsCount()); }
char *WMGetTextFieldText(WMTextField * tPtr) { CHECK_CLASS(tPtr, WC_TextField); return wstrdup(tPtr->text); }
WMTextFieldDelegate *WMGetTextFieldDelegate(WMTextField * tPtr) { CHECK_CLASS(tPtr, WC_TextField); return tPtr->delegate; }
WMScrollerPart WMGetScrollerHitPart(WMScroller * sPtr) { CHECK_CLASS(sPtr, WC_Scroller); return sPtr->flags.hitPart; }
static void handleActionEvents(XEvent * event, void *data) { Scroller *sPtr = (Scroller *) data; int wheelDecrement, wheelIncrement; int id, dd; /* check if we're really dealing with a scroller, as something * might have gone wrong in the event dispatching stuff */ CHECK_CLASS(sPtr, WC_Scroller); id = sPtr->flags.incrDown; dd = sPtr->flags.decrDown; switch (event->type) { case EnterNotify: break; case LeaveNotify: if (sPtr->timerID) { WMDeleteTimerHandler(sPtr->timerID); sPtr->timerID = NULL; } sPtr->flags.incrDown = 0; sPtr->flags.decrDown = 0; break; case ButtonPress: /* FIXME: change Mod1Mask with something else */ if (sPtr->flags.documentFullyVisible) break; if (sPtr->flags.horizontal) { wheelDecrement = WINGsConfiguration.mouseWheelDown; wheelIncrement = WINGsConfiguration.mouseWheelUp; } else { wheelDecrement = WINGsConfiguration.mouseWheelUp; wheelIncrement = WINGsConfiguration.mouseWheelDown; } if (event->xbutton.button == wheelDecrement) { if (event->xbutton.state & ControlMask) { sPtr->flags.hitPart = WSDecrementPage; } else if (event->xbutton.state & ShiftMask) { sPtr->flags.hitPart = WSDecrementLine; } else { sPtr->flags.hitPart = WSDecrementWheel; } if (sPtr->action) { (*sPtr->action) (sPtr, sPtr->clientData); WMPostNotificationName(WMScrollerDidScrollNotification, sPtr, NULL); } } else if (event->xbutton.button == wheelIncrement) { if (event->xbutton.state & ControlMask) { sPtr->flags.hitPart = WSIncrementPage; } else if (event->xbutton.state & ShiftMask) { sPtr->flags.hitPart = WSIncrementLine; } else { sPtr->flags.hitPart = WSIncrementWheel; } if (sPtr->action) { (*sPtr->action) (sPtr, sPtr->clientData); WMPostNotificationName(WMScrollerDidScrollNotification, sPtr, NULL); } } else { handlePush(sPtr, event->xbutton.x, event->xbutton.y, (event->xbutton.state & Mod1Mask) || event->xbutton.button == Button2); /* continue scrolling if pushed on the buttons */ if (sPtr->flags.hitPart == WSIncrementLine || sPtr->flags.hitPart == WSDecrementLine) { sPtr->timerID = WMAddTimerHandler(AUTOSCROLL_INITIAL_DELAY, autoScroll, sPtr); } } break; case ButtonRelease: if (sPtr->flags.draggingKnob) { if (sPtr->action) { (*sPtr->action) (sPtr, sPtr->clientData); WMPostNotificationName(WMScrollerDidScrollNotification, sPtr, NULL); } } if (sPtr->timerID) { WMDeleteTimerHandler(sPtr->timerID); sPtr->timerID = NULL; } sPtr->flags.incrDown = 0; sPtr->flags.decrDown = 0; sPtr->flags.draggingKnob = 0; break; case MotionNotify: handleMotion(sPtr, event->xbutton.x, event->xbutton.y); if (sPtr->timerID && sPtr->flags.hitPart != WSIncrementLine && sPtr->flags.hitPart != WSDecrementLine) { WMDeleteTimerHandler(sPtr->timerID); sPtr->timerID = NULL; } break; } if (id != sPtr->flags.incrDown || dd != sPtr->flags.decrDown) paintScroller(sPtr); }
void WMSetTextFieldDelegate(WMTextField * tPtr, WMTextFieldDelegate * delegate) { CHECK_CLASS(tPtr, WC_TextField); tPtr->delegate = delegate; }
void WMSetSplitViewResizeSubviewsProc(WMSplitView * sPtr, WMSplitViewResizeSubviewsProc * proc) { CHECK_CLASS(sPtr, WC_SplitView); sPtr->resizeSubviewsProc = proc; }
Bool WMGetSplitViewVertical(WMSplitView * sPtr) { CHECK_CLASS(sPtr, WC_SplitView); return (sPtr->flags.vertical == 1); }
unsigned WMGetTextFieldCursorPosition(WMTextField *tPtr) { CHECK_CLASS(tPtr, WC_TextField); return tPtr->cursorPosition; }
Bool WMGetTextFieldEditable(WMTextField * tPtr) { CHECK_CLASS(tPtr, WC_TextField); return tPtr->flags.enabled; }
int WMGetSplitViewDividerThickness(WMSplitView * sPtr) { CHECK_CLASS(sPtr, WC_SplitView); return (DIVIDER_THICKNESS); }
float WMGetScrollerKnobProportion(WMScroller * sPtr) { CHECK_CLASS(sPtr, WC_Scroller); return sPtr->knobProportion; }
float WMGetScrollerValue(WMScroller * sPtr) { CHECK_CLASS(sPtr, WC_Scroller); return sPtr->floatValue; }
static void handleTextFieldActionEvents(XEvent * event, void *data) { TextField *tPtr = (TextField *) data; static Time lastButtonReleasedEvent = 0; static Time lastButtonReleasedEvent2 = 0; Display *dpy = event->xany.display; CHECK_CLASS(data, WC_TextField); switch (event->type) { case KeyPress: if (tPtr->flags.waitingSelection) { return; } if (tPtr->flags.enabled && tPtr->flags.focused) { handleTextFieldKeyPress(tPtr, event); XDefineCursor(dpy, W_VIEW(tPtr)->window, W_VIEW(tPtr)->screen->invisibleCursor); tPtr->flags.pointerGrabbed = 1; } break; case MotionNotify: if (tPtr->flags.pointerGrabbed) { tPtr->flags.pointerGrabbed = 0; XDefineCursor(dpy, W_VIEW(tPtr)->window, W_VIEW(tPtr)->screen->textCursor); } if (tPtr->flags.waitingSelection) { return; } if (tPtr->flags.enabled && (event->xmotion.state & Button1Mask)) { if (tPtr->viewPosition < tPtr->textLen && event->xmotion.x > tPtr->usableWidth) { if (WMWidthOfString(tPtr->font, &(tPtr->text[tPtr->viewPosition]), tPtr->cursorPosition - tPtr->viewPosition) > tPtr->usableWidth) { tPtr->viewPosition += oneUTF8CharForward(&tPtr->text[tPtr->viewPosition], tPtr->textLen - tPtr->viewPosition); } } else if (tPtr->viewPosition > 0 && event->xmotion.x < 0) { paintCursor(tPtr); tPtr->viewPosition += oneUTF8CharBackward(&tPtr->text[tPtr->viewPosition], tPtr->viewPosition); } tPtr->cursorPosition = pointToCursorPosition(tPtr, event->xmotion.x); /* Do not allow text selection in secure textfields */ if (tPtr->flags.secure) { tPtr->selection.position = tPtr->cursorPosition; } tPtr->selection.count = tPtr->cursorPosition - tPtr->selection.position; paintCursor(tPtr); paintTextField(tPtr); } break; case ButtonPress: if (tPtr->flags.pointerGrabbed) { tPtr->flags.pointerGrabbed = 0; XDefineCursor(dpy, W_VIEW(tPtr)->window, W_VIEW(tPtr)->screen->textCursor); break; } if (tPtr->flags.waitingSelection) { break; } switch (tPtr->flags.alignment) { int textWidth; case WARight: textWidth = WMWidthOfString(tPtr->font, tPtr->text, tPtr->textLen); if (tPtr->flags.enabled && !tPtr->flags.focused) { WMSetFocusToWidget(tPtr); } if (tPtr->flags.focused) { tPtr->selection.position = tPtr->cursorPosition; tPtr->selection.count = 0; } if (textWidth < tPtr->usableWidth) { tPtr->cursorPosition = pointToCursorPosition(tPtr, event->xbutton.x - tPtr->usableWidth + textWidth); } else tPtr->cursorPosition = pointToCursorPosition(tPtr, event->xbutton.x); paintTextField(tPtr); break; case WALeft: if (tPtr->flags.enabled && !tPtr->flags.focused) { WMSetFocusToWidget(tPtr); } if (tPtr->flags.focused && event->xbutton.button == Button1) { tPtr->cursorPosition = pointToCursorPosition(tPtr, event->xbutton.x); tPtr->selection.position = tPtr->cursorPosition; tPtr->selection.count = 0; paintTextField(tPtr); } if (event->xbutton.button == Button2 && tPtr->flags.enabled) { char *text; int n; if (!WMRequestSelection(tPtr->view, XA_PRIMARY, XA_STRING, event->xbutton.time, pasteText, NULL)) { text = XFetchBuffer(tPtr->view->screen->display, &n, 0); if (text) { text[n] = 0; WMInsertTextFieldText(tPtr, text, tPtr->cursorPosition); XFree(text); NOTIFY(tPtr, didChange, WMTextDidChangeNotification, (void *)WMInsertTextEvent); } } else { tPtr->flags.waitingSelection = 1; } } break; default: break; } break; case ButtonRelease: if (tPtr->flags.pointerGrabbed) { tPtr->flags.pointerGrabbed = 0; XDefineCursor(dpy, W_VIEW(tPtr)->window, W_VIEW(tPtr)->screen->textCursor); } if (tPtr->flags.waitingSelection) { break; } if (!tPtr->flags.secure && tPtr->selection.count != 0) { int start, count; XRotateBuffers(dpy, 1); count = abs(tPtr->selection.count); if (tPtr->selection.count < 0) start = tPtr->selection.position - count; else start = tPtr->selection.position; XStoreBuffer(dpy, &tPtr->text[start], count, 0); } if (!tPtr->flags.secure && event->xbutton.time - lastButtonReleasedEvent <= WINGsConfiguration.doubleClickDelay) { if (event->xbutton.time - lastButtonReleasedEvent2 <= 2 * WINGsConfiguration.doubleClickDelay) { tPtr->selection.position = 0; tPtr->selection.count = tPtr->textLen; } else { int pos, cnt; char *txt; pos = tPtr->selection.position; cnt = tPtr->selection.count; txt = tPtr->text; while (pos >= 0) { if (txt[pos] == ' ' || txt[pos] == '\t') break; pos--; } pos++; while (pos + cnt < tPtr->textLen) { if (txt[pos + cnt] == ' ' || txt[pos + cnt] == '\t') break; cnt++; } tPtr->selection.position = pos; tPtr->selection.count = cnt; } paintTextField(tPtr); if (!tPtr->flags.ownsSelection) { tPtr->flags.ownsSelection = WMCreateSelectionHandler(tPtr->view, XA_PRIMARY, event->xbutton.time, &selectionHandler, NULL); } } else if (!tPtr->flags.secure && tPtr->selection.count != 0 && !tPtr->flags.ownsSelection) { tPtr->flags.ownsSelection = WMCreateSelectionHandler(tPtr->view, XA_PRIMARY, event->xbutton.time, &selectionHandler, NULL); } lastButtonReleasedEvent2 = lastButtonReleasedEvent; lastButtonReleasedEvent = event->xbutton.time; break; } }