├── .appveyor.yml ├── .gitignore ├── .travis.yml ├── README.md ├── callbacks.c ├── examples ├── callback │ ├── callback.go │ └── index.html ├── demoes │ ├── 01 │ │ ├── demo1.go │ │ └── demo1.html │ ├── 02 │ │ ├── demo2.go │ │ └── demo2.html │ ├── 03 │ │ └── demo3.go │ ├── 04 │ │ ├── demo4.go │ │ └── demo4.html │ ├── 05 │ │ ├── demo5.go │ │ └── demo5.html │ ├── 06 │ │ ├── demo6.go │ │ └── demo6.html │ ├── 07 │ │ ├── demo7.go │ │ ├── demo7.html │ │ └── demo8.html │ ├── 08 │ │ ├── demo9.go │ │ ├── demo9.html │ │ └── simple.html │ └── 09 │ │ ├── Contents │ │ └── MacOS │ │ │ └── .gitkeep │ │ ├── build.sh │ │ └── main.go ├── download │ └── download.go ├── fixed │ ├── fixed.html │ └── fixedWindow.go ├── handlers │ ├── a.html │ ├── handlers.go │ └── res │ │ └── decorators.tis ├── insert │ └── insert.go ├── request │ ├── index.html │ ├── lighthouse.jpg │ └── main.go ├── restest │ ├── res │ │ └── simple.html │ └── restest.go ├── restest2 │ ├── res.go │ ├── res │ │ └── simple.html │ └── restest.go ├── simple │ ├── simple.go │ └── simple.html ├── sview │ └── sview.go └── textHtml │ └── textHtml.go ├── generate.go ├── include ├── sciter-om-def.h ├── sciter-om.h ├── sciter-x-api.h ├── sciter-x-behavior.h ├── sciter-x-debug.h ├── sciter-x-def.h ├── sciter-x-dom.h ├── sciter-x-graphics.h ├── sciter-x-lite-keycodes.h ├── sciter-x-msg.h ├── sciter-x-request.h ├── sciter-x-script.h ├── sciter-x-threads.h ├── sciter-x-types.h ├── sciter-x-value.h ├── sciter-x-video-api.h ├── sciter-x.h ├── tiscript.h └── value.h ├── request.c ├── request.go ├── rice └── rice.go ├── sciter-x-api.c ├── sciter.go ├── sciter_darwin.go ├── sciter_linux.go ├── sciter_windows.go ├── types.go ├── types_string.go ├── utils.go ├── value.go ├── window ├── window.go ├── window_darwin.go ├── window_linux.go └── window_windows.go └── wrapper.go /.appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 0.4.0.{build} 2 | 3 | branches: 4 | only: 5 | - master 6 | - travis 7 | 8 | image: 9 | - Visual Studio 2015 10 | 11 | environment: 12 | matrix: 13 | - TARGET: Go 1.12.0 14 | ARCH: 64 15 | ARCHGO: 16 | VERGO: 112 17 | MGWVER: x86_64-7.2.0-posix-seh-rt_v5-rev1 18 | 19 | - TARGET: Go 1.12.0 20 | ARCH: 32 21 | ARCHGO: -x86 22 | VERGO: 112 23 | MGWVER: i686-6.3.0-posix-dwarf-rt_v5-rev1 24 | 25 | - TARGET: Go 1.13.0 26 | ARCH: 64 27 | ARCHGO: 28 | VERGO: 113 29 | MGWVER: x86_64-7.2.0-posix-seh-rt_v5-rev1 30 | 31 | - TARGET: Go 1.13.0 32 | ARCH: 32 33 | ARCHGO: -x86 34 | VERGO: 113 35 | MGWVER: i686-6.3.0-posix-dwarf-rt_v5-rev1 36 | 37 | - TARGET: Go 1.14.0 38 | ARCH: 64 39 | ARCHGO: 40 | VERGO: 113 41 | MGWVER: x86_64-7.2.0-posix-seh-rt_v5-rev1 42 | 43 | - TARGET: Go 1.14.0 44 | ARCH: 32 45 | ARCHGO: -x86 46 | VERGO: 113 47 | MGWVER: i686-6.3.0-posix-dwarf-rt_v5-rev1 48 | 49 | - TARGET: Go 1.15.0 50 | ARCH: 64 51 | ARCHGO: 52 | VERGO: 113 53 | MGWVER: x86_64-7.2.0-posix-seh-rt_v5-rev1 54 | 55 | - TARGET: Go 1.15.0 56 | ARCH: 32 57 | ARCHGO: -x86 58 | VERGO: 113 59 | MGWVER: i686-6.3.0-posix-dwarf-rt_v5-rev1 60 | 61 | install: 62 | - cmd: echo Testing sciter%ARCH% with %TARGET%. 63 | - cmd: echo Current directory is %APPVEYOR_BUILD_FOLDER% 64 | - cmd: set PATH=C:\projects\deps;C:\go%VERGO%%ARCHGO%\bin;C:\mingw-w64\%MGWVER%\mingw%ARCH%\bin;%PATH% 65 | 66 | - gcc --version 67 | - go version 68 | 69 | - mkdir C:\projects\deps 70 | - curl -so "C:\projects\deps\sciter.dll" "https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.win/x%ARCH%/sciter.dll" 71 | 72 | before_build: 73 | - cmd: set GOROOT=C:\go%VERGO%%ARCHGO% 74 | - cmd: set GOPATH=C:\projects\gopath 75 | - cmd: set PATH=%GOPATH%\bin;%PATH% 76 | - cmd: mkdir %GOPATH% 77 | - go env 78 | - go get -u github.com/lxn/win 79 | - go get -u github.com/GeertJohan/go.rice 80 | - go get -u github.com/GeertJohan/go.rice/rice 81 | - go get -u github.com/kardianos/osext 82 | 83 | 84 | build_script: 85 | - cmd: echo Building library 86 | - cmd: cd 87 | - go build -x 88 | 89 | - go get github.com/sciter-sdk/go-sciter 90 | 91 | - cmd: echo Building examples 92 | - cmd: cd examples 93 | - cmd: go build ./... 94 | 95 | test: off 96 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | 30 | # sciter sdk 31 | sciter-sdk*/ 32 | 33 | # editor config 34 | .vscode/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Based on the "trust" template v0.1.2 2 | # https://github.com/japaric/trust/tree/v0.1.2 3 | 4 | dist: trusty 5 | sudo: false 6 | language: go 7 | 8 | notifications: 9 | email: change 10 | 11 | os: 12 | - linux 13 | - osx 14 | 15 | # "1.9" go-sciter is incompatible with 1.9 16 | # The latest 1.9 version was 9646a0a383. 17 | 18 | go: 19 | - "1.12" 20 | - "1.13" 21 | - "1.14" 22 | - "1.15" 23 | 24 | 25 | branches: 26 | only: 27 | - master 28 | - travis 29 | 30 | addons: 31 | apt: 32 | sources: 33 | - ubuntu-toolchain-r-test 34 | 35 | packages: 36 | - libgtk-3-dev 37 | - libgtk-3-0 38 | - libstdc++-6-pic 39 | 40 | cache: 41 | directories: 42 | - $GOPATH/src 43 | - $GOPATH/pkg 44 | 45 | before_cache: 46 | - rm -rf $GOPATH/src/github.com/sciter-sdk/go-sciter/* 47 | - rm -rf $GOPATH/pkg/**/github.com/sciter-sdk/go-sciter 48 | 49 | install: 50 | - export SDK_PATH=https://raw.githubusercontent.com/c-smile/sciter-sdk/master 51 | - if [ "$TRAVIS_OS_NAME" = "linux" ]; then curl -so "$TRAVIS_BUILD_DIR/libsciter-gtk.so" $SDK_PATH/bin.lnx/x64/libsciter-gtk.so; fi 52 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then curl -so "$TRAVIS_BUILD_DIR/libsciter.dylib" $SDK_PATH/bin.osx/libsciter.dylib; fi 53 | 54 | # - go get golang.org/x/lint/golint 55 | 56 | - go get -u github.com/GeertJohan/go.rice 57 | - go get -u github.com/GeertJohan/go.rice/rice 58 | 59 | before_script: 60 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then export DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:$TRAVIS_BUILD_DIR"; fi 61 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then cp "$TRAVIS_BUILD_DIR/libsciter.dylib" "$TRAVIS_BUILD_DIR/liblibsciter.dylib"; fi 62 | 63 | - if [ "$TRAVIS_OS_NAME" = "linux" ]; then export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$TRAVIS_BUILD_DIR"; fi 64 | 65 | - export PATH="$PATH:$TRAVIS_BUILD_DIR" 66 | - export LIBRARY_PATH="$LIBRARY_PATH:$TRAVIS_BUILD_DIR" 67 | 68 | - gcc --version 69 | - go version 70 | - go env 71 | - echo $PWD 72 | 73 | 74 | script: 75 | - go build 76 | 77 | - if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd examples; fi 78 | - if [ "$TRAVIS_OS_NAME" = "linux" ]; then go build ./...; fi 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Go bindings for Sciter 2 | 3 | [![AppVeyor status](https://ci.appveyor.com/api/projects/status/rphv883klffw9em9/branch/master?svg=true)](https://ci.appveyor.com/project/pravic/go-sciter) 4 | [![Travis Status](https://travis-ci.com/sciter-sdk/go-sciter.svg?branch=master)](https://travis-ci.com/sciter-sdk/go-sciter) 5 | [![License](https://img.shields.io/github/license/sciter-sdk/go-sciter.svg)](https://github.com/sciter-sdk/go-sciter) 6 | [![Join the forums at https://sciter.com/forums](https://img.shields.io/badge/forum-sciter.com-orange.svg)](https://sciter.com/forums) 7 | 8 | Check [this page](http://sciter.com/developers/sciter-sdk-bindings/) for other language bindings (Delphi / D / Go / .NET / Python / Rust). 9 | 10 | ---- 11 | 12 | 13 | # Attention 14 | 15 | The ownership of project is transferred to this new organization. 16 | Thus the `import path` for golang should now be `github.com/sciter-sdk/go-sciter`, but the package name is still `sciter`. 17 | 18 | # Introduction 19 | 20 | This package provides a Golang bindings of [Sciter][] using cgo. 21 | Using go sciter you must have the platform specified `sciter dynamic library` 22 | downloaded from [sciter-sdk][], the library itself is rather small 23 | (under 5MB, less than 2MB when upxed) . 24 | 25 | Most [Sciter][] API are supported, including: 26 | 27 | * Html string/file loading 28 | * DOM manipulation/callback/event handling 29 | * DOM state/attribute handling 30 | * Custom resource loading 31 | * Sciter Behavior 32 | * Sciter Options 33 | * Sciter Value support 34 | * NativeFunctor (used in sciter scripting) 35 | 36 | And the API are organized in more or less a gopher friendly way. 37 | 38 | Things that are not supported: 39 | 40 | * Sciter Node API 41 | * TIScript Engine API 42 | 43 | # Getting Started 44 | 45 | ### At the moment only **Go 1.10** or higher is supported (issue #136). 46 | 47 | 1. Download the [sciter-sdk][] 48 | 2. Extract the sciter runtime library from [sciter-sdk][] to system PATH 49 | 50 | The runtime libraries lives in `bin` `bin.lnx` `bin.osx` with suffix like `dll` `so` or `dylib` 51 | 52 | * Windows: simply copying `bin\64\sciter.dll` to `c:\windows\system32` is just enough 53 | * Linux: 54 | - `cd sciter-sdk/bin.lnx/x64` 55 | - `export LIBRARY_PATH=$PWD` 56 | - `echo $PWD >> libsciter.conf` 57 | - `sudo cp libsciter.conf /etc/ld.so.conf.d/` 58 | - `sudo ldconfig` 59 | - `ldconfig -p | grep sciter` should print libsciter-gtk.so location 60 | * OSX: 61 | - `cd sciter-sdk/bin.osx/` 62 | - `export DYLD_LIBRARY_PATH=$PWD` 63 | 64 | 3. Set up GCC envrionmnet for CGO 65 | 66 | [mingw64-gcc][] (5.2.0 and 7.2.0 are tested) is recommended for Windows users. 67 | 68 | Under Linux gcc(4.8 or above) and gtk+-3.0 are needed. 69 | 70 | 4. `go get -x github.com/sciter-sdk/go-sciter` 71 | 72 | 5. Run the example and enjoy :) 73 | 74 | # Sciter Desktop UI Examples 75 | 76 | ![](http://sciter.com/screenshots/slide-wt5.png) 77 | 78 | ![](http://sciter.com/screenshots/slide-norton360.png) 79 | 80 | ![](http://sciter.com/screenshots/slide-norton-nis.png) 81 | 82 | ![](http://sciter.com/screenshots/slide-cardio.png) 83 | 84 | ![](http://sciter.com/screenshots/slide-surveillance.png) 85 | 86 | ![](http://sciter.com/screenshots/slide-technology.png) 87 | 88 | ![](http://sciter.com/screenshots/slide-sciter-ide.png) 89 | 90 | ![](http://sciter.com/screenshots/slide-sciter-osx.png) 91 | 92 | ![](http://sciter.com/screenshots/slide-sciter-gtk.png) 93 | 94 | 95 | # Sciter Version Support 96 | Currently supports [Sciter][] version `4.0.0.0` and higher. 97 | 98 | [Sciter]: http://sciter.com/ 99 | [sciter-sdk]: http://sciter.com/download/ 100 | 101 | # About Sciter 102 | 103 | [Sciter][] is an `Embeddable HTML/CSS/script engine for modern UI development, Web designers, and developers, can reuse their experience and expertise in creating modern looking desktop applications.` 104 | 105 | In my opinion, [Sciter][] , though not open sourced, is an great 106 | desktop UI development envrionment using the full stack of web technologies, 107 | which is rather small (under 5MB) especially compared to [CEF][],[Node Webkit][nw] and [Atom Electron][electron]. :) 108 | 109 | Finally, according to [Andrew Fedoniouk][author] the author and the Sciter 110 | `END USER LICENSE AGREEMENT` , the binary form of the [Sciter][] 111 | dynamic libraries are totally free to use for commercial or 112 | non-commercial applications. 113 | 114 | # The Tailored Sciter C Headers 115 | This binding ueses a tailored version of the sciter C Headers, which lives in directory: `include`. The included c headers are a modified version of the 116 | [sciter-sdk][] standard headers. 117 | 118 | It seems [Sciter][] is developed using C++, and the included headers in the 119 | [Sciter SDK][sciter-sdk] are a mixture of C and C++, which is not 120 | quite suitable for an easy golang binding. 121 | 122 | I'm not much fond of C++ since I started to use Golang, so I made this 123 | modification and hope [Andrew Fedoniouk][author] the author would provide 124 | pure C header files for Sciter. :) 125 | 126 | [CEF]:https://bitbucket.org/chromiumembedded/cef 127 | [nw]: https://github.com/nwjs/nw.js 128 | [electron]:https://github.com/atom/electron 129 | 130 | [author]: http://sciter.com/about/ 131 | [mingw64-gcc]: http://sourceforge.net/projects/mingw-w64/ 132 | -------------------------------------------------------------------------------- /callbacks.c: -------------------------------------------------------------------------------- 1 | #include "sciter-x.h" 2 | #include "_cgo_export.h" 3 | 4 | // typedef SBOOL SC_CALLBACK SciterElementCallback(HELEMENT he, LPVOID param); 5 | 6 | SBOOL SC_CALLBACK SciterElementCallback_cgo(HELEMENT he, LPVOID param) 7 | { 8 | return goSciterElementCallback(he, param); 9 | } 10 | 11 | // typedef VOID SC_CALLBACK LPCBYTE_RECEIVER(LPCBYTE bytes, UINT num_bytes, LPVOID param); 12 | VOID SC_CALLBACK LPCBYTE_RECEIVER_cgo(LPCBYTE bytes, UINT num_bytes, LPVOID param) 13 | { 14 | goLPCBYTE_RECEIVER((BYTE*)bytes, num_bytes, param); 15 | } 16 | 17 | // typedef VOID SC_CALLBACK LPCWSTR_RECEIVER(LPCWSTR str, UINT str_length, LPVOID param); 18 | VOID SC_CALLBACK LPCWSTR_RECEIVER_cgo(LPCWSTR str, UINT str_length, LPVOID param) 19 | { 20 | goLPCWSTR_RECEIVER((WCHAR*)str, str_length, param); 21 | } 22 | 23 | // typedef VOID SC_CALLBACK LPCSTR_RECEIVER(LPCSTR str, UINT str_length, LPVOID param); 24 | VOID SC_CALLBACK LPCSTR_RECEIVER_cgo(LPCSTR str, UINT str_length, LPVOID param) 25 | { 26 | goLPCSTR_RECEIVER(str, str_length, param); 27 | } 28 | 29 | // typedef SBOOL SC_CALLBACK ElementEventProc(LPVOID tag, HELEMENT he, UINT evtg, LPVOID prms); 30 | SBOOL SC_CALLBACK ElementEventProc_cgo(LPVOID tag, HELEMENT he, UINT evtg, LPVOID prms) 31 | { 32 | return goElementEventProc(tag, he, evtg, prms); 33 | } 34 | 35 | // typedef UINT SC_CALLBACK SciterHostCallback(LPSCITER_CALLBACK_NOTIFICATION pns, LPVOID callbackParam); 36 | UINT SC_CALLBACK SciterHostCallback_cgo(LPSCITER_CALLBACK_NOTIFICATION pns, LPVOID callbackParam) 37 | { 38 | return goSciterHostCallback(pns, callbackParam); 39 | } 40 | 41 | // typedef VOID NATIVE_FUNCTOR_INVOKE(VOID* tag, UINT argc, const VALUE* argv, VALUE* retval); // retval may contain error definition 42 | VOID NATIVE_FUNCTOR_INVOKE_cgo(VOID* tag, UINT argc, const VALUE* argv, VALUE* retval) 43 | { 44 | goNATIVE_FUNCTOR_INVOKE(tag, argc, (VALUE*)argv, retval); 45 | } 46 | 47 | // typedef VOID NATIVE_FUNCTOR_RELEASE(VOID* tag); 48 | VOID NATIVE_FUNCTOR_RELEASE_cgo(VOID* tag) 49 | { 50 | goNATIVE_FUNCTOR_RELEASE(tag); 51 | } 52 | 53 | // typedef INT SC_CALLBACK ELEMENT_COMPARATOR(HELEMENT he1, HELEMENT he2, LPVOID param); 54 | 55 | INT SC_CALLBACK ELEMENT_COMPARATOR_cgo(HELEMENT he1, HELEMENT he2, LPVOID param) 56 | { 57 | return goELEMENT_COMPARATOR(he1, he2, param); 58 | } 59 | 60 | // typedef SBOOL SC_CALLBACK KeyValueCallback(LPVOID param, const VALUE* pkey, const VALUE* pval); 61 | 62 | SBOOL SC_CALLBACK KeyValueCallback_cgo(LPVOID param, const VALUE* pkey, const VALUE* pval) 63 | { 64 | return goKeyValueCallback(param, (VALUE*)pkey, (VALUE*)pval); 65 | } -------------------------------------------------------------------------------- /examples/callback/callback.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "path/filepath" 6 | 7 | "github.com/sciter-sdk/go-sciter" 8 | "github.com/sciter-sdk/go-sciter/window" 9 | ) 10 | 11 | func main() { 12 | w, err := window.New(sciter.SW_TITLEBAR|sciter.SW_RESIZEABLE|sciter.SW_CONTROLS|sciter.SW_MAIN|sciter.SW_ENABLE_DEBUG, nil) 13 | if err != nil { 14 | log.Fatal("Create Window Error: ", err) 15 | } 16 | fullpath, err := filepath.Abs("index.html") 17 | if err != nil { 18 | log.Fatal(err) 19 | } 20 | w.LoadFile(fullpath) 21 | setEventHandler(w) 22 | w.Show() 23 | w.Run() 24 | } 25 | 26 | func setEventHandler(w *window.Window) { 27 | w.DefineFunction("getNetInformation", func(args ...*sciter.Value) *sciter.Value { 28 | log.Println("Args Length:", len(args)) 29 | log.Println("Arg 0:", args[0], args[0].IsInt()) 30 | log.Println("Arg 1:", args[1], args[1].IsString()) 31 | log.Println("Arg 2: IsFunction", args[2], args[2].IsFunction()) 32 | log.Println("Arg 2: IsObjectFunction", args[2], args[2].IsObjectFunction()) 33 | log.Println("args[3].IsMap():", args[3].IsMap(), args[3].Length()) 34 | log.Println("args[3].IsObject():", args[3].IsObject(), args[3].Length(), args[3].Get("str")) 35 | args[3].EnumerateKeyValue(func(key, val *sciter.Value) bool { 36 | log.Println(key, val) 37 | return true 38 | }) 39 | fn := args[2] 40 | fn.Invoke(sciter.NullValue(), "[Native Script]", sciter.NewValue("OK")) 41 | ret := sciter.NewValue() 42 | ret.Set("ip", sciter.NewValue("127.0.0.1")) 43 | return ret 44 | }) 45 | } 46 | -------------------------------------------------------------------------------- /examples/callback/index.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 14 | -------------------------------------------------------------------------------- /examples/demoes/01/demo1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "path/filepath" 6 | 7 | "github.com/sciter-sdk/go-sciter" 8 | "github.com/sciter-sdk/go-sciter/window" 9 | ) 10 | 11 | func main() { 12 | //create windows;创建window窗口 13 | //parm 1: style of window;参数一表示创建窗口的样式 14 | //SW_TITLEBAR :with titlebar;顶层窗口,有标题栏 15 | //SW_RESIZEABLE : resizeable; 可调整大小 16 | //SW_CONTROLS :has max, min button;有最小/最大按钮 17 | //SW_MAIN : main window, if it close, application will exit; 应用程序主窗口,关闭后其他所有窗口也会关闭 18 | //SW_ENABLE_DEBUG : debug;可以调试 19 | //parm 2: the rect of window;参数二表示创建窗口的矩形 20 | w, err := window.New(sciter.SW_TITLEBAR| 21 | sciter.SW_RESIZEABLE| 22 | sciter.SW_CONTROLS| 23 | sciter.SW_MAIN| 24 | sciter.SW_ENABLE_DEBUG, 25 | nil) 26 | if err != nil { 27 | log.Fatal(err) 28 | } 29 | //load file;加载文件 30 | fullpath, err := filepath.Abs("demo1.html") 31 | if err != nil { 32 | log.Fatal(err) 33 | } 34 | w.LoadFile(fullpath) 35 | //set title; 设置标题 36 | w.SetTitle("Hello, world") 37 | //show;显示窗口 38 | w.Show() 39 | //run, loop message;运行窗口,进入消息循环 40 | w.Run() 41 | } 42 | -------------------------------------------------------------------------------- /examples/demoes/01/demo1.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | Hello,world 8 | 9 | -------------------------------------------------------------------------------- /examples/demoes/02/demo2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "path/filepath" 6 | 7 | "github.com/sciter-sdk/go-sciter" 8 | "github.com/sciter-sdk/go-sciter/window" 9 | ) 10 | 11 | func main() { 12 | //创建window窗口 13 | //参数一表示创建窗口的样式 14 | //SW_TITLEBAR 顶层窗口,有标题栏 15 | //SW_RESIZEABLE 可调整大小 16 | //SW_CONTROLS 有最小/最大按钮 17 | //SW_MAIN 应用程序主窗口,关闭后其他所有窗口也会关闭 18 | //SW_ENABLE_DEBUG 可以调试 19 | //参数二表示创建窗口的矩形 20 | w, err := window.New(sciter.SW_TITLEBAR| 21 | sciter.SW_RESIZEABLE| 22 | sciter.SW_CONTROLS| 23 | sciter.SW_MAIN| 24 | sciter.SW_ENABLE_DEBUG, 25 | //给窗口设置个大小 26 | &sciter.Rect{Left: 0, Top: 0, Right: 500, Bottom: 500}) 27 | if err != nil { 28 | log.Fatal(err) 29 | } 30 | //加载文件 31 | fp, err := filepath.Abs("demo2.html") 32 | if err != nil { 33 | log.Fatal(err) 34 | } 35 | w.LoadFile(fp) 36 | //设置标题 37 | w.SetTitle("表单") 38 | //显示窗口 39 | w.Show() 40 | //运行窗口,进入消息循环 41 | w.Run() 42 | } 43 | -------------------------------------------------------------------------------- /examples/demoes/02/demo2.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 表单 6 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 39 | 40 | 41 | 42 | 47 | 48 | 49 | 50 | 53 | 54 | 55 | 56 | 57 | 58 |
用户:
密码:
性别: 36 | 男 37 | 女 38 |
爱好: 43 | 看书 44 | 打球 45 | 旅游 46 |
简介: 51 | 52 |
59 |
60 | 61 | -------------------------------------------------------------------------------- /examples/demoes/03/demo3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | 7 | "github.com/sciter-sdk/go-sciter" 8 | "github.com/sciter-sdk/go-sciter/window" 9 | ) 10 | 11 | //一些基础操作 12 | func base(root *sciter.Element) { 13 | //通过ID选择元素 14 | ul, _ := root.SelectById("list") 15 | //获取元素的文本 16 | text, _ := ul.Text() 17 | fmt.Println("text:", text) 18 | //获取元素的html 19 | //参数为真,则返回元素外部html 20 | //参数为假,则返回元素内部html 21 | text, _ = ul.Html(false) 22 | fmt.Println("html:", text) 23 | //获取子元素个数 24 | n, _ := ul.ChildrenCount() 25 | fmt.Println(n) 26 | } 27 | 28 | //动态的添加元素 29 | func addElement(root *sciter.Element) { 30 | //创建一个元素 31 | add, _ := sciter.CreateElement("li", "444") 32 | //设置元素的属性 33 | add.SetAttr("data", "add") 34 | 35 | //通过标签和ID来选择元素,类似jquery 36 | ul, _ := root.SelectFirst("ul#list") 37 | //插入元素,下标从0开始 38 | err := ul.Insert(add, 3) 39 | if err != nil { 40 | log.Fatal("添加元素失败") 41 | } 42 | 43 | add2, _ := sciter.CreateElement("li", "") 44 | err2 := ul.Insert(add2, 4) 45 | //注意这里,元素先insert后再去设置html才有效 46 | //设置添加元素的html 47 | add2.SetHtml("555", sciter.SIH_REPLACE_CONTENT) 48 | if err2 != nil { 49 | log.Fatal("添加元素失败") 50 | } 51 | } 52 | 53 | //删除元素 54 | func delElement(root *sciter.Element) { 55 | ul, _ := root.SelectFirst("ul#list") 56 | //获取第一个子元素,下标从0开始 57 | li, _ := ul.NthChild(0) 58 | //删除元素 59 | li.Delete() 60 | 61 | //我们也可以用css选择器直接选择要删除的元素 62 | //注意css里面的nth-child(n)下标从1开始 63 | li2, _ := root.SelectFirst("ul#list>li:nth-child(2)") 64 | //删除元素 65 | li2.Delete() 66 | } 67 | 68 | //修改元素 69 | func updElement(root *sciter.Element) { 70 | li, _ := root.SelectFirst("ul#list>li:nth-child(1)") 71 | //给元素设置样式 72 | li.SetStyle("color", "#f00") 73 | //给元素设置html 74 | //参数一:html内容 75 | //参数二:html放在哪里,SIH_REPLACE_CONTENT表示替换旧内容 76 | li.SetHtml("baidu.com", sciter.SIH_REPLACE_CONTENT) 77 | //在最后面追加内容 78 | li.SetHtml("哈哈", sciter.SIH_APPEND_AFTER_LAST) 79 | //设置元素属性 80 | li.SetAttr("test", "test") 81 | li2, _ := root.SelectFirst("ul#list>li:nth-child(2)") 82 | //设置文本 83 | li2.SetText("我改我改") 84 | } 85 | 86 | //查找元素 87 | func selElement(root *sciter.Element) { 88 | //通过css选择器选择元素,会返回*Element的slice 89 | root.Select("ul#list>li") 90 | //通过选择器返回第一个元素 91 | //也是调用的Select,不过只返回第一个元素 92 | root.SelectFirst("ul#list>li") 93 | //通过元素ID 94 | root.SelectById("list") 95 | //选择父元素 96 | //参数二:表示深度 97 | root.SelectParent("li", 1) 98 | //返回选择器匹配唯一子元素,如果没有或匹配多个,会引发Panic 99 | root.SelectUnique("ul#list>li:nth-child(1)") 100 | } 101 | 102 | func main() { 103 | //创建一个新窗口 104 | //这里参数一和参数二都使用的默认值 105 | //DefaultWindowCreateFlag = SW_TITLEBAR | SW_RESIZEABLE | SW_CONTROLS | SW_MAIN | SW_ENABLE_DEBUG 106 | //DefaultRect = &Rect{0, 0, 300, 400} 107 | w, err := window.New(sciter.DefaultWindowCreateFlag, sciter.DefaultRect) 108 | if err != nil { 109 | log.Fatal(err) 110 | } 111 | //设置标题 112 | w.SetTitle("文本html") 113 | html := ` 114 | 115 | 116 | 121 | 122 | ` 123 | //加载html,从一个字符串变量中 124 | w.LoadHtml(html, "") 125 | //窗口获取根元素,这里应该是html 126 | root, _ := w.GetRootElement() 127 | 128 | //这里把一些操作单独写成函数方便查看 129 | base(root) 130 | addElement(root) 131 | delElement(root) 132 | updElement(root) 133 | selElement(root) 134 | 135 | //显示窗口 136 | w.Show() 137 | //运行窗口,进入消息循环 138 | w.Run() 139 | } 140 | -------------------------------------------------------------------------------- /examples/demoes/04/demo4.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "path/filepath" 7 | 8 | "github.com/sciter-sdk/go-sciter" 9 | "github.com/sciter-sdk/go-sciter/window" 10 | ) 11 | 12 | //设置元素的处理程序 13 | func setElementHandlers(root *sciter.Element) { 14 | btn1, _ := root.SelectById("btn1") 15 | //处理元素简单点击事件 16 | btn1.OnClick(func() { 17 | fmt.Println("btn1被点击了") 18 | }) 19 | 20 | //这里给元素定义的方法是在tiscript中进行调用的 21 | //并且作为元素的属性进行访问 22 | btn1.DefineMethod("test", func(args ...*sciter.Value) *sciter.Value { 23 | //我们把从传入的参数打印出来 24 | for _, arg := range args { 25 | //String()把参数转换成字符串 26 | fmt.Print(arg.String() + " ") 27 | } 28 | 29 | //返回一个空值 30 | return sciter.NullValue() 31 | }) 32 | btn2, _ := root.SelectById("btn2") 33 | //调用在tiscript中定义的方法 34 | data, _ := btn2.CallMethod("test2", sciter.NewValue("1"), sciter.NewValue("2"), sciter.NewValue("3")) 35 | //输出调用方法的返回值 36 | fmt.Println(data.String()) 37 | } 38 | 39 | //设置回调 40 | func setCallbackHandlers(w *window.Window) { 41 | //CallbackHandler是一个结构,里面定义了一些方法 42 | //你可以通过实现这些方法,自定义自已的回调 43 | cb := &sciter.CallbackHandler{ 44 | //加载数据开始 45 | OnLoadData: func(p *sciter.ScnLoadData) int { 46 | //显示加载资源的uri 47 | fmt.Println("加载:", p.Uri()) 48 | return sciter.LOAD_OK 49 | }, 50 | //加载数据过程中 51 | OnDataLoaded: func(p *sciter.ScnDataLoaded) int { 52 | fmt.Println("加载中:", p.Uri()) 53 | return sciter.LOAD_OK 54 | }, 55 | } 56 | w.SetCallback(cb) 57 | } 58 | 59 | //定义函数 60 | func setWinHandler(w *window.Window) { 61 | //定义函数,在tis脚本中需要通过view对象调用 62 | 63 | //定义inc函数,返回参数加1 64 | w.DefineFunction("inc", func(args ...*sciter.Value) *sciter.Value { 65 | return sciter.NewValue(args[0].Int() + 1) 66 | }) 67 | //定义dec函数,返回参数减1 68 | w.DefineFunction("dec", func(args ...*sciter.Value) *sciter.Value { 69 | return sciter.NewValue(args[0].Int() - 1) 70 | }) 71 | } 72 | 73 | //测试调用函数 74 | func testCallFunc(w *window.Window) { 75 | //调用tis脚本中定义的函数 76 | data, _ := w.Call("sum", sciter.NewValue(10), sciter.NewValue(20)) 77 | fmt.Println(data.String()) 78 | root, _ := w.GetRootElement() 79 | //我们也可以指定元素调用函数 80 | data, _ = root.CallFunction("sum", sciter.NewValue(50), sciter.NewValue(100)) 81 | fmt.Println(data.String()) 82 | } 83 | 84 | func main() { 85 | //创建一个新窗口 86 | w, err := window.New(sciter.DefaultWindowCreateFlag, sciter.DefaultRect) 87 | if err != nil { 88 | log.Fatal(err) 89 | } 90 | fullpath, err := filepath.Abs("demo4.html") 91 | if err != nil { 92 | log.Fatal(err) 93 | } 94 | w.LoadFile(fullpath) 95 | //设置标题 96 | w.SetTitle("事件处理") 97 | 98 | //设置回调处理程序 99 | setCallbackHandlers(w) 100 | //获取根元素 101 | root, _ := w.GetRootElement() 102 | //设置元素处理程序 103 | setElementHandlers(root) 104 | //设置窗口处理程序 105 | setWinHandler(w) 106 | //测试调用函数 107 | testCallFunc(w) 108 | 109 | //显示窗口 110 | w.Show() 111 | //运行窗口,进入消息循环 112 | w.Run() 113 | } 114 | -------------------------------------------------------------------------------- /examples/demoes/04/demo4.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 事件处理 6 | 7 | 8 | 9 | 10 | 11 | 12 | 43 | 44 | -------------------------------------------------------------------------------- /examples/demoes/05/demo5.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "path/filepath" 6 | 7 | "github.com/sciter-sdk/go-sciter" 8 | "github.com/sciter-sdk/go-sciter/window" 9 | ) 10 | 11 | func main() { 12 | //创建新窗口 13 | //并设置窗口大小 14 | w, err := window.New(sciter.DefaultWindowCreateFlag, &sciter.Rect{200, 200, 500, 500}) 15 | if err != nil { 16 | log.Fatal(err) 17 | } 18 | //加载文件 19 | fullpath, err := filepath.Abs("demo5.html") 20 | if err != nil { 21 | log.Fatal(err) 22 | } 23 | 24 | w.LoadFile(fullpath) 25 | //设置标题 26 | w.SetTitle("固定大小窗口") 27 | //显示窗口 28 | w.Show() 29 | //运行窗口,进入消息循环 30 | w.Run() 31 | } 32 | -------------------------------------------------------------------------------- /examples/demoes/05/demo5.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 固定大小窗口 6 | 7 | 8 |
固定大小窗口
9 | 15 | 16 | -------------------------------------------------------------------------------- /examples/demoes/06/demo6.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "path/filepath" 7 | 8 | "github.com/sciter-sdk/go-sciter" 9 | "github.com/sciter-sdk/go-sciter/window" 10 | ) 11 | 12 | func load(root *sciter.Element) { 13 | frame, _ := root.SelectById("frame") 14 | //load()类似jquery.load(),用于给元素加载指定内容 15 | //加载html内容 16 | frame.Load("http://www.qq.com", sciter.RT_DATA_HTML) 17 | 18 | // txt, _ := root.SelectById("txt") 19 | // //附加元素事件处理 20 | // txt.AttachEventHandler(&sciter.EventHandler{ 21 | // //OnDataArrived 当资源被加载但未使用时调用 22 | // //返回true,取消资源使用 23 | // //返回false,遵循正常过程 24 | // OnDataArrived: func(he *sciter.Element, params *sciter.DataArrivedParams) bool { 25 | // //设置元素html 26 | // he.SetHtml(string(params.Data()), sciter.SIH_REPLACE_CONTENT) 27 | // return false 28 | // }, 29 | // }) 30 | // //加载本地原始数据 31 | // txt.Load("file:///D:/gopath/src/gui/1.txt", sciter.RT_DATA_RAW) 32 | 33 | img, _ := root.SelectById("img") 34 | img.AttachEventHandler(&sciter.EventHandler{ 35 | //OnDataArrived 当资源被加载但未使用时调用 36 | OnDataArrived: func(he *sciter.Element, params *sciter.DataArrivedParams) bool { 37 | //设置属性,给img标签设置src 38 | he.SetAttr("src", params.Uri()) 39 | return false 40 | }, 41 | }) 42 | img.Load("http://mat1.gtimg.com/www/images/qq2012/qqLogoFilter.png", sciter.RT_DATA_IMAGE) 43 | 44 | script, _ := root.SelectById("script") 45 | script.AttachEventHandler(&sciter.EventHandler{ 46 | //OnDataArrived 当资源被加载但未使用时调用 47 | OnDataArrived: func(he *sciter.Element, params *sciter.DataArrivedParams) bool { 48 | fmt.Println(string(params.Data())) 49 | return false 50 | }, 51 | }) 52 | //加载脚本资源 53 | script.Load("http://apps.bdimg.com/libs/jquery/1.8.3/jquery.min.js", sciter.RT_DATA_SCRIPT) 54 | } 55 | 56 | func main() { 57 | w, err := window.New(sciter.DefaultWindowCreateFlag, sciter.DefaultRect) 58 | if err != nil { 59 | log.Fatal(err) 60 | } 61 | //加载文件 62 | fullpath, err := filepath.Abs("demo6.html") 63 | if err != nil { 64 | log.Fatal(err) 65 | } 66 | 67 | w.LoadFile(fullpath) 68 | //设置标题 69 | w.SetTitle("元素加载内容") 70 | //获取根元素 71 | root, _ := w.GetRootElement() 72 | //元素加载资源 73 | load(root) 74 | w.Show() 75 | w.Run() 76 | } 77 | -------------------------------------------------------------------------------- /examples/demoes/06/demo6.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 元素加载内容 6 | 18 | 19 | 20 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /examples/demoes/07/demo7.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "path/filepath" 7 | 8 | "github.com/sciter-sdk/go-sciter" 9 | "github.com/sciter-sdk/go-sciter/window" 10 | ) 11 | 12 | func defFunc(w *window.Window) { 13 | //注册dump函数方便在tis脚本中打印数据 14 | w.DefineFunction("dump", func(args ...*sciter.Value) *sciter.Value { 15 | for _, v := range args { 16 | fmt.Print(v.String() + " ") 17 | } 18 | fmt.Println() 19 | return sciter.NullValue() 20 | }) 21 | //注册reg函数,用于处理注册逻辑,这里只是简单的把数据打印出来 22 | w.DefineFunction("reg", func(args ...*sciter.Value) *sciter.Value { 23 | for _, v := range args { 24 | fmt.Print(v.String() + " ") 25 | } 26 | fmt.Println() 27 | return sciter.NullValue() 28 | }) 29 | } 30 | 31 | func main() { 32 | w, err := window.New(sciter.DefaultWindowCreateFlag, sciter.DefaultRect) 33 | if err != nil { 34 | log.Fatal(err) 35 | } 36 | fullpath, err := filepath.Abs("demo7.html") 37 | if err != nil { 38 | log.Fatal(err) 39 | } 40 | 41 | w.LoadFile(fullpath) 42 | w.SetTitle("tiscript脚本学习") 43 | defFunc(w) 44 | w.Show() 45 | w.Run() 46 | } 47 | -------------------------------------------------------------------------------- /examples/demoes/07/demo7.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | tiscript脚本学习 6 | 7 | 8 |
9 | 10 | 11 | 12 | 15 | 16 | 17 | 18 | 21 | 22 | 23 | 24 | 29 | 30 | 31 | 32 | 39 | 40 | 41 | 42 | 45 | 46 |
用户名: 13 | 14 |
密码: 19 | 20 |
爱好: 25 | 看书 26 | 打球 27 | 旅游 28 |
性别: 33 | 38 |
简介: 43 | 44 |
47 |
48 | 49 | 104 | 105 | -------------------------------------------------------------------------------- /examples/demoes/07/demo8.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | tiscript脚本学习 6 | 13 | 14 | 15 |
16 | 21 |
22 |
23 | ID:
24 | 姓名:
25 | 性别:男 26 | 女 27 | 28 | 29 |
30 |
31 |
32 |
33 | 34 |
35 | 36 |
37 | 42 |
43 |
44 | 177 | 178 | -------------------------------------------------------------------------------- /examples/demoes/08/demo9.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "log" 7 | "os" 8 | "path/filepath" 9 | "strings" 10 | 11 | "github.com/sciter-sdk/go-sciter" 12 | "github.com/sciter-sdk/go-sciter/window" 13 | ) 14 | 15 | func defFunc(w *window.Window) { 16 | //注册dump函数方便在tis脚本中打印数据 17 | w.DefineFunction("dump", func(args ...*sciter.Value) *sciter.Value { 18 | for _, v := range args { 19 | fmt.Print(v.String() + " ") 20 | } 21 | fmt.Println() 22 | return sciter.NullValue() 23 | }) 24 | //处理文件移动 25 | w.DefineFunction("moveFile", func(args ...*sciter.Value) *sciter.Value { 26 | file := args[0].String() 27 | folder := args[1].String() 28 | 29 | //去掉路径左边的file:// 30 | file = strings.TrimLeft(file, "file://") 31 | //获取文件名 32 | fileName := filepath.Base(file) 33 | //读取文件数据 34 | data, err := ioutil.ReadFile(file) 35 | if err != nil { 36 | return sciter.NewValue(err.Error()) 37 | } 38 | //写入文件数据 39 | err = ioutil.WriteFile(filepath.Join(folder, fileName), data, os.ModePerm) 40 | if err == nil { 41 | //删除原文件 42 | os.Remove(file) 43 | return sciter.NewValue("移动成功") 44 | } else { 45 | return sciter.NewValue("移动失败") 46 | } 47 | }) 48 | } 49 | 50 | func main() { 51 | w, err := window.New(sciter.DefaultWindowCreateFlag, sciter.DefaultRect) 52 | if err != nil { 53 | log.Fatal(err) 54 | } 55 | w.SetOption(sciter.SCITER_SET_SCRIPT_RUNTIME_FEATURES, sciter.ALLOW_SYSINFO|sciter.ALLOW_FILE_IO) 56 | fullpath, err := filepath.Abs("demo9.html") 57 | if err != nil { 58 | log.Fatal(err) 59 | } 60 | 61 | w.LoadFile(fullpath) 62 | w.SetTitle("view对象学习") 63 | defFunc(w) 64 | w.Show() 65 | w.Run() 66 | } 67 | -------------------------------------------------------------------------------- /examples/demoes/08/demo9.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | view对象学习 6 | 13 | 14 | 15 | 16 |
17 | 18 | 19 |
20 | 21 | 22 |
23 | 24 | 25 |
26 |
27 | 28 |
29 | 30 |
31 | 32 |
33 | 34 |
35 | 36 |
37 | 38 |
39 | 40 |
41 | 42 |
43 | 44 |
45 |
46 | 47 |
48 | 49 | 50 | 51 |
52 | 53 |
54 | 55 | 结果: 56 | 57 |
58 | 59 | 240 | 241 | -------------------------------------------------------------------------------- /examples/demoes/08/simple.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 29 | 43 | 44 | 45 |

Mozilla Canvas Samples.

46 | 47 |
48 | 49 |
 50 | var ctx = gfx;
 51 | 
 52 | ctx.noLine()
 53 |    .fillColor( color(200,0,0) )
 54 |    .rectangle(10, 10, 55, 50)
 55 |    .fillColor( color(0, 0, 200, 0.5) )
 56 |    .rectangle(30, 30, 55, 50);
 57 |       
58 |
59 | 60 |
61 | 62 |
 63 | var ctx = gfx;
 64 | 
 65 | ctx.fillColor(color("red"))
 66 |    .lineWidth(1)
 67 |    .lineColor(color(0,0,0));
 68 | 
 69 | var path = new Graphics.Path();
 70 | 
 71 | path.moveTo(30, 30)
 72 |     .lineTo(150, 150)
 73 |     .bezierCurveTo(60, 70, 60, 70, 70, 150)
 74 |     .lineTo(30, 30)
 75 |     .close();
 76 | 
 77 | ctx.drawPath(path);
 78 |       
79 |
80 | 81 |
82 | 83 |
 84 | var ctx = gfx;
 85 | 
 86 | function drawBowtie(fillColor) {
 87 | 
 88 |   ctx.fillColor(color(200,200,200,0.3));
 89 |   ctx.rectangle(-30, -30, 60, 60);
 90 |   
 91 |   ctx.fillColor(fillColor);
 92 | 
 93 |   var path = new Graphics.Path();
 94 |     path.moveTo(25, 25)
 95 |         .lineTo(-25, -25)
 96 |         .lineTo(25, -25)
 97 |         .lineTo(-25, 25)
 98 |         .close();
 99 |   ctx.drawPath(path);
100 | }
101 | 
102 | function dot() {
103 |   ctx.save();
104 |     ctx.fillColor(0);
105 |     ctx.rectangle(-2, -2, 4, 4);
106 |   ctx.restore();
107 | }
108 | 
109 | // note that all other translates are relative to this
110 | // one
111 | ctx.translate(45.5, 45.5);
112 | 
113 | ctx.lineWidth(1)
114 |    .lineColor(color(0,0,0));
115 | 
116 | ctx.save();
117 | //ctx.translate(0, 0); // unnecessary
118 |  drawBowtie(0xFF); //"red"
119 |  dot();
120 | ctx.restore();
121 | 
122 | ctx.save();
123 |  ctx.translate(85, 0);
124 |  ctx.rotate(45 * Math.PI / 180);
125 |  drawBowtie(0x00FF00); //"green"
126 |  dot();
127 | ctx.restore();
128 | 
129 | ctx.save();
130 |  ctx.translate(0, 85);
131 |  ctx.rotate(135 * Math.PI / 180);
132 |  drawBowtie(0xFF0000); //"blue"
133 |  dot();
134 | ctx.restore();
135 | 
136 | ctx.save();
137 |  ctx.translate(85, 85);
138 |  ctx.rotate(90 * Math.PI / 180);
139 |  drawBowtie(color(0xFF,0xFF,0)); //"yellow"
140 |  dot();
141 | ctx.restore();
142 |     
143 |       
144 |
145 | 146 | 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /examples/demoes/09/Contents/MacOS/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sciter-sdk/go-sciter/7f18ada7f2f5758e0aa9e22340cb1abd6728f919/examples/demoes/09/Contents/MacOS/.gitkeep -------------------------------------------------------------------------------- /examples/demoes/09/build.sh: -------------------------------------------------------------------------------- 1 | go build -o Contents/MacOS/09 2 | -------------------------------------------------------------------------------- /examples/demoes/09/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/sciter-sdk/go-sciter" 7 | "github.com/sciter-sdk/go-sciter/window" 8 | ) 9 | 10 | func main() { 11 | // Creating application window with default flags and rect size 12 | win, err := window.New(sciter.DefaultWindowCreateFlag, sciter.DefaultRect) 13 | if err != nil { 14 | log.Fatal(err) 15 | } 16 | 17 | // AddQuitMenu function adds Quit menu (in menubar) and support for 18 | // CMD+q to terminate / close application on MacOS 19 | // 20 | // Note : AddQuitMenu() only works for MacOS on other platform is 21 | // does not have any effect. 22 | win.AddQuitMenu() 23 | 24 | win.Show() 25 | win.Run() 26 | } 27 | -------------------------------------------------------------------------------- /examples/download/download.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "log" 6 | 7 | "github.com/sciter-sdk/go-sciter" 8 | "github.com/sciter-sdk/go-sciter/window" 9 | ) 10 | 11 | func load(w *window.Window, url string) { 12 | root, err := w.GetRootElement() 13 | if err != nil { 14 | log.Panic(err) 15 | } 16 | els, err := root.Select("#url") 17 | if err != nil { 18 | log.Fatal("select:", err) 19 | } 20 | log.Println("els:", els) 21 | span, _ := root.SelectById("url") 22 | if span == nil { 23 | log.Panic("span is nil") 24 | } 25 | content, _ := root.SelectById("content") 26 | if content == nil { 27 | log.Panic("content is nil") 28 | } 29 | text, err := span.Text() 30 | if err != nil { 31 | log.Panic(err) 32 | } 33 | log.Println("span:", text) 34 | err = span.SetText(url) 35 | if err != nil { 36 | log.Panic(err) 37 | } 38 | 39 | content.AttachEventHandler(&sciter.EventHandler{ 40 | OnDataArrived: func(he *sciter.Element, params *sciter.DataArrivedParams) bool { 41 | log.Println("uri:", params.Uri(), len(params.Data())) 42 | return false 43 | }, 44 | }) 45 | 46 | err = content.Load(url, sciter.RT_DATA_HTML) 47 | if err != nil { 48 | log.Panic(err) 49 | } 50 | } 51 | 52 | func testArray() { 53 | v := sciter.NewValue() 54 | // v.SetIndex(0, sciter.NewValue(100)) 55 | log.Println("v.len", v.Length()) 56 | v.Append(105) 57 | log.Println("v.len", v.Length(), v.IsArray()) 58 | v.Append(205) 59 | log.Println("v.len", v.Length()) 60 | v.Append(200) 61 | log.Println("v.len", v.Length()) 62 | rv := v.Index(0) 63 | log.Println("test Value.Index:", rv) 64 | } 65 | 66 | func testMap() { 67 | m := sciter.NewValue() 68 | m.Set("key", "asdf") 69 | log.Println("m.len", m.Length(), m.IsMap()) 70 | m.Set("int", 123) 71 | log.Println("m:", m.Get("key"), m.Get("int")) 72 | } 73 | 74 | func test() { 75 | testArray() 76 | testMap() 77 | } 78 | 79 | func main() { 80 | log.Println("Sciter Version:", sciter.VersionAsString()) 81 | flag.Parse() 82 | if flag.NArg() == 0 { 83 | log.Fatalln("at least one Sciter compatible page url is needed") 84 | } 85 | log.Println(flag.Arg(0)) 86 | w, err := window.New(sciter.SW_ENABLE_DEBUG|sciter.SW_GLASSY, sciter.DefaultRect) 87 | if err != nil { 88 | log.Fatal(err) 89 | } 90 | 91 | w.SetTitle("Download Element Content") 92 | w.LoadHtml("Url To Load", "/") 93 | test() 94 | load(w, flag.Arg(0)) 95 | w.Show() 96 | w.Run() 97 | } 98 | -------------------------------------------------------------------------------- /examples/fixed/fixed.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 |

Sciter Testing Page

11 |
12 |

Can you resize this window?

13 |
14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/fixed/fixedWindow.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "log" 6 | "path/filepath" 7 | 8 | "github.com/sciter-sdk/go-sciter" 9 | "github.com/sciter-sdk/go-sciter/window" 10 | ) 11 | 12 | func main() { 13 | flag.Parse() 14 | if flag.NArg() < 1 { 15 | log.Fatal("html file needed") 16 | } 17 | rect := sciter.NewRect(300, 300, 300, 400) 18 | // create window 19 | w, err := window.New(sciter.DefaultWindowCreateFlag, rect) 20 | if err != nil { 21 | log.Fatal(err) 22 | } 23 | fullpath, err := filepath.Abs(flag.Arg(0)) //if it's already an absolute path, it'll be returned as is. 24 | if err != nil { 25 | log.Fatal(err) 26 | } 27 | w.LoadFile(fullpath) 28 | w.Show() 29 | w.Run() 30 | } 31 | -------------------------------------------------------------------------------- /examples/handlers/a.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 27 | 28 | 53 | 54 | 55 |

Sciter Testing Page

56 |
57 | 58 | 59 | 60 | 61 | 62 |
63 | 64 | 65 |
66 |
67 |
68 | 69 |
70 | 71 | -------------------------------------------------------------------------------- /examples/handlers/handlers.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "log" 6 | "path/filepath" 7 | 8 | "github.com/sciter-sdk/go-sciter" 9 | "github.com/sciter-sdk/go-sciter/rice" 10 | "github.com/sciter-sdk/go-sciter/window" 11 | ) 12 | 13 | func setEventHandler(w *window.Window) { 14 | w.DefineFunction("kkk", func(args ...*sciter.Value) *sciter.Value { 15 | log.Println("kkk called!") 16 | rval := sciter.NewValue() 17 | rval.Set("num", sciter.NewValue(1000)) 18 | rval.Set("str", sciter.NewValue("a string")) 19 | var fn sciter.NativeFunctor 20 | fn = func(args ...*sciter.Value) *sciter.Value { 21 | log.Printf("args[%d]:%v\n", len(args), args) 22 | return sciter.NewValue("native functor called") 23 | } 24 | rval.Set("f", sciter.NewValue(fn)) 25 | return rval 26 | }) 27 | w.DefineFunction("sumall", func(args ...*sciter.Value) *sciter.Value { 28 | sum := 0 29 | for i := 0; i < len(args); i++ { 30 | sum += args[i].Int() 31 | } 32 | return sciter.NewValue(sum) 33 | }) 34 | w.DefineFunction("gprintln", func(args ...*sciter.Value) *sciter.Value { 35 | print("\t->") 36 | for _, arg := range args { 37 | print(arg.String(), "\t") 38 | } 39 | println() 40 | return sciter.NullValue() 41 | }) 42 | } 43 | 44 | func setCallbackHandlers(w *window.Window) { 45 | h := &sciter.CallbackHandler{ 46 | OnDataLoaded: func(ld *sciter.ScnDataLoaded) int { 47 | log.Println("loaded", ld.Uri()) 48 | return sciter.LOAD_OK 49 | }, 50 | OnLoadData: func(ld *sciter.ScnLoadData) int { 51 | log.Println("loading", ld.Uri()) 52 | return sciter.LOAD_OK 53 | }, 54 | } 55 | w.SetCallback(h) 56 | } 57 | 58 | func setElementHandlers(root *sciter.Element) { 59 | log.Println("setElementHandlers") 60 | el, err := root.SelectFirst("#native") 61 | if err == nil { 62 | log.Println("SelectFirst:", el) 63 | el.OnClick(func() { 64 | log.Println("native handler called") 65 | }) 66 | } 67 | root.DefineMethod("mcall", func(args ...*sciter.Value) *sciter.Value { 68 | print("->method args:") 69 | for _, arg := range args { 70 | print(arg.String(), "\t") 71 | } 72 | println() 73 | return sciter.NullValue() 74 | }) 75 | } 76 | 77 | func testCall(w *window.Window) { 78 | // test sciter call 79 | v, err := w.Call("gFunc", sciter.NewValue("kkk"), sciter.NewValue(555)) 80 | if err != nil { 81 | log.Println("sciter call failed:", err) 82 | } else { 83 | log.Println("sciter call successfully:", v.String()) 84 | } 85 | 86 | // test method call 87 | root, err := w.GetRootElement() 88 | if err != nil { 89 | log.Fatalf("get root element failed: %s", err.Error()) 90 | } 91 | v, err = root.CallMethod("mfn", sciter.NewValue("method call"), sciter.NewValue(10300)) 92 | if err != nil { 93 | log.Println("method call failed:", err) 94 | } else { 95 | log.Println("method call successfully:", v.String()) 96 | } 97 | // test function call 98 | v, err = root.CallFunction("gFunc", sciter.NewValue("function call"), sciter.NewValue(10300)) 99 | if err != nil { 100 | log.Println("function call failed:", err) 101 | } else { 102 | log.Println("function call successfully:", v.String()) 103 | } 104 | 105 | v, err = root.CallFunction("gFuncEmpty") 106 | if err != nil { 107 | log.Println("function call gFuncEmpty() failed:", err) 108 | } else { 109 | log.Println("function call gFuncEmpty() successfully:", v.String()) 110 | } 111 | } 112 | 113 | func main() { 114 | flag.Parse() 115 | if len(flag.Args()) < 1 { 116 | log.Fatal("no html file found") 117 | } 118 | // create window 119 | w, err := window.New(sciter.DefaultWindowCreateFlag, sciter.DefaultRect) 120 | if err != nil { 121 | log.Fatal(err) 122 | } 123 | log.Printf("Sciter Version: %X %X\n", sciter.Version(true), sciter.Version(false)) 124 | // resource packing 125 | rice.HandleDataLoad(w.Sciter) 126 | // enable debug 127 | ok := w.SetOption(sciter.SCITER_SET_DEBUG_MODE, 1) 128 | if !ok { 129 | log.Println("set debug mode failed") 130 | } 131 | // load file 132 | fullpath, err := filepath.Abs(flag.Arg(0)) 133 | if err != nil { 134 | log.Fatal(err) 135 | } 136 | 137 | if err = w.LoadFile(fullpath); err != nil { 138 | log.Println("LoadFile error:", err.Error()) 139 | return 140 | } 141 | root, err := w.GetRootElement() 142 | if err != nil { 143 | log.Fatalf("get root element failed: %s", err.Error()) 144 | } 145 | setElementHandlers(root) 146 | // set handlers 147 | setEventHandler(w) 148 | setCallbackHandlers(w) 149 | testCall(w) 150 | w.Show() 151 | w.Run() 152 | } 153 | -------------------------------------------------------------------------------- /examples/handlers/res/decorators.tis: -------------------------------------------------------------------------------- 1 | 2 | 3 | // decorator '@when' - filters event type and establishes chain of event handlers 4 | function @when(func, evtType) 5 | { 6 | function t(evt) 7 | { 8 | var r = false; 9 | if( evt.type == evtType) 10 | r = func.call(this,evt); 11 | if(t.next) return t.next.call(this,evt) || r; 12 | return r; 13 | } 14 | // note 'this' in decorators is a current namespace - class or global (ns) 15 | var principal = this instanceof Behavior? this : self; 16 | t.next = principal.onControlEvent; 17 | return principal.onControlEvent = t; 18 | } 19 | 20 | function @click(func) // short form of @when Event.BUTTON_CLICK ... 21 | { 22 | function t(evt) 23 | { 24 | var r = false; 25 | if( evt.type == Event.BUTTON_CLICK 26 | || evt.type == Event.HYPERLINK_CLICK 27 | || evt.type == Event.MENU_ITEM_CLICK ) 28 | r = func.call(this,evt); 29 | if(t.next) return t.next.call(this,evt) || r; 30 | return r; 31 | } 32 | // note 'this' in decorators is a current namespace - class or global (ns) 33 | var principal = this instanceof Behavior? this : self; 34 | t.next = principal.onControlEvent; 35 | return principal.onControlEvent = t; 36 | } 37 | 38 | function @dblclick(func) 39 | { 40 | function t(evt) 41 | { 42 | var r = false; 43 | if( evt.type == Event.MOUSE_DCLICK ) 44 | r = func.call(this,evt); 45 | if(t.next) return t.next.call(this,evt) || r; 46 | return r; 47 | } 48 | // note 'this' in decorators is a current namespace - class or global (ns) 49 | var principal = this instanceof Behavior? this : self; 50 | t.next = principal.onMouse; 51 | return principal.onMouse = t; 52 | } 53 | 54 | 55 | function @change(func) // short form of @when Event.EDIT_VALUE_CHANGED ... 56 | { 57 | function t(evt) 58 | { 59 | var r = false; 60 | if( evt.type == Event.BUTTON_STATE_CHANGED 61 | || evt.type == Event.SELECT_SELECTION_CHANGED 62 | || evt.type == Event.EDIT_VALUE_CHANGED ) 63 | r = func.call(this,evt); 64 | if(t.next) return t.next.call(this,evt) || r; 65 | return r; 66 | } 67 | // note 'this' in decorators is a current namespace - class or global (ns) 68 | var principal = this instanceof Behavior? this : self; 69 | t.next = principal.onControlEvent; 70 | return principal.onControlEvent = t; 71 | } 72 | 73 | // decorator '@on' - filters evt.target by selector 74 | function @on(func, selector) 75 | { 76 | return function(evt) 77 | { 78 | var el = evt.target.selectParent(selector); 79 | if( el && el.belongsTo(this)) 80 | return func.call(this,evt,el); 81 | } 82 | } 83 | 84 | // decorator '@key' - filters Event.KEY_DOWN events by keyCode and ctrl, shift, alt flags. 85 | // Establishes chain of event handlers on onKey 86 | function @key(func, keyCode = undefined, modifiers..) 87 | { 88 | function t(evt) 89 | { 90 | var r = false; 91 | if( evt.type == Event.KEY_DOWN && 92 | (keyCode === undefined || (keyCode == evt.keyCode)) ) 93 | r = func.call(this,evt); 94 | if(t.next) return t.next.call(this,evt) || r; 95 | return r; 96 | } 97 | // note 'this' in decorators is a current namespace - class or global (ns) 98 | var principal = this instanceof Behavior ? this : self; 99 | t.next = principal.onKey; 100 | principal.onKey = t; 101 | //return 102 | } 103 | 104 | // decorator '@CTRL' - pass if evt.ctrlKey === true 105 | function @CTRL(func) { return function(evt) { if( evt.ctrlKey === true ) return func.call(this,evt); } } 106 | // decorator '@NOCTRL' - pass if evt.ctrlKey === false 107 | function @NOCTRL(func) { return function(evt) { if( evt.ctrlKey === false ) return func.call(this,evt); } } 108 | // decorator '@SHIFT' - pass if evt.shiftKey === true 109 | function @SHIFT(func) { return function(evt) { if( evt.shiftKey === true ) return func.call(this,evt); } } 110 | // decorator '@NOSHIFT' - pass if evt.shiftKey === false 111 | function @NOSHIFT(func) { return function(evt) { if( evt.shiftKey === false ) return func.call(this,evt); } } 112 | // decorator '@ALT' - pass if evt.ctrlKey === true 113 | function @ALT(func) { return function(evt) { if( evt.altKey === true ) return func.call(this,evt); } } 114 | // decorator '@NOCTRL' - pass if evt.ctrlKey === false 115 | function @NOALT(func) { return function(evt) { if( evt.altKey === false ) return func.call(this,evt); } } 116 | 117 | // decorator '@mouse' - filters mouse events by type, establishes chain of event handlers 118 | function @mouse(func, mouseEvtType) 119 | { 120 | function t(evt) 121 | { 122 | var r = false; 123 | if( evt.type == mouseEvtType) 124 | r = func.call(this,evt); 125 | if(t.next) return t.next.call(this,evt) || r; 126 | return r; 127 | } 128 | // note 'this' in decorators is a current namespace - class or global (ns) 129 | var principal = this instanceof Behavior? this : self; 130 | t.next = principal.onMouse; 131 | return principal.onMouse = t; 132 | } 133 | 134 | // decorator '@focus' - filters focus events by type, establishes chain of event handlers 135 | function @focus(func, got /*true|false*/) 136 | { 137 | function t(evt) 138 | { 139 | var r = false; 140 | if( evt.type == (got ? Event.GOT_FOCUS : Event.LOST_FOCUS) ) 141 | r = func.call(this,evt); 142 | if(t.next) return t.next.call(this,evt) || r; 143 | return r; 144 | } 145 | // note 'this' in decorators is a current namespace - class or global (ns) 146 | var principal = this instanceof Behavior? this : self; 147 | t.next = principal.onFocus; 148 | return principal.onFocus = t; 149 | } 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /examples/insert/insert.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/sciter-sdk/go-sciter" 7 | "github.com/sciter-sdk/go-sciter/window" 8 | ) 9 | 10 | func main() { 11 | w, err := window.New(sciter.SW_TITLEBAR|sciter.SW_RESIZEABLE|sciter.SW_CONTROLS|sciter.SW_MAIN|sciter.SW_ENABLE_DEBUG, nil) 12 | if err != nil { 13 | log.Fatal(err) 14 | } 15 | // log.Printf("handle: %v", w.Handle) 16 | // w.LoadFile("simple.html") 17 | w.LoadHtml("asdf", "") 18 | w.SetTitle("Inserting Example") 19 | root, err := w.GetRootElement() 20 | if err != nil { 21 | log.Panicln(err) 22 | } 23 | div, err := sciter.CreateElement("div", "hello world") 24 | if err != nil { 25 | log.Printf("sciter.CreateElement('div', '') %s", err.Error()) 26 | return 27 | } 28 | err = root.Insert(div, 0) 29 | if err != nil { 30 | log.Printf("root.Insert(div, 0) %s", err.Error()) 31 | return 32 | } 33 | w.Show() 34 | w.Run() 35 | } 36 | -------------------------------------------------------------------------------- /examples/request/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 21 | 22 | 23 |

Normal Condition

24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |

Fail Condition

33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /examples/request/lighthouse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sciter-sdk/go-sciter/7f18ada7f2f5758e0aa9e22340cb1abd6728f919/examples/request/lighthouse.jpg -------------------------------------------------------------------------------- /examples/request/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io" 5 | "io/ioutil" 6 | "log" 7 | "os" 8 | "path/filepath" 9 | "strings" 10 | 11 | "github.com/sciter-sdk/go-sciter" 12 | "github.com/sciter-sdk/go-sciter/window" 13 | ) 14 | 15 | func main() { 16 | // NOTE: ALLOW_SOCKET_IO is necessary in order to make requests programmatically 17 | sciter.SetOption(sciter.SCITER_SET_SCRIPT_RUNTIME_FEATURES, sciter.ALLOW_SOCKET_IO) 18 | 19 | win, err := window.New(sciter.SW_MAIN|sciter.SW_TITLEBAR|sciter.SW_CONTROLS|sciter.SW_RESIZEABLE|sciter.SW_ENABLE_DEBUG, nil) 20 | if err != nil { 21 | log.Panic(err) 22 | } 23 | 24 | // setup asset routes 25 | win.SetCallback(&sciter.CallbackHandler{ 26 | OnLoadData: func(params *sciter.ScnLoadData) int { 27 | return customOnLoadData(params) 28 | }, 29 | }) 30 | 31 | fullpath, err := filepath.Abs("index.html") 32 | if err != nil { 33 | log.Panic(err) 34 | } 35 | 36 | // load main page 37 | if err := win.LoadFile(fullpath); err != nil { 38 | log.Panic(err) 39 | } 40 | 41 | win.Show() 42 | win.Run() 43 | } 44 | 45 | func customOnLoadData(params *sciter.ScnLoadData) int { 46 | rq := sciter.WrapRequest(params.RequestId()) // get a new Request interface 47 | uri, _ := rq.Url() 48 | rqType, _ := rq.RequestType() 49 | rqDataType, _ := rq.RequestedDataType() 50 | if strings.HasPrefix(uri, "sync://") && rqType == sciter.RRT_GET && rqDataType == sciter.RT_DATA_IMAGE { // serve content synchronously 51 | path := uri[7:] 52 | f, err := os.Open(path) 53 | if err != nil { 54 | return sciter.LOAD_DISCARD 55 | } 56 | data, err := ioutil.ReadAll(f) 57 | if err != nil { 58 | return sciter.LOAD_DISCARD 59 | } 60 | rq.SetSucceeded(200, data) 61 | } else if strings.HasPrefix(uri, "async://") && rqType == sciter.RRT_GET && rqDataType == sciter.RT_DATA_IMAGE { // serve content asynchronously 62 | go func() { // load content from a goroutine 63 | path := uri[8:] 64 | f, err := os.Open(path) 65 | if err != nil { 66 | rq.SetFailed(404, nil) 67 | return 68 | } 69 | data, err := ioutil.ReadAll(f) 70 | if err != nil { 71 | rq.SetFailed(500, nil) 72 | return 73 | } 74 | //time.Sleep(time.Second * 3) // simulated network lag 75 | rq.SetSucceeded(200, data) 76 | }() 77 | 78 | // let sciter know we intend to load the data later 79 | return sciter.LOAD_DELAYED 80 | } else if strings.HasPrefix(uri, "chunked://") && rqType == sciter.RRT_GET && rqDataType == sciter.RT_DATA_IMAGE { // serve content asynchronously in chunks 81 | go func() { // load content from a goroutine 82 | path := uri[10:] 83 | f, err := os.Open(path) 84 | if err != nil { 85 | rq.SetFailed(404, nil) 86 | return 87 | } 88 | 89 | // load the data in chunks 90 | buf := make([]byte, 1<<16) // 65KB 91 | for { 92 | //time.Sleep(time.Millisecond * 100) // simulated network lag 93 | n, err := f.Read(buf) 94 | rq.AppendDataChunk(buf[:n]) 95 | if err == io.EOF { 96 | rq.SetSucceeded(200, nil) 97 | return 98 | } 99 | } 100 | }() 101 | 102 | // let sciter know we intend to load the data later 103 | return sciter.LOAD_DELAYED 104 | } 105 | 106 | return sciter.LOAD_OK 107 | } 108 | -------------------------------------------------------------------------------- /examples/restest/res/simple.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | angles demo (packed in rice archive) 5 | 35 | 36 | 37 | 38 |
gradient rotated +45°
39 |
element rotated +45°
40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /examples/restest/restest.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | tool "github.com/GeertJohan/go.rice" 6 | sciter "github.com/sciter-sdk/go-sciter" 7 | rice "github.com/sciter-sdk/go-sciter/rice" 8 | window "github.com/sciter-sdk/go-sciter/window" 9 | ) 10 | 11 | /* 12 | A go.rice usage example. 13 | 14 | To build it you need an actual `go.rice` package and its tool: 15 | 16 | * install go.gice: `go get github.com/GeertJohan/go.rice && go get github.com/GeertJohan/go.rice/rice` 17 | * append resources to executable via `go build && rice append /exec restest.exe` (omit .exe if not on Windows) 18 | * or you can embed it via `rice embed-go && go build` (in that order) 19 | 20 | Now the resulting executable is completely stand-alone. 21 | */ 22 | func main() { 23 | // As usual, create a sciter window. 24 | w, err := window.New(sciter.SW_TITLEBAR|sciter.SW_RESIZEABLE|sciter.SW_CONTROLS|sciter.SW_MAIN, nil) 25 | if err != nil { 26 | log.Fatal(err) 27 | } 28 | 29 | // 1. Handle resources via sciter.rice loader. 30 | // It handles URLs like `file://box/` and `rice://box/`. 31 | rice.HandleDataLoad(w.Sciter) 32 | 33 | // 2. A dummy call to allow `go.rice` to package and register that folder. 34 | tool.MustFindBox("res") 35 | 36 | // 3. Load a packaged resource. 37 | err = w.LoadFile("rice://res/simple.html") 38 | if err != nil { 39 | log.Fatal(err) 40 | } 41 | w.Show() 42 | w.Run() 43 | } 44 | -------------------------------------------------------------------------------- /examples/restest2/res.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | var resource_name []byte = []byte { 4 | 0x53,0x41,0x72,0x00,0x0c,0x00,0x00,0x00,0x73,0x00,0xff,0xff,0x01,0x00,0xff,0xff,0x69,0x00,0xff,0xff,0x02,0x00,0xff,0xff,0x6d,0x00,0xff,0xff,0x03,0x00,0xff,0xff,0x70,0x00,0xff,0xff,0x04,0x00,0xff,0xff,0x6c, 5 | 0x00,0xff,0xff,0x05,0x00,0xff,0xff,0x65,0x00,0xff,0xff,0x06,0x00,0xff,0xff,0x2e,0x00,0xff,0xff,0x07,0x00,0xff,0xff,0x68,0x00,0xff,0xff,0x08,0x00,0xff,0xff,0x74,0x00,0xff,0xff,0x09,0x00,0xff,0xff,0x6d,0x00, 6 | 0xff,0xff,0x0a,0x00,0xff,0xff,0x6c,0x00,0xff,0xff,0x0b,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x01,0x00,0xff,0xff,0x01,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x0e,0x02,0x00,0x00,0xf5,0x04,0x00,0x00,0x0e,0x3c,0x68, 7 | 0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x20,0x09,0x00,0x20,0x20,0x00,0x13,0x3c,0x74,0x69,0x74,0x6c,0x65,0x3e,0x61,0x6e,0x67,0x6c,0x65,0x73,0x20,0x64,0x65,0x6d,0x6f,0x3c,0x2f,0x80, 8 | 0x12,0xa0,0x1f,0x02,0x73,0x74,0x79,0xe0,0x00,0x0c,0x12,0x23,0x67,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x2d,0x72,0x6f,0x74,0x61,0x74,0x65,0x64,0x20,0x7b,0x80,0x18,0x40,0x00,0x12,0x70,0x6f,0x73,0x69,0x74,0x69, 9 | 0x6f,0x6e,0x3a,0x20,0x61,0x62,0x73,0x6f,0x6c,0x75,0x74,0x65,0x3b,0xe0,0x01,0x1c,0x08,0x74,0x6f,0x70,0x3a,0x20,0x34,0x30,0x70,0x78,0xe0,0x02,0x13,0x03,0x6c,0x65,0x66,0x74,0xe0,0x08,0x14,0x08,0x77,0x69,0x64, 10 | 0x74,0x68,0x3a,0x20,0x33,0x30,0xe0,0x05,0x16,0x04,0x68,0x65,0x69,0x67,0x68,0x20,0x2d,0xe0,0x07,0x17,0x12,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3a,0x20,0x6c,0x69,0x6e,0x65,0x61,0x72,0x2d,0xc0, 11 | 0xa3,0x13,0x28,0x34,0x35,0x64,0x65,0x67,0x2c,0x20,0x72,0x65,0x64,0x2c,0x20,0x79,0x65,0x6c,0x6c,0x6f,0x77,0x29,0xe0,0x0c,0x39,0x0c,0x2d,0x69,0x6d,0x61,0x67,0x65,0x3a,0x20,0x2d,0x6d,0x6f,0x7a,0x2d,0xe0,0x07, 12 | 0x44,0x20,0xb8,0x60,0xa8,0x01,0x20,0x2d,0xe0,0x0b,0x4e,0x0f,0x20,0x2f,0x2f,0x20,0x74,0x68,0x65,0x73,0x65,0x20,0x67,0x75,0x79,0x73,0x20,0x75,0x20,0x08,0x08,0x43,0x43,0x57,0x20,0x64,0x69,0x72,0x65,0x63,0x41, 13 | 0x0b,0x03,0x20,0x69,0x6e,0x20,0xc0,0x4a,0x09,0x73,0x20,0x66,0x6f,0x72,0x20,0x73,0x6f,0x6d,0x65,0x20,0x43,0x04,0x61,0x73,0x6f,0x6e,0x73,0xe0,0x14,0x8c,0x05,0x77,0x65,0x62,0x6b,0x69,0x74,0xe0,0x08,0x8f,0xe0, 14 | 0x0c,0x86,0x80,0x48,0x00,0x7d,0x80,0x06,0x80,0x05,0x00,0x23,0xe1,0x50,0xa1,0x0f,0x62,0x6f,0x72,0x64,0x65,0x72,0x3a,0x20,0x31,0x70,0x78,0x20,0x64,0x61,0x73,0x68,0x20,0x63,0x04,0x62,0x72,0x6f,0x77,0x6e,0xe0, 15 | 0x02,0x22,0xa1,0xc4,0x02,0x34,0x32,0x34,0xe0,0x04,0x39,0xc1,0xc4,0x00,0x35,0xe0,0x05,0x50,0x04,0x74,0x72,0x61,0x6e,0x73,0x21,0x1b,0x02,0x6d,0x3a,0x20,0x80,0xb4,0x81,0xb9,0xc0,0xd6,0x40,0x00,0xe0,0x00,0x22, 16 | 0x05,0x2d,0x6f,0x72,0x69,0x67,0x69,0x20,0xc1,0x20,0xae,0x60,0x9e,0xe0,0x02,0x24,0x61,0xbf,0xe0,0x00,0x29,0xe0,0x11,0x4c,0xc1,0x5a,0xe0,0x1b,0x2a,0xe0,0x04,0x52,0xe0,0x14,0x7c,0xe0,0x07,0x54,0xe0,0x13,0x2c, 17 | 0xe1,0x01,0xee,0xe2,0x09,0xb5,0x40,0x2a,0xe1,0x0c,0xde,0x40,0x00,0xe0,0x01,0x38,0xe2,0x00,0x27,0x40,0xa1,0xe0,0x37,0x43,0xa0,0xbb,0xe0,0x20,0x46,0xa2,0x69,0x01,0x3c,0x2f,0xc4,0x1c,0x01,0x3c,0x2f,0xa4,0x52, 18 | 0x20,0x0a,0x03,0x62,0x6f,0x64,0x79,0x20,0x09,0x20,0x1f,0x08,0x20,0x3c,0x64,0x69,0x76,0x20,0x69,0x64,0x3d,0xc0,0x51,0xc4,0x36,0x00,0x3e,0xc0,0x10,0xa1,0x78,0x05,0x64,0x20,0x2b,0x34,0x35,0x26,0x21,0x7b,0x02, 19 | 0x3b,0x3c,0x2f,0x20,0x32,0xe0,0x06,0x3d,0xa0,0x23,0x04,0x3e,0x65,0x6c,0x65,0x6d,0xe0,0x13,0x33,0x01,0x3c,0x2f,0xa0,0x7a,0x40,0x0a,0x64,0xec,0x01,0x0d,0x0a, 20 | } 21 | -------------------------------------------------------------------------------- /examples/restest2/res/simple.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | angles demo (packed in sciter archive) 5 | 35 | 36 | 37 | 38 |
gradient rotated +45°
39 |
element rotated +45°
40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /examples/restest2/restest.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | sciter "github.com/sciter-sdk/go-sciter" 6 | window "github.com/sciter-sdk/go-sciter/window" 7 | ) 8 | 9 | /* 10 | A Sciter archive usage example. 11 | 12 | To build it you need the `packfolder` tool from the Sciter SDK: 13 | 14 | * convert resources from folder `res` to `res.go` via `packfolder res res.go -v resource_name -go` 15 | * use it in your source code via `win.SetResourceArchive(resource_name)` 16 | 17 | Now the resulting executable is completely stand-alone. 18 | */ 19 | func main() { 20 | // As usual, create a sciter window. 21 | w, err := window.New(sciter.SW_TITLEBAR|sciter.SW_RESIZEABLE|sciter.SW_CONTROLS|sciter.SW_MAIN, nil) 22 | if err != nil { 23 | log.Fatal(err) 24 | } 25 | 26 | // 1. Handle resources via sciter archive loader. 27 | // It handles URLs like `this://app/`. 28 | w.SetResourceArchive(resource_name) 29 | 30 | // 2. Load a packaged resource. 31 | err = w.LoadFile("this://app/simple.html") 32 | if err != nil { 33 | log.Fatal(err) 34 | } 35 | w.Show() 36 | w.Run() 37 | } 38 | -------------------------------------------------------------------------------- /examples/simple/simple.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "path/filepath" 6 | 7 | "github.com/sciter-sdk/go-sciter" 8 | "github.com/sciter-sdk/go-sciter/window" 9 | ) 10 | 11 | func main() { 12 | w, err := window.New(sciter.SW_TITLEBAR|sciter.SW_RESIZEABLE|sciter.SW_CONTROLS|sciter.SW_MAIN|sciter.SW_ENABLE_DEBUG, nil) 13 | if err != nil { 14 | log.Fatal(err) 15 | } 16 | fullpath, err := filepath.Abs("simple.html") 17 | if err != nil { 18 | log.Fatal(err) 19 | } 20 | w.LoadFile(fullpath) 21 | w.SetTitle("Example") 22 | w.Show() 23 | w.Run() 24 | } 25 | -------------------------------------------------------------------------------- /examples/simple/simple.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | angles demo 5 | 35 | 36 | 37 | 38 |
gradient rotated +45°
39 |
element rotated +45°
40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /examples/sview/sview.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "log" 6 | "path/filepath" 7 | 8 | "github.com/sciter-sdk/go-sciter" 9 | "github.com/sciter-sdk/go-sciter/window" 10 | ) 11 | 12 | var ( 13 | pageURI = "" 14 | ) 15 | 16 | func setupViewer(w *window.Window) { 17 | log.Println("setup for new view ...") 18 | w.SetTitle("Sciter HTM viewer") 19 | root, err := w.GetRootElement() 20 | if err != nil { 21 | log.Println(err) 22 | return 23 | } 24 | root.AttachEventHandler(&sciter.EventHandler{ 25 | OnKey: func(el *sciter.Element, p *sciter.KeyParams) bool { 26 | if p.Cmd == sciter.KEY_DOWN|sciter.SINKING && p.KeyCode == 0x74 { 27 | log.Println("reloading", pageURI) 28 | w.LoadFile(pageURI) 29 | setupViewer(w) 30 | return true 31 | } 32 | return false 33 | }, 34 | OnExchange: func(el *sciter.Element, p *sciter.ExchangeParams) bool { 35 | if p.Cmd == sciter.X_WILL_ACCEPT_DROP|sciter.SINKING { 36 | if p.Data.IsString() { 37 | return true 38 | } 39 | } 40 | if p.Cmd == sciter.X_DROP|sciter.SINKING { 41 | pageURI = p.Data.String() 42 | log.Println("Loading new content:", pageURI) 43 | w.LoadFile(pageURI) 44 | setupViewer(w) 45 | return true 46 | } 47 | return true 48 | }, 49 | }) 50 | } 51 | 52 | func setCallbackHandlers(w *window.Window) { 53 | h := &sciter.CallbackHandler{ 54 | OnDataLoaded: func(ld *sciter.ScnDataLoaded) int { 55 | uri := ld.Uri() 56 | log.Println("loaded", uri) 57 | return sciter.LOAD_OK 58 | }, 59 | OnLoadData: func(ld *sciter.ScnLoadData) int { 60 | log.Println("loading", ld.Uri()) 61 | return sciter.LOAD_OK 62 | }, 63 | } 64 | w.SetCallback(h) 65 | } 66 | 67 | func main() { 68 | flag.Parse() 69 | // create window 70 | w, err := window.New(sciter.DefaultWindowCreateFlag, sciter.DefaultRect) 71 | if err != nil { 72 | log.Fatal(err) 73 | } 74 | log.Printf("Sciter Version: %X %X\n", sciter.Version(true), sciter.Version(false)) 75 | // enable debug 76 | ok := w.SetOption(sciter.SCITER_SET_DEBUG_MODE, 1) 77 | if !ok { 78 | log.Println("set debug mode failed") 79 | } 80 | // enable full rt features 81 | ok = w.SetOption(sciter.SCITER_SET_SCRIPT_RUNTIME_FEATURES, sciter.ALLOW_FILE_IO| 82 | sciter.ALLOW_SOCKET_IO| 83 | sciter.ALLOW_EVAL| 84 | sciter.ALLOW_SYSINFO) 85 | if !ok { 86 | log.Println("enable full fetures failed") 87 | } 88 | // load file 89 | if len(flag.Args()) >= 1 { 90 | fp, err := filepath.Abs(flag.Arg(0)) 91 | if err != nil { 92 | log.Fatal(err) 93 | } 94 | pageURI = fp 95 | if err = w.LoadFile(pageURI); err != nil { 96 | log.Fatal(err) 97 | return 98 | } 99 | } else { 100 | w.LoadHtml("Drag sciter htm file here, using F5 to refresh", "self") 101 | } 102 | // set handlers 103 | setupViewer(w) 104 | setCallbackHandlers(w) 105 | // show 106 | w.Show() 107 | w.Run() 108 | } 109 | -------------------------------------------------------------------------------- /examples/textHtml/textHtml.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/sciter-sdk/go-sciter" 7 | "github.com/sciter-sdk/go-sciter/window" 8 | ) 9 | 10 | const ( 11 | html = ` 12 | 13 | 14 |

test for element.Text and element.Html

15 |
16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 |
25 |
26 |
27 | 28 |
29 | 30 | 31 | ` 32 | ) 33 | 34 | func main() { 35 | w, err := window.New(sciter.DefaultWindowCreateFlag, sciter.DefaultRect) 36 | if err != nil { 37 | log.Fatal("sciter create window failed", err) 38 | } 39 | 40 | w.SetTitle("test for element.Text and element.Html") 41 | w.LoadHtml(html, "") 42 | 43 | root, err := w.GetRootElement() 44 | if err != nil { 45 | log.Fatal(err) 46 | } 47 | text, err := root.Text() 48 | if err != nil { 49 | log.Fatal(err) 50 | } 51 | log.Println("text:", text) 52 | text, err = root.Html(false) 53 | if err != nil { 54 | log.Fatal(err) 55 | } 56 | log.Println("html:", text) 57 | } 58 | -------------------------------------------------------------------------------- /generate.go: -------------------------------------------------------------------------------- 1 | package sciter 2 | 3 | //go:generate stringer -type=BehaviorEvent,MouseEvent,CursorType,KeyEvent,FocusEvent,ScrollEvent,GestureCmd,GestureState,GestureTypeFlag,DrawEvent,EventReason,EditChangedReason,BehaviorMethodIdentifier,SCDOM_RESULT,VALUE_RESULT -output types_string.go 4 | -------------------------------------------------------------------------------- /include/sciter-om.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef __SCITER_OM_H__ 4 | #define __SCITER_OM_H__ 5 | 6 | 7 | struct som_passport_t; 8 | struct som_asset_class_t; 9 | 10 | typedef UINT64 som_atom_t; 11 | 12 | typedef struct som_asset_t { 13 | struct som_asset_class_t* isa; 14 | } som_asset_t; 15 | 16 | typedef struct som_asset_class_t { 17 | long(*asset_add_ref)(som_asset_t* thing); 18 | long(*asset_release)(som_asset_t* thing); 19 | long(*asset_get_interface)(som_asset_t* thing, const char* name, void** out); 20 | struct som_passport_t* (*asset_get_passport)(som_asset_t* thing); 21 | } som_asset_class_t; 22 | 23 | 24 | inline som_asset_class_t* som_asset_get_class(const som_asset_t* pass) 25 | { 26 | return pass ? pass->isa : 0; 27 | } 28 | 29 | som_atom_t SCAPI SciterAtomValue(const char* name); 30 | 31 | #ifdef CPP11 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | namespace sciter { 38 | 39 | class atom { 40 | som_atom_t _atom; 41 | public: 42 | atom(const char* name) { _atom = SciterAtomValue(name); } 43 | atom(const atom& other) { _atom = other._atom; } 44 | operator som_atom_t() const { return _atom; } 45 | }; 46 | 47 | namespace om { 48 | 49 | template class hasset; 50 | 51 | // implementation of som_asset_t ISA 52 | // note: does not define asset_add_ref()/asset_release() as they shall be defined in specializations 53 | template 54 | class iasset : public som_asset_t 55 | { 56 | public: 57 | iasset() { isa = get_asset_class(); } 58 | 59 | // mandatory: 60 | virtual long asset_add_ref() = 0; 61 | virtual long asset_release() = 0; 62 | // can be used to as to get interface as to check if the thing supports the feature 63 | virtual long asset_get_interface(const char* name, void** out = nullptr) { 64 | if (0 != strcmp(name, interface_name())) return false; 65 | if (out) { this->asset_add_ref(); *out = this; } 66 | return true; 67 | } 68 | virtual som_passport_t* asset_get_passport() const { 69 | return nullptr; 70 | } 71 | 72 | static som_asset_class_t* get_asset_class() { 73 | static som_asset_class_t cls = { 74 | &thunk_asset_add_ref, 75 | &thunk_asset_release, 76 | &thunk_asset_get_interface, 77 | &thunk_asset_get_passport 78 | }; 79 | return &cls; 80 | }; 81 | 82 | static long thunk_asset_add_ref(som_asset_t* thing) { return static_cast(thing)->asset_add_ref(); } 83 | static long thunk_asset_release(som_asset_t* thing) { return static_cast(thing)->asset_release(); } 84 | static long thunk_asset_get_interface(som_asset_t* thing, const char* name, void** out) { return static_cast(thing)->asset_get_interface(name, out); } 85 | static som_passport_t* thunk_asset_get_passport(som_asset_t* thing) { return static_cast(thing)->asset_get_passport(); } 86 | 87 | static const char* interface_name() { return "asset.sciter.com"; } 88 | //template hasset interface_of() { hasset p; get_interface(C::interface_name(), p.target()); return p; } 89 | }; 90 | 91 | inline long asset_add_ref(som_asset_t *ptr) { 92 | assert(ptr); 93 | assert(ptr->isa); 94 | assert(ptr->isa->asset_add_ref); 95 | return ptr->isa->asset_add_ref(ptr); 96 | } 97 | inline long asset_release(som_asset_t *ptr) { 98 | assert(ptr); 99 | assert(ptr->isa); 100 | assert(ptr->isa->asset_release); 101 | return ptr->isa->asset_release(ptr); 102 | } 103 | inline long asset_get_interface(som_asset_t *ptr, const char* name, void** out = nullptr) { 104 | assert(ptr); 105 | assert(ptr->isa); 106 | assert(ptr->isa->asset_get_interface); 107 | return ptr->isa->asset_get_interface(ptr, name, out); 108 | } 109 | 110 | inline som_passport_t* asset_get_passport(som_asset_t *ptr) { 111 | assert(ptr); 112 | assert(ptr->isa); 113 | assert(ptr->isa->asset_get_passport); 114 | return ptr->isa->asset_get_passport(ptr); 115 | } 116 | 117 | inline som_asset_class_t* asset_get_class(som_asset_t *ptr) { 118 | assert(ptr); 119 | return ptr->isa; 120 | } 121 | 122 | //hasset - yet another shared_ptr 123 | // R here is an entity derived from som_asset_t 124 | template class hasset 125 | { 126 | protected: 127 | R* p; 128 | 129 | public: 130 | typedef R asset_t; 131 | 132 | hasset() :p(nullptr) {} 133 | hasset(R* lp) :p(nullptr) { if (lp) asset_add_ref(p = lp); } 134 | hasset(const hasset& cp) :p(nullptr) { if (cp.p) asset_add_ref(p = cp.p); } 135 | 136 | ~hasset() { if (p) asset_release(p); } 137 | operator R*() const { return p; } 138 | R* operator->() const { assert(p != 0); return p; } 139 | 140 | bool operator!() const { return p == 0; } 141 | explicit operator bool() const { return p != 0; } 142 | bool operator!=(R* pR) const { return p != pR; } 143 | bool operator==(R* pR) const { return p == pR; } 144 | 145 | // release the interface and set it to NULL 146 | void release() { if (p) { R* pt = p; p = 0; asset_release(pt); } } 147 | 148 | // attach to an existing interface (does not AddRef) 149 | void attach(R* p2) { asset_release(p); p = p2; } 150 | // detach the interface (does not Release) 151 | R* detach() { R* pt = p; p = 0; return pt; } 152 | 153 | static R* assign(R* &pp, R* lp) 154 | { 155 | if (lp != 0) asset_add_ref(lp); 156 | if (pp) asset_release(pp); 157 | pp = lp; 158 | return lp; 159 | } 160 | 161 | R* operator=(R* lp) { if (p != lp) return assign(p, lp); return p; } 162 | R* operator=(const hasset& lp) { if (p != lp) return assign(p, lp.p); return p; } 163 | 164 | void** target() { release(); return (void**)&p; } 165 | 166 | }; 167 | 168 | // reference counted asset, uses intrusive add_ref/release counter 169 | template 170 | class asset : public iasset> 171 | { 172 | std::atomic _ref_cntr; 173 | public: 174 | asset() :_ref_cntr(0) {} 175 | asset(const asset&/*r*/) = delete; 176 | 177 | virtual ~asset() 178 | { 179 | assert(_ref_cntr == 0); 180 | } 181 | 182 | long asset_release() override 183 | { 184 | assert(_ref_cntr > 0); 185 | long t = --_ref_cntr; 186 | if (t == 0) 187 | asset_finalize(); 188 | return t; 189 | } 190 | long asset_add_ref() override { return ++_ref_cntr; } 191 | 192 | // "name" here is an arbitrary name that includes domain name in reversed order: 193 | // "element.dom.sciter.com" 194 | // "video-renderer.dom.sciter.com" 195 | //virtual bool asset_get_interface(const char* name, iasset** out) override { return false; } 196 | 197 | virtual void asset_finalize() 198 | { 199 | delete static_cast(this); 200 | } 201 | }; 202 | } 203 | 204 | template 205 | inline AT* value::get_asset() const { 206 | som_asset_t* pass = get_asset(); 207 | if (pass && (som_asset_get_class(pass) == AT::get_asset_class())) 208 | return static_cast(pass); 209 | return nullptr; 210 | } 211 | 212 | } 213 | 214 | #endif 215 | 216 | #include "sciter-om-def.h" 217 | 218 | #endif 219 | -------------------------------------------------------------------------------- /include/sciter-x-debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The Sciter Engine of Terra Informatica Software, Inc. 3 | * http://sciter.com 4 | * 5 | * The code and information provided "as-is" without 6 | * warranty of any kind, either expressed or implied. 7 | * 8 | * (C) 2003-2015, Terra Informatica Software, Inc. 9 | */ 10 | 11 | #ifndef __SCITER_X_DEBUG_H__ 12 | #define __SCITER_X_DEBUG_H__ 13 | 14 | //| 15 | //| Sciter Inspector/Debug API 16 | //| 17 | 18 | #include "sciter-x-api.h" 19 | 20 | inline VOID SCAPI SciterSetupDebugOutput ( HWINDOW hwndOrNull, LPVOID param, DEBUG_OUTPUT_PROC pfOutput) { return SAPI()->SciterSetupDebugOutput ( hwndOrNull,param,pfOutput); } 21 | 22 | #if defined(__cplusplus) && !defined( PLAIN_API_ONLY ) 23 | 24 | namespace sciter 25 | { 26 | 27 | struct debug_output 28 | { 29 | 30 | debug_output(HWINDOW hwnd = 0) 31 | { 32 | setup_on(hwnd); 33 | } 34 | 35 | void setup_on(HWINDOW hwnd = 0) 36 | { 37 | ::SciterSetupDebugOutput(hwnd,this,_output_debug); 38 | instance(this); 39 | } 40 | 41 | static debug_output* instance(debug_output* pi = nullptr) { 42 | static debug_output* _instance = nullptr; 43 | if (pi) _instance = pi; 44 | return _instance; 45 | } 46 | 47 | static VOID SC_CALLBACK _output_debug(LPVOID param, UINT subsystem, UINT severity, LPCWSTR text, UINT text_length) 48 | { 49 | static_cast(param)->output((OUTPUT_SUBSYTEMS)subsystem,(OUTPUT_SEVERITY)severity, (const WCHAR*)text,text_length); 50 | } 51 | virtual void output( OUTPUT_SUBSYTEMS subsystem, OUTPUT_SEVERITY severity, const WCHAR* text, unsigned int text_length ) 52 | { 53 | switch(severity) 54 | { 55 | case OS_INFO : print("info:"); break; 56 | case OS_WARNING : print("warning:"); break; 57 | case OS_ERROR : print("error:"); break; 58 | } 59 | switch(subsystem) 60 | { 61 | case OT_DOM: print("DOM: "); break; 62 | case OT_CSSS: print("csss!: "); break; 63 | case OT_CSS: print("css: "); break; 64 | case OT_TIS: print("script: "); break; 65 | } 66 | if(text[text_length]) 67 | { 68 | //unsigned n = wcslen(text); 69 | assert(false); 70 | } 71 | else 72 | print(text); 73 | } 74 | #if defined(WINDOWS) 75 | virtual void print(const WCHAR* text) { OutputDebugStringW(text); } 76 | virtual void print(const char* text) { OutputDebugStringA(text); } 77 | #elif defined(OSX) || defined(LINUX) 78 | virtual void print(const WCHAR* text) { std::cout << aux::w2a(text).c_str(); } 79 | virtual void print(const char* text) { std::cout << text; } 80 | #endif 81 | 82 | void printf( const char* fmt, ... ) 83 | { 84 | char buffer [ 2049 ]; 85 | va_list args; 86 | va_start ( args, fmt ); 87 | #if _MSC_VER == 1400 88 | int len = vsnprintf( buffer, sizeof(buffer), _TRUNCATE, fmt, args ); 89 | #else 90 | int len = vsnprintf( buffer, sizeof(buffer), fmt, args ); 91 | #endif 92 | va_end ( args ); 93 | buffer [ len ] = 0; 94 | buffer [ 2048 ] = 0; 95 | print(buffer); 96 | } 97 | 98 | /* void printf( const WCHAR* fmt, ... ) 99 | { 100 | WCHAR buffer [ 2049 ]; 101 | va_list args; 102 | va_start ( args, fmt ); 103 | #if defined(WINDOWS) 104 | int len = vswprintf_s( buffer, fmt, args ); 105 | #elif defined(OSX) 106 | int len = vswprintf( buffer, 2048, fmt, args ); 107 | #endif 108 | va_end ( args ); 109 | buffer [ len ] = 0; 110 | buffer [ 2048 ] = 0; 111 | print(buffer); 112 | } */ 113 | 114 | 115 | }; 116 | 117 | struct debug_output_console: public debug_output 118 | { 119 | 120 | #ifdef _WIN32_WCE 121 | FILE *f; 122 | ~debug_output_console() 123 | { 124 | fclose(f); 125 | } 126 | #endif 127 | debug_output_console():debug_output() 128 | { 129 | #ifdef _WINCE32_WCE 130 | f = 0; 131 | #endif 132 | } 133 | #if !defined(_WIN32_WCE) 134 | virtual void print(const WCHAR* text) /*override*/ 135 | { 136 | print(aux::w2oem(text)); 137 | } 138 | virtual void print(const char* text) /*override*/ 139 | { 140 | #if defined(WINDOWS) 141 | static bool initialized = false; 142 | if(!initialized) 143 | { 144 | AllocConsole(); 145 | #pragma warning( push ) 146 | #pragma warning(disable:4996) 147 | freopen("conin$", "r", stdin); 148 | freopen("conout$", "w", stdout); 149 | freopen("conout$", "w", stderr); 150 | #if 0 151 | DWORD cm; 152 | if(GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE),&cm)) 153 | SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), cm | ENABLE_VIRTUAL_TERMINAL_INPUT); 154 | if (GetConsoleMode(GetStdHandle(STD_ERROR_HANDLE), &cm)) 155 | SetConsoleMode(GetStdHandle(STD_ERROR_HANDLE), cm | ENABLE_VIRTUAL_TERMINAL_INPUT); 156 | #endif 157 | #pragma warning( pop ) 158 | initialized = true; 159 | } 160 | #endif 161 | while(text && *text) { 162 | char c = *text++; 163 | if(c == '\r') 164 | putchar('\n'); 165 | else 166 | putchar(c); 167 | } 168 | } 169 | #else 170 | virtual void print(const WCHAR* text) /*override*/ 171 | { 172 | if( !f ) 173 | f = fopen("\\mosciter.log", "wb"); 174 | fputws(text, f); 175 | } 176 | virtual void print(const char* text) /*override*/ 177 | { 178 | if( !f ) 179 | f = fopen("\\mosciter.log", "wb"); 180 | fputs(text, f); 181 | } 182 | #endif 183 | 184 | }; 185 | 186 | } 187 | 188 | #endif 189 | 190 | #endif 191 | -------------------------------------------------------------------------------- /include/sciter-x-lite-keycodes.h: -------------------------------------------------------------------------------- 1 | #ifndef __sciter_lite_keycodes_h__ 2 | #define __sciter_lite_keycodes_h__ 3 | 4 | enum KEYBOARD_CODES { // table matches GLFW table 5 | 6 | KB_SPACE = 32, 7 | KB_APOSTROPHE = 39, /* ' */ 8 | KB_COMMA = 44, /* , */ KB_QUOTE = KB_COMMA, 9 | KB_MINUS = 45, /* - */ 10 | KB_PERIOD = 46, /* . */ 11 | KB_SLASH = 47, /* / */ 12 | KB_0 = 48, 13 | KB_1 = 49, 14 | KB_2 = 50, 15 | KB_3 = 51, 16 | KB_4 = 52, 17 | KB_5 = 53, 18 | KB_6 = 54, 19 | KB_7 = 55, 20 | KB_8 = 56, 21 | KB_9 = 57, 22 | KB_SEMICOLON = 59, /* ; */ 23 | KB_EQUAL = 61, /* = */ 24 | KB_A = 65, 25 | KB_B = 66, 26 | KB_C = 67, 27 | KB_D = 68, 28 | KB_E = 69, 29 | KB_F = 70, 30 | KB_G = 71, 31 | KB_H = 72, 32 | KB_I = 73, 33 | KB_J = 74, 34 | KB_K = 75, 35 | KB_L = 76, 36 | KB_M = 77, 37 | KB_N = 78, 38 | KB_O = 79, 39 | KB_P = 80, 40 | KB_Q = 81, 41 | KB_R = 82, 42 | KB_S = 83, 43 | KB_T = 84, 44 | KB_U = 85, 45 | KB_V = 86, 46 | KB_W = 87, 47 | KB_X = 88, 48 | KB_Y = 89, 49 | KB_Z = 90, 50 | KB_LEFT_BRACKET = 91, /* [ */ KB_LEFTBRACKET = KB_LEFT_BRACKET, 51 | KB_BACKSLASH = 92, /* \ */ 52 | KB_RIGHT_BRACKET = 93, /* ] */ KB_RIGHTBRACKET = KB_RIGHT_BRACKET, 53 | KB_GRAVE_ACCENT = 96, /* ` */ 54 | KB_WORLD_1 = 161, /* non-US #1 */ KB_DOT = KB_WORLD_1, 55 | KB_WORLD_2 = 162, /* non-US #2 */ 56 | 57 | /* Function keys */ 58 | KB_ESCAPE = 256, 59 | KB_ENTER = 257, KB_RETURN = KB_ENTER, 60 | KB_TAB = 258, 61 | KB_BACKSPACE = 259, KB_BACK = KB_BACKSPACE, 62 | KB_INSERT = 260, 63 | KB_DELETE = 261, 64 | KB_RIGHT = 262, 65 | KB_LEFT = 263, 66 | KB_DOWN = 264, 67 | KB_UP = 265, 68 | KB_PAGE_UP = 266, KB_PRIOR = KB_PAGE_UP, 69 | KB_PAGE_DOWN = 267, KB_NEXT = KB_PAGE_DOWN, 70 | KB_HOME = 268, 71 | KB_END = 269, 72 | KB_CAPS_LOCK = 280, KB_CAPITAL = KB_CAPS_LOCK, 73 | KB_SCROLL_LOCK = 281, KB_SCROLL = KB_SCROLL_LOCK, 74 | KB_NUM_LOCK = 282, KB_NUMLOCK = KB_NUM_LOCK, 75 | KB_PRINT_SCREEN = 283, 76 | KB_PAUSE = 284, 77 | KB_F1 = 290, 78 | KB_F2 = 291, 79 | KB_F3 = 292, 80 | KB_F4 = 293, 81 | KB_F5 = 294, 82 | KB_F6 = 295, 83 | KB_F7 = 296, 84 | KB_F8 = 297, 85 | KB_F9 = 298, 86 | KB_F10 = 299, 87 | KB_F11 = 300, 88 | KB_F12 = 301, 89 | KB_F13 = 302, 90 | KB_F14 = 303, 91 | KB_F15 = 304, 92 | KB_F16 = 305, 93 | KB_F17 = 306, 94 | KB_F18 = 307, 95 | KB_F19 = 308, 96 | KB_F20 = 309, 97 | KB_F21 = 310, 98 | KB_F22 = 311, 99 | KB_F23 = 312, 100 | KB_F24 = 313, 101 | KB_F25 = 314, 102 | KB_NUMPAD0 = 320, 103 | KB_NUMPAD1 = 321, 104 | KB_NUMPAD2 = 322, 105 | KB_NUMPAD3 = 323, 106 | KB_NUMPAD4 = 324, 107 | KB_NUMPAD5 = 325, 108 | KB_NUMPAD6 = 326, 109 | KB_NUMPAD7 = 327, 110 | KB_NUMPAD8 = 328, 111 | KB_NUMPAD9 = 329, 112 | KB_NUMPAD_DECIMAL = 330, KB_DECIMAL = KB_NUMPAD_DECIMAL, KB_SEPARATOR = KB_DECIMAL, 113 | KB_NUMPAD_DIVIDE = 331, KB_DIVIDE = KB_NUMPAD_DIVIDE, 114 | KB_NUMPAD_MULTIPLY = 332, KB_MULTIPLY = KB_NUMPAD_MULTIPLY, 115 | KB_NUMPAD_SUBTRACT = 333, KB_SUBTRACT = KB_NUMPAD_SUBTRACT, 116 | KB_NUMPAD_ADD = 334, KB_ADD = KB_NUMPAD_ADD, KB_PLUS = KB_ADD, 117 | KB_NUMPAD_ENTER = 335, 118 | KB_NUMPAD_EQUAL = 336, 119 | KB_LEFT_SHIFT = 340, KB_SHIFT = KB_LEFT_SHIFT, 120 | KB_LEFT_CONTROL = 341, KB_CONTROL = KB_LEFT_CONTROL, KB_SHORTCUT = KB_CONTROL, 121 | KB_LEFT_ALT = 342, 122 | KB_LEFT_SUPER = 343, 123 | KB_RIGHT_SHIFT = 344, 124 | KB_RIGHT_CONTROL = 345, 125 | KB_RIGHT_ALT = 346, 126 | KB_RIGHT_SUPER = 347, 127 | KB_MENU = 348, 128 | }; 129 | 130 | #endif -------------------------------------------------------------------------------- /include/sciter-x-msg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The Sciter Engine of Terra Informatica Software, Inc. 3 | * http://sciter.com 4 | * 5 | * The code and information provided "as-is" without 6 | * warranty of any kind, either expressed or implied. 7 | * 8 | * (C) Terra Informatica Software, Inc. 9 | */ 10 | 11 | /* 12 | * Message definitions to be passed to SciterProcX function 13 | */ 14 | 15 | 16 | #ifndef __sciter_x_msg_h__ 17 | #define __sciter_x_msg_h__ 18 | 19 | #include "sciter-x-types.h" 20 | #include "sciter-x-def.h" 21 | 22 | /** #SCITER_X_MSG_CODE message/function identifier */ 23 | typedef enum SCITER_X_MSG_CODE { 24 | SXM_CREATE = 0, 25 | SXM_DESTROY = 1, 26 | SXM_SIZE = 2, 27 | SXM_PAINT = 3, 28 | SXM_RESOLUTION = 4, 29 | SXM_HEARTBIT = 5, 30 | SXM_MOUSE = 6, 31 | SXM_KEY = 7, 32 | SXM_FOCUS = 8, 33 | } SCITER_X_MSG_CODE; 34 | 35 | /** #SCITER_X_MSG common header of message structures passed to SciterProcX */ 36 | typedef struct SCITER_X_MSG 37 | { 38 | UINT msg; /**< [in] one of the codes of #SCITER_X_MSG_CODE.*/ 39 | #ifdef __cplusplus 40 | SCITER_X_MSG(UINT m) : msg(m) {} 41 | #endif 42 | } SCITER_X_MSG; 43 | 44 | typedef struct SCITER_X_MSG_CREATE 45 | { 46 | SCITER_X_MSG header; 47 | UINT backend; 48 | SBOOL transparent; 49 | #ifdef __cplusplus 50 | SCITER_X_MSG_CREATE(UINT backendType = GFX_LAYER_SKIA_OPENGL, SBOOL isTransparent = TRUE ) 51 | : header(SXM_CREATE), backend(backendType), transparent(isTransparent) {} 52 | #endif 53 | } SCITER_X_MSG_CREATE; 54 | 55 | typedef struct SCITER_X_MSG_DESTROY { 56 | SCITER_X_MSG header; 57 | #ifdef __cplusplus 58 | SCITER_X_MSG_DESTROY() : header(SXM_DESTROY) {} 59 | #endif 60 | } SCITER_X_MSG_DESTROY; 61 | 62 | typedef struct SCITER_X_MSG_SIZE { 63 | SCITER_X_MSG header; 64 | UINT width; 65 | UINT height; 66 | #ifdef __cplusplus 67 | SCITER_X_MSG_SIZE(UINT w, UINT h) : header(SXM_SIZE), width(w), height(h) {} 68 | #endif 69 | } SCITER_X_MSG_SIZE; 70 | 71 | typedef struct SCITER_X_MSG_RESOLUTION { 72 | SCITER_X_MSG header; 73 | UINT pixelsPerInch; 74 | #ifdef __cplusplus 75 | SCITER_X_MSG_RESOLUTION(UINT ppi) : header(SXM_RESOLUTION), pixelsPerInch(ppi) {} 76 | #endif 77 | } SCITER_X_MSG_RESOLUTION; 78 | 79 | typedef struct SCITER_X_MSG_MOUSE { 80 | SCITER_X_MSG header; 81 | enum MOUSE_EVENTS event; 82 | enum MOUSE_BUTTONS button; 83 | enum KEYBOARD_STATES modifiers; 84 | POINT pos; 85 | #ifdef __cplusplus 86 | SCITER_X_MSG_MOUSE(MOUSE_EVENTS e, MOUSE_BUTTONS b, KEYBOARD_STATES mods, POINT p) : header(SXM_MOUSE), event(e), button(b), modifiers(mods), pos(p) {} 87 | #endif 88 | } SCITER_X_MSG_MOUSE; 89 | 90 | typedef struct SCITER_X_MSG_KEY { 91 | SCITER_X_MSG header; 92 | enum KEY_EVENTS event; 93 | UINT code; 94 | enum KEYBOARD_STATES modifiers; 95 | #ifdef __cplusplus 96 | SCITER_X_MSG_KEY(KEY_EVENTS e, UINT c, KEYBOARD_STATES mods) : header(SXM_KEY), event(e), code(c), modifiers(mods) {} 97 | #endif 98 | } SCITER_X_MSG_KEY; 99 | 100 | typedef struct SCITER_X_MSG_FOCUS { 101 | SCITER_X_MSG header; 102 | SBOOL got; // true - got, false - lost 103 | #ifdef __cplusplus 104 | SCITER_X_MSG_FOCUS(SBOOL g) : header(SXM_FOCUS), got(g) {} 105 | #endif 106 | } SCITER_X_MSG_FOCUS; 107 | 108 | 109 | typedef struct SCITER_X_MSG_HEARTBIT { 110 | SCITER_X_MSG header; 111 | UINT time; 112 | #ifdef __cplusplus 113 | SCITER_X_MSG_HEARTBIT(UINT t) : header(SXM_HEARTBIT), time(t) {} 114 | #endif 115 | } SCITER_X_MSG_HEARTBIT; 116 | 117 | 118 | /** #ELEMENT_BITMAP_RECEIVER - callback function that receives pointer to pixmap and location 119 | * \param[in] bgra \b LPCBYTE, pointer to BGRA bitmap, number of bytes = width * height * 4 120 | * \param[in] x \b INT, position of the bitmap on elements window. 121 | * \param[in] y \b INT, position of the bitmap on elements window. 122 | * \param[in] width \b UINT, width of bitmap (and element's shape). 123 | * \param[in] height \b UINT, height of bitmap (and element's shape). 124 | * \param[in] param \b LPVOID, param that passed as SCITER_X_MSG_PAINT::receiver::param . 125 | **/ 126 | typedef VOID SC_CALLBACK ELEMENT_BITMAP_RECEIVER(LPCBYTE rgba, INT x, INT y, UINT width, UINT height, LPVOID param); 127 | 128 | /** #SCITER_X_MSG_PAINT target identifier. */ 129 | typedef enum SCITER_PAINT_TARGET_TYPE { 130 | SPT_DEFAULT = 0, /**< default rendering target - window surface */ 131 | SPT_RECEIVER = 1, /**< target::receiver fields are valid */ 132 | SPT_SURFACE = 2, /**< target::pSurface is valid */ 133 | //SPT_OPENGL = 3, /**< target is not used - caller shall set current context on its side */ 134 | //SPT_OPENGLES = 4, /**< target is not used - caller shall set current context on its side */ 135 | //SPT_ 136 | } SCITER_PAINT_TARGET_TYPE; 137 | 138 | typedef struct SCITER_X_MSG_PAINT { 139 | SCITER_X_MSG header; 140 | HELEMENT element; /**< [in] layer #HELEMENT, can be NULL if whole tree (document) needs to be rendered.*/ 141 | SBOOL isFore; /**< [in] if element is not null tells if that element is fore-layer.*/ 142 | UINT targetType; /**< [in] one of #SCITER_PAINT_TARGET_TYPE values */ 143 | union { 144 | LPVOID pSurface; /**< [in] must be IDXGISurface* */ 145 | struct { 146 | VOID* param; 147 | ELEMENT_BITMAP_RECEIVER* callback; 148 | } receiver; 149 | } target; 150 | 151 | #ifdef __cplusplus 152 | SCITER_X_MSG_PAINT(HELEMENT layerElement = NULL, SBOOL foreLayer = TRUE) : header(SXM_PAINT), element(layerElement), isFore(foreLayer), targetType(SPT_DEFAULT) {} 153 | #endif 154 | } SCITER_X_MSG_PAINT; 155 | 156 | #endif 157 | -------------------------------------------------------------------------------- /include/sciter-x-request.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The Sciter Engine of Terra Informatica Software, Inc. 3 | * http://sciter.com 4 | * 5 | * The code and information provided "as-is" without 6 | * warranty of any kind, either expressed or implied. 7 | * 8 | * (C) Terra Informatica Software, Inc. 9 | */ 10 | 11 | /* 12 | * Sciter's get resource request object - represents requests made by Element/View.request() functions. 13 | * 14 | */ 15 | 16 | 17 | #ifndef __sciter_request_h__ 18 | #define __sciter_request_h__ 19 | 20 | #include "sciter-x-types.h" 21 | 22 | #if defined(__cplusplus) 23 | namespace html 24 | { 25 | struct request; 26 | } 27 | typedef html::request* HREQUEST; 28 | #else 29 | typedef void* HREQUEST; 30 | #endif 31 | 32 | typedef enum REQUEST_RESULT 33 | { 34 | REQUEST_PANIC = -1, // e.g. not enough memory 35 | REQUEST_OK = 0, 36 | REQUEST_BAD_PARAM = 1, // bad parameter 37 | REQUEST_FAILURE = 2, // operation failed, e.g. index out of bounds 38 | REQUEST_NOTSUPPORTED = 3 // the platform does not support requested feature 39 | } REQUEST_RESULT; 40 | 41 | typedef enum REQUEST_RQ_TYPE 42 | { 43 | RRT_GET = 1, 44 | RRT_POST = 2, 45 | RRT_PUT = 3, 46 | RRT_DELETE = 4, 47 | 48 | RRT_FORCE_DWORD = 0xffffffff 49 | } REQUEST_RQ_TYPE; 50 | 51 | typedef enum SciterResourceType 52 | { 53 | RT_DATA_HTML = 0, 54 | RT_DATA_IMAGE = 1, 55 | RT_DATA_STYLE = 2, 56 | RT_DATA_CURSOR = 3, 57 | RT_DATA_SCRIPT = 4, 58 | RT_DATA_RAW = 5, 59 | RT_DATA_FONT, 60 | RT_DATA_SOUND, // wav bytes 61 | RT_DATA_FORCE_DWORD = 0xffffffff 62 | } SciterResourceType; 63 | 64 | typedef enum REQUEST_STATE 65 | { 66 | RS_PENDING = 0, 67 | RS_SUCCESS = 1, // completed successfully 68 | RS_FAILURE = 2, // completed with failure 69 | 70 | RS_FORCE_DWORD = 0xffffffff 71 | } REQUEST_STATE; 72 | 73 | struct SciterRequestAPI 74 | { 75 | // a.k.a AddRef() 76 | REQUEST_RESULT 77 | SCFN(RequestUse)( HREQUEST rq ); 78 | 79 | // a.k.a Release() 80 | REQUEST_RESULT 81 | SCFN(RequestUnUse)( HREQUEST rq ); 82 | 83 | // get requested URL 84 | REQUEST_RESULT 85 | SCFN(RequestUrl)( HREQUEST rq, LPCSTR_RECEIVER* rcv, LPVOID rcv_param ); 86 | 87 | // get real, content URL (after possible redirection) 88 | REQUEST_RESULT 89 | SCFN(RequestContentUrl)( HREQUEST rq, LPCSTR_RECEIVER* rcv, LPVOID rcv_param ); 90 | 91 | // get requested data type 92 | REQUEST_RESULT 93 | SCFN(RequestGetRequestType)( HREQUEST rq, REQUEST_RQ_TYPE* pType ); 94 | 95 | // get requested data type 96 | REQUEST_RESULT 97 | SCFN(RequestGetRequestedDataType)( HREQUEST rq, SciterResourceType* pData ); 98 | 99 | // get received data type, string, mime type 100 | REQUEST_RESULT 101 | SCFN(RequestGetReceivedDataType)( HREQUEST rq, LPCSTR_RECEIVER* rcv, LPVOID rcv_param ); 102 | 103 | 104 | // get number of request parameters passed 105 | REQUEST_RESULT 106 | SCFN(RequestGetNumberOfParameters)( HREQUEST rq, UINT* pNumber ); 107 | 108 | // get nth request parameter name 109 | REQUEST_RESULT 110 | SCFN(RequestGetNthParameterName)( HREQUEST rq, UINT n, LPCWSTR_RECEIVER* rcv, LPVOID rcv_param ); 111 | 112 | // get nth request parameter value 113 | REQUEST_RESULT 114 | SCFN(RequestGetNthParameterValue)( HREQUEST rq, UINT n, LPCWSTR_RECEIVER* rcv, LPVOID rcv_param ); 115 | 116 | // get request times , ended - started = milliseconds to get the requst 117 | REQUEST_RESULT 118 | SCFN(RequestGetTimes)( HREQUEST rq, UINT* pStarted, UINT* pEnded ); 119 | 120 | // get number of request headers 121 | REQUEST_RESULT 122 | SCFN(RequestGetNumberOfRqHeaders)( HREQUEST rq, UINT* pNumber ); 123 | 124 | // get nth request header name 125 | REQUEST_RESULT 126 | SCFN(RequestGetNthRqHeaderName)( HREQUEST rq, UINT n, LPCWSTR_RECEIVER* rcv, LPVOID rcv_param ); 127 | 128 | // get nth request header value 129 | REQUEST_RESULT 130 | SCFN(RequestGetNthRqHeaderValue)( HREQUEST rq, UINT n, LPCWSTR_RECEIVER* rcv, LPVOID rcv_param ); 131 | 132 | // get number of response headers 133 | REQUEST_RESULT 134 | SCFN(RequestGetNumberOfRspHeaders)( HREQUEST rq, UINT* pNumber ); 135 | 136 | // get nth response header name 137 | REQUEST_RESULT 138 | SCFN(RequestGetNthRspHeaderName)( HREQUEST rq, UINT n, LPCWSTR_RECEIVER* rcv, LPVOID rcv_param ); 139 | 140 | // get nth response header value 141 | REQUEST_RESULT 142 | SCFN(RequestGetNthRspHeaderValue)( HREQUEST rq, UINT n, LPCWSTR_RECEIVER* rcv, LPVOID rcv_param ); 143 | 144 | // get completion status (CompletionStatus - http response code : 200, 404, etc.) 145 | REQUEST_RESULT 146 | SCFN(RequestGetCompletionStatus)( HREQUEST rq, REQUEST_STATE* pState, UINT* pCompletionStatus ); 147 | 148 | // get proxy host 149 | REQUEST_RESULT 150 | SCFN(RequestGetProxyHost)( HREQUEST rq, LPCSTR_RECEIVER* rcv, LPVOID rcv_param ); 151 | 152 | // get proxy port 153 | REQUEST_RESULT 154 | SCFN(RequestGetProxyPort)( HREQUEST rq, UINT* pPort ); 155 | 156 | // mark reequest as complete with status and data 157 | REQUEST_RESULT 158 | SCFN(RequestSetSucceeded)( HREQUEST rq, UINT status, LPCBYTE dataOrNull, UINT dataLength); 159 | 160 | // mark reequest as complete with failure and optional data 161 | REQUEST_RESULT 162 | SCFN(RequestSetFailed)( HREQUEST rq, UINT status, LPCBYTE dataOrNull, UINT dataLength ); 163 | 164 | // append received data chunk 165 | REQUEST_RESULT 166 | SCFN(RequestAppendDataChunk)( HREQUEST rq, LPCBYTE data, UINT dataLength ); 167 | 168 | // set request header (single item) 169 | REQUEST_RESULT 170 | SCFN(RequestSetRqHeader)( HREQUEST rq, LPCWSTR name, LPCWSTR value ); 171 | 172 | // set respone header (single item) 173 | REQUEST_RESULT 174 | SCFN(RequestSetRspHeader)( HREQUEST rq, LPCWSTR name, LPCWSTR value ); 175 | 176 | // set received data type, string, mime type 177 | REQUEST_RESULT 178 | SCFN(RequestSetReceivedDataType)( HREQUEST rq, LPCSTR type ); 179 | 180 | // set received data encoding, string 181 | REQUEST_RESULT 182 | SCFN(RequestSetReceivedDataEncoding)( HREQUEST rq, LPCSTR encoding ); 183 | 184 | // get received (so far) data 185 | REQUEST_RESULT 186 | SCFN(RequestGetData)( HREQUEST rq, LPCBYTE_RECEIVER* rcv, LPVOID rcv_param ); 187 | 188 | }; 189 | 190 | typedef struct SciterRequestAPI* LPSciterRequestAPI; 191 | 192 | #endif 193 | -------------------------------------------------------------------------------- /include/sciter-x-script.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The Sciter Engine of Terra Informatica Software, Inc. 3 | * http://sciter.com 4 | * 5 | * The code and information provided "as-is" without 6 | * warranty of any kind, either expressed or implied. 7 | * 8 | * (C) 2003-2015, Terra Informatica Software, Inc. 9 | */ 10 | 11 | /* 12 | * Main include file of Sciter script primitives. 13 | */ 14 | 15 | 16 | #ifndef __sciter_x_scripting_h__ 17 | #define __sciter_x_scripting_h__ 18 | 19 | #include "sciter-x.h" 20 | #include "sciter-x-value.h" 21 | #include "tiscript.h" 22 | 23 | typedef tiscript_VM* HVM; 24 | 25 | #if defined(__cplusplus) && !defined( PLAIN_API_ONLY ) 26 | #include "tiscript.hpp" 27 | namespace sciter 28 | { 29 | OBSOLETE inline SCITER_VALUE v2v(tiscript::VM* vm, tiscript::value val, bool isolate = true) 30 | { 31 | SCITER_VALUE v; 32 | BOOL r = Sciter_v2V(vm,val,(VALUE*)&v, BOOL(isolate)); 33 | assert(r); r; 34 | return v; 35 | } 36 | OBSOLETE inline tiscript::value v2v(tiscript::VM* vm, const SCITER_VALUE& val) 37 | { 38 | tiscript::value v; 39 | BOOL r = Sciter_V2v(vm,(const VALUE*)&val,&v); 40 | assert(r); r; 41 | return v; 42 | } 43 | } 44 | #endif 45 | 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /include/sciter-x-threads.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The Sciter Engine of Terra Informatica Software, Inc. 3 | * http://sciter.com 4 | * 5 | * The code and information provided "as-is" without 6 | * warranty of any kind, either expressed or implied. 7 | * 8 | * (C) 2003-2015, Terra Informatica Software, Inc. 9 | */ 10 | 11 | /* 12 | * Asynchronous GUI Task Queue. 13 | * Use these primitives when you need to run code in GUI thread. 14 | */ 15 | 16 | 17 | #if !defined(__SCITER_THREADS_H__) 18 | #define __SCITER_THREADS_H__ 19 | 20 | #if defined(WINDOWS) 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #ifndef THIS_HINSTANCE 28 | EXTERN_C IMAGE_DOS_HEADER __ImageBase; 29 | #define THIS_HINSTANCE ((HINSTANCE)&__ImageBase) 30 | #endif 31 | 32 | 33 | namespace sciter { 34 | 35 | namespace sync { 36 | 37 | class mutex 38 | { 39 | CRITICAL_SECTION cs; 40 | public: 41 | void lock() { EnterCriticalSection(&cs); } 42 | void unlock() { LeaveCriticalSection(&cs); } 43 | mutex() { InitializeCriticalSection(&cs); } 44 | ~mutex() { DeleteCriticalSection(&cs); } 45 | }; 46 | 47 | class critical_section { 48 | mutex& m; 49 | public: 50 | critical_section(mutex& guard) : m(guard) { m.lock(); } 51 | ~critical_section() { m.unlock(); } 52 | }; 53 | 54 | struct event 55 | { 56 | HANDLE h; 57 | event() { h = CreateEvent(NULL, FALSE, FALSE, NULL); } 58 | ~event() { CloseHandle(h); } 59 | void signal() { SetEvent(h); } 60 | bool wait(unsigned int ms = INFINITE) { return WaitForSingleObject(h, ms) == WAIT_OBJECT_0; } 61 | private: 62 | event( const event& ); 63 | event& operator=( const event& ); 64 | }; 65 | 66 | inline void yield() { Sleep(0); } 67 | inline void sleep(unsigned ms) { Sleep(ms); } 68 | 69 | class gui_thread_ctx 70 | { 71 | HHOOK _hook; 72 | 73 | typedef std::function gui_block; 74 | 75 | static DWORD thread_id() 76 | { 77 | static DWORD _thread_id = ::GetCurrentThreadId(); 78 | return _thread_id; 79 | } 80 | static UINT message() 81 | { 82 | static UINT _message = ::RegisterWindowMessage( TEXT("GUI-THREAD-EXEC_RQ")); 83 | return _message; 84 | } 85 | 86 | void install_hook() 87 | { 88 | message(); // force message to be registered 89 | // setup the WH_GETMESSAGE hook. 90 | // Using hooks here allows this mechanism to work even under modal dialogs. 91 | _hook = ::SetWindowsHookEx(WH_GETMESSAGE,&exec_hook,THIS_HINSTANCE, thread_id()); 92 | } 93 | void release_hook() 94 | { 95 | if(_hook) ::UnhookWindowsHookEx(_hook); 96 | } 97 | 98 | // message hook to handle WM_EXEC in GUI thread 99 | static LRESULT CALLBACK exec_hook(int code, WPARAM wParam, LPARAM lParam ) 100 | { 101 | MSG* pmsg = reinterpret_cast(lParam); 102 | if(wParam == PM_REMOVE && pmsg->message == message()) 103 | { 104 | event* pe = reinterpret_cast(pmsg->wParam); 105 | gui_block* pf = reinterpret_cast(pmsg->lParam); 106 | (*pf)(); // execute the block in this GUI thread 107 | pe->signal(); // signal that we've done with it 108 | // this will resume execution of worker thread. 109 | } 110 | return CallNextHookEx(0,code, wParam,lParam); 111 | } 112 | 113 | public: 114 | gui_thread_ctx() { install_hook(); } 115 | ~gui_thread_ctx() { release_hook(); } 116 | 117 | // this function is called from worker threads to 118 | // execute the gui_block in GUI thread 119 | static void exec( gui_block code ) 120 | { 121 | event evt; 122 | PostThreadMessage(thread_id(), message(), WPARAM(&evt),LPARAM(&code)); 123 | evt.wait(); // suspend worker thread until GUI will execute the block. 124 | } 125 | 126 | }; 127 | 128 | #define GUI_CODE_START sciter::sync::gui_thread_ctx::exec([&]() { 129 | #define GUI_CODE_END }); 130 | 131 | } 132 | 133 | template 134 | class thread_ctx 135 | { 136 | F _f; 137 | P _p; 138 | static DWORD WINAPI ThreadProc(LPVOID lpData) 139 | { 140 | thread_ctx* self = reinterpret_cast(lpData); 141 | try { 142 | self->_f(self->_p); 143 | } 144 | catch(...) { 145 | assert(false); 146 | } 147 | delete self; 148 | return 0; 149 | } 150 | thread_ctx(const F& f, const P& p): _f(f),_p(p) { 151 | 152 | DWORD dwThreadID; 153 | HANDLE hThread = ::CreateThread(NULL, 0, ThreadProc, this, 0, &dwThreadID); 154 | assert(hThread != NULL); 155 | ::CloseHandle(hThread); 156 | } 157 | public: 158 | static void start( const F& f, const P& p ) 159 | { 160 | new thread_ctx(f,p); 161 | } 162 | }; 163 | 164 | template 165 | inline void thread( F f, P p ) 166 | { 167 | thread_ctx::start(f,p); 168 | } 169 | 170 | } 171 | 172 | #else 173 | 174 | #include 175 | #include 176 | #include 177 | #include 178 | 179 | namespace sciter { 180 | 181 | namespace sync { 182 | 183 | class mutex :public std::recursive_mutex 184 | { 185 | friend class event; 186 | typedef std::recursive_mutex super; 187 | mutex( const mutex& ) = delete; 188 | mutex& operator=(const mutex&) = delete; 189 | public: 190 | mutex():super() {} 191 | //void lock() { super::lock(); } 192 | //void unlock() { super::unlock(); } 193 | }; 194 | 195 | class critical_section: public std::lock_guard 196 | { 197 | typedef std::lock_guard super; 198 | critical_section(const critical_section& rs) = delete; 199 | critical_section& operator=(const critical_section&) = delete; 200 | 201 | public: 202 | critical_section(mutex& m) : super(m) {} 203 | ~critical_section() {} 204 | }; 205 | 206 | class event 207 | { 208 | //typedef std::condition_variable super; 209 | event( const event& ) = delete; 210 | event& operator=(const event&) = delete; 211 | 212 | std::condition_variable_any _var; 213 | std::mutex _mtx; 214 | public: 215 | event() {} 216 | void signal() { 217 | _var.notify_one(); 218 | } 219 | void wait(mutex& m) { 220 | std::unique_lock lock(m); 221 | _var.wait(lock); 222 | } 223 | void wait(unsigned int ms = unsigned(-1)) { 224 | std::unique_lock lock(_mtx); 225 | if( ms == unsigned(-1) ) 226 | _var.wait(lock); 227 | else 228 | _var.wait_for(lock, std::chrono::milliseconds(ms)); 229 | } 230 | 231 | }; 232 | 233 | inline void sleep(uint ms) { std::this_thread::sleep_for(std::chrono::milliseconds(ms)); } 234 | inline void yield() { std::this_thread::yield(); } 235 | 236 | } 237 | template 238 | inline void thread( F f, P p ) 239 | { 240 | std::thread(f,p).detach(); 241 | } 242 | 243 | } 244 | 245 | #endif 246 | 247 | #endif // __SCITER_THREADS_H__ 248 | -------------------------------------------------------------------------------- /include/sciter-x-types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The Sciter Engine of Terra Informatica Software, Inc. 3 | * http://sciter.com 4 | * 5 | * The code and information provided "as-is" without 6 | * warranty of any kind, either expressed or implied. 7 | * 8 | * (C) 2003-2015, Terra Informatica Software, Inc. 9 | */ 10 | 11 | /* 12 | * Sciter basic types, platform isolation declarations 13 | */ 14 | 15 | #ifndef sciter_sciter_x_types_h 16 | #define sciter_sciter_x_types_h 17 | 18 | #ifdef __cplusplus 19 | 20 | #if __cplusplus >= 201103L 21 | #define CPP11 22 | #elif _MSC_VER >= 1600 23 | #define CPP11 24 | #endif 25 | #include 26 | #else 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | typedef uint16_t char16_t; 33 | typedef uint32_t char32_t; 34 | 35 | #endif 36 | 37 | enum GFX_LAYER 38 | { 39 | GFX_LAYER_GDI = 1, GFX_LAYER_CG = 1, /*Mac OS*/ GFX_LAYER_CAIRO = 1, /*GTK*/ 40 | GFX_LAYER_WARP = 2, GFX_LAYER_D2D_WARP = 2, 41 | GFX_LAYER_D2D = 3, 42 | GFX_LAYER_SKIA = 4, 43 | GFX_LAYER_SKIA_OPENGL = 5, 44 | GFX_LAYER_AUTO = 0xFFFF, 45 | }; 46 | 47 | #if defined(SCITER_LITE) 48 | #define WINDOWLESS 49 | #endif 50 | 51 | #ifndef SBOOL 52 | typedef int SBOOL; 53 | #endif 54 | #ifndef TRUE 55 | #define TRUE (1) 56 | #define FALSE (0) 57 | #endif 58 | 59 | #if defined(_WIN32) || defined(_WIN64) 60 | 61 | #define WINDOWS 62 | 63 | #elif defined(__APPLE__) 64 | #include "TargetConditionals.h" 65 | 66 | #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE 67 | #define IOS 68 | #elif TARGET_OS_MAC 69 | #define OSX 70 | #else 71 | #error "This platform is not supported yet" 72 | #endif 73 | 74 | #elif defined(__ANDROID__) 75 | #ifndef ANDROID 76 | #define ANDROID 77 | #endif 78 | #ifndef WINDOWLESS 79 | #define WINDOWLESS 80 | #endif 81 | #elif defined(__linux__) 82 | #ifndef LINUX 83 | #define LINUX 84 | #endif 85 | #else 86 | #error "This platform is not supported yet" 87 | #endif 88 | 89 | #if defined(WINDOWS) 90 | #define WIN32_LEAN_AND_MEAN 91 | #define _WINSOCKAPI_ 92 | #include 93 | #include 94 | #include 95 | 96 | #if defined(_MSC_VER) && _MSC_VER < 1900 97 | // Microsoft has finally implemented snprintf in Visual Studio 2015. 98 | #define snprintf _snprintf_s 99 | #define vsnprintf vsnprintf_s 100 | #endif 101 | 102 | //#if __STDC_WANT_SECURE_LIB__ 103 | //// use the safe version of `wcsncpy` if wanted 104 | // #define wcsncpy wcsncpy_s 105 | //#endif 106 | 107 | #ifdef STATIC_LIB 108 | void SciterInit( bool start); 109 | #endif 110 | 111 | #define SCAPI __stdcall 112 | #define SCFN(name) (__stdcall *name) 113 | 114 | #if defined(WINDOWLESS) 115 | #define HWINDOW LPVOID 116 | #else 117 | #define HWINDOW HWND 118 | #endif 119 | 120 | #define SC_CALLBACK __stdcall 121 | 122 | typedef wchar_t wchar; 123 | 124 | #define SCITER_DLL_NAME "sciter.dll" 125 | 126 | #ifdef _WIN64 127 | #define TARGET_64 128 | #else 129 | #define TARGET_32 130 | #endif 131 | 132 | #elif defined(OSX) 133 | 134 | //#ifdef __OBJC__ 135 | // #define char16_t uint16_t 136 | //#endif 137 | 138 | typedef unsigned int UINT; 139 | typedef int INT; 140 | typedef unsigned int UINT32; 141 | typedef int INT32; 142 | typedef unsigned long long UINT64; 143 | typedef long long INT64; 144 | 145 | typedef unsigned char BYTE; 146 | typedef char16_t WCHAR; 147 | typedef const WCHAR* LPCWSTR; 148 | typedef WCHAR* LPWSTR; 149 | typedef char CHAR; 150 | typedef const CHAR* LPCSTR; 151 | typedef void VOID; 152 | typedef size_t UINT_PTR; 153 | typedef void* LPVOID; 154 | typedef const void* LPCVOID; 155 | 156 | #define SCAPI 157 | #define SCFN(name) (*name) 158 | #define SC_CALLBACK 159 | #define CALLBACK 160 | 161 | typedef struct tagRECT 162 | { 163 | INT left; 164 | INT top; 165 | INT right; 166 | INT bottom; 167 | } RECT, *LPRECT; 168 | typedef const RECT * LPCRECT; 169 | 170 | typedef struct tagPOINT 171 | { 172 | INT x; 173 | INT y; 174 | } POINT, *PPOINT, *LPPOINT; 175 | 176 | typedef struct tagSIZE 177 | { 178 | INT cx; 179 | INT cy; 180 | } SIZE, *PSIZE, *LPSIZE; 181 | 182 | #define HWINDOW LPVOID // NSView* 183 | #define HINSTANCE LPVOID // NSApplication* 184 | #define HDC void* // CGContextRef 185 | 186 | #define LRESULT long 187 | 188 | #define SCITER_DLL_NAME "libsciter.dylib" 189 | 190 | #elif defined(LINUX) 191 | 192 | #if !defined(WINDOWLESS) 193 | #include 194 | #endif 195 | #include 196 | #include 197 | 198 | typedef unsigned int UINT; 199 | typedef int INT; 200 | typedef unsigned int UINT32; 201 | typedef int INT32; 202 | typedef unsigned long long UINT64; 203 | typedef long long INT64; 204 | 205 | typedef unsigned char BYTE; 206 | typedef char16_t WCHAR; 207 | typedef const WCHAR* LPCWSTR; 208 | typedef WCHAR* LPWSTR; 209 | typedef char CHAR; 210 | typedef const CHAR* LPCSTR; 211 | typedef void VOID; 212 | typedef size_t UINT_PTR; 213 | typedef void* LPVOID; 214 | typedef const void* LPCVOID; 215 | 216 | #define SCAPI 217 | #define SCFN(name) (*name) 218 | #define SC_CALLBACK 219 | 220 | typedef struct tagRECT 221 | { 222 | INT left; 223 | INT top; 224 | INT right; 225 | INT bottom; 226 | } RECT, *LPRECT; 227 | typedef const RECT * LPCRECT; 228 | 229 | typedef struct tagPOINT 230 | { 231 | INT x; 232 | INT y; 233 | } POINT, *PPOINT, *LPPOINT; 234 | 235 | typedef struct tagSIZE 236 | { 237 | INT cx; 238 | INT cy; 239 | } SIZE, *PSIZE, *LPSIZE; 240 | 241 | #if defined(WINDOWLESS) 242 | #define HWINDOW void * 243 | #else 244 | #define HWINDOW GtkWidget* // 245 | #endif 246 | 247 | #define HINSTANCE LPVOID // 248 | #define LRESULT long 249 | #define HDC LPVOID // cairo_t 250 | 251 | #if defined(ARM) || defined(__arm__) 252 | #define TARGET_ARM 253 | #elif defined(__x86_64) 254 | #define TARGET_64 255 | #else 256 | #define TARGET_32 257 | #endif 258 | 259 | #if defined(WINDOWLESS) 260 | #define SCITER_DLL_NAME "libsciter.so" 261 | #else 262 | #define SCITER_DLL_NAME "libsciter-gtk.so" 263 | #endif 264 | 265 | #elif defined(ANDROID) 266 | 267 | #define WINDOWLESS 268 | 269 | //#include 270 | #include 271 | 272 | #ifndef SBOOL 273 | typedef signed int SBOOL; 274 | #endif 275 | #ifndef TRUE 276 | #define TRUE (1) 277 | #define FALSE (0) 278 | #endif 279 | typedef unsigned int UINT; 280 | typedef int INT; 281 | typedef unsigned long long UINT64; 282 | typedef long long INT64; 283 | 284 | typedef unsigned char BYTE; 285 | typedef char16_t WCHAR; 286 | typedef const WCHAR * LPCWSTR; 287 | typedef WCHAR * LPWSTR; 288 | typedef char CHAR; 289 | typedef const CHAR * LPCSTR; 290 | typedef void VOID; 291 | typedef size_t UINT_PTR; 292 | typedef void * LPVOID; 293 | typedef const void * LPCVOID; 294 | 295 | #define SCAPI 296 | #define SCFN(name) (*name) 297 | #define SC_CALLBACK 298 | 299 | typedef struct tagRECT { 300 | INT left; 301 | INT top; 302 | INT right; 303 | INT bottom; 304 | } RECT, *LPRECT; 305 | typedef const RECT *LPCRECT; 306 | 307 | typedef struct tagPOINT { 308 | INT x; 309 | INT y; 310 | } POINT, *PPOINT, *LPPOINT; 311 | 312 | typedef struct tagSIZE { 313 | INT cx; 314 | INT cy; 315 | } SIZE, *PSIZE, *LPSIZE; 316 | 317 | #define HWINDOW LPVOID 318 | 319 | #define HINSTANCE LPVOID // 320 | #define LRESULT long 321 | #define HDC LPVOID // not used anyway, draws on OpenGLESv2 322 | 323 | #if defined(ARM) || defined(__arm__) 324 | #define TARGET_ARM 325 | #elif defined(__x86_64) 326 | #define TARGET_64 327 | #else 328 | #define TARGET_32 329 | #endif 330 | 331 | #define SCITER_DLL_NAME "libsciter.so" 332 | 333 | #endif 334 | 335 | 336 | #if !defined(OBSOLETE) 337 | /* obsolete API marker*/ 338 | #if defined(__GNUC__) 339 | #define OBSOLETE __attribute__((deprecated)) 340 | #elif defined(_MSC_VER) && (_MSC_VER >= 1300) 341 | #define OBSOLETE __declspec(deprecated) 342 | #else 343 | #define OBSOLETE 344 | #endif 345 | #endif 346 | 347 | #ifndef LPUINT 348 | typedef UINT* LPUINT; 349 | #endif 350 | 351 | #ifndef LPCBYTE 352 | typedef const BYTE* LPCBYTE; 353 | #endif 354 | 355 | /**callback function used with various get*** functions */ 356 | typedef VOID SC_CALLBACK LPCWSTR_RECEIVER( LPCWSTR str, UINT str_length, LPVOID param ); 357 | typedef VOID SC_CALLBACK LPCSTR_RECEIVER( LPCSTR str, UINT str_length, LPVOID param ); 358 | typedef VOID SC_CALLBACK LPCBYTE_RECEIVER( LPCBYTE str, UINT num_bytes, LPVOID param ); 359 | 360 | #define STDCALL __stdcall 361 | #define HWINDOW_PTR HWINDOW* 362 | 363 | #ifdef __cplusplus 364 | 365 | #define EXTERN_C extern "C" 366 | 367 | namespace std { 368 | typedef basic_string ustring; 369 | } 370 | 371 | // Note: quote here is a string literal! 372 | #ifdef WINDOWS 373 | #define _WSTR(quote) L##quote 374 | #else 375 | #define _WSTR(quote) u##quote 376 | #endif 377 | 378 | #define WSTR(quote) ((const WCHAR*)_WSTR(quote)) 379 | 380 | inline VOID SC_CALLBACK _LPCBYTE2ASTRING(LPCBYTE bytes, UINT num_bytes, LPVOID param) 381 | { 382 | std::string* s = (std::string*)param; 383 | *s = std::string((const char*)bytes, num_bytes); 384 | } 385 | inline VOID SC_CALLBACK _LPCWSTR2STRING(LPCWSTR str, UINT str_length, LPVOID param) 386 | { 387 | std::ustring* s = (std::ustring*)param; 388 | *s = std::ustring(str, str_length); 389 | } 390 | inline VOID SC_CALLBACK _LPCSTR2ASTRING(LPCSTR str, UINT str_length, LPVOID param) 391 | { 392 | std::string* s = (std::string*)param; 393 | *s = std::string(str, str_length); 394 | } 395 | 396 | #else 397 | #define EXTERN_C extern 398 | #endif /* __cplusplus **/ 399 | 400 | 401 | #endif 402 | 403 | 404 | 405 | -------------------------------------------------------------------------------- /include/sciter-x-value.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The Sciter Engine of Terra Informatica Software, Inc. 3 | * http://sciter.com 4 | * 5 | * The code and information provided "as-is" without 6 | * warranty of any kind, either expressed or implied. 7 | * 8 | * (C) 2003-2015, Terra Informatica Software, Inc. 9 | */ 10 | 11 | /* 12 | * sciter::value, aka variant, aka discriminated union 13 | */ 14 | 15 | 16 | #ifndef __sciter_x_value_h__ 17 | #define __sciter_x_value_h__ 18 | 19 | #pragma once 20 | 21 | #define HAS_TISCRIPT 22 | 23 | #include "value.h" 24 | 25 | #if defined(__cplusplus) && !defined( PLAIN_API_ONLY ) 26 | typedef sciter::value SCITER_VALUE; 27 | #include "value.hpp" 28 | #else 29 | typedef VALUE SCITER_VALUE; 30 | #endif 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /include/sciter-x-video-api.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The Sciter Engine of Terra Informatica Software, Inc. 3 | * http://sciter.com 4 | * 5 | * The code and information provided "as-is" without 6 | * warranty of any kind, either expressed or implied. 7 | * 8 | * (C) 2003-2015, Terra Informatica Software, Inc. 9 | */ 10 | 11 | /* 12 | * Sciter's custom video rendering primitives 13 | */ 14 | 15 | #pragma once 16 | 17 | #include "aux-asset.h" 18 | #include "sciter-x-types.h" 19 | 20 | namespace sciter { 21 | 22 | enum COLOR_SPACE { 23 | COLOR_SPACE_UNKNOWN, 24 | COLOR_SPACE_YV12, 25 | COLOR_SPACE_IYUV, // a.k.a. I420 26 | COLOR_SPACE_NV12, 27 | COLOR_SPACE_YUY2, 28 | COLOR_SPACE_RGB24, 29 | COLOR_SPACE_RGB555, 30 | COLOR_SPACE_RGB565, 31 | COLOR_SPACE_RGB32 // with alpha, sic! 32 | }; 33 | 34 | #define VIDEO_SOURCE_INAME "source.video.sciter.com" 35 | 36 | struct video_source : public sciter::om::iasset 37 | { 38 | virtual bool play() = 0; 39 | virtual bool pause() = 0; 40 | virtual bool stop() = 0; 41 | virtual bool get_is_ended(bool& eos) = 0; 42 | virtual bool get_position(double& seconds) = 0; 43 | virtual bool set_position(double seconds) = 0; 44 | virtual bool get_duration(double& seconds) = 0; 45 | // audio 46 | virtual bool get_volume(double& vol) = 0; 47 | virtual bool set_volume(double vol) = 0; 48 | virtual bool get_balance(double& vol) = 0; 49 | virtual bool set_balance(double vol) = 0; 50 | }; 51 | 52 | #define VIDEO_DESTINATION_INAME "destination.video.sciter.com" 53 | 54 | // video_destination interface, represents video rendering site 55 | struct video_destination : public sciter::om::iasset 56 | { 57 | // true if this instance of video_renderer is attached to DOM element and is capable of playing. 58 | virtual bool is_alive() = 0; 59 | 60 | // start streaming/rendering 61 | virtual bool start_streaming( int frame_width // width 62 | , int frame_height // height 63 | , int color_space // COLOR_SPACE above 64 | , video_source* src = 0 ) = 0; // video_source interface implementation, can be null 65 | 66 | // stop streaming, eof. 67 | virtual bool stop_streaming() = 0; 68 | 69 | // render frame request, false - video_destination is not available ( isn't alive, document unloaded etc.) 70 | virtual bool render_frame(const BYTE* frame_data, UINT frame_data_size) = 0; 71 | 72 | }; 73 | 74 | #define FRAGMENTED_VIDEO_DESTINATION_INAME "fragmented.destination.video.sciter.com" 75 | 76 | struct fragmented_video_destination : public video_destination 77 | { 78 | // render frame part request, returns false - video_destination is not available ( isn't alive, document unloaded etc.) 79 | virtual bool render_frame_part(const BYTE* frame_data, UINT frame_data_size, int x, int y, int width, int height) = 0; 80 | 81 | }; 82 | 83 | 84 | } 85 | -------------------------------------------------------------------------------- /include/sciter-x.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The Sciter Engine of Terra Informatica Software, Inc. 3 | * http://sciter.com 4 | * 5 | * The code and information provided "as-is" without 6 | * warranty of any kind, either expressed or implied. 7 | * 8 | * 9 | * (C) 2003-2015, Terra Informatica Software, Inc. 10 | */ 11 | 12 | /* 13 | * Sciter main include file 14 | */ 15 | 16 | 17 | #ifndef __SCITER_X__ 18 | #define __SCITER_X__ 19 | 20 | #if __cplusplus > 199711L 21 | #define CPP11 22 | #elif _MSC_VER >= 1600 23 | #define CPP11 24 | #endif 25 | 26 | #include "sciter-x-types.h" 27 | #include "sciter-x-def.h" 28 | #include "sciter-x-dom.h" 29 | #include "sciter-x-value.h" 30 | #include "sciter-x-api.h" 31 | #include "sciter-x-msg.h" 32 | #include "sciter-om.h" 33 | 34 | #if defined(__cplusplus) && !defined( PLAIN_API_ONLY ) 35 | // C++, namespace sciter things 36 | #include "sciter-x-dom.hpp" 37 | #include "sciter-x-host-callback.h" 38 | #include "sciter-x-debug.h" 39 | #endif 40 | 41 | /** Signatire of Sciter extension library entry point 42 | * \param psapi #ISciterAPI - Sciter API to be used inside the DLL. 43 | * \param plibobject #SCITER_VALUE* - value to initialize, can be native functor, sciter::om::asset, array, map, etc. 44 | * \return TRUE, if it populates plibobject; 45 | * 46 | * The DLL should have function exported with the name "SciterLibraryInit" and wit this signature. 47 | * In script such sciter extension library can be imported as: 48 | * 49 | * include library "name-without-extension"; 50 | * 51 | **/ 52 | 53 | typedef SBOOL SCAPI SciterLibraryInitFunc(ISciterAPI* psapi, SCITER_VALUE* plibobject); 54 | 55 | 56 | 57 | 58 | #endif 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /include/value.h: -------------------------------------------------------------------------------- 1 | #ifndef __value_h__ 2 | #define __value_h__ 3 | 4 | #include "sciter-x-types.h" 5 | 6 | enum VALUE_RESULT 7 | { 8 | HV_OK_TRUE = -1, 9 | HV_OK = 0, 10 | HV_BAD_PARAMETER = 1, 11 | HV_INCOMPATIBLE_TYPE = 2 12 | }; 13 | 14 | typedef struct 15 | { 16 | UINT t; 17 | UINT u; 18 | UINT64 d; 19 | } VALUE; 20 | 21 | #define FLOAT_VALUE double 22 | 23 | enum VALUE_TYPE 24 | { 25 | T_UNDEFINED = 0, 26 | T_NULL = 1, 27 | T_BOOL = 2, 28 | T_INT = 3, 29 | T_FLOAT = 4, 30 | T_STRING = 5, 31 | T_DATE = 6, // INT64 - contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC), a.k.a. FILETIME on Windows 32 | T_CURRENCY = 7, // INT64 - 14.4 fixed number. E.g. dollars = int64 / 10000; 33 | T_LENGTH = 8, // length units, value is int or float, units are VALUE_UNIT_TYPE 34 | T_ARRAY = 9, 35 | T_MAP = 10, 36 | T_FUNCTION = 11, // named tuple , like array but with name tag 37 | T_BYTES = 12, // sequence of bytes - e.g. image data 38 | T_OBJECT = 13, // scripting object proxy (TISCRIPT/SCITER) 39 | //T_DOM_OBJECT = 14, // DOM object, use get_object_data to get HELEMENT 40 | T_RESOURCE = 15, // 15 - other thing derived from tool::resource 41 | //T_RANGE = 16, // 16 - N..M, integer range. 42 | T_DURATION = 17, // double, seconds 43 | T_ANGLE = 18, // double, radians 44 | T_COLOR = 19, // [unsigned] INT, ABGR 45 | T_ASSET = 21, // sciter::om::iasset* add_ref'ed pointer 46 | 47 | 48 | }; 49 | 50 | enum VALUE_UNIT_TYPE 51 | { 52 | UT_EM = 1, //height of the element's font. 53 | UT_EX = 2, //height of letter 'x' 54 | UT_PR = 3, //% 55 | UT_SP = 4, //%% "springs", a.k.a. flex units 56 | reserved1 = 5, 57 | reserved2 = 6, 58 | UT_PX = 7, //pixels 59 | UT_IN = 8, //inches (1 inch = 2.54 centimeters). 60 | UT_CM = 9, //centimeters. 61 | UT_MM = 10, //millimeters. 62 | UT_PT = 11, //points (1 point = 1/72 inches). 63 | UT_PC = 12, //picas (1 pica = 12 points). 64 | UT_DIP = 13, 65 | reserved3 = 14, 66 | reserved4 = 15, 67 | UT_URL = 16, // url in string 68 | }; 69 | 70 | enum VALUE_UNIT_TYPE_DATE 71 | { 72 | DT_HAS_DATE = 0x01, // date contains date portion 73 | DT_HAS_TIME = 0x02, // date contains time portion HH:MM 74 | DT_HAS_SECONDS = 0x04, // date contains time and seconds HH:MM:SS 75 | DT_UTC = 0x10, // T_DATE is known to be UTC. Otherwise it is local date/time 76 | }; 77 | 78 | // Sciter or TIScript specific 79 | enum VALUE_UNIT_TYPE_OBJECT 80 | { 81 | UT_OBJECT_ARRAY = 0, // type T_OBJECT of type Array 82 | UT_OBJECT_OBJECT = 1, // type T_OBJECT of type Object 83 | UT_OBJECT_CLASS = 2, // type T_OBJECT of type Class (class or namespace) 84 | UT_OBJECT_NATIVE = 3, // type T_OBJECT of native Type with data slot (LPVOID) 85 | UT_OBJECT_FUNCTION = 4, // type T_OBJECT of type Function 86 | UT_OBJECT_ERROR = 5, // type T_OBJECT of type Error 87 | }; 88 | 89 | enum VALUE_UNIT_UNDEFINED { 90 | UT_NOTHING = 1 // T_UNDEFINED && UT_NOTHING - 'nothing' a.k.a. 'void' value in script 91 | }; 92 | 93 | // Sciter or TIScript specific 94 | enum VALUE_UNIT_TYPE_STRING 95 | { 96 | UT_STRING_STRING = 0, // string 97 | UT_STRING_ERROR = 1, // is an error string 98 | UT_STRING_SECURE = 2, // secure string ("wiped" on destroy) 99 | UT_STRING_SYMBOL = 0xffff, // symbol in tiscript sense 100 | }; 101 | 102 | // Native functor 103 | typedef VOID NATIVE_FUNCTOR_INVOKE( VOID* tag, UINT argc, const VALUE* argv, VALUE* retval); // retval may contain error definition 104 | typedef VOID NATIVE_FUNCTOR_RELEASE( VOID* tag ); 105 | 106 | 107 | /** 108 | * ValueInit - initialize VALUE storage 109 | * This call has to be made before passing VALUE* to any other functions 110 | */ 111 | UINT SCAPI ValueInit( VALUE* pval ); 112 | 113 | /** 114 | * ValueClear - clears the VALUE and deallocates all assosiated structures that are not used anywhere else. 115 | */ 116 | UINT SCAPI ValueClear( VALUE* pval ); 117 | 118 | /** 119 | * ValueCompare - compares two values, returns HV_OK_TRUE if val1 == val2. 120 | */ 121 | UINT SCAPI ValueCompare( const VALUE* pval1, const VALUE* pval2 ); 122 | 123 | /** 124 | * ValueCopy - copies src VALUE to dst VALUE. dst VALUE must be in ValueInit state. 125 | */ 126 | UINT SCAPI ValueCopy( VALUE* pdst, const VALUE* psrc ); 127 | 128 | /** 129 | * ValueIsolate - converts T_OBJECT value types to T_MAP or T_ARRAY. 130 | * use this method if you need to pass values between different threads. 131 | * The fanction is applicable for the Sciter 132 | */ 133 | UINT SCAPI ValueIsolate( VALUE* pdst ); 134 | 135 | /** 136 | * ValueType - returns VALUE_TYPE and VALUE_UNIT_TYPE flags of the VALUE 137 | */ 138 | UINT SCAPI ValueType( const VALUE* pval, UINT* pType, UINT* pUnits ); 139 | 140 | /** 141 | * ValueStringData - returns string data for T_STRING type 142 | * For T_FUNCTION returns name of the fuction. 143 | */ 144 | UINT SCAPI ValueStringData( const VALUE* pval, LPCWSTR* pChars, UINT* pNumChars ); 145 | 146 | /** 147 | * ValueStringDataSet - sets VALUE to T_STRING type and copies chars/numChars to 148 | * internal refcounted buffer assosiated with the value. 149 | */ 150 | UINT SCAPI ValueStringDataSet( VALUE* pval, LPCWSTR chars, UINT numChars, UINT units ); 151 | 152 | /** 153 | * ValueIntData - retreive integer data of T_INT, T_LENGTH and T_BOOL types 154 | */ 155 | UINT SCAPI ValueIntData( const VALUE* pval, INT* pData ); 156 | 157 | /** 158 | * ValueIntDataSet - sets VALUE integer data of T_INT and T_BOOL types 159 | * Optionally sets units field too. 160 | */ 161 | UINT SCAPI ValueIntDataSet( VALUE* pval, INT data, UINT type, UINT units ); 162 | 163 | /** 164 | * ValueInt64Data - retreive 64bit integer data of T_CURRENCY and T_DATE values. 165 | */ 166 | UINT SCAPI ValueInt64Data( const VALUE* pval, INT64* pData ); 167 | 168 | /** 169 | * ValueInt64DataSet - sets 64bit integer data of T_CURRENCY and T_DATE values. 170 | */ 171 | UINT SCAPI ValueInt64DataSet( VALUE* pval, INT64 data, UINT type, UINT units ); 172 | 173 | /** 174 | * ValueFloatData - retreive FLOAT_VALUE (double) data of T_FLOAT and T_LENGTH values. 175 | */ 176 | UINT SCAPI ValueFloatData( const VALUE* pval, FLOAT_VALUE* pData ); 177 | 178 | /** 179 | * ValueFloatDataSet - sets FLOAT_VALUE data of T_FLOAT and T_LENGTH values. 180 | */ 181 | UINT SCAPI ValueFloatDataSet( VALUE* pval, FLOAT_VALUE data, UINT type, UINT units ); 182 | 183 | /** 184 | * ValueBinaryData - retreive integer data of T_BYTES type 185 | */ 186 | UINT SCAPI ValueBinaryData( const VALUE* pval, LPCBYTE* pBytes, UINT* pnBytes ); 187 | 188 | /** 189 | * ValueBinaryDataSet - sets VALUE to sequence of bytes of type T_BYTES 190 | * 'type' here must be set to T_BYTES. Optionally sets units field too. 191 | * The function creates local copy of bytes in its own storage. 192 | */ 193 | UINT SCAPI ValueBinaryDataSet( VALUE* pval, LPCBYTE pBytes, UINT nBytes, UINT type, UINT units ); 194 | 195 | /** 196 | * ValueElementsCount - retreive number of sub-elements for: 197 | * - T_ARRAY - number of elements in the array; 198 | * - T_MAP - number of key/value pairs in the map; 199 | * - T_FUNCTION - number of arguments in the function; 200 | */ 201 | UINT SCAPI ValueElementsCount( const VALUE* pval, INT* pn); 202 | 203 | /** 204 | * ValueNthElementValue - retreive value of sub-element at index n for: 205 | * - T_ARRAY - nth element of the array; 206 | * - T_MAP - value of nth key/value pair in the map; 207 | * - T_FUNCTION - value of nth argument of the function; 208 | */ 209 | UINT SCAPI ValueNthElementValue( const VALUE* pval, INT n, VALUE* pretval); 210 | 211 | /** 212 | * ValueNthElementValueSet - sets value of sub-element at index n for: 213 | * - T_ARRAY - nth element of the array; 214 | * - T_MAP - value of nth key/value pair in the map; 215 | * - T_FUNCTION - value of nth argument of the function; 216 | * If the VALUE is not of one of types above then it makes it of type T_ARRAY with 217 | * single element - 'val_to_set'. 218 | */ 219 | UINT SCAPI ValueNthElementValueSet( VALUE* pval, INT n, const VALUE* pval_to_set); 220 | 221 | /**Callback function used with #ValueEnumElements(). 222 | * return TRUE to continue enumeration 223 | */ 224 | typedef SBOOL SC_CALLBACK KeyValueCallback( LPVOID param, const VALUE* pkey, const VALUE* pval ); 225 | 226 | /** 227 | * ValueEnumElements - enumeartes key/value pairs of T_MAP, T_FUNCTION and T_OBJECT values 228 | * - T_MAP - key of nth key/value pair in the map; 229 | * - T_FUNCTION - name of nth argument of the function (if any); 230 | */ 231 | UINT SCAPI ValueNthElementKey( const VALUE* pval, INT n, VALUE* pretval); 232 | 233 | UINT SCAPI ValueEnumElements( const VALUE* pval, KeyValueCallback* penum, LPVOID param); 234 | 235 | /** 236 | * ValueSetValueToKey - sets value of sub-element by key: 237 | * - T_MAP - value of key/value pair with the key; 238 | * - T_FUNCTION - value of argument with the name key; 239 | * - T_OBJECT (tiscript) - value of property of the object 240 | * If the VALUE is not of one of types above then it makes it of type T_MAP with 241 | * single pair - 'key'/'val_to_set'. 242 | * 243 | * key usually is a value of type T_STRING 244 | * 245 | */ 246 | UINT SCAPI ValueSetValueToKey( VALUE* pval, const VALUE* pkey, const VALUE* pval_to_set); 247 | 248 | /** 249 | * ValueGetValueOfKey - retrieves value of sub-element by key: 250 | * - T_MAP - value of key/value pair with the key; 251 | * - T_FUNCTION - value of argument with the name key; 252 | * - T_OBJECT (tiscript) - value of property of the object 253 | * Otherwise *pretval will have T_UNDEFINED value. 254 | */ 255 | UINT SCAPI ValueGetValueOfKey( const VALUE* pval, const VALUE* pkey, VALUE* pretval); 256 | 257 | enum VALUE_STRING_CVT_TYPE 258 | { 259 | CVT_SIMPLE, ///< simple conversion of terminal values 260 | CVT_JSON_LITERAL, ///< json literal parsing/emission 261 | CVT_JSON_MAP, ///< json parsing/emission, it parses as if token '{' already recognized 262 | CVT_XJSON_LITERAL, ///< x-json parsing/emission, date is emitted as ISO8601 date literal, currency is emitted in the form DDDD$CCC 263 | 264 | }; 265 | 266 | /** 267 | * ValueToString - converts value to T_STRING inplace: 268 | * - CVT_SIMPLE - parse/emit terminal values (T_INT, T_FLOAT, T_LENGTH, T_STRING) 269 | * - CVT_JSON_LITERAL - parse/emit value using JSON literal rules: {}, [], "string", true, false, null 270 | * - CVT_JSON_MAP - parse/emit MAP value without enclosing '{' and '}' brackets. 271 | */ 272 | UINT SCAPI ValueToString( VALUE* pval, /*VALUE_STRING_CVT_TYPE*/ UINT how ); 273 | 274 | /** 275 | * ValueFromString - parses string into value: 276 | * - CVT_SIMPLE - parse/emit terminal values (T_INT, T_FLOAT, T_LENGTH, T_STRING), "guess" non-strict parsing 277 | * - CVT_JSON_LITERAL - parse/emit value using JSON literal rules: {}, [], "string", true, false, null 278 | * - CVT_JSON_MAP - parse/emit MAP value without enclosing '{' and '}' brackets. 279 | * Returns: 280 | * Number of non-parsed characters in case of errors. Thus if string was parsed in full it returns 0 (success) 281 | */ 282 | UINT SCAPI ValueFromString( VALUE* pval, LPCWSTR str, UINT strLength, /*VALUE_STRING_CVT_TYPE*/ UINT how ); 283 | 284 | /** 285 | * ValueInvoke - function invocation (Sciter/TIScript). 286 | * - VALUE* pval is a value of type T_OBJECT/UT_OBJECT_FUNCTION 287 | * - VALUE* pthis - object that will be known as 'this' inside that function. 288 | * - UINT argc, const VALUE* argv - vector of arguments to pass to the function. 289 | * - VALUE* pretval - parse/emit MAP value without enclosing '{' and '}' brackets. 290 | * - LPCWSTR url - url or name of the script - used for error reporting in the script. 291 | * Returns: 292 | * HV_OK, HV_BAD_PARAMETER or HV_INCOMPATIBLE_TYPE 293 | */ 294 | UINT SCAPI ValueInvoke( const VALUE* pval, VALUE* pthis, UINT argc, const VALUE* argv, VALUE* pretval, LPCWSTR url); 295 | 296 | /** 297 | * ValueNativeFunctorSet - set reference to native function 298 | * - VALUE* pval - value to be initialized 299 | * - NATIVE_FUNCTOR_INVOKE* pinvoke - reference to native functor implementation. 300 | * - NATIVE_FUNCTOR_RELEASE* prelease - reference to native functor dtor implementation. 301 | * - VOID* tag - optional tag, passed as it is to pinvoke and prelease 302 | * Returns: 303 | * HV_OK, HV_BAD_PARAMETER 304 | */ 305 | UINT SCAPI ValueNativeFunctorSet( VALUE* pval, 306 | NATIVE_FUNCTOR_INVOKE* pinvoke, 307 | NATIVE_FUNCTOR_RELEASE* prelease /* = NULL*/, 308 | VOID* tag /* = NULL*/ ); 309 | 310 | SBOOL SCAPI ValueIsNativeFunctor( const VALUE* pval); 311 | 312 | 313 | #if defined(__cplusplus) && !defined(__value_hpp__) && !defined(PLAIN_API_ONLY) 314 | 315 | #include "value.hpp" 316 | 317 | #pragma warning( push ) 318 | #pragma warning(disable:4786) //identifier was truncated... 319 | 320 | namespace json 321 | { 322 | using sciter::value; 323 | using sciter::string; 324 | using sciter::astring; 325 | } 326 | 327 | #endif //defined(__cplusplus) 328 | 329 | #endif 330 | -------------------------------------------------------------------------------- /request.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern LPSciterRequestAPI rapi(); 4 | 5 | REQUEST_RESULT SCAPI RequestUse( HREQUEST rq ) { return rapi()->RequestUse(rq); } 6 | REQUEST_RESULT SCAPI RequestUnUse( HREQUEST rq ) { return rapi()->RequestUnUse(rq); } 7 | REQUEST_RESULT SCAPI RequestUrl( HREQUEST rq, LPCSTR_RECEIVER* rcv, LPVOID rcv_param ) { return rapi()->RequestUrl(rq,rcv,rcv_param); } 8 | REQUEST_RESULT SCAPI RequestContentUrl( HREQUEST rq, LPCSTR_RECEIVER* rcv, LPVOID rcv_param ) { return rapi()->RequestContentUrl(rq,rcv,rcv_param); } 9 | REQUEST_RESULT SCAPI RequestGetRequestType( HREQUEST rq, REQUEST_RQ_TYPE* pType ) { return rapi()->RequestGetRequestType(rq,pType); } 10 | REQUEST_RESULT SCAPI RequestGetRequestedDataType( HREQUEST rq, SciterResourceType* pData ) { return rapi()->RequestGetRequestedDataType(rq,pData); } 11 | REQUEST_RESULT SCAPI RequestGetReceivedDataType( HREQUEST rq, LPCSTR_RECEIVER* rcv, LPVOID rcv_param ) { return rapi()->RequestGetReceivedDataType(rq,rcv,rcv_param); } 12 | REQUEST_RESULT SCAPI RequestGetNumberOfParameters( HREQUEST rq, UINT* pNumber ) { return rapi()->RequestGetNumberOfParameters(rq,pNumber); } 13 | REQUEST_RESULT SCAPI RequestGetNthParameterName( HREQUEST rq, UINT n, LPCWSTR_RECEIVER* rcv, LPVOID rcv_param ) { return rapi()->RequestGetNthParameterName(rq,n,rcv,rcv_param); } 14 | REQUEST_RESULT SCAPI RequestGetNthParameterValue( HREQUEST rq, UINT n, LPCWSTR_RECEIVER* rcv, LPVOID rcv_param ) { return rapi()->RequestGetNthParameterValue(rq,n,rcv,rcv_param); } 15 | REQUEST_RESULT SCAPI RequestGetTimes( HREQUEST rq, UINT* pStarted, UINT* pEnded ) { return rapi()->RequestGetTimes(rq,pStarted,pEnded); } 16 | REQUEST_RESULT SCAPI RequestGetNumberOfRqHeaders( HREQUEST rq, UINT* pNumber ) { return rapi()->RequestGetNumberOfRqHeaders(rq,pNumber); } 17 | REQUEST_RESULT SCAPI RequestGetNthRqHeaderName( HREQUEST rq, UINT n, LPCWSTR_RECEIVER* rcv, LPVOID rcv_param ) { return rapi()->RequestGetNthRqHeaderName(rq,n,rcv,rcv_param); } 18 | REQUEST_RESULT SCAPI RequestGetNthRqHeaderValue( HREQUEST rq, UINT n, LPCWSTR_RECEIVER* rcv, LPVOID rcv_param ) { return rapi()->RequestGetNthRqHeaderValue(rq,n,rcv,rcv_param); } 19 | REQUEST_RESULT SCAPI RequestGetNumberOfRspHeaders( HREQUEST rq, UINT* pNumber ) { return rapi()->RequestGetNumberOfRspHeaders(rq,pNumber); } 20 | REQUEST_RESULT SCAPI RequestGetNthRspHeaderName( HREQUEST rq, UINT n, LPCWSTR_RECEIVER* rcv, LPVOID rcv_param ) { return rapi()->RequestGetNthRspHeaderName(rq,n,rcv,rcv_param); } 21 | REQUEST_RESULT SCAPI RequestGetNthRspHeaderValue( HREQUEST rq, UINT n, LPCWSTR_RECEIVER* rcv, LPVOID rcv_param ) { return rapi()->RequestGetNthRspHeaderValue(rq,n,rcv,rcv_param); } 22 | REQUEST_RESULT SCAPI RequestGetCompletionStatus( HREQUEST rq, REQUEST_STATE* pState, UINT* pCompletionStatus ) { return rapi()->RequestGetCompletionStatus(rq,pState,pCompletionStatus); } 23 | REQUEST_RESULT SCAPI RequestGetProxyHost( HREQUEST rq, LPCSTR_RECEIVER* rcv, LPVOID rcv_param ) { return rapi()->RequestGetProxyHost(rq,rcv,rcv_param); } 24 | REQUEST_RESULT SCAPI RequestGetProxyPort( HREQUEST rq, UINT* pPort ) { return rapi()->RequestGetProxyPort(rq,pPort); } 25 | REQUEST_RESULT SCAPI RequestSetSucceeded( HREQUEST rq, UINT status, LPCBYTE dataOrNull, UINT dataLength) { return rapi()->RequestSetSucceeded(rq,status,dataOrNull,dataLength); } 26 | REQUEST_RESULT SCAPI RequestSetFailed( HREQUEST rq, UINT status, LPCBYTE dataOrNull, UINT dataLength ) { return rapi()->RequestSetFailed(rq,status,dataOrNull,dataLength); } 27 | REQUEST_RESULT SCAPI RequestAppendDataChunk( HREQUEST rq, LPCBYTE data, UINT dataLength ) { return rapi()->RequestAppendDataChunk(rq,data,dataLength); } 28 | REQUEST_RESULT SCAPI RequestSetRqHeader( HREQUEST rq, LPCWSTR name, LPCWSTR value ) { return rapi()->RequestSetRqHeader(rq,name,value); } 29 | REQUEST_RESULT SCAPI RequestSetRspHeader( HREQUEST rq, LPCWSTR name, LPCWSTR value ) { return rapi()->RequestSetRspHeader(rq,name,value); } 30 | REQUEST_RESULT SCAPI RequestSetReceivedDataType( HREQUEST rq, LPCSTR type ) { return rapi()->RequestSetReceivedDataType(rq,type); } 31 | REQUEST_RESULT SCAPI RequestSetReceivedDataEncoding( HREQUEST rq, LPCSTR encoding ) { return rapi()->RequestSetReceivedDataEncoding(rq,encoding); } 32 | REQUEST_RESULT SCAPI RequestGetData( HREQUEST rq, LPCBYTE_RECEIVER* rcv, LPVOID rcv_param ) { return rapi()->RequestGetData(rq,rcv,rcv_param); } 33 | -------------------------------------------------------------------------------- /request.go: -------------------------------------------------------------------------------- 1 | package sciter 2 | 3 | /* 4 | #include 5 | 6 | extern REQUEST_RESULT SCAPI RequestUse( HREQUEST rq ); 7 | extern REQUEST_RESULT SCAPI RequestUnUse( HREQUEST rq ); 8 | extern REQUEST_RESULT SCAPI RequestUrl( HREQUEST rq, LPCSTR_RECEIVER* rcv, LPVOID rcv_param ); 9 | extern REQUEST_RESULT SCAPI RequestContentUrl( HREQUEST rq, LPCSTR_RECEIVER* rcv, LPVOID rcv_param ); 10 | extern REQUEST_RESULT SCAPI RequestGetRequestType( HREQUEST rq, REQUEST_RQ_TYPE* pType ); 11 | extern REQUEST_RESULT SCAPI RequestGetRequestedDataType( HREQUEST rq, SciterResourceType* pData ); 12 | extern REQUEST_RESULT SCAPI RequestGetReceivedDataType( HREQUEST rq, LPCSTR_RECEIVER* rcv, LPVOID rcv_param ); 13 | extern REQUEST_RESULT SCAPI RequestGetNumberOfParameters( HREQUEST rq, UINT* pNumber ); 14 | extern REQUEST_RESULT SCAPI RequestGetNthParameterName( HREQUEST rq, UINT n, LPCWSTR_RECEIVER* rcv, LPVOID rcv_param ); 15 | extern REQUEST_RESULT SCAPI RequestGetNthParameterValue( HREQUEST rq, UINT n, LPCWSTR_RECEIVER* rcv, LPVOID rcv_param ); 16 | extern REQUEST_RESULT SCAPI RequestGetTimes( HREQUEST rq, UINT* pStarted, UINT* pEnded ); 17 | extern REQUEST_RESULT SCAPI RequestGetNumberOfRqHeaders( HREQUEST rq, UINT* pNumber ); 18 | extern REQUEST_RESULT SCAPI RequestGetNthRqHeaderName( HREQUEST rq, UINT n, LPCWSTR_RECEIVER* rcv, LPVOID rcv_param ); 19 | extern REQUEST_RESULT SCAPI RequestGetNthRqHeaderValue( HREQUEST rq, UINT n, LPCWSTR_RECEIVER* rcv, LPVOID rcv_param ); 20 | extern REQUEST_RESULT SCAPI RequestGetNumberOfRspHeaders( HREQUEST rq, UINT* pNumber ); 21 | extern REQUEST_RESULT SCAPI RequestGetNthRspHeaderName( HREQUEST rq, UINT n, LPCWSTR_RECEIVER* rcv, LPVOID rcv_param ); 22 | extern REQUEST_RESULT SCAPI RequestGetNthRspHeaderValue( HREQUEST rq, UINT n, LPCWSTR_RECEIVER* rcv, LPVOID rcv_param ); 23 | extern REQUEST_RESULT SCAPI RequestGetCompletionStatus( HREQUEST rq, REQUEST_STATE* pState, UINT* pCompletionStatus ); 24 | extern REQUEST_RESULT SCAPI RequestGetProxyHost( HREQUEST rq, LPCSTR_RECEIVER* rcv, LPVOID rcv_param ); 25 | extern REQUEST_RESULT SCAPI RequestGetProxyPort( HREQUEST rq, UINT* pPort ); 26 | extern REQUEST_RESULT SCAPI RequestSetSucceeded( HREQUEST rq, UINT status, LPCBYTE dataOrNull, UINT dataLength); 27 | extern REQUEST_RESULT SCAPI RequestSetFailed( HREQUEST rq, UINT status, LPCBYTE dataOrNull, UINT dataLength ); 28 | extern REQUEST_RESULT SCAPI RequestAppendDataChunk( HREQUEST rq, LPCBYTE data, UINT dataLength ); 29 | extern REQUEST_RESULT SCAPI RequestSetRqHeader( HREQUEST rq, LPCWSTR name, LPCWSTR value ); 30 | extern REQUEST_RESULT SCAPI RequestSetRspHeader( HREQUEST rq, LPCWSTR name, LPCWSTR value ); 31 | extern REQUEST_RESULT SCAPI RequestSetReceivedDataType( HREQUEST rq, LPCSTR type ); 32 | extern REQUEST_RESULT SCAPI RequestSetReceivedDataEncoding( HREQUEST rq, LPCSTR encoding ); 33 | extern REQUEST_RESULT SCAPI RequestGetData( HREQUEST rq, LPCBYTE_RECEIVER* rcv, LPVOID rcv_param ); 34 | */ 35 | import "C" 36 | import ( 37 | "fmt" 38 | "runtime" 39 | "time" 40 | "unsafe" 41 | ) 42 | 43 | /** Resource data type. 44 | * Used by SciterDataReadyAsync() function. 45 | **/ 46 | type SciterResourceType uint32 47 | 48 | // typedef enum SciterResourceType 49 | const ( 50 | RT_DATA_HTML SciterResourceType = iota 51 | RT_DATA_IMAGE 52 | RT_DATA_STYLE 53 | RT_DATA_CURSOR 54 | RT_DATA_SCRIPT 55 | RT_DATA_RAW 56 | RT_DATA_FONT 57 | RT_DATA_SOUND // wav bytes 58 | 59 | RT_DATA_FORCE_DWORD = 0xffffffff 60 | ) 61 | 62 | type REQUEST_RESULT int32 63 | 64 | // enum REQUEST_RESULT 65 | const ( 66 | REQUEST_PANIC = iota - 1 // e.g. not enough memory 67 | REQUEST_OK 68 | REQUEST_BAD_PARAM // bad parameter 69 | REQUEST_FAILURE // operation failed, e.g. index out of bounds 70 | REQUEST_NOTSUPPORTED // the platform does not support requested feature 71 | ) 72 | 73 | // enum REQUEST_RQ_TYPE 74 | const ( 75 | RRT_GET = 1 + iota 76 | RRT_POST 77 | RRT_PUT 78 | RRT_DELETE 79 | 80 | RRT_FORCE_DWORD = 0xFFFFFFFF 81 | ) 82 | 83 | // enum REQUEST_STATE 84 | const ( 85 | RS_PENDING = iota 86 | RS_SUCCESS // completed successfully 87 | RS_FAILURE // completed with failure 88 | 89 | RS_FORCE_DWORD = 0xFFFFFFFF 90 | ) 91 | 92 | type requestError struct { 93 | Result REQUEST_RESULT 94 | Message string 95 | } 96 | 97 | func (e *requestError) Error() string { 98 | return fmt.Sprintf("%s: %s", e.Result.String(), e.Message) 99 | } 100 | 101 | func newRequestError(ret REQUEST_RESULT, msg string) *requestError { 102 | return &requestError{ 103 | Result: ret, 104 | Message: msg, 105 | } 106 | } 107 | 108 | func wrapRequestResult(r C.REQUEST_RESULT, msg string) error { 109 | if r == C.REQUEST_RESULT(REQUEST_OK) { 110 | return nil 111 | } 112 | return newRequestError(REQUEST_RESULT(r), msg) 113 | } 114 | 115 | var ( 116 | BAD_HREQUEST = C.HREQUEST(unsafe.Pointer(uintptr(0))) 117 | ) 118 | 119 | // Request represents a request issued by sciter 120 | // e.g. el.request(...) or view.request(...) 121 | type Request struct { 122 | handle C.HREQUEST 123 | } 124 | 125 | // WrapRequest wraps C.HREQUEST to a go side *Request, doing RequestUse/RequestUnUse automatically 126 | func WrapRequest(requestId C.HREQUEST) *Request { 127 | r := &Request{ 128 | handle: requestId, 129 | } 130 | r.use() 131 | runtime.SetFinalizer(r, (*Request).finalize) 132 | return r 133 | } 134 | 135 | func (r *Request) use() error { 136 | ret := C.RequestUse(r.handle) 137 | return wrapRequestResult(ret, "RequestUse") 138 | } 139 | 140 | func (r *Request) unUse() error { 141 | ret := C.RequestUnUse(r.handle) 142 | return wrapRequestResult(ret, "RequestUnUse") 143 | } 144 | 145 | func (r *Request) finalize() { 146 | r.unUse() 147 | r.handle = BAD_HREQUEST 148 | } 149 | 150 | func (r *Request) Url() (string, error) { 151 | var url string 152 | // args 153 | curl := C.LPVOID(unsafe.Pointer(&url)) 154 | // cgo call 155 | ret := C.RequestUrl(r.handle, lpcstr_receiver, curl) 156 | return url, wrapRequestResult(ret, "RequestUrl") 157 | } 158 | 159 | func (r *Request) ContentUrl() (string, error) { 160 | var url string 161 | // args 162 | curl := C.LPVOID(unsafe.Pointer(&url)) 163 | // cgo call 164 | ret := C.RequestContentUrl(r.handle, lpcstr_receiver, curl) 165 | return url, wrapRequestResult(ret, "RequestContentUrl") 166 | } 167 | 168 | func (r *Request) RequestType() (uint, error) { 169 | var requestType uint 170 | // args 171 | crequestType := (*C.REQUEST_RQ_TYPE)(unsafe.Pointer(&requestType)) 172 | // cgo call 173 | ret := C.RequestGetRequestType(r.handle, crequestType) 174 | return requestType, wrapRequestResult(ret, "RequestGetRequestType") 175 | } 176 | 177 | func (r *Request) RequestedDataType() (SciterResourceType, error) { 178 | var resourceType SciterResourceType 179 | // args 180 | cresourceType := (*C.SciterResourceType)(unsafe.Pointer(&resourceType)) 181 | // cgo call 182 | ret := C.RequestGetRequestedDataType(r.handle, cresourceType) 183 | return resourceType, wrapRequestResult(ret, "RequestGetRequestedDataType") 184 | } 185 | 186 | func (r *Request) ReceivedDataType() (string, error) { 187 | var dataType string 188 | // args 189 | cdataType := C.LPVOID(unsafe.Pointer(&dataType)) 190 | // cgo call 191 | ret := C.RequestGetReceivedDataType(r.handle, lpcstr_receiver, cdataType) 192 | return dataType, wrapRequestResult(ret, "RequestGetReceivedDataType") 193 | } 194 | 195 | func (r *Request) NumberOfParameters() (uint, error) { 196 | var numParams uint 197 | // args 198 | cnumParams := (*C.UINT)(unsafe.Pointer(&numParams)) 199 | // cgo call 200 | ret := C.RequestGetNumberOfParameters(r.handle, cnumParams) 201 | return numParams, wrapRequestResult(ret, "RequestGetNumberOfParameters") 202 | } 203 | 204 | func (r *Request) NthParameterName(idx uint) (string, error) { 205 | var name string 206 | // args 207 | cname := C.LPVOID(unsafe.Pointer(&name)) 208 | cidx := C.UINT(idx) 209 | // cgo call 210 | ret := C.RequestGetNthParameterName(r.handle, cidx, lpcwstr_receiver, cname) 211 | return name, wrapRequestResult(ret, "RequestGetNthParameterName") 212 | } 213 | 214 | func (r *Request) NthParameterValue(idx uint) (string, error) { 215 | var value string 216 | // args 217 | cvalue := C.LPVOID(unsafe.Pointer(&value)) 218 | cidx := C.UINT(idx) 219 | // cgo call 220 | ret := C.RequestGetNthParameterValue(r.handle, cidx, lpcwstr_receiver, cvalue) 221 | return value, wrapRequestResult(ret, "RequestGetNthParameterValue") 222 | } 223 | 224 | func (r *Request) Times() (time.Time, time.Time, error) { 225 | var started, ended uint 226 | var tStarted, tEnded time.Time 227 | // args 228 | cstarted := (*C.UINT)(unsafe.Pointer(&started)) 229 | cended := (*C.UINT)(unsafe.Pointer(&ended)) 230 | // cgo call 231 | ret := C.RequestGetTimes(r.handle, cstarted, cended) 232 | tStarted = time.Unix(int64(started), 0) 233 | tEnded = time.Unix(int64(ended), 0) 234 | return tStarted, tEnded, wrapRequestResult(ret, "RequestGetTimes") 235 | } 236 | 237 | func (r *Request) NumberOfRqHeaders() (uint, error) { 238 | var num uint 239 | // args 240 | cnum := (*C.UINT)(unsafe.Pointer(&num)) 241 | // cgo call 242 | ret := C.RequestGetNumberOfRqHeaders(r.handle, cnum) 243 | return num, wrapRequestResult(ret, "RequestGetNumberOfRqHeaders") 244 | } 245 | 246 | func (r *Request) NthRqHeaderName(idx uint) (string, error) { 247 | var name string 248 | // args 249 | cname := C.LPVOID(unsafe.Pointer(&name)) 250 | cidx := C.UINT(idx) 251 | // cgo call 252 | ret := C.RequestGetNthRqHeaderName(r.handle, cidx, lpcwstr_receiver, cname) 253 | return name, wrapRequestResult(ret, "RequestGetNthRqHeaderName") 254 | } 255 | 256 | func (r *Request) NthRqHeaderValue(idx uint) (string, error) { 257 | var val string 258 | // args 259 | cvalue := C.LPVOID(unsafe.Pointer(&val)) 260 | cidx := C.UINT(idx) 261 | // cgo call 262 | ret := C.RequestGetNthRqHeaderValue(r.handle, cidx, lpcwstr_receiver, cvalue) 263 | return val, wrapRequestResult(ret, "RequestGetNthRqHeaderValue") 264 | } 265 | 266 | func (r *Request) NumberOfRspHeaders() (uint, error) { 267 | var num uint 268 | // args 269 | cnum := (*C.UINT)(unsafe.Pointer(&num)) 270 | // cgo call 271 | ret := C.RequestGetNumberOfRspHeaders(r.handle, cnum) 272 | return num, wrapRequestResult(ret, "RequestGetNumberOfRspHeaders") 273 | } 274 | 275 | func (r *Request) NthRspHeaderName(idx uint) (string, error) { 276 | var name string 277 | // args 278 | cname := C.LPVOID(unsafe.Pointer(&name)) 279 | cidx := C.UINT(idx) 280 | // cgo call 281 | ret := C.RequestGetNthRspHeaderName(r.handle, cidx, lpcwstr_receiver, cname) 282 | return name, wrapRequestResult(ret, "RequestGetNthRspHeaderName") 283 | } 284 | 285 | func (r *Request) NthRspHeaderValue(idx uint) (string, error) { 286 | var val string 287 | // args 288 | cvalue := C.LPVOID(unsafe.Pointer(&val)) 289 | cidx := C.UINT(idx) 290 | // cgo call 291 | ret := C.RequestGetNthRspHeaderValue(r.handle, cidx, lpcwstr_receiver, cvalue) 292 | return val, wrapRequestResult(ret, "RequestGetNthRspHeaderValue") 293 | } 294 | 295 | func (r *Request) CompletionStatus() (uint, uint, error) { 296 | var state, status uint 297 | // args 298 | cstate := (*C.REQUEST_STATE)(unsafe.Pointer(&state)) 299 | cstatus := (*C.UINT)(unsafe.Pointer(&status)) 300 | // cgo call 301 | ret := C.RequestGetCompletionStatus(r.handle, cstate, cstatus) 302 | return state, status, wrapRequestResult(ret, "RequestGetCompletionStatus") 303 | } 304 | 305 | func (r *Request) ProxyHost() (string, error) { 306 | var host string 307 | // args 308 | chost := C.LPVOID(unsafe.Pointer(&host)) 309 | // cgo call 310 | ret := C.RequestGetProxyHost(r.handle, lpcstr_receiver, chost) 311 | return host, wrapRequestResult(ret, "RequestGetProxyHost") 312 | } 313 | 314 | func (r *Request) ProxyPort() (uint, error) { 315 | var portno uint 316 | // args 317 | cportno := (*C.UINT)(unsafe.Pointer(&portno)) 318 | // cgo call 319 | ret := C.RequestGetProxyPort(r.handle, cportno) 320 | return portno, wrapRequestResult(ret, "RequestGetProxyPort") 321 | } 322 | 323 | func (r *Request) SetSucceeded(status uint, data []byte) error { 324 | // args 325 | cstatus := C.UINT(status) 326 | var pData C.LPCBYTE 327 | if len(data) > 0 { 328 | pData = C.LPCBYTE(unsafe.Pointer(&data[0])) 329 | } 330 | cdataLength := C.UINT(len(data)) 331 | 332 | //cgo call 333 | ret := C.RequestSetSucceeded(r.handle, cstatus, pData, cdataLength) 334 | return wrapRequestResult(ret, "RequestSetSucceeded") 335 | } 336 | 337 | func (r *Request) SetFailed(status uint, data []byte) error { 338 | // args 339 | cstatus := C.UINT(status) 340 | var pData C.LPCBYTE 341 | if len(data) > 0 { 342 | pData = C.LPCBYTE(unsafe.Pointer(&data[0])) 343 | } 344 | cdataLength := C.UINT(len(data)) 345 | 346 | //cgo call 347 | ret := C.RequestSetFailed(r.handle, cstatus, pData, cdataLength) 348 | return wrapRequestResult(ret, "RequestSetFailed") 349 | } 350 | 351 | func (r *Request) AppendDataChunk(data []byte) error { 352 | // args 353 | var pData C.LPCBYTE 354 | if len(data) > 0 { 355 | pData = C.LPCBYTE(unsafe.Pointer(&data[0])) 356 | } 357 | cdataLength := C.UINT(len(data)) 358 | 359 | //cgo call 360 | ret := C.RequestAppendDataChunk(r.handle, pData, cdataLength) 361 | return wrapRequestResult(ret, "RequestAppendDataChunk") 362 | } 363 | 364 | func (r *Request) SetRqHeader(name, value string) error { 365 | // args 366 | cname := C.LPCWSTR(unsafe.Pointer(StringToWcharPtr(name))) 367 | cvalue := C.LPCWSTR(unsafe.Pointer(StringToWcharPtr(value))) 368 | // cgo call 369 | ret := C.RequestSetRqHeader(r.handle, cname, cvalue) 370 | return wrapRequestResult(ret, "RequestSetRqHeader") 371 | } 372 | 373 | func (r *Request) SetRspHeader(name, value string) error { 374 | // args 375 | cname := C.LPCWSTR(unsafe.Pointer(StringToWcharPtr(name))) 376 | cvalue := C.LPCWSTR(unsafe.Pointer(StringToWcharPtr(value))) 377 | // cgo call 378 | ret := C.RequestSetRspHeader(r.handle, cname, cvalue) 379 | return wrapRequestResult(ret, "RequestSetRspHeader") 380 | } 381 | 382 | func (r *Request) SetReceivedDataType(dataType string) error { 383 | // args 384 | cdataType := C.LPCSTR(unsafe.Pointer(StringToBytePtr(dataType))) 385 | // cgo call 386 | ret := C.RequestSetReceivedDataType(r.handle, cdataType) 387 | return wrapRequestResult(ret, "RequestSetReceivedDataType") 388 | } 389 | 390 | func (r *Request) RequestSetReceivedDataEncoding(encoding string) error { 391 | // args 392 | cencoding := C.LPCSTR(unsafe.Pointer(StringToBytePtr(encoding))) 393 | // cgo call 394 | ret := C.RequestSetReceivedDataEncoding(r.handle, cencoding) 395 | return wrapRequestResult(ret, "RequestSetReceivedDataEncoding") 396 | } 397 | 398 | func (r *Request) Data() ([]byte, error) { 399 | var buf []byte 400 | // args 401 | cbuf := C.LPVOID(unsafe.Pointer(&buf)) 402 | // cgo call 403 | ret := C.RequestGetData(r.handle, lpcbyte_receiver, cbuf) 404 | return buf, wrapRequestResult(ret, "RequestGetData") 405 | } 406 | -------------------------------------------------------------------------------- /rice/rice.go: -------------------------------------------------------------------------------- 1 | package rice 2 | 3 | import ( 4 | "log" 5 | "strings" 6 | 7 | "github.com/GeertJohan/go.rice" 8 | "github.com/sciter-sdk/go-sciter" 9 | ) 10 | 11 | var ( 12 | conf = rice.Config{ 13 | LocateOrder: []rice.LocateMethod{ 14 | rice.LocateWorkingDirectory, 15 | rice.LocateFS, 16 | rice.LocateAppended, 17 | rice.LocateEmbedded, 18 | }, 19 | } 20 | boxmap = make(map[string]*rice.Box) 21 | ) 22 | 23 | func OnLoadData(s *sciter.Sciter) func(ld *sciter.ScnLoadData) int { 24 | return func(ld *sciter.ScnLoadData) int { 25 | uri := ld.Uri() 26 | path := "" 27 | boxname := "." 28 | // log.Println("loading:", uri) 29 | // file:// or rice:// 30 | if strings.HasPrefix(uri, "file://") || strings.HasPrefix(uri, "rice://") { 31 | path = uri[7:] 32 | ps := strings.Split(path, "/") 33 | if len(ps) >= 2 { 34 | boxname = ps[0] 35 | path = strings.Join(ps[1:], "/") 36 | } 37 | } else { 38 | // // do not handle schemes other than file:// or rice:// 39 | return sciter.LOAD_OK 40 | } 41 | // log.Println("rice loading:", path, "in box:", boxname) 42 | // do box loading 43 | box, ok := boxmap[boxname] 44 | if !ok { 45 | var err error 46 | box, err = conf.FindBox(boxname) 47 | if err != nil { 48 | log.Println(err) 49 | // box locating failed, return to Sciter loading 50 | return sciter.LOAD_OK 51 | } 52 | boxmap[boxname] = box 53 | } 54 | // load resource from rice box 55 | dat, err := box.Bytes(path) 56 | if err != nil { 57 | // box locating failed, return to Sciter loading 58 | return sciter.LOAD_OK 59 | } else { 60 | // using rice found data 61 | s.DataReady(uri, dat) 62 | // log.Println("rice loaded:", path, "in box:", boxname) 63 | } 64 | return sciter.LOAD_OK 65 | } 66 | } 67 | 68 | func newHandler(s *sciter.Sciter) *sciter.CallbackHandler { 69 | return &sciter.CallbackHandler{ 70 | OnLoadData: OnLoadData(s), 71 | } 72 | } 73 | 74 | func HandleDataLoad(s *sciter.Sciter) { 75 | s.SetCallback(newHandler(s)) 76 | } 77 | -------------------------------------------------------------------------------- /sciter_darwin.go: -------------------------------------------------------------------------------- 1 | package sciter 2 | 3 | /* 4 | #cgo CFLAGS: -Iinclude 5 | #include "sciter-x.h" 6 | */ 7 | import "C" 8 | import ( 9 | "unsafe" 10 | ) 11 | 12 | // HWINDOW SciterCreateWindow ( UINT creationFlags,LPRECT frame, SciterWindowDelegate* delegate, LPVOID delegateParam, HWINDOW parent); 13 | 14 | // rect is the display area 15 | func CreateWindow(createFlags WindowCreationFlag, rect *Rect, delegate uintptr, delegateParam uintptr, parent C.HWINDOW) C.HWINDOW { 16 | // set default size 17 | if rect == nil { 18 | rect = DefaultRect 19 | } 20 | // create window 21 | hwnd := C.SciterCreateWindow( 22 | C.UINT(createFlags), 23 | (*C.RECT)(unsafe.Pointer(rect)), 24 | nil, 25 | (C.LPVOID)(delegateParam), 26 | parent) 27 | // in case of NULL 28 | if int(uintptr(unsafe.Pointer(hwnd))) == 0 { 29 | return BAD_HWINDOW 30 | } 31 | return hwnd 32 | } 33 | -------------------------------------------------------------------------------- /sciter_linux.go: -------------------------------------------------------------------------------- 1 | package sciter 2 | 3 | /* 4 | #cgo CFLAGS: -Iinclude 5 | #include "sciter-x.h" 6 | */ 7 | import "C" 8 | import ( 9 | "unsafe" 10 | ) 11 | 12 | // HWINDOW SciterCreateWindow ( UINT creationFlags,LPRECT frame, SciterWindowDelegate* delegate, LPVOID delegateParam, HWINDOW parent); 13 | 14 | // rect is the display area 15 | func CreateWindow(createFlags WindowCreationFlag, rect *Rect, delegate uintptr, delegateParam uintptr, parent C.HWINDOW) C.HWINDOW { 16 | // set default size 17 | if rect == nil { 18 | rect = DefaultRect 19 | } 20 | // create window 21 | hwnd := C.SciterCreateWindow( 22 | C.UINT(createFlags), 23 | (*C.RECT)(unsafe.Pointer(rect)), 24 | nil, 25 | (C.LPVOID)(delegateParam), 26 | parent) 27 | // in case of NULL 28 | if int(uintptr(unsafe.Pointer(hwnd))) == 0 { 29 | return BAD_HWINDOW 30 | } 31 | return hwnd 32 | } 33 | -------------------------------------------------------------------------------- /sciter_windows.go: -------------------------------------------------------------------------------- 1 | package sciter 2 | 3 | /* 4 | #cgo CFLAGS: -Iinclude 5 | #include "sciter-x.h" 6 | */ 7 | import "C" 8 | import ( 9 | "github.com/lxn/win" 10 | "unsafe" 11 | ) 12 | 13 | // LRESULT SciterProc (HWINDOW hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ;//{ return SAPI()->SciterProc (hwnd,msg,wParam,lParam); } 14 | // LRESULT SciterProcND (HWINDOW hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL* pbHandled) ;//{ return SAPI()->SciterProcND (hwnd,msg,wParam,lParam,pbHandled); } 15 | 16 | func ProcND(hwnd win.HWND, msg uint, wParam uintptr, lParam uintptr) (ret int, handled bool) { 17 | var bHandled C.BOOL 18 | // ret = uintptr(syssciterProcND(HWND(hwnd), msg, wParam, lParam, &bHandled)) 19 | ret = int(C.SciterProcND(C.HWINDOW(unsafe.Pointer(hwnd)), C.UINT(msg), C.WPARAM(wParam), C.LPARAM(lParam), &bHandled)) 20 | if bHandled == 0 { 21 | handled = false 22 | } else { 23 | handled = true 24 | } 25 | return 26 | } 27 | 28 | // HWINDOW SciterCreateWindow ( UINT creationFlags,LPRECT frame, SciterWindowDelegate* delegate, LPVOID delegateParam, HWINDOW parent); 29 | 30 | // Create sciter window. 31 | // On Windows returns HWND of either top-level or child window created. 32 | // On OS X returns NSView* of either top-level window or child view . 33 | // 34 | // \param[in] creationFlags \b SCITER_CREATE_WINDOW_FLAGS, creation flags. 35 | // \param[in] frame \b LPRECT, window frame position and size. 36 | // \param[in] delegate \b SciterWindowDelegate, either partial WinProc implementation or thing implementing NSWindowDelegate protocol. 37 | // \param[in] delegateParam \b LPVOID, optional param passed to SciterWindowDelegate. 38 | // \param[in] parent \b HWINDOW, optional parent window. 39 | // rect is the display area 40 | func CreateWindow(createFlags WindowCreationFlag, rect *Rect, delegate uintptr, delegateParam uintptr, parent C.HWINDOW) C.HWINDOW { 41 | // set default size 42 | if rect == nil { 43 | rect = DefaultRect 44 | } 45 | // create window 46 | hwnd := C.SciterCreateWindow( 47 | C.UINT(createFlags), 48 | (*C.RECT)(unsafe.Pointer(rect)), 49 | (*C.SciterWindowDelegate)(unsafe.Pointer(delegate)), 50 | (C.LPVOID)(delegateParam), 51 | parent) 52 | // in case of NULL 53 | if int(uintptr(unsafe.Pointer(hwnd))) == 0 { 54 | return BAD_HWINDOW 55 | } 56 | return hwnd 57 | } 58 | -------------------------------------------------------------------------------- /types_string.go: -------------------------------------------------------------------------------- 1 | // generated by stringer -type=BehaviorEvent,MouseEvent,CursorType,KeyEvent,FocusEvent,ScrollEvent,GestureCmd,GestureState,GestureTypeFlag,DrawEvent,EventReason,EditChangedReason,BehaviorMethodIdentifier,SCDOM_RESULT,VALUE_RESULT -output types_string.go; DO NOT EDIT 2 | 3 | package sciter 4 | 5 | import "fmt" 6 | 7 | const ( 8 | _BehaviorEvent_name_0 = "BUTTON_CLICKBUTTON_PRESSBUTTON_STATE_CHANGEDEDIT_VALUE_CHANGINGEDIT_VALUE_CHANGEDSELECT_SELECTION_CHANGEDSELECT_STATE_CHANGEDPOPUP_REQUESTPOPUP_READYPOPUP_DISMISSEDMENU_ITEM_ACTIVEMENU_ITEM_CLICK" 9 | _BehaviorEvent_name_1 = "CONTEXT_MENU_REQUESTVISIUAL_STATUS_CHANGEDDISABLED_STATUS_CHANGEDPOPUP_DISMISSING" 10 | _BehaviorEvent_name_2 = "CONTENT_CHANGED" 11 | _BehaviorEvent_name_3 = "HYPERLINK_CLICK" 12 | _BehaviorEvent_name_4 = "ELEMENT_COLLAPSEDELEMENT_EXPANDEDACTIVATE_CHILDINIT_DATA_VIEWROWS_DATA_REQUESTUI_STATE_CHANGEDFORM_SUBMITFORM_RESETDOCUMENT_COMPLETEHISTORY_PUSHHISTORY_DROPHISTORY_PRIORHISTORY_NEXTHISTORY_STATE_CHANGEDCLOSE_POPUPREQUEST_TOOLTIPANIMATION" 13 | _BehaviorEvent_name_5 = "DOCUMENT_CREATEDDOCUMENT_CLOSE_REQUESTDOCUMENT_CLOSEDOCUMENT_READY" 14 | _BehaviorEvent_name_6 = "VIDEO_INITIALIZEDVIDEO_STARTEDVIDEO_STOPPEDVIDEO_BIND_RQ" 15 | ) 16 | 17 | var ( 18 | _BehaviorEvent_index_0 = [...]uint8{0, 12, 24, 44, 63, 81, 105, 125, 138, 149, 164, 180, 195} 19 | _BehaviorEvent_index_1 = [...]uint8{0, 20, 42, 65, 81} 20 | _BehaviorEvent_index_2 = [...]uint8{0, 15} 21 | _BehaviorEvent_index_3 = [...]uint8{0, 15} 22 | _BehaviorEvent_index_4 = [...]uint8{0, 17, 33, 47, 61, 78, 94, 105, 115, 132, 144, 156, 169, 181, 202, 213, 228, 237} 23 | _BehaviorEvent_index_5 = [...]uint8{0, 16, 38, 52, 66} 24 | _BehaviorEvent_index_6 = [...]uint8{0, 17, 30, 43, 56} 25 | ) 26 | 27 | func (i BehaviorEvent) String() string { 28 | switch { 29 | case 0 <= i && i <= 11: 30 | return _BehaviorEvent_name_0[_BehaviorEvent_index_0[i]:_BehaviorEvent_index_0[i+1]] 31 | case 16 <= i && i <= 19: 32 | i -= 16 33 | return _BehaviorEvent_name_1[_BehaviorEvent_index_1[i]:_BehaviorEvent_index_1[i+1]] 34 | case i == 21: 35 | return _BehaviorEvent_name_2 36 | case i == 128: 37 | return _BehaviorEvent_name_3 38 | case 144 <= i && i <= 160: 39 | i -= 144 40 | return _BehaviorEvent_name_4[_BehaviorEvent_index_4[i]:_BehaviorEvent_index_4[i+1]] 41 | case 192 <= i && i <= 195: 42 | i -= 192 43 | return _BehaviorEvent_name_5[_BehaviorEvent_index_5[i]:_BehaviorEvent_index_5[i+1]] 44 | case 209 <= i && i <= 212: 45 | i -= 209 46 | return _BehaviorEvent_name_6[_BehaviorEvent_index_6[i]:_BehaviorEvent_index_6[i+1]] 47 | default: 48 | return fmt.Sprintf("BehaviorEvent(%d)", i) 49 | } 50 | } 51 | 52 | const ( 53 | _MouseEvent_name_0 = "MOUSE_ENTERMOUSE_LEAVEMOUSE_MOVEMOUSE_UPMOUSE_DOWNMOUSE_DCLICKMOUSE_WHEELMOUSE_TICKMOUSE_IDLEDROPDRAG_ENTERDRAG_LEAVEDRAG_REQUEST" 54 | _MouseEvent_name_1 = "MOUSE_CLICKDRAGGING" 55 | ) 56 | 57 | var ( 58 | _MouseEvent_index_0 = [...]uint8{0, 11, 22, 32, 40, 50, 62, 73, 83, 93, 97, 107, 117, 129} 59 | _MouseEvent_index_1 = [...]uint8{0, 11, 19} 60 | ) 61 | 62 | func (i MouseEvent) String() string { 63 | switch { 64 | case 0 <= i && i <= 12: 65 | return _MouseEvent_name_0[_MouseEvent_index_0[i]:_MouseEvent_index_0[i+1]] 66 | case 255 <= i && i <= 256: 67 | i -= 255 68 | return _MouseEvent_name_1[_MouseEvent_index_1[i]:_MouseEvent_index_1[i+1]] 69 | default: 70 | return fmt.Sprintf("MouseEvent(%d)", i) 71 | } 72 | } 73 | 74 | const _CursorType_name = "CURSOR_ARROWCURSOR_IBEAMCURSOR_WAITCURSOR_CROSSCURSOR_UPARROWCURSOR_SIZENWSECURSOR_SIZENESWCURSOR_SIZEWECURSOR_SIZENSCURSOR_SIZEALLCURSOR_NOCURSOR_APPSTARTINGCURSOR_HELPCURSOR_HANDCURSOR_DRAG_MOVECURSOR_DRAG_COPY" 75 | 76 | var _CursorType_index = [...]uint8{0, 12, 24, 35, 47, 61, 76, 91, 104, 117, 131, 140, 158, 169, 180, 196, 212} 77 | 78 | func (i CursorType) String() string { 79 | if i+1 >= CursorType(len(_CursorType_index)) { 80 | return fmt.Sprintf("CursorType(%d)", i) 81 | } 82 | return _CursorType_name[_CursorType_index[i]:_CursorType_index[i+1]] 83 | } 84 | 85 | const _KeyEvent_name = "KEY_DOWNKEY_UPKEY_CHAR" 86 | 87 | var _KeyEvent_index = [...]uint8{0, 8, 14, 22} 88 | 89 | func (i KeyEvent) String() string { 90 | if i+1 >= KeyEvent(len(_KeyEvent_index)) { 91 | return fmt.Sprintf("KeyEvent(%d)", i) 92 | } 93 | return _KeyEvent_name[_KeyEvent_index[i]:_KeyEvent_index[i+1]] 94 | } 95 | 96 | const _FocusEvent_name = "FOCUS_LOSTFOCUS_GOT" 97 | 98 | var _FocusEvent_index = [...]uint8{0, 10, 19} 99 | 100 | func (i FocusEvent) String() string { 101 | if i+1 >= FocusEvent(len(_FocusEvent_index)) { 102 | return fmt.Sprintf("FocusEvent(%d)", i) 103 | } 104 | return _FocusEvent_name[_FocusEvent_index[i]:_FocusEvent_index[i+1]] 105 | } 106 | 107 | const _ScrollEvent_name = "SCROLL_HOMESCROLL_ENDSCROLL_STEP_PLUSSCROLL_STEP_MINUSSCROLL_PAGE_PLUSSCROLL_PAGE_MINUSSCROLL_POSSCROLL_SLIDER_RELEASEDSCROLL_CORNER_PRESSEDSCROLL_CORNER_RELEASED" 108 | 109 | var _ScrollEvent_index = [...]uint8{0, 11, 21, 37, 54, 70, 87, 97, 119, 140, 162} 110 | 111 | func (i ScrollEvent) String() string { 112 | if i+1 >= ScrollEvent(len(_ScrollEvent_index)) { 113 | return fmt.Sprintf("ScrollEvent(%d)", i) 114 | } 115 | return _ScrollEvent_name[_ScrollEvent_index[i]:_ScrollEvent_index[i+1]] 116 | } 117 | 118 | const _GestureCmd_name = "GESTURE_REQUESTGESTURE_ZOOMGESTURE_PANGESTURE_ROTATEGESTURE_TAP1GESTURE_TAP2" 119 | 120 | var _GestureCmd_index = [...]uint8{0, 15, 27, 38, 52, 64, 76} 121 | 122 | func (i GestureCmd) String() string { 123 | if i+1 >= GestureCmd(len(_GestureCmd_index)) { 124 | return fmt.Sprintf("GestureCmd(%d)", i) 125 | } 126 | return _GestureCmd_name[_GestureCmd_index[i]:_GestureCmd_index[i+1]] 127 | } 128 | 129 | const ( 130 | _GestureState_name_0 = "GESTURE_STATE_BEGINGESTURE_STATE_INERTIA" 131 | _GestureState_name_1 = "GESTURE_STATE_END" 132 | ) 133 | 134 | var ( 135 | _GestureState_index_0 = [...]uint8{0, 19, 40} 136 | _GestureState_index_1 = [...]uint8{0, 17} 137 | ) 138 | 139 | func (i GestureState) String() string { 140 | switch { 141 | case 1 <= i && i <= 2: 142 | i -= 1 143 | return _GestureState_name_0[_GestureState_index_0[i]:_GestureState_index_0[i+1]] 144 | case i == 4: 145 | return _GestureState_name_1 146 | default: 147 | return fmt.Sprintf("GestureState(%d)", i) 148 | } 149 | } 150 | 151 | const ( 152 | _GestureTypeFlag_name_0 = "GESTURE_FLAG_ZOOMGESTURE_FLAG_ROTATE" 153 | _GestureTypeFlag_name_1 = "GESTURE_FLAG_PAN_VERTICAL" 154 | _GestureTypeFlag_name_2 = "GESTURE_FLAG_TAP1" 155 | _GestureTypeFlag_name_3 = "GESTURE_FLAG_TAP2" 156 | _GestureTypeFlag_name_4 = "GESTURE_FLAG_PAN_WITH_GUTTER" 157 | _GestureTypeFlag_name_5 = "GESTURE_FLAG_PAN_WITH_INERTIA" 158 | _GestureTypeFlag_name_6 = "GESTURE_FLAGS_ALL" 159 | ) 160 | 161 | var ( 162 | _GestureTypeFlag_index_0 = [...]uint8{0, 17, 36} 163 | _GestureTypeFlag_index_1 = [...]uint8{0, 25} 164 | _GestureTypeFlag_index_2 = [...]uint8{0, 17} 165 | _GestureTypeFlag_index_3 = [...]uint8{0, 17} 166 | _GestureTypeFlag_index_4 = [...]uint8{0, 28} 167 | _GestureTypeFlag_index_5 = [...]uint8{0, 29} 168 | _GestureTypeFlag_index_6 = [...]uint8{0, 17} 169 | ) 170 | 171 | func (i GestureTypeFlag) String() string { 172 | switch { 173 | case 1 <= i && i <= 2: 174 | i -= 1 175 | return _GestureTypeFlag_name_0[_GestureTypeFlag_index_0[i]:_GestureTypeFlag_index_0[i+1]] 176 | case i == 4: 177 | return _GestureTypeFlag_name_1 178 | case i == 16: 179 | return _GestureTypeFlag_name_2 180 | case i == 32: 181 | return _GestureTypeFlag_name_3 182 | case i == 16384: 183 | return _GestureTypeFlag_name_4 184 | case i == 32768: 185 | return _GestureTypeFlag_name_5 186 | case i == 65535: 187 | return _GestureTypeFlag_name_6 188 | default: 189 | return fmt.Sprintf("GestureTypeFlag(%d)", i) 190 | } 191 | } 192 | 193 | const _DrawEvent_name = "DRAW_CONTENTDRAW_FOREGROUND" 194 | 195 | var _DrawEvent_index = [...]uint8{0, 12, 27} 196 | 197 | func (i DrawEvent) String() string { 198 | i -= 1 199 | if i+1 >= DrawEvent(len(_DrawEvent_index)) { 200 | return fmt.Sprintf("DrawEvent(%d)", i+1) 201 | } 202 | return _DrawEvent_name[_DrawEvent_index[i]:_DrawEvent_index[i+1]] 203 | } 204 | 205 | const _EventReason_name = "BY_MOUSE_CLICKBY_KEY_CLICKSYNTHESIZEDBY_MOUSE_ON_ICON" 206 | 207 | var _EventReason_index = [...]uint8{0, 14, 26, 37, 53} 208 | 209 | func (i EventReason) String() string { 210 | if i+1 >= EventReason(len(_EventReason_index)) { 211 | return fmt.Sprintf("EventReason(%d)", i) 212 | } 213 | return _EventReason_name[_EventReason_index[i]:_EventReason_index[i+1]] 214 | } 215 | 216 | const _EditChangedReason_name = "BY_INS_CHARBY_INS_CHARSBY_DEL_CHARBY_DEL_CHARSBY_UNDO_REDO" 217 | 218 | var _EditChangedReason_index = [...]uint8{0, 11, 23, 34, 46, 58} 219 | 220 | func (i EditChangedReason) String() string { 221 | if i+1 >= EditChangedReason(len(_EditChangedReason_index)) { 222 | return fmt.Sprintf("EditChangedReason(%d)", i) 223 | } 224 | return _EditChangedReason_name[_EditChangedReason_index[i]:_EditChangedReason_index[i+1]] 225 | } 226 | 227 | const ( 228 | _BehaviorMethodIdentifier_name_0 = "DO_CLICKGET_TEXT_VALUESET_TEXT_VALUETEXT_EDIT_GET_SELECTIONTEXT_EDIT_SET_SELECTIONTEXT_EDIT_REPLACE_SELECTIONSCROLL_BAR_GET_VALUESCROLL_BAR_SET_VALUETEXT_EDIT_GET_CARET_POSITIONTEXT_EDIT_GET_SELECTION_TEXTTEXT_EDIT_GET_SELECTION_HTMLTEXT_EDIT_CHAR_POS_AT_XY" 229 | _BehaviorMethodIdentifier_name_1 = "IS_EMPTYGET_VALUESET_VALUE" 230 | _BehaviorMethodIdentifier_name_2 = "FIRST_APPLICATION_METHOD_ID" 231 | ) 232 | 233 | var ( 234 | _BehaviorMethodIdentifier_index_0 = [...]uint16{0, 8, 22, 36, 59, 82, 109, 129, 149, 177, 205, 233, 257} 235 | _BehaviorMethodIdentifier_index_1 = [...]uint8{0, 8, 17, 26} 236 | _BehaviorMethodIdentifier_index_2 = [...]uint8{0, 27} 237 | ) 238 | 239 | func (i BehaviorMethodIdentifier) String() string { 240 | switch { 241 | case 0 <= i && i <= 11: 242 | return _BehaviorMethodIdentifier_name_0[_BehaviorMethodIdentifier_index_0[i]:_BehaviorMethodIdentifier_index_0[i+1]] 243 | case 252 <= i && i <= 254: 244 | i -= 252 245 | return _BehaviorMethodIdentifier_name_1[_BehaviorMethodIdentifier_index_1[i]:_BehaviorMethodIdentifier_index_1[i+1]] 246 | case i == 256: 247 | return _BehaviorMethodIdentifier_name_2 248 | default: 249 | return fmt.Sprintf("BehaviorMethodIdentifier(%d)", i) 250 | } 251 | } 252 | 253 | const _SCDOM_RESULT_name = "SCDOM_OK_NOT_HANDLEDSCDOM_OKSCDOM_INVALID_HWNDSCDOM_INVALID_HANDLESCDOM_PASSIVE_HANDLESCDOM_INVALID_PARAMETERSCDOM_OPERATION_FAILED" 254 | 255 | var _SCDOM_RESULT_index = [...]uint8{0, 20, 28, 46, 66, 86, 109, 131} 256 | 257 | func (i SCDOM_RESULT) String() string { 258 | i -= -1 259 | if i < 0 || i+1 >= SCDOM_RESULT(len(_SCDOM_RESULT_index)) { 260 | return fmt.Sprintf("SCDOM_RESULT(%d)", i+-1) 261 | } 262 | return _SCDOM_RESULT_name[_SCDOM_RESULT_index[i]:_SCDOM_RESULT_index[i+1]] 263 | } 264 | 265 | const _VALUE_RESULT_name = "HV_OK_TRUEHV_OKHV_BAD_PARAMETERHV_INCOMPATIBLE_TYPE" 266 | 267 | var _VALUE_RESULT_index = [...]uint8{0, 10, 15, 31, 51} 268 | 269 | func (i VALUE_RESULT) String() string { 270 | i -= -1 271 | if i < 0 || i+1 >= VALUE_RESULT(len(_VALUE_RESULT_index)) { 272 | return fmt.Sprintf("VALUE_RESULT(%d)", i+-1) 273 | } 274 | return _VALUE_RESULT_name[_VALUE_RESULT_index[i]:_VALUE_RESULT_index[i+1]] 275 | } 276 | 277 | const _REQUEST_RESULT_name = "REQUEST_PANICREQUEST_OKREQUEST_BAD_PARAMREQUEST_FAILUREREQUEST_NOTSUPPORTED" 278 | 279 | var _REQUEST_RESULT_index = [...]uint8{0, 13, 23, 40, 55, 75} 280 | 281 | func (i REQUEST_RESULT) String() string { 282 | i -= -1 283 | if i < 0 || i+1 >= REQUEST_RESULT(len(_REQUEST_RESULT_index)) { 284 | return fmt.Sprintf("REQUEST_RESULT(%d)", i+-1) 285 | } 286 | return _REQUEST_RESULT_name[_REQUEST_RESULT_index[i]:_REQUEST_RESULT_index[i+1]] 287 | } 288 | -------------------------------------------------------------------------------- /utils.go: -------------------------------------------------------------------------------- 1 | package sciter 2 | 3 | /* 4 | #cgo CFLAGS: -Iinclude 5 | #include "sciter-x.h" 6 | */ 7 | import "C" 8 | import ( 9 | "syscall" 10 | "unicode/utf16" 11 | "unsafe" 12 | ) 13 | 14 | // Returns the utf-8 encoding of the utf-16 sequence s, 15 | // with a terminating NUL removed. 16 | func Utf16ToString(s *uint16) string { 17 | if s == nil { 18 | panic("null cstring") 19 | } 20 | us := make([]uint16, 0, 256) 21 | for p := uintptr(unsafe.Pointer(s)); ; p += 2 { 22 | u := *(*uint16)(unsafe.Pointer(p)) 23 | if u == 0 { 24 | return string(utf16.Decode(us)) 25 | } 26 | us = append(us, u) 27 | } 28 | return "" 29 | } 30 | 31 | func Utf16ToStringLength(s *uint16, length int) string { 32 | if s == nil { 33 | panic("null cstring") 34 | } 35 | us := make([]uint16, 0, 256) 36 | for p, i := uintptr(unsafe.Pointer(s)), 0; i < length; p, i = p+2, i+1 { 37 | u := *(*uint16)(unsafe.Pointer(p)) 38 | us = append(us, u) 39 | } 40 | return string(utf16.Decode(us)) 41 | } 42 | 43 | func StringToBytePtr(s string) *byte { 44 | bs := ([]byte)(s) 45 | return &bs[0] 46 | } 47 | 48 | // returns a UTF-16 string, including the trailing zero 49 | func Utf16FromString(s string) ([]uint16, error) { 50 | for i := 0; i < len(s); i++ { 51 | if s[i] == 0 { 52 | return nil, syscall.EINVAL 53 | } 54 | } 55 | return utf16.Encode([]rune(s + "\x00")), nil 56 | } 57 | 58 | func StringToWcharPtr(s string) *C.WCHAR { 59 | return (*C.WCHAR)(unsafe.Pointer(StringToUTF16Ptr(s))) 60 | } 61 | 62 | func StringToUTF16Ptr(s string) *uint16 { 63 | us, _ := Utf16FromString(s) 64 | return &us[0] 65 | } 66 | 67 | func StringToUTF16PtrWithLen(s string) (*uint16, int) { 68 | us, _ := Utf16FromString(s) 69 | length := len(us) - 1 70 | return &us[0], length 71 | } 72 | 73 | func ByteCPtrToBytes(bp C.LPCBYTE, size C.UINT) []byte { 74 | bs := C.GoBytes(unsafe.Pointer(bp), C.INT(size)) 75 | return bs 76 | } 77 | 78 | func BytePtrToBytes(bp *byte, size uint) []byte { 79 | bs := C.GoBytes(unsafe.Pointer(bp), C.INT(size)) 80 | return bs 81 | } 82 | -------------------------------------------------------------------------------- /value.go: -------------------------------------------------------------------------------- 1 | package sciter 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | ) 7 | 8 | type NativeFunctor func(args ...*Value) *Value 9 | 10 | // typedef VALUE SCITER_VALUE; 11 | // type Scitervalue Value 12 | 13 | type valueError struct { 14 | Result VALUE_RESULT 15 | Message string 16 | } 17 | 18 | func (e *valueError) Error() string { 19 | return fmt.Sprintf("%s: %s", e.Result.String(), e.Message) 20 | } 21 | 22 | func newValueError(ret VALUE_RESULT, msg string) *valueError { 23 | return &valueError{ 24 | Result: ret, 25 | Message: msg, 26 | } 27 | } 28 | 29 | func wrapValueResult(r VALUE_RESULT, msg string) error { 30 | if r == VALUE_RESULT(HV_OK) { 31 | return nil 32 | } 33 | return newValueError(VALUE_RESULT(r), msg) 34 | } 35 | 36 | func valuePanic(result uint, message ...interface{}) { 37 | panic(&valueError{VALUE_RESULT(result), fmt.Sprint(message...)}) 38 | } 39 | 40 | // Only supported basic types: int/bool/string/float/NativeFunctor/Value 41 | // for creating array: a := NewValue(); a.SetIndex(0, 123)|a.Append(123) 42 | // for creating map/object: obj := NewValue(); obj.Set("key", "value") 43 | // The creating process would call ValueInit/VlaueClear automatically 44 | func NewValue(val ...interface{}) *Value { 45 | v := new(Value) 46 | v.init() 47 | runtime.SetFinalizer(v, (*Value).finalize) 48 | if len(val) == 0 { 49 | return v 50 | } 51 | v.Assign(val[0]) 52 | return v 53 | } 54 | 55 | func (v *Value) finalize() { 56 | // log.Println("finalizing value:", v) 57 | v.clear() 58 | } 59 | 60 | // release the object from sciter and go world 61 | func (v *Value) Release() { 62 | runtime.SetFinalizer(v, nil) 63 | v.finalize() 64 | } 65 | 66 | // Assign go value to Sciter Value 67 | // currently supported go types: bool integer float string and NativeFunctor 68 | func (v *Value) Assign(val interface{}) { 69 | switch val.(type) { 70 | case string: 71 | s := val.(string) 72 | v.SetString(s) 73 | case int: 74 | i := val.(int) 75 | v.SetInt(i) 76 | case float64: 77 | f := val.(float64) 78 | // valueInit(this); valueFloatDataSet(this, v, T_FLOAT, 0) 79 | v.SetFloat(f) 80 | case bool: 81 | // value( bool v ) { valueInit(this); valueIntDataSet(this, v?1:0, T_BOOL, 0); } 82 | v.SetBool(val.(bool)) 83 | case float32: 84 | v.Assign(float64(val.(float32))) 85 | case uint: 86 | v.Assign(int(val.(uint))) 87 | case uint32: 88 | v.Assign(int(val.(uint32))) 89 | case uint64: 90 | v.Assign(int(val.(uint64))) 91 | case int32: 92 | v.Assign(int(val.(int32))) 93 | case int64: 94 | v.Assign(int(val.(int64))) 95 | case Value: 96 | vf := val.(Value) 97 | v.Copy(&vf) 98 | case *Value: 99 | v.Copy(val.(*Value)) 100 | case NativeFunctor: 101 | v.SetNativeFunctor(val.(NativeFunctor)) 102 | case func(args ...*Value) *Value: 103 | v.SetNativeFunctor((NativeFunctor)(val.(func(args ...*Value) *Value))) 104 | default: 105 | nf, ok := val.(NativeFunctor) 106 | if ok { 107 | v.SetNativeFunctor(nf) 108 | } else { 109 | panic("unsupported value type") 110 | } 111 | } 112 | } 113 | 114 | // bool is_undefined() const { return t == T_UNDEFINED; } 115 | func (v *Value) IsUndefined() bool { 116 | return v.t == T_UNDEFINED 117 | } 118 | 119 | // bool is_bool() const { return t == T_BOOL; } 120 | func (v *Value) IsBool() bool { 121 | return v.t == T_BOOL 122 | } 123 | 124 | // bool is_int() const { return t == T_INT; } 125 | func (v *Value) IsInt() bool { 126 | return v.t == T_INT 127 | } 128 | 129 | // bool is_float() const { return t == T_FLOAT; } 130 | func (v *Value) IsFloat() bool { 131 | return v.t == T_FLOAT 132 | } 133 | 134 | // bool is_string() const { return t == T_STRING; } 135 | func (v *Value) IsString() bool { 136 | return v.t == T_STRING 137 | } 138 | 139 | // bool is_symbol() const { return t == T_STRING && u == UT_SYMBOL; } 140 | func (v *Value) IsSymbol() bool { 141 | return v.t == T_STRING && v.t == UT_SYMBOL 142 | } 143 | 144 | // bool is_date() const { return t == T_DATE; } 145 | func (v *Value) IsDate() bool { 146 | return v.t == T_DATE 147 | } 148 | 149 | // bool is_currency() const { return t == T_CURRENCY; } 150 | func (v *Value) IsCurrency() bool { 151 | return v.t == T_CURRENCY 152 | } 153 | 154 | // bool is_map() const { return t == T_MAP; } 155 | func (v *Value) IsMap() bool { 156 | return v.t == T_MAP 157 | } 158 | 159 | // bool is_array() const { return t == T_ARRAY; } 160 | func (v *Value) IsArray() bool { 161 | return v.t == T_ARRAY 162 | } 163 | 164 | // bool is_function() const { return t == T_FUNCTION; } 165 | func (v *Value) IsFunction() bool { 166 | return v.t == T_FUNCTION 167 | } 168 | 169 | // bool is_color() const { return t == T_COLOR; } 170 | func (v *Value) IsColor() bool { 171 | return v.t == T_COLOR 172 | } 173 | 174 | // bool is_duration() const { return t == T_DURATION; } 175 | func (v *Value) IsDuration() bool { 176 | return v.t == T_DURATION 177 | } 178 | // bool is_angle() const { return t == T_ANGLE; } 179 | func (v *Value) IsAngle() bool { 180 | return v.t == T_ANGLE 181 | } 182 | 183 | // bool is_asset() const { return t == T_ASSET; } 184 | func (v *Value) IsAsset() bool { 185 | return v.t == T_ASSET 186 | } 187 | 188 | // bool is_bytes() const { return t == T_BYTES; } 189 | func (v *Value) IsByte() bool { 190 | return v.t == T_BYTES 191 | } 192 | 193 | // bool is_object() const { return t == T_OBJECT; } 194 | func (v *Value) IsObject() bool { 195 | return v.t == T_OBJECT 196 | } 197 | 198 | // bool is_object_native() const { return t == T_OBJECT && u == UT_OBJECT_NATIVE; } 199 | func (v *Value) IsObjectNative() bool { 200 | return v.t == T_OBJECT && v.u == UT_OBJECT_NATIVE 201 | } 202 | 203 | // bool is_object_array() const { return t == T_OBJECT && u == UT_OBJECT_ARRAY; } 204 | func (v *Value) IsObjectArray() bool { 205 | return v.t == T_OBJECT && v.u == UT_OBJECT_ARRAY 206 | } 207 | 208 | // bool is_object_function() const { return t == T_OBJECT && u == UT_OBJECT_FUNCTION; } 209 | func (v *Value) IsObjectFunction() bool { 210 | return v.t == T_OBJECT && v.u == UT_OBJECT_FUNCTION 211 | } 212 | 213 | // bool is_object_object() const { return t == T_OBJECT && u == UT_OBJECT_OBJECT; } // that is plain TS object 214 | func (v *Value) IsObjectObject() bool { 215 | return v.t == T_OBJECT && v.u == UT_OBJECT_OBJECT 216 | } 217 | 218 | // bool is_object_class() const { return t == T_OBJECT && u == UT_OBJECT_CLASS; } // that is TS class 219 | func (v *Value) IsObjectClass() bool { 220 | return v.t == T_OBJECT && v.u == UT_OBJECT_CLASS 221 | } 222 | 223 | // bool is_object_error() const { return t == T_OBJECT && u == UT_OBJECT_ERROR; } // that is TS error 224 | func (v *Value) IsObjectE() bool { 225 | return v.t == T_OBJECT && v.u == UT_OBJECT_ERROR 226 | } 227 | 228 | // bool is_dom_element() const { return t == T_DOM_OBJECT; } 229 | func (v *Value) IsDomElement() bool { 230 | return v.t == T_DOM_OBJECT 231 | } 232 | 233 | // bool is_null() const { return t == T_NULL; } 234 | func (v *Value) IsNull() bool { 235 | return v.t == T_NULL 236 | } 237 | 238 | // // static value null() { value n; n.t = T_NULL; return n; } 239 | func NullValue() *Value { 240 | v := new(Value) 241 | v.init() 242 | v.t = T_NULL 243 | return v 244 | } 245 | 246 | // bool is_nothing() const { return t == T_UNDEFINED && u == UT_NOTHING; } 247 | func (v *Value) IsNothing() bool { 248 | return v.t == T_UNDEFINED && v.u == UT_NOTHING 249 | } 250 | 251 | // static value nothing() { value n; n.t = T_UNDEFINED; n.u = UT_NOTHING; return n; } 252 | func NothingValue() *Value { 253 | v := new(Value) 254 | v.init() 255 | v.t = T_UNDEFINED 256 | v.u = UT_NOTHING 257 | return v 258 | } 259 | -------------------------------------------------------------------------------- /window/window.go: -------------------------------------------------------------------------------- 1 | package window 2 | 3 | import ( 4 | "github.com/sciter-sdk/go-sciter" 5 | "runtime" 6 | ) 7 | 8 | type Window struct { 9 | *sciter.Sciter 10 | creationFlags sciter.WindowCreationFlag 11 | } 12 | 13 | func (w *Window) run() { 14 | // runtime.LockOSThread() 15 | } 16 | 17 | // https://github.com/golang/go/wiki/LockOSThread 18 | // https://github.com/sciter-sdk/go-sciter/issues/201 19 | func init() { 20 | runtime.LockOSThread() 21 | } 22 | -------------------------------------------------------------------------------- /window/window_darwin.go: -------------------------------------------------------------------------------- 1 | // +build darwin 2 | 3 | package window 4 | 5 | /* 6 | #cgo CFLAGS: -x objective-c 7 | #cgo LDFLAGS: -framework Cocoa 8 | #import 9 | #import 10 | #include 11 | 12 | int Run(void) { 13 | [NSApplication sharedApplication]; 14 | [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; 15 | 16 | [NSApp activateIgnoringOtherApps:YES]; 17 | [NSApp run]; 18 | return 0; 19 | } 20 | 21 | void MinimalMenu(void) { 22 | id menubar = [[NSMenu new] autorelease]; 23 | id appMenuItem = [[NSMenuItem new] autorelease]; 24 | [menubar addItem:appMenuItem]; 25 | [NSApp setMainMenu:menubar]; 26 | id appMenu = [[NSMenu new] autorelease]; 27 | id appName = [[NSProcessInfo processInfo] processName]; 28 | id quitTitle = [@"Quit " stringByAppendingString:appName]; 29 | id quitMenuItem = [[[NSMenuItem alloc] initWithTitle:quitTitle 30 | action:@selector(terminate:) keyEquivalent:@"q"] 31 | autorelease]; 32 | 33 | [appMenu addItem:quitMenuItem]; 34 | [appMenuItem setSubmenu:appMenu]; 35 | } 36 | 37 | void SetWindowTitle(void * w, char * title) { 38 | [[(NSView*)w window] setTitle:[NSString stringWithUTF8String:title]]; 39 | } 40 | 41 | void ShowWindow(void * w) { 42 | [[(NSView*)w window] makeKeyAndOrderFront:nil]; 43 | } 44 | */ 45 | import "C" 46 | import ( 47 | "fmt" 48 | "unsafe" 49 | 50 | "github.com/sciter-sdk/go-sciter" 51 | ) 52 | 53 | func New(creationFlags sciter.WindowCreationFlag, rect *sciter.Rect) (*Window, error) { 54 | w := new(Window) 55 | w.creationFlags = creationFlags 56 | // create window 57 | hwnd := sciter.CreateWindow( 58 | creationFlags, 59 | rect, 60 | 0, 61 | 0, 62 | sciter.BAD_HWINDOW) 63 | 64 | if hwnd == sciter.BAD_HWINDOW { 65 | return nil, fmt.Errorf("Sciter CreateWindow failed") 66 | } 67 | 68 | w.Sciter = sciter.Wrap(hwnd) 69 | return w, nil 70 | } 71 | func (s *Window) SetTitle(title string) { 72 | t := C.CString(title) 73 | C.SetWindowTitle(unsafe.Pointer(s.GetHwnd()), t) 74 | C.free(unsafe.Pointer(t)) 75 | } 76 | 77 | // Add a simple menu with a Quit item in it. 78 | func (s *Window) AddQuitMenu() { 79 | C.MinimalMenu() 80 | } 81 | 82 | func (s *Window) Show() { 83 | C.ShowWindow(unsafe.Pointer(s.GetHwnd())) 84 | } 85 | 86 | func (s *Window) Run() { 87 | s.run() 88 | 89 | C.Run() 90 | } 91 | -------------------------------------------------------------------------------- /window/window_linux.go: -------------------------------------------------------------------------------- 1 | package window 2 | 3 | /* 4 | #cgo linux pkg-config: gtk+-3.0 5 | 6 | #include 7 | #include 8 | 9 | GtkWindow* gwindow(GtkWidget* hwnd) { 10 | return hwnd ? GTK_WINDOW(gtk_widget_get_toplevel(hwnd)) : NULL; 11 | } 12 | 13 | void gshow(GtkWidget* hwnd){ 14 | if(hwnd) gtk_window_present(gwindow(hwnd)); 15 | } 16 | 17 | */ 18 | import "C" 19 | import ( 20 | "fmt" 21 | "unsafe" 22 | 23 | "github.com/sciter-sdk/go-sciter" 24 | ) 25 | 26 | // Linux/gtk3 must (at least) use sciter.DefaultWindowCreationFlag to create the main window correctly 27 | func New(creationFlags sciter.WindowCreationFlag, rect *sciter.Rect) (*Window, error) { 28 | w := new(Window) 29 | w.creationFlags = creationFlags 30 | // create window 31 | hwnd := sciter.CreateWindow( 32 | creationFlags, 33 | rect, 34 | 0, 35 | 0, 36 | sciter.BAD_HWINDOW) 37 | 38 | if hwnd == sciter.BAD_HWINDOW { 39 | return nil, fmt.Errorf("Sciter CreateWindow failed") 40 | } 41 | 42 | w.Sciter = sciter.Wrap(hwnd) 43 | return w, nil 44 | } 45 | 46 | func (s *Window) SetTitle(title string) { 47 | w := C.gwindow((*C.GtkWidget)(unsafe.Pointer(s.GetHwnd()))) 48 | t := C.CString(title) 49 | C.gtk_window_set_title(w, t) 50 | C.free(unsafe.Pointer(t)) 51 | } 52 | 53 | func (s *Window) AddQuitMenu() { 54 | // Define behaviour for linux 55 | } 56 | 57 | func (s *Window) Show() { 58 | w := (*C.GtkWidget)(unsafe.Pointer(s.GetHwnd())) 59 | C.gshow(w) 60 | } 61 | 62 | func (s *Window) Run() { 63 | s.run() 64 | C.gtk_main() 65 | } 66 | 67 | func init() { 68 | C.gtk_init(nil, nil) 69 | } 70 | -------------------------------------------------------------------------------- /window/window_windows.go: -------------------------------------------------------------------------------- 1 | package window 2 | 3 | /* 4 | #include 5 | */ 6 | import "C" 7 | import ( 8 | "fmt" 9 | "syscall" 10 | "unsafe" 11 | 12 | "github.com/lxn/win" 13 | "github.com/sciter-sdk/go-sciter" 14 | ) 15 | 16 | func New(creationFlags sciter.WindowCreationFlag, rect *sciter.Rect) (*Window, error) { 17 | w := new(Window) 18 | w.creationFlags = creationFlags 19 | 20 | // Initialize OLE for DnD and printing support 21 | win.OleInitialize() 22 | 23 | // create window 24 | hwnd := sciter.CreateWindow( 25 | creationFlags, 26 | rect, 27 | syscall.NewCallback(delegateProc), 28 | 0, 29 | sciter.BAD_HWINDOW) 30 | 31 | if hwnd == sciter.BAD_HWINDOW { 32 | return nil, fmt.Errorf("Sciter CreateWindow failed [%d]", win.GetLastError()) 33 | } 34 | 35 | w.Sciter = sciter.Wrap(hwnd) 36 | return w, nil 37 | } 38 | 39 | func (s *Window) Show() { 40 | // message handling 41 | hwnd := win.HWND(unsafe.Pointer(s.GetHwnd())) 42 | win.ShowWindow(hwnd, win.SW_SHOW) 43 | win.UpdateWindow(hwnd) 44 | } 45 | 46 | func (s *Window) SetTitle(title string) { 47 | // message handling 48 | hwnd := C.HWND(unsafe.Pointer(s.GetHwnd())) 49 | C.SetWindowTextW(hwnd, (*C.WCHAR)(unsafe.Pointer(sciter.StringToWcharPtr(title)))) 50 | } 51 | 52 | func (s *Window) AddQuitMenu() { 53 | // Define behaviour for windows 54 | } 55 | 56 | func (s *Window) Run() { 57 | // for system drag-n-drop 58 | // win.OleInitialize() 59 | // defer win.OleUninitialize() 60 | s.run() 61 | // start main gui message loop 62 | msg := (*win.MSG)(unsafe.Pointer(win.GlobalAlloc(0, unsafe.Sizeof(win.MSG{})))) 63 | defer win.GlobalFree(win.HGLOBAL(unsafe.Pointer(msg))) 64 | for win.GetMessage(msg, 0, 0, 0) > 0 { 65 | win.TranslateMessage(msg) 66 | win.DispatchMessage(msg) 67 | } 68 | } 69 | 70 | // delegate Windows GUI messsage 71 | func delegateProc(hWnd win.HWND, message uint, wParam uintptr, lParam uintptr, pParam uintptr, pHandled *int) int { 72 | switch message { 73 | case win.WM_DESTROY: 74 | // log.Println("closing window ...") 75 | win.PostQuitMessage(0) 76 | *pHandled = 1 77 | } 78 | return 0 79 | } 80 | -------------------------------------------------------------------------------- /wrapper.go: -------------------------------------------------------------------------------- 1 | package sciter 2 | 3 | type eventMapper struct { 4 | mouseHandlerList []func(he *Element, params *MouseParams) bool 5 | keyHandlerList []func(he *Element, params *KeyParams) bool 6 | focusHandlerList []func(he *Element, params *FocusParams) bool 7 | timerHandlerList []func(he *Element, params *TimerParams) bool 8 | behaviorEventHandlerList []func(he *Element, params *BehaviorEventParams) bool 9 | methodCallHandlerList []func(he *Element, params *MethodParams) bool 10 | scriptingMethodMap map[string]func(args ...*Value) *Value 11 | dataArrivedHandlerList []func(he *Element, params *DataArrivedParams) bool 12 | sizeHandlerList []func(he *Element) 13 | scrollHandlerList []func(he *Element, params *ScrollParams) bool 14 | gestureHandlerList []func(he *Element, params *GestureParams) bool 15 | // the handler instance 16 | eventhandler *EventHandler 17 | } 18 | 19 | func newEventMapper() *eventMapper { 20 | em := &eventMapper{ 21 | mouseHandlerList: make([]func(he *Element, params *MouseParams) bool, 0), 22 | keyHandlerList: make([]func(he *Element, params *KeyParams) bool, 0), 23 | focusHandlerList: make([]func(he *Element, params *FocusParams) bool, 0), 24 | timerHandlerList: make([]func(he *Element, params *TimerParams) bool, 0), 25 | behaviorEventHandlerList: make([]func(he *Element, params *BehaviorEventParams) bool, 0), 26 | methodCallHandlerList: make([]func(he *Element, params *MethodParams) bool, 0), 27 | scriptingMethodMap: make(map[string]func(args ...*Value) *Value), 28 | dataArrivedHandlerList: make([]func(he *Element, params *DataArrivedParams) bool, 0), 29 | sizeHandlerList: make([]func(he *Element), 0), 30 | scrollHandlerList: make([]func(he *Element, params *ScrollParams) bool, 0), 31 | gestureHandlerList: make([]func(he *Element, params *GestureParams) bool, 0), 32 | } 33 | em.eventhandler = em.toEventHandler() 34 | return em 35 | } 36 | 37 | func (s *Sciter) checkMapper() { 38 | if s.eventMapper == nil { 39 | s.eventMapper = newEventMapper() 40 | s.AttachWindowEventHandler(s.eventMapper.eventhandler) 41 | } 42 | } 43 | 44 | func (el *Element) checkMapper() { 45 | if el.eventMapper == nil { 46 | el.eventMapper = newEventMapper() 47 | el.AttachEventHandler(el.eventMapper.eventhandler) 48 | } 49 | } 50 | 51 | func (e *eventMapper) addMethod(name string, nf func(args ...*Value) *Value) { 52 | e.scriptingMethodMap[name] = nf 53 | } 54 | 55 | func (e *eventMapper) onClick(fn func()) { 56 | e.behaviorEventHandlerList = append(e.behaviorEventHandlerList, func(he *Element, params *BehaviorEventParams) bool { 57 | if params.Cmd() == BUTTON_CLICK && params.Phase() == SINKING { 58 | fn() 59 | } 60 | return false 61 | }) 62 | } 63 | 64 | // DefineFunction defines global scripting function which works for tiscript and csss! script. 65 | // The global function must be access via the `view` namespace 66 | func (s *Sciter) DefineFunction(name string, nf func(args ...*Value) *Value) { 67 | s.checkMapper() 68 | s.eventMapper.scriptingMethodMap[name] = nf 69 | } 70 | 71 | // DefineMethod defines Element locally scripting function in tiscript 72 | // The local method must be access as the element attribute. 73 | func (e *Element) DefineMethod(name string, nf func(args ...*Value) *Value) { 74 | e.checkMapper() 75 | e.eventMapper.scriptingMethodMap[name] = nf 76 | } 77 | 78 | func (e *Element) OnClick(fn func()) { 79 | e.checkMapper() 80 | e.eventMapper.onClick(fn) 81 | } 82 | 83 | func (e *eventMapper) toEventHandler() *EventHandler { 84 | return &EventHandler{ 85 | OnMouse: func(he *Element, params *MouseParams) bool { 86 | for _, h := range e.mouseHandlerList { 87 | h(he, params) 88 | } 89 | return false 90 | }, 91 | OnKey: func(he *Element, params *KeyParams) bool { 92 | for _, h := range e.keyHandlerList { 93 | h(he, params) 94 | } 95 | return false 96 | }, 97 | OnFocus: func(he *Element, params *FocusParams) bool { 98 | for _, h := range e.focusHandlerList { 99 | h(he, params) 100 | } 101 | return false 102 | }, 103 | OnTimer: func(he *Element, params *TimerParams) bool { 104 | for _, h := range e.timerHandlerList { 105 | h(he, params) 106 | } 107 | return false 108 | }, 109 | OnBehaviorEvent: func(he *Element, params *BehaviorEventParams) bool { 110 | for _, h := range e.behaviorEventHandlerList { 111 | h(he, params) 112 | } 113 | return false 114 | }, 115 | OnMethodCall: func(he *Element, params *MethodParams) bool { 116 | for _, h := range e.methodCallHandlerList { 117 | h(he, params) 118 | } 119 | return false 120 | }, 121 | OnScriptingMethodCall: func(he *Element, params *ScriptingMethodParams) bool { 122 | if nf, ok := e.scriptingMethodMap[params.Name()]; ok { 123 | params.Return(nf(params.Args()...)) 124 | return true 125 | } 126 | return false 127 | }, 128 | OnDataArrived: func(he *Element, params *DataArrivedParams) bool { 129 | for _, h := range e.dataArrivedHandlerList { 130 | h(he, params) 131 | } 132 | return false 133 | }, 134 | OnSize: func(he *Element) { 135 | for _, h := range e.sizeHandlerList { 136 | h(he) 137 | } 138 | }, 139 | OnScroll: func(he *Element, params *ScrollParams) bool { 140 | for _, h := range e.scrollHandlerList { 141 | h(he, params) 142 | } 143 | return false 144 | }, 145 | OnGesture: func(he *Element, params *GestureParams) bool { 146 | for _, h := range e.gestureHandlerList { 147 | h(he, params) 148 | } 149 | return false 150 | }, 151 | } 152 | } 153 | --------------------------------------------------------------------------------