helpPointerSvc.py (29659B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\pointerTool\helpPointerSvc.py 2 import re 3 import blue 4 import neocom2.btnIDs as btnIDs 5 import carbonui.const as uiconst 6 import eve.client.script.ui.shared.pointerTool.pointerToolConst as pConst 7 import eveexceptions 8 import log 9 import mathext 10 import uthread 11 from carbon.common.script.sys.service import Service 12 from carbon.common.script.util.timerstuff import AutoTimer 13 from carbonui.uicore import uicore 14 from eve.client.script.ui.inflight.selectedItemConst import ICON_ID_AND_CMD_BY_ACTIONID 15 from eve.client.script.ui.shared.agencyNew.contentGroups import contentGroupProvider 16 from eve.client.script.ui.shared.agencyNew.contentGroups.contentGroupConst import contentGroupNameByID 17 import eve.client.script.ui.shared.mapView.categories.const as mapFilterConst 18 from eve.client.script.ui.shared.neocom.neocom.btnData.btnDataRaw import BTNDATARAW_BY_ID 19 from eve.client.script.ui.shared.neocom.neocom.buttons.buttonEveMenu import ButtonEveMenu 20 from eve.client.script.ui.shared.neocom.neocom.neocomConst import BTNTYPE_GROUP, BTNTYPE_CMD, BTNTYPE_INVENTORY, BTNTYPE_CHAT, RAWDATA_SKILLS, BTNTYPE_CAREER_PROGRAM 21 from eve.client.script.ui.shared.neocom.neocom.neocomRawData import GetEveMenuRawData 22 from eve.client.script.ui.shared.pointerTool.entry import PointerWndEntry 23 from eve.client.script.ui.shared.pointerTool.link import SCHEME_HELP_POINTER 24 from eve.client.script.ui.shared.pointerTool.message_bus.helpPointerMessenger import HelpPointerMessenger 25 from eve.client.script.ui.shared.pointerTool.pointerObject import GetPointerObjectFromAuthoredPointer, GetPointerObjectFromActions, GetPointerObjectForStationSvc, GetPointerObjectForAgencyTab, GetPointerObjectForNeocom, GetPointerObjectForAgencyCard, GetPointerObjectForSkillPlan, GetPointerObjectForSkillPlanFaction, GetPointerObjectForSkillPlanCareer, GetPointerObjectMapCategory, GetPointerObjectMapFilter 26 from eve.client.script.ui.shared.pointerTool.pointerOverlay import PointerOverlay 27 from eve.client.script.ui.shared.pointerTool.pointerToolUtil import GetFilteredNodes, TextAndTexture 28 from eve.client.script.ui.shared.pointerTool.textContainerWithSubIcon import PointerContainerWithPath 29 from eve.client.script.ui.shared.pointerTool.pointerToolSignals import on_reset 30 from eve.client.script.ui.station.stationServiceConst import serviceDataByNameID 31 from eve.common.script.sys.idCheckers import IsNPCCorporation 32 from eveexceptions import UserError 33 from expiringdict import ExpiringDict 34 from fsdBuiltData.common.uiHelpPointersFSDLoader import UiHelpPointersFSDLoader 35 from localization import GetByLabel 36 from skills.skillplan.skillPlanService import GetSkillPlanSvc 37 from uihighlighting import UiHighlightDirections 38 from uihighlighting.ui.uipointer import CONTENT_CONTAINER_PADDING, UIPOINTER_WIDTH 39 NEOCOM_E_ICON = 'res:/UI/Texture/icons/79_64_11.png' 40 urlText = 'a href="{}:'.format(SCHEME_HELP_POINTER) 41 POINTER_TAG_PATTERN = '<%s[\\w.]+">' % urlText 42 POINTER_URL_END = '">' 43 44 class HelpPointerSvc(Service): 45 __guid__ = 'svc.helpPointer' 46 __servicename__ = 'helpPointer' 47 __displayname__ = 'Help Pointer Service' 48 49 def __init__(self): 50 self._action_label_paths_by_element_name = None 51 self._agency_label_by_element_name = None 52 self._all_pointers_by_element_name = None 53 self._highlight_by_element_name = None 54 self._loading = False 55 self._neocom_pointers_by_element_name = None 56 self._ready = False 57 self._station_service_text_by_element_name = None 58 self._skill_plans_by_name = None 59 self.pendingPointers = ExpiringDict(100, 5) 60 self.pendingThread = None 61 self.pointerOverlay = None 62 self.utilMenuHighlights = ExpiringDict(100, 5) 63 super(HelpPointerSvc, self).__init__() 64 65 def GetActionLabelPathsByElementName(self): 66 return self.action_label_paths_by_element_name 67 68 @property 69 def action_label_paths_by_element_name(self): 70 self._ensure_loaded() 71 return self._action_label_paths_by_element_name 72 73 def GetHighlightByElementName(self): 74 return self.highlight_by_element_name 75 76 @property 77 def highlight_by_element_name(self): 78 self._ensure_loaded() 79 return self._highlight_by_element_name 80 81 def GetStationServiceTextByElementName(self): 82 return self.station_service_text_by_element_name 83 84 @property 85 def station_service_text_by_element_name(self): 86 self._ensure_loaded() 87 return self._station_service_text_by_element_name 88 89 def GetAgencyLabelByElementName(self): 90 return self.agency_label_by_element_name 91 92 @property 93 def agency_label_by_element_name(self): 94 self._ensure_loaded() 95 return self._agency_label_by_element_name 96 97 def GetNeocomPointersByElementName(self): 98 return self.neocom_pointers_by_element_name 99 100 @property 101 def neocom_pointers_by_element_name(self): 102 self._ensure_loaded() 103 return self._neocom_pointers_by_element_name 104 105 @property 106 def skill_plans_by_name(self): 107 self._ensure_loaded() 108 return self._skill_plans_by_name 109 110 def GetSkillPlansByElementName(self): 111 return self.skill_plans_by_name 112 113 def GetAllPointersByElementName(self): 114 return self.all_pointers_by_element_name 115 116 def GetMapPointersByName(self): 117 return self.map_pointers_by_name 118 119 @property 120 def map_pointers_by_name(self): 121 self._ensure_loaded() 122 return self._map_pointers_by_name 123 124 @property 125 def all_pointers_by_element_name(self): 126 self._ensure_loaded() 127 return self._all_pointers_by_element_name 128 129 def reset(self): 130 self._ready = False 131 self._loading = False 132 on_reset() 133 134 def _ensure_loaded(self): 135 if self._ready: 136 return 137 if self._loading: 138 while self._loading: 139 blue.synchro.Yield() 140 141 return 142 self._loading = True 143 try: 144 self._load_data() 145 self._ready = True 146 finally: 147 self._loading = False 148 149 def _load_data(self): 150 higlights_data = UiHelpPointersFSDLoader.GetData() 151 self._highlight_by_element_name = {x.uiElementName:GetPointerObjectFromAuthoredPointer(x) for x in higlights_data.itervalues()} 152 self._action_label_paths_by_element_name = self._load_all_action_options_pointers() 153 self._station_service_text_by_element_name = self._load_station_services_by_unique_name() 154 self._agency_label_by_element_name = self._load_agency_pointers() 155 self._neocom_pointers_by_element_name = self._load_neocom_buttons_by_pointer() 156 self._skill_plans_by_name = self._load_skill_plans_pointers() 157 self._map_pointers_by_name = self._load_map_pointers() 158 self._all_pointers_by_element_name = self._action_label_paths_by_element_name.copy() 159 self._all_pointers_by_element_name.update(self._station_service_text_by_element_name) 160 self._all_pointers_by_element_name.update(self._agency_label_by_element_name) 161 self._all_pointers_by_element_name.update(self._neocom_pointers_by_element_name) 162 self._all_pointers_by_element_name.update(self._highlight_by_element_name) 163 self._all_pointers_by_element_name.update(self._skill_plans_by_name) 164 self._all_pointers_by_element_name.update(self._map_pointers_by_name) 165 166 def _load_station_services_by_unique_name(self): 167 wanted = [serviceDataByNameID['charcustomization'], 168 serviceDataByNameID['medical'], 169 serviceDataByNameID['repairshop'], 170 serviceDataByNameID['reprocessingPlant'], 171 serviceDataByNameID['navyoffices'], 172 serviceDataByNameID['insurance'], 173 serviceDataByNameID['lpstore'], 174 serviceDataByNameID['securityoffice']] 175 servicesByUniqueName = {} 176 for serviceInfo in wanted: 177 pointerObj = GetPointerObjectForStationSvc(serviceInfo) 178 servicesByUniqueName[pointerObj.uiElementName] = pointerObj 179 180 return servicesByUniqueName 181 182 def _load_all_action_options_pointers(self): 183 ret = {} 184 for labelPath, action in ICON_ID_AND_CMD_BY_ACTIONID.iteritems(): 185 pointerObj = GetPointerObjectFromActions(labelPath, action) 186 if pointerObj is not None: 187 ret[pointerObj.uiElementName] = pointerObj 188 189 return ret 190 191 def _load_agency_pointers(self): 192 ret = {} 193 rootContentGroup = contentGroupProvider.GetRootContentGroup() 194 for g in rootContentGroup.children: 195 if not g.IsContentAvailable(): 196 continue 197 pointerObject = GetPointerObjectForAgencyTab(g) 198 ret[pointerObject.uiElementName] = pointerObject 199 self._add_agency_card_children(ret, g.children) 200 201 return ret 202 203 def _add_agency_card_children(self, pointerDict, groupChildren, level = 0): 204 for eachChild in groupChildren: 205 contentGroupID = eachChild.contentGroupID 206 namePath = contentGroupNameByID.get(contentGroupID, None) 207 if namePath and eachChild.IsVisible(): 208 pointerObject = GetPointerObjectForAgencyCard(eachChild) 209 pointerDict[pointerObject.uiElementName] = pointerObject 210 self._add_agency_card_children(pointerDict, eachChild.children, level=level + 1) 211 212 def _load_skill_plans_pointers(self): 213 ret = {} 214 allCertifiedSkillPlans = GetSkillPlanSvc().GetAllCertified() 215 for eachPlan in allCertifiedSkillPlans.itervalues(): 216 pointerObject = GetPointerObjectForSkillPlan(eachPlan) 217 ret[pointerObject.uiElementName] = pointerObject 218 pointerObject = GetPointerObjectForSkillPlanFaction(eachPlan) 219 if pointerObject: 220 ret[pointerObject.uiElementName] = pointerObject 221 pointerObject = GetPointerObjectForSkillPlanCareer(eachPlan) 222 if pointerObject: 223 ret[pointerObject.uiElementName] = pointerObject 224 225 return ret 226 227 def _load_map_pointers(self): 228 ret = {} 229 groups = mapFilterConst.GROUP_CONTENT + mapFilterConst.GROUP_STATISTICS + [mapFilterConst.CATEGORY_FAVORITES] 230 for groupID in groups: 231 pointerObject = GetPointerObjectMapCategory(groupID) 232 ret[pointerObject.uiElementName] = pointerObject 233 234 for category_id, filterFunc in mapFilterConst.CATEGORY_FILTERS.iteritems(): 235 for f in filterFunc(): 236 pointerObject = GetPointerObjectMapFilter(f) 237 ret[pointerObject.uiElementName] = pointerObject 238 239 return ret 240 241 def _load_neocom_buttons_by_pointer(self): 242 from eve.client.script.ui.shared.neocom.neocom.btnData.btnDataRaw import BTNDATARAW_BY_ID 243 neocomDataByPointerName = {} 244 allValidBtnIDs = set() 245 btnData = GetEveMenuRawData() + list(RAWDATA_SKILLS) + [(BTNTYPE_CHAT, 'chat', None)] 246 self._add_valid_buttons_for_data(btnData, allValidBtnIDs) 247 validBtnData = [] 248 for eachBtnID in allValidBtnIDs: 249 eachData = BTNDATARAW_BY_ID.get(eachBtnID, None) 250 if not eachData or not uicore.cmd.IsCommandAllowed(eachData.cmdName): 251 continue 252 validBtnData.append((eachBtnID, eachData)) 253 254 fixedBtnData = sm.GetService('neocom').GetFixedButtonData() 255 if fixedBtnData: 256 for eachDataNode in fixedBtnData.children: 257 validBtnData.append((eachDataNode.id, eachDataNode)) 258 259 for eachBtnID, eachData in validBtnData: 260 cmd = uicore.cmd.commandMap.GetCommandByName(eachData.cmdName) 261 if cmd: 262 text = cmd.GetName() 263 elif eachData and eachData.label is not None: 264 text = GetByLabel(eachData.label) 265 else: 266 continue 267 pointerObject = GetPointerObjectForNeocom(eachBtnID, eachData, text) 268 neocomDataByPointerName[pointerObject.uiElementName] = pointerObject 269 270 return neocomDataByPointerName 271 272 def _add_valid_buttons_for_data(self, btnData, validBtns): 273 for each in btnData: 274 btnType, btnID, btnChildren = each 275 if btnType in (BTNTYPE_CMD, 276 BTNTYPE_INVENTORY, 277 BTNTYPE_CHAT, 278 BTNTYPE_CAREER_PROGRAM): 279 validBtns.add(btnID) 280 if btnType == BTNTYPE_GROUP and btnChildren: 281 self._add_valid_buttons_for_data(btnChildren, validBtns) 282 283 def ActivateHelperPointer(self, pointerUniqueName, sourceLocation = 0, displayTime = 2): 284 self.LogPointerCreated(pointerUniqueName, sourceLocation) 285 self._ActivateHelperPointer(pointerUniqueName, displayTime) 286 287 def _ActivateHelperPointer(self, pointerUniqueName, displayTime = 2, isFirstCall = True): 288 myHighlight = self.GetAuthoredHighlightByName(pointerUniqueName) 289 if myHighlight: 290 textAndTexture = myHighlight.GetTexAndTexture() 291 elif pointerUniqueName in self.action_label_paths_by_element_name: 292 pointerObject = self.action_label_paths_by_element_name[pointerUniqueName] 293 textAndTexture = pointerObject.GetTexAndTexture() 294 elif pointerUniqueName in self.station_service_text_by_element_name: 295 pointerObject = self.station_service_text_by_element_name[pointerUniqueName] 296 textAndTexture = pointerObject.GetTexAndTexture() 297 elif pointerUniqueName in self.agency_label_by_element_name: 298 pointerObject = self.agency_label_by_element_name[pointerUniqueName] 299 textAndTexture = pointerObject.GetTexAndTexture() 300 elif pointerUniqueName in self.skill_plans_by_name: 301 pointerObject = self.skill_plans_by_name[pointerUniqueName] 302 textAndTexture = pointerObject.GetTexAndTexture() 303 elif pointerUniqueName in self.map_pointers_by_name: 304 pointerObject = self.map_pointers_by_name[pointerUniqueName] 305 textAndTexture = pointerObject.GetTexAndTexture() 306 elif pointerUniqueName.startswith(pConst.NEOCOM_PREFIX): 307 neocomID = pointerUniqueName.replace(pConst.NEOCOM_PREFIX, '') 308 btnData = sm.GetService('neocom').GetBtnData(neocomID) 309 if btnData and btnData.cmdName is not None: 310 cmd = uicore.cmd.commandMap.GetCommandByName(btnData.cmdName) 311 textAndTexture = TextAndTexture(cmd.GetName(), getattr(btnData, 'iconPath', None)) 312 elif btnData and btnData.label is not None: 313 textAndTexture = TextAndTexture(btnData.label, getattr(btnData, 'iconPath', None)) 314 else: 315 if pointerUniqueName in self.neocom_pointers_by_element_name: 316 label = getattr(self.neocom_pointers_by_element_name[pointerUniqueName], 'label', None) 317 if label: 318 notifyText = GetByLabel('UI/Help/PointerWndNotOnScreen', elementName=label) 319 raise UserError('CustomNotify', {'notify': notifyText}) 320 log.LogWarn('PointerWnd: Invalid pointer, pointerUniqueName=%s' % pointerUniqueName) 321 raise UserError('CustomNotify', {'notify': GetByLabel('UI/Help/PointerWndInvalidPointer')}) 322 else: 323 log.LogWarn('PointerWnd: Invalid pointer, pointerUniqueName=%s' % pointerUniqueName) 324 raise UserError('CustomNotify', {'notify': GetByLabel('UI/Help/PointerWndInvalidPointer')}) 325 self.ShowPointer(pointerUniqueName, textAndTexture, displayTime, isFirstCall) 326 327 def ShowPointer(self, pointerUniqueName, uiPointerTextAndTexture, displayTime, isFirstCall = True): 328 if pointerUniqueName is None or pointerUniqueName == '': 329 return 330 pointToElement, newPointerName, extraLines, scopeWarnings, chainElements = self.FindElementToPointToAndScopeCheck(pointerUniqueName) 331 from carbonui.control.window import Window 332 if isinstance(pointToElement, Window): 333 newPointerName = pointToElement.name 334 if not pointToElement or not pointToElement.IsVisible(): 335 notifyText = '<br>'.join([GetByLabel('UI/Help/PointerWndNotOnScreen', elementName=uiPointerTextAndTexture.GetText())] + scopeWarnings) 336 raise UserError('CustomNotify', {'notify': notifyText}) 337 subTextLines = self.GetSubText(pointerUniqueName, pointToElement, extraLines, chainElements) 338 pointerNameToFind = newPointerName or pointerUniqueName 339 defaultDirection = self.GetDirection(pointerNameToFind, pointToElement) 340 uthread.new(self._ShowPointerThread, pointerNameToFind, uiPointerTextAndTexture, subTextLines, displayTime, defaultDirection, not bool(chainElements)) 341 if self.IsMenuHighlight(pointerUniqueName): 342 self.AddUniqueNameToUtilMenuHighlights(pointerUniqueName) 343 if isFirstCall and chainElements: 344 self.pendingPointers[pointerUniqueName] = True 345 if self.pendingThread is None: 346 self.pendingThread = AutoTimer(500, self.ShowPendingPointersThread) 347 348 def FindElementToPointToAndScopeCheck(self, pointerName): 349 elementKeyVal = sm.GetService('uipointerSvc').FindElementToPointTo(pointerName.split('.'), blinkNeocom=False, findWindow=True) 350 element = elementKeyVal.pointToElement if elementKeyVal else None 351 extraLines = getattr(elementKeyVal, 'extraTextLines', []) 352 scopeWarningListEmpty = [] 353 chainElementsEmpty = [] 354 if element and element.IsVisible(): 355 return (element, 356 None, 357 extraLines, 358 scopeWarningListEmpty, 359 chainElementsEmpty) 360 if element and not element.IsVisible() and not pointerName.startswith(pConst.NEOCOM_PREFIX): 361 newPointerName = pConst.GetUniqueNeocomPointerName(pointerName) 362 newElementKeyVal = sm.GetService('uipointerSvc').FindElementToPointTo(newPointerName.split('.'), blinkNeocom=False) 363 if newElementKeyVal and newElementKeyVal.pointToElement: 364 return (newElementKeyVal.pointToElement, 365 newPointerName, 366 extraLines, 367 scopeWarningListEmpty, 368 chainElementsEmpty) 369 if not element or not element.IsVisible(): 370 scopeWarnings = self.GetScopeWarnings(pointerName) 371 if scopeWarnings: 372 return (None, 373 None, 374 [], 375 scopeWarnings, 376 chainElementsEmpty) 377 from eve.client.script.ui.shared.pointerTool.pointerChains import FindChainForPointer 378 pointerChain = FindChainForPointer(pointerName) 379 chainElements = [] 380 for eachPointerName in reversed(pointerChain): 381 nextElementKeyVal = sm.GetService('uipointerSvc').FindElementToPointTo(eachPointerName.split('.'), blinkNeocom=False, findWindow=True) 382 chainElements.insert(0, eachPointerName) 383 if nextElementKeyVal and nextElementKeyVal.pointToElement and nextElementKeyVal.pointToElement.IsVisible(): 384 return (nextElementKeyVal.pointToElement, 385 eachPointerName, 386 extraLines, 387 scopeWarningListEmpty, 388 chainElements) 389 390 return (None, 391 None, 392 extraLines, 393 scopeWarningListEmpty, 394 chainElementsEmpty) 395 396 def GetAuthoredHighlightByName(self, pointerName): 397 return self.highlight_by_element_name.get(pointerName, None) 398 399 def GetDirection(self, pointerName, pointToElement = None): 400 from carbonui.control.window import Window 401 if isinstance(pointToElement, Window): 402 return UiHighlightDirections.UP 403 if pointerName in self.agency_label_by_element_name: 404 return UiHighlightDirections.UP 405 if pointerName in self.agency_label_by_element_name: 406 return UiHighlightDirections.UP 407 myHighlight = self.all_pointers_by_element_name.get(pointerName, None) 408 if myHighlight: 409 return myHighlight.defaultDirection 410 411 def GetOffset(self, pointerName): 412 if pointerName in self.action_label_paths_by_element_name: 413 return -12 414 myHighlight = self.GetAuthoredHighlightByName(pointerName) 415 if myHighlight: 416 return myHighlight.offset 417 418 def IsMenuHighlight(self, pointerUniqueName): 419 myHighlight = self.GetAuthoredHighlightByName(pointerUniqueName) 420 if myHighlight: 421 if myHighlight.isMenuOption: 422 return True 423 return False 424 425 def GetScopeWarnings(self, pointerName): 426 if pointerName in self.action_label_paths_by_element_name and not session.solarsystemid: 427 return [GetByLabel('UI/HelpPointers/Wnd/ScopeInSpace')] 428 myHighlight = self.GetAuthoredHighlightByName(pointerName) 429 if not myHighlight: 430 return '' 431 pointerScope = myHighlight.pointerScope 432 if not pointerScope: 433 return '' 434 scopeWarningList = [] 435 scope = [ x for x in pointerScope ] 436 if 'Fleet' in scope and not session.fleetid: 437 scopeWarningList.append(GetByLabel('UI/HelpPointers/Wnd/ScopeFleet')) 438 if 'Docked' in scope and session.solarsystemid: 439 scopeWarningList.append(GetByLabel('UI/HelpPointers/Wnd/ScopeDocked')) 440 if 'InSpace' in scope and not session.solarsystemid: 441 scopeWarningList.append(GetByLabel('UI/HelpPointers/Wnd/ScopeInSpace')) 442 if 'PlayerCorp' in scope and IsNPCCorporation(session.corpid): 443 scopeWarningList.append(GetByLabel('UI/HelpPointers/Wnd/ScopeInPlayerCorp')) 444 return scopeWarningList 445 446 def GetNameElements(self, pointerName): 447 nameElements = pointerName.split('.') 448 return nameElements 449 450 def GetSubText(self, pointerName, pointToElement, extraLines, chainElements): 451 extraTextList = [] 452 for x in extraLines or (): 453 extraTextList.append(TextAndTexture(x, indentChar='')) 454 455 extraTextList += self.FindSubTextAndIconForNeocomPointer(pointerName, pointToElement) 456 for eachPointerName in chainElements: 457 if eachPointerName in self.highlight_by_element_name: 458 element = self.highlight_by_element_name[eachPointerName] 459 extraTextList.append(TextAndTexture(element.label, element.texturePath, element.iconSizes, iconData=element.iconData)) 460 else: 461 textPath = self.FindSubTextAndIconForNeocomPointer(eachPointerName, pointToElement) 462 if textPath: 463 extraTextList = textPath + extraTextList 464 else: 465 pointerObject = self.all_pointers_by_element_name.get(eachPointerName, None) 466 pointerText = pointerObject.label if pointerObject else '' 467 extraTextList.append(TextAndTexture(pointerText, pointerObject.texturePath, pointerObject.iconSizes, iconData=pointerObject.iconData)) 468 469 return extraTextList 470 471 def FindSubTextAndIconForNeocomPointer(self, pointerName, pointToElement): 472 if not isinstance(pointToElement, ButtonEveMenu) or not pointerName.startswith('neocom.'): 473 return [] 474 nameElements = self.GetNameElements(pointerName) 475 wndID = nameElements[1] 476 actualBtn = pointToElement.btnData.GetBtnDataByTypeAndID(wndID, recursive=True) 477 if actualBtn and getattr(actualBtn, 'parent', None): 478 label = getattr(actualBtn.parent, 'label', None) 479 if label: 480 iconPath = getattr(actualBtn.parent, 'iconPath', None) 481 pathList = [TextAndTexture(GetByLabel('UI/Help/PointerWndNeocomHeader'), NEOCOM_E_ICON), TextAndTexture(label, iconPath), TextAndTexture(actualBtn.label, actualBtn.iconPath)] 482 return pathList 483 return [] 484 485 def _ShowPointerThread(self, pointerName, uiPointerTextAndTexture, subTextLines, displayTime, defaultDirection = None, finalPointer = True): 486 offset = self.GetOffset(pointerName) 487 highlightingSvc = sm.GetService('uiHighlightingService') 488 if finalPointer: 489 fadeoutTime = displayTime 490 else: 491 fadeoutTime = 0.75 492 iconSize = 24 493 maxTextWidth = 0 494 if uiPointerTextAndTexture: 495 maxTextWidth = uiPointerTextAndTexture.GetMaxWidth(0, iconSize) 496 if subTextLines: 497 maxSubLines = max((x.GetMaxWidth(i, iconSize) for i, x in enumerate(subTextLines))) 498 maxTextWidth = max(maxTextWidth, maxSubLines) 499 maxTextWidth += 2 * CONTENT_CONTAINER_PADDING 500 defaultPointerWidth = UIPOINTER_WIDTH - 2 * CONTENT_CONTAINER_PADDING 501 pointerWidth = mathext.clamp(maxTextWidth, defaultPointerWidth, 2 * UIPOINTER_WIDTH - 2 * CONTENT_CONTAINER_PADDING) 502 highlight_content = PointerContainerWithPath(align=uiconst.TOLEFT, name='textContainer', width=pointerWidth, height=0, titleAndIcon=uiPointerTextAndTexture, textAndIconObjects=subTextLines, iconSize=iconSize) 503 highlightingSvc.custom_highlight_ui_element_by_name(ui_element_name=pointerName, offset=offset, highlight_content=highlight_content, fadeout_seconds=fadeoutTime, allowOffscreenPointing=True, default_direction=defaultDirection, idx=0) 504 505 def ShowPendingPointersThread(self): 506 pointersFound = False 507 try: 508 for pointerName in self.pendingPointers.iterkeys(): 509 if self.pendingPointers.get(pointerName, False): 510 pointersFound = True 511 self._ActivateHelperPointer(pointerName, isFirstCall=False) 512 513 if not pointersFound: 514 self.pendingThread = None 515 except Exception: 516 self.pendingPointers.clear() 517 self.pendingThread = None 518 raise 519 520 def SearchPointers(self, searchStr): 521 filteredNodes = GetFilteredNodes(searchStr, sourceLocation=pConst.SOURCE_LOCATION_SEARCH) 522 if filteredNodes: 523 from eve.client.script.ui.control.entries.util import GetFromClass 524 from eve.client.script.ui.control.listgroup import ListGroup 525 from eve.client.script.ui.util.searchUtil import GetScrollListGroup 526 data = GetScrollListGroup(filteredNodes, PointerWndEntry, GetByLabel('UI/Help/PointerWndUiElementsSearch'), 'uiPointers') 527 return ([GetFromClass(ListGroup, data)], len(filteredNodes)) 528 return ([], 0) 529 530 def FindLocalChatWindow(self, uniqueUiName): 531 return self._FindChatWnd('chatchannel_local', uniqueUiName) 532 533 def FindCorpChatWindow(self, uniqueUiName): 534 return self._FindChatWnd('chatchannel_corp', uniqueUiName) 535 536 def FindFleetChatWindow(self, uniqueUiName): 537 return self._FindChatWnd('chatchannel_fleet', uniqueUiName) 538 539 def _FindChatWnd(self, windowID, uniqueUiName): 540 from chat.client.window import BaseChatWindow 541 wnd = BaseChatWindow.GetIfOpen(windowID=windowID) 542 if wnd and not wnd.destroyed: 543 wnd.uniqueUiName = uniqueUiName 544 if hasattr(wnd, 'InStack') and wnd.InStack(): 545 return wnd.sr.tab 546 return wnd 547 548 @eveexceptions.EatsExceptions('protoClientLogs') 549 def LogPointerCreated(self, pointerUniqueName, sourceLocation): 550 message_bus = HelpPointerMessenger(sm.GetService('publicGatewaySvc')) 551 message_bus.pointer_created(pointerUniqueName, sourceLocation) 552 553 @eveexceptions.EatsExceptions('protoClientLogs') 554 def LogPointerLinkCreated(self, pointerUniqueName): 555 message_bus = HelpPointerMessenger(sm.GetService('publicGatewaySvc')) 556 message_bus.link_created(pointerUniqueName) 557 558 def FindTagToIgnore(self, text): 559 if text.find(SCHEME_HELP_POINTER) < 0: 560 return [] 561 matches = re.findall(POINTER_TAG_PATTERN, text) 562 tagsToIgnore = [] 563 for eachMatch in matches: 564 pointerName = eachMatch.replace('<%s' % urlText, '') 565 if pointerName.endswith(POINTER_URL_END): 566 pointerName = pointerName.rstrip(POINTER_URL_END) 567 if self._IsValidPointerName(pointerName): 568 tag = '%s%s"' % (urlText, pointerName) 569 tagsToIgnore.append(tag) 570 571 if tagsToIgnore: 572 tagsToIgnore.append('/a') 573 return tagsToIgnore 574 575 def _IsValidPointerName(self, pointerName): 576 if pointerName in self.highlight_by_element_name: 577 return True 578 if pointerName in self.all_pointers_by_element_name: 579 return True 580 if pointerName.startswith(pConst.NEOCOM_PREFIX): 581 neocomID = pointerName.replace(pConst.NEOCOM_PREFIX, '') 582 btnData = BTNDATARAW_BY_ID.get(neocomID) 583 if btnData and btnData.cmdName is not None: 584 return True 585 return False 586 587 def IsUtilMenuEntryHighlighted(self, uniqueUiName): 588 return uniqueUiName in self.utilMenuHighlights 589 590 def AddUniqueNameToUtilMenuHighlights(self, uniqueUiName): 591 self.utilMenuHighlights[uniqueUiName] = True 592 593 def GetPointerOverlay(self, create = False): 594 if self.pointerOverlay is None and create: 595 self.pointerOverlay = PointerOverlay() 596 return self.pointerOverlay 597 598 def HidePointerOverlay(self): 599 self.LogInfo('cmd:UI Pointer overlay: unload callback called') 600 pointerHelper = self.GetPointerOverlay() 601 if pointerHelper: 602 self.LogInfo('cmd:UI Pointer overlay: hide overlay 1') 603 pointerHelper.HideOverlay() 604 self.LogInfo('cmd:Pointer overlay: hide overlay 2')