⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gwidgets.cpp

📁 一个非常有用的开源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*	Copyright (C) 2006, Mike Gashler	This library is free software; you can redistribute it and/or	modify it under the terms of the GNU Lesser General Public	License as published by the Free Software Foundation; either	version 2.1 of the License, or (at your option) any later version.	see http://www.gnu.org/copyleft/lesser.html*/#include "GWidgets.h"#include "GImage.h"#include "GArray.h"#include "GDirList.h"#ifdef WIN32#include <direct.h>#else // WIN32#include <unistd.h>#endif // !WIN32#include "GFile.h"#include <math.h>GWidgetStyle::GWidgetStyle(){	m_nButtonFontSize = 14;	m_nLabelFontSize = 14;	m_fButtonFontWidth = (float).8;	m_fLabelFontWidth = (float)1;	m_cButtonTextColor = 0xff000000;	m_cLabelTextColor = 0xff8888ff;	m_cButtonPressedTextColor = gRGB(255, 255, 255);	m_cTextBoxBorderColor = gRGB(255, 255, 255);	m_cTextBoxTextColor = gRGB(255, 255, 255);}GWidgetStyle::~GWidgetStyle(){}void GWidgetStyle::DrawButtonText(GImage* pImage, int x, int y, int w, int h, GString* pString, bool pressed){	int nTempBufLen = pString->GetLength() + 1;	GTEMPBUF(char, szText, nTempBufLen);	pString->GetAnsi(szText);	int nButtonFontSize = m_nButtonFontSize;	if(h < nButtonFontSize)		nButtonFontSize = h;	int wid = pImage->MeasureHardTextWidth(nButtonFontSize, szText, m_fButtonFontWidth);	GRect r;	r.x = x + (w - wid) / 2;	if(r.x < x)		r.x = x;	r.y = y + (h - nButtonFontSize) / 2;	if(r.y < y)		r.y = y;	r.w = w - (r.x - x);	r.h = nButtonFontSize;	pImage->DrawHardText(&r, szText, pressed ? m_cButtonPressedTextColor : m_cButtonTextColor, m_fButtonFontWidth);}void GWidgetStyle::DrawLabelText(GImage* pImage, int x, int y, int w, int h, GString* pString, bool alignLeft, GColor c){	int nTempBufLen = pString->GetLength() + 1;	GTEMPBUF(char, szText, nTempBufLen);	pString->GetAnsi(szText);	int nLabelFontSize = m_nLabelFontSize;	if(h < nLabelFontSize)		nLabelFontSize = h;	int wid = pImage->MeasureHardTextWidth(nLabelFontSize, szText, m_fLabelFontWidth);	GRect r;	if(alignLeft)		r.x = x;	else	{		r.x = x + w - wid;		if(r.x < x)			r.x = x;	}	r.y = y + (h - nLabelFontSize) / 2;	if(r.y < y)		r.y = y;	r.w = w - (r.x - x);	r.h = nLabelFontSize;	pImage->DrawHardText(&r, szText, c, m_fLabelFontWidth);}void GWidgetStyle::DrawHorizCurvedOutSurface(GImage* pImage, int x, int y, int w, int h){	if(w <= 0 || h <= 0)		return;	float fac = (float)1.1 / w;	int n;	for(n = 0; n < w; n++)	{		float t = (float)n * fac - (float).1;		int shade = (int)(255 * (1 - (t * t)));		pImage->DrawLine(x, y, x, y + h - 1, gRGB(shade, shade, 255));		x++;	}}void GWidgetStyle::DrawHorizCurvedInSurface(GImage* pImage, int x, int y, int w, int h, int colorMaskRed, int colorMaskGreen, int colorMaskBlue){	if(w <= 0 || h <= 0)		return;	int n;	for(n = 0; n < w; n++)	{		float t = (float)(n + n) / w - 1;		int shade = (int)(64 + 191 * ((t * t)));		pImage->DrawLine(x, y, x, y + h - 1, gRGB(colorMaskRed & shade, colorMaskGreen & shade, colorMaskBlue & shade));		x++;	}}void GWidgetStyle::DrawVertCurvedOutSurface(GImage* pImage, int x, int y, int w, int h){	float fac = (float)1.1 / h;	int yStart = 0;	if(y < 0)		yStart = -y;	if(y + h > (int)pImage->GetHeight())		h = pImage->GetHeight() - y;	int n;	for(n = yStart; n < h; n++)	{		float t = (float)n * fac - (float).1;		int shade = (int)(255 * (1 - (t * t)));		pImage->DrawLine(x, y, x + w - 1, y, gRGB(shade, shade, 255));		y++;	}}void GWidgetStyle::DrawVertCurvedInSurface(GImage* pImage, int x, int y, int w, int h){	int n;	for(n = 0; n < h; n++)	{		float t = (float)(n + n) / h - 1;		int shade = (int)(64 + 191 * ((t * t)));		pImage->DrawLine(x, y, x + w - 1, y, gRGB(0, 0, shade));		y++;	}}void GWidgetStyle::DrawCursor(GImage* pImage, int x, int y, int w, int h){	pImage->DrawBox(x, y, x + w, y + h, m_cTextBoxTextColor, false);}// ----------------------------------------------------------------------GWidget::GWidget(GWidgetGroup* pParent, int x, int y, int w, int h){	m_pParent = pParent;	m_pStyle = pParent ? pParent->GetStyle() : NULL;	m_rect.Set(x, y, w, h);	if(pParent)		pParent->AddWidget(this);	else		m_nID = -1;	GAssert(m_nDebugCheck = 0x600df00d, "");}/*virtual*/ GWidget::~GWidget(){	GAssert(DebugCheck(), "corruption!");	//GAssert(m_pParent || GetType() == Dialog, "Unexpected root widget");	if(m_pParent)		m_pParent->OnDestroyWidget(this);}#ifdef _DEBUGbool GWidget::DebugCheck(){	GAssert(m_nDebugCheck == 0x600df00d, "corruption!");	return true;}#endif // _DEBUGvoid GWidget::SetPos(int x, int y){	m_rect.x = x;	m_rect.y = y;	// todo: dirty the parent?}// ----------------------------------------------------------------------GWidgetAtomic::GWidgetAtomic(GWidgetGroup* pParent, int x, int y, int w, int h) : GWidget(pParent, x, y, w, h){}/*virtual*/ GWidgetAtomic::~GWidgetAtomic(){}void GWidgetAtomic::Draw(GWidgetGroupWithCanvas* pTarget){	GRect r, rTmp;	GImage* pSrcImage = GetImage(&r);	GImage* pCanvas;	int x = m_rect.x;	int y = m_rect.y;	GWidgetGroup* pGroup;	for(pGroup = this->GetParent(); pGroup; pGroup = pGroup->GetParent())	{		pCanvas = pGroup->GetImage(&rTmp);		if(pCanvas)			pCanvas->AlphaBlit(x, y, pSrcImage, &r);		if(pGroup == pTarget)			break;		x += pGroup->m_rect.x;		y += pGroup->m_rect.y;	}}/*virtual*/ void GWidgetAtomic::OnChar(char c){	if(m_pParent)		m_pParent->OnChar(c);}/*virtual*/ void GWidgetAtomic::OnMouseMove(int dx, int dy){}// ----------------------------------------------------------------------GWidgetGroup::GWidgetGroup(GWidgetGroup* pParent, int x, int y, int w, int h) : GWidget(pParent, x, y, w, h){	m_pWidgets = new GPointerArray(16);	m_dirty = true;}/*virtual*/ GWidgetGroup::~GWidgetGroup(){	GWidget* pWidget;	while(m_pWidgets->GetSize() > 0)	{		pWidget = (GWidget*)m_pWidgets->GetPointer(0);		delete(pWidget);	}	delete(m_pWidgets);}void GWidgetGroup::AddWidget(GWidget* pWidget){	m_pWidgets->AddPointer(pWidget);	pWidget->m_nID = m_pWidgets->GetSize() - 1;	m_dirty = true;}// todo: use a divide-and-conquer technique to improve performance/*virtual*/ GWidgetAtomic* GWidgetGroup::FindAtomicWidget(int x, int y){	int n;	int nCount = m_pWidgets->GetSize();	GWidget* pWidget;	for(n = 0; n < nCount; n++)	{		pWidget = (GWidget*)m_pWidgets->GetPointer(n);		if(pWidget->GetRect()->DoesInclude(x, y))		{			if(pWidget->IsAtomicWidget())				return (GWidgetAtomic*)pWidget;			else			{				GRect* pRect = pWidget->GetRect();				return ((GWidgetGroup*)pWidget)->FindAtomicWidget(x - pRect->x, y - pRect->y);			}		}	}	return NULL;}int GWidgetGroup::GetChildWidgetCount(){	return m_pWidgets->GetSize();}GWidget* GWidgetGroup::GetChildWidget(int n){	return (GWidget*)m_pWidgets->GetPointer(n);}/*virtual*/ void GWidgetGroup::OnDestroyWidget(GWidget* pWidget){	if(pWidget->m_nID >= 0)	{		// Remove the widget from my list		GAssert(GetChildWidget(pWidget->m_nID) == pWidget, "bad id");		int nLast = m_pWidgets->GetSize() - 1;		GWidget* pLast = (GWidget*)m_pWidgets->GetPointer(nLast);		pLast->m_nID = pWidget->m_nID;		m_pWidgets->SetPointer(pWidget->m_nID, pLast);		m_pWidgets->DeleteCell(nLast);		pWidget->m_nID = -1;		m_dirty = true;	}	if(m_pParent)		m_pParent->OnDestroyWidget(pWidget);}// ----------------------------------------------------------------------GWidgetGroupWithCanvas::GWidgetGroupWithCanvas(GWidgetGroup* pParent, int x, int y, int w, int h) : GWidgetGroup(pParent, x, y, w, h){	m_image.SetSize(w, h);}/*virtual*/ GWidgetGroupWithCanvas::~GWidgetGroupWithCanvas(){}/*virtual*/ GImage* GWidgetGroupWithCanvas::GetImage(GRect* pOutRect){	if(m_dirty)		Update();	pOutRect->x = 0;	pOutRect->y = 0;	pOutRect->w = m_image.GetWidth();	pOutRect->h = m_image.GetHeight();	return &m_image;}void GWidgetGroupWithCanvas::Draw(GWidgetGroupWithCanvas* pTarget){	GRect r, rTmp;	GImage* pSrcImage = GetImage(&r);	GImage* pCanvas;	int x = m_rect.x;	int y = m_rect.y;	GWidgetGroup* pGroup;	for(pGroup = this->GetParent(); pGroup; pGroup = pGroup->GetParent())	{		pCanvas = pGroup->GetImage(&rTmp);		if(pCanvas)			pCanvas->Blit(x, y, pSrcImage, &r);		if(pGroup == pTarget)			break;		x += pGroup->m_rect.x;		y += pGroup->m_rect.y;	}}// ----------------------------------------------------------------------GWidgetDialog::GWidgetDialog(int w, int h, GColor cBackground) : GWidgetGroupWithCanvas(NULL, 0, 0, w, h){	m_cBackground = cBackground;	m_pStyle = new GWidgetStyle();	m_pGrabbedWidget = NULL;	m_pFocusWidget = NULL;	m_prevMouseX = 0;	m_prevMouseY = 0;}/*virtual*/ GWidgetDialog::~GWidgetDialog(){	ReleaseWidget();	delete(m_pStyle);}/*virtual*/ void GWidgetDialog::Update(){	m_image.Clear(m_cBackground);	m_dirty = false;	int n;	int nCount = m_pWidgets->GetSize();	GWidget* pWidget;	for(n = 0; n < nCount; n++)	{		pWidget = (GWidget*)m_pWidgets->GetPointer(n);		pWidget->Draw(this);	}}void GWidgetDialog::SetFocusWidget(GWidgetAtomic* pWidget){	if(m_pFocusWidget != pWidget)	{		if(m_pFocusWidget)			m_pFocusWidget->OnLoseFocus();		m_pFocusWidget = pWidget;		if(pWidget)			pWidget->OnGetFocus();	}}void GWidgetDialog::GrabWidget(GWidgetAtomic* pWidget, int mouseX, int mouseY){	ReleaseWidget();	m_pGrabbedWidget = pWidget;	SetFocusWidget(pWidget);	if(pWidget)	{		GWidget* pTmp;		GRect* pRect;		for(pTmp = pWidget; pTmp; pTmp = pTmp->GetParent())		{			pRect = pTmp->GetRect();			mouseX -= pRect->x;			mouseY -= pRect->y;		}		pWidget->Grab(mouseX, mouseY);	}}void GWidgetDialog::ReleaseWidget(){	if(!m_pGrabbedWidget)		return;	// Use a local var in case the handler destroys this dialog	GWidgetAtomic* pGrabbedWidget = m_pGrabbedWidget;	m_pGrabbedWidget = NULL;	pGrabbedWidget->Release();}/*virtual*/ void GWidgetDialog::OnDestroyWidget(GWidget* pWidget){	if(pWidget == m_pGrabbedWidget)		m_pGrabbedWidget = NULL;	if(pWidget == m_pFocusWidget)		m_pFocusWidget = NULL;	GWidgetGroup::OnDestroyWidget(pWidget);}void GWidgetDialog::HandleChar(char c){	if(!m_pFocusWidget)		return;	m_pFocusWidget->OnChar(c);}bool GWidgetDialog::HandleMousePos(int x, int y){	x -= m_prevMouseX;	y -= m_prevMouseY;	if(x == 0 && y == 0)		return false;	m_prevMouseX += x;	m_prevMouseY += y;	if(!m_pGrabbedWidget)		return false;	m_pGrabbedWidget->OnMouseMove(x, y);	return true;}// ----------------------------------------------------------------------GWidgetTextButton::GWidgetTextButton(GWidgetGroup* pParent, int x, int y, int w, int h, GString* pText): GWidgetAtomic(pParent, x, y, w, h){	m_image.SetSize(w * 2, h);	m_text.Copy(pText);	m_pressed = false;	m_dirty = true;}/*virtual*/ GWidgetTextButton::~GWidgetTextButton(){}/*virtual*/ void GWidgetTextButton::Grab(int x, int y){	m_pressed = true;	Draw(NULL);	m_pParent->OnPushTextButton(this);}/*virtual*/ void GWidgetTextButton::Release(){	m_pressed = false;	Draw(NULL);	m_pParent->OnReleaseTextButton(this);}void GWidgetTextButton::Update(){	m_dirty = false;	// Draw the non-pressed image	int w = m_image.GetWidth() / 2;	int h = m_image.GetHeight();	m_pStyle->DrawVertCurvedOutSurface(&m_image, 0, 0, w, h);	m_pStyle->DrawButtonText(&m_image, 0, 0, w, h, &m_text, false);	m_image.DrawBox(0, 0, w - 1, h - 1, gRGB(64, 64, 64), false);	// Draw the pressed image	int nHorizOfs = (int)(w * (float).05);	int nVertOfs = (int)(h * (float).15);	m_pStyle->DrawVertCurvedInSurface(&m_image, w, 0, w, h);	m_pStyle->DrawButtonText(&m_image, w + nHorizOfs, nVertOfs, w - nHorizOfs, h - nVertOfs, &m_text, true);	m_image.DrawBox(w, 0, w + w - 1, h - 1, gRGB(255, 255, 255), false);}GImage* GWidgetTextButton::GetImage(GRect* pOutRect){	if(m_dirty)		Update();	pOutRect->x = m_pressed ? m_image.GetWidth() / 2 : 0;	pOutRect->y = 0;	pOutRect->w = m_image.GetWidth() / 2;	pOutRect->h = m_image.GetHeight();	return &m_image;}void GWidgetTextButton::SetSize(int w, int h){	m_rect.w = w;	m_rect.h = h;	m_image.SetSize(w * 2, h);	m_dirty = true;}void GWidgetTextButton::SetText(GString* pText){	m_text.Copy(pText);	m_dirty = true;	Draw(NULL);}void GWidgetTextButton::SetText(const char* szText){	m_text.Copy(szText);	m_dirty = true;	Draw(NULL);}// ----------------------------------------------------------------------GWidgetImageButton::GWidgetImageButton(GWidgetGroup* pParent, int x, int y, GImage* pImage): GWidgetAtomic(pParent, x, y, pImage->GetWidth() / 2, pImage->GetHeight()){	m_image.CopyImage(pImage);	m_pressed = false;}/*virtual*/ GWidgetImageButton::~GWidgetImageButton(){}/*virtual*/ void GWidgetImageButton::Grab(int x, int y){	m_pressed = true;	Draw(NULL);}/*virtual*/ void GWidgetImageButton::Release(){	m_pressed = false;	Draw(NULL);	m_pParent->OnReleaseImageButton(this);}GImage* GWidgetImageButton::GetImage(GRect* pOutRect){	pOutRect->x = m_pressed ? m_image.GetWidth() / 2 : 0;	pOutRect->y = 0;	pOutRect->w = m_image.GetWidth() / 2;	pOutRect->h = m_image.GetHeight();	return &m_image;}// ----------------------------------------------------------------------GWidgetAnimation::GWidgetAnimation(GWidgetGroup* pParent, int x, int y, GImage* pImage, int nFrames): GWidgetAtomic(pParent, x, y, pImage->GetWidth() / 2, pImage->GetHeight()){	m_image.CopyImage(pImage);	m_nFrames = nFrames;	m_nFrame = 0;}/*virtual*/ GWidgetAnimation::~GWidgetAnimation(){}/*virtual*/ void GWidgetAnimation::Grab(int x, int y){}/*virtual*/ void GWidgetAnimation::Release(){}GImage* GWidgetAnimation::GetImage(GRect* pOutRect){	int nFrameWidth = m_image.GetWidth() / m_nFrames;	pOutRect->x = m_nFrame * nFrameWidth;	pOutRect->y = 0;	pOutRect->w = nFrameWidth;	pOutRect->h = m_image.GetHeight();	return &m_image;}void GWidgetAnimation::SetFrame(int nFrame){	m_nFrame = nFrame;	Draw(NULL);}// ----------------------------------------------------------------------GWidgetTextLabel::GWidgetTextLabel(GWidgetGroup* pParent, int x, int y, int w, int h, GString* pText, GColor c): GWidgetAtomic(pParent, x, y, w, h){	m_image.SetSize(w, h);	m_text.Copy(pText);	m_alignLeft = true;	m_cForeground = c;	m_cBackground = 0x00000000; // transparent	m_dirty = true;}/*virtual*/ GWidgetTextLabel::~GWidgetTextLabel(){}/*virtual*/ void GWidgetTextLabel::Grab(int x, int y){	m_pParent->OnClickTextLabel(this);}/*virtual*/ void GWidgetTextLabel::Release(){}void GWidgetTextLabel::Update(){	m_dirty = false;	m_image.Clear(m_cBackground);	m_pStyle->DrawLabelText(&m_image, 0, 0, m_image.GetWidth(), m_image.GetHeight(), &m_text, m_alignLeft, m_cForeground);}GImage* GWidgetTextLabel::GetImage(GRect* pOutRect){

⌨️ 快捷键说明

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