相关文章推荐
拉风的猴子  ·  Types.Nvarchar Field ...·  3 月前    · 
俊逸的长颈鹿  ·  javascript - ...·  9 月前    · 
精明的冲锋衣  ·  Error in piloting DOS ...·  1 年前    · 
注意: web.layout( HTMLayout ) 与 web.sciter ( Sciter JS ) 基本用法类似,
但 Sciter JS 支持 JavaScript,web.layout 教程一般也适用 web.sciter,只要将示例代码中的 web.layout 简单替换为 web.sciter 即可。

更多HTMLayout入门教程请点这里

打开aardio,在【快速访问工具栏】点击第二个按钮【新建对话框】,如下图:
切换到代码视图,找到显示窗体的语句 winform.show();
在这句代码前面插入下面的代码( 注意绿色字体的是注释):
import web.layout; //导入HTMLayout支持库
wbLayout = web.layout( winform ) //创建HTMLayout窗体
wbLayout.html = /**
在这里写入HTML
经过我们改造后的完整的代码如下:
  1. import win.ui;
  2. /*DSG{{*/
  3. var winform = ..win.form( right=599;bottom=399;text="HTMLayout示例")
  4. winform.add(  )
  5. /*}}*/

  6. //web.layout 这里很需要你
  7. import web.layout;

  8. /*
  9. winform窗体对象交给你,
  10. 请帮我改造成可以显示网页的HTMLayout窗体,

  11. 我准备给即将出生的HTMLayout窗体取个名字叫"wbLayout"
  12. 并且使用var语句声明为局部变量,毕竟他还是个孩子,我可不想他满地乱跑变成大众情人
  13. */
  14. var wbLayout = web.layout( winform )


  15. wbLayout.html = /**
  16. <div>据说在HTML里这样就可以表示一个节点?</div>
  17. **/

  18. winform.show()
  19. win.loopMessage();

复制代码

复制上面的源代码到aardio编辑器中,然后按【 运行(F5) 】运行上面的代码
你可以 点击上图放大 查看一下原始图片(帖子里默认显示缩略图)。
html标签 是根节点,地面以下的是 head节点 (即头节点,这部分代码不是用来显示的,通常用来添加一些页面的选项,例如用title节点表示页面的标题 )地面以上的是 body 节点 ( 即内容节点,这里面的代码是用来显示的、可见的 )
一个完整的HTML文件的结构如下:
建议你安装一个支持emmet的HTML编辑器 (参考: http://www.iteye.com/news/27580 ) ,
例如notepad++安装 emmet插件以后,输入 html:xt 然后按CTRL+E 就会自动生成一个简单的HTML文件了。
当然我们也可以偷懒省略掉html,head,body这些标签( 本教程中省略了这些部分 )。
而最常用的标签就是 div ,div是英文division( 分区)的缩写,你可以理解为div就是一个盒子,
大盒子里面可以有小盒子,小盒子里面可以有小小盒子,也就是div里面可以套div
import web.layout;
var wbLayout = web.layout( winform )

然后在后面输入 wbLayout.debug()  - 按回车键完成代码如下:
import web.layout.debug;
wbLayout.attachEventHandler( web.layout.debug );

上面的代码用于输出HTMLayout引擎内置的调试信息到控制台,
并且添加一个全局函数 debug() 用于在CSSS!脚本中向控制台输出内容。
添加了这两行代码以后,如果我们的HTML,CSS书写有错误会自动打开控制台并显示错误信息.
再次运行修改后的代码,看看发生了什么?!
仍然没有显示任何错误信息,这说明我们所有的代码至少在语法上是正确的。
我们实在找不到原因,咒骂开发工具远水救不了近火,
于是我决定使用排除法,首先我跑去运行了一下aardio自带的behavior范例居然一切正常。
我看了一下范例中用的是div而不是button,难道是这个button有什么问题。
于是我修改上面的范例改成使用div
  1. import win.ui;
  2. /*DSG{{*/
  3. var winform = ..win.form( right=599;bottom=399;text="HTMLayout - 自定义behavior";)
  4. winform.add(  )
  5. /*}}*/

  6. import web.layout;
  7. var wbLayout = web.layout( winform )

  8. namespace web.layout.behavior.command {

  9. onMouseClick = function (ltTarget,ltOwner,x,y,ltMouseParams) {
  10. ltOwner.innerHTML = "鼠标点击了!"
  11. }
  12. }

  13. wbLayout.html = /**
  14. <div id="my-button">点击这里</div>
  15. **/

  16. wbLayout.css = /**
  17. #my-button{
  18. behavior:command;
  19. }
  20. **/

  21. winform.show()
  22. win.loopMessage();
复制代码
注意对于div这样的普通节点并没有 onButtonClick 这样的按钮事件,
只有 onMouseClick 这样的鼠标事件. 而按钮没有 onMouseClick 事件(只能使用 onButtonClick )。
运行上面的代码,点击后节点里面的文字变成了 "鼠标点击了!",behavior工作了。
可是为什么改成button就没有反应呢?请试试你能不能找出答案?!
添加 behavior
HTMLayout有很多内建的behavior,
例如 button节点这样的按钮就默认拥有内建behavior:button。

  1. #my-button{
  2. behavior:command;
  3. }
复制代码
在前面我们使用上面的代码给一个button节点指定自定义behavior时,就覆盖并清除了默认拥有的behavior。
也就是说他虽然有button的默认CSS样式外观,却在行为上不再是一个button了,当然鼠标点击的时候也就不再触发 onButtonClick 事件,而是象普通的div等节点一样触发 onMouseClick ,这就是我们在前面失败的原因。
所以这时候我们需要添加behavior,就是给节点添加新的behavior但是又不覆盖节点已经拥有的behavior.
在HTMLayout中使用波浪号表示添加behavior,例如:  behavior:~command;   波浪号在名字前面表示追加behavior,波浪号在名字后面表示插入behavior,你可以把 ~ 理解为原来的behavior列表。
如果要同时为节点指定多个behavior,则可以使用空格分格,例如:

  1. #my-button{
  2. behavior:button command;
  3. }
复制代码
所以我们同时指定多个behavior,或者使用了个 波浪号 都可以解决前面遇到的问题,正确代码如下:
  1. import win.ui;
  2. /*DSG{{*/
  3. var winform = ..win.form( right=599;bottom=399;text="HTMLayout - 自定义behavior";)
  4. winform.add(  )
  5. /*}}*/

  6. import web.layout;
  7. var wbLayout = web.layout( winform )

  8. namespace web.layout.behavior.command {

  9. onButtonClick = function (ltTarget,ltOwner,reason,behaviorParams) {
  10. /*
  11. 当用户点击按钮时,
  12. 使用 innerHTML 属性改变节点内部的HTML代码,
  13. inner是内部的意思,innerHTML就是指的节点内部的HTML代码
  14. */
  15. ltOwner.innerHTML = "谢谢!"
  16. }
  17. }

  18. wbLayout.html = /**
  19. <button id="my-button">据说在html里可以使用button表示一个按钮</button>
  20. **/

  21. wbLayout.css = /**
  22. #my-button{
  23. behavior:~command; /*用波浪号追加 behavior */
  24. }
  25. **/

  26. winform.show()
  27. win.loopMessage();
复制代码
然后切换到代码视图,在 import web.layout; 后面添加
import web.layout.behavior.windowCommand; 以导入标准库实现的behavior
然后我们在HTML中添加一个简单的标题栏和关闭按钮
wbLayout.html = /**
<div #title-bar>
<a>关闭窗口</a>
最后在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>
然后我们简单的改进一下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{
//标题栏按钮容器绝对定位到窗口右上角
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中指定以使用绝对定位方式。

最终代码如下:
  1. import win.ui;
  2. /*DSG{{*/
  3. var winform = ..win.form( bottom=399;text="HTMLayout - 无边框窗口";border="none";right=599 )
  4. winform.add(  )
  5. /*}}*/

  6. import win.util.round;
  7. win.util.round(winform,,,6,6); //窗体改成圆角,最后两个参数指定圆角半径

  8. import web.layout;
  9. import web.layout.behavior.windowCommand;

  10. var wbLayout = web.layout( winform )

  11. wbLayout.html = /**
  12. <div #title-bar command="window-caption">
  13. <div .ctrl-bar>
  14. <a command="window-close">r</a>
  15. </button>
  16. </div>
  17. **/

  18. wbLayout.css = /**
  19. html{
  20. background:#999;/*网页背景色*/
  21. border-radius:4px; /*8像素大小的圆角*/
  22. }

  23. #title-bar{
  24. behavior:windowCommand;
  25. width:100%; /*宽度撑满窗口*/
  26. height:22px; /*指定高度*/
  27. background:#CCCCCC; /*背景色*/

  28. }

  29. /*CSS选择器中,空格表示节点间的父子包含关系*/
  30. #title-bar .ctrl-bar{
  31. //标题栏按钮容器绝对定位到窗口右上
  32. top:0px;//顶坐标1像素
  33. right:8px;//右坐标5像素
  34. }

  35. /*CSS选择器中,方括号指定节点拥有的属性*/
  36. #title-bar a[command]{
  37. display:block; //显示为块节点
  38. float:left;//块节点左浮动,如果有多个按钮可以从左向右排
  39. height:16px;
  40. font-family:"Marlett";/*这个字体把小写r显示为关闭符号*/
  41. padding:4px;

  42. }

  43. #title-bar a[command]:hover{
  44. background:#999;
  45. }
  46. **/

  47. winform.show()
  48. 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 属性可以用来改变节点内容,例如:

  1. div#my-id{ content:"文本"; })
复制代码
答案在下面:

  1. import win.ui;
  2. /*DSG{{*/
  3. var winform = ..win.form(text="HTMLayout 无边框窗体";right=599;bottom=399;border="none";parent=...)
  4. winform.add()
  5. /*}}*/

  6. import web.layout;
  7. import web.layout.behavior.windowCommand;
  8. import web.layout.behavior.windowSizer;

  9. //创建网页浏览器
  10. var wbLayout = web.layout( winform )

  11. wbLayout.html = /**
  12. <html>
  13. <body>
  14. <!-- 下面是标题栏,凡在CSS中指定 behavior:windowCommand 的节点(含子节点) 可用 command 属性指明命令类型 -->
  15. <div #title-bar command="window-caption"> <span .title> 我 的 软 件 </span>
  16. <div .ctrl-bar>

  17. <!-- 弹出菜单,类似这种包含弹出节点的最好用div或button,
  18. div主要用作布局容器 - 可更好的支持弹出子节点或浮动子节点,
  19. 而a,li等节点存在的主要目的不是用来做其他节点的容器 -->
  20. <div .window-menu>u
  21. <menu .popup> <!-- .popup是内置的弹出菜单样式 -->
  22. <li>在线帮助</li>
  23. <li>子菜单
  24. <menu >
  25. <li>这是子菜单</li>
  26. </menu>
  27. </li>
  28. <li #exit>退出</li>
  29. </menu>
  30. </div>

  31. <!-- 下面是标题栏按钮,必须使用a标记表示,command属性指示该按钮执行的命令 -->
  32. <a command="window-min">0</a>
  33. <a command="window-max">1</a>
  34. <a command="window-close">r</a>
  35. </div>
  36. </div>

  37. <!--下面这句用来支持可拖动的边框,必须在aardio中调用 import web.layout.behavior.windowSizer -->
  38. <div style="behavior:windowSizer"/>
  39. </body>
  40. </html>
  41. **/

  42. wbLayout.css = /**

  43. body{
  44. margin:0;
  45. background:#fff;/*网页背景色*/
  46. }

  47. #title-bar{
  48. behavior:windowCommand;  /*必须在aardio中 import web.layout.behavior.windowCommand */
  49. width:100%; /*宽度撑满窗口*/
  50. height:28px; /*指定高度*/
  51. background:#5a5a5a; /*背景色*/
  52. }

  53. /*最大化后body会自动添加maximize属性*/
  54. body[maximize]{
  55. border-radius:0;/*最大化去掉圆角*/
  56. }

  57. body[maximize] #title-bar{
  58. border-radius:0;/*最大化去掉圆角*/
  59. }

  60. #title-bar span.title{
  61. font:system;
  62. margin:6px 0 0 10px;
  63. color:#CCCCCC;
  64. }

  65. /*CSS选择器中,空格表示节点间的父子包含关系*/
  66. #title-bar .ctrl-bar{
  67. //标题栏按钮容器绝对定位到窗口右上角
  68. top:1px;//顶坐标
  69. right:8px;//右坐标
  70. width:95px
  71. }

  72. /*CSS选择器中,方括号指定节点拥有的属性*/
  73. #title-bar .ctrl-bar a{
  74. display:block; //显示为块节点
  75. float:left;//块节点左浮动( 从左向右排 )
  76. height:14px;
  77. font-family:"Marlett";/*该字体显示按钮符号*/
  78. font-size:14px;
  79. padding:4px;
  80. color:#fff;
  81. }

  82. #title-bar a[command]:hover{
  83. background:#6ebccf;
  84. }

  85. #title-bar a[command]:active{
  86. background:#FF0000;
  87. }

  88. #title-bar a[command="window-restore"]{
  89. content:"2";/*改变文本,Marlett字体为还原符号*/
  90. }

  91. #title-bar .window-menu{
  92. behavior:popup-menu;
  93. float:left;
  94. height:14px;
  95. font-family:"Marlett";/*该字体显示按钮符号*/
  96. font-size:14px;
  97. padding:4px;
  98. color:#fff;
  99. }
  100. #title-bar .window-menu:hover{
  101. background:#6ebccf;
  102. }
  103. #title-bar .window-menu:owns-popup /*菜单已弹出*/
  104. {
  105. background-color: #FF0000;
  106. color: #FFFFFF;
  107. }
  108. **/

  109. // 响应菜单点击事件
  110. wbLayout.onMenuItemClick =  {

  111. // 事件可以是一个函数或列表,如果是列表键名匹配节点的id或name属性
  112. exit = function (ltTarget,ltOwner,reason,behaviorParams) {
  113. winform.close();
  114. }

  115. // 在这里没有匹配不到id的节点会触发default函数*/
  116. default = function (ltTarget,ltOwner,reason,behaviorParams) {
  117. var ltPopupOwner = web.layout.element( behaviorParams.he );//这是弹出菜单的按钮节点
  118. winform.msgbox( ltTarget.innerText )
  119. }
  120. }

  121. import win.ui.shadow;
  122. win.ui.shadow(winform); //添加阴影边框

  123. winform.show();
  124. win.loopMessage();

复制代码

运行效果: