Advertisement
GigaDelta

tui

Feb 10th, 2023
932
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.28 KB | None | 0 0
  1. import sys
  2. from asciimatics.widgets import Frame, Layout, VerticalDivider
  3. from asciimatics.widgets import Button
  4. from asciimatics.effects import Screen
  5. from asciimatics.scene import Scene
  6. from asciimatics.exceptions import ResizeScreenError, StopApplication
  7. from asciimatics.renderers import Box, ImageFile, StaticRenderer
  8. from asciimatics.utilities import DOUBLE_LINE, SINGLE_LINE
  9. from asciimatics.widgets.utilities import THEMES
  10. from asciimatics.widgets.widget import Widget
  11. from asciimatics.event import KeyboardEvent, MouseEvent
  12. from asciimatics.widgets.divider import Divider
  13.  
  14. from builtins import object
  15. from builtins import range
  16. from PIL import Image
  17.  
  18. last = None
  19. s, z = 0, 0
  20.  
  21.  
  22. def cancel():
  23.     raise StopApplication("User pressed quit")
  24.  
  25.  
  26. def none():
  27.     pass
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34. class PhotoButton(Widget):
  35.     def __init__(self, picture, height=1, on_click=None, label=None, add_box=True, name=None, **kwargs):
  36.         """
  37.        :param text: The text for the button.
  38.        :param on_click: The function to invoke when the button is clicked.
  39.        :param label: An optional label for the widget.
  40.        :param add_box: Whether to wrap the text with chevrons.
  41.        :param name: The name of this widget.
  42.  
  43.        Also see the common keyword arguments in :py:obj:`.Widget`.
  44.        """
  45.         super().__init__(name, **kwargs)
  46.         self._add_box = add_box
  47.         self._picture = picture # вместо текста
  48.         self._required_height = height
  49.         self._on_click = on_click
  50.         self._label = label
  51.         #self._w = height
  52.         # вместо лен(текст) надо бы вычислять сторону квадрата фотограафии
  53.         # так как квадрат, значит все стороны раны
  54.         # значит просто передаем height
  55.         #self._strings = list(ImageFile(self._picture, self._required_height).images)[0][1:]
  56.         #self._string_len = len(self._strings[1]) + 2
  57.         #self._renderer_on = Box(width=self._string_len, height=3, uni=True, style=DOUBLE_LINE)
  58.         #self._renderer_off = Box(width=self._string_len, height=3, uni=True, style=SINGLE_LINE)
  59.         #self._excess = 0
  60.  
  61.         self._strings = ImageFile(self._picture, self._required_height).images
  62.         self._string_len = height
  63.         self._renderer_on = Box(width=self._string_len, height=3, uni=True, style=DOUBLE_LINE)
  64.         self._renderer_off = Box(width=self._string_len, height=3, uni=True, style=SINGLE_LINE)
  65.  
  66.  
  67.         #renderer = list(Box(width=20, height=30, uni=True, style=SINGLE_LINE).images)
  68.  
  69.     def reset(self):
  70.         self._value = False
  71.  
  72.     def update(self, frame_no):
  73.         self._draw_label()
  74.  
  75.         (colour, attr, background) = self._frame.palette['borders']
  76.         #colour = self._colours
  77.         # if self._picture:
  78.         #     for dig, string in enumerate(self._strings):
  79.         #         self._frame.canvas.print_at(string, self._x, self._y + dig-1, colour, attr, background)
  80.  
  81.         # Нужно модифицировать функцию чтобы после добавления границ
  82.         # Сохранился текст фотографии
  83.         if self._has_focus:
  84.             box = self._renderer_on.images
  85.             frame = next(box)
  86.             (colour, attr, bg) = self._pick_colours("button")
  87.             bg = Screen.COLOUR_BLUE
  88.             self._frame.canvas.print_at(frame[0], self._x - 1, self._y-1, colour, attr, bg)
  89.             for dig, string in enumerate(self._strings):
  90.                 self._frame.canvas.print_at(frame[1][0] + string + frame[1][-1], self._x - 1, self._y + dig, colour, attr, bg)
  91.             self._frame.canvas.print_at(frame[2], self._x - 1, self._y + dig, colour, attr, bg)
  92.  
  93.         else:
  94.             # self._draw_label()
  95.             # (colour, attr, bg) = self._pick_colours("button")
  96.             # for dig, string in enumerate(self._strings):
  97.             #     self._frame.canvas.print_at(string, self._x, self._y + dig, colour, attr, background)
  98.             box = self._renderer_off.images
  99.             frame = next(box)
  100.             (colour, attr, bg) = self._pick_colours("button")
  101.             bg = Screen.COLOUR_BLUE
  102.             self._frame.canvas.print_at(frame[0], self._x - 1, self._y - 1, colour, attr, bg)
  103.             for dig, string in enumerate(self._strings):
  104.                 self._frame.canvas.print_at(frame[1][0] + string + frame[1][-1], self._x - 1, self._y + dig, colour,
  105.                                             attr, bg)
  106.             #[self._frame.canvas.print_at(frame[1][0] + string + frame[1][-1], self._x-1, self._y-1 + dig, colour) for dig, string in enumerate(self._strings)]
  107.             #self._frame.canvas.print_at(frame[2], self._x - 1, self._y + self.h, colour, attr, bg)
  108.  
  109.     def process_event(self, event):
  110.         if isinstance(event, KeyboardEvent):
  111.             if event.key_code in [ord(" "), 10, 13]:
  112.                 self._on_click()
  113.                 return None
  114.             # Ignore any other key press.
  115.             return event
  116.         if isinstance(event, MouseEvent):
  117.             if event.buttons != 0 and self.is_mouse_over(event, include_label=False):
  118.                 self._on_click()
  119.                 return None
  120.         # Ignore other events
  121.         return event
  122.  
  123.     def value(self):
  124.         return self._value
  125.  
  126.     def required_height(self, offset, width):
  127.         return self._required_height + 3
  128.  
  129.  
  130.  
  131.  
  132.  
  133.     def _pick_palette_key(self, palette_name, selected=False, allow_input_state=True):
  134.         """
  135.        Pick the rendering colour for a widget based on the current state.
  136.  
  137.        :param palette_name: The stem name for the widget - e.g. "button".
  138.        :param selected: Whether this item is selected or not.
  139.        :param allow_input_state: Whether to allow input state (e.g. focus) to affect result.
  140.        :returns: A colour palette key to be used.
  141.        """
  142.         key = palette_name
  143.         if self._custom_colour:
  144.             key = self._custom_colour
  145.         elif self.disabled:
  146.             key = "disabled"
  147.         elif not self._is_valid:
  148.             key = "invalid"
  149.         elif allow_input_state:
  150.             if self._has_focus:
  151.                 key = "focus_" + palette_name
  152.             if selected:
  153.                 key = "selected_" + key
  154.         return key
  155.  
  156.     def _pick_colours(self, palette_name, selected=False):
  157.         """
  158.        Pick the rendering colour for a widget based on the current state.
  159.  
  160.        :param palette_name: The stem name for the widget - e.g. "button".
  161.        :param selected: Whether this item is selected or not.
  162.        :returns: A colour tuple (fg, attr, background) to be used.
  163.        """
  164.         return self._frame.palette[self._pick_palette_key(palette_name, selected)]
  165.  
  166.     # НУЖНО МОДИФИЦИРОВАТЬ ФУНКЦИЮ
  167.     def set_layout(self, x, y, offset, w, h):
  168.         # Do the usual layout work. then recalculate exact x/w values for the
  169.         # rendered button.
  170.         super().set_layout(x, y, offset, w, h)
  171.         text_width = self._required_height
  172.         self._x += 1
  173.         self._y += 1
  174.         self._excess = w
  175.  
  176.  
  177.         #if self._add_box:
  178.             # Minimize widget to make a nice little button.  Only centre it if there are no label offsets.
  179.             #if offset == 0:
  180.                 #self._x += max(0, (self.width - text_width) // 2)
  181.             #self._w = min(self._w, text_width) + offset
  182.         #else:
  183.             # Maximize text to make for a consistent colouring when used in menus.
  184.             #self._text += " " * (self._w - text_width)
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191. class _ImageSequence(object):
  192.     """
  193.    Simple class to make an iterator for a PIL Image object.
  194.    """
  195.  
  196.     def __init__(self, im):
  197.         self.im = im
  198.  
  199.     def __getitem__(self, ix):
  200.         try:
  201.             if ix:
  202.                 self.im.seek(ix)
  203.             return self.im
  204.         except EOFError:
  205.             raise IndexError
  206.  
  207. class ImageFile(StaticRenderer):
  208.     """
  209.    Renderer to convert an image file (as supported by the Python Imaging
  210.    Library) into an ascii grey scale text image.
  211.    """
  212.  
  213.     # The ASCII grey scale from darkest to lightest.
  214.     _greyscale = ' .:;rsA23hHG#9&@'
  215.  
  216.     def __init__(self, filename, height=30, colours=8):
  217.         """
  218.        :param filename: The name of the file to render.
  219.        :param height: The height of the text rendered image.
  220.        :param colours: The number of colours the terminal supports.
  221.        """
  222.         super(ImageFile, self).__init__()
  223.         with Image.open(filename) as image:
  224.             background = image.info['background'] if 'background' in \
  225.                 image.info else None
  226.             for frame in _ImageSequence(image):
  227.                 ascii_image = ""
  228.                 frame = frame.resize(
  229.                     (height*2, height),
  230.                     Image.QUAD)
  231.                 grey_frame = frame.convert('L')
  232.                 for py in range(0, grey_frame.size[1]):
  233.                     ascii_image += "\n"
  234.                     for px in range(0, grey_frame.size[0]):
  235.                         real_col = frame.getpixel((px, py))
  236.                         col = grey_frame.getpixel((px, py))
  237.                         if real_col == background:
  238.                             ascii_image += " "
  239.                         else:
  240.                             if colours >= 256:
  241.                                 ascii_image += "${%d}" % (232 + col * 23 // 256)
  242.                             else:
  243.                                 ascii_image += "${%d,%d}" % (
  244.                                     7 if col >= 85 else 0,
  245.                                     Screen.A_BOLD if col < 85 or col > 170 else
  246.                                     Screen.A_NORMAL
  247.                                 )
  248.                             ascii_image += self._greyscale[
  249.                                 (int(col) * len(self._greyscale)) // 256]
  250.                 self._images.append(ascii_image)
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258. def demo(screen, scene):
  259.  
  260.     frame = Frame(screen, screen.height - 3, screen.width // 3 * 2, can_scroll=False, has_border=True, title="VK.COM")
  261.     frame.border_box.unicode_aware = True
  262.     frame.border_box.style = 2
  263.     half = 60 // 5
  264.     buttons = Layout([half, half, half, half, half, 34, 6])
  265.     line = Layout([1])
  266.     window = Layout([1, 1, 1])
  267.     frame.add_layout(buttons)
  268.     frame.add_layout(line)
  269.     frame.add_layout(window)
  270.  
  271.     window.add_widget(PhotoButton("1.jpg", height=15, on_click=cancel), 0)
  272.     window.add_widget(PhotoButton("2.jpg", height=15, on_click=cancel), 1)
  273.     window.add_widget(PhotoButton("3.jpg", height=15, on_click=cancel), 2)
  274.  
  275.  
  276.  
  277.  
  278.  
  279.     # layout.add_widget(MyButton(text=" Vasya ", on_click=none), 0)
  280.     # layout.add_widget(MyButton(text=" Pupok ", on_click=cancel), 1)
  281.     # layout.add_widget(MyButton(text=" Pupok ", on_click=cancel), 2)
  282.     # layout1.add_widget(Block(on_click=cancel), 0)
  283.     frame.fix()
  284.  
  285.     global s
  286.     global z
  287.     s = screen.height
  288.     z = screen.width
  289.  
  290.     scenes = [Scene([frame], -1, name="Main")]
  291.     screen.play(scenes, stop_on_resize=True, start_scene=scene, repeat=False)
  292.  
  293.  
  294. last_scene = None
  295. while True:
  296.     try:
  297.         Screen.wrapper(demo, arguments=[last_scene])
  298.         print(s, z)
  299.         sys.exit(0)
  300.     except ResizeScreenError as e:
  301.         last_scene = e.scene
  302.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement