bones脚本篇 - 模拟一个按钮

本文介绍如何使用bones脚本来模拟一个按钮,包括按钮的四个状态:普通、高亮、按下和禁用。通过在XML文件中链接4幅图片并设置mouse事件响应。同时讲解了bones的事件模型,类似DOM的事件模型,涉及捕获、目标和冒泡三个阶段。文章提供了具体的lua代码示例,并利用onHitTest通知自定义鼠标响应区域,通过检查像素透明度决定是否响应鼠标事件。

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

本篇使用image标签来模拟1个按钮的行为,要模拟按钮就要响应事件,除root以外每一个内置标签都可以响应事件。 bones的事件模型类似于dom的事件模型,事件在传递的过程中分为3个阶段 capturing target bublling,
以鼠标事件为例 a,b,c三个节点 a是b的父 b是c的父 ,当鼠标在c的节点时
事件会先传递给a 然后b 此时是capturing阶段 再传给c 此时是target阶段 再传个b然后是a此时是bublling阶段 具体的描述参照dom文档
支持的事件类型参照bones.h中BonesHandler接口

一:如何模拟一个按钮
通常按钮有4个状态 普通状态 鼠标进入的高亮状态 左键点击的 按下状态 以及禁用disable状态
按钮的xml文件如下:


<bones>
  <head>
    <link type ="pixmap" name ="common" file ="../res/common.png"></link>
    <link type ="pixmap" name ="highlight" file ="../res/highlight.png"></link>
    <link type ="pixmap" name ="press" file ="../res/press.png"></link>
    <link type ="pixmap" name ="disable" file ="../res/disable.png"></link>
    <link type ="script" module ="test" file="test.lua"></link>
    <style>
      .red
      {
      color:#ffff0000;
      }
      .pic
      {
      loc:20px 20px;
      size:256px 256px;
      }
    </style>
  </head>
  <body>
    <root id ="main" class ="red" >
      <image class ="pic">
        <notify name ="onCreate" module ="test" func ="onCreate"></notify>
          <notify name ="onHitTest" module ="test" func ="onHitTest"></notify>
        <event name ="onMouseDown" phase ="target" module ="test" func ="onMouseDown"></event>
        <event name ="onMouseUp" phase ="target" module ="test" func ="onMouseUp"></event>
        <event name ="onMouseMove" phase ="target" module ="test" func ="onMouseMove"></event>
        <event name ="onMouseLeave" phase ="target" module ="test" func ="onMouseLeave"></event>
        <event name ="onMouseEnter" phase ="target" module ="test" func ="onMouseEnter"></event>

      </image>
    </root>
  </body>
</bones>

test.lua:


local mod = {}

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

--button
local function isEnable(self)
    return self.enable_
end

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("common")
        elseif self.state_ == highlight then
            self:setContent("highlight")
        elseif self.state_ == press then
            self:setContent("press")
        elseif self.state_ == disable then
            self:setContent("disable")
        end
    end

end

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

self.state_ = disable
stateChanged(self)
end

function mod.onHitTest(self, x, y)
    return self:isTransparent(x, y)
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



return mod;

这里我们链接了4幅图片 并响应了mouse事件,具体如何响应参照lua代码, 这里用到了一个新的通知onHitTest 这个通知是用来自定义鼠标响应区域的,当鼠标在标签上的时候 onHitTest如果返回true则响应鼠标否则交给其他标签处理,这里通过isTransparent来看位图像素是否为透明 如果透明则不处理
效果图:
这里写图片描述

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值