Package horizons :: Package gui :: Package modules :: Module ingame
[hide private]
[frames] | no frames]

Source Code for Module horizons.gui.modules.ingame

  1  # ################################################### 
  2  # Copyright (C) 2008-2017 The Unknown Horizons Team 
  3  # team@unknown-horizons.org 
  4  # This file is part of Unknown Horizons. 
  5  # 
  6  # Unknown Horizons is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 2 of the License, or 
  9  # (at your option) any later version. 
 10  # 
 11  # This program is distributed in the hope that it will be useful, 
 12  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  # GNU General Public License for more details. 
 15  # 
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not, write to the 
 18  # Free Software Foundation, Inc., 
 19  # 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
 20  # ################################################### 
 21   
 22   
 23  import horizons.globals 
 24  from horizons.command.misc import Chat 
 25  from horizons.command.uioptions import RenameObject 
 26  from horizons.component.ambientsoundcomponent import AmbientSoundComponent 
 27  from horizons.component.namedcomponent import NamedComponent, SettlementNameComponent 
 28  from horizons.constants import GUI 
 29  from horizons.extscheduler import ExtScheduler 
 30  from horizons.gui.util import load_uh_widget 
 31  from horizons.gui.widgets.imagebutton import CancelButton, OkButton 
 32  from horizons.gui.windows import Dialog 
 33  from horizons.i18n import gettext as T 
 34  from horizons.messaging import HoverSettlementChanged, ResourceBarResize, SettlerInhabitantsChanged 
 35  from horizons.util.pychanchildfinder import PychanChildFinder 
 36  from horizons.util.python.callback import Callback 
 37   
 38   
39 -class ChatDialog(Dialog):
40 """Allow player to send messages to other players.""" 41 focus = 'msg' 42
43 - def __init__(self, windows, session):
44 super().__init__(windows) 45 self._session = session
46
47 - def prepare(self):
48 self._gui = load_uh_widget('chat.xml') 49 self.return_events = { 50 OkButton.DEFAULT_NAME: True, 51 CancelButton.DEFAULT_NAME: False, 52 }
53
54 - def act(self, send_message):
55 """Actually initiates chatting and hides the dialog""" 56 if not send_message: 57 return 58 msg = self._gui.findChild(name="msg").text 59 Chat(msg).execute(self._session)
60 61
62 -class ChangeNameDialog(Dialog):
63 """Shows a dialog where the user can change the name of a NamedComponent.""" 64 modal = True 65 focus = 'new_name' 66
67 - def __init__(self, windows, session):
68 super().__init__(windows) 69 self._session = session
70
71 - def prepare(self, instance):
72 self._gui = load_uh_widget('change_name.xml') 73 self.return_events = { 74 OkButton.DEFAULT_NAME: instance, 75 CancelButton.DEFAULT_NAME: False, 76 } 77 oldname = self._gui.findChild(name='old_name') 78 oldname.text = instance.get_component(NamedComponent).name
79
80 - def act(self, named_instance):
81 """Renames the instance that is returned by the dialog, if confirmed. 82 83 Hitting Esc or the Cancel button will not trigger a rename. 84 if no name was entered or the new name only consists of spaces, abort 85 the renaming as well. 86 """ 87 if not named_instance: 88 return 89 90 new_name = self._gui.collectData('new_name') 91 92 if new_name and not new_name.isspace(): 93 # different namedcomponent classes share the name 94 namedcomp = named_instance.get_component_by_name(NamedComponent.NAME) 95 RenameObject(namedcomp, new_name).execute(self._session)
96 97
98 -class CityInfo:
99 """Display city name and inhabitant count at top of the screen.""" 100 # FIXME updating the position of this widget should be the responsibility of the 101 # FIXME ingamegui, as it needs to take the resource overview bar into account as 102 # FIXME well. However, an update to the settlement's name triggers repositioning 103 # FIXME too, and we'd need a clean way to pass that info the ingamegui. 104
105 - def __init__(self, ingame_gui):
106 self._ingame_gui = ingame_gui 107 self._widget = load_uh_widget('city_info.xml', 'resource_bar') 108 self._widget.adaptLayout() 109 self._child_finder = PychanChildFinder(self._widget) 110 111 self._settlement = None 112 HoverSettlementChanged.subscribe(self._on_hover_settlement_change) 113 SettlerInhabitantsChanged.subscribe(self._on_settler_inhabitant_change) 114 ResourceBarResize.subscribe(self._on_resourcebar_resize)
115
116 - def end(self):
120
121 - def _on_hover_settlement_change(self, message):
123
124 - def set_settlement(self, settlement):
125 """Sets the city name at top center of screen. 126 127 Show/Hide is handled automatically 128 """ 129 if self._settlement: 130 self._settlement.remove_change_listener(self._update_settlement) 131 132 self._settlement = settlement 133 134 if not settlement: 135 # Hide the widget (after some seconds). 136 # Delayed to allow players scrolling away to click on the widget. 137 # This often happens when moving mouse up from island to reach it. 138 ExtScheduler().add_new_object(self.hide, self, run_in=GUI.CITYINFO_UPDATE_DELAY) 139 else: 140 # Cancel previously scheduled hide if a settlement is hovered again. 141 ExtScheduler().rem_call(self, self.hide) 142 143 self._update_settlement() # This calls show()! 144 settlement.add_change_listener(self._update_settlement)
145
146 - def _on_settler_inhabitant_change(self, message):
147 """Update display of inhabitants count.""" 148 foundlabel = self._child_finder('city_inhabitants') 149 old_amount = int(foundlabel.text) if foundlabel.text else 0 150 foundlabel.text = ' {amount:>4d}'.format(amount=old_amount + message.change) 151 foundlabel.resizeToContent()
152
153 - def _update_settlement(self):
154 city_name_label = self._child_finder('city_name') 155 if self._settlement.owner.is_local_player: # allow name changes 156 # Update settlement on the resource overview to make sure it 157 # is setup correctly for the coming calculations 158 self._ingame_gui.resource_overview.set_inventory_instance(self._settlement) 159 cb = Callback(self._ingame_gui.show_change_name_dialog, self._settlement) 160 helptext = T("Click to change the name of your settlement") 161 city_name_label.enable_cursor_change_on_hover() 162 else: # no name changes 163 cb = lambda: AmbientSoundComponent.play_special('error') 164 helptext = "" 165 city_name_label.disable_cursor_change_on_hover() 166 167 self._widget.mapEvents({ 168 'city_name': cb 169 }) 170 city_name_label.helptext = helptext 171 172 foundlabel = self._child_finder('owner_emblem') 173 foundlabel.image = 'content/gui/icons/widgets/cityinfo/settlement_{}.png'.format( 174 self._settlement.owner.color.name) 175 foundlabel.helptext = self._settlement.owner.name 176 177 foundlabel = self._child_finder('city_name') 178 foundlabel.text = self._settlement.get_component(SettlementNameComponent).name 179 foundlabel.resizeToContent() 180 181 foundlabel = self._child_finder('city_inhabitants') 182 foundlabel.text = ' {amount:>4d}'.format(amount=self._settlement.inhabitants) 183 foundlabel.resizeToContent() 184 185 self._update_position()
186
187 - def _update_position(self):
188 """Places cityinfo widget depending on resource bar dimensions. 189 190 For a normal-sized resource bar and reasonably large resolution: 191 * determine resource bar length (includes gold) 192 * determine empty horizontal space between resbar end and minimap start 193 * display cityinfo centered in that area if it is sufficiently large 194 195 If too close to the minimap (cityinfo larger than length of this empty space) 196 move cityinfo centered to very upper screen edge. Looks bad, works usually. 197 In this case, the resbar is redrawn to put the cityinfo "behind" it visually. 198 """ 199 width = horizons.globals.fife.engine_settings.getScreenWidth() 200 resbar = self._ingame_gui.resource_overview.get_size() 201 is_foreign = (self._settlement.owner != self._ingame_gui.session.world.player) 202 blocked = self._widget.size[0] + int(1.5 * self._ingame_gui.minimap.get_size()[1]) 203 # minimap[1] returns width! Use 1.5*width because of the GUI around it 204 205 if is_foreign: # other player, no resbar exists 206 self._widget.pos = ('center', 'top') 207 xoff = 0 208 yoff = 10 209 elif blocked < width < resbar[0] + blocked: # large resbar / small resolution 210 self._widget.pos = ('center', 'top') 211 xoff = 0 212 yoff = resbar[1] # below resbar 213 else: 214 self._widget.pos = ('left', 'top') 215 xoff = resbar[0] + (width - blocked - resbar[0]) // 2 216 yoff = 15 217 218 self._widget.offset = (xoff, yoff) 219 self._widget.position_technique = "{pos[0]}{off[0]:+d}:{pos[1]}{off[1]:+d}".format( 220 pos=self._widget.pos, 221 off=self._widget.offset) 222 self._widget.hide() 223 self._widget.show()
224
225 - def _on_resourcebar_resize(self, message):
226 self._update_position()
227
228 - def hide(self):
229 self._widget.hide()
230