astilectron
架构
+-----------------------+    TCP    +-------------+    IPC   +---------------------+
+ Client App (any Lang) |<--------->+ Astilectron +<-------->+ win1: (HTML/JS/CSS) +
+-----------------------+           +-------------+     |    +---------------------++
             |                             |            +---->+ win2: (HTML/JS/CSS) +
             |         +----------+        |               |  +---------------------++
             +---------+ Electron +--------+               +-->+ win3: (HTML/JS/CSS) +
                       +----------+                            +---------------------+
astilectron

我想为一种新的语言开发语言绑定

大!:)

以下是您需要了解的几件事情:

astilectronastilectronelectronastilectronastilectron /main.js 

GO的语言绑定

astilectron


go-astilectron
go-astilectrongo-astilectron

警告:以下代码无法处理可读性的错误。但你应该!

go-astilectron
go-astilectron
$ go get -u github.com/asticode/go-astilectron
go-astilectron
//初始化astilectron 
var  a, _ = astilectron。新的(astilectron。选项 {
     AppName: “ <您的应用程序名称> ”,
     AppIconDefaultPath: “ <您的.png图标> ”,
     AppIconDarwinPath:   “ <your .icns图标> ”,
     BaseDirectoryPath: “ <您希望供应商安装依赖关系> “,
})
推迟一个 关闭()

//开始astilectron 
a。开始()
.Start()
go-astilectron.SetProvisioner(p Provisioner)

当您尝试添加自己的应用程序图标时,请注意,您需要2个图标:一个与MacOSX(.icns)兼容的图标,另一个与其他图标兼容(例如.png)。

如果没有提供BaseDirectoryPath,它将默认为可执行文件的目录路径。

go-astilectron.Start()app.event.readyastilectron

创建一个窗口

//创建一个新窗口
var  w, _ = a。NewWindow( “ http://127.0.0.1:4000 ”,与astilectron。 WindowOptions {
    中心:astilectron PtrBool(真),
    身高:astilectron PtrInt( 600),
    宽度:astilectron PtrInt( 600)
})
W上。创建()

创建窗口时,您需要指定一个URL以及位置,大小等选项。

astilectron.Ptr*

添加听众

//在Astilectron上添加一个监听器 
a。在(astilectron。 EventNameAppCrash, FUNC(E astilectron。事件)(deleteListener布尔){
    astilog。错误(“ App已崩溃”)
     返回
})

//在窗口 
w上添加一个监听器。在(astilectron。 EventNameWindowEventResize, FUNC(E astilectron。事件)(deleteListener布尔){
    astilog。Info(“ Window resized ”)
     return 
})

除了你可以添加听众到Astilectron以外,没有什么可说的。

玩窗户

//玩窗户 
w。调整大小( 200, 200)
时间。睡觉(时间第二)
W上。最大化()

查看窗口文档以获取所有已导出方法的列表

在GO和您的网络服务器之间发送消息

在您的网络服务器中,将以下JavaScript添加到您要与之进行交互的任何页面:

< script >
    //这将等待astilectron命名空间准备好
文档。的addEventListener( “ astilectron就绪”,函数(){ //这将听取GO发送的消息astilectron。听(函数(消息){ //这将消息发送回走astilectron。发送( “我很好bro “)        });    })    
    
        
        
                            
            
            


< / script >

在您的GO应用中添加以下内容:

//听Web服务器 
w发送的消息。上(astilectron。 EventNameWindowEventMessage, FUNC(E astilectron。事件)(deleteListener布尔){
     VAR  米 串 
    即消息。解组(M)
    astilog。Infof(“ Received message %s ”,m)
     return
})

//发送消息到webserver 
w。发送( “什么事了”)

就是这样!

注意:不用说,消息可以是字符串以外的东西。一个自定义结构体例如!

处理几个屏幕/显示

//如果有几个显示,将窗口移动到第二个显示器
var  displays = a。显示()
如果 len(显示)> 1 {
    时间。睡觉(时间第二)
    W上。MoveInDisplay(显示[ 1 ],50,50)
}

菜单

//初始化一个新的应用程序菜单
//您可以使用窗口
var  m = a执行相同的操作。NewMenu([] * astilectron。 MenuItemOptions {
    {
        标签:astilectron。PtrStr(“ Separator ”),
        子菜单:[] * astilectron。MenuItemOptions {
            {标签:astilectron。PtrStr(“ Normal 1 ”)},
            {
                标签:astilectron。PtrStr(“ Normal 2 ”),
                的OnClick:FUNC(即astilectron 事件)(deleteListener 布尔){
                    astilog。信息(“正常2项已被点击”)
                     返回
                },
            },
            {类型:astilectron。MenuItemTypeSeparator },
            {标签:astilectron。PtrStr(“ Normal 3 ”)},
        },
    },
    {
        标签:astilectron。PtrStr(“复选框”),
        子菜单:[] * astilectron。MenuItemOptions {
            {检查:astilectron。PtrBool(true),标签:astilectron。PtrStr(“复选框1 ”),类型:astilectron。MenuItemTypeCheckbox },
            {标签:astilectron。PtrStr(“复选框2 ”),类型:astilectron。MenuItemTypeCheckbox },
            {标签:astilectron。PtrStr(“复选框3 ”),类型:astilectron。MenuItemTypeCheckbox },
        },
    },
    {
        标签:astilectron。PtrStr(“ Radio ”),
        子菜单:[] * astilectron。MenuItemOptions {
            {检查:astilectron。PtrBool(true),标签:astilectron。PtrStr(“ Radio 1 ”),类型:astilectron。MenuItemTypeRadio },
            {标签:astilectron。PtrStr(“ Radio 2 ”),类型:astilectron。MenuItemTypeRadio },
            {标签:astilectron。PtrStr(“ Radio 3 ”),类型:astilectron。MenuItemTypeRadio },
        },
    },
    {
        标签:astilectron。PtrStr(“角色”),
        子菜单:[] * astilectron。MenuItemOptions {
            {标签:astilectron。PtrStr(“最小化”),角色:astilectron。MenuItemRoleMinimize },
            {标签:astilectron。PtrStr(“关闭”),角色:astilectron。MenuItemRoleClose },
        },
    },
})

//检索菜单项
//这将检索“复选框1”项目
mi, _  := m。项( 1, 0)

//手动添加监听器
//一个OnClick监听器已经直接添加到另一个菜单项 
mi的选项中。在(astilectron。 EventNameMenuItemEventClicked, FUNC(E astilectron。事件) BOOL {
    astilog。Infof(“菜单项已被点击。‘经过’现在状态%T ”,* E。MenuItemOptions。经过)
     返回 假
})

//创建菜单 
m。创建()

//操纵菜单项 
mi。SetChecked( true)

//初始化一个新菜单项
var  ni = m。的newitem(astilectron。 MenuItemOptions {
    标签:astilectron PtrStr( “插入的”),
    子菜单:[] * astilectron MenuItemOptions {
        {标签:astilectron。PtrStr(“插入1 ”)},
        {标签:astilectron。PtrStr(“插入2 ”)},
    },
})

//将菜单项插入位置“1” 
m。插入( 1,ni)

//获取子菜单
s, _  := m。子菜单( 0)

//初始化一个新的菜单项 
ni = s。的newitem(astilectron。 MenuItemOptions {
    标签:astilectron PtrStr( “追加”),
    子菜单:[] * astilectron MenuItemOptions {
        {标签:astilectron。PtrStr(“附加1 ”)},
        {标签:astilectron。PtrStr(“附加2 ”)},
    },
})

//动态附加菜单项 
。追加(ni)

//弹出子菜单作为上下文菜单 
。弹出(&astilectron。 MenuPopupOptions {PositionOptions:astilectron。 PositionOptions {X:astilectron PtrInt( 50)中,Y:astilectron PtrInt( 50)}})

//关闭弹出 
秒。ClosePopup()

//破坏菜单 
m。毁灭()

要知道的几件事情

go-astilectron

对话框

在您的网络服务器中,添加以下JavaScript之一来实现任何类型的对话。

错误框

< script >
    //这将等待astilectron命名空间准备好
文档。的addEventListener( ' astilectron就绪',函数(){ //这将打开对话框astilectron。 showErrorBox( “我的标题”, “我的内容”)    })    
        
        

< / script >

留言框

< script >
    //这将等待astilectron命名空间准备好
文档。的addEventListener( ' astilectron就绪',函数(){ //这将打开对话框astilectron。 showMessageBox({消息:“我的信息”,标题:“我的标题” })    })    
        
          

< / script >

打开对话框

< script >
    //这将等待astilectron命名空间准备好
文档。的addEventListener( ' astilectron就绪',函数(){ //这将打开对话框astilectron。 showOpenDialog({属性: [ '中openFile ', ' multiSelections ' ],标题:“我的标题” },功能(路径){控制台。日志( “选择路径是”,    
        
         
            


< / script >

保存对话框

< script >
    //这将等待astilectron命名空间准备好
文档。的addEventListener( ' astilectron就绪',函数(){ //这将打开对话框astilectron。 showSaveDialog({标题:“我的标题” },函数(文件名){控制台。日志( “选择文件名”,文件名)        } )    })    
        
         
            


< / script >

最终代码

//设置记录器
var  l <您的记录器类型 >
astilog。SetLogger(l)

//启动http服务器 
http。HandleFunc( “ / ”, FUNC(瓦特HTTP。 ResponseWriter,R * HTTP。请求){
    W上。写([] 字节(` <!DOCTYPE HTML> 
    <HTML LANG = “EN”> 
    <HEAD> 
        <META字符集= “UTF-8”> 
        <标题>世界,你好</ title> 
    </ HEAD> 
    <BODY> 
        < span id =“message”> Hello world </ span> 
        <script> 
            //这将等待astilectron命名空间准备好
            document.addEventListener('astilectron-ready',function(){ 
                //这将
收到发送的消息通过GO                 astilectron.listen(function(message){ 
                    document.getElementById('message'))。
                    innerHTML = message //这将发送一条消息给GO 
                    astilectron.send(“我是好兄弟”)
                }); 
            })
        </ script> 
    </ body> 
    </ html> `))
})
去 http ListenAndServe(“ 127.0.0.1:4000 ”,nil)

//初始化astilectron 
var  a, _ = astilectron。新的(astilectron。选项 {
     AppName: “ <您的应用程序名称> ”,
     AppIconDefaultPath: “ <您的.png图标> ”,
     AppIconDarwinPath:   “ <your .icns图标> ”,
     BaseDirectoryPath: “ <您希望供应商安装依赖关系> “,
})
推迟一个 关闭()

//处理退出 
a。HandleSignals()
一个。在(astilectron。EventNameAppCrash,FUNC(E astilectron。事件)(deleteListener 布尔){
    astilog。错误(“ App已崩溃”)
     返回
})

//启动astilectron:这将下载并设置依赖关系,并启动Electron应用程序 
。开始()

//初始化一个新的应用程序菜单
//您可以使用窗口
var  m = a执行相同的操作。NewMenu([] * astilectron。 MenuItemOptions {
    {
        标签:astilectron。PtrStr(“ Separator ”),
        子菜单:[] * astilectron。MenuItemOptions {
            {标签:astilectron。PtrStr(“ Normal 1 ”)},
            {
                标签:astilectron。PtrStr(“ Normal 2 ”),
                的OnClick:FUNC(即astilectron 事件)(deleteListener 布尔){
                    astilog。信息(“正常2项已被点击”)
                     返回
                },
            },
            {类型:astilectron。MenuItemTypeSeparator },
            {标签:astilectron。PtrStr(“ Normal 3 ”)},
        },
    },
    {
        标签:astilectron。PtrStr(“复选框”),
        子菜单:[] * astilectron。MenuItemOptions {
            {检查:astilectron。PtrBool(true),标签:astilectron。PtrStr(“复选框1 ”),类型:astilectron。MenuItemTypeCheckbox },
            {标签:astilectron。PtrStr(“复选框2 ”),类型:astilectron。MenuItemTypeCheckbox },
            {标签:astilectron。PtrStr(“复选框3 ”),类型:astilectron。MenuItemTypeCheckbox },
        },
    },
    {
        标签:astilectron。PtrStr(“ Radio ”),
        子菜单:[] * astilectron。MenuItemOptions {
            {检查:astilectron。PtrBool(true),标签:astilectron。PtrStr(“ Radio 1 ”),类型:astilectron。MenuItemTypeRadio },
            {标签:astilectron。PtrStr(“ Radio 2 ”),类型:astilectron。MenuItemTypeRadio },
            {标签:astilectron。PtrStr(“ Radio 3 ”),类型:astilectron。MenuItemTypeRadio },
        },
    },
    {
        标签:astilectron。PtrStr(“角色”),
        子菜单:[] * astilectron。MenuItemOptions {
            {标签:astilectron。PtrStr(“最小化”),角色:astilectron。MenuItemRoleMinimize },
            {标签:astilectron。PtrStr(“关闭”),角色:astilectron。MenuItemRoleClose },
        },
    },
})

//检索菜单项
//这将检索“复选框1”项目
mi, _  := m。项( 1, 0)

//手动添加监听器
//一个OnClick监听器已经直接添加到另一个菜单项 
mi的选项中。在(astilectron。 EventNameMenuItemEventClicked, FUNC(E astilectron。事件) BOOL {
    astilog。Infof(“菜单项已被点击。‘经过’现在状态%T ”,* E。MenuItemOptions。经过)
     返回 假
})

//创建菜单 
m。创建()

//在resize 
var  w, _ = a上创建一个带有监听器的新窗口。NewWindow( “ http://127.0.0.1:4000 ”,与astilectron。 WindowOptions {
    中心:astilectron PtrBool(真),
    身高:astilectron PtrInt( 600),
    图标:astilectron PtrStr(<你的图标路径>),
    宽度:astilectron PtrInt( 600),
})
W上。在(astilectron。EventNameWindowEventResize,FUNC(E astilectron。事件)(deleteListener 布尔){
    astilog。信息(“窗口大小调整”)
     返回
})
W上。上(astilectron。EventNameWindowEventMessage,FUNC(E astilectron。事件)(deleteListener 布尔){
     VAR  米 串 
    即消息。解组(M)
    astilog。Infof(“ Received message %s ”,m)
     return
})
W上。创建()

//玩窗户 
w。调整大小( 200, 200)
时间。睡觉(时间第二)
W上。最大化()

//如果有几个显示,将窗口移动到第二个显示器
var  displays = a。显示()
如果 len(显示)> 1 {
    时间。睡觉(时间第二)
    W上。MoveInDisplay(显示[ 1 ],50,50)
}

//发送消息到服务器的 
时间。睡觉(时间第二)
W上。发送(“什么事了”)

//操纵菜单项 
时间。睡觉(时间第二)
MI。SetChecked(true)

//初始化一个新菜单项
var  ni = m。的newitem(astilectron。 MenuItemOptions {
    标签:astilectron PtrStr( “插入的”),
    子菜单:[] * astilectron MenuItemOptions {
        {标签:astilectron。PtrStr(“插入1 ”)},
        {标签:astilectron。PtrStr(“插入2 ”)},
    },
})

//将菜单项插入位置“1” 
。睡觉(时间第二)
米 插入(1,ni)

//获取子菜单
s, _  := m。子菜单( 0)

//初始化一个新的菜单项 
ni = s。的newitem(astilectron。 MenuItemOptions {
    标签:astilectron PtrStr( “追加”),
    子菜单:[] * astilectron MenuItemOptions {
        {标签:astilectron。PtrStr(“附加1 ”)},
        {标签:astilectron。PtrStr(“附加2 ”)},
    },
})

//动态追加菜单项 
时间。睡觉(时间第二)
秒。追加(ni)

//弹出子菜单作为上下文菜单 
时间。睡觉(时间第二)
秒。弹出(&astilectron。MenuPopupOptions {PositionOptions:astilectron。PositionOptions {X:astilectron PtrInt(50)中,Y:astilectron PtrInt(50)}})

//关闭弹出 
时间。睡觉(时间第二)
秒。ClosePopup()

//销毁菜单 
时间 睡觉(时间第二)
米 毁灭()

//阻止模式 
a。等()

为了方便起见,我添加了一个引导程序来帮助第一个定时器,并避免代码重复。

注意:您不必使用引导,完全取决于您是否使用它。

引导允许您快速创建单窗口应用程序。

使用静态文件和远程信息(最好的方式)

为了使用引导与静态文件和远程消息传递,您必须:

  |--+ resources
      |
      |--+ app (contains your static files such as .html, .css, .js, .png, etc.)
  |--+ main.go

使用Web服务器

为了使用带有Web服务器的引导程序,您必须:

  |--+ resources
        |
        |--+ static (contains your static files such as .css, .js, .png, etc.)
        |
        |--+ templates (contains your templates .html files)
  |--+ main.go

共同

  //go:generate go-bindata -pkg $GOPACKAGE -o resources.go resources/...
  $ go generate main.go

检查出的例子进行了详细的工作实施例(见实施例下面的特定命令来运行部分)。

为了使事情更加清晰,我试图在不同的例子中分割特征。

要运行任何示例,请运行以下命令:

$ go run examples/<name of the example>/main.go -v

以下是示例的列表:

$ go generate examples/5.single_binary_distribution/main.go
$ go run examples/5.single_binary_distribution/main.go examples/5.single_binary_distribution/vendor.go -v
$ go generate examples/8.bootstrap/main.go
$ go run examples/8.bootstrap/main.go examples/8.bootstrap/resources.go -v