bones脚本篇 - 给按钮增加响应焦点的外观

本文详细讲解了如何在UI程序中为按钮添加焦点响应,并通过shape标签实现边框显示。包括按钮控件的事件处理、状态变化、透明度调整等关键步骤,以及tab切换焦点的效果演示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本篇主要讲如何给按钮增加焦点响应,通常我们在一个UI程序里按下tab或者shift-tab键,会导致控件切换焦点,获取焦点的控件则会显示出一个边框, bones同样是支持焦点切换的,这里要感谢chrome 的开源了,焦点切换这部分代码 是从chrome提取并修改的。要想显示一个边框需要用到shape标签,这个标签后面的教程再详细介绍,这里简单的使用它来绘制控件周围的边框
看下 button.xml 和button.lua

<bones>
<head>
  <link type ='script' module ='button' file ='button.lua'></link>
</head>
<body>
  <image class ="pic">
    <notify name ="onCreate" module ="button" func ="onCreate"></notify>
    <notify name ="onHitTest" module ="button" func ="onHitTest"></notify>
    <notify name ="onSizeChanged" module ="button" func ="onSizeChanged"></notify>
    <event name ="onMouseDown" phase ="target" module ="button" func ="onMouseDown"></event>
    <event name ="onMouseUp" phase ="target" module ="button" func ="onMouseUp"></event>
    <event name ="onMouseMove" phase ="target" module ="button" func ="onMouseMove"></event>
    <event name ="onMouseLeave" phase ="target" module ="button" func ="onMouseLeave"></event>
    <event name ="onMouseEnter" phase ="target" module ="button" func ="onMouseEnter"></event>
    <event name ="onFocus" phase ="target" module ="button" func ="onFocus"></event>
    <event name ="onBlur" phase ="target" module ="button" func ="onBlur"></event>
    <!--shape不接受事件-->
    <shape>
      <notify name ="onHitTest" module ="button" func ="onContentHitTest"></notify>
    </shape>
  </image>

</body>
</bones>

local mod = {}

--control state
local common = 1
local highlight = 2
local press = 3
local disable = 4

--button

local function stateChanged(self)
    local state = common;
    if self:isEnable() ~= true then
        state = disable;
    elseif self.down_ then
        if self.hover_ then
        state = press;
        else
        state = highlight;
        end
    elseif self.hover_ then
        state = highlight;
    end

    if state ~= self.state_ then 
        self.state_ = state;
        if self.state_ == common then
            self:setContent(self.common_)
        elseif self.state_ == highlight then
            self:setContent(self.highlight_)
        elseif self.state_ == press then
            self:setContent(self.press_)
        elseif self.state_ == disable then
            self:setContent(self.disable_)
        end
    end

end

local function isEnable(self)
    return self.enable_
end


local function setBitmap(self, common, highlight, press, disable)
    self.common_ = common
    self.highlight_ = highlight
    self.press_ = press
    self.disable_ = disable
    stateChanged(self)
end

function mod.onContentHitTest(self, x, y)
    return false
end

function mod.onHitTest(self, x, y)
    return self:isTransparent(x, y)
end

function mod.onCreate(self)
--public method
self.isEnable = isEnable
self.setBitmap = setBitmap
--private member
self.enable_ = true
self.hover_ = false
self.down_ = false

self.state_ = disable
self.focus_ = self:getChildAt(0)
self.focus_:setRect();
self.focus_:setColor(0xff00ffff)
self.focus_:setOpacity(0)
self.focus_:setStroke(true)
self.focus_:setFocusable(false)
--stateChanged(self)
end

function mod.onMouseEnter(self, e)

end

function mod.onMouseMove(self, e)
    self.hover_ = self:contains(e:getLoc())
    stateChanged(self);
end

function mod.onMouseDown(self, e)
    if self:isEnable() and e:isLeftMouse() then
        if not self.down_ then
            self.down_ = true
            stateChanged(self)
        end
    end
end

function mod.onMouseUp(self, e)
    local notify = false

    if self:isEnable() and e:isLeftMouse() then
        if self.down_ then
            self.down_ = false
            if self.hover_ then
                notify = true
            end
            stateChanged(self)
        end
        if notify then
            print("click")
        end
    end
end

function mod.onMouseLeave(self, e)
    self.hover_ = false
    self.down_ = false
    stateChanged(self)
end

function mod.onSizeChanged(self, w, h)
    self.focus_:setSize(w, h)
end

function mod.onFocus(self, e)
    if e:isTabTraversal() then
        self.focus_:setOpacity(1)
    end
end

function mod.onBlur(self, e)
self.focus_:setOpacity(0)
end

return mod;

image标签下 多了一个子标签 shape, 由于notify和event是设置回调的标签 并不是用于创建对象,所以shape 在image中的索引为0, lua的onCreate函数 使用了getChildAt(0)来获取shape标签并设置了shape的属性, 在onFocus中 检测焦点事件是否是因为tab切换引起的 如果是我们要显示边框 即设置透明度为1,
在onBlur中设置透明度为0 隐藏边框的显示,另外由于shape 的大小跟image一样所以鼠标移动到按钮上,实际上是移动到了shape上,因此shape注册了onHitTest通知 不接受鼠标事件。
tab切换焦点的顺序是先父后子 如果标签不可接收焦点则跳过, 鼠标点击切换焦点则点击到的标签获取焦点,如果标签不可接受焦点则寻找第一个可接受焦点的父标签来获取焦点。默认情况下每一个内置标签都是可以接收焦点的,所以直接使用tab切换 会先设置焦点到image 然后到shape 为了保证按钮控件只接收一次焦点所以调用setFocusable将image设置为不可接受焦点,这样跳过image直接到shape标签

按tab或者shift-tab切换焦点效果图如下:
这里写图片描述
这里写图片描述

本篇代码下载:
http://blog.youkuaiyun.com/dalixux/article/details/48830721

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值