def __init__(self, parent): super().__init__( parent, title=gettext("Execute a file"), maximizable=False, minimizable=False, escape=True, ) vertlayout = VerticalLayout(20) self.layout.add(vertlayout, fill=True, expand=True) vertlayout.add(Label(self, gettext("Enter command and its arguments:"))) horilayout = HorizontalLayout() vertlayout.add(horilayout, fill=True, margin_top=10) horilayout.add(Label(self, gettext("Command:")), fill=True) self.textfield = TextField(self) self.textfield.set_min_width(300) self.textfield.activated.connect(self.__on_execute) horilayout.add(self.textfield, expand=True, fill=True, margin_left=10) # Creating execute button first, so it will become default for when # the user presses return in the text field. This only applies when # this dialog is implemented as an actual Dialog though. self.executebutton = Button(self, gettext("Execute")) self.executebutton.activated.connect(self.__on_execute) self.cancelbutton = Button(self, gettext("Cancel")) self.cancelbutton.activated.connect(self.__on_cancel) horilayout = HorizontalLayout() vertlayout.add(horilayout, fill=True, margin_top=20) horilayout.add_spacer(0, expand=True) horilayout.add(self.cancelbutton, margin_left=10) horilayout.add(self.executebutton, margin_left=10) self._command = ""
class TabPanel(Panel): def __init__(self, parent, spacing=10): unused(spacing) Panel.__init__(self, parent, paintable=True) Skin.set_background_color(self) self.layout = HorizontalLayout() self.layout.add_spacer(20) # self.layout.add_spacer(spacing) # self.layout.padding_left = 10 # self.layout.padding_right = 10 # self.set_background_color(Color(0xAEAEAE)) # self.set_min_height(Constants.TAB_HEIGHT) self.bgcolor = get_theme(self).window_bgcolor() self.set_background_color(self.bgcolor) def select_tab(self, index): counter = 0 for child in self.layout.children: child = child.element if hasattr(child, "type"): if child.type == child.TYPE_TAB: if counter == index: child.select() counter += 1 def set_selected_tab(self, tab): for child in self.layout.children: child = child.element if hasattr(child, "type"): if child.type == child.TYPE_TAB: if child == tab: child.state = child.STATE_SELECTED child.refresh() elif child.state == child.STATE_SELECTED: if child.group_id == tab.group_id: child.state = child.STATE_NORMAL child.refresh() def add(self, button, expand=False): self.layout.add(button, expand=expand) def add_spacer(self, spacer=0, expand=False): self.layout.add_spacer(spacer, 0, expand=expand)
class StatusBar(Panel): def __init__(self, parent): Panel.__init__(self, parent, paintable=True) self.set_min_height(29) # self.set_background_color(Color(0xd8, 0xd8, 0xd8)) self.layout = VerticalLayout() self.hori_layout = HorizontalLayout() if Skin.fws(): self.top_border_size = 2 else: self.top_border_size = 1 self.layout.add(self.hori_layout, fill=True, expand=True, margin_top=self.top_border_size) element = ProtectionElement(self) self.hori_layout.add(element, fill=True) element = WarningsElement(self) self.hori_layout.add(element, fill=True, expand=True) self.hori_layout.add_spacer(16) for language, icon_name in reversed([ ("en", "flag-gb"), ("de", "flag-de"), ("fr", "flag-fr"), ("es", "flag-es"), ("it", "flag-it"), ("ja", "flag-jp"), # ("", "flag-unknown"), ]): icon = Image("workspace:res/16/" + icon_name + ".png") element = LanguageElement(self, language, icon) self.hori_layout.add(element, fill=True) self.hori_layout.add_spacer(16) element = PlayersElement(self) self.hori_layout.add(element, fill=True) # for config_key, icon_name in [ # ("database_url", "database_url_16"), # ("hol_url", "hol_url_16"), # ("lemonamiga_url", "lemon_url_16"), # ("mobygames_url", "mobygames_url_16"), # ("wikipedia_url", "wikipedia_url_16"), # ]: # icon = Image("launcher:res/" + icon_name + ".png") # element = LinkButtonElement(self, config_key, icon) # self.hori_layout.add(element) element = WebLinkElement(self) self.hori_layout.add(element, fill=True) # this listener is added after all status bar children have # added their listeners, this is important for re-layout... LauncherConfig.add_listener(self) def on_destroy(self): LauncherConfig.remove_listener(self) def on_config(self, key, value): unused(value) layout = False if key in ["languages", "protection"]: layout = True if layout: self.layout.update() def on_paint(self): dc = self.create_dc() size = self.size() if Skin.fws(): dc.draw_rectangle( 0, 0, size[0], 2, Color(0xe5, 0xe5, 0xe5, 0xff)) return color_1 = Skin.get_background_color() if color_1 is not None: color_1 = color_1.copy().darken(0.12) else: color_1 = Color(0x00, 0x00, 0x00, 0x30) dc.draw_line(0, 0, size[0], 0, color_1) self.draw_background(self, dc, offset=1, height=size[1] - 1) @classmethod def draw_element_background(cls, widget, dc): cls.draw_background(widget, dc) @classmethod def draw_background(cls, widget, dc, offset=None, height=None): size = widget.size() if Skin.fws(): return x = 0 y = 0 w = size[0] h = size[1] if offset is not None: y += offset if height is not None: h = height color_1 = Skin.get_background_color() color_2 = color_1 # if fsui.System.macosx: # color_1 = Color(0xa7, 0xa7, 0xa7) # color_2 = Color(0xc0, 0xc0, 0xc0) if color_1 is not None: color_1 = color_1.copy().darken(0.08) else: color_1 = Color(0x00, 0x00, 0x00, 0x20) color_2 = Color(0x00, 0x00, 0x00, 0x00) dc.draw_vertical_gradient(x, y, w, h, color_1, color_2)
class StatusBar(Panel): def __init__(self, parent): Panel.__init__(self, parent, paintable=True) self.set_min_height(29) # self.set_background_color(Color(0xd8, 0xd8, 0xd8)) self.layout = VerticalLayout() self.hori_layout = HorizontalLayout() if Skin.fws(): self.top_border_size = 2 else: self.top_border_size = 1 self.layout.add(self.hori_layout, fill=True, expand=True, margin_top=self.top_border_size) element = ProtectionElement(self) self.hori_layout.add(element, fill=True) element = WarningsElement(self) self.hori_layout.add(element, fill=True, expand=True) self.hori_layout.add_spacer(16) for language, icon_name in reversed([ ("en", "flag-gb"), ("de", "flag-de"), ("fr", "flag-fr"), ("es", "flag-es"), ("it", "flag-it"), ("ja", "flag-jp"), # ("", "flag-unknown"), ]): icon = Image("workspace:res/16/" + icon_name + ".png") element = LanguageElement(self, language, icon) self.hori_layout.add(element, fill=True) self.hori_layout.add_spacer(16) element = PlayersElement(self) self.hori_layout.add(element, fill=True) # for config_key, icon_name in [ # ("database_url", "database_url_16"), # ("hol_url", "hol_url_16"), # ("lemonamiga_url", "lemon_url_16"), # ("mobygames_url", "mobygames_url_16"), # ("wikipedia_url", "wikipedia_url_16"), # ]: # icon = Image("launcher:res/" + icon_name + ".png") # element = LinkButtonElement(self, config_key, icon) # self.hori_layout.add(element) element = WebLinkElement(self) self.hori_layout.add(element, fill=True) # this listener is added after all status bar children have # added their listeners, this is important for re-layout... LauncherConfig.add_listener(self) def on_destroy(self): LauncherConfig.remove_listener(self) def on_config(self, key, value): unused(value) layout = False if key in ["languages", "protection"]: layout = True if layout: self.layout.update() def on_paint(self): dc = self.create_dc() size = self.size() if Skin.fws(): dc.draw_rectangle(0, 0, size[0], 2, Color(0xe5, 0xe5, 0xe5, 0xff)) return color_1 = Skin.get_background_color() if color_1 is not None: color_1 = color_1.copy().darken(0.12) else: color_1 = Color(0x00, 0x00, 0x00, 0x30) dc.draw_line(0, 0, size[0], 0, color_1) self.draw_background(self, dc, offset=1, height=size[1] - 1) @classmethod def draw_element_background(cls, widget, dc): cls.draw_background(widget, dc) @classmethod def draw_background(cls, widget, dc, offset=None, height=None): size = widget.size() if Skin.fws(): return x = 0 y = 0 w = size[0] h = size[1] if offset is not None: y += offset if height is not None: h = height color_1 = Skin.get_background_color() color_2 = color_1 # if fsui.System.macosx: # color_1 = Color(0xa7, 0xa7, 0xa7) # color_2 = Color(0xc0, 0xc0, 0xc0) if color_1 is not None: color_1 = color_1.copy().darken(0.08) else: color_1 = Color(0x00, 0x00, 0x00, 0x20) color_2 = Color(0x00, 0x00, 0x00, 0x00) dc.draw_vertical_gradient(x, y, w, h, color_1, color_2)
class OpenRetroPrefsPanel(BasePrefsPanel): def __init__(self, parent): super().__init__(parent) # FIXME self.set_min_size((540, 100)) self.layout.set_padding(20, 20, 20, 20) # self.layout.set_padding(10, 10, 10, 10) import fsui # self.layout.add(fsui.Button(self, "hei")) with AsParent(self): LoginPanel() self.add_section("Platforms") self.add_option(Option.PLATFORMS_FEATURE) self.hori_layout = None self.hori_counter = 0 # if openretro or settings.get(Option.PLATFORMS_FEATURE) == "1": # # self.add_section(gettext("Game Databases")) label = MultiLineLabel( self, gettext( "Note: This is an experimental feature. " "Additional plugins are needed." ), 640, ) self.layout.add(label, margin_top=20, margin_bottom=20) self.add_database_option( Platform.CPC, Option.CPC_DATABASE, "Amstrad CPC" ) self.add_database_option( Platform.ARCADE, Option.ARCADE_DATABASE, "Arcade" ) self.add_database_option( Platform.A7800, Option.A7800_DATABASE, "Atari 7800" ) self.add_database_option( Platform.C64, Option.C64_DATABASE, "Commodore 64" ) self.add_database_option(Platform.DOS, Option.DOS_DATABASE, "DOS") self.add_database_option(Platform.GB, Option.GB_DATABASE, "Game Boy") self.add_database_option( Platform.GBA, Option.GBA_DATABASE, "Game Boy Advance" ) self.add_database_option( Platform.GBC, Option.GBC_DATABASE, "Game Boy Color" ) self.add_database_option( Platform.SMS, Option.SMS_DATABASE, "Master System" ) self.add_database_option( Platform.SMD, Option.SMD_DATABASE, "Mega Drive" ) self.add_database_option( Platform.NEOGEO, Option.NEOGEO_DATABASE, "Neo-Geo" ) self.add_database_option(Platform.NES, Option.NES_DATABASE, "Nintendo") self.add_database_option( Platform.PSX, Option.PSX_DATABASE, "PlayStation" ) self.add_database_option( Platform.SNES, Option.SNES_DATABASE, "Super Nintendo" ) self.add_database_option(Platform.ST, Option.ST_DATABASE, "Atari ST") self.add_database_option( Platform.TG16, Option.TG16_DATABASE, "TurboGrafx-16" ) self.add_database_option( Platform.TGCD, Option.TGCD_DATABASE, "TurboGrafx-CD" ) self.add_database_option( Platform.ZXS, Option.ZXS_DATABASE, "ZX Spectrum" ) # label = fsui.MultiLineLabel( # self, gettext( # "Note: Support for additional game databases is an " # "experimental feature and does not provide the " # "same level of maturity as Amiga/CDTV/CD32. " # "Also, additional plugins are needed to play the " # "games."), 640) # self.layout.add(label, margin_top=20) def add_database_option(self, platform, name, description=""): # self.options_on_page.add(name) group = OptionUI.create_group( self, name, description=description, help_button=False ) if self.hori_counter % 2 == 0: self.hori_layout = HorizontalLayout() self.layout.add( self.hori_layout, fill=True, margin_top=10, margin_bottom=10, margin_left=-10, margin_right=-10, ) self.hori_layout.add( group, fill=True, expand=-1, margin=10, margin_top=0, margin_bottom=0, ) self.hori_layout.add( PlatformSettingsButton(self, platform), margin_right=10 ) if self.hori_counter % 2 == 0: self.hori_layout.add_spacer(0) self.hori_counter += 1
class WorkspaceTitleBar(Panel): def __init__(self, parent): super().__init__(parent) self.layout = HorizontalLayout() self.title = get_workspace_window_title() self.dragging = False self.dragging_mouse_origin = (0, 0) self.dragging_window_origin = (0, 0) self.buttons = [] theme = get_theme(self) self.height = theme.titlebar_height() self.set_min_height(self.height) button_size = (self.height, self.height) # fgcolor = theme.titlebar_fgcolor() # fgcolor_inactive = theme.titlebar_fgcolor_inactive() fgcolor = Color(0x000000) fgcolor_inactive = Color(0x000000) self.set_background_color(Color(0xFFFFFF)) menu = True if menu: self.menubutton = TitleBarButton( self, icon_name="TitleBarMenu", size=button_size, fgcolor=fgcolor, fgcolor_inactive=fgcolor_inactive, ) self.menubutton.activated.connect(self.__on_menu_activated) self.layout.add(self.menubutton) self.buttons.append(self.menubutton) else: self.menubutton = None self.layout.add_spacer(0, expand=True) self.volumebutton = VolumeButton(self) self.layout.add(self.volumebutton) self.monitorbutton = MonitorButton(self) self.layout.add(self.monitorbutton) self.fullscreenbutton = FullscreenToggleButton(self) self.layout.add(self.fullscreenbutton) self._window_active = True # parent.activated.connect(self.__on_window_activated) # parent.deactivated.connect(self.__on_window_deactivated) # FIXME: Would be better to do this via theme instead and get a theme # updated notification. Works well enough for now. for option in [ "launcher_titlebar_font", "launcher_titlebar_height", "launcher_titlebar_uppercase", ]: self.on_setting( option, get_settings(self).get(option), ) get_settings(self).add_listener(self) def on_destroy(self): get_settings(self).remove_listener(self) super().on_destroy() @exceptionhandler def on_setting(self, option, _): if option == "launcher_titlebar_font": self.refresh() elif option == "launcher_titlebar_uppercase": self.refresh() elif option == "launcher_titlebar_height": new_height = get_theme(self).titlebar_height() self.update_height(new_height) def update_height(self, new_height): if self.height == new_height: return self.height = new_height self.set_min_height(new_height) for button in self.buttons: button.set_size((new_height, new_height)) get_window(self).layout.update() @exceptionhandler def on_paint(self): theme = get_theme(self) text = self.title if theme.titlebar_uppercase(): text = text.upper() _, wh = self.size() dc = self.create_dc() dc.set_font(theme.titlebar_font()) color = Color(0, 0, 0) dc.set_text_color(color) _, th = dc.measure_text(text) if self.menubutton: # Adding width of button (same as height). Also, adding 6 gives # 20 pixels between edge of burger icon and start of text. x = self.height + 6 else: x = 20 y = (wh - th) // 2 + 1 dc.draw_text(text, x, y) @exceptionhandler def __on_menu_activated(self): try: on_menu = self.window.on_menu except AttributeError: print( f"WARNING: Window {self.window} has menu enabled, but missing " "on_menu method" ) return menu = on_menu() if menu is None: return print("FIXME: Open menu") # menu.open() self.popup_menu(menu, (0, self.height))
class TitleBar(Panel): def __init__(self, parent): super().__init__(parent, paintable=True) self.set_min_height(40) self.set_background_color(Color(0xFF, 0xFF, 0xFF)) self.menu_button = Button(self, "=") self.minimize_button = Button(self, "_") self.minimize_button.activated.connect(self.on_minimize_button) self.maximize_button = Button(self, "^") self.maximize_button.activated.connect(self.on_maximize_button) self.close_button = Button(self, "X") self.close_button.activated.connect(self.on_close_button) self.layout = HorizontalLayout() self.layout.add(self.menu_button, fill=True) self.layout.add_spacer(0, expand=True) self.layout.add(self.minimize_button, fill=True) self.layout.add(self.maximize_button, fill=True) self.layout.add(self.close_button, fill=True) self.window_pos = (-1, -1) self.mouse_pos = (-1, -1) def on_menu_button(self): pass def on_minimize_button(self): self.parent().minimize() def on_maximize_button(self): self.parent().maximize(not self.parent().is_maximized()) def on_close_button(self): self.parent().close() def on_left_dclick(self): self.on_maximize_button() def on_left_down(self): self.window_pos = self.parent().get_position() self.mouse_pos = get_mouse_position() def on_mouse_motion(self): mouse_pos = get_mouse_position() window_pos = ( self.window_pos[0] + mouse_pos[0] - self.mouse_pos[0], self.window_pos[1] + mouse_pos[1] - self.mouse_pos[1], ) self.parent().set_position(window_pos) # def on_left_up(self): # pass def on_paint(self): dc = self.create_dc() if self.close_button is not None: x_offset = self.close_button.width() + 20 else: x_offset = 20 # print(self.parent()) # text = self.parent().title() text = "FIXME" _, th = dc.measure_text(text) dc.draw_text(text, x_offset, (self.height() - th) // 2)