mirror of
https://github.com/YGGverse/Yoda.git
synced 2026-03-31 16:45:27 +00:00
implement custom word wrap for text blocks
This commit is contained in:
parent
f81cf9fdee
commit
7ec3d06db9
4 changed files with 85 additions and 65 deletions
|
|
@ -18,11 +18,7 @@ abstract class Markup
|
|||
// Dependencies
|
||||
public Content $content;
|
||||
|
||||
// Defaults
|
||||
public const WRAP = 140;
|
||||
|
||||
// Extras
|
||||
protected int $_wrap = self::WRAP;
|
||||
protected ?string $_source = null;
|
||||
|
||||
public function __construct(
|
||||
|
|
@ -113,11 +109,18 @@ abstract class Markup
|
|||
return false;
|
||||
}
|
||||
|
||||
// Require custom wordwrap implementation on widget resize
|
||||
abstract protected function _onSizeAllocate(
|
||||
// Custom wordwrap on widget resize
|
||||
protected function _onSizeAllocate(
|
||||
GtkLabel $label,
|
||||
GdkEvent $event
|
||||
): bool;
|
||||
): bool
|
||||
{
|
||||
$this->set( // @TODO Gtk::timeout_add
|
||||
$this->_source
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Require custom layout implementation
|
||||
abstract public function set(
|
||||
|
|
@ -125,61 +128,6 @@ abstract class Markup
|
|||
): void;
|
||||
|
||||
// Tools
|
||||
protected function _line(
|
||||
int $offset
|
||||
): ?string
|
||||
{
|
||||
if (is_null($this->_source))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$start = strrpos(
|
||||
substr(
|
||||
$this->_source,
|
||||
0,
|
||||
$offset
|
||||
),
|
||||
PHP_EOL
|
||||
) + 1;
|
||||
|
||||
$end = strpos(
|
||||
$this->_source,
|
||||
PHP_EOL,
|
||||
$offset
|
||||
);
|
||||
|
||||
if ($end === false)
|
||||
{
|
||||
$end = strlen(
|
||||
$this->_source
|
||||
);
|
||||
}
|
||||
|
||||
return substr(
|
||||
$this->_source,
|
||||
$start,
|
||||
$end - $start
|
||||
);
|
||||
}
|
||||
|
||||
protected function _wrap(
|
||||
string $source
|
||||
): string
|
||||
{
|
||||
if ($wrap = $this->_wrap ? $this->_wrap : $this::WRAP)
|
||||
{
|
||||
return wordwrap(
|
||||
$source,
|
||||
$wrap,
|
||||
PHP_EOL,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
throw new Exception;
|
||||
}
|
||||
|
||||
protected function _url(
|
||||
string $link
|
||||
): ?string
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ declare(strict_types=1);
|
|||
|
||||
namespace Yggverse\Yoda\Abstract\Model\Gtk\Pango;
|
||||
|
||||
use \PangoLayout;
|
||||
use \GtkDrawingArea;
|
||||
|
||||
class Markup implements \Yggverse\Yoda\Interface\Model\Gtk\Pango\Markup
|
||||
{
|
||||
public static function code(
|
||||
|
|
@ -99,11 +102,15 @@ class Markup implements \Yggverse\Yoda\Interface\Model\Gtk\Pango\Markup
|
|||
}
|
||||
|
||||
public static function text(
|
||||
string $value
|
||||
string $value,
|
||||
int $width = self::WRAP_WIDTH
|
||||
): string
|
||||
{
|
||||
return htmlspecialchars(
|
||||
$value
|
||||
self::_wrap(
|
||||
$value,
|
||||
$width
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -131,4 +138,62 @@ class Markup implements \Yggverse\Yoda\Interface\Model\Gtk\Pango\Markup
|
|||
|
||||
throw new Exception;
|
||||
}
|
||||
|
||||
public static function width(
|
||||
string $markup
|
||||
): ?int
|
||||
{
|
||||
$layout = new PangoLayout(
|
||||
(new GtkDrawingArea)->create_pango_context()
|
||||
);
|
||||
|
||||
$layout->set_markup(
|
||||
$markup,
|
||||
mb_strlen(
|
||||
$markup,
|
||||
'UTF-8'
|
||||
)
|
||||
);
|
||||
|
||||
if ($size = $layout->get_pixel_size())
|
||||
{
|
||||
return $size['width'];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static function _wrap(
|
||||
string $string,
|
||||
int $width = self::WRAP_WIDTH,
|
||||
int $line = 1
|
||||
): string
|
||||
{
|
||||
$words = [];
|
||||
|
||||
foreach (explode(' ', $string) as $word)
|
||||
{
|
||||
if (isset($words[$line]) && Markup::width(implode(' ', $words[$line])) > $width)
|
||||
{
|
||||
$line++;
|
||||
}
|
||||
|
||||
$words[$line][] = $word;
|
||||
}
|
||||
|
||||
$lines = [];
|
||||
|
||||
foreach ($words as $values)
|
||||
{
|
||||
$lines[] = implode(
|
||||
' ',
|
||||
$values
|
||||
);
|
||||
}
|
||||
|
||||
return implode(
|
||||
PHP_EOL,
|
||||
$lines
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -180,7 +180,8 @@ class Gemtext extends \Yggverse\Yoda\Abstract\Entity\Browser\Container\Page\Cont
|
|||
else
|
||||
{
|
||||
$line[] = Markup::text(
|
||||
$entity->getData()
|
||||
$entity->getData(),
|
||||
$this->content->page->gtk->get_allocated_width()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ interface Markup
|
|||
{
|
||||
public const TAG_CODE = 'tt';
|
||||
|
||||
public const WRAP_WIDTH = 140;
|
||||
|
||||
public static function code(
|
||||
string $value
|
||||
): string;
|
||||
|
|
@ -54,4 +56,8 @@ interface Markup
|
|||
string $const,
|
||||
bool $close
|
||||
): string;
|
||||
|
||||
public static function width(
|
||||
string $markup
|
||||
): ?int;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue