Merge branch 'master' into feature/1521_Support_Tray_Menus

This commit is contained in:
Lea Anthony 2022-10-12 21:04:52 +11:00 committed by GitHub
commit 62c19f128e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
114 changed files with 1725 additions and 999 deletions

View file

@ -1,15 +1,14 @@
name: Release
name: Build + Test
on:
push:
branches: [ release/* ]
pull_request:
branches: [ release/* ]
branches: [ release/*, master ]
workflow_dispatch:
jobs:
test:
name: Run Go Tests
if: github.repository == 'wailsapp/wails'
runs-on: ${{ matrix.os }}
strategy:
matrix:
@ -35,7 +34,6 @@ jobs:
test_templates:
name: Test Templates
needs: test
if: github.repository == 'wailsapp/wails'
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true

View file

@ -6,6 +6,7 @@ on:
jobs:
docs:
name: Website Updated
if: github.repository == 'wailsapp/wails'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

View file

@ -4,12 +4,11 @@ on:
workflow_dispatch:
schedule:
- cron: "0 0 * * *"
push:
branches: [ master ]
jobs:
update-sponsors:
runs-on: ubuntu-latest
if: github.repository == 'wailsapp/wails'
steps:
- uses: actions/checkout@v2

View file

@ -8,6 +8,7 @@ on:
jobs:
build:
runs-on: ubuntu-latest
if: github.repository == 'wailsapp/wails'
steps:
- uses: tomsun28/issues-translate-action@v2.6
with:

View file

@ -7,6 +7,7 @@ on:
jobs:
build:
name: is-sponsor-label
if: github.repository == 'wailsapp/wails'
runs-on: ubuntu-latest
steps:
- uses: JasonEtco/is-sponsor-label-action@v1

View file

@ -5,6 +5,7 @@ on:
jobs:
check_branch_name:
runs-on: ubuntu-latest
if: github.repository == 'wailsapp/wails'
name: Check branch name
steps:
- run: |

View file

@ -7,6 +7,7 @@ on:
jobs:
projectcardautolabel_job:
runs-on: ubuntu-latest
if: github.repository == 'wailsapp/wails'
steps:
- name: Run ProjectCard AutoLabel
id: runprojectcardautolabel

View file

@ -115,7 +115,7 @@ This project is supported by these kind people / companies:
## Stargazers over time
[![Stargazers over time](https://starchart.cc/wailsapp/wails.svg)](https://starchart.cc/wailsapp/wails)
[![Star History Chart](https://api.star-history.com/svg?repos=wailsapp/wails&type=Date)](https://star-history.com/#wailsapp/wails&Date)
## Contributors

View file

@ -111,7 +111,7 @@
## 星星增长趋势
[![星星增长趋势](https://starchart.cc/wailsapp/wails.svg)](https://starchart.cc/wailsapp/wails)
[![星星增长趋势](https://api.star-history.com/svg?repos=wailsapp/wails&type=Date)](https://star-history.com/#wailsapp/wails&Date)
## 贡献者

View file

@ -160,6 +160,7 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
}
buildOptions := generateBuildOptions(flags)
buildOptions.SkipBindings = flags.skipBindings
buildOptions.Logger = logger
userTags, err := buildtags.Parse(flags.tags)
@ -169,7 +170,7 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
buildOptions.UserTags = userTags
if !flags.skipBindings {
if !buildOptions.SkipBindings {
if flags.verbosity == build.VERBOSE {
LogGreen("Generating Bindings...")
}
@ -573,7 +574,19 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
case err := <-watcher.Errors:
LogDarkYellow(err.Error())
case item := <-watcher.Events:
// Check for file writes
isEligibleFile := func(fileName string) bool {
// Iterate all file patterns
ext := filepath.Ext(fileName)
if ext != "" {
ext = ext[1:]
if _, exists := extensionsThatTriggerARebuild[ext]; exists {
return true
}
}
return false
}
// Handle write operations
if item.Op&fsnotify.Write == fsnotify.Write {
// Ignore directories
itemName := item.Name
@ -581,15 +594,10 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
continue
}
// Iterate all file patterns
ext := filepath.Ext(itemName)
if ext != "" {
ext = ext[1:]
if _, exists := extensionsThatTriggerARebuild[ext]; exists {
rebuild = true
timer.Reset(interval)
continue
}
if isEligibleFile(itemName) {
rebuild = true
timer.Reset(interval)
continue
}
for _, reloadDir := range dirsThatTriggerAReload {
@ -605,7 +613,8 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
timer.Reset(interval)
}
// Check for new directories
// Handle new fs entries that are created
if item.Op&fsnotify.Create == fsnotify.Create {
// If this is a folder, add it to our watch list
if fs.DirExists(item.Name) {
@ -617,6 +626,14 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
}
LogGreen("Added new directory to watcher: %s", item.Name)
}
} else if isEligibleFile(item.Name) {
// Handle creation of new file.
// Note: On some platforms an update to a file is represented as
// REMOVE -> CREATE instead of WRITE, so this is not only new files
// but also updates to existing files
rebuild = true
timer.Reset(interval)
continue
}
}
case <-timer.C:

View file

@ -189,6 +189,12 @@ func initProject(options *templates.Options, quiet bool, ciMode bool) error {
updateReplaceLine(workspace)
}
// Remove the `.git`` directory in the template project
err = os.RemoveAll(".git")
if err != nil {
return err
}
if options.InitGit {
err = initGit(options)
if err != nil {

View file

@ -13,7 +13,7 @@ require (
github.com/imdario/mergo v0.3.12
github.com/jackmordaunt/icns v1.0.0
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e
github.com/labstack/echo/v4 v4.7.2
github.com/labstack/echo/v4 v4.9.0
github.com/leaanthony/clir v1.0.4
github.com/leaanthony/debme v1.2.1
github.com/leaanthony/go-ansi-parser v1.0.1

View file

@ -80,8 +80,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labstack/echo/v4 v4.7.2 h1:Kv2/p8OaQ+M6Ex4eGimg9b9e6icoxA42JSlOR3msKtI=
github.com/labstack/echo/v4 v4.7.2/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
github.com/labstack/echo/v4 v4.9.0 h1:wPOF1CE6gvt/kmbMR4dGzWvHMPT+sAEUJOwOTtvITVY=
github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/leaanthony/clir v1.0.4 h1:Dov2y9zWJmZr7CjaCe86lKa4b5CSxskGAt2yBkoDyiU=

View file

@ -20,7 +20,6 @@ import (
"github.com/wailsapp/wails/v2/internal/fs"
"github.com/wailsapp/wails/v2/internal/logger"
"github.com/wailsapp/wails/v2/internal/menumanager"
"github.com/wailsapp/wails/v2/internal/project"
pkglogger "github.com/wailsapp/wails/v2/pkg/logger"
"github.com/wailsapp/wails/v2/pkg/options"
)
@ -172,10 +171,6 @@ func CreateApp(appoptions *options.App) (*App, error) {
}
appBindings := binding.NewBindings(myLogger, appoptions.Bind, bindingExemptions, false)
err = generateBindings(appBindings)
if err != nil {
return nil, err
}
eventHandler := runtime.NewEvents(myLogger)
ctx = context.WithValue(ctx, "events", eventHandler)
messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler)
@ -186,6 +181,7 @@ func CreateApp(appoptions *options.App) (*App, error) {
eventHandler.AddFrontend(appFrontend)
eventHandler.AddFrontend(desktopFrontend)
ctx = context.WithValue(ctx, "frontend", appFrontend)
result := &App{
ctx: ctx,
frontend: appFrontend,
@ -202,37 +198,6 @@ func CreateApp(appoptions *options.App) (*App, error) {
}
func generateBindings(bindings *binding.Bindings) error {
cwd, err := os.Getwd()
if err != nil {
return err
}
projectConfig, err := project.Load(cwd)
if err != nil {
return err
}
if projectConfig.WailsJSDir == "" {
projectConfig.WailsJSDir = filepath.Join(cwd, "frontend")
}
targetDir := filepath.Join(projectConfig.WailsJSDir, "wailsjs", "go")
err = os.RemoveAll(targetDir)
if err != nil {
return err
}
_ = fs.MkDirs(targetDir)
err = bindings.GenerateGoBindings(targetDir)
if err != nil {
return err
}
return nil
}
func tryInferAssetDirFromFS(assets iofs.FS) (string, error) {
if _, isEmbedFs := assets.(embed.FS); !isEmbedFs {
// We only infer the assetdir for embed.FS assets

View file

@ -84,6 +84,7 @@ func CreateApp(appoptions *options.App) (*App, error) {
appFrontend := desktop.NewFrontend(ctx, appoptions, myLogger, appBindings, messageDispatcher)
eventHandler.AddFrontend(appFrontend)
ctx = context.WithValue(ctx, "frontend", appFrontend)
result := &App{
ctx: ctx,
frontend: appFrontend,

View file

@ -8,6 +8,7 @@ import (
"path/filepath"
"reflect"
"runtime"
"sort"
"strings"
"github.com/wailsapp/wails/v2/internal/typescriptify"
@ -35,7 +36,7 @@ func NewBindings(logger *logger.Logger, structPointersToBind []interface{}, exem
}
for _, exemption := range exemptions {
if exemptions == nil {
if exemption == nil {
continue
}
name := runtime.FuncForPC(reflect.ValueOf(exemption).Pointer()).Name()
@ -83,7 +84,7 @@ func (b *Bindings) ToJSON() (string, error) {
return b.db.ToJSON()
}
func (b *Bindings) WriteModels(modelsDir string) error {
func (b *Bindings) GenerateModels() ([]byte, error) {
models := map[string]string{}
var seen slicer.StringSlicer
allStructNames := b.getAllStructNames()
@ -102,15 +103,23 @@ func (b *Bindings) WriteModels(modelsDir string) error {
}
str, err := w.Convert(nil)
if err != nil {
return err
return nil, err
}
thisPackageCode += str
seen.AddSlice(w.GetGeneratedStructs())
models[packageName] = thisPackageCode
}
// Sort the package names first to make the output deterministic
sortedPackageNames := make([]string, 0)
for packageName := range models {
sortedPackageNames = append(sortedPackageNames, packageName)
}
sort.Strings(sortedPackageNames)
var modelsData bytes.Buffer
for packageName, modelData := range models {
for _, packageName := range sortedPackageNames {
modelData := models[packageName]
if strings.TrimSpace(modelData) == "" {
continue
}
@ -121,14 +130,22 @@ func (b *Bindings) WriteModels(modelsDir string) error {
}
modelsData.WriteString("\n}\n\n")
}
return modelsData.Bytes(), nil
}
func (b *Bindings) WriteModels(modelsDir string) error {
modelsData, err := b.GenerateModels()
if err != nil {
return err
}
// Don't write if we don't have anything
if len(modelsData.Bytes()) == 0 {
if len(modelsData) == 0 {
return nil
}
filename := filepath.Join(modelsDir, "models.ts")
err := os.WriteFile(filename, modelsData.Bytes(), 0755)
err = os.WriteFile(filename, modelsData, 0755)
if err != nil {
return err
}
@ -147,7 +164,7 @@ func (b *Bindings) AddStructToGenerateTS(packageName string, structName string,
// Iterate this struct and add any struct field references
structType := reflect.TypeOf(s)
if structType.Kind() == reflect.Ptr {
if hasElements(structType) {
structType = structType.Elem()
}
@ -169,11 +186,11 @@ func (b *Bindings) AddStructToGenerateTS(packageName string, structName string,
s := reflect.Indirect(a).Interface()
b.AddStructToGenerateTS(pName, sName, s)
}
} else if kind == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct {
} else if hasElements(field.Type) && field.Type.Elem().Kind() == reflect.Struct {
if !field.IsExported() {
continue
}
fqname := field.Type.String()
fqname := field.Type.Elem().String()
sName := strings.Split(fqname, ".")[1]
pName := getPackageName(fqname)
typ := field.Type.Elem()

View file

@ -0,0 +1,64 @@
package binding_test
import (
"io/fs"
"os"
"testing"
"github.com/wailsapp/wails/v2/internal/binding"
"github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import/float_package"
"github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import/int_package"
"github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import/map_package"
"github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import/uint_package"
"github.com/wailsapp/wails/v2/internal/logger"
)
const expectedBindings = `// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import {float_package} from '../models';
import {int_package} from '../models';
import {map_package} from '../models';
import {uint_package} from '../models';
export function StartingWithFloat(arg1:float_package.SomeStruct):Promise<void>;
export function StartingWithInt(arg1:int_package.SomeStruct):Promise<void>;
export function StartingWithMap(arg1:map_package.SomeStruct):Promise<void>;
export function StartingWithUint(arg1:uint_package.SomeStruct):Promise<void>;
`
type HandlerTest struct{}
func (h *HandlerTest) StartingWithInt(_ int_package.SomeStruct) {}
func (h *HandlerTest) StartingWithFloat(_ float_package.SomeStruct) {}
func (h *HandlerTest) StartingWithUint(_ uint_package.SomeStruct) {}
func (h *HandlerTest) StartingWithMap(_ map_package.SomeStruct) {}
func TestConflictingPackageName(t *testing.T) {
// given
generationDir := t.TempDir()
// setup
testLogger := &logger.Logger{}
b := binding.NewBindings(testLogger, []interface{}{&HandlerTest{}}, []interface{}{}, false)
// then
err := b.GenerateGoBindings(generationDir)
if err != nil {
t.Fatalf("could not generate the Go bindings: %v", err)
}
// then
rawGeneratedBindings, err := fs.ReadFile(os.DirFS(generationDir), "binding_test/HandlerTest.d.ts")
if err != nil {
t.Fatalf("could not read the generated bindings: %v", err)
}
// then
generatedBindings := string(rawGeneratedBindings)
if generatedBindings != expectedBindings {
t.Fatalf("the generated bindings does not match the expected ones.\nWanted:\n%s\n\nGot:\n%s", expectedBindings, generatedBindings)
}
}

View file

@ -0,0 +1,32 @@
package binding_test
type EscapedName struct {
Name string `json:"n.a.m.e"`
}
func (s EscapedName) Get() EscapedName {
return s
}
var EscapedNameTest = BindingTest{
name: "EscapedName",
structs: []interface{}{
&EscapedName{},
},
exemptions: nil,
shouldError: false,
want: `
export namespace binding_test {
export class EscapedName {
"n.a.m.e": string;
static createFrom(source: any = {}) {
return new EscapedName(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this["n.a.m.e"] = source["n.a.m.e"];
}
}
}
`,
}

View file

@ -0,0 +1,94 @@
package binding_test
import "github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import"
type ImportedMap struct {
AMapWrapperContainer binding_test_import.AMapWrapper `json:"AMapWrapperContainer"`
}
func (s ImportedMap) Get() ImportedMap {
return s
}
var ImportedMapTest = BindingTest{
name: "ImportedMap",
structs: []interface{}{
&ImportedMap{},
},
exemptions: nil,
shouldError: false,
want: `
export namespace binding_test {
export class ImportedMap {
AMapWrapperContainer: binding_test_import.AMapWrapper;
static createFrom(source: any = {}) {
return new ImportedMap(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.AMapWrapperContainer = this.convertValues(source["AMapWrapperContainer"], binding_test_import.AMapWrapper);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
}
export namespace binding_test_import {
export class AMapWrapper {
AMap: {[key: string]: binding_test_nestedimport.A};
static createFrom(source: any = {}) {
return new AMapWrapper(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.AMap = this.convertValues(source["AMap"], binding_test_nestedimport.A, true);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
}
export namespace binding_test_nestedimport {
export class A {
A: string;
static createFrom(source: any = {}) {
return new A(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.A = source["A"];
}
}
}
`,
}

View file

@ -0,0 +1,94 @@
package binding_test
import "github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import"
type ImportedSlice struct {
ASliceWrapperContainer binding_test_import.ASliceWrapper `json:"ASliceWrapperContainer"`
}
func (s ImportedSlice) Get() ImportedSlice {
return s
}
var ImportedSliceTest = BindingTest{
name: "ImportedSlice",
structs: []interface{}{
&ImportedSlice{},
},
exemptions: nil,
shouldError: false,
want: `
export namespace binding_test {
export class ImportedSlice {
ASliceWrapperContainer: binding_test_import.ASliceWrapper;
static createFrom(source: any = {}) {
return new ImportedSlice(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.ASliceWrapperContainer = this.convertValues(source["ASliceWrapperContainer"], binding_test_import.ASliceWrapper);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
}
export namespace binding_test_import {
export class ASliceWrapper {
ASlice: binding_test_nestedimport.A[];
static createFrom(source: any = {}) {
return new ASliceWrapper(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.ASlice = this.convertValues(source["ASlice"], binding_test_nestedimport.A);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
}
export namespace binding_test_nestedimport {
export class A {
A: string;
static createFrom(source: any = {}) {
return new A(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.A = source["A"];
}
}
}
`,
}

View file

@ -0,0 +1,95 @@
package binding_test
import "github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import"
type ImportedStruct struct {
AWrapperContainer binding_test_import.AWrapper `json:"AWrapperContainer"`
}
func (s ImportedStruct) Get() ImportedStruct {
return s
}
var ImportedStructTest = BindingTest{
name: "ImportedStruct",
structs: []interface{}{
&ImportedStruct{},
},
exemptions: nil,
shouldError: false,
want: `
export namespace binding_test {
export class ImportedStruct {
AWrapperContainer: binding_test_import.AWrapper;
static createFrom(source: any = {}) {
return new ImportedStruct(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.AWrapperContainer = this.convertValues(source["AWrapperContainer"], binding_test_import.AWrapper);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
}
export namespace binding_test_import {
export class AWrapper {
AWrapper: binding_test_nestedimport.A;
static createFrom(source: any = {}) {
return new AWrapper(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.AWrapper = this.convertValues(source["AWrapper"], binding_test_nestedimport.A);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
}
export namespace binding_test_nestedimport {
export class A {
A: string;
static createFrom(source: any = {}) {
return new A(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.A = source["A"];
}
}
}
`,
}

View file

@ -0,0 +1,63 @@
package binding_test
type As struct {
B Bs `json:"b"`
}
type Bs struct {
Name string `json:"name"`
}
func (a As) Get() As {
return a
}
var NestedFieldTest = BindingTest{
name: "NestedField",
structs: []interface{}{
&As{},
},
exemptions: nil,
shouldError: false,
want: `
export namespace binding_test {
export class Bs {
name: string;
static createFrom(source: any = {}) {
return new Bs(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.name = source["name"];
}
}
export class As {
b: Bs;
static createFrom(source: any = {}) {
return new As(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.b = this.convertValues(source["b"], Bs);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
}
`,
}

View file

@ -0,0 +1,32 @@
package binding_test
type NonStringMapKey struct {
NumberMap map[uint]any `json:"numberMap"`
}
func (s NonStringMapKey) Get() NonStringMapKey {
return s
}
var NonStringMapKeyTest = BindingTest{
name: "NonStringMapKey",
structs: []interface{}{
&NonStringMapKey{},
},
exemptions: nil,
shouldError: false,
want: `
export namespace binding_test {
export class NonStringMapKey {
numberMap: {[key: number]: any};
static createFrom(source: any = {}) {
return new NonStringMapKey(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.numberMap = source["numberMap"];
}
}
}
`,
}

View file

@ -0,0 +1,32 @@
package binding_test
type SingleField struct {
Name string `json:"name"`
}
func (s SingleField) Get() SingleField {
return s
}
var SingleFieldTest = BindingTest{
name: "SingleField",
structs: []interface{}{
&SingleField{},
},
exemptions: nil,
shouldError: false,
want: `
export namespace binding_test {
export class SingleField {
name: string;
static createFrom(source: any = {}) {
return new SingleField(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.name = source["name"];
}
}
}
`,
}

View file

@ -0,0 +1,51 @@
package binding_test
import (
"reflect"
"strings"
"testing"
"github.com/stretchr/testify/require"
"github.com/wailsapp/wails/v2/internal/binding"
"github.com/wailsapp/wails/v2/internal/logger"
)
type BindingTest struct {
name string
structs []interface{}
exemptions []interface{}
want string
shouldError bool
}
func TestBindings_GenerateModels(t *testing.T) {
tests := []BindingTest{
EscapedNameTest,
ImportedStructTest,
ImportedSliceTest,
ImportedMapTest,
NestedFieldTest,
NonStringMapKeyTest,
SingleFieldTest,
}
testLogger := &logger.Logger{}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b := binding.NewBindings(testLogger, tt.structs, tt.exemptions, false)
for _, s := range tt.structs {
err := b.Add(s)
require.NoError(t, err)
}
got, err := b.GenerateModels()
if (err != nil) != tt.shouldError {
t.Errorf("GenerateModels() error = %v, shouldError %v", err, tt.shouldError)
return
}
if !reflect.DeepEqual(strings.Fields(string(got)), strings.Fields(tt.want)) {
t.Errorf("GenerateModels() got = %v, want %v", string(got), tt.want)
}
})
}
}

View file

@ -0,0 +1,15 @@
package binding_test_import
import "github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import/binding_test_nestedimport"
type AWrapper struct {
AWrapper binding_test_nestedimport.A `json:"AWrapper"`
}
type ASliceWrapper struct {
ASlice []binding_test_nestedimport.A `json:"ASlice"`
}
type AMapWrapper struct {
AMap map[string]binding_test_nestedimport.A `json:"AMap"`
}

View file

@ -0,0 +1,5 @@
package binding_test_nestedimport
type A struct {
A string `json:"A"`
}

View file

@ -0,0 +1,5 @@
package float_package
type SomeStruct struct {
Name string `json:"string"`
}

View file

@ -0,0 +1,5 @@
package int_package
type SomeStruct struct {
Name string `json:"string"`
}

View file

@ -0,0 +1,5 @@
package map_package
type SomeStruct struct {
Name string `json:"string"`
}

View file

@ -0,0 +1,5 @@
package uint_package
type SomeStruct struct {
Name string `json:"string"`
}

View file

@ -120,6 +120,16 @@ func (b *Bindings) GenerateGoBindings(baseDir string) error {
}
func goTypeToJSDocType(input string, importNamespaces *slicer.StringSlicer) string {
// Verifying this first to ensure we are not converting a type
// coming from a package that has a name matching a golang type, such as:
// - interactor -> int
// - mapper -> map
if strings.ContainsRune(input, '.') {
namespace := getPackageName(input)
importNamespaces.Add(namespace)
return namespace + "." + strings.Split(input, ".")[1]
}
switch true {
case input == "interface {}" || input == "interface{}":
return "any"
@ -150,11 +160,6 @@ func goTypeToJSDocType(input string, importNamespaces *slicer.StringSlicer) stri
arrayType := goTypeToJSDocType(input[2:], importNamespaces)
return "Array<" + arrayType + ">"
default:
if strings.ContainsRune(input, '.') {
namespace := getPackageName(input)
importNamespaces.Add(namespace)
return namespace + "." + strings.Split(input, ".")[1]
}
return "any"
}
}

View file

@ -165,3 +165,8 @@ func getPackageName(in string) string {
result = strings.ReplaceAll(result, "*", "")
return result
}
func hasElements(typ reflect.Type) bool {
kind := typ.Kind()
return kind == reflect.Ptr || kind == reflect.Array || kind == reflect.Slice || kind == reflect.Map
}

View file

@ -32,7 +32,7 @@ type assetHandler struct {
retryMissingFiles bool
}
func NewAssetHandler(ctx context.Context, vfs iofs.FS, AssetsHandler http.Handler) (http.Handler, error) {
func NewAssetHandler(ctx context.Context, vfs iofs.FS, assetsHandler http.Handler) (http.Handler, error) {
if vfs != nil {
if _, err := vfs.Open("."); err != nil {
return nil, err
@ -51,7 +51,7 @@ func NewAssetHandler(ctx context.Context, vfs iofs.FS, AssetsHandler http.Handle
result := &assetHandler{
fs: vfs,
handler: AssetsHandler,
handler: assetsHandler,
}
if _logger := ctx.Value("logger"); _logger != nil {

View file

@ -31,8 +31,8 @@ type AssetServer struct {
appendSpinnerToBody bool
}
func NewAssetServer(ctx context.Context, vfs iofs.FS, AssetsHandler http.Handler, bindingsJSON string) (*AssetServer, error) {
handler, err := NewAssetHandler(ctx, vfs, AssetsHandler)
func NewAssetServer(ctx context.Context, vfs iofs.FS, assetsHandler http.Handler, bindingsJSON string) (*AssetServer, error) {
handler, err := NewAssetHandler(ctx, vfs, assetsHandler)
if err != nil {
return nil, err
}

View file

@ -82,6 +82,14 @@ func (f *Frontend) WindowClose() {
C.ReleaseContext(f.mainWindow.context)
}
func (f *Frontend) RunMainLoop() {
C.RunMainLoop()
}
func (f *Frontend) WindowClose() {
C.ReleaseContext(f.mainWindow.context)
}
func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.Logger, appBindings *binding.Bindings, dispatcher frontend.Dispatcher) *Frontend {
result := &Frontend{
frontendOptions: appoptions,
@ -174,9 +182,7 @@ func (f *Frontend) WindowSetDarkTheme() {
}
func (f *Frontend) Run(ctx context.Context) error {
f.ctx = context.WithValue(ctx, "frontend", f)
f.ctx = ctx
var _debug = ctx.Value("debug")
if _debug != nil {
f.debug = _debug.(bool)

View file

@ -21,6 +21,7 @@ import (
"os"
"runtime"
"strconv"
"strings"
"text/template"
"unsafe"
@ -141,8 +142,7 @@ func (f *Frontend) WindowSetDarkTheme() {
}
func (f *Frontend) Run(ctx context.Context) error {
f.ctx = context.WithValue(ctx, "frontend", f)
f.ctx = ctx
go func() {
if f.frontendOptions.OnStartup != nil {
@ -183,10 +183,16 @@ func (f *Frontend) WindowSetTitle(title string) {
}
func (f *Frontend) WindowFullscreen() {
if f.frontendOptions.Frameless && f.frontendOptions.DisableResize == false {
f.ExecJS("window.wails.flags.enableResize = false;")
}
f.mainWindow.Fullscreen()
}
func (f *Frontend) WindowUnfullscreen() {
if f.frontendOptions.Frameless && f.frontendOptions.DisableResize == false {
f.ExecJS("window.wails.flags.enableResize = true;")
}
f.mainWindow.UnFullscreen()
}
@ -289,6 +295,17 @@ func (f *Frontend) Notify(name string, data ...interface{}) {
f.mainWindow.ExecJS(`window.wails.EventsNotify('` + template.JSEscapeString(string(payload)) + `');`)
}
var edgeMap = map[string]uintptr{
"n-resize": C.GDK_WINDOW_EDGE_NORTH,
"ne-resize": C.GDK_WINDOW_EDGE_NORTH_EAST,
"e-resize": C.GDK_WINDOW_EDGE_EAST,
"se-resize": C.GDK_WINDOW_EDGE_SOUTH_EAST,
"s-resize": C.GDK_WINDOW_EDGE_SOUTH,
"sw-resize": C.GDK_WINDOW_EDGE_SOUTH_WEST,
"w-resize": C.GDK_WINDOW_EDGE_WEST,
"nw-resize": C.GDK_WINDOW_EDGE_NORTH_WEST,
}
func (f *Frontend) processMessage(message string) {
if message == "DomReady" {
if f.frontendOptions.OnDomReady != nil {
@ -304,9 +321,29 @@ func (f *Frontend) processMessage(message string) {
return
}
if strings.HasPrefix(message, "resize:") {
if !f.mainWindow.IsFullScreen() {
sl := strings.Split(message, ":")
if len(sl) != 2 {
f.logger.Info("Unknown message returned from dispatcher: %+v", message)
return
}
edge := edgeMap[sl[1]]
err := f.startResize(edge)
if err != nil {
f.logger.Error(err.Error())
}
}
return
}
if message == "runtime:ready" {
cmd := fmt.Sprintf("window.wails.setCSSDragProperties('%s', '%s');", f.frontendOptions.CSSDragProperty, f.frontendOptions.CSSDragValue)
f.ExecJS(cmd)
if f.frontendOptions.Frameless && f.frontendOptions.DisableResize == false {
f.ExecJS("window.wails.flags.enableResize = true;")
}
return
}
@ -339,6 +376,11 @@ func (f *Frontend) startDrag() {
f.mainWindow.StartDrag()
}
func (f *Frontend) startResize(edge uintptr) error {
f.mainWindow.StartResize(edge)
return nil
}
func (f *Frontend) ExecJS(js string) {
f.mainWindow.ExecJS(js)
}

View file

@ -159,11 +159,12 @@ ulong setupInvokeSignal(void* contentManager) {
return g_signal_connect((WebKitUserContentManager*)contentManager, "script-message-received::external", G_CALLBACK(sendMessageToBackend), NULL);
}
// These are the x,y & time of the last mouse down event
// These are the x,y,time & button of the last mouse down event
// It's used for window dragging
float xroot = 0.0f;
float yroot = 0.0f;
int dragTime = -1;
uint mouseButton = 0;
bool contextMenuDisabled = false;
gboolean buttonPress(GtkWidget *widget, GdkEventButton *event, void* dummy)
@ -173,7 +174,7 @@ gboolean buttonPress(GtkWidget *widget, GdkEventButton *event, void* dummy)
dragTime = -1;
return FALSE;
}
mouseButton = event->button;
if( event->button == 3 && contextMenuDisabled ) {
return TRUE;
}
@ -256,7 +257,7 @@ static gboolean startDrag(gpointer data) {
return G_SOURCE_REMOVE;
}
gtk_window_begin_move_drag(options->mainwindow, 1, xroot, yroot, dragTime);
gtk_window_begin_move_drag(options->mainwindow, mouseButton, xroot, yroot, dragTime);
free(data);
return G_SOURCE_REMOVE;
@ -269,6 +270,36 @@ static void StartDrag(void *webview, GtkWindow* mainwindow) {
ExecuteOnMainThread(startDrag, (gpointer)data);
}
typedef struct ResizeOptions {
void *webview;
GtkWindow* mainwindow;
GdkWindowEdge edge;
} ResizeOptions;
static gboolean startResize(gpointer data) {
ResizeOptions* options = (ResizeOptions*)data;
// Ignore non-toplevel widgets
GtkWidget *window = gtk_widget_get_toplevel(GTK_WIDGET(options->webview));
if (!GTK_IS_WINDOW(window)) {
free(data);
return G_SOURCE_REMOVE;
}
gtk_window_begin_resize_drag(options->mainwindow, options->edge, mouseButton, xroot, yroot, dragTime);
free(data);
return G_SOURCE_REMOVE;
}
static void StartResize(void *webview, GtkWindow* mainwindow, GdkWindowEdge edge) {
ResizeOptions* data = malloc(sizeof(ResizeOptions));
data->webview = webview;
data->mainwindow = mainwindow;
data->edge = edge;
ExecuteOnMainThread(startResize, (gpointer)data);
}
typedef struct JSCallback {
void* webview;
char* script;
@ -592,6 +623,17 @@ void SetWindowIcon(GtkWindow* window, const guchar* buf, gsize len) {
g_object_unref(loader);
}
static void SetWindowTransparency(GtkWidget *widget)
{
GdkScreen *screen = gtk_widget_get_screen(widget);
GdkVisual *visual = gdk_screen_get_rgba_visual(screen);
if (visual != NULL && gdk_screen_is_composited(screen)) {
gtk_widget_set_app_paintable(widget, true);
gtk_widget_set_visual(widget, visual);
}
}
*/
import "C"
import (
@ -683,6 +725,9 @@ func NewWindow(appoptions *options.App, debug bool) *Window {
if appoptions.Linux.Icon != nil {
result.SetWindowIcon(appoptions.Linux.Icon)
}
if appoptions.Linux.WindowIsTranslucent {
C.SetWindowTransparency(gtkWindow)
}
}
// Menu
@ -895,6 +940,10 @@ func (w *Window) StartDrag() {
C.StartDrag(w.webview, w.asGTKWindow())
}
func (w *Window) StartResize(edge uintptr) {
C.StartResize(w.webview, w.asGTKWindow(), C.GdkWindowEdge(edge))
}
func (w *Window) Quit() {
C.gtk_main_quit()
}

View file

@ -128,8 +128,7 @@ func (f *Frontend) WindowSetDarkTheme() {
}
func (f *Frontend) Run(ctx context.Context) error {
f.ctx = context.WithValue(ctx, "frontend", f)
f.ctx = ctx
mainWindow := NewWindow(nil, f.frontendOptions, f.versionInfo)
f.mainWindow = mainWindow

View file

@ -23,7 +23,6 @@ import (
"github.com/wailsapp/wails/v2/internal/frontend/assetserver"
"github.com/wailsapp/wails/v2/internal/logger"
"github.com/wailsapp/wails/v2/internal/menumanager"
"github.com/wailsapp/wails/v2/pkg/menu"
"github.com/wailsapp/wails/v2/pkg/options"
"golang.org/x/net/websocket"
)
@ -43,35 +42,11 @@ type DevWebServer struct {
starttime string
// Desktop frontend
desktopFrontend frontend.Frontend
frontend.Frontend
devServerAddr string
}
func (d *DevWebServer) Hide() {
d.desktopFrontend.Hide()
}
func (d *DevWebServer) Show() {
d.desktopFrontend.Show()
}
func (d *DevWebServer) TrayMenuAdd(trayMenu *menu.TrayMenu) menu.TrayMenuImpl {
return d.desktopFrontend.TrayMenuAdd(trayMenu)
}
func (d *DevWebServer) WindowSetSystemDefaultTheme() {
d.desktopFrontend.WindowSetSystemDefaultTheme()
}
func (d *DevWebServer) WindowSetLightTheme() {
d.desktopFrontend.WindowSetLightTheme()
}
func (d *DevWebServer) WindowSetDarkTheme() {
d.desktopFrontend.WindowSetDarkTheme()
}
func (d *DevWebServer) Run(ctx context.Context) error {
d.ctx = ctx
@ -87,7 +62,7 @@ func (d *DevWebServer) Run(ctx context.Context) error {
})
var err error
assetHandler, err = assetserver.NewAssetHandler(ctx, d.appoptions)
assetHandler, err = assetserver.NewAssetHandler(ctx, d.appoptions.Assets, d.appoptions.AssetsHandler)
if err != nil {
log.Fatal(err)
}
@ -136,162 +111,22 @@ func (d *DevWebServer) Run(ctx context.Context) error {
}(d.server, d.logger)
d.LogDebug("Serving DevServer at http://%s", devServerAddr)
defer func() {
err := d.server.Shutdown(context.Background())
if err != nil {
d.logger.Error(err.Error())
}
}()
}
// Launch desktop app
err = d.desktopFrontend.Run(ctx)
d.LogDebug("Starting shutdown")
err = d.Frontend.Run(ctx)
return err
}
func (d *DevWebServer) Quit() {
d.desktopFrontend.Quit()
}
func (d *DevWebServer) OpenFileDialog(dialogOptions frontend.OpenDialogOptions) (string, error) {
return d.desktopFrontend.OpenFileDialog(dialogOptions)
}
func (d *DevWebServer) OpenMultipleFilesDialog(dialogOptions frontend.OpenDialogOptions) ([]string, error) {
return d.OpenMultipleFilesDialog(dialogOptions)
}
func (d *DevWebServer) OpenDirectoryDialog(dialogOptions frontend.OpenDialogOptions) (string, error) {
return d.OpenDirectoryDialog(dialogOptions)
}
func (d *DevWebServer) SaveFileDialog(dialogOptions frontend.SaveDialogOptions) (string, error) {
return d.desktopFrontend.SaveFileDialog(dialogOptions)
}
func (d *DevWebServer) MessageDialog(dialogOptions frontend.MessageDialogOptions) (string, error) {
return d.desktopFrontend.MessageDialog(dialogOptions)
}
func (d *DevWebServer) WindowReload() {
d.broadcast("reload")
d.desktopFrontend.WindowReload()
d.Frontend.WindowReload()
}
func (d *DevWebServer) WindowReloadApp() {
d.broadcast("reloadapp")
d.desktopFrontend.WindowReloadApp()
}
func (d *DevWebServer) WindowSetTitle(title string) {
d.desktopFrontend.WindowSetTitle(title)
}
func (d *DevWebServer) WindowShow() {
d.desktopFrontend.WindowShow()
}
func (d *DevWebServer) WindowHide() {
d.desktopFrontend.WindowHide()
}
func (d *DevWebServer) WindowCenter() {
d.desktopFrontend.WindowCenter()
}
func (d *DevWebServer) WindowMaximise() {
d.desktopFrontend.WindowMaximise()
}
func (d *DevWebServer) WindowToggleMaximise() {
d.desktopFrontend.WindowToggleMaximise()
}
func (d *DevWebServer) WindowUnmaximise() {
d.desktopFrontend.WindowUnmaximise()
}
func (d *DevWebServer) WindowIsMaximised() bool {
return d.desktopFrontend.WindowIsMaximised()
}
func (d *DevWebServer) WindowMinimise() {
d.desktopFrontend.WindowMinimise()
}
func (d *DevWebServer) WindowUnminimise() {
d.desktopFrontend.WindowUnminimise()
}
func (d *DevWebServer) WindowSetAlwaysOnTop(b bool) {
d.desktopFrontend.WindowSetAlwaysOnTop(b)
}
func (d *DevWebServer) WindowIsMinimised() bool {
return d.desktopFrontend.WindowIsMinimised()
}
func (d *DevWebServer) WindowSetPosition(x int, y int) {
d.desktopFrontend.WindowSetPosition(x, y)
}
func (d *DevWebServer) WindowGetPosition() (int, int) {
return d.desktopFrontend.WindowGetPosition()
}
func (d *DevWebServer) WindowSetSize(width int, height int) {
d.desktopFrontend.WindowSetSize(width, height)
}
func (d *DevWebServer) WindowGetSize() (int, int) {
return d.desktopFrontend.WindowGetSize()
}
func (d *DevWebServer) WindowSetMinSize(width int, height int) {
d.desktopFrontend.WindowSetMinSize(width, height)
}
func (d *DevWebServer) WindowSetMaxSize(width int, height int) {
d.desktopFrontend.WindowSetMaxSize(width, height)
}
func (d *DevWebServer) WindowFullscreen() {
d.desktopFrontend.WindowFullscreen()
}
func (d *DevWebServer) WindowUnfullscreen() {
d.desktopFrontend.WindowUnfullscreen()
}
func (d *DevWebServer) WindowSetBackgroundColour(col *options.RGBA) {
d.desktopFrontend.WindowSetBackgroundColour(col)
}
func (d *DevWebServer) ScreenGetAll() ([]Screen, error) {
return d.desktopFrontend.ScreenGetAll()
}
func (d *DevWebServer) WindowIsFullscreen() bool {
return d.desktopFrontend.WindowIsFullscreen()
}
func (d *DevWebServer) WindowIsNormal() bool {
return d.desktopFrontend.WindowIsNormal()
}
func (d *DevWebServer) MenuSetApplicationMenu(menu *menu.Menu) {
d.desktopFrontend.MenuSetApplicationMenu(menu)
}
func (d *DevWebServer) MenuUpdateApplicationMenu() {
d.desktopFrontend.MenuUpdateApplicationMenu()
}
// BrowserOpenURL uses the system default browser to open the url
func (d *DevWebServer) BrowserOpenURL(url string) {
d.desktopFrontend.BrowserOpenURL(url)
d.Frontend.WindowReloadApp()
}
func (d *DevWebServer) Notify(name string, data ...interface{}) {
@ -302,6 +137,7 @@ func (d *DevWebServer) handleReload(c echo.Context) error {
d.WindowReload()
return c.NoContent(http.StatusNoContent)
}
func (d *DevWebServer) handleReloadApp(c echo.Context) error {
d.WindowReloadApp()
return c.NoContent(http.StatusNoContent)
@ -430,13 +266,13 @@ func (d *DevWebServer) notifyExcludingSender(eventMessage []byte, sender *websoc
d.logger.Error(err.Error())
return
}
d.desktopFrontend.Notify(notifyMessage.Name, notifyMessage.Data...)
d.Frontend.Notify(notifyMessage.Name, notifyMessage.Data...)
}
func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.Logger, appBindings *binding.Bindings, dispatcher frontend.Dispatcher, menuManager *menumanager.Manager, desktopFrontend frontend.Frontend) *DevWebServer {
result := &DevWebServer{
ctx: ctx,
desktopFrontend: desktopFrontend,
Frontend: desktopFrontend,
appoptions: appoptions,
logger: myLogger,
appBindings: appBindings,

View file

@ -66,6 +66,7 @@ type MessageDialogOptions struct {
type Frontend interface {
Run(context.Context) error
RunMainLoop()
ExecJS(js string)
Hide()
Show()
Quit()

View file

@ -122,6 +122,11 @@ function setResize(cursor) {
}
window.addEventListener('mousemove', function (e) {
let mousePressed = e.buttons !== undefined ? e.buttons : e.which;
if(window.wails.flags.shouldDrag && mousePressed <= 0) {
window.wails.flags.shouldDrag = false;
}
if (window.wails.flags.shouldDrag) {
window.WailsInvoke("drag");
return;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -3,14 +3,16 @@ package typescriptify
import (
"bufio"
"fmt"
"github.com/leaanthony/slicer"
"io/ioutil"
"os"
"path"
"reflect"
"regexp"
"strings"
"time"
"github.com/leaanthony/slicer"
"github.com/tkrajina/go-reflector/reflector"
)
@ -34,6 +36,7 @@ const (
}
return a;
}`
jsVariableNameRegex = `^([A-Z]|[a-z]|\$|_)([A-Z]|[a-z]|[0-9]|\$|_)*$`
)
// TypeOptions overrides options set by `ts_*` tags.
@ -266,20 +269,34 @@ func (t *typeScriptClassBuilder) AddMapField(fieldName string, field reflect.Str
if valueType.Kind() == reflect.Ptr {
valueTypeName = valueType.Elem().Name()
}
if valueType.Kind() == reflect.Struct && differentNamespaces(t.namespace, valueType) {
valueTypeName = valueType.String()
}
strippedFieldName := strings.ReplaceAll(fieldName, "?", "")
isOptional := strings.HasSuffix(fieldName, "?")
keyTypeStr := keyType.Name()
// Key should always be string, no need for this:
// _, isSimple := t.types[keyType.Kind()]
// if !isSimple {
// keyTypeStr = t.prefix + keyType.Name() + t.suffix
// }
keyTypeStr := ""
// Key should always be a JS primitive. JS will read it as a string either way.
if typeStr, isSimple := t.types[keyType.Kind()]; isSimple {
keyTypeStr = typeStr
} else {
keyTypeStr = t.types[reflect.String]
}
var dotField string
if regexp.MustCompile(jsVariableNameRegex).Match([]byte(strippedFieldName)) {
dotField = fmt.Sprintf(".%s", strippedFieldName)
} else {
dotField = fmt.Sprintf(`["%s"]`, strippedFieldName)
if isOptional {
fieldName = fmt.Sprintf(`"%s"?`, strippedFieldName)
}
}
t.fields = append(t.fields, fmt.Sprintf("%s%s: {[key: %s]: %s};", t.indent, fieldName, keyTypeStr, valueTypeName))
if valueType.Kind() == reflect.Struct {
t.constructorBody = append(t.constructorBody, fmt.Sprintf("%s%sthis.%s = this.convertValues(source[\"%s\"], %s, true);", t.indent, t.indent, strippedFieldName, strippedFieldName, t.prefix+valueTypeName+t.suffix))
t.constructorBody = append(t.constructorBody, fmt.Sprintf("%s%sthis%s = this.convertValues(source[\"%s\"], %s, true);", t.indent, t.indent, dotField, strippedFieldName, t.prefix+valueTypeName+t.suffix))
} else {
t.constructorBody = append(t.constructorBody, fmt.Sprintf("%s%sthis.%s = source[\"%s\"];", t.indent, t.indent, strippedFieldName, strippedFieldName))
t.constructorBody = append(t.constructorBody, fmt.Sprintf("%s%sthis%s = source[\"%s\"];", t.indent, t.indent, dotField, strippedFieldName))
}
}
@ -571,11 +588,8 @@ func (t *TypeScriptify) convertType(depth int, typeOf reflect.Type, customCode m
return "", nil
}
t.logf(depth, "Converting type %s", typeOf.String())
if strings.ContainsRune(typeOf.String(), '.') {
namespace := strings.Split(typeOf.String(), ".")[0]
if namespace != t.Namespace {
return "", nil
}
if differentNamespaces(t.Namespace, typeOf) {
return "", nil
}
t.alreadyConverted[typeOf.String()] = true
@ -829,17 +843,34 @@ func (t *typeScriptClassBuilder) AddStructField(fieldName string, field reflect.
func (t *typeScriptClassBuilder) AddArrayOfStructsField(fieldName string, field reflect.StructField, arrayDepth int) {
fieldType := field.Type.Elem().Name()
if differentNamespaces(t.namespace, field.Type.Elem()) {
fieldType = field.Type.Elem().String()
}
strippedFieldName := strings.ReplaceAll(fieldName, "?", "")
t.addField(fieldName, fmt.Sprint(t.prefix+fieldType+t.suffix, strings.Repeat("[]", arrayDepth)), false)
t.addInitializerFieldLine(strippedFieldName, fmt.Sprintf("this.convertValues(source[\"%s\"], %s)", strippedFieldName, t.prefix+fieldType+t.suffix))
}
func (t *typeScriptClassBuilder) addInitializerFieldLine(fld, initializer string) {
t.createFromMethodBody = append(t.createFromMethodBody, fmt.Sprint(t.indent, t.indent, "result.", fld, " = ", initializer, ";"))
t.constructorBody = append(t.constructorBody, fmt.Sprint(t.indent, t.indent, "this.", fld, " = ", initializer, ";"))
var dotField string
if regexp.MustCompile(jsVariableNameRegex).Match([]byte(fld)) {
dotField = fmt.Sprintf(".%s", fld)
} else {
dotField = fmt.Sprintf(`["%s"]`, fld)
}
t.createFromMethodBody = append(t.createFromMethodBody, fmt.Sprint(t.indent, t.indent, "result", dotField, " = ", initializer, ";"))
t.constructorBody = append(t.constructorBody, fmt.Sprint(t.indent, t.indent, "this", dotField, " = ", initializer, ";"))
}
func (t *typeScriptClassBuilder) addField(fld, fldType string, isAnyType bool) {
isOptional := strings.HasSuffix(fld, "?")
strippedFieldName := strings.ReplaceAll(fld, "?", "")
if !regexp.MustCompile(jsVariableNameRegex).Match([]byte(strippedFieldName)) {
fld = fmt.Sprintf(`"%s"`, fld)
if isOptional {
fld += "?"
}
}
if isAnyType {
t.fields = append(t.fields, fmt.Sprint(t.indent, "// Go type: ", fldType, "\n", t.indent, fld, ": any;"))
} else {
@ -860,3 +891,13 @@ func getStructFQN(in string) string {
result = strings.ReplaceAll(result, "*", "")
return result
}
func differentNamespaces(namespace string, typeOf reflect.Type) bool {
if strings.ContainsRune(typeOf.String(), '.') {
typeNamespace := strings.Split(typeOf.String(), ".")[0]
if namespace != typeNamespace {
return true
}
}
return false
}

View file

@ -108,6 +108,20 @@ func (b *BaseBuilder) CleanUp() {
})
}
func commandPrettifier(args []string) string {
// If we have a single argument, just return it
if len(args) == 1 {
return args[0]
}
// If an argument contains a space, quote it
for i, arg := range args {
if strings.Contains(arg, " ") {
args[i] = fmt.Sprintf("\"%s\"", arg)
}
}
return strings.Join(args, " ")
}
func (b *BaseBuilder) OutputFilename(options *Options) string {
outputFile := options.OutputFile
if outputFile == "" {
@ -270,7 +284,7 @@ func (b *BaseBuilder) CompileProject(options *Options) error {
cmd := exec.Command(compiler, commands.AsSlice()...)
cmd.Stderr = os.Stderr
if verbose {
println(" Build command:", compiler, commands.Join(" "))
println(" Build command:", compiler, commandPrettifier(commands.AsSlice()))
cmd.Stdout = os.Stdout
}
// Set the directory

View file

@ -35,3 +35,34 @@ func TestUpdateEnv(t *testing.T) {
}
}
func Test_commandPrettifier(t *testing.T) {
tests := []struct {
name string
input []string
want string
}{
{
name: "empty",
input: []string{},
want: "",
},
{
name: "one arg",
input: []string{"one"},
want: "one",
},
{
name: "args where one has spaces",
input: []string{"one", "two three"},
want: `one "two three"`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := commandPrettifier(tt.input); got != tt.want {
t.Errorf("commandPrettifier() = %v, want %v", got, tt.want)
}
})
}
}

View file

@ -2,5 +2,6 @@ package linux
// Options specific to Linux builds
type Options struct {
Icon []byte
Icon []byte
WindowIsTranslucent bool
}

View file

@ -163,6 +163,12 @@ func WindowIsNormal(ctx context.Context) bool {
return appFrontend.WindowIsNormal()
}
// WindowExecJS executes the given Js in the window
func WindowExecJS(ctx context.Context, js string) {
appFrontend := getFrontend(ctx)
appFrontend.ExecJS(js)
}
func WindowSetBackgroundColour(ctx context.Context, R, G, B, A uint8) {
appFrontend := getFrontend(ctx)
col := &options.RGBA{

View file

@ -22,3 +22,6 @@ The [definitive list](https://github.com/wailsapp/awesome-wails) of links relate
- [Twitter](https://twitter.com/wailsapp)
- [Wails Chinese Community QQ Group](https://qm.qq.com/cgi-bin/qm/qr?k=PmIURne5hFGNd7QWzW5qd6FV-INEjNJv&jump_from=webapi) - Group number: 1067173054
## Other Tutorials and Articles
- [Building of Bulletin Board](https://blog.customct.com/building-bulletin-board)

View file

@ -36,6 +36,7 @@ If you are unsure about a template, inspect `package.json` and `wails.json` for
- [wails-react-template](https://github.com/AlienRecall/wails-react-template) - A template using reactjs
- [wails-react-template](https://github.com/flin7/wails-react-template) - A minimal template for React that supports live development
- [wails-template-nextjs](https://github.com/LGiki/wails-template-nextjs) - A template using Next.js and TypeScript
- [wails-vite-react-ts-tailwind-template](https://github.com/hotafrika/wails-vite-react-ts-tailwind-template) - A template for React + TypeScript + Vite + TailwindCSS
## Svelte
@ -47,6 +48,7 @@ If you are unsure about a template, inspect `package.json` and `wails.json` for
## Elm
- [wails-elm-template](https://github.com/benjamin-thomas/wails-elm-template) - Develop your GUI app with functional programming and a **snappy** hot-reload setup :tada: :rocket:
- [wails-template-elm-tailwind](https://github.com/rnice01/wails-template-elm-tailwind) - Combine the powers :muscle: of Elm + Tailwind CSS + Wails! Hot reloading supported.
## Pure JavaScript (Vanilla)

View file

@ -5,13 +5,13 @@ Wails includes support for obfuscating your application using [garble](https://g
To produce an obfuscated build, you can use the `-obfuscate` flag with the `wails build` command:
```bash
wails build -obfuscate
wails build -obfuscated
```
To customise the obfuscation settings, you can use the `-garbleargs` flag:
```bash
wails build -obfuscate -garbleargs "-literals -tiny -seed=myrandomseed"
wails build -obfuscated -garbleargs "-literals -tiny -seed=myrandomseed"
```
These settings may be persisted in your [project config](../reference/project-config).

View file

@ -264,11 +264,12 @@ In the example above, `Greet` only returns a `string` so the Javascript call wil
is passed to it.
All data types are correctly translated between Go and Javascript. Even structs. If you return a struct from a Go call,
it will be returned to your frontend as a Javascript class. Note: If you wish to use structs, you **must** define
`json` struct tags for your fields!
it will be returned to your frontend as a Javascript class.
:::info Note
Struct fields *must* have a valid `json` tag to be included in the generated Typescript.
Anonymous nested structs are not supported at this time.
:::

View file

@ -89,6 +89,7 @@ func main() {
},
Linux: &linux.Options{
Icon: icon,
WindowIsTranslucent: false,
},
})
if err != nil {
@ -748,3 +749,10 @@ On KDE it should work.
The icon should be provided in whatever size it was naturally drawn; that is, dont scale the image before passing it.
Scaling is postponed until the last minute, when the desired final size is known, to allow best quality.
#### WindowIsTranslucent
Setting this to `true` will make the window background translucent. Some window managers may ignore it, or result in a black window.
Name: WindowIsTranslucent<br/>
Type: `bool`

View file

@ -41,6 +41,15 @@ Centers the window on the monitor the window is currently on.
Go: `WindowCenter(ctx context.Context)`<br/>
JS: `WindowCenter()`
### WindowExecJS
Executes arbitrary JS code in the window.
This method runs the code in the browser asynchronously and returns immediately.
If the script causes any errors, they will only be available in the browser console.
Go: `WindowExecJS(ctx context.Context, js string)`
### WindowReload
Performs a "reload" (Reloads current page).

View file

@ -3,7 +3,7 @@
"message": "豊富な機能"
},
"homepage.Features.Description1": {
"message": "Build comprehensive cross-platform applications using native UI elements such as menus and dialogs."
"message": "メニューやダイアログといったネイティブUI要素を使用して、クロスプラットフォームアプリを構築しましょう。"
},
"homepage.Features.Title2": {
"message": "使い慣れた技術"
@ -147,7 +147,7 @@
"description": "The ARIA label and title attribute for expand button of doc sidebar"
},
"theme.docs.sidebar.expandButtonAriaLabel": {
"message": "サイドバーを開",
"message": "サイドバーを",
"description": "The ARIA label and title attribute for expand button of doc sidebar"
},
"theme.docs.paginator.navAriaLabel": {
@ -167,7 +167,7 @@
"description": "The title attribute for collapse button of doc sidebar"
},
"theme.docs.sidebar.collapseButtonAriaLabel": {
"message": "サイドバーを折りたたむ",
"message": "サイドバーをたたむ",
"description": "The title attribute for collapse button of doc sidebar"
},
"theme.DocSidebarItem.toggleCollapsedCategoryAriaLabel": {
@ -242,7 +242,7 @@
"description": "The label used by the button on the collapsible TOC component"
},
"theme.navbar.mobileLanguageDropdown.label": {
"message": "言語一覧",
"message": "言語",
"description": "The label for the mobile language switcher dropdown"
},
"theme.SearchBar.seeAll": {

View file

@ -4,35 +4,35 @@
"description": "The label for version current"
},
"sidebar.docs.category.Getting Started": {
"message": "Getting Started",
"message": "はじめよう",
"description": "The label for category Getting Started in sidebar docs"
},
"sidebar.docs.category.Reference": {
"message": "Reference",
"message": "リファレンス",
"description": "The label for category Reference in sidebar docs"
},
"sidebar.docs.category.Runtime": {
"message": "Runtime",
"message": "ランタイム",
"description": "The label for category Runtime in sidebar docs"
},
"sidebar.docs.category.Community": {
"message": "Community",
"message": "コミュニティ",
"description": "The label for category Community in sidebar docs"
},
"sidebar.docs.category.Showcase": {
"message": "Showcase",
"message": "事例紹介",
"description": "The label for category Showcase in sidebar docs"
},
"sidebar.docs.category.Guides": {
"message": "Guides",
"message": "ガイド",
"description": "The label for category Guides in sidebar docs"
},
"sidebar.docs.category.Tutorials": {
"message": "Tutorials",
"message": "チュートリアル",
"description": "The label for category Tutorials in sidebar docs"
},
"sidebar.docs.link.Contributing": {
"message": "Contributing",
"message": "コントリビューション",
"description": "The label for link Contributing in sidebar docs, linking to /community-guide#ways-of-contributing"
}
}

View file

@ -21,3 +21,6 @@ The [definitive list](https://github.com/wailsapp/awesome-wails) of links relate
- [Twitter](https://twitter.com/wailsapp)
- [Wails Chinese Community QQ Group](https://qm.qq.com/cgi-bin/qm/qr?k=PmIURne5hFGNd7QWzW5qd6FV-INEjNJv&jump_from=webapi) - Group number: 1067173054
## Other Tutorials and Articles
- [Building of Bulletin Board](https://blog.customct.com/building-bulletin-board)

View file

@ -37,6 +37,7 @@ If you are unsure about a template, inspect `package.json` and `wails.json` for
- [wails-react-template](https://github.com/AlienRecall/wails-react-template) - A template using reactjs
- [wails-react-template](https://github.com/flin7/wails-react-template) - A minimal template for React that supports live development
- [wails-template-nextjs](https://github.com/LGiki/wails-template-nextjs) - A template using Next.js and TypeScript
- [wails-vite-react-ts-tailwind-template](https://github.com/hotafrika/wails-vite-react-ts-tailwind-template) - A template for React + TypeScript + Vite + TailwindCSS
## Svelte
@ -49,6 +50,6 @@ If you are unsure about a template, inspect `package.json` and `wails.json` for
- [wails-elm-template](https://github.com/benjamin-thomas/wails-elm-template) - Develop your GUI app with functional programming and a **snappy** hot-reload setup :tada: :rocket:
## Pure JavaScript (Vanilla)
## ピュアJavaScript (バニラ)
- [wails-pure-js-template](https://github.com/KiddoV/wails-pure-js-template) - A template with nothing but just basic JavaScript, HTML, and CSS
- [wails-pure-js-template](https://github.com/KiddoV/wails-pure-js-template) - 基本的なJavaScript、HTML、CSSのみを含むテンプレート

View file

@ -2,11 +2,11 @@
sidebar_position: 6
---
# Compiling your Project
# プロジェクトのコンパイル
From the project directory, run `wails build`. This will compile your project and save the production-ready binary in the `build/bin` directory.
プロジェクトディレクトリ上で、`wails build`コマンドを実行しましょう。 そうすることで、プロジェクトがコンパイルされ、`build/bin`ディレクトリ内に本番配布用のバイナリが出力されます。
If you run the binary, you should see the default application:
バイナリを起動すると、デフォルト仕様のアプリを確認することができます:
```mdx-code-block
<div class="text--center">
@ -19,4 +19,4 @@ If you run the binary, you should see the default application:
<br />
```
For more details on compilation options, please refer to the [CLI Reference](../reference/cli.mdx#build).
コンパイルオプションについて詳しくは、[CLIリファレンス](../reference/cli.mdx#build)をご覧ください。

View file

@ -2,15 +2,15 @@
sidebar_position: 5
---
# Developing your Application
# アプリの開発
You can run your application in development mode by running `wails dev` from your project directory. This will do the following things:
プロジェクトディレクトリのルート上で`wails dev`コマンドを実行すると、アプリを開発モードで起動することができます。 コマンドを実行すると下記の処理が実行されます:
- Build your application and run it
- Bind your Go code to the frontend so it can be called from Javascript
- アプリをビルドしたのち、起動する
- Goのコードをフロントエンドにバインドし、Javascriptから呼び出せるようにする
- Using the power of [Vite](https://vitejs.dev/), will watch for modifications in your Go files and rebuild/re-run on change
- Sets up a [webserver](http://localhost:34115) that will serve your application over a browser. This allows you to use your favourite browser extensions. You can even call your Go code from the console
- ブラウザからアプリを操作できるようにする[Webサーバ](http://localhost:34115)を立ち上げる。 これにより、任意のブラウザ拡張機能を利用できる。 JavascriptのコンソールからGoのコードを呼び出すこともできる
To get started, run `wails dev` in the project directory. More information on this can be found [here](../reference/cli.mdx#dev).
アプリ開発を始めるときは、プロジェクトディレクトリ上で`wails dev`コマンドを実行しましょう。 詳しくは、[こちら](../reference/cli.mdx#dev)をご覧ください。
Coming soon: Tutorial
近日中にチュートリアルを公開予定です。

View file

@ -2,13 +2,13 @@
sidebar_position: 2
---
# Creating a Project
# プロジェクトの開始
## Project Generation
## プロジェクトの生成
Now that the CLI is installed, you can generate a new project by using the `wails init` command.
CLIのインストールが終わったら、`wails init`コマンドで新しいプロジェクトを生成しましょう。
Pick your favourite framework:
好きなフレームワークを選択してください:
```mdx-code-block
import Tabs from "@theme/Tabs";
@ -90,13 +90,13 @@ If you would rather use Typescript:<br/>
<hr />
There are also [community templates](../community/templates.mdx) available that offer different capabilities and frameworks.
様々な機能やフレームワークを提供する[コミュニティテンプレート](../community/templates.mdx)を利用することもできます。
To see the other options available, you can run `wails init -help`. More details can be found in the [CLI Reference](../reference/cli.mdx#init).
プロジェクト生成時に使用可能なオプションを確認するには、`wails init -help`を実行してください。 詳しくは、[CLIリファレンス](../reference/cli.mdx#init)を参照してください。
## Project Layout
## プロジェクトのディレクトリ構成
Wails projects have the following layout:
Wailsのプロジェクトディレクトリの構成は次のとおりです:
```
.
@ -111,20 +111,20 @@ Wails projects have the following layout:
└── wails.json
```
### Project structure rundown
### プロジェクトの構造
- `/main.go` - The main application
- `/frontend/` - Frontend project files
- `/build/` - Project build directory
- `/build/appicon.png` - The application icon
- `/build/darwin/` - Mac specific project files
- `/build/windows/` - Windows specific project files
- `/wails.json` - The project configuration
- `/go.mod` - Go module file
- `/go.sum` - Go module checksum file
- `/main.go` - アプリのメインコード
- `/frontend/` - フロントエンドのプロジェクトディレクトリ
- `/build/` - ビルドディレクトリ
- `/build/appicon.png` - アプリアイコン
- `/build/darwin/` - Mac固有のプロジェクトディレクトリ
- `/build/windows/` - Windows固有のプロジェクトディレクトリ
- `/wails.json` - プロジェクト構成ファイル
- `/go.mod` - Goモジュール定義ファイル
- `/go.sum` - Goモジュールチェックサムファイル
The `frontend` directory has nothing specific to Wails and can be any frontend project of your choosing.
`frontend`ディレクトリ内は、Wailsで決まったファイル構成等は無く、お好きなフロントエンドプロジェクトを配置することができます。
The `build` directory is used during the build process. These files may be updated to customise your builds. If files are removed from the build directory, default versions will be regenerated.
`build`ディレクトリは、アプリのビルド時に使用されます。 この中のファイルは、ビルドの挙動をカスタマイズするために、適宜ファイル内容を書き換えることができます。 buildディレクトリ内のファイルを削除すると、デフォルトのファイルが再生成されます。
The default module name in `go.mod` is "changeme". You should change this to something more appropriate.
`go.mod`のモジュール名は、最初は"changeme"になっています。 このモジュール名は、あなたのプロジェクトに適切な名前に変更しましょう。

View file

@ -2,18 +2,18 @@
sidebar_position: 1
---
# Installation
# インストール
## Supported Platforms
## サポートされているプラットフォーム
- Windows 10/11 AMD64/ARM64
- MacOS 10.13+ AMD64
- MacOS 11.0+ ARM64
- Linux AMD64/ARM64
## Dependencies
## 依存関係
Wails has a number of common dependencies that are required before installation:
Wailsをインストールする前に、下記のものを導入しておく必要があります。
- Go 1.18+
- NPM (Node 15+)
@ -22,20 +22,20 @@ Wails has a number of common dependencies that are required before installation:
Download Go from the [Go Downloads Page](https://go.dev/dl/).
Ensure that you follow the official [Go installation instructions](https://go.dev/doc/install). You will also need to ensure that your `PATH` environment variable also includes the path to your `~/go/bin` directory. Restart your terminal and do the following checks:
公式の[Goインストール手順](https://go.dev/doc/install)に従って、Goをインストールしてください。 その際、`PATH`環境変数に`~/go/bin`ディレクトリへのパスが含まれていることも確認してください。 それらが終わったら、ターミナルを再起動し、以下の確認をしてください:
- Check Go is installed correctly: `go version`
- Check "~/go/bin" is in your PATH variable: `echo $PATH | grep go/bin`
- Goが正しくインストールされているかを確認する: `go version`
- "~/go/bin"のディレクトリパスがPATH環境変数に含まれているか確認する: `echo $PATH | grep go/bin`
### NPM
Download NPM from the [Node Downloads Page](https://nodejs.org/en/download/). It is best to use the latest release as that is what we generally test against.
[Nodeダウンロードページ](https://nodejs.org/ja/download/)からNPMをダウンロードしてください。 最新版を利用することをお勧めします。なぜなら、私たちは最新版に対してテストを実施しているためです。
Run `npm --version` to verify.
`npm --version`を実行して、インストールが完了しているかを確認してください。
## Platform Specific Dependencies
## プラットフォーム固有の依存関係
You will also need to install platform specific dependencies:
開発作業を行うプラットフォームによって、必要な依存関係が存在します:
```mdx-code-block
import Tabs from "@theme/Tabs";
@ -62,18 +62,18 @@ import TabItem from "@theme/TabItem";
</Tabs>
```
## Optional Dependencies
## 任意の依存関係
- [UPX](https://upx.github.io/) for compressing your applications.
- [UPX](https://upx.github.io/)を導入することで、構築したアプリを圧縮できます。
## Installing Wails
## Wailsのインストール
Run `go install github.com/wailsapp/wails/v2/cmd/wails@latest` to install the Wails CLI.
`go install github.com/wailsapp/wails/v2/cmd/wails@latest`を実行して、Wails CLIをインストールしてください。
## System Check
## システムチェック
Running `wails doctor` will check if you have the correct dependencies installed. If not, it will advise on what is missing and help on how to rectify any problems.
`wails doctor`を実行すると、必要な依存関係が正しくインストールされているかを確認することができます。 正しくインストールされていない場合は、その内容をあなたにお知らせして、どうすれば解決できるかを教えてくれます。
## The `wails` command appears to be missing?
## `wails`コマンドが見つからないのですが?
If your system is reporting that the `wails` command is missing, make sure you have followed the Go installation guide correctly. Normally, it means that the `go/bin` directory in your User's home directory is not in the `PATH` environment variable. You will also normally need to close and reopen any open command prompts so that changes to the environment made by the installer are reflected at the command prompt.
`wails`コマンドが見つからないとシステムに怒られた場合は、Goが、公式のGoインストール手順に従って導入されているかを確認してください。 コマンドが見つからないほとんどの理由は、あなたのホームディレクトリ配下にある`go/bin`ディレクトリのパスが、`PATH`環境変数に含まれていないからです。 また、インストールによって行われた環境変更を反映させるために、もともと開いていたコマンドプロンプト(ターミナル)がある場合はそれらをいったん閉じて、再度開きなおしてください。

View file

@ -106,13 +106,13 @@ However, if we request `go.mod`, we will see the following output:
This technique can be used to load images directly into the page. If we updated our default vanilla template and replaced the logo image:
```html
<img id="logo" class="logo">
<img id="logo" class="logo" />
```
with:
```html
<img src="build/appicon.png" style="width: 300px">
<img src="build/appicon.png" style="width: 300px" />
```
Then we would see the following:

View file

@ -39,7 +39,7 @@ To provide more flexibility to developers, there is a meta tag that may be used
The options are as follows:
| Value | Description |
| | Description |
| ------------------- | ------------------------------------------------ |
| noautoinjectruntime | Disable the autoinjection of `/wails/runtime.js` |
| noautoinjectipc | Disable the autoinjection of `/wails/ipc.js` |

View file

@ -21,36 +21,44 @@ The 2 files generated are `tasks.json` and `launch.json`. Below are the files ge
```json title="tasks.json"
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"options": {
"cwd": "${workspaceFolder}"
},
"command": "go",
"args": ["build", "-tags", "dev", "-gcflags", "all=-N -l", "-o", "build/bin/myproject.exe"]
},
]
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"options": {
"cwd": "${workspaceFolder}"
},
"command": "go",
"args": [
"build",
"-tags",
"dev",
"-gcflags",
"all=-N -l",
"-o",
"build/bin/myproject.exe"
]
}
]
}
```
```json title="launch.json"
{
"version": "0.2.0",
"configurations": [
{
"name": "Wails: Debug myproject",
"type": "go",
"request": "launch",
"mode": "exec",
"program": "${workspaceFolder}/build/bin/myproject.exe",
"preLaunchTask": "build",
"cwd": "${workspaceFolder}",
"env": {}
},
]
"version": "0.2.0",
"configurations": [
{
"name": "Wails: Debug myproject",
"type": "go",
"request": "launch",
"mode": "exec",
"program": "${workspaceFolder}/build/bin/myproject.exe",
"preLaunchTask": "build",
"cwd": "${workspaceFolder}",
"env": {}
}
]
}
```
@ -60,51 +68,55 @@ The `tasks.json` file is simple for the default project as there is no `npm inst
```json title="tasks.json"
{
"version": "2.0.0",
"tasks": [
{
"label": "npm install",
"type": "npm",
"script": "install",
"options": {
"cwd": "${workspaceFolder}/frontend"
},
"presentation": {
"clear": true,
"panel": "shared",
"showReuseMessage": false
},
"problemMatcher": []
},
{
"label": "npm run build",
"type": "npm",
"script": "build",
"options": {
"cwd": "${workspaceFolder}/frontend"
},
"presentation": {
"clear": true,
"panel": "shared",
"showReuseMessage": false
},
"problemMatcher": []
},
{
"label": "build",
"type": "shell",
"options": {
"cwd": "${workspaceFolder}"
},
"command": "go",
"args": ["build", "-tags", "dev", "-gcflags", "all=-N -l", "-o", "build/bin/vscode.exe"],
"dependsOn":[
"npm install",
"npm run build"
]
},
]
"version": "2.0.0",
"tasks": [
{
"label": "npm install",
"type": "npm",
"script": "install",
"options": {
"cwd": "${workspaceFolder}/frontend"
},
"presentation": {
"clear": true,
"panel": "shared",
"showReuseMessage": false
},
"problemMatcher": []
},
{
"label": "npm run build",
"type": "npm",
"script": "build",
"options": {
"cwd": "${workspaceFolder}/frontend"
},
"presentation": {
"clear": true,
"panel": "shared",
"showReuseMessage": false
},
"problemMatcher": []
},
{
"label": "build",
"type": "shell",
"options": {
"cwd": "${workspaceFolder}"
},
"command": "go",
"args": [
"build",
"-tags",
"dev",
"-gcflags",
"all=-N -l",
"-o",
"build/bin/vscode.exe"
],
"dependsOn": ["npm install", "npm run build"]
}
]
}
```

View file

@ -5,13 +5,13 @@ Wails includes support for obfuscating your application using [garble](https://g
To produce an obfuscated build, you can use the `-obfuscate` flag with the `wails build` command:
```bash
wails build -obfuscate
wails build -obfuscated
```
To customise the obfuscation settings, you can use the `-garbleargs` flag:
```bash
wails build -obfuscate -garbleargs "-literals -tiny -seed=myrandomseed"
wails build -obfuscated -garbleargs "-literals -tiny -seed=myrandomseed"
```
These settings may be persisted in your [project config](../reference/project-config).

View file

@ -22,7 +22,7 @@ const router = createRouter({
The recommended approach for routing in Angular is [HashLocationStrategy](https://codecraft.tv/courses/angular/routing/routing-strategies#_hashlocationstrategy):
```ts
RouterModule.forRoot(routes, {useHash: true})
RouterModule.forRoot(routes, { useHash: true });
```
## React

View file

@ -16,23 +16,24 @@ on:
workflow_dispatch:
# This Action only starts when you go to Actions and manually run the workflow.
- name: Get Wails
run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
- name: Build Wails app
run: |
wails build
- name: upload artifacts macOS
if: matrix.platform == 'macos-latest'
uses: actions/upload-artifact@v2
jobs:
package:
strategy:
matrix:
platform: [windows-latest, macos-latest]
go-version: [1.18]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v2
- name: Install Go
uses: actions/setup-go@v2
with:
name: wails-binaries-macos
path: build/bin/*
- name: upload artifacts windows
if: matrix.platform == 'windows-latest'
uses: actions/upload-artifact@v2
go-version: ${{ matrix.go-version }}
- name: setup node
uses: actions/setup-node@v2
with:
name: wails-binaries-windows
path: build/bin/*
node-version: 14
# You may need to manually build you frontend manually here, unless you have configured frontend build and install commands in wails.json.
- name: Get Wails
run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
- name: Build Wails app
@ -58,7 +59,7 @@ Next we need to give the GitHub workflow access to our signing certificate. This
certutil -encode .\my-cert.p12 my-cert-base64.txt
```
You should now have your .txt file with the base64 encoded certificate. Now you need to make two action secrets on GitHub. Now you need to make two action secrets on GitHub. Navigate to *Settings -> Secrets -> Actions* and create the two following secrets:
You should now have your .txt file with the base64 encoded certificate. It should start with _-----BEGIN CERTIFICATE-----_ and end with _-----END CERTIFICATE-----_. Now you need to make two action secrets on GitHub. Navigate to _Settings -> Secrets -> Actions_ and create the two following secrets:
- **WIN_SIGNING_CERT** with the contents of your base64 encoded certificate text.
- **WIN_SIGNING_CERT_PASSWORD** with the contents of your certificate password.

View file

@ -2,9 +2,9 @@
An assortment of troubleshooting tips.
## The `wails` command appears to be missing?
## `wails`コマンドが見つからないのですが?
If your system is reporting that the `wails` command is missing, make sure you have followed the Go installation guide correctly. Normally, it means that the `go/bin` directory in your User's home directory is not in the `PATH` environment variable. You will also normally need to close and reopen any open command prompts so that changes to the environment made by the installer are reflected at the command prompt.
`wails`コマンドが見つからないとシステムに怒られた場合は、Goが、公式のGoインストール手順に従って導入されているかを確認してください。 コマンドが見つからないほとんどの理由は、あなたのホームディレクトリ配下にある`go/bin`ディレクトリのパスが、`PATH`環境変数に含まれていないからです。 また、インストールによって行われた環境変更を反映させるために、もともと開いていたコマンドプロンプト(ターミナル)がある場合はそれらをいったん閉じて、再度開きなおしてください。
## My application is displaying a white/blank screen

View file

@ -24,7 +24,7 @@ If you use the chocolatey package manager, run the following script:
choco install nsis
```
If you install NSIS manually, you need to add the *Bin* folder, which contains `makensis.exe`, in your NSIS installation to your path. [Here](https://www.architectryan.com/2018/03/17/add-to-the-path-on-windows-10/) is a good tutorial on how to add to path on Windows.
If you install NSIS manually, you need to add the _Bin_ folder, which contains `makensis.exe`, in your NSIS installation to your path. [Here](https://www.architectryan.com/2018/03/17/add-to-the-path-on-windows-10/) is a good tutorial on how to add to path on Windows.
### Linux

View file

@ -2,9 +2,9 @@
sidebar_position: 20
---
# How does it work?
# どうやって動いているの?
A Wails application is a standard Go application, with a webkit frontend. The Go part of the application consists of the application code and a runtime library that provides a number of useful operations, like controlling the application window. The frontend is a webkit window that will display the frontend assets. Also available to the frontend is a Javascript version of the runtime library. Finally, it is possible to bind Go methods to the frontend, and these will appear as Javascript methods that can be called, just as if they were local Javascript methods.
Wailsは、webkitフロントエンドを備えた、何の変哲もないGoアプリです。 アプリ全体のうちGoの部分は、アプリのコードと、ウィンドウ制御などの便利な機能を提供するランタイムライブラリで構成されています。 フロントエンドはwebkitウィンドウであり、フロンドエンドアセットをウィンドウ上に表示します。 フロントエンドからも、Javascriptでランタイムライブラリを呼び出すことができます。 そして最終的に、Goのメソッドはフロントエンドにバインドされ、ローカルのJavascriptメソッドであるかのように、フロントエンドから呼び出すことができます。
```mdx-code-block
<div className="text--center">
@ -12,11 +12,11 @@ A Wails application is a standard Go application, with a webkit frontend. The Go
</div>
```
## The Main Application
## アプリのメインコード
### Overview
The main application consists of a single call to `wails.Run()`. It accepts the application configuration which describes the size of the application window, the window title, what assets to use, etc. A basic application might look like this:
アプリは、`wails.Run()`メソッドを1回呼び出すことで、構成することができます。 このメソッドで、アプリのウィンドウサイズやウィンドウタイトル、使用アセットなどを指定することができます。 基本的なアプリを作るコードは次のとおりです:
```go title="main.go"
package main
@ -68,45 +68,45 @@ func (b *App) Greet(name string) string {
}
```
### Options rundown
### オプション
This example has the following options set:
上記のコードでは、次のオプションが指定されています:
- `Title` - The text that should appear in the window's title bar
- `Width` & `Height` - The dimensions of the window
- `Assets` - The application's frontend assets
- `OnStartup` - A callback for when the window is created and is about to start loading the frontend assets
- `OnShutdown` - A callback for when the application is about to quit
- `Bind` - A slice of struct instances that we wish to expose to the frontend
- `Title` - ウィンドウのタイトルバーに表示されるテキスト
- `Width` & `Height` - ウィンドウの大きさ
- `Assets` - アプリのフロントエンドアセット
- `OnStartup` - ウィンドウが作成され、フロントエンドの読み込みを開始しようとする時のコールバック
- `OnShutdown` - アプリを終了しようとするときのコールバック
- `Bind` - フロントエンドにバインドさせたい構造体インスタンスのスライス
A full list of application options can be found in the [Options Reference](reference/options).
設定可能なすべてのオプションについては、[オプションのリファレンス](reference/options)をご覧ください。
#### Assets
The `Assets` option is mandatory as you can't have a Wails application without frontend assets. Those assets can be any files you would expect to find in a web application - html, js, css, svg, png, etc. **There is no requirement to generate asset bundles** - plain files will do. When the application starts, it will attempt to load `index.html` from your assets and the frontend will essentially work as a browser from that point on. It is worth noting that there is no requirement on where in the `embed.FS` the files live. It is likely that the embed path uses a nested directory relative to your main application code, such as `frontend/dist`:
Wailsでフロントエンドアセット無しのアプリを作成することはできないため、`Assets`オプションは必須オプションです。 アセットには、一般的なWebアプリケーションでよく見かけるような、html、js、css、svg、pngなどのファイルを含めることができます。**アセットバンドルを生成する必要は一切なく**、そのままのファイルを使用できます。 アプリが起動すると、アセット内の`index.html`が読み込まれます。この時点で、フロントエンドはブラウザとして動作するようになります。 `embed.FS`を使ってアセットファイルが格納されたディレクトリを指定しますが、ディレクトリの場所はどこでも構いません。 embedで指定するパスは、`frontend/dist`のように、アプリのメインコードから相対的に見たディレクトリパスになります:
```go title="main.go"
//go:embed all:frontend/dist
var assets embed.FS
```
At startup, Wails will iterate the embedded files looking for the directory containing `index.html`. All other assets will be loaded relative to this directory.
起動時に、Wailsは`index.html`が含まれるディレクトリを再帰的に探します。 他のすべてのアセットは、当該ディレクトリから相対的に読み込まれます。
As production binaries use the files contained in `embed.FS`, there are no external files required to be shipped with the application.
本番用のバイナリファイルには、`embed.FS`で指定されたアセットファイルが含まれるため、アプリ配布時に、バイナリファイルとは別にアセットファイルを付加させる必要はありません。
When running in development mode using the `wails dev` command, the assets are loaded off disk, and any changes result in a "live reload". The location of the assets will be inferred from the `embed.FS`.
`wails dev`コマンドを使って開発モードでアプリを起動した場合、アセットはディスクから読み込まれ、アセットファイルが更新されると、自動的にアプリがライブリロードされます。 アセットの場所は、`embed.FS`での指定値から推定されます。
More details can be found in the [Application Development Guide](guides/application-development.mdx).
詳細は、[アプリ開発ガイド](guides/application-development.mdx)をご覧ください。
#### Application Lifecycle Callbacks
#### アプリのライフサイクル
Just before the frontend is about to load `index.html`, a callback is made to the function provided in [OnStartup](reference/options.mdx#onstartup). A standard Go context is passed to this method. This context is required when calling the runtime so a standard pattern is to save a reference to in this method. Just before the application shuts down, the [OnShutdown](reference/options.mdx#onshutdown) callback is called in the same way, again with the context. There is also an [OnDomReady](reference/options.mdx#ondomready) callback for when the frontend has completed loading all assets in `index.html` and is equivalent of the [`body onload`](https://www.w3schools.com/jsref/event_onload.asp) event in Javascript. It is also possible to hook into the window close (or application quit) event by setting the option [OnBeforeClose](reference/options.mdx#onbeforeclose).
フロントエンドが`index.html`を読み込もうとする直前に、[OnStartup](reference/options.mdx#onstartup)で指定されたメソッドがコールバックされます。 A standard Go context is passed to this method. このメソッドに引数で渡されるContextは、今後、Wailsのラインタイムを呼び出すときに必要になるため、通常は、このContextへの参照を保持しておいてください。 同様に、アプリがシャットダウンされる直前には、[OnShutdown](reference/options.mdx#onshutdown)で指定されたコールバックが呼び出され、Contextも渡されます。 `index.html`に含まれるすべてのアセットが読み込み終わったときに呼び出される[OnDomReady](reference/options.mdx#ondomready)コールバックもあります。これは、Javascriptの[`body onload`](https://www.w3schools.com/jsref/event_onload.asp)イベントと同等のものです。 また、[OnBeforeClose](reference/options.mdx#onbeforeclose)を指定すると、ウィンドウを閉じる(またはアプリを終了する)イベントにフックさせることもできます。
#### Method Binding
#### メソッドのバインド
The `Bind` option is one of the most important options in a Wails application. It specifies which struct methods to expose to the frontend. Think of structs like "controllers" in a traditional web application. When the application starts, it examines the struct instances listed in the `Bind` field in the options, determines which methods are public (starts with an uppercase letter) and will generate Javascript versions of those methods that can be called by the frontend code.
`Bind`オプションは、Wailsアプリで最も重要なオプションの1つです。 このオプションでは、フロントエンドに公開する、構造体のメソッドを指定することができます。 構造体は、従来のWebアプリにおける"コントローラ"の立ち位置であるとお考えください。 アプリが起動すると、`Bind`オプションで指定されている構造体を対象に、その中にあるパブリックメソッド(大文字で始まるメソッド名)を探します。そして、フロントエンドのコードからそれらのメソッドを呼び出せるJavascriptが生成されます。
:::info Note
:::info 備考
Wailsで構造体を正しくバインドするためには、構造体の*インスタンス*をオプションで指定してください。
@ -114,7 +114,7 @@ Wailsで構造体を正しくバインドするためには、構造体の*イ
:::
In this example, we create a new `App` instance and then add this instance to the `Bind` option in `wails.Run`:
下記のコードでは、新しく`App`インスタンスを作成し、`wails.Run`関数の`Bind`オプションの中で、そのインスタンスを追加しています:
```go {16,24} title="main.go"
package main
@ -158,7 +158,7 @@ func (a *App) Greet(name string) string {
}
```
You may bind as many structs as you like. Just make sure you create an instance of it and pass it in `Bind`:
構造体は、好きな数だけバインドできます。 `Bind`には、構造体のインスタンスを渡すようにしてください:
```go {8-10}
//...
@ -176,26 +176,26 @@ You may bind as many structs as you like. Just make sure you create an instance
```
When you run `wails dev` (or `wails generate module`), a frontend module will be generated containing the following:
`wails dev`コマンド(または、`wails generate module`コマンド)を実行すると、以下のものを含むフロントエンドモジュールが生成されます:
- Javascript bindings for all bound methods
- Typescript declarations for all bound methods
- Typescript definitions for all Go structs used as inputs or outputs by the bound methods
- バインドされたすべてのメソッドのJavascript
- バインドされたすべてのメソッドのTypescript宣言
- バインドされたメソッドの引数または返り値で使用されているGoの構造体のTypescript宣言
This makes it incredibly simple to call Go code from the frontend, using the same strongly typed datastructures.
これにより、強力な型付けがなされたデータ構造を使用して、フロントエンドから簡単にGoのコードを呼び出すことができます。
## The Frontend
## フロントエンド
### Overview
The frontend is a collection of files rendered by webkit. It's like a browser and webserver in one. There is virtually[^1] no limit to which frameworks or libraries you can use. The main points of interaction between the frontend and your Go code are:
フロントエンドは、webkitによってレンダリングされるファイル群です。 ブラウザとWebサーバが一体となったような動きをします。 使用できるフレームワークやライブラリの制限はほぼありません[^1]。 フロントエンドとGoコードとの相互のやり取りについて、主なポイントは次のとおりです:
- Calling bound Go methods
- Calling runtime methods
- バインドされたGoメソッドの呼び出し
- ランタイムメソッドの呼び出し
### Calling bound Go methods
### バインドされたGoメソッドの呼び出し
When you run your application with `wails dev`, it will automatically generate Javascript bindings for your structs in a directory called `wailsjs/go` (You can also do this by running `wails generate module`). The generated files mirror the package names in your application. In the example above, we bind `app`, which has one public method `Greet`. This will lead to the generation of the following files:
`wails dev`コマンドでアプリを起動すると、Go構造体のJavascriptバインディングが`wailsjs/go`ディレクトリに自動的に生成されます(`wails generate module`コマンドでも生成可能)。 生成されたファイルには、アプリ内のGoパッケージ名が反映されています。 先の例では、`Greet`というパブリックメソッドを持つ`app`をバインドしていました。 この場合、次のようなファイルが生成されることになります:
```bash
wailsjs
@ -205,7 +205,7 @@ wailsjs
└─App.js
```
Here we can see that there is a `main` package that contains the Javascript bindings for the bound `App` struct, as well as the Typescript declaration file for those methods. To call `Greet` from our frontend, we simply import the method and call it like a regular Javascript function:
ご覧のとおり、`main`パッケージ内の`App`構造体Javascriptバインディングが、それらのメソッドのTypescript型定義と並んで生成されていることが分かります。 フロントエンドから`Greet`メソッドを呼び出すには、単純にメソッドをインポートし、通常のJavascript関数と同じように呼び出してください:
```javascript
// ...
@ -218,29 +218,31 @@ import {Greet} from '../wailsjs/go/main/App'
}
```
The Typescript declaration file gives you the correct types for the bound methods:
Typescript型定義ファイルは、バインドされたメソッドの正しい型を提供します:
```ts
export function Greet(arg1:string):Promise<string>;
```
The generated methods return a Promise. A successful call will result in the first return value from the Go call to be passed to the `resolve` handler. An unsuccessful call is when a Go method that has an error type as it's second return value, passes an error instance back to the caller. This is passed back via the `reject` handler. In the example above, `Greet` only returns a `string` so the Javascript call will never reject - unless invalid data is passed to it.
生成されたメソッドはPromiseを返すようになっています。 呼び出しが成功すると、Goからの1番目の返り値が`resolve`ハンドラに渡されます。 呼び出しに失敗したとみなされるのは、Goメソッドの2番目の返り値がerror型で、それがerrorインスタンスを返したときです。 これは、`reject`ハンドラを介して返されます。 先の例では、`Greet`メソッドは`string`型の返り値のみであるため、無効なデータが渡されない限り、Javascript側でrejectハンドラが呼ばれることはありません。
All data types are correctly translated between Go and Javascript. Even structs. If you return a struct from a Go call, it will be returned to your frontend as a Javascript class. Note: If you wish to use structs, you **must** define `json` struct tags for your fields!
すべてのデータ型は、GoとJavascriptの間で正しく解釈されます。 もちろん構造体も正しく解釈されます。 Goから構造体が返された場合、フロントエンドにはJavascriptのクラスとして返されます。
:::info Note
:::info 備考
Struct fields *must* have a valid `json` tag to be included in the generated Typescript.
Anonymous nested structs are not supported at this time.
:::
It is possible to send structs back to Go. Any Javascript map/class passed as an argument that is expecting a struct, will be converted to that struct type. To make this process a lot easier, in `dev` mode, a TypeScript module is generated, defining all the struct types used in bound methods. Using this module, it's possible to construct and send native Javascript objects to the Go code.
Goに対して引数として構造体を渡すこともできます。 構造体として取り扱ってほしいJavascriptのマップやクラスを渡すと、構造体に変換されます。 あなたが簡単にこれらのことを把握できるように、`dev`モードでは、バウンドされたGoメソッドで使用されている全構造体の型が定義された、Typescriptモジュールが生成されます。 このモジュールを使用すると、Javascriptネイティブなオブジェクトを構築し、Goコードへ送信することができます。
There is also support for Go methods that use structs in their signature. All Go structs specified by a bound method (either as parameters or return types) will have Typescript versions auto generated as part of the Go code wrapper module. Using these, it's possible to share the same data model between Go and Javascript.
There is also support for Go methods that use structs in their signature. バインドされたメソッドで、引数または返り値として指定されているすべてのGo構造体は、Goのコードラッパーモジュールの一部として生成されたTypescript定義を持っています。 これらを使用することで、GoとJavascriptの間で、同じデータモデルを共有できます。
Example: We update our `Greet` method to accept a `Person` instead of a string:
例: `Greet`メソッドを更新して、文字列型の代わりに`Person`型を引数で受け付けてみる:
```go title="main.go"
type Person struct {
@ -259,7 +261,7 @@ func (a *App) Greet(p Person) string {
}
```
The `wailsjs/go/main/App.js` file will still have the following code:
`wailsjs/go/main/App.js`ファイルには、次のコードが出力されます:
```js title="App.js"
export function Greet(arg1) {
@ -267,98 +269,97 @@ export function Greet(arg1) {
}
```
But the `wailsjs/go/main/App.d.ts` file will be updated with the following code:
しかし、`wailsjs/go/main/App.d.ts`ファイルは次のコードが出力されます:
```ts title="App.d.ts"
import {main} from '../models';
import { main } from "../models";
export function Greet(arg1:main.Person):Promise<string>;
export function Greet(arg1: main.Person): Promise<string>;
```
As we can see, the "main" namespace is imported from a new "models.ts" file. This file contains all the struct definitions used by our bound methods. In this example, this is a `Person` struct. If we look at `models.ts`, we can see how the models are defined:
見ると分かるように、"main"名前空間は、新しく生成された"models.ts"ファイルからインポートされています。 このファイルには、バインドされたメソッドで使用されるすべての構造体の型定義が含まれています。 この例では、`Person`構造体の型定義が含まれています。 `models.ts`を確認すれば、モデルがどのように定義されているかが分かります。
```ts title="models.ts"
export namespace main {
export class Address {
street: string;
postcode: string;
export class Address {
street: string;
postcode: string;
static createFrom(source: any = {}) {
return new Address(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.street = source["street"];
this.postcode = source["postcode"];
}
static createFrom(source: any = {}) {
return new Address(source);
}
export class Person {
name: string;
age: number;
address?: Address;
static createFrom(source: any = {}) {
return new Person(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.name = source["name"];
this.age = source["age"];
this.address = this.convertValues(source["address"], Address);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
constructor(source: any = {}) {
if ("string" === typeof source) source = JSON.parse(source);
this.street = source["street"];
this.postcode = source["postcode"];
}
}
export class Person {
name: string;
age: number;
address?: Address;
static createFrom(source: any = {}) {
return new Person(source);
}
constructor(source: any = {}) {
if ("string" === typeof source) source = JSON.parse(source);
this.name = source["name"];
this.age = source["age"];
this.address = this.convertValues(source["address"], Address);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice) {
return (a as any[]).map((elem) => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
}
```
So long as you have TypeScript as part of your frontend build configuration, you can use these models in the following way:
フロントエンドのビルド構成にTypescriptを使用している限り、これらのモデルを次のように使用できます:
```js title="mycode.js"
import {Greet} from '../wailsjs/go/main/App'
import {main} from '../wailsjs/go/models'
import { Greet } from "../wailsjs/go/main/App";
import { main } from "../wailsjs/go/models";
function generate() {
let person = new main.Person()
person.name = "Peter"
person.age = 27
Greet(person).then((result) => {
console.log(result)
})
}
function generate() {
let person = new main.Person();
person.name = "Peter";
person.age = 27;
Greet(person).then((result) => {
console.log(result);
});
}
```
The combination of generated bindings and TypeScript models makes for a powerful development environment.
生成されたバインディングとTypescriptモデルの組み合わせによって、強力な開発環境を実現させています。
More information on Binding can be found in the [Binding Methods](guides/application-development.mdx#binding-methods) section of the [Application Development Guide](guides/application-development.mdx).
バインディングの詳細については、[アプリ開発ガイド](guides/application-development.mdx)の[バインディングメソッド](guides/application-development.mdx#binding-methods)をご覧ください。
### Calling runtime methods
### ランタイムメソッドの呼び出し
The Javascript runtime is located at `window.runtime` and contains many methods to do various tasks such as emit an event or perform logging operations:
Javascriptランタイムは`window.runtime`に存在し、イベント発行やロギングなど、さまざまなタスクを実行するためのメソッドが含まれています:
```js title="mycode.js"
window.runtime.EventsEmit("my-event", 1);
```
More details about the JS runtime can be found in the [Runtime Reference](reference/runtime/intro).
Javascriptランタイムの詳細については、[ランタイムリファレンス](reference/runtime/intro)をご覧ください。
[^1]: There is a very small subset of libraries that use features unsupported in WebViews. There are often alternatives and workarounds for such cases.
[^1]: まれに、WebViewでサポートされていない機能を使用するライブラリがあります。 ほとんどの場合、それらは代替手段や回避方法がありますので、それらを検討してください。

View file

@ -2,26 +2,26 @@
sidebar_position: 1
---
# Introduction
# イントロダクション
Wails is a project that enables you to write desktop apps using Go and web technologies.
Wailsは、Go言語とWeb技術を使用して、デスクトップアプリの構築を可能にするプロジェクトです。
Consider it a lightweight and fast Electron alternative for Go. You can easily build applications with the flexibility and power of Go, combined with a rich, modern frontend.
"Goの力によって、Electronが軽量かつ高速になったようなもの"、と考えるとよいでしょう。 Goの柔軟性とパワーに、リッチでモダンなフロントエンドを組み合わせたアプリを、簡単に構築することができます。
### Features
### 機能
- Native Menus, Dialogs, Theming and Translucency
- Windows, macOS and linux support
- Built in templates for Svelte, React, Preact, Vue, Lit and Vanilla JS
- Easily call Go methods from Javascript
- Automatic Go struct to Typescript model generation
- No CGO or external DLLs required on Windows
- Live development mode using the power of [Vite](https://vitejs.dev/)
- Powerful CLI to easily Create, Build and Package applications
- A rich [runtime library](/docs/reference/runtime/intro)
- Applications built with Wails are Apple & Microsoft Store compliant
- ネイティブなメニュー、ダイアログ、テーマ、透過を使用できます
- Windows、macOS、Linuxをサポートしています
- Svelte、React、Preact、Vue、Lit、Vanilla JS向けのテンプレートを用意しています
- JavascriptからGoのメソッドを簡単に呼び出せます
- Go構造体からTypescriptの型を自動的に生成します
- Windowsでは、CGOや外部DLLを用意する必要はありません
- [Vite](https://vitejs.dev/)の力を利用したライブ開発が可能です
- 簡単にアプリを生成、ビルド、パッケージ化できる強力なCLIを用意しています
- 豊富な[ランタイムライブラリ](/docs/reference/runtime/intro)を用意しています
- Wailsで構築されたアプリケーションは、Apple StoreおよびMicrosoft Storeに準拠しています
This is [varly](https://varly.app) - a desktop application for MacOS & Windows written using Wails. Not only does it look great, it uses native menus and translucency - everything you'd expect from a modern native app.
例えば [varly](https://varly.app) は、Wailsで構築されたMacOS・Windows向けのデスクトップアプリです。 見栄えが良いだけではなく、ネイティブメニューや半透明効果を使用しています。これらは、モダンなネイティブアプリに期待されるものです。
```mdx-code-block
<p class="text--center">
@ -34,42 +34,42 @@ This is [varly](https://varly.app) - a desktop application for MacOS & Windows w
</p>
```
### Quick Start Templates
### クイックスタートテンプレート
Wails comes with a number of pre-configured templates that allow you to get your application up and running quickly. There are templates for the following frameworks: Svelte, React, Vue, Preact, Lit and Vanilla. There are both Javascript and Typescript versions for each template.
Wailsには、アプリの開発をすばやく始められるように、多数のテンプレートが用意されています。 Svelte、React、Vue、Preact、LitおよびVanilla用で、それぞれのテンプレートがあります。 各テンプレートには、Javascript版とTypescript版が用意されています。
### Native Elements
### ネイティブ要素
Wails uses a purpose built library for handling native elements such as Window, Menus, Dialogs, etc, so you can build good-looking, feature rich desktop applications.
Wailsは、ウィンドウ、メニュー、ダイアログなどのネイティブ要素を処理する専用ライブラリを使用するため、見栄えが良く、リッチな機能を備えたデスクトップアプリを構築できます。
**It does not embed a browser**, so it is resource efficient. Instead, it uses the native rendering engine for the platform. On Windows, this is the new Microsoft Webview2 library, built on Chromium.
**ブラウザを埋め込まないため**、無駄なリソースを割きません。 ブラウザを埋め込まない代わりに、OSプラットフォームのネイティブなレンダリングエンジンを使用します。 例えばWindowsの場合、Chromium上でビルトされているMicrosoft Webview2ライブラリを使用します。
### Go & Javascript Interoperability
### GoとJavascriptのやり取り
Wails automatically makes your Go methods available to Javascript, so you can call them by name from your frontend! It even generates Typescript models for the structs used by your Go methods, so you can pass the same data structures between Go and Javascript.
Wailsは自動的に、GoのメソッドをJavascriptから利用できるようにするので、フロントエンドからGoのメソッド名を呼び出すことができます。 It even generates Typescript models for the structs used by your Go methods, so you can pass the same data structures between Go and Javascript.
### Runtime Library
### ランタイムライブラリ
Wails provides a runtime library, for both Go and Javascript, that handles a lot of the things modern applications need, like Eventing, Logging, Dialogs, etc.
WailsはGoとJavascriptの両方にランタイムライブラリを提供し、イベント、ロギング、ダイアログなど、モダンなアプリに必要な多くの機能を使うことができます。
### Live Development Experience
### ライブ開発
#### Automatic Rebuilds
#### 自動リビルド
When you run your application in "dev" mode, Wails will build your application as a native desktop application, but will read your assets from disk. It will detect any changes to your Go code and automatically rebuild and relaunch your application.
アプリを"dev"モードで起動すると、Wailsはあなたが書いたコードをネイティブデスクトップアプリとしてビルドしますが、プログラムアセットは常にディスクから読み込む状態になります。 その仕組みにより、アプリ起動中にGoコードが書き換えられると、変更を検出して自動的にアプリがリビルドされ、再起動します。
#### Automatic Reloads
#### 自動リロード
When changes to your application assets are detected, your running application will "reload", reflecting your changes almost immediately.
フロントエンドアセットの変更が検出された場合、起動中のアプリは自動的にリロードされ、変更がすぐに反映されます。
#### Develop your application in a Browser
#### ブラウザを使った開発
If you prefer to debug and develop in a browser then Wails has you covered. The running application also has a webserver that will run your application in any browser that connects to it. It will even refresh when your assets change on disk.
If you prefer to debug and develop in a browser then Wails has you covered. ブラウザでのデバッグや開発も、Wailsにお任せください。 起動中のアプリはWebサーバを兼ねており、お好きなブラウザから接続してアプリを操作することができます。 プログラムアセットが書き換わった時はすぐに更新されます。
### Production-ready Native Binaries
### 本番用のネイティブバイナリ
When you're ready to do the final build of your application, the CLI will compile it down to a single executable, with all the assets bundled into it. On Windows and MacOS, it is possible to create a native package for distribution. The assets used in packaging (icon, info.plist, manifest file, etc) are part of your project and may be customised, giving you total control over how your applications are built.
アプリを本番用にビルドする準備ができたら、CLIが、アプリを単一の実行可能ファイルへコンパイルし、すべてのアセットをバンドルしてくれます。 WindowsおよびMacOSでは、配布用のネイティブパッケージを作成できます。 パッケージ化に必要なアイコン、info.plist、マニフェストファイルなどは、プロジェクトの一部としてカスタマイズできるため、アプリのビルド方法をフルコントロールできます。
### Tooling
### ツール
The Wails CLI provides a hassle-free way to generate, build and bundle your applications. It will do the heavy lifting of creating icons, compiling your application with optimal settings and delivering a distributable, production ready binary. Choose from a number of starter templates to get up and running quickly!
Wails CLIを使うことで、簡単にアプリを生成、ビルド、バンドルすることができます。 アイコンの作成、最適なコンパイル構成の設定、本番向けのバイナリ配布など、面倒なことをあなたの代わりに引き受けてくれます。 多数のテンプレートの中から、あなたに合ったものを選んで、すぐに開発を始めましょう!

View file

@ -23,7 +23,7 @@ The Wails CLI has a number of commands that are used for managing your projects.
| -ide | Generate IDE project files | |
| -f | Force build application | false |
Example: `wails init -n test -d mytestproject -g -ide vscode -q`
: `wails init -n test -d mytestproject -g -ide vscode -q`
This will generate a a project called "test" in the "mytestproject" directory, initialise git, generate vscode project files and do so silently.
@ -33,7 +33,7 @@ More information on using IDEs with Wails can be found [here](../guides/ides.mdx
Remote templates (hosted on GitHub) are supported and can be installed by using the template's project URL.
Example: `wails init -n test -t https://github.com/leaanthony/testtemplate[@v1.0.0]`
: `wails init -n test -t https://github.com/leaanthony/testtemplate[@v1.0.0]`
A list of community maintained templates can be found [here](../community/templates.mdx)
@ -61,7 +61,7 @@ If you are unsure about a template, inspect `package.json` and `wails.json` for
| -o filename | Output filename | |
| -s | Skip building the frontend | false |
| -f | Force build application | false |
| -tags "extra tags" | Build tags to pass to Go compiler. Must be quoted. Space or comma (but not both) separated | |
| -tags "extra tags" | Goコンパイラに渡すビルドタグ。 値は引用符で囲んでください。 また、スペースまたはカンマで区切ってください(両方は使用しないでください)。 | |
| -upx | Compress final binary using "upx" | |
| -upxflags | Flags to pass to upx | |
| -v int | Verbosity level (0 - silent, 1 - default, 2 - verbose) | 1 |
@ -71,8 +71,8 @@ If you are unsure about a template, inspect `package.json` and `wails.json` for
| -trimpath | Remove all file system paths from the resulting executable. | false |
| -race | Build with Go's race detector | false |
| -windowsconsole | Keep the console window for Windows builds | |
| -obfuscate | Obfuscate the application using [garble](https://github.com/burrowers/garble) | false |
| -garbleargs | Arguments to pass to garble | `-literals -tiny -seed=random` |
| -obfuscate | [garble](https://github.com/burrowers/garble)を使用してアプリケーションを難読化する | false |
| -garbleargs | garbleへ渡す引数 | `-literals -tiny -seed=random` |
For a detailed description of the `webview2` flag, please refer to the [Windows](../guides/windows.mdx) Guide.
@ -172,7 +172,7 @@ Your system is ready for Wails development!
| -reloaddirs | Additional directories to trigger reloads (comma separated) | Value in `wails.json` |
| -ldflags "flags" | Additional ldflags to pass to the compiler | |
| -tags "extra tags" | Build tags to pass to compiler (quoted and space separated) | |
| -loglevel "loglevel" | Loglevel to use - Trace, Debug, Info, Warning, Error | Debug |
| -loglevel "loglevel" | Loglevel to use - Trace, Debug, Info, Warning, Error | デバッグ |
| -noreload | Disable automatic reload when assets change | |
| -nogen | Disable generate module | |
| -v | Verbosity level (0 - silent, 1 - standard, 2 - verbose) | 1 |

View file

@ -33,18 +33,13 @@ An example of how to create a menu:
// ...
```
```` It is also possible to dynamically update the menu, by updating the menu struct and calling \[MenuUpdateApplicationMenu\](../reference/runtime/menu.mdx#menuupdateapplicationmenu).
Menu構造体を更新し、[MenuUpdateApplicationMenu](../reference/runtime/menu.mdx#menuupdateapplicationmenu)メソッドを呼び出すことで、メニューを動的に更新することも可能です。
The example above uses helper methods, however it's possible to build the menu structs manually.
## Menu
A Menu is a collection of MenuItems:
```go title="Package: github.com/wailsapp/wails/v2/pkg/menu"
## Menu
A Menu is a collection of MenuItems:
Menuは、MenuItemのコレクションです。
```go title="Package: github.com/wailsapp/wails/v2/pkg/menu"
type Menu struct {
@ -126,7 +121,7 @@ Keys are any single character on a keyboard with the exception of `+`, which is
Wails also supports parsing accelerators using the same syntax as Electron. This is useful for storing accelerators in config files.
Example:
:
```go title="Package: github.com/wailsapp/wails/v2/pkg/menu/keys"
// Defines cmd+o on Mac and ctrl-o on Window/Linux
@ -228,7 +223,7 @@ Roles are currently supported on Mac only.
A menu item may have a role, which is essentially a pre-defined menu item. We currently support the following roles:
| Role | Description |
| ロール | Description |
| ------------ | ------------------------------------------------------------------------ |
| AppMenuRole | The standard Mac application menu. Can be created using `menu.AppMenu()` |
| EditMenuRole | The standard Mac edit menu. Can be created using `menu.EditMenu()` |

View file

@ -2,7 +2,7 @@
sidebar_position: 3
---
# Options
# オプション
## Application Options
@ -88,6 +88,7 @@ func main() {
},
Linux: &linux.Options{
Icon: icon,
WindowIsTranslucent: false,
},
})
if err != nil {
@ -101,93 +102,93 @@ func main() {
The text shown in the window's title bar.
Name: Title<br/> Type: `string`
名前: Title<br/> データ型: `string`
### Width
The initial width of the window.
Name: Width<br/> Type: `int`<br/> Default: 1024.
名前: Width<br/> データ型: `int`<br/> デフォルト値: 1024
### Height
The initial height of the window.
Name: Height<br/> Type: `int`<br/> Default: 768
名前: Height<br/> データ型: `int`<br/> デフォルト値: 768
### DisableResize
By default, the main window is resizable. Setting this to `true` will keep it a fixed size.
Name: DisableResize<br/> Type: `bool`
名前: DisableResize<br/> データ型: `bool`
### Fullscreen
Setting this to `true` will make the window fullscreen at startup.
Name: Fullscreen<br/> Type: `bool`
名前: Fullscreen<br/> データ型: `bool`
### Frameless
When set to `true`, the window will have no borders or title bar. Also see [Frameless Windows](../guides/frameless.mdx).
Name: Frameless<br/> Type: `bool`
名前: Frameless<br/> データ型: `bool`
### MinWidth
This sets the minimum width for the window. If the value given in `Width` is less than this value, the window will be set to `MinWidth` by default.
Name: MinWidth<br/> Type: `int`
名前: MinWidth<br/> データ型: `int`
### MinHeight
This sets the minimum height for the window. If the value given in `Height` is less than this value, the window will be set to `MinHeight` by default.
Name: MinHeight<br/> Type: `int`
名前: MinHeight<br/> データ型: `int`
### MaxWidth
This sets the maximum width for the window. If the value given in `Width` is more than this value, the window will be set to `MaxWidth` by default.
Name: MaxWidth<br/> Type: `int`
名前: MaxWidth<br/> データ型: `int`
### MaxHeight
This sets the maximum height for the window. If the value given in `Height` is more than this value, the window will be set to `MaxHeight` by default.
Name: MaxHeight<br/> Type: `int`
名前: MaxHeight<br/> データ型: `int`
### StartHidden
When set to `true`, the application will be hidden until [WindowShow](../reference/runtime/window.mdx#windowshow) is called.
Name: StartHidden<br/> Type: `bool`
名前: StartHidden<br/> データ型: `bool`
### HideWindowOnClose
By default, closing the window will close the application. Setting this to `true` means closing the window will hide the window instead.
By default, closing the window will close the application. この設定を`true`にすると、ウィンドウを閉じる操作をした際に、
hide the window instead.
ウィンドウが非表示の状態になります。
Name: HideWindowOnClose<br/> Type: `bool`
名前: HideWindowOnClose<br/> データ型: `bool`
### BackgroundColour
This value is the default background colour of the window. Default: white
This value is the default background colour of the window. 例: options.NewRGBA(255,0,0,128) - 50%透過された赤色
Name: BackgroundColour<br/> Type: `*options.RGBA`<br/> Default: white
名前: BackgroundColour<br/> データ型: `*options.RGBA`<br/> デフォルト値: white
### AlwaysOnTop
Indicates that the window should stay above other windows when losing focus.
Name: AlwaysOnTop<br/> Type: `bool`
名前: AlwaysOnTop<br/> データ型: `bool`
### Assets
The frontend assets to be used by the application. Requires an `index.html` file.
Name: Assets<br/> Type: `embed.FS`
名前: Assets<br/> データ型: `embed.FS`
### AssetsHandler
@ -195,7 +196,7 @@ Name: Assets<br/> Type: `embed.FS`
The assets handler is a generic `http.Handler` which will be called for any non GET request on the assets server and for GET requests which can not be served from the `assets` because the file is not found.
| Value | Win | Mac | Lin |
| | Win | Mac | Lin |
| ----------------------- | --- | --- | --- |
| GET | ✅ | ✅ | ✅ |
| POST | ✅ | ✅ | ❌ |
@ -214,7 +215,7 @@ NOTE: Linux is currently very limited due to targeting a WebKit2GTK Version < 2.
NOTE: When used in combination with a Frontend DevServer there might be limitations, eg. Vite serves the index.html on every path, that does not contain a file extension.
Name: AssetsHandler<br/> Type: `http.Handler`
名前: AssetsHandler<br/> データ型: `http.Handler`
### Menu
@ -223,48 +224,48 @@ The menu to be used by the application. More details about Menus in the [Menu Re
:::note
On Mac, if no menu is specified, a default menu will be created.
Macでは、メニューが指定されていない場合、デフォルトメニューが作成されます。
:::
Name: Menu<br/> Type: `*menu.Menu`
名前: Menu<br/> データ型: `*menu.Menu`
### Logger
The logger to be used by the application. More details about logging in the [Log Reference](../reference/runtime/log.mdx).
Name: Logger<br/> Type: `logger.Logger`<br/> Default: Logs to Stdout
名前: Logger<br/> データ型: `logger.Logger`<br/> デフォルト値: 標準出力へのロガー
### LogLevel
The default log level. More details about logging in the [Log Reference](../reference/runtime/log.mdx).
Name: LogLevel<br/> Type: `logger.LogLevel`<br/> Default: `Info` in dev mode, `Error` in production mode
名前: LogLevel<br/> データ型: `logger.LogLevel`<br/> デフォルト値: 開発モードの場合は`Info`、本番モードの場合は`Error`
### LogLevelProduction
The default log level for production builds. More details about logging in the [Log Reference](../reference/runtime/log.mdx).
Name: LogLevelProduction<br/> Type: `logger.LogLevel`<br/> Default: `Error`
名前: LogLevelProduction<br/> データ型: `logger.LogLevel`<br/> デフォルト値: `Error`
### OnStartup
This callback is called after the frontend has been created, but before `index.html` has been loaded. It is given the application context.
Name: OnStartup<br/> Type: `func(ctx context.Context)`
名前: OnStartup<br/> データ型: `func(ctx context.Context)`
### OnDomReady
This callback is called after the frontend has loaded `index.html` and its resources. It is given the application context.
Name: OnDomReady<br/> Type: `func(ctx context.Context)`
名前: OnDomReady<br/> データ型: `func(ctx context.Context)`
### OnShutdown
This callback is called after the frontend has been destroyed, just before the application terminates. It is given the application context.
Name: OnShutdown<br/> Type: `func(ctx context.Context)`
名前: OnShutdown<br/> データ型: `func(ctx context.Context)`
### OnBeforeClose
@ -287,99 +288,99 @@ func (b *App) beforeClose(ctx context.Context) (prevent bool) {
}
```
Name: OnBeforeClose<br/> Type: `func(ctx context.Context) bool`
名前: OnBeforeClose<br/> データ型: `func(ctx context.Context) bool`
### WindowStartState
Defines how the window should present itself at startup.
| Value | Win | Mac | Lin |
| | Win | Mac | Lin |
| ---------- | --- | --- | --- |
| Fullscreen | ✅ | ✅ | ✅ |
| Maximised | ✅ | ✅ | ✅ |
| Minimised | ✅ | ❌ | ✅ |
Name: WindowStartState<br/> Type: `options.WindowStartState`
名前: WindowStartState<br/> データ型: `options.WindowStartState`
### CSSDragProperty
Indicates the CSS property to use to identify which elements can be used to drag the window. Default: `--wails-draggable`.
ウィンドウをドラッグできる要素を特定するためのCSSプロパティ名を設定します。 デフォルト値: `--wails-draggable`
Name: CSSDragProperty<br/> Type: `string`
名前: CSSDragProperty<br/> データ型: `string`
### CSSDragValue
Indicates what value the `CSSDragProperty` style should have to drag the window. Default: `drag`.
Indicates what value the `CSSDragProperty` style should have to drag the window. デフォルト値: `drag`
Name: CSSDragValue<br/> Type: `string`
名前: CSSDragValue<br/> データ型: `string`
### Bind
A slice of struct instances defining methods that need to be bound to the frontend.
Name: Bind<br/> Type: `[]interface{}`
名前: Bind<br/> データ型: `[]interface{}`
### Windows
This defines [Windows specific options](#windows).
[Windows固有のオプション](#windows)を定義します。
Name: Windows<br/> Type: `*windows.Options`
名前: Windows<br/> データ型: `*windows.Options`
#### WebviewIsTransparent
Setting this to `true` will make the webview background transparent when an alpha value of `0` is used. This means that if you use `rgba(0,0,0,0)` for `background-color` in your CSS, the host window will show through. Often combined with [WindowIsTranslucent](#WindowIsTranslucent) to make frosty-looking applications.
Name: WebviewIsTransparent<br/> Type: `bool`
名前: WebviewIsTransparent<br/> データ型: `bool`
#### WindowIsTranslucent
Setting this to `true` will make the window background translucent. Often combined with [WebviewIsTransparent](#WebviewIsTransparent).
Setting this to `true` will make the window background translucent. 多くの場合、[WebviewIsTransparent](#WebviewIsTransparent)と組み合わせて使用されます。
For Windows 11 versions before build 22621, this will use the [BlurBehind](https://learn.microsoft.com/en-us/windows/win32/dwm/blur-ovw) method for translucency, which can be slow. For Windows 11 versions after build 22621, this will enable the newer translucency types that are much faster. By default, the type of translucency used will be determined by Windows. To configure this, use the [BackdropType](#BackdropType) option.
ビルド22621より前のWindows 11の場合、半透明を実現させるために[BlurBehind](https://learn.microsoft.com/ja-jp/windows/win32/dwm/blur-ovw)メソッドを使用するため、処理が遅くなる可能性があります。 ビルド22621以降のWindows 11では、より高速な、新しい半透明タイプが有効になります。 デフォルトで使用される半透明タイプは、Windowsにより決定されます。 このタイプを設定するには、[BackdropType](#BackdropType)オプションを使用してください。
Name: WindowIsTranslucent<br/> Type: `bool`
名前: WindowIsTranslucent<br/> データ型: `bool`
#### BackdropType
:::note
Requires Windows 11 build 22621 or later.
この設定を適用するには、Windows 11 ビルド22621以降が必要です。
:::
Sets the translucency type of the window. This is only applicable if [WindowIsTranslucent](#WindowIsTranslucent) is set to `true`.
ウィンドウの半透明タイプを設定します。 この設定は、[WindowIsTranslucent](#WindowIsTranslucent)が`true`に設定されている場合にのみ適用されます。
Name: BackdropType<br/> Type `windows.BackdropType`
名前: BackdropType<br/> データ型: `windows.BackdropType`
The value can be one of the following:
値は次のいずれかを指定してください:
| Value | Description |
| ------- | ----------------------------------------------------------------------------------------- |
| Auto | Let Windows decide which backdrop to use |
| None | Do not use translucency |
| Acrylic | Use [Acrylic](https://learn.microsoft.com/en-us/windows/apps/design/style/acrylic) effect |
| Mica | Use [Mica](https://learn.microsoft.com/en-us/windows/apps/design/style/mica) effect |
| Tabbed | Use Tabbed. This is a backdrop that is similar to Mica. |
| | Description |
| ------- | ----------------------------------------------------------------------------------- |
| Auto | Windowsに背景を決定させる |
| None | 半透明にしない |
| Acrylic | [アクリル](https://learn.microsoft.com/ja-jp/windows/apps/design/style/acrylic)の効果を使用する |
| Mica | [マイカ](https://learn.microsoft.com/ja-jp/windows/apps/design/style/mica)の効果を使用する |
| Tabbed | タブを使用する。 これはマイカに似ている背景です。 |
#### DisableWindowIcon
Setting this to `true` will remove the icon in the top left corner of the title bar.
Name: DisableWindowIcon<br/> Type: `bool`
名前: DisableWindowIcon<br/> データ型: `bool`
#### DisableFramelessWindowDecorations
Setting this to `true` will remove the window decorations in [Frameless](#Frameless) mode. This means there will be no 'Aero Shadow' and no 'Rounded Corners' shown for the window. Please note that 'Rounded Corners' are only supported on Windows 11.
Name: DisableFramelessWindowDecorations<br/> Type: `bool`
名前: DisableFramelessWindowDecorations<br/> データ型: `bool`
#### WebviewUserDataPath
This defines the path where the WebView2 stores the user data. If empty `%APPDATA%\[BinaryName.exe]` will be used.
Name: WebviewUserDataPath<br/> Type: `string`
名前: WebviewUserDataPath<br/> データ型: `string`
#### WebviewBrowserPath
@ -391,7 +392,7 @@ Important information about distribution of fixed version runtime:
- [Known issues for fixed version](https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#known-issues-for-fixed-version)
- [The path of fixed version of the WebView2 Runtime should not contain \Edge\Application\.](https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.1245.22#createcorewebview2environmentwithoptions)
Name: WebviewBrowserPath<br/> Type: `string`
名前: WebviewBrowserPath<br/> データ型: `string`
#### Theme
@ -399,29 +400,29 @@ Minimum Windows Version: Windows 10 2004/20H1
This defines the theme that the application should use:
| Value | Description |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| SystemDefault | *Default*. The theme will be based on the system default. If the user changes their theme, the application will update to use the new setting |
| Dark | The application will use a dark theme exclusively |
| Light | The application will use a light theme exclusively |
| | Description |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| SystemDefault | _デフォルト値_です。 The theme will be based on the system default. If the user changes their theme, the application will update to use the new setting |
| Dark | The application will use a dark theme exclusively |
| Light | The application will use a light theme exclusively |
Name: Theme<br/> Type: `windows.Theme`
名前: Theme<br/> データ型: `windows.Theme`
#### CustomTheme
:::note
Minimum Windows Version: Windows 10/11 2009/21H2 Build 22000
サポートされるWindowsの最小バージョン: Windows 10/11 2009/21H2 ビルド22000
:::
Allows you to specify custom colours for TitleBar, TitleText and Border for both light and dark mode, as well as when the window is active or inactive.
Name: CustomTheme<br/> Type: `windows.CustomTheme`
名前: CustomTheme<br/> データ型: `windows.CustomTheme`
##### CustomTheme type
##### CustomTheme
The CustomTheme struct uses `int32` to specify the colour values. These are in the standard(!) Windows format of: `0x00BBGGAA`. A helper function is provided to do RGB conversions into this format: `windows.RGB(r,g,b uint8)`.
@ -469,7 +470,7 @@ Example:
A struct of strings used by the webview2 installer if a valid webview2 runtime is not found.
Name: Messages<br/> Type: `*windows.Messages`
名前: Messages<br/> データ型: `*windows.Messages`
Customise this for any language you choose to support.
@ -477,31 +478,31 @@ Customise this for any language you choose to support.
ResizeDebounceMS is the amount of time to debounce redraws of webview2 when resizing the window. The default value (0) will perform redraws as fast as it can.
Name: ResizeDebounceMS<br/> Type: `uint16`
名前: ResizeDebounceMS<br/> データ型: `uint16`
#### OnSuspend
If set, this function will be called when Windows initiates a switch to low power mode (suspend/hibernate)
Windowsがローパワーモード(サスペンド/休止状態) に切り替わると呼び出されるコールバックを設定します。
Name: OnSuspend<br/> Type: `func()`
名前: OnSuspend<br/> データ型: `func()`
#### OnResume
If set, this function will be called when Windows resumes from low power mode (suspend/hibernate)
Windowsがローパワーモード(サスペンド/休止状態) から復帰したときに呼び出されるコールバックを設定します。
Name: OnResume<br/> Type: `func()`
名前: OnResume<br/> データ型: `func()`
### Mac
This defines [Mac specific options](#mac).
[Mac固有のオプション](#mac)を定義します。
Name: Mac<br/> Type: `*mac.Options`
名前: Mac<br/> データ定義: `*mac.Options`
#### TitleBar
The TitleBar struct provides the ability to configure the look and feel of the title bar.
Name: TitleBar<br/> Type: [`*mac.TitleBar`](#titlebar-struct)
名前: TitleBar<br/> データ型: [`*mac.TitleBar`](#titlebar-struct)
##### Titlebar struct
@ -549,13 +550,13 @@ Click [here](https://github.com/lukakerr/NSWindowStyles) for some inspiration on
Appearance is used to set the style of your app in accordance with Apple's [NSAppearance](https://developer.apple.com/documentation/appkit/nsappearancename?language=objc) names.
Name: Appearance<br/> Type: [`mac.AppearanceType`](#appearance-type)
名前: Appearance<br/> データ型: [`mac.AppearanceType`](#appearance-type)
##### Appearance type
##### Appearance
You can specify the application's [appearance](https://developer.apple.com/documentation/appkit/nsappearance?language=objc).
| Value | Description |
| | Description |
| ----------------------------------------------------- | --------------------------------------------------------------- |
| DefaultAppearance | DefaultAppearance uses the default system value |
| NSAppearanceNameAqua | The standard light system appearance |
@ -578,19 +579,19 @@ Mac: &mac.Options{
Setting this to `true` will make the webview background transparent when an alpha value of `0` is used. This means that if you use `rgba(0,0,0,0)` for `background-color` in your CSS, the host window will show through. Often combined with [WindowIsTranslucent](#WindowIsTranslucent) to make frosty-looking applications.
Name: WebviewIsTransparent<br/> Type: `bool`
名前: WebviewIsTransparent<br/> データ型: `bool`
#### WindowIsTranslucent
Setting this to `true` will make the window background translucent. Often combined with [WebviewIsTransparent](#WebviewIsTransparent) to make frosty-looking applications.
Name: WindowIsTranslucent<br/> Type: `bool`
名前: WindowIsTranslucent<br/> データ型: `bool`
#### About
This configuration lets you set the title, message and icon for the "About" menu item in the app menu created by the "AppMenu" role.
Name: About<br/> Type: [`*mac.AboutInfo`](#about-struct)
名前: About<br/> データ型: [`*mac.AboutInfo`](#about-struct)
##### About struct
@ -649,18 +650,24 @@ When clicked, that will open an about message box:
### Linux
This defines [Linux specific options](#linux).
[Linux固有のオプション](#linux)を定義します。
Name: Linux<br/> Type: `*linux.Options`
名前: Linux<br/> データ型: `*linux.Options`
#### Icon
Sets up the icon representing the window. This icon is used when the window is minimized (also known as iconified).
Name: Icon<br/> Type: `[]byte`
名前: Icon<br/> データ型: `[]byte`
Some window managers or desktop environments may also place it in the window frame, or display it in other contexts. On others, the icon is not used at all, so your mileage may vary.
NOTE: Gnome on Wayland at least does not display this icon. To have a application icon there, a `.desktop` file has to be used. On KDE it should work.
The icon should be provided in whatever size it was naturally drawn; that is, dont scale the image before passing it. Scaling is postponed until the last minute, when the desired final size is known, to allow best quality.
#### WindowIsTranslucent
Setting this to `true` will make the window background translucent. Some window managers may ignore it, or result in a black window.
名前: WindowIsTranslucent<br/> データ型: `bool`

View file

@ -4,10 +4,10 @@ sidebar_position: 7
# Browser
These methods are related to the system browser.
これらは、システムブラウザに関連したメソッドです。
### BrowserOpenURL
Opens the given URL in the system browser.
指定されたURLをシステムブラウザで開きます。
Go: `BrowserOpenURL(ctx context.Context, url string)`<br/> JS: `BrowserOpenURL(url string)`

View file

@ -2,59 +2,59 @@
sidebar_position: 5
---
# Dialog
# ダイアログ
This part of the runtime provides access to native dialogs, such as File Selectors and Message boxes.
ランタイムでは、ファイルセレクターやメッセージボックスといったネイティブダイアログへのアクセスを提供しています。
:::info Javascript
Dialog is currently unsupported in the JS runtime.
現在、Javascriptランタイムではダイアログをサポートしていません。
:::
### OpenDirectoryDialog
Opens a dialog that prompts the user to select a directory. Can be customised using [OpenDialogOptions](#opendialogoptions).
ユーザにディレクトリの選択を求めるダイアログを開きます。 [OpenDialogOptions](#opendialogoptions)を使用してカスタマイズできます。
Go: `OpenDirectoryDialog(ctx context.Context, dialogOptions OpenDialogOptions) (string, error)`
Returns: Selected directory (blank if the user cancelled) or an error
返り値: 選択されたディレクトリ(キャンセルされた場合は空) またはエラー
### OpenFileDialog
Opens a dialog that prompts the user to select a file. Can be customised using [OpenDialogOptions](#opendialogoptions).
ユーザにファイルの選択を求めるダイアログを開きます。 [OpenDialogOptions](#opendialogoptions)を使用してカスタマイズできます。
Go: `OpenFileDialog(ctx context.Context, dialogOptions OpenDialogOptions) (string, error)`
Returns: Selected file (blank if the user cancelled) or an error
返り値: 選択されたファイル(キャンセルされた場合は空) またはエラー
### OpenMultipleFilesDialog
Opens a dialog that prompts the user to select multiple files. Can be customised using [OpenDialogOptions](#opendialogoptions).
ユーザに複数ファイルの選択を求めるダイアログを開きます。 [OpenDialogOptions](#opendialogoptions)を使用してカスタマイズできます。
Go: `OpenMultipleFilesDialog(ctx context.Context, dialogOptions OpenDialogOptions) ([]string, error)`
Returns: Selected files (nil if the user cancelled) or an error
返り値: 選択された複数ファイル(キャンセルされた場合はnil) またはエラー
### SaveFileDialog
Opens a dialog that prompts the user to select a filename for the purposes of saving. Can be customised using [SaveDialogOptions](#savedialogoptions).
保存の目的でユーザにファイル名を入力選択させるダイアログを開きます。 [SaveDialogOptions](#savedialogoptions)を使用してカスタマイズできます。
Go: `SaveFileDialog(ctx context.Context, dialogOptions SaveDialogOptions) (string, error)`
Returns: The selected file (blank if the user cancelled) or an error
返り値: 入力選択されたファイル(キャンセルされた場合は空) またはエラー
### MessageDialog
Displays a message using a message dialog. Can be customised using [MessageDialogOptions](#messagedialogoptions).
メッセージダイアログを使用してメッセージを表示します。 [MessageDialogOptions](#messagedialogoptions)を使用してカスタマイズできます。
Go: `MessageDialog(ctx context.Context, dialogOptions MessageDialogOptions) (string, error)`
Returns: The text of the selected button or an error
返り値: 選択されたボタンのテキストまたはエラー
## Options
## オプション
### OpenDialogOptions
@ -71,16 +71,16 @@ type OpenDialogOptions struct {
}
```
| Field | Description | Win | Mac | Lin |
| -------------------------- | ---------------------------------------------- | --- | --- | --- |
| DefaultDirectory | The directory the dialog will show when opened | ✅ | ✅ | ✅ |
| DefaultFilename | The default filename | ✅ | ✅ | ✅ |
| Title | Title for the dialog | ✅ | ✅ | ✅ |
| [Filters](#filefilter) | A list of file filters | ✅ | ✅ | ✅ |
| ShowHiddenFiles | Show files hidden by the system | | ✅ | ✅ |
| CanCreateDirectories | Allow user to create directories | | ✅ | |
| ResolvesAliases | If true, returns the file not the alias | | ✅ | |
| TreatPackagesAsDirectories | Allow navigating into packages | | ✅ | |
| Field | Description | Win | Mac | Lin |
| -------------------------- | ------------------------- | --- | --- | --- |
| DefaultDirectory | ダイアログが開かれたときに初期表示するディレクトリ | ✅ | ✅ | ✅ |
| DefaultFilename | デフォルトファイル名 | ✅ | ✅ | ✅ |
| Title | ダイアログのタイトル | ✅ | ✅ | ✅ |
| [Filters](#filefilter) | ファイルフィルタのリスト | ✅ | ✅ | ✅ |
| ShowHiddenFiles | システムの隠しファイルを表示 | | ✅ | ✅ |
| CanCreateDirectories | ユーザによるディレクトリの作成を許可する | | ✅ | |
| ResolvesAliases | エイリアスではなくファイルパスを返す | | ✅ | |
| TreatPackagesAsDirectories | パッケージへのナビゲーションを許可 | | ✅ | |
### SaveDialogOptions
@ -96,15 +96,15 @@ type SaveDialogOptions struct {
}
```
| Field | Description | Win | Mac | Lin |
| -------------------------- | ---------------------------------------------- | --- | --- | --- |
| DefaultDirectory | The directory the dialog will show when opened | ✅ | ✅ | ✅ |
| DefaultFilename | The default filename | ✅ | ✅ | ✅ |
| Title | Title for the dialog | ✅ | ✅ | ✅ |
| [Filters](#filefilter) | A list of file filters | ✅ | ✅ | ✅ |
| ShowHiddenFiles | Show files hidden by the system | | ✅ | ✅ |
| CanCreateDirectories | Allow user to create directories | | ✅ | |
| TreatPackagesAsDirectories | Allow navigating into packages | | ✅ | |
| Field | Description | Win | Mac | Lin |
| -------------------------- | ------------------------- | --- | --- | --- |
| DefaultDirectory | ダイアログが開かれたときに初期表示するディレクトリ | ✅ | ✅ | ✅ |
| DefaultFilename | デフォルトファイル名 | ✅ | ✅ | ✅ |
| Title | ダイアログのタイトル | ✅ | ✅ | ✅ |
| [Filters](#filefilter) | ファイルフィルタのリスト | ✅ | ✅ | ✅ |
| ShowHiddenFiles | システムの隠しファイルを表示 | | ✅ | ✅ |
| CanCreateDirectories | ユーザによるディレクトリの作成を許可する | | ✅ | |
| TreatPackagesAsDirectories | パッケージへのナビゲーションを許可 | | ✅ | |
### MessageDialogOptions
@ -119,18 +119,30 @@ type MessageDialogOptions struct {
}
```
| Field | Description | Win | Mac | Lin |
| ------------- | ------------------------------------------------------------------------- | --- | --- | --- |
| Type | The type of message dialog, eg question, info... | ✅ | ✅ | ✅ |
| Title | Title for the dialog | ✅ | ✅ | ✅ |
| Message | The message to show the user | ✅ | ✅ | ✅ |
| Buttons | A list of button titles | | ✅ | |
| DefaultButton | The button with this text should be treated as default. Bound to `return` | | ✅ | |
| CancelButton | The button with this text should be treated as cancel. Bound to `escape` | | ✅ | |
| Field | Description | Win | Mac | Lin |
| ------------- | ------------------------------------------------- | -------------- | --- | --- |
| Type | メッセージダイアログの種類 (質問、情報など) | ✅ | ✅ | ✅ |
| Title | ダイアログのタイトル | ✅ | ✅ | ✅ |
| Message | ユーザに表示するメッセージ | ✅ | ✅ | ✅ |
| Buttons | ボタンテキストのリスト | | ✅ | |
| DefaultButton | 指定されたテキストのボタンをデフォルトボタンとして扱う。 Bound to `return`. | ✅[*](#windows) | ✅ | |
| CancelButton | 指定されたテキストのボタンをキャンセルボタンとして扱う。 `escape`キーにバインドされます。 | | ✅ | |
#### Windows
Windows has standard dialog types in which the buttons are not customisable. The value returned will be one of: "Ok", "Cancel", "Abort", "Retry", "Ignore", "Yes", "No", "Try Again" or "Continue"
Windowsでは、ボタンのカスタマイズができない標準ダイアログタイプがあります。 The value returned will be one of: "Ok", "Cancel", "Abort", "Retry", "Ignore", "Yes", "No", "Try Again" or "Continue".
For Question dialogs, the default button is "Yes" and the cancel button is "No". This can be changed by setting the `DefaultButton` value to `"No"`.
Example:
```go
result, err := runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
Type: runtime.QuestionDialog,
Title: "Question",
Message: "Do you want to continue?",
DefaultButton: "No",
})
```
#### Linux
@ -150,7 +162,7 @@ selection, err := runtime.MessageDialog(b.ctx, runtime.MessageDialogOptions{
})
```
the first button is shown as default:
1番目のボタンがデフォルトになります:
```mdx-code-block
<div class="text--center">

View file

@ -2,13 +2,13 @@
sidebar_position: 2
---
# Events
# イベント
The Wails runtime provides a unified events system, where events can be emitted or received by either Go or Javascript. Optionally, data may be passed with the events. Listeners will receive the data in the local data types.
Wailsでは、GoまたはJavascriptによって発行および受信できる、一元化されたイベントシステムが用意されています。 必要に応じて、イベント発行時にデータを渡すことも可能です。 イベントリスナーは、そのデータをローカルデータ型で受け取ります。
### EventsOn
This method sets up a listener for the given event name. When an event of type `eventName` is [emitted](#EventsEmit), the callback is triggered. Any additional data sent with the emitted event will be passed to the callback.
このメソッドは、指定されたイベント名のイベントリスナーを新たに設定します。 `eventName`という名前のイベントが[発行](#EventsEmit)されると、コールバックがトリガーされます。 イベント発行時にデータも付与されていた場合、そのデータはコールバックに渡されます。
Go: `EventsOn(ctx context.Context, eventName string, callback func(optionalData ...interface{}))`<br/> JS: `EventsOn(eventName string, callback function(optionalData?: any))`
@ -20,18 +20,18 @@ Go: `EventsOff(ctx context.Context, eventName string, additionalEventNames ...st
### EventsOnce
This method sets up a listener for the given event name, but will only trigger once.
このメソッドは、指定されたイベント名のイベントリスナーを新たに設定し、一度だけトリガーさせます。
Go: `EventsOnce(ctx context.Context, eventName string, callback func(optionalData ...interface{}))`<br/> JS: `EventsOnce(eventName string, callback function(optionalData?: any))`
### EventsOnMultiple
This method sets up a listener for the given event name, but will only trigger a maximum of `counter` times.
このメソッドは、指定されたイベント名のイベントリスナーを新たに設定し、最大`counter`回だけトリガーします。
Go: `EventsOnMultiple(ctx context.Context, eventName string, callback func(optionalData ...interface{}), counter int)`<br/> JS: `EventsOnMultiple(eventName string, callback function(optionalData?: any), counter int)`
### EventsEmit
This method emits the given event. Optional data may be passed with the event. This will trigger any event listeners.
このメソッドは、指定されたイベントを発行します。 必要に応じて、イベント発行時にデータを渡すこともできます。 このメソッドによって、任意のイベントリスナーをトリガーさせることができます。
Go: `EventsEmit(ctx context.Context, eventName string, optionalData ...interface{})`<br/> JS: `EventsEmit(ctx context, optionalData function(optionalData?: any))`

View file

@ -2,68 +2,68 @@
sidebar_position: 1
---
# Introduction
# イントロダクション
The runtime is a library that provides utility methods for your application. There is both a Go and Javascript runtime and the aim is to try and keep them at parity where possible.
ランタイムは、アプリケーションにユーティリティメソッドを提供するライブラリです。 GoとJavascriptの両方にランタイムがあり、どちらにもほぼ同じメソッドが提供されています。
ユーティリティメソッドには次のようなものがあります:
- [Window](window.mdx)
- [ウィンドウ](window.mdx)
- [Menu](menu.mdx)
- [Dialog](dialog.mdx)
- [Events](events.mdx)
- [ダイアログ](dialog.mdx)
- [イベント](events.mdx)
- [Browser](browser.mdx)
- [Log](log.mdx)
- [ログ](log.mdx)
The Go Runtime is available through importing `github.com/wailsapp/wails/v2/pkg/runtime`. All methods in this package take a context as the first parameter. This context should be obtained from the [OnStartup](../options.mdx#onstartup) or [OnDomReady](../options.mdx#ondomready) hooks.
Goのランタイムは、`github.com/wailsapp/wails/v2/pkg/runtime`をインポートすることで利用できます。 このパッケージのすべてのメソッドは、1番目の引数でContextを渡す必要があります。 このContextは、[OnStartup](../options.mdx#onstartup)フック、または[OnDomReady](../options.mdx#ondomready)フックからあらかじめ取得しておいてください。
:::info Note
:::info 備考
Whilst the context will be provided to the [OnStartup](../options.mdx#onstartup) method, there's no guarantee the runtime will work in this method as the window is initialising in a different thread. If you wish to call runtime methods at startup, use [OnDomReady](../options.mdx#ondomready).
[OnStartup](../options.mdx#onstartup)で提供されるContextは、ウィンドウが別のスレッドで初期化されているため、ランタイムが機能する保証がありません。 起動時にランタイムメソッドを呼び出したい場合は、[OnDomReady](../options.mdx#ondomready)を使用してください。
:::
The Javascript library is available to the frontend via the `window.runtime` map. There is a runtime package generated when using `dev` mode that provides Typescript declarations for the runtime. This should be located in the `wailsjs` directory in your frontend directory.
Javascriptのランタイムは、`window.runtime`マップを介してフロントエンド上で利用できます。 `dev`モードでは、Typescript型定義を提供するランタイムパッケージが生成されます。 これらは、フロントエンドディレクトリの`wailsjs`ディレクトリに配置しておく必要があります。
### Hide
### 非表示
Go: `Hide(ctx context.Context)`<br/> JS: `Hide()`
Hides the application.
アプリケーションを非表示にします。
:::info Note
:::info 備考
Macでこのメソッドを使用すると、標準のMacアプリケーションにおけるメニュー項目の`Hide`と同じ方法で、アプリケーションが非表示になります。 This is different to hiding the window, but the application still being in the foreground. For Windows and Linux, this is currently the same as `WindowHide`.
Macでこのメソッドを使用すると、標準のMacアプリケーションにおけるメニュー項目の`Hide`と同じ方法で、アプリケーションが非表示になります。 これはウィンドウの非表示とは異なりますが、アプリケーションはフォアグラウンドに残ったままになります。 WindowsおよびLinuxでは、`WindowHide`メソッドと同等です。
:::
### Show
### 表示
Shows the application.
アプリケーションを表示します。
:::info Note
:::info 備考
Macでこのメソッドを使用すると、アプリケーションがフォアグラウンドに戻ります。 For Windows and Linux, this is currently the same as `WindowShow`.
Macでこのメソッドを使用すると、アプリケーションがフォアグラウンドに戻ります。 WindowsおよびLinuxでは、`WindowShow`メソッドと同等です。
:::
Go: `Show(ctx context.Context)`<br/> JS: `Show()`
### Quit
### 終了
Quits the application.
アプリケーションを終了します。
Go: `Quit(ctx context.Context)`<br/> JS: `Quit()`
### Environment
### 環境
Returns details of the current environment.
現在の環境の詳細情報を取得します。
Go: `Environment(ctx context.Context) EnvironmentInfo`<br/> JS: `Environment(): Promise<EnvironmentInfo>`

View file

@ -2,120 +2,120 @@
sidebar_position: 3
---
# Log
# ログ
The Wails runtime provides a logging mechanism that may be called from Go or Javascript. Like most loggers, there are a number of log levels:
Wailsでは、GoまたはJavascriptから呼び出すことのできるロギングメカニズムを用意しています。 一般的なロガーと同じように、ログにはいくつかのログレベルがあります:
- Trace
- Debug
- Info
- Warning
- トレース
- デバッグ
- 情報
- 警告
- Error
- Fatal
- 致命的
The logger will output any log message at the current, or higher, log level. Example: The `Debug` log level will output all messages except `Trace` messages.
ロガーは、設定されている出力ログレベル以上のログメッセージを出力します。 例えば、出力ログレベルを`Debug`に設定した場合、`Trace`以外のすべてのレベルのメッセージが出力されます。
### LogPrint
Logs the given message as a raw message.
指定されたメッセージをRawメッセージとしてロギングします。
Go: `LogPrint(ctx context.Context, message string)`<br/> JS: `LogPrint(message: string)`
### LogPrintf
Logs the given message as a raw message.
指定されたメッセージをRawメッセージとしてロギングします。
Go: `LogPrintf(ctx context.Context, format string, args ...interface{})`<br/>
### LogTrace
Logs the given message at the `Trace` log level.
指定されたメッセージを`Trace`ログレベルでロギングします。
Go: `LogTrace(ctx context.Context, message string)`<br/> JS: `LogTrace(message: string)`
### LogTracef
Logs the given message at the `Trace` log level.
指定されたメッセージを`Trace`ログレベルでロギングします。
Go: `LogTracef(ctx context.Context, format string, args ...interface{})`<br/>
### LogDebug
Logs the given message at the `Debug` log level.
指定されたメッセージを`Debug`ログレベルでロギングします。
Go: `LogDebug(ctx context.Context, message string)`<br/> JS: `LogDebug(message: string)`
### LogDebugf
Logs the given message at the `Debug` log level.
指定されたメッセージを`Debug`ログレベルでロギングします。
Go: `LogDebugf(ctx context.Context, format string, args ...interface{})`<br/>
### LogInfo
Logs the given message at the `Info` log level.
指定されたメッセージを`Info`ログレベルでロギングします。
Go: `LogInfo(ctx context.Context, message string)`<br/> JS: `LogInfo(message: string)`
### LogInfof
Logs the given message at the `Info` log level.
指定されたメッセージを`Info`ログレベルでロギングします。
Go: `LogInfof(ctx context.Context, format string, args ...interface{})`<br/>
### LogWarning
Logs the given message at the `Warning` log level.
指定されたメッセージを`Warning`ログレベルでロギングします。
Go: `LogWarning(ctx context.Context, message string)`<br/> JS: `LogWarning(message: string)`
### LogWarningf
Logs the given message at the `Warning` log level.
指定されたメッセージを`Warning`ログレベルでロギングします。
Go: `LogWarningf(ctx context.Context, format string, args ...interface{})`<br/>
### LogError
Logs the given message at the `Error` log level.
指定されたメッセージを`Error`ログレベルでロギングします。
Go: `LogError(ctx context.Context, message string)`<br/> JS: `LogError(message: string)`
### LogErrorf
Logs the given message at the `Error` log level.
指定されたメッセージを`Error`ログレベルでロギングします。
Go: `LogErrorf(ctx context.Context, format string, args ...interface{})`<br/>
### LogFatal
Logs the given message at the `Fatal` log level.
指定されたメッセージを`Fatal`ログレベルでロギングします。
Go: `LogFatal(ctx context.Context, message string)`<br/> JS: `LogFatal(message: string)`
### LogFatalf
Logs the given message at the `Fatal` log level.
指定されたメッセージを`Fatal`ログレベルでロギングします。
Go: `LogFatalf(ctx context.Context, format string, args ...interface{})`<br/>
### LogSetLogLevel
Sets the log level. In Javascript, the number relates to the following log levels:
出力ログレベルを設定します。 Javascriptでは、数値が次のログレベルに対応しています:
| Value | Log Level |
| ----- | --------- |
| 1 | Trace |
| 2 | Debug |
| 3 | Info |
| 4 | Warning |
| 5 | Error |
| 値 | ログレベル |
| - | ----- |
| 1 | トレース |
| 2 | デバッグ |
| 3 | 情報 |
| 4 | 警告 |
| 5 | Error |
Go: `LogSetLogLevel(ctx context.Context, level logger.LogLevel)`<br/> JS: `LogSetLogLevel(level: number)`
## Using a Custom Logger
## カスタムロガーの使用
A custom logger may be used by providing it using the [Logger](../options.mdx#logger) application option. The only requirement is that the logger implements the `logger.Logger` interface defined in `github.com/wailsapp/wails/v2/pkg/logger`:
カスタムロガーは、アプリケーションオプションの1つである[Logger](../options.mdx#logger)で指定してあげることで、使用することができます。 カスタムロガーを使用する際の唯一の要件は、`github.com/wailsapp/wails/v2/pkg/logger`で定義されている`logger.Logger`インターフェースを、ロガーに実装することです:
```go title="logger.go"
type Logger interface {

View file

@ -4,24 +4,24 @@ sidebar_position: 6
# Menu
These methods are related to the application menu.
これらは、アプリケーションメニューに関連したメソッドです。
:::info Javascript
Menu is currently unsupported in the JS runtime.
現在、Javascriptランタイムではメニューをサポートしていません。
:::
### MenuSetApplicationMenu
Sets the application menu to the given [menu](../menus.mdx).
指定された[menu](../menus.mdx)をアプリケーションメニューとして設定します。
Go: `MenuSetApplicationMenu(ctx context.Context, menu *menu.Menu)`
### MenuUpdateApplicationMenu
Updates the application menu, picking up any changes to the menu passed to `MenuSetApplicationMenu`.
`MenuSetApplicationMenu`に渡されたメニューへの変更を検知し、アプリケーションメニューを更新します。
Go: `MenuUpdateApplicationMenu(ctx context.Context)`

View file

@ -2,199 +2,199 @@
sidebar_position: 4
---
# Window
# ウィンドウ
These methods give control of the application window.
アプリケーションウィンドウを制御できるメソッド群です。
### WindowSetTitle
Sets the text in the window title bar.
ウィンドウのタイトルバーにテキストを設定します。
Go: `WindowSetTitle(ctx context.Context, title string)`<br/> JS: `WindowSetTitle(title: string)`
### WindowFullscreen
Makes the window full screen.
ウィンドウをフルスクリーンにします。
Go: `WindowFullscreen(ctx context.Context)`<br/> JS: `WindowFullscreen()`
### WindowUnfullscreen
Restores the previous window dimensions and position prior to full screen.
フルスクリーンにする前のウィンドウサイズおよび位置に戻します。
Go: `WindowUnfullscreen(ctx context.Context)`<br/> JS: `WindowUnfullscreen()`
### WindowIsFullscreen
Returns true if the window is full screen.
ウィンドウがフルスクリーンの場合は、trueを返します。
Go: `WindowIsFullscreen(ctx context.Context) bool`<br/> JS: `WindowIsFullscreen() bool`
### WindowCenter
Centers the window on the monitor the window is currently on.
ウィンドウが現在表示されているモニターの中央に、ウィンドウを配置させます。
Go: `WindowReload(ctx context.Context)`<br/> JS: `WindowReload()`
### WindowReload
Performs a "reload" (Reloads current page).
リロードします。(現在表示されているページをリロード)
Go: `WindowReloadApp(ctx context.Context)`<br/> JS: `WindowReloadApp()`
### WindowReloadApp
Reloads the application frontend.
アプリケーションフロントエンドをリロードします。
Go: `WindowSetSystemDefaultTheme(ctx context.Context)`<br/> JS: `WindowSetSystemDefaultTheme()`
### WindowSetSystemDefaultTheme
Windows only.
Windowsのみ使用可能。
Go: `WindowSetDarkTheme(ctx context.Context)`<br/> JS: `WindowSetDarkTheme()`
Sets window theme to system default (dark/light).
ウィンドウのテーマをシステムデフォルト(ダーク/ライト) に設定します。
### WindowSetLightTheme
Windows only.
Windowsのみ使用可能。
Go: `WindowSetLightTheme(ctx context.Context)`<br/> JS: `WindowSetLightTheme()`
Sets window theme to light.
ウィンドウのテーマをライトに設定します。
### WindowSetDarkTheme
Windows only.
Windowsのみ使用可能。
Go: `WindowShow(ctx context.Context)`<br/> JS: `WindowShow()`
Sets window theme to dark.
ウィンドウのテーマをダークに設定します。
### WindowShow
Shows the window, if it is currently hidden.
ウィンドウが非表示になっている場合は、表示させます。
Go: `WindowHide(ctx context.Context)`<br/> JS: `WindowHide()`
### WindowHide
Hides the window, if it is currently visible.
現在表示されているウィンドウを非表示にします。
Go: `WindowSetSize(ctx context.Context, width int, height int)`<br/> JS: `WindowSetSize(size: Size)`
### WindowIsNormal
Returns true if the window not minimised, maximised or fullscreen.
ウィンドウが最小化、最大化、またはフルスクリーンになっていない場合、trueを返します。
Go: `WindowIsNormal(ctx context.Context) bool`<br/> JS: `WindowIsNormal() bool`
### WindowSetSize
Sets the width and height of the window.
ウィンドウの幅と高さを設定します。
Go: `WindowSetMaxSize(ctx context.Context, width int, height int)`<br/> JS: `WindowSetMaxSize(size: Size)`
### WindowGetSize
Gets the width and height of the window.
ウィンドウの幅と高さを取得します。
Go: `WindowSetMinSize(ctx context.Context, width int, height int)`<br/> JS: `WindowSetMinSize(size: Size)`
Go: `WindowGetSize(ctx context.Context) (width int, height int)`<br/> JS: `WindowGetSize() : Size`
### WindowSetMinSize
Sets the minimum window size. Will resize the window if the window is currently smaller than the given dimensions.
ウィンドウの最小サイズを設定します。 現在のウィンドウサイズが、指定された最小サイズよりも小さい場合、現在のウィンドウサイズは変更されます。
Setting a size of `0,0` will disable this constraint.
サイズを`0,0`に設定すると、サイズの制約が無効化されます。
Go: `WindowSetAlwaysOnTop(ctx context.Context, b bool)`<br/> JS: `WindowSetAlwaysOnTop(b: Boolen)`
### WindowSetMaxSize
Sets the maximum window size. Will resize the window if the window is currently larger than the given dimensions.
ウィンドウの最大サイズを設定します。 現在のウィンドウサイズが、指定された最大サイズよりも大きい場合、現在のウィンドウサイズは変更されます。
Setting a size of `0,0` will disable this constraint.
サイズを`0,0`に設定すると、サイズの制約が無効化されます。
Go: `WindowSetPosition(ctx context.Context, x int, y int)`<br/> JS: `WindowSetPosition(position: Position)`
### WindowSetAlwaysOnTop
Sets the window AlwaysOnTop or not on top.
ウィンドウを常に最前面に表示するかを切り替えます。
Go: `WindowGetPosition(ctx context.Context) (x int, y int)`<br/> JS: `WindowGetPosition() : Position`
Go: `WindowSetAlwaysOnTop(ctx context.Context, b bool)`<br/> JS: `WindowSetAlwaysOnTop(b: Boolen)`
### WindowSetPosition
Sets the window position relative to the monitor the window is currently on.
現在ウィンドウが表示されているモニターに対する、相対的なウィンドウ位置を設定します。
Go: `WindowMaximise(ctx context.Context)`<br/> JS: `WindowMaximise()`
### WindowGetPosition
Gets the window position relative to the monitor the window is currently on.
現在ウィンドウが表示されているモニターに対する、相対的なウィンドウ位置を取得します。
Go: `WindowUnmaximise(ctx context.Context)`<br/> JS: `WindowUnmaximise()`
Go: `WindowGetPosition(ctx context.Context) (x int, y int)`<br/> JS: `WindowGetPosition() : Position`
### WindowMaximise
Maximises the window to fill the screen.
ウィンドウを最大化します。
Go: `WindowToggleMaximise(ctx context.Context)`<br/> JS: `WindowToggleMaximise()`
### WindowUnmaximise
Restores the window to the dimensions and position prior to maximising.
ウィンドウの最大化を解除し、最大化する前のサイズおよび位置に戻します。
Go: `WindowMinimise(ctx context.Context)`<br/> JS: `WindowMinimise()`
### WindowIsMaximised
Returns true if the window is maximised.
ウィンドウが最大化している場合はtrueを返します。
Go: `WindowIsMaximised(ctx context.Context) bool`<br/> JS: `WindowIsMaximised() bool`
### WindowToggleMaximise
Toggles between Maximised and UnMaximised.
最大化の状態を切り替えます。
Go: `WindowToggleMaximise(ctx context.Context)`<br/> JS: `WindowToggleMaximise()`
### WindowMinimise
Minimises the window.
ウィンドウを最小化します。
Go: `WindowSetBackgroundColour(ctx context.Context, R, G, B, A uint8)`<br/> JS: `WindowSetBackgroundColour(R, G, B, A)`
### WindowUnminimise
Restores the window to the dimensions and position prior to minimising.
ウィンドウの最小化を解除し、最小化する前のサイズおよび位置に戻します。
Go: `WindowUnminimise(ctx context.Context)`<br/> JS: `WindowUnminimise()`
### WindowIsMinimised
Returns true if the window is minimised.
ウィンドウが最小化している場合はtrueを返します。
Go: `WindowIsMinimised(ctx context.Context) bool`<br/> JS: `WindowIsMinimised() bool`
### WindowSetBackgroundColour
Sets the background colour of the window to the given RGBA colour definition. This colour will show through for all transparent pixels.
ウィンドウの背景色をRGBAカラー定義で設定します。 この色は、すべての透過ピクセルに対して表示されます。
Valid values for R, G, B and A are 0-255.
R、G、B、Aの有効な値の範囲は0255です。
:::info Windows
On Windows, only alpha values of 0 or 255 are supported. Any value that is not 0 will be considered 255.
Windowsの場合、0または255のアルファ値(A) のみがサポートされています。 0以外の値を指定すると、すべて255とみなされます。
:::
Go: `WindowSetBackgroundColour(ctx context.Context, R, G, B, A uint8)`<br/> JS: `WindowSetBackgroundColour(R, G, B, A)`
## Typescript Object Definitions
## Typescript型定義
### Position

View file

@ -4,11 +4,11 @@
"description": "The label for version v2.0.0-rc.1"
},
"sidebar.docs.category.Getting Started": {
"message": "Getting Started",
"message": "はじめよう",
"description": "The label for category Getting Started in sidebar docs"
},
"sidebar.docs.category.Reference": {
"message": "Reference",
"message": "リファレンス",
"description": "The label for category Reference in sidebar docs"
},
"sidebar.docs.category.Runtime": {
@ -16,23 +16,23 @@
"description": "The label for category Runtime in sidebar docs"
},
"sidebar.docs.category.Community": {
"message": "Community",
"message": "コミュニティ",
"description": "The label for category Community in sidebar docs"
},
"sidebar.docs.category.Showcase": {
"message": "Showcase",
"message": "事例紹介",
"description": "The label for category Showcase in sidebar docs"
},
"sidebar.docs.category.Guides": {
"message": "Guides",
"message": "ガイド",
"description": "The label for category Guides in sidebar docs"
},
"sidebar.docs.category.Tutorials": {
"message": "Tutorials",
"message": "チュートリアル",
"description": "The label for category Tutorials in sidebar docs"
},
"sidebar.docs.link.Contributing": {
"message": "Contributing",
"message": "コントリビューション",
"description": "The label for link Contributing in sidebar docs, linking to /community-guide#ways-of-contributing"
}
}

View file

@ -4,11 +4,11 @@
"description": "The label for version v2.0.0"
},
"sidebar.docs.category.Getting Started": {
"message": "Getting Started",
"message": "はじめよう",
"description": "The label for category Getting Started in sidebar docs"
},
"sidebar.docs.category.Reference": {
"message": "Reference",
"message": "リファレンス",
"description": "The label for category Reference in sidebar docs"
},
"sidebar.docs.category.Runtime": {
@ -16,23 +16,23 @@
"description": "The label for category Runtime in sidebar docs"
},
"sidebar.docs.category.Community": {
"message": "Community",
"message": "コミュニティ",
"description": "The label for category Community in sidebar docs"
},
"sidebar.docs.category.Showcase": {
"message": "Showcase",
"message": "事例紹介",
"description": "The label for category Showcase in sidebar docs"
},
"sidebar.docs.category.Guides": {
"message": "Guides",
"message": "ガイド",
"description": "The label for category Guides in sidebar docs"
},
"sidebar.docs.category.Tutorials": {
"message": "Tutorials",
"message": "チュートリアル",
"description": "The label for category Tutorials in sidebar docs"
},
"sidebar.docs.link.Contributing": {
"message": "Contributing",
"message": "コントリビューション",
"description": "The label for link Contributing in sidebar docs, linking to /community-guide#ways-of-contributing"
}
}

View file

@ -5,13 +5,13 @@ Wails includes support for obfuscating your application using [garble](https://g
To produce an obfuscated build, you can use the `-obfuscate` flag with the `wails build` command:
```bash
wails build -obfuscate
wails build -obfuscated
```
To customise the obfuscation settings, you can use the `-garbleargs` flag:
```bash
wails build -obfuscate -garbleargs "-literals -tiny -seed=myrandomseed"
wails build -obfuscated -garbleargs "-literals -tiny -seed=myrandomseed"
```
These settings may be persisted in your [project config](../reference/project-config).

View file

@ -4,7 +4,22 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
## v2.0.0 - 2022-09-22
## Fixed
* Fix buildtags parsing if only one tag is specified by @stffabi in https://github.com/wailsapp/wails/pull/1858
* Use embed all to include all files in templates by @stffabi in https://github.com/wailsapp/wails/pull/1862
## Changed
* Bump minimum required Go version to 1.18 by @stffabi in https://github.com/wailsapp/wails/pull/1854
* Add check for minimum required Go version by @stffabi in https://github.com/wailsapp/wails/pull/1853
* chore: update README and workflows by @misitebao in https://github.com/wailsapp/wails/pull/1848
* Update introduction.mdx by @ParvinEyvazov in https://github.com/wailsapp/wails/pull/1863
* Releasetest/release workflow by @leaanthony in https://github.com/wailsapp/wails/pull/1869
* Optimize documentation website by @misitebao in https://github.com/wailsapp/wails/pull/1849
## New Contributors
* @ParvinEyvazov made their first contribution in https://github.com/wailsapp/wails/pull/1863
## v2.0.0-rc.1 - 2022-09-13

View file

@ -1,4 +1,4 @@
# Contributor Covenant Code of Conduct
# コントリビューターの行動規範
## 私たちの約束
@ -32,25 +32,25 @@
## 適用範囲
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
この行動規範は、すべてのコミュニティスペース内で適用され、個人がパブリックスペースでコミュニティを公式に代表している場合にも適用されます。 私たちのコミュニティを代表する例には、公式の電子メールアドレスの使用、公式のソーシャルメディアアカウントを介した投稿、オンラインまたはオフラインのイベントでの指定代理人としての行動などがあります。
## 執行
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at coc@wails.io. All complaints will be reviewed and investigated promptly and fairly.
虐待的、嫌がらせ、またはその他の許容できない行動の事例は、執行を担当するコミュニティリーダー coc@wails.io へ報告される場合があります。 すべての苦情は迅速かつ公正にレビューおよび調査されます。
すべてのコミュニティリーダーは、問題の報告者のプライバシーとセキュリティを尊重する義務があります。
## 執行ガイドライン
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
コミュニティリーダーは、この行動規範に違反していると見なした行動への帰結を判断する際に、これらのコミュニティガイドラインに従います。
### 1. Correction
### 1. 更生
**コミュニティへの影響**: コミュニティで専門家にふさわしくない、または歓迎されないと思われる不適切な言葉の使用やその他の不適切な行動をすること。
**帰結**: コミュニティリーダーからの非公開の書面による警告。 違反の理由を明確にし、行動が不適切だった理由を説明します。 公の謝罪が要求される場合があります。
### 2. Warning
### 2. 警告
**コミュニティへの影響**: 単一の出来事または一連の動作による違反。
@ -60,7 +60,7 @@ Community leaders will follow these Community Impact Guidelines in determining t
**コミュニティへの影響**: 持続的で不適切な行動を含む、コミュニティ標準の重大な違反。
**帰結**: 指定された期間のコミュニティとのあらゆる種類の相互関係または公的なコミュニケーションの一時的な禁止。 この期間中、行動規範を実施する人々との一方的な対話を含め、関係する人々との公的または私的な対話は許可されません。 これらの条件に違反すると、永久的に禁止される場合があります。 Violating these terms may lead to a permanent ban.
**帰結**: 指定された期間のコミュニティとのあらゆる種類の相互関係または公的なコミュニケーションの一時的な禁止。 この期間中、行動規範を実施する人々との一方的な対話を含め、関係する人々との公的または私的な対話は許可されません。 これらの条件に違反すると、永久的に禁止される場合があります。 これらの条件に違反すると、永久的に禁止される場合があります。
### 4. 永久的な禁止
@ -68,7 +68,7 @@ Community leaders will follow these Community Impact Guidelines in determining t
**帰結**: コミュニティ内でのあらゆる種類の公的な相互関係の永久的な禁止。
## Attribution
## 帰属
この行動規範は、https://www.contributor-covenant.org/version/2/0/code_of_conduct.html で利用可能な [Contributor Covenant](https://www.contributor-covenant.org) バージョン 2.0 を基に作成されています。

View file

@ -1,15 +1,15 @@
# Credits
# クレジット
- [Lea Anthony](https://github.com/leaanthony) - Project owner, lead developer
- [Stffabi](https://github.com/stffabi) - Technical lead, developer and maintainer
- [Misite Bao](https://github.com/misitebao) - Documentation wizard, Chinese translation, Windows testing, Bug finder general
- [Travis McLane](https://github.com/tmclane) - Cross-compilation work, MacOS testing
- [Byron Chris](https://github.com/bh90210) - Linux distro wizard, Linux testing
- [Lea Anthony](https://github.com/leaanthony) - プロジェクトオーナー、開発リーダー
- [Stffabi](https://github.com/stffabi) - テクニカルリーダー、開発担当、保守担当
- [Misite Bao](https://github.com/misitebao) - ドキュメント専門担当、翻訳担当(中国語)、Windowsテスター、不具合収集担当
- [Travis McLane](https://github.com/tmclane) - クロスコンパイル担当、MacOSテスター
- [Byron Chris](https://github.com/bh90210) - Linuxディストリビューション専門担当、Linuxテスター
## Sponsors
## スポンサー
<img src="/img/sponsors.svg" style={{"width":"85%","max-width":"800px;"}} />
## Contributors
## コントリビューター
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
@ -179,6 +179,7 @@
<td align="center"><a href="http://mai.car.ons"><img src="https://avatars.githubusercontent.com/u/101958587?v=4?s=75" width="75px;" alt=""/><br /><sub><b>Maicarons J</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=Maicarons2022" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/KiddoV"><img src="https://avatars.githubusercontent.com/u/28552977?v=4?s=75" width="75px;" alt=""/><br /><sub><b>kiddov</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=KiddoV" title="Documentation">📖</a> <a href="#financial-KiddoV" title="Financial">💵</a> <a href="https://github.com/wailsapp/wails/commits?author=KiddoV" title="Tests">⚠️</a> <a href="#ideas-KiddoV" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center"><a href="https://nicolas-coutin.com/"><img src="https://avatars.githubusercontent.com/u/6564012?v=4?s=75" width="75px;" alt=""/><br /><sub><b>Nicolas Coutin</b></sub></a><br /><a href="#financial-Ilshidur" title="Financial">💵</a></td>
<td align="center"><a href="https://github.com/ParvinEyvazov"><img src="https://avatars.githubusercontent.com/u/32189770?v=4?s=75" width="75px;" alt=""/><br /><sub><b>Parvin Eyvazov</b></sub></a><br /><a href="https://github.com/wailsapp/wails/commits?author=ParvinEyvazov" title="Documentation">📖</a></td>
</tr>
</table>
@ -187,12 +188,12 @@
<!-- ALL-CONTRIBUTORS-LIST:END -->
## Special Mentions
## スペシャルサンクス
- [John Chadwick](https://github.com/jchv) - His amazing work on [go-webview2](https://github.com/jchv/go-webview2) and [go-winloader](https://github.com/jchv/go-winloader) have made the Windows version possible.
- [Tad Vizbaras](https://github.com/tadvi) - His winc project was the first step down the path to a pure Go Wails.
- [Mat Ryer](https://github.com/matryer) - For advice, support and bants.
- [Dustin Krysak](https://wiki.ubuntu.com/bashfulrobot) - His support and feedback has been invaluable.
- [Justen Walker](https://github.com/justenwalker/) - For helping wrangle COM issues which got v2 over the line.
- [Wang, Chi](https://github.com/patr0nus/) - The DeskGap project was a huge influence on the direction of Wails v2.
- [Serge Zaitsev](https://github.com/zserge) - Whilst Wails does not use the Webview project, it is still a source of inspiration.
- [John Chadwick](https://github.com/jchv) - 彼の[go-webview2](https://github.com/jchv/go-webview2)および[go-winloader](https://github.com/jchv/go-winloader)というすばらしい成果によって、Windows版を開発できました。
- [Tad Vizbaras](https://github.com/tadvi) - 彼のwincプロジェクトは、純粋なGo Wails開発の最初のステップでした。
- [Mat Ryer](https://github.com/matryer) - アドバイス、サポート、営業。
- [Dustin Krysak](https://wiki.ubuntu.com/bashfulrobot) - 彼は非常に有益なサポートおよびフィードバックをしてくれました。
- [Justen Walker](https://github.com/justenwalker/) - v2を成功させるために、COM問題を解決してくれました。
- [Wang, Chi](https://github.com/patr0nus/) - DeskGapプロジェクトは、Wails v2の方向性に大きな影響を与えてくれました。
- [Serge Zaitsev](https://github.com/zserge) - WailsがWebviewを使用していない間、インスピレーションの源となっていました。

View file

@ -4,4 +4,4 @@ title: Markdown page example
# Markdown page example
You don't need React to write simple standalone pages.
シンプルな単一ページを作成する場合、Reactは必要ありません。

View file

@ -4,7 +4,7 @@
"description": "The title of the footer links column with title=Docs in the footer"
},
"link.title.Community": {
"message": "Community",
"message": "コミュニティ",
"description": "The title of the footer links column with title=Community in the footer"
},
"link.title.More": {
@ -12,11 +12,11 @@
"description": "The title of the footer links column with title=More in the footer"
},
"link.item.label.Introduction": {
"message": "Introduction",
"message": "イントロダクション",
"description": "The label of footer link with label=Introduction linking to /docs/introduction"
},
"link.item.label.Getting Started": {
"message": "Getting Started",
"message": "はじめよう",
"description": "The label of footer link with label=Getting Started linking to /docs/gettingstarted/installation"
},
"link.item.label.Changelog": {

View file

@ -16,7 +16,7 @@
"description": "Navbar item with label GitHub"
},
"item.label.About": {
"message": "About",
"message": "概要",
"description": "Navbar item with label About"
},
"item.label.FAQ": {
@ -32,11 +32,11 @@
"description": "Navbar item with label Community Guide"
},
"item.label.Credits": {
"message": "Credits",
"message": "クレジット",
"description": "Navbar item with label Credits"
},
"item.label.Code of Conduct": {
"message": "Code of Conduct",
"message": "行動規範",
"description": "Navbar item with label Code of Conduct"
}
}

View file

@ -242,7 +242,7 @@
"description": "The label used by the button on the collapsible TOC component"
},
"theme.navbar.mobileLanguageDropdown.label": {
"message": "语言",
"message": "选择语言",
"description": "The label for the mobile language switcher dropdown"
},
"theme.SearchBar.seeAll": {

View file

@ -65,9 +65,9 @@ Gophers 欢呼吧! 单个二进制文件的构想依然存在!
<br />
```
有很多对原生菜单支持的求。 Wails 终于帮您搞定了。 应用程序菜单现已可用,并且包括对大多数原生菜单功能的支持。 这包括标准菜单项、复选框、单选组、子菜单和分隔符。
有很多对原生菜单支持的求。 Wails 终于帮您搞定了。 应用程序菜单现已可用,并且包括对大多数原生菜单功能的支持。 这包括标准菜单项、复选框、单选组、子菜单和分隔符。
在 v1 中有大量的求,要求能够更好地控制窗口本身。 我很高兴地宣布,有专门用于此的新运行时 API。 它功能丰富,支持多显示器配置。 还有一个改进的对话框 API现在您可以拥有具有丰富配置的现代原生对话框以满足您所有对话框需求。
在 v1 中有大量的求,要求能够更好地控制窗口本身。 我很高兴地宣布,有专门用于此的新运行时 API。 它功能丰富,支持多显示器配置。 还有一个改进的对话框 API现在您可以拥有具有丰富配置的现代原生对话框以满足您所有对话框需求。
现在可以选择随项目生成 IDE 配置。 这意味着如果您在受支持的 IDE 中打开您的项目,它已经被配置为构建和调试您的应用程序。 目前支持 VSCode但我们希望尽快支持其他 IDE例如 Goland。

View file

@ -95,4 +95,4 @@ V2 版本是该项目的巨大飞跃,解决了 v1 的许多痛点。 如果您
&dash; Lea
PPS如果您或您的公司发现 Wails 有用,可以考虑 [赞助该项目](https://github.com/sponsors/leaanthony)。 谢谢! 谢谢!
PPS如果您或您的公司发现 Wails 有用,可以考虑 [赞助该项目](https://github.com/sponsors/leaanthony)。 谢谢!

View file

@ -21,3 +21,6 @@ Wails 相关的 [优秀列表](https://github.com/wailsapp/awesome-wails)。
- [Twitter](https://twitter.com/wailsapp)
- [Wails 中文社区 QQ 群](https://qm.qq.com/cgi-bin/qm/qr?k=PmIURne5hFGNd7QWzW5qd6FV-INEjNJv&jump_from=webapi) - 群号1067173054
## 其他教程和文章
- [Building of Bulletin Board](https://blog.customct.com/building-bulletin-board)

View file

@ -37,6 +37,7 @@ sidebar_position: 1
- [wails-react-template](https://github.com/AlienRecall/wails-react-template) - 基于 reactjs 的模板
- [wails-react-template](https://github.com/flin7/wails-react-template) - 基于 React 并支持实时开发模式的轻量级模板
- [wails-vite-react-ts](https://github.com/lontten/wails-vite-react-ts) - 基于 Vite + React + TypeScript 的模板
- [wails-vite-react-ts-tailwind-template](https://github.com/hotafrika/wails-vite-react-ts-tailwind-template) - 一个 React + TypeScript + Vite + TailwindCSS 模板
## Svelte

View file

@ -9,7 +9,7 @@ sidebar_position: 5
- 构建您的应用程序并运行它
- 将您的 Go 代码绑定到前端,以便可以从 Javascript 调用它
- 使用 [Vite](https://vitejs.dev/) 的强大功能,将监视您的 Go 文件中的修改并在更改时重新构建/重新运行
- 启动一个 [网络服务器](http://localhost:34115) 通过浏览器为您的应用程序提供服务。 这使您可以使用自己喜欢的浏览器扩展。你甚至可以从控制台调用你的 Go 代码。 您甚至可以从控制台调用 Go 代码。
- 启动一个 [网络服务器](http://localhost:34115) 通过浏览器为您的应用程序提供服务。 这使您可以使用自己喜欢的浏览器扩展。 你甚至可以从控制台调用你的 Go 代码。
首先,在项目目录中运行 `wails dev`。 可以在 [此处](../reference/cli#开发) 找到有关这方面的更多信息。

View file

@ -116,10 +116,10 @@ Wails 项目有以下布局:
- `/main.go` - 主应用
- `/frontend/` - 前端项目文件
- `/build/` - 项目构建目录
- `/wails.json` - 应用程序图标
- `/go.mod` - Mac 特定的项目文件
- `/go.sum` - Windows 特定的项目文件
- `/build/windows/` - 项目配置
- `/build/appicon.png` - 应用程序图标
- `/build/darwin/` - Mac 特定的项目文件
- `/build/windows/` - Windows 特定的项目文件
- `/wails.json` - 项目配置
- `/go.mod` - Go module 文件
- `/go.sum` - Go module 校验文件

Some files were not shown because too many files have changed in this diff Show more