Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/prompt_toolkit/widgets/dialogs.py: 42%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

36 statements  

1""" 

2Collection of reusable components for building full screen applications. 

3""" 

4 

5from __future__ import annotations 

6 

7from typing import Sequence 

8 

9from prompt_toolkit.filters import has_completions, has_focus 

10from prompt_toolkit.formatted_text import AnyFormattedText 

11from prompt_toolkit.key_binding.bindings.focus import focus_next, focus_previous 

12from prompt_toolkit.key_binding.key_bindings import KeyBindings 

13from prompt_toolkit.layout.containers import ( 

14 AnyContainer, 

15 DynamicContainer, 

16 HSplit, 

17 VSplit, 

18) 

19from prompt_toolkit.layout.dimension import AnyDimension 

20from prompt_toolkit.layout.dimension import Dimension as D 

21 

22from .base import Box, Button, Frame, Shadow 

23 

24__all__ = [ 

25 "Dialog", 

26] 

27 

28 

29class Dialog: 

30 """ 

31 Simple dialog window. This is the base for input dialogs, message dialogs 

32 and confirmation dialogs. 

33 

34 Changing the title and body of the dialog is possible at runtime by 

35 assigning to the `body` and `title` attributes of this class. 

36 

37 :param body: Child container object. 

38 :param title: Text to be displayed in the heading of the dialog. 

39 :param buttons: A list of `Button` widgets, displayed at the bottom. 

40 """ 

41 

42 def __init__( 

43 self, 

44 body: AnyContainer, 

45 title: AnyFormattedText = "", 

46 buttons: Sequence[Button] | None = None, 

47 modal: bool = True, 

48 width: AnyDimension = None, 

49 with_background: bool = False, 

50 ) -> None: 

51 self.body = body 

52 self.title = title 

53 

54 buttons = buttons or [] 

55 

56 # When a button is selected, handle left/right key bindings. 

57 buttons_kb = KeyBindings() 

58 if len(buttons) > 1: 

59 first_selected = has_focus(buttons[0]) 

60 last_selected = has_focus(buttons[-1]) 

61 

62 buttons_kb.add("left", filter=~first_selected)(focus_previous) 

63 buttons_kb.add("right", filter=~last_selected)(focus_next) 

64 

65 frame_body: AnyContainer 

66 if buttons: 

67 frame_body = HSplit( 

68 [ 

69 # Add optional padding around the body. 

70 Box( 

71 body=DynamicContainer(lambda: self.body), 

72 padding=D(preferred=1, max=1), 

73 padding_bottom=0, 

74 ), 

75 # The buttons. 

76 Box( 

77 body=VSplit(buttons, padding=1, key_bindings=buttons_kb), 

78 height=D(min=1, max=3, preferred=3), 

79 ), 

80 ] 

81 ) 

82 else: 

83 frame_body = body 

84 

85 # Key bindings for whole dialog. 

86 kb = KeyBindings() 

87 kb.add("tab", filter=~has_completions)(focus_next) 

88 kb.add("s-tab", filter=~has_completions)(focus_previous) 

89 

90 frame = Shadow( 

91 body=Frame( 

92 title=lambda: self.title, 

93 body=frame_body, 

94 style="class:dialog.body", 

95 width=(None if with_background is None else width), 

96 key_bindings=kb, 

97 modal=modal, 

98 ) 

99 ) 

100 

101 self.container: Box | Shadow 

102 if with_background: 

103 self.container = Box(body=frame, style="class:dialog", width=width) 

104 else: 

105 self.container = frame 

106 

107 def __pt_container__(self) -> AnyContainer: 

108 return self.container