<?phpnamespace App\Ui;use JumPHP\Kernel\Engine;use JumPHP\Renderer\Renderer;use JumPHP\Renderer\TtfFont;use JumPHP\Util\Lang;/** * The look of the example: its languages, the font of each (Lato for the Latin and Cyrillic ones, Noto Sans subsets for Japanese, Chinese * and Korean: assets/fonts/), its colours and its buttons (a click, a tap, or the keys). */final class Look{ /** The playground's languages, each named in itself. */ public const LANGUAGES = [ 'en' => 'English', 'fr' => 'Français', 'es' => 'Español', 'de' => 'Deutsch', 'it' => 'Italiano', 'pt' => 'Português', 'nl' => 'Nederlands', 'pl' => 'Polski', 'ru' => 'Русский', 'uk' => 'Українська', 'tr' => 'Türkçe', 'ja' => '日本語', 'zh' => '中文', 'ko' => '한국어', ]; private const FONTS = ['ja' => 'ja.ttf', 'zh' => 'zh.ttf', 'ko' => 'ko.ttf']; public const BG = [10, 12, 24]; public const PANEL = [22, 26, 48]; public const LINE = [70, 80, 130]; public const TEXT = [235, 238, 255]; public const MUTED = [150, 156, 196]; public const ACCENT = [90, 200, 255]; public const ME = [64, 214, 128]; public const OTHER = [255, 150, 64]; public const STAR = [255, 220, 80]; private static string $fontLang = ''; /** The font of the current language, made the engine's default one (menus, the lobby). Call it in enter() (with its params) and after a language change. */ public static function apply(Engine $engine, array $params = []): void { if (isset($params['lang']) && isset(self::LANGUAGES[(string)$params['lang']])) { $engine->lang->setLang((string)$params['lang']); // shots and tests: JUMPHP_SCENE_PARAMS='{"lang":"ja"}' } $lang = $engine->lang->getLang(); if (!isset(self::LANGUAGES[$lang])) { $engine->lang->setLang($lang = 'en'); } if (self::$fontLang === $lang) { return; } self::$fontLang = $lang; $file = 'assets/fonts/' . (self::FONTS[$lang] ?? 'ui.ttf'); $engine->setFont(new TtfFont($engine->sdl, $file, 8, true)); } public static function setLang(Engine $engine, string $lang): void { $engine->lang->setLang($lang); $engine->options->set('lang', $lang); self::apply($engine); } /** The next / previous language of the list. */ public static function cycle(Engine $engine, int $dir): void { $codes = array_keys(self::LANGUAGES); $i = array_search($engine->lang->getLang(), $codes, true); $i = $i === false ? 0 : $i; self::setLang($engine, $codes[($i + $dir + count($codes)) % count($codes)]); } /** A button: its box, its text (translated), lit when selected. */ public static function button(Renderer $r, Engine $engine, float $x, float $y, float $w, float $h, string $text, bool $lit = false): void { $r->fillRect($x, $y, $w, $h, $lit ? [40, 70, 120] : self::PANEL); $r->drawRect($x, $y, $w, $h, $lit ? self::ACCENT : self::LINE); $font = $engine->font(); $font->draw($r, $text, $x + $w / 2, $y + ($h - $font->height()) / 2, 1, $lit ? [255, 255, 255] : self::TEXT, 'center'); } /** Is the mouse (or a finger: touches are clicks) inside this box, and pressed this frame? */ public static function clicked(Engine $engine, float $x, float $y, float $w, float $h): bool { $m = $engine->input->getMouse(); return $m->isPressed(1) && $m->x >= $x && $m->x <= $x + $w && $m->y >= $y && $m->y <= $y + $h; } public static function hover(Engine $engine, float $x, float $y, float $w, float $h): bool { $m = $engine->input->getMouse(); return $m->x >= $x && $m->x <= $x + $w && $m->y >= $y && $m->y <= $y + $h; } /** The "< Menu" button of every screen: a click on it, or Escape. */ public static function menuPressed(Engine $engine): bool { return $engine->actions->isPressed('back') || self::clicked($engine, 3, 3, 46, 12); } public static function menuButton(Renderer $r, Engine $engine): void { self::button($r, $engine, 3, 3, 46, 12, '< ' . Lang::t('Menu'), self::hover($engine, 3, 3, 46, 12)); } /** A connection state, translated (new, connecting, connected, disconnected, failed, closed). */ public static function state(string $state): string { return Lang::t('state:' . $state); } public static function stateColor(string $state): array { return match ($state) { 'connected' => self::ME, 'connecting', 'new', '' => self::STAR, default => [240, 80, 80], }; }}