def __init__(self, title, description, hint_text): Heading.__init__(self, title, description) self.container.set_spacing(0) self.hint = Gtk.Label(hint_text) self.description.set_justify(Gtk.Justification.CENTER) self.hint.set_line_wrap(True) self.hint.get_style_context().add_class("hint_label") self.container.pack_start(self.hint, False, False, 0)
def __init__(self, img_filename, title, description, kano_button_text, orange_button_text): Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL) if img_filename: self.image = Gtk.Image.new_from_file(img_filename) self.pack_start(self.image, False, False, 0) self.heading = Heading(title, description) self.kano_button = KanoButton(kano_button_text) self.pack_start(self.heading.container, False, False, 0) self.button_box = Gtk.ButtonBox(spacing=10) self.button_box.set_layout(Gtk.ButtonBoxStyle.SPREAD) self.button_box.set_margin_bottom(30) self.pack_start(self.button_box, False, False, 0) if not orange_button_text == "": self.orange_button = OrangeButton(orange_button_text) self.button_box.pack_start(self.orange_button, False, False, 0) self.button_box.pack_start(self.kano_button, False, False, 0) # The empty label is to centre the kano_button label = Gtk.Label(" ") self.button_box.pack_start(label, False, False, 0) else: self.button_box.pack_start(self.kano_button, False, False, 0)
def __init__(self): Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL) kano_button_text = _("CREATE") skip_button_text = _("Skip") login_button_text = _("I have a profile") header = _('Keep your creations safe') subheader = _( 'Create a Kano World account so you never lose your progress...\n' 'and to get inspired by creations from the community') img_width = 590 img_height = 270 self.skip_button = OrangeButton(skip_button_text) self.login_button = OrangeButton(login_button_text) image_filename = get_image('login', "", 'first-screen', str(img_width) + 'x' + str(img_height)) self.image = Gtk.Image.new_from_file(image_filename) self.pack_start(self.image, False, False, 0) self.heading = Heading(header, subheader) self.kano_button = KanoButton(kano_button_text) self.pack_start(self.heading.container, False, False, 0) self.button_box = Gtk.ButtonBox(spacing=10) self.button_box.set_layout(Gtk.ButtonBoxStyle.SPREAD) self.pack_start(self.button_box, False, False, 0) self.button_box.pack_start(self.login_button, False, False, 0) self.button_box.pack_start(self.kano_button, False, False, 0) self.button_box.pack_start(self.skip_button, False, False, 0)
def __init__(self, win): Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL) self.win = win self.win.set_main_widget(self) self.win.set_decorated(True) title = Heading(_("Kano World"), _("Choose a cool name and secure password")) self.pack_start(title.container, False, False, 0) self.data_screen = GetData() # TODO: refactor this self.data_screen.connect('widgets-filled', self._enable_register_button) self.data_screen.connect('widgets-empty', self._disable_register_button) self.add(self.data_screen) self.register_button = KanoButton(_("JOIN KANO WORLD")) self.register_button.set_sensitive(False) self.register_button.set_margin_top(10) self.register_button.set_margin_left(30) self.register_button.set_margin_right(30) self.register_button.set_margin_bottom(30) self.register_button.connect('clicked', self._on_register_button) self.pack_end(self.register_button, False, False, 0) self.win.show_all()
def __init__(self): Gtk.Grid.__init__(self) self.get_style_context().add_class('password') self.set_row_spacing(10) title = Heading(_('Select Account'), _('Log in to which account?')) self.attach(title.container, 0, 0, 2, 1) self.scrolled_window = ScrolledWindow() self.scrolled_window.set_size_request(self.WIDTH, self.HEIGHT) self.box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.box.set_spacing(10) self.box.set_margin_left(10) self.box.set_margin_right(10) self.scrolled_window.add(self.box) self.attach(self.scrolled_window, 0, 1, 2, 1) self.last_username = get_last_user() self._populate() self.add_account_btn = OrangeButton(_('Add Account')) self.add_account_btn.connect('clicked', self._btn_add_account_pressed) self.attach(self.add_account_btn, 0, 2, 1, 1) self.shutdown_btn = OrangeButton(_('Shutdown')) self.shutdown_btn.connect('clicked', self._btn_shutdown_pressed) self.attach(self.shutdown_btn, 1, 2, 1, 1)
class LoggedIn(Gtk.Window): def __init__(self): Gtk.Window.__init__(self, title='Profile') self.set_size_request(200, 150) self.set_decorated(False) self.set_position(Gtk.WindowPosition.CENTER) self.set_resizable(False) self.ok_button = KanoButton(_("OK")) self.ok_button.pack_and_align() self.ok_button.set_padding(20, 20, 0, 0) self.ok_button.connect("clicked", Gtk.main_quit) self.title = Heading(_("Logged in!"), _("You're already logged in")) self.main_container = Gtk.Box( orientation=Gtk.Orientation.VERTICAL, spacing=0) self.add(self.main_container) self.main_container.pack_start(self.title.container, False, False, 0) self.main_container.pack_start(self.ok_button.align, False, False, 0) # To get a logout button, uncomment out the lines below #self.logout_button = OrangeButton(_("Log out?")) #self.logout_button.connect("clicked", self.logout) #self.main_container.pack_start(self.logout_button, False, False, 0) self.connect('delete-event', Gtk.main_quit) self.show_all() def logged_out_screen(self): for child in self.main_container: self.main_container.remove(child) self.title.set_text(_("Logged out!"), "") self.main_container.pack_start(self.title.container, False, False, 0) self.main_container.pack_start(self.alignment, False, False, 0) def logout(self, event): remove_token() self.logged_out_screen() def close_window(self, event, button, win): self.ok_button.disconnect_handlers() cursor.arrow_cursor(None, None, win) Gtk.main_quit()
class LoggedIn(Gtk.Window): def __init__(self): Gtk.Window.__init__(self, title='Profile') self.set_size_request(200, 150) self.set_decorated(False) self.set_position(Gtk.WindowPosition.CENTER) self.set_resizable(False) self.ok_button = KanoButton(_("OK")) self.ok_button.pack_and_align() self.ok_button.set_padding(20, 20, 0, 0) self.ok_button.connect('clicked', Gtk.main_quit) self.title = Heading(_("Logged in!"), _("You're already logged in")) self.main_container = Gtk.Box( orientation=Gtk.Orientation.VERTICAL, spacing=0) self.add(self.main_container) self.main_container.pack_start(self.title.container, False, False, 0) self.main_container.pack_start(self.ok_button.align, False, False, 0) # To get a logout button, uncomment out the lines below #self.logout_button = OrangeButton(_("Log out?")) #self.logout_button.connect('clicked', self.logout) #self.main_container.pack_start(self.logout_button, False, False, 0) self.connect('delete-event', Gtk.main_quit) self.show_all() def logged_out_screen(self): for child in self.main_container: self.main_container.remove(child) self.title.set_text(_("Logged out!"), "") self.main_container.pack_start(self.title.container, False, False, 0) self.main_container.pack_start(self.alignment, False, False, 0) def logout(self, event): remove_token() self.logged_out_screen() def close_window(self, event, button, win): self.ok_button.disconnect_handlers() cursor.arrow_cursor(None, None, win) Gtk.main_quit()
def __init__(self): Gtk.Window.__init__(self, title=self._TITLE) apply_common_to_screen() window_height = self._IMAGE_HEIGHT + 220 self.set_size_request(self._IMAGE_WIDTH, window_height) self.set_decorated(False) self.set_resizable(False) self.set_position(Gtk.WindowPosition.CENTER) self.set_icon_name('kano-updater') # Put the window above all the existing ones when it starts # FIXME: this needs to happen within a 'realized' signal handler # disabled for now #self.get_window().raise_() image = Gtk.Image() image.set_from_file(self._HEADER_IMAGE) background = Gtk.EventBox() background.set_size_request(self._IMAGE_WIDTH, self._IMAGE_HEIGHT) background.add(image) # Header heading = Heading(self._HEADING, self._BYLINE) heading.description.set_line_wrap(True) action = KanoButton(self._ACTION.upper()) action.connect('clicked', self._do_action) action.set_halign(Gtk.Align.CENTER) later = OrangeButton(_("Later")) later.connect('clicked', self._do_later) later.set_halign(Gtk.Align.START) later.set_margin_left(40) buttons = Gtk.Overlay() buttons.add(action) buttons.add_overlay(later) box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) box.pack_start(background, False, False, 0) box.pack_start(heading.container, False, False, 10) box.pack_start(buttons, False, False, 0) self.add(box) self.show_all()
def __init__(self): Gtk.Window.__init__(self, title='Profile') self.set_size_request(200, 150) self.set_decorated(False) self.set_position(Gtk.WindowPosition.CENTER) self.set_resizable(False) self.ok_button = KanoButton(_("OK")) self.ok_button.pack_and_align() self.ok_button.set_padding(20, 20, 0, 0) self.ok_button.connect('clicked', Gtk.main_quit) self.title = Heading(_("Logged in!"), _("You're already logged in")) self.main_container = Gtk.Box( orientation=Gtk.Orientation.VERTICAL, spacing=0) self.add(self.main_container) self.main_container.pack_start(self.title.container, False, False, 0) self.main_container.pack_start(self.ok_button.align, False, False, 0) # To get a logout button, uncomment out the lines below #self.logout_button = OrangeButton(_("Log out?")) #self.logout_button.connect('clicked', self.logout) #self.main_container.pack_start(self.logout_button, False, False, 0) self.connect('delete-event', Gtk.main_quit) self.show_all()
def _set_title(self, create=True): ''' Creates a Heading text widget, or updates it with the currently selected username. ''' text_title = _('{}: Enter your password').format(self.user) text_description = _( 'If you haven\'t changed your\npassword, use "kano"') if create: title = Heading(text_title, text_description) return title else: self.title.set_text(text_title, text_description) return self.title
def __init__(self): Gtk.Window.__init__(self, title=self._TITLE) apply_common_to_screen() window_height = self._IMAGE_HEIGHT + 220 self.set_size_request(self._IMAGE_WIDTH, window_height) self.set_decorated(False) self.set_resizable(False) self.set_position(Gtk.WindowPosition.CENTER) self.set_icon_name('kano-updater') # Make sure this window is always above self.set_keep_above(True) image = Gtk.Image() image.set_from_file(self._HEADER_IMAGE) background = Gtk.EventBox() background.set_size_request(self._IMAGE_WIDTH, self._IMAGE_HEIGHT) background.add(image) # Header heading = Heading(self._HEADING, self._BYLINE) heading.description.set_line_wrap(True) action = KanoButton(self._ACTION.upper()) action.connect('clicked', self._do_action) action.set_halign(Gtk.Align.CENTER) later = OrangeButton(_('Later')) later.connect('clicked', Gtk.main_quit) later.set_halign(Gtk.Align.START) later.set_margin_left(40) buttons = Gtk.Overlay() buttons.add(action) buttons.add_overlay(later) box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) box.pack_start(background, False, False, 0) box.pack_start(heading.container, False, False, 10) box.pack_start(buttons, False, False, 0) self.add(box) self.show_all()
def __init__(self, greeter): Gtk.Grid.__init__(self) self.get_style_context().add_class('password') self.set_row_spacing(12) self.greeter = greeter title = Heading(_('Add new account'), _('Login with Kano World\n' 'or create a new account.')) self.attach(title.container, 0, 0, 1, 1) # the 2 push buttons self.login_btn = KanoButton(_('Kano World')) self.login_btn.connect('clicked', self._login_button_pressed) self.attach(self.login_btn, 0, 1, 1, 1) self.newuser_btn = KanoButton(_('New Account')) self.newuser_btn.connect('clicked', self._new_user_reboot) self.attach(self.newuser_btn, 0, 2, 1, 1)
def __init__(self, win): Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL) self.win = win self.win.set_decorated(False) self.win.set_main_widget(self) self.heading = Heading(_("Reset your password"), _("We'll send a new password to your email")) self.pack_start(self.heading.container, False, False, 10) self.labelled_entries = LabelledEntries([{ 'heading': _("Username"), 'subheading': "" }]) align = Gtk.Alignment(xscale=0, xalign=0.5) self.pack_start(align, False, False, 15) self.labelled_entries.set(0, 0, 1, 1) self.labelled_entries.set_hexpand(True) align.add(self.labelled_entries) # Get the currently logged on user, the kid can override it # FIXME: Is this necessary? username = get_mixed_username() self.username_entry = self.labelled_entries.get_entry(0) self.username_entry.set_text(username) self.username_entry.select_region(0, -1) self.username_entry.connect('key-release-event', self.activate) self.button = KanoButton(_("RESET PASSWORD")) self.button.pack_and_align() self.button.connect('button-release-event', self.activate) self.button.connect('key-release-event', self.activate) self.button.set_padding(30, 30, 0, 0) self.pack_start(self.button.align, False, False, 0) self.win.show_all()
def __init__(self): Gtk.Window.__init__(self, title='Profile') self.set_size_request(200, 150) self.set_decorated(False) self.set_position(Gtk.WindowPosition.CENTER) self.set_resizable(False) self.ok_button = KanoButton(_("OK")) self.ok_button.pack_and_align() self.ok_button.set_padding(20, 20, 0, 0) self.ok_button.connect("clicked", Gtk.main_quit) self.title = Heading(_("Logged in!"), _("You're already logged in")) self.main_container = Gtk.Box( orientation=Gtk.Orientation.VERTICAL, spacing=0) self.add(self.main_container) self.main_container.pack_start(self.title.container, False, False, 0) self.main_container.pack_start(self.ok_button.align, False, False, 0) # To get a logout button, uncomment out the lines below #self.logout_button = OrangeButton(_("Log out?")) #self.logout_button.connect("clicked", self.logout) #self.main_container.pack_start(self.logout_button, False, False, 0) self.connect('delete-event', Gtk.main_quit) self.show_all()
def __init__(self, greeter): Gtk.Grid.__init__(self) self.get_style_context().add_class('password') self.set_row_spacing(12) self.greeter = greeter title = Heading(_('Login with Kano World'), _('Enter your Kano World details.')) self.attach(title.container, 0, 0, 1, 1) self.username = Gtk.Entry() self.username.set_placeholder_text('username') self.attach(self.username, 0, 1, 1, 1) self.password = Gtk.Entry() self.password.set_visibility(False) self.password.set_placeholder_text('password') self.attach(self.password, 0, 2, 1, 1) self.login_btn = KanoButton(_('LOGIN')) self.login_btn.connect('clicked', self._btn_login_pressed) self.attach(self.login_btn, 0, 3, 1, 1)
def __init__(self, win): Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL) self.win = win self.win.set_decorated(False) self.win.set_main_widget(self) self.heading = Heading(_("Forgotten your username"), _("We'll send a reminder to your email")) self.pack_start(self.heading.container, False, False, 10) self.labelled_entries = LabelledEntries([{ 'heading': _("Email"), 'subheading': "" }]) align = Gtk.Alignment(xscale=0, xalign=0.5) self.pack_start(align, False, False, 15) self.labelled_entries.set(0, 0, 1, 1) self.labelled_entries.set_hexpand(True) align.add(self.labelled_entries) self.email_entry = self.labelled_entries.get_entry(0) self.email_entry.set_text("") self.email_entry.connect('key-release-event', self.activate) self.button = KanoButton(_("REQUEST REMINDER")) self.button.pack_and_align() self.button.connect('button-release-event', self.activate) self.button.connect('key-release-event', self.activate) self.button.set_padding(30, 30, 0, 0) self.pack_start(self.button.align, False, False, 0) self.email_entry.grab_focus() self.win.show_all()
def __init__(self, win, prev_screen=None, first_boot=False): Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL) self.win = win self.win.set_main_widget(self) self.win.set_decorated(True) self.win.set_size_request(self.width, -1) self.first_boot = first_boot self.heading = Heading(_("Login"), _("Enter your username and password")) self.pack_start(self.heading.container, False, False, 10) if force_login: self.add_username_as_label() else: align = Gtk.Alignment(xscale=0, xalign=0.5) self.pack_start(align, False, False, 15) self.labelled_entries = LabelledEntries([{ 'heading': _("Username"), 'subheading': "" }, { 'heading': _("Password"), 'subheading': "" }]) self.labelled_entries.set_spacing(15) self.username_entry = self.labelled_entries.get_entry(0) self.password_entry = self.labelled_entries.get_entry(1) align.add(self.labelled_entries) self.password_entry.set_visibility(False) for entry in self.labelled_entries.get_entries(): entry.connect('key_release_event', self.enable_kano_button) entry.connect('key-release-event', self.activate) self.button_box = KanoButtonBox(_("LOGIN"), _("Create New"), _("Forgot your password?"), _("Or your username?")) self.button_box.set_spacing(40) self.button_box.set_margin_left(70) self.button_box.set_margin_right(70) self.button_box.set_margin_bottom(30) self.kano_button = self.button_box.kano_button self.button_box.set_orange_button_cb(self.go_to_registration) self.button_box.set_orange_button2_cb(self.reset_password_screen) self.button_box.set_orange_button3_cb(self.recover_username_screen) self.kano_button.connect('button_release_event', self.activate) self.kano_button.connect('key-release-event', self.activate) self.pack_start(self.button_box, False, False, 20) self.kano_button.set_sensitive(False) if not force_login: self.username_entry.grab_focus() else: self.password_entry.grab_focus() self.win.show_all()
class KanoDialog(): CSS_PATH = os.path.join(common_css_dir, "dialog.css") # button_dict includes the button text, color and button return values # It can either be a dictionary for backwards compatibility, or a list def __init__(self, title_text="", description_text="", button_dict=None, widget=None, has_entry=False, has_list=False, scrolled_text="", global_style="", parent_window=None, orange_info=None, hide_from_taskbar=False): self.title_text = title_text self.description_text = description_text self.widget = widget self.button_info = button_dict self.returnvalue = 0 self.has_entry = has_entry self.has_list = has_list self.scrolled_text = scrolled_text self.global_style = global_style self.parent_window = parent_window self.orange_info = orange_info self.dialog = Gtk.Dialog() self.dialog.set_decorated(False) self.dialog.set_resizable(False) # TODO: review this - should this always be set? # self.dialog.set_keep_above(True) self.dialog.set_skip_taskbar_hint(hide_from_taskbar) self.dialog.set_border_width(5) apply_styling_to_widget(self.dialog, self.CSS_PATH) apply_colours_to_widget(self.dialog) # if widget or an orange button is added, to get styling correct # the global_styling property should be on. # TODO: is this needed any more? if global_style or (widget is not None or orange_info is not None): apply_common_to_screen() content_area, action_area = self.__colour_dialog_background() self.title = Heading(self.title_text, self.description_text) content_area.pack_start(self.title.container, False, False, 0) # If button_info is None, or an empty dictionary or list, default to an OK button if not self.button_info: button_defaults['label'] = _("OK") self.button_info = [button_defaults] # convert button dictionary to list if isinstance(self.button_info, dict): self.__convert_dict_to_list() kano_button_box = self.__generate_buttons() if orange_info is not None: button_container = self.__add_orange_button( orange_info, kano_button_box) else: button_container = Gtk.Alignment() button_container.add(kano_button_box) # annoying uneven alignment - cannot seem to centre y position button_container.set_padding(6, 3, 0, 0) action_area.pack_start(button_container, False, False, 0) # Add scrolled window if self.scrolled_text: scrolledwindow = self.__add_scrolled_window() content_area.pack_start(scrolledwindow, False, False, 0) # or add widget elif self.widget is not None: content_area.pack_start(self.widget, False, False, 0) # Set keyboard focus on first button if no entry if not has_entry: self.buttons[0].grab_focus() # Brings the focus back to the default button (OK) "hacky" if isinstance(self.widget, Gtk.Entry): def entry_activated(w): self.returnvalue = self.widget.get_text() self.dialog.response(Gtk.ResponseType.OK) self.widget.connect('activate', entry_activated) def __add_scrolled_window(self): text = Gtk.TextView() text.get_buffer().set_text(self.scrolled_text) text.set_wrap_mode(Gtk.WrapMode.WORD) text.set_editable(False) scrolledwindow = ScrolledWindow() scrolledwindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolledwindow.add_with_viewport(text) scrolledwindow.set_size_request(400, 200) scrolledwindow.apply_styling_to_widget(wide=False) return scrolledwindow def __add_orange_button(self, orange_info, kano_button_box): orange_text = orange_info['name'] orange_return_value = orange_info['return_value'] button_container = Gtk.ButtonBox(spacing=10) button_container.set_layout(Gtk.ButtonBoxStyle.SPREAD) self.orange_button = OrangeButton(orange_text) self.orange_button.connect('button-release-event', self.exit_dialog, orange_return_value) button_container.pack_start(self.orange_button, False, False, 0) button_container.pack_start(kano_button_box, False, False, 0) # The empty label is to centre the kano_button label = Gtk.Label(" ") button_container.pack_start(label, False, False, 0) return button_container def __colour_dialog_background(self): content_area = self.dialog.get_content_area() self.content_background = Gtk.EventBox() self.add_style(self.content_background, 'white') self.content_background.set_size_request(140, 140) content_area.reparent(self.content_background) action_area = self.dialog.get_action_area() self.action_background = Gtk.EventBox() self.add_style(self.action_background, 'white') action_area.reparent(self.action_background) action_area.set_layout(Gtk.ButtonBoxStyle.CENTER) # Set area around the buttons grey by default self.set_action_background('grey') container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) container.add(self.content_background) container.add(self.action_background) self.dialog.add(container) return content_area, action_area def __convert_dict_to_list(self): button_list = [] for button_name, button_arguments in self.button_info.iteritems(): button_arguments['label'] = button_name button_list.append(button_arguments) self.button_info = button_list def __generate_buttons(self): self.buttons = [] kano_button_box = Gtk.Box() for button in self.button_info: for argument, value in button_defaults.iteritems(): # Use default info if not provided if argument not in button: button[argument] = value # Create default return values for OK and CANCEL buttons if argument == 'return_value': if hasattr(button, 'label'): if button['label'] == _("OK"): button['return_value'] = 0 elif button['label'] == _("CANCEL"): button['return_value'] = 1 if argument == 'color': if button['label'] == _("CANCEL"): button['color'] = 'red' color = button['color'] return_value = button['return_value'] button_name = button['label'] button = KanoButton(button_name) button.set_color(color) button.connect('button-release-event', self.exit_dialog, return_value) button.connect('key-release-event', self.exit_dialog, return_value) self.buttons.append(button) kano_button_box.pack_start(button, False, False, 6) return kano_button_box def add_style(self, widget, app_class): apply_styling_to_widget(widget, self.CSS_PATH) style = widget.get_style_context() style.add_class(app_class) def exit_dialog(self, button, event, return_value): # 65293 is the ENTER keycode if not hasattr(event, 'keyval') or event.keyval == 65293: self.returnvalue = return_value # If we have an entry if self.has_entry: # We have to click an OK button to get entry value # May want to change this logic later to be more flexible if unicode(button.get_label().decode('utf8')) == _("OK"): self.returnvalue = self.widget.get_text() elif self.has_list: # get selected radio button only if press the OK button if unicode(button.get_label().decode('utf8')) == _("OK"): self.returnvalue = radio_returnvalue # TODO: change the structure so we emit different signals depending on the button clicked self.dialog.response(Gtk.ResponseType.OK) # Indicate that the signal has been handled return True def run(self): if self.parent_window is not None: # Make the dialog always above the parent window self.dialog.set_transient_for(self.parent_window) if self.parent_window is not None and \ hasattr(self.parent_window, 'blur') and \ callable(self.parent_window.blur): self.parent_window.blur() self.dialog.show_all() self.dialog.set_icon_name('kano-dialog') self.dialog.run() self.dialog.destroy() if self.parent_window is not None and \ hasattr(self.parent_window, 'unblur') and \ callable(self.parent_window.unblur): self.parent_window.unblur() return self.returnvalue def close(self): ''' Use this method if your app is nesting several Kano Dialogs, and you need to step through without stacking them up. ''' self.dialog.destroy() # Dispatch events so Gtk has a chance to close the dialog while Gtk.events_pending(): Gtk.main_iteration() def set_text(self, title_text, description_text): self.title_text = title_text self.description_text = description_text self.title.set_text(title_text, description_text) def set_action_background(self, color): for c in background_colors: self.action_background.get_style_context().add_class(c) self.action_background.get_style_context().add_class(color)
def __init__(self, title_text="", description_text="", button_dict=None, widget=None, has_entry=False, has_list=False, scrolled_text="", global_style="", parent_window=None, orange_info=None, hide_from_taskbar=False): self.title_text = title_text self.description_text = description_text self.widget = widget self.button_info = button_dict self.returnvalue = 0 self.has_entry = has_entry self.has_list = has_list self.scrolled_text = scrolled_text self.global_style = global_style self.parent_window = parent_window self.orange_info = orange_info self.dialog = Gtk.Dialog() self.dialog.set_decorated(False) self.dialog.set_resizable(False) # TODO: review this - should this always be set? # self.dialog.set_keep_above(True) self.dialog.set_skip_taskbar_hint(hide_from_taskbar) self.dialog.set_border_width(5) apply_styling_to_widget(self.dialog, self.CSS_PATH) apply_colours_to_widget(self.dialog) # if widget or an orange button is added, to get styling correct # the global_styling property should be on. # TODO: is this needed any more? if global_style or (widget is not None or orange_info is not None): apply_common_to_screen() content_area, action_area = self.__colour_dialog_background() self.title = Heading(self.title_text, self.description_text) content_area.pack_start(self.title.container, False, False, 0) # If button_info is None, or an empty dictionary or list, default to an OK button if not self.button_info: button_defaults['label'] = _("OK") self.button_info = [button_defaults] # convert button dictionary to list if isinstance(self.button_info, dict): self.__convert_dict_to_list() kano_button_box = self.__generate_buttons() if orange_info is not None: button_container = self.__add_orange_button( orange_info, kano_button_box) else: button_container = Gtk.Alignment() button_container.add(kano_button_box) # annoying uneven alignment - cannot seem to centre y position button_container.set_padding(6, 3, 0, 0) action_area.pack_start(button_container, False, False, 0) # Add scrolled window if self.scrolled_text: scrolledwindow = self.__add_scrolled_window() content_area.pack_start(scrolledwindow, False, False, 0) # or add widget elif self.widget is not None: content_area.pack_start(self.widget, False, False, 0) # Set keyboard focus on first button if no entry if not has_entry: self.buttons[0].grab_focus() # Brings the focus back to the default button (OK) "hacky" if isinstance(self.widget, Gtk.Entry): def entry_activated(w): self.returnvalue = self.widget.get_text() self.dialog.response(Gtk.ResponseType.OK) self.widget.connect('activate', entry_activated)
class KanoDialog: CSS_PATH = os.path.join(common_css_dir, "dialog.css") # button_dict includes the button text, color and button return values # It can either be a dictionary for backwards compatibility, or a list def __init__( self, title_text="", description_text="", button_dict=None, widget=None, has_entry=False, has_list=False, scrolled_text="", global_style="", parent_window=None, orange_info=None, hide_from_taskbar=False, ): self.title_text = title_text self.description_text = description_text self.widget = widget self.button_info = button_dict self.returnvalue = 0 self.has_entry = has_entry self.has_list = has_list self.scrolled_text = scrolled_text self.global_style = global_style self.parent_window = parent_window self.orange_info = orange_info self.dialog = Gtk.Dialog() self.dialog.set_decorated(False) self.dialog.set_resizable(False) # TODO: review this - should this always be set? # self.dialog.set_keep_above(True) self.dialog.set_skip_taskbar_hint(hide_from_taskbar) self.dialog.set_border_width(5) apply_styling_to_widget(self.dialog, self.CSS_PATH) apply_colours_to_widget(self.dialog) # if widget or an orange button is added, to get styling correct # the global_styling property should be on. # TODO: is this needed any more? if global_style or (widget is not None or orange_info is not None): apply_common_to_screen() content_area, action_area = self.__colour_dialog_background() self.title = Heading(self.title_text, self.description_text) content_area.pack_start(self.title.container, False, False, 0) # If button_info is None, or an empty dictionary or list, default to an OK button if not self.button_info: button_defaults["label"] = _("OK") self.button_info = [button_defaults] # convert button dictionary to list if isinstance(self.button_info, dict): self.__convert_dict_to_list() kano_button_box = self.__generate_buttons() if orange_info is not None: button_container = self.__add_orange_button(orange_info, kano_button_box) else: button_container = Gtk.Alignment() button_container.add(kano_button_box) # annoying uneven alignment - cannot seem to centre y position button_container.set_padding(6, 3, 0, 0) action_area.pack_start(button_container, False, False, 0) # Add scrolled window if self.scrolled_text: scrolledwindow = self.__add_scrolled_window() content_area.pack_start(scrolledwindow, False, False, 0) # or add widget elif self.widget is not None: content_area.pack_start(self.widget, False, False, 0) # Set keyboard focus on first button if no entry if not has_entry: self.buttons[0].grab_focus() def __add_scrolled_window(self): text = Gtk.TextView() text.get_buffer().set_text(self.scrolled_text) text.set_wrap_mode(Gtk.WrapMode.WORD) text.set_editable(False) scrolledwindow = ScrolledWindow() scrolledwindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolledwindow.add_with_viewport(text) scrolledwindow.set_size_request(400, 200) scrolledwindow.apply_styling_to_widget(wide=False) return scrolledwindow def __add_orange_button(self, orange_info, kano_button_box): orange_text = orange_info["name"] orange_return_value = orange_info["return_value"] button_container = Gtk.ButtonBox(spacing=10) button_container.set_layout(Gtk.ButtonBoxStyle.SPREAD) self.orange_button = OrangeButton(orange_text) self.orange_button.connect("button-release-event", self.exit_dialog, orange_return_value) button_container.pack_start(self.orange_button, False, False, 0) button_container.pack_start(kano_button_box, False, False, 0) # The empty label is to centre the kano_button label = Gtk.Label(" ") button_container.pack_start(label, False, False, 0) return button_container def __colour_dialog_background(self): content_area = self.dialog.get_content_area() self.content_background = Gtk.EventBox() self.add_style(self.content_background, "white") self.content_background.set_size_request(140, 140) content_area.reparent(self.content_background) action_area = self.dialog.get_action_area() self.action_background = Gtk.EventBox() self.add_style(self.action_background, "white") action_area.reparent(self.action_background) action_area.set_layout(Gtk.ButtonBoxStyle.CENTER) # Set area around the buttons grey by default self.set_action_background("grey") container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) container.add(self.content_background) container.add(self.action_background) self.dialog.add(container) return content_area, action_area def __convert_dict_to_list(self): button_list = [] for button_name, button_arguments in self.button_info.iteritems(): button_arguments["label"] = button_name button_list.append(button_arguments) self.button_info = button_list def __generate_buttons(self): self.buttons = [] kano_button_box = Gtk.Box() for button in self.button_info: for argument, value in button_defaults.iteritems(): # Use default info if not provided if argument not in button: button[argument] = value # Create default return values for OK and CANCEL buttons if argument == "return_value": if hasattr(button, "label"): if button["label"] == _("OK"): button["return_value"] = 0 elif button["label"] == _("CANCEL"): button["return_value"] = 1 if argument == "color": if button["label"] == _("CANCEL"): button["color"] = "red" color = button["color"] return_value = button["return_value"] button_name = button["label"] button = KanoButton(button_name) button.set_color(color) button.connect("button-release-event", self.exit_dialog, return_value) button.connect("key-release-event", self.exit_dialog, return_value) self.buttons.append(button) kano_button_box.pack_start(button, False, False, 6) return kano_button_box def add_style(self, widget, app_class): apply_styling_to_widget(widget, self.CSS_PATH) style = widget.get_style_context() style.add_class(app_class) def exit_dialog(self, button, event, return_value): # 65293 is the ENTER keycode if not hasattr(event, "keyval") or event.keyval == 65293: self.returnvalue = return_value # If we have an entry if self.has_entry: # We have to click an OK button to get entry value # May want to change this logic later to be more flexible if unicode(button.get_label().decode("utf8")) == _("OK"): self.returnvalue = self.widget.get_text() elif self.has_list: # get selected radio button only if press the OK button if unicode(button.get_label().decode("utf8")) == _("OK"): self.returnvalue = radio_returnvalue # TODO: change the structure so we emit different signals depending on the button clicked self.dialog.response(Gtk.ResponseType.OK) # Indicate that the signal has been handled return True def run(self): if self.parent_window is not None: # Make the dialog always above the parent window self.dialog.set_transient_for(self.parent_window) if self.parent_window is not None and hasattr(self.parent_window, "blur") and callable(self.parent_window.blur): self.parent_window.blur() self.dialog.show_all() self.dialog.set_icon_name("kano-dialog") self.dialog.run() self.dialog.destroy() if ( self.parent_window is not None and hasattr(self.parent_window, "unblur") and callable(self.parent_window.unblur) ): self.parent_window.unblur() return self.returnvalue def close(self): """ Use this method if your app is nesting several Kano Dialogs, and you need to step through without stacking them up. """ self.dialog.destroy() # Dispatch events so Gtk has a chance to close the dialog while Gtk.events_pending(): Gtk.main_iteration() def set_text(self, title_text, description_text): self.title_text = title_text self.description_text = description_text self.title.set_text(title_text, description_text) def set_action_background(self, color): for c in background_colors: self.action_background.get_style_context().add_class(c) self.action_background.get_style_context().add_class(color)
def __init__( self, title_text="", description_text="", button_dict=None, widget=None, has_entry=False, has_list=False, scrolled_text="", global_style="", parent_window=None, orange_info=None, hide_from_taskbar=False, ): self.title_text = title_text self.description_text = description_text self.widget = widget self.button_info = button_dict self.returnvalue = 0 self.has_entry = has_entry self.has_list = has_list self.scrolled_text = scrolled_text self.global_style = global_style self.parent_window = parent_window self.orange_info = orange_info self.dialog = Gtk.Dialog() self.dialog.set_decorated(False) self.dialog.set_resizable(False) # TODO: review this - should this always be set? # self.dialog.set_keep_above(True) self.dialog.set_skip_taskbar_hint(hide_from_taskbar) self.dialog.set_border_width(5) apply_styling_to_widget(self.dialog, self.CSS_PATH) apply_colours_to_widget(self.dialog) # if widget or an orange button is added, to get styling correct # the global_styling property should be on. # TODO: is this needed any more? if global_style or (widget is not None or orange_info is not None): apply_common_to_screen() content_area, action_area = self.__colour_dialog_background() self.title = Heading(self.title_text, self.description_text) content_area.pack_start(self.title.container, False, False, 0) # If button_info is None, or an empty dictionary or list, default to an OK button if not self.button_info: button_defaults["label"] = _("OK") self.button_info = [button_defaults] # convert button dictionary to list if isinstance(self.button_info, dict): self.__convert_dict_to_list() kano_button_box = self.__generate_buttons() if orange_info is not None: button_container = self.__add_orange_button(orange_info, kano_button_box) else: button_container = Gtk.Alignment() button_container.add(kano_button_box) # annoying uneven alignment - cannot seem to centre y position button_container.set_padding(6, 3, 0, 0) action_area.pack_start(button_container, False, False, 0) # Add scrolled window if self.scrolled_text: scrolledwindow = self.__add_scrolled_window() content_area.pack_start(scrolledwindow, False, False, 0) # or add widget elif self.widget is not None: content_area.pack_start(self.widget, False, False, 0) # Set keyboard focus on first button if no entry if not has_entry: self.buttons[0].grab_focus()