Browse Source

init multi-window implementation

PHP-GTK3
yggverse 4 months ago
parent
commit
847a0fb01d
  1. 18
      src/Abstract/Entity/Browser/Container/Tab/Page/Navbar/Button.php
  2. 18
      src/Abstract/Entity/Browser/Container/Tab/Page/Navbar/Entry.php
  3. 18
      src/Abstract/Entity/Browser/History/Container/Navbar/Button.php
  4. 18
      src/Abstract/Entity/Browser/History/Container/Navbar/Entry.php
  5. 20
      src/Abstract/Entity/HeaderBar.php
  6. 18
      src/Abstract/Entity/Window/Tab/Address/Navbar/Button.php
  7. 18
      src/Abstract/Entity/Window/Tab/Address/Navbar/Entry.php
  8. 18
      src/Abstract/Entity/Window/Tab/History/Navbar/Button.php
  9. 18
      src/Abstract/Entity/Window/Tab/History/Navbar/Entry.php
  10. 23
      src/Entity/Browser.php
  11. 47
      src/Entity/Browser/Container.php
  12. 97
      src/Entity/Browser/Container/Tab.php
  13. 89
      src/Entity/Browser/Container/Tab/Page.php
  14. 156
      src/Entity/Browser/Container/Tab/Page/Content.php
  15. 30
      src/Entity/Browser/Container/Tab/Page/Content/Data.php
  16. 73
      src/Entity/Browser/Container/Tab/Page/Navbar.php
  17. 12
      src/Entity/Browser/Container/Tab/Page/Navbar/Base.php
  18. 6
      src/Entity/Browser/Container/Tab/Page/Navbar/Go.php
  19. 28
      src/Entity/Browser/Container/Tab/Page/Navbar/History.php
  20. 15
      src/Entity/Browser/Container/Tab/Page/Navbar/History/Back.php
  21. 15
      src/Entity/Browser/Container/Tab/Page/Navbar/History/Forward.php
  22. 10
      src/Entity/Browser/Container/Tab/Page/Navbar/Request.php
  23. 16
      src/Entity/Browser/Container/Tab/Page/Statusbar.php
  24. 13
      src/Entity/Browser/Container/Tab/Page/Title.php
  25. 10
      src/Entity/Browser/Header.php
  26. 63
      src/Entity/Browser/History.php
  27. 59
      src/Entity/Browser/History/Container.php
  28. 67
      src/Entity/Browser/History/Container/Content.php
  29. 104
      src/Entity/Browser/History/Container/Navbar.php
  30. 33
      src/Entity/Browser/History/Container/Navbar/Delete.php
  31. 8
      src/Entity/Browser/History/Container/Navbar/Filter.php
  32. 28
      src/Entity/Browser/History/Container/Navbar/Open.php
  33. 20
      src/Entity/Browser/History/Container/Navbar/Search.php
  34. 10
      src/Entity/Browser/History/Header.php
  35. 109
      src/Entity/Window/Tab.php
  36. 45
      src/Entity/Window/Tab/Address/Content.php
  37. 54
      src/Entity/Window/Tab/Address/Content/Plain.php
  38. 74
      src/Entity/Window/Tab/History.php
  39. 99
      src/Entity/Window/Tab/History/Navbar.php
  40. 30
      src/Entity/Window/Tab/History/Navbar/Delete.php
  41. 31
      src/Entity/Window/Tab/History/Navbar/Open.php
  42. 28
      src/Entity/Window/Tab/History/Navbar/Search.php
  43. 46
      src/Entity/Window/Tab/History/Title.php
  44. 2
      src/Model/Database.php
  45. 15
      src/Yoda.php

18
src/Abstract/Entity/Browser/Container/Tab/Page/Navbar/Button.php

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Abstract\Entity\Browser\Container\Tab\Page\Navbar;
abstract class Button extends \Yggverse\Yoda\Abstract\Entity\Button
{
public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar $navbar;
public function __construct(
\Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar $navbar
) {
parent::__construct();
$this->navbar = $navbar;
}
}

18
src/Abstract/Entity/Browser/Container/Tab/Page/Navbar/Entry.php

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Abstract\Entity\Browser\Container\Tab\Page\Navbar;
abstract class Entry extends \Yggverse\Yoda\Abstract\Entity\Entry
{
public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar $navbar;
public function __construct(
\Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar $navbar
) {
parent::__construct();
$this->navbar = $navbar;
}
}

18
src/Abstract/Entity/Browser/History/Container/Navbar/Button.php

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Abstract\Entity\Browser\History\Container\Navbar;
abstract class Button extends \Yggverse\Yoda\Abstract\Entity\Button
{
public \Yggverse\Yoda\Entity\Browser\History\Container\Navbar $navbar;
public function __construct(
\Yggverse\Yoda\Entity\Browser\History\Container\Navbar $navbar
) {
parent::__construct();
$this->navbar = $navbar;
}
}

18
src/Abstract/Entity/Browser/History/Container/Navbar/Entry.php

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Abstract\Entity\Browser\History\Container\Navbar;
abstract class Entry extends \Yggverse\Yoda\Abstract\Entity\Entry
{
public \Yggverse\Yoda\Entity\Browser\History\Container\Navbar $navbar;
public function __construct(
\Yggverse\Yoda\Entity\Browser\History\Container\Navbar $navbar
) {
parent::__construct();
$this->navbar = $navbar;
}
}

20
src/Entity/Window/Header.php → src/Abstract/Entity/HeaderBar.php

@ -2,30 +2,24 @@
declare(strict_types=1); declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window; namespace Yggverse\Yoda\Abstract\Entity;
class Header abstract class HeaderBar
{ {
public \GtkHeaderBar $gtk; public \GtkHeaderBar $gtk;
public \Yggverse\Yoda\Entity\Window $window; protected bool $_actions = true;
protected string $_title = 'Yoda';
// Defaults
private bool $_actions = true;
private string $_title = 'Yoda';
public function __construct(
\Yggverse\Yoda\Entity\Window $window
) {
$this->window = $window;
public function __construct()
{
$this->gtk = new \GtkHeaderBar; $this->gtk = new \GtkHeaderBar;
$this->gtk->set_show_close_button( $this->gtk->set_show_close_button(
$this->_actions $this->_actions
); );
$this->setTitle( $this->gtk->set_title(
$this->_title $this->_title
); );
} }

18
src/Abstract/Entity/Window/Tab/Address/Navbar/Button.php

@ -1,18 +0,0 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Abstract\Entity\Window\Tab\Address\Navbar;
abstract class Button extends \Yggverse\Yoda\Abstract\Entity\Button
{
public \Yggverse\Yoda\Entity\Window\Tab\Address\Navbar $navbar;
public function __construct(
\Yggverse\Yoda\Entity\Window\Tab\Address\Navbar $navbar
) {
parent::__construct();
$this->navbar = $navbar;
}
}

18
src/Abstract/Entity/Window/Tab/Address/Navbar/Entry.php

@ -1,18 +0,0 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Abstract\Entity\Window\Tab\Address\Navbar;
abstract class Entry extends \Yggverse\Yoda\Abstract\Entity\Entry
{
public \Yggverse\Yoda\Entity\Window\Tab\Address\Navbar $navbar;
public function __construct(
\Yggverse\Yoda\Entity\Window\Tab\Address\Navbar $navbar
) {
parent::__construct();
$this->navbar = $navbar;
}
}

18
src/Abstract/Entity/Window/Tab/History/Navbar/Button.php

@ -1,18 +0,0 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Abstract\Entity\Window\Tab\History\Navbar;
abstract class Button extends \Yggverse\Yoda\Abstract\Entity\Button
{
public \Yggverse\Yoda\Entity\Window\Tab\History\Navbar $navbar;
public function __construct(
\Yggverse\Yoda\Entity\Window\Tab\History\Navbar $navbar
) {
parent::__construct();
$this->navbar = $navbar;
}
}

18
src/Abstract/Entity/Window/Tab/History/Navbar/Entry.php

@ -1,18 +0,0 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Abstract\Entity\Window\Tab\History\Navbar;
abstract class Entry extends \Yggverse\Yoda\Abstract\Entity\Entry
{
public \Yggverse\Yoda\Entity\Window\Tab\History\Navbar $navbar;
public function __construct(
\Yggverse\Yoda\Entity\Window\Tab\History\Navbar $navbar
) {
parent::__construct();
$this->navbar = $navbar;
}
}

23
src/Entity/Window.php → src/Entity/Browser.php

@ -4,29 +4,32 @@ declare(strict_types=1);
namespace Yggverse\Yoda\Entity; namespace Yggverse\Yoda\Entity;
use \Yggverse\Yoda\Entity\Window\Header; use \Yggverse\Yoda\Entity\Browser\Header;
use \Yggverse\Yoda\Entity\Window\Tab; use \Yggverse\Yoda\Entity\Browser\Container;
class Window class Browser
{ {
public \GtkWindow $gtk; public \GtkWindow $gtk;
// Dependencies
public \Yggverse\Yoda\Model\Database $database; public \Yggverse\Yoda\Model\Database $database;
public \Yggverse\Yoda\Entity\Window\Header $header; // Requirements
public \Yggverse\Yoda\Entity\Window\Tab $tab; public \Yggverse\Yoda\Entity\Browser\Header $header;
public \Yggverse\Yoda\Entity\Browser\Container $container;
// Defaults // Defaults
private int $_width = 640; private int $_width = 640;
private int $_height = 480; private int $_height = 480;
private bool $_maximize = true; private bool $_maximize = true;
public function __construct( public function __construct(
\Yggverse\Yoda\Model\Database $database \Yggverse\Yoda\Model\Database $database
) { ) {
// Init dependencies
$this->database = $database; $this->database = $database;
// Init window
$this->gtk = new \GtkWindow; $this->gtk = new \GtkWindow;
$this->gtk->set_size_request( $this->gtk->set_size_request(
@ -39,6 +42,7 @@ class Window
$this->gtk->maximize(); $this->gtk->maximize();
} }
// Init header
$this->header = new Header( $this->header = new Header(
$this $this
); );
@ -47,14 +51,13 @@ class Window
$this->header->gtk $this->header->gtk
); );
$this->tab = new Tab( // Init container
$this->container = new Container(
$this $this
); );
$this->gtk->add( $this->gtk->add(
$this->tab->gtk $this->container->gtk
); );
$this->gtk->show_all();
} }
} }

47
src/Entity/Browser/Container.php

@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Browser;
use \Yggverse\Yoda\Entity\Browser\Container\Tab;
class Container
{
public \GtkBox $gtk;
// Dependencies
public \Yggverse\Yoda\Entity\Browser $browser;
// Requirements
public \Yggverse\Yoda\Entity\Browser\Container\Tab $tab;
public function __construct(
\Yggverse\Yoda\Entity\Browser $browser
) {
// Init dependency
$this->browser = $browser;
// Init container
$this->gtk = new \GtkBox(
\GtkOrientation::VERTICAL
);
// Init tab
$this->tab = new Tab(
$this
);
$this->gtk->pack_start(
$this->tab->gtk,
true,
true,
0
);
}
public function refresh()
{
// @TODO
}
}

97
src/Entity/Browser/Container/Tab.php

@ -0,0 +1,97 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Browser\Container;
class Tab
{
public \GtkNotebook $gtk;
// Dependencies
public \Yggverse\Yoda\Entity\Browser\Container $container;
// Defaults
private bool $_reorderable = true;
private bool $_scrollable = true;
public function __construct(
\Yggverse\Yoda\Entity\Browser\Container $container
) {
// Init dependency
$this->container = $container;
// Init container
$this->gtk = new \GtkNotebook;
$this->gtk->set_scrollable(
$this->_scrollable
);
// Init previous session @TODO
$this->append();
$this->append();
// Connect events
$this->gtk->connect(
'switch-page',
function (
\GtkNotebook $entity,
\GtkWidget $child,
int $position
) {
$this->container->browser->header->setTitle(
$entity->get_tab_label(
$child
)->get_text()
);
}
);
}
public function append(
?string $request = null,
bool $focus = true
): void
{
$page = new \Yggverse\Yoda\Entity\Browser\Container\Tab\Page(
$this
);
if ($request)
{
$page->navbar->request->setValue(
$request
);
$page->content->update();
}
$this->gtk->append_page(
$page->gtk,
$page->title->gtk
);
$this->gtk->set_tab_reorderable(
$page->gtk,
$this->_reorderable
);
if ($focus)
{
// Focus on appended tab
$this->gtk->set_current_page(
$this->gtk->page_num(
$page->gtk
)
);
// Update application title
$this->container->browser->header->setTitle(
$page->title->gtk->get_text()
);
}
$this->gtk->show_all();
}
}

89
src/Entity/Browser/Container/Tab/Page.php

@ -0,0 +1,89 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Browser\Container\Tab;
use \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Title;
use \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar;
use \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Content;
use \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Statusbar;
class Page
{
public \GtkBox $gtk;
// Dependencies
public \Yggverse\Yoda\Entity\Browser\Container\Tab $tab;
// Requirements
public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Title $title;
public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar $navbar;
public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Content $content;
public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Statusbar $statusbar;
public function __construct(
\Yggverse\Yoda\Entity\Browser\Container\Tab $tab
) {
// Init dependencies
$this->tab = $tab;
// Init container
$this->gtk = new \GtkBox(
\GtkOrientation::VERTICAL
);
// Init title
$this->title = new Title(
$this
);
// Init navbar
$this->navbar = new Navbar(
$this
);
$this->gtk->add(
$this->navbar->gtk
);
// Init content
$this->content = new Content(
$this
);
$this->gtk->pack_start(
$this->content->gtk,
true,
true,
0
);
// Init statusbar
$this->statusbar = new Statusbar(
$this
);
$this->gtk->add(
$this->statusbar->gtk
);
}
public function refresh(): void
{
$this->navbar->refresh();
$this->content->refresh();
$this->statusbar->refresh();
}
public function update(
bool $history = true
): void
{
// @TODO navbar
$this->content->update(
$history
);
}
}

156
src/Entity/Window/Tab/Address.php → src/Entity/Browser/Container/Tab/Page/Content.php

@ -2,101 +2,84 @@
declare(strict_types=1); declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab; namespace Yggverse\Yoda\Entity\Browser\Container\Tab\Page;
use \Yggverse\Yoda\Entity\Window\Tab\Address\Title; use \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Content\Data;
use \Yggverse\Yoda\Entity\Window\Tab\Address\Navbar;
use \Yggverse\Yoda\Entity\Window\Tab\Address\Content;
use \Yggverse\Yoda\Entity\Window\Tab\Address\Statusbar;
class Address class Content
{ {
public \GtkBox $gtk; public \GtkScrolledWindow $gtk;
public \Yggverse\Yoda\Entity\Window\Tab $tab; // Dependencies
public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page $page;
public \Yggverse\Yoda\Entity\Window\Tab\Address\Title $title; // Requirements
public \Yggverse\Yoda\Entity\Window\Tab\Address\Navbar $navbar; public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Content\Data $data;
public \Yggverse\Yoda\Entity\Window\Tab\Address\Content $content;
public \Yggverse\Yoda\Entity\Window\Tab\Address\Statusbar $statusbar; // Defaults
private int $_margin = 8;
public function __construct( public function __construct(
\Yggverse\Yoda\Entity\Window\Tab $tab \Yggverse\Yoda\Entity\Browser\Container\Tab\Page $page
) { ) {
$this->tab = $tab; $this->page = $page;
$this->title = new Title(
$this
);
$this->gtk = new \GtkBox(
\GtkOrientation::VERTICAL
);
$this->navbar = new Navbar(
$this
);
$this->gtk->add( // Init container
$this->navbar->gtk $this->gtk = new \GtkScrolledWindow;
);
$this->content = new Content( $this->gtk->set_margin_start(
$this $this->_margin
); );
$this->gtk->pack_start( $this->gtk->set_margin_end(
$this->content->gtk, $this->_margin
true,
true,
0
); );
$this->statusbar = new Statusbar( // Init label
$this->data = new Data(
$this $this
); );
$this->gtk->add( $this->gtk->add(
$this->statusbar->gtk $this->data->gtk
); );
} }
public function refresh()
{
// @TODO
}
public function update( public function update(
bool $history = true bool $history = true
): void ): void
{ {
// Parse address // Parse address
$address = new \Yggverse\Net\Address( $address = new \Yggverse\Net\Address(
$this->navbar->request->gtk->get_text() $this->page->navbar->request->gtk->get_text()
); );
// Update title // Update title
$this->title->setValue( $this->page->title->setValue(
$address->getHost() $address->getHost()
); );
// Update navbar elements
$this->navbar->base->refresh();
if ($history) if ($history)
{ {
// Remember address in the navigation memory // Remember address in the navigation memory
$this->navbar->history->add( $this->page->navbar->history->add(
$address->get() $address->get()
); );
// Refresh history in database // Refresh history in database
$this->navbar->address->tab->window->database->refreshHistory( $this->page->tab->container->browser->database->renewHistory(
$address->get(), $address->get(),
// @TODO title // @TODO title
); );
// Refresh tabs
$this->navbar->address->tab->refresh();
} }
// Update statusbar indicator // Update statusbar indicator
$this->statusbar->setValue( $this->page->statusbar->setValue(
'Loading...' 'Loading...'
); );
@ -119,7 +102,7 @@ class Address
$title = null; $title = null;
$this->content->data->setValue( $this->data->setGemtext(
file_get_contents( // @TODO format relative links file_get_contents( // @TODO format relative links
$address->getPath() $address->getPath()
), ),
@ -128,12 +111,12 @@ class Address
if ($title) // detect title by document h1 if ($title) // detect title by document h1
{ {
$this->title->setValue( $this->page->title->setValue(
$title $title
); );
} }
$this->statusbar->setValue( $this->page->statusbar->setValue(
null null
); );
@ -141,15 +124,15 @@ class Address
default: default:
$this->title->setValue( $this->page->title->setValue(
'Oops!' 'Oops!'
); );
$this->content->data->setValue( $this->data->setPlain(
'File extension not supported' 'File extension not supported'
); );
$this->statusbar->setValue( $this->page->statusbar->setValue(
null null
); );
} }
@ -157,15 +140,15 @@ class Address
else else
{ {
$this->title->setValue( $this->page->title->setValue(
'Failure' 'Failure'
); );
$this->content->data->setValue( $this->data->setPlain(
'Could not open file' 'Could not open file'
); );
$this->statusbar->setValue( $this->page->statusbar->setValue(
'Resource not found or not readable' 'Resource not found or not readable'
); );
} }
@ -196,14 +179,14 @@ class Address
$title = null; $title = null;
$this->content->data->setValue( $this->data->setGemtext(
$response->getBody(), $response->getContainer(),
$title $title
); );
if ($title) // detect title by document h1 if ($title) // detect title by document h1
{ {
$this->title->setValue( $this->page->title->setValue(
$title $title
); );
} }
@ -212,34 +195,34 @@ class Address
default: default:
$this->content->data->setValue( $this->data->setPlain(
$response->getBody() $response->getContainer()
); );
} }
$this->statusbar->setValue( $this->page->statusbar->setValue(
$response->getMeta() $response->getMeta()
); );
} }
else else
{ {
$this->title->setValue( $this->page->title->setValue(
'Failure' 'Failure'
); );
$this->content->data->setValue( $this->data->setPlain(
'Resource not available!'
);
$this->page->statusbar->setValue(
sprintf( sprintf(
'Resource not available (code %d)', 'code %d',
intval( intval(
$response->getCode() $response->getCode()
) )
) )
); );
$this->statusbar->setValue(
'Request failed'
);
} }
break; break;
@ -250,30 +233,32 @@ class Address
$address = new \Yggverse\Net\Address( $address = new \Yggverse\Net\Address(
sprintf( sprintf(
'gemini://%s', 'gemini://%s',
$this->navbar->request->gtk->get_text() trim(
$this->page->navbar->request->gtk->get_text()
)
) )
); );
// Hostname request // Is hostname request
if (filter_var( if (filter_var(
$address->getHost(), $address->getHost(),
FILTER_VALIDATE_DOMAIN, FILTER_VALIDATE_DOMAIN,
FILTER_FLAG_HOSTNAME FILTER_FLAG_HOSTNAME
) )
) { ) {
$this->navbar->request->setValue( $this->page->navbar->request->setValue(
$address->get() $address->get()
); );
} }
// Search request // Is search request
else else
{ {
$this->navbar->request->setValue( $this->page->navbar->request->setValue(
sprintf( sprintf(
'gemini://tlgs.one/search?%s', // @TODO custom provider 'gemini://tlgs.one/search?%s', // @TODO custom provider
urlencode( urlencode(
$this->navbar->request->gtk->get_text() $this->page->navbar->request->gtk->get_text()
) )
) )
); );
@ -285,28 +270,19 @@ class Address
default: default:
$this->title->setValue( $this->page->title->setValue(
'Oops!' 'Oops!'
); );
$this->content->data->setValue( $this->data->setPlain(
sprintf( 'Protocol not supported!'
'Protocol not supported',
intval(
$response->getCode()
)
)
); );
$this->statusbar->setValue( $this->page->statusbar->setValue(
null null
); );
} }
$this->tab->window->header->setTitle(
$this->title->gtk->get_text()
);
$this->gtk->show_all(); $this->gtk->show_all();
} }
} }

30
src/Entity/Window/Tab/Address/Content/Gemtext.php → src/Entity/Browser/Container/Tab/Page/Content/Data.php

@ -2,25 +2,28 @@
declare(strict_types=1); declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\Address\Content; namespace Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Content;
use \Yggverse\Gemtext\Document; use \Yggverse\Gemtext\Document;
use \Yggverse\Net\Address; use \Yggverse\Net\Address;
class Gemtext class Data
{ {
public \GtkLabel $gtk; public \GtkLabel $gtk;
public \Yggverse\Yoda\Entity\Window\Tab\Address\Content $content; // Dependencies
public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Content $content;
// Defaults // Defaults
private string $_value = ''; private string $_value = '';
public function __construct( public function __construct(
\Yggverse\Yoda\Entity\Window\Tab\Address\Content $content \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Content $content
) { ) {
// Init dependency
$this->content = $content; $this->content = $content;
// Init markup label
$this->gtk = new \GtkLabel; $this->gtk = new \GtkLabel;
$this->gtk->set_use_markup( $this->gtk->set_use_markup(
@ -43,7 +46,7 @@ class Gemtext
0 0
); );
$this->setValue( $this->setPlain(
$this->_value $this->_value
); );
@ -53,18 +56,27 @@ class Gemtext
\GtkLabel $label, \GtkLabel $label,
string $href string $href
) { ) {
$this->content->address->navbar->request->setValue( $this->content->page->navbar->request->setValue(
$this->_url( $this->_url(
$href $href
) )
); );
$this->content->address->update(); $this->content->page->update();
} }
); );
} }
public function setValue( public function setPlain(
string $value
): void
{
$this->gtk->set_text(
$value
);
}
public function setGemtext(
string $value, string $value,
string | null &$title = null string | null &$title = null
): void ): void
@ -221,7 +233,7 @@ class Gemtext
{ {
$address->toAbsolute( $address->toAbsolute(
new Address( new Address(
$this->content->address->navbar->request->gtk->get_text() $this->content->page->navbar->request->gtk->get_text()
) )
); );
} }

73
src/Entity/Window/Tab/Address/Navbar.php → src/Entity/Browser/Container/Tab/Page/Navbar.php

@ -2,38 +2,57 @@
declare(strict_types=1); declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\Address; namespace Yggverse\Yoda\Entity\Browser\Container\Tab\Page;
use \Yggverse\Yoda\Entity\Window\Tab\Address\Navbar\Base; use \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar\Base;
use \Yggverse\Yoda\Entity\Window\Tab\Address\Navbar\Go; use \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar\Go;
use \Yggverse\Yoda\Entity\Window\Tab\Address\Navbar\History; use \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar\History;
use \Yggverse\Yoda\Entity\Window\Tab\Address\Navbar\Request; use \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar\Request;
class Navbar class Navbar
{ {
public \GtkBox $gtk; public \GtkBox $gtk;
public \Yggverse\Yoda\Entity\Window\Tab\Address $address; // Dependencies
public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page $page;
public \Yggverse\Yoda\Entity\Window\Tab\Address\Navbar\Base $base; // Requirements
public \Yggverse\Yoda\Entity\Window\Tab\Address\Navbar\Go $go; public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar\Base $base;
public \Yggverse\Yoda\Entity\Window\Tab\Address\Navbar\History $history; public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar\Go $go;
public \Yggverse\Yoda\Entity\Window\Tab\Address\Navbar\Request $request; public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar\History $history;
public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar\Request $request;
// Defaults // Defaults
private int $_margin = 8; private int $_margin = 8;
public function __construct( public function __construct(
\Yggverse\Yoda\Entity\Window\Tab\Address $address \Yggverse\Yoda\Entity\Browser\Container\Tab\Page $page
) { ) {
$this->address = $address; // Init dependencies
$this->page = $page;
// Init navbar area // Init navbar
$this->gtk = new \GtkBox( $this->gtk = new \GtkBox(
\GtkOrientation::HORIZONTAL \GtkOrientation::HORIZONTAL
); );
$this->setMargins( $this->gtk->set_margin_top(
$this->_margin
);
$this->gtk->set_margin_bottom(
$this->_margin
);
$this->gtk->set_margin_start(
$this->_margin
);
$this->gtk->set_margin_end(
$this->_margin
);
$this->gtk->set_spacing(
$this->_margin $this->_margin
); );
@ -77,28 +96,10 @@ class Navbar
); );
} }
public function setMargins( public function refresh()
?int $value
): void
{ {
$this->gtk->set_margin_top( $this->base->refresh();
$value ?? $this->_margin $this->go->refresh();
); $this->history->refresh();
$this->gtk->set_margin_bottom(
$value ?? $this->_margin
);
$this->gtk->set_margin_start(
$value ?? $this->_margin
);
$this->gtk->set_margin_end(
$value ?? $this->_margin
);
$this->gtk->set_spacing(
$value ?? $this->_margin
);
} }
} }

12
src/Entity/Window/Tab/Address/Navbar/Base.php → src/Entity/Browser/Container/Tab/Page/Navbar/Base.php

@ -2,9 +2,9 @@
declare(strict_types=1); declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\Address\Navbar; namespace Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar;
class Base extends \Yggverse\Yoda\Abstract\Entity\Window\Tab\Address\Navbar\Button class Base extends \Yggverse\Yoda\Abstract\Entity\Browser\Container\Tab\Page\Navbar\Button
{ {
protected string $_label = 'Base'; protected string $_label = 'Base';
@ -13,7 +13,11 @@ class Base extends \Yggverse\Yoda\Abstract\Entity\Window\Tab\Address\Navbar\Butt
): void ): void
{ {
$address = new \Yggverse\Net\Address( $address = new \Yggverse\Net\Address(
$this->navbar->request->gtk->get_text() trim(
strval(
$this->navbar->request->gtk->get_text()
)
)
); );
if ($address->getHost()) if ($address->getHost())
@ -46,7 +50,7 @@ class Base extends \Yggverse\Yoda\Abstract\Entity\Window\Tab\Address\Navbar\Butt
) )
); );
$this->navbar->base->gtk->set_sensitive( $this->gtk->set_sensitive(
$address->getHost() && ( $address->getHost() && (
$address->getPath() || $address->getQuery() $address->getPath() || $address->getQuery()
) )

6
src/Entity/Window/Tab/Address/Navbar/Go.php → src/Entity/Browser/Container/Tab/Page/Navbar/Go.php

@ -2,9 +2,9 @@
declare(strict_types=1); declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\Address\Navbar; namespace Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar;
class Go extends \Yggverse\Yoda\Abstract\Entity\Window\Tab\Address\Navbar\Button class Go extends \Yggverse\Yoda\Abstract\Entity\Browser\Container\Tab\Page\Navbar\Button
{ {
protected string $_label = 'Go'; protected string $_label = 'Go';
@ -12,7 +12,7 @@ class Go extends \Yggverse\Yoda\Abstract\Entity\Window\Tab\Address\Navbar\Button
\GtkButton $entity \GtkButton $entity
): void ): void
{ {
$this->navbar->address->update(); $this->navbar->page->update();
} }
public function refresh(): void public function refresh(): void

28
src/Entity/Window/Tab/Address/Navbar/History.php → src/Entity/Browser/Container/Tab/Page/Navbar/History.php

@ -2,23 +2,26 @@
declare(strict_types=1); declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\Address\Navbar; namespace Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar;
use \Yggverse\Yoda\Entity\Window\Tab\Address\Navbar\History\Back; use \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar\History\Back;
use \Yggverse\Yoda\Entity\Window\Tab\Address\Navbar\History\Forward; use \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar\History\Forward;
class History class History
{ {
public \GtkButtonBox $gtk; public \GtkButtonBox $gtk;
public \Yggverse\Yoda\Entity\Window\Tab\Address\Navbar $navbar; // Dependencies
public \Yggverse\Yoda\Entity\Window\Tab\Address\Navbar\History\Back $back;
public \Yggverse\Yoda\Entity\Window\Tab\Address\Navbar\History\Forward $forward;
public \Yggverse\Yoda\Model\History $memory; public \Yggverse\Yoda\Model\History $memory;
public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar $navbar;
// Requirements
public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar\History\Back $back;
public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar\History\Forward $forward;
public function __construct( public function __construct(
\Yggverse\Yoda\Entity\Window\Tab\Address\Navbar $navbar \Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar $navbar
) { ) {
$this->memory = new \Yggverse\Yoda\Model\History(); $this->memory = new \Yggverse\Yoda\Model\History();
@ -70,12 +73,7 @@ class History
public function refresh(): void public function refresh(): void
{ {
$this->back->gtk->set_sensitive( $this->back->refresh();
(bool) $this->memory->getBack() $this->forward->refresh();
);
$this->forward->gtk->set_sensitive(
(bool) $this->memory->getForward()
);
} }
} }

15
src/Entity/Window/Tab/Address/Navbar/History/Back.php → src/Entity/Browser/Container/Tab/Page/Navbar/History/Back.php

@ -2,9 +2,9 @@
declare(strict_types=1); declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\Address\Navbar\History; namespace Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar\History;
class Back extends \Yggverse\Yoda\Abstract\Entity\Window\Tab\Address\Navbar\Button class Back extends \Yggverse\Yoda\Abstract\Entity\Browser\Container\Tab\Page\Navbar\Button
{ {
protected string $_label = 'Back'; protected string $_label = 'Back';
@ -18,11 +18,20 @@ class Back extends \Yggverse\Yoda\Abstract\Entity\Window\Tab\Address\Navbar\Butt
$this->navbar->history->memory->goBack() $this->navbar->history->memory->goBack()
); );
$this->navbar->address->update( $this->navbar->page->update(
false false
); );
} }
$this->navbar->history->refresh(); $this->navbar->history->refresh();
} }
public function refresh(): void
{
$this->gtk->set_sensitive(
boolval(
$this->navbar->history->memory->getBack()
)
);
}
} }

15
src/Entity/Window/Tab/Address/Navbar/History/Forward.php → src/Entity/Browser/Container/Tab/Page/Navbar/History/Forward.php

@ -2,9 +2,9 @@
declare(strict_types=1); declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\Address\Navbar\History; namespace Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar\History;
class Forward extends \Yggverse\Yoda\Abstract\Entity\Window\Tab\Address\Navbar\Button class Forward extends \Yggverse\Yoda\Abstract\Entity\Browser\Container\Tab\Page\Navbar\Button
{ {
protected string $_label = 'Forward'; protected string $_label = 'Forward';
@ -18,11 +18,20 @@ class Forward extends \Yggverse\Yoda\Abstract\Entity\Window\Tab\Address\Navbar\B
$this->navbar->history->memory->goForward() $this->navbar->history->memory->goForward()
); );
$this->navbar->address->update( $this->navbar->page->update(
false false
); );
} }
$this->navbar->history->refresh(); $this->navbar->history->refresh();
} }
public function refresh(): void
{
$this->gtk->set_sensitive(
boolval(
$this->navbar->history->memory->getForward()
)
);
}
} }

10
src/Entity/Window/Tab/Address/Navbar/Request.php → src/Entity/Browser/Container/Tab/Page/Navbar/Request.php

@ -2,9 +2,9 @@
declare(strict_types=1); declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\Address\Navbar; namespace Yggverse\Yoda\Entity\Browser\Container\Tab\Page\Navbar;
class Request extends \Yggverse\Yoda\Abstract\Entity\Window\Tab\Address\Navbar\Entry class Request extends \Yggverse\Yoda\Abstract\Entity\Browser\Container\Tab\Page\Navbar\Entry
{ {
private string $_placeholder = 'URL or search term...'; private string $_placeholder = 'URL or search term...';
@ -12,7 +12,7 @@ class Request extends \Yggverse\Yoda\Abstract\Entity\Window\Tab\Address\Navbar\E
\GtkEntry $entry \GtkEntry $entry
): void ): void
{ {
$this->navbar->address->update(); $this->navbar->page->content->update();
} }
protected function _onKeyRelease( protected function _onKeyRelease(
@ -20,8 +20,6 @@ class Request extends \Yggverse\Yoda\Abstract\Entity\Window\Tab\Address\Navbar\E
\GdkEvent $event \GdkEvent $event
): void ): void
{ {
$this->navbar->base->refresh(); $this->navbar->refresh();
$this->navbar->go->refresh();
} }
} }

16
src/Entity/Window/Tab/Address/Statusbar.php → src/Entity/Browser/Container/Tab/Page/Statusbar.php

@ -2,23 +2,26 @@
declare(strict_types=1); declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\Address; namespace Yggverse\Yoda\Entity\Browser\Container\Tab\Page;
class Statusbar class Statusbar
{ {
public \GtkLabel $gtk; public \GtkLabel $gtk;
public \Yggverse\Yoda\Entity\Window\Tab\Address $address; // Dependencies
public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page $page;
// Defaults // Defaults
private int $_margin = 8; private int $_margin = 8;
private string $_value = ''; private string $_value = '';
public function __construct( public function __construct(
\Yggverse\Yoda\Entity\Window\Tab\Address $address \Yggverse\Yoda\Entity\Browser\Container\Tab\Page $page
) { ) {
$this->address = $address; // Init dependency
$this->page = $page;
// Init container
$this->gtk = new \GtkLabel; $this->gtk = new \GtkLabel;
$this->gtk->set_use_markup( $this->gtk->set_use_markup(
@ -72,4 +75,9 @@ class Statusbar
) )
); );
} }
public function refresh()
{
// @TODO
}
} }

13
src/Entity/Window/Tab/Address/Title.php → src/Entity/Browser/Container/Tab/Page/Title.php

@ -2,24 +2,27 @@
declare(strict_types=1); declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\Address; namespace Yggverse\Yoda\Entity\Browser\Container\Tab\Page;
class Title class Title
{ {
public \GtkLabel $gtk; public \GtkLabel $gtk;
public \Yggverse\Yoda\Entity\Window\Tab\Address $address; // Dependencies
public \Yggverse\Yoda\Entity\Browser\Container\Tab\Page $page;
// Defaults // Defaults
private int $_ellipsize = 3; private int $_ellipsize = 3;
private int $_length = 12; private int $_length = 12;
private string $_value = 'New address'; private string $_value = 'New page';
public function __construct( public function __construct(
\Yggverse\Yoda\Entity\Window\Tab\Address $address, \Yggverse\Yoda\Entity\Browser\Container\Tab\Page $page,
) { ) {
$this->address = $address; // Init dependencies
$this->page = $page;
// Init container
$this->gtk = new \GtkLabel( $this->gtk = new \GtkLabel(
$this->_value $this->_value
); );

10
src/Entity/Browser/Header.php

@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Browser;
class Header extends \Yggverse\Yoda\Abstract\Entity\HeaderBar
{
protected string $_title = 'Yoda';
}

63
src/Entity/Browser/History.php

@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Browser;
use \Yggverse\Yoda\Entity\Browser\History\Header;
use \Yggverse\Yoda\Entity\Browser\History\Container;
class History
{
public \GtkWindow $gtk;
// Dependencies
public \Yggverse\Yoda\Entity\Browser $browser;
// Requirements
public \Yggverse\Yoda\Entity\Browser\History\Header $header;
public \Yggverse\Yoda\Entity\Browser\History\Container $container;
// Defaults
private int $_width = 640;
private int $_height = 480;
private bool $_maximize = false;
public function __construct(
\Yggverse\Yoda\Entity\Browser $browser
) {
// Init dependencies
$this->browser = $browser;
// Init window
$this->gtk = new \GtkWindow;
$this->gtk->set_size_request(
$this->_width,
$this->_height
);
if ($this->_maximize)
{
$this->gtk->maximize();
}
// Init header
$this->header = new Header(
$this
);
$this->gtk->set_titlebar(
$this->header->gtk
);
// Init container
$this->container = new Container(
$this
);
$this->gtk->add(
$this->container->gtk
);
}
}

59
src/Entity/Browser/History/Container.php

@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Browser\History;
use \Yggverse\Yoda\Entity\Browser\History\Container\Navbar;
use \Yggverse\Yoda\Entity\Browser\History\Container\Content;
class Container
{
public \GtkBox $gtk;
// Dependencies
public \Yggverse\Yoda\Entity\Browser\History $history;
// Requirements
public \Yggverse\Yoda\Entity\Browser\History\Container\Navbar $navbar;
public \Yggverse\Yoda\Entity\Browser\History\Container\Content $content;
public function __construct(
\Yggverse\Yoda\Entity\Browser\History $history
) {
// Init dependency
$this->history = $history;
// Init container
$this->gtk = new \GtkBox(
\GtkOrientation::VERTICAL
);
// Init navbar
$this->navbar = new Navbar(
$this
);
$this->gtk->add(
$this->navbar->gtk
);
// Init content
$this->content = new Content(
$this
);
$this->gtk->pack_start(
$this->content->gtk,
true,
true,
0
);
}
public function refresh()
{
$this->navbar->refresh();
$this->content->refresh();
}
}

67
src/Entity/Window/Tab/History/Content.php → src/Entity/Browser/History/Container/Content.php

@ -2,18 +2,18 @@
declare(strict_types=1); declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\History; namespace Yggverse\Yoda\Entity\Browser\History\Container;
use \Yggverse\Yoda\Entity\Window\Tab\Address;
class Content class Content
{ {
public \GtkScrolledWindow $gtk; public \GtkScrolledWindow $gtk;
// Requirements @TODO entity
public \GtkTreeView $treeview; public \GtkTreeView $treeview;
public \GtkListStore $list; public \GtkListStore $list;
public \Yggverse\Yoda\Entity\Window\Tab\History $history; // Dependencies
public \Yggverse\Yoda\Entity\Browser\History\Container $container;
// Defaults // Defaults
private string $_time = 'Time'; private string $_time = 'Time';
@ -23,22 +23,25 @@ class Content
private int $_margin = 8; private int $_margin = 8;
public function __construct( public function __construct(
\Yggverse\Yoda\Entity\Window\Tab\History $history \Yggverse\Yoda\Entity\Browser\History\Container $container
) { ) {
$this->history = $history; // Init dependency
$this->container = $container;
// Init container
$this->gtk = new \GtkScrolledWindow; $this->gtk = new \GtkScrolledWindow;
$this->gtk->set_margin_start( // Init records listing
$this->treeview = new \GtkTreeView;
$this->treeview->set_margin_start(
$this->_margin $this->_margin
); );
$this->gtk->set_margin_end( $this->treeview->set_margin_end(
$this->_margin $this->_margin
); );
$this->treeview = new \GtkTreeView;
$this->treeview->append_column( $this->treeview->append_column(
new \GtkTreeViewColumn( new \GtkTreeViewColumn(
$this->_time, $this->_time,
@ -81,26 +84,15 @@ class Content
$this->treeview $this->treeview
); );
$this->search(); // Connect events
$this->treeview->connect( $this->treeview->connect(
'row-activated', 'row-activated',
function( function(
\GtkTreeView $treeview \GtkTreeView $treeview
) { ) {
$address = new Address( $this->container->history->browser->container->tab->append(
$this->history->tab
);
$address->navbar->request->setValue(
$this->getSelectedUrl() $this->getSelectedUrl()
); );
$this->history->tab->append(
$address
);
$address->update();
} }
); );
@ -109,17 +101,25 @@ class Content
function( function(
\GtkTreeView $treeview \GtkTreeView $treeview
) { ) {
$this->history->navbar->open->gtk->set_sensitive( $this->container->navbar->open->gtk->set_sensitive(
(bool) $this->getSelectedId() boolval(
$this->getSelectedId()
)
); );
$this->history->navbar->delete->gtk->set_sensitive( $this->container->navbar->delete->gtk->set_sensitive(
(bool) $this->getSelectedId() boolval(
$this->getSelectedId()
)
); );
} }
); );
// Make initial search
$this->search();
} }
// Append new row
public function append( public function append(
int $id, int $id,
int $time, int $time,
@ -142,25 +142,28 @@ class Content
); );
} }
// Remove rows from list
public function clear(): void public function clear(): void
{ {
$this->list->clear(); $this->list->clear();
} }
public function update(): void // Refresh rows using current navbar value
public function refresh(): void
{ {
$this->search( $this->search(
$this->history->navbar->filter->gtk->get_text() $this->container->navbar->filter->gtk->get_text()
); );
} }
// Do records search in database
public function search( public function search(
string $filter = '' string $filter = ''
): void ): void
{ {
$this->clear(); $this->clear();
if ($records = $this->history->tab->window->database->findHistory($filter)) if ($records = $this->container->history->browser->database->findHistory($filter))
{ {
foreach ($records as $record) foreach ($records as $record)
{ {
@ -175,11 +178,11 @@ class Content
else else
{ {
$this->history->navbar->open->gtk->set_sensitive( $this->container->navbar->open->gtk->set_sensitive(
false false
); );
$this->history->navbar->delete->gtk->set_sensitive( $this->container->navbar->delete->gtk->set_sensitive(
false false
); );
} }

104
src/Entity/Browser/History/Container/Navbar.php

@ -0,0 +1,104 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Browser\History\Container;
use \Yggverse\Yoda\Entity\Browser\History\Container\Navbar\Delete;
use \Yggverse\Yoda\Entity\Browser\History\Container\Navbar\Filter;
use \Yggverse\Yoda\Entity\Browser\History\Container\Navbar\Open;
use \Yggverse\Yoda\Entity\Browser\History\Container\Navbar\Search;
class Navbar
{
public \GtkBox $gtk;
// Dependencies
public \Yggverse\Yoda\Entity\Browser\History\Container $container;
// Requirements
public \Yggverse\Yoda\Entity\Browser\History\Container\Navbar\Delete $delete;
public \Yggverse\Yoda\Entity\Browser\History\Container\Navbar\Filter $filter;
public \Yggverse\Yoda\Entity\Browser\History\Container\Navbar\Open $open;
public \Yggverse\Yoda\Entity\Browser\History\Container\Navbar\Search $search;
// Defaults
private int $_margin = 8;
public function __construct(
\Yggverse\Yoda\Entity\Browser\History\Container $container
) {
// Init dependency
$this->container = $container;
// Init container
$this->gtk = new \GtkBox(
\GtkOrientation::HORIZONTAL
);
$this->gtk->set_margin_top(
$this->_margin
);
$this->gtk->set_margin_bottom(
$this->_margin
);
$this->gtk->set_margin_start(
$this->_margin
);
$this->gtk->set_margin_end(
$this->_margin
);
$this->gtk->set_spacing(
$this->_margin
);
// Init open button
$this->open = new Open(
$this
);
$this->gtk->add(
$this->open->gtk
);
// Init delete button
$this->delete = new Delete(
$this
);
$this->gtk->add(
$this->delete->gtk
);
// Init filter entry
$this->filter = new Filter(
$this
);
$this->gtk->pack_start(
$this->filter->gtk,
true,
true,
0
);
// Init search button
$this->search = new Search(
$this
);
$this->gtk->add(
$this->search->gtk
);
}
public function refresh(): void
{
$this->delete->refresh();
$this->open->refresh();
}
}

33
src/Entity/Browser/History/Container/Navbar/Delete.php

@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Browser\History\Container\Navbar;
class Delete extends \Yggverse\Yoda\Abstract\Entity\Browser\History\Container\Navbar\Button
{
protected string $_label = 'Delete';
protected function _onCLick(
\GtkButton $entity
): void
{
if ($id = $this->navbar->container->content->getSelectedId())
{
$this->navbar->container->history->browser->database->deleteHistory(
$id
);
}
$this->navbar->container->refresh();
}
public function refresh(): void
{
$this->gtk->set_sensitive(
boolval(
$this->navbar->container->content->getSelectedId()
)
);
}
}

8
src/Entity/Window/Tab/History/Navbar/Filter.php → src/Entity/Browser/History/Container/Navbar/Filter.php

@ -2,9 +2,9 @@
declare(strict_types=1); declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\History\Navbar; namespace Yggverse\Yoda\Entity\Browser\History\Container\Navbar;
class Filter extends \Yggverse\Yoda\Abstract\Entity\Window\Tab\History\Navbar\Entry class Filter extends \Yggverse\Yoda\Abstract\Entity\Browser\History\Container\Navbar\Entry
{ {
private string $_placeholder = 'Search in history...'; private string $_placeholder = 'Search in history...';
@ -12,7 +12,7 @@ class Filter extends \Yggverse\Yoda\Abstract\Entity\Window\Tab\History\Navbar\En
\GtkEntry $entry \GtkEntry $entry
): void ): void
{ {
$this->navbar->history->content->search( $this->navbar->container->content->search(
$entry->get_text() $entry->get_text()
); );
} }
@ -22,7 +22,7 @@ class Filter extends \Yggverse\Yoda\Abstract\Entity\Window\Tab\History\Navbar\En
\GdkEvent $event \GdkEvent $event
): void ): void
{ {
$this->navbar->history->content->search( $this->navbar->container->content->search(
$entry->get_text() $entry->get_text()
); );
} }

28
src/Entity/Browser/History/Container/Navbar/Open.php

@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Browser\History\Container\Navbar;
class Open extends \Yggverse\Yoda\Abstract\Entity\Browser\History\Container\Navbar\Button
{
protected string $_label = 'Open';
protected function _onCLick(
\GtkButton $entity
): void
{
$this->navbar->container->history->browser->container->tab->append(
$this->navbar->container->content->getSelectedUrl()
);
}
public function refresh(): void
{
$this->gtk->set_sensitive(
boolval(
$this->navbar->container->content->getSelectedId()
)
);
}
}

20
src/Entity/Browser/History/Container/Navbar/Search.php

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Browser\History\Container\Navbar;
class Search extends \Yggverse\Yoda\Abstract\Entity\Browser\History\Container\Navbar\Button
{
protected bool $_sensitive = true;
protected string $_label = 'Search';
protected function _onCLick(
\GtkButton $entity
): void
{
$this->navbar->container->content->search(
$this->navbar->filter->gtk->get_text()
);
}
}

10
src/Entity/Browser/History/Header.php

@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Browser\History;
class Header extends \Yggverse\Yoda\Abstract\Entity\HeaderBar
{
protected string $_title = 'History - Yoda';
}

109
src/Entity/Window/Tab.php

@ -1,109 +0,0 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window;
use \Yggverse\Yoda\Entity\Window\Tab\Address;
use \Yggverse\Yoda\Entity\Window\Tab\History;
class Tab
{
public \GtkNotebook $gtk;
public \Yggverse\Yoda\Entity\Window $window;
// App entity operations
private array $_tab = [];
// Defaults
private bool $_reorderable = true;
private bool $_scrollable = true;
public function __construct(
\Yggverse\Yoda\Entity\Window $window
) {
$this->window = $window;
$this->gtk = new \GtkNotebook;
$this->gtk->set_scrollable(
$this->_scrollable
);
$this->gtk->connect(
'switch-page',
function (
\GtkNotebook $entity,
\GtkWidget $child,
int $position
) {
$this->window->header->setTitle(
$entity->get_tab_label(
$child
)->get_text()
);
}
);
$this->append( // @TODO remove
new History(
$this
)
);
$this->append( // @TODO remove
new Address(
$this
)
);
}
public function append(
Address | History $entity,
?bool $reorderable = null
): void
{
$this->gtk->append_page(
$entity->gtk,
$entity->title->gtk
);
$this->gtk->set_tab_reorderable(
$entity->gtk,
is_null($reorderable) ? $this->_reorderable : $reorderable
);
$this->gtk->show_all();
// Focus on appended tab
$this->gtk->set_current_page(
$this->gtk->page_num(
$entity->gtk
)
);
// Update application title
$this->window->header->setTitle(
$entity->title->gtk->get_text()
);
// Register new tab entity
$this->_tab[] = $entity;
}
public function refresh()
{
foreach ($this->_tab as $entity)
{
switch (true)
{
case $entity instanceof History:
$entity->content->update();
break;
}
}
}
}

45
src/Entity/Window/Tab/Address/Content.php

@ -1,45 +0,0 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\Address;
use \Yggverse\Yoda\Entity\Window\Tab\Address\Content\Gemtext;
use \Yggverse\Yoda\Entity\Window\Tab\Address\Content\Plain;
class Content
{
public \GtkScrolledWindow $gtk;
public \Yggverse\Yoda\Entity\Window\Tab\Address $address;
public Gemtext | Plain $data;
private int $_margin = 8;
public function __construct(
\Yggverse\Yoda\Entity\Window\Tab\Address $address
) {
$this->address = $address;
$this->gtk = new \GtkScrolledWindow;
$this->gtk->set_margin_start(
$this->_margin
);
$this->gtk->set_margin_end(
$this->_margin
);
$this->data = new Gemtext(
$this
);
$this->gtk->add(
$this->data->gtk
);
$this->gtk->show_all();
}
}

54
src/Entity/Window/Tab/Address/Content/Plain.php

@ -1,54 +0,0 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\Address\Content;
class Plain
{
public \GtkLabel $gtk;
public \Yggverse\Yoda\Entity\Window\Tab\Address\Content $content;
// Defaults
private string $_value = '';
public function __construct(
\Yggverse\Yoda\Entity\Window\Tab\Address\Content $content
) {
$this->content = $content;
$this->gtk = new \GtkLabel(
$this->_value
);
$this->gtk->set_use_markup(
false
);
$this->gtk->set_selectable(
true
);
$this->gtk->set_line_wrap(
true
);
$this->gtk->set_xalign(
0
);
$this->gtk->set_yalign(
0
);
}
public function setValue(
string $value
): void
{
$this->gtk->set_text(
$value
);
}
}

74
src/Entity/Window/Tab/History.php

@ -1,74 +0,0 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab;
use \Yggverse\Yoda\Entity\Window\Tab\History\Title;
use \Yggverse\Yoda\Entity\Window\Tab\History\Navbar;
use \Yggverse\Yoda\Entity\Window\Tab\History\Content;
class History
{
public \GtkBox $gtk;
public \Yggverse\Yoda\Entity\Window\Tab $tab;
public \Yggverse\Yoda\Entity\Window\Tab\History\Title $title;
public \Yggverse\Yoda\Entity\Window\Tab\History\Navbar $navbar;
public \Yggverse\Yoda\Entity\Window\Tab\History\Content $content;
public function __construct(
\Yggverse\Yoda\Entity\Window\Tab $tab
) {
$this->tab = $tab;
$this->title = new Title(
$this
);
$this->gtk = new \GtkBox(
\GtkOrientation::VERTICAL
);
$this->navbar = new Navbar(
$this
);
$this->content = new Content(
$this
);
$this->gtk->add(
$this->navbar->gtk
);
$this->gtk->pack_start(
$this->content->gtk,
true,
true,
0
);
}
public function search(
?string $filter = null
): void
{
$this->navbar->filter->setValue(
trim(
strval(
$filter
)
)
);
$this->content->search(
trim(
strval(
$filter
)
)
);
}
}

99
src/Entity/Window/Tab/History/Navbar.php

@ -1,99 +0,0 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\History;
use \Yggverse\Yoda\Entity\Window\Tab\History\Navbar\Delete;
use \Yggverse\Yoda\Entity\Window\Tab\History\Navbar\Filter;
use \Yggverse\Yoda\Entity\Window\Tab\History\Navbar\Open;
use \Yggverse\Yoda\Entity\Window\Tab\History\Navbar\Search;
class Navbar
{
public \GtkBox $gtk;
public \Yggverse\Yoda\Entity\Window\Tab\History $history;
public \Yggverse\Yoda\Entity\Window\Tab\History\Navbar\Delete $delete;
public \Yggverse\Yoda\Entity\Window\Tab\History\Navbar\Filter $filter;
public \Yggverse\Yoda\Entity\Window\Tab\History\Navbar\Open $open;
public \Yggverse\Yoda\Entity\Window\Tab\History\Navbar\Search $search;
// Defaults
private int $_margin = 8;
public function __construct(
\Yggverse\Yoda\Entity\Window\Tab\History $history
) {
$this->history = $history;
$this->gtk = new \GtkBox(
\GtkOrientation::HORIZONTAL
);
$this->setMargin(
$this->_margin
);
$this->open = new Open(
$this
);
$this->gtk->add(
$this->open->gtk
);
$this->delete = new Delete(
$this
);
$this->gtk->add(
$this->delete->gtk
);
$this->filter = new Filter(
$this
);
$this->gtk->pack_start(
$this->filter->gtk,
true,
true,
0
);
$this->search = new Search(
$this
);
$this->gtk->add(
$this->search->gtk
);
}
public function setMargin(
?int $value = null
): void
{
$this->gtk->set_margin_top(
$margin ?? $this->_margin
);
$this->gtk->set_margin_bottom(
$margin ?? $this->_margin
);
$this->gtk->set_margin_start(
$margin ?? $this->_margin
);
$this->gtk->set_margin_end(
$margin ?? $this->_margin
);
$this->gtk->set_spacing(
$margin ?? $this->_margin
);
}
}

30
src/Entity/Window/Tab/History/Navbar/Delete.php

@ -1,30 +0,0 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\History\Navbar;
class Delete extends \Yggverse\Yoda\Abstract\Entity\Window\Tab\History\Navbar\Button
{
protected string $_label = 'Delete';
protected function _onCLick(
\GtkButton $entity
): void
{
if ($id = $this->navbar->history->content->getSelectedId())
{
$this->navbar->history->tab->window->database->deleteHistory(
$id
);
$this->navbar->open->gtk->set_sensitive(
false
);
$this->navbar->history->content->search(
$this->navbar->filter->gtk->get_text()
);
}
}
}

31
src/Entity/Window/Tab/History/Navbar/Open.php

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\History\Navbar;
use \Yggverse\Yoda\Entity\Window\Tab\Address;
class Open extends \Yggverse\Yoda\Abstract\Entity\Window\Tab\History\Navbar\Button
{
protected string $_label = 'Open';
protected function _onCLick(
\GtkButton $entity
): void
{
$address = new Address(
$this->navbar->history->tab
);
$this->navbar->history->tab->append( // @TODO
$address
);
$address->navbar->request->setValue(
$this->navbar->history->content->getSelectedUrl()
);
$address->update();
}
}

28
src/Entity/Window/Tab/History/Navbar/Search.php

@ -1,28 +0,0 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\History\Navbar;
class Search extends \Yggverse\Yoda\Abstract\Entity\Window\Tab\History\Navbar\Button
{
protected bool $_sensitive = true;
protected string $_label = 'Search';
protected function _onCLick(
\GtkButton $entity
): void
{
$this->gtk->set_sensitive(
false
);
$this->navbar->history->content->search(
$this->navbar->filter->gtk->get_text()
);
$this->gtk->set_sensitive(
true
);
}
}

46
src/Entity/Window/Tab/History/Title.php

@ -1,46 +0,0 @@
<?php
declare(strict_types=1);
namespace Yggverse\Yoda\Entity\Window\Tab\History;
class Title
{
public \GtkLabel $gtk;
public \Yggverse\Yoda\Entity\Window\Tab\History $history;
// Defaults
private int $_ellipsize = 0;
private int $_length = 12;
private string $_value = 'History';
public function __construct(
\Yggverse\Yoda\Entity\Window\Tab\History $history
) {
$this->history = $history;
$this->gtk = new \GtkLabel(
$this->_value
);
$this->gtk->set_width_chars(
$this->_length
);
$this->gtk->set_ellipsize(
$this->_ellipsize
);
}
public function setValue(
?string $value = null
): void
{
$this->gtk->set_text(
is_null($value) ? $this->_value : trim(
$value
)
);
}
}

2
src/Model/Database.php

@ -123,7 +123,7 @@ class Database
return $query->rowCount(); return $query->rowCount();
} }
public function refreshHistory( public function renewHistory(
string $url, string $url,
?string $title = null ?string $title = null
): void ): void

15
src/Yoda.php

@ -23,12 +23,12 @@ $database = new \Yggverse\Yoda\Model\Database(
// Init GTK // Init GTK
\Gtk::init(); \Gtk::init();
// Init window // Init browser
$window = new \Yggverse\Yoda\Entity\Window( $browser = new \Yggverse\Yoda\Entity\Browser(
$database $database
); );
$window->gtk->connect( $browser->gtk->connect(
'destroy', 'destroy',
function() function()
{ {
@ -36,4 +36,13 @@ $window->gtk->connect(
} }
); );
$browser->gtk->show_all();
// Init history (test)
$history = new \Yggverse\Yoda\Entity\Browser\History(
$browser
);
$history->gtk->show_all();
\Gtk::main(); \Gtk::main();
Loading…
Cancel
Save