def __init__(self): super().__init__() ParentStack.push(self) Button(label="A") Button(label="C") # Allow next item(s) to be inserted between A and C self.layout.insert_index = 1 assert ParentStack.pop() == self
def __init__(self, parent=None): super().__init__( title=gettext("OpenRetro logout"), minimizable=False, maximizable=False, ) # self.theme = WorkspaceTheme.instance() # self.layout = fsui.VerticalLayout() self.set_icon(fsui.Icon("password", "pkg:workspace")) with FlexContainer( parent=self, style={ "backgroundColor": "#bbbbbb", "gap": 20, "padding": 20, "paddingBottom": 10, }, ): with VerticalFlexContainer(style={"flexGrow": 1, "gap": 5}): Label( gettext("Log out from your OpenRetro.org account"), style={"fontWeight": "bold"}, ) Label( gettext( "While logged out you will not get database updates")) ImageView(fsui.Image("workspace:/data/48/password.png")) with FlexContainer( parent=self, style={ "backgroundColor": "#bbbbbb", "gap": 10, "padding": 20, "paddingTop": 10, }, ): # Spacer(style={"flexGrow": 1}) self.errorLabel = Label(style={"flexGrow": 1}) # FIXME: Set visible via stylesheet instead? self.spinner = WidgetSizeSpinner(visible=False) self.logoutButton = Button(gettext("Log out"), onClick=self.onLogoutActivated)
def __init__(self): super().__init__( style={ "backgroundColor": "#cccccc", "gap": 10, "padding": 10, } ) with AsParent(self): Label(gettext("Currently logged in as:")) # Label("Username", style={"fontWeight": "bold", "flexGrow": 1}) # from rx.core.typing import Observable # from rx.core.typing import Observable as ObservableT # from typing import Union # a = None # type: Union[None, ObservableT[int]] # print(a) a = SettingObservable( "database_username" ) # x-type: ObservableT[int] Label( # UsernameObservable(), SettingObservable("database_username").pipe( mapOperator(username), # op.map(lambda x: "Not logged in " if x == "Foo" else x) ), style={"fontWeight": "bold", "flexGrow": 1}, ) Button( "Log in", enabled=SettingObservable("database_username").pipe( mapOperator(lambda x: not x) ), onClick=self.onLogInButton, ) Button( "Log out", enabled=SettingObservable("database_username"), onClick=self.onLogOutButton, )
class LogoutWindow(Window): def __init__(self, parent=None): super().__init__( title=gettext("OpenRetro logout"), minimizable=False, maximizable=False, ) # self.theme = WorkspaceTheme.instance() # self.layout = fsui.VerticalLayout() self.set_icon(fsui.Icon("password", "pkg:workspace")) with FlexContainer( parent=self, style={ "backgroundColor": "#bbbbbb", "gap": 20, "padding": 20, "paddingBottom": 10, }, ): with VerticalFlexContainer(style={"flexGrow": 1, "gap": 5}): Label( gettext("Log out from your OpenRetro.org account"), style={"fontWeight": "bold"}, ) Label( gettext( "While logged out you will not get database updates")) ImageView(fsui.Image("workspace:/data/48/password.png")) with FlexContainer( parent=self, style={ "backgroundColor": "#bbbbbb", "gap": 10, "padding": 20, "paddingTop": 10, }, ): # Spacer(style={"flexGrow": 1}) self.errorLabel = Label(style={"flexGrow": 1}) # FIXME: Set visible via stylesheet instead? self.spinner = WidgetSizeSpinner(visible=False) self.logoutButton = Button(gettext("Log out"), onClick=self.onLogoutActivated) # self.logoutButton.activated.connect(self.onLogoutActivated) def __del__(self): print("LogoutWindow.__del__") def setRunning(self, running): self.spinner.set_visible(running) self.logoutButton.set_enabled(not running) def onLogoutActivated(self): self.setRunning(True) authToken = app.settings["database_auth"] def onResult(): self.setRunning(False) self.errorLabel.setText("") self.getWindow().close() def onError(error): self.setRunning(False) self.errorLabel.setText(f"Error: {str(error)}") def onProgress(progress, *, task): self.errorLabel.setText(progress) # task.cancel() self.addEventListener( "destroy", AsyncTaskRunner(onResult, onError, onProgress).run(LogoutTask(authToken)).cancel, ) # FIXME: Move to widget def addEventListener(self, eventName, listener): if eventName == "destroy": self.destroyed.connect(listener) # def onLogoutActivated(self): # self.setRunning(True) # authToken = app.settings["database_auth"] # def onResult(result): # print(result) # self.setRunning(False) # def onError(error): # print(error) # def onProgress(progress): # print(progress) # self.errorLabel.set_text(progress.value) # self.addEventListener( # "destroy", # AsyncTaskRunner(onResult, onError, onProgress) # .run(LogoutTask(authToken)) # .cancel, # ) # with AsyncTaskRunner(onResult, onError, onProgress): # LogoutTask(authToken) # import time # time.sleep(3) # self.close() # LogoutTask(authToken).start() # LogoutTask(authToken).runAsync() # AsyncTaskRunner(onResult, onError, onProgress).run( # LogoutTask(authToken) # ).cancelOn(self.destroy) # self.runTask(LogoutTask(authToken), onProgress, onError, onComplete) # self.disposable = ( # logoutTask(auth_token) # .pipe( # # rx.operators.subscribe_on(rx.scheduler.EventLoopScheduler()), # rx.operators.subscribe_on(rx.scheduler.NewThreadScheduler()), # rx.operators.observe_on(MainLoopScheduler()), # ) # .subscribe(self.onNext, self.onError, self.onCompleted) # ) # # ).subscribe(self, scheduler=qtScheduler) return if auth_token: task = OGDClient().logout_task(auth_token) # task.progressed.connect(self.progress) task.succeeded.connect(self.close) # task.failed.connect(fsui.error_function(gettext("Login Failed"))) task.failed.connect(self.on_failure) task.start() else: # this is not a normal case, no auth token stored, but clear # all auth-related settings just in case app.settings["database_auth"] = "" app.settings["database_username"] = "" # app.settings["database_email"] = "" app.settings["database_password"] = "" self.on_close() def onNext(self, value): import threading print("on_next", value, threading.currentThread()) self.errorLabel.set_text(value) def disp(): self.disposable.dispose() fsui.call_after(disp) def onError(self, error): print("on_error", repr(error)) self.spinner.set_visible(False) self.logoutButton.set_enabled(True) self.errorLabel.set_text(f"Error: {str(error)}") # fsui.show_error(str(message), parent=self.getWindow()) def onCompleted(self): import threading print("on_completed", threading.currentThread()) self.spinner.set_visible(False) self.logoutButton.set_enabled(True) def on_failure(self, error): self.spinner.set_visible(False) self.logoutButton.set_enabled(True) self.errorLabel.set_text(str(error)) fsui.show_error(error, parent=self.window)
def __init__(self): super().__init__(title=gettext("OpenRetro Login"), maximizable=False) # return self.set_icon(fsui.Icon("password", "pkg:workspace")) # self.theme = WorkspaceTheme.instance() with FlexContainer( parent=self, style={ "backgroundColor": "#bbbbbb", "gap": 20, # "marginLeft": 10, # "marginRight": 10, # "marginTop": 10, "padding": 20, "paddingBottom": 10, }, ): with VerticalFlexContainer(style={"flexGrow": 1, "gap": 5}): Label( gettext("Log in to your OpenRetro.org account"), style={"fontWeight": "bold"}, ) Label( gettext("Logging in will enable the online game database " "and more")) ImageView(fsui.Image("workspace:/data/48/password.png")) with VerticalFlexContainer( parent=self, style={ "backgroundColor": "#bbbbbb", "gap": 10, # "marginLeft": 10, # "marginRight": 10, # "padding": 10, "padding": 20, "paddingBottom": 10, "paddingTop": 10, }, ): labelStyle = {"width": 140} with FlexContainer(): Label(gettext("E-mail:"), style=labelStyle) self.username_field = TextField( app.settings["database_email"].strip(), style={"flexGrow": 1}, ) with FlexContainer(): Label(gettext("Password:"******"password", style={"flexGrow": 1}) # with VerticalFlexContainer( # parent=self, # style={ # "backgroundColor": "#ff0000", # "gap": 10, # "padding": 20, # "paddingTop": 0, # }, # ): # with FlexContainer(style={"gap": 10}): # Label(gettext("Don't have an account already?")) # UrlLabel( # gettext("Create an account now"), # "https://openretro.org/user/register?r=fs-uae-launcher", # ) # with FlexContainer(style={"gap": 10}): # Label(gettext("Forgot your password?")) # UrlLabel( # gettext("Reset password via e-mail"), # "https://openretro.org/user/reset?r=fs-uae-launcher", # ) with FlexContainer( parent=self, style={ "backgroundColor": "#bbbbbb", "gap": 10, # "marginLeft": 10, # "marginRight": 10, # "padding": 10, "padding": 20, "paddingBottom": 10, "paddingTop": 10, }, ): with VerticalFlexContainer(style={"gap": 10}): Label(gettext("Don't have an account already?")) Label(gettext("Forgot your password?")) with VerticalFlexContainer(style={"gap": 10}): UrlLabel( gettext("Create an account on openretro.org"), "https://openretro.org/user/register?r=fs-uae-launcher", ) self.reset_label = UrlLabel( gettext("Reset password via e-mail"), "https://openretro.org/user/reset?r=fs-uae-launcher", ) with FlexContainer( parent=self, style= { "backgroundColor": "#bbbbbb", "gap": 10, # "marginBottom": 10, # "marginLeft": 10, # "marginRight": 10, # "padding": 10, "padding": 20, "paddingTop": 10, }, ): Spacer(style={"flexGrow": 1}) # FIXME: Set visible via stylesheet instead? self.spinner = WidgetSizeSpinner(visible=False) self.login_button = Button(gettext("Log in")) self.username_field.changed.connect(self.on_text_field_changed) self.username_field.activated.connect(self.on_username_activated) self.password_field.changed.connect(self.on_text_field_changed) self.password_field.activated.connect(self.on_password_activated) self.login_button.set_enabled(False) self.login_button.activated.connect(self.on_login_activated) if len(self.username_field.text()) == 0: self.username_field.focus() else: self.password_field.focus()
class LoginWindow(Window): def __init__(self): super().__init__(title=gettext("OpenRetro Login"), maximizable=False) # return self.set_icon(fsui.Icon("password", "pkg:workspace")) # self.theme = WorkspaceTheme.instance() with FlexContainer( parent=self, style={ "backgroundColor": "#bbbbbb", "gap": 20, # "marginLeft": 10, # "marginRight": 10, # "marginTop": 10, "padding": 20, "paddingBottom": 10, }, ): with VerticalFlexContainer(style={"flexGrow": 1, "gap": 5}): Label( gettext("Log in to your OpenRetro.org account"), style={"fontWeight": "bold"}, ) Label( gettext("Logging in will enable the online game database " "and more")) ImageView(fsui.Image("workspace:/data/48/password.png")) with VerticalFlexContainer( parent=self, style={ "backgroundColor": "#bbbbbb", "gap": 10, # "marginLeft": 10, # "marginRight": 10, # "padding": 10, "padding": 20, "paddingBottom": 10, "paddingTop": 10, }, ): labelStyle = {"width": 140} with FlexContainer(): Label(gettext("E-mail:"), style=labelStyle) self.username_field = TextField( app.settings["database_email"].strip(), style={"flexGrow": 1}, ) with FlexContainer(): Label(gettext("Password:"******"password", style={"flexGrow": 1}) # with VerticalFlexContainer( # parent=self, # style={ # "backgroundColor": "#ff0000", # "gap": 10, # "padding": 20, # "paddingTop": 0, # }, # ): # with FlexContainer(style={"gap": 10}): # Label(gettext("Don't have an account already?")) # UrlLabel( # gettext("Create an account now"), # "https://openretro.org/user/register?r=fs-uae-launcher", # ) # with FlexContainer(style={"gap": 10}): # Label(gettext("Forgot your password?")) # UrlLabel( # gettext("Reset password via e-mail"), # "https://openretro.org/user/reset?r=fs-uae-launcher", # ) with FlexContainer( parent=self, style={ "backgroundColor": "#bbbbbb", "gap": 10, # "marginLeft": 10, # "marginRight": 10, # "padding": 10, "padding": 20, "paddingBottom": 10, "paddingTop": 10, }, ): with VerticalFlexContainer(style={"gap": 10}): Label(gettext("Don't have an account already?")) Label(gettext("Forgot your password?")) with VerticalFlexContainer(style={"gap": 10}): UrlLabel( gettext("Create an account on openretro.org"), "https://openretro.org/user/register?r=fs-uae-launcher", ) self.reset_label = UrlLabel( gettext("Reset password via e-mail"), "https://openretro.org/user/reset?r=fs-uae-launcher", ) with FlexContainer( parent=self, style= { "backgroundColor": "#bbbbbb", "gap": 10, # "marginBottom": 10, # "marginLeft": 10, # "marginRight": 10, # "padding": 10, "padding": 20, "paddingTop": 10, }, ): Spacer(style={"flexGrow": 1}) # FIXME: Set visible via stylesheet instead? self.spinner = WidgetSizeSpinner(visible=False) self.login_button = Button(gettext("Log in")) self.username_field.changed.connect(self.on_text_field_changed) self.username_field.activated.connect(self.on_username_activated) self.password_field.changed.connect(self.on_text_field_changed) self.password_field.activated.connect(self.on_password_activated) self.login_button.set_enabled(False) self.login_button.activated.connect(self.on_login_activated) if len(self.username_field.text()) == 0: self.username_field.focus() else: self.password_field.focus() # self.spinner.set_visible(False) def __del__(self): print("LoginWindow.__del__") def on_text_field_changed(self): print("on_text_field_changed") email = self.username_field.get_text().strip() password = self.password_field.get_text().strip() self.login_button.set_enabled(bool(email) and bool(password)) self.reset_label.set_url( "https://openretro.org/user/reset?r=fs-uae-launcher" "&email={0}".format(email)) def on_username_activated(self): if self.username_field.get_text().strip(): self.password_field.focus() def on_password_activated(self): self.on_login_activated() def on_login_activated(self): email = self.username_field.get_text().strip() password = self.password_field.get_text().strip() if not email or not password: return self.username_field.set_enabled(False) self.password_field.set_enabled(False) self.login_button.set_enabled(False) self.spinner.set_visible(True) task = OGDClient().login_task(email, password) # task.progressed.connect(self.progress) task.succeeded.connect(self.on_success) # task.failed.connect(fsui.error_function(gettext("Login Failed"))) task.failed.connect(self.on_failure) task.start() def on_success(self): # center = self.get_window_center() # fsui.call_after(start_refresh_task, center) # shell_open("Workspace:Tools/Refresh", center=self.get_window_center()) # RefreshWindow.open(self.parent()) wsopen("SYS:Tools/DatabaseUpdater") self.close() def on_failure(self, message): fsui.show_error(message, parent=self.get_window()) self.username_field.set_enabled() self.password_field.set_enabled() self.login_button.set_enabled() self.password_field.select_all() self.password_field.focus() self.spinner.set_visible(False)
def __init__(self, parent=None): ParentStack.push(self) super().__init__(title=gettext("Flexbox test window"), style={"display": "flex"}) # OpenRetroPrefsPanel() # with VerticalFlexContainer(): # OpenRetroPrefsPanel() # with VerticalFlexContainer(self): with FlexContainer( style={ "backgroundColor": "#ffcccc", "flexDirection": "column", "padding": 10, "width": 640, # "height": 480, }): Button(label="A", style={"alignSelf": "flex-start"}) Button(label="B", style={"alignSelf": "center"}) Button(label="C", style={"alignSelf": "flex-end"}) # with FlexContainer(style={ # "backgroundColor": "#ffcccc", # "paddingLeft": 10, # "paddingRight": 10, # }): # Button(label="A") # Button(label="B") # with FlexContainer(style={ # "backgroundColor": "#ffcccc", # "paddingLeft": 10, # "paddingRight": 10, # }): # Button(label="A") # Button(label="B") # Button(label="C") # with FlexContainer(style={ # "paddingLeft": 10, # }): # Button(label="A") # Button(label="B") # Button(label="C") # Button(label="D") with VerticalFlexContainer(style={ "backgroundColor": "#ccffcc", "padding": 10, }): Button( label="D is a button with a really long label", style={"marginBottom": 10}, ) Button( label="E", style={ "marginBottom": 10, "marginLeft": 20, "marginRight": 10, }, ) Button(label="F") # Button(label="C", style={"flexGrow": 1}) with FlexContainer(style={ "backgroundColor": "#ccccff", "flexGrow": 1, "padding": 10, }): Button(label="G", style={"flexGrow": 1}) Button( label="H is much longer than both G and I", style={"flexGrow": 1}, ) Button(label="I") with FlexContainer(style={ "backgroundColor": "#ffcccc", "padding": 10, }): Button( label= "J has a really long label, let's see what happens if we try to cut it off", style={ "flexGrow": 1, "maxWidth": 200 }, ) Button(label="K (longer)", style={"flexGrow": 1}) Button(label="L", style={"flexGrow": 1}) with FlexContainer(style={ "backgroundColor": "#ccffcc", "padding": 10, }): Button(label="M", style={"height": 100}) Button(label="N") Button(label="O", style={"maxHeight": 50}) with VerticalFlexContainer(style={ "backgroundColor": "#ccffcc", "padding": 10, }): Button( label="D is a button with a really long label", style={"marginBottom": 10}, ) Button( label="E", style={ "marginBottom": 10, "marginLeft": 20, "marginRight": 10, }, ) Button(label="F") Button( label="Big", style={ "flexGrow": 1, "margin": -10, "marginLeft": 0 }, ) with FlexContainer(style={ "backgroundColor": "#ccccff", "padding": 10, }): Button(label="P", style={"margin": 10}) Button(label="Q", style={"margin": 20}) Button(label="R", style={"margin": 30}) Button(label="P", style={"height": 30, "margin": 10}) Button(label="Q", style={"height": 30, "margin": 20}) Button(label="R", style={"height": 30, "margin": 30}) # with FlexContainer(style={ # "backgroundColor": "#ccccff", # "padding": 10, # }): with FlexContainer(style={ "backgroundColor": "#ffcccc", }): Button(label="S", style={ "flexGrow": 1, "height": 30, "margin": 10 }) Button(label="T", style={ "flexGrow": 1, "height": 30, "margin": 20 }) Button(label="U", style={ "flexGrow": 1, "height": 30, "margin": 30 }) with FlexContainer( style={ "alignItems": "center", "backgroundColor": "#ccffcc", "height": 100, "padding": 10, }): Button(label="v", style={ "flexGrow": 1, "height": 30, "margin": 10 }) Button( label="W", style={ "flexGrow": 1, "height": 30, "margin": 10, "marginBottom": 60, }, ) Button( label="X", style={ "flexGrow": 1, "height": 30, "margin": 10, "marginRight": 150, "marginBottom": 110, }, ) pass # with VerticalFlexContainer(style={ # "backgroundColor": "#00ff00", # "paddingLeft": 10, # "paddingRight": 10, # }): # Button(label="D") # Button(label="E", style={ # "alignSelf": "flex-start" # }) # Button(label="E", style={ # "alignSelf": "center" # }) # Button(label="F", style={ # "alignSelf": "flex-end" # }) with InsertWidgetTest(): Button(label="B") assert ParentStack.pop() == self WindowResizeHandle(self)