def __init__(self, color_palette=None):
		"""
		@param widgets: WidgetsDict
		"""
		self.gui = load_uh_widget('playerdataselection.xml')

		self.colors = self.gui.findChild(name='playercolor')
		self.selected_color = horizons.globals.fife.get_uh_setting("ColorID") # starts at 1!
		self.set_color(self.selected_color)

		colorlabels = []
		events = {}

		# need the id to save it as int in settings file.
		for color in (Color if color_palette is None else color_palette):
			label = Label(name = u'{color}'.format(color=color.name),
			              text = u"    ",
			              max_size = (20,20),
			              min_size = (20,20),
			              background_color = color)
			events['{label}/mouseClicked'.format(label=color.name)] = \
			                             Callback(self.set_color, color.id)
			colorlabels.append(label)

		# split into three rows with at max 5 entries in each row
		# right now there are 14 different colors to choose from.
		for i in xrange(0, len(colorlabels), 5):
			hbox = HBox(name='line_{index}'.format(index=i))
			hbox.addChildren(colorlabels[i:i+5])
			self.colors.addChild(hbox)

		self.gui.distributeData({
			'playername': unicode(horizons.globals.fife.get_uh_setting("Nickname")),
		})
		self.gui.mapEvents(events)
Beispiel #2
0
	def __init__(self, **kwargs):
		HBox.__init__(self, name='city_info_background', padding=0)
		TilingBackground.__init__(self,
			amount=0,
			base_path="content/gui/images/background/widgets/cityinfo_",
			start_img="left.png", tiles_img="fill.png", final_img="right.png",
			**kwargs)
Beispiel #3
0
	def __init__(self, **kwargs):
		HBox.__init__(self, name='city_info_background', padding=0)
		TilingBackground.__init__(self,
			amount=0,
			base_path="content/gui/images/background/widgets/cityinfo_",
			start_img="left.png", tiles_img="fill.png", final_img="right.png",
			**kwargs)
Beispiel #4
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
Beispiel #5
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
Beispiel #6
0
	def show_tooltip(self):
		if not self.helptext:
			return
		if self.gui is None:
			self.__init_gui()

		#HACK: support icons in build menu
		# Code below exists for the sole purpose of build menu tooltips showing
		# resource icons. Even supporting that is a pain (as you will see),
		# so if you think you need icons in other tooltips, maybe reconsider.
		# [These unicode() calls brought to you by status icon tooltip code.]
		buildmenu_icons = self.icon_regexp.findall(unicode(self.helptext))
		# Remove the weird stuff before displaying text.
		replaced = self.icon_regexp.sub('', unicode(self.helptext))
		# Specification looks like [[Buildmenu 1:250 4:2 6:2]]
		if buildmenu_icons:
			hbox = HBox(position=(7, 5), padding=0)
			for spec in buildmenu_icons[0].split():
				(res_id, amount) = spec.split(':')
				label = Label(text=amount+'  ')
				icon = Icon(image=get_res_icon_path(int(res_id)), size=(16, 16),
				            scale=True)
				# For compatibility with FIFE 0.3.5 and older, also set min/max.
				icon.max_size = icon.min_size = (16, 16)
				hbox.addChildren(icon, label)
			hbox.adaptLayout()
			# Now display the 16x16px "required resources" icons in the last line.
			self.gui.addChild(hbox)

		#HACK: wrap tooltip text
		# This looks better than splitting into several lines and joining them.
		# It works because replace_whitespace in `fill` defaults to True.
		replaced = replaced.replace(r'\n', self.CHARS_PER_LINE * ' ')
		replaced = replaced.replace('[br]', self.CHARS_PER_LINE * ' ')
		tooltip = textwrap.fill(replaced, self.CHARS_PER_LINE)

		# Finish up the actual tooltip (text, background panel amount, layout).
		# To display build menu icons, we need another empty (first) line.
		self.bg.amount = len(tooltip.splitlines()) - 1 + bool(buildmenu_icons)
		self.label.text = bool(buildmenu_icons) * '\n' + tooltip
		self.gui.adaptLayout()
		self.gui.show()

		# NOTE: the below code in this method is a hack to resolve #2227
		# cannot find a better way to fix it, cause in fife.pychan, it seems
		# if a widget gets hidden or removed, the children of that widget are not
		# hidden or removed properly (at least in Python code)

		# update topmost_widget every time the tooltip is shown
		# this is to dismiss the tooltip later, see _check_hover_alive
		target_widget = self
		while target_widget:
			self.topmost_widget = target_widget
			target_widget = target_widget.parent

		# add an event to constantly check whether the hovered widget is still there
		# if this is no longer there, dismiss the tooltip widget
		ExtScheduler().add_new_object(self._check_hover_alive, self, run_in=0.5, loops=-1)
Beispiel #7
0
 def createStatisticList(self, statistics):
     statistics_list = self.gui.findChild(name='statisticsList')
     # Start with an empty list.
     statistics_list.removeAllChildren()
     for statistic in statistics:
         name = statistic.long_name
         hbox = HBox()
         hbox.opaque = 0
         label = Label(text=name)
         spinner = IntSpinner(lower_limit=0, upper_limit=100)
         hbox.addChildren(label, spinner)
         statistics_list.addChildren(hbox)
	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
Beispiel #9
0
	def update_needed_resources(self, needed_res_container):
		""" Update needed resources """
		production = self.producer.get_productions()[0]
		needed_res = production.get_consumed_resources()
		# Now sort! -amount is the positive value, drop unnecessary res (amount 0)
		needed_res = dict((res, -amount) for res, amount in needed_res.items() if amount < 0)
		needed_res = sorted(needed_res.items(), key=itemgetter(1), reverse=True)
		needed_res_container.removeAllChildren()
		for i, (res, amount) in enumerate(needed_res):
			icon = create_resource_icon(res, self.instance.session.db)
			icon.max_size = icon.min_size = icon.size = (16, 16)
			label = Label(name="needed_res_lbl_%s" % i)
			label.text = '{amount}t'.format(amount=amount)
			new_hbox = HBox(name="needed_res_box_%s" % i)
			new_hbox.addChildren(icon, label)
			needed_res_container.addChild(new_hbox)
 def update_needed_resources(self, needed_res_container):
     """ Update needed resources """
     production = self.producer.get_productions()[0]
     needed_res = production.get_consumed_resources()
     # Now sort! -amount is the positive value, drop unnecessary res (amount 0)
     needed_res = dict((res, -amount) for res, amount in needed_res.iteritems() if amount < 0)
     needed_res = sorted(needed_res.iteritems(), key=itemgetter(1), reverse=True)
     needed_res_container.removeAllChildren()
     for i, (res, amount) in enumerate(needed_res):
         icon = create_resource_icon(res, self.instance.session.db)
         icon.max_size = icon.min_size = icon.size = (16, 16)
         label = Label(name="needed_res_lbl_%s" % i)
         label.text = u"{amount}t".format(amount=amount)
         new_hbox = HBox(name="needed_res_box_%s" % i)
         new_hbox.addChildren(icon, label)
         needed_res_container.addChild(new_hbox)
Beispiel #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)
Beispiel #12
0
 def __init__(
     self,
     items=None,
     default_item_n=0,
     circular=True,
     min_size=(50, 14),
     max_size=(50, 14),
     font=None,
     background_color=None,
     **kwargs
 ):
     self._current_index = 0
     self._items = map(unicode, items) if items is not None else []
     self._default_item_n = default_item_n
     self._min_size = min_size
     self.circular = circular
     padding = 1
     self.text_field = TextField(background_color=background_color)
     self.decrease_button = ImageButton(
         up_image="gui/buttons/left_arrow_up.png",
         down_image="gui/buttons/left_arrow_down.png",
         hover_image="gui/buttons/left_arrow_hover.png",
     )
     # FIXME Technomage 2011-03-05: This is a hack to prevent the button
     #     from expanding width-wise and skewing the TextField orientation.
     #     Max size shouldn't be hard-coded like this though...
     self.decrease_button.max_size = (12, 12)
     self.decrease_button.capture(self.previousItem)
     self.increase_button = ImageButton(
         up_image="gui/buttons/right_arrow_up.png",
         down_image="gui/buttons/right_arrow_down.png",
         hover_image="gui/buttons/right_arrow_hover.png",
     )
     self.increase_button.capture(self.nextItem)
     increase_button_width, increase_button_height = self.increase_button.size
     decrease_button_width, decrease_button_height = self.decrease_button.size
     self.text_field = TextField(font=font)
     text_field_width = min_size[0] - (2 * padding) - (increase_button_width + decrease_button_width)
     self.text_field.min_width = text_field_width
     self.text_field.max_width = text_field_width
     self.text_field.min_height = min_size[1]
     self.text_field.text = self.items[default_item_n] if len(self.items) > 0 else u""
     HBox.__init__(self, **kwargs)
     self.opaque = 0
     self.padding = padding
     self.margins = (0, 0)
     self.addChildren(self.decrease_button, self.text_field, self.increase_button)
Beispiel #13
0
	def show_tooltip(self):
		if self.shown is True:
			return
		self.shown = True

		if not self.helptext:
			return
		if self.gui is None:
			self.__init_gui()

		#HACK: support icons in build menu
		# Code below exists for the sole purpose of build menu tooltips showing
		# resource icons. Even supporting that is a pain (as you will see),
		# so if you think you need icons in other tooltips, maybe reconsider.
		# [These unicode() calls brought to you by status icon tooltip code.]
		buildmenu_icons = self.icon_regexp.findall(unicode(self.helptext))
		# Remove the weird stuff before displaying text.
		replaced = self.icon_regexp.sub('', unicode(self.helptext))
		# Specification looks like [[Buildmenu 1:250 4:2 6:2]]
		if buildmenu_icons:
			hbox = HBox(position=(7, 5), padding=0)
			for spec in buildmenu_icons[0].split():
				(res_id, amount) = spec.split(':')
				label = Label(text=amount+'  ')
				icon = Icon(image=get_res_icon_path(int(res_id)), size=(16, 16))
				# For compatibility with FIFE 0.3.5 and older, also set min/max.
				icon.max_size = icon.min_size = (16, 16)
				hbox.addChildren(icon, label)
			hbox.adaptLayout()
			# Now display the 16x16px "required resources" icons in the last line.
			self.gui.addChild(hbox)

		#HACK: wrap tooltip text
		# This looks better than splitting into several lines and joining them.
		# It works because replace_whitespace in `fill` defaults to True.
		replaced = replaced.replace(r'\n', self.CHARS_PER_LINE * ' ')
		replaced = replaced.replace('[br]', self.CHARS_PER_LINE * ' ')
		tooltip = textwrap.fill(replaced, self.CHARS_PER_LINE)

		# Finish up the actual tooltip (text, background panel amount, layout).
		# To display build menu icons, we need another empty (first) line.
		self.bg.amount = len(tooltip.splitlines()) - 1 + bool(buildmenu_icons)
		self.label.text = bool(buildmenu_icons) * '\n' + tooltip
		self.gui.adaptLayout()
		self.gui.show()
Beispiel #14
0
	def parse_logbook_item(self, parameter):
		# json.loads() returns unicode, thus convert strings and compare to unicode
		# Image works with str() since pychan can only use str objects as file path
		if parameter and parameter[0]: # allow empty Labels
			parameter_type = parameter[0]
		if isinstance(parameter, basestring):
			add = Label(text=unicode(parameter), wrap_text=True, min_size=(335, 0), max_size=(335, 508))
		elif parameter_type == u'Label':
			add = Label(text=unicode(parameter[1]), wrap_text=True, min_size=(335, 0), max_size=(335, 508))
		elif parameter_type == u'Image':
			add = Icon(image=str(parameter[1]))
		elif parameter_type == u'Gallery':
			add = HBox()
			for image in parameter[1]:
				add.addChild(Icon(image=str(image)))
		elif parameter_type == u'Headline':
			add = HBox()
			is_not_last_headline = self._parameters and self._cur_entry < (len(self._parameters) - 2)
			if is_not_last_headline:
				add.addChild(Icon(image="content/gui/images/tabwidget/done.png"))

			add.addChild(Label(text=unicode(parameter[1]), wrap_text=True,
			            min_size=(335, 0), max_size=(335, 508), font='headline'))
		elif parameter_type == u'BoldLabel':
			add = Label(text=unicode(parameter[1]), wrap_text=True,
			            min_size=(335, 0), max_size=(335, 508), font='14_bold')
		elif parameter_type == u'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:
			print '[WW] Warning: Unknown parameter type {typ} in parameter {prm}'.format(
				typ=parameter[0], prm=parameter)
			add = None
		return add
        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 __init__(self, color_palette=None):
        """
		@param widgets: WidgetsDict
		"""
        self.gui = load_uh_widget("playerdataselection.xml")

        self.colors = self.gui.findChild(name="playercolor")
        self.selected_color = horizons.globals.fife.get_uh_setting("ColorID")  # starts at 1!
        self.set_color(self.selected_color)

        colorlabels = []
        events = {}

        # need the id to save it as int in settings file.
        for color in Color if color_palette is None else color_palette:
            label = Label(
                name=u"{color}".format(color=color.name),
                text=u"    ",
                max_size=(20, 20),
                min_size=(20, 20),
                background_color=color,
            )
            events["{label}/mouseClicked".format(label=color.name)] = Callback(self.set_color, color.id)
            colorlabels.append(label)

            # split into three rows with at max 5 entries in each row
            # right now there are 14 different colors to choose from.
        for i in xrange(0, len(colorlabels), 5):
            hbox = HBox(name="line_{index}".format(index=i))
            hbox.addChildren(colorlabels[i : i + 5])
            self.colors.addChild(hbox)

        playertextfield = self.gui.findChild(name="playername")

        def playertextfield_clicked():
            if playertextfield.text == "Unnamed Traveler":
                playertextfield.text = ""

        playertextfield.capture(playertextfield_clicked, event_name="mouseClicked")

        self.gui.distributeData({"playername": unicode(horizons.globals.fife.get_uh_setting("Nickname"))})
        self.gui.mapEvents(events)
    def __init__(self, color_palette=None):
        """
		@param widgets: WidgetsDict
		"""
        self.gui = load_uh_widget('playerdataselection.xml')

        self.colors = self.gui.findChild(name='playercolor')

        colorlabels = []
        events = {}

        # need the id to save it as int in settings file.
        for color in (Color.get_defaults()
                      if color_palette is None else color_palette):
            label = Label(name='{color}'.format(color=color.name),
                          text="    ",
                          max_size=(20, 20),
                          min_size=(20, 20),
                          background_color=color)
            events['{label}/mouseClicked'.format(label=color.name)] = \
                                         Callback(self.set_color, color.id)
            colorlabels.append(label)

        # split into three rows with at max 5 entries in each row
        # right now there are 14 different colors to choose from.
        for i in range(0, len(colorlabels), 5):
            hbox = HBox(name='line_{index}'.format(index=i))
            hbox.addChildren(colorlabels[i:i + 5])
            self.colors.addChild(hbox)

        playertextfield = self.gui.findChild(name='playername')

        def playertextfield_clicked():
            if playertextfield.text == 'Unnamed Traveler':
                playertextfield.text = ""

        playertextfield.capture(playertextfield_clicked,
                                event_name='mouseClicked')

        self.gui.mapEvents(events)
        self.update_data()
Beispiel #18
0
    def update(self):
        self.removeAllChildren()
        if self.display_legend:
            self.addChildren(self.__icon, self.legend)
        vbox = VBox(padding=0)
        vbox.width = self.width
        current_hbox = HBox(padding=0)

        # draw the content
        self._draw(vbox, current_hbox)

        self.adaptLayout()
Beispiel #19
0
 def __init__(self, min_size=(0, 0), max_size=(9999, 9999), border_size=1,
              **kwargs):
     self._min_size = min_size
     self._max_size = max_size
     self.views = {}
     tab_bar = HBox(name='tabBar')
     tab_bar.min_size = (0, 20)
     tab_bar.max_size = (9999, 20)
     self.view = ScrollArea(name='view')
     self.view.min_size = self._min_size
     self.view.max_size = self._max_size
     self.view.border_size = border_size
     frame = VBox(name='frame')
     frame.border_size = border_size
     frame.opaque = 0
     frame.addChild(self.view)
     VBox.__init__(self, **kwargs)
     self.padding = 0
     VBox.addChild(self, tab_bar)
     VBox.addChild(self, frame)
     self.adaptLayout()
	def __init__(self, parent_gui, widgets):
		"""
		Adds the playerdataselection container to a parent gui
		@param parent_gui: a pychan gui object containing a container named "playerdataselectioncontainer"
		@param widgets: WidgetsDict
		"""
		widgets.reload( 'playerdataselection' )
		self.gui = widgets[ 'playerdataselection' ]

		self.colors = self.gui.findChild(name = 'playercolor')
		self.selected_color = horizons.main.fife.get_uh_setting("ColorID") # starts at 1!
		self._set_color(self.selected_color)

		colorlabels = []
		events = {}

		# need the id to save it as int in settings file.
		for color_id, color in enumerate(Color):
			label = Label(name = u'{color}'.format(color=color.name),
			              text = u"    ",
			              max_size = (20,20),
			              min_size = (20,20),
			              background_color = color)
			events['{label}/mouseClicked'.format(label=color.name)] = \
			                             Callback(self._set_color, color_id+1)
			colorlabels.append(label)

		# split into three rows with at max 5 entries in each row
		# right now there are 14 different colors to choose from.
		for i in xrange(0, len(colorlabels), 5):
			hbox = HBox(name='line_{index}'.format(index=i))
			hbox.addChildren(colorlabels[i:i+5])
			self.colors.addChild(hbox)

		self.gui.distributeData({
			'playername': unicode(horizons.main.fife.get_uh_setting("Nickname")),
		})
		parent_gui.findChild(name="playerdataselectioncontainer").addChild( self.gui )
		parent_gui.mapEvents(events)
Beispiel #21
0
	def __init__(self, parent_gui, widgets, color_palette=None):
		"""
		Adds the playerdataselection container to a parent gui
		@param parent_gui: a pychan gui object containing a container named "playerdataselectioncontainer"
		@param widgets: WidgetsDict
		"""
		widgets.reload( 'playerdataselection' )
		self.gui = widgets[ 'playerdataselection' ]

		self.colors = self.gui.findChild(name='playercolor')
		self.selected_color = horizons.globals.fife.get_uh_setting("ColorID") # starts at 1!
		self.set_color(self.selected_color)

		colorlabels = []
		events = {}

		# need the id to save it as int in settings file.
		for color in (Color if color_palette is None else color_palette):
			label = Label(name = u'{color}'.format(color=color.name),
			              text = u"    ",
			              max_size = (20,20),
			              min_size = (20,20),
			              background_color = color)
			events['{label}/mouseClicked'.format(label=color.name)] = \
			                             Callback(self.set_color, color.id)
			colorlabels.append(label)

		# split into three rows with at max 5 entries in each row
		# right now there are 14 different colors to choose from.
		for i in xrange(0, len(colorlabels), 5):
			hbox = HBox(name='line_{index}'.format(index=i))
			hbox.addChildren(colorlabels[i:i+5])
			self.colors.addChild(hbox)

		self.gui.distributeData({
			'playername': unicode(horizons.globals.fife.get_uh_setting("Nickname")),
		})
		parent_gui.findChild(name="playerdataselectioncontainer").addChild( self.gui )
		parent_gui.mapEvents(events)
		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 __init__(self, color_palette=None):
		"""
		@param widgets: WidgetsDict
		"""
		self.gui = load_uh_widget('playerdataselection.xml')

		self.colors = self.gui.findChild(name='playercolor')

		colorlabels = []
		events = {}

		# need the id to save it as int in settings file.
		for color in (Color if color_palette is None else color_palette):
			label = Label(name = u'{color}'.format(color=color.name),
			              text = u"    ",
			              max_size = (20, 20),
			              min_size = (20, 20),
			              background_color = color)
			events['{label}/mouseClicked'.format(label=color.name)] = \
			                             Callback(self.set_color, color.id)
			colorlabels.append(label)

		# split into three rows with at max 5 entries in each row
		# right now there are 14 different colors to choose from.
		for i in xrange(0, len(colorlabels), 5):
			hbox = HBox(name='line_{index}'.format(index=i))
			hbox.addChildren(colorlabels[i:i+5])
			self.colors.addChild(hbox)
		
		playertextfield = self.gui.findChild(name='playername')
		def playertextfield_clicked():
			if playertextfield.text == 'Unnamed Traveler':
				playertextfield.text = "";
		playertextfield.capture(playertextfield_clicked, event_name='mouseClicked')
		
		self.gui.mapEvents(events)
		self.update_data()
		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)
Beispiel #25
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
	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 _draw(self, vbox, current_hbox, index=0):
		"""Draws the inventory."""
		for resid, limit in sorted(self._limits.items()):
			if self._selling:
				amount = max(0, self._inventory[resid] - limit)
			else:
				amount = max(0, limit - self._inventory[resid])

			# check if this res should be displayed
			button = ImageFillStatusButton.init_for_res(self.db, resid, amount,
			                                            filled=0, uncached=self.uncached)
			button.button.name = "buy_sell_inventory_%s_entry_%s" % (self._selling, index) # for 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
		vbox.addChild(current_hbox)
		self.addChild(vbox)
	def show_tooltip(self):
		if not self.helptext:
			return
		if self.gui is None:
			self.__init_gui()

		#HACK: support icons in build menu
		# Code below exists for the sole purpose of build menu tooltips showing
		# resource icons. Even supporting that is a pain (as you will see),
		# so if you think you need icons in other tooltips, maybe reconsider.
		# [These unicode() calls brought to you by status icon tooltip code.]
		buildmenu_icons = self.icon_regexp.findall(unicode(self.helptext))
		# Remove the weird stuff before displaying text.
		replaced = self.icon_regexp.sub('', unicode(self.helptext))
		# Specification looks like [[Buildmenu 1:250 4:2 6:2]]
		if buildmenu_icons:
			hbox = HBox(position=(7, 5), padding=0)
			for spec in buildmenu_icons[0].split():
				(res_id, amount) = spec.split(':')
				label = Label(text=amount+'  ')
				icon = Icon(image=get_res_icon_path(int(res_id)), size=(16, 16))
				# For compatibility with FIFE 0.3.5 and older, also set min/max.
				icon.max_size = icon.min_size = (16, 16)
				hbox.addChildren(icon, label)
			hbox.adaptLayout()
			# Now display the 16x16px "required resources" icons in the last line.
			self.gui.addChild(hbox)

		#HACK: wrap tooltip text
		# This looks better than splitting into several lines and joining them.
		# It works because replace_whitespace in `fill` defaults to True.
		replaced = replaced.replace(r'\n', self.CHARS_PER_LINE * ' ')
		replaced = replaced.replace('[br]', self.CHARS_PER_LINE * ' ')
		tooltip = textwrap.fill(replaced, self.CHARS_PER_LINE)

		# Finish up the actual tooltip (text, background panel amount, layout).
		# To display build menu icons, we need another empty (first) line.
		self.bg.amount = len(tooltip.splitlines()) - 1 + bool(buildmenu_icons)
		self.label.text = bool(buildmenu_icons) * '\n' + tooltip
		self.gui.adaptLayout()
		self.gui.show()
        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 refresh(self):
        """This function is called by the TabWidget to redraw the widget."""
        super(BoatbuilderTab, self).refresh()

        main_container = self.widget.findChild(name="BB_main_tab")
        container_active = main_container.findChild(name="container_active")
        container_inactive = main_container.findChild(
            name="container_inactive")
        progress_container = main_container.findChild(
            name="BB_progress_container")
        cancel_container = main_container.findChild(name="BB_cancel_container")
        needed_res_container = self.widget.findChild(
            name="BB_needed_resources_container")

        # a boatbuilder is considered active here if it builds sth, no matter if it's paused
        production_lines = self.producer.get_production_lines()

        if production_lines:
            cancel_container.parent.showChild(cancel_container)

            # Set progress
            progress_container.parent.showChild(progress_container)
            progress = math.floor(self.producer.get_production_progress() *
                                  100)
            self.widget.findChild(name='progress').progress = progress
            progress_perc = self.widget.findChild(name='BB_progress_perc')
            progress_perc.text = u'{progress}%'.format(progress=progress)

            container_active.parent.showChild(container_active)
            if (Fife.getVersion() >= (0, 4, 0)):
                container_inactive.parent.hideChild(container_inactive)
            else:
                if not container_inactive in container_inactive.parent.hidden_children:
                    container_inactive.parent.hideChild(container_inactive)

            # Update boatbuilder queue
            queue = self.producer.get_unit_production_queue()
            queue_container = container_active.findChild(
                name="queue_container")
            queue_container.removeAllChildren()
            for place_in_queue, unit_type in enumerate(queue):
                image = self.__class__.SHIP_THUMBNAIL.format(type_id=unit_type)
                helptext = _("{ship} (place in queue: {place})").format(
                    ship=self.instance.session.db.get_unit_type_name(
                        unit_type),
                    place=place_in_queue + 1)
                # people don't count properly, always starting at 1..
                icon_name = "queue_elem_" + str(place_in_queue)
                icon = Icon(name=icon_name, image=image, helptext=helptext)
                rm_from_queue_cb = Callback(
                    RemoveFromQueue(self.producer, place_in_queue).execute,
                    self.instance.session)
                icon.capture(rm_from_queue_cb, event_name="mouseClicked")
                queue_container.addChild(icon)

            # Set built ship info
            production_line = self.producer._get_production(
                production_lines[0])
            produced_unit_id = production_line.get_produced_units().keys()[0]

            name = self.instance.session.db.get_unit_type_name(
                produced_unit_id)

            container_active.findChild(
                name="headline_BB_builtship_label").text = _(name)
            ship_icon = container_active.findChild(name="BB_cur_ship_icon")
            ship_icon.helptext = self.instance.session.db.get_ship_tooltip(
                produced_unit_id)
            ship_icon.image = self.__class__.SHIP_PREVIEW_IMG.format(
                type_id=produced_unit_id)

            button_active = container_active.findChild(
                name="toggle_active_active")
            button_inactive = container_active.findChild(
                name="toggle_active_inactive")
            to_active = not self.producer.is_active()

            if not to_active:  # swap what we want to show and hide
                button_active, button_inactive = button_inactive, button_active
            if (Fife.getVersion() >= (0, 4, 0)):
                button_active.parent.hideChild(button_active)
            else:
                if not button_active in button_active.parent.hidden_children:
                    button_active.parent.hideChild(button_active)
            button_inactive.parent.showChild(button_inactive)

            set_active_cb = Callback(self.producer.set_active,
                                     active=to_active)
            button_inactive.capture(set_active_cb, event_name="mouseClicked")

            upgrades_box = container_active.findChild(name="BB_upgrades_box")
            upgrades_box.removeAllChildren()

            # Update needed resources
            production = self.producer.get_productions()[0]
            needed_res = production.get_consumed_resources()
            # Now sort! -amount is the positive value, drop unnecessary res (amount 0)
            needed_res = dict((res, -amount)
                              for res, amount in needed_res.iteritems()
                              if amount < 0)
            needed_res = sorted(needed_res.iteritems(),
                                key=itemgetter(1),
                                reverse=True)
            needed_res_container.removeAllChildren()
            for i, (res, amount) in enumerate(needed_res):
                icon = create_resource_icon(res, self.instance.session.db)
                icon.max_size = icon.min_size = icon.size = (16, 16)
                label = Label(name="needed_res_lbl_%s" % i)
                label.text = u'{amount}t'.format(amount=amount)
                new_hbox = HBox(name="needed_res_box_%s" % i)
                new_hbox.addChildren(icon, label)
                needed_res_container.addChild(new_hbox)

            cancel_button = self.widget.findChild(name="BB_cancel_button")
            cancel_cb = Callback(
                CancelCurrentProduction(self.producer).execute,
                self.instance.session)
            cancel_button.capture(cancel_cb, event_name="mouseClicked")

        else:  # display sth when nothing is produced
            container_inactive.parent.showChild(container_inactive)
            for w in (container_active, progress_container, cancel_container):
                if (Fife.getVersion() >= (0, 4, 0)):
                    w.parent.hideChild(w)
                else:
                    if not w in w.parent.hidden_children:
                        w.parent.hideChild(w)

        self.widget.adaptLayout()
Beispiel #31
0
	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",     _("Running costs")),
			("content/gui/images/resbar_stats/income.png",      _("Taxes")),
			("content/gui/images/resbar_stats/buy.png",         _("Buy expenses")),
			("content/gui/images/resbar_stats/sell.png",        _("Sell income")),
			("content/gui/images/resbar_stats/scales_icon.png", _("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_%s" % num
			box.helptext = helptext
			#TODO Fix icon size; looks like not 16x16 a surprising amount of times.
			box.addChild(Icon(image=image))
			box.addSpacer(Spacer())
			box.addChild(Label(name="resbar_stats_entry_%s"%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_%s"%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)
Beispiel #32
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
Beispiel #33
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)
    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)
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 refresh(self):
		"""This function is called by the TabWidget to redraw the widget."""
		super(BoatbuilderTab, self).refresh()

		main_container = self.widget.findChild(name="BB_main_tab")
		container_active = main_container.findChild(name="container_active")
		container_inactive = main_container.findChild(name="container_inactive")
		progress_container = main_container.findChild(name="BB_progress_container")
		cancel_container = main_container.findChild(name="BB_cancel_container")
		needed_res_container = self.widget.findChild(name="BB_needed_resources_container")

		# a boatbuilder is considered active here if it build sth, no matter if it's paused
		production_lines = self.producer.get_production_lines()

		if production_lines:
			cancel_container.parent.showChild(cancel_container)

			# Set progress
			progress_container.parent.showChild(progress_container)
			progress = math.floor(self.producer.get_production_progress() * 100)
			self.widget.findChild(name='progress').progress = progress
			progress_perc = self.widget.findChild(name='BB_progress_perc')
			progress_perc.text = u'{progress}%'.format(progress=progress)

			container_active.parent.showChild(container_active)
			if not container_inactive in container_inactive.parent.hidden_children:
				container_inactive.parent.hideChild(container_inactive)

			# Update boatbuilder queue
			queue = self.producer.get_unit_production_queue()
			queue_container = container_active.findChild(name="queue_container")
			queue_container.removeAllChildren()
			for place_in_queue, unit_type in enumerate(queue):
				image = self.__class__.SHIP_THUMBNAIL.format(type_id=unit_type)
				helptext = _(u"{ship} (place in queue: {place})") #xgettext:python-format
				helptext.format(ship=self.instance.session.db.get_unit_type_name(unit_type),
				                place=place_in_queue+1)
				# people don't count properly, always starting at 1..
				icon_name = "queue_elem_"+str(place_in_queue)
				icon = Icon(name=icon_name, image=image, helptext=helptext)
				rm_from_queue_cb = Callback(RemoveFromQueue(self.producer, place_in_queue).execute,
				                            self.instance.session)
				icon.capture(rm_from_queue_cb, event_name="mouseClicked")
				queue_container.addChild( icon )

			# Set built ship info
			production_line = self.producer._get_production(production_lines[0])
			produced_unit_id = production_line.get_produced_units().keys()[0]

			name = self.instance.session.db.get_unit_type_name(produced_unit_id)

			container_active.findChild(name="headline_BB_builtship_label").text = _(name)
			ship_icon = container_active.findChild(name="BB_cur_ship_icon")
			ship_icon.helptext = self.instance.session.db.get_ship_tooltip(produced_unit_id)
			ship_icon.image = self.__class__.SHIP_PREVIEW_IMG.format(type_id=produced_unit_id)

			button_active = container_active.findChild(name="toggle_active_active")
			button_inactive = container_active.findChild(name="toggle_active_inactive")
			to_active = not self.producer.is_active()

			if not to_active: # swap what we want to show and hide
				button_active, button_inactive = button_inactive, button_active
			if not button_active in button_active.parent.hidden_children:
				button_active.parent.hideChild(button_active)
			button_inactive.parent.showChild(button_inactive)

			set_active_cb = Callback(self.producer.set_active, active=to_active)
			button_inactive.capture(set_active_cb, event_name="mouseClicked")

			upgrades_box = container_active.findChild(name="BB_upgrades_box")
			upgrades_box.removeAllChildren()
#			upgrades_box.addChild(Label(text=u"+ love"))
#			upgrades_box.addChild(Label(text=u"+ affection"))
# no upgrades in 2010.1 release ---^
			upgrades_box.stylize('menu_black')

			# Update needed resources
			production = self.producer.get_productions()[0]
			needed_res = production.get_consumed_resources()
			# Now sort! -amount is the positive value, drop unnecessary res (amount 0)
			needed_res = dict((res, -amount) for res, amount in needed_res.iteritems() if amount < 0)
			needed_res = sorted(needed_res.iteritems(), key=itemgetter(1), reverse=True)
			needed_res_container.removeAllChildren()
			for i, (res, amount) in enumerate(needed_res):
				icon = create_resource_icon(res, self.instance.session.db)
				icon.max_size = icon.min_size = icon.size = (16, 16)
				label = Label(name="needed_res_lbl_%s" % i)
				label.text = u'{amount}t'.format(amount=amount)
				new_hbox = HBox(name="needed_res_box_%s" % i)
				new_hbox.addChildren(icon, label)
				needed_res_container.addChild(new_hbox)

			cancel_button = self.widget.findChild(name="BB_cancel_button")
			cancel_cb = Callback(CancelCurrentProduction(self.producer).execute, self.instance.session)
			cancel_button.capture(cancel_cb, event_name="mouseClicked")

		else: # display sth when nothing is produced
			container_inactive.parent.showChild(container_inactive)
			for w in (container_active, progress_container, cancel_container):
				if not w in w.parent.hidden_children:
					w.parent.hideChild(w)

		self.widget.adaptLayout()
	def refresh(self):
		"""This function is called by the TabWidget to redraw the widget."""
		super(BoatbuilderTab, self).refresh()

		THUMB_PATH = "content/gui/images/objects/ships/116/%s.png"

		main_container = self.widget.findChild(name="BB_main_tab")
		container_active = main_container.findChild(name="container_active")
		container_inactive = main_container.findChild(name="container_inactive")
		progress_container = main_container.findChild(name="BB_progress_container")
		cancel_container = main_container.findChild(name="BB_cancel_container")
		needed_res_container = self.widget.findChild(name="BB_needed_resources_container")

		# a boatbuilder is considered active here if it build sth, no matter if it's paused
		production_lines = self.producer.get_production_lines()

		if production_lines:

			if cancel_container is None:
				main_container.addChild(main_container.cancel_container)
				cancel_container = main_container.cancel_container

			if needed_res_container is None:
				main_container.insertChildBefore(main_container.needed_res_container, cancel_container)
				needed_res_container = main_container.needed_res_container

			# Set progress
			if progress_container is None:
				main_container.insertChildBefore( main_container.progress_container, self.widget.findChild(name="BB_needed_resources_container"))
				progress_container = main_container.progress_container

			progress = math.floor(self.producer.get_production_progress() * 100)
			self.widget.findChild(name='progress').progress = progress
			self.widget.findChild(name='BB_progress_perc').text = u'{progress}%'.format(progress=progress)

			# remove other container, but save it
			if container_inactive is not None:
				main_container.container_inactive = container_inactive
				main_container.removeChild( container_inactive )
			if container_active is None:
				main_container.insertChildBefore( main_container.container_active, progress_container)
				container_active = main_container.container_active

			# Update boatbuilder queue
			queue = self.producer.get_unit_production_queue()
			queue_container = container_active.findChild(name="queue_container")
			queue_container.removeAllChildren()
			for place_in_queue, unit_type in enumerate(queue):
				image = self.__class__.SHIP_THUMBNAIL.format(type_id=unit_type)
				#xgettext:python-format
				helptext = _(u"{ship} (place in queue: {place})").format(
				               ship=self.instance.session.db.get_unit_type_name(unit_type),
				               place=place_in_queue+1 )
				# people don't count properly, always starting at 1..
				icon_name = "queue_elem_"+str(place_in_queue)
				icon = Icon(name=icon_name, image=image, helptext=helptext)
				icon.capture(
				  Callback(RemoveFromQueue(self.producer, place_in_queue).execute, self.instance.session),
				  event_name="mouseClicked"
				)
				queue_container.addChild( icon )

			# Set built ship info
			produced_unit_id = self.producer._get_production(production_lines[0]).get_produced_units().keys()[0]
			name = self.instance.session.db.get_unit_type_name(produced_unit_id)
			container_active.findChild(name="headline_BB_builtship_label").text = _(name)
			container_active.findChild(name="BB_cur_ship_icon").helptext = "Storage: 4 slots, 120t \nHealth: 100"
			container_active.findChild(name="BB_cur_ship_icon").image = THUMB_PATH % produced_unit_id

			button_active = container_active.findChild(name="toggle_active_active")
			button_inactive = container_active.findChild(name="toggle_active_inactive")

			if not self.producer.is_active(): # if production is paused
				# remove active button, if it's there, and save a reference to it
				if button_active is not None:
					container_active.button_active = button_active
					container_active.removeChild( button_active )
				# restore inactive button, if it isn't in the gui
				if button_inactive is None:
					# insert at the end
					container_active.insertChild(container_active.button_inactive,
					                             len(container_active.children))
				container_active.mapEvents({
				  'toggle_active_inactive' : Callback(self.producer.set_active, active=True)
				})
				# TODO: make this button do sth
			else:
				# remove inactive button, if it's there, and save a reference to it
				if button_inactive is not None:
					container_active.button_inactive = button_inactive
					container_active.removeChild( button_inactive )
				# restore active button, if it isn't in the gui
				if button_active is None:
					# insert at the end
					container_active.insertChild(container_active.button_active,
					                             len(container_active.children))

				container_active.mapEvents({
				  'toggle_active_active' : Callback(self.producer.set_active, active=False)
				})
			upgrades_box = container_active.findChild(name="BB_upgrades_box")
			for child in upgrades_box.children[:]:
				upgrades_box.removeChild(child)
#			upgrades_box.addChild( pychan.widgets.Label(text=u"+ love") )
#			upgrades_box.addChild( pychan.widgets.Label(text=u"+ affection") )
# no upgrades in 2010.1 release ---^
			upgrades_box.stylize('menu_black')

			# Update needed resources
			production = self.producer.get_productions()[0]
			needed_res = production.get_consumed_resources()
			# Now sort! -amount is the positive value, drop unnecessary res (amount 0)
			needed_res = dict((res, -amount) for res, amount in needed_res.iteritems() if amount < 0)
			needed_res = sorted(needed_res.iteritems(), key=itemgetter(1), reverse=True)
			needed_res_container.removeAllChildren()
			for i, (res, amount) in enumerate(needed_res):
				icon = create_resource_icon(res, self.instance.session.db)
				icon.max_size = icon.min_size = icon.size = (16, 16)
				label = Label(name="needed_res_lbl_%s" % i)
				label.text = u'{amount}t'.format(amount=amount)
				new_hbox = HBox(name="needed_res_box_%s" % i)
				new_hbox.addChildren(icon, label)
				needed_res_container.addChild(new_hbox)

			cancel_button = self.widget.findChild(name="BB_cancel_button")
			cancel_cb = Callback(CancelCurrentProduction(self.producer).execute, self.instance.session)
			cancel_button.capture(cancel_cb, event_name="mouseClicked")

		else: # display sth when nothing is produced
			# remove other container, but save it
			if container_active is not None:
				main_container.container_active = container_active
				main_container.removeChild( container_active )
			if container_inactive is None:
				main_container.insertChildBefore( main_container.container_inactive, progress_container)
				container_inactive = main_container.container_inactive

			if progress_container is not None:
				main_container.progress_container = progress_container
				main_container.removeChild(progress_container)

			if needed_res_container is not None:
				main_container.needed_res_container = needed_res_container
				main_container.removeChild(needed_res_container)

			if cancel_container is not None:
				main_container.cancel_container = cancel_container
				main_container.removeChild(cancel_container)


		self.widget.adaptLayout()
	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)
Beispiel #40
0
    def show_tooltip(self):
        if not self.helptext:
            return
        if self.gui is None:
            self.__init_gui()

        # Compare and reset timer value if difference from current time shorter than X sec.
        if (time.time() - self.cooldown) < 1:
            return
        else:
            self.cooldown = time.time()

        #HACK: support icons in build menu
        # Code below exists for the sole purpose of build menu tooltips showing
        # resource icons. Even supporting that is a pain (as you will see),
        # so if you think you need icons in other tooltips, maybe reconsider.
        # [These unicode() calls brought to you by status icon tooltip code.]
        buildmenu_icons = self.icon_regexp.findall(str(self.helptext))
        # Remove the weird stuff before displaying text.
        replaced = self.icon_regexp.sub('', str(self.helptext))
        # Specification looks like [[Buildmenu 1:250 4:2 6:2]]
        if buildmenu_icons:
            hbox = HBox(position=(7, 5))
            for spec in buildmenu_icons[0].split():
                (res_id, amount) = spec.split(':')
                label = Label(text=amount + '  ')
                icon = Icon(image=get_res_icon_path(int(res_id)),
                            size=(16, 16),
                            scale=True)
                hbox.addChildren(icon, label)
            hbox.adaptLayout()
            # Now display the 16x16px "required resources" icons in the last line.
            self.gui.addChild(hbox)

        #HACK: wrap tooltip text
        # This looks better than splitting into several lines and joining them.
        # It works because replace_whitespace in `fill` defaults to True.
        replaced = replaced.replace(r'\n', self.CHARS_PER_LINE * ' ')
        replaced = replaced.replace('[br]', self.CHARS_PER_LINE * ' ')
        tooltip = textwrap.fill(replaced, self.CHARS_PER_LINE)

        # Finish up the actual tooltip (text, background panel amount, layout).
        # To display build menu icons, we need another empty (first) line.
        self.bg.amount = len(tooltip.splitlines()) - 1 + bool(buildmenu_icons)
        self.label.text = bool(buildmenu_icons) * '\n' + tooltip
        self.gui.adaptLayout()
        self.gui.show()

        # NOTE: the below code in this method is a hack to resolve #2227
        # cannot find a better way to fix it, cause in fife.pychan, it seems
        # if a widget gets hidden or removed, the children of that widget are not
        # hidden or removed properly (at least in Python code)

        # update topmost_widget every time the tooltip is shown
        # this is to dismiss the tooltip later, see _check_hover_alive
        target_widget = self
        while target_widget:
            self.topmost_widget = target_widget
            target_widget = target_widget.parent

        # add an event to constantly check whether the hovered widget is still there
        # if this is no longer there, dismiss the tooltip widget
        ExtScheduler().add_new_object(self._check_hover_alive,
                                      self,
                                      run_in=0.5,
                                      loops=-1)