除了象 button 这样HTMLayout引擎内建的behavior,以及我们自定义的 behavior,
aardio标准库同样提供了很多behavior。
使用标准库的behavior只要导入指定的名字空间即可,
例如模拟窗口标题栏按钮的 web.layout.behavior.windowCommand;
首先我们切换到【窗体设计器】,
在【属性面板】中设置为无边框(也就没有默认的标题栏了)
然后切换到代码视图,在 import web.layout; 后面添加
import web.layout.behavior.windowCommand; 以导入标准库实现的behavior
然后我们在HTML中添加一个简单的标题栏和关闭按钮
wbLayout.html = /**
<div #title-bar>
<a>关闭窗口</a>
</div>
**/
最后在CSS中为标题栏应用 windowCommand 这个 behavior,CSS代码如下:
wbLayout.css = /**
#title-bar{
behavior:windowCommand;
}
**/
windowCommand 这个behavior(交互行为)会监听用户的操作,
并且在回调事件中读取节点的 command 属性以决定执行什么样的命令,
所以我们需要为标题栏里的节点指定 command 属性以执行对应的命令。
在标准库中打开web.layout.behavior.windowCommand; 的源代码 可以看到 command 可以指定为以下属性:
command = "window-caption" 表示鼠标左键按住该节点可以拖动窗口
command = "window-close" 关闭窗口
command = "window-min" 最小化窗口
command = "window-max" 最大化窗口
command = "window-restore" 恢复窗口
所以我们修改HTML如下
wbLayout.html = /**
<div #title-bar command="window-caption">
<div .ctrl-bar>
<a command="window-close">r</a>
</button>
</div>
**/
然后我们简单的改进一下CSS外观
wbLayout.css = /**
html{
background:#999;/*网页背景色*/
border-radius:4px; /*8像素大小的圆角*/
}
#title-bar{
behavior:windowCommand;
width:100%; /*宽度撑满窗口*/
height:22px; /*指定高度*/
background:#CCCCCC; /*背景色*/
}
/*CSS选择器中,空格表示节点间的父子包含关系*/
#title-bar .ctrl-bar{
position:absolute;//标题栏按钮容器绝对定位到窗口右上角
top:0px;//顶坐标1像素
right:8px;//右坐标5像素
}
#title-bar a[command]{
display:block; //显示为块节点
float:left;//块节点左浮动,如果有多个按钮可以从左向右排
height:16px;
font-family:"Marlett";/*这个字体把小写r显示为关闭符号*/
padding:4px;
}
#title-bar a[command]:hover{
background:#999;
}
**/ 使用 border-radius:8px; 指定了网页使用圆角,我们运行程序以后,发现网页虽然圆角了,
但是winform窗体并没有圆角而是显示不协议的黑色背景,这里我们要请出标准库里的 win.util.round 把窗体也改造成圆角。
import win.util.round;
win.util.round( winform );
你可能注意到了关闭按钮是这样写的 <a>关闭窗口</a>
a标签是一个超链接,超链接类似普通文本、span标签是一个内联节点(区别是超链接可以使用href属性指定点击打开的网址),所谓内联节点主要是指其不能向块节点(例如div节点)那样指定与高度有关的样式、内联节点会自左向右流动布局(类似文本那样水平流动)。关于内联节点与块节点的区别可参考教程《HTML - DIV,CSS 布局基础》
所以我们需要在CSS中指定 display:block; 将超链接转换为块模式(可以指定大小),
并且在CSS中用 float:left; 指定了向左浮动( 块默认是自上向下布局的,左浮动可以水平排放块节点 )关于块节点、左浮动等知识请参考《DIV,CSS布局快速入门》,
那么您可能会问:“为什么不直接用button标签来表示关闭按钮呢?” - 这是 web.layout.behavior.windowCommand 里的一个特殊设定 - 将button预留给了可能出现在标题栏内的导航按钮( 例如仿360界面 )。
<div .ctrl-bar> </div> 这个DIV容器准备用来放所有的标题栏按钮(虽然目前只有一个关闭按钮) 在HTML里可以用div对节点分组、划分空间,例如这里的.ctrl-bar 可以绝对定位到窗口的右上角 - 如果有多个按钮(例如最大化、最小化等)就不用一个个的去调整到右上角了。在CSS中指定position:absolute;以使用绝对定位方式。
最终代码如下:- import win.ui;
- /*DSG{{*/
- var winform = ..win.form( bottom=399;text="HTMLayout - 无边框窗口";border="none";right=599 )
- winform.add( )
- /*}}*/
- import win.util.round;
- win.util.round(winform,,,6,6); //窗体改成圆角,最后两个参数指定圆角半径
- import web.layout;
- import web.layout.behavior.windowCommand;
- var wbLayout = web.layout( winform )
- wbLayout.html = /**
- <div #title-bar command="window-caption">
- <div .ctrl-bar>
- <a command="window-close">r</a>
- </button>
- </div>
- **/
- wbLayout.css = /**
- html{
- background:#999;/*网页背景色*/
- border-radius:4px; /*8像素大小的圆角*/
- }
- #title-bar{
- behavior:windowCommand;
- width:100%; /*宽度撑满窗口*/
- height:22px; /*指定高度*/
- background:#CCCCCC; /*背景色*/
-
- }
- /*CSS选择器中,空格表示节点间的父子包含关系*/
- #title-bar .ctrl-bar{
- position:absolute;//标题栏按钮容器绝对定位到窗口右上
- top:0px;//顶坐标1像素
- right:8px;//右坐标5像素
- }
- /*CSS选择器中,方括号指定节点拥有的属性*/
- #title-bar a[command]{
- display:block; //显示为块节点
- float:left;//块节点左浮动,如果有多个按钮可以从左向右排
- height:16px;
- font-family:"Marlett";/*这个字体把小写r显示为关闭符号*/
- padding:4px;
-
- }
- #title-bar a[command]:hover{
- background:#999;
- }
- **/
- winform.show();
- win.loopMessage();
复制代码 在aardio编辑器中粘帖上面的代码,按F5快捷键运行效果如下:
当然,我们也不必要把HTML,CSS都写在一个文件里。
可以创建一个aardio工程文件,css可以写到单独的 *.css 文件里, html 可以写到单独的 *.html 范例里,
然后调用 web.go( "/res/my.html" ) 打开html即可,html,css都可以方便的加入内嵌资源生成独立绿色的EXE文件。
课后作业题
请修改课程中无边框窗口的源代码,要求如下:
1、 增加最大化、最小化等按钮,不得使用图片
2、 使窗体边框可以拖动调整大小
作业提示:
1、 Marlett 字体里的数字 0,1,2 分别是什么图案?
2、 在aardio里新建 HTMLayout UI 工程,里面用到了一个behavior: web.layout.behavior.windowSizer
3、 HTMLayout扩展的CSS语法中有一个 content 属性可以用来改变节点内容,例如:
- div#my-id{ content:"文本"; })
复制代码 答案在下面:
- import win.ui;
- /*DSG{{*/
- var winform = ..win.form(text="HTMLayout 无边框窗体";right=599;bottom=399;border="none";parent=...)
- winform.add()
- /*}}*/
- import web.layout;
- import web.layout.behavior.windowCommand;
- import web.layout.behavior.windowSizer;
- //创建网页浏览器
- var wbLayout = web.layout( winform )
- wbLayout.html = /**
- <html>
- <body>
- <!-- 下面是标题栏,凡在CSS中指定 behavior:windowCommand 的节点(含子节点) 可用 command 属性指明命令类型 -->
- <div #title-bar command="window-caption"> <span .title> 我 的 软 件 </span>
- <div .ctrl-bar>
-
- <!-- 弹出菜单,类似这种包含弹出节点的最好用div或button,
- div主要用作布局容器 - 可更好的支持弹出子节点或浮动子节点,
- 而a,li等节点存在的主要目的不是用来做其他节点的容器 -->
- <div .window-menu>u
- <menu .popup> <!-- .popup是内置的弹出菜单样式 -->
- <li>在线帮助</li>
- <li>子菜单
- <menu >
- <li>这是子菜单</li>
- </menu>
- </li>
- <li #exit>退出</li>
- </menu>
- </div>
-
- <!-- 下面是标题栏按钮,必须使用a标记表示,command属性指示该按钮执行的命令 -->
- <a command="window-min">0</a>
- <a command="window-max">1</a>
- <a command="window-close">r</a>
- </div>
- </div>
- <!--下面这句用来支持可拖动的边框,必须在aardio中调用 import web.layout.behavior.windowSizer -->
- <div style="behavior:windowSizer"/>
- </body>
- </html>
- **/
-
- wbLayout.css = /**
- body{
- margin:0;
- background:#fff;/*网页背景色*/
- }
- #title-bar{
- behavior:windowCommand; /*必须在aardio中 import web.layout.behavior.windowCommand */
- width:100%; /*宽度撑满窗口*/
- height:28px; /*指定高度*/
- background:#5a5a5a; /*背景色*/
- }
- /*最大化后body会自动添加maximize属性*/
- body[maximize]{
- border-radius:0;/*最大化去掉圆角*/
- }
- body[maximize] #title-bar{
- border-radius:0;/*最大化去掉圆角*/
- }
- #title-bar span.title{
- font:system;
- margin:6px 0 0 10px;
- color:#CCCCCC;
- }
- /*CSS选择器中,空格表示节点间的父子包含关系*/
- #title-bar .ctrl-bar{
- position:absolute;//标题栏按钮容器绝对定位到窗口右上角
- top:1px;//顶坐标
- right:8px;//右坐标
- width:95px
- }
- /*CSS选择器中,方括号指定节点拥有的属性*/
- #title-bar .ctrl-bar a{
- display:block; //显示为块节点
- float:left;//块节点左浮动( 从左向右排 )
- height:14px;
- font-family:"Marlett";/*该字体显示按钮符号*/
- font-size:14px;
- padding:4px;
- color:#fff;
- }
- #title-bar a[command]:hover{
- background:#6ebccf;
- }
- #title-bar a[command]:active{
- background:#FF0000;
- }
- #title-bar a[command="window-restore"]{
- content:"2";/*改变文本,Marlett字体为还原符号*/
- }
- #title-bar .window-menu{
- behavior:popup-menu;
- float:left;
- height:14px;
- font-family:"Marlett";/*该字体显示按钮符号*/
- font-size:14px;
- padding:4px;
- color:#fff;
- }
- #title-bar .window-menu:hover{
- background:#6ebccf;
- }
- #title-bar .window-menu:owns-popup /*菜单已弹出*/
- {
- background-color: #FF0000;
- color: #FFFFFF;
- }
- **/
- // 响应菜单点击事件
- wbLayout.onMenuItemClick = {
- // 事件可以是一个函数或列表,如果是列表键名匹配节点的id或name属性
- exit = function (ltTarget,ltOwner,reason,behaviorParams) {
- winform.close();
- }
-
- // 在这里没有匹配不到id的节点会触发default函数*/
- default = function (ltTarget,ltOwner,reason,behaviorParams) {
- var ltPopupOwner = web.layout.element( behaviorParams.he );//这是弹出菜单的按钮节点
- winform.msgbox( ltTarget.innerText )
- }
- }
- import win.ui.shadow;
- win.ui.shadow(winform); //添加阴影边框
- winform.show();
- win.loopMessage();
复制代码
运行效果:
添加下面的代码为无边框窗口添加阴影边框:import win.ui.shadow;
win.ui.shadow(winform); //添加阴影边框 一些扁平化风格的界面可能在背景上没有边框,使用阴影边框因为其半透明效果比画的边框更自然一些( 边框是必须的,否则同色窗体会相互混淆边界 ),注意使用阴影边框的窗体不要使用圆角、即不好看也容易出现锯齿。 |