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 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 parse_logbook_item(self, parameter): # Some error checking for widgets that are to be loaded. # This happens, for example, with outdated YAML stored in old # scenario savegames. Instead of crashing, display nothing. def _icon(image): try: # Pychan can only use str objects as file path. # json.loads() however returns unicode. return Icon(image=str(image)) except fife.NotFound: return None def _label(text, font='default'): try: return Label(text=str(text), wrap_text=True, min_size=(325, 0), max_size=(325, 1024), font=font) except InitializationError: return None if parameter and parameter[0]: # allow empty Labels parameter_type = parameter[0] if isinstance(parameter, str): add = _label(parameter) elif parameter_type == 'Label': add = _label(parameter[1]) elif parameter_type == 'Image': add = _icon(parameter[1]) elif parameter_type == 'Gallery': add = HBox() for image in parameter[1]: new_icon = _icon(image) if new_icon is not None: add.addChild(new_icon) elif parameter_type == 'Headline': add = HBox() is_not_last_headline = self._parameters and self._cur_entry is not None and self._cur_entry < (len(self._parameters) - 2) if is_not_last_headline: add.addChild(_icon("content/gui/images/tabwidget/done.png")) add.addChild(_label(parameter[1], font='headline')) elif parameter_type == 'BoldLabel': add = _label(parameter[1], font='default_bold') elif parameter_type == 'Message': add = None # parameters are re-read on page reload. # duplicate_message stops messages from # being duplicated on page reload. message = parameter[1] # message is already going to be displayed or has been displayed # before (e.g. re-opening older logbook pages) duplicate_message = (message in self._messages_to_display or message in self._message_log) if not duplicate_message: self._messages_to_display.append(message) # the new message has not been displayed else: self.log.warning('Unknown parameter type %s in parameter %s', parameter[0], parameter) add = None return add
def _add_player_line(player): name = player['name'] pname = Label(name="pname_%s" % name) pname.helptext = _("Click here to change your name and/or color") pname.text = name pname.min_size = pname.max_size = (130, 15) if name == NetworkInterface().get_client_name(): pname.capture( Callback(self._show_change_player_details_popup, game)) pcolor = Label(name="pcolor_%s" % name, text=u" ") pcolor.helptext = _("Click here to change your name and/or color") pcolor.background_color = player['color'] pcolor.min_size = pcolor.max_size = (15, 15) if name == NetworkInterface().get_client_name(): pcolor.capture( Callback(self._show_change_player_details_popup, game)) pstatus = Label(name="pstatus_%s" % name) pstatus.text = "\t\t\t" + player['status'] pstatus.min_size = pstatus.max_size = (120, 15) picon = HRule(name="picon_%s" % name) hbox = HBox() hbox.addChildren(pname, pcolor, pstatus) if NetworkInterface().get_client_name( ) == game.creator and name != game.creator: pkick = CancelButton(name="pkick_%s" % name) pkick.helptext = _("Kick {player}").format(player=name) pkick.capture(Callback(NetworkInterface().kick, player['sid'])) pkick.path = "images/buttons/delete_small" pkick.min_size = pkick.max_size = (20, 15) hbox.addChild(pkick) players_vbox.addChildren(hbox, picon)
def _add_player_line(player): name = player['name'] pname = Label(name="pname_%s" % name) pname.helptext = _("Click here to change your name and/or color") pname.text = name pname.min_size = pname.max_size = (130, 15) if name == NetworkInterface().get_client_name(): pname.capture(Callback(self._show_change_player_details_popup, game)) pcolor = Label(name="pcolor_%s" % name, text=u" ") pcolor.helptext = _("Click here to change your name and/or color") pcolor.background_color = player['color'] pcolor.min_size = pcolor.max_size = (15, 15) if name == NetworkInterface().get_client_name(): pcolor.capture(Callback(self._show_change_player_details_popup, game)) pstatus = Label(name="pstatus_%s" % name) pstatus.text = "\t\t\t" + player['status'] pstatus.min_size = pstatus.max_size = (120, 15) picon = HRule(name="picon_%s" % name) hbox = HBox() hbox.addChildren(pname, pcolor, pstatus) if NetworkInterface().get_client_name() == game.creator and name != game.creator: pkick = CancelButton(name="pkick_%s" % name) #xgettext:python-format pkick.helptext = _("Kick {player}").format(player=name) pkick.capture(Callback(NetworkInterface().kick, player['sid'])) pkick.path = "images/buttons/delete_small" pkick.min_size = pkick.max_size = (20, 15) hbox.addChild(pkick) players_vbox.addChildren(hbox, picon)
def _add_player_line(player): pname = Label(name="pname_%s" % player['name']) pname.helptext = _("Click here to change your name and/or color") pname.text = player['name'] if player['name'] == NetworkInterface().get_client_name(): pname.capture(Callback( self.__show_change_player_details_popup)) pname.min_size = pname.max_size = (130, 15) pcolor = Label(name="pcolor_%s" % player['name'], text=u" ") pcolor.helptext = _("Click here to change your name and/or color") pcolor.background_color = player['color'] if player['name'] == NetworkInterface().get_client_name(): pcolor.capture( Callback(self.__show_change_player_details_popup)) pcolor.min_size = pcolor.max_size = (15, 15) pstatus = Label(name="pstatus_%s" % player['name']) pstatus.text = "\t\t\t" + player['status'] pstatus.min_size = pstatus.max_size = (120, 15) picon = Icon(name="picon_%s" % player['name']) picon.image = "content/gui/images/background/hr.png" hbox = HBox() hbox.addChild(pname) hbox.addChild(pcolor) hbox.addChild(pstatus) if NetworkInterface().get_client_name() == game.get_creator( ) and player['name'] != game.get_creator(): pkick = CancelButton(name="pkick_%s" % player['name']) pkick.helptext = _("Kick {player}").format( player=player['name']) pkick.capture(Callback(NetworkInterface().kick, player['sid'])) pkick.up_image = "content/gui/images/buttons/delete_small.png" pkick.down_image = "content/gui/images/buttons/delete_small.png" pkick.hover_image = "content/gui/images/buttons/delete_small_h.png" pkick.min_size = pkick.max_size = (20, 15) hbox.addChild(pkick) players_vbox.addChild(hbox) players_vbox.addChild(picon)
def _add_player_line(player): pname = Label(name="pname_%s" % player['name']) pname.helptext = _("Click here to change your name and/or color") pname.text = player['name'] pname.min_size = pname.max_size = (130, 15) if player['name'] == NetworkInterface().get_client_name(): pname.capture(Callback(self._show_change_player_details_popup, game)) pcolor = Label(name="pcolor_%s" % player['name'], text=u" ") pcolor.helptext = _("Click here to change your name and/or color") pcolor.background_color = player['color'] pcolor.min_size = pcolor.max_size = (15, 15) if player['name'] == NetworkInterface().get_client_name(): pcolor.capture(Callback(self._show_change_player_details_popup, game)) pstatus = Label(name="pstatus_%s" % player['name']) pstatus.text = "\t\t\t" + player['status'] pstatus.min_size = pstatus.max_size = (120, 15) picon = Icon(name="picon_%s" % player['name']) picon.image = "content/gui/images/background/hr.png" hbox = HBox() hbox.addChild(pname) hbox.addChild(pcolor) hbox.addChild(pstatus) if NetworkInterface().get_client_name() == game.creator and player['name'] != game.creator: pkick = CancelButton(name="pkick_%s" % player['name']) pkick.helptext = _("Kick {player}").format(player=player['name']) pkick.capture(Callback(NetworkInterface().kick, player['sid'])) pkick.up_image = "content/gui/images/buttons/delete_small.png" pkick.down_image = "content/gui/images/buttons/delete_small.png" pkick.hover_image = "content/gui/images/buttons/delete_small_h.png" pkick.min_size = pkick.max_size = (20, 15) hbox.addChild(pkick) players_vbox.addChild(hbox) players_vbox.addChild(picon)
def _init_stats_gui(self): reference_icon = self.gold_gui.child_finder("balance_background") self.stats_gui = load_uh_widget(self.__class__.STATS_GUI_FILE) self.stats_gui.child_finder = PychanChildFinder(self.stats_gui) self.stats_gui.position = (reference_icon.x + self.gold_gui.x, reference_icon.y + self.gold_gui.y) self.stats_gui.mapEvents({ 'resbar_stats_container/mouseClicked/stats': self._toggle_stats, }) # This list must correspond to `figures` in _update_stats images = [ ("content/gui/images/resbar_stats/expense.png", T("Running costs")), ("content/gui/images/resbar_stats/income.png", T("Taxes")), ("content/gui/images/resbar_stats/buy.png", T("Buy expenses")), ("content/gui/images/resbar_stats/sell.png", T("Sell income")), ("content/gui/images/resbar_stats/scales_icon.png", T("Balance")), ] for num, (image, helptext) in enumerate(images): # Keep in sync with comment there until we can use that data: # ./content/gui/xml/ingame/hud/resource_overview_bar_stats.xml box = HBox(padding=0, min_size=(70, 0)) box.name = "resbar_stats_line_{}".format(num) box.helptext = helptext #TODO Fix icon size; looks like not 16x16 a surprising amount of times. box.addChild(Icon(image=image)) box.addChild(Spacer()) box.addChild(Label(name="resbar_stats_entry_{}".format(num))) #TODO This label is a workaround for some fife font bug, # probably http://github.com/fifengine/fifengine/issues/666. templabel = Label(name="resbar_stats_whatever_{}".format(num)) box.addChild(templabel) if num == len(images) - 1: # The balance line (last one) gets bold font. box.stylize('resource_bar') self.stats_gui.child_finder("entries_box").addChild(box)
def _show_stats(self): """Show data below gold icon when balance label is clicked""" if self.stats_gui is None: reference_icon = self.gold_gui.child_finder("balance_background") self.stats_gui = load_uh_widget(self.__class__.STATS_GUI_FILE) self.stats_gui.child_finder = PychanChildFinder(self.stats_gui) self.stats_gui.position = (reference_icon.x + self.gold_gui.x, reference_icon.y + self.gold_gui.y) self.stats_gui.mapEvents({ 'resbar_stats_container/mouseClicked/stats': self._toggle_stats }) images = [ # these must correspond to the entries in _update_stats "content/gui/images/resbar_stats/expense.png", "content/gui/images/resbar_stats/income.png", "content/gui/images/resbar_stats/buy.png", "content/gui/images/resbar_stats/sell.png", "content/gui/images/resbar_stats/scales_icon.png", ] for num, image in enumerate(images): # keep in sync with comment there until we can use that data: # ./content/gui/xml/ingame/hud/resource_overview_bar_stats.xml box = HBox(padding=0, min_size=(70, 0), name="resbar_stats_line_%s" % num) box.addChild(Icon(image=image)) box.addSpacer(Spacer()) box.addChild(Label(name="resbar_stats_entry_%s" % num)) # workaround for fife font bug, probably http://fife.trac.cloudforge.com/engine/ticket/666 box.addChild(Label(text=u" ")) if num < len(images) - 1: # regular one self.stats_gui.child_finder("entries_box").addChild(box) else: # last one self.stats_gui.child_finder("bottom_box").addChild(box) self.stats_gui.child_finder("bottom_box").stylize( 'resource_bar') self._update_stats() self.stats_gui.show() ExtScheduler().add_new_object(self._update_stats, self, run_in=Player.STATS_UPDATE_INTERVAL, loops=-1)
def _show_stats(self): """Show data below gold icon when balance label is clicked""" if self.stats_gui is None: reference_icon = self.gold_gui.child_finder("balance_background") self.stats_gui = load_uh_widget( self.__class__.STATS_GUI_FILE ) self.stats_gui.child_finder = PychanChildFinder(self.stats_gui) self.stats_gui.position = (reference_icon.x + self.gold_gui.x, reference_icon.y + self.gold_gui.y) self.stats_gui.mapEvents({ 'resbar_stats_container/mouseClicked/stats' : self._toggle_stats }) images = [ # these must correspond to the entries in _update_stats "content/gui/images/resbar_stats/expense.png", "content/gui/images/resbar_stats/income.png", "content/gui/images/resbar_stats/buy.png", "content/gui/images/resbar_stats/sell.png", "content/gui/images/resbar_stats/scales_icon.png", ] for num, image in enumerate(images): # keep in sync with comment there until we can use that data: # ./content/gui/xml/ingame/hud/resource_overview_bar_stats.xml box = HBox(padding=0, min_size=(70, 0), name="resbar_stats_line_%s"%num) box.addChild(Icon(image=image)) box.addSpacer(Spacer()) box.addChild(Label(name="resbar_stats_entry_%s"%num)) # workaround for fife font bug, probably http://fife.trac.cloudforge.com/engine/ticket/666 box.addChild(Label(text=u" ")) if num < len(images)-1: # regular one self.stats_gui.child_finder("entries_box").addChild(box) else: # last one self.stats_gui.child_finder("bottom_box").addChild(box) self.stats_gui.child_finder("bottom_box").stylize('resource_bar') self._update_stats() self.stats_gui.show() ExtScheduler().add_new_object(self._update_stats, self, run_in=Player.STATS_UPDATE_INTERVAL, loops=-1)
def _draw(self, vbox, current_hbox, index=0): """Draws the inventory.""" # add res to res order in case there are new ones # (never remove old ones for consistent positioning) new_res = sorted(resid for resid in self._inventory.iterslots() if resid not in self._res_order) if isinstance(self._inventory, PositiveTotalNumSlotsStorage): # limited number of slots. We have to switch unused slots with newly added ones on overflow while len( self._res_order) + len(new_res) > self._inventory.slotnum: for i in xrange(self._inventory.slotnum): if len(self._res_order) <= i or self._inventory[ self._res_order[i]]: # search empty slot continue # insert new res here self._res_order[i] = new_res.pop(0) if not new_res: break # all done # add remaining slots for slotstorage or just add it without consideration for other storage kinds self._res_order += new_res for resid in self._res_order: amount = self._inventory[resid] if amount == 0: index += 1 continue # check if this res should be displayed if not self.db.cached_query( 'SELECT shown_in_inventory FROM resource WHERE id = ?', resid)[0][0]: continue if self.ordinal: lower, upper = self.ordinal.get(resid, (0, 100)) filled = (100 * (amount - lower)) // (upper - lower) amount = "" # do not display exact information for resource deposits elif isinstance(self._inventory, TotalStorage): filled = 0 else: filled = (100 * amount) // self._inventory.get_limit(resid) button = ImageFillStatusButton.init_for_res(self.db, resid, amount, filled=filled, uncached=self.uncached) button.button.name = "inventory_entry_%s" % index # required for gui tests current_hbox.addChild(button) if index % self.items_per_line == self.items_per_line - 1: vbox.addChild(current_hbox) current_hbox = HBox(padding=0) index += 1 if index <= self.items_per_line: # Hide/Remove second line icons = self.parent.findChildren(name='slot') if len(icons) > self.items_per_line: self.parent.removeChildren(icons[self.items_per_line - 1:]) vbox.addChild(current_hbox) self.addChild(vbox) height = ImageFillStatusButton.CELL_SIZE[1] * len( self._res_order) // self.items_per_line self.min_size = (self.min_size[0], height) if isinstance(self._inventory, TotalStorage): # if it's full, the additional slots have to be marked as unusable (#1686) # check for any res, the res type doesn't matter here if not self._inventory.get_free_space_for(0): for i in xrange(index, self.items_per_line): button = Icon(image=self.__class__.UNUSABLE_SLOT_IMAGE) # set min & max_size to prevent pychan to expand this dynamic widget (icon) button.min_size = button.max_size = ImageFillStatusButton.ICON_SIZE current_hbox.addChild(button) if self.display_legend: limit = self._inventory.get_limit(None) if isinstance(self._inventory, TotalStorage): # Add total storage indicator sum_stored = self._inventory.get_sum_of_stored_resources() self.legend.text = _('{stored}/{limit}').format( stored=sum_stored, limit=limit) elif isinstance(self._inventory, PositiveSizedSlotStorage): self.legend.text = _('Limit: {amount}t per slot').format( amount=limit)
def _draw(self, vbox, current_hbox, index=0): """Draws the inventory.""" # add res to res order in case there are new ones # (never remove old ones for consistent positioning) new_res = sorted( resid for resid in self._inventory.iterslots() if resid not in self._res_order ) if isinstance(self._inventory, PositiveTotalNumSlotsStorage): # limited number of slots. We have to switch unused slots with newly added ones on overflow while len(self._res_order) + len(new_res) > self._inventory.slotnum: for i in xrange(self._inventory.slotnum): if len(self._res_order) <= i or self._inventory[self._res_order[i]]: # search empty slot continue # insert new res here self._res_order[i] = new_res.pop(0) if not new_res: break # all done # add remaining slots for slotstorage or just add it without consideration for other storage kinds self._res_order += new_res for resid in self._res_order: # check if this res should be displayed if not self.db.cached_query('SELECT shown_in_inventory FROM resource WHERE id = ?', resid)[0][0]: continue amount = self._inventory[resid] if self.ordinal: lower, upper = self.ordinal.get(resid, (0, 100)) filled = (100 * (amount - lower)) // (upper - lower) amount = "" # do not display exact information for resource deposits elif isinstance(self._inventory, TotalStorage): filled = 0 else: filled = (100 * amount) // self._inventory.get_limit(resid) button = ImageFillStatusButton.init_for_res(self.db, resid, amount, filled=filled, uncached=self.uncached) button.button.name = "inventory_entry_%s" % index # required for gui tests current_hbox.addChild(button) if index % self.items_per_line == self.items_per_line - 1: vbox.addChild(current_hbox) current_hbox = HBox(padding=0) index += 1 if index <= self.items_per_line: # Hide/Remove second line icons = self.parent.findChildren(name='slot') if len(icons) > self.items_per_line: self.parent.removeChildren(icons[self.items_per_line-1:]) vbox.addChild(current_hbox) self.addChild(vbox) height = ImageFillStatusButton.CELL_SIZE[1] * len(self._res_order) // self.items_per_line self.min_size = (self.min_size[0], height) if isinstance(self._inventory, TotalStorage): # if it's full, the additional slots have to be marked as unusable (#1686) # check for any res, the res type doesn't matter here if not self._inventory.get_free_space_for(0): for i in xrange(index, self.items_per_line): button = Icon(image=self.__class__.UNUSABLE_SLOT_IMAGE) current_hbox.addChild(button) if self.display_legend: limit = self._inventory.get_limit(None) if isinstance(self._inventory, TotalStorage): # Add total storage indicator sum_stored = self._inventory.get_sum_of_stored_resources() self.legend.text = _('{stored}/{limit}').format(stored=sum_stored, limit=limit) elif isinstance(self._inventory, PositiveSizedSlotStorage): self.legend.text = _('Limit: {amount}t per slot').format(amount=limit)
def 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 create_resource_selection_dialog( on_click, inventory, db, widget="select_trade_resource.xml", res_filter=None, amount_per_line=None ): """Returns a container containing resource icons. @param on_click: called with resource id as parameter on clicks @param inventory: to determine fill status of resource slots @param db: main db instance @param widget: which xml file to use as a template. Default: tabwidget. Required since the resource bar also uses this code (no tabs there though). @param res_filter: callback to decide which icons to use. Default: show all @param amount_per_line: how many resource icons per line. Default: try to fit layout """ from horizons.gui.widgets.imagefillstatusbutton import ImageFillStatusButton dummy_icon_path = "icons/resources/none_gray" dlg = load_uh_widget(widget) icon_size = ImageFillStatusButton.ICON_SIZE # used for dummy button cell_size = ImageFillStatusButton.CELL_SIZE button_width = cell_size[0] vbox = dlg.findChild(name="resources") amount_per_line = amount_per_line or vbox.width // button_width # Add the zero element to the beginning that allows to remove the currently # sold/bought resource: resources = [0] + db.get_res(only_tradeable=True) current_hbox = HBox(name="hbox_0", padding=0) index = 1 for res_id in resources: # don't show resources that are already in the list if res_filter is not None and not res_filter(res_id): continue # on click: add this res cb = Callback(on_click, res_id) # create button (dummy one or real one) if res_id == 0 or inventory is None: reset_button = ImageButton(max_size=icon_size, name="resource_icon_00") reset_button.path = dummy_icon_path button = Container(size=cell_size) # add the "No Resource" image to the container, positioned in the top left button.addChild(reset_button) # capture a mouse click on the container. It's possible to click on the # image itself or into the empty area (below or to the right of the image) button.capture(cb, event_name="mouseClicked") button.name = "resource_%d" % res_id else: amount = inventory[res_id] filled = int(float(inventory[res_id]) / float(inventory.get_limit(res_id)) * 100.0) button = ImageFillStatusButton.init_for_res( db, res_id, amount=amount, filled=filled, uncached=True, use_inactive_icon=False, showprice=True ) button.button.capture(cb) button.button.name = "resource_%d" % res_id current_hbox.addChild(button) if index % amount_per_line == 0: vbox.addChild(current_hbox) box_id = index // amount_per_line current_hbox = HBox(name="hbox_%s" % box_id, padding=0) index += 1 vbox.addChild(current_hbox) vbox.adaptLayout() return dlg
def _add_line_to_gui(self, ship, sequence_number): sequence_number_label = Label(name='sequence_number_{:d}'.format(ship.worldid)) sequence_number_label.text = str(sequence_number) sequence_number_label.min_size = sequence_number_label.max_size = (15, 20) ship_name = Label(name='ship_name_{:d}'.format(ship.worldid)) ship_name.text = ship.get_component(NamedComponent).name ship_name.min_size = ship_name.max_size = (100, 20) from horizons.engine.pychan_util import RenameImageButton rename_icon = RenameImageButton(name='rename_{:d}'.format(ship.worldid)) rename_icon.path = "images/background/rename_feather_20" rename_icon.helptext = T("Click to change the name of this ship") rename_icon.max_size = (20, 20) # (width, height) ship_type = Label(name='ship_type_{:d}'.format(ship.worldid)) ship_type.text = ship.classname ship_type.min_size = ship_type.max_size = (60, 20) weapons = Label(name='weapons_{:d}'.format(ship.worldid)) if isinstance(ship, FightingShip): weapon_list = [] for weapon_id, amount in sorted(ship.get_weapon_storage().itercontents()): weapon_list.append('{:d} {}'.format(amount, self.session.db.get_res_name(weapon_id))) if weapon_list: weapons.text = ', '.join(weapon_list) else: #i18n There are no weapons equipped at the moment. weapons.text = T('None') else: weapons.text = T('N/A') weapons.min_size = weapons.max_size = (60, 20) health = Label(name='health_{:d}'.format(ship.worldid)) health_component = ship.get_component(HealthComponent) health.text = '{:.1f}/{:.1f}'.format(health_component.health, health_component.max_health) health.min_size = health.max_size = (65, 20) status = Label(name='status_{:d}'.format(ship.worldid)) status.text, status_position = ship.get_status() status.min_size = status.max_size = (320, 20) hbox = HBox() hbox.addChild(sequence_number_label) hbox.addChild(ship_name) hbox.addChild(rename_icon) hbox.addChild(ship_type) hbox.addChild(weapons) hbox.addChild(health) hbox.addChild(status) self._content_vbox.addChild(hbox) return (ship_name, rename_icon, status, status_position)
def _add_line_to_gui(self, ship, sequence_number): sequence_number_label = Label(name='sequence_number_%d' % ship.worldid) sequence_number_label.text = unicode(sequence_number) sequence_number_label.min_size = sequence_number_label.max_size = (15, 20) ship_name = Label(name='ship_name_%d' % ship.worldid) ship_name.text = ship.get_component(NamedComponent).name ship_name.min_size = ship_name.max_size = (100, 20) from horizons.engine.pychan_util import RenameImageButton rename_icon = RenameImageButton(name='rename_%d' % ship.worldid) rename_icon.path = "images/background/rename_feather_20" rename_icon.helptext = T("Click to change the name of this ship") rename_icon.max_size = (20, 20) # (width, height) ship_type = Label(name='ship_type_%d' % ship.worldid) ship_type.text = ship.classname ship_type.min_size = ship_type.max_size = (60, 20) weapons = Label(name='weapons_%d' % ship.worldid) if isinstance(ship, FightingShip): weapon_list = [] for weapon_id, amount in sorted( ship.get_weapon_storage().itercontents()): weapon_list.append( '%d %s' % (amount, self.session.db.get_res_name(weapon_id))) if weapon_list: weapons.text = u', '.join(weapon_list) else: #i18n There are no weapons equipped at the moment. weapons.text = T('None') else: weapons.text = T('N/A') weapons.min_size = weapons.max_size = (60, 20) health = Label(name='health_%d' % ship.worldid) health_component = ship.get_component(HealthComponent) health.text = u'%d/%d' % (health_component.health, health_component.max_health) health.min_size = health.max_size = (65, 20) status = Label(name='status_%d' % ship.worldid) status.text, status_position = ship.get_status() status.min_size = status.max_size = (320, 20) hbox = HBox() hbox.addChild(sequence_number_label) hbox.addChild(ship_name) hbox.addChild(rename_icon) hbox.addChild(ship_type) hbox.addChild(weapons) hbox.addChild(health) hbox.addChild(status) self._content_vbox.addChild(hbox) return (ship_name, rename_icon, status, status_position)