Skip to content

Releases: aratakileo/pygex

v0.3.3 - moving to pygame-ce

13 May 17:01
Compare
Choose a tag to compare

pygex - v0.3.3

Code from preview
import pygame
import pygex


window = pygex.Window(fps_limit=120)
fullscreen_toast = pygex.Toast('To exit full screen press [F11]')
debug_panel = pygex.DebugPanel(is_demonstration_mode=False)

some_textview = pygex.gui.TextView(
    'Where is the incredible GUI kit for pygame? Right here is pygex!',
    size=(pygex.gui.SIZE_MATCH_PARENT,) * 2,
    text_line_spacing=10,
    text_align=pygex.gui.ALIGN_CENTER,
    content_gravity=pygex.gui.GRAVITY_CENTER,
    text_color=pygex.color.COLOR_WHITE,
    font_or_font_size=55,
    background_drawable_or_color=pygex.gui.drawable.GradientDrawable(
        pygex.color.GRADIENT_WITCHING_HOUR[::-1]
    )
)

window.add_view(some_textview)
debug_panel.apply_on_screen()

if debug_panel.is_demonstration_mode:
    from pygex.surface_recorder import SurfaceRecorder
    surface_recorder = SurfaceRecorder(window.size, window.fps_limit)

    window.resizable = False

while True:
    window.render_views()

    if window.input.is_up(pygame.K_F1):
        window.take_screenshot()
    elif window.input.is_up(pygame.K_F11):
        window.fullscreen = not window.fullscreen

        if window.fullscreen:
            fullscreen_toast.show()
        else:
            fullscreen_toast.cancel()
    elif window.input.is_up(pygame.K_F5) and debug_panel.is_demonstration_mode:
        if surface_recorder.is_recording:
            surface_recorder.pause_record()
            surface_recorder.save()

            window.show_toast('Record stopped and saved!')
        else:
            surface_recorder.start_record()

            window.show_toast('Record started!')

    window.flip()

    if debug_panel.is_demonstration_mode:
        surface_recorder.process_frame(window.surface)

What's new?

  • The move from pygame to pygame-ce for better experience
  • New DebugPanel widget for displaying debug information
  • Refactor Hint:
    • Now it is displayed on top of the entire render and interface (like Toast).
    • A more correct and convenient programming interface for implementing it.
    • Other changes
  • Refactor Views:
    • Fixed a bug when changing visibility from any to GONE or vice versa, the corresponding changes did not affect the parent in any way. The same applies to changing padding and margin values
    • Fixed bug with no update background surface after content surface size has changes
    • Other changes
  • Fixed cyclic import for Window, Input, Mouse due to the use of the broker module
  • Other changes

Install this release

pip install https://github.com/aratakileo/pygex/archive/refs/tags/v0.3.3.zip
for windows
py -m pip install https://github.com/aratakileo/pygex/archive/refs/tags/v0.3.3.zip
for unix/macos
python3 -m pip install https://github.com/aratakileo/pygex/archive/refs/tags/v0.3.3.zip

pygex v0.3.2

08 May 21:20
Compare
Choose a tag to compare

pygex

Install this release

pip install https://github.com/aratakileo/pygex/archive/refs/tags/v0.3.2.zip

Demonstration of the features of the version

from platform import python_version
import pygame
import pygex


preview_mode = True

window = pygex.Window()
window.fps_limit = 120

fullscreen_toast = pygex.Toast('To exit full screen press [F11]')

some_textview = pygex.gui.TextView(
    'Where is the incredible interface kit for pygame? Right here is pygex!',
    size=(pygex.gui.SIZE_MATCH_PARENT,) * 2,
    text_line_spacing=-2,
    text_align=pygex.gui.ALIGN_CENTER,
    content_gravity=pygex.gui.GRAVITY_CENTER,
    text_color=pygex.color.COLOR_WHITE,
    font_or_font_size=55,
    background_drawable_or_color=pygex.gui.drawable.GradientDrawable(
        pygex.color.GRADIENT_WITCHING_HOUR.TUPLE[::-1]
    )
)

recording_debug_text = '\n[f5] - start/stop window record' if preview_mode else ''
debug_text = 'DEBUG INFO:' \
    '\nv%s pygex' \
    '\nv%s pygame' \
    '\nv%s python' \
    '\n%sfps' \
    '\n\nis preview mode - %s' \
    '\n\n' \
    '\nSHORTCUTS:' \
    '\n[f1] - take screenshot' \
    '\n[f2] - show/hide this menu' \
    f'{recording_debug_text}' \
    '\n[f11] - switch screen mode'

debug_textview = pygex.gui.TextView(
    debug_text,
    text_color=pygex.color.COLOR_WHITE,
    background_drawable_or_color=pygex.gui.drawable.ColorDrawable(
        pygex.color.set_alpha(pygex.color.COLOR_BLACK, 0xaa),
        border_radius_or_radii=(0,) * 3 + (10,)
    ),
    prerender_during_initialization=False
)

debug_close_button = pygex.gui.ButtonView(
    'X',
    size=(25,) * 2,
    padding=pygex.gui.NO_PADDING,
    margin=(5,) + (0,) * 3,
    background_drawable_or_color=pygex.gui.buttonview.ButtonFadingDrawable(
        pygex.color.COLOR_RED,
        border_radius_or_radii=90
    ),
    prerender_during_initialization=False
)
debug_close_button.set_hint(
    'Close debug menu',
    hint_gravity=pygex.gui.Hint.GRAVITY_LEFT | pygex.gui.Hint.GRAVITY_UNDER_CENTER
)

debug_linearlayout = pygex.gui.LinearLayout(
    (debug_textview, debug_close_button),
    padding=pygex.gui.NO_PADDING,
    orientation=pygex.gui.ORIENTATION_HORIZONTAL,
    content_gravity=pygex.gui.GRAVITY_CENTER_VERTICAL
)

just_button = pygex.gui.ButtonView(
    'Just button',
    font_or_font_size=pygex.gui.textview.DEFAULT_FONT_SIZE + 10,
    background_drawable_or_color=pygex.color.COLOR_DEEP_PURPLE,
    padding=(14,) * 4,
    margin=(5,) * 2 + (0,) * 2
)
just_button.y = debug_linearlayout.get_computed_background_height()
just_button.width = debug_linearlayout.get_computed_background_width() - 40


window.add_view(some_textview)
window.add_view(debug_linearlayout)
window.add_view(just_button)

if preview_mode:
    from pygex.surface_recorder import SurfaceRecorder
    surface_recorder = SurfaceRecorder(window.size, window.fps_limit)

    window.resizable = False


while True:
    debug_textview.set_text(
        debug_text % (
            pygex.ver,
            pygame.ver,
            python_version(),
            window.fps.__str__() if window.fps_limit is None else f'{window.fps:.3f}/{window.fps_limit}',
            preview_mode.__str__().lower()
        )
    )

    if debug_close_button.is_clicked or window.input.is_up(pygame.K_F2):
        if debug_textview.visibility == pygex.gui.VISIBILITY_GONE:
            debug_textview.visibility = pygex.gui.VISIBILITY_VISIBLE

            debug_close_button.set_text('X')
            debug_close_button.set_background_drawable(pygex.gui.buttonview.ButtonFadingDrawable(
                pygex.color.COLOR_RED,
                border_radius_or_radii=90
            ))
            debug_close_button.set_hint('Close debug menu')
        elif debug_textview.visibility == pygex.gui.VISIBILITY_VISIBLE:
            debug_textview.visibility = pygex.gui.VISIBILITY_GONE

            debug_close_button.set_text('O')
            debug_close_button.set_background_drawable(pygex.gui.buttonview.ButtonFadingDrawable(
                pygex.color.COLOR_DEEP_PURPLE,
                border_radius_or_radii=90
            ))
            debug_close_button.set_hint('Open debug menu')

    if just_button.is_clicked:
        window.show_toast(f'You clicked "{just_button.text_renderer.get_text()}"')

    window.render_views()

    if preview_mode:
        surface_recorder.process_frame(window.surface)

    if window.input.is_up(pygame.K_F1):
        window.take_screenshot()
    elif window.input.is_up(pygame.K_F11):
        window.fullscreen = not window.fullscreen

        if window.fullscreen:
            fullscreen_toast.show()
        else:
            fullscreen_toast.cancel()
    elif window.input.is_up(pygame.K_F5) and preview_mode:
        if surface_recorder.is_recording:
            surface_recorder.stop_record()
            surface_recorder.save()

            window.show_toast('Record stopped and saved!')
        else:
            surface_recorder.start_record()

            window.show_toast('Record started!')

    window.flip()

pygex v0.3.1

19 Feb 15:22
Compare
Choose a tag to compare

pygex

Install this release

pip install https://github.com/aratakileo/pygex/archive/refs/tags/v0.3.1.zip

Demonstration of the features of the version

from platform import python_version
from pygex.info import pygex_ver
import pygame
import pygex

preview_mode = False

window = pygex.Window()
window.fps_limit = 120

fullscreen_toast = pygex.Toast('To exit full screen press [F11]')

some_textview = pygex.gui.TextView(
    'Where is the incredible interface kit for pygame? Right here is pygex!',
    size=(pygex.gui.SIZE_MATCH_PARENT, pygex.gui.SIZE_MATCH_PARENT),
    text_line_spacing=-2,
    text_align=pygex.gui.ALIGN_CENTER,
    content_gravity=pygex.gui.GRAVITY_CENTER_HORIZONTAL | pygex.gui.GRAVITY_CENTER_VERTICAL,
    text_color=0xcaf0f8,
    font_or_font_size=50,
    background_drawable_or_color=pygex.gui.drawable.GradientDrawable(
        (0xcaf0f8, 0x00b4d8, 0xcaf0f8),
        border_width=10,
        border_color=0xcaf0f8,
        is_vertical=True
    )
)

recording_debug_text = '\n[f5] - start/stop window record' if preview_mode else ''
debug_text = 'DEBUG INFO:' \
    '\nv%s pygex' \
    '\nv%s pygame' \
    '\nv%s python' \
    '\n%sfps' \
    '\n\npreview mode: %a' \
    '\n\n' \
    '\nSHORTCUTS:' \
    '\n[f1] - take screenshot' \
    '\n[f2] - show/hide this menu' \
    f'{recording_debug_text}' \
    '\n[f11] - switch screen mode'

debug_textview = pygex.gui.TextView(
    debug_text,
    text_color=pygex.color.C_WHITE,
    background_drawable_or_color=pygex.gui.drawable.ColorDrawable(
        0xaa000000,
        border_radius_or_radii=(0, 0, 0, 10)
    ),
    render_content_during_initialization=False
)

debug_button = pygex.gui.View(
    size=(20, 20),
    pos=(5, 5),
    padding=(0, 0, 0, 0),
    content_gravity=0,
    background_drawable_or_color=pygex.gui.drawable.InteractionDrawable(
        pygex.gui.drawable.ColorDrawable(pygex.color.C_RED, border_radius_or_radii=90)
    ),
    render_content_during_initialization=False
)
debug_button.set_hint(
    'Close debug menu',
    hint_gravity=pygex.gui.Hint.GRAVITY_LEFT | pygex.gui.Hint.GRAVITY_UNDER_CENTER
)


def open_or_close_debug_menu():
    if debug_textview.visibility == pygex.gui.VISIBILITY_GONE:
        debug_textview.visibility = pygex.gui.VISIBILITY_VISIBLE
        debug_button.set_hint('Close debug menu')
    elif debug_textview.visibility == pygex.gui.VISIBILITY_VISIBLE:
        debug_textview.visibility = pygex.gui.VISIBILITY_GONE
        debug_button.set_hint('Open debug menu')
        debug_button.x = 5


window.add_view(some_textview)
window.add_view(debug_textview)
window.add_view(debug_button)


if preview_mode:
    from pygex.surface_recorder import SurfaceRecorder
    surface_recorder = SurfaceRecorder(window.size, window.fps_limit)

    window.resizable = False


while True:
    debug_textview.text_renderer.set_text(
        debug_text % (
            pygex_ver,
            pygame.ver,
            python_version(),
            window.fps.__str__() if window.fps_limit is None else f'{window.fps:.3f}/{window.fps_limit}',
            preview_mode
        )
    )

    if debug_button.x == 5 and debug_textview.visibility == pygex.gui.VISIBILITY_VISIBLE:
        debug_button.x += debug_textview.get_computed_background_width()

    if debug_button.is_clicked or window.input.is_up(pygame.K_F2):
        open_or_close_debug_menu()

    window.render_views()

    if preview_mode:
        surface_recorder.process_frame(window.surface)

    if window.input.is_up(pygame.K_F1):
        window.take_screenshot()
    elif window.input.is_up(pygame.K_F11):
        window.fullscreen = not window.fullscreen

        if window.fullscreen:
            fullscreen_toast.show()
        else:
            fullscreen_toast.cancel()
    elif window.input.is_up(pygame.K_F5) and preview_mode:
        if surface_recorder.is_recording:
            surface_recorder.stop_record()
            surface_recorder.save()

            window.show_toast('Record stopped and saved!')
        else:
            surface_recorder.start_record()

            window.show_toast('Record started!')

    window.flip()

pygex v0.3

19 Feb 11:18
Compare
Choose a tag to compare

pygex

Install this release

pip install https://github.com/aratakileo/pygex/archive/refs/tags/v0.3.zip

Demonstration of the features of the version

from pygex.info import pygex_ver
import pygame
import pygex


window = pygex.Window()
window.fps_limit = 120

fullscreen_toast = pygex.Toast('To exit full screen press [F11]')

some_textview = pygex.gui.TextView(
    'Where is the incredible interface kit for pygame? Right here is pygex!',
    size=(pygex.gui.SIZE_MATCH_PARENT, pygex.gui.SIZE_MATCH_PARENT),
    text_line_spacing=-2,
    text_align=pygex.gui.ALIGN_CENTER,
    content_gravity=pygex.gui.GRAVITY_CENTER_HORIZONTAL | pygex.gui.GRAVITY_CENTER_VERTICAL,
    text_color=0xcaf0f8,
    font_or_font_size=50,
    background_drawable_or_color=pygex.gui.drawable.GradientDrawable(
        (0xcaf0f8, 0x00b4d8, 0xcaf0f8),
        border_width=10,
        border_color=0xcaf0f8,
        is_vertical=True
    )
)

debug_text = '=========DEBUG MENU=========' \
    '\n - pygex: v%s' \
    '\n - %s/%ifps' \
    '\n\n' \
    '\n=========SHORTCUTS==========' \
    '\n - press [f1] to take screenshot' \
    '\n - press [f2] to show/hide this menu' \
    '\n - press [f11] to switch screen mode'

debug_textview = pygex.gui.TextView(
    debug_text,
    text_color=pygex.color.C_WHITE,
    background_drawable_or_color=pygex.gui.drawable.ColorDrawable(
        0xaa000000,
        border_radius_or_radii=(0, 0, 0, 10)
    ),
    render_content_during_initialization=False
)


debug_button = pygex.gui.ButtonView('[!]', pos=(5, 5), render_content_during_initialization=False)
debug_button.get_background_drawable().get_content_drawable().set_border_radius(90)
debug_button.get_background_drawable().get_content_drawable().color = pygex.color.C_RED | 0xaa000000
debug_button.set_hint(
    'Close debug menu',
    hint_gravity=pygex.gui.Hint.GRAVITY_LEFT | pygex.gui.Hint.GRAVITY_UNDER_CENTER
)


def open_or_close_debug_menu():
    if debug_textview.visibility == pygex.gui.VISIBILITY_GONE:
        debug_textview.visibility = pygex.gui.VISIBILITY_VISIBLE
        debug_button.set_hint('Close debug menu')
    elif debug_textview.visibility == pygex.gui.VISIBILITY_VISIBLE:
        debug_textview.visibility = pygex.gui.VISIBILITY_GONE
        debug_button.set_hint('Open debug menu')
        debug_button.x = 5


window.add_view(some_textview)
window.add_view(debug_textview)
window.add_view(debug_button)


while True:
    debug_textview.set_text(debug_text % (pygex_ver, f'{window.fps:.3f}', window.fps_limit))

    if debug_button.x == 5 and debug_textview.visibility == pygex.gui.VISIBILITY_VISIBLE:
        debug_button.x += debug_textview.get_computed_background_width()

    if debug_button.is_clicked or window.input.is_up(pygame.K_F2):
        open_or_close_debug_menu()

    window.render_views()

    if window.input.is_up(pygame.K_F1):
        window.take_screenshot()
    elif window.input.is_up(pygame.K_F11):
        window.fullscreen = not window.fullscreen

        if window.fullscreen:
            fullscreen_toast.show()
        else:
            fullscreen_toast.cancel()

    window.flip()

pygex v0.2.dev3

23 Dec 13:49
Compare
Choose a tag to compare
pygex v0.2.dev3 Pre-release
Pre-release

pygex

Install

pip install https://github.com/aratakileo/pygex/archive/refs/tags/v0.2.dev3.zip

Example code

import pygame
import pygex


window = pygex.Window()
window.bg_color = 0xffffff
window.fps_limit = 120

fullscreen_toast = pygex.Toast('To exit full screen press [F11]')

some_textview = pygex.gui.TextView(
    'Um... Excuse me? What you actually doing in my house? Please leave now!',
    size=(pygex.gui.SIZE_MATCH_PARENT, pygex.gui.SIZE_MATCH_PARENT),
    text_line_spacing=-2,
    text_align=pygex.gui.ALIGN_CENTER,
    content_gravity=pygex.gui.GRAVITY_CENTER_HORIZONTAL | pygex.gui.GRAVITY_CENTER_VERTICAL,
    text_color=0xcaf0f8,
    font_or_font_size=50,
    background_drawable_or_color=pygex.gui.GradientDrawable(
        (0xcaf0f8, 0x00b4d8, 0xcaf0f8),
        border_width=10,
        border_color=0xcaf0f8,
        is_vertical=True
    )
)
some_textview.render_content_surface()

fps_counter_text = '=========DEBUG MENU=========' \
    '\n - pygex: v0.2.dev3' \
    '\n - %s/%ifps' \
    '\n\n' \
    '\n=========SHORTCUTS==========' \
    '\n - press [f1] to take screenshot' \
    '\n - press [f2] to show/hide this menu' \
    '\n - press [f11] to switch screen mode'

fps_counter_textview = pygex.gui.TextView(
    '',
    text_color=pygex.color.WHITE,
    background_drawable_or_color=pygex.gui.ColorDrawable(
        0xaa000000,
        border_radius_or_radii=(0, 0, 0, 10)
    )
)


show_debug_info = True


while True:
    fps_counter_textview.text_renderer.set_text(fps_counter_text % (f'{window.fps:.3f}', window.fps_limit))
    fps_counter_textview.apply_text_surface_changes()

    some_textview.render(window.surface)

    if show_debug_info:
        fps_counter_textview.render(window.surface)

    if window.input.is_up(pygame.K_F1):
        window.take_screenshot()
    elif window.input.is_up(pygame.K_F2):
        show_debug_info = not show_debug_info
    elif window.input.is_up(pygame.K_F11):
        window.fullscreen = not window.fullscreen

        if window.fullscreen:
            fullscreen_toast.show()
        else:
            fullscreen_toast.cancel()

    window.flip()

pygex v0.2.dev2

11 Dec 19:24
Compare
Choose a tag to compare
pygex v0.2.dev2 Pre-release
Pre-release

pygex

Install

pip install https://github.com/aratakileo/pygex/archive/refs/tags/v0.2.dev2.zip

Example code

import pygame
import pygex


window = pygex.Window()
window.bg_color = 0xffffff
window.fps_limit = 120

fullscreen_toast = pygex.Toast('To exit full screen press [F11]')

some_textview = pygex.gui.TextView(
    'Um... Excuse me? What you actually doing in my house? Please leave now!',
    size=(pygex.gui.SIZE_MATCH_PARENT, pygex.gui.SIZE_MATCH_PARENT),
    padding=(8, 200, 8, 8),
    text_line_spacing=-2,
    text_align=pygex.gui.ALIGN_CENTER,
    content_gravity=pygex.gui.GRAVITY_CENTER_HORIZONTAL | pygex.gui.GRAVITY_CENTER_VERTICAL,
    text_color=0xcaf0f8,
    font_or_font_size=50,
    background_drawable_or_color=pygex.gui.GradientDrawable(
        (0xcaf0f8, 0x00b4d8, 0xcaf0f8),
        border_width=10,
        border_color=0xcaf0f8,
        is_vertical=True
    )
)
some_textview.render_content_surface()

fps_counter_textview = pygex.gui.TextView(
    '=========DEBUG MENU========='
    '\n - pygex: v0.2.dev2'
    '\n - %s/%ifps'
    '\n\n'
    '\n=========SHORTCUTS=========='
    '\n - press [f1] to take screenshot'
    '\n - press [f2] to show/hide this menu'
    '\n - press [f11] to switch screen mode',
    text_color=pygex.color.WHITE,
    background_drawable_or_color=pygex.gui.ColorDrawable(
        0xaa000000,
        border_radius_or_radii=(0, 0, 0, 10)
    )
)


show_debug_info = True


while True:
    fps_counter_textview.format_text(f'{window.fps:.3f}', window.fps_limit)

    some_textview.render(window.surface)

    if show_debug_info:
        fps_counter_textview.render(window.surface)

    if window.input.is_up(pygame.K_F1):
        window.take_screenshot()
    elif window.input.is_up(pygame.K_F2):
        show_debug_info = not show_debug_info
    elif window.input.is_up(pygame.K_F11):
        window.fullscreen = not window.fullscreen

        if window.fullscreen:
            fullscreen_toast.show()
        else:
            fullscreen_toast.cancel()

    window.flip()

pygex v0.2.dev1

10 Dec 19:38
Compare
Choose a tag to compare
pygex v0.2.dev1 Pre-release
Pre-release

pygex

What's new?

  • added colors library
  • added View and TextView interfaces to pygex.gui
  • added Drawable, ColorDrawable and GradientDrawable interfaces to pygex.gui
  • code in text.py has been refactored

Install

pip install https://github.com/aratakileo/pygex/archive/refs/tags/v0.2.dev1.zip

Example code

from pygex.gui.drawable import ColorDrawable, GradientDrawable
from pygex.gui import textview
from pygex.gui import view
from pygex import color
import pygame
import pygex


window = pygex.Window()
window.bg_color = 0xffffff
window.fps_limit = 120

fullscreen_toast = pygex.Toast('To exit full screen press [F11]')

some_textview = textview.TextView(
    'Um... Excuse me? What you actually doing in my house?'
    '\nPlease leave now!',
    size=(400, 400),
    text_paragraph_space=50,
    text_line_spacing=25,
    text_align=textview.ALIGN_BLOCK,
    content_gravity=view.GRAVITY_CENTER_HORIZONTAL | view.GRAVITY_CENTER_VERTICAL,
    text_color=0xcaf0f8,
    font_or_font_size=30,
    background_drawable_or_color=GradientDrawable(
        (0xcaf0f8, 0x00b4d8, 0xcaf0f8),
        border_radius_or_radii=10,
        border_width=5,
        border_color=0xcaf0f8,
        is_vertical=True
    )
)
some_textview.render_content_surface()

fps_counter_textview = textview.TextView(
    '=========DEBUG MENU========='
    '\n - pygex: v0.2.dev1'
    '\n - %s/%ifps'
    '\n\n'
    '\n=========SHORTCUTS=========='
    '\n - press [f1] to take screenshot'
    '\n - press [f2] to show/hide this menu'
    '\n - press [f11] to switch screen mode',
    text_color=color.WHITE,
    background_drawable_or_color=ColorDrawable(
        0xaa000000,
        border_radius_or_radii=(0, 0, 0, 10)
    )
)


show_debug_info = True


while True:
    fps_counter_textview.format_text(f'{window.fps:.3f}', window.fps_limit)

    some_textview.x = (window.width - some_textview.background_width) / 2
    some_textview.y = (window.height - some_textview.background_height) / 2

    some_textview.render(window.surface)

    if show_debug_info:
        fps_counter_textview.render(window.surface)

    if window.input.is_up(pygame.K_F1):
        window.take_screenshot()
    elif window.input.is_up(pygame.K_F2):
        show_debug_info = not show_debug_info
    elif window.input.is_up(pygame.K_F11):
        window.fullscreen = not window.fullscreen

        if window.fullscreen:
            fullscreen_toast.show()
        else:
            fullscreen_toast.cancel()

    window.flip()

pygex v0.2

04 Dec 11:13
Compare
Choose a tag to compare

pygex

Install

pip install https://github.com/aratakileo/pygex/archive/refs/tags/v0.2.zip

Example code

from typing import Sequence
import pygex.image
import pygex.text
import pygame
import pygex


def render_text(_header_text: str, _text: str, size: Sequence[int], _agent_rect: pygame.Rect, _agent_moved: bool):
    output_surface = pygex.image.gradient(size, (0xffc107, 0xfff3e0), is_vertical=True)

    pygex.text.get_pygame_font(50).bold = True

    _header_text_surface = pygex.text.render_aligned_text(
        _header_text,
        0xffb300,
        size[0],
        50,
        pygex.text.ALIGN_CENTER
    )

    pygex.text.get_pygame_font(35).italic = True

    _text_surface = pygex.text.render_aligned_text(
        _text,
        0xffffff,
        size[0],
        35,
        pygex.text.ALIGN_CENTER
    )

    text_height = _header_text_surface.get_height() + _text_surface.get_height()
    header_text_y = max((size[1] - text_height) / 2 - _header_text_surface.get_height() * 2, 0)
    text_y = header_text_y + _header_text_surface.get_height()

    if not _agent_moved:
        _agent_text_surface = pygex.text.render_text('Hold, press [w,a,s,d] or drag by mouse to move «     »', 0x80deea, 35)
        _agent_text_surface_y = text_y + _text_surface.get_height() + _agent_text_surface.get_height() * 2
        _agent_text_surface_x = (size[0] - _agent_text_surface.get_width()) / 2

        output_surface.blit(_agent_text_surface, (_agent_text_surface_x, _agent_text_surface_y))

        _agent_rect.x = _agent_text_surface_x + _agent_text_surface.get_width() - _agent_rect.width - 20
        _agent_rect.y = _agent_text_surface_y

    output_surface.blit(_header_text_surface, (0, header_text_y))
    output_surface.blit(_text_surface, (0, text_y))

    return output_surface, pygex.image.blur(output_surface, 10)


window = pygex.Window()
window.bg_color = 0xffffff
window.fps_limit = 120


agent_moved = False
agent_rect = pygame.Rect(0, 0, 25, 25)
agent_dragging = False


fullscreen_toast = pygex.Toast('To exit full screen press [F11]')

header_text = 'Welcome to pygex example!'
text = '''- press [f11] to enter full screen -
- press [f1] to take screenshot -
- hold [f2] to blur text -'''


text_surface, blured_text_surface = render_text(header_text, text, window.size, agent_rect, agent_moved)
old_window_size = window.size


def rerender_screen_bg():
    global text_surface, blured_text_surface
    text_surface, blured_text_surface = render_text(header_text, text, window.size, agent_rect, agent_moved)


while True:
    if old_window_size != window.size:
        old_window_size = window.size
        rerender_screen_bg()

    window.surface.blit(blured_text_surface if window.input.is_hold(pygame.K_F2) else text_surface, (0, 0))

    debug_text_info = pygex.text.render_text(f'{window.fps:.3f}/120fps, pygex: v0.2', 0)

    window.surface.blit(
        debug_text_info,
        (window.width - debug_text_info.get_width(), window.height - debug_text_info.get_height())
    )

    pygame.draw.rect(window.surface, 0x80deea, agent_rect)

    if window.input.any_is_applying(pygame.K_w, pygame.K_UP):
        agent_rect.y -= 10

        if not agent_moved:
            agent_moved = True
            rerender_screen_bg()
    elif window.input.any_is_applying(pygame.K_s, pygame.K_DOWN):
        agent_rect.y += 10

        if not agent_moved:
            agent_moved = True
            rerender_screen_bg()

    if window.input.any_is_applying(pygame.K_a, pygame.K_LEFT):
        agent_rect.x -= 10

        if not agent_moved:
            agent_moved = True
            rerender_screen_bg()
    elif window.input.any_is_applying(pygame.K_d, pygame.K_RIGHT):
        agent_rect.x += 10

        if not agent_moved:
            agent_moved = True
            rerender_screen_bg()

    if window.mouse.left_is_down and agent_rect.collidepoint(window.mouse.pos):
        agent_dragging = True
    elif window.mouse.left_is_hold and agent_dragging:
        agent_rect.center = window.mouse.pos

        if not agent_moved:
            agent_moved = True
            rerender_screen_bg()
    else:
        agent_dragging = False

    if agent_rect.x < 0:
        agent_rect.x = 0
    elif agent_rect.right > window.width:
        agent_rect.right = window.width

    if agent_rect.y < 0:
        agent_rect.y = 0
    elif agent_rect.bottom > window.height:
        agent_rect.bottom = window.height

    if window.input.is_up(pygame.K_F1):
        window.take_screenshot()
    elif window.input.is_up(pygame.K_F11):
        window.fullscreen = not window.fullscreen

        if window.fullscreen:
            fullscreen_toast.show()
        else:
            fullscreen_toast.cancel()

    window.flip()