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

colorblind.py (4880B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\carbonui\util\colorblind.py
      2 import logging
      3 from carbonui.util.color import Color
      4 from clientsettings.setting import UserSettingEnum
      5 from signals import Signal
      6 log = logging.getLogger(__name__)
      7 on_colorblind_mode_changed = Signal('on_colorblind_mode_changed')
      8 RED = 0.0
      9 YELLOW = 1.0 / 6
     10 GREEN = 2.0 / 6
     11 AQUA = 3.0 / 6
     12 BLUE = 4.0 / 6
     13 PINK = 5.0 / 6
     14 MODE_OFF = 0
     15 MODE_DEUTERANOPIA = 1
     16 MODE_TRITONOPIA = 2
     17 MODE_CUSTOM = 3
     18 H_0 = 1.0 / 24
     19 HUES = (RED,
     20  YELLOW,
     21  GREEN,
     22  AQUA,
     23  BLUE,
     24  PINK)
     25 HUES_BY_MODE = {MODE_DEUTERANOPIA: (YELLOW, BLUE),
     26  MODE_TRITONOPIA: (RED, AQUA)}
     27 
     28 def GetCustomHues():
     29     return settings.user.ui.Get('colorBlindCustomHues', HUES[:])
     30 
     31 
     32 def SetCustomHues(hues):
     33     hues = [ hue for hue in HUES if hue in hues ]
     34     return settings.user.ui.Set('colorBlindCustomHues', hues)
     35 
     36 
     37 def ToggleCustomHue(hue):
     38     hues = list(GetCustomHues())
     39     if hue in hues:
     40         hues.remove(hue)
     41     else:
     42         hues.append(hue)
     43     if hues:
     44         SetCustomHues(hues)
     45 
     46 
     47 color_replacement_setting = UserSettingEnum(settings_key='colorBlindMode', default_value=MODE_OFF, options=[MODE_OFF,
     48  MODE_DEUTERANOPIA,
     49  MODE_TRITONOPIA,
     50  MODE_CUSTOM])
     51 
     52 def GetMode():
     53     return color_replacement_setting.get()
     54 
     55 
     56 def SetMode(mode):
     57     color_replacement_setting.set(mode)
     58 
     59 
     60 def GetCurrentHues():
     61     mode = GetMode()
     62     if mode == MODE_CUSTOM:
     63         return GetCustomHues()
     64     return HUES_BY_MODE.get(mode, [])
     65 
     66 
     67 def GetReplacementColorHex(colorHex, maintainBrightness = False, maxSaturation = None):
     68     col = Color.HextoRGBA(colorHex)
     69     col = GetReplacementColor(col, maintainBrightness, maxSaturation)
     70     return Color.RGBtoHex(*col)
     71 
     72 
     73 def GetReplacementColor(color, maintainBrightness = False, maxSaturation = None):
     74     try:
     75         c = Color()
     76         c.SetRGB(*color)
     77         if not c.IsGrayscale() and c.GetBrightness() > 0.3:
     78             h0, s0, b0 = c.GetHSB()
     79             h, x = _GetHueAndRelativeXWithinHue(h0)
     80             b, s = _GetSaturationAndBrightness(x)
     81             if h == BLUE:
     82                 s *= 0.7
     83             if maintainBrightness:
     84                 b = b0
     85             if maxSaturation is not None:
     86                 s = min(maxSaturation, s)
     87             c.SetHSB(h, s, b)
     88             if len(color) == 4:
     89                 color = c.GetRGBA()
     90             else:
     91                 color = c.GetRGB()
     92     except:
     93         log.exception()
     94     finally:
     95         return color
     96 
     97 
     98 def _GetHueAndRelativeXWithinHue(hue):
     99     hues = GetCurrentHues()
    100     numSegments = len(hues)
    101     segmentLen = 1.0 / numSegments
    102     if hue <= H_0:
    103         hue += 1.0
    104     hue = round(hue, 3)
    105     for i in xrange(numSegments):
    106         hStart = round(H_0 + i * segmentLen, 3)
    107         hEnd = round(hStart + segmentLen, 3)
    108         if hStart <= hue and hue <= hEnd:
    109             xRel = (hue - hStart) / segmentLen
    110             xRel = max(0.0, min(xRel, 1.0))
    111             if i % 2:
    112                 xRel = 1.0 - xRel
    113             try:
    114                 hue = hues[i + 1]
    115             except IndexError:
    116                 hue = hues[0]
    117 
    118             return (hue, xRel)
    119 
    120     raise ValueError
    121 
    122 
    123 def GetSaturationConstraints():
    124     SAT_MIN = 0.3
    125     SAT_MAX = 1.0
    126     SAT_DIFF = SAT_MAX - SAT_MIN
    127     return (SAT_MIN, SAT_MAX, SAT_DIFF)
    128 
    129 
    130 def GetBrightnessConstraints():
    131     BRI_MIN = 0.35 + len(GetCurrentHues()) * 0.075
    132     BRI_MAX = 1.0
    133     BRI_DIFF = BRI_MAX - BRI_MIN
    134     return (BRI_MIN, BRI_MAX, BRI_DIFF)
    135 
    136 
    137 def _GetSaturationAndBrightness(x):
    138     if x > 1.0:
    139         raise ValueError('x is > 1.0')
    140     briMin, briMax, briDiff = GetBrightnessConstraints()
    141     satMin, satMax, satDiff = GetSaturationConstraints()
    142     if x <= 1.0 / 3:
    143         x = 3 * x
    144         s = satMin + satDiff * x
    145         b = briMax
    146     elif x <= 2.0 / 3:
    147         x = 3 * (x - 1.0 / 3)
    148         s = satMax
    149         b = briMax - briDiff * x
    150     else:
    151         x = 3 * (x - 2.0 / 3)
    152         s = satMax - satDiff * x
    153         b = briMin
    154     return (b, s)
    155 
    156 
    157 def IsReplacementEnabled():
    158     if hasattr(session, 'charid') is False:
    159         return False
    160     if session.charid is None:
    161         return False
    162     return GetMode() != MODE_OFF
    163 
    164 
    165 def CheckReplaceColor(color, maintainBrightness = False, maxSaturation = None):
    166     if IsReplacementEnabled():
    167         return GetReplacementColor(color, maintainBrightness, maxSaturation)
    168     return color
    169 
    170 
    171 def CheckReplaceColorHex(colorHex, maintainBrightness = False, maxSaturation = None):
    172     if IsReplacementEnabled():
    173         colorHex = colorHex.replace('L', '')
    174         colorHex = GetReplacementColorHex(colorHex, maintainBrightness, maxSaturation)
    175     return colorHex
    176 
    177 
    178 def GetEvenlyDistributedColor(color, i, numColors):
    179     x = H_0 + float(i) / numColors
    180     if x >= 1.0:
    181         x -= 1.0
    182     color = Color(*color)
    183     if not color.IsGrayscale():
    184         color.SetHSB(x, 1.0, 1.0)
    185     return color.GetRGBA()