diff --git a/.github/workflows/sunnypilot-build-prebuilt.yaml b/.github/workflows/sunnypilot-build-prebuilt.yaml index 50456f93d3..dacbacbe26 100644 --- a/.github/workflows/sunnypilot-build-prebuilt.yaml +++ b/.github/workflows/sunnypilot-build-prebuilt.yaml @@ -200,37 +200,28 @@ jobs: sudo rm -rf ${OUTPUT_DIR} mkdir -p ${OUTPUT_DIR} rsync -am${RUNNER_DEBUG:+v} \ - --include='**/panda/board/' \ - --include='**/panda/board/obj' \ - --include='**/panda/board/obj/panda.bin.signed' \ - --include='**/panda/board/obj/panda_h7.bin.signed' \ - --include='**/panda/board/obj/bootstub.panda.bin' \ - --include='**/panda/board/obj/bootstub.panda_h7.bin' \ --exclude='.sconsign.dblite' \ --exclude='*.a' \ --exclude='*.o' \ --exclude='*.os' \ --exclude='*.pyc' \ --exclude='moc_*' \ - --exclude='*.cc' \ + --exclude='__pycache__' \ --exclude='Jenkinsfile' \ - --exclude='supercombo.onnx' \ - --exclude='**/panda/board/*' \ - --exclude='**/panda/board/obj/**' \ - --exclude='**/panda/certs/' \ - --exclude='**/panda/crypto/' \ --exclude='**/release/' \ --exclude='**/.github/' \ --exclude='**/selfdrive/ui/replay/' \ --exclude='**/__pycache__/' \ - --exclude='**/selfdrive/ui/*.h' \ - --exclude='**/selfdrive/ui/**/*.h' \ - --exclude='**/selfdrive/ui/qt/offroad/sunnypilot/' \ --exclude='${{env.SCONS_CACHE_DIR}}' \ --exclude='**/.git/' \ --exclude='**/SConstruct' \ --exclude='**/SConscript' \ --exclude='**/.venv/' \ + --exclude='selfdrive/modeld/models/driving_vision.onnx' \ + --exclude='selfdrive/modeld/models/driving_policy.onnx' \ + --exclude='sunnypilot/modeld*/models/supercombo.onnx' \ + --exclude='third_party/*x86*' \ + --exclude='third_party/*Darwin*' \ --delete-excluded \ --chown=comma:comma \ ${BUILD_DIR}/ ${OUTPUT_DIR}/ diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 38bb7435e2..7ae393bb5b 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -115,14 +115,13 @@ jobs: - run: echo "CACHE_COMMIT_DATE=$(git log -1 --pretty='format:%cd' --date=format:'%Y-%m-%d-%H:%M')" >> $GITHUB_ENV - name: Homebrew cache uses: ./.github/workflows/auto-cache - if: false # disabling the cache for now because it is breaking macos builds... with: save: false # No need save here if we manually save it later conditionally path: ~/Library/Caches/Homebrew - key: brew-macos-${{ env.CACHE_COMMIT_DATE }}-${{ github.sha }} + key: brew-macos-${{ hashFiles('tools/Brewfile') }}-${{ github.sha }} restore-keys: | - brew-macos-${{ env.CACHE_COMMIT_DATE }} - brew-macos + brew-macos-${{ hashFiles('tools/Brewfile') }} + brew-macos- - name: Install dependencies run: ./tools/mac_setup.sh env: @@ -133,7 +132,7 @@ jobs: if: github.ref == 'refs/heads/master' with: path: ~/Library/Caches/Homebrew - key: brew-macos-${{ env.CACHE_COMMIT_DATE }}-${{ github.sha }} + key: brew-macos-${{ hashFiles('tools/Brewfile') }}-${{ github.sha }} - run: git lfs pull - name: Getting scons cache uses: ./.github/workflows/auto-cache diff --git a/selfdrive/ui/sunnypilot/layouts/settings/models.py b/selfdrive/ui/sunnypilot/layouts/settings/models.py index 16d406ea98..211aad6a22 100644 --- a/selfdrive/ui/sunnypilot/layouts/settings/models.py +++ b/selfdrive/ui/sunnypilot/layouts/settings/models.py @@ -74,7 +74,7 @@ class ModelsLayout(Widget): self.lane_turn_value_control = option_item_sp(tr("Adjust Lane Turn Speed"), "LaneTurnValue", 500, 2000, tr("Set the maximum speed for lane turn desires. Default is 19 mph."), - int(round(100 / CV.MPH_TO_KPH)), None, True, "", style.BUTTON_WIDTH, None, True, + int(round(100 / CV.MPH_TO_KPH)), None, True, "", style.BUTTON_ACTION_WIDTH, None, True, lambda v: f"{int(round(v / 100 * (CV.MPH_TO_KPH if ui_state.is_metric else 1)))}" + f" {'km/h' if ui_state.is_metric else 'mph'}") @@ -86,7 +86,7 @@ class ModelsLayout(Widget): self.delay_control = option_item_sp(tr("Adjust Software Delay"), "LagdToggleDelay", 5, 50, tr("Adjust the software delay when Live Learning Steer Delay is toggled off. The default software delay value is 0.2"), - 1, None, True, "", style.BUTTON_WIDTH, None, True, lambda v: f"{v / 100:.2f}s") + 1, None, True, "", style.BUTTON_ACTION_WIDTH, None, True, lambda v: f"{v / 100:.2f}s") self.lagd_toggle = toggle_item_sp(tr("Live Learning Steer Delay"), "", param="LagdToggle") diff --git a/system/ui/sunnypilot/lib/styles.py b/system/ui/sunnypilot/lib/styles.py index 3e1d2dc408..7a29b5bb13 100644 --- a/system/ui/sunnypilot/lib/styles.py +++ b/system/ui/sunnypilot/lib/styles.py @@ -28,9 +28,13 @@ class Base: TOGGLE_BG_HEIGHT = TOGGLE_HEIGHT - 20 # Button Control - BUTTON_WIDTH = 300 + BUTTON_ACTION_WIDTH = 300 BUTTON_HEIGHT = 120 + # Simple Button Control + SIMPLE_BUTTON_WIDTH = 800 + SIMPLE_BUTTON_HEIGHT = 150 + @dataclass class DefaultStyleSP(Base): @@ -81,5 +85,11 @@ class DefaultStyleSP(Base): BLUE = rl.Color(0, 134, 233, 255) YELLOW = rl.Color(255, 213, 0, 255) + # Button Colors + BUTTON_ENABLED_OFF = rl.Color(0x39, 0x39, 0x39, 0xFF) + BUTTON_OFF_PRESSED = rl.Color(0x4A, 0x4A, 0x4A, 0xFF) + BUTTON_DISABLED = rl.Color(0x12, 0x12, 0x12, 0xFF) + BUTTON_TEXT_DISABLED = rl.Color(0x5C, 0x5C, 0x5C, 0xFF) + style = DefaultStyleSP diff --git a/system/ui/sunnypilot/widgets/list_view.py b/system/ui/sunnypilot/widgets/list_view.py index ac646df5bf..2d7239ae66 100644 --- a/system/ui/sunnypilot/widgets/list_view.py +++ b/system/ui/sunnypilot/widgets/list_view.py @@ -11,6 +11,7 @@ from openpilot.common.params import Params from openpilot.system.ui.lib.application import gui_app, MousePos, FontWeight from openpilot.system.ui.lib.text_measure import measure_text_cached from openpilot.system.ui.sunnypilot.widgets.toggle import ToggleSP +from openpilot.system.ui.widgets.button import Button, ButtonStyle from openpilot.system.ui.widgets.label import gui_label from openpilot.system.ui.widgets.list_view import ListItem, ToggleAction, ItemAction, MultipleButtonAction, ButtonAction, \ _resolve_value, BUTTON_WIDTH, BUTTON_HEIGHT, TEXT_PADDING @@ -25,8 +26,37 @@ class ToggleActionSP(ToggleAction): self.toggle = ToggleSP(initial_state=initial_state, callback=callback, param=param) +class ButtonSP(Button): + def _update_state(self): + super()._update_state() + if self.enabled: + if self.is_pressed: + self._background_color = style.BUTTON_OFF_PRESSED + else: + self._background_color = style.BUTTON_ENABLED_OFF + else: + self._background_color = style.BUTTON_DISABLED + self._label.set_text_color(style.BUTTON_TEXT_DISABLED) + + +class SimpleButtonActionSP(ItemAction): + def __init__(self, button_text: str | Callable[[], str], callback: Callable = None, + enabled: bool | Callable[[], bool] = True, button_width: int = style.SIMPLE_BUTTON_WIDTH): + super().__init__(width=button_width, enabled=enabled) + self.button_action = ButtonSP(button_text, click_callback=callback, button_style=ButtonStyle.NORMAL, + border_radius=20) + + def set_touch_valid_callback(self, touch_callback: Callable[[], bool]) -> None: + super().set_touch_valid_callback(touch_callback) + self.button_action.set_touch_valid_callback(touch_callback) + + def _render(self, rect: rl.Rectangle) -> bool | int | None: + self.button_action.set_enabled(self.enabled) + return self.button_action.render(rect) + + class ButtonActionSP(ButtonAction): - def __init__(self, text: str | Callable[[], str], width: int = style.BUTTON_WIDTH, enabled: bool | Callable[[], bool] = True): + def __init__(self, text: str | Callable[[], str], width: int = style.BUTTON_ACTION_WIDTH, enabled: bool | Callable[[], bool] = True): super().__init__(text=text, width=width, enabled=enabled) self._value_color: rl.Color = style.ITEM_TEXT_VALUE_COLOR @@ -165,7 +195,7 @@ class ListItemSP(ListItem): content_width = item_rect.width - (style.ITEM_PADDING * 2) title_width = measure_text_cached(self._font, self.title, style.ITEM_TEXT_FONT_SIZE).x right_width = min(content_width - title_width, right_width) - if isinstance(self.action_item, ToggleAction): + if isinstance(self.action_item, ToggleAction) or isinstance(self.action_item, SimpleButtonActionSP): action_x = item_rect.x else: action_x = item_rect.x + item_rect.width - right_width @@ -182,14 +212,15 @@ class ListItemSP(ListItem): content_x = self._rect.x + style.ITEM_PADDING text_x = content_x - left_action_item = isinstance(self.action_item, ToggleAction) + left_action_item = isinstance(self.action_item, ToggleAction) or isinstance(self.action_item, SimpleButtonActionSP) if left_action_item: + item_height = style.SIMPLE_BUTTON_HEIGHT if isinstance(self.action_item, SimpleButtonActionSP) else style.TOGGLE_HEIGHT left_rect = rl.Rectangle( content_x, - self._rect.y + (style.ITEM_BASE_HEIGHT - style.TOGGLE_HEIGHT) // 2, - style.TOGGLE_WIDTH, - style.TOGGLE_HEIGHT + self._rect.y + (style.ITEM_BASE_HEIGHT - item_height) // 2, + self.action_item.rect.width, + item_height ) text_x = left_rect.x + left_rect.width + style.ITEM_PADDING * 1.5 @@ -245,6 +276,12 @@ class ListItemSP(ListItem): self._html_renderer.render(description_rect) +def simple_button_item_sp(button_text: str | Callable[[], str], callback: Callable | None = None, + enabled: bool | Callable[[], bool] = True, button_width: int = style.SIMPLE_BUTTON_WIDTH) -> ListItemSP: + action = SimpleButtonActionSP(button_text=button_text, enabled=enabled, callback=callback, button_width=button_width) + return ListItemSP(title="", callback=callback, description="", action_item=action) + + def toggle_item_sp(title: str | Callable[[], str], description: str | Callable[[], str] | None = None, initial_state: bool = False, callback: Callable | None = None, icon: str = "", enabled: bool | Callable[[], bool] = True, param: str | None = None) -> ListItemSP: action = ToggleActionSP(initial_state=initial_state, enabled=enabled, callback=callback, param=param) @@ -252,7 +289,7 @@ def toggle_item_sp(title: str | Callable[[], str], description: str | Callable[[ def multiple_button_item_sp(title: str | Callable[[], str], description: str | Callable[[], str], buttons: list[str | Callable[[], str]], - selected_index: int = 0, button_width: int = style.BUTTON_WIDTH, callback: Callable = None, + selected_index: int = 0, button_width: int = style.BUTTON_ACTION_WIDTH, callback: Callable = None, icon: str = "", param: str | None = None, inline: bool = False) -> ListItemSP: action = MultipleButtonActionSP(buttons, button_width, selected_index, callback=callback, param=param) return ListItemSP(title=title, description=description, icon=icon, action_item=action, inline=inline) diff --git a/tools/Brewfile b/tools/Brewfile new file mode 100644 index 0000000000..af610be75d --- /dev/null +++ b/tools/Brewfile @@ -0,0 +1,15 @@ +brew "git-lfs" +brew "capnp" +brew "coreutils" +brew "eigen" +brew "ffmpeg" +brew "glfw" +brew "libusb" +brew "libtool" +brew "llvm" +brew "openssl@3.0" +brew "qt@5" +brew "zeromq" +cask "gcc-arm-embedded" +brew "portaudio" +brew "gcc@13" diff --git a/tools/mac_setup.sh b/tools/mac_setup.sh index 0ae0b35359..ae8a1974ac 100755 --- a/tools/mac_setup.sh +++ b/tools/mac_setup.sh @@ -32,23 +32,7 @@ else brew up fi -brew bundle --file=- <<-EOS -brew "git-lfs" -brew "capnp" -brew "coreutils" -brew "eigen" -brew "ffmpeg" -brew "glfw" -brew "libusb" -brew "libtool" -brew "llvm" -brew "openssl@3.0" -brew "qt@5" -brew "zeromq" -cask "gcc-arm-embedded" -brew "portaudio" -brew "gcc@13" -EOS +brew bundle --file=$DIR/Brewfile echo "[ ] finished brew install t=$SECONDS"