Membuat Tombol Sederhana

Kita akan menerapkan dan mengembangkan apa yang sudah kita pelajari sebelumnya dengan membuat tombol sederhana. SDL tidak menyediakan function untuk membuat tombol. Karena itu, kita harus membuat custom button dengan menggunakan potongan gambar. Gambar yang akan kita gunakan kali ini adalah gambar seperti di bawah ini. Nama gambarnya adalah "tombol.png" sesuai parameter dalam function IMG_load. Karena kita menggunakan IMG_Load dalam program, pastikan SDL_Image sudah terinstal jika kalian menggunakan linux. Jika kalian menggunakan windows, pastikan dll-nya sudah diletakkan di folder project atau program.

Potongan gambar yang pertama kali kita tampilkan bisa potongan manapun. Saat area tombol diklik atau dilewati, kita bisa mengubah potongan yang kita tampilkan. Untuk mengecek apakah pointer mouse sudah berada di dalam area tombol, kalian perlu menggunakan percabangan untuk mengecek koordinatnya.
#include <math.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#define playar 640
#define tlayar 480

int main(int argc, char* args[]){
    SDL_Window* window = NULL;
    SDL_Event evt;

    SDL_Rect rct, rcd;
    int xpos=0, ypos=0, pas=0, tinggi=0;

    if( SDL_Init( SDL_INIT_VIDEO ) < 0){
        printf( "Error: %s\n", SDL_GetError() );
    }else{
        window = SDL_CreateWindow( "SDLku", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, playar, tlayar, SDL_WINDOW_SHOWN );
        if( window == NULL ){
            printf( "Error : %s", SDL_GetError() );
        }else{
            SDL_Renderer *trender = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED);
            SDL_Surface* tmp=IMG_Load("tombol.png");
            SDL_Texture* gambar=SDL_CreateTextureFromSurface(trender, tmp);
    
            if(gambar){
                tinggi=tmp->h/3;
                rct.x=0;
                rct.y=0;
                rct.w=tmp->w;
                rct.h=tinggi;
            
                rcd.x=280;
                rcd.y=280;
                rcd.w=tmp->w;
                rcd.h=tinggi;
                SDL_FreeSurface(tmp);

                while(evt.type!=SDL_QUIT){
                    while(SDL_PollEvent(&evt)){
                        if(evt.type==SDL_MOUSEBUTTONDOWN){
                            //tambahkan aksi yang ingin dilakukan di sini
                        }
                    }
                    xpos=evt.button.x;
                    ypos=evt.button.y;
            
                    
                    SDL_SetRenderDrawColor(trender, 0xFF, 0xFF, 0xFF, 0xFF);
                    SDL_RenderClear(trender);
                    if((xpos>rcd.x && xpos <=(rcd.x+rcd.w)) && (ypos>rcd.y && ypos <=(rcd.y+rcd.h))){
                        pas=1;
                    }else pas=0;
      
                    if(pas==1){
                        if(evt.button.state==SDL_PRESSED)rct.y=tinggi+tinggi;
                        else rct.y=tinggi;
                    }else rct.y=0;
                    SDL_RenderCopy(trender, gambar, &rct, &rcd);
                    SDL_RenderPresent(trender);
                }
                SDL_DestroyTexture(gambar);
            }        
        }
    }

    SDL_DestroyWindow( window );
    SDL_Quit();

    return 0;
}

Karena pengecekkan dilakukan berdasarkan "bounding box" atau kotak terkecil yang bisa mengurung suatu area, maka tampilan "tidak hanya" berubah saat area tombol diklik. Tombol akan berubah saat area berbentuk persegi di sekitar tombol diklik, termasuk pada area transparan gambar. Pada kode program berikut ini, saya akan menambahkan kotak di sekeliling tombol dengan SDL_RenderDrawRect.
#include <math.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#define playar 640
#define tlayar 480

int main(int argc, char* args[]){
    SDL_Window* window = NULL;
    SDL_Event evt;

    SDL_Rect rct, rcd;
    int xpos=0, ypos=0, pas=0, tinggi=0;

    if( SDL_Init( SDL_INIT_VIDEO ) < 0){
        printf( "Error: %s\n", SDL_GetError() );
    }else{
        window = SDL_CreateWindow( "SDLku", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, playar, tlayar, SDL_WINDOW_SHOWN );
        if( window == NULL ){
            printf( "Error : %s", SDL_GetError() );
        }else{
            SDL_Renderer *trender = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED);
            SDL_Surface* tmp=IMG_Load("tombol.png");
            SDL_Texture* gambar=SDL_CreateTextureFromSurface(trender, tmp);
    
            if(gambar){
                tinggi=tmp->h/3;
                rct.x=0;
                rct.y=0;
                rct.w=tmp->w;
                rct.h=tinggi;
             
                rcd.x=280;
                rcd.y=280;
                rcd.w=tmp->w;
                rcd.h=tinggi;
                SDL_FreeSurface(tmp);

                while(evt.type!=SDL_QUIT){
                    while(SDL_PollEvent(&evt)){
                        if(evt.type==SDL_MOUSEBUTTONDOWN){
                            //tambahkan aksi yang ingin dilakukan di sini
                        }
                    }
                    xpos=evt.button.x;
                    ypos=evt.button.y;
            
                    SDL_SetRenderDrawColor(trender, 0xFF, 0xFF, 0xFF, 0xFF);
                    SDL_RenderClear(trender);
            
                    if((xpos>rcd.x && xpos <=(rcd.x+rcd.w)) && (ypos>rcd.y && ypos <=(rcd.y+rcd.h))){
                        pas=1;
                    }else pas=0;
  
                    if(pas==1){
                        if(evt.button.state==SDL_PRESSED)rct.y=tinggi+tinggi;
                        else rct.y=tinggi;
                    }else rct.y=0;
            
                    //bounding box
                    SDL_SetRenderDrawColor(trender, 0xFF, 0x00, 0x00, 0xFF);
                    SDL_RenderDrawRect(trender, &rcd);
                    //gambar
                    SDL_RenderCopy(trender, gambar, &rct, &rcd);
                    SDL_RenderPresent(trender);
                }
                SDL_DestroyTexture(gambar);
            }        
        }
    }

    SDL_DestroyWindow( window );
    SDL_Quit();

    return 0;
}


Seperti yang sudah saya jelaskan bounding box / rectangle adalah area kotak di sekitar gambar. Pada contoh kode program di atas, saya menandainya dengan kotak merah. Kalau kalian melakukan klik di luar kotak merah, maka tombol tidak akan berubah tampilannya. Tombol hanya akan berubah tampilannya jika pointer mouse berada di dalam bounding box.

Multiple Button

Kode program di atas bisa diubah jika tombol yang ingin kita tampilkan ada lebih dari satu. Kita perlu menggunakan loop sehingga kode programnya jadi seperti di bawah ini.

#include <math.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#define playar 640
#define tlayar 480
#define jtombol 3

struct info_tombol{
    int x, y;
}tombolku[jtombol];

int main(int argc, char* args[]){
    SDL_Window* window = NULL;
    SDL_Event evt;

    SDL_Rect rct, rcd;
    int xpos=0, ypos=0, pas=0, tinggi=0;

    if( SDL_Init( SDL_INIT_VIDEO ) < 0){
        printf( "Error: %s\n", SDL_GetError() );
    }else{
        window = SDL_CreateWindow( "SDLku", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, playar, tlayar, SDL_WINDOW_SHOWN );
        if( window == NULL ){
            printf( "Error : %s", SDL_GetError() );
        }else{
            SDL_Renderer *trender = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED);
            SDL_Surface* tmp=IMG_Load("tombol.png");
            SDL_Texture* gambar=SDL_CreateTextureFromSurface(trender, tmp);

            if(gambar){
                tinggi=tmp->h/3;
                rct.x=0;
                rct.y=0;
                rct.w=tmp->w;
                rct.h=tinggi;

                rcd.w=tmp->w;
                rcd.h=tinggi;
                SDL_FreeSurface(tmp);


                //Atur posisi 3 tombol
                for(int i=0;i<jtombol;i++){
                    tombolku[i].x=280;
                    tombolku[i].y=(i*(tinggi+12))+100;
                }

                while(evt.type!=SDL_QUIT){
                    while(SDL_PollEvent(&evt)){
                        if(evt.type==SDL_MOUSEBUTTONDOWN){
                            //tambahkan aksi yang ingin dilakukan di sini
                        }
                    }
                    //simpan posisi mouse
                    xpos=evt.button.x;
                    ypos=evt.button.y;

                    SDL_SetRenderDrawColor(trender, 0xFF, 0xFF, 0xFF, 0xFF);
                    SDL_RenderClear(trender);

                    for(int i=0;i<jtombol;i++){
                        rcd.x=tombolku[i].x;
                        rcd.y=tombolku[i].y;

                        if((xpos>tombolku[i].x && xpos <=(tombolku[i].x+rcd.w)) && (ypos>tombolku[i].y && ypos <=(tombolku[i].y+rcd.h))){
                            pas=1;
                        }else pas=0;

                        if(pas==1){
                            if(evt.button.state==SDL_PRESSED)rct.y=tinggi+tinggi;
                            else rct.y=tinggi;
                        }else rct.y=0;
                        SDL_RenderCopy(trender, gambar, &rct, &rcd);
                    }
                    SDL_RenderPresent(trender);
                }
                SDL_DestroyTexture(gambar);
            }
        }
    }

    SDL_DestroyWindow( window );
    SDL_Quit();

    return 0;
}

Kode program tersebut memerlukan array of struct untuk menyimpan posisi tiap tombol beserta informasi lain yang bisa kalian tambahkan. Kebetulan, di sini kita hanya membuat tombol dengan ukuran dan tampilan yang sama.

Kalau malas mengetik, silakan download kode programnya di sini.