Jump to content

TriZet

Members
  • Posts

    18
  • Joined

  • Last visited

Everything posted by TriZet

  1. Keil still show the same warnings. No matter "unsigned" or "uint32" :? I have version 5.14 for now. Some time later I will try in 5.17. And will write about results.
  2. 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 }
  3. 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. 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.
  4. 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
  5. Interesting. Other compilers also show this warning? If not, possible only Keil bug.
  6. I think this is stupid compiller bug... I see in debug what GKEYSTATE_MISSED_EVENT also = 0x80000000. As it should be.
  7. 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.
  8. 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; }
  9. Hi! Have test your font. Seems all work. What problem do you have? Please write more detail.
  10. I just say what I see when I play with uGFX. Maybe deinit functions is a real garbage as Tectu say. Or maybe some user with problem of the memory will see this topic and will know how not to do. Whos know..
  11. 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 )
  12. 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.
  13. Great! If I get new ideas, I will write them on the forum. Happy to help improve the uGFX
  14. 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); } //===============================================================
  15. 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...