def set_construction_mode(self, resource_source_instance, build_costs): """Show resources relevant to construction and build costs @param resource_source_instance: object with StorageComponent @param build_costs: dict, { res : amount } """ if resource_source_instance is None: # Build moved out of settlement. This is usually not sane and an interaction error. # Use this heuristically computed settlement to fix preconditions. resource_source_instance = LastActivePlayerSettlementManager().get() if ( self.construction_mode and resource_source_instance == self.current_instance() and build_costs == self._last_build_costs ): return # now that's not an update self._last_build_costs = build_costs self.construction_mode = True self.set_inventory_instance(resource_source_instance, keep_construction_mode=True) # label background icons cost_icon_gold = "content/gui/images/background/widgets/resbar_stats_bottom.png" cost_icon_res = "content/gui/images/background/widgets/res_extra_bg.png" res_list = self._get_current_resources() # remove old one before, avoids duplicates self._drop_cost_labels() for res, amount in build_costs.iteritems(): assert res in res_list or res == RES.GOLD cost_label = Label(text=u"-" + unicode(amount)) cost_label.stylize(self.__class__.STYLE) # add icon below end of background icon if res in res_list: entry = res_list.index(res) cur_gui = self.gui[entry] reference_icon = cur_gui.findChild(name="background_icon") below = reference_icon.size[1] cost_icon = Icon(image=cost_icon_res, position=(0, below)) cost_label.position = (15, below) # TODO: centering cur_gui.addChild(cost_icon) cur_gui.addChild(cost_label) cur_gui.cost_gui = [cost_label, cost_icon] cur_gui.resizeToContent() # container needs to be bigger now else: # must be gold # there is an icon with scales there, use its positioning reference_icon = self.gold_gui.child_finder("balance_background") cost_icon = Icon(image=cost_icon_gold, position=(reference_icon.x, reference_icon.y)) cost_label.position = (23, 74) # TODO: centering self.gold_gui.addChild(cost_icon) self.gold_gui.addChild(cost_label) self.gold_gui.cost_gui = [cost_label, cost_icon] self.gold_gui.resizeToContent()
def _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 _set_resource_amounts(self, container, production): for res, amount in production.get_consumed_resources().iteritems(): # consumed resources are negative! label = Label(text=unicode(-amount), margins=(0, 16)) container.findChild(name='input_box').addChild(label) for res, amount in production.get_produced_resources().iteritems(): label = Label(text=unicode(amount).rjust(2), margins=(0, 16)) container.findChild(name='output_box').addChild(label)
def parse_logbook_item(self, parameter): # json.loads() returns unicode, thus convert strings and compare to unicode # Image works with str() since pychan can only use str objects as file path if parameter and parameter[0]: # allow empty Labels parameter_type = parameter[0] if isinstance(parameter, basestring): add = Label(text=unicode(parameter), wrap_text=True, min_size=(335, 0), max_size=(335, 508)) elif parameter_type == u'Label': add = Label(text=unicode(parameter[1]), wrap_text=True, min_size=(335, 0), max_size=(335, 508)) elif parameter_type == u'Image': add = Icon(image=str(parameter[1])) elif parameter_type == u'Gallery': add = HBox() for image in parameter[1]: add.addChild(Icon(image=str(image))) elif parameter_type == u'Headline': add = Label(text=parameter[1]) add.stylize('headline') elif parameter_type == u'Message': add = None # parameters are re-read on page reload. # duplicate_message stops messages from # being duplicated on page reload. duplicate_message = parameter[1] in self._messages if not duplicate_message: self._messages[parameter[1]] = False # has not been displayed else: print '[WW] Warning: Unknown parameter type {typ} in parameter {prm}'.format( typ=parameter[0], prm=parameter) add = None self.log.debug("parameter added of type %s", parameter_type) return add
def refresh(self): self.widget.mapEvents({ 'allow_upgrades/mouseClicked' : self.toggle_upgrades, }) # refresh taxes self.widget.child_finder('taxes').text = str(self._get_last_tax_paid()) # refresh upgrade permissions upgrades_button = self.widget.child_finder('allow_upgrades') # The currently highest playable tier cannot allow upgrades. if self.__class__.LEVEL < TIER.CURRENT_MAX: if self.settlement.upgrade_permissions[self.__class__.LEVEL]: upgrades_button.set_active() upgrades_button.helptext = T("Don't allow upgrades") else: upgrades_button.set_inactive() upgrades_button.helptext = T('Allow upgrades') # refresh residents per house info resident_counts = self._get_resident_counts() houses = 0 residents = 0 container = self.widget.child_finder('residents_per_house_table') space_per_label = container.size[0] // 6 for number in range(self.min_inhabitants, self.max_inhabitants + 1): column = number - (self.min_inhabitants - 1 if self.min_inhabitants > 0 else 0) house_count = resident_counts.get(number, 0) houses += house_count residents += house_count * number position_x = (space_per_label * (column - 1)) + 10 if not container.findChild(name="resident_" + str(column)): label = Label(name="resident_" + str(column), position=(position_x, 0), text=str(number)) container.addChild(label) count_label = Label(name="resident_count_" + str(column), position=(position_x - 1, 20), text=str(house_count)) container.addChild(count_label) else: container.findChild(name="resident_" + str(column)).text = str(number) container.findChild(name="resident_count_" + str(column)).text = str(house_count) sad = self.instance.session.db.get_lower_happiness_limit() happy = self.instance.session.db.get_upper_happiness_limit() inhabitants = partial(self.settlement.get_residentials_of_lvl_for_happiness, self.__class__.LEVEL) self.widget.child_finder('sad_amount').text = str(inhabitants(max_happiness=sad)) self.widget.child_finder('avg_amount').text = str(inhabitants(sad, happy)) self.widget.child_finder('happy_amount').text = str(inhabitants(happy)) # refresh the summary self.widget.child_finder('house_count').text = str(houses) self.widget.child_finder('resident_count').text = str(residents) self.widget.adaptLayout() super(MainSquareSettlerLevelTab, self).refresh()
def build_ship_info(self, index, ship, prodline): size = (260, 90) widget = Container(name='showcase_%s' % index, position=(0, 20 + index * 90), min_size=size, max_size=size, size=size) bg_icon = Icon(image='content/gui/images/background/square_80.png', name='bg_%s' % index) widget.addChild(bg_icon) image = 'content/gui/images/objects/ships/76/{unit_id}.png'.format( unit_id=ship) helptext = self.instance.session.db.get_ship_tooltip(ship) unit_icon = Icon(image=image, name='icon_%s' % index, position=(2, 2), helptext=helptext) widget.addChild(unit_icon) # if not buildable, this returns string with reason why to be displayed as helptext #ship_unbuildable = self.is_ship_unbuildable(ship) ship_unbuildable = False if not ship_unbuildable: button = OkButton(position=(60, 50), name='ok_%s' % index, helptext=_('Build this ship!')) button.capture(Callback(self.start_production, prodline)) else: button = CancelButton(position=(60, 50), name='ok_%s' % index, helptext=ship_unbuildable) widget.addChild(button) # Get production line info production = self.producer.create_production_line(prodline) # consumed == negative, reverse to sort in *ascending* order: costs = sorted(production.consumed_res.iteritems(), key=itemgetter(1)) for i, (res, amount) in enumerate(costs): xoffset = 103 + (i % 2) * 55 yoffset = 20 + (i // 2) * 20 icon = create_resource_icon(res, self.instance.session.db) icon.max_size = icon.min_size = icon.size = (16, 16) icon.position = (xoffset, yoffset) label = Label(name='cost_%s_%s' % (index, i)) if res == RES.GOLD: label.text = unicode(-amount) else: label.text = u'{amount:02}t'.format(amount=-amount) label.position = (22 + xoffset, yoffset) widget.addChild(icon) widget.addChild(label) return widget
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 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()
def _label(text, font='default'): try: return Label(text=unicode(text), wrap_text=True, min_size=(325, 0), max_size=(325, 1024), font=font) except RuntimeError: return None
def init(self, db, inventory, ordinal=None): """ @param ordinal: {res: (min, max)} Display ordinal scale with these boundaries instead of numbers for a particular resource. Currently implemented via ImageFillStatusButton. """ # check if we must init everything anew if self.init_needed(inventory): # this inits the logic of the inventory. @see __init__(). self._inited = True self.db = db self._inventory = inventory # specific to Inventory self.ordinal = ordinal self._res_order = sorted(self._inventory.iterslots()) self.legend = Label(name="legend") self.__icon = Icon(name="legend_icon") self.__icon.image = "content/gui/icons/ship/civil_16.png" if isinstance(self._inventory, TotalStorage): self.__icon.position = (130, 53) self.legend.position = (150, 53) elif isinstance(self._inventory, PositiveSizedSlotStorage): self.__icon.position = ( 0, 248) self.legend.position = (20, 248) self.update()
def update_needed_resources(self, needed_res_container): """ Update needed resources """ production = self.producer.get_productions()[0] needed_res = production.get_consumed_resources() # Now sort! -amount is the positive value, drop unnecessary res (amount 0) needed_res = dict((res, -amount) for res, amount in needed_res.items() if amount < 0) needed_res = sorted(needed_res.items(), key=itemgetter(1), reverse=True) needed_res_container.removeAllChildren() for i, (res, amount) in enumerate(needed_res): icon = create_resource_icon(res, self.instance.session.db) icon.max_size = icon.min_size = icon.size = (16, 16) label = Label(name="needed_res_lbl_%s" % i) label.text = '{amount}t'.format(amount=amount) new_hbox = HBox(name="needed_res_box_%s" % i) new_hbox.addChildren(icon, label) needed_res_container.addChild(new_hbox)
def _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
def update_needed_resources(self, needed_res_container): """ Update needed resources """ production = self.producer.get_productions()[0] needed_res = production.get_consumed_resources() # Now sort! -amount is the positive value, drop unnecessary res (amount 0) needed_res = dict((res, -amount) for res, amount in needed_res.iteritems() if amount < 0) needed_res = sorted(needed_res.iteritems(), key=itemgetter(1), reverse=True) needed_res_container.removeAllChildren() for i, (res, amount) in enumerate(needed_res): icon = create_resource_icon(res, self.instance.session.db) icon.max_size = icon.min_size = icon.size = (16, 16) label = Label(name="needed_res_lbl_%s" % i) label.text = u"{amount}t".format(amount=amount) new_hbox = HBox(name="needed_res_box_%s" % i) new_hbox.addChildren(icon, label) needed_res_container.addChild(new_hbox)
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 build_ship_info(self, index, ship, prodline): size = (260, 90) widget = Container(name='showcase_%s' % index, position=(0, 20 + index*90), min_size=size, max_size=size, size=size) bg_icon = Icon(image='content/gui/images/background/square_80.png', name='bg_%s'%index) widget.addChild(bg_icon) icon_path = 'content/gui/images/objects/ships/76/{unit_id}.png'.format(unit_id=ship) helptext = self.instance.session.db.get_ship_tooltip(ship) unit_icon = Icon(image=icon_path, name='icon_%s'%index, position=(2, 2), helptext=helptext) widget.addChild(unit_icon) # if not buildable, this returns string with reason why to be displayed as helptext #ship_unbuildable = self.is_ship_unbuildable(ship) ship_unbuildable = False if not ship_unbuildable: button = OkButton(position=(60, 50), name='ok_%s'%index, helptext=_('Build this ship!')) button.capture(Callback(self.start_production, prodline)) else: button = CancelButton(position=(60, 50), name='ok_%s'%index, helptext=ship_unbuildable) widget.addChild(button) #TODO since this code uses the boat builder as producer, the # gold cost of ships is in consumed res is always 0 since it # is paid from player inventory, not from the boat builder one. production = self.producer.create_production(prodline) # consumed == negative, reverse to sort in *ascending* order: costs = sorted(production.get_consumed_resources().iteritems(), key=itemgetter(1)) for i, (res, amount) in enumerate(costs): xoffset = 103 + (i % 2) * 55 yoffset = 20 + (i // 2) * 20 icon = create_resource_icon(res, self.instance.session.db) icon.max_size = icon.min_size = icon.size = (16, 16) icon.position = (xoffset, yoffset) label = Label(name='cost_%s_%s' % (index, i)) if res == RES.GOLD: label.text = unicode(-amount) else: label.text = u'{amount:02}t'.format(amount=-amount) label.position = (22 + xoffset, yoffset) widget.addChild(icon) widget.addChild(label) return widget
def __init__(self): super(FPSDisplay, self).__init__() self._label = Label(text=u"- - -") self.addChild(self._label) self.stylize('menu') self.position_technique = "left:bottom" self._timemanager = horizons.globals.fife.engine.getTimeManager()
def build_groundunit_info(self, index, groundunit, prodline): size = (260, 90) widget = Container(name='showcase_%s' % index, position=(0, 20 + index*90), min_size=size, max_size=size, size=size) bg_icon = Icon(image='content/gui/images/background/square_80.png', name='bg_%s'%index) widget.addChild(bg_icon) image = 'content/gui/images/objects/groundunit/76/{unit_id}.png'.format(unit_id=groundunit) helptext = self.instance.session.db.get_unit_tooltip(groundunit) unit_icon = Icon(image=image, name='icon_%s'%index, position=(2, 2), helptext=helptext) widget.addChild(unit_icon) # if not buildable, this returns string with reason why to be displayed as helptext #groundunit_unbuildable = self.is_groundunit_unbuildable(groundunit) groundunit_unbuildable = False if not groundunit_unbuildable: button = OkButton(position=(60, 50), name='ok_%s'%index, helptext=_('Build this groundunit!')) button.capture(Callback(self.start_production, prodline)) else: button = CancelButton(position=(60, 50), name='ok_%s'%index, helptext=groundunit_unbuildable) widget.addChild(button) # Get production line info production = self.producer.create_production_line(prodline) # consumed == negative, reverse to sort in *ascending* order: costs = sorted(production.consumed_res.iteritems(), key=itemgetter(1)) for i, (res, amount) in enumerate(costs): xoffset = 103 + (i % 2) * 55 yoffset = 20 + (i // 2) * 20 icon = create_resource_icon(res, self.instance.session.db) icon.max_size = icon.min_size = icon.size = (16, 16) icon.position = (xoffset, yoffset) label = Label(name='cost_%s_%s' % (index, i)) if res == RES.GOLD: label.text = unicode(-amount) else: label.text = u'{amount:02}t'.format(amount=-amount) label.position = (22 + xoffset, yoffset) widget.addChild(icon) widget.addChild(label) return widget
def __init__(self, windows): super(HelpDialog, self).__init__(windows) self.widget = load_uh_widget('help.xml') self.widget.findChild(name=OkButton.DEFAULT_NAME).capture(self._windows.close) self.widget.findChild(name='headline').text = GAMEPLAY_TIPS['name'] tip_box = self.widget.findChild(name='tip_box') size = {'max_size': (300, 60), 'min_size': (300, 20)} for tip in GAMEPLAY_TIPS['items']: tip_label = Label(text=unicode(tip), wrap_text=True, **size) tip_box.addChild(tip_label)
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 set_construction_mode(self, resource_source_instance, build_costs): """Show resources relevant to construction and build costs @param resource_source_instance: object with StorageComponent @param build_costs: dict, { res : amount } """ if resource_source_instance is None: # Build moved out of settlement. This is usually not sane and an interaction error. # Use this heuristically computed settlement to fix preconditions. resource_source_instance = LastActivePlayerSettlementManager().get() if self.construction_mode and \ resource_source_instance == self.current_instance() and \ build_costs == self._last_build_costs: return # now that's not an update self._last_build_costs = build_costs self.construction_mode = True self.set_inventory_instance(resource_source_instance, keep_construction_mode=True) # label background icons cost_icon_gold = "content/gui/images/background/widgets/resbar_stats_bottom.png" cost_icon_res = "content/gui/images/background/widgets/res_extra_bg.png" res_list = self._get_current_resources() # remove old one before, avoids duplicates self._drop_cost_labels() for res, amount in build_costs.iteritems(): assert res in res_list or res == RES.GOLD cost_label = Label(text=u"-"+unicode(amount)) cost_label.stylize( self.__class__.STYLE ) # add icon below end of background icon if res in res_list: entry = res_list.index(res) cur_gui = self.gui[ entry ] reference_icon = cur_gui.findChild(name="background_icon") below = reference_icon.size[1] cost_icon = Icon(image=cost_icon_res, position=(0, below)) cost_label.position = (15, below) # TODO: centering cur_gui.addChild(cost_icon) cur_gui.addChild(cost_label) cur_gui.cost_gui = [cost_label, cost_icon] cur_gui.resizeToContent() # container needs to be bigger now else: # must be gold # there is an icon with scales there, use its positioning reference_icon = self.gold_gui.child_finder("balance_background") cost_icon = Icon(image=cost_icon_gold, position=(reference_icon.x, reference_icon.y)) cost_label.position = (23, 74) # TODO: centering self.gold_gui.addChild(cost_icon) self.gold_gui.addChild(cost_label) self.gold_gui.cost_gui = [cost_label, cost_icon] self.gold_gui.resizeToContent()
def parse_logbook_item(self, widget): # json.loads() returns unicode, thus convert strings and compare to unicode # Image works with str() since pychan can only use str objects as file path if widget and widget[0]: # allow empty Labels widget_type = widget[0] if isinstance(widget, basestring): add = Label(text=widget, wrap_text=True, max_size=(340,508)) elif widget_type == u'Label': add = Label(text=widget[1], wrap_text=True, max_size=(340,508)) elif widget_type == u'Image': add = Icon(image=str(widget[1])) elif widget_type == u'Gallery': add = HBox() for image in widget[1]: add.addChild(Icon(image=str(image))) elif widget_type == u'Headline': add = Label(text=widget[1]) add.stylize('headline') else: print '[WW] Warning: Unknown widget type {typ} in widget {wdg}'.format( typ=widget[0], wdg=widget) add = None return add
def __init__(self, color_palette=None): """ @param widgets: WidgetsDict """ self.gui = load_uh_widget('playerdataselection.xml') self.colors = self.gui.findChild(name='playercolor') colorlabels = [] events = {} # need the id to save it as int in settings file. for color in (Color.get_defaults() if color_palette is None else color_palette): label = Label(name='{color}'.format(color=color.name), text=" ", max_size=(20, 20), min_size=(20, 20), background_color=color) events['{label}/mouseClicked'.format(label=color.name)] = \ Callback(self.set_color, color.id) colorlabels.append(label) # split into three rows with at max 5 entries in each row # right now there are 14 different colors to choose from. for i in range(0, len(colorlabels), 5): hbox = HBox(name='line_{index}'.format(index=i)) hbox.addChildren(colorlabels[i:i + 5]) self.colors.addChild(hbox) playertextfield = self.gui.findChild(name='playername') def playertextfield_clicked(): if playertextfield.text == 'Unnamed Traveler': playertextfield.text = "" playertextfield.capture(playertextfield_clicked, event_name='mouseClicked') self.gui.mapEvents(events) self.update_data()
def show_tooltip(self): if not self.helptext: return if self.gui is None: self.__init_gui() #HACK: support icons in build menu # Code below exists for the sole purpose of build menu tooltips showing # resource icons. Even supporting that is a pain (as you will see), # so if you think you need icons in other tooltips, maybe reconsider. # [These unicode() calls brought to you by status icon tooltip code.] buildmenu_icons = self.icon_regexp.findall(unicode(self.helptext)) # Remove the weird stuff before displaying text. replaced = self.icon_regexp.sub('', unicode(self.helptext)) # Specification looks like [[Buildmenu 1:250 4:2 6:2]] if buildmenu_icons: hbox = HBox(position=(7, 5), padding=0) for spec in buildmenu_icons[0].split(): (res_id, amount) = spec.split(':') label = Label(text=amount+' ') icon = Icon(image=get_res_icon_path(int(res_id)), size=(16, 16)) # For compatibility with FIFE 0.3.5 and older, also set min/max. icon.max_size = icon.min_size = (16, 16) hbox.addChildren(icon, label) hbox.adaptLayout() # Now display the 16x16px "required resources" icons in the last line. self.gui.addChild(hbox) #HACK: wrap tooltip text # This looks better than splitting into several lines and joining them. # It works because replace_whitespace in `fill` defaults to True. replaced = replaced.replace(r'\n', self.CHARS_PER_LINE * ' ') replaced = replaced.replace('[br]', self.CHARS_PER_LINE * ' ') tooltip = textwrap.fill(replaced, self.CHARS_PER_LINE) # Finish up the actual tooltip (text, background panel amount, layout). # To display build menu icons, we need another empty (first) line. self.bg.amount = len(tooltip.splitlines()) - 1 + bool(buildmenu_icons) self.label.text = bool(buildmenu_icons) * '\n' + tooltip self.gui.adaptLayout() self.gui.show()
def __init__(self, parent_gui, widgets, color_palette=None): """ Adds the playerdataselection container to a parent gui @param parent_gui: a pychan gui object containing a container named "playerdataselectioncontainer" @param widgets: WidgetsDict """ widgets.reload( 'playerdataselection' ) self.gui = widgets[ 'playerdataselection' ] self.colors = self.gui.findChild(name='playercolor') self.selected_color = horizons.globals.fife.get_uh_setting("ColorID") # starts at 1! self.set_color(self.selected_color) colorlabels = [] events = {} # need the id to save it as int in settings file. for color in (Color if color_palette is None else color_palette): label = Label(name = u'{color}'.format(color=color.name), text = u" ", max_size = (20,20), min_size = (20,20), background_color = color) events['{label}/mouseClicked'.format(label=color.name)] = \ Callback(self.set_color, color.id) colorlabels.append(label) # split into three rows with at max 5 entries in each row # right now there are 14 different colors to choose from. for i in xrange(0, len(colorlabels), 5): hbox = HBox(name='line_{index}'.format(index=i)) hbox.addChildren(colorlabels[i:i+5]) self.colors.addChild(hbox) self.gui.distributeData({ 'playername': unicode(horizons.globals.fife.get_uh_setting("Nickname")), }) parent_gui.findChild(name="playerdataselectioncontainer").addChild( self.gui ) parent_gui.mapEvents(events)
def parse_logbook_item(self, parameter): # json.loads() returns unicode, thus convert strings and compare to unicode # Image works with str() since pychan can only use str objects as file path if parameter and parameter[0]: # allow empty Labels parameter_type = parameter[0] if isinstance(parameter, basestring): add = Label(text=unicode(parameter), wrap_text=True, min_size=(335, 0), max_size=(335, 508)) elif parameter_type == u'Label': add = Label(text=unicode(parameter[1]), wrap_text=True, min_size=(335, 0), max_size=(335, 508)) elif parameter_type == u'Image': add = Icon(image=str(parameter[1])) elif parameter_type == u'Gallery': add = HBox() for image in parameter[1]: add.addChild(Icon(image=str(image))) elif parameter_type == u'Headline': add = Label(text=unicode(parameter[1]), wrap_text=True, min_size=(335, 0), max_size=(335, 508), font='headline') elif parameter_type == u'BoldLabel': add = Label(text=unicode(parameter[1]), wrap_text=True, min_size=(335, 0), max_size=(335, 508), font='14_bold') elif parameter_type == u'Message': add = None # parameters are re-read on page reload. # duplicate_message stops messages from # being duplicated on page reload. message = parameter[1] duplicate_message = message in self._messages_to_display # message is already going to be displayed if not duplicate_message: self._messages_to_display.append(message) # the new message has not been displayed else: print '[WW] Warning: Unknown parameter type {typ} in parameter {prm}'.format( typ=parameter[0], prm=parameter) add = None return add
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) pkick.helptext = _("Kick {player}").format(player=name) pkick.capture(Callback(NetworkInterface().kick, player['sid'])) pkick.path = "images/buttons/delete_small" pkick.min_size = pkick.max_size = (20, 15) hbox.addChild(pkick) players_vbox.addChildren(hbox, picon)
def __init_gui(self): self.gui = ABox() self.label = Label(position=(10, 5)) self.bg = TooltipBG() self.gui.addChildren(self.bg, self.label)
def show_tooltip(self): if not self.helptext: return if self.gui is None: self.__init_gui() # Compare and reset timer value if difference from current time shorter than X sec. if (time.time() - self.cooldown) < 1: return else: self.cooldown = time.time() #HACK: support icons in build menu # Code below exists for the sole purpose of build menu tooltips showing # resource icons. Even supporting that is a pain (as you will see), # so if you think you need icons in other tooltips, maybe reconsider. # [These unicode() calls brought to you by status icon tooltip code.] buildmenu_icons = self.icon_regexp.findall(str(self.helptext)) # Remove the weird stuff before displaying text. replaced = self.icon_regexp.sub('', str(self.helptext)) # Specification looks like [[Buildmenu 1:250 4:2 6:2]] if buildmenu_icons: hbox = HBox(position=(7, 5)) for spec in buildmenu_icons[0].split(): (res_id, amount) = spec.split(':') label = Label(text=amount + ' ') icon = Icon(image=get_res_icon_path(int(res_id)), size=(16, 16), scale=True) hbox.addChildren(icon, label) hbox.adaptLayout() # Now display the 16x16px "required resources" icons in the last line. self.gui.addChild(hbox) #HACK: wrap tooltip text # This looks better than splitting into several lines and joining them. # It works because replace_whitespace in `fill` defaults to True. replaced = replaced.replace(r'\n', self.CHARS_PER_LINE * ' ') replaced = replaced.replace('[br]', self.CHARS_PER_LINE * ' ') tooltip = textwrap.fill(replaced, self.CHARS_PER_LINE) # Finish up the actual tooltip (text, background panel amount, layout). # To display build menu icons, we need another empty (first) line. self.bg.amount = len(tooltip.splitlines()) - 1 + bool(buildmenu_icons) self.label.text = bool(buildmenu_icons) * '\n' + tooltip self.gui.adaptLayout() self.gui.show() # NOTE: the below code in this method is a hack to resolve #2227 # cannot find a better way to fix it, cause in fife.pychan, it seems # if a widget gets hidden or removed, the children of that widget are not # hidden or removed properly (at least in Python code) # update topmost_widget every time the tooltip is shown # this is to dismiss the tooltip later, see _check_hover_alive target_widget = self while target_widget: self.topmost_widget = target_widget target_widget = target_widget.parent # add an event to constantly check whether the hovered widget is still there # if this is no longer there, dismiss the tooltip widget ExtScheduler().add_new_object(self._check_hover_alive, self, run_in=0.5, loops=-1)
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 refresh(self): """This function is called by the TabWidget to redraw the widget.""" super(BoatbuilderTab, self).refresh() main_container = self.widget.findChild(name="BB_main_tab") container_active = main_container.findChild(name="container_active") container_inactive = main_container.findChild(name="container_inactive") progress_container = main_container.findChild(name="BB_progress_container") cancel_container = main_container.findChild(name="BB_cancel_container") needed_res_container = self.widget.findChild(name="BB_needed_resources_container") # a boatbuilder is considered active here if it build sth, no matter if it's paused production_lines = self.producer.get_production_lines() if production_lines: cancel_container.parent.showChild(cancel_container) # Set progress progress_container.parent.showChild(progress_container) progress = math.floor(self.producer.get_production_progress() * 100) self.widget.findChild(name='progress').progress = progress progress_perc = self.widget.findChild(name='BB_progress_perc') progress_perc.text = u'{progress}%'.format(progress=progress) container_active.parent.showChild(container_active) if not container_inactive in container_inactive.parent.hidden_children: container_inactive.parent.hideChild(container_inactive) # Update boatbuilder queue queue = self.producer.get_unit_production_queue() queue_container = container_active.findChild(name="queue_container") queue_container.removeAllChildren() for place_in_queue, unit_type in enumerate(queue): image = self.__class__.SHIP_THUMBNAIL.format(type_id=unit_type) helptext = _(u"{ship} (place in queue: {place})") #xgettext:python-format helptext.format(ship=self.instance.session.db.get_unit_type_name(unit_type), place=place_in_queue+1) # people don't count properly, always starting at 1.. icon_name = "queue_elem_"+str(place_in_queue) icon = Icon(name=icon_name, image=image, helptext=helptext) rm_from_queue_cb = Callback(RemoveFromQueue(self.producer, place_in_queue).execute, self.instance.session) icon.capture(rm_from_queue_cb, event_name="mouseClicked") queue_container.addChild( icon ) # Set built ship info production_line = self.producer._get_production(production_lines[0]) produced_unit_id = production_line.get_produced_units().keys()[0] name = self.instance.session.db.get_unit_type_name(produced_unit_id) container_active.findChild(name="headline_BB_builtship_label").text = _(name) ship_icon = container_active.findChild(name="BB_cur_ship_icon") ship_icon.helptext = self.instance.session.db.get_ship_tooltip(produced_unit_id) ship_icon.image = self.__class__.SHIP_PREVIEW_IMG.format(type_id=produced_unit_id) button_active = container_active.findChild(name="toggle_active_active") button_inactive = container_active.findChild(name="toggle_active_inactive") to_active = not self.producer.is_active() if not to_active: # swap what we want to show and hide button_active, button_inactive = button_inactive, button_active if not button_active in button_active.parent.hidden_children: button_active.parent.hideChild(button_active) button_inactive.parent.showChild(button_inactive) set_active_cb = Callback(self.producer.set_active, active=to_active) button_inactive.capture(set_active_cb, event_name="mouseClicked") upgrades_box = container_active.findChild(name="BB_upgrades_box") upgrades_box.removeAllChildren() # upgrades_box.addChild(Label(text=u"+ love")) # upgrades_box.addChild(Label(text=u"+ affection")) # no upgrades in 2010.1 release ---^ upgrades_box.stylize('menu_black') # Update needed resources production = self.producer.get_productions()[0] needed_res = production.get_consumed_resources() # Now sort! -amount is the positive value, drop unnecessary res (amount 0) needed_res = dict((res, -amount) for res, amount in needed_res.iteritems() if amount < 0) needed_res = sorted(needed_res.iteritems(), key=itemgetter(1), reverse=True) needed_res_container.removeAllChildren() for i, (res, amount) in enumerate(needed_res): icon = create_resource_icon(res, self.instance.session.db) icon.max_size = icon.min_size = icon.size = (16, 16) label = Label(name="needed_res_lbl_%s" % i) label.text = u'{amount}t'.format(amount=amount) new_hbox = HBox(name="needed_res_box_%s" % i) new_hbox.addChildren(icon, label) needed_res_container.addChild(new_hbox) cancel_button = self.widget.findChild(name="BB_cancel_button") cancel_cb = Callback(CancelCurrentProduction(self.producer).execute, self.instance.session) cancel_button.capture(cancel_cb, event_name="mouseClicked") else: # display sth when nothing is produced container_inactive.parent.showChild(container_inactive) for w in (container_active, progress_container, cancel_container): if not w in w.parent.hidden_children: w.parent.hideChild(w) self.widget.adaptLayout()
def _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 refresh(self): """This function is called by the TabWidget to redraw the widget.""" super(BoatbuilderTab, self).refresh() THUMB_PATH = "content/gui/images/objects/ships/116/%s.png" main_container = self.widget.findChild(name="BB_main_tab") container_active = main_container.findChild(name="container_active") container_inactive = main_container.findChild(name="container_inactive") progress_container = main_container.findChild(name="BB_progress_container") cancel_container = main_container.findChild(name="BB_cancel_container") needed_res_container = self.widget.findChild(name="BB_needed_resources_container") # a boatbuilder is considered active here if it build sth, no matter if it's paused production_lines = self.producer.get_production_lines() if production_lines: if cancel_container is None: main_container.addChild(main_container.cancel_container) cancel_container = main_container.cancel_container if needed_res_container is None: main_container.insertChildBefore(main_container.needed_res_container, cancel_container) needed_res_container = main_container.needed_res_container # Set progress if progress_container is None: main_container.insertChildBefore( main_container.progress_container, self.widget.findChild(name="BB_needed_resources_container")) progress_container = main_container.progress_container progress = math.floor(self.producer.get_production_progress() * 100) self.widget.findChild(name='progress').progress = progress self.widget.findChild(name='BB_progress_perc').text = u'{progress}%'.format(progress=progress) # remove other container, but save it if container_inactive is not None: main_container.container_inactive = container_inactive main_container.removeChild( container_inactive ) if container_active is None: main_container.insertChildBefore( main_container.container_active, progress_container) container_active = main_container.container_active # Update boatbuilder queue queue = self.producer.get_unit_production_queue() queue_container = container_active.findChild(name="queue_container") queue_container.removeAllChildren() for place_in_queue, unit_type in enumerate(queue): image = self.__class__.SHIP_THUMBNAIL.format(type_id=unit_type) #xgettext:python-format helptext = _(u"{ship} (place in queue: {place})").format( ship=self.instance.session.db.get_unit_type_name(unit_type), place=place_in_queue+1 ) # people don't count properly, always starting at 1.. icon_name = "queue_elem_"+str(place_in_queue) icon = Icon(name=icon_name, image=image, helptext=helptext) icon.capture( Callback(RemoveFromQueue(self.producer, place_in_queue).execute, self.instance.session), event_name="mouseClicked" ) queue_container.addChild( icon ) # Set built ship info produced_unit_id = self.producer._get_production(production_lines[0]).get_produced_units().keys()[0] name = self.instance.session.db.get_unit_type_name(produced_unit_id) container_active.findChild(name="headline_BB_builtship_label").text = _(name) container_active.findChild(name="BB_cur_ship_icon").helptext = "Storage: 4 slots, 120t \nHealth: 100" container_active.findChild(name="BB_cur_ship_icon").image = THUMB_PATH % produced_unit_id button_active = container_active.findChild(name="toggle_active_active") button_inactive = container_active.findChild(name="toggle_active_inactive") if not self.producer.is_active(): # if production is paused # remove active button, if it's there, and save a reference to it if button_active is not None: container_active.button_active = button_active container_active.removeChild( button_active ) # restore inactive button, if it isn't in the gui if button_inactive is None: # insert at the end container_active.insertChild(container_active.button_inactive, len(container_active.children)) container_active.mapEvents({ 'toggle_active_inactive' : Callback(self.producer.set_active, active=True) }) # TODO: make this button do sth else: # remove inactive button, if it's there, and save a reference to it if button_inactive is not None: container_active.button_inactive = button_inactive container_active.removeChild( button_inactive ) # restore active button, if it isn't in the gui if button_active is None: # insert at the end container_active.insertChild(container_active.button_active, len(container_active.children)) container_active.mapEvents({ 'toggle_active_active' : Callback(self.producer.set_active, active=False) }) upgrades_box = container_active.findChild(name="BB_upgrades_box") for child in upgrades_box.children[:]: upgrades_box.removeChild(child) # upgrades_box.addChild( pychan.widgets.Label(text=u"+ love") ) # upgrades_box.addChild( pychan.widgets.Label(text=u"+ affection") ) # no upgrades in 2010.1 release ---^ upgrades_box.stylize('menu_black') # Update needed resources production = self.producer.get_productions()[0] needed_res = production.get_consumed_resources() # Now sort! -amount is the positive value, drop unnecessary res (amount 0) needed_res = dict((res, -amount) for res, amount in needed_res.iteritems() if amount < 0) needed_res = sorted(needed_res.iteritems(), key=itemgetter(1), reverse=True) needed_res_container.removeAllChildren() for i, (res, amount) in enumerate(needed_res): icon = create_resource_icon(res, self.instance.session.db) icon.max_size = icon.min_size = icon.size = (16, 16) label = Label(name="needed_res_lbl_%s" % i) label.text = u'{amount}t'.format(amount=amount) new_hbox = HBox(name="needed_res_box_%s" % i) new_hbox.addChildren(icon, label) needed_res_container.addChild(new_hbox) cancel_button = self.widget.findChild(name="BB_cancel_button") cancel_cb = Callback(CancelCurrentProduction(self.producer).execute, self.instance.session) cancel_button.capture(cancel_cb, event_name="mouseClicked") else: # display sth when nothing is produced # remove other container, but save it if container_active is not None: main_container.container_active = container_active main_container.removeChild( container_active ) if container_inactive is None: main_container.insertChildBefore( main_container.container_inactive, progress_container) container_inactive = main_container.container_inactive if progress_container is not None: main_container.progress_container = progress_container main_container.removeChild(progress_container) if needed_res_container is not None: main_container.needed_res_container = needed_res_container main_container.removeChild(needed_res_container) if cancel_container is not None: main_container.cancel_container = cancel_container main_container.removeChild(cancel_container) self.widget.adaptLayout()
def _add_line_to_gui(self, ship, sequence_number): sequence_number_label = Label(name='sequence_number_{:d}'.format(ship.worldid)) sequence_number_label.text = str(sequence_number) sequence_number_label.min_size = sequence_number_label.max_size = (15, 20) ship_name = Label(name='ship_name_{:d}'.format(ship.worldid)) ship_name.text = ship.get_component(NamedComponent).name ship_name.min_size = ship_name.max_size = (100, 20) from horizons.engine.pychan_util import RenameImageButton rename_icon = RenameImageButton(name='rename_{:d}'.format(ship.worldid)) rename_icon.path = "images/background/rename_feather_20" rename_icon.helptext = T("Click to change the name of this ship") rename_icon.max_size = (20, 20) # (width, height) ship_type = Label(name='ship_type_{:d}'.format(ship.worldid)) ship_type.text = ship.classname ship_type.min_size = ship_type.max_size = (60, 20) weapons = Label(name='weapons_{:d}'.format(ship.worldid)) if isinstance(ship, FightingShip): weapon_list = [] for weapon_id, amount in sorted(ship.get_weapon_storage().itercontents()): weapon_list.append('{:d} {}'.format(amount, self.session.db.get_res_name(weapon_id))) if weapon_list: weapons.text = ', '.join(weapon_list) else: #i18n There are no weapons equipped at the moment. weapons.text = T('None') else: weapons.text = T('N/A') weapons.min_size = weapons.max_size = (60, 20) health = Label(name='health_{:d}'.format(ship.worldid)) health_component = ship.get_component(HealthComponent) health.text = '{:.1f}/{:.1f}'.format(health_component.health, health_component.max_health) health.min_size = health.max_size = (65, 20) status = Label(name='status_{:d}'.format(ship.worldid)) status.text, status_position = ship.get_status() status.min_size = status.max_size = (320, 20) hbox = HBox() hbox.addChild(sequence_number_label) hbox.addChild(ship_name) hbox.addChild(rename_icon) hbox.addChild(ship_type) hbox.addChild(weapons) hbox.addChild(health) hbox.addChild(status) self._content_vbox.addChild(hbox) return (ship_name, rename_icon, status, status_position)
def __init_gui(self): self.gui = AutoResizeContainer() self.label = Label(position=(10, 5)) self.bg = TooltipBG() self.gui.addChildren(self.bg, self.label)
def refresh(self): """This function is called by the TabWidget to redraw the widget.""" super(BoatbuilderTab, self).refresh() main_container = self.widget.findChild(name="BB_main_tab") container_active = main_container.findChild(name="container_active") container_inactive = main_container.findChild( name="container_inactive") progress_container = main_container.findChild( name="BB_progress_container") cancel_container = main_container.findChild(name="BB_cancel_container") needed_res_container = self.widget.findChild( name="BB_needed_resources_container") # a boatbuilder is considered active here if it builds sth, no matter if it's paused production_lines = self.producer.get_production_lines() if production_lines: cancel_container.parent.showChild(cancel_container) # Set progress progress_container.parent.showChild(progress_container) progress = math.floor(self.producer.get_production_progress() * 100) self.widget.findChild(name='progress').progress = progress progress_perc = self.widget.findChild(name='BB_progress_perc') progress_perc.text = u'{progress}%'.format(progress=progress) container_active.parent.showChild(container_active) if (Fife.getVersion() >= (0, 4, 0)): container_inactive.parent.hideChild(container_inactive) else: if not container_inactive in container_inactive.parent.hidden_children: container_inactive.parent.hideChild(container_inactive) # Update boatbuilder queue queue = self.producer.get_unit_production_queue() queue_container = container_active.findChild( name="queue_container") queue_container.removeAllChildren() for place_in_queue, unit_type in enumerate(queue): image = self.__class__.SHIP_THUMBNAIL.format(type_id=unit_type) helptext = _("{ship} (place in queue: {place})").format( ship=self.instance.session.db.get_unit_type_name( unit_type), place=place_in_queue + 1) # people don't count properly, always starting at 1.. icon_name = "queue_elem_" + str(place_in_queue) icon = Icon(name=icon_name, image=image, helptext=helptext) rm_from_queue_cb = Callback( RemoveFromQueue(self.producer, place_in_queue).execute, self.instance.session) icon.capture(rm_from_queue_cb, event_name="mouseClicked") queue_container.addChild(icon) # Set built ship info production_line = self.producer._get_production( production_lines[0]) produced_unit_id = production_line.get_produced_units().keys()[0] name = self.instance.session.db.get_unit_type_name( produced_unit_id) container_active.findChild( name="headline_BB_builtship_label").text = _(name) ship_icon = container_active.findChild(name="BB_cur_ship_icon") ship_icon.helptext = self.instance.session.db.get_ship_tooltip( produced_unit_id) ship_icon.image = self.__class__.SHIP_PREVIEW_IMG.format( type_id=produced_unit_id) button_active = container_active.findChild( name="toggle_active_active") button_inactive = container_active.findChild( name="toggle_active_inactive") to_active = not self.producer.is_active() if not to_active: # swap what we want to show and hide button_active, button_inactive = button_inactive, button_active if (Fife.getVersion() >= (0, 4, 0)): button_active.parent.hideChild(button_active) else: if not button_active in button_active.parent.hidden_children: button_active.parent.hideChild(button_active) button_inactive.parent.showChild(button_inactive) set_active_cb = Callback(self.producer.set_active, active=to_active) button_inactive.capture(set_active_cb, event_name="mouseClicked") upgrades_box = container_active.findChild(name="BB_upgrades_box") upgrades_box.removeAllChildren() # Update needed resources production = self.producer.get_productions()[0] needed_res = production.get_consumed_resources() # Now sort! -amount is the positive value, drop unnecessary res (amount 0) needed_res = dict((res, -amount) for res, amount in needed_res.iteritems() if amount < 0) needed_res = sorted(needed_res.iteritems(), key=itemgetter(1), reverse=True) needed_res_container.removeAllChildren() for i, (res, amount) in enumerate(needed_res): icon = create_resource_icon(res, self.instance.session.db) icon.max_size = icon.min_size = icon.size = (16, 16) label = Label(name="needed_res_lbl_%s" % i) label.text = u'{amount}t'.format(amount=amount) new_hbox = HBox(name="needed_res_box_%s" % i) new_hbox.addChildren(icon, label) needed_res_container.addChild(new_hbox) cancel_button = self.widget.findChild(name="BB_cancel_button") cancel_cb = Callback( CancelCurrentProduction(self.producer).execute, self.instance.session) cancel_button.capture(cancel_cb, event_name="mouseClicked") else: # display sth when nothing is produced container_inactive.parent.showChild(container_inactive) for w in (container_active, progress_container, cancel_container): if (Fife.getVersion() >= (0, 4, 0)): w.parent.hideChild(w) else: if not w in w.parent.hidden_children: w.parent.hideChild(w) self.widget.adaptLayout()
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): # search empty slot if not self._inventory[self._res_order[i]]: # 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: if isinstance(self._inventory, TotalStorage): # Add total storage indicator sum_stored_res = self._inventory.get_sum_of_stored_resources() label = 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 = 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)
def parse_logbook_item(self, parameter): # json.loads() returns unicode, thus convert strings and compare to unicode # Image works with str() since pychan can only use str objects as file path if parameter and parameter[0]: # allow empty Labels parameter_type = parameter[0] if isinstance(parameter, basestring): add = Label(text=unicode(parameter), wrap_text=True, min_size=(335, 0), max_size=(335, 508)) elif parameter_type == u'Label': add = Label(text=unicode(parameter[1]), wrap_text=True, min_size=(335, 0), max_size=(335, 508)) elif parameter_type == u'Image': add = Icon(image=str(parameter[1])) elif parameter_type == u'Gallery': add = HBox() for image in parameter[1]: add.addChild(Icon(image=str(image))) elif parameter_type == u'Headline': add = Label(text=unicode(parameter[1]), wrap_text=True, min_size=(335, 0), max_size=(335, 508), font='headline') elif parameter_type == u'BoldLabel': add = Label(text=unicode(parameter[1]), wrap_text=True, min_size=(335, 0), max_size=(335, 508), font='14_bold') elif parameter_type == u'Message': add = None # parameters are re-read on page reload. # duplicate_message stops messages from # being duplicated on page reload. message = parameter[1] # message is already going to be displayed or has been displayed # before (e.g. re-opening older logbook pages) duplicate_message = (message in self._messages_to_display or message in self._message_log) if not duplicate_message: self._messages_to_display.append(message) # the new message has not been displayed else: print '[WW] Warning: Unknown parameter type {typ} in parameter {prm}'.format( typ=parameter[0], prm=parameter) add = None return add
def _add_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)