悬浮提示的一种简单实现(CEGUI)

悬浮提示是一种常见的提示,那么界面中的简单悬浮提示(只有文本的)是如何实现的?

下面简单的以CEGUI中的实现加以分析,下面的代码主要截取与设置悬浮提示相关的部分。悬浮提示其实也是一种特殊的界面,因此也派生自CEGUI各种窗口的基类Window类。

CEGUI中的window类继承自属性集和事件集:

class CEGUIEXPORT Window : public PropertySet, public EventSet
{
	//!< 事件相关

	///< 鼠标进入事件
	virtual void onMouseEnters(MouseEventArgs& e);
	///< 鼠标离开事件
	virtual void onMouseLeaves(MouseEventArgs& e);
	///< 鼠标移动事件
	virtual void onMouseMove(MouseEventArgs& e);

	//!< 成员变量相关

	///< 窗口设置的文本
	String d_text;
	///< 窗口悬浮提示的文本
	String d_tooltipText;
	///< 窗口保存的指向悬浮提示的指针
	Tooltip* d_customTip;
}

Tooltip继承自Window类,这样看起来Tooltip也类似成为了Window的一种属性,而通过Window::d_customTip及Tooltip::d_target可以进行方便地修改,Tooltip内部主要实现了设置关联目标窗口及控制显示的接口。

class CEGUIEXPORT Tooltip : public Window
{
	///< 设置/获取目标窗口
	void setTargetWindow(Window* wnd);
	const Window* getTargetWindow();
	///< 重置显示时间
	void resetTimer(void);
	///< 关联的目标窗口
	const Window* d_target;
}

当鼠标进入窗口的有效范围时,会触发Tooltip类中重新定义的onMouseEnters()接口。

void Tooltip::onMouseEnters(MouseEventArgs& e)
{
	///< 计算位置
	positionSelf();
	Window::onMouseEnters(e);
}
可以看出Tooltip只是计算了自身的位置,然后便调用Window类的接口。

void Window::onMouseEnters(MouseEventArgs& e)
{
	///< 设置鼠标图标
	getGUIContext().getMouseCursor().setImage(getMouseCursor());
	///< 获取Window关联的Tooltip
	Tooltip* const tip = getTooltip();
	///< 判断tip是否为空,且tip不是父窗口
	if (tip && !isAncestor(tip))
		tip->setTargetWindow(this);
	///< 触发事件
	fireEvent(EventMouseEntersSurface, e, EventNamespace);
}
这其中调用了Tooltip的接口setTargetWindow():

void Tooltip::setTargetWindow(Window* wnd)
{
	//...
	///< 保存关联的目标窗口
	d_target = wnd;
	///< 设置Tooltip的窗口文本
	setText(wnd->getTooltipText());
	///< 重置显示时间
	resetTimer();
	//...
}

这里要注意一下,setText(wnd->getTooltipText())设置的是Tooltip的成员d_text,而非wnd的成员d_text。在Tooltip的渲染层,悬浮提示文字的尺寸及内容都是通过Tooltip的d_text来获取的。

Tooltip中并没有重新定义onMouseMove()这个接口,所以当鼠标在窗口上移动时,触发的是Window::onMouseMove

void Window::onMouseMove(MouseEventArgs& e)
{
	///< 重新设置显示时间
	Tooltip* const tip = getTooltip();
	if (tip)
		tip->resetTimer();
}
当鼠标离开窗口区域时,会触发OnMouseLeaves()
void Window::onMouseLeaves(MouseEventArgs& e)
{
	const Window* const mw = getGUIContext().getWindowContainingMouse();
	Tooltip* const tip = getTooltip();
	///< 悬浮提示窗口存在且不为包含鼠标的wnd且不是当前窗口的父窗口时,将关联窗口指针置为空
	if (tip && mw != tip && !(mw && mw->isAncestor(tip)))
		tip->setTargetWindow(0);
	///< 触发事件
	fireEvent(EventMouseLeavesSurface, e, EventNamespace);
}






桌面悬浮菜单易语言源码 特色一: 全程渐变效果,透明度由高到低、由低到高,打开速度由快到慢,由慢加速,都是一个过程而非瞬间完成。 而且窗口的颜色,也是由渐变完成的。 特色二: 自定义列表,动态添加、程序,可添加任何目标。 特色三: 支持拖放,只需要把文件拖到这个悬浮窗上面,即可自动填写完毕添加向导,只需要点最后一步确定即可。 特色四: 可开启鼠标透过功能,把这个悬浮窗扔在一边,即使想要点某个点,而正巧那个点被悬浮窗覆盖时,悬浮窗将不会干扰你的操作,仍旧可以点的到!只有在鼠标停留在悬浮窗一段时间使菜单完全弹开以后,鼠标才不会透过悬浮窗。 特色五: 可以开机启动,点击右下角的那个小按钮,即可保持菜单处于一直张开的状态。 特色六: 即使是小白用户,也可以对那些霸屏的窗口开刀了。 正常隐藏时: 弹开后的菜单页: 鼠标透过判定修正:如果开启了鼠标透过,在窗口未完全打开时点击了菜单,菜单会自动趋向关闭方向,不再理会停留在窗口上的鼠标,直到鼠标移开窗口后再移回来。 弹开后的工具页: 右下角三个按钮,从左到右依次是: 菜单页、工具页、最大化锁定。 左上角的十字瞄准线,拖动它就可以方便地在屏幕上取组件句柄。 点击"你给我消失"以后,目标窗口(必须是整个窗口)就会完全消失,仅在任务栏中有显示。而且无论怎么点击任务栏,窗口都不会出现,。此时列表框中会自动记录已消失的窗口,只有关闭那个窗口重新启动,或者从列表框中选中,点击"你可以回来了"放回来,那个窗口才会重新出现。 但是三次元封印,不会影响目标的运行情况。 一直留在最前可以设置某个窗口一直在最前面。 最前面没你事了 可以取消一个窗口的总在最前的属性,比如迅雷的悬浮框等。 注:切换到工具页后,会暂时取消本软件的自动鼠标透过,并且使用拖拽十字选中目标以后,最大化锁会自动锁上。 切换回菜单页,鼠标透过功能会自动恢复用户的设置。 源码看点: 1.API弹开菜单。 2.API开启鼠标透过。 3.API检测按键。 4.API打开通用对话框,功能和美观还有易用性上面,都超过易语言的通用对话框。 5.API实现单一实例。 6.API实现可调控式鼠标透过。 7.即使窗口总在最前,信息框仍旧不会被窗口遮挡。 8.API在屏幕上画矩形取目标句柄组件的边框。(新增) 9.让某窗口去三次旅游或者增加、取消其总在最前的属性。(新增)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值