From a7a29d63edf47c9542facefe8bd307d7246327aa Mon Sep 17 00:00:00 2001 From: BroBordd Date: Mon, 5 Jan 2026 01:43:04 +0200 Subject: [PATCH 1/9] push --- CHANGELOG.md | 4 ++ index.json | 3 +- plugin_manager.py | 118 +++++++++++++++++++++++++++++++--------------- 3 files changed, 86 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72983d233..d86931869 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## Plugin Manager (dd-mm-yyyy) +### 1.1.5 (05-01-2026) + +- Small UI Improvements. + ### 1.1.4 (09-08-2025) - Cleaning up the code. diff --git a/index.json b/index.json index 54310e98e..ec82e55e8 100644 --- a/index.json +++ b/index.json @@ -1,6 +1,7 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { + "1.1.5": null, "1.1.4": { "api_version": 9, "commit_sha": "1a9468d", @@ -278,4 +279,4 @@ "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugins/maps.json" ], "external_source_url": "https://github.com/{repository}/{content_type}/{tag}/category.json" -} \ No newline at end of file +} diff --git a/plugin_manager.py b/plugin_manager.py index d2558774a..30c8f7f13 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -29,7 +29,7 @@ # Modules used for overriding AllSettingsWindow import logging -PLUGIN_MANAGER_VERSION = "1.1.4" +PLUGIN_MANAGER_VERSION = "1.1.5" REPOSITORY_URL = "https://github.com/bombsquad-community/plugin-manager" # Current tag can be changed to "staging" or any other branch in # plugin manager repo for testing purpose. @@ -1035,7 +1035,6 @@ async def soft_refresh(self): class ChangelogWindow(popup.PopupWindow): def __init__(self, origin_widget): self.scale_origin = origin_widget.get_screen_space_center() - bui.getsound('swish').play() s = 1.65 if _uiscale() is babase.UIScale.SMALL else 1.39 if _uiscale() is babase.UIScale.MEDIUM else 1.67 width = 400 * s height = width * 0.5 @@ -1074,7 +1073,8 @@ def __init__(self, origin_widget): scale=0.8, label=babase.charstr(babase.SpecialChar.BACK), button_type='backSmall', - on_activate_call=self._back + on_activate_call=self._back, + enable_sound=False ) bui.containerwidget(edit=self._root_widget, cancel_button=back_button) @@ -1092,7 +1092,7 @@ def __init__(self, origin_widget): bui.textwidget( parent=self._root_widget, - position=(width * 0.49, height * 0.72), + position=(width * 0.49, height * 0.75), size=(0, 0), h_align='center', v_align='center', @@ -1104,12 +1104,16 @@ def __init__(self, origin_widget): bui.buttonwidget( parent=self._root_widget, - position=(width * 0.7, height * 0.72 - 20), + position=(width * 0.7, height * 0.72), size=(140, 60), scale=0.8, label='Full ChangeLog', button_type='square', - on_activate_call=lambda: bui.open_url(REPOSITORY_URL + '/blob/main/CHANGELOG.md') + enable_sound=False, + on_activate_call=lambda: ( + bui.getsound('deek').play() or + bui.open_url(REPOSITORY_URL + '/blob/main/CHANGELOG.md') + ) ) loop_height = height * 0.62 @@ -1119,13 +1123,13 @@ def __init__(self, origin_widget): position=(width * 0.5 * extra, loop_height), size=(0, 0), h_align=h_align, - v_align='top', + v_align='center', text=log, scale=text_scale, color=color, maxwidth=width * 0.9 ) - loop_height -= 35 + loop_height -= 30 def _back(self) -> None: bui.getsound('swish').play() @@ -1137,7 +1141,6 @@ class AuthorsWindow(popup.PopupWindow): def __init__(self, authors_info, origin_widget): self.authors_info = authors_info self.scale_origin = origin_widget.get_screen_space_center() - bui.getsound('swish').play() s = 1.25 if _uiscale() is babase.UIScale.SMALL else 1.39 if _uiscale() is babase.UIScale.MEDIUM else 1.67 width = 400 * s height = width * 0.8 @@ -1177,7 +1180,8 @@ def __init__(self, authors_info, origin_widget): scale=0.8, label=babase.charstr(babase.SpecialChar.BACK), button_type='backSmall', - on_activate_call=self._back + on_activate_call=self._back, + enable_sound=False ) bui.containerwidget(edit=self._root_widget, cancel_button=back_button) @@ -1298,11 +1302,13 @@ async def draw_ui(self): parent=self._root_widget, position=(-12.5*s + (4 if _uiscale() is babase.UIScale.SMALL else -5), height/2 - 20*s), - label='<', + label=bui.charstr(bui.SpecialChar.LEFT_ARROW), size=(25, 40), color=(1, 0.5, 0.5), scale=s, - on_activate_call=self.show_previous_plugin + on_activate_call=self.show_previous_plugin, + enable_sound=False, + textcolor=(1,1,1) ) if self.p_n_plugins[1] is not None: @@ -1310,14 +1316,16 @@ async def draw_ui(self): parent=self._root_widget, position=(width - 12.5*s - (8 if _uiscale() is babase.UIScale.SMALL else 0), height/2 - 20*s), - label='>', + label=bui.charstr(bui.SpecialChar.RIGHT_ARROW), size=(25, 40), color=(1, 0.5, 0.5), scale=s, - on_activate_call=self.show_next_plugin + on_activate_call=self.show_next_plugin, + enable_sound=False, + textcolor=(1,1,1) ) - pos = height * 0.8 + pos = height * 0.85 plug_name = self.plugin.name.replace('_', ' ').title() plugin_title = f"{plug_name} (v{self.plugin.latest_compatible_version.number})" bui.textwidget( @@ -1449,10 +1457,15 @@ async def draw_ui(self): selected_child=selected_btn ) - open_pos_x = (390 if _uiscale() is babase.UIScale.SMALL else - 450 if _uiscale() is babase.UIScale.MEDIUM else 440) - open_pos_y = (100 if _uiscale() is babase.UIScale.SMALL else - 110 if _uiscale() is babase.UIScale.MEDIUM else 120) + tool_top = 190 + + open_pos_x = (60 if _uiscale() is babase.UIScale.SMALL else + 60 if _uiscale() is babase.UIScale.MEDIUM else 60) + open_pos_y = tool_top - 45 - ( + 0 if _uiscale() is babase.UIScale.SMALL else + 10 if _uiscale() is babase.UIScale.MEDIUM else + 20 + ) open_button = bui.buttonwidget( parent=self._root_widget, autoselect=True, @@ -1491,10 +1504,13 @@ def tutorial_confirm_window(): text=text, action=lambda: bui.open_url(self.plugin.info["external_url"]), ) - open_pos_x = (440 if _uiscale() is babase.UIScale.SMALL else - 500 if _uiscale() is babase.UIScale.MEDIUM else 490) - open_pos_y = (100 if _uiscale() is babase.UIScale.SMALL else - 110 if _uiscale() is babase.UIScale.MEDIUM else 120) + open_pos_x = (60 if _uiscale() is babase.UIScale.SMALL else + 60 if _uiscale() is babase.UIScale.MEDIUM else 60) + open_pos_y = tool_top - 90 - ( + 0 if _uiscale() is babase.UIScale.SMALL else + 10 if _uiscale() is babase.UIScale.MEDIUM else + 20 + ) open_button = bui.buttonwidget( parent=self._root_widget, autoselect=True, @@ -1528,8 +1544,11 @@ def tutorial_confirm_window(): if to_draw_button4: settings_pos_x = (60 if _uiscale() is babase.UIScale.SMALL else 60 if _uiscale() is babase.UIScale.MEDIUM else 60) - settings_pos_y = (100 if _uiscale() is babase.UIScale.SMALL else - 110 if _uiscale() is babase.UIScale.MEDIUM else 120) + settings_pos_y = tool_top - ( + 0 if _uiscale() is babase.UIScale.SMALL else + 10 if _uiscale() is babase.UIScale.MEDIUM else + 20 + ) settings_button = bui.buttonwidget( parent=self._root_widget, autoselect=True, @@ -1541,7 +1560,7 @@ def tutorial_confirm_window(): ) bui.buttonwidget( edit=settings_button, - on_activate_call=babase.Call(self.settings, settings_button) + on_activate_call=babase.CallPartial(self.settings, settings_button) ) bui.imagewidget( parent=self._root_widget, @@ -1857,6 +1876,10 @@ def _ok(self) -> None: class PluginManagerWindow(bui.MainWindow): + @override + def main_window_should_preserve_selection(self) -> bool: + return False + def __init__( self, transition: str = "in_right", @@ -2059,7 +2082,8 @@ def draw_category_selection_button(self, post_label): on_activate_call=lambda: loop.create_task(self._on_order_button_press()), button_type="square", textcolor=b_textcolor, - text_scale=0.6 + text_scale=0.6, + enable_sound=False ) else: b = self.alphabet_order_selection_button @@ -2090,6 +2114,7 @@ def draw_category_selection_button(self, post_label): ) if b.exists() else None async def _on_order_button_press(self) -> None: + bui.getsound('deek').play() self.selected_alphabet_order = ('a_z' if self.selected_alphabet_order == 'z_a' else 'z_a') bui.buttonwidget(edit=self.alphabet_order_selection_button, label=('Z - A' if self.selected_alphabet_order == 'z_a' else 'A - Z') @@ -2179,7 +2204,7 @@ def draw_settings_icon(self): ) bui.buttonwidget( controller_button, - on_activate_call=babase.Call( + on_activate_call=babase.CallPartial( PluginManagerSettingsWindow, self.plugin_manager, controller_button @@ -2206,7 +2231,11 @@ def draw_refresh_icon(self): size=(30, 30), button_type="square", label="", - on_activate_call=lambda: loop.create_task(self.refresh()) + on_activate_call=lambda: ( + bui.getsound('deek').play() or + loop.create_task(self.refresh()) + ), + enable_sound=False ) bui.imagewidget( parent=self._root_widget, @@ -2328,19 +2357,27 @@ async def draw_plugin_name(self, plugin, plugins_list): color=color, text=plugin.name.replace('_', ' ').title(), click_activate=True, - on_activate_call=lambda: self.show_plugin_window(plugin, plugins_list), h_align='left', v_align='center', maxwidth=420 ) + bui.textwidget( + text_widget, + on_activate_call=bui.CallPartial( + self.show_plugin_window, + plugin, + plugins_list, + text_widget + ) + ) self.plugins_in_current_view[plugin.name] = text_widget # XXX: This seems nicer. Might wanna use this in future. # text_widget.add_delete_callback(lambda: self.plugins_in_current_view.pop(plugin.name)) - def show_plugin_window(self, plugin, plugins_list): + def show_plugin_window(self, plugin, plugins_list, source): PluginWindow( plugin, - self._root_widget, + source, plugins_list=plugins_list, button_callback=lambda: self.draw_plugin_name(plugin, plugins_list) ) @@ -2482,7 +2519,7 @@ async def draw_ui(self): size=(170, 30), text=setting, value=value, - on_value_change_call=babase.Call(self.toggle_setting, setting), + on_value_change_call=babase.CallPartial(self.toggle_setting, setting), maxwidth=500, textcolor=(0.9, 0.9, 0.9), scale=text_scale * 0.8 @@ -2651,8 +2688,11 @@ def _ok(self) -> None: class NewAllSettingsWindow(AllSettingsWindow): - """Window for selecting a settings category.""" + @override + def main_window_should_preserve_selection(self) -> bool: + return False + """Window for selecting a settings category.""" def __init__( self, transition: str | None = 'in_right', @@ -2840,7 +2880,7 @@ def _b_title( size=(basew, baseh), button_type='square', label='', - on_activate_call=self._do_plugman, + on_activate_call=self._do_plugman ) _b_title(x_offs6, v, pmb, bui.Lstr(value="Plugin Manager")) imgw = imgh = 120 @@ -2850,7 +2890,7 @@ def _b_title( size=(imgw, imgh), color=(0.8, 0.95, 1), texture=bui.gettexture('storeIcon'), - draw_controller=pmb, + draw_controller=pmb ) self._restore_state() @@ -2860,7 +2900,9 @@ def _do_plugman(self) -> None: return self.main_window_replace( - PluginManagerWindow(origin_widget=self._plugman_button) + lambda:PluginManagerWindow( + origin_widget=self._plugman_button + ) ) def _save_state(self) -> None: @@ -2915,7 +2957,7 @@ def _restore_state(self) -> None: # ba_meta export babase.Plugin class EntryPoint(babase.Plugin): def on_app_running(self) -> None: - """Called when the app is being launched.""" + """CallPartialed when the app is being launched.""" from bauiv1lib.settings import allsettings allsettings.AllSettingsWindow = NewAllSettingsWindow DNSBlockWorkaround.apply() From fb1f9c1589c25d0e669ac4a2d802a591172a8bd3 Mon Sep 17 00:00:00 2001 From: BroBordd Date: Tue, 6 Jan 2026 00:20:49 +0200 Subject: [PATCH 2/9] push --- plugin_manager.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/plugin_manager.py b/plugin_manager.py index 30c8f7f13..8d13bc3ca 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -1457,14 +1457,14 @@ async def draw_ui(self): selected_child=selected_btn ) - tool_top = 190 + tool_top = 195 open_pos_x = (60 if _uiscale() is babase.UIScale.SMALL else 60 if _uiscale() is babase.UIScale.MEDIUM else 60) open_pos_y = tool_top - 45 - ( - 0 if _uiscale() is babase.UIScale.SMALL else + 5 if _uiscale() is babase.UIScale.SMALL else 10 if _uiscale() is babase.UIScale.MEDIUM else - 20 + 15 ) open_button = bui.buttonwidget( parent=self._root_widget, @@ -1507,9 +1507,9 @@ def tutorial_confirm_window(): open_pos_x = (60 if _uiscale() is babase.UIScale.SMALL else 60 if _uiscale() is babase.UIScale.MEDIUM else 60) open_pos_y = tool_top - 90 - ( - 0 if _uiscale() is babase.UIScale.SMALL else + 5 if _uiscale() is babase.UIScale.SMALL else 10 if _uiscale() is babase.UIScale.MEDIUM else - 20 + 15 ) open_button = bui.buttonwidget( parent=self._root_widget, @@ -1545,9 +1545,9 @@ def tutorial_confirm_window(): settings_pos_x = (60 if _uiscale() is babase.UIScale.SMALL else 60 if _uiscale() is babase.UIScale.MEDIUM else 60) settings_pos_y = tool_top - ( - 0 if _uiscale() is babase.UIScale.SMALL else + 5 if _uiscale() is babase.UIScale.SMALL else 10 if _uiscale() is babase.UIScale.MEDIUM else - 20 + 15 ) settings_button = bui.buttonwidget( parent=self._root_widget, @@ -2046,7 +2046,7 @@ async def draw_index(self): await self.select_category("All") def draw_plugins_scroll_bar(self): - scroll_size_x = (515 if _uiscale() is babase.UIScale.SMALL else + scroll_size_x = self.scrollx = (515 if _uiscale() is babase.UIScale.SMALL else 430 if _uiscale() is babase.UIScale.MEDIUM else 420) scroll_size_y = (245 if _uiscale() is babase.UIScale.SMALL else 265 if _uiscale() is babase.UIScale.MEDIUM else 335) @@ -2351,7 +2351,7 @@ async def draw_plugin_name(self, plugin, plugins_list): else: text_widget = bui.textwidget( parent=self._columnwidget, - size=(410, 30), + size=(self.scrollx, 30), selectable=True, always_highlight=True, color=color, @@ -2359,7 +2359,7 @@ async def draw_plugin_name(self, plugin, plugins_list): click_activate=True, h_align='left', v_align='center', - maxwidth=420 + maxwidth=self.scrollx-10 ) bui.textwidget( text_widget, From ac3de427397024f337f3f0abcd2b06aea9393aa2 Mon Sep 17 00:00:00 2001 From: BroBordd Date: Fri, 23 Jan 2026 18:34:46 +0200 Subject: [PATCH 3/9] ok --- plugin_manager.py | 684 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 545 insertions(+), 139 deletions(-) diff --git a/plugin_manager.py b/plugin_manager.py index 8d13bc3ca..541f10ad7 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -1,8 +1,5 @@ # ba_meta require api 9 import babase -import _babase -import _bauiv1 -import _bascenev1 import bauiv1 as bui from bauiv1lib import popup, confirm from babase._meta import EXPORT_CLASS_NAME_SHORTCUTS @@ -23,7 +20,7 @@ import hashlib import contextlib -from typing import cast, override +from typing import override from datetime import datetime # Modules used for overriding AllSettingsWindow @@ -35,9 +32,11 @@ # plugin manager repo for testing purpose. CURRENT_TAG = "main" -_env = _babase.env() +_env = babase.env() _app_api_version = babase.app.env.api_version +PLUGIN_ISSUE_TEMPLATE = "plugin-bug-report.md" +GITHUB_ISSUE_META = "{repository_url}/issues/new?template={issue_template}" INDEX_META = "{repository_url}/{content_type}/{tag}/index.json" CHANGELOG_META = "{repository_url}/{content_type}/{tag}/CHANGELOG.md" HEADERS = { @@ -48,20 +47,21 @@ open_popups = [] - -def _add_popup(popup): open_popups.append(popup) - - +def _add_popup(popup): + open_popups.append(popup) def _remove_popup(popup): try: open_popups.remove(popup) except ValueError: pass - - def _uiscale(): return bui.app.ui_v1.uiscale def _regexp_friendly_class_name_shortcut(string): return string.replace(".", "\\.") - +def _by_scale(a,b,c): + return ( + a if _uiscale is babase.UIScale.SMALL else + b if _uiscale is babase.UIScale.MEDIUM else + c + ) REGEXP = { "plugin_api_version": re.compile(b"(?<=ba_meta require api )(.*)"), @@ -425,7 +425,7 @@ async def validate(self): self.get_plugins(), ) except KeyError: - raise CategoryMetadataParseError(f"Failed to parse JSON; missing required fields.") + raise CategoryMetadataParseError("Failed to parse JSON; missing required fields.") else: return True @@ -1296,38 +1296,50 @@ async def draw_ui(self): self.plugins_list[i+1] if (i+1 < len(self.plugins_list)) else None ] - if self.p_n_plugins is not None: - if self.p_n_plugins[0] is not None: - previous_plugin_button = bui.buttonwidget( - parent=self._root_widget, - position=(-12.5*s + (4 if _uiscale() is babase.UIScale.SMALL else -5), - height/2 - 20*s), - label=bui.charstr(bui.SpecialChar.LEFT_ARROW), - size=(25, 40), - color=(1, 0.5, 0.5), - scale=s, - on_activate_call=self.show_previous_plugin, - enable_sound=False, - textcolor=(1,1,1) - ) + # initialize all widgets + previous_plugin_button = None + next_plugin_button = None + author_text_control_btn = None + button1 = None + button2 = None + button3 = None + more_button = None + settings_button = None + tutorial_button = None + + # previous plugin button + if self.p_n_plugins[0] is not None: + previous_plugin_button = bui.buttonwidget( + parent=self._root_widget, + position=(-12.5*s + (4 if _uiscale() is babase.UIScale.SMALL else -5), + height/2 - 20*s), + label=bui.charstr(bui.SpecialChar.LEFT_ARROW), + size=(25, 40), + color=(1, 0.5, 0.5), + scale=s, + on_activate_call=self.show_previous_plugin, + enable_sound=False, + textcolor=(1,1,1) + ) - if self.p_n_plugins[1] is not None: - next_plugin_button = bui.buttonwidget( - parent=self._root_widget, - position=(width - 12.5*s - (8 if _uiscale() - is babase.UIScale.SMALL else 0), height/2 - 20*s), - label=bui.charstr(bui.SpecialChar.RIGHT_ARROW), - size=(25, 40), - color=(1, 0.5, 0.5), - scale=s, - on_activate_call=self.show_next_plugin, - enable_sound=False, - textcolor=(1,1,1) - ) + # next plugin button + if self.p_n_plugins[1] is not None: + next_plugin_button = bui.buttonwidget( + parent=self._root_widget, + position=(width - 12.5*s - (8 if _uiscale() + is babase.UIScale.SMALL else 0), height/2 - 20*s), + label=bui.charstr(bui.SpecialChar.RIGHT_ARROW), + size=(25, 40), + color=(1, 0.5, 0.5), + scale=s, + on_activate_call=self.show_next_plugin, + enable_sound=False, + textcolor=(1,1,1) + ) pos = height * 0.85 plug_name = self.plugin.name.replace('_', ' ').title() - plugin_title = f"{plug_name} (v{self.plugin.latest_compatible_version.number})" + plugin_title = plug_name bui.textwidget( parent=self._root_widget, position=(width * 0.49, pos), @@ -1337,10 +1349,11 @@ async def draw_ui(self): text=plugin_title, scale=text_scale * 1.25, color=color, - maxwidth=width * 0.9 + maxwidth=width * 0.7 - 40 ) pos -= 25 - # Author + + # author text = 'by ' + ', '.join([author["name"] for author in self.plugin.info["authors"]]) author_text_control_btn = bui.buttonwidget( parent=self._root_widget, @@ -1363,7 +1376,8 @@ async def draw_ui(self): draw_controller=author_text_control_btn, ) pos -= 60 - # Info + + # info bui.textwidget( parent=self._root_widget, position=(width * 0.49, pos), @@ -1375,6 +1389,7 @@ async def draw_ui(self): color=color, maxwidth=width * 0.95 ) + b1_color = None b2_color = (0.8, 0.15, 0.35) b3_color = (0.2, 0.8, 0.3) @@ -1382,7 +1397,9 @@ async def draw_ui(self): button_size = (80 * s, 40 * s) to_draw_button1 = True - to_draw_button4 = False + to_draw_settings_button = False + has_update = False + if self.plugin.is_installed: self.local_plugin = self.plugin.get_local() if not await self.local_plugin.has_plugins(): @@ -1393,7 +1410,7 @@ async def draw_ui(self): b1_color = (0.6, 0.53, 0.63) button1_action = self.disable if self.local_plugin.has_settings(): - to_draw_button4 = True + to_draw_settings_button = True else: button1_label = "Enable" button1_action = self.enable @@ -1407,8 +1424,9 @@ async def draw_ui(self): button1_label = "Install" button1_action = self.install + # button1 if to_draw_button1: - selected_btn = bui.buttonwidget( + button1 = bui.buttonwidget( parent=self._root_widget, position=( width * (0.1 if self.plugin.is_installed and has_update else @@ -1423,8 +1441,9 @@ async def draw_ui(self): label=button1_label ) + # button2 if self.plugin.is_installed: - selected_btn = bui.buttonwidget( + button2 = bui.buttonwidget( parent=self._root_widget, position=( width * (0.4 if has_update or not to_draw_button1 else 0.55), pos), @@ -1437,8 +1456,9 @@ async def draw_ui(self): label=button2_label ) + # button3 if has_update: - selected_btn = bui.buttonwidget( + button3 = bui.buttonwidget( parent=self._root_widget, position=(width * 0.7, pos), size=button_size, @@ -1451,124 +1471,246 @@ async def draw_ui(self): label=button3_label ) + # determine selected button + selected_btn = button3 if has_update and self.plugin.is_installed else ( + button2 if self.plugin.is_installed else button1 + ) + bui.containerwidget( edit=self._root_widget, on_cancel_call=self._cancel, selected_child=selected_btn ) - tool_top = 195 - - open_pos_x = (60 if _uiscale() is babase.UIScale.SMALL else - 60 if _uiscale() is babase.UIScale.MEDIUM else 60) - open_pos_y = tool_top - 45 - ( - 5 if _uiscale() is babase.UIScale.SMALL else - 10 if _uiscale() is babase.UIScale.MEDIUM else - 15 - ) - open_button = bui.buttonwidget( + # button math + button_x = width - 90 + button_y = 210 - _by_scale(5,10,15) + button_color = (0, 0.75, 0.75) + button_image_color = (0.8, 0.95, 1) + button_text_color = (1,1,1,1) + + # more button + more_button = bui.buttonwidget( parent=self._root_widget, - autoselect=True, - position=(open_pos_x, open_pos_y), + position=(button_x, button_y), size=(40, 40), - button_type="square", - label="", - color=(0.6, 0.53, 0.63), - on_activate_call=lambda: bui.open_url(self.plugin.view_url) + button_type='square', + label='', + color=button_color + ) + bui.buttonwidget( + edit=more_button, + on_activate_call=babase.CallPartial( + MoreWindow, + plugin=self.plugin, + origin=more_button + ) ) bui.imagewidget( parent=self._root_widget, - position=(open_pos_x, open_pos_y), + position=(button_x, button_y), size=(40, 40), - color=(0.8, 0.95, 1), - texture=bui.gettexture("file"), - draw_controller=open_button + color=button_image_color, + texture=bui.gettexture('file'), + draw_controller=more_button ) bui.textwidget( parent=self._root_widget, - position=(open_pos_x-3, open_pos_y+12), - text="Source", + position=(button_x-3, button_y+12), + text='More...', size=(10, 10), - draw_controller=open_button, - color=(1, 1, 1, 1), + draw_controller=more_button, + color=button_text_color, rotate=25, scale=0.45 ) - # Below snippet handles the tutorial button in the plugin window - tutorial_url = self.plugin.info["external_url"] - if tutorial_url: - def tutorial_confirm_window(): - text = "This will take you to \n\""+self.plugin.info["external_url"] + "\"" - tutorial_confirm_window = confirm.ConfirmWindow( - text=text, - action=lambda: bui.open_url(self.plugin.info["external_url"]), - ) - open_pos_x = (60 if _uiscale() is babase.UIScale.SMALL else - 60 if _uiscale() is babase.UIScale.MEDIUM else 60) - open_pos_y = tool_top - 90 - ( - 5 if _uiscale() is babase.UIScale.SMALL else - 10 if _uiscale() is babase.UIScale.MEDIUM else - 15 - ) - open_button = bui.buttonwidget( + # settings button + if to_draw_settings_button: + button_y -= 50 + settings_button = bui.buttonwidget( parent=self._root_widget, autoselect=True, - position=(open_pos_x, open_pos_y), + position=(button_x, button_y), size=(40, 40), button_type="square", label="", - color=(0.6, 0.53, 0.63), - on_activate_call=tutorial_confirm_window + color=button_color + ) + bui.buttonwidget( + edit=settings_button, + on_activate_call=babase.CallPartial(self.settings, settings_button) + ) + bui.imagewidget( + parent=self._root_widget, + position=(button_x, button_y), + size=(40, 40), + color=button_image_color, + texture=bui.gettexture("settingsIcon"), + draw_controller=settings_button ) + # tutorial + tutorial_url = self.plugin.info['external_url'] + if tutorial_url: + button_y -= 50 + tutorial_button = bui.buttonwidget( + parent=self._root_widget, + autoselect=True, + position=(button_x, button_y), + size=(40, 40), + button_type="square", + label="", + color=button_color + ) bui.imagewidget( parent=self._root_widget, - position=(open_pos_x, open_pos_y), + position=(button_x, button_y), size=(40, 40), - color=(0.8, 0.95, 1), + color=button_image_color, texture=bui.gettexture("frameInset"), - draw_controller=open_button + draw_controller=tutorial_button ) bui.textwidget( parent=self._root_widget, - position=(open_pos_x - 3, open_pos_y + 12), + position=(button_x - 3, button_y + 12), text="Tutorial", size=(10, 10), - draw_controller=open_button, - color=(1, 1, 1, 1), + draw_controller=tutorial_button, + color=button_text_color, rotate=25, scale=0.45 ) + bui.buttonwidget( + tutorial_button, + on_activate_call=bui.CallPartial( + confirm.ConfirmWindow, + text=f'This will take you to:\n{tutorial_url}', + origin_widget=tutorial_button, + action=bui.CallPartial( + bui.open_url, tutorial_url + ) + ) + ) + # navigation #XXX + if button1 and button2 and button3: + # three buttons + leftmost_button = button1 + center_button = button2 + rightmost_button = button3 + elif button1 and button2: + # two buttons + leftmost_button = button1 + center_button = None + rightmost_button = button2 + elif button2 and button3: + # two buttons + leftmost_button = button2 + center_button = None + rightmost_button = button3 + elif button1: + # one button + leftmost_button = button1 + center_button = None + rightmost_button = button1 + elif button2: + # one button + leftmost_button = button2 + center_button = None + rightmost_button = button2 + else: + leftmost_button = center_button = rightmost_button = None + + # determine vertical stack + bottom_stack = tutorial_button or settings_button or more_button + top_stack = more_button - if to_draw_button4: - settings_pos_x = (60 if _uiscale() is babase.UIScale.SMALL else - 60 if _uiscale() is babase.UIScale.MEDIUM else 60) - settings_pos_y = tool_top - ( - 5 if _uiscale() is babase.UIScale.SMALL else - 10 if _uiscale() is babase.UIScale.MEDIUM else - 15 + # previous plugin button + if previous_plugin_button is not None: + bui.buttonwidget( + edit=previous_plugin_button, + left_widget=next_plugin_button, + right_widget=leftmost_button, + up_widget=author_text_control_btn, + down_widget=leftmost_button ) - settings_button = bui.buttonwidget( - parent=self._root_widget, - autoselect=True, - position=(settings_pos_x, settings_pos_y), - size=(40, 40), - button_type="square", - label="", - color=(0, 0.75, 0.75) + + # next plugin button + if next_plugin_button is not None: + bui.buttonwidget( + edit=next_plugin_button, + left_widget=bottom_stack, + right_widget=bui.get_special_widget('squad_button'), + up_widget=author_text_control_btn, + down_widget=bottom_stack ) + + # author button + bui.buttonwidget( + edit=author_text_control_btn, + left_widget=previous_plugin_button, + right_widget=top_stack, + up_widget=center_button or leftmost_button, + down_widget=leftmost_button + ) + + # button1 + if button1 is not None: + bui.buttonwidget( + edit=button1, + left_widget=previous_plugin_button, + right_widget=center_button or bottom_stack, + up_widget=author_text_control_btn, + down_widget=author_text_control_btn + ) + + # button2 + if button2 is not None: + bui.buttonwidget( + edit=button2, + left_widget=button1 or previous_plugin_button, + right_widget=button3 or bottom_stack, + up_widget=author_text_control_btn, + down_widget=author_text_control_btn + ) + + # button3 + if button3 is not None: + bui.buttonwidget( + edit=button3, + left_widget=center_button or leftmost_button, + right_widget=bottom_stack, + up_widget=author_text_control_btn, + down_widget=author_text_control_btn + ) + + # more button + bui.buttonwidget( + edit=more_button, + left_widget=rightmost_button, + right_widget=next_plugin_button, + up_widget=author_text_control_btn, + down_widget=settings_button + ) + + # settings button + if settings_button is not None: bui.buttonwidget( edit=settings_button, - on_activate_call=babase.CallPartial(self.settings, settings_button) + left_widget=rightmost_button, + right_widget=next_plugin_button, + up_widget=more_button, + down_widget=tutorial_button ) - bui.imagewidget( - parent=self._root_widget, - position=(settings_pos_x, settings_pos_y), - size=(40, 40), - color=(0.8, 0.95, 1), - texture=bui.gettexture("settingsIcon"), - draw_controller=settings_button + + # tutorial button + if tutorial_button is not None: + bui.buttonwidget( + edit=tutorial_button, + left_widget=rightmost_button, + right_widget=next_plugin_button, + up_widget=settings_button or more_button, + down_widget=rightmost_button ) def _ok(self) -> None: @@ -1645,6 +1787,192 @@ async def update(self): await self.plugin.update() bui.getsound('shieldUp').play() +class MoreWindow: + def __init__(self, plugin, origin=None): + _add_popup(self) + # collect info + last_updated = None + for value in plugin.info['versions'].values(): + if value['api_version'] == _app_api_version: + last_updated = value['released_on'] + # math + step = 40 + margin = 20 + width = 350 + px,py = margin,margin + px2 = width-(margin+step) + mw = px2-margin*2 + # root + self.transition = origin and 'scale' or 'left' + self._root_widget = bui.containerwidget( + on_outside_click_call=self._back, + transition=f'in_{self.transition}', + scale=_by_scale(1.5,1.5,1), + scale_origin_stack_offset=( + origin and + origin.get_screen_space_center() + or None + ) + ) + # last updated + bui.textwidget( + parent=self._root_widget, + position=(px,py), + h_align='left', + v_align='center', + maxwidth=width-margin*2, + max_height=step, + size=(step,step), + color=(1,1,1,0.5), + text=( + last_updated and + f'Last updated on: {last_updated}' + or 'Unknown' + ) + ) + # version + py += margin+step/3 + bui.textwidget( + parent=self._root_widget, + position=(px,py), + h_align='left', + v_align='center', + maxwidth=mw, + max_height=step, + size=(step,step), + color=(1,1,1,0.5), + text=f"Version {plugin.latest_compatible_version.number}" + ) + # source url + py += step+margin + bui.textwidget( + parent=self._root_widget, + position=(px,py), + h_align='left', + v_align='center', + maxwidth=mw, + max_height=step, + size=(step,step), + text='Source URL:' + ) + source_button = bui.buttonwidget( + parent=self._root_widget, + autoselect=True, + position=(px2,py), + size=(step,step), + color=(0.6, 0.53, 0.63), + button_type='square', + label='', + on_activate_call=bui.CallPartial( + bui.open_url, + plugin.view_url + ) + ) + bui.imagewidget( + parent=self._root_widget, + position=(px2,py), + size=(step,step), + color=(0.8, 0.95, 1), + texture=bui.gettexture('file'), + draw_controller=source_button + ) + # report bug + py += step+margin + bui.textwidget( + parent=self._root_widget, + position=(px,py), + h_align='left', + v_align='center', + maxwidth=mw, + max_height=step, + size=(step,step), + text='Report a bug:' + ) + report_button = bui.buttonwidget( + parent=self._root_widget, + position=(px2,py), + size=(step,step), + button_type='square', + color=(0.6, 0.53, 0.63), + label='', + on_activate_call=bui.CallPartial( + bui.open_url, + GITHUB_ISSUE_META.format( + repository_url=REPOSITORY_URL, + issue_template=PLUGIN_ISSUE_TEMPLATE + ) + ) + ) + bui.imagewidget( + parent=self._root_widget, + position=(px2,py), + size=(step,step), + color=(0.8, 0.95, 1), + texture=bui.gettexture('githubLogo'), + draw_controller=report_button + ) + # back + py += step+margin + back_button = bui.buttonwidget( + parent=self._root_widget, + position=(px,py), + size=(step,step), + label=babase.charstr(babase.SpecialChar.BACK), + button_type='backSmall', + on_activate_call=self._back, + enable_sound=False + ) + # title + px += margin + bui.textwidget( + parent=self._root_widget, + position=(px+(step+margin),py), + h_align='left', + v_align='center', + maxwidth=width-margin*2, + max_height=step*2, + size=(step,step), + text='More info', + scale=2 + ) + # finally + py += step+margin + bui.containerwidget( + edit=self._root_widget, + cancel_button=back_button, + size=(width,py) + ) + # navigation + bui.buttonwidget( + edit=back_button, + left_widget=report_button, + right_widget=report_button, + up_widget=source_button, + down_widget=report_button + ) + + bui.buttonwidget( + edit=source_button, + left_widget=back_button, + right_widget=back_button, + up_widget=report_button, + down_widget=back_button + ) + + bui.buttonwidget( + edit=report_button, + left_widget=back_button, + right_widget=back_button, + up_widget=back_button, + down_widget=source_button + ) + def _back(self) -> None: + _remove_popup(self) + bui.getsound('swish').play() + bui.containerwidget( + edit=self._root_widget, + transition=f'out_{self.transition}' + ) class PluginCustomSourcesWindow(popup.PopupWindow): def __init__(self, origin_widget): @@ -1983,12 +2311,11 @@ def __init__( @override def get_main_window_state(self) -> bui.MainWindowState: # Support recreating our window for back/refresh purposes. - global open_popups # Close all open popups if ui changes. # check pr #390 for more info. - for popup in open_popups: + for pup in open_popups: try: - bui.containerwidget(edit=popup._root_widget, transition='out_scale') + bui.containerwidget(edit=pup._root_widget, transition='out_scale') except: pass cls = type(self) @@ -2054,7 +2381,7 @@ def draw_plugins_scroll_bar(self): 50 if _uiscale() is babase.UIScale.MEDIUM else 70) scroll_pos_y = (100 if _uiscale() is babase.UIScale.SMALL else 35 if _uiscale() is babase.UIScale.MEDIUM else 40) - self._scrollwidget = bui.scrollwidget( + self._scrollwidget = sw = bui.scrollwidget( parent=self._root_widget, size=(scroll_size_x, scroll_size_y), position=(scroll_pos_x, scroll_pos_y) @@ -2064,6 +2391,15 @@ def draw_plugins_scroll_bar(self): border=2, margin=0 ) + bui.widget( + sw, + left_widget=self._back_button, + up_widget=self._filter_widget + ) + bui.widget( + self._filter_widget, + down_widget=sw + ) def draw_category_selection_button(self, post_label): category_pos_x = (440 if _uiscale() is babase.UIScale.SMALL else @@ -2083,7 +2419,10 @@ def draw_category_selection_button(self, post_label): button_type="square", textcolor=b_textcolor, text_scale=0.6, - enable_sound=False + enable_sound=False, + left_widget=self._filter_widget, + down_widget=self._scrollwidget, + up_widget=self._back_button ) else: b = self.alphabet_order_selection_button @@ -2102,10 +2441,14 @@ def draw_category_selection_button(self, post_label): label=label, button_type="square", textcolor=b_textcolor, - text_scale=0.6 + text_scale=0.6, + up_widget=self._back_button ) bui.buttonwidget( - edit=b, on_activate_call=lambda: self.show_categories_window(source=b)), + edit=b, + down_widget=self._scrollwidget, + on_activate_call=lambda: self.show_categories_window(source=b) + ) else: b = self.category_selection_button bui.buttonwidget( @@ -2200,7 +2543,9 @@ def draw_settings_icon(self): position=(settings_pos_x, settings_pos_y), size=(30, 30), button_type="square", - label="" + label="", + left_widget=self._scrollwidget, + right_widget=bui.get_special_widget('squad_button') ) bui.buttonwidget( controller_button, @@ -2235,7 +2580,13 @@ def draw_refresh_icon(self): bui.getsound('deek').play() or loop.create_task(self.refresh()) ), - enable_sound=False + enable_sound=False, + left_widget=self._scrollwidget, + right_widget=bui.get_special_widget('squad_button') + ) + bui.widget( + self._scrollwidget, + right_widget=controller_button ) bui.imagewidget( parent=self._root_widget, @@ -2310,21 +2661,25 @@ def return_name(val): else: plugin_names_to_draw = plugins - [plugin.delete() for plugin in self._columnwidget.get_children()] + for plugin in self._columnwidget.get_children(): + plugin.delete() text_widget = bui.textwidget(parent=self._columnwidget) text_widget.delete() # await asyncio.gather(*plugin_names_to_draw) plugin_names_ready_to_draw = [] for plugin in plugin_names_to_draw: - try: - lcv = plugin.latest_compatible_version + try: plugin.latest_compatible_version except NoCompatibleVersion: continue plugin_names_ready_to_draw += [plugin] for i, plugin in enumerate(plugin_names_ready_to_draw): await self.draw_plugin_name(plugin, plugin_names_ready_to_draw) + kids = self._columnwidget.get_children() + first_child,last_child = kids[::len(kids)-1] + bui.widget(first_child,up_widget=self._filter_widget) + bui.widget(last_child,down_widget=self._back_button) async def draw_plugin_name(self, plugin, plugins_list): @@ -2434,7 +2789,6 @@ def __init__(self, plugin_manager, origin_widget): self._plugin_manager = plugin_manager self.scale_origin = origin_widget.get_screen_space_center() self.settings = babase.app.config["Community Plugin Manager"]["Settings"].copy() - loop.create_task(self.draw_ui()) async def draw_ui(self): @@ -2512,8 +2866,9 @@ async def draw_ui(self): ) pos -= 40 + self.checkboxes = [] for setting, value in self.settings.items(): - bui.checkboxwidget( + chk = bui.checkboxwidget( parent=self._root_widget, position=(width * 0.1, pos), size=(170, 30), @@ -2524,7 +2879,18 @@ async def draw_ui(self): textcolor=(0.9, 0.9, 0.9), scale=text_scale * 0.8 ) + self.checkboxes.append(chk) pos -= 34 * text_scale + bui.widget( + self.checkboxes[0], + up_widget=self._changelog_button + ) + bui.widget( + self._changelog_button, + down_widget=self.checkboxes[0], + left_widget=self.checkboxes[0], + right_widget=self.checkboxes[0] + ) pos = height - 200 bui.textwidget( @@ -2554,7 +2920,12 @@ async def draw_ui(self): color=discord_bg_color, button_type='square', text_scale=1, - label="" + label="", + down_widget=self._changelog_button + ) + bui.widget( + self._changelog_button, + up_widget=self.discord_button ) bui.imagewidget( @@ -2576,7 +2947,9 @@ async def draw_ui(self): color=github_bg_color, button_type='square', text_scale=1, - label='' + label='', + up_widget=self.checkboxes[-1], + down_widget=self._changelog_button ) bui.imagewidget( @@ -2608,7 +2981,14 @@ async def draw_ui(self): button_type='square', text_scale=1, color=(0, 0.7, 0), - label=update_button_label + label=update_button_label, + up_widget=self.checkboxes[-1], + down_widget=self._changelog_button, + right_widget=self.discord_button + ) + bui.widget( + self.discord_button, + left_widget=self._update_button ) self._restart_to_reload_changes_text = bui.textwidget( parent=self._root_widget, @@ -2658,6 +3038,28 @@ def toggle_setting(self, setting, set_value): scale=0 if check else 1, selectable=(not check) ) + bui.widget( + self._changelog_button, + right_widget=( + check and self.checkboxes[0] + or self._save_button + ), + left_widget=( + check and self.checkboxes[0] + or self._save_button + ) + ) + bui.widget( + self._update_button, + up_widget=( + check and self.checkboxes[0] + or self._save_button + ), + down_widget=( + check and self._changelog_button + or self._save_button + ) + ) def save_settings_button(self): babase.app.config["Community Plugin Manager"]["Settings"] = self.settings.copy() @@ -2837,9 +3239,12 @@ def _b_title( position=(x_offs4, v), size=(basew, baseh), button_type='square', + up_widget=pbtn, + right_widget=pbtn, label='', on_activate_call=self._do_audio, ) + bui.buttonwidget(gfxb,right_widget=abtn) _b_title(x_offs4, v, abtn, bui.Lstr(resource=f'{self._r}.audioText')) imgw = imgh = 120 bui.imagewidget( @@ -2880,6 +3285,7 @@ def _b_title( size=(basew, baseh), button_type='square', label='', + up_widget=abtn, on_activate_call=self._do_plugman ) _b_title(x_offs6, v, pmb, bui.Lstr(value="Plugin Manager")) From 57bff9df716377f0be4ddd0e2e96b8a2613a72a5 Mon Sep 17 00:00:00 2001 From: BroBordd Date: Fri, 23 Jan 2026 18:40:19 +0200 Subject: [PATCH 4/9] ok --- plugin_manager.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugin_manager.py b/plugin_manager.py index 541f10ad7..43723fda5 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -1926,14 +1926,15 @@ def __init__(self, plugin, origin=None): px += margin bui.textwidget( parent=self._root_widget, - position=(px+(step+margin),py), + position=(px+(step),py), h_align='left', v_align='center', maxwidth=width-margin*2, max_height=step*2, size=(step,step), text='More info', - scale=2 + scale=1.4, + shadow=0.8 ) # finally py += step+margin From fff386a2ac28575e7622dd0d3b878cab0f67a87d Mon Sep 17 00:00:00 2001 From: BroBordd Date: Fri, 23 Jan 2026 18:43:28 +0200 Subject: [PATCH 5/9] ok --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d86931869..196f6022c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,11 @@ ### 1.1.5 (05-01-2026) -- Small UI Improvements. +- Various UI bugfixes and improvements +- Optimized PluginWindow displays +- Added a compact MoreWindow +- Better support for arrow control overall +- Cleaned up old stuffs in code ### 1.1.4 (09-08-2025) From a0ade9cf30beede26b8bf919647c3fd852d9f3b8 Mon Sep 17 00:00:00 2001 From: BroBordd <192699453+BroBordd@users.noreply.github.com> Date: Fri, 23 Jan 2026 16:47:30 +0000 Subject: [PATCH 6/9] [ci] apply-plugin-metadata-and-formatting --- plugin_manager.py | 99 +++++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 43 deletions(-) diff --git a/plugin_manager.py b/plugin_manager.py index 43723fda5..09f1ee6a6 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -47,22 +47,30 @@ open_popups = [] + def _add_popup(popup): open_popups.append(popup) + + def _remove_popup(popup): try: open_popups.remove(popup) except ValueError: pass + + def _uiscale(): return bui.app.ui_v1.uiscale def _regexp_friendly_class_name_shortcut(string): return string.replace(".", "\\.") -def _by_scale(a,b,c): + + +def _by_scale(a, b, c): return ( a if _uiscale is babase.UIScale.SMALL else b if _uiscale is babase.UIScale.MEDIUM else c ) + REGEXP = { "plugin_api_version": re.compile(b"(?<=ba_meta require api )(.*)"), "plugin_entry_points": re.compile( @@ -1319,7 +1327,7 @@ async def draw_ui(self): scale=s, on_activate_call=self.show_previous_plugin, enable_sound=False, - textcolor=(1,1,1) + textcolor=(1, 1, 1) ) # next plugin button @@ -1334,7 +1342,7 @@ async def draw_ui(self): scale=s, on_activate_call=self.show_next_plugin, enable_sound=False, - textcolor=(1,1,1) + textcolor=(1, 1, 1) ) pos = height * 0.85 @@ -1352,7 +1360,7 @@ async def draw_ui(self): maxwidth=width * 0.7 - 40 ) pos -= 25 - + # author text = 'by ' + ', '.join([author["name"] for author in self.plugin.info["authors"]]) author_text_control_btn = bui.buttonwidget( @@ -1376,7 +1384,7 @@ async def draw_ui(self): draw_controller=author_text_control_btn, ) pos -= 60 - + # info bui.textwidget( parent=self._root_widget, @@ -1389,7 +1397,7 @@ async def draw_ui(self): color=color, maxwidth=width * 0.95 ) - + b1_color = None b2_color = (0.8, 0.15, 0.35) b3_color = (0.2, 0.8, 0.3) @@ -1399,7 +1407,7 @@ async def draw_ui(self): to_draw_button1 = True to_draw_settings_button = False has_update = False - + if self.plugin.is_installed: self.local_plugin = self.plugin.get_local() if not await self.local_plugin.has_plugins(): @@ -1484,11 +1492,11 @@ async def draw_ui(self): # button math button_x = width - 90 - button_y = 210 - _by_scale(5,10,15) + button_y = 210 - _by_scale(5, 10, 15) button_color = (0, 0.75, 0.75) button_image_color = (0.8, 0.95, 1) - button_text_color = (1,1,1,1) - + button_text_color = (1, 1, 1, 1) + # more button more_button = bui.buttonwidget( parent=self._root_widget, @@ -1635,7 +1643,7 @@ async def draw_ui(self): down_widget=leftmost_button ) - # next plugin button + # next plugin button if next_plugin_button is not None: bui.buttonwidget( edit=next_plugin_button, @@ -1787,6 +1795,7 @@ async def update(self): await self.plugin.update() bui.getsound('shieldUp').play() + class MoreWindow: def __init__(self, plugin, origin=None): _add_popup(self) @@ -1799,7 +1808,7 @@ def __init__(self, plugin, origin=None): step = 40 margin = 20 width = 350 - px,py = margin,margin + px, py = margin, margin px2 = width-(margin+step) mw = px2-margin*2 # root @@ -1807,7 +1816,7 @@ def __init__(self, plugin, origin=None): self._root_widget = bui.containerwidget( on_outside_click_call=self._back, transition=f'in_{self.transition}', - scale=_by_scale(1.5,1.5,1), + scale=_by_scale(1.5, 1.5, 1), scale_origin_stack_offset=( origin and origin.get_screen_space_center() @@ -1817,13 +1826,13 @@ def __init__(self, plugin, origin=None): # last updated bui.textwidget( parent=self._root_widget, - position=(px,py), + position=(px, py), h_align='left', v_align='center', maxwidth=width-margin*2, max_height=step, - size=(step,step), - color=(1,1,1,0.5), + size=(step, step), + color=(1, 1, 1, 0.5), text=( last_updated and f'Last updated on: {last_updated}' @@ -1834,32 +1843,32 @@ def __init__(self, plugin, origin=None): py += margin+step/3 bui.textwidget( parent=self._root_widget, - position=(px,py), + position=(px, py), h_align='left', v_align='center', maxwidth=mw, max_height=step, - size=(step,step), - color=(1,1,1,0.5), + size=(step, step), + color=(1, 1, 1, 0.5), text=f"Version {plugin.latest_compatible_version.number}" ) # source url py += step+margin bui.textwidget( parent=self._root_widget, - position=(px,py), + position=(px, py), h_align='left', v_align='center', maxwidth=mw, max_height=step, - size=(step,step), + size=(step, step), text='Source URL:' ) source_button = bui.buttonwidget( parent=self._root_widget, autoselect=True, - position=(px2,py), - size=(step,step), + position=(px2, py), + size=(step, step), color=(0.6, 0.53, 0.63), button_type='square', label='', @@ -1870,8 +1879,8 @@ def __init__(self, plugin, origin=None): ) bui.imagewidget( parent=self._root_widget, - position=(px2,py), - size=(step,step), + position=(px2, py), + size=(step, step), color=(0.8, 0.95, 1), texture=bui.gettexture('file'), draw_controller=source_button @@ -1880,18 +1889,18 @@ def __init__(self, plugin, origin=None): py += step+margin bui.textwidget( parent=self._root_widget, - position=(px,py), + position=(px, py), h_align='left', v_align='center', maxwidth=mw, max_height=step, - size=(step,step), + size=(step, step), text='Report a bug:' ) report_button = bui.buttonwidget( parent=self._root_widget, - position=(px2,py), - size=(step,step), + position=(px2, py), + size=(step, step), button_type='square', color=(0.6, 0.53, 0.63), label='', @@ -1905,8 +1914,8 @@ def __init__(self, plugin, origin=None): ) bui.imagewidget( parent=self._root_widget, - position=(px2,py), - size=(step,step), + position=(px2, py), + size=(step, step), color=(0.8, 0.95, 1), texture=bui.gettexture('githubLogo'), draw_controller=report_button @@ -1915,8 +1924,8 @@ def __init__(self, plugin, origin=None): py += step+margin back_button = bui.buttonwidget( parent=self._root_widget, - position=(px,py), - size=(step,step), + position=(px, py), + size=(step, step), label=babase.charstr(babase.SpecialChar.BACK), button_type='backSmall', on_activate_call=self._back, @@ -1926,12 +1935,12 @@ def __init__(self, plugin, origin=None): px += margin bui.textwidget( parent=self._root_widget, - position=(px+(step),py), + position=(px+(step), py), h_align='left', v_align='center', maxwidth=width-margin*2, max_height=step*2, - size=(step,step), + size=(step, step), text='More info', scale=1.4, shadow=0.8 @@ -1941,7 +1950,7 @@ def __init__(self, plugin, origin=None): bui.containerwidget( edit=self._root_widget, cancel_button=back_button, - size=(width,py) + size=(width, py) ) # navigation bui.buttonwidget( @@ -1967,6 +1976,7 @@ def __init__(self, plugin, origin=None): up_widget=back_button, down_widget=source_button ) + def _back(self) -> None: _remove_popup(self) bui.getsound('swish').play() @@ -1975,6 +1985,7 @@ def _back(self) -> None: transition=f'out_{self.transition}' ) + class PluginCustomSourcesWindow(popup.PopupWindow): def __init__(self, origin_widget): self.selected_source = None @@ -2375,7 +2386,7 @@ async def draw_index(self): def draw_plugins_scroll_bar(self): scroll_size_x = self.scrollx = (515 if _uiscale() is babase.UIScale.SMALL else - 430 if _uiscale() is babase.UIScale.MEDIUM else 420) + 430 if _uiscale() is babase.UIScale.MEDIUM else 420) scroll_size_y = (245 if _uiscale() is babase.UIScale.SMALL else 265 if _uiscale() is babase.UIScale.MEDIUM else 335) scroll_pos_x = (70 if _uiscale() is babase.UIScale.SMALL else @@ -2670,7 +2681,8 @@ def return_name(val): plugin_names_ready_to_draw = [] for plugin in plugin_names_to_draw: - try: plugin.latest_compatible_version + try: + plugin.latest_compatible_version except NoCompatibleVersion: continue plugin_names_ready_to_draw += [plugin] @@ -2678,9 +2690,9 @@ def return_name(val): for i, plugin in enumerate(plugin_names_ready_to_draw): await self.draw_plugin_name(plugin, plugin_names_ready_to_draw) kids = self._columnwidget.get_children() - first_child,last_child = kids[::len(kids)-1] - bui.widget(first_child,up_widget=self._filter_widget) - bui.widget(last_child,down_widget=self._back_button) + first_child, last_child = kids[::len(kids)-1] + bui.widget(first_child, up_widget=self._filter_widget) + bui.widget(last_child, down_widget=self._back_button) async def draw_plugin_name(self, plugin, plugins_list): @@ -3096,6 +3108,7 @@ def main_window_should_preserve_selection(self) -> bool: return False """Window for selecting a settings category.""" + def __init__( self, transition: str | None = 'in_right', @@ -3245,7 +3258,7 @@ def _b_title( label='', on_activate_call=self._do_audio, ) - bui.buttonwidget(gfxb,right_widget=abtn) + bui.buttonwidget(gfxb, right_widget=abtn) _b_title(x_offs4, v, abtn, bui.Lstr(resource=f'{self._r}.audioText')) imgw = imgh = 120 bui.imagewidget( @@ -3307,7 +3320,7 @@ def _do_plugman(self) -> None: return self.main_window_replace( - lambda:PluginManagerWindow( + lambda: PluginManagerWindow( origin_widget=self._plugman_button ) ) From 1cd05c086eeba9185ce5666e79ed69618e38a0ee Mon Sep 17 00:00:00 2001 From: BroBordd <192699453+BroBordd@users.noreply.github.com> Date: Fri, 23 Jan 2026 16:47:31 +0000 Subject: [PATCH 7/9] [ci] apply-version-metadata --- index.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/index.json b/index.json index ec82e55e8..0a4fe1538 100644 --- a/index.json +++ b/index.json @@ -1,7 +1,12 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { - "1.1.5": null, + "1.1.5": { + "api_version": 9, + "commit_sha": "a0ade9c", + "released_on": "23-01-2026", + "md5sum": "b376805cf71251df55c4d83558f43cd1" + }, "1.1.4": { "api_version": 9, "commit_sha": "1a9468d", @@ -279,4 +284,4 @@ "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugins/maps.json" ], "external_source_url": "https://github.com/{repository}/{content_type}/{tag}/category.json" -} +} \ No newline at end of file From a552bd3905f7b0418f6809cb1b1657848715721f Mon Sep 17 00:00:00 2001 From: Loup-Garou911XD <90267658+Loup-Garou911XD@users.noreply.github.com> Date: Mon, 26 Jan 2026 02:51:12 +0530 Subject: [PATCH 8/9] minor cleanup --- CHANGELOG.md | 2 +- index.json | 7 +------ plugin_manager.py | 15 +++++++++++---- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 196f6022c..65c4e009f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## Plugin Manager (dd-mm-yyyy) -### 1.1.5 (05-01-2026) +### 1.1.5 (26-01-2026) - Various UI bugfixes and improvements - Optimized PluginWindow displays diff --git a/index.json b/index.json index 0a4fe1538..b8685cca3 100644 --- a/index.json +++ b/index.json @@ -1,12 +1,7 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { - "1.1.5": { - "api_version": 9, - "commit_sha": "a0ade9c", - "released_on": "23-01-2026", - "md5sum": "b376805cf71251df55c4d83558f43cd1" - }, + "1.1.5": null, "1.1.4": { "api_version": 9, "commit_sha": "1a9468d", diff --git a/plugin_manager.py b/plugin_manager.py index 09f1ee6a6..0b76453fd 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -1832,7 +1832,6 @@ def __init__(self, plugin, origin=None): maxwidth=width-margin*2, max_height=step, size=(step, step), - color=(1, 1, 1, 0.5), text=( last_updated and f'Last updated on: {last_updated}' @@ -1849,8 +1848,7 @@ def __init__(self, plugin, origin=None): maxwidth=mw, max_height=step, size=(step, step), - color=(1, 1, 1, 0.5), - text=f"Version {plugin.latest_compatible_version.number}" + text=f"Version: {plugin.latest_compatible_version.number}" ) # source url py += step+margin @@ -1885,6 +1883,15 @@ def __init__(self, plugin, origin=None): texture=bui.gettexture('file'), draw_controller=source_button ) + bui.textwidget( + parent=self._root_widget, + position=(px2-3, py+12), + text='source', + size=(10, 10), + draw_controller=source_button, + rotate=25, + scale=0.45 + ) # report bug py += step+margin bui.textwidget( @@ -3377,7 +3384,7 @@ def _restore_state(self) -> None: # ba_meta export babase.Plugin class EntryPoint(babase.Plugin): def on_app_running(self) -> None: - """CallPartialed when the app is being launched.""" + """Called when the app is being launched.""" from bauiv1lib.settings import allsettings allsettings.AllSettingsWindow = NewAllSettingsWindow DNSBlockWorkaround.apply() From de7076f5f71b93afe548e1a1e4905fa87fd670ce Mon Sep 17 00:00:00 2001 From: Loup-Garou911XD <90267658+Loup-Garou911XD@users.noreply.github.com> Date: Sun, 25 Jan 2026 21:22:02 +0000 Subject: [PATCH 9/9] [ci] apply-version-metadata --- index.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/index.json b/index.json index b8685cca3..60df84979 100644 --- a/index.json +++ b/index.json @@ -1,7 +1,12 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { - "1.1.5": null, + "1.1.5": { + "api_version": 9, + "commit_sha": "a552bd3", + "released_on": "25-01-2026", + "md5sum": "adf9bfcbbb93808454ba9fce345a1035" + }, "1.1.4": { "api_version": 9, "commit_sha": "1a9468d",