05 - Scrollbar 源码

#include <stdlib.h>
#include "SDL.h"

// If you're going to render widgets to the same
// UI from different source files, you can avoid
// ID collisions by defining IMGUI_SRC_ID before
// this define block:
#ifdef IMGUI_SRC_ID
#define GEN_ID ((IMGUI_SRC_ID) + (__LINE__))
#else
#define GEN_ID (__LINE__)
#endif

// Screen surface
SDL_Surface *gScreen;

struct UIState
{
  int mousex;
  int mousey;
  int mousedown;

  int hotitem;
  int activeitem;
} 
uistate = {0,0,0,0,0};

// Simplified interface to SDL's fillrect call
void drawrect(int x, int y, int w, int h, int color)
{
  SDL_Rect r;
  r.x = x;
  r.y = y;
  r.w = w;
  r.h = h;
  SDL_FillRect(gScreen, &r, color);
}


// Check whether current mouse position is within a rectangle
int regionhit(int x, int y, int w, int h)
{
  if (uistate.mousex < x ||
    uistate.mousey < y ||
    uistate.mousex >= x + w ||
    uistate.mousey >= y + h)
    return 0;
  return 1;
}

// Simple button IMGUI widget
int button(int id, int x, int y)
{
  // Check whether the button should be hot
  if (regionhit(x, y, 64, 48))
  {
    uistate.hotitem = id;
    if (uistate.activeitem == 0 && uistate.mousedown)
      uistate.activeitem = id;
  }

  // Render button 
  drawrect(x+8, y+8, 64, 48, 0);
  if (uistate.hotitem == id)
  {
    if (uistate.activeitem == id)
    {
      // Button is both 'hot' and 'active'
      drawrect(x+2, y+2, 64, 48, 0xffffff);
    }
    else
    {
      // Button is merely 'hot'
      drawrect(x, y, 64, 48, 0xffffff);
    }
  }
  else
  {
    // button is not hot, but it may be active    
    drawrect(x, y, 64, 48, 0xaaaaaa);
  }

  // If button is hot and active, but mouse button is not
  // down, the user must have clicked the button.
  if (uistate.mousedown == 0 && 
    uistate.hotitem == id && 
    uistate.activeitem == id)
    return 1;

  // Otherwise, no clicky.
  return 0;
}

// Simple scroll bar IMGUI widget
int slider(int id, int x, int y, int max, int &value)
{
  // Calculate mouse cursor's relative y offset
  int ypos = ((256 - 16) * value) / max;

  // Check for hotness
  if (regionhit(x+8, y+8, 16, 255))
  {
    uistate.hotitem = id;
    if (uistate.activeitem == 0 && uistate.mousedown)
      uistate.activeitem = id;
  }

  // Render the scrollbar
  drawrect(x, y, 32, 256+16, 0x777777);
  
  if (uistate.activeitem == id || uistate.hotitem == id)
  {
    drawrect(x+8, y+8 + ypos, 16, 16, 0xffffff);
  }
  else
  {
    drawrect(x+8, y+8 + ypos, 16, 16, 0xaaaaaa);
  }

  // Update widget value
  if (uistate.activeitem == id)
  {
    int mousepos = uistate.mousey - (y + 8);
    if (mousepos < 0) mousepos = 0;
    if (mousepos > 255) mousepos = 255;
    int v = (mousepos * max) / 255;
    if (v != value)
    {
      value = v;
      return 1;
    }
  }
  
  return 0;
}

void imgui_prepare()
{
  uistate.hotitem = 0;
}

void imgui_finish()
{
  if (uistate.mousedown == 0)
  {
    uistate.activeitem = 0;
  }
  else
  {
    if (uistate.activeitem == 0)
      uistate.activeitem = -1;
  }
}

// Rendering function
void render()
{   
  static int bgcolor = 0x77;

  // clear screen
  drawrect(0,0,640,480,bgcolor);

  imgui_prepare();

  button(GEN_ID,50,50);
  
  button(GEN_ID,150,50);
  
  if (button(GEN_ID,50,150))
    bgcolor = (SDL_GetTicks() * 0xc0cac01a) | 0x77;
  
  if (button(GEN_ID,150,150))
    exit(0);

  int slidervalue = bgcolor & 0xff;
  if (slider(GEN_ID, 500, 40, 255, slidervalue))
  {
    bgcolor = (bgcolor & 0xffff00) | slidervalue;
  }

  slidervalue = ((bgcolor >> 10) & 0x3f);
  if (slider(GEN_ID, 550, 40, 63, slidervalue))
  {
    bgcolor = (bgcolor & 0xff00ff) | (slidervalue << 10);
  }

  slidervalue = ((bgcolor >> 20) & 0xf);
  if (slider(GEN_ID, 600, 40, 15, slidervalue))
  {
    bgcolor = (bgcolor & 0x00ffff) | (slidervalue << 20);
  }


  imgui_finish();

  // update the screen
    SDL_UpdateRect(gScreen, 0, 0, 640, 480);    

  // don't take all the cpu time
  SDL_Delay(10); 
}


// Entry point
int main(int argc, char *argv[])
{
  // Initialize SDL's subsystems - in this case, only video.
    if (SDL_Init(SDL_INIT_VIDEO) < 0) 
  {
        fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
        exit(1);
    }

  // Register SDL_Quit to be called at exit; makes sure things are
  // cleaned up when we quit.
    atexit(SDL_Quit);
    
  // Attempt to create a 640x480 window with 32bit pixels.
    gScreen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
  
  // If we fail, return error.
    if (gScreen == NULL) 
  {
        fprintf(stderr, "Unable to set up video: %s\n", SDL_GetError());
        exit(1);
    }

  // Main loop: loop forever.
    while (1)
    {
    // Render stuff
        render();

    // Poll for events, and handle the ones we care about.
        SDL_Event event;
        while (SDL_PollEvent(&event)) 
        {
            switch (event.type) 
            {
      case SDL_MOUSEMOTION:
        // update mouse position
        uistate.mousex = event.motion.x;
        uistate.mousey = event.motion.y;
        break;
      case SDL_MOUSEBUTTONDOWN:
        // update button down state if left-clicking
        if (event.button.button == 1)
          uistate.mousedown = 1;
        break;
      case SDL_MOUSEBUTTONUP:
        // update button down state if left-clicking
        if (event.button.button == 1)
          uistate.mousedown = 0;
        break;
            case SDL_KEYUP:                  
        switch (event.key.keysym.sym)
        {
        case SDLK_ESCAPE:
          // If escape is pressed, return (and thus, quit)
          return 0;
        }
                break;
            case SDL_QUIT:
                return(0);
            }
        }
    }
    return 0;
}

 

posted @ 2017-03-29 10:48  夜梦多离殇  阅读(132)  评论(0)    收藏  举报