Day 84/100 100 Days of Code

Chris DourisChris Douris
2 min read

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

0
Subscribe to my newsletter

Read articles from Chris Douris directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Chris Douris
Chris Douris

AKA Chris, is a software developer from Athens, Greece. He started programming with basic when he was very young. He lost interest in programming during school years but after an unsuccessful career in audio, he decided focus on what he really loves which is technology. He loves working with older languages like C and wants to start programming electronics and microcontrollers because he wants to get into embedded systems programming.