class IngameGui(LivingObject): """Class handling all the ingame gui events.""" gui = livingProperty() tabwidgets = livingProperty() message_widget = livingProperty() minimap = livingProperty() styles = { 'city_info': 'city_info', 'change_name': 'book', 'chat': 'book', 'status': 'resource_bar', 'status_gold': 'resource_bar', 'status_extra': 'resource_bar', 'status_extra_gold': 'resource_bar', } def __init__(self, session, gui): super(IngameGui, self).__init__() self.session = session self.main_gui = gui self.widgets = {} self.tabwidgets = {} self.settlement = None self.resource_source = None self.resources_needed, self.resources_usable = {}, {} self._old_menu = None self.widgets = LazyWidgetsDict(self.styles, center_widgets=False) cityinfo = self.widgets['city_info'] cityinfo.child_finder = PychanChildFinder(cityinfo) cityinfo.position_technique = "center-10:top+5" self.logbook = LogBook() self.logbook.add_pause_request_listener( Callback(self.session.speed_pause)) self.logbook.add_unpause_request_listener( Callback(self.session.speed_unpause)) self.scenario_chooser = ScenarioChooser(self.session) # self.widgets['minimap'] is the guichan gui around the actual minimap, # which is saved in self.minimap minimap = self.widgets['minimap'] minimap.position_technique = "right-20:top+4" minimap.show() minimap_rect = Rect.init_from_topleft_and_size( minimap.position[0] + 77, 55, 120, 120) self.minimap = Minimap(minimap_rect, self.session, \ self.session.view.renderer['GenericRenderer']) minimap.mapEvents({ 'zoomIn': self.session.view.zoom_in, 'zoomOut': self.session.view.zoom_out, 'rotateRight': Callback.ChainedCallbacks(self.session.view.rotate_right, self.minimap.rotate_right), 'rotateLeft': Callback.ChainedCallbacks(self.session.view.rotate_left, self.minimap.rotate_left), 'speedUp': self.session.speed_up, 'speedDown': self.session.speed_down }) minimap_overlay = minimap.findChild(name='minimap_overlay_image') self.minimap.use_overlay_icon(minimap_overlay) self.widgets['menu_panel'].position_technique = "right+15:top+153" self.widgets['menu_panel'].show() self.widgets['menu_panel'].mapEvents({ 'destroy_tool': self.session.destroy_tool, 'build': self.show_build_menu, 'helpLink': self.main_gui.on_help, 'gameMenuButton': self.main_gui.show_pause, 'logbook': self.logbook.toggle_visibility }) self.widgets['tooltip'].hide() self.widgets['status'].child_finder = PychanChildFinder( self.widgets['status']) self.widgets['status_extra'].child_finder = PychanChildFinder( self.widgets['status_extra']) self.message_widget = MessageWidget(self.session, \ cityinfo.position[0] + cityinfo.size[0], 5) self.widgets['status_gold'].show() self.widgets['status_gold'].child_finder = PychanChildFinder( self.widgets['status_gold']) self.widgets['status_extra_gold'].child_finder = PychanChildFinder( self.widgets['status_extra_gold']) # map button names to build functions calls with the building id callbackWithArguments = pychan.tools.callbackWithArguments self.callbacks_build = {} for id, button_name, settler_level in horizons.main.db.get_building_id_buttonname_settlerlvl( ): if not settler_level in self.callbacks_build: self.callbacks_build[settler_level] = {} self.callbacks_build[settler_level][button_name] = Callback( self._build, id) def end(self): self.widgets['menu_panel'].mapEvents({ 'destroy_tool': None, 'build': None, 'helpLink': None, 'gameMenuButton': None }) self.widgets['minimap'].mapEvents({ 'zoomIn': None, 'zoomOut': None, 'rotateRight': None, 'rotateLeft': None }) for w in self.widgets.itervalues(): if w.parent is None: w.hide() self.message_widget = None self.tabwidgets = None self.minimap = None self.hide_menu() super(IngameGui, self).end() def update_gold(self): first = str(self.session.world.player.inventory[RES.GOLD_ID]) lines = [] show = False if self.resource_source is not None and self.resources_needed.get( RES.GOLD_ID, 0) != 0: show = True lines.append('- ' + str(self.resources_needed[RES.GOLD_ID])) self.status_set('gold', first) self.status_set_extra('gold', lines) self.set_status_position('gold') if show: self.widgets['status_extra_gold'].show() else: self.widgets['status_extra_gold'].hide() def status_set(self, label, value): """Sets a value on the status bar (available res of the settlement). @param label: str containing the name of the label to be set. @param value: value the Label is to be set to. """ if isinstance(value, list): value = value[0] gui = self.widgets['status_gold'] if label == 'gold' else self.widgets[ 'status'] foundlabel = gui.child_finder(label + '_1') foundlabel._setText(unicode(value)) foundlabel.resizeToContent() gui.resizeToContent() def status_set_extra(self, label, value): """Sets a value on the extra status bar. (below normal status bar, needed res for build) @param label: str containing the name of the label to be set. @param value: value the Label is to be set to. """ bg_icon_gold = "content/gui/images/background/widgets/res_mon_extra_bg.png" bg_icon_res = "content/gui/images/background/widgets/res_extra_bg.png" if not hasattr(self, "bg_icon_pos"): self.bg_icon_pos = { 'gold': (14, 83), 'food': (0, 6), 'tools': (52, 6), 'boards': (104, 6), 'bricks': (156, 6), 'textiles': (207, 6) } self.bgs_shown = {} bg_icon = pychan.widgets.Icon(image=bg_icon_gold if label == 'gold' else bg_icon_res, \ position=self.bg_icon_pos[label], name='bg_icon_' + label) if not value: foundlabel = (self.widgets['status_extra_gold'] if label == 'gold' else self.widgets['status_extra']).child_finder(label + '_' + str(2)) foundlabel.text = u'' foundlabel.resizeToContent() if label in self.bgs_shown: (self.widgets['status_extra_gold'] if label == 'gold' else self.widgets['status_extra']).removeChild( self.bgs_shown[label]) del self.bgs_shown[label] self.widgets['status_extra_gold'].resizeToContent( ) if label == 'gold' else self.widgets[ 'status_extra'].resizeToContent() return if isinstance(value, str): value = [value] #for i in xrange(len(value), 3): # value.append("") if (self.widgets['status_extra_gold'] if label == 'gold' else self.widgets['status_extra']).findChild(name='bg_icon_' + label) is None: (self.widgets['status_extra_gold'] if label == 'gold' else self.widgets['status_extra']).insertChild(bg_icon, 0) self.bgs_shown[label] = bg_icon for i in xrange(0, len(value)): foundlabel = (self.widgets['status_extra_gold'] if label == 'gold' else self.widgets['status_extra']).child_finder( name=label + '_' + str(i + 2)) foundlabel._setText(unicode(value[i])) foundlabel.resizeToContent() if label == 'gold': self.widgets['status_extra_gold'].resizeToContent() else: self.widgets['status_extra'].resizeToContent() def cityinfo_set(self, settlement): """Sets the city name at top center Show/Hide is handled automatically To hide cityname, set name to '' @param settlement: Settlement class providing the information needed """ if settlement is self.settlement: return if self.settlement is not None: self.settlement.remove_change_listener(self.update_settlement) self.settlement = settlement if settlement is None: self.widgets['city_info'].hide() else: self.widgets['city_info'].show() self.update_settlement() settlement.add_change_listener(self.update_settlement) def resourceinfo_set(self, source, res_needed={}, res_usable={}, res_from_ship=False): city = source if not res_from_ship else None self.cityinfo_set(city) if source is not self.resource_source: if self.resource_source is not None: self.resource_source.remove_change_listener( self.update_resource_source) if source is None or self.session.world.player != source.owner: self.widgets['status'].hide() self.widgets['status_extra'].hide() self.resource_source = None self.update_gold() if source is not None and self.session.world.player == source.owner: if source is not self.resource_source: source.add_change_listener(self.update_resource_source) self.resource_source = source self.resources_needed = res_needed self.resources_usable = res_usable self.update_resource_source() self.widgets['status'].show() def update_settlement(self): cityinfo = self.widgets['city_info'] cityinfo.mapEvents({ 'city_name': Callback(self.show_change_name_dialog, self.settlement) }) foundlabel = cityinfo.child_finder('city_name') foundlabel._setText(unicode(self.settlement.name)) foundlabel.resizeToContent() foundlabel = self.widgets['city_info'].child_finder('city_inhabitants') foundlabel.text = unicode(' ' + str(self.settlement.inhabitants)) foundlabel.resizeToContent() self.widgets['city_info'].resizeToContent() def update_resource_source(self): """Sets the values for resource status bar as well as the building costs""" self.update_gold() for res_id, res_name in { 3: 'textiles', 4: 'boards', 5: 'food', 6: 'tools', 7: 'bricks' }.iteritems(): first = str(self.resource_source.inventory[res_id]) lines = [] show = False if self.resources_needed.get(res_id, 0) != 0: show = True lines.append('- ' + str(self.resources_needed[res_id])) self.status_set(res_name, first) self.status_set_extra(res_name, lines) self.set_status_position(res_name) if show: self.widgets['status_extra'].show() def ship_build(self, ship): """Calls the Games build_object class.""" self._build(1, ship) def minimap_to_front(self): self.widgets['minimap'].hide() self.widgets['minimap'].show() self.widgets['menu_panel'].hide() self.widgets['menu_panel'].show() def show_build_menu(self): # check if build menu is already shown if hasattr(self.get_cur_menu(), 'name') and self.get_cur_menu( ).name == "build_menu_tab_widget": self.hide_menu() return self.session.cursor = SelectionTool( self.session) # set cursor for build menu self.deselect_all() btabs = [BuildTab(index, self.callbacks_build[index]) for index in \ range(0, self.session.world.player.settler_level+1)] tab = TabWidget(self, tabs=btabs, name="build_menu_tab_widget", \ active_tab=BuildTab.last_active_build_tab) self.show_menu(tab) def deselect_all(self): for instance in self.session.selected_instances: instance.deselect() self.session.selected_instances.clear() def _build(self, building_id, unit=None): """Calls the games buildingtool class for the building_id. @param building_id: int with the building id that is to be built. @param unit: weakref to the unit, that builds (e.g. ship for branch office)""" self.hide_menu() self.deselect_all() cls = Entities.buildings[building_id] if hasattr(cls, 'show_build_menu'): cls.show_build_menu() self.session.cursor = BuildingTool(self.session, cls, None if unit is None else unit()) def _get_menu_object(self, menu): """Returns pychan object if menu is a string, else returns menu @param menu: str with the guiname or pychan object. """ if isinstance(menu, str): menu = self.widgets[menu] return menu def get_cur_menu(self): """Returns menu that is currently displayed""" return self._old_menu def show_menu(self, menu): """Shows a menu @param menu: str with the guiname or pychan object. """ if self._old_menu is not None: self._old_menu.hide() self._old_menu = self._get_menu_object(menu) if self._old_menu is not None: self._old_menu.show() self.minimap_to_front() def hide_menu(self): self.show_menu(None) def toggle_menu(self, menu): """Shows a menu or hides it if it is already displayed. @param menu: parameter supported by show_menu(). """ if self.get_cur_menu() == self._get_menu_object(menu): self.hide_menu() else: self.show_menu(menu) def build_load_tab(self, num): """Loads a subcontainer into the build menu and changes the tabs background. @param num: number representing the tab to load. """ tab1 = self.widgets['build'].findChild(name=('tab' + str(self.active_build))) tab2 = self.widgets['build'].findChild(name=('tab' + str(num))) activetabimg, nonactiveimg = tab1._getImage(), tab2._getImage() tab1._setImage(nonactiveimg) tab2._setImage(activetabimg) contentarea = self.widgets['build'].findChild(name='content') contentarea.removeChild(self.widgets['build_tab' + str(self.active_build)]) contentarea.addChild(self.widgets['build_tab' + str(num)]) contentarea.adaptLayout() self.active_build = num def set_status_position(self, resource_name): icon_name = resource_name + '_icon' for i in xrange(1, 3): lbl_name = resource_name + '_' + str(i) # tools_1 = inventory amount, tools_2 = cost of to-be-built building if resource_name == 'gold': self._set_label_position('status_gold', lbl_name, icon_name, 33, 31 + i * 20) else: self._set_label_position('status', lbl_name, icon_name, 24, 31 + i * 20) def _set_label_position(self, widget, lbl_name, icon_name, xoffset, yoffset): icon = self.widgets[widget].child_finder(icon_name) label = self.widgets[widget].child_finder(lbl_name) label.position = (icon.position[0] - label.size[0] / 2 + xoffset, yoffset) def save(self, db): self.message_widget.save(db) self.logbook.save(db) def load(self, db): self.message_widget.load(db) self.logbook.load(db) self.minimap.draw() # update minimap to new world def show_change_name_dialog(self, instance): """Shows a dialog where the user can change the name of a NamedObject. The game gets paused while the dialog is executed.""" self.session.speed_pause() events = { 'okButton': Callback(self.change_name, instance), 'cancelButton': self._hide_change_name_dialog } self.main_gui.on_escape = self._hide_change_name_dialog changename = self.widgets['change_name'] newname = changename.findChild(name='new_name') changename.mapEvents(events) newname.capture(Callback(self.change_name, instance)) changename.show() newname.requestFocus() def _hide_change_name_dialog(self): """Escapes the change_name dialog""" self.session.speed_unpause() self.main_gui.on_escape = self.main_gui.show_pause self.widgets['change_name'].hide() def change_name(self, instance): """Applies the change_name dialogs input and hides it""" new_name = self.widgets['change_name'].collectData('new_name') self.widgets['change_name'].findChild(name='new_name').text = u'' if not (len(new_name) == 0 or new_name.isspace()): RenameObject(instance, new_name).execute(self.session) self._hide_change_name_dialog() _toggle_ingame_pause_shown = False def toggle_ingame_pause(self): """ Called when the hotkey for pause is pressed. Displays pause notification and does the actual (un)pausing. """ message = _("Hit P to continue the game or click below!") popup = self.main_gui.build_popup(_("Game paused"), message) if not self._toggle_ingame_pause_shown: self.session.speed_pause() self.main_gui.on_escape = self.toggle_ingame_pause popup.mapEvents({'okButton': self.toggle_ingame_pause}) popup.show() self._toggle_ingame_pause_shown = True else: self.main_gui.on_escape = self.main_gui.show_pause popup.hide() self.session.speed_unpause() self._toggle_ingame_pause_shown = False def on_escape(self): if self.logbook.is_visible(): self.logbook.hide() else: return False return True def display_game_speed(self, text): """ @param text: unicode string to display as speed value """ wdg = self.widgets['minimap'].findChild(name="speed_text") wdg.text = text wdg.resizeToContent() self.widgets['minimap'].show() def _player_settler_level_change_listener(self): """Gets called when the player changes""" menu = self.get_cur_menu() if hasattr(menu, "name"): if menu.name == "build_menu_tab_widget": # player changed and build menu is currently displayed self.show_build_menu() def show_chat_dialog(self): """Show a dialog where the user can enter a chat message""" events = { 'okButton': self._do_chat, 'cancelButton': self._hide_chat_dialog } self.main_gui.on_escape = self._hide_chat_dialog self.widgets['chat'].mapEvents(events) self.widgets['chat'].findChild(name='msg').capture(self._do_chat) self.widgets['chat'].show() self.widgets['chat'].findChild(name="msg").requestFocus() def _hide_chat_dialog(self): """Escapes the chat dialog""" self.main_gui.on_escape = self.main_gui.show_pause self.widgets['chat'].hide() def _do_chat(self): """Actually initiates chatting and hides the dialog""" msg = self.widgets['chat'].findChild(name='msg').text Chat(msg).execute(self.session) self.widgets['chat'].findChild(name='msg').text = u'' self._hide_chat_dialog()
class IngameGui(LivingObject): """Class handling all the ingame gui events.""" gui = livingProperty() tabwidgets = livingProperty() message_widget = livingProperty() minimap = livingProperty() resbar = livingProperty() styles = { 'city_info' : 'city_info', 'change_name' : 'book', 'chat' : 'book', 'status' : 'resource_bar', 'status_gold' : 'resource_bar', 'status_extra' : 'resource_bar', 'status_extra_gold' : 'resource_bar', } def __init__(self, session, gui): super(IngameGui, self).__init__() self.session = session self.main_gui = gui self.widgets = {} self.tabwidgets = {} self.settlement = None self.resource_source = None self.resources_needed, self.resources_usable = {}, {} self._old_menu = None self.widgets = LazyWidgetsDict(self.styles, center_widgets=False) screenwidth = horizons.main.fife.engine_settings.getScreenWidth() cityinfo = self.widgets['city_info'] cityinfo.child_finder = PychanChildFinder(cityinfo) cityinfo.position = ( screenwidth/2 - cityinfo.size[0]/2 - 10, 5 ) self.logbook = LogBook(session) # self.widgets['minimap'] is the guichan gui around the actual minimap, # which is saved in self.minimap minimap = self.widgets['minimap'] minimap.position = (screenwidth - minimap.size[0] -20, 4) minimap.show() minimap_rect = Rect.init_from_topleft_and_size(minimap.position[0]+77, 55, 120, 120) self.minimap = Minimap(minimap_rect, self.session, \ self.session.view.renderer['GenericRenderer']) minimap.mapEvents({ 'zoomIn' : self.session.view.zoom_in, 'zoomOut' : self.session.view.zoom_out, 'rotateRight' : Callback.ChainedCallbacks(self.session.view.rotate_right, self.minimap.rotate_right), 'rotateLeft' : Callback.ChainedCallbacks(self.session.view.rotate_left, self.minimap.rotate_left), 'speedUp' : self.session.speed_up, 'speedDown' : self.session.speed_down }) minimap_overlay = minimap.findChild(name='minimap_overlay_image') self.minimap.use_overlay_icon(minimap_overlay) menupanel = self.widgets['menu_panel'] menupanel.position = (screenwidth - menupanel.size[0] +15, 149) menupanel.show() menupanel.mapEvents({ 'destroy_tool' : self.session.destroy_tool, 'build' : self.show_build_menu, 'helpLink' : self.main_gui.on_help, 'gameMenuButton' : self.main_gui.show_pause, 'logbook' : self.logbook.toggle_visibility }) self.widgets['tooltip'].hide() for w in ('status','status_extra','status_gold','status_extra_gold'): self.widgets[w].child_finder = PychanChildFinder(self.widgets[w]) self.widgets['status_gold'].show() self.message_widget = MessageWidget(self.session, \ cityinfo.position[0] + cityinfo.size[0], 5) self.resbar = ResBar(self.session, gui, self.widgets, self.resource_source) # map button names to build functions calls with the building id building_list = horizons.main.db.get_building_id_buttonname_settlerlvl() self.callbacks_build = {} for id,button_name,settler_level in building_list: if not settler_level in self.callbacks_build: self.callbacks_build[settler_level] = {} self.callbacks_build[settler_level][button_name] = Callback(self._build, id) def resourceinfo_set(self, source, res_needed = {}, res_usable = {}, res_from_ship = False): #TODO what is this stuff doing? I could maybe fix the problems if I understood that: # why that much if-checks? need to better explain each case # * when does this happen and * what are the steps we do then? # method is called without arguments in navigationtool (to update) # and with arguments in buildingtool to create proper build preview city = source if not res_from_ship else None self.cityinfo_set(city) # the source we hover is a settlement, # cityinfo_set(None) hides the widget. # print source, " ", self.resource_source listener = self.resbar.update_resource_source(source, res_needed) if source is None or self.session.world.player != source.owner: # player hovers enemy settlement / unsettled territory -> don't show inventory self.widgets['status'].hide() self.widgets['status_extra'].hide() if source is not None: pass # remove changelistener? source = None # ---- if source is not None and self.session.world.player == source.owner: # 'source' is always carried over to islandinventorydisplay.py # in difference from the below code where self.resource_source was # only modified if some conditions applied but always passed over. self.resbar.update_resource_source(self.resource_source, res_needed) self.widgets['status'].show() self.resbar.update_gold() """ Below the old code of this method for bugfixing and comparison purposes: def resourceinfo_set(self, source, res_needed = {}, res_usable = {}, res_from_ship = False): city = source if not res_from_ship else None self.cityinfo_set(city) if source is not self.resource_source: if self.resource_source is not None: self.resource_source.remove_change_listener(self.update_resource_source) if source is None or self.session.world.player != source.owner: self.widgets['status'].hide() self.widgets['status_extra'].hide() self.resource_source = None self.update_gold() if source is not None and self.session.world.player == source.owner: if source is not self.resource_source: source.add_change_listener(self.update_resource_source) self.resource_source = source self.resources_needed = res_needed self.resources_usable = res_usable self.update_resource_source() self.widgets['status'].show() """ def end(self): self.widgets['menu_panel'].mapEvents({ 'destroy_tool' : None, 'build' : None, 'helpLink' : None, 'gameMenuButton' : None }) self.widgets['minimap'].mapEvents({ 'zoomIn' : None, 'zoomOut' : None, 'rotateRight' : None, 'rotateLeft' : None }) for w in self.widgets.itervalues(): if w.parent is None: w.hide() self.message_widget = None self.tabwidgets = None self.minimap = None self.hide_menu() super(IngameGui, self).end() def cityinfo_set(self, settlement): """Sets the city name at top center Show/Hide is handled automatically To hide cityname, set name to '' @param settlement: Settlement class providing the information needed """ if settlement is self.settlement: return if self.settlement is not None: self.settlement.remove_change_listener(self.update_settlement) self.settlement = settlement if settlement is None: self.widgets['city_info'].hide() else: self.widgets['city_info'].show() self.update_settlement() settlement.add_change_listener(self.update_settlement) def update_settlement(self): """Assigns values to labels of cityinfo widget""" cityinfo = self.widgets['city_info'] cityinfo.mapEvents({ 'city_name': Callback(self.show_change_name_dialog, self.settlement) }) foundlabel = cityinfo.child_finder('city_name') foundlabel._setText(unicode(self.settlement.name)) foundlabel.resizeToContent() foundlabel = cityinfo.child_finder('city_inhabitants') foundlabel.text = unicode(' '+str(self.settlement.inhabitants)) foundlabel.resizeToContent() cityinfo.resizeToContent() def minimap_to_front(self): self.widgets['minimap'].hide() self.widgets['minimap'].show() self.widgets['menu_panel'].hide() self.widgets['menu_panel'].show() def show_build_menu(self): # check if build menu is already shown if hasattr(self.get_cur_menu(), 'name'): if self.get_cur_menu().name == "build_menu_tab_widget": self.hide_menu() return self.session.cursor = SelectionTool(self.session) # set cursor for build menu self.deselect_all() lvl = self.session.world.player.settler_level btabs = [BuildTab(i, self.callbacks_build[i]) for i in range(0, lvl+1)] tab = TabWidget(self, tabs=btabs, name="build_menu_tab_widget", \ active_tab=BuildTab.last_active_build_tab) self.show_menu(tab) def deselect_all(self): for instance in self.session.selected_instances: instance.deselect() self.session.selected_instances.clear() def _build(self, building_id, unit = None): """Calls the games buildingtool class for the building_id. @param building_id: int with the building id that is to be built. @param unit: weakref to the unit, that builds (e.g. ship for branch office). """ self.hide_menu() self.deselect_all() cls = Entities.buildings[building_id] if hasattr(cls, 'show_build_menu'): cls.show_build_menu() self.session.cursor = BuildingTool(self.session, cls, \ None if unit is None else unit()) def _get_menu_object(self, menu): """Returns pychan object if menu is a string, else returns menu @param menu: str with the guiname or pychan object. """ if isinstance(menu, str): menu = self.widgets[menu] return menu def get_cur_menu(self): """Returns menu that is currently displayed""" return self._old_menu def show_menu(self, menu): """Shows a menu @param menu: str with the guiname or pychan object. """ if self._old_menu is not None: self._old_menu.hide() self._old_menu = self._get_menu_object(menu) if self._old_menu is not None: self._old_menu.show() self.minimap_to_front() def hide_menu(self): self.show_menu(None) def toggle_menu(self, menu): """Shows a menu or hides it if it is already displayed. @param menu: parameter supported by show_menu(). """ if self.get_cur_menu() == self._get_menu_object(menu): self.hide_menu() else: self.show_menu(menu) def build_load_tab(self, num): """Loads a subcontainer into the build menu and changes the tabs background. @param num: number representing the tab to load. """ tab1 = self.widgets['build'].findChild(name=('tab'+str(self.active_build))) tab2 = self.widgets['build'].findChild(name=('tab'+str(num))) activetabimg, nonactiveimg= tab1._getImage(), tab2._getImage() tab1._setImage(nonactiveimg) tab2._setImage(activetabimg) contentarea = self.widgets['build'].findChild(name='content') contentarea.removeChild(self.widgets['build_tab'+str(self.active_build)]) contentarea.addChild(self.widgets['build_tab'+str(num)]) contentarea.adaptLayout() self.active_build = num def save(self, db): self.message_widget.save(db) self.logbook.save(db) def load(self, db): self.message_widget.load(db) self.logbook.load(db) self.minimap.draw() # update minimap to new world def show_change_name_dialog(self, instance): """Shows a dialog where the user can change the name of a NamedObject. The game gets paused while the dialog is executed.""" self.session.speed_pause() events = { 'okButton': Callback(self.change_name, instance), 'cancelButton': self._hide_change_name_dialog } self.main_gui.on_escape = self._hide_change_name_dialog changename = self.widgets['change_name'] newname = changename.findChild(name='new_name') changename.mapEvents(events) newname.capture(Callback(self.change_name, instance)) changename.show() newname.requestFocus() def _hide_change_name_dialog(self): """Escapes the change_name dialog""" self.session.speed_unpause() self.main_gui.on_escape = self.main_gui.show_pause self.widgets['change_name'].hide() def change_name(self, instance): """Applies the change_name dialogs input and hides it""" new_name = self.widgets['change_name'].collectData('new_name') self.widgets['change_name'].findChild(name='new_name').text = u'' if not (len(new_name) == 0 or new_name.isspace()): RenameObject(instance, new_name).execute(self.session) self._hide_change_name_dialog() def toggle_ingame_pause(self): """ Called when the hotkey for pause is pressed. Displays pause notification and does the actual (un)pausing. """ #TODO currently a bug occurs when the game menu is displayed (game is # paused already): popup still appears, need ESC twice to return. message = _("Hit P to continue the game or click below!") popup = self.main_gui.build_popup(_("Game paused"), message) if not hasattr(self, "_toggle_ingame_pause_shown"): self._toggle_ingame_pause_shown = False if not self._toggle_ingame_pause_shown: self.session.speed_pause() self.main_gui.on_escape = self.toggle_ingame_pause popup.mapEvents({'okButton': self.toggle_ingame_pause}) popup.show() self._toggle_ingame_pause_shown = True else: self.main_gui.on_escape = self.main_gui.show_pause popup.hide() self.session.speed_unpause() self._toggle_ingame_pause_shown = False def on_escape(self): if self.logbook.is_visible(): self.logbook.hide() else: return False return True def display_game_speed(self, text): """ @param text: unicode string to display as speed value """ wdg = self.widgets['minimap'].findChild(name="speed_text") wdg.text = text wdg.resizeToContent() self.widgets['minimap'].show() def _player_settler_level_change_listener(self): """Gets called when the player changes""" menu = self.get_cur_menu() if hasattr(menu, "name"): if menu.name == "build_menu_tab_widget": # player changed and build menu is currently displayed self.show_build_menu() def show_chat_dialog(self): """Show a dialog where the user can enter a chat message""" events = { 'okButton': self._do_chat, 'cancelButton': self._hide_chat_dialog } self.main_gui.on_escape = self._hide_chat_dialog self.widgets['chat'].mapEvents(events) self.widgets['chat'].findChild(name='msg').capture( self._do_chat ) self.widgets['chat'].show() self.widgets['chat'].findChild(name="msg").requestFocus() def _hide_chat_dialog(self): """Escapes the chat dialog""" self.main_gui.on_escape = self.main_gui.show_pause self.widgets['chat'].hide() def _do_chat(self): """Actually initiates chatting and hides the dialog""" msg = self.widgets['chat'].findChild(name='msg').text Chat(msg).execute(self.session) self.widgets['chat'].findChild(name='msg').text = u'' self._hide_chat_dialog()
class IngameGui(LivingObject): """Class handling all the ingame gui events. Assumes that only 1 instance is used (class variables)""" gui = livingProperty() tabwidgets = livingProperty() message_widget = livingProperty() minimap = livingProperty() styles = { 'city_info' : 'city_info', 'change_name' : 'book', 'chat' : 'book', 'status' : 'resource_bar', 'status_gold' : 'resource_bar', 'status_extra' : 'resource_bar', 'status_extra_gold' : 'resource_bar', } def __init__(self, session, gui): super(IngameGui, self).__init__() self.session = session self.main_gui = gui self.widgets = {} self.tabwidgets = {} self.settlement = None self.resource_source = None self.resources_needed, self.resources_usable = {}, {} self._old_menu = None self.widgets = LazyWidgetsDict(self.styles, center_widgets=False) cityinfo = self.widgets['city_info'] cityinfo.child_finder = PychanChildFinder(cityinfo) cityinfo.position_technique = "center-10:top+5" self.logbook = LogBook() self.logbook.add_pause_request_listener(Callback(self.session.speed_pause)) self.logbook.add_unpause_request_listener(Callback(self.session.speed_unpause)) self.players_overview = PlayersOverview(self.session) self.scenario_chooser = ScenarioChooser(self.session) # self.widgets['minimap'] is the guichan gui around the actual minimap, # which is saved in self.minimap minimap = self.widgets['minimap'] minimap.position_technique = "right-20:top+4" minimap.show() minimap_rect = Rect.init_from_topleft_and_size(minimap.position[0]+77, 52, 120, 117) self.minimap = Minimap(minimap_rect, self.session, \ self.session.view.renderer['GenericRenderer']) minimap.mapEvents({ 'zoomIn' : self.session.view.zoom_in, 'zoomOut' : self.session.view.zoom_out, 'rotateRight' : Callback.ChainedCallbacks(self.session.view.rotate_right, self.minimap.rotate_right), 'rotateLeft' : Callback.ChainedCallbacks(self.session.view.rotate_left, self.minimap.rotate_left), 'speedUp' : self.session.speed_up, 'speedDown' : self.session.speed_down }) minimap_overlay = minimap.findChild(name='minimap_overlay_image') self.minimap.use_overlay_icon(minimap_overlay) self.widgets['menu_panel'].position_technique = "right+15:top+153" self.widgets['menu_panel'].show() self.widgets['menu_panel'].mapEvents({ 'destroy_tool' : self.session.destroy_tool, 'build' : self.show_build_menu, 'diplomacyButton' : self.show_diplomacy_menu, 'gameMenuButton' : self.main_gui.toggle_pause, 'logbook' : self.logbook.toggle_visibility }) self.widgets['tooltip'].hide() self.widgets['status'].child_finder = PychanChildFinder(self.widgets['status']) self.widgets['status_extra'].child_finder = PychanChildFinder(self.widgets['status_extra']) self.message_widget = MessageWidget(self.session, \ cityinfo.position[0] + cityinfo.size[0], 5) self.widgets['status_gold'].show() self.widgets['status_gold'].child_finder = PychanChildFinder(self.widgets['status_gold']) self.widgets['status_extra_gold'].child_finder = PychanChildFinder(self.widgets['status_extra_gold']) # map button names to build functions calls with the building id self.callbacks_build = {} for id,button_name,settler_level in horizons.main.db.get_building_id_buttonname_settlerlvl(): if not settler_level in self.callbacks_build: self.callbacks_build[settler_level] = {} self.callbacks_build[settler_level][button_name] = Callback(self._build, id) def end(self): self.widgets['menu_panel'].mapEvents({ 'destroy_tool' : None, 'build' : None, 'diplomacyButton' : None, 'gameMenuButton' : None }) self.widgets['minimap'].mapEvents({ 'zoomIn' : None, 'zoomOut' : None, 'rotateRight' : None, 'rotateLeft' : None }) for w in self.widgets.itervalues(): if w.parent is None: w.hide() self.message_widget = None self.tabwidgets = None self.minimap = None self.hide_menu() super(IngameGui, self).end() def update_gold(self): first = str(self.session.world.player.inventory[RES.GOLD_ID]) lines = [] show = False if self.resource_source is not None and self.resources_needed.get(RES.GOLD_ID, 0) != 0: show = True lines.append('- ' + str(self.resources_needed[RES.GOLD_ID])) self.status_set('gold', first) self.status_set_extra('gold',lines) self.set_status_position('gold') if show: self.widgets['status_extra_gold'].show() else: self.widgets['status_extra_gold'].hide() def status_set(self, label, value): """Sets a value on the status bar (available res of the settlement). @param label: str containing the name of the label to be set. @param value: value the Label is to be set to. """ if isinstance(value,list): value = value[0] gui = self.widgets['status_gold'] if label == 'gold' else self.widgets['status'] foundlabel = gui.child_finder(label + '_1') foundlabel._setText(unicode(value)) foundlabel.resizeToContent() gui.resizeToContent() def status_set_extra(self,label,value): """Sets a value on the extra status bar. (below normal status bar, needed res for build) @param label: str containing the name of the label to be set. @param value: value the Label is to be set to. """ bg_icon_gold = "content/gui/images/background/widgets/res_mon_extra_bg.png" bg_icon_res = "content/gui/images/background/widgets/res_extra_bg.png" if not hasattr(self, "bg_icon_pos"): self.bg_icon_pos = {'gold':(14,83), 'food':(0,6), 'tools':(52,6), 'boards':(104,6), 'bricks':(156,6), 'textiles':(207,6)} self.bgs_shown = {} bg_icon = pychan.widgets.Icon(image=bg_icon_gold if label == 'gold' else bg_icon_res, \ position=self.bg_icon_pos[label], name='bg_icon_' + label) if not value: foundlabel = (self.widgets['status_extra_gold'] if label == 'gold' else self.widgets['status_extra']).child_finder(label + '_' + str(2)) foundlabel.text = u'' foundlabel.resizeToContent() if label in self.bgs_shown: (self.widgets['status_extra_gold'] if label == 'gold' else self.widgets['status_extra']).removeChild(self.bgs_shown[label]) del self.bgs_shown[label] self.widgets['status_extra_gold'].resizeToContent() if label == 'gold' else self.widgets['status_extra'].resizeToContent() return if isinstance(value, str): value = [value] #for i in xrange(len(value), 3): # value.append("") if (self.widgets['status_extra_gold'] if label == 'gold' else self.widgets['status_extra']).findChild(name='bg_icon_' + label) is None: (self.widgets['status_extra_gold'] if label == 'gold' else self.widgets['status_extra']).insertChild(bg_icon, 0) self.bgs_shown[label] = bg_icon for i in xrange(0,len(value)): foundlabel = (self.widgets['status_extra_gold'] if label == 'gold' else self.widgets['status_extra']).child_finder(name=label + '_' + str(i+2)) foundlabel._setText(unicode(value[i])) foundlabel.resizeToContent() if label == 'gold': self.widgets['status_extra_gold'].resizeToContent() else: self.widgets['status_extra'].resizeToContent() def cityinfo_set(self, settlement): """Sets the city name at top center Show/Hide is handled automatically To hide cityname, set name to '' @param settlement: Settlement class providing the information needed """ if settlement is self.settlement: return if self.settlement is not None: self.settlement.remove_change_listener(self.update_settlement) self.settlement = settlement if settlement is None: self.widgets['city_info'].hide() else: self.widgets['city_info'].show() self.update_settlement() settlement.add_change_listener(self.update_settlement) def resourceinfo_set(self, source, res_needed = None, res_usable = None, res_from_ship = False): city = source if not res_from_ship else None self.cityinfo_set(city) if source is not self.resource_source: if self.resource_source is not None: self.resource_source.remove_change_listener(self.update_resource_source) if source is None or self.session.world.player != source.owner: self.widgets['status'].hide() self.widgets['status_extra'].hide() self.resource_source = None self.update_gold() if source is not None and self.session.world.player == source.owner: if source is not self.resource_source: source.add_change_listener(self.update_resource_source) self.resource_source = source self.resources_needed = {} if not res_needed else res_needed self.resources_usable = {} if not res_usable else res_usable self.update_resource_source() self.widgets['status'].show() def update_settlement(self): cityinfo = self.widgets['city_info'] cityinfo.mapEvents({ 'city_name': Callback(self.show_change_name_dialog, self.settlement) }) foundlabel = cityinfo.child_finder('city_name') foundlabel._setText(unicode(self.settlement.name)) foundlabel.resizeToContent() foundlabel = self.widgets['city_info'].child_finder('city_inhabitants') foundlabel.text = unicode(' '+str(self.settlement.inhabitants)) foundlabel.resizeToContent() self.widgets['city_info'].resizeToContent() def update_resource_source(self): """Sets the values for resource status bar as well as the building costs""" self.update_gold() for res_id, res_name in {3 : 'textiles', 4 : 'boards', 5 : 'food', 6 : 'tools', 7 : 'bricks'}.iteritems(): first = str(self.resource_source.inventory[res_id]) lines = [] show = False if self.resources_needed.get(res_id, 0) != 0: show = True lines.append('- ' + str(self.resources_needed[res_id])) self.status_set(res_name, first) self.status_set_extra(res_name,lines) self.set_status_position(res_name) if show: self.widgets['status_extra'].show() def ship_build(self, ship): """Calls the Games build_object class.""" self._build(1, ship) def minimap_to_front(self): self.widgets['minimap'].hide() self.widgets['minimap'].show() self.widgets['menu_panel'].hide() self.widgets['menu_panel'].show() def show_diplomacy_menu(self): # check if the menu is already shown if hasattr(self.get_cur_menu(), 'name') and self.get_cur_menu().name == "diplomacy_widget": self.hide_menu() return players = self.session.world.players local_player = self.session.world.player dtabs = [] for player in players + [self.session.world.pirate]: if player is not local_player: dtabs.append(DiplomacyTab(player)) tab = TabWidget(self, tabs=dtabs, name="diplomacy_widget") self.show_menu(tab) def show_multi_select_tab(self): tab = TabWidget(self, tabs = [SelectMultiTab(self.session)], name = 'select_multi') self.show_menu(tab) def show_build_menu(self, update=False): """ @param update: set when build possiblities change (e.g. after settler upgrade) """ # check if build menu is already shown if hasattr(self.get_cur_menu(), 'name') and self.get_cur_menu().name == "build_menu_tab_widget": self.hide_menu() if not update: # this was only a toggle call, don't reshow return self.session.cursor = SelectionTool(self.session) # set cursor for build menu self.deselect_all() btabs = [BuildTab(index, self.callbacks_build[index]) for index in \ range(0, self.session.world.player.settler_level+1)] tab = TabWidget(self, tabs=btabs, name="build_menu_tab_widget", \ active_tab=BuildTab.last_active_build_tab) self.show_menu(tab) def deselect_all(self): for instance in self.session.selected_instances: instance.deselect() self.session.selected_instances.clear() def _build(self, building_id, unit = None): """Calls the games buildingtool class for the building_id. @param building_id: int with the building id that is to be built. @param unit: weakref to the unit, that builds (e.g. ship for branch office)""" self.hide_menu() self.deselect_all() cls = Entities.buildings[building_id] if hasattr(cls, 'show_build_menu'): cls.show_build_menu() self.session.cursor = BuildingTool(self.session, cls, None if unit is None else unit()) def _get_menu_object(self, menu): """Returns pychan object if menu is a string, else returns menu @param menu: str with the guiname or pychan object. """ if isinstance(menu, str): menu = self.widgets[menu] return menu def get_cur_menu(self): """Returns menu that is currently displayed""" return self._old_menu def show_menu(self, menu): """Shows a menu @param menu: str with the guiname or pychan object. """ if self._old_menu is not None: self._old_menu.hide() self._old_menu = self._get_menu_object(menu) if self._old_menu is not None: self._old_menu.show() self.minimap_to_front() def hide_menu(self): self.show_menu(None) def toggle_menu(self, menu): """Shows a menu or hides it if it is already displayed. @param menu: parameter supported by show_menu(). """ if self.get_cur_menu() == self._get_menu_object(menu): self.hide_menu() else: self.show_menu(menu) def build_load_tab(self, num): """Loads a subcontainer into the build menu and changes the tabs background. @param num: number representing the tab to load. """ tab1 = self.widgets['build'].findChild(name=('tab'+str(self.active_build))) tab2 = self.widgets['build'].findChild(name=('tab'+str(num))) activetabimg, nonactiveimg= tab1._getImage(), tab2._getImage() tab1._setImage(nonactiveimg) tab2._setImage(activetabimg) contentarea = self.widgets['build'].findChild(name='content') contentarea.removeChild(self.widgets['build_tab'+str(self.active_build)]) contentarea.addChild(self.widgets['build_tab'+str(num)]) contentarea.adaptLayout() self.active_build = num def set_status_position(self, resource_name): icon_name = resource_name + '_icon' for i in xrange(1, 3): lbl_name = resource_name + '_' + str(i) # tools_1 = inventory amount, tools_2 = cost of to-be-built building if resource_name == 'gold': self._set_label_position('status_gold', lbl_name, icon_name, 33, 31 + i*20) else: self._set_label_position('status', lbl_name, icon_name, 24, 31 + i*20) def _set_label_position(self, widget, lbl_name, icon_name, xoffset, yoffset): icon = self.widgets[widget].child_finder(icon_name) label = self.widgets[widget].child_finder(lbl_name) label.position = (icon.position[0] - label.size[0]/2 + xoffset, yoffset) def save(self, db): self.message_widget.save(db) self.logbook.save(db) def load(self, db): self.message_widget.load(db) self.logbook.load(db) self.minimap.draw() # update minimap to new world def show_change_name_dialog(self, instance): """Shows a dialog where the user can change the name of a NamedObject. The game gets paused while the dialog is executed.""" self.session.speed_pause() events = { 'okButton': Callback(self.change_name, instance), 'cancelButton': self._hide_change_name_dialog } self.main_gui.on_escape = self._hide_change_name_dialog changename = self.widgets['change_name'] newname = changename.findChild(name='new_name') changename.mapEvents(events) newname.capture(Callback(self.change_name, instance)) changename.show() newname.requestFocus() def _hide_change_name_dialog(self): """Escapes the change_name dialog""" self.session.speed_unpause() self.main_gui.on_escape = self.main_gui.toggle_pause self.widgets['change_name'].hide() def change_name(self, instance): """Applies the change_name dialogs input and hides it""" new_name = self.widgets['change_name'].collectData('new_name') self.widgets['change_name'].findChild(name='new_name').text = u'' if not (len(new_name) == 0 or new_name.isspace()): RenameObject(instance, new_name).execute(self.session) self._hide_change_name_dialog() def on_escape(self): if self.logbook.is_visible(): self.logbook.hide() else: return False return True def display_game_speed(self, text): """ @param text: unicode string to display as speed value """ wdg = self.widgets['minimap'].findChild(name="speed_text") wdg.text = text wdg.resizeToContent() self.widgets['minimap'].show() def _player_settler_level_change_listener(self): """Gets called when the player changes""" menu = self.get_cur_menu() if hasattr(menu, "name"): if menu.name == "build_menu_tab_widget": # player changed and build menu is currently displayed self.show_build_menu(update=True) def show_chat_dialog(self): """Show a dialog where the user can enter a chat message""" events = { 'okButton': self._do_chat, 'cancelButton': self._hide_chat_dialog } self.main_gui.on_escape = self._hide_chat_dialog self.widgets['chat'].mapEvents(events) self.widgets['chat'].findChild(name='msg').capture( self._do_chat ) self.widgets['chat'].show() self.widgets['chat'].findChild(name="msg").requestFocus() def _hide_chat_dialog(self): """Escapes the chat dialog""" self.main_gui.on_escape = self.main_gui.toggle_pause self.widgets['chat'].hide() def _do_chat(self): """Actually initiates chatting and hides the dialog""" msg = self.widgets['chat'].findChild(name='msg').text Chat(msg).execute(self.session) self.widgets['chat'].findChild(name='msg').text = u'' self._hide_chat_dialog()
class IngameGui(LivingObject): """Class handling all the ingame gui events.""" gui = livingProperty() tabwidgets = livingProperty() message_widget = livingProperty() minimap = livingProperty() styles = { 'city_info' : 'city_info', 'change_name' : 'book', 'chat' : 'book', 'status' : 'resource_bar', 'status_gold' : 'resource_bar', 'status_extra' : 'resource_bar', 'status_extra_gold' : 'resource_bar', 'ingame_pause' : 'book' } def __init__(self, session, gui): super(IngameGui, self).__init__() self.session = session self.main_gui = gui self.widgets = {} self.tabwidgets = {} self.settlement = None self.resource_source = None self.resources_needed, self.resources_usable = {}, {} self._old_menu = None self.widgets = LazyWidgetsDict(self.styles, center_widgets=False) self.widgets['city_info'].child_finder = PychanChildFinder(self.widgets['city_info']) self.widgets['city_info'].position = ( horizons.main.fife.engine_settings.getScreenWidth()/2 - self.widgets['city_info'].size[0]/2 - 10, 5 ) self.logbook = LogBook(session) # self.widgets['minimap'] is the guichan gui around the acctual minimap, which is saved # in self.minimap self.widgets['minimap'].position = ( horizons.main.fife.engine_settings.getScreenWidth() - self.widgets['minimap'].size[0] -20, 4 ) self.widgets['minimap'].show() self.widgets['minimap'].mapEvents({ 'zoomIn' : self.session.view.zoom_in, 'zoomOut' : self.session.view.zoom_out, 'rotateRight' : self.session.view.rotate_right, 'rotateLeft' : self.session.view.rotate_left, 'speedUp' : self.session.speed_up, 'speedDown' : self.session.speed_down }) self.widgets['minimap'].findChild(name="speed_text").stylize('menu') minimap_rect = Rect.init_from_topleft_and_size(self.widgets['minimap'].position[0]+77, 55, 120, 120) self.minimap = Minimap(minimap_rect, self.session, \ self.session.view.renderer['GenericRenderer']) minimap_overlay = self.widgets['minimap'].findChild(name='minimap_overlay_image') self.minimap.use_overlay_icon(minimap_overlay) self.widgets['menu_panel'].position = ( horizons.main.fife.engine_settings.getScreenWidth() - self.widgets['menu_panel'].size[0] +15, 149) self.widgets['menu_panel'].show() self.widgets['menu_panel'].mapEvents({ 'destroy_tool' : self.session.destroy_tool, 'build' : self.show_build_menu, 'helpLink' : self.main_gui.on_help, 'gameMenuButton' : self.main_gui.show_pause, 'logbook' : self.logbook.toggle_visibility }) self.widgets['tooltip'].hide() self.widgets['status'].child_finder = PychanChildFinder(self.widgets['status']) self.widgets['status_extra'].child_finder = PychanChildFinder(self.widgets['status_extra']) self.message_widget = MessageWidget(self.session, \ self.widgets['city_info'].position[0] + \ self.widgets['city_info'].size[0], 5) self.widgets['status_gold'].show() self.widgets['status_gold'].child_finder = PychanChildFinder(self.widgets['status_gold']) self.widgets['status_extra_gold'].child_finder = PychanChildFinder(self.widgets['status_extra_gold']) # map button names to build functions calls with the building id callbackWithArguments = pychan.tools.callbackWithArguments self.callbacks_build = {} for id,button_name,settler_level in horizons.main.db.get_building_id_buttonname_settlerlvl(): if not settler_level in self.callbacks_build: self.callbacks_build[settler_level] = {} self.callbacks_build[settler_level][button_name] = callbackWithArguments(self._build, id) def end(self): self.widgets['menu_panel'].mapEvents({ 'destroy_tool' : None, 'build' : None, 'helpLink' : None, 'gameMenuButton' : None }) self.widgets['minimap'].mapEvents({ 'zoomIn' : None, 'zoomOut' : None, 'rotateRight' : None, 'rotateLeft' : None }) for w in self.widgets.itervalues(): if w.parent is None: w.hide() self.message_widget = None self.tabwidgets = None self.minimap = None self.hide_menu() super(IngameGui, self).end() def update_gold(self): first = str(self.session.world.player.inventory[RES.GOLD_ID]) lines = [] show = False if self.resource_source is not None and self.resources_needed.get(RES.GOLD_ID, 0) != 0: show = True lines.append('- ' + str(self.resources_needed[RES.GOLD_ID])) self.status_set('gold', first) self.status_set_extra('gold',lines) self.set_status_position('gold') if show: self.widgets['status_extra_gold'].show() else: self.widgets['status_extra_gold'].hide() def status_set(self, label, value): """Sets a value on the status bar (available res of the settlement). @param label: str containing the name of the label to be set. @param value: value the Label is to be set to. """ if isinstance(value,list): value = value[0] gui = self.widgets['status_gold'] if label == 'gold' else self.widgets['status'] foundlabel = gui.child_finder(label + '_1') foundlabel._setText(unicode(value)) foundlabel.resizeToContent() gui.resizeToContent() def status_set_extra(self,label,value): """Sets a value on the extra status bar. (below normal status bar, needed res for build) @param label: str containing the name of the label to be set. @param value: value the Label is to be set to. """ if not hasattr(self, "bg_icon_pos"): self.bg_icon_pos = {'gold':(14,83), 'food':(0,6), 'tools':(52,6), 'boards':(104,6), 'bricks':(156,6), 'textiles':(207,6)} self.bgs_shown = {} bg_icon = pychan.widgets.Icon(image="content/gui/images/background/res_mon_extra_bg.png" if label == 'gold' else "content/gui/images/background/res_extra_bg.png", position=self.bg_icon_pos[label], name='bg_icon_' + label) if not value: foundlabel = (self.widgets['status_extra_gold'] if label == 'gold' else self.widgets['status_extra']).child_finder(label + '_' + str(2)) foundlabel.text = u'' foundlabel.resizeToContent() if label in self.bgs_shown: (self.widgets['status_extra_gold'] if label == 'gold' else self.widgets['status_extra']).removeChild(self.bgs_shown[label]) del self.bgs_shown[label] self.widgets['status_extra_gold'].resizeToContent() if label == 'gold' else self.widgets['status_extra'].resizeToContent() return if isinstance(value, str): value = [value] #for i in xrange(len(value), 3): # value.append("") if (self.widgets['status_extra_gold'] if label == 'gold' else self.widgets['status_extra']).findChild(name='bg_icon_' + label) is None: (self.widgets['status_extra_gold'] if label == 'gold' else self.widgets['status_extra']).insertChild(bg_icon, 0) self.bgs_shown[label] = bg_icon for i in xrange(0,len(value)): foundlabel = (self.widgets['status_extra_gold'] if label == 'gold' else self.widgets['status_extra']).child_finder(name=label + '_' + str(i+2)) foundlabel._setText(unicode(value[i])) foundlabel.resizeToContent() if label == 'gold': self.widgets['status_extra_gold'].resizeToContent() else: self.widgets['status_extra'].resizeToContent() def cityinfo_set(self, settlement): """Sets the city name at top center Show/Hide is handled automatically To hide cityname, set name to '' @param settlement: Settlement class providing the information needed """ if settlement is self.settlement: return if self.settlement is not None: self.settlement.remove_change_listener(self.update_settlement) self.settlement = settlement if settlement is None: self.widgets['city_info'].hide() else: self.widgets['city_info'].show() self.update_settlement() settlement.add_change_listener(self.update_settlement) def resourceinfo_set(self, source, res_needed = {}, res_usable = {}, res_from_ship = False): city = source if not res_from_ship else None self.cityinfo_set(city) if source is not self.resource_source: if self.resource_source is not None: self.resource_source.remove_change_listener(self.update_resource_source) if source is None or self.session.world.player != source.owner: self.widgets['status'].hide() self.widgets['status_extra'].hide() self.resource_source = None self.update_gold() if source is not None and self.session.world.player == source.owner: if source is not self.resource_source: source.add_change_listener(self.update_resource_source) self.resource_source = source self.resources_needed = res_needed self.resources_usable = res_usable self.update_resource_source() self.widgets['status'].show() def update_settlement(self): self.widgets['city_info'].mapEvents({'city_name': pychan.tools.callbackWithArguments( \ self.show_change_name_dialog, self.settlement)}) foundlabel = self.widgets['city_info'].child_finder('city_name') foundlabel._setText(unicode(self.settlement.name)) foundlabel.resizeToContent() foundlabel = self.widgets['city_info'].child_finder('city_inhabitants') foundlabel.text = unicode(' '+str(self.settlement.inhabitants)) foundlabel.resizeToContent() self.widgets['city_info'].resizeToContent() def update_resource_source(self): """Sets the values for resource status bar as well as the building costs""" self.update_gold() for res_id, res_name in {3 : 'textiles', 4 : 'boards', 5 : 'food', 6 : 'tools', 7 : 'bricks'}.iteritems(): first = str(self.resource_source.inventory[res_id]) lines = [] show = False if self.resources_needed.get(res_id, 0) != 0: show = True lines.append('- ' + str(self.resources_needed[res_id])) self.status_set(res_name, first) self.status_set_extra(res_name,lines) self.set_status_position(res_name) if show: self.widgets['status_extra'].show() def ship_build(self, ship): """Calls the Games build_object class.""" self._build(1, ship) def minimap_to_front(self): self.widgets['minimap'].hide() self.widgets['minimap'].show() self.widgets['menu_panel'].hide() self.widgets['menu_panel'].show() def show_ship(self, ship): self.widgets['ship'].findChild(name='buildingNameLabel').text = \ unicode(ship.name+" (Ship type)") size = self.widgets['ship'].findChild(name='chargeBar').size size = (size[0] - 2, size[1] - 2) self.widgets['ship'].findChild(name='chargeBarLeft').size = (int(0.5 + 0.75 * size[0]), size[1]) self.widgets['ship'].findChild(name='chargeBarRight').size = (int(0.5 + size[0] - 0.75 * size[0]), size[1]) pos = self.widgets['ship'].findChild(name='chargeBar').position pos = (pos[0] + 1, pos[1] + 1) self.widgets['ship'].findChild(name='chargeBarLeft').position = pos self.widgets['ship'].findChild(name='chargeBarRight').position = (int(0.5 + pos[0] + 0.75 * size[0]), pos[1]) self.widgets['ship'].mapEvents({ 'foundSettelment' : ychan.tools.callbackWithArguments(self.ship_build, ship) }) self.show_menu('ship') def show_build_menu(self): # check if build menu is already showed if hasattr(self.get_cur_menu(), 'name') and self.get_cur_menu().name == "build_menu_tab_widget": self.hide_menu() return self.session.cursor = SelectionTool(self.session) # set cursor for build menu self.deselect_all() btabs = [BuildTab(index, self.callbacks_build[index]) for index in \ range(0, self.session.world.player.settler_level+1)] tab = TabWidget(self, tabs=btabs, name="build_menu_tab_widget", \ active_tab=BuildTab.last_active_build_tab) self.show_menu(tab) def deselect_all(self): for instance in self.session.selected_instances: instance.deselect() self.session.selected_instances.clear() def _build(self, building_id, unit = None): """Calls the games buildingtool class for the building_id. @param building_id: int with the building id that is to be built. @param unit: weakref to the unit, that builds (e.g. ship for branch office)""" self.hide_menu() self.deselect_all() cls = Entities.buildings[building_id] if hasattr(cls, 'show_build_menu'): cls.show_build_menu() self.session.cursor = BuildingTool(self.session, cls, None if unit is None else unit()) def _get_menu_object(self, menu): """Returns pychan object if menu is a string, else returns menu @param menu: str with the guiname or pychan object. """ if isinstance(menu, str): menu = self.widgets[menu] return menu def get_cur_menu(self): """Returns menu that is currently displayed""" return self._old_menu def show_menu(self, menu): """Shows a menu @param menu: str with the guiname or pychan object. """ if self._old_menu is not None: self._old_menu.hide() self._old_menu = self._get_menu_object(menu) if self._old_menu is not None: self._old_menu.show() self.minimap_to_front() def hide_menu(self): self.show_menu(None) def toggle_menu(self, menu): """Shows a menu or hides it if it is already displayed. @param menu: parameter supported by show_menu(). """ if self.get_cur_menu() == self._get_menu_object(menu): self.hide_menu() else: self.show_menu(menu) def build_load_tab(self, num): """Loads a subcontainer into the build menu and changes the tabs background. @param num: number representing the tab to load. """ tab1 = self.widgets['build'].findChild(name=('tab'+str(self.active_build))) tab2 = self.widgets['build'].findChild(name=('tab'+str(num))) activetabimg, nonactiveimg= tab1._getImage(), tab2._getImage() tab1._setImage(nonactiveimg) tab2._setImage(activetabimg) contentarea = self.widgets['build'].findChild(name='content') contentarea.removeChild(self.widgets['build_tab'+str(self.active_build)]) contentarea.addChild(self.widgets['build_tab'+str(num)]) contentarea.adaptLayout() self.active_build = num def set_status_position(self, resource_name): for i in xrange(1, 4): icon_name = resource_name + '_icon' plusx = 0 if i > 1: # increase x position for lines greater the 1 plusx = 20 if resource_name == 'gold': self.widgets['status_gold'].child_finder(resource_name + '_' + str(i)).position = ( self.widgets['status_gold'].child_finder(icon_name).position[0] + 33 - self.widgets['status_gold'].findChild(name = resource_name + '_' + str(i)).size[0]/2, 41 + 10 * i + plusx ) else: self.widgets['status'].child_finder(resource_name + '_' + str(i)).position = ( self.widgets['status'].child_finder(icon_name).position[0] + 24 - self.widgets['status'].child_finder(resource_name + '_' + str(i)).size[0]/2, 41 + 10 * i + plusx ) def save(self, db): self.message_widget.save(db) def load(self, db): self.message_widget.load(db) self.minimap.draw() # update minimap to new world def show_change_name_dialog(self, instance): """Shows a dialog where the user can change the name of a NamedObject. The game gets paused while the dialog is executed.""" self.session.speed_pause() events = { 'okButton': pychan.tools.callbackWithArguments(self.change_name, instance), 'cancelButton': self._hide_change_name_dialog } self.main_gui.on_escape = self._hide_change_name_dialog self.widgets['change_name'].mapEvents(events) self.widgets['change_name'].findChild(name='new_name').capture( \ pychan.tools.callbackWithArguments(self.change_name, instance) ) self.widgets['change_name'].show() self.widgets['change_name'].findChild(name="new_name").requestFocus() def _hide_change_name_dialog(self): """Escapes the change_name dialog""" self.session.speed_unpause() self.main_gui.on_escape = self.main_gui.show_pause self.widgets['change_name'].hide() def change_name(self, instance): """Applies the change_name dialogs input and hides it""" new_name = self.widgets['change_name'].collectData('new_name') self.widgets['change_name'].findChild(name='new_name').text = u'' if not (len(new_name) == 0 or new_name.isspace()): RenameObject(instance, new_name).execute(self.session) self._hide_change_name_dialog() def toggle_ingame_pause(self): """Called when the hotkey for pause is pressed. Displays pause notification and does the acctual (un)pausing.""" if not hasattr(self, "_toggle_ingame_pause_shown"): self._toggle_ingame_pause_shown = False if not self._toggle_ingame_pause_shown: self.session.speed_pause() self.main_gui.on_escape = self.toggle_ingame_pause self.widgets['ingame_pause'].mapEvents({'unpause_button': self.toggle_ingame_pause}) self.widgets['ingame_pause'].show() self._toggle_ingame_pause_shown = True else: self.main_gui.on_escape = self.main_gui.show_pause self.widgets['ingame_pause'].hide() self.session.speed_unpause() self._toggle_ingame_pause_shown = False def toggle_ingame_pdb_start(self): """Called when the hotkey for debug is pressed. Displays only debug notification.""" pass def on_escape(self): if self.logbook.is_visible(): self.logbook.hide() else: return False return True def display_game_speed(self, text): """ @param text: unicode string to display as speed value """ wdg = self.widgets['minimap'].findChild(name="speed_text") wdg.text = text wdg.resizeToContent() self.widgets['minimap'].show() def _player_settler_level_change_listener(self): """Gets called when the player changes""" menu = self.get_cur_menu() if hasattr(menu, "name"): if menu.name == "build_menu_tab_widget": # player changed and build menu is currently displayed self.show_build_menu() def show_chat_dialog(self): """Show a dialog where the user can enter a chat message""" events = { 'okButton': self._do_chat, 'cancelButton': self._hide_chat_dialog } self.main_gui.on_escape = self._hide_chat_dialog self.widgets['chat'].mapEvents(events) self.widgets['chat'].findChild(name='msg').capture( self._do_chat ) self.widgets['chat'].show() self.widgets['chat'].findChild(name="msg").requestFocus() def _hide_chat_dialog(self): """Escapes the chat dialog""" self.main_gui.on_escape = self.main_gui.show_pause self.widgets['chat'].hide() def _do_chat(self): """Acctually initiates chatting and hides the dialog""" msg = self.widgets['chat'].findChild(name='msg').text Chat(msg).execute(self.session) self.widgets['chat'].findChild(name='msg').text = u'' self._hide_chat_dialog()