Skip to content

Commit c6488ff

Browse files
Refactor Menu class to enhance structure, improve option handling, and add command registration
1 parent 78ceb3a commit c6488ff

File tree

1 file changed

+86
-9
lines changed

1 file changed

+86
-9
lines changed

src/Widget/Menu.php

Lines changed: 86 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,90 @@
11
<?php
2+
23
namespace PhpGui\Widget;
3-
/**
4-
* Class Menu
5-
* Represents a menu widget in the GUI.
6-
*
7-
* @package PhpGui\Widget
8-
*/
9-
class Menu extends AbstractWidget {
10-
protected function create(): void {
11-
$this->tcl->evalTcl("menu .{$this->parentId}.{$this->id} -tearoff 0");
4+
5+
use PhpGui\ProcessTCL;
6+
7+
class Menu extends AbstractWidget
8+
{
9+
private $type;
10+
private $menuItems = [];
11+
12+
public function __construct(string $parentId, array $options = [])
13+
{
14+
$this->type = $options['type'] ?? 'normal';
15+
parent::__construct($parentId, $options);
16+
$this->create();
17+
}
18+
19+
protected function create(): void
20+
{
21+
$extra = $this->getOptionString();
22+
23+
if ($this->type === 'main') {
24+
// For main menu, attach directly to window
25+
$this->tcl->evalTcl("menu .{$this->id} -tearoff 0 {$extra}");
26+
$this->tcl->evalTcl(".{$this->parentId} configure -menu .{$this->id}");
27+
} else {
28+
// For submenus, use parent's path
29+
$this->tcl->evalTcl("menu .{$this->id} -tearoff 0 {$extra}");
30+
}
31+
}
32+
33+
protected function getOptionString(): string
34+
{
35+
$opts = "";
36+
foreach ($this->options as $key => $value) {
37+
if (in_array($key, ['type'])) continue;
38+
$opts .= " -$key \"$value\"";
39+
}
40+
return $opts;
41+
}
42+
43+
public function addCommand(string $label, callable $callback = null, array $options = []): void
44+
{
45+
$cmdOpts = ["-label \"{$label}\""];
46+
47+
if ($callback) {
48+
$callbackId = $this->id . '_cmd_' . count($this->menuItems);
49+
ProcessTCL::getInstance()->registerCallback($callbackId, $callback);
50+
$cmdOpts[] = "-command {php::executeCallback $callbackId}";
51+
}
52+
53+
foreach ($options as $key => $value) {
54+
$cmdOpts[] = "-$key \"{$value}\"";
55+
}
56+
57+
$this->tcl->evalTcl(".{$this->id} add command " . implode(' ', $cmdOpts));
58+
$this->menuItems[] = ['type' => 'command', 'label' => $label];
59+
}
60+
61+
public function addSubmenu(string $label, array $options = []): Menu
62+
{
63+
$submenuId = $this->id . '_sub_' . count($this->menuItems);
64+
$submenu = new Menu($this->id, ['type' => 'submenu'] + $options);
65+
66+
$this->tcl->evalTcl(".{$this->id} add cascade -label \"{$label}\" -menu .{$submenu->getId()}");
67+
68+
$this->menuItems[] = ['type' => 'submenu', 'label' => $label, 'menu' => $submenu];
69+
return $submenu;
70+
}
71+
72+
public function addSeparator(): void
73+
{
74+
$this->tcl->evalTcl(".{$this->id} add separator");
75+
$this->menuItems[] = ['type' => 'separator'];
76+
}
77+
78+
protected function formatOptions(array $options): string
79+
{
80+
$result = [];
81+
foreach ($options as $key => $value) {
82+
if ($key === 'command') {
83+
$result[] = "-$key {$value}";
84+
} else {
85+
$result[] = "-$key \"$value\"";
86+
}
87+
}
88+
return implode(' ', $result);
1289
}
1390
}

0 commit comments

Comments
 (0)