经常遇到如下的需求

鼠标hover到目标对象一定时间后,弹出tips或者窗口;

鼠标离开目标对象一定时间后,隐藏tips或者窗口;

鼠标从目标对象移动到弹出的窗口上,这种状况下不隐藏窗口;

考虑到这种需求,绘制如下的状态图:

如上图所示,将tips的状态分为hide,showing,show,hiding,enter 五个状态;

hide: tips没有显示

showing: 准备显示tips

show: 显示tips

hiding: 准备隐藏tips

enter: 鼠标进入了tips控件,这种状况下仍然显示 tips

使用上面的状态图,清晰地描述了tips可能存在的各种状态,并确定了驱动事件有哪些。理清了思路。

hide状态时:hover到目标控件会进入 showing 状态;

showing 状态时:离开目标控件会返回到 hide 状态;

进入 showing 状态后,开启一个timer,当timer结束后,如果仍然是 showing 状态,则转到 show 状态并显示tips

show 状态时:离开目标控件会进入hiding状态;

hiding 状态时:hover到目标控件会返回到 show 状态;

进入 hiding 状态后,开启一个timer,当timer结束后,如果仍然是 hiding 状态,则转到 hide 状态并隐藏tips

鼠标从目标控件移动到tips上,会使得状态从 show 转到 hiding 转到 enter, 此时tips仍然显示,当离开tips控件后,状态又转移回 hiding ,此时开启一个timer,timer结束后,同样根据是否仍然是 hiding 状态来隐藏tips

编程实现:

  1. function AddWindowTip(tippedObj, text, callback)
  2.  
  3. local function showTipsFunc(tippedObj, x, y)
  4. -- 创建tips窗口
  5. local hostwndId = "TipsHelper.TipsHostWnd.Instance." .. tippedObj:GetID()
  6. local objtreeId = "TipsHelper.TipsTree.Instance." .. tippedObj:GetID()
  7. local hostwndTemplateId = "TipsWndTemplate"
  8. local objtreeTemplateId = "TipsTreeTemplate"
  9.  
  10. local hostwndManager = XLGetObject("Xunlei.UIEngine.HostWndManager")
  11. local hostwnd = hostwndManager:GetHostWnd(hostwndId)
  12. if hostwnd then
  13. local objtree = hostwnd:GetBindUIObjectTree()
  14. if objtree then
  15. hostwnd:UnbindUIObjectTree()
  16. local objtreeManager = XLGetObject("Xunlei.UIEngine.TreeManager")
  17. objtreeManager:DestroyTree(objtree)
  18. end
  19. hostwndManager:RemoveHostWnd(hostwndId)
  20. end
  21. local templateManager = XLGetObject("Xunlei.UIEngine.TemplateManager")
  22. local wndTemplate = templateManager:GetTemplate(hostwndTemplateId, "HostWndTemplate")
  23. if not wndTemplate then
  24. return
  25. end
  26. local hostwnd = wndTemplate:CreateInstance(hostwndId)
  27. if not hostwnd then
  28. return
  29. end
  30. local objtreeTemplate = templateManager:GetTemplate(objtreeTemplateId, "ObjectTreeTemplate")
  31. local objtree = objtreeTemplate:CreateInstance(objtreeId)
  32. if not objtree then
  33. return
  34. end
  35. hostwnd:BindUIObjectTree(objtree)
  36. hostwnd:Create()
  37.  
  38. -- 设定text
  39. local rootObj = objtree:GetRootObject()
  40. local textObj = objtree:GetUIObject("text")
  41. textObj:SetText(text)
  42. local width, height = textObj:GetTextExtent()
  43. textObj:SetObjPos(,,width,height)
  44. width,height = width + , height +
  45. rootObj:SetObjPos(,,width+,height+)
  46.  
  47. -- 移动窗口位置
  48. local tippedOwner = tippedObj:GetOwner()
  49. local tippedHostWnd = tippedOwner:GetBindHostWnd()
  50. local l,t,r,b = tippedObj:GetObjPos()
  51. local left = l+(r-l-width)/
  52. local top = b
  53. left,top = tippedHostWnd:HostWndPtToScreenPt(left,top)
  54. hostwnd:Move(left,top,width,height)
  55.  
  56. return rootObj
  57. end
  58. local function hideTipsFunc(tippedObj)
  59. -- 销毁tips窗口
  60. local hostwndId = "TipsHelper.TipsHostWnd.Instance." .. tippedObj:GetID()
  61.  
  62. local hostwndManager = XLGetObject("Xunlei.UIEngine.HostWndManager")
  63. local hostwnd = hostwndManager:GetHostWnd(hostwndId)
  64. if not hostwnd then
  65. return
  66. end
  67.  
  68. local objtree = hostwnd:GetBindUIObjectTree()
  69. if objtree then
  70. hostwnd:UnbindUIObjectTree()
  71. local objtreeManager = XLGetObject("Xunlei.UIEngine.TreeManager")
  72. objtreeManager:DestroyTree(objtree)
  73. end
  74. hostwndManager:RemoveHostWnd(hostwndId)
  75.  
  76. return true
  77. end
  78.  
  79. -- state: tip 的状态, hide隐藏,showing正在显示,show显示,hiding正在隐藏,enter进入tips
  80. local state = "hide" -- 使用状态控制 tips 在各个状态间转换
  81. tippedObj:AttachListener("OnMouseMove", true, function(obj, x, y, flags)
  82. if state == "hide" then
  83. state = "showing"
  84. local timerMgr = XLGetObject("Xunlei.UIEngine.TimerManager")
  85. timerMgr:SetOnceTimer(function()
  86. if state == "showing" then
  87. local tipsObj = showTipsFunc(obj, x, y)
  88. if tipsObj then
  89. state = "show"
  90.  
  91. --[[ 这段代码,使得移动到弹出的窗口上时,窗口不会被隐藏
  92. tipsObj:AttachListener("OnMouseMove", true, function()
  93. if state == "hiding" then
  94. state = "enter"
  95. end
  96. end)
  97. tipsObj:AttachListener("OnMouseLeave", true, function()
  98. if state == "enter" then
  99. state = "hiding"
  100. local timerMgr = XLGetObject("Xunlei.UIEngine.TimerManager")
  101. timerMgr:SetOnceTimer(function()
  102. if state == "hiding" then
  103. if hideTipsFunc(obj) then
  104. state = "hide"
  105. if callback and type(callback) == "function" then
  106. callback(tippedObj, false)
  107. end
  108. end
  109. end
  110. end, 300)
  111. end
  112. end)
  113. --]]
  114.  
  115. if callback and type(callback) == "function" then
  116. callback(obj, true)
  117. end
  118. end
  119. end
  120. end, )
  121. elseif state == "hiding" then
  122. state = "show"
  123. end
  124. end)
  125. tippedObj:AttachListener("OnMouseLeave", true, function(obj, x, y, flags)
  126. if state == "show" then
  127. state = "hiding"
  128. local timerMgr = XLGetObject("Xunlei.UIEngine.TimerManager")
  129. timerMgr:SetOnceTimer(function()
  130. if state == "hiding" then
  131. if hideTipsFunc(obj) then
  132. state = "hide"
  133. if callback and type(callback) == "function" then
  134. callback(tippedObj, false)
  135. end
  136. end
  137. end
  138. end, )
  139. elseif state == "showing" then
  140. state = "hide"
  141. end
  142. end)
  143.  
  144. end

使用 xlue 实现 tips的更多相关文章

  1. Mac上MySQL忘记root密码且没有权限的处理办法&workbench的一些tips (转)

    忘记Root密码肿么办 Mac上安装MySQL就不多说了,去mysql的官网上下载最新的mysql包以及workbench,先安装哪个影响都不大.如果你是第一次安装,在mysql安装完成之后,会弹出来 ...

  2. 【Tips】史上最全H1B问题合辑——保持H1B身份终级篇

    [Tips]史上最全H1B问题合辑——保持H1B身份终级篇 2015-04-10留学小助手留学小助手 留学小助手 微信号 liuxue_xiaozhushou 功能介绍 提供最真实全面的留学干货,帮您 ...

  3. layer.js中layer.tips

    <script src="~/Content/js/layer/layer.js"></script> layer.tips('名称不能为空', '#pro ...

  4. HTML 最简单的tips 怎么支持指定DIV显示提示信息

    <body> <style type="text/css"> a.link{position:relative;} a.link div.tips{ bor ...

  5. CSS:CSS使用Tips

    Css是前端开发中效果展现的主要部分之一,良好的Css书写习惯可以为实际的项目开发提高效率,也可以为实现良好的团队合作提供保证. 一般新手在使用Css的时候经常会犯一些错误,出现一些不经意的漏洞,如果 ...

  6. 【读书笔记】100个Switf必备tips

    声明 欢迎转载,但请保留文章原始出处:)  博客园:http://www.cnblogs.com 农民伯伯: http://over140.cnblogs.com 正文 1.Selector 在Swi ...

  7. 【转】40个良好用户界面Tips

    一个良好的用户界面应具有高转换率,并且易于使用.但要用户体验良好并不容易做到,下面我们整理了40个良好用户界面Tips,希望能对你有帮助! 1 尽量使用单列而不是多列布局 单列布局能够让对全局有更好的 ...

  8. 转:Eclipse Search Tips

    from:  https://github.com/ajermakovics/eclipse-instasearch/wiki/Eclipse-search-tips Eclipse Search T ...

  9. VS:101 Visual Studio 2010 Tips

    101 Visual Studio 2010 Tips Tip #1        How to not accidentally copy a blank line TO – Text Editor ...

随机推荐

  1. 解决kylin报错:Failed to create dictionary on <db>.<table>, Caused by: java.lang.IllegalArgumentException: Too high cardinality is not suitable for dictionary

    报错信息: 2017-05-13 15:14:30,035 DEBUG [pool-9-thread-10] dict.DictionaryGenerator:94 : Dictionary clas ...

  2. 新手遇到的问题:Easy UI的对话框老是在页面载入完毕后自己主动弹出

    因为是第一次接触Easy UI,还不是非常熟悉,尝试了一下对话框功能,还是非常不错的.但问题是页面载入完毕后.全部的对话框都自己主动弹出来了,百度了好久,也没有详细说明确的,貌似别人都没有这个问题哦 ...

  3. iOS:多线程的详细介绍

    多线程: 一.概念 1.什么是进程?     程序的一次性执行就是进程.进程占独立的内存空间.   2.什么是线程?     进程中的代码的执行路径.   3.进程与线程之间的关系?      每个进 ...

  4. Dedecms会员中心注入漏洞

    详细说明: member/buy_action.php   require_once(dirname(__FILE__)."/config.php");   CheckRank(0 ...

  5. python scikit-learn选择正确估算器

    下图摘自官方文档 链接 http://scikit-learn.org/stable/tutorial/machine_learning_map/index.html

  6. java程序计算数独游戏

    兴趣来了,写了个简单的数独游戏计算程序,未做算法优化. 通过文件来输入一个二维数组,9行,每行9个数组,数独游戏中需要填空的地方用0来表示.结果也是打印二维数组. import java.io.Fil ...

  7. Druid对比Redshift

    Redshift 内部使用了亚马逊取得了授权的ParAccel 实时注入数据 抛开可能的性能不同, 有功能性的不同 Druid 适合分析大数据量的流式数据, 也能够实时加载和聚合数据一般来讲, 传统的 ...

  8. C#中如何动态加载DockPanel

    在WinForm项目中要求实现动态加载DockPanel. 简单研究了下,演示代码如下: 很简单几行代码,实现了基本意图.看起来问题很快解决. 但是实际应用中发现几个问题: 1.当第一次运行时,doc ...

  9. [物理题+枚举] hdu 4445 Crazy Tank

    题意: 给你N个炮弹的发射速度,以及炮台高度H和L1,R1,L2,R2. 问任选发射角度.最多能有几个炮弹在不打入L2~R2的情况下打入L1~R1 注意:区间有可能重叠. 思路: 物理题,发现单纯的依 ...

  10. Spring MVC 单元测试异常 Caused by: org.springframework.core.NestedIOException: ASM ClassReader failed to parse class file

    Sping 3.2.8.RELEASE + sping mvc + JDK 1.8运行异常. java.lang.IllegalStateException: Failed to load Appli ...