def refresh(self): """This function is called by the TabWidget to redraw the widget.""" cap_util = 0 if hasattr(self.instance, 'capacity_utilisation'): cap_util = int(round( self.instance.capacity_utilisation * 100)) self.widget.child_finder('capacity_utilisation').text = unicode(cap_util) + u'%' # remove old production line data parent_container = self.widget.child_finder('production_lines') while len(parent_container.children) > 0: parent_container.removeChild(parent_container.children[0]) # create a container for each production # sort by production line id to have a consistent (basically arbitrary) order for production in sorted(self.instance._get_productions(), \ key=(lambda x: x.get_production_line_id())): gui = load_xml_translated(self.production_line_gui_xml) # fill in values to gui reflecting the current game state container = gui.findChild(name="production_line_container") if production.is_paused(): container.removeChild( container.findChild(name="toggle_active_active") ) container.findChild(name="toggle_active_inactive").name = "toggle_active" else: container.removeChild( container.findChild(name="toggle_active_inactive") ) container.findChild(name="toggle_active_active").name = "toggle_active" # fill it with input and output resources in_res_container = container.findChild(name="input_res") for in_res in production.get_consumed_resources(): filled = float(self.instance.inventory[in_res]) * 100 / \ self.instance.inventory.get_limit(in_res) in_res_container.addChild( \ ImageFillStatusButton.init_for_res(self.instance.session.db,\ in_res, \ self.instance.inventory[in_res], \ filled, \ use_inactive_icon=False) \ ) out_res_container = container.findChild(name="output_res") for out_res in production.get_produced_res(): filled = float(self.instance.inventory[out_res]) * 100 / \ self.instance.inventory.get_limit(out_res) out_res_container.addChild( \ ImageFillStatusButton.init_for_res(self.instance.session.db, \ out_res, \ self.instance.inventory[out_res], \ filled, \ use_inactive_icon=False) \ ) # active toggle_active button container.mapEvents( \ { 'toggle_active': \ Callback(ToggleActive(self.instance, production).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, vbox, current_hbox, index=0): """Draws the inventory. """ for resid, limit in sorted(self._limits.iteritems()): if self._selling: amount = max(0, self._inventory[resid] - limit) else: amount = max(0, limit - self._inventory[resid]) # check if this res should be displayed button = ImageFillStatusButton.init_for_res(self.db, resid, amount, filled=0, uncached=self.uncached) button.button.name = "buy_sell_inventory_%s_entry_%s" % (self._selling, index) # for tests current_hbox.addChild(button) if index % self.items_per_line == self.items_per_line - 1: vbox.addChild(current_hbox) current_hbox = HBox(padding = 0) index += 1 vbox.addChild(current_hbox) self.addChild(vbox) label = Label() #xgettext:python-format label.text = _('Limit: {amount}t per slot').format(amount=self._inventory.get_limit(None)) label.position = (110, 150) self.__icon.position = (90, 150) self.addChildren(label, self.__icon)
def _add_resource_icons(self, container, resources): for res in resources: inventory = self.instance.get_component(StorageComponent).inventory filled = (inventory[res] * 100) // inventory.get_limit(res) container.addChild( ImageFillStatusButton.init_for_res(self.instance.session.db, res, inventory[res], filled, use_inactive_icon=False, uncached=True))
def _draw(self): """Draws the inventory.""" if len(self.children) != 0: self.removeChildren(*self.children) vbox = pychan.widgets.VBox(padding = 0) vbox.width = self.width current_hbox = pychan.widgets.HBox(padding = 0) index = 0 for resid, amount in sorted(self._inventory): # sort by resid for unchangeable positions # check if this res should be displayed if not self.db.cached_query('SELECT shown_in_inventory FROM resource WHERE id = ?', resid)[0][0]: continue filled = int(float(amount) / float(self._inventory.get_limit(resid)) * 100.0) button = ImageFillStatusButton.init_for_res(self.db, resid, amount, filled=filled) current_hbox.addChild(button) # old code to do this, which was bad but kept for reference #if index % ((vbox.width/(self.__class__.icon_width + 10))) < 0 and index != 0: if index % self.ITEMS_PER_LINE == (self.ITEMS_PER_LINE - 1) and index != 0: vbox.addChild(current_hbox) current_hbox = pychan.widgets.HBox(padding = 0) index += 1 if (index <= self.ITEMS_PER_LINE): # Hide/Remove second line icons = self.parent.findChildren(name='slot') if len(icons) > self.ITEMS_PER_LINE: self.parent.removeChildren(icons[self.ITEMS_PER_LINE-1:]) vbox.addChild(current_hbox) self.addChild(vbox) self.adaptLayout() self.stylize('menu_black')
def _draw(self): """Draws the inventory.""" if len(self.children) != 0: self.removeChildren(*self.children) vbox = pychan.widgets.VBox(padding = 0) vbox.width = self.width current_hbox = pychan.widgets.HBox(padding = 0) index = 0 for resid, limit in sorted(self._limits.iteritems()): amount = max(0, self._inventory[resid] - limit) if self._selling else max(0, limit - self._inventory[resid]) # check if this res should be displayed button = ImageFillStatusButton.init_for_res(self.db, resid, amount, \ filled=0, uncached=self.uncached) button.button.name = "buy_sell_inventory_%s_entry_%s" % (self._selling, index) # for tests current_hbox.addChild(button) if index % self.ITEMS_PER_LINE == (self.ITEMS_PER_LINE - 1) and index != 0: vbox.addChild(current_hbox) current_hbox = pychan.widgets.HBox(padding = 0) index += 1 vbox.addChild(current_hbox) self.addChild(vbox) label = pychan.widgets.Label() #xgettext:python-format label.text = _('Limit: {amount}t per slot').format(amount=self._inventory.get_limit(None)) label.position = (110, 150) self.__icon.position = (90, 150) self.addChildren(label, self.__icon) self.adaptLayout() self.stylize('menu_black')
def show_resource_menu(self, slot, entry): position = self.widgets.index(entry) if self.resource_menu_shown: self.hide_resource_menu() self.resource_menu_shown = True vbox = self._gui.findChild(name="resources") lbl = widgets.Label(name="select_res_label", text=_("Select a resource:")) vbox.addChild(lbl) scrollarea = widgets.ScrollArea(name="resources_scrollarea") res_box = widgets.VBox() scrollarea.addChild(res_box) vbox.addChild(scrollarea) # TODO: use create_resource_selection_dialog from util/gui.py # hardcoded for 5 works better than vbox.width / button_width amount_per_line = 5 current_hbox = widgets.HBox(max_size="326,46") index = 1 settlement = entry.settlement() inventory = settlement.get_component(StorageComponent).inventory if settlement else None from horizons.gui.widgets.imagefillstatusbutton import ImageFillStatusButton for res_id in sorted(self.icon_for_resource): if ( res_id in self.instance.route.waypoints[position]["resource_list"] and slot.findChild(name="button").up_image.source is not self.icon_for_resource[res_id] ): continue cb = Callback(self.add_resource, slot, res_id, entry) if res_id == 0 or inventory is None: # no fillbar e.g. on dead settlement (shouldn't happen) or dummy slot button = ImageButton(size=(46, 46)) icon = self.icon_for_resource[res_id] button.up_image, button.down_image, button.hover_image = icon, icon, icon button.capture(cb) else: # button with fillbar amount = inventory[res_id] filled = int(float(inventory[res_id]) / float(inventory.get_limit(res_id)) * 100.0) button = ImageFillStatusButton.init_for_res( self.session.db, res_id, amount=amount, filled=filled, use_inactive_icon=False ) button.button.capture(cb) current_hbox.addChild(button) if index >= amount_per_line: index -= amount_per_line res_box.addChild(current_hbox) current_hbox = widgets.HBox(max_size="326,26") index += 1 current_hbox.addSpacer(widgets.Spacer()) # TODO this spacer does absolutely nothing. res_box.addChild(current_hbox) self._gui.adaptLayout() self._resource_selection_area_layout_hack_fix()
def _draw(self): """Draws the inventory.""" if len(self.children) != 0: self.removeChildren(*self.children) vbox = pychan.widgets.VBox(padding=0) vbox.width = self.width current_hbox = pychan.widgets.HBox(padding=0) index = 0 for resid, amount in sorted( self._inventory): # sort by resid for unchangeable positions # check if this res should be displayed if not self.db.cached_query( 'SELECT shown_in_inventory FROM resource WHERE id = ?', resid)[0][0]: continue if isinstance(self._inventory, TotalStorage): filled = 0 else: filled = int( float(amount) / float(self._inventory.get_limit(resid)) * 100.0) button = ImageFillStatusButton.init_for_res(self.db, resid, amount, filled=filled) current_hbox.addChild(button) # old code to do this, which was bad but kept for reference #if index % ((vbox.width/(self.__class__.icon_width + 10))) < 0 and index != 0: if index % self.ITEMS_PER_LINE == (self.ITEMS_PER_LINE - 1) and index != 0: vbox.addChild(current_hbox) current_hbox = pychan.widgets.HBox(padding=0) index += 1 if (index <= self.ITEMS_PER_LINE): # Hide/Remove second line icons = self.parent.findChildren(name='slot') if len(icons) > self.ITEMS_PER_LINE: self.parent.removeChildren(icons[self.ITEMS_PER_LINE - 1:]) vbox.addChild(current_hbox) self.addChild(vbox) if isinstance(self._inventory, TotalStorage): # Add total storage indicator sum_stored_res = self._inventory.get_sum_of_stored_resources() label = pychan.widgets.Label() label.text = unicode(sum_stored_res) + u"/" + unicode( self._inventory.get_limit(None)) label.position = (170, 50) self.__icon.position = (150, 50) self.addChildren(label, self.__icon) elif isinstance(self._inventory, PositiveSizedSlotStorage): label = pychan.widgets.Label() label.text = _('Limit: %st per slot') % self._inventory.get_limit( None) label.position = (110, 150) self.__icon.position = (90, 150) self.addChildren(label, self.__icon) self.adaptLayout() self.stylize('menu_black')
def create_resource_selection_dialog( on_click, inventory, db, widget="select_trade_resource.xml", res_filter=None, amount_per_line=None ): """Returns a container containing resource icons. @param on_click: called with resource id as parameter on clicks @param inventory: to determine fill status of resource slots @param db: main db instance @param widget: which xml file to use as a template. Default: tabwidget. Required since the resource bar also uses this code (no tabs there though). @param res_filter: callback to decide which icons to use. Default: show all @param amount_per_line: how many resource icons per line. Default: try to fit layout """ from horizons.gui.widgets.imagefillstatusbutton import ImageFillStatusButton dummy_icon_path = "content/gui/icons/resources/none_gray.png" dlg = load_uh_widget(widget) button_width = ImageFillStatusButton.CELL_SIZE[0] # used for dummy button vbox = dlg.findChild(name="resources") amount_per_line = amount_per_line or vbox.width // button_width # Add the zero element to the beginning that allows to remove the currently # sold/bought resource: resources = [0] + db.get_res(only_tradeable=True) current_hbox = HBox(name="hbox_0", padding=0) index = 1 for res_id in resources: # don't show resources that are already in the list if res_filter is not None and not res_filter(res_id): continue # create button (dummy one or real one) if res_id == 0 or inventory is None: button = ImageButton(size=(button_width, button_width), name="resource_icon_00") button.up_image, button.down_image, button.hover_image = (dummy_icon_path,) * 3 else: amount = inventory[res_id] filled = int(float(inventory[res_id]) / float(inventory.get_limit(res_id)) * 100.0) button = ImageFillStatusButton.init_for_res( db, res_id, amount=amount, filled=filled, uncached=True, use_inactive_icon=False ) # on click: add this res cb = Callback(on_click, res_id) if hasattr(button, "button"): # for imagefillstatusbuttons button.button.capture(cb) button.button.name = "resource_%d" % res_id else: button.capture(cb) button.name = "resource_%d" % res_id current_hbox.addChild(button) if index % amount_per_line == 0: vbox.addChild(current_hbox) box_id = index // amount_per_line current_hbox = HBox(name="hbox_%s" % box_id, padding=0) index += 1 vbox.addChild(current_hbox) vbox.adaptLayout() return dlg
def _add_resource_icons(self, container, resources, marker=False): calculate_position = lambda amount: (amount * 100) // inventory.get_limit(res) for res in resources: inventory = self.instance.get_component(StorageComponent).inventory filled = calculate_position(inventory[res]) marker_level = calculate_position(-resources[res]) if marker else 0 image_button = ImageFillStatusButton.init_for_res(self.instance.session.db, res, inventory[res], filled, marker=marker_level, use_inactive_icon=False, uncached=True) container.addChild(image_button)
def create_resource_selection_dialog(on_click, inventory, db, widget="select_trade_resource.xml", res_filter=None): """Returns a container containing resource icons @param on_click: called with resource id as parameter on clicks @param inventory: to determine fill status of resource slots @param db: main db instance @param widget: which xml file to use as a template. Default: tabwidget. Required since the resource bar also uses this code (no tabs there though). @param res_filter: callback to decide which icons to use. Default: show all """ from horizons.gui.widgets.imagefillstatusbutton import ImageFillStatusButton from fife.extensions.pychan.widgets import ImageButton dummy_icon_path = "content/gui/icons/resources/none_gray.png" dlg = load_uh_widget(widget) button_width = ImageFillStatusButton.DEFAULT_BUTTON_SIZE[0] # used for dummy button vbox = dlg.findChild(name="resources") amount_per_line = vbox.width / button_width current_hbox = pychan.widgets.HBox(name="hbox_0", padding=0) index = 1 resources = db.get_res(True) # Add the zero element to the beginning that allows to remove the currently # sold/bought resource for res_id in [0] + list(resources): # don't show resources that are already in the list if res_filter is not None and not res_filter(res_id): continue # create button (dummy one or real one) if res_id == 0: button = ImageButton(size=(button_width, button_width), name="resource_icon_00") button.up_image, button.down_image, button.hover_image = (dummy_icon_path,) * 3 else: amount = inventory[res_id] filled = int(float(inventory[res_id]) / float(inventory.get_limit(res_id)) * 100.0) button = ImageFillStatusButton.init_for_res( db, res_id, amount=amount, filled=filled, use_inactive_icon=False ) # on click: add this res cb = Callback(on_click, res_id) if hasattr(button, "button"): # for imagefillstatusbuttons button.button.capture(cb) else: button.capture(cb) current_hbox.addChild(button) if index % amount_per_line == 0 and index is not 0: vbox.addChild(current_hbox) current_hbox = pychan.widgets.HBox(name="hbox_%s" % (index / amount_per_line), padding=0) index += 1 # current_hbox.addSpacer(pychan.widgets.layout.Spacer) #TODO: proper alignment vbox.addChild(current_hbox) vbox.adaptLayout() return dlg
def _draw(self): """Draws the inventory.""" if len(self.children) != 0: self.removeChildren(*self.children) vbox = pychan.widgets.VBox(padding = 0) vbox.width = self.width current_hbox = pychan.widgets.HBox(padding = 0) index = 0 for resid, amount in sorted(self._inventory): # sort by resid for unchangeable positions # check if this res should be displayed if not self.db.cached_query('SELECT shown_in_inventory FROM resource WHERE id = ?', resid)[0][0]: continue if self.ordinal is not None: range_ = self.ordinal[1] - self.ordinal[0] filled = ( float(amount - self.ordinal[0]) / range_ ) * 100 amount = "" elif isinstance(self._inventory, TotalStorage): filled = 0 else: filled = int(float(amount) / float(self._inventory.get_limit(resid)) * 100.0) button = ImageFillStatusButton.init_for_res(self.db, resid, amount, \ filled=filled, uncached=self.uncached) current_hbox.addChild(button) # old code to do this, which was bad but kept for reference #if index % ((vbox.width/(self.__class__.icon_width + 10))) < 0 and index != 0: if index % self.ITEMS_PER_LINE == (self.ITEMS_PER_LINE - 1) and index != 0: vbox.addChild(current_hbox) current_hbox = pychan.widgets.HBox(padding = 0) index += 1 if (index <= self.ITEMS_PER_LINE): # Hide/Remove second line icons = self.parent.findChildren(name='slot') if len(icons) > self.ITEMS_PER_LINE: self.parent.removeChildren(icons[self.ITEMS_PER_LINE-1:]) vbox.addChild(current_hbox) self.addChild(vbox) if self.display_legend: if isinstance(self._inventory, TotalStorage): # Add total storage indicator sum_stored_res = self._inventory.get_sum_of_stored_resources() label = pychan.widgets.Label() label.text = unicode(sum_stored_res) + u"/" + unicode(self._inventory.get_limit(None)) label.position = (170, 53) self.__icon.position = (150, 53) self.addChildren(label, self.__icon) elif isinstance(self._inventory, PositiveSizedSlotStorage): label = pychan.widgets.Label() #xgettext:python-format label.text = _('Limit: {amount}t per slot').format(amount=self._inventory.get_limit(None)) label.position = (20, 203) self.__icon.position = (0, 203) self.addChildren(label, self.__icon) self.adaptLayout() self.stylize('menu_black')
def create_resource_selection_dialog(on_click, inventory, db, widget='select_trade_resource.xml', res_filter=None, amount_per_line=None): """Returns a container containing resource icons. @param on_click: called with resource id as parameter on clicks @param inventory: to determine fill status of resource slots @param db: main db instance @param widget: which xml file to use as a template. Default: tabwidget. Required since the resource bar also uses this code (no tabs there though). @param res_filter: callback to decide which icons to use. Default: show all @param amount_per_line: how many resource icons per line. Default: try to fit layout """ from horizons.gui.widgets.imagefillstatusbutton import ImageFillStatusButton dummy_icon_path = "content/gui/icons/resources/none_gray.png" dlg = load_uh_widget(widget) button_width = ImageFillStatusButton.CELL_SIZE[0] # used for dummy button vbox = dlg.findChild(name="resources") amount_per_line = amount_per_line or vbox.width // button_width # Add the zero element to the beginning that allows to remove the currently # sold/bought resource: resources = [0] + db.get_res(only_tradeable=True) current_hbox = HBox(name="hbox_0", padding=0) index = 1 for res_id in resources: # don't show resources that are already in the list if res_filter is not None and not res_filter(res_id): continue # create button (dummy one or real one) if res_id == 0 or inventory is None: button = ImageButton( size=(button_width, button_width), name="resource_icon_00") button.up_image, button.down_image, button.hover_image = (dummy_icon_path,)*3 else: amount = inventory[res_id] filled = int(float(inventory[res_id]) / float(inventory.get_limit(res_id)) * 100.0) button = ImageFillStatusButton.init_for_res(db, res_id, amount=amount, filled=filled, uncached=True, use_inactive_icon=False) # on click: add this res cb = Callback(on_click, res_id) if hasattr(button, "button"): # for imagefillstatusbuttons button.button.capture( cb ) else: button.capture( cb ) current_hbox.addChild(button) if index % amount_per_line == 0: vbox.addChild(current_hbox) box_id = index // amount_per_line current_hbox = HBox(name="hbox_%s" % box_id, padding=0) index += 1 vbox.addChild(current_hbox) vbox.adaptLayout() return dlg
def _draw(self, vbox, current_hbox, index=0): """Draws the inventory.""" for resid, limit in sorted(self._limits.iteritems()): if self._selling: amount = max(0, self._inventory[resid] - limit) else: amount = max(0, limit - self._inventory[resid]) # check if this res should be displayed button = ImageFillStatusButton.init_for_res(self.db, resid, amount, filled=0, uncached=self.uncached) button.button.name = "buy_sell_inventory_%s_entry_%s" % (self._selling, index) # for tests current_hbox.addChild(button) if index % self.items_per_line == self.items_per_line - 1: vbox.addChild(current_hbox) current_hbox = HBox(padding=0) index += 1 vbox.addChild(current_hbox) self.addChild(vbox)
def _draw(self, vbox, current_hbox, index=0): """Draws the inventory.""" for resid, limit in sorted(self._limits.items()): if self._selling: amount = max(0, self._inventory[resid] - limit) else: amount = max(0, limit - self._inventory[resid]) # check if this res should be displayed button = ImageFillStatusButton.init_for_res(self.db, resid, amount, filled=0, uncached=self.uncached) button.button.name = "buy_sell_inventory_%s_entry_%s" % (self._selling, index) # for tests current_hbox.addChild(button) if index % self.items_per_line == self.items_per_line - 1: vbox.addChild(current_hbox) current_hbox = HBox(padding=0) index += 1 vbox.addChild(current_hbox) self.addChild(vbox)
def 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 len(parent_container.children) > 0: 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 sorted(self.instance.get_component(Producer).get_productions(), \ key=(lambda x: x.get_production_line_id())): if not production.has_change_listener(self.refresh): # we need to be notified of small production changes, that aren't passed through the instance production.add_change_listener(self.refresh) 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") 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 = pychan.widgets.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") for in_res in production.get_consumed_resources(): filled = float(self.instance.get_component(StorageComponent).inventory[in_res]) * 100 / \ self.instance.get_component(StorageComponent).inventory.get_limit(in_res) in_res_container.addChild( \ ImageFillStatusButton.init_for_res(self.instance.session.db,\ in_res, \ self.instance.get_component(StorageComponent).inventory[in_res], \ filled, \ use_inactive_icon=False, \ uncached=True) \ ) out_res_container = container.findChild(name="output_res") for out_res in production.get_produced_res(): filled = float(self.instance.get_component(StorageComponent).inventory[out_res]) * 100 / \ self.instance.get_component(StorageComponent).inventory.get_limit(out_res) out_res_container.addChild( \ ImageFillStatusButton.init_for_res(self.instance.session.db, \ out_res, \ self.instance.get_component(StorageComponent).inventory[out_res], \ filled, \ use_inactive_icon=False, \ uncached=True) \ ) # fix pychans lack of dynamic container sizing # the container in the xml must provide a height attribute, that is valid for # one resource. max_res_in_one_line = max(len(production.get_produced_res()), \ len(production.get_consumed_resources())) container.height = max_res_in_one_line * container.height # active toggle_active button container.mapEvents( \ { 'toggle_active': \ Callback(ToggleActive(self.instance.get_component(Producer), production).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 refresh(self): """This function is called by the TabWidget to redraw the widget.""" cap_util = 0 if hasattr(self.instance, 'capacity_utilisation'): cap_util = int(round( self.instance.capacity_utilisation * 100)) self.widget.child_finder('capacity_utilisation').text = unicode(cap_util) + u'%' # remove old production line data parent_container = self.widget.child_finder('production_lines') while len(parent_container.children) > 0: parent_container.removeChild(parent_container.children[0]) # create a container for each production # sort by production line id to have a consistent (basically arbitrary) order for production in sorted(self.instance._get_productions(), \ key=(lambda x: x.get_production_line_id())): gui = load_xml_translated(self.production_line_gui_xml) # fill in values to gui reflecting the current game state container = gui.findChild(name="production_line_container") if production.is_paused(): container.removeChild( container.findChild(name="toggle_active_active") ) container.findChild(name="toggle_active_inactive").name = "toggle_active" else: container.removeChild( container.findChild(name="toggle_active_inactive") ) container.findChild(name="toggle_active_active").name = "toggle_active" # fill it with input and output resources in_res_container = container.findChild(name="input_res") for in_res in production.get_consumed_resources(): filled = float(self.instance.inventory[in_res]) * 100 / \ self.instance.inventory.get_limit(in_res) in_res_container.addChild( \ ImageFillStatusButton.init_for_res(self.instance.session.db,\ in_res, \ self.instance.inventory[in_res], \ filled, \ use_inactive_icon=False) \ ) out_res_container = container.findChild(name="output_res") for out_res in production.get_produced_res(): filled = float(self.instance.inventory[out_res]) * 100 / \ self.instance.inventory.get_limit(out_res) out_res_container.addChild( \ ImageFillStatusButton.init_for_res(self.instance.session.db, \ out_res, \ self.instance.inventory[out_res], \ filled, \ use_inactive_icon=False) \ ) # fix pychans lack of dynamic container sizing # the container in the xml must provide a height attribute, that is valid for # one resource. max_res_in_one_line = max(len(production.get_produced_res()), \ len(production.get_consumed_resources())) container.height = max_res_in_one_line * container.height # active toggle_active button container.mapEvents( \ { 'toggle_active': \ Callback(ToggleActive(self.instance, production).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 create_resource_selection_dialog( on_click, inventory, db, widget="select_trade_resource.xml", res_filter=None, amount_per_line=None ): """Returns a container containing resource icons. @param on_click: called with resource id as parameter on clicks @param inventory: to determine fill status of resource slots @param db: main db instance @param widget: which xml file to use as a template. Default: tabwidget. Required since the resource bar also uses this code (no tabs there though). @param res_filter: callback to decide which icons to use. Default: show all @param amount_per_line: how many resource icons per line. Default: try to fit layout """ from horizons.gui.widgets.imagefillstatusbutton import ImageFillStatusButton dummy_icon_path = "icons/resources/none_gray" dlg = load_uh_widget(widget) icon_size = ImageFillStatusButton.ICON_SIZE # used for dummy button cell_size = ImageFillStatusButton.CELL_SIZE button_width = cell_size[0] vbox = dlg.findChild(name="resources") amount_per_line = amount_per_line or vbox.width // button_width # Add the zero element to the beginning that allows to remove the currently # sold/bought resource: resources = [0] + db.get_res(only_tradeable=True) current_hbox = HBox(name="hbox_0", padding=0) index = 1 for res_id in resources: # don't show resources that are already in the list if res_filter is not None and not res_filter(res_id): continue # on click: add this res cb = Callback(on_click, res_id) # create button (dummy one or real one) if res_id == 0 or inventory is None: reset_button = ImageButton(max_size=icon_size, name="resource_icon_00") reset_button.path = dummy_icon_path button = Container(size=cell_size) # add the "No Resource" image to the container, positioned in the top left button.addChild(reset_button) # capture a mouse click on the container. It's possible to click on the # image itself or into the empty area (below or to the right of the image) button.capture(cb, event_name="mouseClicked") button.name = "resource_%d" % res_id else: amount = inventory[res_id] filled = int(float(inventory[res_id]) / float(inventory.get_limit(res_id)) * 100.0) button = ImageFillStatusButton.init_for_res( db, res_id, amount=amount, filled=filled, uncached=True, use_inactive_icon=False, showprice=True ) button.button.capture(cb) button.button.name = "resource_%d" % res_id current_hbox.addChild(button) if index % amount_per_line == 0: vbox.addChild(current_hbox) box_id = index // amount_per_line current_hbox = HBox(name="hbox_%s" % box_id, padding=0) index += 1 vbox.addChild(current_hbox) vbox.adaptLayout() return dlg
def _draw(self, vbox, current_hbox, index=0): """Draws the inventory.""" # add res to res order in case there are new ones # (never remove old ones for consistent positioning) new_res = sorted(resid for resid in self._inventory.iterslots() if resid not in self._res_order) if isinstance(self._inventory, PositiveTotalNumSlotsStorage): # limited number of slots. We have to switch unused slots with newly added ones on overflow while len( self._res_order) + len(new_res) > self._inventory.slotnum: for i in xrange(self._inventory.slotnum): if len(self._res_order) <= i or self._inventory[ self._res_order[i]]: # search empty slot continue # insert new res here self._res_order[i] = new_res.pop(0) if not new_res: break # all done # add remaining slots for slotstorage or just add it without consideration for other storage kinds self._res_order += new_res for resid in self._res_order: amount = self._inventory[resid] if amount == 0: index += 1 continue # check if this res should be displayed if not self.db.cached_query( 'SELECT shown_in_inventory FROM resource WHERE id = ?', resid)[0][0]: continue if self.ordinal: lower, upper = self.ordinal.get(resid, (0, 100)) filled = (100 * (amount - lower)) // (upper - lower) amount = "" # do not display exact information for resource deposits elif isinstance(self._inventory, TotalStorage): filled = 0 else: filled = (100 * amount) // self._inventory.get_limit(resid) button = ImageFillStatusButton.init_for_res(self.db, resid, amount, filled=filled, uncached=self.uncached) button.button.name = "inventory_entry_%s" % index # required for gui tests current_hbox.addChild(button) if index % self.items_per_line == self.items_per_line - 1: vbox.addChild(current_hbox) current_hbox = HBox(padding=0) index += 1 if index <= self.items_per_line: # Hide/Remove second line icons = self.parent.findChildren(name='slot') if len(icons) > self.items_per_line: self.parent.removeChildren(icons[self.items_per_line - 1:]) vbox.addChild(current_hbox) self.addChild(vbox) height = ImageFillStatusButton.CELL_SIZE[1] * len( self._res_order) // self.items_per_line self.min_size = (self.min_size[0], height) if isinstance(self._inventory, TotalStorage): # if it's full, the additional slots have to be marked as unusable (#1686) # check for any res, the res type doesn't matter here if not self._inventory.get_free_space_for(0): for i in xrange(index, self.items_per_line): button = Icon(image=self.__class__.UNUSABLE_SLOT_IMAGE) # set min & max_size to prevent pychan to expand this dynamic widget (icon) button.min_size = button.max_size = ImageFillStatusButton.ICON_SIZE current_hbox.addChild(button) if self.display_legend: limit = self._inventory.get_limit(None) if isinstance(self._inventory, TotalStorage): # Add total storage indicator sum_stored = self._inventory.get_sum_of_stored_resources() self.legend.text = _('{stored}/{limit}').format( stored=sum_stored, limit=limit) elif isinstance(self._inventory, PositiveSizedSlotStorage): self.legend.text = _('Limit: {amount}t per slot').format( amount=limit)
def 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 len(parent_container.children) > 0: parent_container.removeChild(parent_container.children[0]) # create a container for each production # sort by production line id to have a consistent (basically arbitrary) order for production in sorted(self.instance._get_productions(), key=(lambda x: x.get_production_line_id())): 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") if production.is_paused(): container.removeChild(container.findChild(name="toggle_active_active")) container.findChild(name="toggle_active_inactive").name = "toggle_active" else: container.removeChild(container.findChild(name="toggle_active_inactive")) container.findChild(name="toggle_active_active").name = "toggle_active" # fill it with input and output resources in_res_container = container.findChild(name="input_res") for in_res in production.get_consumed_resources(): filled = float(self.instance.inventory[in_res]) * 100 / self.instance.inventory.get_limit(in_res) in_res_container.addChild( ImageFillStatusButton.init_for_res( self.instance.session.db, in_res, self.instance.inventory[in_res], filled, use_inactive_icon=False, uncached=True, ) ) out_res_container = container.findChild(name="output_res") for out_res in production.get_produced_res(): filled = float(self.instance.inventory[out_res]) * 100 / self.instance.inventory.get_limit(out_res) out_res_container.addChild( ImageFillStatusButton.init_for_res( self.instance.session.db, out_res, self.instance.inventory[out_res], filled, use_inactive_icon=False, uncached=True, ) ) # fix pychans lack of dynamic container sizing # the container in the xml must provide a height attribute, that is valid for # one resource. max_res_in_one_line = max(len(production.get_produced_res()), len(production.get_consumed_resources())) container.height = max_res_in_one_line * container.height # active toggle_active button container.mapEvents( {"toggle_active": Callback(ToggleActive(self.instance, production).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 create_resource_selection_dialog(on_click, inventory, db, widget='select_trade_resource.xml', res_filter=None, amount_per_line=None): """Returns a container containing resource icons. @param on_click: called with resource id as parameter on clicks @param inventory: to determine fill status of resource slots @param db: main db instance @param widget: which xml file to use as a template. Default: tabwidget. Required since the resource bar also uses this code (no tabs there though). @param res_filter: callback to decide which icons to use. Default: show all @param amount_per_line: how many resource icons per line. Default: try to fit layout """ from horizons.gui.widgets.imagefillstatusbutton import ImageFillStatusButton dummy_icon_path = "icons/resources/none_gray" dlg = load_uh_widget(widget) icon_size = ImageFillStatusButton.ICON_SIZE # used for dummy button cell_size = ImageFillStatusButton.CELL_SIZE button_width = cell_size[0] vbox = dlg.findChild(name="resources") amount_per_line = amount_per_line or vbox.width // button_width # Add the zero element to the beginning that allows to remove the currently # sold/bought resource: resources = [0] + db.get_res(only_tradeable=True) current_hbox = HBox(name="hbox_0", padding=0) index = 1 for res_id in resources: # don't show resources that are already in the list if res_filter is not None and not res_filter(res_id): continue # on click: add this res cb = Callback(on_click, res_id) # create button (dummy one or real one) if res_id == 0 or inventory is None: reset_button = ImageButton(max_size=icon_size, name="resource_icon_00") reset_button.path = dummy_icon_path button = Container(size=cell_size) # add the "No Resource" image to the container, positioned in the top left button.addChild(reset_button) # capture a mouse click on the container. It's possible to click on the # image itself or into the empty area (below or to the right of the image) button.capture(cb, event_name="mouseClicked") button.name = "resource_{:d}".format(res_id) else: amount = inventory[res_id] filled = int(inventory[res_id] / inventory.get_limit(res_id) * 100) button = ImageFillStatusButton.init_for_res(db, res_id, amount=amount, filled=filled, uncached=True, use_inactive_icon=False, showprice=True) button.capture(cb, event_name="mouseClicked") button.name = "resource_{:d}".format(res_id) current_hbox.addChild(button) if index % amount_per_line == 0: vbox.addChild(current_hbox) box_id = index // amount_per_line current_hbox = HBox(name="hbox_{}".format(box_id), padding=0) index += 1 vbox.addChild(current_hbox) vbox.adaptLayout() return dlg
def _draw(self, vbox, current_hbox, index=0): """Draws the inventory.""" # add res to res order in case there are new ones # (never remove old ones for consistent positioning) new_res = sorted( resid for resid in self._inventory.iterslots() if resid not in self._res_order ) if isinstance(self._inventory, PositiveTotalNumSlotsStorage): # limited number of slots. We have to switch unused slots with newly added ones on overflow while len(self._res_order) + len(new_res) > self._inventory.slotnum: for i in xrange(self._inventory.slotnum): if len(self._res_order) <= i or self._inventory[self._res_order[i]]: # search empty slot continue # insert new res here self._res_order[i] = new_res.pop(0) if not new_res: break # all done # add remaining slots for slotstorage or just add it without consideration for other storage kinds self._res_order += new_res for resid in self._res_order: # check if this res should be displayed if not self.db.cached_query('SELECT shown_in_inventory FROM resource WHERE id = ?', resid)[0][0]: continue amount = self._inventory[resid] if self.ordinal: lower, upper = self.ordinal.get(resid, (0, 100)) filled = (100 * (amount - lower)) // (upper - lower) amount = "" # do not display exact information for resource deposits elif isinstance(self._inventory, TotalStorage): filled = 0 else: filled = (100 * amount) // self._inventory.get_limit(resid) button = ImageFillStatusButton.init_for_res(self.db, resid, amount, filled=filled, uncached=self.uncached) button.button.name = "inventory_entry_%s" % index # required for gui tests current_hbox.addChild(button) if index % self.items_per_line == self.items_per_line - 1: vbox.addChild(current_hbox) current_hbox = HBox(padding=0) index += 1 if index <= self.items_per_line: # Hide/Remove second line icons = self.parent.findChildren(name='slot') if len(icons) > self.items_per_line: self.parent.removeChildren(icons[self.items_per_line-1:]) vbox.addChild(current_hbox) self.addChild(vbox) height = ImageFillStatusButton.CELL_SIZE[1] * len(self._res_order) // self.items_per_line self.min_size = (self.min_size[0], height) if isinstance(self._inventory, TotalStorage): # if it's full, the additional slots have to be marked as unusable (#1686) # check for any res, the res type doesn't matter here if not self._inventory.get_free_space_for(0): for i in xrange(index, self.items_per_line): button = Icon(image=self.__class__.UNUSABLE_SLOT_IMAGE) current_hbox.addChild(button) if self.display_legend: limit = self._inventory.get_limit(None) if isinstance(self._inventory, TotalStorage): # Add total storage indicator sum_stored = self._inventory.get_sum_of_stored_resources() self.legend.text = _('{stored}/{limit}').format(stored=sum_stored, limit=limit) elif isinstance(self._inventory, PositiveSizedSlotStorage): self.legend.text = _('Limit: {amount}t per slot').format(amount=limit)
def _draw(self): """Draws the inventory.""" self.removeAllChildren() vbox = pychan.widgets.VBox(padding=0) vbox.width = self.width current_hbox = pychan.widgets.HBox(padding=0) index = 0 # add res to res order in case there are new ones # (never remove old ones for consistent positioning) new_res = sorted( resid for resid in self._inventory.iterslots() if resid not in self._res_order ) if isinstance(self._inventory, PositiveTotalNumSlotsStorage): # limited number of slots. We have to switch unused slots with newly added ones on overflow while len(self._res_order) + len(new_res) > self._inventory.slotnum: for i in xrange( self._inventory.slotnum ): # search empty slot if self._inventory[ self._res_order[i] ] == 0: # insert new res here self._res_order[i] = new_res.pop(0) if not new_res: break # all done # add remaining slots for slotstorage or just add it without consideration for other storage kinds self._res_order += new_res for resid in self._res_order: # check if this res should be displayed if not self.db.cached_query('SELECT shown_in_inventory FROM resource WHERE id = ?', resid)[0][0]: continue amount = self._inventory[resid] if self.ordinal: lower, upper = self.ordinal.get(resid, (0, 100)) filled = (100 * (amount - lower)) // (upper - lower) amount = "" # do not display exact information for resource deposits elif isinstance(self._inventory, TotalStorage): filled = 0 else: filled = (100 * amount) // self._inventory.get_limit(resid) button = ImageFillStatusButton.init_for_res(self.db, resid, amount, filled=filled, uncached=self.uncached) button.button.name = "inventory_entry_%s" % index # required for gui tests current_hbox.addChild(button) # old code to do this, which was bad but kept for reference #if index % ((vbox.width/(self.__class__.icon_width + 10))) < 0 and index != 0: if index % self.ITEMS_PER_LINE == (self.ITEMS_PER_LINE - 1) and index != 0: vbox.addChild(current_hbox) current_hbox = pychan.widgets.HBox(padding=0) index += 1 if index <= self.ITEMS_PER_LINE: # Hide/Remove second line icons = self.parent.findChildren(name='slot') if len(icons) > self.ITEMS_PER_LINE: self.parent.removeChildren(icons[self.ITEMS_PER_LINE-1:]) vbox.addChild(current_hbox) self.addChild(vbox) height = ImageFillStatusButton.CELL_SIZE[1] * len(self._res_order) // self.ITEMS_PER_LINE self.min_size = (self.min_size[0], height) if isinstance(self._inventory, TotalStorage): # if it's full, the additional slots have to be marked as unusable (#1686) # check for any res, the res type doesn't matter here if self._inventory.get_free_space_for(0) == 0: for i in xrange(index, self.ITEMS_PER_LINE): button = pychan.widgets.Icon(image=self.__class__.UNUSABLE_SLOT_IMAGE) current_hbox.addChild(button) if self.display_legend: if isinstance(self._inventory, TotalStorage): # Add total storage indicator sum_stored_res = self._inventory.get_sum_of_stored_resources() label = pychan.widgets.Label() label.text = unicode(sum_stored_res) + u"/" + unicode(self._inventory.get_limit(None)) label.position = (150, 53) self.__icon.position = (130, 53) self.addChildren(label, self.__icon) elif isinstance(self._inventory, PositiveSizedSlotStorage): label = pychan.widgets.Label() #xgettext:python-format label.text = _('Limit: {amount}t per slot').format(amount=self._inventory.get_limit(None)) label.position = (20, 203) self.__icon.position = (0, 203) self.addChildren(label, self.__icon) self.adaptLayout() self.stylize('menu_black')