示例#1
0
def create_resource_selection_dialog(
    on_click, inventory, db, widget="select_trade_resource.xml", res_filter=None, amount_per_line=None
):
    """Returns a container containing resource icons.
	@param on_click: called with resource id as parameter on clicks
	@param inventory: to determine fill status of resource slots
	@param db: main db instance
	@param widget: which xml file to use as a template. Default: tabwidget. Required
	               since the resource bar also uses this code (no tabs there though).
	@param res_filter: callback to decide which icons to use. Default: show all
	@param amount_per_line: how many resource icons per line. Default: try to fit layout
	"""
    from horizons.gui.widgets.imagefillstatusbutton import ImageFillStatusButton

    dummy_icon_path = "content/gui/icons/resources/none_gray.png"

    dlg = load_uh_widget(widget)

    button_width = ImageFillStatusButton.CELL_SIZE[0]  # used for dummy button
    vbox = dlg.findChild(name="resources")
    amount_per_line = amount_per_line or vbox.width // button_width
    # Add the zero element to the beginning that allows to remove the currently
    # sold/bought resource:
    resources = [0] + db.get_res(only_tradeable=True)
    current_hbox = HBox(name="hbox_0", padding=0)
    index = 1
    for res_id in resources:
        # don't show resources that are already in the list
        if res_filter is not None and not res_filter(res_id):
            continue
            # create button (dummy one or real one)
        if res_id == 0 or inventory is None:
            button = ImageButton(size=(button_width, button_width), name="resource_icon_00")
            button.up_image, button.down_image, button.hover_image = (dummy_icon_path,) * 3
        else:
            amount = inventory[res_id]
            filled = int(float(inventory[res_id]) / float(inventory.get_limit(res_id)) * 100.0)
            button = ImageFillStatusButton.init_for_res(
                db, res_id, amount=amount, filled=filled, uncached=True, use_inactive_icon=False
            )
            # on click: add this res
        cb = Callback(on_click, res_id)
        if hasattr(button, "button"):  # for imagefillstatusbuttons
            button.button.capture(cb)
            button.button.name = "resource_%d" % res_id
        else:
            button.capture(cb)
            button.name = "resource_%d" % res_id

        current_hbox.addChild(button)
        if index % amount_per_line == 0:
            vbox.addChild(current_hbox)
            box_id = index // amount_per_line
            current_hbox = HBox(name="hbox_%s" % box_id, padding=0)
        index += 1
    vbox.addChild(current_hbox)
    vbox.adaptLayout()

    return dlg
示例#2
0
def create_resource_selection_dialog(on_click, inventory, db,
		widget='select_trade_resource.xml', res_filter=None, amount_per_line=None):
	"""Returns a container containing resource icons.
	@param on_click: called with resource id as parameter on clicks
	@param inventory: to determine fill status of resource slots
	@param db: main db instance
	@param widget: which xml file to use as a template. Default: tabwidget. Required
	               since the resource bar also uses this code (no tabs there though).
	@param res_filter: callback to decide which icons to use. Default: show all
	@param amount_per_line: how many resource icons per line. Default: try to fit layout
	"""
	from horizons.gui.widgets.imagefillstatusbutton import ImageFillStatusButton
	dummy_icon_path = "content/gui/icons/resources/none_gray.png"

	dlg = load_uh_widget(widget)

	button_width = ImageFillStatusButton.CELL_SIZE[0] # used for dummy button
	vbox = dlg.findChild(name="resources")
	amount_per_line = amount_per_line or vbox.width // button_width
	# Add the zero element to the beginning that allows to remove the currently
	# sold/bought resource:
	resources = [0] + db.get_res(only_tradeable=True)
	current_hbox = HBox(name="hbox_0", padding=0)
	index = 1
	for res_id in resources:
		# don't show resources that are already in the list
		if res_filter is not None and not res_filter(res_id):
			continue
		# create button (dummy one or real one)
		if res_id == 0 or inventory is None:
			button = ImageButton( size=(button_width, button_width), name="resource_icon_00")
			button.up_image, button.down_image, button.hover_image = (dummy_icon_path,)*3
		else:
			amount = inventory[res_id]
			filled = int(float(inventory[res_id]) / float(inventory.get_limit(res_id)) * 100.0)
			button = ImageFillStatusButton.init_for_res(db, res_id,
			                                            amount=amount, filled=filled, uncached=True,
			                                            use_inactive_icon=False)
		# on click: add this res
		cb = Callback(on_click, res_id)
		if hasattr(button, "button"): # for imagefillstatusbuttons
			button.button.capture( cb )
		else:
			button.capture( cb )

		current_hbox.addChild(button)
		if index % amount_per_line == 0:
			vbox.addChild(current_hbox)
			box_id = index // amount_per_line
			current_hbox = HBox(name="hbox_%s" % box_id, padding=0)
		index += 1
	vbox.addChild(current_hbox)
	vbox.adaptLayout()

	return dlg
示例#3
0
	def parse_logbook_item(self, parameter):
		# Some error checking for widgets that are to be loaded.
		# This happens, for example, with outdated YAML stored in old
		# scenario savegames. Instead of crashing, display nothing.
		def _icon(image):
			try:
				# Pychan can only use str objects as file path.
				# json.loads() however returns unicode.
				return Icon(image=str(image))
			except fife.NotFound:
				return None

		def _label(text, font='default'):
			try:
				return Label(text=str(text), wrap_text=True,
				             min_size=(325, 0), max_size=(325, 1024),
				             font=font)
			except InitializationError:
				return None

		if parameter and parameter[0]: # allow empty Labels
			parameter_type = parameter[0]
		if isinstance(parameter, str):
			add = _label(parameter)
		elif parameter_type == 'Label':
			add = _label(parameter[1])
		elif parameter_type == 'Image':
			add = _icon(parameter[1])
		elif parameter_type == 'Gallery':
			add = HBox()
			for image in parameter[1]:
				new_icon = _icon(image)
				if new_icon is not None:
					add.addChild(new_icon)
		elif parameter_type == 'Headline':
			add = HBox()
			is_not_last_headline = self._parameters and self._cur_entry is not None and self._cur_entry < (len(self._parameters) - 2)
			if is_not_last_headline:
				add.addChild(_icon("content/gui/images/tabwidget/done.png"))
			add.addChild(_label(parameter[1], font='headline'))
		elif parameter_type == 'BoldLabel':
			add = _label(parameter[1], font='default_bold')
		elif parameter_type == 'Message':
			add = None
			# parameters are re-read on page reload.
			# duplicate_message stops messages from
			# being duplicated on page reload.
			message = parameter[1]
			# message is already going to be displayed or has been displayed
			# before (e.g. re-opening older logbook pages)
			duplicate_message = (message in self._messages_to_display or
								message in self._message_log)

			if not duplicate_message:
				self._messages_to_display.append(message) # the new message has not been displayed
		else:
			self.log.warning('Unknown parameter type %s in parameter %s',
			                 parameter[0], parameter)
			add = None
		return add
	def parse_logbook_item(self, parameter):
		# Some error checking for widgets that are to be loaded.
		# This happens, for example, with outdated YAML stored in old
		# scenario savegames. Instead of crashing, display nothing.
		def _icon(image):
			try:
				# Pychan can only use str objects as file path.
				# json.loads() however returns unicode.
				return Icon(image=str(image))
			except fife.NotFound:
				return None

		def _label(text, font='default'):
			try:
				return Label(text=str(text), wrap_text=True,
				             min_size=(325, 0), max_size=(325, 1024),
				             font=font)
			except InitializationError:
				return None

		if parameter and parameter[0]: # allow empty Labels
			parameter_type = parameter[0]
		if isinstance(parameter, str):
			add = _label(parameter)
		elif parameter_type == 'Label':
			add = _label(parameter[1])
		elif parameter_type == 'Image':
			add = _icon(parameter[1])
		elif parameter_type == 'Gallery':
			add = HBox()
			for image in parameter[1]:
				new_icon = _icon(image)
				if new_icon is not None:
					add.addChild(new_icon)
		elif parameter_type == 'Headline':
			add = HBox()
			is_not_last_headline = self._parameters and self._cur_entry is not None and self._cur_entry < (len(self._parameters) - 2)
			if is_not_last_headline:
				add.addChild(_icon("content/gui/images/tabwidget/done.png"))
			add.addChild(_label(parameter[1], font='headline'))
		elif parameter_type == 'BoldLabel':
			add = _label(parameter[1], font='default_bold')
		elif parameter_type == 'Message':
			add = None
			# parameters are re-read on page reload.
			# duplicate_message stops messages from
			# being duplicated on page reload.
			message = parameter[1]
			# message is already going to be displayed or has been displayed
			# before (e.g. re-opening older logbook pages)
			duplicate_message = (message in self._messages_to_display or
								message in self._message_log)

			if not duplicate_message:
				self._messages_to_display.append(message) # the new message has not been displayed
		else:
			self.log.warning('Unknown parameter type %s in parameter %s',
			                 parameter[0], parameter)
			add = None
		return add
        def _add_player_line(player):
            name = player['name']
            pname = Label(name="pname_%s" % name)
            pname.helptext = _("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=u"   ")
            pcolor.helptext = _("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 = _("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 _add_player_line(player):
			name = player['name']
			pname = Label(name="pname_%s" % name)
			pname.helptext = _("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=u"   ")
			pcolor.helptext = _("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)
				#xgettext:python-format
				pkick.helptext = _("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 _add_player_line(player):
            pname = Label(name="pname_%s" % player['name'])
            pname.helptext = _("Click here to change your name and/or color")
            pname.text = player['name']
            if player['name'] == NetworkInterface().get_client_name():
                pname.capture(Callback(
                    self.__show_change_player_details_popup))
            pname.min_size = pname.max_size = (130, 15)

            pcolor = Label(name="pcolor_%s" % player['name'], text=u"   ")
            pcolor.helptext = _("Click here to change your name and/or color")
            pcolor.background_color = player['color']
            if player['name'] == NetworkInterface().get_client_name():
                pcolor.capture(
                    Callback(self.__show_change_player_details_popup))
            pcolor.min_size = pcolor.max_size = (15, 15)

            pstatus = Label(name="pstatus_%s" % player['name'])
            pstatus.text = "\t\t\t" + player['status']
            pstatus.min_size = pstatus.max_size = (120, 15)

            picon = Icon(name="picon_%s" % player['name'])
            picon.image = "content/gui/images/background/hr.png"

            hbox = HBox()
            hbox.addChild(pname)
            hbox.addChild(pcolor)
            hbox.addChild(pstatus)

            if NetworkInterface().get_client_name() == game.get_creator(
            ) and player['name'] != game.get_creator():
                pkick = CancelButton(name="pkick_%s" % player['name'])
                pkick.helptext = _("Kick {player}").format(
                    player=player['name'])
                pkick.capture(Callback(NetworkInterface().kick, player['sid']))
                pkick.up_image = "content/gui/images/buttons/delete_small.png"
                pkick.down_image = "content/gui/images/buttons/delete_small.png"
                pkick.hover_image = "content/gui/images/buttons/delete_small_h.png"
                pkick.min_size = pkick.max_size = (20, 15)
                hbox.addChild(pkick)

            players_vbox.addChild(hbox)
            players_vbox.addChild(picon)
		def _add_player_line(player):
			pname = Label(name="pname_%s" % player['name'])
			pname.helptext = _("Click here to change your name and/or color")
			pname.text = player['name']
			pname.min_size = pname.max_size = (130, 15)

			if player['name'] == NetworkInterface().get_client_name():
				pname.capture(Callback(self._show_change_player_details_popup, game))

			pcolor = Label(name="pcolor_%s" % player['name'], text=u"   ")
			pcolor.helptext = _("Click here to change your name and/or color")
			pcolor.background_color = player['color']
			pcolor.min_size = pcolor.max_size = (15, 15)

			if player['name'] == NetworkInterface().get_client_name():
				pcolor.capture(Callback(self._show_change_player_details_popup, game))

			pstatus = Label(name="pstatus_%s" % player['name'])
			pstatus.text = "\t\t\t" + player['status']
			pstatus.min_size = pstatus.max_size = (120, 15)

			picon = Icon(name="picon_%s" % player['name'])
			picon.image = "content/gui/images/background/hr.png"

			hbox = HBox()
			hbox.addChild(pname)
			hbox.addChild(pcolor)
			hbox.addChild(pstatus)

			if NetworkInterface().get_client_name() == game.creator and player['name'] != game.creator:
				pkick = CancelButton(name="pkick_%s" % player['name'])
				pkick.helptext = _("Kick {player}").format(player=player['name'])
				pkick.capture(Callback(NetworkInterface().kick, player['sid']))
				pkick.up_image = "content/gui/images/buttons/delete_small.png"
				pkick.down_image = "content/gui/images/buttons/delete_small.png"
				pkick.hover_image = "content/gui/images/buttons/delete_small_h.png"
				pkick.min_size = pkick.max_size = (20, 15)
				hbox.addChild(pkick)

			players_vbox.addChild(hbox)
			players_vbox.addChild(picon)
    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 _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)
示例#11
0
    def _show_stats(self):
        """Show data below gold icon when balance label is clicked"""
        if self.stats_gui is None:
            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
            })

            images = [  # these must correspond to the entries in _update_stats
                "content/gui/images/resbar_stats/expense.png",
                "content/gui/images/resbar_stats/income.png",
                "content/gui/images/resbar_stats/buy.png",
                "content/gui/images/resbar_stats/sell.png",
                "content/gui/images/resbar_stats/scales_icon.png",
            ]

            for num, image 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),
                           name="resbar_stats_line_%s" % num)
                box.addChild(Icon(image=image))
                box.addSpacer(Spacer())
                box.addChild(Label(name="resbar_stats_entry_%s" % num))
                # workaround for fife font bug, probably http://fife.trac.cloudforge.com/engine/ticket/666
                box.addChild(Label(text=u" "))

                if num < len(images) - 1:  # regular one
                    self.stats_gui.child_finder("entries_box").addChild(box)
                else:  # last one
                    self.stats_gui.child_finder("bottom_box").addChild(box)
                    self.stats_gui.child_finder("bottom_box").stylize(
                        'resource_bar')

        self._update_stats()
        self.stats_gui.show()

        ExtScheduler().add_new_object(self._update_stats,
                                      self,
                                      run_in=Player.STATS_UPDATE_INTERVAL,
                                      loops=-1)
	def _show_stats(self):
		"""Show data below gold icon when balance label is clicked"""
		if self.stats_gui is None:
			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
			  })

			images = [ # these must correspond to the entries in _update_stats
				"content/gui/images/resbar_stats/expense.png",
				"content/gui/images/resbar_stats/income.png",
				"content/gui/images/resbar_stats/buy.png",
				"content/gui/images/resbar_stats/sell.png",
				"content/gui/images/resbar_stats/scales_icon.png",
			  ]

			for num, image 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), name="resbar_stats_line_%s"%num)
				box.addChild(Icon(image=image))
				box.addSpacer(Spacer())
				box.addChild(Label(name="resbar_stats_entry_%s"%num))
				# workaround for fife font bug, probably http://fife.trac.cloudforge.com/engine/ticket/666
				box.addChild(Label(text=u" "))

				if num < len(images)-1: # regular one
					self.stats_gui.child_finder("entries_box").addChild(box)
				else: # last one
					self.stats_gui.child_finder("bottom_box").addChild(box)
					self.stats_gui.child_finder("bottom_box").stylize('resource_bar')

		self._update_stats()
		self.stats_gui.show()

		ExtScheduler().add_new_object(self._update_stats, self, run_in=Player.STATS_UPDATE_INTERVAL, loops=-1)
示例#13
0
    def _draw(self, vbox, current_hbox, index=0):
        """Draws the inventory."""
        # add res to res order in case there are new ones
        # (never remove old ones for consistent positioning)
        new_res = sorted(resid for resid in self._inventory.iterslots()
                         if resid not in self._res_order)

        if isinstance(self._inventory, PositiveTotalNumSlotsStorage):
            # limited number of slots. We have to switch unused slots with newly added ones on overflow

            while len(
                    self._res_order) + len(new_res) > self._inventory.slotnum:
                for i in xrange(self._inventory.slotnum):
                    if len(self._res_order) <= i or self._inventory[
                            self._res_order[i]]:
                        # search empty slot
                        continue
                    # insert new res here
                    self._res_order[i] = new_res.pop(0)
                    if not new_res:
                        break  # all done

        # add remaining slots for slotstorage or just add it without consideration for other storage kinds
        self._res_order += new_res

        for resid in self._res_order:
            amount = self._inventory[resid]
            if amount == 0:
                index += 1
                continue

            # check if this res should be displayed
            if not self.db.cached_query(
                    'SELECT shown_in_inventory FROM resource WHERE id = ?',
                    resid)[0][0]:
                continue

            if self.ordinal:
                lower, upper = self.ordinal.get(resid, (0, 100))
                filled = (100 * (amount - lower)) // (upper - lower)
                amount = ""  # do not display exact information for resource deposits
            elif isinstance(self._inventory, TotalStorage):
                filled = 0
            else:
                filled = (100 * amount) // self._inventory.get_limit(resid)

            button = ImageFillStatusButton.init_for_res(self.db,
                                                        resid,
                                                        amount,
                                                        filled=filled,
                                                        uncached=self.uncached)
            button.button.name = "inventory_entry_%s" % index  # required for gui tests
            current_hbox.addChild(button)

            if index % self.items_per_line == self.items_per_line - 1:
                vbox.addChild(current_hbox)
                current_hbox = HBox(padding=0)
            index += 1
        if index <= self.items_per_line:  # Hide/Remove second line
            icons = self.parent.findChildren(name='slot')
            if len(icons) > self.items_per_line:
                self.parent.removeChildren(icons[self.items_per_line - 1:])
        vbox.addChild(current_hbox)
        self.addChild(vbox)
        height = ImageFillStatusButton.CELL_SIZE[1] * len(
            self._res_order) // self.items_per_line
        self.min_size = (self.min_size[0], height)

        if isinstance(self._inventory, TotalStorage):
            # if it's full, the additional slots have to be marked as unusable (#1686)
            # check for any res, the res type doesn't matter here
            if not self._inventory.get_free_space_for(0):
                for i in xrange(index, self.items_per_line):
                    button = Icon(image=self.__class__.UNUSABLE_SLOT_IMAGE)
                    # set min & max_size to prevent pychan to expand this dynamic widget (icon)
                    button.min_size = button.max_size = ImageFillStatusButton.ICON_SIZE
                    current_hbox.addChild(button)

        if self.display_legend:
            limit = self._inventory.get_limit(None)
            if isinstance(self._inventory, TotalStorage):
                # Add total storage indicator
                sum_stored = self._inventory.get_sum_of_stored_resources()
                self.legend.text = _('{stored}/{limit}').format(
                    stored=sum_stored, limit=limit)
            elif isinstance(self._inventory, PositiveSizedSlotStorage):
                self.legend.text = _('Limit: {amount}t per slot').format(
                    amount=limit)
	def _draw(self, vbox, current_hbox, index=0):
		"""Draws the inventory."""
		# add res to res order in case there are new ones
		# (never remove old ones for consistent positioning)
		new_res = sorted( resid for resid in self._inventory.iterslots() if resid not in self._res_order )

		if isinstance(self._inventory, PositiveTotalNumSlotsStorage):
			# limited number of slots. We have to switch unused slots with newly added ones on overflow

			while len(self._res_order) + len(new_res) > self._inventory.slotnum:
				for i in xrange(self._inventory.slotnum):
					if len(self._res_order) <= i or self._inventory[self._res_order[i]]:
						# search empty slot
						continue
					# insert new res here
					self._res_order[i] = new_res.pop(0)
					if not new_res:
						break # all done

		# add remaining slots for slotstorage or just add it without consideration for other storage kinds
		self._res_order += new_res

		for resid in self._res_order:
			# check if this res should be displayed
			if not self.db.cached_query('SELECT shown_in_inventory FROM resource WHERE id = ?', resid)[0][0]:
				continue

			amount = self._inventory[resid]

			if self.ordinal:
				lower, upper = self.ordinal.get(resid, (0, 100))
				filled = (100 * (amount - lower)) // (upper - lower)
				amount = "" # do not display exact information for resource deposits
			elif isinstance(self._inventory, TotalStorage):
				filled = 0
			else:
				filled = (100 * amount) // self._inventory.get_limit(resid)

			button = ImageFillStatusButton.init_for_res(self.db, resid, amount,
			                                            filled=filled, uncached=self.uncached)
			button.button.name = "inventory_entry_%s" % index # required for gui tests
			current_hbox.addChild(button)

			if index % self.items_per_line == self.items_per_line - 1:
				vbox.addChild(current_hbox)
				current_hbox = HBox(padding=0)
			index += 1
		if index <= self.items_per_line: # Hide/Remove second line
			icons = self.parent.findChildren(name='slot')
			if len(icons) > self.items_per_line:
				self.parent.removeChildren(icons[self.items_per_line-1:])
		vbox.addChild(current_hbox)
		self.addChild(vbox)
		height = ImageFillStatusButton.CELL_SIZE[1] * len(self._res_order) // self.items_per_line
		self.min_size = (self.min_size[0], height)

		if isinstance(self._inventory, TotalStorage):
			# if it's full, the additional slots have to be marked as unusable (#1686)
			# check for any res, the res type doesn't matter here
			if not self._inventory.get_free_space_for(0):
				for i in xrange(index, self.items_per_line):
					button = Icon(image=self.__class__.UNUSABLE_SLOT_IMAGE)
					current_hbox.addChild(button)

		if self.display_legend:
			limit = self._inventory.get_limit(None)
			if isinstance(self._inventory, TotalStorage):
				# Add total storage indicator
				sum_stored = self._inventory.get_sum_of_stored_resources()
				self.legend.text = _('{stored}/{limit}').format(stored=sum_stored, limit=limit)
			elif isinstance(self._inventory, PositiveSizedSlotStorage):
				self.legend.text = _('Limit: {amount}t per slot').format(amount=limit)
示例#15
0
def create_resource_selection_dialog(on_click, inventory, db,
                                     widget='select_trade_resource.xml', res_filter=None, amount_per_line=None):
	"""Returns a container containing resource icons.
	@param on_click: called with resource id as parameter on clicks
	@param inventory: to determine fill status of resource slots
	@param db: main db instance
	@param widget: which xml file to use as a template. Default: tabwidget. Required
	               since the resource bar also uses this code (no tabs there though).
	@param res_filter: callback to decide which icons to use. Default: show all
	@param amount_per_line: how many resource icons per line. Default: try to fit layout
	"""
	from horizons.gui.widgets.imagefillstatusbutton import ImageFillStatusButton
	dummy_icon_path = "icons/resources/none_gray"

	dlg = load_uh_widget(widget)

	icon_size = ImageFillStatusButton.ICON_SIZE # used for dummy button
	cell_size = ImageFillStatusButton.CELL_SIZE
	button_width = cell_size[0]
	vbox = dlg.findChild(name="resources")
	amount_per_line = amount_per_line or vbox.width // button_width
	# Add the zero element to the beginning that allows to remove the currently
	# sold/bought resource:
	resources = [0] + db.get_res(only_tradeable=True)
	current_hbox = HBox(name="hbox_0", padding=0)
	index = 1
	for res_id in resources:
		# don't show resources that are already in the list
		if res_filter is not None and not res_filter(res_id):
			continue

		# on click: add this res
		cb = Callback(on_click, res_id)

		# create button (dummy one or real one)
		if res_id == 0 or inventory is None:
			reset_button = ImageButton(max_size=icon_size, name="resource_icon_00")
			reset_button.path = dummy_icon_path

			button = Container(size=cell_size)
			# add the "No Resource" image to the container, positioned in the top left
			button.addChild(reset_button)
			# capture a mouse click on the container. It's possible to click on the
			# image itself or into the empty area (below or to the right of the image)
			button.capture(cb, event_name="mouseClicked")
			button.name = "resource_{:d}".format(res_id)
		else:
			amount = inventory[res_id]
			filled = int(inventory[res_id] / inventory.get_limit(res_id) * 100)
			button = ImageFillStatusButton.init_for_res(db, res_id,
						                                amount=amount, filled=filled, uncached=True,
						                                use_inactive_icon=False, showprice=True)
			button.capture(cb, event_name="mouseClicked")
			button.name = "resource_{:d}".format(res_id)

		current_hbox.addChild(button)
		if index % amount_per_line == 0:
			vbox.addChild(current_hbox)
			box_id = index // amount_per_line
			current_hbox = HBox(name="hbox_{}".format(box_id), padding=0)
		index += 1
	vbox.addChild(current_hbox)
	vbox.adaptLayout()

	return dlg
示例#16
0
def create_resource_selection_dialog(
    on_click, inventory, db, widget="select_trade_resource.xml", res_filter=None, amount_per_line=None
):
    """Returns a container containing resource icons.
	@param on_click: called with resource id as parameter on clicks
	@param inventory: to determine fill status of resource slots
	@param db: main db instance
	@param widget: which xml file to use as a template. Default: tabwidget. Required
	               since the resource bar also uses this code (no tabs there though).
	@param res_filter: callback to decide which icons to use. Default: show all
	@param amount_per_line: how many resource icons per line. Default: try to fit layout
	"""
    from horizons.gui.widgets.imagefillstatusbutton import ImageFillStatusButton

    dummy_icon_path = "icons/resources/none_gray"

    dlg = load_uh_widget(widget)

    icon_size = ImageFillStatusButton.ICON_SIZE  # used for dummy button
    cell_size = ImageFillStatusButton.CELL_SIZE
    button_width = cell_size[0]
    vbox = dlg.findChild(name="resources")
    amount_per_line = amount_per_line or vbox.width // button_width
    # Add the zero element to the beginning that allows to remove the currently
    # sold/bought resource:
    resources = [0] + db.get_res(only_tradeable=True)
    current_hbox = HBox(name="hbox_0", padding=0)
    index = 1
    for res_id in resources:
        # don't show resources that are already in the list
        if res_filter is not None and not res_filter(res_id):
            continue

            # on click: add this res
        cb = Callback(on_click, res_id)

        # create button (dummy one or real one)
        if res_id == 0 or inventory is None:
            reset_button = ImageButton(max_size=icon_size, name="resource_icon_00")
            reset_button.path = dummy_icon_path

            button = Container(size=cell_size)
            # add the "No Resource" image to the container, positioned in the top left
            button.addChild(reset_button)
            # capture a mouse click on the container. It's possible to click on the
            # image itself or into the empty area (below or to the right of the image)
            button.capture(cb, event_name="mouseClicked")
            button.name = "resource_%d" % res_id
        else:
            amount = inventory[res_id]
            filled = int(float(inventory[res_id]) / float(inventory.get_limit(res_id)) * 100.0)
            button = ImageFillStatusButton.init_for_res(
                db, res_id, amount=amount, filled=filled, uncached=True, use_inactive_icon=False, showprice=True
            )
            button.button.capture(cb)
            button.button.name = "resource_%d" % res_id

        current_hbox.addChild(button)
        if index % amount_per_line == 0:
            vbox.addChild(current_hbox)
            box_id = index // amount_per_line
            current_hbox = HBox(name="hbox_%s" % box_id, padding=0)
        index += 1
    vbox.addChild(current_hbox)
    vbox.adaptLayout()

    return dlg
	def _add_line_to_gui(self, ship, sequence_number):
		sequence_number_label = Label(name='sequence_number_{:d}'.format(ship.worldid))
		sequence_number_label.text = str(sequence_number)
		sequence_number_label.min_size = sequence_number_label.max_size = (15, 20)

		ship_name = Label(name='ship_name_{:d}'.format(ship.worldid))
		ship_name.text = ship.get_component(NamedComponent).name
		ship_name.min_size = ship_name.max_size = (100, 20)

		from horizons.engine.pychan_util import RenameImageButton
		rename_icon = RenameImageButton(name='rename_{:d}'.format(ship.worldid))
		rename_icon.path = "images/background/rename_feather_20"
		rename_icon.helptext = T("Click to change the name of this ship")
		rename_icon.max_size = (20, 20) # (width, height)

		ship_type = Label(name='ship_type_{:d}'.format(ship.worldid))
		ship_type.text = ship.classname
		ship_type.min_size = ship_type.max_size = (60, 20)

		weapons = Label(name='weapons_{:d}'.format(ship.worldid))
		if isinstance(ship, FightingShip):
			weapon_list = []
			for weapon_id, amount in sorted(ship.get_weapon_storage().itercontents()):
				weapon_list.append('{:d} {}'.format(amount, self.session.db.get_res_name(weapon_id)))
			if weapon_list:
				weapons.text = ', '.join(weapon_list)
			else:
				#i18n There are no weapons equipped at the moment.
				weapons.text = T('None')
		else:
			weapons.text = T('N/A')
		weapons.min_size = weapons.max_size = (60, 20)

		health = Label(name='health_{:d}'.format(ship.worldid))
		health_component = ship.get_component(HealthComponent)
		health.text = '{:.1f}/{:.1f}'.format(health_component.health, health_component.max_health)
		health.min_size = health.max_size = (65, 20)

		status = Label(name='status_{:d}'.format(ship.worldid))
		status.text, status_position = ship.get_status()
		status.min_size = status.max_size = (320, 20)

		hbox = HBox()
		hbox.addChild(sequence_number_label)
		hbox.addChild(ship_name)
		hbox.addChild(rename_icon)
		hbox.addChild(ship_type)
		hbox.addChild(weapons)
		hbox.addChild(health)
		hbox.addChild(status)
		self._content_vbox.addChild(hbox)
		return (ship_name, rename_icon, status, status_position)
示例#18
0
    def _add_line_to_gui(self, ship, sequence_number):
        sequence_number_label = Label(name='sequence_number_%d' % ship.worldid)
        sequence_number_label.text = unicode(sequence_number)
        sequence_number_label.min_size = sequence_number_label.max_size = (15,
                                                                           20)

        ship_name = Label(name='ship_name_%d' % ship.worldid)
        ship_name.text = ship.get_component(NamedComponent).name
        ship_name.min_size = ship_name.max_size = (100, 20)

        from horizons.engine.pychan_util import RenameImageButton
        rename_icon = RenameImageButton(name='rename_%d' % ship.worldid)
        rename_icon.path = "images/background/rename_feather_20"
        rename_icon.helptext = T("Click to change the name of this ship")
        rename_icon.max_size = (20, 20)  # (width, height)

        ship_type = Label(name='ship_type_%d' % ship.worldid)
        ship_type.text = ship.classname
        ship_type.min_size = ship_type.max_size = (60, 20)

        weapons = Label(name='weapons_%d' % ship.worldid)
        if isinstance(ship, FightingShip):
            weapon_list = []
            for weapon_id, amount in sorted(
                    ship.get_weapon_storage().itercontents()):
                weapon_list.append(
                    '%d %s' %
                    (amount, self.session.db.get_res_name(weapon_id)))
            if weapon_list:
                weapons.text = u', '.join(weapon_list)
            else:
                #i18n There are no weapons equipped at the moment.
                weapons.text = T('None')
        else:
            weapons.text = T('N/A')
        weapons.min_size = weapons.max_size = (60, 20)

        health = Label(name='health_%d' % ship.worldid)
        health_component = ship.get_component(HealthComponent)
        health.text = u'%d/%d' % (health_component.health,
                                  health_component.max_health)
        health.min_size = health.max_size = (65, 20)

        status = Label(name='status_%d' % ship.worldid)
        status.text, status_position = ship.get_status()
        status.min_size = status.max_size = (320, 20)

        hbox = HBox()
        hbox.addChild(sequence_number_label)
        hbox.addChild(ship_name)
        hbox.addChild(rename_icon)
        hbox.addChild(ship_type)
        hbox.addChild(weapons)
        hbox.addChild(health)
        hbox.addChild(status)
        self._content_vbox.addChild(hbox)
        return (ship_name, rename_icon, status, status_position)