📄 gui.cpp
字号:
// ********************************************************// This is demo code. You may derive from, use, modify, and// distribute it without limitation for any purpose.// Obviously you don't get a warranty or an assurance of// fitness for a particular purpose with this code. Your// welcome to remove this header and claim original// authorship. I really don't care.// ********************************************************#include "Gui.h"#include "../GClasses/GSDL.h"#ifdef WIN32#include <windows.h>#endif // WIN32ViewBase::ViewBase(){ SetScreenSize(800, 600);}ViewBase::~ViewBase(){}void ViewBase::SetScreenSize(int x, int y){ unsigned int flags = // SDL_FULLSCREEN |// SDL_HWSURFACE | SDL_SWSURFACE |// SDL_DOUBLEBUF | SDL_ANYFORMAT; m_pScreen = SDL_SetVideoMode(x, y, 32, flags); if(!m_pScreen) { GAssert(false, SDL_GetError()); throw "failed to create SDL screen"; } m_screenRect.x = 5; m_screenRect.y = 5; m_screenRect.w = m_pScreen->w - 10; m_screenRect.h = m_pScreen->h - 10;}/*static*/ void ViewBase::BlitImage(SDL_Surface* pScreen, int x, int y, GImage* pImage){ if(pScreen->format->BytesPerPixel == 4) { // 32 bits per pixel GColor* pRGB = pImage->GetRGBQuads(); int w = pImage->GetWidth(); int h = pImage->GetHeight(); int yy; Uint32* pPix; for(yy = 0; yy < h; yy++) { pPix = getPixMem32(pScreen, x, y); memcpy(pPix, &pRGB[yy * w], w * sizeof(GColor)); y++; } } else { // 16 bits per pixel GAssert(pScreen->format->BytesPerPixel == 2, "Only 16 and 32 bit video modes are supported"); int w = pImage->GetWidth(); int h = pImage->GetHeight(); int xx, yy, xxx; GColor colIn; Uint16* pPix; for(yy = 0; yy < h; yy++) { xxx = x; pPix = (Uint16*)pScreen->pixels + y * pScreen->pitch / 2 + x; for(xx = 0; xx < w; xx++) { colIn = pImage->GetPixel(xx, yy); *pPix = SDL_MapRGB(pScreen->format, gRed(colIn), gGreen(colIn), gBlue(colIn)); xxx++; pPix++; } y++; } }}/*static*/ void ViewBase::StretchClipAndBlitImage(SDL_Surface* pScreen, GRect* pDestRect, GRect* pClipRect, GImage* pImage){ float fSourceDX = (float)(pImage->GetWidth() - 1) / (float)(pDestRect->w - 1); GAssert((int)((pDestRect->w - 1) * fSourceDX) < (int)pImage->GetWidth(), "Extends past source image width"); float fSourceDY = (float)(pImage->GetHeight() - 1) / (float)(pDestRect->h - 1); GAssert((int)((pDestRect->h - 1) * fSourceDY) < (int)pImage->GetHeight(), "Extends past source image height"); float fSourceX = 0; float fSourceY = 0; int xStart = pDestRect->x; int yStart = pDestRect->y; if(pClipRect->x > xStart) { xStart = pClipRect->x; fSourceX = (pClipRect->x * pDestRect->x) * fSourceDX; } if(pClipRect->y > yStart) { yStart = pClipRect->y; fSourceY = (pClipRect->y * pDestRect->y) * fSourceDY; } int xEnd = MIN(pDestRect->x + pDestRect->w, pClipRect->x + pClipRect->w); int yEnd = MIN(pDestRect->y + pDestRect->h, pClipRect->y + pClipRect->h); int x, y; float fSX; if(pScreen->format->BytesPerPixel == 4) { // 32 bits per pixel for(y = yStart; y < yEnd; y++) { fSX = fSourceX; for(x = xStart; x < xEnd; x++) { *getPixMem32(pScreen, x, y) = pImage->GetPixel((int)fSX, (int)fSourceY); fSX += fSourceDX; } fSourceY += fSourceDY; } } else { // 16 bits per pixel GAssert(pScreen->format->BytesPerPixel == 2, "Only 16 and 32 bit video modes are supported"); GColor colIn; for(y = yStart; y < yEnd; y++) { fSX = fSourceX; for(x = xStart; x < xEnd; x++) { colIn = pImage->GetPixel((int)fSX, (int)fSourceY); *getPixMem16(pScreen, x, y) = SDL_MapRGB(pScreen->format, gRed(colIn), gGreen(colIn), gBlue(colIn)); fSX += fSourceDX; } fSourceY += fSourceDY; } }}void ViewBase::DrawDot(SDL_Surface *pScreen, int x, int y, GColor col, int nSize){ int nWhiteAmount; int nColorAmount; int xx, yy; int nYMax = MIN(y + nSize, m_screenRect.y + m_screenRect.h); int nXMax = MIN(x + nSize, m_screenRect.x + m_screenRect.w); int nSizeSquared = nSize * nSize; int nDoubleSizeSquared = nSizeSquared + nSizeSquared; for(yy = MAX(m_screenRect.y, y - nSize); yy < nYMax; yy++) { for(xx = MAX(m_screenRect.x, x - nSize); xx < nXMax; xx++) { nWhiteAmount = (x - xx) * (x - xx) + (y - yy) * (y - yy); if(nWhiteAmount > nSizeSquared) continue; nWhiteAmount += nWhiteAmount; nColorAmount = nDoubleSizeSquared - nWhiteAmount; *getPixMem32(pScreen, xx, yy) = gARGB( 0xff, (nColorAmount * gRed(col)/* + nWhiteAmount * 0xff*/) / nDoubleSizeSquared, (nColorAmount * gGreen(col)/* + nWhiteAmount * 0xff*/) / nDoubleSizeSquared, (nColorAmount * gBlue(col)/* + nWhiteAmount * 0xff*/) / nDoubleSizeSquared ); } }}void ViewBase::Update(){ // Lock the screen for direct access to the pixels SDL_Surface *pScreen = m_pScreen; if ( SDL_MUSTLOCK(pScreen) ) { if ( SDL_LockSurface(pScreen) < 0 ) { GAssert(false, SDL_GetError()); // failed to lock the surface return; } } // Draw the screen Draw(pScreen); // Unlock the screen if ( SDL_MUSTLOCK(pScreen) ) SDL_UnlockSurface(pScreen); // Update the whole screen SDL_UpdateRect(pScreen, m_screenRect.x, m_screenRect.y, m_screenRect.w, m_screenRect.h);}// -------------------------------------------------------------------#define KEY_REPEAT_DELAY .3#define KEY_REPEAT_RATE .01/*static*/ char* ControllerBase::s_szAppPath = NULL;ControllerBase::ControllerBase(){ m_pView = NULL; m_bKeepRunning = true; // Init the keyboard int n; for(n = 0; n < SDLK_LAST; n++) m_keyboard[n] = 0; m_mouse[1] = 0; m_mouse[2] = 0; m_mouse[3] = 0; m_bMouseDown = false; m_mouseX = -1; m_mouseY = -1; m_eKeyState = Normal; m_lastPressedKey = SDLK_UNKNOWN;}ControllerBase::~ControllerBase(){}bool ControllerBase::HandleEvents(double dTimeDelta){ GAssert(m_pView, "m_pView should be set in the constructor"); // Check for events bool bRet = false; SDL_Event event; while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_KEYDOWN: m_keyboard[event.key.keysym.sym] = 1; HandleKeyPress(event.key.keysym.sym, event.key.keysym.mod); bRet = true; break; case SDL_KEYUP: m_keyboard[event.key.keysym.sym] = 0; m_eKeyState = Normal; break; case SDL_MOUSEBUTTONDOWN: m_mouse[event.button.button] = 1; m_mouseX = event.button.x; m_mouseY = event.button.y; bRet = true; HandleMouseClick(); break; case SDL_MOUSEBUTTONUP: m_mouse[event.button.button] = 0; bRet = true; HandleMouseClick(); break; case SDL_MOUSEMOTION: m_mouseX = event.motion.x; m_mouseY = event.motion.y; break; case SDL_QUIT: m_bKeepRunning = false; break; default: break; } } if(bRet) { } else if(m_keyboard[m_lastPressedKey]) { switch(m_eKeyState) { case Normal: m_eKeyState = Holding; m_dKeyRepeatTimer = 0; return false; // don't bother updating the display case Holding: m_dKeyRepeatTimer += dTimeDelta; if(m_dKeyRepeatTimer >= KEY_REPEAT_DELAY) { m_dKeyRepeatTimer = 0; m_eKeyState = Repeating; } return false; // don't bother updating the display case Repeating: m_dKeyRepeatTimer += dTimeDelta; if(m_dKeyRepeatTimer > KEY_REPEAT_RATE) { m_dKeyRepeatTimer -= KEY_REPEAT_RATE; HandleKeyPress(m_lastPressedKey, event.key.keysym.mod); } break; default: GAssert(false, "unexpected case"); } } else if(m_pView->OnMousePos(m_mouseX, m_mouseY)) { } else { m_eKeyState = Normal; return false; // false = don't bother updating the view } return true; // true = need to update the view}void ControllerBase::HandleKeyPress(SDLKey key, SDLMod mod){ if(key > SDLK_z) { int dx = m_keyboard[SDLK_RIGHT] - m_keyboard[SDLK_LEFT]; int dy = m_keyboard[SDLK_DOWN] - m_keyboard[SDLK_UP]; // todo: do something return; } if(key == SDLK_ESCAPE) { m_bKeepRunning = false; return; } char cKey; if(key == SDLK_BACKSPACE) cKey = '\b'; else if(key == SDLK_RETURN) cKey = '\r'; else if(key < SDLK_SPACE) return; cKey = (char)key; // Capitalize if shift is down if(mod & KMOD_SHIFT) cKey = GSDL::ShiftKey(cKey); m_pView->OnChar(cKey); m_lastPressedKey = key;}void ControllerBase::HandleMouseClick(){ if(m_mouse[1]) // left button { if(!m_bMouseDown) { m_pView->OnMouseDown(m_mouseX, m_mouseY); m_bMouseDown = true; } } else { if(m_bMouseDown) { m_pView->OnMouseUp(m_mouseX, m_mouseY); m_bMouseDown = false; } }}void OpenFile(const char* szFilename){#ifdef WIN32 ShellExecute(NULL, NULL, szFilename, NULL, NULL, SW_SHOW);#else GTEMPBUF(char, pBuf, 32 + strlen(szFilename)); // KDE strcpy(pBuf, "konqueror "); strcat(pBuf, szFilename); strcat(pBuf, " &"); system(pBuf); // Gnome strcpy(pBuf, "open "); strcat(pBuf, szFilename); strcat(pBuf, " &"); system(pBuf);#endif // !WIN32}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -