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

panContainer.py (8446B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\control\panContainer.py
      2 from carbonui.primitives.container import Container
      3 from carbonui.primitives.containerAutoSize import ContainerAutoSize
      4 from carbonui.const import UI_PICKCHILDREN, TOPLEFT, UICURSOR_DRAGGABLE, UI_NORMAL, CENTER
      5 import geo2
      6 import uthread
      7 import blue
      8 from carbonui.primitives.transform import Transform
      9 from carbonui.uicore import uicore
     10 
     11 class PanContainer(Container):
     12     default_name = 'PanContainer'
     13     default_panSpeed = 8.0
     14     default_panAmount = 2.0
     15     default_callback = None
     16     default_state = UI_NORMAL
     17     default_clipChildren = True
     18     default_panLeft = 0.0
     19     default_panTop = 0.0
     20     default_border = (10, 10, 10, 10)
     21     default_axisLockMargin = 50
     22     default_isPanRelativeToContentSize = True
     23 
     24     def GetCursor(self):
     25         if not (self.IsClampedHorizontally() and self.IsClampedVertically()):
     26             return UICURSOR_DRAGGABLE
     27 
     28     def ApplyAttributes(self, attributes):
     29         Container.ApplyAttributes(self, attributes)
     30         self.panSpeed = attributes.Get('panSpeed', self.default_panSpeed)
     31         self.panAmount = attributes.Get('panAmount', self.default_panAmount)
     32         self.callback = attributes.Get('callback', self.default_callback)
     33         self._border = None
     34         self.border = attributes.Get('border', self.default_border)
     35         self._panLeft = attributes.Get('panLeft', self.default_panLeft)
     36         self._panTop = attributes.Get('panTop', self.default_panTop)
     37         self.axisLockMargin = attributes.Get('axisLockMargin', self.default_axisLockMargin)
     38         self.isPanRelativeToContentSize = attributes.Get('isPanRelativeToContentSize', self.default_isPanRelativeToContentSize)
     39         self._scale = 1.0
     40         self.panUpdateThread = None
     41         self.panTarget = None
     42         self.transform = Transform(parent=self, align=TOPLEFT, state=UI_PICKCHILDREN, scalingCenter=(0.5, 0.5))
     43         self.mainCont = ContainerAutoSize(name='mainCont', parent=self.transform, align=CENTER, state=UI_PICKCHILDREN)
     44 
     45     def OnMouseMove(self, *args):
     46         if uicore.uilib.leftbtn and not uicore.uilib.rightbtn and not uicore.IsDragging():
     47             k = self.panAmount / self.scale
     48             self.Pan(k * uicore.uilib.dx, k * uicore.uilib.dy)
     49 
     50     def Pan(self, dx = 0, dy = 0):
     51         if self.panTarget is None:
     52             self.panTarget = geo2.Vector(0, 0)
     53         if self.IsClampedHorizontally():
     54             dx = 0
     55         if self.IsClampedVertically():
     56             dy = 0
     57         self.panTarget += geo2.Vector(dx, dy)
     58         if not self.panUpdateThread:
     59             self.panUpdateThread = uthread.new(self._PanUpdateThread)
     60 
     61     def IsClampedHorizontally(self, includeMargin = True):
     62         width = self.transform.width
     63         parWidth, _ = self.GetAbsoluteSize()
     64         bLeft, _, bRight, _ = self.border
     65         margin = self.axisLockMargin if includeMargin else 0
     66         if width < parWidth - bLeft - bRight + margin:
     67             return True
     68         return False
     69 
     70     def IsClampedVertically(self, includeMargin = True):
     71         height = self.transform.height
     72         _, parHeight = self.GetAbsoluteSize()
     73         _, bTop, _, bBottom = self.border
     74         margin = self.axisLockMargin if includeMargin else 0
     75         if height < parHeight - bTop - bBottom + margin:
     76             return True
     77         return False
     78 
     79     def PanTo(self, panLeft, panTop, animate = True, duration = None, timeOffset = 0.0, sleep = False):
     80         if animate:
     81             if not duration:
     82                 length = geo2.Vec3Distance((panLeft, panTop, 0), (self.panLeft, self.panTop, 0))
     83                 duration = max(0.1, length * self.scale)
     84             uicore.animations.MorphScalar(self, 'panLeft', self.panLeft, panLeft, duration=duration, timeOffset=timeOffset)
     85             uicore.animations.MorphScalar(self, 'panTop', self.panTop, panTop, duration=duration, timeOffset=timeOffset, sleep=sleep)
     86         else:
     87             self.panLeft = panLeft
     88             self.panTop = panTop
     89 
     90     def PanToMouseOver(self, duration = None, timeOffset = 0.0, sleep = False):
     91         panLeft, panTop = self.GetMousePositionProportional()
     92         if not duration:
     93             length = geo2.Vec2Length((panLeft - self.panLeft, panTop - self.panTop))
     94             if length < 0.2:
     95                 return 0.0
     96             duration = max(0.3, length * 0.4)
     97         self.PanTo(panLeft, panTop, duration=duration, timeOffset=timeOffset, sleep=sleep)
     98         return duration
     99 
    100     def GetMousePositionProportional(self):
    101         x = uicore.uilib.x
    102         y = uicore.uilib.y
    103         left, top, width, height = self.transform.GetAbsolute()
    104         x = (x - left) / float(width)
    105         y = (y - top) / float(height)
    106         x = max(0.0, min(x, 1.0))
    107         y = max(0.0, min(y, 1.0))
    108         return (x, y)
    109 
    110     def GetScale(self):
    111         return self._scale
    112 
    113     def SetScale(self, value):
    114         self._scale = value
    115         self.transform.scale = (value, value)
    116         self.FlagAlignmentDirty()
    117 
    118     scale = property(GetScale, SetScale)
    119 
    120     def _PanUpdateThread(self):
    121         while True:
    122             if self.panTarget is None or not self.mainCont.children:
    123                 break
    124             distLeft = geo2.Vec2Length(self.panTarget)
    125             if distLeft == 0:
    126                 break
    127             dist = self.panSpeed / blue.os.fps
    128             if distLeft < 1.0:
    129                 dist *= 1.0 / distLeft
    130             dist = min(dist, 1.0)
    131             toMove = geo2.Vec2Scale(self.panTarget, dist)
    132             self.panTarget -= toMove
    133             dx, dy = toMove
    134             if self.isPanRelativeToContentSize:
    135                 totalPanWidth = self.mainCont.width
    136                 totalPanHeight = self.mainCont.height
    137             else:
    138                 minLeft, maxLeft, minTop, maxTop = self._GetPanningConstraints()
    139                 totalPanWidth = maxLeft - minLeft
    140                 totalPanHeight = maxTop - minTop
    141             if totalPanWidth > 0:
    142                 self.panLeft -= dx / totalPanWidth
    143             if totalPanHeight > 0:
    144                 self.panTop -= dy / totalPanHeight
    145             blue.synchro.Yield()
    146 
    147         self.panUpdateThread = None
    148         self.panTarget = None
    149 
    150     def GetPanLeft(self):
    151         return self._panLeft
    152 
    153     def SetPanLeft(self, value):
    154         self._panLeft = max(0.0, min(value, 1.0))
    155         self.FlagAlignmentDirty()
    156 
    157     panLeft = property(GetPanLeft, SetPanLeft)
    158 
    159     def GetPanTop(self):
    160         return self._panTop
    161 
    162     def SetPanTop(self, value):
    163         self._panTop = max(0.0, min(value, 1.0))
    164         self.FlagAlignmentDirty()
    165 
    166     panTop = property(GetPanTop, SetPanTop)
    167 
    168     def UpdateAlignment(self, *args, **kwds):
    169         budget = super(PanContainer, self).UpdateAlignment(*args, **kwds)
    170         self._UpdateTransformPos()
    171         return budget
    172 
    173     def _UpdateTransformPos(self):
    174         self.transform.width = self.mainCont.width * self.scale
    175         self.transform.height = self.mainCont.height * self.scale
    176         minLeft, maxLeft, minTop, maxTop = self._GetPanningConstraints()
    177         diff = minTop - maxTop
    178         self.transform.top = maxTop + diff * self._panTop
    179         diff = minLeft - maxLeft
    180         self.transform.left = maxLeft + diff * self._panLeft
    181         if self.callback:
    182             self.callback()
    183 
    184     def _GetPanningConstraints(self):
    185         width, height = self.transform.width, self.transform.height
    186         parWidth, parHeight = self.GetAbsoluteSize()
    187         bLeft, bTop, bRight, bBottom = self.border
    188         if self.IsClampedHorizontally(includeMargin=False):
    189             minLeft = maxLeft = (bRight - bLeft + parWidth - width) / 2
    190         else:
    191             minLeft = parWidth - width - bLeft
    192             maxLeft = bRight
    193         if self.IsClampedVertically(includeMargin=False):
    194             minTop = maxTop = (bBottom - bTop + parHeight - height) / 2
    195         else:
    196             minTop = parHeight - height - bTop
    197             maxTop = bBottom
    198         return (minLeft,
    199          maxLeft,
    200          minTop,
    201          maxTop)
    202 
    203     def SetBorder(self, border):
    204         if isinstance(border, int):
    205             self._border = (border,
    206              border,
    207              border,
    208              border)
    209         else:
    210             self._border = border
    211         self.FlagAlignmentDirty()
    212 
    213     def GetBorder(self):
    214         return self._border
    215 
    216     border = property(GetBorder, SetBorder)
    217 
    218     def Flush(self):
    219         self.mainCont.Flush()