gui.cpp

来自「一个由Mike Gashler完成的机器学习方面的includes neural」· C++ 代码 · 共 479 行

CPP
479
字号
// --------------------------------------------------------
// This demo file is dedicated to the Public Domain. See:
// http://creativecommons.org/licenses/publicdomain
// --------------------------------------------------------

#include "Gui.h"
#include "../GClasses/GSDL.h"
#include "../GClasses/GArff.h"
#include "../GClasses/GImage.h"
#include "../GClasses/GFile.h"
#ifdef WIN32
#include <windows.h>
#endif // WIN32

ViewBase::ViewBase()
{
	SetScreenSize(1010, 690);
}

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->GetPixelArray();
		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 = (Uint16)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) < pImage->GetWidth(), "Extends past source image width");
	float fSourceDY = (float)(pImage->GetHeight() - 1) / (float)(pDestRect->h - 1);
	GAssert((int)((pDestRect->h - 1) * fSourceDY) < 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) = (Uint16)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;
	if(pScreen->format->BytesPerPixel == 4)
	{
		// 32 bits per pixel
		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
					);
			}
		}
	}
	else
	{
		// 16 bits per pixel
		GAssert(pScreen->format->BytesPerPixel == 2, "Only 16 and 32 bit video modes are supported");
		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;
				*getPixMem16(pScreen, xx, yy) =	
					(Uint16)SDL_MapRGB(pScreen->format,
						(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;
/*static*/ GImage* ControllerBase::s_pManualImage = 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_mouseX = -1;
	m_mouseY = -1;
	m_eKeyState = Normal;
	m_lastPressedKey = SDLK_UNKNOWN;
}

ControllerBase::~ControllerBase()
{
}

// static
void ControllerBase::SetAppPath(char* szAppPath)
{
	s_szAppPath = szAppPath;

	// load the manual image
	char szManualImageFilename[512];
	strcpy(szManualImageFilename, szAppPath);
	strcat(szManualImageFilename, "manual.png");
	s_pManualImage = new GImage();
	s_pManualImage->LoadPNGFile(szManualImageFilename);
}

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;
				m_pView->OnMouseDown(event.button.button, m_mouseX, m_mouseY);
				bRet = true;
				break;
	
			case SDL_MOUSEBUTTONUP:
				m_mouse[event.button.button] = 0;
				m_pView->OnMouseUp(event.button.button, m_mouseX, m_mouseY);
				bRet = true;
				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 OpenFile(const char* szFilename)
{
	printf("Opening file \"%s\"\n", szFilename);
#ifdef WIN32
	ShellExecute(NULL, NULL, szFilename, NULL, NULL, SW_SHOW);
#else
#ifdef DARWIN
	// Mac
	GTEMPBUF(char, pBuf, 32 + strlen(szFilename));
	strcpy(pBuf, "open ");
	strcat(pBuf, szFilename);
	strcat(pBuf, " &");
	system(pBuf);
#else // DARWIN
	GTEMPBUF(char, pBuf, 32 + strlen(szFilename));
/*
	// KDE
	//strcpy(pBuf, "kfmclient exec ");
	strcpy(pBuf, "konqueror ");
	strcat(pBuf, szFilename);
	strcat(pBuf, " &");
	system(pBuf);
*/
	// Gnome
	strcpy(pBuf, "gnome-open ");
	strcat(pBuf, szFilename);
	system(pBuf);
#endif // !DARWIN
#endif // !WIN32
}


void OpenAppFile(const char* szRelativeFilename)
{
	const char* szAppPath = ControllerBase::GetAppPath();
	GTEMPBUF(char, szFilename, strlen(szAppPath) + strlen(szRelativeFilename) + 1);
	strcpy(szFilename, szAppPath);
	strcat(szFilename, szRelativeFilename);
	GFile::CondensePath(szFilename);
	OpenFile(szFilename);
}

// -----------------------------------------------------------------------------------------------


GWidgetRelation::GWidgetRelation(GArffRelation* pRelation, GWidgetGroup* pParent, int x, int y, int w, int h)
 : GWidgetGrid(pParent, MakeRows(), pRelation->GetAttributeCount(), x, y, w, h)
{
	m_pRelation = pRelation;
	int n;
	for(n = 0; n < pRelation->GetAttributeCount(); n++)
	{
		GArffAttribute* pAttr = pRelation->GetAttribute(n);
		GWidgetTextTab* pTab = new GWidgetTextTab(this, 0, 0, 80, 20, pAttr->GetName());
		pTab->SetSelected(!pAttr->IsInput());
		SetColumnHeader(n, pTab);
	}
}

// virtual
GWidgetRelation::~GWidgetRelation()
{
	delete(m_pRows);
}

GPointerArray* GWidgetRelation::MakeRows()
{
	m_pRows = new GPointerArray(256);
	return m_pRows;
}

// virtual
void GWidgetRelation::OnSelectTextTab(GWidgetTextTab* pTab)
{
	int i;
	for(i = 0; i < m_pRelation->GetAttributeCount(); i++)
	{
		if(GetColumnHeader(i) == pTab)
		{
			GArffAttribute* pAttr = m_pRelation->GetAttribute(i);
			pTab->SetSelected(!pTab->IsSelected());
			pAttr->SetIsInput(!pTab->IsSelected());
			return;
		}
	}
	GAssert(false, "couldn't find column header");
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?