NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

container.py (16095B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\carbonui\primitives\container.py
      2 import weakref
      3 import trinity
      4 from carbonui.util.autonaming import apply_auto_naming
      5 from carbonui import uiconst
      6 from carbonui.primitives.backgroundList import BackgroundList
      7 from carbonui.primitives.base import Base
      8 from carbonui.primitives.childrenlist import PyChildrenList
      9 from carbonui.primitives.fill import Fill
     10 from carbonui.primitives.sprite import Sprite
     11 from carbonui.uiconst import PickState
     12 from carbonui.uicore import uicore
     13 import logging
     14 log = logging.getLogger(__name__)
     15 
     16 class Container(Base):
     17     __guid__ = 'uiprimitives.Container'
     18     __renderObject__ = trinity.Tr2Sprite2dContainer
     19     isDropLocation = True
     20     default_clipChildren = False
     21     default_pickRadius = 0
     22     default_opacity = 1.0
     23     default_align = uiconst.TOALL
     24     default_state = uiconst.UI_PICKCHILDREN
     25     default_pickState = PickState.CHILDREN
     26     default_depthMin = 0.0
     27     default_depthMax = 0.0
     28     default_bgColor = None
     29     default_bgTexturePath = None
     30     default_bgRotation = 0.0
     31     default_bgBlendMode = trinity.TR2_SBM_BLEND
     32     default_bgSpriteEffect = Sprite.default_spriteEffect
     33     default_bgOutputMode = Sprite.default_outputMode
     34     _cacheContents = False
     35     _containerClosing = False
     36     _childrenAlignmentDirty = False
     37     _backgroundlist = None
     38     _opacity = None
     39 
     40     def ApplyAttributes(self, attributes):
     41         self.children = self.GetChildrenList()
     42         Base.ApplyAttributes(self, attributes)
     43         self.depthMin = attributes.get('depthMin', self.default_depthMin)
     44         self.depthMax = attributes.get('depthMax', self.default_depthMax)
     45         self.pickRadius = attributes.get('pickRadius', self.default_pickRadius)
     46         self.opacity = attributes.get('opacity', self.default_opacity)
     47         self.clipChildren = attributes.get('clipChildren', self.default_clipChildren)
     48         self._bgColor = attributes.get('bgColor', self.default_bgColor)
     49         self._bgTexturePath = attributes.get('bgTexturePath', self.default_bgTexturePath)
     50         self._bgRotation = attributes.get('bgRotation', self.default_bgRotation)
     51         self._bgBlendMode = attributes.get('bgBlendMode', self.default_bgBlendMode)
     52         self._bgSpriteEffect = attributes.get('bgSpriteEffect', self.default_bgSpriteEffect)
     53         self._bgSpriteOutputMode = attributes.get('bgOutputMode', self.default_bgOutputMode)
     54         self._bgSprite = None
     55         self.bgFill = None
     56         self._SetupBackground()
     57         try:
     58             self._ApplyAutonaming(attributes)
     59         except Exception as exc:
     60             log.exception('Failed to autoname container: %s', exc)
     61 
     62     def _SetupBackground(self):
     63         if self._bgSprite is not None:
     64             self._bgSprite.Close()
     65         if self.bgFill is not None:
     66             self.bgFill.Close()
     67         if self._bgTexturePath:
     68             self._bgSprite = Sprite(bgParent=self, texturePath=self._bgTexturePath, color=self._bgColor or (1.0, 1.0, 1.0, 1.0), rotation=self._bgRotation, blendMode=self._bgBlendMode, outputMode=self._bgSpriteOutputMode, spriteEffect=self._bgSpriteEffect)
     69         elif self._bgColor:
     70             self.bgFill = Fill(bgParent=self, color=self._bgColor, rotation=self._bgRotation, blendMode=self._bgBlendMode)
     71 
     72     def _ApplyAutonaming(self, attributes):
     73         apply_auto_naming(self, attributes)
     74 
     75     def Close(self):
     76         if getattr(self, 'destroyed', False):
     77             return
     78         self._containerClosing = True
     79         for child in self.children:
     80             child.Close()
     81 
     82         self.children = []
     83         if self._backgroundlist:
     84             for child in self.background[:]:
     85                 child.Close()
     86 
     87         Base.Close(self)
     88 
     89     def UpdateAlignment(self, budgetLeft = 0, budgetTop = 0, budgetWidth = 0, budgetHeight = 0, updateChildrenOnly = False):
     90         forceUpdate = self._forceUpdateAlignment
     91         if updateChildrenOnly:
     92             childrenDirty = True
     93             sizeChange = False
     94         else:
     95             budgetLeft, budgetTop, budgetWidth, budgetHeight, sizeChange = Base.UpdateAlignment(self, budgetLeft, budgetTop, budgetWidth, budgetHeight)
     96             childrenDirty = self._childrenAlignmentDirty
     97         self._childrenAlignmentDirty = False
     98         if childrenDirty or forceUpdate or sizeChange:
     99             self._update_children_alignment(sizeChange, forceUpdate)
    100         return (budgetLeft,
    101          budgetTop,
    102          budgetWidth,
    103          budgetHeight,
    104          sizeChange)
    105 
    106     def _update_children_alignment(self, sizeChange, forceUpdate):
    107         flagNextChild = False
    108         cbLeft, cbTop, cbWidth, cbHeight = (0,
    109          0,
    110          self.displayWidth,
    111          self.displayHeight)
    112         for each in self.children:
    113             if each.destroyed:
    114                 continue
    115             if each.display and forceUpdate:
    116                 each._forceUpdateAlignment = True
    117             isPushAligned = each.isPushAligned
    118             if isPushAligned and each._forceUpdateAlignment:
    119                 flagNextChild = True
    120             if each.display:
    121                 if not each._alignmentDirty and (sizeChange or flagNextChild and each.isAffectedByPushAlignment):
    122                     each._alignmentDirty = True
    123                 if getattr(each, '_childrenAlignmentDirty', False) or each._alignmentDirty or each._forceUpdateAlignment or isPushAligned:
    124                     preDisplayX = each.displayX
    125                     preDisplayY = each.displayY
    126                     cbLeft, cbTop, cbWidth, cbHeight, changedSize = each.UpdateAlignment(cbLeft, cbTop, cbWidth, cbHeight)
    127                     if not flagNextChild and isPushAligned:
    128                         flagNextChild = changedSize or preDisplayX != each.displayX or preDisplayY != each.displayY
    129 
    130     def GetChildrenList(self):
    131         return PyChildrenList(self)
    132 
    133     def GetOpacity(self):
    134         return self.opacity
    135 
    136     def SetOpacity(self, opacity):
    137         self.opacity = opacity
    138 
    139     def IsVisibleAndClickable(self):
    140         if not hasattr(self, 'opacity'):
    141             return False
    142         if self.opacity <= 0.5:
    143             return False
    144         return super(Container, self).IsVisibleAndClickable()
    145 
    146     def AutoFitToContent(self):
    147         if self.isAffectedByPushAlignment:
    148             raise RuntimeError('AutoFitToContent: invalid alignment')
    149         minWidth = 0
    150         minHeight = 0
    151         totalAutoVertical = 0
    152         totalAutoHorizontal = 0
    153         for each in self.children:
    154             if not each.isAffectedByPushAlignment:
    155                 minWidth = max(minWidth, each.left + each.width)
    156                 minHeight = max(minHeight, each.top + each.height)
    157             elif each.align in (uiconst.TOTOP, uiconst.TOBOTTOM):
    158                 totalAutoVertical += each.padTop + each.height + each.padBottom
    159             elif each.align in (uiconst.TOLEFT, uiconst.TORIGHT):
    160                 totalAutoHorizontal += each.padLeft + each.width + each.padRight
    161 
    162         self.width = max(minWidth, totalAutoHorizontal)
    163         self.height = max(minHeight, totalAutoVertical)
    164 
    165     def Flush(self):
    166         for child in self.children[:]:
    167             child.Close()
    168 
    169     def FindChild(self, *names, **kwds):
    170         if self.destroyed:
    171             return
    172         ret = None
    173         searchFrom = self
    174         for name in names:
    175             ret = searchFrom._FindChildByName(name)
    176             if hasattr(ret, 'children'):
    177                 searchFrom = ret
    178 
    179         if not ret or ret.name != names[-1]:
    180             if kwds.get('raiseError', False):
    181                 raise RuntimeError('ChildNotFound', (self.name, names))
    182             return
    183         return ret
    184 
    185     def _FindChildByName(self, name, lvl = 0):
    186         for child in self.children:
    187             if child.name == name:
    188                 return child
    189 
    190         for child in self.children:
    191             if hasattr(child, 'children'):
    192                 ret = child._FindChildByName(name, lvl + 1)
    193                 if ret is not None:
    194                     return ret
    195 
    196     def iter_children(self):
    197         for child in self.children:
    198             yield child
    199 
    200     def iter_descendants_breadth_first(self):
    201         remaining = list((weakref.ref(child) for child in self.children))
    202         while remaining:
    203             element_ref = remaining.pop(0)
    204             element = element_ref()
    205             if element is None:
    206                 continue
    207             yield element
    208             if hasattr(element, 'children'):
    209                 remaining.extend((weakref.ref(child) for child in element.children))
    210 
    211     def iter_descendants_depth_first(self):
    212         remaining = list((weakref.ref(child) for child in reversed(self.children)))
    213         while remaining:
    214             element_ref = remaining.pop()
    215             element = element_ref()
    216             if element is None:
    217                 continue
    218             yield element
    219             remaining.extend((weakref.ref(child) for child in reversed(getattr(element, 'children', []))))
    220 
    221     def Find(self, triTypeName):
    222         return list(filter(lambda element: getattr(element, '__bluetype__', None) == triTypeName, self.iter_descendants_depth_first()))
    223 
    224     def FindByInstance(self, classTypeOrTypeTuple):
    225         return set(filter(lambda element: isinstance(element, classTypeOrTypeTuple), self.iter_descendants_depth_first()))
    226 
    227     def GetChild(self, *names):
    228         return self.FindChild(*names, **{'raiseError': True})
    229 
    230     def IsChildClipped(self, child):
    231         if not self.clipChildren:
    232             return False
    233         cdx = child.displayX
    234         cdw = child.displayWidth
    235         sdx = self.displayX
    236         sdw = self.displayWidth
    237         if cdx >= sdx and cdx <= sdx + sdw or cdx + cdw >= sdx and cdx + cdw <= sdx + sdw:
    238             cdy = child.displayY
    239             cdh = child.displayHeight
    240             sdy = self.displayY
    241             sdh = self.displayHeight
    242             if cdy >= sdy and cdy <= sdy + sdh or cdy + cdh >= sdy and cdy + cdh <= sdy + sdh:
    243                 return False
    244         return True
    245 
    246     @property
    247     def background(self):
    248         if not self._backgroundlist:
    249             self._backgroundlist = BackgroundList(self)
    250         return self._backgroundlist
    251 
    252     @property
    253     def depthMin(self):
    254         return self._depthMin
    255 
    256     @depthMin.setter
    257     def depthMin(self, value):
    258         self._depthMin = value
    259         ro = self.renderObject
    260         if ro and hasattr(ro, 'depthMin'):
    261             ro.depthMin = value or 0.0
    262 
    263     @property
    264     def depthMax(self):
    265         return self._depthMax
    266 
    267     @depthMax.setter
    268     def depthMax(self, value):
    269         self._depthMax = value
    270         ro = self.renderObject
    271         if ro and hasattr(ro, 'depthMax'):
    272             ro.depthMax = value or 0.0
    273 
    274     @property
    275     def clipChildren(self):
    276         return self._clipChildren
    277 
    278     @clipChildren.setter
    279     def clipChildren(self, value):
    280         self._clipChildren = value
    281         ro = self.renderObject
    282         if ro and hasattr(ro, 'clip'):
    283             ro.clip = value
    284 
    285     @property
    286     def opacity(self):
    287         return self._opacity
    288 
    289     @opacity.setter
    290     def opacity(self, value):
    291         self._SetOpacity(value)
    292 
    293     def _SetOpacity(self, value):
    294         if value != self._opacity:
    295             self._opacity = value
    296             ro = self.renderObject
    297             if ro and hasattr(ro, 'opacity'):
    298                 ro.opacity = value or 0.0
    299             for child in self.children:
    300                 childRenderObject = child.renderObject
    301                 if childRenderObject:
    302                     childRenderObject.isDirty = True
    303 
    304     @property
    305     def pickRadius(self):
    306         return self._pickRadius
    307 
    308     @pickRadius.setter
    309     def pickRadius(self, value):
    310         self._pickRadius = value
    311         ro = self.renderObject
    312         if ro and hasattr(ro, 'pickRadius'):
    313             if value < 0:
    314                 ro.pickRadius = value
    315             else:
    316                 ro.pickRadius = uicore.ScaleDpi(value) or 0.0
    317 
    318     @Base.displayWidth.setter
    319     def displayWidth(self, value):
    320         Base.displayWidth.fset(self, value)
    321         if self._backgroundlist and len(self.background):
    322             self.UpdateBackgrounds()
    323 
    324     @Base.displayHeight.setter
    325     def displayHeight(self, value):
    326         Base.displayHeight.fset(self, value)
    327         if self._backgroundlist and len(self.background):
    328             self.UpdateBackgrounds()
    329 
    330     @Base.displayRect.setter
    331     def displayRect(self, value):
    332         Base.displayRect.fset(self, value)
    333         if self._backgroundlist and len(self.background):
    334             self.UpdateBackgrounds()
    335 
    336     def UpdateBackgrounds(self):
    337         for each in self.background:
    338             pl, pt, pr, pb = each.padding
    339             each.displayRect = (uicore.ScaleDpi(pl),
    340              uicore.ScaleDpi(pt),
    341              self._displayWidth - uicore.ScaleDpi(pl + pr),
    342              self._displayHeight - uicore.ScaleDpi(pt + pb))
    343 
    344     @property
    345     def cacheContents(self):
    346         return self._cacheContents
    347 
    348     @cacheContents.setter
    349     def cacheContents(self, value):
    350         self._cacheContents = value
    351         if self.renderObject:
    352             self.renderObject.cacheContents = value
    353 
    354     def _AppendChildRO(self, child):
    355         try:
    356             self.renderObject.children.append(child.renderObject)
    357         except (AttributeError, TypeError):
    358             pass
    359 
    360     def _InsertChildRO(self, idx, child):
    361         try:
    362             self.renderObject.children.insert(idx, child.renderObject)
    363         except IndexError:
    364             self.renderObject.children.append(child.renderObject)
    365         except (AttributeError, TypeError):
    366             pass
    367 
    368     def _RemoveChildRO(self, child):
    369         try:
    370             self.renderObject.children.remove(child.renderObject)
    371         except (AttributeError,
    372          ValueError,
    373          RuntimeError,
    374          TypeError):
    375             pass
    376 
    377     def AppendBackgroundObject(self, child):
    378         try:
    379             self.renderObject.background.append(child.renderObject)
    380         except AttributeError:
    381             pass
    382 
    383     def InsertBackgroundObject(self, idx, child):
    384         try:
    385             self.renderObject.background.insert(idx, child.renderObject)
    386         except AttributeError:
    387             pass
    388 
    389     def RemoveBackgroundObject(self, child):
    390         try:
    391             self.renderObject.background.remove(child.renderObject)
    392         except (AttributeError,
    393          ValueError,
    394          RuntimeError,
    395          TypeError):
    396             pass
    397 
    398     @property
    399     def background_color(self):
    400         return self._bgColor
    401 
    402     @background_color.setter
    403     def background_color(self, value):
    404         self._bgColor = value
    405         self._SetupBackground()
    406 
    407     @property
    408     def background_texture_path(self):
    409         return self._bgTexturePath
    410 
    411     @background_texture_path.setter
    412     def background_texture_path(self, value):
    413         self._bgTexturePath = value
    414         self._SetupBackground()
    415 
    416     def UpdateUIScaling(self, value, oldValue):
    417         for child in self.children:
    418             child.UpdateUIScaling(value, oldValue)
    419 
    420         for bgChild in self.background:
    421             bgChild.UpdateUIScaling(value, oldValue)
    422 
    423     def OnColorThemeChanged(self):
    424         for child in self.children:
    425             child.OnColorThemeChanged()
    426 
    427         for bgChild in self.background:
    428             bgChild.OnColorThemeChanged()
    429 
    430     def OnWindowAboveSetActive(self):
    431         for child in self.children:
    432             child.OnWindowAboveSetActive()
    433 
    434         for bgChild in self.background:
    435             bgChild.OnWindowAboveSetActive()
    436 
    437     def OnWindowAboveSetInactive(self):
    438         for child in self.children:
    439             child.OnWindowAboveSetInactive()
    440 
    441         for bgChild in self.background:
    442             bgChild.OnWindowAboveSetInactive()
    443 
    444     def OnGlobalFontSizeChanged(self):
    445         for child in self.children:
    446             child.OnGlobalFontSizeChanged()
    447 
    448         for bgChild in self.background:
    449             bgChild.OnGlobalFontSizeChanged()
    450 
    451     def OnGlobalFontShadowChanged(self):
    452         for child in self.children:
    453             child.OnGlobalFontShadowChanged()
    454 
    455         for bgChild in self.background:
    456             bgChild.OnGlobalFontShadowChanged()