mirror of
https://github.com/taigrr/wails.git
synced 2026-04-02 05:08:54 -07:00
Add Message dialog to Kitchen Sink
This commit is contained in:
@@ -162,14 +162,10 @@ func (c *Client) MessageDialog(dialogOptions *options.MessageDialog, callbackID
|
||||
return
|
||||
}
|
||||
|
||||
// Reverse
|
||||
|
||||
// Process buttons
|
||||
buttons := []string{"", "", "", ""}
|
||||
count := 0
|
||||
for i := len(dialogOptions.Buttons) - 1; i >= 0; i-- {
|
||||
buttons[count] = dialogOptions.Buttons[i]
|
||||
count++
|
||||
for i, button := range dialogOptions.Buttons {
|
||||
buttons[i] = button
|
||||
}
|
||||
|
||||
C.MessageDialog(c.app.app,
|
||||
|
||||
@@ -72,7 +72,7 @@ export function Save(options) {
|
||||
* @param {DialogType} [Type=InfoDialog] - The type of the dialog
|
||||
* @param {string} [Title=""] - The dialog title
|
||||
* @param {string} [Message=""] - The dialog message
|
||||
* @param {string[]} [Buttons=[]] - The button titles in the order they should appear
|
||||
* @param {string[]} [Buttons=[]] - The button titles
|
||||
* @param {string} [DefaultButton=""] - The button that should be used as the default button
|
||||
* @param {string} [CancelButton=""] - The button that should be used as the cancel button
|
||||
* @param {string} [Icon=""] - The name of the icon to use in the dialog
|
||||
@@ -83,6 +83,7 @@ export function Save(options) {
|
||||
* or prompt the user to select an option
|
||||
*
|
||||
* @export
|
||||
* @name Message
|
||||
* @param {MessageDialogOptions} options
|
||||
* @returns {Promise<string>} - The button text that was selected
|
||||
*/
|
||||
|
||||
@@ -67,7 +67,7 @@ export function Save(options) {
|
||||
* @param {DialogType} [Type=InfoDialog] - The type of the dialog
|
||||
* @param {string} [Title=""] - The dialog title
|
||||
* @param {string} [Message=""] - The dialog message
|
||||
* @param {string[]} [Buttons=[]] - The button titles in the order they should appear
|
||||
* @param {string[]} [Buttons=[]] - The button titles
|
||||
* @param {string} [DefaultButton=""] - The button that should be used as the default button
|
||||
* @param {string} [CancelButton=""] - The button that should be used as the cancel button
|
||||
* @param {string} [Icon=""] - The name of the icon to use in the dialog
|
||||
|
||||
@@ -31,17 +31,3 @@ func (l *Dialog) Save(options *options.SaveDialog) string {
|
||||
func (l *Dialog) Message(options *options.MessageDialog) string {
|
||||
return l.runtime.Dialog.Message(options)
|
||||
}
|
||||
|
||||
// Message Dialog
|
||||
func (l *Dialog) Test() string {
|
||||
return l.runtime.Dialog.Message(&options.MessageDialog{
|
||||
Type: options.InfoDialog,
|
||||
Title: " ",
|
||||
Message: "I am a longer message but these days, can't be too long!",
|
||||
// Buttons are declared in the order they should be appear in
|
||||
Buttons: []string{"test", "Cancel", "OK"},
|
||||
DefaultButton: "OK",
|
||||
CancelButton: "Cancel",
|
||||
//Icon: "wails",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<Link href="https://wails.app">Here</Link> is an example.
|
||||
|
||||
<br/><br/>
|
||||
|
||||
<Browser></Browser>
|
||||
|
||||
<Browser/>
|
||||
</div>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
<input class="btn btn-primary" type="button" on:click="{processOpen}" value="Open using {lang} runtime">
|
||||
|
||||
<CodeSnippet bind:isJs={isJs} jsCode={testcodeJs} goCode={testcodeGo}></CodeSnippet>
|
||||
<CodeSnippet bind:isJs={isJs} jsCode={testcodeJs} goCode={testcodeGo}/>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
@@ -1,14 +1,23 @@
|
||||
<script>
|
||||
import Open from './Open/Open.svelte';
|
||||
import Save from './Save/Save.svelte';
|
||||
import Open from './Open/Open.svelte';
|
||||
import Save from './Save/Save.svelte';
|
||||
import Message from "./Message/Message.svelte";
|
||||
</script>
|
||||
<div>
|
||||
The ability to open a dialog and prompt the user to select files or directories is provided as part of the <code>runtime.Dialog</code> component. There are 2 types of dialogs available: Save and Open.
|
||||
|
||||
Sometimes there is a need to prompt the user for input. Dialogs are a good approach to this and Wails provides access to native dialogs. The dialog types supported are:
|
||||
|
||||
<ul class="list">
|
||||
<li>Open - Prompts the user to select one or more files or folders</li>
|
||||
<li>Save - Prompts the user to select a file or input a filename</li>
|
||||
<li>Message - Prompts the user with information and optionally provides action buttons</li>
|
||||
</ul>
|
||||
|
||||
<br/><br/>
|
||||
|
||||
<Open></Open>
|
||||
|
||||
<Open/>
|
||||
<br/>
|
||||
<Save></Save>
|
||||
<Save/>
|
||||
<br/>
|
||||
<Message/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
<script>
|
||||
import {Dialog} from '@wails/runtime';
|
||||
import CodeBlock from '../../../components/CodeBlock.svelte';
|
||||
import CodeSnippet from '../../../components/CodeSnippet.svelte';
|
||||
import jsCode from './code.jsx';
|
||||
import goCode from './code.go';
|
||||
|
||||
let isJs = false;
|
||||
$: lang = isJs ? 'Javascript' : 'Go';
|
||||
let id = "MessageDialog";
|
||||
|
||||
let options = {
|
||||
"Type": "info",
|
||||
"Title": "",
|
||||
"Message": "",
|
||||
"Buttons": [],
|
||||
"DefaultButton": "",
|
||||
"CancelButton": "",
|
||||
"Icon": "",
|
||||
}
|
||||
|
||||
function processMessage() {
|
||||
if( isJs ) {
|
||||
console.log(options);
|
||||
Dialog.Message(options);
|
||||
} else {
|
||||
backend.main.Dialog.Message(options).then( (result) => {
|
||||
console.log(result);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function prettyPrintArray(json) {
|
||||
if (typeof json === 'string') {
|
||||
json = JSON.parse(json);
|
||||
}
|
||||
return JSON.stringify(json, function (k, v) {
|
||||
if (v instanceof Array)
|
||||
return JSON.stringify(v);
|
||||
return v;
|
||||
}, 2).replace(/\\/g, '')
|
||||
.replace(/"\[/g, '[')
|
||||
.replace(/]"/g, ']')
|
||||
.replace(/"{/g, '{')
|
||||
.replace(/}"/g, '}');
|
||||
}
|
||||
|
||||
let dialogTypes = ["Info", "Warning", "Error", "Question"];
|
||||
let dialogTypeSelected = dialogTypes[0];
|
||||
let buttonInputs = ["","","",""];
|
||||
|
||||
// Keep buttons in sync
|
||||
$: {
|
||||
options.Buttons = [];
|
||||
buttonInputs.forEach( (button) => {
|
||||
if ( button.length > 0 ) {
|
||||
options.Buttons.push(button);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Keep options in sync with dialog type selected
|
||||
$: options.Type = dialogTypeSelected.toLowerCase();
|
||||
|
||||
// Inspired by: https://stackoverflow.com/a/54931396
|
||||
$: encodedJSOptions = JSON.stringify(options, function (k, v) {
|
||||
if (v instanceof Array)
|
||||
return JSON.stringify(v);
|
||||
return v;
|
||||
}, 4)
|
||||
.replace(/\\/g, '')
|
||||
.replace(/"\[/g, '[')
|
||||
.replace(/]"/g, ']')
|
||||
.replace(/"{/g, '{')
|
||||
.replace(/}"/g, '}');
|
||||
|
||||
$: encodedGoOptions = encodedJSOptions
|
||||
.replace(/ {2}"(.*)":/mg, " $1:")
|
||||
.replace(/Type: "(.*)"/mg, "Type: options." + dialogTypeSelected + "Dialog")
|
||||
.replace(/Buttons: \[(.*)],/mg, "Buttons: []string{$1},")
|
||||
.replace(/\n}/, ",\n}");
|
||||
|
||||
$: testcodeJs = "import { Dialog } from '@wails/runtime';\n\nDialog.Message(" + encodedJSOptions + ");";
|
||||
$: testcodeGo = '// runtime is given through WailsInit()\nimport "github.com/wailsapp/wails/v2/pkg/options"\n\nselectedFiles := runtime.Dialog.Message( &options.MessageDialog' + encodedGoOptions + ')';
|
||||
|
||||
</script>
|
||||
|
||||
<CodeBlock bind:isJs={isJs} {jsCode} {goCode} title="Message" {id} showRun=true>
|
||||
<div class="browser-form">
|
||||
<form data-wails-no-drag class="mw-full">
|
||||
<div class="form-row row-eq-spacing-sm">
|
||||
<div class="form-group">
|
||||
<div>Dialog Type</div>
|
||||
{#each dialogTypes as option}
|
||||
<div class="custom-radio">
|
||||
<input type="radio" name="dialogType" bind:group="{dialogTypeSelected}" id="{id}-{option}" value="{option}">
|
||||
<label for="{id}-{option}">{option}</label>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row row-eq-spacing-sm">
|
||||
<div class="col-sm">
|
||||
<label for="{id}-Title">Title</label>
|
||||
<input type="text" class="form-control" id="{id}-Title" bind:value="{options.Title}">
|
||||
<div class="form-text"> The title for the dialog </div>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<label for="{id}-Message">Message</label>
|
||||
<input type="text" class="form-control" id="{id}-Message" bind:value="{options.Message}">
|
||||
<div class="form-text"> The dialog message </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row row-eq-spacing-sm">
|
||||
<div class="col-sm">
|
||||
<label for="{id}-Button1">Button 1</label>
|
||||
<input type="text" class="form-control" id="{id}-Button1" bind:value="{buttonInputs[0]}">
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<label for="{id}-Button2">Button 2</label>
|
||||
<input type="text" class="form-control" id="{id}-Button2" bind:value="{buttonInputs[1]}">
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<label for="{id}-Button3">Button 3</label>
|
||||
<input type="text" class="form-control" id="{id}-Button3" bind:value="{buttonInputs[2]}">
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<label for="{id}-Button4">Button 4</label>
|
||||
<input type="text" class="form-control" id="{id}-Button4" bind:value="{buttonInputs[3]}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row row-eq-spacing-sm">
|
||||
<div class="col-sm">
|
||||
<label for="{id}-DefaultButton">Default Button</label>
|
||||
<input type="text" class="form-control" id="{id}-DefaultButton" bind:value="{options.DefaultButton}">
|
||||
<div class="form-text"> The button that is the default option</div>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<label for="{id}-CancelButton">Cancel Button</label>
|
||||
<input type="text" class="form-control" id="{id}-CancelButton" bind:value="{options.CancelButton}">
|
||||
<div class="form-text"> The button that is the cancel option </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row row-eq-spacing-sm">
|
||||
<div class="col-sm">
|
||||
<label for="{id}-Icon">Icon</label>
|
||||
<input type="text" class="form-control" id="{id}-Icon" bind:value="{options.Icon}">
|
||||
<div class="form-text"> The icon to use in the dialog </div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input class="btn btn-primary" type="button" on:click="{processMessage}" value="Show message dialog using {lang} runtime">
|
||||
|
||||
<CodeSnippet bind:isJs={isJs} jsCode={testcodeJs} goCode={testcodeGo}/>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</CodeBlock>
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/wailsapp/wails/v2"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
)
|
||||
|
||||
type Notepad struct {
|
||||
runtime *wails.Runtime
|
||||
}
|
||||
|
||||
func (n *Notepad) WailsInit(runtime *wails.Runtime) error {
|
||||
n.runtime = runtime
|
||||
return nil
|
||||
}
|
||||
|
||||
// SaveNotes attempts to save the given notes to disk.
|
||||
// Returns false if the user cancelled the save, true on
|
||||
// successful save.
|
||||
func (n *Notepad) SaveNotes(notes string) (bool, error) {
|
||||
|
||||
selectedFile := n.runtime.Dialog.Save(&options.SaveDialog{
|
||||
DefaultFilename: "notes.md",
|
||||
Filters: "*.md",
|
||||
})
|
||||
|
||||
// Check if the user pressed cancel
|
||||
if selectedFile == "" {
|
||||
// Cancelled
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Save notes
|
||||
err := ioutil.WriteFile(selectedFile, []byte(notes), 0700)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Dialog } from '@wails/runtime';
|
||||
|
||||
let notes = "";
|
||||
|
||||
function saveNotes() {
|
||||
// Prompt the user to select a single file
|
||||
let filename = Dialog.Save({
|
||||
"DefaultFilename": "notes.md",
|
||||
"Filters": "*.md",
|
||||
});
|
||||
|
||||
// Do something with the file
|
||||
backend.main.SaveNotes(filename, notes).then( (result) => {
|
||||
if ( !result ) {
|
||||
// Cancelled
|
||||
return
|
||||
}
|
||||
showMessage('Notes saved!');
|
||||
}).catch( (err) => {
|
||||
// Show an alert
|
||||
showAlert(err);
|
||||
})
|
||||
}
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
<input class="btn btn-primary" type="button" on:click="{sendLogMessage}" value="Log using {lang} runtime">
|
||||
|
||||
<CodeSnippet bind:isJs={isJs} jsCode={testcodeJs} goCode={testcodeGo}></CodeSnippet>
|
||||
<CodeSnippet bind:isJs={isJs} jsCode={testcodeJs} goCode={testcodeGo}/>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
@@ -38,9 +38,9 @@ I am a Print message
|
||||
Custom loggers may be given to your Wails application. More details <Link href="https://wails.app">here</Link>.
|
||||
|
||||
<br/><br/>
|
||||
|
||||
<Log></Log>
|
||||
|
||||
<Log/>
|
||||
<br/>
|
||||
<SetLogLevel></SetLogLevel>
|
||||
<SetLogLevel/>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
let logLevelUpper = loglevelText.toUpperCase();
|
||||
let logLevelMethod = Log.Level[logLevelUpper];
|
||||
setLogLevelMethod(logLevelMethod);
|
||||
};
|
||||
}
|
||||
|
||||
$: lang = isJs ? 'Javascript' : 'Go';
|
||||
|
||||
let description = `You can set the log level using Log.SetLogLevel(). It accepts a log level (number) but there are consts available which may be used. See example code for more details.`;
|
||||
@@ -41,7 +42,7 @@
|
||||
{/each}
|
||||
</div>
|
||||
<input class="btn btn-primary" type="button" on:click="{setLogLevel}" value="SetLogLevel using {lang} runtime">
|
||||
<CodeSnippet bind:isJs={isJs} jsCode={testcodeJs} goCode={testcodeGo}></CodeSnippet>
|
||||
<CodeSnippet bind:isJs={isJs} jsCode={testcodeJs} goCode={testcodeGo}/>
|
||||
</form>
|
||||
</div>
|
||||
</CodeBlock>
|
||||
Reference in New Issue
Block a user