Phasor 3.3.0
Stack VM based Programming Language
Loading...
Searching...
No Matches
userconsent.h
Go to the documentation of this file.
1#pragma once
2#include <print>
3#include <string>
4#include <format>
5#include <unordered_map>
6#include <cstdlib>
7#include <enum_array>
8
9#ifdef _WIN32
10#include <Windows.h>
11#include <io.h>
12#else
13#include <unistd.h>
14#endif
15
16#ifdef __APPLE__
17#include <CoreFoundation/CoreFoundation.h>
18#endif
19
20// If you are here, you probably have one question, why?
21// I cannot consistantly format grammar, this forces me (and potential contributors) to use "static time grammar"
22// It reads *almost* like english so it works
23
33
35static constexpr enum_array<EConsentVolition, std::string_view, 6> AConsentVolition = {{
36 "might",
37 "would like to",
38 "wants to",
39 "needs to",
40 "has to",
41 "must"
42}};
43
55template<size_t N1, size_t N2, size_t N3>
56inline bool prompt_consent(const char (&subsystem)[N1], EConsentVolition volition, const char (&verb)[N2], const char (&noun)[N3], bool default_val = false)
57{
58 bool res = false;
59 std::string prompt = std::format("Phasor {} {} {} the {}. Is this okay?", subsystem, AConsentVolition[volition], verb, noun);
60#ifdef _WIN32
61 bool tty = _isatty(_fileno(stdin));
62#else
63 bool tty = isatty(fileno(stdin));
64#endif
65
66 if (!tty) {
67#ifdef _WIN32
68 if (MessageBoxA(NULL, prompt.c_str(), "Phasor Programming Language", MB_YESNO) == IDYES) return true;
69 else return false;
70#elif __APPLE__
71 CFStringRef cfTitle = CFStringCreateWithCString(NULL, "Phasor Programming Language", kCFStringEncodingUTF8);
72 CFStringRef cfMessage = CFStringCreateWithCString(NULL, prompt.c_str(), kCFStringEncodingUTF8);
73
74 CFOptionFlags responseFlags;
75 CFUserNotificationDisplayAlert(
76 0,
77 kCFUserNotificationNoteAlertLevel,
78 nullptr,
79 nullptr,
80 nullptr,
81 cfTitle,
82 cfMessage,
83 CFSTR("No"),
84 CFSTR("Yes"),
85 nullptr,
86 &responseFlags
87 );
88
89 CFRelease(cfTitle);
90 CFRelease(cfMessage);
91
92 return responseFlags == kCFUserNotificationAlternateResponse;
93#else
94 bool has_display = std::getenv("DISPLAY") || std::getenv("WAYLAND_DISPLAY");
95 if (!has_display) return false;
96
97 const std::array<std::string, 2> tools = {"zenity", "kdialog"};
98
99 for (const auto& tool : tools) {
100 std::string cmd;
101 if (tool == "zenity")
102 cmd = std::format("zenity --question --text='{}' 2>/dev/null", prompt);
103 else
104 cmd = std::format("kdialog --yesno '{}' 2>/dev/null", prompt);
105
106 int ret = std::system(cmd.c_str());
107 if (ret == 127) continue;
108
109 if (WIFEXITED(ret) && WEXITSTATUS(ret) == 0)
110 return true;
111 }
112 return false;
113#endif
114 }
115 std::println("");
116 while (true) {
117 std::string line;
118 std::print("{} {} ", prompt, default_val ? "[Y/n]" : "[y/N]");
119 std::getline(std::cin, line);
120 if (line.empty()) return default_val;
121 else if (line[0] == 'y' || line[0] == 'Y') res = true;
122 else if (line[0] == 'n' || line[0] == 'N') res = false;
123 else continue;
124 break;
125 }
126 return res;
127}
static constexpr enum_array< EConsentVolition, std::string_view, 6 > AConsentVolition
Array for the EConsentVolition enum.
Definition userconsent.h:35
bool prompt_consent(const char(&subsystem)[N1], EConsentVolition volition, const char(&verb)[N2], const char(&noun)[N3], bool default_val=false)
Prompt the user for consent.
Definition userconsent.h:56
EConsentVolition
Priority level for the prompt_consent permission request.
Definition userconsent.h:25
@ Must
SHOULD ONLY BE USED IF IT WILL END THE PROGRAM ON FALSE.
Definition userconsent.h:31