Example #1
0
    def _init_tab_buttons(self):
        """Add enough tabbuttons for all widgets."""
        def on_tab_removal(tabwidget):
            # called when a tab is being removed (via weakref since tabs shouldn't have references to the parent tabwidget)
            # If one tab is removed, the whole tabwidget will die..
            # This is easy usually the desired behavior.
            if tabwidget():
                tabwidget().on_remove()

        # Load buttons
        for index, tab in enumerate(self._tabs):
            # don't add a reference to the
            tab.add_remove_listener(Callback(on_tab_removal,
                                             weakref.ref(self)))
            container = Container(name="container_{}".format(index))
            background = Icon(name="bg_{}".format(index))
            button = ImageButton(name=str(index), size=(50, 50))
            if self.current_tab is tab:
                background.image = tab.button_background_image_active
                button.path = tab.path_active
            else:
                background.image = tab.button_background_image
                button.path = tab.path
            button.capture(Callback(self.show_tab, index))
            if hasattr(tab, 'helptext') and tab.helptext:
                button.helptext = tab.helptext
            container.size = (50, 52)
            container.addChild(background)
            container.addChild(button)
            self.content.addChild(container)
        self.widget.size = (54, 55 * len(self._tabs))
        self.widget.adaptLayout()

        self._apply_layout_hack()
	def refresh(self):
		"""This function is called by the TabWidget to redraw the widget."""
		self._refresh_utilisation()

		# remove old production line data
		parent_container = self.widget.child_finder('production_lines')
		while parent_container.children:
			child = parent_container.children[-1]
			if hasattr(child, "anim"):
				child.anim.stop()
				del child.anim
			parent_container.removeChild( child )

		# create a container for each production
		# sort by production line id to have a consistent (basically arbitrary) order
		for production in self.get_displayed_productions():
			# we need to be notified of small production changes
			# that aren't passed through the instance
			production.add_change_listener(self._schedule_refresh, no_duplicates=True)

			gui = load_uh_widget(self.production_line_gui_xml)
			# fill in values to gui reflecting the current game state
			container = gui.findChild(name="production_line_container")
			self._set_resource_amounts(container, production)

			if production.is_paused():
				container.removeChild( container.findChild(name="toggle_active_active") )
				toggle_icon = container.findChild(name="toggle_active_inactive")
				toggle_icon.name = "toggle_active"
			else:
				container.removeChild( container.findChild(name="toggle_active_inactive") )
				toggle_icon = container.findChild(name="toggle_active_active")
				toggle_icon.name = "toggle_active"

				if production.get_state() == PRODUCTION.STATES.producing:
					bg = Icon(image=self.__class__.BUTTON_BACKGROUND)
					bg.position = toggle_icon.position
					container.addChild(bg)
					container.removeChild(toggle_icon) # fix z-ordering
					container.addChild(toggle_icon)
					anim = PychanAnimation(toggle_icon, self.__class__.ACTIVE_PRODUCTION_ANIM_DIR)
					container.anim = anim
					anim.start(1.0/12, -1) # always start anew, people won't notice
					self._animations.append( weakref.ref( anim ) )

			# fill it with input and output resources
			in_res_container = container.findChild(name="input_res")
			self._add_resource_icons(in_res_container, production.get_consumed_resources(), marker=True)
			out_res_container = container.findChild(name="output_res")
			self._add_resource_icons(out_res_container, production.get_produced_resources())

			# active toggle_active button
			toggle_active = ToggleActive(self.instance.get_component(Producer), production)
			container.mapEvents({
				'toggle_active': Callback(toggle_active.execute, self.instance.session)
			})
			# NOTE: this command causes a refresh, so we needn't change the toggle_active-button-image
			container.stylize('menu_black')
			parent_container.addChild(container)
		super(ProductionOverviewTab, self).refresh()
			def __init__(self, cursor_tool, **kwargs):
				super(CoordsTooltip, self).__init__(**kwargs)
				cursor_tool.session.ingame_gui.coordinates_tooltip = self
				self.cursor_tool = cursor_tool
				self.enabled = False

				self.icon = Icon(position=(1, 1)) # 0, 0 is currently not supported by tooltips
	def _draw(self):
		"""Draws the icon + bar."""
		# hash buttons by creation function call
		# NOTE: there may be problems with multiple buttons with the same
		# images and helptext at the same time
		create_btn = Callback(ImageButton, path=self.path, helptext=self.helptext)
		self.button = None
		if self.uncached:
			self.button = create_btn()
		else:
			self.button = self.__widget_cache.get(create_btn, None)
			if self.button is None: # create button
				self.__widget_cache[create_btn] = self.button = create_btn()
			else: # disconnect button from earlier layout
				if self.button.parent:
					self.button.parent.removeChild(self.button)

		# can't cache the other instances, because we need multiple instances
		# with the same data active at the same time
		self.label = Label(text=self.text)
		self.label.position = self.text_position
		self.fill_bar = Icon(image="content/gui/images/tabwidget/green_line.png")
		fill_level = (self.button.height * self.filled) // 100
		self.fill_bar.size = ((2 * self.fill_bar.size[0]) // 3, fill_level)
		# move fillbar down after resizing, since its origin is top aligned
		self.fill_bar.position = (self.button.width, self.button.height - fill_level)
		self.addChildren(self.button, self.fill_bar, self.label)
		if self.marker > 0:
			marker_icon = Icon(image="content/gui/icons/templates/production/marker.png")
			marker_level = (self.button.height * self.marker) // 100
			marker_icon.position = (self.button.width - 1, self.button.height - marker_level)
			marker_icon.max_size = (5, 1)
			self.addChild(marker_icon)
Example #5
0
	def show_tooltip(self):
		if not self.helptext:
			return
		# recreate full tooltip since new text needs to be relayouted
		if self.gui is None:
			self.gui = load_uh_widget('tooltip.xml')
		else:
			self.gui.removeAllChildren()
		translated_tooltip = _(self.helptext)
		#HACK this looks better than splitting into several lines & joining
		# them. works because replace_whitespace in fill defaults to True:
		replaced = translated_tooltip.replace(r'\n', self.CHARS_PER_LINE * ' ')
		replaced = replaced.replace('[br]', self.CHARS_PER_LINE * ' ')
		tooltip = textwrap.fill(replaced, self.CHARS_PER_LINE)

		line_count = len(tooltip.splitlines()) - 1
		top_image = Icon(image=self.TOP_IMAGE, position=(0, 0))
		self.gui.addChild(top_image)
		top_x, top_y = top_image.position
		top_y += self.SIZE_BG_TOP
		for i in xrange(0, line_count):
			middle_image = Icon(image=self.MIDDLE_IMAGE)
			middle_image.position = (top_x, top_y + self.LINE_HEIGHT * i)
			self.gui.addChild(middle_image)
		bottom_image = Icon(image=self.BOTTOM_IMAGE)
		bottom_image.position = (top_x, top_y + self.LINE_HEIGHT * line_count)
		self.gui.addChild(bottom_image)

		label = Label(text=tooltip, position=(10, 5))
		self.gui.addChild(label)
		self.gui.stylize('tooltip')
		size_y = self.SIZE_BG_TOP + self.LINE_HEIGHT * line_count + self.SIZE_BG_BOTTOM
		self.gui.size = (145, size_y)
		self.gui.show()
Example #6
0
def create_resource_icon(res_id, db):
	"""Creates a pychan Icon for a resource. Helptext is set to name of *res_id*.
	@param res_id: resource id
	@param db: dbreader for main db"""
	widget = Icon(image=get_res_icon_path(res_id))
	widget.helptext = db.get_res_name(res_id)
	return widget
Example #7
0
 def _set_tile_amount(self, amount):
     self.__tile_amount = amount
     for i in xrange(self.amount):
         mid = Icon(image=self.tiles_img, name=self.name + str(i + 1))
         self.addChild(mid)
     self.addChild(
         Icon(image=self.final_img, name=self.name + str(self.amount + 1)))
Example #8
0
def create_resource_icon(res_id, db):
	"""Creates a pychan Icon for a resource. Helptext is set to name of *res_id*.
	@param res_id: resource id
	@param db: dbreader for main db"""
	widget = Icon(image=get_res_icon_path(res_id))
	widget.helptext = db.get_res_name(res_id)
	return widget
	def _draw(self):
		"""Draws the icon + bar."""
		# hash buttons by creation function call
		# NOTE: there may be problems with multiple buttons with the same
		# images and helptext at the same time
		create_btn = Callback(ImageButton, path=self.path, helptext=self.helptext)
		self.button = None
		if self.uncached:
			self.button = create_btn()
		else:
			self.button = self.__widget_cache.get(create_btn, None)
			if self.button is None: # create button
				self.__widget_cache[create_btn] = self.button = create_btn()
			else: # disconnect button from earlier layout
				if self.button.parent:
					self.button.parent.removeChild(self.button)

		# can't cache the other instances, because we need multiple instances
		# with the same data active at the same time
		self.label = Label(text=self.text)
		self.label.position = self.text_position
		self.fill_bar = Icon(image="content/gui/images/tabwidget/green_line.png")
		fill_level = (self.button.height * self.filled) // 100
		self.fill_bar.size = ((2 * self.fill_bar.size[0]) // 3, fill_level)
		# move fillbar down after resizing, since its origin is top aligned
		self.fill_bar.position = (self.button.width, self.button.height - fill_level)
		self.addChildren(self.button, self.fill_bar, self.label)
		if self.marker > 0:
			marker_icon = Icon(image="content/gui/icons/templates/production/marker.png")
			marker_level = (self.button.height * self.marker) // 100
			marker_icon.position = (self.button.width - 1, self.button.height - marker_level)
			marker_icon.max_size = (5, 1)
			self.addChild(marker_icon)
	def update_queue(self, container_active):
		""" Update the queue display"""
		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__.UNIT_THUMBNAIL.format(type_id=unit_type)
			helptext = T("{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)

			try:
				icon = Icon(name=icon_name, image=image, helptext=helptext)
			except fife.NotFound as e:
				# It's possible that this error was raised from a missing thumbnail asset,
				# so we check against that now and use a fallback thumbnail instead
				if 'content/gui/icons/thumbnails/' in e.what():
					# actually load the fallback unit image
					image = self.__class__.UNIT_THUMBNAIL.format(type_id="unknown_unit")
					icon = Icon(name=icon_name, image=image, helptext=helptext)
				else:
					raise

			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)
Example #11
0
	def _init_tabs(self):
		"""Add enough tabbuttons for all widgets."""
		def on_tab_removal(tabwidget):
			# called when a tab is being removed (via weakref since tabs shouldn't have references to the parent tabwidget)
			# If one tab is removed, the whole tabwidget will die..
			# This is easy usually the desired behavior.
			if tabwidget():
				tabwidget().on_remove()

		# Load buttons
		for index, tab in enumerate(self._tabs):
			# don't add a reference to the
			tab.add_remove_listener(Callback(on_tab_removal, weakref.ref(self)))
			container = Container(name="container_%s" % index)
			background = Icon(name="bg_%s" % index)
			button = ImageButton(name=str(index), size=(50, 50))
			if self.current_tab is tab:
				background.image = tab.button_background_image_active
				button.path = tab.path_active
			else:
				background.image = tab.button_background_image
				button.path = tab.path
			button.capture(Callback(self._show_tab, index))
			if hasattr(tab, 'helptext') and tab.helptext is not None:
				button.helptext = tab.helptext
			container.size = background.size
			container.addChild(background)
			container.addChild(button)
			self.content.addChild(container)
		self.widget.size = (50, 55*len(self._tabs))
		self.widget.adaptLayout()

		self._apply_layout_hack()
    def update_queue(self, container_active):
        """ Update the queue display"""
        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__.UNIT_THUMBNAIL.format(type_id=unit_type)
            helptext = T("{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)

            try:
                icon = Icon(name=icon_name, image=image, helptext=helptext)
            except RuntimeError, e:
                # It's possible that this error was raised from a missing thumbnail asset,
                # so we check against that now and use a fallback thumbnail instead

                # TODO string matching for runtime errors is nightmare fuel
                # Better: Replace RuntimeError in fife with a more precise error class if possible
                # and only catch that class here
                if e.message.startswith(
                    "_[NotFound]_ , Something was searched, but not found :: content/gui/icons/thumbnails/"
                ):
                    # actually load the fallback unit image
                    image = self.__class__.UNIT_THUMBNAIL.format(type_id="unknown_unit")
                    icon = Icon(name=icon_name, image=image, helptext=helptext)
                else:
                    raise

            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)
Example #13
0
	def __init__(self):
		self.mainlistener = MainListener(self)

		self.windows = WindowManager()
		# temporary aliases for compatibility with rest of the code
		self.open_popup = self.windows.open_popup
		self.open_error_popup = self.windows.open_error_popup

		# Main menu background image setup.
		available_images = glob.glob('content/gui/images/background/mainmenu/bg_*.png')
		self.bg_images = deque(available_images)

		latest_bg = horizons.globals.fife.get_uh_setting("LatestBackground")
		try:
			# If we know the current background from an earlier session,
			# show all other available ones before picking that one again.
			self.bg_images.remove(latest_bg)
			self.bg_images.append(latest_bg)
		except ValueError:
			pass
		self._background = Icon(position_technique='center:center')
		self.rotate_background()
		self._background.show()

		# Initialize menu dialogs and widgets that are accessed from `gui`.
		self.singleplayermenu = SingleplayerMenu(self.windows)
		self.multiplayermenu = MultiplayerMenu(self, self.windows)
		self.help_dialog = HelpDialog(self.windows)
		self.loadingscreen = LoadingScreen()
		self.settings_dialog = SettingsDialog(self.windows)
		self.mainmenu = MainMenu(self, self.windows)
		self.fps_display = FPSDisplay()
Example #14
0
	def set_construction_mode(self, resource_source_instance, build_costs):
		"""Show resources relevant to construction and build costs
		@param resource_source_instance: object with StorageComponent
		@param build_costs: dict, { res : amount }
		"""
		if resource_source_instance is None:
			# Build moved out of settlement. This is usually not sane and an interaction error.
			# Use this heuristically computed settlement to fix preconditions.
			resource_source_instance = LastActivePlayerSettlementManager().get()
		if self.construction_mode and \
		   resource_source_instance == self.current_instance() and \
		   build_costs == self._last_build_costs:
			return # now that's not an update

		self._last_build_costs = build_costs

		self.construction_mode = True
		self.set_inventory_instance(resource_source_instance, keep_construction_mode=True)

		# label background icons
		cost_icon_gold = "content/gui/images/background/widgets/resbar_stats_bottom.png"
		cost_icon_res = "content/gui/images/background/widgets/res_extra_bg.png"

		res_list = self._get_current_resources()

		# remove old one before, avoids duplicates
		self._drop_cost_labels()

		for res, amount in build_costs.iteritems():
			assert res in res_list or res == RES.GOLD

			cost_label = Label(text=u"-"+unicode(amount))
			cost_label.stylize( self.__class__.STYLE )
			# add icon below end of background icon
			if res in res_list:
				entry = res_list.index(res)
				cur_gui = self.gui[ entry ]
				reference_icon = cur_gui.findChild(name="background_icon")
				below = reference_icon.size[1]
				cost_icon = Icon(image=cost_icon_res, position=(0, below))
				cost_label.position = (15, below) # TODO: centering

				cur_gui.addChild(cost_icon)
				cur_gui.addChild(cost_label)
				cur_gui.cost_gui = [cost_label, cost_icon]

				cur_gui.resizeToContent() # container needs to be bigger now
			else: # must be gold
				# there is an icon with scales there, use its positioning
				reference_icon = self.gold_gui.child_finder("balance_background")
				cost_icon = Icon(image=cost_icon_gold, position=(reference_icon.x, reference_icon.y))
				cost_label.position = (23, 74) # TODO: centering

				self.gold_gui.addChild(cost_icon)
				self.gold_gui.addChild(cost_label)
				self.gold_gui.cost_gui = [cost_label, cost_icon]

				self.gold_gui.resizeToContent()
    def build_ship_info(self, index, ship, prodline):
        size = (260, 90)
        widget = Container(name='showcase_%s' % index,
                           position=(0, 20 + index * 90),
                           min_size=size,
                           max_size=size,
                           size=size)
        bg_icon = Icon(image='content/gui/images/background/square_80.png',
                       name='bg_%s' % index)
        widget.addChild(bg_icon)

        image = 'content/gui/images/objects/ships/76/{unit_id}.png'.format(
            unit_id=ship)
        helptext = self.instance.session.db.get_ship_tooltip(ship)
        unit_icon = Icon(image=image,
                         name='icon_%s' % index,
                         position=(2, 2),
                         helptext=helptext)
        widget.addChild(unit_icon)

        # if not buildable, this returns string with reason why to be displayed as helptext
        #ship_unbuildable = self.is_ship_unbuildable(ship)
        ship_unbuildable = False
        if not ship_unbuildable:
            button = OkButton(position=(60, 50),
                              name='ok_%s' % index,
                              helptext=_('Build this ship!'))
            button.capture(Callback(self.start_production, prodline))
        else:
            button = CancelButton(position=(60, 50),
                                  name='ok_%s' % index,
                                  helptext=ship_unbuildable)

        widget.addChild(button)

        # Get production line info
        production = self.producer.create_production_line(prodline)
        # consumed == negative, reverse to sort in *ascending* order:
        costs = sorted(production.consumed_res.iteritems(), key=itemgetter(1))
        for i, (res, amount) in enumerate(costs):
            xoffset = 103 + (i % 2) * 55
            yoffset = 20 + (i // 2) * 20
            icon = create_resource_icon(res, self.instance.session.db)
            icon.max_size = icon.min_size = icon.size = (16, 16)
            icon.position = (xoffset, yoffset)
            label = Label(name='cost_%s_%s' % (index, i))
            if res == RES.GOLD:
                label.text = unicode(-amount)
            else:
                label.text = u'{amount:02}t'.format(amount=-amount)
            label.position = (22 + xoffset, yoffset)
            widget.addChild(icon)
            widget.addChild(label)
        return widget
Example #16
0
def create_resource_icon(res_id, db, size=50):
	"""Creates a pychan Icon for a resource. Helptext is set to name of *res_id*.
	Returns None if *size* parameter is invalid (not one of 16, 24, 32, 50).
	@param res_id: resource id
	@param db: dbreader for main db
	@param size: Size of icon in px. Valid: 16, 24, 32, 50."""
	widget = None
	if size in (16, 24, 32, 50):
		widget = Icon(image=get_res_icon_path(res_id, size))
		widget.helptext = db.get_res_name(res_id)
	return widget
Example #17
0
	def _set_tile_amount(self, amount):
		if amount == self.__tile_amount and amount > 0:
			# Default amount of 0 should still add top/bottom graphics once
			return
		self.__tile_amount = amount
		self.removeAllChildren()
		start_img = Icon(image=self.start_img, name=self.name + '0')
		self.addChild(start_img)
		for i in xrange(self.amount):
			mid = Icon(image=self.tiles_img, name=self.name + str(i+1))
			self.addChild(mid)
		self.addChild(Icon(image=self.final_img, name=self.name + str(self.amount+1)))
Example #18
0
    def _show_modal_background(self):
        """
		Loads transparent background that de facto prohibits access to other
		gui elements by eating all input events.
		"""
        height = horizons.globals.fife.engine_settings.getScreenHeight()
        width = horizons.globals.fife.engine_settings.getScreenWidth()
        image = horizons.globals.fife.imagemanager.loadBlank(width, height)
        image = fife.GuiImage(image)
        self._modal_background = Icon(image=image)
        self._modal_background.position = (0, 0)
        self._modal_background.show()
Example #19
0
class Background:
    """
	Display a centered background image on top of a black screen.
	"""
    def __init__(self):
        available_images = glob.glob(
            'content/gui/images/background/mainmenu/bg_*.png')
        self.bg_images = deque(available_images)

        latest_bg = horizons.globals.fife.get_uh_setting("LatestBackground")
        try:
            # If we know the current background from an earlier session,
            # show all other available ones before picking that one again.
            self.bg_images.remove(latest_bg)
            self.bg_images.append(latest_bg)
        except ValueError:
            pass

        (res_width, res_height) = horizons.globals.fife.get_fife_setting(
            'ScreenResolution').split('x')
        self._black_box = Container()
        self._black_box.size = int(res_width), int(res_height)
        self._black_box.base_color = (0, 0, 0, 255)

        self._image = Icon(position_technique='center:center')
        self.rotate_image()

    def rotate_image(self):
        """Select next background image to use in the game menu.

		Triggered by the "Change background" main menu button.
		"""
        self.bg_images.rotate(1)
        self._image.image = self.bg_images[0]
        # Save current background choice to settings.
        # This keeps the background image consistent between sessions.
        horizons.globals.fife.set_uh_setting("LatestBackground",
                                             self.bg_images[0])
        horizons.globals.fife.save_settings()

    def show(self):
        self._black_box.show()
        self._image.show()

    def hide(self):
        self._image.hide()
        self._black_box.hide()

    @property
    def visible(self):
        return self._image.isVisible()
		class CoordsTooltip:
			@classmethod
			def get_instance(cls, cursor_tool):
				if cursor_tool.session.ingame_gui.coordinates_tooltip is not None:
					inst = cursor_tool.session.ingame_gui.coordinates_tooltip
					inst.cursor_tool = cursor_tool
					return inst
				else:
					return CoordsTooltip(cursor_tool)

			def __init__(self, cursor_tool, **kwargs):
				super().__init__(**kwargs)
				cursor_tool.session.ingame_gui.coordinates_tooltip = self
				self.cursor_tool = cursor_tool
				self.enabled = False

				self.icon = Icon(position=(1, 1)) # 0, 0 is currently not supported by tooltips

			def toggle(self):
				self.enabled = not self.enabled
				if not self.enabled and self.icon.tooltip_shown:
					self.icon.hide_tooltip()

			def show_evt(self, evt):
				if self.enabled:
					if evt.isConsumedByWidgets():
						if self.icon.tooltip_shown:
							self.icon.hide_tooltip()
						return
					x, y = self.cursor_tool.get_world_location(evt).to_tuple()
					self.icon.helptext = '{:d}, {:d} '.format(x, y) + T("Press H to remove this hint")
					self.icon.position_tooltip(evt)
					self.icon.show_tooltip()
        class CoordsTooltip:
            @classmethod
            def get_instance(cls, cursor_tool):
                if cursor_tool.session.ingame_gui.coordinates_tooltip is not None:
                    inst = cursor_tool.session.ingame_gui.coordinates_tooltip
                    inst.cursor_tool = cursor_tool
                    return inst
                else:
                    return CoordsTooltip(cursor_tool)

            def __init__(self, cursor_tool, **kwargs):
                super().__init__(**kwargs)
                cursor_tool.session.ingame_gui.coordinates_tooltip = self
                self.cursor_tool = cursor_tool
                self.enabled = False

                self.icon = Icon(position=(
                    1, 1))  # 0, 0 is currently not supported by tooltips

            def toggle(self):
                self.enabled = not self.enabled
                if not self.enabled and self.icon.tooltip_shown:
                    self.icon.hide_tooltip()

            def show_evt(self, evt):
                if self.enabled:
                    if evt.isConsumedByWidgets():
                        if self.icon.tooltip_shown:
                            self.icon.hide_tooltip()
                        return
                    x, y = self.cursor_tool.get_world_location(evt).to_tuple()
                    self.icon.helptext = '{:d}, {:d} '.format(
                        x, y) + T("Press H to remove this hint")
                    self.icon.position_tooltip(evt)
                    self.icon.show_tooltip()
Example #22
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 = 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]
            duplicate_message = message in self._messages_to_display  # message is already going to be displayed

            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
Example #23
0
class Background:
	"""
	Display a centered background image on top of a black screen.
	"""
	def __init__(self):
		available_images = glob.glob('content/gui/images/background/mainmenu/bg_*.png')
		self.bg_images = deque(available_images)

		latest_bg = horizons.globals.fife.get_uh_setting("LatestBackground")
		try:
			# If we know the current background from an earlier session,
			# show all other available ones before picking that one again.
			self.bg_images.remove(latest_bg)
			self.bg_images.append(latest_bg)
		except ValueError:
			pass

		(res_width, res_height) = horizons.globals.fife.get_fife_setting('ScreenResolution').split('x')
		self._black_box = Container()
		self._black_box.size = int(res_width), int(res_height)
		self._black_box.base_color = (0, 0, 0, 255)

		self._image = Icon(position_technique='center:center')
		self.rotate_image()

	def rotate_image(self):
		"""Select next background image to use in the game menu.

		Triggered by the "Change background" main menu button.
		"""
		self.bg_images.rotate(1)
		self._image.image = self.bg_images[0]
		# Save current background choice to settings.
		# This keeps the background image consistent between sessions.
		horizons.globals.fife.set_uh_setting("LatestBackground", self.bg_images[0])
		horizons.globals.fife.save_settings()

	def show(self):
		self._black_box.show()
		self._image.show()

	def hide(self):
		self._image.hide()
		self._black_box.hide()

	@property
	def visible(self):
		return self._image.isVisible()
 def update_queue(self, container_active):
     """ Update the queue display"""
     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__.UNIT_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)
Example #25
0
    def show_text(self, index):
        """Shows the text for a button.
		@param index: index of button"""
        assert isinstance(index, int)
        ExtScheduler().rem_call(
            self, self.hide_text)  # stop hiding if a new text has been shown
        label = self.text_widget.findChild(name='text')
        text = self.active_messages[self.item + index].message
        text = text.replace(r'\n', self.CHARS_PER_LINE * ' ')
        text = text.replace(r'[br]', self.CHARS_PER_LINE * ' ')
        text = textwrap.fill(text, self.CHARS_PER_LINE)

        self.bg_middle = self.text_widget.findChild(name='msg_bg_middle')
        self.bg_middle.removeAllChildren()

        line_count = len(text.splitlines()) - 1
        for i in xrange(line_count * self.LINE_HEIGHT // self.IMG_HEIGHT):
            middle_icon = Icon(image=self.BG_IMAGE_MIDDLE)
            self.bg_middle.addChild(middle_icon)

        message_container = self.text_widget.findChild(name='message')
        message_container.size = (300, 21 + self.IMG_HEIGHT * line_count + 21)

        self.bg_middle.adaptLayout()
        label.text = text
        label.adaptLayout()
        self.text_widget.show()
Example #26
0
	def __init__(self):
		self.mainlistener = MainListener(self)

		self.windows = WindowManager()
		# temporary aliases for compatibility with rest of the code
		self.show_popup = self.windows.show_popup
		self.show_error_popup = self.windows.show_error_popup

		# Main menu background image setup.
		available_images = glob.glob('content/gui/images/background/mainmenu/bg_*.png')
		self.bg_images = deque(available_images)

		latest_bg = horizons.globals.fife.get_uh_setting("LatestBackground")
		try:
			# If we know the current background from an earlier session,
			# show all other available ones before picking that one again.
			self.bg_images.remove(latest_bg)
			self.bg_images.append(latest_bg)
		except ValueError:
			pass
		self._background = Icon(position_technique='center:center')
		self.rotate_background()
		self._background.show()

		self.singleplayermenu = SingleplayerMenu(self.windows)
		self.multiplayermenu = MultiplayerMenu(self, self.windows)
		self.help_dialog = HelpDialog(self.windows)
		self.loadingscreen = LoadingScreen()
		self.settings_dialog = SettingsDialog(self.windows)
		self.mainmenu = MainMenu(self, self.windows)
		self.fps_display = FPSDisplay()
Example #27
0
 def update(self):
     self.removeAllChildren()
     weapons_added = False
     if hasattr(self.instance, 'get_weapon_storage'):
         storage = self.instance.get_weapon_storage()
         for weapon, amount in storage:
             weapons_added = True
             icon_image = get_res_icon_path(weapon, 24)
             icon_tooltip = self.instance.session.db.get_res_name(
                 weapon) + ': ' + str(amount)
             icon = Icon(image=icon_image, helptext=icon_tooltip)
             self.addChild(icon)
     if not weapons_added:
         icon_image = "content/gui/icons/resources/none.png"
         icon = Icon(image=icon_image, helptext=_("none"))
         self.addChild(icon)
Example #28
0
def get_res_icon_path(res, size=32, greyscale=False, full_path=True):
	"""Returns path of a resource icon or placeholder path, if icon does not exist.
	@param res: resource id. Pass 'placeholder' to get placeholder path.
	@param full_path: whether to return full icon path or a stub path suitable for ImageButton path=
	"""
	icon_path = 'content/gui/icons/resources/{size}/'.format(size=size)
	if greyscale:
		icon_path = icon_path + 'greyscale/'
	if res == 'placeholder':
		icon_path = icon_path + 'placeholder.png'
	else:
		icon_path = icon_path + '{res:03d}.png'.format(res=res)

	try:
		Icon(image=icon_path).hide()
	except fife.NotFound: # ImageManager: image not found, use placeholder or die
		if res == 'placeholder':
			raise Exception('Image not found: {icon_path}'.format(icon_path=icon_path))
		else:
			log = logging.getLogger('gui')
			log.warning('Image not found: %s', icon_path)
			icon_path = get_res_icon_path('placeholder', size)

	if full_path:
		return icon_path
	else:
		# remove 'content/gui/' and '.png'
		return icon_path[12:][:-4]
Example #29
0
	def init(self, db, inventory, ordinal=None):
		"""
		@param ordinal: {res: (min, max)} Display ordinal scale with these boundaries instead of numbers for a particular resource. Currently implemented via ImageFillStatusButton.
		"""
		# check if we must init everything anew
		if self.init_needed(inventory):
			# this inits the logic of the inventory. @see __init__().
			self._inited = True
			self.db = db
			self._inventory = inventory

			# specific to Inventory
			self.ordinal = ordinal
			self._res_order = sorted(self._inventory.iterslots())
			self.legend = Label(name="legend")
			self.__icon = Icon(name="legend_icon")
			self.__icon.image = "content/gui/icons/ship/civil_16.png"
			if isinstance(self._inventory, TotalStorage):
				self.__icon.position = (130, 53)
				self.legend.position = (150, 53)
			elif isinstance(self._inventory, PositiveSizedSlotStorage):
				self.__icon.position = ( 0, 248)
				self.legend.position = (20, 248)

		self.update()
Example #30
0
 def _icon(image):
     try:
         # Pychan can only use str objects as file path.
         # json.loads() however returns unicode.
         return Icon(image=str(image))
     except RuntimeError:
         return None
Example #31
0
			def __init__(self, cursor_tool, **kwargs):
				super(CoordsTooltip, self).__init__(**kwargs)
				cursor_tool.session.coordinates_tooltip = self
				self.cursor_tool = cursor_tool
				self.enabled = False

				self.icon = Icon()
Example #32
0
		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 refresh(self):
        """
		This function is called by the TabWidget to redraw the widget.
		"""
        # remove old data
        parent_container = self.widget.child_finder('related_buildings')
        while parent_container.children:
            parent_container.removeChild(parent_container.children[0])

        # load all related buildings from DB
        building_ids = self.instance.session.db.get_related_building_ids_for_menu(
            self.instance.id)
        sorted_ids = sorted([(b, Entities.buildings[b].settler_level)
                             for b in building_ids],
                            key=lambda x: x[1])
        container = self.__get_new_container()
        for i, (building_id, level) in enumerate(sorted_ids):
            if level > self.instance.owner.settler_level:
                break

            button = self._create_build_buttons(building_id, container)
            # check whether to start new line (currently only 4 fit per line)
            if i and i % 4 == 0:
                parent_container.addChild(container)
                container = self.__get_new_container()
            container.findChild(name="build_button_container").addChild(button)
            button_bg = Icon(
                image="content/gui/images/buttons/buildmenu_button_bg.png")
            container.findChild(
                name="build_button_bg_container").addChild(button_bg)
        # Still need to add last container
        parent_container.addChild(container)
        super(BuildRelatedTab, self).refresh()
Example #34
0
    def show_text(self, index):
        """Shows the text for a button.
		@param index: index of button"""
        assert isinstance(index, int)
        # stop hiding if a new text has been shown
        ExtScheduler().rem_call(self, self.hide_text)

        text = self.active_messages[index].message
        text = text.replace(r'\n', self.CHARS_PER_LINE * ' ')
        text = text.replace('[br]', self.CHARS_PER_LINE * ' ')
        text = textwrap.fill(text, self.CHARS_PER_LINE)

        self.bg_middle = self.text_widget.findChild(name='msg_bg_middle')
        self.bg_middle.removeAllChildren()

        line_count = len(text.splitlines()) - 1
        for i in range(line_count * self.LINE_HEIGHT // self.IMG_HEIGHT):
            middle_icon = Icon(image=self.BG_IMAGE_MIDDLE)
            self.bg_middle.addChild(middle_icon)

        button = self.widget.findChild(name=str(index))
        # y position relative to parent
        button_y = button.position[1]
        # Show text next to corresponding icon
        x, y = self.reference_text_widget_position
        self.text_widget.position = (x, y + button_y)

        message_container = self.text_widget.findChild(name='message')
        message_container.size = (300, 21 + self.IMG_HEIGHT * line_count + 21)

        self.bg_middle.adaptLayout()
        label = self.text_widget.findChild(name='text')
        label.text = text
        label.adaptLayout()
        self.text_widget.show()
			def __init__(self, cursor_tool, **kwargs):
				super(CoordsTooltip, self).__init__(**kwargs)
				cursor_tool.session.ingame_gui.coordinates_tooltip = self
				self.cursor_tool = cursor_tool
				self.enabled = False

				self.icon = Icon(position=(1, 1)) # 0, 0 is currently not supported by tooltips
	def _connect_input_res(self, centered_container, container, production):
		"""Draws incoming arrows for production line container."""
		input_amount = len(production.get_consumed_resources())
		if input_amount == 0:
			# Do not draw input arrows if there is no input
			return

		# center the production line
		icon_height = ImageFillStatusButton.CELL_SIZE[1] + ImageFillStatusButton.PADDING
		center_y = (icon_height // 2) * (input_amount - 1)
		centered_container.position = (0, center_y)

		if input_amount % 2:
			# Add center arrow for 1, 3, 5, ... but not 2, 4, ...
			mid_arrow = Icon(image=self.__class__.ARROW_MID)
			mid_arrow.position = (58, 17 + center_y)
			container.insertChild(mid_arrow, 0)

		for res in xrange(input_amount // 2):
			# --\                      <= placed for res = 1
			# --\| <= place connector  <= placed for res = 0
			# ---O-->                  <= placed above (mid_arrow)
			# --/| <= place connector  <= placed for res = 0
			# --/                      <= placed for res = 1
			offset = -17 + (icon_height // 2) * (2 * res + (input_amount % 2) + 1)

			top_arrow = Icon(image=self.__class__.ARROW_TOP)
			top_arrow.position = (58, center_y - offset)
			container.insertChild(top_arrow, 0)

			bottom_arrow = Icon(image=self.__class__.ARROW_BOTTOM)
			bottom_arrow.position = (58, center_y + offset)
			container.insertChild(bottom_arrow, 0)

			# Place a connector image (the | in above sketch) that vertically connects
			# the input resource arrows. We need those if the production line has more
			# than three input resources. Connectors are placed in the inner loop parts.
			place_connectors = (1 + 2 * res) < (input_amount // 2)
			if place_connectors:
				# the connector downwards connects top_arrows
				down_connector = Icon(image=self.__class__.ARROW_CONNECT_DOWN)
				down_connector.position = (98, center_y - offset)
				container.insertChild(down_connector, 0)
				# the connector upwards connects up_arrows
				up_connector = Icon(image=self.__class__.ARROW_CONNECT_UP)
				up_connector.position = (98, center_y + offset)
				container.insertChild(up_connector, 0)
Example #37
0
	def update(self):
		self.removeAllChildren()
		weapons_added = False
		if hasattr(self.instance, 'get_weapon_storage'):
			storage = self.instance.get_weapon_storage()
			for weapon, amount in storage:
				weapons_added = True
				icon_image = get_res_icon_path(weapon, 24)
				weapon_name = self.instance.session.db.get_res_name(weapon)
				# You usually do not need to change anything here when translating
				helptext = T('{weapon}: {amount}').format(weapon=weapon_name, amount=amount)
				icon = Icon(image=icon_image, helptext=helptext)
				self.addChild(icon)
		if not weapons_added:
			icon_image = "content/gui/icons/resources/none.png"
			icon = Icon(image=icon_image, helptext=T("none"))
			self.addChild(icon)
Example #38
0
def create_resource_icon(res_id, db, size=50):
	"""Creates a pychan Icon for a resource. Helptext is set to res name.
	Returns None if  size  parameter is invalid.
	@param res_id: resource id
	@param db: dbreader for main db
	@param size: Size of icon in px. Valid: 16, 24, 32, 50."""
	from fife.extensions.pychan.widgets import Icon
	widget = None
	if size in (16, 24, 32, 50):
		icon_path = get_res_icon_path(res_id, size)
		try:
			widget = Icon(image=icon_path)
		except RuntimeError: # ImageManager: image not found, use placeholder
			print '[WW] Image not found: {icon_path}'.format(icon_path=icon_path)
			widget = Icon(image=get_res_icon_path('placeholder', size))
		widget.helptext = db.get_res_name(res_id)
	return widget
Example #39
0
	def show_tooltip(self):
		if not self.helptext:
			return
		# recreate full tooltip since new text needs to be relayouted
		if self.gui is None:
			self.gui = load_uh_widget('tooltip.xml')
		else:
			self.gui.removeAllChildren()
		translated_tooltip = _(self.helptext)
		#HACK this looks better than splitting into several lines & joining
		# them. works because replace_whitespace in fill defaults to True:
		replaced = translated_tooltip.replace(r'\n', self.CHARS_PER_LINE*' ')
		replaced = replaced.replace(r'[br]', self.CHARS_PER_LINE*' ')
		tooltip = textwrap.fill(replaced, self.CHARS_PER_LINE)

		line_count = len(tooltip.splitlines()) - 1
		top_image = Icon(image=self.TOP_IMAGE, position=(0, 0))
		self.gui.addChild(top_image)
		top_x, top_y = top_image.position
		top_y += self.SIZE_BG_TOP
		for i in xrange(0, line_count):
			middle_image = Icon(image=self.MIDDLE_IMAGE)
			middle_image.position = (top_x, top_y + self.LINE_HEIGHT * i)
			self.gui.addChild(middle_image)
		bottom_image = Icon(image=self.BOTTOM_IMAGE)
		bottom_image.position = (top_x, top_y + self.LINE_HEIGHT * line_count)
		self.gui.addChild(bottom_image)

		label = Label(text=tooltip, position=(10, 5))
		self.gui.addChild(label)
		self.gui.stylize('tooltip')
		size_y = self.SIZE_BG_TOP + self.LINE_HEIGHT * line_count + self.SIZE_BG_BOTTOM
		self.gui.size = (145, size_y)
		self.gui.show()
Example #40
0
	def init_widget(self):
		super(LumberjackOverviewTab, self).init_widget()
		container = AutoResizeContainer(position=(20, 210))
		icon = Icon(name='build_all_bg')
		button = ImageButton(name='build_all_button')
		container.addChild(icon)
		container.addChild(button)
		self.widget.addChild(container)
		self.update_data()
 def update_queue(self, container_active):
     """ Update the queue display"""
     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__.UNIT_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)
 def init_widget(self):
     super().init_widget()
     container = ABox(position=(20, 210))
     icon = Icon(name='build_all_bg')
     button = ImageButton(name='build_all_button')
     container.addChild(icon)
     container.addChild(button)
     self.widget.addChild(container)
     self.update_data()
Example #43
0
	def __init__(self):
		self.mainlistener = MainListener(self)

		self.windows = WindowManager()
		# temporary aliases for compatibility with rest of the code
		self.show_popup = self.windows.show_popup
		self.show_error_popup = self.windows.show_error_popup

		self._background = Icon(image=self._get_random_background(),
		                        position_technique='center:center')
		self._background.show()

		self.singleplayermenu = SingleplayerMenu(self.windows)
		self.multiplayermenu = MultiplayerMenu(self, self.windows)
		self.help_dialog = HelpDialog(self.windows)
		self.loadingscreen = LoadingScreen()
		self.settings_dialog = SettingsDialog(self.windows)
		self.mainmenu = MainMenu(self, self.windows)
		self.fps_display = FPSDisplay()
Example #44
0
	def __init__(self, renderer, layer):
		"""
		@param renderer: Renderer used to render the icons
		@param layer: map layer, needed to place icon
		"""
		self.layer = layer
		self.renderer = renderer

		# {instance: [list of icons]}
		self.icons = {}

		self.tooltip_instance = None # no weakref:
		# we need to remove the tooltip always anyway, and along with it the entry here
		self.tooltip_icon = Icon(position=(1, 1)) # 0, 0 is currently not supported by tooltips

		AddStatusIcon.subscribe(self.on_add_icon_message)
		HoverInstancesChanged.subscribe(self.on_hover_instances_changed)
		RemoveStatusIcon.subscribe(self.on_remove_icon_message)
		WorldObjectDeleted.subscribe(self.on_worldobject_deleted_message)
Example #45
0
 def get_unit_thumbnail(self, unit_id):
     """Returns path of the thumbnail icon for unit with id *unit_id*."""
     template = "content/gui/icons/thumbnails/{unit_id}.png"
     path = template.format(unit_id=unit_id)
     try:
         Icon(image=path)
     except RuntimeError:
         self.log.warning('Missing unit thumbnail {0}'.format(path))
         path = template.format(unit_id='unknown_unit')
     return path
        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)
Example #48
0
	def _show_modal_background(self):
		"""
		Loads transparent background that de facto prohibits access to other
		gui elements by eating all input events.
		"""
		height = horizons.globals.fife.engine_settings.getScreenHeight()
		width = horizons.globals.fife.engine_settings.getScreenWidth()
		image = horizons.globals.fife.imagemanager.loadBlank(width, height)
		image = fife.GuiImage(image)
		self._modal_background = Icon(image=image)
		self._modal_background.position = (0, 0)
		self._modal_background.show()
Example #49
0
		class CoordsTooltip(object):
			@classmethod
			def get_instance(cls, cursor_tool):
				if cursor_tool.session.coordinates_tooltip is not None:
					inst = cursor_tool.session.coordinates_tooltip
					inst.cursor_tool = cursor_tool
					return inst
				else:
					return CoordsTooltip(cursor_tool)

			def __init__(self, cursor_tool, **kwargs):
				super(CoordsTooltip, self).__init__(**kwargs)
				cursor_tool.session.coordinates_tooltip = self
				self.cursor_tool = cursor_tool
				self.enabled = False

				self.icon = Icon()

			def toggle(self):
				self.enabled = not self.enabled
				if not self.enabled and self.icon.tooltip_shown:
					self.icon.hide_tooltip()

			def show_evt(self, evt):
				if self.enabled:
					x, y = self.cursor_tool.get_world_location_from_event(evt).to_tuple()
					self.icon.helptext = str(x) + ', ' + str(y) + " "+_("Press H to remove this hint")
					self.icon.position_tooltip(evt)
					self.icon.show_tooltip()
	def __init__(self, session):
		self.session = session
		# {instance: [list of icons]}
		self.icons = {}
		# Renderer used to render the icons
		self.renderer = self.session.view.renderer['GenericRenderer']

		self.tooltip_instance = None # no weakref:
		# we need to remove the tooltip always anyway, and along with it the entry here
		self.tooltip_icon = Icon(position=(1,1)) # 0, 0 is currently not supported by tooltips

		AddStatusIcon.subscribe(self.on_add_icon_message)
		HoverInstancesChanged.subscribe(self.on_hover_instances_changed)
		RemoveStatusIcon.subscribe(self.on_remove_icon_message)
		WorldObjectDeleted.subscribe(self.on_worldobject_deleted_message)
	def __init__(self, session):
		self.session = session
		# {instance: [list of icons]}
		self.icons = {}
		# Renderer used to render the icons
		self.renderer = self.session.view.renderer['GenericRenderer']

		self.tooltip_instance = None # no weakref:
		# we need to remove the tooltip always anyway, and along with it the entry here
		self.tooltip_icon = Icon()

		self.session.message_bus.subscribe_globally(AddStatusIcon, self.on_add_icon_message)
		self.session.message_bus.subscribe_globally(HoverInstancesChanged, self.on_hover_instances_changed)
		self.session.message_bus.subscribe_globally(RemoveStatusIcon, self.on_remove_icon_message)
		self.session.message_bus.subscribe_globally(WorldObjectDeleted, self.on_worldobject_deleted_message)
Example #52
0
	def __init__(self):
		available_images = glob.glob('content/gui/images/background/mainmenu/bg_*.png')
		self.bg_images = deque(available_images)

		latest_bg = horizons.globals.fife.get_uh_setting("LatestBackground")
		try:
			# If we know the current background from an earlier session,
			# show all other available ones before picking that one again.
			self.bg_images.remove(latest_bg)
			self.bg_images.append(latest_bg)
		except ValueError:
			pass

		(res_width, res_height) = horizons.globals.fife.get_fife_setting('ScreenResolution').split('x')
		self._black_box = Container()
		self._black_box.size = int(res_width), int(res_height)
		self._black_box.base_color = (0, 0, 0, 255)

		self._image = Icon(position_technique='center:center')
		self.rotate_image()
Example #53
0
class Gui(object):
	"""This class handles all the out of game menu, like the main and pause menu, etc.
	"""
	log = logging.getLogger("gui")

	def __init__(self):
		self.mainlistener = MainListener(self)

		self.windows = WindowManager()
		# temporary aliases for compatibility with rest of the code
		self.show_popup = self.windows.show_popup
		self.show_error_popup = self.windows.show_error_popup

		# Main menu background image setup.
		available_images = glob.glob('content/gui/images/background/mainmenu/bg_*.png')
		self.bg_images = deque(available_images)

		latest_bg = horizons.globals.fife.get_uh_setting("LatestBackground")
		try:
			# If we know the current background from an earlier session,
			# show all other available ones before picking that one again.
			self.bg_images.remove(latest_bg)
			self.bg_images.append(latest_bg)
		except ValueError:
			pass
		self._background = Icon(position_technique='center:center')
		self.rotate_background()
		self._background.show()

		self.singleplayermenu = SingleplayerMenu(self.windows)
		self.multiplayermenu = MultiplayerMenu(self, self.windows)
		self.help_dialog = HelpDialog(self.windows)
		self.loadingscreen = LoadingScreen()
		self.settings_dialog = SettingsDialog(self.windows)
		self.mainmenu = MainMenu(self, self.windows)
		self.fps_display = FPSDisplay()

	def show_main(self):
		"""Shows the main menu """
		GuiAction.subscribe(self._on_gui_action)

		if not self._background.isVisible():
			self._background.show()

		self.windows.show(self.mainmenu)

	def show_select_savegame(self, mode):
		window = SelectSavegameDialog(mode, self.windows)
		return self.windows.show(window)

	def load_game(self):
		saved_game = self.show_select_savegame(mode='load')
		if saved_game is None:
			return False # user aborted dialog

		options = StartGameOptions(saved_game)
		horizons.main.start_singleplayer(options)
		return True

	def on_help(self):
		self.windows.toggle(self.help_dialog)

	def show_credits(self):
		"""Shows the credits dialog. """
		window = CreditsPickbeltWidget(self.windows)
		self.windows.show(window)

	def on_escape(self):
		self.windows.on_escape()

	def on_return(self):
		self.windows.on_return()

	def close_all(self):
		GuiAction.discard(self._on_gui_action)
		self.windows.close_all()
		self._background.hide()

	def show_loading_screen(self):
		if not self._background.isVisible():
			self._background.show()
		self.windows.show(self.loadingscreen)

	def rotate_background(self):
		"""Select next background image to use in the game menu.

		Triggered by the "Change background" main menu button.
		"""
		# Note: bg_images is a deque.
		self.bg_images.rotate()
		self._background.image = self.bg_images[0]
		# Save current background choice to settings.
		# This keeps the background image consistent between sessions.
		horizons.globals.fife.set_uh_setting("LatestBackground", self.bg_images[0])
		horizons.globals.fife.save_settings()

	def _on_gui_action(self, msg):
		AmbientSoundComponent.play_special('click')

	def show_editor_start_menu(self):
		editor_start_menu = EditorStartMenu(self.windows)
		self.windows.show(editor_start_menu)
class StatusIconManager(object):
	"""Manager class that manages all status icons. It listenes to AddStatusIcon
	and RemoveStatusIcon messages on the main message bus"""

	def __init__(self, session):
		self.session = session
		# {instance: [list of icons]}
		self.icons = {}
		# Renderer used to render the icons
		self.renderer = self.session.view.renderer['GenericRenderer']

		self.tooltip_instance = None # no weakref:
		# we need to remove the tooltip always anyway, and along with it the entry here
		self.tooltip_icon = Icon(position=(1,1)) # 0, 0 is currently not supported by tooltips

		AddStatusIcon.subscribe(self.on_add_icon_message)
		HoverInstancesChanged.subscribe(self.on_hover_instances_changed)
		RemoveStatusIcon.subscribe(self.on_remove_icon_message)
		WorldObjectDeleted.subscribe(self.on_worldobject_deleted_message)

	def end(self):
		self.tooltip_instance = None
		self.tooltip_icon.hide_tooltip()
		self.tooltip_icon = None

		self.renderer = None
		self.icons = None
		self.session = None

		AddStatusIcon.unsubscribe(self.on_add_icon_message)
		HoverInstancesChanged.unsubscribe(self.on_hover_instances_changed)
		RemoveStatusIcon.unsubscribe(self.on_remove_icon_message)
		WorldObjectDeleted.unsubscribe(self.on_worldobject_deleted_message)

	def on_add_icon_message(self, message):
		"""This is called by the message bus with AddStatusIcon messages"""
		assert isinstance(message, AddStatusIcon)
		icon_instance = message.icon.instance
		if not icon_instance in self.icons:
			self.icons[icon_instance] = []
		assert not message.icon in self.icons[icon_instance]
		self.icons[icon_instance].append(message.icon)
		# Sort, make sure highest icon is at top
		self.icons[icon_instance] = sorted(self.icons[icon_instance], key=StatusIcon.get_sorting_key(), reverse=True)
		# Now render the most important one
		self.__render_status(icon_instance, self.icons[icon_instance][0])

	def on_worldobject_deleted_message(self, message):
		assert isinstance(message, WorldObjectDeleted)
		# remove icon
		if message.worldobject in self.icons:
			self.renderer.removeAll(self.get_status_string(message.worldobject))
			del self.icons[message.worldobject]
		# remove icon tooltip
		if message.worldobject is self.tooltip_instance:
			self.on_hover_instances_changed( HoverInstancesChanged(self, set()) )

	def on_remove_icon_message(self, message):
		"""Called by the MessageBus with RemoveStatusIcon messages."""
		assert isinstance(message, RemoveStatusIcon)
		icon_instance = message.instance
		if icon_instance in self.icons:
			for registered_icon in self.icons[icon_instance][:]:
				if message.icon_class is registered_icon.__class__:
					self.icons[icon_instance].remove(registered_icon)
					if len(self.icons[icon_instance]) == 0:
						# No icon left for this building, remove it
						self.renderer.removeAll(self.get_status_string(icon_instance))
						del self.icons[icon_instance]
					else:
						# Render next icon
						self.__render_status(icon_instance, self.icons[icon_instance][0])
					return

	def __render_status(self, instance, status):
		status_string = self.get_status_string(instance)

		# Clean icons
		self.renderer.removeAll(status_string)

		# pixel-offset on screen (will be constant across zoom-levels)
		rel = fife.Point(0, -30)

		layer = self.session.view.layers[LAYERS.OBJECTS]

		pos = instance.position

		# trial and error has brought me to this (it's supposed to hit the center)
		loc = fife.Location(layer)
		loc.setExactLayerCoordinates(
		  fife.ExactModelCoordinate(
		    pos.origin.x + float(pos.width) / 4,
		    pos.origin.y + float(pos.height) / 4,
		  )
		)

		node = fife.RendererNode(loc, rel)

		try: # to load an animation
			anim = horizons.main.fife.animationloader.loadResource(status.icon)
			self.renderer.addAnimation(status_string, node, anim)
		except ValueError:
			img = horizons.main.fife.imagemanager.load(status.icon)
			self.renderer.addImage(status_string, node, img)

	def get_status_string(self, instance):
		"""Returns render name for status icons of this instance"""
		status_string = "status_"+ str(id(instance))
		return status_string

	def on_hover_instances_changed(self, msg):
		"""Check if we need to display a tooltip"""
		instances = msg.instances

		# only those that have icons
		instances = (i for i in instances if i in self.icons)
		# and belong to the player
		instances = [i for i in instances if \
		             hasattr(i, "owner" ) and \
		             hasattr(i.owner, "is_local_player") and \
		             i.owner.is_local_player]

		if not instances:
			# hide
			self.tooltip_instance = None
			self.tooltip_icon.hide_tooltip()
		else:
			# get tooltip text, set, position and show
			self.tooltip_instance = instances[0] # pick any (usually ordered by fife)

			icons_of_instance = self.icons[self.tooltip_instance]
			icon = max(icons_of_instance, key=StatusIcon.get_sorting_key())

			self.tooltip_icon.helptext = icon.helptext

			pos = self.session.cursor.last_event_pos
			self.tooltip_icon.position_tooltip( (pos.x, pos.y) )
			self.tooltip_icon.show_tooltip()
	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()
Example #56
0
class Window(object):

	def __init__(self, windows=None):
		# Reference to the window manager. Use it to show new windows or close
		# this window.
		self._windows = windows

		self._modal_background = None

	def show(self, **kwargs):
		"""Show the window.

		After this call, the window should be visible. If you decide to not show
		the window here (e.g. an error occurred), you'll need to call
		`self._windows.close()` to remove the window from the manager.
		"""
		raise NotImplementedError

	def hide(self):
		"""Hide the window.

		After this call, the window should not be visible anymore. However, it remains
		in the stack of open windows and will be visible once it becomes the topmost
		window again.

		You should *never* call this directly in your code, other than in `close()`
		when you overwrote it in your subclass.
		"""
		raise NotImplementedError

	def close(self):
		"""Closes the window.

		You should *never* call this directly in your code. Use `self._windows.close()`
		to ask the WindowManager to remove the window instead.
		"""
		self.hide()

	def on_escape(self):
		"""Define what happens when ESC is pressed.

		By default, the window will be closed.
		"""
		self._windows.close()

	def on_return(self):
		"""Define what happens when RETURN is pressed."""
		pass

	def _show_modal_background(self):
		"""
		Loads transparent background that de facto prohibits access to other
		gui elements by eating all input events.
		"""
		height = horizons.globals.fife.engine_settings.getScreenHeight()
		width = horizons.globals.fife.engine_settings.getScreenWidth()
		image = horizons.globals.fife.imagemanager.loadBlank(width, height)
		image = fife.GuiImage(image)
		self._modal_background = Icon(image=image)
		self._modal_background.position = (0, 0)
		self._modal_background.show()

	def _hide_modal_background(self):
		self._modal_background.hide()
Example #57
0
class Gui(object):
	"""This class handles all the out of game menu, like the main and pause menu, etc.
	"""
	log = logging.getLogger("gui")

	def __init__(self):
		self.mainlistener = MainListener(self)

		self.windows = WindowManager()
		# temporary aliases for compatibility with rest of the code
		self.show_popup = self.windows.show_popup
		self.show_error_popup = self.windows.show_error_popup

		self._background = Icon(image=self._get_random_background(),
		                        position_technique='center:center')
		self._background.show()

		self.subscribe()

		self.singleplayermenu = SingleplayerMenu(self.windows)
		self.multiplayermenu = MultiplayerMenu(self, self.windows)
		self.help_dialog = HelpDialog(self.windows)
		self.loadingscreen = LoadingScreen()
		self.settings_dialog = SettingsDialog(self.windows)
		self.mainmenu = MainMenu(self, self.windows)
		self.fps_display = FPSDisplay()

	def subscribe(self):
		"""Subscribe to the necessary messages."""
		GuiAction.subscribe(self._on_gui_action)

	def unsubscribe(self):
		GuiAction.unsubscribe(self._on_gui_action)

	def show_main(self):
		"""Shows the main menu """
		if not self._background.isVisible():
			self._background.show()

		self.windows.show(self.mainmenu)

	def show_select_savegame(self, mode):
		window = SelectSavegameDialog(mode, self.windows)
		return self.windows.show(window)

	def load_game(self):
		saved_game = self.show_select_savegame(mode='load')
		if saved_game is None:
			return False # user aborted dialog

		options = StartGameOptions(saved_game)
		horizons.main.start_singleplayer(options)
		return True

	def on_help(self):
		self.windows.toggle(self.help_dialog)

	def show_credits(self):
		"""Shows the credits dialog. """
		window = CreditsPickbeltWidget(self.windows)
		self.windows.show(window)

	def on_escape(self):
		self.windows.on_escape()

	def close_all(self):
		self.windows.close_all()
		self._background.hide()

	def show_loading_screen(self):
		if not self._background.isVisible():
			self._background.show()
		self.windows.show(self.loadingscreen)

	def randomize_background(self):
		"""Randomly select a background image to use. This function is triggered by
		change background button from main menu."""
		self._background.image = self._get_random_background()

	def _get_random_background(self):
		"""Randomly select a background image to use through out the game menu."""
		available_images = glob.glob('content/gui/images/background/mainmenu/bg_*.png')
		#get latest background
		latest_background = horizons.globals.fife.get_uh_setting("LatestBackground")
		#if there is a latest background then remove it from available list
		if latest_background is not None:
			available_images.remove(latest_background)
		background_choice = random.choice(available_images)
		#save current background choice
		horizons.globals.fife.set_uh_setting("LatestBackground", background_choice)
		horizons.globals.fife.save_settings()
		return background_choice

	def _on_gui_action(self, msg):
		AmbientSoundComponent.play_special('click')

	def show_editor_start_menu(self):
		editor_start_menu = EditorStartMenu(self.windows)
		self.windows.show(editor_start_menu)
	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:

			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]
			produced_unit_id = self.producer._get_production(production_lines[0]).get_produced_units().keys()[0]
			(name,) = self.instance.session.db.cached_query("SELECT name FROM unit WHERE id = ?", produced_unit_id)[0]
			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 = "content/gui/images/objects/ships/116/%s.png" % (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]
			still_needed_res = production.get_consumed_resources()
			# Now sort!
			still_needed_res = sorted(still_needed_res.iteritems(), key=operator.itemgetter(1))
			main_container.findChild(name="BB_needed_res_label").text = _('Resources still needed:')
			i = 0
			for res, amount in still_needed_res:
				if amount == 0:
					continue # Don't show res that are not really needed anymore
				assert i <= 3, "Only 3 still needed res for ships are currently supported"

				icon_path = get_res_icon_path(res, 16)
				needed_res_container.findChild(name="BB_needed_res_icon_"+str(i+1)).image = icon_path
				needed_res_container.findChild(name="BB_needed_res_lbl_"+str(i+1)).text = unicode(-1*amount)+u't' # -1 makes them positive
				i += 1
				if i >= 3:
					break
			for j in xrange(i, 3):
				# these are not filled by a resource, so we need to make it invisible
				needed_res_container.findChild(name="BB_needed_res_icon_"+str(j+1)).image = None
				needed_res_container.findChild(name="BB_needed_res_lbl_"+str(j+1)).text = u""

			cancel_button = self.widget.findChild(name="BB_cancel_button")
			cancel_button.capture(
			  Callback(CancelCurrentProduction(self.producer).execute, self.instance.session),
			  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()