Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: customize button texts of message dialog #4383

Merged
merged 8 commits into from
Dec 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[env]
__TAURI_WORKSPACE__ = "true"
5 changes: 5 additions & 0 deletions .changes/custom-buttons-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"api": minor
---

Allow setting the text of the dialog buttons.
5 changes: 5 additions & 0 deletions .changes/custom-buttons.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri": minor
---

Added `OkWithLabel` and `OkCancelWithLabels` variants to the `api::dialog::MessageDialogButtons` enum to set the text of the dialog buttons.
2 changes: 1 addition & 1 deletion core/tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ ico = { version = "0.2.0", optional = true }
encoding_rs = "0.8.31"

[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
rfd = { version = "0.10", optional = true }
rfd = { version = "0.10", optional = true, features=["gtk3", "common-controls-v6"] }
notify-rust = { version = "4.5", default-features = false, features = [ "d" ], optional = true }

[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
Expand Down
14 changes: 14 additions & 0 deletions core/tauri/Windows Manifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
29 changes: 29 additions & 0 deletions core/tauri/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,18 @@ fn main() {
CHECKED_FEATURES.get().unwrap().lock().unwrap().join(","),
)
.expect("failed to write checked_features file");

// workaround needed to preven `STATUS_ENTRYPOINT_NOT_FOUND` error
// see https://github.com/tauri-apps/tauri/pull/4383#issuecomment-1212221864
let target_os = std::env::var("CARGO_CFG_TARGET_OS");
let target_env = std::env::var("CARGO_CFG_TARGET_ENV");
let is_tauri_workspace = std::env::var("__TAURI_WORKSPACE__").map_or(false, |v| v == "true");
if is_tauri_workspace
&& Ok("windows") == target_os.as_deref()
&& Ok("msvc") == target_env.as_deref()
{
add_manifest();
}
}

// create aliases for the given module with its apis.
Expand Down Expand Up @@ -170,3 +182,20 @@ fn alias_module(module: &str, apis: &[&str], api_all: bool) {

alias(&format!("{}_any", AsSnakeCase(module)), any);
}

fn add_manifest() {
static WINDOWS_MANIFEST_FILE: &str = "Windows Manifest.xml";

let mut manifest = std::env::current_dir().unwrap();
manifest.push(WINDOWS_MANIFEST_FILE);

println!("cargo:rerun-if-changed={}", WINDOWS_MANIFEST_FILE);
// Embed the Windows application manifest file.
println!("cargo:rustc-link-arg=/MANIFEST:EMBED");
println!(
"cargo:rustc-link-arg=/MANIFESTINPUT:{}",
manifest.to_str().unwrap()
);
// Turn linker warnings into errors.
println!("cargo:rustc-link-arg=/WX");
}
8 changes: 4 additions & 4 deletions core/tauri/scripts/bundle.global.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions core/tauri/scripts/bundle.js

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion core/tauri/src/api/dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,14 +171,18 @@ macro_rules! message_dialog_builder {

/// Options for action buttons on message dialogs.
#[non_exhaustive]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum MessageDialogButtons {
/// Ok button.
Ok,
/// Ok and Cancel buttons.
OkCancel,
/// Yes and No buttons.
YesNo,
/// OK button with customized text.
OkWithLabel(String),
/// Ok and Cancel buttons with customized text.
OkCancelWithLabels(String, String),
}

impl From<MessageDialogButtons> for rfd::MessageButtons {
Expand All @@ -187,6 +191,10 @@ impl From<MessageDialogButtons> for rfd::MessageButtons {
MessageDialogButtons::Ok => Self::Ok,
MessageDialogButtons::OkCancel => Self::OkCancel,
MessageDialogButtons::YesNo => Self::YesNo,
MessageDialogButtons::OkWithLabel(ok_text) => Self::OkCustom(ok_text),
MessageDialogButtons::OkCancelWithLabels(ok_text, cancel_text) => {
Self::OkCancelCustom(ok_text, cancel_text)
}
}
}
}
Expand Down
35 changes: 30 additions & 5 deletions core/tauri/src/endpoints/dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,21 @@ use tauri_macros::{command_enum, module_command_handler, CommandModule};
use std::path::PathBuf;

macro_rules! message_dialog {
($fn_name: ident, $allowlist: ident, $buttons: expr) => {
($fn_name: ident, $allowlist: ident, $button_labels_type: ty, $buttons: expr) => {
#[module_command_handler($allowlist)]
fn $fn_name<R: Runtime>(
context: InvokeContext<R>,
title: Option<String>,
message: String,
level: Option<MessageDialogType>,
button_labels: $button_labels_type,
) -> super::Result<bool> {
let determine_button = $buttons;
let mut builder = crate::api::dialog::blocking::MessageDialogBuilder::new(
title.unwrap_or_else(|| context.window.app_handle.package_info().name.clone()),
message,
)
.buttons($buttons);
.buttons(determine_button(button_labels));
#[cfg(any(windows, target_os = "macos"))]
{
builder = builder.parent(&context.window);
Expand Down Expand Up @@ -139,20 +141,26 @@ pub enum Cmd {
message: String,
#[serde(rename = "type")]
level: Option<MessageDialogType>,
#[serde(rename = "buttonLabel")]
button_label: Option<String>,
},
#[cmd(dialog_ask, "dialog > ask")]
AskDialog {
title: Option<String>,
message: String,
#[serde(rename = "type")]
level: Option<MessageDialogType>,
#[serde(rename = "buttonLabels")]
button_label: Option<(String, String)>,
},
#[cmd(dialog_confirm, "dialog > confirm")]
ConfirmDialog {
title: Option<String>,
message: String,
#[serde(rename = "type")]
level: Option<MessageDialogType>,
#[serde(rename = "buttonLabels")]
button_labels: Option<(String, String)>,
},
}

Expand Down Expand Up @@ -255,19 +263,36 @@ impl Cmd {
message_dialog!(
message_dialog,
dialog_message,
crate::api::dialog::MessageDialogButtons::Ok
Option<String>,
|label: Option<String>| {
label
.map(crate::api::dialog::MessageDialogButtons::OkWithLabel)
.unwrap_or(crate::api::dialog::MessageDialogButtons::Ok)
}
);

message_dialog!(
ask_dialog,
dialog_ask,
crate::api::dialog::MessageDialogButtons::YesNo
Option<(String, String)>,
|labels: Option<(String, String)>| {
labels
.map(|(yes, no)| crate::api::dialog::MessageDialogButtons::OkCancelWithLabels(yes, no))
.unwrap_or(crate::api::dialog::MessageDialogButtons::YesNo)
}
);

message_dialog!(
confirm_dialog,
dialog_confirm,
crate::api::dialog::MessageDialogButtons::OkCancel
Option<(String, String)>,
|labels: Option<(String, String)>| {
labels
.map(|(ok, cancel)| {
crate::api::dialog::MessageDialogButtons::OkCancelWithLabels(ok, cancel)
})
.unwrap_or(crate::api::dialog::MessageDialogButtons::OkCancel)
}
);
}

Expand Down
32 changes: 16 additions & 16 deletions examples/api/dist/assets/index.js

Large diffs are not rendered by default.

24 changes: 22 additions & 2 deletions examples/api/src-tauri/src/desktop.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use std::sync::atomic::{AtomicBool, Ordering};
use tauri::{
api::dialog::ask, CustomMenuItem, GlobalShortcutManager, Manager, RunEvent, SystemTray,
SystemTrayEvent, SystemTrayMenu, WindowBuilder, WindowEvent, WindowUrl,
api::{
dialog::{ask, MessageDialogBuilder, MessageDialogButtons},
shell,
},
CustomMenuItem, GlobalShortcutManager, Manager, RunEvent, SystemTray, SystemTrayEvent,
SystemTrayMenu, WindowBuilder, WindowEvent, WindowUrl,
};

pub fn main() {
Expand Down Expand Up @@ -71,13 +75,15 @@ fn create_tray(app: &tauri::App) -> tauri::Result<()> {

tray_menu1 = tray_menu1
.add_item(CustomMenuItem::new("switch_menu", "Switch Menu"))
.add_item(CustomMenuItem::new("about", "About"))
.add_item(CustomMenuItem::new("exit_app", "Quit"))
.add_item(CustomMenuItem::new("destroy", "Destroy"));

let tray_menu2 = SystemTrayMenu::new()
.add_item(CustomMenuItem::new("toggle", "Toggle"))
.add_item(CustomMenuItem::new("new", "New window"))
.add_item(CustomMenuItem::new("switch_menu", "Switch Menu"))
.add_item(CustomMenuItem::new("about", "About"))
.add_item(CustomMenuItem::new("exit_app", "Quit"))
.add_item(CustomMenuItem::new("destroy", "Destroy"));
let is_menu1 = AtomicBool::new(true);
Expand Down Expand Up @@ -161,6 +167,20 @@ fn create_tray(app: &tauri::App) -> tauri::Result<()> {
.unwrap();
is_menu1.store(!flag, Ordering::Relaxed);
}
"about" => {
let window = handle.get_window("main").unwrap();
MessageDialogBuilder::new("About app", "Tauri demo app")
.parent(&window)
.buttons(MessageDialogButtons::OkCancelCustom(
"Homepage".into(),
"know it".into(),
))
.show(move |ok| {
if ok {
shell::open(&window.shell_scope(), "https://tauri.app/", None).unwrap();
}
});
}
_ => {}
}
}
Expand Down
35 changes: 29 additions & 6 deletions tooling/api/src/dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,19 @@ interface MessageDialogOptions {
title?: string
/** The type of the dialog. Defaults to `info`. */
type?: 'info' | 'warning' | 'error'
/** The label of the confirm button. */
okLabel?: string
}

interface ConfirmDialogOptions {
/** The title of the dialog. Defaults to the app name. */
title?: string
/** The type of the dialog. Defaults to `info`. */
type?: 'info' | 'warning' | 'error'
/** The label of the confirm button. */
okLabel?: string
/** The label of the cancel button. */
cancelLabel?: string
}

/**
Expand Down Expand Up @@ -233,7 +246,8 @@ async function message(
cmd: 'messageDialog',
message: message.toString(),
title: opts?.title?.toString(),
type: opts?.type
type: opts?.type,
buttonLabel: opts?.okLabel?.toString()
}
})
}
Expand All @@ -256,7 +270,7 @@ async function message(
*/
async function ask(
message: string,
options?: string | MessageDialogOptions
options?: string | ConfirmDialogOptions
): Promise<boolean> {
const opts = typeof options === 'string' ? { title: options } : options
return invokeTauriCommand({
Expand All @@ -265,7 +279,11 @@ async function ask(
cmd: 'askDialog',
message: message.toString(),
title: opts?.title?.toString(),
type: opts?.type
type: opts?.type,
buttonLabels: [
opts?.okLabel?.toString() ?? 'Yes',
opts?.cancelLabel?.toString() ?? 'No'
]
}
})
}
Expand All @@ -288,7 +306,7 @@ async function ask(
*/
async function confirm(
message: string,
options?: string | MessageDialogOptions
options?: string | ConfirmDialogOptions
): Promise<boolean> {
const opts = typeof options === 'string' ? { title: options } : options
return invokeTauriCommand({
Expand All @@ -297,7 +315,11 @@ async function confirm(
cmd: 'confirmDialog',
message: message.toString(),
title: opts?.title?.toString(),
type: opts?.type
type: opts?.type,
buttonLabels: [
opts?.okLabel?.toString() ?? 'Ok',
opts?.cancelLabel?.toString() ?? 'Cancel'
]
}
})
}
Expand All @@ -306,7 +328,8 @@ export type {
DialogFilter,
OpenDialogOptions,
SaveDialogOptions,
MessageDialogOptions
MessageDialogOptions,
ConfirmDialogOptions
}

export { open, save, message, ask, confirm }