Example #1
0
//根据Menu内容来绘制菜单内容
void DrawXlibMenu(XlibMenu * menu)
{
    FcitxSkin *sc = &menu->owner->skin;
    FcitxClassicUI *classicui = menu->owner;
    Display* dpy = classicui->dpy;
    GC gc = XCreateGC(dpy, menu->menuWindow, 0, NULL);
    int i = 0;
    int fontheight;
    int iPosY = 0;
    int dpi = sc->skinFont.respectDPI? menu->owner->dpi: 0;
    FCITX_UNUSED(dpi);

    fontheight = FontHeight(menu->owner->menuFont, sc->skinFont.menuFontSize, dpi);
    SkinImage *background = LoadImage(sc, sc->skinMenu.backImg, false);

    GetMenuSize(menu);
    EnlargeCairoSurface(&menu->menu_cs, menu->width, menu->height);

    if (background) {
        cairo_t* cr = cairo_create(menu->menu_cs);
        DrawResizableBackground(cr, background->image, menu->height, menu->width,
                                sc->skinMenu.marginLeft,
                                sc->skinMenu.marginTop,
                                sc->skinMenu.marginRight,
                                sc->skinMenu.marginBottom,
                                sc->skinMenu.fillV,
                                sc->skinMenu.fillH
                            );

        cairo_destroy(cr);
    }

    iPosY = sc->skinMenu.marginTop;
    for (i = 0; i < utarray_len(&menu->menushell->shell); i++) {
        if (GetMenuItem(menu->menushell, i)->type == MENUTYPE_SIMPLE || GetMenuItem(menu->menushell, i)->type == MENUTYPE_SUBMENU) {
            DisplayText(menu, i, iPosY, fontheight);
            if (menu->menushell->mark == i)
                MenuMark(menu, iPosY, i);

            if (GetMenuItem(menu->menushell, i)->type == MENUTYPE_SUBMENU)
                DrawArrow(menu, iPosY);
            iPosY = iPosY + 6 + fontheight;
        } else if (GetMenuItem(menu->menushell, i)->type == MENUTYPE_DIVLINE) {
            DrawDivLine(menu, iPosY);
            iPosY += 5;
        }
    }
    XResizeWindow(dpy, menu->menuWindow, menu->width, menu->height);
    _CAIRO_SETSIZE(menu->menu_x_cs, menu->width, menu->height);
    cairo_t* c = cairo_create(menu->menu_x_cs);
    cairo_set_operator(c, CAIRO_OPERATOR_SOURCE);
    cairo_set_source_surface(c, menu->menu_cs, 0, 0);
    cairo_rectangle(c, 0, 0, menu->width, menu->height);
    cairo_clip(c);
    cairo_paint(c);
    cairo_destroy(c);
    cairo_surface_flush(menu->menu_x_cs);
    XFreeGC(dpy, gc);
}
Example #2
0
//根据Menu内容来绘制菜单内容
void DrawXlibMenu(XlibMenu * menu)
{
    FcitxLightUI *lightui = menu->owner;
    Display* dpy = lightui->dpy;
    GC gc = XCreateGC( dpy, menu->menuWindow, 0, NULL );
    int i=0;
    int fontheight;
    int iPosY = 0;

    fontheight= MenuFontSize;

    GetMenuSize(menu);

    DrawResizableBackground(menu->owner, menu->pixmap, menu->height, menu->width,
                            menu->owner->backcolor, menu->owner->bordercolor, gc);

    iPosY=MenuMarginTop;
    for (i=0;i<utarray_len(&menu->menushell->shell);i++)
    {
        if ( GetMenuShell(menu->menushell, i)->type == MENUTYPE_SIMPLE || GetMenuShell(menu->menushell, i)->type == MENUTYPE_SUBMENU)
        {
            DisplayText( menu,i,iPosY);
            if (menu->menushell->mark == i)
                MenuMark(menu,iPosY,i);

            if (GetMenuShell(menu->menushell, i)->type == MENUTYPE_SUBMENU)
                DrawArrow(menu, iPosY);
            iPosY=iPosY+6+fontheight;
        }
        else if ( GetMenuShell(menu->menushell, i)->type == MENUTYPE_DIVLINE)
        {
            DrawDivLine(menu,iPosY);
            iPosY+=5;
        }
    }

    XResizeWindow(dpy, menu->menuWindow, menu->width, menu->height);
    XCopyArea (dpy,
               menu->pixmap,
               menu->menuWindow,
               gc,
               0,
               0,
               menu->width,
               menu->height, 0, 0);
    XFreeGC(dpy, gc);
}
Example #3
0
File: skin.c Project: areslp/fcitx
void DrawInputBar(FcitxSkin* sc, InputWindow* inputWindow, int iCursorPos, FcitxMessages * msgup, FcitxMessages *msgdown , unsigned int * iheight, unsigned int *iwidth)
{
    int i;
    char *strUp[MAX_MESSAGE_COUNT];
    char *strDown[MAX_MESSAGE_COUNT];
    int posUpX[MAX_MESSAGE_COUNT], posUpY[MAX_MESSAGE_COUNT];
    int posDownX[MAX_MESSAGE_COUNT], posDownY[MAX_MESSAGE_COUNT];
    int oldHeight = *iheight, oldWidth = *iwidth;
    int newHeight = 0, newWidth = 0;
    int cursor_pos = 0;
    int inputWidth = 0, outputWidth = 0;
    int outputHeight = 0;
    cairo_t *c = NULL;
    FcitxInputState* input = FcitxInstanceGetInputState(inputWindow->owner->owner);
    FcitxInstance* instance = inputWindow->owner->owner;
    FcitxClassicUI* classicui = inputWindow->owner;
    int iChar = iCursorPos;
    int strWidth = 0, strHeight = 0;

    SkinImage *inputimg, *prev, *next;
    inputimg = LoadImage(sc, sc->skinInputBar.backImg, false);
    prev = LoadImage(sc, sc->skinInputBar.backArrow, false);
    next = LoadImage(sc, sc->skinInputBar.forwardArrow, false);

    if (!FcitxMessagesIsMessageChanged(msgup) && !FcitxMessagesIsMessageChanged(msgdown))
        return;

    inputWidth = 0;
    int dpi = sc->skinFont.respectDPI? classicui->dpi : 0;
    FCITX_UNUSED(dpi);
#ifdef _ENABLE_PANGO /* special case which only macro unable to handle */
    SetFontContext(dummy, inputWindow->owner->font, inputWindow->owner->fontSize > 0 ? inputWindow->owner->fontSize : sc->skinFont.fontSize, dpi);
#endif

    int fontHeight = FontHeightWithContext(inputWindow->c_font[0], dpi);
    for (i = 0; i < FcitxMessagesGetMessageCount(msgup) ; i++) {
        char *trans = FcitxInstanceProcessOutputFilter(instance, FcitxMessagesGetMessageString(msgup, i));
        if (trans)
            strUp[i] = trans;
        else
            strUp[i] = FcitxMessagesGetMessageString(msgup, i);
        posUpX[i] = sc->skinInputBar.marginLeft + inputWidth;

        StringSizeWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgup, i)], dpi, strUp[i], &strWidth, &strHeight);

        if (sc->skinFont.respectDPI)
            posUpY[i] = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos;
        else
            posUpY[i] = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos - strHeight;
        inputWidth += strWidth;
        if (FcitxInputStateGetShowCursor(input)) {
            int length = strlen(FcitxMessagesGetMessageString(msgup, i));
            if (iChar >= 0) {
                if (iChar < length) {
                    char strTemp[MESSAGE_MAX_LENGTH];
                    char *strGBKT = NULL;
                    strncpy(strTemp, strUp[i], iChar);
                    strTemp[iChar] = '\0';
                    strGBKT = strTemp;
                    StringSizeWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgup, i)], dpi, strGBKT, &strWidth, &strHeight);
                    cursor_pos = posUpX[i]
                                 + strWidth + 2;
                }
                iChar -= length;
            }
        }

    }

    if (iChar >= 0)
        cursor_pos = inputWidth + sc->skinInputBar.marginLeft;

    outputWidth = 0;
    outputHeight = 0;
    int currentX = 0;
    int offsetY;
    if (sc->skinFont.respectDPI)
        offsetY = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos + fontHeight + (FcitxMessagesGetMessageCount(msgdown) ? sc->skinInputBar.iOutputPos : 0);
    else
        offsetY = sc->skinInputBar.marginTop + sc->skinInputBar.iOutputPos - fontHeight;
    for (i = 0; i < FcitxMessagesGetMessageCount(msgdown) ; i++) {
        char *trans = FcitxInstanceProcessOutputFilter(instance, FcitxMessagesGetMessageString(msgdown, i));
        if (trans)
            strDown[i] = trans;
        else
            strDown[i] = FcitxMessagesGetMessageString(msgdown, i);

        if (inputWindow->owner->bVerticalList) { /* vertical */
            if (FcitxMessagesGetMessageType(msgdown, i) == MSG_INDEX) {
                if (currentX > outputWidth)
                    outputWidth = currentX;
                if (i != 0) {
                    currentX = 0;
                }
            }
            posDownX[i] = sc->skinInputBar.marginLeft + currentX;
            StringSizeWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgdown, i)], dpi, strDown[i], &strWidth, &strHeight);
            if (FcitxMessagesGetMessageType(msgdown, i) == MSG_INDEX && i != 0)
                outputHeight += fontHeight + 2;
            currentX += strWidth;
        } else { /* horizontal */
            posDownX[i] = sc->skinInputBar.marginLeft + outputWidth;
            StringSizeWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgdown, i)], dpi, strDown[i], &strWidth, &strHeight);
            outputWidth += strWidth;
        }
        posDownY[i] = offsetY + outputHeight;
    }
    if (inputWindow->owner->bVerticalList && currentX > outputWidth)
        outputWidth = currentX;

    newHeight = offsetY + outputHeight + sc->skinInputBar.marginBottom + (FcitxMessagesGetMessageCount(msgdown) || !sc->skinFont.respectDPI ? fontHeight : 0);

    newWidth = (inputWidth < outputWidth) ? outputWidth : inputWidth;
    newWidth += sc->skinInputBar.marginLeft + sc->skinInputBar.marginRight;

    /* round to ROUND_SIZE in order to decrease resize */
    newWidth = (newWidth / ROUND_SIZE) * ROUND_SIZE + ROUND_SIZE;

    if (inputWindow->owner->bVerticalList) { /* vertical */
        newWidth = (newWidth < INPUT_BAR_VMIN_WIDTH) ? INPUT_BAR_VMIN_WIDTH : newWidth;
    } else {
        newWidth = (newWidth < INPUT_BAR_HMIN_WIDTH) ? INPUT_BAR_HMIN_WIDTH : newWidth;
    }

    *iwidth = newWidth;
    *iheight = newHeight;

    EnlargeCairoSurface(&inputWindow->cs_input_back, newWidth, newHeight);
    if (EnlargeCairoSurface(&inputWindow->cs_input_bar, newWidth, newHeight)) {
        LoadInputMessage(&classicui->skin, classicui->inputWindow, classicui->font);
    }

    if (oldHeight != newHeight || oldWidth != newWidth) {
        c = cairo_create(inputWindow->cs_input_back);
        DrawResizableBackground(c, inputimg->image, newHeight, newWidth,
                                sc->skinInputBar.marginLeft,
                                sc->skinInputBar.marginTop,
                                sc->skinInputBar.marginRight,
                                sc->skinInputBar.marginBottom,
                                sc->skinInputBar.fillV,
                                sc->skinInputBar.fillH
                               );
        cairo_destroy(c);
    }

    c = cairo_create(inputWindow->cs_input_bar);
    cairo_set_source_surface(c, inputWindow->cs_input_back, 0, 0);
    cairo_save(c);
    cairo_rectangle(c, 0, 0, newWidth, newHeight);
    cairo_set_operator(c, CAIRO_OPERATOR_SOURCE);
    cairo_clip(c);
    cairo_paint(c);
    cairo_restore(c);

    cairo_set_operator(c, CAIRO_OPERATOR_OVER);


    if (FcitxInputStateGetShowCursor(input)) {
        //画向前向后箭头
        if (prev && next) {
            cairo_set_source_surface(inputWindow->c_back, prev->image,
                                     newWidth - sc->skinInputBar.iBackArrowX ,
                                     sc->skinInputBar.iBackArrowY);
            if (FcitxCandidateWordHasPrev(FcitxInputStateGetCandidateList(input)))
                cairo_paint(inputWindow->c_back);
            else
                cairo_paint_with_alpha(inputWindow->c_back, 0.5);

            //画向前箭头
            cairo_set_source_surface(inputWindow->c_back, next->image,
                                     newWidth - sc->skinInputBar.iForwardArrowX ,
                                     sc->skinInputBar.iForwardArrowY);
            if (FcitxCandidateWordHasNext(FcitxInputStateGetCandidateList(input)))
                cairo_paint(inputWindow->c_back);
            else
                cairo_paint_with_alpha(inputWindow->c_back, 0.5);
        }
    }

    for (i = 0; i < FcitxMessagesGetMessageCount(msgup) ; i++) {
        OutputStringWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgup, i)], dpi, strUp[i], posUpX[i], posUpY[i]);
        if (strUp[i] != FcitxMessagesGetMessageString(msgup, i))
            free(strUp[i]);
    }

    for (i = 0; i < FcitxMessagesGetMessageCount(msgdown) ; i++) {
        OutputStringWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgdown, i)], dpi, strDown[i], posDownX[i], posDownY[i]);
        if (strDown[i] != FcitxMessagesGetMessageString(msgdown, i))
            free(strDown[i]);
    }

    int cursorY1, cursorY2;
    if (sc->skinFont.respectDPI) {
        cursorY1 = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos;
        cursorY2 = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos + fontHeight;
    }
    else {
        cursorY1 = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos - fontHeight - 4;
        cursorY2 = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos;
    }

    //画光标
    if (FcitxInputStateGetShowCursor(input)) {
        cairo_move_to(inputWindow->c_cursor, cursor_pos, cursorY1);
        cairo_line_to(inputWindow->c_cursor, cursor_pos, cursorY2);
        cairo_stroke(inputWindow->c_cursor);
    }

    ResetFontContext();

    cairo_destroy(c);
    FcitxMessagesSetMessageChanged(msgup, false);
    FcitxMessagesSetMessageChanged(msgdown, false);
}
Example #4
0
void DrawInputBar(InputWindow* inputWindow, int iCursorPos, Messages * msgup, Messages *msgdown ,unsigned int * iheight, unsigned int *iwidth)
{
    int i;
    char *strUp[MAX_MESSAGE_COUNT];
    char *strDown[MAX_MESSAGE_COUNT];
    int posUpX[MAX_MESSAGE_COUNT], posUpY[MAX_MESSAGE_COUNT];
    int posDownX[MAX_MESSAGE_COUNT], posDownY[MAX_MESSAGE_COUNT];
    int oldHeight = *iheight, oldWidth = *iwidth;
    int newHeight = 0, newWidth = 0;
    int cursor_pos=0;
    int inputWidth = 0, outputWidth = 0;
    int outputHeight = 0;
    FcitxInputState* input = &inputWindow->owner->owner->input;
    FcitxInstance* instance = inputWindow->owner->owner;
    int iChar = iCursorPos;
    int strWidth = 0, strHeight = 0;
    int fontSize = FONTHEIGHT;

    if (!IsMessageChanged(msgup) && !IsMessageChanged(msgdown))
        return;

    inputWidth = 0;
    strHeight = FONTHEIGHT;

    for (i = 0; i < GetMessageCount(msgup) ; i++)
    {
        char *trans = ProcessOutputFilter(instance, GetMessageString(msgup, i));
        if (trans)
            strUp[i] = trans;
        else
            strUp[i] = GetMessageString(msgup, i);
        posUpX[i] = MarginLeft + inputWidth;

        strWidth = StringWidth(inputWindow->dpy, inputWindow->owner->xftfont, strUp[i]);

        posUpY[i] = MarginTop + InputPos - strHeight;
        inputWidth += strWidth;
        if (input->bShowCursor)
        {
            int length = strlen(GetMessageString(msgup, i));
            if (iChar >= 0)
            {
                if (iChar < length)
                {
                    char strTemp[MESSAGE_MAX_LENGTH];
                    char *strGBKT = NULL;
                    strncpy(strTemp, strUp[i], iChar);
                    strTemp[iChar] = '\0';
                    strGBKT = strTemp;
                    strWidth = StringWidth(inputWindow->dpy, inputWindow->owner->xftfont, strGBKT);
                    cursor_pos= posUpX[i]
                                + strWidth + 2;
                }
                iChar -= length;
            }
        }

    }

    if (iChar >= 0)
        cursor_pos = inputWidth + MarginLeft;

    outputWidth = 0;
    outputHeight = 0;
    int currentX = 0;
    for (i = 0; i < GetMessageCount(msgdown) ; i++)
    {
        char *trans = ProcessOutputFilter(instance, GetMessageString(msgdown, i));
        if (trans)
            strDown[i] = trans;
        else
            strDown[i] = GetMessageString(msgdown, i);

        if (inputWindow->owner->bVerticalList) /* vertical */
        {
            if (GetMessageType(msgdown, i) == MSG_INDEX)
            {
                if (currentX > outputWidth)
                    outputWidth = currentX;
                if (i != 0)
                {
                    outputHeight += fontSize + 2;
                    currentX = 0;
                }
            }
            posDownX[i] = MarginLeft + currentX;
            strWidth = StringWidth(inputWindow->dpy, inputWindow->owner->xftfont, strDown[i]);
            currentX += strWidth;
            posDownY[i] =  MarginTop + OutputPos + outputHeight - strHeight;
        }
        else /* horizontal */
        {
            posDownX[i] = MarginLeft + outputWidth;
            strWidth = StringWidth(inputWindow->dpy, inputWindow->owner->xftfont, strDown[i]);
            posDownY[i] = MarginTop + OutputPos - strHeight;
            outputWidth += strWidth;
        }
    }
    if (inputWindow->owner->bVerticalList && currentX > outputWidth)
        outputWidth = currentX;

    newHeight = MarginTop + OutputPos + outputHeight + MarginBottom;

    newWidth = (inputWidth<outputWidth)?outputWidth:inputWidth;
    newWidth+=MarginLeft+MarginRight;

    /* round to ROUND_SIZE in order to decrease resize */
    newWidth =  (newWidth / ROUND_SIZE) * ROUND_SIZE + ROUND_SIZE;

    //输入条长度应该比背景图长度要长,比最大长度要短
    newWidth=(newWidth>=INPUT_BAR_MAX_WIDTH)?INPUT_BAR_MAX_WIDTH:newWidth;
    if (inputWindow->owner->bVerticalList) /* vertical */
    {
        newWidth = (newWidth < INPUT_BAR_VMIN_WIDTH)?INPUT_BAR_VMIN_WIDTH:newWidth;
    }
    else
    {
        newWidth = (newWidth < INPUT_BAR_HMIN_WIDTH)?INPUT_BAR_HMIN_WIDTH:newWidth;
    }

    *iwidth = newWidth;
    *iheight = newHeight;

    if (oldHeight != newHeight || oldWidth != newWidth)
    {
        DrawResizableBackground(inputWindow->owner, inputWindow->pixmap2, newHeight, newWidth,
                                inputWindow->owner->backcolor,
                                inputWindow->owner->bordercolor,
                                inputWindow->pixmap2_gc
                               );
    }
    XGCValues gcvalues;
    GC gc = XCreateGC(inputWindow->dpy, inputWindow->pixmap, 0, &gcvalues);
    XCopyArea(
        inputWindow->dpy,
        inputWindow->pixmap2,
        inputWindow->pixmap,
        gc,
        0, 0,
        inputWindow->iInputWindowWidth,
        inputWindow->iInputWindowHeight,
        0, 0
    );
    XFreeGC(inputWindow->dpy, gc);
    if (input->bShowCursor )
    {
        //画向前向后箭头
    }

    for (i = 0; i < GetMessageCount(msgup) ; i++)
    {
        OutputString(inputWindow->dpy, inputWindow->xftDraw, inputWindow->pixmap, inputWindow->owner->xftfont, strUp[i], posUpX[i], posUpY[i], inputWindow->owner->fontColor[GetMessageType(msgup, i)]);
        if (strUp[i] != GetMessageString(msgup, i))
            free(strUp[i]);
    }

    for (i = 0; i < GetMessageCount(msgdown) ; i++)
    {
        OutputString(inputWindow->dpy, inputWindow->xftDraw, inputWindow->pixmap, inputWindow->owner->xftfont, strDown[i], posDownX[i], posDownY[i], inputWindow->owner->fontColor[GetMessageType(msgdown, i)]);
        if (strDown[i] != GetMessageString(msgdown, i))
            free(strDown[i]);
    }

    //画光标
    if (input->bShowCursor )
    {
        GC gc = LightUICreateGC(inputWindow->dpy, inputWindow->pixmap, inputWindow->owner->cursorColor);
        XDrawLine(inputWindow->dpy, inputWindow->pixmap, gc, cursor_pos, MarginTop + InputPos,
                  cursor_pos, MarginTop + InputPos - fontSize - 4);
        XFreeGC(inputWindow->dpy, gc);
    }

    SetMessageChanged(msgup, false);
    SetMessageChanged(msgdown, false);
}