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)
示例#3
0
	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'])
示例#5
0
	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
示例#6
0
	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
示例#8
0
    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
示例#9
0
 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()
示例#10
0
    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("")
示例#13
0
    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)
示例#14
0
	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."))
示例#15
0
	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)
示例#16
0
    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)
示例#17
0
    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()
示例#18
0
	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
示例#20
0
    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)
示例#21
0
	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()
示例#22
0
    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()
示例#24
0
	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)
示例#25
0
	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
示例#26
0
	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
示例#27
0
	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()
示例#28
0
	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)
示例#30
0
	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)