EGE绘图之五 按钮(下)

EGE专栏:EGE专栏

上一篇:EGE绘图之(五) 按钮(上)

下一篇:

四、按钮状态

1. 按钮状态分类

  给按钮加上几个状态参数,比如用来标记 点击,选中,悬停,可被选中之类的按键状态。绘制按钮时,就根据这些状态,选用不同的样式来绘制按钮,给予用户更好的交互体验。

  通常是选用不同的颜色,改变按钮大小,叠加图形等,也有更换样式的。

  这些状态在鼠标进行按下,松开,悬停,点击之类的操作时进行相应的更改。
  一个按钮分为以下几种状态,用于和用户进行交互。对于根据不同状态显示不同样式的按钮,操作上会更为友好。

No.状态名含义
描述
1Enabled可用状态按钮是否可用,不可用的按钮不响应事件
2Visible可见状态按钮是否可见
3Pressed按下状态按键是否被按下
4Checked选中状态按钮处于选中或非选中状态
5Checkable可选状态设置按钮是否可以切换选中状态
6Focused焦点状态按钮是否取得焦点
7Hovered悬停状态鼠标,指针等悬停在按钮上方

2. 按钮状态交互

  对于上面几种状态,需要根据鼠标操作来实时进行交互的有 选中,按下和悬停,重点便是这几种状态的交互。

2.1 状态变化:选中 (Checked)

  选中状态一般由点击事件进行触发状态改变,外观上和处于非选中的按钮有较大的区别。

  可选状态(Checkable):用于设置用户是否可以切换按钮的选中状态,当按钮设置了初始状态后,按钮选中和非选中将不可由用户行为进行切换

在这里插入图片描述

选中状态切换示例

  这里只简单地做个选中的示例:当鼠标点击按钮后,按钮的选中状态选中非选中之间切换。

if (insideButton(&buttonArray[i], x, y)) {
	//状态切换,这里在选中和非选中之间切换
	buttonArray[i].checked = !buttonArray[i].checked;
}

  对于按钮的不同状态,设置不同的填充颜色。

for (int i = 0; i < length; i++) {
	//根据状态进行不同的绘制,这里按状态改变颜色
	if (buttonArray[i].checked) {
		setfillcolor(EGEARGB(0xFF, 0x1E, 0x90, 0xFF));
	} else {
		setfillcolor(EGEARGB(0xFF, 0x40, 0xE0, 0xD0));
	}
}

  如下图所示,在点击后,切换按钮选中状态为选中和非选中,选中状态的按钮显示为蓝色。
在这里插入图片描述

示例代码
#include <graphics.h>

struct CircleButton
{
	int x, y;		/* 圆心*/
	int radius;		/* 半径*/
	bool checked;	/* 是否选中*/
};

// 判断点(x, y)是否在按钮点击区域内部
bool insideButton(const CircleButton* button, int x, int y);

// 绘制所有按钮
void drawButton(const CircleButton buttonArray[], int length);

// 查找 (x, y) 所在的按钮,返回按钮ID, 没有返回 -1
int searchButton(int x, int y, const CircleButton buttonArray[], int length);

// 绘制
void draw();

#define BUTTON_SIZE 8
#define BUTTON_ID_NONE -1

//定义按钮,确定区域
CircleButton buttonArray[BUTTON_SIZE];

// 点击按钮ID
int clickButtonId = BUTTON_ID_NONE;

int btnId = BUTTON_ID_NONE;

int main()
{
	initgraph(640, 480, INIT_RENDERMANUAL);
	setbkcolor(WHITE);
	setbkmode(TRANSPARENT);
	ege_enable_aa(true);

	for (int i = 0; i < BUTTON_SIZE; i++) {
		buttonArray[i].x = (i % 2 * 2 + 1) * 640 / 4;
		buttonArray[i].y = (i / 2) * 320 / 3 + 60;
		buttonArray[i].radius = 50;
		buttonArray[i].checked = false;
	}

	bool redraw = true;

	for (; is_run(); delay_fps(60)) {
		while (mousemsg()) {
			mouse_msg msg = getmouse();

			//判断鼠标左键点击(左键按下确定位置,抬起为执行时刻)
			if (msg.is_left()) {
				if (msg.is_down()) {
					btnId = searchButton(msg.x, msg.y, buttonArray, BUTTON_SIZE);
				}
				else {
					// 存在点击的按钮,则设置状态,这里状态在选中和非选中之间切换
					if (btnId != BUTTON_ID_NONE) {
						buttonArray[btnId].checked = !buttonArray[btnId].checked;
						redraw = true;
					}
					
					if (clickButtonId != btnId) {
						clickButtonId = btnId;
						redraw = true;
					}
				}
			}
		}

		// 判断是否需要重绘,减少不必要的绘制操作
		if (redraw) {
			cleardevice();
			draw();
			redraw = false;
		}
	}

	return 0;
}


bool insideButton(const CircleButton* button, int x, int y)
{
	int dx = x - button->x, dy = y - button->y;
	return (dx * dx + dy * dy) <= (button->radius * button->radius);
}

void drawButton(const CircleButton buttonArray[], int length)
{

	setfillcolor(EGEARGB(0xFF, 0x1E, 0x90, 0xFF));
	setcolor(WHITE);
	settextjustify(CENTER_TEXT, CENTER_TEXT);
	setfont(36, 0, "");

	color_t lastFillColor = getfillcolor();

	for (int i = 0; i < length; i++) {
		//根据状态进行不同的绘制,这里按状态改变颜色
		color_t curColor;
		if (buttonArray[i].checked) {
			curColor = EGEARGB(0xFF, 0x1E, 0x90, 0xFF);
		}
		else {
			curColor = EGEARGB(0xFF, 0x40, 0xE0, 0xD0);
		}

		//为了减少颜色设置操作进行的优化操作,少量绘制可有可无
		if (lastFillColor != curColor) {
			setfillcolor(curColor);
			lastFillColor = curColor;
		}

		// 绘制按钮
		ege_fillellipse(buttonArray[i].x - buttonArray[i].radius,
			buttonArray[i].y - buttonArray[i].radius,
			2 * buttonArray[i].radius,
			2 * buttonArray[i].radius);

		xyprintf(buttonArray[i].x, buttonArray[i].y, "%d", i);
	}
}

int searchButton(int x, int y, const CircleButton buttonArray[], int length)
{
	int buttonId = BUTTON_ID_NONE;

	for (int i = 0; i < length; i++) {
		if (insideButton(&buttonArray[i], x, y)) {
			buttonId = i;
			break;   //退出,已经检测到,后面的按钮不再检测
		}
	}

	return buttonId;
}

void draw()
{
	//绘制
	drawButton(buttonArray, BUTTON_SIZE);
	setcolor(BLACK);
	setfont(24, 0, "");
	settextjustify(LEFT_TEXT, TOP_TEXT);
	xyprintf(240, 360, "点击按钮ID:%d", clickButtonId);
}

2.2 状态变化:悬停(Hovered)

  悬停状态:鼠标移动到按钮位置上方却没有按下时的状态。

  检测到鼠标位置移动时,对按钮进行检索,找到悬停的按钮,将按钮标记为悬停状态,而原先如果有悬停的按钮,则将原先的按钮取消悬停状态。

在这里插入图片描述

#include <graphics.h>

struct CircleButton
{
	int x, y;		/* 圆心*/
	int radius;		/* 半径*/
	bool hovered;	/* 是否悬停*/
};

// 判断点(x, y)是否在按钮点击区域内部
bool insideButton(const CircleButton* button, int x, int y);

// 绘制所有按钮
void drawButton(const CircleButton buttonArray[], int length);

// 查找 (x, y) 所在的按钮,返回按钮ID, 没有返回 -1
int searchButton(int x, int y, const CircleButton buttonArray[], int length);

// 绘制
void draw();

#define BUTTON_SIZE 8
#define BUTTON_ID_NONE -1

//定义按钮,确定区域
CircleButton buttonArray[BUTTON_SIZE];

// 悬停按钮ID
int hoveredButtonId = BUTTON_ID_NONE;

int main()
{
	initgraph(640, 480, INIT_RENDERMANUAL);
	setbkcolor(WHITE);
	setbkmode(TRANSPARENT);
	ege_enable_aa(true);

	for (int i = 0; i < BUTTON_SIZE; i++) {
		buttonArray[i].x = (i % 2 * 2 + 1) * 640 / 4;
		buttonArray[i].y = (i / 2) * 320 / 3 + 60;
		buttonArray[i].radius = 50;
		buttonArray[i].hovered = false;
	}

	hoveredButtonId = BUTTON_ID_NONE;

	int xMouse = 0, yMouse = 0;
	bool redraw = true;

	for (; is_run(); delay_fps(60)) {
		bool mouseMoved = false;

		//记录鼠标最后移动的位置

		while (mousemsg()) {
			mouse_msg msg = getmouse();

			if (msg.is_move())
			{
				mouseMoved = true;
				xMouse = msg.x;
				yMouse = msg.y;
			}
		}

		//当鼠标移动
		if (mouseMoved) {
			//查找悬停的按钮
			int btnId = searchButton(xMouse, yMouse, buttonArray, BUTTON_SIZE);

			// 悬停按钮改变
			if (btnId != hoveredButtonId) {
				// 标记原先的按钮为非悬停状态
				if (hoveredButtonId != BUTTON_ID_NONE) {
					buttonArray[hoveredButtonId].hovered = false;
				}

				// 标记当前悬停的按钮为悬停状态
				if (btnId != BUTTON_ID_NONE) {
					buttonArray[btnId].hovered = true;
				}

				hoveredButtonId = btnId;
				redraw = true;
			}
		}

		// 判断是否需要重绘,减少不必要的绘制操作
		if (redraw) {
			cleardevice();
			draw();
			redraw = false;
		}
	}

	return 0;
}


bool insideButton(const CircleButton* button, int x, int y)
{
	int dx = x - button->x, dy = y - button->y;
	return (dx * dx + dy * dy) <= (button->radius * button->radius);
}

void drawButton(const CircleButton buttonArray[], int length)
{

	setfillcolor(EGEARGB(0xFF, 0x1E, 0x90, 0xFF));
	setcolor(WHITE);
	settextjustify(CENTER_TEXT, CENTER_TEXT);
	setfont(36, 0, "");

	color_t lastFillColor = getfillcolor();

	for (int i = 0; i < length; i++) {
		//根据状态进行不同的绘制,这里按状态改变颜色
		color_t curColor;
		if (buttonArray[i].hovered) {
			curColor = EGEARGB(0xFF, 0x1E, 0x90, 0xFF);
		}
		else {
			curColor = EGEARGB(0xFF, 0x40, 0xE0, 0xD0);
		}

		//为了减少颜色设置操作进行的优化操作,少量绘制可有可无
		if (lastFillColor != curColor) {
			setfillcolor(curColor);
			lastFillColor = curColor;
		}

		// 绘制按钮
		ege_fillellipse(buttonArray[i].x - buttonArray[i].radius,
			buttonArray[i].y - buttonArray[i].radius,
			2 * buttonArray[i].radius,
			2 * buttonArray[i].radius);

		xyprintf(buttonArray[i].x, buttonArray[i].y, "%d", i);
	}
}

int searchButton(int x, int y, const CircleButton buttonArray[], int length)
{
	int buttonId = BUTTON_ID_NONE;

	for (int i = 0; i < length; i++) {
		if (insideButton(&buttonArray[i], x, y)) {
			buttonId = i;
			break;   //退出,已经检测到,后面的按钮不再检测
		}
	}

	return buttonId;
}

void draw()
{
	//绘制
	drawButton(buttonArray, BUTTON_SIZE);
	setcolor(BLACK);
	setfont(24, 0, "");
	settextjustify(LEFT_TEXT, TOP_TEXT);
	xyprintf(240, 360, "悬停按钮ID:%d", hoveredButtonId);
}

2.3 状态变化:按下状态

  按下状态:是指鼠标在按钮的点击区域内按下,还没有抬起的状态。

  一般的做法是,鼠标在按钮的点击区域按下后,就将按钮设置为按下状态,如果鼠标没有松开,即使鼠标离开按钮点击区域,按钮依然是处于按下状态,鼠标抬起后,才解除按键状态。

在这里插入图片描述

#include <graphics.h>

// 圆形按钮
struct CircleButton
{
	int x, y;		/* 圆心*/
	int radius;		/* 半径*/
	bool pressed;	/* 是否按下*/
};

// 判断点(x, y)是否在按钮点击区域内部
bool insideButton(const CircleButton* button, int x, int y);

// 绘制所有按钮
void drawButton(const CircleButton buttonArray[], int length);

// 查找 (x, y) 所在的按钮,返回按钮ID, 没有返回 -1
int searchButton(int x, int y, const CircleButton buttonArray[], int length);

// 绘制
void draw();

#define BUTTON_SIZE 8
#define BUTTON_ID_NONE -1

//定义按钮,确定区域
CircleButton buttonArray[BUTTON_SIZE];

// 按下按钮ID
int pressButtonId = BUTTON_ID_NONE;

int main()
{
	initgraph(640, 480, INIT_RENDERMANUAL);
	setbkcolor(WHITE);
	setbkmode(TRANSPARENT);
	ege_enable_aa(true);

	for (int i = 0; i < BUTTON_SIZE; i++) {
		buttonArray[i].x = (i % 2 * 2 + 1) * 640 / 4;
		buttonArray[i].y = (i / 2) * 320 / 3 + 60;
		buttonArray[i].radius = 50;
		buttonArray[i].pressed = false;
	}

	pressButtonId = BUTTON_ID_NONE;

	bool redraw = true;

	for (; is_run(); delay_fps(60)) {

		while (mousemsg()) {
			mouse_msg msg = getmouse();

			// 判断鼠标左键按下(左键按下确定位置,同时判断是否为按钮区域
			// 抬起则解除按下状态
			if (msg.is_left()) {
				if (msg.is_down()) {
					// 检查是否有按钮被按下
					int btnId = searchButton(msg.x, msg.y, buttonArray, BUTTON_SIZE);

					// 将被按下的按钮设置为按下状态
					if (btnId != BUTTON_ID_NONE) {
						pressButtonId = btnId;
						buttonArray[pressButtonId].pressed = true;
						redraw = true;
					}
				}
				else {
					//左键抬起,如果有按钮被按下,解除按下状态
					if (pressButtonId != BUTTON_ID_NONE) {
						buttonArray[pressButtonId].pressed = false;
						pressButtonId = BUTTON_ID_NONE;
						redraw = true;
					}
				}
			}
		}

		// 判断是否需要重绘,减少不必要的绘制操作
		if (redraw) {
			cleardevice();
			draw();
			redraw = false;
		}
	}

	return 0;
}


bool insideButton(const CircleButton* button, int x, int y)
{
	int dx = x - button->x, dy = y - button->y;
	return (dx * dx + dy * dy) <= (button->radius * button->radius);
}

void drawButton(const CircleButton buttonArray[], int length)
{

	setfillcolor(EGEARGB(0xFF, 0x1E, 0x90, 0xFF));
	setcolor(WHITE);
	settextjustify(CENTER_TEXT, CENTER_TEXT);
	setfont(36, 0, "");

	color_t lastFillColor = getfillcolor();

	for (int i = 0; i < length; i++) {
		//根据状态进行不同的绘制,这里按状态改变颜色
		color_t curColor;
		if (buttonArray[i].pressed) {
			curColor = EGEARGB(0xFF, 0x1E, 0x90, 0xFF);
		}
		else {
			curColor = EGEARGB(0xFF, 0x40, 0xE0, 0xD0);
		}

		//为了减少颜色设置操作进行的优化操作,少量绘制可有可无
		if (lastFillColor != curColor) {
			setfillcolor(curColor);
			lastFillColor = curColor;
		}

		// 绘制按钮
		ege_fillellipse(buttonArray[i].x - buttonArray[i].radius,
			buttonArray[i].y - buttonArray[i].radius,
			2 * buttonArray[i].radius,
			2 * buttonArray[i].radius);

		xyprintf(buttonArray[i].x, buttonArray[i].y, "%d", i);
	}
}

int searchButton(int x, int y, const CircleButton buttonArray[], int length)
{
	int buttonId = BUTTON_ID_NONE;

	for (int i = 0; i < length; i++) {
		if (insideButton(&buttonArray[i], x, y)) {
			buttonId = i;
			break;   //退出,已经检测到,后面的按钮不再检测
		}
	}

	return buttonId;
}

void draw()
{
	//绘制
	drawButton(buttonArray, BUTTON_SIZE);
	setcolor(BLACK);
	setfont(24, 0, "");
	settextjustify(LEFT_TEXT, TOP_TEXT);
	xyprintf(240, 360, "按下按钮ID:%d", pressButtonId);
}

2.4 完整状态交互

状态描述样式
不可用无法交互灰色按钮
不可见按钮不可见文字指示
焦点点击按钮后获得焦点。外围圆圈标记
不可选按钮选中状态无法通过点击进行切换
选中按钮被点击后切换左边选框
悬停鼠标移动到按钮上方时设置,离开取消颜色加深
按下鼠标按下设置,松开取消颜色切换

在这里插入图片描述

#include <graphics.h>
#include <math.h>

struct ButtonStates
{
	bool enable;	/* 可用状态 */
	bool visible;	/* 可见状态 */
	bool pressed;	/* 按下状态 */
	bool checkable; /* 可选状态 */
	bool checked;	/* 选中状态 */
	bool hovered;	/* 悬停状态 */
	bool focused;	/* 焦点状态 */
};

// 圆形按钮
struct CircleButton
{
	unsigned int id;
	int x, y;		/* 圆心*/
	int radius;		/* 半径*/
	color_t normalColor;
	color_t pressedColor;
	const char* text;
	ButtonStates state;
};

void initButton(CircleButton* button, int x, int y, int radius);

void initAllButtons();

//初始化按钮状态
void initButtonState(CircleButton* button);

// 判断点(x, y)是否在按钮点击区域内部
bool insideButton(const CircleButton* button, int x, int y);

CircleButton* findButton(unsigned int id);

// 绘制按钮
void drawButton(const CircleButton* buttonArray);

// 绘制所有按钮
void drawAllButtons();

// 查找 (x, y) 所在的按钮,返回按钮ID, 没有返回 -1
int searchButton(int x, int y);

// 绘制
void draw();

// 颜色插值, t 范围为 (0.0 ~ 1.0),分别对应colorA和colorB
color_t interpColor(color_t colorA, color_t colorB, float t);

#define BUTTON_SIZE		8
#define BUTTON_ID_ZERO	((unsigned int)0)
#define BUTTON_MIN_ID	1
#define BUTTON_MAX_ID	BUTTON_SIZE

//定义按钮,确定区域
CircleButton buttonArray[BUTTON_SIZE];
int buttonNum = BUTTON_SIZE;

// 按下按钮ID
int pressButtonId   = BUTTON_ID_ZERO;
int hoveredButtonId = BUTTON_ID_ZERO;
int focusedButtonId = BUTTON_ID_ZERO;

int windowWidth = 640, windowHeight = 480;

int main()
{
	
	initgraph(windowWidth, windowHeight, INIT_RENDERMANUAL);
	setbkcolor(WHITE);
	setbkmode(TRANSPARENT);
	ege_enable_aa(true);

	initAllButtons();

	int xMouse = 0, yMouse = 0;
	int xSearched = -1, ySearched = -1;
	unsigned int idSearched = BUTTON_ID_ZERO;
	bool redraw = true;

	for (; is_run(); delay_fps(60)) {

		bool mouseMoved = false;

		while (mousemsg()) {
			mouse_msg msg = getmouse();

			// 判断鼠标左键按下(左键按下确定位置,同时判断是否为按钮区域
			// 抬起则解除按下状态
			if (msg.is_left()) {
				if (msg.is_down()) {
					
					int btnId = BUTTON_ID_ZERO;

					// 检查位置对应的按钮ID
					btnId = searchButton(msg.x, msg.y);
					 
					if ((btnId != BUTTON_ID_ZERO) && (findButton(btnId)->state.enable)) {
						// 将被按下的按钮设置为按下状态
						if (btnId != BUTTON_ID_ZERO) {
							pressButtonId = btnId;
							findButton(pressButtonId)->state.pressed = true;
							redraw = true;
						}
					}
				}
				else {
					//左键抬起,如果有按钮被按下
					if (pressButtonId != BUTTON_ID_ZERO) {
						unsigned btnId = pressButtonId;
						CircleButton* button = findButton(btnId);
						
						// 取消之前按钮的焦点状态
						if (focusedButtonId != BUTTON_ID_ZERO)
						{
							findButton(focusedButtonId)->state.focused = false;
						}

						//设置当前按钮为焦点状态
						button->state.focused = true;
						focusedButtonId = btnId;

						// 解除按下状态
						button->state.pressed = false;
						pressButtonId = BUTTON_ID_ZERO;
						
						// 切换选中
						if (button->state.checkable)
							button->state.checked = !(button->state.checked);
						
						redraw = true;
					}
				}
			}
			else if (msg.is_move()) {
				mouseMoved = true;
				xMouse = msg.x;
				yMouse = msg.y;
			}
		}

		//当鼠标移动
		if (mouseMoved) {
			//查找悬停的按钮
			int btnId = searchButton(xMouse, yMouse);

			// 悬停按钮改变
			if (btnId != hoveredButtonId) {
				// 标记原先的按钮为非悬停状态
				if (hoveredButtonId != BUTTON_ID_ZERO) {
					findButton(hoveredButtonId)->state.hovered = false;
				}

				// 标记当前悬停的按钮为悬停状态
				if (btnId != BUTTON_ID_ZERO) {
					findButton(btnId)->state.hovered = true;
				}

				hoveredButtonId = btnId;
				redraw = true;
			}
		}

		// 判断是否需要重绘,减少不必要的绘制操作
		if (redraw) {
			cleardevice();
			draw();
			redraw = false;
		}
	}

	return 0;
}


bool insideButton(const CircleButton* button, int x, int y)
{
	int dx = x - button->x, dy = y - button->y;
	return (dx * dx + dy * dy) <= (button->radius * button->radius);
}

unsigned int generateId()
{
	static unsigned int id = 0;
	return ++id;
}

CircleButton* findButton(unsigned int id)
{
	return (id == BUTTON_ID_ZERO) ? NULL : &buttonArray[id - 1];
}

unsigned int getButtonId(const CircleButton* button)
{
	return button->id;
}

// 绘制按钮
void drawButton(const CircleButton* button)
{
	if (button != NULL) {
		if (button->state.visible) {
			setfillcolor(EGEARGB(0xFF, 0x1E, 0x90, 0xFF));
			setcolor(WHITE);
			settextjustify(CENTER_TEXT, CENTER_TEXT);
			setfont(24, 0, "");

			//根据状态进行不同的绘制
			color_t color;

			if (!(button->state.enable)) {
				color = DARKGRAY;
			}
			else
			{
				if (button->state.pressed) {
					color = button->pressedColor;
				}
				else {
					color = button->normalColor;
				}

				if (button->state.hovered) {
					color = interpColor(color, BLACK, 0.125f);
				}
			}

			setfillcolor(color);

			// 绘制按钮
			ege_fillellipse(button->x - button->radius, button->y - button->radius,
				2 * button->radius, 2 * button->radius
			);

			// 选中则绘制外环边框
			if (button->state.focused)
			{
				setcolor(interpColor(color, BLACK, 0.25f));
				setlinewidth(4);

				int borderRadius = button->radius + 4;

				ege_ellipse(button->x - borderRadius, button->y - borderRadius,
					2 * borderRadius, 2 * borderRadius
				);
			}


			int radiusCheckBox = 14;
			int xCheckBox = button->x - button->radius - 2 * radiusCheckBox;
			int yCheckBox = button->y;

			if (button->state.checked) {
				setfillcolor(button->pressedColor);
				ege_fillellipse(xCheckBox - radiusCheckBox, yCheckBox - radiusCheckBox,
					2 * radiusCheckBox, 2 * radiusCheckBox
				);
			}
			else {
				setcolor(button->pressedColor);
				setlinewidth(2);
				ege_ellipse(xCheckBox - radiusCheckBox, yCheckBox - radiusCheckBox,
					2 * radiusCheckBox, 2 * radiusCheckBox
				);
			}

			setcolor(WHITE);
			xyprintf(button->x, button->y, "%s", button->text);
		}
		else {
			setcolor(BLACK);
			settextjustify(CENTER_TEXT, CENTER_TEXT);
			setfont(24, 0, "");
			xyprintf(button->x, button->y, "不可见");
		}
	}
}


// 绘制所有按钮
void drawAllButtons()
{
	for (int i = 0; i < buttonNum; i++) {
		unsigned int btnId = BUTTON_MIN_ID + i;
		drawButton(findButton(btnId));
	}
}

int searchButton(int x, int y)
{
	int buttonId = BUTTON_ID_ZERO;

	for (int i = 0; i < buttonNum; i++) {
		unsigned int btnId = BUTTON_MIN_ID + i;
		CircleButton* button = findButton(btnId);

		if ((button != NULL) && (insideButton(button, x, y))) {
			buttonId = btnId;
			break;   //退出,已经检测到,后面的按钮不再检测
		}
	}

	return buttonId;
}

void draw()
{
	//绘制
	drawAllButtons();
	setcolor(BLACK);
	setfont(24, 0, "");
	settextjustify(LEFT_TEXT, TOP_TEXT);
	xyprintf(240, 360, "按下按钮ID:%d", pressButtonId);
}

color_t interpColor(color_t colorA, color_t colorB, float t)
{
	if (t > 1)
		t = 1;
	else if (t < 0)
		t = 0;

	int r = roundf((1 - t) * EGEGET_R(colorA) + t * EGEGET_R(colorB));
	int g = roundf((1 - t) * EGEGET_G(colorA) + t * EGEGET_G(colorB));
	int b = roundf((1 - t) * EGEGET_B(colorA) + t * EGEGET_B(colorB));

	return EGERGB(r, g, b);
}


void initButtonState(CircleButton* button)
{
	button->state.enable = true;
	button->state.visible = true;
	button->state.pressed = false;
	button->state.checkable = true;
	button->state.checked = false;
	button->state.hovered = false;
	button->state.focused = false;
}

void initButton(CircleButton* button, int x, int y, int radius)
{
	if (button != NULL) {
		button->id = generateId();
		button->x = x;
		button->y = y;
		button->radius = radius;
		button->normalColor  = EGEARGB(0xFF, 0x40, 0xE0, 0xD0);
		button->pressedColor = EGEARGB(0xFF, 0x1E, 0x90, 0xFF);
		button->text = "Button";

		initButtonState(button);
	}
}

void initAllButtons()
{
	int colNum = 2;

	for (int i = 0; i < buttonNum; i++) {
		int id = BUTTON_MIN_ID + i;
		int x = (int)(((i % colNum) + 0.5f) * (windowWidth / colNum));
		int y = (int)(((i / colNum) + 0.5f) * (windowHeight / ((buttonNum + colNum - 1) / colNum)));

		initButton(findButton(id), x, y, 50);
	}

	CircleButton* btn;
	btn = findButton(BUTTON_MIN_ID);
	btn->state.enable = false;
	btn->text = "不可用";

	btn = findButton(BUTTON_MIN_ID + 1);
	btn->state.visible = false;

	btn = findButton(BUTTON_MIN_ID + 2);
	btn->state.checkable = false;
	btn->state.checked = false;
	btn->state.focused = true;
	btn->text = "不可选";

	btn = findButton(BUTTON_MIN_ID + 3);
	btn->state.checkable = false;
	btn->state.checked = true;
	btn->text = "不可选";

	btn = findButton(BUTTON_MIN_ID + 4);
	btn->state.pressed = true;

	btn = findButton(BUTTON_MIN_ID + 5);
	btn->state.checked = true;

	btn = findButton(BUTTON_MIN_ID + 6);
	btn->state.pressed = true;
	btn->state.checked = true;

	focusedButtonId = BUTTON_MIN_ID + 2;
}

EGE专栏:EGE专栏

上一篇:EGE绘图之(五) 按钮(上)

下一篇:

  • 18
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

依稀_yixy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值