class MegaMenuEntry(Container): default_align = uiconst.TOPLEFT default_state = uiconst.UI_NORMAL default_height = 24 sidePadding = 30 def ApplyAttributes(self, attributes): Container.ApplyAttributes(self, attributes) self.hiliteFill = Fill(bgParent=self, opacity=0.0) entryInfo = attributes.entryInfo self.callback = entryInfo['callback'] self.callbackArgs = entryInfo['args'] entryInfoDict = attributes.entryInfo text = entryInfoDict['text'] self.textLabel = EveLabelSmall(parent=self, text=text, align=uiconst.CENTER) self.width = self.textLabel.textwidth + self.sidePadding self.height = max(self.default_height, self.textLabel.textheight + 4) def OnMouseEnter(self, *args): self.hiliteFill.opacity = 0.2 self.textLabel.SetRGB(1, 0, 0, 1) def OnMouseExit(self, *args): self.hiliteFill.opacity = 0.0 self.textLabel.SetRGB(1, 1, 1, 1) def OnClick(self, *args): if self.callback: self.callback(self.callbackArgs)
class VulnerabilityScheduler(Container): default_align = uiconst.TOALL default_name = 'VulnerabilityScheduler' default_state = uiconst.UI_NORMAL DAY_COLUMN_HEIGHT = 20 shortDayNamesPaths = [ 'UI/StructureProfiles/MondayShort', 'UI/StructureProfiles/TuesdayShort', 'UI/StructureProfiles/WednesdayShort', 'UI/StructureProfiles/ThursdayShort', 'UI/StructureProfiles/FridayShort', 'UI/StructureProfiles/SaturdayShort', 'UI/StructureProfiles/SundayShort' ] def ApplyAttributes(self, attributes): Container.ApplyAttributes(self, attributes) if attributes.schedule: self.mySchedule = attributes.schedule self.requiredHours = self.mySchedule.GetRequiredHours() elif attributes.requiredHours: self.requiredHours = attributes.requiredHours self.mySchedule = structures.Schedule(required=self.requiredHours) else: raise RuntimeError( 'VulnerabilityScheduler - neither schedule nor required hours?' ) self.callback = attributes.callback self.unallocatedCont = None self.remainingLabel = None self.timeConts = [] self.showDay = attributes.get('showDay', True) self.showTime = attributes.get('showTime', True) self.canModify = attributes.get('canModify', True) self.dragStart = None self.dragContainer = None self.dragMouseBtn = None self.hourConts = defaultdict(dict) self.MakeUnallocatedStrip() if attributes.get('frame', True): Frame(parent=self, color=(1, 1, 1, 0.5)) self.MakeGrid() self.AddBackgroundImage() self.ColorBoxes() self.UpdateHourFill() self.UpdateView() def AddBackgroundImage(self): self.backgroundImage = SpriteThemeColored( name='backgroundImage', parent=self.weekContParent, state=uiconst.UI_DISABLED, colorType=uiconst.COLORTYPE_UIHILIGHTGLOW, spriteEffect=trinity.TR2_SFX_BLUR, blendMode=trinity.TR2_SBM_ADDX2, texturePath= 'res:/UI/Texture/classes/StructureDeployment/deploymentBg.png', opacity=0.02, align=uiconst.CENTER) def MakeUnallocatedStrip(self): padTop = self.DAY_COLUMN_HEIGHT if self.showDay else 0 self.bottomCont = Container(parent=self, align=uiconst.TOBOTTOM, height=8, padTop=8) if not self.canModify: return if self.showDay: remainingCont = Container(parent=self.bottomCont, align=uiconst.TORIGHT, width=40) self.remainingLabel = EveLabelSmall(parent=remainingCont, align=uiconst.CENTER, text='') self.unallocatedCont = UnallocatedCont( name='unallocatedCont', parent=self.bottomCont, columns=self.requiredHours, requiredHours=self.requiredHours, schedule=self.mySchedule, padRight=4) self.UpdateUnallocatedCounter() def MakeGrid(self): if self.showTime: padTop = self.DAY_COLUMN_HEIGHT if self.showDay else 0 hourCont = GridContainer(name='hourCont', parent=self, align=uiconst.TOLEFT, width=50, columns=1, lines=24, padTop=padTop) for x in xrange(24): c = Container(parent=hourCont) self.timeConts.append(c) if self.showDay: dayCont = GridContainer(name='dayCont', parent=self, align=uiconst.TOTOP, columns=7, height=self.DAY_COLUMN_HEIGHT) for eachDayPath in self.shortDayNamesPaths: c = Container(parent=dayCont) text = GetByLabel(eachDayPath) EveLabelMedium(parent=c, align=uiconst.CENTER, text=text) self.weekContParent = Container(name='weekContParent', parent=self, align=uiconst.TOALL) self.weekCont = GridContainer(name='weekCont', parent=self.weekContParent, align=uiconst.TOALL, columns=7) self.hourConts.clear() for hour in xrange(24): for day in xrange(7): c = HourContWithReinforcement( parent=self.weekCont, name='%s_%s' % (day, hour), dayHour=(day, hour), hint='%s<br>%s' % (GetByLabel( self.shortDayNamesPaths[day]), '%.2d:00' % hour), parentMouseDown=self.OnMouseDown) self.hourConts[day][hour] = c self.DecorateGrid() def DecorateGrid(self): lineColor = (1.0, 1.0, 1.0, 0.2) interval = 2 firstCol = True for i, c in enumerate(self.timeConts): self._DecorateCell(c, i, interval, lineColor, firstCol=True) if i % interval == 0: EveLabelSmall(parent=c, align=uiconst.CENTERTOP, text='%.2d:00' % i, top=1) firstCol = False for dayHour, hourCont in self.GetDayHourIterator(): day, hour = dayHour firstCol = firstCol and day == 0 self._DecorateCell(hourCont, hour, interval, lineColor, firstCol) def _DecorateCell(self, cell, hour, interval, lineColor, firstCol=False): Line(parent=cell, align=uiconst.TORIGHT, color=lineColor) if firstCol: Line(parent=cell, align=uiconst.TOLEFT, color=lineColor) if hour == 23: Line(parent=cell, align=uiconst.TOBOTTOM, color=lineColor) if hour % interval == 0: Line(parent=cell, align=uiconst.TOTOP, color=lineColor) def OnMouseDown(self, *args): if not self.canModify: return if self.dragMouseBtn is not None: return if args[0] in (uiconst.MOUSELEFT, uiconst.MOUSERIGHT): self.dragMouseBtn = args[0] else: return self.dragStart = (uicore.uilib.x - self.weekCont.absoluteLeft, uicore.uilib.y - self.weekCont.absoluteTop) self.previousSchedule = self.mySchedule.Copy() if self.dragContainer is None or self.dragContainer.destroyed: self.MakeDragContainer() self.dragContainer.Hide() uthread.new(self.RubberbandSelection_thread) def MakeDragContainer(self): self.dragContainer = Container(parent=self.weekContParent, align=uiconst.TOPLEFT, idx=0) FrameThemeColored(parent=self.dragContainer, frameConst=uiconst.FRAME_BORDER1_CORNER3, colorType=uiconst.COLORTYPE_UIHILIGHT, opacity=0.5) FillThemeColored(parent=self.dragContainer, frameConst=uiconst.FRAME_FILLED_CORNER3, opacity=0.3) def RubberbandSelection_thread(self, *args): counter = 0 while self.dragMouseBtn is not None and uicore.uilib.GetMouseButtonState( self.dragMouseBtn) and trinity.app.IsActive(): self.RubberbandWhileLoop() blue.pyos.synchro.SleepSim(10) if counter % 10 == 0: self.TryCallback() counter += 1 self.dragStart = None self.dragContainer.Hide() self.dragMouseBtn = None self.TryCallback() def TryCallback(self): if self.callback: self.callback(self.mySchedule) def RubberbandWhileLoop(self): startX, startY = self.dragStart currentX, currentY = uicore.uilib.x - self.weekCont.absoluteLeft, uicore.uilib.y - self.weekCont.absoluteTop if startX > currentX: temp = currentX currentX = startX startX = temp if startY > currentY: temp = currentY currentY = startY startY = temp left = max(startX, 0) mainWidth = self.weekCont.absoluteRight - self.weekCont.absoluteLeft width = min(currentX, mainWidth) - max(startX, 0) top = max(startY, 0) mainHeight = self.weekCont.absoluteBottom - self.weekCont.absoluteTop height = min(currentY, mainHeight) - max(startY, 0) self.dragContainer.left = left self.dragContainer.top = top self.dragContainer.width = width self.dragContainer.height = height self.dragContainer.Show() self.FindSelected(startX, startY, currentX, currentY) self.UpdateView() def UpdateView(self): self.ColorBoxes() if self.unallocatedCont: self.unallocatedCont.Update() self.UpdateUnallocatedCounter() self.UpdateHourFill() def UpdateUnallocatedCounter(self): if self.remainingLabel is None: return remaining = self.mySchedule.Remaining() total = self.mySchedule.GetRequiredHours() text = '%s / %s' % (remaining, total) if remaining == 0: color = Color.GREEN elif remaining > 0: color = Color.YELLOW else: color = Color.RED self.remainingLabel.text = text self.remainingLabel.SetRGB(*color) def UpdateHourFill(self): blocksByDay = self.FindBlocksByDay() for eachDay, blocks in blocksByDay.iteritems(): for eachBlock in blocks: firstHour = self.hourConts[eachDay][eachBlock[0]] firstHourTop = firstHour.absoluteTop for idxInBlock, eachHour in enumerate(eachBlock): hourCont = self.hourConts[eachDay][eachHour] hourCont.UpdateFillAlignment(firstHourTop) def FindBlocksByDay(self): vulnerableHours = self.mySchedule.GetVulnerableHours() reinforcementHours = self.mySchedule.GetReinforcementHours() markedHoursByDay = defaultdict(set) for day, hour in itertoolsext.chain(vulnerableHours, reinforcementHours): markedHoursByDay[day].add(hour) blocksByDay = { day: self.FindBlocks(sorted(list(hoursSet))) for day, hoursSet in markedHoursByDay.iteritems() } return blocksByDay def FindBlocks(self, hoursInDay): listOfBlocks = [] for k, g in itertools.groupby(enumerate(hoursInDay), lambda (i, x): i - x): listOfBlocks.append(map(itemgetter(1), g)) return listOfBlocks