Skip to content

Commit 87bc716

Browse files
authored
Merge pull request #9 from skoro/widget/treeview
TreeView ttk widget
2 parents bcd281a + fa190bb commit 87bc716

File tree

12 files changed

+633
-54
lines changed

12 files changed

+633
-54
lines changed

composer.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

demos/treeview.php

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
use Tkui\Widgets\Container;
4+
use Tkui\Widgets\Scrollbar;
5+
use Tkui\Widgets\TreeView\Column;
6+
use Tkui\Widgets\TreeView\Item;
7+
use Tkui\Widgets\TreeView\TreeView;
8+
9+
require_once dirname(__FILE__) . '/DemoAppWindow.php';
10+
11+
$demo = new class extends DemoAppWindow
12+
{
13+
private array $data = [
14+
['Argentina', 'Buenos Aires', 'ARS'],
15+
['Australia', 'Canberra', 'AUD'],
16+
['Brazil', 'Brazilia', 'BRL'],
17+
['Canada', 'Ottawa', 'CAD'],
18+
['China', 'Beijing', 'CNY'],
19+
['France', 'Paris', 'EUR'],
20+
['Germany', 'Berlin', 'EUR'],
21+
['India', 'New Delhi', 'INR'],
22+
['Italy', 'Rome', 'EUR'],
23+
['Japan', 'Tokyo', 'JPY'],
24+
['Mexico', 'Mexico City', 'MXN'],
25+
['South Africa', 'Pretoria', 'ZAR'],
26+
['United Kingdom', 'London', 'GBP'],
27+
['United States', 'Washington, D.C.', 'USD'],
28+
];
29+
30+
private TreeView $tv;
31+
32+
public function __construct()
33+
{
34+
parent::__construct('TreeView demo');
35+
$this->buildUI();
36+
$this->addValues();
37+
38+
$this->tv->onSelect([$this, 'onSelectItem']);
39+
}
40+
41+
private function buildUI(): void
42+
{
43+
$this->tv = $this->buildTreeView($this);
44+
}
45+
46+
private function buildTreeView(Container $parent, array $options = []): TreeView
47+
{
48+
$columns = $this->createColumns();
49+
50+
$tv = new TreeView($parent, $columns, $options);
51+
$tv->xScrollCommand = new Scrollbar($parent, ['orient' => Scrollbar::ORIENT_HORIZONTAL]);
52+
$tv->yScrollCommand = new Scrollbar($parent, ['orient' => Scrollbar::ORIENT_VERTICAL]);
53+
54+
$parent->grid($tv, ['sticky' => 'news', 'row' => 0, 'column' => 0])
55+
->rowConfigure($parent, 0, ['weight' => 1])
56+
->columnConfigure($parent, 0, ['weight' => 1]);
57+
$parent->grid($tv->yScrollCommand, ['sticky' => 'nsew', 'row' => 0, 'column' => 1]);
58+
$parent->grid($tv->xScrollCommand, ['sticky' => 'nsew', 'row' => 1, 'column' => 0]);
59+
60+
return $tv;
61+
}
62+
63+
/**
64+
* @return array<Column>
65+
*/
66+
private function createColumns(): array
67+
{
68+
return [
69+
Column::create('country', 'Country'),
70+
Column::create('capital', 'Capital'),
71+
Column::create('currency', 'Currency'),
72+
];
73+
}
74+
75+
private function addValues(): void
76+
{
77+
foreach ($this->data as $values) {
78+
$this->tv->add(new Item($values));
79+
}
80+
}
81+
82+
public function onSelectItem(array $selected): void
83+
{
84+
foreach ($selected as $itemId) {
85+
echo "$itemId" . PHP_EOL;
86+
}
87+
}
88+
};
89+
90+
$demo->run();
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tkui\Widgets\Common;
6+
7+
use InvalidArgumentException;
8+
use Tkui\Widgets\Scrollbar;
9+
10+
trait HasScrollBars
11+
{
12+
private Scrollbar $xScroll;
13+
private Scrollbar $yScroll;
14+
15+
public function __get($name)
16+
{
17+
switch ($name) {
18+
case 'xScrollCommand':
19+
return $this->xScroll;
20+
case 'yScrollCommand':
21+
return $this->yScroll;
22+
}
23+
return parent::__get($name);
24+
}
25+
26+
public function __set($name, $value)
27+
{
28+
switch ($name) {
29+
case 'xScrollCommand':
30+
case 'yScrollCommand':
31+
if (!($value instanceof Scrollbar)) {
32+
throw new InvalidArgumentException("$name must be an instance of " . Scrollbar::class);
33+
}
34+
switch ($name) {
35+
case 'xScrollCommand':
36+
$this->xScroll = $value;
37+
break;
38+
case 'yScrollCommand':
39+
$this->yScroll = $value;
40+
break;
41+
}
42+
parent::__set($name, $value->path() . ' set');
43+
$value->command = $this;
44+
break;
45+
46+
default:
47+
parent::__set($name, $value);
48+
}
49+
}
50+
}

src/Widgets/Common/Scrollable.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tkui\Widgets\Common;
6+
7+
use Tkui\Widgets\Widget;
8+
9+
interface Scrollable extends Widget
10+
{
11+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tkui\Widgets;
6+
7+
use Tkui\Widgets\Common\HasScrollBars;
8+
use Tkui\Widgets\Common\Scrollable;
9+
10+
abstract class ScrollableTtkWidget extends TtkWidget implements Scrollable
11+
{
12+
use HasScrollBars;
13+
}

src/Widgets/ScrollableWidget.php

Lines changed: 5 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,52 +2,10 @@
22

33
namespace Tkui\Widgets;
44

5-
use InvalidArgumentException;
5+
use Tkui\Widgets\Common\HasScrollBars;
6+
use Tkui\Widgets\Common\Scrollable;
67

7-
abstract class ScrollableWidget extends TkWidget
8+
abstract class ScrollableWidget extends TkWidget implements Scrollable
89
{
9-
private Scrollbar $xScroll;
10-
private Scrollbar $yScroll;
11-
12-
/**
13-
* @inheritdoc
14-
*/
15-
public function __get($name)
16-
{
17-
switch ($name) {
18-
case 'xScrollCommand':
19-
return $this->xScroll;
20-
case 'yScrollCommand':
21-
return $this->yScroll;
22-
}
23-
return parent::__get($name);
24-
}
25-
26-
/**
27-
* @inheritdoc
28-
*/
29-
public function __set($name, $value)
30-
{
31-
switch ($name) {
32-
case 'xScrollCommand':
33-
case 'yScrollCommand':
34-
if (!($value instanceof Scrollbar)) {
35-
throw new InvalidArgumentException("$name must be an instance of " . Scrollbar::class);
36-
}
37-
switch ($name) {
38-
case 'xScrollCommand':
39-
$this->xScroll = $value;
40-
break;
41-
case 'yScrollCommand':
42-
$this->yScroll = $value;
43-
break;
44-
}
45-
parent::__set($name, $value->path() . ' set');
46-
$value->command = $this;
47-
break;
48-
49-
default:
50-
parent::__set($name, $value);
51-
}
52-
}
53-
}
10+
use HasScrollBars;
11+
}

src/Widgets/Scrollbar.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use LogicException;
66
use Tkui\Options;
7+
use Tkui\Widgets\Common\Scrollable;
78
use Tkui\Widgets\Consts\Orient;
89

910
/**
@@ -35,7 +36,7 @@ public function initWidgetOptions(): Options
3536
*/
3637
public function __set(string $name, $value)
3738
{
38-
if ($name === 'command' && $value instanceof ScrollableWidget) {
39+
if ($name === 'command' && $value instanceof Scrollable) {
3940
$value = $value->path() . ' ' . $this->getOrientToView();
4041
}
4142
parent::__set($name, $value);

src/Widgets/TreeView/Column.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tkui\Widgets\TreeView;
6+
7+
use Tkui\Options;
8+
9+
/**
10+
* @property string $id
11+
* @property string $anchor
12+
* @property int $minWidth
13+
* @property bool $stretch
14+
* @property int $width
15+
*/
16+
class Column
17+
{
18+
private Options $options;
19+
private Header $header;
20+
21+
final public function __construct(string $id, Header $header, array $options = [])
22+
{
23+
$options['id'] = $id;
24+
$this->header = $header;
25+
$this->options = $this->createOptions()->mergeAsArray($options);
26+
}
27+
28+
protected function createOptions(): Options
29+
{
30+
return new Options([
31+
'id' => null,
32+
'anchor' => null,
33+
'minWidth' => null,
34+
'stretch' => null,
35+
'width' => null,
36+
]);
37+
}
38+
39+
public function options(): Options
40+
{
41+
return $this->options;
42+
}
43+
44+
/**
45+
* @param string $name
46+
* @return mixed
47+
*/
48+
public function __get($name)
49+
{
50+
return $this->options->$name;
51+
}
52+
53+
/**
54+
* @param string $name
55+
* @param mixed $value
56+
*/
57+
public function __set($name, $value)
58+
{
59+
$this->options->$name = $value;
60+
}
61+
62+
public function header(): Header
63+
{
64+
return $this->header;
65+
}
66+
67+
public static function create(string $id, string $header): static
68+
{
69+
return new static($id, new Header($header));
70+
}
71+
}

0 commit comments

Comments
 (0)