def show_tooltip(self): if not self.helptext: return # recreate full tooltip since new text needs to be relayouted if self.gui is None: self.gui = load_uh_widget('tooltip.xml') else: self.gui.removeAllChildren() translated_tooltip = _(self.helptext) #HACK this looks better than splitting into several lines & joining # them. works because replace_whitespace in fill defaults to True: replaced = translated_tooltip.replace(r'\n', self.CHARS_PER_LINE * ' ') replaced = replaced.replace('[br]', self.CHARS_PER_LINE * ' ') tooltip = textwrap.fill(replaced, self.CHARS_PER_LINE) line_count = len(tooltip.splitlines()) - 1 top_image = Icon(image=self.TOP_IMAGE, position=(0, 0)) self.gui.addChild(top_image) top_x, top_y = top_image.position top_y += self.SIZE_BG_TOP for i in xrange(0, line_count): middle_image = Icon(image=self.MIDDLE_IMAGE) middle_image.position = (top_x, top_y + self.LINE_HEIGHT * i) self.gui.addChild(middle_image) bottom_image = Icon(image=self.BOTTOM_IMAGE) bottom_image.position = (top_x, top_y + self.LINE_HEIGHT * line_count) self.gui.addChild(bottom_image) label = Label(text=tooltip, position=(10, 5)) self.gui.addChild(label) self.gui.stylize('tooltip') size_y = self.SIZE_BG_TOP + self.LINE_HEIGHT * line_count + self.SIZE_BG_BOTTOM self.gui.size = (145, size_y) self.gui.show()
def __init__(self): self.page_widgets = {} self.dict_lt = {} self.dict_rt = {} self.widget = load_uh_widget(self.widget_xml, style=self.style) self.pickbelts_container_lt = self.widget.findChild(name="left_pickbelts") self.pickbelts_container_rt = self.widget.findChild(name="right_pickbelts") for i in range(len(self.sections)): self.page_widgets[i] = self.widget.findChild(name=self.sections[i][0]) # Create the required pickbelts for side in ('lt', 'rt'): for i in range(len(self.sections)): pickbelt = ImageButton(is_focusable=False) pickbelt.name = self.sections[i][0] + '_' + side pickbelt.text = self.sections[i][1] pickbelt.font = "small_tooltip" pickbelt.position = (self.pickbelt_start_pos[0]+5*i, self.pickbelt_start_pos[1]+70*i) pickbelt.capture(Callback(self.update_view, i), event_name="mouseClicked") if side == 'lt': pickbelt.up_image='content/gui/images/background/pickbelt_l.png' self.pickbelts_container_lt.addChild(pickbelt) self.dict_lt[i] = pickbelt else: pickbelt.up_image='content/gui/images/background/pickbelt_r.png' self.pickbelts_container_rt.addChild(pickbelt) self.dict_rt[i] = pickbelt self.widget.show() # Hack to initially setup the pickbelts properly self.update_view() self.widget.hide() # Hack to initially setup the pickbelts properly
def add_gui_entry(self, warehouse, resource_list=None): vbox = self._gui.findChild(name="left_vbox") entry = load_uh_widget("route_entry.xml") entry.name = 'container_%s' % len(self.widgets) entry.settlement = weakref.ref(warehouse.settlement) self.widgets.append(entry) settlement_name_label = entry.findChild(name="warehouse_name") settlement_name_label.text = warehouse.settlement.get_component(NamedComponent).name player_name_label = entry.findChild(name="player_name") player_name_label.text = warehouse.owner.name self.add_trade_slots(entry) index = 1 resource_list = resource_list or {} for res_id in resource_list: if index > self.SLOTS_PER_ENTRY: break self.add_resource(slot=self.slots[entry][index - 1], res_id=res_id, entry=entry, has_value=True, value=resource_list[res_id]) index += 1 entry.mapEvents({ 'delete_warehouse/mouseClicked': Callback(self.remove_entry, entry), 'move_up/mouseClicked': Callback(self.move_entry, entry, 'up'), 'move_down/mouseClicked': Callback(self.move_entry, entry, 'down') }) vbox.addChild(entry)
def __init__(self, instances, show_number=True): self.log = logging.getLogger("gui.tabs") self.instances = instances self.widget = load_uh_widget("unit_entry_widget.xml") # get the icon of the first instance i = instances[0] if i.id < UNITS.DIFFERENCE_BUILDING_UNIT_ID: # A building. Generate dynamic thumbnail from its action set. imgs = ActionSetLoader.get_set(i._action_set_id).items()[0][1] thumbnail = imgs[45].keys()[0] else: # Units use manually created thumbnails because those need to be # precise and recognizable in combat situations. thumbnail = self.get_unit_thumbnail(i.id) self.widget.findChild(name="unit_button").up_image = thumbnail if show_number: self.widget.findChild(name="instance_number").text = unicode(len(self.instances)) # only two callbacks are needed so drop unwanted changelistener inheritance for i in instances: if not i.has_remove_listener(Callback(self.on_instance_removed, i)): i.add_remove_listener(Callback(self.on_instance_removed, i)) health_component = i.get_component(HealthComponent) if not health_component.has_damage_dealt_listener(self.draw_health): health_component.add_damage_dealt_listener(self.draw_health) self.draw_health()
def __init__(self, windows): super(EditorStartMenu, self).__init__(windows) self._gui = load_uh_widget('editor_start_menu.xml') self._gui.position_technique = "center:center" self._right_side = None self._select_mode('create_new_map')
def refresh(self): """This function is called by the TabWidget to redraw the widget.""" self._refresh_utilisation() # remove old production line data parent_container = self.widget.child_finder('production_lines') while parent_container.children: child = parent_container.children[-1] if hasattr(child, "anim"): child.anim.stop() del child.anim parent_container.removeChild( child ) # create a container for each production # sort by production line id to have a consistent (basically arbitrary) order for production in self.get_displayed_productions(): # we need to be notified of small production changes # that aren't passed through the instance production.add_change_listener(self._schedule_refresh, no_duplicates=True) gui = load_uh_widget(self.production_line_gui_xml) # fill in values to gui reflecting the current game state container = gui.findChild(name="production_line_container") self._set_resource_amounts(container, production) if production.is_paused(): container.removeChild( container.findChild(name="toggle_active_active") ) toggle_icon = container.findChild(name="toggle_active_inactive") toggle_icon.name = "toggle_active" else: container.removeChild( container.findChild(name="toggle_active_inactive") ) toggle_icon = container.findChild(name="toggle_active_active") toggle_icon.name = "toggle_active" if production.get_state() == PRODUCTION.STATES.producing: bg = Icon(image=self.__class__.BUTTON_BACKGROUND) bg.position = toggle_icon.position container.addChild(bg) container.removeChild(toggle_icon) # fix z-ordering container.addChild(toggle_icon) anim = PychanAnimation(toggle_icon, self.__class__.ACTIVE_PRODUCTION_ANIM_DIR) container.anim = anim anim.start(1.0/12, -1) # always start anew, people won't notice self._animations.append( weakref.ref( anim ) ) # fill it with input and output resources in_res_container = container.findChild(name="input_res") self._add_resource_icons(in_res_container, production.get_consumed_resources(), marker=True) out_res_container = container.findChild(name="output_res") self._add_resource_icons(out_res_container, production.get_produced_resources()) # active toggle_active button toggle_active = ToggleActive(self.instance.get_component(Producer), production) container.mapEvents({ 'toggle_active': Callback(toggle_active.execute, self.instance.session) }) # NOTE: this command causes a refresh, so we needn't change the toggle_active-button-image container.stylize('menu_black') parent_container.addChild(container) super(ProductionOverviewTab, self).refresh()
def add_trade_slots(self, entry, slot_amount=SLOTS_PER_ENTRY): x_position = 105 # Initialize slots with empty dict. self.slots[entry] = {} for num in range(slot_amount): slot = load_uh_widget('trade_single_slot.xml') slot.name = 'slot_%d' % num slot.position = (x_position, 0) slot.action = "load" slider = slot.findChild(name="slider") slider.scale_start = 0.0 slider.scale_end = float(self.instance.get_component(StorageComponent).inventory.limit) slot.findChild(name="buysell").capture(Callback(self.toggle_load_unload, slot, entry)) button = slot.findChild(name="button") button.capture(self.handle_resource_click, event_name='mouseClicked') button.up_image = self.dummy_icon_path button.down_image = self.dummy_icon_path button.hover_image = self.dummy_icon_path icon = slot.findChild(name="icon") fillbar = slot.findChild(name="fillbar") fillbar.position = (icon.width - fillbar.width - 1, icon.height) x_position += 60 entry.addChild(slot) self.slots[entry][num] = slot self.show_load_icon(slot)
def _get_res_background_icon_position(self): # currently unused since always 0 # can be used for relative positioning of labels # old formula: label.position = (icon.position[0] - label.size[0]/2 + xoffset, yoffset) gui = load_uh_widget( self.__class__.ENTRY_GUI_FILE ) icon = gui.findChild(name="background_icon") return icon.position
def __init__(self, session): from horizons.session import Session assert isinstance(session, Session) self.session = session # special slot because of special properties self.gold_gui = load_uh_widget(self.__class__.GOLD_ENTRY_GUI_FILE, style=self.__class__.STYLE) self.gold_gui.balance_visible = False self.gold_gui.child_finder = PychanChildFinder(self.gold_gui) gold_icon = self.gold_gui.child_finder("res_icon") gold_icon.image = get_res_icon_path(RES.GOLD) gold_icon.max_size = gold_icon.min_size = gold_icon.size = (32, 32) self.gold_gui.mapEvents({ "resbar_gold_container/mouseClicked/stats" : self._toggle_stats, }) self.gold_gui.helptext = _("Click to show statistics") self.stats_gui = None self.gui = [] # list of slots self.resource_configurations = weakref.WeakKeyDictionary() self.current_instance = weakref.ref(self) # can't weakref to None self.construction_mode = False self._last_build_costs = None self._do_show_dummy = False self._update_default_configuration() NewPlayerSettlementHovered.subscribe(self._on_different_settlement) TabWidgetChanged.subscribe(self._on_tab_widget_changed) # set now and then every few sec ExtScheduler().add_new_object(self._update_balance_display, self, run_in=0) ExtScheduler().add_new_object(self._update_balance_display, self, run_in=Player.STATS_UPDATE_INTERVAL, loops=-1)
def add_slots(self, num): """ Adds num amount of slots to the buysellmenu. @param num: amount of slots that are to be added. """ content = self.widget.findChild(name="content") assert(content is not None) for num in range(0, num): slot = load_uh_widget('trade_single_slot.xml') self.slots[num] = slot slot.id = num slot.action = 'buy' slot.res = None slot.findChild(name='button').capture(self.handle_click, event_name = 'mouseClicked') slot.findChild(name='button').up_image = self.dummy_icon_path slot.findChild(name='button').down_image = self.dummy_icon_path slot.findChild(name='button').hover_image = self.dummy_icon_path slot.findChild(name='amount').stylize('menu_black') slider = slot.findChild(name="slider") slider.scale_start = 0.0 slider.scale_end = float(self.tradepost.get_inventory().limit) # Set scale according to the settlement inventory size slot.findChild(name="buysell").capture(Callback(self.toggle_buysell, num)) fillbar = slot.findChild(name="fillbar") # hide fillbar by setting position icon = slot.findChild(name="icon") fillbar.position = (icon.width - fillbar.width - 1, icon.height) content.addChild(slot) self.widget.adaptLayout()
def _init_gui(self): self._gui = load_uh_widget(self.widget_file_name, center_widget=self.center_widget) if not self.center_widget: self._gui.position_technique = 'center+20:center+25' self._page_left = self._gui.findChild(name='page_left') self._page_right = self._gui.findChild(name='page_right') self.refresh()
def __init__(self): self.gui = load_uh_widget('aidataselection.xml') self.gui.distributeInitialData({'ai_players': [unicode(n) for n in xrange(MULTIPLAYER.MAX_PLAYER_COUNT)]}) self.gui.distributeData({ 'ai_players': int(horizons.globals.fife.get_uh_setting("AIPlayers")) })
def __init__(self, windows, singleplayer_menu, aidata): self._windows = windows self._singleplayer_menu = singleplayer_menu self._aidata = aidata self._scenarios = {} self._gui = load_uh_widget('sp_scenario.xml')
def _show_change_player_details_popup(self, game): """Shows a dialog where the player can change its name and/or color""" assigned = [p["color"] for p in NetworkInterface().get_game().get_player_list() if p["name"] != NetworkInterface().get_client_name()] unused_colors = set(Color) - set(assigned) playerdata = PlayerDataSelection(color_palette=unused_colors) playerdata.set_player_name(NetworkInterface().get_client_name()) playerdata.set_color(NetworkInterface().get_client_color()) dialog = load_uh_widget('set_player_details.xml') dialog.findChild(name="playerdataselectioncontainer").addChild(playerdata.get_widget()) def _change_playerdata(): NetworkInterface().change_name(playerdata.get_player_name()) NetworkInterface().change_color(playerdata.get_player_color().id) dialog.hide() self._update_game_details() def _cancel(): dialog.hide() dialog.mapEvents({ OkButton.DEFAULT_NAME: _change_playerdata, CancelButton.DEFAULT_NAME: _cancel }) dialog.show()
def __init__(self, player, resource_id, amount, gold, **kwargs): super(TradeHistoryItem, self).__init__(**kwargs) self.widget = load_uh_widget('trade_history_item.xml') self.addChild(self.widget) self.findChild(name='player_emblem').background_color = player.color self.findChild(name='player_name').text = player.name gold_amount_label = self.findChild(name='gold_amount') gold_amount_label.text = u'{gold:+5d}'.format(gold=gold) gold_icon = self.findChild(name='gold_icon') gold_icon.image = get_res_icon_path(RES.GOLD) gold_icon.max_size = gold_icon.min_size = gold_icon.size = (16, 16) gold_icon.helptext = player.session.db.get_res_name(RES.GOLD) resource_amount_label = self.findChild(name='resource_amount') resource_amount_label.text = u'{amount:+5d}'.format(amount=amount) resource_icon = self.findChild(name='resource_icon') resource_icon.image = get_res_icon_path(resource_id) resource_icon.max_size = resource_icon.min_size = resource_icon.size = (16, 16) resource_icon.helptext = player.session.db.get_res_name(resource_id) self.size = self.widget.size
def show(self): if not self._check_connection(): return self._gui = load_uh_widget('multiplayermenu.xml') self._gui.mapEvents({ 'cancel' : self._windows.close, 'join' : self._join_game, 'create' : self._create_game, 'refresh': Callback(self._refresh, play_sound=True) }) self._gui.findChild(name='gamelist').capture(self._update_game_details) self._playerdata = PlayerDataSelection() self._gui.findChild(name="playerdataselectioncontainer").addChild(self._playerdata.get_widget()) refresh_worked = self._refresh() if not refresh_worked: self._windows.close() return # FIXME workaround for multiple callback registrations # this happens because subscription is done when the window is showed, unsubscription # only when it is closed. if new windows appear and disappear, show is called multiple # times. the error handler is used throughout the entire mp menu, that's why we can't # unsubscribe in hide. need to find a better solution. NetworkInterface().discard("error", self._on_error) NetworkInterface().subscribe("error", self._on_error) self._gui.show() # TODO Remove once loading a game is implemented again self._gui.findChild(name='load').parent.hide()
def __init__(self): super(HotkeyConfiguration, self).__init__() self.widget = load_uh_widget('hotkeys.xml') self.buttons = [] self.secondary_buttons = [] self.keyconf = KeyConfig() self.actions = self.keyconf.get_bindable_actions_by_name() self.keys = self.keyconf.get_keys_by_value() self.HELPSTRING_LAYOUT = None self._is_displayed = False self._build_interface() # When detecing is True, the interface detects keypresses and binds them to actions self.detecting = False self.current_button = None self.current_index = None self.last_combination = [] # Stores whether the last button pressed was for a primary or secondary binding (1 or 2) self.last_column = 1 # There are some keys which are not detected by the event widget/keyPressed # In that case, the key presses are detected by the listener, which calls _detect_keypress self.listener = HotkeysListener(self._detect_keypress) self.widget.mapEvents({self.widget.name + '/keyPressed' : self._detect_keypress}) self.widget.findChild(name=OkButton.DEFAULT_NAME).capture(self.save_settings) self.widget.mapEvents({OkButton.DEFAULT_NAME : self.save_settings}) self.widget.findChild(name="reset_to_default").capture(self.reset_to_default)
def __init__(self): self.page_widgets = {} self.widget = load_uh_widget(self.widget_xml, center_widget=True) # Lists holding pickbelt ImageButtons, placed to the left/right of the book self.buttons = {'left': [], 'right': []} for i, (name, text) in enumerate(self.sections): self.page_widgets[i] = self.widget.findChild(name=name) # Create the required pickbelts for i, (name, text) in enumerate(self.sections): for side in self.buttons: pickbelt = ImageButton(text=text) pickbelt.name = name + '_' + side pickbelt.path = 'images/background/pickbelt_%s' % side pickbelt.font = "pickbelt" pickbelt.capture(Callback(self.update_view, i), event_name="mouseClicked") start_x, start_y = self.pickbelt_start_pos pickbelt.position = (start_x + 5*i, start_y + 70*i) container = self.widget.findChild(name="%s_pickbelts" % side) container.addChild(pickbelt) self.buttons[side].append(pickbelt) self.widget.show() # Hack to initially setup the pickbelts properly self.update_view() self.widget.hide() # Hack to initially setup the pickbelts properly
def _build_popup(self, windowtitle, message, show_cancel_button=False, size=0): """ Creates a pychan popup widget with the specified properties. @param windowtitle: the title of the popup @param message: the text displayed in the popup @param show_cancel_button: boolean, include cancel button or not @param size: 0, 1 or 2 @return: Container(name='popup_window') with buttons 'okButton' and optionally 'cancelButton' """ if size == 0: wdg_name = "popup_230" elif size == 1: wdg_name = "popup_290" elif size == 2: wdg_name = "popup_350" else: assert False, "size should be 0 <= size <= 2, but is "+str(size) # NOTE: reusing popup dialogs can sometimes lead to exit(0) being called. # it is yet unknown why this happens, so let's be safe for now and reload the widgets. popup = load_uh_widget(wdg_name + '.xml') if not show_cancel_button: cancel_button = popup.findChild(name=CancelButton.DEFAULT_NAME) cancel_button.parent.removeChild(cancel_button) popup.headline = popup.findChild(name='headline') popup.headline.text = _(windowtitle) popup.message = popup.findChild(name='popup_message') popup.message.text = _(message) popup.adaptLayout() # recalculate widths return popup
def __init__(self, color_palette=None): """ @param widgets: WidgetsDict """ self.gui = load_uh_widget('playerdataselection.xml') self.colors = self.gui.findChild(name='playercolor') self.selected_color = horizons.globals.fife.get_uh_setting("ColorID") # starts at 1! self.set_color(self.selected_color) colorlabels = [] events = {} # need the id to save it as int in settings file. for color in (Color if color_palette is None else color_palette): label = Label(name = u'{color}'.format(color=color.name), text = u" ", max_size = (20,20), min_size = (20,20), background_color = color) events['{label}/mouseClicked'.format(label=color.name)] = \ Callback(self.set_color, color.id) colorlabels.append(label) # split into three rows with at max 5 entries in each row # right now there are 14 different colors to choose from. for i in xrange(0, len(colorlabels), 5): hbox = HBox(name='line_{index}'.format(index=i)) hbox.addChildren(colorlabels[i:i+5]) self.colors.addChild(hbox) self.gui.distributeData({ 'playername': unicode(horizons.globals.fife.get_uh_setting("Nickname")), }) self.gui.mapEvents(events)
def show(self): if not self._check_connection(): return self._gui = load_uh_widget('multiplayermenu.xml') self._gui.mapEvents({ 'cancel' : self._windows.close, 'join' : self._join_game, 'create' : self._create_game, 'refresh': Callback(self._refresh, play_sound=True) }) self._gui.findChild(name='gamelist').capture(self._update_game_details) self._playerdata = PlayerDataSelection() self._gui.findChild(name="playerdataselectioncontainer").addChild(self._playerdata.get_widget()) refresh_worked = self._refresh() if not refresh_worked: self._windows.close() return NetworkInterface().subscribe("game_prepare", self._prepare_game) NetworkInterface().subscribe("error", self._on_error) self._gui.show() # TODO Remove once loading a game is implemented again self._gui.findChild(name='load').parent.hide()
def add_slots(self, amount): """ Add `amount` slot widgets to the buysellmenu. @param amount: number of slot widgets that are to be added. """ content = self.widget.findChild(name="content") for i in xrange(amount): slot = load_uh_widget('trade_single_slot.xml') self.slot_widgets[i] = slot slot.id = i slot.action = 'buy' slot.res = None slot.name = "slot_%d" % i slot.findChild(name='button').capture(self.handle_click, event_name='mouseClicked') slot.findChild(name='button').path = self.dummy_icon_path slider = slot.findChild(name="slider") slider.scale_start = 0.0 slider.scale_end = float(self.trade_post.get_inventory().limit) # Set scale according to the settlement inventory size slot.findChild(name="buysell").capture(Callback(self.toggle_buysell, i)) fillbar = slot.findChild(name="fillbar") # hide fillbar by setting position icon = slot.findChild(name="icon") fillbar.position = (icon.width - fillbar.width - 1, icon.height) content.addChild(slot) self.widget.adaptLayout()
def prepare(self, instance): self._gui = load_uh_widget("change_name.xml") self._gui.findChild(name="new_name").capture(self._on_keypress, "keyPressed") self.return_events = {OkButton.DEFAULT_NAME: instance, CancelButton.DEFAULT_NAME: False} oldname = self._gui.findChild(name="old_name") oldname.text = instance.get_component(NamedComponent).name
def __init__(self, session): from horizons.session import Session assert isinstance(session, Session) self.session = session # special slot because of special properties self.gold_gui = load_uh_widget(self.__class__.GOLD_ENTRY_GUI_FILE, style=self.__class__.STYLE) self.gold_gui.balance_visible = False self.gold_gui.child_finder = PychanChildFinder(self.gold_gui) self.gold_gui.child_finder("res_icon").image = get_res_icon_path(RES.GOLD, 32) self.gui = [] # list of slots self.resource_configurations = weakref.WeakKeyDictionary() self.current_instance = weakref.ref(self) # can't weakref to None self.construction_mode = False self._last_build_costs = None self._do_show_dummy = False self._update_default_configuration() NewPlayerSettlementHovered.subscribe(self._on_different_settlement) TabWidgetChanged.subscribe(self._on_tab_widget_changed) # set now and then every 2 sec ExtScheduler().add_new_object(self._update_balance_display, self, run_in=0) ExtScheduler().add_new_object(self._update_balance_display, self, run_in=2, loops=-1)
def __init__(self, ingame_gui, tabs=None, position=None, name=None, active_tab=None): """ @param ingame_gui: IngameGui instance @param tabs: tab instances to show @param position: position as tuple (x, y) @param name: optional name for the tabwidget @param active_tab: int id of tab, 0 <= active_tab < len(tabs) """ super(TabWidget, self).__init__() self.name = name self.ingame_gui = ingame_gui self._tabs = [] if not tabs else tabs self.current_tab = self._tabs[0] # Start with the first tab self.widget = load_uh_widget("tab_base.xml") if position is None: # add positioning here self.widget.position = ( horizons.globals.fife.engine_settings.getScreenWidth() - 290, 209 ) else: self.widget.position = position self.content = self.widget.findChild(name='content') self._init_tabs() # select a tab to show (first one is default) if active_tab is not None: self._show_tab(active_tab)
def __init__(self, mode, windows): super(SelectSavegameDialog, self).__init__(windows) assert mode in ('load', 'save', 'editor-save') self._mode = mode self._gui = load_uh_widget('select_savegame.xml') if self._mode == 'save': helptext = _('Save game') elif self._mode == 'load': helptext = _('Load game') elif self._mode == 'editor-save': helptext = _('Save map') self._gui.findChild(name='headline').text = helptext self._gui.findChild(name=OkButton.DEFAULT_NAME).helptext = helptext w = self._gui.findChild(name="gamename_box") if w not in w.parent.hidden_children: w.parent.hideChild(w) w = self._gui.findChild(name="gamepassword_box") if w not in w.parent.hidden_children: w.parent.hideChild(w) w = self._gui.findChild(name='enter_filename') if self._mode in ('save', 'editor-save'): # only show enter_filename on save w.parent.showChild(w) elif w not in w.parent.hidden_children: w.parent.hideChild(w) self.last_click_event = None
def get_widget(self): """Loads the filename in self.widget. Override this in your subclass if you want to handle widget loading/creation yourself. """ return load_uh_widget(self.widget)
def __init__(self, gui, windows): super(MainMenu, self).__init__(windows) self._gui = load_uh_widget('mainmenu.xml', 'menu') self._gui.mapEvents({ 'single_button': lambda: self._windows.open(gui.singleplayermenu), 'single_label' : lambda: self._windows.open(gui.singleplayermenu), 'multi_button': lambda: self._windows.open(gui.multiplayermenu), 'multi_label' : lambda: self._windows.open(gui.multiplayermenu), 'settings_button': lambda: self._windows.open(gui.settings_dialog), 'settings_label' : lambda: self._windows.open(gui.settings_dialog), 'help_button': gui.on_help, 'help_label' : gui.on_help, 'quit_button': self.on_escape, 'quit_label' : self.on_escape, 'editor_button': gui.show_editor_start_menu, 'editor_label' : gui.show_editor_start_menu, 'credits_button': gui.show_credits, 'credits_label' : gui.show_credits, 'load_button': gui.load_game, 'load_label' : gui.load_game, 'changeBackground' : gui.rotate_background, 'changeBackground/mouseEntered' : self.mouse_entered_changebackground, 'changeBackground/mouseExited': self.mouse_exited_changebackground, }) # non-default background color for this Label w = self._gui.findChildByName('changeBackground') w.background_color = self.CHANGE_BACKGROUND_LABEL_BACKGROUND_COLOR[0]
def show_tooltip(self): if self.helptext not in ("", None): # recreate full tooltip since new text needs to be relayouted if self.gui is None: self.gui = load_uh_widget('tooltip.xml') else: self.gui.removeAllChildren() translated_tooltip = _(self.helptext) #HACK this looks better than splitting into several lines & joining # them. works because replace_whitespace in fill defaults to True: replaced = translated_tooltip.replace(r'\n', self.CHARS_PER_LINE*' ') replaced = replaced.replace(r'[br]', self.CHARS_PER_LINE*' ') tooltip = textwrap.fill(replaced, self.CHARS_PER_LINE) #---------------------------------------------------------------- line_count = len(tooltip.splitlines())-1 top_image = pychan.widgets.Icon(image='content/gui/images/background/widgets/tooltip_bg_top.png', position=(0, 0)) self.gui.addChild(top_image) for i in xrange(0, line_count): middle_image = pychan.widgets.Icon( \ image='content/gui/images/background/widgets/tooltip_bg_middle.png', position=(top_image.position[0], \ top_image.position[1] + self.SIZE_BG_TOP + self.LINE_HEIGHT * i)) self.gui.addChild(middle_image) bottom_image = pychan.widgets.Icon( \ image='content/gui/images/background/widgets/tooltip_bg_bottom.png', position=(top_image.position[0], \ top_image.position[1] + self.SIZE_BG_TOP + self.LINE_HEIGHT * line_count)) self.gui.addChild(bottom_image) label = pychan.widgets.Label(text=u"", position=(10, 5)) label.text = tooltip self.gui.addChild(label) self.gui.stylize('tooltip') self.gui.size = (145, self.SIZE_BG_TOP + self.LINE_HEIGHT * line_count + self.SIZE_BG_BOTTOM) self.gui.show()
def show_popup(self, windowtitle, message, show_cancel_button=False, size=0, modal=True): """Displays a popup with the specified text @param windowtitle: the title of the popup @param message: the text displayed in the popup @param show_cancel_button: boolean, show cancel button or not @param size: 0, 1 or 2. Larger means bigger. @param modal: Whether to block user interaction while displaying the popup @return: True on ok, False on cancel (if no cancel button, always True) """ if size == 0: wdg_name = "popup_230" elif size == 1: wdg_name = "popup_290" elif size == 2: wdg_name = "popup_350" else: assert False, "size should be 0 <= size <= 2, but is " + str(size) popup = load_uh_widget(wdg_name + '.xml') headline = popup.findChild(name='headline') headline.text = _(windowtitle) message_lbl = popup.findChild(name='popup_message') message_lbl.text = _(message) popup.adaptLayout() # recalculate widths if show_cancel_button: bind = {OkButton.DEFAULT_NAME: True, CancelButton.DEFAULT_NAME: False} else: bind = {OkButton.DEFAULT_NAME: True} cancel_button = popup.findChild(name=CancelButton.DEFAULT_NAME) cancel_button.parent.removeChild(cancel_button) return self.show_dialog(popup, bind, modal=modal)
def __init__(self): (width, height) = horizons.globals.fife.get_fife_setting( 'ScreenResolution').split('x') res_width = int(width) res_height = int(height) center_width = (res_width // 2) center_height = (res_height // 2) loading_pos_width = (center_width - 125) loading_pos_height = (center_height - 68) quotearea_pos_width = 0 quotearea_pos_height = (res_height - 207) loading_label_pos_width = (loading_pos_width + 25) loading_label_pos_height = (loading_pos_height) qotl_type_label_pos_width = (center_width - 50) qotl_type_label_pos_height = (res_height - 100) qotl_label_pos_width = (qotl_type_label_pos_width) qotl_label_pos_height = (res_height - 80) version_label_pos_width = (res_width - 150) version_label_pos_height = (res_height - 100) loading_stage_pos_width = 150 loading_stage_pos_height = (res_height - 80) loading_progress_pos_width = (loading_label_pos_width) loading_progress_pos_height = (loading_label_pos_height + 79) self._widget = load_uh_widget('loadingscreen.xml') self._widget.position_technique = "center:center" loadingscreen = self._widget.findChild(name='loadingscreen') loadingscreen.size = res_width, res_height loading_image = self._widget.findChild(name='loading_image') loading_image.position = loading_pos_width, loading_pos_height quote_area = self._widget.findChild(name='quote_area') quote_area.position = quotearea_pos_width, quotearea_pos_height loading_label = self._widget.findChild(name='loading_label') loading_label.position = loading_label_pos_width, loading_label_pos_height qotl_type_label = self._widget.findChild(name='qotl_type_label') qotl_type_label.position = qotl_type_label_pos_width, qotl_type_label_pos_height qotl_label = self._widget.findChild(name='qotl_label') qotl_label.position = qotl_label_pos_width, qotl_label_pos_height version_label = self._widget.findChild(name='version_label') version_label.position = version_label_pos_width, version_label_pos_height loading_stage = self._widget.findChild(name='loading_stage') loading_stage.position = loading_stage_pos_width, loading_stage_pos_height loading_progress = self._widget.findChild(name='loading_progress') loading_progress.position = loading_progress_pos_width, loading_progress_pos_height self._current_step = 0
def __init__(self, **kwargs): super(StanceWidget, self).__init__(size=(245, 50), **kwargs) widget = load_uh_widget('stancewidget.xml') self.addChild(widget) ExtScheduler().add_new_object(self.refresh, self, run_in=0.3, loops=-1)
def __init__(self, **kwargs): super(HealthWidget, self).__init__(size=(50, 25), **kwargs) widget = load_uh_widget('healthwidget.xml') self.addChild(widget)
def __init__(self, windows, parent_widget): self._windows = windows self._parent_widget = parent_widget self._gui = load_uh_widget('editor_select_saved_game.xml') self._saved_game_data = None
def _load_widget(self, widget): widget = load_uh_widget(widget, style="menu_black") widget.child_finder = PychanChildFinder(widget) return widget
def prepare(self): self._gui = load_uh_widget('chat.xml') self.return_events = { OkButton.DEFAULT_NAME: True, CancelButton.DEFAULT_NAME: False, }
def _init_gui(self): """ Initial init of gui. widgets : list of route entry widgets slots : dict with slots for each entry """ self._gui = load_uh_widget("configure_route.xml") self.widgets = [] self.slots = {} self.slots_per_entry = 3 icon = self._gui.findChild(name="minimap") def on_click(event, drag): if drag: return if event.getButton() == fife.MouseEvent.LEFT: map_coords = event.map_coords tile = self.session.world.get_tile(Point(*map_coords)) if tile is not None and tile.settlement is not None: self.append_warehouse( tile.settlement.warehouse ) self.minimap = Minimap(icon, session=self.session, world=self.session.world, view=self.session.view, targetrenderer=horizons.globals.fife.targetrenderer, imagemanager=horizons.globals.fife.imagemanager, cam_border=False, use_rotation=False, on_click=on_click) resources = self.session.db.get_res_id_and_icon(only_tradeable=True) # map an icon for a resource # map a resource for an icon self.resource_for_icon = {} self.icon_for_resource = {} for res_id, icon in list(resources) + [(0, self.dummy_icon_path)]: self.resource_for_icon[icon] = res_id self.icon_for_resource[res_id] = icon # don't do any actions if the resource menu is shown self.resource_menu_shown = False for entry in self.instance.route.waypoints: self.add_gui_entry(entry['warehouse'], entry['resource_list']) self._check_no_entries_label() wait_at_unload_box = self._gui.findChild(name="wait_at_unload") wait_at_unload_box.marked = self.instance.route.wait_at_unload def toggle_wait_at_unload(): self._route_cmd("set_wait_at_unload", not self.instance.route.wait_at_unload) wait_at_unload_box.capture(toggle_wait_at_unload) wait_at_load_box = self._gui.findChild(name="wait_at_load") wait_at_load_box.marked = self.instance.route.wait_at_load def toggle_wait_at_load(): self._route_cmd("set_wait_at_load", not self.instance.route.wait_at_load) wait_at_load_box.capture(toggle_wait_at_load) self._gui.mapEvents({ OkButton.DEFAULT_NAME : self.hide, 'start_route/mouseClicked' : self.toggle_route }) self._gui.position_technique = "automatic" # "center:center" """
def refresh(self): """This function is called by the TabWidget to redraw the widget.""" self._refresh_utilization() # remove old production line data parent_container = self.widget.child_finder('production_lines') while parent_container.children: child = parent_container.children[-1] if hasattr(child, "anim"): child.anim.stop() del child.anim parent_container.removeChild(child) # create a container for each production # sort by production line id to have a consistent (basically arbitrary) order for production in self.get_displayed_productions(): # we need to be notified of small production changes # that aren't passed through the instance production.add_change_listener(self._schedule_refresh, no_duplicates=True) gui = load_uh_widget(self.production_line_gui_xml) # fill in values to gui reflecting the current game state container = gui.findChild(name="production_line_container") centered_container = container.findChild(name='centered_production_icons') center_y = self._center_production_line(container, production) centered_container.position = (centered_container.position[0], center_y - 44 // 2) self._set_resource_amounts(container, production) if production.is_paused(): centered_container.removeChild(centered_container.findChild(name="toggle_active_active")) toggle_icon = centered_container.findChild(name="toggle_active_inactive") toggle_icon.name = "toggle_active" else: centered_container.removeChild(centered_container.findChild(name="toggle_active_inactive")) toggle_icon = centered_container.findChild(name="toggle_active_active") toggle_icon.name = "toggle_active" if production.get_state() == PRODUCTION.STATES.producing: bg = Icon(image=self.__class__.BUTTON_BACKGROUND) bg.position = toggle_icon.position centered_container.addChild(bg) centered_container.removeChild(toggle_icon) # fix z-ordering centered_container.addChild(toggle_icon) anim = PychanAnimation(toggle_icon, self.__class__.ACTIVE_PRODUCTION_ANIM_DIR) centered_container.anim = anim anim.start(1.0 / 12, -1) # always start anew, people won't notice self._animations.append(weakref.ref(anim)) # fill it with input and output resources in_res_container = container.findChild(name="input_res") self._add_resource_icons(in_res_container, production.get_consumed_resources(), marker=True) out_res_container = container.findChild(name="output_res") self._add_resource_icons(out_res_container, production.get_produced_resources()) # active toggle_active button toggle_active = ToggleActive(self.instance.get_component(Producer), production) centered_container.mapEvents({ 'toggle_active': Callback(toggle_active.execute, self.instance.session) }) # NOTE: this command causes a refresh, so we needn't change the toggle_active-button-image parent_container.addChild(container) super(ProductionOverviewTab, self).refresh()
def __get_new_container(self): """ Loads a background container xml file. Returns the loaded widget. """ gui = load_uh_widget(self.template_gui_xml) return gui.findChild(name="buildings_container")
def __init__(self): self._gui = load_uh_widget('game_settings.xml')
def _init_gui(self): self._gui = load_uh_widget(self.widget_file_name, center_widget=self.center_widget) if not self.center_widget: self._gui.position_technique = 'center+20:center+25' self._content_vbox = self._gui.findChild(name='content_vbox') self.refresh()
def set_inventory_instance(self, instance, keep_construction_mode=False, force_update=False): """Display different inventory. May change resources that are displayed""" if self.current_instance( ) is instance and not self.construction_mode and not force_update: return # caller is drunk yet again if self.construction_mode and not keep_construction_mode: # stop construction mode, immediately update view, which will be a normal view self.close_construction_mode(update_slots=False) # reconstruct general gui # remove old gui (keep entries for reuse) for i in self.gui: i.hide() self._hide_resource_selection_dialog() inv = self._get_current_inventory() if inv is not None: inv.remove_change_listener(self._update_resources) if instance in (None, self): # show nothing instead self.current_instance = weakref.ref(self) # can't weakref to None self._do_show_dummy = False # don't save dummy value return self.current_instance = weakref.ref(instance) # construct new slots (fill values later) load_entry = lambda: load_uh_widget(self.ENTRY_GUI_FILE, style=self.__class__.STYLE) resources = self._get_current_resources() addition = [-1] if self._do_show_dummy or not resources else [ ] # add dummy at end for adding stuff for i, res in enumerate(resources + addition): try: # get old slot entry = self.gui[i] if res == -1: # can't reuse dummy slot, need default data self.gui[i] = entry = load_entry() except IndexError: # need new one entry = load_entry() self.gui.append(entry) entry.findChild(name="entry").position = (self.INITIAL_X_OFFSET + i * self.ENTRY_X_OFFSET, self.ENTRY_Y_OFFSET) background_icon = entry.findChild(name="entry") background_icon.capture( Callback(self._show_resource_selection_dialog, i), 'mouseEntered', 'resbar') if res != -1: helptext = self.session.db.get_res_name(res) icon = entry.findChild(name="res_icon") icon.num = i icon.image = get_res_icon_path(res) icon.max_size = icon.min_size = icon.size = (24, 24) icon.capture(self._on_res_slot_click, event_name='mouseClicked') else: helptext = T("Click to add a new slot") entry.show() # this will not be filled as the other res background_icon.helptext = helptext # show it just when values are entered, this appeases pychan # fill values inv = self._get_current_inventory() # update on all changes as well as now inv.add_change_listener(self._update_resources, call_listener_now=True)
def _init_gui(self): """ Initial init of gui. widgets : list of route entry widgets slots : dict with slots for each entry """ self._gui = load_uh_widget("configure_route.xml", center_widget=True) self.widgets = [] self.slots = {} icon = self._gui.findChild(name="minimap") self.minimap = Minimap( icon, session=self.session, world=self.session.world, view=self.session.view, targetrenderer=horizons.globals.fife.targetrenderer, imagemanager=horizons.globals.fife.imagemanager, cam_border=False, use_rotation=False, on_click=self.on_map_click) resources = self.session.db.get_res(only_tradeable=True) # map an icon for a resource # map a resource for an icon self.resource_for_icon = {self.dummy_icon_path: 0} self.icon_for_resource = {0: self.dummy_icon_path} for res_id in resources: icon = get_res_icon_path(res_id) self.resource_for_icon[icon] = res_id self.icon_for_resource[res_id] = icon # don't do any actions if the resource menu is shown self.resource_menu_shown = False for entry in self.instance.route.waypoints: self.add_gui_entry(entry['warehouse'], entry['resource_list']) self._check_no_entries_label() wait_at_unload_box = self._gui.findChild(name="wait_at_unload") wait_at_unload_box.marked = self.instance.route.wait_at_unload def toggle_wait_at_unload(): self._route_cmd("set_wait_at_unload", not self.instance.route.wait_at_unload) wait_at_unload_box.capture(toggle_wait_at_unload) wait_at_load_box = self._gui.findChild(name="wait_at_load") wait_at_load_box.marked = self.instance.route.wait_at_load def toggle_wait_at_load(): self._route_cmd("set_wait_at_load", not self.instance.route.wait_at_load) wait_at_load_box.capture(toggle_wait_at_load) self._gui.mapEvents({ OkButton.DEFAULT_NAME: self._windows.close, 'start_route/mouseClicked': self.toggle_route, })
def __init__(self): self._widget = load_uh_widget('loadingscreen.xml') self._widget.position_technique = "center:center" self._current_step = 0
def _get_gold_background_icon_position(self): # see above gui = load_uh_widget(self.__class__.GOLD_ENTRY_GUI_FILE) icon = gui.findChild(name="background_icon") return icon.position
def __init__(self, session): super(IngameGui, self).__init__() self.session = session assert isinstance(self.session, horizons.session.Session) self.settlement = None self._old_menu = None self.cursor = None self.coordinates_tooltip = None self.keylistener = IngameKeyListener(self.session) self.cityinfo = CityInfo(self) LastActivePlayerSettlementManager.create_instance(self.session) self.message_widget = MessageWidget(self.session) # Windows self.windows = WindowManager() self.open_popup = self.windows.open_popup self.open_error_popup = self.windows.open_error_popup self.logbook = LogBook(self.session, self.windows) self.players_overview = PlayersOverview(self.session) self.players_settlements = PlayersSettlements(self.session) self.players_ships = PlayersShips(self.session) self.chat_dialog = ChatDialog(self.windows, self.session) self.change_name_dialog = ChangeNameDialog(self.windows, self.session) self.pausemenu = PauseMenu(self.session, self, self.windows, in_editor_mode=False) self.help_dialog = HelpDialog(self.windows) # Icon manager self.status_icon_manager = StatusIconManager( renderer=self.session.view.renderer['GenericRenderer'], layer=self.session.view.layers[LAYERS.OBJECTS]) self.production_finished_icon_manager = ProductionFinishedIconManager( renderer=self.session.view.renderer['GenericRenderer'], layer=self.session.view.layers[LAYERS.OBJECTS]) # 'minimap' is the guichan gui around the actual minimap, which is saved # in self.minimap self.mainhud = load_uh_widget('minimap.xml') self.mainhud.position_technique = "right:top" icon = self.mainhud.findChild(name="minimap") self.minimap = Minimap( icon, targetrenderer=horizons.globals.fife.targetrenderer, imagemanager=horizons.globals.fife.imagemanager, session=self.session, view=self.session.view) def speed_up(): SpeedUpCommand().execute(self.session) def speed_down(): SpeedDownCommand().execute(self.session) self.mainhud.mapEvents({ 'zoomIn': self.session.view.zoom_in, 'zoomOut': self.session.view.zoom_out, 'rotateRight': Callback.ChainedCallbacks(self.session.view.rotate_right, self.minimap.rotate_right), 'rotateLeft': Callback.ChainedCallbacks(self.session.view.rotate_left, self.minimap.rotate_left), 'speedUp': speed_up, 'speedDown': speed_down, 'destroy_tool': self.toggle_destroy_tool, 'build': self.show_build_menu, 'diplomacyButton': self.show_diplomacy_menu, 'gameMenuButton': self.toggle_pause, 'logbook': lambda: self.windows.toggle(self.logbook) }) self.mainhud.show() hotkey_replacements = { 'rotateRight': 'ROTATE_RIGHT', 'rotateLeft': 'ROTATE_LEFT', 'speedUp': 'SPEED_UP', 'speedDown': 'SPEED_DOWN', 'destroy_tool': 'DESTROY_TOOL', 'build': 'BUILD_TOOL', 'gameMenuButton': 'ESCAPE', 'logbook': 'LOGBOOK', } for (widgetname, action) in hotkey_replacements.iteritems(): widget = self.mainhud.findChild(name=widgetname) keys = horizons.globals.fife.get_keys_for_action(action) # No `.upper()` here: "Pause" looks better than "PAUSE". keyname = HOTKEYS.DISPLAY_KEY.get(keys[0], keys[0].capitalize()) widget.helptext = widget.helptext.format(key=keyname) self.resource_overview = ResourceOverviewBar(self.session) # Register for messages SpeedChanged.subscribe(self._on_speed_changed) NewDisaster.subscribe(self._on_new_disaster) NewSettlement.subscribe(self._on_new_settlement) PlayerLevelUpgrade.subscribe(self._on_player_level_upgrade) MineEmpty.subscribe(self._on_mine_empty) ZoomChanged.subscribe(self._update_zoom) self._display_speed(self.session.timer.ticks_per_second)
def _load_widget(self, widget): widget = load_uh_widget(widget) widget.child_finder = PychanChildFinder(widget) return widget