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.
		
		
		
		
		
			
		
			
				
					
					
						
							77 lines
						
					
					
						
							3.2 KiB
						
					
					
				
			
		
		
	
	
							77 lines
						
					
					
						
							3.2 KiB
						
					
					
				import pyray as rl
 | 
						|
from openpilot.system.ui.lib.application import FontWeight
 | 
						|
from openpilot.system.ui.lib.multilang import tr
 | 
						|
from openpilot.system.ui.widgets import Widget, DialogResult
 | 
						|
from openpilot.system.ui.widgets.button import Button, ButtonStyle
 | 
						|
from openpilot.system.ui.widgets.label import gui_label
 | 
						|
from openpilot.system.ui.widgets.scroller import Scroller
 | 
						|
 | 
						|
# Constants
 | 
						|
MARGIN = 50
 | 
						|
TITLE_FONT_SIZE = 70
 | 
						|
ITEM_HEIGHT = 135
 | 
						|
BUTTON_SPACING = 50
 | 
						|
BUTTON_HEIGHT = 160
 | 
						|
ITEM_SPACING = 50
 | 
						|
LIST_ITEM_SPACING = 25
 | 
						|
 | 
						|
 | 
						|
class MultiOptionDialog(Widget):
 | 
						|
  def __init__(self, title, options, current=""):
 | 
						|
    super().__init__()
 | 
						|
    self.title = title
 | 
						|
    self.options = options
 | 
						|
    self.current = current
 | 
						|
    self.selection = current
 | 
						|
    self._result: DialogResult = DialogResult.NO_ACTION
 | 
						|
 | 
						|
    # Create scroller with option buttons
 | 
						|
    self.option_buttons = [Button(option, click_callback=lambda opt=option: self._on_option_clicked(opt),
 | 
						|
                                  text_alignment=rl.GuiTextAlignment.TEXT_ALIGN_LEFT, button_style=ButtonStyle.NORMAL,
 | 
						|
                                  text_padding=50) for option in options]
 | 
						|
    self.scroller = Scroller(self.option_buttons, spacing=LIST_ITEM_SPACING)
 | 
						|
 | 
						|
    self.cancel_button = Button(tr("Cancel"), click_callback=lambda: self._set_result(DialogResult.CANCEL))
 | 
						|
    self.select_button = Button(tr("Select"), click_callback=lambda: self._set_result(DialogResult.CONFIRM), button_style=ButtonStyle.PRIMARY)
 | 
						|
 | 
						|
  def _set_result(self, result: DialogResult):
 | 
						|
    self._result = result
 | 
						|
 | 
						|
  def _on_option_clicked(self, option):
 | 
						|
    self.selection = option
 | 
						|
 | 
						|
  def _render(self, rect):
 | 
						|
    dialog_rect = rl.Rectangle(rect.x + MARGIN, rect.y + MARGIN, rect.width - 2 * MARGIN, rect.height - 2 * MARGIN)
 | 
						|
    rl.draw_rectangle_rounded(dialog_rect, 0.02, 20, rl.Color(30, 30, 30, 255))
 | 
						|
 | 
						|
    content_rect = rl.Rectangle(dialog_rect.x + MARGIN, dialog_rect.y + MARGIN,
 | 
						|
                                dialog_rect.width - 2 * MARGIN, dialog_rect.height - 2 * MARGIN)
 | 
						|
 | 
						|
    gui_label(rl.Rectangle(content_rect.x, content_rect.y, content_rect.width, TITLE_FONT_SIZE), self.title, 70, font_weight=FontWeight.BOLD)
 | 
						|
 | 
						|
    # Options area
 | 
						|
    options_y = content_rect.y + TITLE_FONT_SIZE + ITEM_SPACING
 | 
						|
    options_h = content_rect.height - TITLE_FONT_SIZE - BUTTON_HEIGHT - 2 * ITEM_SPACING
 | 
						|
    options_rect = rl.Rectangle(content_rect.x, options_y, content_rect.width, options_h)
 | 
						|
 | 
						|
    # Update button styles and set width based on selection
 | 
						|
    for i, option in enumerate(self.options):
 | 
						|
      selected = option == self.selection
 | 
						|
      button = self.option_buttons[i]
 | 
						|
      button.set_button_style(ButtonStyle.PRIMARY if selected else ButtonStyle.NORMAL)
 | 
						|
      button.set_rect(rl.Rectangle(0, 0, options_rect.width, ITEM_HEIGHT))
 | 
						|
 | 
						|
    self.scroller.render(options_rect)
 | 
						|
 | 
						|
    # Buttons
 | 
						|
    button_y = content_rect.y + content_rect.height - BUTTON_HEIGHT
 | 
						|
    button_w = (content_rect.width - BUTTON_SPACING) / 2
 | 
						|
 | 
						|
    cancel_rect = rl.Rectangle(content_rect.x, button_y, button_w, BUTTON_HEIGHT)
 | 
						|
    self.cancel_button.render(cancel_rect)
 | 
						|
 | 
						|
    select_rect = rl.Rectangle(content_rect.x + button_w + BUTTON_SPACING, button_y, button_w, BUTTON_HEIGHT)
 | 
						|
    self.select_button.set_enabled(self.selection != self.current)
 | 
						|
    self.select_button.render(select_rect)
 | 
						|
 | 
						|
    return self._result
 | 
						|
 |