** Function name: drawMainMenu ** Description: Função para desenhar e mostrar o menu principal ***************************************************************************************/
| 792 | ** Description: Função para desenhar e mostrar o menu principal |
| 793 | ***************************************************************************************/ |
| 794 | void drawMainMenu(std::vector<MenuOptions> &opt, int index) { |
| 795 | |
| 796 | uint8_t size = opt.size(); |
| 797 | if (size < 1) { |
| 798 | displayRedStripe("No options available"); |
| 799 | return; |
| 800 | } |
| 801 | bool compactOneLine = tftHeight <= 90; |
| 802 | int cols = compactOneLine ? 5 : 3; // Number of columns based on height |
| 803 | int visibleItems = compactOneLine && size > cols ? cols : size; |
| 804 | int rows = compactOneLine ? 1 : (size + cols - 1) / cols; // Calculate rows needed |
| 805 | int w = (tftWidth - 16) / cols; // Width of each icon |
| 806 | int h = (tftHeight - ((6 + 6 + FP * LH + 6) + LH * FP + 6)) / rows; // Height of each icon |
| 807 | |
| 808 | int maxIconTextSize = tftHeight <= 135 ? FM : FG; |
| 809 | |
| 810 | for (int i = 0; i < size; ++i) opt[i].resetCoords(); |
| 811 | |
| 812 | for (int slot = 0; slot < visibleItems; ++slot) { |
| 813 | int i = slot; |
| 814 | if (compactOneLine && size > cols) { |
| 815 | int centerSlot = cols / 2; |
| 816 | i = (index + slot - centerSlot + size) % size; |
| 817 | } |
| 818 | |
| 819 | int col = slot % cols; |
| 820 | int row = compactOneLine ? 0 : slot / cols; |
| 821 | int y = (6 + 6 + FP * LH + 8) + row * h; |
| 822 | int xOffset = 0; |
| 823 | |
| 824 | // Última linha incompleta: centralizar |
| 825 | if (!compactOneLine && row == rows - 1 && (size % cols) != 0 && (size % cols) < cols) { |
| 826 | int itemsInLastRow = size % cols; |
| 827 | int totalWidthUsed = itemsInLastRow * w; |
| 828 | xOffset = ((tftWidth - 16) - totalWidthUsed) / 2; |
| 829 | } |
| 830 | |
| 831 | int x = 8 + xOffset + col * w; |
| 832 | |
| 833 | opt[i].x = x; |
| 834 | opt[i].y = y; |
| 835 | opt[i].w = w; |
| 836 | opt[i].h = h; |
| 837 | // Serial.printf("Menu Name: %s, x=%d, y=%d, w=%d, h=%d\n", opt[i].name, opt[i].x, opt[i].y, opt[i].w, |
| 838 | // opt[i].h); // Debug purpose |
| 839 | |
| 840 | uint16_t itemColor = opt[i].active ? opt[i].color : DARKGREY; |
| 841 | uint16_t selectedColor = opt[i].active ? opt[i].color : LIGHTGREY; |
| 842 | int f_size = maxIconTextSize; |
| 843 | const int textLimit = w - 10; |
| 844 | tft->setTextSize(f_size); |
| 845 | if (static_cast<int>(opt[i].name.length()) * LW * f_size > textLimit && f_size > FM) { |
| 846 | f_size = FM; |
| 847 | tft->setTextSize(f_size); |
| 848 | } |
| 849 | if (static_cast<int>(opt[i].name.length()) * LW * f_size > textLimit && f_size > FP) { |
| 850 | f_size = FP; |
| 851 | tft->setTextSize(f_size); |
no test coverage detected