GUI图形界面库

Mac App Store 上的Silk内置了一些GUI类库供使用者开发MacOS上的图形界面程序,只需引用gui.si即可,gui.si包含下列类库:

CNative类
CNative类是所有GUI类的基类,包含如下成员函数:

GrantPermission(path)
GrantPermission 用来获取某个目录的读写权限,由于Mac App Store的SandBox机制,App Store上下载的App默认情况下对除了自己的目录,其它目录均没有读写权限。GrantPermission函数将会弹出选择对话框让用户选择确认后 获取权限,并且会记录用户的选择,下次调用就直接赋予权限,用户不用再次选择。参数path是需要获取权限的目录的路径。
#include "gui.si"
main()
{
    native=CNative();
    native.GrantPermission(_fun("curdir"));
}

ClearOutput()
ClearOutput()函数用来清空IDE输出窗口的运行结果。
#include "gui.si"
main()
{
    print("output test");
    native=CNative();
    native.ClearOutput();
}

GetInputkey()
GetInputkey()函数从Silk IDE的输入框读取用户的键盘输入。
#include "gui.si"
main()
{
    print("请输入号码并按回车键:");
    native=CNative();
    s=native.GetInputkey();
    print(s);
}

LiveOutput(enable)
LiveOutput 函数将会控制程序是否实时地在IDE输出窗口输出print或printf等函数的打印信息。在某些情况下(如线程运行),为了程序的运行速度,IDE默 认将不会实时输出打印的信息,程序运行完成会输出所有的打印信息。参数enable可以传入true或者false,true为实时输出。
#include "gui.si"
main()
{
    native=CNative();
    native.LiveOutput(true);
}

CWindow
CWindow类用来创建MacOS的窗口,包含如下成员函数:

CreateWindow(title,width,height)
CreateWindow 用来创建一个Mac的窗口,参数title为窗口的标题,width为窗口宽度,height为窗口高度。
#include "gui.si"
main()
{
    win=CWindow();
    w=400;
    h=300;
    win.CreateWindow("我的第一个窗口程序",w,h);
    win.MainLoop();
}

Close()
Close函数关闭当前窗口。

Show(enable)
Show函数显示或隐藏当前窗口,参数enable为true显示,false为隐藏。

SetTitle(title)
SetTitle函数设置窗口标题,参数title为标题字符串。
#include "gui.si"
main()
{
    win=CWindow();
    w=400;
    h=300;
    win.CreateWindow("我的第一个窗口程序",w,h);
    win.SetTitle("我的标题");
    win.MainLoop();
}

GetRect()
GetRect函数获取窗口的位置和大小,返回的类型为CRect类,CRect类包含对象的坐标(x,y)以及对象的长和宽(w,h)。
#include "gui.si"
main()
{
    win=CWindow();
    w=400;
    h=300;
    win.CreateWindow("我的第一个窗口程序",w,h);
    rect=win.GetRect();
    print(rect.x,rect.y,rect.w,rect.h);
}

SetRect(rect)
SetRect函数设置窗口的位置和大小,参数rect为CRect类。
#include "gui.si"
main()
{
    win=CWindow();
    w=400;
    h=300;
    win.CreateWindow("我的第一个窗口程序",w,h);
    rect=CRect(100,100,500,600);
    win.SetRect(rect);
    win.MainLoop(false);
}

SetStyle(resizable,closable=true,miniaturizable=true)
SetStyle函数设置窗口的风格,参数resizable为true表示窗口有最大化按钮并可改变大小,closable表示窗口有关闭按钮,miniaturizable表示窗口有最小化按钮。
closable和miniaturizable都有缺省值true,可省略。
#include "gui.si"
main()
{
    win=CWindow();
    w=400;
    h=300;
    win.CreateWindow("我的第一个窗口程序",w,h);
    win.SetStyle(true);
    win.MainLoop();
}

 AddComboBox(rect=null,callback=null,param=null)
  AddComboBox函数用来在窗口上加入下拉列表框控件,参数rect为列表框的位置和大小,callback为列表框改变选项后的回调函数,param为任意参 数,传入可供回调函数使用。
回调函数包 含4个参数,分别为列表框句柄handle,当前选项index,当前选项的文字text,传入的参数param,具体用法如下列例子。
所有参数都有缺省值null,如果使用缺省值而不传入参数,那么Silk将自动设置列表框的位置和大小,一般在窗口的居中位置,宽度200,高度25。
AddComboBox执行成功将返回加入的列表框对象CComboBox
#include "gui.si"
func comboSelected(handle,index,text,param)
{
    print(index,text,param);
}
main()
{
    win=CWindow();
    w=400;
    h=300;
    win.CreateWindow("我的第一个窗口程序",w,h);
    param=win;
    combo=win.AddComboBox(null,comboSelected,param);
    combo.AddString("test1");
    win.MainLoop();
}

AddPopupButton(rect=null,callback=null,param=null)
AddPopupButton函数用来在窗口上加入列表按钮控件,参数rect为列表按钮的位置和大小,callback为列表按钮改变选项后的回调函数,param为任意参数,传入可供回调函数使用。
所有参数都有缺省值null,如果使用缺省值而不传入参数,那么Silk将自动设置列表按钮的位置和大小,一般在窗口的居中位置,宽度200,高度25。
AddPopupButton执行成功将返回加入的列表按钮对象CPopupButton
#include "gui.si"

func popup_click(handle,index,title,param)
{
    print(index,title);
}
main()
{
    win=CWindow();
    win.CreateWindow("Test",300,200);
    label=win.AddLabel("Please select your language:");
    rect=label.GetRect();
    rect.h=20;
    rect.y=rect.y-rect.h-5;
    btn=win.AddPopupButton(rect,popup_click);
    btn.AddItem("English");
    btn.AddItem("Chinese");

    win.MainLoop();
}

 
AddTextView(text="",rect=null)
AddTextView函数用来在窗口上加入文本显示框控件,文本显示框支持多行。参数rect为文本显示框的位置和大小,text为文本显示框的初始文字。
AddTextView执行成功将返回加入的文本显示框对象CTextView
#include "gui.si"

func save_click(handle,param)
{
}
main()
{
    win=CWindow();
    w=500;
    h=400;
    win.CreateWindow("录入人员信息",w,h);
    label=win.AddLabel("name:");
    text1=win.AddTextField("");
    rect=text1.GetRect();
    rect.h=20;
    rect.y=rect.y-rect.h-5;
    win.AddLabel("memo:",rect);
    text2=win.AddTextView();
    
    rect=text2.GetRect();
    rect.h=25;
    rect.y=rect.y-rect.h-10;
    param={"name":text1, "memo":text2};
    win.AddButton("save",rect,save_click,param);

    win.MainLoop();
}


AddTableView(rect=null,selectionChanged=null,doubleClicked=null,param=null)
AddTableView函数用来在窗口上加入表格框控件,表格支持多行多列。参数rect为表格框的位置和大小,selectionChanged为改变表格选项后的回调函数,
doubleClicked为双击表格选项后的回调函数,param为任意参数,传入可供回调函数使用。
所有参数都有缺省值null,如果使用缺省值而不传入参数,那么Silk将自动设置表格框的位置和大小。
AddTableView执行成功将返回加入的表格框对象CTableView
#include "gui.si"

func tableViewSelectionChanged(handle,parent,index,data,param)
{
    print("selection changed: ",index,data)
}
func tableViewDoubleClicked(handle,parent,index,data,param)
{
   table=CTableView(handle,parent);
   print("selection double clicked: ",index,data);
}

main()
{
    win=CWindow();
    w=600;
    h=400;
    win.CreateWindow("人员信息",w,h);
   
    res=[{"id":1000,"name":"Jack","age":27,"phone":"18801000000"}];
    data={};
    data["id"]=1001;
    data["name"]="Wang";
    data["age"]=21;
    data["phone"]="13799999999";
    res.append(data);

    rect=CRect(10,10,w-20,h-40-20);
    param={"win":win};
    table=win.AddTableView(rect,tableViewSelectionChanged,tableViewDoubleClicked,param);
    table.AddColumn("姓名","name");
    table.AddColumn("年龄","age");
    table.AddColumn("电话","phone");
    for(i=0;i<res.size();i++)
        table.AddData(res[i]);
    table.Refresh();
    
    win.MainLoop();
}


AddButton(title,rect=null,callback=null,param=null)
AddButton函数用来在窗口上加入按钮控件。参数title为按钮文字,rect为按钮的位置和大小,callback为按下按钮后的回调函数,param为任意参数,传入可供回调函数使用。
参数rect有缺省值null,如果使用缺省值而不传入参数,那么Silk将自动设置按钮的位置和大小。
AddButton执行成功将返回加入的按钮对象CButton
具体用法如下列例子。

AddLabel(title,rect=null)
AddLabel函数用来在窗口上加入文本标签控件。参数rect为文本标签的位置和大小,title为文本标签的文字。
AddLabel执行成功将返回加入的文本标签对象CTextField
具体用法如下列例子。

AddTextField(title="",rect=null)
AddTextField函数用来在窗口上加入文本输入框控件。参数rect为输入框的位置和大小,title为输入框的初始文字。
AddTextField执行成功将返回加入的文本输入框对象CTextField
具体用法如下列例子。

AddSecureTextField(title="",rect=null)
AddSecureTextField函数用来在窗口上加入密码输入框控件。参数rect为输入框的位置和大小,title为输入框的初始文字。
AddSecureTextField执行成功将返回加入的密码输入框对象CSecureTextField
具体用法如下列例子。
#include "gui.si"

func login_click(handle,param)
{
    if(!param)
       return;
    pass_field=param["pass_field"];
    if(pass_field.GetText()=="test")
    {
        msgbox=CMessageBox();
        msgbox.ShowMessage("提示","登录成功!");
    }
}
main()
{
    win=CWindow();
    win.CreateWindow("登录",300,200);

    label=win.AddLabel("用户名:");
    user_field=win.AddTextField("test");
    rect=user_field.GetRect();
    rect.h=20;
    rect.y=rect.y-rect.h-5;
    win.AddLabel("密码:",rect);
    pass_field=win.AddSecureTextField("");
    rect=pass_field.GetRect();
    rect.y=rect.y-rect.h-15;
    param={"win":win, "user_field":user_field, "pass_field":pass_field};
    button=win.AddButton("登录",rect,login_click,param);
    
    win.MainLoop();
}


CreateCanvas(rect,backcolor=null)
CreateCanvas函数用来在窗口上创建画布,在画布上可以绘制各种图形和图像。参数rect为画布的位置和大小,backcolor为画布的背景色。
CreateCanvas执行成功将返回创建的画布对象CCanvas
#include "gui.si"

main()
{
    win=CWindow();
    win.CreateWindow("Test",400,300);
    rect=CRect(10,10,200,200);
    canvas=win.CreateCanvas(rect,"#bbada0");
    canvas.DrawLine(CPoint(10,10),CPoint(100,100),2,"red");
    canvas.DrawText("Hello silk",CPoint(50,50),"white",20,true);

    win.MainLoop();
}

BindEvent(event,callback,param=null)
BindEvent函数用来绑定各种键盘,鼠标和窗口事件。参数event为事件名称,callback为事件的回调函数,param为任意参数,
传入可供回调函数使用,目前支持的事件有EventLeftMouseDown,EventLeftMouseUp,EventRightMouseDown,EventRightMouseUp,EventLeftMouseDragged,
EventMouseMoved,EventKeyDown,EventKeyUp和EventWindowWillResize。
具体用法如下列例子。
#include "gui.si"

func winResize(handle,size,param)
{
    print(size);
}
func LeftMouseDown(data,param)
{
    x=data["x"];//鼠标点击后x坐标
    y=data["y"];//鼠标点击后y坐标
    win=param;//传入的参数
    print(x,y,win);
}
func KeyDown(key,param)
{
    print("the pressed key code is ",key);//打印键盘按下的键代码值
}
main()
{
    win=CWindow();
    win.LiveOutput(true);
    win.CreateWindow("Test",400,300);
    win.SetStyle(1);
    win.BindEvent("EventLeftMouseDown",LeftMouseDown,win);//绑定鼠标左键按下事件
    win.BindEvent("EventKeyDown",KeyDown);//绑定键盘按下事件,参数不传入
    win.BindEvent("EventWindowWillResize",winResize,win);//绑定窗口大小改变事件
    
    win.MainLoop();
}


CreateTimer(interval,callback)
CreateTimer函数用来创建定时器,定时执行各种任务。参数interval为每隔多少秒执行定时器,callback为定时器执行时的回调函数,具体用法如下列例子。
#include "gui.si"
_timer1=null;
_timer2=null;

func HandleTimer(timer)
{
    if(timer==_timer1.handle)
    {
        print("timer1");
    }
    else if(timer==_timer2.handle)
    {
        print("timer2");
    }
}
main()
{
    win=CWindow();
    win.CreateWindow("Test",400,300);
    _timer1=win.CreateTimer(1,HandleTimer);//每隔1秒执行定时任务
    _timer2=win.CreateTimer(0.5,HandleTimer);//每隔0.5秒执行定时任务
    
    win.MainLoop();
}


MainLoop(center=true)
MainLoop函数用来显示窗口并进入消息循环接收各种窗口消息,直到收到退出消息才会退出循环终止程序。参数center为设置窗体居中显示


CMessageBox类
CMessageBox类用来显示消息框,文件选择对话框,文件保存对话框,输入框和颜色选择框,包含如下成员函数:

ShowMessage(title,message,button1="OK",button2=null,button3=null)
ShowMessage 用来显示消息框,参数title为消息框标题,message为消息文字,button1为第一个按钮,一般为确认按钮,缺省文字为OK,
button2为第二个按钮,一般为取消按钮,button3为第三个按钮,一般提问消息需要三个按钮。button2和button3有缺省值null,可以省略。
#include "gui.si"

main()
{
    box=CMessageBox();
    box.ShowMessage("test","hello silk");
}

ShowInputBox(title,button1,button2=null)
ShowInputBox 用来显示输入框,参数title为输入框标题,button1为第一个按钮,一般为确认按钮,button2为第二个按钮,一般为取消按钮。
函数返回值为用户输入的字符串。
#include "gui.si"

main()
{
    box=CMessageBox();
    text=box.ShowInputBox("Please input your name:","OK");
    print(text);
}

ShowFileDialog(title,multisel=false,dir=false,createdir=false)
ShowFileDialog 用来显示文件选择框,参数title为选择框标题,multisel为是否可以选择多个文件,缺省为false;dir为是否可以选择目录,缺省为false;
createdir为是否可以创建目录,缺省为false。函数的返回值为包含选中文件路径的数组。
#include "gui.si"

main()
{
    box=CMessageBox();
    filelist=box.ShowFileDialog("Please select files",true);
    for(i=0;i<filelist.size();i++)//filelist contains all the selected files
        print(filelist[i]);
}

ShowSaveDialog(title,defaultdir=null,createdir=false)
ShowSaveDialog 用来显示文件保存框,参数title为保存框标题,defaultdir为默认的保存路径,缺省为null;createdir为是否可以创建目录,缺省为false。
函数的返回值为包含选中文件路径的数组。
#include "gui.si"

main()
{
    box=CMessageBox();
    files=box.ShowSaveDialog("Please select a file to save");
    if(files)
        print(files[0]);
}

ShowColorDialog(colorChanged,param=null,color=null)
ShowColorDialog 用来显示颜色选择框,参数colorChanged为选择的颜色改变后的回调函数,param为传入回调函数的任意参数,缺省为null;color为默认的颜色。
注意:ShowColorDialog的回调函数colorChanged必须在窗口的消息循环内使用,所以需调用MainLoop函数进入消息循环后使用。
#include "gui.si"

func colorChanged(color,param)
{
    print("The selected color is ", color);
}
func buttonClick(handle,param)
{
    box=CMessageBox();
    box.ShowColorDialog(colorChanged);
}
main()
{
    win=CWindow();
    win.LiveOutput(true);
    win.CreateWindow("Test",400,300);
    win.AddButton("color",null,buttonClick);
    
    win.MainLoop();
}

CComboBox
CComboBox下拉列表框类,包含如下成员函数:

GetCurSel()
GetCurSel函数 用来获取列表框当前选中的项目的索引,索引从0开始,如果没有选中的项,返回的索引为-1。具体用法见下列例子。

SetCurSel(index)
SetCurSel函数 用来设置列表框当前选中的项目,参数index为需要选中项的索引。具体用法见下列例子。

AddString(string)
AddString函数 用来在列表框中加入项目,参数string为加入的项目,为字符串类型。具体用法见下列例子。

InsertString(string,index)
InsertString函数 用来在列表框的某个项目前插入项目,参数string为插入的项目,index为某个项目的索引。具体用法见下列例子。

Remove(index)
Remove函数 用来删除列表框中的某个项目,参数index为某个项目的索引。具体用法见下列例子。

SetEditable(enable)
SetEditable函数 用来设置列表框是否可以编辑,参数enable为true可编辑。具体用法见下列例子。

Clear()
Clear函数 用来清空列表框中的所有项目。具体用法见下列例子。

GetString()
GetString函数 用来获取列表框中当前的项目文字。具体用法见下列例子。

SetString(string)
SetString函数 用来在列表框中设置当前的文字,参数string为设置的文字。具体用法见下列例子。

GetStringAtIndex(index)
GetStringAtIndex函数 用来获取列表框中某个项目的文字,参数index为某个项目的索引。具体用法见下列例子。
#include "gui.si"
func buttonClick(handle,param)
{
    type=param["type"];
    combo=param["combo"];
    if(type=="index")
    {
        index=combo.GetCurSel();
        print(index);
        print(combo.GetString());
        combo.SetString("sss");
        print(combo.GetStringAtIndex(0));
    }
    else if(type=="clear")
    {
        combo.Clear();
    }
}

main()
{
    win=CWindow();
    w=400;
    h=300;
    win.CreateWindow("我的第一个窗口程序",w,h);
    combo=win.AddComboBox();
    combo.AddString("test1");
    combo.AddString("test2");
    combo.AddString("test3");
    combo.InsertString("hello",1);
    combo.Remove(2);
    combo.SetCurSel(1);
    combo.SetEditable(false);
    param={"combo":combo,"type":"index"};
    btn=win.AddButton("Index",null,buttonClick,param);
    param={"combo":combo,"type":"clear"};
    btn=win.AddButton("Clear",null,buttonClick,param);

    win.MainLoop();
}


CTableView
CTableView为表格框类,包含如下成员函数:

GetData(row)
GetData函数 用来获取表格框中的某行数据,参数row为行号,从0开始。具体用法见下列例子。

GetCurSel()
GetCurSel函数 用来获取表格框中当前选中行的行号。具体用法见下列例子。

SetData(row,data)
SetData函数 用来设置表格框中的某行数据,参数row为行号,data为行数据,为字典类型。具体用法见下列例子。

Delete(row)
Delete函数 用来删除表格框中的某行数据,参数row为行号。具体用法见下列例子。

Clear()
Clear函数 用来清空表格框中的所有数据。具体用法见下列例子。

AddData(data)
AddData函数 用来在表格框中添加一行数据,参数data为数据。具体用法见下列例子。

Refresh()
Refresh函数 用来在界面上刷新数据,对表格添加,删除或修改数据后必须调用Refresh函数,不然界面不会更新。具体用法见下列例子。

AddColumn(title,identifier=null,width=null)
AddColumn函数 用来在表格框中添加列,一般在创建表格框后调用,参数title为列名,identifier为列的唯一标识符,width为列宽。具体用法见下列例子。
#include "gui.si"

func tableViewSelectionChanged(handle,parent,index,data,param)
{
    print("selection changed: ",index,data)
}
func tableViewDoubleClicked(handle,parent,index,data,param)
{
   table=CTableView(handle,parent);
   print("selection double clicked: ",index,data);
}
func add_click(handle,param)
{
    table=param["table"];
    res={"id":1000,"name":"New","age":10,"phone":"1000"};
    table.AddData(res);
    table.Refresh();
}
func edit_click(handle,param)
{
    table=param["table"];
    row=table.GetCurSel();
    if(row>=0)
    {
        data=table.GetData(row);
        data["name"]="updated";
        table.SetData(row,data);
        table.Refresh();
    }
}
func delete_click(handle,param)
{
    table=param["table"];
    row=table.GetCurSel();
    if(row>=0)
    {
        //table.Clear();
        table.Delete(row);
        table.Refresh();
    }
}

main()
{
    win=CWindow();
    w=600;
    h=400;
    win.CreateWindow("人员信息",w,h);
   
    res=[{"id":1000,"name":"Jack","age":27,"phone":"18801000000"}];
    rect=CRect(10,10,w-20,h-40-20);
    param={"win":win};
    table=win.AddTableView(rect,tableViewSelectionChanged,tableViewDoubleClicked,param);
    table.AddColumn("姓名","name");
    table.AddColumn("年龄","age");
    table.AddColumn("电话","phone");
    for(i=0;i<res.size();i++)
        table.AddData(res[i]);
    table.Refresh();
    
    w2=100;
    h2=25;
    rect=CRect(10,h-40,w2,h2);
    param={"table":table};
    button=win.AddButton("增加",rect,add_click,param);
    rect=CRect(10+w2+5,h-40,w2,h2);
    button=win.AddButton("编辑",rect,edit_click,param);
    rect=CRect(10+(w2+5)*2,h-40,w2,h2);
    button=win.AddButton("删除",rect,delete_click,param);
   
    win.MainLoop();
}


CButton
CButton为按钮类,包含如下成员函数:

SetCheckBox(enable,status=0)
SetCheckBox函数 用来设置按钮为Checkbox类型,参数enable为true则为Checkbox类型,status为1则状态打勾。具体用法见下列例子。

SetRadio(enable,status=0)
SetRadio函数 用来设置按钮为Radio类型,参数enable为true则为Radio类型,status为1则radio选中状态。具体用法见下列例子。

GetStatus()
GetStatus函数 用来获取按钮状态,如果是Checkbox或Radio按钮,则打勾或选中返回1,否则返回0。具体用法见下列例子。

SetStatus(status)
SetStatus函数 用来设置Checkbox或Radio按钮的状态,参数status为1则设置为打勾或选中。具体用法见下列例子。

SetTitle(title)
SetTitle函数 用来设置按钮标题,参数title为标题文字。

GetRect()
GetRect函数 用来获取按钮在窗口上的坐标和长宽。

SetRect(rect)
SetRect函数 用来设置按钮在窗口上的坐标和长宽。参数rect为按钮的位置坐标和长宽。

RoundedStyle(enable)
RoundedStyle函数 用来设置按钮为圆角风格,参数enable为true则为圆角按钮。具体用法见下列例子。
#include "gui.si"

func button_click(handle,param)
{
    button=CButton(handle);
    if(param==1)
    {
        print("checkbox status: ",button.GetStatus());   
    }
    else if(param==2)
    {
        print("radio1 status: ",button.GetStatus());   
    }
    else if(param==3)
    {
        print("radio2 status: ",button.GetStatus());   
    }
    else
    {
        button1=param[0];
        button1.SetStatus(0);
        button3=param[2];
        button3.SetStatus(1);
    }
}
main()
{
    win=CWindow();
    win.LiveOutput(true);
    win.CreateWindow("Test",300,200);
    button1=win.AddButton("checkbox",null,button_click,1);
    button1.SetCheckBox(true,1);
    button2=win.AddButton("radio1",null,button_click,2);
    button2.SetRadio(true,1);
    button3=win.AddButton("radio2",null,button_click,3);
    button3.SetRadio(true,0);
    param=[button1,button2,button3];
    button4=win.AddButton("button",null,button_click,param);
    button4.RoundedStyle(true);
   
    win.MainLoop();
}

CPopupButton
CPopupButton为按钮列表框类,包含如下成员函数:

AddItem(item)
AddItem函数 用来往按钮列表框中加入项目,参数item为需要加入的项目,字符串类型。


CTextField类,CSecureTextField类,CTextView
CTextField为字符框类,CSecureTextField为密码框类,CTextView为文本框类(支持多行),他们的用法类似,共同包含如下成员函数:

GetText()
GetText函数 用来获取字符框的内容。具体用法见下列例子。

SetText(text)
SetText函数 用来设置字符框的内容,参数text为需要设置的文字。具体用法见下列例子。

GetRect()
GetRect函数 用来获取字符框在窗口上的坐标和长宽。

SetRect(rect)
SetRect函数 用来设置字符框在窗口上的坐标和长宽。参数rect为字符框的位置坐标和长宽。

SetEditable(enable)
SetEditable函数 用来设置字符框是否可编辑,参数enable为true表示可编辑。具体用法见下列例子。
#include "gui.si"

func button_click(handle,param)
{
    textfield=param[0];
    passfield=param[1];
    textview=param[2];
    print(textfield.GetText(),passfield.GetText());
    textfield.SetText("ok");
    textfield.SetEditable(true);
    textview.SetText("good\r\ngreat\r\namazing")
}
main()
{
    win=CWindow();
    win.LiveOutput(true);
    win.CreateWindow("Test",300,200);
    textfield=win.AddTextField("test");
    textfield.SetEditable(false);
    passfield=win.AddSecureTextField("pass");
    textview=win.AddTextView("hello\r\nhow are you");
    param=[textfield,passfield,textview];
    button=win.AddButton("test",null,button_click,param);
    
    win.MainLoop();
}


CTimer
CTimer为定时器类,包含如下成员变量和成员函数:

handle
handle成员变量 用来获取定时器的句柄用来和定时器回调函数参数里的句柄比较。具体用法见下列例子。

Pause()
Pause函数 用来暂停定时器。具体用法见下列例子。

Start()
Start函数 用来启动定时器,当定时器被Pause函数暂停时,可以通过Start重新启动。具体用法见下列例子。

Stop()
Stop函数 用来停止定时器,也就是关闭定时器。具体用法见下列例子。
#include "gui.si"
_timer=null;
_pause=false;

func button_click(handle,param)
{
    global _pause;
    if(!_pause)
    {
        _timer.Pause();
        print("timer was paused");
    }
    else
    {
        _timer.Start();
        print("timer was restarted");
    }
    _pause=!_pause;
}
func button2_click(handle,param)
{
    _timer.Stop();
    print("timer was stopped!");
}
func HandleTimer(timer)
{
    if(timer==_timer.handle)
    {
        print("timer");
    }
}
main()
{
    win=CWindow();
    win.LiveOutput(true);
    win.CreateWindow("Test",400,300);
    _timer=win.CreateTimer(1,HandleTimer);
    win.AddButton("pause/restart",null,button_click);
    win.AddButton("stop",null,button2_click);
    
    win.MainLoop();
}


CCanvas
CCanvas为画布类,包含如下成员函数:

DrawLine(point1,point2,width=1.0,color="00ff00")
DrawLine 函数 用来在画布上画线段。参数point1为线段起始点坐标,point2为终点坐标;width为线段的宽度,默认为1.0;color为线段的颜色,颜色 为字符串类型,可以传入颜色的十六进制字符串形式,常用颜色(red,green,blue,yellow,white,black)可以用英文单词代 替。具体用法见下列例子。

DrawRect(rect,width=1.0,colorLine="ff0000",fill=true,colorFill="ff0000")
DrawRect函数 用来在画布上画矩形。参数rect为矩形的左下角坐标和长宽;width为线的宽度;colorLine为线的颜色;fill为是否用颜色填充矩形,默认为true;colorFill为填充的颜色,默认为红色。
具体用法见下列例子。

DrawRoundedRect(rect,width=1.0,colorLine="ff0000",fill=true,colorFill="ff0000",xRadius=30.0,yRadius=30.0)
DrawRoundedRect 函数 用来在画布上画圆角矩形。参数rect为矩形的左下角坐标和长宽;width为线的宽度;colorLine为线的颜色;fill为是否用颜色填充矩形, 默认为true;colorFill为填充的颜色,默认为红色;xRadius为圆角在x轴方向的半径,yRadius为圆角在y轴方向的半径,默认为 30,这2个参数用来调整圆角的弧度。
具体用法见下列例子。

DrawOval(rect,width=1.0,colorLine="ff0000",fill=true,colorFill="ff0000")
DrawOval函数 用来在画布上画椭圆或圆(外围矩形为正方形时为圆)。参数rect为椭圆外围矩形的左下角坐标和长宽;width为线的宽度;colorLine为线的颜色;fill为是否用颜色填充矩形,默认为true;colorFill为填充的颜色,默认为红色。
具体用法见下列例子。

DrawText(text,point,color="ff0000",size=12,center=false,font="Helvetica")
DrawText 函数 用来在画布上画文字。参数text为文字字符串;point为文字外围矩形框的左下角坐标;color为文字颜色;size为文字字体大小,默认为12; center表示文字是否居中显示,默认不居中;font为文字的字体名,默认为Helvetica。具体用法见下列例子。

OpenImage(filename)
OpenImage函数 用来打开图像文件,返回一个类型为CImage的图像对象,CImage只有一个成员函数Close(),如果对象不再使用,可以通过Close关闭。参数filename为图像文件的路径。具体用法见下列例子。

DrawImage(image,rect,operation=1,fraction=1.0,scale=1)
DrawImage 函数 用来在画布上画图像。参数image为通过OpenImage函数打开的图像对象;rect为图像在画布上显示的位置坐标和长宽;operation为是 否透明显示图像,缺省1为透明;fraction为图像透明度,默认为1.0;scale为是否可以放大缩小图片,默认为1,表示可以放大缩小,将按 rect的大小显示图片,如果为0,则按图片原始大小显示,rect的大小将被忽略。具体用法见下列例子。

SaveToImage(filename,rect=null)
SaveToImage函数 用来保存画布到图像文件。参数filename为图像文件的路径;rect为指定要保存画布的某一部分的坐标和大小,默认为null,表示要保存全部的画布。具体用法见下列例子。

Clear()
Clear函数 用来清除画布上所画内容,最后需要调用Refresh才能呈现清除后的画布。具体用法见下列例子。

Refresh()
Refresh函数 用来刷新画布,对画布的任何操作(DrawLine,DrawRect,DrawImage等)最后都需要调用Refresh函数才能呈现。具体用法见下列例子。

GetRect()
GetRect函数 用来获取画布在窗口上的坐标和长宽。

SetRect(rect)
SetRect函数 用来设置画布在窗口上的坐标和长宽。参数rect为画布的位置坐标和长宽。具体用法见下列例子。

 SetBackColor(color)
SetBackColor函数 用来设置画布的背景颜色。参数color为颜色值。具体用法见下列例子。
#include "gui.si"

func button_click(handle,param)
{
    canvas=param;
    canvas.DrawLine(CPoint(10,10),CPoint(100,100),2,"red");//draw line
    canvas.DrawText("Hello silk",CPoint(50,50),"white",20,true);//draw text
    rect=CRect(10,70,40,30);
    canvas.DrawRect(rect,1,"0000ff",true,"00ff00");//draw rect
    rect=CRect(10,110,30,30);
    canvas.DrawRoundedRect(rect,1,"0000ff",true,"00ffff",5,5);//draw rounded rect
    rect=CRect(10,150,40,40);
    canvas.DrawOval(rect,1,"0000ff",true,"ffff00");//draw oval

    //download the image and draw it
    save_path=_fun("curdir")+"silk.png";
    native=CNative();
    native.GrantPermission(save_path);//We may need to grant permission manually for the Mac sandbox limit.
    url="http://www.silklang.org/silk.png";
    request=CHttpRequest();
    response=request.HttpGet(url,null,save_path,null);
    if(response.find("status")==200)
    {
        image=canvas.OpenImage(save_path);
        rect=CRect(60,60,100,100);
        canvas.DrawImage(image,rect);
        image.Close();
    }

    //In the end, we need to call Refresh to refresh the canvas.
    canvas.Refresh();
}
func button2_click(handle,param)
{
    canvas=param;
    
    rect=CRect(20,20,210,210);
    canvas.SetRect(rect);
    canvas.SetBackColor("e9967a");
    canvas.Clear();
    canvas.Refresh();
}
func button3_click(handle,param)
{
    rect=CRect(20,20,100,100);
    canvas=param;
    box=CMessageBox();
    path=box.ShowSaveDialog("Please choose the path to save the canvas");
    if(path)
        canvas.SaveToImage(path[0],rect);
}
main()
{
    win=CWindow();
    win.LiveOutput(true);
    win.CreateWindow("Test",400,350);
    rect=CRect(10,10,200,200);
    canvas=win.CreateCanvas(rect,"#bbada0");

    win.AddButton("draw",null,button_click,canvas);
    win.AddButton("clear",null,button2_click,canvas);
    win.AddButton("save",null,button3_click,canvas);

    win.MainLoop();
}


CPoint
CPoint为构建二维坐标系(坐标系原点为左下角,右边为x轴正方向,上边为y轴正方向。)上一个点的类,包含x,y成员变量,分别代表x轴和y轴上的坐标,包含如下成员函数:

CPoint(x,y)
CPoint函数 用来构造坐标系上的一个点。参数x为x坐标,y为y坐标。具体用法见下列例子。

CRect
CRect为构建二维坐标系(坐标系原点为左下角,右边为x轴正方向,上边为y轴正方向。)上一个矩形,包含x,y,w,h成员变量,分别代表x轴和y轴上的坐标,以及x轴上的宽度和轴上的高度。包含如下成员函数:

CRect(x,y,w,h)
CRect函数 用来构造坐标系上的一个矩形。参数x为矩形左下角x坐标,y为矩形左下角y坐标,w为矩形x轴方向宽度,h为矩形y轴方向高度。具体用法见下列例子。
#include "gui.si"

main()
{
    win=CWindow();
    win.CreateWindow("Test",400,300);
    rect=CRect(10,10,200,200);
    canvas=win.CreateCanvas(rect,"#bbada0");
    
    rect=CRect(10,10,120,120);
    canvas.DrawRect(rect);
    printf("draw a rectangle(x:%d, y:%d, width:%d, height:%d)\n",rect.x,rect.y,rect.w,rect.h);
    point1=CPoint(20,20);
    point2=CPoint(100,100);
    canvas.DrawLine(point1,point2,2,"green");
    printf("draw a line from point1(%d,%d) to point2(%d,%d)\n",point1.x,point1.y,point2.x,point2.y);
    
    win.MainLoop();
}

CHttpRequest
CHttpRequest为一个实现了HTTP客户端的类,帮助用户通过HTTP协议连接Web服务器。包含如下成员函数:

HttpGet(url,callback=null,filepath=null,header=null)
HttpGet 函数 用来通过GET方式连接Web服务器获取数据。参数url为服务器的网址,callback为获取数据完成后的回调函数,如果callback不为 null,则采用异步方式连接,为null则为同步方式;filepath为保存数据的文件的路径,如果filepath不为null,则获取的数据将会 保存到文件,为null则会返回数据,注意:目前CHttpRequest类只能处理UTF8编码的数据,如果获取的数据不是UTF8编码,请设置 filepath让数据保存到文件,然后读取文件再处理;header为HTTP的头信息,如果需要定制HTTP头,则可以设置此参数。返回的数据是字典类型,包含服务器返回的status,body,header,error等数据。
具体用法见下列例子。

HttpPost(url,body,callback=null,filepath=null,header=null)
HttpPost 函数 用来通过POST方式连接Web服务器发送和获取数据。参数url为服务器的网址;body为需要通过POST方式发送的数据;callback为获取数据完成后的回调函数,如果callback不为 null,则采用异步方式连接,为null则为同步方式;filepath为保存数据的文件的路径,如果filepath不为null,则获取的数据将会 保存到文件,为null则会返回数据,注意:目前CHttpRequest类只能处理UTF8编码的数据,如果获取的数据不是UTF8编码,请设置 filepath让数据保存到文件,然后读取文件再处理;header为HTTP的头信息,如果需要定制HTTP头,则可以设置此参数。返回的数据是字典类型,包含服务器返回的status,body,header,error等数据。
具体用法见下列例子。
#include "gui.si"
#include "file.si"

//异步获取数据成功后的回调函数
func async_get_ok(response)
{
    //print(response);
    error=response.find("error");
    if(error)
    {
        print(error);
        return;
    }
    if(response.find("status")==200)
    {
        html=response["body"];
        print(html);
    }
}
//异步从服务器获取数据
func async_get_data()
{
    header = {"content-type":"application/x-www-form-urlencoded",
             "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36",
             "Connection":"keep-alive",
             "Cache-Control":"max-age=0",
             "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
             "Accept-Encoding":"gzip, deflate",
             "Accept-Language":"zh-CN,zh;q=0.9",
             "Upgrade-Insecure-Requests":"1"
             };
    url="https://www.baidu.com";
                 
    request=CHttpRequest();
    request.HttpGet(url,async_get_ok,null,header);//执行后不等数据到来直接返回,数据获取成功后会调用async_get_ok
}
//同步从服务器获取数据
func sync_get_data()
{
    header = {"content-type":"application/x-www-form-urlencoded",
             "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36",
             "Connection":"keep-alive",
             "Cache-Control":"max-age=0",
             "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
             "Accept-Encoding":"gzip, deflate",
             "Accept-Language":"zh-CN,zh;q=0.9",
             "Upgrade-Insecure-Requests":"1"
             };
    url="https://www.baidu.com";
                 
    request=CHttpRequest();
    response=request.HttpGet(url,null,null,header);//执行后一直等待,直到获取数据后返回
    if(response.find("status")==200)
    {
        html=response["body"];
        print(html);
    }
    
}
//同步POST数据到服务器
func sync_post_data()
{
    url="https://getman.cn/echo";//POST测试服务器
    data="TEST POST DATA";
         
    request=CHttpRequest();
    response=request.HttpPost(url,data);//执行后一直等待,直到获取数据后返回
    if(response.find("status")==200)
    {
        html=response["body"];
        print(html);
    }
    
}
func download_file()
{
    //由于Mac的Sandbox限制,我们可能需要手动确认保存的路径
    save_path=_fun("curdir")+"test.html";
    native=CNative();
    native.GrantPermission(save_path);
    
    //同步下载文件到选择的路径
    url="http://silklang.org/download.html";
    request=CHttpRequest();
    response=request.HttpGet(url,null,save_path,null);
    if(response.find("status")==200)
    {
        //打开文件
        file=CFile();
        if(file.Open(save_path,"rb"))
        {
            data=file.ReadAll();
            print(data);
            file.Close();
        }
   }

}
func button1_click(handle,param)
{
    sync_get_data();
}
func button2_click(handle,param)
{
    async_get_data();
}
func button3_click(handle,param)
{
    sync_post_data();
}
func button4_click(handle,param)
{
    download_file();
}
main()
{
    win=CWindow();
    win.LiveOutput(true);
    win.CreateWindow("Test",400,300);

    win.AddButton("同步获取数据",null,button1_click);
    win.AddButton("异步获取数据",null,button2_click);
    win.AddButton("POST数据",null,button3_click);
    win.AddButton("下载文件",null,button4_click);

    win.MainLoop();
}



CAudioPlay
CAudioPlay为播放音频的类,音频可以是mp3,wav文件等。包含如下成员函数:

PlayFile(file)
PlayFile 函数 用来直接播放音频文件。参数file为音频文件的路径。PlayFile播放的文件无法通过Stop停止,直到播放完成。具体用法见下列例子。

Open(file,callback)
Open 函数 用来打开需要播放的音频文件。参数file为音频文件的路径,callback为文件播放完成后的回调函数。具体用法见下列例子。

Play()

Play 函数 用来播放被Open函数打开的音频文件。具体用法见下列例子。

Pause()
Pause 函数 用来暂停播放的音频文件,暂停后可以再次通过Play函数播放。具体用法见下列例子。

Stop()
Stop 函数 用来停止播放的音频文件。具体用法见下列例子。
#include "gui.si"
#include "file.si"

func play_end()
{
    print("play end");
}
func button_click(button,param)
{
    box=CMessageBox();
    filelist=box.ShowFileDialog("Please select an audio file to play");
    if(filelist.size()<=0)
        return;
    
    audio=CAudioPlay();
    filePath=filelist[0];
    audio.PlayFile(filePath);
}

func open_click(button,param)
{
    box=CMessageBox();
    filelist=box.ShowFileDialog("Please select an audio file to play");
    if(filelist.size()<=0)
        return;

    audio=param;
    filePath=filelist[0];
    audio.Open(filePath,play_end);
}
func play_click(button,param)
{
    audio=param;
    audio.Play();
}
func pause_click(button,param)
{
    audio=param;
    audio.Pause();
}
func stop_click(button,param)
{
    audio=param;
    audio.Stop();
}
main()
{
    win=CWindow();
    win.LiveOutput(true);
    win.CreateWindow("Test",400,300);

    audio=CAudioPlay();
    btn=win.AddButton("playfile",null,button_click);
    btn=win.AddButton("open",null,open_click,audio);
    btn=win.AddButton("play",null,play_click,audio);
    btn=win.AddButton("pause",null,pause_click,audio);
    btn=win.AddButton("stop",null,stop_click,audio);

    win.MainLoop();
}