Shofel2_T124_python/venv/lib/python3.10/site-packages/asciimatics/widgets/popupmenu.py

76 lines
3.0 KiB
Python
Raw Permalink Normal View History

2024-05-25 16:45:07 +00:00
# -*- coding: utf-8 -*-
"""This module implements a pop up menu widget"""
from __future__ import division
from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals
from collections import defaultdict
from functools import partial
from asciimatics.event import KeyboardEvent, MouseEvent
from asciimatics.screen import Screen
from asciimatics.widgets.button import Button
from asciimatics.widgets.frame import Frame
from asciimatics.widgets.layout import Layout
class PopupMenu(Frame):
"""
A widget for displaying a menu.
"""
palette = defaultdict(lambda: (Screen.COLOUR_WHITE, Screen.A_NORMAL, Screen.COLOUR_CYAN))
palette["focus_button"] = (Screen.COLOUR_CYAN, Screen.A_NORMAL, Screen.COLOUR_WHITE)
def __init__(self, screen, menu_items, x, y):
"""
:param screen: The Screen being used for this pop-up.
:param menu_items: a list of items to be displayed in the menu.
:param x: The X coordinate for the desired pop-up.
:param y: The Y coordinate for the desired pop-up.
The menu_items parameter is a list of 2-tuples, which define the text to be displayed in
the menu and the function to call when that menu item is clicked. For example:
menu_items = [("Open", file_open), ("Save", file_save), ("Close", file_close)]
"""
# Sort out location based on width of menu text.
w = max(len(i[0]) for i in menu_items)
h = len(menu_items)
if x + w >= screen.width:
x -= w - 1
if y + h >= screen.height:
y -= h - 1
# Construct the Frame
super(PopupMenu, self).__init__(
screen, h, w, x=x, y=y, has_border=False, can_scroll=False, is_modal=True, hover_focus=True)
# Build the widget to display the time selection.
layout = Layout([1], fill_frame=True)
self.add_layout(layout)
for item in menu_items:
func = partial(self._destroy, item[1])
layout.add_widget(Button(item[0], func, add_box=False), 0)
self.fix()
def _destroy(self, callback=None):
self._scene.remove_effect(self)
if callback is not None:
callback()
def process_event(self, event):
# Look for events that will close the pop-up - e.g. clicking outside the Frame or ESC key.
if event is not None:
if isinstance(event, KeyboardEvent):
if event.key_code == Screen.KEY_ESCAPE:
event = None
elif isinstance(event, MouseEvent) and event.buttons != 0:
origin = self._canvas.origin
if event.y < origin[1] or event.y >= origin[1] + self._canvas.height:
event = None
elif event.x < origin[0] or event.x >= origin[0] + self._canvas.width:
event = None
if event is None:
self._destroy()
return super(PopupMenu, self).process_event(event)