def _delete_savegame(self, map_files): """Deletes the selected savegame if the user confirms self._gui has to contain the widget "savegamelist" @param map_files: list of files that corresponds to the entries of 'savegamelist' @return: True if something was deleted, else False """ selected_item = self._gui.collectData("savegamelist") if selected_item == -1 or selected_item >= len(map_files): self._windows.open_popup( T("No file selected"), T("You need to select a savegame to delete.")) return False selected_file = map_files[selected_item] message = T( "Do you really want to delete the savegame '{name}'?").format( name=SavegameManager.get_savegamename_from_filename( selected_file)) if self._windows.open_popup(T("Confirm deletion"), message, show_cancel_button=True): try: os.unlink(selected_file) return True except: self._windows.open_popup(T("Error!"), T("Failed to delete savefile!")) return False else: # player cancelled deletion return False
def _add_player_line(player): name = player['name'] pname = Label(name="pname_%s" % name) pname.helptext = T("Click here to change your name and/or color") pname.text = name pname.min_size = pname.max_size = (130, 15) if name == NetworkInterface().get_client_name(): pname.capture( Callback(self._show_change_player_details_popup, game)) pcolor = Label(name="pcolor_%s" % name, text=" ") pcolor.helptext = T("Click here to change your name and/or color") pcolor.background_color = player['color'] pcolor.min_size = pcolor.max_size = (15, 15) if name == NetworkInterface().get_client_name(): pcolor.capture( Callback(self._show_change_player_details_popup, game)) pstatus = Label(name="pstatus_%s" % name) pstatus.text = "\t\t\t" + player['status'] pstatus.min_size = pstatus.max_size = (120, 15) picon = HRule(name="picon_%s" % name) hbox = HBox() hbox.addChildren(pname, pcolor, pstatus) if NetworkInterface().get_client_name( ) == game.creator and name != game.creator: pkick = CancelButton(name="pkick_%s" % name) pkick.helptext = T("Kick {player}").format(player=name) pkick.capture(Callback(NetworkInterface().kick, player['sid'])) pkick.path = "images/buttons/delete_small" pkick.min_size = pkick.max_size = (20, 15) hbox.addChild(pkick) players_vbox.addChildren(hbox, picon)
def _on_Language_changed(self, widget): value = widget.items[widget.getData()] language_code = LANGUAGENAMES.get_by_value(value) status_label = self.widget.findChild(name='language_translation_status') if not language_code or language_code == 'en': status_label.text = '' else: value = get_language_translation_stats(language_code) if value: status_label.text = T('Translation {percentage}% completed').format(percentage=value) else: status_label.text = ''
def _update_scenario_translation_infos(self, scenario): """Fill in translation infos of selected scenario to translation label.""" try: metadata = ScenarioEventHandler.get_metadata_from_file(scenario) except InvalidScenarioFileFormat as e: self._show_invalid_scenario_file_popup(e) return translation_status = metadata.get('translation_status', '') lbl = self._gui.findChild(name="translation_status") lbl.text = translation_status lbl = self._gui.findChild(name="uni_map_difficulty") lbl.text = T("Difficulty: {difficulty}").format( difficulty=metadata['difficulty']) lbl = self._gui.findChild(name="uni_map_author") lbl.text = T("Author: {author}").format(author=metadata['author']) lbl = self._gui.findChild(name="uni_map_desc") lbl.text = T("Description: {desc}").format( desc=metadata['description'])
def save(self, savegamename=None): self.ingame_gui.open_popup(T("Not possible"), T("Save/load for multiplayer games is not possible yet")) return #TODO disabled for now, see #2151 for details if savegamename is None: def sanity_checker(string): try: SavegameManager.create_multiplayersave_filename(string) except RuntimeError: return False else: return True sanity_criteria = T( "The filename must consist only of letters, numbers, spaces " "and these characters: _ . -" ) savegamename = self.ingame_gui.show_select_savegame(mode='mp_save', sanity_checker=sanity_checker, sanity_criteria=sanity_criteria) if savegamename is None: return True # user aborted dialog SaveCommand(savegamename).execute(self) return True
def _redraw_captainslog(self): """Redraws gui. Necessary when current message has changed.""" if self._parameters: # there is something to display if this has items self._display_parameters_on_page(self._parameters[self._cur_entry], 'left') if self._cur_entry + 1 < len(self._parameters): # check for content on right page self._display_parameters_on_page(self._parameters[self._cur_entry + 1], 'right') else: self._display_parameters_on_page([], 'right') # display empty page else: self._display_parameters_on_page([ ['Headline', T("Emptiness")], ['Image', "content/gui/images/background/hr.png"], ['Label', "\n\n"], ['Label', T('There is nothing written in your logbook yet!')], ], 'left') self.backward_button.set_active() self.forward_button.set_active() if not self._parameters or self._cur_entry == 0: self.backward_button.set_inactive() if not self._parameters or self._cur_entry >= len(self._parameters) - 2: self.forward_button.set_inactive() self._gui.adaptLayout()
def prepare(self): if self._mode == 'load': self._map_files, self._map_file_display = SavegameManager.get_saves() if not self._map_files: self._windows.open_popup(T("No saved games"), T("There are no saved games to load.")) return False elif self._mode == 'save': self._map_files, self._map_file_display = SavegameManager.get_regular_saves() elif self._mode == 'editor-save': self._map_files, self._map_file_display = SavegameManager.get_maps() self._gui.distributeInitialData({'savegamelist': self._map_file_display}) if self._mode == 'load': self._gui.distributeData({'savegamelist': 0}) self._cb = self._create_show_savegame_details(self._gui, self._map_files, 'savegamelist') if self._mode in ('save', 'editor-save'): def selected_changed(): """Fills in the name of the savegame in the textbox when selected in the list""" if self._gui.collectData('savegamelist') == -1: # set blank if nothing is selected self._gui.findChild(name="savegamefile").text = "" else: savegamefile = self._map_file_display[self._gui.collectData('savegamelist')] self._gui.distributeData({'savegamefile': savegamefile}) self._cb = Callback.ChainedCallbacks(self._cb, selected_changed) self._cb() # Refresh data on start self._gui.mapEvents({'savegamelist/action': self._cb}) self._gui.findChild(name="savegamelist").capture(self._cb, event_name="keyPressed") self._gui.findChild(name="savegamelist").capture(self.check_double_click, event_name="mousePressed") self.return_events = { OkButton.DEFAULT_NAME : True, CancelButton.DEFAULT_NAME: False, DeleteButton.DEFAULT_NAME: 'delete' } if self._mode in ('save', 'editor-save'): self.return_events['savegamefile'] = True
def _refresh_found_settlement_button(self, events): island_without_player_settlement_found = False helptext = T( "The ship needs to be close to an island to found a settlement.") for island in self.instance.session.world.get_islands_in_radius( self.instance.position, self.instance.radius): if not any(settlement.owner.is_local_player for settlement in island.settlements): island_without_player_settlement_found = True else: helptext = T("You already have a settlement on this island.") if island_without_player_settlement_found: events['found_settlement'] = Callback( self.instance.session.ingame_gui._build, BUILDINGS.WAREHOUSE, weakref.ref(self.instance)) self.widget.child_finder('found_settlement_bg').set_active() self.widget.child_finder('found_settlement').set_active() self.widget.child_finder('found_settlement').helptext = T( "Build settlement") else: events['found_settlement'] = None self.widget.child_finder('found_settlement_bg').set_inactive() self.widget.child_finder('found_settlement').set_inactive() self.widget.child_finder('found_settlement').helptext = helptext cb = Callback( self.instance.session.ingame_gui.resource_overview. set_construction_mode, self.instance, Entities.buildings[BUILDINGS.WAREHOUSE].costs) events['found_settlement/mouseEntered'] = cb cb1 = Callback(self.instance.session.ingame_gui.resource_overview. close_construction_mode) cb2 = Callback( self.widget.child_finder('found_settlement').hide_tooltip) #TODO the tooltip should actually hide on its own. Ticket #1096 cb = Callback.ChainedCallbacks(cb1, cb2) events['found_settlement/mouseExited'] = cb
def load_gui(self): if self.__class__.gui is None: self.__class__.gui = load_uh_widget("place_building.xml") self.__class__.gui.position_technique = "right-1:top+157" self.__class__.gui.mapEvents({ "rotate_left": self.rotate_left, "rotate_right": self.rotate_right }) # set translated building name in gui self.__class__.gui.findChild( name='headline').text = T('Build {building}').format( building=T(self._class.name)) self.__class__.gui.findChild(name='running_costs').text = str( self._class.running_costs) head_box = self.__class__.gui.findChild(name='head_box') head_box.adaptLayout() # recalculates size of new content # calculate and set new center new_x = max(25, (self.__class__.gui.size[0] // 2) - (head_box.size[0] // 2)) head_box.position = (new_x, head_box.position[1]) head_box.adaptLayout() self.draw_gui()
def __init__(self, mode, windows): super().__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 = T('Save game') elif self._mode == 'load': helptext = T('Load game') elif self._mode == 'editor-save': helptext = T('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") w.parent.hideChild(w) w = self._gui.findChild(name="gamepassword_box") w.parent.hideChild(w) w = self._gui.findChild(name='enter_filename') if self._mode in ('save'): # only show enter_filename on save w.parent.showChild(w) else: w.parent.hideChild(w) w2 = self._gui.findChild(name='players_recommended') if self._mode in ( 'editor-save' ): # only show players_recommended and enter_filename on editor-save w.parent.showChild(w) w2.parent.showChild(w2) else: w.parent.hideChild(w) w2.parent.hideChild(w2) self.last_click_event = None
def _init_stats_gui(self): reference_icon = self.gold_gui.child_finder("balance_background") self.stats_gui = load_uh_widget(self.__class__.STATS_GUI_FILE) self.stats_gui.child_finder = PychanChildFinder(self.stats_gui) self.stats_gui.position = (reference_icon.x + self.gold_gui.x, reference_icon.y + self.gold_gui.y) self.stats_gui.mapEvents({ 'resbar_stats_container/mouseClicked/stats': self._toggle_stats, }) # This list must correspond to `figures` in _update_stats images = [ ("content/gui/images/resbar_stats/expense.png", T("Running costs")), ("content/gui/images/resbar_stats/income.png", T("Taxes")), ("content/gui/images/resbar_stats/buy.png", T("Buy expenses")), ("content/gui/images/resbar_stats/sell.png", T("Sell income")), ("content/gui/images/resbar_stats/scales_icon.png", T("Balance")), ] for num, (image, helptext) in enumerate(images): # Keep in sync with comment there until we can use that data: # ./content/gui/xml/ingame/hud/resource_overview_bar_stats.xml box = HBox(padding=0, min_size=(70, 0)) box.name = "resbar_stats_line_{}".format(num) box.helptext = helptext #TODO Fix icon size; looks like not 16x16 a surprising amount of times. box.addChild(Icon(image=image)) box.addChild(Spacer()) box.addChild(Label(name="resbar_stats_entry_{}".format(num))) #TODO This label is a workaround for some fife font bug, # probably http://github.com/fifengine/fifengine/issues/666. templabel = Label(name="resbar_stats_whatever_{}".format(num)) box.addChild(templabel) if num == len(images) - 1: # The balance line (last one) gets bold font. box.stylize('resource_bar') self.stats_gui.child_finder("entries_box").addChild(box)
def _poll_preview_process(self): """This will be called regularly to see if the process ended. If the process has not yet finished, schedule a new callback to this function. Otherwise use the data to update the minimap. """ if not self._preview_process: return self._preview_process.poll() if self._preview_process.returncode is None: # not finished ExtScheduler().add_new_object(self._poll_preview_process, self, 0.1) return elif self._preview_process.returncode != 0: self._preview_process = None self._set_map_preview_status( "An unknown error occurred while generating the map preview") return with open(self._preview_output, 'r') as f: data = f.read() # Sometimes the subprocess outputs more then the minimap data, e.g. debug # information. Since we just read from its stdout, parse out the data that # is relevant to us. data = re.findall(r'^DATA (\[\[.*\]\]) ENDDATA$', data, re.MULTILINE)[0] data = json.loads(data) os.unlink(self._preview_output) self._preview_process = None if self._map_preview: self._map_preview.end() self._map_preview = Minimap( self._gui.findChild(name='map_preview_minimap'), session=None, view=None, world=None, targetrenderer=horizons.globals.fife.targetrenderer, imagemanager=horizons.globals.fife.imagemanager, cam_border=False, use_rotation=False, tooltip=T("Click to generate a different random map"), on_click=self._on_preview_click, preview=True) self._map_preview.draw_data(data) self._set_map_preview_status("")
def get_unit_tooltip(self, unit_id): """Tries to identify unit properties to display as tooltip. #TODO Should be extended later to also include movement speed, etc.""" helptexts = [] # collects all information we will find unit = Entities.units[unit_id] try: comp = unit.get_component_template('StorageComponent') storage = comp['PositiveTotalNumSlotsStorage'] # Ship storage properties helptext = T('{slotnum} slots, {limit}t') helptext = helptext.format(slotnum=storage['slotnum'], limit=storage['limit']) helptexts.append(helptext) except KeyError: # Component not found, ignore this part pass try: comp = unit.get_component_template('HealthComponent') helptext = T('Health: {health}') helptext = helptext.format(health=comp['maxhealth']) helptexts.append(helptext) except KeyError: # Component not found, ignore this part pass return '\\n'.join(helptexts)
def connect(self): """Connect to master server. After this, you can use `send_packet` and `receive_packet` to communicate with the server. """ if self.is_connected: raise network.AlreadyConnected("We are already connected to a server") self.log.debug("[CONNECT] to server %s" % (self.server_address)) try: if self.server_address is None: # can only construct address now, as it resolves the target and requires internet connection self.server_address = enet.Address(*self.server_address_parameters) self.server_peer = self.host.connect(self.server_address, 1, SERVER_PROTOCOL) except (IOError, MemoryError): raise network.NetworkException(T("Unable to connect to server.") + u" " + T("Maybe invalid or irresolvable server address.")) event = self.host.service(SERVER_TIMEOUT) if event.type != enet.EVENT_TYPE_CONNECT: self._reset() raise network.UnableToConnect(T("Unable to connect to server."))
def _init_settings(self): """Init the settings with the stored values.""" languages = find_available_languages().keys() language_names = [LANGUAGENAMES[x] for x in sorted(languages)] fps = {0: LazyT("Disabled"), 30: 30, 45: 45, 60: 60, 90: 90, 120: 120} FIFE = SETTINGS.FIFE_MODULE UH = SETTINGS.UH_MODULE def get_resolutions(): return get_screen_resolutions(self._settings.get(FIFE, 'ScreenResolution')) self._options = [ # Graphics/Sound/Input Setting(FIFE, 'ScreenResolution', 'screen_resolution', get_resolutions, restart=True), Setting(FIFE, 'FullScreen', 'enable_fullscreen', restart=True), Setting(FIFE, 'FrameLimit', 'fps_rate', fps, restart=True, callback=self._on_FrameLimit_changed), Setting(UH, 'VolumeMusic', 'volume_music', callback=self._on_VolumeMusic_changed), Setting(UH, 'VolumeEffects', 'volume_effects', callback=self._on_VolumeEffects_changed), Setting(FIFE, 'PlaySounds', 'enable_sound', callback=self._on_PlaySounds_changed), Setting(UH, 'EdgeScrolling', 'edgescrolling'), Setting(UH, 'CursorCenteredZoom', 'cursor_centered_zoom'), Setting(UH, 'MiddleMousePan', 'middle_mouse_pan'), Setting(FIFE, 'MouseSensitivity', 'mousesensitivity', restart=True), # Game Setting(UH, 'AutosaveInterval', 'autosaveinterval'), Setting(UH, 'AutosaveMaxCount', 'autosavemaxcount'), Setting(UH, 'QuicksaveMaxCount', 'quicksavemaxcount'), Setting(UH, 'Language', 'uni_language', language_names, callback=self._on_Language_changed), Setting(UH, 'MinimapRotation', 'minimaprotation'), Setting(UH, 'UninterruptedBuilding', 'uninterrupted_building'), Setting(UH, 'AutoUnload', 'auto_unload'), Setting(UH, 'DebugLog', 'debug_log', callback=self._on_DebugLog_changed), Setting(UH, 'ShowResourceIcons', 'show_resource_icons'), Setting(UH, 'ScrollSpeed', 'scrollspeed'), Setting(UH, 'QuotesType', 'quotestype', QUOTES_SETTINGS), Setting(UH, 'NetworkPort', 'network_port', callback=self._on_NetworkPort_changed), ] self._fill_widgets() # key configuration self.hotkey_interface = HotkeyConfiguration() number = self.sections.index(('hotkeys_settings', T('Hotkeys'))) self.page_widgets[number].removeAllChildren() self.page_widgets[number].addChild(self.hotkey_interface.widget)
def _update_hint(self, slot_id): """Sets default hint for last updated slot""" slot_widget = self.slot_widgets[slot_id] limit = int(slot_widget.findChild(name="slider").value) action = slot_widget.action price = self.session.db.get_res_value(slot_widget.res) if action == "buy": hint = T( "Will buy {resource_name} for {price} gold/t whenever less than {limit}t are in stock." ) price *= TRADER.PRICE_MODIFIER_SELL elif action == "sell": hint = T( "Will sell {resource_name} for {price} gold/t whenever more than {limit}t are available." ) price *= TRADER.PRICE_MODIFIER_BUY hint = hint.format(limit=unicode(limit), resource_name=self.session.db.get_res_name( slot_widget.res), price=int(price)) # same price rounding as in tradepostcomponent self._set_hint(hint)
def _update_game_details(self): """Set map name and other misc data in a widget.""" try: index = self._gui.collectData('gamelist') game = self._games[index] except IndexError: return self._gui.findChild( name="game_map").text = T("Map: {map_name}").format( map_name=game.map_name) self._gui.findChild( name="game_name").text = T("Name: {game_name}").format( game_name=game.name) self._gui.findChild( name="game_creator").text = T("Creator: {game_creator}").format( game_creator=game.creator) self._gui.findChild(name="game_playersnum").text = T( "Players: {player_amount}/{player_limit}").format( player_amount=game.player_count, player_limit=game.player_limit) vbox_inner = self._gui.findChild(name="game_info") vbox_inner.adaptLayout()
def refresh(self): if (hasattr(self.instance, 'name') or self.instance.has_component(NamedComponent)) and self.widget.child_finder('name'): name_widget = self.widget.child_finder('name') # Named objects can't be translated. if self.instance.has_component(NamedComponent): name_widget.text = self.instance.get_component(NamedComponent).name else: name_widget.text = T(self.instance.name) if hasattr(self.instance, 'running_costs') and \ self.widget.child_finder('running_costs'): self.widget.child_finder('running_costs').text = \ str(self.instance.running_costs) self.widget.adaptLayout()
def init_widget(self): super(AccountTab, self).init_widget() self.widget.mapEvents({ 'show_production_overview/mouseClicked': self.show_production_overview, }) # FIXME having to access the WindowManager this way is pretty ugly self._windows = self.instance.session.ingame_gui.windows self.prod_overview = ProductionOverview(self._windows, self.settlement) self.widget.child_finder('headline').text = self.settlement.get_component(NamedComponent).name self.widget.child_finder('headline').helptext = T('Click to change the name of your settlement') path = 'icons/widgets/cityinfo/settlement_{}'.format(self.settlement.owner.color.name) self.widget.child_finder('show_production_overview').path = path
def prepare(self, **kwargs): super(VersionHint, self).prepare(**kwargs) dl_btn = Button(name="dl", text=T("Click to download")) dl_btn.position = ( 48, 138) # i've tried, this button cannot be placed in a sane way def do_dl(): webbrowser.open(self.info.link) dl_btn.text = T("A page has been opened in your browser.") self._gui.adaptLayout() dl_btn.capture(do_dl) self._gui.addChild(dl_btn)
def refresh(self): super().refresh() self._gui.findChild(name='headline').text = T("Settlements of {player}").format(player=self.session.world.player.name) sequence_number = 0 events = {} for settlement in sorted(self.session.world.settlements, key=lambda settlement: (settlement.get_component(NamedComponent).name, settlement.worldid)): if settlement.owner is self.session.world.player: sequence_number += 1 name_label, rename_icon = self._add_line_to_gui(settlement, sequence_number) events['{}/mouseClicked'.format(name_label.name)] = Callback(self._go_to_settlement, settlement) cb = Callback(self.session.ingame_gui.show_change_name_dialog, settlement) events['{}/mouseClicked'.format(rename_icon.name)] = cb self._gui.mapEvents(events) self._add_summary_line_to_gui() self._content_vbox.adaptLayout()
def get_metadata_from_file(cls, filename): """Returns metadata dictionary from a yaml scenario file. Dictionary contains "unknown" for all of these fields if not specified in the scenario file: - difficulty - author - description @throws InvalidScenarioFileFormat on yaml parse error """ fallback = T('unknown') metadata = cls._parse_yaml_file(filename).get('metadata', {}) for required_key in ('author', 'difficulty', 'description'): metadata.setdefault(required_key, fallback) return metadata
def __init__(self, path, text, res_id, helptext="", filled=0, marker=0, uncached=False, **kwargs): """Represents the image in the ingame gui, with a bar to show how full the inventory is for that resource. Derives from Container and also takes all arguments of Imagebutton in order to display the resource icon. This is meant to be used with the Inventory widget.""" super(ImageFillStatusButton, self).__init__(**kwargs) self.path = path self.text = text self.helptext = T(helptext) # res_id is used by the TradeTab for example to determine the resource this button represents self.res_id = res_id self.text_position = (9, 30) self.marker = marker # force no cache. needed when the same icon has to appear several times at the same time self.uncached = uncached # Since draw() needs all other stuff initialized, only set this in the end: self.filled = filled # <- black magic at work! this calls _draw()
def _add_summary_line_to_gui(self): people = 0 tax = 0 costs = 0 for settlement in self.session.world.settlements: if settlement.owner is self.session.world.player: people += settlement.inhabitants tax += settlement.cumulative_taxes costs += settlement.cumulative_running_costs sequence_number_label = widgets.Label(name='sequence_number_total') sequence_number_label.min_size = sequence_number_label.max_size = (15, 20) name = widgets.Label(name='name_total') name.text = T('Total') name.min_size = name.max_size = (200, 20) self._add_generic_line_to_gui(0, [sequence_number_label, name], people, tax, costs)
def _add_line_to_gui(self, settlement, sequence_number): sequence_number_label = widgets.Label(name='sequence_number_{:d}'.format(settlement.worldid)) sequence_number_label.text = str(sequence_number) sequence_number_label.min_size = sequence_number_label.max_size = (15, 20) name = widgets.Label(name='name_{:d}'.format(settlement.worldid)) name.text = settlement.get_component(NamedComponent).name name.min_size = name.max_size = (175, 20) from horizons.engine.pychan_util import RenameImageButton rename_icon = RenameImageButton(name='rename_{:d}'.format(settlement.worldid)) rename_icon.path = "images/background/rename_feather_20" rename_icon.helptext = T("Click to change the name of your settlement") rename_icon.max_size = (20, 20) # (width, height) self._add_generic_line_to_gui(settlement.worldid, [sequence_number_label, name, rename_icon], settlement.inhabitants, settlement.cumulative_taxes, settlement.cumulative_running_costs) return name, rename_icon
def build_ship_info(self, index, ship, prodline): size = (260, 90) widget = Container(name='showcase_%s' % index, position=(0, 20 + index*90), min_size=size, max_size=size, size=size) bg_icon = Icon(image='content/gui/images/background/square_80.png', name='bg_%s'%index) widget.addChild(bg_icon) image = 'content/gui/images/objects/ships/76/{unit_id}.png'.format(unit_id=ship) helptext = self.instance.session.db.get_unit_tooltip(ship) unit_icon = Icon(image=image, name='icon_%s'%index, position=(2, 2), helptext=helptext) widget.addChild(unit_icon) # if not buildable, this returns string with reason why to be displayed as helptext #ship_unbuildable = self.is_ship_unbuildable(ship) ship_unbuildable = False if not ship_unbuildable: button = OkButton(position=(60, 50), name='ok_%s'%index, helptext=T('Build this ship!')) button.capture(Callback(self.start_production, prodline)) else: button = CancelButton(position=(60, 50), name='ok_%s'%index, helptext=ship_unbuildable) widget.addChild(button) # Get production line info production = self.producer.create_production_line(prodline) # consumed == negative, reverse to sort in *ascending* order: costs = sorted(production.consumed_res.items(), key=itemgetter(1)) for i, (res, amount) in enumerate(costs): xoffset = 103 + (i % 2) * 55 yoffset = 20 + (i // 2) * 20 icon = create_resource_icon(res, self.instance.session.db) icon.max_size = icon.min_size = icon.size = (16, 16) icon.position = (xoffset, yoffset) label = Label(name='cost_%s_%s' % (index, i)) if res == RES.GOLD: label.text = str(-amount) else: label.text = '{amount:02}t'.format(amount=-amount) label.position = (22 + xoffset, yoffset) widget.addChild(icon) widget.addChild(label) return widget
def update_production_is_active_container(self, progress_container, container_active, cancel_container, production_lines): """Update the active production container.""" self.update_progress(progress_container) self.update_queue(container_active) self.update_buttons(container_active, cancel_container) needed_res_container = self.widget.findChild(name="UB_needed_resources_container") self.update_needed_resources(needed_res_container) # Set built unit info production_line = self.producer._get_production(production_lines[0]) produced_unit_id = list(production_line.get_produced_units().keys())[0] name = self.instance.session.db.get_unit_type_name(produced_unit_id) container_active.findChild(name="headline_UB_builtunit_label").text = T(name) self.update_unit_icon(container_active, produced_unit_id) upgrades_box = container_active.findChild(name="UB_upgrades_box") upgrades_box.removeAllChildren()
def append_warehouse(self, warehouse): """Add a warehouse to the list on the left side. @param warehouse: Set to add a specific one, else the selected one gets added. """ if not self.session.world.diplomacy.can_trade(self.session.world.player, warehouse.owner): self.session.ingame_gui.message_widget.add_custom(T("You are not allowed to trade with this player")) return if len(self.widgets) >= self.MAX_ENTRIES: # reached max entries the gui can hold AmbientSoundComponent.play_special('error') return self._route_cmd("append", warehouse.worldid) self.add_gui_entry(warehouse) if self.resource_menu_shown: self.hide_resource_menu() self._check_no_entries_label() self._gui.adaptLayout()
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 = T("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 __init__(self, point, id, created, msg_type=None, read=False, display=None, message=None, message_dict=None, icon_id=None): self.x, self.y = None, None if point is not None: self.x, self.y = point.x, point.y self.id = id self.msg_type = msg_type self.read = read self.created = created self.display = display if display is not None else horizons.globals.db.get_msg_visibility(id) icon = icon_id if icon_id is not None else horizons.globals.db.get_msg_icon_id(id) self.path = horizons.globals.db.get_msg_icon_path(icon) if message is not None: self.message = message else: msg = T(horizons.globals.db.get_msg_text(id)) #TODO why can message_dict not be used with custom messages (`if` branch above) try: self.message = msg.format(**message_dict if message_dict is not None else {}) except KeyError as err: self.message = msg self.log.warning(u'Unsubstituted string %s in %s message "%s", dict %s', err, msg, id, message_dict)