Day 84/100 100 Days of Code

Day 84/100 100 Days of Code

Jumping Ball

I worked on the application's text box, creating two new structures to manage the interior and exterior areas of the box. The exterior is a simple static rectangle with colored borders. The interior will expand or contract depending on the number of characters in the text box and handle correct character input. This is crucial for displaying the content of the box without any glitches.

struct ExteriorBox
{
    int x;
    int y;
    int width;
    int height;
};

struct InteriorBox
{
    char *content;
    char *cursor;
    bool isEnabled;
    bool keyboardPress;
    int x;
    int y;
    int asciiSubstractionValue; // -48
};

I created a function to handle the text box using the 2 structures. The temp variable will be crucial in displaying the values.

void TextBoxHandler(TTF_Font *font, SDL_Renderer *renderer, struct ExteriorBox exteriorbox, 
                    struct InteriorBox interiorTextBox, size_t length)
{
    SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
    SDL_FRect exteriorBoxRect = {exteriorbox.x, exteriorbox.y, exteriorbox.width, exteriorbox.height};
    SDL_RenderRect(renderer, &exteriorBoxRect);

    // Textbox text
    if (interiorTextBox.isEnabled)
    {
        char *temp = calloc(length + 1, sizeof(char));
        SDL_Color fontColor = {0xFF, 0xFF, 0xFF, 0xFF};
        strcpy(temp, interiorTextBox.content);
        strcat(temp, interiorTextBox.cursor);
        SDL_Surface *interiorTextSurface = TTF_RenderText_Solid(font, temp, fontColor);
        SDL_Texture *interiortextTexture = SDL_CreateTextureFromSurface(renderer, interiorTextSurface);
        SDL_FRect interiorBoxRect = {    exteriorbox.x, exteriorbox.y, 
                                                                    interiorTextSurface->w, 
                                                                    interiorTextSurface->h};

        SDL_RenderTexture(renderer, interiortextTexture, NULL, &interiorBoxRect);
        SDL_DestroySurface(interiorTextSurface);
        interiorTextSurface = NULL;
        SDL_DestroyTexture(interiortextTexture);
        interiortextTexture = NULL;
        free(temp);
        temp = NULL;
    }
}

Additionally, I added a function that returns a boolean value to check if the user's cursor is within the boundaries of the exterior box.

bool IsHoveringExteriorBox(int mouseX, int mouseY, struct ExteriorBox exteriorBox)
{
    if (mouseX >= exteriorBox.x && mouseX <= exteriorBox.x + exteriorBox.width)
    {
        if (mouseY >= exteriorBox.y && mouseY <= exteriorBox.y + exteriorBox.height)
        {
            return true;
        }
    }

    return false;
}

Then, I combined everything in the main.c source file.


case SDL_EVENT_MOUSE_BUTTON_UP:
    printf("Button %u\n", mouseState);
    if (mouseState == LEFT_MOUSE_BUTTON)
    {
        if (IsHoveringExteriorBox(mouseX, mouseY, exteriorTextBox))
        {
            if(!interiorTextBox.isEnabled)
            {
                interiorTextBox.isEnabled = true;
            }
            break;
        }

        interiorTextBox.isEnabled = false;
    }
    break;
case SDL_EVENT_KEY_UP:
    switch(events.key.keysym.sym)
    {
        case SDLK_ESCAPE:
            interiorTextBox.isEnabled = false;
            break;

    }
    break;

TextBoxHandler( appFont, appRenderer, exteriorTextBox, 
                interiorTextBox, strlen(interiorTextBox.content));

Now, when the user clicks the left mouse button inside the boundaries of the exterior box, a cursor appears. If the left mouse button is clicked outside these boundaries or the Escape key is pressed, the cursor disappears.

Demonstration