Example #1
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 #2
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 #3
0
	def _draw_pretty_arrows(self, parent_container, amount, x=0, y=0, out=False):
		"""Draws incoming or outgoing arrows for production line container."""
		if amount % 2:
			# Add center arrow for 1, 3, 5, ... but not 2, 4, ...
			if out:
				mid_arrow = Icon(image=self.__class__.ARROWHEAD_MID)
			else:
				mid_arrow = Icon(image=self.__class__.ARROW_MID)
			mid_arrow.position = (x, 17 + y)
			parent_container.insertChild(mid_arrow, 0)

		for res in xrange(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 + (self.ICON_HEIGHT // 2) * (2 * res + (amount % 2) + 1)

			if out:
				top_arrow = Icon(image=self.__class__.ARROWHEAD_TOP)
			else:
				top_arrow = Icon(image=self.__class__.ARROW_TOP)
			top_arrow.position = (x, y - offset)
			parent_container.insertChild(top_arrow, 0)

			if out:
				bottom_arrow = Icon(image=self.__class__.ARROWHEAD_BOTTOM)
			else:
				bottom_arrow = Icon(image=self.__class__.ARROW_BOTTOM)
			bottom_arrow.position = (x, y + offset)
			parent_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 = amount > (3 + 2 * res)
			if place_connectors:
				# the connector downwards connects top_arrows
				if out:
					down_connector = Icon(image=self.__class__.ARROWHEAD_CONNECT_DOWN)
				else:
					down_connector = Icon(image=self.__class__.ARROW_CONNECT_DOWN)
				down_connector.position = (98, y - offset)
				parent_container.insertChild(down_connector, 0)
				# the connector upwards connects up_arrows
				if out:
					up_connector = Icon(image=self.__class__.ARROWHEAD_CONNECT_UP)
				else:
					up_connector = Icon(image=self.__class__.ARROW_CONNECT_UP)
				up_connector.position = (98, y + offset)
				parent_container.insertChild(up_connector, 0)
	def _draw_pretty_arrows(self, parent_container, amount, x=0, y=0, out=False):
		"""Draws incoming or outgoing arrows for production line container."""
		if amount % 2:
			# Add center arrow for 1, 3, 5, ... but not 2, 4, ...
			if out:
				mid_arrow = Icon(image=self.__class__.ARROWHEAD_MID)
			else:
				mid_arrow = Icon(image=self.__class__.ARROW_MID)
			mid_arrow.position = (x, 17 + y)
			parent_container.insertChild(mid_arrow, 0)

		for res in xrange(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 + (self.ICON_HEIGHT // 2) * (2 * res + (amount % 2) + 1)

			if out:
				top_arrow = Icon(image=self.__class__.ARROWHEAD_TOP)
			else:
				top_arrow = Icon(image=self.__class__.ARROW_TOP)
			top_arrow.position = (x, y - offset)
			parent_container.insertChild(top_arrow, 0)

			if out:
				bottom_arrow = Icon(image=self.__class__.ARROWHEAD_BOTTOM)
			else:
				bottom_arrow = Icon(image=self.__class__.ARROW_BOTTOM)
			bottom_arrow.position = (x, y + offset)
			parent_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 = amount > (3 + 2 * res)
			if place_connectors:
				# the connector downwards connects top_arrows
				if out:
					down_connector = Icon(image=self.__class__.ARROWHEAD_CONNECT_DOWN)
				else:
					down_connector = Icon(image=self.__class__.ARROW_CONNECT_DOWN)
				down_connector.position = (98, y - offset)
				parent_container.insertChild(down_connector, 0)
				# the connector upwards connects up_arrows
				if out:
					up_connector = Icon(image=self.__class__.ARROWHEAD_CONNECT_UP)
				else:
					up_connector = Icon(image=self.__class__.ARROW_CONNECT_UP)
				up_connector.position = (98, y + offset)
				parent_container.insertChild(up_connector, 0)
    def _connect_multiple_input_res_for_production(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
            # --/| <= 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)
	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 _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 _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 _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 #10
0
	def refresh(self):
		"""This function is called by the TabWidget to redraw the widget."""
		self._refresh_utilization()

		# 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")

			centered_container = container.findChild(name='centered_production_icons')
			center_y = self._center_production_line(container, production)
			centered_container.position = (centered_container.position[0], center_y - 44 // 2)
			self._set_resource_amounts(container, production)

			if production.is_paused():
				centered_container.removeChild(centered_container.findChild(name="toggle_active_active"))
				toggle_icon = centered_container.findChild(name="toggle_active_inactive")
				toggle_icon.name = "toggle_active"
			else:
				centered_container.removeChild(centered_container.findChild(name="toggle_active_inactive"))
				toggle_icon = centered_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
					centered_container.addChild(bg)
					centered_container.removeChild(toggle_icon) # fix z-ordering
					centered_container.addChild(toggle_icon)
					anim = PychanAnimation(toggle_icon, self.__class__.ACTIVE_PRODUCTION_ANIM_DIR)
					centered_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)
			centered_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
			parent_container.addChild(container)
		super(ProductionOverviewTab, self).refresh()