bones腳本篇 - 給按鈕增加響應焦點的外觀

本篇主要講如何給按鈕增加焦點響應,通常我們在一個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.csdn.net/dalixux/article/details/48830721

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章