class DebugMapBrowser(Window): default_windowID = 'DebugMapBrowser' default_caption = 'Map Debug View' autoLoadTimer = None loadedObjectID = None currentMap = None clipRect = None def ApplyAttributes(self, attributes): Window.ApplyAttributes(self, attributes) self.SetTopparentHeight(0) uthread.new(self.LoadOptions) def LoadOptions(self): PrimeMapData() self.objectIDs = sorted(uicore.mapObjectDataByID.keys()) main = self.GetMainArea() main.clipChildren = True main.padding = 6 lg = LayoutGrid(parent=main, columns=3, cellPadding=2, align=uiconst.TOTOP) self.objectLabel = EveLabelLarge(bold=True) lg.AddCell(self.objectLabel, colSpan=lg.columns - 1) self.inputEdit = SinglelineEdit(OnReturn=self.OnInputConfirm, align=uiconst.TOPRIGHT) self.inputEdit.SetHistoryVisibility(True) lg.AddCell(self.inputEdit, colSpan=1) b = Button(func=self.BrowsePrev, label='Previous') lg.AddCell(b, colSpan=2) Button(parent=lg, func=self.BrowseNext, label='Next', align=uiconst.TOPRIGHT) lg.FillRow() lg.AddCell(Line(align=uiconst.TOTOP), colSpan=lg.columns, cellPadding=(0, 4, 0, 4)) b = Button(func=self.BrowseNextLoop, label='Browse next loop', fixedwidth=240) lg.AddCell(b, colSpan=lg.columns) self.browseLoopButton = b settings.user.ui.Set('mapDebugViewRefreshLayout', 0) c = Checkbox(configName='mapDebugViewRefreshLayout', text='Refresh layouts', align=uiconst.TOPLEFT, checked=settings.user.ui.Get('mapDebugViewRefreshLayout', 0), wrapLabel=False, callback=self.OnCheckBoxChange) lg.AddCell(c, colSpan=lg.columns) c = Checkbox(configName='mapDebugViewStopOnErrors', text='Stop on error', align=uiconst.TOPLEFT, checked=settings.user.ui.Get('mapDebugViewStopOnErrors', 0), wrapLabel=False, callback=self.OnCheckBoxChange) lg.AddCell(c, colSpan=lg.columns) c = Checkbox(configName='mapDebugViewIgnoreFixed', text='Ignore fixed layouts', align=uiconst.TOPLEFT, checked=settings.user.ui.Get('mapDebugViewIgnoreFixed', 0), wrapLabel=False, callback=self.OnCheckBoxChange) lg.AddCell(c, colSpan=lg.columns) c = Checkbox(configName='mapDebugViewEditEnabled', text='Editmode enabled', align=uiconst.TOPLEFT, checked=settings.user.ui.Get('mapDebugViewEditEnabled', 0), wrapLabel=False, callback=self.OnCheckBoxChange) lg.AddCell(c, colSpan=lg.columns) c = Checkbox(configName='mapDebugSubdivision', text='Show Grid Subdivision', align=uiconst.TOPLEFT, checked=settings.user.ui.Get('mapDebugSubdivision', 0), wrapLabel=False, callback=self.OnCheckBoxChange) lg.AddCell(c, colSpan=lg.columns) c = Checkbox(configName='mapLoadCombined', text='Load Combined', align=uiconst.TOPLEFT, checked=settings.user.ui.Get('mapLoadCombined', 0), wrapLabel=False, callback=self.OnCheckBoxChange) lg.AddCell(c, colSpan=lg.columns) c = Checkbox(configName='mapDebugShowIDs', text='Show IDs', align=uiconst.TOPLEFT, checked=settings.user.ui.Get('mapDebugShowIDs', 0), wrapLabel=False, callback=self.OnCheckBoxChange) lg.AddCell(c, colSpan=lg.columns) c = Checkbox(configName='mapDebugLoadHexLines', text='Load Hex Lines', align=uiconst.TOPLEFT, checked=settings.user.ui.Get('mapDebugLoadHexLines', 0), wrapLabel=False, callback=self.OnCheckBoxChange) lg.AddCell(c, colSpan=lg.columns) c = Checkbox(configName='mapDebugShowExitPoints', text='Show Exit Points', align=uiconst.TOPLEFT, checked=settings.user.ui.Get('mapDebugShowExitPoints', 0), wrapLabel=False, callback=self.OnCheckBoxChange) lg.AddCell(c, colSpan=lg.columns) lg.FillRow() lg.AddCell(Line(align=uiconst.TOTOP), colSpan=lg.columns, cellPadding=(0, 4, 0, 4)) b = Button(func=self.ScanCurrent, label='Scan Current', fixedwidth=240) lg.AddCell(b, colSpan=lg.columns) b = Button(func=self.AutoFitSize, label='Auto Fit', fixedwidth=240) lg.AddCell(b, colSpan=lg.columns) self.statsLabel = EveLabelMedium(parent=lg) lg.FillRow() self.clipRect = Container(parent=uicore.layer.main, align=uiconst.CENTER, width=800, height=600, clipChildren=True) Frame(bgParent=self.clipRect) Fill(bgParent=self.clipRect, color=(0, 0, 0, 1)) self.LoadObjectID(loadObjectID=10000001) def Close(self, *args, **kwds): Window.Close(self, *args, **kwds) if self.currentMap and not self.currentMap.destroyed: self.currentMap.Close() self.currentMap = None if self.clipRect: self.clipRect.Close() self.clipRect = None def OnCheckBoxChange(self, *args, **kwds): if self.loadedObjectID: uthread.new(self.LoadObjectID, self.loadedObjectID) def LoadObjectID(self, loadObjectID, *args, **kwds): self.loadedObjectID = loadObjectID self.objectLabel.text = '%s %s/%s' % ( loadObjectID, self.objectIDs.index(loadObjectID) + 1, len(self.objectIDs)) if getattr(self, 'currentMap', None): self.currentMap.Close() inEditMode = settings.user.ui.Get('mapDebugViewEditEnabled', 0) from eve.client.script.ui.shared.mapView.hexagonal.hexMap import HexMap self.currentMap = HexMap(parent=self.clipRect, state=uiconst.UI_NORMAL, editMode=inEditMode) stopOnErrors = settings.user.ui.Get('mapDebugViewStopOnErrors', 0) ignoreFixed = settings.user.ui.Get('mapDebugViewIgnoreFixed', 0) refreshLayout = settings.user.ui.Get('mapDebugViewRefreshLayout', 0) if refreshLayout: refreshLayout = loadObjectID != const.locationUniverse if refreshLayout: resolved = PlotMapObjects(self.currentMap, loadObjectID) if not resolved and stopOnErrors: self.autoLoadTimer = None else: self.currentMap.LoadMapData(loadObjectID, ignoreFixedLayout=ignoreFixed) if loadObjectID > 9 and not settings.user.ui.Get( 'mapLoadCombined', 0): ol, ll, penalty = ScanAllOverlap(self.currentMap) if penalty: print 'Loaded', loadObjectID, 'penalty', penalty if stopOnErrors: self.autoLoadTimer = None def BrowsePrev(self, *args, **kwds): self.autoLoadTimer = None if self.loadedObjectID: ctrl = uicore.uilib.Key(uiconst.VK_CONTROL) if ctrl: i = 1 else: i = self.objectIDs.index(self.loadedObjectID) self.LoadObjectID(self.objectIDs[max(0, i - 1)]) def BrowseNext(self, *args, **kwds): if self.destroyed: self.autoLoadTimer = None return if self.loadedObjectID: i = self.objectIDs.index(self.loadedObjectID) if i + 1 < len(self.objectIDs): self.LoadObjectID(self.objectIDs[i + 1]) return True def AutoFitSize(self, *args): self._AutoFitSize(self, *args) def _AutoFitSize(self, *args): print 'meee' hexMap = self.currentMap layout = hexMap.GetCurrentLayout() newlayout, size = AutoFitLayout(layout) for objectID, column_row in newlayout.iteritems(): hexCell = hexMap.objectByID[objectID] hexCell.MoveToCR(*column_row) hexMap.UpdateJumpLines() hexMap.SetMapSize(size) def ScanCurrent(self, *args): self._ScanCurrent(*args) def _ScanCurrent(self, *args): if self.currentMap: ol, ll, penalty = ScanAllOverlap(self.currentMap) print penalty def MakePattern(self, *args): pass def BrowseNextLoop(self, *args): if self.autoLoadTimer: self.browseLoopButton.SetLabel('Browse next loop') self.autoLoadTimer = None else: self.browseLoopButton.SetLabel('Stop') self.autoLoadTimer = AutoTimer(1, self.AutoBrowse) def AutoBrowse(self): stillLoading = self.BrowseNext() if not stillLoading: self.autoLoadTimer = None def OnInputConfirm(self, *args, **kwds): try: toInt = int(self.inputEdit.GetValue()) if toInt in self.objectIDs: self.LoadObjectID(toInt) except: pass
class AurumStoreContainer(Container): default_name = 'AurumStoreContainer' default_state = uiconst.UI_NORMAL def ApplyAttributes(self, attributes): Container.ApplyAttributes(self, attributes) self.store = sm.GetService('vgsService').GetStore() self.tagsByCategoryId = {} self.selectedRootCategoryId = None self.selectedCategoryId = None self.activeTagsByRootCategoryId = {} self.page = None Fill(bgParent=self, color=BACKGROUND_COLOR) self.CreateRedeemingPanelLayout() self.CreateBaseLayout() self.CreateHeaderLayout() self.CreateContentLayout() self.SetFilterOptions() self.currentAurBalance = 0 self._OnResize() def _OnResize(self, *args): top, left, width, height = self.GetAbsolute() contentWidth = min(MAX_CONTENT_WIDTH, width) self.leftContainer.width = (width - contentWidth) / 2 self.contentContainer.width = contentWidth self.rightContainer.width = width - self.leftContainer.width - contentWidth self.redeemingPanel.width = width if hasattr(self, 'grid'): self.grid.SetParentWidth(self.contentContainer.width) self.SetSidebarContentMask() def CreateHeaderLayout(self): contentContainer = Container(parent=self.headerContainer, align=uiconst.TOTOP, height=CAPTION_HEIGHT, top=CAPTION_OFFSET) LogoHomeButton(parent=self.headerContainer, align=uiconst.TOPLEFT, onClick=self.OnClickHomeButton) ExitButton( parent=self.headerContainer, align=uiconst.TOPRIGHT, onClick=uicore.cmd.ToggleAurumStore, top=4, left=10, hint=localization.GetByLabel('UI/VirtualGoodsStore/ExitStore')) self.aurButton = HeaderBuyAurButton(parent=contentContainer, align=uiconst.TORIGHT, onClick=self._BuyAurum, padding=(4, 0, 4, 0), left=6) cont = Container(name='AurContainer', parent=contentContainer, align=uiconst.TORIGHT, width=200, padRight=8) self.aurLabel = AurLabelHeader(parent=cont, align=uiconst.CENTERRIGHT, height=32, amount=100, padTop=1) def _BuyAurum(self): sm.GetService('audio').SendUIEvent('store_aur') sm.GetService('viewState').GetView( ViewState.VirtualGoodsStore)._LogBuyAurum('TopButton') uicore.cmd.BuyAurumOnline() def SetSidebarContentMask(self): for container in (self.leftContainer, self.rightContainer): container.Flush() GradientSprite(name='OfferSlipGradient', align=uiconst.TOTOP, parent=container, rgbData=((0.0, BACKGROUND_COLOR[:3]), ), alphaData=((0.0, CONTENT_SLIP_UNDER_AREA_OPACITY), (0.5, 1.0), (1.0, 1.0)), height=self.topContainer.height + self.filterContainer.height + HEADER_PADDING, rotation=math.pi / 2) def CreateBaseLayout(self): wholeWidthContainer = Container(parent=self, name='WholeWindowContainer', align=uiconst.TOALL) self.leftContainer = Container(parent=wholeWidthContainer, name='LeftSideBar', align=uiconst.TOLEFT) self.rightContainer = Container(parent=wholeWidthContainer, name='RightSideBar', align=uiconst.TORIGHT) self.contentContainer = Container(parent=wholeWidthContainer, name='Content', align=uiconst.TOLEFT) self.topContainer = ContainerAutoSize(name='Top Container', parent=self.contentContainer, align=uiconst.TOTOP) Fill(name='SlipUnderLayer', bgParent=self.topContainer, color=BACKGROUND_COLOR) self.headerContainer = Container(parent=self.topContainer, name='Header', align=uiconst.TOTOP, bgColor=HEADER_BG_COLOR, height=HEADER_HEIGHT, clipChildren=True) self.categoryContainer = Container(parent=self.topContainer, name='Categories', align=uiconst.TOTOP, height=CATEGORIES_HEIGHT, padTop=HEADER_PADDING, state=uiconst.UI_PICKCHILDREN) self.subCategoryContainer = Container(name='SubCategories', parent=self.topContainer, align=uiconst.TOTOP, padTop=HEADER_PADDING, bgColor=TAG_COLOR, state=uiconst.UI_PICKCHILDREN, clipChildren=True) self.subCategoryButtonContainer = FlowContainer( name='SubCategoryButtons', parent=self.subCategoryContainer, centerContent=True, align=uiconst.TOTOP, contentSpacing=(1, 0), state=uiconst.UI_PICKCHILDREN) self.filterContainer = Container(name='Filter', parent=self.contentContainer, align=uiconst.TOTOP, padTop=HEADER_PADDING, state=uiconst.UI_PICKCHILDREN, height=CATEGORIES_HEIGHT) def CreateContentLayout(self): self.contentScroll = OfferScrollContainer(parent=self.contentContainer, align=uiconst.TOALL) self.banner = BannerReel(parent=self.contentScroll, align=uiconst.TOTOP, bannerWidth=MAX_CONTENT_WIDTH, bannerHeight=AD_HEIGHT) self.grid = OfferGrid(parent=self.contentScroll, align=uiconst.TOTOP, contentSpacing=(CONTENT_PADDING, CONTENT_PADDING), padBottom=CONTENT_PADDING, columns=OFFER_COLUMNS, incrementSize=OFFER_COLUMNS) for x in xrange(4 * OFFER_COLUMNS): offer = VgsOffer(parent=self.grid, width=MAX_OFFER_IMAGE_SIZE, height=MAX_OFFER_IMAGE_SIZE, align=uiconst.NOALIGN) self.contentScroll.RegisterContentLoader(self.grid) def CreateRedeemingPanelLayout(self): instructionText = '<url=localsvc:service=vgsService&method=ShowRedeemUI>%s</url>' % ( localization.GetByLabel( 'UI/RedeemWindow/ClickToInitiateRedeeming'), ) self.redeemingPanel = RedeemPanel( parent=self, align=uiconst.TOBOTTOM, dragEnabled=False, instructionText=instructionText, redeemButtonBackgroundColor=REDEEM_BUTTON_BACKGROUND_COLOR, redeemButtonFillColor=REDEEM_BUTTON_FILL_COLOR) self.redeemingPanel.UpdateDisplay() def SelectCategory(self, categoryId): self.selectedRootCategoryId = categoryId for button in self.categoryButtons: if button.isActive and button.categoryId != categoryId: button.SetActive(False) def SelectSubCategory(self, subcategoryId): self.selectedCategoryId = subcategoryId for button in self.subcategoryButtons: if button.isActive and button.categoryId != subcategoryId: button.SetActive(False) def OnClickCategory(self, categoryId): self.LoadCategoryPage(categoryId) @RunThreadOnce(THREAD_KEY_LOAD_PAGE) def LoadCategoryPage(self, categoryId): if self.page == PAGE_CATEGORY and self.selectedRootCategoryId == categoryId and self.selectedCategoryId is None: return logger.debug('Loading category page: %s', categoryId) self.SelectCategory(categoryId) categoriesById = self.store.GetCategories() category = categoriesById[categoryId] subcategories = [ categoriesById[subCatId] for subCatId in category.subcategories ] subcategories = localization.util.Sort(subcategories, key=lambda c: c.name) self.SetSubCategories(subcategories) self.SelectSubCategory(None) self.SetOffersAndTags(categoryId) self.page = PAGE_CATEGORY def OnClickSubCategory(self, subcategoryId): self.LoadSubCategoryPage(subcategoryId) @RunThreadOnce(THREAD_KEY_LOAD_PAGE) def LoadSubCategoryPage(self, subcategoryId): if self.page == PAGE_SUBCATEGORY and self.selectedCategoryId == subcategoryId: return logger.debug('Loading sub category page: %s', subcategoryId) self.selectedCategoryId = subcategoryId self.SetOffersAndTags(subcategoryId) self.SelectSubCategory(subcategoryId) self.page = PAGE_SUBCATEGORY def SetOffersAndTags(self, categoryId): tags = self.store.GetTagsByCategoryId(categoryId) self.SetFilterTags(tags) tagIds = self.filterBar.GetSelectedFilterTagIds() offers = self.store.GetFilteredOffers(categoryId, tagIds) self.HideBanner() self.SetOffers(offers) @RunThreadOnce(THREAD_KEY_LOAD_PAGE) def OnClickHomeButton(self): self.LoadLandingPage() def LoadLandingPage(self): logger.debug('LoadLandingPage') if self.page == PAGE_HOME: return logger.debug('Loading landing page') self._SetSubCategories(None) self.SelectCategory(None) self.SelectSubCategory(None) self.SetFilterTags([]) self.ShowBanner() offers = self.store.GetOffers().values() self.SetOffers(offers) self.page = PAGE_HOME @RunThreadOnce('VGS.ShowBanner') def ShowBanner(self): if self.banner.HasBanners() and not self.banner.display: self.banner.top = 0 self.banner.display = True self.SetSubCategories(None) uicore.animations.MoveInFromTop(self.banner, amount=self.banner.height, sleep=True) @RunThreadOnce('VGS.HideBanner') def HideBanner(self): uicore.animations.MoveOutTop(self.banner, amount=self.banner.height, sleep=True) self.banner.top = 0 self.banner.display = False @postponeUntilFocus def SetAUR(self, amount): logger.debug('SetAUR %s', amount) uicore.animations.MorphScalar( self, 'currentAurBalance', startVal=self.currentAurBalance, endVal=amount, curveType=uiconst.ANIM_SMOOTH, duration=1.5, callback=lambda: self.SetCurrentAurBalance(amount)) def SetCurrentAurBalance(self, amount): self._currentAurBalance = amount self.aurLabel.SetAmount(self._currentAurBalance) def GetCurrentAurBalance(self): return self._currentAurBalance currentAurBalance = property(GetCurrentAurBalance, SetCurrentAurBalance) def SetCategories(self, categories): logger.debug('SetCategories %s', categories) self.categoryContainer.Flush() searchContainer = Container(name='SearchBox', parent=self.categoryContainer, width=SEARCH_BOX_WIDTH, align=uiconst.TORIGHT) categoryButtonsContainer = GridContainer(name='ButtonGrid', parent=self.categoryContainer, align=uiconst.TOALL, columns=len(categories), lines=1) tagById = self.store.GetTags() self.categoryButtons = [] for category in categories: button = CategoryButton(parent=categoryButtonsContainer, categoryId=category.id, label=category.name, align=uiconst.TOALL, onClick=self.OnClickCategory, padRight=1) self.categoryButtons.append(button) tags = [] for tagId in category.tagIds: tag = tagById.get(tagId) if tag: tags.append(Tag(tag.id, tag.name)) self.tagsByCategoryId[category.id] = tags iconContainer = Container(name='SearchIconContainer', parent=searchContainer, width=CATEGORIES_HEIGHT, align=uiconst.TOLEFT, bgColor=CATEGORY_COLOR) Sprite(parent=iconContainer, texturePath='res:/UI/Texture/Vgs/Search_icon.png', width=32, height=32, align=uiconst.CENTER) self.searchEdit = SinglelineEdit(parent=searchContainer, align=uiconst.TORIGHT, pos=(0, 0, SEARCH_BOX_WIDTH - CATEGORIES_HEIGHT - 2, 0), fontsize=16, padding=(1, 0, 0, 0), OnChange=self.Search, bgColor=TAG_COLOR) self.searchEdit.ShowClearButton( icon='res:/UI/Texture/Icons/73_16_45.png') self.searchEdit.SetHistoryVisibility(False) self.searchEdit.sr.background.Hide() @RunThreadOnce(THREAD_KEY_LOAD_PAGE) def Search(self, searchString): self.page = PAGE_SEARCH self.HideBanner() self.SelectSubCategory(None) self.SelectCategory(None) self._SetSubCategories(None) self.SetFilterTags([]) sm.GetService('viewState').GetView( ViewState.VirtualGoodsStore).Search(searchString) @RunThreadOnce('VGS.SetSubCategories') def SetSubCategories(self, subcategories): self._SetSubCategories(subcategories) def _SetSubCategories(self, subcategories): self.subCategoryButtonContainer.Flush() self.subcategoryButtons = [] if subcategories is None: if self.subCategoryContainer.height > 0: uicore.animations.MorphScalar( self.subCategoryContainer, attrName='height', startVal=self.subCategoryContainer.height, endVal=0, duration=0.5, callback=self.SetSidebarContentMask) else: if int(self.subCategoryContainer.height) != CATEGORIES_HEIGHT: uicore.animations.MorphScalar( self.subCategoryContainer, attrName='height', startVal=self.subCategoryContainer.height, endVal=CATEGORIES_HEIGHT, duration=0.5, sleep=False, callback=self.SetSidebarContentMask) for subcategory in subcategories: button = SubCategoryButton( parent=self.subCategoryButtonContainer, label=subcategory.name, align=uiconst.NOALIGN, height=CATEGORIES_HEIGHT, categoryId=subcategory.id, onClick=self.OnClickSubCategory) self.subcategoryButtons.append(button) def SetOffers(self, offers): if self.selectedCategoryId is None and self.selectedRootCategoryId is None: specialOffers = [o for o in offers if o.label is not None] notSpecialOffers = [o for o in offers if o.label is None] offers = SortOffers(specialOffers) offers.extend(SortOffers(notSpecialOffers)) else: offers = SortOffers(offers) self.grid.SetOffers(offers) def SetFilterOptions(self): self.filterContainer.Flush() Fill(name='SlipUnderLayer', bgParent=self.filterContainer, color=BACKGROUND_COLOR, opacity=CONTENT_SLIP_UNDER_AREA_OPACITY, padTop=-HEADER_PADDING * 2) options = [(localization.GetByLabel( 'UI/VirtualGoodsStore/Sorting/ByPriceAscending'), SORT_PRICE_ASCENDING), (localization.GetByLabel( 'UI/VirtualGoodsStore/Sorting/ByPriceDescending'), SORT_PRICE_DESCENDING), (localization.GetByLabel( 'UI/VirtualGoodsStore/Sorting/ByNameAscending'), SORT_NAME_ASCENDING), (localization.GetByLabel( 'UI/VirtualGoodsStore/Sorting/ByNameDescending'), SORT_NAME_DESCENDING)] self.filterCombo = VgsFilterCombo(parent=self.filterContainer, align=uiconst.TORIGHT, options=options, callback=self.OnSortOrderChanged, select=GetSortOrder(), padding=(4, 2, 0, 4)) self.filterBar = VgsOfferFilterBar( parent=self.filterContainer, onFilterChanged=self.OnFilterChanged) def SetFilterTags(self, tags): activeTags = self.activeTagsByRootCategoryId.get( self.GetSelectedRootCategoryId(), {}) self.subCategoryContainer.state = uiconst.UI_PICKCHILDREN self.filterBar.SetTags(tags, activeTags) def OnSortOrderChanged(self, combo, key, value): settings.user.ui.Set('VgsOfferSortOrder', value) sm.GetService('viewState').GetView( ViewState.VirtualGoodsStore)._LogFilterChange(value) self.SetOffers(self.grid.GetOffers()) def OnFilterChanged(self): tagIds = self.filterBar.GetSelectedFilterTagIds() rootCategoryId = self.GetSelectedRootCategoryId() self.activeTagsByRootCategoryId[rootCategoryId] = tagIds offers = self.store.GetFilteredOffers( self.selectedCategoryId or rootCategoryId, tagIds) self.SetOffers(offers) def GetSelectedCategoryId(self): return self.selectedCategoryId def GetSelectedRootCategoryId(self): return self.selectedRootCategoryId def OnMouseWheel(self, dz): self.contentScroll.OnMouseWheel(dz)
class UITree(Window): default_windowID = 'uitree' default_caption = 'UI Roots' default_width = 300 default_height = 400 default_minSize = (default_width, default_height) default_left = '__center__' default_top = '__center__' filterString = None def ApplyAttributes(self, attributes): Window.ApplyAttributes(self, attributes) mainArea = self.GetMainArea() mainArea.padding = 6 self._selectedObject = None self.SetTopparentHeight(0) self._infoContainer = Container(parent=mainArea, align=uiconst.TOTOP, height=72) self.searchInput = SinglelineEdit(parent=self._infoContainer, align=uiconst.BOTTOMRIGHT, left=4, top=8, width=100, OnChange=self.OnSearchInputChange, hinttext='Search') self.searchInput.SetHistoryVisibility(False) self.searchInput.ShowClearButton() m = UtilMenu(menuAlign=uiconst.TOPRIGHT, parent=self._infoContainer, align=uiconst.TOPRIGHT, GetUtilMenu=self.SettingMenu) self._infoLabel = Label(parent=self._infoContainer, state=uiconst.UI_DISABLED, color=(1.0, 1.0, 1.0, 0.75), left=2) self.searchResultParent = ContainerAutoSize(parent=mainArea, align=uiconst.TOTOP_NOPUSH, padding=(26, -6, 4, 0), bgColor=(0.5, 0.5, 0.5, 1)) self.attributeScroll = Scroll(parent=mainArea, align=uiconst.TOBOTTOM, name='attributeScroll') self.attributeScroll.height = min( self.height / 2, max(72, settings.user.ui.Get('uitree_attributeScroll_height', 200))) settings.user.ui.Set('uitree_attributeScroll_height', self.attributeScroll.height) self.divider = Divider(align=uiconst.TOBOTTOM, parent=mainArea, height=11, state=uiconst.UI_NORMAL) self.divider.OnChange_ = self.OnDividerMove self.divider.OnChangeStart_ = self.OnDividerMoveStart Fill(parent=self.divider, align=uiconst.CENTER, pos=(0, 0, 20, 1)) self.scroll = Scroll(parent=mainArea, name='treeScroll') self._hiliteFrame = Fill(parent=uicore.desktop, align=uiconst.ABSOLUTE, color=(0, 1, 0, 0.3), idx=0, state=uiconst.UI_DISABLED) self._selectedFrame = Frame(parent=uicore.desktop, align=uiconst.ABSOLUTE, color=(0, 1, 0, 0.3), idx=0, state=uiconst.UI_DISABLED) self.ReloadUIRoots() uthread.new(self.UpdateInfo) self._keyDownCookie = uicore.uilib.RegisterForTriuiEvents( [uiconst.UI_KEYDOWN], self.OnGlobalKeyDown) def OnSearchInputChange(self, *args): self.searchThread = base.AutoTimer(250, self.SearchTree) def SearchTree(self): self.searchThread = None self.filterString = self.searchInput.GetValue() if not self.filterString: self.searchResultParent.Hide() self.searchResultParent.Flush() return self.searchResultParent.Flush() res = [] searchFor = self.filterString.lower() def Crawl(obj, path): if obj is self: return if searchFor in obj.name.lower(): if path: res.append((obj, path + '/ <b>' + obj.name + '</b>')) else: res.append((obj, '<b>' + obj.name + '</b>')) if hasattr(obj, 'children'): for each in obj.children: if path: Crawl(each, path + '/' + obj.name) else: Crawl(each, obj.name) for root in uicore.uilib.rootObjects: Crawl(root, '') if res: for obj, path in res[:20]: label = Label(parent=self.searchResultParent, align=uiconst.TOTOP, text=path, state=uiconst.UI_NORMAL, padding=(10, 2, 10, 2)) label._searchObj = obj label.hint = path label.OnClick = (self.OnSearchResultClick, obj) if len(res) > 20: Label(parent=self.searchResultParent, align=uiconst.TOTOP, text='and even more... (%s found)' % len(res), padding=(10, 2, 10, 2)) else: Label(parent=self.searchResultParent, align=uiconst.TOTOP, text='No Match!', padding=(10, 3, 10, 3)) self.searchResultParent.Show() def OnSearchResultClick(self, obj): self.searchResultParent.Hide() self.ShowUIObject(obj) def _OnSizeChange_NoBlock(self, *args, **kwds): Window._OnSizeChange_NoBlock(self, *args, **kwds) self.attributeScroll.height = min( self.height / 2, max(72, settings.user.ui.Get('uitree_attributeScroll_height', 200))) settings.user.ui.Set('uitree_attributeScroll_height', self.attributeScroll.height) def OnDividerMove(self, divider, dx, dy): self.attributeScroll.height = min( self.height / 2, max(72, self._initAttributeScrollHeight - dy)) settings.user.ui.Set('uitree_attributeScroll_height', self.attributeScroll.height) def OnDividerMoveStart(self, *args): self._initAttributeScrollHeight = self.attributeScroll.height def SettingMenu(self, menuParent, *args): checked = settings.user.ui.Get('uitreeShowPickHilite', True) menuParent.AddCheckBox(text='Show pick hilite', checked=checked, callback=(self.ToggleCheckboxSetting, 'ShowPickHilite')) checked = settings.user.ui.Get('uitreeIgnoreFullScreenPick', False) menuParent.AddCheckBox(text='Ignore fullscreen hilite', checked=checked, callback=(self.ToggleCheckboxSetting, 'IgnoreFullScreenPick')) menuParent.AddIconEntry(icon=None, text='Move To Desktop', callback=self.MoveToDesktop) menuParent.AddIconEntry(icon=None, text='Reload Textures', callback=self.ReloadTextures) def ReloadTextures(self): import blue for resPath in blue.motherLode.GetNonCachedKeys( ) + blue.motherLode.GetCachedKeys(): if resPath.lower().startswith('res:/ui'): res = blue.motherLode.Lookup(resPath) if res: if hasattr(res, 'Reload'): res.Reload() def MoveToDesktop(self): self.SetParent(uicore.desktop, idx=0) def ToggleCheckboxSetting(self, settingName, *args): checked = settings.user.ui.Get('uitree' + settingName, True) settings.user.ui.Set('uitree' + settingName, not checked) def Close(self, *args, **kwds): frame = getattr(self, '_hiliteFrame', None) if frame: frame.Close() if getattr(self, '_selectedFrame', None): self._selectedFrame.Close() Window.Close(self, *args, **kwds) def OnGlobalKeyDown(self, *args, **kwds): if self.destroyed: return False ctrl = uicore.uilib.Key(uiconst.VK_CONTROL) alt = uicore.uilib.Key(uiconst.VK_MENU) if ctrl and not (IsUnder(uicore.uilib.mouseOver, self) or uicore.uilib.mouseOver is self): self.ShowUIObject(uicore.uilib.mouseOver) return True def UpdateInfo(self): while not self.destroyed: mo = uicore.uilib.mouseOver if mo: infoText = 'MouseOver: %s' % mo.name else: infoText = 'MouseOver: None' active = uicore.registry.GetActive() if active: infoText += '<br>Active: %s' % active.name else: infoText += '<br>Active: None' focus = uicore.registry.GetFocus() if focus: infoText += '<br>Focus: %s' % (focus.name or focus.__guid__) else: infoText += '<br>Focus: None' capture = uicore.uilib.GetMouseCapture() if capture: infoText += '<br>Capture: %s' % (capture.name or capture.__guid__) else: infoText += '<br>Capture: None' infoText += '<br>MouseX/Y: %s, %s' % (uicore.uilib.x, uicore.uilib.y) showHilite = settings.user.ui.Get('uitreeShowPickHilite', True) ignoreFullScreenPick = settings.user.ui.Get( 'uitreeIgnoreFullScreenPick', False) hiliteUIObject = None if showHilite: if IsUnder(mo, self): if IsUnder(mo, self.scroll): uiObjectGetAbs = GetAttrs(mo, 'sr', 'node', 'uiObject', 'GetAbsolute') if uiObjectGetAbs: hiliteUIObject = GetAttrs(mo, 'sr', 'node', 'uiObject') elif mo is not uicore.desktop and mo is not self and not IsUnder( mo, self) and self.state == uiconst.UI_NORMAL: hiliteUIObject = mo if hiliteUIObject and ignoreFullScreenPick and isinstance( hiliteUIObject, (LayerCore, UIRoot)): hiliteUIObject = None self.ShowHilitedObjectInUI(hiliteUIObject) selectedObject = None if self._selectedObject: selectedObject = self._selectedObject() if getattr(selectedObject, 'destroyed', False): selectedObject = None for node in self.scroll.sr.nodes: if node.panel: node.panel.UpdateSelected(selectedObject) node.panel.UpdatePickHilite(hiliteUIObject) if getattr(node.uiObject, 'destroyed', False): node.panel.CheckDestroyed() self.ShowSelectedObjectInUI(selectedObject) self._infoLabel.text = infoText self._infoContainer.height = self._infoLabel.textheight + 5 blue.pyos.synchro.SleepWallclock(100) def ShowSelectedObjectInUI(self, uiObject): if uiObject and hasattr(uiObject, 'GetAbsolute'): self._selectedFrame.pos = uiObject.GetAbsolute() self._selectedFrame.display = True else: self._selectedFrame.display = False def ShowHilitedObjectInUI(self, uiObject): if self.destroyed: return if uiObject: self._hiliteFrame.pos = uiObject.GetAbsolute() self._hiliteFrame.display = True else: self._hiliteFrame.display = False def ReloadUIRoots(self, *args): startRoot = uicore.uilib.rootObjects scrollNodes = [] for root in startRoot: self._CrawlUIObject(root, scrollNodes, 0) self.scroll.LoadContent(contentList=scrollNodes) def _AddUIObject(self, uiObject, scrollList, lvl, isExpanded=False, objectLabel=None, isExpandable=False): if len(scrollList) > 1 and lvl: for i in xrange(1, len(scrollList) - 1): last = scrollList[-i] if last.level < lvl: break if lvl not in last.connectLevels: last.connectLevels.append(lvl) node = ScrollEntryNode(decoClass=UITreeEntry, uiObject=uiObject, level=lvl, isExpanded=isExpanded, objectLabel=objectLabel, isExpandable=isExpandable, connectLevels=[lvl]) scrollList.append(node) def IsExpanded(self, uiObject): desktopObjectID = id(uicore.desktop) allPrefs = settings.user.ui.Get('UITreeExpandedObjects', {}) if desktopObjectID not in allPrefs: return False uiObjectID = id(uiObject) if getattr(uiObject, 'parent', None): uiObjectID = (id(uiObject.parent), uiObjectID) return uiObjectID in allPrefs[desktopObjectID] def ExpandUIObject(self, uiObject): uiObjectID = id(uiObject) if getattr(uiObject, 'parent', None): uiObjectID = (id(uiObject.parent), uiObjectID) desktopObjectID = id(uicore.desktop) allPrefs = settings.user.ui.Get('UITreeExpandedObjects', {}) if desktopObjectID not in allPrefs: allPrefs[desktopObjectID] = [] if uiObjectID not in allPrefs[desktopObjectID]: allPrefs[desktopObjectID].append(uiObjectID) settings.user.ui.Set('UITreeExpandedObjects', allPrefs) def ToggleExpandedObject(self, uiObject): uiObjectID = id(uiObject) if getattr(uiObject, 'parent', None): uiObjectID = (id(uiObject.parent), uiObjectID) desktopObjectID = id(uicore.desktop) allPrefs = settings.user.ui.Get('UITreeExpandedObjects', {}) if desktopObjectID not in allPrefs: allPrefs[desktopObjectID] = [] if uiObjectID in allPrefs[desktopObjectID]: allPrefs[desktopObjectID].remove(uiObjectID) else: allPrefs[desktopObjectID].append(uiObjectID) settings.user.ui.Set('UITreeExpandedObjects', allPrefs) self.ReloadUIRoots() def _CrawlUIObject(self, uiObject, scrollNodes, lvl, objectLabel=None): """Defines what to show in the tree""" isExpandable = UITree._IsExpandable(uiObject) if isExpandable: isExpanded = self.IsExpanded(uiObject) else: isExpanded = False self._AddUIObject(uiObject, scrollNodes, lvl, isExpanded, objectLabel=objectLabel, isExpandable=isExpandable) if isExpanded: if isinstance(uiObject, Base): allPy = dir(uiObject) for propertyName in allPy: if propertyName.startswith( '_') or propertyName in IGNORE_PROPERTIES: continue try: prop = getattr(uiObject, propertyName, None) except: print 'Failed on property', propertyName continue try: if getattr(prop, 'TypeInfo', None): self._CrawlUIObject(prop, scrollNodes, lvl + 1, objectLabel=propertyName) except (KeyError, RuntimeError): pass for dictName in PYOBJECT_SUBDICTS: dct = getattr(uiObject, dictName, {}) if dct: for k, v in dct.iteritems(): self._CrawlUIObject(v, scrollNodes, lvl + 1, objectLabel='%s: %s' % (dictName.lstrip('_'), k)) for listName in PYOBJECT_SUBLISTS: lst = getattr(uiObject, listName, []) if lst: for objChild in lst: if listName == 'background': self._CrawlUIObject(objChild, scrollNodes, lvl + 1, objectLabel=listName) else: self._CrawlUIObject(objChild, scrollNodes, lvl + 1) else: allC = dir(uiObject) for propertyName in allC: if propertyName.startswith('_'): continue prop = getattr(uiObject, propertyName, None) if callable(prop): continue if getattr(prop, '__bluetype__', None) == 'blue.List': isExpanded = self.IsExpanded(prop) self._AddUIObject(prop, scrollNodes, lvl + 1, isExpanded, isExpandable=True, objectLabel='%s (%s)' % (propertyName, len(prop))) if isExpanded: for each in prop: self._CrawlUIObject(each, scrollNodes, lvl + 2) continue elif getattr(prop, '__bluetype__', None) == 'blue.Dict': isExpanded = self.IsExpanded(prop) self._AddUIObject(prop, scrollNodes, lvl + 1, isExpanded, isExpandable=True, objectLabel=propertyName) if isExpanded: for k, v in prop.items(): self._CrawlUIObject(v, scrollNodes, lvl + 2, objectLabel=k) continue elif hasattr(prop, 'TypeInfo'): self._CrawlUIObject(prop, scrollNodes, lvl + 1, objectLabel=propertyName) @classmethod def _IsExpandable(cls, uiObject): if isinstance(uiObject, Base): return True allC = dir(uiObject) for propertyName in allC: if propertyName.startswith('_'): continue prop = getattr(uiObject, propertyName, None) if getattr(prop, '__bluetype__', None) in ('blue.List', 'blue.Dict'): return True if hasattr(prop, 'TypeInfo'): return True return False def ShowUIObject(self, uiObject): traceUp = [uiObject] parent = uiObject.parent while parent: traceUp.insert(0, parent) parent = parent.parent for each in traceUp: self.ExpandUIObject(each) self.ShowPropertiesForObject(uiObject) for node in self.scroll.sr.nodes: if node.uiObject is uiObject: self.scroll.ShowNodeIdx(node.idx) break def ShowPropertiesForObject(self, uiObject): if uiObject is None: return try: len(uiObject) self.attributeScroll.LoadContent(contentList=[]) return except: pass self._selectedObject = weakref.ref(uiObject) level = 0 newNodes = [] if isinstance(uiObject, Base): combined = [] if hasattr(uiObject, 'color'): combined.append( ('color', ('color.r', 'color.g', 'color.b', 'color.a'))) for propertyName, subs in combined: propertyNode = ScrollEntryNode(decoClass=UITreePropertyEntry, uiObject=uiObject, level=level, propertyName=propertyName, combineProperties=subs) newNodes.append(propertyNode) basics = [ 'name', 'pos', 'opacity', 'padding', 'displayRect', 'display', 'pickState', 'align', 'clipChildren', 'pickRadius', 'absoluteCoordinates', 'cacheContents', 'text', 'blendMode', 'spriteEffect', 'effectAmount', 'effectAmount2', 'glowColor', 'glowFactor', 'glowExpand', 'useSizeFromTexture', 'rotation', 'rotationCenter', 'scale', 'scalingCenter', 'scalingRotation', '', '__guid__', '__class__' ] for propertyName in basics: prop = getattr(uiObject, propertyName, '_!_') if prop == '_!_': continue propertyNode = ScrollEntryNode(decoClass=UITreePropertyEntry, uiObject=uiObject, level=level, propertyName=propertyName) newNodes.append(propertyNode) else: for attr in dir(uiObject): if attr[0] == attr[0].upper(): continue if attr[0] == '_': continue if attr in ('children', 'background'): continue propertyNode = ScrollEntryNode(decoClass=UITreePropertyEntry, uiObject=uiObject, level=level, propertyName=attr) newNodes.append((attr, propertyNode)) newNodes = SortListOfTuples(newNodes) self.ReloadUIRoots() self.attributeScroll.LoadContent(contentList=newNodes)