Jump to content

TriZet

Members
  • Posts

    18
  • Joined

  • Last visited

Posts posted by TriZet

  1. First version of new redrawing function.

    Redraw only changed keys. Not all keyboard. So speed up and redraw flicker gone :)

    Except layout change keyboard. For this we must to redraw all.

    I have tested for bugs and seems what working fine.

    Check this, hope this function will be useful :)


    void gwinKeyboardDraw_Normal(GWidgetObject *gw, void *param) {
    #define gk ((GKeyboardObject *)gw)

    char cap[5];
    const char *pcap;
    const utf8 *krow;
    coord_t x, y, cx, cy;
    uint8_t rows, cols, row, col, kcols;
    ucode key;
    fixed fx, fy;
    const GColorSet *pcol;
    (void) param;

    if (gw->g.vmt != (gwinVMT *)&keyboardVMT) return;

    // Get the y parameters
    rows = NumKeyRows(gk->keyset);
    fy = FIXED(gk->w.g.height) / rows;
    for(row = 0; row < rows; row++) {
    y = NONFIXED(fy * row + FIXED0_5);
    cy = NONFIXED(fy * (row+1) + FIXED0_5) - y;

    // Get the current row
    krow = (const utf8 *)gk->keyset[row];

    // Get the x parameters
    cols = UTF8StrLen(krow);
    fx = FIXED(gk->w.g.width) / cols;
    for(col = 0; col < cols; col=kcols) {

    // Choose the color
    if (!(gk->w.g.flags & GWIN_FLG_SYSENABLED))
    pcol = &gk->w.pstyle->disabled;
    else
    pcol = &gk->w.pstyle->enabled;

    // Get the key
    key = UTF8CharAt(krow, col);

    // Amalgamate identical keys into one big key
    kcols = col+1;
    while(UTF8CharAt(krow, kcols) == key)
    kcols++;

    // if quick update need and keyboard already drawn(if not use this flag, then bug when screen toched before keyboard was drawn)
    if( (gk->w.g.flags & GKEYBOARD_FLG_QUICKUPDATE) && !(gk->w.g.flags & GWIN_FLG_BGREDRAW) )
    {
    // if key down
    if( (gk->keyrow != GKEY_BAD_ROWCOL) && (gk->keycol != GKEY_BAD_ROWCOL) )
    {
    // and previos key have
    if( (gk->lastkeyrow != GKEY_BAD_ROWCOL) && (gk->lastkeycol != GKEY_BAD_ROWCOL) )
    {
    if(gk->lastkeyrow == row && gk->lastkeycol == col)
    { //if keyboard has no "disabled" color
    if(pcol != &gk->w.pstyle->disabled) pcol = &gk->w.pstyle->enabled;
    gk->lastkeyrow = gk->lastkeycol = GKEY_BAD_ROWCOL;
    }
    else continue;
    }
    else//if no previos key
    {
    if(gk->keyrow == row && gk->keycol == col)
    {
    if(pcol != &gk->w.pstyle->disabled) pcol = &gk->w.pstyle->pressed;
    gk->lastkeyrow = row;
    gk->lastkeycol = col;
    }
    else if(gk->lastkeyrow == row && gk->lastkeycol == col)
    {
    if(pcol != &gk->w.pstyle->disabled) pcol = &gk->w.pstyle->enabled;
    }
    else continue;
    }
    }
    // if key up, and need clear the previos key
    else if( (gk->lastkeyrow != GKEY_BAD_ROWCOL) && (gk->lastkeycol != GKEY_BAD_ROWCOL) )
    {
    if( (gk->lastkeyrow == row) && (gk->lastkeycol == col) )
    {
    if(pcol != &gk->w.pstyle->disabled) pcol = &gk->w.pstyle->enabled;
    }
    else continue;
    }
    }
    else
    gk->lastkeyrow = gk->lastkeycol = GKEY_BAD_ROWCOL;

    x = NONFIXED(fx * col + FIXED0_5);
    cx = NONFIXED(fx * kcols + FIXED0_5) - x;

    if (key < 0x20) {
    pcap = gk->keytable->skeys[key-1].keycap;
    } else {
    cap[UCode2UTF8((utf8 *)cap, key)] = 0;
    pcap = cap;
    }

    switch(*pcap) {
    case '\001': // Shift (up arrow)
    gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);

    gdispGDrawLine(gw->g.display, gw->g.x+x +cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/4, pcol->text); /* / \ */
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx -cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/4, pcol->text);
    gdispGDrawLine(gw->g.display, gw->g.x+x +cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy/2, pcol->text); /* _ _ */
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx -cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy/2, pcol->text);
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy/2, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy -cy/3, pcol->text); /* || */
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy/2, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy -cy/3, pcol->text);
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy -cy/3, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy -cy/3, pcol->text);/* _ */
    break;
    case '\002': // Shift locked (up arrow - bold)
    gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);

    gdispGDrawLine(gw->g.display, gw->g.x+x +cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/4, pcol->text); /* / \ */
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx -cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/4, pcol->text);
    gdispGDrawLine(gw->g.display, gw->g.x+x +cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy/2, pcol->text); /* _ _ */
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx -cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy/2, pcol->text);
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy/2, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy -cy/3, pcol->text); /* || */
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy/2, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy -cy/3, pcol->text);
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy -cy/3, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy -cy/3, pcol->text);/* _ */
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/5, gw->g.y+y+cy -cy/4, gw->g.x+x+cx/2+cx/5, gw->g.y+y+cy -cy/4, pcol->text);/* ___ */
    break;
    case '\t':
    gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);
    gdispGDrawLine(gw->g.display, gw->g.x+x+1, gw->g.y+y+1, gw->g.x+x+cx-1, gw->g.y+y+cy/2, pcol->text);
    gdispGDrawLine(gw->g.display, gw->g.x+x+1, gw->g.y+y+cy-1, gw->g.x+x+cx-1, gw->g.y+y+cy/2, pcol->text);
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx-1, gw->g.y+y+1, gw->g.x+x+cx-1, gw->g.y+y+cy-1, pcol->text);
    break;
    case '\b': // Backspace
    gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);

    gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/8, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/3, pcol->text); /* / */
    gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/8, gw->g.y+y+cy/2, gw->g.x+x+cx-cx/8, gw->g.y+y+cy/2, pcol->text); /* -- */
    gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/8, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y+cy -cy/3, pcol->text); /* \ */
    break;
    case '\r': // Enter
    gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);

    gdispGDrawLine(gw->g.display, gw->g.x+x+(cx/3)*2, gw->g.y+y+cy/2, gw->g.x+x+(cx/3)*2, gw->g.y+y+cy/5, pcol->text); /* | */
    gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/3, gw->g.y+y+cy/2, gw->g.x+x+cx/3 +cx/8, gw->g.y+y +cy/3, pcol->text); /* / */
    gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/3, gw->g.y+y+cy/2, gw->g.x+x+(cx/3)*2, gw->g.y+y+cy/2, pcol->text); /* -- */
    gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/3, gw->g.y+y+cy/2, gw->g.x+x+cx/3 +cx/8, gw->g.y+y+cy -cy/3, pcol->text); /* \ */
    break;
    default:
    gdispGFillStringBox(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcap, gw->g.font, pcol->text, pcol->fill, justifyCenter);
    }

    gdispGDrawBox(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->text); // Frame

    //if key up and we already clear previos key
    if( (gk->keyrow == GKEY_BAD_ROWCOL) && (gk->keycol == GKEY_BAD_ROWCOL) && (gk->lastkeyrow == row) && (gk->lastkeycol == col) )
    {
    gk->lastkeyrow = gk->lastkeycol = GKEY_BAD_ROWCOL;
    return;
    }
    //just quit from cycle if we do all work, for time economy
    if( (row >= gk->keyrow && col >= gk->keycol) && (row >= gk->lastkeyrow && col >= gk->lastkeycol) ) return;
    }
    }
    #undef gk
    }

  2. We are very thankful for your contribution. We always wanted to implemented a better rendering function for the keyboard widget but we never got to it.

    I have tested some idea. It work very well for single pressed button. Without redraw all keyboard.

    But troubles come in when we move finger on keyboard. I try to understand interaction between all levels of uGFX more detail. Maybe after I can write better solution.

    Are you interested into creating new/alternative custom renderings for other widgets as well? We would really love to provide some better looking (default) styles as the current ones are the biggest draw-back for most users.

    I interested to develop everything. :) I have many ideas to use in uGFX.

    Some times ago I wrote own very simple gui. But in one person very hard make something cool. Especially if it is no a base work.

  3. Hello!

    I made new draw for "enter, shift, backspace". They are "stretch". So, locking good and same on any keyboard size.

    Maybe it will interesting for you to improve uGFX system. Or for someone else. :)

    Change in gwinKeyboardDraw_Normal function.

    Also some pictures attached.


    switch(*pcap) {
    case '\001': // Shift (up arrow)
    gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);

    gdispGDrawLine(gw->g.display, gw->g.x+x +cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/4, pcol->text); /* / \ */
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx -cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/4, pcol->text);
    gdispGDrawLine(gw->g.display, gw->g.x+x +cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy/2, pcol->text); /* _ _ */
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx -cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy/2, pcol->text);
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy/2, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy -cy/3, pcol->text); /* || */
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy/2, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy -cy/3, pcol->text);
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy -cy/3, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy -cy/3, pcol->text);/* _ */
    break;
    case '\002': // Shift locked (up arrow - bold)
    gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);

    gdispGDrawLine(gw->g.display, gw->g.x+x +cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/4, pcol->text); /* / \ */
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx -cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/4, pcol->text);
    gdispGDrawLine(gw->g.display, gw->g.x+x +cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy/2, pcol->text); /* _ _ */
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx -cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy/2, pcol->text);
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy/2, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy -cy/3, pcol->text); /* || */
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy/2, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy -cy/3, pcol->text);
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy -cy/3, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy -cy/3, pcol->text);/* _ */
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/5, gw->g.y+y+cy -cy/4, gw->g.x+x+cx/2+cx/5, gw->g.y+y+cy -cy/4, pcol->text);/* ___ */
    break;
    case '\t':
    gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);
    gdispGDrawLine(gw->g.display, gw->g.x+x+1, gw->g.y+y+1, gw->g.x+x+cx-1, gw->g.y+y+cy/2, pcol->text);
    gdispGDrawLine(gw->g.display, gw->g.x+x+1, gw->g.y+y+cy-1, gw->g.x+x+cx-1, gw->g.y+y+cy/2, pcol->text);
    gdispGDrawLine(gw->g.display, gw->g.x+x+cx-1, gw->g.y+y+1, gw->g.x+x+cx-1, gw->g.y+y+cy-1, pcol->text);
    break;
    case '\b': // Backspace
    gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);

    gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/8, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/3, pcol->text); /* / */
    gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/8, gw->g.y+y+cy/2, gw->g.x+x+cx-cx/8, gw->g.y+y+cy/2, pcol->text); /* -- */
    gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/8, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y+cy -cy/3, pcol->text); /* \ */
    break;
    case '\r': // Enter
    gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);

    gdispGDrawLine(gw->g.display, gw->g.x+x+(cx/3)*2, gw->g.y+y+cy/2, gw->g.x+x+(cx/3)*2, gw->g.y+y+cy/5, pcol->text); /* | */
    gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/3, gw->g.y+y+cy/2, gw->g.x+x+cx/3 +cx/8, gw->g.y+y +cy/3, pcol->text); /* / */
    gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/3, gw->g.y+y+cy/2, gw->g.x+x+(cx/3)*2, gw->g.y+y+cy/2, pcol->text); /* -- */
    gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/3, gw->g.y+y+cy/2, gw->g.x+x+cx/3 +cx/8, gw->g.y+y+cy -cy/3, pcol->text); /* \ */
    break;
    default:
    gdispGFillStringBox(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcap, gw->g.font, pcol->text, pcol->fill, justifyCenter);
    }

    gdispGDrawBox(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->text); // Frame

    SSD1306.zip

    kbrd_big_shiftlock.thumb.jpg.f7cf0be5f1e

    kbrd_small.thumb.jpg.6d2d2f7f5c7e700bdd8

  4. Strange thing...

    I see what GKEYSTATE_MISSED_EVENT = 1<<31.

    srcflags is 32 bit.

    But warning.


    ..\ugfx\src\gwin/gwin_keyboard.c(131): warning: #61-D: integer operation result is out of range
    ..\ugfx\src\gwin/gwin_keyboard.c(131): warning: #68-D: integer conversion resulted in a change of sign

    But if I change GKEYSTATE_MISSED_EVENT to 0x80000000 warning is gone... :?

    IDE is Keil 5.

  5. Hello!

    When I have use virtual keyboard I see compiller warning in gwin_keyboard.c line psl->srcflags |= GKEYSTATE_MISSED_EVENT; about out of range.

    static void SendKeyboardEventToListener(GSourceListener	*psl, GKeyboardObject *gk) {
    GEventKeyboard *pe;
    const GVSpecialKey *skey;
    unsigned i;

    // If there is no event buffer just mark a missed event
    if (!(pe = (GEventKeyboard *)geventGetEventBuffer(psl))) {
    // This listener is missing - save the meta events that have happened
    psl->srcflags |= GKEYSTATE_MISSED_EVENT;
    return;
    }

  6. I know what I can use one listener for all function. And use geventListenerInit one time close to all init functions. I just write situation if I create new listener and want to delete it after use.

    In this situations I do not have function for clear all memory used by listener. About geventDetachSource and gfxSemDestroy I written what it is just for test )

  7. Hello!

    For example we have some code:


    void clock_config(RTC_t *rtc)
    {
    GHandle ghFrame1;
    GWidgetInit wi;
    GListener cc_li;
    GEvent* pe;

    //Create frame
    gwinWidgetClearInit(&wi);
    wi.g.show = TRUE;
    wi.g.width = 300;
    wi.g.height = 350;
    wi.g.x = (gdispGetWidth() / 2) - (wi.g.width / 2);
    wi.g.y = (gdispGetHeight() / 2) - (wi.g.height / 2);
    wi.text = "Date and time";
    ghFrame1 = gwinFrameCreate(0, &wi, GWIN_FRAME_BORDER | GWIN_FRAME_CLOSE_BTN );

    //Add another widgets and something else code....
    //.......
    //.......

    //Create new listener
    geventListenerInit(&cc_li);
    gwinAttachListener(&cc_li);

    // Do something...
    while(1)
    {
    pe = geventEventWait(&cc_li, TIME_INFINITE);
    switch(pe->type)
    {
    case GEVENT_GWIN_BUTTON:
    if (((GEventGWinButton *)pe)->gwin == ghButton_Save)
    {
    //Exit if button pressed
    geventDetachSource(&cc_li, NULL);
    gwinDestroy(ghFrame1);
    return;
    }
    break;

    default:
    //Exit if frame "x" button pressed
    geventDetachSource(&cc_li, NULL);
    //gwinDestroy(ghFrame1);
    return;
    }
    }
    }

    So if we call this function and then return we lose 88 byte of heap each time a function called.

    I see what in the geventListenerInit we add a semaphore to new listener:


    void geventListenerInit(GListener *pl) {
    gfxSemInit(&pl->waitqueue, 0, MAX_SEMAPHORE_COUNT); // Next wait'er will block
    pl->callback = 0; // No callback active
    pl->event.type = GEVENT_NULL; // Always safety
    pl->flags = 0;
    }

    But this semaphore not deleted anywhere. So every call we have a new semaphore(new 88 bytes in heap).

    I just put gfxSemDestroy(&pl->waitqueue) to the geventDetachSource and memory leak is gone. I know this is not right it is just for test.

    I think need function some like geventListenerDeinit or we must delete this semaphore in some another place if we does not want to use created listener anymore.

  8. Hi again! :)

    I do some device and I was needed functions for select/deselect item. And for scroll to the item in List.

    I don't find how it can be do in uGFX. If it can be please say how )) But for now I added this functions.

    Maybe some people this functions can help too. Or maybe you add them to uGFX to improve functionality. :)


    //===============================================================
    // item - is item to modify
    // param - TRUE to select, FALSE to deselect
    //
    void gwinListSetSelected(GHandle gh, int item, bool_t param) {
    const gfxQueueASyncItem * qi;
    int i;

    // is it a valid handle?
    if (gh->vmt != (gwinVMT *)&listVMT)
    return;

    // watch out for an invalid item
    if (item < 0 || item > (gh2obj->cnt) - 1)
    return;

    // If not a multiselect mode - clear previous selected item
    if (!(gh->flags & GLIST_FLG_MULTISELECT)) {
    for(qi = gfxQueueASyncPeek(&gh2obj->list_head), i = 0; qi; qi = gfxQueueASyncNext(qi), i++) {
    if (qi2li->flags & GLIST_FLG_SELECTED) {
    qi2li->flags &= ~GLIST_FLG_SELECTED;
    break; // or without break to deselect all
    }
    }
    }

    // Find item and set selected or not
    for(qi = gfxQueueASyncPeek(&gh2obj->list_head), i = 0; qi; qi = gfxQueueASyncNext(qi), i++) {
    if (i == item) {
    if(param == TRUE )qi2li->flags |= GLIST_FLG_SELECTED;
    else qi2li->flags &= ~GLIST_FLG_SELECTED;
    break;
    }
    }
    _gwinUpdate(gh);
    }

    //===============================================================
    // item - scrool to him
    void gwinListScroollToItem(GHandle gh, int item) {
    int iheight, oldtop;
    // is it a valid handle?
    if (gh->vmt != (gwinVMT *)&listVMT)
    return;

    // watch out for an invalid item
    if (item < 0 || item > (gh2obj->cnt) - 1)
    return;

    iheight = gdispGetFontMetric(gh->font, fontHeight) + VERTICAL_PADDING;
    gh2obj->top = iheight * item;

    if (gh2obj->top >= gh2obj->cnt * iheight - (gh->height-2))
    gh2obj->top = gh2obj->cnt * iheight - (gh->height-2) - 1;

    if (gh2obj->top < 0)
    gh2obj->top = 0;

    _gwinUpdate(gh);
    }

    //===============================================================

  9. Hello!

    Many thanks for your work! It's amaizing project.

    Now to the work ))

    I have played with uGFX and seen what top menu buttons(maximize, minimize, close) respond for touch on all Y space from top to bottom of frame.

    I found this place(line 57 in gwin_frame.c) and think what something like this must be ))

    Then bug is fixed.

    	static void mouseDown(GWidgetObject *gw, coord_t x, coord_t y) {
    coord_t pos;

    // We must be clicking on the frame button area to be of interest
    //if (y < BUTTON_T && y >= BUTTON_T+BUTTON_Y) OLD CODE !!
    if (y < BUTTON_T || y >= BUTTON_T+BUTTON_Y)
    return;

    pos = gw->g.width - (BORDER_R+BUTTON_X);
    if ((gw->g.flags & GWIN_FRAME_CLOSE_BTN)) {
    if (x >= pos && x < pos+BUTTON_X) {

×
×
  • Create New...