diff --git a/CHANGELOG.md b/CHANGELOG.md index 9390c7fd..24b40e86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,7 @@ ## Plugin Manager (dd-mm-yyyy) +### 1.1.11 (15-07-2026) + +- New plugin manager logo ### 1.1.10 (12-06-2026) diff --git a/index.json b/index.json index 120a1ba7..1cf6cde7 100644 --- a/index.json +++ b/index.json @@ -1,6 +1,12 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { + "1.1.11": { + "api_version": 9, + "commit_sha": "2d4614e", + "released_on": "17-07-2026", + "md5sum": "5ce3e8c910229e724186f3de6c3be4ea" + }, "1.1.10": { "api_version": 9, "commit_sha": "a1baa5f", diff --git a/plugin_manager.py b/plugin_manager.py index 8d3300dd..0e131d8c 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -25,7 +25,7 @@ # Modules used for overriding AllSettingsWindow import logging -PLUGIN_MANAGER_VERSION = "1.1.10" +PLUGIN_MANAGER_VERSION = "1.1.11" 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. @@ -176,6 +176,75 @@ def partial_format(string_template, **kwargs): return string_template +def draw_plugman_logo(parent, position, size, draw_controller=None): + """Draws the Plugman logo with automatically scaled elements(crafted by brostos). + + The Wizard is the Plugin Manager + 🧙‍♂️ The Wizard & Wand + Represents the talented modders who dedicate their time to crafting incredible + mods for the BombSquad community. + + ❤️ The Red Heart + Originally grey in the original mod manager logo by @Mrmaxmeier. + The touch of red was added to represent our deep appreciation and love for + the original creator, contributors, and all past and present plugin manager maintainers. + + 🪄 The Off-Center Star Stick + The stick holds the star, but it is deliberately not centered perfectly. + This symbolizes imperfection: no plugin is ever completely perfect. It serves + as a reminder to keep updating and improving your plugins. + + ⭐ The Star + Highlights the open-source nature of the Plugin Manager and its community plugins. + If you love the project, make sure to give it a star! + + Args: + parent: The parent widget (e.g., self._root_widget). + position (tuple): The (x, y) starting baseline coordinates of the logo. + size (float): The base width/height for the main asset. Defaults to 120. + draw_controller: The pmb drawing controller reference. + """ + base_x, base_y = position + + char_x = base_x + (size * 0.0417) # Originally +5 + char_y = base_y + (size * 0.2917) # Originally +35 + + heart_size = size * 0.3333 # Originally size - 80 (40x40) + heart_x = base_x - (size * 0.1167) # Originally -14 + heart_y = base_y + (size * 0.7167) # Originally +86 + + star_size = size * 0.35 # Originally size - 78 (42x42) + star_x = base_x + (size * 0.80) # Originally +96 + star_y = base_y + (size * 1.00) # Originally +120 + + bui.imagewidget( + parent=parent, + position=(char_x, char_y), + size=(size, size), + color=(0.8, 0.95, 1), + texture=bui.gettexture("storeCharacter"), + draw_controller=draw_controller, + ) + + bui.imagewidget( + parent=parent, + position=(heart_x, heart_y), + size=(heart_size, heart_size), + color=(1.00, 0.20, 0.20), + texture=bui.gettexture("heart"), + draw_controller=draw_controller, + ) + + bui.imagewidget( + parent=parent, + position=(star_x, star_y), + size=(star_size, star_size), + color=(1.00, 1.00, 0.00), + texture=bui.gettexture("star"), + draw_controller=draw_controller, + ) + + class DNSBlockWorkaround: """ Some ISPs put a DNS block on domains that are needed for plugin manager to @@ -3341,85 +3410,83 @@ def _b_title( on_activate_call=self._do_plugman ) _b_title(x_offs6, v, pmb, bui.Lstr(value="Plugin Manager")) - imgw = imgh = 120 - bui.imagewidget( + draw_plugman_logo( parent=self._root_widget, - position=(x_offs6 + basew * 0.49 - imgw * 0.5 + 5, v + 35), - size=(imgw, imgh), - color=(0.8, 0.95, 1), - texture=bui.gettexture('storeIcon'), + position=(x_offs6 + basew * 0.49 - 120 * 0.5, v), + size=110, draw_controller=pmb ) - self._restore_state() + ) + self._restore_state() - def _do_plugman(self) -> None: - # no-op if we're not in control. - if not self.main_window_has_control(): - return + def _do_plugman(self) -> None: + # no-op if we're not in control. + if not self.main_window_has_control(): + return - self.main_window_replace( - lambda: PluginManagerWindow( - origin_widget=self._plugman_button - ) + self.main_window_replace( + lambda: PluginManagerWindow( + origin_widget=self._plugman_button + ) ) - def _save_state(self) -> None: - try: + def _save_state(self) -> None: + try: sel = self._root_widget.get_selected_child() if sel == self._controllers_button: - sel_name = 'Controllers' + sel_name = 'Controllers' elif sel == self._graphics_button: - sel_name = 'Graphics' + sel_name = 'Graphics' elif sel == self._audio_button: - sel_name = 'Audio' + sel_name= 'Audio' elif sel == self._advanced_button: - sel_name = 'Advanced' + sel_name= 'Advanced' elif sel == self._plugman_button: - sel_name = 'PlugMan' + sel_name= 'PlugMan' elif sel == self._back_button: - sel_name = 'Back' + sel_name= 'Back' else: - raise ValueError(f'unrecognized selection \'{sel}\'') + raise ValueError(f'unrecognized selection \'{sel}\'') assert bui.app.classic is not None - bui.app.ui_v1.window_states[type(self)] = {'sel_name': sel_name} - except Exception: - logging.exception('Error saving state for %s.', self) + bui.app.ui_v1.window_states[type(self)]= {'sel_name': sel_name} + except Exception: + logging.exception('Error saving state for %s.', self) - def _restore_state(self) -> None: + def _restore_state(self) -> None: try: assert bui.app.classic is not None sel_name = bui.app.ui_v1.window_states.get(type(self), {}).get( - 'sel_name' - ) - sel: bui.Widget | None - if sel_name == 'Controllers': - sel = self._controllers_button - elif sel_name == 'Graphics': - sel = self._graphics_button - elif sel_name == 'Audio': - sel = self._audio_button - elif sel_name == 'Advanced': - sel = self._advanced_button - elif sel_name == "PlugMan": - sel = self._plugman_button - elif sel_name == 'Back': - sel = self._back_button - else: - sel = self._controllers_button - if sel is not None: - bui.containerwidget(edit=self._root_widget, selected_child=sel) - except Exception: - logging.exception('Error restoring state for %s.', self) - - -# ba_meta export babase.Plugin -class EntryPoint(babase.Plugin): - def on_app_running(self) -> None: - """Called when the app is being launched.""" - from bauiv1lib.settings import allsettings - allsettings.AllSettingsWindow = NewAllSettingsWindow - DNSBlockWorkaround.apply() - asyncio.set_event_loop(babase._asyncio._g_asyncio_event_loop) - startup_tasks = StartupTasks() - - loop.create_task(startup_tasks.execute()) + 'sel_name' + ) + sel: bui.Widget | None + if sel_name == 'Controllers': + sel = self._controllers_button + elif sel_name == 'Graphics': + sel = self._graphics_button + elif sel_name == 'Audio': + sel = self._audio_button + elif sel_name == 'Advanced': + sel = self._advanced_button + elif sel_name == "PlugMan": + sel = self._plugman_button + elif sel_name == 'Back': + sel = self._back_button + else: + sel = self._controllers_button + if sel is not None: + bui.containerwidget(edit=self._root_widget, selected_child=sel) + except Exception: + logging.exception('Error restoring state for %s.', self) + + + # ba_meta export babase.Plugin + class EntryPoint(babase.Plugin): + def on_app_running(self) -> None: + """Called when the app is being launched.""" + from bauiv1lib.settings import allsettings + allsettings.AllSettingsWindow= NewAllSettingsWindow + DNSBlockWorkaround.apply() + asyncio.set_event_loop(babase._asyncio._g_asyncio_event_loop) + startup_tasks= StartupTasks() + + loop.create_task(startup_tasks.execute())