GUI Library

The Silk on Mac App Store has a built-in GUI libray which helps user develop graphical interface programs on MacOS, you just need to include 'gui.si' file in your program, gui.si contains the following classes:

CNative
CNative is the base class for all GUI classes, which contains the following member functions:

GrantPermission(path)
GrantPermission is used to obtain the read and write permissions for a certain directory. Due to the SandBox mechanism of the Mac App Store, apps downloaded on the App Store have no read and write permissions for other directories except their own directories by default. The GrantPermission function will pop up a directory selection dialog box for the user to obtain permission, and will save the permission. The next time when it is called, the permission will be granted directly. The parameter path is the path of the directory for which permission needs to be obtained.
#include "gui.si"
main()
{
    native=CNative();
    native.GrantPermission(_fun("curdir"));
}

ClearOutput()
ClearOutput is used to clear the Output window on Silk IDE.
#include "gui.si"
main()
{
    print("output test");
    native=CNative();
    native.ClearOutput();
}

GetInputkey()
GetInputkey is used to get the user's keyboard input from the Input window on Silk IDE.
#include "gui.si"
main()
{
    print("Please input your name:");
    native=CNative();
    name=native.GetInputkey();
    print(name);
}

LiveOutput(enable)
LiveOutput will control whether the program outputs the printed information which is generated by functions (print, printf) in the IDE Output window in real time. In some cases (such as thread running), for the running speed of the program, the IDE will not output the printed information in real time by default, and will output all the printed information after the program runs. The parameter enable can be passed with 'true' or 'false', and 'true' means real time output.
#include "gui.si"
main()
{
    native=CNative();
    native.LiveOutput(true);
}

CWindow
CWindow is used to create MacOS window, which contains the following member functions:

CreateWindow(title,width,height)
CreateWindow is used to create a Mac window. The parameter title is the title of the window, width is the width of the window, and height is the height of the window.
#include "gui.si"
main()
{
    win=CWindow();
    w=400;
    h=300;
    win.CreateWindow("My Mac Window",w,h);
    win.MainLoop();
}

Close()
Close is used to close the window.

Show(enable)
Show is used to show or hide the window. The parameter enable is to show/hide the window when it is 'true'/'false'.

SetTitle(title)
SetTitle is used to set the title of the window. The parameter title is the title text.
#include "gui.si"
main()
{
    win=CWindow();
    w=400;
    h=300;
    win.CreateWindow("My first window",w,h);
    win.SetTitle("my title");
    win.MainLoop();
}

GetRect()
GetRect obtains the position and size of the window. The returned value is a CRect object. The CRect object contains the coordinates (x, y) of the object and the width and height (w, h) of the object.
#include "gui.si"
main()
{
    win=CWindow();
    w=400;
    h=300;
    win.CreateWindow("My first window",w,h);
    rect=win.GetRect();
    print(rect.x,rect.y,rect.w,rect.h);
}

SetRect(rect)
SetRect is used to set the position and size of the window. The parameter rect is a CRect object.
#include "gui.si"
main()
{
    win=CWindow();
    w=400;
    h=300;
    win.CreateWindow("My first window",w,h);
    rect=CRect(100,100,500,600);
    win.SetRect(rect);
    win.MainLoop(false);
}

SetStyle(resizable,closable=true,miniaturizable=true)
SetStyle is used to set the window style. The parameter resizable indicates that the window has a maximize button and can be resized if it is 'true', closable indicates that the window has a close button if it is 'true', and miniaturizable indicates that the window has a minimize button if it is 'true'.
Both closable and miniaturizable have a default value of 'true', which can be omitted.
#include "gui.si"
main()
{
    win=CWindow();
    w=400;
    h=300;
    win.CreateWindow("My first window",w,h);
    win.SetStyle(true);
    win.MainLoop();
}

 AddComboBox(rect=null,callback=null,param=null)
AddComboBox is used to add a drop-down list box on the window. The parameter rect is the position and size of the list box, callback is the callback function after the list box changes selection, and param is any parameter that can be passed in for the callback function to use.
The callback function contains 4 parameters, which are the handle of the list box, the index of the current selection, the text of the current selection, and the passed parameter param. The specific usage is shown in the following example.
All parameters have a default value of null. If you use the default value without passing a parameter, Silk will automatically set the position and size of the list box, generally in the center of the window, with a width of 200 and a height of 25.
Successful execution of AddComboBox will return the added list box object CComboBox.
#include "gui.si"
func comboSelected(handle,index,text,param)
{
    print(index,text,param);
}
main()
{
    win=CWindow();
    w=400;
    h=300;
    win.CreateWindow("My window",w,h);
    param=win;
    combo=win.AddComboBox(null,comboSelected,param);
    combo.AddString("test1");
    win.MainLoop();
}

AddPopupButton(rect=null,callback=null,param=null)
AddPopupButton is used to add a list button on the window, the parameter rect is the position and size of the list button, callback is the callback function after the list button changes selection, and param is any parameter that can be passed in for the callback function to use.
All parameters have a default value of null. If you use the default value without passing the parameter, Silk will automatically set the position and size of the list button, generally in the center of the window, with a width of 200 and a height of 25.
Successful execution of AddPopupButton will return the added list button object 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 is used to add a text display box on the window, and the text display box supports multiple lines. The parameter rect is the position and size of the text display box, and text is the initial text of the text display box.
Successful execution of AddTextView will return the added text display box object CTextView.
#include "gui.si"

func save_click(handle,param)
{
}
main()
{
    win=CWindow();
    w=500;
    h=400;
    win.CreateWindow("Person information",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)
The AddTableView function is used to add a table box on the window. The table supports multiple rows and multiple columns. The parameter rect is the position and size of the table box, and selectionChanged is the callback function after changing the table row selection.
doubleClicked is the callback function after double-clicking the table row selection, and param is any parameter, which can be passed in for the callback function to use.
All parameters have a default value of null. If you use the default value without passing the parameter, Silk will automatically set the position and size of the table box.
Successful execution of AddTableView will return the added table frame object 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("Person information",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","name");
    table.AddColumn("Age","age");
    table.AddColumn("Telephone","phone");
    for(i=0;i<res.size();i++)
        table.AddData(res[i]);
    table.Refresh();
    
    win.MainLoop();
}


AddButton(title,rect=null,callback=null,param=null)
The AddButton function is used to add button on the window. The parameter title is the button text, rect is the position and size of the button, callback is the callback function after the button is pressed, and param is any parameter that can be passed in for the callback function to use.
The parameter rect has a default value of null. If you use the default value without passing in the parameter, Silk will automatically set the position and size of the button.
Successful execution of AddButton will return the added button object CButton.
Please see the following example for the specific usage.

AddLabel(title,rect=null)
The AddLabel function is used to add a text label to the window. The parameter rect is the position and size of the text label, and title is the text of the text label.
Successful execution of AddLabel will return the added text label object CTextField.
Please see the following example for the specific usage.

AddTextField(title="",rect=null)
The AddTextField function is used to add a text input box on the window. The parameter rect is the position and size of the input box, and title is the initial text of the input box.
Successful execution of AddTextField will return the added text input box object CTextField.
Please see the following example for the specific usage.

AddSecureTextField(title="",rect=null)
The AddSecureTextField function is used to add a password input box on the window. The parameter rect is the position and size of the input box, and title is the initial text of the input box.
Successful execution of AddSecureTextField will return the added password input box object CSecureTextField.
Please see the following example for the specific usage.
#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("Tips","Login successfully!");
    }
}
main()
{
    win=CWindow();
    win.CreateWindow("Login",300,200);

    label=win.AddLabel("UserID:");
    user_field=win.AddTextField("test");
    rect=user_field.GetRect();
    rect.h=20;
    rect.y=rect.y-rect.h-5;
    win.AddLabel("Password:",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("Submit",rect,login_click,param);
    
    win.MainLoop();
}


CreateCanvas(rect,backcolor=null)
The CreateCanvas function is used to create a canvas on the window, and various graphics and images can be drawn on the canvas. The parameter rect is the position and size of the canvas, and backcolor is the background color of the canvas.
Successful execution of CreateCanvas will return the created canvas object 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)
The BindEvent function is used to bind various keyboard, mouse and window events. The parameter event is the name of the event, callback is the callback function of the event, and param is any parameter, which can be used by the callback function.
Currently the supported events are EventLeftMouseDown, EventLeftMouseUp, EventRightMouseDown, EventRightMouseUp, EventLeftMouseDragged, EventMouseMoved, EventKeyDown, EventKeyUp and EventWindowWillResize.
#include "gui.si"

func winResize(handle,size,param)
{
    print(size);
}
func LeftMouseDown(data,param)
{
    x=data["x"];//x value of the clicked point
    y=data["y"];//y value of the clicked point
    win=param;//the passed parameter
    print(x,y,win);
}
func KeyDown(key,param)
{
    print("the pressed key code is ",key);//print the pressed key code
}
main()
{
    win=CWindow();
    win.LiveOutput(true);
    win.CreateWindow("Test",400,300);
    win.SetStyle(1);
    win.BindEvent("EventLeftMouseDown",LeftMouseDown,win);//bind the mouse click event
    win.BindEvent("EventKeyDown",KeyDown);//bind the keyboard event
    win.BindEvent("EventWindowWillResize",winResize,win);//bind the window size change event
    
    win.MainLoop();
}


CreateTimer(interval,callback)
The CreateTimer function is used to create a timer and perform various tasks regularly. The parameter interval is how many seconds to execute the timer, and callback is the callback function when the timer is executed.
#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);//run the timer every 1 second
    _timer2=win.CreateTimer(0.5,HandleTimer);//run the timer every 0.5 second
    
    win.MainLoop();
}


MainLoop(center=true)
The MainLoop function is used to display the window and enter the message loop to receive various window messages. It will not break the loop and termination the program until the exit message is received. The parameter center is to set the window to be displayed in the center of the screen.


CMessageBox
The CMessageBox class is used to display message boxes, file selection dialogs, file saving dialogs, input boxes and color selection boxes, and contains the following member functions:

ShowMessage(title,message,button1="OK",button2=null,button3=null)
ShowMessage is used to display the message box, the parameter title is the title of the message box, message is the message text, button1 is the first button, usually it's the confirmation button, and the default text is OK.
button2 is the second button, usually it's the cancel button, button3 is the third button, and generally three buttons box is for question message. Button2 and button3 have the default value of null, which can be omitted.
#include "gui.si"

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

ShowInputBox(title,button1,button2=null)
ShowInputBox is used to display the input box, the parameter title is the title of the input box, button1 is the first button, usually it's the confirm button, and button2 is the second button, usually it's the cancel button.
The return value is the string entered by the user.
#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 is used to display the file selection box, the parameter title is the title of the selection box, multisel is whether multiple files can be selected or not, the default value is false; dir is whether the directory can be selected or not, the default value is false; createdir is whether the directory can be created or not, the default value is false.
The return value of the function is an array containing the path of the selected files.
#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 is used to display the file save box, the parameter title is the title of the save box, defaultdir is the default saving path, the default value is null; createdir is whether the directory can be created or not, the default value is false.
The return value of the function is an array containing the path of the selected files, nomally only one path is in the array.
#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 is used to display the color selection box, the parameter colorChanged is the callback function after the selected color is changed, param is any parameter passed in the callback function, the default value is null; color is the default color.
Note: The callback function colorChanged must be used in the message loop of the window, so you need to call the MainLoop function to enter the message loop and use it.
#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
The CComboBox class is a drop-down list box class which contains the following member functions:

GetCurSel()
The GetCurSel function is used to obtain the index of the selected item in the list box. The index starts from 0. If there is no selected item, the returned index is -1.
Please see the following example for specific usage.

SetCurSel(index)
The SetCurSel function is used to set the selected item in the list box, and the parameter index is the index of the item to be selected.
Please see the following example for specific usage.

AddString(string)
The AddString function is used to add items to the list box, and the parameter string is the added item, which is a string type text.
Please see the following example for specific usage.

InsertString(string,index)
The InsertString function is used to insert a new item before an item in the list box, the parameter string is the inserted item, and index is the index of an item.
Please see the following example for specific usage.

Remove(index)
The Remove function is used to delete an item in the list box, and the parameter index is the index of the deleted item.
Please see the following example for specific usage.

SetEditable(enable)
The SetEditable function is used to set whether the list box can be edited. It can be edited if the parameter enable is set to true.
Please see the following example for specific usage.

Clear()
The Clear function is used to delete all the items in the list box. Please see the following example for specific usage.

GetString()
The GetString function is used to get the current item text in the list box. Please see the following example for specific usage.

SetString(string)
The SetString function is used to set the current text in the list box, and the parameter string is the text to be set.  
Please see the following example for specific usage.

GetStringAtIndex(index)
The GetStringAtIndex function is used to get the text of an item in the list box, and the parameter index is the index of the item.
Please see the following example for specific usage.
#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("My window",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 is a table box class, which contains the following member functions:

GetData(row)
The GetData function is used to obtain a row of data in the table box, and the parameter row is the row number, starting from 0.
Please see the following example for specific usage.

GetCurSel()
The GetCurSel function is used to obtain the row number of the selected row in the table box.
Please see the following example for specific usage.

SetData(row,data)
The SetData function is used to set the data for one row in the table box, the parameter row is the row number, and data is the row data, which is a dictionary type object.
Please see the following example for specific usage.

Delete(row)
The Delete function is used to delete a row item in the table box, and the parameter row is the row number.
Please see the following example for specific usage.

Clear()
The Clear function is used to delete all the items in the table box.
Please see the following example for specific usage.

AddData(data)
The AddData function is used to add a new row in the table box, and the parameter data is the data of the row item.
Please see the following example for specific usage.

Refresh()
The Refresh function is used to refresh the data on the interface. After adding, deleting or modifying data to the table, the Refresh function must be called, otherwise the interface will not be updated.
Please see the following example for specific usage.

AddColumn(title,identifier=null,width=null)
The AddColumn function is used to add columns to the table box. Generally it is called after the table box is created. The parameter title is the column name, identifier is the unique identifier of the column, and width is the column width.
Please see the following example for specific usage.
#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("Person information",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","name");
    table.AddColumn("Age","age");
    table.AddColumn("Telephone","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("Add",rect,add_click,param);
    rect=CRect(10+w2+5,h-40,w2,h2);
    button=win.AddButton("Edit",rect,edit_click,param);
    rect=CRect(10+(w2+5)*2,h-40,w2,h2);
    button=win.AddButton("Delete",rect,delete_click,param);
   
    win.MainLoop();
}


CButton
CButton is a button class, which contains the following member functions:

SetCheckBox(enable,status=0)
The SetCheckBox function is used to set the button to the Checkbox type. If the parameter enable is true, it is a Checkbox type button, and if the status is 1, the checkbox status is checked.
Please see the following example for specific usage.

SetRadio(enable,status=0)
The SetRadio function is used to set the button to the Radio type, If the parameter enable is true, it is a Radio type button, and if the status is 1, the radio is selected.
Please see the following example for specific usage.

GetStatus()
The GetStatus function is used to get the button status. If it is a Checkbox or Radio button, it returns 1 if it is checked or selected, otherwise it returns 0.
Please see the following example for specific usage.

SetStatus(status)
The SetStatus function is used to set the status of the Checkbox or Radio button. If the parameter status is 1, it is set to be checked or selected.
Please see the following example for specific usage.

SetTitle(title)
The SetTitle function is used to set the button title, and the parameter title is the title text.

GetRect()
The GetRect function is used to obtain the coordinates and length and width of the button on the window. The return value is a CRect object.

SetRect(rect)
The SetRect function is used to set the coordinates and length and width of the button on the window.
The parameter rect is an CRect object which contains the position coordinate and length and width of the button.

RoundedStyle(enable)
The RoundedStyle function is used to set the button to the rounded corner style, and the parameter enable is true for the rounded corner button.
#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 is a button list box, which contains the following member functions:

AddItem(item)
The AddItem function is used to add the item into the button list box. The parameter item is the item string which will be added.


CTextField, CSecureTextField, CTextView
CTextField is a text box class, CSecureTextField is a password box class, and CTextView is a text view class (supports multiple lines).
Their usage is similar, and they include the following member functions:

GetText()
The GetText function is used to get the content of the box. See the following example for specific usage.

SetText(text)
The SetText function is used to set the content of the box, and the parameter text is the text to be set. See the following example for specific usage.

GetRect()
The GetRect function is used to obtain the coordinates and length and width of the box on the window.

SetRect(rect)
The SetRect function is used to set the coordinates and length and width of the box on the window.
The parameter rect is the position coordinate and length and width of the box.

SetEditable(enable)
The SetEditable function is used to set whether the box can be edited, and if the parameter enable is set to true, the box can be edited.
#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 is a timer class, which contains the following member variable and member functions:

handle
The handle variable is used to obtain the timer handle for comparison with the handle in the timer callback function.
See the following example for specific usage.

Pause()
The Pause function is used to pause the timer. See the following examples for specific usage.

Start()
The Start function is used to start the timer. When the timer is paused by the Pause function, it can be restarted by calling Start.
See the following example for specific usage.

Stop()
The Stop function is used to stop the timer, it means the timer is closed. See the following example for specific usage.
#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 is a canvas class, which contains the following member functions:

DrawLine(point1,point2,width=1.0,color="00ff00")
The DrawLine function is used to draw line segments on the canvas. Parameter point1 is the coordinates of the starting point of the line segment, point2 is the coordinates of the end point; width is the width of the line segment, the default is 1.0; color is the color of the line segment, and the color is a string type. You can pass the hexadecimal string form of the color, common colors (Red, green, blue, yellow, white, black) can be replaced by English words.
See the following example for specific usage.

DrawRect(rect,width=1.0,colorLine="ff0000",fill=true,colorFill="ff0000")
The DrawRect function is used to draw a rectangle on the canvas. The parameter rect is the coordinates and size of the rectangle; width is the width of the line; colorLine is the color of the line; fill is whether to fill the rectangle with color, the default value is true; colorFill is the fill color, and the default color is red.
See the following example for specific usage.

DrawRoundedRect(rect,width=1.0,colorLine="ff0000",fill=true,colorFill="ff0000",xRadius=30.0,yRadius=30.0)
The DrawRoundedRect function is used to draw a rounded rectangle on the canvas. The parameter rect is the coordinates and size of the rectangle; width is the width of the line; colorLine is the color of the line; fill is whether to fill the rectangle with color, the default value is true; colorFill is the fill color, the default value is red;  xRadius is the radius of the rounded corner in the x-axis direction, yRadius is the radius of the rounded corner in the y-axis direction, the default is 30, these 2 parameters are used to adjust the radius of the rounded corner.
See the following example for specific usage.

DrawOval(rect,width=1.0,colorLine="ff0000",fill=true,colorFill="ff0000")
The DrawOval function is used to draw an ellipse or circle on the canvas (a circle when the outer rectangle is a square). The parameter rect is the coordinates and size of the outer rectangle of the ellipse; width is the width of the line; colorLine is the color of the line; fill is whether to fill the rectangle with color, the default value is true; colorFill is the fill color, and the default value is red.
See the following example for specific usage.

DrawText(text,point,color="ff0000",size=12,center=false,font="Helvetica")
The DrawText function is used to draw text on the canvas. The parameter text is a text string; point is the coordinate of the bottom left corner of the outer rectangle of the text; color is the text color; size is the font size of the text, the default value is 12; center indicates whether the text is displayed in the center, and the default value is false; font is the font name of the text , the default font is Helvetica.
See the following example for specific usage.

OpenImage(filename)
The OpenImage function is used to open an image file and returns an image object which is CImage type. CImage has only one member function Close(). If the object is no longer used, it can be closed by Close function. The parameter filename is the path of the image file.
See the following example for specific usage.

DrawImage(image,rect,operation=1,fraction=1.0,scale=1)
The DrawImage function is used to draw an image on the canvas. The parameter image is the image object opened by the OpenImage function; rect is the position and size of the image displayed on the canvas; operation is whether to display the image transparently, the default value 1 means transparent; fraction is the image transparency, the default value is 1.0; scale is to determine if the picture can be zoomed in(out) or not. The default value is 1, it means the picture will be displayed according to the size of the rect. If it is 0, the picture will be displayed in its original size, and the size of the rect will be ignored.
See the following example for specific usage.

SaveToImage(filename,rect=null)
The SaveToImage function is used to save the canvas to an image file. The parameter filename is the path of the image file; rect specifies the coordinates and size of a certain part of the canvas to be saved, and the default value is null, which means the whole canvas will be saved.
See the following example for specific usage.

Clear()
The Clear function is used to clear the content drawn on the canvas, and finally you need to call Refresh function to update the canvas.
See the following example for specific usage.

Refresh()
The Refresh function is used to refresh the canvas, and any operations on the canvas (DrawLine, DrawRect, DrawImage, etc.) need to call the Refresh function to render.
See the following example for specific usage.

GetRect()
The GetRect function is used to obtain the coordinates and size of the canvas on the window.

SetRect(rect)
The SetRect function is used to set the coordinates and size of the canvas on the window. The parameter rect is the position coordinate and size of the canvas.
See the following example for specific usage.

 SetBackColor(color)
The SetBackColor function is used to set the background color of the canvas. The parameter color is the color value.
See the following example for specific usage.
#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 class is the point construction on a two-dimensional coordinate system (the origin of the coordinate system is the bottom left corner, the right side is the positive direction of the x-axis, and the upper side is the positive direction of the y-axis.), it has 2 member variables  x and  y which represent the x-axis and y-axis coordinates respectively.
CPoint contains the following member functions:

CPoint(x,y)
The CPoint function is used to construct a point on the coordinate system. The parameter x is the x coordinate, and y is the y coordinate.
See the following example for specific usage.

CRect
CRect is the rectangle construction on a two-dimensional coordinate system (the origin of the coordinate system is the bottom left corner, the right side is the positive direction of the x-axis, and the upper side is the positive direction of the y-axis.). The rectangle contains the x, y, w, and h member variables, which represent the x-axis and the y-axis coordinates, as well as the width and height of the rectangle.
CRect contains the following member functions:

CRect(x,y,w,h)
The CRect function is used to construct a rectangle on the coordinate system. The parameter x is the x coordinate of the bottom left corner of the rectangle, y is the y coordinate of the bottom left corner of the rectangle, w is the width of the rectangle in the x-axis direction, and h is the height of the rectangle in the y-axis direction.
See the following example for specific usage.
#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 is an HTTP client class which can helps users connect to the Web server through the HTTP protocol.
It contains the following member functions:

HttpGet(url,callback=null,filepath=null,header=null)
The HttpGet function is used to connect to the Web server to obtain data through GET method. The parameter url is the URL of the server, and callback is the callback function after the data is obtained. If the callback is not null, the connection will be asynchronous, if it is null, it will be synchronous; filepath is the path of the file where the data is saved, if filepath is not null, the data will be saved to the file. Note: At present, the CHttpRequest class can only process UTF8 encoded data. If the data from the server is not UTF8 encoded, please set the filepath to save the data to file, and then read the data from the file; header is the HTTP header information, if you need to customize the HTTP header, you can set this parameter. The returned data is a dictionary type, which contains the status, body, header, error and other data returned by the server.
See the following example for specific usage.

HttpPost(url,body,callback=null,filepath=null,header=null)
The HttpPost function is used to connect to the Web server through POST method to send and retrieve data. The parameter url is the URL of the server; body is the data that needs to be sent by POST method; callback is the callback function after the data is obtained. If the callback is not null, the connection is asynchronous, if it is null, it is the synchronous method; filepath is the path of the file where the data is saved, if filepath is not null, the data will be saved to the file. Note: At present, the CHttpRequest class can only process UTF8 encoded data. If the data from the server is not UTF8 encoded, please set the filepath to save the data to file, and then read the data from the file; header is the HTTP header information, if you need to customize the HTTP header, you can set this parameter. The returned data is a dictionary type, which contains the status, body, header, error and other data returned by the server.
See the following example for specific usage.
#include "gui.si"
#include "file.si"

//the callback function after the data is obtained
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);
    }
}
//Get data from the server asynchronously
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);//return directly without waiting for the response, and async_get_ok will get the response 
}
//Get data from the server synchronously 
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);//wait until we get the response
    if(response.find("status")==200)
    {
        html=response["body"];
        print(html);
    }
    
}
//Post data to the server synchronously
func sync_post_data()
{
    url="https://getman.cn/echo";//POST testing server
    data="TEST POST DATA";
         
    request=CHttpRequest();
    response=request.HttpPost(url,data);//wait until we get the response
    if(response.find("status")==200)
    {
        html=response["body"];
        print(html);
    }
    
}
func download_file()
{
    //Due to the Mac’s Sandbox limitation, we may need to confirm the save path manually
    save_path=_fun("curdir")+"test.html";
    native=CNative();
    native.GrantPermission(save_path);
    
    //download the file to the saved path synchronously
    url="http://silklang.org/download.html";
    request=CHttpRequest();
    response=request.HttpGet(url,null,save_path,null);
    if(response.find("status")==200)
    {
        //open the downloaded file
        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("sync get",null,button1_click);
    win.AddButton("async get",null,button2_click);
    win.AddButton("Post data",null,button3_click);
    win.AddButton("download file",null,button4_click);

    win.MainLoop();
}



CAudioPlay
CAudioPlay is a class for playing audio, which can be mp3, wav files, etc.  it contains the following member functions:

PlayFile(file)
The PlayFile function is used to play audio file directly. The parameter file is the path of the audio file. The file played by PlayFile cannot be stopped by Stop function.
See the following example for specific usage.

Open(file,callback)
The Open function is used to open the audio file to be played. The parameter file is the path of the audio file, and callback is the callback function after the file is played.
See the following example for specific usage.

Play()

The Play function is used to play the audio file opened by the Open function. See the following example for specific usage.

Pause()
The Pause function is used to pause the playing audio file. After pausing, it can be played again by calling the Play function. See the following example for specific usage.

Stop()
The Stop function is used to stop the playing audio file. See the following example for specific usage.
#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();
}