Skip to content

Commit b4e61ab

Browse files
committed
Add full (probably) macos support
1 parent 6acf14c commit b4e61ab

File tree

4 files changed

+58
-33
lines changed

4 files changed

+58
-33
lines changed

src/Api/MessageBox/Driver/MacOS/LibObjectC.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,17 @@ public function __construct()
2727
}
2828

2929
/**
30+
* @param non-empty-string $return
3031
* @param non-empty-string ...$types
3132
* @return callable(CData,CData,...):mixed
3233
*/
33-
public function getMessageSend(string ...$types): callable
34+
public function getMessageSend(string $return, string ...$types): callable
3435
{
35-
$signature = \sprintf('id(*)(id, SEL, %s)', \implode(',', $types));
36+
$suffix = $types === [] ? '...' : \implode(',', $types);
3637

37-
return $this->cast($signature, $this->ffi->objc_msgSend);
38+
$signature = \sprintf('%s(*)(id, SEL, %s)', $return, $suffix);
39+
40+
return $this->ffi->cast($signature, $this->ffi->objc_msgSend);
3841
}
3942

4043
/**

src/Api/MessageBox/Driver/MacOSMessageBoxExtension.php

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,46 +5,48 @@
55
namespace Boson\Api\MessageBox\Driver;
66

77
use Boson\Api\MessageBox\Driver\MacOS\LibObjectC;
8+
use Boson\Api\MessageBox\MessageBoxButton;
89
use Boson\Api\MessageBox\MessageBoxCreateInfo;
910
use Boson\Api\MessageBox\MessageBoxExtensionInterface;
1011
use Boson\Api\MessageBox\MessageBoxIcon;
1112
use FFI\CData;
12-
use React\Promise\PromiseInterface;
13-
14-
use function React\Promise\resolve;
1513

1614
final readonly class MacOSMessageBoxExtension implements MessageBoxExtensionInterface
1715
{
1816
private CData $msgSendId;
19-
private CData $msgSendString;
17+
private CData $msgSendStringGetId;
2018
private CData $msgSendLong;
19+
private CData $msgSendVoidGetId;
20+
private CData $msgSendVoidGetLong;
2121

2222
public function __construct(
2323
private LibObjectC $libobjc = new LibObjectC(),
2424
) {
25-
$this->msgSendId = $libobjc->getMessageSend('id');
26-
$this->msgSendString = $libobjc->getMessageSend('const char*');
27-
$this->msgSendLong = $libobjc->getMessageSend('long');
25+
$this->msgSendStringGetId = $libobjc->getMessageSend('id', 'const char*');
26+
$this->msgSendId = $libobjc->getMessageSend('id', 'id');
27+
$this->msgSendLong = $libobjc->getMessageSend('id', 'long');
28+
$this->msgSendVoidGetId = $libobjc->getMessageSend('id');
29+
$this->msgSendVoidGetLong = $libobjc->getMessageSend('long');
2830
}
2931

30-
public function create(MessageBoxCreateInfo $info): PromiseInterface
32+
public function create(MessageBoxCreateInfo $info): ?MessageBoxButton
3133
{
3234
// NSString *titleStr = [NSString stringWithUTF8String:title]
33-
$titleStr = ($this->msgSendString)(
35+
$titleStr = ($this->msgSendStringGetId)(
3436
$this->libobjc->objc_getClass('NSString'),
3537
$this->libobjc->sel_registerName('stringWithUTF8String:'),
3638
$info->title . "\0",
3739
);
3840

3941
// NSString *textStr = [NSString stringWithUTF8String:text]
40-
$textStr = ($this->msgSendString)(
42+
$textStr = ($this->msgSendStringGetId)(
4143
$this->libobjc->objc_getClass('NSString'),
4244
$this->libobjc->sel_registerName('stringWithUTF8String:'),
4345
$info->text . "\0",
4446
);
4547

4648
// NSAlert *alert = [NSAlert new]
47-
$alert = $this->libobjc->objc_msgSend(
49+
$alert = ($this->msgSendVoidGetId)(
4850
$this->libobjc->objc_getClass('NSAlert'),
4951
$this->libobjc->sel_registerName('new'),
5052
);
@@ -65,24 +67,52 @@ public function create(MessageBoxCreateInfo $info): PromiseInterface
6567

6668
// Set alert style based on icon
6769
if ($info->icon !== null) {
68-
// [alert setAlertStyle:alertStyle];
6970
($this->msgSendLong)(
7071
$alert,
7172
$this->libobjc->sel_registerName('setAlertStyle:'),
7273
match ($info->icon) {
73-
MessageBoxIcon::Error => 0, // NSAlertStyleCritical
74-
MessageBoxIcon::Warning => 1, // NSAlertStyleWarning
75-
MessageBoxIcon::Info => 2, // NSAlertStyleInformational
74+
MessageBoxIcon::Error => 2, // NSAlertStyleCritical
75+
MessageBoxIcon::Warning => 0, // NSAlertStyleWarning
76+
MessageBoxIcon::Info => 1, // NSAlertStyleInformational
7677
},
7778
);
7879
}
7980

81+
// Add buttons based on cancel flag
82+
if ($info->cancel) {
83+
// [alert addButtonWithTitle:@"Cancel"];
84+
($this->msgSendId)(
85+
$alert,
86+
$this->libobjc->sel_registerName('addButtonWithTitle:'),
87+
($this->msgSendStringGetId)(
88+
$this->libobjc->objc_getClass('NSString'),
89+
$this->libobjc->sel_registerName('stringWithUTF8String:'),
90+
"Cancel\0",
91+
),
92+
);
93+
}
94+
95+
// [alert addButtonWithTitle:@"OK"];
96+
($this->msgSendId)(
97+
$alert,
98+
$this->libobjc->sel_registerName('addButtonWithTitle:'),
99+
($this->msgSendStringGetId)(
100+
$this->libobjc->objc_getClass('NSString'),
101+
$this->libobjc->sel_registerName('stringWithUTF8String:'),
102+
"OK\0",
103+
),
104+
);
105+
80106
// [alert runModal];
81-
$this->libobjc->objc_msgSend(
107+
$result = ($this->msgSendVoidGetLong)(
82108
$alert,
83109
$this->libobjc->sel_registerName('runModal'),
84110
);
85111

86-
return resolve(null);
112+
return match ($result) {
113+
1000 => $info->cancel ? MessageBoxButton::Cancel : MessageBoxButton::Ok,
114+
1001 => MessageBoxButton::Ok,
115+
default => $info->cancel,
116+
};
87117
}
88118
}

src/Api/MessageBox/Driver/WindowsMessageBoxExtension.php

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@
1010
use Boson\Api\MessageBox\MessageBoxExtensionInterface;
1111
use Boson\Api\MessageBox\MessageBoxIcon;
1212
use FFI\CData;
13-
use React\Promise\PromiseInterface;
14-
15-
use function React\Promise\resolve;
1613

1714
final readonly class WindowsMessageBoxExtension implements MessageBoxExtensionInterface
1815
{
@@ -37,7 +34,7 @@ private function string(string $text): CData
3734
return $result;
3835
}
3936

40-
public function create(MessageBoxCreateInfo $info): PromiseInterface
37+
public function create(MessageBoxCreateInfo $info): ?MessageBoxButton
4138
{
4239
$title = $this->string($info->title);
4340
$text = $this->string($info->text);
@@ -59,9 +56,9 @@ public function create(MessageBoxCreateInfo $info): PromiseInterface
5956
\FFI::free($text);
6057

6158
return match ($result) {
62-
User32::IDOK => resolve(MessageBoxButton::Ok),
63-
User32::IDCANCEL => resolve(MessageBoxButton::Cancel),
64-
default => resolve(null),
59+
User32::IDOK => MessageBoxButton::Ok,
60+
User32::IDCANCEL => MessageBoxButton::Cancel,
61+
default => null,
6562
};
6663
}
6764
}

src/Api/MessageBox/MessageBoxExtensionInterface.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,7 @@
44

55
namespace Boson\Api\MessageBox;
66

7-
use React\Promise\PromiseInterface;
8-
97
interface MessageBoxExtensionInterface
108
{
11-
/**
12-
* @return PromiseInterface<MessageBoxButton|null>
13-
*/
14-
public function create(MessageBoxCreateInfo $info): PromiseInterface;
9+
public function create(MessageBoxCreateInfo $info): ?MessageBoxButton;
1510
}

0 commit comments

Comments
 (0)