You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							89 lines
						
					
					
						
							3.7 KiB
						
					
					
				
			
		
		
	
	
							89 lines
						
					
					
						
							3.7 KiB
						
					
					
				| import pyray as rl
 | |
| from openpilot.system.ui.lib.application import gui_app, FontWeight
 | |
| from openpilot.system.ui.widgets import DialogResult
 | |
| from openpilot.system.ui.widgets.button import ButtonStyle, Button
 | |
| from openpilot.system.ui.widgets.label import Label
 | |
| from openpilot.system.ui.widgets.html_render import HtmlRenderer, ElementType
 | |
| from openpilot.system.ui.widgets import Widget
 | |
| from openpilot.system.ui.widgets.scroller import Scroller
 | |
| 
 | |
| OUTER_MARGIN = 200
 | |
| RICH_OUTER_MARGIN = 100
 | |
| BUTTON_HEIGHT = 160
 | |
| MARGIN = 50
 | |
| TEXT_PADDING = 10
 | |
| BACKGROUND_COLOR = rl.Color(27, 27, 27, 255)
 | |
| 
 | |
| 
 | |
| class ConfirmDialog(Widget):
 | |
|   def __init__(self, text: str, confirm_text: str, cancel_text: str = "Cancel", rich: bool = False):
 | |
|     super().__init__()
 | |
|     self._label = Label(text, 70, FontWeight.BOLD, text_color=rl.Color(201, 201, 201, 255))
 | |
|     self._html_renderer = HtmlRenderer(text=text, text_size={ElementType.P: 50}, center_text=True)
 | |
|     self._cancel_button = Button(cancel_text, self._cancel_button_callback)
 | |
|     self._confirm_button = Button(confirm_text, self._confirm_button_callback, button_style=ButtonStyle.PRIMARY)
 | |
|     self._rich = rich
 | |
|     self._dialog_result = DialogResult.NO_ACTION
 | |
|     self._cancel_text = cancel_text
 | |
|     self._scroller = Scroller([self._html_renderer], line_separator=False, spacing=0)
 | |
| 
 | |
|   def set_text(self, text):
 | |
|     if not self._rich:
 | |
|       self._label.set_text(text)
 | |
|     else:
 | |
|       self._html_renderer.parse_html_content(text)
 | |
| 
 | |
|   def reset(self):
 | |
|     self._dialog_result = DialogResult.NO_ACTION
 | |
| 
 | |
|   def _cancel_button_callback(self):
 | |
|     self._dialog_result = DialogResult.CANCEL
 | |
| 
 | |
|   def _confirm_button_callback(self):
 | |
|     self._dialog_result = DialogResult.CONFIRM
 | |
| 
 | |
|   def _render(self, rect: rl.Rectangle):
 | |
|     dialog_x = OUTER_MARGIN if not self._rich else RICH_OUTER_MARGIN
 | |
|     dialog_y = OUTER_MARGIN if not self._rich else RICH_OUTER_MARGIN
 | |
|     dialog_width = gui_app.width - 2 * dialog_x
 | |
|     dialog_height = gui_app.height - 2 * dialog_y
 | |
|     dialog_rect = rl.Rectangle(dialog_x, dialog_y, dialog_width, dialog_height)
 | |
| 
 | |
|     bottom = dialog_rect.y + dialog_rect.height
 | |
|     button_width = (dialog_rect.width - 3 * MARGIN) // 2
 | |
|     cancel_button_x = dialog_rect.x + MARGIN
 | |
|     confirm_button_x = dialog_rect.x + dialog_rect.width - button_width - MARGIN
 | |
|     button_y = bottom - BUTTON_HEIGHT - MARGIN
 | |
|     cancel_button = rl.Rectangle(cancel_button_x, button_y, button_width, BUTTON_HEIGHT)
 | |
|     confirm_button = rl.Rectangle(confirm_button_x, button_y, button_width, BUTTON_HEIGHT)
 | |
| 
 | |
|     rl.draw_rectangle_rec(dialog_rect, BACKGROUND_COLOR)
 | |
| 
 | |
|     text_rect = rl.Rectangle(dialog_rect.x + MARGIN, dialog_rect.y + TEXT_PADDING,
 | |
|                              dialog_rect.width - 2 * MARGIN, dialog_rect.height - BUTTON_HEIGHT - MARGIN - TEXT_PADDING * 2)
 | |
|     if not self._rich:
 | |
|       self._label.render(text_rect)
 | |
|     else:
 | |
|       html_rect = rl.Rectangle(text_rect.x, text_rect.y, text_rect.width,
 | |
|                                self._html_renderer.get_total_height(int(text_rect.width)))
 | |
|       self._html_renderer.set_rect(html_rect)
 | |
|       self._scroller.render(text_rect)
 | |
| 
 | |
|     if rl.is_key_pressed(rl.KeyboardKey.KEY_ENTER):
 | |
|       self._dialog_result = DialogResult.CONFIRM
 | |
|     elif rl.is_key_pressed(rl.KeyboardKey.KEY_ESCAPE):
 | |
|       self._dialog_result = DialogResult.CANCEL
 | |
| 
 | |
|     if self._cancel_text:
 | |
|       self._confirm_button.render(confirm_button)
 | |
|       self._cancel_button.render(cancel_button)
 | |
|     else:
 | |
|       full_button_width = dialog_rect.width - 2 * MARGIN
 | |
|       full_confirm_button = rl.Rectangle(dialog_rect.x + MARGIN, button_y, full_button_width, BUTTON_HEIGHT)
 | |
|       self._confirm_button.render(full_confirm_button)
 | |
| 
 | |
|     return self._dialog_result
 | |
| 
 | |
| 
 | |
| def alert_dialog(message: str, button_text: str = "Ok"):
 | |
|   return ConfirmDialog(message, button_text, cancel_text="")
 | |
| 
 |