使用xlue实现tips

经常遇到如下的需求

鼠标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

 

编程实现:

function AddWindowTip(tippedObj, text, callback)

    local function showTipsFunc(tippedObj, x, y)
        -- 创建tips窗口
        local hostwndId = "TipsHelper.TipsHostWnd.Instance." .. tippedObj:GetID()
        local objtreeId = "TipsHelper.TipsTree.Instance." .. tippedObj:GetID()
        local hostwndTemplateId = "TipsWndTemplate"
        local objtreeTemplateId = "TipsTreeTemplate"

        local hostwndManager = XLGetObject("Xunlei.UIEngine.HostWndManager")
        local hostwnd = hostwndManager:GetHostWnd(hostwndId)
        if hostwnd then
            local objtree = hostwnd:GetBindUIObjectTree()
            if objtree then
                hostwnd:UnbindUIObjectTree()
                local objtreeManager = XLGetObject("Xunlei.UIEngine.TreeManager")
                objtreeManager:DestroyTree(objtree)
            end
            hostwndManager:RemoveHostWnd(hostwndId)
        end
        local templateManager = XLGetObject("Xunlei.UIEngine.TemplateManager")
        local wndTemplate = templateManager:GetTemplate(hostwndTemplateId, "HostWndTemplate")
        if not wndTemplate then
            return
        end
        local hostwnd = wndTemplate:CreateInstance(hostwndId)
        if not hostwnd then
            return
        end
        local objtreeTemplate = templateManager:GetTemplate(objtreeTemplateId, "ObjectTreeTemplate")
        local objtree = objtreeTemplate:CreateInstance(objtreeId)
        if not objtree then
            return
        end
        hostwnd:BindUIObjectTree(objtree)
        hostwnd:Create()

        -- 设定text
        local rootObj = objtree:GetRootObject()
        local textObj = objtree:GetUIObject("text")
        textObj:SetText(text)
        local width, height = textObj:GetTextExtent()
        textObj:SetObjPos(4,3,width,height)
        width,height = width + 8, height + 6
        rootObj:SetObjPos(0,0,width+8,height+6)

        -- 移动窗口位置
        local tippedOwner = tippedObj:GetOwner()
        local tippedHostWnd = tippedOwner:GetBindHostWnd()
        local l,t,r,b = tippedObj:GetObjPos()
        local left = l+(r-l-width)/2
        local top = b
        left,top = tippedHostWnd:HostWndPtToScreenPt(left,top)
        hostwnd:Move(left,top,width,height)

        return rootObj
    end
    local function hideTipsFunc(tippedObj)
        -- 销毁tips窗口
        local hostwndId = "TipsHelper.TipsHostWnd.Instance." .. tippedObj:GetID()

        local hostwndManager = XLGetObject("Xunlei.UIEngine.HostWndManager")
        local hostwnd = hostwndManager:GetHostWnd(hostwndId)
        if not hostwnd then
            return
        end

        local objtree = hostwnd:GetBindUIObjectTree()
        if objtree then
            hostwnd:UnbindUIObjectTree()
            local objtreeManager = XLGetObject("Xunlei.UIEngine.TreeManager")
            objtreeManager:DestroyTree(objtree)
        end
        hostwndManager:RemoveHostWnd(hostwndId)

        return true
    end

    -- state: tip 的状态, hide隐藏,showing正在显示,show显示,hiding正在隐藏,enter进入tips中
    local state = "hide"    -- 使用状态控制 tips 在各个状态间转换
    tippedObj:AttachListener("OnMouseMove", true, function(obj, x, y, flags)
        if state == "hide" then
            state = "showing"
            local timerMgr = XLGetObject("Xunlei.UIEngine.TimerManager")
            timerMgr:SetOnceTimer(function()
                if state == "showing" then
                    local tipsObj = showTipsFunc(obj, x, y)
                    if tipsObj then
                        state = "show"

                        --[[ 这段代码,使得移动到弹出的窗口上时,窗口不会被隐藏
                        tipsObj:AttachListener("OnMouseMove", true, function()
                            if state == "hiding" then
                                state = "enter"
                            end
                        end)
                        tipsObj:AttachListener("OnMouseLeave", true, function()
                            if state == "enter" then
                                state = "hiding"
                                local timerMgr = XLGetObject("Xunlei.UIEngine.TimerManager")
                                timerMgr:SetOnceTimer(function()
                                    if state == "hiding" then
                                        if hideTipsFunc(obj) then
                                            state = "hide"
                                            if callback and type(callback) == "function" then
                                                callback(tippedObj, false)
                                            end
                                        end
                                    end
                                end, 300)
                            end
                        end)
                        --]]

                        if callback and type(callback) == "function" then
                            callback(obj, true)
                        end
                    end
                end
            end, 300)
        elseif state == "hiding" then
            state = "show"
        end
    end)
    tippedObj:AttachListener("OnMouseLeave", true, function(obj, x, y, flags)
        if state == "show" then
            state = "hiding"
            local timerMgr = XLGetObject("Xunlei.UIEngine.TimerManager")
            timerMgr:SetOnceTimer(function()
                if state == "hiding" then
                    if hideTipsFunc(obj) then
                        state = "hide"
                        if callback and type(callback) == "function" then
                            callback(tippedObj, false)
                        end
                    end
                end
            end, 300)
        elseif state == "showing" then
            state = "hide"
        end
    end)

end

使用xlue实现tips

时间: 2024-10-12 09:03:09

使用xlue实现tips的相关文章

Android应用程序性能优化Tips

主要介绍一些小细节的优化技巧,虽然这些小技巧不能较大幅度的提升应用性能,但是恰当的运用这些小技巧并发生累积效应的时候,对于整个App的性能提升还是有不小作用的.通常来说,选择合适的算法与数据结构会是你首要考虑的因素,在这篇文章中不会涉及这方面的知识点.你应该使用这篇文章中的小技巧作为平时写代码的习惯,这样能够提升代码的效率. 通常来说,高效的代码需要满足下面两个原则: 不要做冗余的工作 尽量避免执行过多的内存分配操作 To ensure your app performs well across

程序员取悦女朋友的正确姿势---Tips(iOS美容篇)

前言 女孩子都喜欢用美图工具进行图片美容,近来无事时,特意为某人写了个自定义图片滤镜生成器,安装到手机即可完成自定义滤镜渲染照片.app独一无二,虽简亦繁. JH定律:魔镜:最漂亮的女人是你老婆魔镜:程序员不是木头人 核心技术 图片滤镜核心技术的基本思路如下: 核心技术流程 具体流程 1.创建一个图像处理工具类 注:该类实例包括一个图像处理方法,该方法在传入原始图像和一个颜色矩阵后生成一个处理好的图像. @interface JHFeilterManager : NSObject @proper

android tips—NumberPicker,DataPicker,TimePicker样式修改

在使用NumberPicker,DataPicker,TimePicker这几个控件时,很容易出现如下这个界面 但是我们想要的却是下面图示的结果 修改Application,activity的android:theme这个值.最直观的效果去掉android:theme即可. 本tips 在 android4.4上测试通过.

iOS 小知识-tips

--->1<--- arc的项目中使用非arc代码,则添加-fno-objc-arc: 非arc项目中使用arc代码,则添加-fobjc-arc. --->2<--- 实用的类 NSKeyedArchiver [UIScreen mainScreen] [UIDevice currentDevice] [UIFont familyNames] [UIApplication sharedApplication] [NSUserDefaults standardUserDefaults

FFMPEG Tips (2) 如何提取码流的基本信息

本文是我的<FFMPEG Tips>系列的第二篇文章,上篇文章<FFMPEG Tips (1) 如何打印日志>主要分享了如何利用 ffmpeg 库打印日志,而本文则主要分享一下如何利用 ffmpeg 库拿到码流的一些基本信息. 1.  码流中的哪些信息值得关注 ? [ ] 是否包含:音频.视频 [ ] 码流的封装格式 [ ] 视频的编码格式 [ ] 音频的编码格式 [ ] 视频的分辨率.帧率.码率 [ ] 音频的采样率.位宽.通道数 [ ] 码流的总时长 [ ] 其他 Metada

迅雷tips

1.BT任务不能导出到下载列表 因为这是bt文件,不能导出. 2.可以在文件->导入未完成下载中 导入文件(但是不能批量导入) 3.远程控制下载:电脑绑定迅雷账号后,可以使用手机控制下载任务,但是不能添加任务(迅雷下载宝可以) 4.bt文件99%的问题.如果是在云端,打开云端文件,去掉没有下载的,就可以取回本地了.如果是在本地,就看剩下的1%是不是你关心的了. 5.迅雷极速版(1.0.14.159-1.0.33)没有远程下载功能,极速版1.0.14.158有 6.迅雷7(7.9.43.5054)

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

声明 欢迎转载,但请保留文章原始出处:) 博客园:http://www.cnblogs.com 农民伯伯: http://over140.cnblogs.com 正文 1.Selector 在Swift中可以用字符串常量来构造Selector,例如: NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleMoviePlayerLoadStateDidChange:", name: MPMovieP

关于iPhone的Tips篇……(to be continued...)

虽说作为一名iOS Developer,相比如何使用手中的iPhone,更重要的还是不断钻研如何去code,不过这里还是想起一篇类似<如何利用好你的iPhone>.<怎样才能榨干你手中iPhone的功能和价值>.<iPhone怎样玩才叫cool才叫更bigger>之类主题的blog,嗯,说写就写,今后还会更新MacBook篇.iPad篇:D 注:以下tips的确原创,如遇雷同,敬请留言吧-欢迎讨论. Tips.zero iOS中的一个功能诸位一定都用过,那就是整理主屏幕

使用 xlue 实现简单 listbox 控件

基于 XLUE 实现的 listbox 控件 1. 提供增删查接口,将 obj 作为子控件添加到列表: 2. 提供 Attach/Detach 方法,可以将子控件的事件转发出来: 3. 支持滚动条: 4. 支持鼠标滚轮: 实现过程中的注意点: 1. 使用 ItemObjList 表存储 itemObj , ItemObjList 是一个数组,是 listbox 控件的数据模型: 2. 使用 EventCookieMap 表存储事件回调, Attach 时监听所有 itemObj 的事件,通过 I