本篇主要讲如何给按钮增加焦点响应,通常我们在一个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