def __init__(self, player, resource_id, amount, gold, **kwargs): super(TradeHistoryItem, self).__init__(**kwargs) self.widget = load_uh_widget('trade_history_item.xml') self.addChild(self.widget) self.findChild(name='player_emblem').background_color = player.color self.findChild(name='player_name').text = player.name gold_amount_label = self.findChild(name='gold_amount') gold_amount_label.text = u'{gold:+5d}'.format(gold=gold) gold_icon = self.findChild(name='gold_icon') gold_icon.image = get_res_icon_path(RES.GOLD) gold_icon.max_size = gold_icon.min_size = gold_icon.size = (16, 16) gold_icon.helptext = player.session.db.get_res_name(RES.GOLD) resource_amount_label = self.findChild(name='resource_amount') resource_amount_label.text = u'{amount:+5d}'.format(amount=amount) resource_icon = self.findChild(name='resource_icon') resource_icon.image = get_res_icon_path(resource_id) resource_icon.max_size = resource_icon.min_size = resource_icon.size = (16, 16) resource_icon.helptext = player.session.db.get_res_name(resource_id) self.size = self.widget.size
def __init__(self, player, resource_id, amount, gold, **kwargs): super(TradeHistoryItem, self).__init__(**kwargs) self.widget = load_uh_widget('trade_history_item.xml') self.addChild(self.widget) self.findChild(name='player_emblem').background_color = player.color self.findChild(name='player_name').text = player.name gold_amount_label = self.findChild(name='gold_amount') gold_amount_label.text = u'{gold:+5d}'.format(gold=gold) gold_icon = self.findChild(name='gold_icon') gold_icon.image = get_res_icon_path(RES.GOLD) gold_icon.max_size = gold_icon.min_size = gold_icon.size = (16, 16) gold_icon.helptext = player.session.db.get_res_name(RES.GOLD) resource_amount_label = self.findChild(name='resource_amount') resource_amount_label.text = u'{amount:+5d}'.format(amount=amount) resource_icon = self.findChild(name='resource_icon') resource_icon.image = get_res_icon_path(resource_id) resource_icon.max_size = resource_icon.min_size = resource_icon.size = ( 16, 16) resource_icon.helptext = player.session.db.get_res_name(resource_id) self.size = self.widget.size
def init_for_res(cls, db, res, amount=0, filled=0, marker=0, use_inactive_icon=True, uncached=False, showprice=False): """Inites the button to display the icons for res @param db: dbreader to get info about res icon. @param res: resource id @param amount: int amount of res (used to decide inactiveness and as text) @param filled: percent of fill status (values are ints in [0, 100]) @param use_inactive_icon: whether to use inactive icon if amount == 0 @param uncached: force no cache. see __init__() @return: ImageFillStatusButton instance""" greyscale = use_inactive_icon and amount == 0 path = get_res_icon_path(res, cls.ICON_SIZE[0], greyscale, full_path=False) if showprice: value = db.get_res_value(res) if TRADER.PRICE_MODIFIER_BUY == TRADER.PRICE_MODIFIER_SELL: helptext = T('{resource_name}: {price} gold').format(resource_name=db.get_res_name(res), price=db.get_res_value(res)) else: buyprice = value * TRADER.PRICE_MODIFIER_BUY sellprice = value * TRADER.PRICE_MODIFIER_SELL helptext = (u'{resource_name}[br]'.format(resource_name=db.get_res_name(res)) + T('buy for {buyprice} gold').format(buyprice=buyprice) + u'[br]' + T('sell for {sellprice} gold').format(sellprice=sellprice)) else: helptext = db.get_res_name(res) return cls(path=path, text=unicode(amount), helptext=helptext, size=cls.CELL_SIZE, res_id=res, filled=filled, max_size=cls.CELL_SIZE, min_size=cls.CELL_SIZE, marker=marker, uncached=uncached)
def init_for_res(cls, db, res, amount=0, filled=0, marker=0, use_inactive_icon=True, uncached=False): """Inites the button to display the icons for res @param db: dbreader to get info about res icon. @param res: resource id @param amount: int amount of res (used to decide inactiveness and as text) @param filled: percent of fill status (values are ints in [0, 100]) @param use_inactive_icon: whether to use inactive icon if amount == 0 @param uncached: force no cache. see __init__() @return: ImageFillStatusButton instance""" greyscale = use_inactive_icon and amount == 0 image = get_res_icon_path(res, 32, greyscale) helptext = db.get_res_name(res) return cls(up_image=image, down_image=image, hover_image=image, text=unicode(amount), helptext=helptext, size=cls.CELL_SIZE, res_id=res, filled=filled, marker=marker, uncached=uncached)
def __render_icon(self, instance, group, res, amount): """ This renders the icon. It calculates the position of the icon. Most parts of this were copied from horizons/world/managers/statusiconmanager.py """ # TODO: Try to unify the __render methods of this class and statusiconmanager.py! self.renderer.removeAll(group) pos = instance.position # self.run[group] is used for the moving up animation # use -50 here to get some more offset in height bg_rel = fife.Point(0, -50 - self.run[group]) rel = fife.Point(-14, -50 - self.run[group]) self.run[group] += self.animation_steps loc = fife.Location(self.layer) loc.setExactLayerCoordinates( fife.ExactModelCoordinate( pos.origin.x + float(pos.width) / 4, pos.origin.y + float(pos.height) / 4, )) bg_node = fife.RendererNode(loc, bg_rel) node = fife.RendererNode(loc, rel) bg_image = horizons.globals.fife.imagemanager.load(self.background) res_icon = horizons.globals.fife.imagemanager.load( get_res_icon_path(res)) font = horizons.globals.fife.pychanmanager.getFont('mainmenu') self.renderer.addImage(group, bg_node, bg_image) self.renderer.resizeImage(group, node, res_icon, 24, 24) self.renderer.addText(group, node, font, ' ' * 9 + '{amount:>2d}'.format(amount=amount))
def __init__(self, session): from horizons.session import Session assert isinstance(session, Session) self.session = session # special slot because of special properties self.gold_gui = load_uh_widget(self.__class__.GOLD_ENTRY_GUI_FILE, style=self.__class__.STYLE) self.gold_gui.balance_visible = False self.gold_gui.child_finder = PychanChildFinder(self.gold_gui) self.gold_gui.child_finder("res_icon").image = get_res_icon_path(RES.GOLD, 32) self.gui = [] # list of slots self.resource_configurations = weakref.WeakKeyDictionary() self.current_instance = weakref.ref(self) # can't weakref to None self.construction_mode = False self._last_build_costs = None self._do_show_dummy = False self._update_default_configuration() NewPlayerSettlementHovered.subscribe(self._on_different_settlement) TabWidgetChanged.subscribe(self._on_tab_widget_changed) # set now and then every 2 sec ExtScheduler().add_new_object(self._update_balance_display, self, run_in=0) ExtScheduler().add_new_object(self._update_balance_display, self, run_in=2, loops=-1)
def __render_icon(self, instance, group, res, amount): """ This renders the icon. It calculates the position of the icon. Most parts of this were copied from horizons/world/managers/statusiconmanager.py """ # TODO: Try to unify the __render methods of this class and statusiconmanager.py! self.renderer.removeAll(group) pos = instance.position # self.run[group] is used for the moving up animation # use -50 here to get some more offset in height bg_rel = fife.Point(0, -50 - self.run[group]) rel = fife.Point(-14, -50 - self.run[group]) self.run[group] += self.animation_steps loc = fife.Location(self.layer) loc.setExactLayerCoordinates( fife.ExactModelCoordinate( pos.origin.x + float(pos.width) / 4, pos.origin.y + float(pos.height) / 4, ) ) bg_node = fife.RendererNode(loc, bg_rel) node = fife.RendererNode(loc, rel) bg_image = horizons.main.fife.imagemanager.load(self.background) res_icon = horizons.main.fife.imagemanager.load(get_res_icon_path(res)) font = horizons.main.fife.pychanmanager.getFont('mainmenu') self.renderer.addImage(group, bg_node, bg_image) self.renderer.resizeImage(group, node, res_icon, 24, 24) self.renderer.addText(group, node, font, ' '*9 + '{amount:>2d}'.format(amount=amount))
def init_for_res(cls, db, res, amount=0, filled=0, marker=0, use_inactive_icon=True, uncached=False, showprice=False): """Inites the button to display the icons for res @param db: dbreader to get info about res icon. @param res: resource id @param amount: int amount of res (used to decide inactiveness and as text) @param filled: percent of fill status (values are ints in [0, 100]) @param use_inactive_icon: whether to use inactive icon if amount == 0 @param uncached: force no cache. see __init__() @return: ImageFillStatusButton instance""" greyscale = use_inactive_icon and amount == 0 path = get_res_icon_path(res, cls.ICON_SIZE[0], greyscale, full_path=False) if showprice: value = db.get_res_value(res) if TRADER.PRICE_MODIFIER_BUY == TRADER.PRICE_MODIFIER_SELL: helptext = T('{resource_name}: {price} gold').format(resource_name=db.get_res_name(res), price=db.get_res_value(res)) else: buyprice = value * TRADER.PRICE_MODIFIER_BUY sellprice = value * TRADER.PRICE_MODIFIER_SELL helptext = ('{resource_name}[br]'.format(resource_name=db.get_res_name(res)) + T('buy for {buyprice} gold').format(buyprice=buyprice) + '[br]' + T('sell for {sellprice} gold').format(sellprice=sellprice)) else: helptext = db.get_res_name(res) return cls(path=path, text=str(amount), helptext=helptext, size=cls.CELL_SIZE, res_id=res, filled=filled, max_size=cls.CELL_SIZE, min_size=cls.CELL_SIZE, marker=marker, uncached=uncached)
def __init__(self, session): from horizons.session import Session assert isinstance(session, Session) self.session = session # special slot because of special properties self.gold_gui = load_uh_widget(self.__class__.GOLD_ENTRY_GUI_FILE, style=self.__class__.STYLE) self.gold_gui.balance_visible = False self.gold_gui.child_finder = PychanChildFinder(self.gold_gui) gold_icon = self.gold_gui.child_finder("res_icon") gold_icon.image = get_res_icon_path(RES.GOLD) gold_icon.max_size = gold_icon.min_size = gold_icon.size = (32, 32) self.gold_gui.mapEvents({ "resbar_gold_container/mouseClicked/stats" : self._toggle_stats, }) self.gold_gui.helptext = _("Click to show statistics") self.stats_gui = None self.gui = [] # list of slots self.resource_configurations = weakref.WeakKeyDictionary() self.current_instance = weakref.ref(self) # can't weakref to None self.construction_mode = False self._last_build_costs = None self._do_show_dummy = False self._update_default_configuration() NewPlayerSettlementHovered.subscribe(self._on_different_settlement) TabWidgetChanged.subscribe(self._on_tab_widget_changed) # set now and then every few sec ExtScheduler().add_new_object(self._update_balance_display, self, run_in=0) ExtScheduler().add_new_object(self._update_balance_display, self, run_in=Player.STATS_UPDATE_INTERVAL, loops=-1)
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), scale=True) # 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() # 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 _init_gui(self): """ Initial init of gui. widgets : list of route entry widgets slots : dict with slots for each entry """ self._gui = load_uh_widget("configure_route.xml", center_widget=True) self.widgets = [] self.slots = {} self.slots_per_entry = 3 icon = self._gui.findChild(name="minimap") self.minimap = Minimap(icon, session=self.session, world=self.session.world, view=self.session.view, targetrenderer=horizons.globals.fife.targetrenderer, imagemanager=horizons.globals.fife.imagemanager, cam_border=False, use_rotation=False, on_click=self.on_map_click) resources = self.session.db.get_res(only_tradeable=True) # map an icon for a resource # map a resource for an icon self.resource_for_icon = {self.dummy_icon_path: 0} self.icon_for_resource = {0: self.dummy_icon_path} for res_id in resources: icon = get_res_icon_path(res_id) self.resource_for_icon[icon] = res_id self.icon_for_resource[res_id] = icon # don't do any actions if the resource menu is shown self.resource_menu_shown = False for entry in self.instance.route.waypoints: self.add_gui_entry(entry['warehouse'], entry['resource_list']) self._check_no_entries_label() wait_at_unload_box = self._gui.findChild(name="wait_at_unload") wait_at_unload_box.marked = self.instance.route.wait_at_unload def toggle_wait_at_unload(): self._route_cmd("set_wait_at_unload", not self.instance.route.wait_at_unload) wait_at_unload_box.capture(toggle_wait_at_unload) wait_at_load_box = self._gui.findChild(name="wait_at_load") wait_at_load_box.marked = self.instance.route.wait_at_load def toggle_wait_at_load(): self._route_cmd("set_wait_at_load", not self.instance.route.wait_at_load) wait_at_load_box.capture(toggle_wait_at_load) self._gui.mapEvents({ OkButton.DEFAULT_NAME : self._windows.close, 'start_route/mouseClicked' : self.toggle_route })
def _init_gui(self): """ Initial init of gui. widgets : list of route entry widgets slots : dict with slots for each entry """ self._gui = load_uh_widget("configure_route.xml", center_widget=True) self.widgets = [] self.slots = {} icon = self._gui.findChild(name="minimap") self.minimap = Minimap(icon, session=self.session, world=self.session.world, view=self.session.view, targetrenderer=horizons.globals.fife.targetrenderer, imagemanager=horizons.globals.fife.imagemanager, cam_border=False, use_rotation=False, on_click=self.on_map_click) resources = self.session.db.get_res(only_tradeable=True) # map an icon for a resource # map a resource for an icon self.resource_for_icon = {self.dummy_icon_path: 0} self.icon_for_resource = {0: self.dummy_icon_path} for res_id in resources: icon = get_res_icon_path(res_id) self.resource_for_icon[icon] = res_id self.icon_for_resource[res_id] = icon # don't do any actions if the resource menu is shown self.resource_menu_shown = False for entry in self.instance.route.waypoints: self.add_gui_entry(entry['warehouse'], entry['resource_list']) self._check_no_entries_label() wait_at_unload_box = self._gui.findChild(name="wait_at_unload") wait_at_unload_box.marked = self.instance.route.wait_at_unload def toggle_wait_at_unload(): self._route_cmd("set_wait_at_unload", not self.instance.route.wait_at_unload) wait_at_unload_box.capture(toggle_wait_at_unload) wait_at_load_box = self._gui.findChild(name="wait_at_load") wait_at_load_box.marked = self.instance.route.wait_at_load def toggle_wait_at_load(): self._route_cmd("set_wait_at_load", not self.instance.route.wait_at_load) wait_at_load_box.capture(toggle_wait_at_load) self._gui.mapEvents({ OkButton.DEFAULT_NAME: self._windows.close, 'start_route/mouseClicked': self.toggle_route, })
def get_res_id_and_icon(self, only_tradeable=False, only_inventory=False): """Returns a list of all resources and the matching icon paths. @param only_tradeable: return only those you can trade. @param only_inventory: return only those displayed in inventories. @return: list of tuples: (resource ids, resource icon)""" sql = "SELECT id FROM resource WHERE id " if only_tradeable: sql += " AND tradeable = 1 " if only_inventory: sql += " AND shown_in_inventory = 1 " query = self.cached_query(sql) format_data = lambda res: (res, get_res_icon_path(res)) return [format_data(row[0]) for row in query]
def update(self): self.removeAllChildren() weapons_added = False if hasattr(self.instance, 'get_weapon_storage'): storage = self.instance.get_weapon_storage() for weapon, amount in storage: weapons_added = True icon_image = get_res_icon_path(weapon, 24) icon_tooltip = self.instance.session.db.get_res_name(weapon)+': '+str(amount) icon = Icon(image=icon_image, helptext=icon_tooltip) self.addChild(icon) if not weapons_added: icon_image = "content/gui/icons/resources/none.png" icon = Icon(image=icon_image, helptext=_("none")) self.addChild(icon)
def init_for_res(cls, db, res, amount=0, filled=0, marker=0, use_inactive_icon=True, uncached=False): """Inites the button to display the icons for res @param db: dbreader to get info about res icon. @param res: resource id @param amount: int amount of res (used to decide inactiveness and as text) @param filled: percent of fill status (values are ints in [0, 100]) @param use_inactive_icon: whether to use inactive icon if amount == 0 @param uncached: force no cache. see __init__() @return: ImageFillStatusButton instance""" greyscale = use_inactive_icon and amount == 0 path = get_res_icon_path(res, cls.ICON_SIZE[0], greyscale, full_path=False) helptext = db.get_res_name(res) return cls(path=path, text=unicode(amount), helptext=helptext, size=cls.CELL_SIZE, res_id=res, filled=filled, marker=marker, uncached=uncached)
def init_for_res(cls, db, res, amount=0, filled=0, use_inactive_icon=True, uncached=False): """Inites the button to display the icons for res @param db: dbreader to get info about res icon. @param res: resource id @param amount: int amount of res (used to decide inactiveness and as text) @param filled: percent of fill status (values are ints in [0, 100]) @param use_inactive_icon: wheter to use inactive icon if amount == 0 @param uncached: force no cache. see __init__() @return: ImageFillStatusButton instance""" icon = get_res_icon_path(res, 50) if use_inactive_icon: icon_disabled = get_res_icon_path(res, 50, greyscale=True) else: icon_disabled = icon helptext = db.get_res_name(res) image = icon_disabled if amount == 0 else icon return cls(up_image=image, down_image=image, hover_image=image, text=unicode(amount), helptext=helptext, size=cls.DEFAULT_BUTTON_SIZE, res_id = res, filled = filled, uncached = uncached, opaque=False)
def update(self): self.removeAllChildren() weapons_added = False if hasattr(self.instance, 'get_weapon_storage'): storage = self.instance.get_weapon_storage() for weapon, amount in storage: weapons_added = True icon_image = get_res_icon_path(weapon, 24) icon_tooltip = self.instance.session.db.get_res_name( weapon) + ': ' + str(amount) icon = Icon(image=icon_image, helptext=icon_tooltip) self.addChild(icon) if not weapons_added: icon_image = "content/gui/icons/resources/none.png" icon = Icon(image=icon_image, helptext=_("none")) self.addChild(icon)
def update(self): self.removeAllChildren() weapons_added = False if hasattr(self.instance, 'get_weapon_storage'): storage = self.instance.get_weapon_storage() for weapon, amount in storage: weapons_added = True icon_image = get_res_icon_path(weapon, 24) weapon_name = self.instance.session.db.get_res_name(weapon) # You usually do not need to change anything here when translating helptext = T('{weapon}: {amount}').format(weapon=weapon_name, amount=amount) icon = Icon(image=icon_image, helptext=helptext) self.addChild(icon) if not weapons_added: icon_image = "content/gui/icons/resources/none.png" icon = Icon(image=icon_image, helptext=T("none")) self.addChild(icon)
def update(self): self.removeAllChildren() weapons_added = False if hasattr(self.instance, 'get_weapon_storage'): storage = self.instance.get_weapon_storage() for weapon, amount in storage: weapons_added = True icon_image = get_res_icon_path(weapon, 24) weapon_name = self.instance.session.db.get_res_name(weapon) #xgettext:python-format helptext = _('{weapon}: {amount}').format(weapon=weapon_name, amount=amount) icon = Icon(image=icon_image, helptext=helptext) self.addChild(icon) if not weapons_added: icon_image = "content/gui/icons/resources/none.png" icon = Icon(image=icon_image, helptext=_("none")) self.addChild(icon)
def show_tooltip(self): if self.shown is True: return self.shown = True 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, session): from horizons.session import Session assert isinstance(session, Session) self.session = session # special slot because of special properties self.gold_gui = load_uh_widget(self.__class__.GOLD_ENTRY_GUI_FILE, style=self.__class__.STYLE) self.gold_gui.child_finder = PychanChildFinder(self.gold_gui) self.gold_gui.findChild(name="res_icon").image = get_res_icon_path(RES.GOLD, 32) self.gui = [] # list of slots self.resource_configurations = weakref.WeakKeyDictionary() self.current_instance = weakref.ref(self) # can't weakref to None self.construction_mode = False self._last_build_costs = None self._do_show_dummy = False self._update_default_configuration() NewPlayerSettlementHovered.subscribe(self._on_different_settlement)
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 _update_balance_display(self, toggle=False): """Callback for clicking on gold icon (ticket #1671) and updating the value (in case toggle is False) @param toggle: Whether to enable/disable the balance display or only update icon (pos/neg) """ icon = self.gold_gui.child_finder('res_icon') icon.capture(Callback(self._update_balance_display, True), event_name='mouseClicked') if toggle: self.gold_gui.balance_visible = not self.gold_gui.balance_visible balance = self.session.world.player.get_balance_estimation() if self.gold_gui.balance_visible: icon.image = self.ICON_NEG_BALANCE if balance < 0 else self.ICON_POS_BALANCE else: icon.image = get_res_icon_path(RES.GOLD, 32) # display actual balance in balance label in any case balance_lbl = self.gold_gui.child_finder("balance") balance_lbl.text = u"{sign}{balance}".format(balance=balance, sign=u'+' if balance >= 0 else u'') balance_lbl.resizeToContent() balance_lbl.position = (33 - balance_lbl.size[0]/2, 68) # see _update_gold self.gold_gui.resizeToContent() # update label size
def set_inventory_instance(self, instance, keep_construction_mode=False, force_update=False): """Display different inventory. May change resources that are displayed""" if self.current_instance() is instance and not self.construction_mode and not force_update: return # caller is drunk yet again if self.construction_mode and not keep_construction_mode: # stop construction mode, immediately update view, which will be a normal view self.close_construction_mode(update_slots=False) # reconstruct general gui # remove old gui (keep entries for reuse) for i in self.gui: i.hide() self._hide_resource_selection_dialog() inv = self._get_current_inventory() if inv is not None: inv.remove_change_listener(self._update_resources) if instance in (None, self): # show nothing instead self.current_instance = weakref.ref(self) # can't weakref to None self._do_show_dummy = False # don't save dummy value return self.current_instance = weakref.ref(instance) # construct new slots (fill values later) load_entry = lambda : load_uh_widget(self.ENTRY_GUI_FILE, style=self.__class__.STYLE) resources = self._get_current_resources() addition = [-1] if self._do_show_dummy or not resources else [] # add dummy at end for adding stuff for i, res in enumerate( resources + addition ): try: # get old slot entry = self.gui[i] if res == -1: # can't reuse dummy slot, need default data self.gui[i] = entry = load_entry() except IndexError: # need new one entry = load_entry() self.gui.append(entry) entry.findChild(name="entry").position = (self.INITIAL_X_OFFSET + i * self.ENTRY_X_OFFSET, self.ENTRY_Y_OFFSET) background_icon = entry.findChild(name="entry") background_icon.capture(Callback(self._show_resource_selection_dialog, i), 'mouseEntered', 'resbar') if res != -1: helptext = self.session.db.get_res_name(res) icon = entry.findChild(name="res_icon") icon.num = i icon.image = get_res_icon_path(res) icon.max_size = icon.min_size = icon.size = (24, 24) icon.capture(self._on_res_slot_click, event_name='mouseClicked') else: helptext = _("Click to add a new slot") entry.show() # this will not be filled as the other res background_icon.helptext = helptext # show it just when values are entered, this appeases pychan # fill values inv = self._get_current_inventory() # update on all changes as well as now inv.add_change_listener(self._update_resources, call_listener_now=True)
def add_resource(self, res_id, slot_id, value=None): """ Adds a resource to the specified slot @param res_id: int - resource id @param slot: int - slot number of the slot that is to be set """ self.log.debug("BuySellTab add_resource() resid: %s; slot_id %s; value: %s", res_id, slot_id, value) keep_hint = False if self.resources is not None: # Hide resource menu self.resources.hide() self.show() if res_id != 0: # new res self._set_hint( _("Set to buy or sell by clicking on that label, then adjust the amount via the slider to the right.") ) else: self._set_hint( u"" ) keep_hint = True slot = self.slots[slot_id] slider = slot.findChild(name="slider") if value is None: # use current slider value if player provided no input value = int(slider.value) else: # set slider to value entered by the player slider.value = float(value) if slot.action is "sell": if slot.res is not None: # slot has been in use before, delete old value self.remove_sell_from_settlement(slot.res) if res_id != 0: self.add_sell_to_settlement(res_id, value, slot.id) elif slot.action is "buy": if slot.res is not None: # slot has been in use before, delete old value self.remove_buy_from_settlement(slot.res) if res_id != 0: self.add_buy_to_settlement(res_id, value, slot.id) else: assert False button = slot.findChild(name="button") fillbar = slot.findChild(name="fillbar") # reset slot value for new res if res_id == 0: button.up_image, button.down_image, button.hover_image = [ self.dummy_icon_path ] * 3 button.helptext = u"" slot.findChild(name="amount").text = u"" slot.findChild(name="slider").value = 0.0 slot.res = None slider.capture(None) # hide fillbar by setting position icon = slot.findChild(name="icon") fillbar.position = (icon.width - fillbar.width - 1, icon.height) button = slot.findChild(name="buysell") button.up_image = None button.hover_image = None else: icon = get_res_icon_path(res_id) icon_disabled = get_res_icon_path(res_id, greyscale=True) button.up_image = icon button.down_image = icon button.hover_image = icon_disabled button.helptext = self.session.db.get_res_name(res_id) slot.res = res_id # use some python magic to assign a res attribute to the slot to # save which res_id it stores slider.capture(Callback(self.slider_adjust, res_id, slot.id)) slot.findChild(name="amount").text = u"{amount:-5d}t".format(amount=value) icon = slot.findChild(name="icon") inventory = self.tradepost.get_inventory() filled = (100 * inventory[res_id]) // inventory.get_limit(res_id) fillbar.position = (icon.width - fillbar.width - 1, icon.height - int(icon.height*filled)) # reuse code from toggle to finish setup (must switch state before, it will reset it) slot.action = "sell" if slot.action is "buy" else "buy" self.toggle_buysell(slot_id, keep_hint=keep_hint) slot.adaptLayout()
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_resource(self, resource_id, slot_id, value=None): """ Adds a resource to the specified slot @param resource_id: int - resource id @param slot_id: int - slot number of the slot that is to be set """ self.log.debug( "BuySellTab add_resource() resid: %s; slot_id %s; value: %s", resource_id, slot_id, value) keep_hint = False if self.resources is not None: # Hide resource menu self.resources.hide() self.show() if resource_id != 0: # new res self._set_hint( T("Set to buy or sell by clicking on that label, then adjust the amount via the slider to the right." )) else: self._set_hint(u"") keep_hint = True slot = self.slot_widgets[slot_id] slider = slot.findChild(name="slider") if value is None: # use current slider value if player provided no input value = int(slider.value) else: # set slider to value entered by the player slider.value = float(value) if slot.action == "sell": if slot.res is not None: # slot has been in use before, delete old value self.clear_slot(slot_id) if resource_id != 0: self.set_slot_info(slot.id, resource_id, True, value) elif slot.action == "buy": if slot.res is not None: # slot has been in use before, delete old value self.clear_slot(slot_id) if resource_id != 0: self.set_slot_info(slot.id, resource_id, False, value) button = slot.findChild(name="button") fillbar = slot.findChild(name="fillbar") # reset slot value for new res if resource_id == 0: button.path = self.dummy_icon_path button.helptext = u"" slot.findChild(name="amount").text = u"" slot.findChild(name="slider").value = 0.0 slot.res = None slider.capture(None) # hide fillbar by setting position icon = slot.findChild(name="icon") fillbar.position = (icon.width - fillbar.width - 1, icon.height) button = slot.findChild(name="buysell") button.up_image = None button.hover_image = None else: icon = get_res_icon_path(resource_id) icon_disabled = get_res_icon_path(resource_id, greyscale=True) button.up_image = icon button.down_image = icon button.hover_image = icon_disabled button.helptext = self.session.db.get_res_name(resource_id) slot.res = resource_id # use some python magic to assign a res attribute to the slot to # save which resource_id it stores slider.capture(Callback(self.slider_adjust, resource_id, slot.id)) slot.findChild(name="amount").text = u"{amount:-5d}t".format( amount=value) icon = slot.findChild(name="icon") inventory = self.trade_post.get_inventory() filled = (100 * inventory[resource_id] ) // inventory.get_limit(resource_id) fillbar.position = (icon.width - fillbar.width - 1, icon.height - int(icon.height * filled)) # reuse code from toggle to finish setup (must switch state before, it will reset it) slot.action = "sell" if slot.action == "buy" else "buy" self.toggle_buysell(slot_id, keep_hint=keep_hint) slot.adaptLayout()
def refresh(self): """This function is called by the TabWidget to redraw the widget.""" super(BoatbuilderTab, self).refresh() main_container = self.widget.findChild(name="BB_main_tab") container_active = main_container.findChild(name="container_active") container_inactive = main_container.findChild(name="container_inactive") progress_container = main_container.findChild(name="BB_progress_container") cancel_container = main_container.findChild(name="BB_cancel_container") needed_res_container = self.widget.findChild(name="BB_needed_resources_container") # a boatbuilder is considered active here if it build sth, no matter if it's paused production_lines = self.producer.get_production_lines() if production_lines: if cancel_container is None: main_container.addChild(main_container.cancel_container) cancel_container = main_container.cancel_container if needed_res_container is None: main_container.insertChildBefore(main_container.needed_res_container, cancel_container) needed_res_container = main_container.needed_res_container # Set progress if progress_container is None: main_container.insertChildBefore( main_container.progress_container, self.widget.findChild(name="BB_needed_resources_container")) progress_container = main_container.progress_container progress = math.floor(self.producer.get_production_progress() * 100) self.widget.findChild(name='progress').progress = progress self.widget.findChild(name='BB_progress_perc').text = u'{progress}%'.format(progress=progress) # remove other container, but save it if container_inactive is not None: main_container.container_inactive = container_inactive main_container.removeChild( container_inactive ) if container_active is None: main_container.insertChildBefore( main_container.container_active, progress_container) container_active = main_container.container_active # Update boatbuilder queue queue = self.producer.get_unit_production_queue() queue_container = container_active.findChild(name="queue_container") queue_container.removeAllChildren() for place_in_queue, unit_type in enumerate(queue): image = self.__class__.SHIP_THUMBNAIL.format(type_id=unit_type) #xgettext:python-format helptext = _(u"{ship} (place in queue: {place})").format( ship=self.instance.session.db.get_unit_type_name(unit_type), place=place_in_queue+1 ) # people don't count properly, always starting at 1.. icon_name = "queue_elem_"+str(place_in_queue) icon = Icon(name=icon_name, image=image, helptext=helptext) icon.capture( Callback(RemoveFromQueue(self.producer, place_in_queue).execute, self.instance.session), event_name="mouseClicked" ) queue_container.addChild( icon ) # Set built ship info produced_unit_id = self.producer._get_production(production_lines[0]).get_produced_units().keys()[0] produced_unit_id = self.producer._get_production(production_lines[0]).get_produced_units().keys()[0] (name,) = self.instance.session.db.cached_query("SELECT name FROM unit WHERE id = ?", produced_unit_id)[0] container_active.findChild(name="headline_BB_builtship_label").text = _(name) container_active.findChild(name="BB_cur_ship_icon").helptext = "Storage: 4 slots, 120t \nHealth: 100" container_active.findChild(name="BB_cur_ship_icon").image = "content/gui/images/objects/ships/116/%s.png" % (produced_unit_id) button_active = container_active.findChild(name="toggle_active_active") button_inactive = container_active.findChild(name="toggle_active_inactive") if not self.producer.is_active(): # if production is paused # remove active button, if it's there, and save a reference to it if button_active is not None: container_active.button_active = button_active container_active.removeChild( button_active ) # restore inactive button, if it isn't in the gui if button_inactive is None: # insert at the end container_active.insertChild(container_active.button_inactive, \ len(container_active.children)) container_active.mapEvents({ 'toggle_active_inactive' : Callback(self.producer.set_active, active=True) }) # TODO: make this button do sth else: # remove inactive button, if it's there, and save a reference to it if button_inactive is not None: container_active.button_inactive = button_inactive container_active.removeChild( button_inactive ) # restore active button, if it isn't in the gui if button_active is None: # insert at the end container_active.insertChild(container_active.button_active, \ len(container_active.children)) container_active.mapEvents({ 'toggle_active_active' : Callback(self.producer.set_active, active=False) }) upgrades_box = container_active.findChild(name="BB_upgrades_box") for child in upgrades_box.children[:]: upgrades_box.removeChild(child) # upgrades_box.addChild( pychan.widgets.Label(text=u"+ love") ) # upgrades_box.addChild( pychan.widgets.Label(text=u"+ affection") ) # no upgrades in 2010.1 release ---^ upgrades_box.stylize('menu_black') # Update needed resources production = self.producer.get_productions()[0] still_needed_res = production.get_consumed_resources() # Now sort! still_needed_res = sorted(still_needed_res.iteritems(), key=operator.itemgetter(1)) main_container.findChild(name="BB_needed_res_label").text = _('Resources still needed:') i = 0 for res, amount in still_needed_res: if amount == 0: continue # Don't show res that are not really needed anymore assert i <= 3, "Only 3 still needed res for ships are currently supported" icon_path = get_res_icon_path(res, 16) needed_res_container.findChild(name="BB_needed_res_icon_"+str(i+1)).image = icon_path needed_res_container.findChild(name="BB_needed_res_lbl_"+str(i+1)).text = unicode(-1*amount)+u't' # -1 makes them positive i += 1 if i >= 3: break for j in xrange(i, 3): # these are not filled by a resource, so we need to make it invisible needed_res_container.findChild(name="BB_needed_res_icon_"+str(j+1)).image = None needed_res_container.findChild(name="BB_needed_res_lbl_"+str(j+1)).text = u"" cancel_button = self.widget.findChild(name="BB_cancel_button") cancel_button.capture( Callback(CancelCurrentProduction(self.producer).execute, self.instance.session), event_name="mouseClicked" ) else: # display sth when nothing is produced # remove other container, but save it if container_active is not None: main_container.container_active = container_active main_container.removeChild( container_active ) if container_inactive is None: main_container.insertChildBefore( main_container.container_inactive, progress_container) container_inactive = main_container.container_inactive if progress_container is not None: main_container.progress_container = progress_container main_container.removeChild(progress_container) if needed_res_container is not None: main_container.needed_res_container = needed_res_container main_container.removeChild(needed_res_container) if cancel_container is not None: main_container.cancel_container = cancel_container main_container.removeChild(cancel_container) self.widget.adaptLayout()